[Midnightbsd-cvs] src [10219] trunk/sys/arm: add arm

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Sat Jun 2 11:44:29 EDT 2018


Revision: 10219
          http://svnweb.midnightbsd.org/src/?rev=10219
Author:   laffer1
Date:     2018-06-02 11:44:28 -0400 (Sat, 02 Jun 2018)
Log Message:
-----------
add arm

Added Paths:
-----------
    trunk/sys/arm/
    trunk/sys/arm/allwinner/
    trunk/sys/arm/allwinner/a10_clk.c
    trunk/sys/arm/allwinner/a10_clk.h
    trunk/sys/arm/allwinner/a10_common.c
    trunk/sys/arm/allwinner/a10_ehci.c
    trunk/sys/arm/allwinner/a10_gpio.c
    trunk/sys/arm/allwinner/a10_gpio.h
    trunk/sys/arm/allwinner/a10_machdep.c
    trunk/sys/arm/allwinner/a10_sramc.c
    trunk/sys/arm/allwinner/a10_sramc.h
    trunk/sys/arm/allwinner/a10_wdog.c
    trunk/sys/arm/allwinner/a10_wdog.h
    trunk/sys/arm/allwinner/a20/
    trunk/sys/arm/allwinner/a20/a20_cpu_cfg.c
    trunk/sys/arm/allwinner/a20/a20_cpu_cfg.h
    trunk/sys/arm/allwinner/a20/a20_mp.c
    trunk/sys/arm/allwinner/a20/files.a20
    trunk/sys/arm/allwinner/a20/std.a20
    trunk/sys/arm/allwinner/aintc.c
    trunk/sys/arm/allwinner/console.c
    trunk/sys/arm/allwinner/files.a10
    trunk/sys/arm/allwinner/if_emac.c
    trunk/sys/arm/allwinner/if_emacreg.h
    trunk/sys/arm/allwinner/std.a10
    trunk/sys/arm/allwinner/timer.c
    trunk/sys/arm/arm/
    trunk/sys/arm/arm/autoconf.c
    trunk/sys/arm/arm/bcopy_page.S
    trunk/sys/arm/arm/bcopyinout.S
    trunk/sys/arm/arm/bcopyinout_xscale.S
    trunk/sys/arm/arm/blockio.S
    trunk/sys/arm/arm/bootconfig.c
    trunk/sys/arm/arm/bus_space_asm_generic.S
    trunk/sys/arm/arm/bus_space_base.c
    trunk/sys/arm/arm/bus_space_generic.c
    trunk/sys/arm/arm/busdma_machdep-v6.c
    trunk/sys/arm/arm/busdma_machdep.c
    trunk/sys/arm/arm/copystr.S
    trunk/sys/arm/arm/cpu_asm-v6.S
    trunk/sys/arm/arm/cpufunc.c
    trunk/sys/arm/arm/cpufunc_asm.S
    trunk/sys/arm/arm/cpufunc_asm_arm10.S
    trunk/sys/arm/arm/cpufunc_asm_arm11.S
    trunk/sys/arm/arm/cpufunc_asm_arm11x6.S
    trunk/sys/arm/arm/cpufunc_asm_arm9.S
    trunk/sys/arm/arm/cpufunc_asm_armv4.S
    trunk/sys/arm/arm/cpufunc_asm_armv5.S
    trunk/sys/arm/arm/cpufunc_asm_armv5_ec.S
    trunk/sys/arm/arm/cpufunc_asm_armv6.S
    trunk/sys/arm/arm/cpufunc_asm_armv7.S
    trunk/sys/arm/arm/cpufunc_asm_fa526.S
    trunk/sys/arm/arm/cpufunc_asm_pj4b.S
    trunk/sys/arm/arm/cpufunc_asm_sheeva.S
    trunk/sys/arm/arm/cpufunc_asm_xscale.S
    trunk/sys/arm/arm/cpufunc_asm_xscale_c3.S
    trunk/sys/arm/arm/cpuinfo.c
    trunk/sys/arm/arm/db_disasm.c
    trunk/sys/arm/arm/db_interface.c
    trunk/sys/arm/arm/db_trace.c
    trunk/sys/arm/arm/devmap.c
    trunk/sys/arm/arm/disassem.c
    trunk/sys/arm/arm/dump_machdep.c
    trunk/sys/arm/arm/elf_machdep.c
    trunk/sys/arm/arm/elf_trampoline.c
    trunk/sys/arm/arm/exception.S
    trunk/sys/arm/arm/fiq.c
    trunk/sys/arm/arm/fiq_subr.S
    trunk/sys/arm/arm/fusu.S
    trunk/sys/arm/arm/gdb_machdep.c
    trunk/sys/arm/arm/genassym.c
    trunk/sys/arm/arm/generic_timer.c
    trunk/sys/arm/arm/gic.c
    trunk/sys/arm/arm/identcpu.c
    trunk/sys/arm/arm/in_cksum.c
    trunk/sys/arm/arm/in_cksum_arm.S
    trunk/sys/arm/arm/inckern.S
    trunk/sys/arm/arm/intr.c
    trunk/sys/arm/arm/locore-v4.S
    trunk/sys/arm/arm/locore-v6.S
    trunk/sys/arm/arm/locore.S
    trunk/sys/arm/arm/machdep.c
    trunk/sys/arm/arm/mem.c
    trunk/sys/arm/arm/minidump_machdep.c
    trunk/sys/arm/arm/mp_machdep.c
    trunk/sys/arm/arm/mpcore_timer.c
    trunk/sys/arm/arm/mpcore_timervar.h
    trunk/sys/arm/arm/nexus.c
    trunk/sys/arm/arm/physmem.c
    trunk/sys/arm/arm/pl190.c
    trunk/sys/arm/arm/pl310.c
    trunk/sys/arm/arm/pmap-v6.c
    trunk/sys/arm/arm/pmap.c
    trunk/sys/arm/arm/sc_machdep.c
    trunk/sys/arm/arm/setcpsr.S
    trunk/sys/arm/arm/setstack.s
    trunk/sys/arm/arm/stack_machdep.c
    trunk/sys/arm/arm/stdatomic.c
    trunk/sys/arm/arm/support.S
    trunk/sys/arm/arm/swtch.S
    trunk/sys/arm/arm/sys_machdep.c
    trunk/sys/arm/arm/syscall.c
    trunk/sys/arm/arm/trap-v6.c
    trunk/sys/arm/arm/trap.c
    trunk/sys/arm/arm/uio_machdep.c
    trunk/sys/arm/arm/undefined.c
    trunk/sys/arm/arm/vfp.c
    trunk/sys/arm/arm/vm_machdep.c
    trunk/sys/arm/at91/
    trunk/sys/arm/at91/at91.c
    trunk/sys/arm/at91/at91_aic.c
    trunk/sys/arm/at91/at91_aicreg.h
    trunk/sys/arm/at91/at91_cfata.c
    trunk/sys/arm/at91/at91_gpio.h
    trunk/sys/arm/at91/at91_machdep.c
    trunk/sys/arm/at91/at91_mci.c
    trunk/sys/arm/at91/at91_mcireg.h
    trunk/sys/arm/at91/at91_pdcreg.h
    trunk/sys/arm/at91/at91_pinctrl.c
    trunk/sys/arm/at91/at91_pio.c
    trunk/sys/arm/at91/at91_pio_sam9g20.h
    trunk/sys/arm/at91/at91_pio_sam9g45.h
    trunk/sys/arm/at91/at91_pioreg.h
    trunk/sys/arm/at91/at91_piovar.h
    trunk/sys/arm/at91/at91_pit.c
    trunk/sys/arm/at91/at91_pitreg.h
    trunk/sys/arm/at91/at91_pmc.c
    trunk/sys/arm/at91/at91_pmcreg.h
    trunk/sys/arm/at91/at91_pmcvar.h
    trunk/sys/arm/at91/at91_reset.S
    trunk/sys/arm/at91/at91_rst.c
    trunk/sys/arm/at91/at91_rstreg.h
    trunk/sys/arm/at91/at91_rtc.c
    trunk/sys/arm/at91/at91_rtcreg.h
    trunk/sys/arm/at91/at91_sdramc.c
    trunk/sys/arm/at91/at91_shdwc.c
    trunk/sys/arm/at91/at91_smc.c
    trunk/sys/arm/at91/at91_smc.h
    trunk/sys/arm/at91/at91_spi.c
    trunk/sys/arm/at91/at91_spireg.h
    trunk/sys/arm/at91/at91_ssc.c
    trunk/sys/arm/at91/at91_sscreg.h
    trunk/sys/arm/at91/at91_st.c
    trunk/sys/arm/at91/at91_streg.h
    trunk/sys/arm/at91/at91_tcb.c
    trunk/sys/arm/at91/at91_twi.c
    trunk/sys/arm/at91/at91_twiio.h
    trunk/sys/arm/at91/at91_twireg.h
    trunk/sys/arm/at91/at91_usartreg.h
    trunk/sys/arm/at91/at91_wdt.c
    trunk/sys/arm/at91/at91_wdtreg.h
    trunk/sys/arm/at91/at91board.h
    trunk/sys/arm/at91/at91reg.h
    trunk/sys/arm/at91/at91rm9200.c
    trunk/sys/arm/at91/at91rm9200_devices.c
    trunk/sys/arm/at91/at91rm9200var.h
    trunk/sys/arm/at91/at91rm92reg.h
    trunk/sys/arm/at91/at91sam9260.c
    trunk/sys/arm/at91/at91sam9260reg.h
    trunk/sys/arm/at91/at91sam9g20.c
    trunk/sys/arm/at91/at91sam9g20reg.h
    trunk/sys/arm/at91/at91sam9g45.c
    trunk/sys/arm/at91/at91sam9g45reg.h
    trunk/sys/arm/at91/at91sam9x5.c
    trunk/sys/arm/at91/at91sam9x5reg.h
    trunk/sys/arm/at91/at91soc.c
    trunk/sys/arm/at91/at91soc.h
    trunk/sys/arm/at91/at91var.h
    trunk/sys/arm/at91/board_bwct.c
    trunk/sys/arm/at91/board_eb9200.c
    trunk/sys/arm/at91/board_ethernut5.c
    trunk/sys/arm/at91/board_hl200.c
    trunk/sys/arm/at91/board_hl201.c
    trunk/sys/arm/at91/board_kb920x.c
    trunk/sys/arm/at91/board_qila9g20.c
    trunk/sys/arm/at91/board_sam9260ek.c
    trunk/sys/arm/at91/board_sam9g20ek.c
    trunk/sys/arm/at91/board_sam9x25ek.c
    trunk/sys/arm/at91/board_sn9g45.c
    trunk/sys/arm/at91/board_tsc4370.c
    trunk/sys/arm/at91/files.at91
    trunk/sys/arm/at91/if_ate.c
    trunk/sys/arm/at91/if_atereg.h
    trunk/sys/arm/at91/if_macb.c
    trunk/sys/arm/at91/if_macbreg.h
    trunk/sys/arm/at91/if_macbvar.h
    trunk/sys/arm/at91/std.at91
    trunk/sys/arm/at91/std.at91sam9
    trunk/sys/arm/at91/std.at91sam9g45
    trunk/sys/arm/at91/std.atmel
    trunk/sys/arm/at91/std.bwct
    trunk/sys/arm/at91/std.eb9200
    trunk/sys/arm/at91/std.ethernut5
    trunk/sys/arm/at91/std.hl200
    trunk/sys/arm/at91/std.hl201
    trunk/sys/arm/at91/std.kb920x
    trunk/sys/arm/at91/std.qila9g20
    trunk/sys/arm/at91/std.sam9260ek
    trunk/sys/arm/at91/std.sam9g20ek
    trunk/sys/arm/at91/std.sam9x25ek
    trunk/sys/arm/at91/std.sn9g45
    trunk/sys/arm/at91/std.tsc4370
    trunk/sys/arm/at91/uart_bus_at91usart.c
    trunk/sys/arm/at91/uart_cpu_at91usart.c
    trunk/sys/arm/at91/uart_dev_at91usart.c
    trunk/sys/arm/broadcom/
    trunk/sys/arm/broadcom/bcm2835/
    trunk/sys/arm/broadcom/bcm2835/bcm2835_bsc.c
    trunk/sys/arm/broadcom/bcm2835/bcm2835_bscreg.h
    trunk/sys/arm/broadcom/bcm2835/bcm2835_bscvar.h
    trunk/sys/arm/broadcom/bcm2835/bcm2835_common.c
    trunk/sys/arm/broadcom/bcm2835/bcm2835_cpufreq.c
    trunk/sys/arm/broadcom/bcm2835/bcm2835_dma.c
    trunk/sys/arm/broadcom/bcm2835/bcm2835_dma.h
    trunk/sys/arm/broadcom/bcm2835/bcm2835_fb.c
    trunk/sys/arm/broadcom/bcm2835/bcm2835_fbd.c
    trunk/sys/arm/broadcom/bcm2835/bcm2835_gpio.c
    trunk/sys/arm/broadcom/bcm2835/bcm2835_gpio.h
    trunk/sys/arm/broadcom/bcm2835/bcm2835_intr.c
    trunk/sys/arm/broadcom/bcm2835/bcm2835_machdep.c
    trunk/sys/arm/broadcom/bcm2835/bcm2835_mbox.c
    trunk/sys/arm/broadcom/bcm2835/bcm2835_mbox.h
    trunk/sys/arm/broadcom/bcm2835/bcm2835_mbox_prop.h
    trunk/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c
    trunk/sys/arm/broadcom/bcm2835/bcm2835_spi.c
    trunk/sys/arm/broadcom/bcm2835/bcm2835_spireg.h
    trunk/sys/arm/broadcom/bcm2835/bcm2835_spivar.h
    trunk/sys/arm/broadcom/bcm2835/bcm2835_systimer.c
    trunk/sys/arm/broadcom/bcm2835/bcm2835_vcbus.h
    trunk/sys/arm/broadcom/bcm2835/bcm2835_wdog.c
    trunk/sys/arm/broadcom/bcm2835/bcm2835_wdog.h
    trunk/sys/arm/broadcom/bcm2835/bcm2836.c
    trunk/sys/arm/broadcom/bcm2835/bcm2836.h
    trunk/sys/arm/broadcom/bcm2835/bcm283x_dwc_fdt.c
    trunk/sys/arm/broadcom/bcm2835/files.bcm2835
    trunk/sys/arm/broadcom/bcm2835/files.bcm2836
    trunk/sys/arm/broadcom/bcm2835/std.bcm2835
    trunk/sys/arm/broadcom/bcm2835/std.bcm2836
    trunk/sys/arm/broadcom/bcm2835/std.rpi
    trunk/sys/arm/cavium/
    trunk/sys/arm/cavium/cns11xx/
    trunk/sys/arm/cavium/cns11xx/cfi_bus_econa.c
    trunk/sys/arm/cavium/cns11xx/econa.c
    trunk/sys/arm/cavium/cns11xx/econa_machdep.c
    trunk/sys/arm/cavium/cns11xx/econa_reg.h
    trunk/sys/arm/cavium/cns11xx/econa_var.h
    trunk/sys/arm/cavium/cns11xx/ehci_ebus.c
    trunk/sys/arm/cavium/cns11xx/files.econa
    trunk/sys/arm/cavium/cns11xx/if_ece.c
    trunk/sys/arm/cavium/cns11xx/if_ecereg.h
    trunk/sys/arm/cavium/cns11xx/if_ecevar.h
    trunk/sys/arm/cavium/cns11xx/ohci_ec.c
    trunk/sys/arm/cavium/cns11xx/std.econa
    trunk/sys/arm/cavium/cns11xx/timer.c
    trunk/sys/arm/cavium/cns11xx/uart_bus_ec.c
    trunk/sys/arm/cavium/cns11xx/uart_cpu_ec.c
    trunk/sys/arm/compile/
    trunk/sys/arm/conf/
    trunk/sys/arm/conf/APALIS-IMX6
    trunk/sys/arm/conf/ARMADAXP
    trunk/sys/arm/conf/ARNDALE
    trunk/sys/arm/conf/ARNDALE-OCTA
    trunk/sys/arm/conf/ATMEL
    trunk/sys/arm/conf/AVILA
    trunk/sys/arm/conf/AVILA.hints
    trunk/sys/arm/conf/BEAGLEBONE
    trunk/sys/arm/conf/BWCT
    trunk/sys/arm/conf/BWCT.hints
    trunk/sys/arm/conf/CAMBRIA
    trunk/sys/arm/conf/CAMBRIA.hints
    trunk/sys/arm/conf/CHROMEBOOK
    trunk/sys/arm/conf/CHROMEBOOK.hints
    trunk/sys/arm/conf/CNS11XXNAS
    trunk/sys/arm/conf/COLIBRI-VF50
    trunk/sys/arm/conf/COSMIC
    trunk/sys/arm/conf/CRB
    trunk/sys/arm/conf/CUBIEBOARD
    trunk/sys/arm/conf/CUBIEBOARD2
    trunk/sys/arm/conf/DB-78XXX
    trunk/sys/arm/conf/DB-88F5XXX
    trunk/sys/arm/conf/DB-88F6XXX
    trunk/sys/arm/conf/DEFAULTS
    trunk/sys/arm/conf/DIGI-CCWMX53
    trunk/sys/arm/conf/DOCKSTAR
    trunk/sys/arm/conf/DREAMPLUG-1001
    trunk/sys/arm/conf/EA3250
    trunk/sys/arm/conf/EA3250.hints
    trunk/sys/arm/conf/EB9200
    trunk/sys/arm/conf/EB9200.hints
    trunk/sys/arm/conf/EFIKA_MX
    trunk/sys/arm/conf/EP80219
    trunk/sys/arm/conf/ETHERNUT5
    trunk/sys/arm/conf/ETHERNUT5.hints
    trunk/sys/arm/conf/EXYNOS5.common
    trunk/sys/arm/conf/EXYNOS5250
    trunk/sys/arm/conf/EXYNOS5250.common
    trunk/sys/arm/conf/EXYNOS5420
    trunk/sys/arm/conf/GUMSTIX
    trunk/sys/arm/conf/GUMSTIX-QEMU
    trunk/sys/arm/conf/GUMSTIX.hints
    trunk/sys/arm/conf/HL200
    trunk/sys/arm/conf/HL201
    trunk/sys/arm/conf/HL201.hints
    trunk/sys/arm/conf/IMX53
    trunk/sys/arm/conf/IMX53-QSB
    trunk/sys/arm/conf/IMX6
    trunk/sys/arm/conf/IQ31244
    trunk/sys/arm/conf/KB920X
    trunk/sys/arm/conf/KB920X.hints
    trunk/sys/arm/conf/LN2410SBC
    trunk/sys/arm/conf/Makefile
    trunk/sys/arm/conf/NOTES
    trunk/sys/arm/conf/NSLU
    trunk/sys/arm/conf/NSLU.hints
    trunk/sys/arm/conf/PANDABOARD
    trunk/sys/arm/conf/PANDABOARD.hints
    trunk/sys/arm/conf/QILA9G20
    trunk/sys/arm/conf/QILA9G20.hints
    trunk/sys/arm/conf/QUARTZ
    trunk/sys/arm/conf/RADXA
    trunk/sys/arm/conf/RPI-B
    trunk/sys/arm/conf/SAM9260EK
    trunk/sys/arm/conf/SAM9260EK.hints
    trunk/sys/arm/conf/SAM9G20EK
    trunk/sys/arm/conf/SAM9G20EK.hints
    trunk/sys/arm/conf/SAM9X25EK
    trunk/sys/arm/conf/SAM9X25EK.hints
    trunk/sys/arm/conf/SHEEVAPLUG
    trunk/sys/arm/conf/SN9G45
    trunk/sys/arm/conf/TS7800
    trunk/sys/arm/conf/VERSATILEPB
    trunk/sys/arm/conf/VYBRID
    trunk/sys/arm/conf/ZEDBOARD
    trunk/sys/arm/conf/genboardid.awk
    trunk/sys/arm/conf/mach-types
    trunk/sys/arm/freescale/
    trunk/sys/arm/freescale/fsl_ocotp.c
    trunk/sys/arm/freescale/fsl_ocotpreg.h
    trunk/sys/arm/freescale/fsl_ocotpvar.h
    trunk/sys/arm/freescale/imx/
    trunk/sys/arm/freescale/imx/console.c
    trunk/sys/arm/freescale/imx/files.imx51
    trunk/sys/arm/freescale/imx/files.imx53
    trunk/sys/arm/freescale/imx/files.imx6
    trunk/sys/arm/freescale/imx/imx51_ccm.c
    trunk/sys/arm/freescale/imx/imx51_ccmreg.h
    trunk/sys/arm/freescale/imx/imx51_ccmvar.h
    trunk/sys/arm/freescale/imx/imx51_dpllreg.h
    trunk/sys/arm/freescale/imx/imx51_ipuv3.c
    trunk/sys/arm/freescale/imx/imx51_ipuv3_fbd.c
    trunk/sys/arm/freescale/imx/imx51_ipuv3reg.h
    trunk/sys/arm/freescale/imx/imx51_machdep.c
    trunk/sys/arm/freescale/imx/imx51_sdmareg.h
    trunk/sys/arm/freescale/imx/imx51_ssireg.h
    trunk/sys/arm/freescale/imx/imx51_tzicreg.h
    trunk/sys/arm/freescale/imx/imx53_machdep.c
    trunk/sys/arm/freescale/imx/imx6_anatop.c
    trunk/sys/arm/freescale/imx/imx6_anatopreg.h
    trunk/sys/arm/freescale/imx/imx6_anatopvar.h
    trunk/sys/arm/freescale/imx/imx6_audmux.c
    trunk/sys/arm/freescale/imx/imx6_ccm.c
    trunk/sys/arm/freescale/imx/imx6_ccmreg.h
    trunk/sys/arm/freescale/imx/imx6_machdep.c
    trunk/sys/arm/freescale/imx/imx6_mp.c
    trunk/sys/arm/freescale/imx/imx6_pl310.c
    trunk/sys/arm/freescale/imx/imx6_sdma.c
    trunk/sys/arm/freescale/imx/imx6_sdma.h
    trunk/sys/arm/freescale/imx/imx6_ssi.c
    trunk/sys/arm/freescale/imx/imx6_usbphy.c
    trunk/sys/arm/freescale/imx/imx_ccmvar.h
    trunk/sys/arm/freescale/imx/imx_common.c
    trunk/sys/arm/freescale/imx/imx_gpio.c
    trunk/sys/arm/freescale/imx/imx_gpt.c
    trunk/sys/arm/freescale/imx/imx_gptreg.h
    trunk/sys/arm/freescale/imx/imx_gptvar.h
    trunk/sys/arm/freescale/imx/imx_i2c.c
    trunk/sys/arm/freescale/imx/imx_iomux.c
    trunk/sys/arm/freescale/imx/imx_iomuxvar.h
    trunk/sys/arm/freescale/imx/imx_machdep.c
    trunk/sys/arm/freescale/imx/imx_machdep.h
    trunk/sys/arm/freescale/imx/imx_nop_usbphy.c
    trunk/sys/arm/freescale/imx/imx_sdhci.c
    trunk/sys/arm/freescale/imx/imx_wdog.c
    trunk/sys/arm/freescale/imx/imx_wdogreg.h
    trunk/sys/arm/freescale/imx/std.imx51
    trunk/sys/arm/freescale/imx/std.imx53
    trunk/sys/arm/freescale/imx/std.imx6
    trunk/sys/arm/freescale/imx/tzic.c
    trunk/sys/arm/freescale/vybrid/
    trunk/sys/arm/freescale/vybrid/files.vybrid
    trunk/sys/arm/freescale/vybrid/std.vybrid
    trunk/sys/arm/freescale/vybrid/vf_anadig.c
    trunk/sys/arm/freescale/vybrid/vf_ccm.c
    trunk/sys/arm/freescale/vybrid/vf_common.c
    trunk/sys/arm/freescale/vybrid/vf_common.h
    trunk/sys/arm/freescale/vybrid/vf_dcu4.c
    trunk/sys/arm/freescale/vybrid/vf_dmamux.c
    trunk/sys/arm/freescale/vybrid/vf_dmamux.h
    trunk/sys/arm/freescale/vybrid/vf_edma.c
    trunk/sys/arm/freescale/vybrid/vf_edma.h
    trunk/sys/arm/freescale/vybrid/vf_ehci.c
    trunk/sys/arm/freescale/vybrid/vf_gpio.c
    trunk/sys/arm/freescale/vybrid/vf_i2c.c
    trunk/sys/arm/freescale/vybrid/vf_iomuxc.c
    trunk/sys/arm/freescale/vybrid/vf_iomuxc.h
    trunk/sys/arm/freescale/vybrid/vf_machdep.c
    trunk/sys/arm/freescale/vybrid/vf_mscm.c
    trunk/sys/arm/freescale/vybrid/vf_nfc.c
    trunk/sys/arm/freescale/vybrid/vf_port.c
    trunk/sys/arm/freescale/vybrid/vf_port.h
    trunk/sys/arm/freescale/vybrid/vf_sai.c
    trunk/sys/arm/freescale/vybrid/vf_src.c
    trunk/sys/arm/freescale/vybrid/vf_src.h
    trunk/sys/arm/freescale/vybrid/vf_tcon.c
    trunk/sys/arm/freescale/vybrid/vf_uart.c
    trunk/sys/arm/include/
    trunk/sys/arm/include/_align.h
    trunk/sys/arm/include/_bus.h
    trunk/sys/arm/include/_inttypes.h
    trunk/sys/arm/include/_limits.h
    trunk/sys/arm/include/_stdint.h
    trunk/sys/arm/include/_types.h
    trunk/sys/arm/include/acle-compat.h
    trunk/sys/arm/include/armreg.h
    trunk/sys/arm/include/asm.h
    trunk/sys/arm/include/asmacros.h
    trunk/sys/arm/include/at91_gpio.h
    trunk/sys/arm/include/atags.h
    trunk/sys/arm/include/atomic.h
    trunk/sys/arm/include/blockio.h
    trunk/sys/arm/include/board.h
    trunk/sys/arm/include/bootconfig.h
    trunk/sys/arm/include/bus.h
    trunk/sys/arm/include/bus_dma.h
    trunk/sys/arm/include/clock.h
    trunk/sys/arm/include/counter.h
    trunk/sys/arm/include/cpu-v6.h
    trunk/sys/arm/include/cpu.h
    trunk/sys/arm/include/cpuconf.h
    trunk/sys/arm/include/cpufunc.h
    trunk/sys/arm/include/cpuinfo.h
    trunk/sys/arm/include/db_machdep.h
    trunk/sys/arm/include/devmap.h
    trunk/sys/arm/include/disassem.h
    trunk/sys/arm/include/elf.h
    trunk/sys/arm/include/endian.h
    trunk/sys/arm/include/exec.h
    trunk/sys/arm/include/fdt.h
    trunk/sys/arm/include/fiq.h
    trunk/sys/arm/include/float.h
    trunk/sys/arm/include/floatingpoint.h
    trunk/sys/arm/include/fp.h
    trunk/sys/arm/include/frame.h
    trunk/sys/arm/include/gdb_machdep.h
    trunk/sys/arm/include/ieee.h
    trunk/sys/arm/include/ieeefp.h
    trunk/sys/arm/include/in_cksum.h
    trunk/sys/arm/include/intr.h
    trunk/sys/arm/include/katelib.h
    trunk/sys/arm/include/kdb.h
    trunk/sys/arm/include/limits.h
    trunk/sys/arm/include/machdep.h
    trunk/sys/arm/include/md_var.h
    trunk/sys/arm/include/memdev.h
    trunk/sys/arm/include/metadata.h
    trunk/sys/arm/include/minidump.h
    trunk/sys/arm/include/ofw_machdep.h
    trunk/sys/arm/include/param.h
    trunk/sys/arm/include/pcb.h
    trunk/sys/arm/include/pcpu.h
    trunk/sys/arm/include/physmem.h
    trunk/sys/arm/include/pl310.h
    trunk/sys/arm/include/pmap.h
    trunk/sys/arm/include/pmc_mdep.h
    trunk/sys/arm/include/proc.h
    trunk/sys/arm/include/profile.h
    trunk/sys/arm/include/psl.h
    trunk/sys/arm/include/pte.h
    trunk/sys/arm/include/ptrace.h
    trunk/sys/arm/include/reg.h
    trunk/sys/arm/include/reloc.h
    trunk/sys/arm/include/resource.h
    trunk/sys/arm/include/runq.h
    trunk/sys/arm/include/sc_machdep.h
    trunk/sys/arm/include/setjmp.h
    trunk/sys/arm/include/sf_buf.h
    trunk/sys/arm/include/sigframe.h
    trunk/sys/arm/include/signal.h
    trunk/sys/arm/include/smp.h
    trunk/sys/arm/include/stack.h
    trunk/sys/arm/include/stdarg.h
    trunk/sys/arm/include/swi.h
    trunk/sys/arm/include/sysarch.h
    trunk/sys/arm/include/sysreg.h
    trunk/sys/arm/include/trap.h
    trunk/sys/arm/include/ucontext.h
    trunk/sys/arm/include/undefined.h
    trunk/sys/arm/include/utrap.h
    trunk/sys/arm/include/vdso.h
    trunk/sys/arm/include/vfp.h
    trunk/sys/arm/include/vm.h
    trunk/sys/arm/include/vmparam.h
    trunk/sys/arm/lpc/
    trunk/sys/arm/lpc/files.lpc
    trunk/sys/arm/lpc/if_lpe.c
    trunk/sys/arm/lpc/if_lpereg.h
    trunk/sys/arm/lpc/lpc_dmac.c
    trunk/sys/arm/lpc/lpc_fb.c
    trunk/sys/arm/lpc/lpc_gpio.c
    trunk/sys/arm/lpc/lpc_intc.c
    trunk/sys/arm/lpc/lpc_machdep.c
    trunk/sys/arm/lpc/lpc_mmc.c
    trunk/sys/arm/lpc/lpc_ohci.c
    trunk/sys/arm/lpc/lpc_pll.c
    trunk/sys/arm/lpc/lpc_pwr.c
    trunk/sys/arm/lpc/lpc_rtc.c
    trunk/sys/arm/lpc/lpc_spi.c
    trunk/sys/arm/lpc/lpc_timer.c
    trunk/sys/arm/lpc/lpcreg.h
    trunk/sys/arm/lpc/lpcvar.h
    trunk/sys/arm/lpc/ssd1289.c
    trunk/sys/arm/lpc/std.lpc
    trunk/sys/arm/mv/
    trunk/sys/arm/mv/armadaxp/
    trunk/sys/arm/mv/armadaxp/armadaxp.c
    trunk/sys/arm/mv/armadaxp/armadaxp_mp.c
    trunk/sys/arm/mv/armadaxp/files.armadaxp
    trunk/sys/arm/mv/armadaxp/mptramp.S
    trunk/sys/arm/mv/armadaxp/std.armadaxp
    trunk/sys/arm/mv/armadaxp/std.mv78x60
    trunk/sys/arm/mv/discovery/
    trunk/sys/arm/mv/discovery/discovery.c
    trunk/sys/arm/mv/discovery/files.db78xxx
    trunk/sys/arm/mv/discovery/std.db78xxx
    trunk/sys/arm/mv/files.mv
    trunk/sys/arm/mv/gpio.c
    trunk/sys/arm/mv/ic.c
    trunk/sys/arm/mv/kirkwood/
    trunk/sys/arm/mv/kirkwood/files.kirkwood
    trunk/sys/arm/mv/kirkwood/kirkwood.c
    trunk/sys/arm/mv/kirkwood/std.db88f6xxx
    trunk/sys/arm/mv/kirkwood/std.kirkwood
    trunk/sys/arm/mv/mpic.c
    trunk/sys/arm/mv/mv_common.c
    trunk/sys/arm/mv/mv_localbus.c
    trunk/sys/arm/mv/mv_machdep.c
    trunk/sys/arm/mv/mv_pci.c
    trunk/sys/arm/mv/mv_ts.c
    trunk/sys/arm/mv/mvreg.h
    trunk/sys/arm/mv/mvvar.h
    trunk/sys/arm/mv/mvwin.h
    trunk/sys/arm/mv/orion/
    trunk/sys/arm/mv/orion/db88f5xxx.c
    trunk/sys/arm/mv/orion/files.db88f5xxx
    trunk/sys/arm/mv/orion/files.ts7800
    trunk/sys/arm/mv/orion/orion.c
    trunk/sys/arm/mv/orion/std.db88f5xxx
    trunk/sys/arm/mv/orion/std.ts7800
    trunk/sys/arm/mv/rtc.c
    trunk/sys/arm/mv/std-pj4b.mv
    trunk/sys/arm/mv/std.mv
    trunk/sys/arm/mv/timer.c
    trunk/sys/arm/mv/twsi.c
    trunk/sys/arm/rockchip/
    trunk/sys/arm/rockchip/files.rk30xx
    trunk/sys/arm/rockchip/rk30xx_common.c
    trunk/sys/arm/rockchip/rk30xx_gpio.c
    trunk/sys/arm/rockchip/rk30xx_grf.c
    trunk/sys/arm/rockchip/rk30xx_grf.h
    trunk/sys/arm/rockchip/rk30xx_machdep.c
    trunk/sys/arm/rockchip/rk30xx_mp.c
    trunk/sys/arm/rockchip/rk30xx_pmu.c
    trunk/sys/arm/rockchip/rk30xx_pmu.h
    trunk/sys/arm/rockchip/rk30xx_wdog.c
    trunk/sys/arm/rockchip/rk30xx_wdog.h
    trunk/sys/arm/rockchip/std.rk30xx
    trunk/sys/arm/samsung/
    trunk/sys/arm/samsung/exynos/
    trunk/sys/arm/samsung/exynos/chrome_ec.c
    trunk/sys/arm/samsung/exynos/chrome_ec.h
    trunk/sys/arm/samsung/exynos/chrome_kb.c
    trunk/sys/arm/samsung/exynos/chrome_kb.h
    trunk/sys/arm/samsung/exynos/exynos5_combiner.c
    trunk/sys/arm/samsung/exynos/exynos5_combiner.h
    trunk/sys/arm/samsung/exynos/exynos5_common.c
    trunk/sys/arm/samsung/exynos/exynos5_common.h
    trunk/sys/arm/samsung/exynos/exynos5_ehci.c
    trunk/sys/arm/samsung/exynos/exynos5_fimd.c
    trunk/sys/arm/samsung/exynos/exynos5_i2c.c
    trunk/sys/arm/samsung/exynos/exynos5_machdep.c
    trunk/sys/arm/samsung/exynos/exynos5_mct.c
    trunk/sys/arm/samsung/exynos/exynos5_mp.c
    trunk/sys/arm/samsung/exynos/exynos5_pad.c
    trunk/sys/arm/samsung/exynos/exynos5_pad.h
    trunk/sys/arm/samsung/exynos/exynos_uart.c
    trunk/sys/arm/samsung/exynos/exynos_uart.h
    trunk/sys/arm/samsung/exynos/files.exynos5
    trunk/sys/arm/samsung/exynos/std.exynos5250
    trunk/sys/arm/samsung/exynos/std.exynos5420
    trunk/sys/arm/samsung/s3c2xx0/
    trunk/sys/arm/samsung/s3c2xx0/board_ln2410sbc.c
    trunk/sys/arm/samsung/s3c2xx0/files.s3c2xx0
    trunk/sys/arm/samsung/s3c2xx0/s3c2410reg.h
    trunk/sys/arm/samsung/s3c2xx0/s3c2410var.h
    trunk/sys/arm/samsung/s3c2xx0/s3c2440reg.h
    trunk/sys/arm/samsung/s3c2xx0/s3c24x0.c
    trunk/sys/arm/samsung/s3c2xx0/s3c24x0_clk.c
    trunk/sys/arm/samsung/s3c2xx0/s3c24x0_machdep.c
    trunk/sys/arm/samsung/s3c2xx0/s3c24x0_rtc.c
    trunk/sys/arm/samsung/s3c2xx0/s3c24x0reg.h
    trunk/sys/arm/samsung/s3c2xx0/s3c24x0var.h
    trunk/sys/arm/samsung/s3c2xx0/s3c2xx0board.h
    trunk/sys/arm/samsung/s3c2xx0/s3c2xx0reg.h
    trunk/sys/arm/samsung/s3c2xx0/s3c2xx0var.h
    trunk/sys/arm/samsung/s3c2xx0/std.ln2410sbc
    trunk/sys/arm/samsung/s3c2xx0/std.s3c2410
    trunk/sys/arm/samsung/s3c2xx0/uart_bus_s3c2410.c
    trunk/sys/arm/samsung/s3c2xx0/uart_cpu_s3c2410.c
    trunk/sys/arm/samsung/s3c2xx0/uart_dev_s3c2410.c
    trunk/sys/arm/samsung/s3c2xx0/uart_dev_s3c2410.h
    trunk/sys/arm/ti/
    trunk/sys/arm/ti/aintc.c
    trunk/sys/arm/ti/am335x/
    trunk/sys/arm/ti/am335x/am335x_dmtimer.c
    trunk/sys/arm/ti/am335x/am335x_lcd.c
    trunk/sys/arm/ti/am335x/am335x_lcd.h
    trunk/sys/arm/ti/am335x/am335x_lcd_syscons.c
    trunk/sys/arm/ti/am335x/am335x_pmic.c
    trunk/sys/arm/ti/am335x/am335x_prcm.c
    trunk/sys/arm/ti/am335x/am335x_pwm.c
    trunk/sys/arm/ti/am335x/am335x_pwm.h
    trunk/sys/arm/ti/am335x/am335x_reg.h
    trunk/sys/arm/ti/am335x/am335x_rtc.c
    trunk/sys/arm/ti/am335x/am335x_rtcreg.h
    trunk/sys/arm/ti/am335x/am335x_rtcvar.h
    trunk/sys/arm/ti/am335x/am335x_scm.h
    trunk/sys/arm/ti/am335x/am335x_scm_padconf.c
    trunk/sys/arm/ti/am335x/am335x_usbss.c
    trunk/sys/arm/ti/am335x/files.am335x
    trunk/sys/arm/ti/am335x/std.am335x
    trunk/sys/arm/ti/cpsw/
    trunk/sys/arm/ti/cpsw/if_cpsw.c
    trunk/sys/arm/ti/cpsw/if_cpswreg.h
    trunk/sys/arm/ti/cpsw/if_cpswvar.h
    trunk/sys/arm/ti/files.ti
    trunk/sys/arm/ti/omap3/
    trunk/sys/arm/ti/omap3/omap3_reg.h
    trunk/sys/arm/ti/omap4/
    trunk/sys/arm/ti/omap4/files.omap4
    trunk/sys/arm/ti/omap4/omap4_l2cache.c
    trunk/sys/arm/ti/omap4/omap4_mp.c
    trunk/sys/arm/ti/omap4/omap4_prcm_clks.c
    trunk/sys/arm/ti/omap4/omap4_reg.h
    trunk/sys/arm/ti/omap4/omap4_scm_padconf.c
    trunk/sys/arm/ti/omap4/omap4_smc.h
    trunk/sys/arm/ti/omap4/omap4var.h
    trunk/sys/arm/ti/omap4/pandaboard/
    trunk/sys/arm/ti/omap4/pandaboard/files.pandaboard
    trunk/sys/arm/ti/omap4/pandaboard/pandaboard.c
    trunk/sys/arm/ti/omap4/pandaboard/std.pandaboard
    trunk/sys/arm/ti/omap4/std.omap4
    trunk/sys/arm/ti/std.ti
    trunk/sys/arm/ti/ti_adc.c
    trunk/sys/arm/ti/ti_adcreg.h
    trunk/sys/arm/ti/ti_adcvar.h
    trunk/sys/arm/ti/ti_common.c
    trunk/sys/arm/ti/ti_cpuid.c
    trunk/sys/arm/ti/ti_cpuid.h
    trunk/sys/arm/ti/ti_edma3.c
    trunk/sys/arm/ti/ti_edma3.h
    trunk/sys/arm/ti/ti_gpio.c
    trunk/sys/arm/ti/ti_i2c.c
    trunk/sys/arm/ti/ti_i2c.h
    trunk/sys/arm/ti/ti_machdep.c
    trunk/sys/arm/ti/ti_mbox.c
    trunk/sys/arm/ti/ti_mbox.h
    trunk/sys/arm/ti/ti_mmchs.c
    trunk/sys/arm/ti/ti_mmchs.h
    trunk/sys/arm/ti/ti_prcm.c
    trunk/sys/arm/ti/ti_prcm.h
    trunk/sys/arm/ti/ti_pruss.c
    trunk/sys/arm/ti/ti_pruss.h
    trunk/sys/arm/ti/ti_scm.c
    trunk/sys/arm/ti/ti_scm.h
    trunk/sys/arm/ti/ti_sdhci.c
    trunk/sys/arm/ti/ti_sdma.c
    trunk/sys/arm/ti/ti_sdma.h
    trunk/sys/arm/ti/ti_sdmareg.h
    trunk/sys/arm/ti/ti_smc.S
    trunk/sys/arm/ti/ti_smc.h
    trunk/sys/arm/ti/ti_wdt.c
    trunk/sys/arm/ti/ti_wdt.h
    trunk/sys/arm/ti/tivar.h
    trunk/sys/arm/ti/twl/
    trunk/sys/arm/ti/twl/twl.c
    trunk/sys/arm/ti/twl/twl.h
    trunk/sys/arm/ti/twl/twl_clks.c
    trunk/sys/arm/ti/twl/twl_clks.h
    trunk/sys/arm/ti/twl/twl_vreg.c
    trunk/sys/arm/ti/twl/twl_vreg.h
    trunk/sys/arm/ti/usb/
    trunk/sys/arm/ti/usb/omap_ehci.c
    trunk/sys/arm/ti/usb/omap_usb.h
    trunk/sys/arm/versatile/
    trunk/sys/arm/versatile/files.versatile
    trunk/sys/arm/versatile/if_smc_fdt.c
    trunk/sys/arm/versatile/pl050.c
    trunk/sys/arm/versatile/sp804.c
    trunk/sys/arm/versatile/versatile_clcd.c
    trunk/sys/arm/versatile/versatile_common.c
    trunk/sys/arm/versatile/versatile_machdep.c
    trunk/sys/arm/versatile/versatile_pci.c
    trunk/sys/arm/versatile/versatile_sic.c
    trunk/sys/arm/versatile/versatile_timer.c
    trunk/sys/arm/xilinx/
    trunk/sys/arm/xilinx/files.zynq7
    trunk/sys/arm/xilinx/std.zynq7
    trunk/sys/arm/xilinx/uart_dev_cdnc.c
    trunk/sys/arm/xilinx/zedboard/
    trunk/sys/arm/xilinx/zedboard/files.zedboard
    trunk/sys/arm/xilinx/zedboard/std.zedboard
    trunk/sys/arm/xilinx/zy7_devcfg.c
    trunk/sys/arm/xilinx/zy7_ehci.c
    trunk/sys/arm/xilinx/zy7_gpio.c
    trunk/sys/arm/xilinx/zy7_l2cache.c
    trunk/sys/arm/xilinx/zy7_machdep.c
    trunk/sys/arm/xilinx/zy7_mp.c
    trunk/sys/arm/xilinx/zy7_reg.h
    trunk/sys/arm/xilinx/zy7_slcr.c
    trunk/sys/arm/xilinx/zy7_slcr.h
    trunk/sys/arm/xscale/
    trunk/sys/arm/xscale/i80321/
    trunk/sys/arm/xscale/i80321/ep80219_machdep.c
    trunk/sys/arm/xscale/i80321/files.ep80219
    trunk/sys/arm/xscale/i80321/files.i80219
    trunk/sys/arm/xscale/i80321/files.i80321
    trunk/sys/arm/xscale/i80321/files.iq31244
    trunk/sys/arm/xscale/i80321/i80321.c
    trunk/sys/arm/xscale/i80321/i80321_aau.c
    trunk/sys/arm/xscale/i80321/i80321_dma.c
    trunk/sys/arm/xscale/i80321/i80321_intr.h
    trunk/sys/arm/xscale/i80321/i80321_mcu.c
    trunk/sys/arm/xscale/i80321/i80321_pci.c
    trunk/sys/arm/xscale/i80321/i80321_space.c
    trunk/sys/arm/xscale/i80321/i80321_timer.c
    trunk/sys/arm/xscale/i80321/i80321_wdog.c
    trunk/sys/arm/xscale/i80321/i80321reg.h
    trunk/sys/arm/xscale/i80321/i80321var.h
    trunk/sys/arm/xscale/i80321/iq31244_7seg.c
    trunk/sys/arm/xscale/i80321/iq31244_machdep.c
    trunk/sys/arm/xscale/i80321/iq80321.c
    trunk/sys/arm/xscale/i80321/iq80321reg.h
    trunk/sys/arm/xscale/i80321/iq80321var.h
    trunk/sys/arm/xscale/i80321/obio.c
    trunk/sys/arm/xscale/i80321/obiovar.h
    trunk/sys/arm/xscale/i80321/std.ep80219
    trunk/sys/arm/xscale/i80321/std.i80219
    trunk/sys/arm/xscale/i80321/std.i80321
    trunk/sys/arm/xscale/i80321/std.iq31244
    trunk/sys/arm/xscale/i80321/uart_bus_i80321.c
    trunk/sys/arm/xscale/i80321/uart_cpu_i80321.c
    trunk/sys/arm/xscale/i8134x/
    trunk/sys/arm/xscale/i8134x/crb_machdep.c
    trunk/sys/arm/xscale/i8134x/files.crb
    trunk/sys/arm/xscale/i8134x/files.i81342
    trunk/sys/arm/xscale/i8134x/i81342.c
    trunk/sys/arm/xscale/i8134x/i81342_mcu.c
    trunk/sys/arm/xscale/i8134x/i81342_pci.c
    trunk/sys/arm/xscale/i8134x/i81342_space.c
    trunk/sys/arm/xscale/i8134x/i81342reg.h
    trunk/sys/arm/xscale/i8134x/i81342var.h
    trunk/sys/arm/xscale/i8134x/iq81342_7seg.c
    trunk/sys/arm/xscale/i8134x/iq81342reg.h
    trunk/sys/arm/xscale/i8134x/iq81342var.h
    trunk/sys/arm/xscale/i8134x/obio.c
    trunk/sys/arm/xscale/i8134x/obiovar.h
    trunk/sys/arm/xscale/i8134x/std.crb
    trunk/sys/arm/xscale/i8134x/std.i81342
    trunk/sys/arm/xscale/i8134x/uart_bus_i81342.c
    trunk/sys/arm/xscale/i8134x/uart_cpu_i81342.c
    trunk/sys/arm/xscale/ixp425/
    trunk/sys/arm/xscale/ixp425/avila_ata.c
    trunk/sys/arm/xscale/ixp425/avila_gpio.c
    trunk/sys/arm/xscale/ixp425/avila_led.c
    trunk/sys/arm/xscale/ixp425/avila_machdep.c
    trunk/sys/arm/xscale/ixp425/cambria_exp_space.c
    trunk/sys/arm/xscale/ixp425/cambria_fled.c
    trunk/sys/arm/xscale/ixp425/cambria_gpio.c
    trunk/sys/arm/xscale/ixp425/cambria_led.c
    trunk/sys/arm/xscale/ixp425/files.avila
    trunk/sys/arm/xscale/ixp425/files.ixp425
    trunk/sys/arm/xscale/ixp425/if_npe.c
    trunk/sys/arm/xscale/ixp425/if_npereg.h
    trunk/sys/arm/xscale/ixp425/ixdp425_pci.c
    trunk/sys/arm/xscale/ixp425/ixdp425reg.h
    trunk/sys/arm/xscale/ixp425/ixp425.c
    trunk/sys/arm/xscale/ixp425/ixp425_a4x_io.S
    trunk/sys/arm/xscale/ixp425/ixp425_a4x_space.c
    trunk/sys/arm/xscale/ixp425/ixp425_iic.c
    trunk/sys/arm/xscale/ixp425/ixp425_intr.h
    trunk/sys/arm/xscale/ixp425/ixp425_mem.c
    trunk/sys/arm/xscale/ixp425/ixp425_npe.c
    trunk/sys/arm/xscale/ixp425/ixp425_npereg.h
    trunk/sys/arm/xscale/ixp425/ixp425_npevar.h
    trunk/sys/arm/xscale/ixp425/ixp425_pci.c
    trunk/sys/arm/xscale/ixp425/ixp425_pci_asm.S
    trunk/sys/arm/xscale/ixp425/ixp425_pci_space.c
    trunk/sys/arm/xscale/ixp425/ixp425_qmgr.c
    trunk/sys/arm/xscale/ixp425/ixp425_qmgr.h
    trunk/sys/arm/xscale/ixp425/ixp425_space.c
    trunk/sys/arm/xscale/ixp425/ixp425_timer.c
    trunk/sys/arm/xscale/ixp425/ixp425_wdog.c
    trunk/sys/arm/xscale/ixp425/ixp425reg.h
    trunk/sys/arm/xscale/ixp425/ixp425var.h
    trunk/sys/arm/xscale/ixp425/std.avila
    trunk/sys/arm/xscale/ixp425/std.ixp425
    trunk/sys/arm/xscale/ixp425/std.ixp435
    trunk/sys/arm/xscale/ixp425/uart_bus_ixp425.c
    trunk/sys/arm/xscale/ixp425/uart_cpu_ixp425.c
    trunk/sys/arm/xscale/pxa/
    trunk/sys/arm/xscale/pxa/files.pxa
    trunk/sys/arm/xscale/pxa/if_smc_smi.c
    trunk/sys/arm/xscale/pxa/pxa_gpio.c
    trunk/sys/arm/xscale/pxa/pxa_icu.c
    trunk/sys/arm/xscale/pxa/pxa_machdep.c
    trunk/sys/arm/xscale/pxa/pxa_obio.c
    trunk/sys/arm/xscale/pxa/pxa_smi.c
    trunk/sys/arm/xscale/pxa/pxa_space.c
    trunk/sys/arm/xscale/pxa/pxa_timer.c
    trunk/sys/arm/xscale/pxa/pxareg.h
    trunk/sys/arm/xscale/pxa/pxavar.h
    trunk/sys/arm/xscale/pxa/std.pxa
    trunk/sys/arm/xscale/pxa/uart_bus_pxa.c
    trunk/sys/arm/xscale/pxa/uart_cpu_pxa.c
    trunk/sys/arm/xscale/std.xscale
    trunk/sys/arm/xscale/std.xscale-be

Added: trunk/sys/arm/allwinner/a10_clk.c
===================================================================
--- trunk/sys/arm/allwinner/a10_clk.c	                        (rev 0)
+++ trunk/sys/arm/allwinner/a10_clk.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,192 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Ganbold Tsagaankhuu <ganbold at freebsd.org>
+ * 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.
+ */
+
+/* Simple clock driver for Allwinner A10 */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/allwinner/a10_clk.c 266337 2014-05-17 18:53:36Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/timeet.h>
+#include <sys/timetc.h>
+#include <sys/watchdog.h>
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+
+#include "a10_clk.h"
+
+struct a10_ccm_softc {
+	struct resource		*res;
+	bus_space_tag_t		bst;
+	bus_space_handle_t	bsh;
+};
+
+static struct a10_ccm_softc *a10_ccm_sc = NULL;
+
+#define ccm_read_4(sc, reg)		\
+	bus_space_read_4((sc)->bst, (sc)->bsh, (reg))
+#define ccm_write_4(sc, reg, val)	\
+	bus_space_write_4((sc)->bst, (sc)->bsh, (reg), (val))
+
+static int
+a10_ccm_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (ofw_bus_is_compatible(dev, "allwinner,sun4i-ccm")) {
+		device_set_desc(dev, "Allwinner Clock Control Module");
+		return(BUS_PROBE_DEFAULT);
+	}
+
+	return (ENXIO);
+}
+
+static int
+a10_ccm_attach(device_t dev)
+{
+	struct a10_ccm_softc *sc = device_get_softc(dev);
+	int rid = 0;
+
+	if (a10_ccm_sc)
+		return (ENXIO);
+
+	sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
+	if (!sc->res) {
+		device_printf(dev, "could not allocate resource\n");
+		return (ENXIO);
+	}
+
+	sc->bst = rman_get_bustag(sc->res);
+	sc->bsh = rman_get_bushandle(sc->res);
+
+	a10_ccm_sc = sc;
+
+	return (0);
+}
+
+static device_method_t a10_ccm_methods[] = {
+	DEVMETHOD(device_probe,		a10_ccm_probe),
+	DEVMETHOD(device_attach,	a10_ccm_attach),
+	{ 0, 0 }
+};
+
+static driver_t a10_ccm_driver = {
+	"a10_ccm",
+	a10_ccm_methods,
+	sizeof(struct a10_ccm_softc),
+};
+
+static devclass_t a10_ccm_devclass;
+
+DRIVER_MODULE(a10_ccm, simplebus, a10_ccm_driver, a10_ccm_devclass, 0, 0);
+
+int
+a10_clk_usb_activate(void)
+{
+	struct a10_ccm_softc *sc = a10_ccm_sc;
+	uint32_t reg_value;
+
+	if (sc == NULL)
+		return (ENXIO);
+
+	/* Gating AHB clock for USB */
+	reg_value = ccm_read_4(sc, CCM_AHB_GATING0);
+	reg_value |= CCM_AHB_GATING_USB0; /* AHB clock gate usb0 */
+	reg_value |= CCM_AHB_GATING_EHCI0; /* AHB clock gate ehci1 */
+	reg_value |= CCM_AHB_GATING_EHCI1; /* AHB clock gate ehci1 */
+	ccm_write_4(sc, CCM_AHB_GATING0, reg_value);
+
+	/* Enable clock for USB */
+	reg_value = ccm_read_4(sc, CCM_USB_CLK);
+	reg_value |= CCM_USB_PHY; /* USBPHY */
+	reg_value |= CCM_USB0_RESET; /* disable reset for USB0 */
+	reg_value |= CCM_USB1_RESET; /* disable reset for USB1 */
+	reg_value |= CCM_USB2_RESET; /* disable reset for USB2 */
+	ccm_write_4(sc, CCM_USB_CLK, reg_value);
+
+	return (0);
+}
+
+int
+a10_clk_usb_deactivate(void)
+{
+	struct a10_ccm_softc *sc = a10_ccm_sc;
+	uint32_t reg_value;
+
+	if (sc == NULL)
+		return (ENXIO);
+
+	/* Disable clock for USB */
+	reg_value = ccm_read_4(sc, CCM_USB_CLK);
+	reg_value &= ~CCM_USB_PHY; /* USBPHY */
+	reg_value &= ~CCM_USB0_RESET; /* reset for USB0 */
+	reg_value &= ~CCM_USB1_RESET; /* reset for USB1 */
+	reg_value &= ~CCM_USB2_RESET; /* reset for USB2 */
+	ccm_write_4(sc, CCM_USB_CLK, reg_value);
+
+	/* Disable gating AHB clock for USB */
+	reg_value = ccm_read_4(sc, CCM_AHB_GATING0);
+	reg_value &= ~CCM_AHB_GATING_USB0; /* disable AHB clock gate usb0 */
+	reg_value &= ~CCM_AHB_GATING_EHCI1; /* disable AHB clock gate ehci1 */
+	ccm_write_4(sc, CCM_AHB_GATING0, reg_value);
+
+	return (0);
+}
+
+int
+a10_clk_emac_activate(void) {
+	struct a10_ccm_softc *sc = a10_ccm_sc;
+	uint32_t reg_value;
+
+	if (sc == NULL)
+		return (ENXIO);
+
+	/* Gating AHB clock for EMAC */
+	reg_value = ccm_read_4(sc, CCM_AHB_GATING0);
+	reg_value |= CCM_AHB_GATING_EMAC;
+	ccm_write_4(sc, CCM_AHB_GATING0, reg_value);
+
+	return (0);
+}
+


Property changes on: trunk/sys/arm/allwinner/a10_clk.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/allwinner/a10_clk.h
===================================================================
--- trunk/sys/arm/allwinner/a10_clk.h	                        (rev 0)
+++ trunk/sys/arm/allwinner/a10_clk.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,118 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Ganbold Tsagaankhuu <ganbold at freebsd.org>
+ * 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: stable/10/sys/arm/allwinner/a10_clk.h 266337 2014-05-17 18:53:36Z ian $
+ */
+
+#ifndef _A10_CLK_H_
+#define _A10_CLK_H_
+
+#define CCMU_BASE		0xe1c20000
+
+#define CCM_PLL1_CFG		0x0000
+#define CCM_PLL1_TUN		0x0004
+#define CCM_PLL2_CFG		0x0008
+#define CCM_PLL2_TUN		0x000c
+#define CCM_PLL3_CFG		0x0010
+#define CCM_PLL3_TUN		0x0014
+#define CCM_PLL4_CFG		0x0018
+#define CCM_PLL4_TUN		0x001c
+#define CCM_PLL5_CFG		0x0020
+#define CCM_PLL5_TUN		0x0024
+#define CCM_PLL6_CFG		0x0028
+#define CCM_PLL6_TUN		0x002c
+#define CCM_PLL7_CFG		0x0030
+#define CCM_PLL7_TUN		0x0034
+#define CCM_PLL1_TUN2		0x0038
+#define CCM_PLL5_TUN2		0x003c
+#define CCM_PLL_LOCK_DBG	0x004c
+#define CCM_OSC24M_CFG		0x0050
+#define CCM_CPU_AHB_APB0_CFG	0x0054
+#define CCM_APB1_CLK_DIV	0x0058
+#define CCM_AXI_GATING		0x005c
+#define CCM_AHB_GATING0		0x0060
+#define CCM_AHB_GATING1		0x0064
+#define CCM_APB0_GATING		0x0068
+#define CCM_APB1_GATING		0x006c
+#define CCM_NAND_SCLK_CFG	0x0080
+#define CCM_MS_SCLK_CFG		0x0084
+#define CCM_MMC0_SCLK_CFG	0x0088
+#define CCM_MMC1_SCLK_CFG	0x008c
+#define CCM_MMC2_SCLK_CFG	0x0090
+#define CCM_MMC3_SCLK_CFG	0x0094
+#define CCM_TS_CLK		0x0098
+#define CCM_SS_CLK		0x009c
+#define CCM_SPI0_CLK		0x00a0
+#define CCM_SPI1_CLK		0x00a4
+#define CCM_SPI2_CLK		0x00a8
+#define CCM_PATA_CLK		0x00ac
+#define CCM_IR0_CLK		0x00b0
+#define CCM_IR1_CLK		0x00b4
+#define CCM_IIS_CLK		0x00b8
+#define CCM_AC97_CLK		0x00bc
+#define CCM_SPDIF_CLK		0x00c0
+#define CCM_KEYPAD_CLK		0x00c4
+#define CCM_SATA_CLK		0x00c8
+#define CCM_USB_CLK		0x00cc
+#define CCM_GPS_CLK		0x00d0
+#define CCM_SPI3_CLK		0x00d4
+#define CCM_DRAM_CLK		0x0100
+#define CCM_BE0_SCLK		0x0104
+#define CCM_BE1_SCLK		0x0108
+#define CCM_FE0_CLK		0x010c
+#define CCM_FE1_CLK		0x0110
+#define CCM_MP_CLK		0x0114
+#define CCM_LCD0_CH0_CLK	0x0118
+#define CCM_LCD1_CH0_CLK	0x011c
+#define CCM_CSI_ISP_CLK		0x0120
+#define CCM_TVD_CLK		0x0128
+#define CCM_LCD0_CH1_CLK	0x012c
+#define CCM_LCD1_CH1_CLK	0x0130
+#define CCM_CS0_CLK		0x0134
+#define CCM_CS1_CLK		0x0138
+#define CCM_VE_CLK		0x013c
+#define CCM_AUDIO_CODEC_CLK	0x0140
+#define CCM_AVS_CLK		0x0144
+#define CCM_ACE_CLK		0x0148
+#define CCM_LVDS_CLK		0x014c
+#define CCM_HDMI_CLK		0x0150
+#define CCM_MALI400_CLK		0x0154
+
+#define CCM_AHB_GATING_USB0	(1 << 0)
+#define CCM_AHB_GATING_EHCI0	(1 << 1)
+#define CCM_AHB_GATING_EHCI1	(1 << 3)
+#define CCM_AHB_GATING_EMAC	(1 << 17)
+
+#define CCM_USB_PHY		(1 << 8)
+#define CCM_USB0_RESET		(1 << 0)
+#define CCM_USB1_RESET		(1 << 1)
+#define CCM_USB2_RESET		(1 << 2)
+
+int a10_clk_usb_activate(void);
+int a10_clk_usb_deactivate(void);
+int a10_clk_emac_activate(void);
+
+#endif /* _A10_CLK_H_ */


Property changes on: trunk/sys/arm/allwinner/a10_clk.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/allwinner/a10_common.c
===================================================================
--- trunk/sys/arm/allwinner/a10_common.c	                        (rev 0)
+++ trunk/sys/arm/allwinner/a10_common.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,70 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Ganbold Tsagaankhuu <ganbold at freebsd.org>
+ * 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: stable/10/sys/arm/allwinner/a10_common.c 266337 2014-05-17 18:53:36Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+#include <machine/vmparam.h>
+
+struct fdt_fixup_entry fdt_fixup_table[] = {
+	{ NULL, NULL }
+};
+
+static int
+fdt_aintc_decode_ic(phandle_t node, pcell_t *intr, int *interrupt, int *trig,
+    int *pol)
+{
+	int offset;
+
+	if (fdt_is_compatible(node, "allwinner,sun4i-ic"))
+		offset = 0;
+	else if (fdt_is_compatible(node, "arm,gic"))
+		offset = 32;
+	else
+		return (ENXIO);
+
+	*interrupt = fdt32_to_cpu(intr[0]) + offset;
+	*trig = INTR_TRIGGER_CONFORM;
+	*pol = INTR_POLARITY_CONFORM;
+
+	return (0);
+}
+
+fdt_pic_decode_t fdt_pic_table[] = {
+	&fdt_aintc_decode_ic,
+	NULL
+};


Property changes on: trunk/sys/arm/allwinner/a10_common.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/allwinner/a10_ehci.c
===================================================================
--- trunk/sys/arm/allwinner/a10_ehci.c	                        (rev 0)
+++ trunk/sys/arm/allwinner/a10_ehci.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,300 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Ganbold Tsagaankhuu <ganbold at freebsd.org>
+ * 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.
+ */
+
+/*
+ * Allwinner A10 attachment driver for the USB Enhanced Host Controller.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/allwinner/a10_ehci.c 308402 2016-11-07 09:19:04Z hselasky $");
+
+#include "opt_bus.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/rman.h>
+#include <sys/condvar.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/gpio.h>
+
+#include <machine/bus.h>
+#include <dev/ofw/ofw_bus.h> 
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <dev/usb/usb.h> 
+#include <dev/usb/usbdi.h>
+
+#include <dev/usb/usb_core.h>
+#include <dev/usb/usb_busdma.h>
+#include <dev/usb/usb_process.h>
+#include <dev/usb/usb_util.h>
+
+#include <dev/usb/usb_controller.h>
+#include <dev/usb/usb_bus.h>
+#include <dev/usb/controller/ehci.h>
+#include <dev/usb/controller/ehcireg.h>
+
+#include "gpio_if.h"
+
+#include "a10_clk.h"
+
+#define EHCI_HC_DEVSTR			"Allwinner Integrated USB 2.0 controller"
+
+#define SW_USB_PMU_IRQ_ENABLE		0x800
+
+#define SW_SDRAM_REG_HPCR_USB1		(0x250 + ((1 << 2) * 4))
+#define SW_SDRAM_REG_HPCR_USB2		(0x250 + ((1 << 2) * 5))
+#define SW_SDRAM_BP_HPCR_ACCESS		(1 << 0)
+
+#define SW_ULPI_BYPASS			(1 << 0)
+#define SW_AHB_INCRX_ALIGN		(1 << 8)
+#define SW_AHB_INCR4			(1 << 9)
+#define SW_AHB_INCR8			(1 << 10)
+#define GPIO_USB1_PWR			230
+#define GPIO_USB2_PWR			227
+
+#define A10_READ_4(sc, reg)		\
+	bus_space_read_4((sc)->sc_io_tag, (sc)->sc_io_hdl, reg)
+
+#define A10_WRITE_4(sc, reg, data)	\
+	bus_space_write_4((sc)->sc_io_tag, (sc)->sc_io_hdl, reg, data)
+
+static device_attach_t a10_ehci_attach;
+static device_detach_t a10_ehci_detach;
+
+bs_r_1_proto(reversed);
+bs_w_1_proto(reversed);
+
+static int
+a10_ehci_probe(device_t self)
+{
+
+	if (!ofw_bus_status_okay(self))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(self, "allwinner,usb-ehci")) 
+		return (ENXIO);
+
+	device_set_desc(self, EHCI_HC_DEVSTR);
+
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+a10_ehci_attach(device_t self)
+{
+	ehci_softc_t *sc = device_get_softc(self);
+	bus_space_handle_t bsh;
+	device_t sc_gpio_dev;
+	int err;
+	int rid;
+	uint32_t reg_value = 0;
+
+	/* initialise some bus fields */
+	sc->sc_bus.parent = self;
+	sc->sc_bus.devices = sc->sc_devices;
+	sc->sc_bus.devices_max = EHCI_MAX_DEVICES;
+	sc->sc_bus.dma_bits = 32;
+
+	/* get all DMA memory */
+	if (usb_bus_mem_alloc_all(&sc->sc_bus,
+	    USB_GET_DMA_TAG(self), &ehci_iterate_hw_softc)) {
+		return (ENOMEM);
+	}
+
+	sc->sc_bus.usbrev = USB_REV_2_0;
+
+	rid = 0;
+	sc->sc_io_res = bus_alloc_resource_any(self, SYS_RES_MEMORY, &rid, RF_ACTIVE);
+	if (!sc->sc_io_res) {
+		device_printf(self, "Could not map memory\n");
+		goto error;
+	}
+
+	sc->sc_io_tag = rman_get_bustag(sc->sc_io_res);
+	sc->sc_io_hdl = rman_get_bushandle(sc->sc_io_res);
+	bsh = rman_get_bushandle(sc->sc_io_res);
+
+	sc->sc_io_size = rman_get_size(sc->sc_io_res);
+
+	if (bus_space_subregion(sc->sc_io_tag, bsh, 0x00,
+	    sc->sc_io_size, &sc->sc_io_hdl) != 0)
+		panic("%s: unable to subregion USB host registers",
+		    device_get_name(self));
+
+	rid = 0;
+	sc->sc_irq_res = bus_alloc_resource_any(self, SYS_RES_IRQ, &rid,
+	    RF_SHAREABLE | RF_ACTIVE);
+	if (sc->sc_irq_res == NULL) {
+		device_printf(self, "Could not allocate irq\n");
+		goto error;
+	}
+	sc->sc_bus.bdev = device_add_child(self, "usbus", -1);
+	if (!sc->sc_bus.bdev) {
+		device_printf(self, "Could not add USB device\n");
+		goto error;
+	}
+	device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
+	device_set_desc(sc->sc_bus.bdev, EHCI_HC_DEVSTR);
+
+	sprintf(sc->sc_vendor, "Allwinner");
+
+        /* Get the GPIO device, we need this to give power to USB */
+	sc_gpio_dev = devclass_get_device(devclass_find("gpio"), 0);
+	if (sc_gpio_dev == NULL) {
+		device_printf(self, "Error: failed to get the GPIO device\n");
+		goto error;
+	}
+
+	err = bus_setup_intr(self, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
+	    NULL, (driver_intr_t *)ehci_interrupt, sc, &sc->sc_intr_hdl);
+	if (err) {
+		device_printf(self, "Could not setup irq, %d\n", err);
+		sc->sc_intr_hdl = NULL;
+		goto error;
+	}
+
+	sc->sc_flags |= EHCI_SCFLG_DONTRESET;
+
+	/* Enable clock for USB */
+	a10_clk_usb_activate();
+
+	/* Give power to USB */
+	GPIO_PIN_SETFLAGS(sc_gpio_dev, GPIO_USB2_PWR, GPIO_PIN_OUTPUT);
+	GPIO_PIN_SET(sc_gpio_dev, GPIO_USB2_PWR, GPIO_PIN_HIGH);
+
+	/* Give power to USB */
+	GPIO_PIN_SETFLAGS(sc_gpio_dev, GPIO_USB1_PWR, GPIO_PIN_OUTPUT);
+	GPIO_PIN_SET(sc_gpio_dev, GPIO_USB1_PWR, GPIO_PIN_HIGH);
+
+	/* Enable passby */
+	reg_value = A10_READ_4(sc, SW_USB_PMU_IRQ_ENABLE);
+	reg_value |= SW_AHB_INCR8; /* AHB INCR8 enable */
+	reg_value |= SW_AHB_INCR4; /* AHB burst type INCR4 enable */
+	reg_value |= SW_AHB_INCRX_ALIGN; /* AHB INCRX align enable */
+	reg_value |= SW_ULPI_BYPASS; /* ULPI bypass enable */
+	A10_WRITE_4(sc, SW_USB_PMU_IRQ_ENABLE, reg_value);
+
+	/* Configure port */
+	reg_value = A10_READ_4(sc, SW_SDRAM_REG_HPCR_USB2);
+	reg_value |= SW_SDRAM_BP_HPCR_ACCESS;
+	A10_WRITE_4(sc, SW_SDRAM_REG_HPCR_USB2, reg_value);
+
+	err = ehci_init(sc);
+	if (!err) {
+		err = device_probe_and_attach(sc->sc_bus.bdev);
+	}
+	if (err) {
+		device_printf(self, "USB init failed err=%d\n", err);
+		goto error;
+	}
+	return (0);
+
+error:
+	a10_ehci_detach(self);
+	return (ENXIO);
+}
+
+static int
+a10_ehci_detach(device_t self)
+{
+	ehci_softc_t *sc = device_get_softc(self);
+	int err;
+	uint32_t reg_value = 0;
+
+	/* during module unload there are lots of children leftover */
+	device_delete_children(self);
+
+	if (sc->sc_irq_res && sc->sc_intr_hdl) {
+		/*
+		 * only call ehci_detach() after ehci_init()
+		 */
+		ehci_detach(sc);
+
+		err = bus_teardown_intr(self, sc->sc_irq_res, sc->sc_intr_hdl);
+
+		if (err)
+			/* XXX or should we panic? */
+			device_printf(self, "Could not tear down irq, %d\n",
+			    err);
+		sc->sc_intr_hdl = NULL;
+	}
+
+	if (sc->sc_irq_res) {
+		bus_release_resource(self, SYS_RES_IRQ, 0, sc->sc_irq_res);
+		sc->sc_irq_res = NULL;
+	}
+	if (sc->sc_io_res) {
+		bus_release_resource(self, SYS_RES_MEMORY, 0,
+		    sc->sc_io_res);
+		sc->sc_io_res = NULL;
+	}
+	usb_bus_mem_free_all(&sc->sc_bus, &ehci_iterate_hw_softc);
+
+	/* Disable configure port */
+	reg_value = A10_READ_4(sc, SW_SDRAM_REG_HPCR_USB2);
+	reg_value &= ~SW_SDRAM_BP_HPCR_ACCESS;
+	A10_WRITE_4(sc, SW_SDRAM_REG_HPCR_USB2, reg_value);
+
+	/* Disable passby */
+	reg_value = A10_READ_4(sc, SW_USB_PMU_IRQ_ENABLE);
+	reg_value &= ~SW_AHB_INCR8; /* AHB INCR8 disable */
+	reg_value &= ~SW_AHB_INCR4; /* AHB burst type INCR4 disable */
+	reg_value &= ~SW_AHB_INCRX_ALIGN; /* AHB INCRX align disable */
+	reg_value &= ~SW_ULPI_BYPASS; /* ULPI bypass disable */
+	A10_WRITE_4(sc, SW_USB_PMU_IRQ_ENABLE, reg_value);
+
+	/* Disable clock for USB */
+	a10_clk_usb_deactivate();
+
+	return (0);
+}
+
+static device_method_t ehci_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe, a10_ehci_probe),
+	DEVMETHOD(device_attach, a10_ehci_attach),
+	DEVMETHOD(device_detach, a10_ehci_detach),
+	DEVMETHOD(device_suspend, bus_generic_suspend),
+	DEVMETHOD(device_resume, bus_generic_resume),
+	DEVMETHOD(device_shutdown, bus_generic_shutdown),
+
+	DEVMETHOD_END
+};
+
+static driver_t ehci_driver = {
+	.name = "ehci",
+	.methods = ehci_methods,
+	.size = sizeof(ehci_softc_t),
+};
+
+static devclass_t ehci_devclass;
+
+DRIVER_MODULE(ehci, simplebus, ehci_driver, ehci_devclass, 0, 0);
+MODULE_DEPEND(ehci, usb, 1, 1, 1);


Property changes on: trunk/sys/arm/allwinner/a10_ehci.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/allwinner/a10_gpio.c
===================================================================
--- trunk/sys/arm/allwinner/a10_gpio.c	                        (rev 0)
+++ trunk/sys/arm/allwinner/a10_gpio.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,529 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Ganbold Tsagaankhuu <ganbold at freebsd.org>
+ * Copyright (c) 2012 Oleksandr Tymoshenko <gonzo at freebsd.org>
+ * Copyright (c) 2012 Luiz Otavio O Souza.
+ * 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: stable/10/sys/arm/allwinner/a10_gpio.c 278786 2015-02-14 21:16:19Z loos $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/rman.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/gpio.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+#include <machine/resource.h>
+#include <machine/fdt.h>
+#include <machine/intr.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include "gpio_if.h"
+#include "a10_gpio.h"
+
+/*
+ * A10 have 9 banks of gpio.
+ * 32 pins per bank:
+ * PA0 - PA17 | PB0 - PB23 | PC0 - PC24
+ * PD0 - PD27 | PE0 - PE31 | PF0 - PF5
+ * PG0 - PG9 | PH0 - PH27 | PI0 - PI12
+ */
+
+#define	A10_GPIO_PINS		288
+#define	A10_GPIO_DEFAULT_CAPS	(GPIO_PIN_INPUT | GPIO_PIN_OUTPUT |	\
+    GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN)
+
+#define A10_GPIO_NONE		0
+#define A10_GPIO_PULLUP		1
+#define A10_GPIO_PULLDOWN	2
+
+#define A10_GPIO_INPUT		0
+#define A10_GPIO_OUTPUT		1
+
+struct a10_gpio_softc {
+	device_t		sc_dev;
+	struct mtx		sc_mtx;
+	struct resource *	sc_mem_res;
+	struct resource *	sc_irq_res;
+	bus_space_tag_t		sc_bst;
+	bus_space_handle_t	sc_bsh;
+	void *			sc_intrhand;
+	int			sc_gpio_npins;
+	struct gpio_pin		sc_gpio_pins[A10_GPIO_PINS];
+};
+
+#define	A10_GPIO_LOCK(_sc)		mtx_lock(&_sc->sc_mtx)
+#define	A10_GPIO_UNLOCK(_sc)		mtx_unlock(&_sc->sc_mtx)
+#define	A10_GPIO_LOCK_ASSERT(_sc)	mtx_assert(&_sc->sc_mtx, MA_OWNED)
+
+#define	A10_GPIO_GP_CFG(_bank, _pin)	0x00 + ((_bank) * 0x24) + ((_pin)<<2)
+#define	A10_GPIO_GP_DAT(_bank)		0x10 + ((_bank) * 0x24)
+#define	A10_GPIO_GP_DRV(_bank, _pin)	0x14 + ((_bank) * 0x24) + ((_pin)<<2)
+#define	A10_GPIO_GP_PUL(_bank, _pin)	0x1c + ((_bank) * 0x24) + ((_pin)<<2)
+
+#define	A10_GPIO_GP_INT_CFG0		0x200
+#define	A10_GPIO_GP_INT_CFG1		0x204
+#define	A10_GPIO_GP_INT_CFG2		0x208
+#define	A10_GPIO_GP_INT_CFG3		0x20c
+
+#define	A10_GPIO_GP_INT_CTL		0x210
+#define	A10_GPIO_GP_INT_STA		0x214
+#define	A10_GPIO_GP_INT_DEB		0x218
+
+static struct a10_gpio_softc *a10_gpio_sc;
+
+#define	A10_GPIO_WRITE(_sc, _off, _val)		\
+    bus_space_write_4(_sc->sc_bst, _sc->sc_bsh, _off, _val)
+#define	A10_GPIO_READ(_sc, _off)		\
+    bus_space_read_4(_sc->sc_bst, _sc->sc_bsh, _off)
+
+static uint32_t
+a10_gpio_get_function(struct a10_gpio_softc *sc, uint32_t pin)
+{
+	uint32_t bank, func, offset;
+
+	bank = pin / 32;
+	pin = pin - 32 * bank;
+	func = pin >> 3;
+	offset = ((pin & 0x07) << 2);
+
+	A10_GPIO_LOCK(sc);
+	func = (A10_GPIO_READ(sc, A10_GPIO_GP_CFG(bank, func)) >> offset) & 7;
+	A10_GPIO_UNLOCK(sc);
+
+	return (func);
+}
+
+static uint32_t
+a10_gpio_func_flag(uint32_t nfunc)
+{
+
+	switch (nfunc) {
+	case A10_GPIO_INPUT:
+		return (GPIO_PIN_INPUT);
+	case A10_GPIO_OUTPUT:
+		return (GPIO_PIN_OUTPUT);
+	}
+	return (0);
+}
+
+static void
+a10_gpio_set_function(struct a10_gpio_softc *sc, uint32_t pin, uint32_t f)
+{
+	uint32_t bank, func, data, offset;
+
+	/* Must be called with lock held. */
+	A10_GPIO_LOCK_ASSERT(sc);
+
+	bank = pin / 32;
+	pin = pin - 32 * bank;
+	func = pin >> 3;
+	offset = ((pin & 0x07) << 2);
+
+	data = A10_GPIO_READ(sc, A10_GPIO_GP_CFG(bank, func));
+	data &= ~(7 << offset);
+	data |= (f << offset);
+	A10_GPIO_WRITE(sc, A10_GPIO_GP_CFG(bank, func), data);
+}
+
+static void
+a10_gpio_set_pud(struct a10_gpio_softc *sc, uint32_t pin, uint32_t state)
+{
+	uint32_t bank, offset, pull, val;
+
+	/* Must be called with lock held. */
+	A10_GPIO_LOCK_ASSERT(sc);
+
+	bank = pin / 32;
+	pin = pin - 32 * bank;
+	pull = pin >> 4;
+	offset = ((pin & 0x0f) << 1);
+
+	val = A10_GPIO_READ(sc, A10_GPIO_GP_PUL(bank, pull));
+	val &= ~(0x03 << offset);
+	val |= (state << offset);
+	A10_GPIO_WRITE(sc, A10_GPIO_GP_PUL(bank, pull), val);
+}
+
+static void
+a10_gpio_pin_configure(struct a10_gpio_softc *sc, struct gpio_pin *pin,
+    unsigned int flags)
+{
+
+	A10_GPIO_LOCK(sc);
+
+	/*
+	 * Manage input/output.
+	 */
+	if (flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) {
+		pin->gp_flags &= ~(GPIO_PIN_INPUT|GPIO_PIN_OUTPUT);
+		if (flags & GPIO_PIN_OUTPUT) {
+			pin->gp_flags |= GPIO_PIN_OUTPUT;
+			a10_gpio_set_function(sc, pin->gp_pin,
+			    A10_GPIO_OUTPUT);
+		} else {
+			pin->gp_flags |= GPIO_PIN_INPUT;
+			a10_gpio_set_function(sc, pin->gp_pin,
+			    A10_GPIO_INPUT);
+		}
+	}
+
+	/* Manage Pull-up/pull-down. */
+	pin->gp_flags &= ~(GPIO_PIN_PULLUP|GPIO_PIN_PULLDOWN);
+	if (flags & (GPIO_PIN_PULLUP|GPIO_PIN_PULLDOWN)) {
+		if (flags & GPIO_PIN_PULLUP) {
+			pin->gp_flags |= GPIO_PIN_PULLUP;
+			a10_gpio_set_pud(sc, pin->gp_pin, A10_GPIO_PULLUP);
+		} else {
+			pin->gp_flags |= GPIO_PIN_PULLDOWN;
+			a10_gpio_set_pud(sc, pin->gp_pin, A10_GPIO_PULLDOWN);
+		}
+	} else 
+		a10_gpio_set_pud(sc, pin->gp_pin, A10_GPIO_NONE);
+
+	A10_GPIO_UNLOCK(sc);
+}
+
+static int
+a10_gpio_pin_max(device_t dev, int *maxpin)
+{
+
+	*maxpin = A10_GPIO_PINS - 1;
+	return (0);
+}
+
+static int
+a10_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
+{
+	struct a10_gpio_softc *sc = device_get_softc(dev);
+	int i;
+
+	for (i = 0; i < sc->sc_gpio_npins; i++) {
+		if (sc->sc_gpio_pins[i].gp_pin == pin)
+			break;
+	}
+
+	if (i >= sc->sc_gpio_npins)
+		return (EINVAL);
+
+	A10_GPIO_LOCK(sc);
+	*caps = sc->sc_gpio_pins[i].gp_caps;
+	A10_GPIO_UNLOCK(sc);
+
+	return (0);
+}
+
+static int
+a10_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
+{
+	struct a10_gpio_softc *sc = device_get_softc(dev);
+	int i;
+
+	for (i = 0; i < sc->sc_gpio_npins; i++) {
+		if (sc->sc_gpio_pins[i].gp_pin == pin)
+			break;
+	}
+
+	if (i >= sc->sc_gpio_npins)
+		return (EINVAL);
+
+	A10_GPIO_LOCK(sc);
+	*flags = sc->sc_gpio_pins[i].gp_flags;
+	A10_GPIO_UNLOCK(sc);
+
+	return (0);
+}
+
+static int
+a10_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
+{
+	struct a10_gpio_softc *sc = device_get_softc(dev);
+	int i;
+
+	for (i = 0; i < sc->sc_gpio_npins; i++) {
+		if (sc->sc_gpio_pins[i].gp_pin == pin)
+			break;
+	}
+
+	if (i >= sc->sc_gpio_npins)
+		return (EINVAL);
+
+	A10_GPIO_LOCK(sc);
+	memcpy(name, sc->sc_gpio_pins[i].gp_name, GPIOMAXNAME);
+	A10_GPIO_UNLOCK(sc);
+
+	return (0);
+}
+
+static int
+a10_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
+{
+	struct a10_gpio_softc *sc = device_get_softc(dev);
+	int i;
+
+	for (i = 0; i < sc->sc_gpio_npins; i++) {
+		if (sc->sc_gpio_pins[i].gp_pin == pin)
+			break;
+	}
+
+	if (i >= sc->sc_gpio_npins)
+		return (EINVAL);
+
+	a10_gpio_pin_configure(sc, &sc->sc_gpio_pins[i], flags);
+
+	return (0);
+}
+
+static int
+a10_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value)
+{
+	struct a10_gpio_softc *sc = device_get_softc(dev);
+	uint32_t bank, offset, data;
+	int i;
+
+	for (i = 0; i < sc->sc_gpio_npins; i++) {
+		if (sc->sc_gpio_pins[i].gp_pin == pin)
+			break;
+	}
+
+	if (i >= sc->sc_gpio_npins)
+		return (EINVAL);
+
+	bank = pin / 32;
+	pin = pin - 32 * bank;
+	offset = pin & 0x1f;
+
+	A10_GPIO_LOCK(sc);
+	data = A10_GPIO_READ(sc, A10_GPIO_GP_DAT(bank));
+	if (value)
+		data |= (1 << offset);
+	else
+		data &= ~(1 << offset);
+	A10_GPIO_WRITE(sc, A10_GPIO_GP_DAT(bank), data);
+	A10_GPIO_UNLOCK(sc);
+
+	return (0);
+}
+
+static int
+a10_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val)
+{
+	struct a10_gpio_softc *sc = device_get_softc(dev);
+	uint32_t bank, offset, reg_data;
+	int i;
+
+	for (i = 0; i < sc->sc_gpio_npins; i++) {
+		if (sc->sc_gpio_pins[i].gp_pin == pin)
+			break;
+	}
+
+	if (i >= sc->sc_gpio_npins)
+		return (EINVAL);
+
+	bank = pin / 32;
+	pin = pin - 32 * bank;
+	offset = pin & 0x1f;
+
+	A10_GPIO_LOCK(sc);
+	reg_data = A10_GPIO_READ(sc, A10_GPIO_GP_DAT(bank));
+	A10_GPIO_UNLOCK(sc);
+	*val = (reg_data & (1 << offset)) ? 1 : 0;
+
+	return (0);
+}
+
+static int
+a10_gpio_pin_toggle(device_t dev, uint32_t pin)
+{
+	struct a10_gpio_softc *sc = device_get_softc(dev);
+	uint32_t bank, data, offset;
+	int i;
+
+	for (i = 0; i < sc->sc_gpio_npins; i++) {
+		if (sc->sc_gpio_pins[i].gp_pin == pin)
+			break;
+	}
+
+	if (i >= sc->sc_gpio_npins)
+		return (EINVAL);
+
+	bank = pin / 32;
+	pin = pin - 32 * bank;
+	offset = pin & 0x1f;
+
+	A10_GPIO_LOCK(sc);
+	data = A10_GPIO_READ(sc, A10_GPIO_GP_DAT(bank));
+	if (data & (1 << offset))
+		data &= ~(1 << offset);
+	else
+		data |= (1 << offset);
+	A10_GPIO_WRITE(sc, A10_GPIO_GP_DAT(bank), data);
+	A10_GPIO_UNLOCK(sc);
+
+	return (0);
+}
+
+static int
+a10_gpio_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "allwinner,sun4i-gpio"))
+		return (ENXIO);
+
+	device_set_desc(dev, "Allwinner GPIO controller");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+a10_gpio_attach(device_t dev)
+{
+	struct a10_gpio_softc *sc = device_get_softc(dev);
+	uint32_t func;
+	int i, rid;
+	phandle_t gpio;
+
+	sc->sc_dev = dev;
+
+	mtx_init(&sc->sc_mtx, "a10 gpio", "gpio", MTX_DEF);
+
+	rid = 0;
+	sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	    RF_ACTIVE);
+	if (!sc->sc_mem_res) {
+		device_printf(dev, "cannot allocate memory window\n");
+		return (ENXIO);
+	}
+
+	sc->sc_bst = rman_get_bustag(sc->sc_mem_res);
+	sc->sc_bsh = rman_get_bushandle(sc->sc_mem_res);
+
+	rid = 0;
+	sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+	    RF_ACTIVE);
+	if (!sc->sc_irq_res) {
+		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
+		device_printf(dev, "cannot allocate interrupt\n");
+		return (ENXIO);
+	}
+
+	/* Find our node. */
+	gpio = ofw_bus_get_node(sc->sc_dev);
+
+	if (!OF_hasprop(gpio, "gpio-controller"))
+		/* Node is not a GPIO controller. */
+		goto fail;
+
+	/* Initialize the software controlled pins. */
+	for (i = 0; i < A10_GPIO_PINS; i++) {
+		snprintf(sc->sc_gpio_pins[i].gp_name, GPIOMAXNAME,
+		    "pin %d", i);
+		func = a10_gpio_get_function(sc, i);
+		sc->sc_gpio_pins[i].gp_pin = i;
+		sc->sc_gpio_pins[i].gp_caps = A10_GPIO_DEFAULT_CAPS;
+		sc->sc_gpio_pins[i].gp_flags = a10_gpio_func_flag(func);
+	}
+	sc->sc_gpio_npins = i;
+
+	device_add_child(dev, "gpioc", -1);
+	device_add_child(dev, "gpiobus", -1);
+
+	a10_gpio_sc = sc;
+
+	return (bus_generic_attach(dev));
+
+fail:
+	if (sc->sc_irq_res)
+		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res);
+	if (sc->sc_mem_res)
+		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
+	return (ENXIO);
+}
+
+static int
+a10_gpio_detach(device_t dev)
+{
+
+	return (EBUSY);
+}
+
+static device_method_t a10_gpio_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		a10_gpio_probe),
+	DEVMETHOD(device_attach,	a10_gpio_attach),
+	DEVMETHOD(device_detach,	a10_gpio_detach),
+
+	/* GPIO protocol */
+	DEVMETHOD(gpio_pin_max,		a10_gpio_pin_max),
+	DEVMETHOD(gpio_pin_getname,	a10_gpio_pin_getname),
+	DEVMETHOD(gpio_pin_getflags,	a10_gpio_pin_getflags),
+	DEVMETHOD(gpio_pin_getcaps,	a10_gpio_pin_getcaps),
+	DEVMETHOD(gpio_pin_setflags,	a10_gpio_pin_setflags),
+	DEVMETHOD(gpio_pin_get,		a10_gpio_pin_get),
+	DEVMETHOD(gpio_pin_set,		a10_gpio_pin_set),
+	DEVMETHOD(gpio_pin_toggle,	a10_gpio_pin_toggle),
+
+	DEVMETHOD_END
+};
+
+static devclass_t a10_gpio_devclass;
+
+static driver_t a10_gpio_driver = {
+	"gpio",
+	a10_gpio_methods,
+	sizeof(struct a10_gpio_softc),
+};
+
+DRIVER_MODULE(a10_gpio, simplebus, a10_gpio_driver, a10_gpio_devclass, 0, 0);
+
+int
+a10_emac_gpio_config(uint32_t pin)
+{
+	struct a10_gpio_softc *sc = a10_gpio_sc;
+
+	if (sc == NULL)
+		return (ENXIO);
+
+	/* Configure pin mux settings for MII. */
+	A10_GPIO_LOCK(sc);
+	a10_gpio_set_function(sc, pin, A10_GPIO_PULLDOWN);
+	A10_GPIO_UNLOCK(sc);
+
+	return (0);
+}


Property changes on: trunk/sys/arm/allwinner/a10_gpio.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/allwinner/a10_gpio.h
===================================================================
--- trunk/sys/arm/allwinner/a10_gpio.h	                        (rev 0)
+++ trunk/sys/arm/allwinner/a10_gpio.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,35 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Ganbold Tsagaankhuu <ganbold at freebsd.org>
+ * 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: stable/10/sys/arm/allwinner/a10_gpio.h 266337 2014-05-17 18:53:36Z ian $
+ */
+
+#ifndef	_A10_GPIO_H_
+#define	_A10_GPIO_H_
+
+int a10_emac_gpio_config(uint32_t pin);
+
+#endif


Property changes on: trunk/sys/arm/allwinner/a10_gpio.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/allwinner/a10_machdep.c
===================================================================
--- trunk/sys/arm/allwinner/a10_machdep.c	                        (rev 0)
+++ trunk/sys/arm/allwinner/a10_machdep.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,113 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Ganbold Tsagaankhuu <ganbold at freebsd.org>
+ * All rights reserved.
+ *
+ * This code is derived from software written for Brini by Mark Brinicombe
+ *
+ * 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.
+ *
+ * from: FreeBSD: //depot/projects/arm/src/sys/arm/ti/ti_machdep.c
+ */
+
+#include "opt_ddb.h"
+#include "opt_platform.h"
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/allwinner/a10_machdep.c 266337 2014-05-17 18:53:36Z ian $");
+
+#define _ARM32_BUS_DMA_PRIVATE
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <machine/bus.h>
+#include <machine/devmap.h>
+#include <machine/machdep.h>
+
+#include <dev/fdt/fdt_common.h>
+
+#include <arm/allwinner/a10_wdog.h>
+
+vm_offset_t
+initarm_lastaddr(void)
+{
+
+	return (arm_devmap_lastaddr());
+}
+
+void
+initarm_early_init(void)
+{
+}
+
+void
+initarm_gpio_init(void)
+{
+}
+
+void
+initarm_late_init(void)
+{
+}
+
+/*
+ * Set up static device mappings.
+ *
+ * This covers all the on-chip device with 1MB section mappings, which is good
+ * for performance (uses fewer TLB entries for device access).
+ *
+ * XXX It also covers a block of SRAM and some GPU (mali400) stuff that maybe
+ * shouldn't be device-mapped.  The original code mapped a 4MB block, but
+ * perhaps a 1MB block would be more appropriate.
+ */
+int
+initarm_devmap_init(void)
+{
+
+	arm_devmap_add_entry(0x01C00000, 0x00400000); /* 4MB */
+
+	return (0);
+}
+
+struct arm32_dma_range *
+bus_dma_get_range(void)
+{
+	return (NULL);
+}
+
+int
+bus_dma_get_range_nb(void)
+{
+	return (0);
+}
+
+void
+cpu_reset()
+{
+	a10wd_watchdog_reset();
+	printf("Reset failed!\n");
+	while (1);
+}


Property changes on: trunk/sys/arm/allwinner/a10_machdep.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/allwinner/a10_sramc.c
===================================================================
--- trunk/sys/arm/allwinner/a10_sramc.c	                        (rev 0)
+++ trunk/sys/arm/allwinner/a10_sramc.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,135 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Ganbold Tsagaankhuu <ganbold at freebsd.org>
+ * 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: stable/10/sys/arm/allwinner/a10_sramc.c 266337 2014-05-17 18:53:36Z ian $
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/allwinner/a10_sramc.c 266337 2014-05-17 18:53:36Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/timeet.h>
+#include <sys/timetc.h>
+#include <sys/watchdog.h>
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/frame.h>
+#include <machine/intr.h>
+#include <machine/fdt.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include "a10_sramc.h"
+
+#define	SRAM_CTL1_CFG		0x04
+
+struct a10_sramc_softc {
+	struct resource		*res;
+	bus_space_tag_t		bst;
+	bus_space_handle_t	bsh;
+};
+
+static struct a10_sramc_softc *a10_sramc_sc;
+
+#define	sramc_read_4(sc, reg)		\
+    bus_space_read_4((sc)->bst, (sc)->bsh, (reg))
+#define	sramc_write_4(sc, reg, val)	\
+    bus_space_write_4((sc)->bst, (sc)->bsh, (reg), (val))
+
+
+static int
+a10_sramc_probe(device_t dev)
+{
+
+	if (ofw_bus_is_compatible(dev, "allwinner,sun4i-sramc")) {
+		device_set_desc(dev, "Allwinner sramc module");
+		return (BUS_PROBE_DEFAULT);
+	}
+
+	return (ENXIO);
+}
+
+static int
+a10_sramc_attach(device_t dev)
+{
+	struct a10_sramc_softc *sc = device_get_softc(dev);
+	int rid = 0;
+
+	sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
+	if (!sc->res) {
+		device_printf(dev, "could not allocate resource\n");
+		return (ENXIO);
+	}
+
+	sc->bst = rman_get_bustag(sc->res);
+	sc->bsh = rman_get_bushandle(sc->res);
+
+	a10_sramc_sc = sc;
+
+	return (0);
+}
+
+static device_method_t a10_sramc_methods[] = {
+	DEVMETHOD(device_probe,		a10_sramc_probe),
+	DEVMETHOD(device_attach,	a10_sramc_attach),
+	{ 0, 0 }
+};
+
+static driver_t a10_sramc_driver = {
+	"a10_sramc",
+	a10_sramc_methods,
+	sizeof(struct a10_sramc_softc),
+};
+
+static devclass_t a10_sramc_devclass;
+
+DRIVER_MODULE(a10_sramc, simplebus, a10_sramc_driver, a10_sramc_devclass, 0, 0);
+
+int
+a10_map_to_emac(void)
+{
+	struct a10_sramc_softc *sc = a10_sramc_sc;
+	uint32_t reg_value;
+
+	if (sc == NULL)
+		return (ENXIO);
+
+	/* Map SRAM to EMAC, set bit 2 and 4. */
+	reg_value = sramc_read_4(sc, SRAM_CTL1_CFG);
+	reg_value |= 0x5 << 2;
+	sramc_write_4(sc, SRAM_CTL1_CFG, reg_value);
+
+	return (0);
+}


Property changes on: trunk/sys/arm/allwinner/a10_sramc.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/allwinner/a10_sramc.h
===================================================================
--- trunk/sys/arm/allwinner/a10_sramc.h	                        (rev 0)
+++ trunk/sys/arm/allwinner/a10_sramc.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,35 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Ganbold Tsagaankhuu <ganbold at freebsd.org>
+ * 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: stable/10/sys/arm/allwinner/a10_sramc.h 266337 2014-05-17 18:53:36Z ian $
+ */
+
+#ifndef	_A10_SRAMC_H_
+#define	_A10_SRAMC_H_
+
+int	a10_map_to_emac(void);
+
+#endif


Property changes on: trunk/sys/arm/allwinner/a10_sramc.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/allwinner/a10_wdog.c
===================================================================
--- trunk/sys/arm/allwinner/a10_wdog.c	                        (rev 0)
+++ trunk/sys/arm/allwinner/a10_wdog.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,209 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Oleksandr Tymoshenko <gonzo at freebsd.org>
+ * 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: stable/10/sys/arm/allwinner/a10_wdog.c 266405 2014-05-18 16:03:34Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/watchdog.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/rman.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+#include <machine/cpufunc.h>
+#include <machine/machdep.h>
+#include <machine/fdt.h>
+
+#include <arm/allwinner/a10_wdog.h>
+
+#define	READ(_sc, _r) bus_read_4((_sc)->res, (_r))
+#define	WRITE(_sc, _r, _v) bus_write_4((_sc)->res, (_r), (_v))
+
+#define	WDOG_CTRL		0x00
+#define		WDOG_CTRL_RESTART	(1 << 0)
+#define	WDOG_MODE		0x04
+#define		WDOG_MODE_INTVL_SHIFT	3
+#define		WDOG_MODE_RST_EN	(1 << 1)
+#define		WDOG_MODE_EN		(1 << 0)
+
+struct a10wd_interval {
+	uint64_t	milliseconds;
+	unsigned int	value;
+};
+
+struct a10wd_interval wd_intervals[] = {
+	{   500,	 0 },
+	{  1000,	 1 },
+	{  2000,	 2 },
+	{  3000,	 3 },
+	{  4000,	 4 },
+	{  5000,	 5 },
+	{  6000,	 6 },
+	{  8000,	 7 },
+	{ 10000,	 8 },
+	{ 12000,	 9 },
+	{ 14000,	10 },
+	{ 16000,	11 },
+	{ 0,		 0 } /* sentinel */
+};
+
+static struct a10wd_softc *a10wd_sc = NULL;
+
+struct a10wd_softc {
+	device_t		dev;
+	struct resource *	res;
+	struct mtx		mtx;
+};
+
+static void a10wd_watchdog_fn(void *private, u_int cmd, int *error);
+
+static int
+a10wd_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (ofw_bus_is_compatible(dev, "allwinner,sun4i-wdt")) {
+		device_set_desc(dev, "Allwinner A10 Watchdog");
+		return (BUS_PROBE_DEFAULT);
+	}
+
+	return (ENXIO);
+}
+
+static int
+a10wd_attach(device_t dev)
+{
+	struct a10wd_softc *sc;
+	int rid;
+
+	if (a10wd_sc != NULL)
+		return (ENXIO);
+
+	sc = device_get_softc(dev);
+	sc->dev = dev;
+
+	rid = 0;
+	sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
+	if (sc->res == NULL) {
+		device_printf(dev, "could not allocate memory resource\n");
+		return (ENXIO);
+	}
+
+	a10wd_sc = sc;
+	mtx_init(&sc->mtx, "A10 Watchdog", "a10wd", MTX_DEF);
+	EVENTHANDLER_REGISTER(watchdog_list, a10wd_watchdog_fn, sc, 0);
+
+	return (0);
+}
+
+static void
+a10wd_watchdog_fn(void *private, u_int cmd, int *error)
+{
+	struct a10wd_softc *sc;
+	uint64_t ms;
+	int i;
+
+	sc = private;
+	mtx_lock(&sc->mtx);
+
+	cmd &= WD_INTERVAL;
+
+	if (cmd > 0) {
+		ms = ((uint64_t)1 << (cmd & WD_INTERVAL)) / 1000000;
+		i = 0;
+		while (wd_intervals[i].milliseconds && 
+		    (ms > wd_intervals[i].milliseconds))
+			i++;
+		if (wd_intervals[i].milliseconds) {
+			WRITE(sc, WDOG_MODE, 
+			    (wd_intervals[i].value << WDOG_MODE_INTVL_SHIFT) |
+			    WDOG_MODE_EN | WDOG_MODE_RST_EN);
+			WRITE(sc, WDOG_CTRL, WDOG_CTRL_RESTART);
+			*error = 0;
+		}
+		else {
+			/* 
+			 * Can't arm
+			 * disable watchdog as watchdog(9) requires
+			 */
+			device_printf(sc->dev,
+			    "Can't arm, timeout is more than 16 sec\n");
+			mtx_unlock(&sc->mtx);
+			WRITE(sc, WDOG_MODE, 0);
+			return;
+		}
+	}
+	else
+		WRITE(sc, WDOG_MODE, 0);
+
+	mtx_unlock(&sc->mtx);
+}
+
+void
+a10wd_watchdog_reset()
+{
+
+	if (a10wd_sc == NULL) {
+		printf("Reset: watchdog device has not been initialized\n");
+		return;
+	}
+
+	WRITE(a10wd_sc, WDOG_MODE, 
+	    (wd_intervals[0].value << WDOG_MODE_INTVL_SHIFT) |
+	    WDOG_MODE_EN | WDOG_MODE_RST_EN);
+
+	while(1)
+		;
+
+}
+
+static device_method_t a10wd_methods[] = {
+	DEVMETHOD(device_probe, a10wd_probe),
+	DEVMETHOD(device_attach, a10wd_attach),
+
+	DEVMETHOD_END
+};
+
+static driver_t a10wd_driver = {
+	"a10wd",
+	a10wd_methods,
+	sizeof(struct a10wd_softc),
+};
+static devclass_t a10wd_devclass;
+
+DRIVER_MODULE(a10wd, simplebus, a10wd_driver, a10wd_devclass, 0, 0);


Property changes on: trunk/sys/arm/allwinner/a10_wdog.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/allwinner/a10_wdog.h
===================================================================
--- trunk/sys/arm/allwinner/a10_wdog.h	                        (rev 0)
+++ trunk/sys/arm/allwinner/a10_wdog.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,36 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Oleksandr Tymoshenko <gonzo at freebsd.org>
+ * 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: stable/10/sys/arm/allwinner/a10_wdog.h 246660 2013-02-11 11:31:23Z gonzo $
+ *
+ */
+#ifndef	__A10_WDOG_H__
+#define	__A10_WDOG_H__
+
+void a10wd_watchdog_reset(void);
+
+#endif /*__A10_WDOG_H__*/
+


Property changes on: trunk/sys/arm/allwinner/a10_wdog.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/allwinner/a20/a20_cpu_cfg.c
===================================================================
--- trunk/sys/arm/allwinner/a20/a20_cpu_cfg.c	                        (rev 0)
+++ trunk/sys/arm/allwinner/a20/a20_cpu_cfg.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,139 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Ganbold Tsagaankhuu <ganbold at freebsd.org>
+ * 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.
+ */
+
+/* CPU configuration module for Allwinner A20 */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/allwinner/a20/a20_cpu_cfg.c 266337 2014-05-17 18:53:36Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/timeet.h>
+#include <sys/timetc.h>
+#include <sys/watchdog.h>
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+
+#include "a20_cpu_cfg.h"
+
+struct a20_cpu_cfg_softc {
+	struct resource 	*res;
+	bus_space_tag_t 	bst;
+	bus_space_handle_t	bsh;
+};
+
+static struct a20_cpu_cfg_softc *a20_cpu_cfg_sc = NULL;
+
+#define cpu_cfg_read_4(sc, reg) 	\
+	bus_space_read_4((sc)->bst, (sc)->bsh, (reg))
+#define cpu_cfg_write_4(sc, reg, val)	\
+	bus_space_write_4((sc)->bst, (sc)->bsh, (reg), (val))
+
+static int
+a20_cpu_cfg_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (ofw_bus_is_compatible(dev, "allwinner,sun7i-cpu-cfg")) {
+		device_set_desc(dev, "A20 CPU Configuration Module");
+		return(BUS_PROBE_DEFAULT);
+	}
+
+	return (ENXIO);
+}
+
+static int
+a20_cpu_cfg_attach(device_t dev)
+{
+	struct a20_cpu_cfg_softc *sc = device_get_softc(dev);
+	int rid = 0;
+
+	if (a20_cpu_cfg_sc)
+		return (ENXIO);
+
+	sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
+	if (!sc->res) {
+		device_printf(dev, "could not allocate resource\n");
+		return (ENXIO);
+	}
+
+	sc->bst = rman_get_bustag(sc->res);
+	sc->bsh = rman_get_bushandle(sc->res);
+
+	a20_cpu_cfg_sc = sc;
+
+	return (0);
+}
+
+static device_method_t a20_cpu_cfg_methods[] = {
+	DEVMETHOD(device_probe, 	a20_cpu_cfg_probe),
+	DEVMETHOD(device_attach,	a20_cpu_cfg_attach),
+	{ 0, 0 }
+};
+
+static driver_t a20_cpu_cfg_driver = {
+	"a20_cpu_cfg",
+	a20_cpu_cfg_methods,
+	sizeof(struct a20_cpu_cfg_softc),
+};
+
+static devclass_t a20_cpu_cfg_devclass;
+
+DRIVER_MODULE(a20_cpu_cfg, simplebus, a20_cpu_cfg_driver, a20_cpu_cfg_devclass, 0, 0);
+
+uint64_t
+a20_read_counter64(void)
+{
+	uint32_t lo, hi;
+
+	/* Latch counter, wait for it to be ready to read. */
+	cpu_cfg_write_4(a20_cpu_cfg_sc, OSC24M_CNT64_CTRL_REG, CNT64_RL_EN);
+	while (cpu_cfg_read_4(a20_cpu_cfg_sc, OSC24M_CNT64_CTRL_REG) & CNT64_RL_EN)
+		continue;
+
+	hi = cpu_cfg_read_4(a20_cpu_cfg_sc, OSC24M_CNT64_HIGH_REG);
+	lo = cpu_cfg_read_4(a20_cpu_cfg_sc, OSC24M_CNT64_LOW_REG);
+
+	return (((uint64_t)hi << 32) | lo);
+}
+


Property changes on: trunk/sys/arm/allwinner/a20/a20_cpu_cfg.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/allwinner/a20/a20_cpu_cfg.h
===================================================================
--- trunk/sys/arm/allwinner/a20/a20_cpu_cfg.h	                        (rev 0)
+++ trunk/sys/arm/allwinner/a20/a20_cpu_cfg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,68 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Ganbold Tsagaankhuu <ganbold at freebsd.org>
+ * 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: stable/10/sys/arm/allwinner/a20/a20_cpu_cfg.h 266337 2014-05-17 18:53:36Z ian $
+ */
+
+#ifndef _A20_CPU_CFG_H_
+#define _A20_CPU_CFG_H_
+
+#define CPU_CFG_BASE		0xe1c25c00
+
+#define CPU0_RST_CTRL		0x0040
+#define CPU0_CTRL_REG		0x0044
+#define CPU0_STATUS_REG 	0x0048
+
+#define CPU1_RST_CTRL		0x0080
+#define CPU1_CTRL_REG		0x0084
+#define CPU1_STATUS_REG 	0x0088
+
+#define GENER_CTRL_REG		0x0184
+
+#define EVENT_IN_REG		0x0190
+#define PRIVATE_REG		0x01a4
+
+#define IDLE_CNT0_LOW_REG	0x0200
+#define IDLE_CNT0_HIGH_REG	0x0204
+#define IDLE_CNT0_CTRL_REG	0x0208
+
+#define IDLE_CNT1_LOW_REG	0x0210
+#define IDLE_CNT1_HIGH_REG	0x0214
+#define IDLE_CNT1_CTRL_REG	0x0218
+
+#define OSC24M_CNT64_CTRL_REG	0x0280
+#define OSC24M_CNT64_LOW_REG	0x0284
+#define OSC24M_CNT64_HIGH_REG	0x0288
+
+#define LOSC_CNT64_CTRL_REG	0x0290
+#define LOSC_CNT64_LOW_REG	0x0294
+#define LOSC_CNT64_HIGH_REG	0x0298
+
+#define CNT64_RL_EN		0x02 /* read latch enable */
+
+uint64_t a20_read_counter64(void);
+
+#endif /* _A20_CPU_CFG_H_ */


Property changes on: trunk/sys/arm/allwinner/a20/a20_cpu_cfg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/allwinner/a20/a20_mp.c
===================================================================
--- trunk/sys/arm/allwinner/a20/a20_mp.c	                        (rev 0)
+++ trunk/sys/arm/allwinner/a20/a20_mp.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,160 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014 Ganbold Tsagaankhuu <ganbold at freebsd.org>
+ * 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 ``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 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: stable/10/sys/arm/allwinner/a20/a20_mp.c 286052 2015-07-30 00:24:21Z marius $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/smp.h>
+
+#include <machine/smp.h>
+#include <machine/fdt.h>
+#include <machine/intr.h>
+
+#define	CPUCFG_BASE		0x01c25c00
+#define	CPUCFG_SIZE		0x400
+
+#define	CPU0_RST_CTL		0x40
+#define	CPU0_CTL		0x44
+#define	CPU0_STATUS		0x48
+#define	CPU1_RST_CTL		0x80
+#define	CPU1_CTL		0x84
+#define	CPU1_STATUS		0x88
+#define	CPUCFG_GENCTL		0x184
+#define	CPUCFG_P_REG0		0x1a4
+#define	CPU1_PWR_CLAMP		0x1b0
+#define	CPU1_PWROFF_REG		0x1b4
+#define	CPUCFG_DBGCTL0		0x1e0
+#define	CPUCFG_DBGCTL1		0x1e4
+
+void
+platform_mp_init_secondary(void)
+{
+
+	gic_init_secondary();
+}
+
+void
+platform_mp_setmaxid(void)
+{
+	int ncpu;
+
+	if (mp_ncpus != 0)
+		return;
+
+	/* Read the number of cores from the CP15 L2 Control Register. */
+	__asm __volatile("mrc p15, 1, %0, c9, c0, 2" : "=r" (ncpu));
+	ncpu = ((ncpu >> 24) & 0x3) + 1;
+
+	mp_ncpus = ncpu;
+	mp_maxid = ncpu - 1;
+}
+
+int
+platform_mp_probe(void)
+{
+
+	if (mp_ncpus == 0)
+		platform_mp_setmaxid();
+
+	return (mp_ncpus > 1);
+}
+
+void
+platform_mp_start_ap(void)
+{
+	bus_space_handle_t cpucfg;
+
+	uint32_t val;
+
+	if (bus_space_map(fdtbus_bs_tag, CPUCFG_BASE, CPUCFG_SIZE, 0,
+	    &cpucfg) != 0)
+		panic("Couldn't map the CPUCFG\n");
+
+	cpu_idcache_wbinv_all();
+	cpu_l2cache_wbinv_all();
+
+	bus_space_write_4(fdtbus_bs_tag, cpucfg, CPUCFG_P_REG0,
+	    pmap_kextract((vm_offset_t)mpentry));
+
+	/*
+	 * Assert nCOREPORESET low and set L1RSTDISABLE low.
+	 * Ensure DBGPWRDUP is set to LOW to prevent any external
+	 * debug access to the processor.
+	 */
+	bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_RST_CTL, 0);
+
+	/* Set L1RSTDISABLE low */
+	val = bus_space_read_4(fdtbus_bs_tag, cpucfg, CPUCFG_GENCTL);
+	val &= ~(1 << 1);
+	bus_space_write_4(fdtbus_bs_tag, cpucfg, CPUCFG_GENCTL, val);
+
+	/* Set DBGPWRDUP low */
+	val = bus_space_read_4(fdtbus_bs_tag, cpucfg, CPUCFG_DBGCTL1);
+	val &= ~(1 << 1);
+	bus_space_write_4(fdtbus_bs_tag, cpucfg, CPUCFG_DBGCTL1, val);
+
+	/* Release power clamp */
+	bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_PWR_CLAMP, 0xff);
+	bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_PWR_CLAMP, 0x7f);
+	bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_PWR_CLAMP, 0x3f);
+	bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_PWR_CLAMP, 0x1f);
+	bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_PWR_CLAMP, 0x0f);
+	bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_PWR_CLAMP, 0x07);
+	bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_PWR_CLAMP, 0x03);
+	bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_PWR_CLAMP, 0x01);
+	bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_PWR_CLAMP, 0x00);
+	DELAY(10000);
+
+	/* Clear power-off gating */
+	val = bus_space_read_4(fdtbus_bs_tag, cpucfg, CPU1_PWROFF_REG);
+	val &= ~(1 << 0);
+	bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_PWROFF_REG, val);
+	DELAY(1000);
+
+	/* De-assert cpu core reset */
+	bus_space_write_4(fdtbus_bs_tag, cpucfg, CPU1_RST_CTL, 3);
+
+	/* Assert DBGPWRDUP signal */
+	val = bus_space_read_4(fdtbus_bs_tag, cpucfg, CPUCFG_DBGCTL1);
+	val |= (1 << 1);
+	bus_space_write_4(fdtbus_bs_tag, cpucfg, CPUCFG_DBGCTL1, val);
+
+	armv7_sev();
+	bus_space_unmap(fdtbus_bs_tag, cpucfg, CPUCFG_SIZE);
+}
+
+void
+platform_ipi_send(cpuset_t cpus, u_int ipi)
+{
+
+	pic_ipi_send(cpus, ipi);
+}


Property changes on: trunk/sys/arm/allwinner/a20/a20_mp.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/allwinner/a20/files.a20
===================================================================
--- trunk/sys/arm/allwinner/a20/files.a20	                        (rev 0)
+++ trunk/sys/arm/allwinner/a20/files.a20	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,23 @@
+# $FreeBSD: stable/10/sys/arm/allwinner/a20/files.a20 278727 2015-02-13 22:32:02Z ian $
+kern/kern_clocksource.c 		standard
+
+arm/arm/bus_space_asm_generic.S 	standard
+arm/arm/bus_space_generic.c		standard
+arm/arm/cpufunc_asm_armv5.S		standard
+arm/arm/cpufunc_asm_arm10.S		standard
+arm/arm/cpufunc_asm_arm11.S		standard
+arm/arm/cpufunc_asm_armv7.S		standard
+arm/arm/gic.c				standard
+
+arm/allwinner/a20/a20_cpu_cfg.c 	standard
+arm/allwinner/a10_clk.c 		standard
+arm/allwinner/a10_sramc.c		standard
+arm/allwinner/a10_gpio.c		optional	gpio
+arm/allwinner/a10_ehci.c		optional	ehci
+arm/allwinner/if_emac.c			optional	emac
+arm/allwinner/a10_wdog.c		standard
+arm/allwinner/timer.c			standard
+arm/arm/bus_space_base.c		standard
+arm/allwinner/a10_common.c		standard
+arm/allwinner/a10_machdep.c		standard
+arm/allwinner/a20/a20_mp.c		optional	smp


Property changes on: trunk/sys/arm/allwinner/a20/files.a20
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/allwinner/a20/std.a20
===================================================================
--- trunk/sys/arm/allwinner/a20/std.a20	                        (rev 0)
+++ trunk/sys/arm/allwinner/a20/std.a20	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,25 @@
+# Allwinner A20 common options
+#$FreeBSD: stable/10/sys/arm/allwinner/a20/std.a20 278601 2015-02-11 22:47:48Z ian $
+
+cpu		CPU_CORTEXA
+machine 	arm armv6
+makeoptions	CONF_CFLAGS="-march=armv7a -Wa,-march=armv7a"
+makeoption	ARM_LITTLE_ENDIAN
+
+# Physical memory starts at 0x40200000.  We assume images are loaded at
+# 0x40200000, e.g. from u-boot with 'fatload mmc 0 0x40200000 kernel'
+#
+#
+options 	PHYSADDR=0x40000000
+
+makeoptions	KERNPHYSADDR=0x40200000
+options 	KERNPHYSADDR=0x40200000
+makeoptions	KERNVIRTADDR=0xc0200000
+options 	KERNVIRTADDR=0xc0200000
+
+options 	ARM_L2_PIPT
+
+options 	IPI_IRQ_START=0
+options 	IPI_IRQ_END=15
+
+files		"../allwinner/a20/files.a20"


Property changes on: trunk/sys/arm/allwinner/a20/std.a20
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/allwinner/aintc.c
===================================================================
--- trunk/sys/arm/allwinner/aintc.c	                        (rev 0)
+++ trunk/sys/arm/allwinner/aintc.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,216 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Ganbold Tsagaankhuu <ganbold at freebsd.org>
+ * 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: stable/10/sys/arm/allwinner/aintc.c 266337 2014-05-17 18:53:36Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/ktr.h>
+#include <sys/module.h>
+#include <sys/rman.h>
+#include <machine/bus.h>
+#include <machine/intr.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+/**
+ * Interrupt controller registers
+ *
+ */
+#define SW_INT_VECTOR_REG		0x00
+#define SW_INT_BASE_ADR_REG		0x04
+#define SW_INT_PROTECTION_REG		0x08
+#define SW_INT_NMI_CTRL_REG		0x0c
+
+#define SW_INT_IRQ_PENDING_REG0		0x10
+#define SW_INT_IRQ_PENDING_REG1		0x14
+#define SW_INT_IRQ_PENDING_REG2		0x18
+
+#define SW_INT_FIQ_PENDING_REG0		0x20
+#define SW_INT_FIQ_PENDING_REG1		0x24
+#define SW_INT_FIQ_PENDING_REG2		0x28
+
+#define SW_INT_SELECT_REG0		0x30
+#define SW_INT_SELECT_REG1		0x34
+#define SW_INT_SELECT_REG2		0x38
+
+#define SW_INT_ENABLE_REG0		0x40
+#define SW_INT_ENABLE_REG1		0x44
+#define SW_INT_ENABLE_REG2		0x48
+
+#define SW_INT_MASK_REG0		0x50
+#define SW_INT_MASK_REG1		0x54
+#define SW_INT_MASK_REG2		0x58
+
+#define SW_INT_IRQNO_ENMI		0
+
+#define SW_INT_IRQ_PENDING_REG(_b)	(0x10 + ((_b) * 4))
+#define SW_INT_FIQ_PENDING_REG(_b)	(0x20 + ((_b) * 4))
+#define SW_INT_SELECT_REG(_b)		(0x30 + ((_b) * 4))
+#define SW_INT_ENABLE_REG(_b)		(0x40 + ((_b) * 4))
+#define SW_INT_MASK_REG(_b)		(0x50 + ((_b) * 4))
+
+struct a10_aintc_softc {
+	device_t		sc_dev;
+	struct resource *	aintc_res;
+	bus_space_tag_t		aintc_bst;
+	bus_space_handle_t	aintc_bsh;
+	uint8_t			ver;
+};
+
+static struct a10_aintc_softc *a10_aintc_sc = NULL;
+
+#define	aintc_read_4(reg)	\
+	bus_space_read_4(a10_aintc_sc->aintc_bst, a10_aintc_sc->aintc_bsh, reg)
+#define	aintc_write_4(reg, val)		\
+	bus_space_write_4(a10_aintc_sc->aintc_bst, a10_aintc_sc->aintc_bsh, reg, val)
+
+static int
+a10_aintc_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "allwinner,sun4i-ic"))
+		return (ENXIO);
+	device_set_desc(dev, "A10 AINTC Interrupt Controller");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+a10_aintc_attach(device_t dev)
+{
+	struct a10_aintc_softc *sc = device_get_softc(dev);
+	int rid = 0;
+	int i;
+	
+	sc->sc_dev = dev;
+
+	if (a10_aintc_sc)
+		return (ENXIO);
+
+	sc->aintc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
+	if (!sc->aintc_res) {
+		device_printf(dev, "could not allocate resource\n");
+		return (ENXIO);
+	}
+
+	sc->aintc_bst = rman_get_bustag(sc->aintc_res);
+	sc->aintc_bsh = rman_get_bushandle(sc->aintc_res);
+
+	a10_aintc_sc = sc;
+
+	/* Disable & clear all interrupts */
+	for (i = 0; i < 3; i++) {
+		aintc_write_4(SW_INT_ENABLE_REG(i), 0);
+		aintc_write_4(SW_INT_MASK_REG(i), 0xffffffff);
+	}
+	/* enable protection mode*/
+	aintc_write_4(SW_INT_PROTECTION_REG, 0x01);
+
+	/* config the external interrupt source type*/
+	aintc_write_4(SW_INT_NMI_CTRL_REG, 0x00);
+
+	return (0);
+}
+
+static device_method_t a10_aintc_methods[] = {
+	DEVMETHOD(device_probe,		a10_aintc_probe),
+	DEVMETHOD(device_attach,	a10_aintc_attach),
+	{ 0, 0 }
+};
+
+static driver_t a10_aintc_driver = {
+	"aintc",
+	a10_aintc_methods,
+	sizeof(struct a10_aintc_softc),
+};
+
+static devclass_t a10_aintc_devclass;
+
+DRIVER_MODULE(aintc, simplebus, a10_aintc_driver, a10_aintc_devclass, 0, 0);
+
+int
+arm_get_next_irq(int last_irq)
+{
+	uint32_t value;
+	int i, b;
+
+	for (i = 0; i < 3; i++) {
+		value = aintc_read_4(SW_INT_IRQ_PENDING_REG(i));
+		for (b = 0; b < 32; b++)
+			if (value & (1 << b)) {
+				return (i * 32 + b);
+			}
+	}
+
+	return (-1);
+}
+
+void
+arm_mask_irq(uintptr_t nb)
+{
+	uint32_t bit, block, value;
+	
+	bit = (nb % 32);
+	block = (nb / 32);
+
+	value = aintc_read_4(SW_INT_ENABLE_REG(block));
+	value &= ~(1 << bit);
+	aintc_write_4(SW_INT_ENABLE_REG(block), value);
+
+	value = aintc_read_4(SW_INT_MASK_REG(block));
+	value |= (1 << bit);
+	aintc_write_4(SW_INT_MASK_REG(block), value);
+}
+
+void
+arm_unmask_irq(uintptr_t nb)
+{
+	uint32_t bit, block, value;
+
+	bit = (nb % 32);
+	block = (nb / 32);
+
+	value = aintc_read_4(SW_INT_ENABLE_REG(block));
+	value |= (1 << bit);
+	aintc_write_4(SW_INT_ENABLE_REG(block), value);
+
+	value = aintc_read_4(SW_INT_MASK_REG(block));
+	value &= ~(1 << bit);
+	aintc_write_4(SW_INT_MASK_REG(block), value);
+
+	if(nb == SW_INT_IRQNO_ENMI) /* must clear pending bit when enabled */
+		aintc_write_4(SW_INT_IRQ_PENDING_REG(0), (1 << SW_INT_IRQNO_ENMI));
+}


Property changes on: trunk/sys/arm/allwinner/aintc.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/allwinner/console.c
===================================================================
--- trunk/sys/arm/allwinner/console.c	                        (rev 0)
+++ trunk/sys/arm/allwinner/console.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,143 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Ganbold Tsagaankhuu <ganbold at freebsd.org>
+ * 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.
+ */
+
+/* Simple UART console driver for Allwinner A10 */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/allwinner/console.c 266337 2014-05-17 18:53:36Z ian $");
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/cons.h>
+#include <sys/consio.h>
+#include <sys/kernel.h>
+
+#ifndef	A10_UART_BASE
+#define	A10_UART_BASE	0xe1c28000 	/* UART0 */
+#endif
+
+#define	REG_SHIFT	2
+
+#define	UART_DLL	0	/* Out: Divisor Latch Low */
+#define	UART_DLM	1	/* Out: Divisor Latch High */
+#define	UART_FCR	2	/* Out: FIFO Control Register */
+#define	UART_LCR	3	/* Out: Line Control Register */
+#define	UART_MCR	4	/* Out: Modem Control Register */
+#define	UART_LSR	5	/* In:  Line Status Register */
+#define	UART_LSR_THRE	0x20	/* Transmit-hold-register empty */
+#define	UART_LSR_DR	0x01	/* Receiver data ready */
+#define	UART_MSR	6	/* In:  Modem Status Register */
+#define	UART_SCR	7	/* I/O: Scratch Register */
+
+static uint32_t
+uart_getreg(uint32_t *bas)
+{
+	return *((volatile uint32_t *)(bas)) & 0xff;
+}
+
+static void
+uart_setreg(uint32_t *bas, uint32_t val)
+{
+	*((volatile uint32_t *)(bas)) = val;
+}
+
+static int
+ub_getc(void)
+{
+	while ((uart_getreg((uint32_t *)(A10_UART_BASE + 
+	    (UART_LSR << REG_SHIFT))) & UART_LSR_DR) == 0);
+		__asm __volatile("nop");
+
+	return (uart_getreg((uint32_t *)A10_UART_BASE) & 0xff);
+}
+
+static void
+ub_putc(unsigned char c)
+{
+	if (c == '\n')
+		ub_putc('\r');
+
+	while ((uart_getreg((uint32_t *)(A10_UART_BASE + 
+	    (UART_LSR << REG_SHIFT))) & UART_LSR_THRE) == 0)
+		__asm __volatile("nop");
+
+	uart_setreg((uint32_t *)A10_UART_BASE, c);
+}
+
+static cn_probe_t	uart_cnprobe;
+static cn_init_t	uart_cninit;
+static cn_term_t	uart_cnterm;
+static cn_getc_t	uart_cngetc;
+static cn_putc_t	uart_cnputc;
+static cn_grab_t	uart_cngrab;
+static cn_ungrab_t	uart_cnungrab;
+
+static void
+uart_cngrab(struct consdev *cp)
+{
+}
+
+static void
+uart_cnungrab(struct consdev *cp)
+{
+}
+
+
+static void
+uart_cnprobe(struct consdev *cp)
+{
+	sprintf(cp->cn_name, "uart");
+	cp->cn_pri = CN_NORMAL;
+}
+
+static void
+uart_cninit(struct consdev *cp)
+{
+	uart_setreg((uint32_t *)(A10_UART_BASE + 
+	    (UART_FCR << REG_SHIFT)), 0x06);
+}
+
+void
+uart_cnputc(struct consdev *cp, int c)
+{
+	ub_putc(c);
+}
+
+int
+uart_cngetc(struct consdev * cp)
+{
+	return ub_getc();
+}
+
+static void
+uart_cnterm(struct consdev * cp)
+{
+}
+
+CONSOLE_DRIVER(uart);
+


Property changes on: trunk/sys/arm/allwinner/console.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/allwinner/files.a10
===================================================================
--- trunk/sys/arm/allwinner/files.a10	                        (rev 0)
+++ trunk/sys/arm/allwinner/files.a10	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,23 @@
+# $FreeBSD: stable/10/sys/arm/allwinner/files.a10 278727 2015-02-13 22:32:02Z ian $
+kern/kern_clocksource.c			standard
+
+arm/arm/bus_space_asm_generic.S		standard
+arm/arm/bus_space_generic.c		standard
+arm/arm/cpufunc_asm_armv5.S		standard
+arm/arm/cpufunc_asm_arm10.S		standard
+arm/arm/cpufunc_asm_arm11.S		standard
+arm/arm/cpufunc_asm_armv7.S		standard
+
+arm/allwinner/a10_clk.c			standard
+arm/allwinner/a10_common.c		standard
+arm/allwinner/a10_gpio.c		optional	gpio
+arm/allwinner/a10_ehci.c		optional	ehci
+arm/allwinner/a10_machdep.c		standard
+arm/allwinner/a10_sramc.c		standard
+arm/allwinner/a10_wdog.c		standard
+arm/allwinner/a20/a20_cpu_cfg.c 	standard
+arm/allwinner/aintc.c			standard
+arm/allwinner/if_emac.c			optional	emac
+arm/allwinner/timer.c			standard
+arm/arm/bus_space_base.c		standard
+#arm/allwinner/console.c		standard


Property changes on: trunk/sys/arm/allwinner/files.a10
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/allwinner/if_emac.c
===================================================================
--- trunk/sys/arm/allwinner/if_emac.c	                        (rev 0)
+++ trunk/sys/arm/allwinner/if_emac.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,1153 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Ganbold Tsagaankhuu <ganbold at freebsd.org>
+ * 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: stable/10/sys/arm/allwinner/if_emac.c 266337 2014-05-17 18:53:36Z ian $
+ */
+
+/* A10/A20 EMAC driver */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/allwinner/if_emac.c 266337 2014-05-17 18:53:36Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/lock.h>
+#include <sys/mbuf.h>
+#include <sys/mutex.h>
+#include <sys/rman.h>
+#include <sys/socket.h>
+#include <sys/sockio.h>
+#include <sys/sysctl.h>
+#include <sys/gpio.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+#include <machine/intr.h>
+
+#include <net/if.h>
+#include <net/if_var.h>
+#include <net/if_arp.h>
+#include <net/if_dl.h>
+#include <net/if_media.h>
+#include <net/if_types.h>
+#include <net/if_mib.h>
+#include <net/ethernet.h>
+#include <net/if_vlan_var.h>
+
+#ifdef INET
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#endif
+
+#include <net/bpf.h>
+#include <net/bpfdesc.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <dev/mii/mii.h>
+#include <dev/mii/miivar.h>
+
+#include <arm/allwinner/if_emacreg.h>
+
+#include "miibus_if.h"
+
+#include "gpio_if.h"
+
+#include "a10_clk.h"
+#include "a10_sramc.h"
+#include "a10_gpio.h"
+
+struct emac_softc {
+	struct ifnet		*emac_ifp;
+	device_t		emac_dev;
+	device_t		emac_miibus;
+	bus_space_handle_t	emac_handle;
+	bus_space_tag_t		emac_tag;
+	struct resource		*emac_res;
+	struct resource		*emac_irq;
+	void			*emac_intrhand;
+	int			emac_if_flags;
+	struct mtx		emac_mtx;
+	struct callout		emac_tick_ch;
+	int			emac_watchdog_timer;
+	int			emac_rx_process_limit;
+	int			emac_link;
+};
+
+static int	emac_probe(device_t);
+static int	emac_attach(device_t);
+static int	emac_detach(device_t);
+static int	emac_shutdown(device_t);
+static int	emac_suspend(device_t);
+static int	emac_resume(device_t);
+
+static void	emac_sys_setup(void);
+static void	emac_reset(struct emac_softc *);
+
+static void	emac_init_locked(struct emac_softc *);
+static void	emac_start_locked(struct ifnet *);
+static void	emac_init(void *);
+static void	emac_stop_locked(struct emac_softc *);
+static void	emac_intr(void *);
+static int	emac_ioctl(struct ifnet *, u_long, caddr_t);
+
+static void	emac_rxeof(struct emac_softc *, int);
+static void	emac_txeof(struct emac_softc *);
+
+static int	emac_miibus_readreg(device_t, int, int);
+static int	emac_miibus_writereg(device_t, int, int, int);
+static void	emac_miibus_statchg(device_t);
+
+static int	emac_ifmedia_upd(struct ifnet *);
+static void	emac_ifmedia_sts(struct ifnet *, struct ifmediareq *);
+
+static int	sysctl_int_range(SYSCTL_HANDLER_ARGS, int, int);
+static int	sysctl_hw_emac_proc_limit(SYSCTL_HANDLER_ARGS);
+
+#define	EMAC_READ_REG(sc, reg)		\
+    bus_space_read_4(sc->emac_tag, sc->emac_handle, reg)
+#define	EMAC_WRITE_REG(sc, reg, val)	\
+    bus_space_write_4(sc->emac_tag, sc->emac_handle, reg, val)
+
+static void
+emac_sys_setup(void)
+{
+	int i;
+
+	a10_clk_emac_activate();
+
+	/*
+	 * Configure pin mux settings for MII.
+	 * Pins PA0 from PA17.
+	 */
+	for (i = 0; i <= 17; i++)
+		a10_emac_gpio_config(i);
+	/* Map sram */
+	a10_map_to_emac();
+}
+
+static void
+emac_get_hwaddr(struct emac_softc *sc, uint8_t *hwaddr)
+{
+	uint32_t val0, val1, rnd;
+
+	/*
+	 * Try to get MAC address from running hardware.
+	 * If there is something non-zero there just use it.
+	 *
+	 * Otherwise set the address to a convenient locally assigned address,
+	 * 'bsd' + random 24 low-order bits. 'b' is 0x62, which has the locally
+	 * assigned bit set, and the broadcast/multicast bit clear.
+	 */
+	val0 = EMAC_READ_REG(sc, EMAC_MAC_A0);
+	val1 = EMAC_READ_REG(sc, EMAC_MAC_A1);
+	if ((val0 | val1) != 0 && (val0 | val1) != 0xffffff) {
+		hwaddr[0] = (val1 >> 16) & 0xff;
+		hwaddr[1] = (val1 >> 8) & 0xff;
+		hwaddr[2] = (val1 >> 0) & 0xff;
+		hwaddr[3] = (val0 >> 16) & 0xff;
+		hwaddr[4] = (val0 >> 8) & 0xff;
+		hwaddr[5] = (val0 >> 0) & 0xff;
+	} else {
+		rnd = arc4random() & 0x00ffffff;
+		hwaddr[0] = 'b';
+		hwaddr[1] = 's';
+		hwaddr[2] = 'd';
+		hwaddr[3] = (rnd >> 16) & 0xff;
+		hwaddr[4] = (rnd >> 8) & 0xff;
+		hwaddr[5] = (rnd >> 0) & 0xff;
+	}
+	if (bootverbose)
+		printf("MAC address: %s\n", ether_sprintf(hwaddr));
+}
+
+static void
+emac_set_rx_mode(struct emac_softc *sc)
+{
+	struct ifnet *ifp;
+	struct ifmultiaddr *ifma;
+	uint32_t h, hashes[2];
+	uint32_t rcr = 0;
+
+	EMAC_ASSERT_LOCKED(sc);
+
+	ifp = sc->emac_ifp;
+
+	rcr = EMAC_READ_REG(sc, EMAC_RX_CTL);
+
+	/* Unicast packet and DA filtering */
+	rcr |= EMAC_RX_UCAD;
+	rcr |= EMAC_RX_DAF;
+
+	hashes[0] = 0;
+	hashes[1] = 0;
+	if (ifp->if_flags & IFF_ALLMULTI) {
+		hashes[0] = 0xffffffff;
+		hashes[1] = 0xffffffff;
+	} else {
+		if_maddr_rlock(ifp);
+		TAILQ_FOREACH(ifma, &sc->emac_ifp->if_multiaddrs, ifma_link) {
+			if (ifma->ifma_addr->sa_family != AF_LINK)
+				continue;
+			h = ether_crc32_be(LLADDR((struct sockaddr_dl *)
+			    ifma->ifma_addr), ETHER_ADDR_LEN) >> 26;
+			hashes[h >> 5] |= 1 << (h & 0x1f);
+		}
+		if_maddr_runlock(ifp);
+	}
+	rcr |= EMAC_RX_MCO;
+	rcr |= EMAC_RX_MHF;
+	EMAC_WRITE_REG(sc, EMAC_RX_HASH0, hashes[0]);
+	EMAC_WRITE_REG(sc, EMAC_RX_HASH1, hashes[1]);
+
+	if (ifp->if_flags & IFF_BROADCAST) {
+		rcr |= EMAC_RX_BCO;
+		rcr |= EMAC_RX_MCO;
+	}
+
+	if (ifp->if_flags & IFF_PROMISC)
+		rcr |= EMAC_RX_PA;
+	else
+		rcr |= EMAC_RX_UCAD;
+
+	EMAC_WRITE_REG(sc, EMAC_RX_CTL, rcr);
+}
+
+static void
+emac_reset(struct emac_softc *sc)
+{
+
+	EMAC_WRITE_REG(sc, EMAC_CTL, 0);
+	DELAY(200);
+	EMAC_WRITE_REG(sc, EMAC_CTL, 1);
+	DELAY(200);
+}
+
+static void
+emac_txeof(struct emac_softc *sc)
+{
+	struct ifnet *ifp;
+
+	EMAC_ASSERT_LOCKED(sc);
+
+	ifp = sc->emac_ifp;
+	ifp->if_opackets++;
+	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+
+	/* Unarm watchdog timer if no TX */
+	sc->emac_watchdog_timer = 0;
+}
+
+static void
+emac_rxeof(struct emac_softc *sc, int count)
+{
+	struct ifnet *ifp;
+	struct mbuf *m, *m0;
+	uint32_t reg_val, rxcount;
+	int16_t len;
+	uint16_t status;
+	int good_packet, i;
+
+	ifp = sc->emac_ifp;
+	for (; count > 0 &&
+	    (ifp->if_drv_flags & IFF_DRV_RUNNING) != 0; count--) {
+		/*
+		 * Race warning: The first packet might arrive with
+		 * the interrupts disabled, but the second will fix
+		 */
+		rxcount = EMAC_READ_REG(sc, EMAC_RX_FBC);
+		if (!rxcount) {
+			/* Had one stuck? */
+			rxcount = EMAC_READ_REG(sc, EMAC_RX_FBC);
+			if (!rxcount)
+				return;
+		}
+		/* Check packet header */
+		reg_val = EMAC_READ_REG(sc, EMAC_RX_IO_DATA);
+		if (reg_val != EMAC_PACKET_HEADER) {
+			/* Packet header is wrong */
+			if (bootverbose)
+				if_printf(ifp, "wrong packet header\n");
+			/* Disable RX */
+			reg_val = EMAC_READ_REG(sc, EMAC_CTL);
+			reg_val &= ~EMAC_CTL_RX_EN;
+			EMAC_WRITE_REG(sc, EMAC_CTL, reg_val);
+
+			/* Flush RX FIFO */
+			reg_val = EMAC_READ_REG(sc, EMAC_RX_CTL);
+			reg_val |= EMAC_RX_FLUSH_FIFO;
+			EMAC_WRITE_REG(sc, EMAC_RX_CTL, reg_val);
+			for (i = 100; i > 0; i--) {
+				DELAY(100);
+				if ((EMAC_READ_REG(sc, EMAC_RX_CTL) &
+				    EMAC_RX_FLUSH_FIFO) == 0)
+					break;
+			}
+			if (i == 0) {
+				device_printf(sc->emac_dev,
+				    "flush FIFO timeout\n");
+				/* Reinitialize controller */
+				emac_init_locked(sc);
+				return;
+			}
+			/* Enable RX */
+			reg_val = EMAC_READ_REG(sc, EMAC_CTL);
+			reg_val |= EMAC_CTL_RX_EN;
+			EMAC_WRITE_REG(sc, EMAC_CTL, reg_val);
+
+			return;
+		}
+
+		good_packet = 1;
+
+		/* Get packet size and status */
+		reg_val = EMAC_READ_REG(sc, EMAC_RX_IO_DATA);
+		len = reg_val & 0xffff;
+		status = (reg_val >> 16) & 0xffff;
+
+		if (len < 64) {
+			good_packet = 0;
+			if (bootverbose)
+				if_printf(ifp,
+				    "bad packet: len = %i status = %i\n",
+				    len, status);
+			ifp->if_ierrors++;
+		}
+#if 0
+		if (status & (EMAC_CRCERR | EMAC_LENERR)) {
+			good_packet = 0;
+			ifp->if_ierrors++;
+			if (status & EMAC_CRCERR)
+				if_printf(ifp, "crc error\n");
+			if (status & EMAC_LENERR)
+				if_printf(ifp, "length error\n");
+		}
+#endif
+		if (good_packet) {
+			m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
+			if (m == NULL)
+				return;
+			m->m_len = m->m_pkthdr.len = MCLBYTES;
+
+			len -= ETHER_CRC_LEN;
+
+			/* Copy entire frame to mbuf first. */
+			bus_space_read_multi_4(sc->emac_tag, sc->emac_handle,
+			    EMAC_RX_IO_DATA, mtod(m, uint32_t *),
+			    roundup2(len, 4) / 4);
+
+			m->m_pkthdr.rcvif = ifp;
+			m->m_len = m->m_pkthdr.len = len;
+
+			/*
+			 * Emac controller needs strict aligment, so to avoid
+			 * copying over an entire frame to align, we allocate
+			 * a new mbuf and copy ethernet header + IP header to
+			 * the new mbuf. The new mbuf is prepended into the
+			 * existing mbuf chain.
+			 */
+			if (m->m_len <= (MHLEN - ETHER_HDR_LEN)) {
+				bcopy(m->m_data, m->m_data + ETHER_HDR_LEN,
+				    m->m_len);
+				m->m_data += ETHER_HDR_LEN;
+			} else if (m->m_len <= (MCLBYTES - ETHER_HDR_LEN) &&
+			    m->m_len > (MHLEN - ETHER_HDR_LEN)) {
+				MGETHDR(m0, M_NOWAIT, MT_DATA);
+				if (m0 != NULL) {
+					len = ETHER_HDR_LEN +
+					    m->m_pkthdr.l2hlen;
+					bcopy(m->m_data, m0->m_data, len);
+					m->m_data += len;
+					m->m_len -= len;
+					m0->m_len = len;
+					M_MOVE_PKTHDR(m0, m);
+					m0->m_next = m;
+					m = m0;
+				} else {
+					ifp->if_ierrors++;
+					m_freem(m);
+					m = NULL;
+					continue;
+				}
+			} else if (m->m_len > EMAC_MAC_MAXF) {
+				ifp->if_ierrors++;
+				m_freem(m);
+				m = NULL;
+				continue;
+			}
+			ifp->if_ipackets++;
+			EMAC_UNLOCK(sc);
+			(*ifp->if_input)(ifp, m);
+			EMAC_LOCK(sc);
+		}
+	}
+}
+
+static void
+emac_watchdog(struct emac_softc *sc)
+{
+	struct ifnet *ifp;
+
+	EMAC_ASSERT_LOCKED(sc);
+
+	if (sc->emac_watchdog_timer == 0 || --sc->emac_watchdog_timer)
+		return;
+
+	ifp = sc->emac_ifp;
+
+	if (sc->emac_link == 0) {
+		if (bootverbose)
+			if_printf(sc->emac_ifp, "watchdog timeout "
+			    "(missed link)\n");
+	} else
+		if_printf(sc->emac_ifp, "watchdog timeout -- resetting\n");
+	
+	ifp->if_oerrors++;
+	ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
+	emac_init_locked(sc);
+	if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
+		emac_start_locked(ifp);
+}
+
+static void
+emac_tick(void *arg)
+{
+	struct emac_softc *sc;
+	struct mii_data *mii;
+
+	sc = (struct emac_softc *)arg;
+	mii = device_get_softc(sc->emac_miibus);
+	mii_tick(mii);
+
+	emac_watchdog(sc);
+	callout_reset(&sc->emac_tick_ch, hz, emac_tick, sc);
+}
+
+static void
+emac_init(void *xcs)
+{
+	struct emac_softc *sc;
+
+	sc = (struct emac_softc *)xcs;
+	EMAC_LOCK(sc);
+	emac_init_locked(sc);
+	EMAC_UNLOCK(sc);
+}
+
+static void
+emac_init_locked(struct emac_softc *sc)
+{
+	struct ifnet *ifp;
+	struct mii_data *mii;
+	uint32_t reg_val;
+	uint8_t *eaddr;
+
+	EMAC_ASSERT_LOCKED(sc);
+
+	ifp = sc->emac_ifp;
+	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
+		return;
+
+	/* Flush RX FIFO */
+	reg_val = EMAC_READ_REG(sc, EMAC_RX_CTL);
+	reg_val |= EMAC_RX_FLUSH_FIFO;
+	EMAC_WRITE_REG(sc, EMAC_RX_CTL, reg_val);
+	DELAY(1);
+
+	/* Soft reset MAC */
+	reg_val = EMAC_READ_REG(sc, EMAC_MAC_CTL0);
+	reg_val &= (~EMAC_MAC_CTL0_SOFT_RST);
+	EMAC_WRITE_REG(sc, EMAC_MAC_CTL0, reg_val);
+
+	/* Set MII clock */
+	reg_val = EMAC_READ_REG(sc, EMAC_MAC_MCFG);
+	reg_val &= (~(0xf << 2));
+	reg_val |= (0xd << 2);
+	EMAC_WRITE_REG(sc, EMAC_MAC_MCFG, reg_val);
+
+	/* Clear RX counter */
+	EMAC_WRITE_REG(sc, EMAC_RX_FBC, 0);
+
+	/* Disable all interrupt and clear interrupt status */
+	EMAC_WRITE_REG(sc, EMAC_INT_CTL, 0);
+	reg_val = EMAC_READ_REG(sc, EMAC_INT_STA);
+	EMAC_WRITE_REG(sc, EMAC_INT_STA, reg_val);
+	DELAY(1);
+
+	/* Set up TX */
+	reg_val = EMAC_READ_REG(sc, EMAC_TX_MODE);
+	reg_val |= EMAC_TX_AB_M;
+	reg_val &= EMAC_TX_TM;
+	EMAC_WRITE_REG(sc, EMAC_TX_MODE, reg_val);
+
+	/* Set up RX */
+	reg_val = EMAC_READ_REG(sc, EMAC_RX_CTL);
+	reg_val |= EMAC_RX_SETUP;
+	reg_val &= EMAC_RX_TM;
+	EMAC_WRITE_REG(sc, EMAC_RX_CTL, reg_val);
+
+	/* Set up MAC CTL0. */
+	reg_val = EMAC_READ_REG(sc, EMAC_MAC_CTL0);
+	reg_val |= EMAC_MAC_CTL0_SETUP;
+	EMAC_WRITE_REG(sc, EMAC_MAC_CTL0, reg_val);
+
+	/* Set up MAC CTL1. */
+	reg_val = EMAC_READ_REG(sc, EMAC_MAC_CTL1);
+	reg_val |= EMAC_MAC_CTL1_SETUP;
+	EMAC_WRITE_REG(sc, EMAC_MAC_CTL1, reg_val);
+
+	/* Set up IPGT */
+	EMAC_WRITE_REG(sc, EMAC_MAC_IPGT, EMAC_MAC_IPGT_FD);
+
+	/* Set up IPGR */
+	EMAC_WRITE_REG(sc, EMAC_MAC_IPGR, EMAC_MAC_NBTB_IPG2 |
+	    (EMAC_MAC_NBTB_IPG1 << 8));
+
+	/* Set up Collison window */
+	EMAC_WRITE_REG(sc, EMAC_MAC_CLRT, EMAC_MAC_RM | (EMAC_MAC_CW << 8));
+
+	/* Set up Max Frame Length */
+	EMAC_WRITE_REG(sc, EMAC_MAC_MAXF, EMAC_MAC_MFL);
+
+	/* Setup ethernet address */
+	eaddr = IF_LLADDR(ifp);
+	EMAC_WRITE_REG(sc, EMAC_MAC_A1, eaddr[0] << 16 |
+	    eaddr[1] << 8 | eaddr[2]);
+	EMAC_WRITE_REG(sc, EMAC_MAC_A0, eaddr[3] << 16 |
+	    eaddr[4] << 8 | eaddr[5]);
+
+	/* Setup rx filter */
+	emac_set_rx_mode(sc);
+
+	/* Enable RX/TX0/RX Hlevel interrupt */
+	reg_val = EMAC_READ_REG(sc, EMAC_INT_CTL);
+	reg_val |= EMAC_INT_EN;
+	EMAC_WRITE_REG(sc, EMAC_INT_CTL, reg_val);
+
+	ifp->if_drv_flags |= IFF_DRV_RUNNING;
+	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+
+	sc->emac_link = 0;
+
+	/* Switch to the current media. */
+	mii = device_get_softc(sc->emac_miibus);
+	mii_mediachg(mii);
+
+	callout_reset(&sc->emac_tick_ch, hz, emac_tick, sc);
+}
+
+
+static void
+emac_start(struct ifnet *ifp)
+{
+	struct emac_softc *sc;
+
+	sc = ifp->if_softc;
+	EMAC_LOCK(sc);
+	emac_start_locked(ifp);
+	EMAC_UNLOCK(sc);
+}
+
+static void
+emac_start_locked(struct ifnet *ifp)
+{
+	struct emac_softc *sc;
+	struct mbuf *m, *m0;
+	uint32_t reg_val;
+
+	sc = ifp->if_softc;
+	if (ifp->if_drv_flags & IFF_DRV_OACTIVE)
+		return;
+	if (sc->emac_link == 0)
+		return;
+	IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
+	if (m == NULL)
+		return;
+
+	/* Select channel */
+	EMAC_WRITE_REG(sc, EMAC_TX_INS, 0);
+
+	/*
+	 * Emac controller wants 4 byte aligned TX buffers.
+	 * We have to copy pretty much all the time.
+	 */
+	if (m->m_next != NULL || (mtod(m, uintptr_t) & 3) != 0) {
+		m0 = m_defrag(m, M_NOWAIT);
+		if (m0 == NULL) {
+			m_freem(m);
+			m = NULL;
+			return;
+		}
+		m = m0;
+	}
+	/* Write data */
+	bus_space_write_multi_4(sc->emac_tag, sc->emac_handle,
+	    EMAC_TX_IO_DATA, mtod(m, uint32_t *),
+	    roundup2(m->m_len, 4) / 4);
+
+	/* Send the data lengh. */
+	EMAC_WRITE_REG(sc, EMAC_TX_PL0, m->m_len);
+
+	/* Start translate from fifo to phy. */
+	reg_val = EMAC_READ_REG(sc, EMAC_TX_CTL0);
+	reg_val |= 1;
+	EMAC_WRITE_REG(sc, EMAC_TX_CTL0, reg_val);
+
+	/* Set timeout */
+	sc->emac_watchdog_timer = 5;
+
+	ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+	BPF_MTAP(ifp, m);
+	m_freem(m);
+}
+
+static void
+emac_stop_locked(struct emac_softc *sc)
+{
+	struct ifnet *ifp;
+	uint32_t reg_val;
+
+	EMAC_ASSERT_LOCKED(sc);
+
+	ifp = sc->emac_ifp;
+	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+	sc->emac_link = 0;
+
+	/* Disable all interrupt and clear interrupt status */
+	EMAC_WRITE_REG(sc, EMAC_INT_CTL, 0);
+	reg_val = EMAC_READ_REG(sc, EMAC_INT_STA);
+	EMAC_WRITE_REG(sc, EMAC_INT_STA, reg_val);
+
+	/* Disable RX/TX */
+	reg_val = EMAC_READ_REG(sc, EMAC_CTL);
+	reg_val &= ~(EMAC_CTL_RST | EMAC_CTL_TX_EN | EMAC_CTL_RX_EN);
+	EMAC_WRITE_REG(sc, EMAC_CTL, reg_val);
+
+	callout_stop(&sc->emac_tick_ch);
+}
+
+static void
+emac_intr(void *arg)
+{
+	struct emac_softc *sc;
+	struct ifnet *ifp;
+	uint32_t reg_val;
+
+	sc = (struct emac_softc *)arg;
+	EMAC_LOCK(sc);
+	ifp = sc->emac_ifp;
+	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+		return;
+
+	/* Disable all interrupts */
+	EMAC_WRITE_REG(sc, EMAC_INT_CTL, 0);
+	/* Get EMAC interrupt status */
+	reg_val = EMAC_READ_REG(sc, EMAC_INT_STA);
+	/* Clear ISR status */
+	EMAC_WRITE_REG(sc, EMAC_INT_STA, reg_val);
+
+	/* Received incoming packet */
+	if (reg_val & EMAC_INT_STA_RX)
+		emac_rxeof(sc, sc->emac_rx_process_limit);
+
+	/* Transmit Interrupt check */
+	if (reg_val & EMAC_INT_STA_TX){
+		emac_txeof(sc);
+		if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
+			emac_start_locked(ifp);
+	}
+
+	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) {
+		/* Re-enable interrupt mask */
+		reg_val = EMAC_READ_REG(sc, EMAC_INT_CTL);
+		reg_val |= EMAC_INT_EN;
+		EMAC_WRITE_REG(sc, EMAC_INT_CTL, reg_val);
+	}
+	EMAC_UNLOCK(sc);
+}
+
+static int
+emac_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
+{
+	struct emac_softc *sc;
+	struct mii_data *mii;
+	struct ifreq *ifr;
+	int error = 0;
+
+	sc = ifp->if_softc;
+	ifr = (struct ifreq *)data;
+
+	switch (command) {
+	case SIOCSIFFLAGS:
+		EMAC_LOCK(sc);
+		if (ifp->if_flags & IFF_UP) {
+			if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) {
+				if ((ifp->if_flags ^ sc->emac_if_flags) &
+				    (IFF_PROMISC | IFF_ALLMULTI))
+					emac_set_rx_mode(sc);
+			} else
+				emac_init_locked(sc);
+		} else {
+			if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
+				emac_stop_locked(sc);
+		}
+		sc->emac_if_flags = ifp->if_flags;
+		EMAC_UNLOCK(sc);
+		break;
+	case SIOCADDMULTI:
+	case SIOCDELMULTI:
+		EMAC_LOCK(sc);
+		if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
+			emac_set_rx_mode(sc);
+		}
+		EMAC_UNLOCK(sc);
+		break;
+	case SIOCGIFMEDIA:
+	case SIOCSIFMEDIA:
+		mii = device_get_softc(sc->emac_miibus);
+		error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command);
+		break;
+	default:
+		error = ether_ioctl(ifp, command, data);
+		break;
+	}
+	return (error);
+}
+
+static int
+emac_probe(device_t dev)
+{
+
+	if (!ofw_bus_is_compatible(dev, "allwinner,sun4i-emac"))
+		return (ENXIO);
+
+	device_set_desc(dev, "A10/A20 EMAC ethernet controller");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+emac_detach(device_t dev)
+{
+	struct emac_softc *sc;
+
+	sc = device_get_softc(dev);
+	sc->emac_ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
+	if (device_is_attached(dev)) {
+		ether_ifdetach(sc->emac_ifp);
+		EMAC_LOCK(sc);
+		emac_stop_locked(sc);
+		EMAC_UNLOCK(sc);
+		callout_drain(&sc->emac_tick_ch);
+	}
+
+	if (sc->emac_intrhand != NULL)
+		bus_teardown_intr(sc->emac_dev, sc->emac_irq,
+		    sc->emac_intrhand);
+
+	if (sc->emac_miibus != NULL) {
+		device_delete_child(sc->emac_dev, sc->emac_miibus);
+		bus_generic_detach(sc->emac_dev);
+	}
+
+	if (sc->emac_res != NULL)
+		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->emac_res);
+
+	if (sc->emac_irq != NULL)
+		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->emac_irq);
+
+	if (sc->emac_ifp != NULL)
+		if_free(sc->emac_ifp);
+
+	if (mtx_initialized(&sc->emac_mtx))
+		mtx_destroy(&sc->emac_mtx);
+
+	return (0);
+}
+
+static int
+emac_shutdown(device_t dev)
+{
+
+	return (emac_suspend(dev));
+}
+
+static int
+emac_suspend(device_t dev)
+{
+	struct emac_softc *sc;
+	struct ifnet *ifp;
+
+	sc = device_get_softc(dev);
+
+	EMAC_LOCK(sc);
+	ifp = sc->emac_ifp;
+	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
+		emac_stop_locked(sc);
+	EMAC_UNLOCK(sc);
+
+	return (0);
+}
+
+static int
+emac_resume(device_t dev)
+{
+	struct emac_softc *sc;
+	struct ifnet *ifp;
+
+	sc = device_get_softc(dev);
+
+	EMAC_LOCK(sc);
+	ifp = sc->emac_ifp;
+	if ((ifp->if_flags & IFF_UP) != 0) {
+		ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
+		emac_init_locked(sc);
+	}
+	EMAC_UNLOCK(sc);
+
+	return (0);
+}
+
+static int
+emac_attach(device_t dev)
+{
+	struct emac_softc *sc;
+	struct ifnet *ifp;
+	int error, rid;
+	uint8_t eaddr[ETHER_ADDR_LEN];
+
+	sc = device_get_softc(dev);
+	sc->emac_dev = dev;
+
+	error = 0;
+	mtx_init(&sc->emac_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
+	    MTX_DEF);
+	callout_init_mtx(&sc->emac_tick_ch, &sc->emac_mtx, 0);
+
+	rid = 0;
+	sc->emac_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	    RF_ACTIVE);
+	if (sc->emac_res == NULL) {
+		device_printf(dev, "unable to map memory\n");
+		error = ENXIO;
+		goto fail;
+	}
+
+	sc->emac_tag = rman_get_bustag(sc->emac_res);
+	sc->emac_handle = rman_get_bushandle(sc->emac_res);
+
+	rid = 0;
+	sc->emac_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+	    RF_SHAREABLE | RF_ACTIVE);
+	if (sc->emac_irq == NULL) {
+		device_printf(dev, "cannot allocate IRQ resources.\n");
+		error = ENXIO;
+		goto fail;
+	}
+	/* Create device sysctl node. */
+	SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
+	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+	    OID_AUTO, "process_limit", CTLTYPE_INT | CTLFLAG_RW,
+	    &sc->emac_rx_process_limit, 0, sysctl_hw_emac_proc_limit, "I",
+	    "max number of Rx events to process");
+
+	sc->emac_rx_process_limit = EMAC_PROC_DEFAULT;
+	error = resource_int_value(device_get_name(dev), device_get_unit(dev),
+	    "process_limit", &sc->emac_rx_process_limit);
+	if (error == 0) {
+		if (sc->emac_rx_process_limit < EMAC_PROC_MIN ||
+		    sc->emac_rx_process_limit > EMAC_PROC_MAX) {
+			device_printf(dev, "process_limit value out of range; "
+			    "using default: %d\n", EMAC_PROC_DEFAULT);
+			sc->emac_rx_process_limit = EMAC_PROC_DEFAULT;
+		}
+	}
+	/* Setup EMAC */
+	emac_sys_setup();
+	emac_reset(sc);
+
+	ifp = sc->emac_ifp = if_alloc(IFT_ETHER);
+	if (ifp == NULL) {
+		device_printf(dev, "unable to allocate ifp\n");
+		error = ENOSPC;
+		goto fail;
+	}
+	ifp->if_softc = sc;
+
+	/* Setup MII */
+	error = mii_attach(dev, &sc->emac_miibus, ifp, emac_ifmedia_upd,
+	    emac_ifmedia_sts, BMSR_DEFCAPMASK, MII_PHY_ANY, MII_OFFSET_ANY, 0);
+	if (error != 0) {
+		device_printf(dev, "PHY probe failed\n");
+		goto fail;
+	}
+
+	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
+	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+	ifp->if_start = emac_start;
+	ifp->if_ioctl = emac_ioctl;
+	ifp->if_init = emac_init;
+	IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
+
+	/* Get MAC address */
+	emac_get_hwaddr(sc, eaddr);
+	ether_ifattach(ifp, eaddr);
+
+	/* VLAN capability setup. */
+	ifp->if_capabilities |= IFCAP_VLAN_MTU;
+	ifp->if_capenable = ifp->if_capabilities;
+	/* Tell the upper layer we support VLAN over-sized frames. */
+	ifp->if_hdrlen = sizeof(struct ether_vlan_header);
+
+	error = bus_setup_intr(dev, sc->emac_irq, INTR_TYPE_NET | INTR_MPSAFE,
+	    NULL, emac_intr, sc, &sc->emac_intrhand);
+	if (error != 0) {
+		device_printf(dev, "could not set up interrupt handler.\n");
+		ether_ifdetach(ifp);
+		goto fail;
+	}
+
+fail:
+	if (error != 0)
+		emac_detach(dev);
+	return (error);
+}
+
+static boolean_t
+emac_miibus_iowait(struct emac_softc *sc)
+{
+	uint32_t timeout;
+
+	for (timeout = 100; timeout != 0; --timeout) {
+		DELAY(100);
+		if ((EMAC_READ_REG(sc, EMAC_MAC_MIND) & 0x1) == 0)
+			return (true);
+	}
+
+	return (false);
+}
+
+/*
+ * The MII bus interface
+ */
+static int
+emac_miibus_readreg(device_t dev, int phy, int reg)
+{
+	struct emac_softc *sc;
+	int rval;
+
+	sc = device_get_softc(dev);
+
+	/* Issue phy address and reg */
+	EMAC_WRITE_REG(sc, EMAC_MAC_MADR, (phy << 8) | reg);
+	/* Pull up the phy io line */
+	EMAC_WRITE_REG(sc, EMAC_MAC_MCMD, 0x1);
+	if (!emac_miibus_iowait(sc)) {
+		device_printf(dev, "timeout waiting for mii read\n");
+		return (0);
+	}
+	/* Push down the phy io line */
+	EMAC_WRITE_REG(sc, EMAC_MAC_MCMD, 0x0);
+	/* Read data */
+	rval = EMAC_READ_REG(sc, EMAC_MAC_MRDD);
+
+	return (rval);
+}
+
+static int
+emac_miibus_writereg(device_t dev, int phy, int reg, int data)
+{
+	struct emac_softc *sc;
+
+	sc = device_get_softc(dev);
+
+	/* Issue phy address and reg */
+	EMAC_WRITE_REG(sc, EMAC_MAC_MADR, (phy << 8) | reg);
+	/* Write data */
+	EMAC_WRITE_REG(sc, EMAC_MAC_MWTD, data);
+	/* Pull up the phy io line */
+	EMAC_WRITE_REG(sc, EMAC_MAC_MCMD, 0x1);
+	if (!emac_miibus_iowait(sc)) {
+		device_printf(dev, "timeout waiting for mii write\n");
+		return (0);
+	}
+	/* Push down the phy io line */
+	EMAC_WRITE_REG(sc, EMAC_MAC_MCMD, 0x0);
+
+	return (0);
+}
+
+static void
+emac_miibus_statchg(device_t dev)
+{
+	struct emac_softc *sc;
+	struct mii_data *mii;
+	struct ifnet *ifp;
+	uint32_t reg_val;
+
+	sc = device_get_softc(dev);
+
+	mii = device_get_softc(sc->emac_miibus);
+	ifp = sc->emac_ifp;
+	if (mii == NULL || ifp == NULL ||
+	    (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+		return;
+
+	sc->emac_link = 0;
+	if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) ==
+	    (IFM_ACTIVE | IFM_AVALID)) {
+		switch (IFM_SUBTYPE(mii->mii_media_active)) {
+		case IFM_10_T:
+		case IFM_100_TX:
+			sc->emac_link = 1;
+			break;
+		default:
+			break;
+		}
+	}
+	/* Program MACs with resolved speed/duplex. */
+	if (sc->emac_link != 0) {
+		reg_val = EMAC_READ_REG(sc, EMAC_MAC_IPGT);
+		if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0) {
+			reg_val &= ~EMAC_MAC_IPGT_HD;
+			reg_val |= EMAC_MAC_IPGT_FD;
+		} else {
+			reg_val &= ~EMAC_MAC_IPGT_FD;
+			reg_val |= EMAC_MAC_IPGT_HD;
+		}
+		EMAC_WRITE_REG(sc, EMAC_MAC_IPGT, reg_val);
+		/* Enable RX/TX */
+		reg_val = EMAC_READ_REG(sc, EMAC_CTL);
+		reg_val |= EMAC_CTL_RST | EMAC_CTL_TX_EN | EMAC_CTL_RX_EN;
+		EMAC_WRITE_REG(sc, EMAC_CTL, reg_val);
+	} else {
+		/* Disable RX/TX */
+		reg_val = EMAC_READ_REG(sc, EMAC_CTL);
+		reg_val &= ~(EMAC_CTL_RST | EMAC_CTL_TX_EN | EMAC_CTL_RX_EN);
+		EMAC_WRITE_REG(sc, EMAC_CTL, reg_val);
+	}
+}
+
+static int
+emac_ifmedia_upd(struct ifnet *ifp)
+{
+	struct emac_softc *sc;
+	struct mii_data *mii;
+	struct mii_softc *miisc;
+	int error;
+
+	sc = ifp->if_softc;
+	mii = device_get_softc(sc->emac_miibus);
+	EMAC_LOCK(sc);
+	LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
+		PHY_RESET(miisc);
+	error = mii_mediachg(mii);
+	EMAC_UNLOCK(sc);
+
+	return (error);
+}
+
+static void
+emac_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
+{
+	struct emac_softc *sc;
+	struct mii_data *mii;
+
+	sc = ifp->if_softc;
+	mii = device_get_softc(sc->emac_miibus);
+
+	EMAC_LOCK(sc);
+	mii_pollstat(mii);
+	ifmr->ifm_active = mii->mii_media_active;
+	ifmr->ifm_status = mii->mii_media_status;
+	EMAC_UNLOCK(sc);
+}
+
+static device_method_t emac_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		emac_probe),
+	DEVMETHOD(device_attach,	emac_attach),
+	DEVMETHOD(device_detach,	emac_detach),
+	DEVMETHOD(device_shutdown,	emac_shutdown),
+	DEVMETHOD(device_suspend,	emac_suspend),
+	DEVMETHOD(device_resume,	emac_resume),
+
+	/* bus interface, for miibus */
+	DEVMETHOD(bus_print_child,	bus_generic_print_child),
+	DEVMETHOD(bus_driver_added,	bus_generic_driver_added),
+
+	/* MII interface */
+	DEVMETHOD(miibus_readreg,	emac_miibus_readreg),
+	DEVMETHOD(miibus_writereg,	emac_miibus_writereg),
+	DEVMETHOD(miibus_statchg,	emac_miibus_statchg),
+
+	DEVMETHOD_END
+};
+
+static driver_t emac_driver = {
+	"emac",
+	emac_methods,
+	sizeof(struct emac_softc)
+};
+
+static devclass_t emac_devclass;
+
+DRIVER_MODULE(emac, simplebus, emac_driver, emac_devclass, 0, 0);
+DRIVER_MODULE(miibus, emac, miibus_driver, miibus_devclass, 0, 0);
+MODULE_DEPEND(emac, miibus, 1, 1, 1);
+MODULE_DEPEND(emac, ether, 1, 1, 1);
+
+static int
+sysctl_int_range(SYSCTL_HANDLER_ARGS, int low, int high)
+{
+	int error, value;
+
+	if (arg1 == NULL)
+		return (EINVAL);
+	value = *(int *)arg1;
+	error = sysctl_handle_int(oidp, &value, 0, req);
+	if (error || req->newptr == NULL)
+		return (error);
+	if (value < low || value > high)
+		return (EINVAL);
+	*(int *)arg1 = value;
+
+	return (0);
+}
+
+static int
+sysctl_hw_emac_proc_limit(SYSCTL_HANDLER_ARGS)
+{
+
+	return (sysctl_int_range(oidp, arg1, arg2, req,
+	    EMAC_PROC_MIN, EMAC_PROC_MAX));
+}


Property changes on: trunk/sys/arm/allwinner/if_emac.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/allwinner/if_emacreg.h
===================================================================
--- trunk/sys/arm/allwinner/if_emacreg.h	                        (rev 0)
+++ trunk/sys/arm/allwinner/if_emacreg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,240 @@
+/* $MidnightBSD$ */
+/*
+ * Copyright (C) 2013 Ganbold Tsagaankhuu <ganbold at freebsd.org>
+ * 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: stable/10/sys/arm/allwinner/if_emacreg.h 266337 2014-05-17 18:53:36Z ian $
+ */
+
+#ifndef	__IF_EMACREG_H__
+#define	__IF_EMACREG_H__
+
+/*
+ * EMAC register definitions
+ */
+#define	EMAC_CTL		0x00
+#define	EMAC_CTL_RST		(1 << 0)
+#define	EMAC_CTL_TX_EN		(1 << 1)
+#define	EMAC_CTL_RX_EN		(1 << 2)
+
+#define	EMAC_TX_MODE		0x04
+#define	EMAC_TX_FLOW		0x08
+#define	EMAC_TX_CTL0		0x0C
+#define	EMAC_TX_CTL1		0x10
+#define	EMAC_TX_INS		0x14
+#define	EMAC_TX_PL0		0x18
+#define	EMAC_TX_PL1		0x1C
+#define	EMAC_TX_STA		0x20
+#define	EMAC_TX_IO_DATA		0x24
+#define	EMAC_TX_IO_DATA1	0x28
+#define	EMAC_TX_TSVL0		0x2C
+#define	EMAC_TX_TSVH0		0x30
+#define	EMAC_TX_TSVL1		0x34
+#define	EMAC_TX_TSVH1		0x38
+
+#define	EMAC_RX_CTL		0x3C
+#define	EMAC_RX_HASH0		0x40
+#define	EMAC_RX_HASH1		0x44
+#define	EMAC_RX_STA		0x48
+#define	EMAC_RX_IO_DATA		0x4C
+#define	EMAC_RX_FBC		0x50
+
+#define	EMAC_INT_CTL		0x54
+#define	EMAC_INT_STA		0x58
+#define	EMAC_INT_STA_TX		(0x01 | 0x02)
+#define	EMAC_INT_STA_RX		0x100
+#define	EMAC_INT_EN		(0xf << 0) | (1 << 8)
+
+#define	EMAC_MAC_CTL0		0x5C
+#define	EMAC_MAC_CTL1		0x60
+#define	EMAC_MAC_IPGT		0x64
+#define	EMAC_MAC_IPGR		0x68
+#define	EMAC_MAC_CLRT		0x6C
+#define	EMAC_MAC_MAXF		0x70
+#define	EMAC_MAC_SUPP		0x74
+#define	EMAC_MAC_TEST		0x78
+#define	EMAC_MAC_MCFG		0x7C
+#define	EMAC_MAC_MCMD		0x80
+#define	EMAC_MAC_MADR		0x84
+#define	EMAC_MAC_MWTD		0x88
+#define	EMAC_MAC_MRDD		0x8C
+#define	EMAC_MAC_MIND		0x90
+#define	EMAC_MAC_SSRR		0x94
+#define	EMAC_MAC_A0		0x98
+#define	EMAC_MAC_A1		0x9C
+#define	EMAC_MAC_A2		0xA0
+
+#define	EMAC_SAFX_L0		0xA4
+#define	EMAC_SAFX_H0		0xA8
+#define	EMAC_SAFX_L1		0xAC
+#define	EMAC_SAFX_H1		0xB0
+#define	EMAC_SAFX_L2		0xB4
+#define	EMAC_SAFX_H2		0xB8
+#define	EMAC_SAFX_L3		0xBC
+#define	EMAC_SAFX_H3		0xC0
+
+#define	EMAC_PHY_DUPLEX		(1 << 8)
+
+/*
+ * Each received packet has 8 bytes header:
+ * Byte 0: Packet valid flag: 0x01 valid, 0x00 not valid
+ * Byte 1: 0x43 -> Ascii code 'C'
+ * Byte 2: 0x41 -> Ascii code 'A'
+ * Byte 3: 0x4d -> Ascii code 'M'
+ * Byte 4: High byte of received packet's status
+ * Byte 5: Low byte of received packet's status
+ * Byte 6: High byte of packet size
+ * Byte 7: Low byte of packet size
+ */
+#define	EMAC_PACKET_HEADER	(0x0143414d)
+
+/* Aborted frame enable */
+#define	EMAC_TX_AB_M		(1 << 0)
+
+/* 0: Enable CPU mode for TX, 1: DMA */
+#define	EMAC_TX_TM		~(1 << 1)
+
+/* 0: DRQ asserted, 1: DRQ automatically */
+#define	EMAC_RX_DRQ_MODE	(1 << 1)
+
+/* 0: Enable CPU mode for RX, 1: DMA */
+#define	EMAC_RX_TM		~(1 << 2)
+
+/* Pass all Frames */
+#define	EMAC_RX_PA		(1 << 4)
+
+/* Pass Control Frames */
+#define	EMAC_RX_PCF		(1 << 5)
+
+/* Pass Frames with CRC Error */
+#define	EMAC_RX_PCRCE		(1 << 6)
+
+/* Pass Frames with Length Error */
+#define	EMAC_RX_PLE		(1 << 7)
+
+/* Pass Frames length out of range */
+#define	EMAC_RX_POR		(1 << 8)
+
+/* Accept unicast Packets */
+#define	EMAC_RX_UCAD		(1 << 16)
+
+/* Enable DA Filtering */
+#define	EMAC_RX_DAF		(1 << 17)
+
+/* Accept multicast Packets */
+#define	EMAC_RX_MCO		(1 << 20)
+
+/* Enable Hash filter */
+#define	EMAC_RX_MHF		(1 << 21)
+
+/* Accept Broadcast Packets */
+#define	EMAC_RX_BCO		(1 << 22)
+
+/* Enable SA Filtering */
+#define	EMAC_RX_SAF		(1 << 24)
+
+/* Inverse Filtering */
+#define	EMAC_RX_SAIF		(1 << 25)
+
+#define	EMAC_RX_SETUP		(EMAC_RX_POR | EMAC_RX_UCAD | \
+    EMAC_RX_DAF | EMAC_RX_MCO | EMAC_RX_BCO)
+
+/* Enable Receive Flow Control */
+#define	EMAC_MAC_CTL0_RFC	(1 << 2)
+
+/* Enable Transmit Flow Control */
+#define	EMAC_MAC_CTL0_TFC	(1 << 3)
+
+/* Enable soft reset */
+#define	EMAC_MAC_CTL0_SOFT_RST	(1 << 15)
+
+#define	EMAC_MAC_CTL0_SETUP	(EMAC_MAC_CTL0_RFC | EMAC_MAC_CTL0_TFC)
+
+/* Enable duplex */
+#define	EMAC_MAC_CTL1_DUP	(1 << 0)
+
+/* Enable MAC Frame Length Checking */
+#define	EMAC_MAC_CTL1_FLC	(1 << 1)
+
+/* Enable Huge Frame */
+#define	EMAC_MAC_CTL1_HF	(1 << 2)
+
+/* Enable MAC Delayed CRC */
+#define	EMAC_MAC_CTL1_DCRC	(1 << 3)
+
+/* Enable MAC CRC */
+#define	EMAC_MAC_CTL1_CRC	(1 << 4)
+
+/* Enable MAC PAD Short frames */
+#define	EMAC_MAC_CTL1_PC	(1 << 5)
+
+/* Enable MAC PAD Short frames and append CRC */
+#define	EMAC_MAC_CTL1_VC	(1 << 6)
+
+/* Enable MAC auto detect Short frames */
+#define	EMAC_MAC_CTL1_ADP	(1 << 7)
+
+#define	EMAC_MAC_CTL1_PRE	(1 << 8)
+#define	EMAC_MAC_CTL1_LPE	(1 << 9)
+
+/* Enable no back off */
+#define	EMAC_MAC_CTL1_NB	(1 << 12)
+
+#define	EMAC_MAC_CTL1_BNB	(1 << 13)
+#define	EMAC_MAC_CTL1_ED	(1 << 14)
+
+#define	EMAC_MAC_CTL1_SETUP	(EMAC_MAC_CTL1_FLC | EMAC_MAC_CTL1_CRC | \
+    EMAC_MAC_CTL1_PC)
+
+/* half duplex */
+#define	EMAC_MAC_IPGT_HD	0x12
+
+/* full duplex */
+#define	EMAC_MAC_IPGT_FD	0x15
+
+#define	EMAC_MAC_NBTB_IPG1	0xC
+#define	EMAC_MAC_NBTB_IPG2	0x12
+
+#define	EMAC_MAC_CW		0x37
+#define	EMAC_MAC_RM		0xF
+
+#define	EMAC_MAC_MFL		0x0600
+
+/* Receive status */
+#define	EMAC_CRCERR		(1 << 4)
+#define	EMAC_LENERR		(3 << 5)
+
+#define	EMAC_RX_FLUSH_FIFO	(1 << 3)
+#define	EMAC_PHY_RESET		(1 << 15)
+#define	EMAC_PHY_PWRDOWN	(1 << 11)
+
+#define	EMAC_PROC_MIN		16
+#define	EMAC_PROC_MAX		255
+#define	EMAC_PROC_DEFAULT	64
+
+#define	EMAC_LOCK(cs)		mtx_lock(&(sc)->emac_mtx)
+#define	EMAC_UNLOCK(cs)		mtx_unlock(&(sc)->emac_mtx)
+#define	EMAC_ASSERT_LOCKED(sc)	mtx_assert(&(sc)->emac_mtx, MA_OWNED);
+
+#endif	/* __IF_EMACREG_H__ */


Property changes on: trunk/sys/arm/allwinner/if_emacreg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/allwinner/std.a10
===================================================================
--- trunk/sys/arm/allwinner/std.a10	                        (rev 0)
+++ trunk/sys/arm/allwinner/std.a10	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,20 @@
+# Allwinner A10 common options
+#$FreeBSD: stable/10/sys/arm/allwinner/std.a10 278601 2015-02-11 22:47:48Z ian $
+
+cpu		CPU_CORTEXA
+machine 	arm armv6
+makeoptions	CONF_CFLAGS="-march=armv7a -Wa,-march=armv7a"
+makeoption	ARM_LITTLE_ENDIAN
+
+# Physical memory starts at 0x40200000.  We assume images are loaded at
+# 0x40200000, e.g. from u-boot with 'fatload mmc 0 0x40200000 kernel'
+#
+#
+options		PHYSADDR=0x40000000
+
+makeoptions	KERNPHYSADDR=0x40200000
+options		KERNPHYSADDR=0x40200000
+makeoptions	KERNVIRTADDR=0xc0200000
+options		KERNVIRTADDR=0xc0200000
+
+files		"../allwinner/files.a10"


Property changes on: trunk/sys/arm/allwinner/std.a10
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/allwinner/timer.c
===================================================================
--- trunk/sys/arm/allwinner/timer.c	                        (rev 0)
+++ trunk/sys/arm/allwinner/timer.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,378 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Ganbold Tsagaankhuu <ganbold at freebsd.org>
+ * 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: stable/10/sys/arm/allwinner/timer.c 277113 2015-01-13 07:45:16Z ganbold $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/timeet.h>
+#include <sys/timetc.h>
+#include <sys/watchdog.h>
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+
+#include <sys/kdb.h>
+
+#include "a20/a20_cpu_cfg.h"
+
+/**
+ * Timer registers addr
+ *
+ */
+#define SW_TIMER_IRQ_EN_REG 	0x00
+#define SW_TIMER_IRQ_STA_REG 	0x04
+#define SW_TIMER0_CTRL_REG 	0x10
+#define SW_TIMER0_INT_VALUE_REG	0x14
+#define SW_TIMER0_CUR_VALUE_REG	0x18
+
+#define SW_COUNTER64LO_REG	0xa4
+#define SW_COUNTER64HI_REG	0xa8
+#define CNT64_CTRL_REG		0xa0
+
+#define CNT64_RL_EN		0x02 /* read latch enable */
+
+#define TIMER_ENABLE		(1<<0)
+#define TIMER_AUTORELOAD	(1<<1)
+#define TIMER_OSC24M		(1<<2) /* oscillator = 24mhz */
+#define TIMER_PRESCALAR		(0<<4) /* prescalar = 1 */
+
+#define SYS_TIMER_CLKSRC	24000000 /* clock source */
+
+struct a10_timer_softc {
+	device_t 	sc_dev;
+	struct resource *res[2];
+	bus_space_tag_t sc_bst;
+	bus_space_handle_t sc_bsh;
+	void 		*sc_ih;		/* interrupt handler */
+	uint32_t 	sc_period;
+	uint32_t 	timer0_freq;
+	struct eventtimer et;
+	uint8_t 	sc_timer_type;	/* 0 for A10, 1 for A20 */
+};
+
+int a10_timer_get_timerfreq(struct a10_timer_softc *);
+
+#define timer_read_4(sc, reg)	\
+	bus_space_read_4(sc->sc_bst, sc->sc_bsh, reg)
+#define timer_write_4(sc, reg, val)	\
+	bus_space_write_4(sc->sc_bst, sc->sc_bsh, reg, val)
+
+static u_int	a10_timer_get_timecount(struct timecounter *);
+static int	a10_timer_timer_start(struct eventtimer *,
+    sbintime_t first, sbintime_t period);
+static int	a10_timer_timer_stop(struct eventtimer *);
+
+static uint64_t timer_read_counter64(void);
+
+static int a10_timer_initialized = 0;
+static int a10_timer_hardclock(void *);
+static int a10_timer_probe(device_t);
+static int a10_timer_attach(device_t);
+
+static struct timecounter a10_timer_timecounter = {
+	.tc_name           = "a10_timer timer0",
+	.tc_get_timecount  = a10_timer_get_timecount,
+	.tc_counter_mask   = ~0u,
+	.tc_frequency      = 0,
+	.tc_quality        = 1000,
+};
+
+struct a10_timer_softc *a10_timer_sc = NULL;
+
+static struct resource_spec a10_timer_spec[] = {
+	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		0,	RF_ACTIVE },
+	{ -1, 0 }
+};
+
+static uint64_t
+timer_read_counter64(void)
+{
+	uint32_t lo, hi;
+
+	/* In case of A20 get appropriate counter info */
+	if (a10_timer_sc->sc_timer_type)
+		return (a20_read_counter64());
+
+	/* Latch counter, wait for it to be ready to read. */
+	timer_write_4(a10_timer_sc, CNT64_CTRL_REG, CNT64_RL_EN);
+	while (timer_read_4(a10_timer_sc, CNT64_CTRL_REG) & CNT64_RL_EN)
+		continue;
+
+	hi = timer_read_4(a10_timer_sc, SW_COUNTER64HI_REG);
+	lo = timer_read_4(a10_timer_sc, SW_COUNTER64LO_REG);
+
+	return (((uint64_t)hi << 32) | lo);
+}
+
+static int
+a10_timer_probe(device_t dev)
+{
+	struct a10_timer_softc *sc;
+
+	sc = device_get_softc(dev);
+
+	if (ofw_bus_is_compatible(dev, "allwinner,sun4i-timer"))
+		sc->sc_timer_type = 0;
+	else if (ofw_bus_is_compatible(dev, "allwinner,sun7i-timer"))
+		sc->sc_timer_type = 1;
+	else
+		return (ENXIO);
+
+	device_set_desc(dev, "Allwinner A10/A20 timer");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+a10_timer_attach(device_t dev)
+{
+	struct a10_timer_softc *sc;
+	int err;
+	uint32_t val;
+
+	sc = device_get_softc(dev);
+
+	if (bus_alloc_resources(dev, a10_timer_spec, sc->res)) {
+		device_printf(dev, "could not allocate resources\n");
+		return (ENXIO);
+	}
+
+	sc->sc_dev = dev;
+	sc->sc_bst = rman_get_bustag(sc->res[0]);
+	sc->sc_bsh = rman_get_bushandle(sc->res[0]);
+
+	/* Setup and enable the timer interrupt */
+	err = bus_setup_intr(dev, sc->res[1], INTR_TYPE_CLK, a10_timer_hardclock,
+	    NULL, sc, &sc->sc_ih);
+	if (err != 0) {
+		bus_release_resources(dev, a10_timer_spec, sc->res);
+		device_printf(dev, "Unable to setup the clock irq handler, "
+		    "err = %d\n", err);
+		return (ENXIO);
+	}
+
+	/* Set clock source to OSC24M, 16 pre-division */
+	val = timer_read_4(sc, SW_TIMER0_CTRL_REG);
+	val |= TIMER_PRESCALAR | TIMER_OSC24M;
+	timer_write_4(sc, SW_TIMER0_CTRL_REG, val);
+
+	/* Enable timer0 */
+	val = timer_read_4(sc, SW_TIMER_IRQ_EN_REG);
+	val |= TIMER_ENABLE;
+	timer_write_4(sc, SW_TIMER_IRQ_EN_REG, val);
+
+	sc->timer0_freq = SYS_TIMER_CLKSRC;
+
+	/* Set desired frequency in event timer and timecounter */
+	sc->et.et_frequency = sc->timer0_freq;
+	sc->et.et_name = "a10_timer Eventtimer";
+	sc->et.et_flags = ET_FLAGS_ONESHOT | ET_FLAGS_PERIODIC;
+	sc->et.et_quality = 1000;
+	sc->et.et_min_period = (0x00000005LLU << 32) / sc->et.et_frequency;
+	sc->et.et_max_period = (0xfffffffeLLU << 32) / sc->et.et_frequency;
+	sc->et.et_start = a10_timer_timer_start;
+	sc->et.et_stop = a10_timer_timer_stop;
+	sc->et.et_priv = sc;
+	et_register(&sc->et);
+
+	if (device_get_unit(dev) == 0)
+		a10_timer_sc = sc;
+
+	a10_timer_timecounter.tc_frequency = sc->timer0_freq;
+	tc_init(&a10_timer_timecounter);
+
+	if (bootverbose) {
+		device_printf(sc->sc_dev, "clock: hz=%d stathz = %d\n", hz, stathz);
+
+		device_printf(sc->sc_dev, "event timer clock frequency %u\n", 
+		    sc->timer0_freq);
+		device_printf(sc->sc_dev, "timecounter clock frequency %lld\n", 
+		    a10_timer_timecounter.tc_frequency);
+	}
+
+	a10_timer_initialized = 1;
+
+	return (0);
+}
+
+static int
+a10_timer_timer_start(struct eventtimer *et, sbintime_t first,
+    sbintime_t period)
+{
+	struct a10_timer_softc *sc;
+	uint32_t count;
+	uint32_t val;
+
+	sc = (struct a10_timer_softc *)et->et_priv;
+
+	if (period != 0)
+		sc->sc_period = ((uint32_t)et->et_frequency * period) >> 32;
+	else
+		sc->sc_period = 0;
+	if (first != 0)
+		count = ((uint32_t)et->et_frequency * first) >> 32;
+	else
+		count = sc->sc_period;
+
+	/* Update timer values */
+	timer_write_4(sc, SW_TIMER0_INT_VALUE_REG, sc->sc_period);
+	timer_write_4(sc, SW_TIMER0_CUR_VALUE_REG, count);
+
+	val = timer_read_4(sc, SW_TIMER0_CTRL_REG);
+	if (period != 0) {
+		/* periodic */
+		val |= TIMER_AUTORELOAD;
+	} else {
+		/* oneshot */
+		val &= ~TIMER_AUTORELOAD;
+	}
+	/* Enable timer0 */
+	val |= TIMER_ENABLE;
+	timer_write_4(sc, SW_TIMER0_CTRL_REG, val);
+
+	return (0);
+}
+
+static int
+a10_timer_timer_stop(struct eventtimer *et)
+{
+	struct a10_timer_softc *sc;
+	uint32_t val;
+
+	sc = (struct a10_timer_softc *)et->et_priv;
+
+	/* Disable timer0 */
+	val = timer_read_4(sc, SW_TIMER0_CTRL_REG);
+	val &= ~TIMER_ENABLE;
+	timer_write_4(sc, SW_TIMER0_CTRL_REG, val);
+
+	sc->sc_period = 0;
+
+	return (0);
+}
+
+int
+a10_timer_get_timerfreq(struct a10_timer_softc *sc)
+{
+	return (sc->timer0_freq);
+}
+
+static int
+a10_timer_hardclock(void *arg)
+{
+	struct a10_timer_softc *sc;
+	uint32_t val;
+
+	sc = (struct a10_timer_softc *)arg;
+
+	/* Clear interrupt pending bit. */
+	timer_write_4(sc, SW_TIMER_IRQ_STA_REG, 0x1);
+
+	val = timer_read_4(sc, SW_TIMER0_CTRL_REG);
+	/*
+	 * Disabled autoreload and sc_period > 0 means 
+	 * timer_start was called with non NULL first value.
+	 * Now we will set periodic timer with the given period 
+	 * value.
+	 */
+	if ((val & (1<<1)) == 0 && sc->sc_period > 0) {
+		/* Update timer */
+		timer_write_4(sc, SW_TIMER0_CUR_VALUE_REG, sc->sc_period);
+
+		/* Make periodic and enable */
+		val |= TIMER_AUTORELOAD | TIMER_ENABLE;
+		timer_write_4(sc, SW_TIMER0_CTRL_REG, val);
+	}
+
+	if (sc->et.et_active)
+		sc->et.et_event_cb(&sc->et, sc->et.et_arg);
+
+	return (FILTER_HANDLED);
+}
+
+u_int
+a10_timer_get_timecount(struct timecounter *tc)
+{
+
+	if (a10_timer_sc == NULL)
+		return (0);
+
+	return ((u_int)timer_read_counter64());
+}
+
+static device_method_t a10_timer_methods[] = {
+	DEVMETHOD(device_probe,		a10_timer_probe),
+	DEVMETHOD(device_attach,	a10_timer_attach),
+
+	DEVMETHOD_END
+};
+
+static driver_t a10_timer_driver = {
+	"a10_timer",
+	a10_timer_methods,
+	sizeof(struct a10_timer_softc),
+};
+
+static devclass_t a10_timer_devclass;
+
+DRIVER_MODULE(a10_timer, simplebus, a10_timer_driver, a10_timer_devclass, 0, 0);
+
+void
+DELAY(int usec)
+{
+	uint32_t counter;
+	uint64_t end, now;
+
+	if (!a10_timer_initialized) {
+		for (; usec > 0; usec--)
+			for (counter = 50; counter > 0; counter--)
+				cpufunc_nullop();
+		return;
+	}
+
+	now = timer_read_counter64();
+	end = now + (a10_timer_sc->timer0_freq / 1000000) * (usec + 1);
+
+	while (now < end)
+		now = timer_read_counter64();
+}
+


Property changes on: trunk/sys/arm/allwinner/timer.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/autoconf.c
===================================================================
--- trunk/sys/arm/arm/autoconf.c	                        (rev 0)
+++ trunk/sys/arm/arm/autoconf.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,100 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ *	from: @(#)autoconf.c	7.1 (Berkeley) 5/9/91
+ * from: FreeBSD: src/sys/i386/i386/autoconf.c,v 1.156
+ */
+
+/*
+ * Setup the system to run on the current machine.
+ *
+ * Configure() is called at boot time and initializes the vba
+ * device tables and the memory controller monitoring.  Available
+ * devices are determined (from possibilities mentioned in ioconf.c),
+ * and the drivers are initialized.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/autoconf.c 146794 2005-05-29 23:44:22Z marcel $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/disklabel.h>
+#include <sys/reboot.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/mount.h>
+#include <sys/cons.h>
+
+static void	configure_first (void *);
+static void	configure (void *);
+static void	configure_final (void *);
+
+SYSINIT(configure1, SI_SUB_CONFIGURE, SI_ORDER_FIRST, configure_first, NULL);
+/* SI_ORDER_SECOND is hookable */
+SYSINIT(configure2, SI_SUB_CONFIGURE, SI_ORDER_THIRD, configure, NULL);
+/* SI_ORDER_MIDDLE is hookable */
+SYSINIT(configure3, SI_SUB_CONFIGURE, SI_ORDER_ANY, configure_final, NULL);
+
+device_t nexus_dev;
+
+
+/*
+ * Determine i/o configuration for a machine.
+ */
+static void
+configure_first(void *dummy)
+{
+
+	device_add_child(root_bus, "nexus", 0);
+}
+
+static void
+configure(void *dummy)
+{
+
+	root_bus_configure();
+}
+
+static void
+configure_final(void *dummy)
+{
+
+	cninit_finish();
+	cold = 0;
+}


Property changes on: trunk/sys/arm/arm/autoconf.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/bcopy_page.S
===================================================================
--- trunk/sys/arm/arm/bcopy_page.S	                        (rev 0)
+++ trunk/sys/arm/arm/bcopy_page.S	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,281 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: bcopy_page.S,v 1.7 2003/10/13 21:03:13 scw Exp $	*/
+
+/*-
+ * Copyright (c) 1995 Scott Stevens
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Scott Stevens.
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
+ *
+ * RiscBSD kernel project
+ *
+ * bcopy_page.S
+ *
+ * page optimised bcopy and bzero routines
+ *
+ * Created      : 08/04/95
+ */
+
+#include <machine/asm.h>
+
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/bcopy_page.S 248361 2013-03-16 02:48:49Z andrew $");
+
+#include "assym.s"
+
+#ifndef _ARM_ARCH_5E
+
+/* #define BIG_LOOPS */
+
+/*
+ * bcopy_page(src, dest)
+ *
+ * Optimised copy page routine.
+ *
+ * On entry:
+ *   r0 - src address
+ *   r1 - dest address
+ *
+ * Requires:
+ *   number of bytes per page (PAGE_SIZE) is a multiple of 512 (BIG_LOOPS), 128
+ *   otherwise.
+ */
+
+#define	CHUNK_SIZE	32
+
+#define	PREFETCH_FIRST_CHUNK	/* nothing */
+#define	PREFETCH_NEXT_CHUNK	/* nothing */
+
+#ifndef COPY_CHUNK
+#define	COPY_CHUNK \
+	PREFETCH_NEXT_CHUNK ; \
+	ldmia	r0!, {r3-r8,ip,lr} ; \
+	stmia	r1!, {r3-r8,ip,lr}
+#endif /* ! COPY_CHUNK */
+
+#ifndef SAVE_REGS
+#define	SAVE_REGS	stmfd	sp!, {r4-r8, lr}
+#define	RESTORE_REGS	ldmfd	sp!, {r4-r8, pc}
+#endif
+
+ENTRY(bcopy_page)
+	PREFETCH_FIRST_CHUNK
+	SAVE_REGS
+#ifdef BIG_LOOPS
+	mov	r2, #(PAGE_SIZE >> 9)
+#else
+	mov	r2, #(PAGE_SIZE >> 7)
+#endif
+
+1:
+	COPY_CHUNK
+	COPY_CHUNK
+	COPY_CHUNK
+	COPY_CHUNK
+
+#ifdef BIG_LOOPS
+	/* There is little point making the loop any larger; unless we are
+	   running with the cache off, the load/store overheads will
+	   completely dominate this loop.  */
+	COPY_CHUNK
+	COPY_CHUNK
+	COPY_CHUNK
+	COPY_CHUNK
+
+	COPY_CHUNK
+	COPY_CHUNK
+	COPY_CHUNK
+	COPY_CHUNK
+
+	COPY_CHUNK
+	COPY_CHUNK
+	COPY_CHUNK
+	COPY_CHUNK
+#endif
+	subs	r2, r2, #1
+	bne	1b
+
+	RESTORE_REGS		/* ...and return. */
+END(bcopy_page)
+
+/*
+ * bzero_page(dest)
+ *
+ * Optimised zero page routine.
+ *
+ * On entry:
+ *   r0 - dest address
+ *
+ * Requires:
+ *   number of bytes per page (PAGE_SIZE) is a multiple of 512 (BIG_LOOPS), 128
+ *   otherwise
+ */
+
+ENTRY(bzero_page)
+	stmfd	sp!, {r4-r8, lr}
+#ifdef BIG_LOOPS
+	mov	r2, #(PAGE_SIZE >> 9)
+#else
+	mov	r2, #(PAGE_SIZE >> 7)
+#endif
+	mov	r3, #0
+	mov	r4, #0
+	mov	r5, #0
+	mov	r6, #0
+	mov	r7, #0
+	mov	r8, #0
+	mov	ip, #0
+	mov	lr, #0
+
+1:
+	stmia	r0!, {r3-r8,ip,lr}
+	stmia	r0!, {r3-r8,ip,lr}
+	stmia	r0!, {r3-r8,ip,lr}
+	stmia	r0!, {r3-r8,ip,lr}
+
+#ifdef BIG_LOOPS
+	/* There is little point making the loop any larger; unless we are
+	   running with the cache off, the load/store overheads will
+	   completely dominate this loop.  */
+	stmia	r0!, {r3-r8,ip,lr}
+	stmia	r0!, {r3-r8,ip,lr}
+	stmia	r0!, {r3-r8,ip,lr}
+	stmia	r0!, {r3-r8,ip,lr}
+
+	stmia	r0!, {r3-r8,ip,lr}
+	stmia	r0!, {r3-r8,ip,lr}
+	stmia	r0!, {r3-r8,ip,lr}
+	stmia	r0!, {r3-r8,ip,lr}
+
+	stmia	r0!, {r3-r8,ip,lr}
+	stmia	r0!, {r3-r8,ip,lr}
+	stmia	r0!, {r3-r8,ip,lr}
+	stmia	r0!, {r3-r8,ip,lr}
+
+#endif
+
+	subs	r2, r2, #1
+	bne	1b
+
+	ldmfd	sp!, {r4-r8, pc}
+END(bzero_page)
+
+#else	/* _ARM_ARCH_5E */
+
+/*
+ * armv5e version of bcopy_page
+ */
+ENTRY(bcopy_page)
+	pld	[r0]
+	stmfd	sp!, {r4, r5}
+	mov	ip, #32
+	ldr	r2, [r0], #0x04		/* 0x00 */
+	ldr	r3, [r0], #0x04		/* 0x04 */
+1:	pld	[r0, #0x18]		/* Prefetch 0x20 */
+	ldr	r4, [r0], #0x04		/* 0x08 */
+	ldr	r5, [r0], #0x04		/* 0x0c */
+	strd	r2, [r1], #0x08
+	ldr	r2, [r0], #0x04		/* 0x10 */
+	ldr	r3, [r0], #0x04		/* 0x14 */
+	strd	r4, [r1], #0x08
+	ldr	r4, [r0], #0x04		/* 0x18 */
+	ldr	r5, [r0], #0x04		/* 0x1c */
+	strd	r2, [r1], #0x08
+	ldr	r2, [r0], #0x04		/* 0x20 */
+	ldr	r3, [r0], #0x04		/* 0x24 */
+	pld	[r0, #0x18]		/* Prefetch 0x40 */
+	strd	r4, [r1], #0x08
+	ldr	r4, [r0], #0x04		/* 0x28 */
+	ldr	r5, [r0], #0x04		/* 0x2c */
+	strd	r2, [r1], #0x08
+	ldr	r2, [r0], #0x04		/* 0x30 */
+	ldr	r3, [r0], #0x04		/* 0x34 */
+	strd	r4, [r1], #0x08
+	ldr	r4, [r0], #0x04		/* 0x38 */
+	ldr	r5, [r0], #0x04		/* 0x3c */
+	strd	r2, [r1], #0x08
+	ldr	r2, [r0], #0x04		/* 0x40 */
+	ldr	r3, [r0], #0x04		/* 0x44 */
+	pld	[r0, #0x18]		/* Prefetch 0x60 */
+	strd	r4, [r1], #0x08
+	ldr	r4, [r0], #0x04		/* 0x48 */
+	ldr	r5, [r0], #0x04		/* 0x4c */
+	strd	r2, [r1], #0x08
+	ldr	r2, [r0], #0x04		/* 0x50 */
+	ldr	r3, [r0], #0x04		/* 0x54 */
+	strd	r4, [r1], #0x08
+	ldr	r4, [r0], #0x04		/* 0x58 */
+	ldr	r5, [r0], #0x04		/* 0x5c */
+	strd	r2, [r1], #0x08
+	ldr	r2, [r0], #0x04		/* 0x60 */
+	ldr	r3, [r0], #0x04		/* 0x64 */
+	pld	[r0, #0x18]		/* Prefetch 0x80 */
+	strd	r4, [r1], #0x08
+	ldr	r4, [r0], #0x04		/* 0x68 */
+	ldr	r5, [r0], #0x04		/* 0x6c */
+	strd	r2, [r1], #0x08
+	ldr	r2, [r0], #0x04		/* 0x70 */
+	ldr	r3, [r0], #0x04		/* 0x74 */
+	strd	r4, [r1], #0x08
+	ldr	r4, [r0], #0x04		/* 0x78 */
+	ldr	r5, [r0], #0x04		/* 0x7c */
+	strd	r2, [r1], #0x08
+	subs	ip, ip, #0x01
+	ldrgt	r2, [r0], #0x04		/* 0x80 */
+	ldrgt	r3, [r0], #0x04		/* 0x84 */
+	strd	r4, [r1], #0x08
+	bgt	1b
+	ldmfd	sp!, {r4, r5}
+	RET
+END(bcopy_page)
+
+/*
+ * armv5e version of bzero_page
+ */
+ENTRY(bzero_page)
+	mov	r1, #PAGE_SIZE
+	mov	r2, #0
+	mov	r3, #0
+1:	strd	r2, [r0], #8		/* 32 */
+	strd	r2, [r0], #8
+	strd	r2, [r0], #8
+	strd	r2, [r0], #8
+	strd	r2, [r0], #8		/* 64 */
+	strd	r2, [r0], #8
+	strd	r2, [r0], #8
+	strd	r2, [r0], #8
+	strd	r2, [r0], #8		/* 96 */
+	strd	r2, [r0], #8
+	strd	r2, [r0], #8
+	strd	r2, [r0], #8
+	strd	r2, [r0], #8		/* 128 */
+	strd	r2, [r0], #8
+	strd	r2, [r0], #8
+	strd	r2, [r0], #8
+	subs	r1, r1, #128
+	bne	1b
+	RET
+END(bzero_page)
+#endif	/* _ARM_ARCH_5E */


Property changes on: trunk/sys/arm/arm/bcopy_page.S
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/bcopyinout.S
===================================================================
--- trunk/sys/arm/arm/bcopyinout.S	                        (rev 0)
+++ trunk/sys/arm/arm/bcopyinout.S	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,624 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: bcopyinout.S,v 1.11 2003/10/13 21:22:40 scw Exp $	*/
+
+/*-
+ * Copyright (c) 2002 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Allen Briggs for Wasabi Systems, Inc.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed for the NetBSD Project by
+ *      Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
+ * 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 "assym.s"
+
+#include <machine/acle-compat.h>
+#include <machine/asm.h>
+#include <sys/errno.h>
+
+.L_arm_memcpy:
+	.word	_C_LABEL(_arm_memcpy)
+.L_min_memcpy_size:
+	.word	_C_LABEL(_min_memcpy_size)
+
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/bcopyinout.S 294681 2016-01-24 19:58:58Z ian $");
+#ifdef _ARM_ARCH_5E
+#include <arm/arm/bcopyinout_xscale.S>
+#else
+
+	.text
+	.align	2
+
+#if __ARM_ARCH >= 6
+#define GET_PCB(tmp) \
+	mrc p15, 0, tmp, c13, c0, 4; \
+	add	tmp, tmp, #(TD_PCB)
+#else
+.Lcurpcb:
+	.word	_C_LABEL(__pcpu) + PC_CURPCB
+
+#define GET_PCB(tmp) \
+	ldr	tmp, .Lcurpcb
+#endif
+
+
+#define SAVE_REGS	stmfd	sp!, {r4-r11}
+#define RESTORE_REGS	ldmfd	sp!, {r4-r11}
+		
+#if defined(_ARM_ARCH_5E)
+#define HELLOCPP #
+#define PREFETCH(rx,o)	pld	[ rx , HELLOCPP (o) ]
+#else
+#define PREFETCH(rx,o)
+#endif
+
+/*
+ * r0 = user space address
+ * r1 = kernel space address
+ * r2 = length
+ *
+ * Copies bytes from user space to kernel space
+ *
+ * We save/restore r4-r11:
+ * r4-r11 are scratch
+ */
+ENTRY(copyin)
+	/* Quick exit if length is zero */	
+	teq	r2, #0
+	moveq	r0, #0
+	RETeq
+
+	ldr	r3, .L_arm_memcpy
+	ldr	r3, [r3]
+	cmp	r3, #0
+	beq	.Lnormal
+	ldr	r3, .L_min_memcpy_size
+	ldr	r3, [r3]
+	cmp	r2, r3
+	blt	.Lnormal
+	stmfd	sp!, {r0-r2, r4, lr}
+	mov     r3, r0
+	mov     r0, r1
+	mov     r1, r3
+	mov     r3, #2 /* SRC_IS_USER */
+	ldr	r4, .L_arm_memcpy
+	mov	lr, pc
+	ldr	pc, [r4]
+	cmp     r0, #0
+	ldmfd   sp!, {r0-r2, r4, lr}
+	moveq	r0, #0
+	RETeq
+
+.Lnormal:
+	SAVE_REGS
+	GET_PCB(r4)
+	ldr	r4, [r4]
+
+
+	ldr	r5, [r4, #PCB_ONFAULT]
+	adr	r3, .Lcopyfault
+	str	r3, [r4, #PCB_ONFAULT]
+
+	PREFETCH(r0, 0)
+	PREFETCH(r1, 0)
+
+	/*
+	 * If not too many bytes, take the slow path.
+	 */
+	cmp	r2, #0x08
+	blt	.Licleanup
+
+	/*
+	 * Align destination to word boundary.
+	 */
+	and	r6, r1, #0x3
+	ldr	pc, [pc, r6, lsl #2]
+	b	.Lialend
+	.word	.Lialend
+	.word	.Lial3
+	.word	.Lial2
+	.word	.Lial1
+.Lial3:	ldrbt	r6, [r0], #1
+	sub	r2, r2, #1
+	strb	r6, [r1], #1
+.Lial2:	ldrbt	r7, [r0], #1
+	sub	r2, r2, #1
+	strb	r7, [r1], #1
+.Lial1:	ldrbt	r6, [r0], #1
+	sub	r2, r2, #1
+	strb	r6, [r1], #1
+.Lialend:
+
+	/*
+	 * If few bytes left, finish slow.
+	 */
+	cmp	r2, #0x08
+	blt	.Licleanup
+
+	/*
+	 * If source is not aligned, finish slow.
+	 */
+	ands	r3, r0, #0x03
+	bne	.Licleanup
+
+	cmp	r2, #0x60	/* Must be > 0x5f for unrolled cacheline */
+	blt	.Licleanup8
+
+	/*
+	 * Align destination to cacheline boundary.
+	 * If source and destination are nicely aligned, this can be a big
+	 * win.  If not, it's still cheaper to copy in groups of 32 even if
+	 * we don't get the nice cacheline alignment.
+	 */
+	and	r6, r1, #0x1f
+	ldr	pc, [pc, r6]
+	b	.Licaligned
+	.word	.Licaligned
+	.word	.Lical28
+	.word	.Lical24
+	.word	.Lical20
+	.word	.Lical16
+	.word	.Lical12
+	.word	.Lical8
+	.word	.Lical4
+.Lical28:ldrt	r6, [r0], #4
+	sub	r2, r2, #4
+	str	r6, [r1], #4
+.Lical24:ldrt	r7, [r0], #4
+	sub	r2, r2, #4
+	str	r7, [r1], #4
+.Lical20:ldrt	r6, [r0], #4
+	sub	r2, r2, #4
+	str	r6, [r1], #4
+.Lical16:ldrt	r7, [r0], #4
+	sub	r2, r2, #4
+	str	r7, [r1], #4
+.Lical12:ldrt	r6, [r0], #4
+	sub	r2, r2, #4
+	str	r6, [r1], #4
+.Lical8:ldrt	r7, [r0], #4
+	sub	r2, r2, #4
+	str	r7, [r1], #4
+.Lical4:ldrt	r6, [r0], #4
+	sub	r2, r2, #4
+	str	r6, [r1], #4
+
+	/*
+	 * We start with > 0x40 bytes to copy (>= 0x60 got us into this
+	 * part of the code, and we may have knocked that down by as much
+	 * as 0x1c getting aligned).
+	 *
+	 * This loop basically works out to:
+	 * do {
+	 * 	prefetch-next-cacheline(s)
+	 *	bytes -= 0x20;
+	 *	copy cacheline
+	 * } while (bytes >= 0x40);
+	 * bytes -= 0x20;
+	 * copy cacheline
+	 */
+.Licaligned:
+	PREFETCH(r0, 32)
+	PREFETCH(r1, 32)
+
+	sub	r2, r2, #0x20
+
+	/* Copy a cacheline */
+	ldrt	r10, [r0], #4
+	ldrt	r11, [r0], #4
+	ldrt	r6, [r0], #4
+	ldrt	r7, [r0], #4
+	ldrt	r8, [r0], #4
+	ldrt	r9, [r0], #4
+	stmia	r1!, {r10-r11}
+	ldrt	r10, [r0], #4
+	ldrt	r11, [r0], #4
+	stmia	r1!, {r6-r11}
+
+	cmp	r2, #0x40
+	bge	.Licaligned
+
+	sub	r2, r2, #0x20
+
+	/* Copy a cacheline */
+	ldrt	r10, [r0], #4
+	ldrt	r11, [r0], #4
+	ldrt	r6, [r0], #4
+	ldrt	r7, [r0], #4
+	ldrt	r8, [r0], #4
+	ldrt	r9, [r0], #4
+	stmia	r1!, {r10-r11}
+	ldrt	r10, [r0], #4
+	ldrt	r11, [r0], #4
+	stmia	r1!, {r6-r11}
+
+	cmp	r2, #0x08
+	blt	.Liprecleanup
+
+.Licleanup8:
+	ldrt	r8, [r0], #4
+	ldrt	r9, [r0], #4
+	sub	r2, r2, #8
+	stmia	r1!, {r8, r9}
+	cmp	r2, #8
+	bge	.Licleanup8
+
+.Liprecleanup:
+	/*
+	 * If we're done, bail.
+	 */
+	cmp	r2, #0
+	beq	.Lout
+
+.Licleanup:
+	and	r6, r2, #0x3
+	ldr	pc, [pc, r6, lsl #2]
+	b	.Licend
+	.word	.Lic4
+	.word	.Lic1
+	.word	.Lic2
+	.word	.Lic3
+.Lic4:	ldrbt	r6, [r0], #1
+	sub	r2, r2, #1
+	strb	r6, [r1], #1
+.Lic3:	ldrbt	r7, [r0], #1
+	sub	r2, r2, #1
+	strb	r7, [r1], #1
+.Lic2:	ldrbt	r6, [r0], #1
+	sub	r2, r2, #1
+	strb	r6, [r1], #1
+.Lic1:	ldrbt	r7, [r0], #1
+	subs	r2, r2, #1
+	strb	r7, [r1], #1
+.Licend:
+	bne	.Licleanup
+
+.Liout:
+	mov	r0, #0
+
+	str	r5, [r4, #PCB_ONFAULT]
+	RESTORE_REGS
+
+	RET
+
+.Lcopyfault:
+	ldr	r0, =EFAULT
+	str	r5, [r4, #PCB_ONFAULT]
+	RESTORE_REGS
+
+	RET
+END(copyin)
+
+/*
+ * r0 = kernel space address
+ * r1 = user space address
+ * r2 = length
+ *
+ * Copies bytes from kernel space to user space
+ *
+ * We save/restore r4-r11:
+ * r4-r11 are scratch
+ */
+
+ENTRY(copyout)
+	/* Quick exit if length is zero */	
+	teq	r2, #0
+	moveq	r0, #0
+	RETeq
+
+	ldr	r3, .L_arm_memcpy
+	ldr	r3, [r3]
+	cmp	r3, #0
+	beq	.Lnormale
+	ldr	r3, .L_min_memcpy_size
+	ldr	r3, [r3]
+	cmp	r2, r3
+	blt	.Lnormale
+	stmfd	sp!, {r0-r2, r4, lr}
+	mov     r3, r0
+	mov     r0, r1
+	mov     r1, r3
+	mov     r3, #1 /* DST_IS_USER */
+	ldr	r4, .L_arm_memcpy
+	mov	lr, pc
+	ldr	pc, [r4]
+	cmp     r0, #0
+	ldmfd   sp!, {r0-r2, r4, lr}
+	moveq	r0, #0
+	RETeq
+
+.Lnormale:
+	SAVE_REGS
+	GET_PCB(r4)
+	ldr	r4, [r4]
+
+	ldr	r5, [r4, #PCB_ONFAULT]
+	adr	r3, .Lcopyfault
+	str	r3, [r4, #PCB_ONFAULT]
+
+	PREFETCH(r0, 0)
+	PREFETCH(r1, 0)
+
+	/*
+	 * If not too many bytes, take the slow path.
+	 */
+	cmp	r2, #0x08
+	blt	.Lcleanup
+
+	/*
+	 * Align destination to word boundary.
+	 */
+	and	r6, r1, #0x3
+	ldr	pc, [pc, r6, lsl #2]
+	b	.Lalend
+	.word	.Lalend
+	.word	.Lal3
+	.word	.Lal2
+	.word	.Lal1
+.Lal3:	ldrb	r6, [r0], #1
+	sub	r2, r2, #1
+	strbt	r6, [r1], #1
+.Lal2:	ldrb	r7, [r0], #1
+	sub	r2, r2, #1
+	strbt	r7, [r1], #1
+.Lal1:	ldrb	r6, [r0], #1
+	sub	r2, r2, #1
+	strbt	r6, [r1], #1
+.Lalend:
+
+	/*
+	 * If few bytes left, finish slow.
+	 */
+	cmp	r2, #0x08
+	blt	.Lcleanup
+
+	/*
+	 * If source is not aligned, finish slow.
+	 */
+	ands	r3, r0, #0x03
+	bne	.Lcleanup
+
+	cmp	r2, #0x60	/* Must be > 0x5f for unrolled cacheline */
+	blt	.Lcleanup8
+
+	/*
+	 * Align source & destination to cacheline boundary.
+	 */
+	and	r6, r1, #0x1f
+	ldr	pc, [pc, r6]
+	b	.Lcaligned
+	.word	.Lcaligned
+	.word	.Lcal28
+	.word	.Lcal24
+	.word	.Lcal20
+	.word	.Lcal16
+	.word	.Lcal12
+	.word	.Lcal8
+	.word	.Lcal4
+.Lcal28:ldr	r6, [r0], #4
+	sub	r2, r2, #4
+	strt	r6, [r1], #4
+.Lcal24:ldr	r7, [r0], #4
+	sub	r2, r2, #4
+	strt	r7, [r1], #4
+.Lcal20:ldr	r6, [r0], #4
+	sub	r2, r2, #4
+	strt	r6, [r1], #4
+.Lcal16:ldr	r7, [r0], #4
+	sub	r2, r2, #4
+	strt	r7, [r1], #4
+.Lcal12:ldr	r6, [r0], #4
+	sub	r2, r2, #4
+	strt	r6, [r1], #4
+.Lcal8:	ldr	r7, [r0], #4
+	sub	r2, r2, #4
+	strt	r7, [r1], #4
+.Lcal4:	ldr	r6, [r0], #4
+	sub	r2, r2, #4
+	strt	r6, [r1], #4
+
+	/*
+	 * We start with > 0x40 bytes to copy (>= 0x60 got us into this
+	 * part of the code, and we may have knocked that down by as much
+	 * as 0x1c getting aligned).
+	 *
+	 * This loop basically works out to:
+	 * do {
+	 * 	prefetch-next-cacheline(s)
+	 *	bytes -= 0x20;
+	 *	copy cacheline
+	 * } while (bytes >= 0x40);
+	 * bytes -= 0x20;
+	 * copy cacheline
+	 */
+.Lcaligned:
+	PREFETCH(r0, 32)
+	PREFETCH(r1, 32)
+
+	sub	r2, r2, #0x20
+
+	/* Copy a cacheline */
+	ldmia	r0!, {r6-r11}
+	strt	r6, [r1], #4
+	strt	r7, [r1], #4
+	ldmia	r0!, {r6-r7}
+	strt	r8, [r1], #4
+	strt	r9, [r1], #4
+	strt	r10, [r1], #4
+	strt	r11, [r1], #4
+	strt	r6, [r1], #4
+	strt	r7, [r1], #4
+
+	cmp	r2, #0x40
+	bge	.Lcaligned
+
+	sub	r2, r2, #0x20
+
+	/* Copy a cacheline */
+	ldmia	r0!, {r6-r11}
+	strt	r6, [r1], #4
+	strt	r7, [r1], #4
+	ldmia	r0!, {r6-r7}
+	strt	r8, [r1], #4
+	strt	r9, [r1], #4
+	strt	r10, [r1], #4
+	strt	r11, [r1], #4
+	strt	r6, [r1], #4
+	strt	r7, [r1], #4
+
+	cmp	r2, #0x08
+	blt	.Lprecleanup
+
+.Lcleanup8:
+	ldmia	r0!, {r8-r9}
+	sub	r2, r2, #8
+	strt	r8, [r1], #4
+	strt	r9, [r1], #4
+	cmp	r2, #8
+	bge	.Lcleanup8
+
+.Lprecleanup:
+	/*
+	 * If we're done, bail.
+	 */
+	cmp	r2, #0
+	beq	.Lout
+
+.Lcleanup:
+	and	r6, r2, #0x3
+	ldr	pc, [pc, r6, lsl #2]
+	b	.Lcend
+	.word	.Lc4
+	.word	.Lc1
+	.word	.Lc2
+	.word	.Lc3
+.Lc4:	ldrb	r6, [r0], #1
+	sub	r2, r2, #1
+	strbt	r6, [r1], #1
+.Lc3:	ldrb	r7, [r0], #1
+	sub	r2, r2, #1
+	strbt	r7, [r1], #1
+.Lc2:	ldrb	r6, [r0], #1
+	sub	r2, r2, #1
+	strbt	r6, [r1], #1
+.Lc1:	ldrb	r7, [r0], #1
+	subs	r2, r2, #1
+	strbt	r7, [r1], #1
+.Lcend:
+	bne	.Lcleanup
+
+.Lout:
+	mov	r0, #0
+
+	str	r5, [r4, #PCB_ONFAULT]
+	RESTORE_REGS
+
+	RET
+END(copyout)
+#endif
+
+/*
+ * int badaddr_read_1(const uint8_t *src, uint8_t *dest)
+ *
+ * Copies a single 8-bit value from src to dest, returning 0 on success,
+ * else EFAULT if a page fault occurred.
+ */
+ENTRY(badaddr_read_1)
+	GET_PCB(r2)
+	ldr	r2, [r2]
+
+	ldr	ip, [r2, #PCB_ONFAULT]
+	adr	r3, 1f
+	str	r3, [r2, #PCB_ONFAULT]
+	nop
+	nop
+	nop
+	ldrb	r3, [r0]
+	nop
+	nop
+	nop
+	strb	r3, [r1]
+	mov	r0, #0		/* No fault */
+1:	str	ip, [r2, #PCB_ONFAULT]
+	RET
+END(badaddr_read_1)
+
+/*
+ * int badaddr_read_2(const uint16_t *src, uint16_t *dest)
+ *
+ * Copies a single 16-bit value from src to dest, returning 0 on success,
+ * else EFAULT if a page fault occurred.
+ */
+ENTRY(badaddr_read_2)
+	GET_PCB(r2)
+	ldr	r2, [r2]
+
+	ldr	ip, [r2, #PCB_ONFAULT]
+	adr	r3, 1f
+	str	r3, [r2, #PCB_ONFAULT]
+	nop
+	nop
+	nop
+	ldrh	r3, [r0]
+	nop
+	nop
+	nop
+	strh	r3, [r1]
+	mov	r0, #0		/* No fault */
+1:	str	ip, [r2, #PCB_ONFAULT]
+	RET
+END(badaddr_read_2)
+
+/*
+ * int badaddr_read_4(const uint32_t *src, uint32_t *dest)
+ *
+ * Copies a single 32-bit value from src to dest, returning 0 on success,
+ * else EFAULT if a page fault occurred.
+ */
+ENTRY(badaddr_read_4)
+	GET_PCB(r2)
+	ldr	r2, [r2]
+
+	ldr	ip, [r2, #PCB_ONFAULT]
+	adr	r3, 1f
+	str	r3, [r2, #PCB_ONFAULT]
+	nop
+	nop
+	nop
+	ldr	r3, [r0]
+	nop
+	nop
+	nop
+	str	r3, [r1]
+	mov	r0, #0		/* No fault */
+1:	str	ip, [r2, #PCB_ONFAULT]
+	RET
+END(badaddr_read_4)
+


Property changes on: trunk/sys/arm/arm/bcopyinout.S
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/bcopyinout_xscale.S
===================================================================
--- trunk/sys/arm/arm/bcopyinout_xscale.S	                        (rev 0)
+++ trunk/sys/arm/arm/bcopyinout_xscale.S	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,943 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: bcopyinout_xscale.S,v 1.3 2003/12/15 09:27:18 scw Exp $	*/
+
+/*-
+ * Copyright 2003 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Steve C. Woodford for Wasabi Systems, Inc.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed for the NetBSD Project by
+ *      Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
+ * 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 <machine/asm.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/bcopyinout_xscale.S 294681 2016-01-24 19:58:58Z ian $");
+
+#include <machine/acle-compat.h>
+
+	.syntax	unified
+	.text
+	.align	2
+
+#if __ARM_ARCH >= 6
+#define GET_PCB(tmp) \
+	mrc p15, 0, tmp, c13, c0, 4; \
+	add	tmp, tmp, #(TD_PCB)
+#else
+.Lcurpcb:
+	.word	_C_LABEL(__pcpu) + PC_CURPCB
+#define GET_PCB(tmp) \
+	ldr	tmp, .Lcurpcb
+#endif
+
+/*
+ * r0 = user space address
+ * r1 = kernel space address
+ * r2 = length
+ *
+ * Copies bytes from user space to kernel space
+ */
+ENTRY(copyin)
+	cmp	r2, #0x00
+	movle	r0, #0x00
+	movle	pc, lr			/* Bail early if length is <= 0 */
+
+	ldr	r3, .L_arm_memcpy
+	ldr	r3, [r3]
+	cmp	r3, #0
+	beq	.Lnormal
+	ldr	r3, .L_min_memcpy_size
+	ldr	r3, [r3]
+	cmp	r2, r3
+	blt	.Lnormal
+	stmfd	sp!, {r0-r2, r4, lr}
+	mov     r3, r0
+	mov     r0, r1
+	mov     r1, r3
+	mov     r3, #2 /* SRC_IS_USER */
+	ldr	r4, .L_arm_memcpy
+	mov	lr, pc
+	ldr	pc, [r4]
+	cmp     r0, #0
+	ldmfd   sp!, {r0-r2, r4, lr}
+	moveq	r0, #0
+	RETeq
+					
+.Lnormal:
+	stmfd	sp!, {r10-r11, lr}
+
+	GET_PCB(r10)
+	ldr	r10, [r10]
+
+	mov	r3, #0x00
+	adr	ip, .Lcopyin_fault
+	ldr	r11, [r10, #PCB_ONFAULT]
+	str	ip, [r10, #PCB_ONFAULT]
+	bl	.Lcopyin_guts
+	str	r11, [r10, #PCB_ONFAULT]
+	mov	r0, #0x00
+	ldmfd	sp!, {r10-r11, pc}
+
+.Lcopyin_fault:
+	ldr	r0, =EFAULT
+	str	r11, [r10, #PCB_ONFAULT]
+	cmp	r3, #0x00
+	ldmfdgt	sp!, {r4-r7}		/* r3 > 0 Restore r4-r7 */
+	ldmfdlt	sp!, {r4-r9}		/* r3 < 0 Restore r4-r9 */
+	ldmfd	sp!, {r10-r11, pc}
+
+.Lcopyin_guts:
+	pld	[r0]
+	/* Word-align the destination buffer */
+	ands	ip, r1, #0x03		/* Already word aligned? */
+	beq	.Lcopyin_wordaligned	/* Yup */
+	rsb	ip, ip, #0x04
+	cmp	r2, ip			/* Enough bytes left to align it? */
+	blt	.Lcopyin_l4_2		/* Nope. Just copy bytewise */
+	sub	r2, r2, ip
+	rsbs	ip, ip, #0x03
+	addne	pc, pc, ip, lsl #3
+	nop
+	ldrbt	ip, [r0], #0x01
+	strb	ip, [r1], #0x01
+	ldrbt	ip, [r0], #0x01
+	strb	ip, [r1], #0x01
+	ldrbt	ip, [r0], #0x01
+	strb	ip, [r1], #0x01
+	cmp	r2, #0x00		/* All done? */
+	RETeq
+
+	/* Destination buffer is now word aligned */
+.Lcopyin_wordaligned:
+	ands	ip, r0, #0x03		/* Is src also word-aligned? */
+	bne	.Lcopyin_bad_align	/* Nope. Things just got bad */
+	cmp	r2, #0x08		/* Less than 8 bytes remaining? */
+	blt	.Lcopyin_w_less_than8
+
+	/* Quad-align the destination buffer */
+	tst	r1, #0x07		/* Already quad aligned? */
+	ldrtne	ip, [r0], #0x04
+	strne	ip, [r1], #0x04
+	subne	r2, r2, #0x04
+	stmfd	sp!, {r4-r9}		/* Free up some registers */
+	mov	r3, #-1			/* Signal restore r4-r9 */
+
+	/* Destination buffer quad aligned, source is word aligned */
+	subs	r2, r2, #0x80
+	blt	.Lcopyin_w_lessthan128
+
+	/* Copy 128 bytes at a time */
+.Lcopyin_w_loop128:
+	ldrt	r4, [r0], #0x04		/* LD:00-03 */
+	ldrt	r5, [r0], #0x04		/* LD:04-07 */
+	pld	[r0, #0x18]		/* Prefetch 0x20 */
+	ldrt	r6, [r0], #0x04		/* LD:08-0b */
+	ldrt	r7, [r0], #0x04		/* LD:0c-0f */
+	ldrt	r8, [r0], #0x04		/* LD:10-13 */
+	ldrt	r9, [r0], #0x04		/* LD:14-17 */
+	strd	r4, [r1], #0x08		/* ST:00-07 */
+	ldrt	r4, [r0], #0x04		/* LD:18-1b */
+	ldrt	r5, [r0], #0x04		/* LD:1c-1f */
+	strd	r6, [r1], #0x08		/* ST:08-0f */
+	ldrt	r6, [r0], #0x04		/* LD:20-23 */
+	ldrt	r7, [r0], #0x04		/* LD:24-27 */
+	pld	[r0, #0x18]		/* Prefetch 0x40 */
+	strd	r8, [r1], #0x08		/* ST:10-17 */
+	ldrt	r8, [r0], #0x04		/* LD:28-2b */
+	ldrt	r9, [r0], #0x04		/* LD:2c-2f */
+	strd	r4, [r1], #0x08		/* ST:18-1f */
+	ldrt	r4, [r0], #0x04		/* LD:30-33 */
+	ldrt	r5, [r0], #0x04		/* LD:34-37 */
+	strd	r6, [r1], #0x08		/* ST:20-27 */
+	ldrt	r6, [r0], #0x04		/* LD:38-3b */
+	ldrt	r7, [r0], #0x04		/* LD:3c-3f */
+	strd	r8, [r1], #0x08		/* ST:28-2f */
+	ldrt	r8, [r0], #0x04		/* LD:40-43 */
+	ldrt	r9, [r0], #0x04		/* LD:44-47 */
+	pld	[r0, #0x18]		/* Prefetch 0x60 */
+	strd	r4, [r1], #0x08		/* ST:30-37 */
+	ldrt	r4, [r0], #0x04		/* LD:48-4b */
+	ldrt	r5, [r0], #0x04		/* LD:4c-4f */
+	strd	r6, [r1], #0x08		/* ST:38-3f */
+	ldrt	r6, [r0], #0x04		/* LD:50-53 */
+	ldrt	r7, [r0], #0x04		/* LD:54-57 */
+	strd	r8, [r1], #0x08		/* ST:40-47 */
+	ldrt	r8, [r0], #0x04		/* LD:58-5b */
+	ldrt	r9, [r0], #0x04		/* LD:5c-5f */
+	strd	r4, [r1], #0x08		/* ST:48-4f */
+	ldrt	r4, [r0], #0x04		/* LD:60-63 */
+	ldrt	r5, [r0], #0x04		/* LD:64-67 */
+	pld	[r0, #0x18]		/* Prefetch 0x80 */
+	strd	r6, [r1], #0x08		/* ST:50-57 */
+	ldrt	r6, [r0], #0x04		/* LD:68-6b */
+	ldrt	r7, [r0], #0x04		/* LD:6c-6f */
+	strd	r8, [r1], #0x08		/* ST:58-5f */
+	ldrt	r8, [r0], #0x04		/* LD:70-73 */
+	ldrt	r9, [r0], #0x04		/* LD:74-77 */
+	strd	r4, [r1], #0x08		/* ST:60-67 */
+	ldrt	r4, [r0], #0x04		/* LD:78-7b */
+	ldrt	r5, [r0], #0x04		/* LD:7c-7f */
+	strd	r6, [r1], #0x08		/* ST:68-6f */
+	strd	r8, [r1], #0x08		/* ST:70-77 */
+	subs	r2, r2, #0x80
+	strd	r4, [r1], #0x08		/* ST:78-7f */
+	bge	.Lcopyin_w_loop128
+
+.Lcopyin_w_lessthan128:
+	adds	r2, r2, #0x80		/* Adjust for extra sub */
+	ldmfdeq	sp!, {r4-r9}
+	RETeq
+	subs	r2, r2, #0x20
+	blt	.Lcopyin_w_lessthan32
+
+	/* Copy 32 bytes at a time */
+.Lcopyin_w_loop32:
+	ldrt	r4, [r0], #0x04
+	ldrt	r5, [r0], #0x04
+	pld	[r0, #0x18]
+	ldrt	r6, [r0], #0x04
+	ldrt	r7, [r0], #0x04
+	ldrt	r8, [r0], #0x04
+	ldrt	r9, [r0], #0x04
+	strd	r4, [r1], #0x08
+	ldrt	r4, [r0], #0x04
+	ldrt	r5, [r0], #0x04
+	strd	r6, [r1], #0x08
+	strd	r8, [r1], #0x08
+	subs	r2, r2, #0x20
+	strd	r4, [r1], #0x08
+	bge	.Lcopyin_w_loop32
+
+.Lcopyin_w_lessthan32:
+	adds	r2, r2, #0x20		/* Adjust for extra sub */
+	ldmfdeq	sp!, {r4-r9}
+	RETeq				/* Return now if done */
+
+	and	r4, r2, #0x18
+	rsb	r5, r4, #0x18
+	subs	r2, r2, r4
+	add	pc, pc, r5, lsl #1
+	nop
+
+	/* At least 24 bytes remaining */
+	ldrt	r4, [r0], #0x04
+	ldrt	r5, [r0], #0x04
+	nop
+	strd	r4, [r1], #0x08
+
+	/* At least 16 bytes remaining */
+	ldrt	r4, [r0], #0x04
+	ldrt	r5, [r0], #0x04
+	nop
+	strd	r4, [r1], #0x08
+
+	/* At least 8 bytes remaining */
+	ldrt	r4, [r0], #0x04
+	ldrt	r5, [r0], #0x04
+	nop
+	strd	r4, [r1], #0x08
+
+	/* Less than 8 bytes remaining */
+	ldmfd	sp!, {r4-r9}
+	RETeq				/* Return now if done */
+	mov	r3, #0x00
+
+.Lcopyin_w_less_than8:
+	subs	r2, r2, #0x04
+	ldrtge	ip, [r0], #0x04
+	strge	ip, [r1], #0x04
+	RETeq				/* Return now if done */
+	addlt	r2, r2, #0x04
+	ldrbt	ip, [r0], #0x01
+	cmp	r2, #0x02
+	ldrbtge	r2, [r0], #0x01
+	strb	ip, [r1], #0x01
+	ldrbtgt	ip, [r0]
+	strbge	r2, [r1], #0x01
+	strbgt	ip, [r1]
+	RET
+
+/*
+ * At this point, it has not been possible to word align both buffers.
+ * The destination buffer (r1) is word aligned, but the source buffer
+ * (r0) is not.
+ */
+.Lcopyin_bad_align:
+	stmfd	sp!, {r4-r7}
+	mov	r3, #0x01
+	bic	r0, r0, #0x03
+	cmp	ip, #2
+	ldrt	ip, [r0], #0x04
+	bgt	.Lcopyin_bad3
+	beq	.Lcopyin_bad2
+	b	.Lcopyin_bad1
+
+.Lcopyin_bad1_loop16:
+#ifdef __ARMEB__
+	mov	r4, ip, lsl #8
+#else
+	mov	r4, ip, lsr #8
+#endif
+	ldrt	r5, [r0], #0x04
+	pld	[r0, #0x018]
+	ldrt	r6, [r0], #0x04
+	ldrt	r7, [r0], #0x04
+	ldrt	ip, [r0], #0x04
+#ifdef __ARMEB__
+	orr	r4, r4, r5, lsr #24
+	mov	r5, r5, lsl #8
+	orr	r5, r5, r6, lsr #24
+	mov	r6, r6, lsl #8
+	orr	r6, r6, r7, lsr #24
+	mov	r7, r7, lsl #8
+	orr	r7, r7, ip, lsr #24
+#else
+	orr	r4, r4, r5, lsl #24
+	mov	r5, r5, lsr #8
+	orr	r5, r5, r6, lsl #24
+	mov	r6, r6, lsr #8
+	orr	r6, r6, r7, lsl #24
+	mov	r7, r7, lsr #8
+	orr	r7, r7, ip, lsl #24
+#endif
+	str	r4, [r1], #0x04
+	str	r5, [r1], #0x04
+	str	r6, [r1], #0x04
+	str	r7, [r1], #0x04
+.Lcopyin_bad1:
+	subs	r2, r2, #0x10
+	bge	.Lcopyin_bad1_loop16
+
+	adds	r2, r2, #0x10
+	ldmfdeq	sp!, {r4-r7}
+	RETeq				/* Return now if done */
+	subs	r2, r2, #0x04
+	sublt	r0, r0, #0x03
+	blt	.Lcopyin_l4
+
+.Lcopyin_bad1_loop4:
+#ifdef __ARMEB__
+	mov	r4, ip, lsl #8
+#else
+	mov	r4, ip, lsr #8
+#endif
+	ldrt	ip, [r0], #0x04
+	subs	r2, r2, #0x04
+#ifdef __ARMEB__
+	orr	r4, r4, ip, lsr #24
+#else
+	orr	r4, r4, ip, lsl #24
+#endif
+	str	r4, [r1], #0x04
+	bge	.Lcopyin_bad1_loop4
+	sub	r0, r0, #0x03
+	b	.Lcopyin_l4
+
+.Lcopyin_bad2_loop16:
+#ifdef __ARMEB__
+	mov	r4, ip, lsl #16
+#else
+	mov	r4, ip, lsr #16
+#endif
+	ldrt	r5, [r0], #0x04
+	pld	[r0, #0x018]
+	ldrt	r6, [r0], #0x04
+	ldrt	r7, [r0], #0x04
+	ldrt	ip, [r0], #0x04
+#ifdef __ARMEB__
+	orr	r4, r4, r5, lsr #16
+	mov	r5, r5, lsl #16
+	orr	r5, r5, r6, lsr #16
+	mov	r6, r6, lsl #16
+	orr	r6, r6, r7, lsr #16
+	mov	r7, r7, lsl #16
+	orr	r7, r7, ip, lsr #16
+#else
+	orr	r4, r4, r5, lsl #16
+	mov	r5, r5, lsr #16
+	orr	r5, r5, r6, lsl #16
+	mov	r6, r6, lsr #16
+	orr	r6, r6, r7, lsl #16
+	mov	r7, r7, lsr #16
+	orr	r7, r7, ip, lsl #16
+#endif
+	str	r4, [r1], #0x04
+	str	r5, [r1], #0x04
+	str	r6, [r1], #0x04
+	str	r7, [r1], #0x04
+.Lcopyin_bad2:
+	subs	r2, r2, #0x10
+	bge	.Lcopyin_bad2_loop16
+
+	adds	r2, r2, #0x10
+	ldmfdeq	sp!, {r4-r7}
+	RETeq				/* Return now if done */
+	subs	r2, r2, #0x04
+	sublt	r0, r0, #0x02
+	blt	.Lcopyin_l4
+
+.Lcopyin_bad2_loop4:
+#ifdef __ARMEB__
+	mov	r4, ip, lsl #16
+#else
+	mov	r4, ip, lsr #16
+#endif
+	ldrt	ip, [r0], #0x04
+	subs	r2, r2, #0x04
+#ifdef __ARMEB__
+	orr	r4, r4, ip, lsr #16
+#else
+	orr	r4, r4, ip, lsl #16
+#endif
+	str	r4, [r1], #0x04
+	bge	.Lcopyin_bad2_loop4
+	sub	r0, r0, #0x02
+	b	.Lcopyin_l4
+
+.Lcopyin_bad3_loop16:
+#ifdef __ARMEB__
+	mov	r4, ip, lsl #24
+#else
+	mov	r4, ip, lsr #24
+#endif
+	ldrt	r5, [r0], #0x04
+	pld	[r0, #0x018]
+	ldrt	r6, [r0], #0x04
+	ldrt	r7, [r0], #0x04
+	ldrt	ip, [r0], #0x04
+#ifdef __ARMEB__
+	orr	r4, r4, r5, lsr #8
+	mov	r5, r5, lsl #24
+	orr	r5, r5, r6, lsr #8
+	mov	r6, r6, lsl #24
+	orr	r6, r6, r7, lsr #8
+	mov	r7, r7, lsl #24
+	orr	r7, r7, ip, lsr #8
+#else
+	orr	r4, r4, r5, lsl #8
+	mov	r5, r5, lsr #24
+	orr	r5, r5, r6, lsl #8
+	mov	r6, r6, lsr #24
+	orr	r6, r6, r7, lsl #8
+	mov	r7, r7, lsr #24
+	orr	r7, r7, ip, lsl #8
+#endif
+	str	r4, [r1], #0x04
+	str	r5, [r1], #0x04
+	str	r6, [r1], #0x04
+	str	r7, [r1], #0x04
+.Lcopyin_bad3:
+	subs	r2, r2, #0x10
+	bge	.Lcopyin_bad3_loop16
+
+	adds	r2, r2, #0x10
+	ldmfdeq	sp!, {r4-r7}
+	RETeq				/* Return now if done */
+	subs	r2, r2, #0x04
+	sublt	r0, r0, #0x01
+	blt	.Lcopyin_l4
+
+.Lcopyin_bad3_loop4:
+#ifdef __ARMEB__
+	mov	r4, ip, lsl #24
+#else
+	mov	r4, ip, lsr #24
+#endif
+	ldrt	ip, [r0], #0x04
+	subs	r2, r2, #0x04
+#ifdef __ARMEB__
+	orr	r4, r4, ip, lsr #8
+#else
+	orr	r4, r4, ip, lsl #8
+#endif
+	str	r4, [r1], #0x04
+	bge	.Lcopyin_bad3_loop4
+	sub	r0, r0, #0x01
+
+.Lcopyin_l4:
+	ldmfd	sp!, {r4-r7}
+	mov	r3, #0x00
+	adds	r2, r2, #0x04
+	RETeq
+.Lcopyin_l4_2:
+	rsbs	r2, r2, #0x03
+	addne	pc, pc, r2, lsl #3
+	nop
+	ldrbt	ip, [r0], #0x01
+	strb	ip, [r1], #0x01
+	ldrbt	ip, [r0], #0x01
+	strb	ip, [r1], #0x01
+	ldrbt	ip, [r0]
+	strb	ip, [r1]
+	RET
+END(copyin)
+
+/*
+ * r0 = kernel space address
+ * r1 = user space address
+ * r2 = length
+ *
+ * Copies bytes from kernel space to user space
+ */
+ENTRY(copyout)
+	cmp	r2, #0x00
+	movle	r0, #0x00
+	movle	pc, lr			/* Bail early if length is <= 0 */
+
+	ldr	r3, .L_arm_memcpy
+	ldr	r3, [r3]
+	cmp	r3, #0
+	beq	.Lnormale
+	ldr	r3, .L_min_memcpy_size
+	ldr	r3, [r3]
+	cmp	r2, r3
+	blt	.Lnormale
+	stmfd	sp!, {r0-r2, r4, lr}
+	mov     r3, r0
+	mov     r0, r1
+	mov     r1, r3
+	mov     r3, #1 /* DST_IS_USER */
+	ldr	r4, .L_arm_memcpy
+	mov	lr, pc
+	ldr	pc, [r4]
+	cmp     r0, #0
+	ldmfd   sp!, {r0-r2, r4, lr}
+	moveq	r0, #0
+	RETeq
+	
+.Lnormale:									
+	stmfd	sp!, {r10-r11, lr}
+
+	GET_PCB(r10)
+	ldr	r10, [r10]
+
+	mov	r3, #0x00
+	adr	ip, .Lcopyout_fault
+	ldr	r11, [r10, #PCB_ONFAULT]
+	str	ip, [r10, #PCB_ONFAULT]
+	bl	.Lcopyout_guts
+	str	r11, [r10, #PCB_ONFAULT]
+	mov	r0, #0x00
+	ldmfd	sp!, {r10-r11, pc}
+
+.Lcopyout_fault:
+	ldr	r0, =EFAULT
+	str	r11, [r10, #PCB_ONFAULT]
+	cmp	r3, #0x00
+	ldmfdgt	sp!, {r4-r7}		/* r3 > 0 Restore r4-r7 */
+	ldmfdlt	sp!, {r4-r9}		/* r3 < 0 Restore r4-r9 */
+	ldmfd	sp!, {r10-r11, pc}
+
+.Lcopyout_guts:
+	pld	[r0]
+	/* Word-align the destination buffer */
+	ands	ip, r1, #0x03		/* Already word aligned? */
+	beq	.Lcopyout_wordaligned	/* Yup */
+	rsb	ip, ip, #0x04
+	cmp	r2, ip			/* Enough bytes left to align it? */
+	blt	.Lcopyout_l4_2		/* Nope. Just copy bytewise */
+	sub	r2, r2, ip
+	rsbs	ip, ip, #0x03
+	addne	pc, pc, ip, lsl #3
+	nop
+	ldrb	ip, [r0], #0x01
+	strbt	ip, [r1], #0x01
+	ldrb	ip, [r0], #0x01
+	strbt	ip, [r1], #0x01
+	ldrb	ip, [r0], #0x01
+	strbt	ip, [r1], #0x01
+	cmp	r2, #0x00		/* All done? */
+	RETeq
+
+	/* Destination buffer is now word aligned */
+.Lcopyout_wordaligned:
+	ands	ip, r0, #0x03		/* Is src also word-aligned? */
+	bne	.Lcopyout_bad_align	/* Nope. Things just got bad */
+	cmp	r2, #0x08		/* Less than 8 bytes remaining? */
+	blt	.Lcopyout_w_less_than8
+
+	/* Quad-align the destination buffer */
+	tst	r0, #0x07		/* Already quad aligned? */
+	ldrne	ip, [r0], #0x04
+	subne	r2, r2, #0x04
+	strtne	ip, [r1], #0x04
+	
+	stmfd	sp!, {r4-r9}		/* Free up some registers */
+	mov	r3, #-1			/* Signal restore r4-r9 */
+
+	/* Destination buffer word aligned, source is quad aligned */
+	subs	r2, r2, #0x80
+	blt	.Lcopyout_w_lessthan128
+
+	/* Copy 128 bytes at a time */
+.Lcopyout_w_loop128:
+	ldrd	r4, [r0], #0x08		/* LD:00-07 */
+	pld	[r0, #0x18]		/* Prefetch 0x20 */
+	ldrd	r6, [r0], #0x08		/* LD:08-0f */
+	ldrd	r8, [r0], #0x08		/* LD:10-17 */
+	strt	r4, [r1], #0x04		/* ST:00-03 */
+	strt	r5, [r1], #0x04		/* ST:04-07 */
+	ldrd	r4, [r0], #0x08		/* LD:18-1f */
+	strt	r6, [r1], #0x04		/* ST:08-0b */
+	strt	r7, [r1], #0x04		/* ST:0c-0f */
+	ldrd	r6, [r0], #0x08		/* LD:20-27 */
+	pld	[r0, #0x18]		/* Prefetch 0x40 */
+	strt	r8, [r1], #0x04		/* ST:10-13 */
+	strt	r9, [r1], #0x04		/* ST:14-17 */
+	ldrd	r8, [r0], #0x08		/* LD:28-2f */
+	strt	r4, [r1], #0x04		/* ST:18-1b */
+	strt	r5, [r1], #0x04		/* ST:1c-1f */
+	ldrd	r4, [r0], #0x08		/* LD:30-37 */
+	strt	r6, [r1], #0x04		/* ST:20-23 */
+	strt	r7, [r1], #0x04		/* ST:24-27 */
+	ldrd	r6, [r0], #0x08		/* LD:38-3f */
+	strt	r8, [r1], #0x04		/* ST:28-2b */
+	strt	r9, [r1], #0x04		/* ST:2c-2f */
+	ldrd	r8, [r0], #0x08		/* LD:40-47 */
+	pld	[r0, #0x18]		/* Prefetch 0x60 */
+	strt	r4, [r1], #0x04		/* ST:30-33 */
+	strt	r5, [r1], #0x04		/* ST:34-37 */
+	ldrd	r4, [r0], #0x08		/* LD:48-4f */
+	strt	r6, [r1], #0x04		/* ST:38-3b */
+	strt	r7, [r1], #0x04		/* ST:3c-3f */
+	ldrd	r6, [r0], #0x08		/* LD:50-57 */
+	strt	r8, [r1], #0x04		/* ST:40-43 */
+	strt	r9, [r1], #0x04		/* ST:44-47 */
+	ldrd	r8, [r0], #0x08		/* LD:58-4f */
+	strt	r4, [r1], #0x04		/* ST:48-4b */
+	strt	r5, [r1], #0x04		/* ST:4c-4f */
+	ldrd	r4, [r0], #0x08		/* LD:60-67 */
+	pld	[r0, #0x18]		/* Prefetch 0x80 */
+	strt	r6, [r1], #0x04		/* ST:50-53 */
+	strt	r7, [r1], #0x04		/* ST:54-57 */
+	ldrd	r6, [r0], #0x08		/* LD:68-6f */
+	strt	r8, [r1], #0x04		/* ST:58-5b */
+	strt	r9, [r1], #0x04		/* ST:5c-5f */
+	ldrd	r8, [r0], #0x08		/* LD:70-77 */
+	strt	r4, [r1], #0x04		/* ST:60-63 */
+	strt	r5, [r1], #0x04		/* ST:64-67 */
+	ldrd	r4, [r0], #0x08		/* LD:78-7f */
+	strt	r6, [r1], #0x04		/* ST:68-6b */
+	strt	r7, [r1], #0x04		/* ST:6c-6f */
+	strt	r8, [r1], #0x04		/* ST:70-73 */
+	strt	r9, [r1], #0x04		/* ST:74-77 */
+	subs	r2, r2, #0x80
+	strt	r4, [r1], #0x04		/* ST:78-7b */
+	strt	r5, [r1], #0x04		/* ST:7c-7f */
+	bge	.Lcopyout_w_loop128
+
+.Lcopyout_w_lessthan128:
+	adds	r2, r2, #0x80		/* Adjust for extra sub */
+	ldmfdeq	sp!, {r4-r9}
+	RETeq				/* Return now if done */
+	subs	r2, r2, #0x20
+	blt	.Lcopyout_w_lessthan32
+
+	/* Copy 32 bytes at a time */
+.Lcopyout_w_loop32:
+	ldrd	r4, [r0], #0x08
+	pld	[r0, #0x18]
+	ldrd	r6, [r0], #0x08
+	ldrd	r8, [r0], #0x08
+	strt	r4, [r1], #0x04
+	strt	r5, [r1], #0x04
+	ldrd	r4, [r0], #0x08
+	strt	r6, [r1], #0x04
+	strt	r7, [r1], #0x04
+	strt	r8, [r1], #0x04
+	strt	r9, [r1], #0x04
+	subs	r2, r2, #0x20
+	strt	r4, [r1], #0x04
+	strt	r5, [r1], #0x04
+	bge	.Lcopyout_w_loop32
+
+.Lcopyout_w_lessthan32:
+	adds	r2, r2, #0x20		/* Adjust for extra sub */
+	ldmfdeq	sp!, {r4-r9}
+	RETeq				/* Return now if done */
+
+	and	r4, r2, #0x18
+	rsb	r5, r4, #0x18
+	subs	r2, r2, r4
+	add	pc, pc, r5, lsl #1
+	nop
+
+	/* At least 24 bytes remaining */
+	ldrd	r4, [r0], #0x08
+	strt	r4, [r1], #0x04
+	strt	r5, [r1], #0x04
+	nop
+
+	/* At least 16 bytes remaining */
+	ldrd	r4, [r0], #0x08
+	strt	r4, [r1], #0x04
+	strt	r5, [r1], #0x04
+	nop
+
+	/* At least 8 bytes remaining */
+	ldrd	r4, [r0], #0x08
+	strt	r4, [r1], #0x04
+	strt	r5, [r1], #0x04
+	nop
+
+	/* Less than 8 bytes remaining */
+	ldmfd	sp!, {r4-r9}
+	RETeq				/* Return now if done */
+	mov	r3, #0x00
+
+.Lcopyout_w_less_than8:
+	subs	r2, r2, #0x04
+	ldrge	ip, [r0], #0x04
+	strtge	ip, [r1], #0x04
+	RETeq				/* Return now if done */
+	addlt	r2, r2, #0x04
+	ldrb	ip, [r0], #0x01
+	cmp	r2, #0x02
+	ldrbge	r2, [r0], #0x01
+	strbt	ip, [r1], #0x01
+	ldrbgt	ip, [r0]
+	strbtge	r2, [r1], #0x01
+	strbtgt	ip, [r1]
+	RET
+
+/*
+ * At this point, it has not been possible to word align both buffers.
+ * The destination buffer (r1) is word aligned, but the source buffer
+ * (r0) is not.
+ */
+.Lcopyout_bad_align:
+	stmfd	sp!, {r4-r7}
+	mov	r3, #0x01
+	bic	r0, r0, #0x03
+	cmp	ip, #2
+	ldr	ip, [r0], #0x04
+	bgt	.Lcopyout_bad3
+	beq	.Lcopyout_bad2
+	b	.Lcopyout_bad1
+
+.Lcopyout_bad1_loop16:
+#ifdef	__ARMEB__
+	mov	r4, ip, lsl #8
+#else
+	mov	r4, ip, lsr #8
+#endif
+	ldr	r5, [r0], #0x04
+	pld	[r0, #0x018]
+	ldr	r6, [r0], #0x04
+	ldr	r7, [r0], #0x04
+	ldr	ip, [r0], #0x04
+#ifdef	__ARMEB__
+	orr	r4, r4, r5, lsr #24
+	mov	r5, r5, lsl #8
+	orr	r5, r5, r6, lsr #24
+	mov	r6, r6, lsl #8
+	orr	r6, r6, r7, lsr #24
+	mov	r7, r7, lsl #8
+	orr	r7, r7, ip, lsr #24
+#else
+	orr	r4, r4, r5, lsl #24
+	mov	r5, r5, lsr #8
+	orr	r5, r5, r6, lsl #24
+	mov	r6, r6, lsr #8
+	orr	r6, r6, r7, lsl #24
+	mov	r7, r7, lsr #8
+	orr	r7, r7, ip, lsl #24
+#endif
+	strt	r4, [r1], #0x04
+	strt	r5, [r1], #0x04
+	strt	r6, [r1], #0x04
+	strt	r7, [r1], #0x04
+.Lcopyout_bad1:
+	subs	r2, r2, #0x10
+	bge	.Lcopyout_bad1_loop16
+
+	adds	r2, r2, #0x10
+	ldmfdeq	sp!, {r4-r7}
+	RETeq				/* Return now if done */
+	subs	r2, r2, #0x04
+	sublt	r0, r0, #0x03
+	blt	.Lcopyout_l4
+
+.Lcopyout_bad1_loop4:
+#ifdef __ARMEB__
+	mov	r4, ip, lsl #8
+#else
+	mov	r4, ip, lsr #8
+#endif
+	ldr	ip, [r0], #0x04
+	subs	r2, r2, #0x04
+#ifdef __ARMEB__
+	orr	r4, r4, ip, lsr #24
+#else
+	orr	r4, r4, ip, lsl #24
+#endif
+	strt	r4, [r1], #0x04
+	bge	.Lcopyout_bad1_loop4
+	sub	r0, r0, #0x03
+	b	.Lcopyout_l4
+
+.Lcopyout_bad2_loop16:
+#ifdef __ARMEB__
+	mov	r4, ip, lsl #16
+#else
+	mov	r4, ip, lsr #16
+#endif
+	ldr	r5, [r0], #0x04
+	pld	[r0, #0x018]
+	ldr	r6, [r0], #0x04
+	ldr	r7, [r0], #0x04
+	ldr	ip, [r0], #0x04
+#ifdef __ARMEB__
+	orr	r4, r4, r5, lsr #16
+	mov	r5, r5, lsl #16
+	orr	r5, r5, r6, lsr #16
+	mov	r6, r6, lsl #16
+	orr	r6, r6, r7, lsr #16
+	mov	r7, r7, lsl #16
+	orr	r7, r7, ip, lsr #16
+#else
+	orr	r4, r4, r5, lsl #16
+	mov	r5, r5, lsr #16
+	orr	r5, r5, r6, lsl #16
+	mov	r6, r6, lsr #16
+	orr	r6, r6, r7, lsl #16
+	mov	r7, r7, lsr #16
+	orr	r7, r7, ip, lsl #16
+#endif
+	strt	r4, [r1], #0x04
+	strt	r5, [r1], #0x04
+	strt	r6, [r1], #0x04
+	strt	r7, [r1], #0x04
+.Lcopyout_bad2:
+	subs	r2, r2, #0x10
+	bge	.Lcopyout_bad2_loop16
+
+	adds	r2, r2, #0x10
+	ldmfdeq	sp!, {r4-r7}
+	RETeq				/* Return now if done */
+	subs	r2, r2, #0x04
+	sublt	r0, r0, #0x02
+	blt	.Lcopyout_l4
+
+.Lcopyout_bad2_loop4:
+#ifdef __ARMEB__
+	mov	r4, ip, lsl #16
+#else
+	mov	r4, ip, lsr #16
+#endif
+	ldr	ip, [r0], #0x04
+	subs	r2, r2, #0x04
+#ifdef __ARMEB__
+	orr	r4, r4, ip, lsr #16
+#else
+	orr	r4, r4, ip, lsl #16
+#endif
+	strt	r4, [r1], #0x04
+	bge	.Lcopyout_bad2_loop4
+	sub	r0, r0, #0x02
+	b	.Lcopyout_l4
+
+.Lcopyout_bad3_loop16:
+#ifdef __ARMEB__
+	mov	r4, ip, lsl #24
+#else
+	mov	r4, ip, lsr #24
+#endif
+	ldr	r5, [r0], #0x04
+	pld	[r0, #0x018]
+	ldr	r6, [r0], #0x04
+	ldr	r7, [r0], #0x04
+	ldr	ip, [r0], #0x04
+#ifdef __ARMEB__
+	orr	r4, r4, r5, lsr #8
+	mov	r5, r5, lsl #24
+	orr	r5, r5, r6, lsr #8
+	mov	r6, r6, lsl #24
+	orr	r6, r6, r7, lsr #8
+	mov	r7, r7, lsl #24
+	orr	r7, r7, ip, lsr #8
+#else
+	orr	r4, r4, r5, lsl #8
+	mov	r5, r5, lsr #24
+	orr	r5, r5, r6, lsl #8
+	mov	r6, r6, lsr #24
+	orr	r6, r6, r7, lsl #8
+	mov	r7, r7, lsr #24
+	orr	r7, r7, ip, lsl #8
+#endif
+	strt	r4, [r1], #0x04
+	strt	r5, [r1], #0x04
+	strt	r6, [r1], #0x04
+	strt	r7, [r1], #0x04
+.Lcopyout_bad3:
+	subs	r2, r2, #0x10
+	bge	.Lcopyout_bad3_loop16
+
+	adds	r2, r2, #0x10
+	ldmfdeq	sp!, {r4-r7}
+	RETeq				/* Return now if done */
+	subs	r2, r2, #0x04
+	sublt	r0, r0, #0x01
+	blt	.Lcopyout_l4
+
+.Lcopyout_bad3_loop4:
+#ifdef __ARMEB__
+	mov	r4, ip, lsl #24
+#else
+	mov	r4, ip, lsr #24
+#endif
+	ldr	ip, [r0], #0x04
+	subs	r2, r2, #0x04
+#ifdef __ARMEB__
+	orr	r4, r4, ip, lsr #8
+#else
+	orr	r4, r4, ip, lsl #8
+#endif
+	strt	r4, [r1], #0x04
+	bge	.Lcopyout_bad3_loop4
+	sub	r0, r0, #0x01
+
+.Lcopyout_l4:
+	ldmfd	sp!, {r4-r7}
+	mov	r3, #0x00
+	adds	r2, r2, #0x04
+	RETeq
+.Lcopyout_l4_2:
+	rsbs	r2, r2, #0x03
+	addne	pc, pc, r2, lsl #3
+	nop
+	ldrb	ip, [r0], #0x01
+	strbt	ip, [r1], #0x01
+	ldrb	ip, [r0], #0x01
+	strbt	ip, [r1], #0x01
+	ldrb	ip, [r0]
+	strbt	ip, [r1]
+	RET
+END(copyout)
+


Property changes on: trunk/sys/arm/arm/bcopyinout_xscale.S
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/blockio.S
===================================================================
--- trunk/sys/arm/arm/blockio.S	                        (rev 0)
+++ trunk/sys/arm/arm/blockio.S	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,597 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: blockio.S,v 1.5 2002/08/15 01:38:16 briggs Exp $	*/
+
+/*-
+ * Copyright (c) 2001 Ben Harris.
+ * Copyright (c) 1994 Mark Brinicombe.
+ * Copyright (c) 1994 Brini.
+ * All rights reserved.
+ *
+ * This code is derived from software written for Brini by Mark Brinicombe
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Brini.
+ * 4. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BRINI ``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 BRINI 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.
+ *
+ * RiscBSD kernel project
+ *
+ * blockio.S
+ *
+ * optimised block read/write from/to IO routines.
+ *
+ * Created      : 08/10/94
+ * Modified	: 22/01/99  -- R.Earnshaw
+ *			       Faster, and small tweaks for StrongARM 	
+ */
+
+#include <machine/asm.h>
+
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/blockio.S 275767 2014-12-14 16:28:53Z andrew $");
+
+	.syntax	unified
+
+/*
+ * Read bytes from an I/O address into a block of memory
+ *
+ * r0 = address to read from (IO)
+ * r1 = address to write to (memory)
+ * r2 = length
+ */
+
+/* This code will look very familiar if you've read _memcpy(). */
+ENTRY(read_multi_1)
+	mov	ip, sp
+	stmfd	sp!, {fp, ip, lr, pc}
+	sub	fp, ip, #4
+	subs	r2, r2, #4		/* r2 = length - 4 */
+	blt	.Lrm1_l4			/* less than 4 bytes */
+	ands	r12, r1, #3
+	beq	.Lrm1_main		/* aligned destination */
+	rsb	r12, r12, #4
+	cmp	r12, #2
+	ldrb	r3, [r0]
+	strb	r3, [r1], #1
+	ldrbge	r3, [r0]
+	strbge	r3, [r1], #1
+	ldrbgt	r3, [r0]
+	strbgt	r3, [r1], #1
+	subs	r2, r2, r12
+	blt	.Lrm1_l4
+.Lrm1_main:
+.Lrm1loop:
+	ldrb	r3, [r0]
+	ldrb	r12, [r0]
+	orr	r3, r3, r12, lsl #8
+	ldrb	r12, [r0]
+	orr	r3, r3, r12, lsl #16
+	ldrb	r12, [r0]
+	orr	r3, r3, r12, lsl #24
+	str	r3, [r1], #4
+	subs	r2, r2, #4
+	bge	.Lrm1loop
+.Lrm1_l4:
+	adds	r2, r2, #4			/* r2 = length again */
+	ldmdbeq	fp, {fp, sp, pc}
+	RETeq
+	cmp	r2, #2
+	ldrb	r3, [r0]
+	strb	r3, [r1], #1
+	ldrbge	r3, [r0]
+	strbge	r3, [r1], #1
+	ldrbgt	r3, [r0]
+	strbgt	r3, [r1], #1
+	ldmdb	fp, {fp, sp, pc}
+END(read_multi_1)
+
+/*
+ * Write bytes to an I/O address from a block of memory
+ *
+ * r0 = address to write to (IO)
+ * r1 = address to read from (memory)
+ * r2 = length
+ */
+
+/* This code will look very familiar if you've read _memcpy(). */
+ENTRY(write_multi_1)
+	mov	ip, sp
+	stmfd	sp!, {fp, ip, lr, pc}
+	sub	fp, ip, #4
+	subs	r2, r2, #4		/* r2 = length - 4 */
+	blt	.Lwm1_l4		/* less than 4 bytes */
+	ands	r12, r1, #3
+	beq	.Lwm1_main		/* aligned source */
+	rsb	r12, r12, #4
+	cmp	r12, #2
+	ldrb	r3, [r1], #1
+	strb	r3, [r0]
+	ldrbge	r3, [r1], #1
+	strbge	r3, [r0]
+	ldrbgt	r3, [r1], #1
+	strbgt	r3, [r0]
+	subs	r2, r2, r12
+	blt	.Lwm1_l4
+.Lwm1_main:
+.Lwm1loop:
+	ldr	r3, [r1], #4
+	strb	r3, [r0]
+	mov	r3, r3, lsr #8
+	strb	r3, [r0]
+	mov	r3, r3, lsr #8
+	strb	r3, [r0]
+	mov	r3, r3, lsr #8
+	strb	r3, [r0]
+	subs	r2, r2, #4
+	bge	.Lwm1loop
+.Lwm1_l4:
+	adds	r2, r2, #4			/* r2 = length again */
+	ldmdbeq	fp, {fp, sp, pc}
+	cmp	r2, #2
+	ldrb	r3, [r1], #1
+	strb	r3, [r0]
+	ldrbge	r3, [r1], #1
+	strbge	r3, [r0]
+	ldrbgt	r3, [r1], #1
+	strbgt	r3, [r0]
+	ldmdb	fp, {fp, sp, pc}
+END(write_multi_1)
+
+/*
+ * Reads short ints (16 bits) from an I/O address into a block of memory
+ *
+ * r0 = address to read from (IO)
+ * r1 = address to write to (memory)
+ * r2 = length
+ */
+
+ENTRY(insw)
+/* Make sure that we have a positive length */
+	cmp	r2, #0x00000000
+	movle	pc, lr
+
+/* If the destination address and the size is word aligned, do it fast */
+
+	tst	r2, #0x00000001
+	tsteq	r1, #0x00000003
+	beq	.Lfastinsw
+
+/* Non aligned insw */
+
+.Linswloop:
+	ldr	r3, [r0]
+	subs	r2, r2, #0x00000001	/* Loop test in load delay slot */
+	strb	r3, [r1], #0x0001
+	mov	r3, r3, lsr #8
+	strb	r3, [r1], #0x0001
+	bgt	.Linswloop
+
+	RET
+
+/* Word aligned insw */
+
+.Lfastinsw:
+
+.Lfastinswloop:
+	ldr	r3, [r0, #0x0002]	/* take advantage of nonaligned
+					 * word accesses */
+	ldr	ip, [r0]
+	mov	r3, r3, lsr #16		/* Put the two shorts together */
+	orr	r3, r3, ip, lsl #16
+	str	r3, [r1], #0x0004	/* Store */
+	subs	r2, r2, #0x00000002	/* Next */
+	bgt	.Lfastinswloop
+
+	RET
+END(insw)
+
+/*
+ * Writes short ints (16 bits) from a block of memory to an I/O address
+ *
+ * r0 = address to write to (IO)
+ * r1 = address to read from (memory)
+ * r2 = length
+ */
+
+ENTRY(outsw)
+/* Make sure that we have a positive length */
+	cmp	r2, #0x00000000
+	movle	pc, lr
+
+/* If the destination address and the size is word aligned, do it fast */
+
+	tst	r2, #0x00000001
+	tsteq	r1, #0x00000003
+	beq	.Lfastoutsw
+
+/* Non aligned outsw */
+
+.Loutswloop:
+	ldrb	r3, [r1], #0x0001
+	ldrb	ip, [r1], #0x0001
+	subs	r2, r2, #0x00000001	/* Loop test in load delay slot */
+	orr	r3, r3, ip, lsl #8
+	orr	r3, r3, r3, lsl #16
+	str	r3, [r0]
+	bgt	.Loutswloop
+
+	RET
+
+/* Word aligned outsw */
+
+.Lfastoutsw:
+
+.Lfastoutswloop:
+	ldr	r3, [r1], #0x0004	/* r3 = (H)(L) */
+	subs	r2, r2, #0x00000002	/* Loop test in load delay slot */
+
+	eor	ip, r3, r3, lsr #16	/* ip = (H)(H^L) */
+	eor	r3, r3, ip, lsl #16	/* r3 = (H^H^L)(L) = (L)(L) */
+	eor	ip, ip, r3, lsr #16	/* ip = (H)(H^L^L) = (H)(H) */
+
+	str	r3, [r0]
+	str	ip, [r0]
+	
+/*	mov	ip, r3, lsl #16
+ *	orr	ip, ip, ip, lsr #16
+ *	str	ip, [r0]
+ *
+ *	mov	ip, r3, lsr #16
+ *	orr	ip, ip, ip, lsl #16
+ *	str	ip, [r0]
+ */
+
+	bgt	.Lfastoutswloop
+
+	RET
+END(outsw)
+
+/*
+ * reads short ints (16 bits) from an I/O address into a block of memory
+ * with a length garenteed to be a multiple of 16 bytes
+ * with a word aligned destination address
+ *
+ * r0 = address to read from (IO)
+ * r1 = address to write to (memory)
+ * r2 = length
+ */
+
+ENTRY(insw16)
+/* Make sure that we have a positive length */
+	cmp	r2, #0x00000000
+	movle	pc, lr
+
+/* If the destination address is word aligned and the size suitably
+   aligned, do it fast */
+
+	tst	r2, #0x00000007
+	tsteq	r1, #0x00000003
+
+	bne	_C_LABEL(insw)
+
+/* Word aligned insw */
+
+	stmfd	sp!, {r4,r5,lr}
+
+.Linsw16loop:
+	ldr	r3, [r0, #0x0002]	/* take advantage of nonaligned
+					 * word accesses */
+	ldr	lr, [r0]
+	mov	r3, r3, lsr #16		/* Put the two shorts together */
+	orr	r3, r3, lr, lsl #16
+
+	ldr	r4, [r0, #0x0002]	/* take advantage of nonaligned
+					 * word accesses */
+	ldr	lr, [r0]
+	mov	r4, r4, lsr #16		/* Put the two shorts together */
+	orr	r4, r4, lr, lsl #16
+
+	ldr	r5, [r0, #0x0002]	/* take advantage of nonaligned
+					 * word accesses */
+	ldr	lr, [r0]
+	mov	r5, r5, lsr #16		/* Put the two shorts together */
+	orr	r5, r5, lr, lsl #16
+
+	ldr	ip, [r0, #0x0002]	/* take advantage of nonaligned
+					 * word accesses */
+	ldr	lr, [r0]
+	mov	ip, ip, lsr #16		/* Put the two shorts together */
+	orr	ip, ip, lr, lsl #16
+
+	stmia	r1!, {r3-r5,ip}
+	subs	r2, r2, #0x00000008	/* Next */
+	bgt	.Linsw16loop
+
+	ldmfd	sp!, {r4,r5,pc}		/* Restore regs and go home */
+END(insw16)
+
+/*
+ * Writes short ints (16 bits) from a block of memory to an I/O address
+ *
+ * r0 = address to write to (IO)
+ * r1 = address to read from (memory)
+ * r2 = length
+ */
+
+ENTRY(outsw16)
+/* Make sure that we have a positive length */
+	cmp	r2, #0x00000000
+	movle	pc, lr
+
+/* If the destination address is word aligned and the size suitably
+   aligned, do it fast */
+
+	tst	r2, #0x00000007
+	tsteq	r1, #0x00000003
+
+	bne	_C_LABEL(outsw)
+
+/* Word aligned outsw */
+
+	stmfd	sp!, {r4,r5,lr}
+
+.Loutsw16loop:
+	ldmia	r1!, {r4,r5,ip,lr}
+
+	eor	r3, r4, r4, lsl #16	/* r3 = (A^B)(B) */
+	eor	r4, r4, r3, lsr #16	/* r4 = (A)(B^A^B) = (A)(A) */
+	eor	r3, r3, r4, lsl #16	/* r3 = (A^B^A)(B) = (B)(B) */
+	str	r3, [r0]
+	str	r4, [r0]
+	
+/*	mov	r3, r4, lsl #16
+ *	orr	r3, r3, r3, lsr #16
+ *	str	r3, [r0]
+ *
+ *	mov	r3, r4, lsr #16
+ *	orr	r3, r3, r3, lsl #16
+ *	str	r3, [r0]
+ */
+
+	eor	r3, r5, r5, lsl #16	/* r3 = (A^B)(B) */
+	eor	r5, r5, r3, lsr #16	/* r4 = (A)(B^A^B) = (A)(A) */
+	eor	r3, r3, r5, lsl #16	/* r3 = (A^B^A)(B) = (B)(B) */
+	str	r3, [r0]
+	str	r5, [r0]
+
+	eor	r3, ip, ip, lsl #16	/* r3 = (A^B)(B) */
+	eor	ip, ip, r3, lsr #16	/* r4 = (A)(B^A^B) = (A)(A) */
+	eor	r3, r3, ip, lsl #16	/* r3 = (A^B^A)(B) = (B)(B) */
+	str	r3, [r0]
+	str	ip, [r0]
+
+	eor	r3, lr, lr, lsl #16	/* r3 = (A^B)(B) */
+	eor	lr, lr, r3, lsr #16	/* r4 = (A)(B^A^B) = (A)(A) */
+	eor	r3, r3, lr, lsl #16	/* r3 = (A^B^A)(B) = (B)(B) */
+	str	r3, [r0]
+	str	lr, [r0]
+
+	subs	r2, r2, #0x00000008
+	bgt	.Loutsw16loop
+
+	ldmfd	sp!, {r4,r5,pc}		/* and go home */
+END(outsw16)
+
+/*
+ * reads short ints (16 bits) from an I/O address into a block of memory
+ * The I/O address is assumed to be mapped multiple times in a block of
+ * 8 words.
+ * The destination address should be word aligned.
+ *
+ * r0 = address to read from (IO)
+ * r1 = address to write to (memory)
+ * r2 = length
+ */
+
+ENTRY(inswm8)
+/* Make sure that we have a positive length */
+	cmp	r2, #0x00000000
+	movle	pc, lr
+
+/* If the destination address is word aligned and the size suitably
+   aligned, do it fast */
+
+	tst	r1, #0x00000003
+
+	bne	_C_LABEL(insw)
+
+/* Word aligned insw */
+
+	stmfd	sp!, {r4-r9,lr}
+
+	mov	lr, #0xff000000
+	orr	lr, lr, #0x00ff0000
+
+.Linswm8_loop8:
+	cmp	r2, #8
+	bcc	.Linswm8_l8
+
+	ldmia	r0, {r3-r9,ip}
+
+	bic	r3, r3, lr
+	orr	r3, r3, r4, lsl #16
+	bic	r5, r5, lr
+	orr	r4, r5, r6, lsl #16
+	bic	r7, r7, lr
+	orr	r5, r7, r8, lsl #16
+	bic	r9, r9, lr
+	orr	r6, r9, ip, lsl #16
+
+	stmia	r1!, {r3-r6}
+
+	subs	r2, r2, #0x00000008	/* Next */
+	bne	.Linswm8_loop8
+	beq	.Linswm8_l1
+
+.Linswm8_l8:
+	cmp	r2, #4
+	bcc	.Linswm8_l4
+
+	ldmia	r0, {r3-r6}
+
+	bic	r3, r3, lr
+	orr	r3, r3, r4, lsl #16
+	bic	r5, r5, lr
+	orr	r4, r5, r6, lsl #16
+
+	stmia	r1!, {r3-r4}
+
+	subs	r2, r2, #0x00000004
+	beq	.Linswm8_l1
+
+.Linswm8_l4:
+	cmp	r2, #2
+	bcc	.Linswm8_l2
+
+	ldmia	r0, {r3-r4}
+
+	bic	r3, r3, lr
+	orr	r3, r3, r4, lsl #16
+	str	r3, [r1], #0x0004
+
+	subs	r2, r2, #0x00000002
+	beq	.Linswm8_l1
+
+.Linswm8_l2:
+	cmp	r2, #1
+	bcc	.Linswm8_l1
+
+	ldr	r3, [r0]
+	subs	r2, r2, #0x00000001	/* Test in load delay slot */
+					/* XXX, why don't we use result?  */
+
+	strb	r3, [r1], #0x0001
+	mov	r3, r3, lsr #8
+	strb	r3, [r1], #0x0001
+
+
+.Linswm8_l1:
+	ldmfd	sp!, {r4-r9,pc}		/* And go home */
+END(inswm8)
+
+/*
+ * write short ints (16 bits) to an I/O address from a block of memory
+ * The I/O address is assumed to be mapped multiple times in a block of
+ * 8 words.
+ * The source address should be word aligned.
+ *
+ * r0 = address to read to (IO)
+ * r1 = address to write from (memory)
+ * r2 = length
+ */
+
+ENTRY(outswm8)
+/* Make sure that we have a positive length */
+	cmp	r2, #0x00000000
+	movle	pc, lr
+
+/* If the destination address is word aligned and the size suitably
+   aligned, do it fast */
+
+	tst	r1, #0x00000003
+
+	bne	_C_LABEL(outsw)
+
+/* Word aligned outsw */
+
+	stmfd	sp!, {r4-r8,lr}
+
+.Loutswm8_loop8:
+	cmp	r2, #8
+	bcc	.Loutswm8_l8
+
+	ldmia	r1!, {r3,r5,r7,ip}
+
+	eor	r4, r3, r3, lsr #16	/* r4 = (A)(A^B) */
+	eor	r3, r3, r4, lsl #16	/* r3 = (A^A^B)(B) = (B)(B) */
+	eor	r4, r4, r3, lsr #16	/* r4 = (A)(B^A^B) = (A)(A) */
+
+	eor	r6, r5, r5, lsr #16	/* r6 = (A)(A^B) */
+	eor	r5, r5, r6, lsl #16	/* r5 = (A^A^B)(B) = (B)(B) */
+	eor	r6, r6, r5, lsr #16	/* r6 = (A)(B^A^B) = (A)(A) */
+
+	eor	r8, r7, r7, lsr #16	/* r8 = (A)(A^B) */
+	eor	r7, r7, r8, lsl #16	/* r7 = (A^A^B)(B) = (B)(B) */
+	eor	r8, r8, r7, lsr #16	/* r8 = (A)(B^A^B) = (A)(A) */
+
+	eor	lr, ip, ip, lsr #16	/* lr = (A)(A^B) */
+	eor	ip, ip, lr, lsl #16	/* ip = (A^A^B)(B) = (B)(B) */
+	eor	lr, lr, ip, lsr #16	/* lr = (A)(B^A^B) = (A)(A) */
+
+	stmia	r0, {r3-r8,ip,lr}
+
+	subs	r2, r2, #0x00000008	/* Next */
+	bne	.Loutswm8_loop8
+	beq	.Loutswm8_l1
+
+.Loutswm8_l8:
+	cmp	r2, #4
+	bcc	.Loutswm8_l4
+
+	ldmia	r1!, {r3-r4}
+
+	eor	r6, r3, r3, lsr #16	/* r6 = (A)(A^B) */
+	eor	r5, r3, r6, lsl #16	/* r5 = (A^A^B)(B) = (B)(B) */
+	eor	r6, r6, r5, lsr #16	/* r6 = (A)(B^A^B) = (A)(A) */
+
+	eor	r8, r4, r4, lsr #16	/* r8 = (A)(A^B) */
+	eor	r7, r4, r8, lsl #16	/* r7 = (A^A^B)(B) = (B)(B) */
+	eor	r8, r8, r7, lsr #16	/* r8 = (A)(B^A^B) = (A)(A) */
+
+	stmia	r0, {r5-r8}
+
+	subs	r2, r2, #0x00000004
+	beq	.Loutswm8_l1
+
+.Loutswm8_l4:
+	cmp	r2, #2
+	bcc	.Loutswm8_l2
+
+	ldr	r3, [r1], #0x0004	/* r3 = (A)(B) */
+	subs	r2, r2, #0x00000002	/* Done test in Load delay slot */
+
+	eor	r5, r3, r3, lsr #16	/* r5 = (A)(A^B)*/
+	eor	r4, r3, r5, lsl #16	/* r4 = (A^A^B)(B) = (B)(B) */
+	eor	r5, r5, r4, lsr #16	/* r5 = (A)(B^A^B) = (A)(A) */
+
+	stmia	r0, {r4, r5}
+
+	beq	.Loutswm8_l1
+
+.Loutswm8_l2:
+	cmp	r2, #1
+	bcc	.Loutswm8_l1
+
+	ldrb	r3, [r1], #0x0001
+	ldrb	r4, [r1], #0x0001
+	subs	r2, r2, #0x00000001	/* Done test in load delay slot */
+					/* XXX This test isn't used?  */
+	orr	r3, r3, r4, lsl #8
+	orr	r3, r3, r3, lsl #16
+	str	r3, [r0]
+
+.Loutswm8_l1:
+	ldmfd	sp!, {r4-r8,pc}		/* And go home */
+END(outswm8)
+


Property changes on: trunk/sys/arm/arm/blockio.S
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/bootconfig.c
===================================================================
--- trunk/sys/arm/arm/bootconfig.c	                        (rev 0)
+++ trunk/sys/arm/arm/bootconfig.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,127 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: bootconfig.c,v 1.2 2002/03/10 19:56:39 lukem Exp $	*/
+
+/*-
+ * Copyright (c) 1994-1998 Mark Brinicombe.
+ * Copyright (c) 1994 Brini.
+ * All rights reserved.
+ *
+ * This code is derived from software written for Brini by Mark Brinicombe
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Mark Brinicombe
+ *	for the NetBSD Project.
+ * 4. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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: stable/10/sys/arm/arm/bootconfig.c 236991 2012-06-13 04:59:55Z imp $");
+
+#include <sys/param.h>
+
+#include <sys/systm.h>
+
+#include <machine/bootconfig.h>
+
+
+/*
+ * Function to identify and process different types of boot argument
+ */
+
+int
+get_bootconf_option(opts, opt, type, result)
+	char *opts;
+	char *opt;
+	int type;
+	void *result;
+{
+	char *ptr;
+	char *optstart;
+	int not;
+
+	ptr = opts;
+
+	while (*ptr) {
+		/* Find start of option */
+		while (*ptr == ' ' || *ptr == '\t')
+			++ptr;
+
+		if (*ptr == 0)
+			break;
+
+		not = 0;
+
+		/* Is it a negate option */
+		if ((type & BOOTOPT_TYPE_MASK) == BOOTOPT_TYPE_BOOLEAN && *ptr == '!') {
+			not = 1;
+			++ptr;
+		}
+
+		/* Find the end of option */
+		optstart = ptr;
+		while (*ptr != 0 && *ptr != ' ' && *ptr != '\t' && *ptr != '=')
+			++ptr;
+
+		if ((*ptr == '=')
+		    || (*ptr != '=' && ((type & BOOTOPT_TYPE_MASK) == BOOTOPT_TYPE_BOOLEAN))) {
+			/* compare the option */
+			if (strncmp(optstart, opt, (ptr - optstart)) == 0) {
+				/* found */
+
+				if (*ptr == '=')
+					++ptr;
+
+				switch(type & BOOTOPT_TYPE_MASK) {
+				case BOOTOPT_TYPE_BOOLEAN :
+					if (*(ptr - 1) == '=')
+						*((int *)result) = ((u_int)strtoul(ptr, NULL, 10) != 0);
+					else
+						*((int *)result) = !not;
+					break;
+				case BOOTOPT_TYPE_STRING :
+					*((char **)result) = ptr;
+					break;			
+				case BOOTOPT_TYPE_INT :
+					*((int *)result) = (u_int)strtoul(ptr, NULL, 10);
+					break;
+				case BOOTOPT_TYPE_BININT :
+					*((int *)result) = (u_int)strtoul(ptr, NULL, 2);
+					break;
+				case BOOTOPT_TYPE_HEXINT :
+					*((int *)result) = (u_int)strtoul(ptr, NULL, 16);
+					break;
+				default:
+					return(0);
+				}
+				return(1);
+			}
+		}
+		/* skip to next option */
+		while (*ptr != ' ' && *ptr != '\t' && *ptr != 0)
+			++ptr;
+	}
+	return(0);
+}


Property changes on: trunk/sys/arm/arm/bootconfig.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/bus_space_asm_generic.S
===================================================================
--- trunk/sys/arm/arm/bus_space_asm_generic.S	                        (rev 0)
+++ trunk/sys/arm/arm/bus_space_asm_generic.S	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,361 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: bus_space_asm_generic.S,v 1.3 2003/03/27 19:46:14 mycroft Exp $	*/
+
+/*-
+ * Copyright (c) 1997 Causality Limited.
+ * Copyright (c) 1997 Mark Brinicombe.
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Mark Brinicombe
+ *	for the NetBSD Project.
+ * 4. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 <machine/asm.h>
+#include <machine/cpuconf.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/bus_space_asm_generic.S 278727 2015-02-13 22:32:02Z ian $");
+
+/*
+ * Generic bus_space functions.
+ */
+
+/*
+ * read single
+ */
+
+ENTRY(generic_bs_r_1)
+	ldrb	r0, [r1, r2]
+	RET
+END(generic_bs_r_1)
+
+ENTRY(generic_bs_r_2)
+	ldrh	r0, [r1, r2]
+	RET
+END(generic_bs_r_2)
+
+ENTRY(generic_bs_r_4)
+	ldr	r0, [r1, r2]
+	RET
+END(generic_bs_r_4)
+
+/*
+ * write single
+ */
+
+ENTRY(generic_bs_w_1)
+	strb	r3, [r1, r2]
+	RET
+END(generic_bs_w_1)
+
+ENTRY(generic_bs_w_2)
+	strh	r3, [r1, r2]
+	RET
+END(generic_bs_w_2)
+
+ENTRY(generic_bs_w_4)
+	str	r3, [r1, r2]
+	RET
+END(generic_bs_w_4)
+
+/*
+ * read multiple
+ */
+
+ENTRY(generic_bs_rm_1)
+	add	r0, r1, r2
+	mov	r1, r3
+	ldr	r2, [sp, #0]
+	teq	r2, #0
+	RETeq
+
+1:	ldrb	r3, [r0]
+	strb	r3, [r1], #1
+	subs	r2, r2, #1
+	bne	1b
+
+	RET
+END(generic_bs_rm_1)
+
+ENTRY(generic_bs_rm_2)
+	add	r0, r1, r2
+	mov	r1, r3
+	ldr	r2, [sp, #0]
+	teq	r2, #0
+	RETeq
+
+1:	ldrh	r3, [r0]
+	strh	r3, [r1], #2
+	subs	r2, r2, #1
+	bne	1b
+
+	RET
+END(generic_bs_rm_2)
+
+ENTRY(generic_bs_rm_4)
+	add	r0, r1, r2
+	mov	r1, r3
+	ldr	r2, [sp, #0]
+	teq	r2, #0
+	RETeq
+
+1:	ldr	r3, [r0]
+	str	r3, [r1], #4
+	subs	r2, r2, #1
+	bne	1b
+
+	RET
+END(generic_bs_rm_4)
+
+/*
+ * write multiple
+ */
+
+ENTRY(generic_bs_wm_1)
+	add	r0, r1, r2
+	mov	r1, r3
+	ldr	r2, [sp, #0]
+	teq	r2, #0
+	RETeq
+
+1:	ldrb	r3, [r1], #1
+	strb	r3, [r0]
+	subs	r2, r2, #1
+	bne	1b
+
+	RET
+END(generic_bs_wm_1)
+
+ENTRY(generic_bs_wm_2)
+	add	r0, r1, r2
+	mov	r1, r3
+	ldr	r2, [sp, #0]
+	teq	r2, #0
+	RETeq
+
+1:	ldrh	r3, [r1], #2
+	strh	r3, [r0]
+	subs	r2, r2, #1
+	bne	1b
+
+	RET
+END(generic_bs_wm_2)
+
+ENTRY(generic_bs_wm_4)
+	add	r0, r1, r2
+	mov	r1, r3
+	ldr	r2, [sp, #0]
+	teq	r2, #0
+	RETeq
+
+1:	ldr	r3, [r1], #4
+	str	r3, [r0]
+	subs	r2, r2, #1
+	bne	1b
+
+	RET
+END(generic_bs_wm_4)
+
+/*
+ * read region
+ */
+
+ENTRY(generic_bs_rr_1)
+	add	r0, r1, r2
+	mov	r1, r3
+	ldr	r2, [sp, #0]
+	teq	r2, #0
+	RETeq
+
+1:	ldrb	r3, [r0], #1
+	strb	r3, [r1], #1
+	subs	r2, r2, #1
+	bne	1b
+
+	RET
+END(generic_bs_rr_1)
+
+ENTRY(generic_bs_rr_2)
+	add	r0, r1, r2
+	mov	r1, r3
+	ldr	r2, [sp, #0]
+	teq	r2, #0
+	RETeq
+
+1:	ldrh	r3, [r0], #2
+	strh	r3, [r1], #2
+	subs	r2, r2, #1
+	bne	1b
+
+	RET
+END(generic_bs_rr_2)
+
+ENTRY(generic_bs_rr_4)
+	add	r0, r1, r2
+	mov	r1, r3
+	ldr	r2, [sp, #0]
+	teq	r2, #0
+	RETeq
+
+1:	ldr	r3, [r0], #4
+	str	r3, [r1], #4
+	subs	r2, r2, #1
+	bne	1b
+
+	RET
+END(generic_bs_rr_4)
+
+/*
+ * write region.
+ */
+
+ENTRY(generic_bs_wr_1)
+	add	r0, r1, r2
+	mov	r1, r3
+	ldr	r2, [sp, #0]
+	teq	r2, #0
+	RETeq
+
+1:	ldrb	r3, [r1], #1
+	strb	r3, [r0], #1
+	subs	r2, r2, #1
+	bne	1b
+
+	RET
+END(generic_bs_wr_1)
+
+ENTRY(generic_bs_wr_2)
+	add	r0, r1, r2
+	mov	r1, r3
+	ldr	r2, [sp, #0]
+	teq	r2, #0
+	RETeq
+
+1:	ldrh	r3, [r1], #2
+	strh	r3, [r0], #2
+	subs	r2, r2, #1
+	bne	1b
+
+	RET
+END(generic_bs_wr_2)
+
+ENTRY(generic_bs_wr_4)
+	add	r0, r1, r2
+	mov	r1, r3
+	ldr	r2, [sp, #0]
+	teq	r2, #0
+	RETeq
+
+1:	ldr	r3, [r1], #4
+	str	r3, [r0], #4
+	subs	r2, r2, #1
+	bne	1b
+
+	RET
+END(generic_bs_wr_4)
+
+/*
+ * set region
+ */
+
+ENTRY(generic_bs_sr_1)
+	add	r0, r1, r2
+	mov	r1, r3
+	ldr	r2, [sp, #0]
+	teq	r2, #0
+	RETeq
+
+1:	strb	r1, [r0], #1
+	subs	r2, r2, #1
+	bne	1b
+
+	RET
+END(generic_bs_sr_1)
+
+ENTRY(generic_bs_sr_2)
+	add	r0, r1, r2
+	mov	r1, r3
+	ldr	r2, [sp, #0]
+	teq	r2, #0
+	RETeq
+
+1:	strh	r1, [r0], #2
+	subs	r2, r2, #1
+	bne	1b
+
+	RET
+END(generic_bs_sr_2)
+
+ENTRY(generic_bs_sr_4)
+	add	r0, r1, r2
+	mov	r1, r3
+	ldr	r2, [sp, #0]
+	teq	r2, #0
+	RETeq
+
+1:	str	r1, [r0], #4
+	subs	r2, r2, #1
+	bne	1b
+
+	RET
+END(generic_bs_sr_4)
+
+/*
+ * copy region
+ */
+
+ENTRY(generic_bs_c_2)
+	add	r0, r1, r2
+	ldr	r2, [sp, #0]
+	add	r1, r2, r3
+	ldr	r2, [sp, #4]
+	teq	r2, #0
+	RETeq
+
+	cmp	r0, r1
+	blt	2f
+
+1:	ldrh	r3, [r0], #2
+	strh	r3, [r1], #2
+	subs	r2, r2, #1
+	bne	1b
+
+	RET
+
+2:	add	r0, r0, r2, lsl #1
+	add	r1, r1, r2, lsl #1
+	sub	r0, r0, #2
+	sub	r1, r1, #2
+
+3:	ldrh	r3, [r0], #-2
+	strh	r3, [r1], #-2
+	subs	r2, r2, #1
+	bne	3b
+
+	RET
+END(generic_bs_c_2)
+


Property changes on: trunk/sys/arm/arm/bus_space_asm_generic.S
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/bus_space_base.c
===================================================================
--- trunk/sys/arm/arm/bus_space_base.c	                        (rev 0)
+++ trunk/sys/arm/arm/bus_space_base.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,160 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (C) 2008 MARVELL INTERNATIONAL LTD.
+ * All rights reserved.
+ *
+ * Developed by Semihalf.
+ *
+ * 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.
+ * 3. Neither the name of MARVELL nor the names of contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY 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 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: stable/10/sys/arm/arm/bus_space_base.c 278727 2015-02-13 22:32:02Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <machine/bus.h>
+
+#include "opt_platform.h"
+
+/* Prototypes for all the bus_space structure functions */
+bs_protos(generic);
+
+/*
+ * The bus space tag.  This is constant for all instances, so
+ * we never have to explicitly "create" it.
+ */
+static struct bus_space arm_base_bus_space __aligned(CACHE_LINE_SIZE) = {
+	/* privdata is whatever the implementer wants; unused in base tag */
+	.bs_privdata	= NULL,
+
+	/* mapping/unmapping */
+	.bs_map		= generic_bs_map,
+	.bs_unmap	= generic_bs_unmap,
+	.bs_subregion	= generic_bs_subregion,
+
+	/* allocation/deallocation */
+	.bs_alloc	= generic_bs_alloc,
+	.bs_free	= generic_bs_free,
+
+	/* barrier */
+	.bs_barrier	= generic_bs_barrier,
+
+	/* read (single) */
+	.bs_r_1		= NULL,	/* Use inline code in bus.h */
+	.bs_r_2		= NULL,	/* Use inline code in bus.h */
+	.bs_r_4		= NULL,	/* Use inline code in bus.h */
+	.bs_r_8		= NULL,	/* Use inline code in bus.h */
+
+	/* read multiple */
+	.bs_rm_1	= generic_bs_rm_1,
+	.bs_rm_2	= generic_bs_rm_2,
+	.bs_rm_4	= generic_bs_rm_4,
+	.bs_rm_8	= BS_UNIMPLEMENTED,
+
+	/* read region */
+	.bs_rr_1	= generic_bs_rr_1,
+	.bs_rr_2	= generic_bs_rr_2,
+	.bs_rr_4	= generic_bs_rr_4,
+	.bs_rr_8	= BS_UNIMPLEMENTED,
+
+	/* write (single) */
+	.bs_w_1		= NULL,	/* Use inline code in bus.h */
+	.bs_w_2		= NULL,	/* Use inline code in bus.h */
+	.bs_w_4		= NULL,	/* Use inline code in bus.h */
+	.bs_w_8		= NULL,	/* Use inline code in bus.h */
+
+	/* write multiple */
+	.bs_wm_1	= generic_bs_wm_1,
+	.bs_wm_2	= generic_bs_wm_2,
+	.bs_wm_4	= generic_bs_wm_4,
+	.bs_wm_8	= BS_UNIMPLEMENTED,
+
+	/* write region */
+	.bs_wr_1	= generic_bs_wr_1,
+	.bs_wr_2	= generic_bs_wr_2,
+	.bs_wr_4	= generic_bs_wr_4,
+	.bs_wr_8	= BS_UNIMPLEMENTED,
+
+	/* set multiple */
+	.bs_sm_1	= BS_UNIMPLEMENTED,
+	.bs_sm_2	= BS_UNIMPLEMENTED,
+	.bs_sm_4	= BS_UNIMPLEMENTED,
+	.bs_sm_8	= BS_UNIMPLEMENTED,
+
+	/* set region */
+	.bs_sr_1	= generic_bs_sr_1,
+	.bs_sr_2	= generic_bs_sr_2,
+	.bs_sr_4	= generic_bs_sr_4,
+	.bs_sr_8	= BS_UNIMPLEMENTED,
+
+	/* copy */
+	.bs_c_1		= BS_UNIMPLEMENTED,
+	.bs_c_2		= generic_bs_c_2,
+	.bs_c_4		= BS_UNIMPLEMENTED,
+	.bs_c_8		= BS_UNIMPLEMENTED,
+
+	/* read stream (single) */
+	.bs_r_1_s	= NULL,   /* Use inline code in bus.h */ 
+	.bs_r_2_s	= NULL,   /* Use inline code in bus.h */ 
+	.bs_r_4_s	= NULL,   /* Use inline code in bus.h */ 
+	.bs_r_8_s	= NULL,   /* Use inline code in bus.h */ 
+
+	/* read multiple stream */
+	.bs_rm_1_s	= generic_bs_rm_1,
+	.bs_rm_2_s	= generic_bs_rm_2,
+	.bs_rm_4_s	= generic_bs_rm_4,
+	.bs_rm_8_s	= BS_UNIMPLEMENTED,
+
+	/* read region stream */
+	.bs_rr_1_s	= generic_bs_rr_1,
+	.bs_rr_2_s	= generic_bs_rr_2,
+	.bs_rr_4_s	= generic_bs_rr_4,
+	.bs_rr_8_s	= BS_UNIMPLEMENTED,
+
+	/* write stream (single) */
+	.bs_w_1_s	= NULL,   /* Use inline code in bus.h */ 
+	.bs_w_2_s	= NULL,   /* Use inline code in bus.h */ 
+	.bs_w_4_s	= NULL,   /* Use inline code in bus.h */ 
+	.bs_w_8_s	= NULL,   /* Use inline code in bus.h */ 
+
+	/* write multiple stream */
+	.bs_wm_1_s	= generic_bs_wm_1,
+	.bs_wm_2_s	= generic_bs_wm_2,
+	.bs_wm_4_s	= generic_bs_wm_4,
+	.bs_wm_8_s	= BS_UNIMPLEMENTED,
+
+	/* write region stream */
+	.bs_wr_1_s	= generic_bs_wr_1,
+	.bs_wr_2_s	= generic_bs_wr_2,
+	.bs_wr_4_s	= generic_bs_wr_4,
+	.bs_wr_8_s	= BS_UNIMPLEMENTED,
+};
+
+#ifdef FDT
+bus_space_tag_t fdtbus_bs_tag = &arm_base_bus_space;
+#endif
+
+bus_space_tag_t arm_base_bs_tag = &arm_base_bus_space;


Property changes on: trunk/sys/arm/arm/bus_space_base.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/bus_space_generic.c
===================================================================
--- trunk/sys/arm/arm/bus_space_generic.c	                        (rev 0)
+++ trunk/sys/arm/arm/bus_space_generic.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,134 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: obio_space.c,v 1.6 2003/07/15 00:25:05 lukem Exp $	*/
+
+/*-
+ * Copyright (c) 2001, 2002, 2003 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Jason R. Thorpe for Wasabi Systems, Inc.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed for the NetBSD Project by
+ *	Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
+ * 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: stable/10/sys/arm/arm/bus_space_generic.c 278727 2015-02-13 22:32:02Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/vm_kern.h>
+#include <vm/vm_extern.h>
+
+#include <machine/bus.h>
+#include <machine/cpufunc.h>
+#include <machine/devmap.h>
+
+void
+generic_bs_unimplemented(void)
+{
+
+	panic("unimplemented bus_space function called");
+}
+
+/* Prototypes for all the bus_space structure functions */
+bs_protos(generic);
+
+int
+generic_bs_map(bus_space_tag_t t, bus_addr_t bpa, bus_size_t size, int flags,
+    bus_space_handle_t *bshp)
+{
+	void *va;
+
+	/*
+	 * We don't even examine the passed-in flags.  For ARM, the CACHEABLE
+	 * flag doesn't make sense (we create PTE_DEVICE mappings), and the
+	 * LINEAR flag is just implied because we use kva_alloc(size).
+	 */
+	if ((va = pmap_mapdev(bpa, size)) == NULL)
+		return (ENOMEM);
+	*bshp = (bus_space_handle_t)va;
+	return (0);
+}
+
+int
+generic_bs_alloc(bus_space_tag_t t, bus_addr_t rstart, bus_addr_t rend, bus_size_t size,
+    bus_size_t alignment, bus_size_t boundary, int flags, bus_addr_t *bpap,
+    bus_space_handle_t *bshp)
+{
+
+	panic("generic_bs_alloc(): not implemented");
+}
+
+
+void
+generic_bs_unmap(bus_space_tag_t t, bus_space_handle_t h, bus_size_t size)
+{
+
+	pmap_unmapdev((vm_offset_t)h, size);
+}
+
+void
+generic_bs_free(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size)
+{
+
+	panic("generic_bs_free(): not implemented");
+}
+
+int
+generic_bs_subregion(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t offset,
+    bus_size_t size, bus_space_handle_t *nbshp)
+{
+
+	*nbshp = bsh + offset;
+	return (0);
+}
+
+void
+generic_bs_barrier(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t offset,
+    bus_size_t len, int flags)
+{
+
+	/*
+	 * dsb() will drain the L1 write buffer and establish a memory access
+	 * barrier point on platforms where that has meaning.  On a write we
+	 * also need to drain the L2 write buffer, because most on-chip memory
+	 * mapped devices are downstream of the L2 cache.  Note that this needs
+	 * to be done even for memory mapped as Device type, because while
+	 * Device memory is not cached, writes to it are still buffered.
+	 */
+	dsb();
+	if (flags & BUS_SPACE_BARRIER_WRITE) {
+		cpu_l2cache_drain_writebuf();
+	}
+}


Property changes on: trunk/sys/arm/arm/bus_space_generic.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/busdma_machdep-v6.c
===================================================================
--- trunk/sys/arm/arm/busdma_machdep-v6.c	                        (rev 0)
+++ trunk/sys/arm/arm/busdma_machdep-v6.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,1734 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012-2014 Ian Lepore
+ * Copyright (c) 2010 Mark Tinguely
+ * Copyright (c) 2004 Olivier Houchard
+ * Copyright (c) 2002 Peter Grehan
+ * Copyright (c) 1997, 1998 Justin T. Gibbs.
+ * 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,
+ *    without modification, immediately at the beginning of the file.
+ * 2. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 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.
+ *
+ *  From i386/busdma_machdep.c 191438 2009-04-23 20:24:19Z jhb
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/busdma_machdep-v6.c 318977 2017-05-27 08:17:59Z hselasky $");
+
+#define _ARM32_BUS_DMA_PRIVATE
+#include <sys/param.h>
+#include <sys/kdb.h>
+#include <ddb/ddb.h>
+#include <ddb/db_output.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/bus.h>
+#include <sys/busdma_bufalloc.h>
+#include <sys/interrupt.h>
+#include <sys/kernel.h>
+#include <sys/ktr.h>
+#include <sys/lock.h>
+#include <sys/memdesc.h>
+#include <sys/proc.h>
+#include <sys/mutex.h>
+#include <sys/sysctl.h>
+#include <sys/uio.h>
+
+#include <vm/vm.h>
+#include <vm/vm_page.h>
+#include <vm/vm_map.h>
+#include <vm/vm_extern.h>
+#include <vm/vm_kern.h>
+
+#include <machine/atomic.h>
+#include <machine/bus.h>
+#include <machine/cpufunc.h>
+#include <machine/md_var.h>
+
+#define MAX_BPAGES 64
+#define MAX_DMA_SEGMENTS	4096
+#define BUS_DMA_EXCL_BOUNCE	BUS_DMA_BUS2
+#define BUS_DMA_ALIGN_BOUNCE	BUS_DMA_BUS3
+#define BUS_DMA_COULD_BOUNCE	(BUS_DMA_EXCL_BOUNCE | BUS_DMA_ALIGN_BOUNCE)
+#define BUS_DMA_MIN_ALLOC_COMP	BUS_DMA_BUS4
+
+struct bounce_zone;
+
+struct bus_dma_tag {
+	bus_dma_tag_t	  parent;
+	bus_size_t	  alignment;
+	bus_size_t	  boundary;
+	bus_addr_t	  lowaddr;
+	bus_addr_t	  highaddr;
+	bus_dma_filter_t *filter;
+	void		 *filterarg;
+	bus_size_t	  maxsize;
+	u_int		  nsegments;
+	bus_size_t	  maxsegsz;
+	int		  flags;
+	int		  ref_count;
+	int		  map_count;
+	bus_dma_lock_t	 *lockfunc;
+	void		 *lockfuncarg;
+	struct bounce_zone *bounce_zone;
+	/*
+	 * DMA range for this tag.  If the page doesn't fall within
+	 * one of these ranges, an error is returned.  The caller
+	 * may then decide what to do with the transfer.  If the
+	 * range pointer is NULL, it is ignored.
+	 */
+	struct arm32_dma_range	*ranges;
+	int			_nranges;
+};
+
+struct bounce_page {
+	vm_offset_t	vaddr;		/* kva of bounce buffer */
+	bus_addr_t	busaddr;	/* Physical address */
+	vm_offset_t	datavaddr;	/* kva of client data */
+	bus_addr_t	dataaddr;	/* client physical address */
+	bus_size_t	datacount;	/* client data count */
+	STAILQ_ENTRY(bounce_page) links;
+};
+
+struct sync_list {
+	vm_offset_t	vaddr;		/* kva of bounce buffer */
+	bus_addr_t	busaddr;	/* Physical address */
+	bus_size_t	datacount;	/* client data count */
+};
+
+int busdma_swi_pending;
+
+struct bounce_zone {
+	STAILQ_ENTRY(bounce_zone) links;
+	STAILQ_HEAD(bp_list, bounce_page) bounce_page_list;
+	int		total_bpages;
+	int		free_bpages;
+	int		reserved_bpages;
+	int		active_bpages;
+	int		total_bounced;
+	int		total_deferred;
+	int		map_count;
+	bus_size_t	alignment;
+	bus_addr_t	lowaddr;
+	char		zoneid[8];
+	char		lowaddrid[20];
+	struct sysctl_ctx_list sysctl_tree;
+	struct sysctl_oid *sysctl_tree_top;
+};
+
+static struct mtx bounce_lock;
+static int total_bpages;
+static int busdma_zonecount;
+static uint32_t tags_total;
+static uint32_t maps_total;
+static uint32_t maps_dmamem;
+static uint32_t maps_coherent;
+static uint64_t maploads_total;
+static uint64_t maploads_bounced;
+static uint64_t maploads_coherent;
+static uint64_t maploads_dmamem;
+static uint64_t maploads_mbuf;
+static uint64_t maploads_physmem;
+
+static STAILQ_HEAD(, bounce_zone) bounce_zone_list;
+
+SYSCTL_NODE(_hw, OID_AUTO, busdma, CTLFLAG_RD, 0, "Busdma parameters");
+SYSCTL_UINT(_hw_busdma, OID_AUTO, tags_total, CTLFLAG_RD, &tags_total, 0,
+	   "Number of active tags");
+SYSCTL_UINT(_hw_busdma, OID_AUTO, maps_total, CTLFLAG_RD, &maps_total, 0,
+	   "Number of active maps");
+SYSCTL_UINT(_hw_busdma, OID_AUTO, maps_dmamem, CTLFLAG_RD, &maps_dmamem, 0,
+	   "Number of active maps for bus_dmamem_alloc buffers");
+SYSCTL_UINT(_hw_busdma, OID_AUTO, maps_coherent, CTLFLAG_RD, &maps_coherent, 0,
+	   "Number of active maps with BUS_DMA_COHERENT flag set");
+SYSCTL_UQUAD(_hw_busdma, OID_AUTO, maploads_total, CTLFLAG_RD, &maploads_total, 0,
+	   "Number of load operations performed");
+SYSCTL_UQUAD(_hw_busdma, OID_AUTO, maploads_bounced, CTLFLAG_RD, &maploads_bounced, 0,
+	   "Number of load operations that used bounce buffers");
+SYSCTL_UQUAD(_hw_busdma, OID_AUTO, maploads_coherent, CTLFLAG_RD, &maploads_dmamem, 0,
+	   "Number of load operations on BUS_DMA_COHERENT memory");
+SYSCTL_UQUAD(_hw_busdma, OID_AUTO, maploads_dmamem, CTLFLAG_RD, &maploads_dmamem, 0,
+	   "Number of load operations on bus_dmamem_alloc buffers");
+SYSCTL_UQUAD(_hw_busdma, OID_AUTO, maploads_mbuf, CTLFLAG_RD, &maploads_mbuf, 0,
+	   "Number of load operations for mbufs");
+SYSCTL_UQUAD(_hw_busdma, OID_AUTO, maploads_physmem, CTLFLAG_RD, &maploads_physmem, 0,
+	   "Number of load operations on physical buffers");
+SYSCTL_INT(_hw_busdma, OID_AUTO, total_bpages, CTLFLAG_RD, &total_bpages, 0,
+	   "Total bounce pages");
+
+struct bus_dmamap {
+	struct bp_list	       bpages;
+	int		       pagesneeded;
+	int		       pagesreserved;
+	bus_dma_tag_t	       dmat;
+	struct memdesc	       mem;
+	pmap_t		       pmap;
+	bus_dmamap_callback_t *callback;
+	void		      *callback_arg;
+	int		      flags;
+#define DMAMAP_COHERENT		(1 << 0)
+#define DMAMAP_DMAMEM_ALLOC	(1 << 1)
+#define DMAMAP_MBUF		(1 << 2)
+	STAILQ_ENTRY(bus_dmamap) links;
+	bus_dma_segment_t	*segments;
+	int		       sync_count;
+	struct sync_list       slist[];
+};
+
+static STAILQ_HEAD(, bus_dmamap) bounce_map_waitinglist;
+static STAILQ_HEAD(, bus_dmamap) bounce_map_callbacklist;
+
+static void init_bounce_pages(void *dummy);
+static int alloc_bounce_zone(bus_dma_tag_t dmat);
+static int alloc_bounce_pages(bus_dma_tag_t dmat, u_int numpages);
+static int reserve_bounce_pages(bus_dma_tag_t dmat, bus_dmamap_t map,
+				int commit);
+static bus_addr_t add_bounce_page(bus_dma_tag_t dmat, bus_dmamap_t map,
+				  vm_offset_t vaddr, bus_addr_t addr,
+				  bus_size_t size);
+static void free_bounce_page(bus_dma_tag_t dmat, struct bounce_page *bpage);
+static void _bus_dmamap_count_pages(bus_dma_tag_t dmat, bus_dmamap_t map,
+    void *buf, bus_size_t buflen, int flags);
+static void _bus_dmamap_count_phys(bus_dma_tag_t dmat, bus_dmamap_t map,
+    vm_paddr_t buf, bus_size_t buflen, int flags);
+static int _bus_dmamap_reserve_pages(bus_dma_tag_t dmat, bus_dmamap_t map,
+    int flags);
+
+static busdma_bufalloc_t coherent_allocator;	/* Cache of coherent buffers */
+static busdma_bufalloc_t standard_allocator;	/* Cache of standard buffers */
+static void
+busdma_init(void *dummy)
+{
+	int uma_flags;
+
+	uma_flags = 0;
+
+	/* Create a cache of buffers in standard (cacheable) memory. */
+	standard_allocator = busdma_bufalloc_create("buffer", 
+	    arm_dcache_align,	/* minimum_alignment */
+	    NULL,		/* uma_alloc func */ 
+	    NULL,		/* uma_free func */
+	    uma_flags);		/* uma_zcreate_flags */
+
+#ifdef INVARIANTS
+	/* 
+	 * Force UMA zone to allocate service structures like
+	 * slabs using own allocator. uma_debug code performs
+	 * atomic ops on uma_slab_t fields and safety of this
+	 * operation is not guaranteed for write-back caches
+	 */
+	uma_flags = UMA_ZONE_OFFPAGE;
+#endif
+	/*
+	 * Create a cache of buffers in uncacheable memory, to implement the
+	 * BUS_DMA_COHERENT (and potentially BUS_DMA_NOCACHE) flag.
+	 */
+	coherent_allocator = busdma_bufalloc_create("coherent",
+	    arm_dcache_align,	/* minimum_alignment */
+	    busdma_bufalloc_alloc_uncacheable, 
+	    busdma_bufalloc_free_uncacheable, 
+	    uma_flags);	/* uma_zcreate_flags */
+}
+
+/*
+ * This init historically used SI_SUB_VM, but now the init code requires
+ * malloc(9) using M_DEVBUF memory, which is set up later than SI_SUB_VM, by
+ * SI_SUB_KMEM and SI_ORDER_SECOND, so we'll go right after that by using
+ * SI_SUB_KMEM and SI_ORDER_THIRD.
+ */
+SYSINIT(busdma, SI_SUB_KMEM, SI_ORDER_THIRD, busdma_init, NULL);
+
+static int
+exclusion_bounce_check(vm_offset_t lowaddr, vm_offset_t highaddr)
+{
+	int i;
+	for (i = 0; phys_avail[i] && phys_avail[i + 1]; i += 2) {
+		if ((lowaddr >= phys_avail[i] && lowaddr < phys_avail[i + 1]) ||
+		    (lowaddr < phys_avail[i] && highaddr >= phys_avail[i]))
+			return (1);
+	}
+	return (0);
+}
+
+/*
+ * Return true if the tag has an exclusion zone that could lead to bouncing.
+ */
+static __inline int
+exclusion_bounce(bus_dma_tag_t dmat)
+{
+
+	return (dmat->flags & BUS_DMA_EXCL_BOUNCE);
+}
+
+/*
+ * Return true if the given address does not fall on the alignment boundary.
+ */
+static __inline int
+alignment_bounce(bus_dma_tag_t dmat, bus_addr_t addr)
+{
+
+	return (addr & (dmat->alignment - 1));
+}
+
+/*
+ * Return true if the DMA should bounce because the start or end does not fall
+ * on a cacheline boundary (which would require a partial cacheline flush).
+ * COHERENT memory doesn't trigger cacheline flushes.  Memory allocated by
+ * bus_dmamem_alloc() is always aligned to cacheline boundaries, and there's a
+ * strict rule that such memory cannot be accessed by the CPU while DMA is in
+ * progress (or by multiple DMA engines at once), so that it's always safe to do
+ * full cacheline flushes even if that affects memory outside the range of a
+ * given DMA operation that doesn't involve the full allocated buffer.  If we're
+ * mapping an mbuf, that follows the same rules as a buffer we allocated.
+ */
+static __inline int
+cacheline_bounce(bus_dmamap_t map, bus_addr_t addr, bus_size_t size)
+{
+
+	if (map->flags & (DMAMAP_DMAMEM_ALLOC | DMAMAP_COHERENT | DMAMAP_MBUF))
+		return (0);
+	return ((addr | size) & arm_dcache_align_mask);
+}
+
+/*
+ * Return true if we might need to bounce the DMA described by addr and size.
+ *
+ * This is used to quick-check whether we need to do the more expensive work of
+ * checking the DMA page-by-page looking for alignment and exclusion bounces.
+ *
+ * Note that the addr argument might be either virtual or physical.  It doesn't
+ * matter because we only look at the low-order bits, which are the same in both
+ * address spaces.
+ */
+static __inline int
+might_bounce(bus_dma_tag_t dmat, bus_dmamap_t map, bus_addr_t addr, 
+    bus_size_t size)
+{
+
+	return ((dmat->flags & BUS_DMA_EXCL_BOUNCE) ||
+	    alignment_bounce(dmat, addr) ||
+	    cacheline_bounce(map, addr, size));
+}
+
+/*
+ * Return true if we must bounce the DMA described by paddr and size.
+ *
+ * Bouncing can be triggered by DMA that doesn't begin and end on cacheline
+ * boundaries, or doesn't begin on an alignment boundary, or falls within the
+ * exclusion zone of any tag in the ancestry chain.
+ *
+ * For exclusions, walk the chain of tags comparing paddr to the exclusion zone
+ * within each tag.  If the tag has a filter function, use it to decide whether
+ * the DMA needs to bounce, otherwise any DMA within the zone bounces.
+ */
+static int
+must_bounce(bus_dma_tag_t dmat, bus_dmamap_t map, bus_addr_t paddr, 
+    bus_size_t size)
+{
+
+	if (cacheline_bounce(map, paddr, size))
+		return (1);
+
+	/*
+	 *  The tag already contains ancestors' alignment restrictions so this
+	 *  check doesn't need to be inside the loop.
+	 */
+	if (alignment_bounce(dmat, paddr))
+		return (1);
+
+	/*
+	 * Even though each tag has an exclusion zone that is a superset of its
+	 * own and all its ancestors' exclusions, the exclusion zone of each tag
+	 * up the chain must be checked within the loop, because the busdma
+	 * rules say the filter function is called only when the address lies
+	 * within the low-highaddr range of the tag that filterfunc belongs to.
+	 */
+	while (dmat != NULL && exclusion_bounce(dmat)) {
+		if ((paddr >= dmat->lowaddr && paddr <= dmat->highaddr) &&
+		    (dmat->filter == NULL || 
+		    dmat->filter(dmat->filterarg, paddr) != 0))
+			return (1);
+		dmat = dmat->parent;
+	} 
+
+	return (0);
+}
+
+static __inline struct arm32_dma_range *
+_bus_dma_inrange(struct arm32_dma_range *ranges, int nranges,
+    bus_addr_t curaddr)
+{
+	struct arm32_dma_range *dr;
+	int i;
+
+	for (i = 0, dr = ranges; i < nranges; i++, dr++) {
+		if (curaddr >= dr->dr_sysbase &&
+		    round_page(curaddr) <= (dr->dr_sysbase + dr->dr_len))
+			return (dr);
+	}
+
+	return (NULL);
+}
+
+/*
+ * Convenience function for manipulating driver locks from busdma (during
+ * busdma_swi, for example).  Drivers that don't provide their own locks
+ * should specify &Giant to dmat->lockfuncarg.  Drivers that use their own
+ * non-mutex locking scheme don't have to use this at all.
+ */
+void
+busdma_lock_mutex(void *arg, bus_dma_lock_op_t op)
+{
+	struct mtx *dmtx;
+
+	dmtx = (struct mtx *)arg;
+	switch (op) {
+	case BUS_DMA_LOCK:
+		mtx_lock(dmtx);
+		break;
+	case BUS_DMA_UNLOCK:
+		mtx_unlock(dmtx);
+		break;
+	default:
+		panic("Unknown operation 0x%x for busdma_lock_mutex!", op);
+	}
+}
+
+/*
+ * dflt_lock should never get called.  It gets put into the dma tag when
+ * lockfunc == NULL, which is only valid if the maps that are associated
+ * with the tag are meant to never be defered.
+ * XXX Should have a way to identify which driver is responsible here.
+ */
+static void
+dflt_lock(void *arg, bus_dma_lock_op_t op)
+{
+
+	panic("driver error: busdma dflt_lock called");
+}
+
+/*
+ * Allocate a device specific dma_tag.
+ */
+int
+bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment,
+		   bus_size_t boundary, bus_addr_t lowaddr,
+		   bus_addr_t highaddr, bus_dma_filter_t *filter,
+		   void *filterarg, bus_size_t maxsize, int nsegments,
+		   bus_size_t maxsegsz, int flags, bus_dma_lock_t *lockfunc,
+		   void *lockfuncarg, bus_dma_tag_t *dmat)
+{
+	bus_dma_tag_t newtag;
+	int error = 0;
+
+#if 0
+	if (!parent)
+		parent = arm_root_dma_tag;
+#endif
+
+	/* Basic sanity checking */
+	if (boundary != 0 && boundary < maxsegsz)
+		maxsegsz = boundary;
+
+	/* Return a NULL tag on failure */
+	*dmat = NULL;
+
+	if (maxsegsz == 0) {
+		return (EINVAL);
+	}
+
+	newtag = (bus_dma_tag_t)malloc(sizeof(*newtag), M_DEVBUF,
+	    M_ZERO | M_NOWAIT);
+	if (newtag == NULL) {
+		CTR4(KTR_BUSDMA, "%s returned tag %p tag flags 0x%x error %d",
+		    __func__, newtag, 0, error);
+		return (ENOMEM);
+	}
+
+	newtag->parent = parent;
+	newtag->alignment = alignment;
+	newtag->boundary = boundary;
+	newtag->lowaddr = trunc_page((vm_paddr_t)lowaddr) + (PAGE_SIZE - 1);
+	newtag->highaddr = trunc_page((vm_paddr_t)highaddr) +
+	    (PAGE_SIZE - 1);
+	newtag->filter = filter;
+	newtag->filterarg = filterarg;
+	newtag->maxsize = maxsize;
+	newtag->nsegments = nsegments;
+	newtag->maxsegsz = maxsegsz;
+	newtag->flags = flags;
+	newtag->ref_count = 1; /* Count ourself */
+	newtag->map_count = 0;
+	newtag->ranges = bus_dma_get_range();
+	newtag->_nranges = bus_dma_get_range_nb();
+	if (lockfunc != NULL) {
+		newtag->lockfunc = lockfunc;
+		newtag->lockfuncarg = lockfuncarg;
+	} else {
+		newtag->lockfunc = dflt_lock;
+		newtag->lockfuncarg = NULL;
+	}
+
+	/* Take into account any restrictions imposed by our parent tag */
+	if (parent != NULL) {
+		newtag->lowaddr = MIN(parent->lowaddr, newtag->lowaddr);
+		newtag->highaddr = MAX(parent->highaddr, newtag->highaddr);
+		newtag->alignment = MAX(parent->alignment, newtag->alignment);
+		newtag->flags |= parent->flags & BUS_DMA_COULD_BOUNCE;
+		if (newtag->boundary == 0)
+			newtag->boundary = parent->boundary;
+		else if (parent->boundary != 0)
+			newtag->boundary = MIN(parent->boundary,
+					       newtag->boundary);
+		if (newtag->filter == NULL) {
+			/*
+			 * Short circuit to looking at our parent directly
+			 * since we have encapsulated all of its information
+			 */
+			newtag->filter = parent->filter;
+			newtag->filterarg = parent->filterarg;
+			newtag->parent = parent->parent;
+		}
+		if (newtag->parent != NULL)
+			atomic_add_int(&parent->ref_count, 1);
+	}
+
+	if (exclusion_bounce_check(newtag->lowaddr, newtag->highaddr))
+		newtag->flags |= BUS_DMA_EXCL_BOUNCE;
+	if (alignment_bounce(newtag, 1))
+		newtag->flags |= BUS_DMA_ALIGN_BOUNCE;
+
+	/*
+	 * Any request can auto-bounce due to cacheline alignment, in addition
+	 * to any alignment or boundary specifications in the tag, so if the
+	 * ALLOCNOW flag is set, there's always work to do.
+	 */
+	if ((flags & BUS_DMA_ALLOCNOW) != 0) {
+		struct bounce_zone *bz;
+		/*
+		 * Round size up to a full page, and add one more page because
+		 * there can always be one more boundary crossing than the
+		 * number of pages in a transfer.
+		 */
+		maxsize = roundup2(maxsize, PAGE_SIZE) + PAGE_SIZE;
+		
+		if ((error = alloc_bounce_zone(newtag)) != 0) {
+			free(newtag, M_DEVBUF);
+			return (error);
+		}
+		bz = newtag->bounce_zone;
+
+		if (ptoa(bz->total_bpages) < maxsize) {
+			int pages;
+
+			pages = atop(maxsize) - bz->total_bpages;
+
+			/* Add pages to our bounce pool */
+			if (alloc_bounce_pages(newtag, pages) < pages)
+				error = ENOMEM;
+		}
+		/* Performed initial allocation */
+		newtag->flags |= BUS_DMA_MIN_ALLOC_COMP;
+	} else
+		newtag->bounce_zone = NULL;
+
+	if (error != 0) {
+		free(newtag, M_DEVBUF);
+	} else {
+		atomic_add_32(&tags_total, 1);
+		*dmat = newtag;
+	}
+	CTR4(KTR_BUSDMA, "%s returned tag %p tag flags 0x%x error %d",
+	    __func__, newtag, (newtag != NULL ? newtag->flags : 0), error);
+	return (error);
+}
+
+int
+bus_dma_tag_destroy(bus_dma_tag_t dmat)
+{
+	bus_dma_tag_t dmat_copy;
+	int error;
+
+	error = 0;
+	dmat_copy = dmat;
+
+	if (dmat != NULL) {
+
+		if (dmat->map_count != 0) {
+			error = EBUSY;
+			goto out;
+		}
+
+		while (dmat != NULL) {
+			bus_dma_tag_t parent;
+
+			parent = dmat->parent;
+			atomic_subtract_int(&dmat->ref_count, 1);
+			if (dmat->ref_count == 0) {
+				atomic_subtract_32(&tags_total, 1);
+				free(dmat, M_DEVBUF);
+				/*
+				 * Last reference count, so
+				 * release our reference
+				 * count on our parent.
+				 */
+				dmat = parent;
+			} else
+				dmat = NULL;
+		}
+	}
+out:
+	CTR3(KTR_BUSDMA, "%s tag %p error %d", __func__, dmat_copy, error);
+	return (error);
+}
+
+static int allocate_bz_and_pages(bus_dma_tag_t dmat, bus_dmamap_t mapp)
+{
+	struct bounce_zone *bz;
+	int maxpages;
+	int error;
+		
+	if (dmat->bounce_zone == NULL)
+		if ((error = alloc_bounce_zone(dmat)) != 0)
+			return (error);
+	bz = dmat->bounce_zone;
+	/* Initialize the new map */
+	STAILQ_INIT(&(mapp->bpages));
+
+	/*
+	 * Attempt to add pages to our pool on a per-instance basis up to a sane
+	 * limit.  Even if the tag isn't flagged as COULD_BOUNCE due to
+	 * alignment and boundary constraints, it could still auto-bounce due to
+	 * cacheline alignment, which requires at most two bounce pages.
+	 */
+	if (dmat->flags & BUS_DMA_COULD_BOUNCE)
+		maxpages = MAX_BPAGES;
+	else
+		maxpages = 2 * bz->map_count;
+	if ((dmat->flags & BUS_DMA_MIN_ALLOC_COMP) == 0 ||
+	    (bz->map_count > 0 && bz->total_bpages < maxpages)) {
+		int pages;
+		
+		pages = atop(roundup2(dmat->maxsize, PAGE_SIZE)) + 1;
+		pages = MIN(maxpages - bz->total_bpages, pages);
+		pages = MAX(pages, 2);
+		if (alloc_bounce_pages(dmat, pages) < pages)
+			return (ENOMEM);
+		
+		if ((dmat->flags & BUS_DMA_MIN_ALLOC_COMP) == 0)
+			dmat->flags |= BUS_DMA_MIN_ALLOC_COMP;
+	}
+	bz->map_count++;
+	return (0);
+}
+
+static bus_dmamap_t
+allocate_map(bus_dma_tag_t dmat, int mflags)
+{
+	int mapsize, segsize;
+	bus_dmamap_t map;
+
+	/*
+	 * Allocate the map.  The map structure ends with an embedded
+	 * variable-sized array of sync_list structures.  Following that
+	 * we allocate enough extra space to hold the array of bus_dma_segments.
+	 */
+	KASSERT(dmat->nsegments <= MAX_DMA_SEGMENTS, 
+	   ("cannot allocate %u dma segments (max is %u)",
+	    dmat->nsegments, MAX_DMA_SEGMENTS));
+	segsize = sizeof(struct bus_dma_segment) * dmat->nsegments;
+	mapsize = sizeof(*map) + sizeof(struct sync_list) * dmat->nsegments;
+	map = malloc(mapsize + segsize, M_DEVBUF, mflags | M_ZERO);
+	if (map == NULL) {
+		CTR3(KTR_BUSDMA, "%s: tag %p error %d", __func__, dmat, ENOMEM);
+		return (NULL);
+	}
+	map->segments = (bus_dma_segment_t *)((uintptr_t)map + mapsize);
+	return (map);
+}
+
+/*
+ * Allocate a handle for mapping from kva/uva/physical
+ * address space into bus device space.
+ */
+int
+bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp)
+{
+	bus_dmamap_t map;
+	int error = 0;
+
+	*mapp = map = allocate_map(dmat, M_NOWAIT);
+	if (map == NULL) {
+		CTR3(KTR_BUSDMA, "%s: tag %p error %d", __func__, dmat, ENOMEM);
+		return (ENOMEM);
+	}
+
+	/*
+	 * Bouncing might be required if the driver asks for an exclusion
+	 * region, a data alignment that is stricter than 1, or DMA that begins
+	 * or ends with a partial cacheline.  Whether bouncing will actually
+	 * happen can't be known until mapping time, but we need to pre-allocate
+	 * resources now because we might not be allowed to at mapping time.
+	 */
+	error = allocate_bz_and_pages(dmat, map);
+	if (error != 0) {
+		free(map, M_DEVBUF);
+		*mapp = NULL;
+		return (error);
+	}
+	if (map->flags & DMAMAP_COHERENT)
+		atomic_add_32(&maps_coherent, 1);
+	atomic_add_32(&maps_total, 1);
+	dmat->map_count++;
+
+	return (0);
+}
+
+/*
+ * Destroy a handle for mapping from kva/uva/physical
+ * address space into bus device space.
+ */
+int
+bus_dmamap_destroy(bus_dma_tag_t dmat, bus_dmamap_t map)
+{
+	if (STAILQ_FIRST(&map->bpages) != NULL || map->sync_count != 0) {
+		CTR3(KTR_BUSDMA, "%s: tag %p error %d",
+		    __func__, dmat, EBUSY);
+		return (EBUSY);
+	}
+	if (dmat->bounce_zone)
+		dmat->bounce_zone->map_count--;
+	if (map->flags & DMAMAP_COHERENT)
+		atomic_subtract_32(&maps_coherent, 1);
+	atomic_subtract_32(&maps_total, 1);
+	free(map, M_DEVBUF);
+	dmat->map_count--;
+	CTR2(KTR_BUSDMA, "%s: tag %p error 0", __func__, dmat);
+	return (0);
+}
+
+
+/*
+ * Allocate a piece of memory that can be efficiently mapped into
+ * bus device space based on the constraints lited in the dma tag.
+ * A dmamap to for use with dmamap_load is also allocated.
+ */
+int
+bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags,
+		 bus_dmamap_t *mapp)
+{
+	busdma_bufalloc_t ba;
+	struct busdma_bufzone *bufzone;
+	bus_dmamap_t map;
+	vm_memattr_t memattr;
+	int mflags;
+
+	if (flags & BUS_DMA_NOWAIT)
+		mflags = M_NOWAIT;
+	else
+		mflags = M_WAITOK;
+	if (flags & BUS_DMA_ZERO)
+		mflags |= M_ZERO;
+
+	*mapp = map = allocate_map(dmat, mflags);
+	if (map == NULL) {
+		CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d",
+		    __func__, dmat, dmat->flags, ENOMEM);
+		return (ENOMEM);
+	}
+	map->flags = DMAMAP_DMAMEM_ALLOC;
+
+	/* Choose a busdma buffer allocator based on memory type flags. */
+	if (flags & BUS_DMA_COHERENT) {
+		memattr = VM_MEMATTR_UNCACHEABLE;
+		ba = coherent_allocator;
+		map->flags |= DMAMAP_COHERENT;
+	} else {
+		memattr = VM_MEMATTR_DEFAULT;
+		ba = standard_allocator;
+	}
+
+	/*
+	 * Try to find a bufzone in the allocator that holds a cache of buffers
+	 * of the right size for this request.  If the buffer is too big to be
+	 * held in the allocator cache, this returns NULL.
+	 */
+	bufzone = busdma_bufalloc_findzone(ba, dmat->maxsize);
+
+	/*
+	 * Allocate the buffer from the uma(9) allocator if...
+	 *  - It's small enough to be in the allocator (bufzone not NULL).
+	 *  - The alignment constraint isn't larger than the allocation size
+	 *    (the allocator aligns buffers to their size boundaries).
+	 *  - There's no need to handle lowaddr/highaddr exclusion zones.
+	 * else allocate non-contiguous pages if...
+	 *  - The page count that could get allocated doesn't exceed
+	 *    nsegments also when the maximum segment size is less
+	 *    than PAGE_SIZE.
+	 *  - The alignment constraint isn't larger than a page boundary.
+	 *  - There are no boundary-crossing constraints.
+	 * else allocate a block of contiguous pages because one or more of the
+	 * constraints is something that only the contig allocator can fulfill.
+	 */
+	if (bufzone != NULL && dmat->alignment <= bufzone->size &&
+	    !exclusion_bounce(dmat)) {
+		*vaddr = uma_zalloc(bufzone->umazone, mflags);
+	} else if (dmat->nsegments >=
+	    howmany(dmat->maxsize, MIN(dmat->maxsegsz, PAGE_SIZE)) &&
+	    dmat->alignment <= PAGE_SIZE &&
+	    (dmat->boundary % PAGE_SIZE) == 0) {
+		*vaddr = (void *)kmem_alloc_attr(kernel_arena, dmat->maxsize,
+		    mflags, 0, dmat->lowaddr, memattr);
+	} else {
+		*vaddr = (void *)kmem_alloc_contig(kernel_arena, dmat->maxsize,
+		    mflags, 0, dmat->lowaddr, dmat->alignment, dmat->boundary,
+		    memattr);
+	}
+
+
+	if (*vaddr == NULL) {
+		CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d",
+		    __func__, dmat, dmat->flags, ENOMEM);
+		free(map, M_DEVBUF);
+		*mapp = NULL;
+		return (ENOMEM);
+	} else if ((uintptr_t)*vaddr & (dmat->alignment - 1)) {
+		printf("bus_dmamem_alloc failed to align memory properly.\n");
+	}
+	if (map->flags & DMAMAP_COHERENT)
+		atomic_add_32(&maps_coherent, 1);
+	atomic_add_32(&maps_dmamem, 1);
+	atomic_add_32(&maps_total, 1);
+	dmat->map_count++;
+
+	CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d",
+	    __func__, dmat, dmat->flags, 0);
+	return (0);
+}
+
+/*
+ * Free a piece of memory and it's allociated dmamap, that was allocated
+ * via bus_dmamem_alloc.  Make the same choice for free/contigfree.
+ */
+void
+bus_dmamem_free(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map)
+{
+	struct busdma_bufzone *bufzone;
+	busdma_bufalloc_t ba;
+
+	if (map->flags & DMAMAP_COHERENT)
+		ba = coherent_allocator;
+	else
+		ba = standard_allocator;
+
+	bufzone = busdma_bufalloc_findzone(ba, dmat->maxsize);
+
+	if (bufzone != NULL && dmat->alignment <= bufzone->size &&
+	    !exclusion_bounce(dmat))
+		uma_zfree(bufzone->umazone, vaddr);
+	else
+		kmem_free(kernel_arena, (vm_offset_t)vaddr, dmat->maxsize);
+
+	dmat->map_count--;
+	if (map->flags & DMAMAP_COHERENT)
+		atomic_subtract_32(&maps_coherent, 1);
+	atomic_subtract_32(&maps_total, 1);
+	atomic_subtract_32(&maps_dmamem, 1);
+	free(map, M_DEVBUF);
+	CTR3(KTR_BUSDMA, "%s: tag %p flags 0x%x", __func__, dmat, dmat->flags);
+}
+
+static void
+_bus_dmamap_count_phys(bus_dma_tag_t dmat, bus_dmamap_t map, vm_paddr_t buf,
+    bus_size_t buflen, int flags)
+{
+	bus_addr_t curaddr;
+	bus_size_t sgsize;
+
+	if (map->pagesneeded == 0) {
+		CTR5(KTR_BUSDMA, "lowaddr= %d, boundary= %d, alignment= %d"
+		    " map= %p, pagesneeded= %d",
+		    dmat->lowaddr, dmat->boundary, dmat->alignment,
+		    map, map->pagesneeded);
+		/*
+		 * Count the number of bounce pages
+		 * needed in order to complete this transfer
+		 */
+		curaddr = buf;
+		while (buflen != 0) {
+			sgsize = MIN(buflen, dmat->maxsegsz);
+			if (must_bounce(dmat, map, curaddr, sgsize) != 0) {
+				sgsize = MIN(sgsize, PAGE_SIZE);
+				map->pagesneeded++;
+			}
+			curaddr += sgsize;
+			buflen -= sgsize;
+		}
+		CTR1(KTR_BUSDMA, "pagesneeded= %d", map->pagesneeded);
+	}
+}
+
+static void
+_bus_dmamap_count_pages(bus_dma_tag_t dmat, bus_dmamap_t map,
+    void *buf, bus_size_t buflen, int flags)
+{
+	vm_offset_t vaddr;
+	vm_offset_t vendaddr;
+	bus_addr_t paddr;
+
+	if (map->pagesneeded == 0) {
+		CTR5(KTR_BUSDMA, "lowaddr= %d, boundary= %d, alignment= %d"
+		    " map= %p, pagesneeded= %d",
+		    dmat->lowaddr, dmat->boundary, dmat->alignment,
+		    map, map->pagesneeded);
+		/*
+		 * Count the number of bounce pages
+		 * needed in order to complete this transfer
+		 */
+		vaddr = (vm_offset_t)buf;
+		vendaddr = (vm_offset_t)buf + buflen;
+
+		while (vaddr < vendaddr) {
+			if (__predict_true(map->pmap == kernel_pmap))
+				paddr = pmap_kextract(vaddr);
+			else
+				paddr = pmap_extract(map->pmap, vaddr);
+			if (must_bounce(dmat, map, paddr,
+			    min(vendaddr - vaddr, (PAGE_SIZE - ((vm_offset_t)vaddr & 
+			    PAGE_MASK)))) != 0) {
+				map->pagesneeded++;
+			}
+			vaddr += (PAGE_SIZE - ((vm_offset_t)vaddr & PAGE_MASK));
+
+		}
+		CTR1(KTR_BUSDMA, "pagesneeded= %d", map->pagesneeded);
+	}
+}
+
+static int
+_bus_dmamap_reserve_pages(bus_dma_tag_t dmat, bus_dmamap_t map, int flags)
+{
+
+	/* Reserve Necessary Bounce Pages */
+	mtx_lock(&bounce_lock);
+	if (flags & BUS_DMA_NOWAIT) {
+		if (reserve_bounce_pages(dmat, map, 0) != 0) {
+			map->pagesneeded = 0;
+			mtx_unlock(&bounce_lock);
+			return (ENOMEM);
+		}
+	} else {
+		if (reserve_bounce_pages(dmat, map, 1) != 0) {
+			/* Queue us for resources */
+			STAILQ_INSERT_TAIL(&bounce_map_waitinglist, map, links);
+			mtx_unlock(&bounce_lock);
+			return (EINPROGRESS);
+		}
+	}
+	mtx_unlock(&bounce_lock);
+
+	return (0);
+}
+
+/*
+ * Add a single contiguous physical range to the segment list.
+ */
+static int
+_bus_dmamap_addseg(bus_dma_tag_t dmat, bus_dmamap_t map, bus_addr_t curaddr,
+		   bus_size_t sgsize, bus_dma_segment_t *segs, int *segp)
+{
+	bus_addr_t baddr, bmask;
+	int seg;
+
+	/*
+	 * Make sure we don't cross any boundaries.
+	 */
+	bmask = ~(dmat->boundary - 1);
+	if (dmat->boundary > 0) {
+		baddr = (curaddr + dmat->boundary) & bmask;
+		if (sgsize > (baddr - curaddr))
+			sgsize = (baddr - curaddr);
+	}
+
+	if (dmat->ranges) {
+		struct arm32_dma_range *dr;
+
+		dr = _bus_dma_inrange(dmat->ranges, dmat->_nranges,
+		    curaddr);
+		if (dr == NULL) {
+			_bus_dmamap_unload(dmat, map);
+			return (0);
+		}
+		/*
+		 * In a valid DMA range.  Translate the physical
+		 * memory address to an address in the DMA window.
+		 */
+		curaddr = (curaddr - dr->dr_sysbase) + dr->dr_busbase;
+	}
+
+	/*
+	 * Insert chunk into a segment, coalescing with
+	 * previous segment if possible.
+	 */
+	seg = *segp;
+	if (seg == -1) {
+		seg = 0;
+		segs[seg].ds_addr = curaddr;
+		segs[seg].ds_len = sgsize;
+	} else {
+		if (curaddr == segs[seg].ds_addr + segs[seg].ds_len &&
+		    (segs[seg].ds_len + sgsize) <= dmat->maxsegsz &&
+		    (dmat->boundary == 0 ||
+		     (segs[seg].ds_addr & bmask) == (curaddr & bmask)))
+			segs[seg].ds_len += sgsize;
+		else {
+			if (++seg >= dmat->nsegments)
+				return (0);
+			segs[seg].ds_addr = curaddr;
+			segs[seg].ds_len = sgsize;
+		}
+	}
+	*segp = seg;
+	return (sgsize);
+}
+
+/*
+ * Utility function to load a physical buffer.  segp contains
+ * the starting segment on entrace, and the ending segment on exit.
+ */
+int
+_bus_dmamap_load_phys(bus_dma_tag_t dmat,
+		      bus_dmamap_t map,
+		      vm_paddr_t buf, bus_size_t buflen,
+		      int flags,
+		      bus_dma_segment_t *segs,
+		      int *segp)
+{
+	bus_addr_t curaddr;
+	bus_size_t sgsize;
+	int error;
+
+	if (segs == NULL)
+		segs = map->segments;
+
+	maploads_total++;
+	maploads_physmem++;
+
+	if (might_bounce(dmat, map, buflen, buflen)) {
+		_bus_dmamap_count_phys(dmat, map, buf, buflen, flags);
+		if (map->pagesneeded != 0) {
+			maploads_bounced++;
+			error = _bus_dmamap_reserve_pages(dmat, map, flags);
+			if (error)
+				return (error);
+		}
+	}
+
+	while (buflen > 0) {
+		curaddr = buf;
+		sgsize = MIN(buflen, dmat->maxsegsz);
+		if (map->pagesneeded != 0 && must_bounce(dmat, map, curaddr,
+		    sgsize)) {
+			sgsize = MIN(sgsize, PAGE_SIZE);
+			curaddr = add_bounce_page(dmat, map, 0, curaddr,
+						  sgsize);
+		}
+		sgsize = _bus_dmamap_addseg(dmat, map, curaddr, sgsize, segs,
+		    segp);
+		if (sgsize == 0)
+			break;
+		buf += sgsize;
+		buflen -= sgsize;
+	}
+
+	/*
+	 * Did we fit?
+	 */
+	if (buflen != 0) {
+		_bus_dmamap_unload(dmat, map);
+		return (EFBIG); /* XXX better return value here? */
+	}
+	return (0);
+}
+
+int
+_bus_dmamap_load_ma(bus_dma_tag_t dmat, bus_dmamap_t map,
+    struct vm_page **ma, bus_size_t tlen, int ma_offs, int flags,
+    bus_dma_segment_t *segs, int *segp)
+{
+
+	return (bus_dmamap_load_ma_triv(dmat, map, ma, tlen, ma_offs, flags,
+	    segs, segp));
+}
+
+/*
+ * Utility function to load a linear buffer.  segp contains
+ * the starting segment on entrace, and the ending segment on exit.
+ */
+int
+_bus_dmamap_load_buffer(bus_dma_tag_t dmat,
+			bus_dmamap_t map,
+			void *buf, bus_size_t buflen,
+			pmap_t pmap,
+			int flags,
+			bus_dma_segment_t *segs,
+			int *segp)
+{
+	bus_size_t sgsize;
+	bus_addr_t curaddr;
+	vm_offset_t vaddr;
+	struct sync_list *sl;
+	int error;
+
+	maploads_total++;
+	if (map->flags & DMAMAP_COHERENT)
+		maploads_coherent++;
+	if (map->flags & DMAMAP_DMAMEM_ALLOC)
+		maploads_dmamem++;
+
+	if (segs == NULL)
+		segs = map->segments;
+
+	if (flags & BUS_DMA_LOAD_MBUF) {
+		maploads_mbuf++;
+		map->flags |= DMAMAP_MBUF;
+	}
+
+	map->pmap = pmap;
+
+	if (might_bounce(dmat, map, (bus_addr_t)buf, buflen)) {
+		_bus_dmamap_count_pages(dmat, map, buf, buflen, flags);
+		if (map->pagesneeded != 0) {
+			maploads_bounced++;
+			error = _bus_dmamap_reserve_pages(dmat, map, flags);
+			if (error)
+				return (error);
+		}
+	}
+
+	sl = NULL;
+	vaddr = (vm_offset_t)buf;
+
+	while (buflen > 0) {
+		/*
+		 * Get the physical address for this segment.
+		 */
+		if (__predict_true(map->pmap == kernel_pmap))
+			curaddr = pmap_kextract(vaddr);
+		else
+			curaddr = pmap_extract(map->pmap, vaddr);
+
+		/*
+		 * Compute the segment size, and adjust counts.
+		 */
+		sgsize = PAGE_SIZE - ((u_long)curaddr & PAGE_MASK);
+		if (sgsize > dmat->maxsegsz)
+			sgsize = dmat->maxsegsz;
+		if (buflen < sgsize)
+			sgsize = buflen;
+
+		if (map->pagesneeded != 0 && must_bounce(dmat, map, curaddr,
+		    sgsize)) {
+			curaddr = add_bounce_page(dmat, map, vaddr, curaddr,
+						  sgsize);
+		} else {
+			sl = &map->slist[map->sync_count - 1];
+			if (map->sync_count == 0 ||
+#ifdef ARM_L2_PIPT
+			    curaddr != sl->busaddr + sl->datacount ||
+#endif
+			    vaddr != sl->vaddr + sl->datacount) {
+				if (++map->sync_count > dmat->nsegments)
+					goto cleanup;
+				sl++;
+				sl->vaddr = vaddr;
+				sl->datacount = sgsize;
+				sl->busaddr = curaddr;
+			} else
+				sl->datacount += sgsize;
+		}
+		sgsize = _bus_dmamap_addseg(dmat, map, curaddr, sgsize, segs,
+					    segp);
+		if (sgsize == 0)
+			break;
+		vaddr += sgsize;
+		buflen -= sgsize;
+	}
+
+cleanup:
+	/*
+	 * Did we fit?
+	 */
+	if (buflen != 0) {
+		_bus_dmamap_unload(dmat, map);
+		return (EFBIG); /* XXX better return value here? */
+	}
+	return (0);
+}
+
+
+void
+__bus_dmamap_waitok(bus_dma_tag_t dmat, bus_dmamap_t map,
+		    struct memdesc *mem, bus_dmamap_callback_t *callback,
+		    void *callback_arg)
+{
+
+	map->mem = *mem;
+	map->dmat = dmat;
+	map->callback = callback;
+	map->callback_arg = callback_arg;
+}
+
+bus_dma_segment_t *
+_bus_dmamap_complete(bus_dma_tag_t dmat, bus_dmamap_t map,
+		     bus_dma_segment_t *segs, int nsegs, int error)
+{
+
+	if (segs == NULL)
+		segs = map->segments;
+	return (segs);
+}
+
+/*
+ * Release the mapping held by map.
+ */
+void
+_bus_dmamap_unload(bus_dma_tag_t dmat, bus_dmamap_t map)
+{
+	struct bounce_page *bpage;
+	struct bounce_zone *bz;
+
+	if ((bz = dmat->bounce_zone) != NULL) {
+		while ((bpage = STAILQ_FIRST(&map->bpages)) != NULL) {
+			STAILQ_REMOVE_HEAD(&map->bpages, links);
+			free_bounce_page(dmat, bpage);
+		}
+
+		bz = dmat->bounce_zone;
+		bz->free_bpages += map->pagesreserved;
+		bz->reserved_bpages -= map->pagesreserved;
+		map->pagesreserved = 0;
+		map->pagesneeded = 0;
+	}
+	map->sync_count = 0;
+	map->flags &= ~DMAMAP_MBUF;
+}
+
+#ifdef notyetbounceuser
+/* If busdma uses user pages, then the interrupt handler could
+ * be use the kernel vm mapping. Both bounce pages and sync list
+ * do not cross page boundaries.
+ * Below is a rough sequence that a person would do to fix the
+ * user page reference in the kernel vmspace. This would be
+ * done in the dma post routine.
+ */
+void
+_bus_dmamap_fix_user(vm_offset_t buf, bus_size_t len,
+			pmap_t pmap, int op)
+{
+	bus_size_t sgsize;
+	bus_addr_t curaddr;
+	vm_offset_t va;
+
+	/* 
+	 * each synclist entry is contained within a single page.
+	 * this would be needed if BUS_DMASYNC_POSTxxxx was implemented
+	 */
+	curaddr = pmap_extract(pmap, buf);
+	va = pmap_dma_map(curaddr);
+	switch (op) {
+	case SYNC_USER_INV:
+		cpu_dcache_wb_range(va, sgsize);
+		break;
+
+	case SYNC_USER_COPYTO:
+		bcopy((void *)va, (void *)bounce, sgsize);
+		break;
+
+	case SYNC_USER_COPYFROM:
+		bcopy((void *) bounce, (void *)va, sgsize);
+		break;
+
+	default:
+		break;
+	}
+
+	pmap_dma_unmap(va);
+}
+#endif
+
+#ifdef ARM_L2_PIPT
+#define l2cache_wb_range(va, pa, size) cpu_l2cache_wb_range(pa, size)
+#define l2cache_wbinv_range(va, pa, size) cpu_l2cache_wbinv_range(pa, size)
+#define l2cache_inv_range(va, pa, size) cpu_l2cache_inv_range(pa, size)
+#else
+#define l2cache_wb_range(va, pa, size) cpu_l2cache_wb_range(va, size)
+#define l2cache_wbinv_range(va, pa, size) cpu_l2cache_wbinv_range(va, size)
+#define l2cache_inv_range(va, pa, size) cpu_l2cache_inv_range(va, size)
+#endif
+
+void
+_bus_dmamap_sync(bus_dma_tag_t dmat, bus_dmamap_t map, bus_dmasync_op_t op)
+{
+	struct bounce_page *bpage;
+	struct sync_list *sl, *end;
+	/*
+	 * If the buffer was from user space, it is possible that this is not
+	 * the same vm map, especially on a POST operation.  It's not clear that
+	 * dma on userland buffers can work at all right now.  To be safe, until
+	 * we're able to test direct userland dma, panic on a map mismatch.
+	 */
+	if ((bpage = STAILQ_FIRST(&map->bpages)) != NULL) {
+		if (!pmap_dmap_iscurrent(map->pmap))
+			panic("_bus_dmamap_sync: wrong user map for bounce sync.");
+
+		CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x op 0x%x "
+		    "performing bounce", __func__, dmat, dmat->flags, op);
+
+		/*
+		 * For PREWRITE do a writeback.  Clean the caches from the
+		 * innermost to the outermost levels.
+		 */
+		if (op & BUS_DMASYNC_PREWRITE) {
+			while (bpage != NULL) {
+				if (bpage->datavaddr != 0)
+					bcopy((void *)bpage->datavaddr,
+					    (void *)bpage->vaddr,
+					    bpage->datacount);
+				else
+					physcopyout(bpage->dataaddr,
+					    (void *)bpage->vaddr,
+					    bpage->datacount);
+				cpu_dcache_wb_range((vm_offset_t)bpage->vaddr,
+				    bpage->datacount);
+				l2cache_wb_range((vm_offset_t)bpage->vaddr,
+				    (vm_offset_t)bpage->busaddr, 
+				    bpage->datacount);
+				bpage = STAILQ_NEXT(bpage, links);
+			}
+			dmat->bounce_zone->total_bounced++;
+		}
+
+		/*
+		 * Do an invalidate for PREREAD unless a writeback was already
+		 * done above due to PREWRITE also being set.  The reason for a
+		 * PREREAD invalidate is to prevent dirty lines currently in the
+		 * cache from being evicted during the DMA.  If a writeback was
+		 * done due to PREWRITE also being set there will be no dirty
+		 * lines and the POSTREAD invalidate handles the rest. The
+		 * invalidate is done from the innermost to outermost level. If
+		 * L2 were done first, a dirty cacheline could be automatically
+		 * evicted from L1 before we invalidated it, re-dirtying the L2.
+		 */
+		if ((op & BUS_DMASYNC_PREREAD) && !(op & BUS_DMASYNC_PREWRITE)) {
+			bpage = STAILQ_FIRST(&map->bpages);
+			while (bpage != NULL) {
+				cpu_dcache_inv_range((vm_offset_t)bpage->vaddr,
+				    bpage->datacount);
+				l2cache_inv_range((vm_offset_t)bpage->vaddr,
+				    (vm_offset_t)bpage->busaddr,
+				    bpage->datacount);
+				bpage = STAILQ_NEXT(bpage, links);
+			}
+		}
+
+		/*
+		 * Re-invalidate the caches on a POSTREAD, even though they were
+		 * already invalidated at PREREAD time.  Aggressive prefetching
+		 * due to accesses to other data near the dma buffer could have
+		 * brought buffer data into the caches which is now stale.  The
+		 * caches are invalidated from the outermost to innermost; the
+		 * prefetches could be happening right now, and if L1 were
+		 * invalidated first, stale L2 data could be prefetched into L1.
+		 */
+		if (op & BUS_DMASYNC_POSTREAD) {
+			while (bpage != NULL) {
+				vm_offset_t startv;
+				vm_paddr_t startp;
+				int len;
+
+				startv = bpage->vaddr &~ arm_dcache_align_mask;
+				startp = bpage->busaddr &~ arm_dcache_align_mask;
+				len = bpage->datacount;
+				
+				if (startv != bpage->vaddr)
+					len += bpage->vaddr & arm_dcache_align_mask;
+				if (len & arm_dcache_align_mask) 
+					len = (len -
+					    (len & arm_dcache_align_mask)) +
+					    arm_dcache_align;
+				l2cache_inv_range(startv, startp, len);
+				cpu_dcache_inv_range(startv, len);
+				if (bpage->datavaddr != 0)
+					bcopy((void *)bpage->vaddr,
+					    (void *)bpage->datavaddr,
+					    bpage->datacount);
+				else
+					physcopyin((void *)bpage->vaddr,
+					    bpage->dataaddr,
+					    bpage->datacount);
+				bpage = STAILQ_NEXT(bpage, links);
+			}
+			dmat->bounce_zone->total_bounced++;
+		}
+	}
+
+	/*
+	 * For COHERENT memory no cache maintenance is necessary, but ensure all
+	 * writes have reached memory for the PREWRITE case.  No action is
+	 * needed for a PREREAD without PREWRITE also set, because that would
+	 * imply that the cpu had written to the COHERENT buffer and expected
+	 * the dma device to see that change, and by definition a PREWRITE sync
+	 * is required to make that happen.
+	 */
+	if (map->flags & DMAMAP_COHERENT) {
+		if (op & BUS_DMASYNC_PREWRITE) {
+			dsb();
+			cpu_l2cache_drain_writebuf();
+		}
+		return;
+	}
+
+	/*
+	 * Cache maintenance for normal (non-COHERENT non-bounce) buffers.  All
+	 * the comments about the sequences for flushing cache levels in the
+	 * bounce buffer code above apply here as well.  In particular, the fact
+	 * that the sequence is inner-to-outer for PREREAD invalidation and
+	 * outer-to-inner for POSTREAD invalidation is not a mistake.
+	 */
+	if (map->sync_count != 0) {
+		if (!pmap_dmap_iscurrent(map->pmap))
+			panic("_bus_dmamap_sync: wrong user map for sync.");
+
+		sl = &map->slist[0];
+		end = &map->slist[map->sync_count];
+		CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x op 0x%x "
+		    "performing sync", __func__, dmat, dmat->flags, op);
+
+		switch (op) {
+		case BUS_DMASYNC_PREWRITE:
+		case BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD:
+			while (sl != end) {
+				cpu_dcache_wb_range(sl->vaddr, sl->datacount);
+				l2cache_wb_range(sl->vaddr, sl->busaddr,
+				    sl->datacount);
+				sl++;
+			}
+			break;
+
+		case BUS_DMASYNC_PREREAD:
+			/*
+			 * An mbuf may start in the middle of a cacheline. There
+			 * will be no cpu writes to the beginning of that line
+			 * (which contains the mbuf header) while dma is in
+			 * progress.  Handle that case by doing a writeback of
+			 * just the first cacheline before invalidating the
+			 * overall buffer.  Any mbuf in a chain may have this
+			 * misalignment.  Buffers which are not mbufs bounce if
+			 * they are not aligned to a cacheline.
+			 */
+			while (sl != end) {
+				if (sl->vaddr & arm_dcache_align_mask) {
+					KASSERT(map->flags & DMAMAP_MBUF,
+					    ("unaligned buffer is not an mbuf"));
+					cpu_dcache_wb_range(sl->vaddr, 1);
+					l2cache_wb_range(sl->vaddr,
+					    sl->busaddr, 1);
+				}
+				cpu_dcache_inv_range(sl->vaddr, sl->datacount);
+				l2cache_inv_range(sl->vaddr, sl->busaddr, 
+				    sl->datacount);
+				sl++;
+			}
+			break;
+
+		case BUS_DMASYNC_POSTWRITE:
+			break;
+
+		case BUS_DMASYNC_POSTREAD:
+		case BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE:
+			while (sl != end) {
+				l2cache_inv_range(sl->vaddr, sl->busaddr, 
+				    sl->datacount);
+				cpu_dcache_inv_range(sl->vaddr, sl->datacount);
+				sl++;
+			}
+			break;
+
+		default:
+			panic("unsupported combination of sync operations: 0x%08x\n", op);
+			break;
+		}
+	}
+}
+
+static void
+init_bounce_pages(void *dummy __unused)
+{
+
+	total_bpages = 0;
+	STAILQ_INIT(&bounce_zone_list);
+	STAILQ_INIT(&bounce_map_waitinglist);
+	STAILQ_INIT(&bounce_map_callbacklist);
+	mtx_init(&bounce_lock, "bounce pages lock", NULL, MTX_DEF);
+}
+SYSINIT(bpages, SI_SUB_LOCK, SI_ORDER_ANY, init_bounce_pages, NULL);
+
+static struct sysctl_ctx_list *
+busdma_sysctl_tree(struct bounce_zone *bz)
+{
+
+	return (&bz->sysctl_tree);
+}
+
+static struct sysctl_oid *
+busdma_sysctl_tree_top(struct bounce_zone *bz)
+{
+
+	return (bz->sysctl_tree_top);
+}
+
+static int
+alloc_bounce_zone(bus_dma_tag_t dmat)
+{
+	struct bounce_zone *bz;
+
+	/* Check to see if we already have a suitable zone */
+	STAILQ_FOREACH(bz, &bounce_zone_list, links) {
+		if ((dmat->alignment <= bz->alignment) &&
+		    (dmat->lowaddr >= bz->lowaddr)) {
+			dmat->bounce_zone = bz;
+			return (0);
+		}
+	}
+
+	if ((bz = (struct bounce_zone *)malloc(sizeof(*bz), M_DEVBUF,
+	    M_NOWAIT | M_ZERO)) == NULL)
+		return (ENOMEM);
+
+	STAILQ_INIT(&bz->bounce_page_list);
+	bz->free_bpages = 0;
+	bz->reserved_bpages = 0;
+	bz->active_bpages = 0;
+	bz->lowaddr = dmat->lowaddr;
+	bz->alignment = MAX(dmat->alignment, PAGE_SIZE);
+	bz->map_count = 0;
+	snprintf(bz->zoneid, 8, "zone%d", busdma_zonecount);
+	busdma_zonecount++;
+	snprintf(bz->lowaddrid, 18, "%#jx", (uintmax_t)bz->lowaddr);
+	STAILQ_INSERT_TAIL(&bounce_zone_list, bz, links);
+	dmat->bounce_zone = bz;
+
+	sysctl_ctx_init(&bz->sysctl_tree);
+	bz->sysctl_tree_top = SYSCTL_ADD_NODE(&bz->sysctl_tree,
+	    SYSCTL_STATIC_CHILDREN(_hw_busdma), OID_AUTO, bz->zoneid,
+	    CTLFLAG_RD, 0, "");
+	if (bz->sysctl_tree_top == NULL) {
+		sysctl_ctx_free(&bz->sysctl_tree);
+		return (0);	/* XXX error code? */
+	}
+
+	SYSCTL_ADD_INT(busdma_sysctl_tree(bz),
+	    SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO,
+	    "total_bpages", CTLFLAG_RD, &bz->total_bpages, 0,
+	    "Total bounce pages");
+	SYSCTL_ADD_INT(busdma_sysctl_tree(bz),
+	    SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO,
+	    "free_bpages", CTLFLAG_RD, &bz->free_bpages, 0,
+	    "Free bounce pages");
+	SYSCTL_ADD_INT(busdma_sysctl_tree(bz),
+	    SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO,
+	    "reserved_bpages", CTLFLAG_RD, &bz->reserved_bpages, 0,
+	    "Reserved bounce pages");
+	SYSCTL_ADD_INT(busdma_sysctl_tree(bz),
+	    SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO,
+	    "active_bpages", CTLFLAG_RD, &bz->active_bpages, 0,
+	    "Active bounce pages");
+	SYSCTL_ADD_INT(busdma_sysctl_tree(bz),
+	    SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO,
+	    "total_bounced", CTLFLAG_RD, &bz->total_bounced, 0,
+	    "Total bounce requests (pages bounced)");
+	SYSCTL_ADD_INT(busdma_sysctl_tree(bz),
+	    SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO,
+	    "total_deferred", CTLFLAG_RD, &bz->total_deferred, 0,
+	    "Total bounce requests that were deferred");
+	SYSCTL_ADD_STRING(busdma_sysctl_tree(bz),
+	    SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO,
+	    "lowaddr", CTLFLAG_RD, bz->lowaddrid, 0, "");
+	SYSCTL_ADD_ULONG(busdma_sysctl_tree(bz),
+	    SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO,
+	    "alignment", CTLFLAG_RD, &bz->alignment, "");
+
+	return (0);
+}
+
+static int
+alloc_bounce_pages(bus_dma_tag_t dmat, u_int numpages)
+{
+	struct bounce_zone *bz;
+	int count;
+
+	bz = dmat->bounce_zone;
+	count = 0;
+	while (numpages > 0) {
+		struct bounce_page *bpage;
+
+		bpage = (struct bounce_page *)malloc(sizeof(*bpage), M_DEVBUF,
+		    M_NOWAIT | M_ZERO);
+
+		if (bpage == NULL)
+			break;
+		bpage->vaddr = (vm_offset_t)contigmalloc(PAGE_SIZE, M_DEVBUF,
+		    M_NOWAIT, 0ul, bz->lowaddr, PAGE_SIZE, 0);
+		if (bpage->vaddr == 0) {
+			free(bpage, M_DEVBUF);
+			break;
+		}
+		bpage->busaddr = pmap_kextract(bpage->vaddr);
+		mtx_lock(&bounce_lock);
+		STAILQ_INSERT_TAIL(&bz->bounce_page_list, bpage, links);
+		total_bpages++;
+		bz->total_bpages++;
+		bz->free_bpages++;
+		mtx_unlock(&bounce_lock);
+		count++;
+		numpages--;
+	}
+	return (count);
+}
+
+static int
+reserve_bounce_pages(bus_dma_tag_t dmat, bus_dmamap_t map, int commit)
+{
+	struct bounce_zone *bz;
+	int pages;
+
+	mtx_assert(&bounce_lock, MA_OWNED);
+	bz = dmat->bounce_zone;
+	pages = MIN(bz->free_bpages, map->pagesneeded - map->pagesreserved);
+	if (commit == 0 && map->pagesneeded > (map->pagesreserved + pages))
+		return (map->pagesneeded - (map->pagesreserved + pages));
+	bz->free_bpages -= pages;
+	bz->reserved_bpages += pages;
+	map->pagesreserved += pages;
+	pages = map->pagesneeded - map->pagesreserved;
+
+	return (pages);
+}
+
+static bus_addr_t
+add_bounce_page(bus_dma_tag_t dmat, bus_dmamap_t map, vm_offset_t vaddr,
+		bus_addr_t addr, bus_size_t size)
+{
+	struct bounce_zone *bz;
+	struct bounce_page *bpage;
+
+	KASSERT(dmat->bounce_zone != NULL, ("no bounce zone in dma tag"));
+	KASSERT(map != NULL,
+	    ("add_bounce_page: bad map %p", map));
+
+	bz = dmat->bounce_zone;
+	if (map->pagesneeded == 0)
+		panic("add_bounce_page: map doesn't need any pages");
+	map->pagesneeded--;
+
+	if (map->pagesreserved == 0)
+		panic("add_bounce_page: map doesn't need any pages");
+	map->pagesreserved--;
+
+	mtx_lock(&bounce_lock);
+	bpage = STAILQ_FIRST(&bz->bounce_page_list);
+	if (bpage == NULL)
+		panic("add_bounce_page: free page list is empty");
+
+	STAILQ_REMOVE_HEAD(&bz->bounce_page_list, links);
+	bz->reserved_bpages--;
+	bz->active_bpages++;
+	mtx_unlock(&bounce_lock);
+
+	if (dmat->flags & BUS_DMA_KEEP_PG_OFFSET) {
+		/* Page offset needs to be preserved. */
+		bpage->vaddr |= addr & PAGE_MASK;
+		bpage->busaddr |= addr & PAGE_MASK;
+	}
+	bpage->datavaddr = vaddr;
+	bpage->dataaddr = addr;
+	bpage->datacount = size;
+	STAILQ_INSERT_TAIL(&(map->bpages), bpage, links);
+	return (bpage->busaddr);
+}
+
+static void
+free_bounce_page(bus_dma_tag_t dmat, struct bounce_page *bpage)
+{
+	struct bus_dmamap *map;
+	struct bounce_zone *bz;
+
+	bz = dmat->bounce_zone;
+	bpage->datavaddr = 0;
+	bpage->datacount = 0;
+	if (dmat->flags & BUS_DMA_KEEP_PG_OFFSET) {
+		/*
+		 * Reset the bounce page to start at offset 0.  Other uses
+		 * of this bounce page may need to store a full page of
+		 * data and/or assume it starts on a page boundary.
+		 */
+		bpage->vaddr &= ~PAGE_MASK;
+		bpage->busaddr &= ~PAGE_MASK;
+	}
+
+	mtx_lock(&bounce_lock);
+	STAILQ_INSERT_HEAD(&bz->bounce_page_list, bpage, links);
+	bz->free_bpages++;
+	bz->active_bpages--;
+	if ((map = STAILQ_FIRST(&bounce_map_waitinglist)) != NULL) {
+		if (reserve_bounce_pages(map->dmat, map, 1) == 0) {
+			STAILQ_REMOVE_HEAD(&bounce_map_waitinglist, links);
+			STAILQ_INSERT_TAIL(&bounce_map_callbacklist,
+			    map, links);
+			busdma_swi_pending = 1;
+			bz->total_deferred++;
+			swi_sched(vm_ih, 0);
+		}
+	}
+	mtx_unlock(&bounce_lock);
+}
+
+void
+busdma_swi(void)
+{
+	bus_dma_tag_t dmat;
+	struct bus_dmamap *map;
+
+	mtx_lock(&bounce_lock);
+	while ((map = STAILQ_FIRST(&bounce_map_callbacklist)) != NULL) {
+		STAILQ_REMOVE_HEAD(&bounce_map_callbacklist, links);
+		mtx_unlock(&bounce_lock);
+		dmat = map->dmat;
+		dmat->lockfunc(dmat->lockfuncarg, BUS_DMA_LOCK);
+		bus_dmamap_load_mem(map->dmat, map, &map->mem, map->callback,
+		    map->callback_arg, BUS_DMA_WAITOK);
+		dmat->lockfunc(dmat->lockfuncarg, BUS_DMA_UNLOCK);
+		mtx_lock(&bounce_lock);
+	}
+	mtx_unlock(&bounce_lock);
+}


Property changes on: trunk/sys/arm/arm/busdma_machdep-v6.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/busdma_machdep.c
===================================================================
--- trunk/sys/arm/arm/busdma_machdep.c	                        (rev 0)
+++ trunk/sys/arm/arm/busdma_machdep.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,1510 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Ian Lepore
+ * Copyright (c) 2004 Olivier Houchard
+ * Copyright (c) 2002 Peter Grehan
+ * Copyright (c) 1997, 1998 Justin T. Gibbs.
+ * 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,
+ *    without modification, immediately at the beginning of the file.
+ * 2. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 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.
+ *
+ *   From i386/busdma_machdep.c,v 1.26 2002/04/19 22:58:09 alfred
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/busdma_machdep.c 318977 2017-05-27 08:17:59Z hselasky $");
+
+/*
+ * ARM bus dma support routines.
+ *
+ * XXX Things to investigate / fix some day...
+ *  - What is the earliest that this API can be called?  Could there be any
+ *    fallout from changing the SYSINIT() order from SI_SUB_VM to SI_SUB_KMEM?
+ *  - The manpage mentions the BUS_DMA_NOWAIT flag only in the context of the
+ *    bus_dmamap_load() function.  This code has historically (and still does)
+ *    honor it in bus_dmamem_alloc().  If we got rid of that we could lose some
+ *    error checking because some resource management calls would become WAITOK
+ *    and thus "cannot fail."
+ *  - The decisions made by _bus_dma_can_bounce() should be made once, at tag
+ *    creation time, and the result stored in the tag.
+ *  - It should be possible to take some shortcuts when mapping a buffer we know
+ *    came from the uma(9) allocators based on what we know about such buffers
+ *    (aligned, contiguous, etc).
+ *  - The allocation of bounce pages could probably be cleaned up, then we could
+ *    retire arm_remap_nocache().
+ */
+
+#define _ARM32_BUS_DMA_PRIVATE
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/bus.h>
+#include <sys/busdma_bufalloc.h>
+#include <sys/interrupt.h>
+#include <sys/lock.h>
+#include <sys/proc.h>
+#include <sys/memdesc.h>
+#include <sys/mutex.h>
+#include <sys/ktr.h>
+#include <sys/kernel.h>
+#include <sys/sysctl.h>
+#include <sys/uio.h>
+
+#include <vm/uma.h>
+#include <vm/vm.h>
+#include <vm/vm_extern.h>
+#include <vm/vm_kern.h>
+#include <vm/vm_page.h>
+#include <vm/vm_map.h>
+
+#include <machine/atomic.h>
+#include <machine/bus.h>
+#include <machine/cpufunc.h>
+#include <machine/md_var.h>
+
+#define MAX_BPAGES 64
+#define BUS_DMA_COULD_BOUNCE	BUS_DMA_BUS3
+#define BUS_DMA_MIN_ALLOC_COMP	BUS_DMA_BUS4
+
+struct bounce_zone;
+
+struct bus_dma_tag {
+	bus_dma_tag_t		parent;
+	bus_size_t		alignment;
+	bus_addr_t		boundary;
+	bus_addr_t		lowaddr;
+	bus_addr_t		highaddr;
+	bus_dma_filter_t	*filter;
+	void			*filterarg;
+	bus_size_t		maxsize;
+	u_int			nsegments;
+	bus_size_t		maxsegsz;
+	int			flags;
+	int			ref_count;
+	int			map_count;
+	bus_dma_lock_t		*lockfunc;
+	void			*lockfuncarg;
+	/*
+	 * DMA range for this tag.  If the page doesn't fall within
+	 * one of these ranges, an error is returned.  The caller
+	 * may then decide what to do with the transfer.  If the
+	 * range pointer is NULL, it is ignored.
+	 */
+	struct arm32_dma_range	*ranges;
+	int			_nranges;
+	struct bounce_zone *bounce_zone;
+	/*
+	 * Most tags need one or two segments, and can use the local tagsegs
+	 * array.  For tags with a larger limit, we'll allocate a bigger array
+	 * on first use.
+	 */
+	bus_dma_segment_t	*segments;
+	bus_dma_segment_t	tagsegs[2];
+};
+
+struct bounce_page {
+	vm_offset_t	vaddr;		/* kva of bounce buffer */
+	bus_addr_t	busaddr;	/* Physical address */
+	vm_offset_t	datavaddr;	/* kva of client data */
+	bus_addr_t	dataaddr;	/* client physical address */
+	bus_size_t	datacount;	/* client data count */
+	STAILQ_ENTRY(bounce_page) links;
+};
+
+struct sync_list {
+	vm_offset_t	vaddr;		/* kva of bounce buffer */
+	bus_addr_t	busaddr;	/* Physical address */
+	bus_size_t	datacount;	/* client data count */
+};
+
+int busdma_swi_pending;
+
+struct bounce_zone {
+	STAILQ_ENTRY(bounce_zone) links;
+	STAILQ_HEAD(bp_list, bounce_page) bounce_page_list;
+	int		total_bpages;
+	int		free_bpages;
+	int		reserved_bpages;
+	int		active_bpages;
+	int		total_bounced;
+	int		total_deferred;
+	int		map_count;
+	bus_size_t	alignment;
+	bus_addr_t	lowaddr;
+	char		zoneid[8];
+	char		lowaddrid[20];
+	struct sysctl_ctx_list sysctl_tree;
+	struct sysctl_oid *sysctl_tree_top;
+};
+
+static struct mtx bounce_lock;
+static int total_bpages;
+static int busdma_zonecount;
+static STAILQ_HEAD(, bounce_zone) bounce_zone_list;
+
+static SYSCTL_NODE(_hw, OID_AUTO, busdma, CTLFLAG_RD, 0, "Busdma parameters");
+SYSCTL_INT(_hw_busdma, OID_AUTO, total_bpages, CTLFLAG_RD, &total_bpages, 0,
+	   "Total bounce pages");
+
+#define DMAMAP_COHERENT		0x8
+#define DMAMAP_CACHE_ALIGNED	0x10
+
+struct bus_dmamap {
+	struct bp_list	bpages;
+	int		pagesneeded;
+	int		pagesreserved;
+        bus_dma_tag_t	dmat;
+	struct memdesc	mem;
+	int		flags;
+	STAILQ_ENTRY(bus_dmamap) links;
+	bus_dmamap_callback_t *callback;
+	void		      *callback_arg;
+	int		       sync_count;
+	struct sync_list       *slist;
+};
+
+static STAILQ_HEAD(, bus_dmamap) bounce_map_waitinglist;
+static STAILQ_HEAD(, bus_dmamap) bounce_map_callbacklist;
+
+static struct mtx busdma_mtx;
+
+MTX_SYSINIT(busdma_mtx, &busdma_mtx, "busdma lock", MTX_DEF);
+
+static void init_bounce_pages(void *dummy);
+static int alloc_bounce_zone(bus_dma_tag_t dmat);
+static int alloc_bounce_pages(bus_dma_tag_t dmat, u_int numpages);
+static int reserve_bounce_pages(bus_dma_tag_t dmat, bus_dmamap_t map,
+				int commit);
+static bus_addr_t add_bounce_page(bus_dma_tag_t dmat, bus_dmamap_t map,
+				  vm_offset_t vaddr, bus_addr_t addr,
+				  bus_size_t size);
+static void free_bounce_page(bus_dma_tag_t dmat, struct bounce_page *bpage);
+
+/* Default tag, as most drivers provide no parent tag. */
+bus_dma_tag_t arm_root_dma_tag;
+
+/*
+ * ----------------------------------------------------------------------------
+ * Begin block of code useful to transplant to other implementations.
+ */
+
+static uma_zone_t dmamap_zone;	/* Cache of struct bus_dmamap items */
+
+static busdma_bufalloc_t coherent_allocator;	/* Cache of coherent buffers */
+static busdma_bufalloc_t standard_allocator;	/* Cache of standard buffers */
+
+/*
+ * This is the ctor function passed to uma_zcreate() for the pool of dma maps.
+ * It'll need platform-specific changes if this code is copied.
+ */
+static int
+dmamap_ctor(void *mem, int size, void *arg, int flags)
+{
+	bus_dmamap_t map;
+	bus_dma_tag_t dmat;
+
+	map = (bus_dmamap_t)mem;
+	dmat = (bus_dma_tag_t)arg;
+
+	dmat->map_count++;
+
+	map->dmat = dmat;
+	map->flags = 0;
+	STAILQ_INIT(&map->bpages);
+
+	return (0);
+}
+
+/*
+ * This is the dtor function passed to uma_zcreate() for the pool of dma maps.
+ * It may need platform-specific changes if this code is copied              .
+ */
+static void 
+dmamap_dtor(void *mem, int size, void *arg)
+{
+	bus_dmamap_t map;
+
+	map = (bus_dmamap_t)mem;
+
+	map->dmat->map_count--;
+}
+
+static void
+busdma_init(void *dummy)
+{
+
+	/* Create a cache of maps for bus_dmamap_create(). */
+	dmamap_zone = uma_zcreate("dma maps", sizeof(struct bus_dmamap),
+	    dmamap_ctor, dmamap_dtor, NULL, NULL, UMA_ALIGN_PTR, 0);
+
+	/* Create a cache of buffers in standard (cacheable) memory. */
+	standard_allocator = busdma_bufalloc_create("buffer", 
+	    arm_dcache_align,	/* minimum_alignment */
+	    NULL,		/* uma_alloc func */ 
+	    NULL,		/* uma_free func */
+	    0);			/* uma_zcreate_flags */
+
+	/*
+	 * Create a cache of buffers in uncacheable memory, to implement the
+	 * BUS_DMA_COHERENT (and potentially BUS_DMA_NOCACHE) flag.
+	 */
+	coherent_allocator = busdma_bufalloc_create("coherent",
+	    arm_dcache_align,	/* minimum_alignment */
+	    busdma_bufalloc_alloc_uncacheable, 
+	    busdma_bufalloc_free_uncacheable, 
+	    0);			/* uma_zcreate_flags */
+}
+
+/*
+ * This init historically used SI_SUB_VM, but now the init code requires
+ * malloc(9) using M_DEVBUF memory, which is set up later than SI_SUB_VM, by
+ * SI_SUB_KMEM and SI_ORDER_SECOND, so we'll go right after that by using
+ * SI_SUB_KMEM and SI_ORDER_THIRD.
+ */
+SYSINIT(busdma, SI_SUB_KMEM, SI_ORDER_THIRD, busdma_init, NULL);
+
+/*
+ * End block of code useful to transplant to other implementations.
+ * ----------------------------------------------------------------------------
+ */
+
+/*
+ * Return true if a match is made.
+ *
+ * To find a match walk the chain of bus_dma_tag_t's looking for 'paddr'.
+ *
+ * If paddr is within the bounds of the dma tag then call the filter callback
+ * to check for a match, if there is no filter callback then assume a match.
+ */
+static int
+run_filter(bus_dma_tag_t dmat, bus_addr_t paddr)
+{
+	int retval;
+
+	retval = 0;
+
+	do {
+		if (((paddr > dmat->lowaddr && paddr <= dmat->highaddr)
+		 || ((paddr & (dmat->alignment - 1)) != 0))
+		 && (dmat->filter == NULL
+		  || (*dmat->filter)(dmat->filterarg, paddr) != 0))
+			retval = 1;
+
+		dmat = dmat->parent;		
+	} while (retval == 0 && dmat != NULL);
+	return (retval);
+}
+
+/*
+ * This routine checks the exclusion zone constraints from a tag against the
+ * physical RAM available on the machine.  If a tag specifies an exclusion zone
+ * but there's no RAM in that zone, then we avoid allocating resources to bounce
+ * a request, and we can use any memory allocator (as opposed to needing
+ * kmem_alloc_contig() just because it can allocate pages in an address range).
+ *
+ * Most tags have BUS_SPACE_MAXADDR or BUS_SPACE_MAXADDR_32BIT (they are the
+ * same value on 32-bit architectures) as their lowaddr constraint, and we can't
+ * possibly have RAM at an address higher than the highest address we can
+ * express, so we take a fast out.
+ */
+static __inline int
+_bus_dma_can_bounce(vm_offset_t lowaddr, vm_offset_t highaddr)
+{
+	int i;
+
+	if (lowaddr >= BUS_SPACE_MAXADDR)
+		return (0);
+
+	for (i = 0; phys_avail[i] && phys_avail[i + 1]; i += 2) {
+		if ((lowaddr >= phys_avail[i] && lowaddr <= phys_avail[i + 1])
+		    || (lowaddr < phys_avail[i] &&
+		    highaddr > phys_avail[i]))
+			return (1);
+	}
+	return (0);
+}
+
+static __inline struct arm32_dma_range *
+_bus_dma_inrange(struct arm32_dma_range *ranges, int nranges,
+    bus_addr_t curaddr)
+{
+	struct arm32_dma_range *dr;
+	int i;
+
+	for (i = 0, dr = ranges; i < nranges; i++, dr++) {
+		if (curaddr >= dr->dr_sysbase &&
+		    round_page(curaddr) <= (dr->dr_sysbase + dr->dr_len))
+			return (dr);
+	}
+
+	return (NULL);
+}
+/*
+ * Convenience function for manipulating driver locks from busdma (during
+ * busdma_swi, for example).  Drivers that don't provide their own locks
+ * should specify &Giant to dmat->lockfuncarg.  Drivers that use their own
+ * non-mutex locking scheme don't have to use this at all.
+ */
+void
+busdma_lock_mutex(void *arg, bus_dma_lock_op_t op)
+{
+	struct mtx *dmtx;
+
+	dmtx = (struct mtx *)arg;
+	switch (op) {
+	case BUS_DMA_LOCK:
+		mtx_lock(dmtx);
+		break;
+	case BUS_DMA_UNLOCK:
+		mtx_unlock(dmtx);
+		break;
+	default:
+		panic("Unknown operation 0x%x for busdma_lock_mutex!", op);
+	}
+}
+
+/*
+ * dflt_lock should never get called.  It gets put into the dma tag when
+ * lockfunc == NULL, which is only valid if the maps that are associated
+ * with the tag are meant to never be defered.
+ * XXX Should have a way to identify which driver is responsible here.
+ */
+static void
+dflt_lock(void *arg, bus_dma_lock_op_t op)
+{
+#ifdef INVARIANTS
+	panic("driver error: busdma dflt_lock called");
+#else
+	printf("DRIVER_ERROR: busdma dflt_lock called\n");
+#endif
+}
+
+/*
+ * Allocate a device specific dma_tag.
+ */
+#define SEG_NB 1024
+
+int
+bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment,
+		   bus_addr_t boundary, bus_addr_t lowaddr,
+		   bus_addr_t highaddr, bus_dma_filter_t *filter,
+		   void *filterarg, bus_size_t maxsize, int nsegments,
+		   bus_size_t maxsegsz, int flags, bus_dma_lock_t *lockfunc,
+		   void *lockfuncarg, bus_dma_tag_t *dmat)
+{
+	bus_dma_tag_t newtag;
+	int error = 0;
+	/* Return a NULL tag on failure */
+	*dmat = NULL;
+	if (!parent)
+		parent = arm_root_dma_tag;
+
+	newtag = (bus_dma_tag_t)malloc(sizeof(*newtag), M_DEVBUF, M_NOWAIT);
+	if (newtag == NULL) {
+		CTR4(KTR_BUSDMA, "%s returned tag %p tag flags 0x%x error %d",
+		    __func__, newtag, 0, error);
+		return (ENOMEM);
+	}
+
+	newtag->parent = parent;
+	newtag->alignment = alignment ? alignment : 1;
+	newtag->boundary = boundary;
+	newtag->lowaddr = trunc_page((vm_offset_t)lowaddr) + (PAGE_SIZE - 1);
+	newtag->highaddr = trunc_page((vm_offset_t)highaddr) + (PAGE_SIZE - 1);
+	newtag->filter = filter;
+	newtag->filterarg = filterarg;
+        newtag->maxsize = maxsize;
+        newtag->nsegments = nsegments;
+	newtag->maxsegsz = maxsegsz;
+	newtag->flags = flags;
+	newtag->ref_count = 1; /* Count ourself */
+	newtag->map_count = 0;
+	newtag->ranges = bus_dma_get_range();
+	newtag->_nranges = bus_dma_get_range_nb();
+	if (lockfunc != NULL) {
+		newtag->lockfunc = lockfunc;
+		newtag->lockfuncarg = lockfuncarg;
+	} else {
+		newtag->lockfunc = dflt_lock;
+		newtag->lockfuncarg = NULL;
+	}
+	/*
+	 * If all the segments we need fit into the local tagsegs array, set the
+	 * pointer now.  Otherwise NULL the pointer and an array of segments
+	 * will be allocated later, on first use.  We don't pre-allocate now
+	 * because some tags exist just to pass contraints to children in the
+	 * device hierarchy, and they tend to use BUS_SPACE_UNRESTRICTED and we
+	 * sure don't want to try to allocate an array for that.
+	 */
+	if (newtag->nsegments <= nitems(newtag->tagsegs))
+		newtag->segments = newtag->tagsegs;
+	else
+		newtag->segments = NULL;
+	/*
+	 * Take into account any restrictions imposed by our parent tag
+	 */
+        if (parent != NULL) {
+                newtag->lowaddr = MIN(parent->lowaddr, newtag->lowaddr);
+                newtag->highaddr = MAX(parent->highaddr, newtag->highaddr);
+		if (newtag->boundary == 0)
+			newtag->boundary = parent->boundary;
+		else if (parent->boundary != 0)
+                	newtag->boundary = MIN(parent->boundary,
+					       newtag->boundary);
+		if ((newtag->filter != NULL) ||
+		    ((parent->flags & BUS_DMA_COULD_BOUNCE) != 0))
+			newtag->flags |= BUS_DMA_COULD_BOUNCE;
+                if (newtag->filter == NULL) {
+                        /*
+                         * Short circuit looking at our parent directly
+                         * since we have encapsulated all of its information
+                         */
+                        newtag->filter = parent->filter;
+                        newtag->filterarg = parent->filterarg;
+                        newtag->parent = parent->parent;
+		}
+		if (newtag->parent != NULL)
+			atomic_add_int(&parent->ref_count, 1);
+	}
+	if (_bus_dma_can_bounce(newtag->lowaddr, newtag->highaddr)
+	 || newtag->alignment > 1)
+		newtag->flags |= BUS_DMA_COULD_BOUNCE;
+
+	if (((newtag->flags & BUS_DMA_COULD_BOUNCE) != 0) &&
+	    (flags & BUS_DMA_ALLOCNOW) != 0) {
+		struct bounce_zone *bz;
+
+		/* Must bounce */
+
+		if ((error = alloc_bounce_zone(newtag)) != 0) {
+			free(newtag, M_DEVBUF);
+			return (error);
+		}
+		bz = newtag->bounce_zone;
+
+		if (ptoa(bz->total_bpages) < maxsize) {
+			int pages;
+
+			pages = atop(maxsize) - bz->total_bpages;
+
+			/* Add pages to our bounce pool */
+			if (alloc_bounce_pages(newtag, pages) < pages)
+				error = ENOMEM;
+		}
+		/* Performed initial allocation */
+		newtag->flags |= BUS_DMA_MIN_ALLOC_COMP;
+	} else
+		newtag->bounce_zone = NULL;
+	if (error != 0)
+		free(newtag, M_DEVBUF);
+	else
+		*dmat = newtag;
+	CTR4(KTR_BUSDMA, "%s returned tag %p tag flags 0x%x error %d",
+	    __func__, newtag, (newtag != NULL ? newtag->flags : 0), error);
+
+	return (error);
+}
+
+int
+bus_dma_tag_destroy(bus_dma_tag_t dmat)
+{
+#ifdef KTR
+	bus_dma_tag_t dmat_copy = dmat;
+#endif
+
+	if (dmat != NULL) {
+		
+                if (dmat->map_count != 0)
+                        return (EBUSY);
+		
+                while (dmat != NULL) {
+                        bus_dma_tag_t parent;
+			
+                        parent = dmat->parent;
+                        atomic_subtract_int(&dmat->ref_count, 1);
+                        if (dmat->ref_count == 0) {
+				if (dmat->segments != NULL &&
+				    dmat->segments != dmat->tagsegs)
+					free(dmat->segments, M_DEVBUF);
+                                free(dmat, M_DEVBUF);
+                                /*
+                                 * Last reference count, so
+                                 * release our reference
+                                 * count on our parent.
+                                 */
+                                dmat = parent;
+                        } else
+                                dmat = NULL;
+                }
+        }
+	CTR2(KTR_BUSDMA, "%s tag %p", __func__, dmat_copy);
+
+        return (0);
+}
+
+#include <sys/kdb.h>
+/*
+ * Allocate a handle for mapping from kva/uva/physical
+ * address space into bus device space.
+ */
+int
+bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp)
+{
+	struct sync_list *slist;
+	bus_dmamap_t map;
+	int error = 0;
+
+	slist = malloc(sizeof(*slist) * dmat->nsegments, M_DEVBUF, M_NOWAIT);
+	if (slist == NULL)
+		return (ENOMEM);
+
+	map = uma_zalloc_arg(dmamap_zone, dmat, M_NOWAIT);
+	*mapp = map;
+	if (map == NULL) {
+		free(slist, M_DEVBUF);
+		return (ENOMEM);
+	}
+
+	/*
+	 * If the tag's segments haven't been allocated yet we need to do it
+	 * now, because we can't sleep for resources at map load time.
+	 */
+	if (dmat->segments == NULL) {
+		dmat->segments = malloc(dmat->nsegments * 
+		    sizeof(*dmat->segments), M_DEVBUF, M_NOWAIT);
+		if (dmat->segments == NULL) {
+			free(slist, M_DEVBUF);
+			uma_zfree(dmamap_zone, map);
+			*mapp = NULL;
+			return (ENOMEM);
+		}
+	}
+
+	/*
+	 * Bouncing might be required if the driver asks for an active
+	 * exclusion region, a data alignment that is stricter than 1, and/or
+	 * an active address boundary.
+	 */
+	if (dmat->flags & BUS_DMA_COULD_BOUNCE) {
+
+		/* Must bounce */
+		struct bounce_zone *bz;
+		int maxpages;
+
+		if (dmat->bounce_zone == NULL) {
+			if ((error = alloc_bounce_zone(dmat)) != 0) {
+				free(slist, M_DEVBUF);
+				uma_zfree(dmamap_zone, map);
+				*mapp = NULL;
+				return (error);
+			}
+		}
+		bz = dmat->bounce_zone;
+
+		/* Initialize the new map */
+		STAILQ_INIT(&((*mapp)->bpages));
+
+		/*
+		 * Attempt to add pages to our pool on a per-instance
+		 * basis up to a sane limit.
+		 */
+		maxpages = MAX_BPAGES;
+		if ((dmat->flags & BUS_DMA_MIN_ALLOC_COMP) == 0
+		 || (bz->map_count > 0 && bz->total_bpages < maxpages)) {
+			int pages;
+
+			pages = MAX(atop(dmat->maxsize), 1);
+			pages = MIN(maxpages - bz->total_bpages, pages);
+			pages = MAX(pages, 1);
+			if (alloc_bounce_pages(dmat, pages) < pages)
+				error = ENOMEM;
+
+			if ((dmat->flags & BUS_DMA_MIN_ALLOC_COMP) == 0) {
+				if (error == 0)
+					dmat->flags |= BUS_DMA_MIN_ALLOC_COMP;
+			} else {
+				error = 0;
+			}
+		}
+		bz->map_count++;
+	}
+	map->sync_count = 0;
+	map->slist = slist;
+	CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d",
+	    __func__, dmat, dmat->flags, error);
+
+	return (0);
+}
+
+/*
+ * Destroy a handle for mapping from kva/uva/physical
+ * address space into bus device space.
+ */
+int
+bus_dmamap_destroy(bus_dma_tag_t dmat, bus_dmamap_t map)
+{
+
+	if (STAILQ_FIRST(&map->bpages) != NULL || map->sync_count != 0) {
+		CTR3(KTR_BUSDMA, "%s: tag %p error %d",
+		    __func__, dmat, EBUSY);
+		return (EBUSY);
+	}
+	free(map->slist, M_DEVBUF);
+	uma_zfree(dmamap_zone, map);
+	if (dmat->bounce_zone)
+		dmat->bounce_zone->map_count--;
+	CTR2(KTR_BUSDMA, "%s: tag %p error 0", __func__, dmat);
+        return (0);
+}
+
+/*
+ * Allocate a piece of memory that can be efficiently mapped into bus device
+ * space based on the constraints listed in the dma tag.  Returns a pointer to
+ * the allocated memory, and a pointer to an associated bus_dmamap.
+ */
+int
+bus_dmamem_alloc(bus_dma_tag_t dmat, void **vaddrp, int flags,
+                 bus_dmamap_t *mapp)
+{
+	struct sync_list *slist;
+	void * vaddr;
+	struct busdma_bufzone *bufzone;
+	busdma_bufalloc_t ba;
+	bus_dmamap_t map;
+	int mflags;
+	vm_memattr_t memattr;
+
+	if (flags & BUS_DMA_NOWAIT)
+		mflags = M_NOWAIT;
+	else
+		mflags = M_WAITOK;
+	/*
+	 * If the tag's segments haven't been allocated yet we need to do it
+	 * now, because we can't sleep for resources at map load time.
+	 */
+	if (dmat->segments == NULL)
+		dmat->segments = malloc(dmat->nsegments * 
+		   sizeof(*dmat->segments), M_DEVBUF, mflags);
+
+	slist = malloc(sizeof(*slist) * dmat->nsegments, M_DEVBUF, M_NOWAIT);
+	if (slist == NULL)
+		return (ENOMEM);
+	map = uma_zalloc_arg(dmamap_zone, dmat, mflags);
+	if (map == NULL) {
+		free(slist, M_DEVBUF);
+		return (ENOMEM);
+	}
+	if (flags & BUS_DMA_COHERENT) {
+		memattr = VM_MEMATTR_UNCACHEABLE;
+		ba = coherent_allocator;
+		map->flags |= DMAMAP_COHERENT;
+	} else {
+		memattr = VM_MEMATTR_DEFAULT;
+		ba = standard_allocator;
+	}
+	/* All buffers we allocate are cache-aligned. */
+	map->flags |= DMAMAP_CACHE_ALIGNED;
+
+	if (flags & BUS_DMA_ZERO)
+		mflags |= M_ZERO;
+
+	/*
+	 * Try to find a bufzone in the allocator that holds a cache of buffers
+	 * of the right size for this request.  If the buffer is too big to be
+	 * held in the allocator cache, this returns NULL.
+	 */
+	bufzone = busdma_bufalloc_findzone(ba, dmat->maxsize);
+
+	/*
+	 * Allocate the buffer from the uma(9) allocator if...
+	 *  - It's small enough to be in the allocator (bufzone not NULL).
+	 *  - The alignment constraint isn't larger than the allocation size
+	 *    (the allocator aligns buffers to their size boundaries).
+	 *  - There's no need to handle lowaddr/highaddr exclusion zones.
+	 * else allocate non-contiguous pages if...
+	 *  - The page count that could get allocated doesn't exceed nsegments.
+	 *  - The alignment constraint isn't larger than a page boundary.
+	 *  - There are no boundary-crossing constraints.
+	 * else allocate a block of contiguous pages because one or more of the
+	 * constraints is something that only the contig allocator can fulfill.
+	 */
+	if (bufzone != NULL && dmat->alignment <= bufzone->size &&
+	    !_bus_dma_can_bounce(dmat->lowaddr, dmat->highaddr)) {
+		vaddr = uma_zalloc(bufzone->umazone, mflags);
+	} else if (dmat->nsegments >=
+	    howmany(dmat->maxsize, MIN(dmat->maxsegsz, PAGE_SIZE)) &&
+	    dmat->alignment <= PAGE_SIZE &&
+	    (dmat->boundary % PAGE_SIZE) == 0) {
+		vaddr = (void *)kmem_alloc_attr(kernel_arena, dmat->maxsize,
+		    mflags, 0, dmat->lowaddr, memattr);
+	} else {
+		vaddr = (void *)kmem_alloc_contig(kernel_arena, dmat->maxsize,
+		    mflags, 0, dmat->lowaddr, dmat->alignment, dmat->boundary,
+		    memattr);
+	}
+	if (vaddr == NULL) {
+		free(slist, M_DEVBUF);
+		uma_zfree(dmamap_zone, map);
+		map = NULL;
+	} else {
+		map->slist = slist;
+		map->sync_count = 0;
+	}
+	*vaddrp = vaddr;
+	*mapp = map;
+
+	return (vaddr == NULL ? ENOMEM : 0);
+}
+
+/*
+ * Free a piece of memory that was allocated via bus_dmamem_alloc, along with
+ * its associated map.
+ */
+void
+bus_dmamem_free(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map)
+{
+	struct busdma_bufzone *bufzone;
+	busdma_bufalloc_t ba;
+
+	if (map->flags & DMAMAP_COHERENT)
+		ba = coherent_allocator;
+	else
+		ba = standard_allocator;
+
+	free(map->slist, M_DEVBUF);
+	uma_zfree(dmamap_zone, map);
+
+	bufzone = busdma_bufalloc_findzone(ba, dmat->maxsize);
+
+	if (bufzone != NULL && dmat->alignment <= bufzone->size &&
+	    !_bus_dma_can_bounce(dmat->lowaddr, dmat->highaddr))
+		uma_zfree(bufzone->umazone, vaddr);
+	else
+		kmem_free(kernel_arena, (vm_offset_t)vaddr, dmat->maxsize);
+}
+
+static void
+_bus_dmamap_count_phys(bus_dma_tag_t dmat, bus_dmamap_t map, vm_paddr_t buf,
+    bus_size_t buflen, int flags)
+{
+	bus_addr_t curaddr;
+	bus_size_t sgsize;
+
+	if (map->pagesneeded == 0) {
+		CTR3(KTR_BUSDMA, "lowaddr= %d, boundary= %d, alignment= %d",
+		    dmat->lowaddr, dmat->boundary, dmat->alignment);
+		CTR2(KTR_BUSDMA, "map= %p, pagesneeded= %d",
+		    map, map->pagesneeded);
+		/*
+		 * Count the number of bounce pages
+		 * needed in order to complete this transfer
+		 */
+		curaddr = buf;
+		while (buflen != 0) {
+			sgsize = MIN(buflen, dmat->maxsegsz);
+			if (run_filter(dmat, curaddr) != 0) {
+				sgsize = MIN(sgsize, PAGE_SIZE);
+				map->pagesneeded++;
+			}
+			curaddr += sgsize;
+			buflen -= sgsize;
+		}
+		CTR1(KTR_BUSDMA, "pagesneeded= %d\n", map->pagesneeded);
+	}
+}
+
+static void
+_bus_dmamap_count_pages(bus_dma_tag_t dmat, bus_dmamap_t map, pmap_t pmap,
+    void *buf, bus_size_t buflen, int flags)
+{
+	vm_offset_t vaddr;
+	vm_offset_t vendaddr;
+	bus_addr_t paddr;
+
+	if (map->pagesneeded == 0) {
+		CTR3(KTR_BUSDMA, "lowaddr= %d, boundary= %d, alignment= %d",
+		    dmat->lowaddr, dmat->boundary, dmat->alignment);
+		CTR2(KTR_BUSDMA, "map= %p, pagesneeded= %d",
+		    map, map->pagesneeded);
+		/*
+		 * Count the number of bounce pages
+		 * needed in order to complete this transfer
+		 */
+		vaddr = trunc_page((vm_offset_t)buf);
+		vendaddr = (vm_offset_t)buf + buflen;
+
+		while (vaddr < vendaddr) {
+			if (__predict_true(pmap == kernel_pmap))
+				paddr = pmap_kextract(vaddr);
+			else
+				paddr = pmap_extract(pmap, vaddr);
+			if (run_filter(dmat, paddr) != 0)
+				map->pagesneeded++;
+			vaddr += PAGE_SIZE;
+		}
+		CTR1(KTR_BUSDMA, "pagesneeded= %d\n", map->pagesneeded);
+	}
+}
+
+static int
+_bus_dmamap_reserve_pages(bus_dma_tag_t dmat, bus_dmamap_t map, int flags)
+{
+
+	/* Reserve Necessary Bounce Pages */
+	mtx_lock(&bounce_lock);
+	if (flags & BUS_DMA_NOWAIT) {
+		if (reserve_bounce_pages(dmat, map, 0) != 0) {
+			mtx_unlock(&bounce_lock);
+			return (ENOMEM);
+		}
+	} else {
+		if (reserve_bounce_pages(dmat, map, 1) != 0) {
+			/* Queue us for resources */
+			STAILQ_INSERT_TAIL(&bounce_map_waitinglist, map, links);
+			mtx_unlock(&bounce_lock);
+			return (EINPROGRESS);
+		}
+	}
+	mtx_unlock(&bounce_lock);
+
+	return (0);
+}
+
+/*
+ * Add a single contiguous physical range to the segment list.
+ */
+static int
+_bus_dmamap_addseg(bus_dma_tag_t dmat, bus_dmamap_t map, bus_addr_t curaddr,
+    bus_size_t sgsize, bus_dma_segment_t *segs, int *segp)
+{
+	bus_addr_t baddr, bmask;
+	int seg;
+
+	/*
+	 * Make sure we don't cross any boundaries.
+	 */
+	bmask = ~(dmat->boundary - 1);
+	if (dmat->boundary > 0) {
+		baddr = (curaddr + dmat->boundary) & bmask;
+		if (sgsize > (baddr - curaddr))
+			sgsize = (baddr - curaddr);
+	}
+	if (dmat->ranges) {
+		struct arm32_dma_range *dr;
+
+		dr = _bus_dma_inrange(dmat->ranges, dmat->_nranges,
+		    curaddr);
+		if (dr == NULL)
+			return (0);
+		/*
+		 * In a valid DMA range.  Translate the physical
+		 * memory address to an address in the DMA window.
+		 */
+		curaddr = (curaddr - dr->dr_sysbase) + dr->dr_busbase;
+					
+	}
+
+	seg = *segp;
+	/*
+	 * Insert chunk into a segment, coalescing with
+	 * the previous segment if possible.
+	 */
+	if (seg >= 0 &&
+	    curaddr == segs[seg].ds_addr + segs[seg].ds_len &&
+	    (segs[seg].ds_len + sgsize) <= dmat->maxsegsz &&
+	    (dmat->boundary == 0 ||
+	     (segs[seg].ds_addr & bmask) == (curaddr & bmask))) {
+		segs[seg].ds_len += sgsize;
+	} else {
+		if (++seg >= dmat->nsegments)
+			return (0);
+		segs[seg].ds_addr = curaddr;
+		segs[seg].ds_len = sgsize;
+	}
+	*segp = seg;
+	return (sgsize);
+}
+
+/*
+ * Utility function to load a physical buffer.  segp contains
+ * the starting segment on entrace, and the ending segment on exit.
+ */
+int
+_bus_dmamap_load_phys(bus_dma_tag_t dmat, bus_dmamap_t map, vm_paddr_t buf,
+    bus_size_t buflen, int flags, bus_dma_segment_t *segs, int *segp)
+{
+	bus_size_t sgsize;
+	bus_addr_t curaddr;
+	int error;
+
+	if (segs == NULL)
+		segs = dmat->segments;
+
+	if ((dmat->flags & BUS_DMA_COULD_BOUNCE) != 0) {
+		_bus_dmamap_count_phys(dmat, map, buf, buflen, flags);
+		if (map->pagesneeded != 0) {
+			error = _bus_dmamap_reserve_pages(dmat, map, flags);
+			if (error)
+				return (error);
+		}
+	}
+
+	while (buflen > 0) {
+		curaddr = buf;
+		sgsize = MIN(buflen, dmat->maxsegsz);
+		if (((dmat->flags & BUS_DMA_COULD_BOUNCE) != 0) &&
+		    map->pagesneeded != 0 && run_filter(dmat, curaddr)) {
+			sgsize = MIN(sgsize, PAGE_SIZE);
+			curaddr = add_bounce_page(dmat, map, 0, curaddr,
+			    sgsize);
+		}
+		sgsize = _bus_dmamap_addseg(dmat, map, curaddr, sgsize, segs,
+		    segp);
+		if (sgsize == 0)
+			break;
+		buf += sgsize;
+		buflen -= sgsize;
+	}
+
+	/*
+	 * Did we fit?
+	 */
+	if (buflen != 0) {
+		_bus_dmamap_unload(dmat, map);
+		return (EFBIG); /* XXX better return value here? */
+	}
+	return (0);
+}
+
+int
+_bus_dmamap_load_ma(bus_dma_tag_t dmat, bus_dmamap_t map,
+    struct vm_page **ma, bus_size_t tlen, int ma_offs, int flags,
+    bus_dma_segment_t *segs, int *segp)
+{
+
+	return (bus_dmamap_load_ma_triv(dmat, map, ma, tlen, ma_offs, flags,
+	    segs, segp));
+}
+
+/*
+ * Utility function to load a linear buffer.  segp contains
+ * the starting segment on entrance, and the ending segment on exit.
+ */
+int
+_bus_dmamap_load_buffer(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf,
+    bus_size_t buflen, struct pmap *pmap, int flags, bus_dma_segment_t *segs,
+    int *segp)
+{
+	bus_size_t sgsize;
+	bus_addr_t curaddr;
+	struct sync_list *sl;
+	vm_offset_t vaddr = (vm_offset_t)buf;
+	int error = 0;
+
+	if (segs == NULL)
+		segs = dmat->segments;
+	if ((flags & BUS_DMA_LOAD_MBUF) != 0)
+		map->flags |= DMAMAP_CACHE_ALIGNED;
+
+	if ((dmat->flags & BUS_DMA_COULD_BOUNCE) != 0) {
+		_bus_dmamap_count_pages(dmat, map, pmap, buf, buflen, flags);
+		if (map->pagesneeded != 0) {
+			error = _bus_dmamap_reserve_pages(dmat, map, flags);
+			if (error)
+				return (error);
+		}
+	}
+	CTR3(KTR_BUSDMA, "lowaddr= %d boundary= %d, "
+	    "alignment= %d", dmat->lowaddr, dmat->boundary, dmat->alignment);
+
+	while (buflen > 0) {
+		/*
+		 * Get the physical address for this segment.
+		 */
+		if (__predict_true(pmap == kernel_pmap)) {
+			curaddr = pmap_kextract(vaddr);
+		} else {
+			curaddr = pmap_extract(pmap, vaddr);
+			map->flags &= ~DMAMAP_COHERENT;
+		}
+
+		/*
+		 * Compute the segment size, and adjust counts.
+		 */
+		sgsize = PAGE_SIZE - ((u_long)curaddr & PAGE_MASK);
+		if (sgsize > dmat->maxsegsz)
+			sgsize = dmat->maxsegsz;
+		if (buflen < sgsize)
+			sgsize = buflen;
+
+		if (((dmat->flags & BUS_DMA_COULD_BOUNCE) != 0) &&
+		    map->pagesneeded != 0 && run_filter(dmat, curaddr)) {
+			curaddr = add_bounce_page(dmat, map, vaddr, curaddr,
+			    sgsize);
+		} else {
+			sl = &map->slist[map->sync_count - 1];
+			if (map->sync_count == 0 ||
+			    vaddr != sl->vaddr + sl->datacount) {
+				if (++map->sync_count > dmat->nsegments)
+					goto cleanup;
+				sl++;
+				sl->vaddr = vaddr;
+				sl->datacount = sgsize;
+				sl->busaddr = curaddr;
+			} else
+				sl->datacount += sgsize;
+		}
+		sgsize = _bus_dmamap_addseg(dmat, map, curaddr, sgsize, segs,
+		    segp);
+		if (sgsize == 0)
+			break;
+		vaddr += sgsize;
+		buflen -= sgsize;
+	}
+
+cleanup:
+	/*
+	 * Did we fit?
+	 */
+	if (buflen != 0) {
+		_bus_dmamap_unload(dmat, map);
+		return (EFBIG); /* XXX better return value here? */
+	}
+	return (0);
+}
+
+void
+__bus_dmamap_waitok(bus_dma_tag_t dmat, bus_dmamap_t map,
+		    struct memdesc *mem, bus_dmamap_callback_t *callback,
+		    void *callback_arg)
+{
+
+	KASSERT(dmat != NULL, ("dmatag is NULL"));
+	KASSERT(map != NULL, ("dmamap is NULL"));
+	map->mem = *mem;
+	map->callback = callback;
+	map->callback_arg = callback_arg;
+}
+
+bus_dma_segment_t *
+_bus_dmamap_complete(bus_dma_tag_t dmat, bus_dmamap_t map,
+		     bus_dma_segment_t *segs, int nsegs, int error)
+{
+
+	if (segs == NULL)
+		segs = dmat->segments;
+	return (segs);
+}
+
+/*
+ * Release the mapping held by map.
+ */
+void
+_bus_dmamap_unload(bus_dma_tag_t dmat, bus_dmamap_t map)
+{
+	struct bounce_page *bpage;
+
+	while ((bpage = STAILQ_FIRST(&map->bpages)) != NULL) {
+		STAILQ_REMOVE_HEAD(&map->bpages, links);
+		free_bounce_page(dmat, bpage);
+	}
+	map->sync_count = 0;
+	return;
+}
+
+static void
+bus_dmamap_sync_buf(vm_offset_t buf, int len, bus_dmasync_op_t op,
+    int bufaligned)
+{
+	char _tmp_cl[arm_dcache_align], _tmp_clend[arm_dcache_align];
+	register_t s;
+	int partial;
+
+	if ((op & BUS_DMASYNC_PREWRITE) && !(op & BUS_DMASYNC_PREREAD)) {
+		cpu_dcache_wb_range(buf, len);
+		cpu_l2cache_wb_range(buf, len);
+	}
+
+	/*
+	 * If the caller promises the buffer is properly aligned to a cache line
+	 * (even if the call parms make it look like it isn't) we can avoid
+	 * attempting to preserve the non-DMA part of the cache line in the
+	 * POSTREAD case, but we MUST still do a writeback in the PREREAD case.
+	 *
+	 * This covers the case of mbufs, where we know how they're aligned and
+	 * know the CPU doesn't touch the header in front of the DMA data area
+	 * during the IO, but it may have touched it right before invoking the
+	 * sync, so a PREREAD writeback is required.
+	 *
+	 * It also handles buffers we created in bus_dmamem_alloc(), which are
+	 * always aligned and padded to cache line size even if the IO length
+	 * isn't a multiple of cache line size.  In this case the PREREAD
+	 * writeback probably isn't required, but it's harmless.
+	 */
+	partial = (((vm_offset_t)buf) | len) & arm_dcache_align_mask;
+
+	if (op & BUS_DMASYNC_PREREAD) {
+		if (!(op & BUS_DMASYNC_PREWRITE) && !partial) {
+			cpu_dcache_inv_range(buf, len);
+			cpu_l2cache_inv_range(buf, len);
+		} else {
+		    	cpu_dcache_wbinv_range(buf, len);
+	    		cpu_l2cache_wbinv_range(buf, len);
+		}
+	}
+	if (op & BUS_DMASYNC_POSTREAD) {
+		if (partial && !bufaligned) {
+			s = intr_disable();
+			if (buf & arm_dcache_align_mask)
+				memcpy(_tmp_cl, (void *)(buf &
+				    ~arm_dcache_align_mask),
+				    buf & arm_dcache_align_mask);
+			if ((buf + len) & arm_dcache_align_mask)
+				memcpy(_tmp_clend,
+				    (void *)(buf + len),
+				    arm_dcache_align -
+				    ((buf + len) & arm_dcache_align_mask));
+		}
+		cpu_dcache_inv_range(buf, len);
+		cpu_l2cache_inv_range(buf, len);
+		if (partial && !bufaligned) {
+			if (buf & arm_dcache_align_mask)
+				memcpy((void *)(buf &
+				    ~arm_dcache_align_mask), _tmp_cl,
+				    buf & arm_dcache_align_mask);
+			if ((buf + len) & arm_dcache_align_mask)
+				memcpy((void *)(buf + len),
+				    _tmp_clend, arm_dcache_align -
+				    ((buf + len) & arm_dcache_align_mask));
+			intr_restore(s);
+		}
+	}
+}
+
+static void
+_bus_dmamap_sync_bp(bus_dma_tag_t dmat, bus_dmamap_t map, bus_dmasync_op_t op)
+{
+	struct bounce_page *bpage;
+
+	STAILQ_FOREACH(bpage, &map->bpages, links) {
+		if (op & BUS_DMASYNC_PREWRITE) {
+			if (bpage->datavaddr != 0)
+				bcopy((void *)bpage->datavaddr, 
+				    (void *)bpage->vaddr, bpage->datacount);
+			else
+				physcopyout(bpage->dataaddr,
+				    (void *)bpage->vaddr,bpage->datacount);
+			cpu_dcache_wb_range(bpage->vaddr, bpage->datacount);
+			cpu_l2cache_wb_range(bpage->vaddr, bpage->datacount);
+			dmat->bounce_zone->total_bounced++;
+		}
+		if (op & BUS_DMASYNC_POSTREAD) {
+			cpu_dcache_inv_range(bpage->vaddr, bpage->datacount);
+			cpu_l2cache_inv_range(bpage->vaddr, bpage->datacount);
+			if (bpage->datavaddr != 0)
+				bcopy((void *)bpage->vaddr,
+				    (void *)bpage->datavaddr, bpage->datacount);
+			else
+				physcopyin((void *)bpage->vaddr,
+				    bpage->dataaddr, bpage->datacount);
+			dmat->bounce_zone->total_bounced++;
+		}
+	}
+}
+
+void
+_bus_dmamap_sync(bus_dma_tag_t dmat, bus_dmamap_t map, bus_dmasync_op_t op)
+{
+	struct sync_list *sl, *end;
+	int bufaligned;
+
+	if (op == BUS_DMASYNC_POSTWRITE)
+		return;
+	if (map->flags & DMAMAP_COHERENT)
+		goto drain;
+	if (STAILQ_FIRST(&map->bpages))
+		_bus_dmamap_sync_bp(dmat, map, op);
+	CTR3(KTR_BUSDMA, "%s: op %x flags %x", __func__, op, map->flags);
+	bufaligned = (map->flags & DMAMAP_CACHE_ALIGNED);
+	if (map->sync_count) {
+		end = &map->slist[map->sync_count];
+		for (sl = &map->slist[0]; sl != end; sl++)
+			bus_dmamap_sync_buf(sl->vaddr, sl->datacount, op,
+			    bufaligned);
+	}
+
+drain:
+
+	cpu_drain_writebuf();
+}
+
+static void
+init_bounce_pages(void *dummy __unused)
+{
+
+	total_bpages = 0;
+	STAILQ_INIT(&bounce_zone_list);
+	STAILQ_INIT(&bounce_map_waitinglist);
+	STAILQ_INIT(&bounce_map_callbacklist);
+	mtx_init(&bounce_lock, "bounce pages lock", NULL, MTX_DEF);
+}
+SYSINIT(bpages, SI_SUB_LOCK, SI_ORDER_ANY, init_bounce_pages, NULL);
+
+static struct sysctl_ctx_list *
+busdma_sysctl_tree(struct bounce_zone *bz)
+{
+	return (&bz->sysctl_tree);
+}
+
+static struct sysctl_oid *
+busdma_sysctl_tree_top(struct bounce_zone *bz)
+{
+	return (bz->sysctl_tree_top);
+}
+
+static int
+alloc_bounce_zone(bus_dma_tag_t dmat)
+{
+	struct bounce_zone *bz;
+
+	/* Check to see if we already have a suitable zone */
+	STAILQ_FOREACH(bz, &bounce_zone_list, links) {
+		if ((dmat->alignment <= bz->alignment)
+		 && (dmat->lowaddr >= bz->lowaddr)) {
+			dmat->bounce_zone = bz;
+			return (0);
+		}
+	}
+
+	if ((bz = (struct bounce_zone *)malloc(sizeof(*bz), M_DEVBUF,
+	    M_NOWAIT | M_ZERO)) == NULL)
+		return (ENOMEM);
+
+	STAILQ_INIT(&bz->bounce_page_list);
+	bz->free_bpages = 0;
+	bz->reserved_bpages = 0;
+	bz->active_bpages = 0;
+	bz->lowaddr = dmat->lowaddr;
+	bz->alignment = MAX(dmat->alignment, PAGE_SIZE);
+	bz->map_count = 0;
+	snprintf(bz->zoneid, 8, "zone%d", busdma_zonecount);
+	busdma_zonecount++;
+	snprintf(bz->lowaddrid, 18, "%#jx", (uintmax_t)bz->lowaddr);
+	STAILQ_INSERT_TAIL(&bounce_zone_list, bz, links);
+	dmat->bounce_zone = bz;
+
+	sysctl_ctx_init(&bz->sysctl_tree);
+	bz->sysctl_tree_top = SYSCTL_ADD_NODE(&bz->sysctl_tree,
+	    SYSCTL_STATIC_CHILDREN(_hw_busdma), OID_AUTO, bz->zoneid,
+	    CTLFLAG_RD, 0, "");
+	if (bz->sysctl_tree_top == NULL) {
+		sysctl_ctx_free(&bz->sysctl_tree);
+		return (0);	/* XXX error code? */
+	}
+
+	SYSCTL_ADD_INT(busdma_sysctl_tree(bz),
+	    SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO,
+	    "total_bpages", CTLFLAG_RD, &bz->total_bpages, 0,
+	    "Total bounce pages");
+	SYSCTL_ADD_INT(busdma_sysctl_tree(bz),
+	    SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO,
+	    "free_bpages", CTLFLAG_RD, &bz->free_bpages, 0,
+	    "Free bounce pages");
+	SYSCTL_ADD_INT(busdma_sysctl_tree(bz),
+	    SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO,
+	    "reserved_bpages", CTLFLAG_RD, &bz->reserved_bpages, 0,
+	    "Reserved bounce pages");
+	SYSCTL_ADD_INT(busdma_sysctl_tree(bz),
+	    SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO,
+	    "active_bpages", CTLFLAG_RD, &bz->active_bpages, 0,
+	    "Active bounce pages");
+	SYSCTL_ADD_INT(busdma_sysctl_tree(bz),
+	    SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO,
+	    "total_bounced", CTLFLAG_RD, &bz->total_bounced, 0,
+	    "Total bounce requests");
+	SYSCTL_ADD_INT(busdma_sysctl_tree(bz),
+	    SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO,
+	    "total_deferred", CTLFLAG_RD, &bz->total_deferred, 0,
+	    "Total bounce requests that were deferred");
+	SYSCTL_ADD_STRING(busdma_sysctl_tree(bz),
+	    SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO,
+	    "lowaddr", CTLFLAG_RD, bz->lowaddrid, 0, "");
+	SYSCTL_ADD_ULONG(busdma_sysctl_tree(bz),
+	    SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO,
+	    "alignment", CTLFLAG_RD, &bz->alignment, "");
+
+	return (0);
+}
+
+static int
+alloc_bounce_pages(bus_dma_tag_t dmat, u_int numpages)
+{
+	struct bounce_zone *bz;
+	int count;
+
+	bz = dmat->bounce_zone;
+	count = 0;
+	while (numpages > 0) {
+		struct bounce_page *bpage;
+
+		bpage = (struct bounce_page *)malloc(sizeof(*bpage), M_DEVBUF,
+						     M_NOWAIT | M_ZERO);
+
+		if (bpage == NULL)
+			break;
+		bpage->vaddr = (vm_offset_t)contigmalloc(PAGE_SIZE, M_DEVBUF,
+							 M_NOWAIT, 0ul,
+							 bz->lowaddr,
+							 PAGE_SIZE,
+							 0);
+		if (bpage->vaddr == 0) {
+			free(bpage, M_DEVBUF);
+			break;
+		}
+		bpage->busaddr = pmap_kextract(bpage->vaddr);
+		mtx_lock(&bounce_lock);
+		STAILQ_INSERT_TAIL(&bz->bounce_page_list, bpage, links);
+		total_bpages++;
+		bz->total_bpages++;
+		bz->free_bpages++;
+		mtx_unlock(&bounce_lock);
+		count++;
+		numpages--;
+	}
+	return (count);
+}
+
+static int
+reserve_bounce_pages(bus_dma_tag_t dmat, bus_dmamap_t map, int commit)
+{
+	struct bounce_zone *bz;
+	int pages;
+
+	mtx_assert(&bounce_lock, MA_OWNED);
+	bz = dmat->bounce_zone;
+	pages = MIN(bz->free_bpages, map->pagesneeded - map->pagesreserved);
+	if (commit == 0 && map->pagesneeded > (map->pagesreserved + pages))
+		return (map->pagesneeded - (map->pagesreserved + pages));
+	bz->free_bpages -= pages;
+	bz->reserved_bpages += pages;
+	map->pagesreserved += pages;
+	pages = map->pagesneeded - map->pagesreserved;
+
+	return (pages);
+}
+
+static bus_addr_t
+add_bounce_page(bus_dma_tag_t dmat, bus_dmamap_t map, vm_offset_t vaddr,
+		bus_addr_t addr, bus_size_t size)
+{
+	struct bounce_zone *bz;
+	struct bounce_page *bpage;
+
+	KASSERT(dmat->bounce_zone != NULL, ("no bounce zone in dma tag"));
+	KASSERT(map != NULL, ("add_bounce_page: bad map %p", map));
+
+	bz = dmat->bounce_zone;
+	if (map->pagesneeded == 0)
+		panic("add_bounce_page: map doesn't need any pages");
+	map->pagesneeded--;
+
+	if (map->pagesreserved == 0)
+		panic("add_bounce_page: map doesn't need any pages");
+	map->pagesreserved--;
+
+	mtx_lock(&bounce_lock);
+	bpage = STAILQ_FIRST(&bz->bounce_page_list);
+	if (bpage == NULL)
+		panic("add_bounce_page: free page list is empty");
+
+	STAILQ_REMOVE_HEAD(&bz->bounce_page_list, links);
+	bz->reserved_bpages--;
+	bz->active_bpages++;
+	mtx_unlock(&bounce_lock);
+
+	if (dmat->flags & BUS_DMA_KEEP_PG_OFFSET) {
+		/* Page offset needs to be preserved. */
+		bpage->vaddr |= addr & PAGE_MASK;
+		bpage->busaddr |= addr & PAGE_MASK;
+	}
+	bpage->datavaddr = vaddr;
+	bpage->dataaddr = addr;
+	bpage->datacount = size;
+	STAILQ_INSERT_TAIL(&(map->bpages), bpage, links);
+	return (bpage->busaddr);
+}
+
+static void
+free_bounce_page(bus_dma_tag_t dmat, struct bounce_page *bpage)
+{
+	struct bus_dmamap *map;
+	struct bounce_zone *bz;
+
+	bz = dmat->bounce_zone;
+	bpage->datavaddr = 0;
+	bpage->datacount = 0;
+	if (dmat->flags & BUS_DMA_KEEP_PG_OFFSET) {
+		/*
+		 * Reset the bounce page to start at offset 0.  Other uses
+		 * of this bounce page may need to store a full page of
+		 * data and/or assume it starts on a page boundary.
+		 */
+		bpage->vaddr &= ~PAGE_MASK;
+		bpage->busaddr &= ~PAGE_MASK;
+	}
+
+	mtx_lock(&bounce_lock);
+	STAILQ_INSERT_HEAD(&bz->bounce_page_list, bpage, links);
+	bz->free_bpages++;
+	bz->active_bpages--;
+	if ((map = STAILQ_FIRST(&bounce_map_waitinglist)) != NULL) {
+		if (reserve_bounce_pages(map->dmat, map, 1) == 0) {
+			STAILQ_REMOVE_HEAD(&bounce_map_waitinglist, links);
+			STAILQ_INSERT_TAIL(&bounce_map_callbacklist,
+					   map, links);
+			busdma_swi_pending = 1;
+			bz->total_deferred++;
+			swi_sched(vm_ih, 0);
+		}
+	}
+	mtx_unlock(&bounce_lock);
+}
+
+void
+busdma_swi(void)
+{
+	bus_dma_tag_t dmat;
+	struct bus_dmamap *map;
+
+	mtx_lock(&bounce_lock);
+	while ((map = STAILQ_FIRST(&bounce_map_callbacklist)) != NULL) {
+		STAILQ_REMOVE_HEAD(&bounce_map_callbacklist, links);
+		mtx_unlock(&bounce_lock);
+		dmat = map->dmat;
+		(dmat->lockfunc)(dmat->lockfuncarg, BUS_DMA_LOCK);
+		bus_dmamap_load_mem(map->dmat, map, &map->mem,
+		    map->callback, map->callback_arg, BUS_DMA_WAITOK);
+		(dmat->lockfunc)(dmat->lockfuncarg, BUS_DMA_UNLOCK);
+		mtx_lock(&bounce_lock);
+	}
+	mtx_unlock(&bounce_lock);
+}


Property changes on: trunk/sys/arm/arm/busdma_machdep.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/copystr.S
===================================================================
--- trunk/sys/arm/arm/copystr.S	                        (rev 0)
+++ trunk/sys/arm/arm/copystr.S	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,216 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: copystr.S,v 1.8 2002/10/13 14:54:48 bjh21 Exp $	*/
+
+/*-
+ * Copyright (c) 1995 Mark Brinicombe.
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Mark Brinicombe.
+ * 4. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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.
+ *
+ * copystr.S
+ *
+ * optimised and fault protected copystr functions
+ *
+ * Created      : 16/05/95
+ */
+
+	
+#include "assym.s"
+#include <machine/acle-compat.h>
+#include <machine/asm.h>
+#include <machine/armreg.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/copystr.S 294681 2016-01-24 19:58:58Z ian $");
+
+#include <sys/errno.h>
+
+	.text
+	.align	2
+
+#if __ARM_ARCH >= 6
+#define GET_PCB(tmp) \
+	mrc p15, 0, tmp, c13, c0, 4; \
+	add	tmp, tmp, #(TD_PCB)
+#else
+.Lpcb:
+	.word	_C_LABEL(__pcpu) + PC_CURPCB
+
+#define GET_PCB(tmp) \
+	ldr	tmp, .Lpcb
+#endif
+
+/*
+ * r0 - from
+ * r1 - to
+ * r2 - maxlens
+ * r3 - lencopied
+ *
+ * Copy string from r0 to r1
+ */
+ENTRY(copystr)
+	stmfd	sp!, {r4-r5}			/* stack is 8 byte aligned */
+	teq	r2, #0x00000000
+	mov	r5, #0x00000000
+	moveq	r0, #ENAMETOOLONG
+	beq	2f
+
+1:	ldrb	r4, [r0], #0x0001
+	add	r5, r5, #0x00000001
+	teq	r4, #0x00000000
+	strb	r4, [r1], #0x0001
+	teqne	r5, r2
+	bne	1b
+
+	teq	r4, #0x00000000
+	moveq	r0, #0x00000000
+	movne	r0, #ENAMETOOLONG
+
+2:	teq	r3, #0x00000000
+	strne	r5, [r3]
+
+	ldmfd	sp!, {r4-r5}			/* stack is 8 byte aligned */
+	RET
+END(copystr)
+
+#define SAVE_REGS	stmfd	sp!, {r4-r6}
+#define RESTORE_REGS	ldmfd	sp!, {r4-r6}
+
+/*
+ * r0 - user space address
+ * r1 - kernel space address
+ * r2 - maxlens
+ * r3 - lencopied
+ *
+ * Copy string from user space to kernel space
+ */
+ENTRY(copyinstr)
+	SAVE_REGS
+
+	teq	r2, #0x00000000
+	mov	r6, #0x00000000
+	moveq	r0, #ENAMETOOLONG
+	beq	2f
+
+	GET_PCB(r4)
+	ldr	r4, [r4]
+
+#ifdef DIAGNOSTIC
+	teq	r4, #0x00000000
+	beq	.Lcopystrpcbfault
+#endif
+
+	adr	r5, .Lcopystrfault
+	str	r5, [r4, #PCB_ONFAULT]
+
+1:	ldrbt	r5, [r0], #0x0001
+	add	r6, r6, #0x00000001
+	teq	r5, #0x00000000
+	strb	r5, [r1], #0x0001
+	teqne	r6, r2
+	bne	1b
+
+	mov	r0, #0x00000000
+	str	r0, [r4, #PCB_ONFAULT]
+
+	teq	r5, #0x00000000
+	moveq	r0, #0x00000000
+	movne	r0, #ENAMETOOLONG
+
+2:	teq	r3, #0x00000000
+	strne	r6, [r3]
+
+	RESTORE_REGS
+	RET
+END(copyinstr)
+
+/*
+ * r0 - kernel space address
+ * r1 - user space address
+ * r2 - maxlens
+ * r3 - lencopied
+ *
+ * Copy string from kernel space to user space
+ */
+ENTRY(copyoutstr)
+	SAVE_REGS
+
+	teq	r2, #0x00000000
+	mov	r6, #0x00000000
+	moveq	r0, #ENAMETOOLONG
+	beq	2f
+
+	GET_PCB(r4)
+	ldr	r4, [r4]
+
+#ifdef DIAGNOSTIC
+	teq	r4, #0x00000000
+	beq	.Lcopystrpcbfault
+#endif
+
+	adr	r5, .Lcopystrfault
+	str	r5, [r4, #PCB_ONFAULT]
+
+1:	ldrb	r5, [r0], #0x0001
+	add	r6, r6, #0x00000001
+	teq	r5, #0x00000000
+	strbt	r5, [r1], #0x0001
+	teqne	r6, r2
+	bne	1b
+
+	mov	r0, #0x00000000
+	str	r0, [r4, #PCB_ONFAULT]
+
+	teq	r5, #0x00000000
+	moveq	r0, #0x00000000
+	movne	r0, #ENAMETOOLONG
+
+2:	teq	r3, #0x00000000
+	strne	r6, [r3]
+
+	RESTORE_REGS
+	RET
+END(copyoutstr)
+
+/* A fault occurred during the copy */
+.Lcopystrfault:
+	mov	r1, #0x00000000
+	str	r1, [r4, #PCB_ONFAULT]
+	RESTORE_REGS
+	RET
+
+#ifdef DIAGNOSTIC
+.Lcopystrpcbfault:
+	mov	r2, r1
+	mov	r1, r0
+	adr	r0, Lcopystrpcbfaulttext
+	bic	sp, sp, #7			/* align stack to 8 bytes */
+	b	_C_LABEL(panic)
+
+Lcopystrpcbfaulttext:
+	.asciz	"No valid PCB during copyinoutstr() addr1=%08x addr2=%08x\n"
+	.align	2
+#endif


Property changes on: trunk/sys/arm/arm/copystr.S
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/cpu_asm-v6.S
===================================================================
--- trunk/sys/arm/arm/cpu_asm-v6.S	                        (rev 0)
+++ trunk/sys/arm/arm/cpu_asm-v6.S	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,211 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright 2014 Svatopluk Kraus <onwahe at gmail.com>
+ * Copyright 2014 Michal Meloun <meloun at miracle.cz>
+ * 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: stable/10/sys/arm/arm/cpu_asm-v6.S 278645 2015-02-13 00:12:21Z ian $
+ */
+
+#include <machine/acle-compat.h>
+#include <machine/asm.h>
+#include <machine/asmacros.h>
+#include <machine/armreg.h>
+#include <machine/sysreg.h>
+
+/* 
+ * Define cache functions used by startup code, which counts on the fact that
+ * only r0-r3,r12 (ip) are modified and no stack space is used.  These functions
+ * must be called with interrupts disabled.  Moreover, these work only with 
+ * caches integrated to CPU (accessible via CP15); systems with an external L2
+ * cache controller such as a PL310 need separate calls to that device driver
+ * to affect L2 caches.  This is not a factor during early kernel startup, as
+ * any external L2 cache controller has not been enabled yet.
+ */
+
+/* Invalidate D cache to PoC. (aka all cache levels)*/
+ASENTRY_NP(dcache_inv_poc_all)
+#if __ARM_ARCH == 6
+	mcr	CP15_DCIALL
+	DSB
+	bx	lr
+#else
+	mrc	CP15_CLIDR(r0)
+	ands	r0, r0, #0x07000000
+	mov	r0, r0, lsr #23		/* Get LoC 'naturally' aligned for */
+	beq	4f			/* use in the CSSELR register below */
+
+1:	sub	r0, #2
+	mcr	CP15_CSSELR(r0)		/* set cache level */
+	isb
+	mrc	CP15_CCSIDR(r0)		/* read CCSIDR */
+
+	ubfx	r2, r0, #13, #15	/* get num sets - 1 from CCSIDR */
+	ubfx	r3, r0, #3, #10		/* get num ways - 1 from CCSIDR */
+	clz	r1, r3			/* number of bits to MSB of way */
+	lsl	r3, r3, r1		/* shift into position  */
+	mov	ip, #1
+	lsl	ip, ip, r1		/* ip now contains the way decr  */
+
+	ubfx	r0, r0, #0, #3		/* get linesize from CCSIDR  */
+	add	r0, r0, #4		/* apply bias  */
+	lsl	r2, r2, r0		/* shift sets by log2(linesize)  */
+	add	r3, r3, r2		/* merge numsets - 1 with numways - 1 */
+	sub	ip, ip, r2		/* subtract numsets - 1 from way decr */
+	mov	r1, #1
+	lsl	r1, r1, r0		/* r1 now contains the set decr */
+	mov	r2, ip			/* r2 now contains set way decr */
+
+	/* r3 = ways/sets, r2 = way decr, r1 = set decr, r0 and ip are free */
+2:	mcr	CP15_DCISW(r3)		/* invalidate line */
+	movs	r0, r3			/* get current way/set */
+	beq	3f			/* at 0 means we are done */
+	movs	r0, r0, lsl #10		/* clear way bits leaving only set bits*/
+	subne	r3, r3, r1		/* non-zero?, decrement set */
+	subeq	r3, r3, r2		/* zero?, decrement way  and restore set count */
+	b	2b
+
+3:
+	mrc	CP15_CSSELR(r0)		/* get cache level */
+	teq	r0, #0
+	bne	1b
+
+4:	dsb				/* wait for stores to finish */
+	mov	r0, #0
+	mcr	CP15_CSSELR(r0)
+	isb
+	bx	lr
+#endif /* __ARM_ARCH == 6 */
+END(dcache_inv_poc_all)
+
+/* Invalidate D cache to PoU. (aka L1 cache only)*/
+ASENTRY_NP(dcache_inv_pou_all)
+#if __ARM_ARCH == 6
+	mcr	CP15_DCIALL
+	DSB
+	bx	lr
+#else
+	mrc	CP15_CLIDR(r0)
+	ands	r0, r0, #0x38000000
+	mov	r0, r0, lsr #26		/* Get LoUU (naturally aligned) */
+	beq	4f
+
+1:	sub	r0, #2
+	mcr	CP15_CSSELR(r0)		/* set cache level */
+	isb
+	mrc	CP15_CCSIDR(r0)		/* read CCSIDR */
+
+	ubfx	r2, r0, #13, #15	/* get num sets - 1 from CCSIDR */
+	ubfx	r3, r0, #3, #10		/* get num ways - 1 from CCSIDR */
+	clz	r1, r3			/* number of bits to MSB of way */
+	lsl	r3, r3, r1		/* shift into position  */
+	mov	ip, #1
+	lsl	ip, ip, r1		/* ip now contains the way decr  */
+
+	ubfx	r0, r0, #0, #3		/* get linesize from CCSIDR  */
+	add	r0, r0, #4		/* apply bias  */
+	lsl	r2, r2, r0		/* shift sets by log2(linesize)  */
+	add	r3, r3, r2		/* merge numsets - 1 with numways - 1 */
+	sub	ip, ip, r2		/* subtract numsets - 1 from way decr */
+	mov	r1, #1
+	lsl	r1, r1, r0		/* r1 now contains the set decr */
+	mov	r2, ip			/* r2 now contains set way decr */
+
+	/* r3 = ways/sets, r2 = way decr, r1 = set decr, r0 and ip are free */
+2:	mcr	CP15_DCISW(r3)		/* invalidate line */
+	movs	r0, r3			/* get current way/set */
+	beq	3f			/* at 0 means we are done */
+	movs	r0, r0, lsl #10		/* clear way bits leaving only set bits*/
+	subne	r3, r3, r1		/* non-zero?, decrement set */
+	subeq	r3, r3, r2		/* zero?, decrement way  and restore set count */
+	b	2b
+
+3:
+	mrc	CP15_CSSELR(r0)		/* get cache level */
+	teq	r0, #0
+	bne	1b
+
+4:	dsb				/* wait for stores to finish */
+	mov	r0, #0
+	mcr	CP15_CSSELR(r0)
+	bx	lr
+#endif
+END(dcache_inv_pou_all)
+
+/* Write back and Invalidate D cache to PoC. */
+ASENTRY_NP(dcache_wbinv_poc_all)
+#if __ARM_ARCH == 6
+	mcr	CP15_DCCIALL
+	DSB
+	bx	lr
+#else
+	mrc	CP15_CLIDR(r0)
+	ands	r0, r0, #0x07000000
+	beq	4f
+	mov	r0, #0			/* Clean from inner to outer levels */
+
+1:	mcr	CP15_CSSELR(r0)		/* set cache level */
+	isb
+	mrc	CP15_CCSIDR(r0)		/* read CCSIDR */
+
+	ubfx	r2, r0, #13, #15	/* get num sets - 1 from CCSIDR */
+	ubfx	r3, r0, #3, #10		/* get num ways - 1 from CCSIDR */
+	clz	r1, r3			/* number of bits to MSB of way */
+	lsl	r3, r3, r1		/* shift into position  */
+	mov	ip, #1
+	lsl	ip, ip, r1		/* ip now contains the way decr  */
+
+	ubfx	r0, r0, #0, #3		/* get linesize from CCSIDR  */
+	add	r0, r0, #4		/* apply bias  */
+	lsl	r2, r2, r0		/* shift sets by log2(linesize)  */
+	add	r3, r3, r2		/* merge numsets - 1 with numways - 1 */
+	sub	ip, ip, r2		/* subtract numsets - 1 from way decr */
+	mov	r1, #1
+	lsl	r1, r1, r0		/* r1 now contains the set decr */
+	mov	r2, ip			/* r2 now contains set way decr */
+
+	/* r3 = ways/sets, r2 = way decr, r1 = set decr, r0 and ip are free */
+2:	mcr	CP15_DCCISW(r3)		/* clean and invalidate line */
+	movs	r0, r3			/* get current way/set */
+	beq	3f			/* at 0 means we are done */
+	movs	r0, r0, lsl #10		/* clear way bits leaving only set bits*/
+	subne	r3, r3, r1		/* non-zero?, decrement set */
+	subeq	r3, r3, r2		/* zero?, decrement way  and restore set count */
+	b	2b
+
+3:
+	mrc	CP15_CSSELR(r0)		/* get cache level */
+	add	r0, r0, #2		/* next level */
+	mrc	CP15_CLIDR(r1)
+	ands	r1, r1, #0x07000000
+	mov	r1, r1, lsr #23		/* Get LoC (naturally aligned) */
+	cmp 	r1, r0
+	bne	1b
+
+4:	dsb				/* wait for stores to finish */
+	mov	r0, #0
+	mcr	CP15_CSSELR(r0)
+	bx	lr
+#endif /* __ARM_ARCH == 6 */
+END(dcache_wbinv_poc_all)


Property changes on: trunk/sys/arm/arm/cpu_asm-v6.S
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/cpufunc.c
===================================================================
--- trunk/sys/arm/arm/cpufunc.c	                        (rev 0)
+++ trunk/sys/arm/arm/cpufunc.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,1796 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: cpufunc.c,v 1.65 2003/11/05 12:53:15 scw Exp $	*/
+
+/*-
+ * arm9 support code Copyright (C) 2001 ARM Ltd
+ * Copyright (c) 1997 Mark Brinicombe.
+ * Copyright (c) 1997 Causality Limited
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Causality Limited.
+ * 4. The name of Causality Limited may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY CAUSALITY LIMITED ``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 CAUSALITY LIMITED 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.
+ *
+ * RiscBSD kernel project
+ *
+ * cpufuncs.c
+ *
+ * C functions for supporting CPU / MMU / TLB specific operations.
+ *
+ * Created      : 30/01/97
+ */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/cpufunc.c 283335 2015-05-23 22:48:54Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/bus.h>
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/disassem.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/uma.h>
+
+#include <machine/cpuconf.h>
+#include <machine/cpufunc.h>
+#include <machine/bootconfig.h>
+
+#ifdef CPU_XSCALE_80200
+#include <arm/xscale/i80200/i80200reg.h>
+#include <arm/xscale/i80200/i80200var.h>
+#endif
+
+#if defined(CPU_XSCALE_80321) || defined(CPU_XSCALE_80219)
+#include <arm/xscale/i80321/i80321reg.h>
+#include <arm/xscale/i80321/i80321var.h>
+#endif
+
+/*
+ * Some definitions in i81342reg.h clash with i80321reg.h.
+ * This only happens for the LINT kernel. As it happens,
+ * we don't need anything from i81342reg.h that we already
+ * got from somewhere else during a LINT compile.
+ */
+#if defined(CPU_XSCALE_81342) && !defined(COMPILING_LINT)
+#include <arm/xscale/i8134x/i81342reg.h>
+#endif
+
+#ifdef CPU_XSCALE_IXP425
+#include <arm/xscale/ixp425/ixp425reg.h>
+#include <arm/xscale/ixp425/ixp425var.h>
+#endif
+
+/* PRIMARY CACHE VARIABLES */
+int	arm_picache_size;
+int	arm_picache_line_size;
+int	arm_picache_ways;
+
+int	arm_pdcache_size;	/* and unified */
+int	arm_pdcache_line_size;
+int	arm_pdcache_ways;
+
+int	arm_pcache_type;
+int	arm_pcache_unified;
+
+int	arm_dcache_align;
+int	arm_dcache_align_mask;
+
+u_int	arm_cache_level;
+u_int	arm_cache_type[14];
+u_int	arm_cache_loc;
+
+/* 1 == use cpu_sleep(), 0 == don't */
+int cpu_do_powersave;
+int ctrl;
+
+#ifdef CPU_ARM9
+struct cpu_functions arm9_cpufuncs = {
+	/* CPU functions */
+
+	cpufunc_id,			/* id			*/
+	cpufunc_nullop,			/* cpwait		*/
+
+	/* MMU functions */
+
+	cpufunc_control,		/* control		*/
+	cpufunc_domains,		/* Domain		*/
+	arm9_setttb,			/* Setttb		*/
+	cpufunc_faultstatus,		/* Faultstatus		*/
+	cpufunc_faultaddress,		/* Faultaddress		*/
+
+	/* TLB functions */
+
+	armv4_tlb_flushID,		/* tlb_flushID		*/
+	arm9_tlb_flushID_SE,		/* tlb_flushID_SE	*/
+	armv4_tlb_flushI,		/* tlb_flushI		*/
+	(void *)armv4_tlb_flushI,	/* tlb_flushI_SE	*/
+	armv4_tlb_flushD,		/* tlb_flushD		*/
+	armv4_tlb_flushD_SE,		/* tlb_flushD_SE	*/
+
+	/* Cache operations */
+
+	arm9_icache_sync_all,		/* icache_sync_all	*/
+	arm9_icache_sync_range,		/* icache_sync_range	*/
+
+	arm9_dcache_wbinv_all,		/* dcache_wbinv_all	*/
+	arm9_dcache_wbinv_range,	/* dcache_wbinv_range	*/
+	arm9_dcache_inv_range,		/* dcache_inv_range	*/
+	arm9_dcache_wb_range,		/* dcache_wb_range	*/
+
+	armv4_idcache_inv_all,		/* idcache_inv_all	*/
+	arm9_idcache_wbinv_all,		/* idcache_wbinv_all	*/
+	arm9_idcache_wbinv_range,	/* idcache_wbinv_range	*/
+	cpufunc_nullop,			/* l2cache_wbinv_all	*/
+	(void *)cpufunc_nullop,		/* l2cache_wbinv_range	*/
+	(void *)cpufunc_nullop,		/* l2cache_inv_range	*/
+	(void *)cpufunc_nullop,		/* l2cache_wb_range	*/
+	(void *)cpufunc_nullop,         /* l2cache_drain_writebuf */
+
+	/* Other functions */
+
+	cpufunc_nullop,			/* flush_prefetchbuf	*/
+	armv4_drain_writebuf,		/* drain_writebuf	*/
+	cpufunc_nullop,			/* flush_brnchtgt_C	*/
+	(void *)cpufunc_nullop,		/* flush_brnchtgt_E	*/
+
+	(void *)cpufunc_nullop,		/* sleep		*/
+
+	/* Soft functions */
+
+	cpufunc_null_fixup,		/* dataabt_fixup	*/
+	cpufunc_null_fixup,		/* prefetchabt_fixup	*/
+
+	arm9_context_switch,		/* context_switch	*/
+
+	arm9_setup			/* cpu setup		*/
+
+};
+#endif /* CPU_ARM9 */
+
+#if defined(CPU_ARM9E) || defined(CPU_ARM10)
+struct cpu_functions armv5_ec_cpufuncs = {
+	/* CPU functions */
+
+	cpufunc_id,			/* id			*/
+	cpufunc_nullop,			/* cpwait		*/
+
+	/* MMU functions */
+
+	cpufunc_control,		/* control		*/
+	cpufunc_domains,		/* Domain		*/
+	armv5_ec_setttb,		/* Setttb		*/
+	cpufunc_faultstatus,		/* Faultstatus		*/
+	cpufunc_faultaddress,		/* Faultaddress		*/
+
+	/* TLB functions */
+
+	armv4_tlb_flushID,		/* tlb_flushID		*/
+	arm10_tlb_flushID_SE,		/* tlb_flushID_SE	*/
+	armv4_tlb_flushI,		/* tlb_flushI		*/
+	arm10_tlb_flushI_SE,		/* tlb_flushI_SE	*/
+	armv4_tlb_flushD,		/* tlb_flushD		*/
+	armv4_tlb_flushD_SE,		/* tlb_flushD_SE	*/
+
+	/* Cache operations */
+
+	armv5_ec_icache_sync_all,	/* icache_sync_all	*/
+	armv5_ec_icache_sync_range,	/* icache_sync_range	*/
+
+	armv5_ec_dcache_wbinv_all,	/* dcache_wbinv_all	*/
+	armv5_ec_dcache_wbinv_range,	/* dcache_wbinv_range	*/
+	armv5_ec_dcache_inv_range,	/* dcache_inv_range	*/
+	armv5_ec_dcache_wb_range,	/* dcache_wb_range	*/
+
+	armv4_idcache_inv_all,		/* idcache_inv_all	*/
+	armv5_ec_idcache_wbinv_all,	/* idcache_wbinv_all	*/
+	armv5_ec_idcache_wbinv_range,	/* idcache_wbinv_range	*/
+
+	cpufunc_nullop,                 /* l2cache_wbinv_all    */
+	(void *)cpufunc_nullop,         /* l2cache_wbinv_range  */
+      	(void *)cpufunc_nullop,         /* l2cache_inv_range    */
+	(void *)cpufunc_nullop,         /* l2cache_wb_range     */
+	(void *)cpufunc_nullop,         /* l2cache_drain_writebuf */
+
+	/* Other functions */
+
+	cpufunc_nullop,			/* flush_prefetchbuf	*/
+	armv4_drain_writebuf,		/* drain_writebuf	*/
+	cpufunc_nullop,			/* flush_brnchtgt_C	*/
+	(void *)cpufunc_nullop,		/* flush_brnchtgt_E	*/
+
+	(void *)cpufunc_nullop,		/* sleep		*/
+
+	/* Soft functions */
+
+	cpufunc_null_fixup,		/* dataabt_fixup	*/
+	cpufunc_null_fixup,		/* prefetchabt_fixup	*/
+
+	arm10_context_switch,		/* context_switch	*/
+
+	arm10_setup			/* cpu setup		*/
+
+};
+
+struct cpu_functions sheeva_cpufuncs = {
+	/* CPU functions */
+
+	cpufunc_id,			/* id			*/
+	cpufunc_nullop,			/* cpwait		*/
+
+	/* MMU functions */
+
+	cpufunc_control,		/* control		*/
+	cpufunc_domains,		/* Domain		*/
+	sheeva_setttb,			/* Setttb		*/
+	cpufunc_faultstatus,		/* Faultstatus		*/
+	cpufunc_faultaddress,		/* Faultaddress		*/
+
+	/* TLB functions */
+
+	armv4_tlb_flushID,		/* tlb_flushID		*/
+	arm10_tlb_flushID_SE,		/* tlb_flushID_SE	*/
+	armv4_tlb_flushI,		/* tlb_flushI		*/
+	arm10_tlb_flushI_SE,		/* tlb_flushI_SE	*/
+	armv4_tlb_flushD,		/* tlb_flushD		*/
+	armv4_tlb_flushD_SE,		/* tlb_flushD_SE	*/
+
+	/* Cache operations */
+
+	armv5_ec_icache_sync_all,	/* icache_sync_all	*/
+	armv5_ec_icache_sync_range,	/* icache_sync_range	*/
+
+	armv5_ec_dcache_wbinv_all,	/* dcache_wbinv_all	*/
+	sheeva_dcache_wbinv_range,	/* dcache_wbinv_range	*/
+	sheeva_dcache_inv_range,	/* dcache_inv_range	*/
+	sheeva_dcache_wb_range,		/* dcache_wb_range	*/
+
+	armv4_idcache_inv_all,		/* idcache_inv_all	*/
+	armv5_ec_idcache_wbinv_all,	/* idcache_wbinv_all	*/
+	sheeva_idcache_wbinv_range,	/* idcache_wbinv_all	*/
+
+	sheeva_l2cache_wbinv_all,	/* l2cache_wbinv_all    */
+	sheeva_l2cache_wbinv_range,	/* l2cache_wbinv_range  */
+	sheeva_l2cache_inv_range,	/* l2cache_inv_range    */
+	sheeva_l2cache_wb_range,	/* l2cache_wb_range     */
+	(void *)cpufunc_nullop,         /* l2cache_drain_writebuf */
+
+	/* Other functions */
+
+	cpufunc_nullop,			/* flush_prefetchbuf	*/
+	armv4_drain_writebuf,		/* drain_writebuf	*/
+	cpufunc_nullop,			/* flush_brnchtgt_C	*/
+	(void *)cpufunc_nullop,		/* flush_brnchtgt_E	*/
+
+	sheeva_cpu_sleep,		/* sleep		*/
+
+	/* Soft functions */
+
+	cpufunc_null_fixup,		/* dataabt_fixup	*/
+	cpufunc_null_fixup,		/* prefetchabt_fixup	*/
+
+	arm10_context_switch,		/* context_switch	*/
+
+	arm10_setup			/* cpu setup		*/
+};
+#endif /* CPU_ARM9E || CPU_ARM10 */
+
+#ifdef CPU_ARM10
+struct cpu_functions arm10_cpufuncs = {
+	/* CPU functions */
+
+	cpufunc_id,			/* id			*/
+	cpufunc_nullop,			/* cpwait		*/
+
+	/* MMU functions */
+
+	cpufunc_control,		/* control		*/
+	cpufunc_domains,		/* Domain		*/
+	arm10_setttb,			/* Setttb		*/
+	cpufunc_faultstatus,		/* Faultstatus		*/
+	cpufunc_faultaddress,		/* Faultaddress		*/
+
+	/* TLB functions */
+
+	armv4_tlb_flushID,		/* tlb_flushID		*/
+	arm10_tlb_flushID_SE,		/* tlb_flushID_SE	*/
+	armv4_tlb_flushI,		/* tlb_flushI		*/
+	arm10_tlb_flushI_SE,		/* tlb_flushI_SE	*/
+	armv4_tlb_flushD,		/* tlb_flushD		*/
+	armv4_tlb_flushD_SE,		/* tlb_flushD_SE	*/
+
+	/* Cache operations */
+
+	arm10_icache_sync_all,		/* icache_sync_all	*/
+	arm10_icache_sync_range,	/* icache_sync_range	*/
+
+	arm10_dcache_wbinv_all,		/* dcache_wbinv_all	*/
+	arm10_dcache_wbinv_range,	/* dcache_wbinv_range	*/
+	arm10_dcache_inv_range,		/* dcache_inv_range	*/
+	arm10_dcache_wb_range,		/* dcache_wb_range	*/
+
+	armv4_idcache_inv_all,		/* idcache_inv_all	*/
+	arm10_idcache_wbinv_all,	/* idcache_wbinv_all	*/
+	arm10_idcache_wbinv_range,	/* idcache_wbinv_range	*/
+	cpufunc_nullop,			/* l2cache_wbinv_all	*/
+	(void *)cpufunc_nullop,		/* l2cache_wbinv_range	*/
+	(void *)cpufunc_nullop,		/* l2cache_inv_range	*/
+	(void *)cpufunc_nullop,		/* l2cache_wb_range	*/
+	(void *)cpufunc_nullop,         /* l2cache_drain_writebuf */
+
+	/* Other functions */
+
+	cpufunc_nullop,			/* flush_prefetchbuf	*/
+	armv4_drain_writebuf,		/* drain_writebuf	*/
+	cpufunc_nullop,			/* flush_brnchtgt_C	*/
+	(void *)cpufunc_nullop,		/* flush_brnchtgt_E	*/
+
+	(void *)cpufunc_nullop,		/* sleep		*/
+
+	/* Soft functions */
+
+	cpufunc_null_fixup,		/* dataabt_fixup	*/
+	cpufunc_null_fixup,		/* prefetchabt_fixup	*/
+
+	arm10_context_switch,		/* context_switch	*/
+
+	arm10_setup			/* cpu setup		*/
+
+};
+#endif /* CPU_ARM10 */
+
+#ifdef CPU_MV_PJ4B
+struct cpu_functions pj4bv7_cpufuncs = {
+	/* CPU functions */
+
+	cpufunc_id,			/* id			*/
+	arm11_drain_writebuf,		/* cpwait		*/
+
+	/* MMU functions */
+
+	cpufunc_control,		/* control		*/
+	cpufunc_domains,		/* Domain		*/
+	pj4b_setttb,			/* Setttb		*/
+	cpufunc_faultstatus,		/* Faultstatus		*/
+	cpufunc_faultaddress,		/* Faultaddress		*/
+
+	/* TLB functions */
+
+	armv7_tlb_flushID,		/* tlb_flushID		*/
+	armv7_tlb_flushID_SE,		/* tlb_flushID_SE	*/
+	armv7_tlb_flushID,		/* tlb_flushI		*/
+	armv7_tlb_flushID_SE,		/* tlb_flushI_SE	*/
+	armv7_tlb_flushID,		/* tlb_flushD		*/
+	armv7_tlb_flushID_SE,		/* tlb_flushD_SE	*/
+
+	/* Cache operations */
+	armv7_idcache_wbinv_all,	/* icache_sync_all	*/
+	armv7_icache_sync_range,	/* icache_sync_range	*/
+
+	armv7_dcache_wbinv_all,		/* dcache_wbinv_all	*/
+	armv7_dcache_wbinv_range,	/* dcache_wbinv_range	*/
+	armv7_dcache_inv_range,		/* dcache_inv_range	*/
+	armv7_dcache_wb_range,		/* dcache_wb_range	*/
+
+	armv7_idcache_inv_all,		/* idcache_inv_all	*/
+	armv7_idcache_wbinv_all,	/* idcache_wbinv_all	*/
+	armv7_idcache_wbinv_range,	/* idcache_wbinv_all	*/
+
+	(void *)cpufunc_nullop,		/* l2cache_wbinv_all	*/
+	(void *)cpufunc_nullop,		/* l2cache_wbinv_range	*/
+	(void *)cpufunc_nullop,		/* l2cache_inv_range	*/
+	(void *)cpufunc_nullop,		/* l2cache_wb_range	*/
+	(void *)cpufunc_nullop,         /* l2cache_drain_writebuf */
+
+	/* Other functions */
+
+	pj4b_drain_readbuf,		/* flush_prefetchbuf	*/
+	arm11_drain_writebuf,		/* drain_writebuf	*/
+	pj4b_flush_brnchtgt_all,	/* flush_brnchtgt_C	*/
+	pj4b_flush_brnchtgt_va,		/* flush_brnchtgt_E	*/
+
+	(void *)cpufunc_nullop,		/* sleep		*/
+
+	/* Soft functions */
+
+	cpufunc_null_fixup,		/* dataabt_fixup	*/
+	cpufunc_null_fixup,		/* prefetchabt_fixup	*/
+
+	arm11_context_switch,		/* context_switch	*/
+
+	pj4bv7_setup			/* cpu setup		*/
+};
+#endif /* CPU_MV_PJ4B */
+
+#if defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) || \
+  defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) || \
+  defined(CPU_XSCALE_80219)
+
+struct cpu_functions xscale_cpufuncs = {
+	/* CPU functions */
+	
+	cpufunc_id,			/* id			*/
+	xscale_cpwait,			/* cpwait		*/
+
+	/* MMU functions */
+
+	xscale_control,			/* control		*/
+	cpufunc_domains,		/* domain		*/
+	xscale_setttb,			/* setttb		*/
+	cpufunc_faultstatus,		/* faultstatus		*/
+	cpufunc_faultaddress,		/* faultaddress		*/
+
+	/* TLB functions */
+
+	armv4_tlb_flushID,		/* tlb_flushID		*/
+	xscale_tlb_flushID_SE,		/* tlb_flushID_SE	*/
+	armv4_tlb_flushI,		/* tlb_flushI		*/
+	(void *)armv4_tlb_flushI,	/* tlb_flushI_SE	*/
+	armv4_tlb_flushD,		/* tlb_flushD		*/
+	armv4_tlb_flushD_SE,		/* tlb_flushD_SE	*/
+
+	/* Cache operations */
+
+	xscale_cache_syncI,		/* icache_sync_all	*/
+	xscale_cache_syncI_rng,		/* icache_sync_range	*/
+
+	xscale_cache_purgeD,		/* dcache_wbinv_all	*/
+	xscale_cache_purgeD_rng,	/* dcache_wbinv_range	*/
+	xscale_cache_flushD_rng,	/* dcache_inv_range	*/
+	xscale_cache_cleanD_rng,	/* dcache_wb_range	*/
+
+	xscale_cache_flushID,		/* idcache_inv_all	*/
+	xscale_cache_purgeID,		/* idcache_wbinv_all	*/
+	xscale_cache_purgeID_rng,	/* idcache_wbinv_range	*/
+	cpufunc_nullop,			/* l2cache_wbinv_all 	*/
+	(void *)cpufunc_nullop,		/* l2cache_wbinv_range	*/
+	(void *)cpufunc_nullop,		/* l2cache_inv_range	*/
+	(void *)cpufunc_nullop,		/* l2cache_wb_range	*/
+	(void *)cpufunc_nullop,         /* l2cache_drain_writebuf */
+
+	/* Other functions */
+
+	cpufunc_nullop,			/* flush_prefetchbuf	*/
+	armv4_drain_writebuf,		/* drain_writebuf	*/
+	cpufunc_nullop,			/* flush_brnchtgt_C	*/
+	(void *)cpufunc_nullop,		/* flush_brnchtgt_E	*/
+
+	xscale_cpu_sleep,		/* sleep		*/
+
+	/* Soft functions */
+
+	cpufunc_null_fixup,		/* dataabt_fixup	*/
+	cpufunc_null_fixup,		/* prefetchabt_fixup	*/
+
+	xscale_context_switch,		/* context_switch	*/
+
+	xscale_setup			/* cpu setup		*/
+};
+#endif
+/* CPU_XSCALE_80200 || CPU_XSCALE_80321 || CPU_XSCALE_PXA2X0 || CPU_XSCALE_IXP425
+   CPU_XSCALE_80219 */
+
+#ifdef CPU_XSCALE_81342
+struct cpu_functions xscalec3_cpufuncs = {
+	/* CPU functions */
+	
+	cpufunc_id,			/* id			*/
+	xscale_cpwait,			/* cpwait		*/
+
+	/* MMU functions */
+
+	xscale_control,			/* control		*/
+	cpufunc_domains,		/* domain		*/
+	xscalec3_setttb,		/* setttb		*/
+	cpufunc_faultstatus,		/* faultstatus		*/
+	cpufunc_faultaddress,		/* faultaddress		*/
+
+	/* TLB functions */
+
+	armv4_tlb_flushID,		/* tlb_flushID		*/
+	xscale_tlb_flushID_SE,		/* tlb_flushID_SE	*/
+	armv4_tlb_flushI,		/* tlb_flushI		*/
+	(void *)armv4_tlb_flushI,	/* tlb_flushI_SE	*/
+	armv4_tlb_flushD,		/* tlb_flushD		*/
+	armv4_tlb_flushD_SE,		/* tlb_flushD_SE	*/
+
+	/* Cache operations */
+
+	xscalec3_cache_syncI,		/* icache_sync_all	*/
+	xscalec3_cache_syncI_rng,	/* icache_sync_range	*/
+
+	xscalec3_cache_purgeD,		/* dcache_wbinv_all	*/
+	xscalec3_cache_purgeD_rng,	/* dcache_wbinv_range	*/
+	xscale_cache_flushD_rng,	/* dcache_inv_range	*/
+	xscalec3_cache_cleanD_rng,	/* dcache_wb_range	*/
+
+	xscale_cache_flushID,		/* idcache_inv_all	*/
+	xscalec3_cache_purgeID,		/* idcache_wbinv_all	*/
+	xscalec3_cache_purgeID_rng,	/* idcache_wbinv_range	*/
+	xscalec3_l2cache_purge,		/* l2cache_wbinv_all	*/
+	xscalec3_l2cache_purge_rng,	/* l2cache_wbinv_range	*/
+	xscalec3_l2cache_flush_rng,	/* l2cache_inv_range	*/
+	xscalec3_l2cache_clean_rng,	/* l2cache_wb_range	*/
+	(void *)cpufunc_nullop,         /* l2cache_drain_writebuf */
+
+	/* Other functions */
+
+	cpufunc_nullop,			/* flush_prefetchbuf	*/
+	armv4_drain_writebuf,		/* drain_writebuf	*/
+	cpufunc_nullop,			/* flush_brnchtgt_C	*/
+	(void *)cpufunc_nullop,		/* flush_brnchtgt_E	*/
+
+	xscale_cpu_sleep,		/* sleep		*/
+
+	/* Soft functions */
+
+	cpufunc_null_fixup,		/* dataabt_fixup	*/
+	cpufunc_null_fixup,		/* prefetchabt_fixup	*/
+
+	xscalec3_context_switch,	/* context_switch	*/
+
+	xscale_setup			/* cpu setup		*/
+};
+#endif /* CPU_XSCALE_81342 */
+
+
+#if defined(CPU_FA526) || defined(CPU_FA626TE)
+struct cpu_functions fa526_cpufuncs = {
+	/* CPU functions */
+
+	cpufunc_id,			/* id			*/
+	cpufunc_nullop,			/* cpwait		*/
+
+	/* MMU functions */
+
+	cpufunc_control,		/* control		*/
+	cpufunc_domains,		/* domain		*/
+	fa526_setttb,			/* setttb		*/
+	cpufunc_faultstatus,		/* faultstatus		*/
+	cpufunc_faultaddress,		/* faultaddress		*/
+
+	/* TLB functions */
+
+	armv4_tlb_flushID,		/* tlb_flushID		*/
+	fa526_tlb_flushID_SE,		/* tlb_flushID_SE	*/
+	armv4_tlb_flushI,		/* tlb_flushI		*/
+	fa526_tlb_flushI_SE,		/* tlb_flushI_SE	*/
+	armv4_tlb_flushD,		/* tlb_flushD		*/
+	armv4_tlb_flushD_SE,		/* tlb_flushD_SE	*/
+
+	/* Cache operations */
+
+	fa526_icache_sync_all,		/* icache_sync_all	*/
+	fa526_icache_sync_range,	/* icache_sync_range	*/
+
+	fa526_dcache_wbinv_all,		/* dcache_wbinv_all	*/
+	fa526_dcache_wbinv_range,	/* dcache_wbinv_range	*/
+	fa526_dcache_inv_range,		/* dcache_inv_range	*/
+	fa526_dcache_wb_range,		/* dcache_wb_range	*/
+
+	armv4_idcache_inv_all,		/* idcache_inv_all	*/
+	fa526_idcache_wbinv_all,	/* idcache_wbinv_all	*/
+	fa526_idcache_wbinv_range,	/* idcache_wbinv_range	*/
+	cpufunc_nullop,			/* l2cache_wbinv_all	*/
+	(void *)cpufunc_nullop,		/* l2cache_wbinv_range	*/
+	(void *)cpufunc_nullop,		/* l2cache_inv_range	*/
+	(void *)cpufunc_nullop,		/* l2cache_wb_range	*/
+	(void *)cpufunc_nullop,         /* l2cache_drain_writebuf */
+
+	/* Other functions */
+
+	fa526_flush_prefetchbuf,	/* flush_prefetchbuf	*/
+	armv4_drain_writebuf,		/* drain_writebuf	*/
+	cpufunc_nullop,			/* flush_brnchtgt_C	*/
+	fa526_flush_brnchtgt_E,		/* flush_brnchtgt_E	*/
+
+	fa526_cpu_sleep,		/* sleep		*/
+
+	/* Soft functions */
+
+	cpufunc_null_fixup,		/* dataabt_fixup	*/
+	cpufunc_null_fixup,		/* prefetchabt_fixup	*/
+
+	fa526_context_switch,		/* context_switch	*/
+
+	fa526_setup			/* cpu setup 		*/
+};
+#endif	/* CPU_FA526 || CPU_FA626TE */
+
+#if defined(CPU_ARM1136)
+struct cpu_functions arm1136_cpufuncs = {
+	/* CPU functions */
+	
+	cpufunc_id,                     /* id                   */
+	cpufunc_nullop,                 /* cpwait               */
+	
+	/* MMU functions */
+	
+	cpufunc_control,                /* control              */
+	cpufunc_domains,                /* Domain               */
+	arm11x6_setttb,                 /* Setttb               */
+	cpufunc_faultstatus,            /* Faultstatus          */
+	cpufunc_faultaddress,           /* Faultaddress         */
+	
+	/* TLB functions */
+	
+	arm11_tlb_flushID,              /* tlb_flushID          */
+	arm11_tlb_flushID_SE,           /* tlb_flushID_SE       */
+	arm11_tlb_flushI,               /* tlb_flushI           */
+	arm11_tlb_flushI_SE,            /* tlb_flushI_SE        */
+	arm11_tlb_flushD,               /* tlb_flushD           */
+	arm11_tlb_flushD_SE,            /* tlb_flushD_SE        */
+	
+	/* Cache operations */
+	
+	arm11x6_icache_sync_all,        /* icache_sync_all      */
+	arm11x6_icache_sync_range,      /* icache_sync_range    */
+	
+	arm11x6_dcache_wbinv_all,       /* dcache_wbinv_all     */
+	armv6_dcache_wbinv_range,       /* dcache_wbinv_range   */
+	armv6_dcache_inv_range,         /* dcache_inv_range     */
+	armv6_dcache_wb_range,          /* dcache_wb_range      */
+	
+	armv6_idcache_inv_all,		/* idcache_inv_all	*/
+	arm11x6_idcache_wbinv_all,      /* idcache_wbinv_all    */
+	arm11x6_idcache_wbinv_range,    /* idcache_wbinv_range  */
+	
+	(void *)cpufunc_nullop,         /* l2cache_wbinv_all    */
+	(void *)cpufunc_nullop,         /* l2cache_wbinv_range  */
+	(void *)cpufunc_nullop,         /* l2cache_inv_range    */
+	(void *)cpufunc_nullop,         /* l2cache_wb_range     */
+	(void *)cpufunc_nullop,         /* l2cache_drain_writebuf */
+	
+	/* Other functions */
+	
+	arm11x6_flush_prefetchbuf,      /* flush_prefetchbuf    */
+	arm11_drain_writebuf,           /* drain_writebuf       */
+	cpufunc_nullop,                 /* flush_brnchtgt_C     */
+	(void *)cpufunc_nullop,         /* flush_brnchtgt_E     */
+	
+	arm11_sleep,                  	/* sleep                */
+	
+	/* Soft functions */
+	
+	cpufunc_null_fixup,             /* dataabt_fixup        */
+	cpufunc_null_fixup,             /* prefetchabt_fixup    */
+	
+	arm11_context_switch,           /* context_switch       */
+	
+	arm11x6_setup                   /* cpu setup            */
+};
+#endif /* CPU_ARM1136 */
+#if defined(CPU_ARM1176)
+struct cpu_functions arm1176_cpufuncs = {
+	/* CPU functions */
+	
+	cpufunc_id,                     /* id                   */
+	cpufunc_nullop,                 /* cpwait               */
+	
+	/* MMU functions */
+	
+	cpufunc_control,                /* control              */
+	cpufunc_domains,                /* Domain               */
+	arm11x6_setttb,                 /* Setttb               */
+	cpufunc_faultstatus,            /* Faultstatus          */
+	cpufunc_faultaddress,           /* Faultaddress         */
+	
+	/* TLB functions */
+	
+	arm11_tlb_flushID,              /* tlb_flushID          */
+	arm11_tlb_flushID_SE,           /* tlb_flushID_SE       */
+	arm11_tlb_flushI,               /* tlb_flushI           */
+	arm11_tlb_flushI_SE,            /* tlb_flushI_SE        */
+	arm11_tlb_flushD,               /* tlb_flushD           */
+	arm11_tlb_flushD_SE,            /* tlb_flushD_SE        */
+	
+	/* Cache operations */
+	
+	arm11x6_icache_sync_all,        /* icache_sync_all      */
+	arm11x6_icache_sync_range,      /* icache_sync_range    */
+	
+	arm11x6_dcache_wbinv_all,       /* dcache_wbinv_all     */
+	armv6_dcache_wbinv_range,       /* dcache_wbinv_range   */
+	armv6_dcache_inv_range,         /* dcache_inv_range     */
+	armv6_dcache_wb_range,          /* dcache_wb_range      */
+	
+	armv6_idcache_inv_all,		/* idcache_inv_all	*/
+	arm11x6_idcache_wbinv_all,      /* idcache_wbinv_all    */
+	arm11x6_idcache_wbinv_range,    /* idcache_wbinv_range  */
+	
+	(void *)cpufunc_nullop,         /* l2cache_wbinv_all    */
+	(void *)cpufunc_nullop,         /* l2cache_wbinv_range  */
+	(void *)cpufunc_nullop,         /* l2cache_inv_range    */
+	(void *)cpufunc_nullop,         /* l2cache_wb_range     */
+	(void *)cpufunc_nullop,         /* l2cache_drain_writebuf */
+	
+	/* Other functions */
+	
+	arm11x6_flush_prefetchbuf,      /* flush_prefetchbuf    */
+	arm11_drain_writebuf,           /* drain_writebuf       */
+	cpufunc_nullop,                 /* flush_brnchtgt_C     */
+	(void *)cpufunc_nullop,         /* flush_brnchtgt_E     */
+	
+	arm11x6_sleep,                  /* sleep                */
+	
+	/* Soft functions */
+	
+	cpufunc_null_fixup,             /* dataabt_fixup        */
+	cpufunc_null_fixup,             /* prefetchabt_fixup    */
+	
+	arm11_context_switch,           /* context_switch       */
+	
+	arm11x6_setup                   /* cpu setup            */
+};
+#endif /*CPU_ARM1176 */
+
+#if defined(CPU_CORTEXA) || defined(CPU_KRAIT)
+struct cpu_functions cortexa_cpufuncs = {
+	/* CPU functions */
+	
+	cpufunc_id,                     /* id                   */
+	cpufunc_nullop,                 /* cpwait               */
+	
+	/* MMU functions */
+	
+	cpufunc_control,                /* control              */
+	cpufunc_domains,                /* Domain               */
+	armv7_setttb,                   /* Setttb               */
+	cpufunc_faultstatus,            /* Faultstatus          */
+	cpufunc_faultaddress,           /* Faultaddress         */
+	
+	/* 
+	 * TLB functions.  ARMv7 does all TLB ops based on a unified TLB model
+	 * whether the hardware implements separate I+D or not, so we use the
+	 * same 'ID' functions for all 3 variations.
+	 */
+	
+	armv7_tlb_flushID,              /* tlb_flushID          */
+	armv7_tlb_flushID_SE,           /* tlb_flushID_SE       */
+	armv7_tlb_flushID,              /* tlb_flushI           */
+	armv7_tlb_flushID_SE,           /* tlb_flushI_SE        */
+	armv7_tlb_flushID,              /* tlb_flushD           */
+	armv7_tlb_flushID_SE,           /* tlb_flushD_SE        */
+	
+	/* Cache operations */
+	
+	armv7_icache_sync_all, 	        /* icache_sync_all      */
+	armv7_icache_sync_range,        /* icache_sync_range    */
+	
+	armv7_dcache_wbinv_all,         /* dcache_wbinv_all     */
+	armv7_dcache_wbinv_range,       /* dcache_wbinv_range   */
+	armv7_dcache_inv_range,         /* dcache_inv_range     */
+	armv7_dcache_wb_range,          /* dcache_wb_range      */
+	
+	armv7_idcache_inv_all,		/* idcache_inv_all	*/
+	armv7_idcache_wbinv_all,        /* idcache_wbinv_all    */
+	armv7_idcache_wbinv_range,      /* idcache_wbinv_range  */
+	
+	/* 
+	 * Note: For CPUs using the PL310 the L2 ops are filled in when the
+	 * L2 cache controller is actually enabled.
+	 */
+	cpufunc_nullop,                 /* l2cache_wbinv_all    */
+	(void *)cpufunc_nullop,         /* l2cache_wbinv_range  */
+	(void *)cpufunc_nullop,         /* l2cache_inv_range    */
+	(void *)cpufunc_nullop,         /* l2cache_wb_range     */
+	(void *)cpufunc_nullop,         /* l2cache_drain_writebuf */
+	
+	/* Other functions */
+	
+	cpufunc_nullop,                 /* flush_prefetchbuf    */
+	armv7_drain_writebuf,           /* drain_writebuf       */
+	cpufunc_nullop,                 /* flush_brnchtgt_C     */
+	(void *)cpufunc_nullop,         /* flush_brnchtgt_E     */
+	
+	armv7_sleep,                    /* sleep                */
+	
+	/* Soft functions */
+	
+	cpufunc_null_fixup,             /* dataabt_fixup        */
+	cpufunc_null_fixup,             /* prefetchabt_fixup    */
+	
+	armv7_context_switch,           /* context_switch       */
+	
+	cortexa_setup                     /* cpu setup            */
+};
+#endif /* CPU_CORTEXA */
+
+/*
+ * Global constants also used by locore.s
+ */
+
+struct cpu_functions cpufuncs;
+u_int cputype;
+u_int cpu_reset_needs_v4_MMU_disable;	/* flag used in locore.s */
+
+#if defined(CPU_ARM9) ||	\
+  defined (CPU_ARM9E) || defined (CPU_ARM10) || defined (CPU_ARM1136) ||	\
+  defined(CPU_ARM1176) || defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) ||		\
+  defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) ||		\
+  defined(CPU_FA526) || defined(CPU_FA626TE) || defined(CPU_MV_PJ4B) ||			\
+  defined(CPU_XSCALE_80219) || defined(CPU_XSCALE_81342) || \
+  defined(CPU_CORTEXA) || defined(CPU_KRAIT)
+
+/* Global cache line sizes, use 32 as default */
+int	arm_dcache_min_line_size = 32;
+int	arm_icache_min_line_size = 32;
+int	arm_idcache_min_line_size = 32;
+
+static void get_cachetype_cp15(void);
+
+/* Additional cache information local to this file.  Log2 of some of the
+   above numbers.  */
+static int	arm_dcache_l2_nsets;
+static int	arm_dcache_l2_assoc;
+static int	arm_dcache_l2_linesize;
+
+static void
+get_cachetype_cp15()
+{
+	u_int ctype, isize, dsize, cpuid;
+	u_int clevel, csize, i, sel;
+	u_int multiplier;
+	u_char type;
+
+	__asm __volatile("mrc p15, 0, %0, c0, c0, 1"
+		: "=r" (ctype));
+
+	cpuid = cpufunc_id();
+	/*
+	 * ...and thus spake the ARM ARM:
+	 *
+	 * If an <opcode2> value corresponding to an unimplemented or
+	 * reserved ID register is encountered, the System Control
+	 * processor returns the value of the main ID register.
+	 */
+	if (ctype == cpuid)
+		goto out;
+
+	if (CPU_CT_FORMAT(ctype) == CPU_CT_ARMV7) {
+		/* Resolve minimal cache line sizes */
+		arm_dcache_min_line_size = 1 << (CPU_CT_DMINLINE(ctype) + 2);
+		arm_icache_min_line_size = 1 << (CPU_CT_IMINLINE(ctype) + 2);
+		arm_idcache_min_line_size =
+		    min(arm_icache_min_line_size, arm_dcache_min_line_size);
+
+		__asm __volatile("mrc p15, 1, %0, c0, c0, 1"
+		    : "=r" (clevel));
+		arm_cache_level = clevel;
+		arm_cache_loc = CPU_CLIDR_LOC(arm_cache_level);
+		i = 0;
+		while ((type = (clevel & 0x7)) && i < 7) {
+			if (type == CACHE_DCACHE || type == CACHE_UNI_CACHE ||
+			    type == CACHE_SEP_CACHE) {
+				sel = i << 1;
+				__asm __volatile("mcr p15, 2, %0, c0, c0, 0"
+				    : : "r" (sel));
+				__asm __volatile("mrc p15, 1, %0, c0, c0, 0"
+				    : "=r" (csize));
+				arm_cache_type[sel] = csize;
+				arm_dcache_align = 1 << 
+				    (CPUV7_CT_xSIZE_LEN(csize) + 4);
+				arm_dcache_align_mask = arm_dcache_align - 1;
+			}
+			if (type == CACHE_ICACHE || type == CACHE_SEP_CACHE) {
+				sel = (i << 1) | 1;
+				__asm __volatile("mcr p15, 2, %0, c0, c0, 0"
+				    : : "r" (sel));
+				__asm __volatile("mrc p15, 1, %0, c0, c0, 0"
+				    : "=r" (csize));
+				arm_cache_type[sel] = csize;
+			}
+			i++;
+			clevel >>= 3;
+		}
+	} else {
+		if ((ctype & CPU_CT_S) == 0)
+			arm_pcache_unified = 1;
+
+		/*
+		 * If you want to know how this code works, go read the ARM ARM.
+		 */
+
+		arm_pcache_type = CPU_CT_CTYPE(ctype);
+
+		if (arm_pcache_unified == 0) {
+			isize = CPU_CT_ISIZE(ctype);
+			multiplier = (isize & CPU_CT_xSIZE_M) ? 3 : 2;
+			arm_picache_line_size = 1U << (CPU_CT_xSIZE_LEN(isize) + 3);
+			if (CPU_CT_xSIZE_ASSOC(isize) == 0) {
+				if (isize & CPU_CT_xSIZE_M)
+					arm_picache_line_size = 0; /* not present */
+				else
+					arm_picache_ways = 1;
+			} else {
+				arm_picache_ways = multiplier <<
+				    (CPU_CT_xSIZE_ASSOC(isize) - 1);
+			}
+			arm_picache_size = multiplier << (CPU_CT_xSIZE_SIZE(isize) + 8);
+		}
+
+		dsize = CPU_CT_DSIZE(ctype);
+		multiplier = (dsize & CPU_CT_xSIZE_M) ? 3 : 2;
+		arm_pdcache_line_size = 1U << (CPU_CT_xSIZE_LEN(dsize) + 3);
+		if (CPU_CT_xSIZE_ASSOC(dsize) == 0) {
+			if (dsize & CPU_CT_xSIZE_M)
+				arm_pdcache_line_size = 0; /* not present */
+			else
+				arm_pdcache_ways = 1;
+		} else {
+			arm_pdcache_ways = multiplier <<
+			    (CPU_CT_xSIZE_ASSOC(dsize) - 1);
+		}
+		arm_pdcache_size = multiplier << (CPU_CT_xSIZE_SIZE(dsize) + 8);
+
+		arm_dcache_align = arm_pdcache_line_size;
+
+		arm_dcache_l2_assoc = CPU_CT_xSIZE_ASSOC(dsize) + multiplier - 2;
+		arm_dcache_l2_linesize = CPU_CT_xSIZE_LEN(dsize) + 3;
+		arm_dcache_l2_nsets = 6 + CPU_CT_xSIZE_SIZE(dsize) -
+		    CPU_CT_xSIZE_ASSOC(dsize) - CPU_CT_xSIZE_LEN(dsize);
+
+	out:
+		arm_dcache_align_mask = arm_dcache_align - 1;
+	}
+}
+#endif /* ARM9 || XSCALE */
+
+/*
+ * Cannot panic here as we may not have a console yet ...
+ */
+
+int
+set_cpufuncs()
+{
+	cputype = cpufunc_id();
+	cputype &= CPU_ID_CPU_MASK;
+
+	/*
+	 * NOTE: cpu_do_powersave defaults to off.  If we encounter a
+	 * CPU type where we want to use it by default, then we set it.
+	 */
+
+#ifdef CPU_ARM9
+	if (((cputype & CPU_ID_IMPLEMENTOR_MASK) == CPU_ID_ARM_LTD ||
+	     (cputype & CPU_ID_IMPLEMENTOR_MASK) == CPU_ID_TI) &&
+	    (cputype & 0x0000f000) == 0x00009000) {
+		cpufuncs = arm9_cpufuncs;
+		cpu_reset_needs_v4_MMU_disable = 1;	/* V4 or higher */
+		get_cachetype_cp15();
+		arm9_dcache_sets_inc = 1U << arm_dcache_l2_linesize;
+		arm9_dcache_sets_max = (1U << (arm_dcache_l2_linesize +
+		    arm_dcache_l2_nsets)) - arm9_dcache_sets_inc;
+		arm9_dcache_index_inc = 1U << (32 - arm_dcache_l2_assoc);
+		arm9_dcache_index_max = 0U - arm9_dcache_index_inc;
+#ifdef ARM9_CACHE_WRITE_THROUGH
+		pmap_pte_init_arm9();
+#else
+		pmap_pte_init_generic();
+#endif
+		goto out;
+	}
+#endif /* CPU_ARM9 */
+#if defined(CPU_ARM9E) || defined(CPU_ARM10)
+	if (cputype == CPU_ID_MV88FR131 || cputype == CPU_ID_MV88FR571_VD ||
+	    cputype == CPU_ID_MV88FR571_41) {
+		uint32_t sheeva_ctrl;
+
+		sheeva_ctrl = (MV_DC_STREAM_ENABLE | MV_BTB_DISABLE |
+		    MV_L2_ENABLE);
+		/*
+		 * Workaround for Marvell MV78100 CPU: Cache prefetch
+		 * mechanism may affect the cache coherency validity,
+		 * so it needs to be disabled.
+		 *
+		 * Refer to errata document MV-S501058-00C.pdf (p. 3.1
+		 * L2 Prefetching Mechanism) for details.
+		 */
+		if (cputype == CPU_ID_MV88FR571_VD ||
+		    cputype == CPU_ID_MV88FR571_41)
+			sheeva_ctrl |= MV_L2_PREFETCH_DISABLE;
+
+		sheeva_control_ext(0xffffffff & ~MV_WA_ENABLE, sheeva_ctrl);
+
+		cpufuncs = sheeva_cpufuncs;
+		get_cachetype_cp15();
+		pmap_pte_init_generic();
+		goto out;
+	} else if (cputype == CPU_ID_ARM926EJS || cputype == CPU_ID_ARM1026EJS) {
+		cpufuncs = armv5_ec_cpufuncs;
+		get_cachetype_cp15();
+		pmap_pte_init_generic();
+		goto out;
+	}
+#endif /* CPU_ARM9E || CPU_ARM10 */
+#ifdef CPU_ARM10
+	if (/* cputype == CPU_ID_ARM1020T || */
+	    cputype == CPU_ID_ARM1020E) {
+		/*
+		 * Select write-through cacheing (this isn't really an
+		 * option on ARM1020T).
+		 */
+		cpufuncs = arm10_cpufuncs;
+		cpu_reset_needs_v4_MMU_disable = 1;	/* V4 or higher */
+		get_cachetype_cp15();
+		arm10_dcache_sets_inc = 1U << arm_dcache_l2_linesize;
+		arm10_dcache_sets_max =
+		    (1U << (arm_dcache_l2_linesize + arm_dcache_l2_nsets)) -
+		    arm10_dcache_sets_inc;
+		arm10_dcache_index_inc = 1U << (32 - arm_dcache_l2_assoc);
+		arm10_dcache_index_max = 0U - arm10_dcache_index_inc;
+		pmap_pte_init_generic();
+		goto out;
+	}
+#endif /* CPU_ARM10 */
+#if defined(CPU_ARM1136) || defined(CPU_ARM1176)
+	if (cputype == CPU_ID_ARM1136JS
+	    || cputype == CPU_ID_ARM1136JSR1
+	    || cputype == CPU_ID_ARM1176JZS) {
+#ifdef CPU_ARM1136
+		if (cputype == CPU_ID_ARM1136JS
+		    || cputype == CPU_ID_ARM1136JSR1)
+			cpufuncs = arm1136_cpufuncs;
+#endif
+#ifdef CPU_ARM1176
+		if (cputype == CPU_ID_ARM1176JZS)
+			cpufuncs = arm1176_cpufuncs;
+#endif
+		cpu_reset_needs_v4_MMU_disable = 1;     /* V4 or higher */
+		get_cachetype_cp15();
+
+		pmap_pte_init_mmu_v6();
+
+		goto out;
+	}
+#endif /* CPU_ARM1136 || CPU_ARM1176 */
+#if defined(CPU_CORTEXA) || defined(CPU_KRAIT)
+	if (cputype == CPU_ID_CORTEXA7 ||
+	    cputype == CPU_ID_CORTEXA8R1 ||
+	    cputype == CPU_ID_CORTEXA8R2 ||
+	    cputype == CPU_ID_CORTEXA8R3 ||
+	    cputype == CPU_ID_CORTEXA9R1 ||
+	    cputype == CPU_ID_CORTEXA9R2 ||
+	    cputype == CPU_ID_CORTEXA9R3 ||
+	    cputype == CPU_ID_CORTEXA15R0 ||
+	    cputype == CPU_ID_CORTEXA15R1 ||
+	    cputype == CPU_ID_CORTEXA15R2 ||
+	    cputype == CPU_ID_CORTEXA15R3 ||
+	    cputype == CPU_ID_KRAIT ) {
+		cpufuncs = cortexa_cpufuncs;
+		cpu_reset_needs_v4_MMU_disable = 1;     /* V4 or higher */
+		get_cachetype_cp15();
+		
+		pmap_pte_init_mmu_v6();
+		/* Use powersave on this CPU. */
+		cpu_do_powersave = 1;
+		goto out;
+	}
+#endif /* CPU_CORTEXA */
+		
+#if defined(CPU_MV_PJ4B)
+	if (cputype == CPU_ID_MV88SV581X_V7 ||
+	    cputype == CPU_ID_MV88SV584X_V7 ||
+	    cputype == CPU_ID_ARM_88SV581X_V7) {
+		cpufuncs = pj4bv7_cpufuncs;
+		get_cachetype_cp15();
+		pmap_pte_init_mmu_v6();
+		goto out;
+	}
+#endif /* CPU_MV_PJ4B */
+
+#if defined(CPU_FA526) || defined(CPU_FA626TE)
+	if (cputype == CPU_ID_FA526 || cputype == CPU_ID_FA626TE) {
+		cpufuncs = fa526_cpufuncs;
+		cpu_reset_needs_v4_MMU_disable = 1;	/* SA needs it	*/
+		get_cachetype_cp15();
+		pmap_pte_init_generic();
+
+		/* Use powersave on this CPU. */
+		cpu_do_powersave = 1;
+
+		goto out;
+	}
+#endif	/* CPU_FA526 || CPU_FA626TE */
+
+#ifdef CPU_XSCALE_80200
+	if (cputype == CPU_ID_80200) {
+		int rev = cpufunc_id() & CPU_ID_REVISION_MASK;
+
+		i80200_icu_init();
+
+#if defined(XSCALE_CCLKCFG)
+		/*
+		 * Crank CCLKCFG to maximum legal value.
+		 */
+		__asm __volatile ("mcr p14, 0, %0, c6, c0, 0"
+			:
+			: "r" (XSCALE_CCLKCFG));
+#endif
+
+		/*
+		 * XXX Disable ECC in the Bus Controller Unit; we
+		 * don't really support it, yet.  Clear any pending
+		 * error indications.
+		 */
+		__asm __volatile("mcr p13, 0, %0, c0, c1, 0"
+			:
+			: "r" (BCUCTL_E0|BCUCTL_E1|BCUCTL_EV));
+
+		cpufuncs = xscale_cpufuncs;
+		/*
+		 * i80200 errata: Step-A0 and A1 have a bug where
+		 * D$ dirty bits are not cleared on "invalidate by
+		 * address".
+		 *
+		 * Workaround: Clean cache line before invalidating.
+		 */
+		if (rev == 0 || rev == 1)
+			cpufuncs.cf_dcache_inv_range = xscale_cache_purgeD_rng;
+
+		cpu_reset_needs_v4_MMU_disable = 1;	/* XScale needs it */
+		get_cachetype_cp15();
+		pmap_pte_init_xscale();
+		goto out;
+	}
+#endif /* CPU_XSCALE_80200 */
+#if defined(CPU_XSCALE_80321) || defined(CPU_XSCALE_80219)
+	if (cputype == CPU_ID_80321_400 || cputype == CPU_ID_80321_600 ||
+	    cputype == CPU_ID_80321_400_B0 || cputype == CPU_ID_80321_600_B0 ||
+	    cputype == CPU_ID_80219_400 || cputype == CPU_ID_80219_600) {
+		cpufuncs = xscale_cpufuncs;
+		cpu_reset_needs_v4_MMU_disable = 1;	/* XScale needs it */
+		get_cachetype_cp15();
+		pmap_pte_init_xscale();
+		goto out;
+	}
+#endif /* CPU_XSCALE_80321 */
+
+#if defined(CPU_XSCALE_81342)
+	if (cputype == CPU_ID_81342) {
+		cpufuncs = xscalec3_cpufuncs;
+		cpu_reset_needs_v4_MMU_disable = 1;	/* XScale needs it */
+		get_cachetype_cp15();
+		pmap_pte_init_xscale();
+		goto out;
+	}
+#endif /* CPU_XSCALE_81342 */
+#ifdef CPU_XSCALE_PXA2X0
+	/* ignore core revision to test PXA2xx CPUs */
+	if ((cputype & ~CPU_ID_XSCALE_COREREV_MASK) == CPU_ID_PXA250 ||
+	    (cputype & ~CPU_ID_XSCALE_COREREV_MASK) == CPU_ID_PXA27X ||
+	    (cputype & ~CPU_ID_XSCALE_COREREV_MASK) == CPU_ID_PXA210) {
+
+		cpufuncs = xscale_cpufuncs;
+		cpu_reset_needs_v4_MMU_disable = 1;	/* XScale needs it */
+		get_cachetype_cp15();
+		pmap_pte_init_xscale();
+
+		/* Use powersave on this CPU. */
+		cpu_do_powersave = 1;
+
+		goto out;
+	}
+#endif /* CPU_XSCALE_PXA2X0 */
+#ifdef CPU_XSCALE_IXP425
+	if (cputype == CPU_ID_IXP425_533 || cputype == CPU_ID_IXP425_400 ||
+            cputype == CPU_ID_IXP425_266 || cputype == CPU_ID_IXP435) {
+
+		cpufuncs = xscale_cpufuncs;
+		cpu_reset_needs_v4_MMU_disable = 1;	/* XScale needs it */
+		get_cachetype_cp15();
+		pmap_pte_init_xscale();
+
+		goto out;
+	}
+#endif /* CPU_XSCALE_IXP425 */
+	/*
+	 * Bzzzz. And the answer was ...
+	 */
+	panic("No support for this CPU type (%08x) in kernel", cputype);
+	return(ARCHITECTURE_NOT_PRESENT);
+out:
+	uma_set_align(arm_dcache_align_mask);
+	return (0);
+}
+
+/*
+ * Fixup routines for data and prefetch aborts.
+ *
+ * Several compile time symbols are used
+ *
+ * DEBUG_FAULT_CORRECTION - Print debugging information during the
+ * correction of registers after a fault.
+ */
+
+
+/*
+ * Null abort fixup routine.
+ * For use when no fixup is required.
+ */
+int
+cpufunc_null_fixup(arg)
+	void *arg;
+{
+	return(ABORT_FIXUP_OK);
+}
+
+/*
+ * CPU Setup code
+ */
+
+#if defined (CPU_ARM9) || \
+  defined(CPU_ARM9E) || \
+  defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) ||		\
+  defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) ||		\
+  defined(CPU_XSCALE_80219) || defined(CPU_XSCALE_81342) || \
+  defined(CPU_ARM10) ||  defined(CPU_ARM1136) || defined(CPU_ARM1176) ||\
+  defined(CPU_FA526) || defined(CPU_FA626TE)
+
+#define IGN	0
+#define OR	1
+#define BIC	2
+
+struct cpu_option {
+	char	*co_name;
+	int	co_falseop;
+	int	co_trueop;
+	int	co_value;
+};
+
+static u_int parse_cpu_options(char *, struct cpu_option *, u_int);
+
+static u_int
+parse_cpu_options(args, optlist, cpuctrl)
+	char *args;
+	struct cpu_option *optlist;
+	u_int cpuctrl;
+{
+	int integer;
+
+	if (args == NULL)
+		return(cpuctrl);
+
+	while (optlist->co_name) {
+		if (get_bootconf_option(args, optlist->co_name,
+		    BOOTOPT_TYPE_BOOLEAN, &integer)) {
+			if (integer) {
+				if (optlist->co_trueop == OR)
+					cpuctrl |= optlist->co_value;
+				else if (optlist->co_trueop == BIC)
+					cpuctrl &= ~optlist->co_value;
+			} else {
+				if (optlist->co_falseop == OR)
+					cpuctrl |= optlist->co_value;
+				else if (optlist->co_falseop == BIC)
+					cpuctrl &= ~optlist->co_value;
+			}
+		}
+		++optlist;
+	}
+	return(cpuctrl);
+}
+#endif /* CPU_ARM9 || XSCALE*/
+
+#ifdef CPU_ARM9
+struct cpu_option arm9_options[] = {
+	{ "cpu.cache",		BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
+	{ "cpu.nocache",	OR,  BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
+	{ "arm9.cache",	BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
+	{ "arm9.icache",	BIC, OR,  CPU_CONTROL_IC_ENABLE },
+	{ "arm9.dcache",	BIC, OR,  CPU_CONTROL_DC_ENABLE },
+	{ "cpu.writebuf",	BIC, OR,  CPU_CONTROL_WBUF_ENABLE },
+	{ "cpu.nowritebuf",	OR,  BIC, CPU_CONTROL_WBUF_ENABLE },
+	{ "arm9.writebuf",	BIC, OR,  CPU_CONTROL_WBUF_ENABLE },
+	{ NULL,			IGN, IGN, 0 }
+};
+
+void
+arm9_setup(args)
+	char *args;
+{
+	int cpuctrl, cpuctrlmask;
+
+	cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE
+	    | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE
+	    | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
+	    | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_LABT_ENABLE |
+	    CPU_CONTROL_ROUNDROBIN;
+	cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE
+		 | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE
+		 | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
+		 | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE
+		 | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE
+		 | CPU_CONTROL_LABT_ENABLE | CPU_CONTROL_VECRELOC
+		 | CPU_CONTROL_ROUNDROBIN;
+
+#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS
+	cpuctrl |= CPU_CONTROL_AFLT_ENABLE;
+#endif
+
+	cpuctrl = parse_cpu_options(args, arm9_options, cpuctrl);
+
+#ifdef __ARMEB__
+	cpuctrl |= CPU_CONTROL_BEND_ENABLE;
+#endif
+	if (vector_page == ARM_VECTORS_HIGH)
+		cpuctrl |= CPU_CONTROL_VECRELOC;
+
+	/* Clear out the cache */
+	cpu_idcache_wbinv_all();
+
+	/* Set the control register */
+	cpu_control(cpuctrlmask, cpuctrl);
+	ctrl = cpuctrl;
+
+}
+#endif	/* CPU_ARM9 */
+
+#if defined(CPU_ARM9E) || defined(CPU_ARM10)
+struct cpu_option arm10_options[] = {
+	{ "cpu.cache",		BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
+	{ "cpu.nocache",	OR,  BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
+	{ "arm10.cache",	BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
+	{ "arm10.icache",	BIC, OR,  CPU_CONTROL_IC_ENABLE },
+	{ "arm10.dcache",	BIC, OR,  CPU_CONTROL_DC_ENABLE },
+	{ "cpu.writebuf",	BIC, OR,  CPU_CONTROL_WBUF_ENABLE },
+	{ "cpu.nowritebuf",	OR,  BIC, CPU_CONTROL_WBUF_ENABLE },
+	{ "arm10.writebuf",	BIC, OR,  CPU_CONTROL_WBUF_ENABLE },
+	{ NULL,			IGN, IGN, 0 }
+};
+
+void
+arm10_setup(args)
+	char *args;
+{
+	int cpuctrl, cpuctrlmask;
+
+	cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_SYST_ENABLE
+	    | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
+	    | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_BPRD_ENABLE;
+	cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_SYST_ENABLE
+	    | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
+	    | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE
+	    | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE
+	    | CPU_CONTROL_BPRD_ENABLE
+	    | CPU_CONTROL_ROUNDROBIN | CPU_CONTROL_CPCLK;
+
+#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS
+	cpuctrl |= CPU_CONTROL_AFLT_ENABLE;
+#endif
+
+	cpuctrl = parse_cpu_options(args, arm10_options, cpuctrl);
+
+#ifdef __ARMEB__
+	cpuctrl |= CPU_CONTROL_BEND_ENABLE;
+#endif
+
+	/* Clear out the cache */
+	cpu_idcache_wbinv_all();
+
+	/* Now really make sure they are clean.  */
+	__asm __volatile ("mcr\tp15, 0, r0, c7, c7, 0" : : );
+
+	if (vector_page == ARM_VECTORS_HIGH)
+		cpuctrl |= CPU_CONTROL_VECRELOC;
+
+	/* Set the control register */
+	ctrl = cpuctrl;
+	cpu_control(0xffffffff, cpuctrl);
+
+	/* And again. */
+	cpu_idcache_wbinv_all();
+}
+#endif	/* CPU_ARM9E || CPU_ARM10 */
+
+#if defined(CPU_ARM1136) || defined(CPU_ARM1176) \
+ || defined(CPU_MV_PJ4B) \
+ || defined(CPU_CORTEXA) || defined(CPU_KRAIT)
+static __inline void
+cpu_scc_setup_ccnt(void)
+{
+/* This is how you give userland access to the CCNT and PMCn
+ * registers.
+ * BEWARE! This gives write access also, which may not be what
+ * you want!
+ */
+#ifdef _PMC_USER_READ_WRITE_
+#if defined(CPU_ARM1136) || defined(CPU_ARM1176)
+	/* Use the Secure User and Non-secure Access Validation Control Register
+	 * to allow userland access
+	 */
+	__asm volatile ("mcr	p15, 0, %0, c15, c9, 0\n\t"
+			:
+			: "r"(0x00000001));
+#else
+	/* Set PMUSERENR[0] to allow userland access */
+	__asm volatile ("mcr	p15, 0, %0, c9, c14, 0\n\t"
+			:
+			: "r"(0x00000001));
+#endif
+#endif
+#if defined(CPU_ARM1136) || defined(CPU_ARM1176)
+	/* Set PMCR[2,0] to enable counters and reset CCNT */
+	__asm volatile ("mcr	p15, 0, %0, c15, c12, 0\n\t"
+			:
+			: "r"(0x00000005));
+#else
+	/* Set up the PMCCNTR register as a cyclecounter:
+	 * Set PMINTENCLR to 0xFFFFFFFF to block interrupts
+	 * Set PMCR[2,0] to enable counters and reset CCNT
+	 * Set PMCNTENSET to 0x80000000 to enable CCNT */
+	__asm volatile ("mcr	p15, 0, %0, c9, c14, 2\n\t"
+			"mcr	p15, 0, %1, c9, c12, 0\n\t"
+			"mcr	p15, 0, %2, c9, c12, 1\n\t"
+			:
+			: "r"(0xFFFFFFFF),
+			  "r"(0x00000005),
+			  "r"(0x80000000));
+#endif
+}
+#endif
+
+#if defined(CPU_ARM1136) || defined(CPU_ARM1176)
+struct cpu_option arm11_options[] = {
+	{ "cpu.cache",		BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
+	{ "cpu.nocache",	OR,  BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
+	{ "arm11.cache",	BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
+	{ "arm11.icache",	BIC, OR,  CPU_CONTROL_IC_ENABLE },
+	{ "arm11.dcache",	BIC, OR,  CPU_CONTROL_DC_ENABLE },
+	{ NULL,			IGN, IGN, 0 }
+};
+
+void
+arm11x6_setup(char *args)
+{
+	int cpuctrl, cpuctrl_wax;
+	uint32_t auxctrl, auxctrl_wax;
+	uint32_t tmp, tmp2;
+	uint32_t sbz=0;
+	uint32_t cpuid;
+
+	cpuid = cpufunc_id();
+
+	cpuctrl =
+		CPU_CONTROL_MMU_ENABLE  |
+		CPU_CONTROL_DC_ENABLE   |
+		CPU_CONTROL_WBUF_ENABLE |
+		CPU_CONTROL_32BP_ENABLE |
+		CPU_CONTROL_32BD_ENABLE |
+		CPU_CONTROL_LABT_ENABLE |
+		CPU_CONTROL_SYST_ENABLE |
+		CPU_CONTROL_IC_ENABLE;
+
+	/*
+	 * "write as existing" bits
+	 * inverse of this is mask
+	 */
+	cpuctrl_wax =
+		(3 << 30) | /* SBZ */
+		(1 << 29) | /* FA */
+		(1 << 28) | /* TR */
+		(3 << 26) | /* SBZ */ 
+		(3 << 19) | /* SBZ */
+		(1 << 17);  /* SBZ */
+
+	cpuctrl |= CPU_CONTROL_BPRD_ENABLE;
+	cpuctrl |= CPU_CONTROL_V6_EXTPAGE;
+
+	cpuctrl = parse_cpu_options(args, arm11_options, cpuctrl);
+
+#ifdef __ARMEB__
+	cpuctrl |= CPU_CONTROL_BEND_ENABLE;
+#endif
+
+	if (vector_page == ARM_VECTORS_HIGH)
+		cpuctrl |= CPU_CONTROL_VECRELOC;
+
+	auxctrl = 0;
+	auxctrl_wax = ~0;
+	/*
+	 * This options enables the workaround for the 364296 ARM1136
+	 * r0pX errata (possible cache data corruption with
+	 * hit-under-miss enabled). It sets the undocumented bit 31 in
+	 * the auxiliary control register and the FI bit in the control
+	 * register, thus disabling hit-under-miss without putting the
+	 * processor into full low interrupt latency mode. ARM11MPCore
+	 * is not affected.
+	 */
+	if ((cpuid & CPU_ID_CPU_MASK) == CPU_ID_ARM1136JS) { /* ARM1136JSr0pX */
+		cpuctrl |= CPU_CONTROL_FI_ENABLE;
+		auxctrl = ARM1136_AUXCTL_PFI;
+		auxctrl_wax = ~ARM1136_AUXCTL_PFI;
+	}
+
+	/*
+	 * Enable an errata workaround
+	 */
+	if ((cpuid & CPU_ID_CPU_MASK) == CPU_ID_ARM1176JZS) { /* ARM1176JZSr0 */
+		auxctrl = ARM1176_AUXCTL_PHD;
+		auxctrl_wax = ~ARM1176_AUXCTL_PHD;
+	}
+
+	/* Clear out the cache */
+	cpu_idcache_wbinv_all();
+
+	/* Now really make sure they are clean.  */
+	__asm volatile ("mcr\tp15, 0, %0, c7, c7, 0" : : "r"(sbz));
+
+	/* Allow detection code to find the VFP if it's fitted.  */
+	__asm volatile ("mcr\tp15, 0, %0, c1, c0, 2" : : "r" (0x0fffffff));
+
+	/* Set the control register */
+	ctrl = cpuctrl;
+	cpu_control(~cpuctrl_wax, cpuctrl);
+
+	__asm volatile ("mrc	p15, 0, %0, c1, c0, 1\n\t"
+			"and	%1, %0, %2\n\t"
+			"orr	%1, %1, %3\n\t"
+			"teq	%0, %1\n\t"
+			"mcrne	p15, 0, %1, c1, c0, 1\n\t"
+			: "=r"(tmp), "=r"(tmp2) :
+			  "r"(auxctrl_wax), "r"(auxctrl));
+
+	/* And again. */
+	cpu_idcache_wbinv_all();
+
+	cpu_scc_setup_ccnt();
+}
+#endif  /* CPU_ARM1136 || CPU_ARM1176 */
+
+#ifdef CPU_MV_PJ4B
+void
+pj4bv7_setup(args)
+	char *args;
+{
+	int cpuctrl;
+
+	pj4b_config();
+
+	cpuctrl = CPU_CONTROL_MMU_ENABLE;
+#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS
+	cpuctrl |= CPU_CONTROL_AFLT_ENABLE;
+#endif
+	cpuctrl |= CPU_CONTROL_DC_ENABLE;
+	cpuctrl |= (0xf << 3);
+	cpuctrl |= CPU_CONTROL_BPRD_ENABLE;
+	cpuctrl |= CPU_CONTROL_IC_ENABLE;
+	if (vector_page == ARM_VECTORS_HIGH)
+		cpuctrl |= CPU_CONTROL_VECRELOC;
+	cpuctrl |= (0x5 << 16) | (1 < 22);
+	cpuctrl |= CPU_CONTROL_V6_EXTPAGE;
+
+	/* Clear out the cache */
+	cpu_idcache_wbinv_all();
+
+	/* Set the control register */
+	ctrl = cpuctrl;
+	cpu_control(0xFFFFFFFF, cpuctrl);
+
+	/* And again. */
+	cpu_idcache_wbinv_all();
+
+	cpu_scc_setup_ccnt();
+}
+#endif /* CPU_MV_PJ4B */
+
+#if defined(CPU_CORTEXA) || defined(CPU_KRAIT)
+
+void
+cortexa_setup(char *args)
+{
+	int cpuctrl, cpuctrlmask;
+	
+	cpuctrlmask = CPU_CONTROL_MMU_ENABLE |     /* MMU enable         [0] */
+	    CPU_CONTROL_AFLT_ENABLE |    /* Alignment fault    [1] */
+	    CPU_CONTROL_DC_ENABLE |      /* DCache enable      [2] */
+	    CPU_CONTROL_BPRD_ENABLE |    /* Branch prediction [11] */
+	    CPU_CONTROL_IC_ENABLE |      /* ICache enable     [12] */
+	    CPU_CONTROL_VECRELOC;        /* Vector relocation [13] */
+	
+	cpuctrl = CPU_CONTROL_MMU_ENABLE |
+	    CPU_CONTROL_IC_ENABLE |
+	    CPU_CONTROL_DC_ENABLE |
+	    CPU_CONTROL_BPRD_ENABLE;
+	
+#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS
+	cpuctrl |= CPU_CONTROL_AFLT_ENABLE;
+#endif
+	
+	/* Switch to big endian */
+#ifdef __ARMEB__
+	cpuctrl |= CPU_CONTROL_BEND_ENABLE;
+#endif
+	
+	/* Check if the vector page is at the high address (0xffff0000) */
+	if (vector_page == ARM_VECTORS_HIGH)
+		cpuctrl |= CPU_CONTROL_VECRELOC;
+	
+	/* Clear out the cache */
+	cpu_idcache_wbinv_all();
+	
+	/* Set the control register */
+	ctrl = cpuctrl;
+	cpu_control(cpuctrlmask, cpuctrl);
+	
+	/* And again. */
+	cpu_idcache_wbinv_all();
+#ifdef SMP
+	armv7_auxctrl((1 << 6) | (1 << 0), (1 << 6) | (1 << 0)); /* Enable SMP + TLB broadcasting  */
+#endif
+
+	cpu_scc_setup_ccnt();
+}
+#endif  /* CPU_CORTEXA */
+
+#if defined(CPU_FA526) || defined(CPU_FA626TE)
+struct cpu_option fa526_options[] = {
+#ifdef COMPAT_12
+	{ "nocache",		IGN, BIC, (CPU_CONTROL_IC_ENABLE |
+					   CPU_CONTROL_DC_ENABLE) },
+	{ "nowritebuf",		IGN, BIC, CPU_CONTROL_WBUF_ENABLE },
+#endif	/* COMPAT_12 */
+	{ "cpu.cache",		BIC, OR,  (CPU_CONTROL_IC_ENABLE |
+					   CPU_CONTROL_DC_ENABLE) },
+	{ "cpu.nocache",	OR,  BIC, (CPU_CONTROL_IC_ENABLE |
+					   CPU_CONTROL_DC_ENABLE) },
+	{ "cpu.writebuf",	BIC, OR,  CPU_CONTROL_WBUF_ENABLE },
+	{ "cpu.nowritebuf",	OR,  BIC, CPU_CONTROL_WBUF_ENABLE },
+	{ NULL,			IGN, IGN, 0 }
+};
+
+void
+fa526_setup(char *args)
+{
+	int cpuctrl, cpuctrlmask;
+
+	cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE
+		 | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE
+		 | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
+		 | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_LABT_ENABLE
+		| CPU_CONTROL_BPRD_ENABLE;
+	cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE
+		 | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE
+		 | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
+		 | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE
+		 | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE
+		 | CPU_CONTROL_LABT_ENABLE | CPU_CONTROL_BPRD_ENABLE
+		 | CPU_CONTROL_CPCLK | CPU_CONTROL_VECRELOC;
+
+#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS
+	cpuctrl |= CPU_CONTROL_AFLT_ENABLE;
+#endif
+
+	cpuctrl = parse_cpu_options(args, fa526_options, cpuctrl);
+
+#ifdef __ARMEB__
+	cpuctrl |= CPU_CONTROL_BEND_ENABLE;
+#endif
+
+	if (vector_page == ARM_VECTORS_HIGH)
+		cpuctrl |= CPU_CONTROL_VECRELOC;
+
+	/* Clear out the cache */
+	cpu_idcache_wbinv_all();
+
+	/* Set the control register */
+	ctrl = cpuctrl;
+	cpu_control(0xffffffff, cpuctrl);
+}
+#endif	/* CPU_FA526 || CPU_FA626TE */
+
+#if defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) || \
+  defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) || \
+  defined(CPU_XSCALE_80219) || defined(CPU_XSCALE_81342)
+struct cpu_option xscale_options[] = {
+#ifdef COMPAT_12
+	{ "branchpredict", 	BIC, OR,  CPU_CONTROL_BPRD_ENABLE },
+	{ "nocache",		IGN, BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
+#endif	/* COMPAT_12 */
+	{ "cpu.branchpredict", 	BIC, OR,  CPU_CONTROL_BPRD_ENABLE },
+	{ "cpu.cache",		BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
+	{ "cpu.nocache",	OR,  BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
+	{ "xscale.branchpredict", BIC, OR,  CPU_CONTROL_BPRD_ENABLE },
+	{ "xscale.cache",	BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
+	{ "xscale.icache",	BIC, OR,  CPU_CONTROL_IC_ENABLE },
+	{ "xscale.dcache",	BIC, OR,  CPU_CONTROL_DC_ENABLE },
+	{ NULL,			IGN, IGN, 0 }
+};
+
+void
+xscale_setup(args)
+	char *args;
+{
+	uint32_t auxctl;
+	int cpuctrl, cpuctrlmask;
+
+	/*
+	 * The XScale Write Buffer is always enabled.  Our option
+	 * is to enable/disable coalescing.  Note that bits 6:3
+	 * must always be enabled.
+	 */
+
+	cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE
+		 | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE
+		 | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
+		 | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_LABT_ENABLE
+		 | CPU_CONTROL_BPRD_ENABLE;
+	cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE
+		 | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE
+		 | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
+		 | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE
+		 | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE
+		 | CPU_CONTROL_LABT_ENABLE | CPU_CONTROL_BPRD_ENABLE
+		 | CPU_CONTROL_CPCLK | CPU_CONTROL_VECRELOC | \
+		 CPU_CONTROL_L2_ENABLE;
+
+#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS
+	cpuctrl |= CPU_CONTROL_AFLT_ENABLE;
+#endif
+
+	cpuctrl = parse_cpu_options(args, xscale_options, cpuctrl);
+
+#ifdef __ARMEB__
+	cpuctrl |= CPU_CONTROL_BEND_ENABLE;
+#endif
+
+	if (vector_page == ARM_VECTORS_HIGH)
+		cpuctrl |= CPU_CONTROL_VECRELOC;
+#ifdef CPU_XSCALE_CORE3
+	cpuctrl |= CPU_CONTROL_L2_ENABLE;
+#endif
+
+	/* Clear out the cache */
+	cpu_idcache_wbinv_all();
+
+	/*
+	 * Set the control register.  Note that bits 6:3 must always
+	 * be set to 1.
+	 */
+	ctrl = cpuctrl;
+/*	cpu_control(cpuctrlmask, cpuctrl);*/
+	cpu_control(0xffffffff, cpuctrl);
+
+	/* Make sure write coalescing is turned on */
+	__asm __volatile("mrc p15, 0, %0, c1, c0, 1"
+		: "=r" (auxctl));
+#ifdef XSCALE_NO_COALESCE_WRITES
+	auxctl |= XSCALE_AUXCTL_K;
+#else
+	auxctl &= ~XSCALE_AUXCTL_K;
+#endif
+#ifdef CPU_XSCALE_CORE3
+	auxctl |= XSCALE_AUXCTL_LLR;
+	auxctl |= XSCALE_AUXCTL_MD_MASK;
+#endif
+	__asm __volatile("mcr p15, 0, %0, c1, c0, 1"
+		: : "r" (auxctl));
+}
+#endif	/* CPU_XSCALE_80200 || CPU_XSCALE_80321 || CPU_XSCALE_PXA2X0 || CPU_XSCALE_IXP425
+	   CPU_XSCALE_80219 */


Property changes on: trunk/sys/arm/arm/cpufunc.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/cpufunc_asm.S
===================================================================
--- trunk/sys/arm/arm/cpufunc_asm.S	                        (rev 0)
+++ trunk/sys/arm/arm/cpufunc_asm.S	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,196 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: cpufunc_asm.S,v 1.12 2003/09/06 09:14:52 rearnsha Exp $	*/
+
+/*-
+ * Copyright (c) 1997,1998 Mark Brinicombe.
+ * Copyright (c) 1997 Causality Limited
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Causality Limited.
+ * 4. The name of Causality Limited may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY CAUSALITY LIMITED ``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 CAUSALITY LIMITED 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.
+ *
+ * RiscBSD kernel project
+ *
+ * cpufunc.S
+ *
+ * Assembly functions for CPU / MMU / TLB specific operations
+ *
+ * Created      : 30/01/97
+ *
+ */
+
+#include <machine/asm.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/cpufunc_asm.S 278652 2015-02-13 00:49:47Z ian $");
+
+	.text
+	.align	2
+
+ENTRY(cpufunc_nullop)
+	RET
+END(cpufunc_nullop)
+
+/*
+ * Generic functions to read the internal coprocessor registers
+ *
+ * Currently these registers are :
+ *  c0 - CPU ID
+ *  c5 - Fault status
+ *  c6 - Fault address
+ *
+ */
+
+ENTRY(cpufunc_id)
+	mrc	p15, 0, r0, c0, c0, 0
+	RET
+END(cpufunc_id)
+
+ENTRY(cpufunc_cpuid)
+	mrc	p15, 0, r0, c0, c0, 0
+	RET
+END(cpufunc_cpuid)
+
+ENTRY(cpu_get_control)
+	mrc	p15, 0, r0, c1, c0, 0
+	RET
+END(cpu_get_control)
+
+ENTRY(cpu_read_cache_config)
+	mrc	p15, 0, r0, c0, c0, 1
+	RET
+END(cpu_read_cache_config)
+
+ENTRY(cpufunc_faultstatus)
+	mrc	p15, 0, r0, c5, c0, 0
+	RET
+END(cpufunc_faultstatus)
+
+ENTRY(cpufunc_faultaddress)
+	mrc	p15, 0, r0, c6, c0, 0
+	RET
+END(cpufunc_faultaddress)
+
+/*
+ * Generic functions to write the internal coprocessor registers
+ *
+ *
+ * Currently these registers are
+ *  c1 - CPU Control
+ *  c3 - Domain Access Control
+ *
+ * All other registers are CPU architecture specific
+ */
+
+#if 0 /* See below. */
+ENTRY(cpufunc_control)
+	mcr	p15, 0, r0, c1, c0, 0
+	RET
+END(cpufunc_control)
+#endif
+
+ENTRY(cpufunc_domains)
+	mcr	p15, 0, r0, c3, c0, 0
+	RET
+END(cpufunc_domains)
+
+/*
+ * Generic functions to read/modify/write the internal coprocessor registers
+ *
+ *
+ * Currently these registers are
+ *  c1 - CPU Control
+ *
+ * All other registers are CPU architecture specific
+ */
+
+ENTRY(cpufunc_control)
+	mrc	p15, 0, r3, c1, c0, 0	/* Read the control register */
+	bic	r2, r3, r0		/* Clear bits */
+	eor     r2, r2, r1		/* XOR bits */
+
+
+	teq	r2, r3			/* Only write if there is a change */
+	mcrne	p15, 0, r2, c1, c0, 0	/* Write new control register */
+	mov	r0, r3			/* Return old value */
+
+	RET
+.Lglou:
+	.asciz "plop %p\n"
+	.align 2
+END(cpufunc_control)
+
+/*
+ * other potentially useful software functions are:
+ *  clean D cache entry and flush I cache entry
+ *   for the moment use cache_purgeID_E
+ */
+
+/* Random odd functions */
+
+/*
+ * Function to get the offset of a stored program counter from the
+ * instruction doing the store.  This offset is defined to be the same
+ * for all STRs and STMs on a given implementation.  Code based on
+ * section 2.4.3 of the ARM ARM (2nd Ed.), with modifications to work
+ * in 26-bit modes as well.
+ */
+ENTRY(get_pc_str_offset)
+	mov	ip, sp
+	stmfd	sp!, {fp, ip, lr, pc}
+	sub	fp, ip, #4
+	sub	sp, sp, #4
+	mov	r1, pc		/* R1 = addr of following STR */
+	mov	r0, r0
+	str	pc, [sp]	/* [SP] = . + offset */
+	ldr	r0, [sp]
+	sub	r0, r0, r1
+	ldmdb	fp, {fp, sp, pc}
+END(get_pc_str_offset)
+
+/* Allocate and lock a cacheline for the specified address. */
+
+#define CPWAIT_BRANCH			\
+	sub	pc, pc, #4
+#define CPWAIT() \
+	mrc	p15, 0, r2, c2, c0, 0;	\
+	mov	r2, r2;			\
+	CPWAIT_BRANCH
+
+ENTRY(arm_lock_cache_line)
+	mcr	p15, 0, r0, c7, c10, 4 /* Drain write buffer */
+	mov	r1, #1
+	mcr	p15, 0, r1, c9, c2, 0 /* Enable data cache lock mode */
+	CPWAIT()
+	mcr	p15, 0, r0, c7, c2, 5 /* Allocate the cache line */
+	mcr	p15, 0, r0, c7, c10, 4 /* Drain write buffer */
+	mov	r1, #0
+	str	r1, [r0]
+	mcr	p15, 0, r0, c7, c10, 4 /* Drain write buffer */
+	mcr	p15, 0, r1, c9, c2, 0 /* Disable data cache lock mode */
+	CPWAIT()
+	RET
+END(arm_lock_cache_line)
+


Property changes on: trunk/sys/arm/arm/cpufunc_asm.S
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/cpufunc_asm_arm10.S
===================================================================
--- trunk/sys/arm/arm/cpufunc_asm_arm10.S	                        (rev 0)
+++ trunk/sys/arm/arm/cpufunc_asm_arm10.S	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,277 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: cpufunc_asm_arm10.S,v 1.1 2003/09/06 09:12:29 rearnsha Exp $	*/
+
+/*-
+ * Copyright (c) 2002 ARM Limited
+ * 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.
+ * 3. The name of the company may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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.
+ *
+ * ARM10 assembly functions for CPU / MMU / TLB specific operations
+ *
+ */
+
+#include <machine/asm.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/cpufunc_asm_arm10.S 278652 2015-02-13 00:49:47Z ian $");
+
+/*
+ * Functions to set the MMU Translation Table Base register
+ *
+ * We need to clean and flush the cache as it uses virtual
+ * addresses that are about to change.
+ */
+ENTRY(arm10_setttb)
+	stmfd	sp!, {r0, lr}
+	bl	_C_LABEL(arm10_idcache_wbinv_all)
+	ldmfd	sp!, {r0, lr}
+
+	mcr	p15, 0, r0, c2, c0, 0	/* load new TTB */
+
+	mcr	p15, 0, r0, c8, c7, 0	/* invalidate I+D TLBs */
+	bx	lr
+END(arm10_setttb)
+
+/*
+ * TLB functions
+ */
+ENTRY(arm10_tlb_flushID_SE)
+	mcr	p15, 0, r0, c8, c6, 1	/* flush D tlb single entry */
+	mcr	p15, 0, r0, c8, c5, 1	/* flush I tlb single entry */
+	bx	lr
+END(arm10_tlb_flushID_SE)
+
+ENTRY(arm10_tlb_flushI_SE)
+	mcr	p15, 0, r0, c8, c5, 1	/* flush I tlb single entry */
+	bx	lr
+END(arm10_tlb_flushI_SE)
+
+/*
+ * Cache operations.  For the entire cache we use the set/index
+ * operations.
+ */
+	s_max	.req r0
+	i_max	.req r1
+	s_inc	.req r2
+	i_inc	.req r3
+
+ENTRY_NP(arm10_icache_sync_range)
+	ldr	ip, .Larm10_line_size
+	cmp	r1, #0x4000
+	bcs	.Larm10_icache_sync_all
+	ldr	ip, [ip]
+	sub	r3, ip, #1
+	and	r2, r0, r3
+	add	r1, r1, r2
+	bic	r0, r0, r3
+.Larm10_sync_next:
+	mcr	p15, 0, r0, c7, c5, 1	/* Invalidate I cache SE with VA */
+	mcr	p15, 0, r0, c7, c10, 1	/* Clean D cache SE with VA */
+	add	r0, r0, ip
+	subs	r1, r1, ip
+	bhi	.Larm10_sync_next
+	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
+	bx	lr
+END(arm10_icache_sync_range)
+
+ENTRY_NP(arm10_icache_sync_all)
+.Larm10_icache_sync_all:
+	/*
+	 * We assume that the code here can never be out of sync with the
+	 * dcache, so that we can safely flush the Icache and fall through
+	 * into the Dcache cleaning code.
+	 */
+	mcr	p15, 0, r0, c7, c5, 0	/* Flush I cache */
+	/* Fall through to clean Dcache. */
+
+.Larm10_dcache_wb:
+	ldr	ip, .Larm10_cache_data
+	ldmia	ip, {s_max, i_max, s_inc, i_inc}
+.Lnext_set:
+	orr	ip, s_max, i_max
+.Lnext_index:
+	mcr	p15, 0, ip, c7, c10, 2	/* Clean D cache SE with Set/Index */
+	subs	ip, ip, i_inc
+	bhs	.Lnext_index		/* Next index */
+	subs	s_max, s_max, s_inc
+	bhs	.Lnext_set		/* Next set */
+	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
+	bx	lr
+END(arm10_icache_sync_all)
+
+.Larm10_line_size:
+	.word	_C_LABEL(arm_pdcache_line_size)
+
+ENTRY(arm10_dcache_wb_range)
+	ldr	ip, .Larm10_line_size
+	cmp	r1, #0x4000
+	bcs	.Larm10_dcache_wb
+	ldr	ip, [ip]
+	sub	r3, ip, #1
+	and	r2, r0, r3
+	add	r1, r1, r2
+	bic	r0, r0, r3
+.Larm10_wb_next:
+	mcr	p15, 0, r0, c7, c10, 1	/* Clean D cache SE with VA */
+	add	r0, r0, ip
+	subs	r1, r1, ip
+	bhi	.Larm10_wb_next
+	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
+	bx	lr
+END(arm10_dcache_wb_range)
+	
+ENTRY(arm10_dcache_wbinv_range)
+	ldr	ip, .Larm10_line_size
+	cmp	r1, #0x4000
+	bcs	.Larm10_dcache_wbinv_all
+	ldr	ip, [ip]
+	sub	r3, ip, #1
+	and	r2, r0, r3
+	add	r1, r1, r2
+	bic	r0, r0, r3
+.Larm10_wbinv_next:
+	mcr	p15, 0, r0, c7, c14, 1	/* Purge D cache SE with VA */
+	add	r0, r0, ip
+	subs	r1, r1, ip
+	bhi	.Larm10_wbinv_next
+	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
+	bx	lr
+END(arm10_dcache_wbinv_range)
+	
+/*
+ * Note, we must not invalidate everything.  If the range is too big we
+ * must use wb-inv of the entire cache.
+ */
+ENTRY(arm10_dcache_inv_range)
+	ldr	ip, .Larm10_line_size
+	cmp	r1, #0x4000
+	bcs	.Larm10_dcache_wbinv_all
+	ldr	ip, [ip]
+	sub	r3, ip, #1
+	and	r2, r0, r3
+	add	r1, r1, r2
+	bic	r0, r0, r3
+.Larm10_inv_next:
+	mcr	p15, 0, r0, c7, c6, 1	/* Invalidate D cache SE with VA */
+	add	r0, r0, ip
+	subs	r1, r1, ip
+	bhi	.Larm10_inv_next
+	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
+	bx	lr
+END(arm10_dcache_inv_range)
+
+ENTRY(arm10_idcache_wbinv_range)
+	ldr	ip, .Larm10_line_size
+	cmp	r1, #0x4000
+	bcs	.Larm10_idcache_wbinv_all
+	ldr	ip, [ip]
+	sub	r3, ip, #1
+	and	r2, r0, r3
+	add	r1, r1, r2
+	bic	r0, r0, r3
+.Larm10_id_wbinv_next:
+	mcr	p15, 0, r0, c7, c5, 1	/* Invalidate I cache SE with VA */
+	mcr	p15, 0, r0, c7, c14, 1	/* Purge D cache SE with VA */
+	add	r0, r0, ip
+	subs	r1, r1, ip
+	bhi	.Larm10_id_wbinv_next
+	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
+	bx	lr
+END(arm10_idcache_wbinv_range)
+
+ENTRY_NP(arm10_idcache_wbinv_all)
+.Larm10_idcache_wbinv_all:
+	/*
+	 * We assume that the code here can never be out of sync with the
+	 * dcache, so that we can safely flush the Icache and fall through
+	 * into the Dcache purging code.
+	 */
+	mcr	p15, 0, r0, c7, c5, 0	/* Flush I cache */
+	/* Fall through to purge Dcache. */
+
+EENTRY(arm10_dcache_wbinv_all)
+.Larm10_dcache_wbinv_all:
+	ldr	ip, .Larm10_cache_data
+	ldmia	ip, {s_max, i_max, s_inc, i_inc}
+.Lnext_set_inv:
+	orr	ip, s_max, i_max
+.Lnext_index_inv:
+	mcr	p15, 0, ip, c7, c14, 2	/* Purge D cache SE with Set/Index */
+	subs	ip, ip, i_inc
+	bhs	.Lnext_index_inv		/* Next index */
+	subs	s_max, s_max, s_inc
+	bhs	.Lnext_set_inv		/* Next set */
+	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
+	bx	lr
+EEND(arm10_dcache_wbinv_all)
+END(arm10_idcache_wbinv_all)
+
+.Larm10_cache_data:
+	.word	_C_LABEL(arm10_dcache_sets_max)
+
+/*
+ * Context switch.
+ *
+ * These is the CPU-specific parts of the context switcher cpu_switch()
+ * These functions actually perform the TTB reload.
+ *
+ * NOTE: Special calling convention
+ *	r1, r4-r13 must be preserved
+ */
+ENTRY(arm10_context_switch)
+	/*
+	 * We can assume that the caches will only contain kernel addresses
+	 * at this point.  So no need to flush them again.
+	 */
+	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
+	mcr	p15, 0, r0, c2, c0, 0	/* set the new TTB */
+	mcr	p15, 0, r0, c8, c7, 0	/* and flush the I+D tlbs */
+
+	/* Paranoia -- make sure the pipeline is empty. */
+	nop
+	nop
+	nop
+	bx	lr
+END(arm10_context_switch)
+
+	.bss
+
+/* XXX The following macros should probably be moved to asm.h */
+#define _DATA_OBJECT(x) .globl x; .type x,_ASM_TYPE_OBJECT; x:
+#define C_OBJECT(x)	_DATA_OBJECT(_C_LABEL(x))
+
+/*
+ * Parameters for the cache cleaning code.  Note that the order of these
+ * four variables is assumed in the code above.  Hence the reason for
+ * declaring them in the assembler file.
+ */
+	.align 2
+C_OBJECT(arm10_dcache_sets_max)
+	.space	4
+C_OBJECT(arm10_dcache_index_max)
+	.space	4
+C_OBJECT(arm10_dcache_sets_inc)
+	.space	4
+C_OBJECT(arm10_dcache_index_inc)
+	.space	4


Property changes on: trunk/sys/arm/arm/cpufunc_asm_arm10.S
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/cpufunc_asm_arm11.S
===================================================================
--- trunk/sys/arm/arm/cpufunc_asm_arm11.S	                        (rev 0)
+++ trunk/sys/arm/arm/cpufunc_asm_arm11.S	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,136 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: cpufunc_asm_arm11.S,v 1.2 2005/12/11 12:16:41 christos Exp $	*/
+
+/*
+ * Copyright (c) 2002, 2005 ARM Limited
+ * 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.
+ * 3. The name of the company may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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.
+ *
+ * ARM11 assembly functions for CPU / MMU / TLB specific operations
+ *
+ * XXX We make no attempt at present to take advantage of the v6 memroy
+ * architecture or physically tagged cache.
+ */
+
+#include <machine/asm.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/cpufunc_asm_arm11.S 266359 2014-05-17 21:28:49Z ian $");
+
+/*
+ * Functions to set the MMU Translation Table Base register
+ *
+ * We need to clean and flush the cache as it uses virtual
+ * addresses that are about to change.
+ */
+ENTRY(arm11_setttb)
+	mcr	p15, 0, r0, c2, c0, 0	/* load new TTB */
+
+	mcr	p15, 0, r0, c8, c7, 0	/* invalidate I+D TLBs */
+	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
+	RET
+END(arm11_setttb)
+
+/*
+ * TLB functions
+ */
+ENTRY(arm11_tlb_flushID_SE)
+	mcr	p15, 0, r0, c8, c6, 1	/* flush D tlb single entry */
+	mcr	p15, 0, r0, c8, c5, 1	/* flush I tlb single entry */
+	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
+	RET
+END(arm11_tlb_flushID_SE)
+
+ENTRY(arm11_tlb_flushI_SE)
+	mcr	p15, 0, r0, c8, c5, 1	/* flush I tlb single entry */
+	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
+	RET
+END(arm11_tlb_flushI_SE)
+
+/*
+ * Context switch.
+ *
+ * These is the CPU-specific parts of the context switcher cpu_switch()
+ * These functions actually perform the TTB reload.
+ *
+ * NOTE: Special calling convention
+ *	r1, r4-r13 must be preserved
+ */
+ENTRY(arm11_context_switch)
+	/*
+	 * We can assume that the caches will only contain kernel addresses
+	 * at this point.  So no need to flush them again.
+	 */
+	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
+	mcr	p15, 0, r0, c2, c0, 0	/* set the new TTB */
+	mcr	p15, 0, r0, c8, c7, 0	/* and flush the I+D tlbs */
+
+	/* Paranoia -- make sure the pipeline is empty. */
+	nop
+	nop
+	nop
+	RET
+END(arm11_context_switch)
+
+/*
+ * TLB functions
+ */
+ENTRY(arm11_tlb_flushID)
+	mcr	p15, 0, r0, c8, c7, 0	/* flush I+D tlb */
+	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
+	mov	pc, lr
+END(arm11_tlb_flushID)
+
+ENTRY(arm11_tlb_flushI)
+	mcr	p15, 0, r0, c8, c5, 0	/* flush I tlb */
+	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
+	mov	pc, lr
+END(arm11_tlb_flushI)
+
+ENTRY(arm11_tlb_flushD)
+	mcr	p15, 0, r0, c8, c6, 0	/* flush D tlb */
+	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
+	mov	pc, lr
+END(arm11_tlb_flushD)
+
+ENTRY(arm11_tlb_flushD_SE)
+	mcr	p15, 0, r0, c8, c6, 1	/* flush D tlb single entry */
+	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
+	mov	pc, lr
+END(arm11_tlb_flushD_SE)
+
+/*
+ * Other functions
+ */
+ENTRY(arm11_drain_writebuf)
+	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
+	mov	pc, lr
+END(arm11_drain_writebuf)
+
+ENTRY_NP(arm11_sleep)
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c0, 4   /* wait for interrupt */
+	RET
+END(arm11_sleep)
+


Property changes on: trunk/sys/arm/arm/cpufunc_asm_arm11.S
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/cpufunc_asm_arm11x6.S
===================================================================
--- trunk/sys/arm/arm/cpufunc_asm_arm11x6.S	                        (rev 0)
+++ trunk/sys/arm/arm/cpufunc_asm_arm11x6.S	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,223 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: cpufunc_asm_arm11x6.S,v 1.1 2012/07/21 12:19:15 skrll Exp $	*/
+
+/*
+ * Copyright (c) 2007 Microsoft
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Microsoft
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 CONTRIBUTERS 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.
+ */
+
+/*-
+ * Copyright (c) 2012 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Eben Upton
+ *
+ * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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 <machine/asm.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/cpufunc_asm_arm11x6.S 275767 2014-12-14 16:28:53Z andrew $");
+
+	.cpu arm1176jz-s
+
+#if 0
+#define Invalidate_I_cache(Rtmp1, Rtmp2) \
+	mcr	p15, 0, Rtmp1, c7, c5, 0	/* Invalidate Entire I cache */
+#else
+/*
+ * Workaround for
+ *
+ *    Erratum 411920 in ARM1136 (fixed in r1p4)
+ *    Erratum 415045 in ARM1176 (fixed in r0p5?)
+ * 
+ *	- value of arg 'reg' Should Be Zero
+ */
+#define Invalidate_I_cache(Rtmp1, Rtmp2) \
+	mov	Rtmp1, #0;		/* SBZ */			\
+	mrs	Rtmp2, cpsr;						\
+	cpsid	ifa;							\
+	mcr	p15, 0, Rtmp1, c7, c5, 0;	/* Nuke Whole Icache */	\
+	mcr	p15, 0, Rtmp1, c7, c5, 0;	/* Nuke Whole Icache */	\
+	mcr	p15, 0, Rtmp1, c7, c5, 0;	/* Nuke Whole Icache */	\
+	mcr	p15, 0, Rtmp1, c7, c5, 0;	/* Nuke Whole Icache */	\
+	msr	cpsr_cx, Rtmp2;						\
+	nop;								\
+	nop;								\
+	nop;								\
+	nop;								\
+	nop;								\
+	nop;								\
+	nop;								\
+	nop;								\
+	nop;								\
+	nop;								\
+	nop;
+#endif
+
+#if 1
+#define Flush_D_cache(reg) \
+	mov	reg, #0;		/* SBZ */					\
+	mcr	p15, 0, reg, c7, c14, 0;/* Clean and Invalidate Entire Data Cache */	\
+	mcr	p15, 0, reg, c7, c10, 4;/* Data Synchronization Barrier */
+#else
+#define Flush_D_cache(reg) \
+1:	mov	reg, #0;		/* SBZ */					\
+	mcr	p15, 0, reg, c7, c14, 0;/* Clean and Invalidate Entire Data Cache */	\
+	mrc	p15, 0, reg, C7, C10, 6;/* Read Cache Dirty Status Register */		\
+	ands	reg, reg, #01;		/* Check if it is clean */			\
+	bne	1b;			/* loop if not */				\
+	mcr	p15, 0, reg, c7, c10, 4;/* Data Synchronization Barrier */
+#endif
+
+ENTRY(arm11x6_setttb)
+	mov	r1, #0
+	mcr	p15, 0, r0, c2, c0, 0	/* load new TTB */
+	mcr	p15, 0, r1, c8, c7, 0	/* invalidate I+D TLBs */
+	mcr	p15, 0, r1, c7, c10, 4	/* drain write buffer */
+	RET
+END(arm11x6_setttb)
+
+ENTRY_NP(arm11x6_idcache_wbinv_all)
+	Flush_D_cache(r0)
+	Invalidate_I_cache(r0, r1)
+	RET
+END(arm11x6_idcache_wbinv_all)
+
+ENTRY_NP(arm11x6_dcache_wbinv_all)
+	Flush_D_cache(r0)
+	RET
+END(arm11x6_dcache_wbinv_all)
+
+ENTRY_NP(arm11x6_icache_sync_all)
+	Flush_D_cache(r0)
+	Invalidate_I_cache(r0, r1)
+	RET
+END(arm11x6_icache_sync_all)
+
+ENTRY_NP(arm11x6_flush_prefetchbuf)
+	mcr	p15, 0, r0, c7, c5, 4	/* Flush Prefetch Buffer */
+	RET
+END(arm11x6_flush_prefetchbuf)
+
+ENTRY_NP(arm11x6_icache_sync_range)
+	add	r1, r1, r0
+	sub	r1, r1, #1
+	/* Erratum ARM1136 371025, workaround #2 */
+	/* Erratum ARM1176 371367 */
+	mrs	r2, cpsr		/* save the CPSR */
+	cpsid	ifa			/* disable interrupts (irq,fiq,abort) */
+	mov	r3, #0 
+	mcr	p15, 0, r3, c13, c0, 0	/* write FCSE (uTLB invalidate) */
+	mcr	p15, 0, r3, c7, c5, 4	/* flush prefetch buffer */
+	add	r3, pc, #0x24 
+	mcr	p15, 0, r3, c7, c13, 1	/* prefetch I-cache line */
+	mcrr	p15, 0, r1, r0, c5	/* invalidate I-cache range */
+	msr	cpsr_cx, r2		/* local_irq_restore */
+	nop 
+	nop 
+	nop 
+	nop 
+	nop 
+	nop 
+	nop 
+
+	mcrr	p15, 0, r1, r0, c12	/* clean and invalidate D cache range */ /* XXXNH */
+	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
+	RET
+END(arm11x6_icache_sync_range)
+
+ENTRY_NP(arm11x6_idcache_wbinv_range)
+	add	r1, r1, r0
+	sub	r1, r1, #1
+	/* Erratum ARM1136 371025, workaround #2 */
+	/* Erratum ARM1176 371367 */
+	mrs	r2, cpsr		/* save the CPSR */
+	cpsid	ifa			/* disable interrupts (irq,fiq,abort) */
+	mov	r3, #0 
+	mcr	p15, 0, r3, c13, c0, 0	/* write FCSE (uTLB invalidate) */
+	mcr	p15, 0, r3, c7, c5, 4	/* flush prefetch buffer */
+	add	r3, pc, #0x24 
+	mcr	p15, 0, r3, c7, c13, 1	/* prefetch I-cache line */
+	mcrr	p15, 0, r1, r0, c5	/* invalidate I-cache range */
+	msr	cpsr_cx, r2		/* local_irq_restore */
+	nop 
+	nop 
+	nop 
+	nop 
+	nop 
+	nop 
+	nop 
+
+	mcrr	p15, 0, r1, r0, c14	/* clean and invalidate D cache range */
+	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
+	RET
+END(arm11x6_idcache_wbinv_range)
+
+/*
+ * Preload the cache before issuing the WFI by conditionally disabling the
+ * mcr intstructions the first time around the loop. Ensure the function is 
+ * cacheline aligned.
+ */
+	.arch	armv6
+	.p2align 5
+
+ENTRY_NP(arm11x6_sleep)
+	mov	r0, #0
+	mov	r1, #2
+1:
+	subs	r1, #1
+	nop
+	mcreq	p15, 0, r0, c7, c10, 4		/* data sync barrier */
+	mcreq	p15, 0, r0, c7, c0, 4		/* wait for interrupt */
+	nop
+	nop
+	nop
+	bne	1b
+	RET
+END(arm11x6_sleep)
+


Property changes on: trunk/sys/arm/arm/cpufunc_asm_arm11x6.S
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/cpufunc_asm_arm9.S
===================================================================
--- trunk/sys/arm/arm/cpufunc_asm_arm9.S	                        (rev 0)
+++ trunk/sys/arm/arm/cpufunc_asm_arm9.S	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,264 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: cpufunc_asm_arm9.S,v 1.3 2004/01/26 15:54:16 rearnsha Exp $	*/
+
+/*
+ * Copyright (c) 2001, 2004 ARM Limited
+ * 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.
+ * 3. The name of the company may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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.
+ *
+ * ARM9 assembly functions for CPU / MMU / TLB specific operations
+ */
+
+#include <machine/asm.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/cpufunc_asm_arm9.S 278652 2015-02-13 00:49:47Z ian $");
+
+/*
+ * Functions to set the MMU Translation Table Base register
+ *
+ * We need to clean and flush the cache as it uses virtual
+ * addresses that are about to change.
+ */
+ENTRY(arm9_setttb)
+	stmfd	sp!, {r0, lr}
+	bl	_C_LABEL(arm9_idcache_wbinv_all)
+	ldmfd	sp!, {r0, lr}
+
+	mcr	p15, 0, r0, c2, c0, 0	/* load new TTB */
+
+	mcr	p15, 0, r0, c8, c7, 0	/* invalidate I+D TLBs */
+	mov	pc, lr
+END(arm9_setttb)
+
+/*
+ * TLB functions
+ */
+ENTRY(arm9_tlb_flushID_SE)
+	mcr	p15, 0, r0, c8, c6, 1	/* flush D tlb single entry */
+	mcr	p15, 0, r0, c8, c5, 1	/* flush I tlb single entry */
+	mov	pc, lr
+END(arm9_tlb_flushID_SE)
+
+/*
+ * Cache operations.  For the entire cache we use the set/index
+ * operations.
+ */
+	s_max	.req r0
+	i_max	.req r1
+	s_inc	.req r2
+	i_inc	.req r3
+
+ENTRY_NP(arm9_icache_sync_range)
+	ldr	ip, .Larm9_line_size
+	cmp	r1, #0x4000
+	bcs	.Larm9_icache_sync_all
+	ldr	ip, [ip]
+	sub	r3, ip, #1
+	and	r2, r0, r3
+	add	r1, r1, r2
+	bic	r0, r0, r3
+.Larm9_sync_next:
+	mcr	p15, 0, r0, c7, c5, 1	/* Invalidate I cache SE with VA */
+	mcr	p15, 0, r0, c7, c10, 1	/* Clean D cache SE with VA */
+	add	r0, r0, ip
+	subs	r1, r1, ip
+	bhi	.Larm9_sync_next
+	mov	pc, lr
+END(arm9_icache_sync_range)
+
+ENTRY_NP(arm9_icache_sync_all)
+.Larm9_icache_sync_all:
+	/*
+	 * We assume that the code here can never be out of sync with the
+	 * dcache, so that we can safely flush the Icache and fall through
+	 * into the Dcache cleaning code.
+	 */
+	mcr	p15, 0, r0, c7, c5, 0	/* Flush I cache */
+	/* Fall through to clean Dcache. */
+
+.Larm9_dcache_wb:
+	ldr	ip, .Larm9_cache_data
+	ldmia	ip, {s_max, i_max, s_inc, i_inc}
+.Lnext_set:
+	orr	ip, s_max, i_max
+.Lnext_index:
+	mcr	p15, 0, ip, c7, c10, 2	/* Clean D cache SE with Set/Index */
+	subs	ip, ip, i_inc
+	bhs	.Lnext_index		/* Next index */
+	subs	s_max, s_max, s_inc
+	bhs	.Lnext_set		/* Next set */
+	mov	pc, lr
+END(arm9_icache_sync_all)
+
+.Larm9_line_size:
+	.word	_C_LABEL(arm_pdcache_line_size)
+
+ENTRY(arm9_dcache_wb_range)
+	ldr	ip, .Larm9_line_size
+	cmp	r1, #0x4000
+	bcs	.Larm9_dcache_wb
+	ldr	ip, [ip]
+	sub	r3, ip, #1
+	and	r2, r0, r3
+	add	r1, r1, r2
+	bic	r0, r0, r3
+.Larm9_wb_next:
+	mcr	p15, 0, r0, c7, c10, 1	/* Clean D cache SE with VA */
+	add	r0, r0, ip
+	subs	r1, r1, ip
+	bhi	.Larm9_wb_next
+	mov	pc, lr
+END(arm9_dcache_wb_range)
+	
+ENTRY(arm9_dcache_wbinv_range)
+	ldr	ip, .Larm9_line_size
+	cmp	r1, #0x4000
+	bcs	.Larm9_dcache_wbinv_all
+	ldr	ip, [ip]
+	sub	r3, ip, #1
+	and	r2, r0, r3
+	add	r1, r1, r2
+	bic	r0, r0, r3
+.Larm9_wbinv_next:
+	mcr	p15, 0, r0, c7, c14, 1	/* Purge D cache SE with VA */
+	add	r0, r0, ip
+	subs	r1, r1, ip
+	bhi	.Larm9_wbinv_next
+	mov	pc, lr
+END(arm9_dcache_wbinv_range)
+	
+/*
+ * Note, we must not invalidate everything.  If the range is too big we
+ * must use wb-inv of the entire cache.
+ */
+ENTRY(arm9_dcache_inv_range)
+	ldr	ip, .Larm9_line_size
+	cmp	r1, #0x4000
+	bcs	.Larm9_dcache_wbinv_all
+	ldr	ip, [ip]
+	sub	r3, ip, #1
+	and	r2, r0, r3
+	add	r1, r1, r2
+	bic	r0, r0, r3
+.Larm9_inv_next:
+	mcr	p15, 0, r0, c7, c6, 1	/* Invalidate D cache SE with VA */
+	add	r0, r0, ip
+	subs	r1, r1, ip
+	bhi	.Larm9_inv_next
+	mov	pc, lr
+END(arm9_dcache_inv_range)
+
+ENTRY(arm9_idcache_wbinv_range)
+	ldr	ip, .Larm9_line_size
+	cmp	r1, #0x4000
+	bcs	.Larm9_idcache_wbinv_all
+	ldr	ip, [ip]
+	sub	r3, ip, #1
+	and	r2, r0, r3
+	add	r1, r1, r2
+	bic	r0, r0, r3
+.Larm9_id_wbinv_next:
+	mcr	p15, 0, r0, c7, c5, 1	/* Invalidate I cache SE with VA */
+	mcr	p15, 0, r0, c7, c14, 1	/* Purge D cache SE with VA */
+	add	r0, r0, ip
+	subs	r1, r1, ip
+	bhi	.Larm9_id_wbinv_next
+	mov	pc, lr
+END(arm9_idcache_wbinv_range)
+
+ENTRY_NP(arm9_idcache_wbinv_all)
+.Larm9_idcache_wbinv_all:
+	/*
+	 * We assume that the code here can never be out of sync with the
+	 * dcache, so that we can safely flush the Icache and fall through
+	 * into the Dcache purging code.
+	 */
+	mcr	p15, 0, r0, c7, c5, 0	/* Flush I cache */
+	/* Fall through */
+
+EENTRY(arm9_dcache_wbinv_all)
+.Larm9_dcache_wbinv_all:
+	ldr	ip, .Larm9_cache_data
+	ldmia	ip, {s_max, i_max, s_inc, i_inc}
+.Lnext_set_inv:
+	orr	ip, s_max, i_max
+.Lnext_index_inv:
+	mcr	p15, 0, ip, c7, c14, 2	/* Purge D cache SE with Set/Index */
+	subs	ip, ip, i_inc
+	bhs	.Lnext_index_inv		/* Next index */
+	subs	s_max, s_max, s_inc
+	bhs	.Lnext_set_inv		/* Next set */
+	mov	pc, lr
+EEND(arm9_dcache_wbinv_all)
+END(arm9_idcache_wbinv_all)
+
+.Larm9_cache_data:
+	.word	_C_LABEL(arm9_dcache_sets_max)
+
+/*
+ * Context switch.
+ *
+ * These is the CPU-specific parts of the context switcher cpu_switch()
+ * These functions actually perform the TTB reload.
+ *
+ * NOTE: Special calling convention
+ *	r1, r4-r13 must be preserved
+ */
+ENTRY(arm9_context_switch)
+	/*
+	 * We can assume that the caches will only contain kernel addresses
+	 * at this point.  So no need to flush them again.
+	 */
+	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
+	mcr	p15, 0, r0, c2, c0, 0	/* set the new TTB */
+	mcr	p15, 0, r0, c8, c7, 0	/* and flush the I+D tlbs */
+
+	/* Paranoia -- make sure the pipeline is empty. */
+	nop
+	nop
+	nop
+	mov	pc, lr
+END(arm9_context_switch)
+
+	.bss
+
+/* XXX The following macros should probably be moved to asm.h */
+#define _DATA_OBJECT(x) .globl x; .type x,_ASM_TYPE_OBJECT; x:
+#define C_OBJECT(x)	_DATA_OBJECT(_C_LABEL(x))
+
+/*
+ * Parameters for the cache cleaning code.  Note that the order of these
+ * four variables is assumed in the code above.  Hence the reason for
+ * declaring them in the assembler file.
+ */
+	.align 2
+C_OBJECT(arm9_dcache_sets_max)
+	.space	4
+C_OBJECT(arm9_dcache_index_max)
+	.space	4
+C_OBJECT(arm9_dcache_sets_inc)
+	.space	4
+C_OBJECT(arm9_dcache_index_inc)
+	.space	4


Property changes on: trunk/sys/arm/arm/cpufunc_asm_arm9.S
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/cpufunc_asm_armv4.S
===================================================================
--- trunk/sys/arm/arm/cpufunc_asm_armv4.S	                        (rev 0)
+++ trunk/sys/arm/arm/cpufunc_asm_armv4.S	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,80 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: cpufunc_asm_armv4.S,v 1.1 2001/11/10 23:14:09 thorpej Exp $	*/
+
+/*-
+ * Copyright (c) 2001 ARM Limited
+ * Copyright (c) 1997,1998 Mark Brinicombe.
+ * Copyright (c) 1997 Causality Limited
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Causality Limited.
+ * 4. The name of Causality Limited may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY CAUSALITY LIMITED ``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 CAUSALITY LIMITED 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.
+ *
+ * ARM9 assembly functions for CPU / MMU / TLB specific operations
+ *
+ */
+
+#include <machine/asm.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/cpufunc_asm_armv4.S 266203 2014-05-16 00:14:50Z ian $");
+
+/*
+ * TLB functions
+ */
+ENTRY(armv4_tlb_flushID)
+	mcr	p15, 0, r0, c8, c7, 0	/* flush I+D tlb */
+	RET
+END(armv4_tlb_flushID)
+
+ENTRY(armv4_tlb_flushI)
+	mcr	p15, 0, r0, c8, c5, 0	/* flush I tlb */
+	RET
+END(armv4_tlb_flushI)
+
+ENTRY(armv4_tlb_flushD)
+	mcr	p15, 0, r0, c8, c6, 0	/* flush D tlb */
+	RET
+END(armv4_tlb_flushD)
+
+ENTRY(armv4_tlb_flushD_SE)
+	mcr	p15, 0, r0, c8, c6, 1	/* flush D tlb single entry */
+	RET
+END(armv4_tlb_flushD_SE)
+
+/*
+ * Other functions
+ */
+ENTRY(armv4_drain_writebuf)
+	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
+	RET
+END(armv4_drain_writebuf)
+
+ENTRY(armv4_idcache_inv_all)
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c7, 0	/* invalidate all I+D cache */
+	RET
+END(armv4_drain_writebuf)
+


Property changes on: trunk/sys/arm/arm/cpufunc_asm_armv4.S
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/cpufunc_asm_armv5.S
===================================================================
--- trunk/sys/arm/arm/cpufunc_asm_armv5.S	                        (rev 0)
+++ trunk/sys/arm/arm/cpufunc_asm_armv5.S	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,248 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: cpufunc_asm_armv5.S,v 1.3 2007/01/06 00:50:54 christos Exp $	*/
+
+/*
+ * Copyright (c) 2002, 2005 ARM Limited
+ * 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.
+ * 3. The name of the company may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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.
+ *
+ * ARMv5 assembly functions for manipulating caches.
+ * These routines can be used by any core that supports the set/index
+ * operations.
+ */
+
+#include <machine/asm.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/cpufunc_asm_armv5.S 278652 2015-02-13 00:49:47Z ian $");
+
+/*
+ * Functions to set the MMU Translation Table Base register
+ *
+ * We need to clean and flush the cache as it uses virtual
+ * addresses that are about to change.
+ */
+ENTRY(armv5_setttb)
+	stmfd	sp!, {r0, lr}
+	bl	_C_LABEL(armv5_idcache_wbinv_all)
+	ldmfd	sp!, {r0, lr}
+
+	mcr	p15, 0, r0, c2, c0, 0	/* load new TTB */
+
+	mcr	p15, 0, r0, c8, c7, 0	/* invalidate I+D TLBs */
+	RET
+END(armv5_setttb)
+
+/*
+ * Cache operations.  For the entire cache we use the set/index
+ * operations.
+ */
+	s_max	.req r0
+	i_max	.req r1
+	s_inc	.req r2
+	i_inc	.req r3
+
+ENTRY_NP(armv5_icache_sync_range)
+	ldr	ip, .Larmv5_line_size
+	cmp	r1, #0x4000
+	bcs	.Larmv5_icache_sync_all
+	ldr	ip, [ip]
+	sub	r1, r1, #1		/* Don't overrun */
+	sub	r3, ip, #1
+	and	r2, r0, r3
+	add	r1, r1, r2
+	bic	r0, r0, r3
+1:
+	mcr	p15, 0, r0, c7, c5, 1	/* Invalidate I cache SE with VA */
+	mcr	p15, 0, r0, c7, c10, 1	/* Clean D cache SE with VA */
+	add	r0, r0, ip
+	subs	r1, r1, ip
+	bpl	1b
+	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
+	RET
+END(armv5_icache_sync_range)
+
+ENTRY_NP(armv5_icache_sync_all)
+.Larmv5_icache_sync_all:
+	/*
+	 * We assume that the code here can never be out of sync with the
+	 * dcache, so that we can safely flush the Icache and fall through
+	 * into the Dcache cleaning code.
+	 */
+	mcr	p15, 0, r0, c7, c5, 0	/* Flush I cache */
+	/* Fall through to clean Dcache. */
+
+.Larmv5_dcache_wb:
+	ldr	ip, .Larmv5_cache_data
+	ldmia	ip, {s_max, i_max, s_inc, i_inc}
+1:
+	orr	ip, s_max, i_max
+2:
+	mcr	p15, 0, ip, c7, c10, 2	/* Clean D cache SE with Set/Index */
+	sub	ip, ip, i_inc
+	tst	ip, i_max		/* Index 0 is last one */
+	bne	2b			/* Next index */
+	mcr	p15, 0, ip, c7, c10, 2	/* Clean D cache SE with Set/Index */
+	subs	s_max, s_max, s_inc
+	bpl	1b			/* Next set */
+	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
+	RET
+END(armv5_icache_sync_all)
+
+.Larmv5_line_size:
+	.word	_C_LABEL(arm_pdcache_line_size)
+
+ENTRY(armv5_dcache_wb_range)
+	ldr	ip, .Larmv5_line_size
+	cmp	r1, #0x4000
+	bcs	.Larmv5_dcache_wb
+	ldr	ip, [ip]
+	sub	r1, r1, #1		/* Don't overrun */
+	sub	r3, ip, #1
+	and	r2, r0, r3
+	add	r1, r1, r2
+	bic	r0, r0, r3
+1:
+	mcr	p15, 0, r0, c7, c10, 1	/* Clean D cache SE with VA */
+	add	r0, r0, ip
+	subs	r1, r1, ip
+	bpl	1b
+	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
+	RET
+END(armv5_dcache_wb_range)
+	
+ENTRY(armv5_dcache_wbinv_range)
+	ldr	ip, .Larmv5_line_size
+	cmp	r1, #0x4000
+	bcs	.Larmv5_dcache_wbinv_all
+	ldr	ip, [ip]
+	sub	r1, r1, #1		/* Don't overrun */
+	sub	r3, ip, #1
+	and	r2, r0, r3
+	add	r1, r1, r2
+	bic	r0, r0, r3
+1:
+	mcr	p15, 0, r0, c7, c14, 1	/* Purge D cache SE with VA */
+	add	r0, r0, ip
+	subs	r1, r1, ip
+	bpl	1b
+	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
+	RET
+END(armv5_dcache_wbinv_range)
+	
+/*
+ * Note, we must not invalidate everything.  If the range is too big we
+ * must use wb-inv of the entire cache.
+ */
+ENTRY(armv5_dcache_inv_range)
+	ldr	ip, .Larmv5_line_size
+	cmp	r1, #0x4000
+	bcs	.Larmv5_dcache_wbinv_all
+	ldr	ip, [ip]
+	sub	r1, r1, #1		/* Don't overrun */
+	sub	r3, ip, #1
+	and	r2, r0, r3
+	add	r1, r1, r2
+	bic	r0, r0, r3
+1:
+	mcr	p15, 0, r0, c7, c6, 1	/* Invalidate D cache SE with VA */
+	add	r0, r0, ip
+	subs	r1, r1, ip
+	bpl	1b
+	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
+	RET
+END(armv5_dcache_inv_range)
+
+ENTRY(armv5_idcache_wbinv_range)
+	ldr	ip, .Larmv5_line_size
+	cmp	r1, #0x4000
+	bcs	.Larmv5_idcache_wbinv_all
+	ldr	ip, [ip]
+	sub	r1, r1, #1		/* Don't overrun */
+	sub	r3, ip, #1
+	and	r2, r0, r3
+	add	r1, r1, r2
+	bic	r0, r0, r3
+1:
+	mcr	p15, 0, r0, c7, c5, 1	/* Invalidate I cache SE with VA */
+	mcr	p15, 0, r0, c7, c14, 1	/* Purge D cache SE with VA */
+	add	r0, r0, ip
+	subs	r1, r1, ip
+	bpl	1b
+	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
+	RET
+END(armv5_idcache_wbinv_range)
+
+ENTRY_NP(armv5_idcache_wbinv_all)
+.Larmv5_idcache_wbinv_all:
+	/*
+	 * We assume that the code here can never be out of sync with the
+	 * dcache, so that we can safely flush the Icache and fall through
+	 * into the Dcache purging code.
+	 */
+	mcr	p15, 0, r0, c7, c5, 0	/* Flush I cache */
+	/* Fall through to purge Dcache. */
+
+EENTRY(armv5_dcache_wbinv_all)
+.Larmv5_dcache_wbinv_all:
+	ldr	ip, .Larmv5_cache_data
+	ldmia	ip, {s_max, i_max, s_inc, i_inc}
+1:
+	orr	ip, s_max, i_max
+2:
+	mcr	p15, 0, ip, c7, c14, 2	/* Purge D cache SE with Set/Index */
+	sub	ip, ip, i_inc
+	tst	ip, i_max		/* Index 0 is last one */
+	bne	2b			/* Next index */
+	mcr	p15, 0, ip, c7, c14, 2	/* Purge D cache SE with Set/Index */
+	subs	s_max, s_max, s_inc
+	bpl	1b			/* Next set */
+	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
+	RET
+EEND(armv5_dcache_wbinv_all)
+END(armv5_idcache_wbinv_all)
+
+.Larmv5_cache_data:
+	.word	_C_LABEL(armv5_dcache_sets_max)
+
+	.bss
+
+/* XXX The following macros should probably be moved to asm.h */
+#define _DATA_OBJECT(x) .globl x; .type x,_ASM_TYPE_OBJECT; x:
+#define C_OBJECT(x)	_DATA_OBJECT(_C_LABEL(x))
+
+/*
+ * Parameters for the cache cleaning code.  Note that the order of these
+ * four variables is assumed in the code above.  Hence the reason for
+ * declaring them in the assembler file.
+ */
+	.align 2
+C_OBJECT(armv5_dcache_sets_max)
+	.space	4
+C_OBJECT(armv5_dcache_index_max)
+	.space	4
+C_OBJECT(armv5_dcache_sets_inc)
+	.space	4
+C_OBJECT(armv5_dcache_index_inc)
+	.space	4


Property changes on: trunk/sys/arm/arm/cpufunc_asm_armv5.S
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/cpufunc_asm_armv5_ec.S
===================================================================
--- trunk/sys/arm/arm/cpufunc_asm_armv5_ec.S	                        (rev 0)
+++ trunk/sys/arm/arm/cpufunc_asm_armv5_ec.S	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,217 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: cpufunc_asm_armv5_ec.S,v 1.1 2007/01/06 00:50:54 christos Exp $	*/
+
+/*
+ * Copyright (c) 2002, 2005 ARM Limited
+ * 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.
+ * 3. The name of the company may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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.
+ *
+ * ARMv5 assembly functions for manipulating caches.
+ * These routines can be used by any core that supports both the set/index
+ * operations and the test and clean operations for efficiently cleaning the
+ * entire DCache.  If a core does not have the test and clean operations, but
+ * does have the set/index operations, use the routines in cpufunc_asm_armv5.S.
+ * This source was derived from that file.
+ */
+
+#include <machine/asm.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/cpufunc_asm_armv5_ec.S 248361 2013-03-16 02:48:49Z andrew $");
+
+/*
+ * Functions to set the MMU Translation Table Base register
+ *
+ * We need to clean and flush the cache as it uses virtual
+ * addresses that are about to change.
+ */
+ENTRY(armv5_ec_setttb)
+	/*
+	 * Some other ARM ports save registers on the stack, call the
+	 * idcache_wbinv_all function and then restore the registers from the
+	 * stack before setting the TTB.  I observed that this caused a
+	 * problem when the old and new translation table entries' buffering
+	 * bits were different.  If I saved the registers in other registers
+	 * or invalidated the caches when I returned from idcache_wbinv_all,
+	 * it worked fine.  If not, I ended up executing at an invalid PC.
+	 * For armv5_ec_settb, the idcache_wbinv_all is simple enough, I just
+	 * do it directly and entirely avoid the problem.
+	 */
+	mcr	p15, 0, r0, c7, c5, 0	/* Invalidate ICache */
+1:	mrc	p15, 0, r15, c7, c14, 3	/* Test, clean and invalidate DCache */
+	bne	1b			/* More to do? */
+	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
+
+	mcr	p15, 0, r0, c2, c0, 0	/* load new TTB */
+
+	mcr	p15, 0, r0, c8, c7, 0	/* invalidate I+D TLBs */
+	RET
+END(armv5_ec_setttb)
+
+/*
+ * Cache operations.  For the entire cache we use the enhanced cache
+ * operations.
+ */
+
+ENTRY_NP(armv5_ec_icache_sync_range)
+	ldr	ip, .Larmv5_ec_line_size
+	cmp	r1, #0x4000
+	bcs	.Larmv5_ec_icache_sync_all
+	ldr	ip, [ip]
+	sub	r1, r1, #1		/* Don't overrun */
+	sub	r3, ip, #1
+	and	r2, r0, r3
+	add	r1, r1, r2
+	bic	r0, r0, r3
+1:
+	mcr	p15, 0, r0, c7, c5, 1	/* Invalidate I cache SE with VA */
+	mcr	p15, 0, r0, c7, c10, 1	/* Clean D cache SE with VA */
+	add	r0, r0, ip
+	subs	r1, r1, ip
+	bpl	1b
+	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
+	RET
+END(armv5_ec_icache_sync_range)
+
+ENTRY_NP(armv5_ec_icache_sync_all)
+.Larmv5_ec_icache_sync_all:
+	/*
+	 * We assume that the code here can never be out of sync with the
+	 * dcache, so that we can safely flush the Icache and fall through
+	 * into the Dcache cleaning code.
+	 */
+	mcr	p15, 0, r0, c7, c5, 0	/* Flush I cache */
+	/* Fall through to clean Dcache. */
+
+.Larmv5_ec_dcache_wb:
+1:
+	mrc	p15, 0, r15, c7, c10, 3	/* Test and clean (don't invalidate) */
+	bne	1b			/* More to do? */
+	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
+	RET
+END(armv5_ec_icache_sync_all)
+
+.Larmv5_ec_line_size:
+	.word	_C_LABEL(arm_pdcache_line_size)
+
+ENTRY(armv5_ec_dcache_wb_range)
+	ldr	ip, .Larmv5_ec_line_size
+	cmp	r1, #0x4000
+	bcs	.Larmv5_ec_dcache_wb
+	ldr	ip, [ip]
+	sub	r1, r1, #1		/* Don't overrun */
+	sub	r3, ip, #1
+	and	r2, r0, r3
+	add	r1, r1, r2
+	bic	r0, r0, r3
+1:
+	mcr	p15, 0, r0, c7, c10, 1	/* Clean D cache SE with VA */
+	add	r0, r0, ip
+	subs	r1, r1, ip
+	bpl	1b
+	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
+	RET
+END(armv5_ec_dcache_wb_range)
+
+ENTRY(armv5_ec_dcache_wbinv_range)
+	ldr	ip, .Larmv5_ec_line_size
+	cmp	r1, #0x4000
+	bcs	.Larmv5_ec_dcache_wbinv_all
+	ldr	ip, [ip]
+	sub	r1, r1, #1		/* Don't overrun */
+	sub	r3, ip, #1
+	and	r2, r0, r3
+	add	r1, r1, r2
+	bic	r0, r0, r3
+1:
+	mcr	p15, 0, r0, c7, c14, 1	/* Purge D cache SE with VA */
+	add	r0, r0, ip
+	subs	r1, r1, ip
+	bpl	1b
+	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
+	RET
+END(armv5_ec_dcache_wbinv_range)
+
+/*
+ * Note, we must not invalidate everything.  If the range is too big we
+ * must use wb-inv of the entire cache.
+ */
+ENTRY(armv5_ec_dcache_inv_range)
+	ldr	ip, .Larmv5_ec_line_size
+	cmp	r1, #0x4000
+	bcs	.Larmv5_ec_dcache_wbinv_all
+	ldr	ip, [ip]
+	sub	r1, r1, #1		/* Don't overrun */
+	sub	r3, ip, #1
+	and	r2, r0, r3
+	add	r1, r1, r2
+	bic	r0, r0, r3
+1:
+	mcr	p15, 0, r0, c7, c6, 1	/* Invalidate D cache SE with VA */
+	add	r0, r0, ip
+	subs	r1, r1, ip
+	bpl	1b
+	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
+	RET
+END(armv5_ec_dcache_inv_range)
+
+ENTRY(armv5_ec_idcache_wbinv_range)
+	ldr	ip, .Larmv5_ec_line_size
+	cmp	r1, #0x4000
+	bcs	.Larmv5_ec_idcache_wbinv_all
+	ldr	ip, [ip]
+	sub	r1, r1, #1		/* Don't overrun */
+	sub	r3, ip, #1
+	and	r2, r0, r3
+	add	r1, r1, r2
+	bic	r0, r0, r3
+1:
+	mcr	p15, 0, r0, c7, c5, 1	/* Invalidate I cache SE with VA */
+	mcr	p15, 0, r0, c7, c14, 1	/* Purge D cache SE with VA */
+	add	r0, r0, ip
+	subs	r1, r1, ip
+	bpl	1b
+	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
+	RET
+END(armv5_ec_idcache_wbinv_range)
+
+ENTRY_NP(armv5_ec_idcache_wbinv_all)
+.Larmv5_ec_idcache_wbinv_all:
+	/*
+	 * We assume that the code here can never be out of sync with the
+	 * dcache, so that we can safely flush the Icache and fall through
+	 * into the Dcache purging code.
+	 */
+	mcr	p15, 0, r0, c7, c5, 0	/* Invalidate ICache */
+	/* Fall through to purge Dcache. */
+END(armv5_ec_idcache_wbinv_all)
+
+ENTRY(armv5_ec_dcache_wbinv_all)
+.Larmv5_ec_dcache_wbinv_all:
+1:	mrc	p15, 0, r15, c7, c14, 3	/* Test, clean and invalidate DCache */
+	bne	1b			/* More to do? */
+	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
+	RET
+END(armv5_ec_dcache_wbinv_all)
+


Property changes on: trunk/sys/arm/arm/cpufunc_asm_armv5_ec.S
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/cpufunc_asm_armv6.S
===================================================================
--- trunk/sys/arm/arm/cpufunc_asm_armv6.S	                        (rev 0)
+++ trunk/sys/arm/arm/cpufunc_asm_armv6.S	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,153 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: cpufunc_asm_armv6.S,v 1.4 2010/12/10 02:06:22 bsh Exp $	*/
+
+/*
+ * Copyright (c) 2002, 2005 ARM Limited
+ * Portions Copyright (c) 2007 Microsoft
+ * 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.
+ * 3. The name of the company may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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.
+ *
+ * ARMv6 assembly functions for manipulating caches.
+ * These routines can be used by any core that supports the mcrr address
+ * range operations.
+ */
+
+/*
+ * $FreeBSD: stable/10/sys/arm/arm/cpufunc_asm_armv6.S 269796 2014-08-11 01:29:28Z ian $
+ */
+ 
+#include <machine/asm.h>
+
+	.arch	armv6
+
+/*
+ * Functions to set the MMU Translation Table Base register
+ *
+ * We need to clean and flush the cache as it uses virtual
+ * addresses that are about to change.
+ */
+ENTRY(armv6_setttb)
+	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
+
+	mcr	p15, 0, r0, c2, c0, 0	/* load new TTB */
+
+	mcr	p15, 0, r0, c8, c7, 0	/* invalidate I+D TLBs */
+	RET
+END(armv6_setttb)
+
+/*
+ * Cache operations.
+ */
+
+/* LINTSTUB: void armv6_icache_sync_range(vaddr_t, vsize_t); */
+ENTRY_NP(armv6_icache_sync_range)
+	add	r1, r1, r0
+	sub	r1, r1, #1
+	mcrr	p15, 0, r1, r0, c5	/* invalidate I cache range */
+	mcrr	p15, 0, r1, r0, c12	/* clean D cache range */
+	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
+	RET
+END(armv6_icache_sync_range)
+
+/* LINTSTUB: void armv6_icache_sync_all(void); */
+ENTRY_NP(armv6_icache_sync_all)
+	/*
+	 * We assume that the code here can never be out of sync with the
+	 * dcache, so that we can safely flush the Icache and fall through
+	 * into the Dcache cleaning code.
+	 */
+	mcr	p15, 0, r0, c7, c5, 0	/* Flush I cache */
+	mcr	p15, 0, r0, c7, c10, 0	/* Clean D cache */
+	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
+	RET
+END(armv6_icache_sync_all)
+
+/* LINTSTUB: void armv6_dcache_wb_range(vaddr_t, vsize_t); */
+ENTRY(armv6_dcache_wb_range)
+	add	r1, r1, r0
+	sub	r1, r1, #1
+	mcrr	p15, 0, r1, r0, c12	/* clean D cache range */
+	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
+	RET
+END(armv6_dcache_wb_range)
+	
+/* LINTSTUB: void armv6_dcache_wbinv_range(vaddr_t, vsize_t); */
+ENTRY(armv6_dcache_wbinv_range)
+	add	r1, r1, r0
+	sub	r1, r1, #1
+	mcrr	p15, 0, r1, r0, c14	/* clean and invaliate D cache range */
+	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
+	RET
+END(armv6_dcache_wbinv_range)
+	
+/*
+ * Note, we must not invalidate everything.  If the range is too big we
+ * must use wb-inv of the entire cache.
+ *
+ * LINTSTUB: void armv6_dcache_inv_range(vaddr_t, vsize_t);
+ */
+ENTRY(armv6_dcache_inv_range)
+	add	r1, r1, r0
+	sub	r1, r1, #1
+	mcrr	p15, 0, r1, r0, c6	/* invaliate D cache range */
+	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
+	RET
+END(armv6_dcache_inv_range)
+
+/* LINTSTUB: void armv6_idcache_wbinv_range(vaddr_t, vsize_t); */
+ENTRY(armv6_idcache_wbinv_range)
+	add	r1, r1, r0
+	sub	r1, r1, #1
+	mcrr	p15, 0, r1, r0, c5	/* invaliate I cache range */
+	mcrr	p15, 0, r1, r0, c14	/* clean & invaliate D cache range */
+	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
+	RET
+END(armv6_idcache_wbinv_range)
+
+/* LINTSTUB: void armv6_idcache_wbinv_all(void); */
+ENTRY_NP(armv6_idcache_wbinv_all)
+	/*
+	 * We assume that the code here can never be out of sync with the
+	 * dcache, so that we can safely flush the Icache and fall through
+	 * into the Dcache purging code.
+	 */
+	mcr	p15, 0, r0, c7, c5, 0	/* Flush I cache */
+	/* Fall through to purge Dcache. */
+
+/* LINTSTUB: void armv6_dcache_wbinv_all(void); */
+EENTRY(armv6_dcache_wbinv_all)
+	mcr	p15, 0, r0, c7, c14, 0	/* clean & invalidate D cache */
+	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
+	RET
+EEND(armv6_dcache_wbinv_all)
+END(armv6_idcache_wbinv_all)
+
+ENTRY(armv6_idcache_inv_all)
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c7, 0	/* invalidate all I+D cache */
+	RET
+END(armv6_idcache_inv_all)
+


Property changes on: trunk/sys/arm/arm/cpufunc_asm_armv6.S
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/cpufunc_asm_armv7.S
===================================================================
--- trunk/sys/arm/arm/cpufunc_asm_armv7.S	                        (rev 0)
+++ trunk/sys/arm/arm/cpufunc_asm_armv7.S	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,375 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2010 Per Odlund <per.odlund at armagedon.se>
+ * Copyright (C) 2011 MARVELL INTERNATIONAL LTD.
+ * All rights reserved.
+ *
+ * Developed by Semihalf.
+ *
+ * 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.
+ * 3. Neither the name of MARVELL nor the names of contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY 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 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 <machine/asm.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/cpufunc_asm_armv7.S 283499 2015-05-24 18:23:57Z ian $");
+
+#include <machine/sysreg.h>
+
+	.cpu cortex-a8
+
+.Lcoherency_level:
+	.word	_C_LABEL(arm_cache_loc)
+.Lcache_type:
+	.word	_C_LABEL(arm_cache_type)
+.Larmv7_dcache_line_size:
+	.word	_C_LABEL(arm_dcache_min_line_size)
+.Larmv7_icache_line_size:
+	.word	_C_LABEL(arm_icache_min_line_size)
+.Larmv7_idcache_line_size:
+	.word	_C_LABEL(arm_idcache_min_line_size)
+.Lway_mask:
+	.word	0x3ff
+.Lmax_index:
+	.word	0x7fff
+.Lpage_mask:
+	.word	0xfff
+
+#define PT_NOS          (1 << 5)
+#define PT_S 	        (1 << 1)
+#define PT_INNER_NC	0
+#define PT_INNER_WT	(1 << 0)
+#define PT_INNER_WB	((1 << 0) | (1 << 6))
+#define PT_INNER_WBWA	(1 << 6)
+#define PT_OUTER_NC	0
+#define PT_OUTER_WT	(2 << 3)
+#define PT_OUTER_WB	(3 << 3)
+#define PT_OUTER_WBWA	(1 << 3)
+	
+#ifdef SMP
+#define PT_ATTR	(PT_S|PT_INNER_WBWA|PT_OUTER_WBWA|PT_NOS)
+#else
+#define PT_ATTR	(PT_INNER_WBWA|PT_OUTER_WBWA)
+#endif
+
+ENTRY(armv7_setttb)
+ 	dsb
+	orr 	r0, r0, #PT_ATTR
+ 	mcr	CP15_TTBR0(r0)
+	isb
+#ifdef SMP
+ 	mcr	CP15_TLBIALLIS
+#else
+ 	mcr     CP15_TLBIALL
+#endif
+ 	dsb
+ 	isb
+	RET
+END(armv7_setttb)
+
+ENTRY(armv7_tlb_flushID)
+	dsb
+#ifdef SMP
+	mcr	CP15_TLBIALLIS
+	mcr	CP15_BPIALLIS
+#else
+	mcr	CP15_TLBIALL
+	mcr	CP15_BPIALL
+#endif
+	dsb
+	isb
+	mov	pc, lr
+END(armv7_tlb_flushID)
+
+ENTRY(armv7_tlb_flushID_SE)
+	ldr	r1, .Lpage_mask
+	bic	r0, r0, r1
+#ifdef SMP
+	mcr	CP15_TLBIMVAAIS(r0)
+	mcr	CP15_BPIALLIS
+#else
+	mcr	CP15_TLBIMVA(r0)
+	mcr	CP15_BPIALL
+#endif
+	dsb
+	isb
+	mov	pc, lr
+END(armv7_tlb_flushID_SE)
+
+/* Based on algorithm from ARM Architecture Reference Manual */
+ENTRY(armv7_dcache_wbinv_all)
+	stmdb	sp!, {r4, r5, r6, r7, r8, r9}
+
+	/* Get cache level */
+	ldr	r0, .Lcoherency_level
+	ldr	r3, [r0]
+	cmp	r3, #0
+	beq	Finished
+	/* For each cache level */
+	mov	r8, #0
+Loop1:
+	/* Get cache type for given level */
+	mov	r2, r8, lsl #2
+	add	r2, r2, r2
+	ldr	r0, .Lcache_type
+	ldr	r1, [r0, r2]
+
+	/* Get line size */
+	and	r2, r1, #7
+	add	r2, r2, #4
+
+	/* Get number of ways */
+	ldr	r4, .Lway_mask
+	ands	r4, r4, r1, lsr #3
+	clz	r5, r4
+
+	/* Get max index */
+	ldr	r7, .Lmax_index
+	ands	r7, r7, r1, lsr #13
+Loop2:
+	mov	r9, r4
+Loop3:
+	mov	r6, r8, lsl #1
+	orr	r6, r6, r9, lsl r5
+	orr	r6, r6, r7, lsl r2
+
+	/* Clean and invalidate data cache by way/index */
+	mcr	CP15_DCCISW(r6)
+	subs	r9, r9, #1
+	bge	Loop3
+	subs	r7, r7, #1
+	bge	Loop2
+Skip:
+	add	r8, r8, #1
+	cmp	r3, r8
+	bne Loop1
+Finished:
+	dsb
+	ldmia	sp!, {r4, r5, r6, r7, r8, r9}
+	RET
+END(armv7_dcache_wbinv_all)
+
+ENTRY(armv7_idcache_wbinv_all)
+	stmdb	sp!, {lr}
+	bl armv7_dcache_wbinv_all
+#ifdef SMP
+	mcr	CP15_ICIALLUIS
+#else
+	mcr	CP15_ICIALLU
+#endif
+	dsb
+	isb
+	ldmia	sp!, {lr}
+	RET
+END(armv7_idcache_wbinv_all)
+
+ENTRY(armv7_dcache_wb_range)
+	ldr	ip, .Larmv7_dcache_line_size
+	ldr	ip, [ip]
+	sub	r3, ip, #1
+	and	r2, r0, r3
+	add	r1, r1, r2
+	bic	r0, r0, r3
+.Larmv7_wb_next:
+	mcr	CP15_DCCMVAC(r0)
+	add	r0, r0, ip
+	subs	r1, r1, ip
+	bhi	.Larmv7_wb_next
+	dsb				/* data synchronization barrier */
+	RET
+END(armv7_dcache_wb_range)
+
+ENTRY(armv7_dcache_wbinv_range)
+	ldr     ip, .Larmv7_dcache_line_size
+	ldr     ip, [ip]
+	sub     r3, ip, #1
+	and     r2, r0, r3
+	add     r1, r1, r2
+	bic     r0, r0, r3
+.Larmv7_wbinv_next:
+	mcr	CP15_DCCIMVAC(r0)
+	add	r0, r0, ip
+	subs	r1, r1, ip
+	bhi	.Larmv7_wbinv_next
+	dsb				/* data synchronization barrier */
+	RET
+END(armv7_dcache_wbinv_range)
+
+/*
+ * Note, we must not invalidate everything.  If the range is too big we
+ * must use wb-inv of the entire cache.
+ */
+ENTRY(armv7_dcache_inv_range)
+	ldr     ip, .Larmv7_dcache_line_size
+	ldr     ip, [ip]
+	sub     r3, ip, #1
+	and     r2, r0, r3
+	add     r1, r1, r2
+	bic     r0, r0, r3
+.Larmv7_inv_next:
+	mcr	CP15_DCIMVAC(r0)
+	add	r0, r0, ip
+	subs	r1, r1, ip
+	bhi	.Larmv7_inv_next
+	dsb				/* data synchronization barrier */
+	RET
+END(armv7_dcache_inv_range)
+
+ENTRY(armv7_idcache_wbinv_range)
+	ldr     ip, .Larmv7_idcache_line_size
+	ldr     ip, [ip]
+	sub     r3, ip, #1
+	and     r2, r0, r3
+	add     r1, r1, r2
+	bic     r0, r0, r3
+.Larmv7_id_wbinv_next:
+	mcr	CP15_ICIMVAU(r0)
+	mcr	CP15_DCCIMVAC(r0)
+	add	r0, r0, ip
+	subs	r1, r1, ip
+	bhi	.Larmv7_id_wbinv_next
+	dsb				/* data synchronization barrier */
+	isb				/* instruction synchronization barrier */
+	RET
+END(armv7_idcache_wbinv_range)
+
+ENTRY_NP(armv7_icache_sync_all)
+#ifdef SMP
+	mcr	CP15_ICIALLUIS
+#else
+	mcr	CP15_ICIALLU
+#endif
+	dsb				/* data synchronization barrier */
+	isb				/* instruction synchronization barrier */
+	RET
+END(armv7_icache_sync_all)
+
+ENTRY_NP(armv7_icache_sync_range)
+	ldr	ip, .Larmv7_icache_line_size
+	ldr	ip, [ip]
+	sub	r3, ip, #1		/* Address need not be aligned, but */
+	and	r2, r0, r3		/* round length up if op spans line */
+	add	r1, r1, r2		/* boundary: len += addr & linemask; */
+.Larmv7_sync_next:
+	mcr	CP15_DCCMVAC(r0)
+	mcr	CP15_ICIMVAU(r0)
+	add	r0, r0, ip
+	subs	r1, r1, ip
+	bhi	.Larmv7_sync_next
+	dsb				/* data synchronization barrier */
+	isb				/* instruction synchronization barrier */
+	RET
+END(armv7_icache_sync_range)
+
+ENTRY(armv7_cpu_sleep)
+	dsb				/* data synchronization barrier */
+	wfi  				/* wait for interrupt */
+	RET
+END(armv7_cpu_sleep)
+
+ENTRY(armv7_context_switch)
+	dsb
+	orr     r0, r0, #PT_ATTR
+
+	mcr	CP15_TTBR0(r0)
+	isb
+#ifdef SMP
+	mcr	CP15_TLBIALLIS
+#else
+	mcr	CP15_TLBIALL
+#endif
+	dsb
+	isb
+	RET
+END(armv7_context_switch)
+
+ENTRY(armv7_drain_writebuf)
+	dsb
+	RET
+END(armv7_drain_writebuf)
+
+ENTRY(armv7_sev)
+	dsb
+	sev
+	nop
+	RET
+END(armv7_sev)
+
+ENTRY(armv7_auxctrl)
+	mrc	CP15_ACTLR(r2)
+	bic r3, r2, r0	/* Clear bits */
+	eor r3, r3, r1  /* XOR bits */
+
+	teq r2, r3
+	mcrne	CP15_ACTLR(r3)
+	mov r0, r2
+	RET
+END(armv7_auxctrl)
+
+/*
+ * Invalidate all I+D+branch cache.  Used by startup code, which counts
+ * on the fact that only r0-r3,ip are modified and no stack space is used.
+ */
+ENTRY(armv7_idcache_inv_all)
+	mov     r0, #0
+	mcr	CP15_CSSELR(r0)		@ set cache level to L1
+	mrc	CP15_CCSIDR(r0)
+
+	ubfx    r2, r0, #13, #15        @ get num sets - 1 from CCSIDR
+	ubfx    r3, r0, #3, #10         @ get numways - 1 from CCSIDR
+	clz     r1, r3                  @ number of bits to MSB of way
+	lsl     r3, r3, r1              @ shift into position
+	mov     ip, #1                  @
+	lsl     ip, ip, r1              @ ip now contains the way decr
+
+	ubfx    r0, r0, #0, #3          @ get linesize from CCSIDR
+	add     r0, r0, #4              @ apply bias
+	lsl     r2, r2, r0              @ shift sets by log2(linesize)
+	add     r3, r3, r2              @ merge numsets - 1 with numways - 1
+	sub     ip, ip, r2              @ subtract numsets - 1 from way decr
+	mov     r1, #1
+	lsl     r1, r1, r0              @ r1 now contains the set decr
+	mov     r2, ip                  @ r2 now contains set way decr
+
+	/* r3 = ways/sets, r2 = way decr, r1 = set decr, r0 and ip are free */
+1:	mcr	CP15_DCISW(r3)		@ invalidate line
+	movs    r0, r3                  @ get current way/set
+	beq     2f                      @ at 0 means we are done.
+	movs    r0, r0, lsl #10         @ clear way bits leaving only set bits
+	subne   r3, r3, r1              @ non-zero?, decrement set #
+	subeq   r3, r3, r2              @ zero?, decrement way # and restore set count
+	b       1b
+
+2:	dsb                             @ wait for stores to finish
+	mov     r0, #0                  @ and ...
+	mcr	CP15_ICIALLU		@ invalidate instruction+branch cache
+	isb                             @ instruction sync barrier
+	bx      lr                      @ return
+END(armv7_idcache_inv_all)
+
+ENTRY_NP(armv7_sleep)
+	dsb
+	wfi
+	bx	lr
+END(armv7_sleep)
+


Property changes on: trunk/sys/arm/arm/cpufunc_asm_armv7.S
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/cpufunc_asm_fa526.S
===================================================================
--- trunk/sys/arm/arm/cpufunc_asm_fa526.S	                        (rev 0)
+++ trunk/sys/arm/arm/cpufunc_asm_fa526.S	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,229 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: cpufunc_asm_fa526.S,v 1.3 2008/10/15 16:56:49 matt Exp $*/
+/*-
+ * Copyright (c) 2008 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Matt Thomas <matt at 3am-software.com>
+ *
+ * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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 <machine/asm.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/cpufunc_asm_fa526.S 248361 2013-03-16 02:48:49Z andrew $");
+
+#ifdef CPU_FA526
+#define	CACHELINE_SIZE	16
+#else
+#define	CACHELINE_SIZE	32
+#endif
+
+ENTRY(fa526_setttb)
+	mov	r1, #0
+	mcr	p15, 0, r1, c7, c14, 0	/* clean and invalidate D$ */
+	mcr	p15, 0, r1, c7, c5, 0	/* invalidate I$ */
+	mcr	p15, 0, r1, c7, c5, 6	/* invalidate BTB */
+	mcr	p15, 0, r1, c7, c10, 4	/* drain write and fill buffer */
+
+	mcr	p15, 0, r0, c2, c0, 0	/* Write the TTB */
+
+	/* If we have updated the TTB we must flush the TLB */
+	mcr	p15, 0, r1, c8, c7, 0	/* invalidate I+D TLB */
+
+	/* Make sure that pipeline is emptied */
+	mov	r0, r0
+	mov	r0, r0
+	mov	pc, lr
+END(fa526_setttb)
+
+/*
+ * TLB functions
+ */
+ENTRY(fa526_tlb_flushID_SE)
+	mcr	p15, 0, r0, c8, c7, 1	/* flush Utlb single entry */
+	mov	pc, lr
+END(fa526_tlb_flushID_SE)
+
+/*
+ * TLB functions
+ */
+ENTRY(fa526_tlb_flushI_SE)
+	mcr	p15, 0, r0, c8, c5, 1	/* flush Itlb single entry */
+	mov	pc, lr
+END(fa526_tlb_flushI_SE)
+
+ENTRY(fa526_cpu_sleep)
+	mov	r0, #0
+/*	nop
+	nop*/
+	mcr	p15, 0, r0, c7, c0, 4	/* Wait for interrupt*/
+	mov	pc, lr
+END(fa526_cpu_sleep)
+
+ENTRY(fa526_flush_prefetchbuf)
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c5, 4	/* Pre-fetch flush */
+	mov	pc, lr
+END(fa526_flush_prefetchbuf)
+
+/*
+ * Cache functions
+ */
+ENTRY(fa526_idcache_wbinv_all)
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c14, 0	/* clean and invalidate D$ */
+	mcr	p15, 0, r0, c7, c5, 0	/* invalidate I$ */
+	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
+	mov	pc, lr
+END(fa526_idcache_wbinv_all)
+
+ENTRY(fa526_icache_sync_all)
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c5, 0	/* invalidate I$ */
+	mov	pc, lr
+END(fa526_icache_sync_all)
+
+ENTRY(fa526_dcache_wbinv_all)
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c14, 0	/* clean and invalidate D$ */
+	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
+	mov	pc, lr
+END(fa526_dcache_wbinv_all)
+
+/*
+ * Soft functions
+ */
+ENTRY(fa526_dcache_wbinv_range)
+	cmp	r1, #0x4000
+	bhs	_C_LABEL(fa526_dcache_wbinv_all)
+
+	and	r2, r0, #(CACHELINE_SIZE - 1)
+	add	r1, r1, r2
+	bic	r0, r0, #(CACHELINE_SIZE - 1)
+
+1:	mcr	p15, 0, r0, c7, c14, 1	/* clean and invalidate D$ entry */
+	add	r0, r0, #CACHELINE_SIZE
+	subs	r1, r1, #CACHELINE_SIZE
+	bhi	1b
+
+	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
+	mov	pc, lr
+END(fa526_dcache_wbinv_range)
+
+ENTRY(fa526_dcache_wb_range)
+	cmp	r1, #0x4000
+	bls	1f
+
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c10, 0	/* clean entire D$ */
+	b	3f
+
+1:	and	r2, r0, #(CACHELINE_SIZE - 1)
+	add	r1, r1, r2
+	bic	r0, r0, #(CACHELINE_SIZE - 1)
+
+2:	mcr	p15, 0, r0, c7, c10, 1	/* clean D$ entry */
+	add	r0, r0, #CACHELINE_SIZE
+	subs	r1, r1, #CACHELINE_SIZE
+	bhi	2b
+
+3:	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
+	mov	pc, lr
+END(fa526_dcache_wb_range)
+
+ENTRY(fa526_dcache_inv_range)
+	and	r2, r0, #(CACHELINE_SIZE - 1)
+	add	r1, r1, r2
+	bic	r0, r0, #(CACHELINE_SIZE - 1)
+
+1:	mcr	p15, 0, r0, c7, c6, 1	/* invalidate D$ single entry */
+	add	r0, r0, #CACHELINE_SIZE
+	subs	r1, r1, #CACHELINE_SIZE
+	bhi	1b
+
+	mov	pc, lr
+END(fa526_dcache_inv_range)
+
+ENTRY(fa526_idcache_wbinv_range)
+	cmp	r1, #0x4000
+	bhs	_C_LABEL(fa526_idcache_wbinv_all)
+
+	and	r2, r0, #(CACHELINE_SIZE - 1)
+	add	r1, r1, r2
+	bic	r0, r0, #(CACHELINE_SIZE - 1)
+
+1:	mcr	p15, 0, r0, c7, c14, 1	/* clean and invalidate D$ entry */
+	mcr	p15, 0, r0, c7, c5, 1	/* invalidate I$ entry */
+	add	r0, r0, #CACHELINE_SIZE
+	subs	r1, r1, #CACHELINE_SIZE
+	bhi	1b
+
+2:	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
+	mov	pc, lr
+END(fa526_idcache_wbinv_range)
+
+ENTRY(fa526_icache_sync_range)
+	cmp	r1, #0x4000
+	bhs	_C_LABEL(fa526_icache_sync_all)
+
+	and	r2, r0, #(CACHELINE_SIZE - 1)
+	add	r1, r1, r2
+	bic	r0, r0, #(CACHELINE_SIZE - 1)
+
+1:	mcr	p15, 0, r0, c7, c10, 1	/* clean D$ entry */
+	mcr	p15, 0, r0, c7, c5, 1	/* invalidate I$ entry */
+	add	r0, r0, #CACHELINE_SIZE
+	subs	r1, r1, #CACHELINE_SIZE
+	bhi	1b
+
+2:	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
+	mov	pc, lr
+END(fa526_icache_sync_range)
+
+ENTRY(fa526_flush_brnchtgt_E)
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c5, 6	/* invalidate BTB cache */
+	mov	pc, lr
+END(fa526_flush_brnchtgt_E)
+
+ENTRY(fa526_context_switch)
+	/*
+	 * CF_CACHE_PURGE_ID will *ALWAYS* be called prior to this.
+	 * Thus the data cache will contain only kernel data and the
+	 * instruction cache will contain only kernel code, and all
+	 * kernel mappings are shared by all processes.
+	 */
+
+	mcr	p15, 0, r0, c2, c0, 0	/* Write the TTB */
+
+	/* If we have updated the TTB we must flush the TLB */
+	mov	r0, #0
+	mcr	p15, 0, r0, c8, c7, 0	/* flush the I+D tlb */
+
+	/* Make sure that pipeline is emptied */
+	mov	r0, r0
+	mov	r0, r0
+	mov	pc, lr
+END(fa526_context_switch)
+


Property changes on: trunk/sys/arm/arm/cpufunc_asm_fa526.S
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/cpufunc_asm_pj4b.S
===================================================================
--- trunk/sys/arm/arm/cpufunc_asm_pj4b.S	                        (rev 0)
+++ trunk/sys/arm/arm/cpufunc_asm_pj4b.S	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,131 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (C) 2011 MARVELL INTERNATIONAL LTD.
+ * All rights reserved.
+ *
+ * Developed by Semihalf.
+ *
+ * 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.
+ * 3. Neither the name of MARVELL nor the names of contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY 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 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 <machine/asm.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/cpufunc_asm_pj4b.S 266046 2014-05-14 16:32:27Z ian $");
+
+#include <machine/param.h>
+
+.Lpj4b_sf_ctrl_reg:
+	.word	0xf1021820
+
+
+ENTRY(pj4b_setttb)
+	/* Cache synchronization is not required as this core has PIPT caches */
+	mcr	p15, 0, r1, c7, c10, 4	/* drain the write buffer */
+#ifdef SMP
+	orr 	r0, r0, #2		/* Set TTB shared memory flag */
+#endif
+	mcr	p15, 0, r0, c2, c0, 0	/* load new TTB */
+	mcr	p15, 0, r0, c8, c7, 0	/* invalidate I+D TLBs */
+	RET
+END(pj4b_setttb)
+
+ENTRY(pj4b_drain_readbuf)
+	mcr	p15, 0, r0, c7, c5, 4	/* flush prefetch buffers */
+	RET
+END(pj4b_drain_readbuf)
+
+ENTRY(pj4b_flush_brnchtgt_all)
+	mcr	p15, 0, r0, c7, c5, 6	/* flush entrie branch target cache */
+	RET
+END(pj4b_flush_brnchtgt_all)
+
+ENTRY(pj4b_flush_brnchtgt_va)
+	mcr	p15, 0, r0, c7, c5, 7	/* flush branch target cache by VA */
+	RET
+END(pj4b_flush_brnchtgt_va)
+
+ENTRY(get_core_id)
+	mrc p15, 0, r0, c0, c0, 5
+	RET
+END(get_core_id)
+
+ENTRY(pj4b_config)
+
+	/* Set Auxiliary Debug Modes Control 0 register */
+	mrc	p15, 1, r0, c15, c1, 0
+	/* ARMADAXP errata fix: ARM-CPU-6136 */
+	bic	r0, r0, #(1 << 12)	/* LDSTM first issue is single word */
+
+	orr	r0, r0, #(1 << 22)	/* DVM_WAKEUP disable */
+	mcr	p15, 1, r0, c15, c1, 0
+
+	/* Set Auxiliary Debug Modes Control 1 register */
+	mrc	p15, 1, r0, c15, c1, 1
+	/* ARMADAXP errata fix: ARM-CPU-6409 */
+	bic	r0, r0, #(1 << 2)	/* Disable static branch prediction */
+
+	orr	r0, r0, #(1 << 5)	/* STREX backoff disable */
+	orr	r0, r0, #(1 << 8)	/* Internal parity handling disable */
+	orr	r0, r0, #(1 << 16)	/* Disable data transfer for clean line */
+	mcr	p15, 1, r0, c15, c1, 1
+
+	/* Set Auxiliary Function Modes Control 0 register */
+	mrc	p15, 1, r0, c15, c2, 0
+#if defined(SMP)
+	orr	r0, r0, #(1 << 1)	/* SMP/nAMP enabled (coherency) */
+#endif
+	orr	r0, r0, #(1 << 2)	/* L1 parite enable */
+	orr	r0, r0, #(1 << 8)	/* Cache and TLB maintenance broadcast enable */
+	mcr	p15, 1, r0, c15, c2, 0
+
+	/* Set Auxiliary Debug Modes Control 2 register */
+	mrc	p15, 1, r0, c15, c1, 2
+	bic	r0, r0, #(1 << 23)	/* Enable fast LDR */
+	orr	r0, r0, #(1 << 25)	/* Intervention Interleave disable */
+	orr	r0, r0, #(1 << 27)	/* Critical word first sequencing disable */
+	orr	r0, r0, #(1 << 29)	/* Disable MO device read / write */
+	orr	r0, r0, #(1 << 30)	/* L1 cache strict round-robin replacement policy*/
+	orr	r0, r0, #(1 << 31)	/* Enable write evict */
+	mcr	p15, 1, r0, c15, c1, 2
+#if defined(SMP)
+	/* Set SMP mode in Auxiliary Control Register */
+	mrc	p15, 0, r0, c1, c0, 1
+	orr	r0, r0, #(1 << 5)
+	mcr	p15, 0, r0, c1, c0, 1
+#endif
+
+	/* Load CPU number */
+	mrc	p15, 0, r0, c0, c0, 5
+	and	r0, r0, #0xf
+
+	/* SF Enable and invalidate */
+	ldr	r1, .Lpj4b_sf_ctrl_reg
+	ldr	r2, [r1, r0, lsl #8]
+	orr	r2, r2, #(1 << 0)
+	bic	r2, r2, #(1 << 8)
+	str	r2, [r1, r0, lsl #8]
+
+	RET
+END(pj4b_config)
+


Property changes on: trunk/sys/arm/arm/cpufunc_asm_pj4b.S
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/cpufunc_asm_sheeva.S
===================================================================
--- trunk/sys/arm/arm/cpufunc_asm_sheeva.S	                        (rev 0)
+++ trunk/sys/arm/arm/cpufunc_asm_sheeva.S	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,422 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (C) 2008 MARVELL INTERNATIONAL LTD.
+ * All rights reserved.
+ *
+ * Developed by Semihalf.
+ *
+ * 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.
+ * 3. Neither the name of MARVELL nor the names of contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY 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 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 <machine/armreg.h>
+#include <machine/asm.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/cpufunc_asm_sheeva.S 278613 2015-02-12 03:50:33Z ian $");
+
+#include <machine/param.h>
+
+.Lsheeva_cache_line_size:
+	.word	_C_LABEL(arm_pdcache_line_size)
+.Lsheeva_asm_page_mask:
+	.word	_C_LABEL(PAGE_MASK)
+
+ENTRY(sheeva_setttb)
+	/* Disable irqs */
+	mrs	r2, cpsr
+	orr	r3, r2, #PSR_I | PSR_F
+	msr	cpsr_c, r3
+
+	mov	r1, #0
+	mcr	p15, 0, r1, c7, c5, 0	/* Invalidate ICache */
+1:	mrc	p15, 0, r15, c7, c14, 3	/* Test, clean and invalidate DCache */
+	bne	1b			/* More to do? */
+
+	mcr	p15, 1, r1, c15, c9, 0	/* Clean L2 */
+	mcr	p15, 1, r1, c15, c11, 0	/* Invalidate L2 */
+
+	/* Reenable irqs */
+	msr	cpsr_c, r2
+
+	mcr	p15, 0, r1, c7, c10, 4	/* drain the write buffer */
+
+	mcr	p15, 0, r0, c2, c0, 0	/* load new TTB */
+
+	mcr	p15, 0, r0, c8, c7, 0	/* invalidate I+D TLBs */
+	RET
+END(sheeva_setttb)
+
+ENTRY(sheeva_dcache_wbinv_range)
+	str	lr, [sp, #-4]!
+	mrs	lr, cpsr
+	/* Start with cache line aligned address */
+	ldr	ip, .Lsheeva_cache_line_size
+	ldr	ip, [ip]
+	sub	ip, ip, #1
+	and	r2, r0, ip
+	add	r1, r1, r2
+	add	r1, r1, ip
+	bics	r1, r1, ip
+	bics	r0, r0, ip
+
+	ldr	ip, .Lsheeva_asm_page_mask
+	and	r2, r0, ip
+	rsb	r2, r2, #PAGE_SIZE
+	cmp	r1, r2
+	movcc	ip, r1
+	movcs	ip, r2
+1:
+	add	r3, r0, ip
+	sub	r2, r3, #1
+	/* Disable irqs */
+	orr	r3, lr, #PSR_I | PSR_F
+	msr	cpsr_c, r3
+	mcr	p15, 5, r0, c15, c15, 0	/* Clean and inv zone start address */
+	mcr	p15, 5, r2, c15, c15, 1	/* Clean and inv zone end address */
+	/* Enable irqs */
+	msr	cpsr_c, lr
+
+	add	r0, r0, ip
+	sub	r1, r1, ip
+	cmp	r1, #PAGE_SIZE
+	movcc	ip, r1
+	movcs	ip, #PAGE_SIZE
+	cmp	r1, #0
+	bne	1b
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
+	ldr	lr, [sp], #4
+	RET
+END(sheeva_dcache_wbinv_range)
+
+ENTRY(sheeva_idcache_wbinv_range)
+	str	lr, [sp, #-4]!
+	mrs	lr, cpsr
+	/* Start with cache line aligned address */
+	ldr	ip, .Lsheeva_cache_line_size
+	ldr	ip, [ip]
+	sub	ip, ip, #1
+	and	r2, r0, ip
+	add	r1, r1, r2
+	add	r1, r1, ip
+	bics	r1, r1, ip
+	bics	r0, r0, ip
+
+	ldr	ip, .Lsheeva_asm_page_mask
+	and	r2, r0, ip
+	rsb	r2, r2, #PAGE_SIZE
+	cmp	r1, r2
+	movcc	ip, r1
+	movcs	ip, r2
+1:
+	add	r3, r0, ip
+	sub	r2, r3, #1
+	/* Disable irqs */
+	orr	r3, lr, #PSR_I | PSR_F
+	msr	cpsr_c, r3
+	mcr	p15, 5, r0, c15, c15, 0	/* Clean and inv zone start address */
+	mcr	p15, 5, r2, c15, c15, 1	/* Clean and inv zone end address */
+	/* Enable irqs */
+	msr	cpsr_c, lr
+
+	/* Invalidate and clean icache line by line */
+	ldr	r3, .Lsheeva_cache_line_size
+	ldr	r3, [r3]
+2:
+	mcr	p15, 0, r0, c7, c5, 1
+	add	r0, r0, r3
+	cmp	r2, r0
+	bhi	2b
+
+	add	r0, r2, #1
+	sub	r1, r1, ip
+	cmp	r1, #PAGE_SIZE
+	movcc	ip, r1
+	movcs	ip, #PAGE_SIZE
+	cmp	r1, #0
+	bne	1b
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
+	ldr	lr, [sp], #4
+	RET
+END(sheeva_idcache_wbinv_range)
+
+ENTRY(sheeva_dcache_inv_range)
+	str	lr, [sp, #-4]!
+	mrs	lr, cpsr
+	/* Start with cache line aligned address */
+	ldr	ip, .Lsheeva_cache_line_size
+	ldr	ip, [ip]
+	sub	ip, ip, #1
+	and	r2, r0, ip
+	add	r1, r1, r2
+	add	r1, r1, ip
+	bics	r1, r1, ip
+	bics	r0, r0, ip
+
+	ldr	ip, .Lsheeva_asm_page_mask
+	and	r2, r0, ip
+	rsb	r2, r2, #PAGE_SIZE
+	cmp	r1, r2
+	movcc	ip, r1
+	movcs	ip, r2
+1:
+	add	r3, r0, ip
+	sub	r2, r3, #1
+	/* Disable irqs */
+	orr	r3, lr, #PSR_I | PSR_F
+	msr	cpsr_c, r3
+	mcr	p15, 5, r0, c15, c14, 0	/* Inv zone start address */
+	mcr	p15, 5, r2, c15, c14, 1	/* Inv zone end address */
+	/* Enable irqs */
+	msr	cpsr_c, lr
+
+	add	r0, r0, ip
+	sub	r1, r1, ip
+	cmp	r1, #PAGE_SIZE
+	movcc	ip, r1
+	movcs	ip, #PAGE_SIZE
+	cmp	r1, #0
+	bne	1b
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
+	ldr	lr, [sp], #4
+	RET
+END(sheeva_dcache_inv_range)
+
+ENTRY(sheeva_dcache_wb_range)
+	str	lr, [sp, #-4]!
+	mrs	lr, cpsr
+	/* Start with cache line aligned address */
+	ldr	ip, .Lsheeva_cache_line_size
+	ldr	ip, [ip]
+	sub	ip, ip, #1
+	and	r2, r0, ip
+	add	r1, r1, r2
+	add	r1, r1, ip
+	bics	r1, r1, ip
+	bics	r0, r0, ip
+
+	ldr	ip, .Lsheeva_asm_page_mask
+	and	r2, r0, ip
+	rsb	r2, r2, #PAGE_SIZE
+	cmp	r1, r2
+	movcc	ip, r1
+	movcs	ip, r2
+1:
+	add	r3, r0, ip
+	sub	r2, r3, #1
+	/* Disable irqs */
+	orr	r3, lr, #PSR_I | PSR_F
+	msr	cpsr_c, r3
+	mcr	p15, 5, r0, c15, c13, 0	/* Clean zone start address */
+	mcr	p15, 5, r2, c15, c13, 1	/* Clean zone end address */
+	/* Enable irqs */
+	msr	cpsr_c, lr
+
+	add	r0, r0, ip
+	sub	r1, r1, ip
+	cmp	r1, #PAGE_SIZE
+	movcc	ip, r1
+	movcs	ip, #PAGE_SIZE
+	cmp	r1, #0
+	bne	1b
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
+	ldr	lr, [sp], #4
+	RET
+END(sheeva_dcache_wb_range)
+
+ENTRY(sheeva_l2cache_wbinv_range)
+	str	lr, [sp, #-4]!
+	mrs	lr, cpsr
+	/* Start with cache line aligned address */
+	ldr	ip, .Lsheeva_cache_line_size
+	ldr	ip, [ip]
+	sub	ip, ip, #1
+	and	r2, r0, ip
+	add	r1, r1, r2
+	add	r1, r1, ip
+	bics	r1, r1, ip
+	bics	r0, r0, ip
+
+	ldr	ip, .Lsheeva_asm_page_mask
+	and	r2, r0, ip
+	rsb	r2, r2, #PAGE_SIZE
+	cmp	r1, r2
+	movcc	ip, r1
+	movcs	ip, r2
+1:
+	add	r3, r0, ip
+	sub	r2, r3, #1
+	/* Disable irqs */
+	orr	r3, lr, #PSR_I | PSR_F
+	msr	cpsr_c, r3
+	mcr	p15, 1, r0, c15, c9, 4	/* Clean L2 zone start address */
+	mcr	p15, 1, r2, c15, c9, 5	/* Clean L2 zone end address */
+	mcr	p15, 1, r0, c15, c11, 4	/* Inv L2 zone start address */
+	mcr	p15, 1, r2, c15, c11, 5	/* Inv L2 zone end address */
+	/* Enable irqs */
+	msr	cpsr_c, lr
+
+	add	r0, r0, ip
+	sub	r1, r1, ip
+	cmp	r1, #PAGE_SIZE
+	movcc	ip, r1
+	movcs	ip, #PAGE_SIZE
+	cmp	r1, #0
+	bne	1b
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
+	ldr	lr, [sp], #4
+	RET
+END(sheeva_l2cache_wbinv_range)
+
+ENTRY(sheeva_l2cache_inv_range)
+	str	lr, [sp, #-4]!
+	mrs	lr, cpsr
+	/* Start with cache line aligned address */
+	ldr	ip, .Lsheeva_cache_line_size
+	ldr	ip, [ip]
+	sub	ip, ip, #1
+	and	r2, r0, ip
+	add	r1, r1, r2
+	add	r1, r1, ip
+	bics	r1, r1, ip
+	bics	r0, r0, ip
+
+	ldr	ip, .Lsheeva_asm_page_mask
+	and	r2, r0, ip
+	rsb	r2, r2, #PAGE_SIZE
+	cmp	r1, r2
+	movcc	ip, r1
+	movcs	ip, r2
+1:
+	add	r3, r0, ip
+	sub	r2, r3, #1
+	/* Disable irqs */
+	orr	r3, lr, #PSR_I | PSR_F
+	msr	cpsr_c, r3
+	mcr	p15, 1, r0, c15, c11, 4	/* Inv L2 zone start address */
+	mcr	p15, 1, r2, c15, c11, 5	/* Inv L2 zone end address */
+	/* Enable irqs */
+	msr	cpsr_c, lr
+
+	add	r0, r0, ip
+	sub	r1, r1, ip
+	cmp	r1, #PAGE_SIZE
+	movcc	ip, r1
+	movcs	ip, #PAGE_SIZE
+	cmp	r1, #0
+	bne	1b
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
+	ldr	lr, [sp], #4
+	RET
+END(sheeva_l2cache_inv_range)
+
+ENTRY(sheeva_l2cache_wb_range)
+	str	lr, [sp, #-4]!
+	mrs	lr, cpsr
+	/* Start with cache line aligned address */
+	ldr	ip, .Lsheeva_cache_line_size
+	ldr	ip, [ip]
+	sub	ip, ip, #1
+	and	r2, r0, ip
+	add	r1, r1, r2
+	add	r1, r1, ip
+	bics	r1, r1, ip
+	bics	r0, r0, ip
+
+	ldr	ip, .Lsheeva_asm_page_mask
+	and	r2, r0,	ip
+	rsb	r2, r2, #PAGE_SIZE
+	cmp	r1, r2
+	movcc	ip, r1
+	movcs	ip, r2
+1:
+	add	r3, r0, ip
+	sub	r2, r3, #1
+	/* Disable irqs */
+	orr	r3, lr, #PSR_I | PSR_F
+	msr	cpsr_c, r3
+	mcr	p15, 1, r0, c15, c9, 4	/* Clean L2 zone start address */
+	mcr	p15, 1, r2, c15, c9, 5	/* Clean L2 zone end address */
+	/* Enable irqs */
+	msr	cpsr_c, lr
+
+	add	r0, r0, ip
+	sub	r1, r1, ip
+	cmp	r1, #PAGE_SIZE
+	movcc	ip, r1
+	movcs	ip, #PAGE_SIZE
+	cmp	r1, #0
+	bne	1b
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
+	ldr	lr, [sp], #4
+	RET
+END(sheeva_l2cache_wb_range)
+
+ENTRY(sheeva_l2cache_wbinv_all)
+	/* Disable irqs */
+	mrs	r1, cpsr
+	orr	r2, r1, #PSR_I | PSR_F
+	msr	cpsr_c, r2
+
+	mov	r0, #0
+	mcr	p15, 1, r0, c15, c9, 0	/* Clean L2 */
+	mcr	p15, 1, r0, c15, c11, 0	/* Invalidate L2 */
+
+	msr	cpsr_c, r1		/* Reenable irqs */
+
+	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
+	RET
+END(sheeva_l2cache_wbinv_all)
+
+/* This function modifies register value as follows:
+ *
+ * arg1  arg		EFFECT (bit value saved into register)
+ *    0     0           not changed
+ *    0     1           negated
+ *    1     0           cleared
+ *    1     1           set
+ */
+ENTRY(sheeva_control_ext)
+	mrc	p15, 1, r3, c15, c1, 0	/* Read the control register */
+	bic	r2, r3, r0		/* Clear bits */
+	eor     r2, r2, r1		/* XOR bits */
+
+	teq	r2, r3			/* Only write if there is a change */
+	mcrne	p15, 1, r2, c15, c1, 0	/* Write new control register */
+	mov	r0, r3			/* Return old value */
+	RET
+END(sheeva_control_ext)
+
+ENTRY(sheeva_cpu_sleep)
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c10, 4	/* Drain write buffer */
+	mcr	p15, 0, r0, c7, c0, 4	/* Wait for interrupt */
+	mov	pc, lr
+END(sheeva_cpu_sleep)
+


Property changes on: trunk/sys/arm/arm/cpufunc_asm_sheeva.S
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/cpufunc_asm_xscale.S
===================================================================
--- trunk/sys/arm/arm/cpufunc_asm_xscale.S	                        (rev 0)
+++ trunk/sys/arm/arm/cpufunc_asm_xscale.S	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,524 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: cpufunc_asm_xscale.S,v 1.16 2002/08/17 16:36:32 thorpej Exp $	*/
+
+/*-
+ * Copyright (c) 2001, 2002 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Allen Briggs and Jason R. Thorpe for Wasabi Systems, Inc.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed for the NetBSD Project by
+ *	Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
+ * 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.
+ *
+ */
+
+/*-
+ * Copyright (c) 2001 Matt Thomas.
+ * Copyright (c) 1997,1998 Mark Brinicombe.
+ * Copyright (c) 1997 Causality Limited
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Causality Limited.
+ * 4. The name of Causality Limited may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY CAUSALITY LIMITED ``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 CAUSALITY LIMITED 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.
+ *
+ * XScale assembly functions for CPU / MMU / TLB specific operations
+ */
+#include <machine/armreg.h>
+#include <machine/asm.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/cpufunc_asm_xscale.S 278613 2015-02-12 03:50:33Z ian $");
+
+/*
+ * Size of the XScale core D-cache.
+ */
+#define	DCACHE_SIZE		0x00008000
+
+.Lblock_userspace_access:
+	.word	_C_LABEL(block_userspace_access)
+
+/*
+ * CPWAIT -- Canonical method to wait for CP15 update.
+ * From: Intel 80200 manual, section 2.3.3.
+ *
+ * NOTE: Clobbers the specified temp reg.
+ */
+#define	CPWAIT_BRANCH							 \
+	sub	pc, pc, #4
+
+#define	CPWAIT(tmp)							 \
+	mrc	p15, 0, tmp, c2, c0, 0	/* arbitrary read of CP15 */	;\
+	mov	tmp, tmp		/* wait for it to complete */	;\
+	CPWAIT_BRANCH			/* branch to next insn */
+
+#define	CPWAIT_AND_RETURN_SHIFTER	lsr #32
+
+#define	CPWAIT_AND_RETURN(tmp)						 \
+	mrc	p15, 0, tmp, c2, c0, 0	/* arbitrary read of CP15 */	;\
+	/* Wait for it to complete and branch to the return address */	 \
+	sub	pc, lr, tmp, CPWAIT_AND_RETURN_SHIFTER
+
+ENTRY(xscale_cpwait)
+	CPWAIT_AND_RETURN(r0)
+END(xscale_cpwait)
+
+/*
+ * We need a separate cpu_control() entry point, since we have to
+ * invalidate the Branch Target Buffer in the event the BPRD bit
+ * changes in the control register.
+ */
+ENTRY(xscale_control)
+	mrc	p15, 0, r3, c1, c0, 0	/* Read the control register */
+	bic	r2, r3, r0		/* Clear bits */
+	eor	r2, r2, r1		/* XOR bits */
+
+	teq	r2, r3			/* Only write if there was a change */
+	mcrne	p15, 0, r0, c7, c5, 6	/* Invalidate the BTB */
+	mcrne	p15, 0, r2, c1, c0, 0	/* Write new control register */
+	mov	r0, r3			/* Return old value */
+
+	CPWAIT_AND_RETURN(r1)
+END(xscale_control)
+
+/*
+ * Functions to set the MMU Translation Table Base register
+ *
+ * We need to clean and flush the cache as it uses virtual
+ * addresses that are about to change.
+ */
+ENTRY(xscale_setttb)
+#ifdef CACHE_CLEAN_BLOCK_INTR
+	mrs	r3, cpsr
+	orr	r1, r3, #(PSR_I | PSR_F)
+	msr	cpsr_fsxc, r1
+#else
+	ldr	r3, .Lblock_userspace_access
+	ldr	r2, [r3]
+	orr	r1, r2, #1
+	str	r1, [r3]
+#endif
+	stmfd	sp!, {r0-r3, lr}
+	bl	_C_LABEL(xscale_cache_cleanID)
+	mcr	p15, 0, r0, c7, c5, 0	/* invalidate I$ and BTB */
+	mcr	p15, 0, r0, c7, c10, 4	/* drain write and fill buffer */
+
+	CPWAIT(r0)
+
+	ldmfd	sp!, {r0-r3, lr}
+
+	/* Write the TTB */
+	mcr	p15, 0, r0, c2, c0, 0
+
+	/* If we have updated the TTB we must flush the TLB */
+	mcr	p15, 0, r0, c8, c7, 0	/* invalidate I+D TLB */
+
+	/* The cleanID above means we only need to flush the I cache here */
+	mcr	p15, 0, r0, c7, c5, 0	/* invalidate I$ and BTB */
+
+	CPWAIT(r0)
+
+#ifdef CACHE_CLEAN_BLOCK_INTR
+	msr	cpsr_fsxc, r3
+#else
+	str	r2, [r3]
+#endif
+	RET
+END(xscale_setttb)
+
+/*
+ * TLB functions
+ *
+ */
+ENTRY(xscale_tlb_flushID_SE)
+	mcr	p15, 0, r0, c8, c6, 1	/* flush D tlb single entry */
+	mcr	p15, 0, r0, c8, c5, 1	/* flush I tlb single entry */
+	CPWAIT_AND_RETURN(r0)
+END(xscale_tlb_flushID_SE)
+
+/*
+ * Cache functions
+ */
+ENTRY(xscale_cache_flushID)
+	mcr	p15, 0, r0, c7, c7, 0	/* flush I+D cache */
+	CPWAIT_AND_RETURN(r0)
+END(xscale_cache_flushID)
+
+ENTRY(xscale_cache_flushI)
+	mcr	p15, 0, r0, c7, c5, 0	/* flush I cache */
+	CPWAIT_AND_RETURN(r0)
+END(xscale_cache_flushI)
+
+ENTRY(xscale_cache_flushD)
+	mcr	p15, 0, r0, c7, c6, 0	/* flush D cache */
+	CPWAIT_AND_RETURN(r0)
+END(xscale_cache_flushD)
+
+ENTRY(xscale_cache_flushI_SE)
+	mcr	p15, 0, r0, c7, c5, 1	/* flush I cache single entry */
+	CPWAIT_AND_RETURN(r0)
+END(xscale_cache_flushI_SE)
+
+ENTRY(xscale_cache_flushD_SE)
+	/*
+	 * Errata (rev < 2): Must clean-dcache-line to an address
+	 * before invalidate-dcache-line to an address, or dirty
+	 * bits will not be cleared in the dcache array.
+	 */
+	mcr	p15, 0, r0, c7, c10, 1
+	mcr	p15, 0, r0, c7, c6, 1	/* flush D cache single entry */
+	CPWAIT_AND_RETURN(r0)
+END(xscale_cache_flushD_SE)
+
+ENTRY(xscale_cache_cleanD_E)
+	mcr	p15, 0, r0, c7, c10, 1	/* clean D cache entry */
+	CPWAIT_AND_RETURN(r0)
+END(xscale_cache_cleanD_E)
+
+/*
+ * Information for the XScale cache clean/purge functions:
+ *
+ *	* Virtual address of the memory region to use
+ *	* Size of memory region
+ *
+ * Note the virtual address for the Data cache clean operation
+ * does not need to be backed by physical memory, since no loads
+ * will actually be performed by the allocate-line operation.
+ *
+ * Note that the Mini-Data cache MUST be cleaned by executing
+ * loads from memory mapped into a region reserved exclusively
+ * for cleaning of the Mini-Data cache.
+ */
+	.data
+
+	.global	_C_LABEL(xscale_cache_clean_addr)
+_C_LABEL(xscale_cache_clean_addr):
+	.word	0x00000000
+
+	.global	_C_LABEL(xscale_cache_clean_size)
+_C_LABEL(xscale_cache_clean_size):
+	.word	DCACHE_SIZE
+
+	.global	_C_LABEL(xscale_minidata_clean_addr)
+_C_LABEL(xscale_minidata_clean_addr):
+	.word	0x00000000
+
+	.global	_C_LABEL(xscale_minidata_clean_size)
+_C_LABEL(xscale_minidata_clean_size):
+	.word	0x00000800
+
+	.text
+
+.Lxscale_cache_clean_addr:
+	.word	_C_LABEL(xscale_cache_clean_addr)
+.Lxscale_cache_clean_size:
+	.word	_C_LABEL(xscale_cache_clean_size)
+
+.Lxscale_minidata_clean_addr:
+	.word	_C_LABEL(xscale_minidata_clean_addr)
+.Lxscale_minidata_clean_size:
+	.word	_C_LABEL(xscale_minidata_clean_size)
+
+#ifdef CACHE_CLEAN_BLOCK_INTR
+#define	XSCALE_CACHE_CLEAN_BLOCK					\
+	mrs	r3, cpsr					;	\
+	orr	r0, r3, #(PSR_I | PSR_F)			;	\
+	msr	cpsr_fsxc, r0
+
+#define	XSCALE_CACHE_CLEAN_UNBLOCK					\
+	msr	cpsr_fsxc, r3
+#else
+#define	XSCALE_CACHE_CLEAN_BLOCK					\
+	ldr	r3, .Lblock_userspace_access			;	\
+	ldr	ip, [r3]					;	\
+	orr	r0, ip, #1					;	\
+	str	r0, [r3]
+
+#define	XSCALE_CACHE_CLEAN_UNBLOCK					\
+	str	ip, [r3]
+#endif /* CACHE_CLEAN_BLOCK_INTR */
+
+#define	XSCALE_CACHE_CLEAN_PROLOGUE					\
+	XSCALE_CACHE_CLEAN_BLOCK				;	\
+	ldr	r2, .Lxscale_cache_clean_addr			;	\
+	ldmia	r2, {r0, r1}					;	\
+	/*								\
+	 * BUG ALERT!							\
+	 *								\
+	 * The XScale core has a strange cache eviction bug, which	\
+	 * requires us to use 2x the cache size for the cache clean	\
+	 * and for that area to be aligned to 2 * cache size.		\
+	 *								\
+	 * The work-around is to use 2 areas for cache clean, and to	\
+	 * alternate between them whenever this is done.  No one knows	\
+	 * why the work-around works (mmm!).				\
+	 */								\
+	eor	r0, r0, #(DCACHE_SIZE)				;	\
+	str	r0, [r2]					;	\
+	add	r0, r0, r1
+
+#define	XSCALE_CACHE_CLEAN_EPILOGUE					\
+	XSCALE_CACHE_CLEAN_UNBLOCK
+
+ENTRY_NP(xscale_cache_syncI)
+
+EENTRY_NP(xscale_cache_purgeID)
+	mcr	p15, 0, r0, c7, c5, 0	/* flush I cache (D cleaned below) */
+EENTRY_NP(xscale_cache_cleanID)
+EENTRY_NP(xscale_cache_purgeD)
+EENTRY(xscale_cache_cleanD)
+	XSCALE_CACHE_CLEAN_PROLOGUE
+
+1:	subs	r0, r0, #32
+	mcr	p15, 0, r0, c7, c2, 5	/* allocate cache line */
+	subs	r1, r1, #32
+	bne	1b
+
+	CPWAIT(r0)
+
+	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
+
+	CPWAIT(r0)
+
+	XSCALE_CACHE_CLEAN_EPILOGUE
+	RET
+EEND(xscale_cache_cleanD)
+EEND(xscale_cache_purgeD)
+EEND(xscale_cache_cleanID)
+EEND(xscale_cache_purgeID)
+END(xscale_cache_syncI)
+
+/*
+ * Clean the mini-data cache.
+ *
+ * It's expected that we only use the mini-data cache for
+ * kernel addresses, so there is no need to purge it on
+ * context switch, and no need to prevent userspace access
+ * while we clean it.
+ */
+ENTRY(xscale_cache_clean_minidata)
+	ldr	r2, .Lxscale_minidata_clean_addr
+	ldmia	r2, {r0, r1}
+1:	ldr	r3, [r0], #32
+	subs	r1, r1, #32
+	bne	1b
+
+	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
+
+	CPWAIT_AND_RETURN(r1)
+END(xscale_cache_clean_minidata)
+
+ENTRY(xscale_cache_purgeID_E)
+	mcr	p15, 0, r0, c7, c10, 1	/* clean D cache entry */
+	CPWAIT(r1)
+	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
+	mcr	p15, 0, r0, c7, c5, 1	/* flush I cache single entry */
+	mcr	p15, 0, r0, c7, c6, 1	/* flush D cache single entry */
+	CPWAIT_AND_RETURN(r1)
+END(xscale_cache_purgeID_E)
+
+ENTRY(xscale_cache_purgeD_E)
+	mcr	p15, 0, r0, c7, c10, 1	/* clean D cache entry */
+	CPWAIT(r1)
+	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
+	mcr	p15, 0, r0, c7, c6, 1	/* flush D cache single entry */
+	CPWAIT_AND_RETURN(r1)
+END(xscale_cache_purgeD_E)
+
+/*
+ * Soft functions
+ */
+/* xscale_cache_syncI is identical to xscale_cache_purgeID */
+
+EENTRY(xscale_cache_cleanID_rng)
+ENTRY(xscale_cache_cleanD_rng)
+	cmp	r1, #0x4000
+	bcs	_C_LABEL(xscale_cache_cleanID)
+
+	and	r2, r0, #0x1f
+	add	r1, r1, r2
+	bic	r0, r0, #0x1f
+
+1:	mcr	p15, 0, r0, c7, c10, 1	/* clean D cache entry */
+	add	r0, r0, #32
+	subs	r1, r1, #32
+	bhi	1b
+
+	CPWAIT(r0)
+
+	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
+
+	CPWAIT_AND_RETURN(r0)
+/*END(xscale_cache_cleanID_rng)*/
+END(xscale_cache_cleanD_rng)
+
+ENTRY(xscale_cache_purgeID_rng)
+	cmp	r1, #0x4000
+	bcs	_C_LABEL(xscale_cache_purgeID)
+
+	and	r2, r0, #0x1f
+	add	r1, r1, r2
+	bic	r0, r0, #0x1f
+
+1:	mcr	p15, 0, r0, c7, c10, 1	/* clean D cache entry */
+	mcr	p15, 0, r0, c7, c6, 1	/* flush D cache single entry */
+	mcr	p15, 0, r0, c7, c5, 1	/* flush I cache single entry */
+	add	r0, r0, #32
+	subs	r1, r1, #32
+	bhi	1b
+
+	CPWAIT(r0)
+
+	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
+
+	CPWAIT_AND_RETURN(r0)
+END(xscale_cache_purgeID_rng)
+
+ENTRY(xscale_cache_purgeD_rng)
+	cmp	r1, #0x4000
+	bcs	_C_LABEL(xscale_cache_purgeD)
+
+	and	r2, r0, #0x1f
+	add	r1, r1, r2
+	bic	r0, r0, #0x1f
+
+1:	mcr	p15, 0, r0, c7, c10, 1	/* clean D cache entry */
+	mcr	p15, 0, r0, c7, c6, 1	/* flush D cache single entry */
+	add	r0, r0, #32
+	subs	r1, r1, #32
+	bhi	1b
+
+	CPWAIT(r0)
+
+	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
+
+	CPWAIT_AND_RETURN(r0)
+END(xscale_cache_purgeD_rng)
+
+ENTRY(xscale_cache_syncI_rng)
+	cmp	r1, #0x4000
+	bcs	_C_LABEL(xscale_cache_syncI)
+
+	and	r2, r0, #0x1f
+	add	r1, r1, r2
+	bic	r0, r0, #0x1f
+
+1:	mcr	p15, 0, r0, c7, c10, 1	/* clean D cache entry */
+	mcr	p15, 0, r0, c7, c5, 1	/* flush I cache single entry */
+	add	r0, r0, #32
+	subs	r1, r1, #32
+	bhi	1b
+
+	CPWAIT(r0)
+
+	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
+
+	CPWAIT_AND_RETURN(r0)
+END(xscale_cache_syncI_rng)
+
+ENTRY(xscale_cache_flushD_rng)
+	and	r2, r0, #0x1f
+	add	r1, r1, r2
+	bic	r0, r0, #0x1f
+
+1:	mcr	p15, 0, r0, c7, c6, 1	/* flush D cache single entry */
+	add	r0, r0, #32
+	subs	r1, r1, #32
+	bhi	1b
+
+	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
+
+	CPWAIT_AND_RETURN(r0)
+END(xscale_cache_flushD_rng)
+
+/*
+ * Context switch.
+ *
+ * These is the CPU-specific parts of the context switcher cpu_switch()
+ * These functions actually perform the TTB reload.
+ *
+ * NOTE: Special calling convention
+ *	r1, r4-r13 must be preserved
+ */
+ENTRY(xscale_context_switch)
+	/*
+	 * CF_CACHE_PURGE_ID will *ALWAYS* be called prior to this.
+	 * Thus the data cache will contain only kernel data and the
+	 * instruction cache will contain only kernel code, and all
+	 * kernel mappings are shared by all processes.
+	 */
+
+	/* Write the TTB */
+	mcr	p15, 0, r0, c2, c0, 0
+
+	/* If we have updated the TTB we must flush the TLB */
+	mcr	p15, 0, r0, c8, c7, 0	/* flush the I+D tlb */
+
+	CPWAIT_AND_RETURN(r0)
+END(xscale_context_switch)
+
+/*
+ * xscale_cpu_sleep
+ *
+ * This is called when there is nothing on any of the run queues.
+ * We go into IDLE mode so that any IRQ or FIQ will awaken us.
+ *
+ * If this is called with anything other than ARM_SLEEP_MODE_IDLE,
+ * ignore it.
+ */
+ENTRY(xscale_cpu_sleep)
+	tst	r0, #0x00000000
+	bne	1f
+	mov	r0, #0x1
+	mcr	p14, 0, r0, c7, c0, 0
+
+1:
+	RET
+END(xscale_cpu_sleep)
+


Property changes on: trunk/sys/arm/arm/cpufunc_asm_xscale.S
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/cpufunc_asm_xscale_c3.S
===================================================================
--- trunk/sys/arm/arm/cpufunc_asm_xscale_c3.S	                        (rev 0)
+++ trunk/sys/arm/arm/cpufunc_asm_xscale_c3.S	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,417 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: cpufunc_asm_xscale.S,v 1.16 2002/08/17 16:36:32 thorpej Exp $	*/
+
+/*-
+ * Copyright (c) 2007 Olivier Houchard
+ * Copyright (c) 2001, 2002 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Allen Briggs and Jason R. Thorpe for Wasabi Systems, Inc.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed for the NetBSD Project by
+ *	Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
+ * 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.
+ *
+ */
+
+/*-
+ * Copyright (c) 2001 Matt Thomas.
+ * Copyright (c) 1997,1998 Mark Brinicombe.
+ * Copyright (c) 1997 Causality Limited
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Causality Limited.
+ * 4. The name of Causality Limited may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY CAUSALITY LIMITED ``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 CAUSALITY LIMITED 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.
+ *
+ * XScale core 3 assembly functions for CPU / MMU / TLB specific operations
+ */
+
+#include <machine/armreg.h>
+#include <machine/asm.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/cpufunc_asm_xscale_c3.S 278613 2015-02-12 03:50:33Z ian $");
+
+/*
+ * Size of the XScale core D-cache.
+ */
+#define	DCACHE_SIZE		0x00008000
+
+.Lblock_userspace_access:
+	.word	_C_LABEL(block_userspace_access)
+
+/*
+ * CPWAIT -- Canonical method to wait for CP15 update.
+ * From: Intel 80200 manual, section 2.3.3.
+ *
+ * NOTE: Clobbers the specified temp reg.
+ */
+#define	CPWAIT_BRANCH							 \
+	sub	pc, pc, #4
+
+#define	CPWAIT(tmp)							 \
+	mrc	p15, 0, tmp, c2, c0, 0	/* arbitrary read of CP15 */	;\
+	mov	tmp, tmp		/* wait for it to complete */	;\
+	CPWAIT_BRANCH			/* branch to next insn */
+
+#define	CPWAIT_AND_RETURN_SHIFTER	lsr #32
+
+#define	CPWAIT_AND_RETURN(tmp)						 \
+	mrc	p15, 0, tmp, c2, c0, 0	/* arbitrary read of CP15 */	;\
+	/* Wait for it to complete and branch to the return address */	 \
+	sub	pc, lr, tmp, CPWAIT_AND_RETURN_SHIFTER
+
+#define ARM_USE_L2_CACHE
+
+#define L2_CACHE_SIZE		0x80000
+#define L2_CACHE_WAYS		8
+#define L2_CACHE_LINE_SIZE	32
+#define L2_CACHE_SETS		(L2_CACHE_SIZE / \
+    (L2_CACHE_WAYS * L2_CACHE_LINE_SIZE))
+
+#define L1_DCACHE_SIZE		32 * 1024
+#define L1_DCACHE_WAYS		4
+#define L1_DCACHE_LINE_SIZE	32
+#define L1_DCACHE_SETS		(L1_DCACHE_SIZE / \
+    (L1_DCACHE_WAYS * L1_DCACHE_LINE_SIZE))
+#ifdef CACHE_CLEAN_BLOCK_INTR
+#define	XSCALE_CACHE_CLEAN_BLOCK					\
+	stmfd	sp!, {r4}					;	\
+	mrs	r4, cpsr					;	\
+	orr	r0, r4, #(PSR_I | PSR_F)			;	\
+	msr	cpsr_fsxc, r0
+
+#define	XSCALE_CACHE_CLEAN_UNBLOCK					\
+	msr	cpsr_fsxc, r4					;	\
+	ldmfd	sp!, {r4}
+#else
+#define	XSCALE_CACHE_CLEAN_BLOCK					\
+	stmfd	sp!, {r4}					;	\
+	ldr	r4, .Lblock_userspace_access			;	\
+	ldr	ip, [r4]					;	\
+	orr	r0, ip, #1					;	\
+	str	r0, [r4]	
+
+#define	XSCALE_CACHE_CLEAN_UNBLOCK					\
+	str	ip, [r3]					;	\
+	ldmfd	sp!, {r4}
+#endif /* CACHE_CLEAN_BLOCK_INTR */
+
+
+ENTRY_NP(xscalec3_cache_syncI)
+EENTRY_NP(xscalec3_cache_purgeID)
+	mcr	p15, 0, r0, c7, c5, 0	/* flush I cache (D cleaned below) */
+EENTRY_NP(xscalec3_cache_cleanID)
+EENTRY_NP(xscalec3_cache_purgeD)
+EENTRY(xscalec3_cache_cleanD)
+
+	XSCALE_CACHE_CLEAN_BLOCK
+	mov	r0, #0
+1:
+	mov	r1, r0, asl #30
+	mov	r2, #0
+2:
+	orr	r3, r1, r2, asl #5
+	mcr	p15, 0, r3, c7, c14, 2	/* clean and invalidate */
+	add	r2, r2, #1
+	cmp	r2, #L1_DCACHE_SETS
+	bne	2b
+	add	r0, r0, #1
+	cmp	r0, #4
+	bne	1b
+	CPWAIT(r0)
+	XSCALE_CACHE_CLEAN_UNBLOCK
+	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
+
+	RET
+EEND(xscalec3_cache_purgeID)
+EEND(xscalec3_cache_cleanID)
+EEND(xscalec3_cache_purgeD)
+EEND(xscalec3_cache_cleanD)
+END(xscalec3_cache_syncI)
+
+ENTRY(xscalec3_cache_purgeID_rng)
+
+	cmp	r1, #0x4000
+	bcs	_C_LABEL(xscalec3_cache_cleanID)
+	and	r2, r0, #0x1f
+	add	r1, r1, r2
+	bic	r0, r0, #0x1f
+
+1:	mcr	p15, 0, r0, c7, c14, 1	/* clean/invalidate L1 D cache entry */
+	nop
+	mcr	p15, 0, r0, c7, c5, 1	/* flush I cache single entry */
+	add	r0, r0, #32
+	subs	r1, r1, #32
+	bhi	1b
+
+	CPWAIT(r0)
+
+	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
+
+	CPWAIT_AND_RETURN(r0)
+END(xscalec3_cache_purgeID_rng)
+
+ENTRY(xscalec3_cache_syncI_rng)
+	cmp	r1, #0x4000
+	bcs	_C_LABEL(xscalec3_cache_syncI)
+
+	and	r2, r0, #0x1f
+	add	r1, r1, r2
+	bic	r0, r0, #0x1f
+
+1:	mcr	p15, 0, r0, c7, c10, 1	/* clean D cache entry */
+	mcr	p15, 0, r0, c7, c5, 1	/* flush I cache single entry */
+	add	r0, r0, #32
+	subs	r1, r1, #32
+	bhi	1b
+
+	CPWAIT(r0)
+
+	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
+
+	CPWAIT_AND_RETURN(r0)
+END(xscalec3_cache_syncI_rng)
+	
+ENTRY(xscalec3_cache_purgeD_rng)
+
+	cmp	r1, #0x4000
+	bcs	_C_LABEL(xscalec3_cache_cleanID)
+	and	r2, r0, #0x1f
+	add	r1, r1, r2
+	bic	r0, r0, #0x1f
+
+1:	mcr	p15, 0, r0, c7, c14, 1	/* Clean and invalidate D cache entry */
+	add	r0, r0, #32
+	subs	r1, r1, #32
+	bhi	1b
+
+	CPWAIT(r0)
+
+	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
+
+	CPWAIT_AND_RETURN(r0)
+END(xscalec3_cache_purgeD_rng)
+
+ENTRY(xscalec3_cache_cleanID_rng)
+EENTRY(xscalec3_cache_cleanD_rng)
+
+	cmp	r1, #0x4000
+	bcs	_C_LABEL(xscalec3_cache_cleanID)
+	and	r2, r0, #0x1f
+	add	r1, r1, r2
+	bic	r0, r0, #0x1f
+
+1:	mcr	p15, 0, r0, c7, c10, 1	/* clean L1 D cache entry */
+	nop
+	add	r0, r0, #32
+	subs	r1, r1, #32
+	bhi	1b
+
+	CPWAIT(r0)
+
+	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
+
+	CPWAIT_AND_RETURN(r0)
+EEND(xscalec3_cache_cleanD_rng)
+END(xscalec3_cache_cleanID_rng)
+
+ENTRY(xscalec3_l2cache_purge)
+	/* Clean-up the L2 cache */
+	mcr	p15, 0, r0, c7, c10, 5	/* Data memory barrier */
+	mov	r0, #0
+1:
+	mov	r1, r0, asl #29
+	mov	r2, #0
+2:
+	orr	r3, r1, r2, asl #5
+	mcr	p15, 1, r3, c7, c15, 2
+	add	r2, r2, #1
+	cmp	r2, #L2_CACHE_SETS
+	bne	2b
+	add	r0, r0, #1
+	cmp	r0, #8
+	bne	1b
+	mcr	p15, 0, r0, c7, c10, 4		@ data write barrier
+
+	CPWAIT(r0)
+	mcr	p15, 0, r0, c7, c10, 5	/* Data memory barrier */
+	RET
+END(xscalec3_l2cache_purge)
+
+ENTRY(xscalec3_l2cache_clean_rng)
+	mcr	p15, 0, r0, c7, c10, 5	/* Data memory barrier */
+
+	and	r2, r0, #0x1f
+	add	r1, r1, r2
+	bic	r0, r0, #0x1f
+
+1:	mcr	p15, 1, r0, c7, c11, 1	/* Clean L2 D cache entry */
+	add	r0, r0, #32
+	subs	r1, r1, #32
+	bhi	1b
+
+
+	CPWAIT(r0)
+
+	mcr	p15, 0, r0, c7, c10, 4		@ data write barrier
+	mcr	p15, 0, r0, c7, c10, 5
+
+	CPWAIT_AND_RETURN(r0)
+END(xscalec3_l2cache_clean_rng)
+
+ENTRY(xscalec3_l2cache_purge_rng)
+
+	mcr	p15, 0, r0, c7, c10, 5	/* Data memory barrier */
+
+	and	r2, r0, #0x1f
+	add	r1, r1, r2
+	bic	r0, r0, #0x1f
+
+1:	mcr	p15, 1, r0, c7, c11, 1	/* Clean L2 D cache entry */
+	mcr	p15, 1, r0, c7, c7, 1   /* Invalidate L2 D cache entry */
+	add	r0, r0, #32
+	subs	r1, r1, #32
+	bhi	1b
+
+	mcr	p15, 0, r0, c7, c10, 4		@ data write barrier
+	mcr	p15, 0, r0, c7, c10, 5
+
+	CPWAIT_AND_RETURN(r0)
+END(xscalec3_l2cache_purge_rng)
+
+ENTRY(xscalec3_l2cache_flush_rng)
+	mcr	p15, 0, r0, c7, c10, 5	/* Data memory barrier */
+
+	and	r2, r0, #0x1f
+	add	r1, r1, r2
+	bic	r0, r0, #0x1f
+
+1:	mcr	p15, 1, r0, c7, c7, 1   /* Invalidate L2 cache line */
+	add	r0, r0, #32
+	subs	r1, r1, #32
+	bhi	1b
+	mcr	p15, 0, r0, c7, c10, 4		@ data write barrier
+	mcr	p15, 0, r0, c7, c10, 5
+	CPWAIT_AND_RETURN(r0)
+END(xscalec3_l2cache_flush_rng)
+
+/*
+ * Functions to set the MMU Translation Table Base register
+ *
+ * We need to clean and flush the cache as it uses virtual
+ * addresses that are about to change.
+ */
+ENTRY(xscalec3_setttb)
+#ifdef CACHE_CLEAN_BLOCK_INTR
+	mrs	r3, cpsr
+	orr	r1, r3, #(PSR_I | PSR_F)
+	msr	cpsr_fsxc, r1
+#else
+	ldr	r3, .Lblock_userspace_access
+	ldr	r2, [r3]
+	orr	r1, r2, #1
+	str	r1, [r3]
+#endif
+	stmfd	sp!, {r0-r3, lr}
+	bl	_C_LABEL(xscalec3_cache_cleanID)
+	mcr	p15, 0, r0, c7, c5, 0	/* invalidate I$ and BTB */
+	mcr	p15, 0, r0, c7, c10, 4	/* drain write and fill buffer */
+
+	CPWAIT(r0)
+
+	ldmfd	sp!, {r0-r3, lr}
+
+#ifdef ARM_USE_L2_CACHE
+	orr	r0, r0, #0x18	/* cache the page table in L2 */
+#endif
+	/* Write the TTB */
+	mcr	p15, 0, r0, c2, c0, 0
+
+	/* If we have updated the TTB we must flush the TLB */
+	mcr	p15, 0, r0, c8, c7, 0	/* invalidate I+D TLB */
+
+	CPWAIT(r0)
+
+#ifdef CACHE_CLEAN_BLOCK_INTR
+	msr	cpsr_fsxc, r3
+#else
+	str	r2, [r3]
+#endif
+	RET
+END(xscalec3_setttb)
+
+/*
+ * Context switch.
+ *
+ * These is the CPU-specific parts of the context switcher cpu_switch()
+ * These functions actually perform the TTB reload.
+ *
+ * NOTE: Special calling convention
+ *	r1, r4-r13 must be preserved
+ */
+ENTRY(xscalec3_context_switch)
+	/*
+	 * CF_CACHE_PURGE_ID will *ALWAYS* be called prior to this.
+	 * Thus the data cache will contain only kernel data and the
+	 * instruction cache will contain only kernel code, and all
+	 * kernel mappings are shared by all processes.
+	 */
+#ifdef ARM_USE_L2_CACHE
+	orr	r0, r0, #0x18	/* Cache the page table in L2 */
+#endif
+	/* Write the TTB */
+	mcr	p15, 0, r0, c2, c0, 0
+
+	/* If we have updated the TTB we must flush the TLB */
+	mcr	p15, 0, r0, c8, c7, 0	/* flush the I+D tlb */
+
+	CPWAIT_AND_RETURN(r0)
+END(xscalec3_context_switch)
+


Property changes on: trunk/sys/arm/arm/cpufunc_asm_xscale_c3.S
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/cpuinfo.c
===================================================================
--- trunk/sys/arm/arm/cpuinfo.c	                        (rev 0)
+++ trunk/sys/arm/arm/cpuinfo.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,139 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright 2014 Svatopluk Kraus <onwahe at gmail.com>
+ * Copyright 2014 Michal Meloun <meloun at miracle.cz>
+ * 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: stable/10/sys/arm/arm/cpuinfo.c 283336 2015-05-23 23:05:31Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+
+#include <machine/cpuinfo.h>
+#include <machine/cpu-v6.h>
+
+struct cpuinfo cpuinfo =
+{
+	/* Use safe defaults for start */
+	.dcache_line_size = 32,
+	.dcache_line_mask = 31,
+	.icache_line_size = 32,
+	.icache_line_mask = 31,
+};
+
+/* Read and parse CPU id scheme */
+void
+cpuinfo_init(void)
+{
+
+	cpuinfo.midr = cp15_midr_get();	
+	/* Test old version id schemes first */
+	if ((cpuinfo.midr & CPU_ID_IMPLEMENTOR_MASK) == CPU_ID_ARM_LTD) {
+		if (CPU_ID_ISOLD(cpuinfo.midr)) {
+			/* obsolete ARMv2 or ARMv3 CPU */
+			cpuinfo.midr = 0;
+			return;
+		}
+		if (CPU_ID_IS7(cpuinfo.midr)) {
+			if ((cpuinfo.midr & (1 << 23)) == 0) {
+				/* obsolete ARMv3 CPU */
+				cpuinfo.midr = 0;
+				return;
+			}
+			/* ARMv4T CPU */
+			cpuinfo.architecture = 1;
+			cpuinfo.revision = (cpuinfo.midr >> 16) & 0x7F;
+		} else {
+			/* ARM new id scheme */
+			cpuinfo.architecture = (cpuinfo.midr >> 16) & 0x0F;
+			cpuinfo.revision = (cpuinfo.midr >> 20) & 0x0F;
+		}
+	} else {
+		/* non ARM -> must be new id scheme */
+		cpuinfo.architecture = (cpuinfo.midr >> 16) & 0x0F;
+		cpuinfo.revision = (cpuinfo.midr >> 20) & 0x0F;
+	}	
+	/* Parse rest of MIDR  */
+	cpuinfo.implementer = (cpuinfo.midr >> 24) & 0xFF;
+	cpuinfo.part_number = (cpuinfo.midr >> 4) & 0xFFF;
+	cpuinfo.patch = cpuinfo.midr & 0x0F;
+
+	/* CP15 c0,c0 regs 0-7 exist on all CPUs (although aliased with MIDR) */
+	cpuinfo.ctr = cp15_ctr_get();
+	cpuinfo.tcmtr = cp15_tcmtr_get();
+	cpuinfo.tlbtr = cp15_tlbtr_get();
+	cpuinfo.mpidr = cp15_mpidr_get();
+	cpuinfo.revidr = cp15_revidr_get();
+		
+	/* if CPU is not v7 cpu id scheme */
+	if (cpuinfo.architecture != 0xF)
+		return;
+		
+	cpuinfo.id_pfr0 = cp15_id_pfr0_get();
+	cpuinfo.id_pfr1 = cp15_id_pfr1_get();
+	cpuinfo.id_dfr0 = cp15_id_dfr0_get();
+	cpuinfo.id_afr0 = cp15_id_afr0_get();
+	cpuinfo.id_mmfr0 = cp15_id_mmfr0_get();
+	cpuinfo.id_mmfr1 = cp15_id_mmfr1_get();
+	cpuinfo.id_mmfr2 = cp15_id_mmfr2_get();
+	cpuinfo.id_mmfr3 = cp15_id_mmfr3_get();
+	cpuinfo.id_isar0 = cp15_id_isar0_get();
+	cpuinfo.id_isar1 = cp15_id_isar1_get();
+	cpuinfo.id_isar2 = cp15_id_isar2_get();
+	cpuinfo.id_isar3 = cp15_id_isar3_get();
+	cpuinfo.id_isar4 = cp15_id_isar4_get();
+	cpuinfo.id_isar5 = cp15_id_isar5_get();
+
+/* Not yet - CBAR only exist on ARM SMP Cortex A CPUs
+	cpuinfo.cbar = cp15_cbar_get();
+*/
+
+	/* Test if revidr is implemented */
+	if (cpuinfo.revidr == cpuinfo.midr)
+		cpuinfo.revidr = 0;
+
+	/* parsed bits of above registers */
+	/* id_mmfr0 */
+	cpuinfo.outermost_shareability =  (cpuinfo.id_mmfr0 >> 8) & 0xF;
+	cpuinfo.shareability_levels = (cpuinfo.id_mmfr0 >> 12) & 0xF;
+	cpuinfo.auxiliary_registers = (cpuinfo.id_mmfr0 >> 20) & 0xF;
+	cpuinfo.innermost_shareability = (cpuinfo.id_mmfr0 >> 28) & 0xF;
+	/* id_mmfr2 */
+	cpuinfo.mem_barrier = (cpuinfo.id_mmfr2 >> 20) & 0xF;
+	/* id_mmfr3 */
+	cpuinfo.coherent_walk = (cpuinfo.id_mmfr3 >> 20) & 0xF;
+	cpuinfo.maintenance_broadcast =(cpuinfo.id_mmfr3 >> 12) & 0xF;
+	/* id_pfr1 */
+	cpuinfo.generic_timer_ext = (cpuinfo.id_pfr1 >> 16) & 0xF;
+	cpuinfo.virtualization_ext = (cpuinfo.id_pfr1 >> 12) & 0xF;
+	cpuinfo.security_ext = (cpuinfo.id_pfr1 >> 4) & 0xF;
+
+	/* L1 Cache sizes */
+	cpuinfo.dcache_line_size = 1 << (CPU_CT_DMINLINE(cpuinfo.ctr ) + 2);
+	cpuinfo.dcache_line_mask = cpuinfo.dcache_line_size - 1;
+	cpuinfo.icache_line_size= 1 << (CPU_CT_IMINLINE(cpuinfo.ctr ) + 2);
+	cpuinfo.icache_line_mask = cpuinfo.icache_line_size - 1;
+}


Property changes on: trunk/sys/arm/arm/cpuinfo.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/db_disasm.c
===================================================================
--- trunk/sys/arm/arm/db_disasm.c	                        (rev 0)
+++ trunk/sys/arm/arm/db_disasm.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,80 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: db_disasm.c,v 1.4 2003/07/15 00:24:38 lukem Exp $	*/
+
+/*-
+ * Copyright (c) 1996 Mark Brinicombe.
+ * Copyright (c) 1996 Brini.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Brini.
+ * 4. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BRINI ``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 BRINI 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: stable/10/sys/arm/arm/db_disasm.c 236991 2012-06-13 04:59:55Z imp $");
+#include <sys/param.h>
+#include <machine/db_machdep.h>
+#include <ddb/ddb.h>
+#include <ddb/db_access.h>
+#include <ddb/db_sym.h>
+
+#include <machine/disassem.h>
+
+/* Glue code to interface db_disasm to the generic ARM disassembler */
+
+static u_int db_disasm_read_word(u_int);
+static void db_disasm_printaddr(u_int);
+
+static const disasm_interface_t db_disasm_interface = {
+	db_disasm_read_word,
+	db_disasm_printaddr,
+       	db_printf
+};
+
+static u_int
+db_disasm_read_word(u_int address)
+{
+
+	return db_get_value(address, 4, 0);
+}
+
+static void
+db_disasm_printaddr(u_int address)
+{
+
+	db_printsym((db_addr_t)address, DB_STGY_ANY);
+}
+
+vm_offset_t
+db_disasm(vm_offset_t loc, boolean_t altfmt)
+{
+
+	return disasm(&db_disasm_interface, loc, altfmt);
+}
+
+/* End of db_disasm.c */


Property changes on: trunk/sys/arm/arm/db_disasm.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/db_interface.c
===================================================================
--- trunk/sys/arm/arm/db_interface.c	                        (rev 0)
+++ trunk/sys/arm/arm/db_interface.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,388 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: db_interface.c,v 1.33 2003/08/25 04:51:10 mrg Exp $	*/
+
+/*-
+ * Copyright (c) 1996 Scott K. Stevens
+ *
+ * Mach Operating System
+ * Copyright (c) 1991,1990 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ *  Software Distribution Coordinator  or  Software.Distribution at CS.CMU.EDU
+ *  School of Computer Science
+ *  Carnegie Mellon University
+ *  Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ *
+ *	From: db_interface.c,v 2.4 1991/02/05 17:11:13 mrt (CMU)
+ */
+
+/*
+ * Interface to new debugger.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/db_interface.c 236991 2012-06-13 04:59:55Z imp $");
+#include "opt_ddb.h"
+
+#include <sys/param.h>
+#include <sys/proc.h>
+#include <sys/reboot.h>
+#include <sys/systm.h>	/* just for boothowto */
+#include <sys/exec.h>
+#ifdef KDB
+#include <sys/kdb.h>
+#endif
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/vm_map.h>
+#include <vm/vm_extern.h>
+
+#include <machine/db_machdep.h>
+#include <machine/vmparam.h>
+#include <machine/cpu.h>
+
+#include <ddb/ddb.h>
+#include <ddb/db_access.h>
+#include <ddb/db_command.h>
+#include <ddb/db_output.h>
+#include <ddb/db_variables.h>
+#include <ddb/db_sym.h>
+#include <sys/cons.h>
+
+static int nil = 0;
+
+int db_access_und_sp (struct db_variable *, db_expr_t *, int);
+int db_access_abt_sp (struct db_variable *, db_expr_t *, int);
+int db_access_irq_sp (struct db_variable *, db_expr_t *, int);
+
+static db_varfcn_t db_frame;
+
+#define DB_OFFSET(x)	(db_expr_t *)offsetof(struct trapframe, x)
+struct db_variable db_regs[] = {
+	{ "spsr", DB_OFFSET(tf_spsr),	db_frame },
+	{ "r0", DB_OFFSET(tf_r0),	db_frame },
+	{ "r1", DB_OFFSET(tf_r1),	db_frame },
+	{ "r2", DB_OFFSET(tf_r2),	db_frame },
+	{ "r3", DB_OFFSET(tf_r3),	db_frame },
+	{ "r4", DB_OFFSET(tf_r4),	db_frame },
+	{ "r5", DB_OFFSET(tf_r5),	db_frame },
+	{ "r6", DB_OFFSET(tf_r6),	db_frame },
+	{ "r7", DB_OFFSET(tf_r7),	db_frame },
+	{ "r8", DB_OFFSET(tf_r8),	db_frame },
+	{ "r9", DB_OFFSET(tf_r9),	db_frame },
+	{ "r10", DB_OFFSET(tf_r10),	db_frame },
+	{ "r11", DB_OFFSET(tf_r11),	db_frame },
+	{ "r12", DB_OFFSET(tf_r12),	db_frame },
+	{ "usr_sp", DB_OFFSET(tf_usr_sp), db_frame },
+	{ "usr_lr", DB_OFFSET(tf_usr_lr), db_frame },
+	{ "svc_sp", DB_OFFSET(tf_svc_sp), db_frame },
+	{ "svc_lr", DB_OFFSET(tf_svc_lr), db_frame },
+	{ "pc", DB_OFFSET(tf_pc), 	db_frame },
+	{ "und_sp", &nil, db_access_und_sp, },
+	{ "abt_sp", &nil, db_access_abt_sp, },
+	{ "irq_sp", &nil, db_access_irq_sp, },
+};
+
+struct db_variable *db_eregs = db_regs + sizeof(db_regs)/sizeof(db_regs[0]);
+
+int
+db_access_und_sp(struct db_variable *vp, db_expr_t *valp, int rw)
+{
+
+	if (rw == DB_VAR_GET) {
+		*valp = get_stackptr(PSR_UND32_MODE);
+		return (1);
+	}
+	return (0);
+}
+
+int
+db_access_abt_sp(struct db_variable *vp, db_expr_t *valp, int rw)
+{
+
+	if (rw == DB_VAR_GET) {
+		*valp = get_stackptr(PSR_ABT32_MODE);
+		return (1);
+	}
+	return (0);
+}
+
+int
+db_access_irq_sp(struct db_variable *vp, db_expr_t *valp, int rw)
+{
+
+	if (rw == DB_VAR_GET) {
+		*valp = get_stackptr(PSR_IRQ32_MODE);
+		return (1);
+	}
+	return (0);
+}
+
+int db_frame(struct db_variable *vp, db_expr_t *valp, int rw)
+{
+	int *reg;
+
+	if (kdb_frame == NULL)
+		return (0);
+
+	reg = (int *)((uintptr_t)kdb_frame + (db_expr_t)vp->valuep);
+	if (rw == DB_VAR_GET)
+		*valp = *reg;
+	else
+		*reg = *valp;
+	return (1);
+}
+
+void
+db_show_mdpcpu(struct pcpu *pc)
+{
+}
+int
+db_validate_address(vm_offset_t addr)
+{
+	struct proc *p = curproc;
+	struct pmap *pmap;
+
+	if (!p || !p->p_vmspace || !p->p_vmspace->vm_map.pmap ||
+#ifndef ARM32_NEW_VM_LAYOUT
+	    addr >= VM_MAXUSER_ADDRESS
+#else
+	    addr >= VM_MIN_KERNEL_ADDRESS
+#endif
+	   )
+		pmap = pmap_kernel();
+	else
+		pmap = p->p_vmspace->vm_map.pmap;
+
+	return (pmap_extract(pmap, addr) == FALSE);
+}
+
+/*
+ * Read bytes from kernel address space for debugger.
+ */
+int
+db_read_bytes(addr, size, data)
+	vm_offset_t	addr;
+	size_t	size;
+	char	*data;
+{
+	char	*src = (char *)addr;
+
+	if (db_validate_address((u_int)src)) {
+		db_printf("address %p is invalid\n", src);
+		return (-1);
+	}
+
+	if (size == 4 && (addr & 3) == 0 && ((uintptr_t)data & 3) == 0) {
+		*((int*)data) = *((int*)src);
+		return (0);
+	}
+
+	if (size == 2 && (addr & 1) == 0 && ((uintptr_t)data & 1) == 0) {
+		*((short*)data) = *((short*)src);
+		return (0);
+	}
+
+	while (size-- > 0) {
+		if (db_validate_address((u_int)src)) {
+			db_printf("address %p is invalid\n", src);
+			return (-1);
+		}
+		*data++ = *src++;
+	}
+	return (0);
+}
+
+/*
+ * Write bytes to kernel address space for debugger.
+ */
+int
+db_write_bytes(vm_offset_t addr, size_t size, char *data)
+{
+	char *dst;
+	size_t loop;
+
+	dst = (char *)addr;
+	if (db_validate_address((u_int)dst)) {
+		db_printf("address %p is invalid\n", dst);
+		return (0);
+	}
+
+	if (size == 4 && (addr & 3) == 0 && ((uintptr_t)data & 3) == 0)
+		*((int*)dst) = *((int*)data);
+	else
+	if (size == 2 && (addr & 1) == 0 && ((uintptr_t)data & 1) == 0)
+		*((short*)dst) = *((short*)data);
+	else {
+		loop = size;
+		while (loop-- > 0) {
+			if (db_validate_address((u_int)dst)) {
+				db_printf("address %p is invalid\n", dst);
+				return (-1);
+			}
+			*dst++ = *data++;
+		}
+	}
+
+	/* make sure the caches and memory are in sync */
+	cpu_icache_sync_range(addr, size);
+
+	/* In case the current page tables have been modified ... */
+	cpu_tlb_flushID();
+	cpu_cpwait();
+	return (0);
+}
+
+
+static u_int
+db_fetch_reg(int reg)
+{
+
+	switch (reg) {
+	case 0:
+		return (kdb_frame->tf_r0);
+	case 1:
+		return (kdb_frame->tf_r1);
+	case 2:
+		return (kdb_frame->tf_r2);
+	case 3:
+		return (kdb_frame->tf_r3);
+	case 4:
+		return (kdb_frame->tf_r4);
+	case 5:
+		return (kdb_frame->tf_r5);
+	case 6:
+		return (kdb_frame->tf_r6);
+	case 7:
+		return (kdb_frame->tf_r7);
+	case 8:
+		return (kdb_frame->tf_r8);
+	case 9:
+		return (kdb_frame->tf_r9);
+	case 10:
+		return (kdb_frame->tf_r10);
+	case 11:
+		return (kdb_frame->tf_r11);
+	case 12:
+		return (kdb_frame->tf_r12);
+	case 13:
+		return (kdb_frame->tf_svc_sp);
+	case 14:
+		return (kdb_frame->tf_svc_lr);
+	case 15:
+		return (kdb_frame->tf_pc);
+	default:
+		panic("db_fetch_reg: botch");
+	}
+}
+
+u_int
+branch_taken(u_int insn, db_addr_t pc)
+{
+	u_int addr, nregs, offset = 0;
+
+	switch ((insn >> 24) & 0xf) {
+	case 0x2:	/* add pc, reg1, #value */
+	case 0x0:	/* add pc, reg1, reg2, lsl #offset */
+		addr = db_fetch_reg((insn >> 16) & 0xf);
+		if (((insn >> 16) & 0xf) == 15)
+			addr += 8;
+		if (insn & 0x0200000) {
+			offset = (insn >> 7) & 0x1e;
+			offset = (insn & 0xff) << (32 - offset) |
+			    (insn & 0xff) >> offset;
+		} else {
+
+			offset = db_fetch_reg(insn & 0x0f);
+			if ((insn & 0x0000ff0) != 0x00000000) {
+				if (insn & 0x10)
+					nregs = db_fetch_reg((insn >> 8) & 0xf);
+				else
+					nregs = (insn >> 7) & 0x1f;
+				switch ((insn >> 5) & 3) {
+				case 0:
+					/* lsl */
+					offset = offset << nregs;
+					break;
+				case 1:
+					/* lsr */
+					offset = offset >> nregs;
+					break;
+				default:
+					break; /* XXX */
+				}
+					
+			}
+			return (addr + offset);
+				
+		}
+		
+	case 0xa:	/* b ... */
+	case 0xb:	/* bl ... */
+		addr = ((insn << 2) & 0x03ffffff);
+		if (addr & 0x02000000)
+			addr |= 0xfc000000;
+		return (pc + 8 + addr);
+	case 0x7:	/* ldr pc, [pc, reg, lsl #2] */
+		addr = db_fetch_reg(insn & 0xf);
+		addr = pc + 8 + (addr << 2);
+		db_read_bytes(addr, 4, (char *)&addr);
+		return (addr);
+	case 0x1:	/* mov pc, reg */
+		addr = db_fetch_reg(insn & 0xf);
+		return (addr);
+	case 0x4:
+	case 0x5:	/* ldr pc, [reg] */
+		addr = db_fetch_reg((insn >> 16) & 0xf);
+		/* ldr pc, [reg, #offset] */
+		if (insn & (1 << 24))
+			offset = insn & 0xfff;
+		if (insn & 0x00800000)
+			addr += offset;
+		else
+			addr -= offset;
+		db_read_bytes(addr, 4, (char *)&addr);
+		return (addr);
+	case 0x8:	/* ldmxx reg, {..., pc} */
+	case 0x9:
+		addr = db_fetch_reg((insn >> 16) & 0xf);
+		nregs = (insn  & 0x5555) + ((insn  >> 1) & 0x5555);
+		nregs = (nregs & 0x3333) + ((nregs >> 2) & 0x3333);
+		nregs = (nregs + (nregs >> 4)) & 0x0f0f;
+		nregs = (nregs + (nregs >> 8)) & 0x001f;
+		switch ((insn >> 23) & 0x3) {
+		case 0x0:	/* ldmda */
+			addr = addr - 0;
+			break;
+		case 0x1:	/* ldmia */
+			addr = addr + 0 + ((nregs - 1) << 2);
+			break;
+		case 0x2:	/* ldmdb */
+			addr = addr - 4;
+			break;
+		case 0x3:	/* ldmib */
+			addr = addr + 4 + ((nregs - 1) << 2);
+			break;
+		}
+		db_read_bytes(addr, 4, (char *)&addr);
+		return (addr);
+	default:
+		panic("branch_taken: botch");
+	}
+}


Property changes on: trunk/sys/arm/arm/db_interface.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/db_trace.c
===================================================================
--- trunk/sys/arm/arm/db_trace.c	                        (rev 0)
+++ trunk/sys/arm/arm/db_trace.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,643 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: db_trace.c,v 1.8 2003/01/17 22:28:48 thorpej Exp $	*/
+
+/*-
+ * Copyright (c) 2000, 2001 Ben Harris
+ * Copyright (c) 1996 Scott K. Stevens
+ *
+ * Mach Operating System
+ * Copyright (c) 1991,1990 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ *  Software Distribution Coordinator  or  Software.Distribution at CS.CMU.EDU
+ *  School of Computer Science
+ *  Carnegie Mellon University
+ *  Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/db_trace.c 278614 2015-02-12 04:15:55Z ian $");
+#include <sys/param.h>
+#include <sys/systm.h>
+
+
+#include <sys/proc.h>
+#include <sys/kdb.h>
+#include <sys/stack.h>
+#include <machine/armreg.h>
+#include <machine/asm.h>
+#include <machine/cpufunc.h>
+#include <machine/db_machdep.h>
+#include <machine/pcb.h>
+#include <machine/stack.h>
+#include <machine/vmparam.h>
+#include <ddb/ddb.h>
+#include <ddb/db_access.h>
+#include <ddb/db_sym.h>
+#include <ddb/db_output.h>
+
+#ifdef __ARM_EABI__
+/*
+ * Definitions for the instruction interpreter.
+ *
+ * The ARM EABI specifies how to perform the frame unwinding in the
+ * Exception Handling ABI for the ARM Architecture document. To perform
+ * the unwind we need to know the initial frame pointer, stack pointer,
+ * link register and program counter. We then find the entry within the
+ * index table that points to the function the program counter is within.
+ * This gives us either a list of three instructions to process, a 31-bit
+ * relative offset to a table of instructions, or a value telling us
+ * we can't unwind any further.
+ *
+ * When we have the instructions to process we need to decode them
+ * following table 4 in section 9.3. This describes a collection of bit
+ * patterns to encode that steps to take to update the stack pointer and
+ * link register to the correct values at the start of the function.
+ */
+
+/* A special case when we are unable to unwind past this function */
+#define	EXIDX_CANTUNWIND	1
+
+/* The register names */
+#define	FP	11
+#define	SP	13
+#define	LR	14
+#define	PC	15
+
+/*
+ * These are set in the linker script. Their addresses will be
+ * either the start or end of the exception table or index.
+ */
+extern int extab_start, extab_end, exidx_start, exidx_end;
+
+/*
+ * Entry types.
+ * These are the only entry types that have been seen in the kernel.
+ */
+#define	ENTRY_MASK	0xff000000
+#define	ENTRY_ARM_SU16	0x80000000
+#define	ENTRY_ARM_LU16	0x81000000
+
+/* Instruction masks. */
+#define	INSN_VSP_MASK		0xc0
+#define	INSN_VSP_SIZE_MASK	0x3f
+#define	INSN_STD_MASK		0xf0
+#define	INSN_STD_DATA_MASK	0x0f
+#define	INSN_POP_TYPE_MASK	0x08
+#define	INSN_POP_COUNT_MASK	0x07
+#define	INSN_VSP_LARGE_INC_MASK	0xff
+
+/* Instruction definitions */
+#define	INSN_VSP_INC		0x00
+#define	INSN_VSP_DEC		0x40
+#define	INSN_POP_MASKED		0x80
+#define	INSN_VSP_REG		0x90
+#define	INSN_POP_COUNT		0xa0
+#define	INSN_FINISH		0xb0
+#define	INSN_POP_REGS		0xb1
+#define	INSN_VSP_LARGE_INC	0xb2
+
+/* An item in the exception index table */
+struct unwind_idx {
+	uint32_t offset;
+	uint32_t insn;
+};
+
+/* The state of the unwind process */
+struct unwind_state {
+	uint32_t registers[16];
+	uint32_t start_pc;
+	uint32_t *insn;
+	u_int entries;
+	u_int byte;
+	uint16_t update_mask;
+};
+
+/* Expand a 31-bit signed value to a 32-bit signed value */
+static __inline int32_t
+db_expand_prel31(uint32_t prel31)
+{
+
+	return ((int32_t)(prel31 & 0x7fffffffu) << 1) / 2;
+}
+
+/*
+ * Perform a binary search of the index table to find the function
+ * with the largest address that doesn't exceed addr.
+ */
+static struct unwind_idx *
+db_find_index(uint32_t addr)
+{
+	unsigned int min, mid, max;
+	struct unwind_idx *start;
+	struct unwind_idx *item;
+	int32_t prel31_addr;
+	uint32_t func_addr;
+
+	start = (struct unwind_idx *)&exidx_start;
+
+	min = 0;
+	max = (&exidx_end - &exidx_start) / 2;
+
+	while (min != max) {
+		mid = min + (max - min + 1) / 2;
+
+		item = &start[mid];
+
+	 	prel31_addr = db_expand_prel31(item->offset);
+		func_addr = (uint32_t)&item->offset + prel31_addr;
+
+		if (func_addr <= addr) {
+			min = mid;
+		} else {
+			max = mid - 1;
+		}
+	}
+
+	return &start[min];
+}
+
+/* Reads the next byte from the instruction list */
+static uint8_t
+db_unwind_exec_read_byte(struct unwind_state *state)
+{
+	uint8_t insn;
+
+	/* Read the unwind instruction */
+	insn = (*state->insn) >> (state->byte * 8);
+
+	/* Update the location of the next instruction */
+	if (state->byte == 0) {
+		state->byte = 3;
+		state->insn++;
+		state->entries--;
+	} else
+		state->byte--;
+
+	return insn;
+}
+
+/* Executes the next instruction on the list */
+static int
+db_unwind_exec_insn(struct unwind_state *state)
+{
+	unsigned int insn;
+	uint32_t *vsp = (uint32_t *)state->registers[SP];
+	int update_vsp = 0;
+
+	/* This should never happen */
+	if (state->entries == 0)
+		return 1;
+
+	/* Read the next instruction */
+	insn = db_unwind_exec_read_byte(state);
+
+	if ((insn & INSN_VSP_MASK) == INSN_VSP_INC) {
+		state->registers[SP] += ((insn & INSN_VSP_SIZE_MASK) << 2) + 4;
+
+	} else if ((insn & INSN_VSP_MASK) == INSN_VSP_DEC) {
+		state->registers[SP] -= ((insn & INSN_VSP_SIZE_MASK) << 2) + 4;
+
+	} else if ((insn & INSN_STD_MASK) == INSN_POP_MASKED) {
+		unsigned int mask, reg;
+
+		/* Load the mask */
+		mask = db_unwind_exec_read_byte(state);
+		mask |= (insn & INSN_STD_DATA_MASK) << 8;
+
+		/* We have a refuse to unwind instruction */
+		if (mask == 0)
+			return 1;
+
+		/* Update SP */
+		update_vsp = 1;
+
+		/* Load the registers */
+		for (reg = 4; mask && reg < 16; mask >>= 1, reg++) {
+			if (mask & 1) {
+				state->registers[reg] = *vsp++;
+				state->update_mask |= 1 << reg;
+
+				/* If we have updated SP kep its value */
+				if (reg == SP)
+					update_vsp = 0;
+			}
+		}
+
+	} else if ((insn & INSN_STD_MASK) == INSN_VSP_REG &&
+	    ((insn & INSN_STD_DATA_MASK) != 13) &&
+	    ((insn & INSN_STD_DATA_MASK) != 15)) {
+		/* sp = register */
+		state->registers[SP] =
+		    state->registers[insn & INSN_STD_DATA_MASK];
+
+	} else if ((insn & INSN_STD_MASK) == INSN_POP_COUNT) {
+		unsigned int count, reg;
+
+		/* Read how many registers to load */
+		count = insn & INSN_POP_COUNT_MASK;
+
+		/* Update sp */
+		update_vsp = 1;
+
+		/* Pop the registers */
+		for (reg = 4; reg <= 4 + count; reg++) {
+			state->registers[reg] = *vsp++;
+			state->update_mask |= 1 << reg;
+		}
+
+		/* Check if we are in the pop r14 version */
+		if ((insn & INSN_POP_TYPE_MASK) != 0) {
+			state->registers[14] = *vsp++;
+		}
+
+	} else if (insn == INSN_FINISH) {
+		/* Stop processing */
+		state->entries = 0;
+
+	} else if (insn == INSN_POP_REGS) {
+		unsigned int mask, reg;
+
+		mask = db_unwind_exec_read_byte(state);
+		if (mask == 0 || (mask & 0xf0) != 0)
+			return 1;
+
+		/* Update SP */
+		update_vsp = 1;
+
+		/* Load the registers */
+		for (reg = 0; mask && reg < 4; mask >>= 1, reg++) {
+			if (mask & 1) {
+				state->registers[reg] = *vsp++;
+				state->update_mask |= 1 << reg;
+			}
+		}
+
+	} else if ((insn & INSN_VSP_LARGE_INC_MASK) == INSN_VSP_LARGE_INC) {
+		unsigned int uleb128;
+
+		/* Read the increment value */
+		uleb128 = db_unwind_exec_read_byte(state);
+
+		state->registers[SP] += 0x204 + (uleb128 << 2);
+
+	} else {
+		/* We hit a new instruction that needs to be implemented */
+		db_printf("Unhandled instruction %.2x\n", insn);
+		return 1;
+	}
+
+	if (update_vsp) {
+		state->registers[SP] = (uint32_t)vsp;
+	}
+
+#if 0
+	db_printf("fp = %08x, sp = %08x, lr = %08x, pc = %08x\n",
+	    state->registers[FP], state->registers[SP], state->registers[LR],
+	    state->registers[PC]);
+#endif
+
+	return 0;
+}
+
+/* Performs the unwind of a function */
+static int
+db_unwind_tab(struct unwind_state *state)
+{
+	uint32_t entry;
+
+	/* Set PC to a known value */
+	state->registers[PC] = 0;
+
+	/* Read the personality */
+	entry = *state->insn & ENTRY_MASK;
+
+	if (entry == ENTRY_ARM_SU16) {
+		state->byte = 2;
+		state->entries = 1;
+	} else if (entry == ENTRY_ARM_LU16) {
+		state->byte = 1;
+		state->entries = ((*state->insn >> 16) & 0xFF) + 1;
+	} else {
+		db_printf("Unknown entry: %x\n", entry);
+		return 1;
+	}
+
+	while (state->entries > 0) {
+		if (db_unwind_exec_insn(state) != 0)
+			return 1;
+	}
+
+	/*
+	 * The program counter was not updated, load it from the link register.
+	 */
+	if (state->registers[PC] == 0)
+		state->registers[PC] = state->registers[LR];
+
+	return 0;
+}
+
+static void
+db_stack_trace_cmd(struct unwind_state *state)
+{
+	struct unwind_idx *index;
+	const char *name;
+	db_expr_t value;
+	db_expr_t offset;
+	c_db_sym_t sym;
+	u_int reg, i;
+	char *sep;
+	uint16_t upd_mask;
+	bool finished;
+
+	finished = false;
+	while (!finished) {
+		/* Reset the mask of updated registers */
+		state->update_mask = 0;
+
+		/* The pc value is correct and will be overwritten, save it */
+		state->start_pc = state->registers[PC];
+
+		/* Find the item to run */
+		index = db_find_index(state->start_pc);
+
+		if (index->insn != EXIDX_CANTUNWIND) {
+			if (index->insn & (1U << 31)) {
+				/* The data is within the instruction */
+				state->insn = &index->insn;
+			} else {
+				/* A prel31 offset to the unwind table */
+				state->insn = (uint32_t *)
+				    ((uintptr_t)&index->insn + 
+				     db_expand_prel31(index->insn));
+			}
+			/* Run the unwind function */
+			finished = db_unwind_tab(state);
+		}
+
+		/* Print the frame details */
+		sym = db_search_symbol(state->start_pc, DB_STGY_ANY, &offset);
+		if (sym == C_DB_SYM_NULL) {
+			value = 0;
+			name = "(null)";
+		} else
+			db_symbol_values(sym, &name, &value);
+		db_printf("%s() at ", name);
+		db_printsym(state->start_pc, DB_STGY_PROC);
+		db_printf("\n");
+		db_printf("\t pc = 0x%08x  lr = 0x%08x (", state->start_pc,
+		    state->registers[LR]);
+		db_printsym(state->registers[LR], DB_STGY_PROC);
+		db_printf(")\n");
+		db_printf("\t sp = 0x%08x  fp = 0x%08x",
+		    state->registers[SP], state->registers[FP]);
+
+		/* Don't print the registers we have already printed */
+		upd_mask = state->update_mask & 
+		    ~((1 << SP) | (1 << FP) | (1 << LR) | (1 << PC));
+		sep = "\n\t";
+		for (i = 0, reg = 0; upd_mask != 0; upd_mask >>= 1, reg++) {
+			if ((upd_mask & 1) != 0) {
+				db_printf("%s%sr%d = 0x%08x", sep,
+				    (reg < 10) ? " " : "", reg,
+				    state->registers[reg]);
+				i++;
+				if (i == 2) {
+					sep = "\n\t";
+					i = 0;
+				} else
+					sep = " ";
+				
+			}
+		}
+		db_printf("\n");
+
+		/*
+		 * Stop if directed to do so, or if we've unwound back to the
+		 * kernel entry point, or if the unwind function didn't change
+		 * anything (to avoid getting stuck in this loop forever).
+		 * If the latter happens, it's an indication that the unwind
+		 * information is incorrect somehow for the function named in
+		 * the last frame printed before you see the unwind failure
+		 * message (maybe it needs a STOP_UNWINDING).
+		 */
+		if (index->insn == EXIDX_CANTUNWIND) {
+			db_printf("Unable to unwind further\n");
+			finished = true;
+		} else if (state->registers[PC] < VM_MIN_KERNEL_ADDRESS) {
+			db_printf("Unable to unwind into user mode\n");
+			finished = true;
+		} else if (state->update_mask == 0) {
+			db_printf("Unwind failure (no registers changed)\n");
+			finished = true;
+		}
+	}
+}
+#endif
+
+/*
+ * APCS stack frames are awkward beasts, so I don't think even trying to use
+ * a structure to represent them is a good idea.
+ *
+ * Here's the diagram from the APCS.  Increasing address is _up_ the page.
+ *
+ *          save code pointer       [fp]        <- fp points to here
+ *          return link value       [fp, #-4]
+ *          return sp value         [fp, #-8]
+ *          return fp value         [fp, #-12]
+ *          [saved v7 value]
+ *          [saved v6 value]
+ *          [saved v5 value]
+ *          [saved v4 value]
+ *          [saved v3 value]
+ *          [saved v2 value]
+ *          [saved v1 value]
+ *          [saved a4 value]
+ *          [saved a3 value]
+ *          [saved a2 value]
+ *          [saved a1 value]
+ *
+ * The save code pointer points twelve bytes beyond the start of the
+ * code sequence (usually a single STM) that created the stack frame.
+ * We have to disassemble it if we want to know which of the optional
+ * fields are actually present.
+ */
+
+#ifndef __ARM_EABI__	/* The frame format is differend in AAPCS */
+static void
+db_stack_trace_cmd(db_expr_t addr, db_expr_t count, boolean_t kernel_only)
+{
+	u_int32_t	*frame, *lastframe;
+	c_db_sym_t sym;
+	const char *name;
+	db_expr_t value;
+	db_expr_t offset;
+	int	scp_offset;
+
+	frame = (u_int32_t *)addr;
+	lastframe = NULL;
+	scp_offset = -(get_pc_str_offset() >> 2);
+
+	while (count-- && frame != NULL && !db_pager_quit) {
+		db_addr_t	scp;
+		u_int32_t	savecode;
+		int		r;
+		u_int32_t	*rp;
+		const char	*sep;
+
+		/*
+		 * In theory, the SCP isn't guaranteed to be in the function
+		 * that generated the stack frame.  We hope for the best.
+		 */
+		scp = frame[FR_SCP];
+
+		sym = db_search_symbol(scp, DB_STGY_ANY, &offset);
+		if (sym == C_DB_SYM_NULL) {
+			value = 0;
+			name = "(null)";
+		} else
+			db_symbol_values(sym, &name, &value);
+		db_printf("%s() at ", name);
+		db_printsym(scp, DB_STGY_PROC);
+		db_printf("\n");
+#ifdef __PROG26
+		db_printf("\tscp=0x%08x rlv=0x%08x (", scp, frame[FR_RLV] & R15_PC);
+		db_printsym(frame[FR_RLV] & R15_PC, DB_STGY_PROC);
+		db_printf(")\n");
+#else
+		db_printf("\tscp=0x%08x rlv=0x%08x (", scp, frame[FR_RLV]);
+		db_printsym(frame[FR_RLV], DB_STGY_PROC);
+		db_printf(")\n");
+#endif
+		db_printf("\trsp=0x%08x rfp=0x%08x", frame[FR_RSP], frame[FR_RFP]);
+
+		savecode = ((u_int32_t *)scp)[scp_offset];
+		if ((savecode & 0x0e100000) == 0x08000000) {
+			/* Looks like an STM */
+			rp = frame - 4;
+			sep = "\n\t";
+			for (r = 10; r >= 0; r--) {
+				if (savecode & (1 << r)) {
+					db_printf("%sr%d=0x%08x",
+					    sep, r, *rp--);
+					sep = (frame - rp) % 4 == 2 ?
+					    "\n\t" : " ";
+				}
+			}
+		}
+
+		db_printf("\n");
+
+		/*
+		 * Switch to next frame up
+		 */
+		if (frame[FR_RFP] == 0)
+			break; /* Top of stack */
+
+		lastframe = frame;
+		frame = (u_int32_t *)(frame[FR_RFP]);
+
+		if (INKERNEL((int)frame)) {
+			/* staying in kernel */
+			if (frame <= lastframe) {
+				db_printf("Bad frame pointer: %p\n", frame);
+				break;
+			}
+		} else if (INKERNEL((int)lastframe)) {
+			/* switch from user to kernel */
+			if (kernel_only)
+				break;	/* kernel stack only */
+		} else {
+			/* in user */
+			if (frame <= lastframe) {
+				db_printf("Bad user frame pointer: %p\n",
+					  frame);
+				break;
+			}
+		}
+	}
+}
+#endif
+
+/* XXX stubs */
+void
+db_md_list_watchpoints()
+{
+}
+
+int
+db_md_clr_watchpoint(db_expr_t addr, db_expr_t size)
+{
+	return (0);
+}
+
+int
+db_md_set_watchpoint(db_expr_t addr, db_expr_t size)
+{
+	return (0);
+}
+
+int
+db_trace_thread(struct thread *thr, int count)
+{
+#ifdef __ARM_EABI__
+	struct unwind_state state;
+#endif
+	struct pcb *ctx;
+
+	if (thr != curthread) {
+		ctx = kdb_thr_ctx(thr);
+
+#ifdef __ARM_EABI__
+		state.registers[FP] = ctx->pcb_regs.sf_r11;
+		state.registers[SP] = ctx->pcb_regs.sf_sp;
+		state.registers[LR] = ctx->pcb_regs.sf_lr;
+		state.registers[PC] = ctx->pcb_regs.sf_pc;
+
+		db_stack_trace_cmd(&state);
+#else
+		db_stack_trace_cmd(ctx->pcb_regs.sf_r11, -1, TRUE);
+#endif
+	} else
+		db_trace_self();
+	return (0);
+}
+
+void
+db_trace_self(void)
+{
+#ifdef __ARM_EABI__
+	struct unwind_state state;
+	uint32_t sp;
+
+	/* Read the stack pointer */
+	__asm __volatile("mov %0, sp" : "=&r" (sp));
+
+	state.registers[FP] = (uint32_t)__builtin_frame_address(0);
+	state.registers[SP] = sp;
+	state.registers[LR] = (uint32_t)__builtin_return_address(0);
+	state.registers[PC] = (uint32_t)db_trace_self;
+
+	db_stack_trace_cmd(&state);
+#else
+	db_addr_t addr;
+
+	addr = (db_addr_t)__builtin_frame_address(0);
+	db_stack_trace_cmd(addr, -1, FALSE);
+#endif
+}


Property changes on: trunk/sys/arm/arm/db_trace.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/devmap.c
===================================================================
--- trunk/sys/arm/arm/devmap.c	                        (rev 0)
+++ trunk/sys/arm/arm/devmap.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,311 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Ian Lepore <ian at freebsd.org>
+ * 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: stable/10/sys/arm/arm/devmap.c 266086 2014-05-14 20:17:31Z ian $");
+
+/*
+ * Routines for mapping device memory.
+ */
+
+#include "opt_ddb.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <vm/vm.h>
+#include <vm/vm_extern.h>
+#include <vm/pmap.h>
+#include <machine/armreg.h>
+#include <machine/devmap.h>
+
+static const struct arm_devmap_entry *devmap_table;
+static boolean_t devmap_bootstrap_done = false;
+
+/*
+ * The allocated-kva (akva) devmap table and metadata.  Platforms can call
+ * arm_devmap_add_entry() to add static device mappings to this table using
+ * automatically allocated virtual addresses carved out of the top of kva space.
+ * Allocation begins immediately below the ARM_VECTORS_HIGH address.
+ */
+#define	AKVA_DEVMAP_MAX_ENTRIES	32
+static struct arm_devmap_entry	akva_devmap_entries[AKVA_DEVMAP_MAX_ENTRIES];
+static u_int			akva_devmap_idx;
+static vm_offset_t		akva_devmap_vaddr = ARM_VECTORS_HIGH;
+
+/*
+ * Print the contents of the static mapping table using the provided printf-like
+ * output function (which will be either printf or db_printf).
+ */
+static void
+devmap_dump_table(int (*prfunc)(const char *, ...))
+{
+	const struct arm_devmap_entry *pd;
+
+	if (devmap_table == NULL || devmap_table[0].pd_size == 0) {
+		prfunc("No static device mappings.\n");
+		return;
+	}
+
+	prfunc("Static device mappings:\n");
+	for (pd = devmap_table; pd->pd_size != 0; ++pd) {
+		prfunc("  0x%08x - 0x%08x mapped at VA 0x%08x\n",
+		    pd->pd_pa, pd->pd_pa + pd->pd_size - 1, pd->pd_va);
+	}
+}
+
+/*
+ * Print the contents of the static mapping table.  Used for bootverbose.
+ */
+void
+arm_devmap_print_table()
+{
+	devmap_dump_table(printf);
+}
+
+/*
+ * Return the "last" kva address used by the registered devmap table.  It's
+ * actually the lowest address used by the static mappings, i.e., the address of
+ * the first unusable byte of KVA.
+ */
+vm_offset_t
+arm_devmap_lastaddr()
+{
+	const struct arm_devmap_entry *pd;
+	vm_offset_t lowaddr;
+
+	if (akva_devmap_idx > 0)
+		return (akva_devmap_vaddr);
+
+	lowaddr = ARM_VECTORS_HIGH;
+	for (pd = devmap_table; pd != NULL && pd->pd_size != 0; ++pd) {
+		if (lowaddr > pd->pd_va)
+			lowaddr = pd->pd_va;
+	}
+
+	return (lowaddr);
+}
+
+/*
+ * Add an entry to the internal "akva" static devmap table using the given
+ * physical address and size and a virtual address allocated from the top of
+ * kva.  This automatically registers the akva table on the first call, so all a
+ * platform has to do is call this routine to install as many mappings as it
+ * needs and when initarm() calls arm_devmap_bootstrap() it will pick up all the
+ * entries in the akva table automatically.
+ */
+void
+arm_devmap_add_entry(vm_paddr_t pa, vm_size_t sz)
+{
+	struct arm_devmap_entry *m;
+
+	if (devmap_bootstrap_done)
+		panic("arm_devmap_add_entry() after arm_devmap_bootstrap()");
+
+	if (akva_devmap_idx == (AKVA_DEVMAP_MAX_ENTRIES - 1))
+		panic("AKVA_DEVMAP_MAX_ENTRIES is too small");
+
+	if (akva_devmap_idx == 0)
+		arm_devmap_register_table(akva_devmap_entries);
+
+	/*
+	 * Allocate virtual address space from the top of kva downwards.  If the
+	 * range being mapped is aligned and sized to 1MB boundaries then also
+	 * align the virtual address to the next-lower 1MB boundary so that we
+	 * end up with a nice efficient section mapping.
+	 */
+	if ((pa & 0x000fffff) == 0 && (sz & 0x000fffff) == 0) {
+		akva_devmap_vaddr = trunc_1mpage(akva_devmap_vaddr - sz);
+	} else {
+		akva_devmap_vaddr = trunc_page(akva_devmap_vaddr - sz);
+	}
+	m = &akva_devmap_entries[akva_devmap_idx++];
+	m->pd_va    = akva_devmap_vaddr;
+	m->pd_pa    = pa;
+	m->pd_size  = sz;
+	m->pd_prot  = VM_PROT_READ | VM_PROT_WRITE;
+	m->pd_cache = PTE_DEVICE;
+}
+
+/*
+ * Register the given table as the one to use in arm_devmap_bootstrap().
+ */
+void
+arm_devmap_register_table(const struct arm_devmap_entry *table)
+{
+
+	devmap_table = table;
+}
+
+/*
+ * Map all of the static regions in the devmap table, and remember the devmap
+ * table so the mapdev, ptov, and vtop functions can do lookups later.
+ *
+ * If a non-NULL table pointer is given it is used unconditionally, otherwise
+ * the previously-registered table is used.  This smooths transition from legacy
+ * code that fills in a local table then calls this function passing that table,
+ * and newer code that uses arm_devmap_register_table() in platform-specific
+ * code, then lets the common initarm() call this function with a NULL pointer.
+ */
+void
+arm_devmap_bootstrap(vm_offset_t l1pt, const struct arm_devmap_entry *table)
+{
+	const struct arm_devmap_entry *pd;
+
+	devmap_bootstrap_done = true;
+
+	/*
+	 * If given a table pointer, use it.  Otherwise, if a table was
+	 * previously registered, use it.  Otherwise, no work to do.
+	 */
+	if (table != NULL)
+		devmap_table = table;
+	else if (devmap_table == NULL)
+		return;
+
+	for (pd = devmap_table; pd->pd_size != 0; ++pd) {
+		pmap_map_chunk(l1pt, pd->pd_va, pd->pd_pa, pd->pd_size,
+		    pd->pd_prot,pd->pd_cache);
+	}
+}
+
+/*
+ * Look up the given physical address in the static mapping data and return the
+ * corresponding virtual address, or NULL if not found.
+ */
+void *
+arm_devmap_ptov(vm_paddr_t pa, vm_size_t size)
+{
+	const struct arm_devmap_entry *pd;
+
+	if (devmap_table == NULL)
+		return (NULL);
+
+	for (pd = devmap_table; pd->pd_size != 0; ++pd) {
+		if (pa >= pd->pd_pa && pa + size <= pd->pd_pa + pd->pd_size)
+			return ((void *)(pd->pd_va + (pa - pd->pd_pa)));
+	}
+
+	return (NULL);
+}
+
+/*
+ * Look up the given virtual address in the static mapping data and return the
+ * corresponding physical address, or DEVMAP_PADDR_NOTFOUND if not found.
+ */
+vm_paddr_t
+arm_devmap_vtop(void * vpva, vm_size_t size)
+{
+	const struct arm_devmap_entry *pd;
+	vm_offset_t va;
+
+	if (devmap_table == NULL)
+		return (DEVMAP_PADDR_NOTFOUND);
+
+	va = (vm_offset_t)vpva;
+	for (pd = devmap_table; pd->pd_size != 0; ++pd) {
+		if (va >= pd->pd_va && va + size <= pd->pd_va + pd->pd_size)
+			return ((vm_paddr_t)(pd->pd_pa + (va - pd->pd_va)));
+	}
+
+	return (DEVMAP_PADDR_NOTFOUND);
+}
+
+/*
+ * Map a set of physical memory pages into the kernel virtual address space.
+ * Return a pointer to where it is mapped.
+ *
+ * This uses a pre-established static mapping if one exists for the requested
+ * range, otherwise it allocates kva space and maps the physical pages into it.
+ *
+ * This routine is intended to be used for mapping device memory, NOT real
+ * memory; the mapping type is inherently PTE_DEVICE in pmap_kenter_device().
+ */
+void *
+pmap_mapdev(vm_offset_t pa, vm_size_t size)
+{
+	vm_offset_t va, tmpva, offset;
+	void * rva;
+
+	/* First look in the static mapping table. */
+	if ((rva = arm_devmap_ptov(pa, size)) != NULL)
+		return (rva);
+	
+	offset = pa & PAGE_MASK;
+	pa = trunc_page(pa);
+	size = round_page(size + offset);
+	
+	va = kva_alloc(size);
+	if (!va)
+		panic("pmap_mapdev: Couldn't alloc kernel virtual memory");
+
+	for (tmpva = va; size > 0;) {
+		pmap_kenter_device(tmpva, pa);
+		size -= PAGE_SIZE;
+		tmpva += PAGE_SIZE;
+		pa += PAGE_SIZE;
+	}
+	
+	return ((void *)(va + offset));
+}
+
+/*
+ * Unmap device memory and free the kva space.
+ */
+void
+pmap_unmapdev(vm_offset_t va, vm_size_t size)
+{
+	vm_offset_t tmpva, offset;
+	vm_size_t origsize;
+
+	/* Nothing to do if we find the mapping in the static table. */
+	if (arm_devmap_vtop((void*)va, size) != DEVMAP_PADDR_NOTFOUND)
+		return;
+
+	origsize = size;
+	offset = va & PAGE_MASK;
+	va = trunc_page(va);
+	size = round_page(size + offset);
+
+	for (tmpva = va; size > 0;) {
+		pmap_kremove(tmpva);
+		size -= PAGE_SIZE;
+		tmpva += PAGE_SIZE;
+	}
+
+	kva_free(va, origsize);
+}
+
+#ifdef DDB
+#include <ddb/ddb.h>
+
+DB_SHOW_COMMAND(devmap, db_show_devmap)
+{
+	devmap_dump_table(db_printf);
+}
+
+#endif /* DDB */
+


Property changes on: trunk/sys/arm/arm/devmap.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/disassem.c
===================================================================
--- trunk/sys/arm/arm/disassem.c	                        (rev 0)
+++ trunk/sys/arm/arm/disassem.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,694 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: disassem.c,v 1.14 2003/03/27 16:58:36 mycroft Exp $	*/
+
+/*-
+ * Copyright (c) 1996 Mark Brinicombe.
+ * Copyright (c) 1996 Brini.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Brini.
+ * 4. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BRINI ``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 BRINI 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.
+ *
+ * RiscBSD kernel project
+ *
+ * db_disasm.c
+ *
+ * Kernel disassembler
+ *
+ * Created      : 10/02/96
+ *
+ * Structured after the sparc/sparc/db_disasm.c by David S. Miller &
+ * Paul Kranenburg
+ *
+ * This code is not complete. Not all instructions are disassembled.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/disassem.c 279467 2015-03-01 01:08:14Z dim $");
+#include <sys/param.h>
+
+
+#include <sys/systm.h>
+#include <machine/disassem.h>
+#include <machine/armreg.h>
+#include <machine/acle-compat.h>
+#include <ddb/ddb.h>
+
+/*
+ * General instruction format
+ *
+ *	insn[cc][mod]	[operands]
+ *
+ * Those fields with an uppercase format code indicate that the field
+ * follows directly after the instruction before the separator i.e.
+ * they modify the instruction rather than just being an operand to
+ * the instruction. The only exception is the writeback flag which
+ * follows a operand.
+ *
+ *
+ * 2 - print Operand 2 of a data processing instruction
+ * d - destination register (bits 12-15)
+ * n - n register (bits 16-19)
+ * s - s register (bits 8-11)
+ * o - indirect register rn (bits 16-19) (used by swap)
+ * m - m register (bits 0-3)
+ * a - address operand of ldr/str instruction
+ * l - register list for ldm/stm instruction
+ * f - 1st fp operand (register) (bits 12-14)
+ * g - 2nd fp operand (register) (bits 16-18)
+ * h - 3rd fp operand (register/immediate) (bits 0-4)
+ * b - branch address
+ * t - thumb branch address (bits 24, 0-23)
+ * k - breakpoint comment (bits 0-3, 8-19)
+ * X - block transfer type
+ * Y - block transfer type (r13 base)
+ * c - comment field bits(0-23)
+ * p - saved or current status register
+ * F - PSR transfer fields
+ * D - destination-is-r15 (P) flag on TST, TEQ, CMP, CMN
+ * L - co-processor transfer size
+ * S - set status flag
+ * P - fp precision
+ * Q - fp precision (for ldf/stf)
+ * R - fp rounding
+ * v - co-processor data transfer registers + addressing mode
+ * W - writeback flag
+ * x - instruction in hex
+ * # - co-processor number
+ * y - co-processor data processing registers
+ * z - co-processor register transfer registers
+ */
+
+struct arm32_insn {
+	u_int mask;
+	u_int pattern;
+	char* name;
+	char* format;
+};
+
+static const struct arm32_insn arm32_i[] = {
+    { 0x0fffffff, 0x0ff00000, "imb",	"c" },		/* Before swi */
+    { 0x0fffffff, 0x0ff00001, "imbrange",	"c" },	/* Before swi */
+    { 0x0f000000, 0x0f000000, "swi",	"c" },
+    { 0xfe000000, 0xfa000000, "blx",	"t" },		/* Before b and bl */
+    { 0x0f000000, 0x0a000000, "b",	"b" },
+    { 0x0f000000, 0x0b000000, "bl",	"b" },
+    { 0x0fe000f0, 0x00000090, "mul",	"Snms" },
+    { 0x0fe000f0, 0x00200090, "mla",	"Snmsd" },
+    { 0x0fe000f0, 0x00800090, "umull",	"Sdnms" },
+    { 0x0fe000f0, 0x00c00090, "smull",	"Sdnms" },
+    { 0x0fe000f0, 0x00a00090, "umlal",	"Sdnms" },
+    { 0x0fe000f0, 0x00e00090, "smlal",	"Sdnms" },
+    { 0x0d700000, 0x04200000, "strt",	"daW" },
+    { 0x0d700000, 0x04300000, "ldrt",	"daW" },
+    { 0x0d700000, 0x04600000, "strbt",	"daW" },
+    { 0x0d700000, 0x04700000, "ldrbt",	"daW" },
+    { 0x0c500000, 0x04000000, "str",	"daW" },
+    { 0x0c500000, 0x04100000, "ldr",	"daW" },
+    { 0x0c500000, 0x04400000, "strb",	"daW" },
+    { 0x0c500000, 0x04500000, "ldrb",	"daW" },
+#if __ARM_ARCH >= 6
+    { 0xffffffff, 0xf57ff01f, "clrex",	"c" },
+    { 0x0ff00ff0, 0x01800f90, "strex",	"dmo" },
+    { 0x0ff00fff, 0x01900f9f, "ldrex",	"do" },
+    { 0x0ff00ff0, 0x01a00f90, "strexd",	"dmo" },
+    { 0x0ff00fff, 0x01b00f9f, "ldrexd",	"do" },
+    { 0x0ff00ff0, 0x01c00f90, "strexb",	"dmo" },
+    { 0x0ff00fff, 0x01d00f9f, "ldrexb",	"do" },
+    { 0x0ff00ff0, 0x01e00f90, "strexh",	"dmo" },
+    { 0x0ff00fff, 0x01f00f9f, "ldrexh",	"do" },
+#endif
+    { 0x0e1f0000, 0x080d0000, "stm",	"YnWl" },/* separate out r13 base */
+    { 0x0e1f0000, 0x081d0000, "ldm",	"YnWl" },/* separate out r13 base */
+    { 0x0e100000, 0x08000000, "stm",	"XnWl" },
+    { 0x0e100000, 0x08100000, "ldm",	"XnWl" },
+    { 0x0e1000f0, 0x00100090, "ldrb",	"de" },
+    { 0x0e1000f0, 0x00000090, "strb",	"de" },
+    { 0x0e1000f0, 0x001000d0, "ldrsb",	"de" },
+    { 0x0e1000f0, 0x001000b0, "ldrh",	"de" },
+    { 0x0e1000f0, 0x000000b0, "strh",	"de" },
+    { 0x0e1000f0, 0x001000f0, "ldrsh",	"de" },
+    { 0x0f200090, 0x00200090, "und",	"x" },	/* Before data processing */
+    { 0x0e1000d0, 0x000000d0, "und",	"x" },	/* Before data processing */
+    { 0x0ff00ff0, 0x01000090, "swp",	"dmo" },
+    { 0x0ff00ff0, 0x01400090, "swpb",	"dmo" },
+    { 0x0fbf0fff, 0x010f0000, "mrs",	"dp" },	/* Before data processing */
+    { 0x0fb0fff0, 0x0120f000, "msr",	"pFm" },/* Before data processing */
+    { 0x0fb0f000, 0x0320f000, "msr",	"pF2" },/* Before data processing */
+    { 0x0ffffff0, 0x012fff10, "bx",	"m" },
+    { 0x0fff0ff0, 0x016f0f10, "clz",	"dm" },
+    { 0x0ffffff0, 0x012fff30, "blx",	"m" },
+    { 0xfff000f0, 0xe1200070, "bkpt",	"k" },
+    { 0x0de00000, 0x00000000, "and",	"Sdn2" },
+    { 0x0de00000, 0x00200000, "eor",	"Sdn2" },
+    { 0x0de00000, 0x00400000, "sub",	"Sdn2" },
+    { 0x0de00000, 0x00600000, "rsb",	"Sdn2" },
+    { 0x0de00000, 0x00800000, "add",	"Sdn2" },
+    { 0x0de00000, 0x00a00000, "adc",	"Sdn2" },
+    { 0x0de00000, 0x00c00000, "sbc",	"Sdn2" },
+    { 0x0de00000, 0x00e00000, "rsc",	"Sdn2" },
+    { 0x0df00000, 0x01100000, "tst",	"Dn2" },
+    { 0x0df00000, 0x01300000, "teq",	"Dn2" },
+    { 0x0de00000, 0x01400000, "cmp",	"Dn2" },
+    { 0x0de00000, 0x01600000, "cmn",	"Dn2" },
+    { 0x0de00000, 0x01800000, "orr",	"Sdn2" },
+    { 0x0de00000, 0x01a00000, "mov",	"Sd2" },
+    { 0x0de00000, 0x01c00000, "bic",	"Sdn2" },
+    { 0x0de00000, 0x01e00000, "mvn",	"Sd2" },
+    { 0x0ff08f10, 0x0e000100, "adf",	"PRfgh" },
+    { 0x0ff08f10, 0x0e100100, "muf",	"PRfgh" },
+    { 0x0ff08f10, 0x0e200100, "suf",	"PRfgh" },
+    { 0x0ff08f10, 0x0e300100, "rsf",	"PRfgh" },
+    { 0x0ff08f10, 0x0e400100, "dvf",	"PRfgh" },
+    { 0x0ff08f10, 0x0e500100, "rdf",	"PRfgh" },
+    { 0x0ff08f10, 0x0e600100, "pow",	"PRfgh" },
+    { 0x0ff08f10, 0x0e700100, "rpw",	"PRfgh" },
+    { 0x0ff08f10, 0x0e800100, "rmf",	"PRfgh" },
+    { 0x0ff08f10, 0x0e900100, "fml",	"PRfgh" },
+    { 0x0ff08f10, 0x0ea00100, "fdv",	"PRfgh" },
+    { 0x0ff08f10, 0x0eb00100, "frd",	"PRfgh" },
+    { 0x0ff08f10, 0x0ec00100, "pol",	"PRfgh" },
+    { 0x0f008f10, 0x0e000100, "fpbop",	"PRfgh" },
+    { 0x0ff08f10, 0x0e008100, "mvf",	"PRfh" },
+    { 0x0ff08f10, 0x0e108100, "mnf",	"PRfh" },
+    { 0x0ff08f10, 0x0e208100, "abs",	"PRfh" },
+    { 0x0ff08f10, 0x0e308100, "rnd",	"PRfh" },
+    { 0x0ff08f10, 0x0e408100, "sqt",	"PRfh" },
+    { 0x0ff08f10, 0x0e508100, "log",	"PRfh" },
+    { 0x0ff08f10, 0x0e608100, "lgn",	"PRfh" },
+    { 0x0ff08f10, 0x0e708100, "exp",	"PRfh" },
+    { 0x0ff08f10, 0x0e808100, "sin",	"PRfh" },
+    { 0x0ff08f10, 0x0e908100, "cos",	"PRfh" },
+    { 0x0ff08f10, 0x0ea08100, "tan",	"PRfh" },
+    { 0x0ff08f10, 0x0eb08100, "asn",	"PRfh" },
+    { 0x0ff08f10, 0x0ec08100, "acs",	"PRfh" },
+    { 0x0ff08f10, 0x0ed08100, "atn",	"PRfh" },
+    { 0x0f008f10, 0x0e008100, "fpuop",	"PRfh" },
+    { 0x0e100f00, 0x0c000100, "stf",	"QLv" },
+    { 0x0e100f00, 0x0c100100, "ldf",	"QLv" },
+    { 0x0ff00f10, 0x0e000110, "flt",	"PRgd" },
+    { 0x0ff00f10, 0x0e100110, "fix",	"PRdh" },
+    { 0x0ff00f10, 0x0e200110, "wfs",	"d" },
+    { 0x0ff00f10, 0x0e300110, "rfs",	"d" },
+    { 0x0ff00f10, 0x0e400110, "wfc",	"d" },
+    { 0x0ff00f10, 0x0e500110, "rfc",	"d" },
+    { 0x0ff0ff10, 0x0e90f110, "cmf",	"PRgh" },
+    { 0x0ff0ff10, 0x0eb0f110, "cnf",	"PRgh" },
+    { 0x0ff0ff10, 0x0ed0f110, "cmfe",	"PRgh" },
+    { 0x0ff0ff10, 0x0ef0f110, "cnfe",	"PRgh" },
+    { 0xff100010, 0xfe000010, "mcr2",	"#z" },
+    { 0x0f100010, 0x0e000010, "mcr",	"#z" },
+    { 0xff100010, 0xfe100010, "mrc2",	"#z" },
+    { 0x0f100010, 0x0e100010, "mrc",	"#z" },
+    { 0xff000010, 0xfe000000, "cdp2",	"#y" },
+    { 0x0f000010, 0x0e000000, "cdp",	"#y" },
+    { 0xfe100090, 0xfc100000, "ldc2",	"L#v" },
+    { 0x0e100090, 0x0c100000, "ldc",	"L#v" },
+    { 0xfe100090, 0xfc000000, "stc2",	"L#v" },
+    { 0x0e100090, 0x0c000000, "stc",	"L#v" },
+    { 0x00000000, 0x00000000, NULL,	NULL }
+};
+
+static char const arm32_insn_conditions[][4] = {
+	"eq", "ne", "cs", "cc",
+	"mi", "pl", "vs", "vc",
+	"hi", "ls", "ge", "lt",
+	"gt", "le", "",   "nv"
+};
+
+static char const insn_block_transfers[][4] = {
+	"da", "ia", "db", "ib"
+};
+
+static char const insn_stack_block_transfers[][4] = {
+	"ed", "ea", "fd", "fa"
+};
+
+static char const op_shifts[][4] = {
+	"lsl", "lsr", "asr", "ror"
+};
+
+static char const insn_fpa_rounding[][2] = {
+	"", "p", "m", "z"
+};
+
+static char const insn_fpa_precision[][2] = {
+	"s", "d", "e", "p"
+};
+
+static char const insn_fpaconstants[][8] = {
+	"0.0", "1.0", "2.0", "3.0",
+	"4.0", "5.0", "0.5", "10.0"
+};
+
+#define insn_condition(x)	arm32_insn_conditions[(x >> 28) & 0x0f]
+#define insn_blktrans(x)	insn_block_transfers[(x >> 23) & 3]
+#define insn_stkblktrans(x)	insn_stack_block_transfers[(x >> 23) & 3]
+#define op2_shift(x)		op_shifts[(x >> 5) & 3]
+#define insn_fparnd(x)		insn_fpa_rounding[(x >> 5) & 0x03]
+#define insn_fpaprec(x)		insn_fpa_precision[(((x >> 18) & 2)|(x >> 7)) & 1]
+#define insn_fpaprect(x)	insn_fpa_precision[(((x >> 21) & 2)|(x >> 15)) & 1]
+#define insn_fpaimm(x)		insn_fpaconstants[x & 0x07]
+
+/* Local prototypes */
+static void disasm_register_shift(const disasm_interface_t *di, u_int insn);
+static void disasm_print_reglist(const disasm_interface_t *di, u_int insn);
+static void disasm_insn_ldrstr(const disasm_interface_t *di, u_int insn,
+    u_int loc);
+static void disasm_insn_ldrhstrh(const disasm_interface_t *di, u_int insn,
+    u_int loc);
+static void disasm_insn_ldcstc(const disasm_interface_t *di, u_int insn,
+    u_int loc);
+static u_int disassemble_readword(u_int address);
+static void disassemble_printaddr(u_int address);
+
+vm_offset_t
+disasm(const disasm_interface_t *di, vm_offset_t loc, int altfmt)
+{
+	const struct arm32_insn *i_ptr = arm32_i;
+
+	u_int insn;
+	int matchp;
+	int branch;
+	char* f_ptr;
+	int fmt;
+
+	fmt = 0;
+	matchp = 0;
+	insn = di->di_readword(loc);
+
+/*	di->di_printf("loc=%08x insn=%08x : ", loc, insn);*/
+
+	while (i_ptr->name) {
+		if ((insn & i_ptr->mask) ==  i_ptr->pattern) {
+			matchp = 1;
+			break;
+		}
+		i_ptr++;
+	}
+
+	if (!matchp) {
+		di->di_printf("und%s\t%08x\n", insn_condition(insn), insn);
+		return(loc + INSN_SIZE);
+	}
+
+	/* If instruction forces condition code, don't print it. */
+	if ((i_ptr->mask & 0xf0000000) == 0xf0000000)
+		di->di_printf("%s", i_ptr->name);
+	else
+		di->di_printf("%s%s", i_ptr->name, insn_condition(insn));
+
+	f_ptr = i_ptr->format;
+
+	/* Insert tab if there are no instruction modifiers */
+
+	if (*(f_ptr) < 'A' || *(f_ptr) > 'Z') {
+		++fmt;
+		di->di_printf("\t");
+	}
+
+	while (*f_ptr) {
+		switch (*f_ptr) {
+		/* 2 - print Operand 2 of a data processing instruction */
+		case '2':
+			if (insn & 0x02000000) {
+				int rotate= ((insn >> 7) & 0x1e);
+
+				di->di_printf("#0x%08x",
+					      (insn & 0xff) << (32 - rotate) |
+					      (insn & 0xff) >> rotate);
+			} else {
+				disasm_register_shift(di, insn);
+			}
+			break;
+		/* d - destination register (bits 12-15) */
+		case 'd':
+			di->di_printf("r%d", ((insn >> 12) & 0x0f));
+			break;
+		/* D - insert 'p' if Rd is R15 */
+		case 'D':
+			if (((insn >> 12) & 0x0f) == 15)
+				di->di_printf("p");
+			break;
+		/* n - n register (bits 16-19) */
+		case 'n':
+			di->di_printf("r%d", ((insn >> 16) & 0x0f));
+			break;
+		/* s - s register (bits 8-11) */
+		case 's':
+			di->di_printf("r%d", ((insn >> 8) & 0x0f));
+			break;
+		/* o - indirect register rn (bits 16-19) (used by swap) */
+		case 'o':
+			di->di_printf("[r%d]", ((insn >> 16) & 0x0f));
+			break;
+		/* m - m register (bits 0-4) */
+		case 'm':
+			di->di_printf("r%d", ((insn >> 0) & 0x0f));
+			break;
+		/* a - address operand of ldr/str instruction */
+		case 'a':
+			disasm_insn_ldrstr(di, insn, loc);
+			break;
+		/* e - address operand of ldrh/strh instruction */
+		case 'e':
+			disasm_insn_ldrhstrh(di, insn, loc);
+			break;
+		/* l - register list for ldm/stm instruction */
+		case 'l':
+			disasm_print_reglist(di, insn);
+			break;
+		/* f - 1st fp operand (register) (bits 12-14) */
+		case 'f':
+			di->di_printf("f%d", (insn >> 12) & 7);
+			break;
+		/* g - 2nd fp operand (register) (bits 16-18) */
+		case 'g':
+			di->di_printf("f%d", (insn >> 16) & 7);
+			break;
+		/* h - 3rd fp operand (register/immediate) (bits 0-4) */
+		case 'h':
+			if (insn & (1 << 3))
+				di->di_printf("#%s", insn_fpaimm(insn));
+			else
+				di->di_printf("f%d", insn & 7);
+			break;
+		/* b - branch address */
+		case 'b':
+			branch = ((insn << 2) & 0x03ffffff);
+			if (branch & 0x02000000)
+				branch |= 0xfc000000;
+			di->di_printaddr(loc + 8 + branch);
+			break;
+		/* t - blx address */
+		case 't':
+			branch = ((insn << 2) & 0x03ffffff) |
+			    (insn >> 23 & 0x00000002);
+			if (branch & 0x02000000)
+				branch |= 0xfc000000;
+			di->di_printaddr(loc + 8 + branch);
+			break;
+		/* X - block transfer type */
+		case 'X':
+			di->di_printf("%s", insn_blktrans(insn));
+			break;
+		/* Y - block transfer type (r13 base) */
+		case 'Y':
+			di->di_printf("%s", insn_stkblktrans(insn));
+			break;
+		/* c - comment field bits(0-23) */
+		case 'c':
+			di->di_printf("0x%08x", (insn & 0x00ffffff));
+			break;
+		/* k - breakpoint comment (bits 0-3, 8-19) */
+		case 'k':
+			di->di_printf("0x%04x",
+			    (insn & 0x000fff00) >> 4 | (insn & 0x0000000f));
+			break;
+		/* p - saved or current status register */
+		case 'p':
+			if (insn & 0x00400000)
+				di->di_printf("spsr");
+			else
+				di->di_printf("cpsr");
+			break;
+		/* F - PSR transfer fields */
+		case 'F':
+			di->di_printf("_");
+			if (insn & (1 << 16))
+				di->di_printf("c");
+			if (insn & (1 << 17))
+				di->di_printf("x");
+			if (insn & (1 << 18))
+				di->di_printf("s");
+			if (insn & (1 << 19))
+				di->di_printf("f");
+			break;
+		/* B - byte transfer flag */
+		case 'B':
+			if (insn & 0x00400000)
+				di->di_printf("b");
+			break;
+		/* L - co-processor transfer size */
+		case 'L':
+			if (insn & (1 << 22))
+				di->di_printf("l");
+			break;
+		/* S - set status flag */
+		case 'S':
+			if (insn & 0x00100000)
+				di->di_printf("s");
+			break;
+		/* P - fp precision */
+		case 'P':
+			di->di_printf("%s", insn_fpaprec(insn));
+			break;
+		/* Q - fp precision (for ldf/stf) */
+		case 'Q':
+			break;
+		/* R - fp rounding */
+		case 'R':
+			di->di_printf("%s", insn_fparnd(insn));
+			break;
+		/* W - writeback flag */
+		case 'W':
+			if (insn & (1 << 21))
+				di->di_printf("!");
+			break;
+		/* # - co-processor number */
+		case '#':
+			di->di_printf("p%d", (insn >> 8) & 0x0f);
+			break;
+		/* v - co-processor data transfer registers+addressing mode */
+		case 'v':
+			disasm_insn_ldcstc(di, insn, loc);
+			break;
+		/* x - instruction in hex */
+		case 'x':
+			di->di_printf("0x%08x", insn);
+			break;
+		/* y - co-processor data processing registers */
+		case 'y':
+			di->di_printf("%d, ", (insn >> 20) & 0x0f);
+
+			di->di_printf("c%d, c%d, c%d", (insn >> 12) & 0x0f,
+			    (insn >> 16) & 0x0f, insn & 0x0f);
+
+			di->di_printf(", %d", (insn >> 5) & 0x07);
+			break;
+		/* z - co-processor register transfer registers */
+		case 'z':
+			di->di_printf("%d, ", (insn >> 21) & 0x07);
+			di->di_printf("r%d, c%d, c%d, %d",
+			    (insn >> 12) & 0x0f, (insn >> 16) & 0x0f,
+			    insn & 0x0f, (insn >> 5) & 0x07);
+
+/*			if (((insn >> 5) & 0x07) != 0)
+				di->di_printf(", %d", (insn >> 5) & 0x07);*/
+			break;
+		default:
+			di->di_printf("[%c - unknown]", *f_ptr);
+			break;
+		}
+		if (*(f_ptr+1) >= 'A' && *(f_ptr+1) <= 'Z')
+			++f_ptr;
+		else if (*(++f_ptr)) {
+			++fmt;
+			if (fmt == 1)
+				di->di_printf("\t");
+			else
+				di->di_printf(", ");
+		}
+	};
+
+	di->di_printf("\n");
+
+	return(loc + INSN_SIZE);
+}
+
+
+static void
+disasm_register_shift(const disasm_interface_t *di, u_int insn)
+{
+	di->di_printf("r%d", (insn & 0x0f));
+	if ((insn & 0x00000ff0) == 0)
+		;
+	else if ((insn & 0x00000ff0) == 0x00000060)
+		di->di_printf(", rrx");
+	else {
+		if (insn & 0x10)
+			di->di_printf(", %s r%d", op2_shift(insn),
+			    (insn >> 8) & 0x0f);
+		else
+			di->di_printf(", %s #%d", op2_shift(insn),
+			    (insn >> 7) & 0x1f);
+	}
+}
+
+
+static void
+disasm_print_reglist(const disasm_interface_t *di, u_int insn)
+{
+	int loop;
+	int start;
+	int comma;
+
+	di->di_printf("{");
+	start = -1;
+	comma = 0;
+
+	for (loop = 0; loop < 17; ++loop) {
+		if (start != -1) {
+			if (loop == 16 || !(insn & (1 << loop))) {
+				if (comma)
+					di->di_printf(", ");
+				else
+					comma = 1;
+        			if (start == loop - 1)
+        				di->di_printf("r%d", start);
+        			else
+        				di->di_printf("r%d-r%d", start, loop - 1);
+        			start = -1;
+        		}
+        	} else {
+        		if (insn & (1 << loop))
+        			start = loop;
+        	}
+        }
+	di->di_printf("}");
+
+	if (insn & (1 << 22))
+		di->di_printf("^");
+}
+
+static void
+disasm_insn_ldrstr(const disasm_interface_t *di, u_int insn, u_int loc)
+{
+	int offset;
+
+	offset = insn & 0xfff;
+	if ((insn & 0x032f0000) == 0x010f0000) {
+		/* rA = pc, immediate index */
+		if (insn & 0x00800000)
+			loc += offset;
+		else
+			loc -= offset;
+		di->di_printaddr(loc + 8);
+ 	} else {
+		di->di_printf("[r%d", (insn >> 16) & 0x0f);
+		if ((insn & 0x03000fff) != 0x01000000) {
+			di->di_printf("%s, ", (insn & (1 << 24)) ? "" : "]");
+			if (!(insn & 0x00800000))
+				di->di_printf("-");
+			if (insn & (1 << 25))
+				disasm_register_shift(di, insn);
+			else
+				di->di_printf("#0x%03x", offset);
+		}
+		if (insn & (1 << 24))
+			di->di_printf("]");
+	}
+}
+
+static void
+disasm_insn_ldrhstrh(const disasm_interface_t *di, u_int insn, u_int loc)
+{
+	int offset;
+
+	offset = ((insn & 0xf00) >> 4) | (insn & 0xf);
+	if ((insn & 0x004f0000) == 0x004f0000) {
+		/* rA = pc, immediate index */
+		if (insn & 0x00800000)
+			loc += offset;
+		else
+			loc -= offset;
+		di->di_printaddr(loc + 8);
+ 	} else {
+		di->di_printf("[r%d", (insn >> 16) & 0x0f);
+		if ((insn & 0x01400f0f) != 0x01400000) {
+			di->di_printf("%s, ", (insn & (1 << 24)) ? "" : "]");
+			if (!(insn & 0x00800000))
+				di->di_printf("-");
+			if (insn & (1 << 22))
+				di->di_printf("#0x%02x", offset);
+			else
+				di->di_printf("r%d", (insn & 0x0f));
+		}
+		if (insn & (1 << 24))
+			di->di_printf("]");
+	}
+}
+
+static void
+disasm_insn_ldcstc(const disasm_interface_t *di, u_int insn, u_int loc)
+{
+	if (((insn >> 8) & 0xf) == 1)
+		di->di_printf("f%d, ", (insn >> 12) & 0x07);
+	else
+		di->di_printf("c%d, ", (insn >> 12) & 0x0f);
+
+	di->di_printf("[r%d", (insn >> 16) & 0x0f);
+
+	di->di_printf("%s, ", (insn & (1 << 24)) ? "" : "]");
+
+	if (!(insn & (1 << 23)))
+		di->di_printf("-");
+
+	di->di_printf("#0x%03x", (insn & 0xff) << 2);
+
+	if (insn & (1 << 24))
+		di->di_printf("]");
+
+	if (insn & (1 << 21))
+		di->di_printf("!");
+}
+
+static u_int
+disassemble_readword(u_int address)
+{
+	return(*((u_int *)address));
+}
+
+static void
+disassemble_printaddr(u_int address)
+{
+	printf("0x%08x", address);
+}
+
+static const disasm_interface_t disassemble_di = {
+	disassemble_readword, disassemble_printaddr, db_printf
+};
+
+void
+disassemble(u_int address)
+{
+
+	(void)disasm(&disassemble_di, address, 0);
+}
+
+/* End of disassem.c */


Property changes on: trunk/sys/arm/arm/disassem.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/dump_machdep.c
===================================================================
--- trunk/sys/arm/arm/dump_machdep.c	                        (rev 0)
+++ trunk/sys/arm/arm/dump_machdep.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,410 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2002 Marcel Moolenaar
+ * 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 ``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 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: stable/10/sys/arm/arm/dump_machdep.c 278614 2015-02-12 04:15:55Z ian $");
+
+#include "opt_watchdog.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/conf.h>
+#include <sys/cons.h>
+#include <sys/sysctl.h>
+#include <sys/kernel.h>
+#include <sys/proc.h>
+#include <sys/kerneldump.h>
+#ifdef SW_WATCHDOG
+#include <sys/watchdog.h>
+#endif
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <machine/elf.h>
+#include <machine/md_var.h>
+#include <machine/pcb.h>
+#include <machine/armreg.h>
+
+CTASSERT(sizeof(struct kerneldumpheader) == 512);
+
+int do_minidump = 1;
+TUNABLE_INT("debug.minidump", &do_minidump);
+SYSCTL_INT(_debug, OID_AUTO, minidump, CTLFLAG_RW, &do_minidump, 0,
+    "Enable mini crash dumps");
+
+/*
+ * Don't touch the first SIZEOF_METADATA bytes on the dump device. This
+ * is to protect us from metadata and to protect metadata from us.
+ */
+#define	SIZEOF_METADATA		(64*1024)
+
+#define	MD_ALIGN(x)	(((off_t)(x) + PAGE_MASK) & ~PAGE_MASK)
+#define	DEV_ALIGN(x)	(((off_t)(x) + (DEV_BSIZE-1)) & ~(DEV_BSIZE-1))
+extern struct pcb dumppcb;
+
+struct md_pa {
+	vm_paddr_t md_start;
+	vm_paddr_t md_size;
+};
+
+typedef int callback_t(struct md_pa *, int, void *);
+
+static struct kerneldumpheader kdh;
+static off_t dumplo, fileofs;
+
+/* Handle buffered writes. */
+static char buffer[DEV_BSIZE];
+static size_t fragsz;
+
+/* XXX: I suppose 20 should be enough. */
+static struct md_pa dump_map[20];
+
+static void
+md_pa_init(void)
+{
+	int n, idx;
+
+	bzero(dump_map, sizeof(dump_map));
+	for (n = 0; n < sizeof(dump_map) / sizeof(dump_map[0]); n++) {
+		idx = n * 2;
+		if (dump_avail[idx] == 0 && dump_avail[idx + 1] == 0)
+			break;
+		dump_map[n].md_start = dump_avail[idx];
+		dump_map[n].md_size = dump_avail[idx + 1] - dump_avail[idx];
+	}
+}
+
+static struct md_pa *
+md_pa_first(void)
+{
+
+	return (&dump_map[0]);
+}
+
+static struct md_pa *
+md_pa_next(struct md_pa *mdp)
+{
+
+	mdp++;
+	if (mdp->md_size == 0)
+		mdp = NULL;
+	return (mdp);
+}
+
+static int
+buf_write(struct dumperinfo *di, char *ptr, size_t sz)
+{
+	size_t len;
+	int error;
+
+	while (sz) {
+		len = DEV_BSIZE - fragsz;
+		if (len > sz)
+			len = sz;
+		bcopy(ptr, buffer + fragsz, len);
+		fragsz += len;
+		ptr += len;
+		sz -= len;
+		if (fragsz == DEV_BSIZE) {
+			error = dump_write(di, buffer, 0, dumplo,
+			    DEV_BSIZE);
+			if (error)
+				return error;
+			dumplo += DEV_BSIZE;
+			fragsz = 0;
+		}
+	}
+
+	return (0);
+}
+
+static int
+buf_flush(struct dumperinfo *di)
+{
+	int error;
+
+	if (fragsz == 0)
+		return (0);
+
+	error = dump_write(di, buffer, 0, dumplo, DEV_BSIZE);
+	dumplo += DEV_BSIZE;
+	fragsz = 0;
+	return (error);
+}
+
+extern vm_offset_t kernel_l1kva;
+extern char *pouet2;
+
+static int
+cb_dumpdata(struct md_pa *mdp, int seqnr, void *arg)
+{
+	struct dumperinfo *di = (struct dumperinfo*)arg;
+	vm_paddr_t a, pa;
+	void *va;
+	uint32_t pgs;
+	size_t counter, sz, chunk;
+	int i, c, error;
+
+	va = 0;
+	error = 0;	/* catch case in which chunk size is 0 */
+	counter = 0;
+	pgs = mdp->md_size / PAGE_SIZE;
+	pa = mdp->md_start;
+
+	printf("  chunk %d: %dMB (%d pages)", seqnr, pgs * PAGE_SIZE / (
+	    1024*1024), pgs);
+
+	/*
+	 * Make sure we write coherent data.  Note that in the SMP case this
+	 * only operates on the L1 cache of the current CPU, but all other CPUs
+	 * have already been stopped, and their flush/invalidate was done as
+	 * part of stopping.
+	 */
+	cpu_idcache_wbinv_all();
+	cpu_l2cache_wbinv_all();
+#ifdef __XSCALE__
+	xscale_cache_clean_minidata();
+#endif
+	while (pgs) {
+		chunk = pgs;
+		if (chunk > MAXDUMPPGS)
+			chunk = MAXDUMPPGS;
+		sz = chunk << PAGE_SHIFT;
+		counter += sz;
+		if (counter >> 24) {
+			printf(" %d", pgs * PAGE_SIZE);
+			counter &= (1<<24) - 1;
+		}
+		for (i = 0; i < chunk; i++) {
+			a = pa + i * PAGE_SIZE;
+			va = pmap_kenter_temporary(trunc_page(a), i);
+		}
+#ifdef SW_WATCHDOG
+		wdog_kern_pat(WD_LASTVAL);
+#endif
+		error = dump_write(di, va, 0, dumplo, sz);
+		if (error)
+			break;
+		dumplo += sz;
+		pgs -= chunk;
+		pa += sz;
+
+		/* Check for user abort. */
+		c = cncheckc();
+		if (c == 0x03)
+			return (ECANCELED);
+		if (c != -1)
+			printf(" (CTRL-C to abort) ");
+	}
+	printf(" ... %s\n", (error) ? "fail" : "ok");
+	return (error);
+}
+
+static int
+cb_dumphdr(struct md_pa *mdp, int seqnr, void *arg)
+{
+	struct dumperinfo *di = (struct dumperinfo*)arg;
+	Elf_Phdr phdr;
+	uint64_t size;
+	int error;
+
+	size = mdp->md_size;
+	bzero(&phdr, sizeof(phdr));
+	phdr.p_type = PT_LOAD;
+	phdr.p_flags = PF_R;			/* XXX */
+	phdr.p_offset = fileofs;
+	phdr.p_vaddr = mdp->md_start;
+	phdr.p_paddr = mdp->md_start;
+	phdr.p_filesz = size;
+	phdr.p_memsz = size;
+	phdr.p_align = PAGE_SIZE;
+
+	error = buf_write(di, (char*)&phdr, sizeof(phdr));
+	fileofs += phdr.p_filesz;
+	return (error);
+}
+
+/*
+ * Add a header to be used by libkvm to get the va to pa delta
+ */
+static int
+dump_os_header(struct dumperinfo *di)
+{
+	Elf_Phdr phdr;
+	int error;
+
+	bzero(&phdr, sizeof(phdr));
+	phdr.p_type = PT_DUMP_DELTA;
+	phdr.p_flags = PF_R;			/* XXX */
+	phdr.p_offset = 0;
+	phdr.p_vaddr = KERNVIRTADDR;
+	phdr.p_paddr = pmap_kextract(KERNVIRTADDR);
+	phdr.p_filesz = 0;
+	phdr.p_memsz = 0;
+	phdr.p_align = PAGE_SIZE;
+
+	error = buf_write(di, (char*)&phdr, sizeof(phdr));
+	return (error);
+}
+
+static int
+cb_size(struct md_pa *mdp, int seqnr, void *arg)
+{
+	uint32_t *sz = (uint32_t*)arg;
+
+	*sz += (uint32_t)mdp->md_size;
+	return (0);
+}
+
+static int
+foreach_chunk(callback_t cb, void *arg)
+{
+	struct md_pa *mdp;
+	int error, seqnr;
+
+	seqnr = 0;
+	mdp = md_pa_first();
+	while (mdp != NULL) {
+		error = (*cb)(mdp, seqnr++, arg);
+		if (error)
+			return (-error);
+		mdp = md_pa_next(mdp);
+	}
+	return (seqnr);
+}
+
+void
+dumpsys(struct dumperinfo *di)
+{
+	Elf_Ehdr ehdr;
+	uint32_t dumpsize;
+	off_t hdrgap;
+	size_t hdrsz;
+	int error;
+
+	if (do_minidump) {
+		minidumpsys(di);
+		return;
+	}
+
+	bzero(&ehdr, sizeof(ehdr));
+	ehdr.e_ident[EI_MAG0] = ELFMAG0;
+	ehdr.e_ident[EI_MAG1] = ELFMAG1;
+	ehdr.e_ident[EI_MAG2] = ELFMAG2;
+	ehdr.e_ident[EI_MAG3] = ELFMAG3;
+	ehdr.e_ident[EI_CLASS] = ELF_CLASS;
+#if BYTE_ORDER == LITTLE_ENDIAN
+	ehdr.e_ident[EI_DATA] = ELFDATA2LSB;
+#else
+	ehdr.e_ident[EI_DATA] = ELFDATA2MSB;
+#endif
+	ehdr.e_ident[EI_VERSION] = EV_CURRENT;
+	ehdr.e_ident[EI_OSABI] = ELFOSABI_STANDALONE;	/* XXX big picture? */
+	ehdr.e_type = ET_CORE;
+	ehdr.e_machine = EM_ARM;
+	ehdr.e_phoff = sizeof(ehdr);
+	ehdr.e_flags = 0;
+	ehdr.e_ehsize = sizeof(ehdr);
+	ehdr.e_phentsize = sizeof(Elf_Phdr);
+	ehdr.e_shentsize = sizeof(Elf_Shdr);
+
+	md_pa_init();
+
+	/* Calculate dump size. */
+	dumpsize = 0L;
+	ehdr.e_phnum = foreach_chunk(cb_size, &dumpsize) + 1;
+	hdrsz = ehdr.e_phoff + ehdr.e_phnum * ehdr.e_phentsize;
+	fileofs = MD_ALIGN(hdrsz);
+	dumpsize += fileofs;
+	hdrgap = fileofs - DEV_ALIGN(hdrsz);
+
+	/* Determine dump offset on device. */
+	if (di->mediasize < SIZEOF_METADATA + dumpsize + sizeof(kdh) * 2) {
+		error = ENOSPC;
+		goto fail;
+	}
+	dumplo = di->mediaoffset + di->mediasize - dumpsize;
+	dumplo -= sizeof(kdh) * 2;
+
+	mkdumpheader(&kdh, KERNELDUMPMAGIC, KERNELDUMP_ARM_VERSION, dumpsize, di->blocksize);
+
+	printf("Dumping %llu MB (%d chunks)\n", (long long)dumpsize >> 20,
+	    ehdr.e_phnum - 1);
+
+	/* Dump leader */
+	error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh));
+	if (error)
+		goto fail;
+	dumplo += sizeof(kdh);
+
+	/* Dump ELF header */
+	error = buf_write(di, (char*)&ehdr, sizeof(ehdr));
+	if (error)
+		goto fail;
+
+	/* Dump program headers */
+	error = foreach_chunk(cb_dumphdr, di);
+	if (error >= 0)
+		error = dump_os_header(di);
+	if (error < 0)
+		goto fail;
+	buf_flush(di);
+
+	/*
+	 * All headers are written using blocked I/O, so we know the
+	 * current offset is (still) block aligned. Skip the alignement
+	 * in the file to have the segment contents aligned at page
+	 * boundary. We cannot use MD_ALIGN on dumplo, because we don't
+	 * care and may very well be unaligned within the dump device.
+	 */
+	dumplo += hdrgap;
+
+	/* Dump memory chunks (updates dumplo) */
+	error = foreach_chunk(cb_dumpdata, di);
+	if (error < 0)
+		goto fail;
+
+	/* Dump trailer */
+	error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh));
+	if (error)
+		goto fail;
+
+	/* Signal completion, signoff and exit stage left. */
+	dump_write(di, NULL, 0, 0, 0);
+	printf("\nDump complete\n");
+	return;
+
+ fail:
+	if (error < 0)
+		error = -error;
+
+	if (error == ECANCELED)
+		printf("\nDump aborted\n");
+	else if (error == ENOSPC)
+		printf("\nDump failed. Partition too small.\n");
+	else
+		printf("\n** DUMP FAILED (ERROR %d) **\n", error);
+}


Property changes on: trunk/sys/arm/arm/dump_machdep.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/elf_machdep.c
===================================================================
--- trunk/sys/arm/arm/elf_machdep.c	                        (rev 0)
+++ trunk/sys/arm/arm/elf_machdep.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,248 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright 1996-1998 John D. Polstra.
+ * 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 ``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 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: stable/10/sys/arm/arm/elf_machdep.c 294136 2016-01-16 07:56:49Z dchagin $");
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+#include <sys/exec.h>
+#include <sys/imgact.h>
+#include <sys/linker.h>
+#include <sys/sysent.h>
+#include <sys/imgact_elf.h>
+#include <sys/proc.h>
+#include <sys/syscall.h>
+#include <sys/signalvar.h>
+#include <sys/vnode.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/vm_param.h>
+
+#include <machine/elf.h>
+#include <machine/md_var.h>
+
+struct sysentvec elf32_freebsd_sysvec = {
+	.sv_size	= SYS_MAXSYSCALL,
+	.sv_table	= sysent,
+	.sv_mask	= 0,
+	.sv_sigsize	= 0,
+	.sv_sigtbl	= NULL,
+	.sv_errsize	= 0,
+	.sv_errtbl	= NULL,
+	.sv_transtrap	= NULL,
+	.sv_fixup	= __elfN(freebsd_fixup),
+	.sv_sendsig	= sendsig,
+	.sv_sigcode	= sigcode,
+	.sv_szsigcode	= &szsigcode,
+	.sv_prepsyscall	= NULL,
+	.sv_name	= "FreeBSD ELF32",
+	.sv_coredump	= __elfN(coredump),
+	.sv_imgact_try	= NULL,
+	.sv_minsigstksz	= MINSIGSTKSZ,
+	.sv_pagesize	= PAGE_SIZE,
+	.sv_minuser	= VM_MIN_ADDRESS,
+	.sv_maxuser	= VM_MAXUSER_ADDRESS,
+	.sv_usrstack	= USRSTACK,
+	.sv_psstrings	= PS_STRINGS,
+	.sv_stackprot	= VM_PROT_ALL,
+	.sv_copyout_strings = exec_copyout_strings,
+	.sv_setregs	= exec_setregs,
+	.sv_fixlimit	= NULL,
+	.sv_maxssiz	= NULL,
+	.sv_flags	= SV_ABI_FREEBSD | SV_ILP32,
+	.sv_set_syscall_retval = cpu_set_syscall_retval,
+	.sv_fetch_syscall_args = cpu_fetch_syscall_args,
+	.sv_syscallnames = syscallnames,
+	.sv_schedtail	= NULL,
+	.sv_thread_detach = NULL,
+	.sv_trap	= NULL,
+};
+
+static Elf32_Brandinfo freebsd_brand_info = {
+	.brand		= ELFOSABI_FREEBSD,
+	.machine	= EM_ARM,
+	.compat_3_brand	= "FreeBSD",
+	.emul_path	= NULL,
+	.interp_path	= "/libexec/ld-elf.so.1",
+	.sysvec		= &elf32_freebsd_sysvec,
+	.interp_newpath	= NULL,
+	.brand_note	= &elf32_freebsd_brandnote,
+	.flags		= BI_CAN_EXEC_DYN | BI_BRAND_NOTE
+};
+
+SYSINIT(elf32, SI_SUB_EXEC, SI_ORDER_FIRST,
+	(sysinit_cfunc_t) elf32_insert_brand_entry,
+	&freebsd_brand_info);
+
+static Elf32_Brandinfo freebsd_brand_oinfo = {
+	.brand		= ELFOSABI_FREEBSD,
+	.machine	= EM_ARM,
+	.compat_3_brand	= "FreeBSD",
+	.emul_path	= NULL,
+	.interp_path	= "/usr/libexec/ld-elf.so.1",
+	.sysvec		= &elf32_freebsd_sysvec,
+	.interp_newpath	= NULL,
+	.brand_note	= &elf32_freebsd_brandnote,
+	.flags		= BI_CAN_EXEC_DYN | BI_BRAND_NOTE
+};
+
+SYSINIT(oelf32, SI_SUB_EXEC, SI_ORDER_ANY,
+	(sysinit_cfunc_t) elf32_insert_brand_entry,
+	&freebsd_brand_oinfo);
+
+
+void
+elf32_dump_thread(struct thread *td __unused, void *dst __unused,
+    size_t *off __unused)
+{
+}
+
+
+/* Process one elf relocation with addend. */
+static int
+elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data,
+    int type, int local, elf_lookup_fn lookup)
+{
+	Elf_Addr *where;
+	Elf_Addr addr;
+	Elf_Addr addend;
+	Elf_Word rtype, symidx;
+	const Elf_Rel *rel;
+	const Elf_Rela *rela;
+	int error;
+
+	switch (type) {
+	case ELF_RELOC_REL:
+		rel = (const Elf_Rel *)data;
+		where = (Elf_Addr *) (relocbase + rel->r_offset);
+		addend = *where;
+		rtype = ELF_R_TYPE(rel->r_info);
+		symidx = ELF_R_SYM(rel->r_info);
+		break;
+	case ELF_RELOC_RELA:
+		rela = (const Elf_Rela *)data;
+		where = (Elf_Addr *) (relocbase + rela->r_offset);
+		addend = rela->r_addend;
+		rtype = ELF_R_TYPE(rela->r_info);
+		symidx = ELF_R_SYM(rela->r_info);
+		break;
+	default:
+		panic("unknown reloc type %d\n", type);
+	}
+
+	if (local) {
+		if (rtype == R_ARM_RELATIVE) {	/* A + B */
+			addr = elf_relocaddr(lf, relocbase + addend);
+			if (*where != addr)
+				*where = addr;
+		}
+		return (0);
+	}
+
+	switch (rtype) {
+
+		case R_ARM_NONE:	/* none */
+			break;
+
+		case R_ARM_ABS32:
+			error = lookup(lf, symidx, 1, &addr);
+			if (error != 0)
+				return -1;
+			*where += addr;
+			break;
+
+		case R_ARM_COPY:	/* none */
+			/*
+			 * There shouldn't be copy relocations in kernel
+			 * objects.
+			 */
+			printf("kldload: unexpected R_COPY relocation\n");
+			return -1;
+			break;
+
+		case R_ARM_JUMP_SLOT:
+			error = lookup(lf, symidx, 1, &addr);
+			if (error == 0) {
+				*where = addr;
+				return (0);
+			}
+			return (-1);
+		case R_ARM_RELATIVE:
+			break;
+
+		default:
+			printf("kldload: unexpected relocation type %d\n",
+			       rtype);
+			return -1;
+	}
+	return(0);
+}
+
+int
+elf_reloc(linker_file_t lf, Elf_Addr relocbase, const void *data, int type,
+    elf_lookup_fn lookup)
+{
+
+	return (elf_reloc_internal(lf, relocbase, data, type, 0, lookup));
+}
+
+int
+elf_reloc_local(linker_file_t lf, Elf_Addr relocbase, const void *data,
+    int type, elf_lookup_fn lookup)
+{
+
+	return (elf_reloc_internal(lf, relocbase, data, type, 1, lookup));
+}
+
+int
+elf_cpu_load_file(linker_file_t lf __unused)
+{
+
+	/*
+	 * The pmap code does not do an icache sync upon establishing executable
+	 * mappings in the kernel pmap.  It's an optimization based on the fact
+	 * that kernel memory allocations always have EXECUTABLE protection even
+	 * when the memory isn't going to hold executable code.  The only time
+	 * kernel memory holding instructions does need a sync is after loading
+	 * a kernel module, and that's when this function gets called.  Normal
+	 * data cache maintenance has already been done by the IO code, and TLB
+	 * maintenance has been done by the pmap code, so all we have to do here
+	 * is invalidate the instruction cache (which also invalidates the
+	 * branch predictor cache on platforms that have one).
+	 */
+	cpu_icache_sync_all();
+	return (0);
+}
+
+int
+elf_cpu_unload_file(linker_file_t lf __unused)
+{
+
+	return (0);
+}


Property changes on: trunk/sys/arm/arm/elf_machdep.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/elf_trampoline.c
===================================================================
--- trunk/sys/arm/arm/elf_trampoline.c	                        (rev 0)
+++ trunk/sys/arm/arm/elf_trampoline.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,745 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2005 Olivier Houchard.  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 ``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 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.
+ */
+
+/*
+ * Since we are compiled outside of the normal kernel build process, we
+ * need to include opt_global.h manually.
+ */
+#include "opt_global.h"
+#include "opt_kernname.h"
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/elf_trampoline.c 283335 2015-05-23 22:48:54Z ian $");
+#include <machine/asm.h>
+#include <sys/param.h>
+#include <sys/elf32.h>
+#include <sys/inflate.h>
+#include <machine/elf.h>
+#include <machine/pte.h>
+#include <machine/cpufunc.h>
+#include <machine/armreg.h>
+
+extern char kernel_start[];
+extern char kernel_end[];
+
+extern void *_end;
+
+void _start(void);
+void __start(void);
+void __startC(void);
+
+extern unsigned int cpufunc_id(void);
+extern void armv6_idcache_wbinv_all(void);
+extern void armv7_idcache_wbinv_all(void);
+extern void do_call(void *, void *, void *, int);
+
+#define GZ_HEAD	0xa
+
+#if defined(CPU_ARM9)
+#define cpu_idcache_wbinv_all	arm9_idcache_wbinv_all
+extern void arm9_idcache_wbinv_all(void);
+#elif defined(CPU_FA526) || defined(CPU_FA626TE)
+#define cpu_idcache_wbinv_all	fa526_idcache_wbinv_all
+extern void fa526_idcache_wbinv_all(void);
+#elif defined(CPU_ARM9E)
+#define cpu_idcache_wbinv_all	armv5_ec_idcache_wbinv_all
+extern void armv5_ec_idcache_wbinv_all(void);
+#elif defined(CPU_ARM10)
+#define cpu_idcache_wbinv_all	arm10_idcache_wbinv_all
+extern void arm10_idcache_wbinv_all(void);
+#elif defined(CPU_ARM1136) || defined(CPU_ARM1176)
+#define cpu_idcache_wbinv_all	armv6_idcache_wbinv_all
+#elif defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) || \
+  defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) ||	\
+  defined(CPU_XSCALE_80219)
+#define cpu_idcache_wbinv_all	xscale_cache_purgeID
+extern void xscale_cache_purgeID(void);
+#elif defined(CPU_XSCALE_81342)
+#define cpu_idcache_wbinv_all	xscalec3_cache_purgeID
+extern void xscalec3_cache_purgeID(void);
+#elif defined(CPU_MV_PJ4B)
+#if !defined(SOC_MV_ARMADAXP)
+#define cpu_idcache_wbinv_all	armv6_idcache_wbinv_all
+extern void armv6_idcache_wbinv_all(void);
+#else
+#define cpu_idcache_wbinv_all()	armadaxp_idcache_wbinv_all
+#endif
+#endif /* CPU_MV_PJ4B */
+#ifdef CPU_XSCALE_81342
+#define cpu_l2cache_wbinv_all	xscalec3_l2cache_purge
+extern void xscalec3_l2cache_purge(void);
+#elif defined(SOC_MV_KIRKWOOD) || defined(SOC_MV_DISCOVERY)
+#define cpu_l2cache_wbinv_all	sheeva_l2cache_wbinv_all
+extern void sheeva_l2cache_wbinv_all(void);
+#elif defined(CPU_CORTEXA) || defined(CPU_KRAIT)
+#define cpu_idcache_wbinv_all	armv7_idcache_wbinv_all
+#define cpu_l2cache_wbinv_all()
+#else
+#define cpu_l2cache_wbinv_all()	
+#endif
+
+static void armadaxp_idcache_wbinv_all(void);
+
+int     arm_picache_size;
+int     arm_picache_line_size;
+int     arm_picache_ways;
+
+int     arm_pdcache_size;       /* and unified */
+int     arm_pdcache_line_size = 32;
+int     arm_pdcache_ways;
+
+int     arm_pcache_type;
+int     arm_pcache_unified;
+
+int     arm_dcache_align;
+int     arm_dcache_align_mask;
+
+int     arm_dcache_min_line_size = 32;
+int     arm_icache_min_line_size = 32;
+int     arm_idcache_min_line_size = 32;
+
+u_int	arm_cache_level;
+u_int	arm_cache_type[14];
+u_int	arm_cache_loc;
+
+/* Additional cache information local to this file.  Log2 of some of the
+      above numbers.  */
+static int      arm_dcache_l2_nsets;
+static int      arm_dcache_l2_assoc;
+static int      arm_dcache_l2_linesize;
+
+
+int block_userspace_access = 0;
+extern int arm9_dcache_sets_inc;
+extern int arm9_dcache_sets_max;
+extern int arm9_dcache_index_max;
+extern int arm9_dcache_index_inc;
+
+static __inline void *
+memcpy(void *dst, const void *src, int len)
+{
+	const char *s = src;
+    	char *d = dst;
+
+	while (len) {
+		if (0 && len >= 4 && !((vm_offset_t)d & 3) &&
+		    !((vm_offset_t)s & 3)) {
+			*(uint32_t *)d = *(uint32_t *)s;
+			s += 4;
+			d += 4;
+			len -= 4;
+		} else {
+			*d++ = *s++;
+			len--;
+		}
+	}
+	return (dst);
+}
+
+static __inline void
+bzero(void *addr, int count)
+{
+	char *tmp = (char *)addr;
+
+	while (count > 0) {
+		if (count >= 4 && !((vm_offset_t)tmp & 3)) {
+			*(uint32_t *)tmp = 0;
+			tmp += 4;
+			count -= 4;
+		} else {
+			*tmp = 0;
+			tmp++;
+			count--;
+		}
+	}
+}
+
+static void arm9_setup(void);
+
+void
+_startC(void)
+{
+	int tmp1;
+	unsigned int sp = ((unsigned int)&_end & ~3) + 4;
+	unsigned int pc, kernphysaddr;
+
+	/*
+	 * Figure out the physical address the kernel was loaded at.  This
+	 * assumes the entry point (this code right here) is in the first page,
+	 * which will always be the case for this trampoline code.
+	 */
+	__asm __volatile("mov %0, pc\n"
+	    : "=r" (pc));
+	kernphysaddr = pc & ~PAGE_MASK;
+
+#if defined(FLASHADDR) && defined(PHYSADDR) && defined(LOADERRAMADDR)
+	if ((FLASHADDR > LOADERRAMADDR && pc >= FLASHADDR) ||
+	    (FLASHADDR < LOADERRAMADDR && pc < LOADERRAMADDR)) {
+		/*
+		 * We're running from flash, so just copy the whole thing
+		 * from flash to memory.
+		 * This is far from optimal, we could do the relocation or
+		 * the unzipping directly from flash to memory to avoid this
+		 * needless copy, but it would require to know the flash
+		 * physical address.
+		 */
+		unsigned int target_addr;
+		unsigned int tmp_sp;
+		uint32_t src_addr = (uint32_t)&_start - PHYSADDR + FLASHADDR
+		    + (pc - FLASHADDR - ((uint32_t)&_startC - PHYSADDR)) & 0xfffff000;
+
+		target_addr = (unsigned int)&_start - PHYSADDR + LOADERRAMADDR;
+		tmp_sp = target_addr + 0x100000 +
+		    (unsigned int)&_end - (unsigned int)&_start;
+		memcpy((char *)target_addr, (char *)src_addr,
+		    (unsigned int)&_end - (unsigned int)&_start);
+		/* Temporary set the sp and jump to the new location. */
+		__asm __volatile(
+		    "mov sp, %1\n"
+		    "mov pc, %0\n"
+		    : : "r" (target_addr), "r" (tmp_sp));
+		
+	}
+#endif
+#ifdef KZIP
+	sp += KERNSIZE + 0x100;
+	sp &= ~(L1_TABLE_SIZE - 1);
+	sp += 2 * L1_TABLE_SIZE;
+#endif
+	sp += 1024 * 1024; /* Should be enough for a stack */
+	
+	__asm __volatile("adr %0, 2f\n"
+	    		 "bic %0, %0, #0xff000000\n"
+			 "and %1, %1, #0xff000000\n"
+			 "orr %0, %0, %1\n"
+			 "mrc p15, 0, %1, c1, c0, 0\n"
+			 "bic %1, %1, #1\n" /* Disable MMU */
+			 "orr %1, %1, #(4 | 8)\n" /* Add DC enable,
+						     WBUF enable */
+			 "orr %1, %1, #0x1000\n" /* Add IC enable */
+			 "orr %1, %1, #(0x800)\n" /* BPRD enable */
+
+			 "mcr p15, 0, %1, c1, c0, 0\n"
+			 "nop\n"
+			 "nop\n"
+			 "nop\n"
+			 "mov pc, %0\n"
+			 "2: nop\n"
+			 "mov sp, %2\n"
+			 : "=r" (tmp1), "+r" (kernphysaddr), "+r" (sp));
+#ifndef KZIP
+#ifdef CPU_ARM9
+	/* So that idcache_wbinv works; */
+	if ((cpufunc_id() & 0x0000f000) == 0x00009000)
+		arm9_setup();
+#endif
+#endif
+	__start();
+}
+
+static void
+get_cachetype_cp15()
+{
+	u_int ctype, isize, dsize, cpuid;
+	u_int clevel, csize, i, sel;
+	u_int multiplier;
+	u_char type;
+
+	__asm __volatile("mrc p15, 0, %0, c0, c0, 1"
+		: "=r" (ctype));
+
+	cpuid = cpufunc_id();
+	/*
+	 * ...and thus spake the ARM ARM:
+	 *
+	 * If an <opcode2> value corresponding to an unimplemented or
+	 * reserved ID register is encountered, the System Control
+	 * processor returns the value of the main ID register.
+	 */
+	if (ctype == cpuid)
+		goto out;
+
+	if (CPU_CT_FORMAT(ctype) == CPU_CT_ARMV7) {
+		/* Resolve minimal cache line sizes */
+		arm_dcache_min_line_size = 1 << (CPU_CT_DMINLINE(ctype) + 2);
+		arm_icache_min_line_size = 1 << (CPU_CT_IMINLINE(ctype) + 2);
+		arm_idcache_min_line_size =
+		    (arm_dcache_min_line_size > arm_icache_min_line_size ?
+		    arm_icache_min_line_size : arm_dcache_min_line_size);
+
+		__asm __volatile("mrc p15, 1, %0, c0, c0, 1"
+		    : "=r" (clevel));
+		arm_cache_level = clevel;
+		arm_cache_loc = CPU_CLIDR_LOC(arm_cache_level) + 1;
+		i = 0;
+		while ((type = (clevel & 0x7)) && i < 7) {
+			if (type == CACHE_DCACHE || type == CACHE_UNI_CACHE ||
+			    type == CACHE_SEP_CACHE) {
+				sel = i << 1;
+				__asm __volatile("mcr p15, 2, %0, c0, c0, 0"
+				    : : "r" (sel));
+				__asm __volatile("mrc p15, 1, %0, c0, c0, 0"
+				    : "=r" (csize));
+				arm_cache_type[sel] = csize;
+			}
+			if (type == CACHE_ICACHE || type == CACHE_SEP_CACHE) {
+				sel = (i << 1) | 1;
+				__asm __volatile("mcr p15, 2, %0, c0, c0, 0"
+				    : : "r" (sel));
+				__asm __volatile("mrc p15, 1, %0, c0, c0, 0"
+				    : "=r" (csize));
+				arm_cache_type[sel] = csize;
+			}
+			i++;
+			clevel >>= 3;
+		}
+	} else {
+		if ((ctype & CPU_CT_S) == 0)
+			arm_pcache_unified = 1;
+
+		/*
+		 * If you want to know how this code works, go read the ARM ARM.
+		 */
+
+		arm_pcache_type = CPU_CT_CTYPE(ctype);
+
+		if (arm_pcache_unified == 0) {
+			isize = CPU_CT_ISIZE(ctype);
+			multiplier = (isize & CPU_CT_xSIZE_M) ? 3 : 2;
+			arm_picache_line_size = 1U << (CPU_CT_xSIZE_LEN(isize) + 3);
+			if (CPU_CT_xSIZE_ASSOC(isize) == 0) {
+				if (isize & CPU_CT_xSIZE_M)
+					arm_picache_line_size = 0; /* not present */
+				else
+					arm_picache_ways = 1;
+			} else {
+				arm_picache_ways = multiplier <<
+				    (CPU_CT_xSIZE_ASSOC(isize) - 1);
+			}
+			arm_picache_size = multiplier << (CPU_CT_xSIZE_SIZE(isize) + 8);
+		}
+
+		dsize = CPU_CT_DSIZE(ctype);
+		multiplier = (dsize & CPU_CT_xSIZE_M) ? 3 : 2;
+		arm_pdcache_line_size = 1U << (CPU_CT_xSIZE_LEN(dsize) + 3);
+		if (CPU_CT_xSIZE_ASSOC(dsize) == 0) {
+			if (dsize & CPU_CT_xSIZE_M)
+				arm_pdcache_line_size = 0; /* not present */
+			else
+				arm_pdcache_ways = 1;
+		} else {
+			arm_pdcache_ways = multiplier <<
+			    (CPU_CT_xSIZE_ASSOC(dsize) - 1);
+		}
+		arm_pdcache_size = multiplier << (CPU_CT_xSIZE_SIZE(dsize) + 8);
+
+		arm_dcache_align = arm_pdcache_line_size;
+
+		arm_dcache_l2_assoc = CPU_CT_xSIZE_ASSOC(dsize) + multiplier - 2;
+		arm_dcache_l2_linesize = CPU_CT_xSIZE_LEN(dsize) + 3;
+		arm_dcache_l2_nsets = 6 + CPU_CT_xSIZE_SIZE(dsize) -
+		    CPU_CT_xSIZE_ASSOC(dsize) - CPU_CT_xSIZE_LEN(dsize);
+
+	out:
+		arm_dcache_align_mask = arm_dcache_align - 1;
+	}
+}
+
+static void
+arm9_setup(void)
+{
+	
+	get_cachetype_cp15();
+	arm9_dcache_sets_inc = 1U << arm_dcache_l2_linesize;
+	arm9_dcache_sets_max = (1U << (arm_dcache_l2_linesize +
+	    arm_dcache_l2_nsets)) - arm9_dcache_sets_inc;
+	arm9_dcache_index_inc = 1U << (32 - arm_dcache_l2_assoc);
+	arm9_dcache_index_max = 0U - arm9_dcache_index_inc;
+}
+
+static void
+armadaxp_idcache_wbinv_all(void)
+{
+	uint32_t feat;
+
+	__asm __volatile("mrc p15, 0, %0, c0, c1, 0" : "=r" (feat));
+	if (feat & ARM_PFR0_THUMBEE_MASK)
+		armv7_idcache_wbinv_all();
+	else
+		armv6_idcache_wbinv_all();
+
+}
+#ifdef KZIP
+static  unsigned char *orig_input, *i_input, *i_output;
+
+
+static u_int memcnt;		/* Memory allocated: blocks */
+static size_t memtot;		/* Memory allocated: bytes */
+/*
+ * Library functions required by inflate().
+ */
+
+#define MEMSIZ 0x8000
+
+/*
+ * Allocate memory block.
+ */
+unsigned char *
+kzipmalloc(int size)
+{
+	void *ptr;
+	static u_char mem[MEMSIZ];
+
+	if (memtot + size > MEMSIZ)
+		return NULL;
+	ptr = mem + memtot;
+	memtot += size;
+	memcnt++;
+	return ptr;
+}
+
+/*
+ * Free allocated memory block.
+ */
+void
+kzipfree(void *ptr)
+{
+	memcnt--;
+	if (!memcnt)
+		memtot = 0;
+}
+
+void
+putstr(char *dummy)
+{
+}
+
+static int
+input(void *dummy)
+{
+	if ((size_t)(i_input - orig_input) >= KERNCOMPSIZE) {
+		return (GZ_EOF);
+	}
+	return *i_input++;
+}
+
+static int
+output(void *dummy, unsigned char *ptr, unsigned long len)
+{
+
+
+	memcpy(i_output, ptr, len);
+	i_output += len;
+	return (0);
+}
+
+static void *
+inflate_kernel(void *kernel, void *startaddr)
+{
+	struct inflate infl;
+	unsigned char slide[GZ_WSIZE];
+
+	orig_input = kernel;
+	memcnt = memtot = 0;
+	i_input = (unsigned char *)kernel + GZ_HEAD;
+	if (((char *)kernel)[3] & 0x18) {
+		while (*i_input)
+			i_input++;
+		i_input++;
+	}
+	i_output = startaddr;
+	bzero(&infl, sizeof(infl));
+	infl.gz_input = input;
+	infl.gz_output = output;
+	infl.gz_slide = slide;
+	inflate(&infl);
+	return ((char *)(((vm_offset_t)i_output & ~3) + 4));
+}
+
+#endif
+
+void *
+load_kernel(unsigned int kstart, unsigned int curaddr,unsigned int func_end,
+    int d)
+{
+	Elf32_Ehdr *eh;
+	Elf32_Phdr phdr[64] /* XXX */, *php;
+	Elf32_Shdr shdr[64] /* XXX */;
+	int i,j;
+	void *entry_point;
+	int symtabindex = -1;
+	int symstrindex = -1;
+	vm_offset_t lastaddr = 0;
+	Elf_Addr ssym = 0;
+	Elf_Dyn *dp;
+	
+	eh = (Elf32_Ehdr *)kstart;
+	ssym = 0;
+	entry_point = (void*)eh->e_entry;
+	memcpy(phdr, (void *)(kstart + eh->e_phoff ),
+	    eh->e_phnum * sizeof(phdr[0]));
+
+	/* Determine lastaddr. */
+	for (i = 0; i < eh->e_phnum; i++) {
+		if (lastaddr < (phdr[i].p_vaddr - KERNVIRTADDR + curaddr
+		    + phdr[i].p_memsz))
+			lastaddr = phdr[i].p_vaddr - KERNVIRTADDR +
+			    curaddr + phdr[i].p_memsz;
+	}
+	
+	/* Save the symbol tables, as there're about to be scratched. */
+	memcpy(shdr, (void *)(kstart + eh->e_shoff),
+	    sizeof(*shdr) * eh->e_shnum);
+	if (eh->e_shnum * eh->e_shentsize != 0 &&
+	    eh->e_shoff != 0) {
+		for (i = 0; i < eh->e_shnum; i++) {
+			if (shdr[i].sh_type == SHT_SYMTAB) {
+				for (j = 0; j < eh->e_phnum; j++) {
+					if (phdr[j].p_type == PT_LOAD &&
+					    shdr[i].sh_offset >=
+					    phdr[j].p_offset &&
+					    (shdr[i].sh_offset +
+					     shdr[i].sh_size <=
+					     phdr[j].p_offset +
+					     phdr[j].p_filesz)) {
+						shdr[i].sh_offset = 0;
+						shdr[i].sh_size = 0;
+						j = eh->e_phnum;
+					}
+				}
+				if (shdr[i].sh_offset != 0 &&
+				    shdr[i].sh_size != 0) {
+					symtabindex = i;
+					symstrindex = shdr[i].sh_link;
+				}
+			}
+		}
+		func_end = roundup(func_end, sizeof(long));
+		if (symtabindex >= 0 && symstrindex >= 0) {
+			ssym = lastaddr;
+			if (d) {
+				memcpy((void *)func_end, (void *)(
+				    shdr[symtabindex].sh_offset + kstart),
+				    shdr[symtabindex].sh_size);
+				memcpy((void *)(func_end +
+				    shdr[symtabindex].sh_size),
+				    (void *)(shdr[symstrindex].sh_offset +
+				    kstart), shdr[symstrindex].sh_size);
+			} else {
+				lastaddr += shdr[symtabindex].sh_size;
+				lastaddr = roundup(lastaddr,
+				    sizeof(shdr[symtabindex].sh_size));
+				lastaddr += sizeof(shdr[symstrindex].sh_size);
+				lastaddr += shdr[symstrindex].sh_size;
+				lastaddr = roundup(lastaddr,
+				    sizeof(shdr[symstrindex].sh_size));
+			}
+			
+		}
+	}
+	if (!d)
+		return ((void *)lastaddr);
+	
+	j = eh->e_phnum;
+	for (i = 0; i < j; i++) {
+		volatile char c;
+
+		if (phdr[i].p_type != PT_LOAD)
+			continue;
+		memcpy((void *)(phdr[i].p_vaddr - KERNVIRTADDR + curaddr),
+		    (void*)(kstart + phdr[i].p_offset), phdr[i].p_filesz);
+		/* Clean space from oversized segments, eg: bss. */
+		if (phdr[i].p_filesz < phdr[i].p_memsz)
+			bzero((void *)(phdr[i].p_vaddr - KERNVIRTADDR +
+			    curaddr + phdr[i].p_filesz), phdr[i].p_memsz -
+			    phdr[i].p_filesz);
+	}
+	/* Now grab the symbol tables. */
+	if (symtabindex >= 0 && symstrindex >= 0) {
+		*(Elf_Size *)lastaddr =
+		    shdr[symtabindex].sh_size;
+		lastaddr += sizeof(shdr[symtabindex].sh_size);
+		memcpy((void*)lastaddr,
+		    (void *)func_end,
+		    shdr[symtabindex].sh_size);
+		lastaddr += shdr[symtabindex].sh_size;
+		lastaddr = roundup(lastaddr,
+		    sizeof(shdr[symtabindex].sh_size));
+		*(Elf_Size *)lastaddr =
+		    shdr[symstrindex].sh_size;
+		lastaddr += sizeof(shdr[symstrindex].sh_size);
+		memcpy((void*)lastaddr,
+		    (void*)(func_end +
+			    shdr[symtabindex].sh_size),
+		    shdr[symstrindex].sh_size);
+		lastaddr += shdr[symstrindex].sh_size;
+		lastaddr = roundup(lastaddr,
+   		    sizeof(shdr[symstrindex].sh_size));
+		*(Elf_Addr *)curaddr = MAGIC_TRAMP_NUMBER;
+		*((Elf_Addr *)curaddr + 1) = ssym - curaddr + KERNVIRTADDR;
+		*((Elf_Addr *)curaddr + 2) = lastaddr - curaddr + KERNVIRTADDR;
+	} else
+		*(Elf_Addr *)curaddr = 0;
+	/* Invalidate the instruction cache. */
+	__asm __volatile("mcr p15, 0, %0, c7, c5, 0\n"
+	    		 "mcr p15, 0, %0, c7, c10, 4\n"
+			 : : "r" (curaddr));
+	__asm __volatile("mrc p15, 0, %0, c1, c0, 0\n"
+	    "bic %0, %0, #1\n" /* MMU_ENABLE */
+	    "mcr p15, 0, %0, c1, c0, 0\n"
+	    : "=r" (ssym));
+	/* Jump to the entry point. */
+	((void(*)(void))(entry_point - KERNVIRTADDR + curaddr))();
+	__asm __volatile(".globl func_end\n"
+	    "func_end:");
+	
+	/* NOTREACHED */
+	return NULL;
+}
+
+extern char func_end[];
+
+
+#define PMAP_DOMAIN_KERNEL	0 /*
+				    * Just define it instead of including the
+				    * whole VM headers set.
+				    */
+int __hack;
+static __inline void
+setup_pagetables(unsigned int pt_addr, vm_paddr_t physstart, vm_paddr_t physend,
+    int write_back)
+{
+	unsigned int *pd = (unsigned int *)pt_addr;
+	vm_paddr_t addr;
+	int domain = (DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL * 2)) | DOMAIN_CLIENT;
+	int tmp;
+
+	bzero(pd, L1_TABLE_SIZE);
+	for (addr = physstart; addr < physend; addr += L1_S_SIZE) {
+		pd[addr >> L1_S_SHIFT] = L1_TYPE_S|L1_S_C|L1_S_AP(AP_KRW)|
+		    L1_S_DOM(PMAP_DOMAIN_KERNEL) | addr;
+		if (write_back && 0)
+			pd[addr >> L1_S_SHIFT] |= L1_S_B;
+	}
+	/* XXX: See below */
+	if (0xfff00000 < physstart || 0xfff00000 > physend)
+		pd[0xfff00000 >> L1_S_SHIFT] = L1_TYPE_S|L1_S_AP(AP_KRW)|
+		    L1_S_DOM(PMAP_DOMAIN_KERNEL)|physstart;
+	__asm __volatile("mcr p15, 0, %1, c2, c0, 0\n" /* set TTB */
+	    		 "mcr p15, 0, %1, c8, c7, 0\n" /* Flush TTB */
+			 "mcr p15, 0, %2, c3, c0, 0\n" /* Set DAR */
+			 "mrc p15, 0, %0, c1, c0, 0\n"
+			 "orr %0, %0, #1\n" /* MMU_ENABLE */
+			 "mcr p15, 0, %0, c1, c0, 0\n"
+			 "mrc p15, 0, %0, c2, c0, 0\n" /* CPWAIT */
+			 "mov r0, r0\n"
+			 "sub pc, pc, #4\n" :
+			 "=r" (tmp) : "r" (pd), "r" (domain));
+	
+	/*
+	 * XXX: This is the most stupid workaround I've ever wrote.
+	 * For some reason, the KB9202 won't boot the kernel unless
+	 * we access an address which is not in the
+	 * 0x20000000 - 0x20ffffff range. I hope I'll understand
+	 * what's going on later.
+	 */
+	__hack = *(volatile int *)0xfffff21c;
+}
+
+void
+__start(void)
+{
+	void *curaddr;
+	void *dst, *altdst;
+	char *kernel = (char *)&kernel_start;
+	int sp;
+	int pt_addr;
+
+	__asm __volatile("mov %0, pc"  :
+	    "=r" (curaddr));
+	curaddr = (void*)((unsigned int)curaddr & 0xfff00000);
+#ifdef KZIP
+	if (*kernel == 0x1f && kernel[1] == 0x8b) {
+		pt_addr = (((int)&_end + KERNSIZE + 0x100) &
+		    ~(L1_TABLE_SIZE - 1)) + L1_TABLE_SIZE;
+		
+#ifdef CPU_ARM9
+		/* So that idcache_wbinv works; */
+		if ((cpufunc_id() & 0x0000f000) == 0x00009000)
+			arm9_setup();
+#endif
+		setup_pagetables(pt_addr, (vm_paddr_t)curaddr,
+		    (vm_paddr_t)curaddr + 0x10000000, 1);
+		/* Gzipped kernel */
+		dst = inflate_kernel(kernel, &_end);
+		kernel = (char *)&_end;
+		altdst = 4 + load_kernel((unsigned int)kernel,
+		    (unsigned int)curaddr,
+		    (unsigned int)&func_end + 800 , 0);
+		if (altdst > dst)
+			dst = altdst;
+
+		/*
+		 * Disable MMU.  Otherwise, setup_pagetables call below
+		 * might overwrite the L1 table we are currently using.
+		 */
+		cpu_idcache_wbinv_all();
+		cpu_l2cache_wbinv_all();
+		__asm __volatile("mrc p15, 0, %0, c1, c0, 0\n"
+		  "bic %0, %0, #1\n" /* MMU_DISABLE */
+		  "mcr p15, 0, %0, c1, c0, 0\n"
+		  :"=r" (pt_addr));
+	} else
+#endif
+		dst = 4 + load_kernel((unsigned int)&kernel_start,
+	    (unsigned int)curaddr,
+	    (unsigned int)&func_end, 0);
+	dst = (void *)(((vm_offset_t)dst & ~3));
+	pt_addr = ((unsigned int)dst &~(L1_TABLE_SIZE - 1)) + L1_TABLE_SIZE;
+	setup_pagetables(pt_addr, (vm_paddr_t)curaddr,
+	    (vm_paddr_t)curaddr + 0x10000000, 0);	
+	sp = pt_addr + L1_TABLE_SIZE + 8192;
+	sp = sp &~3;
+	dst = (void *)(sp + 4);
+	memcpy((void *)dst, (void *)&load_kernel, (unsigned int)&func_end -
+	    (unsigned int)&load_kernel + 800);
+	do_call(dst, kernel, dst + (unsigned int)(&func_end) -
+	    (unsigned int)(&load_kernel) + 800, sp);
+}
+
+#ifdef __ARM_EABI__
+/* We need to provide these functions but never call them */
+void __aeabi_unwind_cpp_pr0(void);
+void __aeabi_unwind_cpp_pr1(void);
+void __aeabi_unwind_cpp_pr2(void);
+
+__strong_reference(__aeabi_unwind_cpp_pr0, __aeabi_unwind_cpp_pr1);
+__strong_reference(__aeabi_unwind_cpp_pr0, __aeabi_unwind_cpp_pr2);
+void
+__aeabi_unwind_cpp_pr0(void)
+{
+}
+#endif
+


Property changes on: trunk/sys/arm/arm/elf_trampoline.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/exception.S
===================================================================
--- trunk/sys/arm/arm/exception.S	                        (rev 0)
+++ trunk/sys/arm/arm/exception.S	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,466 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: exception.S,v 1.13 2003/10/31 16:30:15 scw Exp $	*/
+
+/*-
+ * Copyright (c) 1994-1997 Mark Brinicombe.
+ * Copyright (c) 1994 Brini.
+ * All rights reserved.
+ *
+ * This code is derived from software written for Brini by Mark Brinicombe
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Brini.
+ * 4. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BRINI ``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 BRINI 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.
+ *
+ * RiscBSD kernel project
+ *
+ * exception.S
+ *
+ * Low level handlers for exception vectors
+ *
+ * Created      : 24/09/94
+ *
+ * Based on kate/display/abort.s
+ *
+ */
+
+#include "assym.s"
+
+#include <machine/asm.h>
+#include <machine/armreg.h>
+#include <machine/asmacros.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/exception.S 278652 2015-02-13 00:49:47Z ian $");
+
+	.text	
+	.align	2
+
+/*
+ * ASM macros for pushing and pulling trapframes from the stack
+ *
+ * These macros are used to handle the irqframe and trapframe structures
+ * defined above.
+ */
+
+/*
+ * PUSHFRAME - macro to push a trap frame on the stack in the current mode
+ * Since the current mode is used, the SVC lr field is not defined.
+ *
+ * NOTE: r13 and r14 are stored separately as a work around for the
+ * SA110 rev 2 STM^ bug
+ */
+#ifdef ARM_TP_ADDRESS
+#define PUSHFRAME							   \
+	sub	sp, sp, #4;		/* Align the stack */		   \
+	str	lr, [sp, #-4]!;		/* Push the return address */	   \
+	sub	sp, sp, #(4*17);	/* Adjust the stack pointer */	   \
+	stmia	sp, {r0-r12};		/* Push the user mode registers */ \
+	add	r0, sp, #(4*13);	/* Adjust the stack pointer */	   \
+	stmia	r0, {r13-r14}^;		/* Push the user mode registers */ \
+	mov	r0, r0;			/* NOP for previous instruction */ \
+	mrs	r0, spsr;		/* Put the SPSR on the stack */	   \
+	str	r0, [sp, #-4]!;						   \
+	ldr	r0, =ARM_RAS_START;					   \
+	mov	r1, #0;							   \
+	str	r1, [r0];						   \
+	mov	r1, #0xffffffff;					   \
+	str	r1, [r0, #4];
+#else
+#define PUSHFRAME							   \
+	sub	sp, sp, #4;		/* Align the stack */		   \
+	str	lr, [sp, #-4]!;		/* Push the return address */	   \
+	sub	sp, sp, #(4*17);	/* Adjust the stack pointer */	   \
+	stmia	sp, {r0-r12};		/* Push the user mode registers */ \
+	add	r0, sp, #(4*13);	/* Adjust the stack pointer */	   \
+	stmia	r0, {r13-r14}^;		/* Push the user mode registers */ \
+	mov	r0, r0;			/* NOP for previous instruction */ \
+	mrs	r0, spsr;		/* Put the SPSR on the stack */	   \
+	str	r0, [sp, #-4]!;
+#endif
+
+/*
+ * PULLFRAME - macro to pull a trap frame from the stack in the current mode
+ * Since the current mode is used, the SVC lr field is ignored.
+ */
+
+#ifdef ARM_TP_ADDRESS
+#define PULLFRAME							   \
+	ldr	r0, [sp], #4;		/* Get the SPSR from stack */	   \
+	msr	spsr_fsxc, r0;						   \
+	ldmia	sp, {r0-r14}^;		/* Restore registers (usr mode) */ \
+	mov	r0, r0;			/* NOP for previous instruction */ \
+	add	sp, sp, #(4*17);	/* Adjust the stack pointer */	   \
+ 	ldr	lr, [sp], #4;		/* Pull the return address */	   \
+	add	sp, sp, #4		/* Align the stack */
+#else 
+#define PULLFRAME							   \
+	ldr	r0, [sp], #4	;	/* Get the SPSR from stack */	   \
+	msr	spsr_fsxc, r0;						   \
+	clrex;								   \
+	ldmia   sp, {r0-r14}^;		/* Restore registers (usr mode) */ \
+	mov	r0, r0;			/* NOP for previous instruction */ \
+	add	sp, sp, #(4*17);	/* Adjust the stack pointer */	   \
+ 	ldr	lr, [sp], #4;		/* Pull the return address */	   \
+	add	sp, sp, #4		/* Align the stack */
+#endif
+
+/*
+ * PUSHFRAMEINSVC - macro to push a trap frame on the stack in SVC32 mode
+ * This should only be used if the processor is not currently in SVC32
+ * mode. The processor mode is switched to SVC mode and the trap frame is
+ * stored. The SVC lr field is used to store the previous value of
+ * lr in SVC mode.
+ *
+ * NOTE: r13 and r14 are stored separately as a work around for the
+ * SA110 rev 2 STM^ bug
+ */
+#ifdef ARM_TP_ADDRESS
+#define PUSHFRAMEINSVC							   \
+	stmdb	sp, {r0-r3};		/* Save 4 registers */		   \
+	mov	r0, lr;			/* Save xxx32 r14 */		   \
+	mov	r1, sp;			/* Save xxx32 sp */		   \
+	mrs	r3, spsr;		/* Save xxx32 spsr */		   \
+	mrs	r2, cpsr; 		/* Get the CPSR */		   \
+	bic	r2, r2, #(PSR_MODE);	/* Fix for SVC mode */		   \
+	orr	r2, r2, #(PSR_SVC32_MODE);				   \
+	msr	cpsr_c, r2;		/* Punch into SVC mode */	   \
+	mov	r2, sp;			/* Save	SVC sp */		   \
+	bic	sp, sp, #7;		/* Align sp to an 8-byte addrress */  \
+	sub	sp, sp, #4;		/* Pad trapframe to keep alignment */ \
+	str	r0, [sp, #-4]!;		/* Push return address */	   \
+	str	lr, [sp, #-4]!;		/* Push SVC lr */		   \
+	str	r2, [sp, #-4]!;		/* Push SVC sp */		   \
+	msr	spsr_fsxc, r3;		/* Restore correct spsr */	   \
+	ldmdb	r1, {r0-r3};		/* Restore 4 regs from xxx mode */ \
+	sub	sp, sp, #(4*15);	/* Adjust the stack pointer */	   \
+	stmia	sp, {r0-r12};		/* Push the user mode registers */ \
+	add	r0, sp, #(4*13);	/* Adjust the stack pointer */	   \
+	stmia	r0, {r13-r14}^;		/* Push the user mode registers */ \
+	mov	r0, r0;			/* NOP for previous instruction */ \
+	ldr	r5, =ARM_RAS_START;	/* Check if there's any RAS */	   \
+	ldr	r4, [r5, #4];		/* reset it to point at the     */ \
+	cmp	r4, #0xffffffff;	/* end of memory if necessary;  */ \
+	movne	r1, #0xffffffff;	/* leave value in r4 for later  */ \
+	strne	r1, [r5, #4];		/* comparision against PC.      */ \
+	ldr	r3, [r5];		/* Retrieve global RAS_START    */ \
+	cmp	r3, #0;			/* and reset it if non-zero.    */ \
+	movne	r1, #0;			/* If non-zero RAS_START and    */ \
+	strne	r1, [r5];		/* PC was lower than RAS_END,   */ \
+	ldrne	r1, [r0, #16];		/* adjust the saved PC so that  */ \
+	cmpne	r4, r1;			/* execution later resumes at   */ \
+	strhi	r3, [r0, #16];		/* the RAS_START location.      */ \
+	mrs	r0, spsr;						   \
+	str	r0, [sp, #-4]!
+#else
+#define PUSHFRAMEINSVC							   \
+	stmdb	sp, {r0-r3};		/* Save 4 registers */		   \
+	mov	r0, lr;			/* Save xxx32 r14 */		   \
+	mov	r1, sp;			/* Save xxx32 sp */		   \
+	mrs	r3, spsr;		/* Save xxx32 spsr */		   \
+	mrs	r2, cpsr;		/* Get the CPSR */		   \
+	bic	r2, r2, #(PSR_MODE);	/* Fix for SVC mode */		   \
+	orr	r2, r2, #(PSR_SVC32_MODE);				   \
+	msr	cpsr_c, r2;		/* Punch into SVC mode */	   \
+	mov	r2, sp;			/* Save	SVC sp */		   \
+	bic	sp, sp, #7;		/* Align sp to an 8-byte addrress */  \
+	sub	sp, sp, #4;		/* Pad trapframe to keep alignment */ \
+	str	r0, [sp, #-4]!;		/* Push return address */	   \
+	str	lr, [sp, #-4]!;		/* Push SVC lr */		   \
+	str	r2, [sp, #-4]!;		/* Push SVC sp */		   \
+	msr	spsr_fsxc, r3;		/* Restore correct spsr */	   \
+	ldmdb	r1, {r0-r3};		/* Restore 4 regs from xxx mode */ \
+	sub	sp, sp, #(4*15);	/* Adjust the stack pointer */	   \
+	stmia	sp, {r0-r12};		/* Push the user mode registers */ \
+	add	r0, sp, #(4*13);	/* Adjust the stack pointer */	   \
+	stmia	r0, {r13-r14}^;		/* Push the user mode registers */ \
+	mov	r0, r0;			/* NOP for previous instruction */ \
+	mrs	r0, spsr;		/* Put the SPSR on the stack */	   \
+	str	r0, [sp, #-4]!
+#endif
+
+/*
+ * PULLFRAMEFROMSVCANDEXIT - macro to pull a trap frame from the stack
+ * in SVC32 mode and restore the saved processor mode and PC.
+ * This should be used when the SVC lr register needs to be restored on
+ * exit.
+ */
+
+#ifdef ARM_TP_ADDRESS
+#define PULLFRAMEFROMSVCANDEXIT						   \
+	ldr	r0, [sp], #4;		/* Get the SPSR from stack */	   \
+	msr	spsr_fsxc, r0;		/* restore SPSR */		   \
+	ldmia	sp, {r0-r14}^;		/* Restore registers (usr mode) */ \
+	mov	r0, r0;	  		/* NOP for previous instruction */ \
+	add	sp, sp, #(4*15);	/* Adjust the stack pointer */	   \
+	ldmia	sp, {sp, lr, pc}^	/* Restore lr and exit */
+#else 
+#define PULLFRAMEFROMSVCANDEXIT						   \
+	ldr	r0, [sp], #4;		/* Get the SPSR from stack */	   \
+	msr	spsr_fsxc, r0;		/* restore SPSR */		   \
+	clrex;								   \
+	ldmia	sp, {r0-r14}^;		/* Restore registers (usr mode) */ \
+	mov	r0, r0;	  		/* NOP for previous instruction */ \
+	add	sp, sp, #(4*15);	/* Adjust the stack pointer */	   \
+	ldmia	sp, {sp, lr, pc}^	/* Restore lr and exit */
+#endif
+
+#if defined(__ARM_EABI__)
+/*
+ * Unwind hints so we can unwind past functions that use
+ * PULLFRAMEFROMSVCANDEXIT. They are run in reverse order.
+ * As the last thing we do is restore the stack pointer
+ * we can ignore the padding at the end of struct trapframe.
+ */
+#define	UNWINDSVCFRAME							   \
+	.save {r13-r15};		/* Restore sp, lr, pc */	   \
+	.pad #(2*4);			/* Skip user sp and lr */	   \
+	.save {r0-r12};			/* Restore r0-r12 */		   \
+	.pad #(4)			/* Skip spsr */
+#else
+#define	UNWINDSVCFRAME
+#endif
+
+#define	DO_AST								   \
+	ldr	r0, [sp];		/* Get the SPSR from stack */	   \
+	mrs	r4, cpsr;		/* save CPSR */			   \
+	orr	r1, r4, #(PSR_I|PSR_F);					   \
+	msr	cpsr_c, r1;		/* Disable interrupts */	   \
+	and	r0, r0, #(PSR_MODE);	/* Returning to USR mode? */	   \
+	teq	r0, #(PSR_USR32_MODE);					   \
+	bne	2f;			/* Nope, get out now */		   \
+	bic	r4, r4, #(PSR_I|PSR_F);					   \
+1:	GET_CURTHREAD_PTR(r5);						   \
+	ldr	r1, [r5, #(TD_FLAGS)];					   \
+	and	r1, r1, #(TDF_ASTPENDING|TDF_NEEDRESCHED);		   \
+	teq	r1, #0;							   \
+	beq	2f;			/* Nope. Just bail */		   \
+	msr	cpsr_c, r4;		/* Restore interrupts */	   \
+	mov	r0, sp;							   \
+	bl	_C_LABEL(ast);		/* ast(frame) */		   \
+	orr	r0, r4, #(PSR_I|PSR_F);					   \
+	msr	cpsr_c, r0;						   \
+	b	1b;							   \
+2:
+
+
+/*
+ * Entry point for a Software Interrupt (SWI).
+ *
+ * The hardware switches to svc32 mode on a swi, so we're already on the
+ * right stack; just build a trapframe and call the handler.
+ */
+ASENTRY_NP(swi_entry)
+	PUSHFRAME			/* Build the trapframe on the */
+	mov	r0, sp			/* scv32 stack, pass it to the */
+	bl	_C_LABEL(swi_handler)	/* swi handler. */
+	/*
+	 * The fork_trampoline() code in swtch.S aranges for the MI fork_exit()
+	 * to return to swi_exit here, to return to userland.  The net effect is
+	 * that a newly created thread appears to return from a SWI just like
+	 * the parent thread that created it.
+	 */
+ASEENTRY_NP(swi_exit)
+	DO_AST				/* Handle pending signals. */
+	PULLFRAME			/* Deallocate trapframe. */
+	movs	pc, lr			/* Return to userland. */
+	STOP_UNWINDING			/* Don't unwind into user mode. */
+EEND(swi_exit)
+END(swi_entry)
+
+/*
+ * Standard exception exit handler.
+ *
+ * This is used to return from all exceptions except SWI.  It uses DO_AST and
+ * PULLFRAMEFROMSVCANDEXIT and can only be called if the exception entry code
+ * used PUSHFRAMEINSVC.
+ *
+ * If the return is to user mode, this uses DO_AST to deliver any pending
+ * signals and/or handle TDF_NEEDRESCHED first.
+ */
+ASENTRY_NP(exception_exit)
+	DO_AST				/* Handle pending signals. */
+	PULLFRAMEFROMSVCANDEXIT		/* Return. */
+	UNWINDSVCFRAME			/* Special unwinding for exceptions. */
+END(exception_exit)
+
+/*
+ * Entry point for a Prefetch Abort exception.
+ *
+ * The hardware switches to the abort mode stack; we switch to svc32 before
+ * calling the handler, then return directly to the original mode/stack 
+ * on exit (without transitioning back through the abort mode stack).
+ */
+ASENTRY_NP(prefetch_abort_entry)
+#ifdef __XSCALE__
+	nop				/* Make absolutely sure any pending */
+	nop				/* imprecise aborts have occurred. */
+#endif
+	sub	lr, lr, #4		/* Adjust the lr. Transition to scv32 */
+	PUSHFRAMEINSVC			/* mode stack, build trapframe there. */
+	adr	lr, exception_exit	/* Return from handler via standard */
+	mov	r0, sp			/* exception exit routine.  Pass the */
+	mov	r1, #1			/* Type flag */
+	b	_C_LABEL(abort_handler)
+END(prefetch_abort_entry)
+
+/*
+ * Entry point for a Data Abort exception.
+ *
+ * The hardware switches to the abort mode stack; we switch to svc32 before
+ * calling the handler, then return directly to the original mode/stack 
+ * on exit (without transitioning back through the abort mode stack).
+ */
+ASENTRY_NP(data_abort_entry)
+#ifdef __XSCALE__
+	nop				/* Make absolutely sure any pending */
+	nop				/* imprecise aborts have occurred. */
+#endif
+	sub	lr, lr, #8		/* Adjust the lr. Transition to scv32 */
+	PUSHFRAMEINSVC			/* mode stack, build trapframe there. */
+	adr	lr, exception_exit	/* Exception exit routine */
+	mov	r0, sp			/* Trapframe to the handler */
+	mov	r1, #0			/* Type flag */
+	b	_C_LABEL(abort_handler)
+END(data_abort_entry)
+
+/*
+ * Entry point for an Undefined Instruction exception.
+ *
+ * The hardware switches to the undefined mode stack; we switch to svc32 before
+ * calling the handler, then return directly to the original mode/stack 
+ * on exit (without transitioning back through the undefined mode stack).
+ */
+ASENTRY_NP(undefined_entry)
+	sub	lr, lr, #4		/* Adjust the lr. Transition to scv32 */
+	PUSHFRAMEINSVC			/* mode stack, build trapframe there. */
+	adr	lr, exception_exit      /* Return from handler via standard */
+	mov	r0, sp			/* exception exit routine.  Pass the */
+	b	undefinedinstruction	/* trapframe to the handler. */
+END(undefined_entry)
+
+/*
+ * Entry point for a normal IRQ.
+ *
+ * The hardware switches to the IRQ mode stack; we switch to svc32 before
+ * calling the handler, then return directly to the original mode/stack 
+ * on exit (without transitioning back through the IRQ mode stack).
+ */
+ASENTRY_NP(irq_entry)
+	sub	lr, lr, #4		/* Adjust the lr. Transition to scv32 */
+	PUSHFRAMEINSVC			/* mode stack, build trapframe there. */
+	adr	lr, exception_exit	/* Return from handler via standard */
+	mov	r0, sp			/* exception exit routine.  Pass the */
+	b	_C_LABEL(arm_irq_handler)/* trapframe to the handler. */
+END(irq_entry)                           
+
+/*
+ * Entry point for an FIQ interrupt.
+ *
+ * We don't currently support FIQ handlers very much.  Something can 
+ * install itself in the FIQ vector using code (that may or may not work
+ * these days) in fiq.c.  If nobody does that and an FIQ happens, this
+ * default handler just disables FIQs and otherwise ignores it.
+ */
+ASENTRY_NP(fiq_entry)
+	mrs	r8, cpsr		/* FIQ handling isn't supported, */
+	bic	r8, #(PSR_F)		/* just disable FIQ and return.  */
+	msr	cpsr_c, r8		/* The r8 we trash here is the  */
+	subs	pc, lr, #4		/* banked FIQ-mode r8. */
+END(fiq_entry)
+
+/*
+ * Entry point for an Address Exception exception.
+ * This is an arm26 exception that should never happen.
+ */
+ASENTRY_NP(addr_exception_entry)
+	mov	r3, lr
+	mrs	r2, spsr
+	mrs	r1, cpsr
+	adr	r0, Laddr_exception_msg
+	b	_C_LABEL(panic)
+Laddr_exception_msg:
+	.asciz	"Address Exception CPSR=0x%08x SPSR=0x%08x LR=0x%08x\n"
+	.balign	4
+END(addr_exception_entry)
+
+/*
+ * Entry point for the system Reset vector.  
+ * This should never happen, so panic.
+ */
+ASENTRY_NP(reset_entry)
+	mov	r1, lr
+	adr	r0, Lreset_panicmsg
+	b	_C_LABEL(panic)
+	/* NOTREACHED */
+Lreset_panicmsg:
+	.asciz	"Reset vector called, LR = 0x%08x"
+	.balign	4
+END(reset_entry)
+
+/*
+ * page0 and page0_data -- An image of the ARM vectors which is copied to
+ * the ARM vectors page (high or low) as part of CPU initialization.  The
+ * code that does the copy assumes that page0_data holds one 32-bit word
+ * of data for each of the predefined ARM vectors.  It also assumes that
+ * page0_data follows the vectors in page0, but other stuff can appear 
+ * between the two.  We currently leave room between the two for some fiq 
+ * handler code to be copied in.
+ */
+	.global	_C_LABEL(page0), _C_LABEL(page0_data)
+
+_C_LABEL(page0):
+	ldr	pc, .Lreset_entry
+	ldr	pc, .Lundefined_entry
+	ldr	pc, .Lswi_entry
+	ldr	pc, .Lprefetch_abort_entry
+	ldr	pc, .Ldata_abort_entry
+	ldr	pc, .Laddr_exception_entry
+	ldr	pc, .Lirq_entry
+.fiqv:	ldr	pc, .Lfiq_entry
+	.space 256	/* room for some fiq handler code */
+
+_C_LABEL(page0_data):
+.Lreset_entry:		.word	reset_entry
+.Lundefined_entry:	.word	undefined_entry
+.Lswi_entry:		.word	swi_entry
+.Lprefetch_abort_entry:	.word	prefetch_abort_entry
+.Ldata_abort_entry:	.word	data_abort_entry
+.Laddr_exception_entry:	.word	addr_exception_entry
+.Lirq_entry:		.word	irq_entry
+.Lfiq_entry:		.word	fiq_entry
+
+/*
+ * These items are used by the code in fiq.c to install what it calls the
+ * "null" handler.  It's actually our default vector entry that just jumps
+ * to the default handler which just disables FIQs and returns.
+ */
+	.global _C_LABEL(fiq_nullhandler_code), _C_LABEL(fiq_nullhandler_size)
+
+_C_LABEL(fiq_nullhandler_code):
+	.word	.fiqv
+_C_LABEL(fiq_nullhandler_size):
+	.word	4
+
+


Property changes on: trunk/sys/arm/arm/exception.S
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/fiq.c
===================================================================
--- trunk/sys/arm/arm/fiq.c	                        (rev 0)
+++ trunk/sys/arm/arm/fiq.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,173 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: fiq.c,v 1.5 2002/04/03 23:33:27 thorpej Exp $	*/
+
+/*-
+ * Copyright (c) 2001, 2002 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Jason R. Thorpe for Wasabi Systems, Inc.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed for the NetBSD Project by
+ *	Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
+ * 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: stable/10/sys/arm/arm/fiq.c 278613 2015-02-12 03:50:33Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+
+#include <machine/armreg.h>
+#include <machine/cpufunc.h>
+#include <machine/fiq.h>
+#include <vm/vm.h>
+#include <machine/pcb.h>
+#include <vm/pmap.h>
+#include <machine/cpu.h>
+
+TAILQ_HEAD(, fiqhandler) fiqhandler_stack =
+    TAILQ_HEAD_INITIALIZER(fiqhandler_stack);
+
+extern char *fiq_nullhandler_code;
+extern uint32_t fiq_nullhandler_size;
+
+/*
+ * fiq_installhandler:
+ *
+ *	Actually install the FIQ handler down at the FIQ vector.
+ *	
+ *	The FIQ vector is fixed by the hardware definition as the
+ *	seventh 32-bit word in the vector page.
+ *
+ *	Note: If the FIQ is invoked via an extra layer of
+ *	indirection, the actual FIQ code store lives in the
+ *	data segment, so there is no need to manipulate
+ *	the vector page's protection.
+ */
+static void
+fiq_installhandler(void *func, size_t size)
+{
+	const uint32_t fiqvector = 7 * sizeof(uint32_t);
+
+#if !defined(__ARM_FIQ_INDIRECT)
+	vector_page_setprot(VM_PROT_READ|VM_PROT_WRITE);
+#endif
+
+	memcpy((void *)(vector_page + fiqvector), func, size);
+
+#if !defined(__ARM_FIQ_INDIRECT)
+	vector_page_setprot(VM_PROT_READ);
+	cpu_icache_sync_range((vm_offset_t) fiqvector, size);
+#endif
+}
+
+/*
+ * fiq_claim:
+ *
+ *	Claim the FIQ vector.
+ */
+int
+fiq_claim(struct fiqhandler *fh)
+{
+	struct fiqhandler *ofh;
+	u_int oldirqstate;
+	int error = 0;
+
+	if (fh->fh_size > 0x100)
+		return (EFBIG);
+
+	oldirqstate = disable_interrupts(PSR_F);
+
+	if ((ofh = TAILQ_FIRST(&fiqhandler_stack)) != NULL) {
+		if ((ofh->fh_flags & FH_CANPUSH) == 0) {
+			error = EBUSY;
+			goto out;
+		}
+
+		/* Save the previous FIQ handler's registers. */
+		if (ofh->fh_regs != NULL)
+			fiq_getregs(ofh->fh_regs);
+	}
+
+	/* Set FIQ mode registers to ours. */
+	if (fh->fh_regs != NULL)
+		fiq_setregs(fh->fh_regs);
+
+	TAILQ_INSERT_HEAD(&fiqhandler_stack, fh, fh_list);
+
+	/* Now copy the actual handler into place. */
+	fiq_installhandler(fh->fh_func, fh->fh_size);
+
+	/* Make sure FIQs are enabled when we return. */
+	oldirqstate &= ~PSR_F;
+
+ out:
+	restore_interrupts(oldirqstate);
+	return (error);
+}
+
+/*
+ * fiq_release:
+ *
+ *	Release the FIQ vector.
+ */
+void
+fiq_release(struct fiqhandler *fh)
+{
+	u_int oldirqstate;
+	struct fiqhandler *ofh;
+
+	oldirqstate = disable_interrupts(PSR_F);
+
+	/*
+	 * If we are the currently active FIQ handler, then we
+	 * need to save our registers and pop the next one back
+	 * into the vector.
+	 */
+	if (fh == TAILQ_FIRST(&fiqhandler_stack)) {
+		if (fh->fh_regs != NULL)
+			fiq_getregs(fh->fh_regs);
+		TAILQ_REMOVE(&fiqhandler_stack, fh, fh_list);
+		if ((ofh = TAILQ_FIRST(&fiqhandler_stack)) != NULL) {
+			if (ofh->fh_regs != NULL)
+				fiq_setregs(ofh->fh_regs);
+			fiq_installhandler(ofh->fh_func, ofh->fh_size);
+		}
+	} else
+		TAILQ_REMOVE(&fiqhandler_stack, fh, fh_list);
+
+	if (TAILQ_FIRST(&fiqhandler_stack) == NULL) {
+		/* Copy the NULL handler back down into the vector. */
+		fiq_installhandler(fiq_nullhandler_code, fiq_nullhandler_size);
+
+		/* Make sure FIQs are disabled when we return. */
+		oldirqstate |= PSR_F;
+	}
+
+	restore_interrupts(oldirqstate);
+}


Property changes on: trunk/sys/arm/arm/fiq.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/fiq_subr.S
===================================================================
--- trunk/sys/arm/arm/fiq_subr.S	                        (rev 0)
+++ trunk/sys/arm/arm/fiq_subr.S	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,94 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: fiq_subr.S,v 1.3 2002/04/12 18:50:31 thorpej Exp $	*/
+
+/*-
+ * Copyright (c) 2001 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Jason R. Thorpe for Wasabi Systems, Inc.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed for the NetBSD Project by
+ *	Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
+ * 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 <machine/armreg.h>
+#include <machine/asm.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/fiq_subr.S 266311 2014-05-17 13:53:38Z ian $");
+
+/*
+ * MODE_CHANGE_NOP should be inserted between a mode change and a
+ * banked register (R8--R15) access.
+ */
+#if defined(CPU_ARM2) || defined(CPU_ARM250)
+#define	MODE_CHANGE_NOP	mov	r0, r0
+#else
+#define	MODE_CHANGE_NOP	/* Data sheet says ARM3 doesn't need it */
+#endif
+
+#define	SWITCH_TO_FIQ_MODE						\
+	mrs	r2, cpsr					;	\
+	mov	r3, r2						;	\
+	bic	r2, r2, #(PSR_MODE)				;	\
+	orr	r2, r2, #(PSR_FIQ32_MODE)			;	\
+	msr	cpsr_fsxc, r2
+
+#define	BACK_TO_SVC_MODE						\
+	msr	cpsr_fsxc, r3
+
+/*
+ * fiq_getregs:
+ *
+ *	Fetch the FIQ mode banked registers into the fiqhandler
+ *	structure.
+ */
+ENTRY(fiq_getregs)
+	SWITCH_TO_FIQ_MODE
+
+	stmia	r0, {r8-r13}
+
+	BACK_TO_SVC_MODE
+	RET
+END(fiq_getregs)
+
+/*
+ * fiq_setregs:
+ *
+ *	Load the FIQ mode banked registers from the fiqhandler
+ *	structure.
+ */
+ENTRY(fiq_setregs)
+	SWITCH_TO_FIQ_MODE
+
+	ldmia	r0, {r8-r13}
+
+	BACK_TO_SVC_MODE
+	RET
+END(fiq_setregs)
+


Property changes on: trunk/sys/arm/arm/fiq_subr.S
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/fusu.S
===================================================================
--- trunk/sys/arm/arm/fusu.S	                        (rev 0)
+++ trunk/sys/arm/arm/fusu.S	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,395 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: fusu.S,v 1.10 2003/12/01 13:34:44 rearnsha Exp $	*/
+
+/*-
+ * Copyright (c) 1996-1998 Mark Brinicombe.
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Mark Brinicombe
+ * 4. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 <machine/asm.h>
+#include <machine/armreg.h>
+#include "assym.s"
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/fusu.S 294686 2016-01-24 22:05:21Z ian $");
+
+	.syntax	unified
+
+#ifdef _ARM_ARCH_6
+#define GET_PCB(tmp) \
+	mrc p15, 0, tmp, c13, c0, 4; \
+	add	tmp, tmp, #(TD_PCB)
+#else
+.Lcurpcb:
+	.word	_C_LABEL(__pcpu) + PC_CURPCB
+#define GET_PCB(tmp) \
+	ldr	tmp, .Lcurpcb
+#endif
+
+/*
+ * fuword(caddr_t uaddr);
+ * Fetch an int from the user's address space.
+ */
+
+ENTRY(casuword)
+EENTRY_NP(casuword32)
+	GET_PCB(r3)
+	ldr	r3, [r3]
+
+#ifdef DIAGNOSTIC
+	teq	r3, #0x00000000
+	beq	.Lfusupcbfault
+#endif
+	stmfd	sp!, {r4, r5}
+	adr	r4, .Lcasuwordfault
+	str	r4, [r3, #PCB_ONFAULT]
+#ifdef _ARM_ARCH_6
+1:    
+	cmp     r0, #KERNBASE
+	mvnhs   r0, #0
+	bhs     2f
+	
+	ldrex   r5, [r0]
+	cmp     r5, r1
+	movne   r0, r5
+	bne     2f
+	strex   r5, r2, [r0]
+	cmp     r5, #0
+	bne     1b
+#else
+	ldrt	r5, [r0]
+	cmp	r5, r1
+	movne	r0, r5
+	strteq	r2, [r0]
+#endif
+	moveq	r0, r1
+2:
+	ldmfd	sp!, {r4, r5}
+	mov	r1, #0x00000000
+	str	r1, [r3, #PCB_ONFAULT]
+	RET
+EEND(casuword32)
+END(casuword)
+
+/*
+ * Handle faults from casuword.  Clean up and return -1.
+ */
+
+.Lcasuwordfault:
+	mov	r0, #0x00000000
+	str	r0, [r3, #PCB_ONFAULT]
+	mvn	r0, #0x00000000
+	ldmfd	sp!, {r4, r5}
+	RET	
+
+/*
+ * fuword(caddr_t uaddr);
+ * Fetch an int from the user's address space.
+ */
+
+ENTRY(fuword)
+EENTRY_NP(fuword32)
+	GET_PCB(r2)
+	ldr	r2, [r2]
+
+#ifdef DIAGNOSTIC
+	teq	r2, #0x00000000
+	beq	.Lfusupcbfault
+#endif
+
+	adr	r1, .Lfusufault
+	str	r1, [r2, #PCB_ONFAULT]
+
+	ldrt	r3, [r0]
+
+	mov	r1, #0x00000000
+	str	r1, [r2, #PCB_ONFAULT]
+	mov	r0, r3
+	RET
+EEND(fueword32)
+END(fueword)
+
+/*
+ * fusword(caddr_t uaddr);
+ * Fetch a short from the user's address space.
+ */
+
+ENTRY(fusword)
+	GET_PCB(r2)
+	ldr	r2, [r2]
+
+#ifdef DIAGNOSTIC
+	teq	r2, #0x00000000
+	beq	.Lfusupcbfault
+#endif
+
+	adr	r1, .Lfusufault
+	str	r1, [r2, #PCB_ONFAULT]
+
+	ldrbt	r3, [r0], #1
+	ldrbt	ip, [r0]
+#ifdef __ARMEB__
+	orr	r0, ip, r3, asl #8
+#else
+	orr	r0, r3, ip, asl #8
+#endif
+	mov	r1, #0x00000000
+	str	r1, [r2, #PCB_ONFAULT]
+	RET
+END(fusword)
+
+/*
+ * fuswintr(caddr_t uaddr);
+ * Fetch a short from the user's address space.  Can be called during an
+ * interrupt.
+ */
+
+ENTRY(fuswintr)
+	ldr	r2, Lblock_userspace_access
+	ldr	r2, [r2]
+	teq	r2, #0
+	mvnne	r0, #0x00000000
+	RETne
+
+	GET_PCB(r2)
+	ldr	r2, [r2]
+
+#ifdef DIAGNOSTIC
+	teq	r2, #0x00000000
+	beq	.Lfusupcbfault
+#endif
+
+	adr	r1, _C_LABEL(fusubailout)
+	str	r1, [r2, #PCB_ONFAULT]
+
+	ldrbt	r3, [r0], #1
+	ldrbt	ip, [r0]
+#ifdef __ARMEB__
+	orr	r0, ip, r3, asl #8
+#else
+	orr	r0, r3, ip, asl #8
+#endif
+
+	mov	r1, #0x00000000
+	str	r1, [r2, #PCB_ONFAULT]
+	RET
+END(fuswintr)
+
+Lblock_userspace_access:
+	.word	_C_LABEL(block_userspace_access)
+
+	.data
+	.align	2
+	.global	_C_LABEL(block_userspace_access)
+_C_LABEL(block_userspace_access):
+	.word	0
+	.text
+
+/*
+ * fubyte(caddr_t uaddr);
+ * Fetch a byte from the user's address space.
+ */
+
+ENTRY(fubyte)
+	GET_PCB(r2)
+	ldr	r2, [r2]
+
+#ifdef DIAGNOSTIC
+	teq	r2, #0x00000000
+	beq	.Lfusupcbfault
+#endif
+
+	adr	r1, .Lfusufault
+	str	r1, [r2, #PCB_ONFAULT]
+
+	ldrbt	r3, [r0]
+
+	mov	r1, #0x00000000
+	str	r1, [r2, #PCB_ONFAULT]
+	mov	r0, r3
+	RET
+END(fubyte)
+
+/*
+ * Handle faults from [fs]u*().  Clean up and return -1.
+ */
+
+.Lfusufault:
+	mov	r0, #0x00000000
+	str	r0, [r2, #PCB_ONFAULT]
+	mvn	r0, #0x00000000
+	RET
+
+/*
+ * Handle faults from [fs]u*().  Clean up and return -1.  This differs from
+ * fusufault() in that trap() will recognise it and return immediately rather
+ * than trying to page fault.
+ */
+
+/* label must be global as fault.c references it */
+	.global	_C_LABEL(fusubailout)
+_C_LABEL(fusubailout):
+	mov	r0, #0x00000000
+	str	r0, [r2, #PCB_ONFAULT]
+	mvn	r0, #0x00000000
+	RET
+
+#ifdef DIAGNOSTIC
+/*
+ * Handle earlier faults from [fs]u*(), due to no pcb
+ */
+
+.Lfusupcbfault:
+	mov	r1, r0
+	adr	r0, fusupcbfaulttext
+	b	_C_LABEL(panic)
+
+fusupcbfaulttext:
+	.asciz	"Yikes - no valid PCB during fusuxxx() addr=%08x\n"
+	.align	2
+#endif
+
+/*
+ * suword(caddr_t uaddr, int x);
+ * Store an int in the user's address space.
+ */
+
+ENTRY(suword)
+EENTRY_NP(suword32)
+	GET_PCB(r2)
+	ldr	r2, [r2]
+
+#ifdef DIAGNOSTIC
+	teq	r2, #0x00000000
+	beq	.Lfusupcbfault
+#endif
+
+	adr	r3, .Lfusufault
+	str	r3, [r2, #PCB_ONFAULT]
+
+	strt	r1, [r0]
+
+	mov	r0, #0x00000000
+	str	r0, [r2, #PCB_ONFAULT]
+	RET
+EEND(suword32)
+END(suword)
+
+/*
+ * suswintr(caddr_t uaddr, short x);
+ * Store a short in the user's address space.  Can be called during an
+ * interrupt.
+ */
+
+ENTRY(suswintr)
+	ldr	r2, Lblock_userspace_access
+	ldr	r2, [r2]
+	teq	r2, #0
+	mvnne	r0, #0x00000000
+	RETne
+
+	GET_PCB(r2)
+	ldr	r2, [r2]
+
+#ifdef DIAGNOSTIC
+	teq	r2, #0x00000000
+	beq	.Lfusupcbfault
+#endif
+
+	adr	r3, _C_LABEL(fusubailout)
+	str	r3, [r2, #PCB_ONFAULT]
+
+#ifdef __ARMEB__
+	mov	ip, r1, lsr #8
+	strbt	ip, [r0], #1
+#else
+	strbt	r1, [r0], #1
+	mov	r1, r1, lsr #8
+#endif
+	strbt	r1, [r0]
+
+	mov	r0, #0x00000000
+	str	r0, [r2, #PCB_ONFAULT]
+	RET
+END(suswintr)
+
+/*
+ * susword(caddr_t uaddr, short x);
+ * Store a short in the user's address space.
+ */
+
+ENTRY(susword)
+	GET_PCB(r2)
+	ldr	r2, [r2]
+
+#ifdef DIAGNOSTIC
+	teq	r2, #0x00000000
+	beq	.Lfusupcbfault
+#endif
+
+	adr	r3, .Lfusufault
+	str	r3, [r2, #PCB_ONFAULT]
+
+#ifdef __ARMEB__
+	mov	ip, r1, lsr #8
+	strbt	ip, [r0], #1
+#else
+	strbt	r1, [r0], #1
+	mov	r1, r1, lsr #8
+#endif
+	strbt	r1, [r0]
+
+	mov	r0, #0x00000000
+	str	r0, [r2, #PCB_ONFAULT]
+	RET
+END(susword)
+
+/*
+ * subyte(caddr_t uaddr, char x);
+ * Store a byte in the user's address space.
+ */
+
+ENTRY(subyte)
+	GET_PCB(r2)
+	ldr	r2, [r2]
+
+
+#ifdef DIAGNOSTIC
+	teq	r2, #0x00000000
+	beq	.Lfusupcbfault
+#endif
+
+	adr	r3, .Lfusufault
+	str	r3, [r2, #PCB_ONFAULT]
+
+	strbt	r1, [r0]
+	mov	r0, #0x00000000
+	str	r0, [r2, #PCB_ONFAULT]
+	RET
+END(subyte)


Property changes on: trunk/sys/arm/arm/fusu.S
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/gdb_machdep.c
===================================================================
--- trunk/sys/arm/arm/gdb_machdep.c	                        (rev 0)
+++ trunk/sys/arm/arm/gdb_machdep.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,116 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2006 Olivier Houchard
+ * 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 AUTHORS ``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 AUTHORS 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: stable/10/sys/arm/arm/gdb_machdep.c 278614 2015-02-12 04:15:55Z ian $");
+
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kdb.h>
+#include <sys/kernel.h>
+#include <sys/proc.h>
+#include <sys/signal.h>
+
+#include <machine/gdb_machdep.h>
+#include <machine/db_machdep.h>
+#include <machine/vmparam.h>
+#include <machine/pcb.h>
+#include <machine/trap.h>
+#include <machine/frame.h>
+#include <machine/endian.h>
+
+#include <gdb/gdb.h>
+
+static register_t stacktest;
+
+void *
+gdb_cpu_getreg(int regnum, size_t *regsz)
+{
+
+	*regsz = gdb_cpu_regsz(regnum);
+
+	if (kdb_thread == curthread) {
+		if (regnum < 13)
+			return (&kdb_frame->tf_r0 + regnum);
+		if (regnum == 13)
+			return (&kdb_frame->tf_svc_sp);
+		if (regnum == 14)
+			return (&kdb_frame->tf_svc_lr);
+		if (regnum == 15)
+			return (&kdb_frame->tf_pc);
+		if (regnum == 25)
+			return (&kdb_frame->tf_spsr);
+	}
+
+	switch (regnum) {
+	case 4:  return (&kdb_thrctx->pcb_regs.sf_r4);
+	case 5:  return (&kdb_thrctx->pcb_regs.sf_r5);
+	case 6:  return (&kdb_thrctx->pcb_regs.sf_r6);
+	case 7:  return (&kdb_thrctx->pcb_regs.sf_r7);
+	case 8:  return (&kdb_thrctx->pcb_regs.sf_r8);
+	case 9:  return (&kdb_thrctx->pcb_regs.sf_r9);
+	case 10:  return (&kdb_thrctx->pcb_regs.sf_r10);
+	case 11:  return (&kdb_thrctx->pcb_regs.sf_r11);
+	case 12:  return (&kdb_thrctx->pcb_regs.sf_r12);
+	case 13:  stacktest = kdb_thrctx->pcb_regs.sf_sp + 5 * 4;
+		  return (&stacktest);
+	case 15:
+		  /*
+		   * On context switch, the PC is not put in the PCB, but
+		   * we can retrieve it from the stack.
+		   */
+		  if (kdb_thrctx->pcb_regs.sf_sp > KERNBASE) {
+			  kdb_thrctx->pcb_regs.sf_pc = *(register_t *)
+			      (kdb_thrctx->pcb_regs.sf_sp + 4 * 4);
+			  return (&kdb_thrctx->pcb_regs.sf_pc);
+		  }
+	}
+
+	return (NULL);
+}
+
+void
+gdb_cpu_setreg(int regnum, void *val)
+{
+
+	switch (regnum) {
+	case GDB_REG_PC:
+		if (kdb_thread  == curthread)
+			kdb_frame->tf_pc = *(register_t *)val;
+	}
+}
+
+int
+gdb_cpu_signal(int type, int code)
+{
+
+	switch (type) {
+	case T_BREAKPOINT: return (SIGTRAP);
+	}
+	return (SIGEMT);
+}


Property changes on: trunk/sys/arm/arm/gdb_machdep.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/genassym.c
===================================================================
--- trunk/sys/arm/arm/genassym.c	                        (rev 0)
+++ trunk/sys/arm/arm/genassym.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,155 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2004 Olivier Houchard
+ * 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: stable/10/sys/arm/arm/genassym.c 283336 2015-05-23 23:05:31Z ian $");
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/assym.h>
+#include <sys/proc.h>
+#include <sys/mbuf.h>
+#include <sys/vmmeter.h>
+#include <sys/bus.h>
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+#include <vm/pmap.h>
+#include <vm/vm_map.h>
+#include <machine/vmparam.h>
+#include <machine/armreg.h>
+#include <machine/frame.h>
+#include <machine/pcb.h>
+#include <machine/cpu.h>
+#include <machine/proc.h>
+#include <machine/cpufunc.h>
+#include <machine/cpuinfo.h>
+#include <machine/pte.h>
+#include <machine/intr.h>
+#include <machine/sysarch.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip6.h>
+#include <netinet/ip_var.h>
+
+ASSYM(KERNBASE, KERNBASE);
+ASSYM(PCB_NOALIGNFLT, PCB_NOALIGNFLT);
+ASSYM(PCB_ONFAULT, offsetof(struct pcb, pcb_onfault));
+ASSYM(PCB_DACR, offsetof(struct pcb, pcb_dacr));
+ASSYM(PCB_FLAGS, offsetof(struct pcb, pcb_flags));
+ASSYM(PCB_PAGEDIR, offsetof(struct pcb, pcb_pagedir));
+ASSYM(PCB_L1VEC, offsetof(struct pcb, pcb_l1vec));
+ASSYM(PCB_PL1VEC, offsetof(struct pcb, pcb_pl1vec));
+ASSYM(PCB_R4, offsetof(struct pcb, pcb_regs.sf_r4));
+ASSYM(PCB_R5, offsetof(struct pcb, pcb_regs.sf_r5));
+ASSYM(PCB_R6, offsetof(struct pcb, pcb_regs.sf_r6));
+ASSYM(PCB_R7, offsetof(struct pcb, pcb_regs.sf_r7));
+ASSYM(PCB_R8, offsetof(struct pcb, pcb_regs.sf_r8));
+ASSYM(PCB_R9, offsetof(struct pcb, pcb_regs.sf_r9));
+ASSYM(PCB_R10, offsetof(struct pcb, pcb_regs.sf_r10));
+ASSYM(PCB_R11, offsetof(struct pcb, pcb_regs.sf_r11));
+ASSYM(PCB_R12, offsetof(struct pcb, pcb_regs.sf_r12));
+ASSYM(PCB_SP, offsetof(struct pcb, pcb_regs.sf_sp));
+ASSYM(PCB_LR, offsetof(struct pcb, pcb_regs.sf_lr));
+ASSYM(PCB_PC, offsetof(struct pcb, pcb_regs.sf_pc));
+
+ASSYM(PC_CURPCB, offsetof(struct pcpu, pc_curpcb));
+ASSYM(PC_CURTHREAD, offsetof(struct pcpu, pc_curthread));
+ASSYM(M_LEN, offsetof(struct mbuf, m_len));
+ASSYM(M_DATA, offsetof(struct mbuf, m_data));
+ASSYM(M_NEXT, offsetof(struct mbuf, m_next));
+ASSYM(IP_SRC, offsetof(struct ip, ip_src));
+ASSYM(IP_DST, offsetof(struct ip, ip_dst));
+ASSYM(CF_SETTTB, offsetof(struct cpu_functions, cf_setttb));
+ASSYM(CF_CONTROL, offsetof(struct cpu_functions, cf_control));
+ASSYM(CF_CONTEXT_SWITCH, offsetof(struct cpu_functions, cf_context_switch));
+ASSYM(CF_DCACHE_WB_RANGE, offsetof(struct cpu_functions, cf_dcache_wb_range));
+ASSYM(CF_L2CACHE_WB_RANGE, offsetof(struct cpu_functions, cf_l2cache_wb_range));
+ASSYM(CF_IDCACHE_WBINV_ALL, offsetof(struct cpu_functions, cf_idcache_wbinv_all));
+ASSYM(CF_L2CACHE_WBINV_ALL, offsetof(struct cpu_functions, cf_l2cache_wbinv_all));
+ASSYM(CF_TLB_FLUSHID_SE, offsetof(struct cpu_functions, cf_tlb_flushID_SE));
+ASSYM(CF_ICACHE_SYNC, offsetof(struct cpu_functions, cf_icache_sync_all));
+
+ASSYM(V_TRAP, offsetof(struct vmmeter, v_trap));
+ASSYM(V_SOFT, offsetof(struct vmmeter, v_soft));
+ASSYM(V_INTR, offsetof(struct vmmeter, v_intr));
+
+ASSYM(TD_PCB, offsetof(struct thread, td_pcb));
+ASSYM(TD_FLAGS, offsetof(struct thread, td_flags));
+ASSYM(TD_PROC, offsetof(struct thread, td_proc));
+ASSYM(TD_FRAME, offsetof(struct thread, td_frame));
+ASSYM(TD_MD, offsetof(struct thread, td_md));
+ASSYM(TD_LOCK, offsetof(struct thread, td_lock));
+ASSYM(MD_TP, offsetof(struct mdthread, md_tp));
+ASSYM(MD_RAS_START, offsetof(struct mdthread, md_ras_start));
+ASSYM(MD_RAS_END, offsetof(struct mdthread, md_ras_end));
+
+ASSYM(TF_R0, offsetof(struct trapframe, tf_r0));
+ASSYM(TF_R1, offsetof(struct trapframe, tf_r1));
+ASSYM(TF_PC, offsetof(struct trapframe, tf_pc));
+ASSYM(P_PID, offsetof(struct proc, p_pid));
+ASSYM(P_FLAG, offsetof(struct proc, p_flag));
+
+ASSYM(SIGF_UC, offsetof(struct sigframe, sf_uc));
+
+#ifdef ARM_TP_ADDRESS
+ASSYM(ARM_TP_ADDRESS, ARM_TP_ADDRESS);
+ASSYM(ARM_RAS_START, ARM_RAS_START);
+ASSYM(ARM_RAS_END, ARM_RAS_END);
+#endif
+
+#ifdef VFP
+ASSYM(PCB_VFPSTATE, offsetof(struct pcb, pcb_vfpstate));
+
+ASSYM(PC_CPU, offsetof(struct pcpu, pc_cpu));
+
+ASSYM(PC_CURPMAP, offsetof(struct pcpu, pc_curpmap));
+#endif
+
+ASSYM(PAGE_SIZE, PAGE_SIZE);
+ASSYM(PDESIZE, PDESIZE);
+ASSYM(PMAP_DOMAIN_KERNEL, PMAP_DOMAIN_KERNEL);
+#ifdef PMAP_INCLUDE_PTE_SYNC
+ASSYM(PMAP_INCLUDE_PTE_SYNC, 1);
+#endif
+ASSYM(TDF_ASTPENDING, TDF_ASTPENDING);
+ASSYM(TDF_NEEDRESCHED, TDF_NEEDRESCHED);
+ASSYM(P_TRACED, P_TRACED);
+ASSYM(P_SIGEVENT, P_SIGEVENT);
+ASSYM(P_PROFIL, P_PROFIL);
+ASSYM(TRAPFRAMESIZE, sizeof(struct trapframe));
+
+ASSYM(MAXCOMLEN, MAXCOMLEN);
+ASSYM(MAXCPU, MAXCPU);
+ASSYM(NIRQ, NIRQ);
+ASSYM(PCPU_SIZE, sizeof(struct pcpu));
+
+ASSYM(DCACHE_LINE_SIZE, offsetof(struct cpuinfo, dcache_line_size));
+ASSYM(DCACHE_LINE_MASK, offsetof(struct cpuinfo, dcache_line_mask));
+ASSYM(ICACHE_LINE_SIZE, offsetof(struct cpuinfo, icache_line_size));
+ASSYM(ICACHE_LINE_MASK, offsetof(struct cpuinfo, icache_line_mask));


Property changes on: trunk/sys/arm/arm/genassym.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/generic_timer.c
===================================================================
--- trunk/sys/arm/arm/generic_timer.c	                        (rev 0)
+++ trunk/sys/arm/arm/generic_timer.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,394 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * Copyright (c) 2013 Ruslan Bukin <br at bsdpad.com>
+ * All rights reserved.
+ *
+ * Based on mpcore_timer.c developed by Ben Gray <ben.r.gray at gmail.com>
+ *
+ * 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.
+ * 3. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * 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.
+ */
+
+/**
+ *      Cortex-A15 (and probably A7) Generic Timer
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/generic_timer.c 275764 2014-12-14 15:41:56Z andrew $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/timeet.h>
+#include <sys/timetc.h>
+#include <sys/watchdog.h>
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+
+#define	GT_CTRL_ENABLE		(1 << 0)
+#define	GT_CTRL_INT_MASK	(1 << 1)
+#define	GT_CTRL_INT_STAT	(1 << 2)
+#define	GT_REG_CTRL		0
+#define	GT_REG_TVAL		1
+
+#define	GT_CNTKCTL_PL0PTEN	(1 << 9) /* PL0 Physical timer reg access */
+#define	GT_CNTKCTL_PL0VTEN	(1 << 8) /* PL0 Virtual timer reg access */
+#define	GT_CNTKCTL_EVNTI	(1 << 4) /* Virtual counter event bits */
+#define	GT_CNTKCTL_EVNTDIR	(1 << 3) /* Virtual counter event transition */
+#define	GT_CNTKCTL_EVNTEN	(1 << 2) /* Enables virtual counter events */
+#define	GT_CNTKCTL_PL0VCTEN	(1 << 1) /* PL0 CNTVCT and CNTFRQ access */
+#define	GT_CNTKCTL_PL0PCTEN	(1 << 0) /* PL0 CNTPCT and CNTFRQ access */
+
+struct arm_tmr_softc {
+	struct resource		*res[4];
+	void			*ihl[4];
+	uint32_t		clkfreq;
+	struct eventtimer	et;
+};
+
+static struct arm_tmr_softc *arm_tmr_sc = NULL;
+
+static struct resource_spec timer_spec[] = {
+	{ SYS_RES_IRQ,		0,	RF_ACTIVE },	/* Secure */
+	{ SYS_RES_IRQ,		1,	RF_ACTIVE },	/* Non-secure */
+	{ SYS_RES_IRQ,		2,	RF_ACTIVE },	/* Virt */
+	{ SYS_RES_IRQ,		3,	RF_ACTIVE | RF_OPTIONAL	}, /* Hyp */
+	{ -1, 0 }
+};
+
+static timecounter_get_t arm_tmr_get_timecount;
+
+static struct timecounter arm_tmr_timecount = {
+	.tc_name           = "ARM MPCore Timecounter",
+	.tc_get_timecount  = arm_tmr_get_timecount,
+	.tc_poll_pps       = NULL,
+	.tc_counter_mask   = ~0u,
+	.tc_frequency      = 0,
+	.tc_quality        = 1000,
+};
+
+static inline int
+get_freq(void)
+{
+	uint32_t val;
+
+	__asm volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (val));
+
+	return (val);
+}
+
+static inline int
+set_freq(uint32_t val)
+{
+
+	__asm volatile("mcr p15, 0, %[val], c14, c0, 0" : :
+	    [val] "r" (val));
+	isb();
+
+	return (val);
+}
+
+
+static inline long
+get_cntpct(void)
+{
+	uint64_t val;
+
+	__asm volatile("mrrc p15, 0, %Q0, %R0, c14" : "=r" (val));
+
+	return (val);
+}
+
+static inline int
+set_ctrl(uint32_t val)
+{
+
+	__asm volatile("mcr p15, 0, %[val], c14, c2, 1" : :
+	    [val] "r" (val));
+	isb();
+
+	return (0);
+}
+
+static inline int
+set_tval(uint32_t val)
+{
+
+	__asm volatile("mcr p15, 0, %[val], c14, c2, 0" : :
+	    [val] "r" (val));
+	isb();
+
+	return (0);
+}
+
+static inline int
+get_ctrl(void)
+{
+	uint32_t val;
+
+	__asm volatile("mrc p15, 0, %0, c14, c2, 1" : "=r" (val));
+
+	return (val);
+}
+
+static inline int
+get_tval(void)
+{
+	uint32_t val;
+
+	__asm volatile("mrc p15, 0, %0, c14, c2, 0" : "=r" (val));
+
+	return (val);
+}
+
+static inline void
+disable_user_access(void)
+{
+	uint32_t cntkctl;
+
+	__asm volatile("mrc p15, 0, %0, c14, c1, 0" : "=r" (cntkctl));
+	cntkctl &= ~(GT_CNTKCTL_PL0PTEN | GT_CNTKCTL_PL0VTEN |
+	    GT_CNTKCTL_EVNTEN | GT_CNTKCTL_PL0VCTEN | GT_CNTKCTL_PL0PCTEN);
+	__asm volatile("mcr p15, 0, %0, c14, c1, 0" : : "r" (cntkctl));
+	isb();
+}
+
+static unsigned
+arm_tmr_get_timecount(struct timecounter *tc)
+{
+
+	return (get_cntpct());
+}
+
+static int
+arm_tmr_start(struct eventtimer *et, sbintime_t first, sbintime_t period)
+{
+	struct arm_tmr_softc *sc;
+	int counts, ctrl;
+
+	sc = (struct arm_tmr_softc *)et->et_priv;
+
+	if (first != 0) {
+		counts = ((uint32_t)et->et_frequency * first) >> 32;
+		ctrl = get_ctrl();
+		ctrl &= ~GT_CTRL_INT_MASK;
+		ctrl |= GT_CTRL_ENABLE;
+		set_tval(counts);
+		set_ctrl(ctrl);
+		return (0);
+	}
+
+	return (EINVAL);
+
+}
+
+static int
+arm_tmr_stop(struct eventtimer *et)
+{
+	int ctrl;
+
+	ctrl = get_ctrl();
+	ctrl &= GT_CTRL_ENABLE;
+	set_ctrl(ctrl);
+
+	return (0);
+}
+
+static int
+arm_tmr_intr(void *arg)
+{
+	struct arm_tmr_softc *sc;
+	int ctrl;
+
+	sc = (struct arm_tmr_softc *)arg;
+	ctrl = get_ctrl();
+	if (ctrl & GT_CTRL_INT_STAT) {
+		ctrl |= GT_CTRL_INT_MASK;
+		set_ctrl(ctrl);
+	}
+
+	if (sc->et.et_active)
+		sc->et.et_event_cb(&sc->et, sc->et.et_arg);
+
+	return (FILTER_HANDLED);
+}
+
+static int
+arm_tmr_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "arm,armv7-timer"))
+		return (ENXIO);
+
+	device_set_desc(dev, "ARMv7 Generic Timer");
+	return (BUS_PROBE_DEFAULT);
+}
+
+
+static int
+arm_tmr_attach(device_t dev)
+{
+	struct arm_tmr_softc *sc;
+	phandle_t node;
+	pcell_t clock;
+	int error;
+	int i;
+
+	sc = device_get_softc(dev);
+	if (arm_tmr_sc)
+		return (ENXIO);
+
+	/* Get the base clock frequency */
+	node = ofw_bus_get_node(dev);
+	error = OF_getprop(node, "clock-frequency", &clock, sizeof(clock));
+	if (error > 0) {
+		sc->clkfreq = fdt32_to_cpu(clock);
+	}
+
+	if (sc->clkfreq == 0) {
+		/* Try to get clock frequency from timer */
+		sc->clkfreq = get_freq();
+	}
+
+	if (sc->clkfreq == 0) {
+		device_printf(dev, "No clock frequency specified\n");
+		return (ENXIO);
+	}
+
+	if (bus_alloc_resources(dev, timer_spec, sc->res)) {
+		device_printf(dev, "could not allocate resources\n");
+		return (ENXIO);
+	};
+
+	arm_tmr_sc = sc;
+
+	/* Setup secure and non-secure IRQs handler */
+	for (i = 0; i < 2; i++) {
+		error = bus_setup_intr(dev, sc->res[i], INTR_TYPE_CLK,
+		    arm_tmr_intr, NULL, sc, &sc->ihl[i]);
+		if (error) {
+			device_printf(dev, "Unable to alloc int resource.\n");
+			return (ENXIO);
+		}
+	}
+
+	disable_user_access();
+
+	arm_tmr_timecount.tc_frequency = sc->clkfreq;
+	tc_init(&arm_tmr_timecount);
+
+	sc->et.et_name = "ARM MPCore Eventtimer";
+	sc->et.et_flags = ET_FLAGS_ONESHOT | ET_FLAGS_PERCPU;
+	sc->et.et_quality = 1000;
+
+	sc->et.et_frequency = sc->clkfreq;
+	sc->et.et_min_period = (0x00000002LLU << 32) / sc->et.et_frequency;
+	sc->et.et_max_period = (0xfffffffeLLU << 32) / sc->et.et_frequency;
+	sc->et.et_start = arm_tmr_start;
+	sc->et.et_stop = arm_tmr_stop;
+	sc->et.et_priv = sc;
+	et_register(&sc->et);
+
+	return (0);
+}
+
+static device_method_t arm_tmr_methods[] = {
+	DEVMETHOD(device_probe,		arm_tmr_probe),
+	DEVMETHOD(device_attach,	arm_tmr_attach),
+	{ 0, 0 }
+};
+
+static driver_t arm_tmr_driver = {
+	"generic_timer",
+	arm_tmr_methods,
+	sizeof(struct arm_tmr_softc),
+};
+
+static devclass_t arm_tmr_devclass;
+
+EARLY_DRIVER_MODULE(timer, simplebus, arm_tmr_driver, arm_tmr_devclass, 0, 0,
+    BUS_PASS_TIMER + BUS_PASS_ORDER_MIDDLE);
+EARLY_DRIVER_MODULE(timer, ofwbus, arm_tmr_driver, arm_tmr_devclass, 0, 0,
+    BUS_PASS_TIMER + BUS_PASS_ORDER_MIDDLE);
+
+void
+DELAY(int usec)
+{
+	int32_t counts, counts_per_usec;
+	uint32_t first, last;
+
+	/*
+	 * Check the timers are setup, if not just
+	 * use a for loop for the meantime
+	 */
+	if (arm_tmr_sc == NULL) {
+		for (; usec > 0; usec--)
+			for (counts = 200; counts > 0; counts--)
+				/*
+				 * Prevent gcc from optimizing
+				 * out the loop
+				 */
+				cpufunc_nullop();
+		return;
+	}
+
+	/* Get the number of times to count */
+	counts_per_usec = ((arm_tmr_timecount.tc_frequency / 1000000) + 1);
+
+	/*
+	 * Clamp the timeout at a maximum value (about 32 seconds with
+	 * a 66MHz clock). *Nobody* should be delay()ing for anywhere
+	 * near that length of time and if they are, they should be hung
+	 * out to dry.
+	 */
+	if (usec >= (0x80000000U / counts_per_usec))
+		counts = (0x80000000U / counts_per_usec) - 1;
+	else
+		counts = usec * counts_per_usec;
+
+	first = get_cntpct();
+
+	while (counts > 0) {
+		last = get_cntpct();
+		counts -= (int32_t)(last - first);
+		first = last;
+	}
+}


Property changes on: trunk/sys/arm/arm/generic_timer.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/gic.c
===================================================================
--- trunk/sys/arm/arm/gic.c	                        (rev 0)
+++ trunk/sys/arm/arm/gic.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,471 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * Developed by Damjan Marion <damjan.marion at gmail.com>
+ *
+ * Based on OMAP4 GIC code by Ben Gray
+ *
+ * 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.
+ * 3. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * 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: stable/10/sys/arm/arm/gic.c 283334 2015-05-23 22:36:41Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/ktr.h>
+#include <sys/module.h>
+#include <sys/rman.h>
+#include <sys/pcpu.h>
+#include <sys/proc.h>
+#include <sys/cpuset.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <machine/bus.h>
+#include <machine/intr.h>
+#include <machine/smp.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+/* We are using GICv2 register naming */
+
+/* Distributor Registers */
+#define GICD_CTLR		0x000			/* v1 ICDDCR */
+#define GICD_TYPER		0x004			/* v1 ICDICTR */
+#define GICD_IIDR		0x008			/* v1 ICDIIDR */
+#define GICD_IGROUPR(n)		(0x0080 + ((n) * 4))	/* v1 ICDISER */
+#define GICD_ISENABLER(n)	(0x0100 + ((n) * 4))	/* v1 ICDISER */
+#define GICD_ICENABLER(n)	(0x0180 + ((n) * 4))	/* v1 ICDICER */
+#define GICD_ISPENDR(n)		(0x0200 + ((n) * 4))	/* v1 ICDISPR */
+#define GICD_ICPENDR(n)		(0x0280 + ((n) * 4))	/* v1 ICDICPR */
+#define GICD_ICACTIVER(n)	(0x0380 + ((n) * 4))	/* v1 ICDABR */
+#define GICD_IPRIORITYR(n)	(0x0400 + ((n) * 4))	/* v1 ICDIPR */
+#define GICD_ITARGETSR(n)	(0x0800 + ((n) * 4))	/* v1 ICDIPTR */
+#define GICD_ICFGR(n)		(0x0C00 + ((n) * 4))	/* v1 ICDICFR */
+#define GICD_SGIR(n)		(0x0F00 + ((n) * 4))	/* v1 ICDSGIR */
+
+/* CPU Registers */
+#define GICC_CTLR		0x0000			/* v1 ICCICR */
+#define GICC_PMR		0x0004			/* v1 ICCPMR */
+#define GICC_BPR		0x0008			/* v1 ICCBPR */
+#define GICC_IAR		0x000C			/* v1 ICCIAR */
+#define GICC_EOIR		0x0010			/* v1 ICCEOIR */
+#define GICC_RPR		0x0014			/* v1 ICCRPR */
+#define GICC_HPPIR		0x0018			/* v1 ICCHPIR */
+#define GICC_ABPR		0x001C			/* v1 ICCABPR */
+#define GICC_IIDR		0x00FC			/* v1 ICCIIDR*/
+
+#define	GIC_FIRST_IPI		 0	/* Irqs 0-15 are SGIs/IPIs. */
+#define	GIC_LAST_IPI		15
+#define	GIC_FIRST_PPI		16	/* Irqs 16-31 are private (per */
+#define	GIC_LAST_PPI		31	/* core) peripheral interrupts. */
+#define	GIC_FIRST_SPI		32	/* Irqs 32+ are shared peripherals. */
+
+/* First bit is a polarity bit (0 - low, 1 - high) */
+#define GICD_ICFGR_POL_LOW	(0 << 0)
+#define GICD_ICFGR_POL_HIGH	(1 << 0)
+#define GICD_ICFGR_POL_MASK	0x1
+/* Second bit is a trigger bit (0 - level, 1 - edge) */
+#define GICD_ICFGR_TRIG_LVL	(0 << 1)
+#define GICD_ICFGR_TRIG_EDGE	(1 << 1)
+#define GICD_ICFGR_TRIG_MASK	0x2
+
+struct arm_gic_softc {
+	struct resource *	gic_res[3];
+	bus_space_tag_t		gic_c_bst;
+	bus_space_tag_t		gic_d_bst;
+	bus_space_handle_t	gic_c_bsh;
+	bus_space_handle_t	gic_d_bsh;
+	uint8_t			ver;
+	device_t		dev;
+	struct mtx		mutex;
+	uint32_t		nirqs;
+};
+
+static struct resource_spec arm_gic_spec[] = {
+	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },	/* Distributor registers */
+	{ SYS_RES_MEMORY,	1,	RF_ACTIVE },	/* CPU Interrupt Intf. registers */
+	{ -1, 0 }
+};
+
+static struct arm_gic_softc *arm_gic_sc = NULL;
+
+#define	gic_c_read_4(reg)		\
+    bus_space_read_4(arm_gic_sc->gic_c_bst, arm_gic_sc->gic_c_bsh, reg)
+#define	gic_c_write_4(reg, val)		\
+    bus_space_write_4(arm_gic_sc->gic_c_bst, arm_gic_sc->gic_c_bsh, reg, val)
+#define	gic_d_read_4(reg)		\
+    bus_space_read_4(arm_gic_sc->gic_d_bst, arm_gic_sc->gic_d_bsh, reg)
+#define	gic_d_write_4(reg, val)		\
+    bus_space_write_4(arm_gic_sc->gic_d_bst, arm_gic_sc->gic_d_bsh, reg, val)
+
+static int gic_config_irq(int irq, enum intr_trigger trig,
+    enum intr_polarity pol);
+static void gic_post_filter(void *);
+
+static struct ofw_compat_data compat_data[] = {
+	{"arm,gic",		true},	/* Non-standard, used in FreeBSD dts. */
+	{"arm,gic-400",		true},
+	{"arm,cortex-a15-gic",	true},
+	{"arm,cortex-a9-gic",	true},
+	{"arm,cortex-a7-gic",	true},
+	{"arm,arm11mp-gic",	true},
+	{"brcm,brahma-b15-gic",	true},
+	{NULL,			false}
+};
+
+static int
+arm_gic_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data)
+		return (ENXIO);
+	device_set_desc(dev, "ARM Generic Interrupt Controller");
+	return (BUS_PROBE_DEFAULT);
+}
+
+void
+gic_init_secondary(void)
+{
+	int i, nirqs;
+
+  	/* Get the number of interrupts */
+	nirqs = gic_d_read_4(GICD_TYPER);
+	nirqs = 32 * ((nirqs & 0x1f) + 1);
+
+	for (i = 0; i < nirqs; i += 4)
+		gic_d_write_4(GICD_IPRIORITYR(i >> 2), 0);
+
+	/* Set all the interrupts to be in Group 0 (secure) */
+	for (i = 0; i < nirqs; i += 32) {
+		gic_d_write_4(GICD_IGROUPR(i >> 5), 0);
+	}
+
+	/* Enable CPU interface */
+	gic_c_write_4(GICC_CTLR, 1);
+
+	/* Set priority mask register. */
+	gic_c_write_4(GICC_PMR, 0xff);
+
+	/* Enable interrupt distribution */
+	gic_d_write_4(GICD_CTLR, 0x01);
+
+	/* Activate IRQ 29, ie private timer IRQ*/
+	gic_d_write_4(GICD_ISENABLER(29 >> 5), (1UL << (29 & 0x1F)));
+}
+
+int
+gic_decode_fdt(uint32_t iparent, uint32_t *intr, int *interrupt,
+    int *trig, int *pol)
+{
+	static u_int num_intr_cells;
+
+	if (num_intr_cells == 0) {
+		if (OF_searchencprop(OF_node_from_xref(iparent), 
+		    "#interrupt-cells", &num_intr_cells, 
+		    sizeof(num_intr_cells)) == -1) {
+			num_intr_cells = 1;
+		}
+	}
+
+	if (num_intr_cells == 1) {
+		*interrupt = fdt32_to_cpu(intr[0]);
+		*trig = INTR_TRIGGER_CONFORM;
+		*pol = INTR_POLARITY_CONFORM;
+	} else {
+		if (fdt32_to_cpu(intr[0]) == 0)
+			*interrupt = fdt32_to_cpu(intr[1]) + GIC_FIRST_SPI;
+		else
+			*interrupt = fdt32_to_cpu(intr[1]) + GIC_FIRST_PPI;
+		/*
+		 * In intr[2], bits[3:0] are trigger type and level flags.
+		 *   1 = low-to-high edge triggered
+		 *   2 = high-to-low edge triggered
+		 *   4 = active high level-sensitive
+		 *   8 = active low level-sensitive
+		 * The hardware only supports active-high-level or rising-edge.
+		 */
+		if (fdt32_to_cpu(intr[2]) & 0x0a) {
+			printf("unsupported trigger/polarity configuration "
+			    "0x%2x\n", fdt32_to_cpu(intr[2]) & 0x0f);
+			return (ENOTSUP);
+		}
+		*pol  = INTR_POLARITY_CONFORM;
+		if (fdt32_to_cpu(intr[2]) & 0x01)
+			*trig = INTR_TRIGGER_EDGE;
+		else
+			*trig = INTR_TRIGGER_LEVEL;
+	}
+	return (0);
+}
+
+static int
+arm_gic_attach(device_t dev)
+{
+	struct		arm_gic_softc *sc;
+	int		i;
+	uint32_t	icciidr;
+
+	if (arm_gic_sc)
+		return (ENXIO);
+
+	sc = device_get_softc(dev);
+	sc->dev = dev;
+
+	if (bus_alloc_resources(dev, arm_gic_spec, sc->gic_res)) {
+		device_printf(dev, "could not allocate resources\n");
+		return (ENXIO);
+	}
+
+	/* Initialize mutex */
+	mtx_init(&sc->mutex, "GIC lock", "", MTX_SPIN);
+
+	/* Distributor Interface */
+	sc->gic_d_bst = rman_get_bustag(sc->gic_res[0]);
+	sc->gic_d_bsh = rman_get_bushandle(sc->gic_res[0]);
+
+	/* CPU Interface */
+	sc->gic_c_bst = rman_get_bustag(sc->gic_res[1]);
+	sc->gic_c_bsh = rman_get_bushandle(sc->gic_res[1]);
+
+	arm_gic_sc = sc;
+
+	/* Disable interrupt forwarding to the CPU interface */
+	gic_d_write_4(GICD_CTLR, 0x00);
+
+	/* Get the number of interrupts */
+	sc->nirqs = gic_d_read_4(GICD_TYPER);
+	sc->nirqs = 32 * ((sc->nirqs & 0x1f) + 1);
+
+	/* Set up function pointers */
+	arm_post_filter = gic_post_filter;
+	arm_config_irq = gic_config_irq;
+
+	icciidr = gic_c_read_4(GICC_IIDR);
+	device_printf(dev,"pn 0x%x, arch 0x%x, rev 0x%x, implementer 0x%x irqs %u\n",
+			icciidr>>20, (icciidr>>16) & 0xF, (icciidr>>12) & 0xf,
+			(icciidr & 0xfff), sc->nirqs);
+
+	/* Set all global interrupts to be level triggered, active low. */
+	for (i = 32; i < sc->nirqs; i += 16) {
+		gic_d_write_4(GICD_ICFGR(i >> 4), 0x00000000);
+	}
+
+	/* Disable all interrupts. */
+	for (i = 32; i < sc->nirqs; i += 32) {
+		gic_d_write_4(GICD_ICENABLER(i >> 5), 0xFFFFFFFF);
+	}
+
+	for (i = 0; i < sc->nirqs; i += 4) {
+		gic_d_write_4(GICD_IPRIORITYR(i >> 2), 0);
+		gic_d_write_4(GICD_ITARGETSR(i >> 2), 1 << 0 | 1 << 8 | 1 << 16 | 1 << 24);
+	}
+
+	/* Set all the interrupts to be in Group 0 (secure) */
+	for (i = 0; i < sc->nirqs; i += 32) {
+		gic_d_write_4(GICD_IGROUPR(i >> 5), 0);
+	}
+
+	/* Enable CPU interface */
+	gic_c_write_4(GICC_CTLR, 1);
+
+	/* Set priority mask register. */
+	gic_c_write_4(GICC_PMR, 0xff);
+
+	/* Enable interrupt distribution */
+	gic_d_write_4(GICD_CTLR, 0x01);
+
+	return (0);
+}
+
+static device_method_t arm_gic_methods[] = {
+	DEVMETHOD(device_probe,		arm_gic_probe),
+	DEVMETHOD(device_attach,	arm_gic_attach),
+	{ 0, 0 }
+};
+
+static driver_t arm_gic_driver = {
+	"gic",
+	arm_gic_methods,
+	sizeof(struct arm_gic_softc),
+};
+
+static devclass_t arm_gic_devclass;
+
+EARLY_DRIVER_MODULE(gic, simplebus, arm_gic_driver, arm_gic_devclass, 0, 0,
+    BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE);
+EARLY_DRIVER_MODULE(gic, ofwbus, arm_gic_driver, arm_gic_devclass, 0, 0,
+    BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE);
+
+static void
+gic_post_filter(void *arg)
+{
+	uintptr_t irq = (uintptr_t) arg;
+
+	if (irq > GIC_LAST_IPI)
+		arm_irq_memory_barrier(irq);
+	gic_c_write_4(GICC_EOIR, irq);
+}
+
+int
+arm_get_next_irq(int last_irq)
+{
+	uint32_t active_irq;
+
+	active_irq = gic_c_read_4(GICC_IAR);
+
+	/*
+	 * Immediatly EOIR the SGIs, because doing so requires the other
+	 * bits (ie CPU number), not just the IRQ number, and we do not
+	 * have this information later.
+	 */
+
+	if ((active_irq & 0x3ff) <= GIC_LAST_IPI)
+		gic_c_write_4(GICC_EOIR, active_irq);
+	active_irq &= 0x3FF;
+
+	if (active_irq == 0x3FF) {
+		if (last_irq == -1)
+			printf("Spurious interrupt detected\n");
+		return -1;
+	}
+
+	return active_irq;
+}
+
+void
+arm_mask_irq(uintptr_t nb)
+{
+
+	gic_d_write_4(GICD_ICENABLER(nb >> 5), (1UL << (nb & 0x1F)));
+	gic_c_write_4(GICC_EOIR, nb);
+}
+
+void
+arm_unmask_irq(uintptr_t nb)
+{
+
+	if (nb > GIC_LAST_IPI)
+		arm_irq_memory_barrier(nb);
+	gic_d_write_4(GICD_ISENABLER(nb >> 5), (1UL << (nb & 0x1F)));
+}
+
+static int
+gic_config_irq(int irq, enum intr_trigger trig,
+    enum intr_polarity pol)
+{
+	uint32_t reg;
+	uint32_t mask;
+
+	/* Function is public-accessible, so validate input arguments */
+	if ((irq < 0) || (irq >= arm_gic_sc->nirqs))
+		goto invalid_args;
+	if ((trig != INTR_TRIGGER_EDGE) && (trig != INTR_TRIGGER_LEVEL) &&
+	    (trig != INTR_TRIGGER_CONFORM))
+		goto invalid_args;
+	if ((pol != INTR_POLARITY_HIGH) && (pol != INTR_POLARITY_LOW) &&
+	    (pol != INTR_POLARITY_CONFORM))
+		goto invalid_args;
+
+	mtx_lock_spin(&arm_gic_sc->mutex);
+
+	reg = gic_d_read_4(GICD_ICFGR(irq >> 4));
+	mask = (reg >> 2*(irq % 16)) & 0x3;
+
+	if (pol == INTR_POLARITY_LOW) {
+		mask &= ~GICD_ICFGR_POL_MASK;
+		mask |= GICD_ICFGR_POL_LOW;
+	} else if (pol == INTR_POLARITY_HIGH) {
+		mask &= ~GICD_ICFGR_POL_MASK;
+		mask |= GICD_ICFGR_POL_HIGH;
+	}
+
+	if (trig == INTR_TRIGGER_LEVEL) {
+		mask &= ~GICD_ICFGR_TRIG_MASK;
+		mask |= GICD_ICFGR_TRIG_LVL;
+	} else if (trig == INTR_TRIGGER_EDGE) {
+		mask &= ~GICD_ICFGR_TRIG_MASK;
+		mask |= GICD_ICFGR_TRIG_EDGE;
+	}
+
+	/* Set mask */
+	reg = reg & ~(0x3 << 2*(irq % 16));
+	reg = reg | (mask << 2*(irq % 16));
+	gic_d_write_4(GICD_ICFGR(irq >> 4), reg);
+
+	mtx_unlock_spin(&arm_gic_sc->mutex);
+
+	return (0);
+
+invalid_args:
+	device_printf(arm_gic_sc->dev, "gic_config_irg, invalid parameters\n");
+	return (EINVAL);
+}
+
+#ifdef SMP
+void
+pic_ipi_send(cpuset_t cpus, u_int ipi)
+{
+	uint32_t val = 0, i;
+
+	for (i = 0; i < MAXCPU; i++)
+		if (CPU_ISSET(i, &cpus))
+			val |= 1 << (16 + i);
+	gic_d_write_4(GICD_SGIR(0), val | ipi);
+
+}
+
+int
+pic_ipi_get(int i)
+{
+
+	if (i != -1) {
+		/*
+		 * The intr code will automagically give the frame pointer
+		 * if the interrupt argument is 0.
+		 */
+		if ((unsigned int)i > 16)
+			return (0);
+		return (i);
+	}
+	return (0x3ff);
+}
+
+void
+pic_ipi_clear(int ipi)
+{
+}
+#endif
+


Property changes on: trunk/sys/arm/arm/gic.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/identcpu.c
===================================================================
--- trunk/sys/arm/arm/identcpu.c	                        (rev 0)
+++ trunk/sys/arm/arm/identcpu.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,527 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: cpu.c,v 1.55 2004/02/13 11:36:10 wiz Exp $	*/
+
+/*-
+ * Copyright (c) 1995 Mark Brinicombe.
+ * Copyright (c) 1995 Brini.
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Brini.
+ * 4. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BRINI ``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 BRINI 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.
+ *
+ * RiscBSD kernel project
+ *
+ * cpu.c
+ *
+ * Probing and configuration for the master CPU
+ *
+ * Created      : 10/10/95
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/identcpu.c 278626 2015-02-12 17:01:54Z ian $");
+#include <sys/systm.h>
+#include <sys/param.h>
+#include <sys/malloc.h>
+#include <sys/time.h>
+#include <sys/proc.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <sys/sysctl.h>
+#include <machine/cpu.h>
+#include <machine/endian.h>
+
+#include <machine/cpuconf.h>
+#include <machine/md_var.h>
+
+char machine[] = "arm";
+
+SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD,
+	machine, 0, "Machine class");
+
+static const char * const generic_steppings[16] = {
+	"rev 0",	"rev 1",	"rev 2",	"rev 3",
+	"rev 4",	"rev 5",	"rev 6",	"rev 7",
+	"rev 8",	"rev 9",	"rev 10",	"rev 11",
+	"rev 12",	"rev 13",	"rev 14",	"rev 15",
+};
+
+static const char * const xscale_steppings[16] = {
+	"step A-0",	"step A-1",	"step B-0",	"step C-0",
+	"step D-0",	"rev 5",	"rev 6",	"rev 7",
+	"rev 8",	"rev 9",	"rev 10",	"rev 11",
+	"rev 12",	"rev 13",	"rev 14",	"rev 15",
+};
+
+static const char * const i80219_steppings[16] = {
+	"step A-0",	"rev 1",	"rev 2",	"rev 3",
+	"rev 4",	"rev 5",	"rev 6",	"rev 7",
+	"rev 8",	"rev 9",	"rev 10",	"rev 11",
+	"rev 12",	"rev 13",	"rev 14",	"rev 15",
+};
+
+static const char * const i80321_steppings[16] = {
+	"step A-0",	"step B-0",	"rev 2",	"rev 3",
+	"rev 4",	"rev 5",	"rev 6",	"rev 7",
+	"rev 8",	"rev 9",	"rev 10",	"rev 11",
+	"rev 12",	"rev 13",	"rev 14",	"rev 15",
+};
+
+static const char * const i81342_steppings[16] = {
+	"step A-0",	"rev 1",	"rev 2",	"rev 3",
+	"rev 4",	"rev 5",	"rev 6",	"rev 7",
+	"rev 8",	"rev 9",	"rev 10",	"rev 11",
+	"rev 12",	"rev 13",	"rev 14",	"rev 15",
+};
+
+/* Steppings for PXA2[15]0 */
+static const char * const pxa2x0_steppings[16] = {
+	"step A-0",	"step A-1",	"step B-0",	"step B-1",
+	"step B-2",	"step C-0",	"rev 6",	"rev 7",
+	"rev 8",	"rev 9",	"rev 10",	"rev 11",
+	"rev 12",	"rev 13",	"rev 14",	"rev 15",
+};
+
+/* Steppings for PXA255/26x.
+ * rev 5: PXA26x B0, rev 6: PXA255 A0
+ */
+static const char * const pxa255_steppings[16] = {
+	"rev 0",	"rev 1",	"rev 2",	"step A-0",
+	"rev 4",	"step B-0",	"step A-0",	"rev 7",
+	"rev 8",	"rev 9",	"rev 10",	"rev 11",
+	"rev 12",	"rev 13",	"rev 14",	"rev 15",
+};
+
+/* Stepping for PXA27x */
+static const char * const pxa27x_steppings[16] = {
+	"step A-0",	"step A-1",	"step B-0",	"step B-1",
+	"step C-0",	"rev 5",	"rev 6",	"rev 7",
+	"rev 8",	"rev 9",	"rev 10",	"rev 11",
+	"rev 12",	"rev 13",	"rev 14",	"rev 15",
+};
+
+static const char * const ixp425_steppings[16] = {
+	"step 0 (A0)",	"rev 1 (ARMv5TE)", "rev 2",	"rev 3",
+	"rev 4",	"rev 5",	"rev 6",	"rev 7",
+	"rev 8",	"rev 9",	"rev 10",	"rev 11",
+	"rev 12",	"rev 13",	"rev 14",	"rev 15",
+};
+
+struct cpuidtab {
+	u_int32_t	cpuid;
+	enum		cpu_class cpu_class;
+	const char	*cpu_name;
+	const char * const *cpu_steppings;
+};
+
+const struct cpuidtab cpuids[] = {
+	{ CPU_ID_ARM920T,	CPU_CLASS_ARM9TDMI,	"ARM920T",
+	  generic_steppings },
+	{ CPU_ID_ARM920T_ALT,	CPU_CLASS_ARM9TDMI,	"ARM920T",
+	  generic_steppings },
+	{ CPU_ID_ARM922T,	CPU_CLASS_ARM9TDMI,	"ARM922T",
+	  generic_steppings },
+	{ CPU_ID_ARM926EJS,	CPU_CLASS_ARM9EJS,	"ARM926EJ-S",
+	  generic_steppings },
+	{ CPU_ID_ARM940T,	CPU_CLASS_ARM9TDMI,	"ARM940T",
+	  generic_steppings },
+	{ CPU_ID_ARM946ES,	CPU_CLASS_ARM9ES,	"ARM946E-S",
+	  generic_steppings },
+	{ CPU_ID_ARM966ES,	CPU_CLASS_ARM9ES,	"ARM966E-S",
+	  generic_steppings },
+	{ CPU_ID_ARM966ESR1,	CPU_CLASS_ARM9ES,	"ARM966E-S",
+	  generic_steppings },
+	{ CPU_ID_FA526,		CPU_CLASS_ARM9TDMI,	"FA526",
+	  generic_steppings },
+	{ CPU_ID_FA626TE,	CPU_CLASS_ARM9ES,	"FA626TE",
+	  generic_steppings },
+
+	{ CPU_ID_TI925T,	CPU_CLASS_ARM9TDMI,	"TI ARM925T",
+	  generic_steppings },
+
+	{ CPU_ID_ARM1020E,	CPU_CLASS_ARM10E,	"ARM1020E",
+	  generic_steppings },
+	{ CPU_ID_ARM1022ES,	CPU_CLASS_ARM10E,	"ARM1022E-S",
+	  generic_steppings },
+	{ CPU_ID_ARM1026EJS,	CPU_CLASS_ARM10EJ,	"ARM1026EJ-S",
+	  generic_steppings },
+
+	{ CPU_ID_CORTEXA7,	CPU_CLASS_CORTEXA,	"Cortex A7",
+	  generic_steppings },
+	{ CPU_ID_CORTEXA8R1,	CPU_CLASS_CORTEXA,	"Cortex A8-r1",
+	  generic_steppings },
+	{ CPU_ID_CORTEXA8R2,	CPU_CLASS_CORTEXA,	"Cortex A8-r2",
+	  generic_steppings },
+	{ CPU_ID_CORTEXA8R3,	CPU_CLASS_CORTEXA,	"Cortex A8-r3",
+	  generic_steppings },
+	{ CPU_ID_CORTEXA9R1,	CPU_CLASS_CORTEXA,	"Cortex A9-r1",
+	  generic_steppings },
+	{ CPU_ID_CORTEXA9R2,	CPU_CLASS_CORTEXA,	"Cortex A9-r2",
+	  generic_steppings },
+	{ CPU_ID_CORTEXA9R3,	CPU_CLASS_CORTEXA,	"Cortex A9-r3",
+	  generic_steppings },
+	{ CPU_ID_CORTEXA15R0,	CPU_CLASS_CORTEXA,	"Cortex A15-r0",
+	  generic_steppings },
+	{ CPU_ID_CORTEXA15R1,	CPU_CLASS_CORTEXA,	"Cortex A15-r1",
+	  generic_steppings },
+	{ CPU_ID_CORTEXA15R2,	CPU_CLASS_CORTEXA,	"Cortex A15-r2",
+	  generic_steppings },
+	{ CPU_ID_CORTEXA15R3,	CPU_CLASS_CORTEXA,	"Cortex A15-r3",
+	  generic_steppings },
+	{ CPU_ID_KRAIT,		CPU_CLASS_KRAIT,	"Krait",
+	  generic_steppings },
+
+	{ CPU_ID_80200,		CPU_CLASS_XSCALE,	"i80200",
+	  xscale_steppings },
+
+	{ CPU_ID_80321_400,	CPU_CLASS_XSCALE,	"i80321 400MHz",
+	  i80321_steppings },
+	{ CPU_ID_80321_600,	CPU_CLASS_XSCALE,	"i80321 600MHz",
+	  i80321_steppings },
+	{ CPU_ID_80321_400_B0,	CPU_CLASS_XSCALE,	"i80321 400MHz",
+	  i80321_steppings },
+	{ CPU_ID_80321_600_B0,	CPU_CLASS_XSCALE,	"i80321 600MHz",
+	  i80321_steppings },
+
+	{ CPU_ID_81342,		CPU_CLASS_XSCALE,	"i81342",
+	  i81342_steppings },
+
+	{ CPU_ID_80219_400,	CPU_CLASS_XSCALE,	"i80219 400MHz",
+	  i80219_steppings },
+	{ CPU_ID_80219_600,	CPU_CLASS_XSCALE,	"i80219 600MHz",
+	  i80219_steppings },
+
+	{ CPU_ID_PXA27X,	CPU_CLASS_XSCALE,	"PXA27x",
+	  pxa27x_steppings },
+	{ CPU_ID_PXA250A,	CPU_CLASS_XSCALE,	"PXA250",
+	  pxa2x0_steppings },
+	{ CPU_ID_PXA210A,	CPU_CLASS_XSCALE,	"PXA210",
+	  pxa2x0_steppings },
+	{ CPU_ID_PXA250B,	CPU_CLASS_XSCALE,	"PXA250",
+	  pxa2x0_steppings },
+	{ CPU_ID_PXA210B,	CPU_CLASS_XSCALE,	"PXA210",
+	  pxa2x0_steppings },
+	{ CPU_ID_PXA250C, 	CPU_CLASS_XSCALE,	"PXA255",
+	  pxa255_steppings },
+	{ CPU_ID_PXA210C, 	CPU_CLASS_XSCALE,	"PXA210",
+	  pxa2x0_steppings },
+
+	{ CPU_ID_IXP425_533,	CPU_CLASS_XSCALE,	"IXP425 533MHz",
+	  ixp425_steppings },
+	{ CPU_ID_IXP425_400,	CPU_CLASS_XSCALE,	"IXP425 400MHz",
+	  ixp425_steppings },
+	{ CPU_ID_IXP425_266,	CPU_CLASS_XSCALE,	"IXP425 266MHz",
+	  ixp425_steppings },
+
+	/* XXX ixp435 steppings? */
+	{ CPU_ID_IXP435,	CPU_CLASS_XSCALE,	"IXP435",
+	  ixp425_steppings },
+
+	{ CPU_ID_ARM1136JS,	CPU_CLASS_ARM11J,	"ARM1136J-S",
+	  generic_steppings },
+	{ CPU_ID_ARM1136JSR1,	CPU_CLASS_ARM11J,	"ARM1136J-S R1",
+	  generic_steppings },
+	{ CPU_ID_ARM1176JZS,	CPU_CLASS_ARM11J,	"ARM1176JZ-S",
+	  generic_steppings },
+
+	{ CPU_ID_MV88FR131,	CPU_CLASS_MARVELL,	"Feroceon 88FR131",
+	  generic_steppings },
+
+	{ CPU_ID_MV88FR571_VD,	CPU_CLASS_MARVELL,	"Feroceon 88FR571-VD",
+	  generic_steppings },
+	{ CPU_ID_MV88SV581X_V7,	CPU_CLASS_MARVELL,	"Sheeva 88SV581x",
+	  generic_steppings },
+	{ CPU_ID_ARM_88SV581X_V7, CPU_CLASS_MARVELL,	"Sheeva 88SV581x",
+	  generic_steppings },
+	{ CPU_ID_MV88SV584X_V7,	CPU_CLASS_MARVELL,	"Sheeva 88SV584x",
+	  generic_steppings },
+
+	{ 0, CPU_CLASS_NONE, NULL, NULL }
+};
+
+struct cpu_classtab {
+	const char	*class_name;
+	const char	*class_option;
+};
+
+const struct cpu_classtab cpu_classes[] = {
+	{ "unknown",	NULL },			/* CPU_CLASS_NONE */
+	{ "ARM9TDMI",	"CPU_ARM9TDMI" },	/* CPU_CLASS_ARM9TDMI */
+	{ "ARM9E-S",	"CPU_ARM9E" },		/* CPU_CLASS_ARM9ES */
+	{ "ARM9EJ-S",	"CPU_ARM9E" },		/* CPU_CLASS_ARM9EJS */
+	{ "ARM10E",	"CPU_ARM10" },		/* CPU_CLASS_ARM10E */
+	{ "ARM10EJ",	"CPU_ARM10" },		/* CPU_CLASS_ARM10EJ */
+	{ "Cortex-A",	"CPU_CORTEXA" },	/* CPU_CLASS_CORTEXA */
+	{ "Krait",	"CPU_KRAIT" },		/* CPU_CLASS_KRAIT */
+	{ "XScale",	"CPU_XSCALE_..." },	/* CPU_CLASS_XSCALE */
+	{ "ARM11J",	"CPU_ARM11" },		/* CPU_CLASS_ARM11J */
+	{ "Marvell",	"CPU_MARVELL" },	/* CPU_CLASS_MARVELL */
+};
+
+/*
+ * Report the type of the specified arm processor. This uses the generic and
+ * arm specific information in the cpu structure to identify the processor.
+ * The remaining fields in the cpu structure are filled in appropriately.
+ */
+
+static const char * const wtnames[] = {
+	"write-through",
+	"write-back",
+	"write-back",
+	"**unknown 3**",
+	"**unknown 4**",
+	"write-back-locking",		/* XXX XScale-specific? */
+	"write-back-locking-A",
+	"write-back-locking-B",
+	"**unknown 8**",
+	"**unknown 9**",
+	"**unknown 10**",
+	"**unknown 11**",
+	"**unknown 12**",
+	"**unknown 13**",
+	"write-back-locking-C",
+	"**unknown 15**",
+};
+
+static void
+print_enadis(int enadis, char *s)
+{
+
+	printf(" %s %sabled", s, (enadis == 0) ? "dis" : "en");
+}
+
+extern int ctrl;
+enum cpu_class cpu_class = CPU_CLASS_NONE;
+
+u_int cpu_pfr(int num)
+{
+	u_int feat;
+
+	switch (num) {
+	case 0:
+		__asm __volatile("mrc p15, 0, %0, c0, c1, 0"
+		    : "=r" (feat));
+		break;
+	case 1:
+		__asm __volatile("mrc p15, 0, %0, c0, c1, 1"
+		    : "=r" (feat));
+		break;
+	default:
+		panic("Processor Feature Register %d not implemented", num);
+		break;
+	}
+
+	return (feat);
+}
+
+static
+void identify_armv7(void)
+{
+	u_int feature;
+
+	printf("Supported features:");
+	/* Get Processor Feature Register 0 */
+	feature = cpu_pfr(0);
+
+	if (feature & ARM_PFR0_ARM_ISA_MASK)
+		printf(" ARM_ISA");
+
+	if (feature & ARM_PFR0_THUMB2)
+		printf(" THUMB2");
+	else if (feature & ARM_PFR0_THUMB)
+		printf(" THUMB");
+
+	if (feature & ARM_PFR0_JAZELLE_MASK)
+		printf(" JAZELLE");
+
+	if (feature & ARM_PFR0_THUMBEE_MASK)
+		printf(" THUMBEE");
+
+
+	/* Get Processor Feature Register 1 */
+	feature = cpu_pfr(1);
+
+	if (feature & ARM_PFR1_ARMV4_MASK)
+		printf(" ARMv4");
+
+	if (feature & ARM_PFR1_SEC_EXT_MASK)
+		printf(" Security_Ext");
+
+	if (feature & ARM_PFR1_MICROCTRL_MASK)
+		printf(" M_profile");
+
+	printf("\n");
+}
+
+void
+identify_arm_cpu(void)
+{
+	u_int cpuid, reg, size, sets, ways;
+	u_int8_t type, linesize;
+	int i;
+
+	cpuid = cpu_id();
+
+	if (cpuid == 0) {
+		printf("Processor failed probe - no CPU ID\n");
+		return;
+	}
+
+	for (i = 0; cpuids[i].cpuid != 0; i++)
+		if (cpuids[i].cpuid == (cpuid & CPU_ID_CPU_MASK)) {
+			cpu_class = cpuids[i].cpu_class;
+			printf("CPU: %s %s (%s core)\n",
+			    cpuids[i].cpu_name,
+			    cpuids[i].cpu_steppings[cpuid &
+			    CPU_ID_REVISION_MASK],
+			    cpu_classes[cpu_class].class_name);
+			break;
+		}
+	if (cpuids[i].cpuid == 0)
+		printf("unknown CPU (ID = 0x%x)\n", cpuid);
+
+	printf(" ");
+
+	if ((cpuid & CPU_ID_ARCH_MASK) == CPU_ID_CPUID_SCHEME) {
+		identify_armv7();
+	} else {
+		if (ctrl & CPU_CONTROL_BEND_ENABLE)
+			printf(" Big-endian");
+		else
+			printf(" Little-endian");
+
+		switch (cpu_class) {
+		case CPU_CLASS_ARM9TDMI:
+		case CPU_CLASS_ARM9ES:
+		case CPU_CLASS_ARM9EJS:
+		case CPU_CLASS_ARM10E:
+		case CPU_CLASS_ARM10EJ:
+		case CPU_CLASS_XSCALE:
+		case CPU_CLASS_ARM11J:
+		case CPU_CLASS_MARVELL:
+			print_enadis(ctrl & CPU_CONTROL_DC_ENABLE, "DC");
+			print_enadis(ctrl & CPU_CONTROL_IC_ENABLE, "IC");
+#ifdef CPU_XSCALE_81342
+			print_enadis(ctrl & CPU_CONTROL_L2_ENABLE, "L2");
+#endif
+#if defined(SOC_MV_KIRKWOOD) || defined(SOC_MV_DISCOVERY)
+			i = sheeva_control_ext(0, 0);
+			print_enadis(i & MV_WA_ENABLE, "WA");
+			print_enadis(i & MV_DC_STREAM_ENABLE, "DC streaming");
+			printf("\n ");
+			print_enadis((i & MV_BTB_DISABLE) == 0, "BTB");
+			print_enadis(i & MV_L2_ENABLE, "L2");
+			print_enadis((i & MV_L2_PREFETCH_DISABLE) == 0,
+			    "L2 prefetch");
+			printf("\n ");
+#endif
+			break;
+		default:
+			break;
+		}
+	}
+
+	print_enadis(ctrl & CPU_CONTROL_WBUF_ENABLE, "WB");
+	if (ctrl & CPU_CONTROL_LABT_ENABLE)
+		printf(" LABT");
+	else
+		printf(" EABT");
+
+	print_enadis(ctrl & CPU_CONTROL_BPRD_ENABLE, "branch prediction");
+	printf("\n");
+
+	if (arm_cache_level) {
+		printf("LoUU:%d LoC:%d LoUIS:%d \n", CPU_CLIDR_LOUU(arm_cache_level) + 1,
+		    arm_cache_loc + 1, CPU_CLIDR_LOUIS(arm_cache_level) + 1);
+		i = 0;
+		while (((type = CPU_CLIDR_CTYPE(arm_cache_level, i)) != 0) && i < 7) {
+			printf("Cache level %d: \n", i + 1);
+			if (type == CACHE_DCACHE || type == CACHE_UNI_CACHE ||
+			    type == CACHE_SEP_CACHE) {
+				reg = arm_cache_type[2 * i];
+				ways = CPUV7_CT_xSIZE_ASSOC(reg) + 1;
+				sets = CPUV7_CT_xSIZE_SET(reg) + 1;
+				linesize = 1 << (CPUV7_CT_xSIZE_LEN(reg) + 4);
+				size = (ways * sets * linesize) / 1024;
+
+				if (type == CACHE_UNI_CACHE)
+					printf(" %dKB/%dB %d-way unified cache", size, linesize,ways);
+				else
+					printf(" %dKB/%dB %d-way data cache", size, linesize, ways);
+				if (reg & CPUV7_CT_CTYPE_WT)
+					printf(" WT");
+				if (reg & CPUV7_CT_CTYPE_WB)
+					printf(" WB");
+				if (reg & CPUV7_CT_CTYPE_RA)
+					printf(" Read-Alloc");
+				if (reg & CPUV7_CT_CTYPE_WA)
+					printf(" Write-Alloc");
+				printf("\n");
+			}
+
+			if (type == CACHE_ICACHE || type == CACHE_SEP_CACHE) {
+				reg = arm_cache_type[(2 * i) + 1];
+
+				ways = CPUV7_CT_xSIZE_ASSOC(reg) + 1;
+				sets = CPUV7_CT_xSIZE_SET(reg) + 1;
+				linesize = 1 << (CPUV7_CT_xSIZE_LEN(reg) + 4);
+				size = (ways * sets * linesize) / 1024;
+
+				printf(" %dKB/%dB %d-way instruction cache", size, linesize, ways);
+				if (reg & CPUV7_CT_CTYPE_WT)
+					printf(" WT");
+				if (reg & CPUV7_CT_CTYPE_WB)
+					printf(" WB");
+				if (reg & CPUV7_CT_CTYPE_RA)
+					printf(" Read-Alloc");
+				if (reg & CPUV7_CT_CTYPE_WA)
+					printf(" Write-Alloc");
+				printf("\n");
+			}
+			i++;
+		}
+	} else {
+		/* Print cache info. */
+		if (arm_picache_line_size == 0 && arm_pdcache_line_size == 0)
+			return;
+
+		if (arm_pcache_unified) {
+			printf("  %dKB/%dB %d-way %s unified cache\n",
+			    arm_pdcache_size / 1024,
+			    arm_pdcache_line_size, arm_pdcache_ways,
+			    wtnames[arm_pcache_type]);
+		} else {
+			printf("  %dKB/%dB %d-way instruction cache\n",
+			    arm_picache_size / 1024,
+			    arm_picache_line_size, arm_picache_ways);
+			printf("  %dKB/%dB %d-way %s data cache\n",
+			    arm_pdcache_size / 1024,
+			    arm_pdcache_line_size, arm_pdcache_ways,
+			    wtnames[arm_pcache_type]);
+		}
+	}
+}


Property changes on: trunk/sys/arm/arm/identcpu.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/in_cksum.c
===================================================================
--- trunk/sys/arm/arm/in_cksum.c	                        (rev 0)
+++ trunk/sys/arm/arm/in_cksum.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,153 @@
+/* $MidnightBSD$ */
+/* $NetBSD: in_cksum.c,v 1.7 1997/09/02 13:18:15 thorpej Exp $ */
+
+/*-
+ * Copyright (c) 1988, 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ * Copyright (c) 1996
+ *	Matt Thomas <matt at 3am-software.com>
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ *	@(#)in_cksum.c	8.1 (Berkeley) 6/10/93
+ */
+
+#include <sys/cdefs.h>			/* RCS ID & Copyright macro defns */
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/in_cksum.c 236991 2012-06-13 04:59:55Z imp $");
+
+#include <sys/param.h>
+#include <sys/mbuf.h>
+#include <sys/systm.h>
+#include <netinet/in_systm.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <machine/in_cksum.h>
+
+/*
+ * Checksum routine for Internet Protocol family headers
+ *    (Portable Alpha version).
+ *
+ * This routine is very heavily used in the network
+ * code and should be modified for each CPU to be as fast as possible.
+ */
+
+#define ADDCARRY(x)  (x > 65535 ? x -= 65535 : x)
+#define REDUCE32							  \
+    {									  \
+	q_util.q = sum;							  \
+	sum = q_util.s[0] + q_util.s[1] + q_util.s[2] + q_util.s[3];	  \
+    }
+#define REDUCE16							  \
+    {									  \
+	q_util.q = sum;							  \
+	l_util.l = q_util.s[0] + q_util.s[1] + q_util.s[2] + q_util.s[3]; \
+	sum = l_util.s[0] + l_util.s[1];				  \
+	ADDCARRY(sum);							  \
+    }
+
+union l_util {
+	u_int16_t s[2];
+	u_int32_t l;
+};
+union q_util {
+	u_int16_t s[4];
+	u_int32_t l[2];
+	u_int64_t q;
+};
+
+u_short
+in_addword(u_short a, u_short b)
+{
+	u_int64_t sum = a + b;
+
+	ADDCARRY(sum);
+	return (sum);
+}
+
+static
+uint64_t _do_cksum(void *addr, int len)
+{
+	uint64_t sum;
+	union q_util q_util;
+
+	sum = do_cksum(addr, len);
+	REDUCE32;
+	return (sum);
+}
+
+u_short
+in_cksum_skip(struct mbuf *m, int len, int skip)
+{
+	u_int64_t sum = 0;
+	int mlen = 0;
+	int clen = 0;
+	caddr_t addr;
+	union q_util q_util;
+	union l_util l_util;
+
+        len -= skip;
+        for (; skip && m; m = m->m_next) {
+                if (m->m_len > skip) {
+                        mlen = m->m_len - skip;
+			addr = mtod(m, caddr_t) + skip;
+                        goto skip_start;
+                } else {
+                        skip -= m->m_len;
+                }
+        }
+
+	for (; m && len; m = m->m_next) {
+		if (m->m_len == 0)
+			continue;
+		mlen = m->m_len;
+		addr = mtod(m, caddr_t);
+skip_start:
+		if (len < mlen)
+			mlen = len;
+
+		if ((clen ^ (int) addr) & 1)
+		    sum += _do_cksum(addr, mlen) << 8;
+		else
+		    sum += _do_cksum(addr, mlen);
+
+		clen += mlen;
+		len -= mlen;
+	}
+	REDUCE16;
+	return (~sum & 0xffff);
+}
+
+u_int in_cksum_hdr(const struct ip *ip)
+{
+	u_int64_t sum = do_cksum(ip, sizeof(struct ip));
+	union q_util q_util;
+    	union l_util l_util;
+	REDUCE16;
+	return (~sum & 0xffff);
+}


Property changes on: trunk/sys/arm/arm/in_cksum.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/in_cksum_arm.S
===================================================================
--- trunk/sys/arm/arm/in_cksum_arm.S	                        (rev 0)
+++ trunk/sys/arm/arm/in_cksum_arm.S	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,345 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: in_cksum_arm.S,v 1.2 2003/09/23 10:01:36 scw Exp $	*/
+
+/*-
+ * Copyright 2003 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Steve C. Woodford for Wasabi Systems, Inc.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed for the NetBSD Project by
+ *      Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
+ * 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.
+ *
+ */
+
+/*
+ * Hand-optimised in_cksum() and in4_cksum() implementations for ARM/armv5e
+ */
+
+#include "opt_inet.h"
+
+#include <machine/asm.h>
+#include "assym.s"
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/in_cksum_arm.S 275767 2014-12-14 16:28:53Z andrew $");
+
+	.syntax	unified
+/*
+ * int in_cksum(struct mbuf *m, int len)
+ *
+ * Entry:
+ *	r0	m
+ *	r1	len
+ *
+ * NOTE: Assumes 'm' is *never* NULL.
+ */
+/* LINTSTUB: Func: int in_cksum(struct mbuf *, int) */
+ENTRY(in_cksum)
+	stmfd	sp!, {r4-r11,lr}
+	mov	r8, #0x00
+	mov	r9, r1
+	mov	r10, #0x00
+	mov	ip, r0
+
+.Lin_cksum_loop:
+	ldr	r1, [ip, #(M_LEN)]
+	ldr	r0, [ip, #(M_DATA)]
+	ldr	ip, [ip, #(M_NEXT)]
+.Lin_cksum_entry4:
+	cmp	r9, r1
+	movlt	r1, r9
+	sub	r9, r9, r1
+	eor	r11, r10, r0
+	add	r10, r10, r1
+	adds	r2, r1, #0x00
+	blne	_ASM_LABEL(L_cksumdata)
+	tst	r11, #0x01
+	movne	r2, r2, ror #8
+	adds	r8, r8, r2
+	adc	r8, r8, #0x00
+	cmp	ip, #0x00
+	bne	.Lin_cksum_loop
+
+	mov	r1, #0xff
+	orr	r1, r1, #0xff00
+	and	r0, r8, r1
+	add	r0, r0, r8, lsr #16
+	add	r0, r0, r0, lsr #16
+	and	r0, r0, r1
+	eor	r0, r0, r1
+	ldmfd	sp!, {r4-r11,pc}
+END(in_cksum)
+
+ENTRY(do_cksum)
+	stmfd	sp!, {r4-r7, lr}
+	bl	L_cksumdata
+	mov	r0, r2
+	ldmfd	sp!, {r4-r7, pc}
+END(do_cksum)
+
+/*
+ * The main in*_cksum() workhorse...
+ *
+ * Entry parameters:
+ *	r0	Pointer to buffer
+ *	r1	Buffer length
+ *	lr	Return address
+ *
+ * Returns:
+ *	r2	Accumulated 32-bit sum
+ *
+ * Clobbers:
+ *	r0-r7
+ */
+/* LINTSTUB: Ignore */
+ASENTRY_NP(L_cksumdata)
+#ifdef _ARM_ARCH_5E
+	pld	[r0]			/* Pre-fetch the start of the buffer */
+#endif
+	mov	r2, #0
+
+	/* We first have to word-align the buffer.  */
+	ands	r7, r0, #0x03
+	beq	.Lcksumdata_wordaligned
+	rsb	r7, r7, #0x04
+	cmp	r1, r7			/* Enough bytes left to make it? */
+	blt	.Lcksumdata_endgame
+	cmp	r7, #0x02
+	ldrb	r4, [r0], #0x01		/* Fetch 1st byte */
+	ldrbge	r5, [r0], #0x01		/* Fetch 2nd byte */
+	movlt	r5, #0x00
+	ldrbgt	r6, [r0], #0x01		/* Fetch 3rd byte */
+	movle	r6, #0x00
+	/* Combine the three bytes depending on endianness and alignment */
+#ifdef __ARMEB__
+	orreq	r2, r5, r4, lsl #8
+	orreq	r2, r2, r6, lsl #24
+	orrne	r2, r4, r5, lsl #8
+	orrne	r2, r2, r6, lsl #16
+#else
+	orreq	r2, r4, r5, lsl #8
+	orreq	r2, r2, r6, lsl #16
+	orrne	r2, r5, r4, lsl #8
+	orrne	r2, r2, r6, lsl #24
+#endif
+	subs	r1, r1, r7		/* Update length */
+	RETeq			/* All done? */
+
+	/* Buffer is now word aligned */
+.Lcksumdata_wordaligned:
+#ifdef _ARM_ARCH_5E
+	cmp	r1, #0x04		/* Less than 4 bytes left? */
+	blt	.Lcksumdata_endgame	/* Yup */
+
+	/* Now quad-align, if necessary */
+	ands	r7, r0, #0x04
+	ldrne	r7, [r0], #0x04
+	subne	r1, r1, #0x04
+	subs	r1, r1, #0x40
+	blt	.Lcksumdata_bigloop_end	/* Note: C flag clear if branch taken */
+
+	/*
+	 * Buffer is now quad aligned. Sum 64 bytes at a time.
+	 * Note: First ldrd is hoisted above the loop, together with
+	 * setting r6 to zero to avoid stalling for results in the
+	 * loop. (r7 is live, from above).
+	 */
+	ldrd	r4, [r0], #0x08
+	mov	r6, #0x00
+.Lcksumdata_bigloop:
+	pld	[r0, #0x18]
+	adds	r2, r2, r6
+	adcs	r2, r2, r7
+	ldrd	r6, [r0], #0x08
+	adcs	r2, r2, r4
+	adcs	r2, r2, r5
+	ldrd	r4, [r0], #0x08
+	adcs	r2, r2, r6
+	adcs	r2, r2, r7
+	ldrd	r6, [r0], #0x08
+	adcs	r2, r2, r4
+	adcs	r2, r2, r5
+	ldrd	r4, [r0], #0x08
+	adcs	r2, r2, r6
+	adcs	r2, r2, r7
+	pld	[r0, #0x18]
+	ldrd	r6, [r0], #0x08
+	adcs	r2, r2, r4
+	adcs	r2, r2, r5
+	ldrd	r4, [r0], #0x08
+	adcs	r2, r2, r6
+	adcs	r2, r2, r7
+	ldrd	r6, [r0], #0x08
+	adcs	r2, r2, r4
+	adcs	r2, r2, r5
+	adc	r2, r2, #0x00
+	subs	r1, r1, #0x40
+	ldrdge	r4, [r0], #0x08
+	bge	.Lcksumdata_bigloop
+
+	adds	r2, r2, r6		/* r6/r7 still need summing */
+.Lcksumdata_bigloop_end:
+	adcs	r2, r2, r7
+	adc	r2, r2, #0x00
+
+#else	/* !_ARM_ARCH_5E */
+
+	subs	r1, r1, #0x40
+	blt	.Lcksumdata_bigloop_end
+
+.Lcksumdata_bigloop:
+	ldmia	r0!, {r3, r4, r5, r6}
+	adds	r2, r2, r3
+	adcs	r2, r2, r4
+	adcs	r2, r2, r5
+	ldmia	r0!, {r3, r4, r5, r7}
+	adcs	r2, r2, r6
+	adcs	r2, r2, r3
+	adcs	r2, r2, r4
+	adcs	r2, r2, r5
+	ldmia	r0!, {r3, r4, r5, r6}
+	adcs	r2, r2, r7
+	adcs	r2, r2, r3
+	adcs	r2, r2, r4
+	adcs	r2, r2, r5
+	ldmia	r0!, {r3, r4, r5, r7}
+	adcs	r2, r2, r6
+	adcs	r2, r2, r3
+	adcs	r2, r2, r4
+	adcs	r2, r2, r5
+	adcs	r2, r2, r7
+	adc	r2, r2, #0x00
+	subs	r1, r1, #0x40
+	bge	.Lcksumdata_bigloop
+.Lcksumdata_bigloop_end:
+#endif
+
+	adds	r1, r1, #0x40
+	RETeq
+	cmp	r1, #0x20
+
+#ifdef _ARM_ARCH_5E
+	ldrdge	r4, [r0], #0x08		/* Avoid stalling pld and result */
+	blt	.Lcksumdata_less_than_32
+	pld	[r0, #0x18]
+	ldrd	r6, [r0], #0x08
+	adds	r2, r2, r4
+	adcs	r2, r2, r5
+	ldrd	r4, [r0], #0x08
+	adcs	r2, r2, r6
+	adcs	r2, r2, r7
+	ldrd	r6, [r0], #0x08
+	adcs	r2, r2, r4
+	adcs	r2, r2, r5
+	adcs	r2, r2, r6		/* XXX: Unavoidable result stall */
+	adcs	r2, r2, r7
+#else
+	blt	.Lcksumdata_less_than_32
+	ldmia	r0!, {r3, r4, r5, r6}
+	adds	r2, r2, r3
+	adcs	r2, r2, r4
+	adcs	r2, r2, r5
+	ldmia	r0!, {r3, r4, r5, r7}
+	adcs	r2, r2, r6
+	adcs	r2, r2, r3
+	adcs	r2, r2, r4
+	adcs	r2, r2, r5
+	adcs	r2, r2, r7
+#endif
+	adc	r2, r2, #0x00
+	subs	r1, r1, #0x20
+	RETeq
+
+.Lcksumdata_less_than_32:
+	/* There are less than 32 bytes left */
+	and	r3, r1, #0x18
+	rsb	r4, r3, #0x18
+	sub	r1, r1, r3
+	adds	r4, r4, r4, lsr #1	/* Side effect: Clear carry flag */
+	addne	pc, pc, r4
+	nop
+
+/*
+ * Note: We use ldm here, even on armv5e, since the combined issue/result
+ * latencies for ldm and ldrd are the same. Using ldm avoids needless #ifdefs.
+ */
+	/* At least 24 bytes remaining... */
+	ldmia	r0!, {r4, r5}
+	adcs	r2, r2, r4
+	adcs	r2, r2, r5
+
+	/* At least 16 bytes remaining... */
+	ldmia	r0!, {r4, r5}
+	adcs	r2, r2, r4
+	adcs	r2, r2, r5
+
+	/* At least 8 bytes remaining... */
+	ldmia	r0!, {r4, r5}
+	adcs	r2, r2, r4
+	adcs	r2, r2, r5
+
+	/* Less than 8 bytes remaining... */
+	adc	r2, r2, #0x00
+	subs	r1, r1, #0x04
+	blt	.Lcksumdata_lessthan4
+
+	ldr	r4, [r0], #0x04
+	sub	r1, r1, #0x04
+	adds	r2, r2, r4
+	adc	r2, r2, #0x00
+
+	/* Deal with < 4 bytes remaining */
+.Lcksumdata_lessthan4:
+	adds	r1, r1, #0x04
+	RETeq
+
+	/* Deal with 1 to 3 remaining bytes, possibly misaligned */
+.Lcksumdata_endgame:
+	ldrb	r3, [r0]		/* Fetch first byte */
+	cmp	r1, #0x02
+	ldrbge	r4, [r0, #0x01]		/* Fetch 2nd and 3rd as necessary */
+	movlt	r4, #0x00
+	ldrbgt	r5, [r0, #0x02]
+	movle	r5, #0x00
+	/* Combine the three bytes depending on endianness and alignment */
+	tst	r0, #0x01
+#ifdef __ARMEB__
+	orreq	r3, r4, r3, lsl #8
+	orreq	r3, r3, r5, lsl #24
+	orrne	r3, r3, r4, lsl #8
+	orrne	r3, r3, r5, lsl #16
+#else
+	orreq	r3, r3, r4, lsl #8
+	orreq	r3, r3, r5, lsl #16
+	orrne	r3, r4, r3, lsl #8
+	orrne	r3, r3, r5, lsl #24
+#endif
+	adds	r2, r2, r3
+	adc	r2, r2, #0x00
+	RET
+END(L_cksumdata)
+


Property changes on: trunk/sys/arm/arm/in_cksum_arm.S
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/inckern.S
===================================================================
--- trunk/sys/arm/arm/inckern.S	                        (rev 0)
+++ trunk/sys/arm/arm/inckern.S	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,43 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2005 Olivier Houchard.  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 ``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 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_kernname.h"
+
+#include <machine/asm.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/inckern.S 159557 2006-06-12 22:58:50Z cognet $")
+ENTRY(do_call)
+	mov	r6, r0
+	mov	r0, r1
+	ldr	r1, =0xfff00000
+	and	r1, pc, r1
+	mov	sp, r3
+	mov	r3, #1
+	mov	pc, r6
+.section ".real_kernel","aw"
+.globl kernel_start;
+kernel_start:
+.incbin KERNNAME
+.globl kernel_end;
+kernel_end:


Property changes on: trunk/sys/arm/arm/inckern.S
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/intr.c
===================================================================
--- trunk/sys/arm/arm/intr.c	                        (rev 0)
+++ trunk/sys/arm/arm/intr.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,219 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: intr.c,v 1.12 2003/07/15 00:24:41 lukem Exp $	*/
+
+/*-
+ * Copyright (c) 2004 Olivier Houchard.
+ * Copyright (c) 1994-1998 Mark Brinicombe.
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Mark Brinicombe
+ *	for the NetBSD Project.
+ * 4. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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.
+ *
+ * Soft interrupt and other generic interrupt functions.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/intr.c 270077 2014-08-17 01:48:12Z ian $");
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/syslog.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/proc.h>
+#include <sys/bus.h>
+#include <sys/interrupt.h>
+#include <sys/conf.h>
+#include <machine/atomic.h>
+#include <machine/intr.h>
+#include <machine/cpu.h>
+
+#define	INTRNAME_LEN	(MAXCOMLEN + 1)
+
+typedef void (*mask_fn)(void *);
+
+static struct intr_event *intr_events[NIRQ];
+
+void	arm_irq_handler(struct trapframe *);
+
+void (*arm_post_filter)(void *) = NULL;
+int (*arm_config_irq)(int irq, enum intr_trigger trig,
+    enum intr_polarity pol) = NULL;
+
+/* Data for statistics reporting. */
+u_long intrcnt[NIRQ];
+char intrnames[NIRQ * INTRNAME_LEN];
+size_t sintrcnt = sizeof(intrcnt);
+size_t sintrnames = sizeof(intrnames);
+
+/*
+ * Pre-format intrnames into an array of fixed-size strings containing spaces.
+ * This allows us to avoid the need for an intermediate table of indices into
+ * the names and counts arrays, while still meeting the requirements and
+ * assumptions of vmstat(8) and the kdb "show intrcnt" command, the two
+ * consumers of this data.
+ */
+static void
+intr_init(void *unused)
+{
+	int i;
+
+	for (i = 0; i < NIRQ; ++i) {
+		snprintf(&intrnames[i * INTRNAME_LEN], INTRNAME_LEN, "%-*s",
+		    INTRNAME_LEN - 1, "");
+	}
+}
+
+SYSINIT(intr_init, SI_SUB_INTR, SI_ORDER_FIRST, intr_init, NULL);
+
+void
+arm_setup_irqhandler(const char *name, driver_filter_t *filt,
+    void (*hand)(void*), void *arg, int irq, int flags, void **cookiep)
+{
+	struct intr_event *event;
+	int error;
+
+	if (irq < 0 || irq >= NIRQ)
+		return;
+	event = intr_events[irq];
+	if (event == NULL) {
+		error = intr_event_create(&event, (void *)irq, 0, irq,
+		    (mask_fn)arm_mask_irq, (mask_fn)arm_unmask_irq,
+		    arm_post_filter, NULL, "intr%d:", irq);
+		if (error)
+			return;
+		intr_events[irq] = event;
+		snprintf(&intrnames[irq * INTRNAME_LEN], INTRNAME_LEN, 
+		    "irq%d: %-*s", irq, INTRNAME_LEN - 1, name);
+	}
+	intr_event_add_handler(event, name, filt, hand, arg,
+	    intr_priority(flags), flags, cookiep);
+}
+
+int
+arm_remove_irqhandler(int irq, void *cookie)
+{
+	struct intr_event *event;
+	int error;
+
+	event = intr_events[irq];
+	arm_mask_irq(irq);
+	
+	error = intr_event_remove_handler(cookie);
+
+	if (!TAILQ_EMPTY(&event->ie_handlers))
+		arm_unmask_irq(irq);
+	return (error);
+}
+
+void dosoftints(void);
+void
+dosoftints(void)
+{
+}
+
+void
+arm_irq_handler(struct trapframe *frame)
+{
+	struct intr_event *event;
+	int i;
+
+	PCPU_INC(cnt.v_intr);
+	i = -1;
+	while ((i = arm_get_next_irq(i)) != -1) {
+		intrcnt[i]++;
+		event = intr_events[i];
+		if (intr_event_handle(event, frame) != 0) {
+			/* XXX: Log stray IRQs */
+			arm_mask_irq(i);
+		}
+	}
+}
+
+/*
+ * arm_irq_memory_barrier()
+ *
+ * Ensure all writes to device memory have reached devices before proceeding.
+ *
+ * This is intended to be called from the post-filter and post-thread routines
+ * of an interrupt controller implementation.  A peripheral device driver should
+ * use bus_space_barrier() if it needs to ensure a write has reached the
+ * hardware for some reason other than clearing interrupt conditions.
+ *
+ * The need for this function arises from the ARM weak memory ordering model.
+ * Writes to locations mapped with the Device attribute bypass any caches, but
+ * are buffered.  Multiple writes to the same device will be observed by that
+ * device in the order issued by the cpu.  Writes to different devices may
+ * appear at those devices in a different order than issued by the cpu.  That
+ * is, if the cpu writes to device A then device B, the write to device B could
+ * complete before the write to device A.
+ *
+ * Consider a typical device interrupt handler which services the interrupt and
+ * writes to a device status-acknowledge register to clear the interrupt before
+ * returning.  That write is posted to the L2 controller which "immediately"
+ * places it in a store buffer and automatically drains that buffer.  This can
+ * be less immediate than you'd think... There may be no free slots in the store
+ * buffers, so an existing buffer has to be drained first to make room.  The
+ * target bus may be busy with other traffic (such as DMA for various devices),
+ * delaying the drain of the store buffer for some indeterminate time.  While
+ * all this delay is happening, execution proceeds on the CPU, unwinding its way
+ * out of the interrupt call stack to the point where the interrupt driver code
+ * is ready to EOI and unmask the interrupt.  The interrupt controller may be
+ * accessed via a faster bus than the hardware whose handler just ran; the write
+ * to unmask and EOI the interrupt may complete quickly while the device write
+ * to ack and clear the interrupt source is still lingering in a store buffer
+ * waiting for access to a slower bus.  With the interrupt unmasked at the
+ * interrupt controller but still active at the device, as soon as interrupts
+ * are enabled on the core the device re-interrupts immediately: now you've got
+ * a spurious interrupt on your hands.
+ *
+ * The right way to fix this problem is for every device driver to use the
+ * proper bus_space_barrier() calls in its interrupt handler.  For ARM a single
+ * barrier call at the end of the handler would work.  This would have to be
+ * done to every driver in the system, not just arm-specific drivers.
+ *
+ * Another potential fix is to map all device memory as Strongly-Ordered rather
+ * than Device memory, which takes the store buffers out of the picture.  This
+ * has a pretty big impact on overall system performance, because each strongly
+ * ordered memory access causes all L2 store buffers to be drained.
+ *
+ * A compromise solution is to have the interrupt controller implementation call
+ * this function to establish a barrier between writes to the interrupt-source
+ * device and writes to the interrupt controller device.
+ *
+ * This takes the interrupt number as an argument, and currently doesn't use it.
+ * The plan is that maybe some day there is a way to flag certain interrupts as
+ * "memory barrier safe" and we can avoid this overhead with them.
+ */
+void
+arm_irq_memory_barrier(uintptr_t irq)
+{
+
+	dsb();
+	cpu_l2cache_drain_writebuf();
+}
+


Property changes on: trunk/sys/arm/arm/intr.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/locore-v4.S
===================================================================
--- trunk/sys/arm/arm/locore-v4.S	                        (rev 0)
+++ trunk/sys/arm/arm/locore-v4.S	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,484 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: locore.S,v 1.14 2003/04/20 16:21:40 thorpej Exp $	*/
+
+/*-
+ * Copyright 2011 Semihalf
+ * Copyright (C) 1994-1997 Mark Brinicombe
+ * Copyright (C) 1994 Brini
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Brini.
+ * 4. The name of Brini may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BRINI ``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 BRINI 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 "assym.s"
+#include <sys/syscall.h>
+#include <machine/asm.h>
+#include <machine/armreg.h>
+#include <machine/cpuconf.h>
+#include <machine/pte.h>
+
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/locore-v4.S 294682 2016-01-24 20:15:52Z ian $");
+
+/* 2K initial stack is plenty, it is only used by initarm() */
+#define INIT_ARM_STACK_SIZE	2048
+
+#define	CPWAIT_BRANCH							 \
+	sub	pc, pc, #4
+
+#define	CPWAIT(tmp)							 \
+	mrc	p15, 0, tmp, c2, c0, 0	/* arbitrary read of CP15 */	;\
+	mov	tmp, tmp		/* wait for it to complete */	;\
+	CPWAIT_BRANCH			/* branch to next insn */
+
+/*
+ * This is for libkvm, and should be the address of the beginning
+ * of the kernel text segment (not necessarily the same as kernbase).
+ *
+ * These are being phased out. Newer copies of libkvm don't need these
+ * values as the information is added to the core file by inspecting
+ * the running kernel.
+ */
+	.text
+	.align	2
+#ifdef PHYSADDR
+.globl kernbase
+.set kernbase,KERNBASE
+.globl physaddr
+.set physaddr,PHYSADDR
+#endif
+
+/*
+ * On entry for FreeBSD boot ABI:
+ *	r0 - metadata pointer or 0 (boothowto on AT91's boot2)
+ *	r1 - if (r0 == 0) then metadata pointer
+ * On entry for Linux boot ABI:
+ *	r0 - 0
+ *	r1 - machine type (passed as arg2 to initarm)
+ *	r2 - Pointer to a tagged list or dtb image (phys addr) (passed as arg1 initarm)
+ *
+ * For both types of boot we gather up the args, put them in a struct arm_boot_params
+ * structure and pass that to initarm.
+ */
+	.globl	btext
+btext:
+ASENTRY_NP(_start)
+	STOP_UNWINDING		/* Can't unwind into the bootloader! */
+
+	mov	r9, r0		/* 0 or boot mode from boot2 */
+	mov	r8, r1		/* Save Machine type */
+	mov	ip, r2		/* Save meta data */
+	mov	fp, r3		/* Future expansion */
+
+	/* Make sure interrupts are disabled. */
+	mrs	r7, cpsr
+	orr	r7, r7, #(PSR_I | PSR_F)
+	msr	cpsr_c, r7
+
+#if defined (FLASHADDR) && defined(LOADERRAMADDR)
+/*
+ * Sanity check the configuration.
+ * FLASHADDR and LOADERRAMADDR depend on PHYSADDR in some cases.
+ * ARMv4 and ARMv5 make assumptions on where they are loaded.
+ * TODO: Fix the ARMv4/v5 case.
+ */
+#ifndef PHYSADDR
+#error PHYSADDR must be defined for this configuration
+#endif
+
+	/* Check if we're running from flash. */
+	ldr	r7, =FLASHADDR
+	/*
+	 * If we're running with MMU disabled, test against the
+	 * physical address instead.
+	 */
+	mrc	p15, 0, r2, c1, c0, 0
+	ands	r2, r2, #CPU_CONTROL_MMU_ENABLE
+	ldreq	r6, =PHYSADDR
+	ldrne	r6, =LOADERRAMADDR
+	cmp	r7, r6
+	bls 	flash_lower
+	cmp	r7, pc
+	bhi	from_ram
+	b	do_copy
+
+flash_lower:
+	cmp	r6, pc
+	bls	from_ram
+do_copy:
+	ldr	r7, =KERNBASE
+	adr	r1, _start
+	ldr	r0, Lreal_start
+	ldr	r2, Lend
+	sub	r2, r2, r0
+	sub	r0, r0, r7
+	add	r0, r0, r6
+	mov	r4, r0
+	bl	memcpy
+	ldr	r0, Lram_offset
+	add	pc, r4, r0
+Lram_offset:	.word from_ram-_C_LABEL(_start)
+from_ram:
+	nop
+#endif
+
+disable_mmu:
+	/* Disable MMU for a while */
+	mrc	p15, 0, r2, c1, c0, 0
+	bic	r2, r2, #(CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_DC_ENABLE |\
+	    CPU_CONTROL_WBUF_ENABLE)
+	bic	r2, r2, #(CPU_CONTROL_IC_ENABLE)
+	bic	r2, r2, #(CPU_CONTROL_BPRD_ENABLE)
+	mcr	p15, 0, r2, c1, c0, 0
+
+	nop
+	nop
+	nop
+	CPWAIT(r0)
+
+Lunmapped:
+	/*
+	 * Build page table from scratch.
+	 */
+
+	/* 
+	 * Figure out the physical address we're loaded at by assuming this
+	 * entry point code is in the first L1 section and so if we clear the
+	 * offset bits of the pc that will give us the section-aligned load
+	 * address, which remains in r5 throughout all the following code.
+	 */
+	ldr	r2, =(L1_S_OFFSET)
+	bic	r5, pc, r2
+
+	/* Find the delta between VA and PA, result stays in r0 throughout. */
+	adr	r0, Lpagetable
+	bl	translate_va_to_pa
+
+	/* 
+	 * First map the entire 4GB address space as VA=PA.  It's mapped as
+	 * normal (cached) memory because it's for things like accessing the
+	 * parameters passed in from the bootloader, which might be at any
+	 * physical address, different for every platform.
+	 */
+	mov	r1, #0
+	mov	r2, #0
+	mov	r3, #4096
+	bl	build_pagetables
+
+	/* 
+	 * Next we do 64MiB starting at the physical load address, mapped to
+	 * the VA the kernel is linked for.
+	 */
+	mov	r1, r5
+	ldr	r2, =(KERNVIRTADDR)
+	mov	r3, #64
+	bl	build_pagetables
+
+	/* Create a device mapping for early_printf if specified. */
+#if defined(SOCDEV_PA) && defined(SOCDEV_VA)
+	ldr	r1, =SOCDEV_PA
+	ldr	r2, =SOCDEV_VA
+	mov	r3, #1
+	bl	build_device_pagetables
+#endif
+
+	mcr	p15, 0, r0, c2, c0, 0	/* Set TTB */
+	mcr	p15, 0, r0, c8, c7, 0	/* Flush TLB */
+
+	/* Set the Domain Access register.  Very important! */
+	mov	r0, #((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT)
+	mcr	p15, 0, r0, c3, c0, 0
+	/*
+	 * Enable MMU.
+	 */
+	mrc	p15, 0, r0, c1, c0, 0
+	orr	r0, r0, #(CPU_CONTROL_MMU_ENABLE)
+	mcr	p15, 0, r0, c1, c0, 0
+	nop
+	nop
+	nop
+	CPWAIT(r0)
+
+	/* Transition the PC from physical to virtual addressing. */
+	ldr	pc,=mmu_done
+
+mmu_done:
+	nop
+	adr	r1, .Lstart
+	ldmia	r1, {r1, r2, sp}	/* Set initial stack and */
+	sub	r2, r2, r1		/* get zero init data */
+	mov	r3, #0
+.L1:
+	str	r3, [r1], #0x0004	/* get zero init data */
+	subs	r2, r2, #4
+	bgt	.L1
+
+virt_done:
+	mov	r1, #28			/* loader info size is 28 bytes also second arg */
+	subs	sp, sp, r1		/* allocate arm_boot_params struct on stack */
+	mov	r0, sp			/* loader info pointer is first arg */
+	bic	sp, sp, #7		/* align stack to 8 bytes */
+	str	r1, [r0]		/* Store length of loader info */
+	str	r9, [r0, #4]		/* Store r0 from boot loader */
+	str	r8, [r0, #8]		/* Store r1 from boot loader */
+	str	ip, [r0, #12]		/* store r2 from boot loader */
+	str	fp, [r0, #16]		/* store r3 from boot loader */
+	str	r5, [r0, #20]		/* store the physical address */
+	adr	r4, Lpagetable		/* load the pagetable address */
+	ldr	r5, [r4, #4]
+	str	r5, [r0, #24]		/* store the pagetable address */
+	mov	fp, #0			/* trace back starts here */
+	bl	_C_LABEL(initarm)	/* Off we go */
+
+	/* init arm will return the new stack pointer. */
+	mov	sp, r0
+
+	bl	_C_LABEL(mi_startup)	/* call mi_startup()! */
+
+	adr	r0, .Lmainreturned
+	b	_C_LABEL(panic)
+	/* NOTREACHED */
+END(_start)
+
+#define VA_TO_PA_POINTER(name, table)	 \
+name:					;\
+	.word	.			;\
+	.word	table
+
+/*
+ * Returns the physical address of a magic va to pa pointer.
+ * r0     - The pagetable data pointer. This must be built using the
+ *          VA_TO_PA_POINTER macro.
+ *          e.g.
+ *            VA_TO_PA_POINTER(Lpagetable, pagetable)
+ *            ...
+ *            adr  r0, Lpagetable
+ *            bl   translate_va_to_pa
+ *            r0 will now contain the physical address of pagetable
+ * r1, r2 - Trashed
+ */
+translate_va_to_pa:
+	ldr	r1, [r0]
+	sub	r2, r1, r0
+	/* At this point: r2 = VA - PA */
+
+	/*
+	 * Find the physical address of the table. After these two
+	 * instructions:
+	 * r1 = va(pagetable)
+	 *
+	 * r0 = va(pagetable) - (VA - PA)
+	 *    = va(pagetable) - VA + PA
+	 *    = pa(pagetable)
+	 */
+	ldr	r1, [r0, #4]
+	sub	r0, r1, r2
+	RET
+
+/*
+ * Builds the page table
+ * r0 - The table base address
+ * r1 - The physical address (trashed)
+ * r2 - The virtual address (trashed)
+ * r3 - The number of 1MiB sections
+ * r4 - Trashed
+ *
+ * Addresses must be 1MiB aligned
+ */
+build_device_pagetables:
+	ldr	r4, =(L1_TYPE_S|L1_S_AP(AP_KRW))
+	b	1f
+build_pagetables:
+	/* Set the required page attributed */
+	ldr	r4, =(L1_TYPE_S|L1_S_C|L1_S_AP(AP_KRW))
+1:
+	orr	r1, r4
+
+	/* Move the virtual address to the correct bit location */
+	lsr	r2, #(L1_S_SHIFT - 2)
+
+	mov	r4, r3
+2:
+	str	r1, [r0, r2]
+	add	r2, r2, #4
+	add	r1, r1, #(L1_S_SIZE)
+	adds	r4, r4, #-1
+	bhi	2b
+
+	RET
+
+VA_TO_PA_POINTER(Lpagetable, pagetable)
+
+Lreal_start:
+	.word	_start
+Lend:
+	.word	_edata
+
+.Lstart:
+	.word	_edata
+	.word	_ebss
+	.word	svcstk + INIT_ARM_STACK_SIZE
+
+.Lvirt_done:
+	.word	virt_done
+
+.Lmainreturned:
+	.asciz	"main() returned"
+	.align	2
+
+	.bss
+svcstk:
+	.space	INIT_ARM_STACK_SIZE
+
+/*
+ * Memory for the initial pagetable. We are unable to place this in
+ * the bss as this will be cleared after the table is loaded.
+ */
+	.section ".init_pagetable"
+	.align	14 /* 16KiB aligned */
+pagetable:
+	.space	L1_TABLE_SIZE
+
+	.text
+	.align	2
+
+.Lcpufuncs:
+	.word	_C_LABEL(cpufuncs)
+
+ENTRY_NP(cpu_halt)
+	mrs	r2, cpsr
+	bic	r2, r2, #(PSR_MODE)
+	orr	r2, r2, #(PSR_SVC32_MODE)
+	orr	r2, r2, #(PSR_I | PSR_F)
+	msr	cpsr_fsxc, r2
+
+	ldr	r4, .Lcpu_reset_address
+	ldr	r4, [r4]
+
+	ldr	r0, .Lcpufuncs
+	mov	lr, pc
+	ldr	pc, [r0, #CF_IDCACHE_WBINV_ALL]
+	mov	lr, pc
+	ldr	pc, [r0, #CF_L2CACHE_WBINV_ALL]
+
+	/*
+	 * Load the cpu_reset_needs_v4_MMU_disable flag to determine if it's
+	 * necessary.
+	 */
+
+	ldr	r1, .Lcpu_reset_needs_v4_MMU_disable
+	ldr	r1, [r1]
+	cmp	r1, #0
+	mov	r2, #0
+
+	/*
+	 * MMU & IDC off, 32 bit program & data space
+	 * Hurl ourselves into the ROM
+	 */
+	mov	r0, #(CPU_CONTROL_32BP_ENABLE | CPU_CONTROL_32BD_ENABLE)
+	mcr	p15, 0, r0, c1, c0, 0
+	mcrne	p15, 0, r2, c8, c7, 0 	/* nail I+D TLB on ARMv4 and greater */
+	mov	pc, r4
+
+	/*
+	 * _cpu_reset_address contains the address to branch to, to complete
+	 * the cpu reset after turning the MMU off
+	 * This variable is provided by the hardware specific code
+	 */
+.Lcpu_reset_address:
+	.word	_C_LABEL(cpu_reset_address)
+
+	/*
+	 * cpu_reset_needs_v4_MMU_disable contains a flag that signals if the
+	 * v4 MMU disable instruction needs executing... it is an illegal instruction
+	 * on f.e. ARM6/7 that locks up the computer in an endless illegal
+	 * instruction / data-abort / reset loop.
+	 */
+.Lcpu_reset_needs_v4_MMU_disable:
+	.word	_C_LABEL(cpu_reset_needs_v4_MMU_disable)
+END(cpu_halt)
+
+
+/*
+ * setjump + longjmp
+ */
+ENTRY(setjmp)
+	stmia	r0, {r4-r14}
+	mov	r0, #0x00000000
+	RET
+END(setjmp)
+
+ENTRY(longjmp)
+	ldmia	r0, {r4-r14}
+	mov	r0, #0x00000001
+	RET
+END(longjmp)
+
+	.data
+	.global	_C_LABEL(esym)
+_C_LABEL(esym):	.word	_C_LABEL(end)
+
+ENTRY_NP(abort)
+	b	_C_LABEL(abort)
+END(abort)
+
+ENTRY_NP(sigcode)
+	mov	r0, sp
+	add	r0, r0, #SIGF_UC
+
+	/*
+	 * Call the sigreturn system call.
+	 *
+	 * We have to load r7 manually rather than using
+	 * "ldr r7, =SYS_sigreturn" to ensure the value of szsigcode is
+	 * correct. Using the alternative places esigcode at the address
+	 * of the data rather than the address one past the data.
+	 */
+
+	ldr	r7, [pc, #12]	/* Load SYS_sigreturn */
+	swi	SYS_sigreturn
+
+	/* Well if that failed we better exit quick ! */
+
+	ldr	r7, [pc, #8]	/* Load SYS_exit */
+	swi	SYS_exit
+
+	/* Branch back to retry SYS_sigreturn */
+	b	. - 16
+END(sigcode)
+	.word	SYS_sigreturn
+	.word	SYS_exit
+
+	.align	2
+	.global _C_LABEL(esigcode)
+		_C_LABEL(esigcode):
+
+	.data
+	.global szsigcode
+szsigcode:
+	.long esigcode-sigcode
+
+/* End of locore.S */


Property changes on: trunk/sys/arm/arm/locore-v4.S
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/locore-v6.S
===================================================================
--- trunk/sys/arm/arm/locore-v6.S	                        (rev 0)
+++ trunk/sys/arm/arm/locore-v6.S	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,567 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright 2004-2014 Olivier Houchard <cognet at FreeBSD.org>
+ * Copyright 2012-2014 Ian Lepore <ian at FreeBSD.org>
+ * Copyright 2013-2014 Andrew Turner <andrew at FreeBSD.org>
+ * Copyright 2014 Svatopluk Kraus <onwahe at gmail.com>
+ * Copyright 2014 Michal Meloun <meloun at miracle.cz>
+ * 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 "assym.s"
+#include <sys/syscall.h>
+#include <machine/asm.h>
+#include <machine/asmacros.h>
+#include <machine/armreg.h>
+#include <machine/sysreg.h>
+#include <machine/cpuconf.h>
+#include <machine/pte.h>
+
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/locore-v6.S 294682 2016-01-24 20:15:52Z ian $");
+
+#ifndef ARM_NEW_PMAP
+#define	PTE1_OFFSET	L1_S_OFFSET
+#define	PTE1_SHIFT	L1_S_SHIFT
+#define	PTE1_SIZE	L1_S_SIZE
+#endif
+
+/* A small statically-allocated stack used only during initarm() and AP startup. */
+#define	INIT_ARM_STACK_SIZE	2048
+
+	.text
+	.align	2
+
+/*
+ * On entry for FreeBSD boot ABI:
+ *	r0 - metadata pointer or 0 (boothowto on AT91's boot2)
+ *	r1 - if (r0 == 0) then metadata pointer
+ * On entry for Linux boot ABI:
+ *	r0 - 0
+ *	r1 - machine type (passed as arg2 to initarm)
+ *	r2 - Pointer to a tagged list or dtb image (phys addr) (passed as arg1 initarm)
+ *
+ * For both types of boot we gather up the args, put them in a struct arm_boot_params
+ * structure and pass that to initarm.
+ */
+	.globl	btext
+btext:
+ASENTRY_NP(_start)
+	STOP_UNWINDING		/* Can't unwind into the bootloader! */
+
+	/* Make sure interrupts are disabled. */
+	cpsid	ifa
+
+	mov	r8, r0		/* 0 or boot mode from boot2 */
+	mov	r9, r1		/* Save Machine type */
+	mov	r10, r2		/* Save meta data */
+	mov	r11, r3		/* Future expansion */
+
+	/*
+	 * Check whether data cache is enabled.  If it is, then we know
+	 * current tags are valid (not power-on garbage values) and there
+	 * might be dirty lines that need cleaning.  Disable cache to prevent
+	 * new lines being allocated, then call wbinv_poc_all to clean it.
+	 */
+	mrc	CP15_SCTLR(r7)
+	tst	r7, #CPU_CONTROL_DC_ENABLE
+	blne	dcache_wbinv_poc_all
+
+	/* ! Do not write to memory between wbinv and disabling cache ! */
+
+	/*
+	 * Now there are no dirty lines, but there may still be lines marked
+	 * valid.  Disable all caches and the MMU, and invalidate everything
+	 * before setting up new page tables and re-enabling the mmu.
+	 */
+1:
+	bic	r7, #CPU_CONTROL_DC_ENABLE
+	bic	r7, #CPU_CONTROL_MMU_ENABLE
+	bic	r7, #CPU_CONTROL_IC_ENABLE
+	bic	r7, #CPU_CONTROL_UNAL_ENABLE
+	bic	r7, #CPU_CONTROL_BPRD_ENABLE
+	bic	r7, #CPU_CONTROL_SW_ENABLE
+	orr	r7, #CPU_CONTROL_AFLT_ENABLE
+	orr	r7, #CPU_CONTROL_VECRELOC
+	mcr	CP15_SCTLR(r7)
+	DSB
+	ISB
+	bl	dcache_inv_poc_all
+	mcr	CP15_ICIALLU
+	DSB
+	ISB
+
+	/*
+	 * Build page table from scratch.
+	 */
+
+	/* 
+	 * Figure out the physical address we're loaded at by assuming this
+	 * entry point code is in the first L1 section and so if we clear the
+	 * offset bits of the pc that will give us the section-aligned load
+	 * address, which remains in r5 throughout all the following code.
+	 */
+	ldr	r2, =(L1_S_OFFSET)
+	bic	r5, pc, r2
+
+	/* Find the delta between VA and PA, result stays in r0 throughout. */
+	adr	r0, Lpagetable
+	bl	translate_va_to_pa
+
+	/* 
+	 * First map the entire 4GB address space as VA=PA.  It's mapped as
+	 * normal (cached) memory because it's for things like accessing the
+	 * parameters passed in from the bootloader, which might be at any
+	 * physical address, different for every platform.
+	 */
+	mov	r1, #0
+	mov	r2, #0
+	mov	r3, #4096
+	bl	build_pagetables
+
+	/* 
+	 * Next we do 64MiB starting at the physical load address, mapped to
+	 * the VA the kernel is linked for.
+	 */
+	mov	r1, r5
+	ldr	r2, =(KERNVIRTADDR)
+	mov	r3, #64
+	bl	build_pagetables
+
+	/* Create a device mapping for early_printf if specified. */
+#if defined(SOCDEV_PA) && defined(SOCDEV_VA)
+	ldr	r1, =SOCDEV_PA
+	ldr	r2, =SOCDEV_VA
+	mov	r3, #1
+	bl	build_device_pagetables
+#endif
+	bl	init_mmu
+
+	/* Transition the PC from physical to virtual addressing. */
+	ldr	pc, =1f
+1:
+
+	/* Setup stack, clear BSS */
+	ldr	r1, =.Lstart
+	ldmia	r1, {r1, r2, sp}	/* Set initial stack and */
+	add	sp, sp,	#INIT_ARM_STACK_SIZE
+	sub	r2, r2, r1		/* get zero init data */
+	mov	r3, #0
+2:
+	str	r3, [r1], #0x0004	/* get zero init data */
+	subs	r2, r2, #4
+	bgt	2b
+
+	mov	r1, #28			/* loader info size is 28 bytes also second arg */
+	subs	sp, sp, r1		/* allocate arm_boot_params struct on stack */
+	mov	r0, sp			/* loader info pointer is first arg */
+	bic	sp, sp, #7		/* align stack to 8 bytes */
+	str	r1, [r0]		/* Store length of loader info */
+	str	r8, [r0, #4]		/* Store r0 from boot loader */
+	str	r9, [r0, #8]		/* Store r1 from boot loader */
+	str	r10, [r0, #12]		/* store r2 from boot loader */
+	str	r11, [r0, #16]		/* store r3 from boot loader */
+	str	r5, [r0, #20]		/* store the physical address */
+	adr	r4, Lpagetable		/* load the pagetable address */
+	ldr	r5, [r4, #4]
+	str	r5, [r0, #24]		/* store the pagetable address */
+	mov	fp, #0			/* trace back starts here */
+	bl	_C_LABEL(initarm)	/* Off we go */
+
+	/* init arm will return the new stack pointer. */
+	mov	sp, r0
+
+	bl	_C_LABEL(mi_startup)	/* call mi_startup()! */
+
+	ldr	r0, =.Lmainreturned
+	b	_C_LABEL(panic)
+	/* NOTREACHED */
+END(_start)
+
+#define VA_TO_PA_POINTER(name, table)	 \
+name:					;\
+	.word	.			;\
+	.word	table
+
+/*
+ * Returns the physical address of a magic va to pa pointer.
+ * r0     - The pagetable data pointer. This must be built using the
+ *          VA_TO_PA_POINTER macro.
+ *          e.g.
+ *            VA_TO_PA_POINTER(Lpagetable, pagetable)
+ *            ...
+ *            adr  r0, Lpagetable
+ *            bl   translate_va_to_pa
+ *            r0 will now contain the physical address of pagetable
+ * r1, r2 - Trashed
+ */
+translate_va_to_pa:
+	ldr	r1, [r0]
+	sub	r2, r1, r0
+	/* At this point: r2 = VA - PA */
+
+	/*
+	 * Find the physical address of the table. After these two
+	 * instructions:
+	 * r1 = va(pagetable)
+	 *
+	 * r0 = va(pagetable) - (VA - PA)
+	 *    = va(pagetable) - VA + PA
+	 *    = pa(pagetable)
+	 */
+	ldr	r1, [r0, #4]
+	sub	r0, r1, r2
+	mov	pc, lr
+
+/*
+ * Init MMU
+ * r0 - the table base address
+ */
+
+ASENTRY_NP(init_mmu)
+
+	/* Setup TLB and MMU registers */
+	mcr	CP15_TTBR0(r0)		/* Set TTB */
+	mov	r0, #0
+	mcr	CP15_CONTEXTIDR(r0)	/* Set ASID to 0 */
+
+	/* Set the Domain Access register */
+	mov	r0, #((DOMAIN_CLIENT <<	(PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT)
+	mcr	CP15_DACR(r0)
+
+#ifdef ARM_NEW_PMAP
+	/*
+	 * Set TEX remap registers
+	 *  - All is set to uncacheable memory
+	 */
+	ldr	r0, =0xAAAAA
+	mrc	CP15_PRRR(r0)
+	mov	r0, #0
+	mcr	CP15_NMRR(r0)
+#endif
+	mcr	CP15_TLBIALL		/* Flush TLB */
+	DSB
+	ISB
+
+	/* Enable MMU */
+	mrc	CP15_SCTLR(r0)
+	orr	r0, r0,	#CPU_CONTROL_MMU_ENABLE
+	orr	r0, r0,	#CPU_CONTROL_V6_EXTPAGE
+#ifdef ARM_NEW_PMAP
+	orr	r0, r0,	#CPU_CONTROL_TR_ENABLE
+#endif
+	orr	r0, r0,	#CPU_CONTROL_AF_ENABLE
+	mcr	CP15_SCTLR(r0)
+	DSB
+	ISB
+	mcr	CP15_TLBIALL		/* Flush TLB */
+	mcr	CP15_BPIALL		/* Flush Branch predictor */
+	DSB
+	ISB
+
+	mov	pc, lr
+END(init_mmu)
+
+
+/*
+ * Init SMP coherent mode, enable caching and switch to final MMU table.
+ * Called with disabled caches
+ * r0 - The table base address
+ * r1 - clear bits for aux register
+ * r2 - set bits for aux register
+ */
+ASENTRY_NP(reinit_mmu)
+	push	{r4-r11, lr}
+	mov	r4, r0
+	mov	r5, r1
+	mov	r6, r2
+
+	/* !! Be very paranoid here !! */
+	/* !! We cannot write single bit here !! */
+
+#if 0	/* XXX writeback shouldn't be necessary */
+	/* Write back and invalidate all integrated caches */
+	bl 	dcache_wbinv_poc_all
+#else
+	bl	dcache_inv_pou_all
+#endif
+	mcr	CP15_ICIALLU
+	DSB
+	ISB
+
+	/* Set auxiliary register */
+	mrc	CP15_ACTLR(r7)
+	bic	r8, r7, r5		/* Mask bits */
+	eor 	r8, r8, r6		/* Set bits */
+	teq 	r7, r8
+	mcrne 	CP15_ACTLR(r8)
+	DSB
+	ISB
+
+	/* Enable caches. */
+	mrc	CP15_SCTLR(r7)
+	orr	r7, #CPU_CONTROL_DC_ENABLE
+	orr	r7, #CPU_CONTROL_IC_ENABLE
+	orr	r7, #CPU_CONTROL_BPRD_ENABLE
+	mcr	CP15_SCTLR(r7)
+	DSB
+
+	mcr	CP15_TTBR0(r4)		/* Set new TTB */
+	DSB
+	ISB
+
+	mcr	CP15_TLBIALL		/* Flush TLB */
+	mcr	CP15_BPIALL		/* Flush Branch predictor */
+	DSB
+	ISB
+
+#if 0 /* XXX writeback shouldn't be necessary */
+	/* Write back and invalidate all integrated caches */
+	bl 	dcache_wbinv_poc_all
+#else
+	bl	dcache_inv_pou_all
+#endif
+	mcr	CP15_ICIALLU
+	DSB
+	ISB
+
+	pop	{r4-r11, pc}
+END(reinit_mmu)
+
+
+/*
+ * Builds the page table
+ * r0 - The table base address
+ * r1 - The physical address (trashed)
+ * r2 - The virtual address (trashed)
+ * r3 - The number of 1MiB sections
+ * r4 - Trashed
+ *
+ * Addresses must be 1MiB aligned
+ */
+build_device_pagetables:
+#if defined(ARM_NEW_PMAP)
+	ldr	r4, =PTE1_V|PTE1_A|PTE1_AP_KRW|TEX1_CLASS_0
+#elif defined(SMP)
+	ldr	r4, =(L1_TYPE_S|L1_S_AP(AP_KRW)|L1_SHARED)
+#else
+	ldr	r4, =(L1_TYPE_S|L1_S_AP(AP_KRW))
+#endif
+	b	1f
+build_pagetables:
+	/* Set the required page attributed */
+#if defined(ARM_NEW_PMAP)
+	ldr	r4, =PTE1_V|PTE1_A|PTE1_AP_KRW|TEX1_CLASS_0
+#elif defined(SMP)
+	ldr	r4, =(L1_TYPE_S|L1_S_C|L1_S_AP(AP_KRW)|L1_SHARED)
+#else
+	ldr	r4, =(L1_TYPE_S|L1_S_C|L1_S_AP(AP_KRW))
+#endif
+1:
+	orr	r1, r4
+
+	/* Move the virtual address to the correct bit location */
+	lsr	r2, #(PTE1_SHIFT - 2)
+
+	mov	r4, r3
+2:
+	str	r1, [r0, r2]
+	add	r2, r2, #4
+	add	r1, r1, #(PTE1_SIZE)
+	adds	r4, r4, #-1
+	bhi	2b
+
+	mov	pc, lr
+
+VA_TO_PA_POINTER(Lpagetable, boot_pt1)
+
+
+.Lstart:
+	.word	_edata			/* Note that these three items are */
+	.word	_ebss			/* loaded with a single ldmia and */
+	.word	svcstk			/* must remain in order together. */
+
+.Lmainreturned:
+	.asciz	"main() returned"
+	.align	2
+
+	.bss
+svcstk:
+	.space	INIT_ARM_STACK_SIZE * MAXCPU
+
+/*
+ * Memory for the initial pagetable. We are unable to place this in
+ * the bss as this will be cleared after the table is loaded.
+ */
+	.section ".init_pagetable"
+	.align	14 /* 16KiB aligned */
+	.globl	boot_pt1
+boot_pt1:
+	.space	L1_TABLE_SIZE
+
+	.text
+	.align	2
+
+.Lcpufuncs:
+	.word	_C_LABEL(cpufuncs)
+
+#if defined(SMP)
+
+ASENTRY_NP(mpentry)
+	/* Make sure interrupts are disabled. */
+	cpsid	ifa
+
+	/* Setup core, disable all caches. */
+	mrc	CP15_SCTLR(r0)
+	bic	r0, #CPU_CONTROL_MMU_ENABLE
+	bic	r0, #CPU_CONTROL_DC_ENABLE
+	bic	r0, #CPU_CONTROL_IC_ENABLE
+	bic	r0, #CPU_CONTROL_UNAL_ENABLE
+	bic	r0, #CPU_CONTROL_BPRD_ENABLE
+	bic	r0, #CPU_CONTROL_SW_ENABLE
+	orr	r0, #CPU_CONTROL_AFLT_ENABLE
+	orr	r0, #CPU_CONTROL_VECRELOC
+	mcr	CP15_SCTLR(r0)
+	DSB
+	ISB
+
+	/* Invalidate L1 cache I+D cache */
+	bl	dcache_inv_pou_all
+	mcr	CP15_ICIALLU
+	DSB
+	ISB
+
+	/* Find the delta between VA and PA */
+	adr	r0, Lpagetable
+	bl	translate_va_to_pa
+
+	bl	init_mmu
+
+	adr	r1, .Lstart+8		/* Get initstack pointer from */
+	ldr	sp, [r1]		/* startup data. */
+	mrc	CP15_MPIDR(r0)		/* Get processor id number. */
+	and	r0, r0,	#0x0f
+	mov	r1, #INIT_ARM_STACK_SIZE
+	mul	r2, r1,	r0		/* Point sp to initstack */
+	add	sp, sp,	r2		/* area for this processor. */
+
+	/* Switch to virtual addresses. */
+	ldr	pc, =1f
+1:
+	mov	fp, #0			/* trace back starts here */
+	bl	_C_LABEL(init_secondary)/* Off we go, cpu id in r0. */
+
+	adr	r0, .Lmpreturned
+	b	_C_LABEL(panic)
+	/* NOTREACHED */
+END(mpentry)
+
+.Lmpreturned:
+	.asciz	"init_secondary() returned"
+	.align	2
+#endif
+
+ENTRY_NP(cpu_halt)
+
+	/* XXX re-implement !!! */
+	cpsid	ifa
+	bl	dcache_wbinv_poc_all
+
+	ldr	r4, .Lcpu_reset_address
+	ldr	r4, [r4]
+	teq	r4, #0
+	movne	pc, r4
+1:
+	WFI
+	b	1b
+
+	/*
+	 * _cpu_reset_address contains the address to branch to, to complete
+	 * the cpu reset after turning the MMU off
+	 * This variable is provided by the hardware specific code
+	 */
+.Lcpu_reset_address:
+	.word	_C_LABEL(cpu_reset_address)
+END(cpu_halt)
+
+
+/*
+ * setjump + longjmp
+ */
+ENTRY(setjmp)
+	stmia	r0, {r4-r14}
+	mov	r0, #0x00000000
+	RET
+END(setjmp)
+
+ENTRY(longjmp)
+	ldmia	r0, {r4-r14}
+	mov	r0, #0x00000001
+	RET
+END(longjmp)
+
+	.data
+	.global	_C_LABEL(esym)
+_C_LABEL(esym):	.word	_C_LABEL(end)
+
+ENTRY_NP(abort)
+	b	_C_LABEL(abort)
+END(abort)
+
+ENTRY_NP(sigcode)
+	mov	r0, sp
+	add	r0, r0, #SIGF_UC
+
+	/*
+	 * Call the sigreturn system call.
+	 *
+	 * We have to load r7 manually rather than using
+	 * "ldr r7, =SYS_sigreturn" to ensure the value of szsigcode is
+	 * correct. Using the alternative places esigcode at the address
+	 * of the data rather than the address one past the data.
+	 */
+
+	ldr	r7, [pc, #12]	/* Load SYS_sigreturn */
+	swi	SYS_sigreturn
+
+	/* Well if that failed we better exit quick ! */
+
+	ldr	r7, [pc, #8]	/* Load SYS_exit */
+	swi	SYS_exit
+
+	/* Branch back to retry SYS_sigreturn */
+	b	. - 16
+END(sigcode)
+	.word	SYS_sigreturn
+	.word	SYS_exit
+
+	.align	2
+	.global _C_LABEL(esigcode)
+		_C_LABEL(esigcode):
+
+	.data
+	.global szsigcode
+szsigcode:
+	.long esigcode-sigcode
+
+/* End of locore.S */


Property changes on: trunk/sys/arm/arm/locore-v6.S
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/locore.S
===================================================================
--- trunk/sys/arm/arm/locore.S	                        (rev 0)
+++ trunk/sys/arm/arm/locore.S	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,42 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014 Ian Lepore <ian at freebsd.org>
+ * All rights excluded.
+ *
+ * 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: stable/10/sys/arm/arm/locore.S 278643 2015-02-13 00:06:07Z ian $
+ */
+
+/*
+ * The kernel build machinery wants the file containing the entry point to be
+ * named locore.S, but we want separate files for v4 and v6 builds, so just
+ * include the arch-appropriate file from this properly-named file.
+ */
+
+#include <machine/acle-compat.h>
+
+#if __ARM_ARCH >= 6
+#include "locore-v6.S"
+#else
+#include "locore-v4.S"
+#endif


Property changes on: trunk/sys/arm/arm/locore.S
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/machdep.c
===================================================================
--- trunk/sys/arm/arm/machdep.c	                        (rev 0)
+++ trunk/sys/arm/arm/machdep.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,1311 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: arm32_machdep.c,v 1.44 2004/03/24 15:34:47 atatat Exp $	*/
+
+/*-
+ * Copyright (c) 2004 Olivier Houchard
+ * Copyright (c) 1994-1998 Mark Brinicombe.
+ * Copyright (c) 1994 Brini.
+ * All rights reserved.
+ *
+ * This code is derived from software written for Brini by Mark Brinicombe
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Mark Brinicombe
+ *	for the NetBSD Project.
+ * 4. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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.
+ *
+ * Machine dependant functions for kernel setup
+ *
+ * Created      : 17/09/94
+ * Updated	: 18/04/01 updated for new wscons
+ */
+
+#include "opt_compat.h"
+#include "opt_ddb.h"
+#include "opt_platform.h"
+#include "opt_sched.h"
+#include "opt_timer.h"
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/machdep.c 294683 2016-01-24 21:04:06Z ian $");
+
+#include <sys/param.h>
+#include <sys/proc.h>
+#include <sys/systm.h>
+#include <sys/bio.h>
+#include <sys/buf.h>
+#include <sys/bus.h>
+#include <sys/cons.h>
+#include <sys/cpu.h>
+#include <sys/exec.h>
+#include <sys/imgact.h>
+#include <sys/kdb.h>
+#include <sys/kernel.h>
+#include <sys/ktr.h>
+#include <sys/linker.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/msgbuf.h>
+#include <sys/mutex.h>
+#include <sys/pcpu.h>
+#include <sys/ptrace.h>
+#include <sys/rwlock.h>
+#include <sys/sched.h>
+#include <sys/signalvar.h>
+#include <sys/syscallsubr.h>
+#include <sys/sysctl.h>
+#include <sys/sysent.h>
+#include <sys/sysproto.h>
+#include <sys/uio.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/vm_map.h>
+#include <vm/vm_object.h>
+#include <vm/vm_page.h>
+#include <vm/vm_pager.h>
+
+#include <machine/armreg.h>
+#include <machine/atags.h>
+#include <machine/cpu.h>
+#include <machine/cpuinfo.h>
+#include <machine/devmap.h>
+#include <machine/frame.h>
+#include <machine/intr.h>
+#include <machine/machdep.h>
+#include <machine/md_var.h>
+#include <machine/metadata.h>
+#include <machine/pcb.h>
+#include <machine/physmem.h>
+#include <machine/reg.h>
+#include <machine/trap.h>
+#include <machine/undefined.h>
+#include <machine/vfp.h>
+#include <machine/vmparam.h>
+#include <machine/sysarch.h>
+
+#ifdef FDT
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#endif
+
+#ifdef DEBUG
+#define	debugf(fmt, args...) printf(fmt, ##args)
+#else
+#define	debugf(fmt, args...)
+#endif
+
+struct pcpu __pcpu[MAXCPU];
+struct pcpu *pcpup = &__pcpu[0];
+
+static struct trapframe proc0_tf;
+uint32_t cpu_reset_address = 0;
+int cold = 1;
+vm_offset_t vector_page;
+
+int (*_arm_memcpy)(void *, void *, int, int) = NULL;
+int (*_arm_bzero)(void *, int, int) = NULL;
+int _min_memcpy_size = 0;
+int _min_bzero_size = 0;
+
+extern int *end;
+#ifdef DDB
+extern vm_offset_t ksym_start, ksym_end;
+#endif
+
+#ifdef FDT
+/*
+ * This is the number of L2 page tables required for covering max
+ * (hypothetical) memsize of 4GB and all kernel mappings (vectors, msgbuf,
+ * stacks etc.), uprounded to be divisible by 4.
+ */
+#define KERNEL_PT_MAX	78
+
+static struct pv_addr kernel_pt_table[KERNEL_PT_MAX];
+
+vm_paddr_t pmap_pa;
+
+struct pv_addr systempage;
+static struct pv_addr msgbufpv;
+struct pv_addr irqstack;
+struct pv_addr undstack;
+struct pv_addr abtstack;
+static struct pv_addr kernelstack;
+
+#endif
+
+#if defined(LINUX_BOOT_ABI)
+#define LBABI_MAX_BANKS	10
+
+uint32_t board_id;
+struct arm_lbabi_tag *atag_list;
+char linux_command_line[LBABI_MAX_COMMAND_LINE + 1];
+char atags[LBABI_MAX_COMMAND_LINE * 2];
+uint32_t memstart[LBABI_MAX_BANKS];
+uint32_t memsize[LBABI_MAX_BANKS];
+uint32_t membanks;
+#endif
+
+static uint32_t board_revision;
+/* hex representation of uint64_t */
+static char board_serial[32];
+
+SYSCTL_NODE(_hw, OID_AUTO, board, CTLFLAG_RD, 0, "Board attributes");
+SYSCTL_UINT(_hw_board, OID_AUTO, revision, CTLFLAG_RD,
+    &board_revision, 0, "Board revision");
+SYSCTL_STRING(_hw_board, OID_AUTO, serial, CTLFLAG_RD,
+    board_serial, 0, "Board serial");
+
+int vfp_exists;
+SYSCTL_INT(_hw, HW_FLOATINGPT, floatingpoint, CTLFLAG_RD,
+    &vfp_exists, 0, "Floating point support enabled");
+
+void
+board_set_serial(uint64_t serial)
+{
+
+	snprintf(board_serial, sizeof(board_serial)-1, 
+		    "%016jx", serial);
+}
+
+void
+board_set_revision(uint32_t revision)
+{
+
+	board_revision = revision;
+}
+
+void
+sendsig(catcher, ksi, mask)
+	sig_t catcher;
+	ksiginfo_t *ksi;
+	sigset_t *mask;
+{
+	struct thread *td;
+	struct proc *p;
+	struct trapframe *tf;
+	struct sigframe *fp, frame;
+	struct sigacts *psp;
+	int onstack;
+	int sig;
+	int code;
+
+	td = curthread;
+	p = td->td_proc;
+	PROC_LOCK_ASSERT(p, MA_OWNED);
+	sig = ksi->ksi_signo;
+	code = ksi->ksi_code;
+	psp = p->p_sigacts;
+	mtx_assert(&psp->ps_mtx, MA_OWNED);
+	tf = td->td_frame;
+	onstack = sigonstack(tf->tf_usr_sp);
+
+	CTR4(KTR_SIG, "sendsig: td=%p (%s) catcher=%p sig=%d", td, p->p_comm,
+	    catcher, sig);
+
+	/* Allocate and validate space for the signal handler context. */
+	if ((td->td_pflags & TDP_ALTSTACK) != 0 && !(onstack) &&
+	    SIGISMEMBER(psp->ps_sigonstack, sig)) {
+		fp = (struct sigframe *)(td->td_sigstk.ss_sp +
+		    td->td_sigstk.ss_size);
+#if defined(COMPAT_43)
+		td->td_sigstk.ss_flags |= SS_ONSTACK;
+#endif
+	} else
+		fp = (struct sigframe *)td->td_frame->tf_usr_sp;
+
+	/* make room on the stack */
+	fp--;
+	
+	/* make the stack aligned */
+	fp = (struct sigframe *)STACKALIGN(fp);
+	/* Populate the siginfo frame. */
+	get_mcontext(td, &frame.sf_uc.uc_mcontext, 0);
+	frame.sf_si = ksi->ksi_info;
+	frame.sf_uc.uc_sigmask = *mask;
+	frame.sf_uc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK )
+	    ? ((onstack) ? SS_ONSTACK : 0) : SS_DISABLE;
+	frame.sf_uc.uc_stack = td->td_sigstk;
+	mtx_unlock(&psp->ps_mtx);
+	PROC_UNLOCK(td->td_proc);
+
+	/* Copy the sigframe out to the user's stack. */
+	if (copyout(&frame, fp, sizeof(*fp)) != 0) {
+		/* Process has trashed its stack. Kill it. */
+		CTR2(KTR_SIG, "sendsig: sigexit td=%p fp=%p", td, fp);
+		PROC_LOCK(p);
+		sigexit(td, SIGILL);
+	}
+
+	/*
+	 * Build context to run handler in.  We invoke the handler
+	 * directly, only returning via the trampoline.  Note the
+	 * trampoline version numbers are coordinated with machine-
+	 * dependent code in libc.
+	 */
+	
+	tf->tf_r0 = sig;
+	tf->tf_r1 = (register_t)&fp->sf_si;
+	tf->tf_r2 = (register_t)&fp->sf_uc;
+
+	/* the trampoline uses r5 as the uc address */
+	tf->tf_r5 = (register_t)&fp->sf_uc;
+	tf->tf_pc = (register_t)catcher;
+	tf->tf_usr_sp = (register_t)fp;
+	tf->tf_usr_lr = (register_t)(PS_STRINGS - *(p->p_sysent->sv_szsigcode));
+
+	CTR3(KTR_SIG, "sendsig: return td=%p pc=%#x sp=%#x", td, tf->tf_usr_lr,
+	    tf->tf_usr_sp);
+
+	PROC_LOCK(p);
+	mtx_lock(&psp->ps_mtx);
+}
+
+struct kva_md_info kmi;
+
+/*
+ * arm32_vector_init:
+ *
+ *	Initialize the vector page, and select whether or not to
+ *	relocate the vectors.
+ *
+ *	NOTE: We expect the vector page to be mapped at its expected
+ *	destination.
+ */
+
+extern unsigned int page0[], page0_data[];
+void
+arm_vector_init(vm_offset_t va, int which)
+{
+	unsigned int *vectors = (int *) va;
+	unsigned int *vectors_data = vectors + (page0_data - page0);
+	int vec;
+
+	/*
+	 * Loop through the vectors we're taking over, and copy the
+	 * vector's insn and data word.
+	 */
+	for (vec = 0; vec < ARM_NVEC; vec++) {
+		if ((which & (1 << vec)) == 0) {
+			/* Don't want to take over this vector. */
+			continue;
+		}
+		vectors[vec] = page0[vec];
+		vectors_data[vec] = page0_data[vec];
+	}
+
+	/* Now sync the vectors. */
+	cpu_icache_sync_range(va, (ARM_NVEC * 2) * sizeof(u_int));
+
+	vector_page = va;
+
+	if (va == ARM_VECTORS_HIGH) {
+		/*
+		 * Assume the MD caller knows what it's doing here, and
+		 * really does want the vector page relocated.
+		 *
+		 * Note: This has to be done here (and not just in
+		 * cpu_setup()) because the vector page needs to be
+		 * accessible *before* cpu_startup() is called.
+		 * Think ddb(9) ...
+		 *
+		 * NOTE: If the CPU control register is not readable,
+		 * this will totally fail!  We'll just assume that
+		 * any system that has high vector support has a
+		 * readable CPU control register, for now.  If we
+		 * ever encounter one that does not, we'll have to
+		 * rethink this.
+		 */
+		cpu_control(CPU_CONTROL_VECRELOC, CPU_CONTROL_VECRELOC);
+	}
+}
+
+static void
+cpu_startup(void *dummy)
+{
+	struct pcb *pcb = thread0.td_pcb;
+	const unsigned int mbyte = 1024 * 1024;
+#ifdef ARM_TP_ADDRESS
+#ifndef ARM_CACHE_LOCK_ENABLE
+	vm_page_t m;
+#endif
+#endif
+
+	identify_arm_cpu();
+
+	vm_ksubmap_init(&kmi);
+
+	/*
+	 * Display the RAM layout.
+	 */
+	printf("real memory  = %ju (%ju MB)\n", 
+	    (uintmax_t)arm32_ptob(realmem),
+	    (uintmax_t)arm32_ptob(realmem) / mbyte);
+	printf("avail memory = %ju (%ju MB)\n",
+	    (uintmax_t)arm32_ptob(cnt.v_free_count),
+	    (uintmax_t)arm32_ptob(cnt.v_free_count) / mbyte);
+	if (bootverbose) {
+		arm_physmem_print_tables();
+		arm_devmap_print_table();
+	}
+
+	bufinit();
+	vm_pager_bufferinit();
+	pcb->pcb_regs.sf_sp = (u_int)thread0.td_kstack +
+	    USPACE_SVC_STACK_TOP;
+	vector_page_setprot(VM_PROT_READ);
+	pmap_set_pcb_pagedir(pmap_kernel(), pcb);
+	pmap_postinit();
+#ifdef ARM_TP_ADDRESS
+#ifdef ARM_CACHE_LOCK_ENABLE
+	pmap_kenter_user(ARM_TP_ADDRESS, ARM_TP_ADDRESS);
+	arm_lock_cache_line(ARM_TP_ADDRESS);
+#else
+	m = vm_page_alloc(NULL, 0, VM_ALLOC_NOOBJ | VM_ALLOC_ZERO);
+	pmap_kenter_user(ARM_TP_ADDRESS, VM_PAGE_TO_PHYS(m));
+#endif
+	*(uint32_t *)ARM_RAS_START = 0;
+	*(uint32_t *)ARM_RAS_END = 0xffffffff;
+#endif
+}
+
+SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL);
+
+/*
+ * Flush the D-cache for non-DMA I/O so that the I-cache can
+ * be made coherent later.
+ */
+void
+cpu_flush_dcache(void *ptr, size_t len)
+{
+
+	cpu_dcache_wb_range((uintptr_t)ptr, len);
+#ifdef ARM_L2_PIPT
+	cpu_l2cache_wb_range((uintptr_t)vtophys(ptr), len);
+#else
+	cpu_l2cache_wb_range((uintptr_t)ptr, len);
+#endif
+}
+
+/* Get current clock frequency for the given cpu id. */
+int
+cpu_est_clockrate(int cpu_id, uint64_t *rate)
+{
+
+	return (ENXIO);
+}
+
+void
+cpu_idle(int busy)
+{
+	
+	CTR2(KTR_SPARE2, "cpu_idle(%d) at %d", busy, curcpu);
+	spinlock_enter();
+#ifndef NO_EVENTTIMERS
+	if (!busy)
+		cpu_idleclock();
+#endif
+	if (!sched_runnable())
+		cpu_sleep(0);
+#ifndef NO_EVENTTIMERS
+	if (!busy)
+		cpu_activeclock();
+#endif
+	spinlock_exit();
+	CTR2(KTR_SPARE2, "cpu_idle(%d) at %d done", busy, curcpu);
+}
+
+int
+cpu_idle_wakeup(int cpu)
+{
+
+	return (0);
+}
+
+/*
+ * Most ARM platforms don't need to do anything special to init their clocks
+ * (they get intialized during normal device attachment), and by not defining a
+ * cpu_initclocks() function they get this generic one.  Any platform that needs
+ * to do something special can just provide their own implementation, which will
+ * override this one due to the weak linkage.
+ */
+void
+arm_generic_initclocks(void)
+{
+
+#ifndef NO_EVENTTIMERS
+#ifdef SMP
+	if (PCPU_GET(cpuid) == 0)
+		cpu_initclocks_bsp();
+	else
+		cpu_initclocks_ap();
+#else
+	cpu_initclocks_bsp();
+#endif
+#endif
+}
+__weak_reference(arm_generic_initclocks, cpu_initclocks);
+
+int
+fill_regs(struct thread *td, struct reg *regs)
+{
+	struct trapframe *tf = td->td_frame;
+	bcopy(&tf->tf_r0, regs->r, sizeof(regs->r));
+	regs->r_sp = tf->tf_usr_sp;
+	regs->r_lr = tf->tf_usr_lr;
+	regs->r_pc = tf->tf_pc;
+	regs->r_cpsr = tf->tf_spsr;
+	return (0);
+}
+int
+fill_fpregs(struct thread *td, struct fpreg *regs)
+{
+	bzero(regs, sizeof(*regs));
+	return (0);
+}
+
+int
+set_regs(struct thread *td, struct reg *regs)
+{
+	struct trapframe *tf = td->td_frame;
+	
+	bcopy(regs->r, &tf->tf_r0, sizeof(regs->r));
+	tf->tf_usr_sp = regs->r_sp;
+	tf->tf_usr_lr = regs->r_lr;
+	tf->tf_pc = regs->r_pc;
+	tf->tf_spsr &=  ~PSR_FLAGS;
+	tf->tf_spsr |= regs->r_cpsr & PSR_FLAGS;
+	return (0);								
+}
+
+int
+set_fpregs(struct thread *td, struct fpreg *regs)
+{
+	return (0);
+}
+
+int
+fill_dbregs(struct thread *td, struct dbreg *regs)
+{
+	return (0);
+}
+int
+set_dbregs(struct thread *td, struct dbreg *regs)
+{
+	return (0);
+}
+
+
+static int
+ptrace_read_int(struct thread *td, vm_offset_t addr, u_int32_t *v)
+{
+	struct iovec iov;
+	struct uio uio;
+
+	PROC_LOCK_ASSERT(td->td_proc, MA_NOTOWNED);
+	iov.iov_base = (caddr_t) v;
+	iov.iov_len = sizeof(u_int32_t);
+	uio.uio_iov = &iov;
+	uio.uio_iovcnt = 1;
+	uio.uio_offset = (off_t)addr;
+	uio.uio_resid = sizeof(u_int32_t);
+	uio.uio_segflg = UIO_SYSSPACE;
+	uio.uio_rw = UIO_READ;
+	uio.uio_td = td;
+	return proc_rwmem(td->td_proc, &uio);
+}
+
+static int
+ptrace_write_int(struct thread *td, vm_offset_t addr, u_int32_t v)
+{
+	struct iovec iov;
+	struct uio uio;
+
+	PROC_LOCK_ASSERT(td->td_proc, MA_NOTOWNED);
+	iov.iov_base = (caddr_t) &v;
+	iov.iov_len = sizeof(u_int32_t);
+	uio.uio_iov = &iov;
+	uio.uio_iovcnt = 1;
+	uio.uio_offset = (off_t)addr;
+	uio.uio_resid = sizeof(u_int32_t);
+	uio.uio_segflg = UIO_SYSSPACE;
+	uio.uio_rw = UIO_WRITE;
+	uio.uio_td = td;
+	return proc_rwmem(td->td_proc, &uio);
+}
+
+int
+ptrace_single_step(struct thread *td)
+{
+	struct proc *p;
+	int error;
+	
+	KASSERT(td->td_md.md_ptrace_instr == 0,
+	 ("Didn't clear single step"));
+	p = td->td_proc;
+	PROC_UNLOCK(p);
+	error = ptrace_read_int(td, td->td_frame->tf_pc + 4,
+	    &td->td_md.md_ptrace_instr);
+	if (error)
+		goto out;
+	error = ptrace_write_int(td, td->td_frame->tf_pc + 4,
+	    PTRACE_BREAKPOINT);
+	if (error)
+		td->td_md.md_ptrace_instr = 0;
+	td->td_md.md_ptrace_addr = td->td_frame->tf_pc + 4;
+out:
+	PROC_LOCK(p);
+	return (error);
+}
+
+int
+ptrace_clear_single_step(struct thread *td)
+{
+	struct proc *p;
+
+	if (td->td_md.md_ptrace_instr) {
+		p = td->td_proc;
+		PROC_UNLOCK(p);
+		ptrace_write_int(td, td->td_md.md_ptrace_addr,
+		    td->td_md.md_ptrace_instr);
+		PROC_LOCK(p);
+		td->td_md.md_ptrace_instr = 0;
+	}
+	return (0);
+}
+
+int
+ptrace_set_pc(struct thread *td, unsigned long addr)
+{
+	td->td_frame->tf_pc = addr;
+	return (0);
+}
+
+void
+cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t size)
+{
+}
+
+void
+spinlock_enter(void)
+{
+	struct thread *td;
+	register_t cspr;
+
+	td = curthread;
+	if (td->td_md.md_spinlock_count == 0) {
+		cspr = disable_interrupts(PSR_I | PSR_F);
+		td->td_md.md_spinlock_count = 1;
+		td->td_md.md_saved_cspr = cspr;
+	} else
+		td->td_md.md_spinlock_count++;
+	critical_enter();
+}
+
+void
+spinlock_exit(void)
+{
+	struct thread *td;
+	register_t cspr;
+
+	td = curthread;
+	critical_exit();
+	cspr = td->td_md.md_saved_cspr;
+	td->td_md.md_spinlock_count--;
+	if (td->td_md.md_spinlock_count == 0)
+		restore_interrupts(cspr);
+}
+
+/*
+ * Clear registers on exec
+ */
+void
+exec_setregs(struct thread *td, struct image_params *imgp, u_long stack)
+{
+	struct trapframe *tf = td->td_frame;
+
+	memset(tf, 0, sizeof(*tf));
+	tf->tf_usr_sp = stack;
+	tf->tf_usr_lr = imgp->entry_addr;
+	tf->tf_svc_lr = 0x77777777;
+	tf->tf_pc = imgp->entry_addr;
+	tf->tf_spsr = PSR_USR32_MODE;
+}
+
+/*
+ * Get machine context.
+ */
+int
+get_mcontext(struct thread *td, mcontext_t *mcp, int clear_ret)
+{
+	struct trapframe *tf = td->td_frame;
+	__greg_t *gr = mcp->__gregs;
+
+	if (clear_ret & GET_MC_CLEAR_RET)
+		gr[_REG_R0] = 0;
+	else
+		gr[_REG_R0]   = tf->tf_r0;
+	gr[_REG_R1]   = tf->tf_r1;
+	gr[_REG_R2]   = tf->tf_r2;
+	gr[_REG_R3]   = tf->tf_r3;
+	gr[_REG_R4]   = tf->tf_r4;
+	gr[_REG_R5]   = tf->tf_r5;
+	gr[_REG_R6]   = tf->tf_r6;
+	gr[_REG_R7]   = tf->tf_r7;
+	gr[_REG_R8]   = tf->tf_r8;
+	gr[_REG_R9]   = tf->tf_r9;
+	gr[_REG_R10]  = tf->tf_r10;
+	gr[_REG_R11]  = tf->tf_r11;
+	gr[_REG_R12]  = tf->tf_r12;
+	gr[_REG_SP]   = tf->tf_usr_sp;
+	gr[_REG_LR]   = tf->tf_usr_lr;
+	gr[_REG_PC]   = tf->tf_pc;
+	gr[_REG_CPSR] = tf->tf_spsr;
+
+	return (0);
+}
+
+/*
+ * Set machine context.
+ *
+ * However, we don't set any but the user modifiable flags, and we won't
+ * touch the cs selector.
+ */
+int
+set_mcontext(struct thread *td, mcontext_t *mcp)
+{
+	struct trapframe *tf = td->td_frame;
+	const __greg_t *gr = mcp->__gregs;
+
+	tf->tf_r0 = gr[_REG_R0];
+	tf->tf_r1 = gr[_REG_R1];
+	tf->tf_r2 = gr[_REG_R2];
+	tf->tf_r3 = gr[_REG_R3];
+	tf->tf_r4 = gr[_REG_R4];
+	tf->tf_r5 = gr[_REG_R5];
+	tf->tf_r6 = gr[_REG_R6];
+	tf->tf_r7 = gr[_REG_R7];
+	tf->tf_r8 = gr[_REG_R8];
+	tf->tf_r9 = gr[_REG_R9];
+	tf->tf_r10 = gr[_REG_R10];
+	tf->tf_r11 = gr[_REG_R11];
+	tf->tf_r12 = gr[_REG_R12];
+	tf->tf_usr_sp = gr[_REG_SP];
+	tf->tf_usr_lr = gr[_REG_LR];
+	tf->tf_pc = gr[_REG_PC];
+	tf->tf_spsr = gr[_REG_CPSR];
+
+	return (0);
+}
+
+/*
+ * MPSAFE
+ */
+int
+sys_sigreturn(td, uap)
+	struct thread *td;
+	struct sigreturn_args /* {
+		const struct __ucontext *sigcntxp;
+	} */ *uap;
+{
+	ucontext_t uc;
+	int spsr;
+	
+	if (uap == NULL)
+		return (EFAULT);
+	if (copyin(uap->sigcntxp, &uc, sizeof(uc)))
+		return (EFAULT);
+	/*
+	 * Make sure the processor mode has not been tampered with and
+	 * interrupts have not been disabled.
+	 */
+	spsr = uc.uc_mcontext.__gregs[_REG_CPSR];
+	if ((spsr & PSR_MODE) != PSR_USR32_MODE ||
+	    (spsr & (PSR_I | PSR_F)) != 0)
+		return (EINVAL);
+		/* Restore register context. */
+	set_mcontext(td, &uc.uc_mcontext);
+
+	/* Restore signal mask. */
+	kern_sigprocmask(td, SIG_SETMASK, &uc.uc_sigmask, NULL, 0);
+
+	return (EJUSTRETURN);
+}
+
+
+/*
+ * Construct a PCB from a trapframe. This is called from kdb_trap() where
+ * we want to start a backtrace from the function that caused us to enter
+ * the debugger. We have the context in the trapframe, but base the trace
+ * on the PCB. The PCB doesn't have to be perfect, as long as it contains
+ * enough for a backtrace.
+ */
+void
+makectx(struct trapframe *tf, struct pcb *pcb)
+{
+	pcb->pcb_regs.sf_r4 = tf->tf_r4;
+	pcb->pcb_regs.sf_r5 = tf->tf_r5;
+	pcb->pcb_regs.sf_r6 = tf->tf_r6;
+	pcb->pcb_regs.sf_r7 = tf->tf_r7;
+	pcb->pcb_regs.sf_r8 = tf->tf_r8;
+	pcb->pcb_regs.sf_r9 = tf->tf_r9;
+	pcb->pcb_regs.sf_r10 = tf->tf_r10;
+	pcb->pcb_regs.sf_r11 = tf->tf_r11;
+	pcb->pcb_regs.sf_r12 = tf->tf_r12;
+	pcb->pcb_regs.sf_pc = tf->tf_pc;
+	pcb->pcb_regs.sf_lr = tf->tf_usr_lr;
+	pcb->pcb_regs.sf_sp = tf->tf_usr_sp;
+}
+
+/*
+ * Fake up a boot descriptor table
+ */
+vm_offset_t
+fake_preload_metadata(struct arm_boot_params *abp __unused)
+{
+#ifdef DDB
+	vm_offset_t zstart = 0, zend = 0;
+#endif
+	vm_offset_t lastaddr;
+	int i = 0;
+	static uint32_t fake_preload[35];
+
+	fake_preload[i++] = MODINFO_NAME;
+	fake_preload[i++] = strlen("kernel") + 1;
+	strcpy((char*)&fake_preload[i++], "kernel");
+	i += 1;
+	fake_preload[i++] = MODINFO_TYPE;
+	fake_preload[i++] = strlen("elf kernel") + 1;
+	strcpy((char*)&fake_preload[i++], "elf kernel");
+	i += 2;
+	fake_preload[i++] = MODINFO_ADDR;
+	fake_preload[i++] = sizeof(vm_offset_t);
+	fake_preload[i++] = KERNVIRTADDR;
+	fake_preload[i++] = MODINFO_SIZE;
+	fake_preload[i++] = sizeof(uint32_t);
+	fake_preload[i++] = (uint32_t)&end - KERNVIRTADDR;
+#ifdef DDB
+	if (*(uint32_t *)KERNVIRTADDR == MAGIC_TRAMP_NUMBER) {
+		fake_preload[i++] = MODINFO_METADATA|MODINFOMD_SSYM;
+		fake_preload[i++] = sizeof(vm_offset_t);
+		fake_preload[i++] = *(uint32_t *)(KERNVIRTADDR + 4);
+		fake_preload[i++] = MODINFO_METADATA|MODINFOMD_ESYM;
+		fake_preload[i++] = sizeof(vm_offset_t);
+		fake_preload[i++] = *(uint32_t *)(KERNVIRTADDR + 8);
+		lastaddr = *(uint32_t *)(KERNVIRTADDR + 8);
+		zend = lastaddr;
+		zstart = *(uint32_t *)(KERNVIRTADDR + 4);
+		ksym_start = zstart;
+		ksym_end = zend;
+	} else
+#endif
+		lastaddr = (vm_offset_t)&end;
+	fake_preload[i++] = 0;
+	fake_preload[i] = 0;
+	preload_metadata = (void *)fake_preload;
+
+	init_static_kenv(NULL, 0);
+
+	return (lastaddr);
+}
+
+void
+pcpu0_init(void)
+{
+#if __ARM_ARCH >= 6
+	set_curthread(&thread0);
+#endif
+	pcpu_init(pcpup, 0, sizeof(struct pcpu));
+	PCPU_SET(curthread, &thread0);
+#ifdef VFP
+	PCPU_SET(cpu, 0);
+#endif
+}
+
+#if defined(LINUX_BOOT_ABI)
+vm_offset_t
+linux_parse_boot_param(struct arm_boot_params *abp)
+{
+	struct arm_lbabi_tag *walker;
+	uint32_t revision;
+	uint64_t serial;
+
+	/*
+	 * Linux boot ABI: r0 = 0, r1 is the board type (!= 0) and r2
+	 * is atags or dtb pointer.  If all of these aren't satisfied,
+	 * then punt.
+	 */
+	if (!(abp->abp_r0 == 0 && abp->abp_r1 != 0 && abp->abp_r2 != 0))
+		return 0;
+
+	board_id = abp->abp_r1;
+	walker = (struct arm_lbabi_tag *)
+	    (abp->abp_r2 + KERNVIRTADDR - abp->abp_physaddr);
+
+	/* xxx - Need to also look for binary device tree */
+	if (ATAG_TAG(walker) != ATAG_CORE)
+		return 0;
+
+	atag_list = walker;
+	while (ATAG_TAG(walker) != ATAG_NONE) {
+		switch (ATAG_TAG(walker)) {
+		case ATAG_CORE:
+			break;
+		case ATAG_MEM:
+			arm_physmem_hardware_region(walker->u.tag_mem.start,
+			    walker->u.tag_mem.size);
+			break;
+		case ATAG_INITRD2:
+			break;
+		case ATAG_SERIAL:
+			serial = walker->u.tag_sn.low |
+			    ((uint64_t)walker->u.tag_sn.high << 32);
+			board_set_serial(serial);
+			break;
+		case ATAG_REVISION:
+			revision = walker->u.tag_rev.rev;
+			board_set_revision(revision);
+			break;
+		case ATAG_CMDLINE:
+			/* XXX open question: Parse this for boothowto? */
+			bcopy(walker->u.tag_cmd.command, linux_command_line,
+			      ATAG_SIZE(walker));
+			break;
+		default:
+			break;
+		}
+		walker = ATAG_NEXT(walker);
+	}
+
+	/* Save a copy for later */
+	bcopy(atag_list, atags,
+	    (char *)walker - (char *)atag_list + ATAG_SIZE(walker));
+
+	init_static_kenv(NULL, 0);
+
+	return fake_preload_metadata(abp);
+}
+#endif
+
+#if defined(FREEBSD_BOOT_LOADER)
+vm_offset_t
+freebsd_parse_boot_param(struct arm_boot_params *abp)
+{
+	vm_offset_t lastaddr = 0;
+	void *mdp;
+	void *kmdp;
+
+	/*
+	 * Mask metadata pointer: it is supposed to be on page boundary. If
+	 * the first argument (mdp) doesn't point to a valid address the
+	 * bootloader must have passed us something else than the metadata
+	 * ptr, so we give up.  Also give up if we cannot find metadta section
+	 * the loader creates that we get all this data out of.
+	 */
+
+	if ((mdp = (void *)(abp->abp_r0 & ~PAGE_MASK)) == NULL)
+		return 0;
+	preload_metadata = mdp;
+	kmdp = preload_search_by_type("elf kernel");
+	if (kmdp == NULL)
+		return 0;
+
+	boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int);
+	init_static_kenv(MD_FETCH(kmdp, MODINFOMD_ENVP, char *), 0);
+	lastaddr = MD_FETCH(kmdp, MODINFOMD_KERNEND, vm_offset_t);
+#ifdef DDB
+	ksym_start = MD_FETCH(kmdp, MODINFOMD_SSYM, uintptr_t);
+	ksym_end = MD_FETCH(kmdp, MODINFOMD_ESYM, uintptr_t);
+#endif
+	return lastaddr;
+}
+#endif
+
+vm_offset_t
+default_parse_boot_param(struct arm_boot_params *abp)
+{
+	vm_offset_t lastaddr;
+
+#if defined(LINUX_BOOT_ABI)
+	if ((lastaddr = linux_parse_boot_param(abp)) != 0)
+		return lastaddr;
+#endif
+#if defined(FREEBSD_BOOT_LOADER)
+	if ((lastaddr = freebsd_parse_boot_param(abp)) != 0)
+		return lastaddr;
+#endif
+	/* Fall back to hardcoded metadata. */
+	lastaddr = fake_preload_metadata(abp);
+
+	return lastaddr;
+}
+
+/*
+ * Stub version of the boot parameter parsing routine.  We are
+ * called early in initarm, before even VM has been initialized.
+ * This routine needs to preserve any data that the boot loader
+ * has passed in before the kernel starts to grow past the end
+ * of the BSS, traditionally the place boot-loaders put this data.
+ *
+ * Since this is called so early, things that depend on the vm system
+ * being setup (including access to some SoC's serial ports), about
+ * all that can be done in this routine is to copy the arguments.
+ *
+ * This is the default boot parameter parsing routine.  Individual
+ * kernels/boards can override this weak function with one of their
+ * own.  We just fake metadata...
+ */
+__weak_reference(default_parse_boot_param, parse_boot_param);
+
+/*
+ * Initialize proc0
+ */
+void
+init_proc0(vm_offset_t kstack)
+{
+	proc_linkup0(&proc0, &thread0);
+	thread0.td_kstack = kstack;
+	thread0.td_pcb = (struct pcb *)
+		(thread0.td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1;
+	thread0.td_pcb->pcb_flags = 0;
+	thread0.td_pcb->pcb_vfpcpu = -1;
+	thread0.td_pcb->pcb_vfpstate.fpscr = VFPSCR_DN | VFPSCR_FZ;
+	thread0.td_frame = &proc0_tf;
+	pcpup->pc_curpcb = thread0.td_pcb;
+}
+
+void
+set_stackptrs(int cpu)
+{
+
+	set_stackptr(PSR_IRQ32_MODE,
+	    irqstack.pv_va + ((IRQ_STACK_SIZE * PAGE_SIZE) * (cpu + 1)));
+	set_stackptr(PSR_ABT32_MODE,
+	    abtstack.pv_va + ((ABT_STACK_SIZE * PAGE_SIZE) * (cpu + 1)));
+	set_stackptr(PSR_UND32_MODE,
+	    undstack.pv_va + ((UND_STACK_SIZE * PAGE_SIZE) * (cpu + 1)));
+}
+
+#ifdef FDT
+static char *
+kenv_next(char *cp)
+{
+
+	if (cp != NULL) {
+		while (*cp != 0)
+			cp++;
+		cp++;
+		if (*cp == 0)
+			cp = NULL;
+	}
+	return (cp);
+}
+
+static void
+print_kenv(void)
+{
+	int len;
+	char *cp;
+
+	debugf("loader passed (static) kenv:\n");
+	if (kern_envp == NULL) {
+		debugf(" no env, null ptr\n");
+		return;
+	}
+	debugf(" kern_envp = 0x%08x\n", (uint32_t)kern_envp);
+
+	len = 0;
+	for (cp = kern_envp; cp != NULL; cp = kenv_next(cp))
+		debugf(" %x %s\n", (uint32_t)cp, cp);
+}
+
+void *
+initarm(struct arm_boot_params *abp)
+{
+	struct mem_region mem_regions[FDT_MEM_REGIONS];
+	struct pv_addr kernel_l1pt;
+	struct pv_addr dpcpu;
+	vm_offset_t dtbp, freemempos, l2_start, lastaddr;
+	uint32_t memsize, l2size;
+	char *env;
+	void *kmdp;
+	u_int l1pagetable;
+	int i, j, err_devmap, mem_regions_sz;
+
+	lastaddr = parse_boot_param(abp);
+	arm_physmem_kernaddr = abp->abp_physaddr;
+
+	memsize = 0;
+
+	cpuinfo_init();
+	set_cpufuncs();
+
+	/*
+	 * Find the dtb passed in by the boot loader.
+	 */
+	kmdp = preload_search_by_type("elf kernel");
+	if (kmdp != NULL)
+		dtbp = MD_FETCH(kmdp, MODINFOMD_DTBP, vm_offset_t);
+	else
+		dtbp = (vm_offset_t)NULL;
+
+#if defined(FDT_DTB_STATIC)
+	/*
+	 * In case the device tree blob was not retrieved (from metadata) try
+	 * to use the statically embedded one.
+	 */
+	if (dtbp == (vm_offset_t)NULL)
+		dtbp = (vm_offset_t)&fdt_static_dtb;
+#endif
+
+	if (OF_install(OFW_FDT, 0) == FALSE)
+		panic("Cannot install FDT");
+
+	if (OF_init((void *)dtbp) != 0)
+		panic("OF_init failed with the found device tree");
+
+	/* Grab physical memory regions information from device tree. */
+	if (fdt_get_mem_regions(mem_regions, &mem_regions_sz, &memsize) != 0)
+		panic("Cannot get physical memory regions");
+	arm_physmem_hardware_regions(mem_regions, mem_regions_sz);
+
+	/* Grab reserved memory regions information from device tree. */
+	if (fdt_get_reserved_regions(mem_regions, &mem_regions_sz) == 0)
+		arm_physmem_exclude_regions(mem_regions, mem_regions_sz, 
+		    EXFLAG_NODUMP | EXFLAG_NOALLOC);
+
+	/* Platform-specific initialisation */
+	initarm_early_init();
+
+	pcpu0_init();
+
+	/* Do basic tuning, hz etc */
+	init_param1();
+
+	/* Calculate number of L2 tables needed for mapping vm_page_array */
+	l2size = (memsize / PAGE_SIZE) * sizeof(struct vm_page);
+	l2size = (l2size >> L1_S_SHIFT) + 1;
+
+	/*
+	 * Add one table for end of kernel map, one for stacks, msgbuf and
+	 * L1 and L2 tables map and one for vectors map.
+	 */
+	l2size += 3;
+
+	/* Make it divisible by 4 */
+	l2size = (l2size + 3) & ~3;
+
+	freemempos = (lastaddr + PAGE_MASK) & ~PAGE_MASK;
+
+	/* Define a macro to simplify memory allocation */
+#define valloc_pages(var, np)						\
+	alloc_pages((var).pv_va, (np));					\
+	(var).pv_pa = (var).pv_va + (abp->abp_physaddr - KERNVIRTADDR);
+
+#define alloc_pages(var, np)						\
+	(var) = freemempos;						\
+	freemempos += (np * PAGE_SIZE);					\
+	memset((char *)(var), 0, ((np) * PAGE_SIZE));
+
+	while (((freemempos - L1_TABLE_SIZE) & (L1_TABLE_SIZE - 1)) != 0)
+		freemempos += PAGE_SIZE;
+	valloc_pages(kernel_l1pt, L1_TABLE_SIZE / PAGE_SIZE);
+
+	for (i = 0, j = 0; i < l2size; ++i) {
+		if (!(i % (PAGE_SIZE / L2_TABLE_SIZE_REAL))) {
+			valloc_pages(kernel_pt_table[i],
+			    L2_TABLE_SIZE / PAGE_SIZE);
+			j = i;
+		} else {
+			kernel_pt_table[i].pv_va = kernel_pt_table[j].pv_va +
+			    L2_TABLE_SIZE_REAL * (i - j);
+			kernel_pt_table[i].pv_pa =
+			    kernel_pt_table[i].pv_va - KERNVIRTADDR +
+			    abp->abp_physaddr;
+
+		}
+	}
+	/*
+	 * Allocate a page for the system page mapped to 0x00000000
+	 * or 0xffff0000. This page will just contain the system vectors
+	 * and can be shared by all processes.
+	 */
+	valloc_pages(systempage, 1);
+
+	/* Allocate dynamic per-cpu area. */
+	valloc_pages(dpcpu, DPCPU_SIZE / PAGE_SIZE);
+	dpcpu_init((void *)dpcpu.pv_va, 0);
+
+	/* Allocate stacks for all modes */
+	valloc_pages(irqstack, IRQ_STACK_SIZE * MAXCPU);
+	valloc_pages(abtstack, ABT_STACK_SIZE * MAXCPU);
+	valloc_pages(undstack, UND_STACK_SIZE * MAXCPU);
+	valloc_pages(kernelstack, KSTACK_PAGES * MAXCPU);
+	valloc_pages(msgbufpv, round_page(msgbufsize) / PAGE_SIZE);
+
+	/*
+	 * Now we start construction of the L1 page table
+	 * We start by mapping the L2 page tables into the L1.
+	 * This means that we can replace L1 mappings later on if necessary
+	 */
+	l1pagetable = kernel_l1pt.pv_va;
+
+	/*
+	 * Try to map as much as possible of kernel text and data using
+	 * 1MB section mapping and for the rest of initial kernel address
+	 * space use L2 coarse tables.
+	 *
+	 * Link L2 tables for mapping remainder of kernel (modulo 1MB)
+	 * and kernel structures
+	 */
+	l2_start = lastaddr & ~(L1_S_OFFSET);
+	for (i = 0 ; i < l2size - 1; i++)
+		pmap_link_l2pt(l1pagetable, l2_start + i * L1_S_SIZE,
+		    &kernel_pt_table[i]);
+
+	pmap_curmaxkvaddr = l2_start + (l2size - 1) * L1_S_SIZE;
+
+	/* Map kernel code and data */
+	pmap_map_chunk(l1pagetable, KERNVIRTADDR, abp->abp_physaddr,
+	   (((uint32_t)(lastaddr) - KERNVIRTADDR) + PAGE_MASK) & ~PAGE_MASK,
+	    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+
+	/* Map L1 directory and allocated L2 page tables */
+	pmap_map_chunk(l1pagetable, kernel_l1pt.pv_va, kernel_l1pt.pv_pa,
+	    L1_TABLE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE);
+
+	pmap_map_chunk(l1pagetable, kernel_pt_table[0].pv_va,
+	    kernel_pt_table[0].pv_pa,
+	    L2_TABLE_SIZE_REAL * l2size,
+	    VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE);
+
+	/* Map allocated DPCPU, stacks and msgbuf */
+	pmap_map_chunk(l1pagetable, dpcpu.pv_va, dpcpu.pv_pa,
+	    freemempos - dpcpu.pv_va,
+	    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+
+	/* Link and map the vector page */
+	pmap_link_l2pt(l1pagetable, ARM_VECTORS_HIGH,
+	    &kernel_pt_table[l2size - 1]);
+	pmap_map_entry(l1pagetable, ARM_VECTORS_HIGH, systempage.pv_pa,
+	    VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE, PTE_CACHE);
+
+	/* Establish static device mappings. */
+	err_devmap = initarm_devmap_init();
+	arm_devmap_bootstrap(l1pagetable, NULL);
+	vm_max_kernel_address = initarm_lastaddr();
+
+	cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL * 2)) | DOMAIN_CLIENT);
+	pmap_pa = kernel_l1pt.pv_pa;
+	setttb(kernel_l1pt.pv_pa);
+	cpu_tlb_flushID();
+	cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL * 2));
+
+	/*
+	 * Now that proper page tables are installed, call cpu_setup() to enable
+	 * instruction and data caches and other chip-specific features.
+	 */
+	cpu_setup("");
+
+	/*
+	 * Only after the SOC registers block is mapped we can perform device
+	 * tree fixups, as they may attempt to read parameters from hardware.
+	 */
+	OF_interpret("perform-fixup", 0);
+
+	initarm_gpio_init();
+
+	cninit();
+
+	debugf("initarm: console initialized\n");
+	debugf(" arg1 kmdp = 0x%08x\n", (uint32_t)kmdp);
+	debugf(" boothowto = 0x%08x\n", boothowto);
+	debugf(" dtbp = 0x%08x\n", (uint32_t)dtbp);
+	print_kenv();
+
+	env = getenv("kernelname");
+	if (env != NULL)
+		strlcpy(kernelname, env, sizeof(kernelname));
+
+	if (err_devmap != 0)
+		printf("WARNING: could not fully configure devmap, error=%d\n",
+		    err_devmap);
+
+	initarm_late_init();
+
+	/*
+	 * Pages were allocated during the secondary bootstrap for the
+	 * stacks for different CPU modes.
+	 * We must now set the r13 registers in the different CPU modes to
+	 * point to these stacks.
+	 * Since the ARM stacks use STMFD etc. we must set r13 to the top end
+	 * of the stack memory.
+	 */
+	cpu_control(CPU_CONTROL_MMU_ENABLE, CPU_CONTROL_MMU_ENABLE);
+
+	set_stackptrs(0);
+
+	/*
+	 * We must now clean the cache again....
+	 * Cleaning may be done by reading new data to displace any
+	 * dirty data in the cache. This will have happened in setttb()
+	 * but since we are boot strapping the addresses used for the read
+	 * may have just been remapped and thus the cache could be out
+	 * of sync. A re-clean after the switch will cure this.
+	 * After booting there are no gross relocations of the kernel thus
+	 * this problem will not occur after initarm().
+	 */
+	cpu_idcache_wbinv_all();
+
+	undefined_init();
+
+	init_proc0(kernelstack.pv_va);
+
+	arm_vector_init(ARM_VECTORS_HIGH, ARM_VEC_ALL);
+	pmap_bootstrap(freemempos, &kernel_l1pt);
+	msgbufp = (void *)msgbufpv.pv_va;
+	msgbufinit(msgbufp, msgbufsize);
+	mutex_init();
+
+	/*
+	 * Exclude the kernel (and all the things we allocated which immediately
+	 * follow the kernel) from the VM allocation pool but not from crash
+	 * dumps.  virtual_avail is a global variable which tracks the kva we've
+	 * "allocated" while setting up pmaps.
+	 *
+	 * Prepare the list of physical memory available to the vm subsystem.
+	 */
+	arm_physmem_exclude_region(abp->abp_physaddr, 
+	    (virtual_avail - KERNVIRTADDR), EXFLAG_NOALLOC);
+	arm_physmem_init_kernel_globals();
+
+	init_param2(physmem);
+	kdb_init();
+
+	return ((void *)(kernelstack.pv_va + USPACE_SVC_STACK_TOP -
+	    sizeof(struct pcb)));
+}
+#endif


Property changes on: trunk/sys/arm/arm/machdep.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/mem.c
===================================================================
--- trunk/sys/arm/arm/mem.c	                        (rev 0)
+++ trunk/sys/arm/arm/mem.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,168 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1988 University of Utah.
+ * Copyright (c) 1982, 1986, 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * the Systems Programming Group of the University of Utah Computer
+ * Science Department, and code derived from software contributed to
+ * Berkeley by William Jolitz.
+ *
+ * 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.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ *	from: Utah $Hdr: mem.c 1.13 89/10/08$
+ *	from: @(#)mem.c	7.2 (Berkeley) 5/9/91
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/mem.c 278746 2015-02-14 08:44:12Z kib $");
+
+/*
+ * Memory special file
+ */
+
+#include <sys/param.h>
+#include <sys/conf.h>
+#include <sys/fcntl.h>
+#include <sys/ioccom.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/memrange.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/proc.h>
+#include <sys/signalvar.h>
+#include <sys/sx.h>
+#include <sys/systm.h>
+#include <sys/uio.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/vm_extern.h>
+
+#include <machine/memdev.h>
+#include <machine/vmparam.h>
+
+/*
+ * Used in /dev/mem drivers and elsewhere
+ */
+MALLOC_DEFINE(M_MEMDESC, "memdesc", "memory range descriptors");
+
+struct mem_range_softc mem_range_softc;
+
+static struct sx tmppt_lock;
+SX_SYSINIT(tmppt, &tmppt_lock, "mem4map");
+
+/* ARGSUSED */
+int
+memrw(struct cdev *dev, struct uio *uio, int flags)
+{
+	int o;
+	u_int c = 0, v;
+	struct iovec *iov;
+	int error = 0;
+	vm_offset_t addr, eaddr;
+
+	while (uio->uio_resid > 0 && error == 0) {
+		iov = uio->uio_iov;
+		if (iov->iov_len == 0) {
+			uio->uio_iov++;
+			uio->uio_iovcnt--;
+			if (uio->uio_iovcnt < 0)
+				panic("memrw");
+			continue;
+		}
+		if (dev2unit(dev) == CDEV_MINOR_MEM) {
+			int i;
+			int address_valid = 0;
+
+			v = uio->uio_offset;
+			v &= ~PAGE_MASK;
+			for (i = 0; dump_avail[i] || dump_avail[i + 1];
+			i += 2) {
+				if (v >= dump_avail[i] &&
+				    v < dump_avail[i + 1]) {
+					address_valid = 1;
+					break;
+				}
+			}
+			if (!address_valid)
+				return (EINVAL);
+			sx_xlock(&tmppt_lock);
+			pmap_kenter((vm_offset_t)_tmppt, v);
+			o = (int)uio->uio_offset & PAGE_MASK;
+			c = (u_int)(PAGE_SIZE - ((int)iov->iov_base & PAGE_MASK));
+			c = min(c, (u_int)(PAGE_SIZE - o));
+			c = min(c, (u_int)iov->iov_len);
+			error = uiomove((caddr_t)&_tmppt[o], (int)c, uio);
+			pmap_qremove((vm_offset_t)_tmppt, 1);
+			sx_xunlock(&tmppt_lock);
+			continue;
+		}
+		else if (dev2unit(dev) == CDEV_MINOR_KMEM) {
+			c = iov->iov_len;
+
+			/*
+			 * Make sure that all of the pages are currently
+			 * resident so that we don't create any zero-fill
+			 * pages.
+			 */
+			addr = trunc_page(uio->uio_offset);
+			eaddr = round_page(uio->uio_offset + c);
+
+			for (; addr < eaddr; addr += PAGE_SIZE)
+				if (pmap_extract(kernel_pmap, addr) == 0)
+					return (EFAULT);
+			if (!kernacc((caddr_t)(int)uio->uio_offset, c,
+			    uio->uio_rw == UIO_READ ?
+			    VM_PROT_READ : VM_PROT_WRITE))
+					return (EFAULT);
+			error = uiomove((caddr_t)(int)uio->uio_offset, (int)c, uio);
+			continue;
+		}
+		/* else panic! */
+	}
+	return (error);
+}
+
+/*
+ * allow user processes to MMAP some memory sections
+ * instead of going through read/write
+ */
+/* ARGSUSED */
+
+int
+memmmap(struct cdev *dev, vm_ooffset_t offset, vm_paddr_t *paddr,
+    int prot __unused, vm_memattr_t *memattr __unused)
+{
+	if (dev2unit(dev) == CDEV_MINOR_MEM)
+		*paddr = offset;
+	else if (dev2unit(dev) == CDEV_MINOR_KMEM)
+        	*paddr = vtophys(offset);
+	/* else panic! */
+	return (0);
+}


Property changes on: trunk/sys/arm/arm/mem.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/minidump_machdep.c
===================================================================
--- trunk/sys/arm/arm/minidump_machdep.c	                        (rev 0)
+++ trunk/sys/arm/arm/minidump_machdep.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,498 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2008 Semihalf, Grzegorz Bernacki
+ * 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 ``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 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.
+ *
+ * from: FreeBSD: src/sys/i386/i386/minidump_machdep.c,v 1.6 2008/08/17 23:27:27
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/minidump_machdep.c 278614 2015-02-12 04:15:55Z ian $");
+
+#include "opt_watchdog.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/conf.h>
+#include <sys/cons.h>
+#include <sys/kernel.h>
+#include <sys/kerneldump.h>
+#include <sys/msgbuf.h>
+#ifdef SW_WATCHDOG
+#include <sys/watchdog.h>
+#endif
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <machine/atomic.h>
+#include <machine/elf.h>
+#include <machine/md_var.h>
+#include <machine/vmparam.h>
+#include <machine/minidump.h>
+#include <machine/cpufunc.h>
+
+CTASSERT(sizeof(struct kerneldumpheader) == 512);
+
+/*
+ * Don't touch the first SIZEOF_METADATA bytes on the dump device. This
+ * is to protect us from metadata and to protect metadata from us.
+ */
+#define	SIZEOF_METADATA		(64*1024)
+
+uint32_t *vm_page_dump;
+int vm_page_dump_size;
+
+static struct kerneldumpheader kdh;
+static off_t dumplo;
+
+/* Handle chunked writes. */
+static size_t fragsz, offset;
+static void *dump_va;
+static uint64_t counter, progress;
+
+CTASSERT(sizeof(*vm_page_dump) == 4);
+
+static int
+is_dumpable(vm_paddr_t pa)
+{
+	int i;
+
+	for (i = 0; dump_avail[i] != 0 || dump_avail[i + 1] != 0; i += 2) {
+		if (pa >= dump_avail[i] && pa < dump_avail[i + 1])
+			return (1);
+	}
+	return (0);
+}
+
+#define PG2MB(pgs) (((pgs) + (1 << 8) - 1) >> 8)
+
+static int
+blk_flush(struct dumperinfo *di)
+{
+	int error;
+
+	if (fragsz == 0)
+		return (0);
+
+	error = dump_write(di, (char*)dump_va + offset, 0, dumplo, fragsz - offset);
+	dumplo += (fragsz - offset);
+	fragsz = 0;
+	offset = 0;
+	return (error);
+}
+
+static int
+blk_write(struct dumperinfo *di, char *ptr, vm_paddr_t pa, size_t sz)
+{
+	size_t len;
+	int error, i, c;
+	u_int maxdumpsz;
+
+	maxdumpsz = di->maxiosize;
+
+	if (maxdumpsz == 0)	/* seatbelt */
+		maxdumpsz = PAGE_SIZE;
+
+	error = 0;
+
+	if (ptr != NULL && pa != 0) {
+		printf("cant have both va and pa!\n");
+		return (EINVAL);
+	}
+
+	if (ptr != NULL) {
+		/* If we're doing a virtual dump, flush any pre-existing pa pages */
+		error = blk_flush(di);
+		if (error)
+			return (error);
+	}
+
+	while (sz) {
+		if (fragsz == 0) {
+			offset = pa & PAGE_MASK;
+			fragsz += offset;
+		}
+		len = maxdumpsz - fragsz;
+		if (len > sz)
+			len = sz;
+		counter += len;
+		progress -= len;
+
+		if (counter >> 22) {
+			printf(" %lld", PG2MB(progress >> PAGE_SHIFT));
+			counter &= (1<<22) - 1;
+		}
+
+#ifdef SW_WATCHDOG
+		wdog_kern_pat(WD_LASTVAL);
+#endif
+		if (ptr) {
+			error = dump_write(di, ptr, 0, dumplo, len);
+			if (error)
+				return (error);
+			dumplo += len;
+			ptr += len;
+			sz -= len;
+		} else {
+			for (i = 0; i < len; i += PAGE_SIZE)
+				dump_va = pmap_kenter_temporary(pa + i,
+				    (i + fragsz) >> PAGE_SHIFT);
+			fragsz += len;
+			pa += len;
+			sz -= len;
+			if (fragsz == maxdumpsz) {
+				error = blk_flush(di);
+				if (error)
+					return (error);
+			}
+		}
+
+		/* Check for user abort. */
+		c = cncheckc();
+		if (c == 0x03)
+			return (ECANCELED);
+		if (c != -1)
+			printf(" (CTRL-C to abort) ");
+	}
+
+	return (0);
+}
+
+static int
+blk_write_cont(struct dumperinfo *di, vm_paddr_t pa, size_t sz)
+{
+	int error;
+
+	error = blk_write(di, 0, pa, sz);
+	if (error)
+		return (error);
+
+	error = blk_flush(di);
+	if (error)
+		return (error);
+
+	return (0);
+}
+
+/* A fake page table page, to avoid having to handle both 4K and 2M pages */
+static pt_entry_t fakept[NPTEPG];
+
+void
+minidumpsys(struct dumperinfo *di)
+{
+	struct minidumphdr mdhdr;
+	uint64_t dumpsize;
+	uint32_t ptesize;
+	uint32_t bits;
+	uint32_t pa, prev_pa = 0, count = 0;
+	vm_offset_t va;
+	pd_entry_t *pdp;
+	pt_entry_t *pt, *ptp;
+	int i, k, bit, error;
+	char *addr;
+
+	/*
+	 * Flush caches.  Note that in the SMP case this operates only on the
+	 * current CPU's L1 cache.  Before we reach this point, code in either
+	 * the system shutdown or kernel debugger has called stop_cpus() to stop
+	 * all cores other than this one.  Part of the ARM handling of
+	 * stop_cpus() is to call wbinv_all() on that core's local L1 cache.  So
+	 * by time we get to here, all that remains is to flush the L1 for the
+	 * current CPU, then the L2.
+	 */
+	cpu_idcache_wbinv_all();
+	cpu_l2cache_wbinv_all();
+
+	counter = 0;
+	/* Walk page table pages, set bits in vm_page_dump */
+	ptesize = 0;
+	for (va = KERNBASE; va < kernel_vm_end; va += NBPDR) {
+		/*
+		 * We always write a page, even if it is zero. Each
+		 * page written corresponds to 2MB of space
+		 */
+		ptesize += L2_TABLE_SIZE_REAL;
+		pmap_get_pde_pte(pmap_kernel(), va, &pdp, &ptp);
+		if (pmap_pde_v(pdp) && pmap_pde_section(pdp)) {
+			/* This is a section mapping 1M page. */
+			pa = (*pdp & L1_S_ADDR_MASK) | (va & ~L1_S_ADDR_MASK);
+			for (k = 0; k < (L1_S_SIZE / PAGE_SIZE); k++) {
+				if (is_dumpable(pa))
+					dump_add_page(pa);
+				pa += PAGE_SIZE;
+			}
+			continue;
+		}
+		if (pmap_pde_v(pdp) && pmap_pde_page(pdp)) {
+			/* Set bit for each valid page in this 1MB block */
+			addr = pmap_kenter_temporary(*pdp & L1_C_ADDR_MASK, 0);
+			pt = (pt_entry_t*)(addr +
+			    (((uint32_t)*pdp  & L1_C_ADDR_MASK) & PAGE_MASK));
+			for (k = 0; k < 256; k++) {
+				if ((pt[k] & L2_TYPE_MASK) == L2_TYPE_L) {
+					pa = (pt[k] & L2_L_FRAME) |
+					    (va & L2_L_OFFSET);
+					for (i = 0; i < 16; i++) {
+						if (is_dumpable(pa))
+							dump_add_page(pa);
+						k++;
+						pa += PAGE_SIZE;
+					}
+				} else if ((pt[k] & L2_TYPE_MASK) == L2_TYPE_S) {
+					pa = (pt[k] & L2_S_FRAME) |
+					    (va & L2_S_OFFSET);
+					if (is_dumpable(pa))
+						dump_add_page(pa);
+				}
+			}
+		} else {
+			/* Nothing, we're going to dump a null page */
+		}
+	}
+
+	/* Calculate dump size. */
+	dumpsize = ptesize;
+	dumpsize += round_page(msgbufp->msg_size);
+	dumpsize += round_page(vm_page_dump_size);
+
+	for (i = 0; i < vm_page_dump_size / sizeof(*vm_page_dump); i++) {
+		bits = vm_page_dump[i];
+		while (bits) {
+			bit = ffs(bits) - 1;
+			pa = (((uint64_t)i * sizeof(*vm_page_dump) * NBBY) +
+			    bit) * PAGE_SIZE;
+			/* Clear out undumpable pages now if needed */
+			if (is_dumpable(pa))
+				dumpsize += PAGE_SIZE;
+			else
+				dump_drop_page(pa);
+			bits &= ~(1ul << bit);
+		}
+	}
+
+	dumpsize += PAGE_SIZE;
+
+	/* Determine dump offset on device. */
+	if (di->mediasize < SIZEOF_METADATA + dumpsize + sizeof(kdh) * 2) {
+		error = ENOSPC;
+		goto fail;
+	}
+
+	dumplo = di->mediaoffset + di->mediasize - dumpsize;
+	dumplo -= sizeof(kdh) * 2;
+	progress = dumpsize;
+
+	/* Initialize mdhdr */
+	bzero(&mdhdr, sizeof(mdhdr));
+	strcpy(mdhdr.magic, MINIDUMP_MAGIC);
+	mdhdr.version = MINIDUMP_VERSION;
+	mdhdr.msgbufsize = msgbufp->msg_size;
+	mdhdr.bitmapsize = vm_page_dump_size;
+	mdhdr.ptesize = ptesize;
+	mdhdr.kernbase = KERNBASE;
+
+	mkdumpheader(&kdh, KERNELDUMPMAGIC, KERNELDUMP_ARM_VERSION, dumpsize,
+	    di->blocksize);
+
+	printf("Physical memory: %u MB\n", ptoa((uintmax_t)physmem) / 1048576);
+	printf("Dumping %llu MB:", (long long)dumpsize >> 20);
+
+	/* Dump leader */
+	error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh));
+	if (error)
+		goto fail;
+	dumplo += sizeof(kdh);
+
+	/* Dump my header */
+	bzero(&fakept, sizeof(fakept));
+	bcopy(&mdhdr, &fakept, sizeof(mdhdr));
+	error = blk_write(di, (char *)&fakept, 0, PAGE_SIZE);
+	if (error)
+		goto fail;
+
+	/* Dump msgbuf up front */
+	error = blk_write(di, (char *)msgbufp->msg_ptr, 0, round_page(msgbufp->msg_size));
+	if (error)
+		goto fail;
+
+	/* Dump bitmap */
+	error = blk_write(di, (char *)vm_page_dump, 0,
+	    round_page(vm_page_dump_size));
+	if (error)
+		goto fail;
+
+	/* Dump kernel page table pages */
+	for (va = KERNBASE; va < kernel_vm_end; va += NBPDR) {
+		/* We always write a page, even if it is zero */
+		pmap_get_pde_pte(pmap_kernel(), va, &pdp, &ptp);
+
+		if (pmap_pde_v(pdp) && pmap_pde_section(pdp))  {
+			if (count) {
+				error = blk_write_cont(di, prev_pa,
+				    count * L2_TABLE_SIZE_REAL);
+				if (error)
+					goto fail;
+				count = 0;
+				prev_pa = 0;
+			}
+			/* This is a single 2M block. Generate a fake PTP */
+			pa = (*pdp & L1_S_ADDR_MASK) | (va & ~L1_S_ADDR_MASK);
+			for (k = 0; k < (L1_S_SIZE / PAGE_SIZE); k++) {
+				fakept[k] = L2_S_PROTO | (pa + (k * PAGE_SIZE)) |
+				    L2_S_PROT(PTE_KERNEL,
+				    VM_PROT_READ | VM_PROT_WRITE);
+			}
+			error = blk_write(di, (char *)&fakept, 0,
+			    L2_TABLE_SIZE_REAL);
+			if (error)
+				goto fail;
+			/* Flush, in case we reuse fakept in the same block */
+			error = blk_flush(di);
+			if (error)
+				goto fail;
+			continue;
+		}
+		if (pmap_pde_v(pdp) && pmap_pde_page(pdp)) {
+			pa = *pdp & L1_C_ADDR_MASK;
+			if (!count) {
+				prev_pa = pa;
+				count++;
+			}
+			else {
+				if (pa == (prev_pa + count * L2_TABLE_SIZE_REAL))
+					count++;
+				else {
+					error = blk_write_cont(di, prev_pa,
+					    count * L2_TABLE_SIZE_REAL);
+					if (error)
+						goto fail;
+					count = 1;
+					prev_pa = pa;
+				}
+			}
+		} else {
+			if (count) {
+				error = blk_write_cont(di, prev_pa,
+				    count * L2_TABLE_SIZE_REAL);
+				if (error)
+					goto fail;
+				count = 0;
+				prev_pa = 0;
+			}
+			bzero(fakept, sizeof(fakept));
+			error = blk_write(di, (char *)&fakept, 0,
+			    L2_TABLE_SIZE_REAL);
+			if (error)
+				goto fail;
+			/* Flush, in case we reuse fakept in the same block */
+			error = blk_flush(di);
+			if (error)
+				goto fail;
+		}
+	}
+
+	if (count) {
+		error = blk_write_cont(di, prev_pa, count * L2_TABLE_SIZE_REAL);
+		if (error)
+			goto fail;
+		count = 0;
+		prev_pa = 0;
+	}
+
+	/* Dump memory chunks */
+	for (i = 0; i < vm_page_dump_size / sizeof(*vm_page_dump); i++) {
+		bits = vm_page_dump[i];
+		while (bits) {
+			bit = ffs(bits) - 1;
+			pa = (((uint64_t)i * sizeof(*vm_page_dump) * NBBY) +
+			    bit) * PAGE_SIZE;
+			if (!count) {
+				prev_pa = pa;
+				count++;
+			} else {
+				if (pa == (prev_pa + count * PAGE_SIZE))
+					count++;
+				else {
+					error = blk_write_cont(di, prev_pa,
+					    count * PAGE_SIZE);
+					if (error)
+						goto fail;
+					count = 1;
+					prev_pa = pa;
+				}
+			}
+			bits &= ~(1ul << bit);
+		}
+	}
+	if (count) {
+		error = blk_write_cont(di, prev_pa, count * PAGE_SIZE);
+		if (error)
+			goto fail;
+		count = 0;
+		prev_pa = 0;
+	}
+
+	/* Dump trailer */
+	error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh));
+	if (error)
+		goto fail;
+	dumplo += sizeof(kdh);
+
+	/* Signal completion, signoff and exit stage left. */
+	dump_write(di, NULL, 0, 0, 0);
+	printf("\nDump complete\n");
+	return;
+
+fail:
+	if (error < 0)
+		error = -error;
+
+	if (error == ECANCELED)
+		printf("\nDump aborted\n");
+	else if (error == ENOSPC)
+		printf("\nDump failed. Partition too small.\n");
+	else
+		printf("\n** DUMP FAILED (ERROR %d) **\n", error);
+}
+
+void
+dump_add_page(vm_paddr_t pa)
+{
+	int idx, bit;
+
+	pa >>= PAGE_SHIFT;
+	idx = pa >> 5;		/* 2^5 = 32 */
+	bit = pa & 31;
+	atomic_set_int(&vm_page_dump[idx], 1ul << bit);
+}
+
+void
+dump_drop_page(vm_paddr_t pa)
+{
+	int idx, bit;
+
+	pa >>= PAGE_SHIFT;
+	idx = pa >> 5;		/* 2^5 = 32 */
+	bit = pa & 31;
+	atomic_clear_int(&vm_page_dump[idx], 1ul << bit);
+}


Property changes on: trunk/sys/arm/arm/minidump_machdep.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/mp_machdep.c
===================================================================
--- trunk/sys/arm/arm/mp_machdep.c	                        (rev 0)
+++ trunk/sys/arm/arm/mp_machdep.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,411 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2011 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/mp_machdep.c 278639 2015-02-12 21:20:28Z ian $");
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/proc.h>
+#include <sys/pcpu.h>
+#include <sys/sched.h>
+#include <sys/smp.h>
+#include <sys/ktr.h>
+#include <sys/malloc.h>
+
+#include <vm/vm.h>
+#include <vm/vm_extern.h>
+#include <vm/vm_kern.h>
+#include <vm/pmap.h>
+
+#include <machine/armreg.h>
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+#include <machine/smp.h>
+#include <machine/pcb.h>
+#include <machine/pte.h>
+#include <machine/physmem.h>
+#include <machine/intr.h>
+#include <machine/vmparam.h>
+#ifdef VFP
+#include <machine/vfp.h>
+#endif
+#ifdef CPU_MV_PJ4B
+#include <arm/mv/mvwin.h>
+#include <dev/fdt/fdt_common.h>
+#endif
+
+#include "opt_smp.h"
+
+extern struct pcpu __pcpu[];
+/* used to hold the AP's until we are ready to release them */
+struct mtx ap_boot_mtx;
+struct pcb stoppcbs[MAXCPU];
+
+/* # of Applications processors */
+volatile int mp_naps;
+
+/* Set to 1 once we're ready to let the APs out of the pen. */
+volatile int aps_ready = 0;
+
+static int ipi_handler(void *arg);
+void set_stackptrs(int cpu);
+
+/* Temporary variables for init_secondary()  */
+void *dpcpu[MAXCPU - 1];
+
+/* Determine if we running MP machine */
+int
+cpu_mp_probe(void)
+{
+	CPU_SETOF(0, &all_cpus);
+
+	return (platform_mp_probe());
+}
+
+/* Start Application Processor via platform specific function */
+static int
+check_ap(void)
+{
+	uint32_t ms;
+
+	for (ms = 0; ms < 2000; ++ms) {
+		if ((mp_naps + 1) == mp_ncpus)
+			return (0);		/* success */
+		else
+			DELAY(1000);
+	}
+
+	return (-2);
+}
+
+extern unsigned char _end[];
+
+/* Initialize and fire up non-boot processors */
+void
+cpu_mp_start(void)
+{
+	int error, i;
+
+	mtx_init(&ap_boot_mtx, "ap boot", NULL, MTX_SPIN);
+
+	/* Reserve memory for application processors */
+	for(i = 0; i < (mp_ncpus - 1); i++)
+		dpcpu[i] = (void *)kmem_malloc(kernel_arena, DPCPU_SIZE,
+		    M_WAITOK | M_ZERO);
+
+	cpu_idcache_wbinv_all();
+	cpu_l2cache_wbinv_all();
+	cpu_idcache_wbinv_all();
+
+	/* Initialize boot code and start up processors */
+	platform_mp_start_ap();
+
+	/*  Check if ap's started properly */
+	error = check_ap();
+	if (error)
+		printf("WARNING: Some AP's failed to start\n");
+	else
+		for (i = 1; i < mp_ncpus; i++)
+			CPU_SET(i, &all_cpus);
+
+}
+
+/* Introduce rest of cores to the world */
+void
+cpu_mp_announce(void)
+{
+
+}
+
+extern vm_paddr_t pmap_pa;
+void
+init_secondary(int cpu)
+{
+	struct pcpu *pc;
+	uint32_t loop_counter;
+	int start = 0, end = 0;
+
+	cpu_setup(NULL);
+	setttb(pmap_pa);
+	cpu_tlb_flushID();
+
+	pc = &__pcpu[cpu];
+
+	/*
+	 * pcpu_init() updates queue, so it should not be executed in parallel
+	 * on several cores
+	 */
+	while(mp_naps < (cpu - 1))
+		;
+
+	pcpu_init(pc, cpu, sizeof(struct pcpu));
+	dpcpu_init(dpcpu[cpu - 1], cpu);
+
+	/* Provide stack pointers for other processor modes. */
+	set_stackptrs(cpu);
+
+	/* Signal our startup to BSP */
+	atomic_add_rel_32(&mp_naps, 1);
+
+	/* Spin until the BSP releases the APs */
+	while (!aps_ready)
+		;
+
+	/* Initialize curthread */
+	KASSERT(PCPU_GET(idlethread) != NULL, ("no idle thread"));
+	pc->pc_curthread = pc->pc_idlethread;
+	pc->pc_curpcb = pc->pc_idlethread->td_pcb;
+	set_curthread(pc->pc_idlethread);
+#ifdef VFP
+	pc->pc_cpu = cpu;
+
+	vfp_init();
+#endif
+
+	mtx_lock_spin(&ap_boot_mtx);
+
+	atomic_add_rel_32(&smp_cpus, 1);
+
+	if (smp_cpus == mp_ncpus) {
+		/* enable IPI's, tlb shootdown, freezes etc */
+		atomic_store_rel_int(&smp_started, 1);
+	}
+
+	mtx_unlock_spin(&ap_boot_mtx);
+
+	/* Enable ipi */
+#ifdef IPI_IRQ_START
+	start = IPI_IRQ_START;
+#ifdef IPI_IRQ_END
+  	end = IPI_IRQ_END;
+#else
+	end = IPI_IRQ_START;
+#endif
+#endif
+				
+	for (int i = start; i <= end; i++)
+		arm_unmask_irq(i);
+	enable_interrupts(PSR_I);
+
+	loop_counter = 0;
+	while (smp_started == 0) {
+		DELAY(100);
+		loop_counter++;
+		if (loop_counter == 1000)
+			CTR0(KTR_SMP, "AP still wait for smp_started");
+	}
+	/* Start per-CPU event timers. */
+	cpu_initclocks_ap();
+
+	CTR0(KTR_SMP, "go into scheduler");
+	platform_mp_init_secondary();
+
+	/* Enter the scheduler */
+	sched_throw(NULL);
+
+	panic("scheduler returned us to %s", __func__);
+	/* NOTREACHED */
+}
+
+static int
+ipi_handler(void *arg)
+{
+	u_int	cpu, ipi;
+
+	cpu = PCPU_GET(cpuid);
+
+	ipi = pic_ipi_get((int)arg);
+
+	while ((ipi != 0x3ff)) {
+		switch (ipi) {
+		case IPI_RENDEZVOUS:
+			CTR0(KTR_SMP, "IPI_RENDEZVOUS");
+			smp_rendezvous_action();
+			break;
+
+		case IPI_AST:
+			CTR0(KTR_SMP, "IPI_AST");
+			break;
+
+		case IPI_STOP:
+			/*
+			 * IPI_STOP_HARD is mapped to IPI_STOP so it is not
+			 * necessary to add it in the switch.
+			 */
+			CTR0(KTR_SMP, "IPI_STOP or IPI_STOP_HARD");
+
+			savectx(&stoppcbs[cpu]);
+
+			/*
+			 * CPUs are stopped when entering the debugger and at
+			 * system shutdown, both events which can precede a
+			 * panic dump.  For the dump to be correct, all caches
+			 * must be flushed and invalidated, but on ARM there's
+			 * no way to broadcast a wbinv_all to other cores.
+			 * Instead, we have each core do the local wbinv_all as
+			 * part of stopping the core.  The core requesting the
+			 * stop will do the l2 cache flush after all other cores
+			 * have done their l1 flushes and stopped.
+			 */
+			cpu_idcache_wbinv_all();
+
+			/* Indicate we are stopped */
+			CPU_SET_ATOMIC(cpu, &stopped_cpus);
+
+			/* Wait for restart */
+			while (!CPU_ISSET(cpu, &started_cpus))
+				cpu_spinwait();
+
+			CPU_CLR_ATOMIC(cpu, &started_cpus);
+			CPU_CLR_ATOMIC(cpu, &stopped_cpus);
+			CTR0(KTR_SMP, "IPI_STOP (restart)");
+			break;
+		case IPI_PREEMPT:
+			CTR1(KTR_SMP, "%s: IPI_PREEMPT", __func__);
+			sched_preempt(curthread);
+			break;
+		case IPI_HARDCLOCK:
+			CTR1(KTR_SMP, "%s: IPI_HARDCLOCK", __func__);
+			hardclockintr();
+			break;
+		case IPI_TLB:
+			CTR1(KTR_SMP, "%s: IPI_TLB", __func__);
+			cpufuncs.cf_tlb_flushID();
+			break;
+		default:
+			panic("Unknown IPI 0x%0x on cpu %d", ipi, curcpu);
+		}
+
+		pic_ipi_clear(ipi);
+		ipi = pic_ipi_get(-1);
+	}
+
+	return (FILTER_HANDLED);
+}
+
+static void
+release_aps(void *dummy __unused)
+{
+	uint32_t loop_counter;
+	int start = 0, end = 0;
+
+	if (mp_ncpus == 1)
+		return;
+#ifdef IPI_IRQ_START
+	start = IPI_IRQ_START;
+#ifdef IPI_IRQ_END
+	end = IPI_IRQ_END;
+#else
+	end = IPI_IRQ_START;
+#endif
+#endif
+
+	for (int i = start; i <= end; i++) {
+		/*
+		 * IPI handler
+		 */
+		/* 
+		 * Use 0xdeadbeef as the argument value for irq 0,
+		 * if we used 0, the intr code will give the trap frame
+		 * pointer instead.
+		 */
+		arm_setup_irqhandler("ipi", ipi_handler, NULL, (void *)i, i,
+		    INTR_TYPE_MISC | INTR_EXCL, NULL);
+
+		/* Enable ipi */
+		arm_unmask_irq(i);
+	}
+	atomic_store_rel_int(&aps_ready, 1);
+
+	printf("Release APs\n");
+
+	for (loop_counter = 0; loop_counter < 2000; loop_counter++) {
+		if (smp_started)
+			return;
+		DELAY(1000);
+	}
+	printf("AP's not started\n");
+}
+
+SYSINIT(start_aps, SI_SUB_SMP, SI_ORDER_FIRST, release_aps, NULL);
+
+struct cpu_group *
+cpu_topo(void)
+{
+
+	return (smp_topo_1level(CG_SHARE_L2, mp_ncpus, 0));
+}
+
+void
+cpu_mp_setmaxid(void)
+{
+
+	platform_mp_setmaxid();
+}
+
+/* Sending IPI */
+void
+ipi_all_but_self(u_int ipi)
+{
+	cpuset_t other_cpus;
+
+	other_cpus = all_cpus;
+	CPU_CLR(PCPU_GET(cpuid), &other_cpus);
+	CTR2(KTR_SMP, "%s: ipi: %x", __func__, ipi);
+	platform_ipi_send(other_cpus, ipi);
+}
+
+void
+ipi_cpu(int cpu, u_int ipi)
+{
+	cpuset_t cpus;
+
+	CPU_ZERO(&cpus);
+	CPU_SET(cpu, &cpus);
+
+	CTR3(KTR_SMP, "%s: cpu: %d, ipi: %x", __func__, cpu, ipi);
+	platform_ipi_send(cpus, ipi);
+}
+
+void
+ipi_selected(cpuset_t cpus, u_int ipi)
+{
+
+	CTR2(KTR_SMP, "%s: ipi: %x", __func__, ipi);
+	platform_ipi_send(cpus, ipi);
+}
+
+void
+tlb_broadcast(int ipi)
+{
+
+	if (smp_started)
+		ipi_all_but_self(ipi);
+}


Property changes on: trunk/sys/arm/arm/mp_machdep.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/mpcore_timer.c
===================================================================
--- trunk/sys/arm/arm/mpcore_timer.c	                        (rev 0)
+++ trunk/sys/arm/arm/mpcore_timer.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,548 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * Developed by Ben Gray <ben.r.gray at gmail.com>
+ *
+ * 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.
+ * 3. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * 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.
+ */
+
+/**
+ * The ARM Cortex-A9 core can support a global timer plus a private and
+ * watchdog timer per core.  This driver reserves memory and interrupt
+ * resources for accessing both timer register sets, these resources are
+ * stored globally and used to setup the timecount and eventtimer.
+ *
+ * The timecount timer uses the global 64-bit counter, whereas the
+ * per-CPU eventtimer uses the private 32-bit counters.
+ *
+ *
+ * REF: ARM Cortex-A9 MPCore, Technical Reference Manual (rev. r2p2)
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/mpcore_timer.c 273673 2014-10-26 03:55:09Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/timeet.h>
+#include <sys/timetc.h>
+#include <sys/watchdog.h>
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+
+#include <arm/arm/mpcore_timervar.h>
+
+/* Private (per-CPU) timer register map */
+#define PRV_TIMER_LOAD                 0x0000
+#define PRV_TIMER_COUNT                0x0004
+#define PRV_TIMER_CTRL                 0x0008
+#define PRV_TIMER_INTR                 0x000C
+
+#define PRV_TIMER_CTR_PRESCALER_SHIFT  8
+#define PRV_TIMER_CTRL_IRQ_ENABLE      (1UL << 2)
+#define PRV_TIMER_CTRL_AUTO_RELOAD     (1UL << 1)
+#define PRV_TIMER_CTRL_TIMER_ENABLE    (1UL << 0)
+
+#define PRV_TIMER_INTR_EVENT           (1UL << 0)
+
+/* Global timer register map */
+#define GBL_TIMER_COUNT_LOW            0x0000
+#define GBL_TIMER_COUNT_HIGH           0x0004
+#define GBL_TIMER_CTRL                 0x0008
+#define GBL_TIMER_INTR                 0x000C
+
+#define GBL_TIMER_CTR_PRESCALER_SHIFT  8
+#define GBL_TIMER_CTRL_AUTO_INC        (1UL << 3)
+#define GBL_TIMER_CTRL_IRQ_ENABLE      (1UL << 2)
+#define GBL_TIMER_CTRL_COMP_ENABLE     (1UL << 1)
+#define GBL_TIMER_CTRL_TIMER_ENABLE    (1UL << 0)
+
+#define GBL_TIMER_INTR_EVENT           (1UL << 0)
+
+struct arm_tmr_softc {
+	device_t		dev;
+	int			irqrid;
+	int			memrid;
+	struct resource *	gbl_mem;
+	struct resource *	prv_mem;
+	struct resource *	prv_irq;
+	uint64_t		clkfreq;
+	struct eventtimer	et;
+};
+
+static struct eventtimer *arm_tmr_et;
+static struct timecounter *arm_tmr_tc;
+static uint64_t arm_tmr_freq;
+static boolean_t arm_tmr_freq_varies;
+
+#define	tmr_prv_read_4(sc, reg)         bus_read_4((sc)->prv_mem, reg)
+#define	tmr_prv_write_4(sc, reg, val)   bus_write_4((sc)->prv_mem, reg, val)
+#define	tmr_gbl_read_4(sc, reg)         bus_read_4((sc)->gbl_mem, reg)
+#define	tmr_gbl_write_4(sc, reg, val)   bus_write_4((sc)->gbl_mem, reg, val)
+
+static timecounter_get_t arm_tmr_get_timecount;
+
+static struct timecounter arm_tmr_timecount = {
+	.tc_name           = "MPCore",
+	.tc_get_timecount  = arm_tmr_get_timecount,
+	.tc_poll_pps       = NULL,
+	.tc_counter_mask   = ~0u,
+	.tc_frequency      = 0,
+	.tc_quality        = 800,
+};
+
+#define	TMR_GBL		0x01
+#define	TMR_PRV		0x02
+#define	TMR_BOTH	(TMR_GBL | TMR_PRV)
+#define	TMR_NONE	0
+
+static struct ofw_compat_data compat_data[] = {
+	{"arm,mpcore-timers",		TMR_BOTH}, /* Non-standard, FreeBSD. */
+	{"arm,cortex-a9-global-timer",	TMR_GBL},
+	{"arm,cortex-a5-global-timer",	TMR_GBL},
+	{"arm,cortex-a9-twd-timer",	TMR_PRV},
+	{"arm,cortex-a5-twd-timer",	TMR_PRV},
+	{"arm,arm11mp-twd-timer",	TMR_PRV},
+	{NULL,				TMR_NONE}
+};
+
+/**
+ *	arm_tmr_get_timecount - reads the timecount (global) timer
+ *	@tc: pointer to arm_tmr_timecount struct
+ *
+ *	We only read the lower 32-bits, the timecount stuff only uses 32-bits
+ *	so (for now?) ignore the upper 32-bits.
+ *
+ *	RETURNS
+ *	The lower 32-bits of the counter.
+ */
+static unsigned
+arm_tmr_get_timecount(struct timecounter *tc)
+{
+	struct arm_tmr_softc *sc;
+
+	sc = tc->tc_priv;
+	return (tmr_gbl_read_4(sc, GBL_TIMER_COUNT_LOW));
+}
+
+/**
+ *	arm_tmr_start - starts the eventtimer (private) timer
+ *	@et: pointer to eventtimer struct
+ *	@first: the number of seconds and fractional sections to trigger in
+ *	@period: the period (in seconds and fractional sections) to set
+ *
+ *	If the eventtimer is required to be in oneshot mode, period will be
+ *	NULL and first will point to the time to trigger.  If in periodic mode
+ *	period will contain the time period and first may optionally contain
+ *	the time for the first period.
+ *
+ *	RETURNS
+ *	Always returns 0
+ */
+static int
+arm_tmr_start(struct eventtimer *et, sbintime_t first, sbintime_t period)
+{
+	struct arm_tmr_softc *sc;
+	uint32_t load, count;
+	uint32_t ctrl;
+
+	sc = et->et_priv;
+	tmr_prv_write_4(sc, PRV_TIMER_CTRL, 0);
+	tmr_prv_write_4(sc, PRV_TIMER_INTR, PRV_TIMER_INTR_EVENT);
+
+	ctrl = PRV_TIMER_CTRL_IRQ_ENABLE | PRV_TIMER_CTRL_TIMER_ENABLE;
+
+	if (period != 0) {
+		load = ((uint32_t)et->et_frequency * period) >> 32;
+		ctrl |= PRV_TIMER_CTRL_AUTO_RELOAD;
+	} else
+		load = 0;
+
+	if (first != 0)
+		count = (uint32_t)((et->et_frequency * first) >> 32);
+	else
+		count = load;
+
+	tmr_prv_write_4(sc, PRV_TIMER_LOAD, load);
+	tmr_prv_write_4(sc, PRV_TIMER_COUNT, count);
+	tmr_prv_write_4(sc, PRV_TIMER_CTRL, ctrl);
+
+	return (0);
+}
+
+/**
+ *	arm_tmr_stop - stops the eventtimer (private) timer
+ *	@et: pointer to eventtimer struct
+ *
+ *	Simply stops the private timer by clearing all bits in the ctrl register.
+ *
+ *	RETURNS
+ *	Always returns 0
+ */
+static int
+arm_tmr_stop(struct eventtimer *et)
+{
+	struct arm_tmr_softc *sc;
+
+	sc = et->et_priv;
+	tmr_prv_write_4(sc, PRV_TIMER_CTRL, 0);
+	tmr_prv_write_4(sc, PRV_TIMER_INTR, PRV_TIMER_INTR_EVENT);
+	return (0);
+}
+
+/**
+ *	arm_tmr_intr - ISR for the eventtimer (private) timer
+ *	@arg: pointer to arm_tmr_softc struct
+ *
+ *	Clears the event register and then calls the eventtimer callback.
+ *
+ *	RETURNS
+ *	Always returns FILTER_HANDLED
+ */
+static int
+arm_tmr_intr(void *arg)
+{
+	struct arm_tmr_softc *sc;
+
+	sc = arg;
+	tmr_prv_write_4(sc, PRV_TIMER_INTR, PRV_TIMER_INTR_EVENT);
+	if (sc->et.et_active)
+		sc->et.et_event_cb(&sc->et, sc->et.et_arg);
+	return (FILTER_HANDLED);
+}
+
+
+
+
+/**
+ *	arm_tmr_probe - timer probe routine
+ *	@dev: new device
+ *
+ *	The probe function returns success when probed with the fdt compatible
+ *	string set to "arm,mpcore-timers".
+ *
+ *	RETURNS
+ *	BUS_PROBE_DEFAULT if the fdt device is compatible, otherwise ENXIO.
+ */
+static int
+arm_tmr_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == TMR_NONE)
+		return (ENXIO);
+
+	device_set_desc(dev, "ARM MPCore Timers");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+attach_tc(struct arm_tmr_softc *sc)
+{
+	int rid;
+
+	if (arm_tmr_tc != NULL)
+		return (EBUSY);
+
+	rid = sc->memrid;
+	sc->gbl_mem = bus_alloc_resource_any(sc->dev, SYS_RES_MEMORY, &rid,
+	    RF_ACTIVE);
+	if (sc->gbl_mem == NULL) {
+		device_printf(sc->dev, "could not allocate gbl mem resources\n");
+		return (ENXIO);
+	}
+	tmr_gbl_write_4(sc, GBL_TIMER_CTRL, 0x00000000);
+
+	arm_tmr_timecount.tc_frequency = sc->clkfreq;
+	arm_tmr_timecount.tc_priv = sc;
+	tc_init(&arm_tmr_timecount);
+	arm_tmr_tc = &arm_tmr_timecount;
+
+	tmr_gbl_write_4(sc, GBL_TIMER_CTRL, GBL_TIMER_CTRL_TIMER_ENABLE);
+
+	return (0);
+}
+
+static int
+attach_et(struct arm_tmr_softc *sc)
+{
+	void *ihl;
+	int irid, mrid;
+
+	if (arm_tmr_et != NULL)
+		return (EBUSY);
+
+	mrid = sc->memrid;
+	sc->prv_mem = bus_alloc_resource_any(sc->dev, SYS_RES_MEMORY, &mrid,
+	    RF_ACTIVE);
+	if (sc->prv_mem == NULL) {
+		device_printf(sc->dev, "could not allocate prv mem resources\n");
+		return (ENXIO);
+	}
+	tmr_prv_write_4(sc, PRV_TIMER_CTRL, 0x00000000);
+
+	irid = sc->irqrid;
+	sc->prv_irq = bus_alloc_resource_any(sc->dev, SYS_RES_IRQ, &irid, RF_ACTIVE);
+	if (sc->prv_irq == NULL) {
+		bus_release_resource(sc->dev, SYS_RES_MEMORY, mrid, sc->prv_mem);
+		device_printf(sc->dev, "could not allocate prv irq resources\n");
+		return (ENXIO);
+	}
+
+	if (bus_setup_intr(sc->dev, sc->prv_irq, INTR_TYPE_CLK, arm_tmr_intr,
+			NULL, sc, &ihl) != 0) {
+		bus_release_resource(sc->dev, SYS_RES_MEMORY, mrid, sc->prv_mem);
+		bus_release_resource(sc->dev, SYS_RES_IRQ, irid, sc->prv_irq);
+		device_printf(sc->dev, "unable to setup the et irq handler.\n");
+		return (ENXIO);
+	}
+
+	/*
+	 * Setup and register the eventtimer.  Most event timers set their min
+	 * and max period values to some value calculated from the clock
+	 * frequency.  We might not know yet what our runtime clock frequency
+	 * will be, so we just use some safe values.  A max of 2 seconds ensures
+	 * that even if our base clock frequency is 2GHz (meaning a 4GHz CPU),
+	 * we won't overflow our 32-bit timer count register.  A min of 20
+	 * nanoseconds is pretty much completely arbitrary.
+	 */
+	sc->et.et_name = "MPCore";
+	sc->et.et_flags = ET_FLAGS_PERIODIC | ET_FLAGS_ONESHOT | ET_FLAGS_PERCPU;
+	sc->et.et_quality = 1000;
+	sc->et.et_frequency = sc->clkfreq;
+	sc->et.et_min_period = 20 * SBT_1NS;
+	sc->et.et_max_period =  2 * SBT_1S;
+	sc->et.et_start = arm_tmr_start;
+	sc->et.et_stop = arm_tmr_stop;
+	sc->et.et_priv = sc;
+	et_register(&sc->et);
+	arm_tmr_et = &sc->et;
+
+	return (0);
+}
+
+/**
+ *	arm_tmr_attach - attaches the timer to the simplebus
+ *	@dev: new device
+ *
+ *	Reserves memory and interrupt resources, stores the softc structure
+ *	globally and registers both the timecount and eventtimer objects.
+ *
+ *	RETURNS
+ *	Zero on sucess or ENXIO if an error occuried.
+ */
+static int
+arm_tmr_attach(device_t dev)
+{
+	struct arm_tmr_softc *sc;
+	phandle_t node;
+	pcell_t clock;
+	int et_err, tc_err, tmrtype;
+
+	sc = device_get_softc(dev);
+	sc->dev = dev;
+
+	if (arm_tmr_freq_varies) {
+		sc->clkfreq = arm_tmr_freq;
+	} else {
+		if (arm_tmr_freq != 0) {
+			sc->clkfreq = arm_tmr_freq;
+		} else {
+			/* Get the base clock frequency */
+			node = ofw_bus_get_node(dev);
+			if ((OF_getencprop(node, "clock-frequency", &clock,
+			    sizeof(clock))) <= 0) {
+				device_printf(dev, "missing clock-frequency "
+				    "attribute in FDT\n");
+				return (ENXIO);
+			}
+			sc->clkfreq = clock;
+		}
+	}
+
+	tmrtype = ofw_bus_search_compatible(dev, compat_data)->ocd_data;
+	tc_err = ENXIO;
+	et_err = ENXIO;
+
+	/*
+	 * If we're handling the global timer and it is fixed-frequency, set it
+	 * up to use as a timecounter.  If it's variable frequency it won't work
+	 * as a timecounter.  We also can't use it for DELAY(), so hopefully the
+	 * platform provides its own implementation. If it doesn't, ours will
+	 * get used, but since the frequency isn't set, it will only use the
+	 * bogus loop counter.
+	 */
+	if (tmrtype & TMR_GBL) {
+		if (!arm_tmr_freq_varies)
+			tc_err = attach_tc(sc);
+		else if (bootverbose)
+			device_printf(sc->dev, 
+			    "not using variable-frequency device as timecounter");
+		sc->memrid++;
+		sc->irqrid++;
+	}
+
+	/* If we are handling the private timer, set it up as an eventtimer. */
+	if (tmrtype & TMR_PRV) {
+		et_err = attach_et(sc);
+	}
+
+	/*
+	 * If we didn't successfully set up a timecounter or eventtimer then we
+	 * didn't actually attach at all, return error.
+	 */
+	if (tc_err != 0 && et_err != 0) {
+		return (ENXIO);
+	}
+	return (0);
+}
+
+static device_method_t arm_tmr_methods[] = {
+	DEVMETHOD(device_probe,		arm_tmr_probe),
+	DEVMETHOD(device_attach,	arm_tmr_attach),
+	{ 0, 0 }
+};
+
+static driver_t arm_tmr_driver = {
+	"mp_tmr",
+	arm_tmr_methods,
+	sizeof(struct arm_tmr_softc),
+};
+
+static devclass_t arm_tmr_devclass;
+
+EARLY_DRIVER_MODULE(mp_tmr, simplebus, arm_tmr_driver, arm_tmr_devclass, 0, 0,
+    BUS_PASS_TIMER + BUS_PASS_ORDER_MIDDLE);
+EARLY_DRIVER_MODULE(mp_tmr, ofwbus, arm_tmr_driver, arm_tmr_devclass, 0, 0,
+    BUS_PASS_TIMER + BUS_PASS_ORDER_MIDDLE);
+
+/*
+ * Handle a change in clock frequency.  The mpcore timer runs at half the CPU
+ * frequency.  When the CPU frequency changes due to power-saving or thermal
+ * managment, the platform-specific code that causes the frequency change calls
+ * this routine to inform the clock driver, and we in turn inform the event
+ * timer system, which actually updates the value in et->frequency for us and
+ * reschedules the current event(s) in a way that's atomic with respect to
+ * start/stop/intr code that may be running on various CPUs at the time of the
+ * call.
+ *
+ * This routine can also be called by a platform's early init code.  If the
+ * value passed is ARM_TMR_FREQUENCY_VARIES, that will cause the attach() code
+ * to register as an eventtimer, but not a timecounter.  If the value passed in
+ * is any other non-zero value it is used as the fixed frequency for the timer.
+ */
+void
+arm_tmr_change_frequency(uint64_t newfreq)
+{
+
+	if (newfreq == ARM_TMR_FREQUENCY_VARIES) {
+		arm_tmr_freq_varies = true;
+		return;
+	}
+
+	arm_tmr_freq = newfreq;
+	if (arm_tmr_et != NULL)
+		et_change_frequency(arm_tmr_et, newfreq);
+}
+
+/**
+ *	DELAY - Delay for at least usec microseconds.
+ *	@usec: number of microseconds to delay by
+ *
+ *	This function is called all over the kernel and is suppose to provide a
+ *	consistent delay.  This function may also be called before the console 
+ *	is setup so no printf's can be called here.
+ *
+ *	RETURNS:
+ *	nothing
+ */
+static void __used /* Must emit function code for the weak ref below. */
+arm_tmr_DELAY(int usec)
+{
+	struct arm_tmr_softc *sc;
+	int32_t counts_per_usec;
+	int32_t counts;
+	uint32_t first, last;
+
+	/* Check the timers are setup, if not just use a for loop for the meantime */
+	if (arm_tmr_tc == NULL || arm_tmr_timecount.tc_frequency == 0) {
+		for (; usec > 0; usec--)
+			for (counts = 200; counts > 0; counts--)
+				cpufunc_nullop();	/* Prevent gcc from optimizing
+							 * out the loop
+							 */
+		return;
+	}
+
+	sc = arm_tmr_tc->tc_priv;
+
+	/* Get the number of times to count */
+	counts_per_usec = ((arm_tmr_timecount.tc_frequency / 1000000) + 1);
+
+	/*
+	 * Clamp the timeout at a maximum value (about 32 seconds with
+	 * a 66MHz clock). *Nobody* should be delay()ing for anywhere
+	 * near that length of time and if they are, they should be hung
+	 * out to dry.
+	 */
+	if (usec >= (0x80000000U / counts_per_usec))
+		counts = (0x80000000U / counts_per_usec) - 1;
+	else
+		counts = usec * counts_per_usec;
+
+	first = tmr_gbl_read_4(sc, GBL_TIMER_COUNT_LOW);
+
+	while (counts > 0) {
+		last = tmr_gbl_read_4(sc, GBL_TIMER_COUNT_LOW);
+		counts -= (int32_t)(last - first);
+		first = last;
+	}
+}
+
+/*
+ * Supply a DELAY() implementation via weak linkage.  A platform may want to use
+ * the mpcore per-cpu eventtimers but provide its own DELAY() routine,
+ * especially when the core frequency can change on the fly.
+ */
+__weak_reference(arm_tmr_DELAY, DELAY);
+


Property changes on: trunk/sys/arm/arm/mpcore_timer.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/mpcore_timervar.h
===================================================================
--- trunk/sys/arm/arm/mpcore_timervar.h	                        (rev 0)
+++ trunk/sys/arm/arm/mpcore_timervar.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,48 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014 Ian Lepore <ian at freebsd.org>
+ * 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: stable/10/sys/arm/arm/mpcore_timervar.h 266347 2014-05-17 20:10:12Z ian $
+ */
+
+#ifndef	_ARM_MPCORE_TIMERVAR_H_
+#define	_ARM_MPCORE_TIMERVAR_H_
+
+/*
+ * This value, passed to arm_tmr_change_frequency() any time before the mpcore
+ * timer device attaches, informs the driver that the mpcore clock frequency can
+ * change on the fly, and thus can't be used as a timecounter.  The hardware can
+ * still be used as an eventtimer, as long as each frequency change is
+ * communicated to it with calls to arm_tmr_change_frequency().
+ */
+#define	ARM_TMR_FREQUENCY_VARIES	-1ULL
+
+/*
+ * Inform the mpcore timer driver of a new clock frequency.  This can be called
+ * both before and after the mpcore timer driver attaches.
+ */
+void arm_tmr_change_frequency(uint64_t newfreq);
+
+#endif


Property changes on: trunk/sys/arm/arm/mpcore_timervar.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/nexus.c
===================================================================
--- trunk/sys/arm/arm/nexus.c	                        (rev 0)
+++ trunk/sys/arm/arm/nexus.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,362 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright 1998 Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that both the above copyright notice and this
+ * permission notice appear in all copies, that both the above
+ * copyright notice and this permission notice appear in all
+ * supporting documentation, and that the name of M.I.T. not be used
+ * in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.  M.I.T. makes
+ * no representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''.  M.I.T. DISCLAIMS
+ * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
+ * SHALL M.I.T. 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.
+ *
+ */
+
+/*
+ * This code implements a `root nexus' for Arm Architecture
+ * machines.  The function of the root nexus is to serve as an
+ * attachment point for both processors and buses, and to manage
+ * resources which are common to all of them.  In particular,
+ * this code implements the core resource managers for interrupt
+ * requests, DMA requests (which rightfully should be a part of the
+ * ISA code but it's easier to do it here for now), I/O port addresses,
+ * and I/O memory address space.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/nexus.c 274268 2014-11-08 03:42:19Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
+#include <sys/interrupt.h>
+
+#include <machine/vmparam.h>
+#include <machine/pcb.h>
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <machine/resource.h>
+#include <machine/intr.h>
+
+#include "opt_platform.h"
+
+#ifdef FDT
+#include <dev/fdt/fdt_common.h>
+#include <machine/fdt.h>
+#include "ofw_bus_if.h"
+#endif
+
+static MALLOC_DEFINE(M_NEXUSDEV, "nexusdev", "Nexus device");
+
+struct nexus_device {
+	struct resource_list	nx_resources;
+};
+
+#define DEVTONX(dev)	((struct nexus_device *)device_get_ivars(dev))
+
+static struct rman mem_rman;
+
+static	int nexus_probe(device_t);
+static	int nexus_attach(device_t);
+static	int nexus_print_child(device_t, device_t);
+static	device_t nexus_add_child(device_t, u_int, const char *, int);
+static	struct resource *nexus_alloc_resource(device_t, device_t, int, int *,
+    u_long, u_long, u_long, u_int);
+static	int nexus_activate_resource(device_t, device_t, int, int,
+    struct resource *);
+static int nexus_config_intr(device_t dev, int irq, enum intr_trigger trig,
+    enum intr_polarity pol);
+static	int nexus_deactivate_resource(device_t, device_t, int, int,
+    struct resource *);
+
+static int nexus_setup_intr(device_t dev, device_t child, struct resource *res,
+    int flags, driver_filter_t *filt, driver_intr_t *intr, void *arg, void **cookiep);
+static int nexus_teardown_intr(device_t, device_t, struct resource *, void *);
+
+#ifdef FDT
+static int nexus_ofw_map_intr(device_t dev, device_t child, phandle_t iparent,
+    int icells, pcell_t *intr);
+#endif
+
+static device_method_t nexus_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		nexus_probe),
+	DEVMETHOD(device_attach,	nexus_attach),
+	/* Bus interface */
+	DEVMETHOD(bus_print_child,	nexus_print_child),
+	DEVMETHOD(bus_add_child,	nexus_add_child),
+	DEVMETHOD(bus_alloc_resource,	nexus_alloc_resource),
+	DEVMETHOD(bus_activate_resource,	nexus_activate_resource),
+	DEVMETHOD(bus_config_intr,	nexus_config_intr),
+	DEVMETHOD(bus_deactivate_resource,	nexus_deactivate_resource),
+	DEVMETHOD(bus_setup_intr,	nexus_setup_intr),
+	DEVMETHOD(bus_teardown_intr,	nexus_teardown_intr),
+#ifdef FDT
+	DEVMETHOD(ofw_bus_map_intr,	nexus_ofw_map_intr),
+#endif
+	{ 0, 0 }
+};
+
+static devclass_t nexus_devclass;
+static driver_t nexus_driver = {
+	"nexus",
+	nexus_methods,
+	1			/* no softc */
+};
+EARLY_DRIVER_MODULE(nexus, root, nexus_driver, nexus_devclass, 0, 0, 
+    BUS_PASS_BUS + BUS_PASS_ORDER_EARLY);
+
+static int
+nexus_probe(device_t dev)
+{
+
+	device_quiet(dev);	/* suppress attach message for neatness */
+
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+nexus_attach(device_t dev)
+{
+
+	mem_rman.rm_start = 0;
+	mem_rman.rm_end = ~0ul;
+	mem_rman.rm_type = RMAN_ARRAY;
+	mem_rman.rm_descr = "I/O memory addresses";
+	if (rman_init(&mem_rman) || rman_manage_region(&mem_rman, 0, ~0))
+		panic("nexus_probe mem_rman");
+
+	/*
+	 * First, deal with the children we know about already
+	 */
+	bus_generic_probe(dev);
+	bus_generic_attach(dev);
+
+	return (0);
+}
+
+static int
+nexus_print_child(device_t bus, device_t child)
+{
+	int retval = 0;
+
+	retval += bus_print_child_header(bus, child);
+	retval += printf("\n");
+
+	return (retval);
+}
+
+static device_t
+nexus_add_child(device_t bus, u_int order, const char *name, int unit)
+{
+	device_t child;
+	struct nexus_device *ndev;
+
+	ndev = malloc(sizeof(struct nexus_device), M_NEXUSDEV, M_NOWAIT|M_ZERO);
+	if (!ndev)
+		return (0);
+	resource_list_init(&ndev->nx_resources);
+
+	child = device_add_child_ordered(bus, order, name, unit);
+
+	/* should we free this in nexus_child_detached? */
+	device_set_ivars(child, ndev);
+
+	return (child);
+}
+
+
+/*
+ * Allocate a resource on behalf of child.  NB: child is usually going to be a
+ * child of one of our descendants, not a direct child of nexus0.
+ * (Exceptions include footbridge.)
+ */
+static struct resource *
+nexus_alloc_resource(device_t bus, device_t child, int type, int *rid,
+    u_long start, u_long end, u_long count, u_int flags)
+{
+	struct resource *rv;
+	struct rman *rm;
+	int needactivate = flags & RF_ACTIVE;
+
+	switch (type) {
+	case SYS_RES_MEMORY:
+	case SYS_RES_IOPORT:
+		rm = &mem_rman;
+		break;
+
+	default:
+		return (0);
+	}
+
+	rv = rman_reserve_resource(rm, start, end, count, flags, child);
+	if (rv == 0)
+		return (0);
+
+	rman_set_rid(rv, *rid);
+	rman_set_bushandle(rv, rman_get_start(rv));
+
+	if (needactivate) {
+		if (bus_activate_resource(child, type, *rid, rv)) {
+			rman_release_resource(rv);
+			return (0);
+		}
+	}
+
+	return (rv);
+}
+
+static int
+nexus_config_intr(device_t dev, int irq, enum intr_trigger trig,
+    enum intr_polarity pol)
+{
+	int ret = ENODEV;
+
+	if (arm_config_irq)
+		ret = (*arm_config_irq)(irq, trig, pol);
+
+	return (ret);
+}
+
+static int
+nexus_setup_intr(device_t dev, device_t child, struct resource *res, int flags,
+    driver_filter_t *filt, driver_intr_t *intr, void *arg, void **cookiep)
+{
+	int irq;
+
+	if ((rman_get_flags(res) & RF_SHAREABLE) == 0)
+		flags |= INTR_EXCL;
+
+	for (irq = rman_get_start(res); irq <= rman_get_end(res); irq++) {
+		arm_setup_irqhandler(device_get_nameunit(child),
+		    filt, intr, arg, irq, flags, cookiep);
+		arm_unmask_irq(irq);
+	}
+	return (0);
+}
+
+static int
+nexus_teardown_intr(device_t dev, device_t child, struct resource *r, void *ih)
+{
+
+	return (arm_remove_irqhandler(rman_get_start(r), ih));
+}
+
+
+static int
+nexus_activate_resource(device_t bus, device_t child, int type, int rid,
+    struct resource *r)
+{
+	int err;
+	bus_addr_t paddr;
+	bus_size_t psize;
+	bus_space_handle_t vaddr;
+
+	if ((err = rman_activate_resource(r)) != 0)
+		return (err);
+
+	/*
+	 * If this is a memory resource, map it into the kernel.
+	 */
+	if (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) {
+		paddr = (bus_addr_t)rman_get_start(r);
+		psize = (bus_size_t)rman_get_size(r);
+#ifdef FDT
+		err = bus_space_map(fdtbus_bs_tag, paddr, psize, 0, &vaddr);
+		if (err != 0) {
+			rman_deactivate_resource(r);
+			return (err);
+		}
+		rman_set_bustag(r, fdtbus_bs_tag);
+#else
+		vaddr = (bus_space_handle_t)pmap_mapdev((vm_offset_t)paddr,
+		    (vm_size_t)psize);
+		if (vaddr == 0) {
+			rman_deactivate_resource(r);
+			return (ENOMEM);
+		}
+		rman_set_bustag(r, (void *)1);
+#endif
+		rman_set_virtual(r, (void *)vaddr);
+		rman_set_bushandle(r, vaddr);
+	}
+	return (0);
+}
+
+static int
+nexus_deactivate_resource(device_t bus, device_t child, int type, int rid,
+    struct resource *r)
+{
+	bus_size_t psize;
+	bus_space_handle_t vaddr;
+
+	psize = (bus_size_t)rman_get_size(r);
+	vaddr = rman_get_bushandle(r);
+
+	if (vaddr != 0) {
+#ifdef FDT
+		bus_space_unmap(fdtbus_bs_tag, vaddr, psize);
+#else
+		pmap_unmapdev((vm_offset_t)vaddr, (vm_size_t)psize);
+#endif
+		rman_set_virtual(r, NULL);
+		rman_set_bushandle(r, 0);
+	}
+
+	return (rman_deactivate_resource(r));
+}
+
+#ifdef FDT
+static int
+nexus_ofw_map_intr(device_t dev, device_t child, phandle_t iparent, int icells,
+    pcell_t *intr)
+{
+	fdt_pic_decode_t intr_decode;
+	phandle_t intr_parent;
+	int i, rv, interrupt, trig, pol;
+
+	intr_parent = OF_node_from_xref(iparent);
+	for (i = 0; i < icells; i++)
+		intr[i] = cpu_to_fdt32(intr[i]);
+
+	for (i = 0; fdt_pic_table[i] != NULL; i++) {
+		intr_decode = fdt_pic_table[i];
+		rv = intr_decode(intr_parent, intr, &interrupt, &trig, &pol);
+
+		if (rv == 0) {
+			/* This was recognized as our PIC and decoded. */
+			interrupt = FDT_MAP_IRQ(intr_parent, interrupt);
+			return (interrupt);
+		}
+	}
+
+	/* Not in table, so guess */
+	interrupt = FDT_MAP_IRQ(intr_parent, fdt32_to_cpu(intr[0]));
+
+	return (interrupt);
+}
+#endif
+ 


Property changes on: trunk/sys/arm/arm/nexus.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/physmem.c
===================================================================
--- trunk/sys/arm/arm/physmem.c	                        (rev 0)
+++ trunk/sys/arm/arm/physmem.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,364 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014 Ian Lepore <ian at freebsd.org>
+ * All rights excluded.
+ *
+ * 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: stable/10/sys/arm/arm/physmem.c 294685 2016-01-24 22:00:36Z ian $");
+
+#include "opt_ddb.h"
+
+/*
+ * Routines for describing and initializing anything related to physical memory.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <vm/vm.h>
+#include <machine/md_var.h>
+#include <machine/physmem.h>
+
+/*
+ * These structures are used internally to keep track of regions of physical
+ * ram, and regions within the physical ram that need to be excluded.  An
+ * exclusion region can be excluded from crash dumps, from the vm pool of pages
+ * that can be allocated, or both, depending on the exclusion flags associated
+ * with the region.
+ */
+#define	MAX_HWCNT	10
+#define	MAX_EXCNT	10
+
+struct region {
+	vm_paddr_t	addr;
+	vm_size_t	size;
+	uint32_t	flags;
+};
+
+static struct region hwregions[MAX_HWCNT];
+static struct region exregions[MAX_EXCNT];
+
+static size_t hwcnt;
+static size_t excnt;
+
+/*
+ * These "avail lists" are globals used to communicate physical memory layout to 
+ * other parts of the kernel.  Within the arrays, each value is the starting
+ * address of a contiguous area of physical address space.  The values at even
+ * indexes are areas that contain usable memory and the values at odd indexes
+ * are areas that aren't usable.  Each list is terminated by a pair of zero
+ * entries.
+ *
+ * dump_avail tells the dump code what regions to include in a crash dump, and
+ * phys_avail is the way we hand all the remaining physical ram we haven't used
+ * in early kernel init over to the vm system for allocation management.
+ *
+ * We size these arrays to hold twice as many available regions as we allow for
+ * hardware memory regions, to allow for the fact that exclusions can split a
+ * hardware region into two or more available regions.  In the real world there
+ * will typically be one or two hardware regions and two or three exclusions.
+ *
+ * Each available region in this list occupies two array slots (the start of the
+ * available region and the start of the unavailable region that follows it).
+ */
+#define	MAX_AVAIL_REGIONS	(MAX_HWCNT * 2)
+#define	MAX_AVAIL_ENTRIES	(MAX_AVAIL_REGIONS * 2)
+
+vm_paddr_t phys_avail[MAX_AVAIL_ENTRIES + 2]; /* +2 to allow for a pair  */
+vm_paddr_t dump_avail[MAX_AVAIL_ENTRIES + 2]; /* of zeroes to terminate. */
+
+/*
+ * realmem is the total number of hardware pages, excluded or not.
+ * Maxmem is one greater than the last physical page number.
+ */
+long realmem;
+long Maxmem;
+
+/* The address at which the kernel was loaded.  Set early in initarm(). */
+vm_paddr_t arm_physmem_kernaddr;
+
+/*
+ * Print the contents of the physical and excluded region tables using the
+ * provided printf-like output function (which will be either printf or
+ * db_printf).
+ */
+static void
+physmem_dump_tables(int (*prfunc)(const char *, ...))
+{
+	int flags, i;
+	uintmax_t addr, size;
+	const unsigned int mbyte = 1024 * 1024;
+
+	prfunc("Physical memory chunk(s):\n");
+	for (i = 0; i < hwcnt; ++i) {
+		addr = hwregions[i].addr;
+		size = hwregions[i].size;
+		prfunc("  0x%08jx - 0x%08jx, %5ju MB (%7ju pages)\n", addr,
+		    addr + size - 1, size / mbyte, size / PAGE_SIZE);
+	}
+
+	prfunc("Excluded memory regions:\n");
+	for (i = 0; i < excnt; ++i) {
+		addr  = exregions[i].addr;
+		size  = exregions[i].size;
+		flags = exregions[i].flags;
+		prfunc("  0x%08jx - 0x%08jx, %5ju MB (%7ju pages) %s %s\n",
+		    addr, addr + size - 1, size / mbyte, size / PAGE_SIZE,
+		    (flags & EXFLAG_NOALLOC) ? "NoAlloc" : "",
+		    (flags & EXFLAG_NODUMP)  ? "NoDump" : "");
+	}
+
+#ifdef DEBUG
+	prfunc("Avail lists:\n");
+	for (i = 0; phys_avail[i] != 0; ++i) {
+		prfunc("  phys_avail[%d] 0x%08x\n", i, phys_avail[i]);
+	}
+	for (i = 0; dump_avail[i] != 0; ++i) {
+		prfunc("  dump_avail[%d] 0x%08x\n", i, dump_avail[i]);
+	}
+#endif
+}
+
+/*
+ * Print the contents of the static mapping table.  Used for bootverbose.
+ */
+void
+arm_physmem_print_tables()
+{
+
+	physmem_dump_tables(printf);
+}
+
+/*
+ * Walk the list of hardware regions, processing it against the list of
+ * exclusions that contain the given exflags, and generating an "avail list".
+ *
+ * Updates the value at *pavail with the sum of all pages in all hw regions.
+ *
+ * Returns the number of pages of non-excluded memory added to the avail list.
+ */
+static size_t
+regions_to_avail(vm_paddr_t *avail, uint32_t exflags, long *pavail)
+{
+	size_t acnt, exi, hwi;
+	uint64_t end, start, xend, xstart;
+	long availmem;
+	const struct region *exp, *hwp;
+
+	realmem = 0;
+	availmem = 0;
+	acnt = 0;
+	for (hwi = 0, hwp = hwregions; hwi < hwcnt; ++hwi, ++hwp) {
+		start = hwp->addr;
+		end   = hwp->size + start;
+		realmem += arm32_btop((vm_offset_t)(end - start));
+		for (exi = 0, exp = exregions; exi < excnt; ++exi, ++exp) {
+			/*
+			 * If the excluded region does not match given flags,
+			 * continue checking with the next excluded region.
+			 */
+			if ((exp->flags & exflags) == 0)
+				continue;
+			xstart = exp->addr;
+			xend   = exp->size + xstart;
+			/*
+			 * If the excluded region ends before this hw region,
+			 * continue checking with the next excluded region.
+			 */
+			if (xend <= start)
+				continue;
+			/*
+			 * If the excluded region begins after this hw region
+			 * we're done because both lists are sorted.
+			 */
+			if (xstart >= end)
+				break;
+			/*
+			 * If the excluded region completely covers this hw
+			 * region, shrink this hw region to zero size.
+			 */
+			if ((start >= xstart) && (end <= xend)) {
+				start = xend;
+				end = xend;
+				break;
+			}
+			/*
+			 * If the excluded region falls wholly within this hw
+			 * region without abutting or overlapping the beginning
+			 * or end, create an available entry from the leading
+			 * fragment, then adjust the start of this hw region to
+			 * the end of the excluded region, and continue checking
+			 * the next excluded region because another exclusion
+			 * could affect the remainder of this hw region.
+			 */
+			if ((xstart > start) && (xend < end)) {
+				avail[acnt++] = (vm_paddr_t)start;
+				avail[acnt++] = (vm_paddr_t)xstart;
+				availmem += 
+				    arm32_btop((vm_offset_t)(xstart - start));
+				start = xend;
+				continue;
+			}
+			/*
+			 * We know the excluded region overlaps either the start
+			 * or end of this hardware region (but not both), trim
+			 * the excluded portion off the appropriate end.
+			 */
+			if (xstart <= start)
+				start = xend;
+			else
+				end = xstart;
+		}
+		/*
+		 * If the trimming actions above left a non-zero size, create an
+		 * available entry for it.
+		 */
+		if (end > start) {
+			avail[acnt++] = (vm_paddr_t)start;
+			avail[acnt++] = (vm_paddr_t)end;
+			availmem += arm32_btop((vm_offset_t)(end - start));
+		}
+		if (acnt >= MAX_AVAIL_ENTRIES)
+			panic("Not enough space in the dump/phys_avail arrays");
+	}
+
+	if (pavail)
+		*pavail = availmem;
+	return (acnt);
+}
+
+/*
+ * Insertion-sort a new entry into a regions list; sorted by start address.
+ */
+static void
+insert_region(struct region *regions, size_t rcnt, vm_paddr_t addr,
+    vm_size_t size, uint32_t flags)
+{
+	size_t i;
+	struct region *ep, *rp;
+
+	ep = regions + rcnt;
+	for (i = 0, rp = regions; i < rcnt; ++i, ++rp) {
+		if (addr < rp->addr) {
+			bcopy(rp, rp + 1, (ep - rp) * sizeof(*rp));
+			break;
+		}
+	}
+	rp->addr  = addr;
+	rp->size  = size;
+	rp->flags = flags;
+}
+
+/*
+ * Add a hardware memory region.
+ */
+void
+arm_physmem_hardware_region(vm_paddr_t pa, vm_size_t sz)
+{
+	vm_offset_t adj;
+
+	/*
+	 * Filter out the page at PA 0x00000000.  The VM can't handle it, as
+	 * pmap_extract() == 0 means failure.
+	 *
+	 * Also filter out the page at the end of the physical address space --
+	 * if addr is non-zero and addr+size is zero we wrapped to the next byte
+	 * beyond what vm_paddr_t can express.  That leads to a NULL pointer
+	 * deref early in startup; work around it by leaving the last page out.
+	 *
+	 * XXX This just in:  subtract out a whole megabyte, not just 1 page.
+	 * Reducing the size by anything less than 1MB results in the NULL
+	 * pointer deref in _vm_map_lock_read().  Better to give up a megabyte
+	 * than leave some folks with an unusable system while we investigate.
+	 */
+	if (pa == 0) {
+		pa  = PAGE_SIZE;
+		sz -= PAGE_SIZE;
+	} else if (pa + sz == 0) {
+		sz -= 1024 * 1024;
+	}
+
+	/*
+	 * Round the starting address up to a page boundary, and truncate the
+	 * ending page down to a page boundary.
+	 */
+	adj = round_page(pa) - pa;
+	pa  = round_page(pa);
+	sz  = trunc_page(sz - adj);
+
+	if (hwcnt < nitems(hwregions))
+		insert_region(hwregions, hwcnt++, pa, sz, 0);
+}
+
+/*
+ * Add an exclusion region.
+ */
+void arm_physmem_exclude_region(vm_paddr_t pa, vm_size_t sz, uint32_t exflags)
+{
+	vm_offset_t adj;
+
+	/*
+	 * Truncate the starting address down to a page boundary, and round the
+	 * ending page up to a page boundary.
+	 */
+	adj = pa - trunc_page(pa);
+	pa  = trunc_page(pa);
+	sz  = round_page(sz + adj);
+
+	if (excnt < nitems(exregions))
+		insert_region(exregions, excnt++, pa, sz, exflags);
+}
+
+/*
+ * Process all the regions added earlier into the global avail lists.
+ *
+ * Updates the kernel global 'physmem' with the number of physical pages
+ * available for use (all pages not in any exclusion region).
+ *
+ * Updates the kernel global 'Maxmem' with the page number one greater then the
+ * last page of physical memory in the system.
+ */
+void
+arm_physmem_init_kernel_globals(void)
+{
+	size_t nextidx;
+
+	regions_to_avail(dump_avail, EXFLAG_NODUMP, NULL);
+	nextidx = regions_to_avail(phys_avail, EXFLAG_NOALLOC, &physmem);
+	if (nextidx == 0)
+		panic("No memory entries in phys_avail");
+	Maxmem = atop(phys_avail[nextidx - 1]);
+}
+
+#ifdef DDB
+#include <ddb/ddb.h>
+
+DB_SHOW_COMMAND(physmem, db_show_physmem)
+{
+
+	physmem_dump_tables(db_printf);
+}
+
+#endif /* DDB */
+


Property changes on: trunk/sys/arm/arm/physmem.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/pl190.c
===================================================================
--- trunk/sys/arm/arm/pl190.c	                        (rev 0)
+++ trunk/sys/arm/arm/pl190.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,193 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Oleksandr Tymoshenko <gonzo at bluezbox.com>
+ * 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: stable/10/sys/arm/arm/pl190.c 270075 2014-08-17 01:28:03Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/ktr.h>
+#include <sys/module.h>
+#include <sys/rman.h>
+#include <machine/bus.h>
+#include <machine/intr.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#ifdef  DEBUG
+#define dprintf(fmt, args...) printf(fmt, ##args)
+#else
+#define dprintf(fmt, args...)
+#endif
+
+#define	VICIRQSTATUS	0x000
+#define	VICFIQSTATUS	0x004
+#define	VICRAWINTR	0x008
+#define	VICINTSELECT	0x00C
+#define	VICINTENABLE	0x010
+#define	VICINTENCLEAR	0x014
+#define	VICSOFTINT	0x018
+#define	VICSOFTINTCLEAR	0x01C
+#define	VICPROTECTION	0x020
+#define	VICPERIPHID	0xFE0
+#define	VICPRIMECELLID	0xFF0
+
+#define	VIC_NIRQS	32
+
+struct pl190_intc_softc {
+	device_t		sc_dev;
+	struct resource *	intc_res;
+};
+
+static struct pl190_intc_softc *pl190_intc_sc = NULL;
+
+#define	intc_vic_read_4(reg)		\
+    bus_read_4(pl190_intc_sc->intc_res, (reg))
+#define	intc_vic_write_4(reg, val)		\
+    bus_write_4(pl190_intc_sc->intc_res, (reg), (val))
+
+static int
+pl190_intc_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "arm,versatile-vic"))
+		return (ENXIO);
+	device_set_desc(dev, "ARM PL190 VIC");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+pl190_intc_attach(device_t dev)
+{
+	struct		pl190_intc_softc *sc = device_get_softc(dev);
+	uint32_t	id;
+	int		i, rid;
+
+	sc->sc_dev = dev;
+
+	if (pl190_intc_sc)
+		return (ENXIO);
+
+	/* Request memory resources */
+	rid = 0;
+	sc->intc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	    RF_ACTIVE);
+	if (sc->intc_res == NULL) {
+		device_printf(dev, "Error: could not allocate memory resources\n");
+		return (ENXIO);
+	}
+
+	pl190_intc_sc = sc;
+	/*
+	 * All interrupts should use IRQ line
+	 */
+	intc_vic_write_4(VICINTSELECT, 0x00000000);
+	/* Disable all interrupts */
+	intc_vic_write_4(VICINTENCLEAR, 0xffffffff);
+	/* Enable INT31, SIC IRQ */
+	intc_vic_write_4(VICINTENABLE, (1U << 31));
+
+	id = 0;
+	for (i = 3; i >= 0; i--) {
+		id = (id << 8) | 
+		     (intc_vic_read_4(VICPERIPHID + i*4) & 0xff);
+	}
+
+	device_printf(dev, "Peripheral ID: %08x\n", id);
+
+	id = 0;
+	for (i = 3; i >= 0; i--) {
+		id = (id << 8) | 
+		     (intc_vic_read_4(VICPRIMECELLID + i*4) & 0xff);
+	}
+
+	device_printf(dev, "PrimeCell ID: %08x\n", id);
+
+	return (0);
+}
+
+static device_method_t pl190_intc_methods[] = {
+	DEVMETHOD(device_probe,		pl190_intc_probe),
+	DEVMETHOD(device_attach,	pl190_intc_attach),
+	{ 0, 0 }
+};
+
+static driver_t pl190_intc_driver = {
+	"intc",
+	pl190_intc_methods,
+	sizeof(struct pl190_intc_softc),
+};
+
+static devclass_t pl190_intc_devclass;
+
+EARLY_DRIVER_MODULE(intc, simplebus, pl190_intc_driver, pl190_intc_devclass, 
+    0, 0, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE);
+
+int
+arm_get_next_irq(int last_irq)
+{
+	uint32_t pending;
+	int32_t irq = last_irq + 1;
+
+	/* Sanity check */
+	if (irq < 0)
+		irq = 0;
+	
+	pending = intc_vic_read_4(VICIRQSTATUS);
+	while (irq < VIC_NIRQS) {
+		if (pending & (1 << irq))
+			return (irq);
+		irq++;
+	}
+
+	return (-1);
+}
+
+void
+arm_mask_irq(uintptr_t nb)
+{
+
+	dprintf("%s: %d\n", __func__, nb);
+	intc_vic_write_4(VICINTENCLEAR, (1 << nb));
+}
+
+void
+arm_unmask_irq(uintptr_t nb)
+{
+
+	dprintf("%s: %d\n", __func__, nb);
+	intc_vic_write_4(VICINTENABLE, (1 << nb));
+}


Property changes on: trunk/sys/arm/arm/pl190.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/pl310.c
===================================================================
--- trunk/sys/arm/arm/pl310.c	                        (rev 0)
+++ trunk/sys/arm/arm/pl310.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,545 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Olivier Houchard <cognet at FreeBSD.org>
+ * Copyright (c) 2011
+ *	Ben Gray <ben.r.gray at gmail.com>.
+ * 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.
+ * 3. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BEN GRAY ``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 BEN GRAY 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: stable/10/sys/arm/arm/pl310.c 273695 2014-10-26 16:09:59Z ian $");
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/rman.h>
+#include <sys/module.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <machine/intr.h>
+
+#include <machine/bus.h>
+#include <machine/pl310.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+/*
+ * Define this if you need to disable PL310 for debugging purpose
+ * Spec: 
+ * http://infocenter.arm.com/help/topic/com.arm.doc.ddi0246e/DDI0246E_l2c310_r3p1_trm.pdf
+ */
+
+/* 
+ * Hardcode errata for now
+ * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0246b/pr01s02s02.html
+ */
+#define	PL310_ERRATA_588369
+#define	PL310_ERRATA_753970
+#define	PL310_ERRATA_727915
+
+#define	PL310_LOCK(sc) do {		\
+	mtx_lock_spin(&(sc)->sc_mtx);	\
+} while(0);
+
+#define	PL310_UNLOCK(sc) do {		\
+	mtx_unlock_spin(&(sc)->sc_mtx);	\
+} while(0);
+
+static int pl310_enabled = 1;
+TUNABLE_INT("hw.pl310.enabled", &pl310_enabled);
+
+static uint32_t g_l2cache_way_mask;
+
+static const uint32_t g_l2cache_line_size = 32;
+static const uint32_t g_l2cache_align_mask = (32 - 1);
+
+static uint32_t g_l2cache_size;
+static uint32_t g_way_size;
+static uint32_t g_ways_assoc;
+
+static struct pl310_softc *pl310_softc;
+
+static struct ofw_compat_data compat_data[] = {
+	{"arm,pl310",		true}, /* Non-standard, FreeBSD. */
+	{"arm,pl310-cache",	true},
+	{NULL,			false}
+};
+
+void
+pl310_print_config(struct pl310_softc *sc)
+{
+	uint32_t aux, prefetch;
+	const char *dis = "disabled";
+	const char *ena = "enabled";
+
+	aux = pl310_read4(sc, PL310_AUX_CTRL);
+	prefetch = pl310_read4(sc, PL310_PREFETCH_CTRL);
+
+	device_printf(sc->sc_dev, "Early BRESP response: %s\n",
+		(aux & AUX_CTRL_EARLY_BRESP) ? ena : dis);
+	device_printf(sc->sc_dev, "Instruction prefetch: %s\n",
+		(aux & AUX_CTRL_INSTR_PREFETCH) ? ena : dis);
+	device_printf(sc->sc_dev, "Data prefetch: %s\n",
+		(aux & AUX_CTRL_DATA_PREFETCH) ? ena : dis);
+	device_printf(sc->sc_dev, "Non-secure interrupt control: %s\n",
+		(aux & AUX_CTRL_NS_INT_CTRL) ? ena : dis);
+	device_printf(sc->sc_dev, "Non-secure lockdown: %s\n",
+		(aux & AUX_CTRL_NS_LOCKDOWN) ? ena : dis);
+	device_printf(sc->sc_dev, "Share override: %s\n",
+		(aux & AUX_CTRL_SHARE_OVERRIDE) ? ena : dis);
+
+	device_printf(sc->sc_dev, "Double linefill: %s\n",
+		(prefetch & PREFETCH_CTRL_DL) ? ena : dis);
+	device_printf(sc->sc_dev, "Instruction prefetch: %s\n",
+		(prefetch & PREFETCH_CTRL_INSTR_PREFETCH) ? ena : dis);
+	device_printf(sc->sc_dev, "Data prefetch: %s\n",
+		(prefetch & PREFETCH_CTRL_DATA_PREFETCH) ? ena : dis);
+	device_printf(sc->sc_dev, "Double linefill on WRAP request: %s\n",
+		(prefetch & PREFETCH_CTRL_DL_ON_WRAP) ? ena : dis);
+	device_printf(sc->sc_dev, "Prefetch drop: %s\n",
+		(prefetch & PREFETCH_CTRL_PREFETCH_DROP) ? ena : dis);
+	device_printf(sc->sc_dev, "Incr double Linefill: %s\n",
+		(prefetch & PREFETCH_CTRL_INCR_DL) ? ena : dis);
+	device_printf(sc->sc_dev, "Not same ID on exclusive sequence: %s\n",
+		(prefetch & PREFETCH_CTRL_NOTSAMEID) ? ena : dis);
+	device_printf(sc->sc_dev, "Prefetch offset: %d\n",
+		(prefetch & PREFETCH_CTRL_OFFSET_MASK));
+}
+
+void
+pl310_set_ram_latency(struct pl310_softc *sc, uint32_t which_reg,
+   uint32_t read, uint32_t write, uint32_t setup)
+{
+	uint32_t v;
+
+	KASSERT(which_reg == PL310_TAG_RAM_CTRL || 
+	    which_reg == PL310_DATA_RAM_CTRL,
+	    ("bad pl310 ram latency register address"));
+
+	v = pl310_read4(sc, which_reg);
+	if (setup != 0) {
+		KASSERT(setup <= 8, ("bad pl310 setup latency: %d", setup));
+		v &= ~RAM_CTRL_SETUP_MASK;
+		v |= (setup - 1) << RAM_CTRL_SETUP_SHIFT;
+	}
+	if (read != 0) {
+		KASSERT(read <= 8, ("bad pl310 read latency: %d", read));
+		v &= ~RAM_CTRL_READ_MASK;
+		v |= (read - 1) << RAM_CTRL_READ_SHIFT;
+	}
+	if (write != 0) {
+		KASSERT(write <= 8, ("bad pl310 write latency: %d", write));
+		v &= ~RAM_CTRL_WRITE_MASK;
+		v |= (write - 1) << RAM_CTRL_WRITE_SHIFT;
+	}
+	pl310_write4(sc, which_reg, v);
+}
+
+static int
+pl310_filter(void *arg)
+{
+	struct pl310_softc *sc = arg;
+	uint32_t intr;
+
+	intr = pl310_read4(sc, PL310_INTR_MASK);
+
+	if (!sc->sc_enabled && (intr & INTR_MASK_ECNTR)) {
+		/*
+		 * This is for debug purpose, so be blunt about it
+		 * We disable PL310 only when something fishy is going
+		 * on and we need to make sure L2 cache is 100% disabled
+		 */
+		panic("pl310: caches disabled but cache event detected\n");
+	}
+
+	return (FILTER_HANDLED);
+}
+
+static __inline void
+pl310_wait_background_op(uint32_t off, uint32_t mask)
+{
+
+	while (pl310_read4(pl310_softc, off) & mask)
+		continue;
+}
+
+
+/**
+ *	pl310_cache_sync - performs a cache sync operation
+ * 
+ *	According to the TRM:
+ *
+ *  "Before writing to any other register you must perform an explicit
+ *   Cache Sync operation. This is particularly important when the cache is
+ *   enabled and changes to how the cache allocates new lines are to be made."
+ *
+ *
+ */
+static __inline void
+pl310_cache_sync(void)
+{
+
+	if ((pl310_softc == NULL) || !pl310_softc->sc_enabled)
+		return;
+
+#ifdef PL310_ERRATA_753970
+	if (pl310_softc->sc_rtl_revision == CACHE_ID_RELEASE_r3p0)
+		/* Write uncached PL310 register */
+		pl310_write4(pl310_softc, 0x740, 0xffffffff);
+	else
+#endif
+		pl310_write4(pl310_softc, PL310_CACHE_SYNC, 0xffffffff);
+}
+
+
+static void
+pl310_wbinv_all(void)
+{
+
+	if ((pl310_softc == NULL) || !pl310_softc->sc_enabled)
+		return;
+
+	PL310_LOCK(pl310_softc);
+#ifdef PL310_ERRATA_727915
+	if (pl310_softc->sc_rtl_revision == CACHE_ID_RELEASE_r2p0) {
+		int i, j;
+
+		for (i = 0; i < g_ways_assoc; i++) {
+			for (j = 0; j < g_way_size / g_l2cache_line_size; j++) {
+				pl310_write4(pl310_softc, 
+				    PL310_CLEAN_INV_LINE_IDX,
+				    (i << 28 | j << 5));
+			}
+		}
+		pl310_cache_sync();
+		PL310_UNLOCK(pl310_softc);
+		return;
+
+	}
+	if (pl310_softc->sc_rtl_revision == CACHE_ID_RELEASE_r3p0)
+		platform_pl310_write_debug(pl310_softc, 3);
+#endif
+	pl310_write4(pl310_softc, PL310_CLEAN_INV_WAY, g_l2cache_way_mask);
+	pl310_wait_background_op(PL310_CLEAN_INV_WAY, g_l2cache_way_mask);
+	pl310_cache_sync();
+#ifdef PL310_ERRATA_727915
+	if (pl310_softc->sc_rtl_revision == CACHE_ID_RELEASE_r3p0)
+		platform_pl310_write_debug(pl310_softc, 0);
+#endif
+	PL310_UNLOCK(pl310_softc);
+}
+
+static void
+pl310_wbinv_range(vm_paddr_t start, vm_size_t size)
+{
+
+	if ((pl310_softc == NULL) || !pl310_softc->sc_enabled)
+		return;
+
+	PL310_LOCK(pl310_softc);
+	if (start & g_l2cache_align_mask) {
+		size += start & g_l2cache_align_mask;
+		start &= ~g_l2cache_align_mask;
+	}
+	if (size & g_l2cache_align_mask) {
+		size &= ~g_l2cache_align_mask;
+	   	size += g_l2cache_line_size;
+	}
+
+
+#ifdef PL310_ERRATA_727915
+	platform_pl310_write_debug(pl310_softc, 3);
+#endif
+	while (size > 0) {
+#ifdef PL310_ERRATA_588369
+		if (pl310_softc->sc_rtl_revision <= CACHE_ID_RELEASE_r1p0) {
+			/* 
+			 * Errata 588369 says that clean + inv may keep the 
+			 * cache line if it was clean, the recommanded
+			 * workaround is to clean then invalidate the cache
+			 * line, with write-back and cache linefill disabled.
+			 */
+			pl310_write4(pl310_softc, PL310_CLEAN_LINE_PA, start);
+			pl310_write4(pl310_softc, PL310_INV_LINE_PA, start);
+		} else
+#endif
+			pl310_write4(pl310_softc, PL310_CLEAN_INV_LINE_PA,
+			    start);
+		start += g_l2cache_line_size;
+		size -= g_l2cache_line_size;
+	}
+#ifdef PL310_ERRATA_727915
+	platform_pl310_write_debug(pl310_softc, 0);
+#endif
+
+	pl310_cache_sync();
+	PL310_UNLOCK(pl310_softc);
+}
+
+static void
+pl310_wb_range(vm_paddr_t start, vm_size_t size)
+{
+
+	if ((pl310_softc == NULL) || !pl310_softc->sc_enabled)
+		return;
+
+	PL310_LOCK(pl310_softc);
+	if (start & g_l2cache_align_mask) {
+		size += start & g_l2cache_align_mask;
+		start &= ~g_l2cache_align_mask;
+	}
+
+	if (size & g_l2cache_align_mask) {
+		size &= ~g_l2cache_align_mask;
+		size += g_l2cache_line_size;
+	}
+
+	while (size > 0) {
+		pl310_write4(pl310_softc, PL310_CLEAN_LINE_PA, start);
+		start += g_l2cache_line_size;
+		size -= g_l2cache_line_size;
+	}
+
+	pl310_cache_sync();
+	PL310_UNLOCK(pl310_softc);
+}
+
+static void
+pl310_inv_range(vm_paddr_t start, vm_size_t size)
+{
+
+	if ((pl310_softc == NULL) || !pl310_softc->sc_enabled)
+		return;
+
+	PL310_LOCK(pl310_softc);
+	if (start & g_l2cache_align_mask) {
+		size += start & g_l2cache_align_mask;
+		start &= ~g_l2cache_align_mask;
+	}
+	if (size & g_l2cache_align_mask) {
+		size &= ~g_l2cache_align_mask;
+		size += g_l2cache_line_size;
+	}
+	while (size > 0) {
+		pl310_write4(pl310_softc, PL310_INV_LINE_PA, start);
+		start += g_l2cache_line_size;
+		size -= g_l2cache_line_size;
+	}
+
+	pl310_cache_sync();
+	PL310_UNLOCK(pl310_softc);
+}
+
+static void
+pl310_drain_writebuf(void)
+{
+
+	if ((pl310_softc == NULL) || !pl310_softc->sc_enabled)
+		return;
+
+	PL310_LOCK(pl310_softc);
+	pl310_cache_sync();
+	PL310_UNLOCK(pl310_softc);
+}
+
+static void
+pl310_set_way_sizes(struct pl310_softc *sc)
+{
+	uint32_t aux_value;
+
+	aux_value = pl310_read4(sc, PL310_AUX_CTRL);
+	g_way_size = (aux_value & AUX_CTRL_WAY_SIZE_MASK) >>
+	    AUX_CTRL_WAY_SIZE_SHIFT;
+	g_way_size = 1 << (g_way_size + 13);
+	if (aux_value & (1 << AUX_CTRL_ASSOCIATIVITY_SHIFT))
+		g_ways_assoc = 16;
+	else
+		g_ways_assoc = 8;
+	g_l2cache_way_mask = (1 << g_ways_assoc) - 1;
+	g_l2cache_size = g_way_size * g_ways_assoc;
+}
+
+/*
+ * Setup interrupt handling.  This is done only if the cache controller is
+ * disabled, for debugging.  We set counters so when a cache event happens we'll
+ * get interrupted and be warned that something is wrong, because no cache
+ * events should happen if we're disabled.
+ */
+static void
+pl310_config_intr(void *arg)
+{
+	struct pl310_softc * sc;
+
+	sc = arg;
+
+	/* activate the interrupt */
+	bus_setup_intr(sc->sc_dev, sc->sc_irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
+	    pl310_filter, NULL, sc, &sc->sc_irq_h);
+
+	/* Cache Line Eviction for Counter 0 */
+	pl310_write4(sc, PL310_EVENT_COUNTER0_CONF, 
+	    EVENT_COUNTER_CONF_INCR | EVENT_COUNTER_CONF_CO);
+	/* Data Read Request for Counter 1 */
+	pl310_write4(sc, PL310_EVENT_COUNTER1_CONF, 
+	    EVENT_COUNTER_CONF_INCR | EVENT_COUNTER_CONF_DRREQ);
+
+	/* Enable and clear pending interrupts */
+	pl310_write4(sc, PL310_INTR_CLEAR, INTR_MASK_ECNTR);
+	pl310_write4(sc, PL310_INTR_MASK, INTR_MASK_ALL);
+
+	/* Enable counters and reset C0 and C1 */
+	pl310_write4(sc, PL310_EVENT_COUNTER_CTRL, 
+	    EVENT_COUNTER_CTRL_ENABLED | 
+	    EVENT_COUNTER_CTRL_C0_RESET | 
+	    EVENT_COUNTER_CTRL_C1_RESET);
+
+	config_intrhook_disestablish(sc->sc_ich);
+	free(sc->sc_ich, M_DEVBUF);
+}
+
+static int
+pl310_probe(device_t dev)
+{
+	
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+	if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data)
+		return (ENXIO);
+	device_set_desc(dev, "PL310 L2 cache controller");
+	return (0);
+}
+
+static int
+pl310_attach(device_t dev)
+{
+	struct pl310_softc *sc = device_get_softc(dev);
+	int rid;
+	uint32_t cache_id, debug_ctrl;
+
+	sc->sc_dev = dev;
+	rid = 0;
+	sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 
+	    RF_ACTIVE);
+	if (sc->sc_mem_res == NULL)
+		panic("%s: Cannot map registers", device_get_name(dev));
+
+	/* Allocate an IRQ resource */
+	rid = 0;
+	sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+	                                        RF_ACTIVE | RF_SHAREABLE);
+	if (sc->sc_irq_res == NULL) {
+		panic("Cannot allocate IRQ\n");
+	}
+
+	pl310_softc = sc;
+	mtx_init(&sc->sc_mtx, "pl310lock", NULL, MTX_SPIN);
+
+	cache_id = pl310_read4(sc, PL310_CACHE_ID);
+	sc->sc_rtl_revision = (cache_id >> CACHE_ID_RELEASE_SHIFT) &
+	    CACHE_ID_RELEASE_MASK;
+	device_printf(dev, "Part number: 0x%x, release: 0x%x\n",
+	    (cache_id >> CACHE_ID_PARTNUM_SHIFT) & CACHE_ID_PARTNUM_MASK,
+	    (cache_id >> CACHE_ID_RELEASE_SHIFT) & CACHE_ID_RELEASE_MASK);
+
+	/*
+	 * If L2 cache is already enabled then something has violated the rules,
+	 * because caches are supposed to be off at kernel entry.  The cache
+	 * must be disabled to write the configuration registers without
+	 * triggering an access error (SLVERR), but there's no documented safe
+	 * procedure for disabling the L2 cache in the manual.  So we'll try to
+	 * invent one:
+	 *  - Use the debug register to force write-through mode and prevent
+	 *    linefills (allocation of new lines on read); now anything we do
+	 *    will not cause new data to come into the L2 cache.
+	 *  - Writeback and invalidate the current contents.
+	 *  - Disable the controller.
+	 *  - Restore the original debug settings.
+	 */
+	if (pl310_read4(sc, PL310_CTRL) & CTRL_ENABLED) {
+		device_printf(dev, "Warning: L2 Cache should not already be "
+		    "active; trying to de-activate and re-initialize...\n");
+		sc->sc_enabled = 1;
+		debug_ctrl = pl310_read4(sc, PL310_DEBUG_CTRL);
+		platform_pl310_write_debug(sc, debug_ctrl |
+		    DEBUG_CTRL_DISABLE_WRITEBACK | DEBUG_CTRL_DISABLE_LINEFILL);
+		pl310_set_way_sizes(sc);
+		pl310_wbinv_all();
+		platform_pl310_write_ctrl(sc, CTRL_DISABLED);
+		platform_pl310_write_debug(sc, debug_ctrl);
+	}
+	sc->sc_enabled = pl310_enabled;
+
+	if (sc->sc_enabled) {
+		platform_pl310_init(sc);
+		pl310_set_way_sizes(sc); /* platform init might change these */
+		pl310_write4(pl310_softc, PL310_INV_WAY, 0xffff);
+		pl310_wait_background_op(PL310_INV_WAY, 0xffff);
+		platform_pl310_write_ctrl(sc, CTRL_ENABLED);
+		device_printf(dev, "L2 Cache enabled: %uKB/%dB %d ways\n", 
+		    (g_l2cache_size / 1024), g_l2cache_line_size, g_ways_assoc);
+		if (bootverbose)
+			pl310_print_config(sc);
+	} else {
+		malloc(sizeof(*sc->sc_ich), M_DEVBUF, M_WAITOK);
+		sc->sc_ich->ich_func = pl310_config_intr;
+		sc->sc_ich->ich_arg = sc;
+		if (config_intrhook_establish(sc->sc_ich) != 0) {
+			device_printf(dev,
+			    "config_intrhook_establish failed\n");
+			return(ENXIO);
+		}
+		device_printf(dev, "L2 Cache disabled\n");
+	}
+
+	/* Set the l2 functions in the set of cpufuncs */
+	cpufuncs.cf_l2cache_wbinv_all = pl310_wbinv_all;
+	cpufuncs.cf_l2cache_wbinv_range = pl310_wbinv_range;
+	cpufuncs.cf_l2cache_inv_range = pl310_inv_range;
+	cpufuncs.cf_l2cache_wb_range = pl310_wb_range;
+	cpufuncs.cf_l2cache_drain_writebuf = pl310_drain_writebuf;
+
+	return (0);
+}
+
+static device_method_t pl310_methods[] = {
+	DEVMETHOD(device_probe, pl310_probe),
+	DEVMETHOD(device_attach, pl310_attach),
+	DEVMETHOD_END
+};
+
+static driver_t pl310_driver = {
+        "l2cache",
+        pl310_methods,
+        sizeof(struct pl310_softc),
+};
+static devclass_t pl310_devclass;
+
+EARLY_DRIVER_MODULE(pl310, simplebus, pl310_driver, pl310_devclass, 0, 0,
+    BUS_PASS_CPU + BUS_PASS_ORDER_MIDDLE);
+


Property changes on: trunk/sys/arm/arm/pl310.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/pmap-v6.c
===================================================================
--- trunk/sys/arm/arm/pmap-v6.c	                        (rev 0)
+++ trunk/sys/arm/arm/pmap-v6.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,5342 @@
+/* $MidnightBSD$ */
+/* From: $NetBSD: pmap.c,v 1.148 2004/04/03 04:35:48 bsh Exp $ */
+/*-
+ * Copyright 2011 Semihalf
+ * Copyright 2004 Olivier Houchard.
+ * Copyright 2003 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Steve C. Woodford for Wasabi Systems, Inc.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed for the NetBSD Project by
+ *      Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
+ * 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.
+ *
+ * From: FreeBSD: src/sys/arm/arm/pmap.c,v 1.113 2009/07/24 13:50:29
+ */
+
+/*-
+ * Copyright (c) 2002-2003 Wasabi Systems, Inc.
+ * Copyright (c) 2001 Richard Earnshaw
+ * Copyright (c) 2001-2002 Christopher Gilbert
+ * All rights reserved.
+ *
+ * 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.
+ * 3. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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.
+ */
+/*-
+ * Copyright (c) 1999 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Charles M. Hannum.
+ *
+ * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
+ */
+
+/*-
+ * Copyright (c) 1994-1998 Mark Brinicombe.
+ * Copyright (c) 1994 Brini.
+ * All rights reserved.
+ *
+ * This code is derived from software written for Brini by Mark Brinicombe
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by Mark Brinicombe.
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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
+ *
+ * RiscBSD kernel project
+ *
+ * pmap.c
+ *
+ * Machine dependant vm stuff
+ *
+ * Created      : 20/09/94
+ */
+
+/*
+ * Special compilation symbols
+ * PMAP_DEBUG           - Build in pmap_debug_level code
+ *
+ * Note that pmap_mapdev() and pmap_unmapdev() are implemented in arm/devmap.c
+*/
+/* Include header files */
+
+#include "opt_vm.h"
+#include "opt_pmap.h"
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/pmap-v6.c 278614 2015-02-12 04:15:55Z ian $");
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/ktr.h>
+#include <sys/lock.h>
+#include <sys/proc.h>
+#include <sys/malloc.h>
+#include <sys/msgbuf.h>
+#include <sys/mutex.h>
+#include <sys/vmmeter.h>
+#include <sys/mman.h>
+#include <sys/rwlock.h>
+#include <sys/smp.h>
+#include <sys/sched.h>
+#include <sys/sysctl.h>
+
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+#include <vm/uma.h>
+#include <vm/pmap.h>
+#include <vm/vm_kern.h>
+#include <vm/vm_object.h>
+#include <vm/vm_map.h>
+#include <vm/vm_page.h>
+#include <vm/vm_pageout.h>
+#include <vm/vm_phys.h>
+#include <vm/vm_extern.h>
+#include <vm/vm_reserv.h>
+
+#include <machine/md_var.h>
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+#include <machine/pcb.h>
+
+#ifdef DEBUG
+extern int last_fault_code;
+#endif
+
+#ifdef PMAP_DEBUG
+#define PDEBUG(_lev_,_stat_) \
+        if (pmap_debug_level >= (_lev_)) \
+                ((_stat_))
+#define dprintf printf
+
+int pmap_debug_level = 0;
+#define PMAP_INLINE
+#else   /* PMAP_DEBUG */
+#define PDEBUG(_lev_,_stat_) /* Nothing */
+#define dprintf(x, arg...)
+#define PMAP_INLINE __inline
+#endif  /* PMAP_DEBUG */
+
+#ifdef PV_STATS
+#define PV_STAT(x)	do { x ; } while (0)
+#else
+#define PV_STAT(x)	do { } while (0)
+#endif
+
+#define	pa_to_pvh(pa)	(&pv_table[pa_index(pa)])
+
+#ifdef ARM_L2_PIPT
+#define pmap_l2cache_wbinv_range(va, pa, size) cpu_l2cache_wbinv_range((pa), (size))
+#define pmap_l2cache_inv_range(va, pa, size) cpu_l2cache_inv_range((pa), (size))
+#else
+#define pmap_l2cache_wbinv_range(va, pa, size) cpu_l2cache_wbinv_range((va), (size))
+#define pmap_l2cache_inv_range(va, pa, size) cpu_l2cache_inv_range((va), (size))
+#endif
+
+extern struct pv_addr systempage;
+
+/*
+ * Internal function prototypes
+ */
+
+static PMAP_INLINE
+struct pv_entry		*pmap_find_pv(struct md_page *, pmap_t, vm_offset_t);
+static void		pmap_free_pv_chunk(struct pv_chunk *pc);
+static void		pmap_free_pv_entry(pmap_t pmap, pv_entry_t pv);
+static pv_entry_t 	pmap_get_pv_entry(pmap_t pmap, boolean_t try);
+static vm_page_t 	pmap_pv_reclaim(pmap_t locked_pmap);
+static boolean_t	pmap_pv_insert_section(pmap_t, vm_offset_t,
+    vm_paddr_t);
+static struct pv_entry	*pmap_remove_pv(struct vm_page *, pmap_t, vm_offset_t);
+static int		pmap_pvh_wired_mappings(struct md_page *, int);
+
+static int		pmap_enter_locked(pmap_t, vm_offset_t, vm_page_t,
+    vm_prot_t, u_int);
+static vm_paddr_t	pmap_extract_locked(pmap_t pmap, vm_offset_t va);
+static void		pmap_alloc_l1(pmap_t);
+static void		pmap_free_l1(pmap_t);
+
+static void		pmap_map_section(pmap_t, vm_offset_t, vm_offset_t,
+    vm_prot_t, boolean_t);
+static void		pmap_promote_section(pmap_t, vm_offset_t);
+static boolean_t	pmap_demote_section(pmap_t, vm_offset_t);
+static boolean_t	pmap_enter_section(pmap_t, vm_offset_t, vm_page_t,
+    vm_prot_t);
+static void		pmap_remove_section(pmap_t, vm_offset_t);
+
+static int		pmap_clearbit(struct vm_page *, u_int);
+
+static struct l2_bucket *pmap_get_l2_bucket(pmap_t, vm_offset_t);
+static struct l2_bucket *pmap_alloc_l2_bucket(pmap_t, vm_offset_t);
+static void		pmap_free_l2_bucket(pmap_t, struct l2_bucket *, u_int);
+static vm_offset_t	kernel_pt_lookup(vm_paddr_t);
+
+static MALLOC_DEFINE(M_VMPMAP, "pmap", "PMAP L1");
+
+vm_offset_t virtual_avail;	/* VA of first avail page (after kernel bss) */
+vm_offset_t virtual_end;	/* VA of last avail page (end of kernel AS) */
+vm_offset_t pmap_curmaxkvaddr;
+vm_paddr_t kernel_l1pa;
+
+vm_offset_t kernel_vm_end = 0;
+
+vm_offset_t vm_max_kernel_address;
+
+struct pmap kernel_pmap_store;
+
+/*
+ * Resources for quickly copying and zeroing pages using virtual address space
+ * and page table entries that are pre-allocated per-CPU by pmap_init().
+ */
+struct czpages {
+	struct	mtx 	lock;
+	pt_entry_t	*srcptep;
+	pt_entry_t	*dstptep;
+	vm_offset_t	srcva;
+	vm_offset_t	dstva;
+};
+static struct czpages cpu_czpages[MAXCPU];
+
+static void		pmap_init_l1(struct l1_ttable *, pd_entry_t *);
+/*
+ * These routines are called when the CPU type is identified to set up
+ * the PTE prototypes, cache modes, etc.
+ *
+ * The variables are always here, just in case LKMs need to reference
+ * them (though, they shouldn't).
+ */
+static void pmap_set_prot(pt_entry_t *pte, vm_prot_t prot, uint8_t user);
+pt_entry_t	pte_l1_s_cache_mode;
+pt_entry_t	pte_l1_s_cache_mode_pt;
+
+pt_entry_t	pte_l2_l_cache_mode;
+pt_entry_t	pte_l2_l_cache_mode_pt;
+
+pt_entry_t	pte_l2_s_cache_mode;
+pt_entry_t	pte_l2_s_cache_mode_pt;
+
+struct msgbuf *msgbufp = 0;
+
+/*
+ * Crashdump maps.
+ */
+static caddr_t crashdumpmap;
+
+extern void bcopy_page(vm_offset_t, vm_offset_t);
+extern void bzero_page(vm_offset_t);
+
+char *_tmppt;
+
+/*
+ * Metadata for L1 translation tables.
+ */
+struct l1_ttable {
+	/* Entry on the L1 Table list */
+	SLIST_ENTRY(l1_ttable) l1_link;
+
+	/* Entry on the L1 Least Recently Used list */
+	TAILQ_ENTRY(l1_ttable) l1_lru;
+
+	/* Track how many domains are allocated from this L1 */
+	volatile u_int l1_domain_use_count;
+
+	/*
+	 * A free-list of domain numbers for this L1.
+	 * We avoid using ffs() and a bitmap to track domains since ffs()
+	 * is slow on ARM.
+	 */
+	u_int8_t l1_domain_first;
+	u_int8_t l1_domain_free[PMAP_DOMAINS];
+
+	/* Physical address of this L1 page table */
+	vm_paddr_t l1_physaddr;
+
+	/* KVA of this L1 page table */
+	pd_entry_t *l1_kva;
+};
+
+/*
+ * Convert a virtual address into its L1 table index. That is, the
+ * index used to locate the L2 descriptor table pointer in an L1 table.
+ * This is basically used to index l1->l1_kva[].
+ *
+ * Each L2 descriptor table represents 1MB of VA space.
+ */
+#define	L1_IDX(va)		(((vm_offset_t)(va)) >> L1_S_SHIFT)
+
+/*
+ * L1 Page Tables are tracked using a Least Recently Used list.
+ *  - New L1s are allocated from the HEAD.
+ *  - Freed L1s are added to the TAIl.
+ *  - Recently accessed L1s (where an 'access' is some change to one of
+ *    the userland pmaps which owns this L1) are moved to the TAIL.
+ */
+static TAILQ_HEAD(, l1_ttable) l1_lru_list;
+/*
+ * A list of all L1 tables
+ */
+static SLIST_HEAD(, l1_ttable) l1_list;
+static struct mtx l1_lru_lock;
+
+/*
+ * The l2_dtable tracks L2_BUCKET_SIZE worth of L1 slots.
+ *
+ * This is normally 16MB worth L2 page descriptors for any given pmap.
+ * Reference counts are maintained for L2 descriptors so they can be
+ * freed when empty.
+ */
+struct l2_dtable {
+	/* The number of L2 page descriptors allocated to this l2_dtable */
+	u_int l2_occupancy;
+
+	/* List of L2 page descriptors */
+	struct l2_bucket {
+		pt_entry_t *l2b_kva;	/* KVA of L2 Descriptor Table */
+		vm_paddr_t l2b_phys;	/* Physical address of same */
+		u_short l2b_l1idx;	/* This L2 table's L1 index */
+		u_short l2b_occupancy;	/* How many active descriptors */
+	} l2_bucket[L2_BUCKET_SIZE];
+};
+
+/* pmap_kenter_internal flags */
+#define KENTER_CACHE	0x1
+#define KENTER_DEVICE	0x2
+#define KENTER_USER	0x4
+
+/*
+ * Given an L1 table index, calculate the corresponding l2_dtable index
+ * and bucket index within the l2_dtable.
+ */
+#define	L2_IDX(l1idx)		(((l1idx) >> L2_BUCKET_LOG2) & \
+				 (L2_SIZE - 1))
+#define	L2_BUCKET(l1idx)	((l1idx) & (L2_BUCKET_SIZE - 1))
+
+/*
+ * Given a virtual address, this macro returns the
+ * virtual address required to drop into the next L2 bucket.
+ */
+#define	L2_NEXT_BUCKET(va)	(((va) & L1_S_FRAME) + L1_S_SIZE)
+
+/*
+ * We try to map the page tables write-through, if possible.  However, not
+ * all CPUs have a write-through cache mode, so on those we have to sync
+ * the cache when we frob page tables.
+ *
+ * We try to evaluate this at compile time, if possible.  However, it's
+ * not always possible to do that, hence this run-time var.
+ */
+int	pmap_needs_pte_sync;
+
+/*
+ * Macro to determine if a mapping might be resident in the
+ * instruction cache and/or TLB
+ */
+#define	PTE_BEEN_EXECD(pte)  (L2_S_EXECUTABLE(pte) && L2_S_REFERENCED(pte))
+
+/*
+ * Macro to determine if a mapping might be resident in the
+ * data cache and/or TLB
+ */
+#define	PTE_BEEN_REFD(pte)   (L2_S_REFERENCED(pte))
+
+#ifndef PMAP_SHPGPERPROC
+#define PMAP_SHPGPERPROC 200
+#endif
+
+#define pmap_is_current(pm)	((pm) == pmap_kernel() || \
+            curproc->p_vmspace->vm_map.pmap == (pm))
+
+/*
+ * Data for the pv entry allocation mechanism
+ */
+static TAILQ_HEAD(pch, pv_chunk) pv_chunks = TAILQ_HEAD_INITIALIZER(pv_chunks);
+static int pv_entry_count, pv_entry_max, pv_entry_high_water;
+static struct md_page *pv_table;
+static int shpgperproc = PMAP_SHPGPERPROC;
+
+struct pv_chunk *pv_chunkbase;		/* KVA block for pv_chunks */
+int pv_maxchunks;			/* How many chunks we have KVA for */
+vm_offset_t pv_vafree;			/* Freelist stored in the PTE */
+
+static __inline struct pv_chunk *
+pv_to_chunk(pv_entry_t pv)
+{
+
+	return ((struct pv_chunk *)((uintptr_t)pv & ~(uintptr_t)PAGE_MASK));
+}
+
+#define PV_PMAP(pv) (pv_to_chunk(pv)->pc_pmap)
+
+CTASSERT(sizeof(struct pv_chunk) == PAGE_SIZE);
+CTASSERT(_NPCM == 8);
+CTASSERT(_NPCPV == 252);
+
+#define	PC_FREE0_6	0xfffffffful	/* Free values for index 0 through 6 */
+#define	PC_FREE7	0x0ffffffful	/* Free values for index 7 */
+
+static const uint32_t pc_freemask[_NPCM] = {
+	PC_FREE0_6, PC_FREE0_6, PC_FREE0_6,
+	PC_FREE0_6, PC_FREE0_6, PC_FREE0_6,
+	PC_FREE0_6, PC_FREE7
+};
+
+static SYSCTL_NODE(_vm, OID_AUTO, pmap, CTLFLAG_RD, 0, "VM/pmap parameters");
+
+/* Superpages utilization enabled = 1 / disabled = 0 */
+static int sp_enabled = 0;
+SYSCTL_INT(_vm_pmap, OID_AUTO, sp_enabled, CTLFLAG_RDTUN, &sp_enabled, 0,
+    "Are large page mappings enabled?");
+
+SYSCTL_INT(_vm_pmap, OID_AUTO, pv_entry_count, CTLFLAG_RD, &pv_entry_count, 0,
+    "Current number of pv entries");
+
+#ifdef PV_STATS
+static int pc_chunk_count, pc_chunk_allocs, pc_chunk_frees, pc_chunk_tryfail;
+
+SYSCTL_INT(_vm_pmap, OID_AUTO, pc_chunk_count, CTLFLAG_RD, &pc_chunk_count, 0,
+    "Current number of pv entry chunks");
+SYSCTL_INT(_vm_pmap, OID_AUTO, pc_chunk_allocs, CTLFLAG_RD, &pc_chunk_allocs, 0,
+    "Current number of pv entry chunks allocated");
+SYSCTL_INT(_vm_pmap, OID_AUTO, pc_chunk_frees, CTLFLAG_RD, &pc_chunk_frees, 0,
+    "Current number of pv entry chunks frees");
+SYSCTL_INT(_vm_pmap, OID_AUTO, pc_chunk_tryfail, CTLFLAG_RD, &pc_chunk_tryfail, 0,
+    "Number of times tried to get a chunk page but failed.");
+
+static long pv_entry_frees, pv_entry_allocs;
+static int pv_entry_spare;
+
+SYSCTL_LONG(_vm_pmap, OID_AUTO, pv_entry_frees, CTLFLAG_RD, &pv_entry_frees, 0,
+    "Current number of pv entry frees");
+SYSCTL_LONG(_vm_pmap, OID_AUTO, pv_entry_allocs, CTLFLAG_RD, &pv_entry_allocs, 0,
+    "Current number of pv entry allocs");
+SYSCTL_INT(_vm_pmap, OID_AUTO, pv_entry_spare, CTLFLAG_RD, &pv_entry_spare, 0,
+    "Current number of spare pv entries");
+#endif
+
+uma_zone_t l2zone;
+static uma_zone_t l2table_zone;
+static vm_offset_t pmap_kernel_l2dtable_kva;
+static vm_offset_t pmap_kernel_l2ptp_kva;
+static vm_paddr_t pmap_kernel_l2ptp_phys;
+static struct rwlock pvh_global_lock;
+
+int l1_mem_types[] = {
+	ARM_L1S_STRONG_ORD,
+	ARM_L1S_DEVICE_NOSHARE,
+	ARM_L1S_DEVICE_SHARE,
+	ARM_L1S_NRML_NOCACHE,
+	ARM_L1S_NRML_IWT_OWT,
+	ARM_L1S_NRML_IWB_OWB,
+	ARM_L1S_NRML_IWBA_OWBA
+};
+
+int l2l_mem_types[] = {
+	ARM_L2L_STRONG_ORD,
+	ARM_L2L_DEVICE_NOSHARE,
+	ARM_L2L_DEVICE_SHARE,
+	ARM_L2L_NRML_NOCACHE,
+	ARM_L2L_NRML_IWT_OWT,
+	ARM_L2L_NRML_IWB_OWB,
+	ARM_L2L_NRML_IWBA_OWBA
+};
+
+int l2s_mem_types[] = {
+	ARM_L2S_STRONG_ORD,
+	ARM_L2S_DEVICE_NOSHARE,
+	ARM_L2S_DEVICE_SHARE,
+	ARM_L2S_NRML_NOCACHE,
+	ARM_L2S_NRML_IWT_OWT,
+	ARM_L2S_NRML_IWB_OWB,
+	ARM_L2S_NRML_IWBA_OWBA
+};
+
+/*
+ * This list exists for the benefit of pmap_map_chunk().  It keeps track
+ * of the kernel L2 tables during bootstrap, so that pmap_map_chunk() can
+ * find them as necessary.
+ *
+ * Note that the data on this list MUST remain valid after initarm() returns,
+ * as pmap_bootstrap() uses it to contruct L2 table metadata.
+ */
+SLIST_HEAD(, pv_addr) kernel_pt_list = SLIST_HEAD_INITIALIZER(kernel_pt_list);
+
+static void
+pmap_init_l1(struct l1_ttable *l1, pd_entry_t *l1pt)
+{
+	int i;
+
+	l1->l1_kva = l1pt;
+	l1->l1_domain_use_count = 0;
+	l1->l1_domain_first = 0;
+
+	for (i = 0; i < PMAP_DOMAINS; i++)
+		l1->l1_domain_free[i] = i + 1;
+
+	/*
+	 * Copy the kernel's L1 entries to each new L1.
+	 */
+	if (l1pt != pmap_kernel()->pm_l1->l1_kva)
+		memcpy(l1pt, pmap_kernel()->pm_l1->l1_kva, L1_TABLE_SIZE);
+
+	if ((l1->l1_physaddr = pmap_extract(pmap_kernel(), (vm_offset_t)l1pt)) == 0)
+		panic("pmap_init_l1: can't get PA of L1 at %p", l1pt);
+	SLIST_INSERT_HEAD(&l1_list, l1, l1_link);
+	TAILQ_INSERT_TAIL(&l1_lru_list, l1, l1_lru);
+}
+
+static vm_offset_t
+kernel_pt_lookup(vm_paddr_t pa)
+{
+	struct pv_addr *pv;
+
+	SLIST_FOREACH(pv, &kernel_pt_list, pv_list) {
+		if (pv->pv_pa == pa)
+			return (pv->pv_va);
+	}
+	return (0);
+}
+
+void
+pmap_pte_init_mmu_v6(void)
+{
+
+	if (PTE_PAGETABLE >= 3)
+		pmap_needs_pte_sync = 1;
+	pte_l1_s_cache_mode = l1_mem_types[PTE_CACHE];
+	pte_l2_l_cache_mode = l2l_mem_types[PTE_CACHE];
+	pte_l2_s_cache_mode = l2s_mem_types[PTE_CACHE];
+
+	pte_l1_s_cache_mode_pt = l1_mem_types[PTE_PAGETABLE];
+	pte_l2_l_cache_mode_pt = l2l_mem_types[PTE_PAGETABLE];
+	pte_l2_s_cache_mode_pt = l2s_mem_types[PTE_PAGETABLE];
+
+}
+
+/*
+ * Allocate an L1 translation table for the specified pmap.
+ * This is called at pmap creation time.
+ */
+static void
+pmap_alloc_l1(pmap_t pmap)
+{
+	struct l1_ttable *l1;
+	u_int8_t domain;
+
+	/*
+	 * Remove the L1 at the head of the LRU list
+	 */
+	mtx_lock(&l1_lru_lock);
+	l1 = TAILQ_FIRST(&l1_lru_list);
+	TAILQ_REMOVE(&l1_lru_list, l1, l1_lru);
+
+	/*
+	 * Pick the first available domain number, and update
+	 * the link to the next number.
+	 */
+	domain = l1->l1_domain_first;
+	l1->l1_domain_first = l1->l1_domain_free[domain];
+
+	/*
+	 * If there are still free domain numbers in this L1,
+	 * put it back on the TAIL of the LRU list.
+	 */
+	if (++l1->l1_domain_use_count < PMAP_DOMAINS)
+		TAILQ_INSERT_TAIL(&l1_lru_list, l1, l1_lru);
+
+	mtx_unlock(&l1_lru_lock);
+
+	/*
+	 * Fix up the relevant bits in the pmap structure
+	 */
+	pmap->pm_l1 = l1;
+	pmap->pm_domain = domain + 1;
+}
+
+/*
+ * Free an L1 translation table.
+ * This is called at pmap destruction time.
+ */
+static void
+pmap_free_l1(pmap_t pmap)
+{
+	struct l1_ttable *l1 = pmap->pm_l1;
+
+	mtx_lock(&l1_lru_lock);
+
+	/*
+	 * If this L1 is currently on the LRU list, remove it.
+	 */
+	if (l1->l1_domain_use_count < PMAP_DOMAINS)
+		TAILQ_REMOVE(&l1_lru_list, l1, l1_lru);
+
+	/*
+	 * Free up the domain number which was allocated to the pmap
+	 */
+	l1->l1_domain_free[pmap->pm_domain - 1] = l1->l1_domain_first;
+	l1->l1_domain_first = pmap->pm_domain - 1;
+	l1->l1_domain_use_count--;
+
+	/*
+	 * The L1 now must have at least 1 free domain, so add
+	 * it back to the LRU list. If the use count is zero,
+	 * put it at the head of the list, otherwise it goes
+	 * to the tail.
+	 */
+	if (l1->l1_domain_use_count == 0) {
+		TAILQ_INSERT_HEAD(&l1_lru_list, l1, l1_lru);
+	}	else
+		TAILQ_INSERT_TAIL(&l1_lru_list, l1, l1_lru);
+
+	mtx_unlock(&l1_lru_lock);
+}
+
+/*
+ * Returns a pointer to the L2 bucket associated with the specified pmap
+ * and VA, or NULL if no L2 bucket exists for the address.
+ */
+static PMAP_INLINE struct l2_bucket *
+pmap_get_l2_bucket(pmap_t pmap, vm_offset_t va)
+{
+	struct l2_dtable *l2;
+	struct l2_bucket *l2b;
+	u_short l1idx;
+
+	l1idx = L1_IDX(va);
+
+	if ((l2 = pmap->pm_l2[L2_IDX(l1idx)]) == NULL ||
+	    (l2b = &l2->l2_bucket[L2_BUCKET(l1idx)])->l2b_kva == NULL)
+		return (NULL);
+
+	return (l2b);
+}
+
+/*
+ * Returns a pointer to the L2 bucket associated with the specified pmap
+ * and VA.
+ *
+ * If no L2 bucket exists, perform the necessary allocations to put an L2
+ * bucket/page table in place.
+ *
+ * Note that if a new L2 bucket/page was allocated, the caller *must*
+ * increment the bucket occupancy counter appropriately *before*
+ * releasing the pmap's lock to ensure no other thread or cpu deallocates
+ * the bucket/page in the meantime.
+ */
+static struct l2_bucket *
+pmap_alloc_l2_bucket(pmap_t pmap, vm_offset_t va)
+{
+	struct l2_dtable *l2;
+	struct l2_bucket *l2b;
+	u_short l1idx;
+
+	l1idx = L1_IDX(va);
+
+	PMAP_ASSERT_LOCKED(pmap);
+	rw_assert(&pvh_global_lock, RA_WLOCKED);
+	if ((l2 = pmap->pm_l2[L2_IDX(l1idx)]) == NULL) {
+		/*
+		 * No mapping at this address, as there is
+		 * no entry in the L1 table.
+		 * Need to allocate a new l2_dtable.
+		 */
+		PMAP_UNLOCK(pmap);
+		rw_wunlock(&pvh_global_lock);
+		if ((l2 = uma_zalloc(l2table_zone, M_NOWAIT)) == NULL) {
+			rw_wlock(&pvh_global_lock);
+			PMAP_LOCK(pmap);
+			return (NULL);
+		}
+		rw_wlock(&pvh_global_lock);
+		PMAP_LOCK(pmap);
+		if (pmap->pm_l2[L2_IDX(l1idx)] != NULL) {
+			/*
+			 * Someone already allocated the l2_dtable while
+			 * we were doing the same.
+			 */
+			uma_zfree(l2table_zone, l2);
+			l2 = pmap->pm_l2[L2_IDX(l1idx)];
+		} else {
+			bzero(l2, sizeof(*l2));
+			/*
+			 * Link it into the parent pmap
+			 */
+			pmap->pm_l2[L2_IDX(l1idx)] = l2;
+		}
+	}
+
+	l2b = &l2->l2_bucket[L2_BUCKET(l1idx)];
+
+	/*
+	 * Fetch pointer to the L2 page table associated with the address.
+	 */
+	if (l2b->l2b_kva == NULL) {
+		pt_entry_t *ptep;
+
+		/*
+		 * No L2 page table has been allocated. Chances are, this
+		 * is because we just allocated the l2_dtable, above.
+		 */
+		PMAP_UNLOCK(pmap);
+		rw_wunlock(&pvh_global_lock);
+		ptep = uma_zalloc(l2zone, M_NOWAIT);
+		rw_wlock(&pvh_global_lock);
+		PMAP_LOCK(pmap);
+		if (l2b->l2b_kva != 0) {
+			/* We lost the race. */
+			uma_zfree(l2zone, ptep);
+			return (l2b);
+		}
+		l2b->l2b_phys = vtophys(ptep);
+		if (ptep == NULL) {
+			/*
+			 * Oops, no more L2 page tables available at this
+			 * time. We may need to deallocate the l2_dtable
+			 * if we allocated a new one above.
+			 */
+			if (l2->l2_occupancy == 0) {
+				pmap->pm_l2[L2_IDX(l1idx)] = NULL;
+				uma_zfree(l2table_zone, l2);
+			}
+			return (NULL);
+		}
+
+		l2->l2_occupancy++;
+		l2b->l2b_kva = ptep;
+		l2b->l2b_l1idx = l1idx;
+	}
+
+	return (l2b);
+}
+
+static PMAP_INLINE void
+pmap_free_l2_ptp(pt_entry_t *l2)
+{
+	uma_zfree(l2zone, l2);
+}
+/*
+ * One or more mappings in the specified L2 descriptor table have just been
+ * invalidated.
+ *
+ * Garbage collect the metadata and descriptor table itself if necessary.
+ *
+ * The pmap lock must be acquired when this is called (not necessary
+ * for the kernel pmap).
+ */
+static void
+pmap_free_l2_bucket(pmap_t pmap, struct l2_bucket *l2b, u_int count)
+{
+	struct l2_dtable *l2;
+	pd_entry_t *pl1pd, l1pd;
+	pt_entry_t *ptep;
+	u_short l1idx;
+
+
+	/*
+	 * Update the bucket's reference count according to how many
+	 * PTEs the caller has just invalidated.
+	 */
+	l2b->l2b_occupancy -= count;
+
+	/*
+	 * Note:
+	 *
+	 * Level 2 page tables allocated to the kernel pmap are never freed
+	 * as that would require checking all Level 1 page tables and
+	 * removing any references to the Level 2 page table. See also the
+	 * comment elsewhere about never freeing bootstrap L2 descriptors.
+	 *
+	 * We make do with just invalidating the mapping in the L2 table.
+	 *
+	 * This isn't really a big deal in practice and, in fact, leads
+	 * to a performance win over time as we don't need to continually
+	 * alloc/free.
+	 */
+	if (l2b->l2b_occupancy > 0 || pmap == pmap_kernel())
+		return;
+
+	/*
+	 * There are no more valid mappings in this level 2 page table.
+	 * Go ahead and NULL-out the pointer in the bucket, then
+	 * free the page table.
+	 */
+	l1idx = l2b->l2b_l1idx;
+	ptep = l2b->l2b_kva;
+	l2b->l2b_kva = NULL;
+
+	pl1pd = &pmap->pm_l1->l1_kva[l1idx];
+
+	/*
+	 * If the L1 slot matches the pmap's domain
+	 * number, then invalidate it.
+	 */
+	l1pd = *pl1pd & (L1_TYPE_MASK | L1_C_DOM_MASK);
+	if (l1pd == (L1_C_DOM(pmap->pm_domain) | L1_TYPE_C)) {
+		*pl1pd = 0;
+		PTE_SYNC(pl1pd);
+		cpu_tlb_flushD_SE((vm_offset_t)ptep);
+		cpu_cpwait();
+	}
+
+	/*
+	 * Release the L2 descriptor table back to the pool cache.
+	 */
+	pmap_free_l2_ptp(ptep);
+
+	/*
+	 * Update the reference count in the associated l2_dtable
+	 */
+	l2 = pmap->pm_l2[L2_IDX(l1idx)];
+	if (--l2->l2_occupancy > 0)
+		return;
+
+	/*
+	 * There are no more valid mappings in any of the Level 1
+	 * slots managed by this l2_dtable. Go ahead and NULL-out
+	 * the pointer in the parent pmap and free the l2_dtable.
+	 */
+	pmap->pm_l2[L2_IDX(l1idx)] = NULL;
+	uma_zfree(l2table_zone, l2);
+}
+
+/*
+ * Pool cache constructors for L2 descriptor tables, metadata and pmap
+ * structures.
+ */
+static int
+pmap_l2ptp_ctor(void *mem, int size, void *arg, int flags)
+{
+	struct l2_bucket *l2b;
+	pt_entry_t *ptep, pte;
+	vm_offset_t va = (vm_offset_t)mem & ~PAGE_MASK;
+
+	/*
+	 * The mappings for these page tables were initially made using
+	 * pmap_kenter() by the pool subsystem. Therefore, the cache-
+	 * mode will not be right for page table mappings. To avoid
+	 * polluting the pmap_kenter() code with a special case for
+	 * page tables, we simply fix up the cache-mode here if it's not
+	 * correct.
+	 */
+	l2b = pmap_get_l2_bucket(pmap_kernel(), va);
+	ptep = &l2b->l2b_kva[l2pte_index(va)];
+	pte = *ptep;
+
+	cpu_idcache_wbinv_range(va, PAGE_SIZE);
+	pmap_l2cache_wbinv_range(va, pte & L2_S_FRAME, PAGE_SIZE);
+	if ((pte & L2_S_CACHE_MASK) != pte_l2_s_cache_mode_pt) {
+		/*
+		 * Page tables must have the cache-mode set to
+		 * Write-Thru.
+		 */
+		*ptep = (pte & ~L2_S_CACHE_MASK) | pte_l2_s_cache_mode_pt;
+		PTE_SYNC(ptep);
+		cpu_tlb_flushD_SE(va);
+		cpu_cpwait();
+	}
+
+	memset(mem, 0, L2_TABLE_SIZE_REAL);
+	return (0);
+}
+
+/*
+ * Modify pte bits for all ptes corresponding to the given physical address.
+ * We use `maskbits' rather than `clearbits' because we're always passing
+ * constants and the latter would require an extra inversion at run-time.
+ */
+static int
+pmap_clearbit(struct vm_page *m, u_int maskbits)
+{
+	struct l2_bucket *l2b;
+	struct pv_entry *pv, *pve, *next_pv;
+	struct md_page *pvh;
+	pd_entry_t *pl1pd;
+	pt_entry_t *ptep, npte, opte;
+	pmap_t pmap;
+	vm_offset_t va;
+	u_int oflags;
+	int count = 0;
+
+	rw_wlock(&pvh_global_lock);
+	if ((m->flags & PG_FICTITIOUS) != 0)
+		goto small_mappings;
+
+	pvh = pa_to_pvh(VM_PAGE_TO_PHYS(m));
+	TAILQ_FOREACH_SAFE(pv, &pvh->pv_list, pv_list, next_pv) {
+		va = pv->pv_va;
+		pmap = PV_PMAP(pv);
+		PMAP_LOCK(pmap);
+		pl1pd = &pmap->pm_l1->l1_kva[L1_IDX(va)];
+		KASSERT((*pl1pd & L1_TYPE_MASK) == L1_S_PROTO,
+		    ("pmap_clearbit: valid section mapping expected"));
+		if ((maskbits & PVF_WRITE) && (pv->pv_flags & PVF_WRITE))
+			(void)pmap_demote_section(pmap, va);
+		else if ((maskbits & PVF_REF) && L1_S_REFERENCED(*pl1pd)) {
+			if (pmap_demote_section(pmap, va)) {
+				if ((pv->pv_flags & PVF_WIRED) == 0) {
+					/*
+					 * Remove the mapping to a single page
+					 * so that a subsequent access may
+					 * repromote. Since the underlying
+					 * l2_bucket is fully populated, this
+					 * removal never frees an entire
+					 * l2_bucket.
+					 */
+					va += (VM_PAGE_TO_PHYS(m) &
+					    L1_S_OFFSET);
+					l2b = pmap_get_l2_bucket(pmap, va);
+					KASSERT(l2b != NULL,
+					    ("pmap_clearbit: no l2 bucket for "
+					     "va 0x%#x, pmap 0x%p", va, pmap));
+					ptep = &l2b->l2b_kva[l2pte_index(va)];
+					*ptep = 0;
+					PTE_SYNC(ptep);
+					pmap_free_l2_bucket(pmap, l2b, 1);
+					pve = pmap_remove_pv(m, pmap, va);
+					KASSERT(pve != NULL, ("pmap_clearbit: "
+					    "no PV entry for managed mapping"));
+					pmap_free_pv_entry(pmap, pve);
+
+				}
+			}
+		} else if ((maskbits & PVF_MOD) && L1_S_WRITABLE(*pl1pd)) {
+			if (pmap_demote_section(pmap, va)) {
+				if ((pv->pv_flags & PVF_WIRED) == 0) {
+					/*
+					 * Write protect the mapping to a
+					 * single page so that a subsequent
+					 * write access may repromote.
+					 */
+					va += (VM_PAGE_TO_PHYS(m) &
+					    L1_S_OFFSET);
+					l2b = pmap_get_l2_bucket(pmap, va);
+					KASSERT(l2b != NULL,
+					    ("pmap_clearbit: no l2 bucket for "
+					     "va 0x%#x, pmap 0x%p", va, pmap));
+					ptep = &l2b->l2b_kva[l2pte_index(va)];
+					if ((*ptep & L2_S_PROTO) != 0) {
+						pve = pmap_find_pv(&m->md,
+						    pmap, va);
+						KASSERT(pve != NULL,
+						    ("pmap_clearbit: no PV "
+						    "entry for managed mapping"));
+						pve->pv_flags &= ~PVF_WRITE;
+						*ptep |= L2_APX;
+						PTE_SYNC(ptep);
+					}
+				}
+			}
+		}
+		PMAP_UNLOCK(pmap);
+	}
+
+small_mappings:
+	if (TAILQ_EMPTY(&m->md.pv_list)) {
+		rw_wunlock(&pvh_global_lock);
+		return (0);
+	}
+
+	/*
+	 * Loop over all current mappings setting/clearing as appropos
+	 */
+	TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
+		va = pv->pv_va;
+		pmap = PV_PMAP(pv);
+		oflags = pv->pv_flags;
+		pv->pv_flags &= ~maskbits;
+
+		PMAP_LOCK(pmap);
+
+		l2b = pmap_get_l2_bucket(pmap, va);
+		KASSERT(l2b != NULL, ("pmap_clearbit: no l2 bucket for "
+		    "va 0x%#x, pmap 0x%p", va, pmap));
+
+		ptep = &l2b->l2b_kva[l2pte_index(va)];
+		npte = opte = *ptep;
+
+		if (maskbits & (PVF_WRITE | PVF_MOD)) {
+			/* make the pte read only */
+			npte |= L2_APX;
+		}
+
+		if (maskbits & PVF_REF) {
+			/*
+			 * Clear referenced flag in PTE so that we
+			 * will take a flag fault the next time the mapping
+			 * is referenced.
+			 */
+			npte &= ~L2_S_REF;
+		}
+
+		CTR4(KTR_PMAP,"clearbit: pmap:%p bits:%x pte:%x->%x",
+		    pmap, maskbits, opte, npte);
+		if (npte != opte) {
+			count++;
+			*ptep = npte;
+			PTE_SYNC(ptep);
+			/* Flush the TLB entry if a current pmap. */
+			if (PTE_BEEN_EXECD(opte))
+				cpu_tlb_flushID_SE(pv->pv_va);
+			else if (PTE_BEEN_REFD(opte))
+				cpu_tlb_flushD_SE(pv->pv_va);
+			cpu_cpwait();
+		}
+
+		PMAP_UNLOCK(pmap);
+
+	}
+
+	if (maskbits & PVF_WRITE)
+		vm_page_aflag_clear(m, PGA_WRITEABLE);
+	rw_wunlock(&pvh_global_lock);
+	return (count);
+}
+
+/*
+ * main pv_entry manipulation functions:
+ *   pmap_enter_pv: enter a mapping onto a vm_page list
+ *   pmap_remove_pv: remove a mappiing from a vm_page list
+ *
+ * NOTE: pmap_enter_pv expects to lock the pvh itself
+ *       pmap_remove_pv expects the caller to lock the pvh before calling
+ */
+
+/*
+ * pmap_enter_pv: enter a mapping onto a vm_page's PV list
+ *
+ * => caller should hold the proper lock on pvh_global_lock
+ * => caller should have pmap locked
+ * => we will (someday) gain the lock on the vm_page's PV list
+ * => caller should adjust ptp's wire_count before calling
+ * => caller should not adjust pmap's wire_count
+ */
+static void
+pmap_enter_pv(struct vm_page *m, struct pv_entry *pve, pmap_t pmap,
+    vm_offset_t va, u_int flags)
+{
+
+	rw_assert(&pvh_global_lock, RA_WLOCKED);
+
+	PMAP_ASSERT_LOCKED(pmap);
+	pve->pv_va = va;
+	pve->pv_flags = flags;
+
+	TAILQ_INSERT_HEAD(&m->md.pv_list, pve, pv_list);
+	if (pve->pv_flags & PVF_WIRED)
+		++pmap->pm_stats.wired_count;
+}
+
+/*
+ *
+ * pmap_find_pv: Find a pv entry
+ *
+ * => caller should hold lock on vm_page
+ */
+static PMAP_INLINE struct pv_entry *
+pmap_find_pv(struct md_page *md, pmap_t pmap, vm_offset_t va)
+{
+	struct pv_entry *pv;
+
+	rw_assert(&pvh_global_lock, RA_WLOCKED);
+	TAILQ_FOREACH(pv, &md->pv_list, pv_list)
+		if (pmap == PV_PMAP(pv) && va == pv->pv_va)
+			break;
+
+	return (pv);
+}
+
+/*
+ * vector_page_setprot:
+ *
+ *	Manipulate the protection of the vector page.
+ */
+void
+vector_page_setprot(int prot)
+{
+	struct l2_bucket *l2b;
+	pt_entry_t *ptep;
+
+	l2b = pmap_get_l2_bucket(pmap_kernel(), vector_page);
+
+	ptep = &l2b->l2b_kva[l2pte_index(vector_page)];
+	/*
+	 * Set referenced flag.
+	 * Vectors' page is always desired
+	 * to be allowed to reside in TLB. 
+	 */
+	*ptep |= L2_S_REF;
+
+	pmap_set_prot(ptep, prot|VM_PROT_EXECUTE, 0);
+	PTE_SYNC(ptep);
+	cpu_tlb_flushID_SE(vector_page);
+	cpu_cpwait();
+}
+
+static void
+pmap_set_prot(pt_entry_t *ptep, vm_prot_t prot, uint8_t user)
+{
+
+	*ptep &= ~(L2_S_PROT_MASK | L2_XN);
+
+	if (!(prot & VM_PROT_EXECUTE))
+		*ptep |= L2_XN;
+
+	/* Set defaults first - kernel read access */
+	*ptep |= L2_APX;
+	*ptep |= L2_S_PROT_R;
+	/* Now tune APs as desired */
+	if (user)
+		*ptep |= L2_S_PROT_U;
+
+	if (prot & VM_PROT_WRITE)
+		*ptep &= ~(L2_APX);
+}
+
+/*
+ * pmap_remove_pv: try to remove a mapping from a pv_list
+ *
+ * => caller should hold proper lock on pmap_main_lock
+ * => pmap should be locked
+ * => caller should hold lock on vm_page [so that attrs can be adjusted]
+ * => caller should adjust ptp's wire_count and free PTP if needed
+ * => caller should NOT adjust pmap's wire_count
+ * => we return the removed pve
+ */
+static struct pv_entry *
+pmap_remove_pv(struct vm_page *m, pmap_t pmap, vm_offset_t va)
+{
+	struct pv_entry *pve;
+
+	rw_assert(&pvh_global_lock, RA_WLOCKED);
+	PMAP_ASSERT_LOCKED(pmap);
+
+	pve = pmap_find_pv(&m->md, pmap, va);	/* find corresponding pve */
+	if (pve != NULL) {
+		TAILQ_REMOVE(&m->md.pv_list, pve, pv_list);
+		if (pve->pv_flags & PVF_WIRED)
+			--pmap->pm_stats.wired_count;
+	}
+	if (TAILQ_EMPTY(&m->md.pv_list))
+		vm_page_aflag_clear(m, PGA_WRITEABLE);
+
+	return(pve);				/* return removed pve */
+}
+
+/*
+ *
+ * pmap_modify_pv: Update pv flags
+ *
+ * => caller should hold lock on vm_page [so that attrs can be adjusted]
+ * => caller should NOT adjust pmap's wire_count
+ * => we return the old flags
+ *
+ * Modify a physical-virtual mapping in the pv table
+ */
+static u_int
+pmap_modify_pv(struct vm_page *m, pmap_t pmap, vm_offset_t va,
+    u_int clr_mask, u_int set_mask)
+{
+	struct pv_entry *npv;
+	u_int flags, oflags;
+
+	PMAP_ASSERT_LOCKED(pmap);
+	rw_assert(&pvh_global_lock, RA_WLOCKED);
+	if ((npv = pmap_find_pv(&m->md, pmap, va)) == NULL)
+		return (0);
+
+	/*
+	 * There is at least one VA mapping this page.
+	 */
+	oflags = npv->pv_flags;
+	npv->pv_flags = flags = (oflags & ~clr_mask) | set_mask;
+
+	if ((flags ^ oflags) & PVF_WIRED) {
+		if (flags & PVF_WIRED)
+			++pmap->pm_stats.wired_count;
+		else
+			--pmap->pm_stats.wired_count;
+	}
+
+	return (oflags);
+}
+
+/* Function to set the debug level of the pmap code */
+#ifdef PMAP_DEBUG
+void
+pmap_debug(int level)
+{
+	pmap_debug_level = level;
+	dprintf("pmap_debug: level=%d\n", pmap_debug_level);
+}
+#endif  /* PMAP_DEBUG */
+
+void
+pmap_pinit0(struct pmap *pmap)
+{
+	PDEBUG(1, printf("pmap_pinit0: pmap = %08x\n", (u_int32_t) pmap));
+
+	bcopy(kernel_pmap, pmap, sizeof(*pmap));
+	bzero(&pmap->pm_mtx, sizeof(pmap->pm_mtx));
+	PMAP_LOCK_INIT(pmap);
+	TAILQ_INIT(&pmap->pm_pvchunk);
+}
+
+/*
+ *	Initialize a vm_page's machine-dependent fields.
+ */
+void
+pmap_page_init(vm_page_t m)
+{
+
+	TAILQ_INIT(&m->md.pv_list);
+	m->md.pv_memattr = VM_MEMATTR_DEFAULT;
+}
+
+static vm_offset_t
+pmap_ptelist_alloc(vm_offset_t *head)
+{
+	pt_entry_t *pte;
+	vm_offset_t va;
+
+	va = *head;
+	if (va == 0)
+		return (va);	/* Out of memory */
+	pte = vtopte(va);
+	*head = *pte;
+	if ((*head & L2_TYPE_MASK) != L2_TYPE_INV)
+		panic("%s: va is not L2_TYPE_INV!", __func__);
+	*pte = 0;
+	return (va);
+}
+
+static void
+pmap_ptelist_free(vm_offset_t *head, vm_offset_t va)
+{
+	pt_entry_t *pte;
+
+	if ((va & L2_TYPE_MASK) != L2_TYPE_INV)
+		panic("%s: freeing va that is not L2_TYPE INV!", __func__);
+	pte = vtopte(va);
+	*pte = *head;		/* virtual! L2_TYPE is L2_TYPE_INV though */
+	*head = va;
+}
+
+static void
+pmap_ptelist_init(vm_offset_t *head, void *base, int npages)
+{
+	int i;
+	vm_offset_t va;
+
+	*head = 0;
+	for (i = npages - 1; i >= 0; i--) {
+		va = (vm_offset_t)base + i * PAGE_SIZE;
+		pmap_ptelist_free(head, va);
+	}
+}
+
+/*
+ *      Initialize the pmap module.
+ *      Called by vm_init, to initialize any structures that the pmap
+ *      system needs to map virtual memory.
+ */
+void
+pmap_init(void)
+{
+	vm_size_t s;
+	int i, pv_npg;
+
+	l2zone = uma_zcreate("L2 Table", L2_TABLE_SIZE_REAL, pmap_l2ptp_ctor,
+	    NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_VM | UMA_ZONE_NOFREE);
+	l2table_zone = uma_zcreate("L2 Table", sizeof(struct l2_dtable), NULL,
+	    NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_VM | UMA_ZONE_NOFREE);
+
+	/*
+	 * Are large page mappings supported and enabled?
+	 */
+	TUNABLE_INT_FETCH("vm.pmap.sp_enabled", &sp_enabled);
+	if (sp_enabled) {
+		KASSERT(MAXPAGESIZES > 1 && pagesizes[1] == 0,
+		    ("pmap_init: can't assign to pagesizes[1]"));
+		pagesizes[1] = NBPDR;
+	}
+
+	/*
+	 * Calculate the size of the pv head table for superpages.
+	 * Handle the possibility that "vm_phys_segs[...].end" is zero.
+	 */
+	pv_npg = trunc_1mpage(vm_phys_segs[vm_phys_nsegs - 1].end -
+	    PAGE_SIZE) / NBPDR + 1;
+
+	/*
+	 * Allocate memory for the pv head table for superpages.
+	 */
+	s = (vm_size_t)(pv_npg * sizeof(struct md_page));
+	s = round_page(s);
+	pv_table = (struct md_page *)kmem_malloc(kernel_arena, s,
+	    M_WAITOK | M_ZERO);
+	for (i = 0; i < pv_npg; i++)
+		TAILQ_INIT(&pv_table[i].pv_list);
+
+	/*
+	 * Initialize the address space for the pv chunks.
+	 */
+
+	TUNABLE_INT_FETCH("vm.pmap.shpgperproc", &shpgperproc);
+	pv_entry_max = shpgperproc * maxproc + cnt.v_page_count;
+	TUNABLE_INT_FETCH("vm.pmap.pv_entries", &pv_entry_max);
+	pv_entry_max = roundup(pv_entry_max, _NPCPV);
+	pv_entry_high_water = 9 * (pv_entry_max / 10);
+
+	pv_maxchunks = MAX(pv_entry_max / _NPCPV, maxproc);
+	pv_chunkbase = (struct pv_chunk *)kva_alloc(PAGE_SIZE * pv_maxchunks);
+
+	if (pv_chunkbase == NULL)
+		panic("pmap_init: not enough kvm for pv chunks");
+
+	pmap_ptelist_init(&pv_vafree, pv_chunkbase, pv_maxchunks);
+
+	/*
+	 * Now it is safe to enable pv_table recording.
+	 */
+	PDEBUG(1, printf("pmap_init: done!\n"));
+}
+
+SYSCTL_INT(_vm_pmap, OID_AUTO, pv_entry_max, CTLFLAG_RD, &pv_entry_max, 0,
+	"Max number of PV entries");
+SYSCTL_INT(_vm_pmap, OID_AUTO, shpgperproc, CTLFLAG_RD, &shpgperproc, 0,
+	"Page share factor per proc");
+
+static SYSCTL_NODE(_vm_pmap, OID_AUTO, section, CTLFLAG_RD, 0,
+    "1MB page mapping counters");
+
+static u_long pmap_section_demotions;
+SYSCTL_ULONG(_vm_pmap_section, OID_AUTO, demotions, CTLFLAG_RD,
+    &pmap_section_demotions, 0, "1MB page demotions");
+
+static u_long pmap_section_mappings;
+SYSCTL_ULONG(_vm_pmap_section, OID_AUTO, mappings, CTLFLAG_RD,
+    &pmap_section_mappings, 0, "1MB page mappings");
+
+static u_long pmap_section_p_failures;
+SYSCTL_ULONG(_vm_pmap_section, OID_AUTO, p_failures, CTLFLAG_RD,
+    &pmap_section_p_failures, 0, "1MB page promotion failures");
+
+static u_long pmap_section_promotions;
+SYSCTL_ULONG(_vm_pmap_section, OID_AUTO, promotions, CTLFLAG_RD,
+    &pmap_section_promotions, 0, "1MB page promotions");
+
+int
+pmap_fault_fixup(pmap_t pmap, vm_offset_t va, vm_prot_t ftype, int user)
+{
+	struct l2_dtable *l2;
+	struct l2_bucket *l2b;
+	pd_entry_t *pl1pd, l1pd;
+	pt_entry_t *ptep, pte;
+	vm_paddr_t pa;
+	u_int l1idx;
+	int rv = 0;
+
+	l1idx = L1_IDX(va);
+	rw_wlock(&pvh_global_lock);
+	PMAP_LOCK(pmap);
+	/*
+	 * Check and possibly fix-up L1 section mapping
+	 * only when superpage mappings are enabled to speed up.
+	 */
+	if (sp_enabled) {
+		pl1pd = &pmap->pm_l1->l1_kva[l1idx];
+		l1pd = *pl1pd;
+		if ((l1pd & L1_TYPE_MASK) == L1_S_PROTO) {
+			/* Catch an access to the vectors section */
+			if (l1idx == L1_IDX(vector_page))
+				goto out;
+			/*
+			 * Stay away from the kernel mappings.
+			 * None of them should fault from L1 entry.
+			 */
+			if (pmap == pmap_kernel())
+				goto out;
+			/*
+			 * Catch a forbidden userland access
+			 */
+			if (user && !(l1pd & L1_S_PROT_U))
+				goto out;
+			/*
+			 * Superpage is always either mapped read only
+			 * or it is modified and permitted to be written
+			 * by default. Therefore, process only reference
+			 * flag fault and demote page in case of write fault.
+			 */
+			if ((ftype & VM_PROT_WRITE) && !L1_S_WRITABLE(l1pd) &&
+			    L1_S_REFERENCED(l1pd)) {
+				(void)pmap_demote_section(pmap, va);
+				goto out;
+			} else if (!L1_S_REFERENCED(l1pd)) {
+				/* Mark the page "referenced" */
+				*pl1pd = l1pd | L1_S_REF;
+				PTE_SYNC(pl1pd);
+				goto l1_section_out;
+			} else
+				goto out;
+		}
+	}
+	/*
+	 * If there is no l2_dtable for this address, then the process
+	 * has no business accessing it.
+	 *
+	 * Note: This will catch userland processes trying to access
+	 * kernel addresses.
+	 */
+	l2 = pmap->pm_l2[L2_IDX(l1idx)];
+	if (l2 == NULL)
+		goto out;
+
+	/*
+	 * Likewise if there is no L2 descriptor table
+	 */
+	l2b = &l2->l2_bucket[L2_BUCKET(l1idx)];
+	if (l2b->l2b_kva == NULL)
+		goto out;
+
+	/*
+	 * Check the PTE itself.
+	 */
+	ptep = &l2b->l2b_kva[l2pte_index(va)];
+	pte = *ptep;
+	if (pte == 0)
+		goto out;
+
+	/*
+	 * Catch a userland access to the vector page mapped at 0x0
+	 */
+	if (user && !(pte & L2_S_PROT_U))
+		goto out;
+	if (va == vector_page)
+		goto out;
+
+	pa = l2pte_pa(pte);
+	CTR5(KTR_PMAP, "pmap_fault_fix: pmap:%p va:%x pte:0x%x ftype:%x user:%x",
+	    pmap, va, pte, ftype, user);
+	if ((ftype & VM_PROT_WRITE) && !(L2_S_WRITABLE(pte)) &&
+	    L2_S_REFERENCED(pte)) {
+		/*
+		 * This looks like a good candidate for "page modified"
+		 * emulation...
+		 */
+		struct pv_entry *pv;
+		struct vm_page *m;
+
+		/* Extract the physical address of the page */
+		if ((m = PHYS_TO_VM_PAGE(pa)) == NULL) {
+			goto out;
+		}
+		/* Get the current flags for this page. */
+
+		pv = pmap_find_pv(&m->md, pmap, va);
+		if (pv == NULL) {
+			goto out;
+		}
+
+		/*
+		 * Do the flags say this page is writable? If not then it
+		 * is a genuine write fault. If yes then the write fault is
+		 * our fault as we did not reflect the write access in the
+		 * PTE. Now we know a write has occurred we can correct this
+		 * and also set the modified bit
+		 */
+		if ((pv->pv_flags & PVF_WRITE) == 0) {
+			goto out;
+		}
+
+		vm_page_dirty(m);
+
+		/* Re-enable write permissions for the page */
+		*ptep = (pte & ~L2_APX);
+		PTE_SYNC(ptep);
+		rv = 1;
+		CTR1(KTR_PMAP, "pmap_fault_fix: new pte:0x%x", *ptep);
+	} else if (!L2_S_REFERENCED(pte)) {
+		/*
+		 * This looks like a good candidate for "page referenced"
+		 * emulation.
+		 */
+		struct pv_entry *pv;
+		struct vm_page *m;
+
+		/* Extract the physical address of the page */
+		if ((m = PHYS_TO_VM_PAGE(pa)) == NULL)
+			goto out;
+		/* Get the current flags for this page. */
+		pv = pmap_find_pv(&m->md, pmap, va);
+		if (pv == NULL)
+			goto out;
+
+		vm_page_aflag_set(m, PGA_REFERENCED);
+
+		/* Mark the page "referenced" */
+		*ptep = pte | L2_S_REF;
+		PTE_SYNC(ptep);
+		rv = 1;
+		CTR1(KTR_PMAP, "pmap_fault_fix: new pte:0x%x", *ptep);
+	}
+
+	/*
+	 * We know there is a valid mapping here, so simply
+	 * fix up the L1 if necessary.
+	 */
+	pl1pd = &pmap->pm_l1->l1_kva[l1idx];
+	l1pd = l2b->l2b_phys | L1_C_DOM(pmap->pm_domain) | L1_C_PROTO;
+	if (*pl1pd != l1pd) {
+		*pl1pd = l1pd;
+		PTE_SYNC(pl1pd);
+		rv = 1;
+	}
+
+#ifdef DEBUG
+	/*
+	 * If 'rv == 0' at this point, it generally indicates that there is a
+	 * stale TLB entry for the faulting address. This happens when two or
+	 * more processes are sharing an L1. Since we don't flush the TLB on
+	 * a context switch between such processes, we can take domain faults
+	 * for mappings which exist at the same VA in both processes. EVEN IF
+	 * WE'VE RECENTLY FIXED UP THE CORRESPONDING L1 in pmap_enter(), for
+	 * example.
+	 *
+	 * This is extremely likely to happen if pmap_enter() updated the L1
+	 * entry for a recently entered mapping. In this case, the TLB is
+	 * flushed for the new mapping, but there may still be TLB entries for
+	 * other mappings belonging to other processes in the 1MB range
+	 * covered by the L1 entry.
+	 *
+	 * Since 'rv == 0', we know that the L1 already contains the correct
+	 * value, so the fault must be due to a stale TLB entry.
+	 *
+	 * Since we always need to flush the TLB anyway in the case where we
+	 * fixed up the L1, or frobbed the L2 PTE, we effectively deal with
+	 * stale TLB entries dynamically.
+	 *
+	 * However, the above condition can ONLY happen if the current L1 is
+	 * being shared. If it happens when the L1 is unshared, it indicates
+	 * that other parts of the pmap are not doing their job WRT managing
+	 * the TLB.
+	 */
+	if (rv == 0 && pmap->pm_l1->l1_domain_use_count == 1) {
+		printf("fixup: pmap %p, va 0x%08x, ftype %d - nothing to do!\n",
+		    pmap, va, ftype);
+		printf("fixup: l2 %p, l2b %p, ptep %p, pl1pd %p\n",
+		    l2, l2b, ptep, pl1pd);
+		printf("fixup: pte 0x%x, l1pd 0x%x, last code 0x%x\n",
+		    pte, l1pd, last_fault_code);
+#ifdef DDB
+		Debugger();
+#endif
+	}
+#endif
+
+l1_section_out:
+	cpu_tlb_flushID_SE(va);
+	cpu_cpwait();
+
+	rv = 1;
+
+out:
+	rw_wunlock(&pvh_global_lock);
+	PMAP_UNLOCK(pmap);
+	return (rv);
+}
+
+void
+pmap_postinit(void)
+{
+	struct l2_bucket *l2b;
+	struct l1_ttable *l1;
+	pd_entry_t *pl1pt;
+	pt_entry_t *ptep, pte;
+	vm_offset_t va, eva;
+	u_int loop, needed;
+
+	needed = (maxproc / PMAP_DOMAINS) + ((maxproc % PMAP_DOMAINS) ? 1 : 0);
+	needed -= 1;
+	l1 = malloc(sizeof(*l1) * needed, M_VMPMAP, M_WAITOK);
+
+	for (loop = 0; loop < needed; loop++, l1++) {
+		/* Allocate a L1 page table */
+		va = (vm_offset_t)contigmalloc(L1_TABLE_SIZE, M_VMPMAP, 0, 0x0,
+		    0xffffffff, L1_TABLE_SIZE, 0);
+
+		if (va == 0)
+			panic("Cannot allocate L1 KVM");
+
+		eva = va + L1_TABLE_SIZE;
+		pl1pt = (pd_entry_t *)va;
+
+		while (va < eva) {
+				l2b = pmap_get_l2_bucket(pmap_kernel(), va);
+				ptep = &l2b->l2b_kva[l2pte_index(va)];
+				pte = *ptep;
+				pte = (pte & ~L2_S_CACHE_MASK) | pte_l2_s_cache_mode_pt;
+				*ptep = pte;
+				PTE_SYNC(ptep);
+				cpu_tlb_flushID_SE(va);
+				cpu_cpwait();
+				va += PAGE_SIZE;
+		}
+		pmap_init_l1(l1, pl1pt);
+	}
+#ifdef DEBUG
+	printf("pmap_postinit: Allocated %d static L1 descriptor tables\n",
+	    needed);
+#endif
+}
+
+/*
+ * This is used to stuff certain critical values into the PCB where they
+ * can be accessed quickly from cpu_switch() et al.
+ */
+void
+pmap_set_pcb_pagedir(pmap_t pmap, struct pcb *pcb)
+{
+	struct l2_bucket *l2b;
+
+	pcb->pcb_pagedir = pmap->pm_l1->l1_physaddr;
+	pcb->pcb_dacr = (DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL * 2)) |
+	    (DOMAIN_CLIENT << (pmap->pm_domain * 2));
+
+	if (vector_page < KERNBASE) {
+		pcb->pcb_pl1vec = &pmap->pm_l1->l1_kva[L1_IDX(vector_page)];
+		l2b = pmap_get_l2_bucket(pmap, vector_page);
+		pcb->pcb_l1vec = l2b->l2b_phys | L1_C_PROTO |
+		    L1_C_DOM(pmap->pm_domain) | L1_C_DOM(PMAP_DOMAIN_KERNEL);
+	} else
+		pcb->pcb_pl1vec = NULL;
+}
+
+void
+pmap_activate(struct thread *td)
+{
+	pmap_t pmap;
+	struct pcb *pcb;
+
+	pmap = vmspace_pmap(td->td_proc->p_vmspace);
+	pcb = td->td_pcb;
+
+	critical_enter();
+	pmap_set_pcb_pagedir(pmap, pcb);
+
+	if (td == curthread) {
+		u_int cur_dacr, cur_ttb;
+
+		__asm __volatile("mrc p15, 0, %0, c2, c0, 0" : "=r"(cur_ttb));
+		__asm __volatile("mrc p15, 0, %0, c3, c0, 0" : "=r"(cur_dacr));
+
+		cur_ttb &= ~(L1_TABLE_SIZE - 1);
+
+		if (cur_ttb == (u_int)pcb->pcb_pagedir &&
+		    cur_dacr == pcb->pcb_dacr) {
+			/*
+			 * No need to switch address spaces.
+			 */
+			critical_exit();
+			return;
+		}
+
+
+		/*
+		 * We MUST, I repeat, MUST fix up the L1 entry corresponding
+		 * to 'vector_page' in the incoming L1 table before switching
+		 * to it otherwise subsequent interrupts/exceptions (including
+		 * domain faults!) will jump into hyperspace.
+		 */
+		if (pcb->pcb_pl1vec) {
+			*pcb->pcb_pl1vec = pcb->pcb_l1vec;
+		}
+
+		cpu_domains(pcb->pcb_dacr);
+		cpu_setttb(pcb->pcb_pagedir);
+	}
+	critical_exit();
+}
+
+static int
+pmap_set_pt_cache_mode(pd_entry_t *kl1, vm_offset_t va)
+{
+	pd_entry_t *pdep, pde;
+	pt_entry_t *ptep, pte;
+	vm_offset_t pa;
+	int rv = 0;
+
+	/*
+	 * Make sure the descriptor itself has the correct cache mode
+	 */
+	pdep = &kl1[L1_IDX(va)];
+	pde = *pdep;
+
+	if (l1pte_section_p(pde)) {
+		if ((pde & L1_S_CACHE_MASK) != pte_l1_s_cache_mode_pt) {
+			*pdep = (pde & ~L1_S_CACHE_MASK) |
+			    pte_l1_s_cache_mode_pt;
+			PTE_SYNC(pdep);
+			rv = 1;
+		}
+	} else {
+		pa = (vm_paddr_t)(pde & L1_C_ADDR_MASK);
+		ptep = (pt_entry_t *)kernel_pt_lookup(pa);
+		if (ptep == NULL)
+			panic("pmap_bootstrap: No L2 for L2 @ va %p\n", ptep);
+
+		ptep = &ptep[l2pte_index(va)];
+		pte = *ptep;
+		if ((pte & L2_S_CACHE_MASK) != pte_l2_s_cache_mode_pt) {
+			*ptep = (pte & ~L2_S_CACHE_MASK) |
+			    pte_l2_s_cache_mode_pt;
+			PTE_SYNC(ptep);
+			rv = 1;
+		}
+	}
+
+	return (rv);
+}
+
+static void
+pmap_alloc_specials(vm_offset_t *availp, int pages, vm_offset_t *vap,
+    pt_entry_t **ptep)
+{
+	vm_offset_t va = *availp;
+	struct l2_bucket *l2b;
+
+	if (ptep) {
+		l2b = pmap_get_l2_bucket(pmap_kernel(), va);
+		if (l2b == NULL)
+			panic("pmap_alloc_specials: no l2b for 0x%x", va);
+
+		*ptep = &l2b->l2b_kva[l2pte_index(va)];
+	}
+
+	*vap = va;
+	*availp = va + (PAGE_SIZE * pages);
+}
+
+/*
+ *	Bootstrap the system enough to run with virtual memory.
+ *
+ *	On the arm this is called after mapping has already been enabled
+ *	and just syncs the pmap module with what has already been done.
+ *	[We can't call it easily with mapping off since the kernel is not
+ *	mapped with PA == VA, hence we would have to relocate every address
+ *	from the linked base (virtual) address "KERNBASE" to the actual
+ *	(physical) address starting relative to 0]
+ */
+#define PMAP_STATIC_L2_SIZE 16
+
+void
+pmap_bootstrap(vm_offset_t firstaddr, struct pv_addr *l1pt)
+{
+	static struct l1_ttable static_l1;
+	static struct l2_dtable static_l2[PMAP_STATIC_L2_SIZE];
+	struct l1_ttable *l1 = &static_l1;
+	struct l2_dtable *l2;
+	struct l2_bucket *l2b;
+	struct czpages *czp;
+	pd_entry_t pde;
+	pd_entry_t *kernel_l1pt = (pd_entry_t *)l1pt->pv_va;
+	pt_entry_t *ptep;
+	vm_paddr_t pa;
+	vm_offset_t va;
+	vm_size_t size;
+	int i, l1idx, l2idx, l2next = 0;
+
+	PDEBUG(1, printf("firstaddr = %08x, lastaddr = %08x\n",
+	    firstaddr, vm_max_kernel_address));
+
+	virtual_avail = firstaddr;
+	kernel_pmap->pm_l1 = l1;
+	kernel_l1pa = l1pt->pv_pa;
+
+	/*
+	 * Scan the L1 translation table created by initarm() and create
+	 * the required metadata for all valid mappings found in it.
+	 */
+	for (l1idx = 0; l1idx < (L1_TABLE_SIZE / sizeof(pd_entry_t)); l1idx++) {
+		pde = kernel_l1pt[l1idx];
+
+		/*
+		 * We're only interested in Coarse mappings.
+		 * pmap_extract() can deal with section mappings without
+		 * recourse to checking L2 metadata.
+		 */
+		if ((pde & L1_TYPE_MASK) != L1_TYPE_C)
+			continue;
+
+		/*
+		 * Lookup the KVA of this L2 descriptor table
+		 */
+		pa = (vm_paddr_t)(pde & L1_C_ADDR_MASK);
+		ptep = (pt_entry_t *)kernel_pt_lookup(pa);
+
+		if (ptep == NULL) {
+			panic("pmap_bootstrap: No L2 for va 0x%x, pa 0x%lx",
+			    (u_int)l1idx << L1_S_SHIFT, (long unsigned int)pa);
+		}
+
+		/*
+		 * Fetch the associated L2 metadata structure.
+		 * Allocate a new one if necessary.
+		 */
+		if ((l2 = kernel_pmap->pm_l2[L2_IDX(l1idx)]) == NULL) {
+			if (l2next == PMAP_STATIC_L2_SIZE)
+				panic("pmap_bootstrap: out of static L2s");
+			kernel_pmap->pm_l2[L2_IDX(l1idx)] = l2 =
+			    &static_l2[l2next++];
+		}
+
+		/*
+		 * One more L1 slot tracked...
+		 */
+		l2->l2_occupancy++;
+
+		/*
+		 * Fill in the details of the L2 descriptor in the
+		 * appropriate bucket.
+		 */
+		l2b = &l2->l2_bucket[L2_BUCKET(l1idx)];
+		l2b->l2b_kva = ptep;
+		l2b->l2b_phys = pa;
+		l2b->l2b_l1idx = l1idx;
+
+		/*
+		 * Establish an initial occupancy count for this descriptor
+		 */
+		for (l2idx = 0;
+		    l2idx < (L2_TABLE_SIZE_REAL / sizeof(pt_entry_t));
+		    l2idx++) {
+			if ((ptep[l2idx] & L2_TYPE_MASK) != L2_TYPE_INV) {
+				l2b->l2b_occupancy++;
+			}
+		}
+
+		/*
+		 * Make sure the descriptor itself has the correct cache mode.
+		 * If not, fix it, but whine about the problem. Port-meisters
+		 * should consider this a clue to fix up their initarm()
+		 * function. :)
+		 */
+		if (pmap_set_pt_cache_mode(kernel_l1pt, (vm_offset_t)ptep)) {
+			printf("pmap_bootstrap: WARNING! wrong cache mode for "
+			    "L2 pte @ %p\n", ptep);
+		}
+	}
+
+
+	/*
+	 * Ensure the primary (kernel) L1 has the correct cache mode for
+	 * a page table. Bitch if it is not correctly set.
+	 */
+	for (va = (vm_offset_t)kernel_l1pt;
+	    va < ((vm_offset_t)kernel_l1pt + L1_TABLE_SIZE); va += PAGE_SIZE) {
+		if (pmap_set_pt_cache_mode(kernel_l1pt, va))
+			printf("pmap_bootstrap: WARNING! wrong cache mode for "
+			    "primary L1 @ 0x%x\n", va);
+	}
+
+	cpu_dcache_wbinv_all();
+	cpu_l2cache_wbinv_all();
+	cpu_tlb_flushID();
+	cpu_cpwait();
+
+	PMAP_LOCK_INIT(kernel_pmap);
+	CPU_FILL(&kernel_pmap->pm_active);
+	kernel_pmap->pm_domain = PMAP_DOMAIN_KERNEL;
+	TAILQ_INIT(&kernel_pmap->pm_pvchunk);
+
+	/*
+	 * Initialize the global pv list lock.
+	 */
+	rw_init(&pvh_global_lock, "pmap pv global");
+
+	/*
+	 * Reserve some special page table entries/VA space for temporary
+	 * mapping of pages that are being copied or zeroed.
+	 */
+	for (czp = cpu_czpages, i = 0; i < MAXCPU; ++i, ++czp) {
+		mtx_init(&czp->lock, "czpages", NULL, MTX_DEF);
+		pmap_alloc_specials(&virtual_avail, 1, &czp->srcva, &czp->srcptep);
+		pmap_set_pt_cache_mode(kernel_l1pt, (vm_offset_t)czp->srcptep);
+		pmap_alloc_specials(&virtual_avail, 1, &czp->dstva, &czp->dstptep);
+		pmap_set_pt_cache_mode(kernel_l1pt, (vm_offset_t)czp->dstptep);
+	}
+
+	size = ((vm_max_kernel_address - pmap_curmaxkvaddr) + L1_S_OFFSET) /
+	    L1_S_SIZE;
+	pmap_alloc_specials(&virtual_avail,
+	    round_page(size * L2_TABLE_SIZE_REAL) / PAGE_SIZE,
+	    &pmap_kernel_l2ptp_kva, NULL);
+
+	size = (size + (L2_BUCKET_SIZE - 1)) / L2_BUCKET_SIZE;
+	pmap_alloc_specials(&virtual_avail,
+	    round_page(size * sizeof(struct l2_dtable)) / PAGE_SIZE,
+	    &pmap_kernel_l2dtable_kva, NULL);
+
+	pmap_alloc_specials(&virtual_avail,
+	    1, (vm_offset_t*)&_tmppt, NULL);
+	pmap_alloc_specials(&virtual_avail,
+	    MAXDUMPPGS, (vm_offset_t *)&crashdumpmap, NULL);
+	SLIST_INIT(&l1_list);
+	TAILQ_INIT(&l1_lru_list);
+	mtx_init(&l1_lru_lock, "l1 list lock", NULL, MTX_DEF);
+	pmap_init_l1(l1, kernel_l1pt);
+	cpu_dcache_wbinv_all();
+	cpu_l2cache_wbinv_all();
+	cpu_tlb_flushID();
+	cpu_cpwait();
+
+	virtual_avail = round_page(virtual_avail);
+	virtual_end = vm_max_kernel_address;
+	kernel_vm_end = pmap_curmaxkvaddr;
+
+	pmap_set_pcb_pagedir(kernel_pmap, thread0.td_pcb);
+}
+
+/***************************************************
+ * Pmap allocation/deallocation routines.
+ ***************************************************/
+
+/*
+ * Release any resources held by the given physical map.
+ * Called when a pmap initialized by pmap_pinit is being released.
+ * Should only be called if the map contains no valid mappings.
+ */
+void
+pmap_release(pmap_t pmap)
+{
+	struct pcb *pcb;
+
+	cpu_tlb_flushID();
+	cpu_cpwait();
+	if (vector_page < KERNBASE) {
+		struct pcb *curpcb = PCPU_GET(curpcb);
+		pcb = thread0.td_pcb;
+		if (pmap_is_current(pmap)) {
+			/*
+			 * Frob the L1 entry corresponding to the vector
+			 * page so that it contains the kernel pmap's domain
+			 * number. This will ensure pmap_remove() does not
+			 * pull the current vector page out from under us.
+			 */
+			critical_enter();
+			*pcb->pcb_pl1vec = pcb->pcb_l1vec;
+			cpu_domains(pcb->pcb_dacr);
+			cpu_setttb(pcb->pcb_pagedir);
+			critical_exit();
+		}
+		pmap_remove(pmap, vector_page, vector_page + PAGE_SIZE);
+		/*
+		 * Make sure cpu_switch(), et al, DTRT. This is safe to do
+		 * since this process has no remaining mappings of its own.
+		 */
+		curpcb->pcb_pl1vec = pcb->pcb_pl1vec;
+		curpcb->pcb_l1vec = pcb->pcb_l1vec;
+		curpcb->pcb_dacr = pcb->pcb_dacr;
+		curpcb->pcb_pagedir = pcb->pcb_pagedir;
+
+	}
+	pmap_free_l1(pmap);
+
+	dprintf("pmap_release()\n");
+}
+
+
+
+/*
+ * Helper function for pmap_grow_l2_bucket()
+ */
+static __inline int
+pmap_grow_map(vm_offset_t va, pt_entry_t cache_mode, vm_paddr_t *pap)
+{
+	struct l2_bucket *l2b;
+	pt_entry_t *ptep;
+	vm_paddr_t pa;
+	struct vm_page *m;
+
+	m = vm_page_alloc(NULL, 0, VM_ALLOC_NOOBJ | VM_ALLOC_WIRED);
+	if (m == NULL)
+		return (1);
+	pa = VM_PAGE_TO_PHYS(m);
+
+	if (pap)
+		*pap = pa;
+
+	l2b = pmap_get_l2_bucket(pmap_kernel(), va);
+
+	ptep = &l2b->l2b_kva[l2pte_index(va)];
+	*ptep = L2_S_PROTO | pa | cache_mode | L2_S_REF;
+	pmap_set_prot(ptep, VM_PROT_READ | VM_PROT_WRITE, 0);
+	PTE_SYNC(ptep);
+	cpu_tlb_flushD_SE(va);
+	cpu_cpwait();
+
+	return (0);
+}
+
+/*
+ * This is the same as pmap_alloc_l2_bucket(), except that it is only
+ * used by pmap_growkernel().
+ */
+static __inline struct l2_bucket *
+pmap_grow_l2_bucket(pmap_t pmap, vm_offset_t va)
+{
+	struct l2_dtable *l2;
+	struct l2_bucket *l2b;
+	struct l1_ttable *l1;
+	pd_entry_t *pl1pd;
+	u_short l1idx;
+	vm_offset_t nva;
+
+	l1idx = L1_IDX(va);
+
+	if ((l2 = pmap->pm_l2[L2_IDX(l1idx)]) == NULL) {
+		/*
+		 * No mapping at this address, as there is
+		 * no entry in the L1 table.
+		 * Need to allocate a new l2_dtable.
+		 */
+		nva = pmap_kernel_l2dtable_kva;
+		if ((nva & PAGE_MASK) == 0) {
+			/*
+			 * Need to allocate a backing page
+			 */
+			if (pmap_grow_map(nva, pte_l2_s_cache_mode, NULL))
+				return (NULL);
+		}
+
+		l2 = (struct l2_dtable *)nva;
+		nva += sizeof(struct l2_dtable);
+
+		if ((nva & PAGE_MASK) < (pmap_kernel_l2dtable_kva &
+		    PAGE_MASK)) {
+			/*
+			 * The new l2_dtable straddles a page boundary.
+			 * Map in another page to cover it.
+			 */
+			if (pmap_grow_map(nva, pte_l2_s_cache_mode, NULL))
+				return (NULL);
+		}
+
+		pmap_kernel_l2dtable_kva = nva;
+
+		/*
+		 * Link it into the parent pmap
+		 */
+		pmap->pm_l2[L2_IDX(l1idx)] = l2;
+		memset(l2, 0, sizeof(*l2));
+	}
+
+	l2b = &l2->l2_bucket[L2_BUCKET(l1idx)];
+
+	/*
+	 * Fetch pointer to the L2 page table associated with the address.
+	 */
+	if (l2b->l2b_kva == NULL) {
+		pt_entry_t *ptep;
+
+		/*
+		 * No L2 page table has been allocated. Chances are, this
+		 * is because we just allocated the l2_dtable, above.
+		 */
+		nva = pmap_kernel_l2ptp_kva;
+		ptep = (pt_entry_t *)nva;
+		if ((nva & PAGE_MASK) == 0) {
+			/*
+			 * Need to allocate a backing page
+			 */
+			if (pmap_grow_map(nva, pte_l2_s_cache_mode_pt,
+			    &pmap_kernel_l2ptp_phys))
+				return (NULL);
+		}
+		memset(ptep, 0, L2_TABLE_SIZE_REAL);
+		l2->l2_occupancy++;
+		l2b->l2b_kva = ptep;
+		l2b->l2b_l1idx = l1idx;
+		l2b->l2b_phys = pmap_kernel_l2ptp_phys;
+
+		pmap_kernel_l2ptp_kva += L2_TABLE_SIZE_REAL;
+		pmap_kernel_l2ptp_phys += L2_TABLE_SIZE_REAL;
+	}
+
+	/* Distribute new L1 entry to all other L1s */
+	SLIST_FOREACH(l1, &l1_list, l1_link) {
+			pl1pd = &l1->l1_kva[L1_IDX(va)];
+			*pl1pd = l2b->l2b_phys | L1_C_DOM(PMAP_DOMAIN_KERNEL) |
+			    L1_C_PROTO;
+			PTE_SYNC(pl1pd);
+	}
+	cpu_tlb_flushID_SE(va);
+	cpu_cpwait();
+
+	return (l2b);
+}
+
+
+/*
+ * grow the number of kernel page table entries, if needed
+ */
+void
+pmap_growkernel(vm_offset_t addr)
+{
+	pmap_t kpmap = pmap_kernel();
+
+	if (addr <= pmap_curmaxkvaddr)
+		return;		/* we are OK */
+
+	/*
+	 * whoops!   we need to add kernel PTPs
+	 */
+
+	/* Map 1MB at a time */
+	for (; pmap_curmaxkvaddr < addr; pmap_curmaxkvaddr += L1_S_SIZE)
+		pmap_grow_l2_bucket(kpmap, pmap_curmaxkvaddr);
+
+	kernel_vm_end = pmap_curmaxkvaddr;
+}
+
+/*
+ * Returns TRUE if the given page is mapped individually or as part of
+ * a 1MB section.  Otherwise, returns FALSE.
+ */
+boolean_t
+pmap_page_is_mapped(vm_page_t m)
+{
+	boolean_t rv;
+
+	if ((m->oflags & VPO_UNMANAGED) != 0)
+		return (FALSE);
+	rw_wlock(&pvh_global_lock);
+	rv = !TAILQ_EMPTY(&m->md.pv_list) ||
+	    ((m->flags & PG_FICTITIOUS) == 0 &&
+	    !TAILQ_EMPTY(&pa_to_pvh(VM_PAGE_TO_PHYS(m))->pv_list));
+	rw_wunlock(&pvh_global_lock);
+	return (rv);
+}
+
+/*
+ * Remove all pages from specified address space
+ * this aids process exit speeds.  Also, this code
+ * is special cased for current process only, but
+ * can have the more generic (and slightly slower)
+ * mode enabled.  This is much faster than pmap_remove
+ * in the case of running down an entire address space.
+ */
+void
+pmap_remove_pages(pmap_t pmap)
+{
+	struct pv_entry *pv;
+ 	struct l2_bucket *l2b = NULL;
+	struct pv_chunk *pc, *npc;
+	struct md_page *pvh;
+	pd_entry_t *pl1pd, l1pd;
+ 	pt_entry_t *ptep;
+ 	vm_page_t m, mt;
+	vm_offset_t va;
+	uint32_t inuse, bitmask;
+	int allfree, bit, field, idx;
+ 
+ 	rw_wlock(&pvh_global_lock);
+ 	PMAP_LOCK(pmap);
+
+	TAILQ_FOREACH_SAFE(pc, &pmap->pm_pvchunk, pc_list, npc) {
+		allfree = 1;
+		for (field = 0; field < _NPCM; field++) {
+			inuse = ~pc->pc_map[field] & pc_freemask[field];
+			while (inuse != 0) {
+				bit = ffs(inuse) - 1;
+				bitmask = 1ul << bit;
+				idx = field * sizeof(inuse) * NBBY + bit;
+				pv = &pc->pc_pventry[idx];
+				va = pv->pv_va;
+				inuse &= ~bitmask;
+				if (pv->pv_flags & PVF_WIRED) {
+					/* Cannot remove wired pages now. */
+					allfree = 0;
+					continue;
+				}
+				pl1pd = &pmap->pm_l1->l1_kva[L1_IDX(va)];
+				l1pd = *pl1pd;
+				l2b = pmap_get_l2_bucket(pmap, va);
+				if ((l1pd & L1_TYPE_MASK) == L1_S_PROTO) {
+					pvh = pa_to_pvh(l1pd & L1_S_FRAME);
+					TAILQ_REMOVE(&pvh->pv_list, pv, pv_list);
+					if (TAILQ_EMPTY(&pvh->pv_list)) {
+						m = PHYS_TO_VM_PAGE(l1pd & L1_S_FRAME);
+						KASSERT((vm_offset_t)m >= KERNBASE,
+						    ("Trying to access non-existent page "
+						     "va %x l1pd %x", trunc_1mpage(va), l1pd));
+						for (mt = m; mt < &m[L2_PTE_NUM_TOTAL]; mt++) {
+							if (TAILQ_EMPTY(&mt->md.pv_list))
+								vm_page_aflag_clear(mt, PGA_WRITEABLE);
+						}
+					}
+					if (l2b != NULL) {
+						KASSERT(l2b->l2b_occupancy == L2_PTE_NUM_TOTAL,
+						    ("pmap_remove_pages: l2_bucket occupancy error"));
+						pmap_free_l2_bucket(pmap, l2b, L2_PTE_NUM_TOTAL);
+					}
+					pmap->pm_stats.resident_count -= L2_PTE_NUM_TOTAL;
+					*pl1pd = 0;
+					PTE_SYNC(pl1pd);
+				} else {
+					KASSERT(l2b != NULL,
+					    ("No L2 bucket in pmap_remove_pages"));
+					ptep = &l2b->l2b_kva[l2pte_index(va)];
+					m = PHYS_TO_VM_PAGE(l2pte_pa(*ptep));
+					KASSERT((vm_offset_t)m >= KERNBASE,
+					    ("Trying to access non-existent page "
+					     "va %x pte %x", va, *ptep));
+					TAILQ_REMOVE(&m->md.pv_list, pv, pv_list);
+					if (TAILQ_EMPTY(&m->md.pv_list) &&
+					    (m->flags & PG_FICTITIOUS) == 0) {
+						pvh = pa_to_pvh(l2pte_pa(*ptep));
+						if (TAILQ_EMPTY(&pvh->pv_list))
+							vm_page_aflag_clear(m, PGA_WRITEABLE);
+					}
+					*ptep = 0;
+					PTE_SYNC(ptep);
+					pmap_free_l2_bucket(pmap, l2b, 1);
+					pmap->pm_stats.resident_count--;
+				}
+
+				/* Mark free */
+				PV_STAT(pv_entry_frees++);
+				PV_STAT(pv_entry_spare++);
+				pv_entry_count--;
+				pc->pc_map[field] |= bitmask;
+			}
+		}
+		if (allfree) {
+			TAILQ_REMOVE(&pmap->pm_pvchunk, pc, pc_list);
+			pmap_free_pv_chunk(pc);
+		}
+
+	}
+
+ 	rw_wunlock(&pvh_global_lock);
+ 	cpu_tlb_flushID();
+ 	cpu_cpwait();
+ 	PMAP_UNLOCK(pmap);
+}
+
+
+/***************************************************
+ * Low level mapping routines.....
+ ***************************************************/
+
+#ifdef ARM_HAVE_SUPERSECTIONS
+/* Map a super section into the KVA. */
+
+void
+pmap_kenter_supersection(vm_offset_t va, uint64_t pa, int flags)
+{
+	pd_entry_t pd = L1_S_PROTO | L1_S_SUPERSEC | (pa & L1_SUP_FRAME) |
+	    (((pa >> 32) & 0xf) << 20) | L1_S_PROT(PTE_KERNEL,
+	    VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE) |
+	    L1_S_DOM(PMAP_DOMAIN_KERNEL);
+	struct l1_ttable *l1;
+	vm_offset_t va0, va_end;
+
+	KASSERT(((va | pa) & L1_SUP_OFFSET) == 0,
+	    ("Not a valid super section mapping"));
+	if (flags & SECTION_CACHE)
+		pd |= pte_l1_s_cache_mode;
+	else if (flags & SECTION_PT)
+		pd |= pte_l1_s_cache_mode_pt;
+
+	va0 = va & L1_SUP_FRAME;
+	va_end = va + L1_SUP_SIZE;
+	SLIST_FOREACH(l1, &l1_list, l1_link) {
+		va = va0;
+		for (; va < va_end; va += L1_S_SIZE) {
+			l1->l1_kva[L1_IDX(va)] = pd;
+			PTE_SYNC(&l1->l1_kva[L1_IDX(va)]);
+		}
+	}
+}
+#endif
+
+/* Map a section into the KVA. */
+
+void
+pmap_kenter_section(vm_offset_t va, vm_offset_t pa, int flags)
+{
+	pd_entry_t pd = L1_S_PROTO | pa | L1_S_PROT(PTE_KERNEL,
+	    VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE) | L1_S_REF |
+	    L1_S_DOM(PMAP_DOMAIN_KERNEL);
+	struct l1_ttable *l1;
+
+	KASSERT(((va | pa) & L1_S_OFFSET) == 0,
+	    ("Not a valid section mapping"));
+	if (flags & SECTION_CACHE)
+		pd |= pte_l1_s_cache_mode;
+	else if (flags & SECTION_PT)
+		pd |= pte_l1_s_cache_mode_pt;
+
+	SLIST_FOREACH(l1, &l1_list, l1_link) {
+		l1->l1_kva[L1_IDX(va)] = pd;
+		PTE_SYNC(&l1->l1_kva[L1_IDX(va)]);
+	}
+	cpu_tlb_flushID_SE(va);
+	cpu_cpwait();
+}
+
+/*
+ * Make a temporary mapping for a physical address.  This is only intended
+ * to be used for panic dumps.
+ */
+void *
+pmap_kenter_temporary(vm_paddr_t pa, int i)
+{
+	vm_offset_t va;
+
+	va = (vm_offset_t)crashdumpmap + (i * PAGE_SIZE);
+	pmap_kenter(va, pa);
+	return ((void *)crashdumpmap);
+}
+
+/*
+ * add a wired page to the kva
+ * note that in order for the mapping to take effect -- you
+ * should do a invltlb after doing the pmap_kenter...
+ */
+static PMAP_INLINE void
+pmap_kenter_internal(vm_offset_t va, vm_offset_t pa, int flags)
+{
+	struct l2_bucket *l2b;
+	pt_entry_t *ptep;
+	pt_entry_t opte;
+
+	PDEBUG(1, printf("pmap_kenter: va = %08x, pa = %08x\n",
+	    (uint32_t) va, (uint32_t) pa));
+
+
+	l2b = pmap_get_l2_bucket(pmap_kernel(), va);
+	if (l2b == NULL)
+		l2b = pmap_grow_l2_bucket(pmap_kernel(), va);
+	KASSERT(l2b != NULL, ("No L2 Bucket"));
+
+	ptep = &l2b->l2b_kva[l2pte_index(va)];
+	opte = *ptep;
+
+	if (flags & KENTER_CACHE)
+		*ptep = L2_S_PROTO | l2s_mem_types[PTE_CACHE] | pa | L2_S_REF;
+	else if (flags & KENTER_DEVICE)
+		*ptep = L2_S_PROTO | l2s_mem_types[PTE_DEVICE] | pa | L2_S_REF;
+	else
+		*ptep = L2_S_PROTO | l2s_mem_types[PTE_NOCACHE] | pa | L2_S_REF;
+
+	if (flags & KENTER_CACHE) {
+		pmap_set_prot(ptep, VM_PROT_READ | VM_PROT_WRITE,
+		    flags & KENTER_USER);
+	} else {
+		pmap_set_prot(ptep, VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE,
+		    0);
+	}
+
+	PTE_SYNC(ptep);
+	if (l2pte_valid(opte)) {
+		if (L2_S_EXECUTABLE(opte) || L2_S_EXECUTABLE(*ptep))
+			cpu_tlb_flushID_SE(va);
+		else
+			cpu_tlb_flushD_SE(va);
+	} else {
+		if (opte == 0)
+			l2b->l2b_occupancy++;
+	}
+	cpu_cpwait();
+
+	PDEBUG(1, printf("pmap_kenter: pte = %08x, opte = %08x, npte = %08x\n",
+	    (uint32_t) ptep, opte, *ptep));
+}
+
+void
+pmap_kenter(vm_offset_t va, vm_paddr_t pa)
+{
+	pmap_kenter_internal(va, pa, KENTER_CACHE);
+}
+
+void
+pmap_kenter_nocache(vm_offset_t va, vm_paddr_t pa)
+{
+
+	pmap_kenter_internal(va, pa, 0);
+}
+
+void
+pmap_kenter_device(vm_offset_t va, vm_paddr_t pa)
+{
+
+	pmap_kenter_internal(va, pa, KENTER_DEVICE);
+}
+
+void
+pmap_kenter_user(vm_offset_t va, vm_paddr_t pa)
+{
+
+	pmap_kenter_internal(va, pa, KENTER_CACHE|KENTER_USER);
+	/*
+	 * Call pmap_fault_fixup now, to make sure we'll have no exception
+	 * at the first use of the new address, or bad things will happen,
+	 * as we use one of these addresses in the exception handlers.
+	 */
+	pmap_fault_fixup(pmap_kernel(), va, VM_PROT_READ|VM_PROT_WRITE, 1);
+}
+
+vm_paddr_t
+pmap_kextract(vm_offset_t va)
+{
+
+	if (kernel_vm_end == 0)
+		return (0);
+	return (pmap_extract_locked(kernel_pmap, va));
+}
+
+/*
+ * remove a page from the kernel pagetables
+ */
+void
+pmap_kremove(vm_offset_t va)
+{
+	struct l2_bucket *l2b;
+	pt_entry_t *ptep, opte;
+
+	l2b = pmap_get_l2_bucket(pmap_kernel(), va);
+	if (!l2b)
+		return;
+	KASSERT(l2b != NULL, ("No L2 Bucket"));
+	ptep = &l2b->l2b_kva[l2pte_index(va)];
+	opte = *ptep;
+	if (l2pte_valid(opte)) {
+		va = va & ~PAGE_MASK;
+		*ptep = 0;
+		PTE_SYNC(ptep);
+		if (L2_S_EXECUTABLE(opte))
+			cpu_tlb_flushID_SE(va);
+		else
+			cpu_tlb_flushD_SE(va);
+		cpu_cpwait();
+	}
+}
+
+
+/*
+ *	Used to map a range of physical addresses into kernel
+ *	virtual address space.
+ *
+ *	The value passed in '*virt' is a suggested virtual address for
+ *	the mapping. Architectures which can support a direct-mapped
+ *	physical to virtual region can return the appropriate address
+ *	within that region, leaving '*virt' unchanged. Other
+ *	architectures should map the pages starting at '*virt' and
+ *	update '*virt' with the first usable address after the mapped
+ *	region.
+ */
+vm_offset_t
+pmap_map(vm_offset_t *virt, vm_offset_t start, vm_offset_t end, int prot)
+{
+	vm_offset_t sva = *virt;
+	vm_offset_t va = sva;
+
+	PDEBUG(1, printf("pmap_map: virt = %08x, start = %08x, end = %08x, "
+	    "prot = %d\n", (uint32_t) *virt, (uint32_t) start, (uint32_t) end,
+	    prot));
+
+	while (start < end) {
+		pmap_kenter(va, start);
+		va += PAGE_SIZE;
+		start += PAGE_SIZE;
+	}
+	*virt = va;
+	return (sva);
+}
+
+/*
+ * Add a list of wired pages to the kva
+ * this routine is only used for temporary
+ * kernel mappings that do not need to have
+ * page modification or references recorded.
+ * Note that old mappings are simply written
+ * over.  The page *must* be wired.
+ */
+void
+pmap_qenter(vm_offset_t va, vm_page_t *m, int count)
+{
+	int i;
+
+	for (i = 0; i < count; i++) {
+		pmap_kenter_internal(va, VM_PAGE_TO_PHYS(m[i]),
+		    KENTER_CACHE);
+		va += PAGE_SIZE;
+	}
+}
+
+
+/*
+ * this routine jerks page mappings from the
+ * kernel -- it is meant only for temporary mappings.
+ */
+void
+pmap_qremove(vm_offset_t va, int count)
+{
+	int i;
+
+	for (i = 0; i < count; i++) {
+		if (vtophys(va))
+			pmap_kremove(va);
+
+		va += PAGE_SIZE;
+	}
+}
+
+
+/*
+ * pmap_object_init_pt preloads the ptes for a given object
+ * into the specified pmap.  This eliminates the blast of soft
+ * faults on process startup and immediately after an mmap.
+ */
+void
+pmap_object_init_pt(pmap_t pmap, vm_offset_t addr, vm_object_t object,
+    vm_pindex_t pindex, vm_size_t size)
+{
+
+	VM_OBJECT_ASSERT_WLOCKED(object);
+	KASSERT(object->type == OBJT_DEVICE || object->type == OBJT_SG,
+	    ("pmap_object_init_pt: non-device object"));
+}
+
+
+/*
+ *	pmap_is_prefaultable:
+ *
+ *	Return whether or not the specified virtual address is elgible
+ *	for prefault.
+ */
+boolean_t
+pmap_is_prefaultable(pmap_t pmap, vm_offset_t addr)
+{
+	pd_entry_t *pdep;
+	pt_entry_t *ptep;
+
+	if (!pmap_get_pde_pte(pmap, addr, &pdep, &ptep))
+		return (FALSE);
+	KASSERT((pdep != NULL && (l1pte_section_p(*pdep) || ptep != NULL)),
+	    ("Valid mapping but no pte ?"));
+	if (*pdep != 0 && !l1pte_section_p(*pdep))
+		if (*ptep == 0)
+			return (TRUE);
+	return (FALSE);
+}
+
+/*
+ * Fetch pointers to the PDE/PTE for the given pmap/VA pair.
+ * Returns TRUE if the mapping exists, else FALSE.
+ *
+ * NOTE: This function is only used by a couple of arm-specific modules.
+ * It is not safe to take any pmap locks here, since we could be right
+ * in the middle of debugging the pmap anyway...
+ *
+ * It is possible for this routine to return FALSE even though a valid
+ * mapping does exist. This is because we don't lock, so the metadata
+ * state may be inconsistent.
+ *
+ * NOTE: We can return a NULL *ptp in the case where the L1 pde is
+ * a "section" mapping.
+ */
+boolean_t
+pmap_get_pde_pte(pmap_t pmap, vm_offset_t va, pd_entry_t **pdp,
+    pt_entry_t **ptp)
+{
+	struct l2_dtable *l2;
+	pd_entry_t *pl1pd, l1pd;
+	pt_entry_t *ptep;
+	u_short l1idx;
+
+	if (pmap->pm_l1 == NULL)
+		return (FALSE);
+
+	l1idx = L1_IDX(va);
+	*pdp = pl1pd = &pmap->pm_l1->l1_kva[l1idx];
+	l1pd = *pl1pd;
+
+	if (l1pte_section_p(l1pd)) {
+		*ptp = NULL;
+		return (TRUE);
+	}
+
+	if (pmap->pm_l2 == NULL)
+		return (FALSE);
+
+	l2 = pmap->pm_l2[L2_IDX(l1idx)];
+
+	if (l2 == NULL ||
+	    (ptep = l2->l2_bucket[L2_BUCKET(l1idx)].l2b_kva) == NULL) {
+		return (FALSE);
+	}
+
+	*ptp = &ptep[l2pte_index(va)];
+	return (TRUE);
+}
+
+/*
+ *      Routine:        pmap_remove_all
+ *      Function:
+ *              Removes this physical page from
+ *              all physical maps in which it resides.
+ *              Reflects back modify bits to the pager.
+ *
+ *      Notes:
+ *              Original versions of this routine were very
+ *              inefficient because they iteratively called
+ *              pmap_remove (slow...)
+ */
+void
+pmap_remove_all(vm_page_t m)
+{
+	struct md_page *pvh;
+	pv_entry_t pv;
+	pmap_t pmap;
+	pt_entry_t *ptep;
+	struct l2_bucket *l2b;
+	boolean_t flush = FALSE;
+	pmap_t curpmap;
+	u_int is_exec = 0;
+
+	KASSERT((m->oflags & VPO_UNMANAGED) == 0,
+	    ("pmap_remove_all: page %p is not managed", m));
+	rw_wlock(&pvh_global_lock);
+	if ((m->flags & PG_FICTITIOUS) != 0)
+		goto small_mappings;
+	pvh = pa_to_pvh(VM_PAGE_TO_PHYS(m));
+	while ((pv = TAILQ_FIRST(&pvh->pv_list)) != NULL) {
+		pmap = PV_PMAP(pv);
+		PMAP_LOCK(pmap);
+		pd_entry_t *pl1pd;
+		pl1pd = &pmap->pm_l1->l1_kva[L1_IDX(pv->pv_va)];
+		KASSERT((*pl1pd & L1_TYPE_MASK) == L1_S_PROTO,
+		    ("pmap_remove_all: valid section mapping expected"));
+		(void)pmap_demote_section(pmap, pv->pv_va);
+		PMAP_UNLOCK(pmap);
+	}
+small_mappings:
+	curpmap = vmspace_pmap(curproc->p_vmspace);
+	while ((pv = TAILQ_FIRST(&m->md.pv_list)) != NULL) {
+		pmap = PV_PMAP(pv);
+		if (flush == FALSE && (pmap == curpmap ||
+		    pmap == pmap_kernel()))
+			flush = TRUE;
+
+		PMAP_LOCK(pmap);
+		l2b = pmap_get_l2_bucket(pmap, pv->pv_va);
+		KASSERT(l2b != NULL, ("No l2 bucket"));
+		ptep = &l2b->l2b_kva[l2pte_index(pv->pv_va)];
+		is_exec |= PTE_BEEN_EXECD(*ptep);
+		*ptep = 0;
+		if (pmap_is_current(pmap))
+			PTE_SYNC(ptep);
+		pmap_free_l2_bucket(pmap, l2b, 1);
+		pmap->pm_stats.resident_count--;
+		TAILQ_REMOVE(&m->md.pv_list, pv, pv_list);
+		if (pv->pv_flags & PVF_WIRED)
+			pmap->pm_stats.wired_count--;
+		pmap_free_pv_entry(pmap, pv);
+		PMAP_UNLOCK(pmap);
+	}
+
+	if (flush) {
+		if (is_exec)
+			cpu_tlb_flushID();
+		else
+			cpu_tlb_flushD();
+		cpu_cpwait();
+	}
+	vm_page_aflag_clear(m, PGA_WRITEABLE);
+	rw_wunlock(&pvh_global_lock);
+}
+
+int
+pmap_change_attr(vm_offset_t sva, vm_size_t len, int mode)
+{
+	vm_offset_t base, offset, tmpva;
+	vm_size_t size;
+	struct l2_bucket *l2b;
+	pt_entry_t *ptep, pte;
+	vm_offset_t next_bucket;
+
+	PMAP_LOCK(kernel_pmap);
+
+	base = trunc_page(sva);
+	offset = sva & PAGE_MASK;
+	size = roundup(offset + len, PAGE_SIZE);
+
+#ifdef checkit
+	/*
+	 * Only supported on kernel virtual addresses, including the direct
+	 * map but excluding the recursive map.
+	 */
+	if (base < DMAP_MIN_ADDRESS) {
+		PMAP_UNLOCK(kernel_pmap);
+		return (EINVAL);
+	}
+#endif
+	for (tmpva = base; tmpva < base + size; ) {
+		next_bucket = L2_NEXT_BUCKET(tmpva);
+		if (next_bucket > base + size)
+			next_bucket = base + size;
+
+		l2b = pmap_get_l2_bucket(kernel_pmap, tmpva);
+		if (l2b == NULL) {
+			tmpva = next_bucket;
+			continue;
+		}
+
+		ptep = &l2b->l2b_kva[l2pte_index(tmpva)];
+
+		if (*ptep == 0) {
+			PMAP_UNLOCK(kernel_pmap);
+			return(EINVAL);
+		}
+
+		pte = *ptep &~ L2_S_CACHE_MASK;
+		cpu_idcache_wbinv_range(tmpva, PAGE_SIZE);
+		pmap_l2cache_wbinv_range(tmpva, pte & L2_S_FRAME, PAGE_SIZE);
+		*ptep = pte;
+		cpu_tlb_flushID_SE(tmpva);
+		cpu_cpwait();
+
+		dprintf("%s: for va:%x ptep:%x pte:%x\n",
+		    __func__, tmpva, (uint32_t)ptep, pte);
+		tmpva += PAGE_SIZE;
+	}
+
+	PMAP_UNLOCK(kernel_pmap);
+
+	return (0);
+}
+
+/*
+ *	Set the physical protection on the
+ *	specified range of this map as requested.
+ */
+void
+pmap_protect(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, vm_prot_t prot)
+{
+	struct l2_bucket *l2b;
+	struct md_page *pvh;
+	struct pv_entry *pve;
+	pd_entry_t *pl1pd, l1pd;
+	pt_entry_t *ptep, pte;
+	vm_offset_t next_bucket;
+	u_int is_exec, is_refd;
+	int flush;
+
+	if ((prot & VM_PROT_READ) == 0) {
+		pmap_remove(pmap, sva, eva);
+		return;
+	}
+
+	if (prot & VM_PROT_WRITE) {
+		/*
+		 * If this is a read->write transition, just ignore it and let
+		 * vm_fault() take care of it later.
+		 */
+		return;
+	}
+
+	rw_wlock(&pvh_global_lock);
+	PMAP_LOCK(pmap);
+
+	/*
+	 * OK, at this point, we know we're doing write-protect operation.
+	 * If the pmap is active, write-back the range.
+	 */
+
+	flush = ((eva - sva) >= (PAGE_SIZE * 4)) ? 0 : -1;
+	is_exec = is_refd = 0;
+
+	while (sva < eva) {
+		next_bucket = L2_NEXT_BUCKET(sva);
+		/*
+		 * Check for large page.
+		 */
+		pl1pd = &pmap->pm_l1->l1_kva[L1_IDX(sva)];
+		l1pd = *pl1pd;
+		if ((l1pd & L1_TYPE_MASK) == L1_S_PROTO) {
+			KASSERT(pmap != pmap_kernel(),
+			    ("pmap_protect: trying to modify "
+			    "kernel section protections"));
+			/*
+			 * Are we protecting the entire large page? If not,
+			 * demote the mapping and fall through.
+			 */
+			if (sva + L1_S_SIZE == L2_NEXT_BUCKET(sva) &&
+			    eva >= L2_NEXT_BUCKET(sva)) {
+				l1pd &= ~(L1_S_PROT_MASK | L1_S_XN);
+				if (!(prot & VM_PROT_EXECUTE))
+					*pl1pd |= L1_S_XN;
+				/*
+				 * At this point we are always setting
+				 * write-protect bit.
+				 */
+				l1pd |= L1_S_APX;
+				/* All managed superpages are user pages. */
+				l1pd |= L1_S_PROT_U;
+				*pl1pd = l1pd;
+				PTE_SYNC(pl1pd);
+				pvh = pa_to_pvh(l1pd & L1_S_FRAME);
+				pve = pmap_find_pv(pvh, pmap,
+				    trunc_1mpage(sva));
+				pve->pv_flags &= ~PVF_WRITE;
+				sva = next_bucket;
+				continue;
+			} else if (!pmap_demote_section(pmap, sva)) {
+				/* The large page mapping was destroyed. */
+				sva = next_bucket;
+				continue;
+			}
+		}
+		if (next_bucket > eva)
+			next_bucket = eva;
+		l2b = pmap_get_l2_bucket(pmap, sva);
+		if (l2b == NULL) {
+			sva = next_bucket;
+			continue;
+		}
+
+		ptep = &l2b->l2b_kva[l2pte_index(sva)];
+
+		while (sva < next_bucket) {
+			if ((pte = *ptep) != 0 && L2_S_WRITABLE(pte)) {
+				struct vm_page *m;
+
+				m = PHYS_TO_VM_PAGE(l2pte_pa(pte));
+				pmap_set_prot(ptep, prot,
+				    !(pmap == pmap_kernel()));
+				PTE_SYNC(ptep);
+
+				pmap_modify_pv(m, pmap, sva, PVF_WRITE, 0);
+
+				if (flush >= 0) {
+					flush++;
+					is_exec |= PTE_BEEN_EXECD(pte);
+					is_refd |= PTE_BEEN_REFD(pte);
+				} else {
+					if (PTE_BEEN_EXECD(pte))
+						cpu_tlb_flushID_SE(sva);
+					else if (PTE_BEEN_REFD(pte))
+						cpu_tlb_flushD_SE(sva);
+				}
+			}
+
+			sva += PAGE_SIZE;
+			ptep++;
+		}
+	}
+
+
+	if (flush) {
+		if (is_exec)
+			cpu_tlb_flushID();
+		else
+		if (is_refd)
+			cpu_tlb_flushD();
+		cpu_cpwait();
+	}
+	rw_wunlock(&pvh_global_lock);
+
+	PMAP_UNLOCK(pmap);
+}
+
+
+/*
+ *	Insert the given physical page (p) at
+ *	the specified virtual address (v) in the
+ *	target physical map with the protection requested.
+ *
+ *	If specified, the page will be wired down, meaning
+ *	that the related pte can not be reclaimed.
+ *
+ *	NB:  This is the only routine which MAY NOT lazy-evaluate
+ *	or lose information.  That is, this routine must actually
+ *	insert this page into the given map NOW.
+ */
+
+int
+pmap_enter(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot,
+    u_int flags, int8_t psind __unused)
+{
+	struct l2_bucket *l2b;
+	int rv;
+
+	rw_wlock(&pvh_global_lock);
+	PMAP_LOCK(pmap);
+	rv = pmap_enter_locked(pmap, va, m, prot, flags);
+	if (rv == KERN_SUCCESS) {
+		/*
+		 * If both the l2b_occupancy and the reservation are fully
+		 * populated, then attempt promotion.
+		 */
+		l2b = pmap_get_l2_bucket(pmap, va);
+		if (l2b != NULL && l2b->l2b_occupancy == L2_PTE_NUM_TOTAL &&
+		    sp_enabled && (m->flags & PG_FICTITIOUS) == 0 &&
+		    vm_reserv_level_iffullpop(m) == 0)
+			pmap_promote_section(pmap, va);
+	}
+	PMAP_UNLOCK(pmap);
+	rw_wunlock(&pvh_global_lock);
+	return (rv);
+}
+
+/*
+ *	The pvh global and pmap locks must be held.
+ */
+static int
+pmap_enter_locked(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot,
+    u_int flags)
+{
+	struct l2_bucket *l2b = NULL;
+	struct vm_page *om;
+	struct pv_entry *pve = NULL;
+	pd_entry_t *pl1pd, l1pd;
+	pt_entry_t *ptep, npte, opte;
+	u_int nflags;
+	u_int is_exec, is_refd;
+	vm_paddr_t pa;
+	u_char user;
+
+	PMAP_ASSERT_LOCKED(pmap);
+	rw_assert(&pvh_global_lock, RA_WLOCKED);
+	if (va == vector_page) {
+		pa = systempage.pv_pa;
+		m = NULL;
+	} else {
+		if ((m->oflags & VPO_UNMANAGED) == 0 && !vm_page_xbusied(m))
+			VM_OBJECT_ASSERT_LOCKED(m->object);
+		pa = VM_PAGE_TO_PHYS(m);
+	}
+
+	pl1pd = &pmap->pm_l1->l1_kva[L1_IDX(va)];
+	if ((va < VM_MAXUSER_ADDRESS) &&
+	    (*pl1pd & L1_TYPE_MASK) == L1_S_PROTO) {
+		(void)pmap_demote_section(pmap, va);
+	}
+
+	user = 0;
+	/*
+	 * Make sure userland mappings get the right permissions
+	 */
+	if (pmap != pmap_kernel() && va != vector_page)
+		user = 1;
+
+	nflags = 0;
+
+	if (prot & VM_PROT_WRITE)
+		nflags |= PVF_WRITE;
+	if ((flags & PMAP_ENTER_WIRED) != 0)
+		nflags |= PVF_WIRED;
+
+	PDEBUG(1, printf("pmap_enter: pmap = %08x, va = %08x, m = %08x, "
+	    "prot = %x, flags = %x\n", (uint32_t) pmap, va, (uint32_t) m,
+	    prot, flags));
+
+	if (pmap == pmap_kernel()) {
+		l2b = pmap_get_l2_bucket(pmap, va);
+		if (l2b == NULL)
+			l2b = pmap_grow_l2_bucket(pmap, va);
+	} else {
+do_l2b_alloc:
+		l2b = pmap_alloc_l2_bucket(pmap, va);
+		if (l2b == NULL) {
+			if ((flags & PMAP_ENTER_NOSLEEP) == 0) {
+				PMAP_UNLOCK(pmap);
+				rw_wunlock(&pvh_global_lock);
+				VM_WAIT;
+				rw_wlock(&pvh_global_lock);
+				PMAP_LOCK(pmap);
+				goto do_l2b_alloc;
+			}
+			return (KERN_RESOURCE_SHORTAGE);
+		}
+	}
+
+	pl1pd = &pmap->pm_l1->l1_kva[L1_IDX(va)];
+	if ((*pl1pd & L1_TYPE_MASK) == L1_S_PROTO)
+		panic("pmap_enter: attempt to enter on 1MB page, va: %#x", va);
+
+	ptep = &l2b->l2b_kva[l2pte_index(va)];
+
+	opte = *ptep;
+	npte = pa;
+	is_exec = is_refd = 0;
+
+	if (opte) {
+		if (l2pte_pa(opte) == pa) {
+			/*
+			 * We're changing the attrs of an existing mapping.
+			 */
+			if (m != NULL)
+				pmap_modify_pv(m, pmap, va,
+				    PVF_WRITE | PVF_WIRED, nflags);
+			is_exec |= PTE_BEEN_EXECD(opte);
+			is_refd |= PTE_BEEN_REFD(opte);
+			goto validate;
+		}
+		if ((om = PHYS_TO_VM_PAGE(l2pte_pa(opte)))) {
+			/*
+			 * Replacing an existing mapping with a new one.
+			 * It is part of our managed memory so we
+			 * must remove it from the PV list
+			 */
+			if ((pve = pmap_remove_pv(om, pmap, va))) {
+				is_exec |= PTE_BEEN_EXECD(opte);
+				is_refd |= PTE_BEEN_REFD(opte);
+		
+				if (m && ((m->oflags & VPO_UNMANAGED)))
+					pmap_free_pv_entry(pmap, pve);
+			}
+		}
+
+	} else {
+		/*
+		 * Keep the stats up to date
+		 */
+		l2b->l2b_occupancy++;
+		pmap->pm_stats.resident_count++;
+	}
+
+	/*
+	 * Enter on the PV list if part of our managed memory.
+	 */
+	if ((m && !(m->oflags & VPO_UNMANAGED))) {
+		if ((!pve) && (pve = pmap_get_pv_entry(pmap, FALSE)) == NULL)
+			panic("pmap_enter: no pv entries");
+
+		KASSERT(va < kmi.clean_sva || va >= kmi.clean_eva,
+		("pmap_enter: managed mapping within the clean submap"));
+		KASSERT(pve != NULL, ("No pv"));
+		pmap_enter_pv(m, pve, pmap, va, nflags);
+	}
+
+validate:
+	/* Make the new PTE valid */
+	npte |= L2_S_PROTO;
+#ifdef SMP
+	npte |= L2_SHARED;
+#endif
+	/* Set defaults first - kernel read access */
+	npte |= L2_APX;
+	npte |= L2_S_PROT_R;
+	/* Set "referenced" flag */
+	npte |= L2_S_REF;
+
+	/* Now tune APs as desired */
+	if (user)
+		npte |= L2_S_PROT_U;
+	/*
+	 * If this is not a vector_page
+	 * then continue setting mapping parameters
+	 */
+	if (m != NULL) {
+		if ((m->oflags & VPO_UNMANAGED) == 0) {
+			if (prot & (VM_PROT_ALL)) {
+				vm_page_aflag_set(m, PGA_REFERENCED);
+			} else {
+				/*
+				 * Need to do page referenced emulation.
+				 */
+				npte &= ~L2_S_REF;
+			}
+		}
+
+		if (prot & VM_PROT_WRITE) {
+			if ((m->oflags & VPO_UNMANAGED) == 0) {
+				vm_page_aflag_set(m, PGA_WRITEABLE);
+				/*
+				 * XXX: Skip modified bit emulation for now.
+				 *	The emulation reveals problems
+				 *	that result in random failures
+				 *	during memory allocation on some
+				 *	platforms.
+				 *	Therefore, the page is marked RW
+				 *	immediately.
+				 */
+				npte &= ~(L2_APX);
+				vm_page_dirty(m);
+			} else
+				npte &= ~(L2_APX);
+		}
+		if (!(prot & VM_PROT_EXECUTE))
+			npte |= L2_XN;
+
+		if (m->md.pv_memattr != VM_MEMATTR_UNCACHEABLE)
+			npte |= pte_l2_s_cache_mode;
+	}
+
+	CTR5(KTR_PMAP,"enter: pmap:%p va:%x prot:%x pte:%x->%x",
+	    pmap, va, prot, opte, npte);
+	/*
+	 * If this is just a wiring change, the two PTEs will be
+	 * identical, so there's no need to update the page table.
+	 */
+	if (npte != opte) {
+		boolean_t is_cached = pmap_is_current(pmap);
+
+		*ptep = npte;
+		PTE_SYNC(ptep);
+		if (is_cached) {
+			/*
+			 * We only need to frob the cache/tlb if this pmap
+			 * is current
+			 */
+			if (L1_IDX(va) != L1_IDX(vector_page) &&
+			    l2pte_valid(npte)) {
+				/*
+				 * This mapping is likely to be accessed as
+				 * soon as we return to userland. Fix up the
+				 * L1 entry to avoid taking another
+				 * page/domain fault.
+				 */
+				l1pd = l2b->l2b_phys |
+				    L1_C_DOM(pmap->pm_domain) | L1_C_PROTO;
+				if (*pl1pd != l1pd) {
+					*pl1pd = l1pd;
+					PTE_SYNC(pl1pd);
+				}
+			}
+		}
+
+		if (is_exec)
+			cpu_tlb_flushID_SE(va);
+		else if (is_refd)
+			cpu_tlb_flushD_SE(va);
+		cpu_cpwait();
+	}
+
+	if ((pmap != pmap_kernel()) && (pmap == &curproc->p_vmspace->vm_pmap))
+		cpu_icache_sync_range(va, PAGE_SIZE);
+	return (KERN_SUCCESS);
+}
+
+/*
+ * Maps a sequence of resident pages belonging to the same object.
+ * The sequence begins with the given page m_start.  This page is
+ * mapped at the given virtual address start.  Each subsequent page is
+ * mapped at a virtual address that is offset from start by the same
+ * amount as the page is offset from m_start within the object.  The
+ * last page in the sequence is the page with the largest offset from
+ * m_start that can be mapped at a virtual address less than the given
+ * virtual address end.  Not every virtual page between start and end
+ * is mapped; only those for which a resident page exists with the
+ * corresponding offset from m_start are mapped.
+ */
+void
+pmap_enter_object(pmap_t pmap, vm_offset_t start, vm_offset_t end,
+    vm_page_t m_start, vm_prot_t prot)
+{
+	vm_offset_t va;
+	vm_page_t m;
+	vm_pindex_t diff, psize;
+
+	VM_OBJECT_ASSERT_LOCKED(m_start->object);
+
+	psize = atop(end - start);
+	m = m_start;
+	prot &= VM_PROT_READ | VM_PROT_EXECUTE;
+	rw_wlock(&pvh_global_lock);
+	PMAP_LOCK(pmap);
+	while (m != NULL && (diff = m->pindex - m_start->pindex) < psize) {
+		va = start + ptoa(diff);
+		if ((va & L1_S_OFFSET) == 0 && L2_NEXT_BUCKET(va) <= end &&
+		    m->psind == 1 && sp_enabled &&
+		    pmap_enter_section(pmap, va, m, prot))
+			m = &m[L1_S_SIZE / PAGE_SIZE - 1];
+		else
+			pmap_enter_locked(pmap, va, m, prot,
+			    PMAP_ENTER_NOSLEEP);
+		m = TAILQ_NEXT(m, listq);
+	}
+	PMAP_UNLOCK(pmap);
+	rw_wunlock(&pvh_global_lock);
+}
+
+/*
+ * this code makes some *MAJOR* assumptions:
+ * 1. Current pmap & pmap exists.
+ * 2. Not wired.
+ * 3. Read access.
+ * 4. No page table pages.
+ * but is *MUCH* faster than pmap_enter...
+ */
+
+void
+pmap_enter_quick(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot)
+{
+
+	prot &= VM_PROT_READ | VM_PROT_EXECUTE;
+	rw_wlock(&pvh_global_lock);
+	PMAP_LOCK(pmap);
+	pmap_enter_locked(pmap, va, m, prot, PMAP_ENTER_NOSLEEP);
+	PMAP_UNLOCK(pmap);
+	rw_wunlock(&pvh_global_lock);
+}
+
+/*
+ *	Clear the wired attribute from the mappings for the specified range of
+ *	addresses in the given pmap.  Every valid mapping within that range
+ *	must have the wired attribute set.  In contrast, invalid mappings
+ *	cannot have the wired attribute set, so they are ignored.
+ *
+ *	XXX Wired mappings of unmanaged pages cannot be counted by this pmap
+ *	implementation.
+ */
+void
+pmap_unwire(pmap_t pmap, vm_offset_t sva, vm_offset_t eva)
+{
+	struct l2_bucket *l2b;
+	struct md_page *pvh;
+	pd_entry_t l1pd;
+	pt_entry_t *ptep, pte;
+	pv_entry_t pv;
+	vm_offset_t next_bucket;
+	vm_paddr_t pa;
+	vm_page_t m;
+ 
+	rw_wlock(&pvh_global_lock);
+	PMAP_LOCK(pmap);
+	while (sva < eva) {
+		next_bucket = L2_NEXT_BUCKET(sva);
+		l1pd = pmap->pm_l1->l1_kva[L1_IDX(sva)];
+		if ((l1pd & L1_TYPE_MASK) == L1_S_PROTO) {
+			pa = l1pd & L1_S_FRAME;
+			m = PHYS_TO_VM_PAGE(pa);
+			KASSERT(m != NULL && (m->oflags & VPO_UNMANAGED) == 0,
+			    ("pmap_unwire: unmanaged 1mpage %p", m));
+			pvh = pa_to_pvh(pa);
+			pv = pmap_find_pv(pvh, pmap, trunc_1mpage(sva));
+			if ((pv->pv_flags & PVF_WIRED) == 0)
+				panic("pmap_unwire: pv %p isn't wired", pv);
+
+			/*
+			 * Are we unwiring the entire large page? If not,
+			 * demote the mapping and fall through.
+			 */
+			if (sva + L1_S_SIZE == next_bucket &&
+			    eva >= next_bucket) {
+				pv->pv_flags &= ~PVF_WIRED;
+				pmap->pm_stats.wired_count -= L2_PTE_NUM_TOTAL;
+				sva = next_bucket;
+				continue;
+			} else if (!pmap_demote_section(pmap, sva))
+				panic("pmap_unwire: demotion failed");
+		}
+		if (next_bucket > eva)
+			next_bucket = eva;
+		l2b = pmap_get_l2_bucket(pmap, sva);
+		if (l2b == NULL) {
+			sva = next_bucket;
+			continue;
+		}
+		for (ptep = &l2b->l2b_kva[l2pte_index(sva)]; sva < next_bucket;
+		    sva += PAGE_SIZE, ptep++) {
+			if ((pte = *ptep) == 0 ||
+			    (m = PHYS_TO_VM_PAGE(l2pte_pa(pte))) == NULL ||
+			    (m->oflags & VPO_UNMANAGED) != 0)
+				continue;
+			pv = pmap_find_pv(&m->md, pmap, sva);
+			if ((pv->pv_flags & PVF_WIRED) == 0)
+				panic("pmap_unwire: pv %p isn't wired", pv);
+			pv->pv_flags &= ~PVF_WIRED;
+			pmap->pm_stats.wired_count--;
+		}
+	}
+	rw_wunlock(&pvh_global_lock);
+ 	PMAP_UNLOCK(pmap);
+}
+
+
+/*
+ *	Copy the range specified by src_addr/len
+ *	from the source map to the range dst_addr/len
+ *	in the destination map.
+ *
+ *	This routine is only advisory and need not do anything.
+ */
+void
+pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vm_offset_t dst_addr,
+    vm_size_t len, vm_offset_t src_addr)
+{
+}
+
+
+/*
+ *	Routine:	pmap_extract
+ *	Function:
+ *		Extract the physical page address associated
+ *		with the given map/virtual_address pair.
+ */
+vm_paddr_t
+pmap_extract(pmap_t pmap, vm_offset_t va)
+{
+	vm_paddr_t pa;
+
+	if (kernel_vm_end != 0)
+		PMAP_LOCK(pmap);
+	pa = pmap_extract_locked(pmap, va);
+	if (kernel_vm_end != 0)
+		PMAP_UNLOCK(pmap);
+	return (pa);
+}
+
+static vm_paddr_t
+pmap_extract_locked(pmap_t pmap, vm_offset_t va)
+{
+	struct l2_dtable *l2;
+	pd_entry_t l1pd;
+	pt_entry_t *ptep, pte;
+	vm_paddr_t pa;
+	u_int l1idx;
+
+	if (kernel_vm_end != 0 && pmap != kernel_pmap)
+		PMAP_ASSERT_LOCKED(pmap);
+	l1idx = L1_IDX(va);
+	l1pd = pmap->pm_l1->l1_kva[l1idx];
+	if (l1pte_section_p(l1pd)) {
+		/* XXX: what to do about the bits > 32 ? */
+		if (l1pd & L1_S_SUPERSEC)
+			pa = (l1pd & L1_SUP_FRAME) | (va & L1_SUP_OFFSET);
+		else
+			pa = (l1pd & L1_S_FRAME) | (va & L1_S_OFFSET);
+	} else {
+		/*
+		 * Note that we can't rely on the validity of the L1
+		 * descriptor as an indication that a mapping exists.
+		 * We have to look it up in the L2 dtable.
+		 */
+		l2 = pmap->pm_l2[L2_IDX(l1idx)];
+		if (l2 == NULL ||
+		    (ptep = l2->l2_bucket[L2_BUCKET(l1idx)].l2b_kva) == NULL)
+			return (0);
+		pte = ptep[l2pte_index(va)];
+		if (pte == 0)
+			return (0);
+		switch (pte & L2_TYPE_MASK) {
+		case L2_TYPE_L:
+			pa = (pte & L2_L_FRAME) | (va & L2_L_OFFSET);
+			break;
+		default:
+			pa = (pte & L2_S_FRAME) | (va & L2_S_OFFSET);
+			break;
+		}
+	}
+	return (pa);
+}
+
+/*
+ * Atomically extract and hold the physical page with the given
+ * pmap and virtual address pair if that mapping permits the given
+ * protection.
+ *
+ */
+vm_page_t
+pmap_extract_and_hold(pmap_t pmap, vm_offset_t va, vm_prot_t prot)
+{
+	struct l2_dtable *l2;
+	pd_entry_t l1pd;
+	pt_entry_t *ptep, pte;
+	vm_paddr_t pa, paddr;
+	vm_page_t m = NULL;
+	u_int l1idx;
+	l1idx = L1_IDX(va);
+	paddr = 0;
+
+	PMAP_LOCK(pmap);
+retry:
+	l1pd = pmap->pm_l1->l1_kva[l1idx];
+	if (l1pte_section_p(l1pd)) {
+		/* XXX: what to do about the bits > 32 ? */
+		if (l1pd & L1_S_SUPERSEC)
+			pa = (l1pd & L1_SUP_FRAME) | (va & L1_SUP_OFFSET);
+		else
+			pa = (l1pd & L1_S_FRAME) | (va & L1_S_OFFSET);
+		if (vm_page_pa_tryrelock(pmap, pa & PG_FRAME, &paddr))
+			goto retry;
+		if (L1_S_WRITABLE(l1pd) || (prot & VM_PROT_WRITE) == 0) {
+			m = PHYS_TO_VM_PAGE(pa);
+			vm_page_hold(m);
+		}
+	} else {
+		/*
+		 * Note that we can't rely on the validity of the L1
+		 * descriptor as an indication that a mapping exists.
+		 * We have to look it up in the L2 dtable.
+		 */
+		l2 = pmap->pm_l2[L2_IDX(l1idx)];
+
+		if (l2 == NULL ||
+		    (ptep = l2->l2_bucket[L2_BUCKET(l1idx)].l2b_kva) == NULL) {
+			PMAP_UNLOCK(pmap);
+			return (NULL);
+		}
+
+		ptep = &ptep[l2pte_index(va)];
+		pte = *ptep;
+
+		if (pte == 0) {
+			PMAP_UNLOCK(pmap);
+			return (NULL);
+		} else if ((prot & VM_PROT_WRITE) && (pte & L2_APX)) {
+			PMAP_UNLOCK(pmap);
+			return (NULL);
+		} else {
+			switch (pte & L2_TYPE_MASK) {
+			case L2_TYPE_L:
+				panic("extract and hold section mapping");
+				break;
+			default:
+				pa = (pte & L2_S_FRAME) | (va & L2_S_OFFSET);
+				break;
+			}
+			if (vm_page_pa_tryrelock(pmap, pa & PG_FRAME, &paddr))
+				goto retry;
+			m = PHYS_TO_VM_PAGE(pa);
+			vm_page_hold(m);
+		}
+
+	}
+
+	PMAP_UNLOCK(pmap);
+	PA_UNLOCK_COND(paddr);
+	return (m);
+}
+
+/*
+ * Initialize a preallocated and zeroed pmap structure,
+ * such as one in a vmspace structure.
+ */
+
+int
+pmap_pinit(pmap_t pmap)
+{
+	PDEBUG(1, printf("pmap_pinit: pmap = %08x\n", (uint32_t) pmap));
+
+	pmap_alloc_l1(pmap);
+	bzero(pmap->pm_l2, sizeof(pmap->pm_l2));
+
+	CPU_ZERO(&pmap->pm_active);
+
+	TAILQ_INIT(&pmap->pm_pvchunk);
+	bzero(&pmap->pm_stats, sizeof pmap->pm_stats);
+	pmap->pm_stats.resident_count = 1;
+	if (vector_page < KERNBASE) {
+		pmap_enter(pmap, vector_page,
+		    PHYS_TO_VM_PAGE(systempage.pv_pa), VM_PROT_READ,
+		    PMAP_ENTER_WIRED, 0);
+	}
+	return (1);
+}
+
+
+/***************************************************
+ * Superpage management routines.
+ ***************************************************/
+
+static PMAP_INLINE struct pv_entry *
+pmap_pvh_remove(struct md_page *pvh, pmap_t pmap, vm_offset_t va)
+{
+	pv_entry_t pv;
+
+	rw_assert(&pvh_global_lock, RA_WLOCKED);
+
+	pv = pmap_find_pv(pvh, pmap, va);
+	if (pv != NULL)
+		TAILQ_REMOVE(&pvh->pv_list, pv, pv_list);
+
+	return (pv);
+}
+
+static void
+pmap_pvh_free(struct md_page *pvh, pmap_t pmap, vm_offset_t va)
+{
+	pv_entry_t pv;
+
+	pv = pmap_pvh_remove(pvh, pmap, va);
+	KASSERT(pv != NULL, ("pmap_pvh_free: pv not found"));
+	pmap_free_pv_entry(pmap, pv);
+}
+
+static boolean_t
+pmap_pv_insert_section(pmap_t pmap, vm_offset_t va, vm_paddr_t pa)
+{
+	struct md_page *pvh;
+	pv_entry_t pv;
+
+	rw_assert(&pvh_global_lock, RA_WLOCKED);
+	if (pv_entry_count < pv_entry_high_water && 
+	    (pv = pmap_get_pv_entry(pmap, TRUE)) != NULL) {
+		pv->pv_va = va;
+		pvh = pa_to_pvh(pa);
+		TAILQ_INSERT_TAIL(&pvh->pv_list, pv, pv_list);
+		return (TRUE);
+	} else
+		return (FALSE);
+}
+
+/*
+ * Create the pv entries for each of the pages within a superpage.
+ */
+static void
+pmap_pv_demote_section(pmap_t pmap, vm_offset_t va, vm_paddr_t pa)
+{
+	struct md_page *pvh;
+	pv_entry_t pve, pv;
+	vm_offset_t va_last;
+	vm_page_t m;
+
+	rw_assert(&pvh_global_lock, RA_WLOCKED);
+	KASSERT((pa & L1_S_OFFSET) == 0,
+	    ("pmap_pv_demote_section: pa is not 1mpage aligned"));
+
+	/*
+	 * Transfer the 1mpage's pv entry for this mapping to the first
+	 * page's pv list.
+	 */
+	pvh = pa_to_pvh(pa);
+	va = trunc_1mpage(va);
+	pv = pmap_pvh_remove(pvh, pmap, va);
+	KASSERT(pv != NULL, ("pmap_pv_demote_section: pv not found"));
+	m = PHYS_TO_VM_PAGE(pa);
+	TAILQ_INSERT_HEAD(&m->md.pv_list, pv, pv_list);
+	/* Instantiate the remaining pv entries. */
+	va_last = L2_NEXT_BUCKET(va) - PAGE_SIZE;
+	do {
+		m++;
+		KASSERT((m->oflags & VPO_UNMANAGED) == 0,
+		    ("pmap_pv_demote_section: page %p is not managed", m));
+		va += PAGE_SIZE;
+		pve = pmap_get_pv_entry(pmap, FALSE);
+		pmap_enter_pv(m, pve, pmap, va, pv->pv_flags);
+	} while (va < va_last);
+}
+
+static void
+pmap_pv_promote_section(pmap_t pmap, vm_offset_t va, vm_paddr_t pa)
+{
+	struct md_page *pvh;
+	pv_entry_t pv;
+	vm_offset_t va_last;
+	vm_page_t m;
+
+	rw_assert(&pvh_global_lock, RA_WLOCKED);
+	KASSERT((pa & L1_S_OFFSET) == 0,
+	    ("pmap_pv_promote_section: pa is not 1mpage aligned"));
+
+	/*
+	 * Transfer the first page's pv entry for this mapping to the
+	 * 1mpage's pv list.  Aside from avoiding the cost of a call
+	 * to get_pv_entry(), a transfer avoids the possibility that
+	 * get_pv_entry() calls pmap_pv_reclaim() and that pmap_pv_reclaim()
+	 * removes one of the mappings that is being promoted.
+	 */
+	m = PHYS_TO_VM_PAGE(pa);
+	va = trunc_1mpage(va);
+	pv = pmap_pvh_remove(&m->md, pmap, va);
+	KASSERT(pv != NULL, ("pmap_pv_promote_section: pv not found"));
+	pvh = pa_to_pvh(pa);
+	TAILQ_INSERT_TAIL(&pvh->pv_list, pv, pv_list);
+	/* Free the remaining pv entries in the newly mapped section pages */
+	va_last = L2_NEXT_BUCKET(va) - PAGE_SIZE;
+	do {
+		m++;
+		va += PAGE_SIZE;
+		/*
+		 * Don't care the flags, first pv contains sufficient
+		 * information for all of the pages so nothing is really lost.
+		 */
+		pmap_pvh_free(&m->md, pmap, va);
+	} while (va < va_last);
+}
+
+/*
+ * Tries to create a 1MB page mapping.  Returns TRUE if successful and
+ * FALSE otherwise.  Fails if (1) page is unmanageg, kernel pmap or vectors
+ * page, (2) a mapping already exists at the specified virtual address, or
+ * (3) a pv entry cannot be allocated without reclaiming another pv entry. 
+ */
+static boolean_t
+pmap_enter_section(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot)
+{
+	pd_entry_t *pl1pd;
+	vm_offset_t pa;
+	struct l2_bucket *l2b;
+
+	rw_assert(&pvh_global_lock, RA_WLOCKED);
+	PMAP_ASSERT_LOCKED(pmap);
+
+	/* Skip kernel, vectors page and unmanaged mappings */
+	if ((pmap == pmap_kernel()) || (L1_IDX(va) == L1_IDX(vector_page)) ||
+	    ((m->oflags & VPO_UNMANAGED) != 0)) {
+		CTR2(KTR_PMAP, "pmap_enter_section: failure for va %#lx"
+		    " in pmap %p", va, pmap);
+		return (FALSE);
+	}
+	/*
+	 * Check whether this is a valid section superpage entry or
+	 * there is a l2_bucket associated with that L1 page directory.
+	 */
+	va = trunc_1mpage(va);
+	pl1pd = &pmap->pm_l1->l1_kva[L1_IDX(va)];
+	l2b = pmap_get_l2_bucket(pmap, va);
+	if ((*pl1pd & L1_S_PROTO) || (l2b != NULL)) {
+		CTR2(KTR_PMAP, "pmap_enter_section: failure for va %#lx"
+		    " in pmap %p", va, pmap);
+		return (FALSE);
+	}
+	pa = VM_PAGE_TO_PHYS(m); 
+	/*
+	 * Abort this mapping if its PV entry could not be created.
+	 */
+	if (!pmap_pv_insert_section(pmap, va, VM_PAGE_TO_PHYS(m))) {
+		CTR2(KTR_PMAP, "pmap_enter_section: failure for va %#lx"
+		    " in pmap %p", va, pmap);
+		return (FALSE);
+	}
+	/*
+	 * Increment counters.
+	 */
+	pmap->pm_stats.resident_count += L2_PTE_NUM_TOTAL;
+	/*
+	 * Despite permissions, mark the superpage read-only.
+	 */
+	prot &= ~VM_PROT_WRITE;
+	/*
+	 * Map the superpage.
+	 */
+	pmap_map_section(pmap, va, pa, prot, FALSE);
+
+	pmap_section_mappings++;
+	CTR2(KTR_PMAP, "pmap_enter_section: success for va %#lx"
+	    " in pmap %p", va, pmap);
+	return (TRUE);
+}
+
+/*
+ * pmap_remove_section: do the things to unmap a superpage in a process
+ */
+static void
+pmap_remove_section(pmap_t pmap, vm_offset_t sva)
+{
+	struct md_page *pvh;
+	struct l2_bucket *l2b;
+	pd_entry_t *pl1pd, l1pd;
+	vm_offset_t eva, va;
+	vm_page_t m;
+
+	PMAP_ASSERT_LOCKED(pmap);
+	if ((pmap == pmap_kernel()) || (L1_IDX(sva) == L1_IDX(vector_page)))
+		return;
+
+	KASSERT((sva & L1_S_OFFSET) == 0,
+	    ("pmap_remove_section: sva is not 1mpage aligned"));
+
+	pl1pd = &pmap->pm_l1->l1_kva[L1_IDX(sva)];
+	l1pd = *pl1pd;
+
+	m = PHYS_TO_VM_PAGE(l1pd & L1_S_FRAME);
+	KASSERT((m != NULL && ((m->oflags & VPO_UNMANAGED) == 0)),
+	    ("pmap_remove_section: no corresponding vm_page or "
+	    "page unmanaged"));
+
+	pmap->pm_stats.resident_count -= L2_PTE_NUM_TOTAL;
+	pvh = pa_to_pvh(l1pd & L1_S_FRAME);
+	pmap_pvh_free(pvh, pmap, sva);
+	eva = L2_NEXT_BUCKET(sva);
+	for (va = sva, m = PHYS_TO_VM_PAGE(l1pd & L1_S_FRAME);
+	    va < eva; va += PAGE_SIZE, m++) {
+		/*
+		 * Mark base pages referenced but skip marking them dirty.
+		 * If the superpage is writeable, hence all base pages were
+		 * already marked as dirty in pmap_fault_fixup() before
+		 * promotion. Reference bit however, might not have been set
+		 * for each base page when the superpage was created at once,
+		 * not as a result of promotion.
+		 */
+		if (L1_S_REFERENCED(l1pd))
+			vm_page_aflag_set(m, PGA_REFERENCED);
+		if (TAILQ_EMPTY(&m->md.pv_list) &&
+		    TAILQ_EMPTY(&pvh->pv_list))
+			vm_page_aflag_clear(m, PGA_WRITEABLE);
+	}
+	
+	l2b = pmap_get_l2_bucket(pmap, sva);
+	if (l2b != NULL) {
+		KASSERT(l2b->l2b_occupancy == L2_PTE_NUM_TOTAL,
+		    ("pmap_remove_section: l2_bucket occupancy error"));
+		pmap_free_l2_bucket(pmap, l2b, L2_PTE_NUM_TOTAL);
+	}
+	/* Now invalidate L1 slot */
+	*pl1pd = 0;
+	PTE_SYNC(pl1pd);
+	if (L1_S_EXECUTABLE(l1pd))
+		cpu_tlb_flushID_SE(sva);
+	else
+		cpu_tlb_flushD_SE(sva);
+	cpu_cpwait();
+}
+
+/*
+ * Tries to promote the 256, contiguous 4KB page mappings that are
+ * within a single l2_bucket to a single 1MB section mapping.
+ * For promotion to occur, two conditions must be met: (1) the 4KB page
+ * mappings must map aligned, contiguous physical memory and (2) the 4KB page
+ * mappings must have identical characteristics.
+ */
+static void
+pmap_promote_section(pmap_t pmap, vm_offset_t va)
+{
+	pt_entry_t *firstptep, firstpte, oldpte, pa, *pte;
+	vm_page_t m, oldm;
+	vm_offset_t first_va, old_va;
+	struct l2_bucket *l2b = NULL;
+	vm_prot_t prot;
+	struct pv_entry *pve, *first_pve;
+
+	PMAP_ASSERT_LOCKED(pmap);
+
+	prot = VM_PROT_ALL;
+	/*
+	 * Skip promoting kernel pages. This is justified by following:
+	 * 1. Kernel is already mapped using section mappings in each pmap
+	 * 2. Managed mappings within the kernel are not to be promoted anyway
+	 */
+	if (pmap == pmap_kernel()) {
+		pmap_section_p_failures++;
+		CTR2(KTR_PMAP, "pmap_promote_section: failure for va %#x"
+		    " in pmap %p", va, pmap);
+		return;
+	}
+	/* Do not attemp to promote vectors pages */
+	if (L1_IDX(va) == L1_IDX(vector_page)) {
+		pmap_section_p_failures++;
+		CTR2(KTR_PMAP, "pmap_promote_section: failure for va %#x"
+		    " in pmap %p", va, pmap);
+		return;
+	}
+	/*
+	 * Examine the first PTE in the specified l2_bucket. Abort if this PTE
+	 * is either invalid, unused, or does not map the first 4KB physical
+	 * page within 1MB page.
+	 */
+	first_va = trunc_1mpage(va);
+	l2b = pmap_get_l2_bucket(pmap, first_va);
+	KASSERT(l2b != NULL, ("pmap_promote_section: trying to promote "
+	    "not existing l2 bucket"));
+	firstptep = &l2b->l2b_kva[0];
+
+	firstpte = *firstptep;
+	if ((l2pte_pa(firstpte) & L1_S_OFFSET) != 0) {
+		pmap_section_p_failures++;
+		CTR2(KTR_PMAP, "pmap_promote_section: failure for va %#x"
+		    " in pmap %p", va, pmap);
+		return;
+	}
+
+	if ((firstpte & (L2_S_PROTO | L2_S_REF)) != (L2_S_PROTO | L2_S_REF)) {
+		pmap_section_p_failures++;
+		CTR2(KTR_PMAP, "pmap_promote_section: failure for va %#x"
+		    " in pmap %p", va, pmap);
+		return;
+	}
+	/*
+	 * ARM uses pv_entry to mark particular mapping WIRED so don't promote
+	 * unmanaged pages since it is impossible to determine, whether the
+	 * page is wired or not if there is no corresponding pv_entry.
+	 */
+	m = PHYS_TO_VM_PAGE(l2pte_pa(firstpte));
+	if (m && ((m->oflags & VPO_UNMANAGED) != 0)) {
+		pmap_section_p_failures++;
+		CTR2(KTR_PMAP, "pmap_promote_section: failure for va %#x"
+		    " in pmap %p", va, pmap);
+		return;
+	}
+	first_pve = pmap_find_pv(&m->md, pmap, first_va);
+	/*
+	 * PTE is modified only on write due to modified bit
+	 * emulation. If the entry is referenced and writable
+	 * then it is modified and we don't clear write enable.
+	 * Otherwise, writing is disabled in PTE anyway and
+	 * we just configure protections for the section mapping
+	 * that is going to be created.
+	 */
+	if ((first_pve->pv_flags & PVF_WRITE) != 0) {
+		if (!L2_S_WRITABLE(firstpte)) {
+			first_pve->pv_flags &= ~PVF_WRITE;
+			prot &= ~VM_PROT_WRITE;
+		}
+	} else
+		prot &= ~VM_PROT_WRITE;
+
+	if (!L2_S_EXECUTABLE(firstpte))
+		prot &= ~VM_PROT_EXECUTE;
+
+	/* 
+	 * Examine each of the other PTEs in the specified l2_bucket. 
+	 * Abort if this PTE maps an unexpected 4KB physical page or
+	 * does not have identical characteristics to the first PTE.
+	 */
+	pa = l2pte_pa(firstpte) + ((L2_PTE_NUM_TOTAL - 1) * PAGE_SIZE);
+	old_va = L2_NEXT_BUCKET(first_va) - PAGE_SIZE;
+
+	for (pte = (firstptep + L2_PTE_NUM_TOTAL - 1); pte > firstptep; pte--) {
+		oldpte = *pte;
+		if (l2pte_pa(oldpte) != pa) {
+			pmap_section_p_failures++;
+			CTR2(KTR_PMAP, "pmap_promote_section: failure for "
+			    "va %#x in pmap %p", va, pmap);
+			return;
+		}
+		if ((oldpte & L2_S_PROMOTE) != (firstpte & L2_S_PROMOTE)) {
+			pmap_section_p_failures++;
+			CTR2(KTR_PMAP, "pmap_promote_section: failure for "
+			    "va %#x in pmap %p", va, pmap);
+			return;
+		}
+		oldm = PHYS_TO_VM_PAGE(l2pte_pa(oldpte));
+		if (oldm && ((oldm->oflags & VPO_UNMANAGED) != 0)) {
+			pmap_section_p_failures++;
+			CTR2(KTR_PMAP, "pmap_promote_section: failure for "
+			    "va %#x in pmap %p", va, pmap);
+			return;
+		}
+
+		pve = pmap_find_pv(&oldm->md, pmap, old_va);
+		if (pve == NULL) {
+			pmap_section_p_failures++;
+			CTR2(KTR_PMAP, "pmap_promote_section: failure for "
+			    "va %#x old_va  %x - no pve", va, old_va);
+			return;
+		}
+
+		if (!L2_S_WRITABLE(oldpte) && (pve->pv_flags & PVF_WRITE))
+			pve->pv_flags &= ~PVF_WRITE;
+		if (pve->pv_flags != first_pve->pv_flags) {
+			pmap_section_p_failures++;
+			CTR2(KTR_PMAP, "pmap_promote_section: failure for "
+			    "va %#x in pmap %p", va, pmap);
+			return;
+		}
+
+		old_va -= PAGE_SIZE;
+		pa -= PAGE_SIZE;
+	}
+	/*
+	 * Promote the pv entries.
+	 */
+	pmap_pv_promote_section(pmap, first_va, l2pte_pa(firstpte));
+	/*
+	 * Map the superpage.
+	 */
+	pmap_map_section(pmap, first_va, l2pte_pa(firstpte), prot, TRUE);
+	/*
+	 * Invalidate all possible TLB mappings for small
+	 * pages within the newly created superpage.
+	 * Rely on the first PTE's attributes since they
+	 * have to be consistent across all of the base pages
+	 * within the superpage. If page is not executable it
+	 * is at least referenced.
+	 * The fastest way to do that is to invalidate whole
+	 * TLB at once instead of executing 256 CP15 TLB
+	 * invalidations by single entry. TLBs usually maintain
+	 * several dozen entries so loss of unrelated entries is
+	 * still a less agresive approach.
+	 */
+	if (L2_S_EXECUTABLE(firstpte))
+		cpu_tlb_flushID();
+	else
+		cpu_tlb_flushD();
+	cpu_cpwait();
+
+	pmap_section_promotions++;
+	CTR2(KTR_PMAP, "pmap_promote_section: success for va %#x"
+	    " in pmap %p", first_va, pmap);
+}
+
+/*
+ * Fills a l2_bucket with mappings to consecutive physical pages.
+ */
+static void
+pmap_fill_l2b(struct l2_bucket *l2b, pt_entry_t newpte)
+{
+	pt_entry_t *ptep;
+	int i;
+
+	for (i = 0; i < L2_PTE_NUM_TOTAL; i++) {
+		ptep = &l2b->l2b_kva[i];
+		*ptep = newpte;
+		PTE_SYNC(ptep);
+
+		newpte += PAGE_SIZE;
+	}
+
+	l2b->l2b_occupancy = L2_PTE_NUM_TOTAL;
+}
+
+/*
+ * Tries to demote a 1MB section mapping. If demotion fails, the
+ * 1MB section mapping is invalidated.
+ */
+static boolean_t
+pmap_demote_section(pmap_t pmap, vm_offset_t va)
+{
+	struct l2_bucket *l2b;
+	struct pv_entry *l1pdpve;
+	struct md_page *pvh;
+	pd_entry_t *pl1pd, l1pd, newl1pd;
+	pt_entry_t *firstptep, newpte;
+	vm_offset_t pa;
+	vm_page_t m;
+
+	PMAP_ASSERT_LOCKED(pmap);
+	/*
+	 * According to assumptions described in pmap_promote_section,
+	 * kernel is and always should be mapped using 1MB section mappings.
+	 * What more, managed kernel pages were not to be promoted. 
+	 */
+	KASSERT(pmap != pmap_kernel() && L1_IDX(va) != L1_IDX(vector_page),
+	    ("pmap_demote_section: forbidden section mapping"));
+
+	va = trunc_1mpage(va);
+	pl1pd = &pmap->pm_l1->l1_kva[L1_IDX(va)];
+	l1pd = *pl1pd;
+	KASSERT((l1pd & L1_TYPE_MASK) == L1_S_PROTO,
+	    ("pmap_demote_section: not section or invalid section"));
+	
+	pa = l1pd & L1_S_FRAME;
+	m = PHYS_TO_VM_PAGE(pa);
+	KASSERT((m != NULL && (m->oflags & VPO_UNMANAGED) == 0),
+	    ("pmap_demote_section: no vm_page for selected superpage or"
+	     "unmanaged"));
+
+	pvh = pa_to_pvh(pa);
+	l1pdpve = pmap_find_pv(pvh, pmap, va);
+	KASSERT(l1pdpve != NULL, ("pmap_demote_section: no pv entry for "
+	    "managed page"));
+
+	l2b = pmap_get_l2_bucket(pmap, va);
+	if (l2b == NULL) {
+		KASSERT((l1pdpve->pv_flags & PVF_WIRED) == 0,
+		    ("pmap_demote_section: No l2_bucket for wired mapping"));
+		/*
+		 * Invalidate the 1MB section mapping and return
+		 * "failure" if the mapping was never accessed or the
+		 * allocation of the new l2_bucket fails.
+		 */
+		if (!L1_S_REFERENCED(l1pd) ||
+		    (l2b = pmap_alloc_l2_bucket(pmap, va)) == NULL) {
+			/* Unmap and invalidate superpage. */
+			pmap_remove_section(pmap, trunc_1mpage(va));
+			CTR2(KTR_PMAP, "pmap_demote_section: failure for "
+			    "va %#x in pmap %p", va, pmap);
+			return (FALSE);
+		}
+	}
+
+	/*
+	 * Now we should have corresponding l2_bucket available.
+	 * Let's process it to recreate 256 PTEs for each base page
+	 * within superpage.
+	 */
+	newpte = pa | L1_S_DEMOTE(l1pd);
+	if (m->md.pv_memattr != VM_MEMATTR_UNCACHEABLE)
+		newpte |= pte_l2_s_cache_mode;
+
+	/*
+	 * If the l2_bucket is new, initialize it.
+	 */
+	if (l2b->l2b_occupancy == 0)
+		pmap_fill_l2b(l2b, newpte);
+	else {
+		firstptep = &l2b->l2b_kva[0];
+		KASSERT(l2pte_pa(*firstptep) == (pa),
+		    ("pmap_demote_section: firstpte and newpte map different "
+		     "physical addresses"));
+		/*
+		 * If the mapping has changed attributes, update the page table
+		 * entries.
+		 */ 
+		if ((*firstptep & L2_S_PROMOTE) != (L1_S_DEMOTE(l1pd)))
+			pmap_fill_l2b(l2b, newpte);
+	}
+	/* Demote PV entry */
+	pmap_pv_demote_section(pmap, va, pa);
+
+	/* Now fix-up L1 */
+	newl1pd = l2b->l2b_phys | L1_C_DOM(pmap->pm_domain) | L1_C_PROTO;
+	*pl1pd = newl1pd;
+	PTE_SYNC(pl1pd);
+	/* Invalidate old TLB mapping */
+	if (L1_S_EXECUTABLE(l1pd))
+		cpu_tlb_flushID_SE(va);
+	else if (L1_S_REFERENCED(l1pd))
+		cpu_tlb_flushD_SE(va);
+	cpu_cpwait();
+
+	pmap_section_demotions++;
+	CTR2(KTR_PMAP, "pmap_demote_section: success for va %#x"
+	    " in pmap %p", va, pmap);
+	return (TRUE);
+}
+
+/***************************************************
+ * page management routines.
+ ***************************************************/
+
+/*
+ * We are in a serious low memory condition.  Resort to
+ * drastic measures to free some pages so we can allocate
+ * another pv entry chunk.
+ */
+static vm_page_t
+pmap_pv_reclaim(pmap_t locked_pmap)
+{
+	struct pch newtail;
+	struct pv_chunk *pc;
+	struct l2_bucket *l2b = NULL;
+	pmap_t pmap;
+	pd_entry_t *pl1pd;
+	pt_entry_t *ptep;
+	pv_entry_t pv;
+	vm_offset_t va;
+	vm_page_t free, m, m_pc;
+	uint32_t inuse;
+	int bit, field, freed, idx;
+
+	PMAP_ASSERT_LOCKED(locked_pmap);
+	pmap = NULL;
+	free = m_pc = NULL;
+	TAILQ_INIT(&newtail);
+	while ((pc = TAILQ_FIRST(&pv_chunks)) != NULL && (pv_vafree == 0 ||
+	    free == NULL)) {
+		TAILQ_REMOVE(&pv_chunks, pc, pc_lru);
+		if (pmap != pc->pc_pmap) {
+			if (pmap != NULL) {
+				cpu_tlb_flushID();
+				cpu_cpwait();
+				if (pmap != locked_pmap)
+					PMAP_UNLOCK(pmap);
+			}
+			pmap = pc->pc_pmap;
+			/* Avoid deadlock and lock recursion. */
+			if (pmap > locked_pmap)
+				PMAP_LOCK(pmap);
+			else if (pmap != locked_pmap && !PMAP_TRYLOCK(pmap)) {
+				pmap = NULL;
+				TAILQ_INSERT_TAIL(&newtail, pc, pc_lru);
+				continue;
+			}
+		}
+
+		/*
+		 * Destroy every non-wired, 4 KB page mapping in the chunk.
+		 */
+		freed = 0;
+		for (field = 0; field < _NPCM; field++) {
+			for (inuse = ~pc->pc_map[field] & pc_freemask[field];
+			    inuse != 0; inuse &= ~(1UL << bit)) {
+				bit = ffs(inuse) - 1;
+				idx = field * sizeof(inuse) * NBBY + bit;
+				pv = &pc->pc_pventry[idx];
+				va = pv->pv_va;
+
+				pl1pd = &pmap->pm_l1->l1_kva[L1_IDX(va)];
+				if ((*pl1pd & L1_TYPE_MASK) == L1_S_PROTO)
+					continue;
+				if (pv->pv_flags & PVF_WIRED)
+					continue;
+
+				l2b = pmap_get_l2_bucket(pmap, va);
+				KASSERT(l2b != NULL, ("No l2 bucket"));
+				ptep = &l2b->l2b_kva[l2pte_index(va)];
+				m = PHYS_TO_VM_PAGE(l2pte_pa(*ptep));
+				KASSERT((vm_offset_t)m >= KERNBASE,
+				    ("Trying to access non-existent page "
+				     "va %x pte %x", va, *ptep));
+				*ptep = 0;
+				PTE_SYNC(ptep);
+				TAILQ_REMOVE(&m->md.pv_list, pv, pv_list);
+				if (TAILQ_EMPTY(&m->md.pv_list))
+					vm_page_aflag_clear(m, PGA_WRITEABLE);
+				pc->pc_map[field] |= 1UL << bit;
+				freed++;
+			}
+		}
+
+		if (freed == 0) {
+			TAILQ_INSERT_TAIL(&newtail, pc, pc_lru);
+			continue;
+		}
+		/* Every freed mapping is for a 4 KB page. */
+		pmap->pm_stats.resident_count -= freed;
+		PV_STAT(pv_entry_frees += freed);
+		PV_STAT(pv_entry_spare += freed);
+		pv_entry_count -= freed;
+		TAILQ_REMOVE(&pmap->pm_pvchunk, pc, pc_list);
+		for (field = 0; field < _NPCM; field++)
+			if (pc->pc_map[field] != pc_freemask[field]) {
+				TAILQ_INSERT_HEAD(&pmap->pm_pvchunk, pc,
+				    pc_list);
+				TAILQ_INSERT_TAIL(&newtail, pc, pc_lru);
+
+				/*
+				 * One freed pv entry in locked_pmap is
+				 * sufficient.
+				 */
+				if (pmap == locked_pmap)
+					goto out;
+				break;
+			}
+		if (field == _NPCM) {
+			PV_STAT(pv_entry_spare -= _NPCPV);
+			PV_STAT(pc_chunk_count--);
+			PV_STAT(pc_chunk_frees++);
+			/* Entire chunk is free; return it. */
+			m_pc = PHYS_TO_VM_PAGE(pmap_kextract((vm_offset_t)pc));
+			pmap_qremove((vm_offset_t)pc, 1);
+			pmap_ptelist_free(&pv_vafree, (vm_offset_t)pc);
+			break;
+		}
+	}
+out:
+	TAILQ_CONCAT(&pv_chunks, &newtail, pc_lru);
+	if (pmap != NULL) {
+		cpu_tlb_flushID();
+		cpu_cpwait();
+		if (pmap != locked_pmap)
+			PMAP_UNLOCK(pmap);
+	}
+	return (m_pc);
+}
+
+/*
+ * free the pv_entry back to the free list
+ */
+static void
+pmap_free_pv_entry(pmap_t pmap, pv_entry_t pv)
+{
+	struct pv_chunk *pc;
+	int bit, field, idx;
+
+	rw_assert(&pvh_global_lock, RA_WLOCKED);
+	PMAP_ASSERT_LOCKED(pmap);
+	PV_STAT(pv_entry_frees++);
+	PV_STAT(pv_entry_spare++);
+	pv_entry_count--;
+	pc = pv_to_chunk(pv);
+	idx = pv - &pc->pc_pventry[0];
+	field = idx / (sizeof(u_long) * NBBY);
+	bit = idx % (sizeof(u_long) * NBBY);
+	pc->pc_map[field] |= 1ul << bit;
+	for (idx = 0; idx < _NPCM; idx++)
+		if (pc->pc_map[idx] != pc_freemask[idx]) {
+			/*
+			 * 98% of the time, pc is already at the head of the
+			 * list.  If it isn't already, move it to the head.
+			 */
+			if (__predict_false(TAILQ_FIRST(&pmap->pm_pvchunk) !=
+			    pc)) {
+				TAILQ_REMOVE(&pmap->pm_pvchunk, pc, pc_list);
+				TAILQ_INSERT_HEAD(&pmap->pm_pvchunk, pc,
+				    pc_list);
+			}
+			return;
+		}
+	TAILQ_REMOVE(&pmap->pm_pvchunk, pc, pc_list);
+	pmap_free_pv_chunk(pc);
+}
+
+static void
+pmap_free_pv_chunk(struct pv_chunk *pc)
+{
+	vm_page_t m;
+
+	TAILQ_REMOVE(&pv_chunks, pc, pc_lru);
+	PV_STAT(pv_entry_spare -= _NPCPV);
+	PV_STAT(pc_chunk_count--);
+	PV_STAT(pc_chunk_frees++);
+	/* entire chunk is free, return it */
+	m = PHYS_TO_VM_PAGE(pmap_kextract((vm_offset_t)pc));
+	pmap_qremove((vm_offset_t)pc, 1);
+	vm_page_unwire(m, 0);
+	vm_page_free(m);
+	pmap_ptelist_free(&pv_vafree, (vm_offset_t)pc);
+
+}
+
+static pv_entry_t
+pmap_get_pv_entry(pmap_t pmap, boolean_t try)
+{
+	static const struct timeval printinterval = { 60, 0 };
+	static struct timeval lastprint;
+	struct pv_chunk *pc;
+	pv_entry_t pv;
+	vm_page_t m;
+	int bit, field, idx;
+
+	rw_assert(&pvh_global_lock, RA_WLOCKED);
+	PMAP_ASSERT_LOCKED(pmap);
+	PV_STAT(pv_entry_allocs++);
+	pv_entry_count++;
+
+	if (pv_entry_count > pv_entry_high_water)
+		if (ratecheck(&lastprint, &printinterval))
+			printf("%s: Approaching the limit on PV entries.\n",
+			    __func__);
+retry:
+	pc = TAILQ_FIRST(&pmap->pm_pvchunk);
+	if (pc != NULL) {
+		for (field = 0; field < _NPCM; field++) {
+			if (pc->pc_map[field]) {
+				bit = ffs(pc->pc_map[field]) - 1;
+				break;
+			}
+		}
+		if (field < _NPCM) {
+			idx = field * sizeof(pc->pc_map[field]) * NBBY + bit;
+			pv = &pc->pc_pventry[idx];
+			pc->pc_map[field] &= ~(1ul << bit);
+			/* If this was the last item, move it to tail */
+			for (field = 0; field < _NPCM; field++)
+				if (pc->pc_map[field] != 0) {
+					PV_STAT(pv_entry_spare--);
+					return (pv);	/* not full, return */
+				}
+			TAILQ_REMOVE(&pmap->pm_pvchunk, pc, pc_list);
+			TAILQ_INSERT_TAIL(&pmap->pm_pvchunk, pc, pc_list);
+			PV_STAT(pv_entry_spare--);
+			return (pv);
+		}
+	}
+	/*
+	 * Access to the ptelist "pv_vafree" is synchronized by the pvh
+	 * global lock.  If "pv_vafree" is currently non-empty, it will
+	 * remain non-empty until pmap_ptelist_alloc() completes.
+	 */
+	if (pv_vafree == 0 || (m = vm_page_alloc(NULL, 0, VM_ALLOC_NORMAL |
+	    VM_ALLOC_NOOBJ | VM_ALLOC_WIRED)) == NULL) {
+		if (try) {
+			pv_entry_count--;
+			PV_STAT(pc_chunk_tryfail++);
+			return (NULL);
+		}
+		m = pmap_pv_reclaim(pmap);
+		if (m == NULL)
+			goto retry;
+	}
+	PV_STAT(pc_chunk_count++);
+	PV_STAT(pc_chunk_allocs++);
+	pc = (struct pv_chunk *)pmap_ptelist_alloc(&pv_vafree);
+	pmap_qenter((vm_offset_t)pc, &m, 1);
+	pc->pc_pmap = pmap;
+	pc->pc_map[0] = pc_freemask[0] & ~1ul;	/* preallocated bit 0 */
+	for (field = 1; field < _NPCM; field++)
+		pc->pc_map[field] = pc_freemask[field];
+	TAILQ_INSERT_TAIL(&pv_chunks, pc, pc_lru);
+	pv = &pc->pc_pventry[0];
+	TAILQ_INSERT_HEAD(&pmap->pm_pvchunk, pc, pc_list);
+	PV_STAT(pv_entry_spare += _NPCPV - 1);
+	return (pv);
+}
+
+/*
+ *	Remove the given range of addresses from the specified map.
+ *
+ *	It is assumed that the start and end are properly
+ *	rounded to the page size.
+ */
+#define	PMAP_REMOVE_CLEAN_LIST_SIZE	3
+void
+pmap_remove(pmap_t pmap, vm_offset_t sva, vm_offset_t eva)
+{
+	struct l2_bucket *l2b;
+	vm_offset_t next_bucket;
+	pd_entry_t *pl1pd, l1pd;
+	pt_entry_t *ptep;
+	u_int total;
+	u_int mappings, is_exec, is_refd;
+	int flushall = 0;
+
+
+	/*
+	 * we lock in the pmap => pv_head direction
+	 */
+
+	rw_wlock(&pvh_global_lock);
+	PMAP_LOCK(pmap);
+	total = 0;
+	while (sva < eva) {
+		/*
+		 * Check for large page.
+		 */
+		pl1pd = &pmap->pm_l1->l1_kva[L1_IDX(sva)];
+		l1pd = *pl1pd;
+		if ((l1pd & L1_TYPE_MASK) == L1_S_PROTO) {
+			KASSERT((l1pd & L1_S_DOM_MASK) !=
+			    L1_S_DOM(PMAP_DOMAIN_KERNEL), ("pmap_remove: "
+			    "Trying to remove kernel section mapping"));
+			/*
+			 * Are we removing the entire large page?  If not,
+			 * demote the mapping and fall through.
+			 */
+			if (sva + L1_S_SIZE == L2_NEXT_BUCKET(sva) &&
+			    eva >= L2_NEXT_BUCKET(sva)) {
+				pmap_remove_section(pmap, sva);
+				sva = L2_NEXT_BUCKET(sva);
+				continue;
+			} else if (!pmap_demote_section(pmap, sva)) {
+				/* The large page mapping was destroyed. */
+				sva = L2_NEXT_BUCKET(sva);
+				continue;
+			}
+		}
+		/*
+		 * Do one L2 bucket's worth at a time.
+		 */
+		next_bucket = L2_NEXT_BUCKET(sva);
+		if (next_bucket > eva)
+			next_bucket = eva;
+
+		l2b = pmap_get_l2_bucket(pmap, sva);
+		if (l2b == NULL) {
+			sva = next_bucket;
+			continue;
+		}
+
+		ptep = &l2b->l2b_kva[l2pte_index(sva)];
+		mappings = 0;
+
+		while (sva < next_bucket) {
+			struct vm_page *m;
+			pt_entry_t pte;
+			vm_paddr_t pa;
+
+			pte = *ptep;
+
+			if (pte == 0) {
+				/*
+				 * Nothing here, move along
+				 */
+				sva += PAGE_SIZE;
+				ptep++;
+				continue;
+			}
+
+			pmap->pm_stats.resident_count--;
+			pa = l2pte_pa(pte);
+			is_exec = 0;
+			is_refd = 1;
+
+			/*
+			 * Update flags. In a number of circumstances,
+			 * we could cluster a lot of these and do a
+			 * number of sequential pages in one go.
+			 */
+			if ((m = PHYS_TO_VM_PAGE(pa)) != NULL) {
+				struct pv_entry *pve;
+
+				pve = pmap_remove_pv(m, pmap, sva);
+				if (pve) {
+					is_exec = PTE_BEEN_EXECD(pte);
+					is_refd = PTE_BEEN_REFD(pte);
+					pmap_free_pv_entry(pmap, pve);
+				}
+			}
+
+			*ptep = 0;
+			PTE_SYNC(ptep);
+			if (pmap_is_current(pmap)) {
+				total++;
+				if (total < PMAP_REMOVE_CLEAN_LIST_SIZE) {
+					if (is_exec)
+						cpu_tlb_flushID_SE(sva);
+					else if (is_refd)
+						cpu_tlb_flushD_SE(sva);
+				} else if (total == PMAP_REMOVE_CLEAN_LIST_SIZE)
+					flushall = 1;
+			}
+
+			sva += PAGE_SIZE;
+			ptep++;
+			mappings++;
+		}
+
+		pmap_free_l2_bucket(pmap, l2b, mappings);
+	}
+
+	rw_wunlock(&pvh_global_lock);
+	if (flushall)
+		cpu_tlb_flushID();
+	cpu_cpwait();
+
+	PMAP_UNLOCK(pmap);
+}
+
+/*
+ * pmap_zero_page()
+ *
+ * Zero a given physical page by mapping it at a page hook point.
+ * In doing the zero page op, the page we zero is mapped cachable, as with
+ * StrongARM accesses to non-cached pages are non-burst making writing
+ * _any_ bulk data very slow.
+ */
+static void
+pmap_zero_page_gen(vm_page_t m, int off, int size)
+{
+	struct czpages *czp;
+
+	KASSERT(TAILQ_EMPTY(&m->md.pv_list), 
+	    ("pmap_zero_page_gen: page has mappings"));
+
+	vm_paddr_t phys = VM_PAGE_TO_PHYS(m);
+
+	sched_pin();
+	czp = &cpu_czpages[PCPU_GET(cpuid)];
+	mtx_lock(&czp->lock);
+	
+	/*
+	 * Hook in the page, zero it.
+	 */
+	*czp->dstptep = L2_S_PROTO | phys | pte_l2_s_cache_mode | L2_S_REF;
+	pmap_set_prot(czp->dstptep, VM_PROT_WRITE, 0);
+	PTE_SYNC(czp->dstptep);
+	cpu_tlb_flushD_SE(czp->dstva);
+	cpu_cpwait();
+
+	if (off || size != PAGE_SIZE)
+		bzero((void *)(czp->dstva + off), size);
+	else
+		bzero_page(czp->dstva);
+
+	/*
+	 * Although aliasing is not possible, if we use temporary mappings with
+	 * memory that will be mapped later as non-cached or with write-through
+	 * caches, we might end up overwriting it when calling wbinv_all.  So
+	 * make sure caches are clean after the operation.
+	 */
+	cpu_idcache_wbinv_range(czp->dstva, size);
+	pmap_l2cache_wbinv_range(czp->dstva, phys, size);
+
+	mtx_unlock(&czp->lock);
+	sched_unpin();
+}
+
+/*
+ *	pmap_zero_page zeros the specified hardware page by mapping
+ *	the page into KVM and using bzero to clear its contents.
+ */
+void
+pmap_zero_page(vm_page_t m)
+{
+	pmap_zero_page_gen(m, 0, PAGE_SIZE);
+}
+
+
+/*
+ *	pmap_zero_page_area zeros the specified hardware page by mapping
+ *	the page into KVM and using bzero to clear its contents.
+ *
+ *	off and size may not cover an area beyond a single hardware page.
+ */
+void
+pmap_zero_page_area(vm_page_t m, int off, int size)
+{
+
+	pmap_zero_page_gen(m, off, size);
+}
+
+
+/*
+ *	pmap_zero_page_idle zeros the specified hardware page by mapping
+ *	the page into KVM and using bzero to clear its contents.  This
+ *	is intended to be called from the vm_pagezero process only and
+ *	outside of Giant.
+ */
+void
+pmap_zero_page_idle(vm_page_t m)
+{
+
+	pmap_zero_page(m);
+}
+
+/*
+ *	pmap_copy_page copies the specified (machine independent)
+ *	page by mapping the page into virtual memory and using
+ *	bcopy to copy the page, one machine dependent page at a
+ *	time.
+ */
+
+/*
+ * pmap_copy_page()
+ *
+ * Copy one physical page into another, by mapping the pages into
+ * hook points. The same comment regarding cachability as in
+ * pmap_zero_page also applies here.
+ */
+void
+pmap_copy_page_generic(vm_paddr_t src, vm_paddr_t dst)
+{
+	struct czpages *czp;
+
+	sched_pin();
+	czp = &cpu_czpages[PCPU_GET(cpuid)];
+	mtx_lock(&czp->lock);
+	
+	/*
+	 * Map the pages into the page hook points, copy them, and purge the
+	 * cache for the appropriate page.
+	 */
+	*czp->srcptep = L2_S_PROTO | src | pte_l2_s_cache_mode | L2_S_REF;
+	pmap_set_prot(czp->srcptep, VM_PROT_READ, 0);
+	PTE_SYNC(czp->srcptep);
+	cpu_tlb_flushD_SE(czp->srcva);
+	*czp->dstptep = L2_S_PROTO | dst | pte_l2_s_cache_mode | L2_S_REF;
+	pmap_set_prot(czp->dstptep, VM_PROT_READ | VM_PROT_WRITE, 0);
+	PTE_SYNC(czp->dstptep);
+	cpu_tlb_flushD_SE(czp->dstva);
+	cpu_cpwait();
+
+	bcopy_page(czp->srcva, czp->dstva);
+
+	/*
+	 * Although aliasing is not possible, if we use temporary mappings with
+	 * memory that will be mapped later as non-cached or with write-through
+	 * caches, we might end up overwriting it when calling wbinv_all.  So
+	 * make sure caches are clean after the operation.
+	 */
+	cpu_idcache_wbinv_range(czp->dstva, PAGE_SIZE);
+	pmap_l2cache_wbinv_range(czp->dstva, dst, PAGE_SIZE);
+
+	mtx_unlock(&czp->lock);
+	sched_unpin();
+}
+
+int unmapped_buf_allowed = 1;
+
+void
+pmap_copy_pages(vm_page_t ma[], vm_offset_t a_offset, vm_page_t mb[],
+    vm_offset_t b_offset, int xfersize)
+{
+	vm_page_t a_pg, b_pg;
+	vm_offset_t a_pg_offset, b_pg_offset;
+	int cnt;
+	struct czpages *czp;
+
+	sched_pin();
+	czp = &cpu_czpages[PCPU_GET(cpuid)];
+	mtx_lock(&czp->lock);
+
+	while (xfersize > 0) {
+		a_pg = ma[a_offset >> PAGE_SHIFT];
+		a_pg_offset = a_offset & PAGE_MASK;
+		cnt = min(xfersize, PAGE_SIZE - a_pg_offset);
+		b_pg = mb[b_offset >> PAGE_SHIFT];
+		b_pg_offset = b_offset & PAGE_MASK;
+		cnt = min(cnt, PAGE_SIZE - b_pg_offset);
+		*czp->srcptep = L2_S_PROTO | VM_PAGE_TO_PHYS(a_pg) |
+		    pte_l2_s_cache_mode | L2_S_REF;
+		pmap_set_prot(czp->srcptep, VM_PROT_READ, 0);
+		PTE_SYNC(czp->srcptep);
+		cpu_tlb_flushD_SE(czp->srcva);
+		*czp->dstptep = L2_S_PROTO | VM_PAGE_TO_PHYS(b_pg) |
+		    pte_l2_s_cache_mode | L2_S_REF;
+		pmap_set_prot(czp->dstptep, VM_PROT_READ | VM_PROT_WRITE, 0);
+		PTE_SYNC(czp->dstptep);
+		cpu_tlb_flushD_SE(czp->dstva);
+		cpu_cpwait();
+		bcopy((char *)czp->srcva + a_pg_offset, (char *)czp->dstva + b_pg_offset,
+		    cnt);
+		cpu_idcache_wbinv_range(czp->dstva + b_pg_offset, cnt);
+		pmap_l2cache_wbinv_range(czp->dstva + b_pg_offset,
+		    VM_PAGE_TO_PHYS(b_pg) + b_pg_offset, cnt);
+		xfersize -= cnt;
+		a_offset += cnt;
+		b_offset += cnt;
+	}
+
+	mtx_unlock(&czp->lock);
+	sched_unpin();
+}
+
+void
+pmap_copy_page(vm_page_t src, vm_page_t dst)
+{
+
+	if (_arm_memcpy && PAGE_SIZE >= _min_memcpy_size &&
+	    _arm_memcpy((void *)VM_PAGE_TO_PHYS(dst),
+	    (void *)VM_PAGE_TO_PHYS(src), PAGE_SIZE, IS_PHYSICAL) == 0)
+		return;
+
+	pmap_copy_page_generic(VM_PAGE_TO_PHYS(src), VM_PAGE_TO_PHYS(dst));
+}
+
+/*
+ * this routine returns true if a physical page resides
+ * in the given pmap.
+ */
+boolean_t
+pmap_page_exists_quick(pmap_t pmap, vm_page_t m)
+{
+	struct md_page *pvh;
+	pv_entry_t pv;
+	int loops = 0;
+	boolean_t rv;
+
+	KASSERT((m->oflags & VPO_UNMANAGED) == 0,
+	    ("pmap_page_exists_quick: page %p is not managed", m));
+	rv = FALSE;
+	rw_wlock(&pvh_global_lock);
+	TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
+		if (PV_PMAP(pv) == pmap) {
+			rv = TRUE;
+			break;
+		}
+		loops++;
+		if (loops >= 16)
+			break;
+	}
+	if (!rv && loops < 16 && (m->flags & PG_FICTITIOUS) == 0) {
+		pvh = pa_to_pvh(VM_PAGE_TO_PHYS(m));
+		TAILQ_FOREACH(pv, &pvh->pv_list, pv_list) {
+			if (PV_PMAP(pv) == pmap) {
+				rv = TRUE;
+				break;
+			}
+			loops++;
+			if (loops >= 16)
+				break;
+		}
+	}
+	rw_wunlock(&pvh_global_lock);
+	return (rv);
+}
+
+/*
+ *	pmap_page_wired_mappings:
+ *
+ *	Return the number of managed mappings to the given physical page
+ *	that are wired.
+ */
+int
+pmap_page_wired_mappings(vm_page_t m)
+{
+	int count;
+
+	count = 0;
+	if ((m->oflags & VPO_UNMANAGED) != 0)
+		return (count);
+	rw_wlock(&pvh_global_lock);
+	count = pmap_pvh_wired_mappings(&m->md, count);
+	if ((m->flags & PG_FICTITIOUS) == 0) {
+	    count = pmap_pvh_wired_mappings(pa_to_pvh(VM_PAGE_TO_PHYS(m)),
+	        count);
+	}
+	rw_wunlock(&pvh_global_lock);
+	return (count);
+}
+
+/*
+ *	pmap_pvh_wired_mappings:
+ *
+ *	Return the updated number "count" of managed mappings that are wired.
+ */
+static int
+pmap_pvh_wired_mappings(struct md_page *pvh, int count)
+{
+	pv_entry_t pv;
+
+	rw_assert(&pvh_global_lock, RA_WLOCKED);
+	TAILQ_FOREACH(pv, &pvh->pv_list, pv_list) {
+		if ((pv->pv_flags & PVF_WIRED) != 0)
+			count++;
+	}
+	return (count);
+}
+
+/*
+ * Returns TRUE if any of the given mappings were referenced and FALSE
+ * otherwise.  Both page and section mappings are supported.
+ */
+static boolean_t
+pmap_is_referenced_pvh(struct md_page *pvh)
+{
+	struct l2_bucket *l2b;
+	pv_entry_t pv;
+	pd_entry_t *pl1pd;
+	pt_entry_t *ptep;
+	pmap_t pmap;
+	boolean_t rv;
+
+	rw_assert(&pvh_global_lock, RA_WLOCKED);
+	rv = FALSE;
+	TAILQ_FOREACH(pv, &pvh->pv_list, pv_list) {
+		pmap = PV_PMAP(pv);
+		PMAP_LOCK(pmap);
+		pl1pd = &pmap->pm_l1->l1_kva[L1_IDX(pv->pv_va)];
+		if ((*pl1pd & L1_TYPE_MASK) == L1_S_PROTO)
+			rv = L1_S_REFERENCED(*pl1pd);
+		else {
+			l2b = pmap_get_l2_bucket(pmap, pv->pv_va);
+			ptep = &l2b->l2b_kva[l2pte_index(pv->pv_va)];
+			rv = L2_S_REFERENCED(*ptep);
+		}
+		PMAP_UNLOCK(pmap);
+		if (rv)
+			break;
+	}
+	return (rv);
+}
+
+/*
+ *	pmap_is_referenced:
+ *
+ *	Return whether or not the specified physical page was referenced
+ *	in any physical maps.
+ */
+boolean_t
+pmap_is_referenced(vm_page_t m)
+{
+	boolean_t rv;
+
+	KASSERT((m->oflags & VPO_UNMANAGED) == 0,
+	    ("pmap_is_referenced: page %p is not managed", m));
+	rw_wlock(&pvh_global_lock);
+	rv = pmap_is_referenced_pvh(&m->md) ||
+	    ((m->flags & PG_FICTITIOUS) == 0 &&
+	    pmap_is_referenced_pvh(pa_to_pvh(VM_PAGE_TO_PHYS(m))));
+	rw_wunlock(&pvh_global_lock);
+	return (rv);
+}
+
+/*
+ *	pmap_ts_referenced:
+ *
+ *	Return the count of reference bits for a page, clearing all of them.
+ */
+int
+pmap_ts_referenced(vm_page_t m)
+{
+
+	KASSERT((m->oflags & VPO_UNMANAGED) == 0,
+	    ("pmap_ts_referenced: page %p is not managed", m));
+	return (pmap_clearbit(m, PVF_REF));
+}
+
+/*
+ * Returns TRUE if any of the given mappings were used to modify
+ * physical memory. Otherwise, returns FALSE. Both page and 1MB section
+ * mappings are supported.
+ */
+static boolean_t
+pmap_is_modified_pvh(struct md_page *pvh)
+{
+	pd_entry_t *pl1pd;
+	struct l2_bucket *l2b;
+	pv_entry_t pv;
+	pt_entry_t *ptep;
+	pmap_t pmap;
+	boolean_t rv;
+
+	rw_assert(&pvh_global_lock, RA_WLOCKED);
+	rv = FALSE;
+
+	TAILQ_FOREACH(pv, &pvh->pv_list, pv_list) {
+		pmap = PV_PMAP(pv);
+		PMAP_LOCK(pmap);
+		pl1pd = &pmap->pm_l1->l1_kva[L1_IDX(pv->pv_va)];
+		if ((*pl1pd & L1_TYPE_MASK) == L1_S_PROTO)
+			rv = L1_S_WRITABLE(*pl1pd);
+		else {
+			l2b = pmap_get_l2_bucket(pmap, pv->pv_va);
+			ptep = &l2b->l2b_kva[l2pte_index(pv->pv_va)];
+			rv = L2_S_WRITABLE(*ptep);
+		}
+		PMAP_UNLOCK(pmap);
+		if (rv)
+			break;
+	}
+
+	return (rv);
+}
+
+boolean_t
+pmap_is_modified(vm_page_t m)
+{
+	boolean_t rv;
+
+	KASSERT((m->oflags & VPO_UNMANAGED) == 0,
+	    ("pmap_is_modified: page %p is not managed", m));
+	/*
+	 * If the page is not exclusive busied, then PGA_WRITEABLE cannot be
+	 * concurrently set while the object is locked.  Thus, if PGA_WRITEABLE
+	 * is clear, no PTEs can have APX cleared.
+	 */
+	VM_OBJECT_ASSERT_WLOCKED(m->object);
+	if (!vm_page_xbusied(m) && (m->aflags & PGA_WRITEABLE) == 0)
+		return (FALSE);
+	rw_wlock(&pvh_global_lock);
+	rv = pmap_is_modified_pvh(&m->md) ||
+	    ((m->flags & PG_FICTITIOUS) == 0 &&
+	    pmap_is_modified_pvh(pa_to_pvh(VM_PAGE_TO_PHYS(m))));
+	rw_wunlock(&pvh_global_lock);
+	return (rv);
+}
+
+/*
+ *	Apply the given advice to the specified range of addresses within the
+ *	given pmap.  Depending on the advice, clear the referenced and/or
+ *	modified flags in each mapping.
+ */
+void
+pmap_advise(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, int advice)
+{
+	struct l2_bucket *l2b;
+	struct pv_entry *pve;
+	pd_entry_t *pl1pd, l1pd;
+	pt_entry_t *ptep, opte, pte;
+	vm_offset_t next_bucket;
+	vm_page_t m;
+
+	if (advice != MADV_DONTNEED && advice != MADV_FREE)
+		return;
+	rw_wlock(&pvh_global_lock);
+	PMAP_LOCK(pmap);
+	for (; sva < eva; sva = next_bucket) {
+		next_bucket = L2_NEXT_BUCKET(sva);
+		if (next_bucket < sva)
+			next_bucket = eva;
+		pl1pd = &pmap->pm_l1->l1_kva[L1_IDX(sva)];
+		l1pd = *pl1pd;
+		if ((l1pd & L1_TYPE_MASK) == L1_S_PROTO) {
+			if (pmap == pmap_kernel())
+				continue;
+			if (!pmap_demote_section(pmap, sva)) {
+				/*
+				 * The large page mapping was destroyed.
+				 */
+				continue;
+			}
+			/*
+			 * Unless the page mappings are wired, remove the
+			 * mapping to a single page so that a subsequent
+			 * access may repromote. Since the underlying
+			 * l2_bucket is fully populated, this removal
+			 * never frees an entire l2_bucket.
+			 */
+			l2b = pmap_get_l2_bucket(pmap, sva);
+			KASSERT(l2b != NULL,
+			    ("pmap_advise: no l2 bucket for "
+			     "va 0x%#x, pmap 0x%p", sva, pmap));
+			ptep = &l2b->l2b_kva[l2pte_index(sva)];
+			opte = *ptep;
+			m = PHYS_TO_VM_PAGE(l2pte_pa(*ptep));
+			KASSERT(m != NULL,
+			    ("pmap_advise: no vm_page for demoted superpage"));
+			pve = pmap_find_pv(&m->md, pmap, sva);
+			KASSERT(pve != NULL,
+			    ("pmap_advise: no PV entry for managed mapping"));
+			if ((pve->pv_flags & PVF_WIRED) == 0) {
+				pmap_free_l2_bucket(pmap, l2b, 1);
+				pve = pmap_remove_pv(m, pmap, sva);
+				pmap_free_pv_entry(pmap, pve);
+				*ptep = 0;
+				PTE_SYNC(ptep);
+				if (pmap_is_current(pmap)) {
+					if (PTE_BEEN_EXECD(opte))
+						cpu_tlb_flushID_SE(sva);
+					else if (PTE_BEEN_REFD(opte))
+						cpu_tlb_flushD_SE(sva);
+				}
+			}
+		}
+		if (next_bucket > eva)
+			next_bucket = eva;
+		l2b = pmap_get_l2_bucket(pmap, sva);
+		if (l2b == NULL)
+			continue;
+		for (ptep = &l2b->l2b_kva[l2pte_index(sva)];
+		    sva != next_bucket; ptep++, sva += PAGE_SIZE) {
+			opte = pte = *ptep;
+			if ((opte & L2_S_PROTO) == 0)
+				continue;
+			m = PHYS_TO_VM_PAGE(l2pte_pa(opte));
+			if (m == NULL || (m->oflags & VPO_UNMANAGED) != 0)
+				continue;
+			else if (L2_S_WRITABLE(opte)) {
+				if (advice == MADV_DONTNEED) {
+					/*
+					 * Don't need to mark the page
+					 * dirty as it was already marked as
+					 * such in pmap_fault_fixup() or
+					 * pmap_enter_locked().
+					 * Just clear the state.
+					 */
+				} else
+					pte |= L2_APX;
+
+				pte &= ~L2_S_REF;
+				*ptep = pte;
+				PTE_SYNC(ptep);
+			} else if (L2_S_REFERENCED(opte)) {
+				pte &= ~L2_S_REF;
+				*ptep = pte;
+				PTE_SYNC(ptep);
+			} else
+				continue;
+			if (pmap_is_current(pmap)) {
+				if (PTE_BEEN_EXECD(opte))
+					cpu_tlb_flushID_SE(sva);
+				else if (PTE_BEEN_REFD(opte))
+					cpu_tlb_flushD_SE(sva);
+			}
+		}
+	}
+	cpu_cpwait();
+	rw_wunlock(&pvh_global_lock);
+	PMAP_UNLOCK(pmap);
+}
+
+/*
+ *	Clear the modify bits on the specified physical page.
+ */
+void
+pmap_clear_modify(vm_page_t m)
+{
+
+	KASSERT((m->oflags & VPO_UNMANAGED) == 0,
+	    ("pmap_clear_modify: page %p is not managed", m));
+	VM_OBJECT_ASSERT_WLOCKED(m->object);
+	KASSERT(!vm_page_xbusied(m),
+	    ("pmap_clear_modify: page %p is exclusive busied", m));
+
+	/*
+	 * If the page is not PGA_WRITEABLE, then no mappings can be modified.
+	 * If the object containing the page is locked and the page is not
+	 * exclusive busied, then PGA_WRITEABLE cannot be concurrently set.
+	 */
+	if ((m->aflags & PGA_WRITEABLE) == 0)
+		return;
+	if (pmap_is_modified(m))
+		pmap_clearbit(m, PVF_MOD);
+}
+
+
+/*
+ * Clear the write and modified bits in each of the given page's mappings.
+ */
+void
+pmap_remove_write(vm_page_t m)
+{
+	KASSERT((m->oflags & VPO_UNMANAGED) == 0,
+	    ("pmap_remove_write: page %p is not managed", m));
+
+	/*
+	 * If the page is not exclusive busied, then PGA_WRITEABLE cannot be
+	 * set by another thread while the object is locked.  Thus,
+	 * if PGA_WRITEABLE is clear, no page table entries need updating.
+	 */
+	VM_OBJECT_ASSERT_WLOCKED(m->object);
+	if (vm_page_xbusied(m) || (m->aflags & PGA_WRITEABLE) != 0)
+		pmap_clearbit(m, PVF_WRITE);
+}
+
+
+/*
+ * perform the pmap work for mincore
+ */
+int
+pmap_mincore(pmap_t pmap, vm_offset_t addr, vm_paddr_t *locked_pa)
+{
+	struct l2_bucket *l2b;
+	pd_entry_t *pl1pd, l1pd;
+	pt_entry_t *ptep, pte;
+	vm_paddr_t pa;
+	vm_page_t m;
+	int val;
+	boolean_t managed;
+
+	PMAP_LOCK(pmap);
+retry:
+	pl1pd = &pmap->pm_l1->l1_kva[L1_IDX(addr)];
+	l1pd = *pl1pd;
+	if ((l1pd & L1_TYPE_MASK) == L1_S_PROTO) {
+		pa = (l1pd & L1_S_FRAME);
+		val = MINCORE_SUPER | MINCORE_INCORE;
+		if (L1_S_WRITABLE(l1pd))
+			val |= MINCORE_MODIFIED | MINCORE_MODIFIED_OTHER;
+		managed = FALSE;
+		m = PHYS_TO_VM_PAGE(pa);
+		if (m != NULL && (m->oflags & VPO_UNMANAGED) == 0)
+			managed = TRUE;
+		if (managed) {
+			if (L1_S_REFERENCED(l1pd))
+				val |= MINCORE_REFERENCED |
+				    MINCORE_REFERENCED_OTHER;
+		}
+	} else {
+		l2b = pmap_get_l2_bucket(pmap, addr);
+		if (l2b == NULL) {
+			val = 0;
+			goto out;
+		}
+		ptep = &l2b->l2b_kva[l2pte_index(addr)];
+		pte = *ptep;
+		if (!l2pte_valid(pte)) {
+			val = 0;
+			goto out;
+		}
+		val = MINCORE_INCORE;
+		if (L2_S_WRITABLE(pte))
+			val |= MINCORE_MODIFIED | MINCORE_MODIFIED_OTHER;
+		managed = FALSE;
+		pa = l2pte_pa(pte);
+		m = PHYS_TO_VM_PAGE(pa);
+		if (m != NULL && (m->oflags & VPO_UNMANAGED) == 0)
+			managed = TRUE;
+		if (managed) {
+			if (L2_S_REFERENCED(pte))
+				val |= MINCORE_REFERENCED |
+				    MINCORE_REFERENCED_OTHER;
+		}
+	}
+	if ((val & (MINCORE_MODIFIED_OTHER | MINCORE_REFERENCED_OTHER)) !=
+	    (MINCORE_MODIFIED_OTHER | MINCORE_REFERENCED_OTHER) && managed) {
+		/* Ensure that "PHYS_TO_VM_PAGE(pa)->object" doesn't change. */
+		if (vm_page_pa_tryrelock(pmap, pa, locked_pa))
+			goto retry;
+	} else
+out:
+		PA_UNLOCK_COND(*locked_pa);
+	PMAP_UNLOCK(pmap);
+	return (val);
+}
+
+void
+pmap_sync_icache(pmap_t pmap, vm_offset_t va, vm_size_t sz)
+{
+}
+
+/*
+ *	Increase the starting virtual address of the given mapping if a
+ *	different alignment might result in more superpage mappings.
+ */
+void
+pmap_align_superpage(vm_object_t object, vm_ooffset_t offset,
+    vm_offset_t *addr, vm_size_t size)
+{
+	vm_offset_t superpage_offset;
+
+	if (size < NBPDR)
+		return;
+	if (object != NULL && (object->flags & OBJ_COLORED) != 0)
+		offset += ptoa(object->pg_color);
+	superpage_offset = offset & PDRMASK;
+	if (size - ((NBPDR - superpage_offset) & PDRMASK) < NBPDR ||
+	    (*addr & PDRMASK) == superpage_offset)
+		return;
+	if ((*addr & PDRMASK) < superpage_offset)
+		*addr = (*addr & ~PDRMASK) + superpage_offset;
+	else
+		*addr = ((*addr + PDRMASK) & ~PDRMASK) + superpage_offset;
+}
+
+/*
+ * pmap_map_section:
+ *
+ *	Create a single section mapping.
+ */
+void
+pmap_map_section(pmap_t pmap, vm_offset_t va, vm_offset_t pa, vm_prot_t prot,
+    boolean_t ref)
+{
+	pd_entry_t *pl1pd, l1pd;
+	pd_entry_t fl;
+
+	KASSERT(((va | pa) & L1_S_OFFSET) == 0,
+	    ("Not a valid section mapping"));
+
+	fl = pte_l1_s_cache_mode;
+
+	pl1pd = &pmap->pm_l1->l1_kva[L1_IDX(va)];
+	l1pd = L1_S_PROTO | pa | L1_S_PROT(PTE_USER, prot) | fl |
+	    L1_S_DOM(pmap->pm_domain);
+
+	/* Mark page referenced if this section is a result of a promotion. */
+	if (ref == TRUE)
+		l1pd |= L1_S_REF;
+#ifdef SMP
+	l1pd |= L1_SHARED;
+#endif
+	*pl1pd = l1pd;
+	PTE_SYNC(pl1pd);
+}
+
+/*
+ * pmap_link_l2pt:
+ *
+ *	Link the L2 page table specified by l2pv.pv_pa into the L1
+ *	page table at the slot for "va".
+ */
+void
+pmap_link_l2pt(vm_offset_t l1pt, vm_offset_t va, struct pv_addr *l2pv)
+{
+	pd_entry_t *pde = (pd_entry_t *) l1pt, proto;
+	u_int slot = va >> L1_S_SHIFT;
+
+	proto = L1_S_DOM(PMAP_DOMAIN_KERNEL) | L1_C_PROTO;
+
+#ifdef VERBOSE_INIT_ARM
+	printf("pmap_link_l2pt: pa=0x%x va=0x%x\n", l2pv->pv_pa, l2pv->pv_va);
+#endif
+
+	pde[slot + 0] = proto | (l2pv->pv_pa + 0x000);
+	PTE_SYNC(&pde[slot]);
+
+	SLIST_INSERT_HEAD(&kernel_pt_list, l2pv, pv_list);
+
+}
+
+/*
+ * pmap_map_entry
+ *
+ *	Create a single page mapping.
+ */
+void
+pmap_map_entry(vm_offset_t l1pt, vm_offset_t va, vm_offset_t pa, int prot,
+    int cache)
+{
+	pd_entry_t *pde = (pd_entry_t *) l1pt;
+	pt_entry_t fl;
+	pt_entry_t *ptep;
+
+	KASSERT(((va | pa) & PAGE_MASK) == 0, ("ouin"));
+
+	fl = l2s_mem_types[cache];
+
+	if ((pde[va >> L1_S_SHIFT] & L1_TYPE_MASK) != L1_TYPE_C)
+		panic("pmap_map_entry: no L2 table for VA 0x%08x", va);
+
+	ptep = (pt_entry_t *)kernel_pt_lookup(pde[L1_IDX(va)] & L1_C_ADDR_MASK);
+
+	if (ptep == NULL)
+		panic("pmap_map_entry: can't find L2 table for VA 0x%08x", va);
+
+	ptep[l2pte_index(va)] = L2_S_PROTO | pa | fl | L2_S_REF;
+	pmap_set_prot(&ptep[l2pte_index(va)], prot, 0);
+	PTE_SYNC(&ptep[l2pte_index(va)]);
+}
+
+/*
+ * pmap_map_chunk:
+ *
+ *	Map a chunk of memory using the most efficient mappings
+ *	possible (section. large page, small page) into the
+ *	provided L1 and L2 tables at the specified virtual address.
+ */
+vm_size_t
+pmap_map_chunk(vm_offset_t l1pt, vm_offset_t va, vm_offset_t pa,
+    vm_size_t size, int prot, int type)
+{
+	pd_entry_t *pde = (pd_entry_t *) l1pt;
+	pt_entry_t *ptep, f1, f2s, f2l;
+	vm_size_t resid;
+	int i;
+
+	resid = (size + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
+
+	if (l1pt == 0)
+		panic("pmap_map_chunk: no L1 table provided");
+
+#ifdef VERBOSE_INIT_ARM
+	printf("pmap_map_chunk: pa=0x%x va=0x%x size=0x%x resid=0x%x "
+	    "prot=0x%x type=%d\n", pa, va, size, resid, prot, type);
+#endif
+
+	f1 = l1_mem_types[type];
+	f2l = l2l_mem_types[type];
+	f2s = l2s_mem_types[type];
+
+	size = resid;
+
+	while (resid > 0) {
+		/* See if we can use a section mapping. */
+		if (L1_S_MAPPABLE_P(va, pa, resid)) {
+#ifdef VERBOSE_INIT_ARM
+			printf("S");
+#endif
+			pde[va >> L1_S_SHIFT] = L1_S_PROTO | pa |
+			    L1_S_PROT(PTE_KERNEL, prot | VM_PROT_EXECUTE) |
+			    f1 | L1_S_DOM(PMAP_DOMAIN_KERNEL) | L1_S_REF;
+			PTE_SYNC(&pde[va >> L1_S_SHIFT]);
+			va += L1_S_SIZE;
+			pa += L1_S_SIZE;
+			resid -= L1_S_SIZE;
+			continue;
+		}
+
+		/*
+		 * Ok, we're going to use an L2 table.  Make sure
+		 * one is actually in the corresponding L1 slot
+		 * for the current VA.
+		 */
+		if ((pde[va >> L1_S_SHIFT] & L1_TYPE_MASK) != L1_TYPE_C)
+			panic("pmap_map_chunk: no L2 table for VA 0x%08x", va);
+
+		ptep = (pt_entry_t *) kernel_pt_lookup(
+		    pde[L1_IDX(va)] & L1_C_ADDR_MASK);
+		if (ptep == NULL)
+			panic("pmap_map_chunk: can't find L2 table for VA"
+			    "0x%08x", va);
+		/* See if we can use a L2 large page mapping. */
+		if (L2_L_MAPPABLE_P(va, pa, resid)) {
+#ifdef VERBOSE_INIT_ARM
+			printf("L");
+#endif
+			for (i = 0; i < 16; i++) {
+				ptep[l2pte_index(va) + i] =
+				    L2_L_PROTO | pa |
+				    L2_L_PROT(PTE_KERNEL, prot) | f2l;
+				PTE_SYNC(&ptep[l2pte_index(va) + i]);
+			}
+			va += L2_L_SIZE;
+			pa += L2_L_SIZE;
+			resid -= L2_L_SIZE;
+			continue;
+		}
+
+		/* Use a small page mapping. */
+#ifdef VERBOSE_INIT_ARM
+		printf("P");
+#endif
+		ptep[l2pte_index(va)] = L2_S_PROTO | pa | f2s | L2_S_REF;
+		pmap_set_prot(&ptep[l2pte_index(va)], prot, 0);
+		PTE_SYNC(&ptep[l2pte_index(va)]);
+		va += PAGE_SIZE;
+		pa += PAGE_SIZE;
+		resid -= PAGE_SIZE;
+	}
+#ifdef VERBOSE_INIT_ARM
+	printf("\n");
+#endif
+	return (size);
+
+}
+
+int
+pmap_dmap_iscurrent(pmap_t pmap)
+{
+	return(pmap_is_current(pmap));
+}
+
+void
+pmap_page_set_memattr(vm_page_t m, vm_memattr_t ma)
+{
+	/* 
+	 * Remember the memattr in a field that gets used to set the appropriate
+	 * bits in the PTEs as mappings are established.
+	 */
+	m->md.pv_memattr = ma;
+
+	/*
+	 * It appears that this function can only be called before any mappings
+	 * for the page are established on ARM.  If this ever changes, this code
+	 * will need to walk the pv_list and make each of the existing mappings
+	 * uncacheable, being careful to sync caches and PTEs (and maybe
+	 * invalidate TLB?) for any current mapping it modifies.
+	 */
+	if (TAILQ_FIRST(&m->md.pv_list) != NULL)
+		panic("Can't change memattr on page with existing mappings");
+}


Property changes on: trunk/sys/arm/arm/pmap-v6.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/pmap.c
===================================================================
--- trunk/sys/arm/arm/pmap.c	                        (rev 0)
+++ trunk/sys/arm/arm/pmap.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,4828 @@
+/* $MidnightBSD$ */
+/* From: $NetBSD: pmap.c,v 1.148 2004/04/03 04:35:48 bsh Exp $ */
+/*-
+ * Copyright 2004 Olivier Houchard.
+ * Copyright 2003 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Steve C. Woodford for Wasabi Systems, Inc.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed for the NetBSD Project by
+ *      Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
+ * 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.
+ */
+
+/*-
+ * Copyright (c) 2002-2003 Wasabi Systems, Inc.
+ * Copyright (c) 2001 Richard Earnshaw
+ * Copyright (c) 2001-2002 Christopher Gilbert
+ * All rights reserved.
+ *
+ * 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.
+ * 3. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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.
+ */
+/*-
+ * Copyright (c) 1999 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Charles M. Hannum.
+ *
+ * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
+ */
+
+/*-
+ * Copyright (c) 1994-1998 Mark Brinicombe.
+ * Copyright (c) 1994 Brini.
+ * All rights reserved.
+ *
+ * This code is derived from software written for Brini by Mark Brinicombe
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by Mark Brinicombe.
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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
+ *
+ * RiscBSD kernel project
+ *
+ * pmap.c
+ *
+ * Machine dependant vm stuff
+ *
+ * Created      : 20/09/94
+ */
+
+/*
+ * Special compilation symbols
+ * PMAP_DEBUG           - Build in pmap_debug_level code
+ *
+ * Note that pmap_mapdev() and pmap_unmapdev() are implemented in arm/devmap.c
+ */
+/* Include header files */
+
+#include "opt_vm.h"
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/pmap.c 283931 2015-06-02 21:36:45Z imp $");
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/ktr.h>
+#include <sys/lock.h>
+#include <sys/proc.h>
+#include <sys/malloc.h>
+#include <sys/msgbuf.h>
+#include <sys/mutex.h>
+#include <sys/vmmeter.h>
+#include <sys/mman.h>
+#include <sys/rwlock.h>
+#include <sys/smp.h>
+#include <sys/sched.h>
+
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+#include <vm/uma.h>
+#include <vm/pmap.h>
+#include <vm/vm_kern.h>
+#include <vm/vm_object.h>
+#include <vm/vm_map.h>
+#include <vm/vm_page.h>
+#include <vm/vm_pageout.h>
+#include <vm/vm_phys.h>
+#include <vm/vm_extern.h>
+
+#include <machine/md_var.h>
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+#include <machine/pcb.h>
+
+#ifdef PMAP_DEBUG
+#define PDEBUG(_lev_,_stat_) \
+        if (pmap_debug_level >= (_lev_)) \
+                ((_stat_))
+#define dprintf printf
+
+int pmap_debug_level = 0;
+#define PMAP_INLINE
+#else   /* PMAP_DEBUG */
+#define PDEBUG(_lev_,_stat_) /* Nothing */
+#define dprintf(x, arg...)
+#define PMAP_INLINE __inline
+#endif  /* PMAP_DEBUG */
+
+extern struct pv_addr systempage;
+
+extern int last_fault_code;
+
+/*
+ * Internal function prototypes
+ */
+static void pmap_free_pv_entry (pv_entry_t);
+static pv_entry_t pmap_get_pv_entry(void);
+
+static int		pmap_enter_locked(pmap_t, vm_offset_t, vm_page_t,
+    vm_prot_t, u_int);
+static vm_paddr_t	pmap_extract_locked(pmap_t pmap, vm_offset_t va);
+static void		pmap_fix_cache(struct vm_page *, pmap_t, vm_offset_t);
+static void		pmap_alloc_l1(pmap_t);
+static void		pmap_free_l1(pmap_t);
+
+static int		pmap_clearbit(struct vm_page *, u_int);
+
+static struct l2_bucket *pmap_get_l2_bucket(pmap_t, vm_offset_t);
+static struct l2_bucket *pmap_alloc_l2_bucket(pmap_t, vm_offset_t);
+static void		pmap_free_l2_bucket(pmap_t, struct l2_bucket *, u_int);
+static vm_offset_t	kernel_pt_lookup(vm_paddr_t);
+
+static MALLOC_DEFINE(M_VMPMAP, "pmap", "PMAP L1");
+
+vm_offset_t virtual_avail;	/* VA of first avail page (after kernel bss) */
+vm_offset_t virtual_end;	/* VA of last avail page (end of kernel AS) */
+vm_offset_t pmap_curmaxkvaddr;
+vm_paddr_t kernel_l1pa;
+
+vm_offset_t kernel_vm_end = 0;
+
+vm_offset_t vm_max_kernel_address;
+
+struct pmap kernel_pmap_store;
+
+static pt_entry_t *csrc_pte, *cdst_pte;
+static vm_offset_t csrcp, cdstp;
+static struct mtx cmtx;
+
+static void		pmap_init_l1(struct l1_ttable *, pd_entry_t *);
+/*
+ * These routines are called when the CPU type is identified to set up
+ * the PTE prototypes, cache modes, etc.
+ *
+ * The variables are always here, just in case LKMs need to reference
+ * them (though, they shouldn't).
+ */
+
+pt_entry_t	pte_l1_s_cache_mode;
+pt_entry_t	pte_l1_s_cache_mode_pt;
+pt_entry_t	pte_l1_s_cache_mask;
+
+pt_entry_t	pte_l2_l_cache_mode;
+pt_entry_t	pte_l2_l_cache_mode_pt;
+pt_entry_t	pte_l2_l_cache_mask;
+
+pt_entry_t	pte_l2_s_cache_mode;
+pt_entry_t	pte_l2_s_cache_mode_pt;
+pt_entry_t	pte_l2_s_cache_mask;
+
+pt_entry_t	pte_l2_s_prot_u;
+pt_entry_t	pte_l2_s_prot_w;
+pt_entry_t	pte_l2_s_prot_mask;
+
+pt_entry_t	pte_l1_s_proto;
+pt_entry_t	pte_l1_c_proto;
+pt_entry_t	pte_l2_s_proto;
+
+void		(*pmap_copy_page_func)(vm_paddr_t, vm_paddr_t);
+void		(*pmap_copy_page_offs_func)(vm_paddr_t a_phys,
+		    vm_offset_t a_offs, vm_paddr_t b_phys, vm_offset_t b_offs,
+		    int cnt);
+void		(*pmap_zero_page_func)(vm_paddr_t, int, int);
+
+struct msgbuf *msgbufp = 0;
+
+/*
+ * Crashdump maps.
+ */
+static caddr_t crashdumpmap;
+
+extern void bcopy_page(vm_offset_t, vm_offset_t);
+extern void bzero_page(vm_offset_t);
+
+extern vm_offset_t alloc_firstaddr;
+
+char *_tmppt;
+
+/*
+ * Metadata for L1 translation tables.
+ */
+struct l1_ttable {
+	/* Entry on the L1 Table list */
+	SLIST_ENTRY(l1_ttable) l1_link;
+
+	/* Entry on the L1 Least Recently Used list */
+	TAILQ_ENTRY(l1_ttable) l1_lru;
+
+	/* Track how many domains are allocated from this L1 */
+	volatile u_int l1_domain_use_count;
+
+	/*
+	 * A free-list of domain numbers for this L1.
+	 * We avoid using ffs() and a bitmap to track domains since ffs()
+	 * is slow on ARM.
+	 */
+	u_int8_t l1_domain_first;
+	u_int8_t l1_domain_free[PMAP_DOMAINS];
+
+	/* Physical address of this L1 page table */
+	vm_paddr_t l1_physaddr;
+
+	/* KVA of this L1 page table */
+	pd_entry_t *l1_kva;
+};
+
+/*
+ * Convert a virtual address into its L1 table index. That is, the
+ * index used to locate the L2 descriptor table pointer in an L1 table.
+ * This is basically used to index l1->l1_kva[].
+ *
+ * Each L2 descriptor table represents 1MB of VA space.
+ */
+#define	L1_IDX(va)		(((vm_offset_t)(va)) >> L1_S_SHIFT)
+
+/*
+ * L1 Page Tables are tracked using a Least Recently Used list.
+ *  - New L1s are allocated from the HEAD.
+ *  - Freed L1s are added to the TAIl.
+ *  - Recently accessed L1s (where an 'access' is some change to one of
+ *    the userland pmaps which owns this L1) are moved to the TAIL.
+ */
+static TAILQ_HEAD(, l1_ttable) l1_lru_list;
+/*
+ * A list of all L1 tables
+ */
+static SLIST_HEAD(, l1_ttable) l1_list;
+static struct mtx l1_lru_lock;
+
+/*
+ * The l2_dtable tracks L2_BUCKET_SIZE worth of L1 slots.
+ *
+ * This is normally 16MB worth L2 page descriptors for any given pmap.
+ * Reference counts are maintained for L2 descriptors so they can be
+ * freed when empty.
+ */
+struct l2_dtable {
+	/* The number of L2 page descriptors allocated to this l2_dtable */
+	u_int l2_occupancy;
+
+	/* List of L2 page descriptors */
+	struct l2_bucket {
+		pt_entry_t *l2b_kva;	/* KVA of L2 Descriptor Table */
+		vm_paddr_t l2b_phys;	/* Physical address of same */
+		u_short l2b_l1idx;	/* This L2 table's L1 index */
+		u_short l2b_occupancy;	/* How many active descriptors */
+	} l2_bucket[L2_BUCKET_SIZE];
+};
+
+/* pmap_kenter_internal flags */
+#define KENTER_CACHE	0x1
+#define KENTER_USER	0x2
+
+/*
+ * Given an L1 table index, calculate the corresponding l2_dtable index
+ * and bucket index within the l2_dtable.
+ */
+#define	L2_IDX(l1idx)		(((l1idx) >> L2_BUCKET_LOG2) & \
+				 (L2_SIZE - 1))
+#define	L2_BUCKET(l1idx)	((l1idx) & (L2_BUCKET_SIZE - 1))
+
+/*
+ * Given a virtual address, this macro returns the
+ * virtual address required to drop into the next L2 bucket.
+ */
+#define	L2_NEXT_BUCKET(va)	(((va) & L1_S_FRAME) + L1_S_SIZE)
+
+/*
+ * We try to map the page tables write-through, if possible.  However, not
+ * all CPUs have a write-through cache mode, so on those we have to sync
+ * the cache when we frob page tables.
+ *
+ * We try to evaluate this at compile time, if possible.  However, it's
+ * not always possible to do that, hence this run-time var.
+ */
+int	pmap_needs_pte_sync;
+
+/*
+ * Macro to determine if a mapping might be resident in the
+ * instruction cache and/or TLB
+ */
+#define	PV_BEEN_EXECD(f)  (((f) & (PVF_REF | PVF_EXEC)) == (PVF_REF | PVF_EXEC))
+
+/*
+ * Macro to determine if a mapping might be resident in the
+ * data cache and/or TLB
+ */
+#define	PV_BEEN_REFD(f)   (((f) & PVF_REF) != 0)
+
+#ifndef PMAP_SHPGPERPROC
+#define PMAP_SHPGPERPROC 200
+#endif
+
+#define pmap_is_current(pm)	((pm) == pmap_kernel() || \
+            curproc->p_vmspace->vm_map.pmap == (pm))
+static uma_zone_t pvzone = NULL;
+uma_zone_t l2zone;
+static uma_zone_t l2table_zone;
+static vm_offset_t pmap_kernel_l2dtable_kva;
+static vm_offset_t pmap_kernel_l2ptp_kva;
+static vm_paddr_t pmap_kernel_l2ptp_phys;
+static int pv_entry_count=0, pv_entry_max=0, pv_entry_high_water=0;
+static struct rwlock pvh_global_lock;
+
+void pmap_copy_page_offs_generic(vm_paddr_t a_phys, vm_offset_t a_offs,
+    vm_paddr_t b_phys, vm_offset_t b_offs, int cnt);
+#if ARM_MMU_XSCALE == 1
+void pmap_copy_page_offs_xscale(vm_paddr_t a_phys, vm_offset_t a_offs,
+    vm_paddr_t b_phys, vm_offset_t b_offs, int cnt);
+#endif
+
+/*
+ * This list exists for the benefit of pmap_map_chunk().  It keeps track
+ * of the kernel L2 tables during bootstrap, so that pmap_map_chunk() can
+ * find them as necessary.
+ *
+ * Note that the data on this list MUST remain valid after initarm() returns,
+ * as pmap_bootstrap() uses it to contruct L2 table metadata.
+ */
+SLIST_HEAD(, pv_addr) kernel_pt_list = SLIST_HEAD_INITIALIZER(kernel_pt_list);
+
+static void
+pmap_init_l1(struct l1_ttable *l1, pd_entry_t *l1pt)
+{
+	int i;
+
+	l1->l1_kva = l1pt;
+	l1->l1_domain_use_count = 0;
+	l1->l1_domain_first = 0;
+
+	for (i = 0; i < PMAP_DOMAINS; i++)
+		l1->l1_domain_free[i] = i + 1;
+
+	/*
+	 * Copy the kernel's L1 entries to each new L1.
+	 */
+	if (l1pt != pmap_kernel()->pm_l1->l1_kva)
+		memcpy(l1pt, pmap_kernel()->pm_l1->l1_kva, L1_TABLE_SIZE);
+
+	if ((l1->l1_physaddr = pmap_extract(pmap_kernel(), (vm_offset_t)l1pt)) == 0)
+		panic("pmap_init_l1: can't get PA of L1 at %p", l1pt);
+	SLIST_INSERT_HEAD(&l1_list, l1, l1_link);
+	TAILQ_INSERT_TAIL(&l1_lru_list, l1, l1_lru);
+}
+
+static vm_offset_t
+kernel_pt_lookup(vm_paddr_t pa)
+{
+	struct pv_addr *pv;
+
+	SLIST_FOREACH(pv, &kernel_pt_list, pv_list) {
+		if (pv->pv_pa == pa)
+			return (pv->pv_va);
+	}
+	return (0);
+}
+
+#if ARM_MMU_GENERIC != 0
+void
+pmap_pte_init_generic(void)
+{
+
+	pte_l1_s_cache_mode = L1_S_B|L1_S_C;
+	pte_l1_s_cache_mask = L1_S_CACHE_MASK_generic;
+
+	pte_l2_l_cache_mode = L2_B|L2_C;
+	pte_l2_l_cache_mask = L2_L_CACHE_MASK_generic;
+
+	pte_l2_s_cache_mode = L2_B|L2_C;
+	pte_l2_s_cache_mask = L2_S_CACHE_MASK_generic;
+
+	/*
+	 * If we have a write-through cache, set B and C.  If
+	 * we have a write-back cache, then we assume setting
+	 * only C will make those pages write-through.
+	 */
+	if (cpufuncs.cf_dcache_wb_range == (void *) cpufunc_nullop) {
+		pte_l1_s_cache_mode_pt = L1_S_B|L1_S_C;
+		pte_l2_l_cache_mode_pt = L2_B|L2_C;
+		pte_l2_s_cache_mode_pt = L2_B|L2_C;
+	} else {
+		pte_l1_s_cache_mode_pt = L1_S_C;
+		pte_l2_l_cache_mode_pt = L2_C;
+		pte_l2_s_cache_mode_pt = L2_C;
+	}
+
+	pte_l2_s_prot_u = L2_S_PROT_U_generic;
+	pte_l2_s_prot_w = L2_S_PROT_W_generic;
+	pte_l2_s_prot_mask = L2_S_PROT_MASK_generic;
+
+	pte_l1_s_proto = L1_S_PROTO_generic;
+	pte_l1_c_proto = L1_C_PROTO_generic;
+	pte_l2_s_proto = L2_S_PROTO_generic;
+
+	pmap_copy_page_func = pmap_copy_page_generic;
+	pmap_copy_page_offs_func = pmap_copy_page_offs_generic;
+	pmap_zero_page_func = pmap_zero_page_generic;
+}
+
+#if defined(CPU_ARM9) && defined(ARM9_CACHE_WRITE_THROUGH)
+void
+pmap_pte_init_arm9(void)
+{
+
+	/*
+	 * ARM9 is compatible with generic, but we want to use
+	 * write-through caching for now.
+	 */
+	pmap_pte_init_generic();
+
+	pte_l1_s_cache_mode = L1_S_C;
+	pte_l2_l_cache_mode = L2_C;
+	pte_l2_s_cache_mode = L2_C;
+
+	pte_l1_s_cache_mode_pt = L1_S_C;
+	pte_l2_l_cache_mode_pt = L2_C;
+	pte_l2_s_cache_mode_pt = L2_C;
+}
+#endif /* CPU_ARM9 */
+#endif /* ARM_MMU_GENERIC != 0 */
+
+#if defined(CPU_ARM10)
+void
+pmap_pte_init_arm10(void)
+{
+
+	/*
+	 * ARM10 is compatible with generic, but we want to use
+	 * write-through caching for now.
+	 */
+	pmap_pte_init_generic();
+
+	pte_l1_s_cache_mode = L1_S_B | L1_S_C;
+	pte_l2_l_cache_mode = L2_B | L2_C;
+	pte_l2_s_cache_mode = L2_B | L2_C;
+
+	pte_l1_s_cache_mode_pt = L1_S_C;
+	pte_l2_l_cache_mode_pt = L2_C;
+	pte_l2_s_cache_mode_pt = L2_C;
+
+}
+#endif /* CPU_ARM10 */
+
+#if ARM_MMU_XSCALE == 1
+#if (ARM_NMMUS > 1) || defined (CPU_XSCALE_CORE3)
+static u_int xscale_use_minidata;
+#endif
+
+void
+pmap_pte_init_xscale(void)
+{
+	uint32_t auxctl;
+	int write_through = 0;
+
+	pte_l1_s_cache_mode = L1_S_B|L1_S_C|L1_S_XSCALE_P;
+	pte_l1_s_cache_mask = L1_S_CACHE_MASK_xscale;
+
+	pte_l2_l_cache_mode = L2_B|L2_C;
+	pte_l2_l_cache_mask = L2_L_CACHE_MASK_xscale;
+
+	pte_l2_s_cache_mode = L2_B|L2_C;
+	pte_l2_s_cache_mask = L2_S_CACHE_MASK_xscale;
+
+	pte_l1_s_cache_mode_pt = L1_S_C;
+	pte_l2_l_cache_mode_pt = L2_C;
+	pte_l2_s_cache_mode_pt = L2_C;
+#ifdef XSCALE_CACHE_READ_WRITE_ALLOCATE
+	/*
+	 * The XScale core has an enhanced mode where writes that
+	 * miss the cache cause a cache line to be allocated.  This
+	 * is significantly faster than the traditional, write-through
+	 * behavior of this case.
+	 */
+	pte_l1_s_cache_mode |= L1_S_XSCALE_TEX(TEX_XSCALE_X);
+	pte_l2_l_cache_mode |= L2_XSCALE_L_TEX(TEX_XSCALE_X);
+	pte_l2_s_cache_mode |= L2_XSCALE_T_TEX(TEX_XSCALE_X);
+#endif /* XSCALE_CACHE_READ_WRITE_ALLOCATE */
+#ifdef XSCALE_CACHE_WRITE_THROUGH
+	/*
+	 * Some versions of the XScale core have various bugs in
+	 * their cache units, the work-around for which is to run
+	 * the cache in write-through mode.  Unfortunately, this
+	 * has a major (negative) impact on performance.  So, we
+	 * go ahead and run fast-and-loose, in the hopes that we
+	 * don't line up the planets in a way that will trip the
+	 * bugs.
+	 *
+	 * However, we give you the option to be slow-but-correct.
+	 */
+	write_through = 1;
+#elif defined(XSCALE_CACHE_WRITE_BACK)
+	/* force write back cache mode */
+	write_through = 0;
+#elif defined(CPU_XSCALE_PXA2X0)
+	/*
+	 * Intel PXA2[15]0 processors are known to have a bug in
+	 * write-back cache on revision 4 and earlier (stepping
+	 * A[01] and B[012]).  Fixed for C0 and later.
+	 */
+	{
+		uint32_t id, type;
+
+		id = cpufunc_id();
+		type = id & ~(CPU_ID_XSCALE_COREREV_MASK|CPU_ID_REVISION_MASK);
+
+		if (type == CPU_ID_PXA250 || type == CPU_ID_PXA210) {
+			if ((id & CPU_ID_REVISION_MASK) < 5) {
+				/* write through for stepping A0-1 and B0-2 */
+				write_through = 1;
+			}
+		}
+	}
+#endif /* XSCALE_CACHE_WRITE_THROUGH */
+
+	if (write_through) {
+		pte_l1_s_cache_mode = L1_S_C;
+		pte_l2_l_cache_mode = L2_C;
+		pte_l2_s_cache_mode = L2_C;
+	}
+
+#if (ARM_NMMUS > 1)
+	xscale_use_minidata = 1;
+#endif
+
+	pte_l2_s_prot_u = L2_S_PROT_U_xscale;
+	pte_l2_s_prot_w = L2_S_PROT_W_xscale;
+	pte_l2_s_prot_mask = L2_S_PROT_MASK_xscale;
+
+	pte_l1_s_proto = L1_S_PROTO_xscale;
+	pte_l1_c_proto = L1_C_PROTO_xscale;
+	pte_l2_s_proto = L2_S_PROTO_xscale;
+
+#ifdef CPU_XSCALE_CORE3
+	pmap_copy_page_func = pmap_copy_page_generic;
+	pmap_copy_page_offs_func = pmap_copy_page_offs_generic;
+	pmap_zero_page_func = pmap_zero_page_generic;
+	xscale_use_minidata = 0;
+	/* Make sure it is L2-cachable */
+    	pte_l1_s_cache_mode |= L1_S_XSCALE_TEX(TEX_XSCALE_T);
+	pte_l1_s_cache_mode_pt = pte_l1_s_cache_mode &~ L1_S_XSCALE_P;
+	pte_l2_l_cache_mode |= L2_XSCALE_L_TEX(TEX_XSCALE_T) ;
+	pte_l2_l_cache_mode_pt = pte_l1_s_cache_mode;
+	pte_l2_s_cache_mode |= L2_XSCALE_T_TEX(TEX_XSCALE_T);
+	pte_l2_s_cache_mode_pt = pte_l2_s_cache_mode;
+
+#else
+	pmap_copy_page_func = pmap_copy_page_xscale;
+	pmap_copy_page_offs_func = pmap_copy_page_offs_xscale;
+	pmap_zero_page_func = pmap_zero_page_xscale;
+#endif
+
+	/*
+	 * Disable ECC protection of page table access, for now.
+	 */
+	__asm __volatile("mrc p15, 0, %0, c1, c0, 1" : "=r" (auxctl));
+	auxctl &= ~XSCALE_AUXCTL_P;
+	__asm __volatile("mcr p15, 0, %0, c1, c0, 1" : : "r" (auxctl));
+}
+
+/*
+ * xscale_setup_minidata:
+ *
+ *	Set up the mini-data cache clean area.  We require the
+ *	caller to allocate the right amount of physically and
+ *	virtually contiguous space.
+ */
+extern vm_offset_t xscale_minidata_clean_addr;
+extern vm_size_t xscale_minidata_clean_size; /* already initialized */
+void
+xscale_setup_minidata(vm_offset_t l1pt, vm_offset_t va, vm_paddr_t pa)
+{
+	pd_entry_t *pde = (pd_entry_t *) l1pt;
+	pt_entry_t *pte;
+	vm_size_t size;
+	uint32_t auxctl;
+
+	xscale_minidata_clean_addr = va;
+
+	/* Round it to page size. */
+	size = (xscale_minidata_clean_size + L2_S_OFFSET) & L2_S_FRAME;
+
+	for (; size != 0;
+	     va += L2_S_SIZE, pa += L2_S_SIZE, size -= L2_S_SIZE) {
+		pte = (pt_entry_t *) kernel_pt_lookup(
+		    pde[L1_IDX(va)] & L1_C_ADDR_MASK);
+		if (pte == NULL)
+			panic("xscale_setup_minidata: can't find L2 table for "
+			    "VA 0x%08x", (u_int32_t) va);
+		pte[l2pte_index(va)] =
+		    L2_S_PROTO | pa | L2_S_PROT(PTE_KERNEL, VM_PROT_READ) |
+		    L2_C | L2_XSCALE_T_TEX(TEX_XSCALE_X);
+	}
+
+	/*
+	 * Configure the mini-data cache for write-back with
+	 * read/write-allocate.
+	 *
+	 * NOTE: In order to reconfigure the mini-data cache, we must
+	 * make sure it contains no valid data!  In order to do that,
+	 * we must issue a global data cache invalidate command!
+	 *
+	 * WE ASSUME WE ARE RUNNING UN-CACHED WHEN THIS ROUTINE IS CALLED!
+	 * THIS IS VERY IMPORTANT!
+	 */
+
+	/* Invalidate data and mini-data. */
+	__asm __volatile("mcr p15, 0, %0, c7, c6, 0" : : "r" (0));
+	__asm __volatile("mrc p15, 0, %0, c1, c0, 1" : "=r" (auxctl));
+	auxctl = (auxctl & ~XSCALE_AUXCTL_MD_MASK) | XSCALE_AUXCTL_MD_WB_RWA;
+	__asm __volatile("mcr p15, 0, %0, c1, c0, 1" : : "r" (auxctl));
+}
+#endif
+
+/*
+ * Allocate an L1 translation table for the specified pmap.
+ * This is called at pmap creation time.
+ */
+static void
+pmap_alloc_l1(pmap_t pm)
+{
+	struct l1_ttable *l1;
+	u_int8_t domain;
+
+	/*
+	 * Remove the L1 at the head of the LRU list
+	 */
+	mtx_lock(&l1_lru_lock);
+	l1 = TAILQ_FIRST(&l1_lru_list);
+	TAILQ_REMOVE(&l1_lru_list, l1, l1_lru);
+
+	/*
+	 * Pick the first available domain number, and update
+	 * the link to the next number.
+	 */
+	domain = l1->l1_domain_first;
+	l1->l1_domain_first = l1->l1_domain_free[domain];
+
+	/*
+	 * If there are still free domain numbers in this L1,
+	 * put it back on the TAIL of the LRU list.
+	 */
+	if (++l1->l1_domain_use_count < PMAP_DOMAINS)
+		TAILQ_INSERT_TAIL(&l1_lru_list, l1, l1_lru);
+
+	mtx_unlock(&l1_lru_lock);
+
+	/*
+	 * Fix up the relevant bits in the pmap structure
+	 */
+	pm->pm_l1 = l1;
+	pm->pm_domain = domain + 1;
+}
+
+/*
+ * Free an L1 translation table.
+ * This is called at pmap destruction time.
+ */
+static void
+pmap_free_l1(pmap_t pm)
+{
+	struct l1_ttable *l1 = pm->pm_l1;
+
+	mtx_lock(&l1_lru_lock);
+
+	/*
+	 * If this L1 is currently on the LRU list, remove it.
+	 */
+	if (l1->l1_domain_use_count < PMAP_DOMAINS)
+		TAILQ_REMOVE(&l1_lru_list, l1, l1_lru);
+
+	/*
+	 * Free up the domain number which was allocated to the pmap
+	 */
+	l1->l1_domain_free[pm->pm_domain - 1] = l1->l1_domain_first;
+	l1->l1_domain_first = pm->pm_domain - 1;
+	l1->l1_domain_use_count--;
+
+	/*
+	 * The L1 now must have at least 1 free domain, so add
+	 * it back to the LRU list. If the use count is zero,
+	 * put it at the head of the list, otherwise it goes
+	 * to the tail.
+	 */
+	if (l1->l1_domain_use_count == 0) {
+		TAILQ_INSERT_HEAD(&l1_lru_list, l1, l1_lru);
+	}	else
+		TAILQ_INSERT_TAIL(&l1_lru_list, l1, l1_lru);
+
+	mtx_unlock(&l1_lru_lock);
+}
+
+/*
+ * Returns a pointer to the L2 bucket associated with the specified pmap
+ * and VA, or NULL if no L2 bucket exists for the address.
+ */
+static PMAP_INLINE struct l2_bucket *
+pmap_get_l2_bucket(pmap_t pm, vm_offset_t va)
+{
+	struct l2_dtable *l2;
+	struct l2_bucket *l2b;
+	u_short l1idx;
+
+	l1idx = L1_IDX(va);
+
+	if ((l2 = pm->pm_l2[L2_IDX(l1idx)]) == NULL ||
+	    (l2b = &l2->l2_bucket[L2_BUCKET(l1idx)])->l2b_kva == NULL)
+		return (NULL);
+
+	return (l2b);
+}
+
+/*
+ * Returns a pointer to the L2 bucket associated with the specified pmap
+ * and VA.
+ *
+ * If no L2 bucket exists, perform the necessary allocations to put an L2
+ * bucket/page table in place.
+ *
+ * Note that if a new L2 bucket/page was allocated, the caller *must*
+ * increment the bucket occupancy counter appropriately *before*
+ * releasing the pmap's lock to ensure no other thread or cpu deallocates
+ * the bucket/page in the meantime.
+ */
+static struct l2_bucket *
+pmap_alloc_l2_bucket(pmap_t pm, vm_offset_t va)
+{
+	struct l2_dtable *l2;
+	struct l2_bucket *l2b;
+	u_short l1idx;
+
+	l1idx = L1_IDX(va);
+
+	PMAP_ASSERT_LOCKED(pm);
+	rw_assert(&pvh_global_lock, RA_WLOCKED);
+	if ((l2 = pm->pm_l2[L2_IDX(l1idx)]) == NULL) {
+		/*
+		 * No mapping at this address, as there is
+		 * no entry in the L1 table.
+		 * Need to allocate a new l2_dtable.
+		 */
+		PMAP_UNLOCK(pm);
+		rw_wunlock(&pvh_global_lock);
+		if ((l2 = uma_zalloc(l2table_zone, M_NOWAIT)) == NULL) {
+			rw_wlock(&pvh_global_lock);
+			PMAP_LOCK(pm);
+			return (NULL);
+		}
+		rw_wlock(&pvh_global_lock);
+		PMAP_LOCK(pm);
+		if (pm->pm_l2[L2_IDX(l1idx)] != NULL) {
+			/*
+			 * Someone already allocated the l2_dtable while
+			 * we were doing the same.
+			 */
+			uma_zfree(l2table_zone, l2);
+			l2 = pm->pm_l2[L2_IDX(l1idx)];
+		} else {
+			bzero(l2, sizeof(*l2));
+			/*
+			 * Link it into the parent pmap
+			 */
+			pm->pm_l2[L2_IDX(l1idx)] = l2;
+		}
+	}
+
+	l2b = &l2->l2_bucket[L2_BUCKET(l1idx)];
+
+	/*
+	 * Fetch pointer to the L2 page table associated with the address.
+	 */
+	if (l2b->l2b_kva == NULL) {
+		pt_entry_t *ptep;
+
+		/*
+		 * No L2 page table has been allocated. Chances are, this
+		 * is because we just allocated the l2_dtable, above.
+		 */
+		PMAP_UNLOCK(pm);
+		rw_wunlock(&pvh_global_lock);
+		ptep = uma_zalloc(l2zone, M_NOWAIT);
+		rw_wlock(&pvh_global_lock);
+		PMAP_LOCK(pm);
+		if (l2b->l2b_kva != 0) {
+			/* We lost the race. */
+			uma_zfree(l2zone, ptep);
+			return (l2b);
+		}
+		l2b->l2b_phys = vtophys(ptep);
+		if (ptep == NULL) {
+			/*
+			 * Oops, no more L2 page tables available at this
+			 * time. We may need to deallocate the l2_dtable
+			 * if we allocated a new one above.
+			 */
+			if (l2->l2_occupancy == 0) {
+				pm->pm_l2[L2_IDX(l1idx)] = NULL;
+				uma_zfree(l2table_zone, l2);
+			}
+			return (NULL);
+		}
+
+		l2->l2_occupancy++;
+		l2b->l2b_kva = ptep;
+		l2b->l2b_l1idx = l1idx;
+	}
+
+	return (l2b);
+}
+
+static PMAP_INLINE void
+#ifndef PMAP_INCLUDE_PTE_SYNC
+pmap_free_l2_ptp(pt_entry_t *l2)
+#else
+pmap_free_l2_ptp(boolean_t need_sync, pt_entry_t *l2)
+#endif
+{
+#ifdef PMAP_INCLUDE_PTE_SYNC
+	/*
+	 * Note: With a write-back cache, we may need to sync this
+	 * L2 table before re-using it.
+	 * This is because it may have belonged to a non-current
+	 * pmap, in which case the cache syncs would have been
+	 * skipped when the pages were being unmapped. If the
+	 * L2 table were then to be immediately re-allocated to
+	 * the *current* pmap, it may well contain stale mappings
+	 * which have not yet been cleared by a cache write-back
+	 * and so would still be visible to the mmu.
+	 */
+	if (need_sync)
+		PTE_SYNC_RANGE(l2, L2_TABLE_SIZE_REAL / sizeof(pt_entry_t));
+#endif
+	uma_zfree(l2zone, l2);
+}
+/*
+ * One or more mappings in the specified L2 descriptor table have just been
+ * invalidated.
+ *
+ * Garbage collect the metadata and descriptor table itself if necessary.
+ *
+ * The pmap lock must be acquired when this is called (not necessary
+ * for the kernel pmap).
+ */
+static void
+pmap_free_l2_bucket(pmap_t pm, struct l2_bucket *l2b, u_int count)
+{
+	struct l2_dtable *l2;
+	pd_entry_t *pl1pd, l1pd;
+	pt_entry_t *ptep;
+	u_short l1idx;
+
+
+	/*
+	 * Update the bucket's reference count according to how many
+	 * PTEs the caller has just invalidated.
+	 */
+	l2b->l2b_occupancy -= count;
+
+	/*
+	 * Note:
+	 *
+	 * Level 2 page tables allocated to the kernel pmap are never freed
+	 * as that would require checking all Level 1 page tables and
+	 * removing any references to the Level 2 page table. See also the
+	 * comment elsewhere about never freeing bootstrap L2 descriptors.
+	 *
+	 * We make do with just invalidating the mapping in the L2 table.
+	 *
+	 * This isn't really a big deal in practice and, in fact, leads
+	 * to a performance win over time as we don't need to continually
+	 * alloc/free.
+	 */
+	if (l2b->l2b_occupancy > 0 || pm == pmap_kernel())
+		return;
+
+	/*
+	 * There are no more valid mappings in this level 2 page table.
+	 * Go ahead and NULL-out the pointer in the bucket, then
+	 * free the page table.
+	 */
+	l1idx = l2b->l2b_l1idx;
+	ptep = l2b->l2b_kva;
+	l2b->l2b_kva = NULL;
+
+	pl1pd = &pm->pm_l1->l1_kva[l1idx];
+
+	/*
+	 * If the L1 slot matches the pmap's domain
+	 * number, then invalidate it.
+	 */
+	l1pd = *pl1pd & (L1_TYPE_MASK | L1_C_DOM_MASK);
+	if (l1pd == (L1_C_DOM(pm->pm_domain) | L1_TYPE_C)) {
+		*pl1pd = 0;
+		PTE_SYNC(pl1pd);
+	}
+
+	/*
+	 * Release the L2 descriptor table back to the pool cache.
+	 */
+#ifndef PMAP_INCLUDE_PTE_SYNC
+	pmap_free_l2_ptp(ptep);
+#else
+	pmap_free_l2_ptp(!pmap_is_current(pm), ptep);
+#endif
+
+	/*
+	 * Update the reference count in the associated l2_dtable
+	 */
+	l2 = pm->pm_l2[L2_IDX(l1idx)];
+	if (--l2->l2_occupancy > 0)
+		return;
+
+	/*
+	 * There are no more valid mappings in any of the Level 1
+	 * slots managed by this l2_dtable. Go ahead and NULL-out
+	 * the pointer in the parent pmap and free the l2_dtable.
+	 */
+	pm->pm_l2[L2_IDX(l1idx)] = NULL;
+	uma_zfree(l2table_zone, l2);
+}
+
+/*
+ * Pool cache constructors for L2 descriptor tables, metadata and pmap
+ * structures.
+ */
+static int
+pmap_l2ptp_ctor(void *mem, int size, void *arg, int flags)
+{
+#ifndef PMAP_INCLUDE_PTE_SYNC
+	struct l2_bucket *l2b;
+	pt_entry_t *ptep, pte;
+
+	vm_offset_t va = (vm_offset_t)mem & ~PAGE_MASK;
+
+	/*
+	 * The mappings for these page tables were initially made using
+	 * pmap_kenter() by the pool subsystem. Therefore, the cache-
+	 * mode will not be right for page table mappings. To avoid
+	 * polluting the pmap_kenter() code with a special case for
+	 * page tables, we simply fix up the cache-mode here if it's not
+	 * correct.
+	 */
+		l2b = pmap_get_l2_bucket(pmap_kernel(), va);
+		ptep = &l2b->l2b_kva[l2pte_index(va)];
+		pte = *ptep;
+		
+		if ((pte & L2_S_CACHE_MASK) != pte_l2_s_cache_mode_pt) {
+			/*
+			 * Page tables must have the cache-mode set to
+			 * Write-Thru.
+			 */
+			*ptep = (pte & ~L2_S_CACHE_MASK) | pte_l2_s_cache_mode_pt;
+			PTE_SYNC(ptep);
+			cpu_tlb_flushD_SE(va);
+			cpu_cpwait();
+		}
+#endif
+	memset(mem, 0, L2_TABLE_SIZE_REAL);
+	PTE_SYNC_RANGE(mem, L2_TABLE_SIZE_REAL / sizeof(pt_entry_t));
+	return (0);
+}
+
+/*
+ * A bunch of routines to conditionally flush the caches/TLB depending
+ * on whether the specified pmap actually needs to be flushed at any
+ * given time.
+ */
+static PMAP_INLINE void
+pmap_tlb_flushID_SE(pmap_t pm, vm_offset_t va)
+{
+
+	if (pmap_is_current(pm))
+		cpu_tlb_flushID_SE(va);
+}
+
+static PMAP_INLINE void
+pmap_tlb_flushD_SE(pmap_t pm, vm_offset_t va)
+{
+
+	if (pmap_is_current(pm))
+		cpu_tlb_flushD_SE(va);
+}
+
+static PMAP_INLINE void
+pmap_tlb_flushID(pmap_t pm)
+{
+
+	if (pmap_is_current(pm))
+		cpu_tlb_flushID();
+}
+static PMAP_INLINE void
+pmap_tlb_flushD(pmap_t pm)
+{
+
+	if (pmap_is_current(pm))
+		cpu_tlb_flushD();
+}
+
+static int
+pmap_has_valid_mapping(pmap_t pm, vm_offset_t va)
+{
+	pd_entry_t *pde;
+	pt_entry_t *ptep;
+
+	if (pmap_get_pde_pte(pm, va, &pde, &ptep) &&
+	    ptep && ((*ptep & L2_TYPE_MASK) != L2_TYPE_INV))
+		return (1);
+
+	return (0);
+}
+
+static PMAP_INLINE void
+pmap_idcache_wbinv_range(pmap_t pm, vm_offset_t va, vm_size_t len)
+{
+	vm_size_t rest;
+
+	CTR4(KTR_PMAP, "pmap_dcache_wbinv_range: pmap %p is_kernel %d va 0x%08x"
+	    " len 0x%x ", pm, pm == pmap_kernel(), va, len);
+
+	if (pmap_is_current(pm) || pm == pmap_kernel()) {
+		rest = MIN(PAGE_SIZE - (va & PAGE_MASK), len);
+		while (len > 0) {
+			if (pmap_has_valid_mapping(pm, va)) {
+				cpu_idcache_wbinv_range(va, rest);
+				cpu_l2cache_wbinv_range(va, rest);
+			}
+			len -= rest;
+			va += rest;
+			rest = MIN(PAGE_SIZE, len);
+		}
+	}
+}
+
+static PMAP_INLINE void
+pmap_dcache_wb_range(pmap_t pm, vm_offset_t va, vm_size_t len, boolean_t do_inv,
+    boolean_t rd_only)
+{
+	vm_size_t rest;
+
+	CTR4(KTR_PMAP, "pmap_dcache_wb_range: pmap %p is_kernel %d va 0x%08x "
+	    "len 0x%x ", pm, pm == pmap_kernel(), va, len);
+	CTR2(KTR_PMAP, " do_inv %d rd_only %d", do_inv, rd_only);
+
+	if (pmap_is_current(pm)) {
+		rest = MIN(PAGE_SIZE - (va & PAGE_MASK), len);
+		while (len > 0) {
+			if (pmap_has_valid_mapping(pm, va)) {
+				if (do_inv && rd_only) {
+					cpu_dcache_inv_range(va, rest);
+					cpu_l2cache_inv_range(va, rest);
+				} else if (do_inv) {
+					cpu_dcache_wbinv_range(va, rest);
+					cpu_l2cache_wbinv_range(va, rest);
+				} else if (!rd_only) {
+					cpu_dcache_wb_range(va, rest);
+					cpu_l2cache_wb_range(va, rest);
+				}
+			}
+			len -= rest;
+			va += rest;
+
+			rest = MIN(PAGE_SIZE, len);
+		}
+	}
+}
+
+static PMAP_INLINE void
+pmap_idcache_wbinv_all(pmap_t pm)
+{
+
+	if (pmap_is_current(pm)) {
+		cpu_idcache_wbinv_all();
+		cpu_l2cache_wbinv_all();
+	}
+}
+
+#ifdef notyet
+static PMAP_INLINE void
+pmap_dcache_wbinv_all(pmap_t pm)
+{
+
+	if (pmap_is_current(pm)) {
+		cpu_dcache_wbinv_all();
+		cpu_l2cache_wbinv_all();
+	}
+}
+#endif
+
+/*
+ * PTE_SYNC_CURRENT:
+ *
+ *     Make sure the pte is written out to RAM.
+ *     We need to do this for one of two cases:
+ *       - We're dealing with the kernel pmap
+ *       - There is no pmap active in the cache/tlb.
+ *       - The specified pmap is 'active' in the cache/tlb.
+ */
+#ifdef PMAP_INCLUDE_PTE_SYNC
+#define	PTE_SYNC_CURRENT(pm, ptep)	\
+do {					\
+	if (PMAP_NEEDS_PTE_SYNC && 	\
+	    pmap_is_current(pm))	\
+		PTE_SYNC(ptep);		\
+} while (/*CONSTCOND*/0)
+#else
+#define	PTE_SYNC_CURRENT(pm, ptep)	/* nothing */
+#endif
+
+/*
+ * cacheable == -1 means we must make the entry uncacheable, 1 means
+ * cacheable;
+ */
+static __inline void
+pmap_set_cache_entry(pv_entry_t pv, pmap_t pm, vm_offset_t va, int cacheable)
+{
+	struct l2_bucket *l2b;
+	pt_entry_t *ptep, pte;
+
+	l2b = pmap_get_l2_bucket(pv->pv_pmap, pv->pv_va);
+	ptep = &l2b->l2b_kva[l2pte_index(pv->pv_va)];
+
+	if (cacheable == 1) {
+		pte = (*ptep & ~L2_S_CACHE_MASK) | pte_l2_s_cache_mode;
+		if (l2pte_valid(pte)) {
+			if (PV_BEEN_EXECD(pv->pv_flags)) {
+				pmap_tlb_flushID_SE(pv->pv_pmap, pv->pv_va);
+			} else if (PV_BEEN_REFD(pv->pv_flags)) {
+				pmap_tlb_flushD_SE(pv->pv_pmap, pv->pv_va);
+			}
+		}
+	} else {
+		pte = *ptep &~ L2_S_CACHE_MASK;
+		if ((va != pv->pv_va || pm != pv->pv_pmap) &&
+			    l2pte_valid(pte)) {
+			if (PV_BEEN_EXECD(pv->pv_flags)) {
+				pmap_idcache_wbinv_range(pv->pv_pmap,
+					    pv->pv_va, PAGE_SIZE);
+				pmap_tlb_flushID_SE(pv->pv_pmap, pv->pv_va);
+			} else if (PV_BEEN_REFD(pv->pv_flags)) {
+				pmap_dcache_wb_range(pv->pv_pmap,
+					    pv->pv_va, PAGE_SIZE, TRUE,
+					    (pv->pv_flags & PVF_WRITE) == 0);
+				pmap_tlb_flushD_SE(pv->pv_pmap,
+					    pv->pv_va);
+			}
+		}
+	}
+	*ptep = pte;
+	PTE_SYNC_CURRENT(pv->pv_pmap, ptep);
+}
+
+static void
+pmap_fix_cache(struct vm_page *pg, pmap_t pm, vm_offset_t va)
+{
+	int pmwc = 0;
+	int writable = 0, kwritable = 0, uwritable = 0;
+	int entries = 0, kentries = 0, uentries = 0;
+	struct pv_entry *pv;
+
+	rw_assert(&pvh_global_lock, RA_WLOCKED);
+
+	/* the cache gets written back/invalidated on context switch.
+	 * therefore, if a user page shares an entry in the same page or
+	 * with the kernel map and at least one is writable, then the
+	 * cache entry must be set write-through.
+	 */
+
+	TAILQ_FOREACH(pv, &pg->md.pv_list, pv_list) {
+			/* generate a count of the pv_entry uses */
+		if (pv->pv_flags & PVF_WRITE) {
+			if (pv->pv_pmap == pmap_kernel())
+				kwritable++;
+			else if (pv->pv_pmap == pm)
+				uwritable++;
+			writable++;
+		}
+		if (pv->pv_pmap == pmap_kernel())
+			kentries++;
+		else {
+			if (pv->pv_pmap == pm)
+				uentries++;
+			entries++;
+		}
+	}
+		/*
+		 * check if the user duplicate mapping has
+		 * been removed.
+		 */
+	if ((pm != pmap_kernel()) && (((uentries > 1) && uwritable) ||
+	    (uwritable > 1)))
+			pmwc = 1;
+
+	TAILQ_FOREACH(pv, &pg->md.pv_list, pv_list) {
+		/* check for user uncachable conditions - order is important */
+		if (pm != pmap_kernel() &&
+		    (pv->pv_pmap == pm || pv->pv_pmap == pmap_kernel())) {
+
+			if ((uentries > 1 && uwritable) || uwritable > 1) {
+
+				/* user duplicate mapping */
+				if (pv->pv_pmap != pmap_kernel())
+					pv->pv_flags |= PVF_MWC;
+
+				if (!(pv->pv_flags & PVF_NC)) {
+					pv->pv_flags |= PVF_NC;
+					pmap_set_cache_entry(pv, pm, va, -1);
+				}
+				continue;
+			} else	/* no longer a duplicate user */
+				pv->pv_flags &= ~PVF_MWC;
+		}
+
+		/*
+		 * check for kernel uncachable conditions
+		 * kernel writable or kernel readable with writable user entry
+		 */
+		if ((kwritable && (entries || kentries > 1)) ||
+		    (kwritable > 1) ||
+		    ((kwritable != writable) && kentries &&
+		     (pv->pv_pmap == pmap_kernel() ||
+		      (pv->pv_flags & PVF_WRITE) ||
+		      (pv->pv_flags & PVF_MWC)))) {
+
+			if (!(pv->pv_flags & PVF_NC)) {
+				pv->pv_flags |= PVF_NC;
+				pmap_set_cache_entry(pv, pm, va, -1);
+			}
+			continue;
+		}
+
+			/* kernel and user are cachable */
+		if ((pm == pmap_kernel()) && !(pv->pv_flags & PVF_MWC) &&
+		    (pv->pv_flags & PVF_NC)) {
+
+			pv->pv_flags &= ~PVF_NC;
+			if (pg->md.pv_memattr != VM_MEMATTR_UNCACHEABLE)
+				pmap_set_cache_entry(pv, pm, va, 1);
+			continue;
+		}
+			/* user is no longer sharable and writable */
+		if (pm != pmap_kernel() &&
+		    (pv->pv_pmap == pm || pv->pv_pmap == pmap_kernel()) &&
+		    !pmwc && (pv->pv_flags & PVF_NC)) {
+
+			pv->pv_flags &= ~(PVF_NC | PVF_MWC);
+			if (pg->md.pv_memattr != VM_MEMATTR_UNCACHEABLE)
+				pmap_set_cache_entry(pv, pm, va, 1);
+		}
+	}
+
+	if ((kwritable == 0) && (writable == 0)) {
+		pg->md.pvh_attrs &= ~PVF_MOD;
+		vm_page_aflag_clear(pg, PGA_WRITEABLE);
+		return;
+	}
+}
+
+/*
+ * Modify pte bits for all ptes corresponding to the given physical address.
+ * We use `maskbits' rather than `clearbits' because we're always passing
+ * constants and the latter would require an extra inversion at run-time.
+ */
+static int
+pmap_clearbit(struct vm_page *pg, u_int maskbits)
+{
+	struct l2_bucket *l2b;
+	struct pv_entry *pv;
+	pt_entry_t *ptep, npte, opte;
+	pmap_t pm;
+	vm_offset_t va;
+	u_int oflags;
+	int count = 0;
+
+	rw_wlock(&pvh_global_lock);
+
+	if (maskbits & PVF_WRITE)
+		maskbits |= PVF_MOD;
+	/*
+	 * Clear saved attributes (modify, reference)
+	 */
+	pg->md.pvh_attrs &= ~(maskbits & (PVF_MOD | PVF_REF));
+
+	if (TAILQ_EMPTY(&pg->md.pv_list)) {
+		rw_wunlock(&pvh_global_lock);
+		return (0);
+	}
+
+	/*
+	 * Loop over all current mappings setting/clearing as appropos
+	 */
+	TAILQ_FOREACH(pv, &pg->md.pv_list, pv_list) {
+		va = pv->pv_va;
+		pm = pv->pv_pmap;
+		oflags = pv->pv_flags;
+
+		if (!(oflags & maskbits)) {
+			if ((maskbits & PVF_WRITE) && (pv->pv_flags & PVF_NC)) {
+				if (pg->md.pv_memattr != 
+				    VM_MEMATTR_UNCACHEABLE) {
+					PMAP_LOCK(pm);
+					l2b = pmap_get_l2_bucket(pm, va);
+					ptep = &l2b->l2b_kva[l2pte_index(va)];
+					*ptep |= pte_l2_s_cache_mode;
+					PTE_SYNC(ptep);
+					PMAP_UNLOCK(pm);
+				}
+				pv->pv_flags &= ~(PVF_NC | PVF_MWC);
+			}
+			continue;
+		}
+		pv->pv_flags &= ~maskbits;
+
+		PMAP_LOCK(pm);
+
+		l2b = pmap_get_l2_bucket(pm, va);
+
+		ptep = &l2b->l2b_kva[l2pte_index(va)];
+		npte = opte = *ptep;
+
+		if (maskbits & (PVF_WRITE|PVF_MOD)) {
+			if ((pv->pv_flags & PVF_NC)) {
+				/*
+				 * Entry is not cacheable:
+				 *
+				 * Don't turn caching on again if this is a
+				 * modified emulation. This would be
+				 * inconsitent with the settings created by
+				 * pmap_fix_cache(). Otherwise, it's safe
+				 * to re-enable cacheing.
+				 *
+				 * There's no need to call pmap_fix_cache()
+				 * here: all pages are losing their write
+				 * permission.
+				 */
+				if (maskbits & PVF_WRITE) {
+					if (pg->md.pv_memattr !=
+					    VM_MEMATTR_UNCACHEABLE)
+						npte |= pte_l2_s_cache_mode;
+					pv->pv_flags &= ~(PVF_NC | PVF_MWC);
+				}
+			} else
+			if (opte & L2_S_PROT_W) {
+				vm_page_dirty(pg);
+				/*
+				 * Entry is writable/cacheable: check if pmap
+				 * is current if it is flush it, otherwise it
+				 * won't be in the cache
+				 */
+				if (PV_BEEN_EXECD(oflags))
+					pmap_idcache_wbinv_range(pm, pv->pv_va,
+					    PAGE_SIZE);
+				else
+				if (PV_BEEN_REFD(oflags))
+					pmap_dcache_wb_range(pm, pv->pv_va,
+					    PAGE_SIZE,
+					    (maskbits & PVF_REF) ? TRUE : FALSE,
+					    FALSE);
+			}
+
+			/* make the pte read only */
+			npte &= ~L2_S_PROT_W;
+		}
+
+		if (maskbits & PVF_REF) {
+			if ((pv->pv_flags & PVF_NC) == 0 &&
+			    (maskbits & (PVF_WRITE|PVF_MOD)) == 0) {
+				/*
+				 * Check npte here; we may have already
+				 * done the wbinv above, and the validity
+				 * of the PTE is the same for opte and
+				 * npte.
+				 */
+				if (npte & L2_S_PROT_W) {
+					if (PV_BEEN_EXECD(oflags))
+						pmap_idcache_wbinv_range(pm,
+						    pv->pv_va, PAGE_SIZE);
+					else
+					if (PV_BEEN_REFD(oflags))
+						pmap_dcache_wb_range(pm,
+						    pv->pv_va, PAGE_SIZE,
+						    TRUE, FALSE);
+				} else
+				if ((npte & L2_TYPE_MASK) != L2_TYPE_INV) {
+					/* XXXJRT need idcache_inv_range */
+					if (PV_BEEN_EXECD(oflags))
+						pmap_idcache_wbinv_range(pm,
+						    pv->pv_va, PAGE_SIZE);
+					else
+					if (PV_BEEN_REFD(oflags))
+						pmap_dcache_wb_range(pm,
+						    pv->pv_va, PAGE_SIZE,
+						    TRUE, TRUE);
+				}
+			}
+
+			/*
+			 * Make the PTE invalid so that we will take a
+			 * page fault the next time the mapping is
+			 * referenced.
+			 */
+			npte &= ~L2_TYPE_MASK;
+			npte |= L2_TYPE_INV;
+		}
+
+		if (npte != opte) {
+			count++;
+			*ptep = npte;
+			PTE_SYNC(ptep);
+			/* Flush the TLB entry if a current pmap. */
+			if (PV_BEEN_EXECD(oflags))
+				pmap_tlb_flushID_SE(pm, pv->pv_va);
+			else
+			if (PV_BEEN_REFD(oflags))
+				pmap_tlb_flushD_SE(pm, pv->pv_va);
+		}
+
+		PMAP_UNLOCK(pm);
+
+	}
+
+	if (maskbits & PVF_WRITE)
+		vm_page_aflag_clear(pg, PGA_WRITEABLE);
+	rw_wunlock(&pvh_global_lock);
+	return (count);
+}
+
+/*
+ * main pv_entry manipulation functions:
+ *   pmap_enter_pv: enter a mapping onto a vm_page list
+ *   pmap_remove_pv: remove a mappiing from a vm_page list
+ *
+ * NOTE: pmap_enter_pv expects to lock the pvh itself
+ *       pmap_remove_pv expects the caller to lock the pvh before calling
+ */
+
+/*
+ * pmap_enter_pv: enter a mapping onto a vm_page's PV list
+ *
+ * => caller should hold the proper lock on pvh_global_lock
+ * => caller should have pmap locked
+ * => we will (someday) gain the lock on the vm_page's PV list
+ * => caller should adjust ptp's wire_count before calling
+ * => caller should not adjust pmap's wire_count
+ */
+static void
+pmap_enter_pv(struct vm_page *pg, struct pv_entry *pve, pmap_t pm,
+    vm_offset_t va, u_int flags)
+{
+
+	rw_assert(&pvh_global_lock, RA_WLOCKED);
+	PMAP_ASSERT_LOCKED(pm);
+	if (pg->md.pv_kva != 0) {
+		pve->pv_pmap = kernel_pmap;
+		pve->pv_va = pg->md.pv_kva;
+		pve->pv_flags = PVF_WRITE | PVF_UNMAN;
+		if (pm != kernel_pmap)
+			PMAP_LOCK(kernel_pmap);
+		TAILQ_INSERT_HEAD(&pg->md.pv_list, pve, pv_list);
+		TAILQ_INSERT_HEAD(&kernel_pmap->pm_pvlist, pve, pv_plist);
+		if (pm != kernel_pmap)
+			PMAP_UNLOCK(kernel_pmap);
+		pg->md.pv_kva = 0;
+		if ((pve = pmap_get_pv_entry()) == NULL)
+			panic("pmap_kenter_pv: no pv entries");
+	}
+	pve->pv_pmap = pm;
+	pve->pv_va = va;
+	pve->pv_flags = flags;
+	TAILQ_INSERT_HEAD(&pg->md.pv_list, pve, pv_list);
+	TAILQ_INSERT_HEAD(&pm->pm_pvlist, pve, pv_plist);
+	pg->md.pvh_attrs |= flags & (PVF_REF | PVF_MOD);
+	if (pve->pv_flags & PVF_WIRED)
+		++pm->pm_stats.wired_count;
+	vm_page_aflag_set(pg, PGA_REFERENCED);
+}
+
+/*
+ *
+ * pmap_find_pv: Find a pv entry
+ *
+ * => caller should hold lock on vm_page
+ */
+static PMAP_INLINE struct pv_entry *
+pmap_find_pv(struct vm_page *pg, pmap_t pm, vm_offset_t va)
+{
+	struct pv_entry *pv;
+
+	rw_assert(&pvh_global_lock, RA_WLOCKED);
+	TAILQ_FOREACH(pv, &pg->md.pv_list, pv_list)
+	    if (pm == pv->pv_pmap && va == pv->pv_va)
+		    break;
+	return (pv);
+}
+
+/*
+ * vector_page_setprot:
+ *
+ *	Manipulate the protection of the vector page.
+ */
+void
+vector_page_setprot(int prot)
+{
+	struct l2_bucket *l2b;
+	pt_entry_t *ptep;
+
+	l2b = pmap_get_l2_bucket(pmap_kernel(), vector_page);
+
+	ptep = &l2b->l2b_kva[l2pte_index(vector_page)];
+
+	*ptep = (*ptep & ~L1_S_PROT_MASK) | L2_S_PROT(PTE_KERNEL, prot);
+	PTE_SYNC(ptep);
+	cpu_tlb_flushD_SE(vector_page);
+	cpu_cpwait();
+}
+
+/*
+ * pmap_remove_pv: try to remove a mapping from a pv_list
+ *
+ * => caller should hold proper lock on pmap_main_lock
+ * => pmap should be locked
+ * => caller should hold lock on vm_page [so that attrs can be adjusted]
+ * => caller should adjust ptp's wire_count and free PTP if needed
+ * => caller should NOT adjust pmap's wire_count
+ * => we return the removed pve
+ */
+
+static void
+pmap_nuke_pv(struct vm_page *pg, pmap_t pm, struct pv_entry *pve)
+{
+
+	struct pv_entry *pv;
+	rw_assert(&pvh_global_lock, RA_WLOCKED);
+	PMAP_ASSERT_LOCKED(pm);
+	TAILQ_REMOVE(&pg->md.pv_list, pve, pv_list);
+	TAILQ_REMOVE(&pm->pm_pvlist, pve, pv_plist);
+	if (pve->pv_flags & PVF_WIRED)
+		--pm->pm_stats.wired_count;
+	if (pg->md.pvh_attrs & PVF_MOD)
+		vm_page_dirty(pg);
+	if (TAILQ_FIRST(&pg->md.pv_list) == NULL)
+		pg->md.pvh_attrs &= ~PVF_REF;
+       	else
+		vm_page_aflag_set(pg, PGA_REFERENCED);
+	if ((pve->pv_flags & PVF_NC) && ((pm == pmap_kernel()) ||
+	     (pve->pv_flags & PVF_WRITE) || !(pve->pv_flags & PVF_MWC)))
+		pmap_fix_cache(pg, pm, 0);
+	else if (pve->pv_flags & PVF_WRITE) {
+		TAILQ_FOREACH(pve, &pg->md.pv_list, pv_list)
+		    if (pve->pv_flags & PVF_WRITE)
+			    break;
+		if (!pve) {
+			pg->md.pvh_attrs &= ~PVF_MOD;
+			vm_page_aflag_clear(pg, PGA_WRITEABLE);
+		}
+	}
+	pv = TAILQ_FIRST(&pg->md.pv_list);
+	if (pv != NULL && (pv->pv_flags & PVF_UNMAN) &&
+	    TAILQ_NEXT(pv, pv_list) == NULL) {
+		pm = kernel_pmap;
+		pg->md.pv_kva = pv->pv_va;
+			/* a recursive pmap_nuke_pv */
+		TAILQ_REMOVE(&pg->md.pv_list, pv, pv_list);
+		TAILQ_REMOVE(&pm->pm_pvlist, pv, pv_plist);
+		if (pv->pv_flags & PVF_WIRED)
+			--pm->pm_stats.wired_count;
+		pg->md.pvh_attrs &= ~PVF_REF;
+		pg->md.pvh_attrs &= ~PVF_MOD;
+		vm_page_aflag_clear(pg, PGA_WRITEABLE);
+		pmap_free_pv_entry(pv);
+	}
+}
+
+static struct pv_entry *
+pmap_remove_pv(struct vm_page *pg, pmap_t pm, vm_offset_t va)
+{
+	struct pv_entry *pve;
+
+	rw_assert(&pvh_global_lock, RA_WLOCKED);
+	pve = TAILQ_FIRST(&pg->md.pv_list);
+
+	while (pve) {
+		if (pve->pv_pmap == pm && pve->pv_va == va) {	/* match? */
+			pmap_nuke_pv(pg, pm, pve);
+			break;
+		}
+		pve = TAILQ_NEXT(pve, pv_list);
+	}
+
+	if (pve == NULL && pg->md.pv_kva == va)
+		pg->md.pv_kva = 0;
+
+	return(pve);				/* return removed pve */
+}
+/*
+ *
+ * pmap_modify_pv: Update pv flags
+ *
+ * => caller should hold lock on vm_page [so that attrs can be adjusted]
+ * => caller should NOT adjust pmap's wire_count
+ * => we return the old flags
+ *
+ * Modify a physical-virtual mapping in the pv table
+ */
+static u_int
+pmap_modify_pv(struct vm_page *pg, pmap_t pm, vm_offset_t va,
+    u_int clr_mask, u_int set_mask)
+{
+	struct pv_entry *npv;
+	u_int flags, oflags;
+
+	PMAP_ASSERT_LOCKED(pm);
+	rw_assert(&pvh_global_lock, RA_WLOCKED);
+	if ((npv = pmap_find_pv(pg, pm, va)) == NULL)
+		return (0);
+
+	/*
+	 * There is at least one VA mapping this page.
+	 */
+
+	if (clr_mask & (PVF_REF | PVF_MOD))
+		pg->md.pvh_attrs |= set_mask & (PVF_REF | PVF_MOD);
+
+	oflags = npv->pv_flags;
+	npv->pv_flags = flags = (oflags & ~clr_mask) | set_mask;
+
+	if ((flags ^ oflags) & PVF_WIRED) {
+		if (flags & PVF_WIRED)
+			++pm->pm_stats.wired_count;
+		else
+			--pm->pm_stats.wired_count;
+	}
+
+	if ((flags ^ oflags) & PVF_WRITE)
+		pmap_fix_cache(pg, pm, 0);
+
+	return (oflags);
+}
+
+/* Function to set the debug level of the pmap code */
+#ifdef PMAP_DEBUG
+void
+pmap_debug(int level)
+{
+	pmap_debug_level = level;
+	dprintf("pmap_debug: level=%d\n", pmap_debug_level);
+}
+#endif  /* PMAP_DEBUG */
+
+void
+pmap_pinit0(struct pmap *pmap)
+{
+	PDEBUG(1, printf("pmap_pinit0: pmap = %08x\n", (u_int32_t) pmap));
+
+	bcopy(kernel_pmap, pmap, sizeof(*pmap));
+	bzero(&pmap->pm_mtx, sizeof(pmap->pm_mtx));
+	PMAP_LOCK_INIT(pmap);
+}
+
+/*
+ *	Initialize a vm_page's machine-dependent fields.
+ */
+void
+pmap_page_init(vm_page_t m)
+{
+
+	TAILQ_INIT(&m->md.pv_list);
+	m->md.pv_memattr = VM_MEMATTR_DEFAULT;
+}
+
+/*
+ *      Initialize the pmap module.
+ *      Called by vm_init, to initialize any structures that the pmap
+ *      system needs to map virtual memory.
+ */
+void
+pmap_init(void)
+{
+	int shpgperproc = PMAP_SHPGPERPROC;
+
+	l2zone = uma_zcreate("L2 Table", L2_TABLE_SIZE_REAL, pmap_l2ptp_ctor,
+	    NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_VM | UMA_ZONE_NOFREE);
+	l2table_zone = uma_zcreate("L2 Table", sizeof(struct l2_dtable), NULL,
+	    NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_VM | UMA_ZONE_NOFREE);
+
+	/*
+	 * Initialize the PV entry allocator.
+	 */
+	pvzone = uma_zcreate("PV ENTRY", sizeof (struct pv_entry), NULL, NULL,
+	    NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_VM | UMA_ZONE_NOFREE);
+	TUNABLE_INT_FETCH("vm.pmap.shpgperproc", &shpgperproc);
+	pv_entry_max = shpgperproc * maxproc + cnt.v_page_count;
+	uma_zone_reserve_kva(pvzone, pv_entry_max);
+	pv_entry_high_water = 9 * (pv_entry_max / 10);
+
+	/*
+	 * Now it is safe to enable pv_table recording.
+	 */
+	PDEBUG(1, printf("pmap_init: done!\n"));
+}
+
+int
+pmap_fault_fixup(pmap_t pm, vm_offset_t va, vm_prot_t ftype, int user)
+{
+	struct l2_dtable *l2;
+	struct l2_bucket *l2b;
+	pd_entry_t *pl1pd, l1pd;
+	pt_entry_t *ptep, pte;
+	vm_paddr_t pa;
+	u_int l1idx;
+	int rv = 0;
+
+	l1idx = L1_IDX(va);
+	rw_wlock(&pvh_global_lock);
+	PMAP_LOCK(pm);
+
+	/*
+	 * If there is no l2_dtable for this address, then the process
+	 * has no business accessing it.
+	 *
+	 * Note: This will catch userland processes trying to access
+	 * kernel addresses.
+	 */
+	l2 = pm->pm_l2[L2_IDX(l1idx)];
+	if (l2 == NULL)
+		goto out;
+
+	/*
+	 * Likewise if there is no L2 descriptor table
+	 */
+	l2b = &l2->l2_bucket[L2_BUCKET(l1idx)];
+	if (l2b->l2b_kva == NULL)
+		goto out;
+
+	/*
+	 * Check the PTE itself.
+	 */
+	ptep = &l2b->l2b_kva[l2pte_index(va)];
+	pte = *ptep;
+	if (pte == 0)
+		goto out;
+
+	/*
+	 * Catch a userland access to the vector page mapped at 0x0
+	 */
+	if (user && (pte & L2_S_PROT_U) == 0)
+		goto out;
+	if (va == vector_page)
+		goto out;
+
+	pa = l2pte_pa(pte);
+
+	if ((ftype & VM_PROT_WRITE) && (pte & L2_S_PROT_W) == 0) {
+		/*
+		 * This looks like a good candidate for "page modified"
+		 * emulation...
+		 */
+		struct pv_entry *pv;
+		struct vm_page *pg;
+
+		/* Extract the physical address of the page */
+		if ((pg = PHYS_TO_VM_PAGE(pa)) == NULL) {
+			goto out;
+		}
+		/* Get the current flags for this page. */
+
+		pv = pmap_find_pv(pg, pm, va);
+		if (pv == NULL) {
+			goto out;
+		}
+
+		/*
+		 * Do the flags say this page is writable? If not then it
+		 * is a genuine write fault. If yes then the write fault is
+		 * our fault as we did not reflect the write access in the
+		 * PTE. Now we know a write has occurred we can correct this
+		 * and also set the modified bit
+		 */
+		if ((pv->pv_flags & PVF_WRITE) == 0) {
+			goto out;
+		}
+
+		pg->md.pvh_attrs |= PVF_REF | PVF_MOD;
+		vm_page_dirty(pg);
+		pv->pv_flags |= PVF_REF | PVF_MOD;
+
+		/*
+		 * Re-enable write permissions for the page.  No need to call
+		 * pmap_fix_cache(), since this is just a
+		 * modified-emulation fault, and the PVF_WRITE bit isn't
+		 * changing. We've already set the cacheable bits based on
+		 * the assumption that we can write to this page.
+		 */
+		*ptep = (pte & ~L2_TYPE_MASK) | L2_S_PROTO | L2_S_PROT_W;
+		PTE_SYNC(ptep);
+		rv = 1;
+	} else
+	if ((pte & L2_TYPE_MASK) == L2_TYPE_INV) {
+		/*
+		 * This looks like a good candidate for "page referenced"
+		 * emulation.
+		 */
+		struct pv_entry *pv;
+		struct vm_page *pg;
+
+		/* Extract the physical address of the page */
+		if ((pg = PHYS_TO_VM_PAGE(pa)) == NULL)
+			goto out;
+		/* Get the current flags for this page. */
+
+		pv = pmap_find_pv(pg, pm, va);
+		if (pv == NULL)
+			goto out;
+
+		pg->md.pvh_attrs |= PVF_REF;
+		pv->pv_flags |= PVF_REF;
+
+
+		*ptep = (pte & ~L2_TYPE_MASK) | L2_S_PROTO;
+		PTE_SYNC(ptep);
+		rv = 1;
+	}
+
+	/*
+	 * We know there is a valid mapping here, so simply
+	 * fix up the L1 if necessary.
+	 */
+	pl1pd = &pm->pm_l1->l1_kva[l1idx];
+	l1pd = l2b->l2b_phys | L1_C_DOM(pm->pm_domain) | L1_C_PROTO;
+	if (*pl1pd != l1pd) {
+		*pl1pd = l1pd;
+		PTE_SYNC(pl1pd);
+		rv = 1;
+	}
+
+#ifdef DEBUG
+	/*
+	 * If 'rv == 0' at this point, it generally indicates that there is a
+	 * stale TLB entry for the faulting address. This happens when two or
+	 * more processes are sharing an L1. Since we don't flush the TLB on
+	 * a context switch between such processes, we can take domain faults
+	 * for mappings which exist at the same VA in both processes. EVEN IF
+	 * WE'VE RECENTLY FIXED UP THE CORRESPONDING L1 in pmap_enter(), for
+	 * example.
+	 *
+	 * This is extremely likely to happen if pmap_enter() updated the L1
+	 * entry for a recently entered mapping. In this case, the TLB is
+	 * flushed for the new mapping, but there may still be TLB entries for
+	 * other mappings belonging to other processes in the 1MB range
+	 * covered by the L1 entry.
+	 *
+	 * Since 'rv == 0', we know that the L1 already contains the correct
+	 * value, so the fault must be due to a stale TLB entry.
+	 *
+	 * Since we always need to flush the TLB anyway in the case where we
+	 * fixed up the L1, or frobbed the L2 PTE, we effectively deal with
+	 * stale TLB entries dynamically.
+	 *
+	 * However, the above condition can ONLY happen if the current L1 is
+	 * being shared. If it happens when the L1 is unshared, it indicates
+	 * that other parts of the pmap are not doing their job WRT managing
+	 * the TLB.
+	 */
+	if (rv == 0 && pm->pm_l1->l1_domain_use_count == 1) {
+		printf("fixup: pm %p, va 0x%lx, ftype %d - nothing to do!\n",
+		    pm, (u_long)va, ftype);
+		printf("fixup: l2 %p, l2b %p, ptep %p, pl1pd %p\n",
+		    l2, l2b, ptep, pl1pd);
+		printf("fixup: pte 0x%x, l1pd 0x%x, last code 0x%x\n",
+		    pte, l1pd, last_fault_code);
+#ifdef DDB
+		Debugger();
+#endif
+	}
+#endif
+
+	cpu_tlb_flushID_SE(va);
+	cpu_cpwait();
+
+	rv = 1;
+
+out:
+	rw_wunlock(&pvh_global_lock);
+	PMAP_UNLOCK(pm);
+	return (rv);
+}
+
+void
+pmap_postinit(void)
+{
+	struct l2_bucket *l2b;
+	struct l1_ttable *l1;
+	pd_entry_t *pl1pt;
+	pt_entry_t *ptep, pte;
+	vm_offset_t va, eva;
+	u_int loop, needed;
+	
+	needed = (maxproc / PMAP_DOMAINS) + ((maxproc % PMAP_DOMAINS) ? 1 : 0);
+	needed -= 1;
+	l1 = malloc(sizeof(*l1) * needed, M_VMPMAP, M_WAITOK);
+
+	for (loop = 0; loop < needed; loop++, l1++) {
+		/* Allocate a L1 page table */
+		va = (vm_offset_t)contigmalloc(L1_TABLE_SIZE, M_VMPMAP, 0, 0x0,
+		    0xffffffff, L1_TABLE_SIZE, 0);
+
+		if (va == 0)
+			panic("Cannot allocate L1 KVM");
+
+		eva = va + L1_TABLE_SIZE;
+		pl1pt = (pd_entry_t *)va;
+		
+		while (va < eva) {
+				l2b = pmap_get_l2_bucket(pmap_kernel(), va);
+				ptep = &l2b->l2b_kva[l2pte_index(va)];
+				pte = *ptep;
+				pte = (pte & ~L2_S_CACHE_MASK) | pte_l2_s_cache_mode_pt;
+				*ptep = pte;
+				PTE_SYNC(ptep);
+				cpu_tlb_flushD_SE(va);
+				
+				va += PAGE_SIZE;
+		}
+		pmap_init_l1(l1, pl1pt);
+	}
+
+
+#ifdef DEBUG
+	printf("pmap_postinit: Allocated %d static L1 descriptor tables\n",
+	    needed);
+#endif
+}
+
+/*
+ * This is used to stuff certain critical values into the PCB where they
+ * can be accessed quickly from cpu_switch() et al.
+ */
+void
+pmap_set_pcb_pagedir(pmap_t pm, struct pcb *pcb)
+{
+	struct l2_bucket *l2b;
+
+	pcb->pcb_pagedir = pm->pm_l1->l1_physaddr;
+	pcb->pcb_dacr = (DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL * 2)) |
+	    (DOMAIN_CLIENT << (pm->pm_domain * 2));
+
+	if (vector_page < KERNBASE) {
+		pcb->pcb_pl1vec = &pm->pm_l1->l1_kva[L1_IDX(vector_page)];
+		l2b = pmap_get_l2_bucket(pm, vector_page);
+		pcb->pcb_l1vec = l2b->l2b_phys | L1_C_PROTO |
+	 	    L1_C_DOM(pm->pm_domain) | L1_C_DOM(PMAP_DOMAIN_KERNEL);
+	} else
+		pcb->pcb_pl1vec = NULL;
+}
+
+void
+pmap_activate(struct thread *td)
+{
+	pmap_t pm;
+	struct pcb *pcb;
+
+	pm = vmspace_pmap(td->td_proc->p_vmspace);
+	pcb = td->td_pcb;
+
+	critical_enter();
+	pmap_set_pcb_pagedir(pm, pcb);
+
+	if (td == curthread) {
+		u_int cur_dacr, cur_ttb;
+
+		__asm __volatile("mrc p15, 0, %0, c2, c0, 0" : "=r"(cur_ttb));
+		__asm __volatile("mrc p15, 0, %0, c3, c0, 0" : "=r"(cur_dacr));
+
+		cur_ttb &= ~(L1_TABLE_SIZE - 1);
+
+		if (cur_ttb == (u_int)pcb->pcb_pagedir &&
+		    cur_dacr == pcb->pcb_dacr) {
+			/*
+			 * No need to switch address spaces.
+			 */
+			critical_exit();
+			return;
+		}
+
+
+		/*
+		 * We MUST, I repeat, MUST fix up the L1 entry corresponding
+		 * to 'vector_page' in the incoming L1 table before switching
+		 * to it otherwise subsequent interrupts/exceptions (including
+		 * domain faults!) will jump into hyperspace.
+		 */
+		if (pcb->pcb_pl1vec) {
+
+			*pcb->pcb_pl1vec = pcb->pcb_l1vec;
+			/*
+			 * Don't need to PTE_SYNC() at this point since
+			 * cpu_setttb() is about to flush both the cache
+			 * and the TLB.
+			 */
+		}
+
+		cpu_domains(pcb->pcb_dacr);
+		cpu_setttb(pcb->pcb_pagedir);
+	}
+	critical_exit();
+}
+
+static int
+pmap_set_pt_cache_mode(pd_entry_t *kl1, vm_offset_t va)
+{
+	pd_entry_t *pdep, pde;
+	pt_entry_t *ptep, pte;
+	vm_offset_t pa;
+	int rv = 0;
+
+	/*
+	 * Make sure the descriptor itself has the correct cache mode
+	 */
+	pdep = &kl1[L1_IDX(va)];
+	pde = *pdep;
+
+	if (l1pte_section_p(pde)) {
+		if ((pde & L1_S_CACHE_MASK) != pte_l1_s_cache_mode_pt) {
+			*pdep = (pde & ~L1_S_CACHE_MASK) |
+			    pte_l1_s_cache_mode_pt;
+			PTE_SYNC(pdep);
+			cpu_dcache_wbinv_range((vm_offset_t)pdep,
+			    sizeof(*pdep));
+			cpu_l2cache_wbinv_range((vm_offset_t)pdep,
+			    sizeof(*pdep));
+			rv = 1;
+		}
+	} else {
+		pa = (vm_paddr_t)(pde & L1_C_ADDR_MASK);
+		ptep = (pt_entry_t *)kernel_pt_lookup(pa);
+		if (ptep == NULL)
+			panic("pmap_bootstrap: No L2 for L2 @ va %p\n", ptep);
+
+		ptep = &ptep[l2pte_index(va)];
+		pte = *ptep;
+		if ((pte & L2_S_CACHE_MASK) != pte_l2_s_cache_mode_pt) {
+			*ptep = (pte & ~L2_S_CACHE_MASK) |
+			    pte_l2_s_cache_mode_pt;
+			PTE_SYNC(ptep);
+			cpu_dcache_wbinv_range((vm_offset_t)ptep,
+			    sizeof(*ptep));
+			cpu_l2cache_wbinv_range((vm_offset_t)ptep,
+			    sizeof(*ptep));
+			rv = 1;
+		}
+	}
+
+	return (rv);
+}
+
+static void
+pmap_alloc_specials(vm_offset_t *availp, int pages, vm_offset_t *vap,
+    pt_entry_t **ptep)
+{
+	vm_offset_t va = *availp;
+	struct l2_bucket *l2b;
+
+	if (ptep) {
+		l2b = pmap_get_l2_bucket(pmap_kernel(), va);
+		if (l2b == NULL)
+			panic("pmap_alloc_specials: no l2b for 0x%x", va);
+
+		*ptep = &l2b->l2b_kva[l2pte_index(va)];
+	}
+
+	*vap = va;
+	*availp = va + (PAGE_SIZE * pages);
+}
+
+/*
+ *	Bootstrap the system enough to run with virtual memory.
+ *
+ *	On the arm this is called after mapping has already been enabled
+ *	and just syncs the pmap module with what has already been done.
+ *	[We can't call it easily with mapping off since the kernel is not
+ *	mapped with PA == VA, hence we would have to relocate every address
+ *	from the linked base (virtual) address "KERNBASE" to the actual
+ *	(physical) address starting relative to 0]
+ */
+#define PMAP_STATIC_L2_SIZE 16
+void
+pmap_bootstrap(vm_offset_t firstaddr, struct pv_addr *l1pt)
+{
+	static struct l1_ttable static_l1;
+	static struct l2_dtable static_l2[PMAP_STATIC_L2_SIZE];
+	struct l1_ttable *l1 = &static_l1;
+	struct l2_dtable *l2;
+	struct l2_bucket *l2b;
+	pd_entry_t pde;
+	pd_entry_t *kernel_l1pt = (pd_entry_t *)l1pt->pv_va;
+	pt_entry_t *ptep;
+	vm_paddr_t pa;
+	vm_offset_t va;
+	vm_size_t size;
+	int l1idx, l2idx, l2next = 0;
+
+	PDEBUG(1, printf("firstaddr = %08x, lastaddr = %08x\n",
+	    firstaddr, vm_max_kernel_address));
+	
+	virtual_avail = firstaddr;
+	kernel_pmap->pm_l1 = l1;
+	kernel_l1pa = l1pt->pv_pa;
+	
+	/*
+	 * Scan the L1 translation table created by initarm() and create
+	 * the required metadata for all valid mappings found in it.
+	 */
+	for (l1idx = 0; l1idx < (L1_TABLE_SIZE / sizeof(pd_entry_t)); l1idx++) {
+		pde = kernel_l1pt[l1idx];
+
+		/*
+		 * We're only interested in Coarse mappings.
+		 * pmap_extract() can deal with section mappings without
+		 * recourse to checking L2 metadata.
+		 */
+		if ((pde & L1_TYPE_MASK) != L1_TYPE_C)
+			continue;
+
+		/*
+		 * Lookup the KVA of this L2 descriptor table
+		 */
+		pa = (vm_paddr_t)(pde & L1_C_ADDR_MASK);
+		ptep = (pt_entry_t *)kernel_pt_lookup(pa);
+		
+		if (ptep == NULL) {
+			panic("pmap_bootstrap: No L2 for va 0x%x, pa 0x%lx",
+			    (u_int)l1idx << L1_S_SHIFT, (long unsigned int)pa);
+		}
+
+		/*
+		 * Fetch the associated L2 metadata structure.
+		 * Allocate a new one if necessary.
+		 */
+		if ((l2 = kernel_pmap->pm_l2[L2_IDX(l1idx)]) == NULL) {
+			if (l2next == PMAP_STATIC_L2_SIZE)
+				panic("pmap_bootstrap: out of static L2s");
+			kernel_pmap->pm_l2[L2_IDX(l1idx)] = l2 =
+			    &static_l2[l2next++];
+		}
+
+		/*
+		 * One more L1 slot tracked...
+		 */
+		l2->l2_occupancy++;
+
+		/*
+		 * Fill in the details of the L2 descriptor in the
+		 * appropriate bucket.
+		 */
+		l2b = &l2->l2_bucket[L2_BUCKET(l1idx)];
+		l2b->l2b_kva = ptep;
+		l2b->l2b_phys = pa;
+		l2b->l2b_l1idx = l1idx;
+
+		/*
+		 * Establish an initial occupancy count for this descriptor
+		 */
+		for (l2idx = 0;
+		    l2idx < (L2_TABLE_SIZE_REAL / sizeof(pt_entry_t));
+		    l2idx++) {
+			if ((ptep[l2idx] & L2_TYPE_MASK) != L2_TYPE_INV) {
+				l2b->l2b_occupancy++;
+			}
+		}
+
+		/*
+		 * Make sure the descriptor itself has the correct cache mode.
+		 * If not, fix it, but whine about the problem. Port-meisters
+		 * should consider this a clue to fix up their initarm()
+		 * function. :)
+		 */
+		if (pmap_set_pt_cache_mode(kernel_l1pt, (vm_offset_t)ptep)) {
+			printf("pmap_bootstrap: WARNING! wrong cache mode for "
+			    "L2 pte @ %p\n", ptep);
+		}
+	}
+
+	
+	/*
+	 * Ensure the primary (kernel) L1 has the correct cache mode for
+	 * a page table. Bitch if it is not correctly set.
+	 */
+	for (va = (vm_offset_t)kernel_l1pt;
+	    va < ((vm_offset_t)kernel_l1pt + L1_TABLE_SIZE); va += PAGE_SIZE) {
+		if (pmap_set_pt_cache_mode(kernel_l1pt, va))
+			printf("pmap_bootstrap: WARNING! wrong cache mode for "
+			    "primary L1 @ 0x%x\n", va);
+	}
+
+	cpu_dcache_wbinv_all();
+	cpu_l2cache_wbinv_all();
+	cpu_tlb_flushID();
+	cpu_cpwait();
+
+	PMAP_LOCK_INIT(kernel_pmap);
+	CPU_FILL(&kernel_pmap->pm_active);
+	kernel_pmap->pm_domain = PMAP_DOMAIN_KERNEL;
+	TAILQ_INIT(&kernel_pmap->pm_pvlist);
+
+ 	/*
+	 * Initialize the global pv list lock.
+	 */
+	rw_init_flags(&pvh_global_lock, "pmap pv global", RW_RECURSE);
+	
+	/*
+	 * Reserve some special page table entries/VA space for temporary
+	 * mapping of pages.
+	 */
+#define SYSMAP(c, p, v, n)						\
+    v = (c)va; va += ((n)*PAGE_SIZE); p = pte; pte += (n);
+
+	pmap_alloc_specials(&virtual_avail, 1, &csrcp, &csrc_pte);
+	pmap_set_pt_cache_mode(kernel_l1pt, (vm_offset_t)csrc_pte);
+	pmap_alloc_specials(&virtual_avail, 1, &cdstp, &cdst_pte);
+	pmap_set_pt_cache_mode(kernel_l1pt, (vm_offset_t)cdst_pte);
+	size = ((vm_max_kernel_address - pmap_curmaxkvaddr) + L1_S_OFFSET) /
+	    L1_S_SIZE;
+	pmap_alloc_specials(&virtual_avail,
+	    round_page(size * L2_TABLE_SIZE_REAL) / PAGE_SIZE,
+	    &pmap_kernel_l2ptp_kva, NULL);
+	
+	size = (size + (L2_BUCKET_SIZE - 1)) / L2_BUCKET_SIZE;
+	pmap_alloc_specials(&virtual_avail,
+	    round_page(size * sizeof(struct l2_dtable)) / PAGE_SIZE,
+	    &pmap_kernel_l2dtable_kva, NULL);
+
+	pmap_alloc_specials(&virtual_avail,
+	    1, (vm_offset_t*)&_tmppt, NULL);
+	pmap_alloc_specials(&virtual_avail,
+	    MAXDUMPPGS, (vm_offset_t *)&crashdumpmap, NULL);
+	SLIST_INIT(&l1_list);
+	TAILQ_INIT(&l1_lru_list);
+	mtx_init(&l1_lru_lock, "l1 list lock", NULL, MTX_DEF);
+	pmap_init_l1(l1, kernel_l1pt);
+	cpu_dcache_wbinv_all();
+	cpu_l2cache_wbinv_all();
+
+	virtual_avail = round_page(virtual_avail);
+	virtual_end = vm_max_kernel_address;
+	kernel_vm_end = pmap_curmaxkvaddr;
+	mtx_init(&cmtx, "TMP mappings mtx", NULL, MTX_DEF);
+
+	pmap_set_pcb_pagedir(kernel_pmap, thread0.td_pcb);
+}
+
+/***************************************************
+ * Pmap allocation/deallocation routines.
+ ***************************************************/
+
+/*
+ * Release any resources held by the given physical map.
+ * Called when a pmap initialized by pmap_pinit is being released.
+ * Should only be called if the map contains no valid mappings.
+ */
+void
+pmap_release(pmap_t pmap)
+{
+	struct pcb *pcb;
+	
+	pmap_idcache_wbinv_all(pmap);
+	cpu_l2cache_wbinv_all();
+	pmap_tlb_flushID(pmap);
+	cpu_cpwait();
+	if (vector_page < KERNBASE) {
+		struct pcb *curpcb = PCPU_GET(curpcb);
+		pcb = thread0.td_pcb;
+		if (pmap_is_current(pmap)) {
+			/*
+ 			 * Frob the L1 entry corresponding to the vector
+			 * page so that it contains the kernel pmap's domain
+			 * number. This will ensure pmap_remove() does not
+			 * pull the current vector page out from under us.
+			 */
+			critical_enter();
+			*pcb->pcb_pl1vec = pcb->pcb_l1vec;
+			cpu_domains(pcb->pcb_dacr);
+			cpu_setttb(pcb->pcb_pagedir);
+			critical_exit();
+		}
+		pmap_remove(pmap, vector_page, vector_page + PAGE_SIZE);
+		/*
+		 * Make sure cpu_switch(), et al, DTRT. This is safe to do
+		 * since this process has no remaining mappings of its own.
+		 */
+		curpcb->pcb_pl1vec = pcb->pcb_pl1vec;
+		curpcb->pcb_l1vec = pcb->pcb_l1vec;
+		curpcb->pcb_dacr = pcb->pcb_dacr;
+		curpcb->pcb_pagedir = pcb->pcb_pagedir;
+
+	}
+	pmap_free_l1(pmap);
+	
+	dprintf("pmap_release()\n");
+}
+
+
+
+/*
+ * Helper function for pmap_grow_l2_bucket()
+ */
+static __inline int
+pmap_grow_map(vm_offset_t va, pt_entry_t cache_mode, vm_paddr_t *pap)
+{
+	struct l2_bucket *l2b;
+	pt_entry_t *ptep;
+	vm_paddr_t pa;
+	struct vm_page *pg;
+	
+	pg = vm_page_alloc(NULL, 0, VM_ALLOC_NOOBJ | VM_ALLOC_WIRED);
+	if (pg == NULL)
+		return (1);
+	pa = VM_PAGE_TO_PHYS(pg);
+
+	if (pap)
+		*pap = pa;
+
+	l2b = pmap_get_l2_bucket(pmap_kernel(), va);
+
+	ptep = &l2b->l2b_kva[l2pte_index(va)];
+	*ptep = L2_S_PROTO | pa | cache_mode |
+	    L2_S_PROT(PTE_KERNEL, VM_PROT_READ | VM_PROT_WRITE);
+	PTE_SYNC(ptep);
+	return (0);
+}
+
+/*
+ * This is the same as pmap_alloc_l2_bucket(), except that it is only
+ * used by pmap_growkernel().
+ */
+static __inline struct l2_bucket *
+pmap_grow_l2_bucket(pmap_t pm, vm_offset_t va)
+{
+	struct l2_dtable *l2;
+	struct l2_bucket *l2b;
+	struct l1_ttable *l1;
+	pd_entry_t *pl1pd;
+	u_short l1idx;
+	vm_offset_t nva;
+
+	l1idx = L1_IDX(va);
+
+	if ((l2 = pm->pm_l2[L2_IDX(l1idx)]) == NULL) {
+		/*
+		 * No mapping at this address, as there is
+		 * no entry in the L1 table.
+		 * Need to allocate a new l2_dtable.
+		 */
+		nva = pmap_kernel_l2dtable_kva;
+		if ((nva & PAGE_MASK) == 0) {
+			/*
+			 * Need to allocate a backing page
+			 */
+			if (pmap_grow_map(nva, pte_l2_s_cache_mode, NULL))
+				return (NULL);
+		}
+
+		l2 = (struct l2_dtable *)nva;
+		nva += sizeof(struct l2_dtable);
+
+		if ((nva & PAGE_MASK) < (pmap_kernel_l2dtable_kva &
+		    PAGE_MASK)) {
+			/*
+			 * The new l2_dtable straddles a page boundary.
+			 * Map in another page to cover it.
+			 */
+			if (pmap_grow_map(nva, pte_l2_s_cache_mode, NULL))
+				return (NULL);
+		}
+
+		pmap_kernel_l2dtable_kva = nva;
+
+		/*
+		 * Link it into the parent pmap
+		 */
+		pm->pm_l2[L2_IDX(l1idx)] = l2;
+		memset(l2, 0, sizeof(*l2));
+	}
+
+	l2b = &l2->l2_bucket[L2_BUCKET(l1idx)];
+
+	/*
+	 * Fetch pointer to the L2 page table associated with the address.
+	 */
+	if (l2b->l2b_kva == NULL) {
+		pt_entry_t *ptep;
+
+		/*
+		 * No L2 page table has been allocated. Chances are, this
+		 * is because we just allocated the l2_dtable, above.
+		 */
+		nva = pmap_kernel_l2ptp_kva;
+		ptep = (pt_entry_t *)nva;
+		if ((nva & PAGE_MASK) == 0) {
+			/*
+			 * Need to allocate a backing page
+			 */
+			if (pmap_grow_map(nva, pte_l2_s_cache_mode_pt,
+			    &pmap_kernel_l2ptp_phys))
+				return (NULL);
+			PTE_SYNC_RANGE(ptep, PAGE_SIZE / sizeof(pt_entry_t));
+		}
+		memset(ptep, 0, L2_TABLE_SIZE_REAL);
+		l2->l2_occupancy++;
+		l2b->l2b_kva = ptep;
+		l2b->l2b_l1idx = l1idx;
+		l2b->l2b_phys = pmap_kernel_l2ptp_phys;
+
+		pmap_kernel_l2ptp_kva += L2_TABLE_SIZE_REAL;
+		pmap_kernel_l2ptp_phys += L2_TABLE_SIZE_REAL;
+	}
+
+	/* Distribute new L1 entry to all other L1s */
+	SLIST_FOREACH(l1, &l1_list, l1_link) {
+			pl1pd = &l1->l1_kva[L1_IDX(va)];
+			*pl1pd = l2b->l2b_phys | L1_C_DOM(PMAP_DOMAIN_KERNEL) |
+			    L1_C_PROTO;
+			PTE_SYNC(pl1pd);
+	}
+
+	return (l2b);
+}
+
+
+/*
+ * grow the number of kernel page table entries, if needed
+ */
+void
+pmap_growkernel(vm_offset_t addr)
+{
+	pmap_t kpm = pmap_kernel();
+
+	if (addr <= pmap_curmaxkvaddr)
+		return;		/* we are OK */
+
+	/*
+	 * whoops!   we need to add kernel PTPs
+	 */
+
+	/* Map 1MB at a time */
+	for (; pmap_curmaxkvaddr < addr; pmap_curmaxkvaddr += L1_S_SIZE)
+		pmap_grow_l2_bucket(kpm, pmap_curmaxkvaddr);
+
+	/*
+	 * flush out the cache, expensive but growkernel will happen so
+	 * rarely
+	 */
+	cpu_dcache_wbinv_all();
+	cpu_l2cache_wbinv_all();
+	cpu_tlb_flushD();
+	cpu_cpwait();
+	kernel_vm_end = pmap_curmaxkvaddr;
+}
+
+
+/*
+ * Remove all pages from specified address space
+ * this aids process exit speeds.  Also, this code
+ * is special cased for current process only, but
+ * can have the more generic (and slightly slower)
+ * mode enabled.  This is much faster than pmap_remove
+ * in the case of running down an entire address space.
+ */
+void
+pmap_remove_pages(pmap_t pmap)
+{
+	struct pv_entry *pv, *npv;
+	struct l2_bucket *l2b = NULL;
+	vm_page_t m;
+	pt_entry_t *pt;
+	
+	rw_wlock(&pvh_global_lock);
+	PMAP_LOCK(pmap);
+	cpu_idcache_wbinv_all();
+	cpu_l2cache_wbinv_all();
+	for (pv = TAILQ_FIRST(&pmap->pm_pvlist); pv; pv = npv) {
+		if (pv->pv_flags & PVF_WIRED || pv->pv_flags & PVF_UNMAN) {
+			/* Cannot remove wired or unmanaged pages now. */
+			npv = TAILQ_NEXT(pv, pv_plist);
+			continue;
+		}
+		pmap->pm_stats.resident_count--;
+		l2b = pmap_get_l2_bucket(pmap, pv->pv_va);
+		KASSERT(l2b != NULL, ("No L2 bucket in pmap_remove_pages"));
+		pt = &l2b->l2b_kva[l2pte_index(pv->pv_va)];
+		m = PHYS_TO_VM_PAGE(*pt & L2_ADDR_MASK);
+		KASSERT((vm_offset_t)m >= KERNBASE, ("Trying to access non-existent page va %x pte %x", pv->pv_va, *pt));
+		*pt = 0;
+		PTE_SYNC(pt);
+		npv = TAILQ_NEXT(pv, pv_plist);
+		pmap_nuke_pv(m, pmap, pv);
+		if (TAILQ_EMPTY(&m->md.pv_list))
+			vm_page_aflag_clear(m, PGA_WRITEABLE);
+		pmap_free_pv_entry(pv);
+		pmap_free_l2_bucket(pmap, l2b, 1);
+	}
+	rw_wunlock(&pvh_global_lock);
+	cpu_tlb_flushID();
+	cpu_cpwait();
+	PMAP_UNLOCK(pmap);
+}
+
+
+/***************************************************
+ * Low level mapping routines.....
+ ***************************************************/
+
+#ifdef ARM_HAVE_SUPERSECTIONS
+/* Map a super section into the KVA. */
+
+void
+pmap_kenter_supersection(vm_offset_t va, uint64_t pa, int flags)
+{
+	pd_entry_t pd = L1_S_PROTO | L1_S_SUPERSEC | (pa & L1_SUP_FRAME) |
+	    (((pa >> 32) & 0xf) << 20) | L1_S_PROT(PTE_KERNEL,
+	    VM_PROT_READ|VM_PROT_WRITE) | L1_S_DOM(PMAP_DOMAIN_KERNEL);
+	struct l1_ttable *l1;	
+	vm_offset_t va0, va_end;
+
+	KASSERT(((va | pa) & L1_SUP_OFFSET) == 0,
+	    ("Not a valid super section mapping"));
+	if (flags & SECTION_CACHE)
+		pd |= pte_l1_s_cache_mode;
+	else if (flags & SECTION_PT)
+		pd |= pte_l1_s_cache_mode_pt;
+	va0 = va & L1_SUP_FRAME;
+	va_end = va + L1_SUP_SIZE;
+	SLIST_FOREACH(l1, &l1_list, l1_link) {
+		va = va0;
+		for (; va < va_end; va += L1_S_SIZE) {
+			l1->l1_kva[L1_IDX(va)] = pd;
+			PTE_SYNC(&l1->l1_kva[L1_IDX(va)]);
+		}
+	}
+}
+#endif
+
+/* Map a section into the KVA. */
+
+void
+pmap_kenter_section(vm_offset_t va, vm_offset_t pa, int flags)
+{
+	pd_entry_t pd = L1_S_PROTO | pa | L1_S_PROT(PTE_KERNEL,
+	    VM_PROT_READ|VM_PROT_WRITE) | L1_S_DOM(PMAP_DOMAIN_KERNEL);
+	struct l1_ttable *l1;
+
+	KASSERT(((va | pa) & L1_S_OFFSET) == 0,
+	    ("Not a valid section mapping"));
+	if (flags & SECTION_CACHE)
+		pd |= pte_l1_s_cache_mode;
+	else if (flags & SECTION_PT)
+		pd |= pte_l1_s_cache_mode_pt;
+	SLIST_FOREACH(l1, &l1_list, l1_link) {
+		l1->l1_kva[L1_IDX(va)] = pd;
+		PTE_SYNC(&l1->l1_kva[L1_IDX(va)]);
+	}
+}
+
+/*
+ * Make a temporary mapping for a physical address.  This is only intended
+ * to be used for panic dumps.
+ */
+void *
+pmap_kenter_temporary(vm_paddr_t pa, int i)
+{
+	vm_offset_t va;
+
+	va = (vm_offset_t)crashdumpmap + (i * PAGE_SIZE);
+	pmap_kenter(va, pa);
+	return ((void *)crashdumpmap);
+}
+
+/*
+ * add a wired page to the kva
+ * note that in order for the mapping to take effect -- you
+ * should do a invltlb after doing the pmap_kenter...
+ */
+static PMAP_INLINE void
+pmap_kenter_internal(vm_offset_t va, vm_offset_t pa, int flags)
+{
+	struct l2_bucket *l2b;
+	pt_entry_t *pte;
+	pt_entry_t opte;
+	struct pv_entry *pve;
+	vm_page_t m;
+
+	PDEBUG(1, printf("pmap_kenter: va = %08x, pa = %08x\n",
+	    (uint32_t) va, (uint32_t) pa));
+
+
+	l2b = pmap_get_l2_bucket(pmap_kernel(), va);
+	if (l2b == NULL)
+		l2b = pmap_grow_l2_bucket(pmap_kernel(), va);
+	KASSERT(l2b != NULL, ("No L2 Bucket"));
+	pte = &l2b->l2b_kva[l2pte_index(va)];
+	opte = *pte;
+	PDEBUG(1, printf("pmap_kenter: pte = %08x, opte = %08x, npte = %08x\n",
+	    (uint32_t) pte, opte, *pte));
+	if (l2pte_valid(opte)) {
+		pmap_kremove(va);
+	} else {
+		if (opte == 0)
+			l2b->l2b_occupancy++;
+	}
+	*pte = L2_S_PROTO | pa | L2_S_PROT(PTE_KERNEL,
+	    VM_PROT_READ | VM_PROT_WRITE);
+	if (flags & KENTER_CACHE)
+		*pte |= pte_l2_s_cache_mode;
+	if (flags & KENTER_USER)
+		*pte |= L2_S_PROT_U;
+	PTE_SYNC(pte);
+
+	/*
+	 * A kernel mapping may not be the page's only mapping, so create a PV
+	 * entry to ensure proper caching.
+ 	 *
+	 * The existence test for the pvzone is used to delay the recording of
+	 * kernel mappings until the VM system is fully initialized.
+	 *
+	 * This expects the physical memory to have a vm_page_array entry.
+	 */
+	if (pvzone != NULL && (m = vm_phys_paddr_to_vm_page(pa)) != NULL) {
+		rw_wlock(&pvh_global_lock);
+		if (!TAILQ_EMPTY(&m->md.pv_list) || m->md.pv_kva != 0) {
+			if ((pve = pmap_get_pv_entry()) == NULL)
+				panic("pmap_kenter_internal: no pv entries");	
+			PMAP_LOCK(pmap_kernel());
+			pmap_enter_pv(m, pve, pmap_kernel(), va,
+			    PVF_WRITE | PVF_UNMAN);
+			pmap_fix_cache(m, pmap_kernel(), va);
+			PMAP_UNLOCK(pmap_kernel());
+		} else {
+			m->md.pv_kva = va;
+		}
+		rw_wunlock(&pvh_global_lock);
+	}
+}
+
+void
+pmap_kenter(vm_offset_t va, vm_paddr_t pa)
+{
+	pmap_kenter_internal(va, pa, KENTER_CACHE);
+}
+
+void
+pmap_kenter_nocache(vm_offset_t va, vm_paddr_t pa)
+{
+
+	pmap_kenter_internal(va, pa, 0);
+}
+
+void
+pmap_kenter_device(vm_offset_t va, vm_paddr_t pa)
+{
+
+	/*
+	 * XXX - Need a way for kenter_internal to handle PTE_DEVICE mapping as
+	 * a potentially different thing than PTE_NOCACHE.
+	 */
+	pmap_kenter_internal(va, pa, 0);
+}
+
+void
+pmap_kenter_user(vm_offset_t va, vm_paddr_t pa)
+{
+
+	pmap_kenter_internal(va, pa, KENTER_CACHE|KENTER_USER);
+	/*
+	 * Call pmap_fault_fixup now, to make sure we'll have no exception
+	 * at the first use of the new address, or bad things will happen,
+	 * as we use one of these addresses in the exception handlers.
+	 */
+	pmap_fault_fixup(pmap_kernel(), va, VM_PROT_READ|VM_PROT_WRITE, 1);
+}
+
+vm_paddr_t
+pmap_kextract(vm_offset_t va)
+{
+
+	return (pmap_extract_locked(kernel_pmap, va));
+}
+
+/*
+ * remove a page from the kernel pagetables
+ */
+void
+pmap_kremove(vm_offset_t va)
+{
+	struct l2_bucket *l2b;
+	pt_entry_t *pte, opte;
+	struct pv_entry *pve;
+	vm_page_t m;
+	vm_offset_t pa;
+		
+	l2b = pmap_get_l2_bucket(pmap_kernel(), va);
+	if (!l2b)
+		return;
+	KASSERT(l2b != NULL, ("No L2 Bucket"));
+	pte = &l2b->l2b_kva[l2pte_index(va)];
+	opte = *pte;
+	if (l2pte_valid(opte)) {
+			/* pa = vtophs(va) taken from pmap_extract() */
+		switch (opte & L2_TYPE_MASK) {
+		case L2_TYPE_L:
+			pa = (opte & L2_L_FRAME) | (va & L2_L_OFFSET);
+			break;
+		default:
+			pa = (opte & L2_S_FRAME) | (va & L2_S_OFFSET);
+			break;
+		}
+			/* note: should never have to remove an allocation
+			 * before the pvzone is initialized.
+			 */
+		rw_wlock(&pvh_global_lock);
+		PMAP_LOCK(pmap_kernel());
+		if (pvzone != NULL && (m = vm_phys_paddr_to_vm_page(pa)) &&
+		    (pve = pmap_remove_pv(m, pmap_kernel(), va)))
+			pmap_free_pv_entry(pve);
+		PMAP_UNLOCK(pmap_kernel());
+		rw_wunlock(&pvh_global_lock);
+		va = va & ~PAGE_MASK;
+		cpu_dcache_wbinv_range(va, PAGE_SIZE);
+		cpu_l2cache_wbinv_range(va, PAGE_SIZE);
+		cpu_tlb_flushD_SE(va);
+		cpu_cpwait();
+		*pte = 0;
+	}
+}
+
+
+/*
+ *	Used to map a range of physical addresses into kernel
+ *	virtual address space.
+ *
+ *	The value passed in '*virt' is a suggested virtual address for
+ *	the mapping. Architectures which can support a direct-mapped
+ *	physical to virtual region can return the appropriate address
+ *	within that region, leaving '*virt' unchanged. Other
+ *	architectures should map the pages starting at '*virt' and
+ *	update '*virt' with the first usable address after the mapped
+ *	region.
+ */
+vm_offset_t
+pmap_map(vm_offset_t *virt, vm_offset_t start, vm_offset_t end, int prot)
+{
+	vm_offset_t sva = *virt;
+	vm_offset_t va = sva;
+
+	PDEBUG(1, printf("pmap_map: virt = %08x, start = %08x, end = %08x, "
+	    "prot = %d\n", (uint32_t) *virt, (uint32_t) start, (uint32_t) end,
+	    prot));
+
+	while (start < end) {
+		pmap_kenter(va, start);
+		va += PAGE_SIZE;
+		start += PAGE_SIZE;
+	}
+	*virt = va;
+	return (sva);
+}
+
+static void
+pmap_wb_page(vm_page_t m)
+{
+	struct pv_entry *pv;
+
+	TAILQ_FOREACH(pv, &m->md.pv_list, pv_list)
+	    pmap_dcache_wb_range(pv->pv_pmap, pv->pv_va, PAGE_SIZE, FALSE,
+		(pv->pv_flags & PVF_WRITE) == 0);
+}
+
+static void
+pmap_inv_page(vm_page_t m)
+{
+	struct pv_entry *pv;
+
+	TAILQ_FOREACH(pv, &m->md.pv_list, pv_list)
+	    pmap_dcache_wb_range(pv->pv_pmap, pv->pv_va, PAGE_SIZE, TRUE, TRUE);
+}
+/*
+ * Add a list of wired pages to the kva
+ * this routine is only used for temporary
+ * kernel mappings that do not need to have
+ * page modification or references recorded.
+ * Note that old mappings are simply written
+ * over.  The page *must* be wired.
+ */
+void
+pmap_qenter(vm_offset_t va, vm_page_t *m, int count)
+{
+	int i;
+
+	for (i = 0; i < count; i++) {
+		pmap_wb_page(m[i]);
+		pmap_kenter_internal(va, VM_PAGE_TO_PHYS(m[i]),
+		    KENTER_CACHE);
+		va += PAGE_SIZE;
+	}
+}
+
+
+/*
+ * this routine jerks page mappings from the
+ * kernel -- it is meant only for temporary mappings.
+ */
+void
+pmap_qremove(vm_offset_t va, int count)
+{
+	vm_paddr_t pa;
+	int i;
+
+	for (i = 0; i < count; i++) {
+		pa = vtophys(va);
+		if (pa) {
+			pmap_inv_page(PHYS_TO_VM_PAGE(pa));
+			pmap_kremove(va);
+		}
+		va += PAGE_SIZE;
+	}
+}
+
+
+/*
+ * pmap_object_init_pt preloads the ptes for a given object
+ * into the specified pmap.  This eliminates the blast of soft
+ * faults on process startup and immediately after an mmap.
+ */
+void
+pmap_object_init_pt(pmap_t pmap, vm_offset_t addr, vm_object_t object,
+    vm_pindex_t pindex, vm_size_t size)
+{
+
+	VM_OBJECT_ASSERT_WLOCKED(object);
+	KASSERT(object->type == OBJT_DEVICE || object->type == OBJT_SG,
+	    ("pmap_object_init_pt: non-device object"));
+}
+
+
+/*
+ *	pmap_is_prefaultable:
+ *
+ *	Return whether or not the specified virtual address is elgible
+ *	for prefault.
+ */
+boolean_t
+pmap_is_prefaultable(pmap_t pmap, vm_offset_t addr)
+{
+	pd_entry_t *pde;
+	pt_entry_t *pte;
+
+	if (!pmap_get_pde_pte(pmap, addr, &pde, &pte))
+		return (FALSE);
+	KASSERT(pte != NULL, ("Valid mapping but no pte ?"));
+	if (*pte == 0)
+		return (TRUE);
+	return (FALSE);
+}
+
+/*
+ * Fetch pointers to the PDE/PTE for the given pmap/VA pair.
+ * Returns TRUE if the mapping exists, else FALSE.
+ *
+ * NOTE: This function is only used by a couple of arm-specific modules.
+ * It is not safe to take any pmap locks here, since we could be right
+ * in the middle of debugging the pmap anyway...
+ *
+ * It is possible for this routine to return FALSE even though a valid
+ * mapping does exist. This is because we don't lock, so the metadata
+ * state may be inconsistent.
+ *
+ * NOTE: We can return a NULL *ptp in the case where the L1 pde is
+ * a "section" mapping.
+ */
+boolean_t
+pmap_get_pde_pte(pmap_t pm, vm_offset_t va, pd_entry_t **pdp, pt_entry_t **ptp)
+{
+	struct l2_dtable *l2;
+	pd_entry_t *pl1pd, l1pd;
+	pt_entry_t *ptep;
+	u_short l1idx;
+
+	if (pm->pm_l1 == NULL)
+		return (FALSE);
+
+	l1idx = L1_IDX(va);
+	*pdp = pl1pd = &pm->pm_l1->l1_kva[l1idx];
+	l1pd = *pl1pd;
+
+	if (l1pte_section_p(l1pd)) {
+		*ptp = NULL;
+		return (TRUE);
+	}
+
+	if (pm->pm_l2 == NULL)
+		return (FALSE);
+
+	l2 = pm->pm_l2[L2_IDX(l1idx)];
+
+	if (l2 == NULL ||
+	    (ptep = l2->l2_bucket[L2_BUCKET(l1idx)].l2b_kva) == NULL) {
+		return (FALSE);
+	}
+
+	*ptp = &ptep[l2pte_index(va)];
+	return (TRUE);
+}
+
+/*
+ *      Routine:        pmap_remove_all
+ *      Function:
+ *              Removes this physical page from
+ *              all physical maps in which it resides.
+ *              Reflects back modify bits to the pager.
+ *
+ *      Notes:
+ *              Original versions of this routine were very
+ *              inefficient because they iteratively called
+ *              pmap_remove (slow...)
+ */
+void
+pmap_remove_all(vm_page_t m)
+{
+	pv_entry_t pv;
+	pt_entry_t *ptep;
+	struct l2_bucket *l2b;
+	boolean_t flush = FALSE;
+	pmap_t curpm;
+	int flags = 0;
+
+	KASSERT((m->oflags & VPO_UNMANAGED) == 0,
+	    ("pmap_remove_all: page %p is not managed", m));
+	if (TAILQ_EMPTY(&m->md.pv_list))
+		return;
+	rw_wlock(&pvh_global_lock);
+	pmap_remove_write(m);
+	curpm = vmspace_pmap(curproc->p_vmspace);
+	while ((pv = TAILQ_FIRST(&m->md.pv_list)) != NULL) {
+		if (flush == FALSE && (pv->pv_pmap == curpm ||
+		    pv->pv_pmap == pmap_kernel()))
+			flush = TRUE;
+
+		PMAP_LOCK(pv->pv_pmap);
+		/*
+		 * Cached contents were written-back in pmap_remove_write(),
+		 * but we still have to invalidate the cache entry to make
+		 * sure stale data are not retrieved when another page will be
+		 * mapped under this virtual address.
+		 */
+		if (pmap_is_current(pv->pv_pmap)) {
+			cpu_dcache_inv_range(pv->pv_va, PAGE_SIZE);
+			if (pmap_has_valid_mapping(pv->pv_pmap, pv->pv_va))
+				cpu_l2cache_inv_range(pv->pv_va, PAGE_SIZE);
+		}
+
+		if (pv->pv_flags & PVF_UNMAN) {
+			/* remove the pv entry, but do not remove the mapping
+			 * and remember this is a kernel mapped page
+			 */
+			m->md.pv_kva = pv->pv_va;
+		} else {
+			/* remove the mapping and pv entry */
+			l2b = pmap_get_l2_bucket(pv->pv_pmap, pv->pv_va);
+			KASSERT(l2b != NULL, ("No l2 bucket"));
+			ptep = &l2b->l2b_kva[l2pte_index(pv->pv_va)];
+			*ptep = 0;
+			PTE_SYNC_CURRENT(pv->pv_pmap, ptep);
+			pmap_free_l2_bucket(pv->pv_pmap, l2b, 1);
+			pv->pv_pmap->pm_stats.resident_count--;
+			flags |= pv->pv_flags;
+		}
+		pmap_nuke_pv(m, pv->pv_pmap, pv);
+		PMAP_UNLOCK(pv->pv_pmap);
+		pmap_free_pv_entry(pv);
+	}
+
+	if (flush) {
+		if (PV_BEEN_EXECD(flags))
+			pmap_tlb_flushID(curpm);
+		else
+			pmap_tlb_flushD(curpm);
+	}
+	vm_page_aflag_clear(m, PGA_WRITEABLE);
+	rw_wunlock(&pvh_global_lock);
+}
+
+
+/*
+ *	Set the physical protection on the
+ *	specified range of this map as requested.
+ */
+void
+pmap_protect(pmap_t pm, vm_offset_t sva, vm_offset_t eva, vm_prot_t prot)
+{
+	struct l2_bucket *l2b;
+	pt_entry_t *ptep, pte;
+	vm_offset_t next_bucket;
+	u_int flags;
+	int flush;
+
+	CTR4(KTR_PMAP, "pmap_protect: pmap %p sva 0x%08x eva 0x%08x prot %x",
+	    pm, sva, eva, prot);
+
+	if ((prot & VM_PROT_READ) == 0) {
+		pmap_remove(pm, sva, eva);
+		return;
+	}
+
+	if (prot & VM_PROT_WRITE) {
+		/*
+		 * If this is a read->write transition, just ignore it and let
+		 * vm_fault() take care of it later.
+		 */
+		return;
+	}
+
+	rw_wlock(&pvh_global_lock);
+	PMAP_LOCK(pm);
+
+	/*
+	 * OK, at this point, we know we're doing write-protect operation.
+	 * If the pmap is active, write-back the range.
+	 */
+	pmap_dcache_wb_range(pm, sva, eva - sva, FALSE, FALSE);
+
+	flush = ((eva - sva) >= (PAGE_SIZE * 4)) ? 0 : -1;
+	flags = 0;
+
+	while (sva < eva) {
+		next_bucket = L2_NEXT_BUCKET(sva);
+		if (next_bucket > eva)
+			next_bucket = eva;
+
+		l2b = pmap_get_l2_bucket(pm, sva);
+		if (l2b == NULL) {
+			sva = next_bucket;
+			continue;
+		}
+
+		ptep = &l2b->l2b_kva[l2pte_index(sva)];
+
+		while (sva < next_bucket) {
+			if ((pte = *ptep) != 0 && (pte & L2_S_PROT_W) != 0) {
+				struct vm_page *pg;
+				u_int f;
+
+				pg = PHYS_TO_VM_PAGE(l2pte_pa(pte));
+				pte &= ~L2_S_PROT_W;
+				*ptep = pte;
+				PTE_SYNC(ptep);
+
+				if (!(pg->oflags & VPO_UNMANAGED)) {
+					f = pmap_modify_pv(pg, pm, sva,
+					    PVF_WRITE, 0);
+					if (f & PVF_WRITE)
+						vm_page_dirty(pg);
+				} else
+					f = 0;
+
+				if (flush >= 0) {
+					flush++;
+					flags |= f;
+				} else
+				if (PV_BEEN_EXECD(f))
+					pmap_tlb_flushID_SE(pm, sva);
+				else
+				if (PV_BEEN_REFD(f))
+					pmap_tlb_flushD_SE(pm, sva);
+			}
+
+			sva += PAGE_SIZE;
+			ptep++;
+		}
+	}
+
+
+	if (flush) {
+		if (PV_BEEN_EXECD(flags))
+			pmap_tlb_flushID(pm);
+		else
+		if (PV_BEEN_REFD(flags))
+			pmap_tlb_flushD(pm);
+	}
+	rw_wunlock(&pvh_global_lock);
+
+ 	PMAP_UNLOCK(pm);
+}
+
+
+/*
+ *	Insert the given physical page (p) at
+ *	the specified virtual address (v) in the
+ *	target physical map with the protection requested.
+ *
+ *	If specified, the page will be wired down, meaning
+ *	that the related pte can not be reclaimed.
+ *
+ *	NB:  This is the only routine which MAY NOT lazy-evaluate
+ *	or lose information.  That is, this routine must actually
+ *	insert this page into the given map NOW.
+ */
+
+int
+pmap_enter(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot,
+    u_int flags, int8_t psind __unused)
+{
+	int rv;
+
+	rw_wlock(&pvh_global_lock);
+	PMAP_LOCK(pmap);
+	rv = pmap_enter_locked(pmap, va, m, prot, flags);
+	rw_wunlock(&pvh_global_lock);
+ 	PMAP_UNLOCK(pmap);
+	return (rv);
+}
+
+/*
+ *	The pvh global and pmap locks must be held.
+ */
+static int
+pmap_enter_locked(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot,
+    u_int flags)
+{
+	struct l2_bucket *l2b = NULL;
+	struct vm_page *opg;
+	struct pv_entry *pve = NULL;
+	pt_entry_t *ptep, npte, opte;
+	u_int nflags;
+	u_int oflags;
+	vm_paddr_t pa;
+
+	PMAP_ASSERT_LOCKED(pmap);
+	rw_assert(&pvh_global_lock, RA_WLOCKED);
+	if (va == vector_page) {
+		pa = systempage.pv_pa;
+		m = NULL;
+	} else {
+		if ((m->oflags & VPO_UNMANAGED) == 0 && !vm_page_xbusied(m))
+			VM_OBJECT_ASSERT_LOCKED(m->object);
+		pa = VM_PAGE_TO_PHYS(m);
+	}
+	nflags = 0;
+	if (prot & VM_PROT_WRITE)
+		nflags |= PVF_WRITE;
+	if (prot & VM_PROT_EXECUTE)
+		nflags |= PVF_EXEC;
+	if ((flags & PMAP_ENTER_WIRED) != 0)
+		nflags |= PVF_WIRED;
+	PDEBUG(1, printf("pmap_enter: pmap = %08x, va = %08x, m = %08x, prot = %x, "
+	    "flags = %x\n", (uint32_t) pmap, va, (uint32_t) m, prot, flags));
+
+	if (pmap == pmap_kernel()) {
+		l2b = pmap_get_l2_bucket(pmap, va);
+		if (l2b == NULL)
+			l2b = pmap_grow_l2_bucket(pmap, va);
+	} else {
+do_l2b_alloc:
+		l2b = pmap_alloc_l2_bucket(pmap, va);
+		if (l2b == NULL) {
+			if ((flags & PMAP_ENTER_NOSLEEP) == 0) {
+				PMAP_UNLOCK(pmap);
+				rw_wunlock(&pvh_global_lock);
+				VM_WAIT;
+				rw_wlock(&pvh_global_lock);
+				PMAP_LOCK(pmap);
+				goto do_l2b_alloc;
+			}
+			return (KERN_RESOURCE_SHORTAGE);
+		}
+	}
+
+	ptep = &l2b->l2b_kva[l2pte_index(va)];
+
+	opte = *ptep;
+	npte = pa;
+	oflags = 0;
+	if (opte) {
+		/*
+		 * There is already a mapping at this address.
+		 * If the physical address is different, lookup the
+		 * vm_page.
+		 */
+		if (l2pte_pa(opte) != pa)
+			opg = PHYS_TO_VM_PAGE(l2pte_pa(opte));
+		else
+			opg = m;
+	} else
+		opg = NULL;
+
+	if ((prot & (VM_PROT_ALL)) ||
+	    (!m || m->md.pvh_attrs & PVF_REF)) {
+		/*
+		 * - The access type indicates that we don't need
+		 *   to do referenced emulation.
+		 * OR
+		 * - The physical page has already been referenced
+		 *   so no need to re-do referenced emulation here.
+		 */
+		npte |= L2_S_PROTO;
+		
+		nflags |= PVF_REF;
+		
+		if (m && ((prot & VM_PROT_WRITE) != 0 ||
+		    (m->md.pvh_attrs & PVF_MOD))) {
+			/*
+			 * This is a writable mapping, and the
+			 * page's mod state indicates it has
+			 * already been modified. Make it
+			 * writable from the outset.
+			 */
+			nflags |= PVF_MOD;
+			if (!(m->md.pvh_attrs & PVF_MOD))
+				vm_page_dirty(m);
+		}
+		if (m && opte)
+			vm_page_aflag_set(m, PGA_REFERENCED);
+	} else {
+		/*
+		 * Need to do page referenced emulation.
+		 */
+		npte |= L2_TYPE_INV;
+	}
+	
+	if (prot & VM_PROT_WRITE) {
+		npte |= L2_S_PROT_W;
+		if (m != NULL &&
+		    (m->oflags & VPO_UNMANAGED) == 0)
+			vm_page_aflag_set(m, PGA_WRITEABLE);
+	}
+	if (m->md.pv_memattr != VM_MEMATTR_UNCACHEABLE)
+		npte |= pte_l2_s_cache_mode;
+	if (m && m == opg) {
+		/*
+		 * We're changing the attrs of an existing mapping.
+		 */
+		oflags = pmap_modify_pv(m, pmap, va,
+		    PVF_WRITE | PVF_EXEC | PVF_WIRED |
+		    PVF_MOD | PVF_REF, nflags);
+		
+		/*
+		 * We may need to flush the cache if we're
+		 * doing rw-ro...
+		 */
+		if (pmap_is_current(pmap) &&
+		    (oflags & PVF_NC) == 0 &&
+		    (opte & L2_S_PROT_W) != 0 &&
+		    (prot & VM_PROT_WRITE) == 0 &&
+		    (opte & L2_TYPE_MASK) != L2_TYPE_INV) {
+			cpu_dcache_wb_range(va, PAGE_SIZE);
+			cpu_l2cache_wb_range(va, PAGE_SIZE);
+		}
+	} else {
+		/*
+		 * New mapping, or changing the backing page
+		 * of an existing mapping.
+		 */
+		if (opg) {
+			/*
+			 * Replacing an existing mapping with a new one.
+			 * It is part of our managed memory so we
+			 * must remove it from the PV list
+			 */
+			if ((pve = pmap_remove_pv(opg, pmap, va))) {
+
+			/* note for patch: the oflags/invalidation was moved
+			 * because PG_FICTITIOUS pages could free the pve
+			 */
+			    oflags = pve->pv_flags;
+			/*
+			 * If the old mapping was valid (ref/mod
+			 * emulation creates 'invalid' mappings
+			 * initially) then make sure to frob
+			 * the cache.
+			 */
+			    if ((oflags & PVF_NC) == 0 && l2pte_valid(opte)) {
+				if (PV_BEEN_EXECD(oflags)) {
+					pmap_idcache_wbinv_range(pmap, va,
+					    PAGE_SIZE);
+				} else
+					if (PV_BEEN_REFD(oflags)) {
+						pmap_dcache_wb_range(pmap, va,
+						    PAGE_SIZE, TRUE,
+						    (oflags & PVF_WRITE) == 0);
+					}
+			    }
+
+			/* free/allocate a pv_entry for UNMANAGED pages if
+			 * this physical page is not/is already mapped.
+			 */
+
+			    if (m && (m->oflags & VPO_UNMANAGED) &&
+				  !m->md.pv_kva &&
+				 TAILQ_EMPTY(&m->md.pv_list)) {
+				pmap_free_pv_entry(pve);
+				pve = NULL;
+			    }
+			} else if (m &&
+				 (!(m->oflags & VPO_UNMANAGED) || m->md.pv_kva ||
+				  !TAILQ_EMPTY(&m->md.pv_list)))
+				pve = pmap_get_pv_entry();
+		} else if (m &&
+			   (!(m->oflags & VPO_UNMANAGED) || m->md.pv_kva ||
+			   !TAILQ_EMPTY(&m->md.pv_list)))
+			pve = pmap_get_pv_entry();
+
+		if (m) {
+			if ((m->oflags & VPO_UNMANAGED)) {
+				if (!TAILQ_EMPTY(&m->md.pv_list) ||
+				    m->md.pv_kva) {
+					KASSERT(pve != NULL, ("No pv"));
+					nflags |= PVF_UNMAN;
+					pmap_enter_pv(m, pve, pmap, va, nflags);
+				} else
+					m->md.pv_kva = va;
+			} else {
+				KASSERT(va < kmi.clean_sva ||
+				    va >= kmi.clean_eva,
+		("pmap_enter: managed mapping within the clean submap"));
+ 				KASSERT(pve != NULL, ("No pv"));
+ 				pmap_enter_pv(m, pve, pmap, va, nflags);
+			}
+		}
+	}
+	/*
+	 * Make sure userland mappings get the right permissions
+	 */
+	if (pmap != pmap_kernel() && va != vector_page) {
+		npte |= L2_S_PROT_U;
+	}
+
+	/*
+	 * Keep the stats up to date
+	 */
+	if (opte == 0) {
+		l2b->l2b_occupancy++;
+		pmap->pm_stats.resident_count++;
+	}
+
+	/*
+	 * If this is just a wiring change, the two PTEs will be
+	 * identical, so there's no need to update the page table.
+	 */
+	if (npte != opte) {
+		boolean_t is_cached = pmap_is_current(pmap);
+
+		*ptep = npte;
+		if (is_cached) {
+			/*
+			 * We only need to frob the cache/tlb if this pmap
+			 * is current
+			 */
+			PTE_SYNC(ptep);
+			if (L1_IDX(va) != L1_IDX(vector_page) &&
+			    l2pte_valid(npte)) {
+				/*
+				 * This mapping is likely to be accessed as
+				 * soon as we return to userland. Fix up the
+				 * L1 entry to avoid taking another
+				 * page/domain fault.
+				 */
+				pd_entry_t *pl1pd, l1pd;
+
+				pl1pd = &pmap->pm_l1->l1_kva[L1_IDX(va)];
+				l1pd = l2b->l2b_phys | L1_C_DOM(pmap->pm_domain) |
+				    L1_C_PROTO;
+				if (*pl1pd != l1pd) {
+					*pl1pd = l1pd;
+					PTE_SYNC(pl1pd);
+				}
+			}
+		}
+
+		if (PV_BEEN_EXECD(oflags))
+			pmap_tlb_flushID_SE(pmap, va);
+		else if (PV_BEEN_REFD(oflags))
+			pmap_tlb_flushD_SE(pmap, va);
+
+
+		if (m)
+			pmap_fix_cache(m, pmap, va);
+	}
+	return (KERN_SUCCESS);
+}
+
+/*
+ * Maps a sequence of resident pages belonging to the same object.
+ * The sequence begins with the given page m_start.  This page is
+ * mapped at the given virtual address start.  Each subsequent page is
+ * mapped at a virtual address that is offset from start by the same
+ * amount as the page is offset from m_start within the object.  The
+ * last page in the sequence is the page with the largest offset from
+ * m_start that can be mapped at a virtual address less than the given
+ * virtual address end.  Not every virtual page between start and end
+ * is mapped; only those for which a resident page exists with the
+ * corresponding offset from m_start are mapped.
+ */
+void
+pmap_enter_object(pmap_t pmap, vm_offset_t start, vm_offset_t end,
+    vm_page_t m_start, vm_prot_t prot)
+{
+	vm_page_t m;
+	vm_pindex_t diff, psize;
+
+	VM_OBJECT_ASSERT_LOCKED(m_start->object);
+
+	psize = atop(end - start);
+	m = m_start;
+	rw_wlock(&pvh_global_lock);
+	PMAP_LOCK(pmap);
+	while (m != NULL && (diff = m->pindex - m_start->pindex) < psize) {
+		pmap_enter_locked(pmap, start + ptoa(diff), m, prot &
+		    (VM_PROT_READ | VM_PROT_EXECUTE), PMAP_ENTER_NOSLEEP);
+		m = TAILQ_NEXT(m, listq);
+	}
+	rw_wunlock(&pvh_global_lock);
+ 	PMAP_UNLOCK(pmap);
+}
+
+/*
+ * this code makes some *MAJOR* assumptions:
+ * 1. Current pmap & pmap exists.
+ * 2. Not wired.
+ * 3. Read access.
+ * 4. No page table pages.
+ * but is *MUCH* faster than pmap_enter...
+ */
+
+void
+pmap_enter_quick(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot)
+{
+
+	rw_wlock(&pvh_global_lock);
+ 	PMAP_LOCK(pmap);
+	pmap_enter_locked(pmap, va, m, prot & (VM_PROT_READ | VM_PROT_EXECUTE),
+	    PMAP_ENTER_NOSLEEP);
+	rw_wunlock(&pvh_global_lock);
+ 	PMAP_UNLOCK(pmap);
+}
+
+/*
+ *	Clear the wired attribute from the mappings for the specified range of
+ *	addresses in the given pmap.  Every valid mapping within that range
+ *	must have the wired attribute set.  In contrast, invalid mappings
+ *	cannot have the wired attribute set, so they are ignored.
+ *
+ *	XXX Wired mappings of unmanaged pages cannot be counted by this pmap
+ *	implementation.
+ */
+void
+pmap_unwire(pmap_t pmap, vm_offset_t sva, vm_offset_t eva)
+{
+	struct l2_bucket *l2b;
+	pt_entry_t *ptep, pte;
+	pv_entry_t pv;
+	vm_offset_t next_bucket;
+	vm_page_t m;
+ 
+	rw_wlock(&pvh_global_lock);
+	PMAP_LOCK(pmap);
+	while (sva < eva) {
+		next_bucket = L2_NEXT_BUCKET(sva);
+		if (next_bucket > eva)
+			next_bucket = eva;
+		l2b = pmap_get_l2_bucket(pmap, sva);
+		if (l2b == NULL) {
+			sva = next_bucket;
+			continue;
+		}
+		for (ptep = &l2b->l2b_kva[l2pte_index(sva)]; sva < next_bucket;
+		    sva += PAGE_SIZE, ptep++) {
+			if ((pte = *ptep) == 0 ||
+			    (m = PHYS_TO_VM_PAGE(l2pte_pa(pte))) == NULL ||
+			    (m->oflags & VPO_UNMANAGED) != 0)
+				continue;
+			pv = pmap_find_pv(m, pmap, sva);
+			if ((pv->pv_flags & PVF_WIRED) == 0)
+				panic("pmap_unwire: pv %p isn't wired", pv);
+			pv->pv_flags &= ~PVF_WIRED;
+			pmap->pm_stats.wired_count--;
+		}
+	}
+	rw_wunlock(&pvh_global_lock);
+ 	PMAP_UNLOCK(pmap);
+}
+
+
+/*
+ *	Copy the range specified by src_addr/len
+ *	from the source map to the range dst_addr/len
+ *	in the destination map.
+ *
+ *	This routine is only advisory and need not do anything.
+ */
+void
+pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vm_offset_t dst_addr,
+    vm_size_t len, vm_offset_t src_addr)
+{
+}
+
+
+/*
+ *	Routine:	pmap_extract
+ *	Function:
+ *		Extract the physical page address associated
+ *		with the given map/virtual_address pair.
+ */
+vm_paddr_t
+pmap_extract(pmap_t pmap, vm_offset_t va)
+{
+	vm_paddr_t pa;
+
+	PMAP_LOCK(pmap);
+	pa = pmap_extract_locked(pmap, va);
+	PMAP_UNLOCK(pmap);
+	return (pa);
+}
+
+static vm_paddr_t
+pmap_extract_locked(pmap_t pmap, vm_offset_t va)
+{
+	struct l2_dtable *l2;
+	pd_entry_t l1pd;
+	pt_entry_t *ptep, pte;
+	vm_paddr_t pa;
+	u_int l1idx;
+
+	if (pmap != kernel_pmap)
+		PMAP_ASSERT_LOCKED(pmap);
+	l1idx = L1_IDX(va);
+	l1pd = pmap->pm_l1->l1_kva[l1idx];
+	if (l1pte_section_p(l1pd)) {
+		/*
+		 * These should only happen for the kernel pmap.
+		 */
+		KASSERT(pmap == kernel_pmap, ("unexpected section"));
+		/* XXX: what to do about the bits > 32 ? */
+		if (l1pd & L1_S_SUPERSEC)
+			pa = (l1pd & L1_SUP_FRAME) | (va & L1_SUP_OFFSET);
+		else
+			pa = (l1pd & L1_S_FRAME) | (va & L1_S_OFFSET);
+	} else {
+		/*
+		 * Note that we can't rely on the validity of the L1
+		 * descriptor as an indication that a mapping exists.
+		 * We have to look it up in the L2 dtable.
+		 */
+		l2 = pmap->pm_l2[L2_IDX(l1idx)];
+		if (l2 == NULL ||
+		    (ptep = l2->l2_bucket[L2_BUCKET(l1idx)].l2b_kva) == NULL)
+			return (0);
+		pte = ptep[l2pte_index(va)];
+		if (pte == 0)
+			return (0);
+		switch (pte & L2_TYPE_MASK) {
+		case L2_TYPE_L:
+			pa = (pte & L2_L_FRAME) | (va & L2_L_OFFSET);
+			break;
+		default:
+			pa = (pte & L2_S_FRAME) | (va & L2_S_OFFSET);
+			break;
+		}
+	}
+	return (pa);
+}
+
+/*
+ * Atomically extract and hold the physical page with the given
+ * pmap and virtual address pair if that mapping permits the given
+ * protection.
+ *
+ */
+vm_page_t
+pmap_extract_and_hold(pmap_t pmap, vm_offset_t va, vm_prot_t prot)
+{
+	struct l2_dtable *l2;
+	pd_entry_t l1pd;
+	pt_entry_t *ptep, pte;
+	vm_paddr_t pa, paddr;
+	vm_page_t m = NULL;
+	u_int l1idx;
+	l1idx = L1_IDX(va);
+	paddr = 0;
+
+ 	PMAP_LOCK(pmap);
+retry:
+	l1pd = pmap->pm_l1->l1_kva[l1idx];
+	if (l1pte_section_p(l1pd)) {
+		/*
+		 * These should only happen for pmap_kernel()
+		 */
+		KASSERT(pmap == pmap_kernel(), ("huh"));
+		/* XXX: what to do about the bits > 32 ? */
+		if (l1pd & L1_S_SUPERSEC)
+			pa = (l1pd & L1_SUP_FRAME) | (va & L1_SUP_OFFSET);
+		else
+			pa = (l1pd & L1_S_FRAME) | (va & L1_S_OFFSET);
+		if (vm_page_pa_tryrelock(pmap, pa & PG_FRAME, &paddr))
+			goto retry;
+		if (l1pd & L1_S_PROT_W || (prot & VM_PROT_WRITE) == 0) {
+			m = PHYS_TO_VM_PAGE(pa);
+			vm_page_hold(m);
+		}
+			
+	} else {
+		/*
+		 * Note that we can't rely on the validity of the L1
+		 * descriptor as an indication that a mapping exists.
+		 * We have to look it up in the L2 dtable.
+		 */
+		l2 = pmap->pm_l2[L2_IDX(l1idx)];
+
+		if (l2 == NULL ||
+		    (ptep = l2->l2_bucket[L2_BUCKET(l1idx)].l2b_kva) == NULL) {
+		 	PMAP_UNLOCK(pmap);
+			return (NULL);
+		}
+
+		ptep = &ptep[l2pte_index(va)];
+		pte = *ptep;
+
+		if (pte == 0) {
+		 	PMAP_UNLOCK(pmap);
+			return (NULL);
+		}
+		if (pte & L2_S_PROT_W || (prot & VM_PROT_WRITE) == 0) {
+			switch (pte & L2_TYPE_MASK) {
+			case L2_TYPE_L:
+				pa = (pte & L2_L_FRAME) | (va & L2_L_OFFSET);
+				break;
+				
+			default:
+				pa = (pte & L2_S_FRAME) | (va & L2_S_OFFSET);
+				break;
+			}
+			if (vm_page_pa_tryrelock(pmap, pa & PG_FRAME, &paddr))
+				goto retry;		
+			m = PHYS_TO_VM_PAGE(pa);
+			vm_page_hold(m);
+		}
+	}
+
+ 	PMAP_UNLOCK(pmap);
+	PA_UNLOCK_COND(paddr);
+	return (m);
+}
+
+/*
+ * Initialize a preallocated and zeroed pmap structure,
+ * such as one in a vmspace structure.
+ */
+
+int
+pmap_pinit(pmap_t pmap)
+{
+	PDEBUG(1, printf("pmap_pinit: pmap = %08x\n", (uint32_t) pmap));
+	
+	pmap_alloc_l1(pmap);
+	bzero(pmap->pm_l2, sizeof(pmap->pm_l2));
+
+	CPU_ZERO(&pmap->pm_active);
+		
+	TAILQ_INIT(&pmap->pm_pvlist);
+	bzero(&pmap->pm_stats, sizeof pmap->pm_stats);
+	pmap->pm_stats.resident_count = 1;
+	if (vector_page < KERNBASE) {
+		pmap_enter(pmap, vector_page, PHYS_TO_VM_PAGE(systempage.pv_pa),
+		    VM_PROT_READ, PMAP_ENTER_WIRED | VM_PROT_READ, 0);
+	}
+	return (1);
+}
+
+
+/***************************************************
+ * page management routines.
+ ***************************************************/
+
+
+static void
+pmap_free_pv_entry(pv_entry_t pv)
+{
+	pv_entry_count--;
+	uma_zfree(pvzone, pv);
+}
+
+
+/*
+ * get a new pv_entry, allocating a block from the system
+ * when needed.
+ * the memory allocation is performed bypassing the malloc code
+ * because of the possibility of allocations at interrupt time.
+ */
+static pv_entry_t
+pmap_get_pv_entry(void)
+{
+	pv_entry_t ret_value;
+	
+	pv_entry_count++;
+	if (pv_entry_count > pv_entry_high_water)
+		pagedaemon_wakeup();
+	ret_value = uma_zalloc(pvzone, M_NOWAIT);
+	return ret_value;
+}
+
+/*
+ *	Remove the given range of addresses from the specified map.
+ *
+ *	It is assumed that the start and end are properly
+ *	rounded to the page size.
+ */
+#define	PMAP_REMOVE_CLEAN_LIST_SIZE	3
+void
+pmap_remove(pmap_t pm, vm_offset_t sva, vm_offset_t eva)
+{
+	struct l2_bucket *l2b;
+	vm_offset_t next_bucket;
+	pt_entry_t *ptep;
+	u_int total;
+	u_int mappings, is_exec, is_refd;
+	int flushall = 0;
+
+
+	/*
+	 * we lock in the pmap => pv_head direction
+	 */
+
+	rw_wlock(&pvh_global_lock);
+	PMAP_LOCK(pm);
+	total = 0;
+	while (sva < eva) {
+		/*
+		 * Do one L2 bucket's worth at a time.
+		 */
+		next_bucket = L2_NEXT_BUCKET(sva);
+		if (next_bucket > eva)
+			next_bucket = eva;
+
+		l2b = pmap_get_l2_bucket(pm, sva);
+		if (l2b == NULL) {
+			sva = next_bucket;
+			continue;
+		}
+
+		ptep = &l2b->l2b_kva[l2pte_index(sva)];
+		mappings = 0;
+
+		while (sva < next_bucket) {
+			struct vm_page *pg;
+			pt_entry_t pte;
+			vm_paddr_t pa;
+
+			pte = *ptep;
+
+			if (pte == 0) {
+				/*
+				 * Nothing here, move along
+				 */
+				sva += PAGE_SIZE;
+				ptep++;
+				continue;
+			}
+
+			pm->pm_stats.resident_count--;
+			pa = l2pte_pa(pte);
+			is_exec = 0;
+			is_refd = 1;
+
+			/*
+			 * Update flags. In a number of circumstances,
+			 * we could cluster a lot of these and do a
+			 * number of sequential pages in one go.
+			 */
+			if ((pg = PHYS_TO_VM_PAGE(pa)) != NULL) {
+				struct pv_entry *pve;
+
+				pve = pmap_remove_pv(pg, pm, sva);
+				if (pve) {
+					is_exec = PV_BEEN_EXECD(pve->pv_flags);
+					is_refd = PV_BEEN_REFD(pve->pv_flags);
+					pmap_free_pv_entry(pve);
+				}
+			}
+
+			if (l2pte_valid(pte) && pmap_is_current(pm)) {
+				if (total < PMAP_REMOVE_CLEAN_LIST_SIZE) {
+					total++;
+			   		if (is_exec) {
+        					cpu_idcache_wbinv_range(sva,
+						    PAGE_SIZE);
+						cpu_l2cache_wbinv_range(sva,
+						    PAGE_SIZE);
+						cpu_tlb_flushID_SE(sva);
+			   		} else if (is_refd) {
+						cpu_dcache_wbinv_range(sva,
+						    PAGE_SIZE);
+						cpu_l2cache_wbinv_range(sva,
+						    PAGE_SIZE);
+						cpu_tlb_flushD_SE(sva);
+					}
+				} else if (total == PMAP_REMOVE_CLEAN_LIST_SIZE) {
+					/* flushall will also only get set for
+					 * for a current pmap
+					 */
+					cpu_idcache_wbinv_all();
+					cpu_l2cache_wbinv_all();
+					flushall = 1;
+					total++;
+				}
+			}
+			*ptep = 0;
+			PTE_SYNC(ptep);
+
+			sva += PAGE_SIZE;
+			ptep++;
+			mappings++;
+		}
+
+		pmap_free_l2_bucket(pm, l2b, mappings);
+	}
+
+	rw_wunlock(&pvh_global_lock);
+	if (flushall)
+		cpu_tlb_flushID();
+ 	PMAP_UNLOCK(pm);
+}
+
+/*
+ * pmap_zero_page()
+ *
+ * Zero a given physical page by mapping it at a page hook point.
+ * In doing the zero page op, the page we zero is mapped cachable, as with
+ * StrongARM accesses to non-cached pages are non-burst making writing
+ * _any_ bulk data very slow.
+ */
+#if ARM_MMU_GENERIC != 0 || defined(CPU_XSCALE_CORE3)
+void
+pmap_zero_page_generic(vm_paddr_t phys, int off, int size)
+{
+
+	if (_arm_bzero && size >= _min_bzero_size &&
+	    _arm_bzero((void *)(phys + off), size, IS_PHYSICAL) == 0)
+		return;
+
+	mtx_lock(&cmtx);
+	/*
+	 * Hook in the page, zero it, invalidate the TLB as needed.
+	 *
+	 * Note the temporary zero-page mapping must be a non-cached page in
+	 * order to work without corruption when write-allocate is enabled.
+	 */
+	*cdst_pte = L2_S_PROTO | phys | L2_S_PROT(PTE_KERNEL, VM_PROT_WRITE);
+	PTE_SYNC(cdst_pte);
+	cpu_tlb_flushD_SE(cdstp);
+	cpu_cpwait();
+	if (off || size != PAGE_SIZE)
+		bzero((void *)(cdstp + off), size);
+	else
+		bzero_page(cdstp);
+
+	mtx_unlock(&cmtx);
+}
+#endif /* ARM_MMU_GENERIC != 0 */
+
+#if ARM_MMU_XSCALE == 1
+void
+pmap_zero_page_xscale(vm_paddr_t phys, int off, int size)
+{
+
+	if (_arm_bzero && size >= _min_bzero_size &&
+	    _arm_bzero((void *)(phys + off), size, IS_PHYSICAL) == 0)
+		return;
+
+	mtx_lock(&cmtx);
+	/*
+	 * Hook in the page, zero it, and purge the cache for that
+	 * zeroed page. Invalidate the TLB as needed.
+	 */
+	*cdst_pte = L2_S_PROTO | phys |
+	    L2_S_PROT(PTE_KERNEL, VM_PROT_WRITE) |
+	    L2_C | L2_XSCALE_T_TEX(TEX_XSCALE_X);	/* mini-data */
+	PTE_SYNC(cdst_pte);
+	cpu_tlb_flushD_SE(cdstp);
+	cpu_cpwait();
+	if (off || size != PAGE_SIZE)
+		bzero((void *)(cdstp + off), size);
+	else
+		bzero_page(cdstp);
+	mtx_unlock(&cmtx);
+	xscale_cache_clean_minidata();
+}
+
+/*
+ * Change the PTEs for the specified kernel mappings such that they
+ * will use the mini data cache instead of the main data cache.
+ */
+void
+pmap_use_minicache(vm_offset_t va, vm_size_t size)
+{
+	struct l2_bucket *l2b;
+	pt_entry_t *ptep, *sptep, pte;
+	vm_offset_t next_bucket, eva;
+
+#if (ARM_NMMUS > 1) || defined(CPU_XSCALE_CORE3)
+	if (xscale_use_minidata == 0)
+		return;
+#endif
+
+	eva = va + size;
+
+	while (va < eva) {
+		next_bucket = L2_NEXT_BUCKET(va);
+		if (next_bucket > eva)
+			next_bucket = eva;
+
+		l2b = pmap_get_l2_bucket(pmap_kernel(), va);
+
+		sptep = ptep = &l2b->l2b_kva[l2pte_index(va)];
+
+		while (va < next_bucket) {
+			pte = *ptep;
+			if (!l2pte_minidata(pte)) {
+				cpu_dcache_wbinv_range(va, PAGE_SIZE);
+				cpu_tlb_flushD_SE(va);
+				*ptep = pte & ~L2_B;
+			}
+			ptep++;
+			va += PAGE_SIZE;
+		}
+		PTE_SYNC_RANGE(sptep, (u_int)(ptep - sptep));
+	}
+	cpu_cpwait();
+}
+#endif /* ARM_MMU_XSCALE == 1 */
+
+/*
+ *	pmap_zero_page zeros the specified hardware page by mapping
+ *	the page into KVM and using bzero to clear its contents.
+ */
+void
+pmap_zero_page(vm_page_t m)
+{
+	pmap_zero_page_func(VM_PAGE_TO_PHYS(m), 0, PAGE_SIZE);
+}
+
+
+/*
+ *	pmap_zero_page_area zeros the specified hardware page by mapping
+ *	the page into KVM and using bzero to clear its contents.
+ *
+ *	off and size may not cover an area beyond a single hardware page.
+ */
+void
+pmap_zero_page_area(vm_page_t m, int off, int size)
+{
+
+	pmap_zero_page_func(VM_PAGE_TO_PHYS(m), off, size);
+}
+
+
+/*
+ *	pmap_zero_page_idle zeros the specified hardware page by mapping
+ *	the page into KVM and using bzero to clear its contents.  This
+ *	is intended to be called from the vm_pagezero process only and
+ *	outside of Giant.
+ */
+void
+pmap_zero_page_idle(vm_page_t m)
+{
+
+	pmap_zero_page(m);
+}
+
+#if 0
+/*
+ * pmap_clean_page()
+ *
+ * This is a local function used to work out the best strategy to clean
+ * a single page referenced by its entry in the PV table. It should be used by
+ * pmap_copy_page, pmap_zero page and maybe some others later on.
+ *
+ * Its policy is effectively:
+ *  o If there are no mappings, we don't bother doing anything with the cache.
+ *  o If there is one mapping, we clean just that page.
+ *  o If there are multiple mappings, we clean the entire cache.
+ *
+ * So that some functions can be further optimised, it returns 0 if it didn't
+ * clean the entire cache, or 1 if it did.
+ *
+ * XXX One bug in this routine is that if the pv_entry has a single page
+ * mapped at 0x00000000 a whole cache clean will be performed rather than
+ * just the 1 page. Since this should not occur in everyday use and if it does
+ * it will just result in not the most efficient clean for the page.
+ *
+ * We don't yet use this function but may want to.
+ */
+static int
+pmap_clean_page(struct pv_entry *pv, boolean_t is_src)
+{
+	pmap_t pm, pm_to_clean = NULL;
+	struct pv_entry *npv;
+	u_int cache_needs_cleaning = 0;
+	u_int flags = 0;
+	vm_offset_t page_to_clean = 0;
+
+	if (pv == NULL) {
+		/* nothing mapped in so nothing to flush */
+		return (0);
+	}
+
+	/*
+	 * Since we flush the cache each time we change to a different
+	 * user vmspace, we only need to flush the page if it is in the
+	 * current pmap.
+	 */
+	if (curthread)
+		pm = vmspace_pmap(curproc->p_vmspace);
+	else
+		pm = pmap_kernel();
+
+	for (npv = pv; npv; npv = TAILQ_NEXT(npv, pv_list)) {
+		if (npv->pv_pmap == pmap_kernel() || npv->pv_pmap == pm) {
+			flags |= npv->pv_flags;
+			/*
+			 * The page is mapped non-cacheable in
+			 * this map.  No need to flush the cache.
+			 */
+			if (npv->pv_flags & PVF_NC) {
+#ifdef DIAGNOSTIC
+				if (cache_needs_cleaning)
+					panic("pmap_clean_page: "
+					    "cache inconsistency");
+#endif
+				break;
+			} else if (is_src && (npv->pv_flags & PVF_WRITE) == 0)
+				continue;
+			if (cache_needs_cleaning) {
+				page_to_clean = 0;
+				break;
+			} else {
+				page_to_clean = npv->pv_va;
+				pm_to_clean = npv->pv_pmap;
+			}
+			cache_needs_cleaning = 1;
+		}
+	}
+	if (page_to_clean) {
+		if (PV_BEEN_EXECD(flags))
+			pmap_idcache_wbinv_range(pm_to_clean, page_to_clean,
+			    PAGE_SIZE);
+		else
+			pmap_dcache_wb_range(pm_to_clean, page_to_clean,
+			    PAGE_SIZE, !is_src, (flags & PVF_WRITE) == 0);
+	} else if (cache_needs_cleaning) {
+		if (PV_BEEN_EXECD(flags))
+			pmap_idcache_wbinv_all(pm);
+		else
+			pmap_dcache_wbinv_all(pm);
+		return (1);
+	}
+	return (0);
+}
+#endif
+
+/*
+ *	pmap_copy_page copies the specified (machine independent)
+ *	page by mapping the page into virtual memory and using
+ *	bcopy to copy the page, one machine dependent page at a
+ *	time.
+ */
+
+/*
+ * pmap_copy_page()
+ *
+ * Copy one physical page into another, by mapping the pages into
+ * hook points. The same comment regarding cachability as in
+ * pmap_zero_page also applies here.
+ */
+#if ARM_MMU_GENERIC != 0 || defined (CPU_XSCALE_CORE3)
+void
+pmap_copy_page_generic(vm_paddr_t src, vm_paddr_t dst)
+{
+#if 0
+	struct vm_page *src_pg = PHYS_TO_VM_PAGE(src);
+#endif
+
+	/*
+	 * Clean the source page.  Hold the source page's lock for
+	 * the duration of the copy so that no other mappings can
+	 * be created while we have a potentially aliased mapping.
+	 */
+#if 0
+	/*
+	 * XXX: Not needed while we call cpu_dcache_wbinv_all() in
+	 * pmap_copy_page().
+	 */
+	(void) pmap_clean_page(TAILQ_FIRST(&src_pg->md.pv_list), TRUE);
+#endif
+	/*
+	 * Map the pages into the page hook points, copy them, and purge
+	 * the cache for the appropriate page. Invalidate the TLB
+	 * as required.
+	 */
+	mtx_lock(&cmtx);
+	*csrc_pte = L2_S_PROTO | src |
+	    L2_S_PROT(PTE_KERNEL, VM_PROT_READ) | pte_l2_s_cache_mode;
+	PTE_SYNC(csrc_pte);
+	*cdst_pte = L2_S_PROTO | dst |
+	    L2_S_PROT(PTE_KERNEL, VM_PROT_WRITE) | pte_l2_s_cache_mode;
+	PTE_SYNC(cdst_pte);
+	cpu_tlb_flushD_SE(csrcp);
+	cpu_tlb_flushD_SE(cdstp);
+	cpu_cpwait();
+	bcopy_page(csrcp, cdstp);
+	mtx_unlock(&cmtx);
+	cpu_dcache_inv_range(csrcp, PAGE_SIZE);
+	cpu_dcache_wbinv_range(cdstp, PAGE_SIZE);
+	cpu_l2cache_inv_range(csrcp, PAGE_SIZE);
+	cpu_l2cache_wbinv_range(cdstp, PAGE_SIZE);
+}
+
+void
+pmap_copy_page_offs_generic(vm_paddr_t a_phys, vm_offset_t a_offs,
+    vm_paddr_t b_phys, vm_offset_t b_offs, int cnt)
+{
+
+	mtx_lock(&cmtx);
+	*csrc_pte = L2_S_PROTO | a_phys |
+	    L2_S_PROT(PTE_KERNEL, VM_PROT_READ) | pte_l2_s_cache_mode;
+	PTE_SYNC(csrc_pte);
+	*cdst_pte = L2_S_PROTO | b_phys |
+	    L2_S_PROT(PTE_KERNEL, VM_PROT_WRITE) | pte_l2_s_cache_mode;
+	PTE_SYNC(cdst_pte);
+	cpu_tlb_flushD_SE(csrcp);
+	cpu_tlb_flushD_SE(cdstp);
+	cpu_cpwait();
+	bcopy((char *)csrcp + a_offs, (char *)cdstp + b_offs, cnt);
+	mtx_unlock(&cmtx);
+	cpu_dcache_inv_range(csrcp + a_offs, cnt);
+	cpu_dcache_wbinv_range(cdstp + b_offs, cnt);
+	cpu_l2cache_inv_range(csrcp + a_offs, cnt);
+	cpu_l2cache_wbinv_range(cdstp + b_offs, cnt);
+}
+#endif /* ARM_MMU_GENERIC != 0 */
+
+#if ARM_MMU_XSCALE == 1
+void
+pmap_copy_page_xscale(vm_paddr_t src, vm_paddr_t dst)
+{
+#if 0
+	/* XXX: Only needed for pmap_clean_page(), which is commented out. */
+	struct vm_page *src_pg = PHYS_TO_VM_PAGE(src);
+#endif
+
+	/*
+	 * Clean the source page.  Hold the source page's lock for
+	 * the duration of the copy so that no other mappings can
+	 * be created while we have a potentially aliased mapping.
+	 */
+#if 0
+	/*
+	 * XXX: Not needed while we call cpu_dcache_wbinv_all() in
+	 * pmap_copy_page().
+	 */
+	(void) pmap_clean_page(TAILQ_FIRST(&src_pg->md.pv_list), TRUE);
+#endif
+	/*
+	 * Map the pages into the page hook points, copy them, and purge
+	 * the cache for the appropriate page. Invalidate the TLB
+	 * as required.
+	 */
+	mtx_lock(&cmtx);
+	*csrc_pte = L2_S_PROTO | src |
+	    L2_S_PROT(PTE_KERNEL, VM_PROT_READ) |
+	    L2_C | L2_XSCALE_T_TEX(TEX_XSCALE_X);	/* mini-data */
+	PTE_SYNC(csrc_pte);
+	*cdst_pte = L2_S_PROTO | dst |
+	    L2_S_PROT(PTE_KERNEL, VM_PROT_WRITE) |
+	    L2_C | L2_XSCALE_T_TEX(TEX_XSCALE_X);	/* mini-data */
+	PTE_SYNC(cdst_pte);
+	cpu_tlb_flushD_SE(csrcp);
+	cpu_tlb_flushD_SE(cdstp);
+	cpu_cpwait();
+	bcopy_page(csrcp, cdstp);
+	mtx_unlock(&cmtx);
+	xscale_cache_clean_minidata();
+}
+
+void
+pmap_copy_page_offs_xscale(vm_paddr_t a_phys, vm_offset_t a_offs,
+    vm_paddr_t b_phys, vm_offset_t b_offs, int cnt)
+{
+
+	mtx_lock(&cmtx);
+	*csrc_pte = L2_S_PROTO | a_phys |
+	    L2_S_PROT(PTE_KERNEL, VM_PROT_READ) |
+	    L2_C | L2_XSCALE_T_TEX(TEX_XSCALE_X);
+	PTE_SYNC(csrc_pte);
+	*cdst_pte = L2_S_PROTO | b_phys |
+	    L2_S_PROT(PTE_KERNEL, VM_PROT_WRITE) |
+	    L2_C | L2_XSCALE_T_TEX(TEX_XSCALE_X);
+	PTE_SYNC(cdst_pte);
+	cpu_tlb_flushD_SE(csrcp);
+	cpu_tlb_flushD_SE(cdstp);
+	cpu_cpwait();
+	bcopy((char *)csrcp + a_offs, (char *)cdstp + b_offs, cnt);
+	mtx_unlock(&cmtx);
+	xscale_cache_clean_minidata();
+}
+#endif /* ARM_MMU_XSCALE == 1 */
+
+void
+pmap_copy_page(vm_page_t src, vm_page_t dst)
+{
+
+	cpu_dcache_wbinv_all();
+	cpu_l2cache_wbinv_all();
+	if (_arm_memcpy && PAGE_SIZE >= _min_memcpy_size &&
+	    _arm_memcpy((void *)VM_PAGE_TO_PHYS(dst),
+	    (void *)VM_PAGE_TO_PHYS(src), PAGE_SIZE, IS_PHYSICAL) == 0)
+		return;
+	pmap_copy_page_func(VM_PAGE_TO_PHYS(src), VM_PAGE_TO_PHYS(dst));
+}
+
+/*
+ * We have code to do unmapped I/O. However, it isn't quite right and
+ * causes un-page-aligned I/O to devices to fail (most notably newfs
+ * or fsck). We give up a little performance to not allow unmapped I/O
+ * to gain stability.
+ */
+int unmapped_buf_allowed = 0;
+
+void
+pmap_copy_pages(vm_page_t ma[], vm_offset_t a_offset, vm_page_t mb[],
+    vm_offset_t b_offset, int xfersize)
+{
+	vm_page_t a_pg, b_pg;
+	vm_offset_t a_pg_offset, b_pg_offset;
+	int cnt;
+
+	cpu_dcache_wbinv_all();
+	cpu_l2cache_wbinv_all();
+	while (xfersize > 0) {
+		a_pg = ma[a_offset >> PAGE_SHIFT];
+		a_pg_offset = a_offset & PAGE_MASK;
+		cnt = min(xfersize, PAGE_SIZE - a_pg_offset);
+		b_pg = mb[b_offset >> PAGE_SHIFT];
+		b_pg_offset = b_offset & PAGE_MASK;
+		cnt = min(cnt, PAGE_SIZE - b_pg_offset);
+		pmap_copy_page_offs_func(VM_PAGE_TO_PHYS(a_pg), a_pg_offset,
+		    VM_PAGE_TO_PHYS(b_pg), b_pg_offset, cnt);
+		xfersize -= cnt;
+		a_offset += cnt;
+		b_offset += cnt;
+	}
+}
+
+/*
+ * this routine returns true if a physical page resides
+ * in the given pmap.
+ */
+boolean_t
+pmap_page_exists_quick(pmap_t pmap, vm_page_t m)
+{
+	pv_entry_t pv;
+	int loops = 0;
+	boolean_t rv;
+	
+	KASSERT((m->oflags & VPO_UNMANAGED) == 0,
+	    ("pmap_page_exists_quick: page %p is not managed", m));
+	rv = FALSE;
+	rw_wlock(&pvh_global_lock);
+	TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
+	    	if (pv->pv_pmap == pmap) {
+			rv = TRUE;
+			break;
+	    	}
+		loops++;
+		if (loops >= 16)
+			break;
+	}
+	rw_wunlock(&pvh_global_lock);
+	return (rv);
+}
+
+/*
+ *	pmap_page_wired_mappings:
+ *
+ *	Return the number of managed mappings to the given physical page
+ *	that are wired.
+ */
+int
+pmap_page_wired_mappings(vm_page_t m)
+{
+	pv_entry_t pv;
+	int count;
+
+	count = 0;
+	if ((m->oflags & VPO_UNMANAGED) != 0)
+		return (count);
+	rw_wlock(&pvh_global_lock);
+	TAILQ_FOREACH(pv, &m->md.pv_list, pv_list)
+		if ((pv->pv_flags & PVF_WIRED) != 0)
+			count++;
+	rw_wunlock(&pvh_global_lock);
+	return (count);
+}
+
+/*
+ *	This function is advisory.
+ */
+void
+pmap_advise(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, int advice)
+{
+}
+
+/*
+ *	pmap_ts_referenced:
+ *
+ *	Return the count of reference bits for a page, clearing all of them.
+ */
+int
+pmap_ts_referenced(vm_page_t m)
+{
+
+	KASSERT((m->oflags & VPO_UNMANAGED) == 0,
+	    ("pmap_ts_referenced: page %p is not managed", m));
+	return (pmap_clearbit(m, PVF_REF));
+}
+
+
+boolean_t
+pmap_is_modified(vm_page_t m)
+{
+
+	KASSERT((m->oflags & VPO_UNMANAGED) == 0,
+	    ("pmap_is_modified: page %p is not managed", m));
+	if (m->md.pvh_attrs & PVF_MOD)
+		return (TRUE);
+	
+	return(FALSE);
+}
+
+
+/*
+ *	Clear the modify bits on the specified physical page.
+ */
+void
+pmap_clear_modify(vm_page_t m)
+{
+
+	KASSERT((m->oflags & VPO_UNMANAGED) == 0,
+	    ("pmap_clear_modify: page %p is not managed", m));
+	VM_OBJECT_ASSERT_WLOCKED(m->object);
+	KASSERT(!vm_page_xbusied(m),
+	    ("pmap_clear_modify: page %p is exclusive busied", m));
+
+	/*
+	 * If the page is not PGA_WRITEABLE, then no mappings can be modified.
+	 * If the object containing the page is locked and the page is not
+	 * exclusive busied, then PGA_WRITEABLE cannot be concurrently set.
+	 */
+	if ((m->aflags & PGA_WRITEABLE) == 0)
+		return;
+	if (m->md.pvh_attrs & PVF_MOD)
+		pmap_clearbit(m, PVF_MOD);
+}
+
+
+/*
+ *	pmap_is_referenced:
+ *
+ *	Return whether or not the specified physical page was referenced
+ *	in any physical maps.
+ */
+boolean_t
+pmap_is_referenced(vm_page_t m)
+{
+
+	KASSERT((m->oflags & VPO_UNMANAGED) == 0,
+	    ("pmap_is_referenced: page %p is not managed", m));
+	return ((m->md.pvh_attrs & PVF_REF) != 0);
+}
+
+
+/*
+ * Clear the write and modified bits in each of the given page's mappings.
+ */
+void
+pmap_remove_write(vm_page_t m)
+{
+
+	KASSERT((m->oflags & VPO_UNMANAGED) == 0,
+	    ("pmap_remove_write: page %p is not managed", m));
+
+	/*
+	 * If the page is not exclusive busied, then PGA_WRITEABLE cannot be
+	 * set by another thread while the object is locked.  Thus,
+	 * if PGA_WRITEABLE is clear, no page table entries need updating.
+	 */
+	VM_OBJECT_ASSERT_WLOCKED(m->object);
+	if (vm_page_xbusied(m) || (m->aflags & PGA_WRITEABLE) != 0)
+		pmap_clearbit(m, PVF_WRITE);
+}
+
+
+/*
+ * perform the pmap work for mincore
+ */
+int
+pmap_mincore(pmap_t pmap, vm_offset_t addr, vm_paddr_t *locked_pa)
+{
+	struct l2_bucket *l2b;
+	pt_entry_t *ptep, pte;
+	vm_paddr_t pa;
+	vm_page_t m;
+	int val;
+	boolean_t managed;
+
+	PMAP_LOCK(pmap);
+retry:
+	l2b = pmap_get_l2_bucket(pmap, addr);
+        if (l2b == NULL) {
+                val = 0;
+                goto out;
+        }
+	ptep = &l2b->l2b_kva[l2pte_index(addr)];
+	pte = *ptep;
+	if (!l2pte_valid(pte)) {
+		val = 0;
+		goto out;
+	}
+	val = MINCORE_INCORE;
+	if (pte & L2_S_PROT_W)
+		val |= MINCORE_MODIFIED | MINCORE_MODIFIED_OTHER;
+        managed = false;
+	pa = l2pte_pa(pte);
+        m = PHYS_TO_VM_PAGE(pa);
+        if (m != NULL && !(m->oflags & VPO_UNMANAGED))
+                managed = true;
+	if (managed) {
+		/*
+		 * The ARM pmap tries to maintain a per-mapping
+		 * reference bit.  The trouble is that it's kept in
+		 * the PV entry, not the PTE, so it's costly to access
+		 * here.  You would need to acquire the pvh global
+		 * lock, call pmap_find_pv(), and introduce a custom
+		 * version of vm_page_pa_tryrelock() that releases and
+		 * reacquires the pvh global lock.  In the end, I
+		 * doubt it's worthwhile.  This may falsely report
+		 * the given address as referenced.
+		 */
+		if ((m->md.pvh_attrs & PVF_REF) != 0)
+			val |= MINCORE_REFERENCED | MINCORE_REFERENCED_OTHER;
+	}
+	if ((val & (MINCORE_MODIFIED_OTHER | MINCORE_REFERENCED_OTHER)) !=
+	    (MINCORE_MODIFIED_OTHER | MINCORE_REFERENCED_OTHER) && managed) {
+		/* Ensure that "PHYS_TO_VM_PAGE(pa)->object" doesn't change. */
+		if (vm_page_pa_tryrelock(pmap, pa, locked_pa))
+			goto retry;
+	} else
+out:
+		PA_UNLOCK_COND(*locked_pa);
+	PMAP_UNLOCK(pmap);
+	return (val);
+}
+
+
+void
+pmap_sync_icache(pmap_t pm, vm_offset_t va, vm_size_t sz)
+{
+}
+
+
+/*
+ *	Increase the starting virtual address of the given mapping if a
+ *	different alignment might result in more superpage mappings.
+ */
+void
+pmap_align_superpage(vm_object_t object, vm_ooffset_t offset,
+    vm_offset_t *addr, vm_size_t size)
+{
+}
+
+#define BOOTSTRAP_DEBUG
+
+/*
+ * pmap_map_section:
+ *
+ *	Create a single section mapping.
+ */
+void
+pmap_map_section(vm_offset_t l1pt, vm_offset_t va, vm_offset_t pa,
+    int prot, int cache)
+{
+	pd_entry_t *pde = (pd_entry_t *) l1pt;
+	pd_entry_t fl;
+
+	KASSERT(((va | pa) & L1_S_OFFSET) == 0, ("ouin2"));
+
+	switch (cache) {
+	case PTE_NOCACHE:
+	default:
+		fl = 0;
+		break;
+
+	case PTE_CACHE:
+		fl = pte_l1_s_cache_mode;
+		break;
+
+	case PTE_PAGETABLE:
+		fl = pte_l1_s_cache_mode_pt;
+		break;
+	}
+
+	pde[va >> L1_S_SHIFT] = L1_S_PROTO | pa |
+	    L1_S_PROT(PTE_KERNEL, prot) | fl | L1_S_DOM(PMAP_DOMAIN_KERNEL);
+	PTE_SYNC(&pde[va >> L1_S_SHIFT]);
+
+}
+
+/*
+ * pmap_link_l2pt:
+ *
+ *	Link the L2 page table specified by l2pv.pv_pa into the L1
+ *	page table at the slot for "va".
+ */
+void
+pmap_link_l2pt(vm_offset_t l1pt, vm_offset_t va, struct pv_addr *l2pv)
+{
+	pd_entry_t *pde = (pd_entry_t *) l1pt, proto;
+	u_int slot = va >> L1_S_SHIFT;
+
+	proto = L1_S_DOM(PMAP_DOMAIN_KERNEL) | L1_C_PROTO;
+
+#ifdef VERBOSE_INIT_ARM
+	printf("pmap_link_l2pt: pa=0x%x va=0x%x\n", l2pv->pv_pa, l2pv->pv_va);
+#endif
+
+	pde[slot + 0] = proto | (l2pv->pv_pa + 0x000);
+
+	PTE_SYNC(&pde[slot]);
+
+	SLIST_INSERT_HEAD(&kernel_pt_list, l2pv, pv_list);
+
+	
+}
+
+/*
+ * pmap_map_entry
+ *
+ * 	Create a single page mapping.
+ */
+void
+pmap_map_entry(vm_offset_t l1pt, vm_offset_t va, vm_offset_t pa, int prot,
+    int cache)
+{
+	pd_entry_t *pde = (pd_entry_t *) l1pt;
+	pt_entry_t fl;
+	pt_entry_t *pte;
+
+	KASSERT(((va | pa) & PAGE_MASK) == 0, ("ouin"));
+
+	switch (cache) {
+	case PTE_NOCACHE:
+	default:
+		fl = 0;
+		break;
+
+	case PTE_CACHE:
+		fl = pte_l2_s_cache_mode;
+		break;
+
+	case PTE_PAGETABLE:
+		fl = pte_l2_s_cache_mode_pt;
+		break;
+	}
+
+	if ((pde[va >> L1_S_SHIFT] & L1_TYPE_MASK) != L1_TYPE_C)
+		panic("pmap_map_entry: no L2 table for VA 0x%08x", va);
+
+	pte = (pt_entry_t *) kernel_pt_lookup(pde[L1_IDX(va)] & L1_C_ADDR_MASK);
+
+	if (pte == NULL)
+		panic("pmap_map_entry: can't find L2 table for VA 0x%08x", va);
+
+	pte[l2pte_index(va)] =
+	    L2_S_PROTO | pa | L2_S_PROT(PTE_KERNEL, prot) | fl;
+	PTE_SYNC(&pte[l2pte_index(va)]);
+}
+
+/*
+ * pmap_map_chunk:
+ *
+ *	Map a chunk of memory using the most efficient mappings
+ *	possible (section. large page, small page) into the
+ *	provided L1 and L2 tables at the specified virtual address.
+ */
+vm_size_t
+pmap_map_chunk(vm_offset_t l1pt, vm_offset_t va, vm_offset_t pa,
+    vm_size_t size, int prot, int cache)
+{
+	pd_entry_t *pde = (pd_entry_t *) l1pt;
+	pt_entry_t *pte, f1, f2s, f2l;
+	vm_size_t resid;
+	int i;
+
+	resid = (size + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
+
+	if (l1pt == 0)
+		panic("pmap_map_chunk: no L1 table provided");
+
+#ifdef VERBOSE_INIT_ARM
+	printf("pmap_map_chunk: pa=0x%x va=0x%x size=0x%x resid=0x%x "
+	    "prot=0x%x cache=%d\n", pa, va, size, resid, prot, cache);
+#endif
+
+	switch (cache) {
+	case PTE_NOCACHE:
+	default:
+		f1 = 0;
+		f2l = 0;
+		f2s = 0;
+		break;
+
+	case PTE_CACHE:
+		f1 = pte_l1_s_cache_mode;
+		f2l = pte_l2_l_cache_mode;
+		f2s = pte_l2_s_cache_mode;
+		break;
+
+	case PTE_PAGETABLE:
+		f1 = pte_l1_s_cache_mode_pt;
+		f2l = pte_l2_l_cache_mode_pt;
+		f2s = pte_l2_s_cache_mode_pt;
+		break;
+	}
+
+	size = resid;
+
+	while (resid > 0) {
+		/* See if we can use a section mapping. */
+		if (L1_S_MAPPABLE_P(va, pa, resid)) {
+#ifdef VERBOSE_INIT_ARM
+			printf("S");
+#endif
+			pde[va >> L1_S_SHIFT] = L1_S_PROTO | pa |
+			    L1_S_PROT(PTE_KERNEL, prot) | f1 |
+			    L1_S_DOM(PMAP_DOMAIN_KERNEL);
+			PTE_SYNC(&pde[va >> L1_S_SHIFT]);
+			va += L1_S_SIZE;
+			pa += L1_S_SIZE;
+			resid -= L1_S_SIZE;
+			continue;
+		}
+
+		/*
+		 * Ok, we're going to use an L2 table.  Make sure
+		 * one is actually in the corresponding L1 slot
+		 * for the current VA.
+		 */
+		if ((pde[va >> L1_S_SHIFT] & L1_TYPE_MASK) != L1_TYPE_C)
+			panic("pmap_map_chunk: no L2 table for VA 0x%08x", va);
+
+		pte = (pt_entry_t *) kernel_pt_lookup(
+		    pde[L1_IDX(va)] & L1_C_ADDR_MASK);
+		if (pte == NULL)
+			panic("pmap_map_chunk: can't find L2 table for VA"
+			    "0x%08x", va);
+		/* See if we can use a L2 large page mapping. */
+		if (L2_L_MAPPABLE_P(va, pa, resid)) {
+#ifdef VERBOSE_INIT_ARM
+			printf("L");
+#endif
+			for (i = 0; i < 16; i++) {
+				pte[l2pte_index(va) + i] =
+				    L2_L_PROTO | pa |
+				    L2_L_PROT(PTE_KERNEL, prot) | f2l;
+				PTE_SYNC(&pte[l2pte_index(va) + i]);
+			}
+			va += L2_L_SIZE;
+			pa += L2_L_SIZE;
+			resid -= L2_L_SIZE;
+			continue;
+		}
+
+		/* Use a small page mapping. */
+#ifdef VERBOSE_INIT_ARM
+		printf("P");
+#endif
+		pte[l2pte_index(va)] =
+		    L2_S_PROTO | pa | L2_S_PROT(PTE_KERNEL, prot) | f2s;
+		PTE_SYNC(&pte[l2pte_index(va)]);
+		va += PAGE_SIZE;
+		pa += PAGE_SIZE;
+		resid -= PAGE_SIZE;
+	}
+#ifdef VERBOSE_INIT_ARM
+	printf("\n");
+#endif
+	return (size);
+
+}
+
+void
+pmap_page_set_memattr(vm_page_t m, vm_memattr_t ma)
+{
+	/* 
+	 * Remember the memattr in a field that gets used to set the appropriate
+	 * bits in the PTEs as mappings are established.
+	 */
+	m->md.pv_memattr = ma;
+
+	/*
+	 * It appears that this function can only be called before any mappings
+	 * for the page are established on ARM.  If this ever changes, this code
+	 * will need to walk the pv_list and make each of the existing mappings
+	 * uncacheable, being careful to sync caches and PTEs (and maybe
+	 * invalidate TLB?) for any current mapping it modifies.
+	 */
+	if (m->md.pv_kva != 0 || TAILQ_FIRST(&m->md.pv_list) != NULL)
+		panic("Can't change memattr on page with existing mappings");
+}
+
+


Property changes on: trunk/sys/arm/arm/pmap.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/sc_machdep.c
===================================================================
--- trunk/sys/arm/arm/sc_machdep.c	                        (rev 0)
+++ trunk/sys/arm/arm/sc_machdep.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,91 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2003 Jake Burkholder.
+ * 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: stable/10/sys/arm/arm/sc_machdep.c 239696 2012-08-25 23:59:31Z gonzo $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/cons.h>
+#include <sys/kbio.h>
+#include <sys/consio.h>
+#include <sys/sysctl.h>
+
+#include <dev/syscons/syscons.h>
+
+static sc_softc_t sc_softcs[8];
+
+int
+sc_get_cons_priority(int *unit, int *flags)
+{
+
+	*unit = 0;
+	*flags = 0;
+	return (CN_INTERNAL);
+}
+
+int
+sc_max_unit(void)
+{
+	return (1);
+}
+
+sc_softc_t *
+sc_get_softc(int unit, int flags)
+{
+	sc_softc_t *sc;
+
+	if (unit < 0)
+		return (NULL);
+	sc = &sc_softcs[unit];
+	sc->unit = unit;
+	if ((sc->flags & SC_INIT_DONE) == 0) {
+		sc->keyboard = -1;
+		sc->adapter = -1;
+		sc->cursor_char = SC_CURSOR_CHAR;
+		sc->mouse_char = SC_MOUSE_CHAR;
+	}
+	return (sc);
+}
+
+void
+sc_get_bios_values(bios_values_t *values)
+{
+	values->cursor_start = 0;
+	values->cursor_end = 32;
+	values->shift_state = 0;
+}
+
+int
+sc_tone(int hz)
+{
+	return (0);
+}


Property changes on: trunk/sys/arm/arm/sc_machdep.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/setcpsr.S
===================================================================
--- trunk/sys/arm/arm/setcpsr.S	                        (rev 0)
+++ trunk/sys/arm/arm/setcpsr.S	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,83 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: setcpsr.S,v 1.2 2002/08/15 01:37:02 briggs Exp $	*/
+
+/*-
+ * Copyright (c) 1994 Mark Brinicombe.
+ * Copyright (c) 1994 Brini.
+ * All rights reserved.
+ *
+ * This code is derived from software written for Brini by Mark Brinicombe
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Brini.
+ * 4. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BRINI ``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 BRINI 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.
+ *
+ * RiscBSD kernel project
+ *
+ * setcpsr.S
+ *
+ * Miscellaneous routines to play with the CPSR register
+ *
+ * Eventually this routine can be inline assembly.
+ *
+ * Created      : 12/09/94
+ *
+ * Based of kate/display/setcpsr.s
+ *
+ */
+
+#include <machine/asm.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/setcpsr.S 266144 2014-05-15 15:40:05Z ian $");
+
+/* Sets and clears bits in the CPSR register
+ *
+ *  r0 - bic mask
+ *  r1 - eor mask
+ */
+
+ENTRY_NP(SetCPSR)
+        mrs     r3, cpsr		/* Set the CPSR */
+	bic	r2, r3, r0
+        eor     r2, r2, r1
+        msr     cpsr_fsxc, r2
+
+        mov	r0, r3			/* Return the old CPSR */
+
+	RET
+END(SetCPSR)
+
+
+/* Gets the CPSR register
+ *
+ * Returns the CPSR in r0
+ */
+
+ENTRY_NP(GetCPSR)
+        mrs     r0, cpsr		/* Get the CPSR */
+
+	RET
+END(GetCPSR)
+


Property changes on: trunk/sys/arm/arm/setcpsr.S
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/setstack.s
===================================================================
--- trunk/sys/arm/arm/setstack.s	                        (rev 0)
+++ trunk/sys/arm/arm/setstack.s	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,95 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: setstack.S,v 1.1 2001/07/28 13:28:03 chris Exp $	*/
+
+/*-
+ * Copyright (c) 1994 Mark Brinicombe.
+ * Copyright (c) 1994 Brini.
+ * All rights reserved.
+ *
+ * This code is derived from software written for Brini by Mark Brinicombe
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Brini.
+ * 4. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BRINI ``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 BRINI 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.
+ *
+ * RiscBSD kernel project
+ *
+ * setstack.S
+ *
+ * Miscellaneous routine to play with the stack pointer in different CPU modes
+ *
+ * Eventually this routine can be inline assembly.
+ *
+ * Created      : 17/09/94
+ *
+ * Based of kate/display/setstack.s
+ *
+ */
+
+#include <machine/armreg.h>
+#include <machine/asm.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/setstack.s 269796 2014-08-11 01:29:28Z ian $");
+
+/* To set the stack pointer for a particular mode we must switch
+ * to that mode update the banked r13 and then switch back.
+ * This routine provides an easy way of doing this for any mode
+ *
+ * r0 = CPU mode
+ * r1 = stackptr
+ */
+
+ENTRY(set_stackptr)
+        mrs	r3, cpsr		/* Switch to the appropriate mode */
+	bic	r2, r3, #(PSR_MODE)
+	orr	r2, r2, r0
+        msr	cpsr_fsxc, r2
+
+	mov	sp, r1			/* Set the stack pointer */
+
+        msr	cpsr_fsxc, r3		/* Restore the old mode */
+
+	mov	pc, lr			/* Exit */
+END(set_stackptr)
+/* To get the stack pointer for a particular mode we must switch
+ * to that mode copy the banked r13 and then switch back.
+ * This routine provides an easy way of doing this for any mode
+ *
+ * r0 = CPU mode
+ */
+
+ENTRY(get_stackptr)
+        mrs	r3, cpsr		/* Switch to the appropriate mode */
+	bic	r2, r3, #(PSR_MODE)
+	orr	r2, r2, r0
+        msr	cpsr_fsxc, r2
+
+	mov	r0, sp			/* Set the stack pointer */
+
+        msr	cpsr_fsxc, r3		/* Restore the old mode */
+
+	mov	pc, lr			/* Exit */
+END(get_stackptr)
+/* End of setstack.S */


Property changes on: trunk/sys/arm/arm/setstack.s
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/stack_machdep.c
===================================================================
--- trunk/sys/arm/arm/stack_machdep.c	                        (rev 0)
+++ trunk/sys/arm/arm/stack_machdep.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,93 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2005 Antoine Brodin
+ * 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: stable/10/sys/arm/arm/stack_machdep.c 278614 2015-02-12 04:15:55Z ian $");
+
+#include <sys/systm.h>
+#include <sys/param.h>
+#include <sys/proc.h>
+#include <sys/stack.h>
+
+#include <machine/vmparam.h>
+#include <machine/pcb.h>
+#include <machine/stack.h>
+
+/*
+ * This code makes assumptions about the stack layout. These are correct
+ * when using APCS (the old ABI), but are no longer true with AAPCS and the
+ * ARM EABI. There is also an issue with clang and llvm when building for
+ * APCS where it lays out the stack incorrectly. Because of this we disable
+ * this when building for ARM EABI or when building with clang.
+ */
+
+extern vm_offset_t kernel_vm_end;
+
+static void
+stack_capture(struct stack *st, u_int32_t *frame)
+{
+#if !defined(__ARM_EABI__) && !defined(__clang__)
+	vm_offset_t callpc;
+
+	while (INKERNEL(frame) && (vm_offset_t)frame < kernel_vm_end) {
+		callpc = frame[FR_SCP];
+		if (stack_put(st, callpc) == -1)
+			break;
+		frame = (u_int32_t *)(frame[FR_RFP]);
+	}
+#endif
+}
+
+void
+stack_save_td(struct stack *st, struct thread *td)
+{
+	u_int32_t *frame;
+
+	if (TD_IS_SWAPPED(td))
+		panic("stack_save_td: swapped");
+	if (TD_IS_RUNNING(td))
+		panic("stack_save_td: running");
+
+	/*
+	 * This register, the frame pointer, is incorrect for the ARM EABI
+	 * as it doesn't have a frame pointer, however it's value is not used
+	 * when building for EABI.
+	 */
+	frame = (u_int32_t *)td->td_pcb->pcb_regs.sf_r11;
+	stack_zero(st);
+	stack_capture(st, frame);
+}
+
+void
+stack_save(struct stack *st)
+{
+	u_int32_t *frame;
+
+	frame = (u_int32_t *)__builtin_frame_address(0);
+	stack_zero(st);
+	stack_capture(st, frame);
+}


Property changes on: trunk/sys/arm/arm/stack_machdep.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/stdatomic.c
===================================================================
--- trunk/sys/arm/arm/stdatomic.c	                        (rev 0)
+++ trunk/sys/arm/arm/stdatomic.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,895 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Ed Schouten <ed at FreeBSD.org>
+ * 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: stable/10/sys/arm/arm/stdatomic.c 275776 2014-12-14 18:28:01Z andrew $");
+
+#include <sys/param.h>
+#include <sys/stdatomic.h>
+#include <sys/types.h>
+
+#include <machine/cpufunc.h>
+#include <machine/sysarch.h>
+
+#ifdef _KERNEL
+#include "opt_global.h"
+#endif
+
+/*
+ * Executing statements with interrupts disabled.
+ */
+
+#if defined(_KERNEL) && !defined(SMP)
+#define	WITHOUT_INTERRUPTS(s) do {					\
+	register_t regs;						\
+									\
+	regs = intr_disable();						\
+	do s while (0);							\
+	intr_restore(regs);						\
+} while (0)
+#endif /* _KERNEL && !SMP */
+
+/*
+ * Memory barriers.
+ *
+ * It turns out __sync_synchronize() does not emit any code when used
+ * with GCC 4.2. Implement our own version that does work reliably.
+ *
+ * Although __sync_lock_test_and_set() should only perform an acquire
+ * barrier, make it do a full barrier like the other functions. This
+ * should make <stdatomic.h>'s atomic_exchange_explicit() work reliably.
+ */
+
+#if defined(_KERNEL) && !defined(SMP)
+static inline void
+do_sync(void)
+{
+
+	__asm volatile ("" : : : "memory");
+}
+#elif defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__)
+static inline void
+do_sync(void)
+{
+
+	__asm volatile ("dmb" : : : "memory");
+}
+#elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || \
+    defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || \
+    defined(__ARM_ARCH_6ZK__)
+static inline void
+do_sync(void)
+{
+
+	__asm volatile ("mcr p15, 0, %0, c7, c10, 5" : : "r" (0) : "memory");
+}
+#endif
+
+#if defined(__CLANG_ATOMICS) || defined(__GNUC_ATOMICS)
+
+/*
+ * New C11 __atomic_* API.
+ */
+
+#if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || \
+    defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || \
+    defined(__ARM_ARCH_6ZK__) || \
+    defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__)
+
+/* These systems should be supported by the compiler. */
+
+#else /* __ARM_ARCH_5__ */
+
+/* Clang doesn't allow us to reimplement builtins without this. */
+#ifdef __clang__
+#pragma redefine_extname __sync_synchronize_ext __sync_synchronize
+#define __sync_synchronize __sync_synchronize_ext
+#endif
+
+void
+__sync_synchronize(void)
+{
+}
+
+#ifdef _KERNEL
+
+#ifdef SMP
+#error "On SMP systems we should have proper atomic operations."
+#endif
+
+/*
+ * On uniprocessor systems, we can perform the atomic operations by
+ * disabling interrupts.
+ */
+
+#define	EMIT_LOAD_N(N, uintN_t)						\
+uintN_t									\
+__atomic_load_##N(uintN_t *mem, int model __unused)			\
+{									\
+	uintN_t ret;							\
+									\
+	WITHOUT_INTERRUPTS({						\
+		ret = *mem;						\
+	});								\
+	return (ret);							\
+}
+
+#define	EMIT_STORE_N(N, uintN_t)					\
+void									\
+__atomic_store_##N(uintN_t *mem, uintN_t val, int model __unused)	\
+{									\
+									\
+	WITHOUT_INTERRUPTS({						\
+		*mem = val;						\
+	});								\
+}
+
+#define	EMIT_COMPARE_EXCHANGE_N(N, uintN_t)				\
+_Bool									\
+__atomic_compare_exchange_##N(uintN_t *mem, uintN_t *expected,		\
+    uintN_t desired, int success __unused, int failure __unused)	\
+{									\
+	_Bool ret;							\
+									\
+	WITHOUT_INTERRUPTS({						\
+		if (*mem == *expected) {				\
+			*mem = desired;					\
+			ret = 1;					\
+		} else {						\
+			*expected = *mem;				\
+			ret = 0;					\
+		}							\
+	});								\
+	return (ret);							\
+}
+
+#define	EMIT_FETCH_OP_N(N, uintN_t, name, op)				\
+uintN_t									\
+__atomic_##name##_##N(uintN_t *mem, uintN_t val, int model __unused)	\
+{									\
+	uintN_t ret;							\
+									\
+	WITHOUT_INTERRUPTS({						\
+		ret = *mem;						\
+		*mem op val;						\
+	});								\
+	return (ret);							\
+}
+
+#define	EMIT_ALL_OPS_N(N, uintN_t)					\
+EMIT_LOAD_N(N, uintN_t)							\
+EMIT_STORE_N(N, uintN_t)						\
+EMIT_COMPARE_EXCHANGE_N(N, uintN_t)					\
+EMIT_FETCH_OP_N(N, uintN_t, exchange, =)				\
+EMIT_FETCH_OP_N(N, uintN_t, fetch_add, +=)				\
+EMIT_FETCH_OP_N(N, uintN_t, fetch_and, &=)				\
+EMIT_FETCH_OP_N(N, uintN_t, fetch_or, |=)				\
+EMIT_FETCH_OP_N(N, uintN_t, fetch_sub, -=)				\
+EMIT_FETCH_OP_N(N, uintN_t, fetch_xor, ^=)
+
+EMIT_ALL_OPS_N(1, uint8_t)
+EMIT_ALL_OPS_N(2, uint16_t)
+EMIT_ALL_OPS_N(4, uint32_t)
+EMIT_ALL_OPS_N(8, uint64_t)
+#undef	EMIT_ALL_OPS_N
+
+#else /* !_KERNEL */
+
+/*
+ * For userspace on uniprocessor systems, we can implement the atomic
+ * operations by using a Restartable Atomic Sequence. This makes the
+ * kernel restart the code from the beginning when interrupted.
+ */
+
+#define	EMIT_LOAD_N(N, uintN_t)						\
+uintN_t									\
+__atomic_load_##N(uintN_t *mem, int model __unused)			\
+{									\
+									\
+	return (*mem);							\
+}
+
+#define	EMIT_STORE_N(N, uintN_t)					\
+void									\
+__atomic_store_##N(uintN_t *mem, uintN_t val, int model __unused)	\
+{									\
+									\
+	*mem = val;							\
+}
+
+#define	EMIT_EXCHANGE_N(N, uintN_t, ldr, str)				\
+uintN_t									\
+__atomic_exchange_##N(uintN_t *mem, uintN_t val, int model __unused)	\
+{									\
+	uint32_t old, temp, ras_start;					\
+									\
+	ras_start = ARM_RAS_START;					\
+	__asm volatile (						\
+		/* Set up Restartable Atomic Sequence. */		\
+		"1:"							\
+		"\tadr   %2, 1b\n"					\
+		"\tstr   %2, [%5]\n"					\
+		"\tadr   %2, 2f\n"					\
+		"\tstr   %2, [%5, #4]\n"				\
+									\
+		"\t"ldr" %0, %4\n"	/* Load old value. */		\
+		"\t"str" %3, %1\n"	/* Store new value. */		\
+									\
+		/* Tear down Restartable Atomic Sequence. */		\
+		"2:"							\
+		"\tmov   %2, #0x00000000\n"				\
+		"\tstr   %2, [%5]\n"					\
+		"\tmov   %2, #0xffffffff\n"				\
+		"\tstr   %2, [%5, #4]\n"				\
+		: "=&r" (old), "=m" (*mem), "=&r" (temp)		\
+		: "r" (val), "m" (*mem), "r" (ras_start));		\
+	return (old);							\
+}
+
+#define	EMIT_COMPARE_EXCHANGE_N(N, uintN_t, ldr, streq)			\
+_Bool									\
+__atomic_compare_exchange_##N(uintN_t *mem, uintN_t *pexpected,		\
+    uintN_t desired, int success __unused, int failure __unused)	\
+{									\
+	uint32_t expected, old, temp, ras_start;			\
+									\
+	expected = *pexpected;						\
+	ras_start = ARM_RAS_START;					\
+	__asm volatile (						\
+		/* Set up Restartable Atomic Sequence. */		\
+		"1:"							\
+		"\tadr   %2, 1b\n"					\
+		"\tstr   %2, [%6]\n"					\
+		"\tadr   %2, 2f\n"					\
+		"\tstr   %2, [%6, #4]\n"				\
+									\
+		"\t"ldr" %0, %5\n"	/* Load old value. */		\
+		"\tcmp   %0, %3\n"	/* Compare to expected value. */\
+		"\t"streq" %4, %1\n"	/* Store new value. */		\
+									\
+		/* Tear down Restartable Atomic Sequence. */		\
+		"2:"							\
+		"\tmov   %2, #0x00000000\n"				\
+		"\tstr   %2, [%6]\n"					\
+		"\tmov   %2, #0xffffffff\n"				\
+		"\tstr   %2, [%6, #4]\n"				\
+		: "=&r" (old), "=m" (*mem), "=&r" (temp)		\
+		: "r" (expected), "r" (desired), "m" (*mem),		\
+		  "r" (ras_start));					\
+	if (old == expected) {						\
+		return (1);						\
+	} else {							\
+		*pexpected = old;					\
+		return (0);						\
+	}								\
+}
+
+#define	EMIT_FETCH_OP_N(N, uintN_t, ldr, str, name, op)			\
+uintN_t									\
+__atomic_##name##_##N(uintN_t *mem, uintN_t val, int model __unused)	\
+{									\
+	uint32_t old, temp, ras_start;					\
+									\
+	ras_start = ARM_RAS_START;					\
+	__asm volatile (						\
+		/* Set up Restartable Atomic Sequence. */		\
+		"1:"							\
+		"\tadr   %2, 1b\n"					\
+		"\tstr   %2, [%5]\n"					\
+		"\tadr   %2, 2f\n"					\
+		"\tstr   %2, [%5, #4]\n"				\
+									\
+		"\t"ldr" %0, %4\n"	/* Load old value. */		\
+		"\t"op"  %2, %0, %3\n"	/* Calculate new value. */	\
+		"\t"str" %2, %1\n"	/* Store new value. */		\
+									\
+		/* Tear down Restartable Atomic Sequence. */		\
+		"2:"							\
+		"\tmov   %2, #0x00000000\n"				\
+		"\tstr   %2, [%5]\n"					\
+		"\tmov   %2, #0xffffffff\n"				\
+		"\tstr   %2, [%5, #4]\n"				\
+		: "=&r" (old), "=m" (*mem), "=&r" (temp)		\
+		: "r" (val), "m" (*mem), "r" (ras_start));		\
+	return (old);							\
+}
+
+#define	EMIT_ALL_OPS_N(N, uintN_t, ldr, str, streq)			\
+EMIT_LOAD_N(N, uintN_t)							\
+EMIT_STORE_N(N, uintN_t)						\
+EMIT_EXCHANGE_N(N, uintN_t, ldr, str)					\
+EMIT_COMPARE_EXCHANGE_N(N, uintN_t, ldr, streq)				\
+EMIT_FETCH_OP_N(N, uintN_t, ldr, str, fetch_add, "add")			\
+EMIT_FETCH_OP_N(N, uintN_t, ldr, str, fetch_and, "and")			\
+EMIT_FETCH_OP_N(N, uintN_t, ldr, str, fetch_or, "orr")			\
+EMIT_FETCH_OP_N(N, uintN_t, ldr, str, fetch_sub, "sub")			\
+EMIT_FETCH_OP_N(N, uintN_t, ldr, str, fetch_xor, "eor")
+
+EMIT_ALL_OPS_N(1, uint8_t, "ldrb", "strb", "strbeq")
+EMIT_ALL_OPS_N(2, uint16_t, "ldrh", "strh", "strheq")
+EMIT_ALL_OPS_N(4, uint32_t, "ldr", "str", "streq")
+#undef	EMIT_ALL_OPS_N
+
+#endif /* _KERNEL */
+
+#endif
+
+#endif /* __CLANG_ATOMICS || __GNUC_ATOMICS */
+
+#if defined(__SYNC_ATOMICS) || defined(EMIT_SYNC_ATOMICS)
+
+#ifdef __clang__
+#pragma redefine_extname __sync_lock_test_and_set_1_c __sync_lock_test_and_set_1
+#pragma redefine_extname __sync_lock_test_and_set_2_c __sync_lock_test_and_set_2
+#pragma	redefine_extname __sync_lock_test_and_set_4_c __sync_lock_test_and_set_4
+#pragma	redefine_extname __sync_val_compare_and_swap_1_c __sync_val_compare_and_swap_1
+#pragma	redefine_extname __sync_val_compare_and_swap_2_c __sync_val_compare_and_swap_2
+#pragma	redefine_extname __sync_val_compare_and_swap_4_c __sync_val_compare_and_swap_4
+#pragma	redefine_extname __sync_fetch_and_add_1_c __sync_fetch_and_add_1
+#pragma	redefine_extname __sync_fetch_and_add_2_c __sync_fetch_and_add_2
+#pragma	redefine_extname __sync_fetch_and_add_4_c __sync_fetch_and_add_4
+#pragma	redefine_extname __sync_fetch_and_and_1_c __sync_fetch_and_and_1
+#pragma	redefine_extname __sync_fetch_and_and_2_c __sync_fetch_and_and_2
+#pragma	redefine_extname __sync_fetch_and_and_4_c __sync_fetch_and_and_4
+#pragma	redefine_extname __sync_fetch_and_or_1_c __sync_fetch_and_or_1
+#pragma	redefine_extname __sync_fetch_and_or_2_c __sync_fetch_and_or_2
+#pragma	redefine_extname __sync_fetch_and_or_4_c __sync_fetch_and_or_4
+#pragma	redefine_extname __sync_fetch_and_xor_1_c __sync_fetch_and_xor_1
+#pragma	redefine_extname __sync_fetch_and_xor_2_c __sync_fetch_and_xor_2
+#pragma	redefine_extname __sync_fetch_and_xor_4_c __sync_fetch_and_xor_4
+#pragma	redefine_extname __sync_fetch_and_sub_1_c __sync_fetch_and_sub_1
+#pragma	redefine_extname __sync_fetch_and_sub_2_c __sync_fetch_and_sub_2
+#pragma	redefine_extname __sync_fetch_and_sub_4_c __sync_fetch_and_sub_4
+#endif
+
+/*
+ * Old __sync_* API.
+ */
+
+#if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || \
+    defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || \
+    defined(__ARM_ARCH_6ZK__) || \
+    defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__)
+
+/* Implementations for old GCC versions, lacking support for atomics. */
+
+typedef union {
+	uint8_t		v8[4];
+	uint32_t	v32;
+} reg_t;
+
+/*
+ * Given a memory address pointing to an 8-bit or 16-bit integer, return
+ * the address of the 32-bit word containing it.
+ */
+
+static inline uint32_t *
+round_to_word(void *ptr)
+{
+
+	return ((uint32_t *)((intptr_t)ptr & ~3));
+}
+
+/*
+ * Utility functions for loading and storing 8-bit and 16-bit integers
+ * in 32-bit words at an offset corresponding with the location of the
+ * atomic variable.
+ */
+
+static inline void
+put_1(reg_t *r, const uint8_t *offset_ptr, uint8_t val)
+{
+	size_t offset;
+
+	offset = (intptr_t)offset_ptr & 3;
+	r->v8[offset] = val;
+}
+
+static inline uint8_t
+get_1(const reg_t *r, const uint8_t *offset_ptr)
+{
+	size_t offset;
+
+	offset = (intptr_t)offset_ptr & 3;
+	return (r->v8[offset]);
+}
+
+static inline void
+put_2(reg_t *r, const uint16_t *offset_ptr, uint16_t val)
+{
+	size_t offset;
+	union {
+		uint16_t in;
+		uint8_t out[2];
+	} bytes;
+
+	offset = (intptr_t)offset_ptr & 3;
+	bytes.in = val;
+	r->v8[offset] = bytes.out[0];
+	r->v8[offset + 1] = bytes.out[1];
+}
+
+static inline uint16_t
+get_2(const reg_t *r, const uint16_t *offset_ptr)
+{
+	size_t offset;
+	union {
+		uint8_t in[2];
+		uint16_t out;
+	} bytes;
+
+	offset = (intptr_t)offset_ptr & 3;
+	bytes.in[0] = r->v8[offset];
+	bytes.in[1] = r->v8[offset + 1];
+	return (bytes.out);
+}
+
+/*
+ * 8-bit and 16-bit routines.
+ *
+ * These operations are not natively supported by the CPU, so we use
+ * some shifting and bitmasking on top of the 32-bit instructions.
+ */
+
+#define	EMIT_LOCK_TEST_AND_SET_N(N, uintN_t)				\
+uintN_t									\
+__sync_lock_test_and_set_##N##_c(uintN_t *mem, uintN_t val)			\
+{									\
+	uint32_t *mem32;						\
+	reg_t val32, negmask, old;					\
+	uint32_t temp1, temp2;						\
+									\
+	mem32 = round_to_word(mem);					\
+	val32.v32 = 0x00000000;						\
+	put_##N(&val32, mem, val);					\
+	negmask.v32 = 0xffffffff;					\
+	put_##N(&negmask, mem, 0);					\
+									\
+	do_sync();							\
+	__asm volatile (						\
+		"1:"							\
+		"\tldrex %0, %6\n"	/* Load old value. */		\
+		"\tand   %2, %5, %0\n"	/* Remove the old value. */	\
+		"\torr   %2, %2, %4\n"	/* Put in the new value. */	\
+		"\tstrex %3, %2, %1\n"	/* Attempt to store. */		\
+		"\tcmp   %3, #0\n"	/* Did it succeed? */		\
+		"\tbne   1b\n"		/* Spin if failed. */		\
+		: "=&r" (old.v32), "=m" (*mem32), "=&r" (temp1),	\
+		  "=&r" (temp2)						\
+		: "r" (val32.v32), "r" (negmask.v32), "m" (*mem32));	\
+	return (get_##N(&old, mem));					\
+}
+
+EMIT_LOCK_TEST_AND_SET_N(1, uint8_t)
+EMIT_LOCK_TEST_AND_SET_N(2, uint16_t)
+
+#define	EMIT_VAL_COMPARE_AND_SWAP_N(N, uintN_t)				\
+uintN_t									\
+__sync_val_compare_and_swap_##N##_c(uintN_t *mem, uintN_t expected,		\
+    uintN_t desired)							\
+{									\
+	uint32_t *mem32;						\
+	reg_t expected32, desired32, posmask, old;			\
+	uint32_t negmask, temp1, temp2;					\
+									\
+	mem32 = round_to_word(mem);					\
+	expected32.v32 = 0x00000000;					\
+	put_##N(&expected32, mem, expected);				\
+	desired32.v32 = 0x00000000;					\
+	put_##N(&desired32, mem, desired);				\
+	posmask.v32 = 0x00000000;					\
+	put_##N(&posmask, mem, ~0);					\
+	negmask = ~posmask.v32;						\
+									\
+	do_sync();							\
+	__asm volatile (						\
+		"1:"							\
+		"\tldrex %0, %8\n"	/* Load old value. */		\
+		"\tand   %2, %6, %0\n"	/* Isolate the old value. */	\
+		"\tcmp   %2, %4\n"	/* Compare to expected value. */\
+		"\tbne   2f\n"		/* Values are unequal. */	\
+		"\tand   %2, %7, %0\n"	/* Remove the old value. */	\
+		"\torr   %2, %5\n"	/* Put in the new value. */	\
+		"\tstrex %3, %2, %1\n"	/* Attempt to store. */		\
+		"\tcmp   %3, #0\n"	/* Did it succeed? */		\
+		"\tbne   1b\n"		/* Spin if failed. */		\
+		"2:"							\
+		: "=&r" (old), "=m" (*mem32), "=&r" (temp1),		\
+		  "=&r" (temp2)						\
+		: "r" (expected32.v32), "r" (desired32.v32),		\
+		  "r" (posmask.v32), "r" (negmask), "m" (*mem32));	\
+	return (get_##N(&old, mem));					\
+}
+
+EMIT_VAL_COMPARE_AND_SWAP_N(1, uint8_t)
+EMIT_VAL_COMPARE_AND_SWAP_N(2, uint16_t)
+
+#define	EMIT_ARITHMETIC_FETCH_AND_OP_N(N, uintN_t, name, op)		\
+uintN_t									\
+__sync_##name##_##N##_c(uintN_t *mem, uintN_t val)				\
+{									\
+	uint32_t *mem32;						\
+	reg_t val32, posmask, old;					\
+	uint32_t negmask, temp1, temp2;					\
+									\
+	mem32 = round_to_word(mem);					\
+	val32.v32 = 0x00000000;						\
+	put_##N(&val32, mem, val);					\
+	posmask.v32 = 0x00000000;					\
+	put_##N(&posmask, mem, ~0);					\
+	negmask = ~posmask.v32;						\
+									\
+	do_sync();							\
+	__asm volatile (						\
+		"1:"							\
+		"\tldrex %0, %7\n"	/* Load old value. */		\
+		"\t"op"  %2, %0, %4\n"	/* Calculate new value. */	\
+		"\tand   %2, %5\n"	/* Isolate the new value. */	\
+		"\tand   %3, %6, %0\n"	/* Remove the old value. */	\
+		"\torr   %2, %2, %3\n"	/* Put in the new value. */	\
+		"\tstrex %3, %2, %1\n"	/* Attempt to store. */		\
+		"\tcmp   %3, #0\n"	/* Did it succeed? */		\
+		"\tbne   1b\n"		/* Spin if failed. */		\
+		: "=&r" (old.v32), "=m" (*mem32), "=&r" (temp1),	\
+		  "=&r" (temp2)						\
+		: "r" (val32.v32), "r" (posmask.v32), "r" (negmask),	\
+		  "m" (*mem32));					\
+	return (get_##N(&old, mem));					\
+}
+
+EMIT_ARITHMETIC_FETCH_AND_OP_N(1, uint8_t, fetch_and_add, "add")
+EMIT_ARITHMETIC_FETCH_AND_OP_N(1, uint8_t, fetch_and_sub, "sub")
+EMIT_ARITHMETIC_FETCH_AND_OP_N(2, uint16_t, fetch_and_add, "add")
+EMIT_ARITHMETIC_FETCH_AND_OP_N(2, uint16_t, fetch_and_sub, "sub")
+
+#define	EMIT_BITWISE_FETCH_AND_OP_N(N, uintN_t, name, op, idempotence)	\
+uintN_t									\
+__sync_##name##_##N##_c(uintN_t *mem, uintN_t val)				\
+{									\
+	uint32_t *mem32;						\
+	reg_t val32, old;						\
+	uint32_t temp1, temp2;						\
+									\
+	mem32 = round_to_word(mem);					\
+	val32.v32 = idempotence ? 0xffffffff : 0x00000000;		\
+	put_##N(&val32, mem, val);					\
+									\
+	do_sync();							\
+	__asm volatile (						\
+		"1:"							\
+		"\tldrex %0, %5\n"	/* Load old value. */		\
+		"\t"op"  %2, %4, %0\n"	/* Calculate new value. */	\
+		"\tstrex %3, %2, %1\n"	/* Attempt to store. */		\
+		"\tcmp   %3, #0\n"	/* Did it succeed? */		\
+		"\tbne   1b\n"		/* Spin if failed. */		\
+		: "=&r" (old.v32), "=m" (*mem32), "=&r" (temp1),	\
+		  "=&r" (temp2)						\
+		: "r" (val32.v32), "m" (*mem32));			\
+	return (get_##N(&old, mem));					\
+}
+
+EMIT_BITWISE_FETCH_AND_OP_N(1, uint8_t, fetch_and_and, "and", 1)
+EMIT_BITWISE_FETCH_AND_OP_N(1, uint8_t, fetch_and_or, "orr", 0)
+EMIT_BITWISE_FETCH_AND_OP_N(1, uint8_t, fetch_and_xor, "eor", 0)
+EMIT_BITWISE_FETCH_AND_OP_N(2, uint16_t, fetch_and_and, "and", 1)
+EMIT_BITWISE_FETCH_AND_OP_N(2, uint16_t, fetch_and_or, "orr", 0)
+EMIT_BITWISE_FETCH_AND_OP_N(2, uint16_t, fetch_and_xor, "eor", 0)
+
+/*
+ * 32-bit routines.
+ */
+
+uint32_t
+__sync_lock_test_and_set_4_c(uint32_t *mem, uint32_t val)
+{
+	uint32_t old, temp;
+
+	do_sync();
+	__asm volatile (
+		"1:"
+		"\tldrex %0, %4\n"	/* Load old value. */
+		"\tstrex %2, %3, %1\n"	/* Attempt to store. */
+		"\tcmp   %2, #0\n"	/* Did it succeed? */
+		"\tbne   1b\n"		/* Spin if failed. */
+		: "=&r" (old), "=m" (*mem), "=&r" (temp)
+		: "r" (val), "m" (*mem));
+	return (old);
+}
+
+uint32_t
+__sync_val_compare_and_swap_4_c(uint32_t *mem, uint32_t expected,
+    uint32_t desired)
+{
+	uint32_t old, temp;
+
+	do_sync();
+	__asm volatile (
+		"1:"
+		"\tldrex %0, %5\n"	/* Load old value. */
+		"\tcmp   %0, %3\n"	/* Compare to expected value. */
+		"\tbne   2f\n"		/* Values are unequal. */
+		"\tstrex %2, %4, %1\n"	/* Attempt to store. */
+		"\tcmp   %2, #0\n"	/* Did it succeed? */
+		"\tbne   1b\n"		/* Spin if failed. */
+		"2:"
+		: "=&r" (old), "=m" (*mem), "=&r" (temp)
+		: "r" (expected), "r" (desired), "m" (*mem));
+	return (old);
+}
+
+#define	EMIT_FETCH_AND_OP_4(name, op)					\
+uint32_t								\
+__sync_##name##_4##_c(uint32_t *mem, uint32_t val)				\
+{									\
+	uint32_t old, temp1, temp2;					\
+									\
+	do_sync();							\
+	__asm volatile (						\
+		"1:"							\
+		"\tldrex %0, %5\n"	/* Load old value. */		\
+		"\t"op"  %2, %0, %4\n"	/* Calculate new value. */	\
+		"\tstrex %3, %2, %1\n"	/* Attempt to store. */		\
+		"\tcmp   %3, #0\n"	/* Did it succeed? */		\
+		"\tbne   1b\n"		/* Spin if failed. */		\
+		: "=&r" (old), "=m" (*mem), "=&r" (temp1),		\
+		  "=&r" (temp2)						\
+		: "r" (val), "m" (*mem));				\
+	return (old);							\
+}
+
+EMIT_FETCH_AND_OP_4(fetch_and_add, "add")
+EMIT_FETCH_AND_OP_4(fetch_and_and, "and")
+EMIT_FETCH_AND_OP_4(fetch_and_or, "orr")
+EMIT_FETCH_AND_OP_4(fetch_and_sub, "sub")
+EMIT_FETCH_AND_OP_4(fetch_and_xor, "eor")
+
+#ifndef __clang__
+__strong_reference(__sync_lock_test_and_set_1_c, __sync_lock_test_and_set_1);
+__strong_reference(__sync_lock_test_and_set_2_c, __sync_lock_test_and_set_2);
+__strong_reference(__sync_lock_test_and_set_4_c, __sync_lock_test_and_set_4);
+__strong_reference(__sync_val_compare_and_swap_1_c, __sync_val_compare_and_swap_1);
+__strong_reference(__sync_val_compare_and_swap_2_c, __sync_val_compare_and_swap_2);
+__strong_reference(__sync_val_compare_and_swap_4_c, __sync_val_compare_and_swap_4);
+__strong_reference(__sync_fetch_and_add_1_c, __sync_fetch_and_add_1);
+__strong_reference(__sync_fetch_and_add_2_c, __sync_fetch_and_add_2);
+__strong_reference(__sync_fetch_and_add_4_c, __sync_fetch_and_add_4);
+__strong_reference(__sync_fetch_and_and_1_c, __sync_fetch_and_and_1);
+__strong_reference(__sync_fetch_and_and_2_c, __sync_fetch_and_and_2);
+__strong_reference(__sync_fetch_and_and_4_c, __sync_fetch_and_and_4);
+__strong_reference(__sync_fetch_and_sub_1_c, __sync_fetch_and_sub_1);
+__strong_reference(__sync_fetch_and_sub_2_c, __sync_fetch_and_sub_2);
+__strong_reference(__sync_fetch_and_sub_4_c, __sync_fetch_and_sub_4);
+__strong_reference(__sync_fetch_and_or_1_c, __sync_fetch_and_or_1);
+__strong_reference(__sync_fetch_and_or_2_c, __sync_fetch_and_or_2);
+__strong_reference(__sync_fetch_and_or_4_c, __sync_fetch_and_or_4);
+__strong_reference(__sync_fetch_and_xor_1_c, __sync_fetch_and_xor_1);
+__strong_reference(__sync_fetch_and_xor_2_c, __sync_fetch_and_xor_2);
+__strong_reference(__sync_fetch_and_xor_4_c, __sync_fetch_and_xor_4);
+#endif
+
+#else /* __ARM_ARCH_5__ */
+
+#ifdef _KERNEL
+
+#ifdef SMP
+#error "On SMP systems we should have proper atomic operations."
+#endif
+
+/*
+ * On uniprocessor systems, we can perform the atomic operations by
+ * disabling interrupts.
+ */
+
+#define	EMIT_VAL_COMPARE_AND_SWAP_N(N, uintN_t)				\
+uintN_t									\
+__sync_val_compare_and_swap_##N(uintN_t *mem, uintN_t expected,		\
+    uintN_t desired)							\
+{									\
+	uintN_t ret;							\
+									\
+	WITHOUT_INTERRUPTS({						\
+		ret = *mem;						\
+		if (*mem == expected)					\
+			*mem = desired;					\
+	});								\
+	return (ret);							\
+}
+
+#define	EMIT_FETCH_AND_OP_N(N, uintN_t, name, op)			\
+uintN_t									\
+__sync_##name##_##N(uintN_t *mem, uintN_t val)				\
+{									\
+	uintN_t ret;							\
+									\
+	WITHOUT_INTERRUPTS({						\
+		ret = *mem;						\
+		*mem op val;						\
+	});								\
+	return (ret);							\
+}
+
+#define	EMIT_ALL_OPS_N(N, uintN_t)					\
+EMIT_VAL_COMPARE_AND_SWAP_N(N, uintN_t)					\
+EMIT_FETCH_AND_OP_N(N, uintN_t, lock_test_and_set, =)			\
+EMIT_FETCH_AND_OP_N(N, uintN_t, fetch_and_add, +=)			\
+EMIT_FETCH_AND_OP_N(N, uintN_t, fetch_and_and, &=)			\
+EMIT_FETCH_AND_OP_N(N, uintN_t, fetch_and_or, |=)			\
+EMIT_FETCH_AND_OP_N(N, uintN_t, fetch_and_sub, -=)			\
+EMIT_FETCH_AND_OP_N(N, uintN_t, fetch_and_xor, ^=)
+
+EMIT_ALL_OPS_N(1, uint8_t)
+EMIT_ALL_OPS_N(2, uint16_t)
+EMIT_ALL_OPS_N(4, uint32_t)
+EMIT_ALL_OPS_N(8, uint64_t)
+#undef	EMIT_ALL_OPS_N
+
+#else /* !_KERNEL */
+
+/*
+ * For userspace on uniprocessor systems, we can implement the atomic
+ * operations by using a Restartable Atomic Sequence. This makes the
+ * kernel restart the code from the beginning when interrupted.
+ */
+
+#define	EMIT_LOCK_TEST_AND_SET_N(N, uintN_t, ldr, str)			\
+uintN_t									\
+__sync_lock_test_and_set_##N##_c(uintN_t *mem, uintN_t val)			\
+{									\
+	uint32_t old, temp, ras_start;					\
+									\
+	ras_start = ARM_RAS_START;					\
+	__asm volatile (						\
+		/* Set up Restartable Atomic Sequence. */		\
+		"1:"							\
+		"\tadr   %2, 1b\n"					\
+		"\tstr   %2, [%5]\n"					\
+		"\tadr   %2, 2f\n"					\
+		"\tstr   %2, [%5, #4]\n"				\
+									\
+		"\t"ldr" %0, %4\n"	/* Load old value. */		\
+		"\t"str" %3, %1\n"	/* Store new value. */		\
+									\
+		/* Tear down Restartable Atomic Sequence. */		\
+		"2:"							\
+		"\tmov   %2, #0x00000000\n"				\
+		"\tstr   %2, [%5]\n"					\
+		"\tmov   %2, #0xffffffff\n"				\
+		"\tstr   %2, [%5, #4]\n"				\
+		: "=&r" (old), "=m" (*mem), "=&r" (temp)		\
+		: "r" (val), "m" (*mem), "r" (ras_start));		\
+	return (old);							\
+}
+
+#define	EMIT_VAL_COMPARE_AND_SWAP_N(N, uintN_t, ldr, streq)		\
+uintN_t									\
+__sync_val_compare_and_swap_##N##_c(uintN_t *mem, uintN_t expected,		\
+    uintN_t desired)							\
+{									\
+	uint32_t old, temp, ras_start;					\
+									\
+	ras_start = ARM_RAS_START;					\
+	__asm volatile (						\
+		/* Set up Restartable Atomic Sequence. */		\
+		"1:"							\
+		"\tadr   %2, 1b\n"					\
+		"\tstr   %2, [%6]\n"					\
+		"\tadr   %2, 2f\n"					\
+		"\tstr   %2, [%6, #4]\n"				\
+									\
+		"\t"ldr" %0, %5\n"	/* Load old value. */		\
+		"\tcmp   %0, %3\n"	/* Compare to expected value. */\
+		"\t"streq" %4, %1\n"	/* Store new value. */		\
+									\
+		/* Tear down Restartable Atomic Sequence. */		\
+		"2:"							\
+		"\tmov   %2, #0x00000000\n"				\
+		"\tstr   %2, [%6]\n"					\
+		"\tmov   %2, #0xffffffff\n"				\
+		"\tstr   %2, [%6, #4]\n"				\
+		: "=&r" (old), "=m" (*mem), "=&r" (temp)		\
+		: "r" (expected), "r" (desired), "m" (*mem),		\
+		  "r" (ras_start));					\
+	return (old);							\
+}
+
+#define	EMIT_FETCH_AND_OP_N(N, uintN_t, ldr, str, name, op)		\
+uintN_t									\
+__sync_##name##_##N##_c(uintN_t *mem, uintN_t val)				\
+{									\
+	uint32_t old, temp, ras_start;					\
+									\
+	ras_start = ARM_RAS_START;					\
+	__asm volatile (						\
+		/* Set up Restartable Atomic Sequence. */		\
+		"1:"							\
+		"\tadr   %2, 1b\n"					\
+		"\tstr   %2, [%5]\n"					\
+		"\tadr   %2, 2f\n"					\
+		"\tstr   %2, [%5, #4]\n"				\
+									\
+		"\t"ldr" %0, %4\n"	/* Load old value. */		\
+		"\t"op"  %2, %0, %3\n"	/* Calculate new value. */	\
+		"\t"str" %2, %1\n"	/* Store new value. */		\
+									\
+		/* Tear down Restartable Atomic Sequence. */		\
+		"2:"							\
+		"\tmov   %2, #0x00000000\n"				\
+		"\tstr   %2, [%5]\n"					\
+		"\tmov   %2, #0xffffffff\n"				\
+		"\tstr   %2, [%5, #4]\n"				\
+		: "=&r" (old), "=m" (*mem), "=&r" (temp)		\
+		: "r" (val), "m" (*mem), "r" (ras_start));		\
+	return (old);							\
+}
+
+#define	EMIT_ALL_OPS_N(N, uintN_t, ldr, str, streq)			\
+EMIT_LOCK_TEST_AND_SET_N(N, uintN_t, ldr, str)				\
+EMIT_VAL_COMPARE_AND_SWAP_N(N, uintN_t, ldr, streq)			\
+EMIT_FETCH_AND_OP_N(N, uintN_t, ldr, str, fetch_and_add, "add")		\
+EMIT_FETCH_AND_OP_N(N, uintN_t, ldr, str, fetch_and_and, "and")		\
+EMIT_FETCH_AND_OP_N(N, uintN_t, ldr, str, fetch_and_or, "orr")		\
+EMIT_FETCH_AND_OP_N(N, uintN_t, ldr, str, fetch_and_sub, "sub")		\
+EMIT_FETCH_AND_OP_N(N, uintN_t, ldr, str, fetch_and_xor, "eor")
+
+#ifdef __clang__
+EMIT_ALL_OPS_N(1, uint8_t, "ldrb", "strb", "strbeq")
+EMIT_ALL_OPS_N(2, uint16_t, "ldrh", "strh", "strheq")
+#else
+EMIT_ALL_OPS_N(1, uint8_t, "ldrb", "strb", "streqb")
+EMIT_ALL_OPS_N(2, uint16_t, "ldrh", "strh", "streqh")
+#endif
+EMIT_ALL_OPS_N(4, uint32_t, "ldr", "str", "streq")
+
+#ifndef __clang__
+__strong_reference(__sync_lock_test_and_set_1_c, __sync_lock_test_and_set_1);
+__strong_reference(__sync_lock_test_and_set_2_c, __sync_lock_test_and_set_2);
+__strong_reference(__sync_lock_test_and_set_4_c, __sync_lock_test_and_set_4);
+__strong_reference(__sync_val_compare_and_swap_1_c, __sync_val_compare_and_swap_1);
+__strong_reference(__sync_val_compare_and_swap_2_c, __sync_val_compare_and_swap_2);
+__strong_reference(__sync_val_compare_and_swap_4_c, __sync_val_compare_and_swap_4);
+__strong_reference(__sync_fetch_and_add_1_c, __sync_fetch_and_add_1);
+__strong_reference(__sync_fetch_and_add_2_c, __sync_fetch_and_add_2);
+__strong_reference(__sync_fetch_and_add_4_c, __sync_fetch_and_add_4);
+__strong_reference(__sync_fetch_and_and_1_c, __sync_fetch_and_and_1);
+__strong_reference(__sync_fetch_and_and_2_c, __sync_fetch_and_and_2);
+__strong_reference(__sync_fetch_and_and_4_c, __sync_fetch_and_and_4);
+__strong_reference(__sync_fetch_and_sub_1_c, __sync_fetch_and_sub_1);
+__strong_reference(__sync_fetch_and_sub_2_c, __sync_fetch_and_sub_2);
+__strong_reference(__sync_fetch_and_sub_4_c, __sync_fetch_and_sub_4);
+__strong_reference(__sync_fetch_and_or_1_c, __sync_fetch_and_or_1);
+__strong_reference(__sync_fetch_and_or_2_c, __sync_fetch_and_or_2);
+__strong_reference(__sync_fetch_and_or_4_c, __sync_fetch_and_or_4);
+__strong_reference(__sync_fetch_and_xor_1_c, __sync_fetch_and_xor_1);
+__strong_reference(__sync_fetch_and_xor_2_c, __sync_fetch_and_xor_2);
+__strong_reference(__sync_fetch_and_xor_4_c, __sync_fetch_and_xor_4);
+#endif
+
+#endif /* _KERNEL */
+
+#endif
+
+#endif /* __SYNC_ATOMICS */


Property changes on: trunk/sys/arm/arm/stdatomic.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/support.S
===================================================================
--- trunk/sys/arm/arm/support.S	                        (rev 0)
+++ trunk/sys/arm/arm/support.S	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,2966 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2004 Olivier Houchard
+ * 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.
+ */
+/*
+ * Copyright 2003 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Steve C. Woodford for Wasabi Systems, Inc.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed for the NetBSD Project by
+ *      Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
+ * 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.
+ */
+/*
+ * Copyright (c) 1997 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Neil A. Carson and Mark Brinicombe
+ *
+ * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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 <machine/asm.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/support.S 275767 2014-12-14 16:28:53Z andrew $");
+
+#include "assym.s"
+
+	.syntax	unified
+
+.L_arm_memcpy:
+	.word	_C_LABEL(_arm_memcpy)
+.L_arm_bzero:
+	.word	_C_LABEL(_arm_bzero)
+.L_min_memcpy_size:
+	.word	_C_LABEL(_min_memcpy_size)
+.L_min_bzero_size:
+	.word	_C_LABEL(_min_bzero_size)
+/*
+ * memset: Sets a block of memory to the specified value
+ *
+ * On entry:
+ *   r0 - dest address
+ *   r1 - byte to write
+ *   r2 - number of bytes to write
+ *
+ * On exit:
+ *   r0 - dest address
+ */
+/* LINTSTUB: Func: void bzero(void *, size_t) */
+ENTRY(bzero)
+	ldr	r3, .L_arm_bzero
+	ldr	r3, [r3]
+	cmp	r3, #0
+	beq	.Lnormal0
+	ldr	r2, .L_min_bzero_size
+	ldr	r2, [r2]
+	cmp	r1, r2
+	blt	.Lnormal0
+	stmfd	sp!, {r0, r1, lr}
+	mov	r2, #0
+	mov	lr, pc
+	mov	pc, r3
+	cmp	r0, #0
+	ldmfd	sp!, {r0, r1, lr}
+	RETeq
+.Lnormal0:
+	mov	r3, #0x00
+	b	do_memset
+END(bzero)
+/* LINTSTUB: Func: void *memset(void *, int, size_t) */
+ENTRY(memset)
+	and	r3, r1, #0xff		/* We deal with bytes */
+	mov	r1, r2
+do_memset:
+	cmp	r1, #0x04		/* Do we have less than 4 bytes */
+	mov	ip, r0
+	blt	.Lmemset_lessthanfour
+
+	/* Ok first we will word align the address */
+	ands	r2, ip, #0x03		/* Get the bottom two bits */
+	bne	.Lmemset_wordunaligned	/* The address is not word aligned */
+
+	/* We are now word aligned */
+.Lmemset_wordaligned:
+	orr	r3, r3, r3, lsl #8	/* Extend value to 16-bits */
+#ifdef _ARM_ARCH_5E
+	tst	ip, #0x04		/* Quad-align for armv5e */
+#else
+	cmp	r1, #0x10
+#endif
+	orr	r3, r3, r3, lsl #16	/* Extend value to 32-bits */
+#ifdef _ARM_ARCH_5E
+	subne	r1, r1, #0x04		/* Quad-align if necessary */
+	strne	r3, [ip], #0x04
+	cmp	r1, #0x10
+#endif
+	blt	.Lmemset_loop4		/* If less than 16 then use words */
+	mov	r2, r3			/* Duplicate data */
+	cmp	r1, #0x80		/* If < 128 then skip the big loop */
+	blt	.Lmemset_loop32
+
+	/* Do 128 bytes at a time */
+.Lmemset_loop128:
+	subs	r1, r1, #0x80
+#ifdef _ARM_ARCH_5E
+	strdge	r2, [ip], #0x08
+	strdge	r2, [ip], #0x08
+	strdge	r2, [ip], #0x08
+	strdge	r2, [ip], #0x08
+	strdge	r2, [ip], #0x08
+	strdge	r2, [ip], #0x08
+	strdge	r2, [ip], #0x08
+	strdge	r2, [ip], #0x08
+	strdge	r2, [ip], #0x08
+	strdge	r2, [ip], #0x08
+	strdge	r2, [ip], #0x08
+	strdge	r2, [ip], #0x08
+	strdge	r2, [ip], #0x08
+	strdge	r2, [ip], #0x08
+	strdge	r2, [ip], #0x08
+	strdge	r2, [ip], #0x08
+#else
+	stmiage	ip!, {r2-r3}
+	stmiage	ip!, {r2-r3}
+	stmiage	ip!, {r2-r3}
+	stmiage	ip!, {r2-r3}
+	stmiage	ip!, {r2-r3}
+	stmiage	ip!, {r2-r3}
+	stmiage	ip!, {r2-r3}
+	stmiage	ip!, {r2-r3}
+	stmiage	ip!, {r2-r3}
+	stmiage	ip!, {r2-r3}
+	stmiage	ip!, {r2-r3}
+	stmiage	ip!, {r2-r3}
+	stmiage	ip!, {r2-r3}
+	stmiage	ip!, {r2-r3}
+	stmiage	ip!, {r2-r3}
+	stmiage	ip!, {r2-r3}
+#endif
+	bgt	.Lmemset_loop128
+	RETeq			/* Zero length so just exit */
+
+	add	r1, r1, #0x80		/* Adjust for extra sub */
+
+	/* Do 32 bytes at a time */
+.Lmemset_loop32:
+	subs	r1, r1, #0x20
+#ifdef _ARM_ARCH_5E
+	strdge	r2, [ip], #0x08
+	strdge	r2, [ip], #0x08
+	strdge	r2, [ip], #0x08
+	strdge	r2, [ip], #0x08
+#else
+	stmiage	ip!, {r2-r3}
+	stmiage	ip!, {r2-r3}
+	stmiage	ip!, {r2-r3}
+	stmiage	ip!, {r2-r3}
+#endif
+	bgt	.Lmemset_loop32
+	RETeq			/* Zero length so just exit */
+
+	adds	r1, r1, #0x10		/* Partially adjust for extra sub */
+
+	/* Deal with 16 bytes or more */
+#ifdef _ARM_ARCH_5E
+	strdge	r2, [ip], #0x08
+	strdge	r2, [ip], #0x08
+#else
+	stmiage	ip!, {r2-r3}
+	stmiage	ip!, {r2-r3}
+#endif
+	RETeq			/* Zero length so just exit */
+
+	addlt	r1, r1, #0x10		/* Possibly adjust for extra sub */
+
+	/* We have at least 4 bytes so copy as words */
+.Lmemset_loop4:
+	subs	r1, r1, #0x04
+	strge	r3, [ip], #0x04
+	bgt	.Lmemset_loop4
+	RETeq			/* Zero length so just exit */
+
+#ifdef _ARM_ARCH_5E
+	/* Compensate for 64-bit alignment check */
+	adds	r1, r1, #0x04
+	RETeq
+	cmp	r1, #2
+#else
+	cmp	r1, #-2
+#endif
+
+	strb	r3, [ip], #0x01		/* Set 1 byte */
+	strbge	r3, [ip], #0x01		/* Set another byte */
+	strbgt	r3, [ip]		/* and a third */
+	RET			/* Exit */
+
+.Lmemset_wordunaligned:
+	rsb	r2, r2, #0x004
+	strb	r3, [ip], #0x01		/* Set 1 byte */
+	cmp	r2, #0x02
+	strbge	r3, [ip], #0x01		/* Set another byte */
+	sub	r1, r1, r2
+	strbgt	r3, [ip], #0x01		/* and a third */
+	cmp	r1, #0x04		/* More than 4 bytes left? */
+	bge	.Lmemset_wordaligned	/* Yup */
+
+.Lmemset_lessthanfour:
+	cmp	r1, #0x00
+	RETeq			/* Zero length so exit */
+	strb	r3, [ip], #0x01		/* Set 1 byte */
+	cmp	r1, #0x02
+	strbge	r3, [ip], #0x01		/* Set another byte */
+	strbgt	r3, [ip]		/* and a third */
+	RET			/* Exit */
+EEND(memset)
+END(bzero)
+
+ENTRY(bcmp)
+	mov	ip, r0
+	cmp	r2, #0x06
+	beq	.Lmemcmp_6bytes
+	mov	r0, #0x00
+
+	/* Are both addresses aligned the same way? */
+	cmp	r2, #0x00
+	eorsne	r3, ip, r1
+	RETeq			/* len == 0, or same addresses! */
+	tst	r3, #0x03
+	subne	r2, r2, #0x01
+	bne	.Lmemcmp_bytewise2	/* Badly aligned. Do it the slow way */
+
+	/* Word-align the addresses, if necessary */
+	sub	r3, r1, #0x05
+	ands	r3, r3, #0x03
+	add	r3, r3, r3, lsl #1
+	addne	pc, pc, r3, lsl #3
+	nop
+
+	/* Compare up to 3 bytes */
+	ldrb	r0, [ip], #0x01
+	ldrb	r3, [r1], #0x01
+	subs	r0, r0, r3
+	RETne
+	subs	r2, r2, #0x01
+	RETeq
+
+	/* Compare up to 2 bytes */
+	ldrb	r0, [ip], #0x01
+	ldrb	r3, [r1], #0x01
+	subs	r0, r0, r3
+	RETne
+	subs	r2, r2, #0x01
+	RETeq
+
+	/* Compare 1 byte */
+	ldrb	r0, [ip], #0x01
+	ldrb	r3, [r1], #0x01
+	subs	r0, r0, r3
+	RETne
+	subs	r2, r2, #0x01
+	RETeq
+
+	/* Compare 4 bytes at a time, if possible */
+	subs	r2, r2, #0x04
+	bcc	.Lmemcmp_bytewise
+.Lmemcmp_word_aligned:
+	ldr	r0, [ip], #0x04
+	ldr	r3, [r1], #0x04
+	subs	r2, r2, #0x04
+	cmpcs	r0, r3
+	beq	.Lmemcmp_word_aligned
+	sub	r0, r0, r3
+
+	/* Correct for extra subtraction, and check if done */
+	adds	r2, r2, #0x04
+	cmpeq	r0, #0x00		/* If done, did all bytes match? */
+	RETeq			/* Yup. Just return */
+
+	/* Re-do the final word byte-wise */
+	sub	ip, ip, #0x04
+	sub	r1, r1, #0x04
+
+.Lmemcmp_bytewise:
+	add	r2, r2, #0x03
+.Lmemcmp_bytewise2:
+	ldrb	r0, [ip], #0x01
+	ldrb	r3, [r1], #0x01
+	subs	r2, r2, #0x01
+	cmpcs	r0, r3
+	beq	.Lmemcmp_bytewise2
+	sub	r0, r0, r3
+	RET
+
+	/*
+	 * 6 byte compares are very common, thanks to the network stack.
+	 * This code is hand-scheduled to reduce the number of stalls for
+	 * load results. Everything else being equal, this will be ~32%
+	 * faster than a byte-wise memcmp.
+	 */
+	.align	5
+.Lmemcmp_6bytes:
+	ldrb	r3, [r1, #0x00]		/* r3 = b2#0 */
+	ldrb	r0, [ip, #0x00]		/* r0 = b1#0 */
+	ldrb	r2, [r1, #0x01]		/* r2 = b2#1 */
+	subs	r0, r0, r3		/* r0 = b1#0 - b2#0 */
+	ldrbeq	r3, [ip, #0x01]		/* r3 = b1#1 */
+	RETne			/* Return if mismatch on #0 */
+	subs	r0, r3, r2		/* r0 = b1#1 - b2#1 */
+	ldrbeq	r3, [r1, #0x02]		/* r3 = b2#2 */
+	ldrbeq	r0, [ip, #0x02]		/* r0 = b1#2 */
+	RETne			/* Return if mismatch on #1 */
+	ldrb	r2, [r1, #0x03]		/* r2 = b2#3 */
+	subs	r0, r0, r3		/* r0 = b1#2 - b2#2 */
+	ldrbeq	r3, [ip, #0x03]		/* r3 = b1#3 */
+	RETne			/* Return if mismatch on #2 */
+	subs	r0, r3, r2		/* r0 = b1#3 - b2#3 */
+	ldrbeq	r3, [r1, #0x04]		/* r3 = b2#4 */
+	ldrbeq	r0, [ip, #0x04]		/* r0 = b1#4 */
+	RETne			/* Return if mismatch on #3 */
+	ldrb	r2, [r1, #0x05]		/* r2 = b2#5 */
+	subs	r0, r0, r3		/* r0 = b1#4 - b2#4 */
+	ldrbeq	r3, [ip, #0x05]		/* r3 = b1#5 */
+	RETne			/* Return if mismatch on #4 */
+	sub	r0, r3, r2		/* r0 = b1#5 - b2#5 */
+	RET
+END(bcmp)
+
+ENTRY(bcopy)
+	/* switch the source and destination registers */
+	eor     r0, r1, r0
+	eor     r1, r0, r1
+	eor     r0, r1, r0
+EENTRY(memmove)
+	/* Do the buffers overlap? */
+	cmp	r0, r1
+	RETeq		/* Bail now if src/dst are the same */
+	subcc	r3, r0, r1	/* if (dst > src) r3 = dst - src */
+	subcs	r3, r1, r0	/* if (src > dsr) r3 = src - dst */
+	cmp	r3, r2		/* if (r3 < len) we have an overlap */
+	bcc	PIC_SYM(_C_LABEL(memcpy), PLT)
+
+	/* Determine copy direction */
+	cmp	r1, r0
+	bcc	.Lmemmove_backwards
+
+	moveq	r0, #0			/* Quick abort for len=0 */
+	RETeq
+
+	stmdb	sp!, {r0, lr}		/* memmove() returns dest addr */
+	subs	r2, r2, #4
+	blt	.Lmemmove_fl4		/* less than 4 bytes */
+	ands	r12, r0, #3
+	bne	.Lmemmove_fdestul	/* oh unaligned destination addr */
+	ands	r12, r1, #3
+	bne	.Lmemmove_fsrcul		/* oh unaligned source addr */
+
+.Lmemmove_ft8:
+	/* We have aligned source and destination */
+	subs	r2, r2, #8
+	blt	.Lmemmove_fl12		/* less than 12 bytes (4 from above) */
+	subs	r2, r2, #0x14
+	blt	.Lmemmove_fl32		/* less than 32 bytes (12 from above) */
+	stmdb	sp!, {r4}		/* borrow r4 */
+
+	/* blat 32 bytes at a time */
+	/* XXX for really big copies perhaps we should use more registers */
+.Lmemmove_floop32:	
+	ldmia	r1!, {r3, r4, r12, lr}
+	stmia	r0!, {r3, r4, r12, lr}
+	ldmia	r1!, {r3, r4, r12, lr}
+	stmia	r0!, {r3, r4, r12, lr}
+	subs	r2, r2, #0x20
+	bge	.Lmemmove_floop32
+
+	cmn	r2, #0x10
+	ldmiage	r1!, {r3, r4, r12, lr}	/* blat a remaining 16 bytes */
+	stmiage	r0!, {r3, r4, r12, lr}
+	subge	r2, r2, #0x10
+	ldmia	sp!, {r4}		/* return r4 */
+
+.Lmemmove_fl32:
+	adds	r2, r2, #0x14
+
+	/* blat 12 bytes at a time */
+.Lmemmove_floop12:
+	ldmiage	r1!, {r3, r12, lr}
+	stmiage	r0!, {r3, r12, lr}
+	subsge	r2, r2, #0x0c
+	bge	.Lmemmove_floop12
+
+.Lmemmove_fl12:
+	adds	r2, r2, #8
+	blt	.Lmemmove_fl4
+
+	subs	r2, r2, #4
+	ldrlt	r3, [r1], #4
+	strlt	r3, [r0], #4
+	ldmiage	r1!, {r3, r12}
+	stmiage	r0!, {r3, r12}
+	subge	r2, r2, #4
+
+.Lmemmove_fl4:
+	/* less than 4 bytes to go */
+	adds	r2, r2, #4
+	ldmiaeq	sp!, {r0, pc}		/* done */
+
+	/* copy the crud byte at a time */
+	cmp	r2, #2
+	ldrb	r3, [r1], #1
+	strb	r3, [r0], #1
+	ldrbge	r3, [r1], #1
+	strbge	r3, [r0], #1
+	ldrbgt	r3, [r1], #1
+	strbgt	r3, [r0], #1
+	ldmia	sp!, {r0, pc}
+
+	/* erg - unaligned destination */
+.Lmemmove_fdestul:
+	rsb	r12, r12, #4
+	cmp	r12, #2
+
+	/* align destination with byte copies */
+	ldrb	r3, [r1], #1
+	strb	r3, [r0], #1
+	ldrbge	r3, [r1], #1
+	strbge	r3, [r0], #1
+	ldrbgt	r3, [r1], #1
+	strbgt	r3, [r0], #1
+	subs	r2, r2, r12
+	blt	.Lmemmove_fl4		/* less the 4 bytes */
+
+	ands	r12, r1, #3
+	beq	.Lmemmove_ft8		/* we have an aligned source */
+
+	/* erg - unaligned source */
+	/* This is where it gets nasty ... */
+.Lmemmove_fsrcul:
+	bic	r1, r1, #3
+	ldr	lr, [r1], #4
+	cmp	r12, #2
+	bgt	.Lmemmove_fsrcul3
+	beq	.Lmemmove_fsrcul2
+	cmp	r2, #0x0c
+	blt	.Lmemmove_fsrcul1loop4
+	sub	r2, r2, #0x0c
+	stmdb	sp!, {r4, r5}
+
+.Lmemmove_fsrcul1loop16:
+#ifdef __ARMEB__
+	mov	r3, lr, lsl #8
+#else
+	mov	r3, lr, lsr #8
+#endif
+	ldmia	r1!, {r4, r5, r12, lr}
+#ifdef __ARMEB__
+	orr	r3, r3, r4, lsr #24
+	mov	r4, r4, lsl #8
+	orr	r4, r4, r5, lsr #24
+	mov	r5, r5, lsl #8
+	orr	r5, r5, r12, lsr #24
+	mov	r12, r12, lsl #8
+	orr	r12, r12, lr, lsr #24
+#else
+	orr	r3, r3, r4, lsl #24
+	mov	r4, r4, lsr #8
+	orr	r4, r4, r5, lsl #24
+	mov	r5, r5, lsr #8
+	orr	r5, r5, r12, lsl #24
+	mov	r12, r12, lsr #8
+	orr	r12, r12, lr, lsl #24
+#endif
+	stmia	r0!, {r3-r5, r12}
+	subs	r2, r2, #0x10
+	bge	.Lmemmove_fsrcul1loop16
+	ldmia	sp!, {r4, r5}
+	adds	r2, r2, #0x0c
+	blt	.Lmemmove_fsrcul1l4
+
+.Lmemmove_fsrcul1loop4:
+#ifdef __ARMEB__
+	mov	r12, lr, lsl #8
+#else
+	mov	r12, lr, lsr #8
+#endif
+	ldr	lr, [r1], #4
+#ifdef __ARMEB__
+	orr	r12, r12, lr, lsr #24
+#else
+	orr	r12, r12, lr, lsl #24
+#endif
+	str	r12, [r0], #4
+	subs	r2, r2, #4
+	bge	.Lmemmove_fsrcul1loop4
+
+.Lmemmove_fsrcul1l4:
+	sub	r1, r1, #3
+	b	.Lmemmove_fl4
+
+.Lmemmove_fsrcul2:
+	cmp	r2, #0x0c
+	blt	.Lmemmove_fsrcul2loop4
+	sub	r2, r2, #0x0c
+	stmdb	sp!, {r4, r5}
+
+.Lmemmove_fsrcul2loop16:
+#ifdef __ARMEB__
+	mov	r3, lr, lsl #16
+#else
+	mov	r3, lr, lsr #16
+#endif
+	ldmia	r1!, {r4, r5, r12, lr}
+#ifdef __ARMEB__
+	orr	r3, r3, r4, lsr #16
+	mov	r4, r4, lsl #16
+	orr	r4, r4, r5, lsr #16
+	mov	r5, r5, lsl #16
+	orr	r5, r5, r12, lsr #16
+	mov	r12, r12, lsl #16
+	orr	r12, r12, lr, lsr #16
+#else
+	orr	r3, r3, r4, lsl #16
+	mov	r4, r4, lsr #16
+	orr	r4, r4, r5, lsl #16
+	mov	r5, r5, lsr #16
+	orr	r5, r5, r12, lsl #16
+	mov	r12, r12, lsr #16
+	orr	r12, r12, lr, lsl #16
+#endif
+	stmia	r0!, {r3-r5, r12}
+	subs	r2, r2, #0x10
+	bge	.Lmemmove_fsrcul2loop16
+	ldmia	sp!, {r4, r5}
+	adds	r2, r2, #0x0c
+	blt	.Lmemmove_fsrcul2l4
+
+.Lmemmove_fsrcul2loop4:
+#ifdef __ARMEB__
+	mov	r12, lr, lsl #16
+#else
+	mov	r12, lr, lsr #16
+#endif
+	ldr	lr, [r1], #4
+#ifdef __ARMEB__
+	orr	r12, r12, lr, lsr #16
+#else
+	orr	r12, r12, lr, lsl #16
+#endif
+	str	r12, [r0], #4
+	subs	r2, r2, #4
+	bge	.Lmemmove_fsrcul2loop4
+
+.Lmemmove_fsrcul2l4:
+	sub	r1, r1, #2
+	b	.Lmemmove_fl4
+
+.Lmemmove_fsrcul3:
+	cmp	r2, #0x0c
+	blt	.Lmemmove_fsrcul3loop4
+	sub	r2, r2, #0x0c
+	stmdb	sp!, {r4, r5}
+
+.Lmemmove_fsrcul3loop16:
+#ifdef __ARMEB__
+	mov	r3, lr, lsl #24
+#else
+	mov	r3, lr, lsr #24
+#endif
+	ldmia	r1!, {r4, r5, r12, lr}
+#ifdef __ARMEB__
+	orr	r3, r3, r4, lsr #8
+	mov	r4, r4, lsl #24
+	orr	r4, r4, r5, lsr #8
+	mov	r5, r5, lsl #24
+	orr	r5, r5, r12, lsr #8
+	mov	r12, r12, lsl #24
+	orr	r12, r12, lr, lsr #8
+#else
+	orr	r3, r3, r4, lsl #8
+	mov	r4, r4, lsr #24
+	orr	r4, r4, r5, lsl #8
+	mov	r5, r5, lsr #24
+	orr	r5, r5, r12, lsl #8
+	mov	r12, r12, lsr #24
+	orr	r12, r12, lr, lsl #8
+#endif
+	stmia	r0!, {r3-r5, r12}
+	subs	r2, r2, #0x10
+	bge	.Lmemmove_fsrcul3loop16
+	ldmia	sp!, {r4, r5}
+	adds	r2, r2, #0x0c
+	blt	.Lmemmove_fsrcul3l4
+
+.Lmemmove_fsrcul3loop4:
+#ifdef __ARMEB__
+	mov	r12, lr, lsl #24
+#else
+	mov	r12, lr, lsr #24
+#endif
+	ldr	lr, [r1], #4
+#ifdef __ARMEB__
+	orr	r12, r12, lr, lsr #8
+#else
+	orr	r12, r12, lr, lsl #8
+#endif
+	str	r12, [r0], #4
+	subs	r2, r2, #4
+	bge	.Lmemmove_fsrcul3loop4
+
+.Lmemmove_fsrcul3l4:
+	sub	r1, r1, #1
+	b	.Lmemmove_fl4
+
+.Lmemmove_backwards:
+	add	r1, r1, r2
+	add	r0, r0, r2
+	subs	r2, r2, #4
+	blt	.Lmemmove_bl4		/* less than 4 bytes */
+	ands	r12, r0, #3
+	bne	.Lmemmove_bdestul	/* oh unaligned destination addr */
+	ands	r12, r1, #3
+	bne	.Lmemmove_bsrcul		/* oh unaligned source addr */
+
+.Lmemmove_bt8:
+	/* We have aligned source and destination */
+	subs	r2, r2, #8
+	blt	.Lmemmove_bl12		/* less than 12 bytes (4 from above) */
+	stmdb	sp!, {r4, lr}
+	subs	r2, r2, #0x14		/* less than 32 bytes (12 from above) */
+	blt	.Lmemmove_bl32
+
+	/* blat 32 bytes at a time */
+	/* XXX for really big copies perhaps we should use more registers */
+.Lmemmove_bloop32:
+	ldmdb	r1!, {r3, r4, r12, lr}
+	stmdb	r0!, {r3, r4, r12, lr}
+	ldmdb	r1!, {r3, r4, r12, lr}
+	stmdb	r0!, {r3, r4, r12, lr}
+	subs	r2, r2, #0x20
+	bge	.Lmemmove_bloop32
+
+.Lmemmove_bl32:
+	cmn	r2, #0x10
+	ldmdbge	r1!, {r3, r4, r12, lr}	/* blat a remaining 16 bytes */
+	stmdbge	r0!, {r3, r4, r12, lr}
+	subge	r2, r2, #0x10
+	adds	r2, r2, #0x14
+	ldmdbge	r1!, {r3, r12, lr}	/* blat a remaining 12 bytes */
+	stmdbge	r0!, {r3, r12, lr}
+	subge	r2, r2, #0x0c
+	ldmia	sp!, {r4, lr}
+
+.Lmemmove_bl12:
+	adds	r2, r2, #8
+	blt	.Lmemmove_bl4
+	subs	r2, r2, #4
+	ldrlt	r3, [r1, #-4]!
+	strlt	r3, [r0, #-4]!
+	ldmdbge	r1!, {r3, r12}
+	stmdbge	r0!, {r3, r12}
+	subge	r2, r2, #4
+
+.Lmemmove_bl4:
+	/* less than 4 bytes to go */
+	adds	r2, r2, #4
+	RETeq			/* done */
+
+	/* copy the crud byte at a time */
+	cmp	r2, #2
+	ldrb	r3, [r1, #-1]!
+	strb	r3, [r0, #-1]!
+	ldrbge	r3, [r1, #-1]!
+	strbge	r3, [r0, #-1]!
+	ldrbgt	r3, [r1, #-1]!
+	strbgt	r3, [r0, #-1]!
+	RET
+
+	/* erg - unaligned destination */
+.Lmemmove_bdestul:
+	cmp	r12, #2
+
+	/* align destination with byte copies */
+	ldrb	r3, [r1, #-1]!
+	strb	r3, [r0, #-1]!
+	ldrbge	r3, [r1, #-1]!
+	strbge	r3, [r0, #-1]!
+	ldrbgt	r3, [r1, #-1]!
+	strbgt	r3, [r0, #-1]!
+	subs	r2, r2, r12
+	blt	.Lmemmove_bl4		/* less than 4 bytes to go */
+	ands	r12, r1, #3
+	beq	.Lmemmove_bt8		/* we have an aligned source */
+
+	/* erg - unaligned source */
+	/* This is where it gets nasty ... */
+.Lmemmove_bsrcul:
+	bic	r1, r1, #3
+	ldr	r3, [r1, #0]
+	cmp	r12, #2
+	blt	.Lmemmove_bsrcul1
+	beq	.Lmemmove_bsrcul2
+	cmp	r2, #0x0c
+	blt	.Lmemmove_bsrcul3loop4
+	sub	r2, r2, #0x0c
+	stmdb	sp!, {r4, r5, lr}
+
+.Lmemmove_bsrcul3loop16:
+#ifdef __ARMEB__
+	mov	lr, r3, lsr #8
+#else
+	mov	lr, r3, lsl #8
+#endif
+	ldmdb	r1!, {r3-r5, r12}
+#ifdef __ARMEB__
+	orr	lr, lr, r12, lsl #24
+	mov	r12, r12, lsr #8
+	orr	r12, r12, r5, lsl #24
+	mov	r5, r5, lsr #8
+	orr	r5, r5, r4, lsl #24
+	mov	r4, r4, lsr #8
+	orr	r4, r4, r3, lsl #24
+#else
+	orr	lr, lr, r12, lsr #24
+	mov	r12, r12, lsl #8
+	orr	r12, r12, r5, lsr #24
+	mov	r5, r5, lsl #8
+	orr	r5, r5, r4, lsr #24
+	mov	r4, r4, lsl #8
+	orr	r4, r4, r3, lsr #24
+#endif
+	stmdb	r0!, {r4, r5, r12, lr}
+	subs	r2, r2, #0x10
+	bge	.Lmemmove_bsrcul3loop16
+	ldmia	sp!, {r4, r5, lr}
+	adds	r2, r2, #0x0c
+	blt	.Lmemmove_bsrcul3l4
+
+.Lmemmove_bsrcul3loop4:
+#ifdef __ARMEB__
+	mov	r12, r3, lsr #8
+#else
+	mov	r12, r3, lsl #8
+#endif
+	ldr	r3, [r1, #-4]!
+#ifdef __ARMEB__
+	orr	r12, r12, r3, lsl #24
+#else
+	orr	r12, r12, r3, lsr #24
+#endif
+	str	r12, [r0, #-4]!
+	subs	r2, r2, #4
+	bge	.Lmemmove_bsrcul3loop4
+
+.Lmemmove_bsrcul3l4:
+	add	r1, r1, #3
+	b	.Lmemmove_bl4
+
+.Lmemmove_bsrcul2:
+	cmp	r2, #0x0c
+	blt	.Lmemmove_bsrcul2loop4
+	sub	r2, r2, #0x0c
+	stmdb	sp!, {r4, r5, lr}
+
+.Lmemmove_bsrcul2loop16:
+#ifdef __ARMEB__
+	mov	lr, r3, lsr #16
+#else
+	mov	lr, r3, lsl #16
+#endif
+	ldmdb	r1!, {r3-r5, r12}
+#ifdef __ARMEB__
+	orr	lr, lr, r12, lsl #16
+	mov	r12, r12, lsr #16
+	orr	r12, r12, r5, lsl #16
+	mov	r5, r5, lsr #16
+	orr	r5, r5, r4, lsl #16
+	mov	r4, r4, lsr #16
+	orr	r4, r4, r3, lsl #16
+#else
+	orr	lr, lr, r12, lsr #16
+	mov	r12, r12, lsl #16
+	orr	r12, r12, r5, lsr #16
+	mov	r5, r5, lsl #16
+	orr	r5, r5, r4, lsr #16
+	mov	r4, r4, lsl #16
+	orr	r4, r4, r3, lsr #16
+#endif
+	stmdb	r0!, {r4, r5, r12, lr}
+	subs	r2, r2, #0x10
+	bge	.Lmemmove_bsrcul2loop16
+	ldmia	sp!, {r4, r5, lr}
+	adds	r2, r2, #0x0c
+	blt	.Lmemmove_bsrcul2l4
+
+.Lmemmove_bsrcul2loop4:
+#ifdef __ARMEB__
+	mov	r12, r3, lsr #16
+#else
+	mov	r12, r3, lsl #16
+#endif
+	ldr	r3, [r1, #-4]!
+#ifdef __ARMEB__
+	orr	r12, r12, r3, lsl #16
+#else
+	orr	r12, r12, r3, lsr #16
+#endif
+	str	r12, [r0, #-4]!
+	subs	r2, r2, #4
+	bge	.Lmemmove_bsrcul2loop4
+
+.Lmemmove_bsrcul2l4:
+	add	r1, r1, #2
+	b	.Lmemmove_bl4
+
+.Lmemmove_bsrcul1:
+	cmp	r2, #0x0c
+	blt	.Lmemmove_bsrcul1loop4
+	sub	r2, r2, #0x0c
+	stmdb	sp!, {r4, r5, lr}
+
+.Lmemmove_bsrcul1loop32:
+#ifdef __ARMEB__
+	mov	lr, r3, lsr #24
+#else
+	mov	lr, r3, lsl #24
+#endif
+	ldmdb	r1!, {r3-r5, r12}
+#ifdef __ARMEB__
+	orr	lr, lr, r12, lsl #8
+	mov	r12, r12, lsr #24
+	orr	r12, r12, r5, lsl #8
+	mov	r5, r5, lsr #24
+	orr	r5, r5, r4, lsl #8
+	mov	r4, r4, lsr #24
+	orr	r4, r4, r3, lsl #8
+#else
+	orr	lr, lr, r12, lsr #8
+	mov	r12, r12, lsl #24
+	orr	r12, r12, r5, lsr #8
+	mov	r5, r5, lsl #24
+	orr	r5, r5, r4, lsr #8
+	mov	r4, r4, lsl #24
+	orr	r4, r4, r3, lsr #8
+#endif
+	stmdb	r0!, {r4, r5, r12, lr}
+	subs	r2, r2, #0x10
+	bge	.Lmemmove_bsrcul1loop32
+	ldmia	sp!, {r4, r5, lr}
+	adds	r2, r2, #0x0c
+	blt	.Lmemmove_bsrcul1l4
+
+.Lmemmove_bsrcul1loop4:
+#ifdef __ARMEB__
+	mov	r12, r3, lsr #24
+#else
+	mov	r12, r3, lsl #24
+#endif
+	ldr	r3, [r1, #-4]!
+#ifdef __ARMEB__
+	orr	r12, r12, r3, lsl #8
+#else
+	orr	r12, r12, r3, lsr #8
+#endif
+	str	r12, [r0, #-4]!
+	subs	r2, r2, #4
+	bge	.Lmemmove_bsrcul1loop4
+
+.Lmemmove_bsrcul1l4:
+	add	r1, r1, #1
+	b	.Lmemmove_bl4
+EEND(memmove)
+END(bcopy)
+
+#if !defined(_ARM_ARCH_5E)
+ENTRY(memcpy)
+	/* save leaf functions having to store this away */
+	/* Do not check arm_memcpy if we're running from flash */
+#if defined(FLASHADDR) && defined(PHYSADDR)
+#if FLASHADDR > PHYSADDR
+	ldr	r3, =FLASHADDR
+	cmp	r3, pc
+	bls	.Lnormal
+#else
+	ldr	r3, =FLASHADDR
+	cmp	r3, pc
+	bhi	.Lnormal
+#endif
+#endif
+	ldr	r3, .L_arm_memcpy
+	ldr	r3, [r3]
+	cmp	r3, #0
+	beq	.Lnormal
+	ldr	r3, .L_min_memcpy_size
+	ldr	r3, [r3]
+	cmp	r2, r3
+	blt	.Lnormal
+	stmfd	sp!, {r0-r2, r4, lr}
+	mov	r3, #0
+	ldr	r4, .L_arm_memcpy
+	mov	lr, pc
+	ldr	pc, [r4]
+	cmp	r0, #0
+	ldmfd	sp!, {r0-r2, r4, lr}
+	RETeq
+
+.Lnormal:
+	stmdb	sp!, {r0, lr}		/* memcpy() returns dest addr */
+
+	subs	r2, r2, #4
+	blt	.Lmemcpy_l4		/* less than 4 bytes */
+	ands	r12, r0, #3
+	bne	.Lmemcpy_destul		/* oh unaligned destination addr */
+	ands	r12, r1, #3
+	bne	.Lmemcpy_srcul		/* oh unaligned source addr */
+
+.Lmemcpy_t8:
+	/* We have aligned source and destination */
+	subs	r2, r2, #8
+	blt	.Lmemcpy_l12		/* less than 12 bytes (4 from above) */
+	subs	r2, r2, #0x14
+	blt	.Lmemcpy_l32		/* less than 32 bytes (12 from above) */
+	stmdb	sp!, {r4}		/* borrow r4 */
+
+	/* blat 32 bytes at a time */
+	/* XXX for really big copies perhaps we should use more registers */
+.Lmemcpy_loop32:	
+	ldmia	r1!, {r3, r4, r12, lr}
+	stmia	r0!, {r3, r4, r12, lr}
+	ldmia	r1!, {r3, r4, r12, lr}
+	stmia	r0!, {r3, r4, r12, lr}
+	subs	r2, r2, #0x20
+	bge	.Lmemcpy_loop32
+
+	cmn	r2, #0x10
+	ldmiage	r1!, {r3, r4, r12, lr}	/* blat a remaining 16 bytes */
+	stmiage	r0!, {r3, r4, r12, lr}
+	subge	r2, r2, #0x10
+	ldmia	sp!, {r4}		/* return r4 */
+
+.Lmemcpy_l32:
+	adds	r2, r2, #0x14
+
+	/* blat 12 bytes at a time */
+.Lmemcpy_loop12:
+	ldmiage	r1!, {r3, r12, lr}
+	stmiage	r0!, {r3, r12, lr}
+	subsge	r2, r2, #0x0c
+	bge	.Lmemcpy_loop12
+
+.Lmemcpy_l12:
+	adds	r2, r2, #8
+	blt	.Lmemcpy_l4
+
+	subs	r2, r2, #4
+	ldrlt	r3, [r1], #4
+	strlt	r3, [r0], #4
+	ldmiage	r1!, {r3, r12}
+	stmiage	r0!, {r3, r12}
+	subge	r2, r2, #4
+
+.Lmemcpy_l4:
+	/* less than 4 bytes to go */
+	adds	r2, r2, #4
+#ifdef __APCS_26_
+	ldmiaeq sp!, {r0, pc}^		/* done */
+#else
+	ldmiaeq	sp!, {r0, pc}		/* done */
+#endif
+	/* copy the crud byte at a time */
+	cmp	r2, #2
+	ldrb	r3, [r1], #1
+	strb	r3, [r0], #1
+	ldrbge	r3, [r1], #1
+	strbge	r3, [r0], #1
+	ldrbgt	r3, [r1], #1
+	strbgt	r3, [r0], #1
+	ldmia	sp!, {r0, pc}
+
+	/* erg - unaligned destination */
+.Lmemcpy_destul:
+	rsb	r12, r12, #4
+	cmp	r12, #2
+
+	/* align destination with byte copies */
+	ldrb	r3, [r1], #1
+	strb	r3, [r0], #1
+	ldrbge	r3, [r1], #1
+	strbge	r3, [r0], #1
+	ldrbgt	r3, [r1], #1
+	strbgt	r3, [r0], #1
+	subs	r2, r2, r12
+	blt	.Lmemcpy_l4		/* less the 4 bytes */
+
+	ands	r12, r1, #3
+	beq	.Lmemcpy_t8		/* we have an aligned source */
+
+	/* erg - unaligned source */
+	/* This is where it gets nasty ... */
+.Lmemcpy_srcul:
+	bic	r1, r1, #3
+	ldr	lr, [r1], #4
+	cmp	r12, #2
+	bgt	.Lmemcpy_srcul3
+	beq	.Lmemcpy_srcul2
+	cmp	r2, #0x0c
+	blt	.Lmemcpy_srcul1loop4
+	sub	r2, r2, #0x0c
+	stmdb	sp!, {r4, r5}
+
+.Lmemcpy_srcul1loop16:
+	mov	r3, lr, lsr #8
+	ldmia	r1!, {r4, r5, r12, lr}
+	orr	r3, r3, r4, lsl #24
+	mov	r4, r4, lsr #8
+	orr	r4, r4, r5, lsl #24
+	mov	r5, r5, lsr #8
+	orr	r5, r5, r12, lsl #24
+	mov	r12, r12, lsr #8
+	orr	r12, r12, lr, lsl #24
+	stmia	r0!, {r3-r5, r12}
+	subs	r2, r2, #0x10
+	bge	.Lmemcpy_srcul1loop16
+	ldmia	sp!, {r4, r5}
+	adds	r2, r2, #0x0c
+	blt	.Lmemcpy_srcul1l4
+
+.Lmemcpy_srcul1loop4:
+	mov	r12, lr, lsr #8
+	ldr	lr, [r1], #4
+	orr	r12, r12, lr, lsl #24
+	str	r12, [r0], #4
+	subs	r2, r2, #4
+	bge	.Lmemcpy_srcul1loop4
+
+.Lmemcpy_srcul1l4:
+	sub	r1, r1, #3
+	b	.Lmemcpy_l4
+
+.Lmemcpy_srcul2:
+	cmp	r2, #0x0c
+	blt	.Lmemcpy_srcul2loop4
+	sub	r2, r2, #0x0c
+	stmdb	sp!, {r4, r5}
+
+.Lmemcpy_srcul2loop16:
+	mov	r3, lr, lsr #16
+	ldmia	r1!, {r4, r5, r12, lr}
+	orr	r3, r3, r4, lsl #16
+	mov	r4, r4, lsr #16
+	orr	r4, r4, r5, lsl #16
+	mov	r5, r5, lsr #16
+	orr	r5, r5, r12, lsl #16
+	mov	r12, r12, lsr #16
+	orr	r12, r12, lr, lsl #16
+	stmia	r0!, {r3-r5, r12}
+	subs	r2, r2, #0x10
+	bge	.Lmemcpy_srcul2loop16
+	ldmia	sp!, {r4, r5}
+	adds	r2, r2, #0x0c
+	blt	.Lmemcpy_srcul2l4
+
+.Lmemcpy_srcul2loop4:
+	mov	r12, lr, lsr #16
+	ldr	lr, [r1], #4
+	orr	r12, r12, lr, lsl #16
+	str	r12, [r0], #4
+	subs	r2, r2, #4
+	bge	.Lmemcpy_srcul2loop4
+
+.Lmemcpy_srcul2l4:
+	sub	r1, r1, #2
+	b	.Lmemcpy_l4
+
+.Lmemcpy_srcul3:
+	cmp	r2, #0x0c
+	blt	.Lmemcpy_srcul3loop4
+	sub	r2, r2, #0x0c
+	stmdb	sp!, {r4, r5}
+
+.Lmemcpy_srcul3loop16:
+	mov	r3, lr, lsr #24
+	ldmia	r1!, {r4, r5, r12, lr}
+	orr	r3, r3, r4, lsl #8
+	mov	r4, r4, lsr #24
+	orr	r4, r4, r5, lsl #8
+	mov	r5, r5, lsr #24
+	orr	r5, r5, r12, lsl #8
+	mov	r12, r12, lsr #24
+	orr	r12, r12, lr, lsl #8
+	stmia	r0!, {r3-r5, r12}
+	subs	r2, r2, #0x10
+	bge	.Lmemcpy_srcul3loop16
+	ldmia	sp!, {r4, r5}
+	adds	r2, r2, #0x0c
+	blt	.Lmemcpy_srcul3l4
+
+.Lmemcpy_srcul3loop4:
+	mov	r12, lr, lsr #24
+	ldr	lr, [r1], #4
+	orr	r12, r12, lr, lsl #8
+	str	r12, [r0], #4
+	subs	r2, r2, #4
+	bge	.Lmemcpy_srcul3loop4
+
+.Lmemcpy_srcul3l4:
+	sub	r1, r1, #1
+	b	.Lmemcpy_l4
+END(memcpy)
+
+#else
+/* LINTSTUB: Func: void *memcpy(void *dst, const void *src, size_t len) */
+ENTRY(memcpy)
+	pld	[r1]
+	cmp	r2, #0x0c
+	ble	.Lmemcpy_short		/* <= 12 bytes */
+#ifdef FLASHADDR
+#if FLASHADDR > PHYSADDR
+	ldr	r3, =FLASHADDR
+	cmp	r3, pc
+	bls	.Lnormal
+#else
+	ldr	r3, =FLASHADDR
+	cmp	r3, pc
+	bhi	.Lnormal
+#endif
+#endif
+	ldr	r3, .L_arm_memcpy
+	ldr	r3, [r3]
+	cmp	r3, #0
+	beq	.Lnormal
+	ldr	r3, .L_min_memcpy_size
+	ldr	r3, [r3]
+	cmp	r2, r3
+	blt	.Lnormal
+	stmfd	sp!, {r0-r2, r4, lr}
+	mov	r3, #0
+	ldr	r4, .L_arm_memcpy
+	mov	lr, pc
+	ldr	pc, [r4]
+	cmp	r0, #0
+	ldmfd	sp!, {r0-r2, r4, lr}
+	RETeq
+.Lnormal:
+	mov	r3, r0			/* We must not clobber r0 */
+
+	/* Word-align the destination buffer */
+	ands	ip, r3, #0x03		/* Already word aligned? */
+	beq	.Lmemcpy_wordaligned	/* Yup */
+	cmp	ip, #0x02
+	ldrb	ip, [r1], #0x01
+	sub	r2, r2, #0x01
+	strb	ip, [r3], #0x01
+	ldrble	ip, [r1], #0x01
+	suble	r2, r2, #0x01
+	strble	ip, [r3], #0x01
+	ldrblt	ip, [r1], #0x01
+	sublt	r2, r2, #0x01
+	strblt	ip, [r3], #0x01
+
+	/* Destination buffer is now word aligned */
+.Lmemcpy_wordaligned:
+	ands	ip, r1, #0x03		/* Is src also word-aligned? */
+	bne	.Lmemcpy_bad_align	/* Nope. Things just got bad */
+
+	/* Quad-align the destination buffer */
+	tst	r3, #0x07		/* Already quad aligned? */
+	ldrne	ip, [r1], #0x04
+	stmfd	sp!, {r4-r9}		/* Free up some registers */
+	subne	r2, r2, #0x04
+	strne	ip, [r3], #0x04
+
+	/* Destination buffer quad aligned, source is at least word aligned */
+	subs	r2, r2, #0x80
+	blt	.Lmemcpy_w_lessthan128
+
+	/* Copy 128 bytes at a time */
+.Lmemcpy_w_loop128:
+	ldr	r4, [r1], #0x04		/* LD:00-03 */
+	ldr	r5, [r1], #0x04		/* LD:04-07 */
+	pld	[r1, #0x18]		/* Prefetch 0x20 */
+	ldr	r6, [r1], #0x04		/* LD:08-0b */
+	ldr	r7, [r1], #0x04		/* LD:0c-0f */
+	ldr	r8, [r1], #0x04		/* LD:10-13 */
+	ldr	r9, [r1], #0x04		/* LD:14-17 */
+	strd	r4, [r3], #0x08		/* ST:00-07 */
+	ldr	r4, [r1], #0x04		/* LD:18-1b */
+	ldr	r5, [r1], #0x04		/* LD:1c-1f */
+	strd	r6, [r3], #0x08		/* ST:08-0f */
+	ldr	r6, [r1], #0x04		/* LD:20-23 */
+	ldr	r7, [r1], #0x04		/* LD:24-27 */
+	pld	[r1, #0x18]		/* Prefetch 0x40 */
+	strd	r8, [r3], #0x08		/* ST:10-17 */
+	ldr	r8, [r1], #0x04		/* LD:28-2b */
+	ldr	r9, [r1], #0x04		/* LD:2c-2f */
+	strd	r4, [r3], #0x08		/* ST:18-1f */
+	ldr	r4, [r1], #0x04		/* LD:30-33 */
+	ldr	r5, [r1], #0x04		/* LD:34-37 */
+	strd	r6, [r3], #0x08		/* ST:20-27 */
+	ldr	r6, [r1], #0x04		/* LD:38-3b */
+	ldr	r7, [r1], #0x04		/* LD:3c-3f */
+	strd	r8, [r3], #0x08		/* ST:28-2f */
+	ldr	r8, [r1], #0x04		/* LD:40-43 */
+	ldr	r9, [r1], #0x04		/* LD:44-47 */
+	pld	[r1, #0x18]		/* Prefetch 0x60 */
+	strd	r4, [r3], #0x08		/* ST:30-37 */
+	ldr	r4, [r1], #0x04		/* LD:48-4b */
+	ldr	r5, [r1], #0x04		/* LD:4c-4f */
+	strd	r6, [r3], #0x08		/* ST:38-3f */
+	ldr	r6, [r1], #0x04		/* LD:50-53 */
+	ldr	r7, [r1], #0x04		/* LD:54-57 */
+	strd	r8, [r3], #0x08		/* ST:40-47 */
+	ldr	r8, [r1], #0x04		/* LD:58-5b */
+	ldr	r9, [r1], #0x04		/* LD:5c-5f */
+	strd	r4, [r3], #0x08		/* ST:48-4f */
+	ldr	r4, [r1], #0x04		/* LD:60-63 */
+	ldr	r5, [r1], #0x04		/* LD:64-67 */
+	pld	[r1, #0x18]		/* Prefetch 0x80 */
+	strd	r6, [r3], #0x08		/* ST:50-57 */
+	ldr	r6, [r1], #0x04		/* LD:68-6b */
+	ldr	r7, [r1], #0x04		/* LD:6c-6f */
+	strd	r8, [r3], #0x08		/* ST:58-5f */
+	ldr	r8, [r1], #0x04		/* LD:70-73 */
+	ldr	r9, [r1], #0x04		/* LD:74-77 */
+	strd	r4, [r3], #0x08		/* ST:60-67 */
+	ldr	r4, [r1], #0x04		/* LD:78-7b */
+	ldr	r5, [r1], #0x04		/* LD:7c-7f */
+	strd	r6, [r3], #0x08		/* ST:68-6f */
+	strd	r8, [r3], #0x08		/* ST:70-77 */
+	subs	r2, r2, #0x80
+	strd	r4, [r3], #0x08		/* ST:78-7f */
+	bge	.Lmemcpy_w_loop128
+
+.Lmemcpy_w_lessthan128:
+	adds	r2, r2, #0x80		/* Adjust for extra sub */
+	ldmfdeq	sp!, {r4-r9}
+	RETeq			/* Return now if done */
+	subs	r2, r2, #0x20
+	blt	.Lmemcpy_w_lessthan32
+
+	/* Copy 32 bytes at a time */
+.Lmemcpy_w_loop32:
+	ldr	r4, [r1], #0x04
+	ldr	r5, [r1], #0x04
+	pld	[r1, #0x18]
+	ldr	r6, [r1], #0x04
+	ldr	r7, [r1], #0x04
+	ldr	r8, [r1], #0x04
+	ldr	r9, [r1], #0x04
+	strd	r4, [r3], #0x08
+	ldr	r4, [r1], #0x04
+	ldr	r5, [r1], #0x04
+	strd	r6, [r3], #0x08
+	strd	r8, [r3], #0x08
+	subs	r2, r2, #0x20
+	strd	r4, [r3], #0x08
+	bge	.Lmemcpy_w_loop32
+
+.Lmemcpy_w_lessthan32:
+	adds	r2, r2, #0x20		/* Adjust for extra sub */
+	ldmfdeq	sp!, {r4-r9}
+	RETeq			/* Return now if done */
+
+	and	r4, r2, #0x18
+	rsbs	r4, r4, #0x18
+	addne	pc, pc, r4, lsl #1
+	nop
+
+	/* At least 24 bytes remaining */
+	ldr	r4, [r1], #0x04
+	ldr	r5, [r1], #0x04
+	sub	r2, r2, #0x08
+	strd	r4, [r3], #0x08
+
+	/* At least 16 bytes remaining */
+	ldr	r4, [r1], #0x04
+	ldr	r5, [r1], #0x04
+	sub	r2, r2, #0x08
+	strd	r4, [r3], #0x08
+
+	/* At least 8 bytes remaining */
+	ldr	r4, [r1], #0x04
+	ldr	r5, [r1], #0x04
+	subs	r2, r2, #0x08
+	strd	r4, [r3], #0x08
+
+	/* Less than 8 bytes remaining */
+	ldmfd	sp!, {r4-r9}
+	RETeq			/* Return now if done */
+	subs	r2, r2, #0x04
+	ldrge	ip, [r1], #0x04
+	strge	ip, [r3], #0x04
+	RETeq			/* Return now if done */
+	addlt	r2, r2, #0x04
+	ldrb	ip, [r1], #0x01
+	cmp	r2, #0x02
+	ldrbge	r2, [r1], #0x01
+	strb	ip, [r3], #0x01
+	ldrbgt	ip, [r1]
+	strbge	r2, [r3], #0x01
+	strbgt	ip, [r3]
+	RET
+/* Place a literal pool here for the above ldr instructions to use */
+.ltorg
+
+
+/*
+ * At this point, it has not been possible to word align both buffers.
+ * The destination buffer is word aligned, but the source buffer is not.
+ */
+.Lmemcpy_bad_align:
+	stmfd	sp!, {r4-r7}
+	bic	r1, r1, #0x03
+	cmp	ip, #2
+	ldr	ip, [r1], #0x04
+	bgt	.Lmemcpy_bad3
+	beq	.Lmemcpy_bad2
+	b	.Lmemcpy_bad1
+
+.Lmemcpy_bad1_loop16:
+#ifdef __ARMEB__
+	mov	r4, ip, lsl #8
+#else
+	mov	r4, ip, lsr #8
+#endif
+	ldr	r5, [r1], #0x04
+	pld	[r1, #0x018]
+	ldr	r6, [r1], #0x04
+	ldr	r7, [r1], #0x04
+	ldr	ip, [r1], #0x04
+#ifdef __ARMEB__
+	orr	r4, r4, r5, lsr #24
+	mov	r5, r5, lsl #8
+	orr	r5, r5, r6, lsr #24
+	mov	r6, r6, lsl #8
+	orr	r6, r6, r7, lsr #24
+	mov	r7, r7, lsl #8
+	orr	r7, r7, ip, lsr #24
+#else
+	orr	r4, r4, r5, lsl #24
+	mov	r5, r5, lsr #8
+	orr	r5, r5, r6, lsl #24
+	mov	r6, r6, lsr #8
+	orr	r6, r6, r7, lsl #24
+	mov	r7, r7, lsr #8
+	orr	r7, r7, ip, lsl #24
+#endif
+	str	r4, [r3], #0x04
+	str	r5, [r3], #0x04
+	str	r6, [r3], #0x04
+	str	r7, [r3], #0x04
+.Lmemcpy_bad1:
+	subs	r2, r2, #0x10
+	bge	.Lmemcpy_bad1_loop16
+
+	adds	r2, r2, #0x10
+	ldmfdeq	sp!, {r4-r7}
+	RETeq			/* Return now if done */
+	subs	r2, r2, #0x04
+	sublt	r1, r1, #0x03
+	blt	.Lmemcpy_bad_done
+
+.Lmemcpy_bad1_loop4:
+#ifdef __ARMEB__
+	mov	r4, ip, lsl #8
+#else
+	mov	r4, ip, lsr #8
+#endif
+	ldr	ip, [r1], #0x04
+	subs	r2, r2, #0x04
+#ifdef __ARMEB__
+	orr	r4, r4, ip, lsr #24
+#else
+	orr	r4, r4, ip, lsl #24
+#endif
+	str	r4, [r3], #0x04
+	bge	.Lmemcpy_bad1_loop4
+	sub	r1, r1, #0x03
+	b	.Lmemcpy_bad_done
+
+.Lmemcpy_bad2_loop16:
+#ifdef __ARMEB__
+	mov	r4, ip, lsl #16
+#else
+	mov	r4, ip, lsr #16
+#endif
+	ldr	r5, [r1], #0x04
+	pld	[r1, #0x018]
+	ldr	r6, [r1], #0x04
+	ldr	r7, [r1], #0x04
+	ldr	ip, [r1], #0x04
+#ifdef __ARMEB__
+	orr	r4, r4, r5, lsr #16
+	mov	r5, r5, lsl #16
+	orr	r5, r5, r6, lsr #16
+	mov	r6, r6, lsl #16
+	orr	r6, r6, r7, lsr #16
+	mov	r7, r7, lsl #16
+	orr	r7, r7, ip, lsr #16
+#else
+	orr	r4, r4, r5, lsl #16
+	mov	r5, r5, lsr #16
+	orr	r5, r5, r6, lsl #16
+	mov	r6, r6, lsr #16
+	orr	r6, r6, r7, lsl #16
+	mov	r7, r7, lsr #16
+	orr	r7, r7, ip, lsl #16
+#endif
+	str	r4, [r3], #0x04
+	str	r5, [r3], #0x04
+	str	r6, [r3], #0x04
+	str	r7, [r3], #0x04
+.Lmemcpy_bad2:
+	subs	r2, r2, #0x10
+	bge	.Lmemcpy_bad2_loop16
+
+	adds	r2, r2, #0x10
+	ldmfdeq	sp!, {r4-r7}
+	RETeq			/* Return now if done */
+	subs	r2, r2, #0x04
+	sublt	r1, r1, #0x02
+	blt	.Lmemcpy_bad_done
+
+.Lmemcpy_bad2_loop4:
+#ifdef __ARMEB__
+	mov	r4, ip, lsl #16
+#else
+	mov	r4, ip, lsr #16
+#endif
+	ldr	ip, [r1], #0x04
+	subs	r2, r2, #0x04
+#ifdef __ARMEB__
+	orr	r4, r4, ip, lsr #16
+#else
+	orr	r4, r4, ip, lsl #16
+#endif
+	str	r4, [r3], #0x04
+	bge	.Lmemcpy_bad2_loop4
+	sub	r1, r1, #0x02
+	b	.Lmemcpy_bad_done
+
+.Lmemcpy_bad3_loop16:
+#ifdef __ARMEB__
+	mov	r4, ip, lsl #24
+#else
+	mov	r4, ip, lsr #24
+#endif
+	ldr	r5, [r1], #0x04
+	pld	[r1, #0x018]
+	ldr	r6, [r1], #0x04
+	ldr	r7, [r1], #0x04
+	ldr	ip, [r1], #0x04
+#ifdef __ARMEB__
+	orr	r4, r4, r5, lsr #8
+	mov	r5, r5, lsl #24
+	orr	r5, r5, r6, lsr #8
+	mov	r6, r6, lsl #24
+	orr	r6, r6, r7, lsr #8
+	mov	r7, r7, lsl #24
+	orr	r7, r7, ip, lsr #8
+#else
+	orr	r4, r4, r5, lsl #8
+	mov	r5, r5, lsr #24
+	orr	r5, r5, r6, lsl #8
+	mov	r6, r6, lsr #24
+	orr	r6, r6, r7, lsl #8
+	mov	r7, r7, lsr #24
+	orr	r7, r7, ip, lsl #8
+#endif
+	str	r4, [r3], #0x04
+	str	r5, [r3], #0x04
+	str	r6, [r3], #0x04
+	str	r7, [r3], #0x04
+.Lmemcpy_bad3:
+	subs	r2, r2, #0x10
+	bge	.Lmemcpy_bad3_loop16
+
+	adds	r2, r2, #0x10
+	ldmfdeq	sp!, {r4-r7}
+	RETeq			/* Return now if done */
+	subs	r2, r2, #0x04
+	sublt	r1, r1, #0x01
+	blt	.Lmemcpy_bad_done
+
+.Lmemcpy_bad3_loop4:
+#ifdef __ARMEB__
+	mov	r4, ip, lsl #24
+#else
+	mov	r4, ip, lsr #24
+#endif
+	ldr	ip, [r1], #0x04
+	subs	r2, r2, #0x04
+#ifdef __ARMEB__
+	orr	r4, r4, ip, lsr #8
+#else
+	orr	r4, r4, ip, lsl #8
+#endif
+	str	r4, [r3], #0x04
+	bge	.Lmemcpy_bad3_loop4
+	sub	r1, r1, #0x01
+
+.Lmemcpy_bad_done:
+	ldmfd	sp!, {r4-r7}
+	adds	r2, r2, #0x04
+	RETeq
+	ldrb	ip, [r1], #0x01
+	cmp	r2, #0x02
+	ldrbge	r2, [r1], #0x01
+	strb	ip, [r3], #0x01
+	ldrbgt	ip, [r1]
+	strbge	r2, [r3], #0x01
+	strbgt	ip, [r3]
+	RET
+
+
+/*
+ * Handle short copies (less than 16 bytes), possibly misaligned.
+ * Some of these are *very* common, thanks to the network stack,
+ * and so are handled specially.
+ */
+.Lmemcpy_short:
+	add	pc, pc, r2, lsl #2
+	nop
+	RET			/* 0x00 */
+	b	.Lmemcpy_bytewise	/* 0x01 */
+	b	.Lmemcpy_bytewise	/* 0x02 */
+	b	.Lmemcpy_bytewise	/* 0x03 */
+	b	.Lmemcpy_4		/* 0x04 */
+	b	.Lmemcpy_bytewise	/* 0x05 */
+	b	.Lmemcpy_6		/* 0x06 */
+	b	.Lmemcpy_bytewise	/* 0x07 */
+	b	.Lmemcpy_8		/* 0x08 */
+	b	.Lmemcpy_bytewise	/* 0x09 */
+	b	.Lmemcpy_bytewise	/* 0x0a */
+	b	.Lmemcpy_bytewise	/* 0x0b */
+	b	.Lmemcpy_c		/* 0x0c */
+.Lmemcpy_bytewise:
+	mov	r3, r0			/* We must not clobber r0 */
+	ldrb	ip, [r1], #0x01
+1:	subs	r2, r2, #0x01
+	strb	ip, [r3], #0x01
+	ldrbne	ip, [r1], #0x01
+	bne	1b
+	RET
+
+/******************************************************************************
+ * Special case for 4 byte copies
+ */
+#define	LMEMCPY_4_LOG2	6	/* 64 bytes */
+#define	LMEMCPY_4_PAD	.align LMEMCPY_4_LOG2
+	LMEMCPY_4_PAD
+.Lmemcpy_4:
+	and	r2, r1, #0x03
+	orr	r2, r2, r0, lsl #2
+	ands	r2, r2, #0x0f
+	sub	r3, pc, #0x14
+	addne	pc, r3, r2, lsl #LMEMCPY_4_LOG2
+
+/*
+ * 0000: dst is 32-bit aligned, src is 32-bit aligned
+ */
+	ldr	r2, [r1]
+	str	r2, [r0]
+	RET
+	LMEMCPY_4_PAD
+
+/*
+ * 0001: dst is 32-bit aligned, src is 8-bit aligned
+ */
+	ldr	r3, [r1, #-1]		/* BE:r3 = x012  LE:r3 = 210x */
+	ldr	r2, [r1, #3]		/* BE:r2 = 3xxx  LE:r2 = xxx3 */
+#ifdef __ARMEB__
+	mov	r3, r3, lsl #8		/* r3 = 012. */
+	orr	r3, r3, r2, lsr #24	/* r3 = 0123 */
+#else
+	mov	r3, r3, lsr #8		/* r3 = .210 */
+	orr	r3, r3, r2, lsl #24	/* r3 = 3210 */
+#endif
+	str	r3, [r0]
+	RET
+	LMEMCPY_4_PAD
+
+/*
+ * 0010: dst is 32-bit aligned, src is 16-bit aligned
+ */
+#ifdef __ARMEB__
+	ldrh	r3, [r1]
+	ldrh	r2, [r1, #0x02]
+#else
+	ldrh	r3, [r1, #0x02]
+	ldrh	r2, [r1]
+#endif
+	orr	r3, r2, r3, lsl #16
+	str	r3, [r0]
+	RET
+	LMEMCPY_4_PAD
+
+/*
+ * 0011: dst is 32-bit aligned, src is 8-bit aligned
+ */
+	ldr	r3, [r1, #-3]		/* BE:r3 = xxx0  LE:r3 = 0xxx */
+	ldr	r2, [r1, #1]		/* BE:r2 = 123x  LE:r2 = x321 */
+#ifdef __ARMEB__
+	mov	r3, r3, lsl #24		/* r3 = 0... */
+	orr	r3, r3, r2, lsr #8	/* r3 = 0123 */
+#else
+	mov	r3, r3, lsr #24		/* r3 = ...0 */
+	orr	r3, r3, r2, lsl #8	/* r3 = 3210 */
+#endif
+	str	r3, [r0]
+	RET
+	LMEMCPY_4_PAD
+
+/*
+ * 0100: dst is 8-bit aligned, src is 32-bit aligned
+ */
+	ldr	r2, [r1]
+#ifdef __ARMEB__
+	strb	r2, [r0, #0x03]
+	mov	r3, r2, lsr #8
+	mov	r1, r2, lsr #24
+	strb	r1, [r0]
+#else
+	strb	r2, [r0]
+	mov	r3, r2, lsr #8
+	mov	r1, r2, lsr #24
+	strb	r1, [r0, #0x03]
+#endif
+	strh	r3, [r0, #0x01]
+	RET
+	LMEMCPY_4_PAD
+
+/*
+ * 0101: dst is 8-bit aligned, src is 8-bit aligned
+ */
+	ldrb	r2, [r1]
+	ldrh	r3, [r1, #0x01]
+	ldrb	r1, [r1, #0x03]
+	strb	r2, [r0]
+	strh	r3, [r0, #0x01]
+	strb	r1, [r0, #0x03]
+	RET
+	LMEMCPY_4_PAD
+
+/*
+ * 0110: dst is 8-bit aligned, src is 16-bit aligned
+ */
+	ldrh	r2, [r1]		/* BE:r2 = ..01  LE:r2 = ..10 */
+	ldrh	r3, [r1, #0x02]		/* LE:r3 = ..23  LE:r3 = ..32 */
+#ifdef __ARMEB__
+	mov	r1, r2, lsr #8		/* r1 = ...0 */
+	strb	r1, [r0]
+	mov	r2, r2, lsl #8		/* r2 = .01. */
+	orr	r2, r2, r3, lsr #8	/* r2 = .012 */
+#else
+	strb	r2, [r0]
+	mov	r2, r2, lsr #8		/* r2 = ...1 */
+	orr	r2, r2, r3, lsl #8	/* r2 = .321 */
+	mov	r3, r3, lsr #8		/* r3 = ...3 */
+#endif
+	strh	r2, [r0, #0x01]
+	strb	r3, [r0, #0x03]
+	RET
+	LMEMCPY_4_PAD
+
+/*
+ * 0111: dst is 8-bit aligned, src is 8-bit aligned
+ */
+	ldrb	r2, [r1]
+	ldrh	r3, [r1, #0x01]
+	ldrb	r1, [r1, #0x03]
+	strb	r2, [r0]
+	strh	r3, [r0, #0x01]
+	strb	r1, [r0, #0x03]
+	RET
+	LMEMCPY_4_PAD
+
+/*
+ * 1000: dst is 16-bit aligned, src is 32-bit aligned
+ */
+	ldr	r2, [r1]
+#ifdef __ARMEB__
+	strh	r2, [r0, #0x02]
+	mov	r3, r2, lsr #16
+	strh	r3, [r0]
+#else
+	strh	r2, [r0]
+	mov	r3, r2, lsr #16
+	strh	r3, [r0, #0x02]
+#endif
+	RET
+	LMEMCPY_4_PAD
+
+/*
+ * 1001: dst is 16-bit aligned, src is 8-bit aligned
+ */
+	ldr	r2, [r1, #-1]		/* BE:r2 = x012  LE:r2 = 210x */
+	ldr	r3, [r1, #3]		/* BE:r3 = 3xxx  LE:r3 = xxx3 */
+	mov	r1, r2, lsr #8		/* BE:r1 = .x01  LE:r1 = .210 */
+	strh	r1, [r0]
+#ifdef __ARMEB__
+	mov	r2, r2, lsl #8		/* r2 = 012. */
+	orr	r2, r2, r3, lsr #24	/* r2 = 0123 */
+#else
+	mov	r2, r2, lsr #24		/* r2 = ...2 */
+	orr	r2, r2, r3, lsl #8	/* r2 = xx32 */
+#endif
+	strh	r2, [r0, #0x02]
+	RET
+	LMEMCPY_4_PAD
+
+/*
+ * 1010: dst is 16-bit aligned, src is 16-bit aligned
+ */
+	ldrh	r2, [r1]
+	ldrh	r3, [r1, #0x02]
+	strh	r2, [r0]
+	strh	r3, [r0, #0x02]
+	RET
+	LMEMCPY_4_PAD
+
+/*
+ * 1011: dst is 16-bit aligned, src is 8-bit aligned
+ */
+	ldr	r3, [r1, #1]		/* BE:r3 = 123x  LE:r3 = x321 */
+	ldr	r2, [r1, #-3]		/* BE:r2 = xxx0  LE:r2 = 0xxx */
+	mov	r1, r3, lsr #8		/* BE:r1 = .123  LE:r1 = .x32 */
+	strh	r1, [r0, #0x02]
+#ifdef __ARMEB__
+	mov	r3, r3, lsr #24		/* r3 = ...1 */
+	orr	r3, r3, r2, lsl #8	/* r3 = xx01 */
+#else
+	mov	r3, r3, lsl #8		/* r3 = 321. */
+	orr	r3, r3, r2, lsr #24	/* r3 = 3210 */
+#endif
+	strh	r3, [r0]
+	RET
+	LMEMCPY_4_PAD
+
+/*
+ * 1100: dst is 8-bit aligned, src is 32-bit aligned
+ */
+	ldr	r2, [r1]		/* BE:r2 = 0123  LE:r2 = 3210 */
+#ifdef __ARMEB__
+	strb	r2, [r0, #0x03]
+	mov	r3, r2, lsr #8
+	mov	r1, r2, lsr #24
+	strh	r3, [r0, #0x01]
+	strb	r1, [r0]
+#else
+	strb	r2, [r0]
+	mov	r3, r2, lsr #8
+	mov	r1, r2, lsr #24
+	strh	r3, [r0, #0x01]
+	strb	r1, [r0, #0x03]
+#endif
+	RET
+	LMEMCPY_4_PAD
+
+/*
+ * 1101: dst is 8-bit aligned, src is 8-bit aligned
+ */
+	ldrb	r2, [r1]
+	ldrh	r3, [r1, #0x01]
+	ldrb	r1, [r1, #0x03]
+	strb	r2, [r0]
+	strh	r3, [r0, #0x01]
+	strb	r1, [r0, #0x03]
+	RET
+	LMEMCPY_4_PAD
+
+/*
+ * 1110: dst is 8-bit aligned, src is 16-bit aligned
+ */
+#ifdef __ARMEB__
+	ldrh	r3, [r1, #0x02]		/* BE:r3 = ..23  LE:r3 = ..32 */
+	ldrh	r2, [r1]		/* BE:r2 = ..01  LE:r2 = ..10 */
+	strb	r3, [r0, #0x03]
+	mov	r3, r3, lsr #8		/* r3 = ...2 */
+	orr	r3, r3, r2, lsl #8	/* r3 = ..12 */
+	strh	r3, [r0, #0x01]
+	mov	r2, r2, lsr #8		/* r2 = ...0 */
+	strb	r2, [r0]
+#else
+	ldrh	r2, [r1]		/* BE:r2 = ..01  LE:r2 = ..10 */
+	ldrh	r3, [r1, #0x02]		/* BE:r3 = ..23  LE:r3 = ..32 */
+	strb	r2, [r0]
+	mov	r2, r2, lsr #8		/* r2 = ...1 */
+	orr	r2, r2, r3, lsl #8	/* r2 = .321 */
+	strh	r2, [r0, #0x01]
+	mov	r3, r3, lsr #8		/* r3 = ...3 */
+	strb	r3, [r0, #0x03]
+#endif
+	RET
+	LMEMCPY_4_PAD
+
+/*
+ * 1111: dst is 8-bit aligned, src is 8-bit aligned
+ */
+	ldrb	r2, [r1]
+	ldrh	r3, [r1, #0x01]
+	ldrb	r1, [r1, #0x03]
+	strb	r2, [r0]
+	strh	r3, [r0, #0x01]
+	strb	r1, [r0, #0x03]
+	RET
+	LMEMCPY_4_PAD
+
+
+/******************************************************************************
+ * Special case for 6 byte copies
+ */
+#define	LMEMCPY_6_LOG2	6	/* 64 bytes */
+#define	LMEMCPY_6_PAD	.align LMEMCPY_6_LOG2
+	LMEMCPY_6_PAD
+.Lmemcpy_6:
+	and	r2, r1, #0x03
+	orr	r2, r2, r0, lsl #2
+	ands	r2, r2, #0x0f
+	sub	r3, pc, #0x14
+	addne	pc, r3, r2, lsl #LMEMCPY_6_LOG2
+
+/*
+ * 0000: dst is 32-bit aligned, src is 32-bit aligned
+ */
+	ldr	r2, [r1]
+	ldrh	r3, [r1, #0x04]
+	str	r2, [r0]
+	strh	r3, [r0, #0x04]
+	RET
+	LMEMCPY_6_PAD
+
+/*
+ * 0001: dst is 32-bit aligned, src is 8-bit aligned
+ */
+	ldr	r2, [r1, #-1]		/* BE:r2 = x012  LE:r2 = 210x */
+	ldr	r3, [r1, #0x03]		/* BE:r3 = 345x  LE:r3 = x543 */
+#ifdef __ARMEB__
+	mov	r2, r2, lsl #8		/* r2 = 012. */
+	orr	r2, r2, r3, lsr #24	/* r2 = 0123 */
+#else
+	mov	r2, r2, lsr #8		/* r2 = .210 */
+	orr	r2, r2, r3, lsl #24	/* r2 = 3210 */
+#endif
+	mov	r3, r3, lsr #8		/* BE:r3 = .345  LE:r3 = .x54 */
+	str	r2, [r0]
+	strh	r3, [r0, #0x04]
+	RET
+	LMEMCPY_6_PAD
+
+/*
+ * 0010: dst is 32-bit aligned, src is 16-bit aligned
+ */
+	ldr	r3, [r1, #0x02]		/* BE:r3 = 2345  LE:r3 = 5432 */
+	ldrh	r2, [r1]		/* BE:r2 = ..01  LE:r2 = ..10 */
+#ifdef __ARMEB__
+	mov	r1, r3, lsr #16		/* r1 = ..23 */
+	orr	r1, r1, r2, lsl #16	/* r1 = 0123 */
+	str	r1, [r0]
+	strh	r3, [r0, #0x04]
+#else
+	mov	r1, r3, lsr #16		/* r1 = ..54 */
+	orr	r2, r2, r3, lsl #16	/* r2 = 3210 */
+	str	r2, [r0]
+	strh	r1, [r0, #0x04]
+#endif
+	RET
+	LMEMCPY_6_PAD
+
+/*
+ * 0011: dst is 32-bit aligned, src is 8-bit aligned
+ */
+	ldr	r2, [r1, #-3]		/* BE:r2 = xxx0  LE:r2 = 0xxx */
+	ldr	r3, [r1, #1]		/* BE:r3 = 1234  LE:r3 = 4321 */
+	ldr	r1, [r1, #5]		/* BE:r1 = 5xxx  LE:r3 = xxx5 */
+#ifdef __ARMEB__
+	mov	r2, r2, lsl #24		/* r2 = 0... */
+	orr	r2, r2, r3, lsr #8	/* r2 = 0123 */
+	mov	r3, r3, lsl #8		/* r3 = 234. */
+	orr	r1, r3, r1, lsr #24	/* r1 = 2345 */
+#else
+	mov	r2, r2, lsr #24		/* r2 = ...0 */
+	orr	r2, r2, r3, lsl #8	/* r2 = 3210 */
+	mov	r1, r1, lsl #8		/* r1 = xx5. */
+	orr	r1, r1, r3, lsr #24	/* r1 = xx54 */
+#endif
+	str	r2, [r0]
+	strh	r1, [r0, #0x04]
+	RET
+	LMEMCPY_6_PAD
+
+/*
+ * 0100: dst is 8-bit aligned, src is 32-bit aligned
+ */
+	ldr	r3, [r1]		/* BE:r3 = 0123  LE:r3 = 3210 */
+	ldrh	r2, [r1, #0x04]		/* BE:r2 = ..45  LE:r2 = ..54 */
+	mov	r1, r3, lsr #8		/* BE:r1 = .012  LE:r1 = .321 */
+	strh	r1, [r0, #0x01]
+#ifdef __ARMEB__
+	mov	r1, r3, lsr #24		/* r1 = ...0 */
+	strb	r1, [r0]
+	mov	r3, r3, lsl #8		/* r3 = 123. */
+	orr	r3, r3, r2, lsr #8	/* r3 = 1234 */
+#else
+	strb	r3, [r0]
+	mov	r3, r3, lsr #24		/* r3 = ...3 */
+	orr	r3, r3, r2, lsl #8	/* r3 = .543 */
+	mov	r2, r2, lsr #8		/* r2 = ...5 */
+#endif
+	strh	r3, [r0, #0x03]
+	strb	r2, [r0, #0x05]
+	RET
+	LMEMCPY_6_PAD
+
+/*
+ * 0101: dst is 8-bit aligned, src is 8-bit aligned
+ */
+	ldrb	r2, [r1]
+	ldrh	r3, [r1, #0x01]
+	ldrh	ip, [r1, #0x03]
+	ldrb	r1, [r1, #0x05]
+	strb	r2, [r0]
+	strh	r3, [r0, #0x01]
+	strh	ip, [r0, #0x03]
+	strb	r1, [r0, #0x05]
+	RET
+	LMEMCPY_6_PAD
+
+/*
+ * 0110: dst is 8-bit aligned, src is 16-bit aligned
+ */
+	ldrh	r2, [r1]		/* BE:r2 = ..01  LE:r2 = ..10 */
+	ldr	r1, [r1, #0x02]		/* BE:r1 = 2345  LE:r1 = 5432 */
+#ifdef __ARMEB__
+	mov	r3, r2, lsr #8		/* r3 = ...0 */
+	strb	r3, [r0]
+	strb	r1, [r0, #0x05]
+	mov	r3, r1, lsr #8		/* r3 = .234 */
+	strh	r3, [r0, #0x03]
+	mov	r3, r2, lsl #8		/* r3 = .01. */
+	orr	r3, r3, r1, lsr #24	/* r3 = .012 */
+	strh	r3, [r0, #0x01]
+#else
+	strb	r2, [r0]
+	mov	r3, r1, lsr #24
+	strb	r3, [r0, #0x05]
+	mov	r3, r1, lsr #8		/* r3 = .543 */
+	strh	r3, [r0, #0x03]
+	mov	r3, r2, lsr #8		/* r3 = ...1 */
+	orr	r3, r3, r1, lsl #8	/* r3 = 4321 */
+	strh	r3, [r0, #0x01]
+#endif
+	RET
+	LMEMCPY_6_PAD
+
+/*
+ * 0111: dst is 8-bit aligned, src is 8-bit aligned
+ */
+	ldrb	r2, [r1]
+	ldrh	r3, [r1, #0x01]
+	ldrh	ip, [r1, #0x03]
+	ldrb	r1, [r1, #0x05]
+	strb	r2, [r0]
+	strh	r3, [r0, #0x01]
+	strh	ip, [r0, #0x03]
+	strb	r1, [r0, #0x05]
+	RET
+	LMEMCPY_6_PAD
+
+/*
+ * 1000: dst is 16-bit aligned, src is 32-bit aligned
+ */
+#ifdef __ARMEB__
+	ldr	r2, [r1]		/* r2 = 0123 */
+	ldrh	r3, [r1, #0x04]		/* r3 = ..45 */
+	mov	r1, r2, lsr #16		/* r1 = ..01 */
+	orr	r3, r3, r2, lsl#16	/* r3 = 2345 */
+	strh	r1, [r0]
+	str	r3, [r0, #0x02]
+#else
+	ldrh	r2, [r1, #0x04]		/* r2 = ..54 */
+	ldr	r3, [r1]		/* r3 = 3210 */
+	mov	r2, r2, lsl #16		/* r2 = 54.. */
+	orr	r2, r2, r3, lsr #16	/* r2 = 5432 */
+	strh	r3, [r0]
+	str	r2, [r0, #0x02]
+#endif
+	RET
+	LMEMCPY_6_PAD
+
+/*
+ * 1001: dst is 16-bit aligned, src is 8-bit aligned
+ */
+	ldr	r3, [r1, #-1]		/* BE:r3 = x012  LE:r3 = 210x */
+	ldr	r2, [r1, #3]		/* BE:r2 = 345x  LE:r2 = x543 */
+	mov	r1, r3, lsr #8		/* BE:r1 = .x01  LE:r1 = .210 */
+#ifdef __ARMEB__
+	mov	r2, r2, lsr #8		/* r2 = .345 */
+	orr	r2, r2, r3, lsl #24	/* r2 = 2345 */
+#else
+	mov	r2, r2, lsl #8		/* r2 = 543. */
+	orr	r2, r2, r3, lsr #24	/* r2 = 5432 */
+#endif
+	strh	r1, [r0]
+	str	r2, [r0, #0x02]
+	RET
+	LMEMCPY_6_PAD
+
+/*
+ * 1010: dst is 16-bit aligned, src is 16-bit aligned
+ */
+	ldrh	r2, [r1]
+	ldr	r3, [r1, #0x02]
+	strh	r2, [r0]
+	str	r3, [r0, #0x02]
+	RET
+	LMEMCPY_6_PAD
+
+/*
+ * 1011: dst is 16-bit aligned, src is 8-bit aligned
+ */
+	ldrb	r3, [r1]		/* r3 = ...0 */
+	ldr	r2, [r1, #0x01]		/* BE:r2 = 1234  LE:r2 = 4321 */
+	ldrb	r1, [r1, #0x05]		/* r1 = ...5 */
+#ifdef __ARMEB__
+	mov	r3, r3, lsl #8		/* r3 = ..0. */
+	orr	r3, r3, r2, lsr #24	/* r3 = ..01 */
+	orr	r1, r1, r2, lsl #8	/* r1 = 2345 */
+#else
+	orr	r3, r3, r2, lsl #8	/* r3 = 3210 */
+	mov	r1, r1, lsl #24		/* r1 = 5... */
+	orr	r1, r1, r2, lsr #8	/* r1 = 5432 */
+#endif
+	strh	r3, [r0]
+	str	r1, [r0, #0x02]
+	RET
+	LMEMCPY_6_PAD
+
+/*
+ * 1100: dst is 8-bit aligned, src is 32-bit aligned
+ */
+	ldr	r2, [r1]		/* BE:r2 = 0123  LE:r2 = 3210 */
+	ldrh	r1, [r1, #0x04]		/* BE:r1 = ..45  LE:r1 = ..54 */
+#ifdef __ARMEB__
+	mov	r3, r2, lsr #24		/* r3 = ...0 */
+	strb	r3, [r0]
+	mov	r2, r2, lsl #8		/* r2 = 123. */
+	orr	r2, r2, r1, lsr #8	/* r2 = 1234 */
+#else
+	strb	r2, [r0]
+	mov	r2, r2, lsr #8		/* r2 = .321 */
+	orr	r2, r2, r1, lsl #24	/* r2 = 4321 */
+	mov	r1, r1, lsr #8		/* r1 = ...5 */
+#endif
+	str	r2, [r0, #0x01]
+	strb	r1, [r0, #0x05]
+	RET
+	LMEMCPY_6_PAD
+
+/*
+ * 1101: dst is 8-bit aligned, src is 8-bit aligned
+ */
+	ldrb	r2, [r1]
+	ldrh	r3, [r1, #0x01]
+	ldrh	ip, [r1, #0x03]
+	ldrb	r1, [r1, #0x05]
+	strb	r2, [r0]
+	strh	r3, [r0, #0x01]
+	strh	ip, [r0, #0x03]
+	strb	r1, [r0, #0x05]
+	RET
+	LMEMCPY_6_PAD
+
+/*
+ * 1110: dst is 8-bit aligned, src is 16-bit aligned
+ */
+	ldrh	r2, [r1]		/* BE:r2 = ..01  LE:r2 = ..10 */
+	ldr	r1, [r1, #0x02]		/* BE:r1 = 2345  LE:r1 = 5432 */
+#ifdef __ARMEB__
+	mov	r3, r2, lsr #8		/* r3 = ...0 */
+	strb	r3, [r0]
+	mov	r2, r2, lsl #24		/* r2 = 1... */
+	orr	r2, r2, r1, lsr #8	/* r2 = 1234 */
+#else
+	strb	r2, [r0]
+	mov	r2, r2, lsr #8		/* r2 = ...1 */
+	orr	r2, r2, r1, lsl #8	/* r2 = 4321 */
+	mov	r1, r1, lsr #24		/* r1 = ...5 */
+#endif
+	str	r2, [r0, #0x01]
+	strb	r1, [r0, #0x05]
+	RET
+	LMEMCPY_6_PAD
+
+/*
+ * 1111: dst is 8-bit aligned, src is 8-bit aligned
+ */
+	ldrb	r2, [r1]
+	ldr	r3, [r1, #0x01]
+	ldrb	r1, [r1, #0x05]
+	strb	r2, [r0]
+	str	r3, [r0, #0x01]
+	strb	r1, [r0, #0x05]
+	RET
+	LMEMCPY_6_PAD
+
+
+/******************************************************************************
+ * Special case for 8 byte copies
+ */
+#define	LMEMCPY_8_LOG2	6	/* 64 bytes */
+#define	LMEMCPY_8_PAD	.align LMEMCPY_8_LOG2
+	LMEMCPY_8_PAD
+.Lmemcpy_8:
+	and	r2, r1, #0x03
+	orr	r2, r2, r0, lsl #2
+	ands	r2, r2, #0x0f
+	sub	r3, pc, #0x14
+	addne	pc, r3, r2, lsl #LMEMCPY_8_LOG2
+
+/*
+ * 0000: dst is 32-bit aligned, src is 32-bit aligned
+ */
+	ldr	r2, [r1]
+	ldr	r3, [r1, #0x04]
+	str	r2, [r0]
+	str	r3, [r0, #0x04]
+	RET
+	LMEMCPY_8_PAD
+
+/*
+ * 0001: dst is 32-bit aligned, src is 8-bit aligned
+ */
+	ldr	r3, [r1, #-1]		/* BE:r3 = x012  LE:r3 = 210x */
+	ldr	r2, [r1, #0x03]		/* BE:r2 = 3456  LE:r2 = 6543 */
+	ldrb	r1, [r1, #0x07]		/* r1 = ...7 */
+#ifdef __ARMEB__
+	mov	r3, r3, lsl #8		/* r3 = 012. */
+	orr	r3, r3, r2, lsr #24	/* r3 = 0123 */
+	orr	r2, r1, r2, lsl #8	/* r2 = 4567 */
+#else
+	mov	r3, r3, lsr #8		/* r3 = .210 */
+	orr	r3, r3, r2, lsl #24	/* r3 = 3210 */
+	mov	r1, r1, lsl #24		/* r1 = 7... */
+	orr	r2, r1, r2, lsr #8	/* r2 = 7654 */
+#endif
+	str	r3, [r0]
+	str	r2, [r0, #0x04]
+	RET
+	LMEMCPY_8_PAD
+
+/*
+ * 0010: dst is 32-bit aligned, src is 16-bit aligned
+ */
+	ldrh	r2, [r1]		/* BE:r2 = ..01  LE:r2 = ..10 */
+	ldr	r3, [r1, #0x02]		/* BE:r3 = 2345  LE:r3 = 5432 */
+	ldrh	r1, [r1, #0x06]		/* BE:r1 = ..67  LE:r1 = ..76 */
+#ifdef __ARMEB__
+	mov	r2, r2, lsl #16		/* r2 = 01.. */
+	orr	r2, r2, r3, lsr #16	/* r2 = 0123 */
+	orr	r3, r1, r3, lsl #16	/* r3 = 4567 */
+#else
+	orr	r2, r2, r3, lsl #16	/* r2 = 3210 */
+	mov	r3, r3, lsr #16		/* r3 = ..54 */
+	orr	r3, r3, r1, lsl #16	/* r3 = 7654 */
+#endif
+	str	r2, [r0]
+	str	r3, [r0, #0x04]
+	RET
+	LMEMCPY_8_PAD
+
+/*
+ * 0011: dst is 32-bit aligned, src is 8-bit aligned
+ */
+	ldrb	r3, [r1]		/* r3 = ...0 */
+	ldr	r2, [r1, #0x01]		/* BE:r2 = 1234  LE:r2 = 4321 */
+	ldr	r1, [r1, #0x05]		/* BE:r1 = 567x  LE:r1 = x765 */
+#ifdef __ARMEB__
+	mov	r3, r3, lsl #24		/* r3 = 0... */
+	orr	r3, r3, r2, lsr #8	/* r3 = 0123 */
+	mov	r2, r2, lsl #24		/* r2 = 4... */
+	orr	r2, r2, r1, lsr #8	/* r2 = 4567 */
+#else
+	orr	r3, r3, r2, lsl #8	/* r3 = 3210 */
+	mov	r2, r2, lsr #24		/* r2 = ...4 */
+	orr	r2, r2, r1, lsl #8	/* r2 = 7654 */
+#endif
+	str	r3, [r0]
+	str	r2, [r0, #0x04]
+	RET
+	LMEMCPY_8_PAD
+
+/*
+ * 0100: dst is 8-bit aligned, src is 32-bit aligned
+ */
+	ldr	r3, [r1]		/* BE:r3 = 0123  LE:r3 = 3210 */
+	ldr	r2, [r1, #0x04]		/* BE:r2 = 4567  LE:r2 = 7654 */
+#ifdef __ARMEB__
+	mov	r1, r3, lsr #24		/* r1 = ...0 */
+	strb	r1, [r0]
+	mov	r1, r3, lsr #8		/* r1 = .012 */
+	strb	r2, [r0, #0x07]
+	mov	r3, r3, lsl #24		/* r3 = 3... */
+	orr	r3, r3, r2, lsr #8	/* r3 = 3456 */
+#else
+	strb	r3, [r0]
+	mov	r1, r2, lsr #24		/* r1 = ...7 */
+	strb	r1, [r0, #0x07]
+	mov	r1, r3, lsr #8		/* r1 = .321 */
+	mov	r3, r3, lsr #24		/* r3 = ...3 */
+	orr	r3, r3, r2, lsl #8	/* r3 = 6543 */
+#endif
+	strh	r1, [r0, #0x01]
+	str	r3, [r0, #0x03]
+	RET
+	LMEMCPY_8_PAD
+
+/*
+ * 0101: dst is 8-bit aligned, src is 8-bit aligned
+ */
+	ldrb	r2, [r1]
+	ldrh	r3, [r1, #0x01]
+	ldr	ip, [r1, #0x03]
+	ldrb	r1, [r1, #0x07]
+	strb	r2, [r0]
+	strh	r3, [r0, #0x01]
+	str	ip, [r0, #0x03]
+	strb	r1, [r0, #0x07]
+	RET
+	LMEMCPY_8_PAD
+
+/*
+ * 0110: dst is 8-bit aligned, src is 16-bit aligned
+ */
+	ldrh	r2, [r1]		/* BE:r2 = ..01  LE:r2 = ..10 */
+	ldr	r3, [r1, #0x02]		/* BE:r3 = 2345  LE:r3 = 5432 */
+	ldrh	r1, [r1, #0x06]		/* BE:r1 = ..67  LE:r1 = ..76 */
+#ifdef __ARMEB__
+	mov	ip, r2, lsr #8		/* ip = ...0 */
+	strb	ip, [r0]
+	mov	ip, r2, lsl #8		/* ip = .01. */
+	orr	ip, ip, r3, lsr #24	/* ip = .012 */
+	strb	r1, [r0, #0x07]
+	mov	r3, r3, lsl #8		/* r3 = 345. */
+	orr	r3, r3, r1, lsr #8	/* r3 = 3456 */
+#else
+	strb	r2, [r0]		/* 0 */
+	mov	ip, r1, lsr #8		/* ip = ...7 */
+	strb	ip, [r0, #0x07]		/* 7 */
+	mov	ip, r2, lsr #8		/* ip = ...1 */
+	orr	ip, ip, r3, lsl #8	/* ip = 4321 */
+	mov	r3, r3, lsr #8		/* r3 = .543 */
+	orr	r3, r3, r1, lsl #24	/* r3 = 6543 */
+#endif
+	strh	ip, [r0, #0x01]
+	str	r3, [r0, #0x03]
+	RET
+	LMEMCPY_8_PAD
+
+/*
+ * 0111: dst is 8-bit aligned, src is 8-bit aligned
+ */
+	ldrb	r3, [r1]		/* r3 = ...0 */
+	ldr	ip, [r1, #0x01]		/* BE:ip = 1234  LE:ip = 4321 */
+	ldrh	r2, [r1, #0x05]		/* BE:r2 = ..56  LE:r2 = ..65 */
+	ldrb	r1, [r1, #0x07]		/* r1 = ...7 */
+	strb	r3, [r0]
+	mov	r3, ip, lsr #16		/* BE:r3 = ..12  LE:r3 = ..43 */
+#ifdef __ARMEB__
+	strh	r3, [r0, #0x01]
+	orr	r2, r2, ip, lsl #16	/* r2 = 3456 */
+#else
+	strh	ip, [r0, #0x01]
+	orr	r2, r3, r2, lsl #16	/* r2 = 6543 */
+#endif
+	str	r2, [r0, #0x03]
+	strb	r1, [r0, #0x07]
+	RET
+	LMEMCPY_8_PAD
+
+/*
+ * 1000: dst is 16-bit aligned, src is 32-bit aligned
+ */
+	ldr	r2, [r1]		/* BE:r2 = 0123  LE:r2 = 3210 */
+	ldr	r3, [r1, #0x04]		/* BE:r3 = 4567  LE:r3 = 7654 */
+	mov	r1, r2, lsr #16		/* BE:r1 = ..01  LE:r1 = ..32 */
+#ifdef __ARMEB__
+	strh	r1, [r0]
+	mov	r1, r3, lsr #16		/* r1 = ..45 */
+	orr	r2, r1 ,r2, lsl #16	/* r2 = 2345 */
+#else
+	strh	r2, [r0]
+	orr	r2, r1, r3, lsl #16	/* r2 = 5432 */
+	mov	r3, r3, lsr #16		/* r3 = ..76 */
+#endif
+	str	r2, [r0, #0x02]
+	strh	r3, [r0, #0x06]
+	RET
+	LMEMCPY_8_PAD
+
+/*
+ * 1001: dst is 16-bit aligned, src is 8-bit aligned
+ */
+	ldr	r2, [r1, #-1]		/* BE:r2 = x012  LE:r2 = 210x */
+	ldr	r3, [r1, #0x03]		/* BE:r3 = 3456  LE:r3 = 6543 */
+	ldrb	ip, [r1, #0x07]		/* ip = ...7 */
+	mov	r1, r2, lsr #8		/* BE:r1 = .x01  LE:r1 = .210 */
+	strh	r1, [r0]
+#ifdef __ARMEB__
+	mov	r1, r2, lsl #24		/* r1 = 2... */
+	orr	r1, r1, r3, lsr #8	/* r1 = 2345 */
+	orr	r3, ip, r3, lsl #8	/* r3 = 4567 */
+#else
+	mov	r1, r2, lsr #24		/* r1 = ...2 */
+	orr	r1, r1, r3, lsl #8	/* r1 = 5432 */
+	mov	r3, r3, lsr #24		/* r3 = ...6 */
+	orr	r3, r3, ip, lsl #8	/* r3 = ..76 */
+#endif
+	str	r1, [r0, #0x02]
+	strh	r3, [r0, #0x06]
+	RET
+	LMEMCPY_8_PAD
+
+/*
+ * 1010: dst is 16-bit aligned, src is 16-bit aligned
+ */
+	ldrh	r2, [r1]
+	ldr	ip, [r1, #0x02]
+	ldrh	r3, [r1, #0x06]
+	strh	r2, [r0]
+	str	ip, [r0, #0x02]
+	strh	r3, [r0, #0x06]
+	RET
+	LMEMCPY_8_PAD
+
+/*
+ * 1011: dst is 16-bit aligned, src is 8-bit aligned
+ */
+	ldr	r3, [r1, #0x05]		/* BE:r3 = 567x  LE:r3 = x765 */
+	ldr	r2, [r1, #0x01]		/* BE:r2 = 1234  LE:r2 = 4321 */
+	ldrb	ip, [r1]		/* ip = ...0 */
+	mov	r1, r3, lsr #8		/* BE:r1 = .567  LE:r1 = .x76 */
+	strh	r1, [r0, #0x06]
+#ifdef __ARMEB__
+	mov	r3, r3, lsr #24		/* r3 = ...5 */
+	orr	r3, r3, r2, lsl #8	/* r3 = 2345 */
+	mov	r2, r2, lsr #24		/* r2 = ...1 */
+	orr	r2, r2, ip, lsl #8	/* r2 = ..01 */
+#else
+	mov	r3, r3, lsl #24		/* r3 = 5... */
+	orr	r3, r3, r2, lsr #8	/* r3 = 5432 */
+	orr	r2, ip, r2, lsl #8	/* r2 = 3210 */
+#endif
+	str	r3, [r0, #0x02]
+	strh	r2, [r0]
+	RET
+	LMEMCPY_8_PAD
+
+/*
+ * 1100: dst is 8-bit aligned, src is 32-bit aligned
+ */
+	ldr	r3, [r1, #0x04]		/* BE:r3 = 4567  LE:r3 = 7654 */
+	ldr	r2, [r1]		/* BE:r2 = 0123  LE:r2 = 3210 */
+	mov	r1, r3, lsr #8		/* BE:r1 = .456  LE:r1 = .765 */
+	strh	r1, [r0, #0x05]
+#ifdef __ARMEB__
+	strb	r3, [r0, #0x07]
+	mov	r1, r2, lsr #24		/* r1 = ...0 */
+	strb	r1, [r0]
+	mov	r2, r2, lsl #8		/* r2 = 123. */
+	orr	r2, r2, r3, lsr #24	/* r2 = 1234 */
+	str	r2, [r0, #0x01]
+#else
+	strb	r2, [r0]
+	mov	r1, r3, lsr #24		/* r1 = ...7 */
+	strb	r1, [r0, #0x07]
+	mov	r2, r2, lsr #8		/* r2 = .321 */
+	orr	r2, r2, r3, lsl #24	/* r2 = 4321 */
+	str	r2, [r0, #0x01]
+#endif
+	RET
+	LMEMCPY_8_PAD
+
+/*
+ * 1101: dst is 8-bit aligned, src is 8-bit aligned
+ */
+	ldrb	r3, [r1]		/* r3 = ...0 */
+	ldrh	r2, [r1, #0x01]		/* BE:r2 = ..12  LE:r2 = ..21 */
+	ldr	ip, [r1, #0x03]		/* BE:ip = 3456  LE:ip = 6543 */
+	ldrb	r1, [r1, #0x07]		/* r1 = ...7 */
+	strb	r3, [r0]
+	mov	r3, ip, lsr #16		/* BE:r3 = ..34  LE:r3 = ..65 */
+#ifdef __ARMEB__
+	strh	ip, [r0, #0x05]
+	orr	r2, r3, r2, lsl #16	/* r2 = 1234 */
+#else
+	strh	r3, [r0, #0x05]
+	orr	r2, r2, ip, lsl #16	/* r2 = 4321 */
+#endif
+	str	r2, [r0, #0x01]
+	strb	r1, [r0, #0x07]
+	RET
+	LMEMCPY_8_PAD
+
+/*
+ * 1110: dst is 8-bit aligned, src is 16-bit aligned
+ */
+	ldrh	r2, [r1]		/* BE:r2 = ..01  LE:r2 = ..10 */
+	ldr	r3, [r1, #0x02]		/* BE:r3 = 2345  LE:r3 = 5432 */
+	ldrh	r1, [r1, #0x06]		/* BE:r1 = ..67  LE:r1 = ..76 */
+#ifdef __ARMEB__
+	mov	ip, r2, lsr #8		/* ip = ...0 */
+	strb	ip, [r0]
+	mov	ip, r2, lsl #24		/* ip = 1... */
+	orr	ip, ip, r3, lsr #8	/* ip = 1234 */
+	strb	r1, [r0, #0x07]
+	mov	r1, r1, lsr #8		/* r1 = ...6 */
+	orr	r1, r1, r3, lsl #8	/* r1 = 3456 */
+#else
+	strb	r2, [r0]
+	mov	ip, r2, lsr #8		/* ip = ...1 */
+	orr	ip, ip, r3, lsl #8	/* ip = 4321 */
+	mov	r2, r1, lsr #8		/* r2 = ...7 */
+	strb	r2, [r0, #0x07]
+	mov	r1, r1, lsl #8		/* r1 = .76. */
+	orr	r1, r1, r3, lsr #24	/* r1 = .765 */
+#endif
+	str	ip, [r0, #0x01]
+	strh	r1, [r0, #0x05]
+	RET
+	LMEMCPY_8_PAD
+
+/*
+ * 1111: dst is 8-bit aligned, src is 8-bit aligned
+ */
+	ldrb	r2, [r1]
+	ldr	ip, [r1, #0x01]
+	ldrh	r3, [r1, #0x05]
+	ldrb	r1, [r1, #0x07]
+	strb	r2, [r0]
+	str	ip, [r0, #0x01]
+	strh	r3, [r0, #0x05]
+	strb	r1, [r0, #0x07]
+	RET
+	LMEMCPY_8_PAD
+
+/******************************************************************************
+ * Special case for 12 byte copies
+ */
+#define	LMEMCPY_C_LOG2	7	/* 128 bytes */
+#define	LMEMCPY_C_PAD	.align LMEMCPY_C_LOG2
+	LMEMCPY_C_PAD
+.Lmemcpy_c:
+	and	r2, r1, #0x03
+	orr	r2, r2, r0, lsl #2
+	ands	r2, r2, #0x0f
+	sub	r3, pc, #0x14
+	addne	pc, r3, r2, lsl #LMEMCPY_C_LOG2
+
+/*
+ * 0000: dst is 32-bit aligned, src is 32-bit aligned
+ */
+	ldr	r2, [r1]
+	ldr	r3, [r1, #0x04]
+	ldr	r1, [r1, #0x08]
+	str	r2, [r0]
+	str	r3, [r0, #0x04]
+	str	r1, [r0, #0x08]
+	RET
+	LMEMCPY_C_PAD
+
+/*
+ * 0001: dst is 32-bit aligned, src is 8-bit aligned
+ */
+	ldrb	r2, [r1, #0xb]		/* r2 = ...B */
+	ldr	ip, [r1, #0x07]		/* BE:ip = 789A  LE:ip = A987 */
+	ldr	r3, [r1, #0x03]		/* BE:r3 = 3456  LE:r3 = 6543 */
+	ldr	r1, [r1, #-1]		/* BE:r1 = x012  LE:r1 = 210x */
+#ifdef __ARMEB__
+	orr	r2, r2, ip, lsl #8	/* r2 = 89AB */
+	str	r2, [r0, #0x08]
+	mov	r2, ip, lsr #24		/* r2 = ...7 */
+	orr	r2, r2, r3, lsl #8	/* r2 = 4567 */
+	mov	r1, r1, lsl #8		/* r1 = 012. */
+	orr	r1, r1, r3, lsr #24	/* r1 = 0123 */
+#else
+	mov	r2, r2, lsl #24		/* r2 = B... */
+	orr	r2, r2, ip, lsr #8	/* r2 = BA98 */
+	str	r2, [r0, #0x08]
+	mov	r2, ip, lsl #24		/* r2 = 7... */
+	orr	r2, r2, r3, lsr #8	/* r2 = 7654 */
+	mov	r1, r1, lsr #8		/* r1 = .210 */
+	orr	r1, r1, r3, lsl #24	/* r1 = 3210 */
+#endif
+	str	r2, [r0, #0x04]
+	str	r1, [r0]
+	RET
+	LMEMCPY_C_PAD
+
+/*
+ * 0010: dst is 32-bit aligned, src is 16-bit aligned
+ */
+	ldrh	r2, [r1]		/* BE:r2 = ..01  LE:r2 = ..10 */
+	ldr	r3, [r1, #0x02]		/* BE:r3 = 2345  LE:r3 = 5432 */
+	ldr	ip, [r1, #0x06]		/* BE:ip = 6789  LE:ip = 9876 */
+	ldrh	r1, [r1, #0x0a]		/* BE:r1 = ..AB  LE:r1 = ..BA */
+#ifdef __ARMEB__
+	mov	r2, r2, lsl #16		/* r2 = 01.. */
+	orr	r2, r2, r3, lsr #16	/* r2 = 0123 */
+	str	r2, [r0]
+	mov	r3, r3, lsl #16		/* r3 = 45.. */
+	orr	r3, r3, ip, lsr #16	/* r3 = 4567 */
+	orr	r1, r1, ip, lsl #16	/* r1 = 89AB */
+#else
+	orr	r2, r2, r3, lsl #16	/* r2 = 3210 */
+	str	r2, [r0]
+	mov	r3, r3, lsr #16		/* r3 = ..54 */
+	orr	r3, r3, ip, lsl #16	/* r3 = 7654 */
+	mov	r1, r1, lsl #16		/* r1 = BA.. */
+	orr	r1, r1, ip, lsr #16	/* r1 = BA98 */
+#endif
+	str	r3, [r0, #0x04]
+	str	r1, [r0, #0x08]
+	RET
+	LMEMCPY_C_PAD
+
+/*
+ * 0011: dst is 32-bit aligned, src is 8-bit aligned
+ */
+	ldrb	r2, [r1]		/* r2 = ...0 */
+	ldr	r3, [r1, #0x01]		/* BE:r3 = 1234  LE:r3 = 4321 */
+	ldr	ip, [r1, #0x05]		/* BE:ip = 5678  LE:ip = 8765 */
+	ldr	r1, [r1, #0x09]		/* BE:r1 = 9ABx  LE:r1 = xBA9 */
+#ifdef __ARMEB__
+	mov	r2, r2, lsl #24		/* r2 = 0... */
+	orr	r2, r2, r3, lsr #8	/* r2 = 0123 */
+	str	r2, [r0]
+	mov	r3, r3, lsl #24		/* r3 = 4... */
+	orr	r3, r3, ip, lsr #8	/* r3 = 4567 */
+	mov	r1, r1, lsr #8		/* r1 = .9AB */
+	orr	r1, r1, ip, lsl #24	/* r1 = 89AB */
+#else
+	orr	r2, r2, r3, lsl #8	/* r2 = 3210 */
+	str	r2, [r0]
+	mov	r3, r3, lsr #24		/* r3 = ...4 */
+	orr	r3, r3, ip, lsl #8	/* r3 = 7654 */
+	mov	r1, r1, lsl #8		/* r1 = BA9. */
+	orr	r1, r1, ip, lsr #24	/* r1 = BA98 */
+#endif
+	str	r3, [r0, #0x04]
+	str	r1, [r0, #0x08]
+	RET
+	LMEMCPY_C_PAD
+
+/*
+ * 0100: dst is 8-bit aligned (byte 1), src is 32-bit aligned
+ */
+	ldr	r2, [r1]		/* BE:r2 = 0123  LE:r2 = 3210 */
+	ldr	r3, [r1, #0x04]		/* BE:r3 = 4567  LE:r3 = 7654 */
+	ldr	ip, [r1, #0x08]		/* BE:ip = 89AB  LE:ip = BA98 */
+	mov	r1, r2, lsr #8		/* BE:r1 = .012  LE:r1 = .321 */
+	strh	r1, [r0, #0x01]
+#ifdef __ARMEB__
+	mov	r1, r2, lsr #24		/* r1 = ...0 */
+	strb	r1, [r0]
+	mov	r1, r2, lsl #24		/* r1 = 3... */
+	orr	r2, r1, r3, lsr #8	/* r1 = 3456 */
+	mov	r1, r3, lsl #24		/* r1 = 7... */
+	orr	r1, r1, ip, lsr #8	/* r1 = 789A */
+#else
+	strb	r2, [r0]
+	mov	r1, r2, lsr #24		/* r1 = ...3 */
+	orr	r2, r1, r3, lsl #8	/* r1 = 6543 */
+	mov	r1, r3, lsr #24		/* r1 = ...7 */
+	orr	r1, r1, ip, lsl #8	/* r1 = A987 */
+	mov	ip, ip, lsr #24		/* ip = ...B */
+#endif
+	str	r2, [r0, #0x03]
+	str	r1, [r0, #0x07]
+	strb	ip, [r0, #0x0b]
+	RET
+	LMEMCPY_C_PAD
+
+/*
+ * 0101: dst is 8-bit aligned (byte 1), src is 8-bit aligned (byte 1)
+ */
+	ldrb	r2, [r1]
+	ldrh	r3, [r1, #0x01]
+	ldr	ip, [r1, #0x03]
+	strb	r2, [r0]
+	ldr	r2, [r1, #0x07]
+	ldrb	r1, [r1, #0x0b]
+	strh	r3, [r0, #0x01]
+	str	ip, [r0, #0x03]
+	str	r2, [r0, #0x07]
+	strb	r1, [r0, #0x0b]
+	RET
+	LMEMCPY_C_PAD
+
+/*
+ * 0110: dst is 8-bit aligned (byte 1), src is 16-bit aligned
+ */
+	ldrh	r2, [r1]		/* BE:r2 = ..01  LE:r2 = ..10 */
+	ldr	r3, [r1, #0x02]		/* BE:r3 = 2345  LE:r3 = 5432 */
+	ldr	ip, [r1, #0x06]		/* BE:ip = 6789  LE:ip = 9876 */
+	ldrh	r1, [r1, #0x0a]		/* BE:r1 = ..AB  LE:r1 = ..BA */
+#ifdef __ARMEB__
+	mov	r2, r2, ror #8		/* r2 = 1..0 */
+	strb	r2, [r0]
+	mov	r2, r2, lsr #16		/* r2 = ..1. */
+	orr	r2, r2, r3, lsr #24	/* r2 = ..12 */
+	strh	r2, [r0, #0x01]
+	mov	r2, r3, lsl #8		/* r2 = 345. */
+	orr	r3, r2, ip, lsr #24	/* r3 = 3456 */
+	mov	r2, ip, lsl #8		/* r2 = 789. */
+	orr	r2, r2, r1, lsr #8	/* r2 = 789A */
+#else
+	strb	r2, [r0]
+	mov	r2, r2, lsr #8		/* r2 = ...1 */
+	orr	r2, r2, r3, lsl #8	/* r2 = 4321 */
+	strh	r2, [r0, #0x01]
+	mov	r2, r3, lsr #8		/* r2 = .543 */
+	orr	r3, r2, ip, lsl #24	/* r3 = 6543 */
+	mov	r2, ip, lsr #8		/* r2 = .987 */
+	orr	r2, r2, r1, lsl #24	/* r2 = A987 */
+	mov	r1, r1, lsr #8		/* r1 = ...B */
+#endif
+	str	r3, [r0, #0x03]
+	str	r2, [r0, #0x07]
+	strb	r1, [r0, #0x0b]
+	RET
+	LMEMCPY_C_PAD
+
+/*
+ * 0111: dst is 8-bit aligned (byte 1), src is 8-bit aligned (byte 3)
+ */
+	ldrb	r2, [r1]
+	ldr	r3, [r1, #0x01]		/* BE:r3 = 1234  LE:r3 = 4321 */
+	ldr	ip, [r1, #0x05]		/* BE:ip = 5678  LE:ip = 8765 */
+	ldr	r1, [r1, #0x09]		/* BE:r1 = 9ABx  LE:r1 = xBA9 */
+	strb	r2, [r0]
+#ifdef __ARMEB__
+	mov	r2, r3, lsr #16		/* r2 = ..12 */
+	strh	r2, [r0, #0x01]
+	mov	r3, r3, lsl #16		/* r3 = 34.. */
+	orr	r3, r3, ip, lsr #16	/* r3 = 3456 */
+	mov	ip, ip, lsl #16		/* ip = 78.. */
+	orr	ip, ip, r1, lsr #16	/* ip = 789A */
+	mov	r1, r1, lsr #8		/* r1 = .9AB */
+#else
+	strh	r3, [r0, #0x01]
+	mov	r3, r3, lsr #16		/* r3 = ..43 */
+	orr	r3, r3, ip, lsl #16	/* r3 = 6543 */
+	mov	ip, ip, lsr #16		/* ip = ..87 */
+	orr	ip, ip, r1, lsl #16	/* ip = A987 */
+	mov	r1, r1, lsr #16		/* r1 = ..xB */
+#endif
+	str	r3, [r0, #0x03]
+	str	ip, [r0, #0x07]
+	strb	r1, [r0, #0x0b]
+	RET
+	LMEMCPY_C_PAD
+
+/*
+ * 1000: dst is 16-bit aligned, src is 32-bit aligned
+ */
+	ldr	ip, [r1]		/* BE:ip = 0123  LE:ip = 3210 */
+	ldr	r3, [r1, #0x04]		/* BE:r3 = 4567  LE:r3 = 7654 */
+	ldr	r2, [r1, #0x08]		/* BE:r2 = 89AB  LE:r2 = BA98 */
+	mov	r1, ip, lsr #16		/* BE:r1 = ..01  LE:r1 = ..32 */
+#ifdef __ARMEB__
+	strh	r1, [r0]
+	mov	r1, ip, lsl #16		/* r1 = 23.. */
+	orr	r1, r1, r3, lsr #16	/* r1 = 2345 */
+	mov	r3, r3, lsl #16		/* r3 = 67.. */
+	orr	r3, r3, r2, lsr #16	/* r3 = 6789 */
+#else
+	strh	ip, [r0]
+	orr	r1, r1, r3, lsl #16	/* r1 = 5432 */
+	mov	r3, r3, lsr #16		/* r3 = ..76 */
+	orr	r3, r3, r2, lsl #16	/* r3 = 9876 */
+	mov	r2, r2, lsr #16		/* r2 = ..BA */
+#endif
+	str	r1, [r0, #0x02]
+	str	r3, [r0, #0x06]
+	strh	r2, [r0, #0x0a]
+	RET
+	LMEMCPY_C_PAD
+
+/*
+ * 1001: dst is 16-bit aligned, src is 8-bit aligned (byte 1)
+ */
+	ldr	r2, [r1, #-1]		/* BE:r2 = x012  LE:r2 = 210x */
+	ldr	r3, [r1, #0x03]		/* BE:r3 = 3456  LE:r3 = 6543 */
+	mov	ip, r2, lsr #8		/* BE:ip = .x01  LE:ip = .210 */
+	strh	ip, [r0]
+	ldr	ip, [r1, #0x07]		/* BE:ip = 789A  LE:ip = A987 */
+	ldrb	r1, [r1, #0x0b]		/* r1 = ...B */
+#ifdef __ARMEB__
+	mov	r2, r2, lsl #24		/* r2 = 2... */
+	orr	r2, r2, r3, lsr #8	/* r2 = 2345 */
+	mov	r3, r3, lsl #24		/* r3 = 6... */
+	orr	r3, r3, ip, lsr #8	/* r3 = 6789 */
+	orr	r1, r1, ip, lsl #8	/* r1 = 89AB */
+#else
+	mov	r2, r2, lsr #24		/* r2 = ...2 */
+	orr	r2, r2, r3, lsl #8	/* r2 = 5432 */
+	mov	r3, r3, lsr #24		/* r3 = ...6 */
+	orr	r3, r3, ip, lsl #8	/* r3 = 9876 */
+	mov	r1, r1, lsl #8		/* r1 = ..B. */
+	orr	r1, r1, ip, lsr #24	/* r1 = ..BA */
+#endif
+	str	r2, [r0, #0x02]
+	str	r3, [r0, #0x06]
+	strh	r1, [r0, #0x0a]
+	RET
+	LMEMCPY_C_PAD
+
+/*
+ * 1010: dst is 16-bit aligned, src is 16-bit aligned
+ */
+	ldrh	r2, [r1]
+	ldr	r3, [r1, #0x02]
+	ldr	ip, [r1, #0x06]
+	ldrh	r1, [r1, #0x0a]
+	strh	r2, [r0]
+	str	r3, [r0, #0x02]
+	str	ip, [r0, #0x06]
+	strh	r1, [r0, #0x0a]
+	RET
+	LMEMCPY_C_PAD
+
+/*
+ * 1011: dst is 16-bit aligned, src is 8-bit aligned (byte 3)
+ */
+	ldr	r2, [r1, #0x09]		/* BE:r2 = 9ABx  LE:r2 = xBA9 */
+	ldr	r3, [r1, #0x05]		/* BE:r3 = 5678  LE:r3 = 8765 */
+	mov	ip, r2, lsr #8		/* BE:ip = .9AB  LE:ip = .xBA */
+	strh	ip, [r0, #0x0a]
+	ldr	ip, [r1, #0x01]		/* BE:ip = 1234  LE:ip = 4321 */
+	ldrb	r1, [r1]		/* r1 = ...0 */
+#ifdef __ARMEB__
+	mov	r2, r2, lsr #24		/* r2 = ...9 */
+	orr	r2, r2, r3, lsl #8	/* r2 = 6789 */
+	mov	r3, r3, lsr #24		/* r3 = ...5 */
+	orr	r3, r3, ip, lsl #8	/* r3 = 2345 */
+	mov	r1, r1, lsl #8		/* r1 = ..0. */
+	orr	r1, r1, ip, lsr #24	/* r1 = ..01 */
+#else
+	mov	r2, r2, lsl #24		/* r2 = 9... */
+	orr	r2, r2, r3, lsr #8	/* r2 = 9876 */
+	mov	r3, r3, lsl #24		/* r3 = 5... */
+	orr	r3, r3, ip, lsr #8	/* r3 = 5432 */
+	orr	r1, r1, ip, lsl #8	/* r1 = 3210 */
+#endif
+	str	r2, [r0, #0x06]
+	str	r3, [r0, #0x02]
+	strh	r1, [r0]
+	RET
+	LMEMCPY_C_PAD
+
+/*
+ * 1100: dst is 8-bit aligned (byte 3), src is 32-bit aligned
+ */
+	ldr	r2, [r1]		/* BE:r2 = 0123  LE:r2 = 3210 */
+	ldr	ip, [r1, #0x04]		/* BE:ip = 4567  LE:ip = 7654 */
+	ldr	r1, [r1, #0x08]		/* BE:r1 = 89AB  LE:r1 = BA98 */
+#ifdef __ARMEB__
+	mov	r3, r2, lsr #24		/* r3 = ...0 */
+	strb	r3, [r0]
+	mov	r2, r2, lsl #8		/* r2 = 123. */
+	orr	r2, r2, ip, lsr #24	/* r2 = 1234 */
+	str	r2, [r0, #0x01]
+	mov	r2, ip, lsl #8		/* r2 = 567. */
+	orr	r2, r2, r1, lsr #24	/* r2 = 5678 */
+	str	r2, [r0, #0x05]
+	mov	r2, r1, lsr #8		/* r2 = ..9A */
+	strh	r2, [r0, #0x09]
+	strb	r1, [r0, #0x0b]
+#else
+	strb	r2, [r0]
+	mov	r3, r2, lsr #8		/* r3 = .321 */
+	orr	r3, r3, ip, lsl #24	/* r3 = 4321 */
+	str	r3, [r0, #0x01]
+	mov	r3, ip, lsr #8		/* r3 = .765 */
+	orr	r3, r3, r1, lsl #24	/* r3 = 8765 */
+	str	r3, [r0, #0x05]
+	mov	r1, r1, lsr #8		/* r1 = .BA9 */
+	strh	r1, [r0, #0x09]
+	mov	r1, r1, lsr #16		/* r1 = ...B */
+	strb	r1, [r0, #0x0b]
+#endif
+	RET
+	LMEMCPY_C_PAD
+
+/*
+ * 1101: dst is 8-bit aligned (byte 3), src is 8-bit aligned (byte 1)
+ */
+	ldrb	r2, [r1, #0x0b]		/* r2 = ...B */
+	ldr	r3, [r1, #0x07]		/* BE:r3 = 789A  LE:r3 = A987 */
+	ldr	ip, [r1, #0x03]		/* BE:ip = 3456  LE:ip = 6543 */
+	ldr	r1, [r1, #-1]		/* BE:r1 = x012  LE:r1 = 210x */
+	strb	r2, [r0, #0x0b]
+#ifdef __ARMEB__
+	strh	r3, [r0, #0x09]
+	mov	r3, r3, lsr #16		/* r3 = ..78 */
+	orr	r3, r3, ip, lsl #16	/* r3 = 5678 */
+	mov	ip, ip, lsr #16		/* ip = ..34 */
+	orr	ip, ip, r1, lsl #16	/* ip = 1234 */
+	mov	r1, r1, lsr #16		/* r1 = ..x0 */
+#else
+	mov	r2, r3, lsr #16		/* r2 = ..A9 */
+	strh	r2, [r0, #0x09]
+	mov	r3, r3, lsl #16		/* r3 = 87.. */
+	orr	r3, r3, ip, lsr #16	/* r3 = 8765 */
+	mov	ip, ip, lsl #16		/* ip = 43.. */
+	orr	ip, ip, r1, lsr #16	/* ip = 4321 */
+	mov	r1, r1, lsr #8		/* r1 = .210 */
+#endif
+	str	r3, [r0, #0x05]
+	str	ip, [r0, #0x01]
+	strb	r1, [r0]
+	RET
+	LMEMCPY_C_PAD
+
+/*
+ * 1110: dst is 8-bit aligned (byte 3), src is 16-bit aligned
+ */
+#ifdef __ARMEB__
+	ldrh	r2, [r1, #0x0a]		/* r2 = ..AB */
+	ldr	ip, [r1, #0x06]		/* ip = 6789 */
+	ldr	r3, [r1, #0x02]		/* r3 = 2345 */
+	ldrh	r1, [r1]		/* r1 = ..01 */
+	strb	r2, [r0, #0x0b]
+	mov	r2, r2, lsr #8		/* r2 = ...A */
+	orr	r2, r2, ip, lsl #8	/* r2 = 789A */
+	mov	ip, ip, lsr #8		/* ip = .678 */
+	orr	ip, ip, r3, lsl #24	/* ip = 5678 */
+	mov	r3, r3, lsr #8		/* r3 = .234 */
+	orr	r3, r3, r1, lsl #24	/* r3 = 1234 */
+	mov	r1, r1, lsr #8		/* r1 = ...0 */
+	strb	r1, [r0]
+	str	r3, [r0, #0x01]
+	str	ip, [r0, #0x05]
+	strh	r2, [r0, #0x09]
+#else
+	ldrh	r2, [r1]		/* r2 = ..10 */
+	ldr	r3, [r1, #0x02]		/* r3 = 5432 */
+	ldr	ip, [r1, #0x06]		/* ip = 9876 */
+	ldrh	r1, [r1, #0x0a]		/* r1 = ..BA */
+	strb	r2, [r0]
+	mov	r2, r2, lsr #8		/* r2 = ...1 */
+	orr	r2, r2, r3, lsl #8	/* r2 = 4321 */
+	mov	r3, r3, lsr #24		/* r3 = ...5 */
+	orr	r3, r3, ip, lsl #8	/* r3 = 8765 */
+	mov	ip, ip, lsr #24		/* ip = ...9 */
+	orr	ip, ip, r1, lsl #8	/* ip = .BA9 */
+	mov	r1, r1, lsr #8		/* r1 = ...B */
+	str	r2, [r0, #0x01]
+	str	r3, [r0, #0x05]
+	strh	ip, [r0, #0x09]
+	strb	r1, [r0, #0x0b]
+#endif
+	RET
+	LMEMCPY_C_PAD
+
+/*
+ * 1111: dst is 8-bit aligned (byte 3), src is 8-bit aligned (byte 3)
+ */
+	ldrb	r2, [r1]
+	ldr	r3, [r1, #0x01]
+	ldr	ip, [r1, #0x05]
+	strb	r2, [r0]
+	ldrh	r2, [r1, #0x09]
+	ldrb	r1, [r1, #0x0b]
+	str	r3, [r0, #0x01]
+	str	ip, [r0, #0x05]
+	strh	r2, [r0, #0x09]
+	strb	r1, [r0, #0x0b]
+	RET
+END(memcpy)
+#endif /* _ARM_ARCH_5E */
+
+#ifdef GPROF
+
+ENTRY(user)
+	nop
+END(user)
+ENTRY(btrap)
+	nop
+END(btrap)
+ENTRY(etrap)
+	nop
+END(etrap)
+ENTRY(bintr)
+	nop
+END(bintr)
+ENTRY(eintr)
+	nop
+END(eintr)
+#endif


Property changes on: trunk/sys/arm/arm/support.S
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/swtch.S
===================================================================
--- trunk/sys/arm/arm/swtch.S	                        (rev 0)
+++ trunk/sys/arm/arm/swtch.S	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,443 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: cpuswitch.S,v 1.41 2003/11/15 08:44:18 scw Exp $	*/
+
+/*-
+ * Copyright 2003 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Steve C. Woodford for Wasabi Systems, Inc.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed for the NetBSD Project by
+ *      Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
+ * 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.
+ */
+/*-
+ * Copyright (c) 1994-1998 Mark Brinicombe.
+ * Copyright (c) 1994 Brini.
+ * All rights reserved.
+ *
+ * This code is derived from software written for Brini by Mark Brinicombe
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Brini.
+ * 4. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BRINI ``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 BRINI 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.
+ *
+ * RiscBSD kernel project
+ *
+ * cpuswitch.S
+ *
+ * cpu switching functions
+ *
+ * Created      : 15/10/94
+ *
+ */
+
+#include "assym.s"
+#include "opt_sched.h"
+
+#include <machine/asm.h>
+#include <machine/asmacros.h>
+#include <machine/armreg.h>
+#include <machine/vfp.h>
+
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/swtch.S 283339 2015-05-23 23:27:00Z ian $");
+
+#define DOMAIN_CLIENT	0x01
+
+#if defined(_ARM_ARCH_6) && defined(SMP)
+#define GET_PCPU(tmp, tmp2) \
+	mrc 	p15, 0, tmp, c0, c0, 5;	\
+	and	tmp, tmp, #0xf;		\
+	ldr 	tmp2, .Lcurpcpu+4;	\
+	mul 	tmp, tmp, tmp2;		\
+	ldr	tmp2, .Lcurpcpu;	\
+	add	tmp, tmp, tmp2;
+#else
+
+#define GET_PCPU(tmp, tmp2) \
+	ldr	tmp, .Lcurpcpu
+#endif
+
+#ifdef VFP
+	.fpu vfp	/* allow VFP instructions */
+#endif
+
+.Lcurpcpu:
+        .word   _C_LABEL(__pcpu)
+	.word	PCPU_SIZE
+.Lcpufuncs:	
+	.word	_C_LABEL(cpufuncs)
+.Lblocked_lock:
+	.word	_C_LABEL(blocked_lock)
+
+/*
+ * cpu_throw(oldtd, newtd)
+ *
+ * Remove current thread state, then select the next thread to run
+ * and load its state.
+ * r0 = oldtd
+ * r1 = newtd
+ */
+ENTRY(cpu_throw)
+	mov	r5, r1
+
+	/*
+	 * r0 = oldtd
+	 * r5 = newtd
+	 */
+
+#ifdef VFP				/* This thread is dying, disable */
+	bl	_C_LABEL(vfp_discard)	/* VFP without preserving state. */
+#endif
+
+	GET_PCPU(r7, r9)
+	ldr	r7, [r5, #(TD_PCB)]		/* r7 = new thread's PCB */
+  
+	/* Switch to lwp0 context */
+
+	ldr	r9, .Lcpufuncs
+#if !defined(CPU_ARM11) && !defined(CPU_CORTEXA) && !defined(CPU_MV_PJ4B) && !defined(CPU_KRAIT)
+	mov	lr, pc
+	ldr	pc, [r9, #CF_IDCACHE_WBINV_ALL]
+#endif
+	ldr	r0, [r7, #(PCB_PL1VEC)]
+	ldr	r1, [r7, #(PCB_DACR)]
+	/*
+	 * r0 = Pointer to L1 slot for vector_page (or NULL)
+	 * r1 = lwp0's DACR
+	 * r5 = lwp0
+	 * r7 = lwp0's PCB
+	 * r9 = cpufuncs
+	 */
+
+	/*
+	 * Ensure the vector table is accessible by fixing up lwp0's L1
+	 */
+	cmp	r0, #0			/* No need to fixup vector table? */
+	ldrne	r3, [r0]		/* But if yes, fetch current value */
+	ldrne	r2, [r7, #(PCB_L1VEC)]	/* Fetch new vector_page value */
+	mcr	p15, 0, r1, c3, c0, 0	/* Update DACR for lwp0's context */
+	cmpne	r3, r2			/* Stuffing the same value? */
+	strne	r2, [r0]		/* Store if not. */
+
+#ifdef PMAP_INCLUDE_PTE_SYNC
+	/*
+	 * Need to sync the cache to make sure that last store is
+	 * visible to the MMU.
+	 */
+	movne	r1, #4
+	movne	lr, pc
+	ldrne	pc, [r9, #CF_DCACHE_WB_RANGE]
+#endif /* PMAP_INCLUDE_PTE_SYNC */
+
+	/*
+	 * Note: We don't do the same optimisation as cpu_switch() with
+	 * respect to avoiding flushing the TLB if we're switching to
+	 * the same L1 since this process' VM space may be about to go
+	 * away, so we don't want *any* turds left in the TLB.
+	 */
+
+	/* Switch the memory to the new process */
+	ldr	r0, [r7, #(PCB_PAGEDIR)]
+	mov	lr, pc
+	ldr	pc, [r9, #CF_CONTEXT_SWITCH]
+
+	GET_PCPU(r6, r4)
+	/* Hook in a new pcb */
+	str	r7, [r6, #PC_CURPCB]
+	/* We have a new curthread now so make a note it */
+	str	r5, [r6, #PC_CURTHREAD]
+#ifndef ARM_TP_ADDRESS
+	mcr	p15, 0, r5, c13, c0, 4
+#endif
+	/* Set the new tp */
+	ldr	r6, [r5, #(TD_MD + MD_TP)]
+#ifdef ARM_TP_ADDRESS
+	ldr	r4, =ARM_TP_ADDRESS
+	str	r6, [r4]
+	ldr	r6, [r5, #(TD_MD + MD_RAS_START)]
+	str	r6, [r4, #4] /* ARM_RAS_START */
+	ldr	r6, [r5, #(TD_MD + MD_RAS_END)]
+	str	r6, [r4, #8] /* ARM_RAS_END */
+#else
+	mcr p15, 0, r6, c13, c0, 3
+#endif
+	/* Restore all the saved registers and exit */
+	add	r3, r7, #PCB_R4
+	ldmia	r3, {r4-r12, sp, pc}
+END(cpu_throw)
+
+/*
+ * cpu_switch(oldtd, newtd, lock)
+ *
+ * Save the current thread state, then select the next thread to run
+ * and load its state.
+ * r0 = oldtd
+ * r1 = newtd
+ * r2 = lock (new lock for old thread)
+ */
+ENTRY(cpu_switch)
+	/* Interrupts are disabled. */
+	/* Save all the registers in the old thread's pcb. */
+	ldr	r3, [r0, #(TD_PCB)]
+
+	/* Restore all the saved registers and exit */
+	add	r3, #(PCB_R4)
+	stmia	r3, {r4-r12, sp, lr, pc}
+
+	mov	r6, r2 /* Save the mutex */
+
+	/* rem: r0 = old lwp */
+	/* rem: interrupts are disabled */
+
+	/* Process is now on a processor. */
+	/* We have a new curthread now so make a note it */
+	GET_PCPU(r7, r2)
+	str	r1, [r7, #PC_CURTHREAD]
+#ifndef ARM_TP_ADDRESS
+	mcr	p15, 0, r1, c13, c0, 4
+#endif
+
+	/* Hook in a new pcb */
+	ldr	r2, [r1, #TD_PCB]
+	str	r2, [r7, #PC_CURPCB]
+
+	/* Stage two : Save old context */
+
+	/* Get the user structure for the old thread. */
+	ldr	r2, [r0, #(TD_PCB)]
+	mov	r4, r0 /* Save the old thread. */
+
+#ifdef ARM_TP_ADDRESS
+	/* Store the old tp; userland can change it on armv4. */
+	ldr	r3, =ARM_TP_ADDRESS
+	ldr	r9, [r3]
+	str	r9, [r0, #(TD_MD + MD_TP)]
+	ldr	r9, [r3, #4]
+	str	r9, [r0, #(TD_MD + MD_RAS_START)]
+	ldr	r9, [r3, #8]
+	str	r9, [r0, #(TD_MD + MD_RAS_END)]
+
+	/* Set the new tp */
+	ldr	r9, [r1, #(TD_MD + MD_TP)]
+	str	r9, [r3]
+	ldr	r9, [r1, #(TD_MD + MD_RAS_START)]
+	str	r9, [r3, #4]
+	ldr	r9, [r1, #(TD_MD + MD_RAS_END)]
+	str	r9, [r3, #8]
+#else
+	/* 
+	 * Set new tp.  No need to store the old one first, userland can't 
+	 * change it directly on armv6.
+	 */
+	ldr	r9, [r1, #(TD_MD + MD_TP)]
+	mcr p15, 0, r9, c13, c0, 3
+#endif
+	
+	/* Get the user structure for the new process in r9 */
+	ldr	r9, [r1, #(TD_PCB)]
+
+	/* rem: r2 = old PCB */
+	/* rem: r9 = new PCB */
+	/* rem: interrupts are enabled */
+
+#ifdef VFP
+	fmrx	r0, fpexc		/* If the VFP is enabled */
+	tst	r0, #(VFPEXC_EN)	/* the current thread has */
+	movne	r1, #1			/* used it, so go save */
+	addne	r0, r2, #(PCB_VFPSTATE)	/* the state into the PCB */
+	blne	_C_LABEL(vfp_store)	/* and disable the VFP. */
+#endif
+
+	/* r0-r3 now free! */
+
+	/* Third phase : restore saved context */
+
+	/* rem: r2 = old PCB */
+	/* rem: r9 = new PCB */
+
+	ldr	r5, [r9, #(PCB_DACR)]		/* r5 = new DACR */
+	mov	r2, #DOMAIN_CLIENT
+	cmp     r5, r2, lsl #(PMAP_DOMAIN_KERNEL * 2) /* Sw to kernel thread? */
+	beq     .Lcs_context_switched        /* Yup. Don't flush cache */
+	mrc	p15, 0, r0, c3, c0, 0		/* r0 = old DACR */
+	/*
+	 * Get the new L1 table pointer into r11.  If we're switching to
+	 * an LWP with the same address space as the outgoing one, we can
+	 * skip the cache purge and the TTB load.
+	 *
+	 * To avoid data dep stalls that would happen anyway, we try
+	 * and get some useful work done in the mean time.
+	 */
+	mrc	p15, 0, r10, c2, c0, 0		/* r10 = old L1 */
+	ldr	r11, [r9, #(PCB_PAGEDIR)]	/* r11 = new L1 */
+
+	teq	r10, r11			/* Same L1? */
+	cmpeq	r0, r5				/* Same DACR? */
+	beq	.Lcs_context_switched		/* yes! */
+
+#if !defined(CPU_ARM11) && !defined(CPU_CORTEXA) && !defined(CPU_MV_PJ4B) && !defined(CPU_KRAIT)
+	/*
+	 * Definately need to flush the cache.
+	 */
+
+	ldr	r1, .Lcpufuncs
+	mov	lr, pc
+	ldr	pc, [r1, #CF_IDCACHE_WBINV_ALL]
+#endif
+.Lcs_cache_purge_skipped:
+	/* rem: r6 = lock */
+	/* rem: r9 = new PCB */
+	/* rem: r10 = old L1 */
+	/* rem: r11 = new L1 */
+
+	mov	r2, #0x00000000
+	ldr	r7, [r9, #(PCB_PL1VEC)]
+
+	/*
+	 * Ensure the vector table is accessible by fixing up the L1
+	 */
+	cmp	r7, #0			/* No need to fixup vector table? */
+	ldrne	r2, [r7]		/* But if yes, fetch current value */
+	ldrne	r0, [r9, #(PCB_L1VEC)]	/* Fetch new vector_page value */
+	mcr	p15, 0, r5, c3, c0, 0	/* Update DACR for new context */
+	cmpne	r2, r0			/* Stuffing the same value? */
+#ifndef PMAP_INCLUDE_PTE_SYNC
+	strne	r0, [r7]		/* Nope, update it */
+#else
+	beq	.Lcs_same_vector
+	str	r0, [r7]		/* Otherwise, update it */
+
+	/*
+	 * Need to sync the cache to make sure that last store is
+	 * visible to the MMU.
+	 */
+	ldr	r2, .Lcpufuncs
+	mov	r0, r7
+	mov	r1, #4
+	mov	lr, pc
+	ldr	pc, [r2, #CF_DCACHE_WB_RANGE]
+
+.Lcs_same_vector:
+#endif /* PMAP_INCLUDE_PTE_SYNC */
+
+	cmp	r10, r11		/* Switching to the same L1? */
+	ldr	r10, .Lcpufuncs
+	beq	.Lcs_same_l1		/* Yup. */
+	/*
+	 * Do a full context switch, including full TLB flush.
+	 */
+	mov	r0, r11
+	mov	lr, pc
+	ldr	pc, [r10, #CF_CONTEXT_SWITCH]
+
+	b	.Lcs_context_switched
+
+	/*
+	 * We're switching to a different process in the same L1.
+	 * In this situation, we only need to flush the TLB for the
+	 * vector_page mapping, and even then only if r7 is non-NULL.
+	 */
+.Lcs_same_l1:
+	cmp	r7, #0
+	movne	r0, #0			/* We *know* vector_page's VA is 0x0 */
+	movne	lr, pc
+	ldrne	pc, [r10, #CF_TLB_FLUSHID_SE]
+
+.Lcs_context_switched:
+
+	/* Release the old thread */
+	str	r6, [r4, #TD_LOCK]
+#if defined(SCHED_ULE) && defined(SMP)
+	ldr	r6, .Lblocked_lock
+	GET_CURTHREAD_PTR(r3)
+1:
+	ldr	r4, [r3, #TD_LOCK]
+	cmp	r4, r6
+	beq	1b
+#endif
+	
+	/* XXXSCW: Safe to re-enable FIQs here */
+
+	/* rem: r9 = new PCB */
+
+	/* Restore all the saved registers and exit */
+	add	r3, r9, #PCB_R4
+	ldmia	r3, {r4-r12, sp, pc}
+END(cpu_switch)
+
+ENTRY(savectx)
+	stmfd	sp!, {lr}
+	sub	sp, sp, #4
+	
+	/* Store all the registers in the thread's pcb */
+	add	r3, r0, #(PCB_R4)
+	stmia	r3, {r4-r12, sp, lr, pc}
+#ifdef VFP
+	fmrx	r2, fpexc		/* If the VFP is enabled */
+	tst	r2, #(VFPEXC_EN)	/* the current thread has */
+	movne	r1, #1			/* used it, so go save */
+	addne	r0, r0, #(PCB_VFPSTATE)	/* the state into the PCB */
+	blne	_C_LABEL(vfp_store)	/* and disable the VFP. */
+#endif
+	add	sp, sp, #4;
+	ldmfd	sp!, {pc}
+END(savectx)
+
+ENTRY(fork_trampoline)
+	STOP_UNWINDING	/* EABI: Don't unwind beyond the thread enty point. */
+	mov	fp, #0	/* OABI: Stack traceback via fp stops here. */
+	mov	r2, sp
+	mov	r1, r5
+	mov	r0, r4
+	ldr	lr, =swi_exit		/* Go finish forking, then return */
+	b	_C_LABEL(fork_exit)	/* to userland via swi_exit code. */
+END(fork_trampoline)
+


Property changes on: trunk/sys/arm/arm/swtch.S
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/sys_machdep.c
===================================================================
--- trunk/sys/arm/arm/sys_machdep.c	                        (rev 0)
+++ trunk/sys/arm/arm/sys_machdep.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,158 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ *	from: @(#)sys_machdep.c	5.5 (Berkeley) 1/19/91
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/sys_machdep.c 283339 2015-05-23 23:27:00Z ian $");
+
+#include "opt_capsicum.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/capsicum.h>
+#include <sys/proc.h>
+#include <sys/sysproto.h>
+#include <sys/syscall.h>
+#include <sys/sysent.h>
+
+#include <machine/sysarch.h>
+
+#ifndef _SYS_SYSPROTO_H_
+struct sysarch_args {
+	int op;
+	char *parms;
+};
+#endif
+
+/* Prototypes */
+static int arm32_sync_icache (struct thread *, void *);
+static int arm32_drain_writebuf(struct thread *, void *);
+
+static int
+arm32_sync_icache(struct thread *td, void *args)
+{
+	struct arm_sync_icache_args ua;
+	int error;
+
+	if ((error = copyin(args, &ua, sizeof(ua))) != 0)
+		return (error);
+
+	cpu_icache_sync_range(ua.addr, ua.len);
+
+	td->td_retval[0] = 0;
+	return (0);
+}
+
+static int
+arm32_drain_writebuf(struct thread *td, void *args)
+{
+	/* No args. */
+
+	td->td_retval[0] = 0;
+	cpu_drain_writebuf();
+	return (0);
+}
+
+static int
+arm32_set_tp(struct thread *td, void *args)
+{
+
+	td->td_md.md_tp = (register_t)args;
+#ifndef ARM_TP_ADDRESS
+	set_tls(args);
+#else
+	*(register_t *)ARM_TP_ADDRESS = (register_t)args;
+#endif
+	return (0);
+}
+
+static int
+arm32_get_tp(struct thread *td, void *args)
+{
+
+#ifndef ARM_TP_ADDRESS
+	td->td_retval[0] = td->td_md.md_tp;
+#else
+	td->td_retval[0] = *(register_t *)ARM_TP_ADDRESS;
+#endif
+	return (0);
+}
+
+int
+sysarch(td, uap)
+	struct thread *td;
+	register struct sysarch_args *uap;
+{
+	int error;
+
+#ifdef CAPABILITY_MODE
+	/*
+	 * When adding new operations, add a new case statement here to
+	 * explicitly indicate whether or not the operation is safe to
+	 * perform in capability mode.
+	 */
+	if (IN_CAPABILITY_MODE(td)) {
+		switch (uap->op) {
+		case ARM_SYNC_ICACHE:
+		case ARM_DRAIN_WRITEBUF:
+		case ARM_SET_TP:
+		case ARM_GET_TP:
+			break;
+
+		default:
+#ifdef KTRACE
+			if (KTRPOINT(td, KTR_CAPFAIL))
+				ktrcapfail(CAPFAIL_SYSCALL, NULL, NULL);
+#endif
+			return (ECAPMODE);
+		}
+	}
+#endif
+
+	switch (uap->op) {
+	case ARM_SYNC_ICACHE:
+		error = arm32_sync_icache(td, uap->parms);
+		break;
+	case ARM_DRAIN_WRITEBUF:
+		error = arm32_drain_writebuf(td, uap->parms);
+		break;
+	case ARM_SET_TP:
+		error = arm32_set_tp(td, uap->parms);
+		break;
+	case ARM_GET_TP:
+		error = arm32_get_tp(td, uap->parms);
+		break;
+	default:
+		error = EINVAL;
+		break;
+	}
+	return (error);
+}


Property changes on: trunk/sys/arm/arm/sys_machdep.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/syscall.c
===================================================================
--- trunk/sys/arm/arm/syscall.c	                        (rev 0)
+++ trunk/sys/arm/arm/syscall.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,198 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: fault.c,v 1.45 2003/11/20 14:44:36 scw Exp $	*/
+
+/*-
+ * Copyright 2004 Olivier Houchard
+ * Copyright 2003 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Steve C. Woodford for Wasabi Systems, Inc.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed for the NetBSD Project by
+ *      Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
+ * 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.
+ */
+/*-
+ * Copyright (c) 1994-1997 Mark Brinicombe.
+ * Copyright (c) 1994 Brini.
+ * All rights reserved.
+ *
+ * This code is derived from software written for Brini by Mark Brinicombe
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Brini.
+ * 4. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BRINI ``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 BRINI 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.
+ *
+ * RiscBSD kernel project
+ *
+ * fault.c
+ *
+ * Fault handlers
+ *
+ * Created      : 28/11/94
+ */
+
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/syscall.c 278656 2015-02-13 02:02:12Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/proc.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/syscall.h>
+#include <sys/sysent.h>
+#include <sys/signalvar.h>
+#include <sys/ptrace.h>
+#include <sys/pioctl.h>
+
+#include <machine/frame.h>
+
+void swi_handler(struct trapframe *);
+
+static __inline void
+call_trapsignal(struct thread *td, int sig, u_long code)
+{
+	ksiginfo_t ksi;
+
+	ksiginfo_init_trap(&ksi);
+	ksi.ksi_signo = sig;
+	ksi.ksi_code = (int)code;
+	trapsignal(td, &ksi);
+}
+
+int
+cpu_fetch_syscall_args(struct thread *td, struct syscall_args *sa)
+{
+	struct proc *p;
+	register_t *ap;
+	int error;
+
+	sa->code = td->td_frame->tf_r7;
+	ap = &td->td_frame->tf_r0;
+	if (sa->code == SYS_syscall) {
+		sa->code = *ap++;
+		sa->nap--;
+	} else if (sa->code == SYS___syscall) {
+		sa->code = ap[_QUAD_LOWWORD];
+		sa->nap -= 2;
+		ap += 2;
+	}
+	p = td->td_proc;
+	if (p->p_sysent->sv_mask)
+		sa->code &= p->p_sysent->sv_mask;
+	if (sa->code >= p->p_sysent->sv_size)
+		sa->callp = &p->p_sysent->sv_table[0];
+	else
+		sa->callp = &p->p_sysent->sv_table[sa->code];
+	sa->narg = sa->callp->sy_narg;
+	error = 0;
+	memcpy(sa->args, ap, sa->nap * sizeof(register_t));
+	if (sa->narg > sa->nap) {
+		error = copyin((void *)td->td_frame->tf_usr_sp, sa->args +
+		    sa->nap, (sa->narg - sa->nap) * sizeof(register_t));
+	}
+	if (error == 0) {
+		td->td_retval[0] = 0;
+		td->td_retval[1] = 0;
+	}
+	return (error);
+}
+
+#include "../../kern/subr_syscall.c"
+
+static void
+syscall(struct thread *td, struct trapframe *frame)
+{
+	struct syscall_args sa;
+	int error;
+
+	sa.nap = 4;
+
+	error = syscallenter(td, &sa);
+	KASSERT(error != 0 || td->td_ar == NULL,
+	    ("returning from syscall with td_ar set!"));
+	syscallret(td, error, &sa);
+}
+
+void
+swi_handler(struct trapframe *frame)
+{
+	struct thread *td = curthread;
+
+	td->td_frame = frame;
+
+	td->td_pticks = 0;
+	/*
+	 * Make sure the program counter is correctly aligned so we
+	 * don't take an alignment fault trying to read the opcode.
+	 * XXX: Fix for Thumb mode
+	 */
+	if (__predict_false(((frame->tf_pc - INSN_SIZE) & 3) != 0)) {
+		call_trapsignal(td, SIGILL, 0);
+		userret(td, frame);
+		return;
+	}
+	/*
+	 * Enable interrupts if they were enabled before the exception.
+	 * Since all syscalls *should* come from user mode it will always
+	 * be safe to enable them, but check anyway.
+	 */
+	if (td->td_md.md_spinlock_count == 0) {
+		if (__predict_true(frame->tf_spsr & PSR_I) == 0)
+			enable_interrupts(PSR_I);
+		if (__predict_true(frame->tf_spsr & PSR_F) == 0)
+			enable_interrupts(PSR_F);
+	}
+
+	syscall(td, frame);
+}


Property changes on: trunk/sys/arm/arm/syscall.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/trap-v6.c
===================================================================
--- trunk/sys/arm/arm/trap-v6.c	                        (rev 0)
+++ trunk/sys/arm/arm/trap-v6.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,664 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright 2014 Olivier Houchard <cognet at FreeBSD.org>
+ * Copyright 2014 Svatopluk Kraus <onwahe at gmail.com>
+ * Copyright 2014 Michal Meloun <meloun at miracle.cz>
+ * Copyright 2014 Andrew Turner <andrew at FreeBSD.org>
+ * 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_ktrace.h"
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/trap-v6.c 278731 2015-02-13 23:32:03Z ian $");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/signalvar.h>
+#include <sys/ktr.h>
+#ifdef KTRACE
+#include <sys/uio.h>
+#include <sys/ktrace.h>
+#endif
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/vm_kern.h>
+#include <vm/vm_map.h>
+#include <vm/vm_extern.h>
+#include <vm/vm_param.h>
+
+#include <machine/cpu.h>
+#include <machine/cpu-v6.h>
+#include <machine/frame.h>
+#include <machine/machdep.h>
+#include <machine/pcb.h>
+#include <machine/vmparam.h>
+
+#ifdef KDB
+#include <sys/kdb.h>
+#include <machine/db_machdep.h>
+#endif
+
+extern char fusubailout[];
+
+#ifdef DEBUG
+int last_fault_code;	/* For the benefit of pmap_fault_fixup() */
+#endif
+
+struct ksig {
+	int sig;
+	u_long code;
+	vm_offset_t	addr;
+};
+
+typedef int abort_func_t(struct trapframe *, u_int, u_int, u_int, u_int,
+    struct thread *, struct ksig *);
+
+static abort_func_t abort_fatal;
+static abort_func_t abort_align;
+static abort_func_t abort_icache;
+
+struct abort {
+	abort_func_t	*func;
+	const char	*desc;
+};
+
+/*
+ * How are the aborts handled?
+ *
+ * Undefined Code:
+ *  - Always fatal as we do not know what does it mean.
+ * Imprecise External Abort:
+ *  - Always fatal, but can be handled somehow in the future.
+ *    Now, due to PCIe buggy harware, ignored.
+ * Precise External Abort:
+ *  - Always fatal, but who knows in the future???
+ * Debug Event:
+ *  - Special handling.
+ * External Translation Abort (L1 & L2)
+ *  - Always fatal as something is screwed up in page tables or harware.
+ * Domain Fault (L1 & L2):
+ *  - Always fatal as we do not play game with domains.
+ * Alignment Fault:
+ *  - Everything should be aligned in kernel including user to kernel and
+ *    vice versa data copying, so we ignore pcb_onfault, and it's always fatal.
+ *    We generate signal in case of abort from user mode.
+ * Instruction cache maintenance:
+ *  - According to manual, this is translation fault during cache maintenance
+ *    operation. So, it could be really complex in SMP case and fuzzy too
+ *    for cache operations working on virtual addresses. For now, we will
+ *    consider this abort as fatal. In fact, no cache maintenance on
+ *    not mapped virtual addresses should be called. As cache maintenance
+ *    operation (except DMB, DSB, and Flush Prefetch Buffer) are priviledged,
+ *    the abort is fatal for user mode as well for now. (This is good place to
+ *    note that cache maintenance on virtual address fill TLB.)
+ * Acces Bit (L1 & L2):
+ *  - Fast hardware emulation for kernel and user mode.
+ * Translation Fault (L1 & L2):
+ *  - Standard fault mechanism is held including vm_fault().
+ * Permission Fault (L1 & L2):
+ *  - Fast harware emulation of modify bits and in other cases, standard
+ *    fault mechanism is held including vm_fault().
+ */
+
+static const struct abort aborts[] = {
+	{abort_fatal,	"Undefined Code (0x000)"},
+	{abort_align,	"Alignment Fault"},
+	{abort_fatal,	"Debug Event"},
+	{NULL,		"Access Bit (L1)"},
+	{abort_icache,	"Instruction cache maintenance"},
+	{NULL,		"Translation Fault (L1)"},
+	{NULL,		"Access Bit (L2)"},
+	{NULL,		"Translation Fault (L2)"},
+
+	{abort_fatal,	"External Abort"},
+	{abort_fatal,	"Domain Fault (L1)"},
+	{abort_fatal,	"Undefined Code (0x00A)"},
+	{abort_fatal,	"Domain Fault (L2)"},
+	{abort_fatal,	"External Translation Abort (L1)"},
+	{NULL,		"Permission Fault (L1)"},
+	{abort_fatal,	"External Translation Abort (L2)"},
+	{NULL,		"Permission Fault (L2)"},
+
+	{abort_fatal,	"TLB Conflict Abort"},
+	{abort_fatal,	"Undefined Code (0x401)"},
+	{abort_fatal,	"Undefined Code (0x402)"},
+	{abort_fatal,	"Undefined Code (0x403)"},
+	{abort_fatal,	"Undefined Code (0x404)"},
+	{abort_fatal,	"Undefined Code (0x405)"},
+	{abort_fatal,	"Asynchronous External Abort"},
+	{abort_fatal,	"Undefined Code (0x407)"},
+
+	{abort_fatal,	"Asynchronous Parity Error on Memory Access"},
+	{abort_fatal,	"Parity Error on Memory Access"},
+	{abort_fatal,	"Undefined Code (0x40A)"},
+	{abort_fatal,	"Undefined Code (0x40B)"},
+	{abort_fatal,	"Parity Error on Translation (L1)"},
+	{abort_fatal,	"Undefined Code (0x40D)"},
+	{abort_fatal,	"Parity Error on Translation (L2)"},
+	{abort_fatal,	"Undefined Code (0x40F)"}
+};
+
+
+static __inline void
+call_trapsignal(struct thread *td, int sig, int code, vm_offset_t addr)
+{
+	ksiginfo_t ksi;
+
+	CTR4(KTR_TRAP, "%s: addr: %#x, sig: %d, code: %d",
+	   __func__, addr, sig, code);
+
+	/*
+	 * TODO: some info would be nice to know
+	 * if we are serving data or prefetch abort.
+	 */
+
+	ksiginfo_init_trap(&ksi);
+	ksi.ksi_signo = sig;
+	ksi.ksi_code = code;
+	ksi.ksi_addr = (void *)addr;
+	trapsignal(td, &ksi);
+}
+
+/*
+ * abort_imprecise() handles the following abort:
+ *
+ *  FAULT_EA_IMPREC - Imprecise External Abort
+ *
+ * The imprecise means that we don't know where the abort happened,
+ * thus FAR is undefined. The abort should not never fire, but hot
+ * plugging or accidental harware failure can be the cause of it.
+ * If the abort happens, it can even be on different (thread) context.
+ * Without any additional support, the abort is fatal, as we do not
+ * know what really happened.
+ *
+ * QQQ: Some additional functionality, like pcb_onfault but global,
+ *      can be implemented. Imprecise handlers could be registered
+ *      which tell us if the abort is caused by something they know
+ *      about. They should return one of three codes like:
+ *		FAULT_IS_MINE,
+ *		FAULT_CAN_BE_MINE,
+ *		FAULT_IS_NOT_MINE.
+ *      The handlers should be called until some of them returns
+ *      FAULT_IS_MINE value or all was called. If all handlers return
+ *	FAULT_IS_NOT_MINE value, then the abort is fatal.
+ */
+static __inline void
+abort_imprecise(struct trapframe *tf, u_int fsr, u_int prefetch, u_int usermode)
+{
+	/* XXXX  We can got imprecise abort as result of access
+	 * to not-present PCI/PCIe configuration space.
+	 */
+#if 0
+	goto out;
+#endif
+	abort_fatal(tf, FAULT_EA_IMPREC, fsr, 0, prefetch, curthread, NULL);
+
+	/*
+	 * Returning from this function means that we ignore
+	 * the abort for good reason. Note that imprecise abort
+	 * could fire any time even in user mode.
+	 */
+
+#if 0
+out:
+	if (usermode)
+		userret(curthread, tf);
+#endif
+}
+
+/*
+ * abort_debug() handles the following abort:
+ *
+ *  FAULT_DEBUG - Debug Event
+ *
+ */
+static __inline void
+abort_debug(struct trapframe *tf, u_int fsr, u_int prefetch, u_int usermode,
+    u_int far)
+{
+	if (usermode) {
+		struct thread *td;
+
+		td = curthread;
+		call_trapsignal(td, SIGTRAP, TRAP_BRKPT, far);
+		userret(td, tf);
+	} else {
+#ifdef KDB
+		kdb_trap(T_BREAKPOINT, 0, tf);
+#else
+		printf("No debugger in kernel.\n");
+#endif
+	}
+}
+
+/*
+ * Abort handler.
+ *
+ * FAR, FSR, and everything what can be lost after enabling
+ * interrupts must be grabbed before the interrupts will be
+ * enabled. Note that when interrupts will be enabled, we
+ * could even migrate to another CPU ...
+ *
+ * TODO: move quick cases to ASM
+ */
+void
+abort_handler(struct trapframe *tf, int prefetch)
+{
+	struct thread *td;
+	vm_offset_t far, va;
+	int idx, usermode;
+	uint32_t fsr;
+	struct ksig ksig;
+	struct proc *p;
+	struct pcb *pcb;
+	struct vm_map *map;
+	struct vmspace *vm;
+	vm_prot_t ftype;
+	int rv;
+#ifdef INVARIANTS
+	void *onfault;
+#endif
+	td = curthread;
+	fsr = (prefetch) ? cp15_ifsr_get(): cp15_dfsr_get();
+	far = (prefetch) ? TRAPF_PC(tf) : cp15_dfar_get();
+
+	idx = FSR_TO_FAULT(fsr);
+	usermode = TRAPF_USERMODE(tf);	/* Abort came from user mode? */
+	if (usermode)
+		td->td_frame = tf;
+
+	CTR4(KTR_TRAP, "abort_handler: fsr %#x (idx %u) far %#x prefetch %u",
+	fsr, idx, far, prefetch);
+
+	/*
+	 * Firstly, handle aborts that are not directly related to mapping.
+	 */
+	if (__predict_false(idx == FAULT_EA_IMPREC)) {
+		abort_imprecise(tf, fsr, prefetch, usermode);
+		return;
+	}
+
+	if (__predict_false(idx == FAULT_DEBUG)) {
+		abort_debug(tf, fsr, prefetch, usermode, far);
+		return;
+	}
+
+#ifdef ARM_NEW_PMAP
+	rv = pmap_fault(PCPU_GET(curpmap), far, fsr, idx, usermode);
+	if (rv == 0) {
+		return;
+	} else if (rv == EFAULT) {
+
+		call_trapsignal(td, SIGSEGV, SEGV_MAPERR, far);
+		userret(td, tf);
+		return;
+	}
+#endif
+	/*
+	 * Now, when we handled imprecise and debug aborts, the rest of
+	 * aborts should be really related to mapping.
+	 *
+	 */
+
+	PCPU_INC(cnt.v_trap);
+
+#ifdef KDB
+	if (kdb_active) {
+		kdb_reenter();
+		goto out;
+	}
+#endif
+	if (__predict_false((td->td_pflags & TDP_NOFAULTING) != 0)) {
+		/*
+		 * Due to both processor errata and lazy TLB invalidation when
+		 * access restrictions are removed from virtual pages, memory
+		 * accesses that are allowed by the physical mapping layer may
+		 * nonetheless cause one spurious page fault per virtual page.
+		 * When the thread is executing a "no faulting" section that
+		 * is bracketed by vm_fault_{disable,enable}_pagefaults(),
+		 * every page fault is treated as a spurious page fault,
+		 * unless it accesses the same virtual address as the most
+		 * recent page fault within the same "no faulting" section.
+		 */
+		if (td->td_md.md_spurflt_addr != far ||
+		    (td->td_pflags & TDP_RESETSPUR) != 0) {
+			td->td_md.md_spurflt_addr = far;
+			td->td_pflags &= ~TDP_RESETSPUR;
+
+			tlb_flush_local(far & ~PAGE_MASK);
+			return;
+		}
+	} else {
+		/*
+		 * If we get a page fault while in a critical section, then
+		 * it is most likely a fatal kernel page fault.  The kernel
+		 * is already going to panic trying to get a sleep lock to
+		 * do the VM lookup, so just consider it a fatal trap so the
+		 * kernel can print out a useful trap message and even get
+		 * to the debugger.
+		 *
+		 * If we get a page fault while holding a non-sleepable
+		 * lock, then it is most likely a fatal kernel page fault.
+		 * If WITNESS is enabled, then it's going to whine about
+		 * bogus LORs with various VM locks, so just skip to the
+		 * fatal trap handling directly.
+		 */
+		if (td->td_critnest != 0 ||
+		    WITNESS_CHECK(WARN_SLEEPOK | WARN_GIANTOK, NULL,
+		    "Kernel page fault") != 0) {
+			abort_fatal(tf, idx, fsr, far, prefetch, td, &ksig);
+			return;
+		}
+	}
+
+	/* Re-enable interrupts if they were enabled previously. */
+	if (td->td_md.md_spinlock_count == 0) {
+		if (__predict_true(tf->tf_spsr & PSR_I) == 0)
+			enable_interrupts(PSR_I);
+		if (__predict_true(tf->tf_spsr & PSR_F) == 0)
+			enable_interrupts(PSR_F);
+	}
+
+	p = td->td_proc;
+	if (usermode) {
+		td->td_pticks = 0;
+		if (td->td_ucred != p->p_ucred)
+			cred_update_thread(td);
+	}
+
+	/* Invoke the appropriate handler, if necessary. */
+	if (__predict_false(aborts[idx].func != NULL)) {
+		if ((aborts[idx].func)(tf, idx, fsr, far, prefetch, td, &ksig))
+			goto do_trapsignal;
+		goto out;
+	}
+
+	/*
+	 * At this point, we're dealing with one of the following aborts:
+	 *
+	 *  FAULT_TRAN_xx  - Translation
+	 *  FAULT_PERM_xx  - Permission
+	 *
+	 * These are the main virtual memory-related faults signalled by
+	 * the MMU.
+	 */
+
+	/* fusubailout is used by [fs]uswintr to avoid page faulting */
+	pcb = td->td_pcb;
+	if (__predict_false(pcb->pcb_onfault == fusubailout)) {
+		tf->tf_r0 = EFAULT;
+		tf->tf_pc = (register_t)pcb->pcb_onfault;
+		return;
+	}
+
+	/*
+	 * QQQ: ARM has a set of unprivileged load and store instructions
+	 *      (LDRT/LDRBT/STRT/STRBT ...) which are supposed to be used
+	 *      in other than user mode and OS should recognize their
+	 *      aborts and behaved appropriately. However, there is no way
+	 *      how to do that reasonably in general unless we restrict
+	 *      the handling somehow. One way is to limit the handling for
+	 *      aborts which come from undefined mode only.
+	 *
+	 *      Anyhow, we do not use these instructions and do not implement
+	 *      any special handling for them.
+	 */
+
+	va = trunc_page(far);
+	if (va >= KERNBASE) {
+		/*
+		 * Don't allow user-mode faults in kernel address space.
+		 */
+		if (usermode)
+			goto nogo;
+
+		map = kernel_map;
+	} else {
+		/*
+		 * This is a fault on non-kernel virtual memory. If curproc
+		 * is NULL or curproc->p_vmspace is NULL the fault is fatal.
+		 */
+		vm = (p != NULL) ? p->p_vmspace : NULL;
+		if (vm == NULL)
+			goto nogo;
+
+		map = &vm->vm_map;
+		if (!usermode && (td->td_intr_nesting_level != 0 ||
+		    pcb->pcb_onfault == NULL)) {
+			abort_fatal(tf, idx, fsr, far, prefetch, td, &ksig);
+			return;
+		}
+	}
+
+	ftype = (fsr & FSR_WNR) ? VM_PROT_WRITE : VM_PROT_READ;
+	if (prefetch)
+		ftype |= VM_PROT_EXECUTE;
+
+#ifdef DEBUG
+	last_fault_code = fsr;
+#endif
+
+#ifndef ARM_NEW_PMAP
+	if (pmap_fault_fixup(vmspace_pmap(td->td_proc->p_vmspace), va, ftype,
+	    usermode)) {
+		goto out;
+	}
+#endif
+
+#ifdef INVARIANTS
+	onfault = pcb->pcb_onfault;
+	pcb->pcb_onfault = NULL;
+#endif
+	if (map != kernel_map) {
+		/*
+		 * Keep swapout from messing with us during this
+		 *	critical time.
+		 */
+		PROC_LOCK(p);
+		++p->p_lock;
+		PROC_UNLOCK(p);
+
+		/* Fault in the user page: */
+		rv = vm_fault(map, va, ftype, VM_FAULT_NORMAL);
+
+		PROC_LOCK(p);
+		--p->p_lock;
+		PROC_UNLOCK(p);
+	} else {
+		/*
+		 * Don't have to worry about process locking or stacks in the
+		 * kernel.
+		 */
+		rv = vm_fault(map, va, ftype, VM_FAULT_NORMAL);
+	}
+
+#ifdef INVARIANTS
+	pcb->pcb_onfault = onfault;
+#endif
+
+	if (__predict_true(rv == KERN_SUCCESS))
+		goto out;
+nogo:
+	if (!usermode) {
+		if (td->td_intr_nesting_level == 0 &&
+		    pcb->pcb_onfault != NULL) {
+			tf->tf_r0 = rv;
+			tf->tf_pc = (int)pcb->pcb_onfault;
+			return;
+		}
+		CTR2(KTR_TRAP, "%s: vm_fault() failed with %d", __func__, rv);
+		abort_fatal(tf, idx, fsr, far, prefetch, td, &ksig);
+		return;
+	}
+
+	ksig.sig = (rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV;
+	ksig.code = 0;
+	ksig.addr = far;
+
+do_trapsignal:
+	call_trapsignal(td, ksig.sig, ksig.code, ksig.addr);
+out:
+	if (usermode)
+		userret(td, tf);
+}
+
+/*
+ * abort_fatal() handles the following data aborts:
+
+ *  FAULT_DEBUG		- Debug Event
+ *  FAULT_ACCESS_xx	- Acces Bit
+ *  FAULT_EA_PREC	- Precise External Abort
+ *  FAULT_DOMAIN_xx	- Domain Fault
+ *  FAULT_EA_TRAN_xx	- External Translation Abort
+ *  FAULT_EA_IMPREC	- Imprecise External Abort
+ *  + all undefined codes for ABORT
+ *
+ * We should never see these on a properly functioning system.
+ *
+ * This function is also called by the other handlers if they
+ * detect a fatal problem.
+ *
+ * Note: If 'l' is NULL, we assume we're dealing with a prefetch abort.
+ */
+static int
+abort_fatal(struct trapframe *tf, u_int idx, u_int fsr, u_int far, u_int prefetch,
+    struct thread *td, struct ksig *ksig)
+{
+	u_int usermode;
+	const char *mode;
+	const char *rw_mode;
+
+	usermode = TRAPF_USERMODE(tf);
+	mode = usermode ? "user" : "kernel";
+	rw_mode  = fsr & FSR_WNR ? "write" : "read";
+	disable_interrupts(PSR_I|PSR_F);
+
+	if (td != NULL) {
+		printf("Fatal %s mode data abort: '%s' on %s\n", mode,
+		    aborts[idx].desc, rw_mode);
+		printf("trapframe: %p\nFSR=%08x, FAR=", tf, fsr);
+		if (idx != FAULT_EA_IMPREC)
+			printf("%08x, ", far);
+		else
+			printf("Invalid,  ");
+		printf("spsr=%08x\n", tf->tf_spsr);
+	} else {
+		printf("Fatal %s mode prefetch abort at 0x%08x\n",
+		    mode, tf->tf_pc);
+		printf("trapframe: %p, spsr=%08x\n", tf, tf->tf_spsr);
+	}
+
+	printf("r0 =%08x, r1 =%08x, r2 =%08x, r3 =%08x\n",
+	    tf->tf_r0, tf->tf_r1, tf->tf_r2, tf->tf_r3);
+	printf("r4 =%08x, r5 =%08x, r6 =%08x, r7 =%08x\n",
+	    tf->tf_r4, tf->tf_r5, tf->tf_r6, tf->tf_r7);
+	printf("r8 =%08x, r9 =%08x, r10=%08x, r11=%08x\n",
+	    tf->tf_r8, tf->tf_r9, tf->tf_r10, tf->tf_r11);
+	printf("r12=%08x, ", tf->tf_r12);
+
+	if (usermode)
+		printf("usp=%08x, ulr=%08x",
+		    tf->tf_usr_sp, tf->tf_usr_lr);
+	else
+		printf("ssp=%08x, slr=%08x",
+		    tf->tf_svc_sp, tf->tf_svc_lr);
+	printf(", pc =%08x\n\n", tf->tf_pc);
+
+#ifdef KDB
+	if (debugger_on_panic || kdb_active)
+		kdb_trap(fsr, 0, tf);
+#endif
+	panic("Fatal abort");
+	/*NOTREACHED*/
+}
+
+/*
+ * abort_align() handles the following data abort:
+ *
+ *  FAULT_ALIGN - Alignment fault
+ *
+ * Every memory access should be correctly aligned in kernel including
+ * user to kernel and vice versa data copying, so we ignore pcb_onfault,
+ * and it's always fatal. We generate a signal in case of abort from user mode.
+ */
+static int
+abort_align(struct trapframe *tf, u_int idx, u_int fsr, u_int far, u_int prefetch,
+    struct thread *td, struct ksig *ksig)
+{
+	u_int usermode;
+
+	usermode = TRAPF_USERMODE(tf);
+
+	/*
+	 * Alignment faults are always fatal if they occur in any but user mode.
+	 *
+	 * XXX The old trap code handles pcb fault even for alignment traps.
+	 * Unfortunately, we don't known why and if is this need.
+	 */
+	if (!usermode) {
+		if (td->td_intr_nesting_level == 0 && td != NULL &&
+		    td->td_pcb->pcb_onfault != NULL) {
+			printf("%s: Got alignment fault with pcb_onfault set"
+			    ", please report this issue\n", __func__);
+			tf->tf_r0 = EFAULT;;
+			tf->tf_pc = (int)td->td_pcb->pcb_onfault;
+			return (0);
+		}
+		abort_fatal(tf, idx, fsr, far, prefetch, td, ksig);
+	}
+	/* Deliver a bus error signal to the process */
+	ksig->code = 0;
+	ksig->sig = SIGBUS;
+	ksig->addr = far;
+	return (1);
+}
+
+/*
+ * abort_icache() handles the following data abort:
+ *
+ * FAULT_ICACHE - Instruction cache maintenance
+ *
+ * According to manual, FAULT_ICACHE is translation fault during cache
+ * maintenance operation. In fact, no cache maintenance operation on
+ * not mapped virtual addresses should be called. As cache maintenance
+ * operation (except DMB, DSB, and Flush Prefetch Buffer) are priviledged,
+ * the abort is concider as fatal for now. However, all the matter with
+ * cache maintenance operation on virtual addresses could be really complex
+ * and fuzzy in SMP case, so maybe in future standard fault mechanism
+ * should be held here including vm_fault() calling.
+ */
+static int
+abort_icache(struct trapframe *tf, u_int idx, u_int fsr, u_int far, u_int prefetch,
+    struct thread *td, struct ksig *ksig)
+{
+	abort_fatal(tf, idx, fsr, far, prefetch, td, ksig);
+	return(0);
+}


Property changes on: trunk/sys/arm/arm/trap-v6.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/trap.c
===================================================================
--- trunk/sys/arm/arm/trap.c	                        (rev 0)
+++ trunk/sys/arm/arm/trap.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,753 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: fault.c,v 1.45 2003/11/20 14:44:36 scw Exp $	*/
+
+/*-
+ * Copyright 2004 Olivier Houchard
+ * Copyright 2003 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Steve C. Woodford for Wasabi Systems, Inc.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed for the NetBSD Project by
+ *      Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
+ * 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.
+ */
+/*-
+ * Copyright (c) 1994-1997 Mark Brinicombe.
+ * Copyright (c) 1994 Brini.
+ * All rights reserved.
+ *
+ * This code is derived from software written for Brini by Mark Brinicombe
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Brini.
+ * 4. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BRINI ``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 BRINI 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.
+ *
+ * RiscBSD kernel project
+ *
+ * fault.c
+ *
+ * Fault handlers
+ *
+ * Created      : 28/11/94
+ */
+
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/trap.c 294681 2016-01-24 19:58:58Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/signalvar.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/vm_kern.h>
+#include <vm/vm_map.h>
+#include <vm/vm_extern.h>
+
+#include <machine/acle-compat.h>
+#include <machine/cpu.h>
+#include <machine/frame.h>
+#include <machine/machdep.h>
+#include <machine/pcb.h>
+#include <machine/vmparam.h>
+
+#ifdef KDB
+#include <sys/kdb.h>
+#endif
+
+extern char fusubailout[];
+
+#ifdef DEBUG
+int last_fault_code;	/* For the benefit of pmap_fault_fixup() */
+#endif
+
+struct ksig {
+	int signb;
+	u_long code;
+};
+struct data_abort {
+	int (*func)(struct trapframe *, u_int, u_int, struct thread *, 
+	    struct ksig *);
+	const char *desc;
+};
+
+static int dab_fatal(struct trapframe *, u_int, u_int, struct thread *,
+    struct ksig *);
+static int dab_align(struct trapframe *, u_int, u_int, struct thread *,
+    struct ksig *);
+static int dab_buserr(struct trapframe *, u_int, u_int, struct thread *,
+    struct ksig *);
+static void prefetch_abort_handler(struct trapframe *);
+
+static const struct data_abort data_aborts[] = {
+	{dab_fatal,	"Vector Exception"},
+	{dab_align,	"Alignment Fault 1"},
+	{dab_fatal,	"Terminal Exception"},
+	{dab_align,	"Alignment Fault 3"},
+	{dab_buserr,	"External Linefetch Abort (S)"},
+	{NULL,		"Translation Fault (S)"},
+#if (ARM_MMU_V6 + ARM_MMU_V7) != 0
+	{NULL,		"Translation Flag Fault"},
+#else
+	{dab_buserr,	"External Linefetch Abort (P)"},
+#endif
+	{NULL,		"Translation Fault (P)"},
+	{dab_buserr,	"External Non-Linefetch Abort (S)"},
+	{NULL,		"Domain Fault (S)"},
+	{dab_buserr,	"External Non-Linefetch Abort (P)"},
+	{NULL,		"Domain Fault (P)"},
+	{dab_buserr,	"External Translation Abort (L1)"},
+	{NULL,		"Permission Fault (S)"},
+	{dab_buserr,	"External Translation Abort (L2)"},
+	{NULL,		"Permission Fault (P)"}
+};
+
+/* Determine if a fault came from user mode */
+#define	TRAP_USERMODE(tf)	((tf->tf_spsr & PSR_MODE) == PSR_USR32_MODE)
+
+/* Determine if 'x' is a permission fault */
+#define	IS_PERMISSION_FAULT(x)					\
+	(((1 << ((x) & FAULT_TYPE_MASK)) &			\
+	  ((1 << FAULT_PERM_P) | (1 << FAULT_PERM_S))) != 0)
+
+static __inline void
+call_trapsignal(struct thread *td, int sig, u_long code)
+{
+	ksiginfo_t ksi;
+
+	ksiginfo_init_trap(&ksi);
+	ksi.ksi_signo = sig;
+	ksi.ksi_code = (int)code;
+	trapsignal(td, &ksi);
+}
+
+void
+abort_handler(struct trapframe *tf, int type)
+{
+	struct vm_map *map;
+	struct pcb *pcb;
+	struct thread *td;
+	u_int user, far, fsr;
+	vm_prot_t ftype;
+	void *onfault;
+	vm_offset_t va;
+	int error = 0;
+	struct ksig ksig;
+	struct proc *p;
+
+	if (type == 1)
+		return (prefetch_abort_handler(tf));
+
+	/* Grab FAR/FSR before enabling interrupts */
+	far = cpu_faultaddress();
+	fsr = cpu_faultstatus();
+#if 0
+	printf("data abort: fault address=%p (from pc=%p lr=%p)\n",
+	       (void*)far, (void*)tf->tf_pc, (void*)tf->tf_svc_lr);
+#endif
+
+	/* Update vmmeter statistics */
+#if 0
+	vmexp.traps++;
+#endif
+
+	td = curthread;
+	p = td->td_proc;
+
+	PCPU_INC(cnt.v_trap);
+	/* Data abort came from user mode? */
+	user = TRAP_USERMODE(tf);
+
+	if (user) {
+		td->td_pticks = 0;
+		td->td_frame = tf;
+		if (td->td_ucred != td->td_proc->p_ucred)
+			cred_update_thread(td);
+
+	}
+	/* Grab the current pcb */
+	pcb = td->td_pcb;
+	/* Re-enable interrupts if they were enabled previously */
+	if (td->td_md.md_spinlock_count == 0) {
+		if (__predict_true(tf->tf_spsr & PSR_I) == 0)
+			enable_interrupts(PSR_I);
+		if (__predict_true(tf->tf_spsr & PSR_F) == 0)
+			enable_interrupts(PSR_F);
+	}
+
+
+	/* Invoke the appropriate handler, if necessary */
+	if (__predict_false(data_aborts[fsr & FAULT_TYPE_MASK].func != NULL)) {
+		if ((data_aborts[fsr & FAULT_TYPE_MASK].func)(tf, fsr, far,
+		    td, &ksig)) {
+			goto do_trapsignal;
+		}
+		goto out;
+	}
+
+	/*
+	 * At this point, we're dealing with one of the following data aborts:
+	 *
+	 *  FAULT_TRANS_S  - Translation -- Section
+	 *  FAULT_TRANS_P  - Translation -- Page
+	 *  FAULT_DOMAIN_S - Domain -- Section
+	 *  FAULT_DOMAIN_P - Domain -- Page
+	 *  FAULT_PERM_S   - Permission -- Section
+	 *  FAULT_PERM_P   - Permission -- Page
+	 *
+	 * These are the main virtual memory-related faults signalled by
+	 * the MMU.
+	 */
+
+	/* fusubailout is used by [fs]uswintr to avoid page faulting */
+	if (__predict_false(pcb->pcb_onfault == fusubailout)) {
+		tf->tf_r0 = EFAULT;
+		tf->tf_pc = (register_t)(intptr_t) pcb->pcb_onfault;
+		return;
+	}
+
+	/*
+	 * Make sure the Program Counter is sane. We could fall foul of
+	 * someone executing Thumb code, in which case the PC might not
+	 * be word-aligned. This would cause a kernel alignment fault
+	 * further down if we have to decode the current instruction.
+	 * XXX: It would be nice to be able to support Thumb at some point.
+	 */
+	if (__predict_false((tf->tf_pc & 3) != 0)) {
+		if (user) {
+			/*
+			 * Give the user an illegal instruction signal.
+			 */
+			/* Deliver a SIGILL to the process */
+			ksig.signb = SIGILL;
+			ksig.code = 0;
+			goto do_trapsignal;
+		}
+
+		/*
+		 * The kernel never executes Thumb code.
+		 */
+		printf("\ndata_abort_fault: Misaligned Kernel-mode "
+		    "Program Counter\n");
+		dab_fatal(tf, fsr, far, td, &ksig);
+	}
+
+	va = trunc_page((vm_offset_t)far);
+
+	/*
+	 * It is only a kernel address space fault iff:
+	 *	1. user == 0  and
+	 *	2. pcb_onfault not set or
+	 *	3. pcb_onfault set and not LDRT/LDRBT/STRT/STRBT instruction.
+	 */
+	if (user == 0 && (va >= VM_MIN_KERNEL_ADDRESS ||
+	    (va < VM_MIN_ADDRESS && vector_page == ARM_VECTORS_LOW)) &&
+	    __predict_true((pcb->pcb_onfault == NULL ||
+	     (ReadWord(tf->tf_pc) & 0x05200000) != 0x04200000))) {
+		map = kernel_map;
+
+		/* Was the fault due to the FPE/IPKDB ? */
+		if (__predict_false((tf->tf_spsr & PSR_MODE)==PSR_UND32_MODE)) {
+
+			/*
+			 * Force exit via userret()
+			 * This is necessary as the FPE is an extension to
+			 * userland that actually runs in a priveledged mode
+			 * but uses USR mode permissions for its accesses.
+			 */
+			user = 1;
+			ksig.signb = SIGSEGV;
+			ksig.code = 0;
+			goto do_trapsignal;
+		}
+	} else {
+		map = &td->td_proc->p_vmspace->vm_map;
+	}
+
+	/*
+	 * We need to know whether the page should be mapped as R or R/W.  On
+	 * armv6 and later the fault status register indicates whether the
+	 * access was a read or write.  Prior to armv6, we know that a
+	 * permission fault can only be the result of a write to a read-only
+	 * location, so we can deal with those quickly.  Otherwise we need to
+	 * disassemble the faulting instruction to determine if it was a write.
+	 */
+#if __ARM_ARCH >= 6
+	ftype = (fsr & FAULT_WNR) ? VM_PROT_READ | VM_PROT_WRITE : VM_PROT_READ;
+#else
+	if (IS_PERMISSION_FAULT(fsr))
+		ftype = VM_PROT_WRITE;
+	else {
+		u_int insn = ReadWord(tf->tf_pc);
+
+		if (((insn & 0x0c100000) == 0x04000000) ||	/* STR/STRB */
+		    ((insn & 0x0e1000b0) == 0x000000b0) ||	/* STRH/STRD */
+		    ((insn & 0x0a100000) == 0x08000000)) {	/* STM/CDT */
+			ftype = VM_PROT_WRITE;
+		} else {
+			if ((insn & 0x0fb00ff0) == 0x01000090)	/* SWP */
+				ftype = VM_PROT_READ | VM_PROT_WRITE;
+			else
+				ftype = VM_PROT_READ;
+		}
+	}
+#endif
+
+	/*
+	 * See if the fault is as a result of ref/mod emulation,
+	 * or domain mismatch.
+	 */
+#ifdef DEBUG
+	last_fault_code = fsr;
+#endif
+	if (pmap_fault_fixup(vmspace_pmap(td->td_proc->p_vmspace), va, ftype,
+	    user)) {
+		goto out;
+	}
+
+	onfault = pcb->pcb_onfault;
+	pcb->pcb_onfault = NULL;
+	if (map != kernel_map) {
+		PROC_LOCK(p);
+		p->p_lock++;
+		PROC_UNLOCK(p);
+	}
+	error = vm_fault(map, va, ftype, VM_FAULT_NORMAL);
+	pcb->pcb_onfault = onfault;
+
+	if (map != kernel_map) {
+		PROC_LOCK(p);
+		p->p_lock--;
+		PROC_UNLOCK(p);
+	}
+	if (__predict_true(error == 0))
+		goto out;
+	if (user == 0) {
+		if (pcb->pcb_onfault) {
+			tf->tf_r0 = error;
+			tf->tf_pc = (register_t)(intptr_t) pcb->pcb_onfault;
+			return;
+		}
+
+		printf("\nvm_fault(%p, %x, %x, 0) -> %x\n", map, va, ftype,
+		    error);
+		dab_fatal(tf, fsr, far, td, &ksig);
+	}
+
+
+	if (error == ENOMEM) {
+		printf("VM: pid %d (%s), uid %d killed: "
+		    "out of swap\n", td->td_proc->p_pid, td->td_name,
+		    (td->td_proc->p_ucred) ?
+		     td->td_proc->p_ucred->cr_uid : -1);
+		ksig.signb = SIGKILL;
+	} else {
+		ksig.signb = SIGSEGV;
+	}
+	ksig.code = 0;
+do_trapsignal:
+	call_trapsignal(td, ksig.signb, ksig.code);
+out:
+	/* If returning to user mode, make sure to invoke userret() */
+	if (user)
+		userret(td, tf);
+}
+
+/*
+ * dab_fatal() handles the following data aborts:
+ *
+ *  FAULT_WRTBUF_0 - Vector Exception
+ *  FAULT_WRTBUF_1 - Terminal Exception
+ *
+ * We should never see these on a properly functioning system.
+ *
+ * This function is also called by the other handlers if they
+ * detect a fatal problem.
+ *
+ * Note: If 'l' is NULL, we assume we're dealing with a prefetch abort.
+ */
+static int
+dab_fatal(struct trapframe *tf, u_int fsr, u_int far, struct thread *td,
+    struct ksig *ksig)
+{
+	const char *mode;
+
+	mode = TRAP_USERMODE(tf) ? "user" : "kernel";
+
+	disable_interrupts(PSR_I|PSR_F);
+	if (td != NULL) {
+		printf("Fatal %s mode data abort: '%s'\n", mode,
+		    data_aborts[fsr & FAULT_TYPE_MASK].desc);
+		printf("trapframe: %p\nFSR=%08x, FAR=", tf, fsr);
+		if ((fsr & FAULT_IMPRECISE) == 0)
+			printf("%08x, ", far);
+		else
+			printf("Invalid,  ");
+		printf("spsr=%08x\n", tf->tf_spsr);
+	} else {
+		printf("Fatal %s mode prefetch abort at 0x%08x\n",
+		    mode, tf->tf_pc);
+		printf("trapframe: %p, spsr=%08x\n", tf, tf->tf_spsr);
+	}
+
+	printf("r0 =%08x, r1 =%08x, r2 =%08x, r3 =%08x\n",
+	    tf->tf_r0, tf->tf_r1, tf->tf_r2, tf->tf_r3);
+	printf("r4 =%08x, r5 =%08x, r6 =%08x, r7 =%08x\n",
+	    tf->tf_r4, tf->tf_r5, tf->tf_r6, tf->tf_r7);
+	printf("r8 =%08x, r9 =%08x, r10=%08x, r11=%08x\n",
+	    tf->tf_r8, tf->tf_r9, tf->tf_r10, tf->tf_r11);
+	printf("r12=%08x, ", tf->tf_r12);
+
+	if (TRAP_USERMODE(tf))
+		printf("usp=%08x, ulr=%08x",
+		    tf->tf_usr_sp, tf->tf_usr_lr);
+	else
+		printf("ssp=%08x, slr=%08x",
+		    tf->tf_svc_sp, tf->tf_svc_lr);
+	printf(", pc =%08x\n\n", tf->tf_pc);
+
+#ifdef KDB
+	if (debugger_on_panic || kdb_active)
+		if (kdb_trap(fsr, 0, tf))
+			return (0);
+#endif
+	panic("Fatal abort");
+	/*NOTREACHED*/
+}
+
+/*
+ * dab_align() handles the following data aborts:
+ *
+ *  FAULT_ALIGN_0 - Alignment fault
+ *  FAULT_ALIGN_1 - Alignment fault
+ *
+ * These faults are fatal if they happen in kernel mode. Otherwise, we
+ * deliver a bus error to the process.
+ */
+static int
+dab_align(struct trapframe *tf, u_int fsr, u_int far, struct thread *td,
+    struct ksig *ksig)
+{
+
+	/* Alignment faults are always fatal if they occur in kernel mode */
+	if (!TRAP_USERMODE(tf)) {
+		if (!td || !td->td_pcb->pcb_onfault)
+			dab_fatal(tf, fsr, far, td, ksig);
+		tf->tf_r0 = EFAULT;
+		tf->tf_pc = (int)td->td_pcb->pcb_onfault;
+		return (0);
+	}
+
+	/* pcb_onfault *must* be NULL at this point */
+
+	/* Deliver a bus error signal to the process */
+	ksig->code = 0;
+	ksig->signb = SIGBUS;
+	td->td_frame = tf;
+
+	return (1);
+}
+
+/*
+ * dab_buserr() handles the following data aborts:
+ *
+ *  FAULT_BUSERR_0 - External Abort on Linefetch -- Section
+ *  FAULT_BUSERR_1 - External Abort on Linefetch -- Page
+ *  FAULT_BUSERR_2 - External Abort on Non-linefetch -- Section
+ *  FAULT_BUSERR_3 - External Abort on Non-linefetch -- Page
+ *  FAULT_BUSTRNL1 - External abort on Translation -- Level 1
+ *  FAULT_BUSTRNL2 - External abort on Translation -- Level 2
+ *
+ * If pcb_onfault is set, flag the fault and return to the handler.
+ * If the fault occurred in user mode, give the process a SIGBUS.
+ *
+ * Note: On XScale, FAULT_BUSERR_0, FAULT_BUSERR_1, and FAULT_BUSERR_2
+ * can be flagged as imprecise in the FSR. This causes a real headache
+ * since some of the machine state is lost. In this case, tf->tf_pc
+ * may not actually point to the offending instruction. In fact, if
+ * we've taken a double abort fault, it generally points somewhere near
+ * the top of "data_abort_entry" in exception.S.
+ *
+ * In all other cases, these data aborts are considered fatal.
+ */
+static int
+dab_buserr(struct trapframe *tf, u_int fsr, u_int far, struct thread *td,
+    struct ksig *ksig)
+{
+	struct pcb *pcb = td->td_pcb;
+
+#ifdef __XSCALE__
+	if ((fsr & FAULT_IMPRECISE) != 0 &&
+	    (tf->tf_spsr & PSR_MODE) == PSR_ABT32_MODE) {
+		/*
+		 * Oops, an imprecise, double abort fault. We've lost the
+		 * r14_abt/spsr_abt values corresponding to the original
+		 * abort, and the spsr saved in the trapframe indicates
+		 * ABT mode.
+		 */
+		tf->tf_spsr &= ~PSR_MODE;
+
+		/*
+		 * We use a simple heuristic to determine if the double abort
+		 * happened as a result of a kernel or user mode access.
+		 * If the current trapframe is at the top of the kernel stack,
+		 * the fault _must_ have come from user mode.
+		 */
+		if (tf != ((struct trapframe *)pcb->pcb_regs.sf_sp) - 1) {
+			/*
+			 * Kernel mode. We're either about to die a
+			 * spectacular death, or pcb_onfault will come
+			 * to our rescue. Either way, the current value
+			 * of tf->tf_pc is irrelevant.
+			 */
+			tf->tf_spsr |= PSR_SVC32_MODE;
+			if (pcb->pcb_onfault == NULL)
+				printf("\nKernel mode double abort!\n");
+		} else {
+			/*
+			 * User mode. We've lost the program counter at the
+			 * time of the fault (not that it was accurate anyway;
+			 * it's not called an imprecise fault for nothing).
+			 * About all we can do is copy r14_usr to tf_pc and
+			 * hope for the best. The process is about to get a
+			 * SIGBUS, so it's probably history anyway.
+			 */
+			tf->tf_spsr |= PSR_USR32_MODE;
+			tf->tf_pc = tf->tf_usr_lr;
+		}
+	}
+
+	/* FAR is invalid for imprecise exceptions */
+	if ((fsr & FAULT_IMPRECISE) != 0)
+		far = 0;
+#endif /* __XSCALE__ */
+
+	if (pcb->pcb_onfault) {
+		tf->tf_r0 = EFAULT;
+		tf->tf_pc = (register_t)(intptr_t) pcb->pcb_onfault;
+		return (0);
+	}
+
+	/*
+	 * At this point, if the fault happened in kernel mode, we're toast
+	 */
+	if (!TRAP_USERMODE(tf))
+		dab_fatal(tf, fsr, far, td, ksig);
+
+	/* Deliver a bus error signal to the process */
+	ksig->signb = SIGBUS;
+	ksig->code = 0;
+	td->td_frame = tf;
+
+	return (1);
+}
+
+/*
+ * void prefetch_abort_handler(struct trapframe *tf)
+ *
+ * Abort handler called when instruction execution occurs at
+ * a non existent or restricted (access permissions) memory page.
+ * If the address is invalid and we were in SVC mode then panic as
+ * the kernel should never prefetch abort.
+ * If the address is invalid and the page is mapped then the user process
+ * does no have read permission so send it a signal.
+ * Otherwise fault the page in and try again.
+ */
+static void
+prefetch_abort_handler(struct trapframe *tf)
+{
+	struct thread *td;
+	struct proc * p;
+	struct vm_map *map;
+	vm_offset_t fault_pc, va;
+	int error = 0;
+	struct ksig ksig;
+
+
+#if 0
+	/* Update vmmeter statistics */
+	uvmexp.traps++;
+#endif
+#if 0
+	printf("prefetch abort handler: %p %p\n", (void*)tf->tf_pc,
+	    (void*)tf->tf_usr_lr);
+#endif
+
+ 	td = curthread;
+	p = td->td_proc;
+	PCPU_INC(cnt.v_trap);
+
+	if (TRAP_USERMODE(tf)) {
+		td->td_frame = tf;
+		if (td->td_ucred != td->td_proc->p_ucred)
+			cred_update_thread(td);
+	}
+	fault_pc = tf->tf_pc;
+	if (td->td_md.md_spinlock_count == 0) {
+		if (__predict_true(tf->tf_spsr & PSR_I) == 0)
+			enable_interrupts(PSR_I);
+		if (__predict_true(tf->tf_spsr & PSR_F) == 0)
+			enable_interrupts(PSR_F);
+	}
+
+	/* Prefetch aborts cannot happen in kernel mode */
+	if (__predict_false(!TRAP_USERMODE(tf)))
+		dab_fatal(tf, 0, tf->tf_pc, NULL, &ksig);
+	td->td_pticks = 0;
+
+
+	/* Ok validate the address, can only execute in USER space */
+	if (__predict_false(fault_pc >= VM_MAXUSER_ADDRESS ||
+	    (fault_pc < VM_MIN_ADDRESS && vector_page == ARM_VECTORS_LOW))) {
+		ksig.signb = SIGSEGV;
+		ksig.code = 0;
+		goto do_trapsignal;
+	}
+
+	map = &td->td_proc->p_vmspace->vm_map;
+	va = trunc_page(fault_pc);
+
+	/*
+	 * See if the pmap can handle this fault on its own...
+	 */
+#ifdef DEBUG
+	last_fault_code = -1;
+#endif
+	if (pmap_fault_fixup(map->pmap, va, VM_PROT_READ, 1))
+		goto out;
+
+	if (map != kernel_map) {
+		PROC_LOCK(p);
+		p->p_lock++;
+		PROC_UNLOCK(p);
+	}
+
+	error = vm_fault(map, va, VM_PROT_READ | VM_PROT_EXECUTE,
+	    VM_FAULT_NORMAL);
+	if (map != kernel_map) {
+		PROC_LOCK(p);
+		p->p_lock--;
+		PROC_UNLOCK(p);
+	}
+
+	if (__predict_true(error == 0))
+		goto out;
+
+	if (error == ENOMEM) {
+		printf("VM: pid %d (%s), uid %d killed: "
+		    "out of swap\n", td->td_proc->p_pid, td->td_name,
+		    (td->td_proc->p_ucred) ?
+		     td->td_proc->p_ucred->cr_uid : -1);
+		ksig.signb = SIGKILL;
+	} else {
+		ksig.signb = SIGSEGV;
+	}
+	ksig.code = 0;
+
+do_trapsignal:
+	call_trapsignal(td, ksig.signb, ksig.code);
+
+out:
+	userret(td, tf);
+
+}
+
+extern int badaddr_read_1(const uint8_t *, uint8_t *);
+extern int badaddr_read_2(const uint16_t *, uint16_t *);
+extern int badaddr_read_4(const uint32_t *, uint32_t *);
+/*
+ * Tentatively read an 8, 16, or 32-bit value from 'addr'.
+ * If the read succeeds, the value is written to 'rptr' and zero is returned.
+ * Else, return EFAULT.
+ */
+int
+badaddr_read(void *addr, size_t size, void *rptr)
+{
+	union {
+		uint8_t v1;
+		uint16_t v2;
+		uint32_t v4;
+	} u;
+	int rv;
+
+	cpu_drain_writebuf();
+
+	/* Read from the test address. */
+	switch (size) {
+	case sizeof(uint8_t):
+		rv = badaddr_read_1(addr, &u.v1);
+		if (rv == 0 && rptr)
+			*(uint8_t *) rptr = u.v1;
+		break;
+
+	case sizeof(uint16_t):
+		rv = badaddr_read_2(addr, &u.v2);
+		if (rv == 0 && rptr)
+			*(uint16_t *) rptr = u.v2;
+		break;
+
+	case sizeof(uint32_t):
+		rv = badaddr_read_4(addr, &u.v4);
+		if (rv == 0 && rptr)
+			*(uint32_t *) rptr = u.v4;
+		break;
+
+	default:
+		panic("badaddr: invalid size (%lu)", (u_long) size);
+	}
+
+	/* Return EFAULT if the address was invalid, else zero */
+	return (rv);
+}
\ No newline at end of file


Property changes on: trunk/sys/arm/arm/trap.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/uio_machdep.c
===================================================================
--- trunk/sys/arm/arm/uio_machdep.c	                        (rev 0)
+++ trunk/sys/arm/arm/uio_machdep.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,125 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2004 Alan L. Cox <alc at cs.rice.edu>
+ * Copyright (c) 1982, 1986, 1991, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ *	@(#)kern_subr.c	8.3 (Berkeley) 1/21/94
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/uio_machdep.c 266312 2014-05-17 13:59:11Z ian $");
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/proc.h>
+#include <sys/systm.h>
+#include <sys/uio.h>
+#include <sys/sf_buf.h>
+
+#include <vm/vm.h>
+#include <vm/vm_page.h>
+
+#include <machine/vmparam.h>
+
+/*
+ * Implement uiomove(9) from physical memory using sf_bufs to
+ * avoid the creation and destruction of ephemeral mappings.
+ */
+int
+uiomove_fromphys(vm_page_t ma[], vm_offset_t offset, int n, struct uio *uio)
+{
+	struct thread *td = curthread;
+	struct iovec *iov;
+	void *cp;
+	vm_offset_t page_offset;
+	size_t cnt;
+	int error = 0;
+	int save = 0;
+	struct sf_buf *sf;
+
+	KASSERT(uio->uio_rw == UIO_READ || uio->uio_rw == UIO_WRITE,
+	    ("uiomove_fromphys: mode"));
+	KASSERT(uio->uio_segflg != UIO_USERSPACE || uio->uio_td == curthread,
+	    ("uiomove_fromphys proc"));
+	save = td->td_pflags & TDP_DEADLKTREAT;
+	td->td_pflags |= TDP_DEADLKTREAT;
+	while (n > 0 && uio->uio_resid) {
+		iov = uio->uio_iov;
+		cnt = iov->iov_len;
+		if (cnt == 0) {
+			uio->uio_iov++;
+			uio->uio_iovcnt--;
+			continue;
+		}
+		if (cnt > n)
+			cnt = n;
+		page_offset = offset & PAGE_MASK;
+		cnt = min(cnt, PAGE_SIZE - page_offset);
+		sf = sf_buf_alloc(ma[offset >> PAGE_SHIFT], 0);
+		cp = (char*)sf_buf_kva(sf) + page_offset;
+		switch (uio->uio_segflg) {
+		case UIO_USERSPACE:
+			maybe_yield();
+			if (uio->uio_rw == UIO_READ)
+				error = copyout(cp, iov->iov_base, cnt);
+			else
+				error = copyin(iov->iov_base, cp, cnt);
+			if (error) {
+				sf_buf_free(sf);
+				goto out;
+			}
+			break;
+		case UIO_SYSSPACE:
+			if (uio->uio_rw == UIO_READ)
+				bcopy(cp, iov->iov_base, cnt);
+			else
+				bcopy(iov->iov_base, cp, cnt);
+			break;
+		case UIO_NOCOPY:
+			break;
+		}
+		sf_buf_free(sf);
+		iov->iov_base = (char *)iov->iov_base + cnt;
+		iov->iov_len -= cnt;
+		uio->uio_resid -= cnt;
+		uio->uio_offset += cnt;
+		offset += cnt;
+		n -= cnt;
+	}
+out:
+	if (save == 0)
+		td->td_pflags &= ~TDP_DEADLKTREAT;
+	return (error);
+}


Property changes on: trunk/sys/arm/arm/uio_machdep.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/undefined.c
===================================================================
--- trunk/sys/arm/arm/undefined.c	                        (rev 0)
+++ trunk/sys/arm/arm/undefined.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,295 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: undefined.c,v 1.22 2003/11/29 22:21:29 bjh21 Exp $	*/
+
+/*-
+ * Copyright (c) 2001 Ben Harris.
+ * Copyright (c) 1995 Mark Brinicombe.
+ * Copyright (c) 1995 Brini.
+ * All rights reserved.
+ *
+ * This code is derived from software written for Brini by Mark Brinicombe
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Brini.
+ * 4. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BRINI ``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 BRINI 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.
+ *
+ * RiscBSD kernel project
+ *
+ * undefined.c
+ *
+ * Fault handler
+ *
+ * Created      : 06/01/95
+ */
+
+
+#include "opt_ddb.h"
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/undefined.c 278613 2015-02-12 03:50:33Z ian $");
+
+#include <sys/param.h>
+#include <sys/malloc.h>
+#include <sys/queue.h>
+#include <sys/signal.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/syslog.h>
+#include <sys/vmmeter.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/signalvar.h>
+#include <sys/ptrace.h>
+#ifdef KDB
+#include <sys/kdb.h>
+#endif
+
+#include <vm/vm.h>
+#include <vm/vm_extern.h>
+
+#include <machine/armreg.h>
+#include <machine/asm.h>
+#include <machine/cpu.h>
+#include <machine/frame.h>
+#include <machine/undefined.h>
+#include <machine/trap.h>
+
+#include <machine/disassem.h>
+
+#ifdef DDB
+#include <ddb/db_output.h>
+#endif
+
+#ifdef KDB
+#include <machine/db_machdep.h>
+#endif
+
+static int gdb_trapper(u_int, u_int, struct trapframe *, int);
+
+LIST_HEAD(, undefined_handler) undefined_handlers[MAX_COPROCS];
+
+
+void *
+install_coproc_handler(int coproc, undef_handler_t handler)
+{
+	struct undefined_handler *uh;
+
+	KASSERT(coproc >= 0 && coproc < MAX_COPROCS, ("bad coproc"));
+	KASSERT(handler != NULL, ("handler is NULL")); /* Used to be legal. */
+
+	/* XXX: M_TEMP??? */
+	uh = malloc(sizeof(*uh), M_TEMP, M_WAITOK);
+	uh->uh_handler = handler;
+	install_coproc_handler_static(coproc, uh);
+	return uh;
+}
+
+void
+install_coproc_handler_static(int coproc, struct undefined_handler *uh)
+{
+
+	LIST_INSERT_HEAD(&undefined_handlers[coproc], uh, uh_link);
+}
+
+void
+remove_coproc_handler(void *cookie)
+{
+	struct undefined_handler *uh = cookie;
+
+	LIST_REMOVE(uh, uh_link);
+	free(uh, M_TEMP);
+}
+
+
+static int
+gdb_trapper(u_int addr, u_int insn, struct trapframe *frame, int code)
+{
+	struct thread *td;
+	ksiginfo_t ksi;
+
+	td = (curthread == NULL) ? &thread0 : curthread;
+
+	if (insn == GDB_BREAKPOINT || insn == GDB5_BREAKPOINT) {
+		if (code == FAULT_USER) {
+			ksiginfo_init_trap(&ksi);
+			ksi.ksi_signo = SIGTRAP;
+			ksi.ksi_code = TRAP_BRKPT;
+			ksi.ksi_addr = (u_int32_t *)addr;
+			trapsignal(td, &ksi);
+			return 0;
+		}
+#if 0
+#ifdef KGDB
+		return !kgdb_trap(T_BREAKPOINT, frame);
+#endif
+#endif
+	}
+	return 1;
+}
+
+static struct undefined_handler gdb_uh;
+
+void
+undefined_init()
+{
+	int loop;
+
+	/* Not actually necessary -- the initialiser is just NULL */
+	for (loop = 0; loop < MAX_COPROCS; ++loop)
+		LIST_INIT(&undefined_handlers[loop]);
+
+	/* Install handler for GDB breakpoints */
+	gdb_uh.uh_handler = gdb_trapper;
+	install_coproc_handler_static(0, &gdb_uh);
+}
+
+
+void
+undefinedinstruction(struct trapframe *frame)
+{
+	struct thread *td;
+	u_int fault_pc;
+	int fault_instruction;
+	int fault_code;
+	int coprocessor;
+	struct undefined_handler *uh;
+#ifdef VERBOSE_ARM32
+	int s;
+#endif
+	ksiginfo_t ksi;
+
+	/* Enable interrupts if they were enabled before the exception. */
+	if (__predict_true(frame->tf_spsr & PSR_I) == 0)
+		enable_interrupts(PSR_I);
+	if (__predict_true(frame->tf_spsr & PSR_F) == 0)
+		enable_interrupts(PSR_F);
+
+	PCPU_INC(cnt.v_trap);
+
+	fault_pc = frame->tf_pc;
+
+	/*
+	 * Get the current thread/proc structure or thread0/proc0 if there is
+	 * none.
+	 */
+	td = curthread == NULL ? &thread0 : curthread;
+
+	/*
+	 * Make sure the program counter is correctly aligned so we
+	 * don't take an alignment fault trying to read the opcode.
+	 */
+	if (__predict_false((fault_pc & 3) != 0)) {
+		ksiginfo_init_trap(&ksi);
+		ksi.ksi_signo = SIGILL;
+		ksi.ksi_code = ILL_ILLADR;
+		ksi.ksi_addr = (u_int32_t *)(intptr_t) fault_pc;
+		trapsignal(td, &ksi);
+		userret(td, frame);
+		return;
+	}
+
+	/*
+	 * Should use fuword() here .. but in the interests of squeezing every
+	 * bit of speed we will just use ReadWord(). We know the instruction
+	 * can be read as was just executed so this will never fail unless the
+	 * kernel is screwed up in which case it does not really matter does
+	 * it ?
+	 */
+
+	fault_instruction = *(u_int32_t *)fault_pc;
+
+	/* Update vmmeter statistics */
+#if 0
+	uvmexp.traps++;
+#endif
+	/* Check for coprocessor instruction */
+
+	/*
+	 * According to the datasheets you only need to look at bit 27 of the
+	 * instruction to tell the difference between and undefined
+	 * instruction and a coprocessor instruction following an undefined
+	 * instruction trap.
+	 */
+
+	coprocessor = 0;
+	if ((fault_instruction & (1 << 27)) != 0)
+		coprocessor = (fault_instruction >> 8) & 0x0f;
+#ifdef VFP
+	else {          /* check for special instructions */
+		if (((fault_instruction & 0xfe000000) == 0xf2000000) ||
+		    ((fault_instruction & 0xff100000) == 0xf4000000))
+			coprocessor = 10;       /* vfp / simd */
+	}
+#endif	/* VFP */
+
+	if ((frame->tf_spsr & PSR_MODE) == PSR_USR32_MODE) {
+		/*
+		 * Modify the fault_code to reflect the USR/SVC state at
+		 * time of fault.
+		 */
+		fault_code = FAULT_USER;
+		td->td_frame = frame;
+	} else
+		fault_code = 0;
+
+	/* OK this is were we do something about the instruction. */
+	LIST_FOREACH(uh, &undefined_handlers[coprocessor], uh_link)
+	    if (uh->uh_handler(fault_pc, fault_instruction, frame,
+			       fault_code) == 0)
+		    break;
+
+	if (fault_code & FAULT_USER && fault_instruction == PTRACE_BREAKPOINT) {
+		PROC_LOCK(td->td_proc);
+		_PHOLD(td->td_proc);
+		ptrace_clear_single_step(td);
+		_PRELE(td->td_proc);
+		PROC_UNLOCK(td->td_proc);
+		return;
+	}
+
+	if (uh == NULL && (fault_code & FAULT_USER)) {
+		/* Fault has not been handled */
+		ksiginfo_init_trap(&ksi);
+		ksi.ksi_signo = SIGILL;
+		ksi.ksi_code = ILL_ILLOPC;
+		ksi.ksi_addr = (u_int32_t *)(intptr_t) fault_pc;
+		trapsignal(td, &ksi);
+	}
+
+	if ((fault_code & FAULT_USER) == 0) {
+		if (fault_instruction == KERNEL_BREAKPOINT) {
+#ifdef KDB
+			kdb_trap(T_BREAKPOINT, 0, frame);
+#else
+			printf("No debugger in kernel.\n");
+#endif
+			return;
+		} else
+			panic("Undefined instruction in kernel.\n");
+	}
+
+	userret(td, frame);
+}


Property changes on: trunk/sys/arm/arm/undefined.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/vfp.c
===================================================================
--- trunk/sys/arm/arm/vfp.c	                        (rev 0)
+++ trunk/sys/arm/arm/vfp.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,303 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014 Ian Lepore <ian at freebsd.org>
+ * Copyright (c) 2012 Mark Tinguely
+ *
+ * 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: stable/10/sys/arm/arm/vfp.c 278646 2015-02-13 00:15:13Z ian $");
+
+#ifdef VFP
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/kernel.h>
+
+#include <machine/armreg.h>
+#include <machine/frame.h>
+#include <machine/fp.h>
+#include <machine/pcb.h>
+#include <machine/undefined.h>
+#include <machine/vfp.h>
+
+/* function prototypes */
+static int vfp_bounce(u_int, u_int, struct trapframe *, int);
+static void vfp_restore(struct vfp_state *);
+
+extern int vfp_exists;
+static struct undefined_handler vfp10_uh, vfp11_uh;
+/* If true the VFP unit has 32 double registers, otherwise it has 16 */
+static int is_d32;
+
+/*
+ * About .fpu directives in this file...
+ *
+ * We should need simply .fpu vfpv3, but clang 3.5 has a quirk where setting
+ * vfpv3 doesn't imply that vfp2 features are also available -- both have to be
+ * explicitly set to get all the features of both.  This is probably a bug in
+ * clang, so it may get fixed and require changes here some day.  Other changes
+ * are probably coming in clang too, because there is email and open PRs
+ * indicating they want to completely disable the ability to use .fpu and
+ * similar directives in inline asm.  That would be catastrophic for us,
+ * hopefully they come to their senses.  There was also some discusion of a new
+ * syntax such as .push fpu=vfpv3; ...; .pop fpu; and that would be ideal for
+ * us, better than what we have now really.
+ *
+ * For gcc, each .fpu directive completely overrides the prior directive, unlike
+ * with clang, but luckily on gcc saying v3 implies all the v2 features as well.
+ */
+
+#define fmxr(reg, val) \
+    __asm __volatile("	.fpu vfpv2\n .fpu vfpv3\n"			\
+		     "	vmsr	" __STRING(reg) ", %0"   :: "r"(val));
+
+#define fmrx(reg) \
+({ u_int val = 0;\
+    __asm __volatile(" .fpu vfpv2\n .fpu vfpv3\n"			\
+		     "	vmrs	%0, " __STRING(reg) : "=r"(val));	\
+    val; \
+})
+
+static u_int
+get_coprocessorACR(void)
+{
+	u_int val;
+	__asm __volatile("mrc p15, 0, %0, c1, c0, 2" : "=r" (val) : : "cc");
+	return val;
+}
+
+static void
+set_coprocessorACR(u_int val)
+{
+	__asm __volatile("mcr p15, 0, %0, c1, c0, 2\n\t"
+	 : : "r" (val) : "cc");
+	isb();
+}
+
+
+	/* called for each cpu */
+void
+vfp_init(void)
+{
+	u_int fpsid, fpexc, tmp;
+	u_int coproc, vfp_arch;
+
+	coproc = get_coprocessorACR();
+	coproc |= COPROC10 | COPROC11;
+	set_coprocessorACR(coproc);
+	
+	fpsid = fmrx(fpsid);		/* read the vfp system id */
+	fpexc = fmrx(fpexc);		/* read the vfp exception reg */
+
+	if (!(fpsid & VFPSID_HARDSOFT_IMP)) {
+		vfp_exists = 1;
+		is_d32 = 0;
+		PCPU_SET(vfpsid, fpsid);	/* save the fpsid */
+
+		vfp_arch =
+		    (fpsid & VFPSID_SUBVERSION2_MASK) >> VFPSID_SUBVERSION_OFF;
+
+		if (vfp_arch >= VFP_ARCH3) {
+			tmp = fmrx(mvfr0);
+			PCPU_SET(vfpmvfr0, tmp);
+
+			if ((tmp & VMVFR0_RB_MASK) == 2)
+				is_d32 = 1;
+
+			tmp = fmrx(mvfr1);
+			PCPU_SET(vfpmvfr1, tmp);
+		}
+
+		/* initialize the coprocess 10 and 11 calls
+		 * These are called to restore the registers and enable
+		 * the VFP hardware.
+		 */
+		if (vfp10_uh.uh_handler == NULL) {
+			vfp10_uh.uh_handler = vfp_bounce;
+			vfp11_uh.uh_handler = vfp_bounce;
+			install_coproc_handler_static(10, &vfp10_uh);
+			install_coproc_handler_static(11, &vfp11_uh);
+		}
+	}
+}
+
+SYSINIT(vfp, SI_SUB_CPU, SI_ORDER_ANY, vfp_init, NULL);
+
+
+/* start VFP unit, restore the vfp registers from the PCB  and retry
+ * the instruction
+ */
+static int
+vfp_bounce(u_int addr, u_int insn, struct trapframe *frame, int code)
+{
+	u_int cpu, fpexc;
+	struct pcb *curpcb;
+	ksiginfo_t ksi;
+
+	if ((code & FAULT_USER) == 0)
+		panic("undefined floating point instruction in supervisor mode");
+
+	critical_enter();
+
+	/*
+	 * If the VFP is already on and we got an undefined instruction, then
+	 * something tried to executate a truly invalid instruction that maps to
+	 * the VFP.
+	 */
+	fpexc = fmrx(fpexc);
+	if (fpexc & VFPEXC_EN) {
+		/* Clear any exceptions */
+		fmxr(fpexc, fpexc & ~(VFPEXC_EX | VFPEXC_FP2V));
+
+		/* kill the process - we do not handle emulation */
+		critical_exit();
+
+		if (fpexc & VFPEXC_EX) {
+			/* We have an exception, signal a SIGFPE */
+			ksiginfo_init_trap(&ksi);
+			ksi.ksi_signo = SIGFPE;
+			if (fpexc & VFPEXC_UFC)
+				ksi.ksi_code = FPE_FLTUND;
+			else if (fpexc & VFPEXC_OFC)
+				ksi.ksi_code = FPE_FLTOVF;
+			else if (fpexc & VFPEXC_IOC)
+				ksi.ksi_code = FPE_FLTINV;
+			ksi.ksi_addr = (void *)addr;
+			trapsignal(curthread, &ksi);
+			return 0;
+		}
+
+		return 1;
+	}
+
+	/*
+	 * If the last time this thread used the VFP it was on this core, and
+	 * the last thread to use the VFP on this core was this thread, then the
+	 * VFP state is valid, otherwise restore this thread's state to the VFP.
+	 */
+	fmxr(fpexc, fpexc | VFPEXC_EN);
+	curpcb = curthread->td_pcb;
+	cpu = PCPU_GET(cpu);
+	if (curpcb->pcb_vfpcpu != cpu || curthread != PCPU_GET(fpcurthread)) {
+		vfp_restore(&curpcb->pcb_vfpstate);
+		curpcb->pcb_vfpcpu = cpu;
+		PCPU_SET(fpcurthread, curthread);
+	}
+
+	critical_exit();
+	return (0);
+}
+
+/*
+ * Restore the given state to the VFP hardware.
+ */
+static void
+vfp_restore(struct vfp_state *vfpsave)
+{
+	uint32_t fpexc;
+
+	/* On vfpv3 we may need to restore FPINST and FPINST2 */
+	fpexc = vfpsave->fpexec;
+	if (fpexc & VFPEXC_EX) {
+		fmxr(fpinst, vfpsave->fpinst);
+		if (fpexc & VFPEXC_FP2V)
+			fmxr(fpinst2, vfpsave->fpinst2);
+	}
+	fmxr(fpscr, vfpsave->fpscr);
+
+	__asm __volatile(
+	    " .fpu	vfpv2\n"
+	    " .fpu	vfpv3\n"
+	    " vldmia	%0!, {d0-d15}\n"	/* d0-d15 */
+	    " cmp	%1, #0\n"		/* -D16 or -D32? */
+	    " vldmiane	%0!, {d16-d31}\n"	/* d16-d31 */
+	    " addeq	%0, %0, #128\n"		/* skip missing regs */
+	    : "+&r" (vfpsave) : "r" (is_d32) : "cc"
+	    );
+
+	fmxr(fpexc, fpexc);
+}
+
+/*
+ * If the VFP is on, save its current state and turn it off if requested to do
+ * so.  If the VFP is not on, does not change the values at *vfpsave.  Caller is
+ * responsible for preventing a context switch while this is running.
+ */
+void
+vfp_store(struct vfp_state *vfpsave, boolean_t disable_vfp)
+{
+	uint32_t fpexc;
+
+	fpexc = fmrx(fpexc);		/* Is the vfp enabled? */
+	if (fpexc & VFPEXC_EN) {
+		vfpsave->fpexec = fpexc;
+		vfpsave->fpscr = fmrx(fpscr);
+
+		/* On vfpv3 we may need to save FPINST and FPINST2 */
+		if (fpexc & VFPEXC_EX) {
+			vfpsave->fpinst = fmrx(fpinst);
+			if (fpexc & VFPEXC_FP2V)
+				vfpsave->fpinst2 = fmrx(fpinst2);
+			fpexc &= ~VFPEXC_EX;
+		}
+
+		__asm __volatile(
+		    " .fpu	vfpv2\n"
+		    " .fpu	vfpv3\n"
+		    " vstmia	%0!, {d0-d15}\n"	/* d0-d15 */
+		    " cmp	%1, #0\n"		/* -D16 or -D32? */
+		    " vstmiane	r0!, {d16-d31}\n"	/* d16-d31 */
+		    " addeq	%0, %0, #128\n"		/* skip missing regs */
+		    : "+&r" (vfpsave) : "r" (is_d32) : "cc"
+		    );
+
+		if (disable_vfp)
+			fmxr(fpexc , fpexc & ~VFPEXC_EN);
+	}
+}
+
+/*
+ * The current thread is dying.  If the state currently in the hardware belongs
+ * to the current thread, set fpcurthread to NULL to indicate that the VFP
+ * hardware state does not belong to any thread.  If the VFP is on, turn it off.
+ * Called only from cpu_throw(), so we don't have to worry about a context
+ * switch here.
+ */
+void
+vfp_discard(struct thread *td)
+{
+	u_int tmp;
+
+	if (PCPU_GET(fpcurthread) == td)
+		PCPU_SET(fpcurthread, NULL);
+
+	tmp = fmrx(fpexc);
+	if (tmp & VFPEXC_EN)
+		fmxr(fpexc, tmp & ~VFPEXC_EN);
+}
+
+#endif
+


Property changes on: trunk/sys/arm/arm/vfp.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/arm/vm_machdep.c
===================================================================
--- trunk/sys/arm/arm/vm_machdep.c	                        (rev 0)
+++ trunk/sys/arm/arm/vm_machdep.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,484 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1982, 1986 The Regents of the University of California.
+ * Copyright (c) 1989, 1990 William Jolitz
+ * Copyright (c) 1994 John Dyson
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * the Systems Programming Group of the University of Utah Computer
+ * Science Department, and William Jolitz.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ *	from: @(#)vm_machdep.c	7.3 (Berkeley) 5/13/91
+ *	Utah $Hdr: vm_machdep.c 1.16.1.1 89/06/23$
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/arm/vm_machdep.c 283339 2015-05-23 23:27:00Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/proc.h>
+#include <sys/socketvar.h>
+#include <sys/sf_buf.h>
+#include <sys/syscall.h>
+#include <sys/sysctl.h>
+#include <sys/sysent.h>
+#include <sys/unistd.h>
+#include <machine/cpu.h>
+#include <machine/frame.h>
+#include <machine/pcb.h>
+#include <machine/sysarch.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/vm_extern.h>
+#include <vm/vm_kern.h>
+#include <vm/vm_page.h>
+#include <vm/vm_map.h>
+#include <vm/vm_param.h>
+#include <vm/vm_pageout.h>
+#include <vm/uma.h>
+#include <vm/uma_int.h>
+
+#include <machine/md_var.h>
+#include <machine/vfp.h>
+
+/*
+ * struct switchframe and trapframe must both be a multiple of 8
+ * for correct stack alignment.
+ */
+CTASSERT(sizeof(struct switchframe) == 48);
+CTASSERT(sizeof(struct trapframe) == 80);
+
+#ifndef NSFBUFS
+#define NSFBUFS		(512 + maxusers * 16)
+#endif
+
+static int nsfbufs;
+static int nsfbufspeak;
+static int nsfbufsused;
+
+SYSCTL_INT(_kern_ipc, OID_AUTO, nsfbufs, CTLFLAG_RDTUN, &nsfbufs, 0,
+    "Maximum number of sendfile(2) sf_bufs available");
+SYSCTL_INT(_kern_ipc, OID_AUTO, nsfbufspeak, CTLFLAG_RD, &nsfbufspeak, 0,
+    "Number of sendfile(2) sf_bufs at peak usage");
+SYSCTL_INT(_kern_ipc, OID_AUTO, nsfbufsused, CTLFLAG_RD, &nsfbufsused, 0,
+    "Number of sendfile(2) sf_bufs in use");
+
+static void     sf_buf_init(void *arg);
+SYSINIT(sock_sf, SI_SUB_MBUF, SI_ORDER_ANY, sf_buf_init, NULL);
+
+LIST_HEAD(sf_head, sf_buf);
+
+/*
+ * A hash table of active sendfile(2) buffers
+ */
+static struct sf_head *sf_buf_active;
+static u_long sf_buf_hashmask;
+
+#define SF_BUF_HASH(m)  (((m) - vm_page_array) & sf_buf_hashmask)
+
+static TAILQ_HEAD(, sf_buf) sf_buf_freelist;
+static u_int    sf_buf_alloc_want;
+
+/*
+ * A lock used to synchronize access to the hash table and free list
+ */
+static struct mtx sf_buf_lock;
+
+/*
+ * Finish a fork operation, with process p2 nearly set up.
+ * Copy and update the pcb, set up the stack so that the child
+ * ready to run and return to user mode.
+ */
+void
+cpu_fork(register struct thread *td1, register struct proc *p2,
+    struct thread *td2, int flags)
+{
+	struct pcb *pcb2;
+	struct trapframe *tf;
+	struct mdproc *mdp2;
+
+	if ((flags & RFPROC) == 0)
+		return;
+
+	/* Point the pcb to the top of the stack */
+	pcb2 = (struct pcb *)
+	    (td2->td_kstack + td2->td_kstack_pages * PAGE_SIZE) - 1;
+#ifdef __XSCALE__
+#ifndef CPU_XSCALE_CORE3
+	pmap_use_minicache(td2->td_kstack, td2->td_kstack_pages * PAGE_SIZE);
+#endif
+#endif
+	td2->td_pcb = pcb2;
+	
+	/* Clone td1's pcb */
+	bcopy(td1->td_pcb, pcb2, sizeof(*pcb2));
+	
+	/* Point to mdproc and then copy over td1's contents */
+	mdp2 = &p2->p_md;
+	bcopy(&td1->td_proc->p_md, mdp2, sizeof(*mdp2));
+
+	/* Point the frame to the stack in front of pcb and copy td1's frame */
+	td2->td_frame = (struct trapframe *)pcb2 - 1;
+	*td2->td_frame = *td1->td_frame;
+
+	/*
+	 * Create a new fresh stack for the new process.
+	 * Copy the trap frame for the return to user mode as if from a
+	 * syscall.  This copies most of the user mode register values.
+	 */
+	pmap_set_pcb_pagedir(vmspace_pmap(p2->p_vmspace), pcb2);
+	pcb2->pcb_regs.sf_r4 = (register_t)fork_return;
+	pcb2->pcb_regs.sf_r5 = (register_t)td2;
+	pcb2->pcb_regs.sf_lr = (register_t)fork_trampoline;
+	pcb2->pcb_regs.sf_sp = STACKALIGN(td2->td_frame);
+
+	pcb2->pcb_vfpcpu = -1;
+	pcb2->pcb_vfpstate.fpscr = VFPSCR_DN | VFPSCR_FZ;
+	
+	tf = td2->td_frame;
+	tf->tf_spsr &= ~PSR_C;
+	tf->tf_r0 = 0;
+	tf->tf_r1 = 0;
+
+
+	/* Setup to release spin count in fork_exit(). */
+	td2->td_md.md_spinlock_count = 1;
+	td2->td_md.md_saved_cspr = PSR_SVC32_MODE;;
+#ifdef ARM_TP_ADDRESS
+	td2->td_md.md_tp = *(register_t *)ARM_TP_ADDRESS;
+#else
+	td2->td_md.md_tp = td1->td_md.md_tp;
+#endif
+}
+				
+void
+cpu_thread_swapin(struct thread *td)
+{
+}
+
+void
+cpu_thread_swapout(struct thread *td)
+{
+}
+
+/*
+ * Detatch mapped page and release resources back to the system.
+ */
+void
+sf_buf_free(struct sf_buf *sf)
+{
+
+	 mtx_lock(&sf_buf_lock);
+	 sf->ref_count--;
+	 if (sf->ref_count == 0) {
+		 TAILQ_INSERT_TAIL(&sf_buf_freelist, sf, free_entry);
+		 nsfbufsused--;
+		 pmap_kremove(sf->kva);
+		 sf->m = NULL;
+		 LIST_REMOVE(sf, list_entry);
+		 if (sf_buf_alloc_want > 0)
+			 wakeup(&sf_buf_freelist);
+	 }
+	 mtx_unlock(&sf_buf_lock);
+}
+
+/*
+ * Allocate a pool of sf_bufs (sendfile(2) or "super-fast" if you prefer. :-))
+ */
+static void
+sf_buf_init(void *arg)
+{
+	struct sf_buf *sf_bufs;
+	vm_offset_t sf_base;
+	int i;
+
+	nsfbufs = NSFBUFS;
+	TUNABLE_INT_FETCH("kern.ipc.nsfbufs", &nsfbufs);
+		
+	sf_buf_active = hashinit(nsfbufs, M_TEMP, &sf_buf_hashmask);
+	TAILQ_INIT(&sf_buf_freelist);
+	sf_base = kva_alloc(nsfbufs * PAGE_SIZE);
+	sf_bufs = malloc(nsfbufs * sizeof(struct sf_buf), M_TEMP,
+	    M_NOWAIT | M_ZERO);
+	for (i = 0; i < nsfbufs; i++) {
+		sf_bufs[i].kva = sf_base + i * PAGE_SIZE;
+		TAILQ_INSERT_TAIL(&sf_buf_freelist, &sf_bufs[i], free_entry);
+	}
+	sf_buf_alloc_want = 0;
+	mtx_init(&sf_buf_lock, "sf_buf", NULL, MTX_DEF);
+}
+
+/*
+ * Get an sf_buf from the freelist. Will block if none are available.
+ */
+struct sf_buf *
+sf_buf_alloc(struct vm_page *m, int flags)
+{
+	struct sf_head *hash_list;
+	struct sf_buf *sf;
+	int error;
+
+	hash_list = &sf_buf_active[SF_BUF_HASH(m)];
+	mtx_lock(&sf_buf_lock);
+	LIST_FOREACH(sf, hash_list, list_entry) {
+		if (sf->m == m) {
+			sf->ref_count++;
+			if (sf->ref_count == 1) {
+				TAILQ_REMOVE(&sf_buf_freelist, sf, free_entry);
+				nsfbufsused++;
+				nsfbufspeak = imax(nsfbufspeak, nsfbufsused);
+			}
+			goto done;
+		}
+	}
+	while ((sf = TAILQ_FIRST(&sf_buf_freelist)) == NULL) {
+		if (flags & SFB_NOWAIT)
+			goto done;
+		sf_buf_alloc_want++;
+		SFSTAT_INC(sf_allocwait);
+		error = msleep(&sf_buf_freelist, &sf_buf_lock,
+		    (flags & SFB_CATCH) ? PCATCH | PVM : PVM, "sfbufa", 0);
+		sf_buf_alloc_want--;
+	
+
+		/*
+		 * If we got a signal, don't risk going back to sleep.
+		 */
+		if (error)
+			goto done;
+	}
+	TAILQ_REMOVE(&sf_buf_freelist, sf, free_entry);
+	if (sf->m != NULL)
+		LIST_REMOVE(sf, list_entry);
+	LIST_INSERT_HEAD(hash_list, sf, list_entry);
+	sf->ref_count = 1;
+	sf->m = m;
+	nsfbufsused++;
+	nsfbufspeak = imax(nsfbufspeak, nsfbufsused);
+	pmap_kenter(sf->kva, VM_PAGE_TO_PHYS(sf->m));
+done:
+	mtx_unlock(&sf_buf_lock);
+	return (sf);
+}
+
+void
+cpu_set_syscall_retval(struct thread *td, int error)
+{
+	struct trapframe *frame;
+	int fixup;
+#ifdef __ARMEB__
+	u_int call;
+#endif
+
+	frame = td->td_frame;
+	fixup = 0;
+
+#ifdef __ARMEB__
+	/*
+	 * __syscall returns an off_t while most other syscalls return an
+	 * int. As an off_t is 64-bits and an int is 32-bits we need to
+	 * place the returned data into r1. As the lseek and frerebsd6_lseek
+	 * syscalls also return an off_t they do not need this fixup.
+	 */
+#ifdef __ARM_EABI__
+	call = frame->tf_r7;
+#else
+	call = *(u_int32_t *)(frame->tf_pc - INSN_SIZE) & 0x000fffff;
+#endif
+	if (call == SYS___syscall) {
+		register_t *ap = &frame->tf_r0;
+		register_t code = ap[_QUAD_LOWWORD];
+		if (td->td_proc->p_sysent->sv_mask)
+			code &= td->td_proc->p_sysent->sv_mask;
+		fixup = (code != SYS_freebsd6_lseek && code != SYS_lseek)
+		    ? 1 : 0;
+	}
+#endif
+
+	switch (error) {
+	case 0:
+		if (fixup) {
+			frame->tf_r0 = 0;
+			frame->tf_r1 = td->td_retval[0];
+		} else {
+			frame->tf_r0 = td->td_retval[0];
+			frame->tf_r1 = td->td_retval[1];
+		}
+		frame->tf_spsr &= ~PSR_C;   /* carry bit */
+		break;
+	case ERESTART:
+		/*
+		 * Reconstruct the pc to point at the swi.
+		 */
+		frame->tf_pc -= INSN_SIZE;
+		break;
+	case EJUSTRETURN:
+		/* nothing to do */
+		break;
+	default:
+		frame->tf_r0 = error;
+		frame->tf_spsr |= PSR_C;    /* carry bit */
+		break;
+	}
+}
+
+/*
+ * Initialize machine state (pcb and trap frame) for a new thread about to
+ * upcall. Put enough state in the new thread's PCB to get it to go back
+ * userret(), where we can intercept it again to set the return (upcall)
+ * Address and stack, along with those from upcals that are from other sources
+ * such as those generated in thread_userret() itself.
+ */
+void
+cpu_set_upcall(struct thread *td, struct thread *td0)
+{
+
+	bcopy(td0->td_frame, td->td_frame, sizeof(struct trapframe));
+	bcopy(td0->td_pcb, td->td_pcb, sizeof(struct pcb));
+
+	td->td_pcb->pcb_regs.sf_r4 = (register_t)fork_return;
+	td->td_pcb->pcb_regs.sf_r5 = (register_t)td;
+	td->td_pcb->pcb_regs.sf_lr = (register_t)fork_trampoline;
+	td->td_pcb->pcb_regs.sf_sp = STACKALIGN(td->td_frame);
+
+	td->td_frame->tf_spsr &= ~PSR_C;
+	td->td_frame->tf_r0 = 0;
+
+	/* Setup to release spin count in fork_exit(). */
+	td->td_md.md_spinlock_count = 1;
+	td->td_md.md_saved_cspr = PSR_SVC32_MODE;
+}
+
+/*
+ * Set that machine state for performing an upcall that has to
+ * be done in thread_userret() so that those upcalls generated
+ * in thread_userret() itself can be done as well.
+ */
+void
+cpu_set_upcall_kse(struct thread *td, void (*entry)(void *), void *arg,
+	stack_t *stack)
+{
+	struct trapframe *tf = td->td_frame;
+
+	tf->tf_usr_sp = STACKALIGN((int)stack->ss_sp + stack->ss_size);
+	tf->tf_pc = (int)entry;
+	tf->tf_r0 = (int)arg;
+	tf->tf_spsr = PSR_USR32_MODE;
+}
+
+int
+cpu_set_user_tls(struct thread *td, void *tls_base)
+{
+
+	td->td_md.md_tp = (register_t)tls_base;
+	if (td == curthread) {
+		critical_enter();
+#ifdef ARM_TP_ADDRESS
+		*(register_t *)ARM_TP_ADDRESS = (register_t)tls_base;
+#else
+		set_tls(tls_base);
+#endif
+		critical_exit();
+	}
+	return (0);
+}
+
+void
+cpu_thread_exit(struct thread *td)
+{
+}
+
+void
+cpu_thread_alloc(struct thread *td)
+{
+	td->td_pcb = (struct pcb *)(td->td_kstack + td->td_kstack_pages *
+	    PAGE_SIZE) - 1;
+	/*
+	 * Ensure td_frame is aligned to an 8 byte boundary as it will be
+	 * placed into the stack pointer which must be 8 byte aligned in
+	 * the ARM EABI.
+	 */
+	td->td_frame = (struct trapframe *)((caddr_t)td->td_pcb) - 1;
+
+#ifdef __XSCALE__
+#ifndef CPU_XSCALE_CORE3
+	pmap_use_minicache(td->td_kstack, td->td_kstack_pages * PAGE_SIZE);
+#endif
+#endif
+}
+
+void
+cpu_thread_free(struct thread *td)
+{
+}
+
+void
+cpu_thread_clean(struct thread *td)
+{
+}
+
+/*
+ * Intercept the return address from a freshly forked process that has NOT
+ * been scheduled yet.
+ *
+ * This is needed to make kernel threads stay in kernel mode.
+ */
+void
+cpu_set_fork_handler(struct thread *td, void (*func)(void *), void *arg)
+{
+	td->td_pcb->pcb_regs.sf_r4 = (register_t)func;	/* function */
+	td->td_pcb->pcb_regs.sf_r5 = (register_t)arg;	/* first arg */
+}
+
+/*
+ * Software interrupt handler for queued VM system processing.
+ */
+void
+swi_vm(void *dummy)
+{
+	
+	if (busdma_swi_pending)
+		busdma_swi();
+}
+
+void
+cpu_exit(struct thread *td)
+{
+}
+


Property changes on: trunk/sys/arm/arm/vm_machdep.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91.c
===================================================================
--- trunk/sys/arm/at91/at91.c	                        (rev 0)
+++ trunk/sys/arm/at91/at91.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,529 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2005 Olivier Houchard.  All rights reserved.
+ * Copyright (c) 2010 Greg Ansley.  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 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 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: stable/10/sys/arm/at91/at91.c 278727 2015-02-13 22:32:02Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+
+#include <vm/vm.h>
+#include <vm/vm_kern.h>
+#include <vm/pmap.h>
+#include <vm/vm_page.h>
+#include <vm/vm_extern.h>
+
+#include <machine/armreg.h>
+#define	_ARM32_BUS_DMA_PRIVATE
+#include <machine/bus.h>
+#include <machine/devmap.h>
+#include <machine/intr.h>
+
+#include <arm/at91/at91var.h>
+#include <arm/at91/at91_pmcvar.h>
+#include <arm/at91/at91_aicreg.h>
+
+uint32_t at91_master_clock;
+
+static int
+at91_bs_map(bus_space_tag_t tag, bus_addr_t bpa, bus_size_t size, int flags,
+    bus_space_handle_t *bshp)
+{
+	vm_paddr_t pa, endpa;
+
+	pa = trunc_page(bpa);
+	if (pa >= AT91_PA_BASE + 0xff00000) {
+		*bshp = bpa - AT91_PA_BASE + AT91_BASE;
+		return (0);
+	}
+	if (pa >= AT91_BASE + 0xff00000) {
+		*bshp = bpa;
+		return (0);
+	}
+	endpa = round_page(bpa + size);
+
+	*bshp = (vm_offset_t)pmap_mapdev(pa, endpa - pa) + (bpa - pa);
+
+	return (0);
+}
+
+static void
+at91_bs_unmap(bus_space_tag_t tag, bus_space_handle_t h, bus_size_t size)
+{
+	vm_offset_t va;
+
+	va = (vm_offset_t)h;
+	if (va >= AT91_BASE && va <= AT91_BASE + 0xff00000)
+		return;
+	pmap_unmapdev(va, size);
+}
+
+static int
+at91_bs_subregion(bus_space_tag_t tag, bus_space_handle_t bsh, bus_size_t offset,
+    bus_size_t size, bus_space_handle_t *nbshp)
+{
+
+	*nbshp = bsh + offset;
+	return (0);
+}
+
+static void
+at91_barrier(bus_space_tag_t tag, bus_space_handle_t bsh, bus_size_t size, bus_size_t b,
+    int a)
+{
+}
+
+struct arm32_dma_range *
+bus_dma_get_range(void)
+{
+
+	return (NULL);
+}
+
+int
+bus_dma_get_range_nb(void)
+{
+	return (0);
+}
+
+bs_protos(generic);
+
+struct bus_space at91_bs_tag = {
+	/* privdata is whatever the implementer wants; unused in base tag */
+	.bs_privdata	= NULL,
+
+	/* mapping/unmapping */
+	.bs_map		= at91_bs_map,
+	.bs_unmap	= at91_bs_unmap,
+	.bs_subregion	= at91_bs_subregion,
+
+	/* allocation/deallocation */
+	.bs_alloc	= generic_bs_alloc,
+	.bs_free	= generic_bs_free,
+
+	/* barrier */
+	.bs_barrier	= at91_barrier,
+
+	/* read (single) */
+	.bs_r_1		= NULL,	/* Use inline code in bus.h */
+	.bs_r_2		= NULL,	/* Use inline code in bus.h */
+	.bs_r_4		= NULL,	/* Use inline code in bus.h */
+	.bs_r_8		= NULL,	/* Use inline code in bus.h */
+
+	/* read multiple */
+	.bs_rm_1	= generic_bs_rm_1,
+	.bs_rm_2	= generic_bs_rm_2,
+	.bs_rm_4	= generic_bs_rm_4,
+	.bs_rm_8	= BS_UNIMPLEMENTED,
+
+	/* read region */
+	.bs_rr_1	= generic_bs_rr_1,
+	.bs_rr_2	= generic_bs_rr_2,
+	.bs_rr_4	= generic_bs_rr_4,
+	.bs_rr_8	= BS_UNIMPLEMENTED,
+
+	/* write (single) */
+	.bs_w_1		= NULL,	/* Use inline code in bus.h */
+	.bs_w_2		= NULL,	/* Use inline code in bus.h */
+	.bs_w_4		= NULL,	/* Use inline code in bus.h */
+	.bs_w_8		= NULL,	/* Use inline code in bus.h */
+
+	/* write multiple */
+	.bs_wm_1	= generic_bs_wm_1,
+	.bs_wm_2	= generic_bs_wm_2,
+	.bs_wm_4	= generic_bs_wm_4,
+	.bs_wm_8	= BS_UNIMPLEMENTED,
+
+	/* write region */
+	.bs_wr_1	= generic_bs_wr_1,
+	.bs_wr_2	= generic_bs_wr_2,
+	.bs_wr_4	= generic_bs_wr_4,
+	.bs_wr_8	= BS_UNIMPLEMENTED,
+
+	/* set multiple */
+	.bs_sm_1	= BS_UNIMPLEMENTED,
+	.bs_sm_2	= BS_UNIMPLEMENTED,
+	.bs_sm_4	= BS_UNIMPLEMENTED,
+	.bs_sm_8	= BS_UNIMPLEMENTED,
+
+	/* set region */
+	.bs_sr_1	= generic_bs_sr_1,
+	.bs_sr_2	= generic_bs_sr_2,
+	.bs_sr_4	= generic_bs_sr_4,
+	.bs_sr_8	= BS_UNIMPLEMENTED,
+
+	/* copy */
+	.bs_c_1		= BS_UNIMPLEMENTED,
+	.bs_c_2		= generic_bs_c_2,
+	.bs_c_4		= BS_UNIMPLEMENTED,
+	.bs_c_8		= BS_UNIMPLEMENTED,
+
+	/* read stream (single) */
+	.bs_r_1_s	= NULL,   /* Use inline code in bus.h */ 
+	.bs_r_2_s	= NULL,   /* Use inline code in bus.h */ 
+	.bs_r_4_s	= NULL,   /* Use inline code in bus.h */ 
+	.bs_r_8_s	= NULL,   /* Use inline code in bus.h */ 
+
+	/* read multiple stream */
+	.bs_rm_1_s	= generic_bs_rm_1,
+	.bs_rm_2_s	= generic_bs_rm_2,
+	.bs_rm_4_s	= generic_bs_rm_4,
+	.bs_rm_8_s	= BS_UNIMPLEMENTED,
+
+	/* read region stream */
+	.bs_rr_1_s	= generic_bs_rr_1,
+	.bs_rr_2_s	= generic_bs_rr_2,
+	.bs_rr_4_s	= generic_bs_rr_4,
+	.bs_rr_8_s	= BS_UNIMPLEMENTED,
+
+	/* write stream (single) */
+	.bs_w_1_s	= NULL,   /* Use inline code in bus.h */ 
+	.bs_w_2_s	= NULL,   /* Use inline code in bus.h */ 
+	.bs_w_4_s	= NULL,   /* Use inline code in bus.h */ 
+	.bs_w_8_s	= NULL,   /* Use inline code in bus.h */ 
+
+	/* write multiple stream */
+	.bs_wm_1_s	= generic_bs_wm_1,
+	.bs_wm_2_s	= generic_bs_wm_2,
+	.bs_wm_4_s	= generic_bs_wm_4,
+	.bs_wm_8_s	= BS_UNIMPLEMENTED,
+
+	/* write region stream */
+	.bs_wr_1_s	= generic_bs_wr_1,
+	.bs_wr_2_s	= generic_bs_wr_2,
+	.bs_wr_4_s	= generic_bs_wr_4,
+	.bs_wr_8_s	= BS_UNIMPLEMENTED,
+};
+
+#ifndef FDT
+
+static struct at91_softc *at91_softc;
+
+static void at91_eoi(void *);
+
+static int
+at91_probe(device_t dev)
+{
+
+	device_set_desc(dev, soc_info.name);
+	return (BUS_PROBE_NOWILDCARD);
+}
+
+static void
+at91_identify(driver_t *drv, device_t parent)
+{
+	
+	BUS_ADD_CHILD(parent, 0, "atmelarm", 0);
+}
+
+static void
+at91_cpu_add_builtin_children(device_t dev, const struct cpu_devs *walker)
+{
+	int i;
+
+	for (i = 1; walker->name; i++, walker++) {
+		at91_add_child(dev, i, walker->name, walker->unit,
+		    walker->mem_base, walker->mem_len, walker->irq0,
+		    walker->irq1, walker->irq2);
+	}
+}
+
+static int
+at91_attach(device_t dev)
+{
+	struct at91_softc *sc = device_get_softc(dev);
+
+	arm_post_filter = at91_eoi;
+
+	at91_softc = sc;
+	sc->sc_st = &at91_bs_tag;
+	sc->sc_sh = AT91_BASE;
+	sc->sc_aic_sh = AT91_BASE + AT91_SYS_BASE;
+	sc->dev = dev;
+
+	sc->sc_irq_rman.rm_type = RMAN_ARRAY;
+	sc->sc_irq_rman.rm_descr = "AT91 IRQs";
+	if (rman_init(&sc->sc_irq_rman) != 0 ||
+	    rman_manage_region(&sc->sc_irq_rman, 1, 31) != 0)
+		panic("at91_attach: failed to set up IRQ rman");
+
+	sc->sc_mem_rman.rm_type = RMAN_ARRAY;
+	sc->sc_mem_rman.rm_descr = "AT91 Memory";
+	if (rman_init(&sc->sc_mem_rman) != 0)
+		panic("at91_attach: failed to set up memory rman");
+	/*
+	 * Manage the physical space, defined as being everything that isn't
+	 * DRAM.
+	 */
+	if (rman_manage_region(&sc->sc_mem_rman, 0, PHYSADDR - 1) != 0)
+		panic("at91_attach: failed to set up memory rman");
+	if (rman_manage_region(&sc->sc_mem_rman, PHYSADDR + (256 << 20),
+	    0xfffffffful) != 0)
+		panic("at91_attach: failed to set up memory rman");
+
+        /*
+         * Add this device's children...
+         */
+	at91_cpu_add_builtin_children(dev, soc_info.soc_data->soc_children);
+	soc_info.soc_data->soc_clock_init();
+
+	bus_generic_probe(dev);
+	bus_generic_attach(dev);
+	enable_interrupts(PSR_I | PSR_F);
+	return (0);
+}
+
+static struct resource *
+at91_alloc_resource(device_t dev, device_t child, int type, int *rid,
+    u_long start, u_long end, u_long count, u_int flags)
+{
+	struct at91_softc *sc = device_get_softc(dev);
+	struct resource_list_entry *rle;
+	struct at91_ivar *ivar = device_get_ivars(child);
+	struct resource_list *rl = &ivar->resources;
+	bus_space_handle_t bsh;
+
+	if (device_get_parent(child) != dev)
+		return (BUS_ALLOC_RESOURCE(device_get_parent(dev), child,
+		    type, rid, start, end, count, flags));
+	
+	rle = resource_list_find(rl, type, *rid);
+	if (rle == NULL)
+		return (NULL);
+	if (rle->res)
+		panic("Resource rid %d type %d already in use", *rid, type);
+	if (start == 0UL && end == ~0UL) {
+		start = rle->start;
+		count = ulmax(count, rle->count);
+		end = ulmax(rle->end, start + count - 1);
+	}
+	switch (type)
+	{
+	case SYS_RES_IRQ:
+		rle->res = rman_reserve_resource(&sc->sc_irq_rman,
+		    start, end, count, flags, child);
+		break;
+	case SYS_RES_MEMORY:
+		rle->res = rman_reserve_resource(&sc->sc_mem_rman,
+		    start, end, count, flags, child);
+		if (rle->res != NULL) {
+			bus_space_map(&at91_bs_tag, start,
+			    rman_get_size(rle->res), 0, &bsh);
+			rman_set_bustag(rle->res, &at91_bs_tag);
+			rman_set_bushandle(rle->res, bsh);
+		}
+		break;
+	}
+	if (rle->res) {
+		rle->start = rman_get_start(rle->res);
+		rle->end = rman_get_end(rle->res);
+		rle->count = count;
+		rman_set_rid(rle->res, *rid);
+	}
+	return (rle->res);
+}
+
+static struct resource_list *
+at91_get_resource_list(device_t dev, device_t child)
+{
+	struct at91_ivar *ivar;
+
+	ivar = device_get_ivars(child);
+	return (&(ivar->resources));
+}
+
+static int
+at91_release_resource(device_t dev, device_t child, int type,
+    int rid, struct resource *r)
+{
+	struct resource_list *rl;
+	struct resource_list_entry *rle;
+
+	rl = at91_get_resource_list(dev, child);
+	if (rl == NULL)
+		return (EINVAL);
+	rle = resource_list_find(rl, type, rid);
+	if (rle == NULL)
+		return (EINVAL);
+	rman_release_resource(r);
+	rle->res = NULL;
+	return (0);
+}
+
+static int
+at91_setup_intr(device_t dev, device_t child,
+    struct resource *ires, int flags, driver_filter_t *filt,
+    driver_intr_t *intr, void *arg, void **cookiep)
+{
+	int error;
+
+	if (rman_get_start(ires) == AT91_IRQ_SYSTEM && filt == NULL)
+		panic("All system interrupt ISRs must be FILTER");
+	error = BUS_SETUP_INTR(device_get_parent(dev), child, ires, flags,
+	    filt, intr, arg, cookiep);
+	if (error)
+		return (error);
+
+	return (0);
+}
+
+static int
+at91_teardown_intr(device_t dev, device_t child, struct resource *res,
+    void *cookie)
+{
+	struct at91_softc *sc = device_get_softc(dev);
+
+	bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_IDCR,
+	    1 << rman_get_start(res));
+	return (BUS_TEARDOWN_INTR(device_get_parent(dev), child, res, cookie));
+}
+
+static int
+at91_activate_resource(device_t bus, device_t child, int type, int rid,
+    struct resource *r)
+{
+#if 0
+	u_long p;
+	int error;
+	
+	if (type == SYS_RES_MEMORY) {
+		error = bus_space_map(rman_get_bustag(r),
+		    rman_get_bushandle(r), rman_get_size(r), 0, &p);
+		if (error)
+			return (error);
+		rman_set_bushandle(r, p);
+	}
+#endif	
+	return (rman_activate_resource(r));
+}
+
+static int
+at91_print_child(device_t dev, device_t child)
+{
+	struct at91_ivar *ivars;
+	struct resource_list *rl;
+	int retval = 0;
+
+	ivars = device_get_ivars(child);
+	rl = &ivars->resources;
+
+	retval += bus_print_child_header(dev, child);
+
+	retval += resource_list_print_type(rl, "port", SYS_RES_IOPORT, "%#lx");
+	retval += resource_list_print_type(rl, "mem", SYS_RES_MEMORY, "%#lx");
+	retval += resource_list_print_type(rl, "irq", SYS_RES_IRQ, "%ld");
+	if (device_get_flags(dev))
+		retval += printf(" flags %#x", device_get_flags(dev));
+
+	retval += bus_print_child_footer(dev, child);
+
+	return (retval);
+}
+
+static void
+at91_eoi(void *unused)
+{
+	bus_space_write_4(at91_softc->sc_st, at91_softc->sc_aic_sh,
+	    IC_EOICR, 0);
+}
+
+void
+at91_add_child(device_t dev, int prio, const char *name, int unit,
+    bus_addr_t addr, bus_size_t size, int irq0, int irq1, int irq2)
+{
+	device_t kid;
+	struct at91_ivar *ivar;
+
+	kid = device_add_child_ordered(dev, prio, name, unit);
+	if (kid == NULL) {
+	    printf("Can't add child %s%d ordered\n", name, unit);
+	    return;
+	}
+	ivar = malloc(sizeof(*ivar), M_DEVBUF, M_NOWAIT | M_ZERO);
+	if (ivar == NULL) {
+		device_delete_child(dev, kid);
+		printf("Can't add alloc ivar\n");
+		return;
+	}
+	device_set_ivars(kid, ivar);
+	resource_list_init(&ivar->resources);
+	if (irq0 != -1) {
+		bus_set_resource(kid, SYS_RES_IRQ, 0, irq0, 1);
+		if (irq0 != AT91_IRQ_SYSTEM)
+			at91_pmc_clock_add(device_get_nameunit(kid), irq0, 0);
+	}
+	if (irq1 != 0)
+		bus_set_resource(kid, SYS_RES_IRQ, 1, irq1, 1);
+	if (irq2 != 0)
+		bus_set_resource(kid, SYS_RES_IRQ, 2, irq2, 1);
+	/*
+	 * Special case for on-board devices. These have their address
+	 * defined relative to AT91_PA_BASE in all the register files we
+	 * have. We could change this, but that's a lot of effort which
+	 * will be obsoleted when FDT arrives.
+	 */
+	if (addr != 0 && addr < 0x10000000 && addr >= 0x0f000000) 
+		addr += AT91_PA_BASE;
+	if (addr != 0)
+		bus_set_resource(kid, SYS_RES_MEMORY, 0, addr, size);
+}
+
+static device_method_t at91_methods[] = {
+	DEVMETHOD(device_probe, at91_probe),
+	DEVMETHOD(device_attach, at91_attach),
+	DEVMETHOD(device_identify, at91_identify),
+
+	DEVMETHOD(bus_alloc_resource, at91_alloc_resource),
+	DEVMETHOD(bus_setup_intr, at91_setup_intr),
+	DEVMETHOD(bus_teardown_intr, at91_teardown_intr),
+	DEVMETHOD(bus_activate_resource, at91_activate_resource),
+	DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+	DEVMETHOD(bus_get_resource_list,at91_get_resource_list),
+	DEVMETHOD(bus_set_resource,	bus_generic_rl_set_resource),
+	DEVMETHOD(bus_get_resource,	bus_generic_rl_get_resource),
+	DEVMETHOD(bus_release_resource,	at91_release_resource),
+	DEVMETHOD(bus_print_child,	at91_print_child),
+
+	{0, 0},
+};
+
+static driver_t at91_driver = {
+	"atmelarm",
+	at91_methods,
+	sizeof(struct at91_softc),
+};
+
+static devclass_t at91_devclass;
+
+DRIVER_MODULE(atmelarm, nexus, at91_driver, at91_devclass, 0, 0);
+#endif


Property changes on: trunk/sys/arm/at91/at91.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91_aic.c
===================================================================
--- trunk/sys/arm/at91/at91_aic.c	                        (rev 0)
+++ trunk/sys/arm/at91/at91_aic.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,190 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014 Warner Losh.  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 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 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: stable/10/sys/arm/at91/at91_aic.c 278613 2015-02-12 03:50:33Z ian $");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/resource.h>
+#include <sys/systm.h>
+#include <sys/rman.h>
+
+#include <machine/armreg.h>
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+#include <machine/frame.h>
+#include <machine/intr.h>
+#include <machine/resource.h>
+
+#include <arm/at91/at91var.h>
+#include <arm/at91/at91_aicreg.h>
+
+#ifdef FDT
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+#endif
+
+static struct aic_softc {
+	struct resource	*mem_res;	/* Memory resource */
+	void		*intrhand;	/* Interrupt handle */
+	device_t	sc_dev;
+} *sc;
+
+static inline uint32_t
+RD4(struct aic_softc *sc, bus_size_t off)
+{
+
+	return (bus_read_4(sc->mem_res, off));
+}
+
+static inline void
+WR4(struct aic_softc *sc, bus_size_t off, uint32_t val)
+{
+
+	bus_write_4(sc->mem_res, off, val);
+}
+
+void
+arm_mask_irq(uintptr_t nb)
+{
+
+	WR4(sc, IC_IDCR, 1 << nb);
+}
+
+int
+arm_get_next_irq(int last __unused)
+{
+	int status;
+	int irq;
+	
+	irq = RD4(sc, IC_IVR);
+	status = RD4(sc, IC_ISR);
+	if (status == 0) {
+		WR4(sc, IC_EOICR, 1);
+		return (-1);
+	}
+	return (irq);
+}
+
+void
+arm_unmask_irq(uintptr_t nb)
+{
+	
+	WR4(sc, IC_IECR, 1 << nb);
+	WR4(sc, IC_EOICR, 0);
+}
+
+static int
+at91_aic_probe(device_t dev)
+{
+#ifdef FDT
+	if (!ofw_bus_is_compatible(dev, "atmel,at91rm9200-aic"))
+		return (ENXIO);
+#endif
+	device_set_desc(dev, "AIC");
+        return (0);
+}
+
+static int
+at91_aic_attach(device_t dev)
+{
+	int i, rid, err = 0;
+
+	device_printf(dev, "Attach %d\n", bus_current_pass);
+
+	sc = device_get_softc(dev);
+	sc->sc_dev = dev;
+
+	rid = 0;
+	sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	    RF_ACTIVE);
+
+	if (sc->mem_res == NULL)
+		panic("couldn't allocate register resources");
+
+	/*
+	 * Setup the interrupt table.
+	 */
+	if (soc_info.soc_data == NULL || soc_info.soc_data->soc_irq_prio == NULL)
+		panic("Interrupt priority table missing\n");
+	for (i = 0; i < 32; i++) {
+		WR4(sc, IC_SVR + i * 4, i);
+		/* Priority. */
+		WR4(sc, IC_SMR + i * 4, soc_info.soc_data->soc_irq_prio[i]);
+		if (i < 8)
+			WR4(sc, IC_EOICR, 1);
+	}
+
+	WR4(sc, IC_SPU, 32);
+	/* No debug. */
+	WR4(sc, IC_DCR, 0);
+	/* Disable and clear all interrupts. */
+	WR4(sc, IC_IDCR, 0xffffffff);
+	WR4(sc, IC_ICCR, 0xffffffff);
+	enable_interrupts(PSR_I | PSR_F);
+
+	return (err);
+}
+
+static void
+at91_aic_new_pass(device_t dev)
+{
+	device_printf(dev, "Pass %d\n", bus_current_pass);
+}
+
+static device_method_t at91_aic_methods[] = {
+	DEVMETHOD(device_probe, at91_aic_probe),
+	DEVMETHOD(device_attach, at91_aic_attach),
+	DEVMETHOD(bus_new_pass, at91_aic_new_pass),
+	DEVMETHOD_END
+};
+
+static driver_t at91_aic_driver = {
+	"at91_aic",
+	at91_aic_methods,
+	sizeof(struct aic_softc),
+};
+
+static devclass_t at91_aic_devclass;
+
+#ifdef FDT
+DRIVER_MODULE(at91_aic, simplebus, at91_aic_driver, at91_aic_devclass, NULL,
+    NULL);
+#else
+DRIVER_MODULE(at91_aic, atmelarm, at91_aic_driver, at91_aic_devclass, NULL,
+    NULL);
+#endif
+/* not yet
+EARLY_DRIVER_MODULE(at91_aic, simplebus, at91_aic_driver, at91_aic_devclass,
+    NULL, NULL, BUS_PASS_INTERRUPT);
+*/


Property changes on: trunk/sys/arm/at91/at91_aic.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91_aicreg.h
===================================================================
--- trunk/sys/arm/at91/at91_aicreg.h	                        (rev 0)
+++ trunk/sys/arm/at91/at91_aicreg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,52 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2009 Sylvestre Gallon. 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: stable/10/sys/arm/at91/at91_aicreg.h 210040 2010-07-14 00:48:53Z cognet $ */
+
+#ifndef ARM_AT91_AT91_AICREG_H
+#define ARM_AT91_AT91_AICREG_H
+
+/* Interrupt Controller */
+#define IC_SMR			(0) /* Source mode register */
+#define IC_SVR			(128) /* Source vector register */
+#define IC_IVR			(256) /* IRQ vector register */
+#define IC_FVR			(260) /* FIQ vector register */
+#define IC_ISR			(264) /* Interrupt status register */
+#define IC_IPR			(268) /* Interrupt pending register */
+#define IC_IMR			(272) /* Interrupt status register */
+#define IC_CISR			(276) /* Core interrupt status register */
+#define IC_IECR			(288) /* Interrupt enable command register */
+#define IC_IDCR			(292) /* Interrupt disable command register */
+#define IC_ICCR			(296) /* Interrupt clear command register */
+#define IC_ISCR			(300) /* Interrupt set command register */
+#define IC_EOICR		(304) /* End of interrupt command register */
+#define IC_SPU			(308) /* Spurious vector register */
+#define IC_DCR			(312) /* Debug control register */
+#define IC_FFER			(320) /* Fast forcing enable register */
+#define IC_FFDR			(324) /* Fast forcing disable register */
+#define IC_FFSR			(328) /* Fast forcing status register */
+
+#endif /*ARM_AT91_AT91_AICREG_H*/


Property changes on: trunk/sys/arm/at91/at91_aicreg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91_cfata.c
===================================================================
--- trunk/sys/arm/at91/at91_cfata.c	                        (rev 0)
+++ trunk/sys/arm/at91/at91_cfata.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,282 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2008 Deglitch Networks, Stanislav Sedov
+ * 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 ``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 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.
+ *
+ * Driver for the AT91RM9200 CompactFlash controller operating in a
+ * common memory mode. Interrupts are driven by polling. The driver
+ * implements an ATA bridge and attached ATA channel driver on top
+ * of it.
+ * NOTE WELL: this driver uses polling mode. To achive an acceptable
+ * operating speed you will probably want to use HZ=2000 in kernel
+ * config.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/at91/at91_cfata.c 193934 2009-06-10 17:39:19Z imp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/time.h>
+#include <sys/bus.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+#include <sys/sema.h>
+#include <sys/taskqueue.h>
+#include <vm/uma.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+#include <machine/resource.h>
+#include <machine/intr.h>
+
+#include <sys/ata.h>
+#include <dev/ata/ata-all.h>
+#include <ata_if.h>
+
+struct at91_cfata_softc {
+	device_t		dev;
+	struct resource		*mem_res;
+	struct resource		irq;
+	void			(*isr_cb)(void *);
+	void			*isr_arg;
+	struct callout		tick;
+};
+
+static int	at91_cfata_detach(device_t dev);
+static void	at91_cfata_callout(void *arg);
+
+static int
+at91_cfata_probe(device_t dev)
+{
+
+	device_set_desc_copy(dev, "AT91RM9200 CompactFlash controller");
+	return (0);
+}
+
+static int
+at91_cfata_attach(device_t dev)
+{
+	struct at91_cfata_softc *sc;
+	int rid, error;
+
+	sc = device_get_softc(dev);
+	sc->dev = dev;
+	rid = 0;
+	error = 0;
+	sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	    RF_ACTIVE);
+	if (sc->mem_res == NULL)
+		return (ENOMEM);
+
+	/* XXX: init CF controller? */
+
+	callout_init(&sc->tick, 1);	/* Callout to poll the device. */
+	device_add_child(dev, "ata", -1);
+	bus_generic_attach(dev);
+	return (0);
+}
+
+static int
+at91_cfata_detach(device_t dev)
+{
+	struct at91_cfata_softc *sc;
+
+	sc = device_get_softc(dev);
+	bus_generic_detach(sc->dev);
+	if (sc->mem_res != NULL) {
+		bus_release_resource(dev, SYS_RES_MEMORY,
+		    rman_get_rid(sc->mem_res), sc->mem_res);
+		sc->mem_res = NULL;
+	}
+	return (0);
+}
+
+static struct resource *
+ata_at91_alloc_resource(device_t dev, device_t child, int type, int *rid,
+    u_long start, u_long end, u_long count, u_int flags)
+{
+	struct at91_cfata_softc *sc = device_get_softc(dev);
+
+	KASSERT(type == SYS_RES_IRQ && *rid == ATA_IRQ_RID,
+	    ("[at91_cfata, %d]: illegal resource request (type %u rid %u)",
+	    __LINE__, type, *rid));
+	return (&sc->irq);
+}
+
+static int
+ata_at91_release_resource(device_t dev, device_t child, int type, int rid,
+    struct resource *r)
+{
+
+	KASSERT(type == SYS_RES_IRQ && rid == ATA_IRQ_RID,
+	    ("[at91_cfata, %d]: illegal resource request (type %u rid %u)",
+	    __LINE__, type, rid));
+	return (0);
+}
+
+
+static int
+ata_at91_setup_intr(device_t dev, device_t child, struct resource *irq,
+    int flags, driver_filter_t *filt,
+    driver_intr_t *function, void *argument, void **cookiep)
+{
+	struct at91_cfata_softc *sc = device_get_softc(dev);
+
+	KASSERT(sc->isr_cb == NULL,
+	    ("[at91_cfata, %d]: overwriting the old handler", __LINE__));
+	sc->isr_cb = function;
+	sc->isr_arg = argument;
+	*cookiep = sc;
+	callout_reset(&sc->tick, 1, at91_cfata_callout, sc);
+	return (0);
+}
+
+static int
+ata_at91_teardown_intr(device_t dev, device_t child, struct resource *irq,
+    void *cookie)
+{
+	struct at91_cfata_softc *sc = device_get_softc(dev);
+
+	sc->isr_cb = NULL;
+	sc->isr_arg = NULL;
+	return (0);
+}
+
+static void
+at91_cfata_callout(void *arg)
+{
+	struct at91_cfata_softc *sc;
+
+	sc = (struct at91_cfata_softc *)arg;
+	if (sc->isr_cb != NULL)
+		sc->isr_cb(sc->isr_arg);
+	callout_reset(&sc->tick, 1, at91_cfata_callout, sc);
+}
+
+static int
+at91_channel_probe(device_t dev)
+{
+	struct ata_channel *ch = device_get_softc(dev);
+
+	ch->unit = 0;
+	ch->flags |= ATA_USE_16BIT | ATA_NO_SLAVE;
+	device_set_desc_copy(dev, "ATA channel 0");
+
+	return (ata_probe(dev));
+}
+
+static int
+at91_channel_attach(device_t dev)
+{
+	struct at91_cfata_softc *sc = device_get_softc(device_get_parent(dev));
+	struct ata_channel *ch = device_get_softc(dev);
+	int i;
+
+	for (i = 0; i < ATA_MAX_RES; i++)
+		ch->r_io[i].res = sc->mem_res;
+
+	/*
+	 * CF+ Specification.
+	 * 6.1.3 Memory Mapped Addressing.
+	 */
+	ch->r_io[ATA_DATA].offset = 0x00;
+	ch->r_io[ATA_FEATURE].offset = 0x01;
+	ch->r_io[ATA_COUNT].offset = 0x02;
+	ch->r_io[ATA_SECTOR].offset = 0x03;
+	ch->r_io[ATA_CYL_LSB].offset = 0x04;
+	ch->r_io[ATA_CYL_MSB].offset = 0x05;
+	ch->r_io[ATA_DRIVE].offset = 0x06;
+	ch->r_io[ATA_COMMAND].offset = 0x07;
+	ch->r_io[ATA_ERROR].offset = 0x01;
+	ch->r_io[ATA_IREASON].offset = 0x02;
+	ch->r_io[ATA_STATUS].offset = 0x07;
+	ch->r_io[ATA_ALTSTAT].offset = 0x0e;
+	ch->r_io[ATA_CONTROL].offset = 0x0e;
+
+	/* Should point at the base of registers. */
+	ch->r_io[ATA_IDX_ADDR].offset = 0x0;
+
+	ata_generic_hw(dev);
+	return (ata_attach(dev));
+}
+
+static device_method_t at91_cfata_methods[] = {
+	/* Device interface. */
+	DEVMETHOD(device_probe,			at91_cfata_probe),
+	DEVMETHOD(device_attach,		at91_cfata_attach),
+	DEVMETHOD(device_detach,		at91_cfata_detach),
+	DEVMETHOD(device_shutdown,		bus_generic_shutdown),
+	DEVMETHOD(device_suspend,		bus_generic_suspend),
+	DEVMETHOD(device_resume,		bus_generic_resume),
+
+	/* ATA bus methods. */
+	DEVMETHOD(bus_alloc_resource,		ata_at91_alloc_resource),
+	DEVMETHOD(bus_release_resource,		ata_at91_release_resource),
+	DEVMETHOD(bus_activate_resource,	bus_generic_activate_resource),
+	DEVMETHOD(bus_deactivate_resource,
+	    bus_generic_deactivate_resource),
+	DEVMETHOD(bus_setup_intr,		ata_at91_setup_intr),
+	DEVMETHOD(bus_teardown_intr,		ata_at91_teardown_intr),
+
+	{ 0, 0 }
+};
+
+devclass_t at91_cfata_devclass;
+
+static driver_t at91_cfata_driver = {
+	"at91_cfata",
+	at91_cfata_methods,
+	sizeof(struct at91_cfata_softc),
+};
+
+DRIVER_MODULE(at91_cfata, atmelarm, at91_cfata_driver, at91_cfata_devclass, 0,
+    0);
+MODULE_VERSION(at91_cfata, 1);
+MODULE_DEPEND(at91_cfata, ata, 1, 1, 1);
+
+/*
+ * ATA channel driver.
+ */
+static device_method_t at91_channel_methods[] = {
+	/* device interface */
+	DEVMETHOD(device_probe,		at91_channel_probe),
+	DEVMETHOD(device_attach,	at91_channel_attach),
+	DEVMETHOD(device_detach,	ata_detach),
+	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
+	DEVMETHOD(device_suspend,	ata_suspend),
+	DEVMETHOD(device_resume,	ata_resume),
+
+	{ 0, 0 }
+};
+
+driver_t at91_channel_driver = {
+	"ata",
+	at91_channel_methods,
+	sizeof(struct ata_channel),
+};
+
+DRIVER_MODULE(ata, at91_cfata, at91_channel_driver, ata_devclass, 0, 0);


Property changes on: trunk/sys/arm/at91/at91_cfata.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91_gpio.h
===================================================================
--- trunk/sys/arm/at91/at91_gpio.h	                        (rev 0)
+++ trunk/sys/arm/at91/at91_gpio.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,297 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014 M. Warner Losh.  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 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 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: stable/10/sys/arm/at91/at91_gpio.h 266087 2014-05-14 20:31:54Z ian $ */
+
+#ifndef ARM_AT91_AT91_GPIO_H
+#define ARM_AT91_AT91_GPIO_H
+
+typedef uint32_t at91_pin_t;
+
+#define AT91_PIN_NONE	0xfffffffful	/* No pin / Not GPIO controlled */
+
+/*
+ * Map Atmel PIO pins to a unique number. They are just numbered sequentially.
+ */
+
+#define	AT91_PIN_PA0	(at91_pin_t)0
+#define	AT91_PIN_PA1	(at91_pin_t)1
+#define	AT91_PIN_PA2	(at91_pin_t)2
+#define	AT91_PIN_PA3	(at91_pin_t)3
+#define	AT91_PIN_PA4	(at91_pin_t)4
+#define	AT91_PIN_PA5	(at91_pin_t)5
+#define	AT91_PIN_PA6	(at91_pin_t)6
+#define	AT91_PIN_PA7	(at91_pin_t)7
+#define	AT91_PIN_PA8	(at91_pin_t)8
+#define	AT91_PIN_PA9	(at91_pin_t)9
+#define	AT91_PIN_PA10	(at91_pin_t)10
+#define	AT91_PIN_PA11	(at91_pin_t)11
+#define	AT91_PIN_PA12	(at91_pin_t)12
+#define	AT91_PIN_PA13	(at91_pin_t)13
+#define	AT91_PIN_PA14	(at91_pin_t)14
+#define	AT91_PIN_PA15	(at91_pin_t)15
+#define	AT91_PIN_PA16	(at91_pin_t)16
+#define	AT91_PIN_PA17	(at91_pin_t)17
+#define	AT91_PIN_PA18	(at91_pin_t)18
+#define	AT91_PIN_PA19	(at91_pin_t)19
+#define	AT91_PIN_PA20	(at91_pin_t)20
+#define	AT91_PIN_PA21	(at91_pin_t)21
+#define	AT91_PIN_PA22	(at91_pin_t)22
+#define	AT91_PIN_PA23	(at91_pin_t)23
+#define	AT91_PIN_PA24	(at91_pin_t)24
+#define	AT91_PIN_PA25	(at91_pin_t)25
+#define	AT91_PIN_PA26	(at91_pin_t)26
+#define	AT91_PIN_PA27	(at91_pin_t)27
+#define	AT91_PIN_PA28	(at91_pin_t)28
+#define	AT91_PIN_PA29	(at91_pin_t)29
+#define	AT91_PIN_PA30	(at91_pin_t)30
+#define	AT91_PIN_PA31	(at91_pin_t)31
+#define	AT91_PIN_PB0	(at91_pin_t)32
+#define	AT91_PIN_PB1	(at91_pin_t)33
+#define	AT91_PIN_PB2	(at91_pin_t)34
+#define	AT91_PIN_PB3	(at91_pin_t)35
+#define	AT91_PIN_PB4	(at91_pin_t)36
+#define	AT91_PIN_PB5	(at91_pin_t)37
+#define	AT91_PIN_PB6	(at91_pin_t)38
+#define	AT91_PIN_PB7	(at91_pin_t)39
+#define	AT91_PIN_PB8	(at91_pin_t)40
+#define	AT91_PIN_PB9	(at91_pin_t)41
+#define	AT91_PIN_PB10	(at91_pin_t)42
+#define	AT91_PIN_PB11	(at91_pin_t)43
+#define	AT91_PIN_PB12	(at91_pin_t)44
+#define	AT91_PIN_PB13	(at91_pin_t)45
+#define	AT91_PIN_PB14	(at91_pin_t)46
+#define	AT91_PIN_PB15	(at91_pin_t)47
+#define	AT91_PIN_PB16	(at91_pin_t)48
+#define	AT91_PIN_PB17	(at91_pin_t)49
+#define	AT91_PIN_PB18	(at91_pin_t)50
+#define	AT91_PIN_PB19	(at91_pin_t)51
+#define	AT91_PIN_PB20	(at91_pin_t)52
+#define	AT91_PIN_PB21	(at91_pin_t)53
+#define	AT91_PIN_PB22	(at91_pin_t)54
+#define	AT91_PIN_PB23	(at91_pin_t)55
+#define	AT91_PIN_PB24	(at91_pin_t)56
+#define	AT91_PIN_PB25	(at91_pin_t)57
+#define	AT91_PIN_PB26	(at91_pin_t)58
+#define	AT91_PIN_PB27	(at91_pin_t)59
+#define	AT91_PIN_PB28	(at91_pin_t)60
+#define	AT91_PIN_PB29	(at91_pin_t)61
+#define	AT91_PIN_PB30	(at91_pin_t)62
+#define	AT91_PIN_PB31	(at91_pin_t)63
+#define	AT91_PIN_PC0	(at91_pin_t)64
+#define	AT91_PIN_PC1	(at91_pin_t)65
+#define	AT91_PIN_PC2	(at91_pin_t)66
+#define	AT91_PIN_PC3	(at91_pin_t)67
+#define	AT91_PIN_PC4	(at91_pin_t)68
+#define	AT91_PIN_PC5	(at91_pin_t)69
+#define	AT91_PIN_PC6	(at91_pin_t)70
+#define	AT91_PIN_PC7	(at91_pin_t)71
+#define	AT91_PIN_PC8	(at91_pin_t)72
+#define	AT91_PIN_PC9	(at91_pin_t)73
+#define	AT91_PIN_PC10	(at91_pin_t)74
+#define	AT91_PIN_PC11	(at91_pin_t)75
+#define	AT91_PIN_PC12	(at91_pin_t)76
+#define	AT91_PIN_PC13	(at91_pin_t)77
+#define	AT91_PIN_PC14	(at91_pin_t)78
+#define	AT91_PIN_PC15	(at91_pin_t)79
+#define	AT91_PIN_PC16	(at91_pin_t)80
+#define	AT91_PIN_PC17	(at91_pin_t)81
+#define	AT91_PIN_PC18	(at91_pin_t)82
+#define	AT91_PIN_PC19	(at91_pin_t)83
+#define	AT91_PIN_PC20	(at91_pin_t)84
+#define	AT91_PIN_PC21	(at91_pin_t)85
+#define	AT91_PIN_PC22	(at91_pin_t)86
+#define	AT91_PIN_PC23	(at91_pin_t)87
+#define	AT91_PIN_PC24	(at91_pin_t)88
+#define	AT91_PIN_PC25	(at91_pin_t)89
+#define	AT91_PIN_PC26	(at91_pin_t)90
+#define	AT91_PIN_PC27	(at91_pin_t)91
+#define	AT91_PIN_PC28	(at91_pin_t)92
+#define	AT91_PIN_PC29	(at91_pin_t)93
+#define	AT91_PIN_PC30	(at91_pin_t)94
+#define	AT91_PIN_PC31	(at91_pin_t)95
+#define	AT91_PIN_PD0	(at91_pin_t)96
+#define	AT91_PIN_PD1	(at91_pin_t)97
+#define	AT91_PIN_PD2	(at91_pin_t)98
+#define	AT91_PIN_PD3	(at91_pin_t)99
+#define	AT91_PIN_PD4	(at91_pin_t)100
+#define	AT91_PIN_PD5	(at91_pin_t)101
+#define	AT91_PIN_PD6	(at91_pin_t)102
+#define	AT91_PIN_PD7	(at91_pin_t)103
+#define	AT91_PIN_PD8	(at91_pin_t)104
+#define	AT91_PIN_PD9	(at91_pin_t)105
+#define	AT91_PIN_PD10	(at91_pin_t)106
+#define	AT91_PIN_PD11	(at91_pin_t)107
+#define	AT91_PIN_PD12	(at91_pin_t)108
+#define	AT91_PIN_PD13	(at91_pin_t)109
+#define	AT91_PIN_PD14	(at91_pin_t)110
+#define	AT91_PIN_PD15	(at91_pin_t)111
+#define	AT91_PIN_PD16	(at91_pin_t)112
+#define	AT91_PIN_PD17	(at91_pin_t)113
+#define	AT91_PIN_PD18	(at91_pin_t)114
+#define	AT91_PIN_PD19	(at91_pin_t)115
+#define	AT91_PIN_PD20	(at91_pin_t)116
+#define	AT91_PIN_PD21	(at91_pin_t)117
+#define	AT91_PIN_PD22	(at91_pin_t)118
+#define	AT91_PIN_PD23	(at91_pin_t)119
+#define	AT91_PIN_PD24	(at91_pin_t)120
+#define	AT91_PIN_PD25	(at91_pin_t)121
+#define	AT91_PIN_PD26	(at91_pin_t)122
+#define	AT91_PIN_PD27	(at91_pin_t)123
+#define	AT91_PIN_PD28	(at91_pin_t)124
+#define	AT91_PIN_PD29	(at91_pin_t)125
+#define	AT91_PIN_PD30	(at91_pin_t)126
+#define	AT91_PIN_PD31	(at91_pin_t)127
+#define	AT91_PIN_PE0	(at91_pin_t)128
+#define	AT91_PIN_PE1	(at91_pin_t)129
+#define	AT91_PIN_PE2	(at91_pin_t)130
+#define	AT91_PIN_PE3	(at91_pin_t)131
+#define	AT91_PIN_PE4	(at91_pin_t)132
+#define	AT91_PIN_PE5	(at91_pin_t)133
+#define	AT91_PIN_PE6	(at91_pin_t)134
+#define	AT91_PIN_PE7	(at91_pin_t)135
+#define	AT91_PIN_PE8	(at91_pin_t)136
+#define	AT91_PIN_PE9	(at91_pin_t)137
+#define	AT91_PIN_PE10	(at91_pin_t)138
+#define	AT91_PIN_PE11	(at91_pin_t)139
+#define	AT91_PIN_PE12	(at91_pin_t)140
+#define	AT91_PIN_PE13	(at91_pin_t)141
+#define	AT91_PIN_PE14	(at91_pin_t)142
+#define	AT91_PIN_PE15	(at91_pin_t)143
+#define	AT91_PIN_PE16	(at91_pin_t)144
+#define	AT91_PIN_PE17	(at91_pin_t)145
+#define	AT91_PIN_PE18	(at91_pin_t)146
+#define	AT91_PIN_PE19	(at91_pin_t)147
+#define	AT91_PIN_PE20	(at91_pin_t)148
+#define	AT91_PIN_PE21	(at91_pin_t)149
+#define	AT91_PIN_PE22	(at91_pin_t)150
+#define	AT91_PIN_PE23	(at91_pin_t)151
+#define	AT91_PIN_PE24	(at91_pin_t)152
+#define	AT91_PIN_PE25	(at91_pin_t)153
+#define	AT91_PIN_PE26	(at91_pin_t)154
+#define	AT91_PIN_PE27	(at91_pin_t)155
+#define	AT91_PIN_PE28	(at91_pin_t)156
+#define	AT91_PIN_PE29	(at91_pin_t)157
+#define	AT91_PIN_PE30	(at91_pin_t)158
+#define	AT91_PIN_PE31	(at91_pin_t)159
+#define	AT91_PIN_PF0	(at91_pin_t)160
+#define	AT91_PIN_PF1	(at91_pin_t)161
+#define	AT91_PIN_PF2	(at91_pin_t)162
+#define	AT91_PIN_PF3	(at91_pin_t)163
+#define	AT91_PIN_PF4	(at91_pin_t)164
+#define	AT91_PIN_PF5	(at91_pin_t)165
+#define	AT91_PIN_PF6	(at91_pin_t)166
+#define	AT91_PIN_PF7	(at91_pin_t)167
+#define	AT91_PIN_PF8	(at91_pin_t)168
+#define	AT91_PIN_PF9	(at91_pin_t)169
+#define	AT91_PIN_PF10	(at91_pin_t)170
+#define	AT91_PIN_PF11	(at91_pin_t)171
+#define	AT91_PIN_PF12	(at91_pin_t)172
+#define	AT91_PIN_PF13	(at91_pin_t)173
+#define	AT91_PIN_PF14	(at91_pin_t)174
+#define	AT91_PIN_PF15	(at91_pin_t)175
+#define	AT91_PIN_PF16	(at91_pin_t)176
+#define	AT91_PIN_PF17	(at91_pin_t)177
+#define	AT91_PIN_PF18	(at91_pin_t)178
+#define	AT91_PIN_PF19	(at91_pin_t)179
+#define	AT91_PIN_PF20	(at91_pin_t)180
+#define	AT91_PIN_PF21	(at91_pin_t)181
+#define	AT91_PIN_PF22	(at91_pin_t)182
+#define	AT91_PIN_PF23	(at91_pin_t)183
+#define	AT91_PIN_PF24	(at91_pin_t)184
+#define	AT91_PIN_PF25	(at91_pin_t)185
+#define	AT91_PIN_PF26	(at91_pin_t)186
+#define	AT91_PIN_PF27	(at91_pin_t)187
+#define	AT91_PIN_PF28	(at91_pin_t)188
+#define	AT91_PIN_PF29	(at91_pin_t)189
+#define	AT91_PIN_PF30	(at91_pin_t)190
+#define	AT91_PIN_PF31	(at91_pin_t)191
+#define	AT91_PIN_PG0	(at91_pin_t)192
+#define	AT91_PIN_PG1	(at91_pin_t)193
+#define	AT91_PIN_PG2	(at91_pin_t)194
+#define	AT91_PIN_PG3	(at91_pin_t)195
+#define	AT91_PIN_PG4	(at91_pin_t)196
+#define	AT91_PIN_PG5	(at91_pin_t)197
+#define	AT91_PIN_PG6	(at91_pin_t)198
+#define	AT91_PIN_PG7	(at91_pin_t)199
+#define	AT91_PIN_PG8	(at91_pin_t)200
+#define	AT91_PIN_PG9	(at91_pin_t)201
+#define	AT91_PIN_PG10	(at91_pin_t)202
+#define	AT91_PIN_PG11	(at91_pin_t)203
+#define	AT91_PIN_PG12	(at91_pin_t)204
+#define	AT91_PIN_PG13	(at91_pin_t)205
+#define	AT91_PIN_PG14	(at91_pin_t)206
+#define	AT91_PIN_PG15	(at91_pin_t)207
+#define	AT91_PIN_PG16	(at91_pin_t)208
+#define	AT91_PIN_PG17	(at91_pin_t)209
+#define	AT91_PIN_PG18	(at91_pin_t)210
+#define	AT91_PIN_PG19	(at91_pin_t)211
+#define	AT91_PIN_PG20	(at91_pin_t)212
+#define	AT91_PIN_PG21	(at91_pin_t)213
+#define	AT91_PIN_PG22	(at91_pin_t)214
+#define	AT91_PIN_PG23	(at91_pin_t)215
+#define	AT91_PIN_PG24	(at91_pin_t)216
+#define	AT91_PIN_PG25	(at91_pin_t)217
+#define	AT91_PIN_PG26	(at91_pin_t)218
+#define	AT91_PIN_PG27	(at91_pin_t)219
+#define	AT91_PIN_PG28	(at91_pin_t)220
+#define	AT91_PIN_PG29	(at91_pin_t)221
+#define	AT91_PIN_PG30	(at91_pin_t)222
+#define	AT91_PIN_PG31	(at91_pin_t)223
+#define	AT91_PIN_PH0	(at91_pin_t)224
+#define	AT91_PIN_PH1	(at91_pin_t)225
+#define	AT91_PIN_PH2	(at91_pin_t)226
+#define	AT91_PIN_PH3	(at91_pin_t)227
+#define	AT91_PIN_PH4	(at91_pin_t)228
+#define	AT91_PIN_PH5	(at91_pin_t)229
+#define	AT91_PIN_PH6	(at91_pin_t)230
+#define	AT91_PIN_PH7	(at91_pin_t)231
+#define	AT91_PIN_PH8	(at91_pin_t)232
+#define	AT91_PIN_PH9	(at91_pin_t)233
+#define	AT91_PIN_PH10	(at91_pin_t)234
+#define	AT91_PIN_PH11	(at91_pin_t)235
+#define	AT91_PIN_PH12	(at91_pin_t)236
+#define	AT91_PIN_PH13	(at91_pin_t)237
+#define	AT91_PIN_PH14	(at91_pin_t)238
+#define	AT91_PIN_PH15	(at91_pin_t)239
+#define	AT91_PIN_PH16	(at91_pin_t)240
+#define	AT91_PIN_PH17	(at91_pin_t)241
+#define	AT91_PIN_PH18	(at91_pin_t)242
+#define	AT91_PIN_PH19	(at91_pin_t)243
+#define	AT91_PIN_PH20	(at91_pin_t)244
+#define	AT91_PIN_PH21	(at91_pin_t)245
+#define	AT91_PIN_PH22	(at91_pin_t)246
+#define	AT91_PIN_PH23	(at91_pin_t)247
+#define	AT91_PIN_PH24	(at91_pin_t)248
+#define	AT91_PIN_PH25	(at91_pin_t)249
+#define	AT91_PIN_PH26	(at91_pin_t)250
+#define	AT91_PIN_PH27	(at91_pin_t)251
+#define	AT91_PIN_PH28	(at91_pin_t)252
+#define	AT91_PIN_PH29	(at91_pin_t)253
+#define	AT91_PIN_PH30	(at91_pin_t)254
+#define	AT91_PIN_PH31	(at91_pin_t)255
+
+#endif /* ARM_AT91_AT91_GPIO_H */


Property changes on: trunk/sys/arm/at91/at91_gpio.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91_machdep.c
===================================================================
--- trunk/sys/arm/at91/at91_machdep.c	                        (rev 0)
+++ trunk/sys/arm/at91/at91_machdep.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,693 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1994-1998 Mark Brinicombe.
+ * Copyright (c) 1994 Brini.
+ * All rights reserved.
+ *
+ * This code is derived from software written for Brini by Mark Brinicombe
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by Brini.
+ * 4. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BRINI ``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 BRINI 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.
+ *
+ * RiscBSD kernel project
+ *
+ * machdep.c
+ *
+ * Machine dependant functions for kernel setup
+ *
+ * This file needs a lot of work.
+ *
+ * Created      : 17/09/94
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/at91/at91_machdep.c 266386 2014-05-18 00:32:35Z ian $");
+
+#define _ARM32_BUS_DMA_PRIVATE
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/sysproto.h>
+#include <sys/signalvar.h>
+#include <sys/imgact.h>
+#include <sys/kernel.h>
+#include <sys/ktr.h>
+#include <sys/linker.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/mutex.h>
+#include <sys/pcpu.h>
+#include <sys/proc.h>
+#include <sys/ptrace.h>
+#include <sys/cons.h>
+#include <sys/bio.h>
+#include <sys/bus.h>
+#include <sys/buf.h>
+#include <sys/exec.h>
+#include <sys/kdb.h>
+#include <sys/msgbuf.h>
+#include <machine/physmem.h>
+#include <machine/reg.h>
+#include <machine/cpu.h>
+#include <machine/board.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/vm_object.h>
+#include <vm/vm_page.h>
+#include <vm/vm_map.h>
+#include <machine/devmap.h>
+#include <machine/vmparam.h>
+#include <machine/pcb.h>
+#include <machine/undefined.h>
+#include <machine/machdep.h>
+#include <machine/metadata.h>
+#include <machine/armreg.h>
+#include <machine/bus.h>
+#include <sys/reboot.h>
+
+#include <arm/at91/at91board.h>
+#include <arm/at91/at91var.h>
+#include <arm/at91/at91soc.h>
+#include <arm/at91/at91_usartreg.h>
+#include <arm/at91/at91rm92reg.h>
+#include <arm/at91/at91sam9g20reg.h>
+#include <arm/at91/at91sam9g45reg.h>
+
+#ifndef MAXCPU
+#define MAXCPU 1
+#endif
+
+/* Page table for mapping proc0 zero page */
+#define KERNEL_PT_SYS		0
+#define KERNEL_PT_KERN		1
+#define KERNEL_PT_KERN_NUM	22
+/* L2 table for mapping after kernel */
+#define KERNEL_PT_AFKERNEL	KERNEL_PT_KERN + KERNEL_PT_KERN_NUM
+#define	KERNEL_PT_AFKERNEL_NUM	5
+
+/* this should be evenly divisable by PAGE_SIZE / L2_TABLE_SIZE_REAL (or 4) */
+#define NUM_KERNEL_PTS		(KERNEL_PT_AFKERNEL + KERNEL_PT_AFKERNEL_NUM)
+
+struct pv_addr kernel_pt_table[NUM_KERNEL_PTS];
+
+/* Static device mappings. */
+const struct arm_devmap_entry at91_devmap[] = {
+	/*
+	 * Map the critical on-board devices. The interrupt vector at
+	 * 0xffff0000 makes it impossible to map them PA == VA, so we map all
+	 * 0xfffxxxxx addresses to 0xdffxxxxx. This covers all critical devices
+	 * on all members of the AT91SAM9 and AT91RM9200 families.
+	 */
+	{
+		0xdff00000,
+		0xfff00000,
+		0x00100000,
+		VM_PROT_READ|VM_PROT_WRITE,
+		PTE_DEVICE,
+	},
+	/* There's a notion that we should do the rest of these lazily. */
+	/*
+	 * We can't just map the OHCI registers VA == PA, because
+	 * AT91xx_xxx_BASE belongs to the userland address space.
+	 * We could just choose a different virtual address, but a better
+	 * solution would probably be to just use pmap_mapdev() to allocate
+	 * KVA, as we don't need the OHCI controller before the vm
+	 * initialization is done. However, the AT91 resource allocation
+	 * system doesn't know how to use pmap_mapdev() yet.
+	 * Care must be taken to ensure PA and VM address do not overlap
+	 * between entries.
+	 */
+	{
+		/*
+		 * Add the ohci controller, and anything else that might be
+		 * on this chip select for a VA/PA mapping.
+		 */
+		/* Internal Memory 1MB  */
+		AT91RM92_OHCI_VA_BASE,
+		AT91RM92_OHCI_BASE,
+		0x00100000,
+		VM_PROT_READ|VM_PROT_WRITE,
+		PTE_DEVICE,
+	},
+	{
+		/* CompactFlash controller. Portion of EBI CS4 1MB */
+		AT91RM92_CF_VA_BASE,
+		AT91RM92_CF_BASE,
+		0x00100000,
+		VM_PROT_READ|VM_PROT_WRITE,
+		PTE_DEVICE,
+	},
+	/*
+	 * The next two should be good for the 9260, 9261 and 9G20 since
+	 * addresses mapping is the same.
+	 */
+	{
+		/* Internal Memory 1MB  */
+		AT91SAM9G20_OHCI_VA_BASE,
+		AT91SAM9G20_OHCI_BASE,
+		0x00100000,
+		VM_PROT_READ|VM_PROT_WRITE,
+		PTE_DEVICE,
+	},
+	{
+		/* EBI CS3 256MB */
+		AT91SAM9G20_NAND_VA_BASE,
+		AT91SAM9G20_NAND_BASE,
+		AT91SAM9G20_NAND_SIZE,
+		VM_PROT_READ|VM_PROT_WRITE,
+		PTE_DEVICE,
+	},
+	/*
+	 * The next should be good for the 9G45.
+	 */
+	{
+		/* Internal Memory 1MB  */
+		AT91SAM9G45_OHCI_VA_BASE,
+		AT91SAM9G45_OHCI_BASE,
+		0x00100000,
+		VM_PROT_READ|VM_PROT_WRITE,
+		PTE_DEVICE,
+	},
+	{ 0, 0, 0, 0, 0, }
+};
+
+/* Physical and virtual addresses for some global pages */
+
+struct pv_addr systempage;
+struct pv_addr msgbufpv;
+struct pv_addr irqstack;
+struct pv_addr undstack;
+struct pv_addr abtstack;
+struct pv_addr kernelstack;
+
+#ifdef LINUX_BOOT_ABI
+extern int membanks;
+extern int memstart[];
+extern int memsize[];
+#endif
+
+long
+at91_ramsize(void)
+{
+	uint32_t cr, mdr, mr, *SDRAMC;
+	int banks, rows, cols, bw;
+#ifdef LINUX_BOOT_ABI
+	/*
+	 * If we found any ATAGs that were for memory, return the first bank.
+	 */
+	if (membanks > 0)
+		return (memsize[0]);
+#endif
+
+	if (at91_is_rm92()) {
+		SDRAMC = (uint32_t *)(AT91_BASE + AT91RM92_SDRAMC_BASE);
+		cr = SDRAMC[AT91RM92_SDRAMC_CR / 4];
+		mr = SDRAMC[AT91RM92_SDRAMC_MR / 4];
+		banks = (cr & AT91RM92_SDRAMC_CR_NB_4) ? 2 : 1;
+		rows = ((cr & AT91RM92_SDRAMC_CR_NR_MASK) >> 2) + 11;
+		cols = (cr & AT91RM92_SDRAMC_CR_NC_MASK) + 8;
+		bw = (mr & AT91RM92_SDRAMC_MR_DBW_16) ? 1 : 2;
+	} else if (at91_cpu_is(AT91_T_SAM9G45)) {
+		SDRAMC = (uint32_t *)(AT91_BASE + AT91SAM9G45_DDRSDRC0_BASE);
+		cr = SDRAMC[AT91SAM9G45_DDRSDRC_CR / 4];
+		mdr = SDRAMC[AT91SAM9G45_DDRSDRC_MDR / 4];
+		banks = 0;
+		rows = ((cr & AT91SAM9G45_DDRSDRC_CR_NR_MASK) >> 2) + 11;
+		cols = (cr & AT91SAM9G45_DDRSDRC_CR_NC_MASK) + 8;
+		bw = (mdr & AT91SAM9G45_DDRSDRC_MDR_DBW_16) ? 1 : 2;
+
+		/* Fix the calculation for DDR memory */
+		mdr &= AT91SAM9G45_DDRSDRC_MDR_MASK;
+		if (mdr & AT91SAM9G45_DDRSDRC_MDR_LPDDR1 ||
+		    mdr & AT91SAM9G45_DDRSDRC_MDR_DDR2) {
+			/* The cols value is 1 higher for DDR */
+			cols += 1;
+			/* DDR has 4 internal banks. */
+			banks = 2;
+		}
+	} else {
+		/*
+		 * This should be good for the 9260, 9261, 9G20, 9G35 and 9X25
+		 * as addresses and registers are the same.
+		 */
+		SDRAMC = (uint32_t *)(AT91_BASE + AT91SAM9G20_SDRAMC_BASE);
+		cr = SDRAMC[AT91SAM9G20_SDRAMC_CR / 4];
+		mr = SDRAMC[AT91SAM9G20_SDRAMC_MR / 4];
+		banks = (cr & AT91SAM9G20_SDRAMC_CR_NB_4) ? 2 : 1;
+		rows = ((cr & AT91SAM9G20_SDRAMC_CR_NR_MASK) >> 2) + 11;
+		cols = (cr & AT91SAM9G20_SDRAMC_CR_NC_MASK) + 8;
+		bw = (cr & AT91SAM9G20_SDRAMC_CR_DBW_16) ? 1 : 2;
+	}
+
+	return (1 << (cols + rows + banks + bw));
+}
+
+static const char *soc_type_name[] = {
+	[AT91_T_CAP9] = "at91cap9",
+	[AT91_T_RM9200] = "at91rm9200",
+	[AT91_T_SAM9260] = "at91sam9260",
+	[AT91_T_SAM9261] = "at91sam9261",
+	[AT91_T_SAM9263] = "at91sam9263",
+	[AT91_T_SAM9G10] = "at91sam9g10",
+	[AT91_T_SAM9G20] = "at91sam9g20",
+	[AT91_T_SAM9G45] = "at91sam9g45",
+	[AT91_T_SAM9N12] = "at91sam9n12",
+	[AT91_T_SAM9RL] = "at91sam9rl",
+	[AT91_T_SAM9X5] = "at91sam9x5",
+	[AT91_T_NONE] = "UNKNOWN"
+};
+
+static const char *soc_subtype_name[] = {
+	[AT91_ST_NONE] = "UNKNOWN",
+	[AT91_ST_RM9200_BGA] = "at91rm9200_bga",
+	[AT91_ST_RM9200_PQFP] = "at91rm9200_pqfp",
+	[AT91_ST_SAM9XE] = "at91sam9xe",
+	[AT91_ST_SAM9G45] = "at91sam9g45",
+	[AT91_ST_SAM9M10] = "at91sam9m10",
+	[AT91_ST_SAM9G46] = "at91sam9g46",
+	[AT91_ST_SAM9M11] = "at91sam9m11",
+	[AT91_ST_SAM9G15] = "at91sam9g15",
+	[AT91_ST_SAM9G25] = "at91sam9g25",
+	[AT91_ST_SAM9G35] = "at91sam9g35",
+	[AT91_ST_SAM9X25] = "at91sam9x25",
+	[AT91_ST_SAM9X35] = "at91sam9x35",
+};
+
+struct at91_soc_info soc_info;
+
+/*
+ * Read the SoC ID from the CIDR register and try to match it against the
+ * values we know.  If we find a good one, we return true.  If not, we
+ * return false.  When we find a good one, we also find the subtype
+ * and CPU family.
+ */
+static int
+at91_try_id(uint32_t dbgu_base)
+{
+	uint32_t socid;
+
+	soc_info.cidr = *(volatile uint32_t *)(AT91_BASE + dbgu_base +
+	    DBGU_C1R);
+	socid = soc_info.cidr & ~AT91_CPU_VERSION_MASK;
+
+	soc_info.type = AT91_T_NONE;
+	soc_info.subtype = AT91_ST_NONE;
+	soc_info.family = (soc_info.cidr & AT91_CPU_FAMILY_MASK) >> 20;
+	soc_info.exid = *(volatile uint32_t *)(AT91_BASE + dbgu_base +
+	    DBGU_C2R);
+
+	switch (socid) {
+	case AT91_CPU_CAP9:
+		soc_info.type = AT91_T_CAP9;
+		break;
+	case AT91_CPU_RM9200:
+		soc_info.type = AT91_T_RM9200;
+		break;
+	case AT91_CPU_SAM9XE128:
+	case AT91_CPU_SAM9XE256:
+	case AT91_CPU_SAM9XE512:
+	case AT91_CPU_SAM9260:
+		soc_info.type = AT91_T_SAM9260;
+		if (soc_info.family == AT91_FAMILY_SAM9XE)
+			soc_info.subtype = AT91_ST_SAM9XE;
+		break;
+	case AT91_CPU_SAM9261:
+		soc_info.type = AT91_T_SAM9261;
+		break;
+	case AT91_CPU_SAM9263:
+		soc_info.type = AT91_T_SAM9263;
+		break;
+	case AT91_CPU_SAM9G10:
+		soc_info.type = AT91_T_SAM9G10;
+		break;
+	case AT91_CPU_SAM9G20:
+		soc_info.type = AT91_T_SAM9G20;
+		break;
+	case AT91_CPU_SAM9G45:
+		soc_info.type = AT91_T_SAM9G45;
+		break;
+	case AT91_CPU_SAM9N12:
+		soc_info.type = AT91_T_SAM9N12;
+		break;
+	case AT91_CPU_SAM9RL64:
+		soc_info.type = AT91_T_SAM9RL;
+		break;
+	case AT91_CPU_SAM9X5:
+		soc_info.type = AT91_T_SAM9X5;
+		break;
+	default:
+		return (0);
+	}
+
+	switch (soc_info.type) {
+	case AT91_T_SAM9G45:
+		switch (soc_info.exid) {
+		case AT91_EXID_SAM9G45:
+			soc_info.subtype = AT91_ST_SAM9G45;
+			break;
+		case AT91_EXID_SAM9G46:
+			soc_info.subtype = AT91_ST_SAM9G46;
+			break;
+		case AT91_EXID_SAM9M10:
+			soc_info.subtype = AT91_ST_SAM9M10;
+			break;
+		case AT91_EXID_SAM9M11:
+			soc_info.subtype = AT91_ST_SAM9M11;
+			break;
+		}
+		break;
+	case AT91_T_SAM9X5:
+		switch (soc_info.exid) {
+		case AT91_EXID_SAM9G15:
+			soc_info.subtype = AT91_ST_SAM9G15;
+			break;
+		case AT91_EXID_SAM9G25:
+			soc_info.subtype = AT91_ST_SAM9G25;
+			break;
+		case AT91_EXID_SAM9G35:
+			soc_info.subtype = AT91_ST_SAM9G35;
+			break;
+		case AT91_EXID_SAM9X25:
+			soc_info.subtype = AT91_ST_SAM9X25;
+			break;
+		case AT91_EXID_SAM9X35:
+			soc_info.subtype = AT91_ST_SAM9X35;
+			break;
+		}
+		break;
+	default:
+		break;
+	}
+	/*
+	 * Disable interrupts in the DBGU unit...
+	 */
+	*(volatile uint32_t *)(AT91_BASE + dbgu_base + USART_IDR) = 0xffffffff;
+
+	/*
+	 * Save the name for later...
+	 */
+	snprintf(soc_info.name, sizeof(soc_info.name), "%s%s%s",
+	    soc_type_name[soc_info.type],
+	    soc_info.subtype == AT91_ST_NONE ? "" : " subtype ",
+	    soc_info.subtype == AT91_ST_NONE ? "" :
+	    soc_subtype_name[soc_info.subtype]);
+
+        /*
+         * try to get the matching CPU support.
+         */
+        soc_info.soc_data = at91_match_soc(soc_info.type, soc_info.subtype);
+        soc_info.dbgu_base = AT91_BASE + dbgu_base;
+
+	return (1);
+}
+
+static void
+at91_soc_id(void)
+{
+
+	if (!at91_try_id(AT91_DBGU0))
+		at91_try_id(AT91_DBGU1);
+}
+
+#ifdef ARM_MANY_BOARD
+/* likely belongs in arm/arm/machdep.c, but since board_init is still at91 only... */
+SET_DECLARE(arm_board_set, const struct arm_board);
+
+/* Not yet fully functional, but enough to build ATMEL config */
+static long
+board_init(void)
+{
+	return -1;
+}
+#endif
+
+void *
+initarm(struct arm_boot_params *abp)
+{
+	struct pv_addr  kernel_l1pt;
+	struct pv_addr  dpcpu;
+	int i;
+	u_int l1pagetable;
+	vm_offset_t freemempos;
+	vm_offset_t afterkern;
+	uint32_t memsize;
+	vm_offset_t lastaddr;
+
+	lastaddr = parse_boot_param(abp);
+	arm_physmem_kernaddr = abp->abp_physaddr;
+	set_cpufuncs();
+	pcpu0_init();
+
+	/* Do basic tuning, hz etc */
+	init_param1();
+
+	freemempos = (lastaddr + PAGE_MASK) & ~PAGE_MASK;
+	/* Define a macro to simplify memory allocation */
+#define valloc_pages(var, np)						\
+	alloc_pages((var).pv_va, (np));					\
+	(var).pv_pa = (var).pv_va + (abp->abp_physaddr - KERNVIRTADDR);
+
+#define alloc_pages(var, np)						\
+	(var) = freemempos;						\
+	freemempos += (np * PAGE_SIZE);					\
+	memset((char *)(var), 0, ((np) * PAGE_SIZE));
+
+	while (((freemempos - L1_TABLE_SIZE) & (L1_TABLE_SIZE - 1)) != 0)
+		freemempos += PAGE_SIZE;
+	valloc_pages(kernel_l1pt, L1_TABLE_SIZE / PAGE_SIZE);
+	for (i = 0; i < NUM_KERNEL_PTS; ++i) {
+		if (!(i % (PAGE_SIZE / L2_TABLE_SIZE_REAL))) {
+			valloc_pages(kernel_pt_table[i],
+			    L2_TABLE_SIZE / PAGE_SIZE);
+		} else {
+			kernel_pt_table[i].pv_va = freemempos -
+			    (i % (PAGE_SIZE / L2_TABLE_SIZE_REAL)) *
+			    L2_TABLE_SIZE_REAL;
+			kernel_pt_table[i].pv_pa =
+			    kernel_pt_table[i].pv_va - KERNVIRTADDR +
+			    abp->abp_physaddr;
+		}
+	}
+	/*
+	 * Allocate a page for the system page mapped to 0x00000000
+	 * or 0xffff0000. This page will just contain the system vectors
+	 * and can be shared by all processes.
+	 */
+	valloc_pages(systempage, 1);
+
+	/* Allocate dynamic per-cpu area. */
+	valloc_pages(dpcpu, DPCPU_SIZE / PAGE_SIZE);
+	dpcpu_init((void *)dpcpu.pv_va, 0);
+
+	/* Allocate stacks for all modes */
+	valloc_pages(irqstack, IRQ_STACK_SIZE * MAXCPU);
+	valloc_pages(abtstack, ABT_STACK_SIZE * MAXCPU);
+	valloc_pages(undstack, UND_STACK_SIZE * MAXCPU);
+	valloc_pages(kernelstack, KSTACK_PAGES * MAXCPU);
+	valloc_pages(msgbufpv, round_page(msgbufsize) / PAGE_SIZE);
+
+	/*
+	 * Now we start construction of the L1 page table
+	 * We start by mapping the L2 page tables into the L1.
+	 * This means that we can replace L1 mappings later on if necessary
+	 */
+	l1pagetable = kernel_l1pt.pv_va;
+
+	/* Map the L2 pages tables in the L1 page table */
+	pmap_link_l2pt(l1pagetable, ARM_VECTORS_HIGH,
+	    &kernel_pt_table[KERNEL_PT_SYS]);
+	for (i = 0; i < KERNEL_PT_KERN_NUM; i++)
+		pmap_link_l2pt(l1pagetable, KERNBASE + i * L1_S_SIZE,
+		    &kernel_pt_table[KERNEL_PT_KERN + i]);
+	pmap_map_chunk(l1pagetable, KERNBASE, PHYSADDR,
+	   (((uint32_t)lastaddr - KERNBASE) + PAGE_SIZE) & ~(PAGE_SIZE - 1),
+	    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+	afterkern = round_page((lastaddr + L1_S_SIZE) & ~(L1_S_SIZE - 1));
+	for (i = 0; i < KERNEL_PT_AFKERNEL_NUM; i++) {
+		pmap_link_l2pt(l1pagetable, afterkern + i * L1_S_SIZE,
+		    &kernel_pt_table[KERNEL_PT_AFKERNEL + i]);
+	}
+
+	/* Map the vector page. */
+	pmap_map_entry(l1pagetable, ARM_VECTORS_HIGH, systempage.pv_pa,
+	    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+
+	/* Map the DPCPU pages */
+	pmap_map_chunk(l1pagetable, dpcpu.pv_va, dpcpu.pv_pa, DPCPU_SIZE,
+	    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+
+	/* Map the stack pages */
+	pmap_map_chunk(l1pagetable, irqstack.pv_va, irqstack.pv_pa,
+	    IRQ_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+	pmap_map_chunk(l1pagetable, abtstack.pv_va, abtstack.pv_pa,
+	    ABT_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+	pmap_map_chunk(l1pagetable, undstack.pv_va, undstack.pv_pa,
+	    UND_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+	pmap_map_chunk(l1pagetable, kernelstack.pv_va, kernelstack.pv_pa,
+	    KSTACK_PAGES * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+
+	pmap_map_chunk(l1pagetable, kernel_l1pt.pv_va, kernel_l1pt.pv_pa,
+	    L1_TABLE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE);
+	pmap_map_chunk(l1pagetable, msgbufpv.pv_va, msgbufpv.pv_pa,
+	    msgbufsize, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+
+	for (i = 0; i < NUM_KERNEL_PTS; ++i) {
+		pmap_map_chunk(l1pagetable, kernel_pt_table[i].pv_va,
+		    kernel_pt_table[i].pv_pa, L2_TABLE_SIZE,
+		    VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE);
+	}
+
+	arm_devmap_bootstrap(l1pagetable, at91_devmap);
+	cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL * 2)) | DOMAIN_CLIENT);
+	setttb(kernel_l1pt.pv_pa);
+	cpu_tlb_flushID();
+	cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL * 2));
+
+	at91_soc_id();
+
+	/*
+	 * Initialize all the clocks, so that the console can work.  We can only
+	 * do this if at91_soc_id() was able to fill in the support data.  Even
+	 * if we can't init the clocks, still try to do a console init so we can
+	 * try to print the error message about missing soc support.  There's a
+	 * chance the printf will work if the bootloader set up the DBGU.
+	 */
+	if (soc_info.soc_data != NULL) {
+		soc_info.soc_data->soc_clock_init();
+		at91_pmc_init_clock();
+	}
+
+	cninit();
+
+	if (soc_info.soc_data == NULL)
+		printf("Warning: No soc support for %s found.\n", soc_info.name);
+
+	memsize = board_init();
+	if (memsize == -1) {
+		printf("board_init() failed, cannot determine ram size; "
+		    "assuming 16MB\n");
+		memsize = 16 * 1024 * 1024;
+	}
+
+	/*
+	 * Pages were allocated during the secondary bootstrap for the
+	 * stacks for different CPU modes.
+	 * We must now set the r13 registers in the different CPU modes to
+	 * point to these stacks.
+	 * Since the ARM stacks use STMFD etc. we must set r13 to the top end
+	 * of the stack memory.
+	 */
+	cpu_control(CPU_CONTROL_MMU_ENABLE, CPU_CONTROL_MMU_ENABLE);
+	cpu_setup("");
+
+	set_stackptrs(0);
+
+	/*
+	 * We must now clean the cache again....
+	 * Cleaning may be done by reading new data to displace any
+	 * dirty data in the cache. This will have happened in setttb()
+	 * but since we are boot strapping the addresses used for the read
+	 * may have just been remapped and thus the cache could be out
+	 * of sync. A re-clean after the switch will cure this.
+	 * After booting there are no gross relocations of the kernel thus
+	 * this problem will not occur after initarm().
+	 */
+	cpu_idcache_wbinv_all();
+
+	undefined_init();
+
+	init_proc0(kernelstack.pv_va);
+
+	arm_vector_init(ARM_VECTORS_HIGH, ARM_VEC_ALL);
+
+	pmap_curmaxkvaddr = afterkern + L1_S_SIZE * (KERNEL_PT_KERN_NUM - 1);
+	/* Always use the 256MB of KVA we have available between the kernel and devices */
+	vm_max_kernel_address = KERNVIRTADDR + (256 << 20);
+	pmap_bootstrap(freemempos, &kernel_l1pt);
+	msgbufp = (void*)msgbufpv.pv_va;
+	msgbufinit(msgbufp, msgbufsize);
+	mutex_init();
+
+	/*
+	 * Add the physical ram we have available.
+	 *
+	 * Exclude the kernel, and all the things we allocated which immediately
+	 * follow the kernel, from the VM allocation pool but not from crash
+	 * dumps.  virtual_avail is a global variable which tracks the kva we've
+	 * "allocated" while setting up pmaps.
+	 *
+	 * Prepare the list of physical memory available to the vm subsystem.
+	 */
+	arm_physmem_hardware_region(PHYSADDR, memsize);
+	arm_physmem_exclude_region(abp->abp_physaddr, 
+	    virtual_avail - KERNVIRTADDR, EXFLAG_NOALLOC);
+	arm_physmem_init_kernel_globals();
+
+	init_param2(physmem);
+	kdb_init();
+	return ((void *)(kernelstack.pv_va + USPACE_SVC_STACK_TOP -
+	    sizeof(struct pcb)));
+}
+
+/*
+ * These functions are handled elsewhere, so make them nops here.
+ */
+void
+cpu_startprofclock(void)
+{
+
+}
+
+void
+cpu_stopprofclock(void)
+{
+
+}
+
+void
+cpu_initclocks(void)
+{
+
+}
+
+void
+DELAY(int n)
+{
+
+	if (soc_info.soc_data)
+		soc_info.soc_data->soc_delay(n);
+}
+
+void
+cpu_reset(void)
+{
+
+	if (soc_info.soc_data)
+		soc_info.soc_data->soc_reset();
+	while (1)
+		continue;
+}


Property changes on: trunk/sys/arm/at91/at91_machdep.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91_mci.c
===================================================================
--- trunk/sys/arm/at91/at91_mci.c	                        (rev 0)
+++ trunk/sys/arm/at91/at91_mci.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,1407 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2006 Bernd Walter.  All rights reserved.
+ * Copyright (c) 2006 M. Warner Losh.  All rights reserved.
+ * Copyright (c) 2010 Greg Ansley.  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 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 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: stable/10/sys/arm/at91/at91_mci.c 318198 2017-05-11 21:01:02Z marius $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/endian.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+#include <sys/sysctl.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+#include <machine/resource.h>
+#include <machine/intr.h>
+
+#include <arm/at91/at91var.h>
+#include <arm/at91/at91_mcireg.h>
+#include <arm/at91/at91_pdcreg.h>
+
+#include <dev/mmc/bridge.h>
+#include <dev/mmc/mmcbrvar.h>
+
+#ifdef FDT
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+#endif
+
+#include "mmcbr_if.h"
+
+#include "opt_at91.h"
+
+/*
+ * About running the MCI bus above 25MHz
+ *
+ * Historically, the MCI bus has been run at 30MHz on systems with a 60MHz
+ * master clock, in part due to a bug in dev/mmc.c making always request
+ * 30MHz, and in part over clocking the bus because 15MHz was too slow.
+ * Fixing that bug causes the mmc driver to request a 25MHz clock (as it
+ * should) and the logic in at91_mci_update_ios() picks the highest speed that
+ * doesn't exceed that limit.  With a 60MHz MCK that would be 15MHz, and
+ * that's a real performance buzzkill when you've been getting away with 30MHz
+ * all along.
+ *
+ * By defining AT91_MCI_ALLOW_OVERCLOCK (or setting the allow_overclock=1
+ * device hint or sysctl) you can enable logic in at91_mci_update_ios() to
+ * overlcock the SD bus a little by running it at MCK / 2 when the requested
+ * speed is 25MHz and the next highest speed is 15MHz or less.  This appears
+ * to work on virtually all SD cards, since it is what this driver has been
+ * doing prior to the introduction of this option, where the overclocking vs
+ * underclocking decision was automaticly "overclock".  Modern SD cards can
+ * run at 45mhz/1-bit in standard mode (high speed mode enable commands not
+ * sent) without problems.
+ *
+ * Speaking of high-speed mode, the rm9200 manual says the MCI device supports
+ * the SD v1.0 specification and can run up to 50MHz.  This is interesting in
+ * that the SD v1.0 spec caps the speed at 25MHz; high speed mode was added in
+ * the v1.10 spec.  Furthermore, high speed mode doesn't just crank up the
+ * clock, it alters the signal timing.  The rm9200 MCI device doesn't support
+ * these altered timings.  So while speeds over 25MHz may work, they only work
+ * in what the SD spec calls "default" speed mode, and it amounts to violating
+ * the spec by overclocking the bus.
+ *
+ * If you also enable 4-wire mode it's possible transfers faster than 25MHz
+ * will fail.  On the AT91RM9200, due to bugs in the bus contention logic, if
+ * you have the USB host device and OHCI driver enabled will fail.  Even
+ * underclocking to 15MHz, intermittant overrun and underrun errors occur.
+ * Note that you don't even need to have usb devices attached to the system,
+ * the errors begin to occur as soon as the OHCI driver sets the register bit
+ * to enable periodic transfers.  It appears (based on brief investigation)
+ * that the usb host controller uses so much ASB bandwidth that sometimes the
+ * DMA for MCI transfers doesn't get a bus grant in time and data gets
+ * dropped.  Adding even a modicum of network activity changes the symptom
+ * from intermittant to very frequent.  Members of the AT91SAM9 family have
+ * corrected this problem, or are at least better about their use of the bus.
+ */
+#ifndef AT91_MCI_ALLOW_OVERCLOCK
+#define AT91_MCI_ALLOW_OVERCLOCK 1
+#endif
+
+/*
+ * Allocate 2 bounce buffers we'll use to endian-swap the data due to the rm9200
+ * erratum.  We use a pair of buffers because when reading that lets us begin
+ * endian-swapping the data in the first buffer while the DMA is reading into
+ * the second buffer.  (We can't use the same trick for writing because we might
+ * not get all the data in the 2nd buffer swapped before the hardware needs it;
+ * dealing with that would add complexity to the driver.)
+ *
+ * The buffers are sized at 16K each due to the way the busdma cache sync
+ * operations work on arm.  A dcache_inv_range() operation on a range larger
+ * than 16K gets turned into a dcache_wbinv_all().  That needlessly flushes the
+ * entire data cache, impacting overall system performance.
+ */
+#define BBCOUNT     2
+#define BBSIZE      (16*1024)
+#define MAX_BLOCKS  ((BBSIZE*BBCOUNT)/512)
+
+static int mci_debug;
+
+struct at91_mci_softc {
+	void *intrhand;			/* Interrupt handle */
+	device_t dev;
+	int sc_cap;
+#define	CAP_HAS_4WIRE		1	/* Has 4 wire bus */
+#define	CAP_NEEDS_BYTESWAP	2	/* broken hardware needing bounce */
+#define	CAP_MCI1_REV2XX		4	/* MCI 1 rev 2.x */
+	int flags;
+#define PENDING_CMD	0x01
+#define PENDING_STOP	0x02
+#define CMD_MULTIREAD	0x10
+#define CMD_MULTIWRITE	0x20
+	int has_4wire;
+	int allow_overclock;
+	struct resource *irq_res;	/* IRQ resource */
+	struct resource	*mem_res;	/* Memory resource */
+	struct mtx sc_mtx;
+	bus_dma_tag_t dmatag;
+	struct mmc_host host;
+	int bus_busy;
+	struct mmc_request *req;
+	struct mmc_command *curcmd;
+	bus_dmamap_t bbuf_map[BBCOUNT];
+	char      *  bbuf_vaddr[BBCOUNT]; /* bounce bufs in KVA space */
+	uint32_t     bbuf_len[BBCOUNT];	  /* len currently queued for bounce buf */
+	uint32_t     bbuf_curidx;	  /* which bbuf is the active DMA buffer */
+	uint32_t     xfer_offset;	  /* offset so far into caller's buf */
+};
+
+/* bus entry points */
+static int at91_mci_probe(device_t dev);
+static int at91_mci_attach(device_t dev);
+static int at91_mci_detach(device_t dev);
+static void at91_mci_intr(void *);
+
+/* helper routines */
+static int at91_mci_activate(device_t dev);
+static void at91_mci_deactivate(device_t dev);
+static int at91_mci_is_mci1rev2xx(void);
+
+#define AT91_MCI_LOCK(_sc)		mtx_lock(&(_sc)->sc_mtx)
+#define	AT91_MCI_UNLOCK(_sc)		mtx_unlock(&(_sc)->sc_mtx)
+#define AT91_MCI_LOCK_INIT(_sc) \
+	mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->dev), \
+	    "mci", MTX_DEF)
+#define AT91_MCI_LOCK_DESTROY(_sc)	mtx_destroy(&_sc->sc_mtx);
+#define AT91_MCI_ASSERT_LOCKED(_sc)	mtx_assert(&_sc->sc_mtx, MA_OWNED);
+#define AT91_MCI_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED);
+
+static inline uint32_t
+RD4(struct at91_mci_softc *sc, bus_size_t off)
+{
+	return (bus_read_4(sc->mem_res, off));
+}
+
+static inline void
+WR4(struct at91_mci_softc *sc, bus_size_t off, uint32_t val)
+{
+	bus_write_4(sc->mem_res, off, val);
+}
+
+static void
+at91_bswap_buf(struct at91_mci_softc *sc, void * dptr, void * sptr, uint32_t memsize)
+{
+	uint32_t * dst = (uint32_t *)dptr;
+	uint32_t * src = (uint32_t *)sptr;
+	uint32_t   i;
+
+	/*
+	 * If the hardware doesn't need byte-swapping, let bcopy() do the
+	 * work.  Use bounce buffer even if we don't need byteswap, since
+	 * buffer may straddle a page boundry, and we don't handle
+	 * multi-segment transfers in hardware.  Seen from 'bsdlabel -w' which
+	 * uses raw geom access to the volume.  Greg Ansley (gja (at)
+	 * ansley.com)
+	 */
+	if (!(sc->sc_cap & CAP_NEEDS_BYTESWAP)) {
+		memcpy(dptr, sptr, memsize);
+		return;
+	}
+
+	/*
+	 * Nice performance boost for slightly unrolling this loop.
+	 * (But very little extra boost for further unrolling it.)
+	 */
+	for (i = 0; i < memsize; i += 16) {
+		*dst++ = bswap32(*src++);
+		*dst++ = bswap32(*src++);
+		*dst++ = bswap32(*src++);
+		*dst++ = bswap32(*src++);
+	}
+
+	/* Mop up the last 1-3 words, if any. */
+	for (i = 0; i < (memsize & 0x0F); i += 4) {
+		*dst++ = bswap32(*src++);
+	}
+}
+
+static void
+at91_mci_getaddr(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
+{
+	if (error != 0)
+		return;
+	*(bus_addr_t *)arg = segs[0].ds_addr;
+}
+
+static void
+at91_mci_pdc_disable(struct at91_mci_softc *sc)
+{
+	WR4(sc, PDC_PTCR, PDC_PTCR_TXTDIS | PDC_PTCR_RXTDIS);
+	WR4(sc, PDC_RPR, 0);
+	WR4(sc, PDC_RCR, 0);
+	WR4(sc, PDC_RNPR, 0);
+	WR4(sc, PDC_RNCR, 0);
+	WR4(sc, PDC_TPR, 0);
+	WR4(sc, PDC_TCR, 0);
+	WR4(sc, PDC_TNPR, 0);
+	WR4(sc, PDC_TNCR, 0);
+}
+
+/*
+ * Reset the controller, then restore most of the current state.
+ *
+ * This is called after detecting an error.  It's also called after stopping a
+ * multi-block write, to un-wedge the device so that it will handle the NOTBUSY
+ * signal correctly.  See comments in at91_mci_stop_done() for more details.
+ */
+static void at91_mci_reset(struct at91_mci_softc *sc)
+{
+	uint32_t mr;
+	uint32_t sdcr;
+	uint32_t dtor;
+	uint32_t imr;
+
+	at91_mci_pdc_disable(sc);
+
+	/* save current state */
+
+	imr  = RD4(sc, MCI_IMR);
+	mr   = RD4(sc, MCI_MR) & 0x7fff;
+	sdcr = RD4(sc, MCI_SDCR);
+	dtor = RD4(sc, MCI_DTOR);
+
+	/* reset the controller */
+
+	WR4(sc, MCI_IDR, 0xffffffff);
+	WR4(sc, MCI_CR, MCI_CR_MCIDIS | MCI_CR_SWRST);
+
+	/* restore state */
+
+	WR4(sc, MCI_CR, MCI_CR_MCIEN|MCI_CR_PWSEN);
+	WR4(sc, MCI_MR, mr);
+	WR4(sc, MCI_SDCR, sdcr);
+	WR4(sc, MCI_DTOR, dtor);
+	WR4(sc, MCI_IER, imr);
+
+	/*
+	 * Make sure sdio interrupts will fire.  Not sure why reading
+	 * SR ensures that, but this is in the linux driver.
+	 */
+
+	RD4(sc, MCI_SR);
+}
+
+static void
+at91_mci_init(device_t dev)
+{
+	struct at91_mci_softc *sc = device_get_softc(dev);
+	uint32_t val;
+
+	WR4(sc, MCI_CR, MCI_CR_MCIDIS | MCI_CR_SWRST); /* device into reset */
+	WR4(sc, MCI_IDR, 0xffffffff);		/* Turn off interrupts */
+	WR4(sc, MCI_DTOR, MCI_DTOR_DTOMUL_1M | 1);
+	val = MCI_MR_PDCMODE;
+	val |= 0x34a;				/* PWSDIV = 3; CLKDIV = 74 */
+//	if (sc->sc_cap & CAP_MCI1_REV2XX)
+//		val |= MCI_MR_RDPROOF | MCI_MR_WRPROOF;
+	WR4(sc, MCI_MR, val);
+#ifndef  AT91_MCI_SLOT_B
+	WR4(sc, MCI_SDCR, 0);			/* SLOT A, 1 bit bus */
+#else
+	/*
+	 * XXX Really should add second "unit" but nobody using using
+	 * a two slot card that we know of. XXX
+	 */
+	WR4(sc, MCI_SDCR, 1);			/* SLOT B, 1 bit bus */
+#endif
+	/*
+	 * Enable controller, including power-save.  The slower clock
+	 * of the power-save mode is only in effect when there is no
+	 * transfer in progress, so it can be left in this mode all
+	 * the time.
+	 */
+	WR4(sc, MCI_CR, MCI_CR_MCIEN|MCI_CR_PWSEN);
+}
+
+static void
+at91_mci_fini(device_t dev)
+{
+	struct at91_mci_softc *sc = device_get_softc(dev);
+
+	WR4(sc, MCI_IDR, 0xffffffff);		/* Turn off interrupts */
+	at91_mci_pdc_disable(sc);
+	WR4(sc, MCI_CR, MCI_CR_MCIDIS | MCI_CR_SWRST); /* device into reset */
+}
+
+static int
+at91_mci_probe(device_t dev)
+{
+#ifdef FDT
+	if (!ofw_bus_is_compatible(dev, "atmel,hsmci"))
+		return (ENXIO);
+#endif
+	device_set_desc(dev, "MCI mmc/sd host bridge");
+	return (0);
+}
+
+static int
+at91_mci_attach(device_t dev)
+{
+	struct at91_mci_softc *sc = device_get_softc(dev);
+	struct sysctl_ctx_list *sctx;
+	struct sysctl_oid *soid;
+	device_t child;
+	int err, i;
+
+	sctx = device_get_sysctl_ctx(dev);
+	soid = device_get_sysctl_tree(dev);
+
+	sc->dev = dev;
+	sc->sc_cap = 0;
+	if (at91_is_rm92())
+		sc->sc_cap |= CAP_NEEDS_BYTESWAP;
+	/*
+	 * MCI1 Rev 2 controllers need some workarounds, flag if so.
+	 */
+	if (at91_mci_is_mci1rev2xx())
+		sc->sc_cap |= CAP_MCI1_REV2XX;
+
+	err = at91_mci_activate(dev);
+	if (err)
+		goto out;
+
+	AT91_MCI_LOCK_INIT(sc);
+
+	at91_mci_fini(dev);
+	at91_mci_init(dev);
+
+	/*
+	 * Allocate DMA tags and maps and bounce buffers.
+	 *
+	 * The parms in the tag_create call cause the dmamem_alloc call to
+	 * create each bounce buffer as a single contiguous buffer of BBSIZE
+	 * bytes aligned to a 4096 byte boundary.
+	 *
+	 * Do not use DMA_COHERENT for these buffers because that maps the
+	 * memory as non-cachable, which prevents cache line burst fills/writes,
+	 * which is something we need since we're trying to overlap the
+	 * byte-swapping with the DMA operations.
+	 */
+	err = bus_dma_tag_create(bus_get_dma_tag(dev), 4096, 0,
+	    BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
+	    BBSIZE, 1, BBSIZE, 0, NULL, NULL, &sc->dmatag);
+	if (err != 0)
+		goto out;
+
+	for (i = 0; i < BBCOUNT; ++i) {
+		err = bus_dmamem_alloc(sc->dmatag, (void **)&sc->bbuf_vaddr[i],
+		    BUS_DMA_NOWAIT, &sc->bbuf_map[i]);
+		if (err != 0)
+			goto out;
+	}
+
+	/*
+	 * Activate the interrupt
+	 */
+	err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
+	    NULL, at91_mci_intr, sc, &sc->intrhand);
+	if (err) {
+		AT91_MCI_LOCK_DESTROY(sc);
+		goto out;
+	}
+
+	/*
+	 * Allow 4-wire to be initially set via #define.
+	 * Allow a device hint to override that.
+	 * Allow a sysctl to override that.
+	 */
+#if defined(AT91_MCI_HAS_4WIRE) && AT91_MCI_HAS_4WIRE != 0
+	sc->has_4wire = 1;
+#endif
+	resource_int_value(device_get_name(dev), device_get_unit(dev),
+			   "4wire", &sc->has_4wire);
+	SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "4wire",
+	    CTLFLAG_RW, &sc->has_4wire, 0, "has 4 wire SD Card bus");
+	if (sc->has_4wire)
+		sc->sc_cap |= CAP_HAS_4WIRE;
+
+	sc->allow_overclock = AT91_MCI_ALLOW_OVERCLOCK;
+	resource_int_value(device_get_name(dev), device_get_unit(dev),
+			   "allow_overclock", &sc->allow_overclock);
+	SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "allow_overclock",
+	    CTLFLAG_RW, &sc->allow_overclock, 0,
+	    "Allow up to 30MHz clock for 25MHz request when next highest speed 15MHz or less.");
+
+	SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "debug",
+	    CTLFLAG_RWTUN, &mci_debug, 0, "enable debug output");
+
+	/*
+	 * Our real min freq is master_clock/512, but upper driver layers are
+	 * going to set the min speed during card discovery, and the right speed
+	 * for that is 400kHz, so advertise a safe value just under that.
+	 *
+	 * For max speed, while the rm9200 manual says the max is 50mhz, it also
+	 * says it supports only the SD v1.0 spec, which means the real limit is
+	 * 25mhz. On the other hand, historical use has been to slightly violate
+	 * the standard by running the bus at 30MHz.  For more information on
+	 * that, see the comments at the top of this file.
+	 */
+	sc->host.f_min = 375000;
+	sc->host.f_max = at91_master_clock / 2;
+	if (sc->host.f_max > 25000000)
+		sc->host.f_max = 25000000;
+	sc->host.host_ocr = MMC_OCR_320_330 | MMC_OCR_330_340;
+	sc->host.caps = 0;
+	if (sc->sc_cap & CAP_HAS_4WIRE)
+		sc->host.caps |= MMC_CAP_4_BIT_DATA;
+
+	child = device_add_child(dev, "mmc", 0);
+	device_set_ivars(dev, &sc->host);
+	err = bus_generic_attach(dev);
+out:
+	if (err)
+		at91_mci_deactivate(dev);
+	return (err);
+}
+
+static int
+at91_mci_detach(device_t dev)
+{
+	struct at91_mci_softc *sc = device_get_softc(dev);
+
+	at91_mci_fini(dev);
+	at91_mci_deactivate(dev);
+
+	bus_dmamem_free(sc->dmatag, sc->bbuf_vaddr[0], sc->bbuf_map[0]);
+	bus_dmamem_free(sc->dmatag, sc->bbuf_vaddr[1], sc->bbuf_map[1]);
+	bus_dma_tag_destroy(sc->dmatag);
+
+	return (EBUSY);	/* XXX */
+}
+
+static int
+at91_mci_activate(device_t dev)
+{
+	struct at91_mci_softc *sc;
+	int rid;
+
+	sc = device_get_softc(dev);
+	rid = 0;
+	sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	    RF_ACTIVE);
+	if (sc->mem_res == NULL)
+		goto errout;
+
+	rid = 0;
+	sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+	    RF_ACTIVE);
+	if (sc->irq_res == NULL)
+		goto errout;
+
+	return (0);
+errout:
+	at91_mci_deactivate(dev);
+	return (ENOMEM);
+}
+
+static void
+at91_mci_deactivate(device_t dev)
+{
+	struct at91_mci_softc *sc;
+
+	sc = device_get_softc(dev);
+	if (sc->intrhand)
+		bus_teardown_intr(dev, sc->irq_res, sc->intrhand);
+	sc->intrhand = 0;
+	bus_generic_detach(sc->dev);
+	if (sc->mem_res)
+		bus_release_resource(dev, SYS_RES_MEMORY,
+		    rman_get_rid(sc->mem_res), sc->mem_res);
+	sc->mem_res = 0;
+	if (sc->irq_res)
+		bus_release_resource(dev, SYS_RES_IRQ,
+		    rman_get_rid(sc->irq_res), sc->irq_res);
+	sc->irq_res = 0;
+	return;
+}
+
+static int
+at91_mci_is_mci1rev2xx(void)
+{
+
+	switch (soc_info.type) {
+	case AT91_T_SAM9260:
+	case AT91_T_SAM9263:
+	case AT91_T_CAP9:
+	case AT91_T_SAM9G10:
+	case AT91_T_SAM9G20:
+	case AT91_T_SAM9RL:
+		return(1);
+	default:
+		return (0);
+	}
+}
+
+static int
+at91_mci_update_ios(device_t brdev, device_t reqdev)
+{
+	struct at91_mci_softc *sc;
+	struct mmc_ios *ios;
+	uint32_t clkdiv;
+	uint32_t freq;
+
+	sc = device_get_softc(brdev);
+	ios = &sc->host.ios;
+
+	/*
+	 * Calculate our closest available clock speed that doesn't exceed the
+	 * requested speed.
+	 *
+	 * When overclocking is allowed, the requested clock is 25MHz, the
+	 * computed frequency is 15MHz or smaller and clockdiv is 1, use
+	 * clockdiv of 0 to double that.  If less than 12.5MHz, double
+	 * regardless of the overclocking setting.
+	 *
+	 * Whatever we come up with, store it back into ios->clock so that the
+	 * upper layer drivers can report the actual speed of the bus.
+	 */
+	if (ios->clock == 0) {
+		WR4(sc, MCI_CR, MCI_CR_MCIDIS);
+		clkdiv = 0;
+	} else {
+		WR4(sc, MCI_CR, MCI_CR_MCIEN|MCI_CR_PWSEN);
+		if ((at91_master_clock % (ios->clock * 2)) == 0)
+			clkdiv = ((at91_master_clock / ios->clock) / 2) - 1;
+		else
+			clkdiv = (at91_master_clock / ios->clock) / 2;
+		freq = at91_master_clock / ((clkdiv+1) * 2);
+		if (clkdiv == 1 && ios->clock == 25000000 && freq <= 15000000) {
+			if (sc->allow_overclock || freq <= 12500000) {
+				clkdiv = 0;
+				freq = at91_master_clock / ((clkdiv+1) * 2);
+			}
+		}
+		ios->clock = freq;
+	}
+	if (ios->bus_width == bus_width_4)
+		WR4(sc, MCI_SDCR, RD4(sc, MCI_SDCR) | MCI_SDCR_SDCBUS);
+	else
+		WR4(sc, MCI_SDCR, RD4(sc, MCI_SDCR) & ~MCI_SDCR_SDCBUS);
+	WR4(sc, MCI_MR, (RD4(sc, MCI_MR) & ~MCI_MR_CLKDIV) | clkdiv);
+	/* Do we need a settle time here? */
+	/* XXX We need to turn the device on/off here with a GPIO pin */
+	return (0);
+}
+
+static void
+at91_mci_start_cmd(struct at91_mci_softc *sc, struct mmc_command *cmd)
+{
+	uint32_t cmdr, mr;
+	struct mmc_data *data;
+
+	sc->curcmd = cmd;
+	data = cmd->data;
+
+	/* XXX Upper layers don't always set this */
+	cmd->mrq = sc->req;
+
+	/* Begin setting up command register. */
+
+	cmdr = cmd->opcode;
+
+	if (sc->host.ios.bus_mode == opendrain)
+		cmdr |= MCI_CMDR_OPDCMD;
+
+	/* Set up response handling.  Allow max timeout for responses. */
+
+	if (MMC_RSP(cmd->flags) == MMC_RSP_NONE)
+		cmdr |= MCI_CMDR_RSPTYP_NO;
+	else {
+		cmdr |= MCI_CMDR_MAXLAT;
+		if (cmd->flags & MMC_RSP_136)
+			cmdr |= MCI_CMDR_RSPTYP_136;
+		else
+			cmdr |= MCI_CMDR_RSPTYP_48;
+	}
+
+	/*
+	 * If there is no data transfer, just set up the right interrupt mask
+	 * and start the command.
+	 *
+	 * The interrupt mask needs to be CMDRDY plus all non-data-transfer
+	 * errors. It's important to leave the transfer-related errors out, to
+	 * avoid spurious timeout or crc errors on a STOP command following a
+	 * multiblock read.  When a multiblock read is in progress, sending a
+	 * STOP in the middle of a block occasionally triggers such errors, but
+	 * we're totally disinterested in them because we've already gotten all
+	 * the data we wanted without error before sending the STOP command.
+	 */
+
+	if (data == NULL) {
+		uint32_t ier = MCI_SR_CMDRDY |
+		    MCI_SR_RTOE | MCI_SR_RENDE |
+		    MCI_SR_RCRCE | MCI_SR_RDIRE | MCI_SR_RINDE;
+
+		at91_mci_pdc_disable(sc);
+
+		if (cmd->opcode == MMC_STOP_TRANSMISSION)
+			cmdr |= MCI_CMDR_TRCMD_STOP;
+
+		/* Ignore response CRC on CMD2 and ACMD41, per standard. */
+
+		if (cmd->opcode == MMC_SEND_OP_COND ||
+		    cmd->opcode == ACMD_SD_SEND_OP_COND)
+			ier &= ~MCI_SR_RCRCE;
+
+		if (mci_debug)
+			printf("CMDR %x (opcode %d) ARGR %x no data\n",
+			    cmdr, cmd->opcode, cmd->arg);
+
+		WR4(sc, MCI_ARGR, cmd->arg);
+		WR4(sc, MCI_CMDR, cmdr);
+		WR4(sc, MCI_IDR, 0xffffffff);
+		WR4(sc, MCI_IER, ier);
+		return;
+	}
+
+	/* There is data, set up the transfer-related parts of the command. */
+
+	if (data->flags & MMC_DATA_READ)
+		cmdr |= MCI_CMDR_TRDIR;
+
+	if (data->flags & (MMC_DATA_READ | MMC_DATA_WRITE))
+		cmdr |= MCI_CMDR_TRCMD_START;
+
+	if (data->flags & MMC_DATA_STREAM)
+		cmdr |= MCI_CMDR_TRTYP_STREAM;
+	else if (data->flags & MMC_DATA_MULTI) {
+		cmdr |= MCI_CMDR_TRTYP_MULTIPLE;
+		sc->flags |= (data->flags & MMC_DATA_READ) ?
+		    CMD_MULTIREAD : CMD_MULTIWRITE;
+	}
+
+	/*
+	 * Disable PDC until we're ready.
+	 *
+	 * Set block size and turn on PDC mode for dma xfer.
+	 * Note that the block size is the smaller of the amount of data to be
+	 * transferred, or 512 bytes.  The 512 size is fixed by the standard;
+	 * smaller blocks are possible, but never larger.
+	 */
+
+	WR4(sc, PDC_PTCR, PDC_PTCR_RXTDIS | PDC_PTCR_TXTDIS);
+
+	mr = RD4(sc,MCI_MR) & ~MCI_MR_BLKLEN;
+	mr |=  min(data->len, 512) << 16;
+	WR4(sc, MCI_MR, mr | MCI_MR_PDCMODE|MCI_MR_PDCPADV);
+
+	/*
+	 * Set up DMA.
+	 *
+	 * Use bounce buffers even if we don't need to byteswap, because doing
+	 * multi-block IO with large DMA buffers is way fast (compared to
+	 * single-block IO), even after incurring the overhead of also copying
+	 * from/to the caller's buffers (which may be in non-contiguous physical
+	 * pages).
+	 *
+	 * In an ideal non-byteswap world we could create a dma tag that allows
+	 * for discontiguous segments and do the IO directly from/to the
+	 * caller's buffer(s), using ENDRX/ENDTX interrupts to chain the
+	 * discontiguous buffers through the PDC. Someday.
+	 *
+	 * If a read is bigger than 2k, split it in half so that we can start
+	 * byte-swapping the first half while the second half is on the wire.
+	 * It would be best if we could split it into 8k chunks, but we can't
+	 * always keep up with the byte-swapping due to other system activity,
+	 * and if an RXBUFF interrupt happens while we're still handling the
+	 * byte-swap from the prior buffer (IE, we haven't returned from
+	 * handling the prior interrupt yet), then data will get dropped on the
+	 * floor and we can't easily recover from that.  The right fix for that
+	 * would be to have the interrupt handling only keep the DMA flowing and
+	 * enqueue filled buffers to be byte-swapped in a non-interrupt context.
+	 * Even that won't work on the write side of things though; in that
+	 * context we have to have all the data ready to go before starting the
+	 * dma.
+	 *
+	 * XXX what about stream transfers?
+	 */
+	sc->xfer_offset = 0;
+	sc->bbuf_curidx = 0;
+
+	if (data->flags & (MMC_DATA_READ | MMC_DATA_WRITE)) {
+		uint32_t len;
+		uint32_t remaining = data->len;
+		bus_addr_t paddr;
+		int err;
+
+		if (remaining > (BBCOUNT*BBSIZE))
+			panic("IO read size exceeds MAXDATA\n");
+
+		if (data->flags & MMC_DATA_READ) {
+			if (remaining > 2048) // XXX
+				len = remaining / 2;
+			else
+				len = remaining;
+			err = bus_dmamap_load(sc->dmatag, sc->bbuf_map[0],
+			    sc->bbuf_vaddr[0], len, at91_mci_getaddr,
+			    &paddr, BUS_DMA_NOWAIT);
+			if (err != 0)
+				panic("IO read dmamap_load failed\n");
+			bus_dmamap_sync(sc->dmatag, sc->bbuf_map[0],
+			    BUS_DMASYNC_PREREAD);
+			WR4(sc, PDC_RPR, paddr);
+			WR4(sc, PDC_RCR, len / 4);
+			sc->bbuf_len[0] = len;
+			remaining -= len;
+			if (remaining == 0) {
+				sc->bbuf_len[1] = 0;
+			} else {
+				len = remaining;
+				err = bus_dmamap_load(sc->dmatag, sc->bbuf_map[1],
+				    sc->bbuf_vaddr[1], len, at91_mci_getaddr,
+				    &paddr, BUS_DMA_NOWAIT);
+				if (err != 0)
+					panic("IO read dmamap_load failed\n");
+				bus_dmamap_sync(sc->dmatag, sc->bbuf_map[1],
+				    BUS_DMASYNC_PREREAD);
+				WR4(sc, PDC_RNPR, paddr);
+				WR4(sc, PDC_RNCR, len / 4);
+				sc->bbuf_len[1] = len;
+				remaining -= len;
+			}
+			WR4(sc, PDC_PTCR, PDC_PTCR_RXTEN);
+		} else {
+			len = min(BBSIZE, remaining);
+			at91_bswap_buf(sc, sc->bbuf_vaddr[0], data->data, len);
+			err = bus_dmamap_load(sc->dmatag, sc->bbuf_map[0],
+			    sc->bbuf_vaddr[0], len, at91_mci_getaddr,
+			    &paddr, BUS_DMA_NOWAIT);
+			if (err != 0)
+				panic("IO write dmamap_load failed\n");
+			bus_dmamap_sync(sc->dmatag, sc->bbuf_map[0],
+			    BUS_DMASYNC_PREWRITE);
+			/*
+			 * Erratum workaround:  PDC transfer length on a write
+			 * must not be smaller than 12 bytes (3 words); only
+			 * blklen bytes (set above) are actually transferred.
+			 */
+			WR4(sc, PDC_TPR,paddr);
+			WR4(sc, PDC_TCR, (len < 12) ? 3 : len / 4);
+			sc->bbuf_len[0] = len;
+			remaining -= len;
+			if (remaining == 0) {
+				sc->bbuf_len[1] = 0;
+			} else {
+				len = remaining;
+				at91_bswap_buf(sc, sc->bbuf_vaddr[1],
+				    ((char *)data->data)+BBSIZE, len);
+				err = bus_dmamap_load(sc->dmatag, sc->bbuf_map[1],
+				    sc->bbuf_vaddr[1], len, at91_mci_getaddr,
+				    &paddr, BUS_DMA_NOWAIT);
+				if (err != 0)
+					panic("IO write dmamap_load failed\n");
+				bus_dmamap_sync(sc->dmatag, sc->bbuf_map[1],
+				    BUS_DMASYNC_PREWRITE);
+				WR4(sc, PDC_TNPR, paddr);
+				WR4(sc, PDC_TNCR, (len < 12) ? 3 : len / 4);
+				sc->bbuf_len[1] = len;
+				remaining -= len;
+			}
+			/* do not enable PDC xfer until CMDRDY asserted */
+		}
+		data->xfer_len = 0; /* XXX what's this? appears to be unused. */
+	}
+
+	if (mci_debug)
+		printf("CMDR %x (opcode %d) ARGR %x with data len %d\n",
+		       cmdr, cmd->opcode, cmd->arg, cmd->data->len);
+
+	WR4(sc, MCI_ARGR, cmd->arg);
+	WR4(sc, MCI_CMDR, cmdr);
+	WR4(sc, MCI_IER, MCI_SR_ERROR | MCI_SR_CMDRDY);
+}
+
+static void
+at91_mci_next_operation(struct at91_mci_softc *sc)
+{
+	struct mmc_request *req;
+
+	req = sc->req;
+	if (req == NULL)
+		return;
+
+	if (sc->flags & PENDING_CMD) {
+		sc->flags &= ~PENDING_CMD;
+		at91_mci_start_cmd(sc, req->cmd);
+		return;
+	} else if (sc->flags & PENDING_STOP) {
+		sc->flags &= ~PENDING_STOP;
+		at91_mci_start_cmd(sc, req->stop);
+		return;
+	}
+
+	WR4(sc, MCI_IDR, 0xffffffff);
+	sc->req = NULL;
+	sc->curcmd = NULL;
+	//printf("req done\n");
+	req->done(req);
+}
+
+static int
+at91_mci_request(device_t brdev, device_t reqdev, struct mmc_request *req)
+{
+	struct at91_mci_softc *sc = device_get_softc(brdev);
+
+	AT91_MCI_LOCK(sc);
+	if (sc->req != NULL) {
+		AT91_MCI_UNLOCK(sc);
+		return (EBUSY);
+	}
+	//printf("new req\n");
+	sc->req = req;
+	sc->flags = PENDING_CMD;
+	if (sc->req->stop)
+		sc->flags |= PENDING_STOP;
+	at91_mci_next_operation(sc);
+	AT91_MCI_UNLOCK(sc);
+	return (0);
+}
+
+static int
+at91_mci_get_ro(device_t brdev, device_t reqdev)
+{
+	return (0);
+}
+
+static int
+at91_mci_acquire_host(device_t brdev, device_t reqdev)
+{
+	struct at91_mci_softc *sc = device_get_softc(brdev);
+	int err = 0;
+
+	AT91_MCI_LOCK(sc);
+	while (sc->bus_busy)
+		msleep(sc, &sc->sc_mtx, PZERO, "mciah", hz / 5);
+	sc->bus_busy++;
+	AT91_MCI_UNLOCK(sc);
+	return (err);
+}
+
+static int
+at91_mci_release_host(device_t brdev, device_t reqdev)
+{
+	struct at91_mci_softc *sc = device_get_softc(brdev);
+
+	AT91_MCI_LOCK(sc);
+	sc->bus_busy--;
+	wakeup(sc);
+	AT91_MCI_UNLOCK(sc);
+	return (0);
+}
+
+static void
+at91_mci_read_done(struct at91_mci_softc *sc, uint32_t sr)
+{
+	struct mmc_command *cmd = sc->curcmd;
+	char * dataptr = (char *)cmd->data->data;
+	uint32_t curidx = sc->bbuf_curidx;
+	uint32_t len = sc->bbuf_len[curidx];
+
+	/*
+	 * We arrive here when a DMA transfer for a read is done, whether it's
+	 * a single or multi-block read.
+	 *
+	 * We byte-swap the buffer that just completed, and if that is the
+	 * last buffer that's part of this read then we move on to the next
+	 * operation, otherwise we wait for another ENDRX for the next bufer.
+	 */
+
+	bus_dmamap_sync(sc->dmatag, sc->bbuf_map[curidx], BUS_DMASYNC_POSTREAD);
+	bus_dmamap_unload(sc->dmatag, sc->bbuf_map[curidx]);
+
+	at91_bswap_buf(sc, dataptr + sc->xfer_offset, sc->bbuf_vaddr[curidx], len);
+
+	if (mci_debug) {
+		printf("read done sr %x curidx %d len %d xfer_offset %d\n",
+		       sr, curidx, len, sc->xfer_offset);
+	}
+
+	sc->xfer_offset += len;
+	sc->bbuf_curidx = !curidx; /* swap buffers */
+
+	/*
+	 * If we've transferred all the data, move on to the next operation.
+	 *
+	 * If we're still transferring the last buffer, RNCR is already zero but
+	 * we have to write a zero anyway to clear the ENDRX status so we don't
+	 * re-interrupt until the last buffer is done.
+	 */
+	if (sc->xfer_offset == cmd->data->len) {
+		WR4(sc, PDC_PTCR, PDC_PTCR_RXTDIS | PDC_PTCR_TXTDIS);
+		cmd->error = MMC_ERR_NONE;
+		at91_mci_next_operation(sc);
+	} else {
+		WR4(sc, PDC_RNCR, 0);
+		WR4(sc, MCI_IER, MCI_SR_ERROR | MCI_SR_ENDRX);
+	}
+}
+
+static void
+at91_mci_write_done(struct at91_mci_softc *sc, uint32_t sr)
+{
+	struct mmc_command *cmd = sc->curcmd;
+
+	/*
+	 * We arrive here when the entire DMA transfer for a write is done,
+	 * whether it's a single or multi-block write.  If it's multi-block we
+	 * have to immediately move on to the next operation which is to send
+	 * the stop command.  If it's a single-block transfer we need to wait
+	 * for NOTBUSY, but if that's already asserted we can avoid another
+	 * interrupt and just move on to completing the request right away.
+	 */
+
+	WR4(sc, PDC_PTCR, PDC_PTCR_RXTDIS | PDC_PTCR_TXTDIS);
+
+	bus_dmamap_sync(sc->dmatag, sc->bbuf_map[sc->bbuf_curidx],
+	    BUS_DMASYNC_POSTWRITE);
+	bus_dmamap_unload(sc->dmatag, sc->bbuf_map[sc->bbuf_curidx]);
+
+	if ((cmd->data->flags & MMC_DATA_MULTI) || (sr & MCI_SR_NOTBUSY)) {
+		cmd->error = MMC_ERR_NONE;
+		at91_mci_next_operation(sc);
+	} else {
+		WR4(sc, MCI_IER, MCI_SR_ERROR | MCI_SR_NOTBUSY);
+	}
+}
+
+static void
+at91_mci_notbusy(struct at91_mci_softc *sc)
+{
+	struct mmc_command *cmd = sc->curcmd;
+
+	/*
+	 * We arrive here by either completion of a single-block write, or
+	 * completion of the stop command that ended a multi-block write (and,
+	 * I suppose, after a card-select or erase, but I haven't tested
+	 * those).  Anyway, we're done and it's time to move on to the next
+	 * command.
+	 */
+
+	cmd->error = MMC_ERR_NONE;
+	at91_mci_next_operation(sc);
+}
+
+static void
+at91_mci_stop_done(struct at91_mci_softc *sc, uint32_t sr)
+{
+	struct mmc_command *cmd = sc->curcmd;
+
+	/*
+	 * We arrive here after receiving CMDRDY for a MMC_STOP_TRANSMISSION
+	 * command.  Depending on the operation being stopped, we may have to
+	 * do some unusual things to work around hardware bugs.
+	 */
+
+	/*
+	 * This is known to be true of at91rm9200 hardware; it may or may not
+	 * apply to more recent chips:
+	 *
+	 * After stopping a multi-block write, the NOTBUSY bit in MCI_SR does
+	 * not properly reflect the actual busy state of the card as signaled
+	 * on the DAT0 line; it always claims the card is not-busy.  If we
+	 * believe that and let operations continue, following commands will
+	 * fail with response timeouts (except of course MMC_SEND_STATUS -- it
+	 * indicates the card is busy in the PRG state, which was the smoking
+	 * gun that showed MCI_SR NOTBUSY was not tracking DAT0 correctly).
+	 *
+	 * The atmel docs are emphatic: "This flag [NOTBUSY] must be used only
+	 * for Write Operations."  I guess technically since we sent a stop
+	 * it's not a write operation anymore.  But then just what did they
+	 * think it meant for the stop command to have "...an optional busy
+	 * signal transmitted on the data line" according to the SD spec?
+	 *
+	 * I tried a variety of things to un-wedge the MCI and get the status
+	 * register to reflect NOTBUSY correctly again, but the only thing
+	 * that worked was a full device reset.  It feels like an awfully big
+	 * hammer, but doing a full reset after every multiblock write is
+	 * still faster than doing single-block IO (by almost two orders of
+	 * magnitude: 20KB/sec improves to about 1.8MB/sec best case).
+	 *
+	 * After doing the reset, wait for a NOTBUSY interrupt before
+	 * continuing with the next operation.
+	 *
+	 * This workaround breaks multiwrite on the rev2xx parts, but some other
+	 * workaround is needed.
+	 */
+	if ((sc->flags & CMD_MULTIWRITE) && (sc->sc_cap & CAP_NEEDS_BYTESWAP)) {
+		at91_mci_reset(sc);
+		WR4(sc, MCI_IER, MCI_SR_ERROR | MCI_SR_NOTBUSY);
+		return;
+	}
+
+	/*
+	 * This is known to be true of at91rm9200 hardware; it may or may not
+	 * apply to more recent chips:
+	 *
+	 * After stopping a multi-block read, loop to read and discard any
+	 * data that coasts in after we sent the stop command.  The docs don't
+	 * say anything about it, but empirical testing shows that 1-3
+	 * additional words of data get buffered up in some unmentioned
+	 * internal fifo and if we don't read and discard them here they end
+	 * up on the front of the next read DMA transfer we do.
+	 *
+	 * This appears to be unnecessary for rev2xx parts.
+	 */
+	if ((sc->flags & CMD_MULTIREAD) && (sc->sc_cap & CAP_NEEDS_BYTESWAP)) {
+		uint32_t sr;
+		int count = 0;
+
+		do {
+			sr = RD4(sc, MCI_SR);
+			if (sr & MCI_SR_RXRDY) {
+				RD4(sc,  MCI_RDR);
+				++count;
+			}
+		} while (sr & MCI_SR_RXRDY);
+		at91_mci_reset(sc);
+	}
+
+	cmd->error = MMC_ERR_NONE;
+	at91_mci_next_operation(sc);
+
+}
+
+static void
+at91_mci_cmdrdy(struct at91_mci_softc *sc, uint32_t sr)
+{
+	struct mmc_command *cmd = sc->curcmd;
+	int i;
+
+	if (cmd == NULL)
+		return;
+
+	/*
+	 * We get here at the end of EVERY command.  We retrieve the command
+	 * response (if any) then decide what to do next based on the command.
+	 */
+
+	if (cmd->flags & MMC_RSP_PRESENT) {
+		for (i = 0; i < ((cmd->flags & MMC_RSP_136) ? 4 : 1); i++) {
+			cmd->resp[i] = RD4(sc, MCI_RSPR + i * 4);
+			if (mci_debug)
+				printf("RSPR[%d] = %x sr=%x\n", i, cmd->resp[i],  sr);
+		}
+	}
+
+	/*
+	 * If this was a stop command, go handle the various special
+	 * conditions (read: bugs) that have to be dealt with following a stop.
+	 */
+	if (cmd->opcode == MMC_STOP_TRANSMISSION) {
+		at91_mci_stop_done(sc, sr);
+		return;
+	}
+
+	/*
+	 * If this command can continue to assert BUSY beyond the response then
+	 * we need to wait for NOTBUSY before the command is really done.
+	 *
+	 * Note that this may not work properly on the at91rm9200.  It certainly
+	 * doesn't work for the STOP command that follows a multi-block write,
+	 * so post-stop CMDRDY is handled separately; see the special handling
+	 * in at91_mci_stop_done().
+	 *
+	 * Beside STOP, there are other R1B-type commands that use the busy
+	 * signal after CMDRDY: CMD7 (card select), CMD28-29 (write protect),
+	 * CMD38 (erase). I haven't tested any of them, but I rather expect
+	 * them all to have the same sort of problem with MCI_SR not actually
+	 * reflecting the state of the DAT0-line busy indicator.  So this code
+	 * may need to grow some sort of special handling for them too. (This
+	 * just in: CMD7 isn't a problem right now because dev/mmc.c incorrectly
+	 * sets the response flags to R1 rather than R1B.) XXX
+	 */
+	if ((cmd->flags & MMC_RSP_BUSY)) {
+		WR4(sc, MCI_IER, MCI_SR_ERROR | MCI_SR_NOTBUSY);
+		return;
+	}
+
+	/*
+	 * If there is a data transfer with this command, then...
+	 * - If it's a read, we need to wait for ENDRX.
+	 * - If it's a write, now is the time to enable the PDC, and we need
+	 *   to wait for a BLKE that follows a TXBUFE, because if we're doing
+	 *   a split transfer we get a BLKE after the first half (when TPR/TCR
+	 *   get loaded from TNPR/TNCR).  So first we wait for the TXBUFE, and
+	 *   the handling for that interrupt will then invoke the wait for the
+	 *   subsequent BLKE which indicates actual completion.
+	 */
+	if (cmd->data) {
+		uint32_t ier;
+		if (cmd->data->flags & MMC_DATA_READ) {
+			ier = MCI_SR_ENDRX;
+		} else {
+			ier = MCI_SR_TXBUFE;
+			WR4(sc, PDC_PTCR, PDC_PTCR_TXTEN);
+		}
+		WR4(sc, MCI_IER, MCI_SR_ERROR | ier);
+		return;
+	}
+
+	/*
+	 * If we made it to here, we don't need to wait for anything more for
+	 * the current command, move on to the next command (will complete the
+	 * request if there is no next command).
+	 */
+	cmd->error = MMC_ERR_NONE;
+	at91_mci_next_operation(sc);
+}
+
+static void
+at91_mci_intr(void *arg)
+{
+	struct at91_mci_softc *sc = (struct at91_mci_softc*)arg;
+	struct mmc_command *cmd = sc->curcmd;
+	uint32_t sr, isr;
+
+	AT91_MCI_LOCK(sc);
+
+	sr = RD4(sc, MCI_SR);
+	isr = sr & RD4(sc, MCI_IMR);
+
+	if (mci_debug)
+		printf("i 0x%x sr 0x%x\n", isr, sr);
+
+	/*
+	 * All interrupts are one-shot; disable it now.
+	 * The next operation will re-enable whatever interrupts it wants.
+	 */
+	WR4(sc, MCI_IDR, isr);
+	if (isr & MCI_SR_ERROR) {
+		if (isr & (MCI_SR_RTOE | MCI_SR_DTOE))
+			cmd->error = MMC_ERR_TIMEOUT;
+		else if (isr & (MCI_SR_RCRCE | MCI_SR_DCRCE))
+			cmd->error = MMC_ERR_BADCRC;
+		else if (isr & (MCI_SR_OVRE | MCI_SR_UNRE))
+			cmd->error = MMC_ERR_FIFO;
+		else
+			cmd->error = MMC_ERR_FAILED;
+		/*
+		 * CMD8 is used to probe for SDHC cards, a standard SD card
+		 * will get a response timeout; don't report it because it's a
+		 * normal and expected condition.  One might argue that all
+		 * error reporting should be left to higher levels, but when
+		 * they report at all it's always EIO, which isn't very
+		 * helpful. XXX bootverbose?
+		 */
+		if (cmd->opcode != 8) {
+			device_printf(sc->dev,
+			    "IO error; status MCI_SR = 0x%x cmd opcode = %d%s\n",
+			    sr, cmd->opcode,
+			    (cmd->opcode != 12) ? "" :
+			    (sc->flags & CMD_MULTIREAD) ? " after read" : " after write");
+			at91_mci_reset(sc);
+		}
+		at91_mci_next_operation(sc);
+	} else {
+		if (isr & MCI_SR_TXBUFE) {
+//			printf("TXBUFE\n");
+			/*
+			 * We need to wait for a BLKE that follows TXBUFE
+			 * (intermediate BLKEs might happen after ENDTXes if
+			 * we're chaining multiple buffers).  If BLKE is also
+			 * asserted at the time we get TXBUFE, we can avoid
+			 * another interrupt and process it right away, below.
+			 */
+			if (sr & MCI_SR_BLKE)
+				isr |= MCI_SR_BLKE;
+			else
+				WR4(sc, MCI_IER, MCI_SR_BLKE);
+		}
+		if (isr & MCI_SR_RXBUFF) {
+//			printf("RXBUFF\n");
+		}
+		if (isr & MCI_SR_ENDTX) {
+//			printf("ENDTX\n");
+		}
+		if (isr & MCI_SR_ENDRX) {
+//			printf("ENDRX\n");
+			at91_mci_read_done(sc, sr);
+		}
+		if (isr & MCI_SR_NOTBUSY) {
+//			printf("NOTBUSY\n");
+			at91_mci_notbusy(sc);
+		}
+		if (isr & MCI_SR_DTIP) {
+//			printf("Data transfer in progress\n");
+		}
+		if (isr & MCI_SR_BLKE) {
+//			printf("Block transfer end\n");
+			at91_mci_write_done(sc, sr);
+		}
+		if (isr & MCI_SR_TXRDY) {
+//			printf("Ready to transmit\n");
+		}
+		if (isr & MCI_SR_RXRDY) {
+//			printf("Ready to receive\n");
+		}
+		if (isr & MCI_SR_CMDRDY) {
+//			printf("Command ready\n");
+			at91_mci_cmdrdy(sc, sr);
+		}
+	}
+	AT91_MCI_UNLOCK(sc);
+}
+
+static int
+at91_mci_read_ivar(device_t bus, device_t child, int which, uintptr_t *result)
+{
+	struct at91_mci_softc *sc = device_get_softc(bus);
+
+	switch (which) {
+	default:
+		return (EINVAL);
+	case MMCBR_IVAR_BUS_MODE:
+		*(int *)result = sc->host.ios.bus_mode;
+		break;
+	case MMCBR_IVAR_BUS_WIDTH:
+		*(int *)result = sc->host.ios.bus_width;
+		break;
+	case MMCBR_IVAR_CHIP_SELECT:
+		*(int *)result = sc->host.ios.chip_select;
+		break;
+	case MMCBR_IVAR_CLOCK:
+		*(int *)result = sc->host.ios.clock;
+		break;
+	case MMCBR_IVAR_F_MIN:
+		*(int *)result = sc->host.f_min;
+		break;
+	case MMCBR_IVAR_F_MAX:
+		*(int *)result = sc->host.f_max;
+		break;
+	case MMCBR_IVAR_HOST_OCR:
+		*(int *)result = sc->host.host_ocr;
+		break;
+	case MMCBR_IVAR_MODE:
+		*(int *)result = sc->host.mode;
+		break;
+	case MMCBR_IVAR_OCR:
+		*(int *)result = sc->host.ocr;
+		break;
+	case MMCBR_IVAR_POWER_MODE:
+		*(int *)result = sc->host.ios.power_mode;
+		break;
+	case MMCBR_IVAR_VDD:
+		*(int *)result = sc->host.ios.vdd;
+		break;
+	case MMCBR_IVAR_CAPS:
+		if (sc->has_4wire) {
+			sc->sc_cap |= CAP_HAS_4WIRE;
+			sc->host.caps |= MMC_CAP_4_BIT_DATA;
+		} else {
+			sc->sc_cap &= ~CAP_HAS_4WIRE;
+			sc->host.caps &= ~MMC_CAP_4_BIT_DATA;
+		}
+		*(int *)result = sc->host.caps;
+		break;
+	case MMCBR_IVAR_MAX_DATA:
+		/*
+		 * Something is wrong with the 2x parts and multiblock, so
+		 * just do 1 block at a time for now, which really kills
+		 * performance.
+		 */
+		if (sc->sc_cap & CAP_MCI1_REV2XX)
+			*(int *)result = 1;
+		else
+			*(int *)result = MAX_BLOCKS;
+		break;
+	}
+	return (0);
+}
+
+static int
+at91_mci_write_ivar(device_t bus, device_t child, int which, uintptr_t value)
+{
+	struct at91_mci_softc *sc = device_get_softc(bus);
+
+	switch (which) {
+	default:
+		return (EINVAL);
+	case MMCBR_IVAR_BUS_MODE:
+		sc->host.ios.bus_mode = value;
+		break;
+	case MMCBR_IVAR_BUS_WIDTH:
+		sc->host.ios.bus_width = value;
+		break;
+	case MMCBR_IVAR_CHIP_SELECT:
+		sc->host.ios.chip_select = value;
+		break;
+	case MMCBR_IVAR_CLOCK:
+		sc->host.ios.clock = value;
+		break;
+	case MMCBR_IVAR_MODE:
+		sc->host.mode = value;
+		break;
+	case MMCBR_IVAR_OCR:
+		sc->host.ocr = value;
+		break;
+	case MMCBR_IVAR_POWER_MODE:
+		sc->host.ios.power_mode = value;
+		break;
+	case MMCBR_IVAR_VDD:
+		sc->host.ios.vdd = value;
+		break;
+	/* These are read-only */
+	case MMCBR_IVAR_CAPS:
+	case MMCBR_IVAR_HOST_OCR:
+	case MMCBR_IVAR_F_MIN:
+	case MMCBR_IVAR_F_MAX:
+	case MMCBR_IVAR_MAX_DATA:
+		return (EINVAL);
+	}
+	return (0);
+}
+
+static device_method_t at91_mci_methods[] = {
+	/* device_if */
+	DEVMETHOD(device_probe, at91_mci_probe),
+	DEVMETHOD(device_attach, at91_mci_attach),
+	DEVMETHOD(device_detach, at91_mci_detach),
+
+	/* Bus interface */
+	DEVMETHOD(bus_read_ivar,	at91_mci_read_ivar),
+	DEVMETHOD(bus_write_ivar,	at91_mci_write_ivar),
+
+	/* mmcbr_if */
+	DEVMETHOD(mmcbr_update_ios, at91_mci_update_ios),
+	DEVMETHOD(mmcbr_request, at91_mci_request),
+	DEVMETHOD(mmcbr_get_ro, at91_mci_get_ro),
+	DEVMETHOD(mmcbr_acquire_host, at91_mci_acquire_host),
+	DEVMETHOD(mmcbr_release_host, at91_mci_release_host),
+
+	DEVMETHOD_END
+};
+
+static driver_t at91_mci_driver = {
+	"at91_mci",
+	at91_mci_methods,
+	sizeof(struct at91_mci_softc),
+};
+
+static devclass_t at91_mci_devclass;
+
+#ifdef FDT
+DRIVER_MODULE(at91_mci, simplebus, at91_mci_driver, at91_mci_devclass, NULL,
+    NULL);
+#else
+DRIVER_MODULE(at91_mci, atmelarm, at91_mci_driver, at91_mci_devclass, NULL,
+    NULL);
+#endif
+
+MMC_DECLARE_BRIDGE(at91_mci);


Property changes on: trunk/sys/arm/at91/at91_mci.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91_mcireg.h
===================================================================
--- trunk/sys/arm/at91/at91_mcireg.h	                        (rev 0)
+++ trunk/sys/arm/at91/at91_mcireg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,133 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2006 Berndt Walter.  All rights reserved.
+ * Copyright (c) 2006 M. Warner Losh.  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 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 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: stable/10/sys/arm/at91/at91_mcireg.h 234560 2012-04-22 00:43:32Z marius $ */
+
+#ifndef ARM_AT91_AT91_MCIREG_H
+#define ARM_AT91_AT91_MCIREG_H
+
+#define MMC_MAX		30
+
+#define MCI_CR 		0x00 	/* MCI Control Register */
+#define MCI_MR		0x04 	/* MCI Mode Register */
+#define MCI_DTOR	0x08 	/* MCI Data Timeout Register */
+#define MCI_SDCR	0x0c 	/* MCI SD Card Register */
+#define MCI_ARGR	0x10 	/* MCI Argument Register */
+#define MCI_CMDR	0x14 	/* MCI Command Register */
+#define MCI_RSPR	0x20 	/* MCI Response Registers - 4 of them */
+#define MCI_RDR		0x30 	/* MCI Receive Data Register */
+#define MCI_TDR		0x34 	/* MCI Transmit Data Register */
+#define MCI_SR		0x40 	/* MCI Status Register */
+#define MCI_IER		0x44 	/* MCI Interrupt Enable Register */
+#define MCI_IDR		0x48 	/* MCI Interrupt Disable Register */
+#define MCI_IMR		0x4c 	/* MCI Interrupt Mask Register */
+
+/* -------- MCI_CR : (MCI Offset: 0x0) MCI Control Register --------  */
+#define	MCI_CR_MCIEN       (0x1u <<  0) /* (MCI) Multimedia Interface Enable */
+#define	MCI_CR_MCIDIS      (0x1u <<  1) /* (MCI) Multimedia Interface Disable */
+#define	MCI_CR_PWSEN       (0x1u <<  2) /* (MCI) Power Save Mode Enable */
+#define	MCI_CR_PWSDIS      (0x1u <<  3) /* (MCI) Power Save Mode Disable */
+#define	MCI_CR_SWRST      (0x1u <<  7) /* (MCI) Software Reset */
+/* -------- MCI_MR : (MCI Offset: 0x4) MCI Mode Register --------  */
+#define	MCI_MR_CLKDIV      (0xffu <<  0) /* (MCI) Clock Divider */
+#define	MCI_MR_PWSDIV      (0x3fu <<  8) /* (MCI) Power Saving Divider */
+#define	MCI_MR_RDPROOF	(0x1u << 11)	/* (MCI) Read Proof Enable */
+#define	MCI_MR_WRPROOF	(0x1u << 12)	/* (MCI) Write Proof Enable */
+#define	MCI_MR_PDCFBYTE	(0x1u << 13)	/* (MCI) PDC Force Byte Transfer */
+#define	MCI_MR_PDCPADV     (0x1u << 14) /* (MCI) PDC Padding Value */
+#define	MCI_MR_PDCMODE     (0x1u << 15) /* (MCI) PDC Oriented Mode */
+#define	MCI_MR_BLKLEN      0x3fff0000ul /* (MCI) Data Block Length */
+/* -------- MCI_DTOR : (MCI Offset: 0x8) MCI Data Timeout Register --------  */
+#define	MCI_DTOR_DTOCYC      (0xfu <<  0) /* (MCI) Data Timeout Cycle Number */
+#define	MCI_DTOR_DTOMUL      (0x7u <<  4) /* (MCI) Data Timeout Multiplier */
+#define		MCI_DTOR_DTOMUL_1                    (0x0u <<  4) /* (MCI) DTOCYC x 1 */
+#define		MCI_DTOR_DTOMUL_16                   (0x1u <<  4) /* (MCI) DTOCYC x 16 */
+#define		MCI_DTOR_DTOMUL_128                  (0x2u <<  4) /* (MCI) DTOCYC x 128 */
+#define		MCI_DTOR_DTOMUL_256                  (0x3u <<  4) /* (MCI) DTOCYC x 256 */
+#define		MCI_DTOR_DTOMUL_1k                   (0x4u <<  4) /* (MCI) DTOCYC x 1024 */
+#define		MCI_DTOR_DTOMUL_4k                   (0x5u <<  4) /* (MCI) DTOCYC x 4096 */
+#define		MCI_DTOR_DTOMUL_64k                  (0x6u <<  4) /* (MCI) DTOCYC x 65536 */
+#define		MCI_DTOR_DTOMUL_1M                   (0x7u <<  4) /* (MCI) DTOCYC x 1048576 */
+/* -------- MCI_SDCR : (MCI Offset: 0xc) MCI SD Card Register --------  */
+#define	MCI_SDCR_SDCSEL      (0x1u <<  0) /* (MCI) SD Card Selector */
+#define	MCI_SDCR_SDCBUS      (0x1u <<  7) /* (MCI) SD Card Bus Width */
+/* -------- MCI_CMDR : (MCI Offset: 0x14) MCI Command Register --------  */
+#define	MCI_CMDR_CMDNB       (0x1Fu <<  0) /* (MCI) Command Number */
+#define	MCI_CMDR_RSPTYP      (0x3u <<  6) /* (MCI) Response Type */
+#define		MCI_CMDR_RSPTYP_NO                   (0x0u <<  6) /* (MCI) No response */
+#define		MCI_CMDR_RSPTYP_48                   (0x1u <<  6) /* (MCI) 48-bit response */
+#define		MCI_CMDR_RSPTYP_136                  (0x2u <<  6) /* (MCI) 136-bit response */
+#define	MCI_CMDR_SPCMD       (0x7u <<  8) /* (MCI) Special CMD */
+#define		MCI_CMDR_SPCMD_NONE                 (0x0u <<  8) /* (MCI) Not a special CMD */
+#define		MCI_CMDR_SPCMD_INIT                 (0x1u <<  8) /* (MCI) Initialization CMD */
+#define		MCI_CMDR_SPCMD_SYNC                 (0x2u <<  8) /* (MCI) Synchronized CMD */
+#define		MCI_CMDR_SPCMD_IT_CMD               (0x4u <<  8) /* (MCI) Interrupt command */
+#define		MCI_CMDR_SPCMD_IT_REP               (0x5u <<  8) /* (MCI) Interrupt response */
+#define	MCI_CMDR_OPDCMD      (0x1u << 11) /* (MCI) Open Drain Command */
+#define	MCI_CMDR_MAXLAT      (0x1u << 12) /* (MCI) Maximum Latency for Command to respond */
+#define	MCI_CMDR_TRCMD       (0x3u << 16) /* (MCI) Transfer CMD */
+#define		MCI_CMDR_TRCMD_NO                   (0x0u << 16) /* (MCI) No transfer */
+#define		MCI_CMDR_TRCMD_START                (0x1u << 16) /* (MCI) Start transfer */
+#define		MCI_CMDR_TRCMD_STOP                 (0x2u << 16) /* (MCI) Stop transfer */
+#define	MCI_CMDR_TRDIR       (0x1u << 18) /* (MCI) Transfer Direction */
+#define	MCI_CMDR_TRTYP       (0x3u << 19) /* (MCI) Transfer Type */
+#define		MCI_CMDR_TRTYP_BLOCK                (0x0u << 19) /* (MCI) Block Transfer type */
+#define		MCI_CMDR_TRTYP_MULTIPLE             (0x1u << 19) /* (MCI) Multiple Block transfer type */
+#define		MCI_CMDR_TRTYP_STREAM               (0x2u << 19) /* (MCI) Stream transfer type */
+/* -------- MCI_SR : (MCI Offset: 0x40) MCI Status Register --------  */
+#define	MCI_SR_CMDRDY   (0x1u <<  0) /* (MCI) Command Ready flag */
+#define	MCI_SR_RXRDY    (0x1u <<  1) /* (MCI) RX Ready flag */
+#define	MCI_SR_TXRDY    (0x1u <<  2) /* (MCI) TX Ready flag */
+#define	MCI_SR_BLKE     (0x1u <<  3) /* (MCI) Data Block Transfer Ended flag */
+#define	MCI_SR_DTIP     (0x1u <<  4) /* (MCI) Data Transfer in Progress flag */
+#define	MCI_SR_NOTBUSY  (0x1u <<  5) /* (MCI) Data Line Not Busy flag */
+#define	MCI_SR_ENDRX    (0x1u <<  6) /* (MCI) End of RX Buffer flag */
+#define	MCI_SR_ENDTX    (0x1u <<  7) /* (MCI) End of TX Buffer flag */
+#define	MCI_SR_RXBUFF   (0x1u << 14) /* (MCI) RX Buffer Full flag */
+#define	MCI_SR_TXBUFE   (0x1u << 15) /* (MCI) TX Buffer Empty flag */
+#define	MCI_SR_RINDE    (0x1u << 16) /* (MCI) Response Index Error flag */
+#define	MCI_SR_RDIRE    (0x1u << 17) /* (MCI) Response Direction Error flag */
+#define	MCI_SR_RCRCE    (0x1u << 18) /* (MCI) Response CRC Error flag */
+#define	MCI_SR_RENDE    (0x1u << 19) /* (MCI) Response End Bit Error flag */
+#define	MCI_SR_RTOE     (0x1u << 20) /* (MCI) Response Time-out Error flag */
+#define	MCI_SR_DCRCE    (0x1u << 21) /* (MCI) data CRC Error flag */
+#define	MCI_SR_DTOE     (0x1u << 22) /* (MCI) Data timeout Error flag */
+#define	MCI_SR_OVRE     (0x1u << 30) /* (MCI) Overrun flag */
+#define	MCI_SR_UNRE     (0x1u << 31) /* (MCI) Underrun flag */
+
+/* -------- MCI_IER : (MCI Offset: 0x44) MCI Interrupt Enable Register --------  */
+/* -------- MCI_IDR : (MCI Offset: 0x48) MCI Interrupt Disable Register --------  */
+/* -------- MCI_IMR : (MCI Offset: 0x4c) MCI Interrupt Mask Register --------  */
+
+#define MCI_SR_ERROR	(MCI_SR_UNRE | MCI_SR_OVRE | MCI_SR_DTOE | \
+			MCI_SR_DCRCE | MCI_SR_RTOE | MCI_SR_RENDE | \
+			MCI_SR_RCRCE | MCI_SR_RDIRE | MCI_SR_RINDE)
+
+#define AT91C_BUS_WIDTH_1BIT		0x00
+#define AT91C_BUS_WIDTH_4BITS		0x02
+
+#endif /* ARM_AT91_AT91_MCIREG_H */


Property changes on: trunk/sys/arm/at91/at91_mcireg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91_pdcreg.h
===================================================================
--- trunk/sys/arm/at91/at91_pdcreg.h	                        (rev 0)
+++ trunk/sys/arm/at91/at91_pdcreg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,49 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2006 M. Warner Losh.  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 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 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: stable/10/sys/arm/at91/at91_pdcreg.h 185265 2008-11-25 00:13:26Z imp $ */
+
+#ifndef ARM_AT91_AT91_PDCREG_H
+#define ARM_AT91_AT91_PDCREG_H
+
+#define PDC_RPR		0x100		/* PDC Receive Pointer Register */
+#define PDC_RCR		0x104		/* PDC Receive Counter Register */
+#define PDC_TPR		0x108		/* PDC Transmit Pointer Register */
+#define PDC_TCR		0x10c		/* PDC Transmit Counter Register */
+#define PDC_RNPR	0x110		/* PDC Receive Next Pointer Register */
+#define PDC_RNCR	0x114		/* PDC Receive Next Counter Register */
+#define PDC_TNPR	0x118		/* PDC Transmit Next Pointer Reg */
+#define PDC_TNCR	0x11c		/* PDC Transmit Next Counter Reg */
+#define PDC_PTCR	0x120		/* PDC Transfer Control Register */
+#define PDC_PTSR	0x124		/* PDC Transfer Status Register */
+
+/* PTCR/PTSR */
+#define PDC_PTCR_RXTEN	(1UL << 0)	/* RXTEN: Receiver Transfer Enable */
+#define PDC_PTCR_RXTDIS	(1UL << 1)	/* RXTDIS: Receiver Transfer Disable */
+#define PDC_PTCR_TXTEN	(1UL << 8)	/* TXTEN: Transmitter Transfer En */
+#define PDC_PTCR_TXTDIS	(1UL << 9)	/* TXTDIS: Transmitter Transmit Dis */
+
+#endif /* ARM_AT91_AT91_PDCREG_H */


Property changes on: trunk/sys/arm/at91/at91_pdcreg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91_pinctrl.c
===================================================================
--- trunk/sys/arm/at91/at91_pinctrl.c	                        (rev 0)
+++ trunk/sys/arm/at91/at91_pinctrl.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,525 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014 Warner Losh.  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 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 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: stable/10/sys/arm/at91/at91_pinctrl.c 273652 2014-10-26 01:30:46Z ian $");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/resource.h>
+#include <sys/systm.h>
+#include <sys/rman.h>
+
+#include <machine/bus.h>
+
+#include <arm/at91/at91var.h>
+#include <arm/at91/at91_piovar.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#define BUS_PASS_PINMUX (BUS_PASS_INTERRUPT + 1)
+
+struct pinctrl_range {
+	uint64_t bus;
+	uint64_t host;
+	uint64_t size;
+};
+
+struct pinctrl_softc {
+	device_t dev;
+	phandle_t node;
+
+	struct pinctrl_range *ranges;
+	int nranges;
+
+	pcell_t acells, scells;
+	int done_pinmux;
+};
+
+struct pinctrl_devinfo {
+	struct ofw_bus_devinfo	obdinfo;
+	struct resource_list	rl;
+};
+
+static int
+at91_pinctrl_probe(device_t dev)
+{
+
+	if (!ofw_bus_is_compatible(dev, "atmel,at91rm9200-pinctrl"))
+		return (ENXIO);
+	device_set_desc(dev, "pincontrol bus");
+        return (0);
+}
+
+/* XXX Make this a subclass of simplebus */
+
+static struct pinctrl_devinfo *
+at91_pinctrl_setup_dinfo(device_t dev, phandle_t node)
+{
+	struct pinctrl_softc *sc;
+	struct pinctrl_devinfo *ndi;
+	uint32_t *reg, *intr, icells;
+	uint64_t phys, size;
+	phandle_t iparent;
+	int i, j, k;
+	int nintr;
+	int nreg;
+
+	sc = device_get_softc(dev);
+
+	ndi = malloc(sizeof(*ndi), M_DEVBUF, M_WAITOK | M_ZERO);
+	if (ofw_bus_gen_setup_devinfo(&ndi->obdinfo, node) != 0) {
+		free(ndi, M_DEVBUF);
+		return (NULL);
+	}
+
+	resource_list_init(&ndi->rl);
+	nreg = OF_getencprop_alloc(node, "reg", sizeof(*reg), (void **)&reg);
+	if (nreg == -1)
+		nreg = 0;
+	if (nreg % (sc->acells + sc->scells) != 0) {
+//		if (bootverbose)
+			device_printf(dev, "Malformed reg property on <%s>\n",
+			    ndi->obdinfo.obd_name);
+		nreg = 0;
+	}
+
+	for (i = 0, k = 0; i < nreg; i += sc->acells + sc->scells, k++) {
+		phys = size = 0;
+		for (j = 0; j < sc->acells; j++) {
+			phys <<= 32;
+			phys |= reg[i + j];
+		}
+		for (j = 0; j < sc->scells; j++) {
+			size <<= 32;
+			size |= reg[i + sc->acells + j];
+		}
+		
+		resource_list_add(&ndi->rl, SYS_RES_MEMORY, k,
+		    phys, phys + size - 1, size);
+	}
+	free(reg, M_OFWPROP);
+
+	nintr = OF_getencprop_alloc(node, "interrupts",  sizeof(*intr),
+	    (void **)&intr);
+	if (nintr > 0) {
+		if (OF_searchencprop(node, "interrupt-parent", &iparent,
+		    sizeof(iparent)) == -1) {
+			device_printf(dev, "No interrupt-parent found, "
+			    "assuming direct parent\n");
+			iparent = OF_parent(node);
+		}
+		if (OF_searchencprop(OF_node_from_xref(iparent), 
+		    "#interrupt-cells", &icells, sizeof(icells)) == -1) {
+			device_printf(dev, "Missing #interrupt-cells property, "
+			    "assuming <1>\n");
+			icells = 1;
+		}
+		if (icells < 1 || icells > nintr) {
+			device_printf(dev, "Invalid #interrupt-cells property "
+			    "value <%d>, assuming <1>\n", icells);
+			icells = 1;
+		}
+		for (i = 0, k = 0; i < nintr; i += icells, k++) {
+			intr[i] = ofw_bus_map_intr(dev, iparent, icells,
+			    &intr[i]);
+			resource_list_add(&ndi->rl, SYS_RES_IRQ, k, intr[i],
+			    intr[i], 1);
+		}
+		free(intr, M_OFWPROP);
+	}
+
+	return (ndi);
+}
+
+static int
+at91_pinctrl_fill_ranges(phandle_t node, struct pinctrl_softc *sc)
+{
+	int host_address_cells;
+	cell_t *base_ranges;
+	ssize_t nbase_ranges;
+	int err;
+	int i, j, k;
+
+	err = OF_searchencprop(OF_parent(node), "#address-cells",
+	    &host_address_cells, sizeof(host_address_cells));
+	if (err <= 0)
+		return (-1);
+
+	nbase_ranges = OF_getproplen(node, "ranges");
+	if (nbase_ranges < 0)
+		return (-1);
+	sc->nranges = nbase_ranges / sizeof(cell_t) /
+	    (sc->acells + host_address_cells + sc->scells);
+	if (sc->nranges == 0)
+		return (0);
+
+	sc->ranges = malloc(sc->nranges * sizeof(sc->ranges[0]),
+	    M_DEVBUF, M_WAITOK);
+	base_ranges = malloc(nbase_ranges, M_DEVBUF, M_WAITOK);
+	OF_getencprop(node, "ranges", base_ranges, nbase_ranges);
+
+	for (i = 0, j = 0; i < sc->nranges; i++) {
+		sc->ranges[i].bus = 0;
+		for (k = 0; k < sc->acells; k++) {
+			sc->ranges[i].bus <<= 32;
+			sc->ranges[i].bus |= base_ranges[j++];
+		}
+		sc->ranges[i].host = 0;
+		for (k = 0; k < host_address_cells; k++) {
+			sc->ranges[i].host <<= 32;
+			sc->ranges[i].host |= base_ranges[j++];
+		}
+		sc->ranges[i].size = 0;
+		for (k = 0; k < sc->scells; k++) {
+			sc->ranges[i].size <<= 32;
+			sc->ranges[i].size |= base_ranges[j++];
+		}
+	}
+
+	free(base_ranges, M_DEVBUF);
+	return (sc->nranges);
+}
+
+static int
+at91_pinctrl_attach(device_t dev)
+{
+	struct pinctrl_softc *sc;
+	struct pinctrl_devinfo *di;
+	phandle_t	node;
+	device_t	cdev;
+
+	sc = device_get_softc(dev);
+	node = ofw_bus_get_node(dev);
+
+	sc->dev = dev;
+	sc->node = node;
+	
+	/*
+	 * Some important numbers
+	 */
+	sc->acells = 2;
+	OF_getencprop(node, "#address-cells", &sc->acells, sizeof(sc->acells));
+	sc->scells = 1;
+	OF_getencprop(node, "#size-cells", &sc->scells, sizeof(sc->scells));
+
+	if (at91_pinctrl_fill_ranges(node, sc) < 0) {
+		device_printf(dev, "could not get ranges\n");
+		return (ENXIO);
+	}
+
+	for (node = OF_child(node); node > 0; node = OF_peer(node)) {
+		if ((di = at91_pinctrl_setup_dinfo(dev, node)) == NULL)
+			continue;
+		cdev = device_add_child(dev, NULL, -1);
+		if (cdev == NULL) {
+			device_printf(dev, "<%s>: device_add_child failed\n",
+			    di->obdinfo.obd_name);
+			resource_list_free(&di->rl);
+			ofw_bus_gen_destroy_devinfo(&di->obdinfo);
+			free(di, M_DEVBUF);
+			continue;
+		}
+		device_set_ivars(cdev, di);
+	}
+
+	return (bus_generic_attach(dev));
+}
+
+static const struct ofw_bus_devinfo *
+pinctrl_get_devinfo(device_t bus __unused, device_t child)
+{
+        struct pinctrl_devinfo *ndi;
+        
+        ndi = device_get_ivars(child);
+        return (&ndi->obdinfo);
+}
+
+static struct resource *
+pinctrl_alloc_resource(device_t bus, device_t child, int type, int *rid,
+    u_long start, u_long end, u_long count, u_int flags)
+{
+	struct pinctrl_softc *sc;
+	struct pinctrl_devinfo *di;
+	struct resource_list_entry *rle;
+	int j;
+
+	sc = device_get_softc(bus);
+
+	/*
+	 * Request for the default allocation with a given rid: use resource
+	 * list stored in the local device info.
+	 */
+	if ((start == 0UL) && (end == ~0UL)) {
+		if ((di = device_get_ivars(child)) == NULL)
+			return (NULL);
+
+		if (type == SYS_RES_IOPORT)
+			type = SYS_RES_MEMORY;
+
+		rle = resource_list_find(&di->rl, type, *rid);
+		if (rle == NULL) {
+//			if (bootverbose)
+				device_printf(bus, "no default resources for "
+				    "rid = %d, type = %d\n", *rid, type);
+			return (NULL);
+		}
+		start = rle->start;
+		end = rle->end;
+		count = rle->count;
+        }
+
+	if (type == SYS_RES_MEMORY) {
+		/* Remap through ranges property */
+		for (j = 0; j < sc->nranges; j++) {
+			if (start >= sc->ranges[j].bus && end <
+			    sc->ranges[j].bus + sc->ranges[j].size) {
+				start -= sc->ranges[j].bus;
+				start += sc->ranges[j].host;
+				end -= sc->ranges[j].bus;
+				end += sc->ranges[j].host;
+				break;
+			}
+		}
+		if (j == sc->nranges && sc->nranges != 0) {
+//			if (bootverbose)
+				device_printf(bus, "Could not map resource "
+				    "%#lx-%#lx\n", start, end);
+
+			return (NULL);
+		}
+	}
+
+	return (bus_generic_alloc_resource(bus, child, type, rid, start, end,
+	    count, flags));
+}
+
+static int
+pinctrl_print_res(struct pinctrl_devinfo *di)
+{
+	int rv;
+
+	rv = 0;
+	rv += resource_list_print_type(&di->rl, "mem", SYS_RES_MEMORY, "%#lx");
+	rv += resource_list_print_type(&di->rl, "irq", SYS_RES_IRQ, "%ld");
+	return (rv);
+}
+
+static void
+pinctrl_probe_nomatch(device_t bus, device_t child)
+{
+	const char *name, *type, *compat;
+
+//	if (!bootverbose)
+		return;
+
+	name = ofw_bus_get_name(child);
+	type = ofw_bus_get_type(child);
+	compat = ofw_bus_get_compat(child);
+
+	device_printf(bus, "<%s>", name != NULL ? name : "unknown");
+	pinctrl_print_res(device_get_ivars(child));
+	if (!ofw_bus_status_okay(child))
+		printf(" disabled");
+	if (type)
+		printf(" type %s", type);
+	if (compat)
+		printf(" compat %s", compat);
+	printf(" (no driver attached)\n");
+}
+
+static int
+pinctrl_print_child(device_t bus, device_t child)
+{
+	int rv;
+
+	rv = bus_print_child_header(bus, child);
+	rv += pinctrl_print_res(device_get_ivars(child));
+	if (!ofw_bus_status_okay(child))
+		rv += printf(" disabled");
+	rv += bus_print_child_footer(bus, child);
+	return (rv);
+}
+
+const char *periphs[] = {"gpio", "periph A", "periph B", "periph C", "periph D", "periph E" };
+
+static void
+pinctrl_walk_tree(device_t bus, phandle_t node)
+{
+	struct pinctrl_softc *sc;
+	char status[10];
+	char name[32];
+	phandle_t pinctrl[32], pins[32 * 4], scratch;
+	ssize_t len, npins;
+	int i, j;
+
+	sc = device_get_softc(bus);
+	for (node = OF_child(node); node > 0; node = OF_peer(node)) {
+		pinctrl_walk_tree(bus, node);
+		memset(status, 0, sizeof(status));
+		memset(name, 0, sizeof(name));
+		OF_getprop(node, "status", status, sizeof(status));
+		OF_getprop(node, "name", name, sizeof(name));
+		if (strcmp(status, "okay") != 0) {
+//			printf("pinctrl: omitting node %s since it isn't active\n", name);
+			continue;
+		}
+		len = OF_getencprop(node, "pinctrl-0", pinctrl, sizeof(pinctrl));
+		if (len <= 0) {
+//			printf("pinctrl: no pinctrl-0 property for node %s, omitting\n", name);
+			continue;
+		}
+		len /= sizeof(phandle_t);
+		printf("pinctrl: Found active node %s\n", name);
+		for (i = 0; i < len; i++) {
+			scratch = OF_node_from_xref(pinctrl[i]);
+			npins = OF_getencprop(scratch, "atmel,pins", pins, sizeof(pins));
+			if (npins <= 0) {
+				printf("We're doing it wrong %s\n", name);
+				continue;
+			}
+			memset(name, 0, sizeof(name));
+			OF_getprop(scratch, "name", name, sizeof(name));
+			npins /= (4 * 4);
+			printf("----> need to cope with %d more pins for %s\n", npins, name);
+			for (j = 0; j < npins; j++) {
+				uint32_t unit = pins[j * 4];
+				uint32_t pin = pins[j * 4 + 1];
+				uint32_t periph = pins[j * 4 + 2];
+				uint32_t flags = pins[j * 4 + 3];
+				uint32_t pio = (0xfffffff & sc->ranges[0].bus) + 0x200 * unit;
+				printf("P%c%d %s %#x\n", unit + 'A', pin, periphs[periph],
+				       flags);
+				switch (periph) {
+				case 0:
+					at91_pio_use_gpio(pio, 1u << pin);
+					at91_pio_gpio_pullup(pio, 1u << pin, !!(flags & 1));
+					at91_pio_gpio_high_z(pio, 1u << pin, !!(flags & 2));
+					at91_pio_gpio_set_deglitch(pio, 1u << pin, !!(flags & 4));
+					// at91_pio_gpio_pulldown(pio, 1u << pin, !!(flags & 8));
+					// at91_pio_gpio_dis_schmidt(pio, 1u << pin, !!(flags & 16));
+					break;
+				case 1:
+					at91_pio_use_periph_a(pio, 1u << pin, flags);
+					break;
+				case 2:
+					at91_pio_use_periph_b(pio, 1u << pin, flags);
+					break;
+				}
+			}
+		}
+	}
+}
+
+static void
+pinctrl_new_pass(device_t bus)
+{
+	struct pinctrl_softc *sc;
+	phandle_t node;
+
+	sc = device_get_softc(bus);
+
+	bus_generic_new_pass(bus);
+
+	if (sc->done_pinmux || bus_current_pass < BUS_PASS_PINMUX)
+		return;
+	sc->done_pinmux++;
+
+	node = OF_peer(0);
+	if (node == -1)
+		return;
+	pinctrl_walk_tree(bus, node);
+}
+
+static device_method_t at91_pinctrl_methods[] = {
+	DEVMETHOD(device_probe, at91_pinctrl_probe),
+	DEVMETHOD(device_attach, at91_pinctrl_attach),
+
+	DEVMETHOD(bus_print_child,	pinctrl_print_child),
+	DEVMETHOD(bus_probe_nomatch,	pinctrl_probe_nomatch),
+	DEVMETHOD(bus_setup_intr,	bus_generic_setup_intr),
+	DEVMETHOD(bus_teardown_intr,	bus_generic_teardown_intr),
+	DEVMETHOD(bus_alloc_resource,	pinctrl_alloc_resource),
+	DEVMETHOD(bus_release_resource,	bus_generic_release_resource),
+	DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
+	DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+	DEVMETHOD(bus_adjust_resource,	bus_generic_adjust_resource),
+	DEVMETHOD(bus_child_pnpinfo_str, ofw_bus_gen_child_pnpinfo_str),
+	DEVMETHOD(bus_new_pass,		pinctrl_new_pass),
+
+	/* ofw_bus interface */
+	DEVMETHOD(ofw_bus_get_devinfo,	pinctrl_get_devinfo),
+	DEVMETHOD(ofw_bus_get_compat,	ofw_bus_gen_get_compat),
+	DEVMETHOD(ofw_bus_get_model,	ofw_bus_gen_get_model),
+	DEVMETHOD(ofw_bus_get_name,	ofw_bus_gen_get_name),
+	DEVMETHOD(ofw_bus_get_node,	ofw_bus_gen_get_node),
+	DEVMETHOD(ofw_bus_get_type,	ofw_bus_gen_get_type),
+
+	DEVMETHOD_END
+};
+
+static driver_t at91_pinctrl_driver = {
+	"at91_pinctrl",
+	at91_pinctrl_methods,
+	sizeof(struct pinctrl_softc),
+};
+
+static devclass_t at91_pinctrl_devclass;
+
+EARLY_DRIVER_MODULE(at91_pinctrl, simplebus, at91_pinctrl_driver, at91_pinctrl_devclass,
+    NULL, NULL, BUS_PASS_BUS);
+
+/*
+ * dummy driver to force pass BUS_PASS_PINMUX to happen.
+ */
+static int
+at91_pingroup_probe(device_t dev)
+{
+	return ENXIO;
+}
+
+static device_method_t at91_pingroup_methods[] = {
+	DEVMETHOD(device_probe, at91_pingroup_probe),
+
+	DEVMETHOD_END
+};
+	
+
+static driver_t at91_pingroup_driver = {
+	"at91_pingroup",
+	at91_pingroup_methods,
+	0,
+};
+
+static devclass_t at91_pingroup_devclass;
+
+EARLY_DRIVER_MODULE(at91_pingroup, at91_pinctrl, at91_pingroup_driver, at91_pingroup_devclass,
+    NULL, NULL, BUS_PASS_PINMUX);


Property changes on: trunk/sys/arm/at91/at91_pinctrl.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91_pio.c
===================================================================
--- trunk/sys/arm/at91/at91_pio.c	                        (rev 0)
+++ trunk/sys/arm/at91/at91_pio.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,651 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2006 M. Warner Losh.  All rights reserved.
+ * Copyright (C) 2012 Ian Lepore. 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 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 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: stable/10/sys/arm/at91/at91_pio.c 273651 2014-10-26 01:26:53Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/mbuf.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/poll.h>
+#include <sys/rman.h>
+#include <sys/selinfo.h>
+#include <sys/sx.h>
+#include <sys/uio.h>
+#include <machine/at91_gpio.h>
+#include <machine/bus.h>
+
+#include <arm/at91/at91reg.h>
+#include <arm/at91/at91_pioreg.h>
+#include <arm/at91/at91_piovar.h>
+
+#ifdef FDT
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+#endif
+
+#define	MAX_CHANGE	64
+
+struct at91_pio_softc
+{
+	device_t dev;			/* Myself */
+	void *intrhand;			/* Interrupt handle */
+	struct resource *irq_res;	/* IRQ resource */
+	struct resource	*mem_res;	/* Memory resource */
+	struct sx sc_mtx;		/* basically a perimeter lock */
+	struct cdev *cdev;
+	struct selinfo selp;
+	int buflen;
+	uint8_t buf[MAX_CHANGE];
+	int flags;
+#define	OPENED 1
+};
+
+static inline uint32_t
+RD4(struct at91_pio_softc *sc, bus_size_t off)
+{
+
+	return (bus_read_4(sc->mem_res, off));
+}
+
+static inline void
+WR4(struct at91_pio_softc *sc, bus_size_t off, uint32_t val)
+{
+
+	bus_write_4(sc->mem_res, off, val);
+}
+
+#define	AT91_PIO_LOCK(_sc)		sx_xlock(&(_sc)->sc_mtx)
+#define	AT91_PIO_UNLOCK(_sc)		sx_xunlock(&(_sc)->sc_mtx)
+#define	AT91_PIO_LOCK_INIT(_sc) \
+	sx_init(&_sc->sc_mtx, device_get_nameunit(_sc->dev))
+#define	AT91_PIO_LOCK_DESTROY(_sc)	sx_destroy(&_sc->sc_mtx);
+#define	AT91_PIO_ASSERT_LOCKED(_sc)	sx_assert(&_sc->sc_mtx, SA_XLOCKED);
+#define	AT91_PIO_ASSERT_UNLOCKED(_sc)	sx_assert(&_sc->sc_mtx, SA_UNLOCKED);
+#define	CDEV2SOFTC(dev)			((dev)->si_drv1)
+
+static devclass_t at91_pio_devclass;
+
+/* bus entry points */
+
+static int at91_pio_probe(device_t dev);
+static int at91_pio_attach(device_t dev);
+static int at91_pio_detach(device_t dev);
+static void at91_pio_intr(void *);
+
+/* helper routines */
+static int at91_pio_activate(device_t dev);
+static void at91_pio_deactivate(device_t dev);
+
+/* cdev routines */
+static d_open_t at91_pio_open;
+static d_close_t at91_pio_close;
+static d_read_t at91_pio_read;
+static d_poll_t at91_pio_poll;
+static d_ioctl_t at91_pio_ioctl;
+
+static struct cdevsw at91_pio_cdevsw =
+{
+	.d_version = D_VERSION,
+	.d_open = at91_pio_open,
+	.d_close = at91_pio_close,
+	.d_read = at91_pio_read,
+	.d_poll = at91_pio_poll,
+	.d_ioctl = at91_pio_ioctl
+};
+
+static int
+at91_pio_probe(device_t dev)
+{
+	const char *name;
+#ifdef FDT
+	if (!ofw_bus_is_compatible(dev, "atmel,at91rm9200-gpio"))
+		return (ENXIO);
+#endif
+	switch (device_get_unit(dev)) {
+	case 0:
+		name = "PIOA";
+		break;
+	case 1:
+		name = "PIOB";
+		break;
+	case 2:
+		name = "PIOC";
+		break;
+	case 3:
+		name = "PIOD";
+		break;
+	case 4:
+		name = "PIOE";
+		break;
+	case 5:
+		name = "PIOF";
+		break;
+	default:
+		name = "PIO";
+		break;
+	}
+	device_set_desc(dev, name);
+	return (0);
+}
+
+static int
+at91_pio_attach(device_t dev)
+{
+	struct at91_pio_softc *sc;
+	int err;
+
+	sc = device_get_softc(dev);
+	sc->dev = dev;
+	err = at91_pio_activate(dev);
+	if (err)
+		goto out;
+
+        if (bootverbose)
+		device_printf(dev, "ABSR: %#x OSR: %#x PSR:%#x ODSR: %#x\n",
+		    RD4(sc, PIO_ABSR), RD4(sc, PIO_OSR), RD4(sc, PIO_PSR),
+		    RD4(sc, PIO_ODSR));
+	AT91_PIO_LOCK_INIT(sc);
+
+	/*
+	 * Activate the interrupt, but disable all interrupts in the hardware.
+	 */
+	WR4(sc, PIO_IDR, 0xffffffff);
+	err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC,
+	    NULL, at91_pio_intr, sc, &sc->intrhand);
+	if (err) {
+		AT91_PIO_LOCK_DESTROY(sc);
+		goto out;
+	}
+	sc->cdev = make_dev(&at91_pio_cdevsw, device_get_unit(dev), UID_ROOT,
+	    GID_WHEEL, 0600, "pio%d", device_get_unit(dev));
+	if (sc->cdev == NULL) {
+		err = ENOMEM;
+		goto out;
+	}
+	sc->cdev->si_drv1 = sc;
+out:
+	if (err)
+		at91_pio_deactivate(dev);
+	return (err);
+}
+
+static int
+at91_pio_detach(device_t dev)
+{
+
+	return (EBUSY);	/* XXX */
+}
+
+static int
+at91_pio_activate(device_t dev)
+{
+	struct at91_pio_softc *sc;
+	int rid;
+
+	sc = device_get_softc(dev);
+	rid = 0;
+	sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	    RF_ACTIVE);
+	if (sc->mem_res == NULL)
+		goto errout;
+	rid = 0;
+	sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+	    RF_ACTIVE | RF_SHAREABLE);
+	if (sc->irq_res == NULL)
+		goto errout;
+	return (0);
+errout:
+	at91_pio_deactivate(dev);
+	return (ENOMEM);
+}
+
+static void
+at91_pio_deactivate(device_t dev)
+{
+	struct at91_pio_softc *sc;
+
+	sc = device_get_softc(dev);
+	if (sc->intrhand)
+		bus_teardown_intr(dev, sc->irq_res, sc->intrhand);
+	sc->intrhand = 0;
+	bus_generic_detach(sc->dev);
+	if (sc->mem_res)
+		bus_release_resource(dev, SYS_RES_MEMORY,
+		    rman_get_rid(sc->mem_res), sc->mem_res);
+	sc->mem_res = 0;
+	if (sc->irq_res)
+		bus_release_resource(dev, SYS_RES_IRQ,
+		    rman_get_rid(sc->irq_res), sc->irq_res);
+	sc->irq_res = 0;
+}
+
+static void
+at91_pio_intr(void *xsc)
+{
+	struct at91_pio_softc *sc = xsc;
+	uint32_t status;
+	int i;
+
+	/* Reading the status also clears the interrupt. */
+	status = RD4(sc, PIO_ISR) & RD4(sc, PIO_IMR);
+	if (status != 0) {
+		AT91_PIO_LOCK(sc);
+		for (i = 0; status != 0 && sc->buflen < MAX_CHANGE; ++i) {
+			if (status & 1)
+				sc->buf[sc->buflen++] = (uint8_t)i;
+			status >>= 1;
+		}
+		AT91_PIO_UNLOCK(sc);
+		wakeup(sc);
+		selwakeup(&sc->selp);
+	}
+}
+
+static int
+at91_pio_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
+{
+	struct at91_pio_softc *sc;
+
+	sc = CDEV2SOFTC(dev);
+	AT91_PIO_LOCK(sc);
+	if (!(sc->flags & OPENED)) {
+		sc->flags |= OPENED;
+	}
+	AT91_PIO_UNLOCK(sc);
+	return (0);
+}
+
+static int
+at91_pio_close(struct cdev *dev, int fflag, int devtype, struct thread *td)
+{
+	struct at91_pio_softc *sc;
+
+	sc = CDEV2SOFTC(dev);
+	AT91_PIO_LOCK(sc);
+	sc->flags &= ~OPENED;
+	AT91_PIO_UNLOCK(sc);
+	return (0);
+}
+
+static int
+at91_pio_poll(struct cdev *dev, int events, struct thread *td)
+{
+	struct at91_pio_softc *sc;
+	int revents = 0;
+
+	sc = CDEV2SOFTC(dev);
+	AT91_PIO_LOCK(sc);
+	if (events & (POLLIN | POLLRDNORM)) {
+		if (sc->buflen != 0)
+			revents |= events & (POLLIN | POLLRDNORM);
+		else
+			selrecord(td, &sc->selp);
+	}
+	AT91_PIO_UNLOCK(sc);
+
+	return (revents);
+}
+
+static int
+at91_pio_read(struct cdev *dev, struct uio *uio, int flag)
+{
+	struct at91_pio_softc *sc;
+	int err, ret, len;
+
+	sc = CDEV2SOFTC(dev);
+	AT91_PIO_LOCK(sc);
+	err = 0;
+	ret = 0;
+	while (uio->uio_resid) {
+		while (sc->buflen == 0 && err == 0)
+			err = msleep(sc, &sc->sc_mtx, PCATCH | PZERO, "prd", 0);
+		if (err != 0)
+			break;
+		len = MIN(sc->buflen, uio->uio_resid);
+		err = uiomove(sc->buf, len, uio);
+		if (err != 0)
+			break;
+		/*
+		 * If we read the whole thing no datacopy is needed,
+		 * otherwise we move the data down.
+		 */
+		ret += len;
+		if (sc->buflen == len)
+			sc->buflen = 0;
+		else {
+			bcopy(sc->buf + len, sc->buf, sc->buflen - len);
+			sc->buflen -= len;
+		}
+		/* If there's no data left, end the read. */
+		if (sc->buflen == 0)
+			break;
+	}
+	AT91_PIO_UNLOCK(sc);
+	return (err);
+}
+
+static void
+at91_pio_bang32(struct at91_pio_softc *sc, uint32_t bits, uint32_t datapin,
+    uint32_t clockpin)
+{
+	int i;
+
+	for (i = 0; i < 32; i++) {
+		if (bits & 0x80000000)
+			WR4(sc, PIO_SODR, datapin);
+		else
+			WR4(sc, PIO_CODR, datapin);
+		bits <<= 1;
+		WR4(sc, PIO_CODR, clockpin);
+		WR4(sc, PIO_SODR, clockpin);
+	}
+}
+
+static void
+at91_pio_bang(struct at91_pio_softc *sc, uint8_t bits, uint32_t bitcount, 
+              uint32_t datapin, uint32_t clockpin)
+{
+	int i;
+
+	for (i = 0; i < bitcount; i++) {
+		if (bits & 0x80)
+			WR4(sc, PIO_SODR, datapin);
+		else
+			WR4(sc, PIO_CODR, datapin);
+		bits <<= 1;
+		WR4(sc, PIO_CODR, clockpin);
+		WR4(sc, PIO_SODR, clockpin);
+	}
+}
+
+static int
+at91_pio_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag,
+    struct thread *td)
+{
+	struct at91_pio_softc *sc;
+	struct at91_gpio_cfg *cfg;
+	struct at91_gpio_info *info;
+	struct at91_gpio_bang *bang;
+	struct at91_gpio_bang_many *bangmany;
+	uint32_t i, num;
+	uint8_t many[1024], *walker;
+	int err;
+        int bitcount;
+
+	sc = CDEV2SOFTC(dev);
+	switch(cmd) {
+	case AT91_GPIO_SET:	/* turn bits on */
+		WR4(sc, PIO_SODR, *(uint32_t *)data);
+		return (0);
+	case AT91_GPIO_CLR:	/* turn bits off */
+		WR4(sc, PIO_CODR, *(uint32_t *)data);
+		return (0);
+	case AT91_GPIO_READ:	/* Get the status of input bits */
+		*(uint32_t *)data = RD4(sc, PIO_PDSR);
+		return (0);
+	case AT91_GPIO_CFG:	/* Configure AT91_GPIO pins */
+		cfg = (struct at91_gpio_cfg *)data;
+		if (cfg->cfgmask & AT91_GPIO_CFG_INPUT) {
+			WR4(sc, PIO_OER, cfg->iomask & ~cfg->input);
+			WR4(sc, PIO_ODR, cfg->iomask & cfg->input);
+		}
+		if (cfg->cfgmask & AT91_GPIO_CFG_HI_Z) {
+			WR4(sc, PIO_MDDR, cfg->iomask & ~cfg->hi_z);
+			WR4(sc, PIO_MDER, cfg->iomask & cfg->hi_z);
+		}
+		if (cfg->cfgmask & AT91_GPIO_CFG_PULLUP) {
+			WR4(sc, PIO_PUDR, cfg->iomask & ~cfg->pullup);
+			WR4(sc, PIO_PUER, cfg->iomask & cfg->pullup);
+		}
+		if (cfg->cfgmask & AT91_GPIO_CFG_GLITCH) {
+			WR4(sc, PIO_IFDR, cfg->iomask & ~cfg->glitch);
+			WR4(sc, PIO_IFER, cfg->iomask & cfg->glitch);
+		}
+		if (cfg->cfgmask & AT91_GPIO_CFG_GPIO) {
+			WR4(sc, PIO_PDR, cfg->iomask & ~cfg->gpio);
+			WR4(sc, PIO_PER, cfg->iomask & cfg->gpio);
+		}
+		if (cfg->cfgmask & AT91_GPIO_CFG_PERIPH) {
+			WR4(sc, PIO_ASR, cfg->iomask & ~cfg->periph);
+			WR4(sc, PIO_BSR, cfg->iomask & cfg->periph);
+		}
+		if (cfg->cfgmask & AT91_GPIO_CFG_INTR) {
+			WR4(sc, PIO_IDR, cfg->iomask & ~cfg->intr);
+			WR4(sc, PIO_IER, cfg->iomask & cfg->intr);
+		}
+		return (0);
+	case AT91_GPIO_BANG:
+		bang = (struct at91_gpio_bang *)data;
+		at91_pio_bang32(sc, bang->bits, bang->datapin, bang->clockpin);
+		return (0);
+	case AT91_GPIO_BANG_MANY:
+		bangmany = (struct at91_gpio_bang_many *)data;
+		walker = (uint8_t *)bangmany->bits;
+		bitcount = bangmany->numbits;
+		while (bitcount > 0) {
+			num = MIN((bitcount + 7) / 8, sizeof(many));
+			err = copyin(walker, many, num);
+			if (err)
+				return err;
+			for (i = 0; i < num && bitcount > 0; i++, bitcount -= 8) 
+				if (bitcount >= 8)
+					at91_pio_bang(sc, many[i], 8, bangmany->datapin, bangmany->clockpin);
+				else
+					at91_pio_bang(sc, many[i], bitcount, bangmany->datapin, bangmany->clockpin);
+			walker += num;
+		}
+		return (0);
+	case AT91_GPIO_INFO:	/* Learn about this device's AT91_GPIO bits */
+		info = (struct at91_gpio_info *)data;
+		info->output_status = RD4(sc, PIO_ODSR);
+		info->input_status = RD4(sc, PIO_OSR);
+		info->highz_status = RD4(sc, PIO_MDSR);
+		info->pullup_status = RD4(sc, PIO_PUSR);
+		info->glitch_status = RD4(sc, PIO_IFSR);
+		info->enabled_status = RD4(sc, PIO_PSR);
+		info->periph_status = RD4(sc, PIO_ABSR);
+		info->intr_status = RD4(sc, PIO_IMR);
+		memset(info->extra_status, 0, sizeof(info->extra_status));
+		return (0);
+	}
+	return (ENOTTY);
+}
+
+/*
+ * The following functions are called early in the boot process, so
+ * don't use bus_space, as that isn't yet available when we need to use
+ * them.
+ */
+
+void
+at91_pio_use_periph_a(uint32_t pio, uint32_t periph_a_mask, int use_pullup)
+{
+	uint32_t *PIO = (uint32_t *)(AT91_BASE + pio);
+
+	PIO[PIO_ASR / 4] = periph_a_mask;
+	PIO[PIO_PDR / 4] = periph_a_mask;
+	if (use_pullup)
+		PIO[PIO_PUER / 4] = periph_a_mask;
+	else
+		PIO[PIO_PUDR / 4] = periph_a_mask;
+}
+
+void
+at91_pio_use_periph_b(uint32_t pio, uint32_t periph_b_mask, int use_pullup)
+{
+	uint32_t *PIO = (uint32_t *)(AT91_BASE + pio);
+
+	PIO[PIO_BSR / 4] = periph_b_mask;
+	PIO[PIO_PDR / 4] = periph_b_mask;
+	if (use_pullup)
+		PIO[PIO_PUER / 4] = periph_b_mask;
+	else
+		PIO[PIO_PUDR / 4] = periph_b_mask;
+}
+
+void
+at91_pio_use_gpio(uint32_t pio, uint32_t gpio_mask)
+{
+	uint32_t *PIO = (uint32_t *)(AT91_BASE + pio);
+
+	PIO[PIO_PER / 4] = gpio_mask;
+}
+
+void
+at91_pio_gpio_input(uint32_t pio, uint32_t input_enable_mask)
+{
+	uint32_t *PIO = (uint32_t *)(AT91_BASE + pio);
+
+	PIO[PIO_ODR / 4] = input_enable_mask;
+}
+
+void
+at91_pio_gpio_output(uint32_t pio, uint32_t output_enable_mask, int use_pullup)
+{
+	uint32_t *PIO = (uint32_t *)(AT91_BASE + pio);
+
+	PIO[PIO_OER / 4] = output_enable_mask;
+	if (use_pullup)
+		PIO[PIO_PUER / 4] = output_enable_mask;
+	else
+		PIO[PIO_PUDR / 4] = output_enable_mask;
+}
+
+void
+at91_pio_gpio_high_z(uint32_t pio, uint32_t high_z_mask, int enable)
+{
+	uint32_t *PIO = (uint32_t *)(AT91_BASE + pio);
+
+	if (enable)
+		PIO[PIO_MDER / 4] = high_z_mask;
+	else
+		PIO[PIO_MDDR / 4] = high_z_mask;
+}
+
+void
+at91_pio_gpio_set(uint32_t pio, uint32_t data_mask)
+{
+	uint32_t *PIO = (uint32_t *)(AT91_BASE + pio);
+
+	PIO[PIO_SODR / 4] = data_mask;
+}
+
+void
+at91_pio_gpio_clear(uint32_t pio, uint32_t data_mask)
+{
+	uint32_t *PIO = (uint32_t *)(AT91_BASE + pio);
+
+	PIO[PIO_CODR / 4] = data_mask;
+}
+
+uint32_t
+at91_pio_gpio_get(uint32_t pio, uint32_t data_mask)
+{
+	uint32_t *PIO = (uint32_t *)(AT91_BASE + pio);
+
+	return (PIO[PIO_PDSR / 4] & data_mask);
+}
+
+void
+at91_pio_gpio_set_deglitch(uint32_t pio, uint32_t data_mask, int use_deglitch)
+{
+	uint32_t *PIO = (uint32_t *)(AT91_BASE + pio);
+
+	if (use_deglitch)
+		PIO[PIO_IFER / 4] = data_mask;
+	else
+		PIO[PIO_IFDR / 4] = data_mask;
+}
+
+void
+at91_pio_gpio_pullup(uint32_t pio, uint32_t data_mask, int do_pullup)
+{
+	uint32_t *PIO = (uint32_t *)(AT91_BASE + pio);
+
+	if (do_pullup)
+		PIO[PIO_PUER / 4] = data_mask;
+	else
+		PIO[PIO_PUDR / 4] = data_mask;
+}
+
+void
+at91_pio_gpio_set_interrupt(uint32_t pio, uint32_t data_mask,
+	int enable_interrupt)
+{
+	uint32_t *PIO = (uint32_t *)(AT91_BASE + pio);
+
+	if (enable_interrupt)
+		PIO[PIO_IER / 4] = data_mask;
+	else
+		PIO[PIO_IDR / 4] = data_mask;
+}
+
+uint32_t
+at91_pio_gpio_clear_interrupt(uint32_t pio)
+{
+	uint32_t *PIO = (uint32_t *)(AT91_BASE + pio);
+
+	/* Reading this register will clear the interrupts. */
+	return (PIO[PIO_ISR / 4]);
+}
+
+static void
+at91_pio_new_pass(device_t dev)
+{
+
+	device_printf(dev, "Pass %d\n", bus_current_pass);
+}
+
+static device_method_t at91_pio_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		at91_pio_probe),
+	DEVMETHOD(device_attach,	at91_pio_attach),
+	DEVMETHOD(device_detach,	at91_pio_detach),
+
+	DEVMETHOD(bus_new_pass,		at91_pio_new_pass),
+
+	DEVMETHOD_END
+};
+
+static driver_t at91_pio_driver = {
+	"at91_pio",
+	at91_pio_methods,
+	sizeof(struct at91_pio_softc),
+};
+
+EARLY_DRIVER_MODULE(at91_pio, at91_pinctrl, at91_pio_driver, at91_pio_devclass,
+    NULL, NULL, BUS_PASS_INTERRUPT);


Property changes on: trunk/sys/arm/at91/at91_pio.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91_pio_sam9g20.h
===================================================================
--- trunk/sys/arm/at91/at91_pio_sam9g20.h	                        (rev 0)
+++ trunk/sys/arm/at91/at91_pio_sam9g20.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,184 @@
+/* $MidnightBSD$ */
+/*
+ * Theses defines come from an atmel file that says specifically that it
+ * has no copyright.
+ *
+ * These defines are also usable for the AT91SAM9260 which has pin multiplexing
+ * that is identical to the AT91SAM9G20.
+ */
+
+/* $FreeBSD: stable/10/sys/arm/at91/at91_pio_sam9g20.h 213498 2010-10-06 22:40:27Z cognet $ */
+
+#ifndef  ARM_AT91_AT91_PIO_SAM9G20_H
+#define  ARM_AT91_AT91_PIO_SAM9G20_H
+
+#include <arm/at91/at91_pioreg.h>
+
+
+// *****************************************************************************
+//               PIO DEFINITIONS FOR AT91SAM9G20
+// *****************************************************************************
+#define AT91C_PA0_SPI0_MISO (AT91C_PIO_PA0)  //  SPI 0 Master In Slave
+#define AT91C_PA0_MCDB0     (AT91C_PIO_PA0)  //  Multimedia Card B Data 0
+#define AT91C_PA1_SPI0_MOSI (AT91C_PIO_PA1)  //  SPI 0 Master Out Slave
+#define AT91C_PA1_MCCDB     (AT91C_PIO_PA1)  //  Multimedia Card B Command
+#define AT91C_PA10_MCDA2    (AT91C_PIO_PA10) //  Multimedia Card A Data 2
+#define AT91C_PA10_ETX2_0   (AT91C_PIO_PA10) //  Ethernet MAC Transmit Data 2
+#define AT91C_PA11_MCDA3    (AT91C_PIO_PA11) //  Multimedia Card A Data 3
+#define AT91C_PA11_ETX3_0   (AT91C_PIO_PA11) //  Ethernet MAC Transmit Data 3
+#define AT91C_PA12_ETX0     (AT91C_PIO_PA12) //  Ethernet MAC Transmit Data 0
+#define AT91C_PA13_ETX1     (AT91C_PIO_PA13) //  Ethernet MAC Transmit Data 1
+#define AT91C_PA14_ERX0     (AT91C_PIO_PA14) //  Ethernet MAC Receive Data 0
+#define AT91C_PA15_ERX1     (AT91C_PIO_PA15) //  Ethernet MAC Receive Data 1
+#define AT91C_PA16_ETXEN    (AT91C_PIO_PA16) //  Ethernet MAC Transmit Enable
+#define AT91C_PA17_ERXDV    (AT91C_PIO_PA17) //  Ethernet MAC Receive Data Valid
+#define AT91C_PA18_ERXER    (AT91C_PIO_PA18) //  Ethernet MAC Receive Error
+#define AT91C_PA19_ETXCK    (AT91C_PIO_PA19) //  Ethernet MAC Transmit Clock/Reference Clock
+#define AT91C_PA2_SPI0_SPCK (AT91C_PIO_PA2)  //  SPI 0 Serial Clock
+#define AT91C_PA20_EMDC     (AT91C_PIO_PA20) //  Ethernet MAC Management Data Clock
+#define AT91C_PA21_EMDIO    (AT91C_PIO_PA21) //  Ethernet MAC Management Data Input/Output
+#define AT91C_PA22_ADTRG    (AT91C_PIO_PA22) //  ADC Trigger
+#define AT91C_PA22_ETXER    (AT91C_PIO_PA22) //  Ethernet MAC Transmikt Coding Error
+#define AT91C_PA23_TWD      (AT91C_PIO_PA23) //  TWI Two-wire Serial Data
+#define AT91C_PA23_ETX2_1   (AT91C_PIO_PA23) //  Ethernet MAC Transmit Data 2
+#define AT91C_PA24_TWCK     (AT91C_PIO_PA24) //  TWI Two-wire Serial Clock
+#define AT91C_PA24_ETX3_1   (AT91C_PIO_PA24) //  Ethernet MAC Transmit Data 3
+#define AT91C_PA25_TCLK0    (AT91C_PIO_PA25) //  Timer Counter 0 external clock input
+#define AT91C_PA25_ERX2     (AT91C_PIO_PA25) //  Ethernet MAC Receive Data 2
+#define AT91C_PA26_TIOA0    (AT91C_PIO_PA26) //  Timer Counter 0 Multipurpose Timer I/O Pin A
+#define AT91C_PA26_ERX3     (AT91C_PIO_PA26) //  Ethernet MAC Receive Data 3
+#define AT91C_PA27_TIOA1    (AT91C_PIO_PA27) //  Timer Counter 1 Multipurpose Timer I/O Pin A
+#define AT91C_PA27_ERXCK    (AT91C_PIO_PA27) //  Ethernet MAC Receive Clock
+#define AT91C_PA28_TIOA2    (AT91C_PIO_PA28) //  Timer Counter 2 Multipurpose Timer I/O Pin A
+#define AT91C_PA28_ECRS     (AT91C_PIO_PA28) //  Ethernet MAC Carrier Sense/Carrier Sense and Data Valid
+#define AT91C_PA29_SCK1     (AT91C_PIO_PA29) //  USART 1 Serial Clock
+#define AT91C_PA29_ECOL     (AT91C_PIO_PA29) //  Ethernet MAC Collision Detected
+#define AT91C_PA3_SPI0_NPCS0 (AT91C_PIO_PA3) //  SPI 0 Peripheral Chip Select 0
+#define AT91C_PA3_MCDB3     (AT91C_PIO_PA3)  //  Multimedia Card B Data 3
+#define AT91C_PA30_SCK2     (AT91C_PIO_PA30) //  USART 2 Serial Clock
+#define AT91C_PA30_RXD4     (AT91C_PIO_PA30) //  USART 4 Receive Data
+#define AT91C_PA31_SCK0     (AT91C_PIO_PA31) //  USART 0 Serial Clock
+#define AT91C_PA31_TXD4     (AT91C_PIO_PA31) //  USART 4 Transmit Data
+#define AT91C_PA4_RTS2      (AT91C_PIO_PA4)  //  USART 2 Ready To Send
+#define AT91C_PA4_MCDB2     (AT91C_PIO_PA4)  //  Multimedia Card B Data 2
+#define AT91C_PA5_CTS2      (AT91C_PIO_PA5)  //  USART 2 Clear To Send
+#define AT91C_PA5_MCDB1     (AT91C_PIO_PA5)  //  Multimedia Card B Data 1
+#define AT91C_PA6_MCDA0     (AT91C_PIO_PA6)  //  Multimedia Card A Data 0
+#define AT91C_PA7_MCCDA     (AT91C_PIO_PA7)  //  Multimedia Card A Command
+#define AT91C_PA8_MCCK      (AT91C_PIO_PA8)  //  Multimedia Card Clock
+#define AT91C_PA9_MCDA1     (AT91C_PIO_PA9)  //  Multimedia Card A Data 1
+#define AT91C_PB0_SPI1_MISO (AT91C_PIO_PB0)  //  SPI 1 Master In Slave
+#define AT91C_PB0_TIOA3     (AT91C_PIO_PB0)  //  Timer Counter 3 Multipurpose Timer I/O Pin A
+#define AT91C_PB1_SPI1_MOSI (AT91C_PIO_PB1)  //  SPI 1 Master Out Slave
+#define AT91C_PB1_TIOB3     (AT91C_PIO_PB1)  //  Timer Counter 3 Multipurpose Timer I/O Pin B
+#define AT91C_PB10_TXD3     (AT91C_PIO_PB10) //  USART 3 Transmit Data
+#define AT91C_PB10_ISI_D8   (AT91C_PIO_PB10) //  Image Sensor Data 8
+#define AT91C_PB11_RXD3     (AT91C_PIO_PB11) //  USART 3 Receive Data
+#define AT91C_PB11_ISI_D9   (AT91C_PIO_PB11) //  Image Sensor Data 9
+#define AT91C_PB12_TXD5     (AT91C_PIO_PB12) //  USART 5 Transmit Data
+#define AT91C_PB12_ISI_D10  (AT91C_PIO_PB12) //  Image Sensor Data 10
+#define AT91C_PB13_RXD5     (AT91C_PIO_PB13) //  USART 5 Receive Data
+#define AT91C_PB13_ISI_D11  (AT91C_PIO_PB13) //  Image Sensor Data 11
+#define AT91C_PB14_DRXD     (AT91C_PIO_PB14) //  DBGU Debug Receive Data
+#define AT91C_PB15_DTXD     (AT91C_PIO_PB15) //  DBGU Debug Transmit Data
+#define AT91C_PB16_TK0      (AT91C_PIO_PB16) //  SSC0 Transmit Clock
+#define AT91C_PB16_TCLK3    (AT91C_PIO_PB16) //  Timer Counter 3 external clock input
+#define AT91C_PB17_TF0      (AT91C_PIO_PB17) //  SSC0 Transmit Frame Sync
+#define AT91C_PB17_TCLK4    (AT91C_PIO_PB17) //  Timer Counter 4 external clock input
+#define AT91C_PB18_TD0      (AT91C_PIO_PB18) //  SSC0 Transmit data
+#define AT91C_PB18_TIOB4    (AT91C_PIO_PB18) //  Timer Counter 4 Multipurpose Timer I/O Pin B
+#define AT91C_PB19_RD0      (AT91C_PIO_PB19) //  SSC0 Receive Data
+#define AT91C_PB19_TIOB5    (AT91C_PIO_PB19) //  Timer Counter 5 Multipurpose Timer I/O Pin B
+#define AT91C_PB2_SPI1_SPCK (AT91C_PIO_PB2)  //  SPI 1 Serial Clock
+#define AT91C_PB2_TIOA4     (AT91C_PIO_PB2)  //  Timer Counter 4 Multipurpose Timer I/O Pin A
+#define AT91C_PB20_RK0      (AT91C_PIO_PB20) //  SSC0 Receive Clock
+#define AT91C_PB20_ISI_D0   (AT91C_PIO_PB20) //  Image Sensor Data 0
+#define AT91C_PB21_RF0      (AT91C_PIO_PB21) //  SSC0 Receive Frame Sync
+#define AT91C_PB21_ISI_D1   (AT91C_PIO_PB21) //  Image Sensor Data 1
+#define AT91C_PB22_DSR0     (AT91C_PIO_PB22) //  USART 0 Data Set ready
+#define AT91C_PB22_ISI_D2   (AT91C_PIO_PB22) //  Image Sensor Data 2
+#define AT91C_PB23_DCD0     (AT91C_PIO_PB23) //  USART 0 Data Carrier Detect
+#define AT91C_PB23_ISI_D3   (AT91C_PIO_PB23) //  Image Sensor Data 3
+#define AT91C_PB24_DTR0     (AT91C_PIO_PB24) //  USART 0 Data Terminal ready
+#define AT91C_PB24_ISI_D4   (AT91C_PIO_PB24) //  Image Sensor Data 4
+#define AT91C_PB25_RI0      (AT91C_PIO_PB25) //  USART 0 Ring Indicator
+#define AT91C_PB25_ISI_D5   (AT91C_PIO_PB25) //  Image Sensor Data 5
+#define AT91C_PB26_RTS0     (AT91C_PIO_PB26) //  USART 0 Ready To Send
+#define AT91C_PB26_ISI_D6   (AT91C_PIO_PB26) //  Image Sensor Data 6
+#define AT91C_PB27_CTS0     (AT91C_PIO_PB27) //  USART 0 Clear To Send
+#define AT91C_PB27_ISI_D7   (AT91C_PIO_PB27) //  Image Sensor Data 7
+#define AT91C_PB28_RTS1     (AT91C_PIO_PB28) //  USART 1 Ready To Send
+#define AT91C_PB28_ISI_PCK  (AT91C_PIO_PB28) //  Image Sensor Data Clock
+#define AT91C_PB29_CTS1     (AT91C_PIO_PB29) //  USART 1 Clear To Send
+#define AT91C_PB29_ISI_VSYNC (AT91C_PIO_PB29) //  Image Sensor Vertical Synchro
+#define AT91C_PB3_SPI1_NPCS0 (AT91C_PIO_PB3) //  SPI 1 Peripheral Chip Select 0
+#define AT91C_PB3_TIOA5     (AT91C_PIO_PB3)  //  Timer Counter 5 Multipurpose Timer I/O Pin A
+#define AT91C_PB30_PCK0_0   (AT91C_PIO_PB30) //  PMC Programmable Clock Output 0
+#define AT91C_PB30_ISI_HSYNC (AT91C_PIO_PB30) //  Image Sensor Horizontal Synchro
+#define AT91C_PB31_PCK1_0   (AT91C_PIO_PB31) //  PMC Programmable Clock Output 1
+#define AT91C_PB31_ISI_MCK  (AT91C_PIO_PB31) //  Image Sensor Reference Clock
+#define AT91C_PB4_TXD0      (AT91C_PIO_PB4) //  USART 0 Transmit Data
+#define AT91C_PB5_RXD0      (AT91C_PIO_PB5) //  USART 0 Receive Data
+#define AT91C_PB6_TXD1      (AT91C_PIO_PB6) //  USART 1 Transmit Data
+#define AT91C_PB6_TCLK1     (AT91C_PIO_PB6) //  Timer Counter 1 external clock input
+#define AT91C_PB7_RXD1      (AT91C_PIO_PB7) //  USART 1 Receive Data
+#define AT91C_PB7_TCLK2     (AT91C_PIO_PB7) //  Timer Counter 2 external clock input
+#define AT91C_PB8_TXD2      (AT91C_PIO_PB8) //  USART 2 Transmit Data
+#define AT91C_PB9_RXD2      (AT91C_PIO_PB9) //  USART 2 Receive Data
+#define AT91C_PC0_AD0       (AT91C_PIO_PC0) //  ADC Analog Input 0
+#define AT91C_PC0_SCK3      (AT91C_PIO_PC0) //  USART 3 Serial Clock
+#define AT91C_PC1_AD1       (AT91C_PIO_PC1) //  ADC Analog Input 1
+#define AT91C_PC1_PCK0_1    (AT91C_PIO_PC1) //  PMC Programmable Clock Output 0
+#define AT91C_PC10_A25_CFR NW (AT91C_PIO_PC10) //  Address Bus[25]
+#define AT91C_PC10_CTS3     (AT91C_PIO_PC10) //  USART 3 Clear To Send
+#define AT91C_PC11_NCS2     (AT91C_PIO_PC11) //  Chip Select Line 2
+#define AT91C_PC11_SPI0_NPCS1 (AT91C_PIO_PC11) //  SPI 0 Peripheral Chip Select 1
+#define AT91C_PC12_IRQ0     (AT91C_PIO_PC12) //  External Interrupt 0
+#define AT91C_PC12_NCS7     (AT91C_PIO_PC12) //  Chip Select Line 7
+#define AT91C_PC13_FIQ      (AT91C_PIO_PC13) //  AIC Fast Interrupt Input
+#define AT91C_PC13_NCS6     (AT91C_PIO_PC13) //  Chip Select Line 6
+#define AT91C_PC14_NCS3_NANDCS (AT91C_PIO_PC14) //  Chip Select Line 3
+#define AT91C_PC14_IRQ2     (AT91C_PIO_PC14) //  External Interrupt 2
+#define AT91C_PC15_NWAIT    (AT91C_PIO_PC15) //  External Wait Signal
+#define AT91C_PC15_IRQ1     (AT91C_PIO_PC15) //  External Interrupt 1
+#define AT91C_PC16_D16      (AT91C_PIO_PC16) //  Data Bus[16]
+#define AT91C_PC16_SPI0_NPCS2 (AT91C_PIO_PC16) //  SPI 0 Peripheral Chip Select 2
+#define AT91C_PC17_D17      (AT91C_PIO_PC17)  //  Data Bus[17]
+#define AT91C_PC17_SPI0_NPCS3 (AT91C_PIO_PC17) //  SPI 0 Peripheral Chip Select 3
+#define AT91C_PC18_D18      (AT91C_PIO_PC18)  //  Data Bus[18]
+#define AT91C_PC18_SPI1_NPCS1_1 (AT91C_PIO_PC18) //  SPI 1 Peripheral Chip Select 1
+#define AT91C_PC19_D19      (AT91C_PIO_PC19) //  Data Bus[19]
+#define AT91C_PC19_SPI1_NPCS2_1 (AT91C_PIO_PC19) //  SPI 1 Peripheral Chip Select 2
+#define AT91C_PC2_AD2       (AT91C_PIO_PC2)  //  ADC Analog Input 2
+#define AT91C_PC2_PCK1_1    (AT91C_PIO_PC2)  //  PMC Programmable Clock Output 1
+#define AT91C_PC20_D20      (AT91C_PIO_PC20) //  Data Bus[20]
+#define AT91C_PC20_SPI1_NPCS3_1 (AT91C_PIO_PC20) //  SPI 1 Peripheral Chip Select 3
+#define AT91C_PC21_D21      (AT91C_PIO_PC21) //  Data Bus[21]
+#define AT91C_PC21_EF100    (AT91C_PIO_PC21) //  Ethernet MAC Force 100 Mbits/sec
+#define AT91C_PC22_D22      (AT91C_PIO_PC22) //  Data Bus[22]
+#define AT91C_PC22_TCLK5    (AT91C_PIO_PC22) //  Timer Counter 5 external clock input
+#define AT91C_PC23_D23      (AT91C_PIO_PC23) //  Data Bus[23]
+#define AT91C_PC24_D24      (AT91C_PIO_PC24) //  Data Bus[24]
+#define AT91C_PC25_D25      (AT91C_PIO_PC25) //  Data Bus[25]
+#define AT91C_PC26_D26      (AT91C_PIO_PC26) //  Data Bus[26]
+#define AT91C_PC27_D27      (AT91C_PIO_PC27) //  Data Bus[27]
+#define AT91C_PC28_D28      (AT91C_PIO_PC28) //  Data Bus[28]
+#define AT91C_PC29_D29      (AT91C_PIO_PC29) //  Data Bus[29]
+#define AT91C_PC3_AD3       (AT91C_PIO_PC3)  //  ADC Analog Input 3
+#define AT91C_PC3_SPI1_NPCS3_0 (AT91C_PIO_PC3) //  SPI 1 Peripheral Chip Select 3
+#define AT91C_PC30_D30      (AT91C_PIO_PC30) //  Data Bus[30]
+#define AT91C_PC31_D31      (AT91C_PIO_PC31) //  Data Bus[31]
+#define AT91C_PC4_A23       (AT91C_PIO_PC4)  //  Address Bus[23]
+#define AT91C_PC4_SPI1_NPCS2_0 (AT91C_PIO_PC4) //  SPI 1 Peripheral Chip Select 2
+#define AT91C_PC5_A24       (AT91C_PIO_PC5)  //  Address Bus[24]
+#define AT91C_PC5_SPI1_NPCS1_0 (AT91C_PIO_PC5) //  SPI 1 Peripheral Chip Select 1
+#define AT91C_PC6_TIOB2     (AT91C_PIO_PC6)  //  Timer Counter 2 Multipurpose Timer I/O Pin B
+#define AT91C_PC6_CFCE1     (AT91C_PIO_PC6)  //  Compact Flash Enable 1
+#define AT91C_PC7_TIOB1     (AT91C_PIO_PC7)  //  Timer Counter 1 Multipurpose Timer I/O Pin B
+#define AT91C_PC7_CFCE2     (AT91C_PIO_PC7)  //  Compact Flash Enable 2
+#define AT91C_PC8_NCS4_CFCS0 (AT91C_PIO_PC8) //  Chip Select Line 4
+#define AT91C_PC8_RTS3      (AT91C_PIO_PC8)  //  USART 3 Ready To Send
+#define AT91C_PC9_NCS5_CFCS1 (AT91C_PIO_PC9) //  Chip Select Line 5
+#define AT91C_PC9_TIOB0     (AT91C_PIO_PC9)  //  Timer Counter 0 Multipurpose Timer I/O Pin B
+
+#endif /* ARM_AT91_AT91_PIO_SAM9G20_H */


Property changes on: trunk/sys/arm/at91/at91_pio_sam9g20.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91_pio_sam9g45.h
===================================================================
--- trunk/sys/arm/at91/at91_pio_sam9g45.h	                        (rev 0)
+++ trunk/sys/arm/at91/at91_pio_sam9g45.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,273 @@
+/* $MidnightBSD$ */
+/*-
+ *  ----------------------------------------------------------------------------
+ *          ATMEL Microcontroller Software Support  -  ROUSSET  -
+ *  ----------------------------------------------------------------------------
+ *  Copyright (c) 2009, Atmel Corporation
+ * 
+ *  All rights reserved.
+ * 
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ * 
+ *  - Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the disclaimer below.
+ * 
+ *  Atmel's name may not be used to endorse or promote products derived from
+ *  this software without specific prior written permission. 
+ *  
+ *  DISCLAIMER:  THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ *  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ *  DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
+ *  ----------------------------------------------------------------------------
+ *
+ * From AT91LIB version 1.9 boards/at91sam9g45-ek/at91sam9g45/AT91SAM9G45.h
+ */
+
+/* $FreeBSD: stable/10/sys/arm/at91/at91_pio_sam9g45.h 238788 2012-07-26 08:01:25Z andrew $ */
+
+#ifndef  ARM_AT91_AT91_PIO_SAM9G45_H
+#define  ARM_AT91_AT91_PIO_SAM9G45_H
+
+#include <arm/at91/at91_pioreg.h>
+
+// *****************************************************************************
+//               PIO DEFINITIONS FOR AT91SAM9G45
+// *****************************************************************************
+#define AT91C_PA0_MCI0_CK  (AT91C_PIO_PA0) //  
+#define AT91C_PA0_TCLK3    (AT91C_PIO_PA0) //  
+#define AT91C_PA1_MCI0_CDA (AT91C_PIO_PA1) //  
+#define AT91C_PA1_TIOA3    (AT91C_PIO_PA1) //  
+#define AT91C_PA10_ETX0     (AT91C_PIO_PA10) //  Ethernet MAC Transmit Data 0
+#define AT91C_PA11_ETX1     (AT91C_PIO_PA11) //  Ethernet MAC Transmit Data 1
+#define AT91C_PA12_ERX0     (AT91C_PIO_PA12) //  Ethernet MAC Receive Data 0
+#define AT91C_PA13_ERX1     (AT91C_PIO_PA13) //  Ethernet MAC Receive Data 1
+#define AT91C_PA14_ETXEN    (AT91C_PIO_PA14) //  Ethernet MAC Transmit Enable
+#define AT91C_PA15_ERXDV    (AT91C_PIO_PA15) //  Ethernet MAC Receive Data Valid
+#define AT91C_PA16_ERXER    (AT91C_PIO_PA16) //  Ethernet MAC Receive Error
+#define AT91C_PA17_ETXCK_EREFCK (AT91C_PIO_PA17) //  Ethernet MAC Transmit Clock/Reference Clock
+#define AT91C_PA18_EMDC     (AT91C_PIO_PA18) //  Ethernet MAC Management Data Clock
+#define AT91C_PA19_EMDIO    (AT91C_PIO_PA19) //  Ethernet MAC Management Data Input/Output
+#define AT91C_PA2_MCI0_DA0 (AT91C_PIO_PA2) //  
+#define AT91C_PA2_TIOB3    (AT91C_PIO_PA2) //  
+#define AT91C_PA20_TWD0     (AT91C_PIO_PA20) //  TWI Two-wire Serial Data
+#define AT91C_PA21_TWCK0    (AT91C_PIO_PA21) //  TWI Two-wire Serial Clock
+#define AT91C_PA22_MCI1_CDA (AT91C_PIO_PA22) //  
+#define AT91C_PA22_SCK3     (AT91C_PIO_PA22) //  
+#define AT91C_PA23_MCI1_DA0 (AT91C_PIO_PA23) //  
+#define AT91C_PA23_RTS3     (AT91C_PIO_PA23) //  
+#define AT91C_PA24_MCI1_DA1 (AT91C_PIO_PA24) //  
+#define AT91C_PA24_CTS3     (AT91C_PIO_PA24) //  
+#define AT91C_PA25_MCI1_DA2 (AT91C_PIO_PA25) //  
+#define AT91C_PA25_PWM3     (AT91C_PIO_PA25) //  
+#define AT91C_PA26_MCI1_DA3 (AT91C_PIO_PA26) //  
+#define AT91C_PA26_TIOB2    (AT91C_PIO_PA26) //  
+#define AT91C_PA27_MCI1_DA4 (AT91C_PIO_PA27) //  
+#define AT91C_PA27_ETXER    (AT91C_PIO_PA27) //  Ethernet MAC Transmikt Coding Error
+#define AT91C_PA28_MCI1_DA5 (AT91C_PIO_PA28) //  
+#define AT91C_PA28_ERXCK    (AT91C_PIO_PA28) //  Ethernet MAC Receive Clock
+#define AT91C_PA29_MCI1_DA6 (AT91C_PIO_PA29) //  
+#define AT91C_PA29_ECRS     (AT91C_PIO_PA29) //  Ethernet MAC Carrier Sense/Carrier Sense and Data Valid
+#define AT91C_PA3_MCI0_DA1 (AT91C_PIO_PA3) //  
+#define AT91C_PA3_TCLK4    (AT91C_PIO_PA3) //  
+#define AT91C_PA30_MCI1_DA7 (AT91C_PIO_PA30) //  
+#define AT91C_PA30_ECOL     (AT91C_PIO_PA30) //  Ethernet MAC Collision Detected
+#define AT91C_PA31_MCI1_CK  (AT91C_PIO_PA31) //  
+#define AT91C_PA31_PCK0     (AT91C_PIO_PA31) //  
+#define AT91C_PA4_MCI0_DA2 (AT91C_PIO_PA4) //  
+#define AT91C_PA4_TIOA4    (AT91C_PIO_PA4) //  
+#define AT91C_PA5_MCI0_DA3 (AT91C_PIO_PA5) //  
+#define AT91C_PA5_TIOB4    (AT91C_PIO_PA5) //  
+#define AT91C_PA6_MCI0_DA4 (AT91C_PIO_PA6) //  
+#define AT91C_PA6_ETX2     (AT91C_PIO_PA6) //  Ethernet MAC Transmit Data 2
+#define AT91C_PA7_MCI0_DA5 (AT91C_PIO_PA7) //  
+#define AT91C_PA7_ETX3     (AT91C_PIO_PA7) //  Ethernet MAC Transmit Data 3
+#define AT91C_PA8_MCI0_DA6 (AT91C_PIO_PA8) //  
+#define AT91C_PA8_ERX2     (AT91C_PIO_PA8) //  Ethernet MAC Receive Data 2
+#define AT91C_PA9_MCI0_DA7 (AT91C_PIO_PA9) //  
+#define AT91C_PA9_ERX3     (AT91C_PIO_PA9) //  Ethernet MAC Receive Data 3
+#define AT91C_PB0_SPI0_MISO (AT91C_PIO_PB0) //  SPI 0 Master In Slave
+#define AT91C_PB1_SPI0_MOSI (AT91C_PIO_PB1) //  SPI 0 Master Out Slave
+#define AT91C_PB10_TWD1     (AT91C_PIO_PB10) //  
+#define AT91C_PB10_ISI_D10  (AT91C_PIO_PB10) //  
+#define AT91C_PB11_TWCK1    (AT91C_PIO_PB11) //  
+#define AT91C_PB11_ISI_D11  (AT91C_PIO_PB11) //  
+#define AT91C_PB12_DRXD     (AT91C_PIO_PB12) //  
+#define AT91C_PB13_DTXD     (AT91C_PIO_PB13) //  
+#define AT91C_PB14_SPI1_MISO (AT91C_PIO_PB14) //  
+#define AT91C_PB15_SPI1_MOSI (AT91C_PIO_PB15) //  
+#define AT91C_PB15_CTS0     (AT91C_PIO_PB15) //  
+#define AT91C_PB16_SPI1_SPCK (AT91C_PIO_PB16) //  
+#define AT91C_PB16_SCK0     (AT91C_PIO_PB16) //  
+#define AT91C_PB17_SPI1_NPCS0 (AT91C_PIO_PB17) //  
+#define AT91C_PB17_RTS0     (AT91C_PIO_PB17) //  
+#define AT91C_PB18_RXD0     (AT91C_PIO_PB18) //  
+#define AT91C_PB18_SPI0_NPCS1 (AT91C_PIO_PB18) //  
+#define AT91C_PB19_TXD0     (AT91C_PIO_PB19) //  
+#define AT91C_PB19_SPI0_NPCS2 (AT91C_PIO_PB19) //  
+#define AT91C_PB2_SPI0_SPCK (AT91C_PIO_PB2) //  SPI 0 Serial Clock
+#define AT91C_PB20_ISI_D0   (AT91C_PIO_PB20) //  
+#define AT91C_PB21_ISI_D1   (AT91C_PIO_PB21) //  
+#define AT91C_PB22_ISI_D2   (AT91C_PIO_PB22) //  
+#define AT91C_PB23_ISI_D3   (AT91C_PIO_PB23) //  
+#define AT91C_PB24_ISI_D4   (AT91C_PIO_PB24) //  
+#define AT91C_PB25_ISI_D5   (AT91C_PIO_PB25) //  
+#define AT91C_PB26_ISI_D6   (AT91C_PIO_PB26) //  
+#define AT91C_PB27_ISI_D7   (AT91C_PIO_PB27) //  
+#define AT91C_PB28_ISI_PCK  (AT91C_PIO_PB28) //  
+#define AT91C_PB29_ISI_VSYNC (AT91C_PIO_PB29) //  
+#define AT91C_PB3_SPI0_NPCS0 (AT91C_PIO_PB3) //  SPI 0 Peripheral Chip Select 0
+#define AT91C_PB30_ISI_HSYNC (AT91C_PIO_PB30) //  
+#define AT91C_PB31_         (AT91C_PIO_PB31) //  
+#define AT91C_PB31_PCK1     (AT91C_PIO_PB31) //  
+#define AT91C_PB4_TXD1     (AT91C_PIO_PB4) //  USART 1 Transmit Data
+#define AT91C_PB5_RXD1     (AT91C_PIO_PB5) //  USART 1 Receive Data
+#define AT91C_PB6_TXD2     (AT91C_PIO_PB6) //  USART 2 Transmit Data
+#define AT91C_PB7_RXD2     (AT91C_PIO_PB7) //  USART 2 Receive Data
+#define AT91C_PB8_TXD3     (AT91C_PIO_PB8) //  USART 3 Transmit Data
+#define AT91C_PB8_ISI_D8   (AT91C_PIO_PB8) //  
+#define AT91C_PB9_RXD3     (AT91C_PIO_PB9) //  USART 3 Receive Data
+#define AT91C_PB9_ISI_D9   (AT91C_PIO_PB9) //  
+#define AT91C_PC0_DQM2     (AT91C_PIO_PC0) //  DQM2
+#define AT91C_PC1_DQM3     (AT91C_PIO_PC1) //  DQM3
+#define AT91C_PC10_NCS4_CFCS0 (AT91C_PIO_PC10) //  
+#define AT91C_PC10_TCLK2    (AT91C_PIO_PC10) //  
+#define AT91C_PC11_NCS5_CFCS1 (AT91C_PIO_PC11) //  
+#define AT91C_PC11_CTS2     (AT91C_PIO_PC11) //  
+#define AT91C_PC12_A25_CFRNW (AT91C_PIO_PC12) //  
+#define AT91C_PC13_NCS2     (AT91C_PIO_PC13) //  
+#define AT91C_PC14_NCS3_NANDCS (AT91C_PIO_PC14) //  
+#define AT91C_PC15_NWAIT    (AT91C_PIO_PC15) //  
+#define AT91C_PC16_D16      (AT91C_PIO_PC16) //  
+#define AT91C_PC17_D17      (AT91C_PIO_PC17) //  
+#define AT91C_PC18_D18      (AT91C_PIO_PC18) //  
+#define AT91C_PC19_D19      (AT91C_PIO_PC19) //  
+#define AT91C_PC2_A19      (AT91C_PIO_PC2) //  
+#define AT91C_PC20_D20      (AT91C_PIO_PC20) //  
+#define AT91C_PC21_D21      (AT91C_PIO_PC21) //  
+#define AT91C_PC22_D22      (AT91C_PIO_PC22) //  
+#define AT91C_PC23_D23      (AT91C_PIO_PC23) //  
+#define AT91C_PC24_D24      (AT91C_PIO_PC24) //  
+#define AT91C_PC25_D25      (AT91C_PIO_PC25) //  
+#define AT91C_PC26_D26      (AT91C_PIO_PC26) //  
+#define AT91C_PC27_D27      (AT91C_PIO_PC27) //  
+#define AT91C_PC28_D28      (AT91C_PIO_PC28) //  
+#define AT91C_PC29_D29      (AT91C_PIO_PC29) //  
+#define AT91C_PC3_A20      (AT91C_PIO_PC3) //  
+#define AT91C_PC30_D30      (AT91C_PIO_PC30) //  
+#define AT91C_PC31_D31      (AT91C_PIO_PC31) //  
+#define AT91C_PC4_A21_NANDALE (AT91C_PIO_PC4) //  
+#define AT91C_PC5_A22_NANDCLE (AT91C_PIO_PC5) //  
+#define AT91C_PC6_A23      (AT91C_PIO_PC6) //  
+#define AT91C_PC7_A24      (AT91C_PIO_PC7) //  
+#define AT91C_PC8_CFCE1    (AT91C_PIO_PC8) //  
+#define AT91C_PC9_CFCE2    (AT91C_PIO_PC9) //  
+#define AT91C_PC9_RTS2     (AT91C_PIO_PC9) //  
+#define AT91C_PD0_TK0      (AT91C_PIO_PD0) //  
+#define AT91C_PD0_PWM3     (AT91C_PIO_PD0) //  
+#define AT91C_PD1_TF0      (AT91C_PIO_PD1) //  
+#define AT91C_PD10_TD1      (AT91C_PIO_PD10) //  
+#define AT91C_PD11_RD1      (AT91C_PIO_PD11) //  
+#define AT91C_PD12_TK1      (AT91C_PIO_PD12) //  
+#define AT91C_PD12_PCK0     (AT91C_PIO_PD12) //  
+#define AT91C_PD13_RK1      (AT91C_PIO_PD13) //  
+#define AT91C_PD14_TF1      (AT91C_PIO_PD14) //  
+#define AT91C_PD15_RF1      (AT91C_PIO_PD15) //  
+#define AT91C_PD16_RTS1     (AT91C_PIO_PD16) //  
+#define AT91C_PD17_CTS1     (AT91C_PIO_PD17) //  
+#define AT91C_PD18_SPI1_NPCS2 (AT91C_PIO_PD18) //  
+#define AT91C_PD18_IRQ      (AT91C_PIO_PD18) //  
+#define AT91C_PD19_SPI1_NPCS3 (AT91C_PIO_PD19) //  
+#define AT91C_PD19_FIQ      (AT91C_PIO_PD19) //  
+#define AT91C_PD2_TD0      (AT91C_PIO_PD2) //  
+#define AT91C_PD20_TIOA0    (AT91C_PIO_PD20) //  
+#define AT91C_PD21_TIOA1    (AT91C_PIO_PD21) //  
+#define AT91C_PD22_TIOA2    (AT91C_PIO_PD22) //  
+#define AT91C_PD23_TCLK0    (AT91C_PIO_PD23) //  
+#define AT91C_PD24_SPI0_NPCS1 (AT91C_PIO_PD24) //  
+#define AT91C_PD24_PWM0     (AT91C_PIO_PD24) //  
+#define AT91C_PD25_SPI0_NPCS2 (AT91C_PIO_PD25) //  
+#define AT91C_PD25_PWM1     (AT91C_PIO_PD25) //  
+#define AT91C_PD26_PCK0     (AT91C_PIO_PD26) //  
+#define AT91C_PD26_PWM2     (AT91C_PIO_PD26) //  
+#define AT91C_PD27_PCK1     (AT91C_PIO_PD27) //  
+#define AT91C_PD27_SPI0_NPCS3 (AT91C_PIO_PD27) //  
+#define AT91C_PD28_TSADTRG  (AT91C_PIO_PD28) //  
+#define AT91C_PD28_SPI1_NPCS1 (AT91C_PIO_PD28) //  
+#define AT91C_PD29_TCLK1    (AT91C_PIO_PD29) //  
+#define AT91C_PD29_SCK1     (AT91C_PIO_PD29) //  
+#define AT91C_PD3_RD0      (AT91C_PIO_PD3) //  
+#define AT91C_PD30_TIOB0    (AT91C_PIO_PD30) //  
+#define AT91C_PD30_SCK2     (AT91C_PIO_PD30) //  
+#define AT91C_PD31_TIOB1    (AT91C_PIO_PD31) //  
+#define AT91C_PD31_PWM1     (AT91C_PIO_PD31) //  
+#define AT91C_PD4_RK0      (AT91C_PIO_PD4) //  
+#define AT91C_PD5_RF0      (AT91C_PIO_PD5) //  
+#define AT91C_PD6_AC97RX   (AT91C_PIO_PD6) //  
+#define AT91C_PD7_AC97TX   (AT91C_PIO_PD7) //  
+#define AT91C_PD7_TIOA5    (AT91C_PIO_PD7) //  
+#define AT91C_PD8_AC97FS   (AT91C_PIO_PD8) //  
+#define AT91C_PD8_TIOB5    (AT91C_PIO_PD8) //  
+#define AT91C_PD9_AC97CK   (AT91C_PIO_PD9) //  
+#define AT91C_PD9_TCLK5    (AT91C_PIO_PD9) //  
+#define AT91C_PE0_LCDPWR   (AT91C_PIO_PE0) //  
+#define AT91C_PE0_PCK0     (AT91C_PIO_PE0) //  
+#define AT91C_PE1_LCDMOD   (AT91C_PIO_PE1) //  
+#define AT91C_PE10_LCDD3    (AT91C_PIO_PE10) //  
+#define AT91C_PE10_LCDD5    (AT91C_PIO_PE10) //  
+#define AT91C_PE11_LCDD4    (AT91C_PIO_PE11) //  
+#define AT91C_PE11_LCDD6    (AT91C_PIO_PE11) //  
+#define AT91C_PE12_LCDD5    (AT91C_PIO_PE12) //  
+#define AT91C_PE12_LCDD7    (AT91C_PIO_PE12) //  
+#define AT91C_PE13_LCDD6    (AT91C_PIO_PE13) //  
+#define AT91C_PE13_LCDD10   (AT91C_PIO_PE13) //  
+#define AT91C_PE14_LCDD7    (AT91C_PIO_PE14) //  
+#define AT91C_PE14_LCDD11   (AT91C_PIO_PE14) //  
+#define AT91C_PE15_LCDD8    (AT91C_PIO_PE15) //  
+#define AT91C_PE15_LCDD12   (AT91C_PIO_PE15) //  
+#define AT91C_PE16_LCDD9    (AT91C_PIO_PE16) //  
+#define AT91C_PE16_LCDD13   (AT91C_PIO_PE16) //  
+#define AT91C_PE17_LCDD10   (AT91C_PIO_PE17) //  
+#define AT91C_PE17_LCDD14   (AT91C_PIO_PE17) //  
+#define AT91C_PE18_LCDD11   (AT91C_PIO_PE18) //  
+#define AT91C_PE18_LCDD15   (AT91C_PIO_PE18) //  
+#define AT91C_PE19_LCDD12   (AT91C_PIO_PE19) //  
+#define AT91C_PE19_LCDD18   (AT91C_PIO_PE19) //  
+#define AT91C_PE2_LCDCC    (AT91C_PIO_PE2) //  
+#define AT91C_PE20_LCDD13   (AT91C_PIO_PE20) //  
+#define AT91C_PE20_LCDD19   (AT91C_PIO_PE20) //  
+#define AT91C_PE21_LCDD14   (AT91C_PIO_PE21) //  
+#define AT91C_PE21_LCDD20   (AT91C_PIO_PE21) //  
+#define AT91C_PE22_LCDD15   (AT91C_PIO_PE22) //  
+#define AT91C_PE22_LCDD21   (AT91C_PIO_PE22) //  
+#define AT91C_PE23_LCDD16   (AT91C_PIO_PE23) //  
+#define AT91C_PE23_LCDD22   (AT91C_PIO_PE23) //  
+#define AT91C_PE24_LCDD17   (AT91C_PIO_PE24) //  
+#define AT91C_PE24_LCDD23   (AT91C_PIO_PE24) //  
+#define AT91C_PE25_LCDD18   (AT91C_PIO_PE25) //  
+#define AT91C_PE26_LCDD19   (AT91C_PIO_PE26) //  
+#define AT91C_PE27_LCDD20   (AT91C_PIO_PE27) //  
+#define AT91C_PE28_LCDD21   (AT91C_PIO_PE28) //  
+#define AT91C_PE29_LCDD22   (AT91C_PIO_PE29) //  
+#define AT91C_PE3_LCDVSYNC (AT91C_PIO_PE3) //  
+#define AT91C_PE30_LCDD23   (AT91C_PIO_PE30) //  
+#define AT91C_PE31_PWM2     (AT91C_PIO_PE31) //  
+#define AT91C_PE31_PCK1     (AT91C_PIO_PE31) //  
+#define AT91C_PE4_LCDHSYNC (AT91C_PIO_PE4) //  
+#define AT91C_PE5_LCDDOTCK (AT91C_PIO_PE5) //  
+#define AT91C_PE6_LCDDEN   (AT91C_PIO_PE6) //  
+#define AT91C_PE7_LCDD0    (AT91C_PIO_PE7) //  
+#define AT91C_PE7_LCDD2    (AT91C_PIO_PE7) //  
+#define AT91C_PE8_LCDD1    (AT91C_PIO_PE8) //  
+#define AT91C_PE8_LCDD3    (AT91C_PIO_PE8) //  
+#define AT91C_PE9_LCDD2    (AT91C_PIO_PE9) //  
+#define AT91C_PE9_LCDD4    (AT91C_PIO_PE9) //  
+
+#endif /* ARM_AT91_AT91_PIO_SAM9G45_H */


Property changes on: trunk/sys/arm/at91/at91_pio_sam9g45.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91_pioreg.h
===================================================================
--- trunk/sys/arm/at91/at91_pioreg.h	                        (rev 0)
+++ trunk/sys/arm/at91/at91_pioreg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,233 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2006 M. Warner Losh.  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 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 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: stable/10/sys/arm/at91/at91_pioreg.h 259378 2013-12-14 01:14:38Z ian $ */
+
+#ifndef ARM_AT91_AT91_PIOREG_H
+#define ARM_AT91_AT91_PIOREG_H
+
+#ifndef ATMEL_ENV
+/* Registers */
+#define PIO_PER		0x00		/* PIO Enable Register */
+#define PIO_PDR		0x04		/* PIO Disable Register */
+#define PIO_PSR		0x08		/* PIO Status Register */
+		/*	0x0c		   reserved */
+#define PIO_OER		0x10		/* PIO Output Enable Register */
+#define PIO_ODR		0x14		/* PIO Output Disable Register */
+#define PIO_OSR		0x18		/* PIO Output Status Register */
+		/*	0x1c		   reserved */
+#define PIO_IFER	0x20		/* PIO Glitch Input Enable Register */
+#define PIO_IFDR	0x24		/* PIO Glitch Input Disable Register */
+#define PIO_IFSR	0x28		/* PIO Glitch Input Status Register */
+		/*	0x2c		   reserved */
+#define PIO_SODR	0x30		/* PIO Set Output Data Register */
+#define PIO_CODR	0x34		/* PIO Clear Output Data Register */
+#define PIO_ODSR	0x38		/* PIO Output Data Status Register */
+#define PIO_PDSR	0x3c		/* PIO Pin Data Status Register */
+#define PIO_IER		0x40		/* PIO Interrupt Enable Register */
+#define PIO_IDR		0x44		/* PIO Interrupt Disable Register */
+#define PIO_IMR		0x48		/* PIO Interrupt Mask Register */
+#define PIO_ISR		0x4c		/* PIO Interrupt Status Register */
+#define PIO_MDER	0x50		/* PIO Multi-Driver Enable Register */
+#define PIO_MDDR	0x54		/* PIO Multi-Driver Disable Register */
+#define PIO_MDSR	0x58		/* PIO Multi-Driver Status Register */
+		/*	0x5c		   reserved */
+#define PIO_PUDR	0x60		/* PIO Pull-up Disable Register */
+#define PIO_PUER	0x64		/* PIO Pull-up Enable Register */
+#define PIO_PUSR	0x68		/* PIO Pull-up Status Register */
+		/*	0x6c		   reserved */
+#define PIO_ASR		0x70		/* PIO Peripheral A Select Register */
+#define PIO_BSR		0x74		/* PIO Peripheral B Select Register */
+#define PIO_ABSR	0x78		/* PIO AB Status Register */
+		/*	0x7c-0x9c	   reserved */
+#define PIO_OWER	0xa0		/* PIO Output Write Enable Register */
+#define PIO_OWDR	0xa4		/* PIO Output Write Disable Register */
+#define PIO_OWSR	0xa8		/* PIO Output Write Status Register */
+		/*	0xac		   reserved */
+#endif
+
+#define AT91C_PIO_PA0        ((unsigned int) 1 <<  0) // Pin Controlled by PA0
+#define AT91C_PIO_PA1        ((unsigned int) 1 <<  1) // Pin Controlled by PA1
+#define AT91C_PIO_PA2        ((unsigned int) 1 <<  2) // Pin Controlled by PA2
+#define AT91C_PIO_PA3        ((unsigned int) 1 <<  3) // Pin Controlled by PA3
+#define AT91C_PIO_PA4        ((unsigned int) 1 <<  4) // Pin Controlled by PA4
+#define AT91C_PIO_PA5        ((unsigned int) 1 <<  5) // Pin Controlled by PA5
+#define AT91C_PIO_PA6        ((unsigned int) 1 <<  6) // Pin Controlled by PA6
+#define AT91C_PIO_PA7        ((unsigned int) 1 <<  7) // Pin Controlled by PA7
+#define AT91C_PIO_PA8        ((unsigned int) 1 <<  8) // Pin Controlled by PA8
+#define AT91C_PIO_PA9        ((unsigned int) 1 <<  9) // Pin Controlled by PA9
+#define AT91C_PIO_PA10       ((unsigned int) 1 << 10) // Pin Controlled by PA10
+#define AT91C_PIO_PA11       ((unsigned int) 1 << 11) // Pin Controlled by PA11
+#define AT91C_PIO_PA12       ((unsigned int) 1 << 12) // Pin Controlled by PA12
+#define AT91C_PIO_PA13       ((unsigned int) 1 << 13) // Pin Controlled by PA13
+#define AT91C_PIO_PA14       ((unsigned int) 1 << 14) // Pin Controlled by PA14
+#define AT91C_PIO_PA15       ((unsigned int) 1 << 15) // Pin Controlled by PA15
+#define AT91C_PIO_PA16       ((unsigned int) 1 << 16) // Pin Controlled by PA16
+#define AT91C_PIO_PA17       ((unsigned int) 1 << 17) // Pin Controlled by PA17
+#define AT91C_PIO_PA18       ((unsigned int) 1 << 18) // Pin Controlled by PA18
+#define AT91C_PIO_PA19       ((unsigned int) 1 << 19) // Pin Controlled by PA19
+#define AT91C_PIO_PA20       ((unsigned int) 1 << 20) // Pin Controlled by PA20
+#define AT91C_PIO_PA21       ((unsigned int) 1 << 21) // Pin Controlled by PA21
+#define AT91C_PIO_PA22       ((unsigned int) 1 << 22) // Pin Controlled by PA22
+#define AT91C_PIO_PA23       ((unsigned int) 1 << 23) // Pin Controlled by PA23
+#define AT91C_PIO_PA24       ((unsigned int) 1 << 24) // Pin Controlled by PA24
+#define AT91C_PIO_PA25       ((unsigned int) 1 << 25) // Pin Controlled by PA25
+#define AT91C_PIO_PA26       ((unsigned int) 1 << 26) // Pin Controlled by PA26
+#define AT91C_PIO_PA27       ((unsigned int) 1 << 27) // Pin Controlled by PA27
+#define AT91C_PIO_PA28       ((unsigned int) 1 << 28) // Pin Controlled by PA28
+#define AT91C_PIO_PA29       ((unsigned int) 1 << 29) // Pin Controlled by PA29
+#define AT91C_PIO_PA30       ((unsigned int) 1 << 30) // Pin Controlled by PA30
+#define AT91C_PIO_PA31       ((unsigned int) 1 << 31) // Pin Controlled by PA31
+#define AT91C_PIO_PB0        ((unsigned int) 1 <<  0) // Pin Controlled by PB0
+#define AT91C_PIO_PB1        ((unsigned int) 1 <<  1) // Pin Controlled by PB1
+#define AT91C_PIO_PB2        ((unsigned int) 1 <<  2) // Pin Controlled by PB2
+#define AT91C_PIO_PB3        ((unsigned int) 1 <<  3) // Pin Controlled by PB3
+#define AT91C_PIO_PB4        ((unsigned int) 1 <<  4) // Pin Controlled by PB4
+#define AT91C_PIO_PB5        ((unsigned int) 1 <<  5) // Pin Controlled by PB5
+#define AT91C_PIO_PB6        ((unsigned int) 1 <<  6) // Pin Controlled by PB6
+#define AT91C_PIO_PB7        ((unsigned int) 1 <<  7) // Pin Controlled by PB7
+#define AT91C_PIO_PB8        ((unsigned int) 1 <<  8) // Pin Controlled by PB8
+#define AT91C_PIO_PB9        ((unsigned int) 1 <<  9) // Pin Controlled by PB9
+#define AT91C_PIO_PB10       ((unsigned int) 1 << 10) // Pin Controlled by PB10
+#define AT91C_PIO_PB11       ((unsigned int) 1 << 11) // Pin Controlled by PB11
+#define AT91C_PIO_PB12       ((unsigned int) 1 << 12) // Pin Controlled by PB12
+#define AT91C_PIO_PB13       ((unsigned int) 1 << 13) // Pin Controlled by PB13
+#define AT91C_PIO_PB14       ((unsigned int) 1 << 14) // Pin Controlled by PB14
+#define AT91C_PIO_PB15       ((unsigned int) 1 << 15) // Pin Controlled by PB15
+#define AT91C_PIO_PB16       ((unsigned int) 1 << 16) // Pin Controlled by PB16
+#define AT91C_PIO_PB17       ((unsigned int) 1 << 17) // Pin Controlled by PB17
+#define AT91C_PIO_PB18       ((unsigned int) 1 << 18) // Pin Controlled by PB18
+#define AT91C_PIO_PB19       ((unsigned int) 1 << 19) // Pin Controlled by PB19
+#define AT91C_PIO_PB20       ((unsigned int) 1 << 20) // Pin Controlled by PB20
+#define AT91C_PIO_PB21       ((unsigned int) 1 << 21) // Pin Controlled by PB21
+#define AT91C_PIO_PB22       ((unsigned int) 1 << 22) // Pin Controlled by PB22
+#define AT91C_PIO_PB23       ((unsigned int) 1 << 23) // Pin Controlled by PB23
+#define AT91C_PIO_PB24       ((unsigned int) 1 << 24) // Pin Controlled by PB24
+#define AT91C_PIO_PB25       ((unsigned int) 1 << 25) // Pin Controlled by PB25
+#define AT91C_PIO_PB26       ((unsigned int) 1 << 26) // Pin Controlled by PB26
+#define AT91C_PIO_PB27       ((unsigned int) 1 << 27) // Pin Controlled by PB27
+#define AT91C_PIO_PB28       ((unsigned int) 1 << 28) // Pin Controlled by PB28
+#define AT91C_PIO_PB29       ((unsigned int) 1 << 29) // Pin Controlled by PB29
+#define AT91C_PIO_PB30       ((unsigned int) 1 << 30) // Pin Controlled by PB30
+#define AT91C_PIO_PB31       ((unsigned int) 1 << 31) // Pin Controlled by PB31
+#define AT91C_PIO_PC0        ((unsigned int) 1 <<  0) // Pin Controlled by PC0
+#define AT91C_PIO_PC1        ((unsigned int) 1 <<  1) // Pin Controlled by PC1
+#define AT91C_PIO_PC2        ((unsigned int) 1 <<  2) // Pin Controlled by PC2
+#define AT91C_PIO_PC3        ((unsigned int) 1 <<  3) // Pin Controlled by PC3
+#define AT91C_PIO_PC4        ((unsigned int) 1 <<  4) // Pin Controlled by PC4
+#define AT91C_PIO_PC5        ((unsigned int) 1 <<  5) // Pin Controlled by PC5
+#define AT91C_PIO_PC6        ((unsigned int) 1 <<  6) // Pin Controlled by PC6
+#define AT91C_PIO_PC7        ((unsigned int) 1 <<  7) // Pin Controlled by PC7
+#define AT91C_PIO_PC8        ((unsigned int) 1 <<  8) // Pin Controlled by PC8
+#define AT91C_PIO_PC9        ((unsigned int) 1 <<  9) // Pin Controlled by PC9
+#define AT91C_PIO_PC10       ((unsigned int) 1 << 10) // Pin Controlled by PC10
+#define AT91C_PIO_PC11       ((unsigned int) 1 << 11) // Pin Controlled by PC11
+#define AT91C_PIO_PC12       ((unsigned int) 1 << 12) // Pin Controlled by PC12
+#define AT91C_PIO_PC13       ((unsigned int) 1 << 13) // Pin Controlled by PC13
+#define AT91C_PIO_PC14       ((unsigned int) 1 << 14) // Pin Controlled by PC14
+#define AT91C_PIO_PC15       ((unsigned int) 1 << 15) // Pin Controlled by PC15
+#define AT91C_PIO_PC16       ((unsigned int) 1 << 16) // Pin Controlled by PC16
+#define AT91C_PIO_PC17       ((unsigned int) 1 << 17) // Pin Controlled by PC17
+#define AT91C_PIO_PC18       ((unsigned int) 1 << 18) // Pin Controlled by PC18
+#define AT91C_PIO_PC19       ((unsigned int) 1 << 19) // Pin Controlled by PC19
+#define AT91C_PIO_PC20       ((unsigned int) 1 << 20) // Pin Controlled by PC20
+#define AT91C_PIO_PC21       ((unsigned int) 1 << 21) // Pin Controlled by PC21
+#define AT91C_PIO_PC22       ((unsigned int) 1 << 22) // Pin Controlled by PC22
+#define AT91C_PIO_PC23       ((unsigned int) 1 << 23) // Pin Controlled by PC23
+#define AT91C_PIO_PC24       ((unsigned int) 1 << 24) // Pin Controlled by PC24
+#define AT91C_PIO_PC25       ((unsigned int) 1 << 25) // Pin Controlled by PC25
+#define AT91C_PIO_PC26       ((unsigned int) 1 << 26) // Pin Controlled by PC26
+#define AT91C_PIO_PC27       ((unsigned int) 1 << 27) // Pin Controlled by PC27
+#define AT91C_PIO_PC28       ((unsigned int) 1 << 28) // Pin Controlled by PC28
+#define AT91C_PIO_PC29       ((unsigned int) 1 << 29) // Pin Controlled by PC29
+#define AT91C_PIO_PC30       ((unsigned int) 1 << 30) // Pin Controlled by PC30
+#define AT91C_PIO_PC31       ((unsigned int) 1 << 31) // Pin Controlled by PC31
+#define AT91C_PIO_PD0        ((unsigned int) 1 <<  0) // Pin Controlled by PD0
+#define AT91C_PIO_PD1        ((unsigned int) 1 <<  1) // Pin Controlled by PD1
+#define AT91C_PIO_PD2        ((unsigned int) 1 <<  2) // Pin Controlled by PD2
+#define AT91C_PIO_PD3        ((unsigned int) 1 <<  3) // Pin Controlled by PD3
+#define AT91C_PIO_PD4        ((unsigned int) 1 <<  4) // Pin Controlled by PD4
+#define AT91C_PIO_PD5        ((unsigned int) 1 <<  5) // Pin Controlled by PD5
+#define AT91C_PIO_PD6        ((unsigned int) 1 <<  6) // Pin Controlled by PD6
+#define AT91C_PIO_PD7        ((unsigned int) 1 <<  7) // Pin Controlled by PD7
+#define AT91C_PIO_PD8        ((unsigned int) 1 <<  8) // Pin Controlled by PD8
+#define AT91C_PIO_PD9        ((unsigned int) 1 <<  9) // Pin Controlled by PD9
+#define AT91C_PIO_PD10       ((unsigned int) 1 << 10) // Pin Controlled by PD10
+#define AT91C_PIO_PD11       ((unsigned int) 1 << 11) // Pin Controlled by PD11
+#define AT91C_PIO_PD12       ((unsigned int) 1 << 12) // Pin Controlled by PD12
+#define AT91C_PIO_PD13       ((unsigned int) 1 << 13) // Pin Controlled by PD13
+#define AT91C_PIO_PD14       ((unsigned int) 1 << 14) // Pin Controlled by PD14
+#define AT91C_PIO_PD15       ((unsigned int) 1 << 15) // Pin Controlled by PD15
+#define AT91C_PIO_PD16       ((unsigned int) 1 << 16) // Pin Controlled by PD16
+#define AT91C_PIO_PD17       ((unsigned int) 1 << 17) // Pin Controlled by PD17
+#define AT91C_PIO_PD18       ((unsigned int) 1 << 18) // Pin Controlled by PD18
+#define AT91C_PIO_PD19       ((unsigned int) 1 << 19) // Pin Controlled by PD19
+#define AT91C_PIO_PD20       ((unsigned int) 1 << 20) // Pin Controlled by PD20
+#define AT91C_PIO_PD21       ((unsigned int) 1 << 21) // Pin Controlled by PD21
+#define AT91C_PIO_PD22       ((unsigned int) 1 << 22) // Pin Controlled by PD22
+#define AT91C_PIO_PD23       ((unsigned int) 1 << 23) // Pin Controlled by PD23
+#define AT91C_PIO_PD24       ((unsigned int) 1 << 24) // Pin Controlled by PD24
+#define AT91C_PIO_PD25       ((unsigned int) 1 << 25) // Pin Controlled by PD25
+#define AT91C_PIO_PD26       ((unsigned int) 1 << 26) // Pin Controlled by PD26
+#define AT91C_PIO_PD27       ((unsigned int) 1 << 27) // Pin Controlled by PD27
+#define AT91C_PIO_PD28       ((unsigned int) 1 << 28) // Pin Controlled by PD28
+#define AT91C_PIO_PD29       ((unsigned int) 1 << 29) // Pin Controlled by PD29
+#define AT91C_PIO_PD30       ((unsigned int) 1 << 30) // Pin Controlled by PD30
+#define AT91C_PIO_PD31       ((unsigned int) 1 << 31) // Pin Controlled by PD31
+#define AT91C_PIO_PE0        ((unsigned int) 1 <<  0) // Pin Controlled by PE0
+#define AT91C_PIO_PE1        ((unsigned int) 1 <<  1) // Pin Controlled by PE1
+#define AT91C_PIO_PE2        ((unsigned int) 1 <<  2) // Pin Controlled by PE2
+#define AT91C_PIO_PE3        ((unsigned int) 1 <<  3) // Pin Controlled by PE3
+#define AT91C_PIO_PE4        ((unsigned int) 1 <<  4) // Pin Controlled by PE4
+#define AT91C_PIO_PE5        ((unsigned int) 1 <<  5) // Pin Controlled by PE5
+#define AT91C_PIO_PE6        ((unsigned int) 1 <<  6) // Pin Controlled by PE6
+#define AT91C_PIO_PE7        ((unsigned int) 1 <<  7) // Pin Controlled by PE7
+#define AT91C_PIO_PE8        ((unsigned int) 1 <<  8) // Pin Controlled by PE8
+#define AT91C_PIO_PE9        ((unsigned int) 1 <<  9) // Pin Controlled by PE9
+#define AT91C_PIO_PE10       ((unsigned int) 1 << 10) // Pin Controlled by PE10
+#define AT91C_PIO_PE11       ((unsigned int) 1 << 11) // Pin Controlled by PE11
+#define AT91C_PIO_PE12       ((unsigned int) 1 << 12) // Pin Controlled by PE12
+#define AT91C_PIO_PE13       ((unsigned int) 1 << 13) // Pin Controlled by PE13
+#define AT91C_PIO_PE14       ((unsigned int) 1 << 14) // Pin Controlled by PE14
+#define AT91C_PIO_PE15       ((unsigned int) 1 << 15) // Pin Controlled by PE15
+#define AT91C_PIO_PE16       ((unsigned int) 1 << 16) // Pin Controlled by PE16
+#define AT91C_PIO_PE17       ((unsigned int) 1 << 17) // Pin Controlled by PE17
+#define AT91C_PIO_PE18       ((unsigned int) 1 << 18) // Pin Controlled by PE18
+#define AT91C_PIO_PE19       ((unsigned int) 1 << 19) // Pin Controlled by PE19
+#define AT91C_PIO_PE20       ((unsigned int) 1 << 20) // Pin Controlled by PE20
+#define AT91C_PIO_PE21       ((unsigned int) 1 << 21) // Pin Controlled by PE21
+#define AT91C_PIO_PE22       ((unsigned int) 1 << 22) // Pin Controlled by PE22
+#define AT91C_PIO_PE23       ((unsigned int) 1 << 23) // Pin Controlled by PE23
+#define AT91C_PIO_PE24       ((unsigned int) 1 << 24) // Pin Controlled by PE24
+#define AT91C_PIO_PE25       ((unsigned int) 1 << 25) // Pin Controlled by PE25
+#define AT91C_PIO_PE26       ((unsigned int) 1 << 26) // Pin Controlled by PE26
+#define AT91C_PIO_PE27       ((unsigned int) 1 << 27) // Pin Controlled by PE27
+#define AT91C_PIO_PE28       ((unsigned int) 1 << 28) // Pin Controlled by PE28
+#define AT91C_PIO_PE29       ((unsigned int) 1 << 29) // Pin Controlled by PE29
+#define AT91C_PIO_PE30       ((unsigned int) 1 << 30) // Pin Controlled by PE30
+#define AT91C_PIO_PE31       ((unsigned int) 1 << 31) // Pin Controlled by PE31
+
+#endif /* ARM_AT91_AT91_PIOREG_H */


Property changes on: trunk/sys/arm/at91/at91_pioreg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91_piovar.h
===================================================================
--- trunk/sys/arm/at91/at91_piovar.h	                        (rev 0)
+++ trunk/sys/arm/at91/at91_piovar.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,51 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2006 M. Warner Losh.  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 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 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: stable/10/sys/arm/at91/at91_piovar.h 273651 2014-10-26 01:26:53Z ian $ */
+
+#ifndef ARM_AT91_AT91_PIOVAR_H
+#define	ARM_AT91_AT91_PIOVAR_H
+
+void at91_pio_use_periph_a(uint32_t pio, uint32_t periph_a_mask,
+    int use_pullup);
+void at91_pio_use_periph_b(uint32_t pio, uint32_t periph_b_mask,
+    int use_pullup);
+void at91_pio_use_gpio(uint32_t pio, uint32_t gpio_mask);
+void at91_pio_gpio_input(uint32_t pio, uint32_t input_enable_mask);
+void at91_pio_gpio_output(uint32_t pio, uint32_t output_enable_mask,
+    int use_pullup);
+void at91_pio_gpio_high_z(uint32_t pio, uint32_t high_z_mask, int enable);
+void at91_pio_gpio_set(uint32_t pio, uint32_t data_mask);
+void at91_pio_gpio_clear(uint32_t pio, uint32_t data_mask);
+uint32_t at91_pio_gpio_get(uint32_t pio, uint32_t data_mask);
+void at91_pio_gpio_set_deglitch(uint32_t pio, uint32_t data_mask,
+    int use_deglitch);
+void at91_pio_gpio_set_interrupt(uint32_t pio, uint32_t data_mask,
+    int enable_interrupt);
+uint32_t at91_pio_gpio_clear_interrupt(uint32_t pio);
+void at91_pio_gpio_pullup(uint32_t pio, uint32_t data_mask, int do_pullup);
+
+#endif /* ARM_AT91_AT91_PIOVAR_H */


Property changes on: trunk/sys/arm/at91/at91_piovar.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91_pit.c
===================================================================
--- trunk/sys/arm/at91/at91_pit.c	                        (rev 0)
+++ trunk/sys/arm/at91/at91_pit.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,223 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2009 Gallon Sylvestre.  All rights reserved.
+ * Copyright (c) 2010 Greg Ansley.  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 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 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: stable/10/sys/arm/at91/at91_pit.c 266196 2014-05-15 21:21:47Z ian $");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/resource.h>
+#include <sys/systm.h>
+#include <sys/rman.h>
+#include <sys/time.h>
+#include <sys/timetc.h>
+#include <sys/watchdog.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+#include <machine/frame.h>
+#include <machine/intr.h>
+#include <machine/resource.h>
+
+#include <arm/at91/at91var.h>
+#include <arm/at91/at91_pitreg.h>
+
+#ifdef FDT
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+#endif
+
+#ifndef PIT_PRESCALE
+#define PIT_PRESCALE (16)
+#endif
+
+static struct pit_softc {
+	struct resource	*mem_res;	/* Memory resource */
+	void		*intrhand;	/* Interrupt handle */
+	device_t	sc_dev;
+} *sc;
+
+static uint32_t timecount = 0;
+static unsigned at91_pit_get_timecount(struct timecounter *tc);
+static int pit_intr(void *arg);
+
+static inline uint32_t
+RD4(struct pit_softc *sc, bus_size_t off)
+{
+
+	return (bus_read_4(sc->mem_res, off));
+}
+
+static inline void
+WR4(struct pit_softc *sc, bus_size_t off, uint32_t val)
+{
+
+	bus_write_4(sc->mem_res, off, val);
+}
+
+void
+at91_pit_delay(int us)
+{
+	int32_t cnt, last, piv;
+	uint64_t pit_freq;
+	const uint64_t mhz  = 1E6;
+
+	if (sc == NULL)
+		return;
+
+	last = PIT_PIV(RD4(sc, PIT_PIIR));
+
+	/* Max delay ~= 260s. @ 133Mhz */
+	pit_freq = at91_master_clock / PIT_PRESCALE;
+	cnt  = ((pit_freq * us) + (mhz -1)) / mhz;
+	cnt  = (cnt <= 0) ? 1 : cnt;
+
+	while (cnt > 0) {
+		piv = PIT_PIV(RD4(sc, PIT_PIIR));
+			cnt  -= piv - last ;
+		if (piv < last)
+			cnt -= PIT_PIV(~0u) - last;
+		last = piv;
+	}
+}
+
+static struct timecounter at91_pit_timecounter = {
+	at91_pit_get_timecount, /* get_timecount */
+	NULL, /* no poll_pps */
+	0xffffffff, /* counter mask */
+	0 / PIT_PRESCALE, /* frequency */
+	"AT91SAM9 timer", /* name */
+	1000 /* quality */
+};
+
+static int
+at91_pit_probe(device_t dev)
+{
+#ifdef FDT
+	if (!ofw_bus_is_compatible(dev, "atmel,at91sam9260-pit"))
+		return (ENXIO);
+#endif
+	device_set_desc(dev, "AT91SAM9 PIT");
+        return (0);
+}
+
+static int
+at91_pit_attach(device_t dev)
+{
+	void *ih;
+	int rid, err = 0;
+	struct resource *irq;
+
+	sc = device_get_softc(dev);
+	sc->sc_dev = dev;
+
+	rid = 0;
+	sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	    RF_ACTIVE);
+
+	if (sc->mem_res == NULL)
+		panic("couldn't allocate register resources");
+
+	rid = 0;
+	irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 1, 1, 1,
+	    RF_ACTIVE | RF_SHAREABLE);
+	if (!irq) {
+		device_printf(dev, "could not allocate interrupt resources.\n");
+		err = ENOMEM;
+		goto out;
+	}
+
+	/* Activate the interrupt. */
+	err = bus_setup_intr(dev, irq, INTR_TYPE_CLK, pit_intr, NULL, NULL,
+	    &ih);
+
+	at91_pit_timecounter.tc_frequency =  at91_master_clock / PIT_PRESCALE;
+	tc_init(&at91_pit_timecounter);
+
+	/* Enable the PIT here. */
+	WR4(sc, PIT_MR, PIT_PIV(at91_master_clock / PIT_PRESCALE / hz) |
+	    PIT_EN | PIT_IEN);
+out:
+	return (err);
+}
+
+
+static int
+pit_intr(void *arg)
+{
+	struct trapframe *fp = arg;
+	uint32_t icnt;
+
+	if (RD4(sc, PIT_SR) & PIT_PITS_DONE) {
+		icnt = RD4(sc, PIT_PIVR) >> 20;
+
+		/* Just add in the overflows we just read */
+		timecount +=  PIT_PIV(RD4(sc, PIT_MR)) * icnt;
+
+		hardclock(TRAPF_USERMODE(fp), TRAPF_PC(fp));
+		return (FILTER_HANDLED);
+	}
+	return (FILTER_STRAY);
+}
+
+static unsigned
+at91_pit_get_timecount(struct timecounter *tc)
+{
+	uint32_t piir, icnt;
+
+	piir = RD4(sc, PIT_PIIR); /* Current  count | over flows */
+	icnt = piir >> 20;	/* Overflows */
+	return (timecount + PIT_PIV(piir) + PIT_PIV(RD4(sc, PIT_MR)) * icnt);
+}
+
+static device_method_t at91_pit_methods[] = {
+	DEVMETHOD(device_probe, at91_pit_probe),
+	DEVMETHOD(device_attach, at91_pit_attach),
+	DEVMETHOD_END
+};
+
+static driver_t at91_pit_driver = {
+	"at91_pit",
+	at91_pit_methods,
+	sizeof(struct pit_softc),
+};
+
+static devclass_t at91_pit_devclass;
+
+#ifdef FDT
+DRIVER_MODULE(at91_pit, simplebus, at91_pit_driver, at91_pit_devclass, NULL,
+    NULL);
+#else
+DRIVER_MODULE(at91_pit, atmelarm, at91_pit_driver, at91_pit_devclass, NULL,
+    NULL);
+#endif


Property changes on: trunk/sys/arm/at91/at91_pit.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91_pitreg.h
===================================================================
--- trunk/sys/arm/at91/at91_pitreg.h	                        (rev 0)
+++ trunk/sys/arm/at91/at91_pitreg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,48 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2009 Sylvestre Gallon.  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 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 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: stable/10/sys/arm/at91/at91_pitreg.h 238370 2012-07-11 17:11:54Z imp $ */
+
+#ifndef ARM_AT91_AT91_PITREG_H
+#define ARM_AT91_AT91_PITREG_H
+
+#define PIT_MR		0x0
+#define PIT_SR		0x4
+#define PIT_PIVR	0x8
+#define PIT_PIIR	0xc
+
+/* PIT_MR */
+#define PIT_PIV(x)	(x & 0xfffff) /* periodic interval value */
+#define PIT_CNT(x)	((x >>20) & 0xfff) /* periodic interval counter */
+#define PIT_EN		(1 << 24) /* pit enable */
+#define PIT_IEN		(1 << 25) /* pit interrupt enable */
+
+/* PIT_SR */
+#define PIT_PITS_DONE	1 /* interrupt done */
+
+void at91_pit_delay(int us);
+
+#endif /* ARM_AT91_AT91_PITREG_H */


Property changes on: trunk/sys/arm/at91/at91_pitreg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91_pmc.c
===================================================================
--- trunk/sys/arm/at91/at91_pmc.c	                        (rev 0)
+++ trunk/sys/arm/at91/at91_pmc.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,718 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2006 M. Warner Losh.  All rights reserved.
+ * Copyright (c) 2010 Greg Ansley.  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 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 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: stable/10/sys/arm/at91/at91_pmc.c 266196 2014-05-15 21:21:47Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/time.h>
+#include <sys/bus.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+#include <sys/timetc.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+#include <machine/resource.h>
+#include <machine/intr.h>
+#include <arm/at91/at91reg.h>
+#include <arm/at91/at91var.h>
+
+#include <arm/at91/at91_pmcreg.h>
+#include <arm/at91/at91_pmcvar.h>
+
+#ifdef FDT
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+#endif
+
+static struct at91_pmc_softc {
+	bus_space_tag_t		sc_st;
+	bus_space_handle_t	sc_sh;
+	struct resource	*mem_res;	/* Memory resource */
+	device_t		dev;
+} *pmc_softc;
+
+static uint32_t pllb_init;
+
+MALLOC_DECLARE(M_PMC);
+MALLOC_DEFINE(M_PMC, "at91_pmc_clocks", "AT91 PMC Clock descriptors");
+
+#define AT91_PMC_BASE 0xffffc00
+
+static void at91_pmc_set_pllb_mode(struct at91_pmc_clock *, int);
+static void at91_pmc_set_upll_mode(struct at91_pmc_clock *, int);
+static void at91_pmc_set_sys_mode(struct at91_pmc_clock *, int);
+static void at91_pmc_set_periph_mode(struct at91_pmc_clock *, int);
+static void at91_pmc_clock_alias(const char *name, const char *alias);
+
+static struct at91_pmc_clock slck = {
+	.name = "slck",		/* 32,768 Hz slow clock */
+	.hz = 32768,
+	.refcnt = 1,
+	.id = 0,
+	.primary = 1,
+};
+
+/*
+ * NOTE: Clocks for "ordinary peripheral" devices e.g. spi0, udp0, uhp0 etc.
+ * are now created automatically. Only "system" clocks need be defined here.
+ */
+static struct at91_pmc_clock main_ck = {
+	.name = "main",		/* Main clock */
+	.refcnt = 0,
+	.id = 1,
+	.primary = 1,
+	.pmc_mask = PMC_IER_MOSCS,
+};
+
+static struct at91_pmc_clock plla = {
+	.name = "plla",		/* PLLA Clock, used for CPU clocking */
+	.parent = &main_ck,
+	.refcnt = 1,
+	.id = 0,
+	.primary = 1,
+	.pll = 1,
+	.pmc_mask = PMC_IER_LOCKA,
+};
+
+static struct at91_pmc_clock pllb = {
+	.name = "pllb",		/* PLLB Clock, used for USB functions */
+	.parent = &main_ck,
+	.refcnt = 0,
+	.id = 0,
+	.primary = 1,
+	.pll = 1,
+	.pmc_mask = PMC_IER_LOCKB,
+	.set_mode = &at91_pmc_set_pllb_mode,
+};
+
+/* Used by USB on at91sam9g45 */
+static struct at91_pmc_clock upll = {
+	.name = "upll",		/* UTMI PLL, used for USB functions on 9G45 family */
+	.parent = &main_ck,
+	.refcnt = 0,
+	.id = 0,
+	.primary = 1,
+	.pll = 1,
+	.pmc_mask = (1 << 6),
+	.set_mode = &at91_pmc_set_upll_mode,
+};
+
+static struct at91_pmc_clock udpck = {
+	.name = "udpck",
+	.parent = &pllb,
+	.pmc_mask = PMC_SCER_UDP,
+	.set_mode = at91_pmc_set_sys_mode
+};
+
+static struct at91_pmc_clock uhpck = {
+	.name = "uhpck",
+	.parent = &pllb,
+	.pmc_mask = PMC_SCER_UHP,
+	.set_mode = at91_pmc_set_sys_mode
+};
+
+static struct at91_pmc_clock mck = {
+	.name = "mck",		/* Master (Peripheral) Clock */
+	.pmc_mask = PMC_IER_MCKRDY,
+	.refcnt = 0,
+};
+
+static struct at91_pmc_clock cpu = {
+	.name = "cpu",		/* CPU Clock */
+	.parent = &plla,
+	.pmc_mask = PMC_SCER_PCK,
+	.refcnt = 0,
+};
+
+/* "+32" or the automatic peripheral clocks */
+static struct at91_pmc_clock *clock_list[16+32] = {
+	&slck,
+	&main_ck,
+	&plla,
+	&pllb,
+	&upll,
+	&udpck,
+	&uhpck,
+	&mck,
+	&cpu
+};
+
+static inline uint32_t
+RD4(struct at91_pmc_softc *sc, bus_size_t off)
+{
+
+	if (sc == NULL) {
+		uint32_t *p = (uint32_t *)(AT91_BASE + AT91_PMC_BASE + off);
+
+		return *p;
+	}
+	return (bus_read_4(sc->mem_res, off));
+}
+
+static inline void
+WR4(struct at91_pmc_softc *sc, bus_size_t off, uint32_t val)
+{
+
+	if (sc == NULL) {
+		uint32_t *p = (uint32_t *)(AT91_BASE + AT91_PMC_BASE + off);
+
+		*p = val;
+	} else
+		bus_write_4(sc->mem_res, off, val);
+}
+
+/*
+ * The following is unused currently since we don't ever set the PLLA
+ * frequency of the device.  If we did, we'd have to also pay attention
+ * to the ICPLLA bit in the PMC_PLLICPR register for frequencies lower
+ * than ~600MHz, which the PMC code doesn't do right now.
+ */
+uint32_t
+at91_pmc_800mhz_plla_outb(int freq)
+{
+	uint32_t outa;
+
+	/*
+	 * Set OUTA, per the data sheet.  See Table 46-16 titled
+	 * PLLA Frequency Regarding ICPLLA and OUTA in the SAM9X25 doc,
+	 * Table 46-17 in the SAM9G20 doc, or Table 46-16 in the SAM9G45 doc.
+	 * Note: the frequencies overlap by 5MHz, so we add 3 here to
+	 * center shoot the transition.
+	 */
+
+	freq /= 1000000;		/* MHz */
+	if (freq >= 800)
+		freq = 800;
+	freq += 3;			/* Allow for overlap. */
+	outa = 3 - ((freq / 50) & 3);	/* 750 / 50 = 7, see table */
+	return (1 << 29)| (outa << 14);
+}
+
+uint32_t
+at91_pmc_800mhz_pllb_outb(int freq)
+{
+
+	return (0);
+}
+
+void
+at91_pmc_set_pllb_mode(struct at91_pmc_clock *clk, int on)
+{
+	struct at91_pmc_softc *sc = pmc_softc;
+	uint32_t value;
+
+	value = on ? pllb_init : 0;
+
+	/*
+	 * Only write to the register if the value is changing.  Besides being
+	 * good common sense, this works around RM9200 Errata #26 (CKGR_PLL[AB]R
+	 * must not be written with the same value currently in the register).
+	 */
+	if (RD4(sc, CKGR_PLLBR) != value) {
+		WR4(sc, CKGR_PLLBR, value);
+		while (on && (RD4(sc, PMC_SR) & PMC_IER_LOCKB) != PMC_IER_LOCKB)
+			continue;
+	}
+}
+
+static void
+at91_pmc_set_upll_mode(struct at91_pmc_clock *clk, int on)
+{
+	struct at91_pmc_softc *sc = pmc_softc;
+	uint32_t value;
+
+	if (on) {
+		on = PMC_IER_LOCKU;
+		value = CKGR_UCKR_UPLLEN | CKGR_UCKR_BIASEN;
+	} else
+		value = 0;
+
+	WR4(sc, CKGR_UCKR, RD4(sc, CKGR_UCKR) | value);
+	while ((RD4(sc, PMC_SR) & PMC_IER_LOCKU) != on)
+		continue;
+
+	WR4(sc, PMC_USB, PMC_USB_USBDIV(9) | PMC_USB_USBS);
+	WR4(sc, PMC_SCER, PMC_SCER_UHP_SAM9);
+}
+
+static void
+at91_pmc_set_sys_mode(struct at91_pmc_clock *clk, int on)
+{
+	struct at91_pmc_softc *sc = pmc_softc;
+
+	WR4(sc, on ? PMC_SCER : PMC_SCDR, clk->pmc_mask);
+	if (on)
+		while ((RD4(sc, PMC_SCSR) & clk->pmc_mask) != clk->pmc_mask)
+			continue;
+	else
+		while ((RD4(sc, PMC_SCSR) & clk->pmc_mask) == clk->pmc_mask)
+			continue;
+}
+
+static void
+at91_pmc_set_periph_mode(struct at91_pmc_clock *clk, int on)
+{
+	struct at91_pmc_softc *sc = pmc_softc;
+
+	WR4(sc, on ? PMC_PCER : PMC_PCDR, clk->pmc_mask);
+	if (on)
+		while ((RD4(sc, PMC_PCSR) & clk->pmc_mask) != clk->pmc_mask)
+			continue;
+	else
+		while ((RD4(sc, PMC_PCSR) & clk->pmc_mask) == clk->pmc_mask)
+			continue;
+}
+
+struct at91_pmc_clock *
+at91_pmc_clock_add(const char *name, uint32_t irq,
+    struct at91_pmc_clock *parent)
+{
+	struct at91_pmc_clock *clk;
+	int i, buflen;
+
+	clk = malloc(sizeof(*clk), M_PMC, M_NOWAIT | M_ZERO);
+	if (clk == NULL)
+		goto err;
+
+	buflen = strlen(name) + 1;
+	clk->name = malloc(buflen, M_PMC, M_NOWAIT);
+	if (clk->name == NULL)
+		goto err;
+
+	strlcpy(clk->name, name, buflen);
+	clk->pmc_mask = 1 << irq;
+	clk->set_mode = &at91_pmc_set_periph_mode;
+	if (parent == NULL)
+		clk->parent = &mck;
+	else
+		clk->parent = parent;
+
+	for (i = 0; i < sizeof(clock_list) / sizeof(clock_list[0]); i++) {
+		if (clock_list[i] == NULL) {
+			clock_list[i] = clk;
+			return (clk);
+		}
+	}
+err:
+	if (clk != NULL) {
+		if (clk->name != NULL)
+			free(clk->name, M_PMC);
+		free(clk, M_PMC);
+	}
+
+	panic("could not allocate pmc clock '%s'", name);
+	return (NULL);
+}
+
+static void
+at91_pmc_clock_alias(const char *name, const char *alias)
+{
+	struct at91_pmc_clock *clk, *alias_clk;
+
+	clk = at91_pmc_clock_ref(name);
+	if (clk)
+		alias_clk = at91_pmc_clock_add(alias, 0, clk->parent);
+
+	if (clk && alias_clk) {
+		alias_clk->hz = clk->hz;
+		alias_clk->pmc_mask = clk->pmc_mask;
+		alias_clk->set_mode = clk->set_mode;
+	}
+}
+
+struct at91_pmc_clock *
+at91_pmc_clock_ref(const char *name)
+{
+	int i;
+
+	for (i = 0; i < sizeof(clock_list) / sizeof(clock_list[0]); i++) {
+		if (clock_list[i] == NULL)
+		    break;
+		if (strcmp(name, clock_list[i]->name) == 0)
+			return (clock_list[i]);
+	}
+
+	return (NULL);
+}
+
+void
+at91_pmc_clock_deref(struct at91_pmc_clock *clk)
+{
+	if (clk == NULL)
+		return;
+}
+
+void
+at91_pmc_clock_enable(struct at91_pmc_clock *clk)
+{
+	if (clk == NULL)
+		return;
+
+	/* XXX LOCKING? XXX */
+	if (clk->parent)
+		at91_pmc_clock_enable(clk->parent);
+	if (clk->refcnt++ == 0 && clk->set_mode)
+		clk->set_mode(clk, 1);
+}
+
+void
+at91_pmc_clock_disable(struct at91_pmc_clock *clk)
+{
+	if (clk == NULL)
+		return;
+
+	/* XXX LOCKING? XXX */
+	if (--clk->refcnt == 0 && clk->set_mode)
+		clk->set_mode(clk, 0);
+	if (clk->parent)
+		at91_pmc_clock_disable(clk->parent);
+}
+
+static int
+at91_pmc_pll_rate(struct at91_pmc_clock *clk, uint32_t reg)
+{
+	uint32_t mul, div, freq;
+
+	freq = clk->parent->hz;
+	div = (reg >> clk->pll_div_shift) & clk->pll_div_mask;
+	mul = (reg >> clk->pll_mul_shift) & clk->pll_mul_mask;
+
+#if 0
+	printf("pll = (%d /  %d) * %d = %d\n",
+	    freq, div, mul + 1, (freq/div) * (mul+1));
+#endif
+
+	if (div != 0 && mul != 0) {
+		freq /= div;
+		freq *= mul + 1;
+	} else
+		freq = 0;
+	clk->hz = freq;
+
+	return (freq);
+}
+
+static uint32_t
+at91_pmc_pll_calc(struct at91_pmc_clock *clk, uint32_t out_freq)
+{
+	uint32_t i, div = 0, mul = 0, diff = 1 << 30;
+
+	unsigned ret = 0x3e00;
+
+	if (out_freq > clk->pll_max_out)
+		goto fail;
+
+	for (i = 1; i < 256; i++) {
+		int32_t diff1;
+		uint32_t input, mul1;
+
+		input = clk->parent->hz / i;
+		if (input < clk->pll_min_in)
+			break;
+		if (input > clk->pll_max_in)
+			continue;
+
+		mul1 = out_freq / input;
+		if (mul1 > (clk->pll_mul_mask + 1))
+			continue;
+		if (mul1 == 0)
+			break;
+
+		diff1 = out_freq - input * mul1;
+		if (diff1 < 0)
+			diff1 = -diff1;
+		if (diff > diff1) {
+			diff = diff1;
+			div = i;
+			mul = mul1;
+			if (diff == 0)
+				break;
+		}
+	}
+	if (diff > (out_freq >> PMC_PLL_SHIFT_TOL))
+		goto fail;
+
+	if (clk->set_outb != NULL)
+		ret |= clk->set_outb(out_freq);
+
+	return (ret |
+		((mul - 1) << clk->pll_mul_shift) |
+		(div << clk->pll_div_shift));
+fail:
+	return (0);
+}
+
+#if !defined(AT91C_MAIN_CLOCK)
+static const unsigned int at91_main_clock_tbl[] = {
+	3000000, 3276800, 3686400, 3840000, 4000000,
+	4433619, 4915200, 5000000, 5242880, 6000000,
+	6144000, 6400000, 6553600, 7159090, 7372800,
+	7864320, 8000000, 9830400, 10000000, 11059200,
+	12000000, 12288000, 13560000, 14318180, 14745600,
+	16000000, 17344700, 18432000, 20000000
+};
+#define	MAIN_CLOCK_TBL_LEN	(sizeof(at91_main_clock_tbl) / sizeof(*at91_main_clock_tbl))
+#endif
+
+static unsigned int
+at91_pmc_sense_main_clock(void)
+{
+#if !defined(AT91C_MAIN_CLOCK)
+	unsigned int ckgr_val;
+	unsigned int diff, matchdiff, freq;
+	int i;
+
+	ckgr_val = (RD4(NULL, CKGR_MCFR) & CKGR_MCFR_MAINF_MASK) << 11;
+
+	/*
+	 * Clocks up to 50MHz can be connected to some models.  If
+	 * the frequency is >= 21MHz, assume that the slow clock can
+	 * measure it correctly, and that any error can be adequately
+	 * compensated for by roudning to the nearest 500Hz.  Users
+	 * with fast, or odd-ball clocks will need to set
+	 * AT91C_MAIN_CLOCK in the kernel config file.
+	 */
+	if (ckgr_val >= 21000000)
+		return ((ckgr_val + 250) / 500 * 500);
+
+	/*
+	 * Try to find the standard frequency that match best.
+	 */
+	freq = at91_main_clock_tbl[0];
+	matchdiff = abs(ckgr_val - at91_main_clock_tbl[0]);
+	for (i = 1; i < MAIN_CLOCK_TBL_LEN; i++) {
+		diff = abs(ckgr_val - at91_main_clock_tbl[i]);
+		if (diff < matchdiff) {
+			freq = at91_main_clock_tbl[i];
+			matchdiff = diff;
+		}
+	}
+	return (freq);
+#else
+	return (AT91C_MAIN_CLOCK);
+#endif
+}
+
+void
+at91_pmc_init_clock(void)
+{
+	struct at91_pmc_softc *sc = NULL;
+	unsigned int main_clock;
+	uint32_t mckr;
+	uint32_t mdiv;
+
+	soc_info.soc_data->soc_clock_init();
+
+	main_clock = at91_pmc_sense_main_clock();
+
+	if (at91_is_sam9() || at91_is_sam9xe()) {
+		uhpck.pmc_mask = PMC_SCER_UHP_SAM9;
+		udpck.pmc_mask = PMC_SCER_UDP_SAM9;
+	}
+
+	/* There is no pllb on AT91SAM9G45 */
+	if (at91_cpu_is(AT91_T_SAM9G45)) {
+		uhpck.parent = &upll;
+		uhpck.pmc_mask = PMC_SCER_UHP_SAM9;
+	}
+
+	mckr = RD4(sc, PMC_MCKR);
+	main_ck.hz = main_clock;
+
+	/*
+	 * Note: this means outa calc code for plla never used since
+	 * we never change it.  If we did, we'd also have to mind
+	 * ICPLLA to get the charge pump current right.
+	 */
+	at91_pmc_pll_rate(&plla, RD4(sc, CKGR_PLLAR));
+
+	if (at91_cpu_is(AT91_T_SAM9G45) && (mckr & PMC_MCKR_PLLADIV2))
+		plla.hz /= 2;
+
+	/*
+	 * Initialize the usb clock.  This sets up pllb, but disables the
+	 * actual clock. XXX except for the if 0 :(
+	 */
+	if (!at91_cpu_is(AT91_T_SAM9G45)) {
+		pllb_init = at91_pmc_pll_calc(&pllb, 48000000 * 2) | 0x10000000;
+		at91_pmc_pll_rate(&pllb, pllb_init);
+#if 0
+		/* Turn off USB clocks */
+		at91_pmc_set_periph_mode(&ohci_clk, 0);
+		at91_pmc_set_periph_mode(&udc_clk, 0);
+#endif
+	}
+
+	if (at91_is_rm92()) {
+		WR4(sc, PMC_SCDR, PMC_SCER_UHP | PMC_SCER_UDP);
+		WR4(sc, PMC_SCER, PMC_SCER_MCKUDP);
+	} else
+		WR4(sc, PMC_SCDR, PMC_SCER_UHP_SAM9 | PMC_SCER_UDP_SAM9);
+
+	/*
+	 * MCK and PCU derive from one of the primary clocks.  Initialize
+	 * this relationship.
+	 */
+	mck.parent = clock_list[mckr & 0x3];
+	mck.parent->refcnt++;
+
+	cpu.hz = mck.hz = mck.parent->hz /
+	    (1 << ((mckr & PMC_MCKR_PRES_MASK) >> 2));
+
+	mdiv = (mckr & PMC_MCKR_MDIV_MASK) >> 8;
+	if (at91_is_sam9() || at91_is_sam9xe()) {
+		/*
+		 * On AT91SAM9G45 when mdiv == 3 we need to divide
+		 * MCK by 3 but not, for example, on 9g20.
+		 */
+		if (!at91_cpu_is(AT91_T_SAM9G45) || mdiv <= 2)
+			mdiv *= 2;
+		if (mdiv > 0)
+			mck.hz /= mdiv;
+	} else
+		mck.hz /= (1 + mdiv);
+
+	/* Only found on SAM9G20 */
+	if (at91_cpu_is(AT91_T_SAM9G20))
+		cpu.hz /= (mckr & PMC_MCKR_PDIV) ?  2 : 1;
+
+	at91_master_clock = mck.hz;
+
+	/* These clocks refrenced by "special" names */
+	at91_pmc_clock_alias("ohci0", "ohci_clk");
+	at91_pmc_clock_alias("udp0",  "udp_clk");
+
+	/* Turn off "Progamable" clocks */
+	WR4(sc, PMC_SCDR, PMC_SCER_PCK0 | PMC_SCER_PCK1 | PMC_SCER_PCK2 |
+	    PMC_SCER_PCK3);
+
+	/* XXX kludge, turn on all peripherals */
+	WR4(sc, PMC_PCER, 0xffffffff);
+
+	/* Disable all interrupts for PMC */
+	WR4(sc, PMC_IDR, 0xffffffff);
+}
+
+static void
+at91_pmc_deactivate(device_t dev)
+{
+	struct at91_pmc_softc *sc;
+
+	sc = device_get_softc(dev);
+	bus_generic_detach(sc->dev);
+	if (sc->mem_res)
+		bus_release_resource(dev, SYS_RES_IOPORT,
+		    rman_get_rid(sc->mem_res), sc->mem_res);
+	sc->mem_res = 0;
+}
+
+static int
+at91_pmc_activate(device_t dev)
+{
+	struct at91_pmc_softc *sc;
+	int rid;
+
+	sc = device_get_softc(dev);
+	rid = 0;
+	sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	    RF_ACTIVE);
+	if (sc->mem_res == NULL)
+		goto errout;
+	return (0);
+errout:
+	at91_pmc_deactivate(dev);
+	return (ENOMEM);
+}
+
+static int
+at91_pmc_probe(device_t dev)
+{
+#ifdef FDT
+	if (!ofw_bus_is_compatible(dev, "atmel,at91rm9200-pmc"))
+		return (ENXIO);
+#endif
+	device_set_desc(dev, "PMC");
+	return (0);
+}
+
+static int
+at91_pmc_attach(device_t dev)
+{
+	int err;
+
+	pmc_softc = device_get_softc(dev);
+	pmc_softc->dev = dev;
+	if ((err = at91_pmc_activate(dev)) != 0)
+		return (err);
+
+	/*
+	 * Configure main clock frequency.
+	 */
+	at91_pmc_init_clock();
+
+	/*
+	 * Display info about clocks previously computed
+	 */
+	device_printf(dev,
+	    "Primary: %d Hz PLLA: %d MHz CPU: %d MHz MCK: %d MHz\n",
+	    main_ck.hz,
+	    plla.hz / 1000000,
+	    cpu.hz / 1000000, mck.hz / 1000000);
+
+	return (0);
+}
+
+static device_method_t at91_pmc_methods[] = {
+	DEVMETHOD(device_probe, at91_pmc_probe),
+	DEVMETHOD(device_attach, at91_pmc_attach),
+	DEVMETHOD_END
+};
+
+static driver_t at91_pmc_driver = {
+	"at91_pmc",
+	at91_pmc_methods,
+	sizeof(struct at91_pmc_softc),
+};
+static devclass_t at91_pmc_devclass;
+
+#ifdef FDT
+DRIVER_MODULE(at91_pmc, simplebus, at91_pmc_driver, at91_pmc_devclass, NULL,
+    NULL);
+#else
+DRIVER_MODULE(at91_pmc, atmelarm, at91_pmc_driver, at91_pmc_devclass, NULL,
+    NULL);
+#endif


Property changes on: trunk/sys/arm/at91/at91_pmc.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91_pmcreg.h
===================================================================
--- trunk/sys/arm/at91/at91_pmcreg.h	                        (rev 0)
+++ trunk/sys/arm/at91/at91_pmcreg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,145 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2005 M. Warner Losh.  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 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 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: stable/10/sys/arm/at91/at91_pmcreg.h 239167 2012-08-10 04:47:20Z imp $ */
+
+#ifndef ARM_AT91_AT91_PMCREG_H
+#define ARM_AT91_AT91_PMCREG_H
+
+/* Registers */
+#define	PMC_SCER	0x00		/* System Clock Enable Register */
+#define	PMC_SCDR	0x04		/* System Clock Disable Register */
+#define	PMC_SCSR	0x08		/* System Clock Status Register */
+		/*	0x0c		   reserved */
+#define	PMC_PCER	0x10		/* Peripheral Clock Enable Register */
+#define	PMC_PCDR	0x14		/* Peripheral Clock Disable Register */
+#define	PMC_PCSR	0x18		/* Peripheral Clock Status Register */
+#define	CKGR_UCKR	0x1c		/* UTMI Clock Configuration Register */
+#define CKGR_MOR	0x20		/* Main Oscillator Register */
+#define CKGR_MCFR	0x24		/* Main Clock Frequency Register */
+#define CKGR_PLLAR	0x28		/* PLL A Register */
+#define CKGR_PLLBR	0x2c		/* PLL B Register */
+#define PMC_MCKR	0x30		/* Master Clock Register */
+		/*	0x34		   reserved */
+#define	PMC_USB		0x38		/* USB Clock Register */
+		/*	0x3c		   reserved */
+#define PMC_PCK0	0x40		/* Programmable Clock 0 Register */
+#define PMC_PCK1	0x44		/* Programmable Clock 1 Register */
+#define PMC_PCK2	0x48		/* Programmable Clock 2 Register */
+#define PMC_PCK3	0x4c		/* Programmable Clock 3 Register */
+		/*	0x50		   reserved */
+		/*	0x54		   reserved */
+		/*	0x58		   reserved */
+		/*	0x5c		   reserved */
+#define PMC_IER		0x60		/* Interrupt Enable Register */
+#define PMC_IDR		0x64		/* Interrupt Disable Register */
+#define PMC_SR		0x68		/* Status Register */
+#define PMC_IMR		0x6c		/* Interrupt Mask Register */
+		/*	0x70		   reserved */
+		/*	0x74		   reserved */
+		/*	0x78		   reserved */
+		/*	0x7c		   reserved */
+#define	PMC_PLLICPR	0x80		/* PLL Charge Pump Current Register */
+
+/* PMC System Clock Enable Register */
+/* PMC System Clock Disable Register */
+/* PMC System Clock StatusRegister */
+#define PMC_SCER_PCK	(1UL << 0)	/* PCK: Processor Clock Enable */
+#define PMC_SCER_UDP	(1UL << 1)	/* UDP: USB Device Port Clock Enable */
+#define PMC_SCER_MCKUDP	(1UL << 2)	/* MCKUDP: Master disable susp/res */
+#define PMC_SCER_UHP	(1UL << 4)	/* UHP: USB Host Port Clock Enable */
+#define PMC_SCER_PCK0	(1UL << 8)	/* PCK0: Programmable Clock out en */
+#define PMC_SCER_PCK1	(1UL << 9)	/* PCK1: Programmable Clock out en */
+#define PMC_SCER_PCK2	(1UL << 10)	/* PCK2: Programmable Clock out en */
+#define PMC_SCER_PCK3	(1UL << 11)	/* PCK3: Programmable Clock out en */
+#define PMC_SCER_UHP_SAM9 (1UL << 6)	/* UHP: USB Host Port Clock Enable */
+#define PMC_SCER_UDP_SAM9 (1UL << 7)	/* UDP: USB Device Port Clock Enable */
+
+/* PMC Peripheral Clock Enable Register */
+/* PMC Peripheral Clock Disable Register */
+/* PMC Peripheral Clock Status Register */
+/* Each bit here is 1 << peripheral number  to enable/disable/status */
+
+/* PMC UTMI Clock Configuration Register */
+#define	CKGR_UCKR_BIASEN	(1UL << 24)
+#define	CKGR_UCKR_UPLLEN	(1UL << 16)
+
+/* PMC Clock Generator Main Oscillator Register */
+#define CKGR_MOR_MOSCEN	(1UL << 0)	/* MOSCEN: Main Oscillator Enable */
+#define CKGR_MOR_OSCBYPASS (1UL << 1)	/* Oscillator Bypass */
+#define CKGR_MOR_OSCOUNT(x) (x << 8)	/* Main Oscillator Start-up Time */
+
+/* PMC Clock Generator Main Clock Frequency Register */
+#define CKGR_MCFR_MAINRDY	(1UL << 16)	/* Main Clock Ready */
+#define CKGR_MCFR_MAINF_MASK	0xfffful	/* Main Clock Frequency */
+
+/* PMC Clock Generator Master Clock Register */
+#define PMC_MCKR_PDIV      (1 << 12)			/* SAM9G20 Only */
+#define PMC_MCKR_PLLADIV2  (1 << 12)			/* SAM9G45 Only */
+#define PMC_MCKR_CSS_MASK  (3 << 0)		
+#define PMC_MCKR_MDIV_MASK (3 << 8)		
+#define PMC_MCKR_PRES_MASK (7 << 2)		
+
+/* PMC USB Clock Register */
+#define	PMC_USB_USBDIV(n) (((n) & 0x0F) << 8)
+#define	PMC_USB_USBS (1 << 0)
+
+/* PMC Interrupt Enable Register */
+/* PMC Interrupt Disable Register */
+/* PMC Status Register */
+/* PMC Interrupt Mask Register */
+#define PMC_IER_MOSCS	(1UL << 0)	/* Main Oscillator Status */
+#define PMC_IER_LOCKA	(1UL << 1)	/* PLL A Locked */
+#define PMC_IER_LOCKB	(1UL << 2)	/* PLL B Locked */
+#define PMC_IER_MCKRDY	(1UL << 3)	/* Master Clock Status */
+#define	PMC_IER_LOCKU	(1UL << 6)	/* UPLL Locked */
+#define PMC_IER_PCK0RDY	(1UL << 8)	/* Programmable Clock 0 Ready */
+#define PMC_IER_PCK1RDY	(1UL << 9)	/* Programmable Clock 1 Ready */
+#define PMC_IER_PCK2RDY	(1UL << 10)	/* Programmable Clock 2 Ready */
+#define PMC_IER_PCK3RDY	(1UL << 11)	/* Programmable Clock 3 Ready */
+
+/*
+ * PLL input frequency spec sheet says it must be between 1MHz and 32MHz,
+ * but it works down as low as 100kHz, a frequency necessary for some
+ * output frequencies to work.
+ */
+#define PMC_PLL_MIN_IN_FREQ	100000
+#define PMC_PLL_MAX_IN_FREQ	32000000
+
+/*
+ * PLL Max output frequency is 240MHz.  The errata says 180MHz is the max
+ * for some revisions of this part.  Be more permissive and optimistic.
+ */
+#define PMC_PLL_MAX_OUT_FREQ	240000000
+
+#define PMC_PLL_MULT_MIN	2
+#define PMC_PLL_MULT_MAX	2048
+
+#define PMC_PLL_SHIFT_TOL	5	/* Allow errors 1 part in 32 */
+
+#define PMC_PLL_FAST_THRESH	155000000
+
+#endif /* ARM_AT91_AT91_PMCREG_H */


Property changes on: trunk/sys/arm/at91/at91_pmcreg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91_pmcvar.h
===================================================================
--- trunk/sys/arm/at91/at91_pmcvar.h	                        (rev 0)
+++ trunk/sys/arm/at91/at91_pmcvar.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,68 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2005 M. Warner Losh.  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 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 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: stable/10/sys/arm/at91/at91_pmcvar.h 239190 2012-08-11 05:45:19Z imp $ */
+
+#ifndef ARM_AT91_AT91_PMCVAR_H
+#define ARM_AT91_AT91_PMCVAR_H
+
+struct at91_pmc_clock
+{
+	char		*name;
+	uint32_t	hz;
+	struct at91_pmc_clock *parent;
+	uint32_t	pmc_mask;
+	void		(*set_mode)(struct at91_pmc_clock *, int);
+	uint32_t	refcnt;
+	unsigned	id:2;
+	unsigned	primary:1;
+	unsigned	pll:1;
+	unsigned	programmable:1;
+
+	/* PLL Params */
+	uint32_t	pll_min_in;
+	uint32_t	pll_max_in;
+	uint32_t	pll_min_out;
+	uint32_t	pll_max_out;
+
+	uint32_t	pll_div_shift;
+	uint32_t	pll_div_mask;
+	uint32_t	pll_mul_shift;
+	uint32_t	pll_mul_mask;
+
+	uint32_t	(*set_outb)(int);
+};
+
+struct at91_pmc_clock *at91_pmc_clock_add(const char *name, uint32_t irq,
+    struct at91_pmc_clock *parent);
+struct at91_pmc_clock *at91_pmc_clock_ref(const char *name);
+void at91_pmc_clock_deref(struct at91_pmc_clock *);
+void at91_pmc_clock_enable(struct at91_pmc_clock *);
+void at91_pmc_clock_disable(struct at91_pmc_clock *);
+
+uint32_t at91_pmc_800mhz_plla_outb(int freq);
+uint32_t at91_pmc_800mhz_pllb_outb(int freq);
+#endif /* ARM_AT91_AT91_PMCVAR_H */


Property changes on: trunk/sys/arm/at91/at91_pmcvar.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91_reset.S
===================================================================
--- trunk/sys/arm/at91/at91_reset.S	                        (rev 0)
+++ trunk/sys/arm/at91/at91_reset.S	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,58 @@
+/* $MidnightBSD$ */
+#include <machine/asm.h>
+#include <arm/at91/at91_rstreg.h>
+#include <arm/at91/at91reg.h>
+#include <arm/at91/at91sam9g20reg.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/at91/at91_reset.S 238330 2012-07-10 02:14:50Z imp $");
+
+#define SDRAM_TR  (AT91_BASE + \
+	AT91SAM9G20_SDRAMC_BASE + AT91SAM9G20_SDRAMC_TR)
+#define SDRAM_LPR (AT91_BASE + \
+	AT91SAM9G20_SDRAMC_BASE + AT91SAM9G20_SDRAMC_LPR)
+#define RSTC_RCR  (AT91_BASE + \
+	AT91SAM9G20_RSTC_BASE + RST_CR)
+
+/*
+ * From AT91SAM9G20 Datasheet errata 44:3.5:
+ *
+ * When User Reset occurs durring SDRAM read acces, eh SDRAM clock is turned
+ * off while data are ready to be read on the data bus. The SDRAM maintains
+ * the data until the clock restarts.
+ *
+ * If the User reset is programed to assert a general reset, the data
+ * maintained by the SDRAM leads to a data bus conflict and adversly affects
+ * the boot memories connected to the EBI:
+ *  + NAND Flash boot functionality, if the system boots out of internal ROM.
+ *  + NOR Flash boot, if the system boots on an external memory connected to
+ *    the EBI CS0.
+ *
+ * Assembly code is mandatory for the following sequnce as ARM
+ * instructions need to be piplined.
+ *
+ */
+
+ENTRY(cpu_reset_sam9g20)
+
+	/* Disable IRQs */
+	mrs	r0, cpsr
+	orr	r0, r0, #0x80
+	msr	cpsr_c, r0
+
+	/* Change Refresh to block all data access */
+	ldr	r0, =SDRAM_TR
+	ldr	r1, =1
+	str	r1, [r0]
+
+	/* Prepare power down command */
+	ldr	r0, =SDRAM_LPR
+	ldr	r1, =2
+
+	/* Prepare proc_reset and periph reset */
+	ldr	r2, =RSTC_RCR
+	ldr	r3, =0xA5000005
+
+	/* perform power down command */
+	str 	r1, [r0]
+
+	/* Perfom proc_reset and periph reset (in the ARM pipeline) */
+	str	r3, [r2]


Property changes on: trunk/sys/arm/at91/at91_reset.S
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91_rst.c
===================================================================
--- trunk/sys/arm/at91/at91_rst.c	                        (rev 0)
+++ trunk/sys/arm/at91/at91_rst.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,236 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2010 Greg Ansley.  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 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 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: stable/10/sys/arm/at91/at91_rst.c 266196 2014-05-15 21:21:47Z ian $");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/rman.h>
+#include <sys/systm.h>
+
+#include <machine/bus.h>
+
+#include <arm/at91/at91var.h>
+#include <arm/at91/at91_rstreg.h>
+#include <arm/at91/at91board.h>
+
+#ifdef FDT
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+#define FDT_HACKS 1
+#endif
+
+#define RST_TIMEOUT (5)	/* Seconds to hold NRST for hard reset */
+#define RST_TICK (20)	/* sample NRST at hz/RST_TICK intervals */
+
+#ifndef FDT
+static int at91_rst_intr(void *arg);
+#endif
+
+static struct at91_rst_softc {
+	struct resource	*mem_res;	/* Memory resource */
+	struct resource	*irq_res;	/* IRQ resource */
+	void		*intrhand;	/* Interrupt handle */
+	struct callout	tick_ch;	/* Tick callout */
+	device_t	sc_dev;
+	u_int		shutdown;	/* Shutdown in progress */
+} *at91_rst_sc;
+
+static inline uint32_t
+RD4(struct at91_rst_softc *sc, bus_size_t off)
+{
+
+	return (bus_read_4(sc->mem_res, off));
+}
+
+static inline void
+WR4(struct at91_rst_softc *sc, bus_size_t off, uint32_t val)
+{
+
+	bus_write_4(sc->mem_res, off, val);
+}
+
+void cpu_reset_sam9g20(void) __attribute__((weak));
+void cpu_reset_sam9g20(void) {}
+
+void
+at91_rst_cpu_reset(void)
+{
+
+	if (at91_rst_sc) {
+		cpu_reset_sam9g20(); /* May be null */
+
+		WR4(at91_rst_sc, RST_MR,
+		    RST_MR_ERSTL(0xd) | RST_MR_URSTEN | RST_MR_KEY);
+
+		WR4(at91_rst_sc, RST_CR,
+		    RST_CR_PROCRST |
+		    RST_CR_PERRST  |
+		    RST_CR_EXTRST  |
+		    RST_CR_KEY);
+	}
+	while(1)
+		continue;
+}
+
+static int
+at91_rst_probe(device_t dev)
+{
+#ifdef FDT
+	if (!ofw_bus_is_compatible(dev, "atmel,at91sam9260-rstc"))
+		return (ENXIO);
+#endif
+
+	device_set_desc(dev, "AT91SAM9 Reset Controller");
+	return (0);
+}
+
+static int
+at91_rst_attach(device_t dev)
+{
+	struct at91_rst_softc *sc;
+	const char *cause;
+	int rid, err = 0;
+
+	at91_rst_sc = sc = device_get_softc(dev);
+	sc->sc_dev = dev;
+
+	callout_init(&sc->tick_ch, 0);
+
+	rid = 0;
+	sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	    RF_ACTIVE);
+	if (sc->mem_res == NULL) {
+		device_printf(dev, "could not allocate memory resources.\n");
+		err = ENOMEM;
+		goto out;
+	}
+
+#ifndef FDT_HACKS
+	rid = 0;
+	sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+	    RF_ACTIVE | RF_SHAREABLE);
+	if (sc->irq_res == NULL) {
+		device_printf(dev, "could not allocate interrupt resources.\n");
+		err = ENOMEM;
+		goto out;
+	}
+
+	/* Activate the interrupt. */
+	err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
+	    at91_rst_intr, NULL, sc, &sc->intrhand);
+	if (err)
+		device_printf(dev, "could not establish interrupt handler.\n");
+#endif
+
+	WR4(at91_rst_sc, RST_MR, RST_MR_ERSTL(0xd) | RST_MR_URSIEN | RST_MR_KEY);
+
+	switch (RD4(sc, RST_SR) & RST_SR_RST_MASK) {
+		case	RST_SR_RST_POW:
+			cause = "Power On";
+			break;
+		case	RST_SR_RST_WAKE:
+			cause = "Wake Up";
+			break;
+		case	RST_SR_RST_WDT:
+			cause = "Watchdog";
+			break;
+		case	RST_SR_RST_SOFT:
+			cause = "Software Request";
+			break;
+		case	RST_SR_RST_USR:
+			cause = "External (User)";
+			break;
+		default:
+			cause = "Unknown";
+			break;
+	}
+
+	device_printf(dev, "Reset cause: %s.\n", cause);
+out:
+	return (err);
+}
+
+#ifndef FDT_HACKS
+static void
+at91_rst_tick(void *argp)
+{
+	struct at91_rst_softc *sc = argp;
+
+	if (sc->shutdown++ >= RST_TIMEOUT * RST_TICK) {
+		/* User released the button in morre than RST_TIMEOUT */
+		cpu_reset();
+	} else if ((RD4(sc, RST_SR) & RST_SR_NRSTL)) {
+		/* User released the button in less than RST_TIMEOUT */
+		sc->shutdown = 0;
+		device_printf(sc->sc_dev, "shutting down...\n");
+		shutdown_nice(0);
+	} else {
+		callout_reset(&sc->tick_ch, hz/RST_TICK, at91_rst_tick, sc);
+	}
+}
+
+static int
+at91_rst_intr(void *argp)
+{
+	struct at91_rst_softc *sc = argp;
+
+	if (RD4(sc, RST_SR) & RST_SR_URSTS) {
+		if (sc->shutdown == 0)
+			callout_reset(&sc->tick_ch, hz/RST_TICK, at91_rst_tick, sc);
+		return (FILTER_HANDLED);
+	}
+	return (FILTER_STRAY);
+}
+#endif
+
+static device_method_t at91_rst_methods[] = {
+	DEVMETHOD(device_probe, at91_rst_probe),
+	DEVMETHOD(device_attach, at91_rst_attach),
+	DEVMETHOD_END
+};
+
+static driver_t at91_rst_driver = {
+	"at91_rst",
+	at91_rst_methods,
+	sizeof(struct at91_rst_softc),
+};
+
+static devclass_t at91_rst_devclass;
+
+#ifdef FDT
+DRIVER_MODULE(at91_rst, simplebus, at91_rst_driver, at91_rst_devclass, NULL,
+    NULL);
+#else
+DRIVER_MODULE(at91_rst, atmelarm, at91_rst_driver, at91_rst_devclass, NULL,
+    NULL);
+#endif


Property changes on: trunk/sys/arm/at91/at91_rst.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91_rstreg.h
===================================================================
--- trunk/sys/arm/at91/at91_rstreg.h	                        (rev 0)
+++ trunk/sys/arm/at91/at91_rstreg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,64 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2009 Greg Ansley.  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 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 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: stable/10/sys/arm/at91/at91_rstreg.h 238369 2012-07-11 17:11:07Z imp $ */
+
+#ifndef ARM_AT91_AT91_RSTREG_H
+#define ARM_AT91_AT91_RSTREG_H
+
+#define	RST_CR		0x0	/* Control Register */
+#define	RST_SR		0x4	/* Status Register */
+#define	RST_MR		0x8	/* Mode Register */
+
+/* RST_CR */
+#define	RST_CR_PROCRST		(1<<0)
+#define	RST_CR_PERRST		(1<<2)
+#define	RST_CR_EXTRST		(1<<3)
+#define	RST_CR_KEY		(0xa5<<24)
+
+/* RST_SR */
+#define	RST_SR_SRCMP		(1<<17)	/* Software Reset in progress */	
+#define	RST_SR_NRSTL		(1<<16)	/* NRST pin level at MCK */	
+#define	RST_SR_URSTS		(1<<0)	/* NRST pin has been active */	
+
+#define	RST_SR_RST_POW		(0<<8)	/* General (Power On) reset */	
+#define	RST_SR_RST_WAKE		(1<<8)	/* Wake-up reset */
+#define	RST_SR_RST_WDT		(2<<8)	/* Watchdog reset */
+#define	RST_SR_RST_SOFT		(3<<8)	/* Software  reset */
+#define	RST_SR_RST_USR		(4<<8)	/* User (External) reset */
+#define	RST_SR_RST_MASK		(7<<8)	/* User (External) reset */
+
+/* RST_MR */
+#define	RST_MR_URSTEN		(1<<0)	/* User reset enable */	
+#define	RST_MR_URSIEN		(1<<4)	/* User interrupt enable */	
+#define	RST_MR_ERSTL(x)		((x)<<8) /* External reset length */	
+#define	RST_MR_KEY		(0xa5<<24)
+
+#ifndef __ASSEMBLER__
+void at91_rst_cpu_reset(void);
+#endif
+
+#endif /* ARM_AT91_AT91_RSTREG_H */


Property changes on: trunk/sys/arm/at91/at91_rstreg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91_rtc.c
===================================================================
--- trunk/sys/arm/at91/at91_rtc.c	                        (rev 0)
+++ trunk/sys/arm/at91/at91_rtc.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,365 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2006 M. Warner Losh.  All rights reserved.
+ * Copyright (c) 2012 Ian Lepore.  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 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 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.
+ */
+
+/*
+ * Driver for the at91 on-chip realtime clock.
+ *
+ * This driver does not currently support alarms, just date and time.
+ *
+ * The RTC on the AT91RM9200 resets when the core rests, so it is useless as a
+ * source of time (except when the CPU clock is powered down to save power,
+ * which we don't currently do).  On AT91SAM9 chips, the RTC survives chip
+ * reset, and there's provisions for it to keep time via battery backup if the
+ * system loses power.  On those systems, we use it as a RTC.  We tell the two
+ * apart because the century field is 19 on AT91RM9200 on reset, or on AT91SAM9
+ * chips that haven't had their time properly set.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/at91/at91_rtc.c 241333 2012-10-07 20:36:46Z imp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/clock.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/mbuf.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/rman.h>
+#include <machine/bus.h>
+#include <machine/cpu.h>
+
+#include <arm/at91/at91_rtcreg.h>
+
+#include "clock_if.h"
+
+/*
+ * The driver has all the infrastructure to use interrupts but doesn't actually
+ * have any need to do so right now.  There's a non-zero cost for installing the
+ * handler because the RTC shares the system interrupt (IRQ 1), and thus will
+ * get called a lot for no reason at all.
+ */
+#define	AT91_RTC_USE_INTERRUPTS_NOT
+
+struct at91_rtc_softc
+{
+	device_t dev;			/* Myself */
+	void *intrhand;			/* Interrupt handle */
+	struct resource *irq_res;	/* IRQ resource */
+	struct resource	*mem_res;	/* Memory resource */
+	struct mtx sc_mtx;		/* basically a perimeter lock */
+};
+
+static inline uint32_t
+RD4(struct at91_rtc_softc *sc, bus_size_t off)
+{
+	return bus_read_4(sc->mem_res, off);
+}
+
+static inline void
+WR4(struct at91_rtc_softc *sc, bus_size_t off, uint32_t val)
+{
+	bus_write_4(sc->mem_res, off, val);
+}
+
+#define AT91_RTC_LOCK(_sc)		mtx_lock_spin(&(_sc)->sc_mtx)
+#define	AT91_RTC_UNLOCK(_sc)		mtx_unlock_spin(&(_sc)->sc_mtx)
+#define AT91_RTC_LOCK_INIT(_sc) \
+	mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->dev), \
+	    "rtc", MTX_SPIN)
+#define AT91_RTC_LOCK_DESTROY(_sc)	mtx_destroy(&_sc->sc_mtx);
+#define AT91_RTC_ASSERT_LOCKED(_sc)	mtx_assert(&_sc->sc_mtx, MA_OWNED);
+#define AT91_RTC_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED);
+
+static devclass_t at91_rtc_devclass;
+
+/* bus entry points */
+
+static int at91_rtc_probe(device_t dev);
+static int at91_rtc_attach(device_t dev);
+static int at91_rtc_detach(device_t dev);
+
+/* helper routines */
+static int at91_rtc_activate(device_t dev);
+static void at91_rtc_deactivate(device_t dev);
+
+#ifdef AT91_RTC_USE_INTERRUPTS
+static int
+at91_rtc_intr(void *xsc)
+{
+	struct at91_rtc_softc *sc;
+	uint32_t status;
+
+	sc = xsc;
+	/* Must clear the status bits after reading them to re-arm. */
+	status = RD4(sc, RTC_SR);
+	WR4(sc, RTC_SCCR, status);
+	if (status == 0)
+		return;
+	AT91_RTC_LOCK(sc);
+        /* Do something here */
+	AT91_RTC_UNLOCK(sc);
+	wakeup(sc);
+	return (FILTER_HANDLED);
+}
+#endif
+
+static int
+at91_rtc_probe(device_t dev)
+{
+	device_set_desc(dev, "RTC");
+	return (0);
+}
+
+static int
+at91_rtc_attach(device_t dev)
+{
+	struct at91_rtc_softc *sc = device_get_softc(dev);
+	int err;
+
+	sc->dev = dev;
+	err = at91_rtc_activate(dev);
+	if (err)
+		goto out;
+
+	AT91_RTC_LOCK_INIT(sc);
+
+	/*
+	 * Disable all interrupts in the hardware.
+	 * Clear all bits in the status register.
+	 * Set 24-hour-clock mode.
+	 */
+	WR4(sc, RTC_IDR, 0xffffffff);
+	WR4(sc, RTC_SCCR, 0x1f);
+	WR4(sc, RTC_MR, 0);
+
+#ifdef AT91_RTC_USE_INTERRUPTS
+	err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC,
+	    at91_rtc_intr, NULL, sc, &sc->intrhand);
+	if (err) {
+		AT91_RTC_LOCK_DESTROY(sc);
+		goto out;
+	}
+#endif	
+
+	/*
+	 * Read the calendar register.  If the century is 19 then the clock has
+	 * never been set.  Try to store an invalid value into the register,
+	 * which will turn on the error bit in RTC_VER, and our getclock code
+	 * knows to return EINVAL if any error bits are on.
+	 */
+	if (RTC_CALR_CEN(RD4(sc, RTC_CALR)) == 19)
+		WR4(sc, RTC_CALR, 0);
+
+	/*
+	 * Register as a time of day clock with 1-second resolution.
+	 */
+	clock_register(dev, 1000000);
+out:
+	if (err)
+		at91_rtc_deactivate(dev);
+	return (err);
+}
+
+/*
+ * Cannot support detach, since there's no clock_unregister function.
+ */
+static int
+at91_rtc_detach(device_t dev)
+{
+	return (EBUSY);
+}
+
+static int
+at91_rtc_activate(device_t dev)
+{
+	struct at91_rtc_softc *sc;
+	int rid;
+
+	sc = device_get_softc(dev);
+	rid = 0;
+	sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	    RF_ACTIVE);
+	if (sc->mem_res == NULL)
+		goto errout;
+#ifdef AT91_RTC_USE_INTERRUPTS
+	rid = 0;
+	sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+	    RF_ACTIVE | RF_SHAREABLE);
+	if (sc->irq_res == NULL)
+		goto errout;
+#endif	
+	return (0);
+errout:
+	at91_rtc_deactivate(dev);
+	return (ENOMEM);
+}
+
+static void
+at91_rtc_deactivate(device_t dev)
+{
+	struct at91_rtc_softc *sc;
+
+	sc = device_get_softc(dev);
+#ifdef AT91_RTC_USE_INTERRUPTS
+	WR4(sc, RTC_IDR, 0xffffffff);
+	if (sc->intrhand)
+		bus_teardown_intr(dev, sc->irq_res, sc->intrhand);
+	sc->intrhand = 0;
+#endif
+	bus_generic_detach(sc->dev);
+	if (sc->mem_res)
+		bus_release_resource(dev, SYS_RES_MEMORY,
+		    rman_get_rid(sc->mem_res), sc->mem_res);
+	sc->mem_res = 0;
+#ifdef AT91_RTC_USE_INTERRUPTS
+	if (sc->irq_res)
+		bus_release_resource(dev, SYS_RES_IRQ,
+		    rman_get_rid(sc->irq_res), sc->irq_res);
+	sc->irq_res = 0;
+#endif	
+	return;
+}
+
+/*
+ * Get the time of day clock and return it in ts.
+ * Return 0 on success, an error number otherwise.
+ */
+static int
+at91_rtc_gettime(device_t dev, struct timespec *ts)
+{
+	struct clocktime ct;
+	uint32_t calr, calr2, timr, timr2;
+	struct at91_rtc_softc *sc;
+
+	sc = device_get_softc(dev);
+
+	/* If the error bits are set we can't return useful values. */
+
+	if (RD4(sc, RTC_VER) & (RTC_VER_NVTIM | RTC_VER_NVCAL))
+		return EINVAL;
+
+	/*
+	 * The RTC hardware can update registers while the CPU is reading them.
+	 * The manual advises reading until you obtain the same values twice.
+	 * Interleaving the reads (rather than timr, timr2, calr, calr2 order)
+	 * also ensures we don't miss a midnight rollover/carry between reads.
+	 */
+	do {
+		timr = RD4(sc, RTC_TIMR);
+		calr = RD4(sc, RTC_CALR);
+		timr2 = RD4(sc, RTC_TIMR);
+		calr2 = RD4(sc, RTC_CALR);
+	} while (timr != timr2 || calr != calr2);
+
+	ct.nsec = 0;
+	ct.sec = RTC_TIMR_SEC(timr);
+	ct.min = RTC_TIMR_MIN(timr);
+	ct.hour = RTC_TIMR_HR(timr);
+	ct.year = RTC_CALR_CEN(calr) * 100 + RTC_CALR_YEAR(calr);
+	ct.mon = RTC_CALR_MON(calr);
+	ct.day = RTC_CALR_DAY(calr);
+	ct.dow = -1;
+	return clock_ct_to_ts(&ct, ts);
+}
+
+/*
+ * Set the time of day clock based on the value of the struct timespec arg.
+ * Return 0 on success, an error number otherwise.
+ */
+static int
+at91_rtc_settime(device_t dev, struct timespec *ts)
+{
+	struct at91_rtc_softc *sc;
+	struct clocktime ct;
+	int rv;
+
+	sc = device_get_softc(dev);
+	clock_ts_to_ct(ts, &ct);
+
+	/*
+	 * Can't set the clock unless a second has elapsed since we last did so.
+	 */
+	while ((RD4(sc, RTC_SR) & RTC_SR_SECEV) == 0)
+		cpu_spinwait();
+
+	/*
+	 * Stop the clocks for an update; wait until hardware is ready.
+	 * Clear the update-ready status after it gets asserted (the manual says
+	 * to do this before updating the value registers).
+	 */
+	WR4(sc, RTC_CR, RTC_CR_UPDCAL | RTC_CR_UPDTIM);
+	while ((RD4(sc, RTC_SR) & RTC_SR_ACKUPD) == 0)
+		cpu_spinwait();
+	WR4(sc, RTC_SCCR, RTC_SR_ACKUPD);
+
+	/*
+	 * Set the values in the hardware, then check whether the hardware was
+	 * happy with them so we can return the correct status.
+	 */
+	WR4(sc, RTC_TIMR, RTC_TIMR_MK(ct.hour, ct.min, ct.sec));
+	WR4(sc, RTC_CALR, RTC_CALR_MK(ct.year, ct.mon, ct.day, ct.dow+1));
+
+	if (RD4(sc, RTC_VER) & (RTC_VER_NVTIM | RTC_VER_NVCAL))
+		rv = EINVAL;
+	else
+		rv = 0;
+
+	/*
+	 * Restart the clocks (turn off the update bits).
+	 * Clear the second-event bit (because the manual says to).
+	 */
+	WR4(sc, RTC_CR, RD4(sc, RTC_CR) & ~(RTC_CR_UPDCAL | RTC_CR_UPDTIM));
+	WR4(sc, RTC_SCCR, RTC_SR_SECEV);
+
+	return (0);
+}
+
+static device_method_t at91_rtc_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		at91_rtc_probe),
+	DEVMETHOD(device_attach,	at91_rtc_attach),
+	DEVMETHOD(device_detach,	at91_rtc_detach),
+
+        /* clock interface */
+        DEVMETHOD(clock_gettime,        at91_rtc_gettime),
+        DEVMETHOD(clock_settime,        at91_rtc_settime),
+
+	DEVMETHOD_END
+};
+
+static driver_t at91_rtc_driver = {
+	"at91_rtc",
+	at91_rtc_methods,
+	sizeof(struct at91_rtc_softc),
+};
+
+DRIVER_MODULE(at91_rtc, atmelarm, at91_rtc_driver, at91_rtc_devclass, 0, 0);


Property changes on: trunk/sys/arm/at91/at91_rtc.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91_rtcreg.h
===================================================================
--- trunk/sys/arm/at91/at91_rtcreg.h	                        (rev 0)
+++ trunk/sys/arm/at91/at91_rtcreg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,104 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2006 M. Warner Losh.  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 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 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: stable/10/sys/arm/at91/at91_rtcreg.h 241307 2012-10-07 01:58:32Z imp $ */
+
+#ifndef ARM_AT91_AT91_RTCREG_H
+#define ARM_AT91_AT91_RTCREG_H
+
+/* Registers */
+#define RTC_CR		0x00		/* RTC Control Register */
+#define RTC_MR		0x04		/* RTC Mode Register */
+#define RTC_TIMR	0x08		/* RTC Time Register */
+#define RTC_CALR	0x0c		/* RTC Calendar Register */
+#define RTC_TIMALR	0x10		/* RTC Time Alarm Register */
+#define RTC_CALALR	0x14		/* RTC Calendar Alarm Register */
+#define RTC_SR		0x18		/* RTC Status Register */
+#define RTC_SCCR	0x1c		/* RTC Status Command Clear Register */
+#define RTC_IER		0x20		/* RTC Interrupt Enable Register */
+#define RTC_IDR		0x24		/* RTC Interrupt Disable Register */
+#define RTC_IMR		0x28		/* RTC Interrupt Mask Register */
+#define RTC_VER		0x2c		/* RTC Valid Entry Register */
+
+/* CR */
+#define	RTC_CR_UPDTIM	(0x1u <<  0)	/* Request update of time register */
+#define	RTC_CR_UPDCAL	(0x1u <<  1)	/* Request update of calendar reg. */
+
+/* TIMR */
+#define RTC_TIMR_SEC_M	0x7fUL
+#define RTC_TIMR_SEC_S	0
+#define RTC_TIMR_SEC(x)	FROMBCD(((x) & RTC_TIMR_SEC_M) >> RTC_TIMR_SEC_S)
+#define RTC_TIMR_MIN_M	0x7f00UL
+#define RTC_TIMR_MIN_S	8
+#define RTC_TIMR_MIN(x)	FROMBCD(((x) & RTC_TIMR_MIN_M) >> RTC_TIMR_MIN_S)
+#define RTC_TIMR_HR_M	0x3f0000UL
+#define RTC_TIMR_HR_S	16
+#define RTC_TIMR_HR(x)	FROMBCD(((x) & RTC_TIMR_HR_M) >> RTC_TIMR_HR_S)
+#define RTC_TIMR_MK(hr, min, sec) \
+		((TOBCD(hr) << RTC_TIMR_HR_S) | \
+		 (TOBCD(min) << RTC_TIMR_MIN_S) | \
+		 (TOBCD(sec) << RTC_TIMR_SEC_S))
+#define RTC_TIMR_PM	(1UL << 22)
+
+/* CALR */
+#define RTC_CALR_CEN_M	0x0000007fUL
+#define RTC_CALR_CEN_S	0
+#define RTC_CALR_CEN(x)	FROMBCD(((x) & RTC_CALR_CEN_M) >> RTC_CALR_CEN_S)
+#define RTC_CALR_YEAR_M	0x0000ff00UL
+#define RTC_CALR_YEAR_S 8
+#define RTC_CALR_YEAR(x) FROMBCD(((x) & RTC_CALR_YEAR_M) >> RTC_CALR_YEAR_S)
+#define RTC_CALR_MON_M	0x001f0000UL
+#define RTC_CALR_MON_S	16
+#define RTC_CALR_MON(x)	FROMBCD(((x) & RTC_CALR_MON_M) >> RTC_CALR_MON_S)
+#define RTC_CALR_DOW_M	0x00d0000UL
+#define RTC_CALR_DOW_S	21
+#define RTC_CALR_DOW(x)	FROMBCD(((x) & RTC_CALR_DOW_M) >> RTC_CALR_DOW_S)
+#define RTC_CALR_DAY_M	0x3f000000UL
+#define RTC_CALR_DAY_S	24
+#define RTC_CALR_DAY(x)	FROMBCD(((x) & RTC_CALR_DAY_M) >> RTC_CALR_DAY_S)
+#define RTC_CALR_MK(yr, mon, day, dow) \
+		((TOBCD((yr) / 100) << RTC_CALR_CEN_S) | \
+		 (TOBCD((yr) % 100) << RTC_CALR_YEAR_S) | \
+		 (TOBCD(mon) << RTC_CALR_MON_S) | \
+		 (TOBCD(dow) << RTC_CALR_DOW_S) | \
+		 (TOBCD(day) << RTC_CALR_DAY_S))
+
+/* SR */
+
+#define	RTC_SR_ACKUPD		(0x1u <<  0)	/* Acknowledge for Update */
+#define	RTC_SR_ALARM		(0x1u <<  1)	/* Alarm Flag */
+#define	RTC_SR_SECEV		(0x1u <<  2)	/* Second Event */
+#define	RTC_SR_TIMEV		(0x1u <<  3)	/* Time Event */
+#define	RTC_SR_CALEV		(0x1u <<  4)	/* Calendar event */
+
+/* VER */
+
+#define	RTC_VER_NVTIM		(0x1 << 0)	/* Non-valid time */
+#define	RTC_VER_NVCAL		(0x1 << 1)	/* Non-valid calendar */
+#define	RTC_VER_NVTIMALR	(0x1 << 2)	/* Non-valid time alarm */
+#define	RTC_VER_NVCALALR	(0x1 << 3)	/* Non-valid calendar alarm */
+
+#endif /* ARM_AT91_AT91_RTCREG_H */


Property changes on: trunk/sys/arm/at91/at91_rtcreg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91_sdramc.c
===================================================================
--- trunk/sys/arm/at91/at91_sdramc.c	                        (rev 0)
+++ trunk/sys/arm/at91/at91_sdramc.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,106 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014 Warner Losh.  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 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 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: stable/10/sys/arm/at91/at91_sdramc.c 266217 2014-05-16 12:43:45Z ian $");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/resource.h>
+#include <sys/systm.h>
+#include <sys/rman.h>
+
+#include <machine/bus.h>
+
+#include <arm/at91/at91var.h>
+#include <arm/at91/at91_aicreg.h>
+
+#ifdef FDT
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+#endif
+
+struct sdramc_softc {
+	struct resource	*mem_res;	/* Memory resource */
+	device_t	sc_dev;
+};
+
+static int
+at91_sdramc_probe(device_t dev)
+{
+#ifdef FDT
+	if (!ofw_bus_is_compatible(dev, "atmel,at91sam9260-sdramc"))
+		return (ENXIO);
+#endif
+	device_set_desc(dev, "SDRAMC");
+        return (0);
+}
+
+static int
+at91_sdramc_attach(device_t dev)
+{
+	int rid, err = 0;
+	struct sdramc_softc *sc;
+
+	sc = device_get_softc(dev);
+	sc->sc_dev = dev;
+
+	rid = 0;
+	sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	    RF_ACTIVE);
+
+	if (sc->mem_res == NULL)
+		panic("couldn't allocate register resources");
+
+	return (err);
+}
+
+static device_method_t at91_sdramc_methods[] = {
+	DEVMETHOD(device_probe, at91_sdramc_probe),
+	DEVMETHOD(device_attach, at91_sdramc_attach),
+	DEVMETHOD_END
+};
+
+static driver_t at91_sdramc_driver = {
+	"at91_sdramc",
+	at91_sdramc_methods,
+	sizeof(struct sdramc_softc),
+};
+
+static devclass_t at91_sdramc_devclass;
+
+#ifdef FDT
+DRIVER_MODULE(at91_sdramc, simplebus, at91_sdramc_driver, at91_sdramc_devclass, NULL,
+    NULL);
+#else
+DRIVER_MODULE(at91_sdramc, atmelarm, at91_sdramc_driver, at91_sdramc_devclass, NULL,
+    NULL);
+#endif


Property changes on: trunk/sys/arm/at91/at91_sdramc.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91_shdwc.c
===================================================================
--- trunk/sys/arm/at91/at91_shdwc.c	                        (rev 0)
+++ trunk/sys/arm/at91/at91_shdwc.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,106 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014 Warner Losh.  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 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 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: stable/10/sys/arm/at91/at91_shdwc.c 266217 2014-05-16 12:43:45Z ian $");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/resource.h>
+#include <sys/systm.h>
+#include <sys/rman.h>
+
+#include <machine/bus.h>
+
+#include <arm/at91/at91var.h>
+#include <arm/at91/at91_aicreg.h>
+
+#ifdef FDT
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+#endif
+
+struct shdwc_softc {
+	struct resource	*mem_res;	/* Memory resource */
+	device_t	sc_dev;
+};
+
+static int
+at91_shdwc_probe(device_t dev)
+{
+#ifdef FDT
+	if (!ofw_bus_is_compatible(dev, "atmel,at91sam9260-shdwc"))
+		return (ENXIO);
+#endif
+	device_set_desc(dev, "SHDWC");
+        return (0);
+}
+
+static int
+at91_shdwc_attach(device_t dev)
+{
+	int rid, err = 0;
+	struct shdwc_softc *sc;
+
+	sc = device_get_softc(dev);
+	sc->sc_dev = dev;
+
+	rid = 0;
+	sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	    RF_ACTIVE);
+
+	if (sc->mem_res == NULL)
+		panic("couldn't allocate register resources");
+
+	return (err);
+}
+
+static device_method_t at91_shdwc_methods[] = {
+	DEVMETHOD(device_probe, at91_shdwc_probe),
+	DEVMETHOD(device_attach, at91_shdwc_attach),
+	DEVMETHOD_END
+};
+
+static driver_t at91_shdwc_driver = {
+	"at91_shdwc",
+	at91_shdwc_methods,
+	sizeof(struct shdwc_softc),
+};
+
+static devclass_t at91_shdwc_devclass;
+
+#ifdef FDT
+DRIVER_MODULE(at91_shdwc, simplebus, at91_shdwc_driver, at91_shdwc_devclass, NULL,
+    NULL);
+#else
+DRIVER_MODULE(at91_shdwc, atmelarm, at91_shdwc_driver, at91_shdwc_devclass, NULL,
+    NULL);
+#endif


Property changes on: trunk/sys/arm/at91/at91_shdwc.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91_smc.c
===================================================================
--- trunk/sys/arm/at91/at91_smc.c	                        (rev 0)
+++ trunk/sys/arm/at91/at91_smc.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,92 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014 M. Warner Losh.  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 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 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: stable/10/sys/arm/at91/at91_smc.c 266087 2014-05-14 20:31:54Z ian $");
+
+#include <sys/types.h>
+
+#include <arm/at91/at91reg.h>
+#include <arm/at91/at91_smc.h>
+#include <arm/at91/at91sam9260reg.h>
+
+/*
+ * RD4HW()/WR4HW() read and write at91 hardware register space directly. They
+ * serve the same purpose as the RD4()/WR4() idiom you see in many drivers,
+ * except that those translate to bus_space calls, but in this code we need to
+ * access some devices before bus_space is ready to use.  Of course for this to
+ * work the appropriate static device mappings need to be made in machdep.c.
+ */
+static inline uint32_t 
+RD4HW(uint32_t devbase, uint32_t regoff)
+{
+	
+	return *(volatile uint32_t *)(AT91_BASE + devbase + regoff);
+}
+
+
+static inline void
+WR4HW(uint32_t devbase, uint32_t regoff, uint32_t val)
+{
+	
+	*(volatile uint32_t *)(AT91_BASE + devbase + regoff) = val;
+}
+
+
+void
+at91_smc_setup(int id, int cs, const struct at91_smc_init *smc)
+{
+	// Need a generic way to get this address for all SoCs... Assume 9260 for now...
+	uint32_t base = AT91SAM9260_SMC_BASE + SMC_CS_OFF(cs);
+
+	WR4HW(base, SMC_SETUP, SMC_SETUP_NCS_RD_SETUP(smc->ncs_rd_setup) |
+	      SMC_SETUP_NRD_SETUP(smc->nrd_setup) |
+	      SMC_SETUP_NCS_WR_SETUP(smc->ncs_wr_setup) |
+	      SMC_SETUP_NWE_SETUP(smc->nwe_setup));
+	WR4HW(base, SMC_PULSE, SMC_PULSE_NCS_RD_PULSE(smc->ncs_rd_pulse) |
+	      SMC_PULSE_NRD_PULSE(smc->nrd_pulse) |
+	      SMC_PULSE_NCS_WR_PULSE(smc->ncs_wr_pulse) |
+	      SMC_PULSE_NWE_PULSE(smc->nwe_pulse));
+	WR4HW(base, SMC_CYCLE, SMC_CYCLE_NRD_CYCLE(smc->nrd_cycle) |
+	      SMC_CYCLE_NWE_CYCLE(smc->nwe_cycle));
+	WR4HW(base, SMC_MODE, smc->mode | SMC_MODE_TDF_CYCLES(smc->tdf_cycles));
+}
+
+void
+at91_ebi_enable(int bank)
+{
+
+	WR4HW(AT91SAM9260_MATRIX_BASE, AT91SAM9260_EBICSA, (1 << bank) |
+	      RD4HW(AT91SAM9260_MATRIX_BASE, AT91SAM9260_EBICSA));
+}
+
+void
+at91_ebi_disable(int bank)
+{
+
+	WR4HW(AT91SAM9260_MATRIX_BASE, AT91SAM9260_EBICSA, ~(1 << bank) &
+	      RD4HW(AT91SAM9260_MATRIX_BASE, AT91SAM9260_EBICSA));
+}


Property changes on: trunk/sys/arm/at91/at91_smc.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91_smc.h
===================================================================
--- trunk/sys/arm/at91/at91_smc.h	                        (rev 0)
+++ trunk/sys/arm/at91/at91_smc.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,117 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014 M. Warner Losh.  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 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 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: stable/10/sys/arm/at91/at91_smc.h 266087 2014-05-14 20:31:54Z ian $ */
+
+#ifndef ARM_AT91_AT91_SMC_H
+#define ARM_AT91_AT91_SMC_H
+
+/* Registers */
+#define	SMC_SETUP	0x00
+#define SMC_PULSE	0x04
+#define SMC_CYCLE	0x08
+#define	SMC_MODE	0x0C
+
+#define	SMC_CS_OFF(cs)	(0x10 * (cs))
+
+/* Setup */
+#define	SMC_SETUP_NCS_RD_SETUP(x)	((x) << 24)
+#define	SMC_SETUP_NRD_SETUP(x)		((x) << 16)
+#define	SMC_SETUP_NCS_WR_SETUP(x)	((x) << 8)
+#define	SMC_SETUP_NWE_SETUP(x)		(x)
+
+/* Pulse */
+#define	SMC_PULSE_NCS_RD_PULSE(x)	((x) << 24)
+#define	SMC_PULSE_NRD_PULSE(x)		((x) << 16)
+#define	SMC_PULSE_NCS_WR_PULSE(x)	((x) << 8)
+#define	SMC_PULSE_NWE_PULSE(x)		(x)
+
+/* Cycle */
+#define	SMC_CYCLE_NRD_CYCLE(x)		((x) << 16)
+#define	SMC_CYCLE_NWE_CYCLE(x)		(x)
+
+/* Mode */
+#define	SMC_MODE_READ			(1 << 0)
+#define	SMC_MODE_WRITE			(1 << 1)
+#define	SMC_MODE_EXNW_DISABLED		(0 << 4)
+#define	SMC_MODE_EXNW_FROZEN_MODE	(2 << 4)
+#define	SMC_MODE_EXNW_READY_MODE	(3 << 4)
+#define	SMC_MODE_BAT			(1 << 8)
+#define	SMC_MODE_DBW_8BIT		(0 << 12)
+#define	SMC_MODE_DBW_16BIT		(1 << 12)
+#define	SMC_MODE_DBW_32_BIT		(2 << 12)
+#define	SMC_MODE_TDF_CYCLES(x)		((x) << 16)
+#define	SMC_MODE_TDF_MODE		(1 << 20)
+#define	SMC_MODE_PMEN			(1 << 24)
+#define SMC_PS_4BYTE			(0 << 28)
+#define SMC_PS_8BYTE			(1 << 28)
+#define SMC_PS_16BYTE			(2 << 28)
+#define SMC_PS_32BYTE			(3 << 28)
+
+/*
+ * structure to ease init. See the SMC chapter in the datasheet for
+ * the appropriate SoC you are using for details.
+ */
+struct at91_smc_init
+{
+	/* Setup register */
+	uint8_t	ncs_rd_setup;
+	uint8_t nrd_setup;
+	uint8_t ncs_wr_setup;
+	uint8_t nwe_setup;
+
+	/* Pulse register */
+	uint8_t	ncs_rd_pulse;
+	uint8_t nrd_pulse;
+	uint8_t ncs_wr_pulse;
+	uint8_t nwe_pulse;
+
+	/* Cycle register */
+	uint16_t nrd_cycle;
+	uint16_t nwe_cycle;
+
+	/* Mode register */
+	uint8_t mode;		/* Combo of READ/WRITE/EXNW fields */
+	uint8_t bat;
+	uint8_t dwb;
+	uint8_t tdf_cycles;
+	uint8_t tdf_mode;
+	uint8_t pmen;
+	uint8_t ps;
+};
+
+/*
+ * Convenience routine to fill in SMC registers for a given chip select.
+ */
+void at91_smc_setup(int id, int cs, const struct at91_smc_init *smc);
+
+/*
+ * Disable/Enable different External Bus Interfaces (EBI)
+ */
+void at91_ebi_enable(int cs);
+void at91_ebi_disable(int cs);
+
+#endif /* ARM_AT91_AT91_SMC_H */


Property changes on: trunk/sys/arm/at91/at91_smc.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91_spi.c
===================================================================
--- trunk/sys/arm/at91/at91_spi.c	                        (rev 0)
+++ trunk/sys/arm/at91/at91_spi.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,458 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2006 M. Warner Losh.
+ * Copyright (c) 2011-2012 Ian Lepore.
+ * 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 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 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: stable/10/sys/arm/at91/at91_spi.c 266196 2014-05-15 21:21:47Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/mbuf.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/rman.h>
+#include <sys/sx.h>
+
+#include <machine/bus.h>
+
+#include <arm/at91/at91var.h>
+#include <arm/at91/at91_spireg.h>
+#include <arm/at91/at91_pdcreg.h>
+
+#include <dev/spibus/spi.h>
+#include <dev/spibus/spibusvar.h>
+
+#ifdef FDT
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+#endif
+
+#include "spibus_if.h"
+
+struct at91_spi_softc
+{
+	device_t dev;			/* Myself */
+	void *intrhand;			/* Interrupt handle */
+	struct resource *irq_res;	/* IRQ resource */
+	struct resource	*mem_res;	/* Memory resource */
+	bus_dma_tag_t dmatag;		/* bus dma tag for transfers */
+	bus_dmamap_t map[4];		/* Maps for the transaction */
+	struct sx xfer_mtx;		/* Enforce one transfer at a time */
+	uint32_t xfer_done;		/* interrupt<->mainthread signaling */
+};
+
+#define CS_TO_MR(cs)	((~(1 << (cs)) & 0x0f) << 16)
+
+static inline uint32_t
+RD4(struct at91_spi_softc *sc, bus_size_t off)
+{
+
+	return (bus_read_4(sc->mem_res, off));
+}
+
+static inline void
+WR4(struct at91_spi_softc *sc, bus_size_t off, uint32_t val)
+{
+
+	bus_write_4(sc->mem_res, off, val);
+}
+
+/* bus entry points */
+static int at91_spi_attach(device_t dev);
+static int at91_spi_detach(device_t dev);
+static int at91_spi_probe(device_t dev);
+static int at91_spi_transfer(device_t dev, device_t child,
+    struct spi_command *cmd);
+
+/* helper routines */
+static void at91_getaddr(void *arg, bus_dma_segment_t *segs, int nsegs,
+    int error);
+static int at91_spi_activate(device_t dev);
+static void at91_spi_deactivate(device_t dev);
+static void at91_spi_intr(void *arg);
+
+static int
+at91_spi_probe(device_t dev)
+{
+#ifdef FDT
+	if (!ofw_bus_is_compatible(dev, "atmel,at91rm9200-spi"))
+		return (ENXIO);
+#endif
+	device_set_desc(dev, "AT91 SPI");
+	return (0);
+}
+
+static int
+at91_spi_attach(device_t dev)
+{
+	struct at91_spi_softc *sc;
+	int err;
+	uint32_t csr;
+
+	sc = device_get_softc(dev);
+
+	sc->dev = dev;
+	sx_init(&sc->xfer_mtx, device_get_nameunit(dev));
+
+	/*
+	 * Allocate resources.
+	 */
+	err = at91_spi_activate(dev);
+	if (err)
+		goto out;
+
+#ifdef FDT
+	/*
+	 * Disable devices need to hold their resources, so return now and not attach
+	 * the spibus, setup interrupt handlers, etc.
+	 */
+	if (!ofw_bus_status_okay(dev))
+		return 0;
+#endif
+
+	/*
+	 * Set up the hardware.
+	 */
+
+	WR4(sc, SPI_CR, SPI_CR_SWRST);
+	/* "Software Reset must be Written Twice" erratum */
+	WR4(sc, SPI_CR, SPI_CR_SWRST);
+	WR4(sc, SPI_IDR, 0xffffffff);
+
+	WR4(sc, SPI_MR, (0xf << 24) | SPI_MR_MSTR | SPI_MR_MODFDIS |
+	    CS_TO_MR(0));
+
+	/*
+	 * For now, run the bus at the slowest speed possible as otherwise we
+	 * may encounter data corruption on transmit as seen with ETHERNUT5
+	 * and AT45DB321D even though both board and slave device can take
+	 * more.
+	 * This also serves as a work-around for the "NPCSx rises if no data
+	 * data is to be transmitted" erratum.  The ideal workaround for the
+	 * latter is to take the chip select control away from the peripheral
+	 * and manage it directly as a GPIO line.  The easy solution is to
+	 * slow down the bus so dramatically that it just never gets starved
+	 * as may be seen when the OCHI controller is running and consuming
+	 * memory and APB bandwidth.
+	 * Also, currently we lack a way for lettting both the board and the
+	 * slave devices take their maximum supported SPI clocks into account.
+	 * Also, we hard-wire SPI mode to 3.
+	 */
+	csr = SPI_CSR_CPOL | (4 << 16) | (0xff << 8);
+	WR4(sc, SPI_CSR0, csr);
+	WR4(sc, SPI_CSR1, csr);
+	WR4(sc, SPI_CSR2, csr);
+	WR4(sc, SPI_CSR3, csr);
+
+	WR4(sc, SPI_CR, SPI_CR_SPIEN);
+
+	WR4(sc, PDC_PTCR, PDC_PTCR_TXTDIS);
+	WR4(sc, PDC_PTCR, PDC_PTCR_RXTDIS);
+	WR4(sc, PDC_RNPR, 0);
+	WR4(sc, PDC_RNCR, 0);
+	WR4(sc, PDC_TNPR, 0);
+	WR4(sc, PDC_TNCR, 0);
+	WR4(sc, PDC_RPR, 0);
+	WR4(sc, PDC_RCR, 0);
+	WR4(sc, PDC_TPR, 0);
+	WR4(sc, PDC_TCR, 0);
+	RD4(sc, SPI_RDR);
+	RD4(sc, SPI_SR);
+
+	device_add_child(dev, "spibus", -1);
+	bus_generic_attach(dev);
+out:
+	if (err)
+		at91_spi_deactivate(dev);
+	return (err);
+}
+
+static int
+at91_spi_detach(device_t dev)
+{
+
+	return (EBUSY);	/* XXX */
+}
+
+static int
+at91_spi_activate(device_t dev)
+{
+	struct at91_spi_softc *sc;
+	int err, i, rid;
+
+	sc = device_get_softc(dev);
+	err = ENOMEM;
+
+	rid = 0;
+	sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	    RF_ACTIVE);
+	if (sc->mem_res == NULL)
+		goto out;
+
+	rid = 0;
+	sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+	    RF_ACTIVE);
+	if (sc->irq_res == NULL)
+		goto out;
+	err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
+	    NULL, at91_spi_intr, sc, &sc->intrhand);
+	if (err != 0)
+		goto out;
+
+	err = bus_dma_tag_create(bus_get_dma_tag(dev), 1, 0,
+	    BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, 2048, 1,
+	    2048, BUS_DMA_ALLOCNOW, NULL, NULL, &sc->dmatag);
+	if (err != 0)
+		goto out;
+
+	for (i = 0; i < 4; i++) {
+		err = bus_dmamap_create(sc->dmatag, 0,  &sc->map[i]);
+		if (err != 0)
+			goto out;
+	}
+out:
+	if (err != 0)
+		at91_spi_deactivate(dev);
+	return (err);
+}
+
+static void
+at91_spi_deactivate(device_t dev)
+{
+	struct at91_spi_softc *sc;
+	int i;
+
+	sc = device_get_softc(dev);
+	bus_generic_detach(dev);
+
+	for (i = 0; i < 4; i++)
+		if (sc->map[i])
+			bus_dmamap_destroy(sc->dmatag, sc->map[i]);
+
+	if (sc->dmatag)
+		bus_dma_tag_destroy(sc->dmatag);
+
+	if (sc->intrhand)
+		bus_teardown_intr(dev, sc->irq_res, sc->intrhand);
+	sc->intrhand = NULL;
+	if (sc->irq_res)
+		bus_release_resource(dev, SYS_RES_IRQ,
+		    rman_get_rid(sc->irq_res), sc->irq_res);
+	sc->irq_res = NULL;
+
+	if (sc->mem_res)
+		bus_release_resource(dev, SYS_RES_MEMORY,
+		    rman_get_rid(sc->mem_res), sc->mem_res);
+	sc->mem_res = NULL;
+}
+
+static void
+at91_getaddr(void *arg, bus_dma_segment_t *segs, int nsegs __unused,
+    int error)
+{
+
+	if (error != 0)
+		return;
+	*(bus_addr_t *)arg = segs[0].ds_addr;
+}
+
+static int
+at91_spi_transfer(device_t dev, device_t child, struct spi_command *cmd)
+{
+	struct at91_spi_softc *sc;
+	bus_addr_t addr;
+	int err, i, j, mode[4], cs;
+
+	KASSERT(cmd->tx_cmd_sz == cmd->rx_cmd_sz,
+	    ("%s: TX/RX command sizes should be equal", __func__));
+	KASSERT(cmd->tx_data_sz == cmd->rx_data_sz,
+	    ("%s: TX/RX data sizes should be equal", __func__));
+
+	/* get the proper chip select */
+	spibus_get_cs(child, &cs);
+
+	sc = device_get_softc(dev);
+	i = 0;
+
+	sx_xlock(&sc->xfer_mtx);
+
+	/*
+	 * Disable transfers while we set things up.
+	 */
+	WR4(sc, PDC_PTCR, PDC_PTCR_TXTDIS | PDC_PTCR_RXTDIS);
+
+	/*
+	 * PSCDEC = 0 has a range of 0..3 for chip select.  We
+	 * don't support PSCDEC = 1 which has a range of 0..15.
+	 */
+	if (cs < 0 || cs > 3) {
+		device_printf(dev,
+		    "Invalid chip select %d requested by %s\n", cs,
+		    device_get_nameunit(child));
+		err = EINVAL;
+		goto out;
+	}
+
+#ifdef SPI_CHIP_SELECT_HIGH_SUPPORT
+	/*
+	 * The AT91RM9200 couldn't do CS high for CS 0.  Other chips can, but we
+	 * don't support that yet, or other spi modes.
+	 */
+	if (at91_is_rm92() && cs == 0 &&
+	    (cmd->flags & SPI_CHIP_SELECT_HIGH) != 0) {
+		device_printf(dev,
+		    "Invalid chip select high requested by %s for cs 0.\n",
+		    device_get_nameunit(child));
+		err = EINVAL;
+		goto out;
+	}
+#endif
+	err = (RD4(sc, SPI_MR) & ~0x000f0000) | CS_TO_MR(cs);
+	WR4(sc, SPI_MR, err);
+
+	/*
+	 * Set up the TX side of the transfer.
+	 */
+	if ((err = bus_dmamap_load(sc->dmatag, sc->map[i], cmd->tx_cmd,
+	    cmd->tx_cmd_sz, at91_getaddr, &addr, 0)) != 0)
+		goto out;
+	WR4(sc, PDC_TPR, addr);
+	WR4(sc, PDC_TCR, cmd->tx_cmd_sz);
+	bus_dmamap_sync(sc->dmatag, sc->map[i], BUS_DMASYNC_PREWRITE);
+	mode[i++] = BUS_DMASYNC_POSTWRITE;
+	if (cmd->tx_data_sz > 0) {
+		if ((err = bus_dmamap_load(sc->dmatag, sc->map[i],
+		    cmd->tx_data, cmd->tx_data_sz, at91_getaddr, &addr, 0)) !=
+		    0)
+			goto out;
+		WR4(sc, PDC_TNPR, addr);
+		WR4(sc, PDC_TNCR, cmd->tx_data_sz);
+		bus_dmamap_sync(sc->dmatag, sc->map[i], BUS_DMASYNC_PREWRITE);
+		mode[i++] = BUS_DMASYNC_POSTWRITE;
+	}
+
+	/*
+	 * Set up the RX side of the transfer.
+	 */
+	if ((err = bus_dmamap_load(sc->dmatag, sc->map[i], cmd->rx_cmd,
+	    cmd->rx_cmd_sz, at91_getaddr, &addr, 0)) != 0)
+		goto out;
+	WR4(sc, PDC_RPR, addr);
+	WR4(sc, PDC_RCR, cmd->rx_cmd_sz);
+	bus_dmamap_sync(sc->dmatag, sc->map[i], BUS_DMASYNC_PREREAD);
+	mode[i++] = BUS_DMASYNC_POSTREAD;
+	if (cmd->rx_data_sz > 0) {
+		if ((err = bus_dmamap_load(sc->dmatag, sc->map[i],
+		    cmd->rx_data, cmd->rx_data_sz, at91_getaddr, &addr, 0)) !=
+		    0)
+			goto out;
+		WR4(sc, PDC_RNPR, addr);
+		WR4(sc, PDC_RNCR, cmd->rx_data_sz);
+		bus_dmamap_sync(sc->dmatag, sc->map[i], BUS_DMASYNC_PREREAD);
+		mode[i++] = BUS_DMASYNC_POSTREAD;
+	}
+
+	/*
+	 * Start the transfer, wait for it to complete.
+	 */
+	sc->xfer_done = 0;
+	WR4(sc, SPI_IER, SPI_SR_RXBUFF);
+	WR4(sc, PDC_PTCR, PDC_PTCR_TXTEN | PDC_PTCR_RXTEN);
+	do
+		err = tsleep(&sc->xfer_done, PCATCH | PZERO, "at91_spi", hz);
+	while (sc->xfer_done == 0 && err != EINTR);
+
+	/*
+	 * Stop the transfer and clean things up.
+	 */
+	WR4(sc, PDC_PTCR, PDC_PTCR_TXTDIS | PDC_PTCR_RXTDIS);
+	if (err == 0)
+		for (j = 0; j < i; j++)
+			bus_dmamap_sync(sc->dmatag, sc->map[j], mode[j]);
+out:
+	for (j = 0; j < i; j++)
+		bus_dmamap_unload(sc->dmatag, sc->map[j]);
+
+	sx_xunlock(&sc->xfer_mtx);
+
+	return (err);
+}
+
+static void
+at91_spi_intr(void *arg)
+{
+	struct at91_spi_softc *sc;
+	uint32_t sr;
+
+	sc = (struct at91_spi_softc*)arg;
+
+	sr = RD4(sc, SPI_SR) & RD4(sc, SPI_IMR);
+	if ((sr & SPI_SR_RXBUFF) != 0) {
+		sc->xfer_done = 1;
+		WR4(sc, SPI_IDR, SPI_SR_RXBUFF);
+		wakeup(&sc->xfer_done);
+	}
+	if ((sr & ~SPI_SR_RXBUFF) != 0) {
+		device_printf(sc->dev, "Unexpected ISR %#x\n", sr);
+		WR4(sc, SPI_IDR, sr & ~SPI_SR_RXBUFF);
+	}
+}
+
+static devclass_t at91_spi_devclass;
+
+static device_method_t at91_spi_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		at91_spi_probe),
+	DEVMETHOD(device_attach,	at91_spi_attach),
+	DEVMETHOD(device_detach,	at91_spi_detach),
+
+	/* spibus interface */
+	DEVMETHOD(spibus_transfer,	at91_spi_transfer),
+
+	DEVMETHOD_END
+};
+
+static driver_t at91_spi_driver = {
+	"spi",
+	at91_spi_methods,
+	sizeof(struct at91_spi_softc),
+};
+
+#ifdef FDT
+DRIVER_MODULE(at91_spi, simplebus, at91_spi_driver, at91_spi_devclass, NULL,
+    NULL);
+#else
+DRIVER_MODULE(at91_spi, atmelarm, at91_spi_driver, at91_spi_devclass, NULL,
+    NULL);
+#endif


Property changes on: trunk/sys/arm/at91/at91_spi.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91_spireg.h
===================================================================
--- trunk/sys/arm/at91/at91_spireg.h	                        (rev 0)
+++ trunk/sys/arm/at91/at91_spireg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,70 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2006 M. Warner Losh.  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 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 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: stable/10/sys/arm/at91/at91_spireg.h 236495 2012-06-03 00:54:10Z marius $ */
+
+#ifndef ARM_AT91_AT91_SPIREG_H
+#define ARM_AT91_AT91_SPIREG_H
+
+#define SPI_CR		0x00		/* CR: Control Register */
+#define	  SPI_CR_SPIEN		0x1
+#define	  SPI_CR_SPIDIS		0x2
+#define	  SPI_CR_SWRST		0x8
+#define SPI_MR		0x04		/* MR: Mode Register */
+#define	  SPI_MR_MSTR		0x01
+#define	  SPI_MR_PS		0x02
+#define   SPI_MR_PCSDEC		0x04
+#define   SPI_MR_DIV32		0x08
+#define	  SPI_MR_MODFDIS	0x10
+#define   SPI_MR_LLB		0x80
+#define   SPI_MR_PSC_CS0	0xe0000
+#define   SPI_MR_PSC_CS1	0xd0000
+#define	  SPI_MR_PSC_CS2	0xb0000
+#define	  SPI_MR_PSC_CS3	0x70000
+#define SPI_RDR		0x08		/* RDR: Receive Data Register */
+#define SPI_TDR		0x0c		/* TDR: Transmit Data Register */
+#define SPI_SR		0x10		/* SR: Status Register */
+#define	  SPI_SR_RDRF		0x00001
+#define	  SPI_SR_TDRE		0x00002
+#define	  SPI_SR_MODF		0x00004
+#define	  SPI_SR_OVRES		0x00008
+#define	  SPI_SR_ENDRX		0x00010
+#define	  SPI_SR_ENDTX		0x00020
+#define	  SPI_SR_RXBUFF		0x00040
+#define	  SPI_SR_TXBUFE		0x00080
+#define	  SPI_SR_NSSR		0x00100
+#define	  SPI_SR_TXEMPTY	0x00200
+#define	  SPI_SR_SPIENS		0x10000
+#define	SPI_IER		0x14		/* IER: Interrupt Enable Regsiter */
+#define	SPI_IDR		0x18		/* IDR: Interrupt Disable Regsiter */
+#define	SPI_IMR		0x1c		/* IMR: Interrupt Mask Regsiter */
+#define SPI_CSR0	0x30		/* CS0: Chip Select 0 */
+#define   SPI_CSR_CPOL		0x01
+#define SPI_CSR1	0x34		/* CS1: Chip Select 1 */
+#define SPI_CSR2	0x38		/* CS2: Chip Select 2 */
+#define SPI_CSR3	0x3c		/* CS3: Chip Select 3 */
+
+#endif /* ARM_AT91_AT91_SPIREG_H */


Property changes on: trunk/sys/arm/at91/at91_spireg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91_ssc.c
===================================================================
--- trunk/sys/arm/at91/at91_ssc.c	                        (rev 0)
+++ trunk/sys/arm/at91/at91_ssc.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,271 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2006 M. Warner Losh.  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 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 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: stable/10/sys/arm/at91/at91_ssc.c 236989 2012-06-13 04:52:19Z imp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/rman.h>
+#include <machine/bus.h>
+
+#include <arm/at91/at91_sscreg.h>
+
+struct at91_ssc_softc
+{
+	device_t dev;			/* Myself */
+	void *intrhand;			/* Interrupt handle */
+	struct resource *irq_res;	/* IRQ resource */
+	struct resource	*mem_res;	/* Memory resource */
+	struct mtx sc_mtx;		/* basically a perimeter lock */
+	struct cdev *cdev;
+	int flags;
+#define OPENED 1
+};
+
+static inline uint32_t
+RD4(struct at91_ssc_softc *sc, bus_size_t off)
+{
+	return bus_read_4(sc->mem_res, off);
+}
+
+static inline void
+WR4(struct at91_ssc_softc *sc, bus_size_t off, uint32_t val)
+{
+	bus_write_4(sc->mem_res, off, val);
+}
+
+#define AT91_SSC_LOCK(_sc)		mtx_lock(&(_sc)->sc_mtx)
+#define	AT91_SSC_UNLOCK(_sc)		mtx_unlock(&(_sc)->sc_mtx)
+#define AT91_SSC_LOCK_INIT(_sc) \
+	mtx_init(&(_sc)->sc_mtx, device_get_nameunit((_sc)->dev), \
+	    "ssc", MTX_DEF)
+#define AT91_SSC_LOCK_DESTROY(_sc)	mtx_destroy(&(_sc)->sc_mtx);
+#define AT91_SSC_ASSERT_LOCKED(_sc)	mtx_assert(&(_sc)->sc_mtx, MA_OWNED);
+#define AT91_SSC_ASSERT_UNLOCKED(_sc) mtx_assert(&(_sc)->sc_mtx, MA_NOTOWNED);
+#define CDEV2SOFTC(dev)		((dev)->si_drv1)
+
+static devclass_t at91_ssc_devclass;
+
+/* bus entry points */
+
+static int at91_ssc_probe(device_t dev);
+static int at91_ssc_attach(device_t dev);
+static int at91_ssc_detach(device_t dev);
+static void at91_ssc_intr(void *);
+
+/* helper routines */
+static int at91_ssc_activate(device_t dev);
+static void at91_ssc_deactivate(device_t dev);
+
+/* cdev routines */
+static d_open_t at91_ssc_open;
+static d_close_t at91_ssc_close;
+static d_read_t at91_ssc_read;
+static d_write_t at91_ssc_write;
+
+static struct cdevsw at91_ssc_cdevsw =
+{
+	.d_version = D_VERSION,
+	.d_open = at91_ssc_open,
+	.d_close = at91_ssc_close,
+	.d_read = at91_ssc_read,
+	.d_write = at91_ssc_write,
+};
+
+static int
+at91_ssc_probe(device_t dev)
+{
+	device_set_desc(dev, "SSC");
+	return (0);
+}
+
+static int
+at91_ssc_attach(device_t dev)
+{
+	struct at91_ssc_softc *sc = device_get_softc(dev);
+	int err;
+
+	sc->dev = dev;
+	err = at91_ssc_activate(dev);
+	if (err)
+		goto out;
+
+	AT91_SSC_LOCK_INIT(sc);
+
+	/*
+	 * Activate the interrupt
+	 */
+	err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
+	    NULL, at91_ssc_intr, sc, &sc->intrhand);
+	if (err) {
+		AT91_SSC_LOCK_DESTROY(sc);
+		goto out;
+	}
+	sc->cdev = make_dev(&at91_ssc_cdevsw, device_get_unit(dev), UID_ROOT,
+	    GID_WHEEL, 0600, "ssc%d", device_get_unit(dev));
+	if (sc->cdev == NULL) {
+		err = ENOMEM;
+		goto out;
+	}
+	sc->cdev->si_drv1 = sc;
+
+	// Init for TSC needs
+	WR4(sc, SSC_CR, SSC_CR_SWRST);
+	WR4(sc, SSC_CMR, 0);		// clock divider unused
+	WR4(sc, SSC_RCMR,
+	    SSC_RCMR_CKS_RK | SSC_RCMR_CKO_NONE | SSC_RCMR_START_FALL_EDGE_RF);
+	WR4(sc, SSC_RFMR,
+	    0x1f | SSC_RFMR_MSFBF | SSC_RFMR_FSOS_NONE);
+	WR4(sc, SSC_TCMR,
+	    SSC_TCMR_CKS_TK | SSC_TCMR_CKO_NONE |  SSC_RCMR_START_CONT);
+	WR4(sc, SSC_TFMR,
+	    0x1f | SSC_TFMR_DATDEF | SSC_TFMR_MSFBF | SSC_TFMR_FSOS_NEG_PULSE);
+
+out:
+	if (err)
+		at91_ssc_deactivate(dev);
+	return (err);
+}
+
+static int
+at91_ssc_detach(device_t dev)
+{
+	return (EBUSY);	/* XXX */
+}
+
+static int
+at91_ssc_activate(device_t dev)
+{
+	struct at91_ssc_softc *sc;
+	int rid;
+
+	sc = device_get_softc(dev);
+	rid = 0;
+	sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	    RF_ACTIVE);
+	if (sc->mem_res == NULL)
+		goto errout;
+	rid = 0;
+	sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+	    RF_ACTIVE);
+	if (sc->irq_res == NULL)
+		goto errout;
+	return (0);
+errout:
+	at91_ssc_deactivate(dev);
+	return (ENOMEM);
+}
+
+static void
+at91_ssc_deactivate(device_t dev)
+{
+	struct at91_ssc_softc *sc;
+
+	sc = device_get_softc(dev);
+	if (sc->intrhand)
+		bus_teardown_intr(dev, sc->irq_res, sc->intrhand);
+	sc->intrhand = 0;
+	bus_generic_detach(sc->dev);
+	if (sc->mem_res)
+		bus_release_resource(dev, SYS_RES_IOPORT,
+		    rman_get_rid(sc->mem_res), sc->mem_res);
+	sc->mem_res = 0;
+	if (sc->irq_res)
+		bus_release_resource(dev, SYS_RES_IRQ,
+		    rman_get_rid(sc->irq_res), sc->irq_res);
+	sc->irq_res = 0;
+	return;
+}
+
+static void
+at91_ssc_intr(void *xsc)
+{
+	struct at91_ssc_softc *sc = xsc;
+	wakeup(sc);
+	return;
+}
+
+static int
+at91_ssc_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
+{
+	struct at91_ssc_softc *sc;
+
+	sc = CDEV2SOFTC(dev);
+	AT91_SSC_LOCK(sc);
+	if (!(sc->flags & OPENED)) {
+		sc->flags |= OPENED;
+	}
+	AT91_SSC_UNLOCK(sc);
+    	return (0);
+}
+
+static int
+at91_ssc_close(struct cdev *dev, int fflag, int devtype, struct thread *td)
+{
+	struct at91_ssc_softc *sc;
+
+	sc = CDEV2SOFTC(dev);
+	AT91_SSC_LOCK(sc);
+	sc->flags &= ~OPENED;
+	AT91_SSC_UNLOCK(sc);
+	return (0);
+}
+
+static int
+at91_ssc_read(struct cdev *dev, struct uio *uio, int flag)
+{
+	return EIO;
+}
+
+static int
+at91_ssc_write(struct cdev *dev, struct uio *uio, int flag)
+{
+	return EIO;
+}
+
+static device_method_t at91_ssc_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		at91_ssc_probe),
+	DEVMETHOD(device_attach,	at91_ssc_attach),
+	DEVMETHOD(device_detach,	at91_ssc_detach),
+
+	{ 0, 0 }
+};
+
+static driver_t at91_ssc_driver = {
+	"at91_ssc",
+	at91_ssc_methods,
+	sizeof(struct at91_ssc_softc),
+};
+
+DRIVER_MODULE(at91_ssc, atmelarm, at91_ssc_driver, at91_ssc_devclass, 0, 0);


Property changes on: trunk/sys/arm/at91/at91_ssc.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91_sscreg.h
===================================================================
--- trunk/sys/arm/at91/at91_sscreg.h	                        (rev 0)
+++ trunk/sys/arm/at91/at91_sscreg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,151 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2006 M. Warner Losh.  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 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 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: stable/10/sys/arm/at91/at91_sscreg.h 185265 2008-11-25 00:13:26Z imp $ */
+
+#ifndef ARM_AT91_AT91_SSCREG_H
+#define ARM_AT91_AT91_SSCREG_H
+
+/* Registers */
+#define	SSC_CR		0x00		/* Control Register */
+#define	SSC_CMR		0x04		/* Clock Mode Register */
+		/*	0x08		Reserved */
+		/*	0x0c		Reserved */
+#define	SSC_RCMR	0x10		/* Receive Clock Mode Register */
+#define	SSC_RFMR	0x14		/* Receive Frame Mode Register */
+#define	SSC_TCMR	0x18		/* Transmit Clock Mode Register */
+#define	SSC_TFMR	0x1c		/* Transmit Frame Mode register */
+#define	SSC_RHR		0x20		/* Receive Holding Register */
+#define	SSC_THR		0x24		/* Transmit Holding Register */
+		/*	0x28		Reserved */
+		/*	0x2c		Reserved */
+#define	SSC_RSHR	0x30		/* Receive Sync Holding Register */
+#define	SSC_TSHR	0x34		/* Transmit Sync Holding Register */
+		/*	0x38		Reserved */
+		/*	0x3c		Reserved */
+#define	SSC_SR		0x40		/* Status Register */
+#define	SSC_IER		0x44		/* Interrupt Enable Register */
+#define	SSC_IDR		0x48		/* Interrupt Disable Register */
+#define	SSC_IMR		0x4c		/* Interrupt Mask Register */
+/* And PDC registers */
+
+/* SSC_CR */
+#define	SSC_CR_RXEN	(1u << 0)	/* RXEN: Receive Enable */
+#define	SSC_CR_RXDIS	(1u << 1)	/* RXDIS: Receive Disable */
+#define	SSC_CR_TXEN	(1u << 8)	/* TXEN: Transmit Enable */
+#define	SSC_CR_TXDIS	(1u << 9)	/* TXDIS: Transmit Disable */
+#define	SSC_CR_SWRST	(1u << 15)	/* SWRST: Software Reset */
+
+/* SSC_CMR */
+#define	SSC_CMR_DIV	0xfffu		/* DIV: Clock Divider mask */
+
+/* SSC_RCMR */
+#define	SSC_RCMR_PERIOD	(0xffu << 24)	/* PERIOD: Receive Period Divider sel*/
+#define	SSC_RCMR_STTDLY	(0xffu << 16)	/* STTDLY: Receive Start Delay */
+#define	SSC_RCMR_START	(0xfu << 8)	/* START: Receive Start Sel */
+#define		SSC_RCMR_START_CONT		(0u << 8)
+#define		SSC_RCMR_START_TX_START		(1u << 8)
+#define		SSC_RCMR_START_LOW_RF		(2u << 8)
+#define		SSC_RCMR_START_HIGH_RF		(3u << 8)
+#define		SSC_RCMR_START_FALL_EDGE_RF	(4u << 8)
+#define		SSC_RCMR_START_RISE_EDGE_RF	(5u << 8)
+#define		SSC_RCMR_START_LEVEL_CHANGE_RF	(6u << 8)
+#define		SSC_RCMR_START_ANY_EDGE_RF	(7u << 8)
+#define	SSC_RCMR_CKI	(1u << 5)	/* CKI: Receive Clock Inversion */
+#define	SSC_RCMR_CKO	(7u << 2)	/* CKO: Receive Clock Output Mode Sel*/
+#define		SSC_RCMR_CKO_NONE		(0u << 2)
+#define		SSC_RCMR_CKO_CONTINUOUS		(1u << 2)
+#define	SSC_RCMR_CKS	(3u)	       	/* CKS: Receive Clock Selection */
+#define		SSC_RCMR_CKS_DIVIDED		(0)
+#define		SSC_RCMR_CKS_TK_CLOCK		(1)
+#define		SSC_RCMR_CKS_RK			(2)
+
+/* SSC_RFMR */
+#define	SSC_RFMR_FSEDGE	(1u << 24)	/* FSEDGE: Frame Sync Edge Detection */
+#define	SSC_RFMR_FSOS	(7u << 20)	/* FSOS: Receive frame Sync Out sel */
+#define		SSC_RFMR_FSOS_NONE		(0u << 20)
+#define		SSC_RFMR_FSOS_NEG_PULSE		(1u << 20)
+#define		SSC_RFMR_FSOS_POS_PULSE		(2u << 20)
+#define		SSC_RFMR_FSOS_LOW		(3u << 20)
+#define		SSC_RFMR_FSOS_HIGH		(4u << 20)
+#define		SSC_RFMR_FSOS_TOGGLE		(5u << 20)
+#define	SSC_RFMR_FSLEN	(0xfu << 16)	/* FSLEN: Receive Frame Sync Length */
+#define	SSC_RFMR_DATNB	(0xfu << 8)	/* DATNB: Data Number per Frame */
+#define	SSC_RFMR_MSFBF	(1u << 7)	/* MSBF: Most Significant Bit First */
+#define	SSC_RFMR_LOOP	(1u << 5)	/* LOOP: Loop Mode */
+#define	SSC_RFMR_DATLEN	(0x1fu << 0)	/* DATLEN: Data Length */
+
+/* SSC_TCMR */
+#define	SSC_TCMR_PERIOD	(0xffu << 24)	/* PERIOD: Receive Period Divider sel*/
+#define	SSC_TCMR_STTDLY	(0xffu << 16)	/* STTDLY: Receive Start Delay */
+#define	SSC_TCMR_START	(0xfu << 8)	/* START: Receive Start Sel */
+#define		SSC_TCMR_START_CONT		(0u << 8)
+#define		SSC_TCMR_START_RX_START		(1u << 8)
+#define		SSC_TCMR_START_LOW_RF		(2u << 8)
+#define		SSC_TCMR_START_HIGH_RF		(3u << 8)
+#define		SSC_TCMR_START_FALL_EDGE_RF	(4u << 8)
+#define		SSC_TCMR_START_RISE_EDGE_RF	(5u << 8)
+#define		SSC_TCMR_START_LEVEL_CHANGE_RF	(6u << 8)
+#define		SSC_TCMR_START_ANY_EDGE_RF	(7u << 8)
+#define	SSC_TCMR_CKI	(1u << 5)	/* CKI: Receive Clock Inversion */
+#define	SSC_TCMR_CKO	(7u << 2)	/* CKO: Receive Clock Output Mode Sel*/
+#define		SSC_TCMR_CKO_NONE		(0u << 2)
+#define		SSC_TCMR_CKO_CONTINUOUS		(1u << 2)
+#define	SSC_TCMR_CKS	(3u)	       	/* CKS: Receive Clock Selection */
+#define		SSC_TCMR_CKS_DIVIDED		(0)
+#define		SSC_TCMR_CKS_RK_CLOCK		(1)
+#define		SSC_TCMR_CKS_TK			(2)
+
+/* SSC_TFMR */
+#define	SSC_TFMR_FSEDGE	(1u << 24)	/* FSEDGE: Frame Sync Edge Detection */
+#define	SSC_TFMR_FSOS	(7u << 20)	/* FSOS: Receive frame Sync Out sel */
+#define		SSC_TFMR_FSOS_NONE		(0u << 20)
+#define		SSC_TFMR_FSOS_NEG_PULSE		(1u << 20)
+#define		SSC_TFMR_FSOS_POS_PULSE		(2u << 20)
+#define		SSC_TFMR_FSOS_LOW		(3u << 20)
+#define		SSC_TFMR_FSOS_HIGH		(4u << 20)
+#define		SSC_TFMR_FSOS_TOGGLE		(5u << 20)
+#define	SSC_TFMR_FSLEN	(0xfu << 16)	/* FSLEN: Receive Frame Sync Length */
+#define	SSC_TFMR_DATNB	(0xfu << 8)	/* DATNB: Data Number per Frame */
+#define	SSC_TFMR_MSFBF	(1u << 7)	/* MSBF: Most Significant Bit First */
+#define	SSC_TFMR_DATDEF	(1u << 5)	/* DATDEF: Data Default Value */
+#define	SSC_TFMR_DATLEN	(0x1fu << 0)	/* DATLEN: Data Length */
+
+/* SSC_SR */
+#define	SSC_SR_TXRDY	(1u << 0)
+#define	SSC_SR_TXEMPTY	(1u << 1)
+#define	SSC_SR_ENDTX	(1u << 2)
+#define	SSC_SR_TXBUFE	(1u << 3)
+#define	SSC_SR_RXRDY	(1u << 4)
+#define	SSC_SR_OVRUN	(1u << 5)
+#define	SSC_SR_ENDRX	(1u << 6)
+#define	SSC_SR_RXBUFF	(1u << 7)
+#define	SSC_SR_TXSYN	(1u << 10)
+#define	SSC_SR_RSSYN	(1u << 11)
+#define	SSC_SR_TXEN	(1u << 16)
+#define	SSC_SR_RXEN	(1u << 17)
+
+#endif /* ARM_AT91_AT91_SSCREG_H */


Property changes on: trunk/sys/arm/at91/at91_sscreg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91_st.c
===================================================================
--- trunk/sys/arm/at91/at91_st.c	                        (rev 0)
+++ trunk/sys/arm/at91/at91_st.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,314 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2005 Olivier Houchard.  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 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 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: stable/10/sys/arm/at91/at91_st.c 238376 2012-07-11 20:17:14Z imp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/time.h>
+#include <sys/bus.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+#include <sys/timetc.h>
+#include <sys/watchdog.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+#include <machine/resource.h>
+#include <machine/frame.h>
+#include <machine/intr.h>
+#include <arm/at91/at91var.h>
+#include <arm/at91/at91_streg.h>
+#include <arm/at91/at91rm92reg.h>
+
+static struct at91_st_softc {
+	struct resource *	sc_irq_res;
+	struct resource	*	sc_mem_res;
+	void *			sc_intrhand;
+	eventhandler_tag	sc_wet;	/* watchdog event handler tag */
+} *timer_softc;
+
+static inline uint32_t
+RD4(bus_size_t off)
+{
+
+	if (timer_softc == NULL) {
+		uint32_t *p = (uint32_t *)(AT91_BASE + AT91RM92_ST_BASE + off);
+
+		return *p;
+	}
+
+	return (bus_read_4(timer_softc->sc_mem_res, off));
+}
+
+static inline void
+WR4(bus_size_t off, uint32_t val)
+{
+
+	if (timer_softc == NULL) {
+		uint32_t *p = (uint32_t *)(AT91_BASE + AT91RM92_ST_BASE + off);
+
+		*p = val;
+	}
+	else
+		bus_write_4(timer_softc->sc_mem_res, off, val);
+}
+
+static void at91_st_watchdog(void *, u_int, int *);
+static void at91_st_initclocks(device_t , struct at91_st_softc *);
+
+static inline int
+st_crtr(void)
+{
+	int cur1, cur2;
+	do {
+		cur1 = RD4(ST_CRTR);
+		cur2 = RD4(ST_CRTR);
+	} while (cur1 != cur2);
+	return (cur1);
+}
+
+static unsigned at91_st_get_timecount(struct timecounter *tc);
+
+static struct timecounter at91_st_timecounter = {
+	at91_st_get_timecount, /* get_timecount */
+	NULL, /* no poll_pps */
+	0xfffffu, /* counter_mask */
+	32768, /* frequency */
+	"AT91RM9200 timer", /* name */
+	1000 /* quality */
+};
+
+static int
+clock_intr(void *arg)
+{
+	struct trapframe *fp = arg;
+
+	/* The interrupt is shared, so we have to make sure it's for us. */
+	if (RD4(ST_SR) & ST_SR_PITS) {
+		hardclock(TRAPF_USERMODE(fp), TRAPF_PC(fp));
+		return (FILTER_HANDLED);
+	}
+	return (FILTER_STRAY);
+}
+
+void
+at91_st_delay(int n)
+{
+	uint32_t start, end, cur;
+
+	start = st_crtr();
+	n = (n * 1000) / 32768;
+	if (n <= 0)
+		n = 1;
+	end = (start + n) & ST_CRTR_MASK;
+	cur = start;
+	if (start > end) {
+		while (cur >= start || cur < end)
+			cur = st_crtr();
+	} else {
+		while (cur < end)
+			cur = st_crtr();
+	}
+}
+
+void
+at91_st_cpu_reset(void)
+{
+	/*
+	 * Reset the CPU by programmig the watchdog timer to reset the
+	 * CPU after 128 'slow' clocks, or about ~4ms.  Loop until
+	 * the reset happens for safety.
+	 */
+	WR4(ST_WDMR, ST_WDMR_RSTEN | 2);
+	WR4(ST_CR, ST_CR_WDRST);
+	while (1)
+		continue;
+}
+
+static int
+at91_st_probe(device_t dev)
+{
+
+	device_set_desc(dev, "ST");
+	return (0);
+}
+
+static void
+at91_st_deactivate(device_t dev)
+{
+	struct at91_st_softc *sc = timer_softc;
+
+	if (sc->sc_intrhand)
+		bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_intrhand);
+	sc->sc_intrhand = NULL;
+
+	if (sc->sc_irq_res)
+		bus_release_resource(dev, SYS_RES_IRQ,
+		    rman_get_rid(sc->sc_irq_res), sc->sc_irq_res);
+	sc->sc_irq_res = NULL;
+
+	if (sc->sc_mem_res)
+		bus_release_resource(dev, SYS_RES_MEMORY,
+		    rman_get_rid(sc->sc_mem_res), sc->sc_mem_res);
+	sc->sc_mem_res = NULL;
+}
+
+static int
+at91_st_activate(device_t dev)
+{
+	int rid;
+	int err;
+	struct at91_st_softc *sc = timer_softc;
+
+	rid = 0;
+	sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	    RF_ACTIVE);
+	err = ENOMEM;
+	if (sc->sc_mem_res == NULL)
+		goto out;
+	/* Disable all interrupts */
+	WR4(ST_IDR, 0xffffffff);
+
+	/* The system timer shares the system irq (1) */
+	rid = 0;
+	sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+	    RF_ACTIVE | RF_SHAREABLE);
+	if (sc->sc_irq_res == NULL) {
+		printf("Unable to allocate irq for the system timer");
+		goto out;
+	}
+	err = bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_CLK, clock_intr,
+	    NULL, NULL, &sc->sc_intrhand);
+out:
+	if (err != 0)
+		at91_st_deactivate(dev);
+	return (err);
+}
+
+static int
+at91_st_attach(device_t dev)
+{
+	int err;
+
+	timer_softc = device_get_softc(dev);
+	err = at91_st_activate(dev);
+	if (err)
+		return err;
+
+	timer_softc->sc_wet = EVENTHANDLER_REGISTER(watchdog_list,
+	  at91_st_watchdog, dev, 0);
+
+	device_printf(dev,
+	  "watchdog registered, timeout intervall max. 64 sec\n");
+
+	at91_st_initclocks(dev, timer_softc);
+	return (0);
+}
+
+static device_method_t at91_st_methods[] = {
+	DEVMETHOD(device_probe, at91_st_probe),
+	DEVMETHOD(device_attach, at91_st_attach),
+	{0, 0},
+};
+
+static driver_t at91_st_driver = {
+	"at91_st",
+	at91_st_methods,
+	sizeof(struct at91_st_softc),
+};
+static devclass_t at91_st_devclass;
+
+DRIVER_MODULE(at91_st, atmelarm, at91_st_driver, at91_st_devclass, 0, 0);
+
+static unsigned
+at91_st_get_timecount(struct timecounter *tc)
+{
+	return (st_crtr());
+}
+
+/*
+ * t below is in a weird unit.  The watchdog is set to 2^t
+ * nanoseconds.  Since our watchdog timer can't really do that too
+ * well, we approximate it by assuming that the timeout interval for
+ * the lsb is 2^22 ns, which is 4.194ms.  This is an overestimation of
+ * the actual time (3.906ms), but close enough for watchdogging.
+ * These approximations, though a violation of the spec, improve the
+ * performance of the application which typically specifies things as
+ * WD_TO_32SEC.  In that last case, we'd wait 32s before the wdog
+ * reset.  The spec says we should wait closer to 34s, but given how
+ * it is likely to be used, and the extremely coarse nature time
+ * interval, I think this is the best solution.
+ */
+static void
+at91_st_watchdog(void *argp, u_int cmd, int *error)
+{
+	uint32_t wdog;
+	int t;
+
+	t = cmd & WD_INTERVAL;
+	if (t >= 22 && t <= 37) {
+		wdog = (1 << (t - 22)) | ST_WDMR_RSTEN;
+		*error = 0;
+	} else {
+		wdog = 0;
+	}
+	WR4(ST_WDMR, wdog);
+	WR4(ST_CR, ST_CR_WDRST);
+}
+
+static void
+at91_st_initclocks(device_t dev, struct at91_st_softc *sc)
+{
+	int rel_value;
+
+	/*
+	 * Real time counter increments every clock cycle, need to set before
+	 * initializing clocks so that DELAY works.
+	 */
+	WR4(ST_RTMR, 1);
+	/* disable watchdog timer */
+	WR4(ST_WDMR, 0);
+
+	rel_value = 32768 / hz;
+	if (rel_value < 1)
+		rel_value = 1;
+	if (32768 % hz) {
+		device_printf(dev, "Cannot get %d Hz clock; using %dHz\n", hz,
+		    32768 / rel_value);
+		hz = 32768 / rel_value;
+		tick = 1000000 / hz;
+	}
+	WR4(ST_PIMR, rel_value);
+
+	/* Enable PITS interrupts. */
+	WR4(ST_IER, ST_SR_PITS);
+	tc_init(&at91_st_timecounter);
+}


Property changes on: trunk/sys/arm/at91/at91_st.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91_streg.h
===================================================================
--- trunk/sys/arm/at91/at91_streg.h	                        (rev 0)
+++ trunk/sys/arm/at91/at91_streg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,62 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2005 M. Warner Losh.  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 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 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: stable/10/sys/arm/at91/at91_streg.h 238376 2012-07-11 20:17:14Z imp $ */
+
+#ifndef ARM_AT91_AT91STREG_H
+#define ARM_AT91_AT91STREG_H
+
+#define ST_CR		0x00 /* Control register */
+#define ST_PIMR		0x04 /* Period interval mode register */
+#define ST_WDMR		0x08 /* Watchdog mode register */
+#define ST_RTMR		0x0c /* Real-time mode register */
+#define ST_SR		0x10 /* Status register */
+#define ST_IER		0x14 /* Interrupt enable register */
+#define ST_IDR		0x18 /* Interrupt disable register */
+#define ST_IMR		0x1c /* Interrupt mask register */
+#define ST_RTAR		0x20 /* Real-time alarm register */
+#define	ST_CRTR		0x24 /* Current real-time register */
+
+/* ST_CR */
+#define ST_CR_WDRST	(1U << 0) /* WDRST: Watchdog Timer Restart */
+
+/* ST_WDMR */
+#define ST_WDMR_EXTEN	(1U << 17) /* EXTEN: External Signal Assert Enable */
+#define ST_WDMR_RSTEN	(1U << 16) /* RSTEN: Reset Enable */
+
+/* ST_SR, ST_IER, ST_IDR, ST_IMR */
+#define ST_SR_PITS	(1U << 0) /* PITS: Period Interval Timer Status */
+#define ST_SR_WDOVF	(1U << 1) /* WDOVF: Watchdog Overflow */
+#define ST_SR_RTTINC	(1U << 2) /* RTTINC: Real-time Timer Increment */
+#define ST_SR_ALMS	(1U << 3) /* ALMS: Alarm Status */
+
+/* ST_CRTR */
+#define ST_CRTR_MASK	0xfffff /* 20-bit counter */
+
+void at91_st_delay(int n);
+void at91_st_cpu_reset(void);
+
+#endif /* ARM_AT91_AT91STREG_H */


Property changes on: trunk/sys/arm/at91/at91_streg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91_tcb.c
===================================================================
--- trunk/sys/arm/at91/at91_tcb.c	                        (rev 0)
+++ trunk/sys/arm/at91/at91_tcb.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,106 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014 Warner Losh.  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 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 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: stable/10/sys/arm/at91/at91_tcb.c 266217 2014-05-16 12:43:45Z ian $");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/resource.h>
+#include <sys/systm.h>
+#include <sys/rman.h>
+
+#include <machine/bus.h>
+
+#include <arm/at91/at91var.h>
+#include <arm/at91/at91_aicreg.h>
+
+#ifdef FDT
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+#endif
+
+struct tcb_softc {
+	struct resource	*mem_res;	/* Memory resource */
+	device_t	sc_dev;
+};
+
+static int
+at91_tcb_probe(device_t dev)
+{
+#ifdef FDT
+	if (!ofw_bus_is_compatible(dev, "atmel,at91rm9200-tcb"))
+		return (ENXIO);
+#endif
+	device_set_desc(dev, "TCB");
+        return (0);
+}
+
+static int
+at91_tcb_attach(device_t dev)
+{
+	int rid, err = 0;
+	struct tcb_softc *sc;
+
+	sc = device_get_softc(dev);
+	sc->sc_dev = dev;
+
+	rid = 0;
+	sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	    RF_ACTIVE);
+
+	if (sc->mem_res == NULL)
+		panic("couldn't allocate register resources");
+
+	return (err);
+}
+
+static device_method_t at91_tcb_methods[] = {
+	DEVMETHOD(device_probe, at91_tcb_probe),
+	DEVMETHOD(device_attach, at91_tcb_attach),
+	DEVMETHOD_END
+};
+
+static driver_t at91_tcb_driver = {
+	"at91_tcb",
+	at91_tcb_methods,
+	sizeof(struct tcb_softc),
+};
+
+static devclass_t at91_tcb_devclass;
+
+#ifdef FDT
+DRIVER_MODULE(at91_tcb, simplebus, at91_tcb_driver, at91_tcb_devclass, NULL,
+    NULL);
+#else
+DRIVER_MODULE(at91_tcb, atmelarm, at91_tcb_driver, at91_tcb_devclass, NULL,
+    NULL);
+#endif


Property changes on: trunk/sys/arm/at91/at91_tcb.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91_twi.c
===================================================================
--- trunk/sys/arm/at91/at91_twi.c	                        (rev 0)
+++ trunk/sys/arm/at91/at91_twi.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,430 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2006 M. Warner Losh.  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 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 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: stable/10/sys/arm/at91/at91_twi.c 266196 2014-05-15 21:21:47Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/mbuf.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/rman.h>
+#include <machine/bus.h>
+
+#include <arm/at91/at91_twireg.h>
+#include <arm/at91/at91var.h>
+
+#include <dev/iicbus/iiconf.h>
+#include <dev/iicbus/iicbus.h>
+#include "iicbus_if.h"
+
+#ifdef FDT
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+#endif
+
+#define	TWI_SLOW_CLOCK		 1500
+#define	TWI_FAST_CLOCK		45000
+#define	TWI_FASTEST_CLOCK	90000
+
+struct at91_twi_softc
+{
+	device_t dev;			/* Myself */
+	void *intrhand;			/* Interrupt handle */
+	struct resource *irq_res;	/* IRQ resource */
+	struct resource	*mem_res;	/* Memory resource */
+	struct mtx sc_mtx;		/* basically a perimeter lock */
+	volatile uint32_t flags;
+	uint32_t cwgr;
+	int	sc_started;
+	int	twi_addr;
+	device_t iicbus;
+};
+
+static inline uint32_t
+RD4(struct at91_twi_softc *sc, bus_size_t off)
+{
+
+	return bus_read_4(sc->mem_res, off);
+}
+
+static inline void
+WR4(struct at91_twi_softc *sc, bus_size_t off, uint32_t val)
+{
+
+	bus_write_4(sc->mem_res, off, val);
+}
+
+#define	AT91_TWI_LOCK(_sc)		mtx_lock(&(_sc)->sc_mtx)
+#define	AT91_TWI_UNLOCK(_sc)		mtx_unlock(&(_sc)->sc_mtx)
+#define	AT91_TWI_LOCK_INIT(_sc) \
+	mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->dev), \
+	    "twi", MTX_DEF)
+#define	AT91_TWI_LOCK_DESTROY(_sc)	mtx_destroy(&_sc->sc_mtx);
+#define	AT91_TWI_ASSERT_LOCKED(_sc)	mtx_assert(&_sc->sc_mtx, MA_OWNED);
+#define	AT91_TWI_ASSERT_UNLOCKED(_sc)	mtx_assert(&_sc->sc_mtx, MA_NOTOWNED);
+#define	TWI_DEF_CLK	100000
+
+static devclass_t at91_twi_devclass;
+
+/* bus entry points */
+
+static int at91_twi_probe(device_t dev);
+static int at91_twi_attach(device_t dev);
+static int at91_twi_detach(device_t dev);
+static void at91_twi_intr(void *);
+
+/* helper routines */
+static int at91_twi_activate(device_t dev);
+static void at91_twi_deactivate(device_t dev);
+
+static int
+at91_twi_probe(device_t dev)
+{
+#ifdef FDT
+	/* XXXX need a whole list, since there's at least 4 different ones */
+	if (!ofw_bus_is_compatible(dev, "atmel,at91sam9g20-i2c"))
+		return (ENXIO);
+#endif
+	device_set_desc(dev, "TWI");
+	return (0);
+}
+
+static int
+at91_twi_attach(device_t dev)
+{
+	struct at91_twi_softc *sc = device_get_softc(dev);
+	int err;
+
+	sc->dev = dev;
+	err = at91_twi_activate(dev);
+	if (err)
+		goto out;
+
+	AT91_TWI_LOCK_INIT(sc);
+
+#ifdef FDT
+	/*
+	 * Disable devices need to hold their resources, so return now and not attach
+	 * the iicbus, setup interrupt handlers, etc.
+	 */
+	if (!ofw_bus_status_okay(dev))
+		return 0;
+#endif
+
+	/*
+	 * Activate the interrupt
+	 */
+	err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
+	    NULL, at91_twi_intr, sc, &sc->intrhand);
+	if (err) {
+		AT91_TWI_LOCK_DESTROY(sc);
+		goto out;
+	}
+	sc->cwgr = TWI_CWGR_CKDIV(8 * at91_master_clock / TWI_FASTEST_CLOCK) |
+	    TWI_CWGR_CHDIV(TWI_CWGR_DIV(TWI_DEF_CLK)) |
+	    TWI_CWGR_CLDIV(TWI_CWGR_DIV(TWI_DEF_CLK));
+	WR4(sc, TWI_CR, TWI_CR_SWRST);
+	WR4(sc, TWI_CR, TWI_CR_MSEN | TWI_CR_SVDIS);
+	WR4(sc, TWI_CWGR, sc->cwgr);
+
+	if ((sc->iicbus = device_add_child(dev, "iicbus", -1)) == NULL)
+		device_printf(dev, "could not allocate iicbus instance\n");
+	/* probe and attach the iicbus */
+	bus_generic_attach(dev);
+out:
+	if (err)
+		at91_twi_deactivate(dev);
+	return (err);
+}
+
+static int
+at91_twi_detach(device_t dev)
+{
+	struct at91_twi_softc *sc;
+	int rv;
+
+	sc = device_get_softc(dev);
+	at91_twi_deactivate(dev);
+	if (sc->iicbus && (rv = device_delete_child(dev, sc->iicbus)) != 0)
+		return (rv);
+
+	AT91_TWI_LOCK_DESTROY(sc);
+
+	return (0);
+}
+
+static int
+at91_twi_activate(device_t dev)
+{
+	struct at91_twi_softc *sc;
+	int rid;
+
+	sc = device_get_softc(dev);
+	rid = 0;
+	sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	    RF_ACTIVE);
+	if (sc->mem_res == NULL)
+		goto errout;
+	rid = 0;
+	sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+	    RF_ACTIVE);
+	if (sc->irq_res == NULL)
+		goto errout;
+	return (0);
+errout:
+	at91_twi_deactivate(dev);
+	return (ENOMEM);
+}
+
+static void
+at91_twi_deactivate(device_t dev)
+{
+	struct at91_twi_softc *sc;
+
+	sc = device_get_softc(dev);
+	if (sc->intrhand)
+		bus_teardown_intr(dev, sc->irq_res, sc->intrhand);
+	sc->intrhand = 0;
+	bus_generic_detach(sc->dev);
+	if (sc->mem_res)
+		bus_release_resource(dev, SYS_RES_MEMORY,
+		    rman_get_rid(sc->mem_res), sc->mem_res);
+	sc->mem_res = 0;
+	if (sc->irq_res)
+		bus_release_resource(dev, SYS_RES_IRQ,
+		    rman_get_rid(sc->irq_res), sc->irq_res);
+	sc->irq_res = 0;
+	return;
+}
+
+static void
+at91_twi_intr(void *xsc)
+{
+	struct at91_twi_softc *sc = xsc;
+	uint32_t status;
+
+	status = RD4(sc, TWI_SR);
+	if (status == 0)
+		return;
+	AT91_TWI_LOCK(sc);
+	sc->flags |= status & (TWI_SR_OVRE | TWI_SR_UNRE | TWI_SR_NACK);
+	if (status & TWI_SR_RXRDY)
+		sc->flags |= TWI_SR_RXRDY;
+	if (status & TWI_SR_TXRDY)
+		sc->flags |= TWI_SR_TXRDY;
+	if (status & TWI_SR_TXCOMP)
+		sc->flags |= TWI_SR_TXCOMP;
+	WR4(sc, TWI_IDR, status);
+	wakeup(sc);
+	AT91_TWI_UNLOCK(sc);
+	return;
+}
+
+static int
+at91_twi_wait(struct at91_twi_softc *sc, uint32_t bit)
+{
+	int err = 0;
+	int counter = 100000;
+	uint32_t sr;
+
+	AT91_TWI_ASSERT_LOCKED(sc);
+	while (!((sr = RD4(sc, TWI_SR)) & bit) && counter-- > 0 &&
+	    !(sr & TWI_SR_NACK))
+		continue;
+	if (counter <= 0)
+		err = EBUSY;
+	else if (sr & TWI_SR_NACK)
+		err = ENXIO;		// iic nack convention
+	return (err);
+}
+
+static int
+at91_twi_rst_card(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
+{
+	struct at91_twi_softc *sc;
+	int clk;
+
+	sc = device_get_softc(dev);
+	AT91_TWI_LOCK(sc);
+	if (oldaddr)
+		*oldaddr = sc->twi_addr;
+	sc->twi_addr = addr;
+
+	/*
+	 * speeds are for 1.5kb/s, 45kb/s and 90kb/s.
+	 */
+	switch (speed) {
+	case IIC_SLOW:
+		clk = TWI_SLOW_CLOCK;
+		break;
+
+	case IIC_FAST:
+		clk = TWI_FAST_CLOCK;
+		break;
+
+	case IIC_UNKNOWN:
+	case IIC_FASTEST:
+	default:
+		clk = TWI_FASTEST_CLOCK;
+		break;
+	}
+	sc->cwgr = TWI_CWGR_CKDIV(1) | TWI_CWGR_CHDIV(TWI_CWGR_DIV(clk)) |
+	    TWI_CWGR_CLDIV(TWI_CWGR_DIV(clk));
+	WR4(sc, TWI_CR, TWI_CR_SWRST);
+	WR4(sc, TWI_CR, TWI_CR_MSEN | TWI_CR_SVDIS);
+	WR4(sc, TWI_CWGR, sc->cwgr);
+	AT91_TWI_UNLOCK(sc);
+
+	return 0;
+}
+
+static int
+at91_twi_callback(device_t dev, int index, caddr_t data)
+{
+	int error = 0;
+
+	switch (index) {
+	case IIC_REQUEST_BUS:
+		break;
+
+	case IIC_RELEASE_BUS:
+		break;
+
+	default:
+		error = EINVAL;
+	}
+
+	return (error);
+}
+
+static int
+at91_twi_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
+{
+	struct at91_twi_softc *sc;
+	int i, len, err;
+	uint32_t rdwr;
+	uint8_t *buf;
+	uint32_t sr;
+
+	sc = device_get_softc(dev);
+	err = 0;
+	AT91_TWI_LOCK(sc);
+	for (i = 0; i < nmsgs; i++) {
+		/*
+		 * The linux atmel driver doesn't use the internal device
+		 * address feature of twi.  A separate i2c message needs to
+		 * be written to use this.
+		 * See http://lists.arm.linux.org.uk/pipermail/linux-arm-kernel/2004-September/024411.html
+		 * for details.  Upon reflection, we could use this as an
+		 * optimization, but it is unclear the code bloat will
+		 * result in faster/better operations.
+		 */
+		rdwr = (msgs[i].flags & IIC_M_RD) ? TWI_MMR_MREAD : 0;
+		WR4(sc, TWI_MMR, TWI_MMR_DADR(msgs[i].slave) | rdwr);
+		len = msgs[i].len;
+		buf = msgs[i].buf;
+		/* zero byte transfers aren't allowed */
+		if (len == 0 || buf == NULL) {
+			err = EINVAL;
+			goto out;
+		}
+		if (len == 1 && msgs[i].flags & IIC_M_RD)
+			WR4(sc, TWI_CR, TWI_CR_START | TWI_CR_STOP);
+		else
+			WR4(sc, TWI_CR, TWI_CR_START);
+		if (msgs[i].flags & IIC_M_RD) {
+			sr = RD4(sc, TWI_SR);
+			while (!(sr & TWI_SR_TXCOMP)) {
+				if ((sr = RD4(sc, TWI_SR)) & TWI_SR_RXRDY) {
+					len--;
+					*buf++ = RD4(sc, TWI_RHR) & 0xff;
+					if (len == 1)
+						WR4(sc, TWI_CR, TWI_CR_STOP);
+				}
+			}
+			if (len > 0 || (sr & TWI_SR_NACK)) {
+				err = ENXIO;		// iic nack convention
+				goto out;
+			}
+		} else {
+			while (len--) {
+				if ((err = at91_twi_wait(sc, TWI_SR_TXRDY)))
+					goto out;
+				WR4(sc, TWI_THR, *buf++);
+			}
+			WR4(sc, TWI_CR, TWI_CR_STOP);
+		}
+		if ((err = at91_twi_wait(sc, TWI_SR_TXCOMP)))
+			break;
+	}
+out:
+	if (err) {
+		WR4(sc, TWI_CR, TWI_CR_SWRST);
+		WR4(sc, TWI_CR, TWI_CR_MSEN | TWI_CR_SVDIS);
+		WR4(sc, TWI_CWGR, sc->cwgr);
+	}
+	AT91_TWI_UNLOCK(sc);
+	return (err);
+}
+
+static device_method_t at91_twi_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		at91_twi_probe),
+	DEVMETHOD(device_attach,	at91_twi_attach),
+	DEVMETHOD(device_detach,	at91_twi_detach),
+
+	/* iicbus interface */
+	DEVMETHOD(iicbus_callback,	at91_twi_callback),
+	DEVMETHOD(iicbus_reset,		at91_twi_rst_card),
+	DEVMETHOD(iicbus_transfer,	at91_twi_transfer),
+	DEVMETHOD_END
+};
+
+static driver_t at91_twi_driver = {
+	"at91_twi",
+	at91_twi_methods,
+	sizeof(struct at91_twi_softc),
+};
+
+#ifdef FDT
+DRIVER_MODULE(at91_twi, simplebus, at91_twi_driver, at91_twi_devclass, NULL,
+    NULL);
+#else
+DRIVER_MODULE(at91_twi, atmelarm, at91_twi_driver, at91_twi_devclass, NULL,
+    NULL);
+#endif
+DRIVER_MODULE(iicbus, at91_twi, iicbus_driver, iicbus_devclass, NULL, NULL);
+MODULE_DEPEND(at91_twi, iicbus, 1, 1, 1);


Property changes on: trunk/sys/arm/at91/at91_twi.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91_twiio.h
===================================================================
--- trunk/sys/arm/at91/at91_twiio.h	                        (rev 0)
+++ trunk/sys/arm/at91/at91_twiio.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,63 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2006 M. Warner Losh.  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 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 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: stable/10/sys/arm/at91/at91_twiio.h 185265 2008-11-25 00:13:26Z imp $
+ */
+
+#ifndef _ARM_AT91_AT91_TWIIO_H
+#define _ARM_AT91_AT91_TWIIO_H
+
+#include <sys/ioccom.h>
+
+struct at91_twi_io
+{
+	int	dadr;			/* Device address */
+	int	type;			/* read/write */
+#define TWI_IO_READ_MASTER	1
+#define TWI_IO_WRITE_MASTER	2
+	int	iadrsz;			/* Internal addr size */
+	uint32_t iadr;			/* Interbak addr */
+	size_t  xfer_len;		/* Size to transfer */
+	caddr_t xfer_buf;		/* buffer for xfer */
+};
+
+struct at91_twi_clock
+{
+	int	ckdiv;			/* Clock divider */
+	int	high_rate;		/* rate of clock high period */
+	int	low_rate;		/* rate of clock low period */
+};
+
+/** TWIIOCXFER: Do a two-wire transfer
+ */
+#define TWIIOCXFER	_IOW('x', 1, struct at91_twi_io)
+
+/** TWIIOCSETCLOCK: Sets the clocking parameters for this operation.
+ */
+#define TWIIOCSETCLOCK _IOW('x', 2, struct at91_twi_clock)
+
+#endif /* !_ARM_AT91_AT91_TWIIO_H */
+
+


Property changes on: trunk/sys/arm/at91/at91_twiio.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91_twireg.h
===================================================================
--- trunk/sys/arm/at91/at91_twireg.h	                        (rev 0)
+++ trunk/sys/arm/at91/at91_twireg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,87 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2006 M. Warner Losh.  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 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 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: stable/10/sys/arm/at91/at91_twireg.h 234291 2012-04-14 17:09:38Z marius $ */
+
+#ifndef ARM_AT91_AT91_TWIREG_H
+#define	ARM_AT91_AT91_TWIREG_H
+
+#define	TWI_CR		0x00		/* TWI Control Register */
+#define	TWI_MMR		0x04		/* TWI Master Mode Register */
+#define	TWI_SMR		0x08		/* TWI Master Mode Register */
+#define	TWI_IADR	0x0c		/* TWI Internal Address Register */
+#define	TWI_CWGR	0x10		/* TWI Clock Waveform Generator Reg */
+		/*	0x14		   reserved */
+		/*	0x18		   reserved */
+		/*	0x1c		   reserved */
+#define	TWI_SR		0x20		/* TWI Status Register */
+#define	TWI_IER		0x24		/* TWI Interrupt Enable Register */
+#define	TWI_IDR		0x28		/* TWI Interrupt Disable Register */
+#define	TWI_IMR		0x2c		/* TWI Interrupt Mask Register */
+#define	TWI_RHR		0x30		/* TWI Receiver Holding Register */
+#define	TWI_THR		0x34		/* TWI Transmit Holding Register */
+
+/* TWI_CR */
+#define	TWI_CR_START	(1U << 0)	/* Send a start */
+#define	TWI_CR_STOP	(1U << 1)	/* Send a stop */
+#define	TWI_CR_MSEN	(1U << 2)	/* Master Transfer Enable */
+#define	TWI_CR_MSDIS	(1U << 3)	/* Master Transfer Disable */
+#define	TWI_CR_SVEN	(1U << 4)	/* Slave Transfer Enable */
+#define	TWI_CR_SVDIS	(1U << 5)	/* Slave Transfer Disable */
+#define	TWI_CR_SWRST	(1U << 7)	/* Software Reset */
+
+/* TWI_MMR */
+/* TWI_SMR */
+#define	TWI_MMR_IADRSZ(n) ((n) << 8)	/* Set size of transfer */
+#define	TWI_MMR_MWRITE	0U		/* Master Read Direction */
+#define	TWI_MMR_MREAD	(1U << 12)	/* Master Read Direction */
+#define	TWI_MMR_DADR(n)	((n) << 15)	/* Device Address */
+
+/* TWI_CWGR */
+#define	TWI_CWGR_CKDIV(x) ((x) << 16)	/* Clock Divider */
+#define	TWI_CWGR_CHDIV(x) ((x) << 8)	/* Clock High Divider */
+#define	TWI_CWGR_CLDIV(x) ((x) << 0)	/* Clock Low Divider */
+#define	TWI_CWGR_DIV(rate) 		 		\
+	(at91_is_sam9() || at91_is_sam9xe() ?		\
+	    ((at91_master_clock / (4 * (rate))) - 3) :	\
+	    ((at91_master_clock / (4 * (rate))) - 2))
+
+/* TWI_SR */
+/* TWI_IER */
+/* TWI_IDR */
+/* TWI_IMR */
+#define	TWI_SR_TXCOMP	(1U << 0)	/* Transmission Completed */
+#define	TWI_SR_RXRDY	(1U << 1)	/* Receive Holding Register Ready */
+#define	TWI_SR_TXRDY	(1U << 2)	/* Transmit Holding Register Ready */
+#define	TWI_SR_SVREAD	(1U << 3)	/* Slave Read */
+#define	TWI_SR_SVACC	(1U << 4)	/* Slave Access */
+#define	TWI_SR_GCACC	(1U << 5)	/* General Call Access */
+#define	TWI_SR_OVRE	(1U << 6)	/* Overrun error */
+#define	TWI_SR_UNRE	(1U << 7)	/* Underrun Error */
+#define	TWI_SR_NACK	(1U << 8)	/* Not Acknowledged */
+#define	TWI_SR_ARBLST	(1U << 9)	/* Arbitration Lost */
+
+#endif /* ARM_AT91_AT91_TWIREG_H */


Property changes on: trunk/sys/arm/at91/at91_twireg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91_usartreg.h
===================================================================
--- trunk/sys/arm/at91/at91_usartreg.h	                        (rev 0)
+++ trunk/sys/arm/at91/at91_usartreg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,130 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2005 Olivier Houchard.  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 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 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: stable/10/sys/arm/at91/at91_usartreg.h 185265 2008-11-25 00:13:26Z imp $ */
+
+#ifndef AT91USARTREG_H_
+#define AT91USARTREG_H_
+
+#define USART_CR		0x00 /* Control register */
+#define USART_CR_RSTRX		(1UL << 2) /* Reset Receiver */
+#define USART_CR_RSTTX		(1UL << 3) /* Reset Transmitter */
+#define USART_CR_RXEN		(1UL << 4) /* Receiver Enable */
+#define USART_CR_RXDIS		(1UL << 5) /* Receiver Disable */
+#define USART_CR_TXEN		(1UL << 6) /* Transmitter Enable */
+#define USART_CR_TXDIS		(1UL << 7) /* Transmitter Disable */
+#define USART_CR_RSTSTA		(1UL << 8) /* Reset Status Bits */
+#define USART_CR_STTBRK		(1UL << 9) /* Start Break */
+#define USART_CR_STPBRK		(1UL << 10) /* Stop Break */
+#define USART_CR_STTTO		(1UL << 11) /* Start Time-out */
+#define USART_CR_SENDA		(1UL << 12) /* Send Address */
+#define USART_CR_RSTIT		(1UL << 13) /* Reset Iterations */
+#define USART_CR_RSTNACK	(1UL << 14) /* Reset Non Acknowledge */
+#define USART_CR_RETTO		(1UL << 15) /* Rearm Time-out */
+#define USART_CR_DTREN		(1UL << 16) /* Data Terminal ready Enable */
+#define USART_CR_DTRDIS		(1UL << 17) /* Data Terminal ready Disable */
+#define USART_CR_RTSEN		(1UL << 18) /* Request to Send enable */
+#define USART_CR_RTSDIS		(1UL << 19) /* Request to Send Disable */
+
+#define USART_MR		0x04 /* Mode register */
+#define USART_MR_MODE_NORMAL	0	/* Normal/Async/3-wire rs-232 */
+#define USART_MR_MODE_RS485	1	/* RS485 */
+#define USART_MR_MODE_HWFLOW	2	/* Hardware flow control/handshake */
+#define USART_MR_MODE_MODEM	3	/* Full modem protocol */
+#define USART_MR_MODE_ISO7816T0 4	/* ISO7816 T=0 */
+#define USART_MR_MODE_ISO7816T1 6	/* ISO7816 T=1 */
+#define USART_MR_MODE_IRDA	8	/* IrDA mode */
+#define USART_MR_USCLKS_MCK	(0U << 4) /* use MCK for baudclock */
+#define USART_MR_USCLKS_MCKDIV	(1U << 4) /* use MCK/DIV for baudclock */
+#define USART_MR_USCLKS_SCK	(3U << 4) /* use SCK (ext) for baudclock */
+#define USART_MR_CHRL_5BITS	(0U << 6)
+#define USART_MR_CHRL_6BITS	(1U << 6)
+#define USART_MR_CHRL_7BITS	(2U << 6)
+#define USART_MR_CHRL_8BITS	(3U << 6)
+#define USART_MR_SYNC		(1U << 8) /* 1 -> sync 0 -> async */
+#define USART_MR_PAR_EVEN	(0U << 9)
+#define USART_MR_PAR_ODD	(1U << 9)
+#define USART_MR_PAR_SPACE	(2U << 9)
+#define USART_MR_PAR_MARK	(3U << 9)
+#define USART_MR_PAR_NONE	(4U << 9)
+#define USART_MR_PAR_MULTIDROP	(6U << 9)
+#define USART_MR_NBSTOP_1	(0U << 12)
+#define USART_MR_NBSTOP_1_5	(1U << 12)
+#define USART_MR_NBSTOP_2	(2U << 12)
+#define USART_MR_CHMODE_NORMAL	(0U << 14)
+#define USART_MR_CHMODE_ECHO	(1U << 14)
+#define USART_MR_CHMODE_LOOP	(2U << 14)
+#define USART_MR_CHMODE_REMLOOP	(3U << 14)
+#define USART_MR_MSBF		(1U << 16)
+#define USART_MR_MODE9		(1U << 17)
+#define USART_MR_CKLO_SCK	(1U << 18)
+#define USART_MR_OVER16		0
+#define USART_MR_OVER8		(1U << 19)
+#define USART_MR_INACK		(1U << 20) /* Inhibit NACK generation */
+#define USART_MR_DSNACK		(1U << 21) /* Disable Successive NACK */
+#define USART_MR_MAXITERATION(x) ((x) << 24)
+#define USART_MR_FILTER		(1U << 28) /* Filters for Ir lines */
+
+#define USART_IER		0x08 /* Interrupt enable register */
+#define USART_IDR		0x0c /* Interrupt disable register */
+#define USART_IMR		0x10 /* Interrupt mask register */
+#define USART_CSR		0x14 /* Channel status register */
+
+#define USART_CSR_RXRDY		(1UL << 0) /* Receiver ready */
+#define USART_CSR_TXRDY		(1UL << 1) /* Transmitter ready */
+#define USART_CSR_RXBRK		(1UL << 2) /* Break received */
+#define USART_CSR_ENDRX		(1UL << 3) /* End of Transfer RX from PDC */
+#define USART_CSR_ENDTX		(1UL << 4) /* End of Transfer TX from PDC */
+#define USART_CSR_OVRE		(1UL << 5) /* Overrun error */
+#define USART_CSR_FRAME		(1UL << 6) /* Framing error */
+#define USART_CSR_PARE		(1UL << 7) /* Parity Error */
+#define USART_CSR_TIMEOUT	(1UL << 8) /* Timeout since start-timeout */
+#define USART_CSR_TXEMPTY	(1UL << 9) /* Transmitter empty */
+#define USART_CSR_ITERATION	(1UL << 10) /* max repetitions since RSIT */
+#define USART_CSR_TXBUFE	(1UL << 11) /* Buffer empty from PDC */
+#define USART_CSR_RXBUFF	(1UL << 12) /* Buffer full from PDC */
+#define USART_CSR_NACK		(1UL << 13) /* NACK since last RSTNACK */
+#define USART_CSR_RIIC		(1UL << 16) /* RI delta since last csr read */
+#define USART_CSR_DSRIC		(1UL << 17) /* DSR delta */
+#define USART_CSR_DCDIC		(1UL << 18) /* DCD delta */
+#define USART_CSR_CTSIC		(1UL << 19) /* CTS delta */
+#define USART_CSR_RI		(1UL << 20) /* RI status */
+#define USART_CSR_DSR		(1UL << 21) /* DSR status */
+#define USART_CSR_DCD		(1UL << 22) /* DCD status */
+#define USART_CSR_CTS		(1UL << 23) /* CTS status */
+
+#define USART_RHR		0x18 /* Receiver holding register */
+#define USART_THR		0x1c /* Transmitter holding register */
+#define USART_BRGR		0x20 /* Baud rate generator register */
+#define USART_RTOR		0x24 /* Receiver time-out register */
+#define USART_TTR		0x28 /* Transmitter timeguard register */
+/* 0x2c to 0x3c reserved */
+#define USART_FDRR		0x40 /* FI DI ratio register */
+#define USART_NER		0x44 /* Number of errors register */
+/* 0x48 reserved */
+#define USART_IFR		0x48 /* IrDA filter register */
+
+#endif /* AT91RM92REG_H_ */


Property changes on: trunk/sys/arm/at91/at91_usartreg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91_wdt.c
===================================================================
--- trunk/sys/arm/at91/at91_wdt.c	                        (rev 0)
+++ trunk/sys/arm/at91/at91_wdt.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,239 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2010 Greg Ansley.  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 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 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.
+ */
+
+/*
+ * The SAM9 watchdog hardware can be programed only once. So we set the
+ * hardware watchdog to 16 s in wdt_attach and only reset it in the wdt_tick
+ * handler.  The watchdog is halted in processor debug mode.
+ */
+
+#include "opt_platform.h"
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/at91/at91_wdt.c 266196 2014-05-15 21:21:47Z ian $");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/kdb.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/systm.h>
+#include <sys/watchdog.h>
+
+#include <machine/bus.h>
+
+#include <arm/at91/at91var.h>
+#include <arm/at91/at91_wdtreg.h>
+
+#ifdef FDT
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+#endif
+
+struct wdt_softc {
+	struct mtx	sc_mtx;
+	device_t	sc_dev;
+	struct resource	*mem_res;
+	struct callout	tick_ch;
+	eventhandler_tag sc_wet;
+	void		*intrhand;
+	u_int		cmd;
+	u_int		interval;
+};
+
+static inline uint32_t
+RD4(struct wdt_softc *sc, bus_size_t off)
+{
+
+	return (bus_read_4(sc->mem_res, off));
+}
+
+static inline void
+WR4(struct wdt_softc *sc, bus_size_t off, uint32_t val)
+{
+
+	bus_write_4(sc->mem_res, off, val);
+}
+
+static int
+wdt_intr(void *argp)
+{
+	struct wdt_softc *sc = argp;
+
+
+	if (RD4(sc, WDT_SR) & (WDT_WDUNF | WDT_WDERR)) {
+#if defined(KDB) && !defined(KDB_UNATTENDED)
+		kdb_backtrace();
+		kdb_enter(KDB_WHY_WATCHDOG, "watchdog timeout");
+#else
+		panic("watchdog timeout");
+#endif
+	}
+	return (FILTER_STRAY);
+}
+
+/* User interface, see watchdog(9) */
+static void
+wdt_watchdog(void *argp, u_int cmd, int *error)
+{
+	struct wdt_softc *sc = argp;
+	u_int interval;
+
+	mtx_lock(&sc->sc_mtx);
+
+	*error = 0;
+	sc->cmd = 0;
+	interval = cmd & WD_INTERVAL;
+	if (interval > WD_TO_16SEC)
+		*error = EOPNOTSUPP;
+	else if (interval > 0)
+		sc->cmd = interval | WD_ACTIVE;
+
+	/* We cannot turn off our watchdog so if user
+	 * fails to turn us on go to passive mode. */
+	if ((sc->cmd & WD_ACTIVE) == 0)
+		sc->cmd = WD_PASSIVE;
+
+	mtx_unlock(&sc->sc_mtx);
+}
+
+/* This routine is called no matter what state the user sets the
+ * watchdog mode to. Called at a rate that is slightly less than
+ * half the hardware timeout. */
+static void
+wdt_tick(void *argp)
+{
+	struct wdt_softc *sc = argp;
+
+	mtx_assert(&sc->sc_mtx, MA_OWNED);
+	if (sc->cmd & (WD_ACTIVE | WD_PASSIVE))
+		WR4(sc, WDT_CR, WDT_KEY|WDT_WDRSTT);
+
+	sc->cmd &= WD_PASSIVE;
+	callout_reset(&sc->tick_ch, sc->interval, wdt_tick, sc);
+}
+
+static int
+wdt_probe(device_t dev)
+{
+#ifdef FDT
+	if (!ofw_bus_is_compatible(dev, "atmel,at91sam9260-wdt"))
+		return (ENXIO);
+#endif
+	device_set_desc(dev, "WDT");
+	return (0);
+}
+
+static int
+wdt_attach(device_t dev)
+{
+	static struct wdt_softc *sc;
+	struct resource *irq;
+	uint32_t wdt_mr;
+	int rid, err;
+
+	sc = device_get_softc(dev);
+	sc->cmd = WD_PASSIVE;
+	sc->sc_dev = dev;
+
+	mtx_init(&sc->sc_mtx, device_get_nameunit(dev), "at91_wdt", MTX_DEF);
+	callout_init_mtx(&sc->tick_ch, &sc->sc_mtx, 0);
+
+	rid = 0;
+	sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	    RF_ACTIVE);
+
+	if (sc->mem_res == NULL)
+		panic("couldn't allocate wdt register resources");
+
+	wdt_mr = RD4(sc, WDT_MR);
+	if ((wdt_mr & WDT_WDRSTEN) == 0)
+		device_printf(dev, "Watchdog disabled! (Boot ROM?)\n");
+	else {
+#ifdef WDT_RESET
+		/* Rude, full reset of whole system on watch dog timeout */
+		WR4(sc, WDT_MR, WDT_WDDBGHLT | WDT_WDD(0xC00)|
+		    WDT_WDRSTEN| WDT_WDV(0xFFF));
+#else
+		/* Generate stack trace and panic on watchdog timeout*/
+		WR4(sc, WDT_MR, WDT_WDDBGHLT | WDT_WDD(0xC00)|
+		    WDT_WDFIEN| WDT_WDV(0xFFF));
+#endif
+		/*
+		 * This may have been set by Boot ROM so register value may
+		 * not be what we just requested since this is a write once
+		 * register.
+		 */
+		wdt_mr = RD4(sc, WDT_MR);
+		if (wdt_mr & WDT_WDFIEN) {
+			rid = 0;
+			irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+			    RF_ACTIVE | RF_SHAREABLE);
+			if (!irq)
+				panic("could not allocate interrupt.\n");
+
+			err = bus_setup_intr(dev, irq, INTR_TYPE_CLK, wdt_intr,
+			    NULL, sc, &sc->intrhand);
+		}
+
+		/* interval * hz */
+		sc->interval = (((wdt_mr & WDT_WDV(~0)) + 1) * WDT_DIV) /
+		    (WDT_CLOCK/hz);
+
+		device_printf(dev, "watchdog timeout: %d seconds\n",
+		    sc->interval / hz);
+
+		/* Slightly less than 1/2 of watchdog hardware timeout */
+		sc->interval = (sc->interval/2) - (sc->interval/20);
+		callout_reset(&sc->tick_ch, sc->interval, wdt_tick, sc);
+
+		/* Register us as a watchdog */
+		sc->sc_wet = EVENTHANDLER_REGISTER(watchdog_list,
+		    wdt_watchdog, sc, 0);
+	}
+	return (0);
+}
+
+static device_method_t wdt_methods[] = {
+	DEVMETHOD(device_probe, wdt_probe),
+	DEVMETHOD(device_attach, wdt_attach),
+	DEVMETHOD_END
+};
+
+static driver_t wdt_driver = {
+	"at91_wdt",
+	wdt_methods,
+	sizeof(struct wdt_softc),
+};
+
+static devclass_t wdt_devclass;
+
+#ifdef FDT
+DRIVER_MODULE(at91_wdt, simplebus, wdt_driver, wdt_devclass, NULL, NULL);
+#else
+DRIVER_MODULE(at91_wdt, atmelarm, wdt_driver, wdt_devclass, NULL, NULL);
+#endif


Property changes on: trunk/sys/arm/at91/at91_wdt.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91_wdtreg.h
===================================================================
--- trunk/sys/arm/at91/at91_wdtreg.h	                        (rev 0)
+++ trunk/sys/arm/at91/at91_wdtreg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,61 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2005 Gallon Sylvestre.  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 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 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: stable/10/sys/arm/at91/at91_wdtreg.h 236989 2012-06-13 04:52:19Z imp $
+ */
+
+#ifndef ARM_AT91_AT91WDTREG_H
+#define ARM_AT91_AT91WDTREG_H
+
+#ifndef WDT_CLOCK
+#define WDT_CLOCK (32768)
+#endif
+#define WDT_DIV (128)	/* Clock is slow clock / 128 */
+
+#define WDT_CR		0x0 /* Control Register */
+#define WDT_MR		0x4 /* Mode Register */
+#define WDT_SR		0x8 /* Status Register */
+
+/* WDT_CR */
+#define WDT_KEY		(0xa5<<24)
+#define WDT_WDRSTT	0x1
+
+/* WDT_MR */
+#define WDT_WDV(x)	(x & 0xfff) /* counter value*/
+#define WDT_WDFIEN	(1<<12) /* enable interrupt */
+#define WDT_WDRSTEN	(1<<13) /* enable reset */
+#define WDT_WDRPROC	(1<<14) /* processor reset */
+#define WDT_WDDIS	(1<<15) /* disable */
+#define WDT_WDD(x)	((x & 0xfff) << 16) /* delta value */
+#define WDT_WDDBGHLT	(1<<28) /* halt in debug */
+#define WDT_WDIDLEHLT	(1<<29) /* halt in idle */
+
+/* WDT_SR */
+#define WDT_WDUNF	0x1
+#define WDT_WDERR	0x2
+
+#endif /* ARM_AT91_AT91WDTREG_H */


Property changes on: trunk/sys/arm/at91/at91_wdtreg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91board.h
===================================================================
--- trunk/sys/arm/at91/at91board.h	                        (rev 0)
+++ trunk/sys/arm/at91/at91board.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,37 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2008 Warner Losh.  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 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 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: stable/10/sys/arm/at91/at91board.h 238189 2012-07-07 05:02:39Z imp $ */
+
+#ifndef _ARM_AT91_AT91BOARD_H_
+#define _ARM_AT91_AT91BOARD_H_
+
+/*
+ * These routines are used by board init routines
+ */
+long at91_ramsize(void);
+
+#endif /* _ARM_AT91_AT91BOARD_H_ */


Property changes on: trunk/sys/arm/at91/at91board.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91reg.h
===================================================================
--- trunk/sys/arm/at91/at91reg.h	                        (rev 0)
+++ trunk/sys/arm/at91/at91reg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,91 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2009 Greg Ansley  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 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 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: stable/10/sys/arm/at91/at91reg.h 238331 2012-07-10 02:39:03Z imp $
+ */
+
+#ifndef _AT91REG_H_
+#define	_AT91REG_H_
+
+#include "opt_at91.h"
+
+/* Where builtin peripherals start in KVM */
+#define	AT91_BASE		0xd0000000
+
+/* Where builtin peripherals start PA */
+#define	AT91_PA_BASE		0xf0000000
+
+/* A few things that we count on being the same
+ * throught the whole family of SOCs */
+
+/* SYSC System Controler */
+/* System Registers */
+#define	AT91_SYS_BASE	0xffff000
+#define	AT91_SYS_SIZE	0x1000
+
+#define AT91_DBGU0	0x0ffff200	/* Most */
+#define AT91_DBGU1	0x0fffee00	/* SAM9263, CAP9, and SAM9G45 */
+
+#define	AT91_DBGU_SIZE	0x200
+#define	DBGU_C1R		(64) /* Chip ID1 Register */
+#define	DBGU_C2R		(68) /* Chip ID2 Register */
+#define	DBGU_FNTR		(72) /* Force NTRST Register */
+
+#define	AT91_CPU_VERSION_MASK	0x0000001f
+#define	AT91_CPU_FAMILY_MASK    0x0ff00000
+
+#define	AT91_CPU_RM9200 	0x09290780
+#define	AT91_CPU_SAM9260	0x019803a0
+#define	AT91_CPU_SAM9261	0x019703a0
+#define	AT91_CPU_SAM9263	0x019607a0
+#define	AT91_CPU_SAM9G10	0x819903a0
+#define	AT91_CPU_SAM9G20	0x019905a0
+#define	AT91_CPU_SAM9G45	0x819b05a0
+#define	AT91_CPU_SAM9N12        0x819a07a0
+#define	AT91_CPU_SAM9RL64	0x019b03a0
+#define	AT91_CPU_SAM9X5		0x819a05a0
+
+#define	AT91_CPU_SAM9XE128	0x329973a0
+#define	AT91_CPU_SAM9XE256	0x329a93a0
+#define	AT91_CPU_SAM9XE512	0x329aa3a0
+
+#define	AT91_CPU_CAP9           0x039a03a0
+
+#define	AT91_EXID_SAM9M11	0x00000001
+#define	AT91_EXID_SAM9M10	0x00000002
+#define	AT91_EXID_SAM9G46	0x00000003
+#define	AT91_EXID_SAM9G45	0x00000004
+
+#define	AT91_EXID_SAM9G15	0x00000000
+#define	AT91_EXID_SAM9G35	0x00000001
+#define	AT91_EXID_SAM9X35	0x00000002
+#define	AT91_EXID_SAM9G25	0x00000003
+#define	AT91_EXID_SAM9X25	0x00000004
+
+#define AT91_IRQ_SYSTEM		1
+
+#endif /* _AT91REG_H_ */


Property changes on: trunk/sys/arm/at91/at91reg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91rm9200.c
===================================================================
--- trunk/sys/arm/at91/at91rm9200.c	                        (rev 0)
+++ trunk/sys/arm/at91/at91rm9200.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,211 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2005 Olivier Houchard.  All rights reserved.
+ * Copyright (c) 2010 Greg Ansley.  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 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 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: stable/10/sys/arm/at91/at91rm9200.c 266277 2014-05-17 00:53:12Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+
+#define	_ARM32_BUS_DMA_PRIVATE
+#include <machine/bus.h>
+
+#include <arm/at91/at91var.h>
+#include <arm/at91/at91reg.h>
+#include <arm/at91/at91rm92reg.h>
+#include <arm/at91/at91_aicreg.h>
+#include <arm/at91/at91_pmcreg.h>
+#include <arm/at91/at91_streg.h>
+#include <arm/at91/at91_pmcvar.h>
+#include <arm/at91/at91soc.h>
+
+/*
+ * Standard priority levels for the system.  0 is lowest and 7 is highest.
+ * These values are the ones Atmel uses for its Linux port, which differ
+ * a little form the ones that are in the standard distribution.  Also,
+ * the ones marked with 'TWEEK' are different based on experience.
+ */
+static const int at91_irq_prio[32] =
+{
+	7,	/* Advanced Interrupt Controller (FIQ) */
+	7,	/* System Peripherals */
+	1,	/* Parallel IO Controller A */
+	1,	/* Parallel IO Controller B */
+	1,	/* Parallel IO Controller C */
+	1,	/* Parallel IO Controller D */
+	5,	/* USART 0 */
+	5,	/* USART 1 */
+	5,	/* USART 2 */
+	5,	/* USART 3 */
+	0,	/* Multimedia Card Interface */
+	2,	/* USB Device Port */
+	4,	/* Two-Wire Interface */		/* TWEEK */
+	5,	/* Serial Peripheral Interface */
+	4,	/* Serial Synchronous Controller 0 */
+	6,	/* Serial Synchronous Controller 1 */	/* TWEEK */
+	4,	/* Serial Synchronous Controller 2 */
+	0,	/* Timer Counter 0 */
+	6,	/* Timer Counter 1 */			/* TWEEK */
+	0,	/* Timer Counter 2 */
+	0,	/* Timer Counter 3 */
+	0,	/* Timer Counter 4 */
+	0,	/* Timer Counter 5 */
+	2,	/* USB Host port */
+	3,	/* Ethernet MAC */
+	0,	/* Advanced Interrupt Controller (IRQ0) */
+	0,	/* Advanced Interrupt Controller (IRQ1) */
+	0,	/* Advanced Interrupt Controller (IRQ2) */
+	0,	/* Advanced Interrupt Controller (IRQ3) */
+	0,	/* Advanced Interrupt Controller (IRQ4) */
+	0,	/* Advanced Interrupt Controller (IRQ5) */
+ 	0	/* Advanced Interrupt Controller (IRQ6) */
+};
+
+static const uint32_t at91_pio_base[] = {
+	AT91RM92_PIOA_BASE,
+	AT91RM92_PIOB_BASE,
+	AT91RM92_PIOC_BASE,
+	AT91RM92_PIOD_BASE,
+};
+
+#define DEVICE(_name, _id, _unit)		\
+	{					\
+		_name, _unit,			\
+		AT91RM92_ ## _id ##_BASE,	\
+		AT91RM92_ ## _id ## _SIZE,	\
+		AT91RM92_IRQ_ ## _id		\
+	}
+
+static const struct cpu_devs at91_devs[] =
+{
+	DEVICE("at91_aic", AIC,  0),
+	DEVICE("at91_pmc",   PMC,    0),
+	DEVICE("at91_st",    ST,     0),
+	DEVICE("at91_pio",   PIOA,   0),
+	DEVICE("at91_pio",   PIOB,   1),
+	DEVICE("at91_pio",   PIOC,   2),
+	DEVICE("at91_pio",   PIOD,   3),
+	DEVICE("at91_rtc",   RTC,    0),
+
+	DEVICE("at91_mci",   MCI,    0),
+	DEVICE("at91_twi",   TWI,    0),
+	DEVICE("at91_udp",   UDP,    0),
+	DEVICE("ate",        EMAC,   0),
+	DEVICE("at91_ssc",   SSC0,   0),
+	DEVICE("at91_ssc",   SSC1,   1),
+	DEVICE("at91_ssc",   SSC2,   2),
+	DEVICE("spi",        SPI,    0),
+
+	DEVICE("uart",       DBGU,   0),
+	DEVICE("uart",       USART0, 1),
+	DEVICE("uart",       USART1, 2),
+	DEVICE("uart",       USART2, 3),
+	DEVICE("uart",       USART3, 4),
+	DEVICE("at91_aic",   AIC,    0),
+	DEVICE("at91_mc",    MC,     0),
+	DEVICE("at91_tc",    TC0,    0),
+	DEVICE("at91_tc",    TC1,    1),
+	DEVICE("ohci",       OHCI,   0),
+	DEVICE("at91_cfata", CF,     0),
+	{	0, 0, 0, 0, 0 }
+};
+
+static uint32_t
+at91_pll_outb(int freq)
+{
+
+	if (freq > 155000000)
+		return (0x0000);
+	else
+		return (0x8000);
+}
+
+#if 0
+/* -- XXX are these needed? */
+	/* Disable all interrupts for RTC (0xe24 == RTC_IDR) */
+	bus_space_write_4(sc->sc_st, sc->sc_sys_sh, 0xe24, 0xffffffff);
+
+	/* Disable all interrupts for the SDRAM controller */
+	bus_space_write_4(sc->sc_st, sc->sc_sys_sh, 0xfa8, 0xffffffff);
+#endif
+
+static void
+at91_clock_init(void)
+{
+	struct at91_pmc_clock *clk;
+
+	/* Update USB device port clock info */
+	clk = at91_pmc_clock_ref("udpck");
+	clk->pmc_mask  = PMC_SCER_UDP;
+	at91_pmc_clock_deref(clk);
+
+	/* Update USB host port clock info */
+	clk = at91_pmc_clock_ref("uhpck");
+	clk->pmc_mask  = PMC_SCER_UHP;
+	at91_pmc_clock_deref(clk);
+
+	/* Each SOC has different PLL contraints */
+	clk = at91_pmc_clock_ref("plla");
+	clk->pll_min_in    = RM9200_PLL_A_MIN_IN_FREQ;		/*   1 MHz */
+	clk->pll_max_in    = RM9200_PLL_A_MAX_IN_FREQ;		/*  32 MHz */
+	clk->pll_min_out   = RM9200_PLL_A_MIN_OUT_FREQ;		/*  80 MHz */
+	clk->pll_max_out   = RM9200_PLL_A_MAX_OUT_FREQ;		/* 180 MHz */
+	clk->pll_mul_shift = RM9200_PLL_A_MUL_SHIFT;
+	clk->pll_mul_mask  = RM9200_PLL_A_MUL_MASK;
+	clk->pll_div_shift = RM9200_PLL_A_DIV_SHIFT;
+	clk->pll_div_mask  = RM9200_PLL_A_DIV_MASK;
+	clk->set_outb      = at91_pll_outb;
+	at91_pmc_clock_deref(clk);
+
+	clk = at91_pmc_clock_ref("pllb");
+	clk->pll_min_in    = RM9200_PLL_B_MIN_IN_FREQ;		/* 100 KHz */
+	clk->pll_max_in    = RM9200_PLL_B_MAX_IN_FREQ;		/*  32 MHz */
+	clk->pll_min_out   = RM9200_PLL_B_MIN_OUT_FREQ;		/*  30 MHz */
+	clk->pll_max_out   = RM9200_PLL_B_MAX_OUT_FREQ;		/* 240 MHz */
+	clk->pll_mul_shift = RM9200_PLL_B_MUL_SHIFT;
+	clk->pll_mul_mask  = RM9200_PLL_B_MUL_MASK;
+	clk->pll_div_shift = RM9200_PLL_B_DIV_SHIFT;
+	clk->pll_div_mask  = RM9200_PLL_B_DIV_MASK;
+	clk->set_outb      = at91_pll_outb;
+	at91_pmc_clock_deref(clk);
+}
+
+static struct at91_soc_data soc_data = {
+	.soc_delay = at91_st_delay,
+	.soc_reset = at91_st_cpu_reset,
+	.soc_clock_init = at91_clock_init,
+	.soc_irq_prio = at91_irq_prio,
+	.soc_children = at91_devs,
+	.soc_pio_base = at91_pio_base,
+	.soc_pio_count = nitems(at91_pio_base),
+};
+
+AT91_SOC(AT91_T_RM9200, &soc_data);


Property changes on: trunk/sys/arm/at91/at91rm9200.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91rm9200_devices.c
===================================================================
--- trunk/sys/arm/at91/at91rm9200_devices.c	                        (rev 0)
+++ trunk/sys/arm/at91/at91rm9200_devices.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,143 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 M. Warner Losh.  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 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 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: stable/10/sys/arm/at91/at91rm9200_devices.c 248902 2013-03-29 18:06:54Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+
+#define	_ARM32_BUS_DMA_PRIVATE
+#include <machine/bus.h>
+
+#include <arm/at91/at91var.h>
+#include <arm/at91/at91board.h>
+#include <arm/at91/at91rm92reg.h>
+#include <arm/at91/at91rm9200var.h>
+#include <arm/at91/at91_pioreg.h>
+#include <arm/at91/at91_piovar.h>
+
+/*
+ * The AT91RM9200 uses the same silicon for both the BGA and PQFP
+ * packages.  There's no documented way to detect this at runtime,
+ * so we require the board code to register what type of SoC is on the
+ * board in question.  The pinouts are not quite compatible, and we
+ * use this information to cope with the slight differences.
+ */
+void
+at91rm9200_set_subtype(enum at91_soc_subtype st)
+{
+
+	switch (st) {
+	case AT91_ST_RM9200_BGA:
+	case AT91_ST_RM9200_PQFP:
+		soc_info.subtype = st;
+		break;
+	default:
+		panic("Bad SoC subtype %d for at91rm9200_set_subtype.", st);
+		break;
+	}
+}
+
+void
+at91rm9200_config_uart(unsigned devid, unsigned unit, unsigned pinmask)
+{
+
+	/*
+	 * Since the USART supports RS-485 multidrop mode, it allows the
+	 * TX pins to float.  However, for RS-232 operations, we don't want
+	 * these pins to float.  Instead, they should be pulled up to avoid
+	 * mismatches.  Linux does something similar when it configures the
+	 * TX lines.  This implies that we also allow the RX lines to float
+	 * rather than be in the state they are left in by the boot loader.
+	 * Since they are input pins, I think that this is the right thing
+	 * to do.
+	 */
+
+	/*
+	 * Current boards supported don't need the extras, but they should be
+	 * implemented.  But that should wait until the new pin api goes in.
+	 */
+	switch (devid) {
+	case AT91_ID_DBGU:
+		at91_pio_use_periph_a(AT91RM92_PIOA_BASE, AT91C_PIO_PA30, 0); /* DRXD */
+		at91_pio_use_periph_a(AT91RM92_PIOA_BASE, AT91C_PIO_PA31, 1); /* DTXD */
+		break;
+
+	case AT91RM9200_ID_USART0:
+		at91_pio_use_periph_a(AT91RM92_PIOA_BASE, AT91C_PIO_PA17, 1); /* TXD0 */
+		at91_pio_use_periph_a(AT91RM92_PIOA_BASE, AT91C_PIO_PA18, 0); /* RXD0 */
+		/* CTS PA20 */
+		/* RTS -- errata #39 PA21 */
+		break;
+
+	case AT91RM9200_ID_USART1:
+		at91_pio_use_periph_a(AT91RM92_PIOB_BASE, AT91C_PIO_PB20, 1); /* TXD1 */
+		at91_pio_use_periph_a(AT91RM92_PIOB_BASE, AT91C_PIO_PB21, 0); /* RXD1 */
+		/* RI - PB18 */
+		/* DTR - PB19 */
+		/* DCD - PB23 */
+		/* CTS - PB24 */
+		/* DSR - PB25 */
+		/* RTS - PB26 */
+		break;
+
+	case AT91RM9200_ID_USART2:
+		at91_pio_use_periph_a(AT91RM92_PIOA_BASE, AT91C_PIO_PA22, 0); /* RXD2 */
+		at91_pio_use_periph_a(AT91RM92_PIOA_BASE, AT91C_PIO_PA23, 1); /* TXD2 */
+		/* CTS - PA30 B periph */
+		/* RTS - PA31 B periph */
+		break;
+
+	case AT91RM9200_ID_USART3:
+		at91_pio_use_periph_b(AT91RM92_PIOA_BASE, AT91C_PIO_PA5, 1); /* TXD3 */
+		at91_pio_use_periph_b(AT91RM92_PIOA_BASE, AT91C_PIO_PA6, 0); /* RXD3 */
+		/* CTS - PB0 B periph */
+		/* RTS - PB1 B periph */
+		break;
+
+	default:
+		break;
+	}
+}
+
+void
+at91rm9200_config_mci(int has_4wire)
+{
+	/* XXX TODO chip changed GPIO, other slots, etc */
+	at91_pio_use_periph_a(AT91RM92_PIOA_BASE, AT91C_PIO_PA27,  0); /* MCCK */
+	at91_pio_use_periph_a(AT91RM92_PIOA_BASE, AT91C_PIO_PA28, 1);  /* MCCDA */
+	at91_pio_use_periph_a(AT91RM92_PIOA_BASE, AT91C_PIO_PA29, 1);  /* MCDA0 */
+	if (has_4wire) {
+		at91_pio_use_periph_b(AT91RM92_PIOB_BASE, AT91C_PIO_PB3, 1); /* MCDA1 */
+		at91_pio_use_periph_b(AT91RM92_PIOB_BASE, AT91C_PIO_PB4, 1); /* MCDA2 */
+		at91_pio_use_periph_b(AT91RM92_PIOB_BASE, AT91C_PIO_PB5, 1); /* MCDA3 */
+	}
+}


Property changes on: trunk/sys/arm/at91/at91rm9200_devices.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91rm9200var.h
===================================================================
--- trunk/sys/arm/at91/at91rm9200var.h	                        (rev 0)
+++ trunk/sys/arm/at91/at91rm9200var.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,59 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 M. Warner Losh.  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 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 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: stable/10/sys/arm/at91/at91rm9200var.h 238465 2012-07-15 05:41:43Z imp $ */
+
+#ifndef ARM_AT91_AT91RM9200VAR_H
+#define ARM_AT91_AT91RM9200VAR_H
+
+void at91rm9200_set_subtype(enum at91_soc_subtype st);
+
+#define AT91RM9200_ID_USART0	1
+#define AT91RM9200_ID_USART1	2
+#define AT91RM9200_ID_USART2	3
+#define AT91RM9200_ID_USART3	4
+
+/*
+ * Serial port convenience routines
+ */
+/* uart pins that are wired... */
+#define	AT91_UART_CTS	0x01
+#define	AT91_UART_RTS	0x02
+#define	AT91_UART_RI    0x04
+#define	AT91_UART_DTR	0x08
+#define AT91_UART_DCD	0x10
+#define	AT91_UART_DSR	0x20
+
+#define AT91_ID_DBGU	0
+
+void at91rm9200_config_uart(unsigned devid, unsigned unit, unsigned pinmask);
+
+/*
+ * MCI (sd/mmc card support)
+ */
+void at91rm9200_config_mci(int has_4wire);
+
+#endif /* ARM_AT91_AT91RM9200VAR_H */


Property changes on: trunk/sys/arm/at91/at91rm9200var.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91rm92reg.h
===================================================================
--- trunk/sys/arm/at91/at91rm92reg.h	                        (rev 0)
+++ trunk/sys/arm/at91/at91rm92reg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,307 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2005 Olivier Houchard.  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 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 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: stable/10/sys/arm/at91/at91rm92reg.h 266110 2014-05-15 02:41:23Z ian $ */
+
+#ifndef AT91RM92REG_H_
+#define AT91RM92REG_H_
+
+/* Chip Specific limits */
+#define RM9200_PLL_A_MIN_IN_FREQ	  1000000 /*   1 MHz */
+#define RM9200_PLL_A_MAX_IN_FREQ	 32000000 /*  32 MHz */
+#define RM9200_PLL_A_MIN_OUT_FREQ	 80000000 /*  80 MHz */
+#define RM9200_PLL_A_MAX_OUT_FREQ	180000000 /* 180 MHz */
+#define RM9200_PLL_A_MUL_SHIFT 16
+#define RM9200_PLL_A_MUL_MASK 0x7FF
+#define RM9200_PLL_A_DIV_SHIFT 0
+#define RM9200_PLL_A_DIV_MASK 0xFF
+
+/*
+ * PLL B input frequency spec sheet says it must be between 1MHz and 32MHz,
+ * but it works down as low as 100kHz, a frequency necessary for some
+ * output frequencies to work.
+ *
+ * PLL Max output frequency is 240MHz.  The errata says 180MHz is the max
+ * for some revisions of this part.  Be more permissive and optimistic.
+ */
+#define RM9200_PLL_B_MIN_IN_FREQ	   100000 /* 100 KHz */
+#define RM9200_PLL_B_MAX_IN_FREQ	 32000000 /*  32 MHz */
+#define RM9200_PLL_B_MIN_OUT_FREQ	 30000000 /*  30 MHz */
+#define RM9200_PLL_B_MAX_OUT_FREQ	240000000 /* 240 MHz */
+#define RM9200_PLL_B_MUL_SHIFT 16
+#define RM9200_PLL_B_MUL_MASK 0x7FF
+#define RM9200_PLL_B_DIV_SHIFT 0
+#define RM9200_PLL_B_DIV_MASK 0xFF
+
+/*
+ * Memory map, from datasheet :
+ * 0x00000000 - 0x0ffffffff : Internal Memories
+ * 0x10000000 - 0x1ffffffff : Chip Select 0
+ * 0x20000000 - 0x2ffffffff : Chip Select 1
+ * 0x30000000 - 0x3ffffffff : Chip Select 2
+ * 0x40000000 - 0x4ffffffff : Chip Select 3
+ * 0x50000000 - 0x5ffffffff : Chip Select 4
+ * 0x60000000 - 0x6ffffffff : Chip Select 5
+ * 0x70000000 - 0x7ffffffff : Chip Select 6
+ * 0x80000000 - 0x8ffffffff : Chip Select 7
+ * 0x90000000 - 0xeffffffff : Undefined (Abort)
+ * 0xf0000000 - 0xfffffffff : Peripherals
+ */
+
+/* Usart */
+
+#define AT91RM92_USART_SIZE	0x4000
+#define AT91RM92_USART0_BASE	0xffc0000
+#define AT91RM92_USART0_PDC	0xffc0100
+#define AT91RM92_USART0_SIZE	AT91RM92_USART_SIZE
+#define AT91RM92_USART1_BASE	0xffc4000
+#define AT91RM92_USART1_PDC	0xffc4100
+#define AT91RM92_USART1_SIZE	AT91RM92_USART_SIZE
+#define AT91RM92_USART2_BASE	0xffc8000
+#define AT91RM92_USART2_PDC	0xffc8100
+#define AT91RM92_USART2_SIZE	AT91RM92_USART_SIZE
+#define AT91RM92_USART3_BASE	0xffcc000
+#define AT91RM92_USART3_PDC	0xffcc100
+#define AT91RM92_USART3_SIZE	AT91RM92_USART_SIZE
+
+/* System Registers */
+
+#define AT91RM92_SYS_BASE	0xffff000
+#define AT91RM92_SYS_SIZE	0x1000
+
+/*
+ * PIO
+ */
+#define AT91RM92_PIO_SIZE	0x200
+#define AT91RM92_PIOA_BASE	0xffff400
+#define AT91RM92_PIOA_SIZE	AT91RM92_PIO_SIZE
+#define AT91RM92_PIOB_BASE	0xffff600
+#define AT91RM92_PIOB_SIZE	AT91RM92_PIO_SIZE
+#define AT91RM92_PIOC_BASE	0xffff800
+#define AT91RM92_PIOC_SIZE	AT91RM92_PIO_SIZE
+#define AT91RM92_PIOD_BASE	0xffffa00
+#define AT91RM92_PIOD_SIZE	AT91RM92_PIO_SIZE
+
+/*
+ * PMC
+ */
+#define AT91RM92_PMC_BASE	0xffffc00
+#define AT91RM92_PMC_SIZE	0x100
+
+/* IRQs : */
+/*
+ * 0: AIC
+ * 1: System peripheral (System timer, RTC, DBGU)
+ * 2: PIO Controller A
+ * 3: PIO Controller B
+ * 4: PIO Controller C
+ * 5: PIO Controller D
+ * 6: USART 0
+ * 7: USART 1
+ * 8: USART 2
+ * 9: USART 3
+ * 10: MMC Interface
+ * 11: USB device port
+ * 12: Two-wirte interface
+ * 13: SPI
+ * 14: SSC
+ * 15: SSC
+ * 16: SSC
+ * 17: Timer Counter 0
+ * 18: Timer Counter 1
+ * 19: Timer Counter 2
+ * 20: Timer Counter 3
+ * 21: Timer Counter 4
+ * 22: Timer Counter 6
+ * 23: USB Host port
+ * 24: Ethernet
+ * 25: AIC
+ * 26: AIC
+ * 27: AIC
+ * 28: AIC
+ * 29: AIC
+ * 30: AIC
+ * 31: AIC
+ */
+
+#define AT91RM92_IRQ_SYSTEM	1
+#define AT91RM92_IRQ_PIOA	2
+#define AT91RM92_IRQ_PIOB	3
+#define AT91RM92_IRQ_PIOC	4
+#define AT91RM92_IRQ_PIOD	5
+#define AT91RM92_IRQ_USART0	6
+#define AT91RM92_IRQ_USART1	7
+#define AT91RM92_IRQ_USART2	8
+#define AT91RM92_IRQ_USART3	9
+#define AT91RM92_IRQ_MCI	10
+#define AT91RM92_IRQ_UDP	11
+#define AT91RM92_IRQ_TWI	12
+#define AT91RM92_IRQ_SPI	13
+#define AT91RM92_IRQ_SSC0	14
+#define AT91RM92_IRQ_SSC1	15
+#define AT91RM92_IRQ_SSC2	16
+#define AT91RM92_IRQ_TC0	17,18,19
+#define AT91RM92_IRQ_TC0C0	17
+#define AT91RM92_IRQ_TC0C1	18
+#define AT91RM92_IRQ_TC0C2	19
+#define AT91RM92_IRQ_TC1	20,21,22
+#define AT91RM92_IRQ_TC1C1	20
+#define AT91RM92_IRQ_TC1C2	21
+#define AT91RM92_IRQ_TC1C3	22
+#define AT91RM92_IRQ_UHP	23
+#define AT91RM92_IRQ_EMAC	24
+#define AT91RM92_IRQ_AIC_IRQ0	25
+#define AT91RM92_IRQ_AIC_IRQ1	26
+#define AT91RM92_IRQ_AIC_IRQ2	27
+#define AT91RM92_IRQ_AIC_IRQ3	28
+#define AT91RM92_IRQ_AIC_IRQ4	29
+#define AT91RM92_IRQ_AIC_IRQ5	30
+#define AT91RM92_IRQ_AIC_IRQ6	31
+
+/* Alias */
+#define AT91RM92_IRQ_DBGU AT91RM92_IRQ_SYSTEM
+#define AT91RM92_IRQ_PMC  AT91RM92_IRQ_SYSTEM
+#define AT91RM92_IRQ_ST   AT91RM92_IRQ_SYSTEM
+#define AT91RM92_IRQ_RTC  AT91RM92_IRQ_SYSTEM
+#define AT91RM92_IRQ_MC   AT91RM92_IRQ_SYSTEM
+#define AT91RM92_IRQ_OHCI AT91RM92_IRQ_UHP
+#define AT91RM92_IRQ_AIC -1
+#define AT91RM92_IRQ_CF -1
+
+/* Timer */
+
+#define AT91RM92_AIC_BASE	0xffff000
+#define AT91RM92_AIC_SIZE	0x200
+
+/* DBGU */
+#define AT91RM92_DBGU_BASE	0xffff200
+#define AT91RM92_DBGU_SIZE	0x200
+
+#define AT91RM92_RTC_BASE	0xffffe00
+#define AT91RM92_RTC_SIZE	0x100
+
+#define AT91RM92_MC_BASE	0xfffff00
+#define AT91RM92_MC_SIZE	0x100
+
+#define AT91RM92_ST_BASE	0xffffd00
+#define AT91RM92_ST_SIZE	0x100
+
+#define AT91RM92_SPI_BASE	0xffe0000
+#define AT91RM92_SPI_SIZE	0x4000
+#define AT91RM92_SPI_PDC	0xffe0100
+
+#define AT91RM92_SSC_SIZE	0x4000
+#define AT91RM92_SSC0_BASE	0xffd0000
+#define AT91RM92_SSC0_PDC	0xffd0100
+#define AT91RM92_SSC0_SIZE	AT91RM92_SSC_SIZE	
+
+#define AT91RM92_SSC1_BASE	0xffd4000
+#define AT91RM92_SSC1_PDC	0xffd4100
+#define AT91RM92_SSC1_SIZE	AT91RM92_SSC_SIZE	
+
+#define AT91RM92_SSC2_BASE	0xffd8000
+#define AT91RM92_SSC2_PDC	0xffd8100
+#define AT91RM92_SSC2_SIZE	AT91RM92_SSC_SIZE	
+
+#define AT91RM92_EMAC_BASE	0xffbc000
+#define AT91RM92_EMAC_SIZE	0x4000
+
+#define AT91RM92_TWI_BASE	0xffb8000
+#define AT91RM92_TWI_SIZE	0x4000
+
+#define AT91RM92_MCI_BASE	0xffb4000
+#define AT91RM92_MCI_PDC	0xffb4100
+#define AT91RM92_MCI_SIZE	0x4000
+
+#define AT91RM92_UDP_BASE	0xffb0000
+#define AT91RM92_UDP_SIZE	0x4000
+
+#define AT91RM92_TC_SIZE	0x4000
+#define AT91RM92_TC0_BASE	0xffa0000
+#define AT91RM92_TC0_SIZE	AT91RM92_TC_SIZE
+#define AT91RM92_TC0C0_BASE	0xffa0000
+#define AT91RM92_TC0C1_BASE	0xffa0040
+#define AT91RM92_TC0C2_BASE	0xffa0080
+
+#define AT91RM92_TC1_BASE	0xffa4000
+#define AT91RM92_TC1_SIZE	AT91RM92_TC_SIZE
+#define AT91RM92_TC1C0_BASE	0xffa4000
+#define AT91RM92_TC1C1_BASE	0xffa4040
+#define AT91RM92_TC1C2_BASE	0xffa4080
+
+/* XXX Needs to be carfully coordinated with
+ * other * soc's so phyical and vm address
+ * mapping are unique. XXX
+ */
+#define AT91RM92_OHCI_VA_BASE	0xdfe00000
+#define AT91RM92_OHCI_BASE	0x00300000
+#define AT91RM92_OHCI_SIZE	0x00100000
+
+#define	AT91RM92_CF_VA_BASE	0xdfd00000
+#define	AT91RM92_CF_BASE	0x51400000
+#define	AT91RM92_CF_SIZE	0x00100000
+
+/* SDRAMC */
+
+#define AT91RM92_SDRAMC_BASE	0xfffff90
+#define AT91RM92_SDRAMC_MR	0x00
+#define AT91RM92_SDRAMC_MR_MODE_NORMAL	0
+#define AT91RM92_SDRAMC_MR_MODE_NOP	1
+#define AT91RM92_SDRAMC_MR_MODE_PRECHARGE 2
+#define AT91RM92_SDRAMC_MR_MODE_LOAD_MODE_REGISTER 3
+#define AT91RM92_SDRAMC_MR_MODE_REFRESH	4
+#define AT91RM92_SDRAMC_MR_DBW_16	0x10
+#define AT91RM92_SDRAMC_TR	0x04
+#define AT91RM92_SDRAMC_CR	0x08
+#define AT91RM92_SDRAMC_CR_NC_8		0x0
+#define AT91RM92_SDRAMC_CR_NC_9		0x1
+#define AT91RM92_SDRAMC_CR_NC_10	0x2
+#define AT91RM92_SDRAMC_CR_NC_11	0x3
+#define AT91RM92_SDRAMC_CR_NC_MASK	0x00000003
+#define AT91RM92_SDRAMC_CR_NR_11	0x0
+#define AT91RM92_SDRAMC_CR_NR_12	0x4
+#define AT91RM92_SDRAMC_CR_NR_13	0x8
+#define AT91RM92_SDRAMC_CR_NR_RES	0xc
+#define AT91RM92_SDRAMC_CR_NR_MASK	0x0000000c
+#define AT91RM92_SDRAMC_CR_NB_2		0x00
+#define AT91RM92_SDRAMC_CR_NB_4		0x10
+#define AT91RM92_SDRAMC_CR_NB_MASK	0x00000010
+#define AT91RM92_SDRAMC_CR_NCAS_MASK	0x00000060
+#define AT91RM92_SDRAMC_CR_TWR_MASK	0x00000780
+#define AT91RM92_SDRAMC_CR_TRC_MASK	0x00007800
+#define AT91RM92_SDRAMC_CR_TRP_MASK	0x00078000
+#define AT91RM92_SDRAMC_CR_TRCD_MASK	0x00780000
+#define AT91RM92_SDRAMC_CR_TRAS_MASK	0x07800000
+#define AT91RM92_SDRAMC_CR_TXSR_MASK	0x78000000
+#define AT91RM92_SDRAMC_SRR	0x0c
+#define AT91RM92_SDRAMC_LPR	0x10
+#define AT91RM92_SDRAMC_IER	0x14
+#define AT91RM92_SDRAMC_IDR	0x18
+#define AT91RM92_SDRAMC_IMR	0x1c
+#define AT91RM92_SDRAMC_ISR	0x20
+#define AT91RM92_SDRAMC_IER_RES	0x1
+
+#endif /* AT91RM92REG_H_ */


Property changes on: trunk/sys/arm/at91/at91rm92reg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91sam9260.c
===================================================================
--- trunk/sys/arm/at91/at91sam9260.c	                        (rev 0)
+++ trunk/sys/arm/at91/at91sam9260.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,218 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2005 Olivier Houchard.  All rights reserved.
+ * Copyright (c) 2010 Greg Ansley.  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 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 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: stable/10/sys/arm/at91/at91sam9260.c 266087 2014-05-14 20:31:54Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+
+#define	_ARM32_BUS_DMA_PRIVATE
+#include <machine/bus.h>
+
+#include <arm/at91/at91var.h>
+#include <arm/at91/at91reg.h>
+#include <arm/at91/at91soc.h>
+#include <arm/at91/at91_aicreg.h>
+#include <arm/at91/at91sam9260reg.h>
+#include <arm/at91/at91_pitreg.h>
+#include <arm/at91/at91_pmcreg.h>
+#include <arm/at91/at91_pmcvar.h>
+#include <arm/at91/at91_rstreg.h>
+
+/*
+ * Standard priority levels for the system.  0 is lowest and 7 is highest.
+ * These values are the ones Atmel uses for its Linux port
+ */
+static const int at91_irq_prio[32] =
+{
+	7,	/* Advanced Interrupt Controller */
+	7,	/* System Peripherals */
+	1,	/* Parallel IO Controller A */
+	1,	/* Parallel IO Controller B */
+	1,	/* Parallel IO Controller C */
+	0,	/* Analog-to-Digital Converter */
+	5,	/* USART 0 */
+	5,	/* USART 1 */
+	5,	/* USART 2 */
+	0,	/* Multimedia Card Interface */
+	2,	/* USB Device Port */
+	6,	/* Two-Wire Interface */
+	5,	/* Serial Peripheral Interface 0 */
+	5,	/* Serial Peripheral Interface 1 */
+	5,	/* Serial Synchronous Controller */
+	0,	/* (reserved) */
+	0,	/* (reserved) */
+	0,	/* Timer Counter 0 */
+	0,	/* Timer Counter 1 */
+	0,	/* Timer Counter 2 */
+	2,	/* USB Host port */
+	3,	/* Ethernet */
+	0,	/* Image Sensor Interface */
+	5,	/* USART 3 */
+	5,	/* USART 4 */
+	5,	/* USART 5 */
+	0,	/* Timer Counter 3 */
+	0,	/* Timer Counter 4 */
+	0,	/* Timer Counter 5 */
+	0,	/* Advanced Interrupt Controller IRQ0 */
+	0,	/* Advanced Interrupt Controller IRQ1 */
+	0,	/* Advanced Interrupt Controller IRQ2 */
+};
+
+static const uint32_t at91_pio_base[] = {
+	AT91SAM9260_PIOA_BASE,
+	AT91SAM9260_PIOB_BASE,
+	AT91SAM9260_PIOC_BASE,
+};
+
+#define	DEVICE(_name, _id, _unit)		\
+	{					\
+		_name, _unit,			\
+		AT91SAM9260_ ## _id ##_BASE,	\
+		AT91SAM9260_ ## _id ## _SIZE,	\
+		AT91SAM9260_IRQ_ ## _id		\
+	}
+
+static const struct cpu_devs at91_devs[] =
+{
+	DEVICE("at91_pmc", PMC,  0),
+	DEVICE("at91_wdt", WDT,  0),
+	DEVICE("at91_rst", RSTC, 0),
+	DEVICE("at91_pit", PIT,  0),
+	DEVICE("at91_pio", PIOA, 0),
+	DEVICE("at91_pio", PIOB, 1),
+	DEVICE("at91_pio", PIOC, 2),
+	DEVICE("at91_twi", TWI, 0),
+	DEVICE("at91_mci", MCI, 0),
+	DEVICE("uart", DBGU,   0),
+	DEVICE("uart", USART0, 1),
+	DEVICE("uart", USART1, 2),
+	DEVICE("uart", USART2, 3),
+	DEVICE("uart", USART3, 4),
+	DEVICE("uart", USART4, 5),
+	DEVICE("uart", USART5, 6),
+	DEVICE("spi",  SPI0,   0),
+	DEVICE("spi",  SPI1,   1),
+	DEVICE("ate",  EMAC,   0),
+	DEVICE("macb", EMAC,   0),
+	DEVICE("nand", NAND,   0),
+	DEVICE("ohci", OHCI,   0),
+	{ 0, 0, 0, 0, 0 }
+};
+
+/*
+ * The following is unused currently since we don't ever set the PLLA
+ * frequency of the device.
+ */
+static uint32_t
+at91_pll_outa(int freq)
+{
+	uint32_t outa = 0;
+
+	/*
+	 * Set OUTA, per the data sheet.  See Table 40-15 titled
+	 * PLLA Characteristics in the SAM9260 doc.
+	 */
+
+	if (freq > 155000000)
+		outa = 2 << 14;
+	return ((1 << 29) | outa);
+}
+
+static uint32_t
+at91_pll_outb(int freq)
+{
+
+	return (1 << 14);
+}
+
+static void
+at91_clock_init(void)
+{
+	struct at91_pmc_clock *clk;
+
+	/* Update USB device port clock info */
+	clk = at91_pmc_clock_ref("udpck");
+	clk->pmc_mask  = PMC_SCER_UDP_SAM9;
+	at91_pmc_clock_deref(clk);
+
+	/* Update USB host port clock info */
+	clk = at91_pmc_clock_ref("uhpck");
+	clk->pmc_mask  = PMC_SCER_UHP_SAM9;
+	at91_pmc_clock_deref(clk);
+
+	/* Each SOC has different PLL contraints */
+	clk = at91_pmc_clock_ref("plla");
+	clk->pll_min_in    = SAM9260_PLL_A_MIN_IN_FREQ;		/*   1 MHz */
+	clk->pll_max_in    = SAM9260_PLL_A_MAX_IN_FREQ;		/*  32 MHz */
+	clk->pll_min_out   = SAM9260_PLL_A_MIN_OUT_FREQ;	/*  80 MHz */
+	clk->pll_max_out   = SAM9260_PLL_A_MAX_OUT_FREQ;	/* 240 MHz */
+	clk->pll_mul_shift = SAM9260_PLL_A_MUL_SHIFT;
+	clk->pll_mul_mask  = SAM9260_PLL_A_MUL_MASK;
+	clk->pll_div_shift = SAM9260_PLL_A_DIV_SHIFT;
+	clk->pll_div_mask  = SAM9260_PLL_A_DIV_MASK;
+	clk->set_outb      = at91_pll_outa;
+	at91_pmc_clock_deref(clk);
+
+	/*
+	 * Fudge MAX pll in frequence down below 3.0 MHz to ensure
+	 * PMC alogrithm choose the divisor that causes the input clock
+	 * to be near the optimal 2 MHz per datasheet.  We know
+	 * we are going to be using this for the USB clock at 96 MHz.
+	 * Causes no extra frequency deviation for all recomended crystal
+	 * values.  See Note 1, table 40-16 SAM9260 doc.
+	 */
+	clk = at91_pmc_clock_ref("pllb");
+	clk->pll_min_in    = SAM9260_PLL_B_MIN_IN_FREQ;		/*   1 MHz */
+	clk->pll_max_in    = SAM9260_PLL_B_MAX_IN_FREQ;		/*   5 MHz */
+	clk->pll_max_in    = 2999999;				/*  ~3 MHz */
+	clk->pll_min_out   = SAM9260_PLL_B_MIN_OUT_FREQ;	/*  70 MHz */
+	clk->pll_max_out   = SAM9260_PLL_B_MAX_OUT_FREQ;	/* 130 MHz */
+	clk->pll_mul_shift = SAM9260_PLL_B_MUL_SHIFT;
+	clk->pll_mul_mask  = SAM9260_PLL_B_MUL_MASK;
+	clk->pll_div_shift = SAM9260_PLL_B_DIV_SHIFT;
+	clk->pll_div_mask  = SAM9260_PLL_B_DIV_MASK;
+	clk->set_outb      = at91_pll_outb;
+	at91_pmc_clock_deref(clk);
+}
+
+static struct at91_soc_data soc_data = {
+	.soc_delay = at91_pit_delay,
+	.soc_reset = at91_rst_cpu_reset,
+	.soc_clock_init = at91_clock_init,
+	.soc_irq_prio = at91_irq_prio,
+	.soc_children = at91_devs,
+	.soc_pio_base = at91_pio_base,
+	.soc_pio_count = nitems(at91_pio_base),
+};
+
+AT91_SOC(AT91_T_SAM9260, &soc_data);


Property changes on: trunk/sys/arm/at91/at91sam9260.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91sam9260reg.h
===================================================================
--- trunk/sys/arm/at91/at91sam9260reg.h	                        (rev 0)
+++ trunk/sys/arm/at91/at91sam9260reg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,304 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2010 Greg Ansley.  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 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 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: stable/10/sys/arm/at91/at91sam9260reg.h 266110 2014-05-15 02:41:23Z ian $ */
+
+#ifndef AT91SAM9260REG_H_
+#define AT91SAM9260REG_H_
+
+/* Chip Specific limits */
+#define SAM9260_PLL_A_MIN_IN_FREQ	  1000000 /*   1 Mhz */
+#define SAM9260_PLL_A_MAX_IN_FREQ	 32000000 /*  32 Mhz */
+#define SAM9260_PLL_A_MIN_OUT_FREQ	 80000000 /*  80 Mhz */
+#define SAM9260_PLL_A_MAX_OUT_FREQ	240000000 /* 240 Mhz */
+#define SAM9260_PLL_A_MUL_SHIFT 16
+#define SAM9260_PLL_A_MUL_MASK 0x3FF
+#define SAM9260_PLL_A_DIV_SHIFT 0
+#define SAM9260_PLL_A_DIV_MASK 0xFF
+
+#define SAM9260_PLL_B_MIN_IN_FREQ	  1000000 /*   1 Mhz */
+#define SAM9260_PLL_B_MAX_IN_FREQ	  5000000 /*   5 Mhz */
+#define SAM9260_PLL_B_MIN_OUT_FREQ	 70000000 /*  70 Mhz */
+#define SAM9260_PLL_B_MAX_OUT_FREQ	130000000 /* 130 Mhz */
+#define SAM9260_PLL_B_MUL_SHIFT 16
+#define SAM9260_PLL_B_MUL_MASK 0x3FF
+#define SAM9260_PLL_B_DIV_SHIFT 0
+#define SAM9260_PLL_B_DIV_MASK 0xFF
+
+/*
+ * Memory map, from datasheet :
+ * 0x00000000 - 0x0ffffffff : Internal Memories
+ * 0x10000000 - 0x1ffffffff : Chip Select 0
+ * 0x20000000 - 0x2ffffffff : Chip Select 1
+ * 0x30000000 - 0x3ffffffff : Chip Select 2
+ * 0x40000000 - 0x4ffffffff : Chip Select 3
+ * 0x50000000 - 0x5ffffffff : Chip Select 4
+ * 0x60000000 - 0x6ffffffff : Chip Select 5
+ * 0x70000000 - 0x7ffffffff : Chip Select 6
+ * 0x80000000 - 0x8ffffffff : Chip Select 7
+ * 0x90000000 - 0xeffffffff : Undefined (Abort)
+ * 0xf0000000 - 0xfffffffff : Peripherals
+ */
+
+#define AT91_CHIPSELECT_0 0x10000000
+#define AT91_CHIPSELECT_1 0x20000000
+#define AT91_CHIPSELECT_2 0x30000000
+#define AT91_CHIPSELECT_3 0x40000000
+#define AT91_CHIPSELECT_4 0x50000000
+#define AT91_CHIPSELECT_5 0x60000000
+#define AT91_CHIPSELECT_6 0x70000000
+#define AT91_CHIPSELECT_7 0x80000000
+
+
+#define AT91SAM9260_EMAC_BASE 0xffc4000
+#define AT91SAM9260_EMAC_SIZE 0x4000
+
+#define AT91SAM9260_RSTC_BASE	0xffffd00
+#define AT91SAM9260_RSTC_SIZE	0x10
+
+#define RSTC_CR			0
+#define RSTC_PROCRST		(1 << 0)
+#define RSTC_PERRST		(1 << 2)
+#define RSTC_KEY		(0xa5 << 24)
+
+/* USART*/
+
+#define AT91SAM9260_USART_SIZE	0x4000
+#define AT91SAM9260_USART0_BASE	0xffb0000
+#define AT91SAM9260_USART0_PDC	0xffb0100
+#define AT91SAM9260_USART0_SIZE	AT91SAM9260_USART_SIZE
+#define AT91SAM9260_USART1_BASE	0xffb4000
+#define AT91SAM9260_USART1_PDC	0xffb4100
+#define AT91SAM9260_USART1_SIZE	AT91SAM9260_USART_SIZE
+#define AT91SAM9260_USART2_BASE	0xffb8000
+#define AT91SAM9260_USART2_PDC	0xffb8100
+#define AT91SAM9260_USART2_SIZE	AT91SAM9260_USART_SIZE
+#define AT91SAM9260_USART3_BASE	0xffd0000
+#define AT91SAM9260_USART3_PDC	0xffd0100
+#define AT91SAM9260_USART3_SIZE	AT91SAM9260_USART_SIZE
+#define AT91SAM9260_USART4_BASE	0xffd4000
+#define AT91SAM9260_USART4_PDC	0xffd4100
+#define AT91SAM9260_USART4_SIZE	AT91SAM9260_USART_SIZE
+#define AT91SAM9260_USART5_BASE	0xffd8000
+#define AT91SAM9260_USART5_PDC	0xffd8100
+#define AT91SAM9260_USART5_SIZE	AT91SAM9260_USART_SIZE
+
+/*TC*/
+#define AT91SAM9260_TC0_BASE	0xffa0000
+#define AT91SAM9260_TC0_SIZE	0x4000
+#define AT91SAM9260_TC0C0_BASE	0xffa0000
+#define AT91SAM9260_TC0C1_BASE	0xffa0040
+#define AT91SAM9260_TC0C2_BASE	0xffa0080
+
+#define AT91SAM9260_TC1_BASE	0xffdc000
+#define AT91SAM9260_TC1_SIZE	0x4000
+
+/*SPI*/
+
+#define AT91SAM9260_SPI0_BASE	0xffc8000
+
+#define AT91SAM9260_SPI0_SIZE	0x4000
+#define AT91SAM9260_IRQ_SPI0	12
+
+#define AT91SAM9260_SPI1_BASE	0xffcc000
+#define AT91SAM9260_SPI1_SIZE	0x4000
+#define AT91SAM9260_IRQ_SPI1	13
+
+/* System Registers */
+#define AT91SAM9260_SYS_BASE	0xffff000
+#define AT91SAM9260_SYS_SIZE	0x1000
+
+#define AT91SAM9260_MATRIX_BASE	0xfffee00
+#define AT91SAM9260_MATRIX_SIZE	0x1000
+#define AT91SAM9260_EBICSA	0x011C
+
+#define AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA	(1 << 3)
+
+#define AT91SAM9260_DBGU_BASE	0xffff200
+#define AT91SAM9260_DBGU_SIZE	0x200
+
+/*
+ * PIO
+ */
+#define AT91SAM9260_PIOA_BASE	0xffff400
+#define AT91SAM9260_PIOA_SIZE	0x200
+#define AT91SAM9260_PIOB_BASE	0xffff600
+#define AT91SAM9260_PIOB_SIZE	0x200
+#define AT91SAM9260_PIOC_BASE	0xffff800
+#define AT91SAM9260_PIOC_SIZE	0x200
+
+#define AT91RM92_PMC_BASE	0xffffc00
+#define AT91RM92_PMC_SIZE	0x100
+/* IRQs : */
+/*
+ * 0: AIC
+ * 1: System peripheral (System timer, RTC, DBGU)
+ * 2: PIO Controller A
+ * 3: PIO Controller B
+ * 4: PIO Controller C
+ * 5: ADC
+ * 6: USART 0
+ * 7: USART 1
+ * 8: USART 2
+ * 9: MMC Interface
+ * 10: USB device port
+ * 11: Two-wirte interface
+ * 12: SPI 0
+ * 13: SPI 1
+ * 14: SSC
+ * 15: - (reserved)
+ * 16: - (reserved)
+ * 17: Timer Counter 0
+ * 18: Timer Counter 1
+ * 19: Timer Counter 2
+ * 20: USB Host port
+ * 21: EMAC
+ * 22: ISI
+ * 23: USART 3
+ * 24: USART 4
+ * 25: USART 2
+ * 26: Timer Counter 3
+ * 27: Timer Counter 4
+ * 28: Timer Counter 5
+ * 29: AIC IRQ0
+ * 30: AIC IRQ1
+ * 31: AIC IRQ2
+ */
+
+#define AT91SAM9260_IRQ_SYSTEM	1
+#define AT91SAM9260_IRQ_PIOA	2
+#define AT91SAM9260_IRQ_PIOB	3
+#define AT91SAM9260_IRQ_PIOC	4
+#define AT91SAM9260_IRQ_USART0	6
+#define AT91SAM9260_IRQ_USART1	7
+#define AT91SAM9260_IRQ_USART2	8
+#define AT91SAM9260_IRQ_MCI	9
+#define AT91SAM9260_IRQ_UDP	10
+#define AT91SAM9260_IRQ_TWI	11
+#define AT91SAM9260_IRQ_SPI0	12
+#define AT91SAM9260_IRQ_SPI1	13
+#define AT91SAM9260_IRQ_SSC0	14
+#define AT91SAM9260_IRQ_SSC1	15
+#define AT91SAM9260_IRQ_SSC2	16
+#define AT91SAM9260_IRQ_TC0	17
+#define AT91SAM9260_IRQ_TC1	18
+#define AT91SAM9260_IRQ_TC2	19
+#define AT91SAM9260_IRQ_UHP	20
+#define AT91SAM9260_IRQ_EMAC	21
+#define AT91SAM9260_IRQ_USART3	23
+#define AT91SAM9260_IRQ_USART4	24
+#define AT91SAM9260_IRQ_USART5	25
+#define AT91SAM9260_IRQ_AICBASE	29
+
+/* Alias */
+#define AT91SAM9260_IRQ_DBGU 	AT91SAM9260_IRQ_SYSTEM
+#define AT91SAM9260_IRQ_PMC 	AT91SAM9260_IRQ_SYSTEM
+#define AT91SAM9260_IRQ_WDT 	AT91SAM9260_IRQ_SYSTEM
+#define AT91SAM9260_IRQ_PIT 	AT91SAM9260_IRQ_SYSTEM
+#define AT91SAM9260_IRQ_RSTC 	AT91SAM9260_IRQ_SYSTEM
+#define AT91SAM9260_IRQ_OHCI 	AT91SAM9260_IRQ_UHP
+#define AT91SAM9260_IRQ_NAND 	(-1)
+
+#define AT91SAM9260_AIC_BASE	0xffff000
+#define AT91SAM9260_AIC_SIZE	0x200
+
+/* Timer */
+
+#define AT91SAM9260_WDT_BASE	0xffffd40
+#define AT91SAM9260_WDT_SIZE	0x10
+
+#define AT91SAM9260_PIT_BASE	0xffffd30
+#define AT91SAM9260_PIT_SIZE	10
+
+#define AT91SAM9260_SMC_BASE	0xfffec00
+#define AT91SAM9260_SMC_SIZE	0x200
+
+#define AT91SAM9260_PMC_BASE	0xffffc00
+#define AT91SAM9260_PMC_SIZE	0x100
+
+#define AT91SAM9260_UDP_BASE	0xffa4000
+#define AT91SAM9260_UDP_SIZE	0x4000
+
+#define AT91SAM9260_MCI_BASE	0xffa8000
+#define AT91SAM9260_MCI_SIZE	0x4000
+
+#define AT91SAM9260_TWI_BASE	0xffaC000
+#define AT91SAM9260_TWI_SIZE	0x4000
+
+/* XXX Needs to be carfully coordinated with
+ * other * soc's so phyical and vm address
+ * mapping are unique. XXX
+ */
+#define AT91SAM9260_OHCI_VA_BASE  0xdfc00000
+#define AT91SAM9260_OHCI_BASE     0x00500000
+#define AT91SAM9260_OHCI_SIZE	  0x00100000
+
+#define AT91SAM9260_NAND_VA_BASE  0xe0000000
+#define AT91SAM9260_NAND_BASE     0x40000000
+#define AT91SAM9260_NAND_SIZE     0x10000000
+
+
+/* SDRAMC */
+#define AT91SAM9260_SDRAMC_BASE	0xfffea00
+#define AT91SAM9260_SDRAMC_MR	0x00
+#define AT91SAM9260_SDRAMC_MR_MODE_NORMAL	0
+#define AT91SAM9260_SDRAMC_MR_MODE_NOP	1
+#define AT91SAM9260_SDRAMC_MR_MODE_PRECHARGE 2
+#define AT91SAM9260_SDRAMC_MR_MODE_LOAD_MODE_REGISTER 3
+#define AT91SAM9260_SDRAMC_MR_MODE_REFRESH	4
+#define AT91SAM9260_SDRAMC_TR	0x04
+#define AT91SAM9260_SDRAMC_CR	0x08
+#define AT91SAM9260_SDRAMC_CR_NC_8		0x0
+#define AT91SAM9260_SDRAMC_CR_NC_9		0x1
+#define AT91SAM9260_SDRAMC_CR_NC_10	0x2
+#define AT91SAM9260_SDRAMC_CR_NC_11	0x3
+#define AT91SAM9260_SDRAMC_CR_NC_MASK	0x00000003
+#define AT91SAM9260_SDRAMC_CR_NR_11	0x0
+#define AT91SAM9260_SDRAMC_CR_NR_12	0x4
+#define AT91SAM9260_SDRAMC_CR_NR_13	0x8
+#define AT91SAM9260_SDRAMC_CR_NR_RES	0xc
+#define AT91SAM9260_SDRAMC_CR_NR_MASK	0x0000000c
+#define AT91SAM9260_SDRAMC_CR_NB_2		0x00
+#define AT91SAM9260_SDRAMC_CR_NB_4		0x10
+#define AT91SAM9260_SDRAMC_CR_DBW_16		0x80
+#define AT91SAM9260_SDRAMC_CR_NB_MASK	0x00000010
+#define AT91SAM9260_SDRAMC_CR_NCAS_MASK	0x00000060
+#define AT91SAM9260_SDRAMC_CR_TWR_MASK	0x00000780
+#define AT91SAM9260_SDRAMC_CR_TRC_MASK	0x00007800
+#define AT91SAM9260_SDRAMC_CR_TRP_MASK	0x00078000
+#define AT91SAM9260_SDRAMC_CR_TRCD_MASK	0x00780000
+#define AT91SAM9260_SDRAMC_CR_TRAS_MASK	0x07800000
+#define AT91SAM9260_SDRAMC_CR_TXSR_MASK	0x78000000
+#define AT91SAM9260_SDRAMC_HSR	0x0c
+#define AT91SAM9260_SDRAMC_LPR	0x10
+#define AT91SAM9260_SDRAMC_IER	0x14
+#define AT91SAM9260_SDRAMC_IDR	0x18
+#define AT91SAM9260_SDRAMC_IMR	0x1c
+#define AT91SAM9260_SDRAMC_ISR	0x20
+#define AT91SAM9260_SDRAMC_MDR	0x24
+
+#endif /* AT91SAM9260REG_H_*/
+


Property changes on: trunk/sys/arm/at91/at91sam9260reg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91sam9g20.c
===================================================================
--- trunk/sys/arm/at91/at91sam9g20.c	                        (rev 0)
+++ trunk/sys/arm/at91/at91sam9g20.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,184 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2005 Olivier Houchard.  All rights reserved.
+ * Copyright (c) 2010 Greg Ansley.  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 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 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: stable/10/sys/arm/at91/at91sam9g20.c 266277 2014-05-17 00:53:12Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+
+#define	_ARM32_BUS_DMA_PRIVATE
+#include <machine/bus.h>
+
+#include <arm/at91/at91var.h>
+#include <arm/at91/at91reg.h>
+#include <arm/at91/at91soc.h>
+#include <arm/at91/at91_aicreg.h>
+#include <arm/at91/at91sam9g20reg.h>
+#include <arm/at91/at91_pitreg.h>
+#include <arm/at91/at91_pmcreg.h>
+#include <arm/at91/at91_pmcvar.h>
+#include <arm/at91/at91_rstreg.h>
+
+/*
+ * Standard priority levels for the system.  0 is lowest and 7 is highest.
+ * These values are the ones Atmel uses for its Linux port
+ */
+static const int at91_irq_prio[32] =
+{
+	7,	/* Advanced Interrupt Controller */
+	7,	/* System Peripherals */
+	1,	/* Parallel IO Controller A */
+	1,	/* Parallel IO Controller B */
+	1,	/* Parallel IO Controller C */
+	0,	/* Analog-to-Digital Converter */
+	5,	/* USART 0 */
+	5,	/* USART 1 */
+	5,	/* USART 2 */
+	0,	/* Multimedia Card Interface */
+	2,	/* USB Device Port */
+	6,	/* Two-Wire Interface */
+	5,	/* Serial Peripheral Interface 0 */
+	5,	/* Serial Peripheral Interface 1 */
+	5,	/* Serial Synchronous Controller */
+	0,	/* (reserved) */
+	0,	/* (reserved) */
+	0,	/* Timer Counter 0 */
+	0,	/* Timer Counter 1 */
+	0,	/* Timer Counter 2 */
+	2,	/* USB Host port */
+	3,	/* Ethernet */
+	0,	/* Image Sensor Interface */
+	5,	/* USART 3 */
+	5,	/* USART 4 */
+	5,	/* USART 5 */
+	0,	/* Timer Counter 3 */
+	0,	/* Timer Counter 4 */
+	0,	/* Timer Counter 5 */
+	0,	/* Advanced Interrupt Controller IRQ0 */
+	0,	/* Advanced Interrupt Controller IRQ1 */
+	0,	/* Advanced Interrupt Controller IRQ2 */
+};
+
+static const uint32_t at91_pio_base[] = {
+	AT91SAM9G20_PIOA_BASE,
+	AT91SAM9G20_PIOB_BASE,
+	AT91SAM9G20_PIOC_BASE,
+};
+
+#define DEVICE(_name, _id, _unit)		\
+	{					\
+		_name, _unit,			\
+		AT91SAM9G20_ ## _id ##_BASE,	\
+		AT91SAM9G20_ ## _id ## _SIZE,	\
+		AT91SAM9G20_IRQ_ ## _id		\
+	}
+
+static const struct cpu_devs at91_devs[] =
+{
+	DEVICE("at91_aic", AIC,  0),
+	DEVICE("at91_pmc", PMC,  0),
+	DEVICE("at91_wdt", WDT,  0),
+	DEVICE("at91_rst", RSTC, 0),
+	DEVICE("at91_pit", PIT,  0),
+	DEVICE("at91_pio", PIOA, 0),
+	DEVICE("at91_pio", PIOB, 1),
+	DEVICE("at91_pio", PIOC, 2),
+	DEVICE("at91_twi", TWI, 0),
+	DEVICE("at91_mci", MCI, 0),
+	DEVICE("uart", DBGU,   0),
+	DEVICE("uart", USART0, 1),
+	DEVICE("uart", USART1, 2),
+	DEVICE("uart", USART2, 3),
+	DEVICE("uart", USART3, 4),
+	DEVICE("uart", USART4, 5),
+	DEVICE("uart", USART5, 6),
+	DEVICE("spi",  SPI0,   0),
+	DEVICE("spi",  SPI1,   1),
+	DEVICE("ate",  EMAC,   0),
+	DEVICE("macb", EMAC,   0),
+	DEVICE("nand", NAND,   0),
+	DEVICE("ohci", OHCI,   0),
+	{ 0, 0, 0, 0, 0 }
+};
+
+static void
+at91_clock_init(void)
+{
+	struct at91_pmc_clock *clk;
+
+	/* Update USB device port clock info */
+	clk = at91_pmc_clock_ref("udpck");
+	clk->pmc_mask  = PMC_SCER_UDP_SAM9;
+	at91_pmc_clock_deref(clk);
+
+	/* Update USB host port clock info */
+	clk = at91_pmc_clock_ref("uhpck");
+	clk->pmc_mask  = PMC_SCER_UHP_SAM9;
+	at91_pmc_clock_deref(clk);
+
+	/* Each SOC has different PLL contraints */
+	clk = at91_pmc_clock_ref("plla");
+	clk->pll_min_in    = SAM9G20_PLL_A_MIN_IN_FREQ;		/*   2 MHz */
+	clk->pll_max_in    = SAM9G20_PLL_A_MAX_IN_FREQ;		/*  32 MHz */
+	clk->pll_min_out   = SAM9G20_PLL_A_MIN_OUT_FREQ;	/* 400 MHz */
+	clk->pll_max_out   = SAM9G20_PLL_A_MAX_OUT_FREQ;	/* 800 MHz */
+	clk->pll_mul_shift = SAM9G20_PLL_A_MUL_SHIFT;
+	clk->pll_mul_mask  = SAM9G20_PLL_A_MUL_MASK;
+	clk->pll_div_shift = SAM9G20_PLL_A_DIV_SHIFT;
+	clk->pll_div_mask  = SAM9G20_PLL_A_DIV_MASK;
+	clk->set_outb      = at91_pmc_800mhz_plla_outb;
+	at91_pmc_clock_deref(clk);
+
+	clk = at91_pmc_clock_ref("pllb");
+	clk->pll_min_in    = SAM9G20_PLL_B_MIN_IN_FREQ;		/*   2 MHz */
+	clk->pll_max_in    = SAM9G20_PLL_B_MAX_IN_FREQ;		/*  32 MHz */
+	clk->pll_min_out   = SAM9G20_PLL_B_MIN_OUT_FREQ;	/*  30 MHz */
+	clk->pll_max_out   = SAM9G20_PLL_B_MAX_OUT_FREQ;	/* 100 MHz */
+	clk->pll_mul_shift = SAM9G20_PLL_B_MUL_SHIFT;
+	clk->pll_mul_mask  = SAM9G20_PLL_B_MUL_MASK;
+	clk->pll_div_shift = SAM9G20_PLL_B_DIV_SHIFT;
+	clk->pll_div_mask  = SAM9G20_PLL_B_DIV_MASK;
+	clk->set_outb      = at91_pmc_800mhz_pllb_outb;
+	at91_pmc_clock_deref(clk);
+}
+
+static struct at91_soc_data soc_data = {
+	.soc_delay = at91_pit_delay,
+	.soc_reset = at91_rst_cpu_reset,
+	.soc_clock_init = at91_clock_init,
+	.soc_irq_prio = at91_irq_prio,
+	.soc_children = at91_devs,
+	.soc_pio_base = at91_pio_base,
+	.soc_pio_count = nitems(at91_pio_base),
+};
+
+AT91_SOC(AT91_T_SAM9G20, &soc_data);


Property changes on: trunk/sys/arm/at91/at91sam9g20.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91sam9g20reg.h
===================================================================
--- trunk/sys/arm/at91/at91sam9g20reg.h	                        (rev 0)
+++ trunk/sys/arm/at91/at91sam9g20reg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,305 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2009 Sylvestre Gallon.  All rights reserved.
+ * Copyright (c) 2010 Greg Ansley.  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 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 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: stable/10/sys/arm/at91/at91sam9g20reg.h 266277 2014-05-17 00:53:12Z ian $ */
+
+#ifndef AT91SAM9G20REG_H_
+#define AT91SAM9G20REG_H_
+
+/* Chip Specific limits */
+#define SAM9G20_PLL_A_MIN_IN_FREQ	  2000000 /*   2 Mhz */
+#define SAM9G20_PLL_A_MAX_IN_FREQ	 32000000 /*  32 Mhz */
+#define SAM9G20_PLL_A_MIN_OUT_FREQ	400000000 /* 400 Mhz */
+#define SAM9G20_PLL_A_MAX_OUT_FREQ	800000000 /* 800 Mhz */
+#define SAM9G20_PLL_A_MUL_SHIFT 16
+#define SAM9G20_PLL_A_MUL_MASK 0xFF
+#define SAM9G20_PLL_A_DIV_SHIFT 0
+#define SAM9G20_PLL_A_DIV_MASK 0xFF
+
+#define SAM9G20_PLL_B_MIN_IN_FREQ	  2000000 /*   2 Mhz */
+#define SAM9G20_PLL_B_MAX_IN_FREQ	 32000000 /*  32 Mhz */
+#define SAM9G20_PLL_B_MIN_OUT_FREQ	 30000000 /*  30 Mhz */
+#define SAM9G20_PLL_B_MAX_OUT_FREQ	100000000 /* 100 Mhz */
+#define SAM9G20_PLL_B_MUL_SHIFT 16
+#define SAM9G20_PLL_B_MUL_MASK 0x3F
+#define SAM9G20_PLL_B_DIV_SHIFT 0
+#define SAM9G20_PLL_B_DIV_MASK 0xFF
+
+/*
+ * Memory map, from datasheet :
+ * 0x00000000 - 0x0ffffffff : Internal Memories
+ * 0x10000000 - 0x1ffffffff : Chip Select 0
+ * 0x20000000 - 0x2ffffffff : Chip Select 1
+ * 0x30000000 - 0x3ffffffff : Chip Select 2
+ * 0x40000000 - 0x4ffffffff : Chip Select 3
+ * 0x50000000 - 0x5ffffffff : Chip Select 4
+ * 0x60000000 - 0x6ffffffff : Chip Select 5
+ * 0x70000000 - 0x7ffffffff : Chip Select 6
+ * 0x80000000 - 0x8ffffffff : Chip Select 7
+ * 0x90000000 - 0xeffffffff : Undefined (Abort)
+ * 0xf0000000 - 0xfffffffff : Peripherals
+ */
+
+#define AT91_CHIPSELECT_0 0x10000000
+#define AT91_CHIPSELECT_1 0x20000000
+#define AT91_CHIPSELECT_2 0x30000000
+#define AT91_CHIPSELECT_3 0x40000000
+#define AT91_CHIPSELECT_4 0x50000000
+#define AT91_CHIPSELECT_5 0x60000000
+#define AT91_CHIPSELECT_6 0x70000000
+#define AT91_CHIPSELECT_7 0x80000000
+
+
+#define AT91SAM9G20_EMAC_BASE 0xffc4000
+#define AT91SAM9G20_EMAC_SIZE 0x4000
+
+#define AT91SAM9G20_RSTC_BASE	0xffffd00
+#define AT91SAM9G20_RSTC_SIZE	0x10
+
+#define RSTC_CR			0
+#define RSTC_PROCRST		(1 << 0)
+#define RSTC_PERRST		(1 << 2)
+#define RSTC_KEY		(0xa5 << 24)
+
+/* USART*/
+
+#define AT91SAM9G20_USART_SIZE	0x4000
+#define AT91SAM9G20_USART0_BASE	0xffb0000
+#define AT91SAM9G20_USART0_PDC	0xffb0100
+#define AT91SAM9G20_USART0_SIZE	AT91SAM9G20_USART_SIZE
+#define AT91SAM9G20_USART1_BASE	0xffb4000
+#define AT91SAM9G20_USART1_PDC	0xffb4100
+#define AT91SAM9G20_USART1_SIZE	AT91SAM9G20_USART_SIZE
+#define AT91SAM9G20_USART2_BASE	0xffb8000
+#define AT91SAM9G20_USART2_PDC	0xffb8100
+#define AT91SAM9G20_USART2_SIZE	AT91SAM9G20_USART_SIZE
+#define AT91SAM9G20_USART3_BASE	0xffd0000
+#define AT91SAM9G20_USART3_PDC	0xffd0100
+#define AT91SAM9G20_USART3_SIZE	AT91SAM9G20_USART_SIZE
+#define AT91SAM9G20_USART4_BASE	0xffd4000
+#define AT91SAM9G20_USART4_PDC	0xffd4100
+#define AT91SAM9G20_USART4_SIZE	AT91SAM9G20_USART_SIZE
+#define AT91SAM9G20_USART5_BASE	0xffd8000
+#define AT91SAM9G20_USART5_PDC	0xffd8100
+#define AT91SAM9G20_USART5_SIZE	AT91SAM9G20_USART_SIZE
+
+/*TC*/
+#define AT91SAM9G20_TC0_BASE	0xffa0000
+#define AT91SAM9G20_TC0_SIZE	0x4000
+#define AT91SAM9G20_TC0C0_BASE	0xffa0000
+#define AT91SAM9G20_TC0C1_BASE	0xffa0040
+#define AT91SAM9G20_TC0C2_BASE	0xffa0080
+
+#define AT91SAM9G20_TC1_BASE	0xffdc000
+#define AT91SAM9G20_TC1_SIZE	0x4000
+
+/*SPI*/
+
+#define AT91SAM9G20_SPI0_BASE	0xffc8000
+
+#define AT91SAM9G20_SPI0_SIZE	0x4000
+#define AT91SAM9G20_IRQ_SPI0	12
+
+#define AT91SAM9G20_SPI1_BASE	0xffcc000
+#define AT91SAM9G20_SPI1_SIZE	0x4000
+#define AT91SAM9G20_IRQ_SPI1	13
+
+/* System Registers */
+#define AT91SAM9G20_SYS_BASE	0xffff000
+#define AT91SAM9G20_SYS_SIZE	0x1000
+
+#define AT91SAM9G20_MATRIX_BASE	0xfffee00
+#define AT91SAM9G20_MATRIX_SIZE	0x1000
+#define AT91SAM9G20_EBICSA	0x011C
+
+#define AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA	(1 << 3)
+
+#define AT91SAM9G20_DBGU_BASE	0xffff200
+#define AT91SAM9G20_DBGU_SIZE	0x200
+
+/*
+ * PIO
+ */
+#define AT91SAM9G20_PIOA_BASE	0xffff400
+#define AT91SAM9G20_PIOA_SIZE	0x200
+#define AT91SAM9G20_PIOB_BASE	0xffff600
+#define AT91SAM9G20_PIOB_SIZE	0x200
+#define AT91SAM9G20_PIOC_BASE	0xffff800
+#define AT91SAM9G20_PIOC_SIZE	0x200
+
+#define AT91RM92_PMC_BASE	0xffffc00
+#define AT91RM92_PMC_SIZE	0x100
+/* IRQs : */
+/*
+ * 0: AIC
+ * 1: System peripheral (System timer, RTC, DBGU)
+ * 2: PIO Controller A
+ * 3: PIO Controller B
+ * 4: PIO Controller C
+ * 5: ADC
+ * 6: USART 0
+ * 7: USART 1
+ * 8: USART 2
+ * 9: MMC Interface
+ * 10: USB device port
+ * 11: Two-wirte interface
+ * 12: SPI 0
+ * 13: SPI 1
+ * 14: SSC
+ * 15: - (reserved)
+ * 16: - (reserved)
+ * 17: Timer Counter 0
+ * 18: Timer Counter 1
+ * 19: Timer Counter 2
+ * 20: USB Host port
+ * 21: EMAC
+ * 22: ISI
+ * 23: USART 3
+ * 24: USART 4
+ * 25: USART 2
+ * 26: Timer Counter 3
+ * 27: Timer Counter 4
+ * 28: Timer Counter 5
+ * 29: AIC IRQ0
+ * 30: AIC IRQ1
+ * 31: AIC IRQ2
+ */
+
+#define AT91SAM9G20_IRQ_SYSTEM	1
+#define AT91SAM9G20_IRQ_PIOA	2
+#define AT91SAM9G20_IRQ_PIOB	3
+#define AT91SAM9G20_IRQ_PIOC	4
+#define AT91SAM9G20_IRQ_USART0	6
+#define AT91SAM9G20_IRQ_USART1	7
+#define AT91SAM9G20_IRQ_USART2	8
+#define AT91SAM9G20_IRQ_MCI	9
+#define AT91SAM9G20_IRQ_UDP	10
+#define AT91SAM9G20_IRQ_TWI	11
+#define AT91SAM9G20_IRQ_SPI0	12
+#define AT91SAM9G20_IRQ_SPI1	13
+#define AT91SAM9G20_IRQ_SSC0	14
+#define AT91SAM9G20_IRQ_SSC1	15
+#define AT91SAM9G20_IRQ_SSC2	16
+#define AT91SAM9G20_IRQ_TC0	17
+#define AT91SAM9G20_IRQ_TC1	18
+#define AT91SAM9G20_IRQ_TC2	19
+#define AT91SAM9G20_IRQ_UHP	20
+#define AT91SAM9G20_IRQ_EMAC	21
+#define AT91SAM9G20_IRQ_USART3	23
+#define AT91SAM9G20_IRQ_USART4	24
+#define AT91SAM9G20_IRQ_USART5	25
+#define AT91SAM9G20_IRQ_AICBASE	29
+
+/* Alias */
+#define AT91SAM9G20_IRQ_DBGU 	AT91SAM9G20_IRQ_SYSTEM
+#define AT91SAM9G20_IRQ_PMC 	AT91SAM9G20_IRQ_SYSTEM
+#define AT91SAM9G20_IRQ_WDT 	AT91SAM9G20_IRQ_SYSTEM
+#define AT91SAM9G20_IRQ_PIT 	AT91SAM9G20_IRQ_SYSTEM
+#define AT91SAM9G20_IRQ_RSTC 	AT91SAM9G20_IRQ_SYSTEM
+#define AT91SAM9G20_IRQ_OHCI 	AT91SAM9G20_IRQ_UHP
+#define AT91SAM9G20_IRQ_NAND 	(-1)
+#define AT91SAM9G20_IRQ_AIC	(-1)
+
+#define AT91SAM9G20_AIC_BASE	0xffff000
+#define AT91SAM9G20_AIC_SIZE	0x200
+
+/* Timer */
+
+#define AT91SAM9G20_WDT_BASE	0xffffd40
+#define AT91SAM9G20_WDT_SIZE	0x10
+
+#define AT91SAM9G20_PIT_BASE	0xffffd30
+#define AT91SAM9G20_PIT_SIZE	0x10
+
+#define AT91SAM9G20_SMC_BASE	0xfffec00
+#define AT91SAM9G20_SMC_SIZE	0x200
+
+#define AT91SAM9G20_PMC_BASE	0xffffc00
+#define AT91SAM9G20_PMC_SIZE	0x100
+
+#define AT91SAM9G20_UDP_BASE	0xffa4000
+#define AT91SAM9G20_UDP_SIZE	0x4000
+
+#define AT91SAM9G20_MCI_BASE	0xffa8000
+#define AT91SAM9G20_MCI_SIZE	0x4000
+
+#define AT91SAM9G20_TWI_BASE	0xffaC000
+#define AT91SAM9G20_TWI_SIZE	0x4000
+
+/* XXX Needs to be carfully coordinated with
+ * other * soc's so phyical and vm address
+ * mapping are unique. XXX
+ */
+#define AT91SAM9G20_OHCI_VA_BASE  0xdfc00000
+#define AT91SAM9G20_OHCI_BASE	0x00500000
+#define AT91SAM9G20_OHCI_SIZE	0x00100000
+
+#define AT91SAM9G20_NAND_VA_BASE 0xe0000000
+#define AT91SAM9G20_NAND_BASE	0x40000000
+#define AT91SAM9G20_NAND_SIZE	0x10000000
+
+/* SDRAMC */
+#define AT91SAM9G20_SDRAMC_BASE	0xfffea00
+#define AT91SAM9G20_SDRAMC_MR	0x00
+#define AT91SAM9G20_SDRAMC_MR_MODE_NORMAL	0
+#define AT91SAM9G20_SDRAMC_MR_MODE_NOP	1
+#define AT91SAM9G20_SDRAMC_MR_MODE_PRECHARGE 2
+#define AT91SAM9G20_SDRAMC_MR_MODE_LOAD_MODE_REGISTER 3
+#define AT91SAM9G20_SDRAMC_MR_MODE_REFRESH	4
+#define AT91SAM9G20_SDRAMC_TR	0x04
+#define AT91SAM9G20_SDRAMC_CR	0x08
+#define AT91SAM9G20_SDRAMC_CR_NC_8		0x0
+#define AT91SAM9G20_SDRAMC_CR_NC_9		0x1
+#define AT91SAM9G20_SDRAMC_CR_NC_10	0x2
+#define AT91SAM9G20_SDRAMC_CR_NC_11	0x3
+#define AT91SAM9G20_SDRAMC_CR_NC_MASK	0x00000003
+#define AT91SAM9G20_SDRAMC_CR_NR_11	0x0
+#define AT91SAM9G20_SDRAMC_CR_NR_12	0x4
+#define AT91SAM9G20_SDRAMC_CR_NR_13	0x8
+#define AT91SAM9G20_SDRAMC_CR_NR_RES	0xc
+#define AT91SAM9G20_SDRAMC_CR_NR_MASK	0x0000000c
+#define AT91SAM9G20_SDRAMC_CR_NB_2		0x00
+#define AT91SAM9G20_SDRAMC_CR_NB_4		0x10
+#define AT91SAM9G20_SDRAMC_CR_DBW_16		0x80
+#define AT91SAM9G20_SDRAMC_CR_NB_MASK	0x00000010
+#define AT91SAM9G20_SDRAMC_CR_NCAS_MASK	0x00000060
+#define AT91SAM9G20_SDRAMC_CR_TWR_MASK	0x00000780
+#define AT91SAM9G20_SDRAMC_CR_TRC_MASK	0x00007800
+#define AT91SAM9G20_SDRAMC_CR_TRP_MASK	0x00078000
+#define AT91SAM9G20_SDRAMC_CR_TRCD_MASK	0x00780000
+#define AT91SAM9G20_SDRAMC_CR_TRAS_MASK	0x07800000
+#define AT91SAM9G20_SDRAMC_CR_TXSR_MASK	0x78000000
+#define AT91SAM9G20_SDRAMC_HSR	0x0c
+#define AT91SAM9G20_SDRAMC_LPR	0x10
+#define AT91SAM9G20_SDRAMC_IER	0x14
+#define AT91SAM9G20_SDRAMC_IDR	0x18
+#define AT91SAM9G20_SDRAMC_IMR	0x1c
+#define AT91SAM9G20_SDRAMC_ISR	0x20
+#define AT91SAM9G20_SDRAMC_MDR	0x24
+
+#endif /* AT91SAM9G20REG_H_*/
+


Property changes on: trunk/sys/arm/at91/at91sam9g20reg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91sam9g45.c
===================================================================
--- trunk/sys/arm/at91/at91sam9g45.c	                        (rev 0)
+++ trunk/sys/arm/at91/at91sam9g45.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,171 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2005 Olivier Houchard.  All rights reserved.
+ * Copyright (c) 2010 Greg Ansley.  All rights reserved.
+ * Copyright (c) 2012 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 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 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: stable/10/sys/arm/at91/at91sam9g45.c 266087 2014-05-14 20:31:54Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+
+#define	_ARM32_BUS_DMA_PRIVATE
+#include <machine/bus.h>
+
+#include <arm/at91/at91var.h>
+#include <arm/at91/at91reg.h>
+#include <arm/at91/at91soc.h>
+#include <arm/at91/at91_aicreg.h>
+#include <arm/at91/at91sam9g45reg.h>
+#include <arm/at91/at91_pitreg.h>
+#include <arm/at91/at91_pmcreg.h>
+#include <arm/at91/at91_pmcvar.h>
+#include <arm/at91/at91_rstreg.h>
+
+/*
+ * Standard priority levels for the system.  0 is lowest and 7 is highest.
+ * These values are the ones Atmel uses for its Linux port
+ */
+static const int at91_irq_prio[32] =
+{
+	7,	/* Advanced Interrupt Controller */
+	7,	/* System Peripherals */
+	1,	/* Parallel IO Controller A */
+	1,	/* Parallel IO Controller B */
+	1,	/* Parallel IO Controller C */
+	1,	/* Parallel IO Controller D and E */
+	0,
+	5,	/* USART 0 */
+	5,	/* USART 1 */
+	5,	/* USART 2 */
+	5,	/* USART 3 */
+	0,	/* Multimedia Card Interface 0 */
+	6,	/* Two-Wire Interface 0 */
+	6,	/* Two-Wire Interface 1 */
+	5,	/* Serial Peripheral Interface 0 */
+	5,	/* Serial Peripheral Interface 1 */
+	4,	/* Serial Synchronous Controller 0 */
+	4,	/* Serial Synchronous Controller 1 */
+	0,	/* Timer Counter 0, 1, 2, 3, 4 and 5 */
+	0,	/* Pulse Width Modulation Controller */
+	0,	/* Touch Screen Controller */
+	0,	/* DMA Controller */
+	2,	/* USB Host High Speed port */
+	3,	/* LCD Controller */
+	5,	/* AC97 Controller */
+	3,	/* Ethernet */
+	0,	/* Image Sensor Interface */
+	2,	/* USB Device High Speed port */
+	0,	/* (reserved) */
+	0,	/* Multimedia Card Interface 1 */
+	0,	/* (reserved) */
+	0,	/* Advanced Interrupt Controller IRQ0 */
+};
+
+static const uint32_t at91_pio_base[] = {
+	AT91SAM9G45_PIOA_BASE,
+	AT91SAM9G45_PIOB_BASE,
+	AT91SAM9G45_PIOC_BASE,
+	AT91SAM9G45_PIOD_BASE,
+	AT91SAM9G45_PIOE_BASE,
+};
+
+#define DEVICE(_name, _id, _unit)		\
+	{					\
+		_name, _unit,			\
+		AT91SAM9G45_ ## _id ##_BASE,	\
+		AT91SAM9G45_ ## _id ## _SIZE,	\
+		AT91SAM9G45_IRQ_ ## _id		\
+	}
+
+static const struct cpu_devs at91_devs[] =
+{
+	DEVICE("at91_pmc", PMC,  0),
+	DEVICE("at91_wdt", WDT,  0),
+	DEVICE("at91_rst", RSTC, 0),
+	DEVICE("at91_pit", PIT,  0),
+	DEVICE("at91_pio", PIOA, 0),
+	DEVICE("at91_pio", PIOB, 1),
+	DEVICE("at91_pio", PIOC, 2),
+	DEVICE("at91_pio", PIOD, 3),
+	DEVICE("at91_pio", PIOE, 4),
+	DEVICE("at91_twi", TWI0, 0),
+	DEVICE("at91_twi", TWI1, 1),
+	DEVICE("at91_mci", HSMCI0, 0),
+	DEVICE("at91_mci", HSMCI1, 1),
+	DEVICE("uart", DBGU,   0),
+	DEVICE("uart", USART0, 1),
+	DEVICE("uart", USART1, 2),
+	DEVICE("uart", USART2, 3),
+	DEVICE("uart", USART3, 4),
+	DEVICE("spi",  SPI0,   0),
+	DEVICE("spi",  SPI1,   1),
+	DEVICE("ate",  EMAC,   0),
+	DEVICE("macb", EMAC,   0),
+	DEVICE("nand", NAND,   0),
+	DEVICE("ohci", OHCI,   0),
+	{ 0, 0, 0, 0, 0 }
+};
+
+static void
+at91_clock_init(void)
+{
+	struct at91_pmc_clock *clk;
+
+	/* Update USB host port clock info */
+	clk = at91_pmc_clock_ref("uhpck");
+	clk->pmc_mask  = PMC_SCER_UHP_SAM9;
+	at91_pmc_clock_deref(clk);
+
+	/* Each SOC has different PLL contraints */
+	clk = at91_pmc_clock_ref("plla");
+	clk->pll_min_in    = SAM9G45_PLL_A_MIN_IN_FREQ;		/*   2 MHz */
+	clk->pll_max_in    = SAM9G45_PLL_A_MAX_IN_FREQ;		/*  32 MHz */
+	clk->pll_min_out   = SAM9G45_PLL_A_MIN_OUT_FREQ;	/* 400 MHz */
+	clk->pll_max_out   = SAM9G45_PLL_A_MAX_OUT_FREQ;	/* 800 MHz */
+	clk->pll_mul_shift = SAM9G45_PLL_A_MUL_SHIFT;
+	clk->pll_mul_mask  = SAM9G45_PLL_A_MUL_MASK;
+	clk->pll_div_shift = SAM9G45_PLL_A_DIV_SHIFT;
+	clk->pll_div_mask  = SAM9G45_PLL_A_DIV_MASK;
+	clk->set_outb      = at91_pmc_800mhz_plla_outb;
+	at91_pmc_clock_deref(clk);
+}
+
+static struct at91_soc_data soc_data = {
+	.soc_delay = at91_pit_delay,
+	.soc_reset = at91_rst_cpu_reset,
+	.soc_clock_init = at91_clock_init,
+	.soc_irq_prio = at91_irq_prio,
+	.soc_children = at91_devs,
+	.soc_pio_base = at91_pio_base,
+	.soc_pio_count = nitems(at91_pio_base),
+};
+
+AT91_SOC(AT91_T_SAM9G45, &soc_data);


Property changes on: trunk/sys/arm/at91/at91sam9g45.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91sam9g45reg.h
===================================================================
--- trunk/sys/arm/at91/at91sam9g45reg.h	                        (rev 0)
+++ trunk/sys/arm/at91/at91sam9g45reg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,295 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2009 Sylvestre Gallon.  All rights reserved.
+ * Copyright (c) 2010 Greg Ansley.  All rights reserved.
+ * Copyright (c) 2012 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 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 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: stable/10/sys/arm/at91/at91sam9g45reg.h 266110 2014-05-15 02:41:23Z ian $ */
+
+#ifndef AT91SAM9G45REG_H_
+#define	AT91SAM9G45REG_H_
+
+/* Chip Specific limits */
+#define	SAM9G45_PLL_A_MIN_IN_FREQ	  2000000 /*   2 Mhz */
+#define	SAM9G45_PLL_A_MAX_IN_FREQ	 32000000 /*  32 Mhz */
+#define	SAM9G45_PLL_A_MIN_OUT_FREQ	400000000 /* 400 Mhz */
+#define	SAM9G45_PLL_A_MAX_OUT_FREQ	800000000 /* 800 Mhz */
+#define	SAM9G45_PLL_A_MUL_SHIFT 16
+#define	SAM9G45_PLL_A_MUL_MASK 0xFF
+#define	SAM9G45_PLL_A_DIV_SHIFT 0
+#define	SAM9G45_PLL_A_DIV_MASK 0xFF
+
+/*
+ * Memory map, from datasheet :
+ * 0x00000000 - 0x0ffffffff : Internal Memories
+ * 0x10000000 - 0x1ffffffff : Chip Select 0
+ * 0x20000000 - 0x2ffffffff : Chip Select 1
+ * 0x30000000 - 0x3ffffffff : Chip Select 2
+ * 0x40000000 - 0x4ffffffff : Chip Select 3
+ * 0x50000000 - 0x5ffffffff : Chip Select 4
+ * 0x60000000 - 0x6ffffffff : Chip Select 5
+ * 0x70000000 - 0x7ffffffff : DDR SDRC 0
+ * 0x80000000 - 0xeffffffff : Undefined (Abort)
+ * 0xf0000000 - 0xfffffffff : Peripherals
+ */
+
+#define	AT91_CHIPSELECT_0 0x10000000
+#define	AT91_CHIPSELECT_1 0x20000000
+#define	AT91_CHIPSELECT_2 0x30000000
+#define	AT91_CHIPSELECT_3 0x40000000
+#define	AT91_CHIPSELECT_4 0x50000000
+#define	AT91_CHIPSELECT_5 0x60000000
+
+
+#define	AT91SAM9G45_EMAC_BASE	0xffbc000
+#define	AT91SAM9G45_EMAC_SIZE	0x4000
+
+#define	AT91SAM9G45_RSTC_BASE	0xffffd00
+#define	AT91SAM9G45_RSTC_SIZE	0x10
+
+/* USART*/
+
+#define	AT91SAM9G45_USART_SIZE	0x4000
+#define	AT91SAM9G45_USART0_BASE	0xff8c000
+#define	AT91SAM9G45_USART0_SIZE	AT91SAM9G45_USART_SIZE
+#define	AT91SAM9G45_USART1_BASE	0xff90000
+#define	AT91SAM9G45_USART1_SIZE	AT91SAM9G45_USART_SIZE
+#define	AT91SAM9G45_USART2_BASE	0xff94000
+#define	AT91SAM9G45_USART2_SIZE	AT91SAM9G45_USART_SIZE
+#define	AT91SAM9G45_USART3_BASE	0xff98000
+#define	AT91SAM9G45_USART3_SIZE	AT91SAM9G45_USART_SIZE
+
+/*TC*/
+#define	AT91SAM9G45_TC0_BASE	0xff7c000
+#define	AT91SAM9G45_TC0_SIZE	0x4000
+#define	AT91SAM9G45_TC0C0_BASE	0xff7c000
+#define	AT91SAM9G45_TC0C1_BASE	0xff7c040
+#define	AT91SAM9G45_TC0C2_BASE	0xff7c080
+
+#define	AT91SAM9G45_TC1_BASE	0xffd4000
+#define	AT91SAM9G45_TC1_SIZE	0x4000
+#define	AT91SAM9G45_TC1C0_BASE	0xffd4000
+#define	AT91SAM9G45_TC1C1_BASE	0xffd4040
+#define	AT91SAM9G45_TC1C2_BASE	0xffd4080
+
+/*SPI*/
+
+#define	AT91SAM9G45_SPI0_BASE	0xffa48000
+#define	AT91SAM9G45_SPI0_SIZE	0x4000
+
+#define	AT91SAM9G45_SPI1_BASE	0xffa8000
+#define	AT91SAM9G45_SPI1_SIZE	0x4000
+
+/* System Registers */
+#define	AT91SAM9G45_SYS_BASE	0xffff000
+#define	AT91SAM9G45_SYS_SIZE	0x1000
+
+#define	AT91SAM9G45_MATRIX_BASE	0xfffea00
+#define	AT91SAM9G45_MATRIX_SIZE	0x200
+
+#define	AT91SAM9G45_DBGU_BASE	0xfffee00
+#define	AT91SAM9G45_DBGU_SIZE	0x200
+
+/*
+ * PIO
+ */
+#define	AT91SAM9G45_PIOA_BASE	0xffff200
+#define	AT91SAM9G45_PIOA_SIZE	0x200
+#define	AT91SAM9G45_PIOB_BASE	0xffff400
+#define	AT91SAM9G45_PIOB_SIZE	0x200
+#define	AT91SAM9G45_PIOC_BASE	0xffff600
+#define	AT91SAM9G45_PIOC_SIZE	0x200
+#define	AT91SAM9G45_PIOD_BASE	0xffff800
+#define	AT91SAM9G45_PIOD_SIZE	0x200
+#define	AT91SAM9G45_PIOE_BASE	0xffffa00
+#define	AT91SAM9G45_PIOE_SIZE	0x200
+
+#define	AT91SAM9G45_PMC_BASE	0xffffc00
+#define	AT91SAM9G45_PMC_SIZE	0x100
+
+/* IRQs : */
+/*
+ * 0: AIC
+ * 1: System peripheral (System timer, RTC, DBGU)
+ * 2: PIO Controller A
+ * 3: PIO Controller B
+ * 4: PIO Controller C
+ * 5: PIO Controller D/E
+ * 6: TRNG
+ * 7: USART 0
+ * 8: USART 1
+ * 9: USART 2
+ * 10: USART 3
+ * 11: Multimedia Card interface 0
+ * 12: Two-wirte interface 0
+ * 13: Two-wirte interface 1
+ * 14: SPI 0
+ * 15: SPI 1
+ * 16: SSC 0
+ * 17: SSC 0
+ * 18: Timer Counter 0, 2, 3, 4, 5
+ * 19: PWM
+ * 20: Touch Screen ADC
+ * 21: DMA
+ * 22: USB Host port
+ * 23: LCD
+ * 24: AC97
+ * 25: EMAC
+ * 26: Image Sensor Interface
+ * 27: USB Device High Speed
+ * 28: -
+ * 29: Multimedia Card interface 1
+ * 30: Reserved
+ * 31: AIC
+ */
+
+#define	AT91SAM9G45_IRQ_SYSTEM	1
+#define	AT91SAM9G45_IRQ_PIOA	2
+#define	AT91SAM9G45_IRQ_PIOB	3
+#define	AT91SAM9G45_IRQ_PIOC	4
+#define	AT91SAM9G45_IRQ_PIOD	5
+#define	AT91SAM9G45_IRQ_PIOE	6
+#define	AT91SAM9G45_IRQ_USART0	7
+#define	AT91SAM9G45_IRQ_USART1	8
+#define	AT91SAM9G45_IRQ_USART2	9
+#define	AT91SAM9G45_IRQ_USART3	10
+#define	AT91SAM9G45_IRQ_HSMCI0	11
+#define	AT91SAM9G45_IRQ_TWI0	12
+#define	AT91SAM9G45_IRQ_TWI1	13
+#define	AT91SAM9G45_IRQ_SPI0	14
+#define	AT91SAM9G45_IRQ_SPI1	15
+#define	AT91SAM9G45_IRQ_SSC0	16
+#define	AT91SAM9G45_IRQ_SSC1	17
+#define	AT91SAM9G45_IRQ_TC0_TC5	18
+#define	AT91SAM9G45_IRQ_PWM	19
+#define	AT91SAM9G45_IRQ_TSADCC	20
+#define	AT91SAM9G45_IRQ_DMA	21
+#define	AT91SAM9G45_IRQ_UHP	22
+#define	AT91SAM9G45_IRQ_LCDC	23
+#define	AT91SAM9G45_IRQ_AC97C	24
+#define	AT91SAM9G45_IRQ_EMAC	25
+#define	AT91SAM9G45_IRQ_ISI	26
+#define	AT91SAM9G45_IRQ_UDPHS	27
+/* Reserved 28 */
+#define	AT91SAM9G45_IRQ_HSMCI1	29
+/* Reserved 30 */
+#define	AT91SAM9G45_IRQ_AICBASE	31
+
+/* Alias */
+#define	AT91SAM9G45_IRQ_DBGU	AT91SAM9G45_IRQ_SYSTEM
+#define	AT91SAM9G45_IRQ_PMC	AT91SAM9G45_IRQ_SYSTEM
+#define	AT91SAM9G45_IRQ_WDT	AT91SAM9G45_IRQ_SYSTEM
+#define	AT91SAM9G45_IRQ_PIT	AT91SAM9G45_IRQ_SYSTEM
+#define	AT91SAM9G45_IRQ_RSTC	AT91SAM9G45_IRQ_SYSTEM
+#define	AT91SAM9G45_IRQ_OHCI	AT91SAM9G45_IRQ_UHP
+#define	AT91SAM9G45_IRQ_TC0	AT91SAM9G45_IRQ_TC0_TC5
+#define	AT91SAM9G45_IRQ_TC1	AT91SAM9G45_IRQ_TC0_TC5
+#define	AT91SAM9G45_IRQ_TC2	AT91SAM9G45_IRQ_TC0_TC5
+#define	AT91SAM9G45_IRQ_TC3	AT91SAM9G45_IRQ_TC0_TC5
+#define	AT91SAM9G45_IRQ_TC4	AT91SAM9G45_IRQ_TC0_TC5
+#define	AT91SAM9G45_IRQ_TC5	AT91SAM9G45_IRQ_TC0_TC5
+#define	AT91SAM9G45_IRQ_NAND 	(-1)
+
+#define	AT91SAM9G45_AIC_BASE	0xffff000
+#define	AT91SAM9G45_AIC_SIZE	0x200
+
+/* Timer */
+
+#define	AT91SAM9G45_WDT_BASE	0xffffd40
+#define	AT91SAM9G45_WDT_SIZE	0x10
+
+#define	AT91SAM9G45_PIT_BASE	0xffffd30
+#define	AT91SAM9G45_PIT_SIZE	0x10
+
+#define	AT91SAM9G45_SMC_BASE	0xfffe800
+#define	AT91SAM9G45_SMC_SIZE	0x200
+
+#define	AT91SAM9G45_PMC_BASE	0xffffc00
+#define	AT91SAM9G45_PMC_SIZE	0x100
+
+#define	AT91SAM9G45_HSMCI0_BASE	0xff80000
+#define	AT91SAM9G45_HSMCI0_SIZE	0x4000
+
+#define	AT91SAM9G45_HSMCI1_BASE	0xffd0000
+#define	AT91SAM9G45_HSMCI1_SIZE	0x4000
+
+#define	AT91SAM9G45_TWI0_BASE	0xff84000
+#define	AT91SAM9G45_TWI0_SIZE	0x4000
+#define	AT91SAM9G45_TWI1_BASE	0xff88000
+#define	AT91SAM9G45_TWI1_SIZE	0x4000
+
+/* XXX Needs to be carfully coordinated with
+ * other * soc's so phyical and vm address
+ * mapping are unique. XXX
+ */
+#define	AT91SAM9G45_OHCI_VA_BASE 0xdfb00000
+#define	AT91SAM9G45_OHCI_BASE	0x00700000
+#define	AT91SAM9G45_OHCI_SIZE	0x00100000
+
+#define	AT91SAM9G45_NAND_VA_BASE 0xe0000000
+#define	AT91SAM9G45_NAND_BASE	0x40000000
+#define	AT91SAM9G45_NAND_SIZE	0x10000000
+
+
+/* DDRSDRC */
+#define	AT91SAM9G45_DDRSDRC1_BASE	0xfffea00
+#define	AT91SAM9G45_DDRSDRC0_BASE	0xfffe600
+#define	AT91SAM9G45_DDRSDRC_MR		0x00
+#define	AT91SAM9G45_DDRSDRC_TR		0x04
+#define	AT91SAM9G45_DDRSDRC_CR		0x08
+#define	AT91SAM9G45_DDRSDRC_CR_NC_8	0x0
+#define	AT91SAM9G45_DDRSDRC_CR_NC_9	0x1
+#define	AT91SAM9G45_DDRSDRC_CR_NC_10	0x2
+#define	AT91SAM9G45_DDRSDRC_CR_NC_11	0x3
+#define	AT91SAM9G45_DDRSDRC_CR_NC_MASK	0x00000003
+#define	AT91SAM9G45_DDRSDRC_CR_NR_11	0x0
+#define	AT91SAM9G45_DDRSDRC_CR_NR_12	0x4
+#define	AT91SAM9G45_DDRSDRC_CR_NR_13	0x8
+#define	AT91SAM9G45_DDRSDRC_CR_NR_14	0xc
+#define	AT91SAM9G45_DDRSDRC_CR_NR_MASK	0x0000000c
+#define	AT91SAM9G45_DDRSDRC_TPR0	0x0c
+#define	AT91SAM9G45_DDRSDRC_TPR1	0x10
+#define	AT91SAM9G45_DDRSDRC_TPR2	0x14
+/* Reserved 0x18 */
+#define	AT91SAM9G45_DDRSDRC_LPR		0x1c
+#define	AT91SAM9G45_DDRSDRC_MDR		0x20
+#define	AT91SAM9G45_DDRSDRC_MDR_SDR	0x0
+#define	AT91SAM9G45_DDRSDRC_MDR_LPSDR	0x1
+#define	AT91SAM9G45_DDRSDRC_MDR_LPDDR1	0x3
+#define	AT91SAM9G45_DDRSDRC_MDR_DDR2	0x6
+#define	AT91SAM9G45_DDRSDRC_MDR_MASK	0x00000007
+#define	AT91SAM9G45_DDRSDRC_MDR_DBW_16	0x10
+#define	AT91SAM9G45_DDRSDRC_DLL		0x24
+#define	AT91SAM9G45_DDRSDRC_HSR		0x2c
+#define	AT91SAM9G45_DDRSDRC_DELAY1R	0x40
+#define	AT91SAM9G45_DDRSDRC_DELAY2R	0x44
+#define	AT91SAM9G45_DDRSDRC_DELAY3R	0x48
+#define	AT91SAM9G45_DDRSDRC_DELAY4R	0x4c
+/* Reserved 0x50 - 0xe0 */
+#define	AT91SAM9G45_DDRSDRC_WPMR	0xe4
+#define	AT91SAM9G45_DDRSDRC_WPSR	0xe8
+
+#endif /* AT91SAM9G45REG_H_*/
+


Property changes on: trunk/sys/arm/at91/at91sam9g45reg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91sam9x5.c
===================================================================
--- trunk/sys/arm/at91/at91sam9x5.c	                        (rev 0)
+++ trunk/sys/arm/at91/at91sam9x5.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,188 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2005 Olivier Houchard.  All rights reserved.
+ * Copyright (c) 2010 Greg Ansley.  All rights reserved.
+ * Copyright (c) 2012 M. Warner Losh..  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 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 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: stable/10/sys/arm/at91/at91sam9x5.c 266277 2014-05-17 00:53:12Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+
+#include <machine/bus.h>
+
+#include <arm/at91/at91var.h>
+#include <arm/at91/at91reg.h>
+#include <arm/at91/at91soc.h>
+#include <arm/at91/at91_aicreg.h>
+#include <arm/at91/at91sam9x5reg.h>
+#include <arm/at91/at91_pitreg.h>
+#include <arm/at91/at91_pmcreg.h>
+#include <arm/at91/at91_pmcvar.h>
+#include <arm/at91/at91_rstreg.h>
+
+/*
+ * Standard priority levels for the system.  0 is lowest and 7 is highest.
+ * These values are the ones Atmel uses for its Linux port
+ */
+static const int at91_irq_prio[32] =
+{
+	7,	/* Advanced Interrupt Controller (FIQ) */
+	7,	/* System Peripherals */
+	1,	/* Parallel IO Controller A and B */
+	1,	/* Parallel IO Controller C and D */
+	4,	/* Soft Modem */
+	5,	/* USART 0 */
+	5,	/* USART 1 */
+	5,	/* USART 2 */
+	5,	/* USART 3 */
+	6,	/* Two-Wire Interface 0 */
+	6,	/* Two-Wire Interface 1 */
+	6,	/* Two-Wire Interface 2 */
+	0,	/* Multimedia Card Interface 0 */
+	5,	/* Serial Peripheral Interface 0 */
+	5,	/* Serial Peripheral Interface 1 */
+	5,	/* UART 0 */
+	5,	/* UART 1 */
+	0,	/* Timer Counter 0, 1, 2, 3, 4 and 5 */
+	0,	/* Pulse Width Modulation Controller */
+	0,	/* ADC Controller */
+	0,	/* DMA Controller 0 */
+	0,	/* DMA Controller 1 */
+	2,	/* USB Host High Speed port */
+	2,	/* USB Device High speed port */
+	3,	/* Ethernet MAC 0 */
+	3,	/* LDC Controller or Image Sensor Interface */
+	0,	/* Multimedia Card Interface 1 */
+	3,	/* Ethernet MAC 1 */
+	4,	/* Synchronous Serial Interface */
+	4,	/* CAN Controller 0 */
+	4,	/* CAN Controller 1 */
+	0,	/* Advanced Interrupt Controller (IRQ0) */
+};
+
+static const uint32_t at91_pio_base[] = {
+	AT91SAM9X25_PIOA_BASE,
+	AT91SAM9X25_PIOB_BASE,
+	AT91SAM9X25_PIOC_BASE,
+	AT91SAM9X25_PIOD_BASE,
+};
+
+#define DEVICE(_name, _id, _unit)		\
+	{					\
+		_name, _unit,			\
+		AT91SAM9X25_ ## _id ##_BASE,	\
+		AT91SAM9X25_ ## _id ## _SIZE,	\
+		AT91SAM9X25_IRQ_ ## _id		\
+	}
+
+static const struct cpu_devs at91_devs[] =
+{
+	DEVICE("at91_aic", AIC,  0),
+	DEVICE("at91_pmc", PMC,  0),
+	DEVICE("at91_wdt", WDT,  0),
+	DEVICE("at91_rst", RSTC, 0),
+	DEVICE("at91_pit", PIT,  0),
+	DEVICE("at91_pio", PIOA, 0),
+	DEVICE("at91_pio", PIOB, 1),
+	DEVICE("at91_pio", PIOC, 2),
+	DEVICE("at91_pio", PIOD, 3),
+	DEVICE("at91_twi", TWI0, 0),
+	DEVICE("at91_twi", TWI1, 1),
+	DEVICE("at91_twi", TWI2, 2),
+	DEVICE("at91_mci", HSMCI0, 0),
+	DEVICE("at91_mci", HSMCI1, 1),
+	DEVICE("uart", DBGU,   0),
+	DEVICE("uart", USART0, 1),
+	DEVICE("uart", USART1, 2),
+	DEVICE("uart", USART2, 3),
+	DEVICE("uart", USART3, 4),
+	DEVICE("spi",  SPI0,   0),
+	DEVICE("spi",  SPI1,   1),
+	DEVICE("macb", EMAC0,  0),
+	DEVICE("macb", EMAC1,  0),
+	DEVICE("nand", NAND,   0),
+	DEVICE("ohci", OHCI,   0),
+	DEVICE("ehci", EHCI,   0),
+	{ 0, 0, 0, 0, 0 }
+};
+
+static void
+at91_clock_init(void)
+{
+	struct at91_pmc_clock *clk;
+
+	/* Update USB device port clock info */
+	clk = at91_pmc_clock_ref("udpck");
+	clk->pmc_mask  = PMC_SCER_UDP_SAM9;
+	at91_pmc_clock_deref(clk);
+
+	/* Update USB host port clock info */
+	clk = at91_pmc_clock_ref("uhpck");
+	clk->pmc_mask  = PMC_SCER_UHP_SAM9;
+	at91_pmc_clock_deref(clk);
+
+	/* Each SOC has different PLL contraints */
+	clk = at91_pmc_clock_ref("plla");
+	clk->pll_min_in    = SAM9X25_PLL_A_MIN_IN_FREQ;		/*   2 MHz */
+	clk->pll_max_in    = SAM9X25_PLL_A_MAX_IN_FREQ;		/*  32 MHz */
+	clk->pll_min_out   = SAM9X25_PLL_A_MIN_OUT_FREQ;	/* 400 MHz */
+	clk->pll_max_out   = SAM9X25_PLL_A_MAX_OUT_FREQ;	/* 800 MHz */
+	clk->pll_mul_shift = SAM9X25_PLL_A_MUL_SHIFT;
+	clk->pll_mul_mask  = SAM9X25_PLL_A_MUL_MASK;
+	clk->pll_div_shift = SAM9X25_PLL_A_DIV_SHIFT;
+	clk->pll_div_mask  = SAM9X25_PLL_A_DIV_MASK;
+	clk->set_outb      = at91_pmc_800mhz_plla_outb;
+	at91_pmc_clock_deref(clk);
+
+	clk = at91_pmc_clock_ref("pllb");
+	clk->pll_min_in    = SAM9X25_PLL_B_MIN_IN_FREQ;		/*   2 MHz */
+	clk->pll_max_in    = SAM9X25_PLL_B_MAX_IN_FREQ;		/*  32 MHz */
+	clk->pll_min_out   = SAM9X25_PLL_B_MIN_OUT_FREQ;	/*  30 MHz */
+	clk->pll_max_out   = SAM9X25_PLL_B_MAX_OUT_FREQ;	/* 100 MHz */
+	clk->pll_mul_shift = SAM9X25_PLL_B_MUL_SHIFT;
+	clk->pll_mul_mask  = SAM9X25_PLL_B_MUL_MASK;
+	clk->pll_div_shift = SAM9X25_PLL_B_DIV_SHIFT;
+	clk->pll_div_mask  = SAM9X25_PLL_B_DIV_MASK;
+	clk->set_outb      = at91_pmc_800mhz_pllb_outb;
+	at91_pmc_clock_deref(clk);
+}
+
+static struct at91_soc_data soc_data = {
+	.soc_delay = at91_pit_delay,
+	.soc_reset = at91_rst_cpu_reset,
+	.soc_clock_init = at91_clock_init,
+	.soc_irq_prio = at91_irq_prio,
+	.soc_children = at91_devs,
+	.soc_pio_base = at91_pio_base,
+	.soc_pio_count = nitems(at91_pio_base),
+};
+
+AT91_SOC_SUB(AT91_T_SAM9X5, AT91_ST_SAM9X25, &soc_data);


Property changes on: trunk/sys/arm/at91/at91sam9x5.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91sam9x5reg.h
===================================================================
--- trunk/sys/arm/at91/at91sam9x5reg.h	                        (rev 0)
+++ trunk/sys/arm/at91/at91sam9x5reg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,316 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2009 Sylvestre Gallon.  All rights reserved.
+ * Copyright (c) 2010 Greg Ansley.  All rights reserved.
+ * Copyright (c) 2012 M. Warener Losh.  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 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 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: stable/10/sys/arm/at91/at91sam9x5reg.h 238922 2012-07-30 21:30:43Z imp $ */
+
+#ifndef AT91SAM9X5REG_H_
+#define AT91SAM9X5REG_H_
+
+#ifndef AT91SAM9X25_MASTER_CLOCK
+#define AT91SAM9X25_MASTER_CLOCK ((18432000 * 43)/6)
+#endif
+
+/* Chip Specific limits */
+#define SAM9X25_PLL_A_MIN_IN_FREQ	  2000000 /*   2 Mhz */
+#define SAM9X25_PLL_A_MAX_IN_FREQ	 32000000 /*  32 Mhz */
+#define SAM9X25_PLL_A_MIN_OUT_FREQ	400000000 /* 400 Mhz */
+#define SAM9X25_PLL_A_MAX_OUT_FREQ	800000000 /* 800 Mhz */
+#define SAM9X25_PLL_A_MUL_SHIFT 16
+#define SAM9X25_PLL_A_MUL_MASK 0xFF 
+#define SAM9X25_PLL_A_DIV_SHIFT 0
+#define SAM9X25_PLL_A_DIV_MASK 0xFF 
+
+#define SAM9X25_PLL_B_MIN_IN_FREQ	  2000000 /*   2 Mhz */
+#define SAM9X25_PLL_B_MAX_IN_FREQ	 32000000 /*  32 Mhz */
+#define SAM9X25_PLL_B_MIN_OUT_FREQ	 30000000 /*  30 Mhz */
+#define SAM9X25_PLL_B_MAX_OUT_FREQ	100000000 /* 100 Mhz */
+#define SAM9X25_PLL_B_MUL_SHIFT 16
+#define SAM9X25_PLL_B_MUL_MASK 0x3F 
+#define SAM9X25_PLL_B_DIV_SHIFT 0
+#define SAM9X25_PLL_B_DIV_MASK 0xFF 
+
+/* 
+ * Memory map, from datasheet :
+ * 0x00000000 - 0x0ffffffff : Internal Memories
+ * 0x10000000 - 0x1ffffffff : Chip Select 0
+ * 0x20000000 - 0x2ffffffff : Chip Select 1 DDR2/LPDDR/SDR/LPSDR
+ * 0x30000000 - 0x3ffffffff : Chip Select 2 
+ * 0x40000000 - 0x4ffffffff : Chip Select 3 NAND Flash
+ * 0x50000000 - 0x5ffffffff : Chip Select 4
+ * 0x60000000 - 0x6ffffffff : Chip Select 5
+ * 0x70000000 - 0xeffffffff : Undefined (Abort)
+ * 0xf0000000 - 0xfffffffff : Peripherals
+ */
+
+#define AT91_CHIPSELECT_0 0x10000000
+#define AT91_CHIPSELECT_1 0x20000000
+#define AT91_CHIPSELECT_2 0x30000000
+#define AT91_CHIPSELECT_3 0x40000000
+#define AT91_CHIPSELECT_4 0x50000000
+#define AT91_CHIPSELECT_5 0x60000000
+
+#define AT91SAM9X25_EMAC_SIZE  0x4000
+#define AT91SAM9X25_EMAC0_BASE 0x802c000
+#define AT91SAM9X25_EMAC0_SIZE AT91SAM9X25_EMAC_SIZE
+#define AT91SAM9X25_EMAC1_BASE 0x8030000
+#define AT91SAM9X25_EMAC1_SIZE AT91SAM9X25_EMAC_SIZE
+
+#define AT91SAM9X25_RSTC_BASE	0xffffe00
+#define AT91SAM9X25_RSTC_SIZE	0x10
+
+/* USART*/
+
+#define AT91SAM9X25_USART_SIZE	0x4000
+#define AT91SAM9X25_USART0_BASE	0x801c000
+#define AT91SAM9X25_USART0_PDC	0x801c100
+#define AT91SAM9X25_USART0_SIZE	AT91SAM9X25_USART_SIZE
+#define AT91SAM9X25_USART1_BASE	0x8020000
+#define AT91SAM9X25_USART1_PDC	0x8020100
+#define AT91SAM9X25_USART1_SIZE	AT91SAM9X25_USART_SIZE
+#define AT91SAM9X25_USART2_BASE	0x8024000
+#define AT91SAM9X25_USART2_PDC	0x8024100
+#define AT91SAM9X25_USART2_SIZE	AT91SAM9X25_USART_SIZE
+#define AT91SAM9X25_USART3_BASE	0x8028000
+#define AT91SAM9X25_USART3_PDC	0x8028100
+#define AT91SAM9X25_USART3_SIZE	AT91SAM9X25_USART_SIZE
+
+/*TC*/
+#define AT91SAM9X25_TC0_BASE	0x8008000
+#define AT91SAM9X25_TC0_SIZE	0x4000
+#define AT91SAM9X25_TC0C0_BASE	0x8008000
+#define AT91SAM9X25_TC0C1_BASE	0x8008040
+#define AT91SAM9X25_TC0C2_BASE	0x8008080
+
+#define AT91SAM9X25_TC1_BASE	0x800c000
+#define AT91SAM9X25_TC1_SIZE	0x4000
+
+/*SPI*/
+
+#define AT91SAM9X25_SPI0_BASE	0x0000000
+
+#define AT91SAM9X25_SPI0_SIZE	0x4000
+
+#define AT91SAM9X25_SPI1_BASE	0x0004000
+#define AT91SAM9X25_SPI1_SIZE	0x4000
+
+/* System Registers */
+#define AT91SAM9X25_SYS_BASE	0xffff000
+#define AT91SAM9X25_SYS_SIZE	0x1000
+
+#define AT91SAM9X25_MATRIX_BASE	0xfffde00
+#define AT91SAM9X25_MATRIX_SIZE	0x200
+
+#define AT91SAM9X25_DBGU_BASE	0xffff200
+#define AT91SAM9X25_DBGU_SIZE	0x200
+
+/*
+ * PIO
+ */
+#define AT91SAM9X25_PIOA_BASE	0xffff400
+#define AT91SAM9X25_PIOA_SIZE	0x200
+#define AT91SAM9X25_PIOB_BASE	0xffff600
+#define AT91SAM9X25_PIOB_SIZE	0x200
+#define AT91SAM9X25_PIOC_BASE	0xffff800
+#define AT91SAM9X25_PIOC_SIZE	0x200
+#define AT91SAM9X25_PIOD_BASE	0xffffa00
+#define AT91SAM9X25_PIOD_SIZE	0x200
+
+#define AT91RM92_PMC_BASE	0xffffc00
+#define AT91RM92_PMC_SIZE	0x100
+/* IRQs :
+ * 0: AIC 
+ * 1: System peripheral (System timer, RTC, DBGU)
+ * 2: PIO Controller A,B
+ * 3: PIO Controller C,D
+ * 4: SMD Soft Modem
+ * 5: USART 0
+ * 6: USART 1
+ * 7: USART 2
+ * 8: USART 3
+ * 9: Two-wirte interface
+ * 10: Two-wirte interface
+ * 11: Two-wirte interface
+ * 12: HSMCI Interface
+ * 13: SPI 0
+ * 14: SPI 1
+ * 15: UART0
+ * 16: UART1
+ * 17: Timer Counter 0,1
+ * 18: PWM
+ * 19: ADC
+ * 20: DMAC 0
+ * 21: DMAC 1
+ * 22: UHPHS - USB Host controller
+ * 23: UDPHS - USB Device Controller
+ * 24: EMAC0
+ * 25: LCD controller or Image Sensor Interface
+ * 26: HSMCI1
+ * 27: EMAC1
+ * 28: SSC
+ * 29: CAN0
+ * 30: CAN1
+ * 31: AIC IRQ0
+ */
+
+#define AT91SAM9X25_IRQ_AIC	0
+#define AT91SAM9X25_IRQ_SYSTEM	1
+#define AT91SAM9X25_IRQ_PIOAB	2
+#define AT91SAM9X25_IRQ_PIOCD	3
+#define AT91SAM9X25_IRQ_SMD	4
+#define AT91SAM9X25_IRQ_USART0	5
+#define AT91SAM9X25_IRQ_USART1	6
+#define AT91SAM9X25_IRQ_USART2	7
+#define AT91SAM9X25_IRQ_USART3	8
+#define AT91SAM9X25_IRQ_TWI0	9
+#define AT91SAM9X25_IRQ_TWI1	10
+#define AT91SAM9X25_IRQ_TWI2	11
+#define AT91SAM9X25_IRQ_HSMCI0	12
+#define AT91SAM9X25_IRQ_SPI0	13
+#define AT91SAM9X25_IRQ_SPI1	14
+#define AT91SAM9X25_IRQ_UART0	15
+#define AT91SAM9X25_IRQ_UART1	16
+#define AT91SAM9X25_IRQ_TC01	17
+#define AT91SAM9X25_IRQ_PWM	18
+#define AT91SAM9X25_IRQ_ADC	19
+#define AT91SAM9X25_IRQ_DMAC0	20
+#define AT91SAM9X25_IRQ_DMAC1	21
+#define AT91SAM9X25_IRQ_UHPHS	22
+#define AT91SAM9X25_IRQ_UDPHS	23
+#define AT91SAM9X25_IRQ_EMAC0	24
+#define AT91SAM9X25_IRQ_HSMCI1	26
+#define AT91SAM9X25_IRQ_EMAC1	27
+#define AT91SAM9X25_IRQ_SSC	28
+#define AT91SAM9X25_IRQ_CAN0	29
+#define AT91SAM9X25_IRQ_CAN1	30
+#define AT91SAM9X25_IRQ_AICBASE	31
+
+/* Alias */
+#define AT91SAM9X25_IRQ_DBGU 	AT91SAM9X25_IRQ_SYSTEM
+#define AT91SAM9X25_IRQ_PMC 	AT91SAM9X25_IRQ_SYSTEM
+#define AT91SAM9X25_IRQ_WDT 	AT91SAM9X25_IRQ_SYSTEM
+#define AT91SAM9X25_IRQ_PIT 	AT91SAM9X25_IRQ_SYSTEM
+#define AT91SAM9X25_IRQ_RSTC 	AT91SAM9X25_IRQ_SYSTEM
+#define AT91SAM9X25_IRQ_OHCI 	AT91SAM9X25_IRQ_UHPHS
+#define AT91SAM9X25_IRQ_EHCI 	AT91SAM9X25_IRQ_UHPHS
+#define AT91SAM9X25_IRQ_PIOA    AT91SAM9X25_IRQ_PIOAB
+#define AT91SAM9X25_IRQ_PIOB    AT91SAM9X25_IRQ_PIOAB
+#define AT91SAM9X25_IRQ_PIOC    AT91SAM9X25_IRQ_PIOCD
+#define AT91SAM9X25_IRQ_PIOD    AT91SAM9X25_IRQ_PIOCD
+#define AT91SAM9X25_IRQ_NAND 	(-1)
+
+#define AT91SAM9X25_AIC_BASE	0xffff000
+#define AT91SAM9X25_AIC_SIZE	0x200
+
+/* Timer */
+
+#define AT91SAM9X25_WDT_BASE	0xffffd40
+#define AT91SAM9X25_WDT_SIZE	0x10
+
+#define AT91SAM9X25_PIT_BASE	0xffffd30
+#define AT91SAM9X25_PIT_SIZE	0x10
+
+#define AT91SAM9X25_SMC_BASE	0xfffea00
+#define AT91SAM9X25_SMC_SIZE	0x200
+
+#define AT91SAM9X25_PMC_BASE	0xffffc00
+#define AT91SAM9X25_PMC_SIZE	0x100
+
+#define AT91SAM9X25_UDPHS_BASE	0x803c000
+#define AT91SAM9X25_UDPHS_SIZE	0x4000
+
+#define AT91SAM9X25_HSMCI_SIZE	0x4000
+#define AT91SAM9X25_HSMCI0_BASE	0x0008000
+#define AT91SAM9X25_HSMCI0_SIZE AT91SAM9X25_HSMCI_SIZE
+#define AT91SAM9X25_HSMCI1_BASE	0x000c000
+#define AT91SAM9X25_HSMCI1_SIZE AT91SAM9X25_HSMCI_SIZE
+
+#define AT91SAM9X25_TWI_SIZE	0x4000
+#define AT91SAM9X25_TWI0_BASE	0xffaC000
+#define AT91SAM9X25_TWI0_SIZE	AT91SAM9X25_TWI_SIZE
+#define AT91SAM9X25_TWI1_BASE	0xffaC000
+#define AT91SAM9X25_TWI1_SIZE	AT91SAM9X25_TWI_SIZE
+#define AT91SAM9X25_TWI2_BASE	0xffaC000
+#define AT91SAM9X25_TWI2_SIZE	AT91SAM9X25_TWI_SIZE
+
+/* XXX Needs to be carfully coordinated with
+ * other * soc's so phyical and vm address
+ * mapping are unique. XXX
+ */
+#define AT91SAM9X25_OHCI_BASE	  0xdfc00000 /* SAME as 9c40 */
+#define AT91SAM9X25_OHCI_PA_BASE  0x00600000
+#define AT91SAM9X25_OHCI_SIZE	  0x00100000
+
+#define AT91SAM9X25_EHCI_BASE	  0xdfd00000
+#define AT91SAM9X25_EHCI_PA_BASE  0x00700000
+#define AT91SAM9X25_EHCI_SIZE	  0x00100000
+
+#define AT91SAM9X25_NAND_BASE     0xe0000000
+#define AT91SAM9X25_NAND_PA_BASE  0x40000000
+#define AT91SAM9X25_NAND_SIZE     0x10000000
+
+
+/* SDRAMC */
+#define AT91SAM9X25_SDRAMC_BASE	0xfffea00               /* SAME as SMC? */
+#define AT91SAM9X25_SDRAMC_MR	0x00
+#define AT91SAM9X25_SDRAMC_MR_MODE_NORMAL	0
+#define AT91SAM9X25_SDRAMC_MR_MODE_NOP	1
+#define AT91SAM9X25_SDRAMC_MR_MODE_PRECHARGE 2
+#define AT91SAM9X25_SDRAMC_MR_MODE_LOAD_MODE_REGISTER 3
+#define AT91SAM9X25_SDRAMC_MR_MODE_REFRESH	4
+#define AT91SAM9X25_SDRAMC_TR	0x04
+#define AT91SAM9X25_SDRAMC_CR	0x08
+#define AT91SAM9X25_SDRAMC_CR_NC_8		0x0
+#define AT91SAM9X25_SDRAMC_CR_NC_9		0x1
+#define AT91SAM9X25_SDRAMC_CR_NC_10	0x2
+#define AT91SAM9X25_SDRAMC_CR_NC_11	0x3
+#define AT91SAM9X25_SDRAMC_CR_NC_MASK	0x00000003
+#define AT91SAM9X25_SDRAMC_CR_NR_11	0x0
+#define AT91SAM9X25_SDRAMC_CR_NR_12	0x4
+#define AT91SAM9X25_SDRAMC_CR_NR_13	0x8
+#define AT91SAM9X25_SDRAMC_CR_NR_RES	0xc
+#define AT91SAM9X25_SDRAMC_CR_NR_MASK	0x0000000c
+#define AT91SAM9X25_SDRAMC_CR_NB_2		0x00
+#define AT91SAM9X25_SDRAMC_CR_NB_4		0x10
+#define AT91SAM9X25_SDRAMC_CR_DBW_16		0x80
+#define AT91SAM9X25_SDRAMC_CR_NB_MASK	0x00000010
+#define AT91SAM9X25_SDRAMC_CR_NCAS_MASK	0x00000060
+#define AT91SAM9X25_SDRAMC_CR_TWR_MASK	0x00000780
+#define AT91SAM9X25_SDRAMC_CR_TRC_MASK	0x00007800
+#define AT91SAM9X25_SDRAMC_CR_TRP_MASK	0x00078000
+#define AT91SAM9X25_SDRAMC_CR_TRCD_MASK	0x00780000
+#define AT91SAM9X25_SDRAMC_CR_TRAS_MASK	0x07800000
+#define AT91SAM9X25_SDRAMC_CR_TXSR_MASK	0x78000000
+#define AT91SAM9X25_SDRAMC_HSR	0x0c
+#define AT91SAM9X25_SDRAMC_LPR	0x10
+#define AT91SAM9X25_SDRAMC_IER	0x14
+#define AT91SAM9X25_SDRAMC_IDR	0x18
+#define AT91SAM9X25_SDRAMC_IMR	0x1c
+#define AT91SAM9X25_SDRAMC_ISR	0x20
+#define AT91SAM9X25_SDRAMC_MDR	0x24
+
+#endif /* AT91SAM9X5REG_H_*/


Property changes on: trunk/sys/arm/at91/at91sam9x5reg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91soc.c
===================================================================
--- trunk/sys/arm/at91/at91soc.c	                        (rev 0)
+++ trunk/sys/arm/at91/at91soc.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,52 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Warner Losh.  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 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 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: stable/10/sys/arm/at91/at91soc.c 238376 2012-07-11 20:17:14Z imp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+
+#include <arm/at91/at91var.h>
+#include <arm/at91/at91soc.h>
+
+SET_DECLARE(at91_socs, const struct at91_soc);
+
+struct at91_soc_data *
+at91_match_soc(enum at91_soc_type type, enum at91_soc_subtype subtype)
+{
+	const struct at91_soc **socp;
+
+	SET_FOREACH(socp, at91_socs) {
+		if ((*socp)->soc_type != type)
+			continue;
+		if ((*socp)->soc_subtype != AT91_ST_ANY &&
+		    (*socp)->soc_subtype != subtype)
+			continue;
+		return (*socp)->soc_data;
+	}
+	return NULL;
+}


Property changes on: trunk/sys/arm/at91/at91soc.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91soc.h
===================================================================
--- trunk/sys/arm/at91/at91soc.h	                        (rev 0)
+++ trunk/sys/arm/at91/at91soc.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,59 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Warner Losh.  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 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 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: stable/10/sys/arm/at91/at91soc.h 238376 2012-07-11 20:17:14Z imp $ */
+
+#ifndef _ARM_AT91_AT91SOC_H_
+#define _ARM_AT91_AT91SOC_H_
+
+#include <sys/linker_set.h>
+
+struct at91_soc {
+	enum at91_soc_type	soc_type;	/* Family of mail type of SoC */
+	enum at91_soc_subtype 	soc_subtype;	/* More specific soc, if any */
+	struct at91_soc_data	*soc_data;
+};
+ 
+// Make varadic
+#define AT91_SOC(type, data)			\
+	static struct at91_soc this_soc = {	\
+		.soc_type = type,		\
+		.soc_subtype = AT91_ST_ANY,	\
+		.soc_data = data,		\
+	};					\
+	DATA_SET(at91_socs, this_soc);
+
+#define AT91_SOC_SUB(type, subtype, data)	\
+	static struct at91_soc this_soc = {	\
+		.soc_type = type,		\
+		.soc_subtype = subtype,		\
+		.soc_data = data,		\
+	};					\
+	DATA_SET(at91_socs, this_soc);
+
+struct at91_soc_data *at91_match_soc(enum at91_soc_type, enum at91_soc_subtype);
+
+#endif /* _ARM_AT91_AT91SOC_H_ */


Property changes on: trunk/sys/arm/at91/at91soc.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/at91var.h
===================================================================
--- trunk/sys/arm/at91/at91var.h	                        (rev 0)
+++ trunk/sys/arm/at91/at91var.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,173 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2005 Olivier Houchard.  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 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 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: stable/10/sys/arm/at91/at91var.h 266087 2014-05-14 20:31:54Z ian $ */
+
+#ifndef _AT91VAR_H_
+#define _AT91VAR_H_
+
+#include <sys/bus.h>
+#include <sys/rman.h>
+
+#include <arm/at91/at91reg.h>
+
+struct at91_softc {
+	device_t dev;
+	bus_space_tag_t sc_st;
+	bus_space_handle_t sc_sh;
+	bus_space_handle_t sc_aic_sh;
+	struct rman sc_irq_rman;
+	struct rman sc_mem_rman;
+};
+
+struct at91_ivar {
+	struct resource_list resources;
+};
+
+struct cpu_devs
+{
+	const char *name;
+	int unit;
+	bus_addr_t mem_base;
+	bus_size_t mem_len;
+	int irq0;
+	int irq1;
+	int irq2;
+	const char *parent_clk;
+};
+
+enum at91_soc_type {
+	AT91_T_NONE = 0,
+	AT91_T_CAP9,
+	AT91_T_RM9200,
+	AT91_T_SAM9260,
+	AT91_T_SAM9261,
+	AT91_T_SAM9263,
+	AT91_T_SAM9G10,
+	AT91_T_SAM9G20,
+	AT91_T_SAM9G45,
+	AT91_T_SAM9N12,
+	AT91_T_SAM9RL,
+	AT91_T_SAM9X5,
+};
+
+enum at91_soc_subtype {
+	AT91_ST_ANY = -1,	/* Match any type */
+	AT91_ST_NONE = 0,
+	/* AT91RM9200 */
+	AT91_ST_RM9200_BGA,
+	AT91_ST_RM9200_PQFP,
+	/* AT91SAM9260 */
+	AT91_ST_SAM9XE,
+	/* AT91SAM9G45 */
+	AT91_ST_SAM9G45,
+	AT91_ST_SAM9M10,
+	AT91_ST_SAM9G46,
+	AT91_ST_SAM9M11,
+	/* AT91SAM9X5 */
+	AT91_ST_SAM9G15,
+	AT91_ST_SAM9G25,
+	AT91_ST_SAM9G35,
+	AT91_ST_SAM9X25,
+	AT91_ST_SAM9X35,
+};
+
+enum at91_soc_family {
+	AT91_FAMILY_SAM9 = 0x19,
+	AT91_FAMILY_SAM9XE = 0x29,
+	AT91_FAMILY_RM92 = 0x92,
+};
+
+#define AT91_SOC_NAME_MAX 50
+
+typedef void (*DELAY_t)(int);
+typedef void (*cpu_reset_t)(void);
+typedef void (*clk_init_t)(void);
+
+struct at91_soc_data {
+	DELAY_t		soc_delay;		/* SoC specific delay function */
+	cpu_reset_t	soc_reset;		/* SoC specific reset function */
+	clk_init_t      soc_clock_init;		/* SoC specific clock init function */
+	const int	*soc_irq_prio;		/* SoC specific IRQ priorities */
+	const struct cpu_devs *soc_children;	/* SoC specific children list */
+	const uint32_t  *soc_pio_base;		/* SoC specific PIO base registers */
+	size_t          soc_pio_count;		/* Count of PIO units (not pins) in SoC */
+};
+
+struct at91_soc_info {
+	enum at91_soc_type type;
+	enum at91_soc_subtype subtype;
+	enum at91_soc_family family;
+	uint32_t cidr;
+	uint32_t exid;
+	char name[AT91_SOC_NAME_MAX];
+	uint32_t dbgu_base;
+	struct at91_soc_data *soc_data;
+};
+
+extern struct at91_soc_info soc_info;
+
+static inline int at91_is_rm92(void);
+static inline int at91_is_sam9(void);
+static inline int at91_is_sam9xe(void);
+static inline int at91_cpu_is(u_int cpu);
+
+static inline int
+at91_is_rm92(void)
+{
+
+	return (soc_info.type == AT91_T_RM9200);
+}
+
+static inline int
+at91_is_sam9(void)
+{
+
+	return (soc_info.family == AT91_FAMILY_SAM9);
+}
+
+static inline int
+at91_is_sam9xe(void)
+{
+
+	return (soc_info.family == AT91_FAMILY_SAM9XE);
+}
+
+static inline int
+at91_cpu_is(u_int cpu)
+{
+
+	return (soc_info.type == cpu);
+}
+
+void at91_add_child(device_t dev, int prio, const char *name, int unit,
+    bus_addr_t addr, bus_size_t size, int irq0, int irq1, int irq2);
+
+extern uint32_t at91_irq_system;
+extern uint32_t at91_master_clock;
+void at91_pmc_init_clock(void);
+
+#endif /* _AT91VAR_H_ */


Property changes on: trunk/sys/arm/at91/at91var.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/board_bwct.c
===================================================================
--- trunk/sys/arm/at91/board_bwct.c	                        (rev 0)
+++ trunk/sys/arm/at91/board_bwct.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,55 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2005-2008 Olivier Houchard.  All rights reserved.
+ * Copyright (c) 2005-2012 Warner Losh.  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 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 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: stable/10/sys/arm/at91/board_bwct.c 238465 2012-07-15 05:41:43Z imp $");
+#include <sys/param.h>
+#include <sys/systm.h>
+
+#include <machine/board.h>
+#include <arm/at91/at91board.h>
+#include <arm/at91/at91var.h>
+#include <arm/at91/at91rm9200var.h>
+
+BOARD_INIT long
+board_init(void)
+{
+
+	at91rm9200_set_subtype(AT91_ST_RM9200_BGA);
+
+	/*
+	 * I don't know anything at all about this board.
+	 */
+	at91rm9200_config_uart(AT91_ID_DBGU, 0, 0);   /* DBGU just Tx and Rx */
+
+	at91rm9200_config_mci(0);
+	/* Configure ethernet */
+
+	return (at91_ramsize());
+}
+
+ARM_BOARD(NONE, "BWCT special");


Property changes on: trunk/sys/arm/at91/board_bwct.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/board_eb9200.c
===================================================================
--- trunk/sys/arm/at91/board_eb9200.c	                        (rev 0)
+++ trunk/sys/arm/at91/board_eb9200.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,69 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2005-2008 Olivier Houchard.  All rights reserved.
+ * Copyright (c) 2005-2012 Warner Losh.  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 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 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: stable/10/sys/arm/at91/board_eb9200.c 266196 2014-05-15 21:21:47Z ian $");
+#include <sys/param.h>
+#include <sys/systm.h>
+
+#include <machine/board.h>
+#include <arm/at91/at91board.h>
+#include <arm/at91/at91var.h>
+#include <arm/at91/at91rm9200var.h>
+
+BOARD_INIT long
+board_init(void)
+{
+
+	at91rm9200_set_subtype(AT91_ST_RM9200_BGA);
+
+	/*
+	 * Setup the serial ports.
+	 * DBGU and USART0 are DB9 ports.
+	 * USART2 is IrDA.
+	 */
+	at91rm9200_config_uart(AT91_ID_DBGU, 0, 0);   /* DBGU just Tx and Rx */
+	at91rm9200_config_uart(AT91RM9200_ID_USART0, 1,
+	    AT91_UART_CTS | AT91_UART_RTS | AT91_UART_DTR | AT91_UART_DSR |
+	    AT91_UART_DCD | AT91_UART_RI);
+	at91rm9200_config_uart(AT91RM9200_ID_USART1, 2, 0);
+
+	at91rm9200_config_mci(1);
+
+	/* CFE interface */
+	/* SPI interface */
+	/* ethernet interface */
+	/* USB host */
+	/* USB device (gadget) */
+	/* TWI */
+	/* CF interface */
+	/* SmartMedia Interface */
+
+	return (at91_ramsize());
+}
+
+ARM_BOARD(ATEB9200, "Embest ATEB9200")


Property changes on: trunk/sys/arm/at91/board_eb9200.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/board_ethernut5.c
===================================================================
--- trunk/sys/arm/at91/board_ethernut5.c	                        (rev 0)
+++ trunk/sys/arm/at91/board_ethernut5.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,150 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Marius Strobl <marius at FreeBSD.org>
+ * 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.
+ */
+
+/*
+ * Ethernut 5 board support
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/at91/board_ethernut5.c 238442 2012-07-14 06:00:37Z imp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <machine/board.h>
+#include <arm/at91/at91_pioreg.h>
+#include <arm/at91/at91_piovar.h>
+#include <arm/at91/at91board.h>
+#include <arm/at91/at91sam9260reg.h>
+
+BOARD_INIT long
+board_init(void)
+{
+
+	/*
+	 * DBGU
+	 */
+	/* DRXD */
+	at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB14, 0);
+	/* DTXD */
+	at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB15, 1);
+
+	/*
+	 * EMAC
+	 */
+	/* ETX0 */
+	at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA12, 0);
+	/* ETX1 */
+	at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA13, 0);
+	/* ERX0 */
+	at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA14, 0);
+	/* ERX1 */
+	at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA15, 0);
+	/* ETXEN */
+	at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA16, 0);
+	/* ERXDV */
+	at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA17, 0);
+	/* ERXER */
+	at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA18, 0);
+	/* ETXCK */
+	at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA19, 0);
+	/* EMDC */
+	at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA20, 0);
+	/* EMDIO */
+	at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA21, 0);
+
+	/*
+	 * MMC
+	 */
+	/* MCDA0 */
+	at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA6, 1);
+	/* MCCDA */
+	at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA7, 1);
+	/* MCCK */
+	at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA8, 1);
+	/* MCDA1 */
+	at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA9, 1);
+	/* MCDA2 */
+	at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA10, 1);
+	/* MCDA3 */
+	at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA11, 1);
+
+	/*
+	 * SPI0
+	 */
+	/* MISO */
+	at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA0, 0);
+	/* MOSI */
+	at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA1, 0);
+	/* SPCK */
+	at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA2, 0);
+	/* NPCS0 */
+	at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA3, 0);
+
+	/*
+	 * TWI
+	 */
+	/* TWD */
+	at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA23, 1);
+	/* TWCK */
+	at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA24, 1);
+
+	/*
+	 * USART0
+	 */
+	/* TXD0 */
+	at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB4, 1);
+	/* RXD0 */
+	at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB5, 0);
+	/* DSR0 */
+	at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB22, 0);
+	/* DCD0 */
+	at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB23, 0);
+	/* DTR0 */
+	at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB24, 1);
+	/* RI0 */
+	at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB25, 0);
+	/* RTS0 */
+	at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB26, 1);
+	/* CTS0 */
+	at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB27, 0);
+
+	/*
+	 * USART2
+	 */
+	/* RTS2 */
+	at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA4, 1);
+	/* CTS2 */
+	at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA5, 0);
+	/* TXD2 */
+	at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB8, 1);
+	/* RXD2 */
+	at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB9, 0);
+
+	return (at91_ramsize());
+}
+
+ARM_BOARD(ETHERNUT5, "Ethernut 5")


Property changes on: trunk/sys/arm/at91/board_ethernut5.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/board_hl200.c
===================================================================
--- trunk/sys/arm/at91/board_hl200.c	                        (rev 0)
+++ trunk/sys/arm/at91/board_hl200.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,66 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2005-2008 Olivier Houchard.  All rights reserved.
+ * Copyright (c) 2005-2012 Warner Losh.  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 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 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: stable/10/sys/arm/at91/board_hl200.c 238465 2012-07-15 05:41:43Z imp $");
+#include <sys/param.h>
+#include <sys/systm.h>
+
+#include <machine/board.h>
+#include <arm/at91/at91board.h>
+#include <arm/at91/at91var.h>
+#include <arm/at91/at91rm92reg.h>
+#include <arm/at91/at91rm9200var.h>
+
+BOARD_INIT long
+board_init(void)
+{
+
+	at91rm9200_set_subtype(AT91_ST_RM9200_BGA);
+
+	/*
+	 * Unsure what all is in the HOTe HL200, but I do know there's
+	 * one serial port that isn't DBGU.  There's many other peripherals
+	 * that need to be configured here.
+	 */
+	at91rm9200_config_uart(AT91_ID_DBGU, 0, 0);   /* DBGU just Tx and Rx */
+	at91rm9200_config_uart(AT91RM9200_ID_USART0, 1, 0);   /* Tx and Rx */
+
+	at91rm9200_config_mci(0);			/* HOTe HL200 unknown 1 vs 4 wire */
+
+	/* Enable CF card slot */
+	/* Enable sound thing */
+	/* Enable VGA chip */
+	/* Enable ethernet */
+	/* Enable TWI + RTC */
+	/* Enable USB Host */
+	/* Enable USB Device (gadget) */
+
+	return (at91_ramsize());
+}
+
+ARM_BOARD(NONE, "HOTe 200");


Property changes on: trunk/sys/arm/at91/board_hl200.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/board_hl201.c
===================================================================
--- trunk/sys/arm/at91/board_hl201.c	                        (rev 0)
+++ trunk/sys/arm/at91/board_hl201.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,71 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2005-2008 Olivier Houchard.  All rights reserved.
+ * Copyright (c) 2005-2008 Warner Losh.  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 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 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: stable/10/sys/arm/at91/board_hl201.c 238189 2012-07-07 05:02:39Z imp $");
+#include <sys/param.h>
+#include <sys/systm.h>
+
+#include <machine/board.h>
+#include <arm/at91/at91board.h>
+#include <arm/at91/at91sam9g20reg.h>
+#include <arm/at91/at91_piovar.h>
+#include <arm/at91/at91_pio_sam9g20.h>
+
+BOARD_INIT long
+board_init(void)
+{
+	/* Setup Ethernet Pins */
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, 1<<7, 0);
+
+	at91_pio_gpio_input(AT91SAM9G20_PIOA_BASE, 1<<7);
+	at91_pio_gpio_set_deglitch(AT91SAM9G20_PIOA_BASE, 1<<7, 1);
+
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA19, 0);	/* ETXCK_EREFCK */
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA17, 0);	/* ERXDV */
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA14, 0);	/* ERX0 */
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA15, 0);	/* ERX1 */
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA18, 0);	/* ERXER */
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA16, 0);	/* ETXEN */
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA12, 0);	/* ETX0 */
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA13, 0);	/* ETX1 */
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA21, 0);	/* EMDIO */
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA20, 0);	/* EMDC */
+
+	at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA28, 0);	/* ECRS */
+	at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA29, 0);	/* ECOL */
+	at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA25, 0);	/* ERX2 */
+	at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA26, 0);	/* ERX3 */
+	at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA27, 0);	/* ERXCK */
+	at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA23, 0);	/* ETX2 */
+	at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA24, 0);	/* ETX3 */
+	at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA22, 0);	/* ETXER */
+
+	return (at91_ramsize());
+}
+
+ARM_BOARD(NONE, "HOTe 201");


Property changes on: trunk/sys/arm/at91/board_hl201.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/board_kb920x.c
===================================================================
--- trunk/sys/arm/at91/board_kb920x.c	                        (rev 0)
+++ trunk/sys/arm/at91/board_kb920x.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,67 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2005-2008 Olivier Houchard.  All rights reserved.
+ * Copyright (c) 2005-2012 Warner Losh.  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 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 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: stable/10/sys/arm/at91/board_kb920x.c 238465 2012-07-15 05:41:43Z imp $");
+#include <sys/param.h>
+#include <sys/systm.h>
+
+#include <machine/board.h>
+#include <arm/at91/at91board.h>
+#include <arm/at91/at91var.h>
+#include <arm/at91/at91rm9200var.h>
+
+BOARD_INIT long
+board_init(void)
+{
+
+	at91rm9200_set_subtype(AT91_ST_RM9200_PQFP);
+
+	/*
+	 * Setup the serial ports.
+	 * DBGU is the main one, although jumpers can make USART0 default.
+	 * USART1 is IrDA, and USART3 is optional RS485.
+	 */
+	at91rm9200_config_uart(AT91_ID_DBGU, 0, 0);   /* DBGU just Tx and Rx */
+	at91rm9200_config_uart(AT91RM9200_ID_USART0, 1, 0);   /* Tx and Rx */
+	at91rm9200_config_uart(AT91RM9200_ID_USART1, 2, 0);   /* Tx and Rx - IRDA */
+	at91rm9200_config_uart(AT91RM9200_ID_USART3, 3,	/* Tx, Rx, CTS, RTS - RS485 */
+	    AT91_UART_CTS | AT91_UART_RTS);
+
+	at91rm9200_config_mci(1);
+
+	/* CFE interface */
+	/* ethernet interface */
+	/* lcd interface */
+	/* USB host */
+	/* USB device (gadget) */
+	/* TWI */
+
+	return (at91_ramsize());
+}
+
+ARM_BOARD(KB9200, "Kwikbyte KB920x")


Property changes on: trunk/sys/arm/at91/board_kb920x.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/board_qila9g20.c
===================================================================
--- trunk/sys/arm/at91/board_qila9g20.c	                        (rev 0)
+++ trunk/sys/arm/at91/board_qila9g20.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,109 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2009 Greg Ansley.  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 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 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.
+ */
+
+/* Calao Systems QIL-9G20-Cxx
+ * http://www.calao-systems.com
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/at91/board_qila9g20.c 238189 2012-07-07 05:02:39Z imp $");
+#include <sys/param.h>
+#include <sys/systm.h>
+
+#include <machine/board.h>
+#include <arm/at91/at91board.h>
+#include <arm/at91/at91reg.h>
+#include <arm/at91/at91var.h>
+#include <arm/at91/at91sam9g20reg.h>
+#include <arm/at91/at91_piovar.h>
+#include <arm/at91/at91_pio_sam9g20.h>
+//#include <arm/at91/at91_led.h>
+
+#define AT91SAM9G20_LED_BASE AT91SAM9G20_PIOA_BASE
+#define AT91SAM9G20_LED_SIZE AT91SAM9G20_PIO_SIZE
+#define AT91SAM9G20_IRQ_LED AT91SAM9G20_IRQ_PIOA
+
+BOARD_INIT long
+board_init(void)
+{
+
+	//at91_led_create("power", 0, 9, 0);
+
+	/* PIOB's A periph: Turn USART 0's TX/RX pins */
+	at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB14_DRXD, 0);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB15_DTXD, 1);
+
+	/* PIOB's A periph: Turn USART 0's TX/RX pins */
+	at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB4_TXD0, 1);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB5_RXD0, 0);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB22_DSR0, 0);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB23_DCD0, 0);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB24_DTR0, 1);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB25_RI0, 0);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB26_RTS0, 1);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB27_CTS0, 0);
+
+	/* PIOB's A periph: Turn USART 1's TX/RX pins */
+	at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB6_TXD1, 1);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB7_RXD1, 0);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB28_RTS1, 1);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB29_CTS1, 0);
+
+	/*  TWI Two-wire Serial Data */
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA23_TWD,  1);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA24_TWCK, 1);
+
+	/*  Multimedia Card  */
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA6_MCDA0,  1);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA7_MCCDA,  1);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA8_MCCK,   1);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA9_MCDA1,  1);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA10_MCDA2, 1);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA11_MCDA3, 1);
+
+	/* SPI0 to DataFlash */
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PA0_SPI0_MISO,  0);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PA1_SPI0_MOSI,  0);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PA2_SPI0_SPCK,  0);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PA3_SPI0_NPCS0, 0);
+
+	/* EMAC */
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA19_ETXCK,  0);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA21_EMDIO,  0);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA20_EMDC,   0);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA17_ERXDV,  0);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA16_ETXEN,  0);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA12_ETX0 ,  0);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA13_ETX1,   0);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA14_ERX0,   0);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA15_ERX1,   0);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA18_ERXER,  0);
+
+
+	return (at91_ramsize());
+}
+
+ARM_BOARD(QIL_A9G20, "Calico System QIL-9G20-Cxx");


Property changes on: trunk/sys/arm/at91/board_qila9g20.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/board_sam9260ek.c
===================================================================
--- trunk/sys/arm/at91/board_sam9260ek.c	                        (rev 0)
+++ trunk/sys/arm/at91/board_sam9260ek.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,263 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Marius Strobl <marius at FreeBSD.org>
+ * 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.
+ */
+
+/*
+ * Ethernut 5 board support
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/at91/board_sam9260ek.c 266097 2014-05-14 23:51:07Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <machine/board.h>
+#include <arm/at91/at91_pioreg.h>
+#include <arm/at91/at91_piovar.h>
+#include <arm/at91/at91board.h>
+#include <arm/at91/at91sam9260reg.h>
+#include <arm/at91/at91_smc.h>
+#include <arm/at91/at91_gpio.h>
+#include <dev/nand/nfc_at91.h>
+
+static struct at91_smc_init nand_smc = {
+	.ncs_rd_setup		= 0,
+	.nrd_setup		= 1,
+	.ncs_wr_setup		= 0,
+	.nwe_setup		= 1,
+
+	.ncs_rd_pulse		= 3,
+	.nrd_pulse		= 3,
+	.ncs_wr_pulse		= 3,
+	.nwe_pulse		= 3,
+
+	.nrd_cycle		= 5,
+	.nwe_cycle		= 5,
+
+	.mode			= SMC_MODE_READ | SMC_MODE_WRITE | SMC_MODE_EXNW_DISABLED,
+	.tdf_cycles		= 2,
+};
+
+static struct at91_nand_params nand_param = {
+	.ale			= 1u << 21,
+	.cle			= 1u << 22,
+	.width			= 8,
+	.rnb_pin		= AT91_PIN_PC13,
+	.nce_pin		= AT91_PIN_PC14,
+	.cs			= 3,
+};
+
+static void
+bi_dbgu(void)
+{
+
+	/*
+	 * DBGU
+	 */
+	/* DRXD */
+	at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB14, 0);
+	/* DTXD */
+	at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB15, 1);
+}
+
+static void
+bi_emac(void)
+{
+
+	/*
+	 * EMAC
+	 */
+	/* ETX0 */
+	at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA12, 0);
+	/* ETX1 */
+	at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA13, 0);
+	/* ERX0 */
+	at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA14, 0);
+	/* ERX1 */
+	at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA15, 0);
+	/* ETXEN */
+	at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA16, 0);
+	/* ERXDV */
+	at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA17, 0);
+	/* ERXER */
+	at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA18, 0);
+	/* ETXCK */
+	at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA19, 0);
+	/* EMDC */
+	at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA20, 0);
+	/* EMDIO */
+	at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA21, 0);
+	/* Not RMII */
+	/* ETX2 */
+	at91_pio_use_periph_b(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA10, 0);
+	/* ETX3 */
+	at91_pio_use_periph_b(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA11, 0);
+	/* ETXER */
+	at91_pio_use_periph_b(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA22, 0);
+	/* ERX2 */
+	at91_pio_use_periph_b(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA25, 0);
+	/* ERX3 */
+	at91_pio_use_periph_b(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA26, 0);
+	/* ERXCK */
+	at91_pio_use_periph_b(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA27, 0);
+	/* ECRS */
+	at91_pio_use_periph_b(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA28, 0);
+	/* ECOL */
+	at91_pio_use_periph_b(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA29, 0);
+}
+
+static void
+bi_mmc(void)
+{
+
+	/*
+	 * MMC, wired to socket B.
+	 */
+	/* MCDB0 */
+	at91_pio_use_periph_b(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA0, 1);
+	/* MCCDB */
+	at91_pio_use_periph_b(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA1, 1);
+	/* MCDB3 */
+	at91_pio_use_periph_b(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA3, 1);
+	/* MCDB2 */
+	at91_pio_use_periph_b(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA4, 1);
+	/* MCDB1 */
+	at91_pio_use_periph_b(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA5, 1);
+	/* MCCK */
+	at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA8, 1);
+
+	/*
+	 * SPI0 and MMC are wired together, since we don't support sharing
+	 * don't support the dataflash.  But if you did, you'd have to
+	 * use CS0 and CS1.
+	 */
+}
+
+static void
+bi_iic(void)
+{
+
+	/*
+	 * TWI.  Only one child on the iic bus, which we take care of
+	 * via hints.
+	 */
+	/* TWD */
+	at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA23, 1);
+	/* TWCK */
+	at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA24, 1);
+}
+
+static void
+bi_usart0(void)
+{
+
+	/*
+	 * USART0
+	 */
+	/* TXD0 */
+	at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB4, 1);
+	/* RXD0 */
+	at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB5, 0);
+	/* DSR0 */
+	at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB22, 0);
+	/* DCD0 */
+	at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB23, 0);
+	/* DTR0 */
+	at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB24, 1);
+	/* RI0 */
+	at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB25, 0);
+	/* RTS0 */
+	at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB26, 1);
+	/* CTS0 */
+	at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB27, 0);
+}
+
+static void
+bi_usart1(void)
+{
+	/*
+	 * USART1
+	 */
+	/* RTS1 */
+	at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB28, 1);
+	/* CTS1 */
+	at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB29, 0);
+	/* TXD1 */
+	at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB6, 1);
+	/* RXD1 */
+	at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB7, 0);
+}
+
+static void
+bi_nand(void)
+{
+	/* Samsung 256MB SLC Flash */
+
+	/* Setup Static Memory Controller */
+	at91_smc_setup(0, 3, &nand_smc);
+	at91_enable_nand(&nand_param);
+
+	/*
+	 * This assumes
+	 *  - RNB is on pin PC13
+	 *  - CE is on pin PC14
+	 *
+	 * Nothing actually uses RNB right now.
+	 *
+	 * For CE, this currently asserts it during board setup and leaves it
+	 * that way forever.
+	 *
+	 * All this can go away when the gpio pin-renumbering happens...
+	 */
+	at91_pio_use_gpio(AT91SAM9260_PIOC_BASE, AT91C_PIO_PC13 | AT91C_PIO_PC14);
+	at91_pio_gpio_input(AT91SAM9260_PIOC_BASE, AT91C_PIO_PC13);	/* RNB */
+	at91_pio_gpio_output(AT91SAM9260_PIOC_BASE, AT91C_PIO_PC14, 0);	/* nCS */
+	at91_pio_gpio_clear(AT91SAM9260_PIOC_BASE, AT91C_PIO_PC14);	/* Assert nCS */
+}
+
+BOARD_INIT long
+board_init(void)
+{
+	bi_dbgu();
+	bi_emac();
+	bi_mmc();
+
+	/*
+	 * SPI1 is wired to a audio CODEC that we don't support, so
+	 * give it a pass.
+	 */
+
+	bi_iic();
+	bi_usart0();
+	bi_usart1();
+	/* USART2 - USART5 aren't wired up, except via PIO pins, ignore them. */
+
+	bi_nand();
+
+	return (at91_ramsize());
+}
+
+ARM_BOARD(AT91SAM9260EK, "Atmel SMA9260-EK")


Property changes on: trunk/sys/arm/at91/board_sam9260ek.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/board_sam9g20ek.c
===================================================================
--- trunk/sys/arm/at91/board_sam9g20ek.c	                        (rev 0)
+++ trunk/sys/arm/at91/board_sam9g20ek.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,128 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2009 Greg Ansley.  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 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 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.
+ */
+
+/*
+ * This board file can be used for both:
+ * Atmel SAM9G20-EK Development Card
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/at91/board_sam9g20ek.c 238189 2012-07-07 05:02:39Z imp $");
+#include <sys/param.h>
+#include <sys/systm.h>
+
+#include <machine/board.h>
+#include <arm/at91/at91board.h>
+#include <arm/at91/at91reg.h>
+#include <arm/at91/at91var.h>
+#include <arm/at91/at91sam9g20reg.h>
+#include <arm/at91/at91_piovar.h>
+#include <arm/at91/at91_pio_sam9g20.h>
+//#include <arm/at91/at91_led.h>
+
+BOARD_INIT long
+board_init(void)
+{
+	/* PIOB's A periph: Turn USART 0's TX/RX pins */
+	at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB14_DRXD, 0);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB15_DTXD, 1);
+
+	/* PIOB's A periph: Turn USART 0's TX/RX pins */
+	at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB4_TXD0, 1);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB5_RXD0, 0);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB22_DSR0, 0);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB23_DCD0, 0);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB24_DTR0, 1);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB25_RI0, 0);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB26_RTS0, 1);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB27_CTS0, 0);
+
+	/* PIOB's A periph: Turn USART 1's TX/RX pins */
+	at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB6_TXD1, 1);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB7_RXD1, 0);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB28_RTS1, 1);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB29_CTS1, 0);
+
+	/*  TWI Two-wire Serial Data */
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA23_TWD,  1);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA24_TWCK, 1);
+
+#if 1
+	/*
+	 * Turn off Clock to DataFlash, conflicts with MCI clock.
+	 */
+	at91_pio_use_gpio(AT91SAM9G20_PIOA_BASE,AT91C_PIO_PA2);
+	at91_pio_gpio_input(AT91SAM9G20_PIOA_BASE,AT91C_PIO_PA2);
+
+	/* Turn off chip select to DataFlash */
+	at91_pio_gpio_output(AT91SAM9G20_PIOC_BASE,AT91C_PIO_PC11, 0);
+	at91_pio_gpio_set(AT91SAM9G20_PIOC_BASE,AT91C_PIO_PC11);
+	at91_pio_use_gpio(AT91SAM9G20_PIOC_BASE,AT91C_PIO_PC11);
+
+	/*  Multimedia Card  */
+	at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA0_MCDB0, 1);
+	at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA1_MCCDB, 1);
+	at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA3_MCDB3, 1);
+	at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA4_MCDB2, 1);
+	at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA5_MCDB1, 1);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA8_MCCK,  1);
+	at91_pio_use_gpio(AT91SAM9G20_PIOC_BASE, AT91C_PIO_PC9);
+#else
+	/* SPI0 to DataFlash */
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA0, 0);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA1, 0);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA2, 0);
+	at91_pio_use_periph_b(AT91SAM9G20_PIOC_BASE, AT91C_PIO_PC11,0);
+
+	at91_pio_gpio_input(AT91SAM9G20_PIOA_BASE,AT91C_PIO_PA8);
+	at91_pio_use_gpio(AT91SAM9G20_PIOA_BASE,AT91C_PIO_PA8);
+#endif
+
+	/* EMAC */
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA12_ETX0 ,  0);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA13_ETX1,   0);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA14_ERX0,   0);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA15_ERX1,   0);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA16_ETXEN,  0);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA17_ERXDV,  0);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA18_ERXER,  0);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA19_ETXCK,  0);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA20_EMDC,   0);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA21_EMDIO,  0);
+
+	at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA10_ETX2_0, 0);
+	at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA11_ETX3_0, 0);
+	at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA22_ETXER,  0);
+	at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA25_ERX2,   0);
+	at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA26_ERX3,   0);
+	at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA27_ERXCK,  0);
+	at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA28_ECRS,   0);
+	at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA29_ECOL,   0);
+
+	return (at91_ramsize());
+}
+
+ARM_BOARD(AT91SAM9G20, "Atmel SAM9G20-EK Development Card");


Property changes on: trunk/sys/arm/at91/board_sam9g20ek.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/board_sam9x25ek.c
===================================================================
--- trunk/sys/arm/at91/board_sam9x25ek.c	                        (rev 0)
+++ trunk/sys/arm/at91/board_sam9x25ek.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,129 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2009 Greg Ansley.  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 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 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.
+ */
+
+/* 
+ * This board file can be used for both:
+ * SAM9X26EK board
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/at91/board_sam9x25ek.c 238189 2012-07-07 05:02:39Z imp $");
+#include <sys/param.h>
+#include <sys/systm.h>
+
+#include <machine/board.h>
+#include <arm/at91/at91board.h>
+#include <arm/at91/at91reg.h>
+#include <arm/at91/at91var.h>
+#include <arm/at91/at91sam9g20reg.h>
+#include <arm/at91/at91_piovar.h>
+#include <arm/at91/at91_pio_sam9g20.h>
+//#include <arm/at91/at91_led.h>
+
+BOARD_INIT long
+board_init(void)
+{
+#if 0
+	/* PIOB's A periph: Turn USART 0's TX/RX pins */
+	at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB14_DRXD, 0);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB15_DTXD, 1);
+
+	/* PIOB's A periph: Turn USART 0's TX/RX pins */
+	at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB4_TXD0, 1);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB5_RXD0, 0);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB22_DSR0, 0);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB23_DCD0, 0);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB24_DTR0, 1);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB25_RI0, 0);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB26_RTS0, 1);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB27_CTS0, 0);
+
+	/* PIOB's A periph: Turn USART 1's TX/RX pins */
+	at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB6_TXD1, 1);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB7_RXD1, 0);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB28_RTS1, 1);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOB_BASE, AT91C_PB29_CTS1, 0);
+
+	/*  TWI Two-wire Serial Data */
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA23_TWD,  1);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA24_TWCK, 1);
+
+#if 1
+	/* 
+	 * Turn off Clock to DataFlash, conflicts with MCI clock.
+	 */
+	at91_pio_use_gpio(AT91SAM9G20_PIOA_BASE,AT91C_PIO_PA2);
+	at91_pio_gpio_input(AT91SAM9G20_PIOA_BASE,AT91C_PIO_PA2);
+
+	/* Turn off chip select to DataFlash */
+	at91_pio_gpio_output(AT91SAM9G20_PIOC_BASE,AT91C_PIO_PC11, 0);
+	at91_pio_gpio_set(AT91SAM9G20_PIOC_BASE,AT91C_PIO_PC11);
+	at91_pio_use_gpio(AT91SAM9G20_PIOC_BASE,AT91C_PIO_PC11);
+
+	/*  Multimedia Card  */
+	at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA0_MCDB0, 1);
+	at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA1_MCCDB, 1);
+	at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA3_MCDB3, 1);
+	at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA4_MCDB2, 1);
+	at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA5_MCDB1, 1);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA8_MCCK,  1);
+	at91_pio_use_gpio(AT91SAM9G20_PIOC_BASE, AT91C_PIO_PC9);
+#else
+	/* SPI0 to DataFlash */
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA0, 0);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA1, 0);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA2, 0);
+	at91_pio_use_periph_b(AT91SAM9G20_PIOC_BASE, AT91C_PIO_PC11,0);
+
+	at91_pio_gpio_input(AT91SAM9G20_PIOA_BASE,AT91C_PIO_PA8);
+	at91_pio_use_gpio(AT91SAM9G20_PIOA_BASE,AT91C_PIO_PA8);
+#endif
+
+	/* EMAC */
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA12_ETX0 ,  0);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA13_ETX1,   0);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA14_ERX0,   0);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA15_ERX1,   0);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA16_ETXEN,  0);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA17_ERXDV,  0);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA18_ERXER,  0);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA19_ETXCK,  0);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA20_EMDC,   0);
+	at91_pio_use_periph_a(AT91SAM9G20_PIOA_BASE,AT91C_PA21_EMDIO,  0);
+
+	at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA10_ETX2_0, 0);
+	at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA11_ETX3_0, 0);
+	at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA22_ETXER,  0);
+	at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA25_ERX2,   0);
+	at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA26_ERX3,   0);
+	at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA27_ERXCK,  0);
+	at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA28_ECRS,   0);
+	at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE,AT91C_PA29_ECOL,   0);
+#endif
+	return (at91_ramsize());
+}
+
+ARM_BOARD(AT91SAM9X5EK, "Atmel AT91SAM9x-EK Evaluation Board");


Property changes on: trunk/sys/arm/at91/board_sam9x25ek.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/board_sn9g45.c
===================================================================
--- trunk/sys/arm/at91/board_sn9g45.c	                        (rev 0)
+++ trunk/sys/arm/at91/board_sn9g45.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,56 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2009 Greg Ansley.  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 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 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.
+ */
+
+/*
+ * DesignA Electronics Snapper9g45
+ * http://www.designa-electronics.com/
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/at91/board_sn9g45.c 238846 2012-07-27 16:38:02Z imp $");
+#include <sys/param.h>
+#include <sys/systm.h>
+
+#include <machine/board.h>
+#include <arm/at91/at91board.h>
+#include <arm/at91/at91reg.h>
+#include <arm/at91/at91var.h>
+#include <arm/at91/at91sam9g45reg.h>
+#include <arm/at91/at91_piovar.h>
+#include <arm/at91/at91_pio_sam9g45.h>
+
+BOARD_INIT long
+board_init(void)
+{
+
+	/* PIOB's A periph: Turn the debug USART's TX/RX pins */
+	at91_pio_use_periph_a(AT91SAM9G45_PIOB_BASE, AT91C_PB12_DRXD, 0);
+	at91_pio_use_periph_a(AT91SAM9G45_PIOB_BASE, AT91C_PB13_DTXD, 1);
+
+	return (at91_ramsize());
+}
+
+ARM_BOARD(SNAPPER9G45, "DesignA Electronics Snapper9G45");


Property changes on: trunk/sys/arm/at91/board_sn9g45.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/board_tsc4370.c
===================================================================
--- trunk/sys/arm/at91/board_tsc4370.c	                        (rev 0)
+++ trunk/sys/arm/at91/board_tsc4370.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,73 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2005-2008 Olivier Houchard.  All rights reserved.
+ * Copyright (c) 2005-2012 Warner Losh.  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 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 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: stable/10/sys/arm/at91/board_tsc4370.c 238465 2012-07-15 05:41:43Z imp $");
+#include <sys/param.h>
+#include <sys/systm.h>
+
+#include <machine/board.h>
+#include <arm/at91/at91board.h>
+#include <arm/at91/at91var.h>
+#include <arm/at91/at91rm92reg.h>
+#include <arm/at91/at91rm9200var.h>
+#include <arm/at91/at91_piovar.h>
+#include <arm/at91/at91_pioreg.h>
+
+BOARD_INIT long
+board_init(void)
+{
+
+	at91rm9200_set_subtype(AT91_ST_RM9200_PQFP);
+
+	at91rm9200_config_uart(AT91_ID_DBGU, 0, 0);   /* DBGU just Tx and Rx */
+	at91rm9200_config_uart(AT91RM9200_ID_USART0, 1, 0);   /* Tx and Rx */
+	at91rm9200_config_uart(AT91RM9200_ID_USART1, 2, 0);   /* Tx and Rx */
+	at91rm9200_config_uart(AT91RM9200_ID_USART2, 3, 0);   /* Tx and Rx */
+	at91rm9200_config_uart(AT91RM9200_ID_USART3, 4, 0);   /* Tx and Rx */
+
+	at91rm9200_config_mci(0);			/* tsc4370 board has only 1 wire */
+							/* Newer boards may have 4 wires */
+
+	/* Configure TWI */
+	/* Configure SPI + dataflash */
+	/* Configure SSC */
+	/* Configure USB Host */
+	/* Configure FPGA attached to chip selects */
+
+	/* Pin assignment */
+	/* Assert PA24 low -- talk to rubidium */
+	at91_pio_use_gpio(AT91RM92_PIOA_BASE, AT91C_PIO_PA24);
+	at91_pio_gpio_output(AT91RM92_PIOA_BASE, AT91C_PIO_PA24, 0);
+	at91_pio_gpio_clear(AT91RM92_PIOA_BASE, AT91C_PIO_PA24);
+	at91_pio_use_gpio(AT91RM92_PIOB_BASE,
+	    AT91C_PIO_PB16 | AT91C_PIO_PB17 | AT91C_PIO_PB18 | AT91C_PIO_PB19);
+
+	return (at91_ramsize());
+}
+
+ARM_BOARD(NONE, "TSC4370 Controller Board");


Property changes on: trunk/sys/arm/at91/board_tsc4370.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/files.at91
===================================================================
--- trunk/sys/arm/at91/files.at91	                        (rev 0)
+++ trunk/sys/arm/at91/files.at91	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,59 @@
+# $FreeBSD: stable/10/sys/arm/at91/files.at91 278727 2015-02-13 22:32:02Z ian $
+arm/arm/bus_space_generic.c	standard
+arm/arm/cpufunc_asm_arm9.S	standard
+arm/at91/at91_machdep.c		standard
+arm/at91/at91_aic.c		standard
+arm/at91/at91.c			standard
+arm/at91/at91_cfata.c		optional	at91_cfata
+arm/at91/at91_mci.c		optional	at91_mci
+dev/nand/nfc_at91.c		optional	nand
+arm/at91/at91_pio.c		standard
+arm/at91/at91_pmc.c		standard
+arm/at91/at91_pit.c		optional	at91sam9
+arm/at91/at91_reset.S		optional	at91sam9
+arm/at91/at91_rst.c		optional	at91sam9
+arm/at91/at91_rtc.c		optional	at91_rtc
+arm/at91/at91_smc.c		standard
+arm/at91/at91_spi.c		optional	at91_spi		\
+	dependency	"spibus_if.h"
+arm/at91/at91_ssc.c		optional	at91_ssc
+arm/at91/at91_st.c		optional	at91rm9200
+arm/at91/at91_tc.c		optional	at91_tc
+arm/at91/at91_twi.c		optional	at91_twi
+arm/at91/at91_wdt.c		optional	at91_wdt
+arm/at91/if_ate.c		optional	ate
+arm/at91/if_macb.c		optional	macb
+arm/at91/uart_bus_at91usart.c	optional	uart
+arm/at91/uart_cpu_at91usart.c	optional	uart
+arm/at91/uart_dev_at91usart.c	optional	uart
+#
+# All the "systems on a chip" we support
+#
+arm/at91/at91soc.c		standard
+arm/at91/at91rm9200.c		optional	at91rm9200
+arm/at91/at91rm9200_devices.c	optional	at91rm9200
+arm/at91/at91sam9260.c		optional	at91sam9260
+arm/at91/at91sam9g20.c		optional	at91sam9g20
+arm/at91/at91sam9g45.c		optional	at91sam9g45
+arm/at91/at91sam9x5.c		optional	at91sam9x5
+#
+# All the boards we support
+#
+arm/at91/board_bwct.c		optional	at91_board_bwct
+arm/at91/board_eb9200.c		optional	at91_board_eb9200
+arm/at91/board_ethernut5.c	optional	at91_board_ethernut5
+arm/at91/board_hl200.c		optional	at91_board_hl200
+arm/at91/board_hl201.c		optional	at91_board_hl201
+arm/at91/board_kb920x.c		optional	at91_board_kb920x
+arm/at91/board_qila9g20.c	optional	at91_board_qila9g20
+arm/at91/board_sam9260ek.c	optional	at91_board_sam9260ek
+arm/at91/board_sam9g20ek.c	optional	at91_board_sam9g20ek
+arm/at91/board_sam9x25ek.c	optional	at91_board_sam9x25ek
+arm/at91/board_sn9g45.c 	optional	at91_board_sn9g45
+arm/at91/board_tsc4370.c	optional	at91_board_tsc4370
+#
+# usb
+#
+dev/usb/controller/at91dci.c		optional	at91_dci
+dev/usb/controller/at91dci_atmelarm.c	optional	at91_dci
+dev/usb/controller/ohci_atmelarm.c	optional	ohci


Property changes on: trunk/sys/arm/at91/files.at91
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/at91/if_ate.c
===================================================================
--- trunk/sys/arm/at91/if_ate.c	                        (rev 0)
+++ trunk/sys/arm/at91/if_ate.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,1480 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2006 M. Warner Losh.  All rights reserved.
+ * Copyright (c) 2009 Greg Ansley.  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 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 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.
+ */
+
+/* TODO
+ *
+ * 1) Turn on the clock in pmc?  Turn off?
+ * 2) GPIO initializtion in board setup code.
+ */
+
+#include "opt_platform.h"
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/at91/if_ate.c 266196 2014-05-15 21:21:47Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/module.h>
+#include <sys/rman.h>
+#include <sys/socket.h>
+#include <sys/sockio.h>
+#include <sys/sysctl.h>
+
+#include <machine/bus.h>
+
+#include <net/ethernet.h>
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <net/if_dl.h>
+#include <net/if_media.h>
+#include <net/if_mib.h>
+#include <net/if_types.h>
+#include <net/if_var.h>
+
+#ifdef INET
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#endif
+
+#include <net/bpf.h>
+#include <net/bpfdesc.h>
+
+#include <dev/mii/mii.h>
+#include <dev/mii/miivar.h>
+
+#include "opt_at91.h"
+#include <arm/at91/at91reg.h>
+#include <arm/at91/at91var.h>
+#include <arm/at91/if_atereg.h>
+
+#ifdef FDT
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+#endif
+
+#include "miibus_if.h"
+
+/*
+ * Driver-specific flags.
+ */
+#define	ATE_FLAG_DETACHING	0x01
+#define	ATE_FLAG_MULTICAST	0x02
+
+/*
+ * Old EMAC assumes whole packet fits in one buffer;
+ * new EBACB assumes all receive buffers are 128 bytes
+ */
+#define	RX_BUF_SIZE(sc)	(sc->is_emacb ? 128 : MCLBYTES)
+
+/*
+ * EMACB has an 11 bit counter for Rx/Tx Descriptors
+ * for max total of 1024 decriptors each.
+ */
+#define	ATE_MAX_RX_DESCR	1024
+#define	ATE_MAX_TX_DESCR	1024
+
+/* How many buffers to allocate */
+#define	ATE_MAX_TX_BUFFERS	4	/* We have ping-pong tx buffers */
+
+/* How much memory to use for rx buffers */
+#define	ATE_RX_MEMORY		(ATE_MAX_RX_DESCR * 128)
+
+/* Actual number of descriptors we allocate */
+#define	ATE_NUM_RX_DESCR	ATE_MAX_RX_DESCR
+#define	ATE_NUM_TX_DESCR	ATE_MAX_TX_BUFFERS
+
+#if ATE_NUM_TX_DESCR > ATE_MAX_TX_DESCR
+#error "Can't have more TX buffers that descriptors"
+#endif
+#if ATE_NUM_RX_DESCR > ATE_MAX_RX_DESCR
+#error "Can't have more RX buffers that descriptors"
+#endif
+
+/* Wrap indexes the same way the hardware does */
+#define	NEXT_RX_IDX(sc, cur)	\
+    ((sc->rx_descs[cur].addr & ETH_WRAP_BIT) ? 0 : (cur + 1))
+
+#define	NEXT_TX_IDX(sc, cur)	\
+    ((sc->tx_descs[cur].status & ETHB_TX_WRAP) ? 0 : (cur + 1))
+
+struct ate_softc
+{
+	struct ifnet	*ifp;		/* ifnet pointer */
+	struct mtx	sc_mtx;		/* Basically a perimeter lock */
+	device_t	dev;		/* Myself */
+	device_t	miibus;		/* My child miibus */
+	struct resource *irq_res;	/* IRQ resource */
+	struct resource	*mem_res;	/* Memory resource */
+	struct callout  tick_ch;	/* Tick callout */
+	struct ifmib_iso_8802_3 mibdata; /* Stuff for network mgmt */
+	bus_dma_tag_t   mtag;		/* bus dma tag for mbufs */
+	bus_dma_tag_t   rx_tag;
+	bus_dma_tag_t   rx_desc_tag;
+	bus_dmamap_t    rx_desc_map;
+	bus_dmamap_t    rx_map[ATE_MAX_RX_DESCR];
+	bus_addr_t	rx_desc_phys;   /* PA of rx descriptors */
+	eth_rx_desc_t   *rx_descs;	/* VA of rx descriptors */
+	void		*rx_buf[ATE_NUM_RX_DESCR]; /* RX buffer space */
+	int		rxhead;		/* Current RX map/desc index */
+	uint32_t	rx_buf_size;    /* Size of Rx buffers */
+
+	bus_dma_tag_t   tx_desc_tag;
+	bus_dmamap_t    tx_desc_map;
+	bus_dmamap_t    tx_map[ATE_MAX_TX_BUFFERS];
+	bus_addr_t	tx_desc_phys;   /* PA of tx descriptors */
+	eth_tx_desc_t   *tx_descs;	/* VA of tx descriptors */
+	int		txhead;		/* Current TX map/desc index */
+	int		txtail;		/* Current TX map/desc index */
+	struct mbuf	*sent_mbuf[ATE_MAX_TX_BUFFERS]; /* Sent mbufs */
+	void		*intrhand;	/* Interrupt handle */
+	int		flags;
+	int		if_flags;
+	int		use_rmii;
+	int		is_emacb;	/* SAM9x hardware version */
+};
+
+static inline uint32_t
+RD4(struct ate_softc *sc, bus_size_t off)
+{
+
+	return (bus_read_4(sc->mem_res, off));
+}
+
+static inline void
+WR4(struct ate_softc *sc, bus_size_t off, uint32_t val)
+{
+
+	bus_write_4(sc->mem_res, off, val);
+}
+
+static inline void
+BARRIER(struct ate_softc *sc, bus_size_t off, bus_size_t len, int flags)
+{
+
+	bus_barrier(sc->mem_res, off, len, flags);
+}
+
+#define	ATE_LOCK(_sc)		mtx_lock(&(_sc)->sc_mtx)
+#define	ATE_UNLOCK(_sc)		mtx_unlock(&(_sc)->sc_mtx)
+#define	ATE_LOCK_INIT(_sc)					\
+	mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->dev),	\
+	    MTX_NETWORK_LOCK, MTX_DEF)
+#define	ATE_LOCK_DESTROY(_sc)	mtx_destroy(&_sc->sc_mtx);
+#define	ATE_ASSERT_LOCKED(_sc)	mtx_assert(&_sc->sc_mtx, MA_OWNED);
+#define	ATE_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED);
+
+static devclass_t ate_devclass;
+
+/*
+ * ifnet entry points.
+ */
+static void	ateinit_locked(void *);
+static void	atestart_locked(struct ifnet *);
+
+static void	ateinit(void *);
+static void	atestart(struct ifnet *);
+static void	atestop(struct ate_softc *);
+static int	ateioctl(struct ifnet * ifp, u_long, caddr_t);
+
+/*
+ * Bus entry points.
+ */
+static int	ate_probe(device_t dev);
+static int	ate_attach(device_t dev);
+static int	ate_detach(device_t dev);
+static void	ate_intr(void *);
+
+/*
+ * Helper routines.
+ */
+static int	ate_activate(device_t dev);
+static void	ate_deactivate(struct ate_softc *sc);
+static int	ate_ifmedia_upd(struct ifnet *ifp);
+static void	ate_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr);
+static int	ate_get_mac(struct ate_softc *sc, u_char *eaddr);
+static void	ate_set_mac(struct ate_softc *sc, u_char *eaddr);
+static void	ate_rxfilter(struct ate_softc *sc);
+
+static int	ate_miibus_readreg(device_t dev, int phy, int reg);
+
+static int	ate_miibus_writereg(device_t dev, int phy, int reg, int data);
+/*
+ * The AT91 family of products has the ethernet interface called EMAC.
+ * However, it isn't self identifying.  It is anticipated that the parent bus
+ * code will take care to only add ate devices where they really are.  As
+ * such, we do nothing here to identify the device and just set its name.
+ */
+static int
+ate_probe(device_t dev)
+{
+#ifdef FDT
+	if (!ofw_bus_is_compatible(dev, "cdns,at32ap7000-macb"))
+		return (ENXIO);
+#endif
+	device_set_desc(dev, "EMAC");
+	return (0);
+}
+
+static int
+ate_attach(device_t dev)
+{
+	struct ate_softc *sc;
+	struct ifnet *ifp = NULL;
+	struct sysctl_ctx_list *sctx;
+	struct sysctl_oid *soid;
+	u_char eaddr[ETHER_ADDR_LEN];
+	uint32_t rnd;
+	int rid, err;
+
+	sc = device_get_softc(dev);
+	sc->dev = dev;
+	ATE_LOCK_INIT(sc);
+
+	rid = 0;
+	sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	    RF_ACTIVE);
+	if (sc->mem_res == NULL) {
+		device_printf(dev, "could not allocate memory resources.\n");
+		err = ENOMEM;
+		goto out;
+	}
+	rid = 0;
+	sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+	    RF_ACTIVE);
+	if (sc->irq_res == NULL) {
+		device_printf(dev, "could not allocate interrupt resources.\n");
+		err = ENOMEM;
+		goto out;
+	}
+
+	/* New or old version, chooses buffer size. */
+	sc->is_emacb = at91_is_sam9() || at91_is_sam9xe();
+	sc->rx_buf_size = RX_BUF_SIZE(sc);
+
+	err = ate_activate(dev);
+	if (err)
+		goto out;
+
+	/* Default to what boot rom did */
+	if (!sc->is_emacb)
+		sc->use_rmii =
+		    (RD4(sc, ETH_CFG) & ETH_CFG_RMII) == ETH_CFG_RMII;
+	else
+		sc->use_rmii =
+		    (RD4(sc, ETHB_UIO) & ETHB_UIO_RMII) == ETHB_UIO_RMII;
+
+#ifdef AT91_ATE_USE_RMII
+	/* Compile time override */
+	sc->use_rmii = 1;
+#endif
+	/* Sysctls */
+	sctx = device_get_sysctl_ctx(dev);
+	soid = device_get_sysctl_tree(dev);
+	SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "rmii",
+	    CTLFLAG_RW, &sc->use_rmii, 0, "rmii in use");
+
+	/* Calling atestop before ifp is set is OK. */
+	ATE_LOCK(sc);
+	atestop(sc);
+	ATE_UNLOCK(sc);
+	callout_init_mtx(&sc->tick_ch, &sc->sc_mtx, 0);
+
+	if ((err = ate_get_mac(sc, eaddr)) != 0) {
+		/* No MAC address configured. Generate the random one. */
+		if (bootverbose)
+			device_printf(dev,
+			    "Generating random ethernet address.\n");
+		rnd = arc4random();
+
+		/*
+		 * Set OUI to convenient locally assigned address.  'b'
+		 * is 0x62, which has the locally assigned bit set, and
+		 * the broadcast/multicast bit clear.
+		 */
+		eaddr[0] = 'b';
+		eaddr[1] = 's';
+		eaddr[2] = 'd';
+		eaddr[3] = (rnd >> 16) & 0xff;
+		eaddr[4] = (rnd >>  8) & 0xff;
+		eaddr[5] = (rnd >>  0) & 0xff;
+	}
+
+	sc->ifp = ifp = if_alloc(IFT_ETHER);
+	err = mii_attach(dev, &sc->miibus, ifp, ate_ifmedia_upd,
+	    ate_ifmedia_sts, BMSR_DEFCAPMASK, MII_PHY_ANY, MII_OFFSET_ANY, 0);
+	if (err != 0) {
+		device_printf(dev, "attaching PHYs failed\n");
+		goto out;
+	}
+	/*
+	 * XXX: Clear the isolate bit, or we won't get up,
+	 * at least on the HL201
+	 */
+	ate_miibus_writereg(dev, 0, 0, 0x3000);
+
+	ifp->if_softc = sc;
+	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
+	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+	ifp->if_capabilities |= IFCAP_VLAN_MTU;
+	ifp->if_capenable |= IFCAP_VLAN_MTU;	/* The hw bits already set. */
+	ifp->if_start = atestart;
+	ifp->if_ioctl = ateioctl;
+	ifp->if_init = ateinit;
+	ifp->if_baudrate = 10000000;
+	IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
+	ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
+	IFQ_SET_READY(&ifp->if_snd);
+	ifp->if_linkmib = &sc->mibdata;
+	ifp->if_linkmiblen = sizeof(sc->mibdata);
+	sc->mibdata.dot3Compliance = DOT3COMPLIANCE_COLLS;
+	sc->if_flags = ifp->if_flags;
+
+	ether_ifattach(ifp, eaddr);
+
+	/* Activate the interrupt. */
+	err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET | INTR_MPSAFE,
+	    NULL, ate_intr, sc, &sc->intrhand);
+	if (err) {
+		device_printf(dev, "could not establish interrupt handler.\n");
+		ether_ifdetach(ifp);
+		goto out;
+	}
+
+out:
+	if (err)
+		ate_detach(dev);
+	return (err);
+}
+
+static int
+ate_detach(device_t dev)
+{
+	struct ate_softc *sc;
+	struct ifnet *ifp;
+
+	sc = device_get_softc(dev);
+	KASSERT(sc != NULL, ("[ate: %d]: sc is NULL", __LINE__));
+	ifp = sc->ifp;
+	if (device_is_attached(dev)) {
+		ATE_LOCK(sc);
+			sc->flags |= ATE_FLAG_DETACHING;
+			atestop(sc);
+		ATE_UNLOCK(sc);
+		callout_drain(&sc->tick_ch);
+		ether_ifdetach(ifp);
+	}
+	if (sc->miibus != NULL) {
+		device_delete_child(dev, sc->miibus);
+		sc->miibus = NULL;
+	}
+	bus_generic_detach(sc->dev);
+	ate_deactivate(sc);
+	if (sc->intrhand != NULL) {
+		bus_teardown_intr(dev, sc->irq_res, sc->intrhand);
+		sc->intrhand = NULL;
+	}
+	if (ifp != NULL) {
+		if_free(ifp);
+		sc->ifp = NULL;
+	}
+	if (sc->mem_res != NULL) {
+		bus_release_resource(dev, SYS_RES_IOPORT,
+		    rman_get_rid(sc->mem_res), sc->mem_res);
+		sc->mem_res = NULL;
+	}
+	if (sc->irq_res != NULL) {
+		bus_release_resource(dev, SYS_RES_IRQ,
+		    rman_get_rid(sc->irq_res), sc->irq_res);
+		sc->irq_res = NULL;
+	}
+	ATE_LOCK_DESTROY(sc);
+	return (0);
+}
+
+static void
+ate_getaddr(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
+{
+
+	if (error != 0)
+		return;
+	*(bus_addr_t *)arg = segs[0].ds_addr;
+}
+
+static void
+ate_load_rx_buf(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
+{
+	struct ate_softc *sc;
+
+	if (error != 0)
+		return;
+	sc = (struct ate_softc *)arg;
+
+	bus_dmamap_sync(sc->rx_desc_tag, sc->rx_desc_map, BUS_DMASYNC_PREWRITE);
+	sc->rx_descs[sc->rxhead].addr = segs[0].ds_addr;
+	sc->rx_descs[sc->rxhead].status = 0;
+	bus_dmamap_sync(sc->rx_desc_tag, sc->rx_desc_map, BUS_DMASYNC_POSTWRITE);
+}
+
+static uint32_t
+ate_mac_hash(const uint8_t *buf)
+{
+	uint32_t index = 0;
+	for (int i = 0; i < 48; i++) {
+		index ^= ((buf[i >> 3] >> (i & 7)) & 1) << (i % 6);
+	}
+	return (index);
+}
+
+/*
+ * Compute the multicast filter for this device.
+ */
+static int
+ate_setmcast(struct ate_softc *sc)
+{
+	uint32_t index;
+	uint32_t mcaf[2];
+	u_char *af = (u_char *) mcaf;
+	struct ifmultiaddr *ifma;
+	struct ifnet *ifp;
+
+	ifp = sc->ifp;
+
+	if ((ifp->if_flags & IFF_PROMISC) != 0)
+		return (0);
+	if ((ifp->if_flags & IFF_ALLMULTI) != 0) {
+		WR4(sc, ETH_HSL, 0xffffffff);
+		WR4(sc, ETH_HSH, 0xffffffff);
+		return (1);
+	}
+
+	/* Compute the multicast hash. */
+	mcaf[0] = 0;
+	mcaf[1] = 0;
+	if_maddr_rlock(ifp);
+	TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
+		if (ifma->ifma_addr->sa_family != AF_LINK)
+			continue;
+		index = ate_mac_hash(LLADDR((struct sockaddr_dl *)
+		    ifma->ifma_addr));
+		af[index >> 3] |= 1 << (index & 7);
+	}
+	if_maddr_runlock(ifp);
+
+	/*
+	 * Write the hash to the hash register.  This card can also
+	 * accept unicast packets as well as multicast packets using this
+	 * register for easier bridging operations, but we don't take
+	 * advantage of that.  Locks here are to avoid LOR with the
+	 * if_maddr_rlock, but might not be strictly necessary.
+	 */
+	WR4(sc, ETH_HSL, mcaf[0]);
+	WR4(sc, ETH_HSH, mcaf[1]);
+	return (mcaf[0] || mcaf[1]);
+}
+
+static int
+ate_activate(device_t dev)
+{
+	struct ate_softc *sc;
+	int i;
+
+	sc = device_get_softc(dev);
+
+	/* Allocate DMA tags and maps for TX mbufs */
+	if (bus_dma_tag_create(bus_get_dma_tag(dev), 1, 0,
+	    BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES,
+	    1, MCLBYTES, 0, busdma_lock_mutex, &sc->sc_mtx, &sc->mtag))
+		goto errout;
+	for (i = 0; i < ATE_MAX_TX_BUFFERS; i++) {
+		if ( bus_dmamap_create(sc->mtag, 0, &sc->tx_map[i]))
+			goto errout;
+	}
+
+
+	/* DMA tag and map for the RX descriptors. */
+	if (bus_dma_tag_create(bus_get_dma_tag(dev), sizeof(eth_rx_desc_t),
+	    0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
+	    ATE_NUM_RX_DESCR * sizeof(eth_rx_desc_t), 1,
+	    ATE_NUM_RX_DESCR * sizeof(eth_rx_desc_t), 0, busdma_lock_mutex,
+	    &sc->sc_mtx, &sc->rx_desc_tag))
+		goto errout;
+	if (bus_dmamem_alloc(sc->rx_desc_tag, (void **)&sc->rx_descs,
+	    BUS_DMA_NOWAIT | BUS_DMA_COHERENT, &sc->rx_desc_map) != 0)
+		goto errout;
+	if (bus_dmamap_load(sc->rx_desc_tag, sc->rx_desc_map,
+	    sc->rx_descs, ATE_NUM_RX_DESCR * sizeof(eth_rx_desc_t),
+	    ate_getaddr, &sc->rx_desc_phys, 0) != 0)
+		goto errout;
+
+	/* Allocate DMA tags and maps for RX. buffers */
+	if (bus_dma_tag_create(bus_get_dma_tag(dev), 1, 0,
+	    BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
+	    sc->rx_buf_size, 1, sc->rx_buf_size, 0,
+	    busdma_lock_mutex, &sc->sc_mtx, &sc->rx_tag))
+		goto errout;
+
+	/*
+	 * Allocate our RX buffers.
+	 * This chip has a RX structure that's filled in.
+	 * XXX On MACB (SAM9 part) we should receive directly into mbuf
+	 * to avoid the copy.  XXX
+	 */
+	sc->rxhead = 0;
+	for (sc->rxhead = 0; sc->rxhead < ATE_RX_MEMORY/sc->rx_buf_size;
+	    sc->rxhead++) {
+		if (bus_dmamem_alloc(sc->rx_tag,
+		    (void **)&sc->rx_buf[sc->rxhead], BUS_DMA_NOWAIT,
+		    &sc->rx_map[sc->rxhead]) != 0)
+			goto errout;
+
+		if (bus_dmamap_load(sc->rx_tag, sc->rx_map[sc->rxhead],
+		    sc->rx_buf[sc->rxhead], sc->rx_buf_size,
+		    ate_load_rx_buf, sc, 0) != 0) {
+			printf("bus_dmamem_load\n");
+			goto errout;
+		}
+		bus_dmamap_sync(sc->rx_tag, sc->rx_map[sc->rxhead], BUS_DMASYNC_PREREAD);
+	}
+
+	/*
+	 * For the last buffer, set the wrap bit so the controller
+	 * restarts from the first descriptor.
+	 */
+	sc->rx_descs[--sc->rxhead].addr |= ETH_WRAP_BIT;
+	sc->rxhead = 0;
+
+	/* Flush the memory for the EMAC rx descriptor. */
+	bus_dmamap_sync(sc->rx_desc_tag, sc->rx_desc_map, BUS_DMASYNC_PREWRITE);
+
+	/* Write the descriptor queue address. */
+	WR4(sc, ETH_RBQP, sc->rx_desc_phys);
+
+	/*
+	 * DMA tag and map for the TX descriptors.
+	 */
+	if (bus_dma_tag_create(bus_get_dma_tag(dev), sizeof(eth_tx_desc_t),
+	    0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
+	    ATE_MAX_TX_BUFFERS * sizeof(eth_tx_desc_t), 1,
+	    ATE_MAX_TX_BUFFERS * sizeof(eth_tx_desc_t), 0, busdma_lock_mutex,
+	    &sc->sc_mtx, &sc->tx_desc_tag) != 0)
+		goto errout;
+
+	if (bus_dmamem_alloc(sc->tx_desc_tag, (void **)&sc->tx_descs,
+	    BUS_DMA_NOWAIT | BUS_DMA_COHERENT, &sc->tx_desc_map) != 0)
+		goto errout;
+
+	if (bus_dmamap_load(sc->tx_desc_tag, sc->tx_desc_map,
+	    sc->tx_descs, ATE_MAX_TX_BUFFERS * sizeof(eth_tx_desc_t),
+	    ate_getaddr, &sc->tx_desc_phys, 0) != 0)
+		goto errout;
+
+	/* Initilize descriptors; mark all empty */
+	for (i = 0; i < ATE_MAX_TX_BUFFERS; i++) {
+		sc->tx_descs[i].addr =0;
+		sc->tx_descs[i].status = ETHB_TX_USED;
+		sc->sent_mbuf[i] = NULL;
+	}
+
+	/* Mark last entry to cause wrap when indexing through */
+	sc->tx_descs[ATE_MAX_TX_BUFFERS - 1].status =
+	    ETHB_TX_WRAP | ETHB_TX_USED;
+
+	/* Flush the memory for the EMAC tx descriptor. */
+	bus_dmamap_sync(sc->tx_desc_tag, sc->tx_desc_map, BUS_DMASYNC_PREWRITE);
+
+	sc->txhead = sc->txtail = 0;
+	if (sc->is_emacb) {
+		/* Write the descriptor queue address. */
+		WR4(sc, ETHB_TBQP, sc->tx_desc_phys);
+
+		/* EMACB: Enable transceiver input clock */
+		WR4(sc, ETHB_UIO, RD4(sc, ETHB_UIO) | ETHB_UIO_CLKE);
+	}
+
+	return (0);
+
+errout:
+	return (ENOMEM);
+}
+
+static void
+ate_deactivate(struct ate_softc *sc)
+{
+	int i;
+
+	KASSERT(sc != NULL, ("[ate, %d]: sc is NULL!", __LINE__));
+	if (sc->mtag != NULL) {
+		for (i = 0; i < ATE_MAX_TX_BUFFERS; i++) {
+			if (sc->sent_mbuf[i] != NULL) {
+				bus_dmamap_sync(sc->mtag, sc->tx_map[i],
+				    BUS_DMASYNC_POSTWRITE);
+				bus_dmamap_unload(sc->mtag, sc->tx_map[i]);
+				m_freem(sc->sent_mbuf[i]);
+			}
+			bus_dmamap_destroy(sc->mtag, sc->tx_map[i]);
+			sc->sent_mbuf[i] = NULL;
+			sc->tx_map[i] = NULL;
+		}
+		bus_dma_tag_destroy(sc->mtag);
+	}
+	if (sc->rx_desc_tag != NULL) {
+		if (sc->rx_descs != NULL) {
+			if (sc->rx_desc_phys != 0) {
+				bus_dmamap_sync(sc->rx_desc_tag,
+				    sc->rx_desc_map, BUS_DMASYNC_POSTREAD);
+				bus_dmamap_unload(sc->rx_desc_tag,
+				    sc->rx_desc_map);
+				sc->rx_desc_phys = 0;
+			}
+		}
+	}
+	if (sc->rx_tag != NULL) {
+		for (i = 0; sc->rx_buf[i] != NULL; i++) {
+			if (sc->rx_descs[i].addr != 0) {
+				bus_dmamap_sync(sc->rx_tag,
+				    sc->rx_map[i],
+				    BUS_DMASYNC_POSTREAD);
+				bus_dmamap_unload(sc->rx_tag,
+				    sc->rx_map[i]);
+				sc->rx_descs[i].addr = 0;
+			}
+			bus_dmamem_free(sc->rx_tag, sc->rx_buf[i],
+			    sc->rx_map[i]);
+			sc->rx_buf[i] = NULL;
+			sc->rx_map[i] = NULL;
+		}
+		bus_dma_tag_destroy(sc->rx_tag);
+	}
+	if (sc->rx_desc_tag != NULL) {
+		if (sc->rx_descs != NULL)
+			bus_dmamem_free(sc->rx_desc_tag, sc->rx_descs,
+			    sc->rx_desc_map);
+		bus_dma_tag_destroy(sc->rx_desc_tag);
+		sc->rx_descs = NULL;
+		sc->rx_desc_tag = NULL;
+	}
+
+	if (sc->is_emacb)
+		WR4(sc, ETHB_UIO, RD4(sc, ETHB_UIO) & ~ETHB_UIO_CLKE);
+}
+
+/*
+ * Change media according to request.
+ */
+static int
+ate_ifmedia_upd(struct ifnet *ifp)
+{
+	struct ate_softc *sc = ifp->if_softc;
+	struct mii_data *mii;
+
+	mii = device_get_softc(sc->miibus);
+	ATE_LOCK(sc);
+	mii_mediachg(mii);
+	ATE_UNLOCK(sc);
+	return (0);
+}
+
+/*
+ * Notify the world which media we're using.
+ */
+static void
+ate_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
+{
+	struct ate_softc *sc = ifp->if_softc;
+	struct mii_data *mii;
+
+	mii = device_get_softc(sc->miibus);
+	ATE_LOCK(sc);
+	mii_pollstat(mii);
+	ifmr->ifm_active = mii->mii_media_active;
+	ifmr->ifm_status = mii->mii_media_status;
+	ATE_UNLOCK(sc);
+}
+
+static void
+ate_stat_update(struct ate_softc *sc, int active)
+{
+	uint32_t reg;
+
+	/*
+	 * The speed and full/half-duplex state needs to be reflected
+	 * in the ETH_CFG register.
+	 */
+	reg = RD4(sc, ETH_CFG);
+	reg &= ~(ETH_CFG_SPD | ETH_CFG_FD);
+	if (IFM_SUBTYPE(active) != IFM_10_T)
+		reg |= ETH_CFG_SPD;
+	if (active & IFM_FDX)
+		reg |= ETH_CFG_FD;
+	WR4(sc, ETH_CFG, reg);
+}
+
+static void
+ate_tick(void *xsc)
+{
+	struct ate_softc *sc = xsc;
+	struct ifnet *ifp = sc->ifp;
+	struct mii_data *mii;
+	int active;
+	uint32_t c;
+
+	/*
+	 * The KB920x boot loader tests ETH_SR & ETH_SR_LINK and will ask
+	 * the MII if there's a link if this bit is clear.  Not sure if we
+	 * should do the same thing here or not.
+	 */
+	ATE_ASSERT_LOCKED(sc);
+	if (sc->miibus != NULL) {
+		mii = device_get_softc(sc->miibus);
+		active = mii->mii_media_active;
+		mii_tick(mii);
+		if (mii->mii_media_status & IFM_ACTIVE &&
+		    active != mii->mii_media_active)
+			ate_stat_update(sc, mii->mii_media_active);
+	}
+
+	/*
+	 * Update the stats as best we can.  When we're done, clear
+	 * the status counters and start over.  We're supposed to read these
+	 * registers often enough that they won't overflow.  Hopefully
+	 * once a second is often enough.  Some don't map well to
+	 * the dot3Stats mib, so for those we just count them as general
+	 * errors.  Stats for iframes, ibutes, oframes and obytes are
+	 * collected elsewhere.  These registers zero on a read to prevent
+	 * races.  For all the collision stats, also update the collision
+	 * stats for the interface.
+	 */
+	sc->mibdata.dot3StatsAlignmentErrors += RD4(sc, ETH_ALE);
+	sc->mibdata.dot3StatsFCSErrors += RD4(sc, ETH_SEQE);
+	c = RD4(sc, ETH_SCOL);
+	ifp->if_collisions += c;
+	sc->mibdata.dot3StatsSingleCollisionFrames += c;
+	c = RD4(sc, ETH_MCOL);
+	sc->mibdata.dot3StatsMultipleCollisionFrames += c;
+	ifp->if_collisions += c;
+	sc->mibdata.dot3StatsSQETestErrors += RD4(sc, ETH_SQEE);
+	sc->mibdata.dot3StatsDeferredTransmissions += RD4(sc, ETH_DTE);
+	c = RD4(sc, ETH_LCOL);
+	sc->mibdata.dot3StatsLateCollisions += c;
+	ifp->if_collisions += c;
+	c = RD4(sc, ETH_ECOL);
+	sc->mibdata.dot3StatsExcessiveCollisions += c;
+	ifp->if_collisions += c;
+	sc->mibdata.dot3StatsCarrierSenseErrors += RD4(sc, ETH_CSE);
+	sc->mibdata.dot3StatsFrameTooLongs += RD4(sc, ETH_ELR);
+	sc->mibdata.dot3StatsInternalMacReceiveErrors += RD4(sc, ETH_DRFC);
+
+	/*
+	 * Not sure where to lump these, so count them against the errors
+	 * for the interface.
+	 */
+	sc->ifp->if_oerrors += RD4(sc, ETH_TUE);
+	sc->ifp->if_ierrors += RD4(sc, ETH_CDE) + RD4(sc, ETH_RJB) +
+	    RD4(sc, ETH_USF);
+
+	/* Schedule another timeout one second from now. */
+	callout_reset(&sc->tick_ch, hz, ate_tick, sc);
+}
+
+static void
+ate_set_mac(struct ate_softc *sc, u_char *eaddr)
+{
+
+	WR4(sc, ETH_SA1L, (eaddr[3] << 24) | (eaddr[2] << 16) |
+	    (eaddr[1] << 8) | eaddr[0]);
+	WR4(sc, ETH_SA1H, (eaddr[5] << 8) | (eaddr[4]));
+}
+
+static int
+ate_get_mac(struct ate_softc *sc, u_char *eaddr)
+{
+	bus_size_t sa_low_reg[] = { ETH_SA1L, ETH_SA2L, ETH_SA3L, ETH_SA4L };
+	bus_size_t sa_high_reg[] = { ETH_SA1H, ETH_SA2H, ETH_SA3H, ETH_SA4H };
+	uint32_t low, high;
+	int i;
+
+	/*
+	 * The boot loader may setup the MAC with an address(es), grab the
+	 * first MAC address from the SA[1-4][HL] registers.
+	 */
+	for (i = 0; i < 4; i++) {
+		low = RD4(sc, sa_low_reg[i]);
+		high = RD4(sc, sa_high_reg[i]);
+		if ((low | (high & 0xffff)) != 0) {
+			eaddr[0] = low & 0xff;
+			eaddr[1] = (low >> 8) & 0xff;
+			eaddr[2] = (low >> 16) & 0xff;
+			eaddr[3] = (low >> 24) & 0xff;
+			eaddr[4] = high & 0xff;
+			eaddr[5] = (high >> 8) & 0xff;
+			return (0);
+		}
+	}
+	return (ENXIO);
+}
+
+static void
+ate_intr(void *xsc)
+{
+	struct ate_softc *sc = xsc;
+	struct ifnet *ifp = sc->ifp;
+	struct mbuf *mb;
+	eth_rx_desc_t	*rxdhead;
+	uint32_t status, reg, idx;
+	int remain, count, done;
+
+	status = RD4(sc, ETH_ISR);
+	if (status == 0)
+		return;
+
+	if (status & ETH_ISR_RCOM) {
+		bus_dmamap_sync(sc->rx_desc_tag, sc->rx_desc_map,
+		    BUS_DMASYNC_POSTREAD);
+
+		rxdhead = &sc->rx_descs[sc->rxhead];
+		while (rxdhead->addr & ETH_CPU_OWNER) {
+			if (!sc->is_emacb) {
+				/*
+				 * Simulate SAM9 FIRST/LAST bits for RM9200.
+				 * RM9200 EMAC has only on Rx buffer per packet.
+				 * But sometime we are handed a zero lenght packet.
+				 */
+				if ((rxdhead->status & ETH_LEN_MASK) == 0)
+					rxdhead->status = 0; /* Mark error */
+				else
+					rxdhead->status |= ETH_BUF_FIRST | ETH_BUF_LAST;
+			}
+
+			if ((rxdhead->status & ETH_BUF_FIRST) == 0) {
+				/* Something went wrong during RX so
+				   release back to EMAC all buffers of invalid packets.
+				*/
+				rxdhead->status = 0;
+				rxdhead->addr &= ~ETH_CPU_OWNER;
+				sc->rxhead = NEXT_RX_IDX(sc, sc->rxhead);
+				rxdhead = &sc->rx_descs[sc->rxhead];
+				continue;
+			}
+
+			/* Find end of packet or start of next */
+			idx = sc->rxhead;
+			if ((sc->rx_descs[idx].status & ETH_BUF_LAST) == 0) {
+				idx = NEXT_RX_IDX(sc, idx);
+
+				while ((sc->rx_descs[idx].addr & ETH_CPU_OWNER) &&
+					((sc->rx_descs[idx].status &
+					    (ETH_BUF_FIRST|ETH_BUF_LAST))== 0))
+					idx = NEXT_RX_IDX(sc, idx);
+			}
+
+			/* Packet NOT yet completely in memory; we are done */
+			if ((sc->rx_descs[idx].addr & ETH_CPU_OWNER) == 0 ||
+			    ((sc->rx_descs[idx].status & (ETH_BUF_FIRST|ETH_BUF_LAST))== 0))
+					break;
+
+			/* Packets with no end descriptor are invalid. */
+			if ((sc->rx_descs[idx].status & ETH_BUF_LAST) == 0) {
+					rxdhead->status &= ~ETH_BUF_FIRST;
+					continue;
+			}
+
+			/* FCS is not coppied into mbuf. */
+			remain = (sc->rx_descs[idx].status & ETH_LEN_MASK) - 4;
+
+			/* Get an appropriately sized mbuf. */
+			mb = m_get2(remain + ETHER_ALIGN, M_NOWAIT, MT_DATA,
+			    M_PKTHDR);
+			if (mb == NULL) {
+				sc->ifp->if_iqdrops++;
+				rxdhead->status = 0;
+				continue;
+			}
+			mb->m_data += ETHER_ALIGN;
+			mb->m_pkthdr.rcvif = ifp;
+
+			WR4(sc, ETH_RSR, RD4(sc, ETH_RSR));	/* Reset status */
+
+			/* Now we process the buffers that make up the packet */
+			do {
+
+				/* Last buffer may just be 1-4 bytes of FCS so remain
+				 * may be zero for last decriptor.  */
+				if (remain > 0) {
+						/* Make sure we get the current bytes */
+						bus_dmamap_sync(sc->rx_tag, sc->rx_map[sc->rxhead],
+						    BUS_DMASYNC_POSTREAD);
+
+						count = MIN(remain, sc->rx_buf_size);
+
+						/* XXX Performance robbing copy. Could
+						 * recieve directly to mbufs if not an
+						 * RM9200. And even then we could likely
+						 * copy just the protocol headers. XXX  */
+						m_append(mb, count, sc->rx_buf[sc->rxhead]);
+						remain -= count;
+				}
+
+				done = (rxdhead->status & ETH_BUF_LAST) != 0;
+
+				/* Return the descriptor to the EMAC */
+				rxdhead->status = 0;
+				rxdhead->addr &= ~ETH_CPU_OWNER;
+				bus_dmamap_sync(sc->rx_desc_tag, sc->rx_desc_map,
+				    BUS_DMASYNC_PREWRITE);
+
+				/* Move on to next descriptor with wrap */
+				sc->rxhead = NEXT_RX_IDX(sc, sc->rxhead);
+				rxdhead = &sc->rx_descs[sc->rxhead];
+
+			} while (!done);
+
+			ifp->if_ipackets++;
+			(*ifp->if_input)(ifp, mb);
+		}
+	}
+
+
+	if (status & ETH_ISR_TCOM) {
+		bus_dmamap_sync(sc->tx_desc_tag, sc->tx_desc_map,
+		    BUS_DMASYNC_POSTREAD);
+
+		ATE_LOCK(sc);
+		/* XXX TSR register should be cleared */
+		if (!sc->is_emacb) {
+			/* Simulate Transmit descriptor table */
+
+			/* First packet done */
+			if (sc->txtail < sc->txhead)
+				sc->tx_descs[sc->txtail].status |= ETHB_TX_USED;
+
+			/* Second Packet done */
+			if (sc->txtail + 1 < sc->txhead &&
+			    RD4(sc, ETH_TSR) & ETH_TSR_IDLE)
+				sc->tx_descs[sc->txtail + 1].status |= ETHB_TX_USED;
+		}
+
+		while ((sc->tx_descs[sc->txtail].status & ETHB_TX_USED) &&
+		    sc->sent_mbuf[sc->txtail] != NULL) {
+			bus_dmamap_sync(sc->mtag, sc->tx_map[sc->txtail],
+			    BUS_DMASYNC_POSTWRITE);
+			bus_dmamap_unload(sc->mtag, sc->tx_map[sc->txtail]);
+			m_freem(sc->sent_mbuf[sc->txtail]);
+			sc->tx_descs[sc->txtail].addr = 0;
+			sc->sent_mbuf[sc->txtail] = NULL;
+			ifp->if_opackets++;
+			sc->txtail = NEXT_TX_IDX(sc, sc->txtail);
+		}
+
+		/* Flush descriptors to EMAC */
+		bus_dmamap_sync(sc->tx_desc_tag, sc->tx_desc_map, BUS_DMASYNC_PREWRITE);
+
+		/*
+		 * We're no longer busy, so clear the busy flag and call the
+		 * start routine to xmit more packets.
+		 */
+		sc->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+		atestart_locked(sc->ifp);
+		ATE_UNLOCK(sc);
+	}
+
+	if (status & ETH_ISR_RBNA) {
+		/* Workaround RM9200 Errata #11 */
+		if (bootverbose)
+			device_printf(sc->dev, "RBNA workaround\n");
+		reg = RD4(sc, ETH_CTL);
+		WR4(sc, ETH_CTL, reg & ~ETH_CTL_RE);
+		BARRIER(sc, ETH_CTL, 4, BUS_SPACE_BARRIER_WRITE);
+		WR4(sc, ETH_CTL, reg | ETH_CTL_RE);
+	}
+
+	/* XXX need to work around SAM9260 errata 43.2.4.1:
+	 * disable the mac, reset tx buffer, enable mac on TUND */
+}
+
+/*
+ * Reset and initialize the chip.
+ */
+static void
+ateinit_locked(void *xsc)
+{
+	struct ate_softc *sc = xsc;
+	struct ifnet *ifp = sc->ifp;
+	struct mii_data *mii;
+	uint8_t eaddr[ETHER_ADDR_LEN];
+	uint32_t reg;
+
+	ATE_ASSERT_LOCKED(sc);
+
+	/*
+	 * XXX TODO(3)
+	 * we need to turn on the EMAC clock in the pmc.  With the
+	 * default boot loader, this is already turned on.  However, we
+	 * need to think about how best to turn it on/off as the interface
+	 * is brought up/down, as well as dealing with the mii bus...
+	 *
+	 * We also need to multiplex the pins correctly (in board_xxx.c).
+	 */
+
+	/*
+	 * There are two different ways that the mii bus is connected
+	 * to this chip mii or rmii.
+	 */
+	if (!sc->is_emacb) {
+		/* RM9200 */
+		reg = RD4(sc, ETH_CFG);
+		if (sc->use_rmii)
+			reg |= ETH_CFG_RMII;
+		else
+			reg &= ~ETH_CFG_RMII;
+		WR4(sc, ETH_CFG, reg);
+	} else  {
+		/* SAM9 */
+		reg = ETHB_UIO_CLKE;
+		reg |= (sc->use_rmii) ? ETHB_UIO_RMII : 0;
+		WR4(sc, ETHB_UIO, reg);
+	}
+
+	ate_rxfilter(sc);
+
+	/*
+	 * Set the chip MAC address.
+	 */
+	bcopy(IF_LLADDR(ifp), eaddr, ETHER_ADDR_LEN);
+	ate_set_mac(sc, eaddr);
+
+	/* Make sure we know state of TX queue */
+	sc->txhead = sc->txtail = 0;
+	if (sc->is_emacb) {
+		/* Write the descriptor queue address. */
+		WR4(sc, ETHB_TBQP, sc->tx_desc_phys);
+	}
+
+	/*
+	 * Turn on MACs and interrupt processing.
+	 */
+	WR4(sc, ETH_CTL, RD4(sc, ETH_CTL) | ETH_CTL_TE | ETH_CTL_RE);
+	WR4(sc, ETH_IER, ETH_ISR_RCOM | ETH_ISR_TCOM | ETH_ISR_RBNA);
+
+	/* Enable big packets. */
+	WR4(sc, ETH_CFG, RD4(sc, ETH_CFG) | ETH_CFG_BIG);
+
+	/*
+	 * Set 'running' flag, and clear output active flag
+	 * and attempt to start the output.
+	 */
+	ifp->if_drv_flags |= IFF_DRV_RUNNING;
+	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+
+	mii = device_get_softc(sc->miibus);
+	mii_pollstat(mii);
+	ate_stat_update(sc, mii->mii_media_active);
+	atestart_locked(ifp);
+
+	callout_reset(&sc->tick_ch, hz, ate_tick, sc);
+}
+
+/*
+ * Dequeue packets and transmit.
+ */
+static void
+atestart_locked(struct ifnet *ifp)
+{
+	struct ate_softc *sc = ifp->if_softc;
+	struct mbuf *m, *mdefrag;
+	bus_dma_segment_t segs[1];
+	int nseg, e;
+
+	ATE_ASSERT_LOCKED(sc);
+	if (ifp->if_drv_flags & IFF_DRV_OACTIVE)
+		return;
+
+	while (sc->tx_descs[sc->txhead].status & ETHB_TX_USED) {
+		/*
+		 * Check to see if there's room to put another packet into the
+		 * xmit queue. The old EMAC version has a ping-pong buffer for
+		 * xmit packets.  We use OACTIVE to indicate "we can stuff more
+		 * into our buffers (clear) or not (set)."
+		 */
+		/* RM9200 has only two hardware entries */
+		if (!sc->is_emacb && (RD4(sc, ETH_TSR) & ETH_TSR_BNQ) == 0) {
+			ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+			return;
+		}
+
+		IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
+		if (m == 0)
+			break;
+
+		e = bus_dmamap_load_mbuf_sg(sc->mtag, sc->tx_map[sc->txhead], m,
+		    segs, &nseg, 0);
+		if (e == EFBIG) {
+			mdefrag = m_defrag(m, M_NOWAIT);
+			if (mdefrag == NULL) {
+				IFQ_DRV_PREPEND(&ifp->if_snd, m);
+				return;
+			}
+			m = mdefrag;
+			e = bus_dmamap_load_mbuf_sg(sc->mtag,
+			    sc->tx_map[sc->txhead], m, segs, &nseg, 0);
+		}
+		if (e != 0) {
+			m_freem(m);
+			continue;
+		}
+
+		/*
+		 * There's a small race between the loop in ate_intr finishing
+		 * and the check above to see if the packet was finished, as well
+		 * as when atestart gets called via other paths. Lose the race
+		 * gracefully and free the mbuf...
+		 */
+		if (sc->sent_mbuf[sc->txhead] != NULL) {
+			bus_dmamap_sync(sc->mtag, sc->tx_map[sc->txtail],
+			    BUS_DMASYNC_POSTWRITE);
+			bus_dmamap_unload(sc->mtag, sc->tx_map[sc->txtail]);
+			m_free(sc->sent_mbuf[sc->txhead]);
+			ifp->if_opackets++;
+		}
+		
+		sc->sent_mbuf[sc->txhead] = m;
+
+		bus_dmamap_sync(sc->mtag, sc->tx_map[sc->txhead],
+		    BUS_DMASYNC_PREWRITE);
+
+		/* Tell the hardware to xmit the packet. */
+		if (!sc->is_emacb) {
+			WR4(sc, ETH_TAR, segs[0].ds_addr);
+			BARRIER(sc, ETH_TAR, 4, BUS_SPACE_BARRIER_WRITE);
+			WR4(sc, ETH_TCR, segs[0].ds_len);
+		} else {
+			bus_dmamap_sync(sc->tx_desc_tag, sc->tx_desc_map,
+			    BUS_DMASYNC_POSTWRITE);
+			sc->tx_descs[sc->txhead].addr = segs[0].ds_addr;
+			sc->tx_descs[sc->txhead].status = segs[0].ds_len |
+			    (sc->tx_descs[sc->txhead].status & ETHB_TX_WRAP) |
+			    ETHB_TX_BUF_LAST;
+			bus_dmamap_sync(sc->tx_desc_tag, sc->tx_desc_map,
+			    BUS_DMASYNC_PREWRITE);
+			WR4(sc, ETH_CTL, RD4(sc, ETH_CTL) | ETHB_CTL_TGO);
+		}
+		sc->txhead = NEXT_TX_IDX(sc, sc->txhead);
+
+		/* Tap off here if there is a bpf listener. */
+		BPF_MTAP(ifp, m);
+	}
+
+	if ((sc->tx_descs[sc->txhead].status & ETHB_TX_USED) == 0)
+	    ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+}
+
+static void
+ateinit(void *xsc)
+{
+	struct ate_softc *sc = xsc;
+
+	ATE_LOCK(sc);
+	ateinit_locked(sc);
+	ATE_UNLOCK(sc);
+}
+
+static void
+atestart(struct ifnet *ifp)
+{
+	struct ate_softc *sc = ifp->if_softc;
+
+	ATE_LOCK(sc);
+	atestart_locked(ifp);
+	ATE_UNLOCK(sc);
+}
+
+/*
+ * Turn off interrupts, and stop the NIC.  Can be called with sc->ifp NULL,
+ * so be careful.
+ */
+static void
+atestop(struct ate_softc *sc)
+{
+	struct ifnet *ifp;
+	int i;
+
+	ATE_ASSERT_LOCKED(sc);
+	ifp = sc->ifp;
+	if (ifp) {
+		//ifp->if_timer = 0;
+		ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+	}
+
+	callout_stop(&sc->tick_ch);
+
+	/*
+	 * Enable some parts of the MAC that are needed always (like the
+	 * MII bus.  This turns off the RE and TE bits, which will remain
+	 * off until ateinit() is called to turn them on.  With RE and TE
+	 * turned off, there's no DMA to worry about after this write.
+	 */
+	WR4(sc, ETH_CTL, ETH_CTL_MPE);
+
+	/*
+	 * Turn off all the configured options and revert to defaults.
+	 */
+
+	/* Make sure thate the MDIO clk is less than
+	 * 2.5 Mhz. Can no longer default to /32 since
+	 * SAM9 family may have MCK > 80 Mhz */
+	if (at91_master_clock <= 2000000)
+		WR4(sc, ETH_CFG, ETH_CFG_CLK_8);
+	else if (at91_master_clock <= 4000000)
+		WR4(sc, ETH_CFG, ETH_CFG_CLK_16);
+	else if (at91_master_clock <= 800000)
+		WR4(sc, ETH_CFG, ETH_CFG_CLK_32);
+	else
+		WR4(sc, ETH_CFG, ETH_CFG_CLK_64);
+
+	/*
+	 * Turn off all the interrupts, and ack any pending ones by reading
+	 * the ISR.
+	 */
+	WR4(sc, ETH_IDR, 0xffffffff);
+	RD4(sc, ETH_ISR);
+
+	/*
+	 * Clear out the Transmit and Receiver Status registers of any
+	 * errors they may be reporting
+	 */
+	WR4(sc, ETH_TSR, 0xffffffff);
+	WR4(sc, ETH_RSR, 0xffffffff);
+
+	/* Release TX resources. */
+	for (i = 0; i < ATE_MAX_TX_BUFFERS; i++) {
+		if (sc->sent_mbuf[i] != NULL) {
+			bus_dmamap_sync(sc->mtag, sc->tx_map[i],
+			    BUS_DMASYNC_POSTWRITE);
+			bus_dmamap_unload(sc->mtag, sc->tx_map[i]);
+			m_freem(sc->sent_mbuf[i]);
+			sc->sent_mbuf[i] = NULL;
+		}
+	}
+
+	/* Turn off transeiver input clock */
+	if (sc->is_emacb)
+		WR4(sc, ETHB_UIO, RD4(sc, ETHB_UIO) & ~ETHB_UIO_CLKE);
+
+	/*
+	 * XXX we should power down the EMAC if it isn't in use, after
+	 * putting it into loopback mode.  This saves about 400uA according
+	 * to the datasheet.
+	 */
+}
+
+static void
+ate_rxfilter(struct ate_softc *sc)
+{
+	struct ifnet *ifp;
+	uint32_t reg;
+	int enabled;
+
+	KASSERT(sc != NULL, ("[ate, %d]: sc is NULL!", __LINE__));
+	ATE_ASSERT_LOCKED(sc);
+	ifp = sc->ifp;
+
+	/* Wipe out old filter settings. */
+	reg = RD4(sc, ETH_CFG);
+	reg &= ~(ETH_CFG_CAF | ETH_CFG_MTI | ETH_CFG_UNI);
+	reg |= ETH_CFG_NBC;
+	sc->flags &= ~ATE_FLAG_MULTICAST;
+
+	/* Set new parameters. */
+	if ((ifp->if_flags & IFF_BROADCAST) != 0)
+		reg &= ~ETH_CFG_NBC;
+	if ((ifp->if_flags & IFF_PROMISC) != 0) {
+		reg |= ETH_CFG_CAF;
+	} else {
+		enabled = ate_setmcast(sc);
+		if (enabled != 0) {
+			reg |= ETH_CFG_MTI;
+			sc->flags |= ATE_FLAG_MULTICAST;
+		}
+	}
+	WR4(sc, ETH_CFG, reg);
+}
+
+static int
+ateioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
+{
+	struct ate_softc *sc = ifp->if_softc;
+	struct mii_data *mii;
+	struct ifreq *ifr = (struct ifreq *)data;
+	int drv_flags, flags;
+	int mask, error, enabled;
+
+	error = 0;
+	flags = ifp->if_flags;
+	drv_flags = ifp->if_drv_flags;
+	switch (cmd) {
+	case SIOCSIFFLAGS:
+		ATE_LOCK(sc);
+		if ((flags & IFF_UP) != 0) {
+			if ((drv_flags & IFF_DRV_RUNNING) != 0) {
+				if (((flags ^ sc->if_flags)
+				    & (IFF_PROMISC | IFF_ALLMULTI)) != 0)
+					ate_rxfilter(sc);
+			} else {
+				if ((sc->flags & ATE_FLAG_DETACHING) == 0)
+					ateinit_locked(sc);
+			}
+		} else if ((drv_flags & IFF_DRV_RUNNING) != 0) {
+			ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
+			atestop(sc);
+		}
+		sc->if_flags = flags;
+		ATE_UNLOCK(sc);
+		break;
+
+	case SIOCADDMULTI:
+	case SIOCDELMULTI:
+		if ((drv_flags & IFF_DRV_RUNNING) != 0) {
+			ATE_LOCK(sc);
+			enabled = ate_setmcast(sc);
+			if (enabled != (sc->flags & ATE_FLAG_MULTICAST))
+				ate_rxfilter(sc);
+			ATE_UNLOCK(sc);
+		}
+		break;
+
+	case SIOCSIFMEDIA:
+	case SIOCGIFMEDIA:
+		mii = device_get_softc(sc->miibus);
+		error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, cmd);
+		break;
+	case SIOCSIFCAP:
+		mask = ifp->if_capenable ^ ifr->ifr_reqcap;
+		if (mask & IFCAP_VLAN_MTU) {
+			ATE_LOCK(sc);
+			if (ifr->ifr_reqcap & IFCAP_VLAN_MTU) {
+				WR4(sc, ETH_CFG, RD4(sc, ETH_CFG) | ETH_CFG_BIG);
+				ifp->if_capenable |= IFCAP_VLAN_MTU;
+			} else {
+				WR4(sc, ETH_CFG, RD4(sc, ETH_CFG) & ~ETH_CFG_BIG);
+				ifp->if_capenable &= ~IFCAP_VLAN_MTU;
+			}
+			ATE_UNLOCK(sc);
+		}
+	default:
+		error = ether_ioctl(ifp, cmd, data);
+		break;
+	}
+	return (error);
+}
+
+static void
+ate_child_detached(device_t dev, device_t child)
+{
+	struct ate_softc *sc;
+
+	sc = device_get_softc(dev);
+	if (child == sc->miibus)
+		sc->miibus = NULL;
+}
+
+/*
+ * MII bus support routines.
+ */
+static int
+ate_miibus_readreg(device_t dev, int phy, int reg)
+{
+	struct ate_softc *sc;
+	int val;
+
+	/*
+	 * XXX if we implement agressive power savings, then we need
+	 * XXX to make sure that the clock to the emac is on here
+	 */
+
+	sc = device_get_softc(dev);
+	DELAY(1);	/* Hangs w/o this delay really 30.5us atm */
+	WR4(sc, ETH_MAN, ETH_MAN_REG_RD(phy, reg));
+	while ((RD4(sc, ETH_SR) & ETH_SR_IDLE) == 0)
+		continue;
+	val = RD4(sc, ETH_MAN) & ETH_MAN_VALUE_MASK;
+
+	return (val);
+}
+
+static int
+ate_miibus_writereg(device_t dev, int phy, int reg, int data)
+{
+	struct ate_softc *sc;
+
+	/*
+	 * XXX if we implement agressive power savings, then we need
+	 * XXX to make sure that the clock to the emac is on here
+	 */
+
+	sc = device_get_softc(dev);
+	WR4(sc, ETH_MAN, ETH_MAN_REG_WR(phy, reg, data));
+	while ((RD4(sc, ETH_SR) & ETH_SR_IDLE) == 0)
+		continue;
+	return (0);
+}
+
+static device_method_t ate_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		ate_probe),
+	DEVMETHOD(device_attach,	ate_attach),
+	DEVMETHOD(device_detach,	ate_detach),
+
+	/* Bus interface */
+	DEVMETHOD(bus_child_detached,	ate_child_detached),
+
+	/* MII interface */
+	DEVMETHOD(miibus_readreg,	ate_miibus_readreg),
+	DEVMETHOD(miibus_writereg,	ate_miibus_writereg),
+
+	DEVMETHOD_END
+};
+
+static driver_t ate_driver = {
+	"ate",
+	ate_methods,
+	sizeof(struct ate_softc),
+};
+
+#ifdef FDT
+DRIVER_MODULE(ate, simplebus, ate_driver, ate_devclass, NULL, NULL);
+#else
+DRIVER_MODULE(ate, atmelarm, ate_driver, ate_devclass, NULL, NULL);
+#endif
+DRIVER_MODULE(miibus, ate, miibus_driver, miibus_devclass, NULL, NULL);
+MODULE_DEPEND(ate, miibus, 1, 1, 1);
+MODULE_DEPEND(ate, ether, 1, 1, 1);


Property changes on: trunk/sys/arm/at91/if_ate.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/if_atereg.h
===================================================================
--- trunk/sys/arm/at91/if_atereg.h	                        (rev 0)
+++ trunk/sys/arm/at91/if_atereg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,215 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2006 M. Warner Losh.  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 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 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: stable/10/sys/arm/at91/if_atereg.h 213496 2010-10-06 22:25:21Z cognet $ */
+
+#ifndef ARM_AT91_IF_ATEREG_H
+#define ARM_AT91_IF_ATEREG_H
+
+/* deines begining ETHB_ are EMACB (newer SAM9 hardware) versions only */
+
+#define ETH_CTL		0x00		/* EMAC Control Register */
+#define ETH_CFG		0x04		/* EMAC Configuration Register */
+#define ETH_SR		0x08		/* EMAC STatus Register */
+#define ETH_TAR		0x0c		/* EMAC Transmit Address Register */
+#define ETH_TCR		0x10		/* EMAC Transmit Control Register */
+#define ETH_TSR		0x14		/* EMAC Transmit Status Register */
+#define ETH_RBQP	0x18		/* EMAC Receive Buffer Queue Pointer */
+#define ETHB_TBQP	0x1c		/*  reserved */
+#define ETH_RSR		0x20		/* EMAC Receive Status Register */
+#define ETH_ISR		0x24		/* EMAC Interrupt Status Register */
+#define ETH_IER		0x28		/* EMAC Interrupt Enable Register */
+#define ETH_IDR		0x2c		/* EMAC Interrupt Disable Register */
+#define ETH_IMR		0x30		/* EMAC Interrupt Mask Register */
+#define ETH_MAN		0x34		/* EMAC PHY Maintenance Register */
+		/*	0x38		   reserved */
+		/*	0x3c		   reserved */
+#define ETH_FRA		0x40		/* Frames Transmitted OK Register */
+#define ETH_SCOL	0x44		/* Single Collision Frame Register */
+#define ETH_MCOL	0x48		/* Multiple Collision Frame Register */
+#define ETH_OK		0x4c		/* Frames Received OK Register */
+#define ETH_SEQE	0x50		/* Frame Check Sequence Error Reg */
+#define ETH_ALE		0x54		/* Alignment Error Register */
+#define ETH_DTE		0x58		/* Deferred Transmittion Frame Reg */
+#define ETH_LCOL	0x5c		/* Late Collision Register */
+#define ETH_ECOL	0x60		/* Excessive Collision Register */
+#define ETH_TUE		0x64		/* Transmit Underrun Error Register */
+#define ETH_CSE		0x68		/* Carrier Sense Error Register */
+#define ETH_DRFC	0x6c		/* Discarded RX Frame Register */
+#define ETH_ROV		0x68		/* Receive Overrun Register */
+#define ETH_CDE		0x64		/* Code Error Register */
+#define ETH_ELR		0x78		/* Excessive Length Error Register */
+#define ETH_RJB		0x7c		/* Receive Jabber Register */
+#define ETH_USF		0x80		/* Undersize Frame Register */
+#define ETH_SQEE	0x84		/* SQE Test Error Register */
+		/*	0x88		   reserved */
+		/*	0x8c		   reserved */
+#define ETH_HSL		0x90		/* EMAC Hash Address Low [31:0] */
+#define ETH_HSH		0x94		/* EMAC Hash Address High [63:32] */
+#define ETH_SA1L	0x98		/* EMAC Specific Address 1 Low */
+#define ETH_SA1H	0x9c		/* EMAC Specific Address 1 High */
+#define ETH_SA2L	0xa0		/* EMAC Specific Address 2 Low */
+#define ETH_SA2H	0xa4		/* EMAC Specific Address 2 High */
+#define ETH_SA3L	0xa8		/* EMAC Specific Address 3 Low */
+#define ETH_SA3H	0xac		/* EMAC Specific Address 3 High */
+#define ETH_SA4L	0xb0		/* EMAC Specific Address 4 Low */
+#define ETH_SA4H	0xb4		/* EMAC Specific Address 4 High */
+#define ETHB_TID	0xb8		/* EMAC Type ID Checking */
+#define ETHB_UIO	0xC0		/* EMAC User I/O Reg */
+
+
+/* ETH_CTL */
+#define ETH_CTL_LB	(1U << 0)	/* LB: Loopback */
+#define ETH_CTL_LBL	(1U << 1)	/* LBL: Loopback Local */
+#define ETH_CTL_RE	(1U << 2)	/* RE: Receive Enable */
+#define ETH_CTL_TE	(1U << 3)	/* TE: Transmit Enable */
+#define ETH_CTL_MPE	(1U << 4)	/* MPE: Management Port Enable */
+#define ETH_CTL_CSR	(1U << 5)	/* CSR: Clear Statistics Registers */
+#define ETH_CTL_ISR	(1U << 6)	/* ISR: Incremenet Statistics Regs */
+#define ETH_CTL_WES	(1U << 7)	/* WES: Write Enable Statistics regs */
+#define ETH_CTL_BP	(1U << 8)	/* BP: Back Pressure */
+
+#define ETHB_CTL_TGO	(1U << 9)	/* TGO: Transmitter Start */
+#define ETHB_CTL_TSTP	(1U << 10)	/* TSTP: Transmitter Stop */
+
+/* ETH_CFG */
+#define ETH_CFG_SPD	(1U << 0)	/* SPD: Speed 1 == 100: 0 == 10 */
+#define ETH_CFG_FD	(1U << 1)	/* FD: Full duplex */
+#define ETH_CFG_BR	(1U << 2)	/* BR: Bit Rate (optional?) */
+		/* bit 3 reserved */
+#define ETH_CFG_CAF	(1U << 4)	/* CAF: Copy All Frames */
+#define ETH_CFG_NBC	(1U << 5)	/* NBC: No Broadcast */
+#define ETH_CFG_MTI	(1U << 6)	/* MTI: Multicast Hash Enable */
+#define ETH_CFG_UNI	(1U << 7)	/* UNI: Unicast Hash Enable */
+#define ETH_CFG_BIG	(1U << 8)	/* BIG: Receive 1522 Bytes */
+#define ETH_CFG_EAE	(1U << 9)	/* EAE: External Address Match En */
+#define ETH_CFG_CLK_8	(0U << 10)	/* CLK: Clock / 8 */
+#define ETH_CFG_CLK_16	(1U << 10)	/* CLK: Clock / 16 */
+#define ETH_CFG_CLK_32	(2U << 10)	/* CLK: Clock / 32 */
+#define ETH_CFG_CLK_64	(3U << 10)	/* CLK: Clock / 64 */
+#define ETH_CFG_RTY	(1U << 12)	/* RTY: Retry Test*/
+#define ETH_CFG_RMII	(1U << 13)	/* RMII: Reduce MII */
+
+#define ETHB_CFG_JBO	(1U << 3)	/* JBO: Jumbo Frames */
+#define ETHB_CFG_PAE	(1U << 13)	/* PAE: Pause Enable */
+#define ETHB_CFG_RBOF_0	(0U << 14)	/* RBOF: Rx Buffer Offset */
+#define ETHB_CFG_RBOF_1	(1U << 14)	/* RBOF: Rx Buffer Offset */
+#define ETHB_CFG_RBOF_2	(3U << 14)	/* RBOF: Rx Buffer Offset */
+#define ETHB_CFG_RBOF_3	(3U << 14)	/* RBOF: Rx Buffer Offset */
+#define ETHB_CFG_RCLE	(1U << 16)	/* RCLE: Rx Length Check Enable */
+#define ETHB_CFG_DRFC	(1U << 17)	/* DRFC: Discard Rx FCS */
+#define ETHB_CFG_RHD	(1U << 18)	/* RHD: RX TX'ed frame in half-duplex */
+#define ETHB_CFG_IFCS	(1U << 19)	/* IFCS: Ignore bad RX FCS */
+
+/* ETH_SR */
+#define ETH_SR_LINK	(1U << 0)	/* Reserved! */
+#define ETH_SR_MDIO	(1U << 1)	/* MDIO pin status */
+#define ETH_SR_IDLE	(1U << 2)	/* IDLE (PHY logic) */
+
+/* ETH_TCR */
+#define ETH_TCR_NCRC	(1U << 15)	/* NCRC: No CRC */
+
+/* ETH_TSR */
+#define ETH_TSR_OVR	(1U << 0)	/* OVR: Ethernet Transmit Overrun */
+#define ETH_TSR_COL	(1U << 1)	/* COL: Collision Occurred */
+#define ETH_TSR_RLE	(1U << 2)	/* RLE: Retry Limit Exceeded */
+#define ETH_TSR_IDLE	(1U << 3)	/* IDLE: Transmitter Idle */
+#define ETH_TSR_BNQ	(1U << 4)	/* BNQ: Enet Tran Buff not Queued */
+#define ETH_TSR_COMP	(1U << 5)	/* COMP: Transmit Complete */
+#define ETH_TSR_UND	(1U << 6)	/* UND: Transmit Underrun */
+#define ETH_TSR_WR_MASK (0x67)	/* write 1 to clear bits */
+
+/* ETH_RSR */
+#define ETH_RSR_BNA	(1U << 0)	/* BNA: Buffer Not Available */
+#define ETH_RSR_REC	(1U << 1)	/* REC: Frame Received */
+#define ETH_RSR_OVR	(1U << 2)	/* OVR: RX Overrun */
+
+/* ETH_ISR */
+#define ETH_ISR_DONE	(1U << 0)	/* DONE: Management Done */
+#define ETH_ISR_RCOM	(1U << 1)	/* RCOM: Receive Complete */
+#define ETH_ISR_RBNA	(1U << 2)	/* RBNA: Receive Buffer Not Avail */
+#define ETH_ISR_TOVR	(1U << 3)	/* TOVR: Transmit Buffer Overrun */
+#define ETH_ISR_TUND	(1U << 4)	/* TUND: Transmit Buffer Underrun */
+#define ETH_ISR_RTRY	(1U << 5)	/* RTRY: Retry Limit */
+#define ETH_ISR_TBRE	(1U << 6)	/* TBRE: Trasnmit Buffer Reg empty */
+#define ETH_ISR_TCOM	(1U << 7)	/* TCOM: Transmit Complete */
+#define ETH_ISR_TIDLE	(1U << 8)	/* TIDLE: Transmit Idle */
+#define ETH_ISR_LINK	(1U << 9)	/* LINK: Link pin delta (optional) */
+#define ETH_ISR_ROVR	(1U << 10)	/* ROVR: RX Overrun */
+#define ETH_ISR_ABT	(1U << 11)	/* ABT: Abort */
+
+/* ETHB_UIO */
+#define ETHB_UIO_RMII	(1U << 0)	/* RMII: Reduce MII */
+#define ETHB_UIO_CLKE	(1U << 1)	/* CLKE: Clock Enable */
+
+/* ETH_MAN */
+#define ETH_MAN_BITS	0x40020000	/* HIGH and CODE bits */
+#define ETH_MAN_READ	(2U << 28)
+#define ETH_MAN_WRITE	(1U << 28)
+#define ETH_MAN_PHYA_BIT 23
+#define ETH_MAN_REGA_BIT 18
+#define ETH_MAN_VALUE_MASK	0xffffU
+#define ETH_MAN_REG_WR(phy, reg, val) \
+		(ETH_MAN_BITS | ETH_MAN_WRITE | ((phy) << ETH_MAN_PHYA_BIT) | \
+		((reg) << ETH_MAN_REGA_BIT) | ((val) & ETH_MAN_VALUE_MASK))
+#define ETH_MAN_REG_RD(phy, reg) \
+		(ETH_MAN_BITS | ETH_MAN_READ | ((phy) << ETH_MAN_PHYA_BIT) | \
+		((reg) << ETH_MAN_REGA_BIT))
+
+typedef struct {
+	uint32_t	addr;
+#define ETH_CPU_OWNER	(1U << 0)
+#define ETH_WRAP_BIT	(1U << 1)
+#define ETH_ADR_MASK	~(EHT_CPU_OWNER | ETH_WRAP_BIT)
+	uint32_t	status;
+#define ETH_LEN_MASK	0x7ff
+#define ETH_BUF_FIRST	(1U << 14)	/* Packet matched addr 4 */
+#define ETH_BUF_LAST	(1U << 15)	/* Packet matched addr 4 */
+#define ETH_MAC_LOCAL_4	(1U << 23)	/* Packet matched addr 4 */
+#define ETH_MAC_LOCAL_3	(1U << 24)	/* Packet matched addr 3 */
+#define ETH_MAC_LOCAL_2	(1U << 25)	/* Packet matched addr 2 */
+#define ETH_MAC_LOCAL_1	(1U << 26)	/* Packet matched addr 1 */
+#define ETH_MAC_UNK	(1U << 27)	/* Unkown source address RFU */
+#define ETH_MAC_EXT	(1U << 28)	/* External Address */
+#define ETH_MAC_UCAST	(1U << 29)	/* Unicast hash match */
+#define ETH_MAC_MCAST	(1U << 30)	/* Multicast hash match */
+#define ETH_MAC_ONES	(1U << 31)	/* Global all ones bcast addr */
+} eth_rx_desc_t;
+
+typedef struct {
+	uint32_t	addr;
+	uint32_t	status;
+#define ETHB_TX_LEN_MASK 0x7ff
+#define ETHB_TX_BUF_LAST (1U << 15)	/* Last buffer in packet */
+#define ETHB_TX_NOCRC	 (1U << 16)	/* Don't xmit CRC*/
+#define ETHB_TX_BUFE	 (1U << 27)	/* Buffers exhausted mid frame */
+#define ETHB_TX_TUND	 (1U << 28)	/* Transmit Underrun  */
+#define ETHB_TX_RTRYE	 (1U << 29)	/* Re-try limit exceeded */
+#define ETHB_TX_WRAP	 (1U << 30)	/* Last descritor in list */
+#define ETHB_TX_USED	 (1U << 31)	/* Packet Transmitted */
+} eth_tx_desc_t;
+
+#endif /* ARM_AT91_IF_ATEREG_H */


Property changes on: trunk/sys/arm/at91/if_atereg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/if_macb.c
===================================================================
--- trunk/sys/arm/at91/if_macb.c	                        (rev 0)
+++ trunk/sys/arm/at91/if_macb.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,1554 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2010 Yohanes Nugroho <yohanes at gmail.com>
+ * 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 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 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: stable/10/sys/arm/at91/if_macb.c 243882 2012-12-05 08:04:20Z glebius $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/mbuf.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/rman.h>
+#include <sys/socket.h>
+#include <sys/sockio.h>
+#include <sys/sysctl.h>
+#include <sys/taskqueue.h>
+
+#include <net/ethernet.h>
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <net/if_dl.h>
+#include <net/if_media.h>
+#include <net/if_types.h>
+#include <net/if_vlan_var.h>
+
+#ifdef INET
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#endif
+
+#include <net/bpf.h>
+#include <net/bpfdesc.h>
+
+#include <dev/mii/mii.h>
+#include <dev/mii/miivar.h>
+
+#include <arm/at91/at91_pmcvar.h>
+#include <arm/at91/if_macbreg.h>
+#include <arm/at91/if_macbvar.h>
+#include <arm/at91/at91_piovar.h>
+
+#include <arm/at91/at91sam9g20reg.h>
+
+#include <machine/bus.h>
+#include <machine/intr.h>
+
+/* "device miibus" required.  See GENERIC if you get errors here. */
+#include "miibus_if.h"
+
+
+#define	MACB_LOCK(_sc)		mtx_lock(&(_sc)->sc_mtx)
+#define	MACB_UNLOCK(_sc)		mtx_unlock(&(_sc)->sc_mtx)
+#define	MACB_LOCK_INIT(_sc)					\
+	mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->dev),	\
+	    MTX_NETWORK_LOCK, MTX_DEF)
+#define	MACB_LOCK_DESTROY(_sc)	mtx_destroy(&_sc->sc_mtx);
+#define	MACB_LOCK_ASSERT(_sc)	mtx_assert(&_sc->sc_mtx, MA_OWNED);
+#define	MACB_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED);
+
+
+static inline uint32_t
+read_4(struct macb_softc *sc, bus_size_t off)
+{
+
+	return (bus_read_4(sc->mem_res, off));
+}
+
+static inline void
+write_4(struct macb_softc *sc, bus_size_t off, uint32_t val)
+{
+
+	bus_write_4(sc->mem_res, off, val);
+}
+
+
+static devclass_t macb_devclass;
+
+/* ifnet entry points */
+
+static void	macbinit_locked(void *);
+static void	macbstart_locked(struct ifnet *);
+
+static void	macbinit(void *);
+static void	macbstart(struct ifnet *);
+static void	macbstop(struct macb_softc *);
+static int	macbioctl(struct ifnet * ifp, u_long, caddr_t);
+
+/* bus entry points */
+
+static int	macb_probe(device_t dev);
+static int	macb_attach(device_t dev);
+static int	macb_detach(device_t dev);
+
+/* helper functions */
+static int
+macb_new_rxbuf(struct macb_softc *sc, int index);
+
+static void
+macb_free_desc_dma_tx(struct macb_softc *sc);
+
+static void
+macb_free_desc_dma_rx(struct macb_softc *sc);
+
+static void
+macb_init_desc_dma_tx(struct macb_softc *sc);
+
+static void
+macb_watchdog(struct macb_softc *sc);
+
+static int macb_intr_rx_locked(struct macb_softc *sc, int count);
+static void macb_intr_task(void *arg, int pending __unused);
+static void macb_intr(void *xsc);
+
+static void
+macb_tx_cleanup(struct macb_softc *sc);
+
+static inline int
+phy_write(struct macb_softc *sc, int phy, int reg, int data);
+
+static void	macb_reset(struct macb_softc *sc);
+
+static void
+macb_deactivate(device_t dev)
+{
+	struct macb_softc *sc;
+
+	sc = device_get_softc(dev);
+
+	macb_free_desc_dma_tx(sc);
+	macb_free_desc_dma_rx(sc);
+
+}
+
+static void
+macb_getaddr(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
+{
+	bus_addr_t *paddr;
+
+	KASSERT(nsegs == 1, ("wrong number of segments, should be 1"));
+	paddr = arg;
+	*paddr = segs->ds_addr;
+}
+
+static int
+macb_alloc_desc_dma_tx(struct macb_softc *sc)
+{
+	int error, i;
+
+	/* Allocate a busdma tag and DMA safe memory for TX/RX descriptors. */
+	error = bus_dma_tag_create(sc->sc_parent_tag,	/* parent */
+	    16, 0,			/* alignment, boundary */
+	    BUS_SPACE_MAXADDR,		/* lowaddr */
+	    BUS_SPACE_MAXADDR,		/* highaddr */
+	    NULL, NULL,			/* filtfunc, filtfuncarg */
+	    sizeof(struct eth_tx_desc) * MACB_MAX_TX_BUFFERS, /* max size */
+	    1,				/* nsegments */
+	    sizeof(struct eth_tx_desc) * MACB_MAX_TX_BUFFERS,
+	    0,				/* flags */
+	    NULL, NULL,			/* lockfunc, lockfuncarg */
+	    &sc->dmatag_data_tx);	/* dmat */
+	if (error != 0) {
+		device_printf(sc->dev,
+		    "Couldn't create TX descriptor dma tag\n");
+		return (error);
+	}
+	/* Allocate memory for TX ring. */
+	error = bus_dmamem_alloc(sc->dmatag_data_tx,
+	    (void**)&(sc->desc_tx), BUS_DMA_NOWAIT | BUS_DMA_ZERO |
+	    BUS_DMA_COHERENT, &sc->dmamap_ring_tx);
+	if (error != 0) {
+		device_printf(sc->dev, "failed to allocate TX dma memory\n");
+		return (error);
+	}
+	/* Load Ring DMA. */
+	error = bus_dmamap_load(sc->dmatag_data_tx, sc->dmamap_ring_tx,
+	    sc->desc_tx, sizeof(struct eth_tx_desc) * MACB_MAX_TX_BUFFERS,
+	    macb_getaddr, &sc->ring_paddr_tx, BUS_DMA_NOWAIT);
+	if (error != 0) {
+		device_printf(sc->dev, "can't load TX descriptor dma map\n");
+		return (error);
+	}
+	/* Allocate a busdma tag for mbufs. No alignment restriction applys. */
+	error = bus_dma_tag_create(sc->sc_parent_tag,	/* parent */
+	    1, 0,			/* alignment, boundary */
+	    BUS_SPACE_MAXADDR,		/* lowaddr */
+	    BUS_SPACE_MAXADDR,		/* highaddr */
+	    NULL, NULL,			/* filtfunc, filtfuncarg */
+	    MCLBYTES * MAX_FRAGMENT,	/* maxsize */
+	    MAX_FRAGMENT,		/* nsegments */
+	    MCLBYTES, 0,		/* maxsegsz, flags */
+	    NULL, NULL,			/* lockfunc, lockfuncarg */
+	    &sc->dmatag_ring_tx);	/* dmat */
+	if (error != 0) {
+		device_printf(sc->dev, "failed to create TX mbuf dma tag\n");
+		return (error);
+	}
+
+	for (i = 0; i < MACB_MAX_TX_BUFFERS; i++) {
+		/* Create dma map for each descriptor. */
+		error = bus_dmamap_create(sc->dmatag_ring_tx, 0,
+		    &sc->tx_desc[i].dmamap);
+		if (error != 0) {
+			device_printf(sc->dev,
+			    "failed to create TX mbuf dma map\n");
+			return (error);
+		}
+	}
+	return (0);
+}
+
+static void
+macb_free_desc_dma_tx(struct macb_softc *sc)
+{
+	struct tx_desc_info *td;
+	int i;
+
+	/* TX buffers. */
+	if (sc->dmatag_ring_tx != NULL) {
+		for (i = 0; i < MACB_MAX_TX_BUFFERS; i++) {
+			td = &sc->tx_desc[i];
+			if (td->dmamap != NULL) {
+				bus_dmamap_destroy(sc->dmatag_ring_tx,
+				    td->dmamap);
+				td->dmamap = NULL;
+			}
+		}
+		bus_dma_tag_destroy(sc->dmatag_ring_tx);
+		sc->dmatag_ring_tx = NULL;
+	}
+
+	/* TX descriptor ring. */
+	if (sc->dmatag_data_tx != NULL) {
+		if (sc->dmamap_ring_tx != NULL)
+			bus_dmamap_unload(sc->dmatag_data_tx,
+			    sc->dmamap_ring_tx);
+		if (sc->dmamap_ring_tx != NULL && sc->desc_tx != NULL)
+			bus_dmamem_free(sc->dmatag_data_tx, sc->desc_tx,
+			    sc->dmamap_ring_tx);
+		sc->dmamap_ring_tx = NULL;
+		sc->dmamap_ring_tx = NULL;
+		bus_dma_tag_destroy(sc->dmatag_data_tx);
+		sc->dmatag_data_tx = NULL;
+	}
+}
+
+static void
+macb_init_desc_dma_tx(struct macb_softc *sc)
+{
+	struct eth_tx_desc *desc;
+	int i;
+
+	MACB_LOCK_ASSERT(sc);
+
+	sc->tx_prod = 0;
+	sc->tx_cons = 0;
+	sc->tx_cnt = 0;
+
+	desc = &sc->desc_tx[0];
+	bzero(desc, sizeof(struct eth_tx_desc) * MACB_MAX_TX_BUFFERS);
+
+	for (i = 0; i < MACB_MAX_TX_BUFFERS; i++) {
+		desc = &sc->desc_tx[i];
+		if (i == MACB_MAX_TX_BUFFERS - 1)
+			desc->flags = TD_OWN | TD_WRAP_MASK;
+		else
+			desc->flags = TD_OWN;
+	}
+
+	bus_dmamap_sync(sc->dmatag_data_tx, sc->dmamap_ring_tx,
+	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+}
+
+static int
+macb_alloc_desc_dma_rx(struct macb_softc *sc)
+{
+	int error, i;
+
+	/* Allocate a busdma tag and DMA safe memory for RX descriptors. */
+	error = bus_dma_tag_create(sc->sc_parent_tag,	/* parent */
+	    16, 0,			/* alignment, boundary */
+	    BUS_SPACE_MAXADDR,		/* lowaddr */
+	    BUS_SPACE_MAXADDR,		/* highaddr */
+	    NULL, NULL,			/* filtfunc, filtfuncarg */
+	    /* maxsize, nsegments */
+	    sizeof(struct eth_rx_desc) * MACB_MAX_RX_BUFFERS, 1,
+	    /* maxsegsz, flags */
+	    sizeof(struct eth_rx_desc) * MACB_MAX_RX_BUFFERS, 0,
+	    NULL, NULL,			/* lockfunc, lockfuncarg */
+	    &sc->dmatag_data_rx);	/* dmat */
+	if (error != 0) {
+		device_printf(sc->dev,
+		    "Couldn't create RX descriptor dma tag\n");
+		return (error);
+	}
+	/* Allocate RX ring. */
+	error = bus_dmamem_alloc(sc->dmatag_data_rx, (void**)&(sc->desc_rx),
+	    BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT,
+	    &sc->dmamap_ring_rx);
+	if (error != 0) {
+		device_printf(sc->dev,
+		    "failed to allocate RX descriptor dma memory\n");
+		return (error);
+	}
+
+	/* Load dmamap. */
+	error = bus_dmamap_load(sc->dmatag_data_rx, sc->dmamap_ring_rx,
+	    sc->desc_rx, sizeof(struct eth_rx_desc) * MACB_MAX_RX_BUFFERS,
+	    macb_getaddr, &sc->ring_paddr_rx, BUS_DMA_NOWAIT);
+	if (error != 0) {
+		device_printf(sc->dev, "can't load RX descriptor dma map\n");
+		return (error);
+	}
+
+	/* Allocate a busdma tag for mbufs. */
+	error = bus_dma_tag_create(sc->sc_parent_tag,/* parent */
+	    16, 0,			/* alignment, boundary */
+	    BUS_SPACE_MAXADDR,		/* lowaddr */
+	    BUS_SPACE_MAXADDR,		/* highaddr */
+	    NULL, NULL,			/* filtfunc, filtfuncarg */
+	    MCLBYTES, 1,		/* maxsize, nsegments */
+	    MCLBYTES, 0,		/* maxsegsz, flags */
+	    NULL, NULL,			/* lockfunc, lockfuncarg */
+	    &sc->dmatag_ring_rx);	/* dmat */
+
+	if (error != 0) {
+		device_printf(sc->dev, "failed to create RX mbuf dma tag\n");
+		return (error);
+	}
+
+	for (i = 0; i < MACB_MAX_RX_BUFFERS; i++) {
+		error = bus_dmamap_create(sc->dmatag_ring_rx, 0,
+		    &sc->rx_desc[i].dmamap);
+		if (error != 0) {
+			device_printf(sc->dev,
+			    "failed to create RX mbuf dmamap\n");
+			return (error);
+		}
+	}
+
+	return (0);
+}
+
+static void
+macb_free_desc_dma_rx(struct macb_softc *sc)
+{
+	struct rx_desc_info *rd;
+	int i;
+
+	/* RX buffers. */
+	if (sc->dmatag_ring_rx != NULL) {
+		for (i = 0; i < MACB_MAX_RX_BUFFERS; i++) {
+			rd = &sc->rx_desc[i];
+			if (rd->dmamap != NULL) {
+				bus_dmamap_destroy(sc->dmatag_ring_rx,
+				    rd->dmamap);
+				rd->dmamap = NULL;
+			}
+		}
+		bus_dma_tag_destroy(sc->dmatag_ring_rx);
+		sc->dmatag_ring_rx = NULL;
+	}
+	/* RX descriptor ring. */
+	if (sc->dmatag_data_rx != NULL) {
+		if (sc->dmamap_ring_rx != NULL)
+			bus_dmamap_unload(sc->dmatag_data_rx,
+			    sc->dmamap_ring_rx);
+		if (sc->dmamap_ring_rx != NULL &&
+		    sc->desc_rx != NULL)
+			bus_dmamem_free(sc->dmatag_data_rx, sc->desc_rx,
+			    sc->dmamap_ring_rx);
+		sc->desc_rx = NULL;
+		sc->dmamap_ring_rx = NULL;
+		bus_dma_tag_destroy(sc->dmatag_data_rx);
+		sc->dmatag_data_rx = NULL;
+	}
+}
+
+static int
+macb_init_desc_dma_rx(struct macb_softc *sc)
+{
+	struct eth_rx_desc *desc;
+	struct rx_desc_info *rd;
+	int i;
+
+	MACB_LOCK_ASSERT(sc);
+
+	sc->rx_cons = 0;
+	desc = &sc->desc_rx[0];
+	bzero(desc, sizeof(struct eth_rx_desc) * MACB_MAX_RX_BUFFERS);
+	for (i = 0; i < MACB_MAX_RX_BUFFERS; i++) {
+		rd = &sc->rx_desc[i];
+		rd->buff = NULL;
+		if (macb_new_rxbuf(sc, i) != 0)
+			return (ENOBUFS);
+	}
+	bus_dmamap_sync(sc->dmatag_ring_rx, sc->dmamap_ring_rx,
+	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+	return (0);
+}
+
+static int
+macb_new_rxbuf(struct macb_softc *sc, int index)
+{
+	struct rx_desc_info *rd;
+	struct eth_rx_desc *desc;
+	struct mbuf *m;
+	bus_dma_segment_t seg[1];
+	int error, nsegs;
+
+	m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
+	if (m == NULL)
+		return (ENOBUFS);
+	m->m_len = m->m_pkthdr.len = MCLBYTES - ETHER_ALIGN;
+	rd = &sc->rx_desc[index];
+	bus_dmamap_unload(sc->dmatag_ring_rx, rd->dmamap);
+	error = bus_dmamap_load_mbuf_sg(sc->dmatag_ring_rx, rd->dmamap, m,
+	    seg, &nsegs, 0);
+	KASSERT(nsegs == 1, ("Too many segments returned!"));
+	if (error != 0) {
+		m_free(m);
+		return (error);
+	}
+
+	bus_dmamap_sync(sc->dmatag_ring_rx, rd->dmamap, BUS_DMASYNC_PREREAD);
+	rd->buff = m;
+
+	desc = &sc->desc_rx[index];
+	desc->addr = seg[0].ds_addr;
+
+	desc->flags = DATA_SIZE;
+
+	if (index == MACB_MAX_RX_BUFFERS - 1)
+		desc->addr |= RD_WRAP_MASK;
+
+	return (0);
+}
+
+static int
+macb_allocate_dma(struct macb_softc *sc)
+{
+	int error;
+
+	/* Create parent tag for tx and rx */
+	error = bus_dma_tag_create(
+	    bus_get_dma_tag(sc->dev),	/* parent */
+	    1, 0,			/* alignment, boundary */
+	    BUS_SPACE_MAXADDR_32BIT,	/* lowaddr */
+	    BUS_SPACE_MAXADDR,		/* highaddr */
+	    NULL, NULL,			/* filter, filterarg */
+	    BUS_SPACE_MAXSIZE_32BIT, 0,	/* maxsize, nsegments */
+	    BUS_SPACE_MAXSIZE_32BIT,	/* maxsegsize */
+	    0,				/* flags */
+	    NULL, NULL,		/* lockfunc, lockarg */
+	    &sc->sc_parent_tag);
+	if (error != 0) {
+		device_printf(sc->dev, "Couldn't create parent DMA tag\n");
+		return (error);
+	}
+
+	if ((error = macb_alloc_desc_dma_tx(sc)) != 0)
+		return (error);
+	if ((error = macb_alloc_desc_dma_rx(sc)) != 0)
+		return (error);
+	return (0);
+}
+
+
+static void
+macb_tick(void *xsc)
+{
+	struct macb_softc *sc;
+	struct mii_data *mii;
+
+	sc = xsc;
+	mii = device_get_softc(sc->miibus);
+	mii_tick(mii);
+	macb_watchdog(sc);
+	/*
+	 * Schedule another timeout one second from now.
+	 */
+	callout_reset(&sc->tick_ch, hz, macb_tick, sc);
+}
+
+
+static void
+macb_watchdog(struct macb_softc *sc)
+{
+	struct ifnet *ifp;
+
+	MACB_LOCK_ASSERT(sc);
+
+	if (sc->macb_watchdog_timer == 0 || --sc->macb_watchdog_timer)
+		return;
+
+	ifp = sc->ifp;
+	if ((sc->flags & MACB_FLAG_LINK) == 0) {
+		if_printf(ifp, "watchdog timeout (missed link)\n");
+		ifp->if_oerrors++;
+		return;
+	}
+
+	if_printf(ifp, "watchdog timeout\n");
+	ifp->if_oerrors++;
+	ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
+	macbinit_locked(sc);
+	if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
+		macbstart_locked(ifp);
+}
+
+
+
+static void
+macbinit_locked(void *xsc)
+{
+	struct macb_softc *sc;
+	struct ifnet *ifp;
+	int err;
+	uint32_t config;
+	struct mii_data *mii;
+
+	sc = xsc;
+	ifp = sc->ifp;
+
+	MACB_LOCK_ASSERT(sc);
+
+	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
+		return;
+
+	if ((err = macb_init_desc_dma_rx(sc)) != 0) {
+		device_printf(sc->dev, "no memory for RX buffers\n");
+		//ecestop(sc);
+		return;
+	}
+	macb_init_desc_dma_tx(sc);
+
+	config = read_4(sc, EMAC_NCFGR) | (sc->clock << 10); /*set clock*/
+	config |= CFG_PAE;		/* PAuse Enable */
+	config |= CFG_DRFCS;		/* Discard Rx FCS */
+	config |= CFG_SPD;		/* 100 mbps*/
+	//config |= CFG_CAF;
+	config |= CFG_FD;
+
+	config |= CFG_RBOF_2; /*offset +2*/
+
+	write_4(sc, EMAC_NCFGR, config);
+
+	/* Initialize TX and RX buffers */
+	write_4(sc, EMAC_RBQP, sc->ring_paddr_rx);
+	write_4(sc, EMAC_TBQP, sc->ring_paddr_tx);
+
+	/* Enable TX and RX */
+	write_4(sc, EMAC_NCR, RX_ENABLE | TX_ENABLE | MPE_ENABLE);
+
+
+	/* Enable interrupts */
+	write_4(sc, EMAC_IER, (RCOMP_INTERRUPT |
+			       RXUBR_INTERRUPT |
+			       TUND_INTERRUPT |
+			       RLE_INTERRUPT |
+			       TXERR_INTERRUPT |
+			       ROVR_INTERRUPT |
+			       HRESP_INTERRUPT|
+			       TCOMP_INTERRUPT
+			));
+
+	/*
+	 * Set 'running' flag, and clear output active flag
+	 * and attempt to start the output
+	 */
+	ifp->if_drv_flags |= IFF_DRV_RUNNING;
+	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+
+	mii = device_get_softc(sc->miibus);
+
+	sc->flags |= MACB_FLAG_LINK;
+
+	mii_mediachg(mii);
+
+	callout_reset(&sc->tick_ch, hz, macb_tick, sc);
+}
+
+
+static void
+macb_tx_cleanup(struct macb_softc *sc)
+{
+	struct ifnet *ifp;
+	struct eth_tx_desc *desc;
+	struct tx_desc_info *td;
+	int flags;
+	int status;
+	int i;
+
+	MACB_LOCK_ASSERT(sc);
+
+	status = read_4(sc, EMAC_TSR);
+
+	write_4(sc, EMAC_TSR, status);
+
+	/*buffer underrun*/
+	if ((status & TSR_UND) != 0) {
+		/*reset buffers*/
+		printf("underrun\n");
+		bus_dmamap_sync(sc->dmatag_data_tx, sc->dmamap_ring_tx,
+		    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
+		sc->tx_cons = sc->tx_prod = 0;
+		for (i = 0; i < MACB_MAX_TX_BUFFERS; i++) {
+			desc = &sc->desc_tx[i];
+			desc->flags = TD_OWN;
+		}
+
+		for (i = 0; i < MACB_MAX_TX_BUFFERS; i++) {
+			td = &sc->tx_desc[i];
+			if (td->buff != NULL) {
+				/* We are finished with this descriptor. */
+				bus_dmamap_sync(sc->dmatag_ring_tx, td->dmamap,
+						BUS_DMASYNC_POSTWRITE);
+				/* ... and unload, so we can reuse. */
+				bus_dmamap_unload(sc->dmatag_data_tx,
+						  td->dmamap);
+				m_freem(td->buff);
+				td->buff = NULL;
+			}
+		}
+	}
+
+	if ((status & TSR_COMP) == 0)
+		return;
+
+
+	if (sc->tx_cons == sc->tx_prod)
+		return;
+
+	ifp = sc->ifp;
+
+	/* Prepare to read the ring (owner bit). */
+	bus_dmamap_sync(sc->dmatag_data_tx, sc->dmamap_ring_tx,
+	    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
+	while (sc->tx_cons != sc->tx_prod) {
+		desc = &sc->desc_tx[sc->tx_cons];
+		if ((desc->flags & TD_OWN) == 0)
+			break;
+
+		td = &sc->tx_desc[sc->tx_cons];
+		if (td->buff != NULL) {
+			/* We are finished with this descriptor. */
+			bus_dmamap_sync(sc->dmatag_ring_tx, td->dmamap,
+					BUS_DMASYNC_POSTWRITE);
+			/* ... and unload, so we can reuse. */
+			bus_dmamap_unload(sc->dmatag_data_tx,
+					  td->dmamap);
+			m_freem(td->buff);
+			td->buff = NULL;
+			ifp->if_opackets++;
+		}
+
+		do {
+			sc->tx_cnt--;
+			MACB_DESC_INC(sc->tx_cons, MACB_MAX_TX_BUFFERS);
+			ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+			flags = desc->flags;
+			desc->flags = TD_OWN;
+			desc = &sc->desc_tx[sc->tx_cons];
+			if (flags & TD_LAST) {
+				break;
+			}
+		} while (sc->tx_cons != sc->tx_prod);
+	}
+
+	/* Unarm watchog timer when there is no pending descriptors in queue. */
+	if (sc->tx_cnt == 0)
+		sc->macb_watchdog_timer = 0;
+}
+
+static void
+macb_rx(struct macb_softc *sc)
+{
+	struct eth_rx_desc	*rxdesc;
+	struct ifnet *ifp;
+	struct mbuf *m;
+	int rxbytes;
+	int flags;
+	int nsegs;
+	int first;
+
+	rxdesc = &(sc->desc_rx[sc->rx_cons]);
+
+	ifp = sc->ifp;
+
+	bus_dmamap_sync(sc->dmatag_ring_rx, sc->dmamap_ring_rx,
+	    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
+
+
+	nsegs = 0;
+	while (rxdesc->addr & RD_OWN) {
+
+		if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+			break;
+
+		flags = rxdesc->flags;
+
+		rxbytes = flags & RD_LEN_MASK;
+
+		m = sc->rx_desc[sc->rx_cons].buff;
+
+		bus_dmamap_sync(sc->dmatag_ring_rx,
+		    sc->rx_desc[sc->rx_cons].dmamap, BUS_DMASYNC_POSTREAD);
+		if (macb_new_rxbuf(sc, sc->rx_cons) != 0) {
+			ifp->if_iqdrops++;
+			first = sc->rx_cons;
+			
+			do  {
+				rxdesc->flags = DATA_SIZE;
+				MACB_DESC_INC(sc->rx_cons, MACB_MAX_RX_BUFFERS);
+				if ((rxdesc->flags & RD_EOF) != 0)
+					break;
+				rxdesc = &(sc->desc_rx[sc->rx_cons]);
+			} while (sc->rx_cons != first);
+
+			if (sc->macb_cdata.rxhead != NULL) {
+				m_freem(sc->macb_cdata.rxhead);
+				sc->macb_cdata.rxhead = NULL;
+				sc->macb_cdata.rxtail = NULL;				
+			}
+			
+			break;
+		}
+
+		nsegs++;
+
+		/* Chain received mbufs. */
+		if (sc->macb_cdata.rxhead == NULL) {
+			m->m_data += 2;
+			sc->macb_cdata.rxhead = m;
+			sc->macb_cdata.rxtail = m;
+			if (flags & RD_EOF)
+				m->m_len = rxbytes;
+			else
+				m->m_len = DATA_SIZE - 2;
+		} else {
+			m->m_flags &= ~M_PKTHDR;
+			m->m_len = DATA_SIZE;
+			sc->macb_cdata.rxtail->m_next = m;
+			sc->macb_cdata.rxtail = m;
+		}
+
+		if (flags & RD_EOF) {
+
+			if (nsegs > 1) {
+				sc->macb_cdata.rxtail->m_len = (rxbytes -
+				    ((nsegs - 1) * DATA_SIZE)) + 2;
+			}
+
+			m = sc->macb_cdata.rxhead;
+			m->m_flags |= M_PKTHDR;
+			m->m_pkthdr.len = rxbytes;
+			m->m_pkthdr.rcvif = ifp;
+			ifp->if_ipackets++;
+
+			nsegs = 0;
+			MACB_UNLOCK(sc);
+			(*ifp->if_input)(ifp, m);
+			MACB_LOCK(sc);
+			sc->macb_cdata.rxhead = NULL;
+			sc->macb_cdata.rxtail = NULL;
+
+		}
+		
+		rxdesc->addr &= ~RD_OWN;
+
+		MACB_DESC_INC(sc->rx_cons, MACB_MAX_RX_BUFFERS);
+
+		rxdesc = &(sc->desc_rx[sc->rx_cons]);
+	}
+
+	write_4(sc, EMAC_IER, (RCOMP_INTERRUPT|RXUBR_INTERRUPT));
+
+}
+
+static int
+macb_intr_rx_locked(struct macb_softc *sc, int count)
+{
+	macb_rx(sc);
+	return (0);
+}
+
+static void
+macb_intr_task(void *arg, int pending __unused)
+{
+	struct macb_softc *sc;
+
+	sc = arg;
+	MACB_LOCK(sc);
+	macb_intr_rx_locked(sc, -1);
+	MACB_UNLOCK(sc);
+}
+
+static void
+macb_intr(void *xsc)
+{
+	struct macb_softc *sc;
+	struct ifnet *ifp;
+	uint32_t status;
+
+	sc = xsc;
+	ifp = sc->ifp;
+	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
+		printf("not running\n");
+		return;
+	}
+
+	MACB_LOCK(sc);
+	status = read_4(sc, EMAC_ISR);
+
+	while (status) {
+		if (status & RCOMP_INTERRUPT) {
+			write_4(sc, EMAC_IDR, (RCOMP_INTERRUPT|RXUBR_INTERRUPT));
+			taskqueue_enqueue(sc->sc_tq, &sc->sc_intr_task);
+		}
+
+		if (status & TCOMP_INTERRUPT) {
+			macb_tx_cleanup(sc);
+		}
+
+		status = read_4(sc, EMAC_ISR);
+	}
+
+	if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
+		macbstart_locked(ifp);
+	MACB_UNLOCK(sc);
+}
+
+static inline int
+macb_encap(struct macb_softc *sc, struct mbuf **m_head)
+{
+	struct eth_tx_desc *desc;
+	struct tx_desc_info *txd, *txd_last;
+	struct mbuf *m;
+	bus_dma_segment_t segs[MAX_FRAGMENT];
+	bus_dmamap_t map;
+	uint32_t csum_flags;
+	int error, i, nsegs, prod, si;
+
+	M_ASSERTPKTHDR((*m_head));
+
+	prod = sc->tx_prod;
+
+	m = *m_head;
+
+	txd = txd_last = &sc->tx_desc[prod];
+	error = bus_dmamap_load_mbuf_sg(sc->dmatag_ring_tx, txd->dmamap,
+	    *m_head, segs, &nsegs, 0);
+	if (error == EFBIG) {
+		m = m_collapse(*m_head, M_NOWAIT, MAX_FRAGMENT);
+		if (m == NULL) {
+			m_freem(*m_head);
+			*m_head = NULL;
+			return (ENOMEM);
+		}
+		*m_head = m;
+		error = bus_dmamap_load_mbuf_sg(sc->dmatag_ring_tx, txd->dmamap,
+		    *m_head, segs, &nsegs, 0);
+		if (error != 0) {
+			m_freem(*m_head);
+			*m_head = NULL;
+			return (error);
+		}
+	} else if (error != 0) {
+		return (error);
+	}
+	/* Check for TX descriptor overruns. */
+	if (sc->tx_cnt + nsegs > MACB_MAX_TX_BUFFERS - 1) {
+		bus_dmamap_unload(sc->dmatag_ring_tx, txd->dmamap);
+		return (ENOBUFS);
+	}
+	bus_dmamap_sync(sc->dmatag_ring_tx, txd->dmamap, BUS_DMASYNC_PREWRITE);
+	m = *m_head;
+
+	/* TODO: VLAN hardware tag insertion. */
+
+	csum_flags = 0;
+	si = prod;
+	desc = NULL;
+
+	for (i = 0; i < nsegs; i++) {
+		desc = &sc->desc_tx[prod];
+		desc->addr = segs[i].ds_addr;
+
+		if (i == 0 ) {
+			desc->flags = segs[i].ds_len | TD_OWN;
+		} else {
+			desc->flags = segs[i].ds_len;
+		}
+
+		if (prod == MACB_MAX_TX_BUFFERS - 1)
+			desc->flags |= TD_WRAP_MASK;
+
+		sc->tx_cnt++;
+		MACB_DESC_INC(prod, MACB_MAX_TX_BUFFERS);
+	}
+	/*
+	 * Set EOP on the last fragment.
+	 */
+
+	desc->flags |= TD_LAST;
+	desc = &sc->desc_tx[si];
+	desc->flags &= ~TD_OWN;
+
+	sc->tx_prod = prod;
+
+	/* Swap the first dma map and the last. */
+	map = txd_last->dmamap;
+	txd_last->dmamap = txd->dmamap;
+	txd->dmamap = map;
+	txd->buff = m;
+
+	return (0);
+}
+
+
+static void
+macbstart_locked(struct ifnet *ifp)
+{
+
+
+
+	struct macb_softc *sc;
+	struct mbuf *m0;
+#if 0
+	struct mbuf *m_new;
+#endif
+	int queued = 0;
+
+	sc = ifp->if_softc;
+
+	if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
+	    IFF_DRV_RUNNING || (sc->flags & MACB_FLAG_LINK) == 0) {
+		return;
+	}
+
+	while (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
+		/* Get packet from the queue */
+		IF_DEQUEUE(&ifp->if_snd, m0);
+		if (m0 == NULL)
+			break;
+#if 0
+		if (m0->m_next != NULL) {
+			/* Fragmented mbuf chain, collapse it. */
+			m_new = m_defrag(m0, M_NOWAIT);
+			if (m_new != NULL) {
+				/* Original frame freed. */
+				m0 = m_new;
+			} else {
+				/* Defragmentation failed, just use the chain. */
+			}
+		}
+#endif
+		if (macb_encap(sc, &m0)) {
+			if (m0 == NULL)
+				break;
+			IF_PREPEND(&ifp->if_snd, m0);
+			ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+			break;
+		}
+		queued++;
+		BPF_MTAP(ifp, m0);
+	}
+	if (IFQ_DRV_IS_EMPTY(&ifp->if_snd))
+		ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+	if (queued) {
+		bus_dmamap_sync(sc->dmatag_data_tx, sc->dmamap_ring_tx,
+		    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+		write_4(sc, EMAC_NCR, read_4(sc, EMAC_NCR) | TRANSMIT_START);
+		sc->macb_watchdog_timer = MACB_TIMEOUT;
+	}
+}
+
+static void
+macbinit(void *xsc)
+{
+	struct macb_softc *sc = xsc;
+
+	MACB_LOCK(sc);
+	macbinit_locked(sc);
+	MACB_UNLOCK(sc);
+}
+
+static void
+macbstart(struct ifnet *ifp)
+{
+	struct macb_softc *sc = ifp->if_softc;
+	MACB_ASSERT_UNLOCKED(sc);
+	MACB_LOCK(sc);
+	macbstart_locked(ifp);
+	MACB_UNLOCK(sc);
+
+}
+
+
+static void
+macbstop(struct macb_softc *sc)
+{
+	struct ifnet *ifp = sc->ifp;
+	struct rx_desc_info *rd;
+	struct tx_desc_info *td;
+	int i;
+
+	ifp = sc->ifp;
+
+	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+
+	macb_reset(sc);
+
+	sc->flags &= ~MACB_FLAG_LINK;
+	callout_stop(&sc->tick_ch);
+	sc->macb_watchdog_timer = 0;
+
+	/* Free TX/RX mbufs still in the queues. */
+	for (i = 0; i < MACB_MAX_TX_BUFFERS; i++) {
+		td = &sc->tx_desc[i];
+		if (td->buff != NULL) {
+			bus_dmamap_sync(sc->dmatag_ring_tx, td->dmamap,
+			    BUS_DMASYNC_POSTWRITE);
+			bus_dmamap_unload(sc->dmatag_data_tx, td->dmamap);
+			m_freem(td->buff);
+			td->buff = NULL;
+		}
+	}
+	for (i = 0; i < MACB_MAX_RX_BUFFERS; i++) {
+		rd = &sc->rx_desc[i];
+		if (rd->buff != NULL) {
+			bus_dmamap_sync(sc->dmatag_ring_rx, rd->dmamap,
+			    BUS_DMASYNC_POSTREAD);
+			bus_dmamap_unload(sc->dmatag_data_rx, rd->dmamap);
+			m_freem(rd->buff);
+			rd->buff = NULL;
+		}
+	}	
+}
+
+static int
+get_hash_index(uint8_t *mac)
+{
+	int i, j, k;
+	int result;
+	int bit;
+
+	result = 0;
+	for (i = 0; i < 6; i++) {
+		bit = 0;
+		for (j = 0; j < 8;  j++) {
+			k = j * 6 + i;
+			bit ^= (mac[k/8] & (1 << (k % 8)) ) != 0;
+		}
+		result |= bit;
+	}
+	return result;
+}
+
+static void
+set_mac_filter(uint32_t *filter, uint8_t *mac)
+{
+	int bits;
+
+	bits = get_hash_index(mac);
+	filter[bits >> 5] |= 1 << (bits & 31);
+}
+
+static void
+set_filter(struct macb_softc *sc)
+{
+	struct ifnet *ifp;
+	struct ifmultiaddr *ifma;
+	int config;
+	int count;
+	uint32_t multicast_filter[2];
+
+	ifp = sc->ifp;
+
+	config = read_4(sc, EMAC_NCFGR);
+	
+	config &= ~(CFG_CAF | CFG_MTI);
+	write_4(sc, EMAC_HRB, 0);
+	write_4(sc, EMAC_HRT, 0);
+
+	if ((ifp->if_flags & (IFF_ALLMULTI |IFF_PROMISC)) != 0){
+		if ((ifp->if_flags & IFF_ALLMULTI) != 0) {
+			write_4(sc, EMAC_HRB, ~0);
+			write_4(sc, EMAC_HRT, ~0);
+			config |= CFG_MTI;
+		}
+		if ((ifp->if_flags & IFF_PROMISC) != 0) {
+			config |= CFG_CAF;
+		}
+		write_4(sc, EMAC_NCFGR, config);
+		return;
+	}
+
+	if_maddr_rlock(ifp);
+	count = 0;
+	multicast_filter[0] = 0;
+	multicast_filter[1] = 0;
+
+	TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
+		if (ifma->ifma_addr->sa_family != AF_LINK)
+			continue;
+		count++;
+		set_mac_filter(multicast_filter,
+			   LLADDR((struct sockaddr_dl *)ifma->ifma_addr));
+	}
+	if (count) {
+		write_4(sc, EMAC_HRB, multicast_filter[0]);
+		write_4(sc, EMAC_HRT, multicast_filter[1]);
+		write_4(sc, EMAC_NCFGR, config|CFG_MTI);
+	}
+	if_maddr_runlock(ifp);
+}
+
+static int
+macbioctl(struct ifnet * ifp, u_long cmd, caddr_t data)
+{
+
+	struct macb_softc *sc = ifp->if_softc;
+	struct mii_data *mii;
+	struct ifreq *ifr = (struct ifreq *)data;
+
+	int error = 0;
+
+	switch (cmd) {
+	case SIOCSIFFLAGS:
+		MACB_LOCK(sc);
+
+		if ((ifp->if_flags & IFF_UP) != 0) {
+			if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) {
+				if (((ifp->if_flags ^ sc->if_flags)
+				    & (IFF_PROMISC | IFF_ALLMULTI)) != 0)
+					set_filter(sc);
+			} else {
+				macbinit_locked(sc);
+			}
+		} else if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) {
+			macbstop(sc);
+		}
+		sc->if_flags = ifp->if_flags;
+		MACB_UNLOCK(sc);
+		break;
+	case SIOCADDMULTI:
+	case SIOCDELMULTI:
+		MACB_LOCK(sc);
+		if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
+			set_filter(sc);
+
+		MACB_UNLOCK(sc);
+		break;
+	case SIOCSIFMEDIA:
+	case SIOCGIFMEDIA:
+		mii = device_get_softc(sc->miibus);
+		error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, cmd);
+		break;
+	default:
+		error = ether_ioctl(ifp, cmd, data);
+		break;
+	}
+	return (error);
+
+}
+
+/* bus entry points */
+
+static int
+macb_probe(device_t dev)
+{
+	device_set_desc(dev, "macb");
+	return (0);
+}
+
+/*
+ * Change media according to request.
+ */
+static int
+macb_ifmedia_upd(struct ifnet *ifp)
+{
+	struct macb_softc *sc = ifp->if_softc;
+	struct mii_data *mii;
+
+	mii = device_get_softc(sc->miibus);
+	MACB_LOCK(sc);
+	mii_mediachg(mii);
+	MACB_UNLOCK(sc);
+	return (0);
+}
+
+/*
+ * Notify the world which media we're using.
+ */
+static void
+macb_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
+{
+	struct macb_softc *sc = ifp->if_softc;
+	struct mii_data *mii;
+
+	mii = device_get_softc(sc->miibus);
+
+	MACB_LOCK(sc);
+	/* Don't report link state if driver is not running. */
+	if ((ifp->if_flags & IFF_UP) == 0) {
+		MACB_UNLOCK(sc);
+		return;
+	}
+	mii_pollstat(mii);
+	ifmr->ifm_active = mii->mii_media_active;
+	ifmr->ifm_status = mii->mii_media_status;
+	MACB_UNLOCK(sc);
+}
+
+static void
+macb_reset(struct macb_softc *sc)
+{
+	/*
+	 * Disable RX and TX
+	 */
+	write_4(sc, EMAC_NCR, 0);
+
+	write_4(sc, EMAC_NCR, CLEAR_STAT);
+
+	/* Clear all status flags */
+	write_4(sc, EMAC_TSR, ~0UL);
+	write_4(sc, EMAC_RSR, ~0UL);
+
+	/* Disable all interrupts */
+	write_4(sc, EMAC_IDR, ~0UL);
+	read_4(sc, EMAC_ISR);
+
+}
+
+
+static int
+macb_get_mac(struct macb_softc *sc, u_char *eaddr)
+{
+	uint32_t bottom;
+	uint16_t top;
+
+	bottom = read_4(sc, EMAC_SA1B);
+	top = read_4(sc, EMAC_SA1T);
+
+	eaddr[0] = bottom & 0xff;
+	eaddr[1] = (bottom >> 8) & 0xff;
+	eaddr[2] = (bottom >> 16) & 0xff;
+	eaddr[3] = (bottom >> 24) & 0xff;
+	eaddr[4] = top & 0xff;
+	eaddr[5] = (top >> 8) & 0xff;
+
+	return (0);
+}
+
+
+static int
+macb_attach(device_t dev)
+{
+	struct macb_softc *sc;
+	struct ifnet *ifp = NULL;
+	struct sysctl_ctx_list *sctx;
+	struct sysctl_oid *soid;
+	int pclk_hz;
+	u_char eaddr[ETHER_ADDR_LEN];
+	int rid;
+	int err;
+	struct at91_pmc_clock *master;
+
+
+	err = 0;
+
+	sc = device_get_softc(dev);
+	sc->dev = dev;
+
+	MACB_LOCK_INIT(sc);
+
+	callout_init_mtx(&sc->tick_ch, &sc->sc_mtx, 0);
+
+	/*
+	 * Allocate resources.
+	 */
+	rid = 0;
+	sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	    RF_ACTIVE);
+	if (sc->mem_res == NULL) {
+		device_printf(dev, "could not allocate memory resources.\n");
+		err = ENOMEM;
+		goto out;
+	}
+	rid = 0;
+	sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+	    RF_ACTIVE);
+	if (sc->irq_res == NULL) {
+		device_printf(dev, "could not allocate interrupt resources.\n");
+		err = ENOMEM;
+		goto out;
+	}
+
+	/*setup clock*/
+	sc->clk = at91_pmc_clock_ref(device_get_nameunit(sc->dev));
+	at91_pmc_clock_enable(sc->clk);
+
+	macb_reset(sc);
+	macb_get_mac(sc, eaddr);
+
+	master = at91_pmc_clock_ref("mck");
+
+	pclk_hz = master->hz;
+
+	sc->clock = CFG_CLK_8;
+	if (pclk_hz <= 20000000)
+		sc->clock = CFG_CLK_8;
+	else if (pclk_hz <= 40000000)
+		sc->clock = CFG_CLK_16;
+	else if (pclk_hz <= 80000000)
+		sc->clock = CFG_CLK_32;
+	else
+		sc->clock = CFG_CLK_64;
+
+	sc->clock = sc->clock << 10;
+
+	write_4(sc, EMAC_NCFGR, sc->clock);
+	write_4(sc, EMAC_USRIO, USRIO_CLOCK);       //enable clock
+
+	write_4(sc, EMAC_NCR, MPE_ENABLE); //enable MPE
+
+	sc->ifp = ifp = if_alloc(IFT_ETHER);
+	err = mii_attach(dev, &sc->miibus, ifp, macb_ifmedia_upd,
+	    macb_ifmedia_sts, BMSR_DEFCAPMASK, MII_PHY_ANY, MII_OFFSET_ANY, 0);
+	if (err != 0) {
+		device_printf(dev, "attaching PHYs failed\n");
+		goto out;
+	}
+
+	if (macb_allocate_dma(sc) != 0)
+		goto out;
+
+	/* Sysctls */
+	sctx = device_get_sysctl_ctx(dev);
+	soid = device_get_sysctl_tree(dev);
+
+	ifp->if_softc = sc;
+	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
+	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+	ifp->if_capabilities |= IFCAP_VLAN_MTU;
+	ifp->if_capenable |= IFCAP_VLAN_MTU;	/* The hw bits already set. */
+	ifp->if_start = macbstart;
+	ifp->if_ioctl = macbioctl;
+	ifp->if_init = macbinit;
+	IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
+	ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
+	IFQ_SET_READY(&ifp->if_snd);
+	sc->if_flags = ifp->if_flags;
+
+	TASK_INIT(&sc->sc_intr_task, 0, macb_intr_task, sc);
+
+	sc->sc_tq = taskqueue_create_fast("macb_taskq", M_WAITOK,
+	    taskqueue_thread_enqueue, &sc->sc_tq);
+	if (sc->sc_tq == NULL) {
+		device_printf(sc->dev, "could not create taskqueue\n");
+		goto out;
+	}
+
+	ether_ifattach(ifp, eaddr);
+
+	/*
+	 * Activate the interrupt.
+	 */
+	err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET | INTR_MPSAFE,
+	    NULL, macb_intr, sc, &sc->intrhand);
+	if (err) {
+		device_printf(dev, "could not establish interrupt handler.\n");
+		ether_ifdetach(ifp);
+		goto out;
+	}
+
+	taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, "%s taskq",
+	    device_get_nameunit(sc->dev));
+
+	sc->macb_cdata.rxhead = 0;
+	sc->macb_cdata.rxtail = 0;
+
+	phy_write(sc, 0, 0, 0x3300); //force autoneg
+
+	return (0);
+out:
+
+	return (err);
+}
+
+static int
+macb_detach(device_t dev)
+{
+	struct macb_softc *sc;
+
+	sc = device_get_softc(dev);
+	ether_ifdetach(sc->ifp);
+	MACB_LOCK(sc);
+	macbstop(sc);
+	MACB_UNLOCK(sc);
+	callout_drain(&sc->tick_ch);
+	bus_teardown_intr(dev, sc->irq_res, sc->intrhand);
+	taskqueue_drain(sc->sc_tq, &sc->sc_intr_task);
+	taskqueue_free(sc->sc_tq);
+	macb_deactivate(dev);
+	bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq_res);
+	bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->mem_res);
+	MACB_LOCK_DESTROY(sc);
+
+	return (0);
+}
+
+/*PHY related functions*/
+static inline int
+phy_read(struct macb_softc *sc, int phy, int reg)
+{
+	int val;
+
+	write_4(sc, EMAC_MAN, EMAC_MAN_REG_RD(phy, reg));
+	while ((read_4(sc, EMAC_SR) & EMAC_SR_IDLE) == 0)
+		continue;
+	val = read_4(sc, EMAC_MAN) & EMAC_MAN_VALUE_MASK;
+
+	return (val);
+}
+
+static inline int
+phy_write(struct macb_softc *sc, int phy, int reg, int data)
+{
+
+	write_4(sc, EMAC_MAN, EMAC_MAN_REG_WR(phy, reg, data));
+	while ((read_4(sc, EMAC_SR) & EMAC_SR_IDLE) == 0)
+		continue;
+
+	return (0);
+}
+
+/*
+ * MII bus support routines.
+ */
+static int
+macb_miibus_readreg(device_t dev, int phy, int reg)
+{
+	struct macb_softc *sc;
+	sc = device_get_softc(dev);
+	return (phy_read(sc, phy, reg));
+}
+
+static int
+macb_miibus_writereg(device_t dev, int phy, int reg, int data)
+{
+	struct macb_softc *sc;
+	sc = device_get_softc(dev);
+	return (phy_write(sc, phy, reg, data));
+}
+
+static void
+macb_child_detached(device_t dev, device_t child)
+{
+	struct macb_softc *sc;
+	sc = device_get_softc(dev);
+
+}
+
+static void
+macb_miibus_statchg(device_t dev)
+{
+	struct macb_softc *sc;
+	struct mii_data *mii;
+	int config;
+
+	sc = device_get_softc(dev);
+
+	mii = device_get_softc(sc->miibus);
+
+	sc->flags &= ~MACB_FLAG_LINK;
+
+	config = read_4(sc, EMAC_NCFGR);
+
+	if ((mii->mii_media_status & IFM_AVALID) != 0) {
+		switch (IFM_SUBTYPE(mii->mii_media_active)) {
+		case IFM_10_T:
+			config &= ~(CFG_SPD);
+			sc->flags |= MACB_FLAG_LINK;
+			break;
+		case IFM_100_TX:
+			config |= CFG_SPD;
+			sc->flags |= MACB_FLAG_LINK;
+			break;
+		default:
+			break;
+		}
+	}
+
+	config |= CFG_FD;
+	write_4(sc, EMAC_NCFGR, config);
+}
+
+static device_method_t macb_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,	macb_probe),
+	DEVMETHOD(device_attach,	macb_attach),
+	DEVMETHOD(device_detach,	macb_detach),
+
+	/* Bus interface */
+	DEVMETHOD(bus_child_detached,	macb_child_detached),
+
+	/* MII interface */
+	DEVMETHOD(miibus_readreg,	macb_miibus_readreg),
+	DEVMETHOD(miibus_writereg,	macb_miibus_writereg),
+	DEVMETHOD(miibus_statchg,	macb_miibus_statchg),
+	{ 0, 0 }
+};
+
+static driver_t macb_driver = {
+	"macb",
+	macb_methods,
+	sizeof(struct macb_softc),
+};
+
+
+DRIVER_MODULE(macb, atmelarm, macb_driver, macb_devclass, 0, 0);
+DRIVER_MODULE(miibus, macb, miibus_driver, miibus_devclass, 0, 0);
+MODULE_DEPEND(macb, miibus, 1, 1, 1);
+MODULE_DEPEND(macb, ether, 1, 1, 1);


Property changes on: trunk/sys/arm/at91/if_macb.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/if_macbreg.h
===================================================================
--- trunk/sys/arm/at91/if_macbreg.h	                        (rev 0)
+++ trunk/sys/arm/at91/if_macbreg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,107 @@
+/* $MidnightBSD$ */
+/*
+ * $FreeBSD: stable/10/sys/arm/at91/if_macbreg.h 210040 2010-07-14 00:48:53Z cognet $
+ */
+
+#ifndef MACB_REG_H
+#define MACB_REG_H
+
+#define EMAC_NCR		0x00
+#define EMAC_NCFGR		0x04
+#define EMAC_TSR		0x14
+#define EMAC_RSR		0x20
+#define EMAC_ISR		0x24
+#define EMAC_IER		0x28
+#define EMAC_IDR		0x2C
+#define EMAC_IMR		0x30
+
+
+
+#define EMAC_RBQP		0x18
+#define EMAC_TBQP		0x1C
+
+#define EMAC_HRB		0x90
+#define EMAC_HRT		0x94
+
+#define EMAC_SA1B		0x98
+#define EMAC_SA1T		0x9C
+
+#define EMAC_USRIO		0xC0
+
+#define EMAC_MAN		0x34		/* EMAC PHY Maintenance Register */
+#define EMAC_SR		0x08		/* EMAC STatus Register */
+#define EMAC_SR_LINK	(1U << 0)	/* Reserved! */
+#define EMAC_SR_MDIO	(1U << 1)	/* MDIO pin status */
+#define EMAC_SR_IDLE	(1U << 2)	/* IDLE (PHY logic) */
+
+#define RX_ENABLE		(1 << 2)
+#define TX_ENABLE		(1 << 3)
+#define MPE_ENABLE		(1 << 4)
+
+
+/* EMAC_MAN */
+#define EMAC_MAN_BITS	0x40020000	/* HIGH and CODE bits */
+#define EMAC_MAN_READ	(2U << 28)
+#define EMAC_MAN_WRITE	(1U << 28)
+#define EMAC_MAN_PHYA_BIT 23
+#define EMAC_MAN_REGA_BIT 18
+#define EMAC_MAN_VALUE_MASK	0xffffU
+#define EMAC_MAN_REG_WR(phy, reg, val) \
+		(EMAC_MAN_BITS | EMAC_MAN_WRITE | ((phy) << EMAC_MAN_PHYA_BIT) | \
+		((reg) << EMAC_MAN_REGA_BIT) | ((val) & EMAC_MAN_VALUE_MASK))
+
+#define EMAC_MAN_REG_RD(phy, reg) \
+		(EMAC_MAN_BITS | EMAC_MAN_READ | ((phy) << EMAC_MAN_PHYA_BIT) | \
+		((reg) << EMAC_MAN_REGA_BIT))
+
+#define RCOMP_INTERRUPT		(1 << 1)
+#define RXUBR_INTERRUPT		(1 << 2)
+#define TUBR_INTERRUPT		(1 << 3)
+#define TUND_INTERRUPT		(1 << 4)
+#define RLE_INTERRUPT		(1 << 5)
+#define TXERR_INTERRUPT		(1 << 6)
+#define ROVR_INTERRUPT		(1 << 10)
+#define HRESP_INTERRUPT		(1 << 11)
+#define TCOMP_INTERRUPT		(1 << 7)
+
+#define CLEAR_STAT		(1 << 5)
+
+#define TRANSMIT_START		(1 << 9)
+#define TRANSMIT_STOP		(1 << 10)
+
+/*Transmit status register flags*/
+#define	TSR_UND			(1 << 6)
+#define	TSR_COMP		(1 << 5)
+#define	TSR_BEX			(1 << 4)
+#define	TSR_TGO			(1 << 3)
+#define	TSR_RLE			(1 << 2)
+#define	TSR_COL			(1 << 1)
+#define	TSR_UBR			(1 << 0)
+
+#define	CFG_SPD		(1 << 0)
+#define	CFG_FD		(1 << 1)
+#define	CFG_CAF		(1 << 4)
+#define	CFG_NBC		(1 << 5)
+#define	CFG_MTI		(1 << 6)
+#define	CFG_UNI		(1 << 7)
+#define	CFG_BIG		(1 << 8)
+
+#define	CFG_CLK_8		(0)
+#define	CFG_CLK_16		(1)
+#define	CFG_CLK_32		(2)
+#define	CFG_CLK_64		(3)
+
+#define	CFG_PAE		(1 << 13)
+
+#define CFG_RBOF_0	(0 << 14)
+#define CFG_RBOF_1	(1 << 14)
+#define CFG_RBOF_2	(2 << 14)
+#define CFG_RBOF_3	(3 << 14)
+
+#define	CFG_DRFCS	(1 << 17)
+
+#define USRIO_CLOCK	(1 << 1)
+
+
+
+#endif


Property changes on: trunk/sys/arm/at91/if_macbreg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/if_macbvar.h
===================================================================
--- trunk/sys/arm/at91/if_macbvar.h	                        (rev 0)
+++ trunk/sys/arm/at91/if_macbvar.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,139 @@
+/* $MidnightBSD$ */
+/*
+ * $FreeBSD: stable/10/sys/arm/at91/if_macbvar.h 261455 2014-02-04 03:36:42Z eadler $
+ */
+
+#ifndef	_IF_MACB_H
+#define	_IF_MACB_H
+
+#define	MACB_MAX_TX_BUFFERS	64
+#define	MACB_MAX_RX_BUFFERS	256
+
+#define MAX_FRAGMENT		20
+#define DATA_SIZE		128
+
+#define	MACB_DESC_INC(x, y)	((x) = ((x) + 1) % (y))
+
+#define MACB_TIMEOUT		1000
+
+struct eth_tx_desc {
+	uint32_t		addr;
+	uint32_t		flags;
+#define TD_OWN		(1U << 31)
+#define TD_LAST		(1 << 15)
+#define	TD_WRAP_MASK		(1 << 30)
+};
+
+struct eth_rx_desc {
+	uint32_t		addr;
+#define	RD_LEN_MASK		0x7ff
+#define	RD_WRAP_MASK		0x00000002
+#define	RD_OWN			0x00000001
+
+	uint32_t		flags;
+#define RD_BROADCAST		(1U << 31)
+#define RD_MULTICAST		(1 << 30)
+#define RD_UNICAST		(1 << 29)
+#define RD_EXTERNAL		(1 << 28)
+#define RD_TYPE_ID		(1 << 22)
+#define RD_PRIORITY		(1 << 20)
+#define RD_VLAN		(1 << 21)
+#define RD_CONCAT		(1 << 16)
+#define RD_EOF		(1 << 15)
+#define RD_SOF		(1 << 14)
+#define RD_OFFSET_MASK		(1 << 13)|(1 << 12)
+#define RD_LENGTH_MASK		(0x00000FFF)
+
+};
+
+
+struct rx_desc_info {
+	struct mbuf *buff;
+	bus_dmamap_t dmamap;
+};
+
+struct tx_desc_info {
+	struct mbuf *buff;
+	bus_dmamap_t dmamap;
+};
+
+
+struct macb_chain_data{	
+	struct mbuf		*rxhead;
+	struct mbuf		*rxtail;
+};
+
+struct macb_softc
+{
+	struct ifnet *ifp;		/* ifnet pointer */
+	struct mtx sc_mtx;		/* global mutex */
+
+	bus_dma_tag_t	sc_parent_tag;	/* parent bus DMA tag */
+
+	device_t dev;			/* Myself */
+	device_t miibus;		/* My child miibus */
+	void *intrhand;			/* Interrupt handle */
+	void *intrhand_qf;		/* queue full */
+	void *intrhand_tx;		/* tx complete */
+	void *intrhand_status;		/* error status */
+
+	struct resource *irq_res;	/* transmit */
+	struct resource *irq_res_rec;	/* receive */
+	struct resource *irq_res_qf;	/* queue full */
+	struct resource *irq_res_status; /* status */
+
+	struct resource	*mem_res;	/* Memory resource */
+
+	struct callout tick_ch;		/* Tick callout */
+
+	struct taskqueue *sc_tq;
+	struct task	sc_intr_task;
+	struct task	sc_tx_task;
+	struct task	sc_link_task;
+
+	bus_dmamap_t	dmamap_ring_tx;
+	bus_dmamap_t	dmamap_ring_rx;
+
+	/*dma tag for ring*/
+	bus_dma_tag_t	dmatag_ring_tx;
+	bus_dma_tag_t	dmatag_ring_rx;
+
+	/*dma tag for data*/
+	bus_dma_tag_t	dmatag_data_tx;
+	bus_dma_tag_t	dmatag_data_rx;
+
+	/*the ring*/
+	struct eth_tx_desc	*desc_tx;
+	struct eth_rx_desc	*desc_rx;
+
+	/*ring physical address*/
+	bus_addr_t	ring_paddr_tx;
+	bus_addr_t	ring_paddr_rx;
+
+	/*index of last received descriptor*/
+	int		rx_cons;
+	struct rx_desc_info rx_desc[MACB_MAX_RX_BUFFERS];
+
+	/* tx producer index */
+	uint32_t tx_prod;
+	/* tx consumer index */
+	uint32_t tx_cons;
+	int	tx_cnt;
+
+	struct tx_desc_info tx_desc[MACB_MAX_TX_BUFFERS];
+
+	int macb_watchdog_timer;
+
+#define	MACB_FLAG_LINK		0x0001
+
+	int flags;
+	int if_flags;
+	struct at91_pmc_clock *clk;
+
+	struct macb_chain_data	macb_cdata;
+	int clock;
+};
+
+
+
+#endif


Property changes on: trunk/sys/arm/at91/if_macbvar.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/std.at91
===================================================================
--- trunk/sys/arm/at91/std.at91	                        (rev 0)
+++ trunk/sys/arm/at91/std.at91	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,11 @@
+# $FreeBSD: stable/10/sys/arm/at91/std.at91 239362 2012-08-18 05:48:19Z andrew $
+
+files		"../at91/files.at91"
+cpu		CPU_ARM9
+machine 	arm
+makeoptions	CONF_CFLAGS=-mcpu=arm9
+options 	PHYSADDR=0x20000000
+options		NO_EVENTTIMERS
+
+# For now, just do the AT91RM9200
+device		at91rm9200


Property changes on: trunk/sys/arm/at91/std.at91
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/at91/std.at91sam9
===================================================================
--- trunk/sys/arm/at91/std.at91sam9	                        (rev 0)
+++ trunk/sys/arm/at91/std.at91sam9	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,11 @@
+# $FreeBSD: stable/10/sys/arm/at91/std.at91sam9 239362 2012-08-18 05:48:19Z andrew $
+
+files		"../at91/files.at91"
+cpu		CPU_ARM9
+machine 	arm
+makeoptions	CONF_CFLAGS=-mcpu=arm9
+options 	PHYSADDR=0x20000000
+options		NO_EVENTTIMERS
+
+# bring in the sam specific timers and such
+device		at91sam9


Property changes on: trunk/sys/arm/at91/std.at91sam9
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/at91/std.at91sam9g45
===================================================================
--- trunk/sys/arm/at91/std.at91sam9g45	                        (rev 0)
+++ trunk/sys/arm/at91/std.at91sam9g45	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,16 @@
+# $FreeBSD: stable/10/sys/arm/at91/std.at91sam9g45 239362 2012-08-18 05:48:19Z andrew $
+#
+# Unlike other Atmel SoCs, which have their SDRAM at CS1, the
+# at91sam9g45 family has it on CS6, so PHYSADDR must be adjusted
+# accordingly.  The at91sam9g45, at91sam9g46, at91sam9m10 and at91sam9m11
+# SoCs are members of this family.
+
+files		"../at91/files.at91"
+cpu		CPU_ARM9
+machine 	arm
+makeoptions	CONF_CFLAGS=-mcpu=arm9
+options 	PHYSADDR=0x70000000
+options		NO_EVENTTIMERS
+
+# bring in the sam specific timers and such
+device		at91sam9


Property changes on: trunk/sys/arm/at91/std.at91sam9g45
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/at91/std.atmel
===================================================================
--- trunk/sys/arm/at91/std.atmel	                        (rev 0)
+++ trunk/sys/arm/at91/std.atmel	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,14 @@
+# $FreeBSD: stable/10/sys/arm/at91/std.atmel 274268 2014-11-08 03:42:19Z ian $
+
+include 	"../at91/std.at91sam9"
+
+# Supported SoCs for the at91 platform
+device		at91rm9200
+device		at91sam9260
+device		at91sam9g20
+device		at91sam9g45
+device		at91sam9x5
+
+# bring in the sam specific timers and such
+device		at91sam9
+


Property changes on: trunk/sys/arm/at91/std.atmel
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/at91/std.bwct
===================================================================
--- trunk/sys/arm/at91/std.bwct	                        (rev 0)
+++ trunk/sys/arm/at91/std.bwct	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,9 @@
+#$FreeBSD: stable/10/sys/arm/at91/std.bwct 266110 2014-05-15 02:41:23Z ian $
+include "../at91/std.at91"
+
+makeoptions	KERNPHYSADDR=0x20000000
+options		KERNPHYSADDR=0x20000000	
+makeoptions	KERNVIRTADDR=0xc0000000
+options		KERNVIRTADDR=0xc0000000
+
+device		at91_board_bwct


Property changes on: trunk/sys/arm/at91/std.bwct
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/at91/std.eb9200
===================================================================
--- trunk/sys/arm/at91/std.eb9200	                        (rev 0)
+++ trunk/sys/arm/at91/std.eb9200	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,9 @@
+#$FreeBSD: stable/10/sys/arm/at91/std.eb9200 266110 2014-05-15 02:41:23Z ian $
+include "../at91/std.at91"
+
+makeoptions	KERNPHYSADDR=0x20000000
+options		KERNPHYSADDR=0x20000000	
+makeoptions	KERNVIRTADDR=0xc0000000
+options		KERNVIRTADDR=0xc0000000
+
+device		at91_board_eb9200


Property changes on: trunk/sys/arm/at91/std.eb9200
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/at91/std.ethernut5
===================================================================
--- trunk/sys/arm/at91/std.ethernut5	                        (rev 0)
+++ trunk/sys/arm/at91/std.ethernut5	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,10 @@
+# $FreeBSD: stable/10/sys/arm/at91/std.ethernut5 266110 2014-05-15 02:41:23Z ian $
+include "../at91/std.at91sam9"
+
+makeoptions	KERNPHYSADDR=0x20000000
+makeoptions	KERNVIRTADDR=0xc0000000
+options 	KERNPHYSADDR=0x20000000
+options 	KERNVIRTADDR=0xc0000000
+
+device		at91_board_ethernut5
+device		at91sam9260


Property changes on: trunk/sys/arm/at91/std.ethernut5
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/at91/std.hl200
===================================================================
--- trunk/sys/arm/at91/std.hl200	                        (rev 0)
+++ trunk/sys/arm/at91/std.hl200	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,9 @@
+#$FreeBSD: stable/10/sys/arm/at91/std.hl200 266110 2014-05-15 02:41:23Z ian $
+include "../at91/std.at91"
+
+makeoptions	KERNPHYSADDR=0x20100000
+options		KERNPHYSADDR=0x20100000	
+makeoptions	KERNVIRTADDR=0xc0100000
+options		KERNVIRTADDR=0xc0100000
+
+device		at91_board_hl200


Property changes on: trunk/sys/arm/at91/std.hl200
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/at91/std.hl201
===================================================================
--- trunk/sys/arm/at91/std.hl201	                        (rev 0)
+++ trunk/sys/arm/at91/std.hl201	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,10 @@
+#$FreeBSD: stable/10/sys/arm/at91/std.hl201 266110 2014-05-15 02:41:23Z ian $
+include "../at91/std.at91sam9"
+
+makeoptions	KERNPHYSADDR=0x20000000
+makeoptions	KERNVIRTADDR=0xc0000000
+options		KERNPHYSADDR=0x20000000	
+options		KERNVIRTADDR=0xc0000000
+
+device		at91_board_hl201
+device		at91sam9g20


Property changes on: trunk/sys/arm/at91/std.hl201
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/at91/std.kb920x
===================================================================
--- trunk/sys/arm/at91/std.kb920x	                        (rev 0)
+++ trunk/sys/arm/at91/std.kb920x	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,9 @@
+#$FreeBSD: stable/10/sys/arm/at91/std.kb920x 266110 2014-05-15 02:41:23Z ian $
+include "../at91/std.at91"
+
+makeoptions	KERNPHYSADDR=0x20000000
+options		KERNPHYSADDR=0x20000000	
+makeoptions	KERNVIRTADDR=0xc0000000
+options		KERNVIRTADDR=0xc0000000
+
+device		at91_board_kb920x


Property changes on: trunk/sys/arm/at91/std.kb920x
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/at91/std.qila9g20
===================================================================
--- trunk/sys/arm/at91/std.qila9g20	                        (rev 0)
+++ trunk/sys/arm/at91/std.qila9g20	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,10 @@
+#$FreeBSD: stable/10/sys/arm/at91/std.qila9g20 266110 2014-05-15 02:41:23Z ian $
+include "../at91/std.at91sam9"
+
+makeoptions	KERNPHYSADDR=0x20000000
+makeoptions	KERNVIRTADDR=0xc0000000
+options		KERNPHYSADDR=0x20000000	
+options		KERNVIRTADDR=0xc0000000
+
+device		at91_board_qila9g20
+device		at91sam9g20


Property changes on: trunk/sys/arm/at91/std.qila9g20
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/at91/std.sam9260ek
===================================================================
--- trunk/sys/arm/at91/std.sam9260ek	                        (rev 0)
+++ trunk/sys/arm/at91/std.sam9260ek	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,10 @@
+# $FreeBSD: stable/10/sys/arm/at91/std.sam9260ek 266110 2014-05-15 02:41:23Z ian $
+include "../at91/std.at91sam9"
+
+makeoptions	KERNPHYSADDR=0x20000000
+makeoptions	KERNVIRTADDR=0xc0000000
+options 	KERNPHYSADDR=0x20000000
+options 	KERNVIRTADDR=0xc0000000
+
+device		at91_board_sam9260ek
+device		at91sam9260


Property changes on: trunk/sys/arm/at91/std.sam9260ek
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/at91/std.sam9g20ek
===================================================================
--- trunk/sys/arm/at91/std.sam9g20ek	                        (rev 0)
+++ trunk/sys/arm/at91/std.sam9g20ek	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,10 @@
+#$FreeBSD: stable/10/sys/arm/at91/std.sam9g20ek 266110 2014-05-15 02:41:23Z ian $
+include "../at91/std.at91sam9"
+
+makeoptions	KERNPHYSADDR=0x20000000
+makeoptions	KERNVIRTADDR=0xc0000000
+options		KERNPHYSADDR=0x20000000	
+options		KERNVIRTADDR=0xc0000000
+
+device		at91_board_sam9g20ek
+device		at91sam9g20


Property changes on: trunk/sys/arm/at91/std.sam9g20ek
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/at91/std.sam9x25ek
===================================================================
--- trunk/sys/arm/at91/std.sam9x25ek	                        (rev 0)
+++ trunk/sys/arm/at91/std.sam9x25ek	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,10 @@
+#$FreeBSD: stable/10/sys/arm/at91/std.sam9x25ek 266110 2014-05-15 02:41:23Z ian $
+include "../at91/std.at91sam9"
+
+makeoptions	KERNPHYSADDR=0x20000000
+makeoptions	KERNVIRTADDR=0xc0000000
+options		KERNPHYSADDR=0x20000000	
+options		KERNVIRTADDR=0xc0000000
+
+device		at91_board_sam9x25ek
+device		at91sam9x5


Property changes on: trunk/sys/arm/at91/std.sam9x25ek
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/at91/std.sn9g45
===================================================================
--- trunk/sys/arm/at91/std.sn9g45	                        (rev 0)
+++ trunk/sys/arm/at91/std.sn9g45	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,11 @@
+#$FreeBSD: stable/10/sys/arm/at91/std.sn9g45 266110 2014-05-15 02:41:23Z ian $
+include "../at91/std.at91sam9g45"
+
+makeoptions	KERNPHYSADDR=0x70008000
+options		KERNPHYSADDR=0x70008000	
+makeoptions	KERNVIRTADDR=0xc0008000
+options		KERNVIRTADDR=0xc0008000
+
+device		at91sam9g45
+device		at91_board_sn9g45
+


Property changes on: trunk/sys/arm/at91/std.sn9g45
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/at91/std.tsc4370
===================================================================
--- trunk/sys/arm/at91/std.tsc4370	                        (rev 0)
+++ trunk/sys/arm/at91/std.tsc4370	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,9 @@
+#$FreeBSD: stable/10/sys/arm/at91/std.tsc4370 266110 2014-05-15 02:41:23Z ian $
+include "../at91/std.at91"
+
+makeoptions	KERNPHYSADDR=0x20000000
+makeoptions	KERNVIRTADDR=0xc0000000
+options		KERNPHYSADDR=0x20000000	
+options		KERNVIRTADDR=0xc0000000
+
+device		at91_board_tsc4370


Property changes on: trunk/sys/arm/at91/std.tsc4370
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/at91/uart_bus_at91usart.c
===================================================================
--- trunk/sys/arm/at91/uart_bus_at91usart.c	                        (rev 0)
+++ trunk/sys/arm/at91/uart_bus_at91usart.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,112 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2005 Olivier Houchard.  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 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 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_uart.h"
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/at91/uart_bus_at91usart.c 283327 2015-05-23 20:54:25Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
+#include <machine/resource.h>
+
+#include <dev/uart/uart.h>
+#include <dev/uart/uart_bus.h>
+#include <dev/uart/uart_cpu.h>
+
+#include <arm/at91/at91var.h>
+
+#include "uart_if.h"
+
+extern struct uart_class at91_usart_class;
+static int usart_at91_probe(device_t dev);
+
+static device_method_t usart_at91_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		usart_at91_probe),
+	DEVMETHOD(device_attach,	uart_bus_attach),
+	DEVMETHOD(device_detach,	uart_bus_detach),
+	{ 0, 0 }
+};
+
+static driver_t usart_at91_driver = {
+	uart_driver_name,
+	usart_at91_methods,
+	sizeof(struct uart_softc),
+};
+
+extern SLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs;
+
+static int
+usart_at91_probe(device_t dev)
+{
+	struct uart_softc *sc;
+
+	sc = device_get_softc(dev);
+	switch (device_get_unit(dev))
+	{
+	case 0:
+		device_set_desc(dev, "DBGU");
+		/*
+		 * Setting sc_sysdev makes this device a 'system device' and
+		 * indirectly makes it the system console.
+		 */
+		sc->sc_sysdev = SLIST_FIRST(&uart_sysdevs);
+		bcopy(&sc->sc_sysdev->bas, &sc->sc_bas, sizeof(sc->sc_bas));
+		break;
+	case 1:
+		device_set_desc(dev, "USART0");
+		break;
+	case 2:
+		device_set_desc(dev, "USART1");
+		break;
+	case 3:
+		device_set_desc(dev, "USART2");
+		break;
+	case 4:
+		device_set_desc(dev, "USART3");
+		break;
+	case 5:
+		device_set_desc(dev, "USART4");
+		break;
+	case 6:
+		device_set_desc(dev, "USART5");
+		break;
+	}
+	sc->sc_class = &at91_usart_class;
+	if (sc->sc_class->uc_rclk == 0)
+		sc->sc_class->uc_rclk = at91_master_clock;
+	return (uart_bus_probe(dev, 0, 0, 0, device_get_unit(dev)));
+}
+
+
+DRIVER_MODULE(uart, atmelarm, usart_at91_driver, uart_devclass, 0, 0);


Property changes on: trunk/sys/arm/at91/uart_bus_at91usart.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/uart_cpu_at91usart.c
===================================================================
--- trunk/sys/arm/at91/uart_cpu_at91usart.c	                        (rev 0)
+++ trunk/sys/arm/at91/uart_cpu_at91usart.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,92 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2003 Marcel Moolenaar
+ * Copyright (c) 2006 M. Warner Losh
+ * 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 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 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 "opt_uart.h"
+
+#ifndef FDT
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/at91/uart_cpu_at91usart.c 283327 2015-05-23 20:54:25Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/cons.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <machine/bus.h>
+
+#include <dev/uart/uart.h>
+#include <dev/uart/uart_bus.h>
+#include <dev/uart/uart_cpu.h>
+
+#include <arm/at91/at91var.h>
+
+bus_space_tag_t uart_bus_space_io;
+bus_space_tag_t uart_bus_space_mem;
+
+extern struct bus_space at91_bs_tag;
+extern struct uart_class at91_usart_class;
+
+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;
+
+	class = &at91_usart_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 = &at91_bs_tag;
+	/*
+	 * XXX: Not pretty, but will work because we map the needed addresses
+	 * early.  At least we probed this so that the console will work on
+         * all flavors of Atmel we can detect.
+	 */
+	di->bas.bsh = soc_info.dbgu_base;
+	di->baudrate = 115200;
+	di->bas.regshft = 0;
+	di->bas.rclk = 0;
+	di->databits = 8;
+	di->stopbits = 1;
+	di->parity = UART_PARITY_NONE;
+	uart_bus_space_io = &at91_bs_tag;
+	uart_bus_space_mem = NULL;
+	/* Check the environment for overrides */
+	uart_getenv(devtype, di, class);
+	return (0);
+}
+#endif


Property changes on: trunk/sys/arm/at91/uart_cpu_at91usart.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/at91/uart_dev_at91usart.c
===================================================================
--- trunk/sys/arm/at91/uart_dev_at91usart.c	                        (rev 0)
+++ trunk/sys/arm/at91/uart_dev_at91usart.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,881 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2005 M. Warner Losh
+ * Copyright (c) 2005 Olivier Houchard
+ * Copyright (c) 2012 Ian Lepore
+ * 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 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 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: stable/10/sys/arm/at91/uart_dev_at91usart.c 283327 2015-05-23 20:54:25Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/cons.h>
+#include <sys/tty.h>
+#include <machine/bus.h>
+
+#include <dev/uart/uart.h>
+#include <dev/uart/uart_cpu.h>
+#ifdef FDT
+#include <dev/uart/uart_cpu_fdt.h>
+#endif
+#include <dev/uart/uart_bus.h>
+#include <arm/at91/at91_usartreg.h>
+#include <arm/at91/at91_pdcreg.h>
+#include <arm/at91/at91_piovar.h>
+#include <arm/at91/at91_pioreg.h>
+#include <arm/at91/at91rm92reg.h>
+#include <arm/at91/at91var.h>
+
+#include "uart_if.h"
+
+#define	DEFAULT_RCLK			at91_master_clock
+#define	USART_DEFAULT_FIFO_BYTES	128
+
+#define	USART_DCE_CHANGE_BITS	(USART_CSR_CTSIC | USART_CSR_DCDIC | \
+				 USART_CSR_DSRIC | USART_CSR_RIIC)
+
+/*
+ * High-level UART interface.
+ */
+struct at91_usart_rx {
+	bus_addr_t	pa;
+	uint8_t		*buffer;
+	bus_dmamap_t	map;
+};
+
+struct at91_usart_softc {
+	struct uart_softc base;
+	bus_dma_tag_t tx_tag;
+	bus_dmamap_t tx_map;
+	uint32_t flags;
+#define	HAS_TIMEOUT		0x1
+#define	USE_RTS0_WORKAROUND	0x2
+	bus_dma_tag_t rx_tag;
+	struct at91_usart_rx ping_pong[2];
+	struct at91_usart_rx *ping;
+	struct at91_usart_rx *pong;
+};
+
+#define	RD4(bas, reg)		\
+	bus_space_read_4((bas)->bst, (bas)->bsh, uart_regofs(bas, reg))
+#define	WR4(bas, reg, value)	\
+	bus_space_write_4((bas)->bst, (bas)->bsh, uart_regofs(bas, reg), value)
+
+#define	SIGCHG(c, i, s, d)				\
+	do {						\
+		if (c) {				\
+			i |= (i & s) ? s : s | d;	\
+		} else {				\
+			i = (i & s) ? (i & ~s) | d : i;	\
+		}					\
+	} while (0);
+
+#define BAUD2DIVISOR(b) \
+	((((DEFAULT_RCLK * 10) / ((b) * 16)) + 5) / 10)
+
+/*
+ * Low-level UART interface.
+ */
+static int at91_usart_probe(struct uart_bas *bas);
+static void at91_usart_init(struct uart_bas *bas, int, int, int, int);
+static void at91_usart_term(struct uart_bas *bas);
+static void at91_usart_putc(struct uart_bas *bas, int);
+static int at91_usart_rxready(struct uart_bas *bas);
+static int at91_usart_getc(struct uart_bas *bas, struct mtx *hwmtx);
+
+extern SLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs;
+
+static int
+at91_usart_param(struct uart_bas *bas, int baudrate, int databits,
+    int stopbits, int parity)
+{
+	uint32_t mr;
+
+	/*
+	 * Assume 3-wire RS-232 configuration.
+	 * XXX Not sure how uart will present the other modes to us, so
+	 * XXX they are unimplemented.  maybe ioctl?
+	 */
+	mr = USART_MR_MODE_NORMAL;
+	mr |= USART_MR_USCLKS_MCK;	/* Assume MCK */
+
+	/*
+	 * Or in the databits requested
+	 */
+	if (databits < 9)
+		mr &= ~USART_MR_MODE9;
+	switch (databits) {
+	case 5:
+		mr |= USART_MR_CHRL_5BITS;
+		break;
+	case 6:
+		mr |= USART_MR_CHRL_6BITS;
+		break;
+	case 7:
+		mr |= USART_MR_CHRL_7BITS;
+		break;
+	case 8:
+		mr |= USART_MR_CHRL_8BITS;
+		break;
+	case 9:
+		mr |= USART_MR_CHRL_8BITS | USART_MR_MODE9;
+		break;
+	default:
+		return (EINVAL);
+	}
+
+	/*
+	 * Or in the parity
+	 */
+	switch (parity) {
+	case UART_PARITY_NONE:
+		mr |= USART_MR_PAR_NONE;
+		break;
+	case UART_PARITY_ODD:
+		mr |= USART_MR_PAR_ODD;
+		break;
+	case UART_PARITY_EVEN:
+		mr |= USART_MR_PAR_EVEN;
+		break;
+	case UART_PARITY_MARK:
+		mr |= USART_MR_PAR_MARK;
+		break;
+	case UART_PARITY_SPACE:
+		mr |= USART_MR_PAR_SPACE;
+		break;
+	default:
+		return (EINVAL);
+	}
+
+	/*
+	 * Or in the stop bits.  Note: The hardware supports 1.5 stop
+	 * bits in async mode, but there's no way to specify that
+	 * AFAICT.  Instead, rely on the convention documented at
+	 * http://www.lammertbies.nl/comm/info/RS-232_specs.html which
+	 * states that 1.5 stop bits are used for 5 bit bytes and
+	 * 2 stop bits only for longer bytes.
+	 */
+	if (stopbits == 1)
+		mr |= USART_MR_NBSTOP_1;
+	else if (databits > 5)
+		mr |= USART_MR_NBSTOP_2;
+	else
+		mr |= USART_MR_NBSTOP_1_5;
+
+	/*
+	 * We want normal plumbing mode too, none of this fancy
+	 * loopback or echo mode.
+	 */
+	mr |= USART_MR_CHMODE_NORMAL;
+
+	mr &= ~USART_MR_MSBF;	/* lsb first */
+	mr &= ~USART_MR_CKLO_SCK;	/* Don't drive SCK */
+
+	WR4(bas, USART_MR, mr);
+
+	/*
+	 * Set the baud rate (only if we know our master clock rate)
+	 */
+	if (DEFAULT_RCLK != 0)
+		WR4(bas, USART_BRGR, BAUD2DIVISOR(baudrate));
+
+	/*
+	 * Set the receive timeout based on the baud rate.  The idea is to
+	 * compromise between being responsive on an interactive connection and
+	 * giving a bulk data sender a bit of time to queue up a new buffer
+	 * without mistaking it for a stopping point in the transmission.  For
+	 * 19.2kbps and below, use 20 * bit time (2 characters).  For faster
+	 * connections use 500 microseconds worth of bits.
+	 */
+	if (baudrate <= 19200)
+		WR4(bas, USART_RTOR, 20);
+	else 
+		WR4(bas, USART_RTOR, baudrate / 2000);
+	WR4(bas, USART_CR, USART_CR_STTTO);
+
+	/* XXX Need to take possible synchronous mode into account */
+	return (0);
+}
+
+static struct uart_ops at91_usart_ops = {
+	.probe = at91_usart_probe,
+	.init = at91_usart_init,
+	.term = at91_usart_term,
+	.putc = at91_usart_putc,
+	.rxready = at91_usart_rxready,
+	.getc = at91_usart_getc,
+};
+
+#ifdef EARLY_PRINTF
+/*
+ * Early printf support. This assumes that we have the SoC "system" devices
+ * mapped into AT91_BASE. To use this before we adjust the boostrap tables,
+ * you'll need to define SOCDEV_VA to be 0xdc000000 and SOCDEV_PA to be
+ * 0xfc000000 in your config file where you define EARLY_PRINTF
+ */
+volatile uint32_t *at91_dbgu = (volatile uint32_t *)(AT91_BASE + AT91_DBGU0);
+
+static void
+eputc(int c)
+{
+
+	while (!(at91_dbgu[USART_CSR / 4] & USART_CSR_TXRDY))
+		continue;
+	at91_dbgu[USART_THR / 4] = c;
+}
+
+early_putc_t * early_putc = eputc;
+#endif
+
+static int
+at91_usart_probe(struct uart_bas *bas)
+{
+
+	/* We know that this is always here */
+	return (0);
+}
+
+/*
+ * Initialize this device for use as a console.
+ */
+static void
+at91_usart_init(struct uart_bas *bas, int baudrate, int databits, int stopbits,
+    int parity)
+{
+
+#ifdef EARLY_PRINTF
+	if (early_putc != NULL) {
+		printf("Early printf yielding control to the real console.\n");
+		early_putc = NULL;
+	}
+#endif
+
+	/*
+	 * This routine is called multiple times, sometimes right after writing
+	 * some output, and the last byte is still shifting out.  If that's the
+	 * case delay briefly before resetting, but don't loop on TXRDY because
+	 * we don't want to hang here forever if the hardware is in a bad state.
+	 */
+	if (!(RD4(bas, USART_CSR) & USART_CSR_TXRDY))
+		DELAY(10000);
+
+	at91_usart_param(bas, baudrate, databits, stopbits, parity);
+
+	/* Reset the rx and tx buffers and turn on rx and tx */
+	WR4(bas, USART_CR, USART_CR_RSTSTA | USART_CR_RSTRX | USART_CR_RSTTX);
+	WR4(bas, USART_CR, USART_CR_RXEN | USART_CR_TXEN);
+	WR4(bas, USART_IDR, 0xffffffff);
+}
+
+/*
+ * Free resources now that we're no longer the console.  This appears to
+ * be never called, and I'm unsure quite what to do if I am called.
+ */
+static void
+at91_usart_term(struct uart_bas *bas)
+{
+
+	/* XXX */
+}
+
+/*
+ * Put a character of console output (so we do it here polling rather than
+ * interrupt driven).
+ */
+static void
+at91_usart_putc(struct uart_bas *bas, int c)
+{
+
+	while (!(RD4(bas, USART_CSR) & USART_CSR_TXRDY))
+		continue;
+	WR4(bas, USART_THR, c);
+}
+
+/*
+ * Check for a character available.
+ */
+static int
+at91_usart_rxready(struct uart_bas *bas)
+{
+
+	return ((RD4(bas, USART_CSR) & USART_CSR_RXRDY) != 0 ? 1 : 0);
+}
+
+/*
+ * Block waiting for a character.
+ */
+static int
+at91_usart_getc(struct uart_bas *bas, struct mtx *hwmtx)
+{
+	int c;
+
+	uart_lock(hwmtx);
+	while (!(RD4(bas, USART_CSR) & USART_CSR_RXRDY)) {
+		uart_unlock(hwmtx);
+		DELAY(4);
+		uart_lock(hwmtx);
+	}
+	c = RD4(bas, USART_RHR) & 0xff;
+	uart_unlock(hwmtx);
+	return (c);
+}
+
+static int at91_usart_bus_probe(struct uart_softc *sc);
+static int at91_usart_bus_attach(struct uart_softc *sc);
+static int at91_usart_bus_flush(struct uart_softc *, int);
+static int at91_usart_bus_getsig(struct uart_softc *);
+static int at91_usart_bus_ioctl(struct uart_softc *, int, intptr_t);
+static int at91_usart_bus_ipend(struct uart_softc *);
+static int at91_usart_bus_param(struct uart_softc *, int, int, int, int);
+static int at91_usart_bus_receive(struct uart_softc *);
+static int at91_usart_bus_setsig(struct uart_softc *, int);
+static int at91_usart_bus_transmit(struct uart_softc *);
+static void at91_usart_bus_grab(struct uart_softc *);
+static void at91_usart_bus_ungrab(struct uart_softc *);
+
+static kobj_method_t at91_usart_methods[] = {
+	KOBJMETHOD(uart_probe,		at91_usart_bus_probe),
+	KOBJMETHOD(uart_attach,		at91_usart_bus_attach),
+	KOBJMETHOD(uart_flush,		at91_usart_bus_flush),
+	KOBJMETHOD(uart_getsig,		at91_usart_bus_getsig),
+	KOBJMETHOD(uart_ioctl,		at91_usart_bus_ioctl),
+	KOBJMETHOD(uart_ipend,		at91_usart_bus_ipend),
+	KOBJMETHOD(uart_param,		at91_usart_bus_param),
+	KOBJMETHOD(uart_receive,	at91_usart_bus_receive),
+	KOBJMETHOD(uart_setsig,		at91_usart_bus_setsig),
+	KOBJMETHOD(uart_transmit,	at91_usart_bus_transmit),
+	KOBJMETHOD(uart_grab,		at91_usart_bus_grab),
+	KOBJMETHOD(uart_ungrab,		at91_usart_bus_ungrab),
+
+	KOBJMETHOD_END
+};
+
+int
+at91_usart_bus_probe(struct uart_softc *sc)
+{
+	int value;
+
+	value = USART_DEFAULT_FIFO_BYTES;
+	resource_int_value(device_get_name(sc->sc_dev), 
+	    device_get_unit(sc->sc_dev), "fifo_bytes", &value);
+	value = roundup2(value, arm_dcache_align);
+	sc->sc_txfifosz = value;
+	sc->sc_rxfifosz = value;
+	sc->sc_hwiflow = 0;
+	return (0);
+}
+
+static void
+at91_getaddr(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
+{
+
+	if (error != 0)
+		return;
+	*(bus_addr_t *)arg = segs[0].ds_addr;
+}
+
+static int
+at91_usart_requires_rts0_workaround(struct uart_softc *sc)
+{
+	int value;
+	int unit;
+
+	unit = device_get_unit(sc->sc_dev);
+
+	/*
+	 * On the rm9200 chips, the PA21/RTS0 pin is not correctly wired to the
+	 * usart device interally (so-called 'erratum 39', but it's 41.14 in rev
+	 * I of the manual).  This prevents use of the hardware flow control
+	 * feature in the usart itself.  It also means that if we are to
+	 * implement RTS/CTS flow via the tty layer logic, we must use pin PA21
+	 * as a gpio and manually manipulate it in at91_usart_bus_setsig().  We
+	 * can only safely do so if we've been given permission via a hint,
+	 * otherwise we might manipulate a pin that's attached to who-knows-what
+	 * and Bad Things could happen.
+	 */
+	if (at91_is_rm92() && unit == 1) {
+		value = 0;
+		resource_int_value(device_get_name(sc->sc_dev), unit,
+		    "use_rts0_workaround", &value);
+		if (value != 0) {
+			at91_pio_use_gpio(AT91RM92_PIOA_BASE, AT91C_PIO_PA21);
+			at91_pio_gpio_output(AT91RM92_PIOA_BASE, 
+			    AT91C_PIO_PA21, 1);
+			at91_pio_use_periph_a(AT91RM92_PIOA_BASE, 
+			    AT91C_PIO_PA20, 0);
+			return (1);
+		}
+	}
+	return (0);
+}
+
+static int
+at91_usart_bus_attach(struct uart_softc *sc)
+{
+	int err;
+	int i;
+	uint32_t cr;
+	struct at91_usart_softc *atsc;
+
+	atsc = (struct at91_usart_softc *)sc;
+
+	if (at91_usart_requires_rts0_workaround(sc))
+		atsc->flags |= USE_RTS0_WORKAROUND;
+
+	/*
+	 * See if we have a TIMEOUT bit.  We disable all interrupts as
+	 * a side effect.  Boot loaders may have enabled them.  Since
+	 * a TIMEOUT interrupt can't happen without other setup, the
+	 * apparent race here can't actually happen.
+	 */
+	WR4(&sc->sc_bas, USART_IDR, 0xffffffff);
+	WR4(&sc->sc_bas, USART_IER, USART_CSR_TIMEOUT);
+	if (RD4(&sc->sc_bas, USART_IMR) & USART_CSR_TIMEOUT)
+		atsc->flags |= HAS_TIMEOUT;
+	WR4(&sc->sc_bas, USART_IDR, 0xffffffff);
+
+	/*
+	 * Allocate transmit DMA tag and map.  We allow a transmit buffer
+	 * to be any size, but it must map to a single contiguous physical
+	 * extent.
+	 */
+	err = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0,
+	    BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
+	    BUS_SPACE_MAXSIZE_32BIT, 1, BUS_SPACE_MAXSIZE_32BIT, 0, NULL,
+	    NULL, &atsc->tx_tag);
+	if (err != 0)
+		goto errout;
+	err = bus_dmamap_create(atsc->tx_tag, 0, &atsc->tx_map);
+	if (err != 0)
+		goto errout;
+
+	if (atsc->flags & HAS_TIMEOUT) {
+		/*
+		 * Allocate receive DMA tags, maps, and buffers.
+		 * The receive buffers should be aligned to arm_dcache_align,
+		 * otherwise partial cache line flushes on every receive
+		 * interrupt are pretty much guaranteed.
+		 */
+		err = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev),
+		    arm_dcache_align, 0, BUS_SPACE_MAXADDR_32BIT,
+		    BUS_SPACE_MAXADDR, NULL, NULL, sc->sc_rxfifosz, 1,
+		    sc->sc_rxfifosz, BUS_DMA_ALLOCNOW, NULL, NULL,
+		    &atsc->rx_tag);
+		if (err != 0)
+			goto errout;
+		for (i = 0; i < 2; i++) {
+			err = bus_dmamem_alloc(atsc->rx_tag,
+			    (void **)&atsc->ping_pong[i].buffer,
+			    BUS_DMA_NOWAIT, &atsc->ping_pong[i].map);
+			if (err != 0)
+				goto errout;
+			err = bus_dmamap_load(atsc->rx_tag,
+			    atsc->ping_pong[i].map,
+			    atsc->ping_pong[i].buffer, sc->sc_rxfifosz,
+			    at91_getaddr, &atsc->ping_pong[i].pa, 0);
+			if (err != 0)
+				goto errout;
+			bus_dmamap_sync(atsc->rx_tag, atsc->ping_pong[i].map,
+			    BUS_DMASYNC_PREREAD);
+		}
+		atsc->ping = &atsc->ping_pong[0];
+		atsc->pong = &atsc->ping_pong[1];
+	}
+
+	/* Turn on rx and tx */
+	cr = USART_CR_RSTSTA | USART_CR_RSTRX | USART_CR_RSTTX;
+	WR4(&sc->sc_bas, USART_CR, cr);
+	WR4(&sc->sc_bas, USART_CR, USART_CR_RXEN | USART_CR_TXEN);
+
+	/*
+	 * Setup the PDC to receive data.  We use the ping-pong buffers
+	 * so that we can more easily bounce between the two and so that
+	 * we get an interrupt 1/2 way through the software 'fifo' we have
+	 * to avoid overruns.
+	 */
+	if (atsc->flags & HAS_TIMEOUT) {
+		WR4(&sc->sc_bas, PDC_RPR, atsc->ping->pa);
+		WR4(&sc->sc_bas, PDC_RCR, sc->sc_rxfifosz);
+		WR4(&sc->sc_bas, PDC_RNPR, atsc->pong->pa);
+		WR4(&sc->sc_bas, PDC_RNCR, sc->sc_rxfifosz);
+		WR4(&sc->sc_bas, PDC_PTCR, PDC_PTCR_RXTEN);
+
+		/*
+		 * Set the receive timeout to be 1.5 character times
+		 * assuming 8N1.
+		 */
+		WR4(&sc->sc_bas, USART_RTOR, 15);
+		WR4(&sc->sc_bas, USART_CR, USART_CR_STTTO);
+		WR4(&sc->sc_bas, USART_IER, USART_CSR_TIMEOUT |
+		    USART_CSR_RXBUFF | USART_CSR_ENDRX);
+	} else {
+		WR4(&sc->sc_bas, USART_IER, USART_CSR_RXRDY);
+	}
+	WR4(&sc->sc_bas, USART_IER, USART_CSR_RXBRK | USART_DCE_CHANGE_BITS);
+
+	/* Prime sc->hwsig with the initial hw line states. */
+	at91_usart_bus_getsig(sc);
+
+errout:
+	return (err);
+}
+
+static int
+at91_usart_bus_transmit(struct uart_softc *sc)
+{
+	bus_addr_t addr;
+	struct at91_usart_softc *atsc;
+	int err;
+
+	err = 0;
+	atsc = (struct at91_usart_softc *)sc;
+	uart_lock(sc->sc_hwmtx);
+	if (bus_dmamap_load(atsc->tx_tag, atsc->tx_map, sc->sc_txbuf,
+	    sc->sc_txdatasz, at91_getaddr, &addr, 0) != 0) {
+		err = EAGAIN;
+		goto errout;
+	}
+	bus_dmamap_sync(atsc->tx_tag, atsc->tx_map, BUS_DMASYNC_PREWRITE);
+	sc->sc_txbusy = 1;
+	/*
+	 * Setup the PDC to transfer the data and interrupt us when it
+	 * is done.  We've already requested the interrupt.
+	 */
+	WR4(&sc->sc_bas, PDC_TPR, addr);
+	WR4(&sc->sc_bas, PDC_TCR, sc->sc_txdatasz);
+	WR4(&sc->sc_bas, PDC_PTCR, PDC_PTCR_TXTEN);
+	WR4(&sc->sc_bas, USART_IER, USART_CSR_ENDTX);
+errout:
+	uart_unlock(sc->sc_hwmtx);
+	return (err);
+}
+
+static int
+at91_usart_bus_setsig(struct uart_softc *sc, int sig)
+{
+	uint32_t new, old, cr;
+	struct at91_usart_softc *atsc;
+
+	atsc = (struct at91_usart_softc *)sc;
+
+	do {
+		old = sc->sc_hwsig;
+		new = old;
+		if (sig & SER_DDTR)
+			SIGCHG(sig & SER_DTR, new, SER_DTR, SER_DDTR);
+		if (sig & SER_DRTS)
+			SIGCHG(sig & SER_RTS, new, SER_RTS, SER_DRTS);
+	} while (!atomic_cmpset_32(&sc->sc_hwsig, old, new));
+
+	cr = 0;
+	if (new & SER_DTR)
+		cr |= USART_CR_DTREN;
+	else
+		cr |= USART_CR_DTRDIS;
+	if (new & SER_RTS)
+		cr |= USART_CR_RTSEN;
+	else
+		cr |= USART_CR_RTSDIS;
+
+	uart_lock(sc->sc_hwmtx);
+	WR4(&sc->sc_bas, USART_CR, cr);
+	if (atsc->flags & USE_RTS0_WORKAROUND) {
+		/* Signal is active-low. */
+		if (new & SER_RTS)
+			at91_pio_gpio_clear(AT91RM92_PIOA_BASE, AT91C_PIO_PA21);
+		else
+			at91_pio_gpio_set(AT91RM92_PIOA_BASE,AT91C_PIO_PA21);
+	}
+	uart_unlock(sc->sc_hwmtx);
+
+	return (0);
+}
+
+static int
+at91_usart_bus_receive(struct uart_softc *sc)
+{
+
+	return (0);
+}
+
+static int
+at91_usart_bus_param(struct uart_softc *sc, int baudrate, int databits,
+    int stopbits, int parity)
+{
+
+	return (at91_usart_param(&sc->sc_bas, baudrate, databits, stopbits,
+	    parity));
+}
+
+static __inline void
+at91_rx_put(struct uart_softc *sc, int key)
+{
+
+#if defined(KDB)
+	if (sc->sc_sysdev != NULL && sc->sc_sysdev->type == UART_DEV_CONSOLE)
+		kdb_alt_break(key, &sc->sc_altbrk);
+#endif
+	uart_rx_put(sc, key);
+}
+
+static int
+at91_usart_bus_ipend(struct uart_softc *sc)
+{
+	struct at91_usart_softc *atsc;
+	struct at91_usart_rx *p;
+	int i, ipend, len;
+	uint32_t csr;
+
+	ipend = 0;
+	atsc = (struct at91_usart_softc *)sc;
+	uart_lock(sc->sc_hwmtx);
+	csr = RD4(&sc->sc_bas, USART_CSR);
+
+	if (csr & USART_CSR_OVRE) {
+		WR4(&sc->sc_bas, USART_CR, USART_CR_RSTSTA);
+		ipend |= SER_INT_OVERRUN;
+	}
+
+	if (csr & USART_DCE_CHANGE_BITS)
+		ipend |= SER_INT_SIGCHG;
+
+	if (csr & USART_CSR_ENDTX) {
+		bus_dmamap_sync(atsc->tx_tag, atsc->tx_map,
+		    BUS_DMASYNC_POSTWRITE);
+		bus_dmamap_unload(atsc->tx_tag, atsc->tx_map);
+	}
+	if (csr & (USART_CSR_TXRDY | USART_CSR_ENDTX)) {
+		if (sc->sc_txbusy)
+			ipend |= SER_INT_TXIDLE;
+		WR4(&sc->sc_bas, USART_IDR, csr & (USART_CSR_TXRDY |
+		    USART_CSR_ENDTX));
+	}
+
+	/*
+	 * Due to the contraints of the DMA engine present in the
+	 * atmel chip, I can't just say I have a rx interrupt pending
+	 * and do all the work elsewhere.  I need to look at the CSR
+	 * bits right now and do things based on them to avoid races.
+	 */
+	if (atsc->flags & HAS_TIMEOUT) {
+		if (csr & USART_CSR_RXBUFF) {
+			/*
+			 * We have a buffer overflow.  Consume data from ping
+			 * and give it back to the hardware before worrying
+			 * about pong, to minimze data loss.  Insert an overrun
+			 * marker after the contents of the pong buffer.
+			 */
+			WR4(&sc->sc_bas, PDC_PTCR, PDC_PTCR_RXTDIS);
+			bus_dmamap_sync(atsc->rx_tag, atsc->ping->map,
+			    BUS_DMASYNC_POSTREAD);
+			for (i = 0; i < sc->sc_rxfifosz; i++)
+				at91_rx_put(sc, atsc->ping->buffer[i]);
+			bus_dmamap_sync(atsc->rx_tag, atsc->ping->map,
+			    BUS_DMASYNC_PREREAD);
+			WR4(&sc->sc_bas, PDC_RPR, atsc->ping->pa);
+			WR4(&sc->sc_bas, PDC_RCR, sc->sc_rxfifosz);
+			WR4(&sc->sc_bas, PDC_PTCR, PDC_PTCR_RXTEN);
+			bus_dmamap_sync(atsc->rx_tag, atsc->pong->map,
+			    BUS_DMASYNC_POSTREAD);
+			for (i = 0; i < sc->sc_rxfifosz; i++)
+				at91_rx_put(sc, atsc->pong->buffer[i]);
+			uart_rx_put(sc, UART_STAT_OVERRUN);
+			bus_dmamap_sync(atsc->rx_tag, atsc->pong->map,
+			    BUS_DMASYNC_PREREAD);
+			WR4(&sc->sc_bas, PDC_RNPR, atsc->pong->pa);
+			WR4(&sc->sc_bas, PDC_RNCR, sc->sc_rxfifosz);
+			ipend |= SER_INT_RXREADY;
+		} else if (csr & USART_CSR_ENDRX) {
+			/*
+			 * Consume data from ping of ping pong buffer, but leave
+			 * current pong in place, as it has become the new ping.
+			 * We need to copy data and setup the old ping as the
+			 * new pong when we're done.
+			 */
+			bus_dmamap_sync(atsc->rx_tag, atsc->ping->map,
+			    BUS_DMASYNC_POSTREAD);
+			for (i = 0; i < sc->sc_rxfifosz; i++)
+				at91_rx_put(sc, atsc->ping->buffer[i]);
+			p = atsc->ping;
+			atsc->ping = atsc->pong;
+			atsc->pong = p;
+			bus_dmamap_sync(atsc->rx_tag, atsc->pong->map,
+			    BUS_DMASYNC_PREREAD);
+			WR4(&sc->sc_bas, PDC_RNPR, atsc->pong->pa);
+			WR4(&sc->sc_bas, PDC_RNCR, sc->sc_rxfifosz);
+			ipend |= SER_INT_RXREADY;
+		} else if (csr & USART_CSR_TIMEOUT) {
+			/*
+			 * On a timeout, one of the following applies:
+			 * 1. Two empty buffers.  The last received byte exactly
+			 *    filled a buffer, causing an ENDTX that got
+			 *    processed earlier; no new bytes have arrived.
+			 * 2. Ping buffer contains some data and pong is empty.
+			 *    This should be the most common timeout condition.
+			 * 3. Ping buffer is full and pong is now being filled.
+			 *    This is exceedingly rare; it can happen only if
+			 *    the ping buffer is almost full when a timeout is
+			 *    signaled, and then dataflow resumes and the ping
+			 *    buffer filled up between the time we read the
+			 *    status register above and the point where the
+			 *    RXTDIS takes effect here.  Yes, it can happen.
+			 * Because dataflow can resume at any time following a
+			 * timeout (it may have already resumed before we get
+			 * here), it's important to minimize the time the PDC is
+			 * disabled -- just long enough to take the ping buffer
+			 * out of service (so we can consume it) and install the
+			 * pong buffer as the active one.  Note that in case 3
+			 * the hardware has already done the ping-pong swap.
+			 */
+			WR4(&sc->sc_bas, PDC_PTCR, PDC_PTCR_RXTDIS);
+			if (RD4(&sc->sc_bas, PDC_RNCR) == 0) {
+				len = sc->sc_rxfifosz;
+			} else {
+				len = sc->sc_rxfifosz - RD4(&sc->sc_bas, PDC_RCR);
+				WR4(&sc->sc_bas, PDC_RPR, atsc->pong->pa);
+				WR4(&sc->sc_bas, PDC_RCR, sc->sc_rxfifosz);
+				WR4(&sc->sc_bas, PDC_RNCR, 0);
+			}
+			WR4(&sc->sc_bas, USART_CR, USART_CR_STTTO);
+			WR4(&sc->sc_bas, PDC_PTCR, PDC_PTCR_RXTEN);
+			bus_dmamap_sync(atsc->rx_tag, atsc->ping->map,
+			    BUS_DMASYNC_POSTREAD);
+			for (i = 0; i < len; i++)
+				at91_rx_put(sc, atsc->ping->buffer[i]);
+			bus_dmamap_sync(atsc->rx_tag, atsc->ping->map,
+			    BUS_DMASYNC_PREREAD);
+			p = atsc->ping;
+			atsc->ping = atsc->pong;
+			atsc->pong = p;
+			WR4(&sc->sc_bas, PDC_RNPR, atsc->pong->pa);
+			WR4(&sc->sc_bas, PDC_RNCR, sc->sc_rxfifosz);
+			ipend |= SER_INT_RXREADY;
+		}
+	} else if (csr & USART_CSR_RXRDY) {
+		/*
+		 * We have another charater in a device that doesn't support
+		 * timeouts, so we do it one character at a time.
+		 */
+		at91_rx_put(sc, RD4(&sc->sc_bas, USART_RHR) & 0xff);
+		ipend |= SER_INT_RXREADY;
+	}
+
+	if (csr & USART_CSR_RXBRK) {
+		ipend |= SER_INT_BREAK;
+		WR4(&sc->sc_bas, USART_CR, USART_CR_RSTSTA);
+	}
+	uart_unlock(sc->sc_hwmtx);
+	return (ipend);
+}
+
+static int
+at91_usart_bus_flush(struct uart_softc *sc, int what)
+{
+
+	return (0);
+}
+
+static int
+at91_usart_bus_getsig(struct uart_softc *sc)
+{
+	uint32_t csr, new, old, sig;
+
+	/*
+	 * Note that the atmel channel status register DCE status bits reflect
+	 * the electrical state of the lines, not the logical state.  Since they
+	 * are logically active-low signals, we invert the tests here.
+	 */
+	do {
+		old = sc->sc_hwsig;
+		sig = old;
+		csr = RD4(&sc->sc_bas, USART_CSR);
+		SIGCHG(!(csr & USART_CSR_DSR), sig, SER_DSR, SER_DDSR);
+		SIGCHG(!(csr & USART_CSR_CTS), sig, SER_CTS, SER_DCTS);
+		SIGCHG(!(csr & USART_CSR_DCD), sig, SER_DCD, SER_DDCD);
+		SIGCHG(!(csr & USART_CSR_RI),  sig, SER_RI,  SER_DRI);
+		new = sig & ~SER_MASK_DELTA;
+	} while (!atomic_cmpset_32(&sc->sc_hwsig, old, new));
+
+	return (sig);
+}
+
+static int
+at91_usart_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
+{
+
+	switch (request) {
+	case UART_IOCTL_BREAK:
+	case UART_IOCTL_IFLOW:
+	case UART_IOCTL_OFLOW:
+		break;
+	case UART_IOCTL_BAUD:
+		/* only if we know our master clock rate */
+		if (DEFAULT_RCLK != 0)
+			WR4(&sc->sc_bas, USART_BRGR,
+			    BAUD2DIVISOR(*(int *)data));
+		return (0);
+	}
+	return (EINVAL);
+}
+
+
+static void
+at91_usart_bus_grab(struct uart_softc *sc)
+{
+
+	uart_lock(sc->sc_hwmtx);
+	WR4(&sc->sc_bas, USART_IDR, USART_CSR_RXRDY);
+	uart_unlock(sc->sc_hwmtx);
+}
+
+static void
+at91_usart_bus_ungrab(struct uart_softc *sc)
+{
+
+	uart_lock(sc->sc_hwmtx);
+	WR4(&sc->sc_bas, USART_IER, USART_CSR_RXRDY);
+	uart_unlock(sc->sc_hwmtx);
+}
+
+struct uart_class at91_usart_class = {
+	"at91_usart",
+	at91_usart_methods,
+	sizeof(struct at91_usart_softc),
+	.uc_ops = &at91_usart_ops,
+	.uc_range = 8
+};
+
+#ifdef FDT
+static struct ofw_compat_data compat_data[] = {
+	{"atmel,at91rm9200-usart",(uintptr_t)&at91_usart_class},
+	{"atmel,at91sam9260-usart",(uintptr_t)&at91_usart_class},
+	{NULL,			(uintptr_t)NULL},
+};
+UART_FDT_CLASS_AND_DEVICE(compat_data);
+#endif


Property changes on: trunk/sys/arm/at91/uart_dev_at91usart.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/broadcom/bcm2835/bcm2835_bsc.c
===================================================================
--- trunk/sys/arm/broadcom/bcm2835/bcm2835_bsc.c	                        (rev 0)
+++ trunk/sys/arm/broadcom/bcm2835/bcm2835_bsc.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,515 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2001 Tsubai Masanari.
+ * Copyright (c) 2012 Oleksandr Tymoshenko <gonzo at freebsd.org>
+ * Copyright (c) 2013 Luiz Otavio O Souza <loos at freebsd.org>
+ * 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: stable/10/sys/arm/broadcom/bcm2835/bcm2835_bsc.c 322724 2017-08-20 16:52:27Z marius $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/bus.h>
+#include <machine/resource.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
+#include <sys/sysctl.h>
+
+#include <dev/iicbus/iicbus.h>
+#include <dev/iicbus/iiconf.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <arm/broadcom/bcm2835/bcm2835_gpio.h>
+#include <arm/broadcom/bcm2835/bcm2835_bscreg.h>
+#include <arm/broadcom/bcm2835/bcm2835_bscvar.h>
+
+#include "iicbus_if.h"
+
+static struct ofw_compat_data compat_data[] = {
+	{"broadcom,bcm2835-bsc",	1},
+	{"brcm,bcm2708-i2c",		1},
+	{"brcm,bcm2835-i2c",		1},
+	{NULL,				0}
+};
+
+static void bcm_bsc_intr(void *);
+static int bcm_bsc_detach(device_t);
+
+static void
+bcm_bsc_modifyreg(struct bcm_bsc_softc *sc, uint32_t off, uint32_t mask,
+	uint32_t value)
+{
+	uint32_t reg;
+
+	mtx_assert(&sc->sc_mtx, MA_OWNED);        
+	reg = BCM_BSC_READ(sc, off);
+	reg &= ~mask;
+	reg |= value;
+	BCM_BSC_WRITE(sc, off, reg);
+}
+
+static int
+bcm_bsc_clock_proc(SYSCTL_HANDLER_ARGS)
+{
+	struct bcm_bsc_softc *sc;
+	uint32_t clk;
+
+	sc = (struct bcm_bsc_softc *)arg1;
+	BCM_BSC_LOCK(sc);
+	clk = BCM_BSC_READ(sc, BCM_BSC_CLOCK);
+	BCM_BSC_UNLOCK(sc);
+	clk &= 0xffff;
+	if (clk == 0)
+		clk = 32768;
+	clk = BCM_BSC_CORE_CLK / clk;
+
+	return (sysctl_handle_int(oidp, &clk, 0, req));
+}
+
+static int
+bcm_bsc_clkt_proc(SYSCTL_HANDLER_ARGS)
+{
+	struct bcm_bsc_softc *sc;
+	uint32_t clkt;
+	int error;
+
+	sc = (struct bcm_bsc_softc *)arg1;
+
+	BCM_BSC_LOCK(sc);
+	clkt = BCM_BSC_READ(sc, BCM_BSC_CLKT);
+	BCM_BSC_UNLOCK(sc);
+	clkt &= 0xffff;
+	error = sysctl_handle_int(oidp, &clkt, sizeof(clkt), req);
+	if (error != 0 || req->newptr == NULL)
+		return (error);
+
+	BCM_BSC_LOCK(sc);
+	BCM_BSC_WRITE(sc, BCM_BSC_CLKT, clkt & 0xffff);
+	BCM_BSC_UNLOCK(sc);
+
+	return (0);
+}
+
+static int
+bcm_bsc_fall_proc(SYSCTL_HANDLER_ARGS)
+{
+	struct bcm_bsc_softc *sc;
+	uint32_t clk, reg;
+	int error;
+
+	sc = (struct bcm_bsc_softc *)arg1;
+
+	BCM_BSC_LOCK(sc);
+	reg = BCM_BSC_READ(sc, BCM_BSC_DELAY);
+	BCM_BSC_UNLOCK(sc);
+	reg >>= 16;
+	error = sysctl_handle_int(oidp, &reg, sizeof(reg), req);
+	if (error != 0 || req->newptr == NULL)
+		return (error);
+
+	BCM_BSC_LOCK(sc);
+	clk = BCM_BSC_READ(sc, BCM_BSC_CLOCK);
+	clk = BCM_BSC_CORE_CLK / clk;
+	if (reg > clk / 2)
+		reg = clk / 2 - 1;
+	bcm_bsc_modifyreg(sc, BCM_BSC_DELAY, 0xffff0000, reg << 16);
+	BCM_BSC_UNLOCK(sc);
+
+	return (0);
+}
+
+static int
+bcm_bsc_rise_proc(SYSCTL_HANDLER_ARGS)
+{
+	struct bcm_bsc_softc *sc;
+	uint32_t clk, reg;
+	int error;
+
+	sc = (struct bcm_bsc_softc *)arg1;
+
+	BCM_BSC_LOCK(sc);
+	reg = BCM_BSC_READ(sc, BCM_BSC_DELAY);
+	BCM_BSC_UNLOCK(sc);
+	reg &= 0xffff;
+	error = sysctl_handle_int(oidp, &reg, sizeof(reg), req);
+	if (error != 0 || req->newptr == NULL)
+		return (error);
+
+	BCM_BSC_LOCK(sc);
+	clk = BCM_BSC_READ(sc, BCM_BSC_CLOCK);
+	clk = BCM_BSC_CORE_CLK / clk;
+	if (reg > clk / 2)
+		reg = clk / 2 - 1;
+	bcm_bsc_modifyreg(sc, BCM_BSC_DELAY, 0xffff, reg);
+	BCM_BSC_UNLOCK(sc);
+
+	return (0);
+}
+
+static void
+bcm_bsc_sysctl_init(struct bcm_bsc_softc *sc)
+{
+	struct sysctl_ctx_list *ctx;
+	struct sysctl_oid *tree_node;
+	struct sysctl_oid_list *tree;
+
+	/*
+	 * Add system sysctl tree/handlers.
+	 */
+	ctx = device_get_sysctl_ctx(sc->sc_dev);
+	tree_node = device_get_sysctl_tree(sc->sc_dev);
+	tree = SYSCTL_CHILDREN(tree_node);
+	SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "frequency",
+	    CTLFLAG_RW | CTLTYPE_UINT, sc, sizeof(*sc),
+	    bcm_bsc_clock_proc, "IU", "I2C BUS clock frequency");
+	SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "clock_stretch",
+	    CTLFLAG_RW | CTLTYPE_UINT, sc, sizeof(*sc),
+	    bcm_bsc_clkt_proc, "IU", "I2C BUS clock stretch timeout");
+	SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "fall_edge_delay",
+	    CTLFLAG_RW | CTLTYPE_UINT, sc, sizeof(*sc),
+	    bcm_bsc_fall_proc, "IU", "I2C BUS falling edge delay");
+	SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "rise_edge_delay",
+	    CTLFLAG_RW | CTLTYPE_UINT, sc, sizeof(*sc),
+	    bcm_bsc_rise_proc, "IU", "I2C BUS rising edge delay");
+}
+
+static void
+bcm_bsc_reset(struct bcm_bsc_softc *sc)
+{
+
+	/* Enable the BSC Controller, disable interrupts. */
+	BCM_BSC_WRITE(sc, BCM_BSC_CTRL, BCM_BSC_CTRL_I2CEN);
+	/* Clear pending interrupts. */
+	BCM_BSC_WRITE(sc, BCM_BSC_STATUS, BCM_BSC_STATUS_CLKT |
+	    BCM_BSC_STATUS_ERR | BCM_BSC_STATUS_DONE);
+	/* Clear the FIFO. */
+	bcm_bsc_modifyreg(sc, BCM_BSC_CTRL, BCM_BSC_CTRL_CLEAR0,
+	    BCM_BSC_CTRL_CLEAR0);
+}
+
+static int
+bcm_bsc_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
+		return (ENXIO);
+
+	device_set_desc(dev, "BCM2708/2835 BSC controller");
+
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+bcm_bsc_attach(device_t dev)
+{
+	struct bcm_bsc_softc *sc;
+	unsigned long start;
+	device_t gpio;
+	int i, rid;
+
+	sc = device_get_softc(dev);
+	sc->sc_dev = dev;
+
+	rid = 0;
+	sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	    RF_ACTIVE);
+	if (!sc->sc_mem_res) {
+		device_printf(dev, "cannot allocate memory window\n");
+		return (ENXIO);
+	}
+
+	sc->sc_bst = rman_get_bustag(sc->sc_mem_res);
+	sc->sc_bsh = rman_get_bushandle(sc->sc_mem_res);
+
+	/* Check the unit we are attaching by its base address. */
+	start = rman_get_start(sc->sc_mem_res);
+	for (i = 0; i < nitems(bcm_bsc_pins); i++) {
+		if (bcm_bsc_pins[i].start == (start & BCM_BSC_BASE_MASK))
+			break;
+	}
+	if (i == nitems(bcm_bsc_pins)) {
+		device_printf(dev, "only bsc0 and bsc1 are supported\n");
+		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
+		return (ENXIO);
+	}
+
+	/*
+	 * Configure the GPIO pins to ALT0 function to enable BSC control
+	 * over the pins.
+	 */
+	gpio = devclass_get_device(devclass_find("gpio"), 0);
+	if (!gpio) {
+		device_printf(dev, "cannot find gpio0\n");
+		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
+		return (ENXIO);
+	}
+	bcm_gpio_set_alternate(gpio, bcm_bsc_pins[i].sda, BCM_GPIO_ALT0);
+	bcm_gpio_set_alternate(gpio, bcm_bsc_pins[i].scl, BCM_GPIO_ALT0);
+
+	rid = 0;
+	sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+	    RF_ACTIVE | RF_SHAREABLE);
+	if (!sc->sc_irq_res) {
+		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
+		device_printf(dev, "cannot allocate interrupt\n");
+		return (ENXIO);
+	}
+
+	/* Hook up our interrupt handler. */
+	if (bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
+	    NULL, bcm_bsc_intr, sc, &sc->sc_intrhand)) {
+		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res);
+		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
+		device_printf(dev, "cannot setup the interrupt handler\n");
+		return (ENXIO);
+	}
+
+	mtx_init(&sc->sc_mtx, "bcm_bsc", NULL, MTX_DEF);
+
+	bcm_bsc_sysctl_init(sc);
+
+	/* Enable the BSC controller.  Flush the FIFO. */
+	BCM_BSC_LOCK(sc);
+	bcm_bsc_reset(sc);
+	BCM_BSC_UNLOCK(sc);
+
+	sc->sc_iicbus = device_add_child(dev, "iicbus", -1);
+	if (sc->sc_iicbus == NULL) {
+		bcm_bsc_detach(dev);
+		return (ENXIO);
+	}
+
+	return (bus_generic_attach(dev));
+}
+
+static int
+bcm_bsc_detach(device_t dev)
+{
+	struct bcm_bsc_softc *sc;
+
+	bus_generic_detach(dev);
+
+	sc = device_get_softc(dev);
+	mtx_destroy(&sc->sc_mtx);
+	if (sc->sc_intrhand)
+		bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_intrhand);
+	if (sc->sc_irq_res)
+		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res);
+	if (sc->sc_mem_res)
+		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
+
+	return (0);
+}
+
+static void
+bcm_bsc_intr(void *arg)
+{
+	struct bcm_bsc_softc *sc;
+	uint32_t status;
+
+	sc = (struct bcm_bsc_softc *)arg;
+
+	BCM_BSC_LOCK(sc);
+
+	/* The I2C interrupt is shared among all the BSC controllers. */
+	if ((sc->sc_flags & BCM_I2C_BUSY) == 0) {
+		BCM_BSC_UNLOCK(sc);
+		return;
+	}
+
+	status = BCM_BSC_READ(sc, BCM_BSC_STATUS);
+
+	/* Check for errors. */
+	if (status & (BCM_BSC_STATUS_CLKT | BCM_BSC_STATUS_ERR)) {
+		/* Disable interrupts. */
+		bcm_bsc_reset(sc);
+		sc->sc_flags |= BCM_I2C_ERROR;
+		wakeup(sc->sc_dev);
+		BCM_BSC_UNLOCK(sc);
+		return;
+	}
+
+	if (sc->sc_flags & BCM_I2C_READ) {
+		while (sc->sc_resid > 0 && (status & BCM_BSC_STATUS_RXD)) {
+			*sc->sc_data++ = BCM_BSC_READ(sc, BCM_BSC_DATA);
+			sc->sc_resid--;
+			status = BCM_BSC_READ(sc, BCM_BSC_STATUS);
+		}
+	} else {
+		while (sc->sc_resid > 0 && (status & BCM_BSC_STATUS_TXD)) {
+			BCM_BSC_WRITE(sc, BCM_BSC_DATA, *sc->sc_data++);
+			sc->sc_resid--;
+			status = BCM_BSC_READ(sc, BCM_BSC_STATUS);
+		}
+	}
+
+	if (status & BCM_BSC_STATUS_DONE) {
+		/* Disable interrupts. */
+		bcm_bsc_reset(sc);
+		wakeup(sc->sc_dev);
+	}
+
+	BCM_BSC_UNLOCK(sc);
+}
+
+static int
+bcm_bsc_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
+{
+	struct bcm_bsc_softc *sc;
+	uint32_t intr, read, status;
+	int i, err;
+
+	sc = device_get_softc(dev);
+	BCM_BSC_LOCK(sc);
+
+	/* If the controller is busy wait until it is available. */
+	while (sc->sc_flags & BCM_I2C_BUSY)
+		mtx_sleep(dev, &sc->sc_mtx, 0, "bscbusw", 0);
+
+	/* Now we have control over the BSC controller. */
+	sc->sc_flags = BCM_I2C_BUSY;
+
+	/* Clear the FIFO and the pending interrupts. */
+	bcm_bsc_reset(sc);
+
+	err = 0;
+	for (i = 0; i < nmsgs; i++) {
+
+		/* Write the slave address. */
+		BCM_BSC_WRITE(sc, BCM_BSC_SLAVE, msgs[i].slave >> 1);
+
+		/* Write the data length. */
+		BCM_BSC_WRITE(sc, BCM_BSC_DLEN, msgs[i].len);
+
+		sc->sc_data = msgs[i].buf;
+		sc->sc_resid = msgs[i].len;
+		if ((msgs[i].flags & IIC_M_RD) == 0) {
+			/* Fill up the TX FIFO. */
+			status = BCM_BSC_READ(sc, BCM_BSC_STATUS);
+			while (sc->sc_resid > 0 &&
+			    (status & BCM_BSC_STATUS_TXD)) {
+				BCM_BSC_WRITE(sc, BCM_BSC_DATA, *sc->sc_data);
+				sc->sc_data++;
+				sc->sc_resid--;
+				status = BCM_BSC_READ(sc, BCM_BSC_STATUS);
+			}
+			read = 0;
+			intr = BCM_BSC_CTRL_INTT;
+			sc->sc_flags &= ~BCM_I2C_READ;
+		} else {
+			sc->sc_flags |= BCM_I2C_READ;
+			read = BCM_BSC_CTRL_READ;
+			intr = BCM_BSC_CTRL_INTR;
+		}
+		intr |= BCM_BSC_CTRL_INTD;
+
+		/* Start the transfer. */
+		BCM_BSC_WRITE(sc, BCM_BSC_CTRL, BCM_BSC_CTRL_I2CEN |
+		    BCM_BSC_CTRL_ST | read | intr);
+
+		/* Wait for the transaction to complete. */
+		err = mtx_sleep(dev, &sc->sc_mtx, 0, "bsciow", hz);
+
+		/* Check for errors. */
+		if (err == 0 && (sc->sc_flags & BCM_I2C_ERROR))
+			err = EIO;
+		if (err != 0)
+			break;
+	}
+
+	/* Clean the controller flags. */
+	sc->sc_flags = 0;
+
+	/* Wake up the threads waiting for bus. */
+	wakeup(dev);
+
+	BCM_BSC_UNLOCK(sc);
+
+	return (err);
+}
+
+static int
+bcm_bsc_iicbus_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
+{
+	struct bcm_bsc_softc *sc;
+	uint32_t busfreq;
+
+	sc = device_get_softc(dev);
+	BCM_BSC_LOCK(sc);
+	bcm_bsc_reset(sc);
+	if (sc->sc_iicbus == NULL)
+		busfreq = 100000;
+	else
+		busfreq = IICBUS_GET_FREQUENCY(sc->sc_iicbus, speed);
+	BCM_BSC_WRITE(sc, BCM_BSC_CLOCK, BCM_BSC_CORE_CLK / busfreq);
+	BCM_BSC_UNLOCK(sc);
+
+	return (IIC_ENOADDR);
+}
+
+static phandle_t
+bcm_bsc_get_node(device_t bus, device_t dev)
+{
+
+	/* We only have one child, the I2C bus, which needs our own node. */
+	return (ofw_bus_get_node(bus));
+}
+
+static device_method_t bcm_bsc_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		bcm_bsc_probe),
+	DEVMETHOD(device_attach,	bcm_bsc_attach),
+	DEVMETHOD(device_detach,	bcm_bsc_detach),
+
+	/* iicbus interface */
+	DEVMETHOD(iicbus_reset,		bcm_bsc_iicbus_reset),
+	DEVMETHOD(iicbus_callback,	iicbus_null_callback),
+	DEVMETHOD(iicbus_transfer,	bcm_bsc_transfer),
+
+	/* ofw_bus interface */
+	DEVMETHOD(ofw_bus_get_node,	bcm_bsc_get_node),
+
+	DEVMETHOD_END
+};
+
+static devclass_t bcm_bsc_devclass;
+
+static driver_t bcm_bsc_driver = {
+	"iichb",
+	bcm_bsc_methods,
+	sizeof(struct bcm_bsc_softc),
+};
+
+DRIVER_MODULE(iicbus, bcm2835_bsc, iicbus_driver, iicbus_devclass, 0, 0);
+DRIVER_MODULE(bcm2835_bsc, simplebus, bcm_bsc_driver, bcm_bsc_devclass, 0, 0);


Property changes on: trunk/sys/arm/broadcom/bcm2835/bcm2835_bsc.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/broadcom/bcm2835/bcm2835_bscreg.h
===================================================================
--- trunk/sys/arm/broadcom/bcm2835/bcm2835_bscreg.h	                        (rev 0)
+++ trunk/sys/arm/broadcom/bcm2835/bcm2835_bscreg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,62 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Oleksandr Tymoshenko <gonzo at freebsd.org>
+ * Copyright (c) 2013 Luiz Otavio O Souza <loos at freebsd.org>
+ * 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: stable/10/sys/arm/broadcom/bcm2835/bcm2835_bscreg.h 261078 2014-01-23 12:32:30Z loos $
+ */
+
+#ifndef	_BCM2835_BSCREG_H_
+#define	_BCM2835_BSCREG_H_
+
+#define	BCM_BSC_CORE_CLK	150000000U
+#define	BCM_BSC_CTRL		0x00
+#define	BCM_BSC_CTRL_I2CEN		(1 << 15)
+#define	BCM_BSC_CTRL_INTR		(1 << 10)
+#define	BCM_BSC_CTRL_INTT		(1 << 9)
+#define	BCM_BSC_CTRL_INTD		(1 << 8)
+#define	BCM_BSC_CTRL_ST			(1 << 7)
+#define	BCM_BSC_CTRL_CLEAR1		(1 << 5)
+#define	BCM_BSC_CTRL_CLEAR0		(1 << 4)
+#define	BCM_BSC_CTRL_READ		(1 << 0)
+#define	BCM_BSC_STATUS		0x04
+#define	BCM_BSC_STATUS_CLKT		(1 << 9)
+#define	BCM_BSC_STATUS_ERR		(1 << 8)
+#define	BCM_BSC_STATUS_RXF		(1 << 7)
+#define	BCM_BSC_STATUS_TXE		(1 << 6)
+#define	BCM_BSC_STATUS_RXD		(1 << 5)
+#define	BCM_BSC_STATUS_TXD		(1 << 4)
+#define	BCM_BSC_STATUS_RXR		(1 << 3)
+#define	BCM_BSC_STATUS_TXW		(1 << 2)
+#define	BCM_BSC_STATUS_DONE		(1 << 1)
+#define	BCM_BSC_STATUS_TA		(1 << 0)
+#define	BCM_BSC_DLEN		0x08
+#define	BCM_BSC_SLAVE		0x0c
+#define	BCM_BSC_DATA		0x10
+#define	BCM_BSC_CLOCK		0x14
+#define	BCM_BSC_DELAY		0x18
+#define	BCM_BSC_CLKT		0x1c
+
+#endif	/* _BCM2835_BSCREG_H_ */


Property changes on: trunk/sys/arm/broadcom/bcm2835/bcm2835_bscreg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/broadcom/bcm2835/bcm2835_bscvar.h
===================================================================
--- trunk/sys/arm/broadcom/bcm2835/bcm2835_bscvar.h	                        (rev 0)
+++ trunk/sys/arm/broadcom/bcm2835/bcm2835_bscvar.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,72 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Oleksandr Tymoshenko <gonzo at freebsd.org>
+ * Copyright (c) 2013 Luiz Otavio O Souza <loos at freebsd.org>
+ * 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: stable/10/sys/arm/broadcom/bcm2835/bcm2835_bscvar.h 322724 2017-08-20 16:52:27Z marius $
+ */
+
+#ifndef _BCM2835_BSCVAR_H
+#define _BCM2835_BSCVAR_H
+
+struct {
+	uint32_t	sda;
+	uint32_t	scl;
+	unsigned long	start;
+} bcm_bsc_pins[] = {
+	{ 0, 1, 0x205000 },	/* BSC0 GPIO pins and base address. */
+	{ 2, 3, 0x804000 }	/* BSC1 GPIO pins and base address. */
+};
+#define	BCM_BSC_BASE_MASK	0x00ffffff
+
+struct bcm_bsc_softc {
+	device_t		sc_dev;
+	device_t		sc_iicbus;
+	struct mtx		sc_mtx;
+	struct resource *	sc_mem_res;
+	struct resource *	sc_irq_res;
+	bus_space_tag_t		sc_bst;
+	bus_space_handle_t	sc_bsh;
+	uint16_t		sc_resid;
+	uint8_t			*sc_data;
+	uint8_t			sc_flags;
+	void *			sc_intrhand;
+};
+
+#define	BCM_I2C_BUSY		0x01
+#define	BCM_I2C_READ		0x02
+#define	BCM_I2C_ERROR		0x04
+
+#define	BCM_BSC_WRITE(_sc, _off, _val)		\
+    bus_space_write_4((_sc)->sc_bst, (_sc)->sc_bsh, _off, _val)
+#define	BCM_BSC_READ(_sc, _off)			\
+    bus_space_read_4((_sc)->sc_bst, (_sc)->sc_bsh, _off)
+
+#define	BCM_BSC_LOCK(_sc)			\
+    mtx_lock(&(_sc)->sc_mtx)
+#define	BCM_BSC_UNLOCK(_sc)			\
+    mtx_unlock(&(_sc)->sc_mtx)
+
+#endif	/* _BCM2835_BSCVAR_H_ */


Property changes on: trunk/sys/arm/broadcom/bcm2835/bcm2835_bscvar.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/broadcom/bcm2835/bcm2835_common.c
===================================================================
--- trunk/sys/arm/broadcom/bcm2835/bcm2835_common.c	                        (rev 0)
+++ trunk/sys/arm/broadcom/bcm2835/bcm2835_common.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,84 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (C) 2008-2011 MARVELL INTERNATIONAL LTD.
+ * All rights reserved.
+ *
+ * Developed by Semihalf.
+ *
+ * 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.
+ * 3. Neither the name of MARVELL nor the names of contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY 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 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_global.h"
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/broadcom/bcm2835/bcm2835_common.c 322724 2017-08-20 16:52:27Z marius $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/kdb.h>
+#include <sys/reboot.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+#include <machine/vmparam.h>
+
+struct fdt_fixup_entry fdt_fixup_table[] = {
+	{ NULL, NULL }
+};
+
+static int
+fdt_intc_decode_ic(phandle_t node, pcell_t *intr, int *interrupt, int *trig,
+    int *pol)
+{
+
+	if (fdt_is_compatible(node, "broadcom,bcm2835-armctrl-ic") ||
+	    fdt_is_compatible(node, "brcm,bcm2836-armctrl-ic")) {
+		*interrupt = fdt32_to_cpu(intr[0]);
+		*trig = INTR_TRIGGER_CONFORM;
+		*pol = INTR_POLARITY_CONFORM;
+		return (0);
+	}
+#ifdef SOC_BCM2836
+	if (fdt_is_compatible(node, "brcm,bcm2836-l1-intc")) {
+		*interrupt = fdt32_to_cpu(intr[0]) + 72;
+		*trig = INTR_TRIGGER_CONFORM;
+		*pol = INTR_POLARITY_CONFORM;
+		return (0);
+	}
+#endif
+	return (ENXIO);
+}
+
+
+fdt_pic_decode_t fdt_pic_table[] = {
+	&fdt_intc_decode_ic,
+	NULL
+};


Property changes on: trunk/sys/arm/broadcom/bcm2835/bcm2835_common.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/broadcom/bcm2835/bcm2835_cpufreq.c
===================================================================
--- trunk/sys/arm/broadcom/bcm2835/bcm2835_cpufreq.c	                        (rev 0)
+++ trunk/sys/arm/broadcom/bcm2835/bcm2835_cpufreq.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,1614 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (C) 2013-2014 Daisuke Aoyama <aoyama at peach.ne.jp>
+ * 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: stable/10/sys/arm/broadcom/bcm2835/bcm2835_cpufreq.c 322724 2017-08-20 16:52:27Z marius $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/cpu.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/sema.h>
+#include <sys/sysctl.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#include <dev/fdt/fdt_common.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <arm/broadcom/bcm2835/bcm2835_mbox.h>
+#include <arm/broadcom/bcm2835/bcm2835_mbox_prop.h>
+#include <arm/broadcom/bcm2835/bcm2835_vcbus.h>
+
+#include "cpufreq_if.h"
+#include "mbox_if.h"
+
+#ifdef DEBUG
+#define DPRINTF(fmt, ...) do {			\
+	printf("%s:%u: ", __func__, __LINE__);	\
+	printf(fmt, ##__VA_ARGS__);		\
+} while (0)
+#else
+#define DPRINTF(fmt, ...)
+#endif
+
+#define HZ2MHZ(freq) ((freq) / (1000 * 1000))
+#define MHZ2HZ(freq) ((freq) * (1000 * 1000))
+#define OFFSET2MVOLT(val) (1200 + ((val) * 25))
+#define MVOLT2OFFSET(val) (((val) - 1200) / 25)
+
+#define DEFAULT_ARM_FREQUENCY	 700
+#define DEFAULT_CORE_FREQUENCY	 250
+#define DEFAULT_SDRAM_FREQUENCY	 400
+#define DEFAULT_LOWEST_FREQ	 300
+#define TRANSITION_LATENCY	1000
+#define MIN_OVER_VOLTAGE	 -16
+#define MAX_OVER_VOLTAGE	   6
+#define MSG_ERROR	  -999999999
+#define MHZSTEP			 100
+#define HZSTEP	   (MHZ2HZ(MHZSTEP))
+#define	TZ_ZEROC		2732
+
+#define VC_LOCK(sc) do {			\
+		sema_wait(&vc_sema);		\
+	} while (0)
+#define VC_UNLOCK(sc) do {			\
+		sema_post(&vc_sema);		\
+	} while (0)
+
+/* ARM->VC mailbox property semaphore */
+static struct sema vc_sema;
+
+static struct sysctl_ctx_list bcm2835_sysctl_ctx;
+
+struct bcm2835_cpufreq_softc {
+	device_t	dev;
+	int		arm_max_freq;
+	int		arm_min_freq;
+	int		core_max_freq;
+	int		core_min_freq;
+	int		sdram_max_freq;
+	int		sdram_min_freq;
+	int		max_voltage_core;
+	int		min_voltage_core;
+
+	/* the values written in mbox */
+	int		voltage_core;
+	int		voltage_sdram;
+	int		voltage_sdram_c;
+	int		voltage_sdram_i;
+	int		voltage_sdram_p;
+	int		turbo_mode;
+
+	/* initial hook for waiting mbox intr */
+	struct intr_config_hook	init_hook;
+};
+
+static struct ofw_compat_data compat_data[] = {
+	{ "broadcom,bcm2835-vc",	1 },
+	{ "broadcom,bcm2708-vc",	1 },
+	{ "brcm,bcm2709",	1 },
+	{ NULL, 0 }
+};
+
+static int cpufreq_verbose = 0;
+TUNABLE_INT("hw.bcm2835.cpufreq.verbose", &cpufreq_verbose);
+static int cpufreq_lowest_freq = DEFAULT_LOWEST_FREQ;
+TUNABLE_INT("hw.bcm2835.cpufreq.lowest_freq", &cpufreq_lowest_freq);
+
+#ifdef PROP_DEBUG
+static void
+bcm2835_dump(const void *data, int len)
+{
+	const uint8_t *p = (const uint8_t*)data;
+	int i;
+
+	printf("dump @ %p:\n", data);
+	for (i = 0; i < len; i++) {
+		printf("%2.2x ", p[i]);
+		if ((i % 4) == 3)
+			printf(" ");
+		if ((i % 16) == 15)
+			printf("\n");
+	}
+	printf("\n");
+}
+#endif
+
+static int
+bcm2835_cpufreq_get_clock_rate(struct bcm2835_cpufreq_softc *sc,
+    uint32_t clock_id)
+{
+	struct msg_get_clock_rate msg;
+	int rate;
+	int err;
+
+	/*
+	 * Get clock rate
+	 *   Tag: 0x00030002
+	 *   Request:
+	 *     Length: 4
+	 *     Value:
+	 *       u32: clock id
+	 *   Response:
+	 *     Length: 8
+	 *     Value:
+	 *       u32: clock id
+	 *       u32: rate (in Hz)
+	 */
+
+	/* setup single tag buffer */
+	memset(&msg, 0, sizeof(msg));
+	msg.hdr.buf_size = sizeof(msg);
+	msg.hdr.code = BCM2835_MBOX_CODE_REQ;
+	msg.tag_hdr.tag = BCM2835_MBOX_TAG_GET_CLOCK_RATE;
+	msg.tag_hdr.val_buf_size = sizeof(msg.body);
+	msg.tag_hdr.val_len = sizeof(msg.body.req);
+	msg.body.req.clock_id = clock_id;
+	msg.end_tag = 0;
+
+	/* call mailbox property */
+	err = bcm2835_mbox_property(&msg, sizeof(msg));
+	if (err) {
+		device_printf(sc->dev, "can't get clock rate (id=%u)\n",
+		    clock_id);
+		return (MSG_ERROR);
+	}
+
+	/* result (Hz) */
+	rate = (int)msg.body.resp.rate_hz;
+	DPRINTF("clock = %d(Hz)\n", rate);
+	return (rate);
+}
+
+static int
+bcm2835_cpufreq_get_max_clock_rate(struct bcm2835_cpufreq_softc *sc,
+    uint32_t clock_id)
+{
+	struct msg_get_max_clock_rate msg;
+	int rate;
+	int err;
+
+	/*
+	 * Get max clock rate
+	 *   Tag: 0x00030004
+	 *   Request:
+	 *     Length: 4
+	 *     Value:
+	 *       u32: clock id
+	 *   Response:
+	 *     Length: 8
+	 *     Value:
+	 *       u32: clock id
+	 *       u32: rate (in Hz)
+	 */
+
+	/* setup single tag buffer */
+	memset(&msg, 0, sizeof(msg));
+	msg.hdr.buf_size = sizeof(msg);
+	msg.hdr.code = BCM2835_MBOX_CODE_REQ;
+	msg.tag_hdr.tag = BCM2835_MBOX_TAG_GET_MAX_CLOCK_RATE;
+	msg.tag_hdr.val_buf_size = sizeof(msg.body);
+	msg.tag_hdr.val_len = sizeof(msg.body.req);
+	msg.body.req.clock_id = clock_id;
+	msg.end_tag = 0;
+
+	/* call mailbox property */
+	err = bcm2835_mbox_property(&msg, sizeof(msg));
+	if (err) {
+		device_printf(sc->dev, "can't get max clock rate (id=%u)\n",
+		    clock_id);
+		return (MSG_ERROR);
+	}
+
+	/* result (Hz) */
+	rate = (int)msg.body.resp.rate_hz;
+	DPRINTF("clock = %d(Hz)\n", rate);
+	return (rate);
+}
+
+static int
+bcm2835_cpufreq_get_min_clock_rate(struct bcm2835_cpufreq_softc *sc,
+    uint32_t clock_id)
+{
+	struct msg_get_min_clock_rate msg;
+	int rate;
+	int err;
+
+	/*
+	 * Get min clock rate
+	 *   Tag: 0x00030007
+	 *   Request:
+	 *     Length: 4
+	 *     Value:
+	 *       u32: clock id
+	 *   Response:
+	 *     Length: 8
+	 *     Value:
+	 *       u32: clock id
+	 *       u32: rate (in Hz)
+	 */
+
+	/* setup single tag buffer */
+	memset(&msg, 0, sizeof(msg));
+	msg.hdr.buf_size = sizeof(msg);
+	msg.hdr.code = BCM2835_MBOX_CODE_REQ;
+	msg.tag_hdr.tag = BCM2835_MBOX_TAG_GET_MIN_CLOCK_RATE;
+	msg.tag_hdr.val_buf_size = sizeof(msg.body);
+	msg.tag_hdr.val_len = sizeof(msg.body.req);
+	msg.body.req.clock_id = clock_id;
+	msg.end_tag = 0;
+
+	/* call mailbox property */
+	err = bcm2835_mbox_property(&msg, sizeof(msg));
+	if (err) {
+		device_printf(sc->dev, "can't get min clock rate (id=%u)\n",
+		    clock_id);
+		return (MSG_ERROR);
+	}
+
+	/* result (Hz) */
+	rate = (int)msg.body.resp.rate_hz;
+	DPRINTF("clock = %d(Hz)\n", rate);
+	return (rate);
+}
+
+static int
+bcm2835_cpufreq_set_clock_rate(struct bcm2835_cpufreq_softc *sc,
+    uint32_t clock_id, uint32_t rate_hz)
+{
+	struct msg_set_clock_rate msg;
+	int rate;
+	int err;
+
+	/*
+	 * Set clock rate
+	 *   Tag: 0x00038002
+	 *   Request:
+	 *     Length: 8
+	 *     Value:
+	 *       u32: clock id
+	 *       u32: rate (in Hz)
+	 *   Response:
+	 *     Length: 8
+	 *     Value:
+	 *       u32: clock id
+	 *       u32: rate (in Hz)
+	 */
+
+	/* setup single tag buffer */
+	memset(&msg, 0, sizeof(msg));
+	msg.hdr.buf_size = sizeof(msg);
+	msg.hdr.code = BCM2835_MBOX_CODE_REQ;
+	msg.tag_hdr.tag = BCM2835_MBOX_TAG_SET_CLOCK_RATE;
+	msg.tag_hdr.val_buf_size = sizeof(msg.body);
+	msg.tag_hdr.val_len = sizeof(msg.body.req);
+	msg.body.req.clock_id = clock_id;
+	msg.body.req.rate_hz = rate_hz;
+	msg.end_tag = 0;
+
+	/* call mailbox property */
+	err = bcm2835_mbox_property(&msg, sizeof(msg));
+	if (err) {
+		device_printf(sc->dev, "can't set clock rate (id=%u)\n",
+		    clock_id);
+		return (MSG_ERROR);
+	}
+
+	/* workaround for core clock */
+	if (clock_id == BCM2835_MBOX_CLOCK_ID_CORE) {
+		/* for safety (may change voltage without changing clock) */
+		DELAY(TRANSITION_LATENCY);
+
+		/*
+		 * XXX: the core clock is unable to change at once,
+		 * to change certainly, write it twice now.
+		 */
+
+		/* setup single tag buffer */
+		memset(&msg, 0, sizeof(msg));
+		msg.hdr.buf_size = sizeof(msg);
+		msg.hdr.code = BCM2835_MBOX_CODE_REQ;
+		msg.tag_hdr.tag = BCM2835_MBOX_TAG_SET_CLOCK_RATE;
+		msg.tag_hdr.val_buf_size = sizeof(msg.body);
+		msg.tag_hdr.val_len = sizeof(msg.body.req);
+		msg.body.req.clock_id = clock_id;
+		msg.body.req.rate_hz = rate_hz;
+		msg.end_tag = 0;
+
+		/* call mailbox property */
+		err = bcm2835_mbox_property(&msg, sizeof(msg));
+		if (err) {
+			device_printf(sc->dev,
+			    "can't set clock rate (id=%u)\n", clock_id);
+			return (MSG_ERROR);
+		}
+	}
+
+	/* result (Hz) */
+	rate = (int)msg.body.resp.rate_hz;
+	DPRINTF("clock = %d(Hz)\n", rate);
+	return (rate);
+}
+
+static int
+bcm2835_cpufreq_get_turbo(struct bcm2835_cpufreq_softc *sc)
+{
+	struct msg_get_turbo msg;
+	int level;
+	int err;
+
+	/*
+	 * Get turbo
+	 *   Tag: 0x00030009
+	 *   Request:
+	 *     Length: 4
+	 *     Value:
+	 *       u32: id
+	 *   Response:
+	 *     Length: 8
+	 *     Value:
+	 *       u32: id
+	 *       u32: level
+	 */
+
+	/* setup single tag buffer */
+	memset(&msg, 0, sizeof(msg));
+	msg.hdr.buf_size = sizeof(msg);
+	msg.hdr.code = BCM2835_MBOX_CODE_REQ;
+	msg.tag_hdr.tag = BCM2835_MBOX_TAG_GET_TURBO;
+	msg.tag_hdr.val_buf_size = sizeof(msg.body);
+	msg.tag_hdr.val_len = sizeof(msg.body.req);
+	msg.body.req.id = 0;
+	msg.end_tag = 0;
+
+	/* call mailbox property */
+	err = bcm2835_mbox_property(&msg, sizeof(msg));
+	if (err) {
+		device_printf(sc->dev, "can't get turbo\n");
+		return (MSG_ERROR);
+	}
+
+	/* result 0=non-turbo, 1=turbo */
+	level = (int)msg.body.resp.level;
+	DPRINTF("level = %d\n", level);
+	return (level);
+}
+
+static int
+bcm2835_cpufreq_set_turbo(struct bcm2835_cpufreq_softc *sc, uint32_t level)
+{
+	struct msg_set_turbo msg;
+	int value;
+	int err;
+
+	/*
+	 * Set turbo
+	 *   Tag: 0x00038009
+	 *   Request:
+	 *     Length: 8
+	 *     Value:
+	 *       u32: id
+	 *       u32: level
+	 *   Response:
+	 *     Length: 8
+	 *     Value:
+	 *       u32: id
+	 *       u32: level
+	 */
+
+	/* replace unknown value to OFF */
+	if (level != BCM2835_MBOX_TURBO_ON && level != BCM2835_MBOX_TURBO_OFF)
+		level = BCM2835_MBOX_TURBO_OFF;
+
+	/* setup single tag buffer */
+	memset(&msg, 0, sizeof(msg));
+	msg.hdr.buf_size = sizeof(msg);
+	msg.hdr.code = BCM2835_MBOX_CODE_REQ;
+	msg.tag_hdr.tag = BCM2835_MBOX_TAG_SET_TURBO;
+	msg.tag_hdr.val_buf_size = sizeof(msg.body);
+	msg.tag_hdr.val_len = sizeof(msg.body.req);
+	msg.body.req.id = 0;
+	msg.body.req.level = level;
+	msg.end_tag = 0;
+
+	/* call mailbox property */
+	err = bcm2835_mbox_property(&msg, sizeof(msg));
+	if (err) {
+		device_printf(sc->dev, "can't set turbo\n");
+		return (MSG_ERROR);
+	}
+
+	/* result 0=non-turbo, 1=turbo */
+	value = (int)msg.body.resp.level;
+	DPRINTF("level = %d\n", value);
+	return (value);
+}
+
+static int
+bcm2835_cpufreq_get_voltage(struct bcm2835_cpufreq_softc *sc,
+    uint32_t voltage_id)
+{
+	struct msg_get_voltage msg;
+	int value;
+	int err;
+
+	/*
+	 * Get voltage
+	 *   Tag: 0x00030003
+	 *   Request:
+	 *     Length: 4
+	 *     Value:
+	 *       u32: voltage id
+	 *   Response:
+	 *     Length: 8
+	 *     Value:
+	 *       u32: voltage id
+	 *       u32: value (offset from 1.2V in units of 0.025V)
+	 */
+
+	/* setup single tag buffer */
+	memset(&msg, 0, sizeof(msg));
+	msg.hdr.buf_size = sizeof(msg);
+	msg.hdr.code = BCM2835_MBOX_CODE_REQ;
+	msg.tag_hdr.tag = BCM2835_MBOX_TAG_GET_VOLTAGE;
+	msg.tag_hdr.val_buf_size = sizeof(msg.body);
+	msg.tag_hdr.val_len = sizeof(msg.body.req);
+	msg.body.req.voltage_id = voltage_id;
+	msg.end_tag = 0;
+
+	/* call mailbox property */
+	err = bcm2835_mbox_property(&msg, sizeof(msg));
+	if (err) {
+		device_printf(sc->dev, "can't get voltage\n");
+		return (MSG_ERROR);
+	}
+
+	/* result (offset from 1.2V) */
+	value = (int)msg.body.resp.value;
+	DPRINTF("value = %d\n", value);
+	return (value);
+}
+
+static int
+bcm2835_cpufreq_get_max_voltage(struct bcm2835_cpufreq_softc *sc,
+    uint32_t voltage_id)
+{
+	struct msg_get_max_voltage msg;
+	int value;
+	int err;
+
+	/*
+	 * Get voltage
+	 *   Tag: 0x00030005
+	 *   Request:
+	 *     Length: 4
+	 *     Value:
+	 *       u32: voltage id
+	 *   Response:
+	 *     Length: 8
+	 *     Value:
+	 *       u32: voltage id
+	 *       u32: value (offset from 1.2V in units of 0.025V)
+	 */
+
+	/* setup single tag buffer */
+	memset(&msg, 0, sizeof(msg));
+	msg.hdr.buf_size = sizeof(msg);
+	msg.hdr.code = BCM2835_MBOX_CODE_REQ;
+	msg.tag_hdr.tag = BCM2835_MBOX_TAG_GET_MAX_VOLTAGE;
+	msg.tag_hdr.val_buf_size = sizeof(msg.body);
+	msg.tag_hdr.val_len = sizeof(msg.body.req);
+	msg.body.req.voltage_id = voltage_id;
+	msg.end_tag = 0;
+
+	/* call mailbox property */
+	err = bcm2835_mbox_property(&msg, sizeof(msg));
+	if (err) {
+		device_printf(sc->dev, "can't get max voltage\n");
+		return (MSG_ERROR);
+	}
+
+	/* result (offset from 1.2V) */
+	value = (int)msg.body.resp.value;
+	DPRINTF("value = %d\n", value);
+	return (value);
+}
+static int
+bcm2835_cpufreq_get_min_voltage(struct bcm2835_cpufreq_softc *sc,
+    uint32_t voltage_id)
+{
+	struct msg_get_min_voltage msg;
+	int value;
+	int err;
+
+	/*
+	 * Get voltage
+	 *   Tag: 0x00030008
+	 *   Request:
+	 *     Length: 4
+	 *     Value:
+	 *       u32: voltage id
+	 *   Response:
+	 *     Length: 8
+	 *     Value:
+	 *       u32: voltage id
+	 *       u32: value (offset from 1.2V in units of 0.025V)
+	 */
+
+	/* setup single tag buffer */
+	memset(&msg, 0, sizeof(msg));
+	msg.hdr.buf_size = sizeof(msg);
+	msg.hdr.code = BCM2835_MBOX_CODE_REQ;
+	msg.tag_hdr.tag = BCM2835_MBOX_TAG_GET_MIN_VOLTAGE;
+	msg.tag_hdr.val_buf_size = sizeof(msg.body);
+	msg.tag_hdr.val_len = sizeof(msg.body.req);
+	msg.body.req.voltage_id = voltage_id;
+	msg.end_tag = 0;
+
+	/* call mailbox property */
+	err = bcm2835_mbox_property(&msg, sizeof(msg));
+	if (err) {
+		device_printf(sc->dev, "can't get min voltage\n");
+		return (MSG_ERROR);
+	}
+
+	/* result (offset from 1.2V) */
+	value = (int)msg.body.resp.value;
+	DPRINTF("value = %d\n", value);
+	return (value);
+}
+
+static int
+bcm2835_cpufreq_set_voltage(struct bcm2835_cpufreq_softc *sc,
+    uint32_t voltage_id, int32_t value)
+{
+	struct msg_set_voltage msg;
+	int err;
+
+	/*
+	 * Set voltage
+	 *   Tag: 0x00038003
+	 *   Request:
+	 *     Length: 4
+	 *     Value:
+	 *       u32: voltage id
+	 *       u32: value (offset from 1.2V in units of 0.025V)
+	 *   Response:
+	 *     Length: 8
+	 *     Value:
+	 *       u32: voltage id
+	 *       u32: value (offset from 1.2V in units of 0.025V)
+	 */
+
+	/*
+	 * over_voltage:
+	 * 0 (1.2 V). Values above 6 are only allowed when force_turbo or
+	 * current_limit_override are specified (which set the warranty bit).
+	 */
+	if (value > MAX_OVER_VOLTAGE || value < MIN_OVER_VOLTAGE) {
+		/* currently not supported */
+		device_printf(sc->dev, "not supported voltage: %d\n", value);
+		return (MSG_ERROR);
+	}
+
+	/* setup single tag buffer */
+	memset(&msg, 0, sizeof(msg));
+	msg.hdr.buf_size = sizeof(msg);
+	msg.hdr.code = BCM2835_MBOX_CODE_REQ;
+	msg.tag_hdr.tag = BCM2835_MBOX_TAG_SET_VOLTAGE;
+	msg.tag_hdr.val_buf_size = sizeof(msg.body);
+	msg.tag_hdr.val_len = sizeof(msg.body.req);
+	msg.body.req.voltage_id = voltage_id;
+	msg.body.req.value = (uint32_t)value;
+	msg.end_tag = 0;
+
+	/* call mailbox property */
+	err = bcm2835_mbox_property(&msg, sizeof(msg));
+	if (err) {
+		device_printf(sc->dev, "can't set voltage\n");
+		return (MSG_ERROR);
+	}
+
+	/* result (offset from 1.2V) */
+	value = (int)msg.body.resp.value;
+	DPRINTF("value = %d\n", value);
+	return (value);
+}
+
+static int
+bcm2835_cpufreq_get_temperature(struct bcm2835_cpufreq_softc *sc)
+{
+	struct msg_get_temperature msg;
+	int value;
+	int err;
+
+	/*
+	 * Get temperature
+	 *   Tag: 0x00030006
+	 *   Request:
+	 *     Length: 4
+	 *     Value:
+	 *       u32: temperature id
+	 *   Response:
+	 *     Length: 8
+	 *     Value:
+	 *       u32: temperature id
+	 *       u32: value
+	 */
+
+	/* setup single tag buffer */
+	memset(&msg, 0, sizeof(msg));
+	msg.hdr.buf_size = sizeof(msg);
+	msg.hdr.code = BCM2835_MBOX_CODE_REQ;
+	msg.tag_hdr.tag = BCM2835_MBOX_TAG_GET_TEMPERATURE;
+	msg.tag_hdr.val_buf_size = sizeof(msg.body);
+	msg.tag_hdr.val_len = sizeof(msg.body.req);
+	msg.body.req.temperature_id = 0;
+	msg.end_tag = 0;
+
+	/* call mailbox property */
+	err = bcm2835_mbox_property(&msg, sizeof(msg));
+	if (err) {
+		device_printf(sc->dev, "can't get temperature\n");
+		return (MSG_ERROR);
+	}
+
+	/* result (temperature of degree C) */
+	value = (int)msg.body.resp.value;
+	DPRINTF("value = %d\n", value);
+	return (value);
+}
+
+
+
+static int
+sysctl_bcm2835_cpufreq_arm_freq(SYSCTL_HANDLER_ARGS)
+{
+	struct bcm2835_cpufreq_softc *sc = arg1;
+	int val;
+	int err;
+
+	/* get realtime value */
+	VC_LOCK(sc);
+	val = bcm2835_cpufreq_get_clock_rate(sc, BCM2835_MBOX_CLOCK_ID_ARM);
+	VC_UNLOCK(sc);
+	if (val == MSG_ERROR)
+		return (EIO);
+
+	err = sysctl_handle_int(oidp, &val, 0, req);
+	if (err || !req->newptr) /* error || read request */
+		return (err);
+
+	/* write request */
+	VC_LOCK(sc);
+	err = bcm2835_cpufreq_set_clock_rate(sc, BCM2835_MBOX_CLOCK_ID_ARM,
+	    val);
+	VC_UNLOCK(sc);
+	if (err == MSG_ERROR) {
+		device_printf(sc->dev, "set clock arm_freq error\n");
+		return (EIO);
+	}
+	DELAY(TRANSITION_LATENCY);
+
+	return (0);
+}
+
+static int
+sysctl_bcm2835_cpufreq_core_freq(SYSCTL_HANDLER_ARGS)
+{
+	struct bcm2835_cpufreq_softc *sc = arg1;
+	int val;
+	int err;
+
+	/* get realtime value */
+	VC_LOCK(sc);
+	val = bcm2835_cpufreq_get_clock_rate(sc, BCM2835_MBOX_CLOCK_ID_CORE);
+	VC_UNLOCK(sc);
+	if (val == MSG_ERROR)
+		return (EIO);
+
+	err = sysctl_handle_int(oidp, &val, 0, req);
+	if (err || !req->newptr) /* error || read request */
+		return (err);
+
+	/* write request */
+	VC_LOCK(sc);
+	err = bcm2835_cpufreq_set_clock_rate(sc, BCM2835_MBOX_CLOCK_ID_CORE,
+	    val);
+	if (err == MSG_ERROR) {
+		VC_UNLOCK(sc);
+		device_printf(sc->dev, "set clock core_freq error\n");
+		return (EIO);
+	}
+	VC_UNLOCK(sc);
+	DELAY(TRANSITION_LATENCY);
+
+	return (0);
+}
+
+static int
+sysctl_bcm2835_cpufreq_sdram_freq(SYSCTL_HANDLER_ARGS)
+{
+	struct bcm2835_cpufreq_softc *sc = arg1;
+	int val;
+	int err;
+
+	/* get realtime value */
+	VC_LOCK(sc);
+	val = bcm2835_cpufreq_get_clock_rate(sc, BCM2835_MBOX_CLOCK_ID_SDRAM);
+	VC_UNLOCK(sc);
+	if (val == MSG_ERROR)
+		return (EIO);
+
+	err = sysctl_handle_int(oidp, &val, 0, req);
+	if (err || !req->newptr) /* error || read request */
+		return (err);
+
+	/* write request */
+	VC_LOCK(sc);
+	err = bcm2835_cpufreq_set_clock_rate(sc, BCM2835_MBOX_CLOCK_ID_SDRAM,
+	    val);
+	VC_UNLOCK(sc);
+	if (err == MSG_ERROR) {
+		device_printf(sc->dev, "set clock sdram_freq error\n");
+		return (EIO);
+	}
+	DELAY(TRANSITION_LATENCY);
+
+	return (0);
+}
+
+static int
+sysctl_bcm2835_cpufreq_turbo(SYSCTL_HANDLER_ARGS)
+{
+	struct bcm2835_cpufreq_softc *sc = arg1;
+	int val;
+	int err;
+
+	/* get realtime value */
+	VC_LOCK(sc);
+	val = bcm2835_cpufreq_get_turbo(sc);
+	VC_UNLOCK(sc);
+	if (val == MSG_ERROR)
+		return (EIO);
+
+	err = sysctl_handle_int(oidp, &val, 0, req);
+	if (err || !req->newptr) /* error || read request */
+		return (err);
+
+	/* write request */
+	if (val > 0)
+		sc->turbo_mode = BCM2835_MBOX_TURBO_ON;
+	else
+		sc->turbo_mode = BCM2835_MBOX_TURBO_OFF;
+
+	VC_LOCK(sc);
+	err = bcm2835_cpufreq_set_turbo(sc, sc->turbo_mode);
+	VC_UNLOCK(sc);
+	if (err == MSG_ERROR) {
+		device_printf(sc->dev, "set turbo error\n");
+		return (EIO);
+	}
+	DELAY(TRANSITION_LATENCY);
+
+	return (0);
+}
+
+static int
+sysctl_bcm2835_cpufreq_voltage_core(SYSCTL_HANDLER_ARGS)
+{
+	struct bcm2835_cpufreq_softc *sc = arg1;
+	int val;
+	int err;
+
+	/* get realtime value */
+	VC_LOCK(sc);
+	val = bcm2835_cpufreq_get_voltage(sc, BCM2835_MBOX_VOLTAGE_ID_CORE);
+	VC_UNLOCK(sc);
+	if (val == MSG_ERROR)
+		return (EIO);
+
+	err = sysctl_handle_int(oidp, &val, 0, req);
+	if (err || !req->newptr) /* error || read request */
+		return (err);
+
+	/* write request */
+	if (val > MAX_OVER_VOLTAGE || val < MIN_OVER_VOLTAGE)
+		return (EINVAL);
+	sc->voltage_core = val;
+
+	VC_LOCK(sc);
+	err = bcm2835_cpufreq_set_voltage(sc, BCM2835_MBOX_VOLTAGE_ID_CORE,
+	    sc->voltage_core);
+	VC_UNLOCK(sc);
+	if (err == MSG_ERROR) {
+		device_printf(sc->dev, "set voltage core error\n");
+		return (EIO);
+	}
+	DELAY(TRANSITION_LATENCY);
+
+	return (0);
+}
+
+static int
+sysctl_bcm2835_cpufreq_voltage_sdram_c(SYSCTL_HANDLER_ARGS)
+{
+	struct bcm2835_cpufreq_softc *sc = arg1;
+	int val;
+	int err;
+
+	/* get realtime value */
+	VC_LOCK(sc);
+	val = bcm2835_cpufreq_get_voltage(sc, BCM2835_MBOX_VOLTAGE_ID_SDRAM_C);
+	VC_UNLOCK(sc);
+	if (val == MSG_ERROR)
+		return (EIO);
+
+	err = sysctl_handle_int(oidp, &val, 0, req);
+	if (err || !req->newptr) /* error || read request */
+		return (err);
+
+	/* write request */
+	if (val > MAX_OVER_VOLTAGE || val < MIN_OVER_VOLTAGE)
+		return (EINVAL);
+	sc->voltage_sdram_c = val;
+
+	VC_LOCK(sc);
+	err = bcm2835_cpufreq_set_voltage(sc, BCM2835_MBOX_VOLTAGE_ID_SDRAM_C,
+	   sc->voltage_sdram_c);
+	VC_UNLOCK(sc);
+	if (err == MSG_ERROR) {
+		device_printf(sc->dev, "set voltage sdram_c error\n");
+		return (EIO);
+	}
+	DELAY(TRANSITION_LATENCY);
+
+	return (0);
+}
+
+static int
+sysctl_bcm2835_cpufreq_voltage_sdram_i(SYSCTL_HANDLER_ARGS)
+{
+	struct bcm2835_cpufreq_softc *sc = arg1;
+	int val;
+	int err;
+
+	/* get realtime value */
+	VC_LOCK(sc);
+	val = bcm2835_cpufreq_get_voltage(sc, BCM2835_MBOX_VOLTAGE_ID_SDRAM_I);
+	VC_UNLOCK(sc);
+	if (val == MSG_ERROR)
+		return (EIO);
+
+	err = sysctl_handle_int(oidp, &val, 0, req);
+	if (err || !req->newptr) /* error || read request */
+		return (err);
+
+	/* write request */
+	if (val > MAX_OVER_VOLTAGE || val < MIN_OVER_VOLTAGE)
+		return (EINVAL);
+	sc->voltage_sdram_i = val;
+
+	VC_LOCK(sc);
+	err = bcm2835_cpufreq_set_voltage(sc, BCM2835_MBOX_VOLTAGE_ID_SDRAM_I,
+	    sc->voltage_sdram_i);
+	VC_UNLOCK(sc);
+	if (err == MSG_ERROR) {
+		device_printf(sc->dev, "set voltage sdram_i error\n");
+		return (EIO);
+	}
+	DELAY(TRANSITION_LATENCY);
+
+	return (0);
+}
+
+static int
+sysctl_bcm2835_cpufreq_voltage_sdram_p(SYSCTL_HANDLER_ARGS)
+{
+	struct bcm2835_cpufreq_softc *sc = arg1;
+	int val;
+	int err;
+
+	/* get realtime value */
+	VC_LOCK(sc);
+	val = bcm2835_cpufreq_get_voltage(sc, BCM2835_MBOX_VOLTAGE_ID_SDRAM_P);
+	VC_UNLOCK(sc);
+	if (val == MSG_ERROR)
+		return (EIO);
+
+	err = sysctl_handle_int(oidp, &val, 0, req);
+	if (err || !req->newptr) /* error || read request */
+		return (err);
+
+	/* write request */
+	if (val > MAX_OVER_VOLTAGE || val < MIN_OVER_VOLTAGE)
+		return (EINVAL);
+	sc->voltage_sdram_p = val;
+
+	VC_LOCK(sc);
+	err = bcm2835_cpufreq_set_voltage(sc, BCM2835_MBOX_VOLTAGE_ID_SDRAM_P,
+	    sc->voltage_sdram_p);
+	VC_UNLOCK(sc);
+	if (err == MSG_ERROR) {
+		device_printf(sc->dev, "set voltage sdram_p error\n");
+		return (EIO);
+	}
+	DELAY(TRANSITION_LATENCY);
+
+	return (0);
+}
+
+static int
+sysctl_bcm2835_cpufreq_voltage_sdram(SYSCTL_HANDLER_ARGS)
+{
+	struct bcm2835_cpufreq_softc *sc = arg1;
+	int val;
+	int err;
+
+	/* multiple write only */
+	if (!req->newptr)
+		return (EINVAL);
+	val = 0;
+	err = sysctl_handle_int(oidp, &val, 0, req);
+	if (err)
+		return (err);
+
+	/* write request */
+	if (val > MAX_OVER_VOLTAGE || val < MIN_OVER_VOLTAGE)
+		return (EINVAL);
+	sc->voltage_sdram = val;
+
+	VC_LOCK(sc);
+	err = bcm2835_cpufreq_set_voltage(sc, BCM2835_MBOX_VOLTAGE_ID_SDRAM_C,
+	    val);
+	if (err == MSG_ERROR) {
+		VC_UNLOCK(sc);
+		device_printf(sc->dev, "set voltage sdram_c error\n");
+		return (EIO);
+	}
+	err = bcm2835_cpufreq_set_voltage(sc, BCM2835_MBOX_VOLTAGE_ID_SDRAM_I,
+	    val);
+	if (err == MSG_ERROR) {
+		VC_UNLOCK(sc);
+		device_printf(sc->dev, "set voltage sdram_i error\n");
+		return (EIO);
+	}
+	err = bcm2835_cpufreq_set_voltage(sc, BCM2835_MBOX_VOLTAGE_ID_SDRAM_P,
+	    val);
+	if (err == MSG_ERROR) {
+		VC_UNLOCK(sc);
+		device_printf(sc->dev, "set voltage sdram_p error\n");
+		return (EIO);
+	}
+	VC_UNLOCK(sc);
+	DELAY(TRANSITION_LATENCY);
+
+	return (0);
+}
+
+static int
+sysctl_bcm2835_cpufreq_temperature(SYSCTL_HANDLER_ARGS)
+{
+	struct bcm2835_cpufreq_softc *sc = arg1;
+	int val;
+	int err;
+
+	/* get realtime value */
+	VC_LOCK(sc);
+	val = bcm2835_cpufreq_get_temperature(sc);
+	VC_UNLOCK(sc);
+	if (val == MSG_ERROR)
+		return (EIO);
+
+	err = sysctl_handle_int(oidp, &val, 0, req);
+	if (err || !req->newptr) /* error || read request */
+		return (err);
+
+	/* write request */
+	return (EINVAL);
+}
+
+static int
+sysctl_bcm2835_devcpu_temperature(SYSCTL_HANDLER_ARGS)
+{
+	struct bcm2835_cpufreq_softc *sc = arg1;
+	int val;
+	int err;
+
+	/* get realtime value */
+	VC_LOCK(sc);
+	val = bcm2835_cpufreq_get_temperature(sc);
+	VC_UNLOCK(sc);
+	if (val == MSG_ERROR)
+		return (EIO);
+
+	/* 1/1000 celsius (raw) to 1/10 kelvin */
+	val = val / 100 + TZ_ZEROC;
+
+	err = sysctl_handle_int(oidp, &val, 0, req);
+	if (err || !req->newptr) /* error || read request */
+		return (err);
+
+	/* write request */
+	return (EINVAL);
+}
+
+
+static void
+bcm2835_cpufreq_init(void *arg)
+{
+	struct bcm2835_cpufreq_softc *sc = arg;
+	struct sysctl_ctx_list *ctx;
+	device_t cpu;
+	int arm_freq, core_freq, sdram_freq;
+	int arm_max_freq, arm_min_freq, core_max_freq, core_min_freq;
+	int sdram_max_freq, sdram_min_freq;
+	int voltage_core, voltage_sdram_c, voltage_sdram_i, voltage_sdram_p;
+	int max_voltage_core, min_voltage_core;
+	int max_voltage_sdram_c, min_voltage_sdram_c;
+	int max_voltage_sdram_i, min_voltage_sdram_i;
+	int max_voltage_sdram_p, min_voltage_sdram_p;
+	int turbo, temperature;
+
+	VC_LOCK(sc);
+
+	/* current clock */
+	arm_freq = bcm2835_cpufreq_get_clock_rate(sc,
+	    BCM2835_MBOX_CLOCK_ID_ARM);
+	core_freq = bcm2835_cpufreq_get_clock_rate(sc,
+	    BCM2835_MBOX_CLOCK_ID_CORE);
+	sdram_freq = bcm2835_cpufreq_get_clock_rate(sc,
+	    BCM2835_MBOX_CLOCK_ID_SDRAM);
+
+	/* max/min clock */
+	arm_max_freq = bcm2835_cpufreq_get_max_clock_rate(sc,
+	    BCM2835_MBOX_CLOCK_ID_ARM);
+	arm_min_freq = bcm2835_cpufreq_get_min_clock_rate(sc,
+	    BCM2835_MBOX_CLOCK_ID_ARM);
+	core_max_freq = bcm2835_cpufreq_get_max_clock_rate(sc,
+	    BCM2835_MBOX_CLOCK_ID_CORE);
+	core_min_freq = bcm2835_cpufreq_get_min_clock_rate(sc,
+	    BCM2835_MBOX_CLOCK_ID_CORE);
+	sdram_max_freq = bcm2835_cpufreq_get_max_clock_rate(sc,
+	    BCM2835_MBOX_CLOCK_ID_SDRAM);
+	sdram_min_freq = bcm2835_cpufreq_get_min_clock_rate(sc,
+	    BCM2835_MBOX_CLOCK_ID_SDRAM);
+
+	/* turbo mode */
+	turbo = bcm2835_cpufreq_get_turbo(sc);
+	if (turbo > 0)
+		sc->turbo_mode = BCM2835_MBOX_TURBO_ON;
+	else
+		sc->turbo_mode = BCM2835_MBOX_TURBO_OFF;
+
+	/* voltage */
+	voltage_core = bcm2835_cpufreq_get_voltage(sc,
+	    BCM2835_MBOX_VOLTAGE_ID_CORE);
+	voltage_sdram_c = bcm2835_cpufreq_get_voltage(sc,
+	    BCM2835_MBOX_VOLTAGE_ID_SDRAM_C);
+	voltage_sdram_i = bcm2835_cpufreq_get_voltage(sc,
+	    BCM2835_MBOX_VOLTAGE_ID_SDRAM_I);
+	voltage_sdram_p = bcm2835_cpufreq_get_voltage(sc,
+	    BCM2835_MBOX_VOLTAGE_ID_SDRAM_P);
+
+	/* current values (offset from 1.2V) */
+	sc->voltage_core = voltage_core;
+	sc->voltage_sdram = voltage_sdram_c;
+	sc->voltage_sdram_c = voltage_sdram_c;
+	sc->voltage_sdram_i = voltage_sdram_i;
+	sc->voltage_sdram_p = voltage_sdram_p;
+
+	/* max/min voltage */
+	max_voltage_core = bcm2835_cpufreq_get_max_voltage(sc,
+	    BCM2835_MBOX_VOLTAGE_ID_CORE);
+	min_voltage_core = bcm2835_cpufreq_get_min_voltage(sc,
+	    BCM2835_MBOX_VOLTAGE_ID_CORE);
+	max_voltage_sdram_c = bcm2835_cpufreq_get_max_voltage(sc,
+	    BCM2835_MBOX_VOLTAGE_ID_SDRAM_C);
+	max_voltage_sdram_i = bcm2835_cpufreq_get_max_voltage(sc,
+	    BCM2835_MBOX_VOLTAGE_ID_SDRAM_I);
+	max_voltage_sdram_p = bcm2835_cpufreq_get_max_voltage(sc,
+	    BCM2835_MBOX_VOLTAGE_ID_SDRAM_P);
+	min_voltage_sdram_c = bcm2835_cpufreq_get_min_voltage(sc,
+	    BCM2835_MBOX_VOLTAGE_ID_SDRAM_C);
+	min_voltage_sdram_i = bcm2835_cpufreq_get_min_voltage(sc,
+	    BCM2835_MBOX_VOLTAGE_ID_SDRAM_I);
+	min_voltage_sdram_p = bcm2835_cpufreq_get_min_voltage(sc,
+	    BCM2835_MBOX_VOLTAGE_ID_SDRAM_P);
+
+	/* temperature */
+	temperature = bcm2835_cpufreq_get_temperature(sc);
+
+	/* show result */
+	if (cpufreq_verbose || bootverbose) {
+		device_printf(sc->dev, "Boot settings:\n");
+		device_printf(sc->dev,
+		    "current ARM %dMHz, Core %dMHz, SDRAM %dMHz, Turbo %s\n",
+		    HZ2MHZ(arm_freq), HZ2MHZ(core_freq), HZ2MHZ(sdram_freq),
+		    (sc->turbo_mode == BCM2835_MBOX_TURBO_ON) ? "ON" : "OFF");
+
+		device_printf(sc->dev,
+		    "max/min ARM %d/%dMHz, Core %d/%dMHz, SDRAM %d/%dMHz\n",
+		    HZ2MHZ(arm_max_freq), HZ2MHZ(arm_min_freq),
+		    HZ2MHZ(core_max_freq), HZ2MHZ(core_min_freq),
+		    HZ2MHZ(sdram_max_freq), HZ2MHZ(sdram_min_freq));
+
+		device_printf(sc->dev,
+		    "current Core %dmV, SDRAM_C %dmV, SDRAM_I %dmV, "
+		    "SDRAM_P %dmV\n",
+		    OFFSET2MVOLT(voltage_core), OFFSET2MVOLT(voltage_sdram_c),
+		    OFFSET2MVOLT(voltage_sdram_i), 
+		    OFFSET2MVOLT(voltage_sdram_p));
+
+		device_printf(sc->dev,
+		    "max/min Core %d/%dmV, SDRAM_C %d/%dmV, SDRAM_I %d/%dmV, "
+		    "SDRAM_P %d/%dmV\n",
+		    OFFSET2MVOLT(max_voltage_core),
+		    OFFSET2MVOLT(min_voltage_core),
+		    OFFSET2MVOLT(max_voltage_sdram_c),
+		    OFFSET2MVOLT(min_voltage_sdram_c),
+		    OFFSET2MVOLT(max_voltage_sdram_i),
+		    OFFSET2MVOLT(min_voltage_sdram_i),
+		    OFFSET2MVOLT(max_voltage_sdram_p),
+		    OFFSET2MVOLT(min_voltage_sdram_p));
+
+		device_printf(sc->dev,
+		    "Temperature %d.%dC\n", (temperature / 1000),
+		    (temperature % 1000) / 100);
+	} else { /* !cpufreq_verbose && !bootverbose */
+		device_printf(sc->dev,
+		    "ARM %dMHz, Core %dMHz, SDRAM %dMHz, Turbo %s\n",
+		    HZ2MHZ(arm_freq), HZ2MHZ(core_freq), HZ2MHZ(sdram_freq),
+		    (sc->turbo_mode == BCM2835_MBOX_TURBO_ON) ? "ON" : "OFF");
+	}
+
+	/* keep in softc (MHz/mV) */
+	sc->arm_max_freq = HZ2MHZ(arm_max_freq);
+	sc->arm_min_freq = HZ2MHZ(arm_min_freq);
+	sc->core_max_freq = HZ2MHZ(core_max_freq);
+	sc->core_min_freq = HZ2MHZ(core_min_freq);
+	sc->sdram_max_freq = HZ2MHZ(sdram_max_freq);
+	sc->sdram_min_freq = HZ2MHZ(sdram_min_freq);
+	sc->max_voltage_core = OFFSET2MVOLT(max_voltage_core);
+	sc->min_voltage_core = OFFSET2MVOLT(min_voltage_core);
+
+	/* if turbo is on, set to max values */
+	if (sc->turbo_mode == BCM2835_MBOX_TURBO_ON) {
+		bcm2835_cpufreq_set_clock_rate(sc, BCM2835_MBOX_CLOCK_ID_ARM,
+		    arm_max_freq);
+		DELAY(TRANSITION_LATENCY);
+		bcm2835_cpufreq_set_clock_rate(sc, BCM2835_MBOX_CLOCK_ID_CORE,
+		    core_max_freq);
+		DELAY(TRANSITION_LATENCY);
+		bcm2835_cpufreq_set_clock_rate(sc,
+		    BCM2835_MBOX_CLOCK_ID_SDRAM, sdram_max_freq);
+		DELAY(TRANSITION_LATENCY);
+	} else {
+		bcm2835_cpufreq_set_clock_rate(sc, BCM2835_MBOX_CLOCK_ID_ARM,
+		    arm_min_freq);
+		DELAY(TRANSITION_LATENCY);
+		bcm2835_cpufreq_set_clock_rate(sc, BCM2835_MBOX_CLOCK_ID_CORE,
+		    core_min_freq);
+		DELAY(TRANSITION_LATENCY);
+		bcm2835_cpufreq_set_clock_rate(sc,
+		    BCM2835_MBOX_CLOCK_ID_SDRAM, sdram_min_freq);
+		DELAY(TRANSITION_LATENCY);
+	}
+
+	VC_UNLOCK(sc);
+
+	/* add human readable temperature to dev.cpu node */
+	cpu = device_get_parent(sc->dev);
+	if (cpu != NULL) {
+		ctx = device_get_sysctl_ctx(cpu);
+		SYSCTL_ADD_PROC(ctx,
+		    SYSCTL_CHILDREN(device_get_sysctl_tree(cpu)), OID_AUTO,
+		    "temperature", CTLTYPE_INT | CTLFLAG_RD, sc, 0,
+		    sysctl_bcm2835_devcpu_temperature, "IK",
+		    "Current SoC temperature");
+	}
+
+	/* release this hook (continue boot) */
+	config_intrhook_disestablish(&sc->init_hook);
+}
+
+static void
+bcm2835_cpufreq_identify(driver_t *driver, device_t parent)
+{
+	const struct ofw_compat_data *compat;
+	phandle_t root;
+
+	root = OF_finddevice("/");
+	for (compat = compat_data; compat->ocd_str != NULL; compat++)
+		if (fdt_is_compatible(root, compat->ocd_str))
+			break;
+
+	if (compat->ocd_data == 0)
+		return;
+
+	DPRINTF("driver=%p, parent=%p\n", driver, parent);
+	if (device_find_child(parent, "bcm2835_cpufreq", -1) != NULL)
+		return;
+	if (BUS_ADD_CHILD(parent, 0, "bcm2835_cpufreq", -1) == NULL)
+		device_printf(parent, "add child failed\n");
+}
+
+static int
+bcm2835_cpufreq_probe(device_t dev)
+{
+
+	device_set_desc(dev, "CPU Frequency Control");
+	return (0);
+}
+
+static int
+bcm2835_cpufreq_attach(device_t dev)
+{
+	struct bcm2835_cpufreq_softc *sc;
+	struct sysctl_oid *oid;
+
+	/* set self dev */
+	sc = device_get_softc(dev);
+	sc->dev = dev;
+
+	/* initial values */
+	sc->arm_max_freq = -1;
+	sc->arm_min_freq = -1;
+	sc->core_max_freq = -1;
+	sc->core_min_freq = -1;
+	sc->sdram_max_freq = -1;
+	sc->sdram_min_freq = -1;
+	sc->max_voltage_core = 0;
+	sc->min_voltage_core = 0;
+
+	/* setup sysctl at first device */
+	if (device_get_unit(dev) == 0) {
+		sysctl_ctx_init(&bcm2835_sysctl_ctx);
+		/* create node for hw.cpufreq */
+		oid = SYSCTL_ADD_NODE(&bcm2835_sysctl_ctx,
+		    SYSCTL_STATIC_CHILDREN(_hw), OID_AUTO, "cpufreq",
+		    CTLFLAG_RD, NULL, "");
+
+		/* Frequency (Hz) */
+		SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
+		    OID_AUTO, "arm_freq", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
+		    sysctl_bcm2835_cpufreq_arm_freq, "IU",
+		    "ARM frequency (Hz)");
+		SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
+		    OID_AUTO, "core_freq", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
+		    sysctl_bcm2835_cpufreq_core_freq, "IU",
+		    "Core frequency (Hz)");
+		SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
+		    OID_AUTO, "sdram_freq", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
+		    sysctl_bcm2835_cpufreq_sdram_freq, "IU",
+		    "SDRAM frequency (Hz)");
+
+		/* Turbo state */
+		SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
+		    OID_AUTO, "turbo", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
+		    sysctl_bcm2835_cpufreq_turbo, "IU",
+		    "Disables dynamic clocking");
+
+		/* Voltage (offset from 1.2V in units of 0.025V) */
+		SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
+		    OID_AUTO, "voltage_core", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
+		    sysctl_bcm2835_cpufreq_voltage_core, "I",
+		    "ARM/GPU core voltage"
+		    "(offset from 1.2V in units of 0.025V)");
+		SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
+		    OID_AUTO, "voltage_sdram", CTLTYPE_INT | CTLFLAG_WR, sc,
+		    0, sysctl_bcm2835_cpufreq_voltage_sdram, "I",
+		    "SDRAM voltage (offset from 1.2V in units of 0.025V)");
+
+		/* Voltage individual SDRAM */
+		SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
+		    OID_AUTO, "voltage_sdram_c", CTLTYPE_INT | CTLFLAG_RW, sc,
+		    0, sysctl_bcm2835_cpufreq_voltage_sdram_c, "I",
+		    "SDRAM controller voltage"
+		    "(offset from 1.2V in units of 0.025V)");
+		SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
+		    OID_AUTO, "voltage_sdram_i", CTLTYPE_INT | CTLFLAG_RW, sc,
+		    0, sysctl_bcm2835_cpufreq_voltage_sdram_i, "I",
+		    "SDRAM I/O voltage (offset from 1.2V in units of 0.025V)");
+		SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
+		    OID_AUTO, "voltage_sdram_p", CTLTYPE_INT | CTLFLAG_RW, sc,
+		    0, sysctl_bcm2835_cpufreq_voltage_sdram_p, "I",
+		    "SDRAM phy voltage (offset from 1.2V in units of 0.025V)");
+
+		/* Temperature */
+		SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
+		    OID_AUTO, "temperature", CTLTYPE_INT | CTLFLAG_RD, sc, 0,
+		    sysctl_bcm2835_cpufreq_temperature, "I",
+		    "SoC temperature (thousandths of a degree C)");
+	}
+
+	/* ARM->VC lock */
+	sema_init(&vc_sema, 1, "vcsema");
+
+	/* register callback for using mbox when interrupts are enabled */
+	sc->init_hook.ich_func = bcm2835_cpufreq_init;
+	sc->init_hook.ich_arg = sc;
+
+	if (config_intrhook_establish(&sc->init_hook) != 0) {
+		device_printf(dev, "config_intrhook_establish failed\n");
+		return (ENOMEM);
+	}
+
+	/* this device is controlled by cpufreq(4) */
+	cpufreq_register(dev);
+
+	return (0);
+}
+
+static int
+bcm2835_cpufreq_detach(device_t dev)
+{
+	struct bcm2835_cpufreq_softc *sc;
+
+	sc = device_get_softc(dev);
+
+	sema_destroy(&vc_sema);
+
+	return (cpufreq_unregister(dev));
+}
+
+static int
+bcm2835_cpufreq_set(device_t dev, const struct cf_setting *cf)
+{
+	struct bcm2835_cpufreq_softc *sc;
+	uint32_t rate_hz, rem;
+	int cur_freq, resp_freq, arm_freq, min_freq, core_freq;
+
+	if (cf == NULL || cf->freq < 0)
+		return (EINVAL);
+
+	sc = device_get_softc(dev);
+
+	/* setting clock (Hz) */
+	rate_hz = (uint32_t)MHZ2HZ(cf->freq);
+	rem = rate_hz % HZSTEP;
+	rate_hz -= rem;
+	if (rate_hz == 0)
+		return (EINVAL);
+
+	/* adjust min freq */
+	min_freq = sc->arm_min_freq;
+	if (sc->turbo_mode != BCM2835_MBOX_TURBO_ON)
+		if (min_freq > cpufreq_lowest_freq)
+			min_freq = cpufreq_lowest_freq;
+
+	if (rate_hz < MHZ2HZ(min_freq) || rate_hz > MHZ2HZ(sc->arm_max_freq))
+		return (EINVAL);
+
+	/* set new value and verify it */
+	VC_LOCK(sc);
+	cur_freq = bcm2835_cpufreq_get_clock_rate(sc,
+	    BCM2835_MBOX_CLOCK_ID_ARM);
+	resp_freq = bcm2835_cpufreq_set_clock_rate(sc,
+	    BCM2835_MBOX_CLOCK_ID_ARM, rate_hz);
+	DELAY(TRANSITION_LATENCY);
+	arm_freq = bcm2835_cpufreq_get_clock_rate(sc,
+	    BCM2835_MBOX_CLOCK_ID_ARM);
+
+	/*
+	 * if non-turbo and lower than or equal min_freq,
+	 * clock down core and sdram to default first.
+	 */
+	if (sc->turbo_mode != BCM2835_MBOX_TURBO_ON) {
+		core_freq = bcm2835_cpufreq_get_clock_rate(sc,
+		    BCM2835_MBOX_CLOCK_ID_CORE);
+		if (rate_hz > MHZ2HZ(sc->arm_min_freq)) {
+			bcm2835_cpufreq_set_clock_rate(sc,
+			    BCM2835_MBOX_CLOCK_ID_CORE,
+			    MHZ2HZ(sc->core_max_freq));
+			DELAY(TRANSITION_LATENCY);
+			bcm2835_cpufreq_set_clock_rate(sc,
+			    BCM2835_MBOX_CLOCK_ID_SDRAM,
+			    MHZ2HZ(sc->sdram_max_freq));
+			DELAY(TRANSITION_LATENCY);
+		} else {
+			if (sc->core_min_freq < DEFAULT_CORE_FREQUENCY &&
+			    core_freq > DEFAULT_CORE_FREQUENCY) {
+				/* first, down to 250, then down to min */
+				DELAY(TRANSITION_LATENCY);
+				bcm2835_cpufreq_set_clock_rate(sc,
+				    BCM2835_MBOX_CLOCK_ID_CORE,
+				    MHZ2HZ(DEFAULT_CORE_FREQUENCY));
+				DELAY(TRANSITION_LATENCY);
+				/* reset core voltage */
+				bcm2835_cpufreq_set_voltage(sc,
+				    BCM2835_MBOX_VOLTAGE_ID_CORE, 0);
+				DELAY(TRANSITION_LATENCY);
+			}
+			bcm2835_cpufreq_set_clock_rate(sc,
+			    BCM2835_MBOX_CLOCK_ID_CORE,
+			    MHZ2HZ(sc->core_min_freq));
+			DELAY(TRANSITION_LATENCY);
+			bcm2835_cpufreq_set_clock_rate(sc,
+			    BCM2835_MBOX_CLOCK_ID_SDRAM,
+			    MHZ2HZ(sc->sdram_min_freq));
+			DELAY(TRANSITION_LATENCY);
+		}
+	}
+
+	VC_UNLOCK(sc);
+
+	if (resp_freq < 0 || arm_freq < 0 || resp_freq != arm_freq) {
+		device_printf(dev, "wrong freq\n");
+		return (EIO);
+	}
+	DPRINTF("cpufreq: %d -> %d\n", cur_freq, arm_freq);
+
+	return (0);
+}
+
+static int
+bcm2835_cpufreq_get(device_t dev, struct cf_setting *cf)
+{
+	struct bcm2835_cpufreq_softc *sc;
+	int arm_freq;
+
+	if (cf == NULL)
+		return (EINVAL);
+
+	sc = device_get_softc(dev);
+	memset(cf, CPUFREQ_VAL_UNKNOWN, sizeof(*cf));
+	cf->dev = NULL;
+
+	/* get cuurent value */
+	VC_LOCK(sc);
+	arm_freq = bcm2835_cpufreq_get_clock_rate(sc,
+	    BCM2835_MBOX_CLOCK_ID_ARM);
+	VC_UNLOCK(sc);
+	if (arm_freq < 0) {
+		device_printf(dev, "can't get clock\n");
+		return (EINVAL);
+	}
+
+	/* CPU clock in MHz or 100ths of a percent. */
+	cf->freq = HZ2MHZ(arm_freq);
+	/* Voltage in mV. */
+	cf->volts = CPUFREQ_VAL_UNKNOWN;
+	/* Power consumed in mW. */
+	cf->power = CPUFREQ_VAL_UNKNOWN;
+	/* Transition latency in us. */
+	cf->lat = TRANSITION_LATENCY;
+	/* Driver providing this setting. */
+	cf->dev = dev;
+
+	return (0);
+}
+
+static int
+bcm2835_cpufreq_make_freq_list(device_t dev, struct cf_setting *sets,
+    int *count)
+{
+	struct bcm2835_cpufreq_softc *sc;
+	int freq, min_freq, volts, rem;
+	int idx;
+
+	sc = device_get_softc(dev);
+	freq = sc->arm_max_freq;
+	min_freq = sc->arm_min_freq;
+
+	/* adjust head freq to STEP */
+	rem = freq % MHZSTEP;
+	freq -= rem;
+	if (freq < min_freq)
+		freq = min_freq;
+
+	/* if non-turbo, add extra low freq */
+	if (sc->turbo_mode != BCM2835_MBOX_TURBO_ON)
+		if (min_freq > cpufreq_lowest_freq)
+			min_freq = cpufreq_lowest_freq;
+
+	/* from freq to min_freq */
+	for (idx = 0; idx < *count && freq >= min_freq; idx++) {
+		if (freq > sc->arm_min_freq)
+			volts = sc->max_voltage_core;
+		else
+			volts = sc->min_voltage_core;
+		sets[idx].freq = freq;
+		sets[idx].volts = volts;
+		sets[idx].lat = TRANSITION_LATENCY;
+		sets[idx].dev = dev;
+		freq -= MHZSTEP;
+	}
+	*count = ++idx;
+
+	return (0);
+}
+
+static int
+bcm2835_cpufreq_settings(device_t dev, struct cf_setting *sets, int *count)
+{
+	struct bcm2835_cpufreq_softc *sc;
+
+	if (sets == NULL || count == NULL)
+		return (EINVAL);
+
+	sc = device_get_softc(dev);
+	if (sc->arm_min_freq < 0 || sc->arm_max_freq < 0) {
+		printf("device is not configured\n");
+		return (EINVAL);
+	}
+
+	/* fill data with unknown value */
+	memset(sets, CPUFREQ_VAL_UNKNOWN, sizeof(*sets) * (*count));
+	/* create new array up to count */
+	bcm2835_cpufreq_make_freq_list(dev, sets, count);
+
+	return (0);
+}
+
+static int
+bcm2835_cpufreq_type(device_t dev, int *type)
+{
+
+	if (type == NULL)
+		return (EINVAL);
+	*type = CPUFREQ_TYPE_ABSOLUTE;
+
+	return (0);
+}
+
+static device_method_t bcm2835_cpufreq_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_identify,	bcm2835_cpufreq_identify),
+	DEVMETHOD(device_probe,		bcm2835_cpufreq_probe),
+	DEVMETHOD(device_attach,	bcm2835_cpufreq_attach),
+	DEVMETHOD(device_detach,	bcm2835_cpufreq_detach),
+
+	/* cpufreq interface */
+	DEVMETHOD(cpufreq_drv_set,	bcm2835_cpufreq_set),
+	DEVMETHOD(cpufreq_drv_get,	bcm2835_cpufreq_get),
+	DEVMETHOD(cpufreq_drv_settings,	bcm2835_cpufreq_settings),
+	DEVMETHOD(cpufreq_drv_type,	bcm2835_cpufreq_type),
+
+	DEVMETHOD_END
+};
+
+static devclass_t bcm2835_cpufreq_devclass;
+static driver_t bcm2835_cpufreq_driver = {
+	"bcm2835_cpufreq",
+	bcm2835_cpufreq_methods,
+	sizeof(struct bcm2835_cpufreq_softc),
+};
+
+DRIVER_MODULE(bcm2835_cpufreq, cpu, bcm2835_cpufreq_driver,
+    bcm2835_cpufreq_devclass, 0, 0);


Property changes on: trunk/sys/arm/broadcom/bcm2835/bcm2835_cpufreq.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/broadcom/bcm2835/bcm2835_dma.c
===================================================================
--- trunk/sys/arm/broadcom/bcm2835/bcm2835_dma.c	                        (rev 0)
+++ trunk/sys/arm/broadcom/bcm2835/bcm2835_dma.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,773 @@
+/* $MidnightBSD$ */
+/*
+ * Copyright (c) 2013 Daisuke Aoyama <aoyama at peach.ne.jp>
+ * Copyright (c) 2013 Oleksandr Tymoshenko <gonzo at bluezbox.com>
+ *
+ * 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: stable/10/sys/arm/broadcom/bcm2835/bcm2835_dma.c 322724 2017-08-20 16:52:27Z marius $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/queue.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+
+#include "bcm2835_dma.h"
+#include "bcm2835_vcbus.h"
+
+#define	MAX_REG			9
+
+/* private flags */
+#define	BCM_DMA_CH_USED		0x00000001
+#define	BCM_DMA_CH_FREE		0x40000000
+#define	BCM_DMA_CH_UNMAP	0x80000000
+
+/* Register Map (4.2.1.2) */
+#define	BCM_DMA_CS(n)		(0x100*(n) + 0x00)
+#define		CS_ACTIVE		(1 <<  0)
+#define		CS_END			(1 <<  1)
+#define		CS_INT			(1 <<  2)
+#define		CS_DREQ			(1 <<  3)
+#define		CS_ISPAUSED		(1 <<  4)
+#define		CS_ISHELD		(1 <<  5)
+#define		CS_ISWAIT		(1 <<  6)
+#define		CS_ERR			(1 <<  8)
+#define		CS_WAITWRT		(1 << 28)
+#define		CS_DISDBG		(1 << 29)
+#define		CS_ABORT		(1 << 30)
+#define		CS_RESET		(1U << 31)
+#define	BCM_DMA_CBADDR(n)	(0x100*(n) + 0x04)
+#define	BCM_DMA_INFO(n)		(0x100*(n) + 0x08)
+#define		INFO_INT_EN		(1 << 0)
+#define		INFO_TDMODE		(1 << 1)
+#define		INFO_WAIT_RESP		(1 << 3)
+#define		INFO_D_INC		(1 << 4)
+#define		INFO_D_WIDTH		(1 << 5)
+#define		INFO_D_DREQ		(1 << 6)
+#define		INFO_S_INC		(1 << 8)
+#define		INFO_S_WIDTH		(1 << 9)
+#define		INFO_S_DREQ		(1 << 10)
+#define		INFO_WAITS_SHIFT	(21)
+#define		INFO_PERMAP_SHIFT	(16)
+#define		INFO_PERMAP_MASK	(0x1f << INFO_PERMAP_SHIFT)
+
+#define	BCM_DMA_SRC(n)		(0x100*(n) + 0x0C)
+#define	BCM_DMA_DST(n)		(0x100*(n) + 0x10)
+#define	BCM_DMA_LEN(n)		(0x100*(n) + 0x14)
+#define	BCM_DMA_STRIDE(n)	(0x100*(n) + 0x18)
+#define	BCM_DMA_CBNEXT(n)	(0x100*(n) + 0x1C)
+#define	BCM_DMA_DEBUG(n)	(0x100*(n) + 0x20)
+#define		DEBUG_ERROR_MASK	(7)
+
+#define	BCM_DMA_INT_STATUS	0xfe0
+#define	BCM_DMA_ENABLE		0xff0
+
+/* relative offset from BCM_VC_DMA0_BASE (p.39) */
+#define	BCM_DMA_CH(n)		(0x100*(n))
+
+/* channels used by GPU */
+#define	BCM_DMA_CH_BULK		0
+#define	BCM_DMA_CH_FAST1	2
+#define	BCM_DMA_CH_FAST2	3
+
+#define	BCM_DMA_CH_GPU_MASK	((1 << BCM_DMA_CH_BULK) |	\
+				 (1 << BCM_DMA_CH_FAST1) |	\
+				 (1 << BCM_DMA_CH_FAST2))
+
+/* DMA Control Block - 256bit aligned (p.40) */
+struct bcm_dma_cb {
+	uint32_t info;		/* Transfer Information */
+	uint32_t src;		/* Source Address */
+	uint32_t dst;		/* Destination Address */
+	uint32_t len;		/* Transfer Length */
+	uint32_t stride;	/* 2D Mode Stride */
+	uint32_t next;		/* Next Control Block Address */
+	uint32_t rsvd1;		/* Reserved */
+	uint32_t rsvd2;		/* Reserved */
+};
+
+#ifdef DEBUG
+static void bcm_dma_cb_dump(struct bcm_dma_cb *cb);
+static void bcm_dma_reg_dump(int ch);
+#endif
+
+/* DMA channel private info */
+struct bcm_dma_ch {
+	int			ch;
+	uint32_t		flags;
+	struct bcm_dma_cb *	cb;
+	uint32_t		vc_cb;
+	bus_dmamap_t		dma_map;
+	void 			(*intr_func)(int, void *);
+	void *			intr_arg;
+};
+
+struct bcm_dma_softc {
+	device_t		sc_dev;
+	struct mtx		sc_mtx;
+	struct resource *	sc_mem;
+	struct resource *	sc_irq[BCM_DMA_CH_MAX];
+	void *			sc_intrhand[BCM_DMA_CH_MAX];
+	struct bcm_dma_ch	sc_dma_ch[BCM_DMA_CH_MAX];
+	bus_dma_tag_t		sc_dma_tag;
+};
+
+static struct bcm_dma_softc *bcm_dma_sc = NULL;
+static uint32_t bcm_dma_channel_mask;
+
+static struct ofw_compat_data compat_data[] = {
+	{"broadcom,bcm2835-dma",	1},
+	{"brcm,bcm2835-dma",		1},
+	{NULL,				0}
+};
+
+static void
+bcm_dmamap_cb(void *arg, bus_dma_segment_t *segs,
+	int nseg, int err)
+{
+        bus_addr_t *addr;
+
+        if (err)
+                return;
+
+        addr = (bus_addr_t*)arg;
+        *addr = PHYS_TO_VCBUS(segs[0].ds_addr);
+}
+
+static void
+bcm_dma_reset(device_t dev, int ch)
+{
+	struct bcm_dma_softc *sc = device_get_softc(dev);
+	struct bcm_dma_cb *cb;
+	uint32_t cs;
+	int count;
+
+	if (ch < 0 || ch >= BCM_DMA_CH_MAX)
+		return;
+
+	cs = bus_read_4(sc->sc_mem, BCM_DMA_CS(ch));
+
+	if (cs & CS_ACTIVE) {
+		/* pause current task */
+		bus_write_4(sc->sc_mem, BCM_DMA_CS(ch), 0);
+
+		count = 1000;
+		do {
+			cs = bus_read_4(sc->sc_mem, BCM_DMA_CS(ch));
+		} while (!(cs & CS_ISPAUSED) && (count-- > 0));
+
+		if (!(cs & CS_ISPAUSED)) {
+			device_printf(dev,
+			    "Can't abort DMA transfer at channel %d\n", ch);
+		}
+
+		bus_write_4(sc->sc_mem, BCM_DMA_CBNEXT(ch), 0);
+
+		/* Complete everything, clear interrupt */
+		bus_write_4(sc->sc_mem, BCM_DMA_CS(ch),
+		    CS_ABORT | CS_INT | CS_END| CS_ACTIVE);
+	}
+
+	/* clear control blocks */
+	bus_write_4(sc->sc_mem, BCM_DMA_CBADDR(ch), 0);
+	bus_write_4(sc->sc_mem, BCM_DMA_CBNEXT(ch), 0);
+
+	/* Reset control block */
+	cb = sc->sc_dma_ch[ch].cb;
+	bzero(cb, sizeof(*cb));
+	cb->info = INFO_WAIT_RESP;
+}
+
+static int
+bcm_dma_init(device_t dev)
+{
+	struct bcm_dma_softc *sc = device_get_softc(dev);
+	uint32_t reg;
+	struct bcm_dma_ch *ch;
+	void *cb_virt;
+	vm_paddr_t cb_phys;
+	int err;
+	int i;
+
+	/*
+	 * Only channels set in bcm_dma_channel_mask can be controlled by us.
+	 * The others are out of our control as well as the corresponding bits
+	 * in both BCM_DMA_ENABLE and BCM_DMA_INT_STATUS global registers. As
+	 * these registers are RW ones, there is no safe way how to write only
+	 * the bits which can be controlled by us.
+	 *
+	 * Fortunately, after reset, all channels are enabled in BCM_DMA_ENABLE
+	 * register and all statuses are cleared in BCM_DMA_INT_STATUS one.
+	 * Not touching these registers is a trade off between correct
+	 * initialization which does not count on anything and not messing up
+	 * something we have no control over.
+	 */
+	reg = bus_read_4(sc->sc_mem, BCM_DMA_ENABLE);
+	if ((reg & bcm_dma_channel_mask) != bcm_dma_channel_mask)
+		device_printf(dev, "channels are not enabled\n");
+	reg = bus_read_4(sc->sc_mem, BCM_DMA_INT_STATUS);
+	if ((reg & bcm_dma_channel_mask) != 0)
+		device_printf(dev, "statuses are not cleared\n");
+
+	/* Allocate DMA chunks control blocks */
+	/* p.40 of spec - control block should be 32-bit aligned */
+	err = bus_dma_tag_create(bus_get_dma_tag(dev),
+	    1, 0, BUS_SPACE_MAXADDR_32BIT,
+	    BUS_SPACE_MAXADDR, NULL, NULL,
+	    sizeof(struct bcm_dma_cb), 1,
+	    sizeof(struct bcm_dma_cb),
+	    BUS_DMA_ALLOCNOW, NULL, NULL,
+	    &sc->sc_dma_tag);
+
+	if (err) {
+		device_printf(dev, "failed allocate DMA tag\n");
+		return (err);
+	}
+
+	/* setup initial settings */
+	for (i = 0; i < BCM_DMA_CH_MAX; i++) {
+		ch = &sc->sc_dma_ch[i];
+
+		bzero(ch, sizeof(struct bcm_dma_ch));
+		ch->ch = i;
+		ch->flags = BCM_DMA_CH_UNMAP;
+
+		if ((bcm_dma_channel_mask & (1 << i)) == 0)
+			continue;
+
+		err = bus_dmamem_alloc(sc->sc_dma_tag, &cb_virt,
+		    BUS_DMA_WAITOK | BUS_DMA_COHERENT | BUS_DMA_ZERO,
+		    &ch->dma_map);
+		if (err) {
+			device_printf(dev, "cannot allocate DMA memory\n");
+			break;
+		}
+
+		/* 
+		 * Least alignment for busdma-allocated stuff is cache 
+		 * line size, so just make sure nothing stupid happend
+		 * and we got properly aligned address
+		 */
+		if ((uintptr_t)cb_virt & 0x1f) {
+			device_printf(dev,
+			    "DMA address is not 32-bytes aligned: %p\n",
+			    (void*)cb_virt);
+			break;
+		}
+
+		err = bus_dmamap_load(sc->sc_dma_tag, ch->dma_map, cb_virt,
+		    sizeof(struct bcm_dma_cb), bcm_dmamap_cb, &cb_phys,
+		    BUS_DMA_WAITOK);
+		if (err) {
+			device_printf(dev, "cannot load DMA memory\n");
+			break;
+		}
+
+		ch->cb = cb_virt;
+		ch->vc_cb = cb_phys;
+		ch->flags = BCM_DMA_CH_FREE;
+		ch->cb->info = INFO_WAIT_RESP;
+
+		/* reset DMA engine */
+		bus_write_4(sc->sc_mem, BCM_DMA_CS(i), CS_RESET);
+	}
+
+	return (0);
+}
+
+/*
+ * Allocate DMA channel for further use, returns channel # or
+ *     BCM_DMA_CH_INVALID
+ */
+int
+bcm_dma_allocate(int req_ch)
+{
+	struct bcm_dma_softc *sc = bcm_dma_sc;
+	int ch = BCM_DMA_CH_INVALID;
+	int i;
+
+	if (req_ch >= BCM_DMA_CH_MAX)
+		return (BCM_DMA_CH_INVALID);
+
+	/* Auto(req_ch < 0) or CH specified */
+	mtx_lock(&sc->sc_mtx);
+
+	if (req_ch < 0) {
+		for (i = 0; i < BCM_DMA_CH_MAX; i++) {
+			if (sc->sc_dma_ch[i].flags & BCM_DMA_CH_FREE) {
+				ch = i;
+				sc->sc_dma_ch[ch].flags &= ~BCM_DMA_CH_FREE;
+				sc->sc_dma_ch[ch].flags |= BCM_DMA_CH_USED;
+				break;
+			}
+		}
+	}
+	else {
+		if (sc->sc_dma_ch[req_ch].flags & BCM_DMA_CH_FREE) {
+			ch = req_ch;
+			sc->sc_dma_ch[ch].flags &= ~BCM_DMA_CH_FREE;
+			sc->sc_dma_ch[ch].flags |= BCM_DMA_CH_USED;
+		}
+	}
+
+	mtx_unlock(&sc->sc_mtx);
+	return (ch);
+}
+
+/*
+ * Frees allocated channel. Returns 0 on success, -1 otherwise
+ */
+int
+bcm_dma_free(int ch)
+{
+	struct bcm_dma_softc *sc = bcm_dma_sc;
+
+	if (ch < 0 || ch >= BCM_DMA_CH_MAX)
+		return (-1);
+
+	mtx_lock(&sc->sc_mtx);
+	if (sc->sc_dma_ch[ch].flags & BCM_DMA_CH_USED) {
+		sc->sc_dma_ch[ch].flags |= BCM_DMA_CH_FREE;
+		sc->sc_dma_ch[ch].flags &= ~BCM_DMA_CH_USED;
+		sc->sc_dma_ch[ch].intr_func = NULL;
+		sc->sc_dma_ch[ch].intr_arg = NULL;
+
+		/* reset DMA engine */
+		bcm_dma_reset(sc->sc_dev, ch);
+	}
+
+	mtx_unlock(&sc->sc_mtx);
+	return (0);
+}
+
+/*
+ * Assign handler function for channel interrupt
+ * Returns 0 on success, -1 otherwise
+ */
+int
+bcm_dma_setup_intr(int ch, void (*func)(int, void *), void *arg)
+{
+	struct bcm_dma_softc *sc = bcm_dma_sc;
+	struct bcm_dma_cb *cb;
+
+	if (ch < 0 || ch >= BCM_DMA_CH_MAX)
+		return (-1);
+
+	if (!(sc->sc_dma_ch[ch].flags & BCM_DMA_CH_USED))
+		return (-1);
+
+	sc->sc_dma_ch[ch].intr_func = func;
+	sc->sc_dma_ch[ch].intr_arg = arg;
+	cb = sc->sc_dma_ch[ch].cb;
+	cb->info |= INFO_INT_EN;
+
+	return (0);
+}
+
+/*
+ * Setup DMA source parameters
+ *     ch - channel number
+ *     dreq - hardware DREQ # or BCM_DMA_DREQ_NONE if
+ *         source is physical memory
+ *     inc_addr - BCM_DMA_INC_ADDR if source address
+ *         should be increased after each access or 
+ *         BCM_DMA_SAME_ADDR if address should remain 
+ *         the same
+ *     width - size of read operation, BCM_DMA_32BIT
+ *         for 32bit bursts, BCM_DMA_128BIT for 128 bits
+ *	  
+ * Returns 0 on success, -1 otherwise
+ */
+int
+bcm_dma_setup_src(int ch, int dreq, int inc_addr, int width)
+{
+	struct bcm_dma_softc *sc = bcm_dma_sc;
+	uint32_t info;
+
+	if (ch < 0 || ch >= BCM_DMA_CH_MAX)
+		return (-1);
+
+	if (!(sc->sc_dma_ch[ch].flags & BCM_DMA_CH_USED))
+		return (-1);
+
+	info = sc->sc_dma_ch[ch].cb->info;
+	info &= ~INFO_PERMAP_MASK;
+	info |= (dreq << INFO_PERMAP_SHIFT) & INFO_PERMAP_MASK;
+
+	if (dreq)
+		info |= INFO_S_DREQ;
+	else
+		info &= ~INFO_S_DREQ;
+
+	if (width == BCM_DMA_128BIT)
+		info |= INFO_S_WIDTH;
+	else
+		info &= ~INFO_S_WIDTH;
+
+	if (inc_addr == BCM_DMA_INC_ADDR)
+		info |= INFO_S_INC;
+	else
+		info &= ~INFO_S_INC;
+
+	sc->sc_dma_ch[ch].cb->info = info;
+
+	return (0);
+}
+
+/*
+ * Setup DMA destination parameters
+ *     ch - channel number
+ *     dreq - hardware DREQ # or BCM_DMA_DREQ_NONE if
+ *         destination is physical memory
+ *     inc_addr - BCM_DMA_INC_ADDR if source address
+ *         should be increased after each access or 
+ *         BCM_DMA_SAME_ADDR if address should remain 
+ *         the same
+ *     width - size of write operation, BCM_DMA_32BIT
+ *         for 32bit bursts, BCM_DMA_128BIT for 128 bits
+ *	  
+ * Returns 0 on success, -1 otherwise
+ */
+int
+bcm_dma_setup_dst(int ch, int dreq, int inc_addr, int width)
+{
+	struct bcm_dma_softc *sc = bcm_dma_sc;
+	uint32_t info;
+
+	if (ch < 0 || ch >= BCM_DMA_CH_MAX)
+		return (-1);
+
+	if (!(sc->sc_dma_ch[ch].flags & BCM_DMA_CH_USED))
+		return (-1);
+
+	info = sc->sc_dma_ch[ch].cb->info;
+	info &= ~INFO_PERMAP_MASK;
+	info |= (dreq << INFO_PERMAP_SHIFT) & INFO_PERMAP_MASK;
+
+	if (dreq)
+		info |= INFO_D_DREQ;
+	else
+		info &= ~INFO_D_DREQ;
+
+	if (width == BCM_DMA_128BIT)
+		info |= INFO_D_WIDTH;
+	else
+		info &= ~INFO_D_WIDTH;
+
+	if (inc_addr == BCM_DMA_INC_ADDR)
+		info |= INFO_D_INC;
+	else
+		info &= ~INFO_D_INC;
+
+	sc->sc_dma_ch[ch].cb->info = info;
+
+	return (0);
+}
+
+#ifdef DEBUG
+void
+bcm_dma_cb_dump(struct bcm_dma_cb *cb)
+{
+
+	printf("DMA CB ");
+	printf("INFO: %8.8x ", cb->info);
+	printf("SRC: %8.8x ", cb->src);
+	printf("DST: %8.8x ", cb->dst);
+	printf("LEN: %8.8x ", cb->len);
+	printf("\n");
+	printf("STRIDE: %8.8x ", cb->stride);
+	printf("NEXT: %8.8x ", cb->next);
+	printf("RSVD1: %8.8x ", cb->rsvd1);
+	printf("RSVD2: %8.8x ", cb->rsvd2);
+	printf("\n");
+}
+
+void
+bcm_dma_reg_dump(int ch)
+{
+	struct bcm_dma_softc *sc = bcm_dma_sc;
+	int i;
+	uint32_t reg;
+
+	if (ch < 0 || ch >= BCM_DMA_CH_MAX)
+		return;
+
+	printf("DMA%d: ", ch);
+	for (i = 0; i < MAX_REG; i++) {
+		reg = bus_read_4(sc->sc_mem, BCM_DMA_CH(ch) + i*4);
+		printf("%8.8x ", reg);
+	}
+	printf("\n");
+}
+#endif
+
+/*
+ * Start DMA transaction
+ *     ch - channel number
+ *     src, dst - source and destination address in
+ *         ARM physical memory address space. 
+ *     len - amount of bytes to be transfered
+ *	  
+ * Returns 0 on success, -1 otherwise
+ */
+int
+bcm_dma_start(int ch, vm_paddr_t src, vm_paddr_t dst, int len)
+{
+	struct bcm_dma_softc *sc = bcm_dma_sc;
+	struct bcm_dma_cb *cb;
+
+	if (ch < 0 || ch >= BCM_DMA_CH_MAX)
+		return (-1);
+
+	if (!(sc->sc_dma_ch[ch].flags & BCM_DMA_CH_USED))
+		return (-1);
+
+	cb = sc->sc_dma_ch[ch].cb;
+	if (BCM2835_ARM_IS_IO(src))
+		cb->src = IO_TO_VCBUS(src);
+	else
+		cb->src = PHYS_TO_VCBUS(src);
+	if (BCM2835_ARM_IS_IO(dst))
+		cb->dst = IO_TO_VCBUS(dst);
+	else
+		cb->dst = PHYS_TO_VCBUS(dst);
+	cb->len = len;
+
+	bus_dmamap_sync(sc->sc_dma_tag,
+	    sc->sc_dma_ch[ch].dma_map, BUS_DMASYNC_PREWRITE);
+
+	bus_write_4(sc->sc_mem, BCM_DMA_CBADDR(ch),
+	    sc->sc_dma_ch[ch].vc_cb);
+	bus_write_4(sc->sc_mem, BCM_DMA_CS(ch), CS_ACTIVE);
+
+#ifdef DEBUG
+	bcm_dma_cb_dump(sc->sc_dma_ch[ch].cb);
+	bcm_dma_reg_dump(ch);
+#endif
+
+	return (0);
+}
+
+/*
+ * Get length requested for DMA transaction
+ *     ch - channel number
+ *	  
+ * Returns size of transaction, 0 if channel is invalid
+ */
+uint32_t
+bcm_dma_length(int ch)
+{
+	struct bcm_dma_softc *sc = bcm_dma_sc;
+	struct bcm_dma_cb *cb;
+
+	if (ch < 0 || ch >= BCM_DMA_CH_MAX)
+		return (0);
+
+	if (!(sc->sc_dma_ch[ch].flags & BCM_DMA_CH_USED))
+		return (0);
+
+	cb = sc->sc_dma_ch[ch].cb;
+
+	return (cb->len);
+}
+
+static void
+bcm_dma_intr(void *arg)
+{
+	struct bcm_dma_softc *sc = bcm_dma_sc;
+	struct bcm_dma_ch *ch = (struct bcm_dma_ch *)arg;
+	uint32_t cs, debug;
+
+	/* my interrupt? */
+	cs = bus_read_4(sc->sc_mem, BCM_DMA_CS(ch->ch));
+
+	if (!(cs & (CS_INT | CS_ERR))) {
+		device_printf(sc->sc_dev,
+		    "unexpected DMA intr CH=%d, CS=%x\n", ch->ch, cs);
+		return;
+	}
+
+	/* running? */
+	if (!(ch->flags & BCM_DMA_CH_USED)) {
+		device_printf(sc->sc_dev,
+		    "unused DMA intr CH=%d, CS=%x\n", ch->ch, cs);
+		return;
+	}
+
+	if (cs & CS_ERR) {
+		debug = bus_read_4(sc->sc_mem, BCM_DMA_DEBUG(ch->ch));
+		device_printf(sc->sc_dev, "DMA error %d on CH%d\n",
+			debug & DEBUG_ERROR_MASK, ch->ch);
+		bus_write_4(sc->sc_mem, BCM_DMA_DEBUG(ch->ch), 
+		    debug & DEBUG_ERROR_MASK);
+		bcm_dma_reset(sc->sc_dev, ch->ch);
+	}
+
+	if (cs & CS_INT) {
+		/* acknowledge interrupt */
+		bus_write_4(sc->sc_mem, BCM_DMA_CS(ch->ch), 
+		    CS_INT | CS_END);
+
+		/* Prepare for possible access to len field */
+		bus_dmamap_sync(sc->sc_dma_tag, ch->dma_map,
+		    BUS_DMASYNC_POSTWRITE);
+
+		/* save callback function and argument */
+		if (ch->intr_func)
+			ch->intr_func(ch->ch, ch->intr_arg);
+	}
+}
+
+static int
+bcm_dma_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
+		return (ENXIO);
+
+	device_set_desc(dev, "BCM2835 DMA Controller");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+bcm_dma_attach(device_t dev)
+{
+	struct bcm_dma_softc *sc = device_get_softc(dev);
+	phandle_t node;
+	int rid, err = 0;
+	int i;
+
+	sc->sc_dev = dev;
+
+	if (bcm_dma_sc)
+		return (ENXIO);
+
+	for (i = 0; i < BCM_DMA_CH_MAX; i++) {
+		sc->sc_irq[i] = NULL;
+		sc->sc_intrhand[i] = NULL;
+	}
+
+	/* Get DMA channel mask. */
+	node = ofw_bus_get_node(sc->sc_dev);
+	if (OF_getencprop(node, "brcm,dma-channel-mask", &bcm_dma_channel_mask,
+	    sizeof(bcm_dma_channel_mask)) == -1 &&
+	    OF_getencprop(node, "broadcom,channels", &bcm_dma_channel_mask,
+	    sizeof(bcm_dma_channel_mask)) == -1) {
+		device_printf(dev, "could not get channel mask property\n");
+		return (ENXIO);
+	}
+
+	/* Mask out channels used by GPU. */
+	bcm_dma_channel_mask &= ~BCM_DMA_CH_GPU_MASK;
+
+	/* DMA0 - DMA14 */
+	rid = 0;
+	sc->sc_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
+	if (sc->sc_mem == NULL) {
+		device_printf(dev, "could not allocate memory resource\n");
+		return (ENXIO);
+	}
+
+	/* IRQ DMA0 - DMA11 XXX NOT USE DMA12(spurious?) */
+	for (rid = 0; rid < BCM_DMA_CH_MAX; rid++) {
+		if ((bcm_dma_channel_mask & (1 << rid)) == 0)
+			continue;
+
+		sc->sc_irq[rid] = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+						       RF_ACTIVE);
+		if (sc->sc_irq[rid] == NULL) {
+			device_printf(dev, "cannot allocate interrupt\n");
+			err = ENXIO;
+			goto fail;
+		}
+		if (bus_setup_intr(dev, sc->sc_irq[rid], INTR_TYPE_MISC | INTR_MPSAFE,
+				   NULL, bcm_dma_intr, &sc->sc_dma_ch[rid],
+				   &sc->sc_intrhand[rid])) {
+			device_printf(dev, "cannot setup interrupt handler\n");
+			err = ENXIO;
+			goto fail;
+		}
+	}
+
+	mtx_init(&sc->sc_mtx, "bcmdma", "bcmdma", MTX_DEF);
+	bcm_dma_sc = sc;
+
+	err = bcm_dma_init(dev);
+	if (err)
+		goto fail;
+
+	return (err);
+
+fail:
+	if (sc->sc_mem)
+		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem);
+
+	for (i = 0; i < BCM_DMA_CH_MAX; i++) {
+		if (sc->sc_intrhand[i])
+			bus_teardown_intr(dev, sc->sc_irq[i], sc->sc_intrhand[i]);
+		if (sc->sc_irq[i])
+			bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq[i]);
+	}
+
+	return (err);
+}
+
+static device_method_t bcm_dma_methods[] = {
+	DEVMETHOD(device_probe,		bcm_dma_probe),
+	DEVMETHOD(device_attach,	bcm_dma_attach),
+	{ 0, 0 }
+};
+
+static driver_t bcm_dma_driver = {
+	"bcm_dma",
+	bcm_dma_methods,
+	sizeof(struct bcm_dma_softc),
+};
+
+static devclass_t bcm_dma_devclass;
+
+DRIVER_MODULE(bcm_dma, simplebus, bcm_dma_driver, bcm_dma_devclass, 0, 0);
+MODULE_VERSION(bcm_dma, 1);


Property changes on: trunk/sys/arm/broadcom/bcm2835/bcm2835_dma.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/broadcom/bcm2835/bcm2835_dma.h
===================================================================
--- trunk/sys/arm/broadcom/bcm2835/bcm2835_dma.h	                        (rev 0)
+++ trunk/sys/arm/broadcom/bcm2835/bcm2835_dma.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,61 @@
+/* $MidnightBSD$ */
+/*
+ * Copyright (c) 2013 Daisuke Aoyama <aoyama at peach.ne.jp>
+ * Copyright (c) 2013 Oleksandr Tymoshenko <gonzo at bluezbox.com>
+ *
+ * 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: stable/10/sys/arm/broadcom/bcm2835/bcm2835_dma.h 322724 2017-08-20 16:52:27Z marius $
+ */
+
+#ifndef	_BCM2835_DMA_H_
+#define	_BCM2835_DMA_H_
+
+#define	BCM_DMA_BLOCK_SIZE	512
+
+/* DMA0-DMA15 but DMA15 is special */
+#define	BCM_DMA_CH_MAX		12
+
+/* request CH for any nubmer */
+#define	BCM_DMA_CH_INVALID	(-1)
+#define	BCM_DMA_CH_ANY		(-1)
+
+/* Peripheral DREQ Signals (4.2.1.3) */
+#define	BCM_DMA_DREQ_NONE	0
+#define	BCM_DMA_DREQ_EMMC	11
+#define	BCM_DMA_DREQ_SDHOST	13
+
+#define	BCM_DMA_SAME_ADDR	0
+#define	BCM_DMA_INC_ADDR	1
+
+#define	BCM_DMA_32BIT		0
+#define	BCM_DMA_128BIT		1
+
+int bcm_dma_allocate(int req_ch);
+int bcm_dma_free(int ch);
+int bcm_dma_setup_intr(int ch, void (*func)(int, void *), void *arg);
+int bcm_dma_setup_src(int ch, int dreq, int inc_addr, int width);
+int bcm_dma_setup_dst(int ch, int dreq, int inc_addr, int width);
+int bcm_dma_start(int ch, vm_paddr_t src, vm_paddr_t dst, int len);
+uint32_t bcm_dma_length(int ch);
+
+#endif	/* _BCM2835_DMA_H_ */


Property changes on: trunk/sys/arm/broadcom/bcm2835/bcm2835_dma.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/broadcom/bcm2835/bcm2835_fb.c
===================================================================
--- trunk/sys/arm/broadcom/bcm2835/bcm2835_fb.c	                        (rev 0)
+++ trunk/sys/arm/broadcom/bcm2835/bcm2835_fb.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,871 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Oleksandr Tymoshenko <gonzo at freebsd.org>
+ * 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: stable/10/sys/arm/broadcom/bcm2835/bcm2835_fb.c 322724 2017-08-20 16:52:27Z marius $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/consio.h>
+#include <sys/fbio.h>
+#include <sys/kdb.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <dev/fb/fbreg.h>
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+#include <dev/syscons/syscons.h>
+
+#include <arm/broadcom/bcm2835/bcm2835_mbox_prop.h>
+
+#include "mbox_if.h"
+
+struct argb {
+	uint8_t		a;
+	uint8_t		r;
+	uint8_t		g;
+	uint8_t		b;
+};
+
+static struct argb bcmfb_palette[16] = {
+	{0x00, 0x00, 0x00, 0x00},
+	{0x00, 0x00, 0x00, 0xaa},
+	{0x00, 0x00, 0xaa, 0x00},
+	{0x00, 0x00, 0xaa, 0xaa},
+	{0x00, 0xaa, 0x00, 0x00},
+	{0x00, 0xaa, 0x00, 0xaa},
+	{0x00, 0xaa, 0x55, 0x00},
+	{0x00, 0xaa, 0xaa, 0xaa},
+	{0x00, 0x55, 0x55, 0x55},
+	{0x00, 0x55, 0x55, 0xff},
+	{0x00, 0x55, 0xff, 0x55},
+	{0x00, 0x55, 0xff, 0xff},
+	{0x00, 0xff, 0x55, 0x55},
+	{0x00, 0xff, 0x55, 0xff},
+	{0x00, 0xff, 0xff, 0x55},
+	{0x00, 0xff, 0xff, 0xff}
+};
+
+/* mouse pointer from dev/syscons/scgfbrndr.c */
+static u_char mouse_pointer[16] = {
+        0x00, 0x40, 0x60, 0x70, 0x78, 0x7c, 0x7e, 0x68,
+        0x0c, 0x0c, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00
+};
+
+#define	BCMFB_FONT_HEIGHT	16
+#define	BCMFB_FONT_WIDTH	8
+#define	FB_WIDTH		640
+#define	FB_HEIGHT		480
+#define	FB_DEPTH		24
+
+struct bcmsc_softc {
+	/* Videoadpater part */
+	video_adapter_t	va;
+
+	intptr_t	fb_addr;
+	intptr_t	fb_paddr;
+	unsigned int	fb_size;
+
+	unsigned int	height;
+	unsigned int	width;
+	unsigned int	depth;
+	unsigned int	stride;
+
+	unsigned int	xmargin;
+	unsigned int	ymargin;
+
+	unsigned char	*font;
+	int		fbswap;
+	int		initialized;
+};
+
+static struct bcmsc_softc bcmsc;
+
+static struct ofw_compat_data compat_data[] = {
+	{"broadcom,bcm2835-fb",		1},
+	{"brcm,bcm2708-fb",		1},
+	{NULL,				0}
+};
+
+static int bcm_fb_probe(device_t);
+static int bcm_fb_attach(device_t);
+static void bcmfb_update_margins(video_adapter_t *adp);
+static int bcmfb_configure(int);
+
+static int
+bcm_fb_probe(device_t dev)
+{
+	int error;
+
+	if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
+		return (ENXIO);
+
+	device_set_desc(dev, "BCM2835 framebuffer device");
+	error = sc_probe_unit(device_get_unit(dev), 
+	    device_get_flags(dev) | SC_AUTODETECT_KBD);
+	if (error != 0)
+		return (error);
+
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+bcm_fb_attach(device_t dev)
+{
+	struct bcm2835_fb_config fb;
+	struct bcmsc_softc *sc;
+
+	sc = (struct bcmsc_softc *)vid_get_adapter(vid_find_adapter(
+	    "bcmfb", 0));
+	if (sc != NULL)
+		device_set_softc(dev, sc);
+	else
+		sc = device_get_softc(dev);
+
+	memset(&fb, 0, sizeof(fb));
+	if (bcm2835_mbox_fb_get_w_h(&fb) != 0)
+		return (ENXIO);
+	fb.bpp = FB_DEPTH;
+	fb.vxres = fb.xres;
+	fb.vyres = fb.yres;
+	fb.xoffset = fb.yoffset = 0;
+	if (bcm2835_mbox_fb_init(&fb) != 0)
+		return (ENXIO);
+
+	sc->fb_addr = (intptr_t)pmap_mapdev(fb.base, fb.size);
+	sc->fb_paddr = fb.base;
+	sc->fb_size = fb.size;
+	sc->depth = fb.bpp;
+	sc->stride = fb.pitch;
+	sc->width = fb.xres;
+	sc->height = fb.yres;
+	bcmfb_update_margins(&sc->va);
+
+	if (sc_attach_unit(device_get_unit(dev),
+	    device_get_flags(dev) | SC_AUTODETECT_KBD) != 0) {
+		device_printf(dev, "failed to attach syscons\n");
+		return (ENXIO);
+	}
+
+	device_printf(dev, "%dx%d(%dx%d@%d,%d) %dbpp\n", fb.xres, fb.yres,
+	    fb.vxres, fb.vyres, fb.xoffset, fb.yoffset, fb.bpp);
+	device_printf(dev,
+	    "fbswap: %d, pitch %d, base 0x%08x, screen_size %d\n",
+	    sc->fbswap, fb.pitch, fb.base, fb.size);
+
+	return (0);
+}
+
+static device_method_t bcm_fb_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		bcm_fb_probe),
+	DEVMETHOD(device_attach,	bcm_fb_attach),
+
+	{ 0, 0 }
+};
+
+static devclass_t bcm_fb_devclass;
+
+static driver_t bcm_fb_driver = {
+	"fb",
+	bcm_fb_methods,
+	sizeof(struct bcmsc_softc),
+};
+
+DRIVER_MODULE(bcm2835fb, ofwbus, bcm_fb_driver, bcm_fb_devclass, 0, 0);
+DRIVER_MODULE(bcm2835fb, simplebus, bcm_fb_driver, bcm_fb_devclass, 0, 0);
+
+/*
+ * Video driver routines and glue.
+ */
+static vi_probe_t		bcmfb_probe;
+static vi_init_t		bcmfb_init;
+static vi_get_info_t		bcmfb_get_info;
+static vi_query_mode_t		bcmfb_query_mode;
+static vi_set_mode_t		bcmfb_set_mode;
+static vi_save_font_t		bcmfb_save_font;
+static vi_load_font_t		bcmfb_load_font;
+static vi_show_font_t		bcmfb_show_font;
+static vi_save_palette_t	bcmfb_save_palette;
+static vi_load_palette_t	bcmfb_load_palette;
+static vi_set_border_t		bcmfb_set_border;
+static vi_save_state_t		bcmfb_save_state;
+static vi_load_state_t		bcmfb_load_state;
+static vi_set_win_org_t		bcmfb_set_win_org;
+static vi_read_hw_cursor_t	bcmfb_read_hw_cursor;
+static vi_set_hw_cursor_t	bcmfb_set_hw_cursor;
+static vi_set_hw_cursor_shape_t	bcmfb_set_hw_cursor_shape;
+static vi_blank_display_t	bcmfb_blank_display;
+static vi_mmap_t		bcmfb_mmap;
+static vi_ioctl_t		bcmfb_ioctl;
+static vi_clear_t		bcmfb_clear;
+static vi_fill_rect_t		bcmfb_fill_rect;
+static vi_bitblt_t		bcmfb_bitblt;
+static vi_diag_t		bcmfb_diag;
+static vi_save_cursor_palette_t	bcmfb_save_cursor_palette;
+static vi_load_cursor_palette_t	bcmfb_load_cursor_palette;
+static vi_copy_t		bcmfb_copy;
+static vi_putp_t		bcmfb_putp;
+static vi_putc_t		bcmfb_putc;
+static vi_puts_t		bcmfb_puts;
+static vi_putm_t		bcmfb_putm;
+
+static video_switch_t bcmfbvidsw = {
+	.probe			= bcmfb_probe,
+	.init			= bcmfb_init,
+	.get_info		= bcmfb_get_info,
+	.query_mode		= bcmfb_query_mode,
+	.set_mode		= bcmfb_set_mode,
+	.save_font		= bcmfb_save_font,
+	.load_font		= bcmfb_load_font,
+	.show_font		= bcmfb_show_font,
+	.save_palette		= bcmfb_save_palette,
+	.load_palette		= bcmfb_load_palette,
+	.set_border		= bcmfb_set_border,
+	.save_state		= bcmfb_save_state,
+	.load_state		= bcmfb_load_state,
+	.set_win_org		= bcmfb_set_win_org,
+	.read_hw_cursor		= bcmfb_read_hw_cursor,
+	.set_hw_cursor		= bcmfb_set_hw_cursor,
+	.set_hw_cursor_shape	= bcmfb_set_hw_cursor_shape,
+	.blank_display		= bcmfb_blank_display,
+	.mmap			= bcmfb_mmap,
+	.ioctl			= bcmfb_ioctl,
+	.clear			= bcmfb_clear,
+	.fill_rect		= bcmfb_fill_rect,
+	.bitblt			= bcmfb_bitblt,
+	.diag			= bcmfb_diag,
+	.save_cursor_palette	= bcmfb_save_cursor_palette,
+	.load_cursor_palette	= bcmfb_load_cursor_palette,
+	.copy			= bcmfb_copy,
+	.putp			= bcmfb_putp,
+	.putc			= bcmfb_putc,
+	.puts			= bcmfb_puts,
+	.putm			= bcmfb_putm,
+};
+
+VIDEO_DRIVER(bcmfb, bcmfbvidsw, bcmfb_configure);
+
+static vr_init_t bcmrend_init;
+static vr_clear_t bcmrend_clear;
+static vr_draw_border_t bcmrend_draw_border;
+static vr_draw_t bcmrend_draw;
+static vr_set_cursor_t bcmrend_set_cursor;
+static vr_draw_cursor_t bcmrend_draw_cursor;
+static vr_blink_cursor_t bcmrend_blink_cursor;
+static vr_set_mouse_t bcmrend_set_mouse;
+static vr_draw_mouse_t bcmrend_draw_mouse;
+
+/*
+ * We use our own renderer; this is because we must emulate a hardware
+ * cursor.
+ */
+static sc_rndr_sw_t bcmrend = {
+	bcmrend_init,
+	bcmrend_clear,
+	bcmrend_draw_border,
+	bcmrend_draw,
+	bcmrend_set_cursor,
+	bcmrend_draw_cursor,
+	bcmrend_blink_cursor,
+	bcmrend_set_mouse,
+	bcmrend_draw_mouse
+};
+
+RENDERER(bcmfb, 0, bcmrend, gfb_set);
+RENDERER_MODULE(bcmfb, gfb_set);
+
+static void
+bcmrend_init(scr_stat* scp)
+{
+}
+
+static void
+bcmrend_clear(scr_stat* scp, int c, int attr)
+{
+}
+
+static void
+bcmrend_draw_border(scr_stat* scp, int color)
+{
+}
+
+static void
+bcmrend_draw(scr_stat* scp, int from, int count, int flip)
+{
+	video_adapter_t* adp = scp->sc->adp;
+	int i, c, a;
+
+	if (!flip) {
+		/* Normal printing */
+		vidd_puts(adp, from, (uint16_t*)sc_vtb_pointer(&scp->vtb, from), count);
+	} else {	
+		/* This is for selections and such: invert the color attribute */
+		for (i = count; i-- > 0; ++from) {
+			c = sc_vtb_getc(&scp->vtb, from);
+			a = sc_vtb_geta(&scp->vtb, from) >> 8;
+			vidd_putc(adp, from, c, (a >> 4) | ((a & 0xf) << 4));
+		}
+	}
+}
+
+static void
+bcmrend_set_cursor(scr_stat* scp, int base, int height, int blink)
+{
+}
+
+static void
+bcmrend_draw_cursor(scr_stat* scp, int off, int blink, int on, int flip)
+{
+	int bytes, col, i, j, row;
+	struct bcmsc_softc *sc;
+	uint8_t *addr;
+	video_adapter_t *adp;
+
+	adp = scp->sc->adp;
+	sc = (struct bcmsc_softc *)adp;
+
+	if (scp->curs_attr.height <= 0)
+		return;
+
+	if (sc->fb_addr == 0)
+		return;
+
+	if (off >= adp->va_info.vi_width * adp->va_info.vi_height)
+		return;
+
+	/* calculate the coordinates in the video buffer */
+	row = (off / adp->va_info.vi_width) * adp->va_info.vi_cheight;
+	col = (off % adp->va_info.vi_width) * adp->va_info.vi_cwidth;
+
+	addr = (uint8_t *)sc->fb_addr
+	    + (row + sc->ymargin)*(sc->stride)
+	    + (sc->depth/8) * (col + sc->xmargin);
+
+	bytes = sc->depth / 8;
+	/* our cursor consists of simply inverting the char under it */
+	for (i = 0; i < adp->va_info.vi_cheight; i++) {
+		for (j = 0; j < adp->va_info.vi_cwidth; j++) {
+			switch (sc->depth) {
+			case 32:
+			case 24:
+				addr[bytes*j + 2] ^= 0xff;
+				/* FALLTHROUGH */
+			case 16:
+				addr[bytes*j + 1] ^= 0xff;
+				addr[bytes*j] ^= 0xff;
+				break;
+			default:
+				break;
+			}
+		}
+
+		addr += sc->stride;
+	}
+}
+
+static void
+bcmrend_blink_cursor(scr_stat* scp, int at, int flip)
+{
+}
+
+static void
+bcmrend_set_mouse(scr_stat* scp)
+{
+}
+
+static void
+bcmrend_draw_mouse(scr_stat* scp, int x, int y, int on)
+{
+	vidd_putm(scp->sc->adp, x, y, mouse_pointer, 0xffffffff, 16, 8);
+}
+
+static uint16_t bcmfb_static_window[ROW*COL];
+extern u_char dflt_font_16[];
+
+/*
+ * Update videoadapter settings after changing resolution
+ */
+static void
+bcmfb_update_margins(video_adapter_t *adp)
+{
+	struct bcmsc_softc *sc;
+	video_info_t *vi;
+
+	sc = (struct bcmsc_softc *)adp;
+	vi = &adp->va_info;
+
+	sc->xmargin = (sc->width - (vi->vi_width * vi->vi_cwidth)) / 2;
+	sc->ymargin = (sc->height - (vi->vi_height * vi->vi_cheight)) / 2;
+}
+
+static int
+bcmfb_configure(int flags)
+{
+	char bootargs[2048], *n, *p, *v;
+	pcell_t cell;
+	phandle_t chosen, display, root;
+	struct bcmsc_softc *sc;
+
+	sc = &bcmsc;
+	if (sc->initialized)
+		return (0);
+
+	sc->width = 0;
+	sc->height = 0;
+
+	/*
+	 * It seems there is no way to let syscons framework know
+	 * that framebuffer resolution has changed. So just try
+	 * to fetch data from FDT bootargs, FDT display data and
+	 * finally go with defaults if everything else has failed.
+	 */
+	chosen = OF_finddevice("/chosen");
+	if (chosen != 0 &&
+	    OF_getprop(chosen, "bootargs", &bootargs, sizeof(bootargs)) > 0) {
+		p = bootargs;
+		while ((v = strsep(&p, " ")) != NULL) {
+			if (*v == '\0')
+				continue;
+			n = strsep(&v, "=");
+			if (strcmp(n, "bcm2708_fb.fbwidth") == 0 && v != NULL)
+				sc->width = (unsigned int)strtol(v, NULL, 0);
+			else if (strcmp(n, "bcm2708_fb.fbheight") == 0 &&
+			    v != NULL)
+				sc->height = (unsigned int)strtol(v, NULL, 0);
+			else if (strcmp(n, "bcm2708_fb.fbswap") == 0 &&
+			    v != NULL)
+				if (*v == '1')
+					sc->fbswap = 1;
+		}
+	}
+
+	root = OF_finddevice("/");
+	if ((root != 0) && 
+	    (display = fdt_find_compatible(root, "broadcom,bcm2835-fb", 1))) {
+		if (sc->width == 0) {
+			if ((OF_getprop(display, "broadcom,width", 
+			    &cell, sizeof(cell))) > 0)
+				sc->width = (int)fdt32_to_cpu(cell);
+		}
+
+		if (sc->height == 0) {
+			if ((OF_getprop(display, "broadcom,height", 
+			    &cell, sizeof(cell))) > 0)
+				sc->height = (int)fdt32_to_cpu(cell);
+		}
+	}
+
+	if (sc->width == 0)
+		sc->width = FB_WIDTH;
+	if (sc->height == 0)
+		sc->height = FB_HEIGHT;
+
+	bcmfb_init(0, &sc->va, 0);
+	sc->initialized = 1;
+
+	return (0);
+}
+
+static int
+bcmfb_probe(int unit, video_adapter_t **adp, void *arg, int flags)
+{
+
+	return (0);
+}
+
+static int
+bcmfb_init(int unit, video_adapter_t *adp, int flags)
+{
+	struct bcmsc_softc *sc;
+	video_info_t *vi;
+
+	sc = (struct bcmsc_softc *)adp;
+	vi = &adp->va_info;
+
+	vid_init_struct(adp, "bcmfb", -1, unit);
+
+	sc->font = dflt_font_16;
+	vi->vi_cheight = BCMFB_FONT_HEIGHT;
+	vi->vi_cwidth = BCMFB_FONT_WIDTH;
+	vi->vi_width = sc->width / vi->vi_cwidth;
+	vi->vi_height = sc->height / vi->vi_cheight;
+
+	/*
+	 * Clamp width/height to syscons maximums
+	 */
+	if (vi->vi_width > COL)
+		vi->vi_width = COL;
+	if (vi->vi_height > ROW)
+		vi->vi_height = ROW;
+
+	sc->xmargin = (sc->width - (vi->vi_width * vi->vi_cwidth)) / 2;
+	sc->ymargin = (sc->height - (vi->vi_height * vi->vi_cheight)) / 2;
+
+	adp->va_window = (vm_offset_t) bcmfb_static_window;
+	adp->va_flags |= V_ADP_FONT /* | V_ADP_COLOR | V_ADP_MODECHANGE */;
+
+	vid_register(&sc->va);
+
+	return (0);
+}
+
+static int
+bcmfb_get_info(video_adapter_t *adp, int mode, video_info_t *info)
+{
+	bcopy(&adp->va_info, info, sizeof(*info));
+	return (0);
+}
+
+static int
+bcmfb_query_mode(video_adapter_t *adp, video_info_t *info)
+{
+	return (0);
+}
+
+static int
+bcmfb_set_mode(video_adapter_t *adp, int mode)
+{
+	return (0);
+}
+
+static int
+bcmfb_save_font(video_adapter_t *adp, int page, int size, int width,
+    u_char *data, int c, int count)
+{
+	return (0);
+}
+
+static int
+bcmfb_load_font(video_adapter_t *adp, int page, int size, int width,
+    u_char *data, int c, int count)
+{
+	struct bcmsc_softc *sc;
+
+	sc = (struct bcmsc_softc *)adp;
+	sc->font = data;
+
+	return (0);
+}
+
+static int
+bcmfb_show_font(video_adapter_t *adp, int page)
+{
+	return (0);
+}
+
+static int
+bcmfb_save_palette(video_adapter_t *adp, u_char *palette)
+{
+	return (0);
+}
+
+static int
+bcmfb_load_palette(video_adapter_t *adp, u_char *palette)
+{
+	return (0);
+}
+
+static int
+bcmfb_set_border(video_adapter_t *adp, int border)
+{
+	return (bcmfb_blank_display(adp, border));
+}
+
+static int
+bcmfb_save_state(video_adapter_t *adp, void *p, size_t size)
+{
+	return (0);
+}
+
+static int
+bcmfb_load_state(video_adapter_t *adp, void *p)
+{
+	return (0);
+}
+
+static int
+bcmfb_set_win_org(video_adapter_t *adp, off_t offset)
+{
+	return (0);
+}
+
+static int
+bcmfb_read_hw_cursor(video_adapter_t *adp, int *col, int *row)
+{
+	*col = *row = 0;
+
+	return (0);
+}
+
+static int
+bcmfb_set_hw_cursor(video_adapter_t *adp, int col, int row)
+{
+	return (0);
+}
+
+static int
+bcmfb_set_hw_cursor_shape(video_adapter_t *adp, int base, int height,
+    int celsize, int blink)
+{
+	return (0);
+}
+
+static int
+bcmfb_blank_display(video_adapter_t *adp, int mode)
+{
+
+	struct bcmsc_softc *sc;
+
+	sc = (struct bcmsc_softc *)adp;
+	if (sc && sc->fb_addr)
+		memset((void*)sc->fb_addr, 0, sc->fb_size);
+
+	return (0);
+}
+
+static int
+bcmfb_mmap(video_adapter_t *adp, vm_ooffset_t offset, vm_paddr_t *paddr,
+    int prot, vm_memattr_t *memattr)
+{
+	struct bcmsc_softc *sc;
+
+	sc = (struct bcmsc_softc *)adp;
+
+	/*
+	 * This might be a legacy VGA mem request: if so, just point it at the
+	 * framebuffer, since it shouldn't be touched
+	 */
+	if (offset < sc->stride*sc->height) {
+		*paddr = sc->fb_paddr + offset;
+		return (0);
+	}
+
+	return (EINVAL);
+}
+
+static int
+bcmfb_ioctl(video_adapter_t *adp, u_long cmd, caddr_t data)
+{
+	struct bcmsc_softc *sc;
+	struct fbtype *fb;
+
+	sc = (struct bcmsc_softc *)adp;
+
+	switch (cmd) {
+	case FBIOGTYPE:
+		fb = (struct fbtype *)data;
+		fb->fb_type = FBTYPE_PCIMISC;
+		fb->fb_height = sc->height;
+		fb->fb_width = sc->width;
+		fb->fb_depth = sc->depth;
+		if (sc->depth <= 1 || sc->depth > 8)
+			fb->fb_cmsize = 0;
+		else
+			fb->fb_cmsize = 1 << sc->depth;
+		fb->fb_size = sc->fb_size;
+		break;
+	default:
+		return (fb_commonioctl(adp, cmd, data));
+	}
+
+	return (0);
+}
+
+static int
+bcmfb_clear(video_adapter_t *adp)
+{
+
+	return (bcmfb_blank_display(adp, 0));
+}
+
+static int
+bcmfb_fill_rect(video_adapter_t *adp, int val, int x, int y, int cx, int cy)
+{
+
+	return (0);
+}
+
+static int
+bcmfb_bitblt(video_adapter_t *adp, ...)
+{
+
+	return (0);
+}
+
+static int
+bcmfb_diag(video_adapter_t *adp, int level)
+{
+
+	return (0);
+}
+
+static int
+bcmfb_save_cursor_palette(video_adapter_t *adp, u_char *palette)
+{
+
+	return (0);
+}
+
+static int
+bcmfb_load_cursor_palette(video_adapter_t *adp, u_char *palette)
+{
+
+	return (0);
+}
+
+static int
+bcmfb_copy(video_adapter_t *adp, vm_offset_t src, vm_offset_t dst, int n)
+{
+
+	return (0);
+}
+
+static int
+bcmfb_putp(video_adapter_t *adp, vm_offset_t off, uint32_t p, uint32_t a,
+    int size, int bpp, int bit_ltor, int byte_ltor)
+{
+
+	return (0);
+}
+
+static int
+bcmfb_putc(video_adapter_t *adp, vm_offset_t off, uint8_t c, uint8_t a)
+{
+	int bytes, col, i, j, k, row;
+	struct bcmsc_softc *sc;
+	u_char *p;
+	uint8_t *addr, fg, bg, color;
+	uint16_t rgb;
+
+	sc = (struct bcmsc_softc *)adp;
+
+	if (sc->fb_addr == 0)
+		return (0);
+
+	row = (off / adp->va_info.vi_width) * adp->va_info.vi_cheight;
+	col = (off % adp->va_info.vi_width) * adp->va_info.vi_cwidth;
+	p = sc->font + c*BCMFB_FONT_HEIGHT;
+	addr = (uint8_t *)sc->fb_addr
+	    + (row + sc->ymargin)*(sc->stride)
+	    + (sc->depth/8) * (col + sc->xmargin);
+
+	fg = a & 0xf ;
+	bg = (a >> 4) & 0xf;
+
+	bytes = sc->depth / 8;
+	for (i = 0; i < BCMFB_FONT_HEIGHT; i++) {
+		for (j = 0, k = 7; j < 8; j++, k--) {
+			if ((p[i] & (1 << k)) == 0)
+				color = bg;
+			else
+				color = fg;
+
+			switch (sc->depth) {
+			case 32:
+			case 24:
+				if (sc->fbswap) {
+					addr[bytes * j + 0] =
+					    bcmfb_palette[color].b;
+					addr[bytes * j + 1] =
+					    bcmfb_palette[color].g;
+					addr[bytes * j + 2] =
+					    bcmfb_palette[color].r;
+				} else {
+					addr[bytes * j + 0] =
+					    bcmfb_palette[color].r;
+					addr[bytes * j + 1] =
+					    bcmfb_palette[color].g;
+					addr[bytes * j + 2] =
+					    bcmfb_palette[color].b;
+				}
+				if (sc->depth == 32)
+					addr[bytes * j + 3] =
+					    bcmfb_palette[color].a;
+				break;
+			case 16:
+				rgb = (bcmfb_palette[color].r >> 3) << 11;
+				rgb |= (bcmfb_palette[color].g >> 2) << 5;
+				rgb |= (bcmfb_palette[color].b >> 3);
+				addr[bytes * j] = rgb & 0xff;
+				addr[bytes * j + 1] = (rgb >> 8) & 0xff;
+			default:
+				/* Not supported yet */
+				break;
+			}
+		}
+
+		addr += (sc->stride);
+	}
+
+        return (0);
+}
+
+static int
+bcmfb_puts(video_adapter_t *adp, vm_offset_t off, u_int16_t *s, int len)
+{
+	int i;
+
+	for (i = 0; i < len; i++) 
+		bcmfb_putc(adp, off + i, s[i] & 0xff, (s[i] & 0xff00) >> 8);
+
+	return (0);
+}
+
+static int
+bcmfb_putm(video_adapter_t *adp, int x, int y, uint8_t *pixel_image,
+    uint32_t pixel_mask, int size, int width)
+{
+
+	return (0);
+}
+
+/*
+ * Define a stub keyboard driver in case one hasn't been
+ * compiled into the kernel
+ */
+#include <sys/kbio.h>
+#include <dev/kbd/kbdreg.h>
+
+static int dummy_kbd_configure(int flags);
+
+keyboard_switch_t bcmdummysw;
+
+static int
+dummy_kbd_configure(int flags)
+{
+
+	return (0);
+}
+KEYBOARD_DRIVER(bcmdummy, bcmdummysw, dummy_kbd_configure);


Property changes on: trunk/sys/arm/broadcom/bcm2835/bcm2835_fb.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/broadcom/bcm2835/bcm2835_fbd.c
===================================================================
--- trunk/sys/arm/broadcom/bcm2835/bcm2835_fbd.c	                        (rev 0)
+++ trunk/sys/arm/broadcom/bcm2835/bcm2835_fbd.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,278 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Oleksandr Tymoshenko <gonzo at freebsd.org>
+ * Copyright (c) 2012, 2013 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * Portions of this software were developed by Oleksandr Rybalko
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * 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: stable/10/sys/arm/broadcom/bcm2835/bcm2835_fbd.c 322724 2017-08-20 16:52:27Z marius $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bio.h>
+#include <sys/bus.h>
+#include <sys/fbio.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <dev/fb/fbreg.h>
+#include <dev/vt/vt.h>
+#include <dev/vt/colors/vt_termcolors.h>
+
+#include <arm/broadcom/bcm2835/bcm2835_mbox_prop.h>
+
+#include "fb_if.h"
+#include "mbox_if.h"
+
+#define	FB_DEPTH		24
+
+struct bcmsc_softc {
+	struct fb_info 			info;
+	int				fbswap;
+	struct bcm2835_fb_config	fb;
+	device_t			dev;
+};
+
+static struct ofw_compat_data compat_data[] = {
+	{"broadcom,bcm2835-fb",		1},
+	{"brcm,bcm2708-fb",		1},
+	{NULL,				0}
+};
+
+static int bcm_fb_probe(device_t);
+static int bcm_fb_attach(device_t);
+
+static int
+bcm_fb_init(struct bcmsc_softc *sc, struct bcm2835_fb_config *fb)
+{
+	int err;
+
+	err = 0;
+
+	memset(fb, 0, sizeof(*fb));
+	if (bcm2835_mbox_fb_get_w_h(fb) != 0)
+		return (ENXIO);
+	fb->bpp = FB_DEPTH;
+
+	fb->vxres = fb->xres;
+	fb->vyres = fb->yres;
+	fb->xoffset = fb->yoffset = 0;
+
+	if ((err = bcm2835_mbox_fb_init(fb)) != 0) {
+		device_printf(sc->dev, "bcm2835_mbox_fb_init failed, err=%d\n", err);
+		return (ENXIO);
+	}
+
+	return (0);
+}
+
+static int
+bcm_fb_setup_fbd(struct bcmsc_softc *sc)
+{
+	struct bcm2835_fb_config fb;
+	device_t fbd;
+	int err;
+
+	err = bcm_fb_init(sc, &fb);
+	if (err)
+		return (err);
+
+	memset(&sc->info, 0, sizeof(sc->info));
+	sc->info.fb_name = device_get_nameunit(sc->dev);
+
+	sc->info.fb_vbase = (intptr_t)pmap_mapdev(fb.base, fb.size);
+	sc->info.fb_pbase = fb.base;
+	sc->info.fb_size = fb.size;
+	sc->info.fb_bpp = sc->info.fb_depth = fb.bpp;
+	sc->info.fb_stride = fb.pitch;
+	sc->info.fb_width = fb.xres;
+	sc->info.fb_height = fb.yres;
+#ifdef VM_MEMATTR_WRITE_COMBINING
+	sc->info.fb_flags = FB_FLAG_MEMATTR;
+	sc->info.fb_memattr = VM_MEMATTR_WRITE_COMBINING;
+#endif
+
+	if (sc->fbswap) {
+		switch (sc->info.fb_bpp) {
+		case 24:
+			vt_generate_cons_palette(sc->info.fb_cmap,
+			    COLOR_FORMAT_RGB, 0xff, 0, 0xff, 8, 0xff, 16);
+			sc->info.fb_cmsize = 16;
+			break;
+		case 32:
+			vt_generate_cons_palette(sc->info.fb_cmap,
+			    COLOR_FORMAT_RGB, 0xff, 16, 0xff, 8, 0xff, 0);
+			sc->info.fb_cmsize = 16;
+			break;
+		}
+	}
+
+	fbd = device_add_child(sc->dev, "fbd", device_get_unit(sc->dev));
+	if (fbd == NULL) {
+		device_printf(sc->dev, "Failed to add fbd child\n");
+		pmap_unmapdev(sc->info.fb_vbase, sc->info.fb_size);
+		return (ENXIO);
+	} else if (device_probe_and_attach(fbd) != 0) {
+		device_printf(sc->dev, "Failed to attach fbd device\n");
+		device_delete_child(sc->dev, fbd);
+		pmap_unmapdev(sc->info.fb_vbase, sc->info.fb_size);
+		return (ENXIO);
+	}
+
+	device_printf(sc->dev, "%dx%d(%dx%d@%d,%d) %dbpp\n", fb.xres, fb.yres,
+	    fb.vxres, fb.vyres, fb.xoffset, fb.yoffset, fb.bpp);
+	device_printf(sc->dev,
+	    "fbswap: %d, pitch %d, base 0x%08x, screen_size %d\n",
+	    sc->fbswap, fb.pitch, fb.base, fb.size);
+
+	return (0);
+}
+
+static int
+bcm_fb_resync_sysctl(SYSCTL_HANDLER_ARGS)
+{
+	struct bcmsc_softc *sc = arg1;
+	struct bcm2835_fb_config fb;
+	int val;
+	int err;
+
+	val = 0;
+	err = sysctl_handle_int(oidp, &val, 0, req);
+	if (err || !req->newptr) /* error || read request */
+		return (err);
+
+	bcm_fb_init(sc, &fb);
+
+	return (0);
+}
+
+static void
+bcm_fb_sysctl_init(struct bcmsc_softc *sc)
+{
+	struct sysctl_ctx_list *ctx;
+	struct sysctl_oid *tree_node;
+	struct sysctl_oid_list *tree;
+
+	/*
+	 * Add system sysctl tree/handlers.
+	 */
+	ctx = device_get_sysctl_ctx(sc->dev);
+	tree_node = device_get_sysctl_tree(sc->dev);
+	tree = SYSCTL_CHILDREN(tree_node);
+	SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "resync",
+	    CTLFLAG_RW | CTLTYPE_UINT, sc, sizeof(*sc),
+	    bcm_fb_resync_sysctl, "IU", "Set to resync framebuffer with VC");
+}
+
+static int
+bcm_fb_probe(device_t dev)
+{
+
+	if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
+		return (ENXIO);
+
+	device_set_desc(dev, "BCM2835 VT framebuffer driver");
+
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+bcm_fb_attach(device_t dev)
+{
+	char bootargs[2048], *n, *p, *v;
+	int err;
+	phandle_t chosen;
+	struct bcmsc_softc *sc;
+
+	sc = device_get_softc(dev);
+	sc->dev = dev;
+
+	/* Newer firmware versions needs an inverted color palette. */
+	sc->fbswap = 0;
+	chosen = OF_finddevice("/chosen");
+	if (chosen != 0 &&
+	    OF_getprop(chosen, "bootargs", &bootargs, sizeof(bootargs)) > 0) {
+		p = bootargs;
+		while ((v = strsep(&p, " ")) != NULL) {
+			if (*v == '\0')
+				continue;
+			n = strsep(&v, "=");
+			if (strcmp(n, "bcm2708_fb.fbswap") == 0 && v != NULL)
+				if (*v == '1')
+					sc->fbswap = 1;
+                }
+        }
+
+	bcm_fb_sysctl_init(sc);
+
+	err = bcm_fb_setup_fbd(sc);
+	if (err)
+		return (err);
+
+	return (0);
+}
+
+static struct fb_info *
+bcm_fb_helper_getinfo(device_t dev)
+{
+	struct bcmsc_softc *sc;
+
+	sc = device_get_softc(dev);
+
+	return (&sc->info);
+}
+
+static device_method_t bcm_fb_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		bcm_fb_probe),
+	DEVMETHOD(device_attach,	bcm_fb_attach),
+
+	/* Framebuffer service methods */
+	DEVMETHOD(fb_getinfo,		bcm_fb_helper_getinfo),
+
+	DEVMETHOD_END
+};
+
+static devclass_t bcm_fb_devclass;
+
+static driver_t bcm_fb_driver = {
+	"fb",
+	bcm_fb_methods,
+	sizeof(struct bcmsc_softc),
+};
+
+DRIVER_MODULE(bcm2835fb, ofwbus, bcm_fb_driver, bcm_fb_devclass, 0, 0);
+DRIVER_MODULE(bcm2835fb, simplebus, bcm_fb_driver, bcm_fb_devclass, 0, 0);


Property changes on: trunk/sys/arm/broadcom/bcm2835/bcm2835_fbd.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/broadcom/bcm2835/bcm2835_gpio.c
===================================================================
--- trunk/sys/arm/broadcom/bcm2835/bcm2835_gpio.c	                        (rev 0)
+++ trunk/sys/arm/broadcom/bcm2835/bcm2835_gpio.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,787 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Oleksandr Tymoshenko <gonzo at freebsd.org>
+ * Copyright (c) 2012 Luiz Otavio O Souza.
+ * 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: stable/10/sys/arm/broadcom/bcm2835/bcm2835_gpio.c 322724 2017-08-20 16:52:27Z marius $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/rman.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/gpio.h>
+#include <sys/sysctl.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+#include <machine/resource.h>
+#include <machine/fdt.h>
+#include <machine/intr.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <arm/broadcom/bcm2835/bcm2835_gpio.h>
+
+#include "gpio_if.h"
+
+#ifdef DEBUG
+#define dprintf(fmt, args...) do { printf("%s(): ", __func__);   \
+    printf(fmt,##args); } while (0)
+#else
+#define dprintf(fmt, args...)
+#endif
+
+#define	BCM_GPIO_PINS		54
+#define	BCM_GPIO_DEFAULT_CAPS	(GPIO_PIN_INPUT | GPIO_PIN_OUTPUT |	\
+    GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN)
+
+struct bcm_gpio_sysctl {
+	struct bcm_gpio_softc	*sc;
+	uint32_t		pin;
+};
+
+struct bcm_gpio_softc {
+	device_t		sc_dev;
+	struct mtx		sc_mtx;
+	struct resource *	sc_mem_res;
+	struct resource *	sc_irq_res;
+	bus_space_tag_t		sc_bst;
+	bus_space_handle_t	sc_bsh;
+	void *			sc_intrhand;
+	int			sc_gpio_npins;
+	int			sc_ro_npins;
+	int			sc_ro_pins[BCM_GPIO_PINS];
+	struct gpio_pin		sc_gpio_pins[BCM_GPIO_PINS];
+	struct bcm_gpio_sysctl	sc_sysctl[BCM_GPIO_PINS];
+};
+
+enum bcm_gpio_pud {
+	BCM_GPIO_NONE,
+	BCM_GPIO_PULLDOWN,
+	BCM_GPIO_PULLUP,
+};
+
+#define	BCM_GPIO_LOCK(_sc)	mtx_lock(&_sc->sc_mtx)
+#define	BCM_GPIO_UNLOCK(_sc)	mtx_unlock(&_sc->sc_mtx)
+#define	BCM_GPIO_LOCK_ASSERT(_sc)	mtx_assert(&_sc->sc_mtx, MA_OWNED)
+
+#define	BCM_GPIO_GPFSEL(_bank)	0x00 + _bank * 4
+#define	BCM_GPIO_GPSET(_bank)	0x1c + _bank * 4
+#define	BCM_GPIO_GPCLR(_bank)	0x28 + _bank * 4
+#define	BCM_GPIO_GPLEV(_bank)	0x34 + _bank * 4
+#define	BCM_GPIO_GPPUD(_bank)	0x94
+#define	BCM_GPIO_GPPUDCLK(_bank)	0x98 + _bank * 4
+
+#define	BCM_GPIO_WRITE(_sc, _off, _val)		\
+    bus_space_write_4(_sc->sc_bst, _sc->sc_bsh, _off, _val)
+#define	BCM_GPIO_READ(_sc, _off)		\
+    bus_space_read_4(_sc->sc_bst, _sc->sc_bsh, _off)
+
+static struct ofw_compat_data compat_data[] = {
+	{"broadcom,bcm2835-gpio",	1},
+	{"brcm,bcm2835-gpio",		1},
+	{NULL,				0}
+};
+
+static int
+bcm_gpio_pin_is_ro(struct bcm_gpio_softc *sc, int pin)
+{
+	int i;
+
+	for (i = 0; i < sc->sc_ro_npins; i++)
+		if (pin == sc->sc_ro_pins[i])
+			return (1);
+	return (0);
+}
+
+static uint32_t
+bcm_gpio_get_function(struct bcm_gpio_softc *sc, uint32_t pin)
+{
+	uint32_t bank, func, offset;
+
+	/* Five banks, 10 pins per bank, 3 bits per pin. */
+	bank = pin / 10;
+	offset = (pin - bank * 10) * 3;
+
+	BCM_GPIO_LOCK(sc);
+	func = (BCM_GPIO_READ(sc, BCM_GPIO_GPFSEL(bank)) >> offset) & 7;
+	BCM_GPIO_UNLOCK(sc);
+
+	return (func);
+}
+
+static void
+bcm_gpio_func_str(uint32_t nfunc, char *buf, int bufsize)
+{
+
+	switch (nfunc) {
+	case BCM_GPIO_INPUT:
+		strncpy(buf, "input", bufsize);
+		break;
+	case BCM_GPIO_OUTPUT:
+		strncpy(buf, "output", bufsize);
+		break;
+	case BCM_GPIO_ALT0:
+		strncpy(buf, "alt0", bufsize);
+		break;
+	case BCM_GPIO_ALT1:
+		strncpy(buf, "alt1", bufsize);
+		break;
+	case BCM_GPIO_ALT2:
+		strncpy(buf, "alt2", bufsize);
+		break;
+	case BCM_GPIO_ALT3:
+		strncpy(buf, "alt3", bufsize);
+		break;
+	case BCM_GPIO_ALT4:
+		strncpy(buf, "alt4", bufsize);
+		break;
+	case BCM_GPIO_ALT5:
+		strncpy(buf, "alt5", bufsize);
+		break;
+	default:
+		strncpy(buf, "invalid", bufsize);
+	}
+}
+
+static int
+bcm_gpio_str_func(char *func, uint32_t *nfunc)
+{
+
+	if (strcasecmp(func, "input") == 0)
+		*nfunc = BCM_GPIO_INPUT;
+	else if (strcasecmp(func, "output") == 0)
+		*nfunc = BCM_GPIO_OUTPUT;
+	else if (strcasecmp(func, "alt0") == 0)
+		*nfunc = BCM_GPIO_ALT0;
+	else if (strcasecmp(func, "alt1") == 0)
+		*nfunc = BCM_GPIO_ALT1;
+	else if (strcasecmp(func, "alt2") == 0)
+		*nfunc = BCM_GPIO_ALT2;
+	else if (strcasecmp(func, "alt3") == 0)
+		*nfunc = BCM_GPIO_ALT3;
+	else if (strcasecmp(func, "alt4") == 0)
+		*nfunc = BCM_GPIO_ALT4;
+	else if (strcasecmp(func, "alt5") == 0)
+		*nfunc = BCM_GPIO_ALT5;
+	else
+		return (-1);
+
+	return (0);
+}
+
+static uint32_t
+bcm_gpio_func_flag(uint32_t nfunc)
+{
+
+	switch (nfunc) {
+	case BCM_GPIO_INPUT:
+		return (GPIO_PIN_INPUT);
+	case BCM_GPIO_OUTPUT:
+		return (GPIO_PIN_OUTPUT);
+	}
+	return (0);
+}
+
+static void
+bcm_gpio_set_function(struct bcm_gpio_softc *sc, uint32_t pin, uint32_t f)
+{
+	uint32_t bank, data, offset;
+
+	/* Must be called with lock held. */
+	BCM_GPIO_LOCK_ASSERT(sc);
+
+	/* Five banks, 10 pins per bank, 3 bits per pin. */
+	bank = pin / 10;
+	offset = (pin - bank * 10) * 3;
+
+	data = BCM_GPIO_READ(sc, BCM_GPIO_GPFSEL(bank));
+	data &= ~(7 << offset);
+	data |= (f << offset);
+	BCM_GPIO_WRITE(sc, BCM_GPIO_GPFSEL(bank), data);
+}
+
+static void
+bcm_gpio_set_pud(struct bcm_gpio_softc *sc, uint32_t pin, uint32_t state)
+{
+	uint32_t bank, offset;
+
+	/* Must be called with lock held. */
+	BCM_GPIO_LOCK_ASSERT(sc);
+
+	bank = pin / 32;
+	offset = pin - 32 * bank;
+
+	BCM_GPIO_WRITE(sc, BCM_GPIO_GPPUD(0), state);
+	DELAY(10);
+	BCM_GPIO_WRITE(sc, BCM_GPIO_GPPUDCLK(bank), (1 << offset));
+	DELAY(10);
+	BCM_GPIO_WRITE(sc, BCM_GPIO_GPPUD(0), 0);
+	BCM_GPIO_WRITE(sc, BCM_GPIO_GPPUDCLK(bank), 0);
+}
+
+void
+bcm_gpio_set_alternate(device_t dev, uint32_t pin, uint32_t nfunc)
+{
+	struct bcm_gpio_softc *sc;
+	int i;
+
+	sc = device_get_softc(dev);
+	BCM_GPIO_LOCK(sc);
+
+	/* Disable pull-up or pull-down on pin. */
+	bcm_gpio_set_pud(sc, pin, BCM_GPIO_NONE);
+
+	/* And now set the pin function. */
+	bcm_gpio_set_function(sc, pin, nfunc);
+
+	/* Update the pin flags. */
+	for (i = 0; i < sc->sc_gpio_npins; i++) {
+		if (sc->sc_gpio_pins[i].gp_pin == pin)
+			break;
+	}
+	if (i < sc->sc_gpio_npins)
+		sc->sc_gpio_pins[i].gp_flags = bcm_gpio_func_flag(nfunc);
+
+        BCM_GPIO_UNLOCK(sc);
+}
+
+static void
+bcm_gpio_pin_configure(struct bcm_gpio_softc *sc, struct gpio_pin *pin,
+    unsigned int flags)
+{
+
+	BCM_GPIO_LOCK(sc);
+
+	/*
+	 * Manage input/output.
+	 */
+	if (flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) {
+		pin->gp_flags &= ~(GPIO_PIN_INPUT|GPIO_PIN_OUTPUT);
+		if (flags & GPIO_PIN_OUTPUT) {
+			pin->gp_flags |= GPIO_PIN_OUTPUT;
+			bcm_gpio_set_function(sc, pin->gp_pin,
+			    BCM_GPIO_OUTPUT);
+		} else {
+			pin->gp_flags |= GPIO_PIN_INPUT;
+			bcm_gpio_set_function(sc, pin->gp_pin,
+			    BCM_GPIO_INPUT);
+		}
+	}
+
+	/* Manage Pull-up/pull-down. */
+	pin->gp_flags &= ~(GPIO_PIN_PULLUP|GPIO_PIN_PULLDOWN);
+	if (flags & (GPIO_PIN_PULLUP|GPIO_PIN_PULLDOWN)) {
+		if (flags & GPIO_PIN_PULLUP) {
+			pin->gp_flags |= GPIO_PIN_PULLUP;
+			bcm_gpio_set_pud(sc, pin->gp_pin, BCM_GPIO_PULLUP);
+		} else {
+			pin->gp_flags |= GPIO_PIN_PULLDOWN;
+			bcm_gpio_set_pud(sc, pin->gp_pin, BCM_GPIO_PULLDOWN);
+		}
+	} else 
+		bcm_gpio_set_pud(sc, pin->gp_pin, BCM_GPIO_NONE);
+
+	BCM_GPIO_UNLOCK(sc);
+}
+
+static int
+bcm_gpio_pin_max(device_t dev, int *maxpin)
+{
+
+	*maxpin = BCM_GPIO_PINS - 1;
+	return (0);
+}
+
+static int
+bcm_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
+{
+	struct bcm_gpio_softc *sc = device_get_softc(dev);
+	int i;
+
+	for (i = 0; i < sc->sc_gpio_npins; i++) {
+		if (sc->sc_gpio_pins[i].gp_pin == pin)
+			break;
+	}
+
+	if (i >= sc->sc_gpio_npins)
+		return (EINVAL);
+
+	BCM_GPIO_LOCK(sc);
+	*caps = sc->sc_gpio_pins[i].gp_caps;
+	BCM_GPIO_UNLOCK(sc);
+
+	return (0);
+}
+
+static int
+bcm_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
+{
+	struct bcm_gpio_softc *sc = device_get_softc(dev);
+	int i;
+
+	for (i = 0; i < sc->sc_gpio_npins; i++) {
+		if (sc->sc_gpio_pins[i].gp_pin == pin)
+			break;
+	}
+
+	if (i >= sc->sc_gpio_npins)
+		return (EINVAL);
+
+	BCM_GPIO_LOCK(sc);
+	*flags = sc->sc_gpio_pins[i].gp_flags;
+	BCM_GPIO_UNLOCK(sc);
+
+	return (0);
+}
+
+static int
+bcm_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
+{
+	struct bcm_gpio_softc *sc = device_get_softc(dev);
+	int i;
+
+	for (i = 0; i < sc->sc_gpio_npins; i++) {
+		if (sc->sc_gpio_pins[i].gp_pin == pin)
+			break;
+	}
+
+	if (i >= sc->sc_gpio_npins)
+		return (EINVAL);
+
+	BCM_GPIO_LOCK(sc);
+	memcpy(name, sc->sc_gpio_pins[i].gp_name, GPIOMAXNAME);
+	BCM_GPIO_UNLOCK(sc);
+
+	return (0);
+}
+
+static int
+bcm_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
+{
+	struct bcm_gpio_softc *sc = device_get_softc(dev);
+	int i;
+
+	for (i = 0; i < sc->sc_gpio_npins; i++) {
+		if (sc->sc_gpio_pins[i].gp_pin == pin)
+			break;
+	}
+
+	if (i >= sc->sc_gpio_npins)
+		return (EINVAL);
+
+	/* We never touch on read-only/reserved pins. */
+	if (bcm_gpio_pin_is_ro(sc, pin))
+		return (EINVAL);
+
+	bcm_gpio_pin_configure(sc, &sc->sc_gpio_pins[i], flags);
+
+	return (0);
+}
+
+static int
+bcm_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value)
+{
+	struct bcm_gpio_softc *sc = device_get_softc(dev);
+	uint32_t bank, offset;
+	int i;
+
+	for (i = 0; i < sc->sc_gpio_npins; i++) {
+		if (sc->sc_gpio_pins[i].gp_pin == pin)
+			break;
+	}
+
+	if (i >= sc->sc_gpio_npins)
+		return (EINVAL);
+
+	/* We never write to read-only/reserved pins. */
+	if (bcm_gpio_pin_is_ro(sc, pin))
+		return (EINVAL);
+
+	bank = pin / 32;
+	offset = pin - 32 * bank;
+
+	BCM_GPIO_LOCK(sc);
+	if (value)
+		BCM_GPIO_WRITE(sc, BCM_GPIO_GPSET(bank), (1 << offset));
+	else
+		BCM_GPIO_WRITE(sc, BCM_GPIO_GPCLR(bank), (1 << offset));
+	BCM_GPIO_UNLOCK(sc);
+
+	return (0);
+}
+
+static int
+bcm_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val)
+{
+	struct bcm_gpio_softc *sc = device_get_softc(dev);
+	uint32_t bank, offset, reg_data;
+	int i;
+
+	for (i = 0; i < sc->sc_gpio_npins; i++) {
+		if (sc->sc_gpio_pins[i].gp_pin == pin)
+			break;
+	}
+
+	if (i >= sc->sc_gpio_npins)
+		return (EINVAL);
+
+	bank = pin / 32;
+	offset = pin - 32 * bank;
+
+	BCM_GPIO_LOCK(sc);
+	reg_data = BCM_GPIO_READ(sc, BCM_GPIO_GPLEV(bank));
+	BCM_GPIO_UNLOCK(sc);
+	*val = (reg_data & (1 << offset)) ? 1 : 0;
+
+	return (0);
+}
+
+static int
+bcm_gpio_pin_toggle(device_t dev, uint32_t pin)
+{
+	struct bcm_gpio_softc *sc = device_get_softc(dev);
+	uint32_t bank, data, offset;
+	int i;
+
+	for (i = 0; i < sc->sc_gpio_npins; i++) {
+		if (sc->sc_gpio_pins[i].gp_pin == pin)
+			break;
+	}
+
+	if (i >= sc->sc_gpio_npins)
+		return (EINVAL);
+
+	/* We never write to read-only/reserved pins. */
+	if (bcm_gpio_pin_is_ro(sc, pin))
+		return (EINVAL);
+
+	bank = pin / 32;
+	offset = pin - 32 * bank;
+
+	BCM_GPIO_LOCK(sc);
+	data = BCM_GPIO_READ(sc, BCM_GPIO_GPLEV(bank));
+	if (data & (1 << offset))
+		BCM_GPIO_WRITE(sc, BCM_GPIO_GPCLR(bank), (1 << offset));
+	else
+		BCM_GPIO_WRITE(sc, BCM_GPIO_GPSET(bank), (1 << offset));
+	BCM_GPIO_UNLOCK(sc);
+
+	return (0);
+}
+
+static int
+bcm_gpio_func_proc(SYSCTL_HANDLER_ARGS)
+{
+	char buf[16];
+	struct bcm_gpio_softc *sc;
+	struct bcm_gpio_sysctl *sc_sysctl;
+	uint32_t nfunc;
+	int error;
+
+	sc_sysctl = arg1;
+	sc = sc_sysctl->sc;
+
+	/* Get the current pin function. */
+	nfunc = bcm_gpio_get_function(sc, sc_sysctl->pin);
+	bcm_gpio_func_str(nfunc, buf, sizeof(buf));
+
+	error = sysctl_handle_string(oidp, buf, sizeof(buf), req);
+	if (error != 0 || req->newptr == NULL)
+		return (error);
+	/* Ignore changes on read-only pins. */
+	if (bcm_gpio_pin_is_ro(sc, sc_sysctl->pin))
+		return (0);
+	/* Parse the user supplied string and check for a valid pin function. */
+	if (bcm_gpio_str_func(buf, &nfunc) != 0)
+		return (EINVAL);
+
+	/* Update the pin alternate function. */
+	bcm_gpio_set_alternate(sc->sc_dev, sc_sysctl->pin, nfunc);
+
+	return (0);
+}
+
+static void
+bcm_gpio_sysctl_init(struct bcm_gpio_softc *sc)
+{
+	char pinbuf[3];
+	struct bcm_gpio_sysctl *sc_sysctl;
+	struct sysctl_ctx_list *ctx;
+	struct sysctl_oid *tree_node, *pin_node, *pinN_node;
+	struct sysctl_oid_list *tree, *pin_tree, *pinN_tree;
+	int i;
+
+	/*
+	 * Add per-pin sysctl tree/handlers.
+	 */
+	ctx = device_get_sysctl_ctx(sc->sc_dev);
+ 	tree_node = device_get_sysctl_tree(sc->sc_dev);
+ 	tree = SYSCTL_CHILDREN(tree_node);
+	pin_node = SYSCTL_ADD_NODE(ctx, tree, OID_AUTO, "pin",
+	    CTLFLAG_RD, NULL, "GPIO Pins");
+	pin_tree = SYSCTL_CHILDREN(pin_node);
+
+	for (i = 0; i < sc->sc_gpio_npins; i++) {
+
+		snprintf(pinbuf, sizeof(pinbuf), "%d", i);
+		pinN_node = SYSCTL_ADD_NODE(ctx, pin_tree, OID_AUTO, pinbuf,
+		    CTLFLAG_RD, NULL, "GPIO Pin");
+		pinN_tree = SYSCTL_CHILDREN(pinN_node);
+
+		sc->sc_sysctl[i].sc = sc;
+		sc_sysctl = &sc->sc_sysctl[i];
+		sc_sysctl->sc = sc;
+		sc_sysctl->pin = sc->sc_gpio_pins[i].gp_pin;
+		SYSCTL_ADD_PROC(ctx, pinN_tree, OID_AUTO, "function",
+		    CTLFLAG_RW | CTLTYPE_STRING, sc_sysctl,
+		    sizeof(struct bcm_gpio_sysctl), bcm_gpio_func_proc,
+		    "A", "Pin Function");
+	}
+}
+
+static int
+bcm_gpio_get_ro_pins(struct bcm_gpio_softc *sc, phandle_t node,
+	const char *propname, const char *label)
+{
+	int i, need_comma, npins, range_start, range_stop;
+	pcell_t *pins;
+
+	/* Get the property data. */
+	npins = OF_getencprop_alloc(node, propname, sizeof(*pins),
+	    (void **)&pins);
+	if (npins < 0)
+		return (-1);
+	if (npins == 0) {
+		free(pins, M_OFWPROP);
+		return (0);
+	}
+	for (i = 0; i < npins; i++)
+		sc->sc_ro_pins[i + sc->sc_ro_npins] = pins[i];
+	sc->sc_ro_npins += npins;
+	need_comma = 0;
+	device_printf(sc->sc_dev, "%s pins: ", label);
+	range_start = range_stop = pins[0];
+	for (i = 1; i < npins; i++) {
+		if (pins[i] != range_stop + 1) {
+			if (need_comma)
+				printf(",");
+			if (range_start != range_stop)
+				printf("%d-%d", range_start, range_stop);
+			else
+				printf("%d", range_start);
+			range_start = range_stop = pins[i];
+			need_comma = 1;
+		} else
+			range_stop++;
+	}
+	if (need_comma)
+		printf(",");
+	if (range_start != range_stop)
+		printf("%d-%d.\n", range_start, range_stop);
+	else
+		printf("%d.\n", range_start);
+	free(pins, M_OFWPROP);
+
+	return (0);
+}
+
+static int
+bcm_gpio_get_reserved_pins(struct bcm_gpio_softc *sc)
+{
+	char *name;
+	phandle_t gpio, node, reserved;
+	ssize_t len;
+
+	/* Get read-only pins if they're provided */
+	gpio = ofw_bus_get_node(sc->sc_dev);
+	if (bcm_gpio_get_ro_pins(sc, gpio, "broadcom,read-only",
+	    "read-only") != 0)
+		return (0);
+	/* Traverse the GPIO subnodes to find the reserved pins node. */
+	reserved = 0;
+	node = OF_child(gpio);
+	while ((node != 0) && (reserved == 0)) {
+		len = OF_getprop_alloc(node, "name", 1, (void **)&name);
+		if (len == -1)
+			return (-1);
+		if (strcmp(name, "reserved") == 0)
+			reserved = node;
+		free(name, M_OFWPROP);
+		node = OF_peer(node);
+	}
+	if (reserved == 0)
+		return (-1);
+	/* Get the reserved pins. */
+	if (bcm_gpio_get_ro_pins(sc, reserved, "broadcom,pins",
+	    "reserved") != 0)
+		return (-1);
+
+	return (0);
+}
+
+static int
+bcm_gpio_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
+		return (ENXIO);
+
+	device_set_desc(dev, "BCM2708/2835 GPIO controller");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+bcm_gpio_attach(device_t dev)
+{
+	struct bcm_gpio_softc *sc = device_get_softc(dev);
+	uint32_t func;
+	int i, j, rid;
+	phandle_t gpio;
+
+	sc->sc_dev = dev;
+
+	mtx_init(&sc->sc_mtx, "bcm gpio", "gpio", MTX_DEF);
+
+	rid = 0;
+	sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	    RF_ACTIVE);
+	if (!sc->sc_mem_res) {
+		device_printf(dev, "cannot allocate memory window\n");
+		return (ENXIO);
+	}
+
+	sc->sc_bst = rman_get_bustag(sc->sc_mem_res);
+	sc->sc_bsh = rman_get_bushandle(sc->sc_mem_res);
+
+	rid = 0;
+	sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+	    RF_ACTIVE);
+	if (!sc->sc_irq_res) {
+		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
+		device_printf(dev, "cannot allocate interrupt\n");
+		return (ENXIO);
+	}
+
+	/* Find our node. */
+	gpio = ofw_bus_get_node(sc->sc_dev);
+
+	if (!OF_hasprop(gpio, "gpio-controller"))
+		/* Node is not a GPIO controller. */
+		goto fail;
+
+	/*
+	 * Find the read-only pins.  These are pins we never touch or bad
+	 * things could happen.
+	 */
+	if (bcm_gpio_get_reserved_pins(sc) == -1)
+		goto fail;
+
+	/* Initialize the software controlled pins. */
+	for (i = 0, j = 0; j < BCM_GPIO_PINS; j++) {
+		snprintf(sc->sc_gpio_pins[i].gp_name, GPIOMAXNAME,
+		    "pin %d", j);
+		func = bcm_gpio_get_function(sc, j);
+		sc->sc_gpio_pins[i].gp_pin = j;
+		sc->sc_gpio_pins[i].gp_caps = BCM_GPIO_DEFAULT_CAPS;
+		sc->sc_gpio_pins[i].gp_flags = bcm_gpio_func_flag(func);
+		i++;
+	}
+	sc->sc_gpio_npins = i;
+
+	bcm_gpio_sysctl_init(sc);
+
+	device_add_child(dev, "gpioc", -1);
+	device_add_child(dev, "gpiobus", -1);
+
+	return (bus_generic_attach(dev));
+
+fail:
+	if (sc->sc_irq_res)
+		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res);
+	if (sc->sc_mem_res)
+		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
+	return (ENXIO);
+}
+
+static int
+bcm_gpio_detach(device_t dev)
+{
+
+	return (EBUSY);
+}
+
+static phandle_t
+bcm_gpio_get_node(device_t bus, device_t dev)
+{
+
+	/* We only have one child, the GPIO bus, which needs our own node. */
+	return (ofw_bus_get_node(bus));
+}
+
+static device_method_t bcm_gpio_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		bcm_gpio_probe),
+	DEVMETHOD(device_attach,	bcm_gpio_attach),
+	DEVMETHOD(device_detach,	bcm_gpio_detach),
+
+	/* GPIO protocol */
+	DEVMETHOD(gpio_pin_max,		bcm_gpio_pin_max),
+	DEVMETHOD(gpio_pin_getname,	bcm_gpio_pin_getname),
+	DEVMETHOD(gpio_pin_getflags,	bcm_gpio_pin_getflags),
+	DEVMETHOD(gpio_pin_getcaps,	bcm_gpio_pin_getcaps),
+	DEVMETHOD(gpio_pin_setflags,	bcm_gpio_pin_setflags),
+	DEVMETHOD(gpio_pin_get,		bcm_gpio_pin_get),
+	DEVMETHOD(gpio_pin_set,		bcm_gpio_pin_set),
+	DEVMETHOD(gpio_pin_toggle,	bcm_gpio_pin_toggle),
+
+	/* ofw_bus interface */
+	DEVMETHOD(ofw_bus_get_node,	bcm_gpio_get_node),
+
+	DEVMETHOD_END
+};
+
+static devclass_t bcm_gpio_devclass;
+
+static driver_t bcm_gpio_driver = {
+	"gpio",
+	bcm_gpio_methods,
+	sizeof(struct bcm_gpio_softc),
+};
+
+DRIVER_MODULE(bcm_gpio, simplebus, bcm_gpio_driver, bcm_gpio_devclass, 0, 0);


Property changes on: trunk/sys/arm/broadcom/bcm2835/bcm2835_gpio.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/broadcom/bcm2835/bcm2835_gpio.h
===================================================================
--- trunk/sys/arm/broadcom/bcm2835/bcm2835_gpio.h	                        (rev 0)
+++ trunk/sys/arm/broadcom/bcm2835/bcm2835_gpio.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,45 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Oleksandr Tymoshenko <gonzo at bluezbox.com>
+ *
+ * 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: stable/10/sys/arm/broadcom/bcm2835/bcm2835_gpio.h 255370 2013-09-07 18:48:15Z loos $
+ */
+
+#ifndef	_BCM2835_GPIO_H_
+#define	_BCM2835_GPIO_H_
+
+enum bcm_gpio_fsel {
+	BCM_GPIO_INPUT,
+	BCM_GPIO_OUTPUT,
+	BCM_GPIO_ALT5,
+	BCM_GPIO_ALT4,
+	BCM_GPIO_ALT0,
+	BCM_GPIO_ALT1,
+	BCM_GPIO_ALT2,
+	BCM_GPIO_ALT3,
+};
+
+void bcm_gpio_set_alternate(device_t, uint32_t, uint32_t);
+
+#endif	/* _BCM2835_GPIO_H_ */


Property changes on: trunk/sys/arm/broadcom/bcm2835/bcm2835_gpio.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/broadcom/bcm2835/bcm2835_intr.c
===================================================================
--- trunk/sys/arm/broadcom/bcm2835/bcm2835_intr.c	                        (rev 0)
+++ trunk/sys/arm/broadcom/bcm2835/bcm2835_intr.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,243 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Damjan Marion <dmarion at Freebsd.org>
+ * All rights reserved.
+ *
+ * Based on OMAP3 INTC code by Ben Gray
+ *
+ * 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: stable/10/sys/arm/broadcom/bcm2835/bcm2835_intr.c 322724 2017-08-20 16:52:27Z marius $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/ktr.h>
+#include <sys/module.h>
+#include <sys/rman.h>
+#include <machine/bus.h>
+#include <machine/intr.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#ifdef SOC_BCM2836
+#include <arm/broadcom/bcm2835/bcm2836.h>
+#endif
+
+#define	INTC_PENDING_BASIC	0x00
+#define	INTC_PENDING_BANK1	0x04
+#define	INTC_PENDING_BANK2	0x08
+#define	INTC_FIQ_CONTROL	0x0C
+#define	INTC_ENABLE_BANK1	0x10
+#define	INTC_ENABLE_BANK2	0x14
+#define	INTC_ENABLE_BASIC	0x18
+#define	INTC_DISABLE_BANK1	0x1C
+#define	INTC_DISABLE_BANK2	0x20
+#define	INTC_DISABLE_BASIC	0x24
+
+#define	BANK1_START	8
+#define	BANK1_END	(BANK1_START + 32 - 1)
+#define	BANK2_START	(BANK1_START + 32)
+#define	BANK2_END	(BANK2_START + 32 - 1)
+#define	BANK3_START	(BANK2_START + 32)
+#define	BANK3_END	(BANK3_START + 32 - 1)
+
+#define	IS_IRQ_BASIC(n)	(((n) >= 0) && ((n) < BANK1_START))
+#define	IS_IRQ_BANK1(n)	(((n) >= BANK1_START) && ((n) <= BANK1_END))
+#define	IS_IRQ_BANK2(n)	(((n) >= BANK2_START) && ((n) <= BANK2_END))
+#define	ID_IRQ_BCM2836(n) (((n) >= BANK3_START) && ((n) <= BANK3_END))
+#define	IRQ_BANK1(n)	((n) - BANK1_START)
+#define	IRQ_BANK2(n)	((n) - BANK2_START)
+
+#ifdef  DEBUG
+#define dprintf(fmt, args...) printf(fmt, ##args)
+#else
+#define dprintf(fmt, args...)
+#endif
+
+struct bcm_intc_softc {
+	device_t		sc_dev;
+	struct resource *	intc_res;
+	bus_space_tag_t		intc_bst;
+	bus_space_handle_t	intc_bsh;
+};
+
+static struct bcm_intc_softc *bcm_intc_sc = NULL;
+
+#define	intc_read_4(_sc, reg)		\
+    bus_space_read_4((_sc)->intc_bst, (_sc)->intc_bsh, (reg))
+#define	intc_write_4(_sc, reg, val)		\
+    bus_space_write_4((_sc)->intc_bst, (_sc)->intc_bsh, (reg), (val))
+
+static int
+bcm_intc_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "broadcom,bcm2835-armctrl-ic") &&
+	    !ofw_bus_is_compatible(dev, "brcm,bcm2836-armctrl-ic"))
+		return (ENXIO);
+	device_set_desc(dev, "BCM2835 Interrupt Controller");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+bcm_intc_attach(device_t dev)
+{
+	struct		bcm_intc_softc *sc = device_get_softc(dev);
+	int		rid = 0;
+
+	sc->sc_dev = dev;
+
+	if (bcm_intc_sc)
+		return (ENXIO);
+
+	sc->intc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
+	if (sc->intc_res == NULL) {
+		device_printf(dev, "could not allocate memory resource\n");
+		return (ENXIO);
+	}
+
+	sc->intc_bst = rman_get_bustag(sc->intc_res);
+	sc->intc_bsh = rman_get_bushandle(sc->intc_res);
+
+	bcm_intc_sc = sc;
+
+	return (0);
+}
+
+static device_method_t bcm_intc_methods[] = {
+	DEVMETHOD(device_probe,		bcm_intc_probe),
+	DEVMETHOD(device_attach,	bcm_intc_attach),
+	{ 0, 0 }
+};
+
+static driver_t bcm_intc_driver = {
+	"intc",
+	bcm_intc_methods,
+	sizeof(struct bcm_intc_softc),
+};
+
+static devclass_t bcm_intc_devclass;
+
+EARLY_DRIVER_MODULE(intc, simplebus, bcm_intc_driver, bcm_intc_devclass,
+    0, 0, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_LATE);
+
+int
+arm_get_next_irq(int last_irq)
+{
+	struct bcm_intc_softc *sc = bcm_intc_sc;
+	uint32_t pending;
+	int32_t irq = last_irq + 1;
+#ifdef SOC_BCM2836
+	int ret;
+#endif
+
+	/* Sanity check */
+	if (irq < 0)
+		irq = 0;
+
+#ifdef SOC_BCM2836
+	if ((ret = bcm2836_get_next_irq(irq)) >= 0)
+		return (ret + BANK3_START);
+#endif
+
+	/* TODO: should we mask last_irq? */
+	if (irq < BANK1_START) {
+		pending = intc_read_4(sc, INTC_PENDING_BASIC);
+		if ((pending & 0xFF) == 0) {
+			irq  = BANK1_START;	/* skip to next bank */
+		} else do {
+			if (pending & (1 << irq))
+				return irq;
+			irq++;
+		} while (irq < BANK1_START);
+	}
+	if (irq < BANK2_START) {
+		pending = intc_read_4(sc, INTC_PENDING_BANK1);
+		if (pending == 0) {
+			irq  = BANK2_START;	/* skip to next bank */
+		} else do {
+			if (pending & (1 << IRQ_BANK1(irq)))
+				return irq;
+			irq++;
+		} while (irq < BANK2_START);
+	}
+	if (irq < BANK3_START) {
+		pending = intc_read_4(sc, INTC_PENDING_BANK2);
+		if (pending != 0) do {
+			if (pending & (1 << IRQ_BANK2(irq)))
+				return irq;
+			irq++;
+		} while (irq < BANK3_START);
+	}
+	return (-1);
+}
+
+void
+arm_mask_irq(uintptr_t nb)
+{
+	struct bcm_intc_softc *sc = bcm_intc_sc;
+	dprintf("%s: %d\n", __func__, nb);
+
+	if (IS_IRQ_BASIC(nb))
+		intc_write_4(sc, INTC_DISABLE_BASIC, (1 << nb));
+	else if (IS_IRQ_BANK1(nb))
+		intc_write_4(sc, INTC_DISABLE_BANK1, (1 << IRQ_BANK1(nb)));
+	else if (IS_IRQ_BANK2(nb))
+		intc_write_4(sc, INTC_DISABLE_BANK2, (1 << IRQ_BANK2(nb)));
+#ifdef SOC_BCM2836
+	else if (ID_IRQ_BCM2836(nb))
+		bcm2836_mask_irq(nb - BANK3_START);
+#endif
+	else
+		printf("arm_mask_irq: Invalid IRQ number: %d\n", nb);
+}
+
+void
+arm_unmask_irq(uintptr_t nb)
+{
+	struct bcm_intc_softc *sc = bcm_intc_sc;
+	dprintf("%s: %d\n", __func__, nb);
+
+	if (IS_IRQ_BASIC(nb))
+		intc_write_4(sc, INTC_ENABLE_BASIC, (1 << nb));
+	else if (IS_IRQ_BANK1(nb))
+		intc_write_4(sc, INTC_ENABLE_BANK1, (1 << IRQ_BANK1(nb)));
+	else if (IS_IRQ_BANK2(nb))
+		intc_write_4(sc, INTC_ENABLE_BANK2, (1 << IRQ_BANK2(nb)));
+#ifdef SOC_BCM2836
+	else if (ID_IRQ_BCM2836(nb))
+		bcm2836_unmask_irq(nb - BANK3_START);
+#endif
+	else
+		printf("arm_mask_irq: Invalid IRQ number: %d\n", nb);
+}


Property changes on: trunk/sys/arm/broadcom/bcm2835/bcm2835_intr.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/broadcom/bcm2835/bcm2835_machdep.c
===================================================================
--- trunk/sys/arm/broadcom/bcm2835/bcm2835_machdep.c	                        (rev 0)
+++ trunk/sys/arm/broadcom/bcm2835/bcm2835_machdep.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,145 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Oleksandr Tymoshenko.
+ * Copyright (c) 1994-1998 Mark Brinicombe.
+ * Copyright (c) 1994 Brini.
+ * All rights reserved.
+ *
+ * This code is derived from software written for Brini by Mark Brinicombe
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by Brini.
+ * 4. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BRINI ``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 BRINI 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.
+ *
+ * from: FreeBSD: //depot/projects/arm/src/sys/arm/at91/kb920x_machdep.c, rev 45
+ */
+
+#include "opt_ddb.h"
+#include "opt_platform.h"
+#include "opt_global.h"
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/broadcom/bcm2835/bcm2835_machdep.c 322724 2017-08-20 16:52:27Z marius $");
+
+#define _ARM32_BUS_DMA_PRIVATE
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <machine/bus.h>
+#include <machine/devmap.h>
+#include <machine/machdep.h>
+
+#include <dev/fdt/fdt_common.h>
+
+#include <arm/broadcom/bcm2835/bcm2835_wdog.h>
+
+vm_offset_t
+initarm_lastaddr(void)
+{
+
+	return (arm_devmap_lastaddr());
+}
+
+void
+initarm_early_init(void)
+{
+
+}
+
+void
+initarm_gpio_init(void)
+{
+}
+
+void
+initarm_late_init(void)
+{
+	phandle_t system;
+	pcell_t cells[2];
+	int len;
+
+	system = OF_finddevice("/system");
+	if (system != 0) {
+		len = OF_getprop(system, "linux,serial", &cells, sizeof(cells));
+		if (len > 0)
+			board_set_serial(fdt64_to_cpu(*((uint64_t *)cells)));
+
+		len = OF_getprop(system, "linux,revision", &cells, sizeof(cells));
+		if (len > 0)
+			board_set_revision(fdt32_to_cpu(*((uint32_t *)cells)));
+	}
+}
+
+#ifdef SOC_BCM2835
+/*
+ * Set up static device mappings.
+ * 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)
+{
+
+	arm_devmap_add_entry(0x20000000, 0x01000000);
+	return (0);
+}
+#endif
+
+#ifdef SOC_BCM2836
+static int
+initarm_devmap_init(void)
+{
+
+	arm_devmap_add_entry(0x3f000000, 0x01000000);
+	return (0);
+}
+#endif
+
+struct arm32_dma_range *
+bus_dma_get_range(void)
+{
+
+	return (NULL);
+}
+
+int
+bus_dma_get_range_nb(void)
+{
+
+	return (0);
+}
+
+void
+cpu_reset()
+{
+	bcmwd_watchdog_reset();
+	while (1);
+}
+


Property changes on: trunk/sys/arm/broadcom/bcm2835/bcm2835_machdep.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/broadcom/bcm2835/bcm2835_mbox.c
===================================================================
--- trunk/sys/arm/broadcom/bcm2835/bcm2835_mbox.c	                        (rev 0)
+++ trunk/sys/arm/broadcom/bcm2835/bcm2835_mbox.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,537 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Oleksandr Tymoshenko <gonzo at freebsd.org>
+ * 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: stable/10/sys/arm/broadcom/bcm2835/bcm2835_mbox.c 322724 2017-08-20 16:52:27Z marius $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/sx.h>
+#include <sys/rman.h>
+#include <machine/bus.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <arm/broadcom/bcm2835/bcm2835_mbox.h>
+#include <arm/broadcom/bcm2835/bcm2835_mbox_prop.h>
+#include <arm/broadcom/bcm2835/bcm2835_vcbus.h>
+
+#include "mbox_if.h"
+
+#define	REG_READ	0x00
+#define	REG_POL		0x10
+#define	REG_SENDER	0x14
+#define	REG_STATUS	0x18
+#define		STATUS_FULL	0x80000000
+#define		STATUS_EMPTY	0x40000000
+#define	REG_CONFIG	0x1C
+#define		CONFIG_DATA_IRQ	0x00000001
+#define	REG_WRITE	0x20 /* This is Mailbox 1 address */
+
+#define	MBOX_MSG(chan, data)	(((data) & ~0xf) | ((chan) & 0xf))
+#define	MBOX_CHAN(msg)		((msg) & 0xf)
+#define	MBOX_DATA(msg)		((msg) & ~0xf)
+
+#define	MBOX_LOCK(sc)	do {	\
+	mtx_lock(&(sc)->lock);	\
+} while(0)
+
+#define	MBOX_UNLOCK(sc)	do {		\
+	mtx_unlock(&(sc)->lock);	\
+} while(0)
+
+#ifdef  DEBUG
+#define dprintf(fmt, args...) printf(fmt, ##args)
+#else
+#define dprintf(fmt, args...)
+#endif
+
+struct bcm_mbox_softc {
+	struct mtx		lock;
+	struct resource *	mem_res;
+	struct resource *	irq_res;
+	void*			intr_hl;
+	bus_space_tag_t		bst;
+	bus_space_handle_t	bsh;
+	int			msg[BCM2835_MBOX_CHANS];
+	int			have_message[BCM2835_MBOX_CHANS];
+	struct sx		property_chan_lock;
+};
+
+#define	mbox_read_4(sc, reg)		\
+    bus_space_read_4((sc)->bst, (sc)->bsh, reg)
+#define	mbox_write_4(sc, reg, val)		\
+    bus_space_write_4((sc)->bst, (sc)->bsh, reg, val)
+
+static struct ofw_compat_data compat_data[] = {
+	{"broadcom,bcm2835-mbox",	1},
+	{"brcm,bcm2835-mbox",		1},
+	{NULL,				0}
+};
+
+static int
+bcm_mbox_read_msg(struct bcm_mbox_softc *sc, int *ochan)
+{
+	uint32_t data;
+	uint32_t msg;
+	int chan;
+
+	msg = mbox_read_4(sc, REG_READ);
+	dprintf("bcm_mbox_intr: raw data %08x\n", msg);
+	chan = MBOX_CHAN(msg);
+	data = MBOX_DATA(msg);
+	if (sc->msg[chan]) {
+		printf("bcm_mbox_intr: channel %d oveflow\n", chan);
+		return (1);
+	}
+	dprintf("bcm_mbox_intr: chan %d, data %08x\n", chan, data);
+	sc->msg[chan] = msg;
+
+	if (ochan != NULL)
+		*ochan = chan;
+
+	return (0);
+}
+
+static void
+bcm_mbox_intr(void *arg)
+{
+	struct bcm_mbox_softc *sc = arg;
+	int chan;
+
+	MBOX_LOCK(sc);
+	while (!(mbox_read_4(sc, REG_STATUS) & STATUS_EMPTY))
+		if (bcm_mbox_read_msg(sc, &chan) == 0) {
+			sc->have_message[chan] = 1;
+			wakeup(&sc->have_message[chan]);
+		}
+	MBOX_UNLOCK(sc);
+}
+
+static int
+bcm_mbox_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
+		return (ENXIO);
+
+	device_set_desc(dev, "BCM2835 VideoCore Mailbox");
+
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+bcm_mbox_attach(device_t dev)
+{
+	struct bcm_mbox_softc *sc = device_get_softc(dev);
+	int i;
+	int rid = 0;
+
+	sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
+	if (sc->mem_res == NULL) {
+		device_printf(dev, "could not allocate memory resource\n");
+		return (ENXIO);
+	}
+
+	sc->bst = rman_get_bustag(sc->mem_res);
+	sc->bsh = rman_get_bushandle(sc->mem_res);
+
+	rid = 0;
+	sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE);
+	if (sc->irq_res == NULL) {
+		device_printf(dev, "could not allocate interrupt resource\n");
+		return (ENXIO);
+	}
+
+	/* Setup and enable the timer */
+	if (bus_setup_intr(dev, sc->irq_res, INTR_MPSAFE | INTR_TYPE_MISC, 
+	    NULL, bcm_mbox_intr, sc, &sc->intr_hl) != 0) {
+		bus_release_resource(dev, SYS_RES_IRQ, rid, sc->irq_res);
+		device_printf(dev, "Unable to setup the clock irq handler.\n");
+		return (ENXIO);
+	}
+
+	mtx_init(&sc->lock, "vcio mbox", NULL, MTX_DEF);
+	for (i = 0; i < BCM2835_MBOX_CHANS; i++) {
+		sc->msg[i] = 0;
+		sc->have_message[i] = 0;
+	}
+
+	sx_init(&sc->property_chan_lock, "mboxprop");
+
+	/* Read all pending messages */
+	while ((mbox_read_4(sc, REG_STATUS) & STATUS_EMPTY) == 0)
+		(void)mbox_read_4(sc, REG_READ);
+
+	mbox_write_4(sc, REG_CONFIG, CONFIG_DATA_IRQ);
+
+	return (0);
+}
+
+/* 
+ * Mailbox API
+ */
+static int
+bcm_mbox_write(device_t dev, int chan, uint32_t data)
+{
+	int limit = 1000;
+	struct bcm_mbox_softc *sc = device_get_softc(dev);
+
+	dprintf("bcm_mbox_write: chan %d, data %08x\n", chan, data);
+	MBOX_LOCK(sc);
+	sc->have_message[chan] = 0;
+	while ((mbox_read_4(sc, REG_STATUS) & STATUS_FULL) && --limit)
+		DELAY(5);
+	if (limit == 0) {
+		printf("bcm_mbox_write: STATUS_FULL stuck");
+		MBOX_UNLOCK(sc);
+		return (EAGAIN);
+	}
+	mbox_write_4(sc, REG_WRITE, MBOX_MSG(chan, data));
+	MBOX_UNLOCK(sc);
+
+	return (0);
+}
+
+static int
+bcm_mbox_read(device_t dev, int chan, uint32_t *data)
+{
+	struct bcm_mbox_softc *sc = device_get_softc(dev);
+	int err, read_chan;
+
+	dprintf("bcm_mbox_read: chan %d\n", chan);
+
+	err = 0;
+	MBOX_LOCK(sc);
+	if (!cold) {
+		if (sc->have_message[chan] == 0) {
+			if (mtx_sleep(&sc->have_message[chan], &sc->lock, 0,
+			    "mbox", 10*hz) != 0) {
+				device_printf(dev, "timeout waiting for message on chan %d\n", chan);
+				err = ETIMEDOUT;
+			}
+		}
+	} else {
+		do {
+			/* Wait for a message */
+			while ((mbox_read_4(sc, REG_STATUS) & STATUS_EMPTY))
+				;
+			/* Read the message */
+			if (bcm_mbox_read_msg(sc, &read_chan) != 0) {
+				err = EINVAL;
+				goto out;
+			}
+		} while (read_chan != chan);
+	}
+	/*
+	 *  get data from intr handler, the same channel is never coming
+	 *  because of holding sc lock.
+	 */
+	*data = MBOX_DATA(sc->msg[chan]);
+	sc->msg[chan] = 0;
+	sc->have_message[chan] = 0;
+out:
+	MBOX_UNLOCK(sc);
+	dprintf("bcm_mbox_read: chan %d, data %08x\n", chan, *data);
+
+	return (err);
+}
+
+static device_method_t bcm_mbox_methods[] = {
+	DEVMETHOD(device_probe,		bcm_mbox_probe),
+	DEVMETHOD(device_attach,	bcm_mbox_attach),
+
+	DEVMETHOD(mbox_read,		bcm_mbox_read),
+	DEVMETHOD(mbox_write,		bcm_mbox_write),
+
+	DEVMETHOD_END
+};
+
+static driver_t bcm_mbox_driver = {
+	"mbox",
+	bcm_mbox_methods,
+	sizeof(struct bcm_mbox_softc),
+};
+
+static devclass_t bcm_mbox_devclass;
+
+DRIVER_MODULE(mbox, simplebus, bcm_mbox_driver, bcm_mbox_devclass, 0, 0);
+
+static void
+bcm2835_mbox_dma_cb(void *arg, bus_dma_segment_t *segs, int nseg, int err)
+{
+	bus_addr_t *addr;
+
+	if (err)
+		return;
+	addr = (bus_addr_t *)arg;
+	*addr = PHYS_TO_VCBUS(segs[0].ds_addr);
+}
+
+static void *
+bcm2835_mbox_init_dma(device_t dev, size_t len, bus_dma_tag_t *tag,
+    bus_dmamap_t *map, bus_addr_t *phys)
+{
+	void *buf;
+	int err;
+
+	err = bus_dma_tag_create(bus_get_dma_tag(dev), 16, 0,
+	    BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
+	    len, 1, len, 0, NULL, NULL, tag);
+	if (err != 0) {
+		device_printf(dev, "can't create DMA tag\n");
+		return (NULL);
+	}
+
+	err = bus_dmamem_alloc(*tag, &buf, 0, map);
+	if (err != 0) {
+		bus_dma_tag_destroy(*tag);
+		device_printf(dev, "can't allocate dmamem\n");
+		return (NULL);
+	}
+
+	err = bus_dmamap_load(*tag, *map, buf, len, bcm2835_mbox_dma_cb,
+	    phys, 0);
+	if (err != 0) {
+		bus_dmamem_free(*tag, buf, *map);
+		bus_dma_tag_destroy(*tag);
+		device_printf(dev, "can't load DMA map\n");
+		return (NULL);
+	}
+
+	return (buf);
+}
+
+static int
+bcm2835_mbox_err(device_t dev, bus_addr_t msg_phys, uint32_t resp_phys,
+	struct bcm2835_mbox_hdr *msg, size_t len)
+{
+	int idx;
+	struct bcm2835_mbox_tag_hdr *tag;
+	uint8_t *last;
+
+	if ((uint32_t)msg_phys != resp_phys) {
+		device_printf(dev, "response channel mismatch\n");
+		return (EIO);
+	}
+	if (msg->code != BCM2835_MBOX_CODE_RESP_SUCCESS) {
+		device_printf(dev, "mbox response error\n");
+		return (EIO);
+	}
+
+	/* Loop until the end tag. */
+	tag = (struct bcm2835_mbox_tag_hdr *)(msg + 1);
+	last = (uint8_t *)msg + len;
+	for (idx = 0; tag->tag != 0; idx++) {
+		if ((tag->val_len & BCM2835_MBOX_TAG_VAL_LEN_RESPONSE) == 0) {
+			device_printf(dev, "tag %d response error\n", idx);
+			return (EIO);
+		}
+		/* Clear the response bit. */
+		tag->val_len &= ~BCM2835_MBOX_TAG_VAL_LEN_RESPONSE;
+
+		/* Next tag. */
+		tag = (struct bcm2835_mbox_tag_hdr *)((uint8_t *)tag +
+		    sizeof(*tag) + tag->val_buf_size);
+
+		if ((uint8_t *)tag > last) {
+			device_printf(dev, "mbox buffer size error\n");
+			return (EIO);
+		}
+	}
+
+	return (0);
+}
+
+int
+bcm2835_mbox_property(void *msg, size_t msg_size)
+{
+	struct bcm_mbox_softc *sc;
+	struct msg_set_power_state *buf;
+	bus_dma_tag_t msg_tag;
+	bus_dmamap_t msg_map;
+	bus_addr_t msg_phys;
+	uint32_t reg;
+	device_t mbox;
+	int err;
+
+	/* get mbox device */
+	mbox = devclass_get_device(devclass_find("mbox"), 0);
+	if (mbox == NULL)
+		return (ENXIO);
+
+	sc = device_get_softc(mbox);
+	sx_xlock(&sc->property_chan_lock);
+
+	/* Allocate memory for the message */
+	buf = bcm2835_mbox_init_dma(mbox, msg_size, &msg_tag, &msg_map,
+	    &msg_phys);
+	if (buf == NULL) {
+		err = ENOMEM;
+		goto out;
+	}
+
+	memcpy(buf, msg, msg_size);
+
+	bus_dmamap_sync(msg_tag, msg_map,
+	    BUS_DMASYNC_PREWRITE);
+
+	MBOX_WRITE(mbox, BCM2835_MBOX_CHAN_PROP, (uint32_t)msg_phys);
+	MBOX_READ(mbox, BCM2835_MBOX_CHAN_PROP, &reg);
+
+	bus_dmamap_sync(msg_tag, msg_map,
+	    BUS_DMASYNC_PREREAD);
+
+	memcpy(msg, buf, msg_size);
+
+	err = bcm2835_mbox_err(mbox, msg_phys, reg,
+	    (struct bcm2835_mbox_hdr *)msg, msg_size);
+
+	bus_dmamap_unload(msg_tag, msg_map);
+	bus_dmamem_free(msg_tag, buf, msg_map);
+	bus_dma_tag_destroy(msg_tag);
+out:
+	sx_xunlock(&sc->property_chan_lock);
+	return (err);
+}
+
+int
+bcm2835_mbox_set_power_state(uint32_t device_id, boolean_t on)
+{
+	struct msg_set_power_state msg;
+	int err;
+
+	memset(&msg, 0, sizeof(msg));
+	msg.hdr.buf_size = sizeof(msg);
+	msg.hdr.code = BCM2835_MBOX_CODE_REQ;
+	msg.tag_hdr.tag = BCM2835_MBOX_TAG_SET_POWER_STATE;
+	msg.tag_hdr.val_buf_size = sizeof(msg.body);
+	msg.tag_hdr.val_len = sizeof(msg.body.req);
+	msg.body.req.device_id = device_id;
+	msg.body.req.state = (on ? BCM2835_MBOX_POWER_ON : 0) |
+	    BCM2835_MBOX_POWER_WAIT;
+	msg.end_tag = 0;
+
+	err = bcm2835_mbox_property(&msg, sizeof(msg));
+
+	return (err);
+}
+
+int
+bcm2835_mbox_get_clock_rate(uint32_t clock_id, uint32_t *hz)
+{
+	struct msg_get_clock_rate msg;
+	int err;
+
+	memset(&msg, 0, sizeof(msg));
+	msg.hdr.buf_size = sizeof(msg);
+	msg.hdr.code = BCM2835_MBOX_CODE_REQ;
+	msg.tag_hdr.tag = BCM2835_MBOX_TAG_GET_CLOCK_RATE;
+	msg.tag_hdr.val_buf_size = sizeof(msg.body);
+	msg.tag_hdr.val_len = sizeof(msg.body.req);
+	msg.body.req.clock_id = clock_id;
+	msg.end_tag = 0;
+
+	err = bcm2835_mbox_property(&msg, sizeof(msg));
+	*hz = msg.body.resp.rate_hz;
+
+	return (err);
+}
+
+int
+bcm2835_mbox_fb_get_w_h(struct bcm2835_fb_config *fb)
+{
+	int err;
+	struct msg_fb_get_w_h msg;
+
+	memset(&msg, 0, sizeof(msg));
+	msg.hdr.buf_size = sizeof(msg);
+	msg.hdr.code = BCM2835_MBOX_CODE_REQ;
+	BCM2835_MBOX_INIT_TAG(&msg.physical_w_h, GET_PHYSICAL_W_H);
+	msg.physical_w_h.tag_hdr.val_len = 0;
+	msg.end_tag = 0;
+
+	err = bcm2835_mbox_property(&msg, sizeof(msg));
+	if (err == 0) {
+		fb->xres = msg.physical_w_h.body.resp.width;
+		fb->yres = msg.physical_w_h.body.resp.height;
+	}
+
+	return (err);
+}
+
+int
+bcm2835_mbox_fb_init(struct bcm2835_fb_config *fb)
+{
+	int err;
+	struct msg_fb_setup msg;
+
+	memset(&msg, 0, sizeof(msg));
+	msg.hdr.buf_size = sizeof(msg);
+	msg.hdr.code = BCM2835_MBOX_CODE_REQ;
+	BCM2835_MBOX_INIT_TAG(&msg.physical_w_h, SET_PHYSICAL_W_H);
+	msg.physical_w_h.body.req.width = fb->xres;
+	msg.physical_w_h.body.req.height = fb->yres;
+	BCM2835_MBOX_INIT_TAG(&msg.virtual_w_h, SET_VIRTUAL_W_H);
+	msg.virtual_w_h.body.req.width = fb->vxres;
+	msg.virtual_w_h.body.req.height = fb->vyres;
+	BCM2835_MBOX_INIT_TAG(&msg.offset, SET_VIRTUAL_OFFSET);
+	msg.offset.body.req.x = fb->xoffset;
+	msg.offset.body.req.y = fb->yoffset;
+	BCM2835_MBOX_INIT_TAG(&msg.depth, SET_DEPTH);
+	msg.depth.body.req.bpp = fb->bpp;
+	BCM2835_MBOX_INIT_TAG(&msg.alpha, SET_ALPHA_MODE);
+	msg.alpha.body.req.alpha = BCM2835_MBOX_ALPHA_MODE_IGNORED;
+	BCM2835_MBOX_INIT_TAG(&msg.buffer, ALLOCATE_BUFFER);
+	msg.buffer.body.req.alignment = PAGE_SIZE;
+	BCM2835_MBOX_INIT_TAG(&msg.pitch, GET_PITCH);
+	msg.end_tag = 0;
+
+	err = bcm2835_mbox_property(&msg, sizeof(msg));
+	if (err == 0) {
+		fb->xres = msg.physical_w_h.body.resp.width;
+		fb->yres = msg.physical_w_h.body.resp.height;
+		fb->vxres = msg.virtual_w_h.body.resp.width;
+		fb->vyres = msg.virtual_w_h.body.resp.height;
+		fb->xoffset = msg.offset.body.resp.x;
+		fb->yoffset = msg.offset.body.resp.y;
+		fb->pitch = msg.pitch.body.resp.pitch;
+		fb->base = VCBUS_TO_PHYS(msg.buffer.body.resp.fb_address);
+		fb->size = msg.buffer.body.resp.fb_size;
+	}
+
+	return (err);
+}


Property changes on: trunk/sys/arm/broadcom/bcm2835/bcm2835_mbox.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/broadcom/bcm2835/bcm2835_mbox.h
===================================================================
--- trunk/sys/arm/broadcom/bcm2835/bcm2835_mbox.h	                        (rev 0)
+++ trunk/sys/arm/broadcom/bcm2835/bcm2835_mbox.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,43 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Oleksandr Tymoshenko <gonzo at freebsd.org>
+ * 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: stable/10/sys/arm/broadcom/bcm2835/bcm2835_mbox.h 278608 2015-02-12 00:25:33Z ian $
+ */
+
+#ifndef _BCM2835_MBOX_H_
+#define _BCM2835_MBOX_H_
+
+#define	BCM2835_MBOX_CHAN_POWER		0
+#define	BCM2835_MBOX_CHAN_FB		1
+#define	BCM2835_MBOX_CHAN_VUART		2
+#define	BCM2835_MBOX_CHAN_VCHIQ		3
+#define	BCM2835_MBOX_CHAN_LEDS		4
+#define	BCM2835_MBOX_CHAN_BUTTONS	5
+#define	BCM2835_MBOX_CHAN_TS		6
+#define	BCM2835_MBOX_CHAN_PROP		8
+#define	BCM2835_MBOX_CHANS		9
+
+#endif /* _BCM2835_MBOX_H_ */


Property changes on: trunk/sys/arm/broadcom/bcm2835/bcm2835_mbox.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/broadcom/bcm2835/bcm2835_mbox_prop.h
===================================================================
--- trunk/sys/arm/broadcom/bcm2835/bcm2835_mbox_prop.h	                        (rev 0)
+++ trunk/sys/arm/broadcom/bcm2835/bcm2835_mbox_prop.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,479 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (C) 2013-2014 Daisuke Aoyama <aoyama at peach.ne.jp>
+ * 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: stable/10/sys/arm/broadcom/bcm2835/bcm2835_mbox_prop.h 322724 2017-08-20 16:52:27Z marius $
+ */
+
+#ifndef _BCM2835_MBOX_PROP_H_
+#define _BCM2835_MBOX_PROP_H_
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+/*
+ * Mailbox property interface:
+ * https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface
+ */
+#define BCM2835_MBOX_CODE_REQ			0
+#define BCM2835_MBOX_CODE_RESP_SUCCESS		0x80000000
+#define BCM2835_MBOX_CODE_RESP_ERROR		0x80000001
+#define BCM2835_MBOX_TAG_VAL_LEN_RESPONSE	0x80000000
+
+struct bcm2835_mbox_hdr {
+	uint32_t	buf_size;
+	uint32_t	code;
+};
+
+struct bcm2835_mbox_tag_hdr {
+	uint32_t	tag;
+	uint32_t	val_buf_size;
+	uint32_t	val_len;
+};
+
+#define	BCM2835_MBOX_INIT_TAG(tag_, tagid_) do {		\
+	(tag_)->tag_hdr.tag = BCM2835_MBOX_TAG_##tagid_;	\
+	(tag_)->tag_hdr.val_buf_size = sizeof((tag_)->body);	\
+	(tag_)->tag_hdr.val_len = sizeof((tag_)->body.req);	\
+} while (0)
+
+#define BCM2835_MBOX_POWER_ID_EMMC		0x00000000
+#define BCM2835_MBOX_POWER_ID_UART0		0x00000001
+#define BCM2835_MBOX_POWER_ID_UART1		0x00000002
+#define BCM2835_MBOX_POWER_ID_USB_HCD		0x00000003
+#define BCM2835_MBOX_POWER_ID_I2C0		0x00000004
+#define BCM2835_MBOX_POWER_ID_I2C1		0x00000005
+#define BCM2835_MBOX_POWER_ID_I2C2		0x00000006
+#define BCM2835_MBOX_POWER_ID_SPI		0x00000007
+#define BCM2835_MBOX_POWER_ID_CCP2TX		0x00000008
+
+#define BCM2835_MBOX_POWER_ON			(1 << 0)
+#define BCM2835_MBOX_POWER_WAIT			(1 << 1)
+
+#define BCM2835_MBOX_TAG_GET_POWER_STATE	0x00020001
+#define BCM2835_MBOX_TAG_SET_POWER_STATE	0x00028001
+
+struct msg_get_power_state {
+	struct bcm2835_mbox_hdr hdr;
+	struct bcm2835_mbox_tag_hdr tag_hdr;
+	union {
+		struct {
+			uint32_t device_id;
+		} req;
+		struct {
+			uint32_t device_id;
+			uint32_t state;
+		} resp;
+	} body;
+	uint32_t end_tag;
+};
+
+struct msg_set_power_state {
+	struct bcm2835_mbox_hdr hdr;
+	struct bcm2835_mbox_tag_hdr tag_hdr;
+	union {
+		struct {
+			uint32_t device_id;
+			uint32_t state;
+		} req;
+		struct {
+			uint32_t device_id;
+			uint32_t state;
+		} resp;
+	} body;
+	uint32_t end_tag;
+};
+
+/* Sets the power state for a given device */
+int bcm2835_mbox_set_power_state(uint32_t, boolean_t);
+
+#define BCM2835_MBOX_CLOCK_ID_EMMC		0x00000001
+#define BCM2835_MBOX_CLOCK_ID_UART		0x00000002
+#define BCM2835_MBOX_CLOCK_ID_ARM		0x00000003
+#define BCM2835_MBOX_CLOCK_ID_CORE		0x00000004
+#define BCM2835_MBOX_CLOCK_ID_V3D		0x00000005
+#define BCM2835_MBOX_CLOCK_ID_H264		0x00000006
+#define BCM2835_MBOX_CLOCK_ID_ISP		0x00000007
+#define BCM2835_MBOX_CLOCK_ID_SDRAM		0x00000008
+#define BCM2835_MBOX_CLOCK_ID_PIXEL		0x00000009
+#define BCM2835_MBOX_CLOCK_ID_PWM		0x0000000a
+
+#define BCM2835_MBOX_TAG_GET_CLOCK_RATE		0x00030002
+#define BCM2835_MBOX_TAG_SET_CLOCK_RATE		0x00038002
+#define BCM2835_MBOX_TAG_GET_MAX_CLOCK_RATE	0x00030004
+#define BCM2835_MBOX_TAG_GET_MIN_CLOCK_RATE	0x00030007
+
+struct msg_get_clock_rate {
+	struct bcm2835_mbox_hdr hdr;
+	struct bcm2835_mbox_tag_hdr tag_hdr;
+	union {
+		struct {
+			uint32_t clock_id;
+		} req;
+		struct {
+			uint32_t clock_id;
+			uint32_t rate_hz;
+		} resp;
+	} body;
+	uint32_t end_tag;
+};
+
+struct msg_set_clock_rate {
+	struct bcm2835_mbox_hdr hdr;
+	struct bcm2835_mbox_tag_hdr tag_hdr;
+	union {
+		struct {
+			uint32_t clock_id;
+			uint32_t rate_hz;
+		} req;
+		struct {
+			uint32_t clock_id;
+			uint32_t rate_hz;
+		} resp;
+	} body;
+	uint32_t end_tag;
+};
+
+struct msg_get_max_clock_rate {
+	struct bcm2835_mbox_hdr hdr;
+	struct bcm2835_mbox_tag_hdr tag_hdr;
+	union {
+		struct {
+			uint32_t clock_id;
+		} req;
+		struct {
+			uint32_t clock_id;
+			uint32_t rate_hz;
+		} resp;
+	} body;
+	uint32_t end_tag;
+};
+
+struct msg_get_min_clock_rate {
+	struct bcm2835_mbox_hdr hdr;
+	struct bcm2835_mbox_tag_hdr tag_hdr;
+	union {
+		struct {
+			uint32_t clock_id;
+		} req;
+		struct {
+			uint32_t clock_id;
+			uint32_t rate_hz;
+		} resp;
+	} body;
+	uint32_t end_tag;
+};
+
+int bcm2835_mbox_get_clock_rate(uint32_t, uint32_t *);
+
+#define BCM2835_MBOX_TURBO_ON			1
+#define BCM2835_MBOX_TURBO_OFF			0
+
+#define BCM2835_MBOX_TAG_GET_TURBO		0x00030009
+#define BCM2835_MBOX_TAG_SET_TURBO		0x00038009
+
+struct msg_get_turbo {
+	struct bcm2835_mbox_hdr hdr;
+	struct bcm2835_mbox_tag_hdr tag_hdr;
+	union {
+		struct {
+			uint32_t id;
+		} req;
+		struct {
+			uint32_t id;
+			uint32_t level;
+		} resp;
+	} body;
+	uint32_t end_tag;
+};
+
+struct msg_set_turbo {
+	struct bcm2835_mbox_hdr hdr;
+	struct bcm2835_mbox_tag_hdr tag_hdr;
+	union {
+		struct {
+			uint32_t id;
+			uint32_t level;
+		} req;
+		struct {
+			uint32_t id;
+			uint32_t level;
+		} resp;
+	} body;
+	uint32_t end_tag;
+};
+
+#define BCM2835_MBOX_VOLTAGE_ID_CORE		0x00000001
+#define BCM2835_MBOX_VOLTAGE_ID_SDRAM_C		0x00000002
+#define BCM2835_MBOX_VOLTAGE_ID_SDRAM_P		0x00000003
+#define BCM2835_MBOX_VOLTAGE_ID_SDRAM_I		0x00000004
+
+#define BCM2835_MBOX_TAG_GET_VOLTAGE		0x00030003
+#define BCM2835_MBOX_TAG_SET_VOLTAGE		0x00038003
+#define BCM2835_MBOX_TAG_GET_MAX_VOLTAGE	0x00030005
+#define BCM2835_MBOX_TAG_GET_MIN_VOLTAGE	0x00030008
+
+struct msg_get_voltage {
+	struct bcm2835_mbox_hdr hdr;
+	struct bcm2835_mbox_tag_hdr tag_hdr;
+	union {
+		struct {
+			uint32_t voltage_id;
+		} req;
+		struct {
+			uint32_t voltage_id;
+			uint32_t value;
+		} resp;
+	} body;
+	uint32_t end_tag;
+};
+
+struct msg_set_voltage {
+	struct bcm2835_mbox_hdr hdr;
+	struct bcm2835_mbox_tag_hdr tag_hdr;
+	union {
+		struct {
+			uint32_t voltage_id;
+			uint32_t value;
+		} req;
+		struct {
+			uint32_t voltage_id;
+			uint32_t value;
+		} resp;
+	} body;
+	uint32_t end_tag;
+};
+
+struct msg_get_max_voltage {
+	struct bcm2835_mbox_hdr hdr;
+	struct bcm2835_mbox_tag_hdr tag_hdr;
+	union {
+		struct {
+			uint32_t voltage_id;
+		} req;
+		struct {
+			uint32_t voltage_id;
+			uint32_t value;
+		} resp;
+	} body;
+	uint32_t end_tag;
+};
+
+struct msg_get_min_voltage {
+	struct bcm2835_mbox_hdr hdr;
+	struct bcm2835_mbox_tag_hdr tag_hdr;
+	union {
+		struct {
+			uint32_t voltage_id;
+		} req;
+		struct {
+			uint32_t voltage_id;
+			uint32_t value;
+		} resp;
+	} body;
+	uint32_t end_tag;
+};
+
+#define BCM2835_MBOX_TAG_GET_TEMPERATURE	0x00030006
+#define BCM2835_MBOX_TAG_GET_MAX_TEMPERATURE	0x0003000a
+
+struct msg_get_temperature {
+	struct bcm2835_mbox_hdr hdr;
+	struct bcm2835_mbox_tag_hdr tag_hdr;
+	union {
+		struct {
+			uint32_t temperature_id;
+		} req;
+		struct {
+			uint32_t temperature_id;
+			uint32_t value;
+		} resp;
+	} body;
+	uint32_t end_tag;
+};
+
+struct msg_get_max_temperature {
+	struct bcm2835_mbox_hdr hdr;
+	struct bcm2835_mbox_tag_hdr tag_hdr;
+	union {
+		struct {
+			uint32_t temperature_id;
+		} req;
+		struct {
+			uint32_t temperature_id;
+			uint32_t value;
+		} resp;
+	} body;
+	uint32_t end_tag;
+};
+
+#define	BCM2835_MBOX_TAG_GET_PHYSICAL_W_H	0x00040003
+#define	BCM2835_MBOX_TAG_SET_PHYSICAL_W_H	0x00048003
+#define	BCM2835_MBOX_TAG_GET_VIRTUAL_W_H	0x00040004
+#define	BCM2835_MBOX_TAG_SET_VIRTUAL_W_H	0x00048004
+
+struct bcm2835_mbox_tag_fb_w_h {
+	struct bcm2835_mbox_tag_hdr tag_hdr;
+	union {
+		struct {
+			uint32_t width;
+			uint32_t height;
+		} req;
+		struct {
+			uint32_t width;
+			uint32_t height;
+		} resp;
+	} body;
+};
+
+#define	BCM2835_MBOX_TAG_GET_DEPTH		0x00040005
+#define	BCM2835_MBOX_TAG_SET_DEPTH		0x00048005
+
+struct bcm2835_mbox_tag_depth {
+	struct bcm2835_mbox_tag_hdr tag_hdr;
+	union {
+		struct {
+			uint32_t bpp;
+		} req;
+		struct {
+			uint32_t bpp;
+		} resp;
+	} body;
+};
+
+#define	BCM2835_MBOX_TAG_GET_ALPHA_MODE		0x00040007
+#define	BCM2835_MBOX_TAG_SET_ALPHA_MODE		0x00048007
+
+#define	BCM2835_MBOX_ALPHA_MODE_0_OPAQUE	0
+#define	BCM2835_MBOX_ALPHA_MODE_0_TRANSPARENT	1
+#define	BCM2835_MBOX_ALPHA_MODE_IGNORED		2
+
+struct bcm2835_mbox_tag_alpha_mode {
+	struct bcm2835_mbox_tag_hdr tag_hdr;
+	union {
+		struct {
+			uint32_t alpha;
+		} req;
+		struct {
+			uint32_t alpha;
+		} resp;
+	} body;
+};
+
+#define	BCM2835_MBOX_TAG_GET_VIRTUAL_OFFSET	0x00040009
+#define	BCM2835_MBOX_TAG_SET_VIRTUAL_OFFSET	0x00048009
+
+struct bcm2835_mbox_tag_virtual_offset {
+	struct bcm2835_mbox_tag_hdr tag_hdr;
+	union {
+		struct {
+			uint32_t x;
+			uint32_t y;
+		} req;
+		struct {
+			uint32_t x;
+			uint32_t y;
+		} resp;
+	} body;
+};
+
+#define	BCM2835_MBOX_TAG_GET_PITCH		0x00040008
+
+struct bcm2835_mbox_tag_pitch {
+	struct bcm2835_mbox_tag_hdr tag_hdr;
+	union {
+		struct {
+		} req;
+		struct {
+			uint32_t pitch;
+		} resp;
+	} body;
+};
+
+#define	BCM2835_MBOX_TAG_ALLOCATE_BUFFER	0x00040001
+
+struct bcm2835_mbox_tag_allocate_buffer {
+	struct bcm2835_mbox_tag_hdr tag_hdr;
+	union {
+		struct {
+			uint32_t alignment;
+		} req;
+		struct {
+			uint32_t fb_address;
+			uint32_t fb_size;
+		} resp;
+	} body;
+};
+
+#define	BCM2835_MBOX_TAG_RELEASE_BUFFER		0x00048001
+
+struct bcm2835_mbox_tag_release_buffer {
+	struct bcm2835_mbox_tag_hdr tag_hdr;
+	union {
+		struct {
+		} req;
+		struct {
+		} resp;
+	} body;
+};
+
+struct bcm2835_fb_config {
+	uint32_t xres;
+	uint32_t yres;
+	uint32_t vxres;
+	uint32_t vyres;
+	uint32_t xoffset;
+	uint32_t yoffset;
+	uint32_t bpp;
+	uint32_t pitch;
+	uint32_t base;
+	uint32_t size;
+};
+
+struct msg_fb_get_w_h {
+	struct bcm2835_mbox_hdr hdr;
+	struct bcm2835_mbox_tag_fb_w_h physical_w_h;
+	uint32_t end_tag;
+};
+
+int bcm2835_mbox_fb_get_w_h(struct bcm2835_fb_config *);
+
+struct msg_fb_setup {
+	struct bcm2835_mbox_hdr hdr;
+	struct bcm2835_mbox_tag_fb_w_h physical_w_h;
+	struct bcm2835_mbox_tag_fb_w_h virtual_w_h;
+	struct bcm2835_mbox_tag_virtual_offset offset;
+	struct bcm2835_mbox_tag_depth depth;
+	struct bcm2835_mbox_tag_alpha_mode alpha;
+	struct bcm2835_mbox_tag_allocate_buffer buffer;
+	struct bcm2835_mbox_tag_pitch pitch;
+	uint32_t end_tag;
+};
+
+int bcm2835_mbox_fb_init(struct bcm2835_fb_config *);
+
+int bcm2835_mbox_property(void *, size_t);
+
+#endif /* _BCM2835_MBOX_PROP_H_ */


Property changes on: trunk/sys/arm/broadcom/bcm2835/bcm2835_mbox_prop.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c
===================================================================
--- trunk/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c	                        (rev 0)
+++ trunk/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,683 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Oleksandr Tymoshenko <gonzo at freebsd.org>
+ * 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: stable/10/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c 322724 2017-08-20 16:52:27Z marius $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/rman.h>
+#include <sys/sysctl.h>
+#include <sys/taskqueue.h>
+
+#include <machine/bus.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <dev/mmc/bridge.h>
+#include <dev/mmc/mmcreg.h>
+
+#include <dev/sdhci/sdhci.h>
+
+#include "mmcbr_if.h"
+#include "sdhci_if.h"
+
+#include "bcm2835_dma.h"
+#include <arm/broadcom/bcm2835/bcm2835_mbox_prop.h>
+#include "bcm2835_vcbus.h"
+
+#define	BCM2835_DEFAULT_SDHCI_FREQ	50
+
+#define	BCM_SDHCI_BUFFER_SIZE		512
+#define	NUM_DMA_SEGS			2
+
+#ifdef DEBUG
+#define dprintf(fmt, args...) do { printf("%s(): ", __func__);   \
+    printf(fmt,##args); } while (0)
+#else
+#define dprintf(fmt, args...)
+#endif
+
+static int bcm2835_sdhci_hs = 1;
+static int bcm2835_sdhci_pio_mode = 0;
+
+static struct ofw_compat_data compat_data[] = {
+	{"broadcom,bcm2835-sdhci",	1},
+	{"brcm,bcm2835-mmc",		1},
+	{NULL,				0}
+};
+
+TUNABLE_INT("hw.bcm2835.sdhci.hs", &bcm2835_sdhci_hs);
+TUNABLE_INT("hw.bcm2835.sdhci.pio_mode", &bcm2835_sdhci_pio_mode);
+
+struct bcm_sdhci_softc {
+	device_t		sc_dev;
+	struct resource *	sc_mem_res;
+	struct resource *	sc_irq_res;
+	bus_space_tag_t		sc_bst;
+	bus_space_handle_t	sc_bsh;
+	void *			sc_intrhand;
+	struct mmc_request *	sc_req;
+	struct sdhci_slot	sc_slot;
+	int			sc_dma_ch;
+	bus_dma_tag_t		sc_dma_tag;
+	bus_dmamap_t		sc_dma_map;
+	vm_paddr_t		sc_sdhci_buffer_phys;
+	uint32_t		cmd_and_mode;
+	bus_addr_t		dmamap_seg_addrs[NUM_DMA_SEGS];
+	bus_size_t		dmamap_seg_sizes[NUM_DMA_SEGS];
+	int			dmamap_seg_count;
+	int			dmamap_seg_index;
+	int			dmamap_status;
+};
+
+static int bcm_sdhci_probe(device_t);
+static int bcm_sdhci_attach(device_t);
+static int bcm_sdhci_detach(device_t);
+static void bcm_sdhci_intr(void *);
+
+static int bcm_sdhci_get_ro(device_t, device_t);
+static void bcm_sdhci_dma_intr(int ch, void *arg);
+
+static void
+bcm_sdhci_dmacb(void *arg, bus_dma_segment_t *segs, int nseg, int err)
+{
+	struct bcm_sdhci_softc *sc = arg;
+	int i;
+
+	sc->dmamap_status = err;
+	sc->dmamap_seg_count = nseg;
+
+	/* Note nseg is guaranteed to be zero if err is non-zero. */
+	for (i = 0; i < nseg; i++) {
+		sc->dmamap_seg_addrs[i] = segs[i].ds_addr;
+		sc->dmamap_seg_sizes[i] = segs[i].ds_len;
+	}
+}
+
+static int
+bcm_sdhci_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
+		return (ENXIO);
+
+	device_set_desc(dev, "Broadcom 2708 SDHCI controller");
+
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+bcm_sdhci_attach(device_t dev)
+{
+	struct bcm_sdhci_softc *sc = device_get_softc(dev);
+	int rid, err;
+	phandle_t node;
+	pcell_t cell;
+	u_int default_freq;
+
+	sc->sc_dev = dev;
+	sc->sc_req = NULL;
+
+	err = bcm2835_mbox_set_power_state(BCM2835_MBOX_POWER_ID_EMMC,
+	    TRUE);
+	if (err != 0) {
+		if (bootverbose)
+			device_printf(dev, "Unable to enable the power\n");
+		return (err);
+	}
+
+	default_freq = 0;
+	err = bcm2835_mbox_get_clock_rate(BCM2835_MBOX_CLOCK_ID_EMMC,
+	    &default_freq);
+	if (err == 0) {
+		/* Convert to MHz */
+		default_freq /= 1000000;
+	}
+	if (default_freq == 0) {
+		node = ofw_bus_get_node(sc->sc_dev);
+		if ((OF_getencprop(node, "clock-frequency", &cell,
+		    sizeof(cell))) > 0)
+			default_freq = cell / 1000000;
+	}
+	if (default_freq == 0)
+		default_freq = BCM2835_DEFAULT_SDHCI_FREQ;
+
+	if (bootverbose)
+		device_printf(dev, "SDHCI frequency: %dMHz\n", default_freq);
+
+	rid = 0;
+	sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	    RF_ACTIVE);
+	if (!sc->sc_mem_res) {
+		device_printf(dev, "cannot allocate memory window\n");
+		err = ENXIO;
+		goto fail;
+	}
+
+	sc->sc_bst = rman_get_bustag(sc->sc_mem_res);
+	sc->sc_bsh = rman_get_bushandle(sc->sc_mem_res);
+
+	rid = 0;
+	sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+	    RF_ACTIVE);
+	if (!sc->sc_irq_res) {
+		device_printf(dev, "cannot allocate interrupt\n");
+		err = ENXIO;
+		goto fail;
+	}
+
+	if (bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
+	    NULL, bcm_sdhci_intr, sc, &sc->sc_intrhand)) {
+		device_printf(dev, "cannot setup interrupt handler\n");
+		err = ENXIO;
+		goto fail;
+	}
+
+	if (!bcm2835_sdhci_pio_mode)
+		sc->sc_slot.opt = SDHCI_PLATFORM_TRANSFER;
+
+	sc->sc_slot.caps = SDHCI_CAN_VDD_330 | SDHCI_CAN_VDD_180;
+	if (bcm2835_sdhci_hs)
+		sc->sc_slot.caps |= SDHCI_CAN_DO_HISPD;
+	sc->sc_slot.caps |= (default_freq << SDHCI_CLOCK_BASE_SHIFT);
+	sc->sc_slot.quirks = SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK 
+		| SDHCI_QUIRK_BROKEN_TIMEOUT_VAL
+		| SDHCI_QUIRK_DONT_SET_HISPD_BIT
+		| SDHCI_QUIRK_MISSING_CAPS;
+ 
+	sdhci_init_slot(dev, &sc->sc_slot, 0);
+
+	sc->sc_dma_ch = bcm_dma_allocate(BCM_DMA_CH_ANY);
+	if (sc->sc_dma_ch == BCM_DMA_CH_INVALID)
+		goto fail;
+
+	bcm_dma_setup_intr(sc->sc_dma_ch, bcm_sdhci_dma_intr, sc);
+
+	/* Allocate bus_dma resources. */
+	err = bus_dma_tag_create(bus_get_dma_tag(dev),
+	    1, 0, BUS_SPACE_MAXADDR_32BIT,
+	    BUS_SPACE_MAXADDR, NULL, NULL,
+	    BCM_SDHCI_BUFFER_SIZE, NUM_DMA_SEGS, BCM_SDHCI_BUFFER_SIZE,
+	    BUS_DMA_ALLOCNOW, NULL, NULL,
+	    &sc->sc_dma_tag);
+
+	if (err) {
+		device_printf(dev, "failed allocate DMA tag");
+		goto fail;
+	}
+
+	err = bus_dmamap_create(sc->sc_dma_tag, 0, &sc->sc_dma_map);
+	if (err) {
+		device_printf(dev, "bus_dmamap_create failed\n");
+		goto fail;
+	}
+
+	sc->sc_sdhci_buffer_phys = BUS_SPACE_PHYSADDR(sc->sc_mem_res, 
+	    SDHCI_BUFFER);
+
+	bus_generic_probe(dev);
+	bus_generic_attach(dev);
+
+	sdhci_start_slot(&sc->sc_slot);
+
+	return (0);
+
+fail:
+	if (sc->sc_intrhand)
+		bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_intrhand);
+	if (sc->sc_irq_res)
+		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res);
+	if (sc->sc_mem_res)
+		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
+
+	return (err);
+}
+
+static int
+bcm_sdhci_detach(device_t dev)
+{
+
+	return (EBUSY);
+}
+
+static void
+bcm_sdhci_intr(void *arg)
+{
+	struct bcm_sdhci_softc *sc = arg;
+
+	sdhci_generic_intr(&sc->sc_slot);
+}
+
+static int
+bcm_sdhci_get_ro(device_t bus, device_t child)
+{
+
+	return (0);
+}
+
+static inline uint32_t
+RD4(struct bcm_sdhci_softc *sc, bus_size_t off)
+{
+	uint32_t val = bus_space_read_4(sc->sc_bst, sc->sc_bsh, off);
+	return val;
+}
+
+static inline void
+WR4(struct bcm_sdhci_softc *sc, bus_size_t off, uint32_t val)
+{
+
+	bus_space_write_4(sc->sc_bst, sc->sc_bsh, off, val);
+	/*
+	 * The Arasan HC has a bug where it may lose the content of
+	 * consecutive writes to registers that are within two SD-card
+	 * clock cycles of each other (a clock domain crossing problem). 
+	 */
+	if (sc->sc_slot.clock > 0)
+		DELAY(((2 * 1000000) / sc->sc_slot.clock) + 1);
+}
+
+static uint8_t
+bcm_sdhci_read_1(device_t dev, struct sdhci_slot *slot, bus_size_t off)
+{
+	struct bcm_sdhci_softc *sc = device_get_softc(dev);
+	uint32_t val = RD4(sc, off & ~3);
+
+	return ((val >> (off & 3)*8) & 0xff);
+}
+
+static uint16_t
+bcm_sdhci_read_2(device_t dev, struct sdhci_slot *slot, bus_size_t off)
+{
+	struct bcm_sdhci_softc *sc = device_get_softc(dev);
+	uint32_t val = RD4(sc, off & ~3);
+
+	/*
+	 * Standard 32-bit handling of command and transfer mode.
+	 */
+	if (off == SDHCI_TRANSFER_MODE) {
+		return (sc->cmd_and_mode >> 16);
+	} else if (off == SDHCI_COMMAND_FLAGS) {
+		return (sc->cmd_and_mode & 0x0000ffff);
+	}
+	return ((val >> (off & 3)*8) & 0xffff);
+}
+
+static uint32_t
+bcm_sdhci_read_4(device_t dev, struct sdhci_slot *slot, bus_size_t off)
+{
+	struct bcm_sdhci_softc *sc = device_get_softc(dev);
+
+	return RD4(sc, off);
+}
+
+static void
+bcm_sdhci_read_multi_4(device_t dev, struct sdhci_slot *slot, bus_size_t off,
+    uint32_t *data, bus_size_t count)
+{
+	struct bcm_sdhci_softc *sc = device_get_softc(dev);
+
+	bus_space_read_multi_4(sc->sc_bst, sc->sc_bsh, off, data, count);
+}
+
+static void
+bcm_sdhci_write_1(device_t dev, struct sdhci_slot *slot, bus_size_t off, uint8_t val)
+{
+	struct bcm_sdhci_softc *sc = device_get_softc(dev);
+	uint32_t val32 = RD4(sc, off & ~3);
+	val32 &= ~(0xff << (off & 3)*8);
+	val32 |= (val << (off & 3)*8);
+	WR4(sc, off & ~3, val32);
+}
+
+static void
+bcm_sdhci_write_2(device_t dev, struct sdhci_slot *slot, bus_size_t off, uint16_t val)
+{
+	struct bcm_sdhci_softc *sc = device_get_softc(dev);
+	uint32_t val32;
+	if (off == SDHCI_COMMAND_FLAGS)
+		val32 = sc->cmd_and_mode;
+	else
+		val32 = RD4(sc, off & ~3);
+	val32 &= ~(0xffff << (off & 3)*8);
+	val32 |= (val << (off & 3)*8);
+	if (off == SDHCI_TRANSFER_MODE)
+		sc->cmd_and_mode = val32;
+	else {
+		WR4(sc, off & ~3, val32);
+		if (off == SDHCI_COMMAND_FLAGS)
+			sc->cmd_and_mode = val32;
+	}
+}
+
+static void
+bcm_sdhci_write_4(device_t dev, struct sdhci_slot *slot, bus_size_t off, uint32_t val)
+{
+	struct bcm_sdhci_softc *sc = device_get_softc(dev);
+	WR4(sc, off, val);
+}
+
+static void
+bcm_sdhci_write_multi_4(device_t dev, struct sdhci_slot *slot, bus_size_t off,
+    uint32_t *data, bus_size_t count)
+{
+	struct bcm_sdhci_softc *sc = device_get_softc(dev);
+
+	bus_space_write_multi_4(sc->sc_bst, sc->sc_bsh, off, data, count);
+}
+
+static void
+bcm_sdhci_start_dma_seg(struct bcm_sdhci_softc *sc)
+{
+	struct sdhci_slot *slot;
+	vm_paddr_t pdst, psrc;
+	int err, idx, len, sync_op;
+
+	slot = &sc->sc_slot;
+	idx = sc->dmamap_seg_index++;
+	len = sc->dmamap_seg_sizes[idx];
+	slot->offset += len;
+
+	if (slot->curcmd->data->flags & MMC_DATA_READ) {
+		bcm_dma_setup_src(sc->sc_dma_ch, BCM_DMA_DREQ_EMMC,
+		    BCM_DMA_SAME_ADDR, BCM_DMA_32BIT); 
+		bcm_dma_setup_dst(sc->sc_dma_ch, BCM_DMA_DREQ_NONE,
+		    BCM_DMA_INC_ADDR,
+		    (len & 0xf) ? BCM_DMA_32BIT : BCM_DMA_128BIT);
+		psrc = sc->sc_sdhci_buffer_phys;
+		pdst = sc->dmamap_seg_addrs[idx];
+		sync_op = BUS_DMASYNC_PREREAD;
+	} else {
+		bcm_dma_setup_src(sc->sc_dma_ch, BCM_DMA_DREQ_NONE,
+		    BCM_DMA_INC_ADDR,
+		    (len & 0xf) ? BCM_DMA_32BIT : BCM_DMA_128BIT);
+		bcm_dma_setup_dst(sc->sc_dma_ch, BCM_DMA_DREQ_EMMC,
+		    BCM_DMA_SAME_ADDR, BCM_DMA_32BIT);
+		psrc = sc->dmamap_seg_addrs[idx];
+		pdst = sc->sc_sdhci_buffer_phys;
+		sync_op = BUS_DMASYNC_PREWRITE;
+	}
+
+	/*
+	 * When starting a new DMA operation do the busdma sync operation, and
+	 * disable SDCHI data interrrupts because we'll be driven by DMA
+	 * interrupts (or SDHCI error interrupts) until the IO is done.
+	 */
+	if (idx == 0) {
+		bus_dmamap_sync(sc->sc_dma_tag, sc->sc_dma_map, sync_op);
+		slot->intmask &= ~(SDHCI_INT_DATA_AVAIL | 
+		    SDHCI_INT_SPACE_AVAIL | SDHCI_INT_DATA_END);
+		bcm_sdhci_write_4(sc->sc_dev, &sc->sc_slot, SDHCI_SIGNAL_ENABLE,
+		    slot->intmask);
+	}
+
+	/*
+	 * Start the DMA transfer.  Only programming errors (like failing to
+	 * allocate a channel) cause a non-zero return from bcm_dma_start().
+	 */
+	err = bcm_dma_start(sc->sc_dma_ch, psrc, pdst, len);
+	KASSERT((err == 0), ("bcm2835_sdhci: failed DMA start"));
+}
+
+static void
+bcm_sdhci_dma_intr(int ch, void *arg)
+{
+	struct bcm_sdhci_softc *sc = (struct bcm_sdhci_softc *)arg;
+	struct sdhci_slot *slot = &sc->sc_slot;
+	uint32_t reg, mask;
+	int left, sync_op;
+
+	mtx_lock(&slot->mtx);
+
+	/*
+	 * If there are more segments for the current dma, start the next one.
+	 * Otherwise unload the dma map and decide what to do next based on the
+	 * status of the sdhci controller and whether there's more data left.
+	 */
+	if (sc->dmamap_seg_index < sc->dmamap_seg_count) {
+		bcm_sdhci_start_dma_seg(sc);
+		mtx_unlock(&slot->mtx);
+		return;
+	}
+
+	if (slot->curcmd->data->flags & MMC_DATA_READ) {
+		sync_op = BUS_DMASYNC_POSTREAD;
+		mask = SDHCI_INT_DATA_AVAIL;
+	} else {
+		sync_op = BUS_DMASYNC_POSTWRITE;
+		mask = SDHCI_INT_SPACE_AVAIL;
+	}
+	bus_dmamap_sync(sc->sc_dma_tag, sc->sc_dma_map, sync_op);
+	bus_dmamap_unload(sc->sc_dma_tag, sc->sc_dma_map);
+
+	sc->dmamap_seg_count = 0;
+	sc->dmamap_seg_index = 0;
+
+	left = min(BCM_SDHCI_BUFFER_SIZE,
+	    slot->curcmd->data->len - slot->offset);
+
+	/* DATA END? */
+	reg = bcm_sdhci_read_4(slot->bus, slot, SDHCI_INT_STATUS);
+
+	if (reg & SDHCI_INT_DATA_END) {
+		/* ACK for all outstanding interrupts */
+		bcm_sdhci_write_4(slot->bus, slot, SDHCI_INT_STATUS, reg);
+
+		/* enable INT */
+		slot->intmask |= SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL
+		    | SDHCI_INT_DATA_END;
+		bcm_sdhci_write_4(slot->bus, slot, SDHCI_SIGNAL_ENABLE,
+		    slot->intmask);
+
+		/* finish this data */
+		sdhci_finish_data(slot);
+	} 
+	else {
+		/* already available? */
+		if (reg & mask) {
+
+			/* ACK for DATA_AVAIL or SPACE_AVAIL */
+			bcm_sdhci_write_4(slot->bus, slot,
+			    SDHCI_INT_STATUS, mask);
+
+			/* continue next DMA transfer */
+			if (bus_dmamap_load(sc->sc_dma_tag, sc->sc_dma_map, 
+			    (uint8_t *)slot->curcmd->data->data + 
+			    slot->offset, left, bcm_sdhci_dmacb, sc, 
+			    BUS_DMA_NOWAIT) != 0 || sc->dmamap_status != 0) {
+				slot->curcmd->error = MMC_ERR_NO_MEMORY;
+				sdhci_finish_data(slot);
+			} else {
+				bcm_sdhci_start_dma_seg(sc);
+			}
+		} else {
+			/* wait for next data by INT */
+
+			/* enable INT */
+			slot->intmask |= SDHCI_INT_DATA_AVAIL |
+			    SDHCI_INT_SPACE_AVAIL | SDHCI_INT_DATA_END;
+			bcm_sdhci_write_4(slot->bus, slot, SDHCI_SIGNAL_ENABLE,
+			    slot->intmask);
+		}
+	}
+
+	mtx_unlock(&slot->mtx);
+}
+
+static void
+bcm_sdhci_read_dma(device_t dev, struct sdhci_slot *slot)
+{
+	struct bcm_sdhci_softc *sc = device_get_softc(slot->bus);
+	size_t left;
+
+	if (sc->dmamap_seg_count != 0) {
+		device_printf(sc->sc_dev, "DMA in use\n");
+		return;
+	}
+
+	left = min(BCM_SDHCI_BUFFER_SIZE,
+	    slot->curcmd->data->len - slot->offset);
+
+	KASSERT((left & 3) == 0,
+	    ("%s: len = %d, not word-aligned", __func__, left));
+
+	if (bus_dmamap_load(sc->sc_dma_tag, sc->sc_dma_map, 
+	    (uint8_t *)slot->curcmd->data->data + slot->offset, left, 
+	    bcm_sdhci_dmacb, sc, BUS_DMA_NOWAIT) != 0 ||
+	    sc->dmamap_status != 0) {
+		slot->curcmd->error = MMC_ERR_NO_MEMORY;
+		return;
+	}
+
+	/* DMA start */
+	bcm_sdhci_start_dma_seg(sc);
+}
+
+static void
+bcm_sdhci_write_dma(device_t dev, struct sdhci_slot *slot)
+{
+	struct bcm_sdhci_softc *sc = device_get_softc(slot->bus);
+	size_t left;
+
+	if (sc->dmamap_seg_count != 0) {
+		device_printf(sc->sc_dev, "DMA in use\n");
+		return;
+	}
+
+	left = min(BCM_SDHCI_BUFFER_SIZE,
+	    slot->curcmd->data->len - slot->offset);
+
+	KASSERT((left & 3) == 0,
+	    ("%s: len = %d, not word-aligned", __func__, left));
+
+	if (bus_dmamap_load(sc->sc_dma_tag, sc->sc_dma_map,
+	    (uint8_t *)slot->curcmd->data->data + slot->offset, left, 
+	    bcm_sdhci_dmacb, sc, BUS_DMA_NOWAIT) != 0 ||
+	    sc->dmamap_status != 0) {
+		slot->curcmd->error = MMC_ERR_NO_MEMORY;
+		return;
+	}
+
+	/* DMA start */
+	bcm_sdhci_start_dma_seg(sc);
+}
+
+static int
+bcm_sdhci_will_handle_transfer(device_t dev, struct sdhci_slot *slot)
+{
+	size_t left;
+
+	/*
+	 * Do not use DMA for transfers less than block size or with a length
+	 * that is not a multiple of four.
+	 */
+	left = min(BCM_DMA_BLOCK_SIZE,
+	    slot->curcmd->data->len - slot->offset);
+	if (left < BCM_DMA_BLOCK_SIZE)
+		return (0);
+	if (left & 0x03)
+		return (0);
+
+	return (1);
+}
+
+static void
+bcm_sdhci_start_transfer(device_t dev, struct sdhci_slot *slot,
+    uint32_t *intmask)
+{
+
+	/* DMA transfer FIFO 1KB */
+	if (slot->curcmd->data->flags & MMC_DATA_READ)
+		bcm_sdhci_read_dma(dev, slot);
+	else
+		bcm_sdhci_write_dma(dev, slot);
+}
+
+static void
+bcm_sdhci_finish_transfer(device_t dev, struct sdhci_slot *slot)
+{
+
+	sdhci_finish_data(slot);
+}
+
+static device_method_t bcm_sdhci_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		bcm_sdhci_probe),
+	DEVMETHOD(device_attach,	bcm_sdhci_attach),
+	DEVMETHOD(device_detach,	bcm_sdhci_detach),
+
+	/* Bus interface */
+	DEVMETHOD(bus_read_ivar,	sdhci_generic_read_ivar),
+	DEVMETHOD(bus_write_ivar,	sdhci_generic_write_ivar),
+
+	/* MMC bridge interface */
+	DEVMETHOD(mmcbr_update_ios,	sdhci_generic_update_ios),
+	DEVMETHOD(mmcbr_request,	sdhci_generic_request),
+	DEVMETHOD(mmcbr_get_ro,		bcm_sdhci_get_ro),
+	DEVMETHOD(mmcbr_acquire_host,	sdhci_generic_acquire_host),
+	DEVMETHOD(mmcbr_release_host,	sdhci_generic_release_host),
+
+	/* Platform transfer methods */
+	DEVMETHOD(sdhci_platform_will_handle,		bcm_sdhci_will_handle_transfer),
+	DEVMETHOD(sdhci_platform_start_transfer,	bcm_sdhci_start_transfer),
+	DEVMETHOD(sdhci_platform_finish_transfer,	bcm_sdhci_finish_transfer),
+	/* SDHCI registers accessors */
+	DEVMETHOD(sdhci_read_1,		bcm_sdhci_read_1),
+	DEVMETHOD(sdhci_read_2,		bcm_sdhci_read_2),
+	DEVMETHOD(sdhci_read_4,		bcm_sdhci_read_4),
+	DEVMETHOD(sdhci_read_multi_4,	bcm_sdhci_read_multi_4),
+	DEVMETHOD(sdhci_write_1,	bcm_sdhci_write_1),
+	DEVMETHOD(sdhci_write_2,	bcm_sdhci_write_2),
+	DEVMETHOD(sdhci_write_4,	bcm_sdhci_write_4),
+	DEVMETHOD(sdhci_write_multi_4,	bcm_sdhci_write_multi_4),
+
+	DEVMETHOD_END
+};
+
+static devclass_t bcm_sdhci_devclass;
+
+static driver_t bcm_sdhci_driver = {
+	"sdhci_bcm",
+	bcm_sdhci_methods,
+	sizeof(struct bcm_sdhci_softc),
+};
+
+DRIVER_MODULE(sdhci_bcm, simplebus, bcm_sdhci_driver, bcm_sdhci_devclass,
+    NULL, NULL);
+MODULE_DEPEND(sdhci_bcm, sdhci, 1, 1, 1);
+MMC_DECLARE_BRIDGE(sdhci_bcm);


Property changes on: trunk/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/broadcom/bcm2835/bcm2835_spi.c
===================================================================
--- trunk/sys/arm/broadcom/bcm2835/bcm2835_spi.c	                        (rev 0)
+++ trunk/sys/arm/broadcom/bcm2835/bcm2835_spi.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,529 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Oleksandr Tymoshenko <gonzo at freebsd.org>
+ * Copyright (c) 2013 Luiz Otavio O Souza <loos at freebsd.org>
+ * 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: stable/10/sys/arm/broadcom/bcm2835/bcm2835_spi.c 322724 2017-08-20 16:52:27Z marius $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/rman.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/sysctl.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+#include <machine/resource.h>
+#include <machine/fdt.h>
+#include <machine/intr.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <dev/spibus/spi.h>
+#include <dev/spibus/spibusvar.h>
+
+#include <arm/broadcom/bcm2835/bcm2835_gpio.h>
+#include <arm/broadcom/bcm2835/bcm2835_spireg.h>
+#include <arm/broadcom/bcm2835/bcm2835_spivar.h>
+
+#include "spibus_if.h"
+
+static struct ofw_compat_data compat_data[] = {
+	{"broadcom,bcm2835-spi",	1},
+	{"brcm,bcm2835-spi",		1},
+	{NULL,				0}
+};
+
+static void bcm_spi_intr(void *);
+
+#ifdef	BCM_SPI_DEBUG
+static void
+bcm_spi_printr(device_t dev)
+{
+	struct bcm_spi_softc *sc;
+	uint32_t reg;
+
+	sc = device_get_softc(dev);
+	reg = BCM_SPI_READ(sc, SPI_CS);
+	device_printf(dev, "CS=%b\n", reg,
+	    "\20\1CS0\2CS1\3CPHA\4CPOL\7CSPOL"
+	    "\10TA\11DMAEN\12INTD\13INTR\14ADCS\15REN\16LEN"
+	    "\21DONE\22RXD\23TXD\24RXR\25RXF\26CSPOL0\27CSPOL1"
+	    "\30CSPOL2\31DMA_LEN\32LEN_LONG");
+	reg = BCM_SPI_READ(sc, SPI_CLK) & SPI_CLK_MASK;
+	if (reg % 2)
+		reg--;
+	if (reg == 0)
+		reg = 65536;
+	device_printf(dev, "CLK=%uMhz/%d=%luhz\n",
+	    SPI_CORE_CLK / 1000000, reg, SPI_CORE_CLK / reg);
+	reg = BCM_SPI_READ(sc, SPI_DLEN) & SPI_DLEN_MASK;
+	device_printf(dev, "DLEN=%d\n", reg);
+	reg = BCM_SPI_READ(sc, SPI_LTOH) & SPI_LTOH_MASK;
+	device_printf(dev, "LTOH=%d\n", reg);
+	reg = BCM_SPI_READ(sc, SPI_DC);
+	device_printf(dev, "DC=RPANIC=%#x RDREQ=%#x TPANIC=%#x TDREQ=%#x\n",
+	    (reg & SPI_DC_RPANIC_MASK) >> SPI_DC_RPANIC_SHIFT,
+	    (reg & SPI_DC_RDREQ_MASK) >> SPI_DC_RDREQ_SHIFT,
+	    (reg & SPI_DC_TPANIC_MASK) >> SPI_DC_TPANIC_SHIFT,
+	    (reg & SPI_DC_TDREQ_MASK) >> SPI_DC_TDREQ_SHIFT);
+}
+#endif
+
+static void
+bcm_spi_modifyreg(struct bcm_spi_softc *sc, uint32_t off, uint32_t mask,
+	uint32_t value)
+{
+	uint32_t reg;
+
+	mtx_assert(&sc->sc_mtx, MA_OWNED);
+	reg = BCM_SPI_READ(sc, off);
+	reg &= ~mask;
+	reg |= value;
+	BCM_SPI_WRITE(sc, off, reg);
+}
+
+static int
+bcm_spi_clock_proc(SYSCTL_HANDLER_ARGS)
+{
+	struct bcm_spi_softc *sc;
+	uint32_t clk;
+	int error;
+
+	sc = (struct bcm_spi_softc *)arg1;
+
+	BCM_SPI_LOCK(sc);
+	clk = BCM_SPI_READ(sc, SPI_CLK);
+	BCM_SPI_UNLOCK(sc);
+	clk &= 0xffff;
+	if (clk == 0)
+		clk = 65536;
+	clk = SPI_CORE_CLK / clk;
+
+	error = sysctl_handle_int(oidp, &clk, sizeof(clk), req);
+	if (error != 0 || req->newptr == NULL)
+		return (error);
+
+	clk = SPI_CORE_CLK / clk;
+	if (clk <= 1)
+		clk = 2;
+	else if (clk % 2)
+		clk--;
+	if (clk > 0xffff)
+		clk = 0;
+	BCM_SPI_LOCK(sc);
+	BCM_SPI_WRITE(sc, SPI_CLK, clk);
+	BCM_SPI_UNLOCK(sc);
+
+	return (0);
+}
+
+static int
+bcm_spi_cs_bit_proc(SYSCTL_HANDLER_ARGS, uint32_t bit)
+{
+	struct bcm_spi_softc *sc;
+	uint32_t reg;
+	int error;
+
+	sc = (struct bcm_spi_softc *)arg1;
+	BCM_SPI_LOCK(sc);
+	reg = BCM_SPI_READ(sc, SPI_CS);
+	BCM_SPI_UNLOCK(sc);
+	reg = (reg & bit) ? 1 : 0;
+
+	error = sysctl_handle_int(oidp, &reg, sizeof(reg), req);
+	if (error != 0 || req->newptr == NULL)
+		return (error);
+
+	if (reg)
+		reg = bit;
+	BCM_SPI_LOCK(sc);
+	bcm_spi_modifyreg(sc, SPI_CS, bit, reg);
+	BCM_SPI_UNLOCK(sc);
+
+	return (0);
+}
+
+static int
+bcm_spi_cpol_proc(SYSCTL_HANDLER_ARGS)
+{
+
+	return (bcm_spi_cs_bit_proc(oidp, arg1, arg2, req, SPI_CS_CPOL));
+}
+
+static int
+bcm_spi_cpha_proc(SYSCTL_HANDLER_ARGS)
+{
+
+	return (bcm_spi_cs_bit_proc(oidp, arg1, arg2, req, SPI_CS_CPHA));
+}
+
+static int
+bcm_spi_cspol0_proc(SYSCTL_HANDLER_ARGS)
+{
+
+	return (bcm_spi_cs_bit_proc(oidp, arg1, arg2, req, SPI_CS_CSPOL0));
+}
+
+static int
+bcm_spi_cspol1_proc(SYSCTL_HANDLER_ARGS)
+{
+
+	return (bcm_spi_cs_bit_proc(oidp, arg1, arg2, req, SPI_CS_CSPOL1));
+}
+
+static void
+bcm_spi_sysctl_init(struct bcm_spi_softc *sc)
+{
+	struct sysctl_ctx_list *ctx;
+	struct sysctl_oid *tree_node;
+	struct sysctl_oid_list *tree;
+
+	/*
+	 * Add system sysctl tree/handlers.
+	 */
+	ctx = device_get_sysctl_ctx(sc->sc_dev);
+	tree_node = device_get_sysctl_tree(sc->sc_dev);
+	tree = SYSCTL_CHILDREN(tree_node);
+	SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "clock",
+	    CTLFLAG_RW | CTLTYPE_UINT, sc, sizeof(*sc),
+	    bcm_spi_clock_proc, "IU", "SPI BUS clock frequency");
+	SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "cpol",
+	    CTLFLAG_RW | CTLTYPE_UINT, sc, sizeof(*sc),
+	    bcm_spi_cpol_proc, "IU", "SPI BUS clock polarity");
+	SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "cpha",
+	    CTLFLAG_RW | CTLTYPE_UINT, sc, sizeof(*sc),
+	    bcm_spi_cpha_proc, "IU", "SPI BUS clock phase");
+	SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "cspol0",
+	    CTLFLAG_RW | CTLTYPE_UINT, sc, sizeof(*sc),
+	    bcm_spi_cspol0_proc, "IU", "SPI BUS chip select 0 polarity");
+	SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "cspol1",
+	    CTLFLAG_RW | CTLTYPE_UINT, sc, sizeof(*sc),
+	    bcm_spi_cspol1_proc, "IU", "SPI BUS chip select 1 polarity");
+}
+
+static int
+bcm_spi_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
+		return (ENXIO);
+
+	device_set_desc(dev, "BCM2708/2835 SPI controller");
+
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+bcm_spi_attach(device_t dev)
+{
+	struct bcm_spi_softc *sc;
+	device_t gpio;
+	int i, rid;
+
+	if (device_get_unit(dev) != 0) {
+		device_printf(dev, "only one SPI controller supported\n");
+		return (ENXIO);
+	}
+
+	sc = device_get_softc(dev);
+	sc->sc_dev = dev;
+
+	/* Configure the GPIO pins to ALT0 function to enable SPI the pins. */
+	gpio = devclass_get_device(devclass_find("gpio"), 0);
+	if (!gpio) {
+		device_printf(dev, "cannot find gpio0\n");
+		return (ENXIO);
+	}
+	for (i = 0; i < nitems(bcm_spi_pins); i++)
+		bcm_gpio_set_alternate(gpio, bcm_spi_pins[i], BCM_GPIO_ALT0);
+
+	rid = 0;
+	sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	    RF_ACTIVE);
+	if (!sc->sc_mem_res) {
+		device_printf(dev, "cannot allocate memory window\n");
+		return (ENXIO);
+	}
+
+	sc->sc_bst = rman_get_bustag(sc->sc_mem_res);
+	sc->sc_bsh = rman_get_bushandle(sc->sc_mem_res);
+
+	rid = 0;
+	sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+	    RF_ACTIVE);
+	if (!sc->sc_irq_res) {
+		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
+		device_printf(dev, "cannot allocate interrupt\n");
+		return (ENXIO);
+	}
+
+	/* Hook up our interrupt handler. */
+	if (bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
+	    NULL, bcm_spi_intr, sc, &sc->sc_intrhand)) {
+		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res);
+		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
+		device_printf(dev, "cannot setup the interrupt handler\n");
+		return (ENXIO);
+	}
+
+	mtx_init(&sc->sc_mtx, "bcm_spi", NULL, MTX_DEF);
+
+	/* Add sysctl nodes. */
+	bcm_spi_sysctl_init(sc);
+
+#ifdef	BCM_SPI_DEBUG
+	bcm_spi_printr(dev);
+#endif
+
+	/*
+	 * Enable the SPI controller.  Clear the rx and tx FIFO.
+	 * Defaults to SPI mode 0.
+	 */
+	BCM_SPI_WRITE(sc, SPI_CS, SPI_CS_CLEAR_RXFIFO | SPI_CS_CLEAR_TXFIFO);
+
+	/* Set the SPI clock to 500Khz. */
+	BCM_SPI_WRITE(sc, SPI_CLK, SPI_CORE_CLK / 500000);
+
+#ifdef	BCM_SPI_DEBUG
+	bcm_spi_printr(dev);
+#endif
+
+	device_add_child(dev, "spibus", -1);
+
+	return (bus_generic_attach(dev));
+}
+
+static int
+bcm_spi_detach(device_t dev)
+{
+	struct bcm_spi_softc *sc;
+
+	bus_generic_detach(dev);
+
+	sc = device_get_softc(dev);
+	mtx_destroy(&sc->sc_mtx);
+	if (sc->sc_intrhand)
+		bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_intrhand);
+	if (sc->sc_irq_res)
+		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res);
+	if (sc->sc_mem_res)
+		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
+
+	return (0);
+}
+
+static void
+bcm_spi_fill_fifo(struct bcm_spi_softc *sc)
+{
+	struct spi_command *cmd;
+	uint32_t cs, written;
+	uint8_t *data;
+
+	cmd = sc->sc_cmd;
+	cs = BCM_SPI_READ(sc, SPI_CS) & (SPI_CS_TA | SPI_CS_TXD);
+	while (sc->sc_written < sc->sc_len &&
+	    cs == (SPI_CS_TA | SPI_CS_TXD)) {
+		data = (uint8_t *)cmd->tx_cmd;
+		written = sc->sc_written++;
+		if (written >= cmd->tx_cmd_sz) {
+			data = (uint8_t *)cmd->tx_data;
+			written -= cmd->tx_cmd_sz;
+		}
+		BCM_SPI_WRITE(sc, SPI_FIFO, data[written]);
+		cs = BCM_SPI_READ(sc, SPI_CS) & (SPI_CS_TA | SPI_CS_TXD);
+	}
+}
+
+static void
+bcm_spi_drain_fifo(struct bcm_spi_softc *sc)
+{
+	struct spi_command *cmd;
+	uint32_t cs, read;
+	uint8_t *data;
+
+	cmd = sc->sc_cmd;
+	cs = BCM_SPI_READ(sc, SPI_CS) & SPI_CS_RXD;
+	while (sc->sc_read < sc->sc_len && cs == SPI_CS_RXD) {
+		data = (uint8_t *)cmd->rx_cmd;
+		read = sc->sc_read++;
+		if (read >= cmd->rx_cmd_sz) {
+			data = (uint8_t *)cmd->rx_data;
+			read -= cmd->rx_cmd_sz;
+		}
+		data[read] = BCM_SPI_READ(sc, SPI_FIFO) & 0xff;
+		cs = BCM_SPI_READ(sc, SPI_CS) & SPI_CS_RXD;
+	}
+}
+
+static void
+bcm_spi_intr(void *arg)
+{
+	struct bcm_spi_softc *sc;
+
+	sc = (struct bcm_spi_softc *)arg;
+	BCM_SPI_LOCK(sc);
+
+	/* Filter stray interrupts. */
+	if ((sc->sc_flags & BCM_SPI_BUSY) == 0) {
+		BCM_SPI_UNLOCK(sc);
+		return;
+	}
+
+	/* TX - Fill up the FIFO. */
+	bcm_spi_fill_fifo(sc);
+
+	/* RX - Drain the FIFO. */
+	bcm_spi_drain_fifo(sc);
+
+	/* Check for end of transfer. */
+	if (sc->sc_written == sc->sc_len && sc->sc_read == sc->sc_len) {
+		/* Disable interrupts and the SPI engine. */
+		bcm_spi_modifyreg(sc, SPI_CS,
+		    SPI_CS_TA | SPI_CS_INTR | SPI_CS_INTD, 0);
+		wakeup(sc->sc_dev);
+	}
+
+	BCM_SPI_UNLOCK(sc);
+}
+
+static int
+bcm_spi_transfer(device_t dev, device_t child, struct spi_command *cmd)
+{
+	struct bcm_spi_softc *sc;
+	int cs, err;
+
+	sc = device_get_softc(dev);
+
+	KASSERT(cmd->tx_cmd_sz == cmd->rx_cmd_sz, 
+	    ("TX/RX command sizes should be equal"));
+	KASSERT(cmd->tx_data_sz == cmd->rx_data_sz, 
+	    ("TX/RX data sizes should be equal"));
+
+	/* Get the proper chip select for this child. */
+	spibus_get_cs(child, &cs);
+	if (cs < 0 || cs > 2) {
+		device_printf(dev,
+		    "Invalid chip select %d requested by %s\n", cs,
+		    device_get_nameunit(child));
+		return (EINVAL);
+	}
+
+	BCM_SPI_LOCK(sc);
+
+	/* If the controller is in use wait until it is available. */
+	while (sc->sc_flags & BCM_SPI_BUSY)
+		mtx_sleep(dev, &sc->sc_mtx, 0, "bcm_spi", 0);
+
+	/* Now we have control over SPI controller. */
+	sc->sc_flags = BCM_SPI_BUSY;
+
+	/* Clear the FIFO. */
+	bcm_spi_modifyreg(sc, SPI_CS,
+	    SPI_CS_CLEAR_RXFIFO | SPI_CS_CLEAR_TXFIFO,
+	    SPI_CS_CLEAR_RXFIFO | SPI_CS_CLEAR_TXFIFO);
+
+	/* Save a pointer to the SPI command. */
+	sc->sc_cmd = cmd;
+	sc->sc_read = 0;
+	sc->sc_written = 0;
+	sc->sc_len = cmd->tx_cmd_sz + cmd->tx_data_sz;
+
+	/*
+	 * Set the CS for this transaction, enable interrupts and announce
+	 * we're ready to tx.  This will kick off the first interrupt.
+	 */
+	bcm_spi_modifyreg(sc, SPI_CS,
+	    SPI_CS_MASK | SPI_CS_TA | SPI_CS_INTR | SPI_CS_INTD,
+	    cs | SPI_CS_TA | SPI_CS_INTR | SPI_CS_INTD);
+
+	/* Wait for the transaction to complete. */
+	err = mtx_sleep(dev, &sc->sc_mtx, 0, "bcm_spi", hz * 2);
+
+	/* Make sure the SPI engine and interrupts are disabled. */
+	bcm_spi_modifyreg(sc, SPI_CS, SPI_CS_TA | SPI_CS_INTR | SPI_CS_INTD, 0);
+
+	/* Release the controller and wakeup the next thread waiting for it. */
+	sc->sc_flags = 0;
+	wakeup_one(dev);
+	BCM_SPI_UNLOCK(sc);
+
+	/*
+	 * Check for transfer timeout.  The SPI controller doesn't
+	 * return errors.
+	 */
+	if (err == EWOULDBLOCK) {
+		device_printf(sc->sc_dev, "SPI error\n");
+		err = EIO;
+	}
+
+	return (err);
+}
+
+static phandle_t
+bcm_spi_get_node(device_t bus, device_t dev)
+{
+
+	/* We only have one child, the SPI bus, which needs our own node. */
+	return (ofw_bus_get_node(bus));
+}
+
+static device_method_t bcm_spi_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		bcm_spi_probe),
+	DEVMETHOD(device_attach,	bcm_spi_attach),
+	DEVMETHOD(device_detach,	bcm_spi_detach),
+
+	/* SPI interface */
+	DEVMETHOD(spibus_transfer,	bcm_spi_transfer),
+
+	/* ofw_bus interface */
+	DEVMETHOD(ofw_bus_get_node,	bcm_spi_get_node),
+
+	DEVMETHOD_END
+};
+
+static devclass_t bcm_spi_devclass;
+
+static driver_t bcm_spi_driver = {
+	"spi",
+	bcm_spi_methods,
+	sizeof(struct bcm_spi_softc),
+};
+
+DRIVER_MODULE(bcm2835_spi, simplebus, bcm_spi_driver, bcm_spi_devclass, 0, 0);


Property changes on: trunk/sys/arm/broadcom/bcm2835/bcm2835_spi.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/broadcom/bcm2835/bcm2835_spireg.h
===================================================================
--- trunk/sys/arm/broadcom/bcm2835/bcm2835_spireg.h	                        (rev 0)
+++ trunk/sys/arm/broadcom/bcm2835/bcm2835_spireg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,76 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Oleksandr Tymoshenko <gonzo at freebsd.org>
+ * Copyright (c) 2013 Luiz Otavio O Souza <loos at freebsd.org>
+ * 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: stable/10/sys/arm/broadcom/bcm2835/bcm2835_spireg.h 259325 2013-12-13 19:27:23Z ian $
+ */
+
+#ifndef	_BCM2835_SPIREG_H_
+#define	_BCM2835_SPIREG_H_
+
+#define	SPI_CORE_CLK	250000000U
+#define	SPI_CS		0x00
+#define	SPI_CS_LEN_LONG		(1 << 25)
+#define	SPI_CS_DMA_LEN		(1 << 24)
+#define	SPI_CS_CSPOL2		(1 << 23)
+#define	SPI_CS_CSPOL1		(1 << 22)
+#define	SPI_CS_CSPOL0		(1 << 21)
+#define	SPI_CS_RXF		(1 << 20)
+#define	SPI_CS_RXR		(1 << 19)
+#define	SPI_CS_TXD		(1 << 18)
+#define	SPI_CS_RXD		(1 << 17)
+#define	SPI_CS_DONE		(1 << 16)
+#define	SPI_CS_LEN		(1 << 13)
+#define	SPI_CS_REN		(1 << 12)
+#define	SPI_CS_ADCS		(1 << 11)
+#define	SPI_CS_INTR		(1 << 10)
+#define	SPI_CS_INTD		(1 << 9)
+#define	SPI_CS_DMAEN		(1 << 8)
+#define	SPI_CS_TA		(1 << 7)
+#define	SPI_CS_CSPOL		(1 << 6)
+#define	SPI_CS_CLEAR_RXFIFO	(1 << 5)
+#define	SPI_CS_CLEAR_TXFIFO	(1 << 4)
+#define	SPI_CS_CPOL		(1 << 3)
+#define	SPI_CS_CPHA		(1 << 2)
+#define	SPI_CS_MASK		0x3
+#define	SPI_FIFO	0x04
+#define	SPI_CLK		0x08
+#define	SPI_CLK_MASK		0xffff
+#define	SPI_DLEN	0x0c
+#define	SPI_DLEN_MASK		0xffff
+#define	SPI_LTOH	0x10
+#define	SPI_LTOH_MASK		0xf
+#define	SPI_DC		0x14
+#define	SPI_DC_RPANIC_SHIFT	24
+#define	SPI_DC_RPANIC_MASK	(0xff << SPI_DC_RPANIC_SHIFT)
+#define	SPI_DC_RDREQ_SHIFT	16
+#define	SPI_DC_RDREQ_MASK	(0xff << SPI_DC_RDREQ_SHIFT)
+#define	SPI_DC_TPANIC_SHIFT	8
+#define	SPI_DC_TPANIC_MASK	(0xff << SPI_DC_TPANIC_SHIFT)
+#define	SPI_DC_TDREQ_SHIFT	0
+#define	SPI_DC_TDREQ_MASK	0xff
+
+#endif	/* _BCM2835_SPIREG_H_ */


Property changes on: trunk/sys/arm/broadcom/bcm2835/bcm2835_spireg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/broadcom/bcm2835/bcm2835_spivar.h
===================================================================
--- trunk/sys/arm/broadcom/bcm2835/bcm2835_spivar.h	                        (rev 0)
+++ trunk/sys/arm/broadcom/bcm2835/bcm2835_spivar.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,73 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Oleksandr Tymoshenko <gonzo at freebsd.org>
+ * Copyright (c) 2013 Luiz Otavio O Souza <loos at freebsd.org>
+ * 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: stable/10/sys/arm/broadcom/bcm2835/bcm2835_spivar.h 259325 2013-12-13 19:27:23Z ian $
+ */
+
+#ifndef	_BCM2835_SPIVAR_H_
+#define	_BCM2835_SPIVAR_H_
+
+/*
+ * Only the available pins are listed here.
+ * i.e. CS2 isn't available.
+ */
+uint32_t bcm_spi_pins[] = {
+	7,	/* CS1 */
+	8,	/* CS0 */
+	9,	/* MISO */
+	10,	/* MOSI */
+	11	/* SCLK */
+};
+
+struct bcm_spi_softc {
+	device_t		sc_dev;
+	struct mtx		sc_mtx;
+	struct resource *	sc_mem_res;
+	struct resource *	sc_irq_res;
+	struct spi_command	*sc_cmd;
+	bus_space_tag_t		sc_bst;
+	bus_space_handle_t	sc_bsh;
+	uint32_t		sc_len;
+	uint32_t		sc_read;
+	uint32_t		sc_flags;
+	uint32_t		sc_written;
+	void *			sc_intrhand;
+};
+
+#define	BCM_SPI_BUSY		0x1
+
+#define BCM_SPI_WRITE(_sc, _off, _val)		\
+    bus_space_write_4(_sc->sc_bst, _sc->sc_bsh, _off, _val)
+#define BCM_SPI_READ(_sc, _off)			\
+    bus_space_read_4(_sc->sc_bst, _sc->sc_bsh, _off)
+
+#define BCM_SPI_LOCK(_sc)			\
+    mtx_lock(&(_sc)->sc_mtx)
+#define BCM_SPI_UNLOCK(_sc)			\
+    mtx_unlock(&(_sc)->sc_mtx)
+
+#endif	/* _BCM2835_SPIVAR_H_ */


Property changes on: trunk/sys/arm/broadcom/bcm2835/bcm2835_spivar.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/broadcom/bcm2835/bcm2835_systimer.c
===================================================================
--- trunk/sys/arm/broadcom/bcm2835/bcm2835_systimer.c	                        (rev 0)
+++ trunk/sys/arm/broadcom/bcm2835/bcm2835_systimer.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,311 @@
+/* $MidnightBSD$ */
+/*
+ * Copyright (c) 2012 Oleksandr Tymoshenko <gonzo at freebsd.org>
+ * Copyright (c) 2012 Damjan Marion <dmarion at freebsd.org>
+ * 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: stable/10/sys/arm/broadcom/bcm2835/bcm2835_systimer.c 266207 2014-05-16 02:21:51Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/timeet.h>
+#include <sys/timetc.h>
+#include <sys/watchdog.h>
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+
+#define	BCM2835_NUM_TIMERS	4
+
+#define	DEFAULT_TIMER		3
+#define	DEFAULT_FREQUENCY	1000000
+#define	MIN_PERIOD		5LLU
+
+#define	SYSTIMER_CS	0x00
+#define	SYSTIMER_CLO	0x04
+#define	SYSTIMER_CHI	0x08
+#define	SYSTIMER_C0	0x0C
+#define	SYSTIMER_C1	0x10
+#define	SYSTIMER_C2	0x14
+#define	SYSTIMER_C3	0x18
+
+struct systimer {
+	int			index;
+	bool			enabled;
+	struct eventtimer	et;
+};
+
+struct bcm_systimer_softc {
+	struct resource*	mem_res;
+	struct resource*	irq_res[BCM2835_NUM_TIMERS];
+	void*			intr_hl[BCM2835_NUM_TIMERS];
+	uint32_t		sysclk_freq;
+	bus_space_tag_t		bst;
+	bus_space_handle_t	bsh;
+	struct systimer		st[BCM2835_NUM_TIMERS];
+};
+
+static struct resource_spec bcm_systimer_irq_spec[] = {
+	{ SYS_RES_IRQ,      0,  RF_ACTIVE },
+	{ SYS_RES_IRQ,      1,  RF_ACTIVE },
+	{ SYS_RES_IRQ,      2,  RF_ACTIVE },
+	{ SYS_RES_IRQ,      3,  RF_ACTIVE },
+	{ -1,               0,  0 }
+};
+
+static struct bcm_systimer_softc *bcm_systimer_sc = NULL;
+
+/* Read/Write macros for Timer used as timecounter */
+#define bcm_systimer_tc_read_4(reg)		\
+	bus_space_read_4(bcm_systimer_sc->bst, \
+		bcm_systimer_sc->bsh, reg)
+
+#define bcm_systimer_tc_write_4(reg, val)	\
+	bus_space_write_4(bcm_systimer_sc->bst, \
+		bcm_systimer_sc->bsh, reg, val)
+
+static unsigned bcm_systimer_tc_get_timecount(struct timecounter *);
+
+static struct timecounter bcm_systimer_tc = {
+	.tc_name           = "BCM2835 Timecounter",
+	.tc_get_timecount  = bcm_systimer_tc_get_timecount,
+	.tc_poll_pps       = NULL,
+	.tc_counter_mask   = ~0u,
+	.tc_frequency      = 0,
+	.tc_quality        = 1000,
+};
+
+static unsigned
+bcm_systimer_tc_get_timecount(struct timecounter *tc)
+{
+	return bcm_systimer_tc_read_4(SYSTIMER_CLO);
+}
+
+static int
+bcm_systimer_start(struct eventtimer *et, sbintime_t first, sbintime_t period)
+{
+	struct systimer *st = et->et_priv;
+	uint32_t clo, clo1;
+	uint32_t count;
+	register_t s;
+
+	if (first != 0) {
+
+		count = ((uint32_t)et->et_frequency * first) >> 32;
+
+		s = intr_disable();
+		clo = bcm_systimer_tc_read_4(SYSTIMER_CLO);
+restart:
+		clo += count;
+		/*
+		 * Clear pending interrupts
+		 */
+		bcm_systimer_tc_write_4(SYSTIMER_CS, (1 << st->index));
+		bcm_systimer_tc_write_4(SYSTIMER_C0 + st->index*4, clo);
+		clo1 = bcm_systimer_tc_read_4(SYSTIMER_CLO);
+		if ((int32_t)(clo1 - clo) >= 0) {
+			count *= 2;
+			clo = clo1;
+			goto restart;
+		}
+		st->enabled = 1;
+		intr_restore(s);
+
+		return (0);
+	} 
+
+	return (EINVAL);
+}
+
+static int
+bcm_systimer_stop(struct eventtimer *et)
+{
+	struct systimer *st = et->et_priv;
+	st->enabled = 0;
+
+	return (0);
+}
+
+static int
+bcm_systimer_intr(void *arg)
+{
+	struct systimer *st = (struct systimer *)arg;
+	uint32_t cs;
+
+ 	cs = bcm_systimer_tc_read_4(SYSTIMER_CS);
+	if ((cs & (1 << st->index)) == 0)
+		return (FILTER_STRAY);
+
+	/* ACK interrupt */
+	bcm_systimer_tc_write_4(SYSTIMER_CS, (1 << st->index));
+	if (st->enabled) {
+		if (st->et.et_active) {
+			st->et.et_event_cb(&st->et, st->et.et_arg);
+		}
+	}
+
+	return (FILTER_HANDLED);
+}
+
+static int
+bcm_systimer_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (ofw_bus_is_compatible(dev, "broadcom,bcm2835-system-timer")) {
+		device_set_desc(dev, "BCM2835 System Timer");
+		return (BUS_PROBE_DEFAULT);
+	}
+
+	return (ENXIO);
+}
+
+static int
+bcm_systimer_attach(device_t dev)
+{
+	struct bcm_systimer_softc *sc = device_get_softc(dev);
+	int err;
+	int rid = 0;
+
+	if (bcm_systimer_sc != NULL)
+		return (EINVAL);
+
+	sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
+	if (sc->mem_res == NULL) {
+		device_printf(dev, "could not allocate memory resource\n");
+		return (ENXIO);
+	}
+
+	sc->bst = rman_get_bustag(sc->mem_res);
+	sc->bsh = rman_get_bushandle(sc->mem_res);
+
+	/* Request the IRQ resources */
+	err = bus_alloc_resources(dev, bcm_systimer_irq_spec,
+		sc->irq_res);
+	if (err) {
+		device_printf(dev, "Error: could not allocate irq resources\n");
+		return (ENXIO);
+	}
+
+	/* TODO: get frequency from FDT */
+	sc->sysclk_freq = DEFAULT_FREQUENCY;
+
+	/* Setup and enable the timer */
+	if (bus_setup_intr(dev, sc->irq_res[DEFAULT_TIMER], INTR_TYPE_CLK,
+			bcm_systimer_intr, NULL, &sc->st[DEFAULT_TIMER],
+			&sc->intr_hl[DEFAULT_TIMER]) != 0) {
+		bus_release_resources(dev, bcm_systimer_irq_spec,
+			sc->irq_res);
+		device_printf(dev, "Unable to setup the clock irq handler.\n");
+		return (ENXIO);
+	}
+
+	sc->st[DEFAULT_TIMER].index = DEFAULT_TIMER;
+	sc->st[DEFAULT_TIMER].enabled = 0;
+	sc->st[DEFAULT_TIMER].et.et_name = malloc(64, M_DEVBUF, M_NOWAIT | M_ZERO);
+	sprintf(sc->st[DEFAULT_TIMER].et.et_name, "BCM2835 Event Timer %d", DEFAULT_TIMER);
+	sc->st[DEFAULT_TIMER].et.et_flags = ET_FLAGS_ONESHOT;
+	sc->st[DEFAULT_TIMER].et.et_quality = 1000;
+	sc->st[DEFAULT_TIMER].et.et_frequency = sc->sysclk_freq;
+	sc->st[DEFAULT_TIMER].et.et_min_period =
+	    (MIN_PERIOD << 32) / sc->st[DEFAULT_TIMER].et.et_frequency + 1;
+	sc->st[DEFAULT_TIMER].et.et_max_period =
+	    (0x7ffffffeLLU << 32) / sc->st[DEFAULT_TIMER].et.et_frequency;
+	sc->st[DEFAULT_TIMER].et.et_start = bcm_systimer_start;
+	sc->st[DEFAULT_TIMER].et.et_stop = bcm_systimer_stop;
+	sc->st[DEFAULT_TIMER].et.et_priv = &sc->st[DEFAULT_TIMER];
+	et_register(&sc->st[DEFAULT_TIMER].et);
+
+	bcm_systimer_sc = sc;
+
+	bcm_systimer_tc.tc_frequency = DEFAULT_FREQUENCY;
+	tc_init(&bcm_systimer_tc);
+
+	return (0);
+}
+
+static device_method_t bcm_systimer_methods[] = {
+	DEVMETHOD(device_probe,		bcm_systimer_probe),
+	DEVMETHOD(device_attach,	bcm_systimer_attach),
+	{ 0, 0 }
+};
+
+static driver_t bcm_systimer_driver = {
+	"systimer",
+	bcm_systimer_methods,
+	sizeof(struct bcm_systimer_softc),
+};
+
+static devclass_t bcm_systimer_devclass;
+
+DRIVER_MODULE(bcm_systimer, simplebus, bcm_systimer_driver, bcm_systimer_devclass, 0, 0);
+
+void
+DELAY(int usec)
+{
+	int32_t counts;
+	uint32_t first, last;
+
+	if (bcm_systimer_sc == NULL) {
+		for (; usec > 0; usec--)
+			for (counts = 200; counts > 0; counts--)
+				/* Prevent gcc from optimizing  out the loop */
+				cpufunc_nullop();
+		return;
+	}
+
+	/* Get the number of times to count */
+	counts = usec * (bcm_systimer_tc.tc_frequency / 1000000) + 1;
+
+	first = bcm_systimer_tc_read_4(SYSTIMER_CLO);
+
+	while (counts > 0) {
+		last = bcm_systimer_tc_read_4(SYSTIMER_CLO);
+		if (last == first)
+			continue;
+		if (last>first) {
+			counts -= (int32_t)(last - first);
+		} else {
+			counts -= (int32_t)((0xFFFFFFFF - first) + last);
+		}
+		first = last;
+	}
+}


Property changes on: trunk/sys/arm/broadcom/bcm2835/bcm2835_systimer.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/broadcom/bcm2835/bcm2835_vcbus.h
===================================================================
--- trunk/sys/arm/broadcom/bcm2835/bcm2835_vcbus.h	                        (rev 0)
+++ trunk/sys/arm/broadcom/bcm2835/bcm2835_vcbus.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,73 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Oleksandr Tymoshenko <gonzo at freebsd.org>
+ * 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: stable/10/sys/arm/broadcom/bcm2835/bcm2835_vcbus.h 322724 2017-08-20 16:52:27Z marius $
+ */
+
+/*
+ * Defines for converting physical address to VideoCore bus address and back
+ */
+
+#ifndef _BCM2835_VCBUS_H_
+#define _BCM2835_VCBUS_H_
+
+#define	BCM2835_VCBUS_SDRAM_CACHED	0x40000000
+#define	BCM2835_VCBUS_IO_BASE		0x7E000000
+#define	BCM2835_VCBUS_SDRAM_UNCACHED	0xC0000000
+
+#ifdef SOC_BCM2836
+#define	BCM2835_ARM_IO_BASE		0x3f000000
+#define	BCM2835_VCBUS_SDRAM_BASE	BCM2835_VCBUS_SDRAM_UNCACHED
+#else
+#define	BCM2835_ARM_IO_BASE		0x20000000
+#define	BCM2835_VCBUS_SDRAM_BASE	BCM2835_VCBUS_SDRAM_CACHED
+#endif
+#define	BCM2835_ARM_IO_SIZE		0x01000000
+
+/*
+ * Convert physical address to VC bus address. Should be used 
+ * when submitting address over mailbox interface 
+ */
+#define	PHYS_TO_VCBUS(pa)	((pa) + BCM2835_VCBUS_SDRAM_BASE)
+
+/* Check whether pa bellong top IO window */
+#define BCM2835_ARM_IS_IO(pa)	(((pa) >= BCM2835_ARM_IO_BASE) && \
+    ((pa) < BCM2835_ARM_IO_BASE + BCM2835_ARM_IO_SIZE))
+
+/*
+ * Convert physical address in IO space to VC bus address. 
+ */
+#define	IO_TO_VCBUS(pa)		((pa - BCM2835_ARM_IO_BASE) + \
+    BCM2835_VCBUS_IO_BASE)
+
+/*
+ * Convert address from VC bus space to physical. Should be used
+ * when address is returned by VC over mailbox interface. e.g.
+ * framebuffer base
+ */
+#define	VCBUS_TO_PHYS(vca)	((vca) & ~(BCM2835_VCBUS_SDRAM_BASE))
+
+#endif /* _BCM2835_VCBUS_H_ */


Property changes on: trunk/sys/arm/broadcom/bcm2835/bcm2835_vcbus.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/broadcom/bcm2835/bcm2835_wdog.c
===================================================================
--- trunk/sys/arm/broadcom/bcm2835/bcm2835_wdog.c	                        (rev 0)
+++ trunk/sys/arm/broadcom/bcm2835/bcm2835_wdog.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,226 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Alexander Rybalko <ray at freebsd.org>
+ * 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: stable/10/sys/arm/broadcom/bcm2835/bcm2835_wdog.c 322724 2017-08-20 16:52:27Z marius $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/watchdog.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/rman.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+#include <machine/cpufunc.h>
+#include <machine/machdep.h>
+#include <machine/fdt.h>
+
+#include <arm/broadcom/bcm2835/bcm2835_wdog.h>
+
+#define	BCM2835_PASSWORD	0x5a
+
+#define BCM2835_WDOG_RESET	0
+#define BCM2835_PASSWORD_MASK	0xff000000
+#define BCM2835_PASSWORD_SHIFT	24
+#define BCM2835_WDOG_TIME_MASK	0x000fffff
+#define BCM2835_WDOG_TIME_SHIFT	0
+
+#define	READ(_sc, _r) bus_space_read_4((_sc)->bst, (_sc)->bsh, (_r) + (_sc)->regs_offset)
+#define	WRITE(_sc, _r, _v) bus_space_write_4((_sc)->bst, (_sc)->bsh, (_r) + (_sc)->regs_offset, (_v))
+
+#define BCM2835_RSTC_WRCFG_CLR		0xffffffcf
+#define BCM2835_RSTC_WRCFG_SET		0x00000030
+#define BCM2835_RSTC_WRCFG_FULL_RESET	0x00000020
+#define BCM2835_RSTC_RESET		0x00000102
+
+#define	BCM2835_RSTC_REG	0x00
+#define	BCM2835_RSTS_REG	0x04
+#define	BCM2835_WDOG_REG	0x08
+
+static struct bcmwd_softc *bcmwd_lsc = NULL;
+
+struct bcmwd_softc {
+	device_t		dev;
+	struct resource *	res;
+	bus_space_tag_t		bst;
+	bus_space_handle_t	bsh;
+	int			wdog_armed;
+	int			wdog_period;
+	char			wdog_passwd;
+	struct mtx		mtx;
+	int			regs_offset;
+};
+
+#define	BSD_DTB		1
+#define	UPSTREAM_DTB	2
+#define	UPSTREAM_DTB_REGS_OFFSET	0x1c
+
+static struct ofw_compat_data compat_data[] = {
+	{"broadcom,bcm2835-wdt",	BSD_DTB},
+	{"brcm,bcm2835-pm-wdt",		UPSTREAM_DTB},
+	{NULL,				0}
+};
+
+static void bcmwd_watchdog_fn(void *private, u_int cmd, int *error);
+
+static int
+bcmwd_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
+		return (ENXIO);
+
+	device_set_desc(dev, "BCM2708/2835 Watchdog");
+
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+bcmwd_attach(device_t dev)
+{
+	struct bcmwd_softc *sc;
+	int rid;
+
+	if (bcmwd_lsc != NULL)
+		return (ENXIO);
+
+	sc = device_get_softc(dev);
+	sc->wdog_period = 7;
+	sc->wdog_passwd = BCM2835_PASSWORD;
+	sc->wdog_armed = 0;
+	sc->dev = dev;
+
+	rid = 0;
+	sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
+	if (sc->res == NULL) {
+		device_printf(dev, "could not allocate memory resource\n");
+		return (ENXIO);
+	}
+
+	sc->bst = rman_get_bustag(sc->res);
+	sc->bsh = rman_get_bushandle(sc->res);
+
+	/* compensate base address difference */
+	if (ofw_bus_search_compatible(dev, compat_data)->ocd_data
+	   == UPSTREAM_DTB)
+		sc->regs_offset = UPSTREAM_DTB_REGS_OFFSET;
+
+	bcmwd_lsc = sc;
+	mtx_init(&sc->mtx, "BCM2835 Watchdog", "bcmwd", MTX_DEF);
+	EVENTHANDLER_REGISTER(watchdog_list, bcmwd_watchdog_fn, sc, 0);
+
+	return (0);
+}
+
+static void
+bcmwd_watchdog_fn(void *private, u_int cmd, int *error)
+{
+	struct bcmwd_softc *sc;
+	uint64_t sec;
+	uint32_t ticks, reg;
+
+	sc = private;
+	mtx_lock(&sc->mtx);
+
+	cmd &= WD_INTERVAL;
+
+	if (cmd > 0) {
+		sec = ((uint64_t)1 << (cmd & WD_INTERVAL)) / 1000000000;
+		if (sec == 0 || sec > 15) {
+			/* 
+			 * Can't arm
+			 * disable watchdog as watchdog(9) requires
+			 */
+			device_printf(sc->dev,
+			    "Can't arm, timeout must be between 1-15 seconds\n");
+			WRITE(sc, BCM2835_RSTC_REG, 
+			    (BCM2835_PASSWORD << BCM2835_PASSWORD_SHIFT) |
+			    BCM2835_RSTC_RESET);
+			mtx_unlock(&sc->mtx);
+			return;
+		}
+
+		ticks = (sec << 16) & BCM2835_WDOG_TIME_MASK;
+		reg = (BCM2835_PASSWORD << BCM2835_PASSWORD_SHIFT) | ticks;
+		WRITE(sc, BCM2835_WDOG_REG, reg);
+
+		reg = READ(sc, BCM2835_RSTC_REG);
+		reg &= BCM2835_RSTC_WRCFG_CLR;
+		reg |= BCM2835_RSTC_WRCFG_FULL_RESET;
+		reg |= (BCM2835_PASSWORD << BCM2835_PASSWORD_SHIFT);
+		WRITE(sc, BCM2835_RSTC_REG, reg);
+
+		*error = 0;
+	}
+	else
+		WRITE(sc, BCM2835_RSTC_REG, 
+		    (BCM2835_PASSWORD << BCM2835_PASSWORD_SHIFT) |
+		    BCM2835_RSTC_RESET);
+
+	mtx_unlock(&sc->mtx);
+}
+
+void
+bcmwd_watchdog_reset()
+{
+
+	if (bcmwd_lsc == NULL)
+		return;
+
+	WRITE(bcmwd_lsc, BCM2835_WDOG_REG,
+	    (BCM2835_PASSWORD << BCM2835_PASSWORD_SHIFT) | 10);
+
+	WRITE(bcmwd_lsc, BCM2835_RSTC_REG,
+	    (READ(bcmwd_lsc, BCM2835_RSTC_REG) & BCM2835_RSTC_WRCFG_CLR) |
+		(BCM2835_PASSWORD << BCM2835_PASSWORD_SHIFT) |
+		BCM2835_RSTC_WRCFG_FULL_RESET);
+}
+
+static device_method_t bcmwd_methods[] = {
+	DEVMETHOD(device_probe, bcmwd_probe),
+	DEVMETHOD(device_attach, bcmwd_attach),
+
+	DEVMETHOD_END
+};
+
+static driver_t bcmwd_driver = {
+	"bcmwd",
+	bcmwd_methods,
+	sizeof(struct bcmwd_softc),
+};
+static devclass_t bcmwd_devclass;
+
+DRIVER_MODULE(bcmwd, simplebus, bcmwd_driver, bcmwd_devclass, 0, 0);


Property changes on: trunk/sys/arm/broadcom/bcm2835/bcm2835_wdog.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/broadcom/bcm2835/bcm2835_wdog.h
===================================================================
--- trunk/sys/arm/broadcom/bcm2835/bcm2835_wdog.h	                        (rev 0)
+++ trunk/sys/arm/broadcom/bcm2835/bcm2835_wdog.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,33 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Alexander Rybalko <ray at freebsd.org>
+ * 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: stable/10/sys/arm/broadcom/bcm2835/bcm2835_wdog.h 239922 2012-08-30 20:59:37Z gonzo $
+ */
+#ifndef _BCM2835_WDOG_H_
+#define _BCM2835_WDOG_H_
+
+void bcmwd_watchdog_reset(void);
+#endif


Property changes on: trunk/sys/arm/broadcom/bcm2835/bcm2835_wdog.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/broadcom/bcm2835/bcm2836.c
===================================================================
--- trunk/sys/arm/broadcom/bcm2835/bcm2836.c	                        (rev 0)
+++ trunk/sys/arm/broadcom/bcm2835/bcm2836.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,185 @@
+/* $MidnightBSD$ */
+/*
+ * Copyright 2015 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/broadcom/bcm2835/bcm2836.c 322724 2017-08-20 16:52:27Z marius $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/rman.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+
+#include <dev/ofw/ofw_bus_subr.h>
+#include <dev/ofw/ofw_bus.h>
+
+#include <arm/broadcom/bcm2835/bcm2836.h>
+
+#define	ARM_LOCAL_BASE	0x40000000
+#define	ARM_LOCAL_SIZE	0x00001000
+
+#define	ARM_LOCAL_CONTROL		0x00
+#define	ARM_LOCAL_PRESCALER		0x08
+#define	 PRESCALER_19_2			0x80000000 /* 19.2 MHz */
+#define	ARM_LOCAL_INT_TIMER(n)		(0x40 + (n) * 4)
+#define	ARM_LOCAL_INT_MAILBOX(n)	(0x50 + (n) * 4)
+#define	ARM_LOCAL_INT_PENDING(n)	(0x60 + (n) * 4)
+#define	 INT_PENDING_MASK		0x0f
+
+/*
+ * A driver for features of the bcm2836.
+ */
+
+struct bcm2836_softc {
+	device_t	 sc_dev;
+	struct resource *sc_mem;
+};
+
+static device_identify_t bcm2836_identify;
+static device_probe_t bcm2836_probe;
+static device_attach_t bcm2836_attach;
+
+struct bcm2836_softc *softc;
+
+static void
+bcm2836_identify(driver_t *driver, device_t parent)
+{
+
+	if (BUS_ADD_CHILD(parent, 0, "bcm2836", -1) == NULL)
+		device_printf(parent, "add child failed\n");
+}
+
+static int
+bcm2836_probe(device_t dev)
+{
+
+	if (softc != NULL)
+		return (ENXIO);
+
+	device_set_desc(dev, "Broadcom bcm2836");
+
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+bcm2836_attach(device_t dev)
+{
+	int i, rid;
+
+	softc = device_get_softc(dev);
+	softc->sc_dev = dev;
+
+	rid = 0;
+	softc->sc_mem = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid,
+	    ARM_LOCAL_BASE, ARM_LOCAL_BASE + ARM_LOCAL_SIZE, ARM_LOCAL_SIZE,
+	    RF_ACTIVE);
+	if (softc->sc_mem == NULL) {
+		device_printf(dev, "could not allocate memory resource\n");
+		return (ENXIO);
+	}
+
+	bus_write_4(softc->sc_mem, ARM_LOCAL_CONTROL, 0);
+	bus_write_4(softc->sc_mem, ARM_LOCAL_PRESCALER, PRESCALER_19_2);
+
+	for (i = 0; i < 4; i++)
+		bus_write_4(softc->sc_mem, ARM_LOCAL_INT_TIMER(i), 0);
+
+	for (i = 0; i < 4; i++)
+		bus_write_4(softc->sc_mem, ARM_LOCAL_INT_MAILBOX(i), 1);
+
+	return (0);
+}
+
+int
+bcm2836_get_next_irq(int last_irq)
+{
+	uint32_t reg;
+	int cpu;
+	int irq;
+
+	cpu = PCPU_GET(cpuid);
+
+	reg = bus_read_4(softc->sc_mem, ARM_LOCAL_INT_PENDING(cpu));
+	reg &= INT_PENDING_MASK;
+	if (reg == 0)
+		return (-1);
+
+	irq = ffs(reg) - 1;
+
+	return (irq);
+}
+
+void
+bcm2836_mask_irq(uintptr_t irq)
+{
+	uint32_t reg;
+	int i;
+
+	for (i = 0; i < 4; i++) {
+		reg = bus_read_4(softc->sc_mem, ARM_LOCAL_INT_TIMER(i));
+		reg &= ~(1 << irq);
+		bus_write_4(softc->sc_mem, ARM_LOCAL_INT_TIMER(i), reg);
+	}
+}
+
+void
+bcm2836_unmask_irq(uintptr_t irq)
+{
+	uint32_t reg;
+	int i;
+
+	for (i = 0; i < 4; i++) {
+		reg = bus_read_4(softc->sc_mem, ARM_LOCAL_INT_TIMER(i));
+		reg |= (1 << irq);
+		bus_write_4(softc->sc_mem, ARM_LOCAL_INT_TIMER(i), reg);
+	}
+}
+
+static device_method_t bcm2836_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_identify,	bcm2836_identify),
+	DEVMETHOD(device_probe,		bcm2836_probe),
+	DEVMETHOD(device_attach,	bcm2836_attach),
+
+	DEVMETHOD_END
+};
+
+static devclass_t bcm2836_devclass;
+
+static driver_t bcm2836_driver = {
+	"bcm2836",
+	bcm2836_methods,
+	sizeof(struct bcm2836_softc),
+};
+
+EARLY_DRIVER_MODULE(bcm2836, nexus, bcm2836_driver, bcm2836_devclass, 0, 0,
+    BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE);


Property changes on: trunk/sys/arm/broadcom/bcm2835/bcm2836.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/broadcom/bcm2835/bcm2836.h
===================================================================
--- trunk/sys/arm/broadcom/bcm2835/bcm2836.h	                        (rev 0)
+++ trunk/sys/arm/broadcom/bcm2835/bcm2836.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,38 @@
+/* $MidnightBSD$ */
+/*
+ * Copyright 2015 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: stable/10/sys/arm/broadcom/bcm2835/bcm2836.h 322724 2017-08-20 16:52:27Z marius $
+ */
+
+#ifndef _BCM2815_BCM2836_H
+#define	_BCM2815_BCM2836_H
+
+int bcm2836_get_next_irq(int);
+void bcm2836_mask_irq(uintptr_t);
+void bcm2836_unmask_irq(uintptr_t);
+
+#endif


Property changes on: trunk/sys/arm/broadcom/bcm2835/bcm2836.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/broadcom/bcm2835/bcm283x_dwc_fdt.c
===================================================================
--- trunk/sys/arm/broadcom/bcm2835/bcm283x_dwc_fdt.c	                        (rev 0)
+++ trunk/sys/arm/broadcom/bcm2835/bcm283x_dwc_fdt.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,105 @@
+/* $MidnightBSD$ */
+/*
+ * Copyright 2015 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/broadcom/bcm2835/bcm283x_dwc_fdt.c 322724 2017-08-20 16:52:27Z marius $");
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/bus.h>
+#include <sys/callout.h>
+#include <sys/condvar.h>
+#include <sys/module.h>
+
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <dev/usb/usb.h>
+#include <dev/usb/usbdi.h>
+
+#include <dev/usb/usb_busdma.h>
+#include <dev/usb/usb_process.h>
+
+#include <dev/usb/usb_controller.h>
+#include <dev/usb/usb_bus.h>
+
+#include <dev/usb/controller/dwc_otg.h>
+#include <dev/usb/controller/dwc_otg_fdt.h>
+
+#include <arm/broadcom/bcm2835/bcm2835_mbox_prop.h>
+
+static struct ofw_compat_data compat_data[] = {
+	{"broadcom,bcm2835-usb",	1},
+	{"brcm,bcm2708-usb",		1},
+	{NULL,				0}
+};
+
+static device_probe_t bcm283x_dwc_otg_probe;
+static device_attach_t bcm283x_dwc_otg_attach;
+
+static int
+bcm283x_dwc_otg_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
+		return (ENXIO);
+
+	device_set_desc(dev, "DWC OTG 2.0 integrated USB controller (bcm283x)");
+
+	return (BUS_PROBE_VENDOR);
+}
+
+static int
+bcm283x_dwc_otg_attach(device_t dev)
+{
+	int err;
+
+	err = bcm2835_mbox_set_power_state(BCM2835_MBOX_POWER_ID_USB_HCD, TRUE);
+	if (err)
+		device_printf(dev, "failed to set power state, err=%d\n", err);
+
+	return (dwc_otg_attach(dev));
+}
+
+static device_method_t bcm283x_dwc_otg_methods[] = {
+	/* bus interface */
+	DEVMETHOD(device_probe, bcm283x_dwc_otg_probe),
+	DEVMETHOD(device_attach, bcm283x_dwc_otg_attach),
+
+	DEVMETHOD_END
+};
+
+static devclass_t bcm283x_dwc_otg_devclass;
+
+DEFINE_CLASS_1(bcm283x_dwcotg, bcm283x_dwc_otg_driver, bcm283x_dwc_otg_methods,
+    sizeof(struct dwc_otg_fdt_softc), dwc_otg_driver);
+DRIVER_MODULE(bcm283x_dwcotg, simplebus, bcm283x_dwc_otg_driver,
+    bcm283x_dwc_otg_devclass, 0, 0);
+MODULE_DEPEND(bcm283x_dwcotg, usb, 1, 1, 1);


Property changes on: trunk/sys/arm/broadcom/bcm2835/bcm283x_dwc_fdt.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/broadcom/bcm2835/files.bcm2835
===================================================================
--- trunk/sys/arm/broadcom/bcm2835/files.bcm2835	                        (rev 0)
+++ trunk/sys/arm/broadcom/bcm2835/files.bcm2835	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,32 @@
+# $FreeBSD: stable/10/sys/arm/broadcom/bcm2835/files.bcm2835 322724 2017-08-20 16:52:27Z marius $
+
+arm/broadcom/bcm2835/bcm2835_bsc.c		optional bcm2835_bsc
+arm/broadcom/bcm2835/bcm2835_common.c		optional fdt
+arm/broadcom/bcm2835/bcm2835_cpufreq.c		standard
+arm/broadcom/bcm2835/bcm2835_dma.c		standard
+arm/broadcom/bcm2835/bcm2835_fb.c		optional sc
+arm/broadcom/bcm2835/bcm2835_fbd.c		optional vt
+arm/broadcom/bcm2835/bcm2835_gpio.c		optional gpio
+arm/broadcom/bcm2835/bcm2835_intr.c		standard
+arm/broadcom/bcm2835/bcm2835_machdep.c		standard
+arm/broadcom/bcm2835/bcm2835_mbox.c		standard
+arm/broadcom/bcm2835/bcm2835_sdhci.c		optional sdhci
+arm/broadcom/bcm2835/bcm2835_spi.c		optional bcm2835_spi
+arm/broadcom/bcm2835/bcm2835_systimer.c		standard
+arm/broadcom/bcm2835/bcm2835_wdog.c		standard
+dev/usb/controller/dwc_otg_fdt.c		optional dwcotg
+
+arm/broadcom/bcm2835/bcm283x_dwc_fdt.c		optional dwcotg fdt
+
+arm/arm/bus_space_base.c			standard
+arm/arm/bus_space_generic.c                     standard
+arm/arm/bus_space_asm_generic.S                 standard
+arm/arm/cpufunc_asm_arm11.S                     standard
+arm/arm/cpufunc_asm_arm11x6.S                   standard
+arm/arm/cpufunc_asm_armv5.S                     standard
+arm/arm/cpufunc_asm_armv6.S                     standard
+
+kern/kern_clocksource.c                         standard
+
+dev/mbox/mbox_if.m				standard
+dev/ofw/ofw_cpu.c				standard


Property changes on: trunk/sys/arm/broadcom/bcm2835/files.bcm2835
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/broadcom/bcm2835/files.bcm2836
===================================================================
--- trunk/sys/arm/broadcom/bcm2835/files.bcm2836	                        (rev 0)
+++ trunk/sys/arm/broadcom/bcm2835/files.bcm2836	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,6 @@
+# $FreeBSD: stable/10/sys/arm/broadcom/bcm2835/files.bcm2836 322724 2017-08-20 16:52:27Z marius $
+
+arm/arm/cpufunc_asm_armv7.S			standard
+arm/arm/generic_timer.c				standard
+
+arm/broadcom/bcm2835/bcm2836.c			standard


Property changes on: trunk/sys/arm/broadcom/bcm2835/files.bcm2836
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/broadcom/bcm2835/std.bcm2835
===================================================================
--- trunk/sys/arm/broadcom/bcm2835/std.bcm2835	                        (rev 0)
+++ trunk/sys/arm/broadcom/bcm2835/std.bcm2835	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,9 @@
+# $FreeBSD: stable/10/sys/arm/broadcom/bcm2835/std.bcm2835 322724 2017-08-20 16:52:27Z marius $
+
+machine	arm armv6
+cpu	CPU_ARM1176
+makeoptions	CONF_CFLAGS="-mcpu=arm1176jzf-s -Wa,-mcpu=arm1176jzf-s"
+options 	SOC_BCM2835
+
+files	"../broadcom/bcm2835/files.bcm2835"
+


Property changes on: trunk/sys/arm/broadcom/bcm2835/std.bcm2835
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/broadcom/bcm2835/std.bcm2836
===================================================================
--- trunk/sys/arm/broadcom/bcm2835/std.bcm2836	                        (rev 0)
+++ trunk/sys/arm/broadcom/bcm2835/std.bcm2836	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,10 @@
+# $FreeBSD: stable/10/sys/arm/broadcom/bcm2835/std.bcm2836 322724 2017-08-20 16:52:27Z marius $
+
+machine 	arm armv6
+cpu		CPU_CORTEXA
+makeoptions	CONF_CFLAGS="-march=armv7a"
+options 	SOC_BCM2836
+
+files	"../broadcom/bcm2835/files.bcm2836"
+files	"../broadcom/bcm2835/files.bcm283x"
+


Property changes on: trunk/sys/arm/broadcom/bcm2835/std.bcm2836
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/broadcom/bcm2835/std.rpi
===================================================================
--- trunk/sys/arm/broadcom/bcm2835/std.rpi	                        (rev 0)
+++ trunk/sys/arm/broadcom/bcm2835/std.rpi	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,11 @@
+# $FreeBSD: stable/10/sys/arm/broadcom/bcm2835/std.rpi 266110 2014-05-15 02:41:23Z ian $
+
+include		"../broadcom/bcm2835/std.bcm2835"
+
+options		KERNVIRTADDR=0xc0100000
+makeoptions	KERNVIRTADDR=0xc0100000
+options		KERNPHYSADDR=0x00100000
+makeoptions	KERNPHYSADDR=0x00100000
+options		PHYSADDR=0x00000000
+options		FREEBSD_BOOT_LOADER
+options		LINUX_BOOT_ABI


Property changes on: trunk/sys/arm/broadcom/bcm2835/std.rpi
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/cavium/cns11xx/cfi_bus_econa.c
===================================================================
--- trunk/sys/arm/cavium/cns11xx/cfi_bus_econa.c	                        (rev 0)
+++ trunk/sys/arm/cavium/cns11xx/cfi_bus_econa.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,68 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2009 Yohanes Nugroho <yohanes at gmail.com>
+ * 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 ``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 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: stable/10/sys/arm/cavium/cns11xx/cfi_bus_econa.c 264219 2014-04-07 05:33:30Z rpaulo $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/rman.h>
+#include <sys/sysctl.h>
+
+#include <machine/bus.h>
+
+#include <dev/cfi/cfi_var.h>
+
+#include <arm/cavium/cns11xx/econa_reg.h>
+#include <arm/cavium/cns11xx/econa_var.h>
+
+static int
+cfi_econa_probe(device_t dev)
+{
+
+	return cfi_probe(dev);
+}
+
+static device_method_t cfi_econa_methods[] = {
+	/* device interface */
+	DEVMETHOD(device_probe,		cfi_econa_probe),
+	DEVMETHOD(device_attach,	cfi_attach),
+	DEVMETHOD(device_detach,	cfi_detach),
+
+	{0, 0}
+};
+
+static driver_t cfi_econa_driver = {
+	cfi_driver_name,
+	cfi_econa_methods,
+	sizeof(struct cfi_softc),
+};
+DRIVER_MODULE(cfi, econaarm, cfi_econa_driver, cfi_devclass, 0, 0);


Property changes on: trunk/sys/arm/cavium/cns11xx/cfi_bus_econa.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/cavium/cns11xx/econa.c
===================================================================
--- trunk/sys/arm/cavium/cns11xx/econa.c	                        (rev 0)
+++ trunk/sys/arm/cavium/cns11xx/econa.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,653 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2009 Yohanes Nugroho <yohanes at gmail.com>
+ * 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 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 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: stable/10/sys/arm/cavium/cns11xx/econa.c 278727 2015-02-13 22:32:02Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/types.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/rman.h>
+#include <vm/vm.h>
+#include <vm/vm_kern.h>
+#include <vm/pmap.h>
+#include <vm/vm_page.h>
+#include <vm/vm_extern.h>
+
+#define	_ARM32_BUS_DMA_PRIVATE
+#include <machine/armreg.h>
+#include <machine/bus.h>
+#include <machine/intr.h>
+#include <machine/resource.h>
+
+#include "econa_reg.h"
+#include "econa_var.h"
+
+static struct econa_softc *econa_softc;
+
+unsigned int CPU_clock = 200000000;
+unsigned int AHB_clock;
+unsigned int APB_clock;
+
+bus_space_tag_t obio_tag;
+
+static int
+econa_probe(device_t dev)
+{
+
+	device_set_desc(dev, "ECONA device bus");
+	return (BUS_PROBE_NOWILDCARD);
+}
+
+static void
+econa_identify(driver_t *drv, device_t parent)
+{
+
+	BUS_ADD_CHILD(parent, 0, "econaarm", 0);
+}
+
+struct arm32_dma_range *
+bus_dma_get_range(void)
+{
+
+	return (NULL);
+}
+
+int
+bus_dma_get_range_nb(void)
+{
+
+	return (0);
+}
+
+extern void irq_entry(void);
+
+static void
+econa_add_child(device_t dev, int prio, const char *name, int unit,
+    bus_addr_t addr, bus_size_t size,
+    int irq0, int irq1,
+    int irq2, int irq3, int irq4)
+{
+	device_t kid;
+	struct econa_ivar *ivar;
+
+	kid = device_add_child_ordered(dev, prio, name, unit);
+	if (kid == NULL) {
+		printf("Can't add child %s%d ordered\n", name, unit);
+		return;
+	}
+	ivar = malloc(sizeof(*ivar), M_DEVBUF, M_NOWAIT | M_ZERO);
+	if (ivar == NULL) {
+		device_delete_child(dev, kid);
+		return;
+	}
+	device_set_ivars(kid, ivar);
+	resource_list_init(&ivar->resources);
+	if (irq0 != -1)
+		bus_set_resource(kid, SYS_RES_IRQ, 0, irq0, 1);
+	if (irq1 != 0)
+		bus_set_resource(kid, SYS_RES_IRQ, 1, irq1, 1);
+	if (irq2 != 0)
+		bus_set_resource(kid, SYS_RES_IRQ, 2, irq2, 1);
+	if (irq3 != 0)
+		bus_set_resource(kid, SYS_RES_IRQ, 3, irq3, 1);
+	if (irq4 != 0)
+		bus_set_resource(kid, SYS_RES_IRQ, 4, irq4, 1);
+
+	if (addr != 0)
+		bus_set_resource(kid, SYS_RES_MEMORY, 0, addr, size);
+
+}
+
+struct cpu_devs
+{
+	const char *name;
+	int unit;
+	bus_addr_t mem_base;
+	bus_size_t mem_len;
+	int irq0;
+	int irq1;
+	int irq2;
+	int irq3;
+	int irq4;
+};
+
+struct cpu_devs econarm_devs[] =
+{
+	{
+		"econa_ic", 0,
+		ECONA_IO_BASE + ECONA_PIC_BASE, ECONA_PIC_SIZE,
+		0
+	},
+	{
+		"system", 0,
+		ECONA_IO_BASE + ECONA_SYSTEM_BASE, ECONA_SYSTEM_SIZE,
+		0
+	},
+	{
+		"uart", 0,
+		ECONA_IO_BASE + ECONA_UART_BASE, ECONA_UART_SIZE,
+		ECONA_IRQ_UART
+	},
+	{
+		"timer", 0,
+		ECONA_IO_BASE + ECONA_TIMER_BASE, ECONA_TIMER_SIZE,
+		ECONA_IRQ_TIMER_1, ECONA_IRQ_TIMER_2
+	},
+	{
+		"ohci", 0,
+		ECONA_OHCI_VBASE, ECONA_OHCI_SIZE,
+		ECONA_IRQ_OHCI
+		},
+	{
+		"ehci", 0,
+		ECONA_EHCI_VBASE, ECONA_EHCI_SIZE,
+		ECONA_IRQ_EHCI
+	},
+	{
+		"cfi", 0,
+		ECONA_CFI_VBASE, ECONA_CFI_SIZE,
+		0
+	},
+	{
+		"ece", 0,
+		ECONA_IO_BASE + ECONA_NET_BASE, ECONA_NET_SIZE,
+		ECONA_IRQ_STATUS,
+		ECONA_IRQ_TSTC, ECONA_IRQ_FSRC,
+		ECONA_IRQ_TSQE, ECONA_IRQ_FSQF,
+	},
+	{	0, 0, 0, 0, 0, 0, 0, 0, 0 }
+};
+
+static void
+econa_cpu_add_builtin_children(device_t dev, struct econa_softc *sc)
+{
+	int i;
+	struct cpu_devs *walker;
+
+	for (i = 0, walker = econarm_devs; walker->name; i++, walker++) {
+		econa_add_child(dev, i, walker->name, walker->unit,
+		    walker->mem_base, walker->mem_len,
+		    walker->irq0,walker->irq1, walker->irq2,
+		    walker->irq3, walker->irq4);
+	}
+
+}
+
+struct intc_trigger_t {
+	int mode;
+	int level;
+};
+
+static struct intc_trigger_t intc_trigger_table[] = {
+	{INTC_EDGE_TRIGGER, INTC_RISING_EDGE},
+	{INTC_EDGE_TRIGGER, INTC_RISING_EDGE},
+	{INTC_EDGE_TRIGGER, INTC_FALLING_EDGE},
+	{INTC_EDGE_TRIGGER, INTC_RISING_EDGE},
+	{INTC_TRIGGER_UNKNOWN, INTC_TRIGGER_UNKNOWN},
+	{INTC_LEVEL_TRIGGER, INTC_ACTIVE_LOW},
+	{INTC_LEVEL_TRIGGER, INTC_ACTIVE_LOW},
+	{INTC_LEVEL_TRIGGER, INTC_ACTIVE_HIGH},
+	{INTC_TRIGGER_UNKNOWN, INTC_TRIGGER_UNKNOWN},
+	{INTC_LEVEL_TRIGGER, INTC_ACTIVE_HIGH},
+	{INTC_LEVEL_TRIGGER, INTC_ACTIVE_HIGH},
+	{INTC_LEVEL_TRIGGER, INTC_ACTIVE_HIGH},
+	{INTC_LEVEL_TRIGGER, INTC_ACTIVE_HIGH},
+	{INTC_TRIGGER_UNKNOWN, INTC_TRIGGER_UNKNOWN},
+	{INTC_LEVEL_TRIGGER, INTC_ACTIVE_HIGH},
+	{INTC_EDGE_TRIGGER, INTC_FALLING_EDGE},
+	{INTC_TRIGGER_UNKNOWN, INTC_TRIGGER_UNKNOWN},
+	{INTC_TRIGGER_UNKNOWN, INTC_TRIGGER_UNKNOWN},
+	{INTC_LEVEL_TRIGGER, INTC_ACTIVE_HIGH},
+	{INTC_EDGE_TRIGGER, INTC_RISING_EDGE},
+	{INTC_EDGE_TRIGGER, INTC_RISING_EDGE},
+	{INTC_EDGE_TRIGGER, INTC_RISING_EDGE},
+	{INTC_EDGE_TRIGGER, INTC_RISING_EDGE},
+	{INTC_LEVEL_TRIGGER, INTC_ACTIVE_LOW},
+	{INTC_LEVEL_TRIGGER, INTC_ACTIVE_LOW},
+};
+
+static inline uint32_t
+read_4(struct econa_softc *sc, bus_size_t off)
+{
+
+	return bus_space_read_4(sc->ec_st, sc->ec_sys_sh, off);
+}
+
+static inline void
+write_4(struct econa_softc *sc, bus_size_t off, uint32_t val)
+{
+
+	return bus_space_write_4(sc->ec_st, sc->ec_sys_sh, off, val);
+}
+
+static inline uint32_t
+system_read_4(struct econa_softc *sc, bus_size_t off)
+{
+
+	return bus_space_read_4(sc->ec_st, sc->ec_system_sh, off);
+}
+
+static inline void
+system_write_4(struct econa_softc *sc, bus_size_t off, uint32_t val)
+{
+
+	return bus_space_write_4(sc->ec_st, sc->ec_system_sh, off, val);
+}
+
+
+
+static inline void
+econa_set_irq_mode(struct econa_softc * sc, unsigned int irq,
+		   unsigned int mode)
+{
+	unsigned int val;
+
+	if ((mode != INTC_LEVEL_TRIGGER) && (mode != INTC_EDGE_TRIGGER))
+		return;
+
+	val =	read_4(sc, INTC_INTERRUPT_TRIGGER_MODE_REG_OFFSET);
+
+	if (mode == INTC_LEVEL_TRIGGER) {
+		if (val & (1UL << irq)) {
+			val &= ~(1UL << irq);
+			write_4(sc, INTC_INTERRUPT_TRIGGER_MODE_REG_OFFSET,
+			    val);
+		}
+	} else {
+		if (!(val & (1UL << irq))) {
+			val |= (1UL << irq);
+			write_4(sc, INTC_INTERRUPT_TRIGGER_MODE_REG_OFFSET,
+			    val);
+		}
+	}
+}
+
+/*
+ * Configure interrupt trigger level to be Active High/Low
+ * or Rising/Falling Edge
+ */
+static inline void
+econa_set_irq_level(struct econa_softc * sc,
+    unsigned int irq, unsigned int level)
+{
+	unsigned int val;
+
+	if ((level != INTC_ACTIVE_HIGH) &&
+	    (level != INTC_ACTIVE_LOW) &&
+	    (level != INTC_RISING_EDGE) &&
+	    (level != INTC_FALLING_EDGE)) {
+		return;
+	}
+
+	val = read_4(sc, INTC_INTERRUPT_TRIGGER_LEVEL_REG_OFFSET);
+
+	if ((level == INTC_ACTIVE_HIGH) || (level == INTC_RISING_EDGE)) {
+		if (val & (1UL << irq)) {
+			val &= ~(1UL << irq);
+			write_4(sc, INTC_INTERRUPT_TRIGGER_LEVEL_REG_OFFSET,
+			    val);
+		}
+	} else {
+		if (!(val & (1UL << irq))) {
+			val |= (1UL << irq);
+			write_4(sc, INTC_INTERRUPT_TRIGGER_LEVEL_REG_OFFSET,
+			    val);
+		}
+	}
+}
+
+static void
+get_system_clock(void)
+{
+	uint32_t sclock = system_read_4(econa_softc, SYSTEM_CLOCK);
+
+	sclock = (sclock >> 6) & 0x03;
+
+	switch (sclock) {
+	case 0:
+		CPU_clock = 175000000;
+		break;
+	case 1:
+		CPU_clock = 200000000;
+		break;
+	case 2:
+		CPU_clock = 225000000;
+		break;
+	case 3:
+		CPU_clock = 250000000;
+		break;
+	}
+	AHB_clock = CPU_clock >> 1;
+	APB_clock = AHB_clock >> 1;
+}
+
+static int
+econa_attach(device_t dev)
+{
+	struct econa_softc *sc = device_get_softc(dev);
+	int i;
+
+	obio_tag = arm_base_bs_tag;
+
+	econa_softc = sc;
+	sc->ec_st = arm_base_bs_tag;
+	sc->ec_sh = ECONA_IO_BASE;
+	sc->dev = dev;
+	if (bus_space_subregion(sc->ec_st, sc->ec_sh, ECONA_PIC_BASE,
+	    ECONA_PIC_SIZE, &sc->ec_sys_sh) != 0)
+		panic("Unable to map IRQ registers");
+
+	if (bus_space_subregion(sc->ec_st, sc->ec_sh, ECONA_SYSTEM_BASE,
+	    ECONA_SYSTEM_SIZE, &sc->ec_system_sh) != 0)
+		panic("Unable to map IRQ registers");
+
+	sc->ec_irq_rman.rm_type = RMAN_ARRAY;
+	sc->ec_irq_rman.rm_descr = "ECONA IRQs";
+	sc->ec_mem_rman.rm_type = RMAN_ARRAY;
+	sc->ec_mem_rman.rm_descr = "ECONA Memory";
+	if (rman_init(&sc->ec_irq_rman) != 0 ||
+	    rman_manage_region(&sc->ec_irq_rman, 0, 31) != 0)
+		panic("econa_attach: failed to set up IRQ rman");
+	if (rman_init(&sc->ec_mem_rman) != 0 ||
+	    rman_manage_region(&sc->ec_mem_rman, 0,
+	    ~0) != 0)
+		panic("econa_attach: failed to set up memory rman");
+
+	write_4(sc, INTC_INTERRUPT_CLEAR_EDGE_TRIGGER_REG_OFFSET, 0xffffffff);
+
+	write_4(sc, INTC_INTERRUPT_MASK_REG_OFFSET, 0xffffffff);
+
+	write_4(sc, INTC_FIQ_MODE_SELECT_REG_OFFSET, 0);
+
+	/*initialize irq*/
+	for (i = 0; i < 32; i++) {
+		if (intc_trigger_table[i].mode != INTC_TRIGGER_UNKNOWN) {
+			econa_set_irq_mode(sc,i, intc_trigger_table[i].mode);
+			econa_set_irq_level(sc, i, intc_trigger_table[i].level);
+		}
+	}
+
+	get_system_clock();
+
+	econa_cpu_add_builtin_children(dev, sc);
+
+	bus_generic_probe(dev);
+	bus_generic_attach(dev);
+	enable_interrupts(PSR_I | PSR_F);
+
+	return (0);
+}
+
+static struct resource *
+econa_alloc_resource(device_t dev, device_t child, int type, int *rid,
+    u_long start, u_long end, u_long count, u_int flags)
+{
+	struct econa_softc *sc = device_get_softc(dev);
+	struct resource_list_entry *rle;
+	struct econa_ivar *ivar = device_get_ivars(child);
+	struct resource_list *rl = &ivar->resources;
+
+	if (device_get_parent(child) != dev)
+		return (BUS_ALLOC_RESOURCE(device_get_parent(dev), child,
+			   type, rid, start, end, count, flags));
+
+	rle = resource_list_find(rl, type, *rid);
+	if (rle == NULL) {
+		return (NULL);
+	}
+	if (rle->res)
+		panic("Resource rid %d type %d already in use", *rid, type);
+	if (start == 0UL && end == ~0UL) {
+		start = rle->start;
+		count = ulmax(count, rle->count);
+		end = ulmax(rle->end, start + count - 1);
+	}
+	switch (type)
+	{
+	case SYS_RES_IRQ:
+		rle->res = rman_reserve_resource(&sc->ec_irq_rman,
+		    start, end, count, flags, child);
+		break;
+	case SYS_RES_MEMORY:
+		rle->res = rman_reserve_resource(&sc->ec_mem_rman,
+		    start, end, count, flags, child);
+		if (rle->res != NULL) {
+			rman_set_bustag(rle->res, arm_base_bs_tag);
+			rman_set_bushandle(rle->res, start);
+		}
+		break;
+	}
+	if (rle->res) {
+		rle->start = rman_get_start(rle->res);
+		rle->end = rman_get_end(rle->res);
+		rle->count = count;
+		rman_set_rid(rle->res, *rid);
+	}
+	return (rle->res);
+}
+
+static struct resource_list *
+econa_get_resource_list(device_t dev, device_t child)
+{
+	struct econa_ivar *ivar;
+	ivar = device_get_ivars(child);
+	return (&(ivar->resources));
+}
+
+static int
+econa_release_resource(device_t dev, device_t child, int type,
+    int rid, struct resource *r)
+{
+	struct resource_list *rl;
+	struct resource_list_entry *rle;
+
+	rl = econa_get_resource_list(dev, child);
+	if (rl == NULL)
+		return (EINVAL);
+	rle = resource_list_find(rl, type, rid);
+	if (rle == NULL)
+		return (EINVAL);
+	rman_release_resource(r);
+	rle->res = NULL;
+	return (0);
+}
+
+static int
+econa_setup_intr(device_t dev, device_t child,
+    struct resource *ires, int flags, driver_filter_t *filt,
+    driver_intr_t *intr, void *arg, void **cookiep)
+{
+	int error;
+
+	if (rman_get_start(ires) == ECONA_IRQ_SYSTEM && filt == NULL)
+		panic("All system interrupt ISRs must be FILTER");
+
+	error = BUS_SETUP_INTR(device_get_parent(dev), child, ires, flags,
+	    filt, intr, arg, cookiep);
+	if (error)
+		return (error);
+
+	return (0);
+}
+
+static int
+econa_teardown_intr(device_t dev, device_t child, struct resource *res,
+    void *cookie)
+{
+
+	return (BUS_TEARDOWN_INTR(device_get_parent(dev), child, res, cookie));
+}
+
+static int
+econa_activate_resource(device_t bus, device_t child, int type, int rid,
+    struct resource *r)
+{
+
+	return (rman_activate_resource(r));
+}
+
+static int
+econa_print_child(device_t dev, device_t child)
+{
+	struct econa_ivar *ivars;
+	struct resource_list *rl;
+	int retval = 0;
+
+	ivars = device_get_ivars(child);
+	rl = &ivars->resources;
+
+	retval += bus_print_child_header(dev, child);
+
+	retval += resource_list_print_type(rl, "port", SYS_RES_IOPORT, "%#lx");
+	retval += resource_list_print_type(rl, "mem", SYS_RES_MEMORY, "%#lx");
+	retval += resource_list_print_type(rl, "irq", SYS_RES_IRQ, "%ld");
+	if (device_get_flags(dev))
+		retval += printf(" flags %#x", device_get_flags(dev));
+
+	retval += bus_print_child_footer(dev, child);
+
+	return (retval);
+}
+
+void
+arm_mask_irq(uintptr_t nb)
+{
+	unsigned int value;
+
+	value = read_4(econa_softc,INTC_INTERRUPT_MASK_REG_OFFSET) | 1<<nb;
+	write_4(econa_softc, INTC_INTERRUPT_MASK_REG_OFFSET, value);
+}
+
+void
+arm_unmask_irq(uintptr_t nb)
+{
+	unsigned int value;
+
+	value = read_4(econa_softc,
+	    INTC_INTERRUPT_CLEAR_EDGE_TRIGGER_REG_OFFSET) | (1 << nb);
+	write_4(econa_softc,
+	    INTC_INTERRUPT_CLEAR_EDGE_TRIGGER_REG_OFFSET, value);
+	value = read_4(econa_softc, INTC_INTERRUPT_MASK_REG_OFFSET)& ~(1 << nb);
+	write_4(econa_softc, INTC_INTERRUPT_MASK_REG_OFFSET, value);
+}
+
+int
+arm_get_next_irq(int x)
+{
+	int irq;
+
+	irq = read_4(econa_softc, INTC_INTERRUPT_STATUS_REG_OFFSET) &
+	    ~(read_4(econa_softc, INTC_INTERRUPT_MASK_REG_OFFSET));
+
+	if (irq!=0) {
+		return (ffs(irq) - 1);
+	}
+
+	return (-1);
+}
+
+void
+cpu_reset(void)
+{
+	uint32_t control;
+
+	control = system_read_4(econa_softc, RESET_CONTROL);
+	control |= GLOBAL_RESET;
+	system_write_4(econa_softc, RESET_CONTROL, control);
+	control = system_read_4(econa_softc, RESET_CONTROL);
+	control &= (~(GLOBAL_RESET));
+	system_write_4(econa_softc, RESET_CONTROL, control);
+	while (1);
+}
+
+
+
+void
+power_on_network_interface(void)
+{
+	uint32_t cfg_reg;
+	int ii;
+
+	cfg_reg =  system_read_4(econa_softc, RESET_CONTROL);
+	cfg_reg |= NET_INTERFACE_RESET;
+	/* set reset bit to HIGH active; */
+	system_write_4(econa_softc, RESET_CONTROL, cfg_reg);
+
+	/*pulse delay */
+	for (ii = 0; ii < 0xFFF; ii++)
+		DELAY(100);
+	/* set reset bit to LOW active; */
+	cfg_reg =  system_read_4(econa_softc, RESET_CONTROL);
+	cfg_reg &= ~(NET_INTERFACE_RESET);
+	system_write_4(econa_softc, RESET_CONTROL, cfg_reg);
+
+	/*pulse delay */
+	for (ii = 0; ii < 0xFFF; ii++)
+		DELAY(100);
+	cfg_reg = system_read_4(econa_softc, RESET_CONTROL);
+	cfg_reg |= NET_INTERFACE_RESET;
+	/* set reset bit to HIGH active; */
+	system_write_4(econa_softc, RESET_CONTROL, cfg_reg);
+}
+
+unsigned int
+get_tclk(void)
+{
+
+	return CPU_clock;
+}
+
+static device_method_t econa_methods[] = {
+	DEVMETHOD(device_probe,		econa_probe),
+	DEVMETHOD(device_attach,		econa_attach),
+	DEVMETHOD(device_identify,		econa_identify),
+	DEVMETHOD(bus_alloc_resource,		econa_alloc_resource),
+	DEVMETHOD(bus_setup_intr,		econa_setup_intr),
+	DEVMETHOD(bus_teardown_intr,		econa_teardown_intr),
+	DEVMETHOD(bus_activate_resource,	econa_activate_resource),
+	DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+	DEVMETHOD(bus_get_resource_list,	econa_get_resource_list),
+	DEVMETHOD(bus_set_resource,		bus_generic_rl_set_resource),
+	DEVMETHOD(bus_get_resource,		bus_generic_rl_get_resource),
+	DEVMETHOD(bus_release_resource,	econa_release_resource),
+	DEVMETHOD(bus_print_child,		econa_print_child),
+	{0, 0},
+};
+
+static driver_t econa_driver = {
+	"econaarm",
+	econa_methods,
+	sizeof(struct econa_softc),
+};
+static devclass_t econa_devclass;
+
+DRIVER_MODULE(econaarm, nexus, econa_driver, econa_devclass, 0, 0);


Property changes on: trunk/sys/arm/cavium/cns11xx/econa.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/cavium/cns11xx/econa_machdep.c
===================================================================
--- trunk/sys/arm/cavium/cns11xx/econa_machdep.c	                        (rev 0)
+++ trunk/sys/arm/cavium/cns11xx/econa_machdep.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,344 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2009 Yohanes Nugroho <yohanes at gmail.com>
+ * Copyright (c) 1994-1998 Mark Brinicombe.
+ * Copyright (c) 1994 Brini.
+ * All rights reserved.
+ *
+ * This code is derived from software written for Brini by Mark Brinicombe
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by Brini.
+ * 4. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BRINI ``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 BRINI 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: stable/10/sys/arm/cavium/cns11xx/econa_machdep.c 266386 2014-05-18 00:32:35Z ian $");
+
+#define	_ARM32_BUS_DMA_PRIVATE
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/sysproto.h>
+#include <sys/signalvar.h>
+#include <sys/imgact.h>
+#include <sys/kernel.h>
+#include <sys/ktr.h>
+#include <sys/linker.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/mutex.h>
+#include <sys/pcpu.h>
+#include <sys/proc.h>
+#include <sys/ptrace.h>
+#include <sys/cons.h>
+#include <sys/bio.h>
+#include <sys/bus.h>
+#include <sys/buf.h>
+#include <sys/exec.h>
+#include <sys/kdb.h>
+#include <sys/msgbuf.h>
+#include <machine/physmem.h>
+#include <machine/reg.h>
+#include <machine/cpu.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/vm_object.h>
+#include <vm/vm_page.h>
+#include <vm/vm_map.h>
+#include <machine/devmap.h>
+#include <machine/vmparam.h>
+#include <machine/pcb.h>
+#include <machine/undefined.h>
+#include <machine/machdep.h>
+#include <machine/metadata.h>
+#include <machine/armreg.h>
+#include <machine/bus.h>
+#include <sys/reboot.h>
+#include "econa_reg.h"
+
+/* Page table for mapping proc0 zero page */
+#define	KERNEL_PT_SYS		0
+#define	KERNEL_PT_KERN		1
+#define	KERNEL_PT_KERN_NUM	22
+/* L2 table for mapping after kernel */
+#define	KERNEL_PT_AFKERNEL	KERNEL_PT_KERN + KERNEL_PT_KERN_NUM
+#define	KERNEL_PT_AFKERNEL_NUM	5
+
+/* this should be evenly divisable by PAGE_SIZE / L2_TABLE_SIZE_REAL (or 4) */
+#define	NUM_KERNEL_PTS	(KERNEL_PT_AFKERNEL + KERNEL_PT_AFKERNEL_NUM)
+
+struct pv_addr kernel_pt_table[NUM_KERNEL_PTS];
+
+/* Physical and virtual addresses for some global pages */
+
+struct pv_addr systempage;
+struct pv_addr msgbufpv;
+struct pv_addr irqstack;
+struct pv_addr undstack;
+struct pv_addr abtstack;
+struct pv_addr kernelstack;
+
+/* Static device mappings. */
+static const struct arm_devmap_entry econa_devmap[] = {
+	{
+		/*
+		 * This maps DDR SDRAM
+		 */
+		ECONA_SDRAM_BASE, /*virtual*/
+		ECONA_SDRAM_BASE, /*physical*/
+		ECONA_SDRAM_SIZE, /*size*/
+		VM_PROT_READ|VM_PROT_WRITE,
+		PTE_DEVICE,
+	},
+	/*
+	 * Map the on-board devices VA == PA so that we can access them
+	 * with the MMU on or off.
+	 */
+	{
+		/*
+		 * This maps the interrupt controller, the UART
+		 * and the timer.
+		 */
+		ECONA_IO_BASE, /*virtual*/
+		ECONA_IO_BASE, /*physical*/
+		ECONA_IO_SIZE, /*size*/
+		VM_PROT_READ|VM_PROT_WRITE,
+		PTE_DEVICE,
+	},
+	{
+		/*
+		 * OHCI + EHCI
+		 */
+		ECONA_OHCI_VBASE, /*virtual*/
+		ECONA_OHCI_PBASE, /*physical*/
+		ECONA_USB_SIZE, /*size*/
+		VM_PROT_READ|VM_PROT_WRITE,
+		PTE_DEVICE,
+	},
+	{
+		/*
+		 * CFI
+		 */
+		ECONA_CFI_VBASE, /*virtual*/
+		ECONA_CFI_PBASE, /*physical*/
+		ECONA_CFI_SIZE,
+		VM_PROT_READ|VM_PROT_WRITE,
+		PTE_DEVICE,
+	},
+	{
+		0,
+		0,
+		0,
+		0,
+		0,
+	}
+};
+
+
+void *
+initarm(struct arm_boot_params *abp)
+{
+	struct pv_addr  kernel_l1pt;
+	volatile uint32_t * ddr = (uint32_t *)0x4000000C;
+	int loop, i;
+	u_int l1pagetable;
+	vm_offset_t afterkern;
+	vm_offset_t freemempos;
+	vm_offset_t lastaddr;
+	uint32_t memsize;
+	int mem_info;
+
+	boothowto = RB_VERBOSE;
+	lastaddr = parse_boot_param(abp);
+	arm_physmem_kernaddr = abp->abp_physaddr;
+	set_cpufuncs();
+	pcpu0_init();
+
+	/* Do basic tuning, hz etc */
+      	init_param1();
+		
+
+	freemempos = (lastaddr + PAGE_MASK) & ~PAGE_MASK;
+	/* Define a macro to simplify memory allocation */
+#define	valloc_pages(var, np)                   \
+	alloc_pages((var).pv_va, (np));         \
+	(var).pv_pa = (var).pv_va + (abp->abp_physaddr - KERNVIRTADDR);
+
+#define	alloc_pages(var, np)			\
+	(var) = freemempos;		\
+	freemempos += (np * PAGE_SIZE);		\
+	memset((char *)(var), 0, ((np) * PAGE_SIZE));
+
+	while (((freemempos - L1_TABLE_SIZE) & (L1_TABLE_SIZE - 1)) != 0)
+		freemempos += PAGE_SIZE;
+	valloc_pages(kernel_l1pt, L1_TABLE_SIZE / PAGE_SIZE);
+	for (loop = 0; loop < NUM_KERNEL_PTS; ++loop) {
+		if (!(loop % (PAGE_SIZE / L2_TABLE_SIZE_REAL))) {
+			valloc_pages(kernel_pt_table[loop],
+			    L2_TABLE_SIZE / PAGE_SIZE);
+		} else {
+			kernel_pt_table[loop].pv_va = freemempos -
+			    (loop % (PAGE_SIZE / L2_TABLE_SIZE_REAL)) *
+			    L2_TABLE_SIZE_REAL;
+			kernel_pt_table[loop].pv_pa =
+			    kernel_pt_table[loop].pv_va - KERNVIRTADDR +
+			    abp->abp_physaddr;
+		}
+	}
+	/*
+	 * Allocate a page for the system page mapped to V0x00000000
+	 * This page will just contain the system vectors and can be
+	 * shared by all processes.
+	 */
+	valloc_pages(systempage, 1);
+
+	/* Allocate stacks for all modes */
+	valloc_pages(irqstack, IRQ_STACK_SIZE);
+	valloc_pages(abtstack, ABT_STACK_SIZE);
+	valloc_pages(undstack, UND_STACK_SIZE);
+	valloc_pages(kernelstack, KSTACK_PAGES);
+	valloc_pages(msgbufpv, round_page(msgbufsize) / PAGE_SIZE);
+
+	/*
+	 * Now we start construction of the L1 page table
+	 * We start by mapping the L2 page tables into the L1.
+	 * This means that we can replace L1 mappings later on if necessary
+	 */
+	l1pagetable = kernel_l1pt.pv_va;
+
+	/* Map the L2 pages tables in the L1 page table */
+	pmap_link_l2pt(l1pagetable, ARM_VECTORS_HIGH,
+	    &kernel_pt_table[KERNEL_PT_SYS]);
+	for (i = 0; i < KERNEL_PT_KERN_NUM; i++)
+		pmap_link_l2pt(l1pagetable, KERNBASE + i * L1_S_SIZE,
+		    &kernel_pt_table[KERNEL_PT_KERN + i]);
+	pmap_map_chunk(l1pagetable, KERNBASE, PHYSADDR,
+	   (((uint32_t)lastaddr - KERNBASE) + PAGE_SIZE) & ~(PAGE_SIZE - 1),
+	    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+	afterkern = round_page((lastaddr + L1_S_SIZE) & ~(L1_S_SIZE - 1));
+	for (i = 0; i < KERNEL_PT_AFKERNEL_NUM; i++) {
+		pmap_link_l2pt(l1pagetable, afterkern + i * L1_S_SIZE,
+		    &kernel_pt_table[KERNEL_PT_AFKERNEL + i]);
+	}
+
+	/* Map the vector page. */
+	pmap_map_entry(l1pagetable, ARM_VECTORS_HIGH, systempage.pv_pa,
+	    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+
+
+	/* Map the stack pages */
+	pmap_map_chunk(l1pagetable, irqstack.pv_va, irqstack.pv_pa,
+	    IRQ_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+	pmap_map_chunk(l1pagetable, abtstack.pv_va, abtstack.pv_pa,
+	    ABT_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+	pmap_map_chunk(l1pagetable, undstack.pv_va, undstack.pv_pa,
+	    UND_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+	pmap_map_chunk(l1pagetable, kernelstack.pv_va, kernelstack.pv_pa,
+	    KSTACK_PAGES * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+
+	pmap_map_chunk(l1pagetable, kernel_l1pt.pv_va, kernel_l1pt.pv_pa,
+	    L1_TABLE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE);
+	pmap_map_chunk(l1pagetable, msgbufpv.pv_va, msgbufpv.pv_pa,
+	    msgbufsize, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+
+	for (loop = 0; loop < NUM_KERNEL_PTS; ++loop) {
+		pmap_map_chunk(l1pagetable, kernel_pt_table[loop].pv_va,
+		    kernel_pt_table[loop].pv_pa, L2_TABLE_SIZE,
+		    VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE);
+	}
+
+	arm_devmap_bootstrap(l1pagetable, econa_devmap);
+	cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT);
+	setttb(kernel_l1pt.pv_pa);
+	cpu_tlb_flushID();
+	cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2));
+	cninit();
+	mem_info = ((*ddr) >> 4) & 0x3;
+	memsize = (8<<mem_info)*1024*1024;
+
+	/*
+	 * Pages were allocated during the secondary bootstrap for the
+	 * stacks for different CPU modes.
+	 * We must now set the r13 registers in the different CPU modes to
+	 * point to these stacks.
+	 * Since the ARM stacks use STMFD etc. we must set r13 to the top end
+	 * of the stack memory.
+	 */
+	cpu_control(CPU_CONTROL_MMU_ENABLE, CPU_CONTROL_MMU_ENABLE);
+
+	set_stackptrs(0);
+
+	/*
+	 * We must now clean the cache again....
+	 * Cleaning may be done by reading new data to displace any
+	 * dirty data in the cache. This will have happened in setttb()
+	 * but since we are boot strapping the addresses used for the read
+	 * may have just been remapped and thus the cache could be out
+	 * of sync. A re-clean after the switch will cure this.
+	 * After booting there are no gross relocations of the kernel thus
+	 * this problem will not occur after initarm().
+	 */
+	cpu_idcache_wbinv_all();
+	cpu_setup("");
+
+	undefined_init();
+
+	init_proc0(kernelstack.pv_va);
+
+	arm_vector_init(ARM_VECTORS_HIGH, ARM_VEC_ALL);
+
+	pmap_curmaxkvaddr = afterkern + L1_S_SIZE * (KERNEL_PT_KERN_NUM - 1);
+	vm_max_kernel_address = KERNVIRTADDR + 3 * memsize;
+	pmap_bootstrap(freemempos, &kernel_l1pt);
+
+	msgbufp = (void*)msgbufpv.pv_va;
+	msgbufinit(msgbufp, msgbufsize);
+
+	mutex_init();
+
+	/*
+	 * Add the physical ram we have available.
+	 *
+	 * Exclude the kernel, and all the things we allocated which immediately
+	 * follow the kernel, from the VM allocation pool but not from crash
+	 * dumps.  virtual_avail is a global variable which tracks the kva we've
+	 * "allocated" while setting up pmaps.
+	 *
+	 * Prepare the list of physical memory available to the vm subsystem.
+	 */
+	arm_physmem_hardware_region(PHYSADDR, memsize);
+	arm_physmem_exclude_region(abp->abp_physaddr, 
+	    virtual_avail - KERNVIRTADDR, EXFLAG_NOALLOC);
+	arm_physmem_init_kernel_globals();
+
+	init_param2(physmem);
+	kdb_init();
+
+	return ((void *)(kernelstack.pv_va + USPACE_SVC_STACK_TOP -
+	    sizeof(struct pcb)));
+}


Property changes on: trunk/sys/arm/cavium/cns11xx/econa_machdep.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/cavium/cns11xx/econa_reg.h
===================================================================
--- trunk/sys/arm/cavium/cns11xx/econa_reg.h	                        (rev 0)
+++ trunk/sys/arm/cavium/cns11xx/econa_reg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,181 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2009 Yohanes Nugroho <yohanes at gmail.com>
+ * 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 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 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: stable/10/sys/arm/cavium/cns11xx/econa_reg.h 201468 2010-01-04 03:35:45Z rpaulo $
+ */
+#ifndef	_ARM_ECONA_REG_H
+#define	_ARM_ECONA_REG_H
+
+#define	ECONA_SRAM_SIZE	0x10000000
+#define	ECONA_DRAM_BASE	0x00000000 /* DRAM (via DDR Control Module) */
+
+#define	ECONA_SDRAM_BASE	0x40000000
+#define	ECONA_SDRAM_SIZE	0x1000000
+
+
+#define	ECONA_IO_BASE		0x70000000
+#define	ECONA_IO_SIZE		0x0E000000
+#define	ECONA_PIC_BASE		0x0D000000
+#define	ECONA_PIC_SIZE		0x01000000
+
+#define	ECONA_UART_BASE	0x08000000
+#define	ECONA_UART_SIZE	0x01000000
+#define	ECONA_IRQ_UART		0xA
+
+#define	ECONA_TIMER_BASE	0x09000000
+#define	ECONA_TIMER_SIZE	0x01000000
+#define	ECONA_IRQ_TIMER_1	0
+#define	ECONA_IRQ_TIMER_2	1
+#define	ECONA_IRQ_OHCI		23
+#define	ECONA_IRQ_EHCI		24
+
+#define	ECONA_NET_BASE		0x00000000
+
+#define	ECONA_SYSTEM_BASE	0x07000000
+#define	ECONA_SYSTEM_SIZE	0x01000000
+
+#define	ECONA_NET_SIZE		0x01000000
+
+#define	ECONA_CFI_PBASE	0x10000000
+#define	ECONA_CFI_VBASE	0xD0000000
+#define	ECONA_CFI_SIZE		0x10000000
+
+#define	ECONA_IRQ_STATUS	18
+#define	ECONA_IRQ_TSTC		19
+#define	ECONA_IRQ_FSRC		20
+#define	ECONA_IRQ_TSQE		21
+#define	ECONA_IRQ_FSQF		22
+
+#define	ECONA_IRQ_SYSTEM	0
+
+#define	ECONA_EHCI_PBASE	0xC8000000
+#define	ECONA_EHCI_VBASE	0xF8000000
+#define	ECONA_EHCI_SIZE	0x8000000
+
+#define	ECONA_OHCI_PBASE	0xC0000000
+#define	ECONA_OHCI_VBASE	0xF0000000
+#define	ECONA_OHCI_SIZE	0x8000000
+
+#define	ECONA_USB_SIZE		0xf000000
+
+/*Interrupt controller*/
+#define	INTC_LEVEL_TRIGGER	0
+#define	INTC_EDGE_TRIGGER	1
+#define	INTC_ACTIVE_HIGH	0
+#define	INTC_ACTIVE_LOW	1
+/*
+ * define rising/falling edge for edge trigger mode
+ */
+#define	INTC_RISING_EDGE	0
+#define	INTC_FALLING_EDGE	1
+
+#define	INTC_INTERRUPT_SOURCE_REG_OFFSET		0x00
+#define	INTC_INTERRUPT_MASK_REG_OFFSET			0x04
+#define	INTC_INTERRUPT_CLEAR_EDGE_TRIGGER_REG_OFFSET	0x08
+#define	INTC_INTERRUPT_TRIGGER_MODE_REG_OFFSET		0x0C
+#define	INTC_INTERRUPT_TRIGGER_LEVEL_REG_OFFSET	0x10
+#define	INTC_INTERRUPT_STATUS_REG_OFFSET		0x14
+#define	INTC_FIQ_MODE_SELECT_REG_OFFSET		0x18
+#define	INTC_SOFTWARE_INTERRUPT_REG_OFFSET		0x1C
+
+
+/*
+ * define rising/falling edge for edge trigger mode
+ */
+#define	INTC_RISING_EDGE	0
+#define	INTC_FALLING_EDGE	1
+
+
+#define	TIMER_TM1_COUNTER_REG		0x00
+#define	TIMER_TM1_LOAD_REG		0x04
+#define	TIMER_TM1_MATCH1_REG		0x08
+#define	TIMER_TM1_MATCH2_REG		0x0C
+
+#define	TIMER_TM2_COUNTER_REG		0x10
+#define	TIMER_TM2_LOAD_REG		0x14
+#define	TIMER_TM2_MATCH1_REG		0x18
+#define	TIMER_TM2_MATCH2_REG		0x1C
+
+#define	TIMER_TM_CR_REG		0x30
+#define	TIMER_TM_INTR_STATUS_REG	0x34
+#define	TIMER_TM_INTR_MASK_REG		0x38
+
+#define	TIMER_TM_REVISION_REG		0x3C
+
+
+#define	INTC_TIMER1_BIT_INDEX		0
+
+#define	TIMER1_UP_DOWN_COUNT		(1<<9)
+#define	TIMER2_UP_DOWN_COUNT		(1<<10)
+
+#define	TIMER1_MATCH1_INTR		(1<<0)
+#define	TIMER1_MATCH2_INTR		(1<<1)
+#define	TIMER1_OVERFLOW_INTR		(1<<2)
+
+
+#define	TIMER2_MATCH1_INTR		(1<<3)
+#define	TIMER2_MATCH2_INTR		(1<<4)
+#define	TIMER2_OVERFLOW_INTR		(1<<5)
+
+
+#define	TIMER_CLOCK_SOURCE_PCLK	0
+#define	TIMER_CLOCK_SOURCE_EXT_CLK	1
+
+/*
+ * define interrupt trigger mode
+ */
+#define	INTC_LEVEL_TRIGGER		0
+#define	INTC_EDGE_TRIGGER		1
+
+
+#define	INTC_TRIGGER_UNKNOWN -1
+
+#define	TIMER1_OVERFLOW_INTERRUPT	(1<<2)
+#define	TIMER2_OVERFLOW_INTERRUPT	(1<<5)
+#define	TIMER_INTERRUPT_STATUS_REG	0x34
+
+
+#define	TIMER1_ENABLE			(1<<0)
+#define	TIMER1_CLOCK_SOURCE		(1<<1)
+#define	TIMER1_OVERFLOW_ENABLE		(1<<2)
+
+
+#define	TIMER2_ENABLE			(1<<3)
+#define	TIMER2_CLOCK_SOURCE		(1<<4)
+#define	TIMER2_OVERFLOW_ENABLE		(1<<5)
+
+
+#define	TIMER_1			1
+
+#define	EC_UART_CLOCK			14769200
+#define	EC_UART_REGSHIFT		2
+
+#define	SYSTEM_CLOCK			0x14
+#define	RESET_CONTROL			0x4
+#define	GLOBAL_RESET			0x1
+#define	NET_INTERFACE_RESET		(0x1 << 4)
+
+#endif


Property changes on: trunk/sys/arm/cavium/cns11xx/econa_reg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/cavium/cns11xx/econa_var.h
===================================================================
--- trunk/sys/arm/cavium/cns11xx/econa_var.h	                        (rev 0)
+++ trunk/sys/arm/cavium/cns11xx/econa_var.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,53 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2009 Yohanes Nugroho <yohanes at gmail.com>.
+ * 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 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 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: stable/10/sys/arm/cavium/cns11xx/econa_var.h 201468 2010-01-04 03:35:45Z rpaulo $
+ */
+
+#ifndef	_ARM_ECONA_VAR_H
+#define	_ARM_ECONA_VAR_H
+
+extern bus_space_tag_t obio_tag;
+
+struct econa_softc {
+	device_t dev;
+	bus_space_tag_t ec_st;
+	bus_space_handle_t ec_sh;
+	bus_space_handle_t ec_sys_sh;
+	bus_space_handle_t ec_system_sh;
+	struct rman ec_irq_rman;
+	struct rman ec_mem_rman;
+};
+
+struct econa_ivar {
+	struct resource_list resources;
+};
+
+void	power_on_network_interface	(void);
+unsigned int	get_tclk	(void);
+
+
+#endif


Property changes on: trunk/sys/arm/cavium/cns11xx/econa_var.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/cavium/cns11xx/ehci_ebus.c
===================================================================
--- trunk/sys/arm/cavium/cns11xx/ehci_ebus.c	                        (rev 0)
+++ trunk/sys/arm/cavium/cns11xx/ehci_ebus.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,249 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (C) 2009 Yohanes Nugroho <yohanes at gmail.com>
+ * based on ehci_mbus.c
+ * Copyright (C) 2008 MARVELL INTERNATIONAL LTD.
+ * 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.
+ * 3. Neither the name of MARVELL nor the names of contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY 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 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: stable/10/sys/arm/cavium/cns11xx/ehci_ebus.c 308402 2016-11-07 09:19:04Z hselasky $");
+
+#include "opt_bus.h"
+
+#include <machine/resource.h>
+
+#include <sys/stdint.h>
+#include <sys/stddef.h>
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/types.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/bus.h>
+#include <sys/module.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/condvar.h>
+#include <sys/sysctl.h>
+#include <sys/sx.h>
+#include <sys/unistd.h>
+#include <sys/callout.h>
+#include <sys/malloc.h>
+#include <sys/priv.h>
+
+#include <sys/rman.h>
+
+#include <dev/usb/usb.h>
+#include <dev/usb/usbdi.h>
+
+#include <dev/usb/usb_core.h>
+#include <dev/usb/usb_busdma.h>
+#include <dev/usb/usb_process.h>
+#include <dev/usb/usb_util.h>
+
+#include <dev/usb/usb_controller.h>
+#include <dev/usb/usb_bus.h>
+#include <dev/usb/controller/ehci.h>
+#include <dev/usb/controller/ehcireg.h>
+
+
+static device_attach_t ehci_ebus_attach;
+static device_detach_t ehci_ebus_detach;
+
+static void *ih_err;
+
+#define	EHCI_HC_DEVSTR "CNS11XX USB EHCI"
+#define	USB_BRIDGE_INTR_MASK   0x214
+
+static int
+ehci_ebus_probe(device_t self)
+{
+
+	device_set_desc(self, EHCI_HC_DEVSTR);
+
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+ehci_ebus_attach(device_t self)
+{
+	ehci_softc_t *sc = device_get_softc(self);
+	bus_space_handle_t bsh;
+	int err;
+	int rid;
+
+	/* initialise some bus fields */
+	sc->sc_bus.parent = self;
+	sc->sc_bus.devices = sc->sc_devices;
+	sc->sc_bus.devices_max = EHCI_MAX_DEVICES;
+	sc->sc_bus.dma_bits = 32;
+
+	/* get all DMA memory */
+	if (usb_bus_mem_alloc_all(&sc->sc_bus,
+	    USB_GET_DMA_TAG(self), &ehci_iterate_hw_softc)) {
+		return (ENOMEM);
+	}
+
+	sc->sc_bus.usbrev = USB_REV_2_0;
+
+	rid = 0;
+	sc->sc_io_res = bus_alloc_resource_any(self, SYS_RES_MEMORY,
+	    &rid, RF_ACTIVE);
+	if (!sc->sc_io_res) {
+		device_printf(self, "Could not map memory\n");
+		goto error;
+	}
+	sc->sc_io_tag = rman_get_bustag(sc->sc_io_res);
+	bsh = rman_get_bushandle(sc->sc_io_res);
+
+	/*magic, undocumented initialization*/
+	bus_space_write_4((sc)->sc_io_tag, bsh, 0x04, 0x106);
+
+	bus_space_write_4((sc)->sc_io_tag, bsh, 0x40, (3 << 5)|0x2000);
+
+	DELAY(1000);
+
+	sc->sc_io_size =  4096;
+
+	if (bus_space_subregion(sc->sc_io_tag, bsh, 0x4000000,
+	    sc->sc_io_size, &sc->sc_io_hdl) != 0)
+		panic("%s: unable to subregion USB host registers",
+		    device_get_name(self));
+
+	rid = 0;
+	sc->sc_irq_res = bus_alloc_resource_any(self, SYS_RES_IRQ, &rid,
+	    RF_SHAREABLE | RF_ACTIVE);
+	if (sc->sc_irq_res == NULL) {
+		device_printf(self, "Could not allocate irq\n");
+		ehci_ebus_detach(self);
+		return (ENXIO);
+	}
+
+	sc->sc_bus.bdev = device_add_child(self, "usbus", -1);
+	if (!sc->sc_bus.bdev) {
+		device_printf(self, "Could not add USB device\n");
+		goto error;
+	}
+	device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
+	device_set_desc(sc->sc_bus.bdev, EHCI_HC_DEVSTR);
+
+	sprintf(sc->sc_vendor, "Cavium");
+
+	err = bus_setup_intr(self,sc->sc_irq_res,
+	    INTR_TYPE_BIO | INTR_MPSAFE, NULL,
+	    (driver_intr_t *)ehci_interrupt, sc,
+	    &sc->sc_intr_hdl);
+	if (err) {
+		device_printf(self, "Could not setup error irq, %d\n", err);
+		ih_err = NULL;
+		goto error;
+	}
+
+	err = ehci_init(sc);
+	if (!err) {
+		err = device_probe_and_attach(sc->sc_bus.bdev);
+	}
+	if (err) {
+		device_printf(self, "USB init failed err=%d\n", err);
+		goto error;
+	}
+	return (0);
+
+error:
+	ehci_ebus_detach(self);
+	return (ENXIO);
+}
+
+static int
+ehci_ebus_detach(device_t self)
+{
+	ehci_softc_t *sc = device_get_softc(self);
+	int err;
+
+	/* during module unload there are lots of children leftover */
+	device_delete_children(self);
+
+	/*
+	 * disable interrupts that might have been switched on in
+	 * ehci_ebus_attach()
+	 */
+	if (sc->sc_io_res) {
+		EWRITE4(sc, USB_BRIDGE_INTR_MASK, 0);
+	}
+	if (sc->sc_irq_res && sc->sc_intr_hdl) {
+		/*
+		 * only call ehci_detach() after ehci_init()
+		 */
+		ehci_detach(sc);
+
+		err = bus_teardown_intr(self, sc->sc_irq_res, sc->sc_intr_hdl);
+
+		if (err)
+			/* XXX or should we panic? */
+			device_printf(self, "Could not tear down irq, %d\n",
+			    err);
+		sc->sc_intr_hdl = NULL;
+	}
+	if (sc->sc_irq_res) {
+		bus_release_resource(self, SYS_RES_IRQ, 1, sc->sc_irq_res);
+		sc->sc_irq_res = NULL;
+	}
+	if (sc->sc_io_res) {
+		bus_release_resource(self, SYS_RES_MEMORY, 0,
+		    sc->sc_io_res);
+		sc->sc_io_res = NULL;
+	}
+	usb_bus_mem_free_all(&sc->sc_bus, &ehci_iterate_hw_softc);
+
+	return (0);
+}
+
+static device_method_t ehci_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe, ehci_ebus_probe),
+	DEVMETHOD(device_attach, ehci_ebus_attach),
+	DEVMETHOD(device_detach, ehci_ebus_detach),
+	DEVMETHOD(device_suspend, bus_generic_suspend),
+	DEVMETHOD(device_resume, bus_generic_resume),
+	DEVMETHOD(device_shutdown, bus_generic_shutdown),
+
+	DEVMETHOD_END
+};
+
+static driver_t ehci_driver = {
+	.name = "ehci",
+	.methods = ehci_methods,
+	.size = sizeof(ehci_softc_t),
+};
+
+static devclass_t ehci_devclass;
+
+DRIVER_MODULE(ehci, econaarm, ehci_driver, ehci_devclass, 0, 0);
+MODULE_DEPEND(ehci, usb, 1, 1, 1);


Property changes on: trunk/sys/arm/cavium/cns11xx/ehci_ebus.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/cavium/cns11xx/files.econa
===================================================================
--- trunk/sys/arm/cavium/cns11xx/files.econa	                        (rev 0)
+++ trunk/sys/arm/cavium/cns11xx/files.econa	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,14 @@
+# $FreeBSD: stable/10/sys/arm/cavium/cns11xx/files.econa 278727 2015-02-13 22:32:02Z ian $
+arm/arm/cpufunc_asm_fa526.S	standard
+arm/cavium/cns11xx/econa_machdep.c		standard
+arm/cavium/cns11xx/econa.c			standard
+arm/cavium/cns11xx/timer.c			standard
+arm/cavium/cns11xx/uart_bus_ec.c		optional	uart
+arm/cavium/cns11xx/uart_cpu_ec.c		optional	uart
+dev/uart/uart_dev_ns8250.c	optional	uart
+arm/arm/bus_space_base.c		standard
+arm/arm/bus_space_generic.c		standard
+arm/cavium/cns11xx/ehci_ebus.c	optional	ehci
+arm/cavium/cns11xx/ohci_ec.c	optional	ohci
+arm/cavium/cns11xx/if_ece.c		standard
+arm/cavium/cns11xx/cfi_bus_econa.c		optional	cfi


Property changes on: trunk/sys/arm/cavium/cns11xx/files.econa
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/cavium/cns11xx/if_ece.c
===================================================================
--- trunk/sys/arm/cavium/cns11xx/if_ece.c	                        (rev 0)
+++ trunk/sys/arm/cavium/cns11xx/if_ece.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,1948 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2009 Yohanes Nugroho <yohanes at gmail.com>
+ * 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 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 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: stable/10/sys/arm/cavium/cns11xx/if_ece.c 264219 2014-04-07 05:33:30Z rpaulo $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/mbuf.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/rman.h>
+#include <sys/socket.h>
+#include <sys/sockio.h>
+#include <sys/sysctl.h>
+#include <sys/taskqueue.h>
+
+#include <net/ethernet.h>
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <net/if_dl.h>
+#include <net/if_media.h>
+#include <net/if_types.h>
+#include <net/if_var.h>
+#include <net/if_vlan_var.h>
+
+#ifdef INET
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#endif
+
+#include <net/bpf.h>
+#include <net/bpfdesc.h>
+
+#include <dev/mii/mii.h>
+#include <dev/mii/miivar.h>
+
+#include <arm/cavium/cns11xx/if_ecereg.h>
+#include <arm/cavium/cns11xx/if_ecevar.h>
+#include <arm/cavium/cns11xx/econa_var.h>
+
+#include <machine/bus.h>
+#include <machine/intr.h>
+
+/* "device miibus" required.  See GENERIC if you get errors here. */
+#include "miibus_if.h"
+
+static uint8_t
+vlan0_mac[ETHER_ADDR_LEN] = {0x00, 0xaa, 0xbb, 0xcc, 0xdd, 0x19};
+
+/*
+ * Boot loader expects the hardware state to be the same when we
+ * restart the device (warm boot), so we need to save the initial
+ * config values.
+ */
+int initial_switch_config;
+int initial_cpu_config;
+int initial_port0_config;
+int initial_port1_config;
+
+static inline uint32_t
+read_4(struct ece_softc *sc, bus_size_t off)
+{
+
+	return (bus_read_4(sc->mem_res, off));
+}
+
+static inline void
+write_4(struct ece_softc *sc, bus_size_t off, uint32_t val)
+{
+
+	bus_write_4(sc->mem_res, off, val);
+}
+
+#define	ECE_LOCK(_sc)		mtx_lock(&(_sc)->sc_mtx)
+#define	ECE_UNLOCK(_sc)		mtx_unlock(&(_sc)->sc_mtx)
+#define	ECE_LOCK_INIT(_sc) \
+	mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->dev),	\
+		 MTX_NETWORK_LOCK, MTX_DEF)
+
+#define	ECE_TXLOCK(_sc)		mtx_lock(&(_sc)->sc_mtx_tx)
+#define	ECE_TXUNLOCK(_sc)		mtx_unlock(&(_sc)->sc_mtx_tx)
+#define	ECE_TXLOCK_INIT(_sc) \
+	mtx_init(&_sc->sc_mtx_tx, device_get_nameunit(_sc->dev),	\
+		 "ECE TX Lock", MTX_DEF)
+
+#define	ECE_CLEANUPLOCK(_sc)	mtx_lock(&(_sc)->sc_mtx_cleanup)
+#define	ECE_CLEANUPUNLOCK(_sc)	mtx_unlock(&(_sc)->sc_mtx_cleanup)
+#define	ECE_CLEANUPLOCK_INIT(_sc) \
+	mtx_init(&_sc->sc_mtx_cleanup, device_get_nameunit(_sc->dev),	\
+		 "ECE cleanup Lock", MTX_DEF)
+
+#define	ECE_RXLOCK(_sc)		mtx_lock(&(_sc)->sc_mtx_rx)
+#define	ECE_RXUNLOCK(_sc)		mtx_unlock(&(_sc)->sc_mtx_rx)
+#define	ECE_RXLOCK_INIT(_sc) \
+	mtx_init(&_sc->sc_mtx_rx, device_get_nameunit(_sc->dev),	\
+		 "ECE RX Lock", MTX_DEF)
+
+#define	ECE_LOCK_DESTROY(_sc)	mtx_destroy(&_sc->sc_mtx);
+#define	ECE_TXLOCK_DESTROY(_sc)	mtx_destroy(&_sc->sc_mtx_tx);
+#define	ECE_RXLOCK_DESTROY(_sc)	mtx_destroy(&_sc->sc_mtx_rx);
+#define	ECE_CLEANUPLOCK_DESTROY(_sc)	\
+	mtx_destroy(&_sc->sc_mtx_cleanup);
+
+#define	ECE_ASSERT_LOCKED(_sc)	mtx_assert(&_sc->sc_mtx, MA_OWNED);
+#define	ECE_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED);
+
+static devclass_t ece_devclass;
+
+/* ifnet entry points */
+
+static void	eceinit_locked(void *);
+static void	ecestart_locked(struct ifnet *);
+
+static void	eceinit(void *);
+static void	ecestart(struct ifnet *);
+static void	ecestop(struct ece_softc *);
+static int	eceioctl(struct ifnet * ifp, u_long, caddr_t);
+
+/* bus entry points */
+
+static int	ece_probe(device_t dev);
+static int	ece_attach(device_t dev);
+static int	ece_detach(device_t dev);
+static void	ece_intr(void *);
+static void	ece_intr_qf(void *);
+static void	ece_intr_status(void *xsc);
+
+/* helper routines */
+static int	ece_activate(device_t dev);
+static void	ece_deactivate(device_t dev);
+static int	ece_ifmedia_upd(struct ifnet *ifp);
+static void	ece_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr);
+static int	ece_get_mac(struct ece_softc *sc, u_char *eaddr);
+static void	ece_set_mac(struct ece_softc *sc, u_char *eaddr);
+static int	configure_cpu_port(struct ece_softc *sc);
+static int	configure_lan_port(struct ece_softc *sc, int phy_type);
+static void	set_pvid(struct ece_softc *sc, int port0, int port1, int cpu);
+static void	set_vlan_vid(struct ece_softc *sc, int vlan);
+static void	set_vlan_member(struct ece_softc *sc, int vlan);
+static void	set_vlan_tag(struct ece_softc *sc, int vlan);
+static int	hardware_init(struct ece_softc *sc);
+static void	ece_intr_rx_locked(struct ece_softc *sc, int count);
+
+static void	ece_free_desc_dma_tx(struct ece_softc *sc);
+static void	ece_free_desc_dma_rx(struct ece_softc *sc);
+
+static void	ece_intr_task(void *arg, int pending __unused);
+static void	ece_tx_task(void *arg, int pending __unused);
+static void	ece_cleanup_task(void *arg, int pending __unused);
+
+static int	ece_allocate_dma(struct ece_softc *sc);
+
+static void	ece_intr_tx(void *xsc);
+
+static void	clear_mac_entries(struct ece_softc *ec, int include_this_mac);
+
+static uint32_t read_mac_entry(struct ece_softc *ec,
+	    uint8_t *mac_result,
+	    int first);
+
+/*PHY related functions*/
+static inline int
+phy_read(struct ece_softc *sc, int phy, int reg)
+{
+	int val;
+	int ii;
+	int status;
+
+	write_4(sc, PHY_CONTROL, PHY_RW_OK);
+	write_4(sc, PHY_CONTROL,
+	    (PHY_ADDRESS(phy)|PHY_READ_COMMAND |
+	    PHY_REGISTER(reg)));
+
+	for (ii = 0; ii < 0x1000; ii++) {
+		status = read_4(sc, PHY_CONTROL);
+		if (status & PHY_RW_OK) {
+			/* Clear the rw_ok status, and clear other
+			 * bits value. */
+			write_4(sc, PHY_CONTROL, PHY_RW_OK);
+			val = PHY_GET_DATA(status);
+			return (val);
+		}
+	}
+	return (0);
+}
+
+static inline void
+phy_write(struct ece_softc *sc, int phy, int reg, int data)
+{
+	int ii;
+
+	write_4(sc, PHY_CONTROL, PHY_RW_OK);
+	write_4(sc, PHY_CONTROL,
+	    PHY_ADDRESS(phy) | PHY_REGISTER(reg) |
+	    PHY_WRITE_COMMAND | PHY_DATA(data));
+	for (ii = 0; ii < 0x1000; ii++) {
+		if (read_4(sc, PHY_CONTROL) & PHY_RW_OK) {
+			/* Clear the rw_ok status, and clear other
+			 * bits value.
+			 */
+			write_4(sc, PHY_CONTROL, PHY_RW_OK);
+			return;
+		}
+	}
+}
+
+static int get_phy_type(struct ece_softc *sc)
+{
+	uint16_t phy0_id = 0, phy1_id = 0;
+
+	/*
+	 * Use SMI (MDC/MDIO) to read Link Partner's PHY Identifier
+	 * Register 1.
+	 */
+	phy0_id = phy_read(sc, 0, 0x2);
+	phy1_id = phy_read(sc, 1, 0x2);
+
+	if ((phy0_id == 0xFFFF) && (phy1_id == 0x000F))
+		return (ASIX_GIGA_PHY);
+	else if ((phy0_id == 0x0243) && (phy1_id == 0x0243))
+		return (TWO_SINGLE_PHY);
+	else if ((phy0_id == 0xFFFF) && (phy1_id == 0x0007))
+		return (VSC8601_GIGA_PHY);
+	else if ((phy0_id == 0x0243) && (phy1_id == 0xFFFF))
+		return (IC_PLUS_PHY);
+
+	return (NOT_FOUND_PHY);
+}
+
+static int
+ece_probe(device_t dev)
+{
+
+	device_set_desc(dev, "Econa Ethernet Controller");
+	return (0);
+}
+
+
+static int
+ece_attach(device_t dev)
+{
+	struct ece_softc *sc;
+	struct ifnet *ifp = NULL;
+	struct sysctl_ctx_list *sctx;
+	struct sysctl_oid *soid;
+	u_char eaddr[ETHER_ADDR_LEN];
+	int err;
+	int i, rid;
+	uint32_t rnd;
+
+	err = 0;
+
+	sc = device_get_softc(dev);
+
+	sc->dev = dev;
+
+	rid = 0;
+	sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+		    RF_ACTIVE);
+	if (sc->mem_res == NULL)
+		goto out;
+
+	power_on_network_interface();
+
+	rid = 0;
+	sc->irq_res_status = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+	    RF_ACTIVE);
+	if (sc->irq_res_status == NULL)
+		goto out;
+
+	rid = 1;
+	/*TSTC: Fm-Switch-Tx-Complete*/
+	sc->irq_res_tx = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+	    RF_ACTIVE);
+	if (sc->irq_res_tx == NULL)
+		goto out;
+
+	rid = 2;
+	/*FSRC: Fm-Switch-Rx-Complete*/
+	sc->irq_res_rec = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+	    RF_ACTIVE);
+	if (sc->irq_res_rec == NULL)
+		goto out;
+
+	rid = 4;
+	/*FSQF: Fm-Switch-Queue-Full*/
+	sc->irq_res_qf = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+	    RF_ACTIVE);
+	if (sc->irq_res_qf == NULL)
+		goto out;
+
+	err = ece_activate(dev);
+	if (err)
+		goto out;
+
+	/* Sysctls */
+	sctx = device_get_sysctl_ctx(dev);
+	soid = device_get_sysctl_tree(dev);
+
+	ECE_LOCK_INIT(sc);
+
+	callout_init_mtx(&sc->tick_ch, &sc->sc_mtx, 0);
+
+	if ((err = ece_get_mac(sc, eaddr)) != 0) {
+		/* No MAC address configured. Generate the random one. */
+		if (bootverbose)
+			device_printf(dev,
+			    "Generating random ethernet address.\n");
+		rnd = arc4random();
+
+		/*from if_ae.c/if_ate.c*/
+		/*
+		 * Set OUI to convenient locally assigned address. 'b'
+		 * is 0x62, which has the locally assigned bit set, and
+		 * the broadcast/multicast bit clear.
+		 */
+		eaddr[0] = 'b';
+		eaddr[1] = 's';
+		eaddr[2] = 'd';
+		eaddr[3] = (rnd >> 16) & 0xff;
+		eaddr[4] = (rnd >> 8) & 0xff;
+		eaddr[5] = rnd & 0xff;
+
+		for (i = 0; i < ETHER_ADDR_LEN; i++)
+			eaddr[i] = vlan0_mac[i];
+	}
+	ece_set_mac(sc, eaddr);
+	sc->ifp = ifp = if_alloc(IFT_ETHER);
+	/* Only one PHY at address 0 in this device. */
+	err = mii_attach(dev, &sc->miibus, ifp, ece_ifmedia_upd,
+	    ece_ifmedia_sts, BMSR_DEFCAPMASK, 0, MII_OFFSET_ANY, 0);
+	if (err != 0) {
+		device_printf(dev, "attaching PHYs failed\n");
+		goto out;
+	}
+	ifp->if_softc = sc;
+	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
+	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+
+	ifp->if_capabilities = IFCAP_HWCSUM;
+
+	ifp->if_hwassist = (CSUM_IP | CSUM_TCP | CSUM_UDP);
+	ifp->if_capenable = ifp->if_capabilities;
+	ifp->if_start = ecestart;
+	ifp->if_ioctl = eceioctl;
+	ifp->if_init = eceinit;
+	ifp->if_snd.ifq_drv_maxlen = ECE_MAX_TX_BUFFERS - 1;
+	IFQ_SET_MAXLEN(&ifp->if_snd, ECE_MAX_TX_BUFFERS - 1);
+	IFQ_SET_READY(&ifp->if_snd);
+
+	/* Create local taskq. */
+
+	TASK_INIT(&sc->sc_intr_task, 0, ece_intr_task, sc);
+	TASK_INIT(&sc->sc_tx_task, 1, ece_tx_task, ifp);
+	TASK_INIT(&sc->sc_cleanup_task, 2, ece_cleanup_task, sc);
+	sc->sc_tq = taskqueue_create_fast("ece_taskq", M_WAITOK,
+	    taskqueue_thread_enqueue,
+	    &sc->sc_tq);
+	if (sc->sc_tq == NULL) {
+		device_printf(sc->dev, "could not create taskqueue\n");
+		goto out;
+	}
+
+	ether_ifattach(ifp, eaddr);
+
+	/*
+	 * Activate interrupts
+	 */
+	err = bus_setup_intr(dev, sc->irq_res_rec, INTR_TYPE_NET | INTR_MPSAFE,
+	    NULL, ece_intr, sc, &sc->intrhand);
+	if (err) {
+		ether_ifdetach(ifp);
+		ECE_LOCK_DESTROY(sc);
+		goto out;
+	}
+
+	err = bus_setup_intr(dev, sc->irq_res_status,
+	    INTR_TYPE_NET | INTR_MPSAFE,
+	    NULL, ece_intr_status, sc, &sc->intrhand_status);
+	if (err) {
+		ether_ifdetach(ifp);
+		ECE_LOCK_DESTROY(sc);
+		goto out;
+	}
+
+	err = bus_setup_intr(dev, sc->irq_res_qf, INTR_TYPE_NET | INTR_MPSAFE,
+	    NULL,ece_intr_qf, sc, &sc->intrhand_qf);
+
+	if (err) {
+		ether_ifdetach(ifp);
+		ECE_LOCK_DESTROY(sc);
+		goto out;
+	}
+
+	err = bus_setup_intr(dev, sc->irq_res_tx, INTR_TYPE_NET | INTR_MPSAFE,
+	    NULL, ece_intr_tx, sc, &sc->intrhand_tx);
+
+	if (err) {
+		ether_ifdetach(ifp);
+		ECE_LOCK_DESTROY(sc);
+		goto out;
+	}
+
+	ECE_TXLOCK_INIT(sc);
+	ECE_RXLOCK_INIT(sc);
+	ECE_CLEANUPLOCK_INIT(sc);
+
+	/* Enable all interrupt sources. */
+	write_4(sc, INTERRUPT_MASK, 0x00000000);
+
+	/* Enable port 0. */
+	write_4(sc, PORT_0_CONFIG, read_4(sc, PORT_0_CONFIG) & ~(PORT_DISABLE));
+
+	taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, "%s taskq",
+	    device_get_nameunit(sc->dev));
+
+out:
+	if (err)
+		ece_deactivate(dev);
+	if (err && ifp)
+		if_free(ifp);
+	return (err);
+}
+
+static int
+ece_detach(device_t dev)
+{
+	struct ece_softc *sc = device_get_softc(dev);
+	struct ifnet *ifp = sc->ifp;
+
+	ecestop(sc);
+	if (ifp != NULL) {
+		ether_ifdetach(ifp);
+		if_free(ifp);
+	}
+	ece_deactivate(dev);
+	return (0);
+}
+
+static void
+ece_getaddr(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
+{
+	u_int32_t *paddr;
+	KASSERT(nsegs == 1, ("wrong number of segments, should be 1"));
+	paddr = arg;
+	*paddr = segs->ds_addr;
+}
+
+static int
+ece_alloc_desc_dma_tx(struct ece_softc *sc)
+{
+	int i;
+	int error;
+
+	/* Allocate a busdma tag and DMA safe memory for TX/RX descriptors. */
+	error = bus_dma_tag_create(sc->sc_parent_tag,	/* parent */
+	    16, 0, /* alignment, boundary */
+	    BUS_SPACE_MAXADDR_32BIT,	/* lowaddr */
+	    BUS_SPACE_MAXADDR,	/* highaddr */
+	    NULL, NULL,	/* filtfunc, filtfuncarg */
+	    sizeof(eth_tx_desc_t)*ECE_MAX_TX_BUFFERS, /* max size */
+	    1, /*nsegments */
+	    sizeof(eth_tx_desc_t)*ECE_MAX_TX_BUFFERS,
+	    0, /* flags */
+	    NULL, NULL,	/* lockfunc, lockfuncarg */
+	    &sc->dmatag_data_tx); /* dmat */
+
+	/* Allocate memory for TX ring. */
+	error = bus_dmamem_alloc(sc->dmatag_data_tx,
+	    (void**)&(sc->desc_tx),
+	    BUS_DMA_NOWAIT | BUS_DMA_ZERO |
+	    BUS_DMA_COHERENT,
+	    &(sc->dmamap_ring_tx));
+
+	if (error) {
+		if_printf(sc->ifp, "failed to allocate DMA memory\n");
+		bus_dma_tag_destroy(sc->dmatag_data_tx);
+		sc->dmatag_data_tx = 0;
+		return (ENXIO);
+	}
+
+	/* Load Ring DMA. */
+	error = bus_dmamap_load(sc->dmatag_data_tx, sc->dmamap_ring_tx,
+	    sc->desc_tx,
+	    sizeof(eth_tx_desc_t)*ECE_MAX_TX_BUFFERS,
+	    ece_getaddr,
+	    &(sc->ring_paddr_tx), BUS_DMA_NOWAIT);
+
+	if (error) {
+		if_printf(sc->ifp, "can't load descriptor\n");
+		bus_dmamem_free(sc->dmatag_data_tx, sc->desc_tx,
+		    sc->dmamap_ring_tx);
+		sc->desc_tx = NULL;
+		bus_dma_tag_destroy(sc->dmatag_data_tx);
+		sc->dmatag_data_tx = 0;
+		return (ENXIO);
+	}
+
+	/* Allocate a busdma tag for mbufs. Alignment is 2 bytes */
+	error = bus_dma_tag_create(sc->sc_parent_tag,	/* parent */
+	    1, 0,			/* alignment, boundary */
+	    BUS_SPACE_MAXADDR_32BIT,	/* lowaddr */
+	    BUS_SPACE_MAXADDR,		/* highaddr */
+	    NULL, NULL,		/* filtfunc, filtfuncarg */
+	   MCLBYTES*MAX_FRAGMENT,	/* maxsize */
+	   MAX_FRAGMENT,		 /* nsegments */
+	    MCLBYTES, 0,		/* maxsegsz, flags */
+	    NULL, NULL,		/* lockfunc, lockfuncarg */
+	    &sc->dmatag_ring_tx);	/* dmat */
+
+	if (error) {
+		if_printf(sc->ifp, "failed to create busdma tag for mbufs\n");
+		return (ENXIO);
+	}
+
+	for (i = 0; i < ECE_MAX_TX_BUFFERS; i++) {
+		/* Create dma map for each descriptor. */
+		error = bus_dmamap_create(sc->dmatag_ring_tx, 0,
+		    &(sc->tx_desc[i].dmamap));
+		if (error) {
+			if_printf(sc->ifp, "failed to create map for mbuf\n");
+			return (ENXIO);
+		}
+	}
+	return (0);
+}
+
+static void
+ece_free_desc_dma_tx(struct ece_softc *sc)
+{
+	int i;
+
+	for (i = 0; i < ECE_MAX_TX_BUFFERS; i++) {
+		if (sc->tx_desc[i].buff) {
+			m_freem(sc->tx_desc[i].buff);
+			sc->tx_desc[i].buff= 0;
+		}
+	}
+
+	if (sc->dmamap_ring_tx) {
+		bus_dmamap_unload(sc->dmatag_data_tx, sc->dmamap_ring_tx);
+		if (sc->desc_tx) {
+			bus_dmamem_free(sc->dmatag_data_tx,
+			    sc->desc_tx, sc->dmamap_ring_tx);
+		}
+		sc->dmamap_ring_tx = 0;
+	}
+
+	if (sc->dmatag_data_tx) {
+		bus_dma_tag_destroy(sc->dmatag_data_tx);
+		sc->dmatag_data_tx = 0;
+	}
+
+	if (sc->dmatag_ring_tx) {
+		for (i = 0; i<ECE_MAX_TX_BUFFERS; i++) {
+			bus_dmamap_destroy(sc->dmatag_ring_tx,
+			    sc->tx_desc[i].dmamap);
+			sc->tx_desc[i].dmamap = 0;
+		}
+		bus_dma_tag_destroy(sc->dmatag_ring_tx);
+		sc->dmatag_ring_tx = 0;
+	}
+}
+
+static int
+ece_alloc_desc_dma_rx(struct ece_softc *sc)
+{
+	int error;
+	int i;
+
+	/* Allocate a busdma tag and DMA safe memory for RX descriptors. */
+	error = bus_dma_tag_create(sc->sc_parent_tag,	/* parent */
+	    16, 0,			/* alignment, boundary */
+	    BUS_SPACE_MAXADDR_32BIT,	/* lowaddr */
+	    BUS_SPACE_MAXADDR,		/* highaddr */
+	    NULL, NULL,		/* filtfunc, filtfuncarg */
+	    /* maxsize, nsegments */
+	    sizeof(eth_rx_desc_t)*ECE_MAX_RX_BUFFERS, 1,
+	    /* maxsegsz, flags */
+	    sizeof(eth_rx_desc_t)*ECE_MAX_RX_BUFFERS, 0,
+	    NULL, NULL,		/* lockfunc, lockfuncarg */
+	    &sc->dmatag_data_rx);	/* dmat */
+
+	/* Allocate RX ring. */
+	error = bus_dmamem_alloc(sc->dmatag_data_rx,
+	    (void**)&(sc->desc_rx),
+	    BUS_DMA_NOWAIT | BUS_DMA_ZERO |
+	    BUS_DMA_COHERENT,
+	    &(sc->dmamap_ring_rx));
+
+	if (error) {
+		if_printf(sc->ifp, "failed to allocate DMA memory\n");
+		return (ENXIO);
+	}
+
+	/* Load dmamap. */
+	error = bus_dmamap_load(sc->dmatag_data_rx, sc->dmamap_ring_rx,
+	    sc->desc_rx,
+	    sizeof(eth_rx_desc_t)*ECE_MAX_RX_BUFFERS,
+	    ece_getaddr,
+	    &(sc->ring_paddr_rx), BUS_DMA_NOWAIT);
+
+	if (error) {
+		if_printf(sc->ifp, "can't load descriptor\n");
+		bus_dmamem_free(sc->dmatag_data_rx, sc->desc_rx,
+		    sc->dmamap_ring_rx);
+		bus_dma_tag_destroy(sc->dmatag_data_rx);
+		sc->desc_rx = NULL;
+		return (ENXIO);
+	}
+
+	/* Allocate a busdma tag for mbufs. */
+	error = bus_dma_tag_create(sc->sc_parent_tag,/* parent */
+	    16, 0,			/* alignment, boundary */
+	    BUS_SPACE_MAXADDR_32BIT,	/* lowaddr */
+	    BUS_SPACE_MAXADDR,		/* highaddr */
+	    NULL, NULL,		/* filtfunc, filtfuncarg */
+	    MCLBYTES, 1,		/* maxsize, nsegments */
+	    MCLBYTES, 0,		/* maxsegsz, flags */
+	    NULL, NULL,		/* lockfunc, lockfuncarg */
+	    &sc->dmatag_ring_rx);	/* dmat */
+
+	if (error) {
+		if_printf(sc->ifp, "failed to create busdma tag for mbufs\n");
+		return (ENXIO);
+	}
+
+	for (i = 0; i<ECE_MAX_RX_BUFFERS; i++) {
+		error = bus_dmamap_create(sc->dmatag_ring_rx, 0,
+		    &sc->rx_desc[i].dmamap);
+		if (error) {
+			if_printf(sc->ifp, "failed to create map for mbuf\n");
+			return (ENXIO);
+		}
+	}
+
+	error = bus_dmamap_create(sc->dmatag_ring_rx, 0, &sc->rx_sparemap);
+	if (error) {
+		if_printf(sc->ifp, "failed to create spare map\n");
+		return (ENXIO);
+	}
+
+	return (0);
+}
+
+static void
+ece_free_desc_dma_rx(struct ece_softc *sc)
+{
+	int i;
+
+	for (i = 0; i < ECE_MAX_RX_BUFFERS; i++) {
+		if (sc->rx_desc[i].buff) {
+			m_freem(sc->rx_desc[i].buff);
+			sc->rx_desc[i].buff= 0;
+		}
+	}
+
+	if (sc->dmatag_data_rx) {
+		bus_dmamap_unload(sc->dmatag_data_rx, sc->dmamap_ring_rx);
+		bus_dmamem_free(sc->dmatag_data_rx, sc->desc_rx,
+		    sc->dmamap_ring_rx);
+		bus_dma_tag_destroy(sc->dmatag_data_rx);
+		sc->dmatag_data_rx = 0;
+		sc->dmamap_ring_rx = 0;
+		sc->desc_rx = 0;
+	}
+
+	if (sc->dmatag_ring_rx) {
+		for (i = 0; i < ECE_MAX_RX_BUFFERS; i++)
+			bus_dmamap_destroy(sc->dmatag_ring_rx,
+			    sc->rx_desc[i].dmamap);
+		bus_dmamap_destroy(sc->dmatag_ring_rx, sc->rx_sparemap);
+		bus_dma_tag_destroy(sc->dmatag_ring_rx);
+		sc->dmatag_ring_rx = 0;
+	}
+}
+
+static int
+ece_new_rxbuf(struct ece_softc *sc, struct rx_desc_info* descinfo)
+{
+	struct mbuf *new_mbuf;
+	bus_dma_segment_t seg[1];
+	bus_dmamap_t map;
+	int error;
+	int nsegs;
+	bus_dma_tag_t tag;
+
+	tag = sc->dmatag_ring_rx;
+
+	new_mbuf = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
+
+	if (new_mbuf == NULL)
+		return (ENOBUFS);
+
+	new_mbuf->m_len = new_mbuf->m_pkthdr.len = MCLBYTES;
+
+	error = bus_dmamap_load_mbuf_sg(tag, sc->rx_sparemap, new_mbuf,
+	    seg, &nsegs, BUS_DMA_NOWAIT);
+
+	KASSERT(nsegs == 1, ("Too many segments returned!"));
+
+	if (nsegs != 1 || error) {
+		m_free(new_mbuf);
+		return (ENOBUFS);
+	}
+
+	if (descinfo->buff != NULL) {
+		bus_dmamap_sync(tag, descinfo->dmamap, BUS_DMASYNC_POSTREAD);
+		bus_dmamap_unload(tag, descinfo->dmamap);
+	}
+
+	map = descinfo->dmamap;
+	descinfo->dmamap = sc->rx_sparemap;
+	sc->rx_sparemap = map;
+
+	bus_dmamap_sync(tag, descinfo->dmamap, BUS_DMASYNC_PREREAD);
+
+	descinfo->buff = new_mbuf;
+	descinfo->desc->data_ptr = seg->ds_addr;
+	descinfo->desc->length = seg->ds_len - 2;
+
+	return (0);
+}
+
+static int
+ece_allocate_dma(struct ece_softc *sc)
+{
+	eth_tx_desc_t *desctx;
+	eth_rx_desc_t *descrx;
+	int i;
+	int error;
+
+	/* Create parent tag for tx and rx */
+	error = bus_dma_tag_create(
+	    bus_get_dma_tag(sc->dev),/* parent */
+	    1, 0,		/* alignment, boundary */
+	    BUS_SPACE_MAXADDR,	/* lowaddr */
+	    BUS_SPACE_MAXADDR,	/* highaddr */
+	    NULL, NULL,	/* filter, filterarg */
+	    BUS_SPACE_MAXSIZE_32BIT, 0,/* maxsize, nsegments */
+	    BUS_SPACE_MAXSIZE_32BIT,	/* maxsegsize */
+	    0,			/* flags */
+	    NULL, NULL,	/* lockfunc, lockarg */
+	    &sc->sc_parent_tag);
+
+	ece_alloc_desc_dma_tx(sc);
+
+	for (i = 0; i < ECE_MAX_TX_BUFFERS; i++) {
+		desctx = (eth_tx_desc_t *)(&sc->desc_tx[i]);
+		memset(desctx, 0, sizeof(eth_tx_desc_t));
+		desctx->length = MAX_PACKET_LEN;
+		desctx->cown = 1;
+		if (i == ECE_MAX_TX_BUFFERS - 1)
+			desctx->eor = 1;
+	}
+
+	ece_alloc_desc_dma_rx(sc);
+
+	for (i = 0; i < ECE_MAX_RX_BUFFERS; i++) {
+		descrx = &(sc->desc_rx[i]);
+		memset(descrx, 0, sizeof(eth_rx_desc_t));
+		sc->rx_desc[i].desc = descrx;
+		sc->rx_desc[i].buff = 0;
+		ece_new_rxbuf(sc, &(sc->rx_desc[i]));
+
+		if (i == ECE_MAX_RX_BUFFERS - 1)
+			descrx->eor = 1;
+	}
+	sc->tx_prod = 0;
+	sc->tx_cons = 0;
+	sc->last_rx = 0;
+	sc->desc_curr_tx = 0;
+
+	return (0);
+}
+
+static int
+ece_activate(device_t dev)
+{
+	struct ece_softc *sc;
+	int err;
+	uint32_t mac_port_config;
+	struct ifnet *ifp;
+
+	sc = device_get_softc(dev);
+	ifp = sc->ifp;
+
+	initial_switch_config = read_4(sc, SWITCH_CONFIG);
+	initial_cpu_config = read_4(sc, CPU_PORT_CONFIG);
+	initial_port0_config = read_4(sc, MAC_PORT_0_CONFIG);
+	initial_port1_config = read_4(sc, MAC_PORT_1_CONFIG);
+
+	/* Disable Port 0 */
+	mac_port_config = read_4(sc, MAC_PORT_0_CONFIG);
+	mac_port_config |= (PORT_DISABLE);
+	write_4(sc, MAC_PORT_0_CONFIG, mac_port_config);
+
+	/* Disable Port 1 */
+	mac_port_config = read_4(sc, MAC_PORT_1_CONFIG);
+	mac_port_config |= (PORT_DISABLE);
+	write_4(sc, MAC_PORT_1_CONFIG, mac_port_config);
+
+	err = ece_allocate_dma(sc);
+	if (err) {
+		if_printf(sc->ifp, "failed allocating dma\n");
+		goto out;
+	}
+
+	write_4(sc, TS_DESCRIPTOR_POINTER, sc->ring_paddr_tx);
+	write_4(sc, TS_DESCRIPTOR_BASE_ADDR, sc->ring_paddr_tx);
+
+	write_4(sc, FS_DESCRIPTOR_POINTER, sc->ring_paddr_rx);
+	write_4(sc, FS_DESCRIPTOR_BASE_ADDR, sc->ring_paddr_rx);
+
+	write_4(sc, FS_DMA_CONTROL, 1);
+
+	return (0);
+out:
+	return (ENXIO);
+
+}
+
+static void
+ece_deactivate(device_t dev)
+{
+	struct ece_softc *sc;
+
+	sc = device_get_softc(dev);
+
+	if (sc->intrhand)
+		bus_teardown_intr(dev, sc->irq_res_rec, sc->intrhand);
+
+	sc->intrhand = 0;
+
+	if (sc->intrhand_qf)
+		bus_teardown_intr(dev, sc->irq_res_qf, sc->intrhand_qf);
+
+	sc->intrhand_qf = 0;
+
+	bus_generic_detach(sc->dev);
+	if (sc->miibus)
+		device_delete_child(sc->dev, sc->miibus);
+	if (sc->mem_res)
+		bus_release_resource(dev, SYS_RES_IOPORT,
+		    rman_get_rid(sc->mem_res), sc->mem_res);
+	sc->mem_res = 0;
+
+	if (sc->irq_res_rec)
+		bus_release_resource(dev, SYS_RES_IRQ,
+		    rman_get_rid(sc->irq_res_rec), sc->irq_res_rec);
+
+	if (sc->irq_res_qf)
+		bus_release_resource(dev, SYS_RES_IRQ,
+		    rman_get_rid(sc->irq_res_qf), sc->irq_res_qf);
+
+	if (sc->irq_res_qf)
+		bus_release_resource(dev, SYS_RES_IRQ,
+		    rman_get_rid(sc->irq_res_status), sc->irq_res_status);
+
+	sc->irq_res_rec = 0;
+	sc->irq_res_qf = 0;
+	sc->irq_res_status = 0;
+	ECE_TXLOCK_DESTROY(sc);
+	ECE_RXLOCK_DESTROY(sc);
+
+	ece_free_desc_dma_tx(sc);
+	ece_free_desc_dma_rx(sc);
+
+	return;
+}
+
+/*
+ * Change media according to request.
+ */
+static int
+ece_ifmedia_upd(struct ifnet *ifp)
+{
+	struct ece_softc *sc = ifp->if_softc;
+	struct mii_data *mii;
+	int error;
+
+	mii = device_get_softc(sc->miibus);
+	ECE_LOCK(sc);
+	error = mii_mediachg(mii);
+	ECE_UNLOCK(sc);
+	return (error);
+}
+
+/*
+ * Notify the world which media we're using.
+ */
+static void
+ece_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
+{
+	struct ece_softc *sc = ifp->if_softc;
+	struct mii_data *mii;
+
+	mii = device_get_softc(sc->miibus);
+	ECE_LOCK(sc);
+	mii_pollstat(mii);
+	ifmr->ifm_active = mii->mii_media_active;
+	ifmr->ifm_status = mii->mii_media_status;
+	ECE_UNLOCK(sc);
+}
+
+static void
+ece_tick(void *xsc)
+{
+	struct ece_softc *sc = xsc;
+	struct mii_data *mii;
+	int active;
+
+	mii = device_get_softc(sc->miibus);
+	active = mii->mii_media_active;
+	mii_tick(mii);
+
+	/*
+	 * Schedule another timeout one second from now.
+	 */
+	callout_reset(&sc->tick_ch, hz, ece_tick, sc);
+}
+
+static uint32_t
+read_mac_entry(struct ece_softc *ec,
+    uint8_t *mac_result,
+    int first)
+{
+	uint32_t ii;
+	struct arl_table_entry_t entry;
+	uint32_t *entry_val;
+	write_4(ec, ARL_TABLE_ACCESS_CONTROL_0, 0);
+	write_4(ec, ARL_TABLE_ACCESS_CONTROL_1, 0);
+	write_4(ec, ARL_TABLE_ACCESS_CONTROL_2, 0);
+	if (first)
+		write_4(ec, ARL_TABLE_ACCESS_CONTROL_0, 0x1);
+	else
+		write_4(ec, ARL_TABLE_ACCESS_CONTROL_0, 0x2);
+
+	for (ii = 0; ii < 0x1000; ii++)
+		if (read_4(ec, ARL_TABLE_ACCESS_CONTROL_1) & (0x1))
+			break;
+
+	entry_val = (uint32_t*) (&entry);
+	entry_val[0] = read_4(ec, ARL_TABLE_ACCESS_CONTROL_1);
+	entry_val[1] = read_4(ec, ARL_TABLE_ACCESS_CONTROL_2);
+
+	if (mac_result)
+		memcpy(mac_result, entry.mac_addr, ETHER_ADDR_LEN);
+
+	return (entry.table_end);
+}
+
+static uint32_t
+write_arl_table_entry(struct ece_softc *ec,
+    uint32_t filter,
+    uint32_t vlan_mac,
+    uint32_t vlan_gid,
+    uint32_t age_field,
+    uint32_t port_map,
+    const uint8_t *mac_addr)
+{
+	uint32_t ii;
+	uint32_t *entry_val;
+	struct arl_table_entry_t entry;
+
+	memset(&entry, 0, sizeof(entry));
+
+	entry.filter = filter;
+	entry.vlan_mac = vlan_mac;
+	entry.vlan_gid = vlan_gid;
+	entry.age_field = age_field;
+	entry.port_map = port_map;
+	memcpy(entry.mac_addr, mac_addr, ETHER_ADDR_LEN);
+
+	entry_val = (uint32_t*) (&entry);
+
+	write_4(ec, ARL_TABLE_ACCESS_CONTROL_0, 0);
+	write_4(ec, ARL_TABLE_ACCESS_CONTROL_1, 0);
+	write_4(ec, ARL_TABLE_ACCESS_CONTROL_2, 0);
+
+	write_4(ec, ARL_TABLE_ACCESS_CONTROL_1, entry_val[0]);
+	write_4(ec, ARL_TABLE_ACCESS_CONTROL_2, entry_val[1]);
+
+	write_4(ec, ARL_TABLE_ACCESS_CONTROL_0, ARL_WRITE_COMMAND);
+
+	for (ii = 0; ii < 0x1000; ii++)
+		if (read_4(ec, ARL_TABLE_ACCESS_CONTROL_1) &
+		    ARL_COMMAND_COMPLETE)
+			return (1); /* Write OK. */
+
+	/* Write failed. */
+	return (0);
+}
+
+static void
+remove_mac_entry(struct ece_softc *sc,
+    uint8_t *mac)
+{
+
+	/* Invalid age_field mean erase this entry. */
+	write_arl_table_entry(sc, 0, 1, VLAN0_GROUP_ID,
+	    INVALID_ENTRY, VLAN0_GROUP,
+	    mac);
+}
+
+static void
+add_mac_entry(struct ece_softc *sc,
+    uint8_t *mac)
+{
+
+	write_arl_table_entry(sc, 0, 1, VLAN0_GROUP_ID,
+	    NEW_ENTRY, VLAN0_GROUP,
+	    mac);
+}
+
+/**
+ * The behavior of ARL table reading and deletion is not well defined
+ * in the documentation. To be safe, all mac addresses are put to a
+ * list, then deleted.
+ *
+ */
+static void
+clear_mac_entries(struct ece_softc *ec, int include_this_mac)
+{
+	int table_end;
+	struct mac_list * temp;
+	struct mac_list * mac_list_header;
+	struct mac_list * current;
+	char mac[ETHER_ADDR_LEN];
+
+	current = 0;
+	mac_list_header = 0;
+
+	table_end = read_mac_entry(ec, mac, 1);
+	while (!table_end) {
+		if (!include_this_mac &&
+		    memcmp(mac, vlan0_mac, ETHER_ADDR_LEN) == 0) {
+			/* Read next entry. */
+			table_end = read_mac_entry(ec, mac, 0);
+			continue;
+		}
+
+		temp = (struct mac_list*)malloc(sizeof(struct mac_list),
+		    M_DEVBUF,
+		    M_NOWAIT | M_ZERO);
+		memcpy(temp->mac_addr, mac, ETHER_ADDR_LEN);
+		temp->next = 0;
+		if (mac_list_header) {
+			current->next = temp;
+			current = temp;
+		} else {
+			mac_list_header = temp;
+			current = temp;
+		}
+		/* Read next Entry */
+		table_end = read_mac_entry(ec, mac, 0);
+	}
+
+	current = mac_list_header;
+
+	while (current) {
+		remove_mac_entry(ec, current->mac_addr);
+		temp = current;
+		current = current->next;
+		free(temp, M_DEVBUF);
+	}
+}
+
+static int
+configure_lan_port(struct ece_softc *sc, int phy_type)
+{
+	uint32_t sw_config;
+	uint32_t mac_port_config;
+
+	/*
+	 * Configure switch
+	 */
+	sw_config = read_4(sc, SWITCH_CONFIG);
+	/* Enable fast aging. */
+	sw_config |= FAST_AGING;
+	/* Enable IVL learning. */
+	sw_config |= IVL_LEARNING;
+	/* Disable hardware NAT. */
+	sw_config &= ~(HARDWARE_NAT);
+
+	sw_config |= SKIP_L2_LOOKUP_PORT_0 | SKIP_L2_LOOKUP_PORT_1| NIC_MODE;
+
+	write_4(sc, SWITCH_CONFIG, sw_config);
+
+	sw_config = read_4(sc, SWITCH_CONFIG);
+
+	mac_port_config = read_4(sc, MAC_PORT_0_CONFIG);
+
+	if (!(mac_port_config & 0x1) || (mac_port_config & 0x2))
+		if_printf(sc->ifp, "Link Down\n");
+	else
+		write_4(sc, MAC_PORT_0_CONFIG, mac_port_config);
+	return (0);
+}
+
+static void
+set_pvid(struct ece_softc *sc, int port0, int port1, int cpu)
+{
+	uint32_t val;
+	val = read_4(sc, VLAN_PORT_PVID) & (~(0x7 << 0));
+	write_4(sc, VLAN_PORT_PVID, val);
+	val = read_4(sc, VLAN_PORT_PVID) | ((port0) & 0x07);
+	write_4(sc, VLAN_PORT_PVID, val);
+	val = read_4(sc, VLAN_PORT_PVID) & (~(0x7 << 4));
+	write_4(sc, VLAN_PORT_PVID, val);
+	val = read_4(sc, VLAN_PORT_PVID) | (((port1) & 0x07) << 4);
+	write_4(sc, VLAN_PORT_PVID, val);
+
+	val = read_4(sc, VLAN_PORT_PVID) & (~(0x7 << 8));
+	write_4(sc, VLAN_PORT_PVID, val);
+	val = read_4(sc, VLAN_PORT_PVID) | (((cpu) & 0x07) << 8);
+	write_4(sc, VLAN_PORT_PVID, val);
+
+}
+
+/* VLAN related functions */
+static void
+set_vlan_vid(struct ece_softc *sc, int vlan)
+{
+	const uint32_t regs[] = {
+	    VLAN_VID_0_1,
+	    VLAN_VID_0_1,
+	    VLAN_VID_2_3,
+	    VLAN_VID_2_3,
+	    VLAN_VID_4_5,
+	    VLAN_VID_4_5,
+	    VLAN_VID_6_7,
+	    VLAN_VID_6_7
+	};
+
+	const int vids[] = {
+	    VLAN0_VID,
+	    VLAN1_VID,
+	    VLAN2_VID,
+	    VLAN3_VID,
+	    VLAN4_VID,
+	    VLAN5_VID,
+	    VLAN6_VID,
+	    VLAN7_VID
+	};
+
+	uint32_t val;
+	uint32_t reg;
+	int vid;
+
+	reg = regs[vlan];
+	vid = vids[vlan];
+
+	if (vlan & 1) {
+		val = read_4(sc, reg);
+		write_4(sc, reg, val & (~(0xFFF << 0)));
+		val = read_4(sc, reg);
+		write_4(sc, reg, val|((vid & 0xFFF) << 0));
+	} else {
+		val = read_4(sc, reg);
+		write_4(sc, reg, val & (~(0xFFF << 12)));
+		val = read_4(sc, reg);
+		write_4(sc, reg, val|((vid & 0xFFF) << 12));
+	}
+}
+
+static void
+set_vlan_member(struct ece_softc *sc, int vlan)
+{
+	unsigned char shift;
+	uint32_t val;
+	int group;
+	const int groups[] = {
+	    VLAN0_GROUP,
+	    VLAN1_GROUP,
+	    VLAN2_GROUP,
+	    VLAN3_GROUP,
+	    VLAN4_GROUP,
+	    VLAN5_GROUP,
+	    VLAN6_GROUP,
+	    VLAN7_GROUP
+	};
+
+	group = groups[vlan];
+
+	shift = vlan*3;
+	val = read_4(sc, VLAN_MEMBER_PORT_MAP) & (~(0x7 << shift));
+	write_4(sc, VLAN_MEMBER_PORT_MAP, val);
+	val = read_4(sc, VLAN_MEMBER_PORT_MAP);
+	write_4(sc, VLAN_MEMBER_PORT_MAP, val | ((group & 0x7) << shift));
+}
+
+static void
+set_vlan_tag(struct ece_softc *sc, int vlan)
+{
+	unsigned char shift;
+	uint32_t val;
+
+	int tag = 0;
+
+	shift = vlan*3;
+	val = read_4(sc, VLAN_TAG_PORT_MAP) & (~(0x7 << shift));
+	write_4(sc, VLAN_TAG_PORT_MAP, val);
+	val = read_4(sc, VLAN_TAG_PORT_MAP);
+	write_4(sc, VLAN_TAG_PORT_MAP, val | ((tag & 0x7) << shift));
+}
+
+static int
+configure_cpu_port(struct ece_softc *sc)
+{
+	uint32_t cpu_port_config;
+	int i;
+
+	cpu_port_config = read_4(sc, CPU_PORT_CONFIG);
+	/* SA learning Disable */
+	cpu_port_config |= (SA_LEARNING_DISABLE);
+	/* set data offset + 2 */
+	cpu_port_config &= ~(1U << 31);
+
+	write_4(sc, CPU_PORT_CONFIG, cpu_port_config);
+
+	if (!write_arl_table_entry(sc, 0, 1, VLAN0_GROUP_ID,
+	    STATIC_ENTRY, VLAN0_GROUP,
+	    vlan0_mac))
+		return (1);
+
+	set_pvid(sc, PORT0_PVID, PORT1_PVID, CPU_PORT_PVID);
+
+	for (i = 0; i < 8; i++) {
+		set_vlan_vid(sc, i);
+		set_vlan_member(sc, i);
+		set_vlan_tag(sc, i);
+	}
+
+	/* disable all interrupt status sources */
+	write_4(sc, INTERRUPT_MASK, 0xffff1fff);
+
+	/* clear previous interrupt sources */
+	write_4(sc, INTERRUPT_STATUS, 0x00001FFF);
+
+	write_4(sc, TS_DMA_CONTROL, 0);
+	write_4(sc, FS_DMA_CONTROL, 0);
+	return (0);
+}
+
+static int
+hardware_init(struct ece_softc *sc)
+{
+	int status = 0;
+	static int gw_phy_type;
+
+	gw_phy_type = get_phy_type(sc);
+	/* Currently only ic_plus phy is supported. */
+	if (gw_phy_type != IC_PLUS_PHY) {
+		device_printf(sc->dev, "PHY type is not supported (%d)\n",
+		    gw_phy_type);
+		return (-1);
+	}
+	status = configure_lan_port(sc, gw_phy_type);
+	configure_cpu_port(sc);
+	return (0);
+}
+
+static void
+set_mac_address(struct ece_softc *sc, const char *mac, int mac_len)
+{
+
+	/* Invalid age_field mean erase this entry. */
+	write_arl_table_entry(sc, 0, 1, VLAN0_GROUP_ID,
+	    INVALID_ENTRY, VLAN0_GROUP,
+	    mac);
+	memcpy(vlan0_mac, mac, ETHER_ADDR_LEN);
+
+	write_arl_table_entry(sc, 0, 1, VLAN0_GROUP_ID,
+	    STATIC_ENTRY, VLAN0_GROUP,
+	    mac);
+}
+
+static void
+ece_set_mac(struct ece_softc *sc, u_char *eaddr)
+{
+	memcpy(vlan0_mac, eaddr, ETHER_ADDR_LEN);
+	set_mac_address(sc, eaddr, ETHER_ADDR_LEN);
+}
+
+/*
+ * TODO: the device doesn't have MAC stored, we should read the
+ * configuration stored in FLASH, but the format depends on the
+ * bootloader used.*
+ */
+static int
+ece_get_mac(struct ece_softc *sc, u_char *eaddr)
+{
+	return (ENXIO);
+}
+
+static void
+ece_intr_rx_locked(struct ece_softc *sc, int count)
+{
+	struct ifnet *ifp = sc->ifp;
+	struct mbuf *mb;
+	struct rx_desc_info *rxdesc;
+	eth_rx_desc_t *desc;
+
+	int fssd_curr;
+	int fssd;
+	int i;
+	int idx;
+	int rxcount;
+	uint32_t status;
+
+	fssd_curr = read_4(sc, FS_DESCRIPTOR_POINTER);
+
+	fssd = (fssd_curr - (uint32_t)sc->ring_paddr_rx)>>4;
+
+	desc = sc->rx_desc[sc->last_rx].desc;
+
+	/* Prepare to read the data in the ring. */
+	bus_dmamap_sync(sc->dmatag_ring_rx,
+	    sc->dmamap_ring_rx,
+	    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
+
+	if (fssd > sc->last_rx)
+		rxcount = fssd - sc->last_rx;
+	else if (fssd < sc->last_rx)
+		rxcount = (ECE_MAX_RX_BUFFERS - sc->last_rx) + fssd;
+	else {
+		if (desc->cown == 0)
+			return;
+		else
+			rxcount = ECE_MAX_RX_BUFFERS;
+	}
+
+	for (i= 0; i < rxcount; i++) {
+		status = desc->cown;
+		if (!status)
+			break;
+
+		idx = sc->last_rx;
+		rxdesc = &sc->rx_desc[idx];
+		mb = rxdesc->buff;
+
+		if (desc->length < ETHER_MIN_LEN - ETHER_CRC_LEN ||
+		    desc->length > ETHER_MAX_LEN - ETHER_CRC_LEN +
+		    ETHER_VLAN_ENCAP_LEN) {
+			ifp->if_ierrors++;
+			desc->cown = 0;
+			desc->length = MCLBYTES - 2;
+			/* Invalid packet, skip and process next
+			 * packet.
+			 */
+			continue;
+		}
+
+		if (ece_new_rxbuf(sc, rxdesc) != 0) {
+			ifp->if_iqdrops++;
+			desc->cown = 0;
+			desc->length = MCLBYTES - 2;
+			break;
+		}
+
+		/**
+		 * The device will write to addrress + 2 So we need to adjust
+		 * the address after the packet is received.
+		 */
+		mb->m_data += 2;
+		mb->m_len = mb->m_pkthdr.len = desc->length;
+
+		mb->m_flags |= M_PKTHDR;
+		mb->m_pkthdr.rcvif = ifp;
+		if ((ifp->if_capenable & IFCAP_RXCSUM) != 0) {
+			/*check for valid checksum*/
+			if ( (!desc->l4f)  && (desc->prot != 3)) {
+				mb->m_pkthdr.csum_flags |= CSUM_IP_CHECKED;
+				mb->m_pkthdr.csum_flags |= CSUM_IP_VALID;
+				mb->m_pkthdr.csum_data = 0xffff;
+			}
+		}
+		ECE_RXUNLOCK(sc);
+		(*ifp->if_input)(ifp, mb);
+		ECE_RXLOCK(sc);
+
+		desc->cown = 0;
+		desc->length = MCLBYTES - 2;
+
+		bus_dmamap_sync(sc->dmatag_ring_rx,
+		    sc->dmamap_ring_rx,
+		    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+
+		if (sc->last_rx == ECE_MAX_RX_BUFFERS - 1)
+			sc->last_rx = 0;
+		else
+			sc->last_rx++;
+
+		desc = sc->rx_desc[sc->last_rx].desc;
+	}
+
+	/* Sync updated flags. */
+	bus_dmamap_sync(sc->dmatag_ring_rx,
+	    sc->dmamap_ring_rx,
+	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+
+	return;
+}
+
+static void
+ece_intr_task(void *arg, int pending __unused)
+{
+	struct ece_softc *sc = arg;
+	ECE_RXLOCK(sc);
+	ece_intr_rx_locked(sc, -1);
+	ECE_RXUNLOCK(sc);
+}
+
+static void
+ece_intr(void *xsc)
+{
+	struct ece_softc *sc = xsc;
+	struct ifnet *ifp = sc->ifp;
+
+	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
+		write_4(sc, FS_DMA_CONTROL, 0);
+		return;
+	}
+
+	taskqueue_enqueue(sc->sc_tq, &sc->sc_intr_task);
+
+	if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
+		taskqueue_enqueue(sc->sc_tq, &sc->sc_tx_task);
+}
+
+static void
+ece_intr_status(void *xsc)
+{
+	struct ece_softc *sc = xsc;
+	struct ifnet *ifp = sc->ifp;
+	int stat;
+
+	stat = read_4(sc, INTERRUPT_STATUS);
+
+	write_4(sc, INTERRUPT_STATUS, stat);
+
+	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) {
+		if ((stat & ERROR_MASK) != 0)
+			ifp->if_iqdrops++;
+	}
+}
+
+static void
+ece_cleanup_locked(struct ece_softc *sc)
+{
+	eth_tx_desc_t *desc;
+
+	if (sc->tx_cons == sc->tx_prod) return;
+
+	/* Prepare to read the ring (owner bit). */
+	bus_dmamap_sync(sc->dmatag_ring_tx,
+	    sc->dmamap_ring_tx,
+	    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
+
+	while (sc->tx_cons != sc->tx_prod) {
+		desc = sc->tx_desc[sc->tx_cons].desc;
+		if (desc->cown != 0) {
+			struct tx_desc_info *td = &(sc->tx_desc[sc->tx_cons]);
+			/* We are finished with this descriptor ... */
+			bus_dmamap_sync(sc->dmatag_data_tx, td->dmamap,
+			    BUS_DMASYNC_POSTWRITE);
+			/* ... and unload, so we can reuse. */
+			bus_dmamap_unload(sc->dmatag_data_tx, td->dmamap);
+			m_freem(td->buff);
+			td->buff = 0;
+			sc->tx_cons = (sc->tx_cons + 1) % ECE_MAX_TX_BUFFERS;
+		} else {
+			break;
+		}
+	}
+
+}
+
+static void
+ece_cleanup_task(void *arg, int pending __unused)
+{
+	struct ece_softc *sc = arg;
+	ECE_CLEANUPLOCK(sc);
+	ece_cleanup_locked(sc);
+	ECE_CLEANUPUNLOCK(sc);
+}
+
+static void
+ece_intr_tx(void *xsc)
+{
+	struct ece_softc *sc = xsc;
+	struct ifnet *ifp = sc->ifp;
+	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
+		/* This should not happen, stop DMA. */
+		write_4(sc, FS_DMA_CONTROL, 0);
+		return;
+	}
+	taskqueue_enqueue(sc->sc_tq, &sc->sc_cleanup_task);
+}
+
+static void
+ece_intr_qf(void *xsc)
+{
+	struct ece_softc *sc = xsc;
+	struct ifnet *ifp = sc->ifp;
+	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
+		/* This should not happen, stop DMA. */
+		write_4(sc, FS_DMA_CONTROL, 0);
+		return;
+	}
+	taskqueue_enqueue(sc->sc_tq, &sc->sc_intr_task);
+	write_4(sc, FS_DMA_CONTROL, 1);
+}
+
+/*
+ * Reset and initialize the chip
+ */
+static void
+eceinit_locked(void *xsc)
+{
+	struct ece_softc *sc = xsc;
+	struct ifnet *ifp = sc->ifp;
+	struct mii_data *mii;
+	uint32_t cfg_reg;
+	uint32_t cpu_port_config;
+	uint32_t mac_port_config;
+
+	while (1) {
+		cfg_reg = read_4(sc, BIST_RESULT_TEST_0);
+		if ((cfg_reg & (1<<17)))
+			break;
+		DELAY(100);
+	}
+	/* Set to default values. */
+	write_4(sc, SWITCH_CONFIG, 0x007AA7A1);
+	write_4(sc, MAC_PORT_0_CONFIG, 0x00423D00);
+	write_4(sc, MAC_PORT_1_CONFIG, 0x00423D80);
+	write_4(sc, CPU_PORT_CONFIG, 0x004C0000);
+
+	hardware_init(sc);
+
+	mac_port_config = read_4(sc, MAC_PORT_0_CONFIG);
+
+	 /* Enable Port 0 */
+	mac_port_config &= (~(PORT_DISABLE));
+	write_4(sc, MAC_PORT_0_CONFIG, mac_port_config);
+
+	cpu_port_config = read_4(sc, CPU_PORT_CONFIG);
+	/* Enable CPU. */
+	cpu_port_config &= ~(PORT_DISABLE);
+	write_4(sc, CPU_PORT_CONFIG, cpu_port_config);
+
+	/*
+	 * Set 'running' flag, and clear output active flag
+	 * and attempt to start the output
+	 */
+	ifp->if_drv_flags |= IFF_DRV_RUNNING;
+	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+
+	mii = device_get_softc(sc->miibus);
+	mii_pollstat(mii);
+	/* Enable DMA. */
+	write_4(sc, FS_DMA_CONTROL, 1);
+
+	callout_reset(&sc->tick_ch, hz, ece_tick, sc);
+}
+
+static inline int
+ece_encap(struct ece_softc *sc, struct mbuf *m0)
+{
+	struct ifnet *ifp;
+	bus_dma_segment_t segs[MAX_FRAGMENT];
+	bus_dmamap_t mapp;
+	eth_tx_desc_t *desc = 0;
+	int csum_flags;
+	int desc_no;
+	int error;
+	int nsegs;
+	int seg;
+
+	ifp = sc->ifp;
+
+	/* Fetch unused map */
+	mapp = sc->tx_desc[sc->tx_prod].dmamap;
+
+	error = bus_dmamap_load_mbuf_sg(sc->dmatag_ring_tx, mapp,
+	    m0, segs, &nsegs,
+	    BUS_DMA_NOWAIT);
+
+	if (error != 0) {
+		bus_dmamap_unload(sc->dmatag_ring_tx, mapp);
+		return ((error != 0) ? error : -1);
+	}
+
+	desc = &(sc->desc_tx[sc->desc_curr_tx]);
+	sc->tx_desc[sc->tx_prod].desc = desc;
+	sc->tx_desc[sc->tx_prod].buff = m0;
+	desc_no = sc->desc_curr_tx;
+
+	for (seg = 0; seg < nsegs; seg++) {
+		if (desc->cown == 0 ) {
+			if_printf(ifp, "ERROR: descriptor is still used\n");
+			return (-1);
+		}
+
+		desc->length = segs[seg].ds_len;
+		desc->data_ptr = segs[seg].ds_addr;
+
+		if (seg == 0) {
+			desc->fs = 1;
+		} else {
+			desc->fs = 0;
+		}
+		if (seg == nsegs - 1) {
+			desc->ls = 1;
+		} else {
+			desc->ls = 0;
+		}
+
+		csum_flags = m0->m_pkthdr.csum_flags;
+
+		desc->fr =  1;
+		desc->pmap =  1;
+		desc->insv =  0;
+		desc->ico = 0;
+		desc->tco = 0;
+		desc->uco = 0;
+		desc->interrupt = 1;
+
+		if (csum_flags & CSUM_IP) {
+			desc->ico = 1;
+			if (csum_flags & CSUM_TCP)
+				desc->tco = 1;
+			if (csum_flags & CSUM_UDP)
+				desc->uco = 1;
+		}
+
+		desc++;
+		sc->desc_curr_tx = (sc->desc_curr_tx + 1) % ECE_MAX_TX_BUFFERS;
+		if (sc->desc_curr_tx == 0) {
+			desc = (eth_tx_desc_t *)&(sc->desc_tx[0]);
+		}
+	}
+
+	desc = sc->tx_desc[sc->tx_prod].desc;
+
+	sc->tx_prod = (sc->tx_prod + 1) % ECE_MAX_TX_BUFFERS;
+
+	/*
+	 * After all descriptors are set, we set the flags to start the
+	 * sending proces.
+	 */
+	for (seg = 0; seg < nsegs; seg++) {
+		desc->cown = 0;
+		desc++;
+		desc_no = (desc_no + 1) % ECE_MAX_TX_BUFFERS;
+		if (desc_no == 0)
+			desc = (eth_tx_desc_t *)&(sc->desc_tx[0]);
+	}
+
+	bus_dmamap_sync(sc->dmatag_data_tx, mapp, BUS_DMASYNC_PREWRITE);
+	return (0);
+}
+
+/*
+ * dequeu packets and transmit
+ */
+static void
+ecestart_locked(struct ifnet *ifp)
+{
+	struct ece_softc *sc;
+	struct mbuf *m0;
+	uint32_t queued = 0;
+
+	sc = ifp->if_softc;
+	if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
+	    IFF_DRV_RUNNING)
+		return;
+
+	bus_dmamap_sync(sc->dmatag_ring_tx,
+	    sc->dmamap_ring_tx,
+	    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
+
+	for (;;) {
+		/* Get packet from the queue */
+		IF_DEQUEUE(&ifp->if_snd, m0);
+		if (m0 == NULL)
+			break;
+		if (ece_encap(sc, m0)) {
+			IF_PREPEND(&ifp->if_snd, m0);
+			ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+			break;
+		}
+		queued++;
+		BPF_MTAP(ifp, m0);
+	}
+	if (queued) {
+		bus_dmamap_sync(sc->dmatag_ring_tx, sc->dmamap_ring_tx,
+		    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
+		write_4(sc, TS_DMA_CONTROL, 1);
+	}
+}
+
+static void
+eceinit(void *xsc)
+{
+	struct ece_softc *sc = xsc;
+	ECE_LOCK(sc);
+	eceinit_locked(sc);
+	ECE_UNLOCK(sc);
+}
+
+static void
+ece_tx_task(void *arg, int pending __unused)
+{
+	struct ifnet *ifp;
+	ifp = (struct ifnet *)arg;
+	ecestart(ifp);
+}
+
+static void
+ecestart(struct ifnet *ifp)
+{
+	struct ece_softc *sc = ifp->if_softc;
+	ECE_TXLOCK(sc);
+	ecestart_locked(ifp);
+	ECE_TXUNLOCK(sc);
+}
+
+/*
+ * Turn off interrupts, and stop the nic.  Can be called with sc->ifp
+ * NULL so be careful.
+ */
+static void
+ecestop(struct ece_softc *sc)
+{
+	struct ifnet *ifp = sc->ifp;
+	uint32_t mac_port_config;
+
+	write_4(sc, TS_DMA_CONTROL, 0);
+	write_4(sc, FS_DMA_CONTROL, 0);
+
+	if (ifp)
+		ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+
+	callout_stop(&sc->tick_ch);
+
+	/*Disable Port 0 */
+	mac_port_config = read_4(sc, MAC_PORT_0_CONFIG);
+	mac_port_config |= (PORT_DISABLE);
+	write_4(sc, MAC_PORT_0_CONFIG, mac_port_config);
+
+	/*Disable Port 1 */
+	mac_port_config = read_4(sc, MAC_PORT_1_CONFIG);
+	mac_port_config |= (PORT_DISABLE);
+	write_4(sc, MAC_PORT_1_CONFIG, mac_port_config);
+
+	/* Disable all interrupt status sources. */
+	write_4(sc, INTERRUPT_MASK, 0x00001FFF);
+
+	/* Clear previous interrupt sources. */
+	write_4(sc, INTERRUPT_STATUS, 0x00001FFF);
+
+	write_4(sc, SWITCH_CONFIG, initial_switch_config);
+	write_4(sc, CPU_PORT_CONFIG, initial_cpu_config);
+	write_4(sc, MAC_PORT_0_CONFIG, initial_port0_config);
+	write_4(sc, MAC_PORT_1_CONFIG, initial_port1_config);
+
+	clear_mac_entries(sc, 1);
+}
+
+static void
+ece_restart(struct ece_softc *sc)
+{
+	struct ifnet *ifp = sc->ifp;
+
+	ifp->if_drv_flags |= IFF_DRV_RUNNING;
+	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+	/* Enable port 0. */
+	write_4(sc, PORT_0_CONFIG,
+	    read_4(sc, PORT_0_CONFIG) & ~(PORT_DISABLE));
+	write_4(sc, INTERRUPT_MASK, 0x00000000);
+	write_4(sc, FS_DMA_CONTROL, 1);
+	callout_reset(&sc->tick_ch, hz, ece_tick, sc);
+}
+
+static void
+set_filter(struct ece_softc *sc)
+{
+	struct ifnet		*ifp;
+	struct ifmultiaddr	*ifma;
+	uint32_t mac_port_config;
+
+	ifp = sc->ifp;
+
+	clear_mac_entries(sc, 0);
+	if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
+		mac_port_config = read_4(sc, MAC_PORT_0_CONFIG);
+		mac_port_config &= ~(DISABLE_BROADCAST_PACKET);
+		mac_port_config &= ~(DISABLE_MULTICAST_PACKET);
+		write_4(sc, MAC_PORT_0_CONFIG, mac_port_config);
+		return;
+	}
+	if_maddr_rlock(ifp);
+	TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
+		if (ifma->ifma_addr->sa_family != AF_LINK)
+			continue;
+		add_mac_entry(sc,
+		    LLADDR((struct sockaddr_dl *)ifma->ifma_addr));
+	}
+	if_maddr_runlock(ifp);
+}
+
+static int
+eceioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
+{
+	struct ece_softc *sc = ifp->if_softc;
+	struct mii_data *mii;
+	struct ifreq *ifr = (struct ifreq *)data;
+	int mask, error = 0;
+
+	switch (cmd) {
+	case SIOCSIFFLAGS:
+		ECE_LOCK(sc);
+		if ((ifp->if_flags & IFF_UP) == 0 &&
+		    ifp->if_drv_flags & IFF_DRV_RUNNING) {
+			ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
+			ecestop(sc);
+		} else {
+			/* Reinitialize card on any parameter change. */
+			if ((ifp->if_flags & IFF_UP) &&
+			    !(ifp->if_drv_flags & IFF_DRV_RUNNING))
+				ece_restart(sc);
+		}
+		ECE_UNLOCK(sc);
+		break;
+
+	case SIOCADDMULTI:
+	case SIOCDELMULTI:
+		ECE_LOCK(sc);
+		set_filter(sc);
+		ECE_UNLOCK(sc);
+		break;
+
+	case SIOCSIFMEDIA:
+	case SIOCGIFMEDIA:
+		mii = device_get_softc(sc->miibus);
+		error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, cmd);
+		break;
+	case SIOCSIFCAP:
+		mask = ifp->if_capenable ^ ifr->ifr_reqcap;
+		if (mask & IFCAP_VLAN_MTU) {
+			ECE_LOCK(sc);
+			ECE_UNLOCK(sc);
+		}
+	default:
+		error = ether_ioctl(ifp, cmd, data);
+		break;
+	}
+	return (error);
+}
+
+static void
+ece_child_detached(device_t dev, device_t child)
+{
+	struct ece_softc *sc;
+
+	sc = device_get_softc(dev);
+	if (child == sc->miibus)
+		sc->miibus = NULL;
+}
+
+/*
+ * MII bus support routines.
+ */
+static int
+ece_miibus_readreg(device_t dev, int phy, int reg)
+{
+	struct ece_softc *sc;
+	sc = device_get_softc(dev);
+	return (phy_read(sc, phy, reg));
+}
+
+static int
+ece_miibus_writereg(device_t dev, int phy, int reg, int data)
+{
+	struct ece_softc *sc;
+	sc = device_get_softc(dev);
+	phy_write(sc, phy, reg, data);
+	return (0);
+}
+
+static device_method_t ece_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,	ece_probe),
+	DEVMETHOD(device_attach,	ece_attach),
+	DEVMETHOD(device_detach,	ece_detach),
+
+	/* Bus interface */
+	DEVMETHOD(bus_child_detached,	ece_child_detached),
+
+	/* MII interface */
+	DEVMETHOD(miibus_readreg,	ece_miibus_readreg),
+	DEVMETHOD(miibus_writereg,	ece_miibus_writereg),
+
+	{ 0, 0 }
+};
+
+static driver_t ece_driver = {
+	"ece",
+	ece_methods,
+	sizeof(struct ece_softc),
+};
+
+DRIVER_MODULE(ece, econaarm, ece_driver, ece_devclass, 0, 0);
+DRIVER_MODULE(miibus, ece, miibus_driver, miibus_devclass, 0, 0);
+MODULE_DEPEND(ece, miibus, 1, 1, 1);
+MODULE_DEPEND(ece, ether, 1, 1, 1);


Property changes on: trunk/sys/arm/cavium/cns11xx/if_ece.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/cavium/cns11xx/if_ecereg.h
===================================================================
--- trunk/sys/arm/cavium/cns11xx/if_ecereg.h	                        (rev 0)
+++ trunk/sys/arm/cavium/cns11xx/if_ecereg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,155 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2009, Yohanes Nugroho <yohanes at gmail.com>
+ * 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 unmodified, 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: stable/10/sys/arm/cavium/cns11xx/if_ecereg.h 201468 2010-01-04 03:35:45Z rpaulo $
+ */
+
+#ifndef	_IF_ECEREG_H
+#define	_IF_ECEREG_H
+
+#define	ETH_CFG		0x08
+#define	ETH_CFG_RMII		(1 << 15)
+#define	PHY_CONTROL		0x00
+#define	PHY_RW_OK		(1<<15)
+
+#define	PHY_ADDRESS(x)		((x) & 0x1)
+#define	PHY_REGISTER(r)	(((r) & 0x1F) << 8)
+#define	PHY_WRITE_COMMAND	(1<<13)
+#define	PHY_READ_COMMAND	(1<<14)
+#define	PHY_GET_DATA(d)	(((d) >> 16) & 0xFFFF)
+#define	PHY_DATA(d)		(((d) & 0xFFFF) << 16)
+
+#define	PORT_0_CONFIG		0x08
+
+#define	ARL_TABLE_ACCESS_CONTROL_0	0x050
+#define	ARL_TABLE_ACCESS_CONTROL_1	0x054
+#define	ARL_TABLE_ACCESS_CONTROL_2	0x058
+
+#define	ARL_WRITE_COMMAND	(1<<3)
+#define	ARL_LOOKUP_COMMAND	(1<<2)
+#define	ARL_COMMAND_COMPLETE	(1)
+
+
+#define	PORT0			(1 << 0)
+#define	PORT1			(1 << 1)
+#define	CPU_PORT		(1 << 2)
+
+
+#define	VLAN0_GROUP_ID		(0)
+#define	VLAN1_GROUP_ID		(1)
+#define	VLAN2_GROUP_ID		(2)
+#define	VLAN3_GROUP_ID		(3)
+#define	VLAN4_GROUP_ID		(4)
+#define	VLAN5_GROUP_ID		(5)
+#define	VLAN6_GROUP_ID		(6)
+#define	VLAN7_GROUP_ID		(7)
+
+#define	PORT0_PVID		(VLAN1_GROUP_ID)
+#define	PORT1_PVID		(VLAN2_GROUP_ID)
+#define	CPU_PORT_PVID		(VLAN0_GROUP_ID)
+
+#define	VLAN0_VID		(0x111)
+#define	VLAN1_VID		(0x222)
+#define	VLAN2_VID		(0x333)
+#define	VLAN3_VID		(0x444)
+#define	VLAN4_VID		(0x555)
+#define	VLAN5_VID		(0x666)
+#define	VLAN6_VID		(0x777)
+#define	VLAN7_VID		(0x888)
+
+#define	VLAN0_GROUP		(PORT0 | PORT1 | CPU_PORT)
+#define	VLAN1_GROUP		(PORT0 | CPU_PORT)
+#define	VLAN2_GROUP		(PORT1 | CPU_PORT)
+#define	VLAN3_GROUP		(0)
+#define	VLAN4_GROUP		(0)
+#define	VLAN5_GROUP		(0)
+#define	VLAN6_GROUP		(0)
+#define	VLAN7_GROUP		(0)
+
+#define	SWITCH_CONFIG		0x004
+#define	MAC_PORT_0_CONFIG	0x008
+#define	MAC_PORT_1_CONFIG	0x00C
+#define	CPU_PORT_CONFIG	0x010
+#define	BIST_RESULT_TEST_0	0x094
+
+#define	FS_DMA_CONTROL		0x104
+#define	TS_DMA_CONTROL		0x100
+
+#define	INTERRUPT_MASK		0x08C
+#define	INTERRUPT_STATUS	0x088
+
+#define	TS_DESCRIPTOR_POINTER		0x108
+#define	TS_DESCRIPTOR_BASE_ADDR	0x110
+#define	FS_DESCRIPTOR_POINTER		0x10C
+#define	FS_DESCRIPTOR_BASE_ADDR	0x114
+
+
+#define	VLAN_VID_0_1		0x060
+#define	VLAN_VID_2_3		0x064
+#define	VLAN_VID_4_5		0x068
+#define	VLAN_VID_6_7		0x06C
+
+#define	VLAN_PORT_PVID		0x05C
+#define	VLAN_MEMBER_PORT_MAP		0x070
+#define	VLAN_TAG_PORT_MAP		0x074
+
+
+#define	ASIX_GIGA_PHY		1
+#define	TWO_SINGLE_PHY		2
+#define	AGERE_GIGA_PHY		3
+#define	VSC8601_GIGA_PHY	4
+#define	IC_PLUS_PHY		5
+#define	NOT_FOUND_PHY		(-1)
+
+#define	MAX_PACKET_LEN		(1536)
+
+#define	INVALID_ENTRY		0
+#define	NEW_ENTRY		0x1
+#define	STATIC_ENTRY		0x7
+
+/*mask status except for link change*/
+#define	ERROR_MASK		0xFFFFFF7F
+
+/*hardware interface flags*/
+
+#define	FAST_AGING		(0xf)
+#define	IVL_LEARNING		(0x1 << 22)
+/*hardware NAT accelerator*/
+#define	HARDWARE_NAT		(0x1 << 23)
+/*aging		time		setting*/
+
+/*skip lookup*/
+#define	SKIP_L2_LOOKUP_PORT_1	(1 << 29)
+#define	SKIP_L2_LOOKUP_PORT_0	(1 << 28)
+
+#define	NIC_MODE		(1 << 30)
+#define	PORT_DISABLE		(1 << 18)
+#define	SA_LEARNING_DISABLE		(1 << 19)
+#define	DISABLE_BROADCAST_PACKET	(1 << 27)
+#define	DISABLE_MULTICAST_PACKET	( 1 << 26)
+
+#endif


Property changes on: trunk/sys/arm/cavium/cns11xx/if_ecereg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/cavium/cns11xx/if_ecevar.h
===================================================================
--- trunk/sys/arm/cavium/cns11xx/if_ecevar.h	                        (rev 0)
+++ trunk/sys/arm/cavium/cns11xx/if_ecevar.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,194 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2009 Yohanes Nugroho <yohanes at gmail.com>
+ * 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 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 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: stable/10/sys/arm/cavium/cns11xx/if_ecevar.h 201468 2010-01-04 03:35:45Z rpaulo $
+ */
+
+#ifndef	_IFECEVAR_H
+#define	_IFECEVAR_H
+
+#define	ECE_MAX_TX_BUFFERS	128
+#define	ECE_MAX_RX_BUFFERS	128
+#define	MAX_FRAGMENT		32
+
+typedef struct {
+	/* 1st 32Bits */
+	uint32_t		data_ptr;
+	/* 2nd	32Bits*/
+	uint32_t		length:16;
+
+	uint32_t		tco:1; /*tcp checksum offload*/
+	uint32_t		uco:1; /*udp checksum offload*/
+	uint32_t		ico:1; /*ip checksum offload*/
+	/* force_route_port_map*/
+	uint32_t		pmap:3;
+	/* force_route */
+	uint32_t		fr:1;
+	/* force_priority_value */
+	uint32_t		pri:3;
+	/* force_priority */
+	uint32_t		fp:1;
+	/*interrupt_bit*/
+	uint32_t		interrupt:1;
+	/*last_seg*/
+	uint32_t		ls:1;
+	/*first_seg*/
+	uint32_t		fs:1;
+	/* end_bit */
+	uint32_t		eor:1;
+	/* c_bit */
+	uint32_t		cown:1;
+	/* 3rd 32Bits*/
+	/*vid_index*/
+	uint32_t		vid:3;
+	/*insert_vid_tag*/
+	uint32_t		insv:1;
+	/*pppoe_section_index*/
+	uint32_t		sid:3;
+	/*insert_pppoe_section*/
+	uint32_t		inss:1;
+	uint32_t		unused:24;
+	/* 4th 32Bits*/
+	uint32_t		unused2;
+
+} eth_tx_desc_t;
+
+typedef struct{
+	uint32_t		data_ptr;
+	uint32_t		length:16;
+	uint32_t		l4f:1;
+	uint32_t		ipf:1;
+	uint32_t		prot:2;
+	uint32_t		hr:6;
+	uint32_t		sp:2;
+	uint32_t		ls:1;
+	uint32_t		fs:1;
+	uint32_t		eor:1;
+	uint32_t		cown:1;
+	uint32_t		unused;
+	uint32_t		unused2;
+} eth_rx_desc_t;
+
+
+struct rx_desc_info {
+	struct mbuf*buff;
+	bus_dmamap_t dmamap;
+	eth_rx_desc_t *desc;
+};
+
+struct tx_desc_info {
+	struct mbuf*buff;
+	bus_dmamap_t dmamap;
+	eth_tx_desc_t *desc;
+};
+
+
+struct ece_softc
+{
+	struct ifnet *ifp;		/* ifnet pointer */
+	struct mtx sc_mtx;		/* global mutex */
+	struct mtx sc_mtx_tx;		/* tx mutex */
+	struct mtx sc_mtx_rx;		/* rx mutex */
+	struct mtx sc_mtx_cleanup;	/* rx mutex */
+
+	bus_dma_tag_t	sc_parent_tag;	/* parent bus DMA tag */
+
+	device_t dev;			/* Myself */
+	device_t miibus;		/* My child miibus */
+	void *intrhand;			/* Interrupt handle */
+	void *intrhand_qf;		/* queue full */
+	void *intrhand_tx;		/* tx complete */
+	void *intrhand_status;		/* error status */
+
+	struct resource *irq_res_tx;	/* transmit */
+	struct resource *irq_res_rec;	/* receive */
+	struct resource *irq_res_qf;	/* queue full */
+	struct resource *irq_res_status; /* status */
+
+	struct resource	*mem_res;	/* Memory resource */
+
+	struct callout tick_ch;		/* Tick callout */
+
+	struct taskqueue *sc_tq;
+	struct task	sc_intr_task;
+	struct task	sc_cleanup_task;
+	struct task	sc_tx_task;
+
+	bus_dmamap_t	dmamap_ring_tx;
+	bus_dmamap_t	dmamap_ring_rx;
+	bus_dmamap_t	rx_sparemap;
+
+	/*dma tag for ring*/
+	bus_dma_tag_t	dmatag_ring_tx;
+	bus_dma_tag_t	dmatag_ring_rx;
+
+	/*dma tag for data*/
+	bus_dma_tag_t	dmatag_data_tx;
+	bus_dma_tag_t	dmatag_data_rx;
+
+	/*the ring*/
+	eth_tx_desc_t*	desc_tx;
+	eth_rx_desc_t*	desc_rx;
+
+	/*ring physical address*/
+	bus_addr_t	ring_paddr_tx;
+	bus_addr_t	ring_paddr_rx;
+
+	/*index of last received descriptor*/
+	uint32_t last_rx;
+	struct rx_desc_info rx_desc[ECE_MAX_RX_BUFFERS];
+
+	/* tx producer index */
+	uint32_t tx_prod;
+	/* tx consumer index */
+	uint32_t tx_cons;
+	/* tx ring index*/
+	uint32_t desc_curr_tx;
+
+	struct tx_desc_info tx_desc[ECE_MAX_TX_BUFFERS];
+};
+
+
+struct arl_table_entry_t {
+	uint32_t cmd_complete: 1;
+	uint32_t table_end: 1;
+	uint32_t search_match: 1;
+	uint32_t filter:1; /*if set, packet will be dropped */
+	uint32_t vlan_mac:1; /*indicates that this is the gateway mac address*/
+	uint32_t vlan_gid:3; /*vlan id*/
+	uint32_t age_field:3;
+	uint32_t port_map:3;
+	 /*48 bit mac address*/
+	uint8_t mac_addr[6];
+	uint8_t pad[2];
+};
+
+struct mac_list{
+	char mac_addr[6];
+	struct mac_list *next;
+};
+
+#endif


Property changes on: trunk/sys/arm/cavium/cns11xx/if_ecevar.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/cavium/cns11xx/ohci_ec.c
===================================================================
--- trunk/sys/arm/cavium/cns11xx/ohci_ec.c	                        (rev 0)
+++ trunk/sys/arm/cavium/cns11xx/ohci_ec.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,235 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2009 Yohanes Nugroho <yohanes at gmail.com>
+ * 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 ``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 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: stable/10/sys/arm/cavium/cns11xx/ohci_ec.c 308402 2016-11-07 09:19:04Z hselasky $");
+
+#include <sys/stdint.h>
+#include <sys/stddef.h>
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/types.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/bus.h>
+#include <sys/module.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/condvar.h>
+#include <sys/sysctl.h>
+#include <sys/sx.h>
+#include <sys/unistd.h>
+#include <sys/callout.h>
+#include <sys/malloc.h>
+#include <sys/priv.h>
+
+#include <dev/usb/usb.h>
+#include <dev/usb/usbdi.h>
+
+#include <dev/usb/usb_core.h>
+#include <dev/usb/usb_busdma.h>
+#include <dev/usb/usb_process.h>
+#include <dev/usb/usb_util.h>
+
+#include <dev/usb/usb_controller.h>
+#include <dev/usb/usb_bus.h>
+#include <dev/usb/controller/ohci.h>
+#include <dev/usb/controller/ohcireg.h>
+
+#include <sys/rman.h>
+
+#include <arm/cavium/cns11xx/econa_reg.h>
+
+#define	MEM_RID	0
+
+static device_probe_t ohci_ec_probe;
+static device_attach_t ohci_ec_attach;
+static device_detach_t ohci_ec_detach;
+
+struct ec_ohci_softc {
+	struct ohci_softc sc_ohci;	/* must be first */
+};
+
+static int
+ohci_ec_probe(device_t dev)
+{
+	device_set_desc(dev, "Econa integrated OHCI controller");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+ohci_ec_attach(device_t dev)
+{
+	struct ec_ohci_softc *sc = device_get_softc(dev);
+	bus_space_handle_t bsh;
+	int err;
+	int rid;
+
+	/* initialise some bus fields */
+	sc->sc_ohci.sc_bus.parent = dev;
+	sc->sc_ohci.sc_bus.devices = sc->sc_ohci.sc_devices;
+	sc->sc_ohci.sc_bus.devices_max = OHCI_MAX_DEVICES;
+	sc->sc_ohci.sc_bus.dma_bits = 32;
+
+	/* get all DMA memory */
+	if (usb_bus_mem_alloc_all(&sc->sc_ohci.sc_bus,
+	    USB_GET_DMA_TAG(dev), &ohci_iterate_hw_softc)) {
+		return (ENOMEM);
+	}
+	sc->sc_ohci.sc_dev = dev;
+
+	rid = MEM_RID;
+
+	sc->sc_ohci.sc_io_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
+	    &rid, RF_ACTIVE);
+
+	if (!(sc->sc_ohci.sc_io_res)) {
+		err = ENOMEM;
+		goto error;
+	}
+	sc->sc_ohci.sc_io_tag = rman_get_bustag(sc->sc_ohci.sc_io_res);
+	bsh = rman_get_bushandle(sc->sc_ohci.sc_io_res);
+	/* Undocumented magic initialization */
+	bus_space_write_4((sc)->sc_ohci.sc_io_tag, bsh,0x04, 0x146);
+
+	bus_space_write_4((sc)->sc_ohci.sc_io_tag, bsh,0x44, 0x0200);
+
+	DELAY(1000);
+
+	sc->sc_ohci.sc_io_size = rman_get_size(sc->sc_ohci.sc_io_res);
+
+	if (bus_space_subregion(sc->sc_ohci.sc_io_tag, bsh, 0x4000000,
+	    sc->sc_ohci.sc_io_size, &sc->sc_ohci.sc_io_hdl) != 0)
+		panic("%s: unable to subregion USB host registers",
+		    device_get_name(dev));
+
+	rid = 0;
+	sc->sc_ohci.sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+	    RF_ACTIVE);
+	if (!(sc->sc_ohci.sc_irq_res)) {
+		goto error;
+	}
+	sc->sc_ohci.sc_bus.bdev = device_add_child(dev, "usbus", -1);
+	if (!(sc->sc_ohci.sc_bus.bdev)) {
+		goto error;
+	}
+	device_set_ivars(sc->sc_ohci.sc_bus.bdev, &sc->sc_ohci.sc_bus);
+
+	strlcpy(sc->sc_ohci.sc_vendor, "Cavium",
+		sizeof(sc->sc_ohci.sc_vendor));
+
+#if (__FreeBSD_version >= 700031)
+	err = bus_setup_intr(dev, sc->sc_ohci.sc_irq_res,
+	    INTR_TYPE_BIO | INTR_MPSAFE,  NULL,
+	    (driver_intr_t *)ohci_interrupt, sc,
+	    &sc->sc_ohci.sc_intr_hdl);
+#else
+	err = bus_setup_intr(dev, sc->sc_ohci.sc_irq_res,
+	    INTR_TYPE_BIO | INTR_MPSAFE,
+	    (driver_intr_t *)ohci_interrupt, sc,
+	    &sc->sc_ohci.sc_intr_hdl);
+#endif
+	if (err) {
+		sc->sc_ohci.sc_intr_hdl = NULL;
+		goto error;
+	}
+
+	bus_space_write_4(sc->sc_ohci.sc_io_tag, sc->sc_ohci.sc_io_hdl,
+	    OHCI_CONTROL, 0);
+
+	err = ohci_init(&sc->sc_ohci);
+	if (!err) {
+		err = device_probe_and_attach(sc->sc_ohci.sc_bus.bdev);
+	}
+	if (err) {
+		goto error;
+	}
+	return (0);
+
+error:
+	ohci_ec_detach(dev);
+	return (ENXIO);
+}
+
+static int
+ohci_ec_detach(device_t dev)
+{
+	struct ec_ohci_softc *sc = device_get_softc(dev);
+	int err;
+
+	/* during module unload there are lots of children leftover */
+	device_delete_children(dev);
+
+	bus_space_write_4(sc->sc_ohci.sc_io_tag, sc->sc_ohci.sc_io_hdl,
+	    OHCI_CONTROL, 0);
+
+	if (sc->sc_ohci.sc_irq_res && sc->sc_ohci.sc_intr_hdl) {
+		/*
+		 * only call ohci_detach() after ohci_init()
+		 */
+		ohci_detach(&sc->sc_ohci);
+
+		err = bus_teardown_intr(dev, sc->sc_ohci.sc_irq_res,
+		    sc->sc_ohci.sc_intr_hdl);
+		sc->sc_ohci.sc_intr_hdl = NULL;
+	}
+	if (sc->sc_ohci.sc_irq_res) {
+		bus_release_resource(dev, SYS_RES_IRQ, 0,
+		    sc->sc_ohci.sc_irq_res);
+		sc->sc_ohci.sc_irq_res = NULL;
+	}
+	if (sc->sc_ohci.sc_io_res) {
+		bus_release_resource(dev, SYS_RES_MEMORY, MEM_RID,
+		    sc->sc_ohci.sc_io_res);
+		sc->sc_ohci.sc_io_res = NULL;
+	}
+	usb_bus_mem_free_all(&sc->sc_ohci.sc_bus, &ohci_iterate_hw_softc);
+
+	return (0);
+}
+
+static device_method_t ohci_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe, ohci_ec_probe),
+	DEVMETHOD(device_attach, ohci_ec_attach),
+	DEVMETHOD(device_detach, ohci_ec_detach),
+	DEVMETHOD(device_resume, bus_generic_resume),
+	DEVMETHOD(device_suspend, bus_generic_suspend),
+	DEVMETHOD(device_shutdown, bus_generic_shutdown),
+
+	DEVMETHOD_END
+};
+
+static driver_t ohci_driver = {
+	.name = "ohci",
+	.methods = ohci_methods,
+	.size = sizeof(struct ec_ohci_softc),
+};
+
+static devclass_t ohci_devclass;
+
+DRIVER_MODULE(ohci, econaarm, ohci_driver, ohci_devclass, 0, 0);
+MODULE_DEPEND(ohci, usb, 1, 1, 1);


Property changes on: trunk/sys/arm/cavium/cns11xx/ohci_ec.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/cavium/cns11xx/std.econa
===================================================================
--- trunk/sys/arm/cavium/cns11xx/std.econa	                        (rev 0)
+++ trunk/sys/arm/cavium/cns11xx/std.econa	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,16 @@
+# $FreeBSD: stable/10/sys/arm/cavium/cns11xx/std.econa 264219 2014-04-07 05:33:30Z rpaulo $
+
+files	"../cavium/cns11xx/files.econa"
+cpu		CPU_FA526
+machine 	arm
+makeoptions	CONF_CFLAGS=-march=armv4
+options	PHYSADDR=0x00000000
+makeoptions	KERNPHYSADDR=0x01000000
+makeoptions	KERNVIRTADDR=0xc1000000
+
+options	KERNPHYSADDR=0x01000000
+options	KERNVIRTADDR=0xc1000000	# Used in ldscript.arm
+options	FLASHADDR=0xD0000000
+options	LOADERRAMADDR=0x00000000
+
+options	NO_EVENTTIMERS


Property changes on: trunk/sys/arm/cavium/cns11xx/std.econa
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/cavium/cns11xx/timer.c
===================================================================
--- trunk/sys/arm/cavium/cns11xx/timer.c	                        (rev 0)
+++ trunk/sys/arm/cavium/cns11xx/timer.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,382 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2009 Yohanes Nugroho <yohanes at gmail.com>.
+ * 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 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 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: stable/10/sys/arm/cavium/cns11xx/timer.c 257200 2013-10-27 01:34:10Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/timetc.h>
+#include <sys/watchdog.h>
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#include "econa_reg.h"
+#include "econa_var.h"
+
+#define	INITIAL_TIMECOUNTER	(0xffffffff)
+
+static int timers_initialized = 0;
+
+#define	HZ	100
+
+extern unsigned int CPU_clock;
+extern unsigned int AHB_clock;
+extern unsigned int APB_clock;
+
+static unsigned long timer_counter = 0;
+
+struct ec_timer_softc {
+	struct resource	*	timer_res[3];
+	bus_space_tag_t		timer_bst;
+	bus_space_handle_t	timer_bsh;
+	struct mtx		timer_mtx;
+};
+
+static struct resource_spec ec_timer_spec[] = {
+	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		0,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		1,	RF_ACTIVE },
+	{ -1, 0 }
+};
+
+static unsigned ec_timer_get_timecount(struct timecounter *);
+
+static struct timecounter ec_timecounter = {
+	.tc_get_timecount = ec_timer_get_timecount,
+	.tc_name = "CPU Timer",
+	/* This is assigned on the fly in the init sequence */
+	.tc_frequency = 0,
+	.tc_counter_mask = ~0u,
+	.tc_quality = 1000,
+};
+
+static struct ec_timer_softc *timer_softc = NULL;
+
+static inline
+void write_4(unsigned int val, unsigned int addr)
+{
+	bus_space_write_4(timer_softc->timer_bst,
+			  timer_softc->timer_bsh, addr, val);
+
+}
+
+static inline
+unsigned int read_4(unsigned int addr)
+{
+
+	return bus_space_read_4(timer_softc->timer_bst,
+	    timer_softc->timer_bsh, addr);
+}
+
+#define	uSECS_PER_TICK	(1000000 / APB_clock)
+#define	TICKS2USECS(x)	((x) * uSECS_PER_TICK)
+
+static unsigned
+read_timer_counter_noint(void)
+{
+
+	arm_mask_irq(0);
+	unsigned int v = read_4(TIMER_TM1_COUNTER_REG);
+	arm_unmask_irq(0);
+	return v;
+}
+
+void
+DELAY(int usec)
+{
+	uint32_t val, val_temp;
+	int nticks;
+
+	if (!timers_initialized) {
+		for (; usec > 0; usec--)
+			for (val = 100; val > 0; val--)
+				;
+		return;
+	}
+
+	val = read_timer_counter_noint();
+	nticks = (((APB_clock / 1000) * usec) / 1000) + 100;
+
+	while (nticks > 0) {
+		val_temp = read_timer_counter_noint();
+		if (val > val_temp)
+			nticks -= (val - val_temp);
+		else
+			nticks -= (val + (timer_counter - val_temp));
+
+		val = val_temp;
+	}
+
+}
+
+/*
+ * Setup timer
+ */
+static inline void
+setup_timer(unsigned int counter_value)
+{
+	unsigned int control_value;
+	unsigned int mask_value;
+
+	control_value = read_4(TIMER_TM_CR_REG);
+
+	mask_value = read_4(TIMER_TM_INTR_MASK_REG);
+	write_4(counter_value, TIMER_TM1_COUNTER_REG);
+	write_4(counter_value, TIMER_TM1_LOAD_REG);
+	write_4(0, TIMER_TM1_MATCH1_REG);
+	write_4(0,TIMER_TM1_MATCH2_REG);
+
+	control_value &= ~(TIMER1_CLOCK_SOURCE);
+	control_value |= TIMER1_UP_DOWN_COUNT;
+
+	write_4(0, TIMER_TM2_COUNTER_REG);
+	write_4(0, TIMER_TM2_LOAD_REG);
+	write_4(~0u, TIMER_TM2_MATCH1_REG);
+	write_4(~0u,TIMER_TM2_MATCH2_REG);
+
+	control_value &= ~(TIMER2_CLOCK_SOURCE);
+	control_value &= ~(TIMER2_UP_DOWN_COUNT);
+
+	mask_value &= ~(63);
+
+	write_4(control_value, TIMER_TM_CR_REG);
+	write_4(mask_value, TIMER_TM_INTR_MASK_REG);
+}
+
+/*
+ * Enable timer
+ */
+static inline void
+timer_enable(void)
+{
+	unsigned int control_value;
+
+	control_value = read_4(TIMER_TM_CR_REG);
+
+	control_value |= TIMER1_OVERFLOW_ENABLE;
+	control_value |= TIMER1_ENABLE;
+	control_value |= TIMER2_OVERFLOW_ENABLE;
+	control_value |= TIMER2_ENABLE;
+
+	write_4(control_value, TIMER_TM_CR_REG);
+}
+
+static inline unsigned int
+read_second_timer_counter(void)
+{
+
+	return read_4(TIMER_TM2_COUNTER_REG);
+}
+
+/*
+ * Get timer interrupt status
+ */
+static inline unsigned int
+read_timer_interrupt_status(void)
+{
+
+	return read_4(TIMER_TM_INTR_STATUS_REG);
+}
+
+/*
+ * Clear timer interrupt status
+ */
+static inline void
+clear_timer_interrupt_status(unsigned int irq)
+{
+	unsigned int interrupt_status;
+
+	interrupt_status =   read_4(TIMER_TM_INTR_STATUS_REG);
+	if (irq == 0) {
+		if (interrupt_status & (TIMER1_MATCH1_INTR))
+			interrupt_status &= ~(TIMER1_MATCH1_INTR);
+		if (interrupt_status & (TIMER1_MATCH2_INTR))
+			interrupt_status &= ~(TIMER1_MATCH2_INTR);
+		if (interrupt_status & (TIMER1_OVERFLOW_INTR))
+			interrupt_status &= ~(TIMER1_OVERFLOW_INTR);
+	}
+	if (irq == 1) {
+		if (interrupt_status & (TIMER2_MATCH1_INTR))
+			interrupt_status &= ~(TIMER2_MATCH1_INTR);
+		if (interrupt_status & (TIMER2_MATCH2_INTR))
+			interrupt_status &= ~(TIMER2_MATCH2_INTR);
+		if (interrupt_status & (TIMER2_OVERFLOW_INTR))
+			interrupt_status &= ~(TIMER2_OVERFLOW_INTR);
+	}
+
+	write_4(interrupt_status, TIMER_TM_INTR_STATUS_REG);
+}
+
+static unsigned
+ec_timer_get_timecount(struct timecounter *a)
+{
+	unsigned int ticks1;
+	arm_mask_irq(1);
+	ticks1 = read_second_timer_counter();
+	arm_unmask_irq(1);
+	return ticks1;
+}
+
+/*
+ * Setup timer
+ */
+static inline void
+do_setup_timer(void)
+{
+
+	timer_counter = APB_clock/HZ;
+	/*
+	 * setup timer-related values
+	 */
+	setup_timer(timer_counter);
+}
+
+void
+cpu_initclocks(void)
+{
+
+	ec_timecounter.tc_frequency = APB_clock;
+	tc_init(&ec_timecounter);
+	timer_enable();
+	timers_initialized = 1;
+}
+
+void
+cpu_startprofclock(void)
+{
+
+}
+
+void
+cpu_stopprofclock(void)
+{
+
+}
+
+static int
+ec_timer_probe(device_t dev)
+{
+
+	device_set_desc(dev, "Econa CPU Timer");
+	return (0);
+}
+
+static int
+ec_reset(void *arg)
+{
+
+	arm_mask_irq(1);
+	clear_timer_interrupt_status(1);
+	arm_unmask_irq(1);
+	return (FILTER_HANDLED);
+}
+
+static int
+ec_hardclock(void *arg)
+{
+	struct	trapframe *frame;
+	unsigned int val;
+	/*clear timer interrupt status*/
+
+	arm_mask_irq(0);
+
+	val = read_4(TIMER_INTERRUPT_STATUS_REG);
+	val &= ~(TIMER1_OVERFLOW_INTERRUPT);
+	write_4(val, TIMER_INTERRUPT_STATUS_REG);
+
+	frame = (struct trapframe *)arg;
+	hardclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
+
+	arm_unmask_irq(0);
+
+	return (FILTER_HANDLED);
+}
+
+static int
+ec_timer_attach(device_t dev)
+{
+	struct	ec_timer_softc *sc;
+	int	error;
+	void	*ihl;
+
+
+	if (timer_softc != NULL)
+		return (ENXIO);
+
+	sc = (struct ec_timer_softc *)device_get_softc(dev);
+
+	timer_softc = sc;
+
+	error = bus_alloc_resources(dev, ec_timer_spec, sc->timer_res);
+	if (error) {
+		device_printf(dev, "could not allocate resources\n");
+		return (ENXIO);
+	}
+
+	sc->timer_bst = rman_get_bustag(sc->timer_res[0]);
+	sc->timer_bsh = rman_get_bushandle(sc->timer_res[0]);
+
+	do_setup_timer();
+
+	if (bus_setup_intr(dev, sc->timer_res[1], INTR_TYPE_CLK,
+	    ec_hardclock, NULL, NULL, &ihl) != 0) {
+		bus_release_resources(dev, ec_timer_spec, sc->timer_res);
+		device_printf(dev, "could not setup hardclock interrupt\n");
+		return (ENXIO);
+	}
+
+	if (bus_setup_intr(dev, sc->timer_res[2], INTR_TYPE_CLK,
+	    ec_reset, NULL, NULL, &ihl) != 0) {
+		bus_release_resources(dev, ec_timer_spec, sc->timer_res);
+		device_printf(dev, "could not setup timer interrupt\n");
+		return (ENXIO);
+	}
+
+	return (0);
+}
+
+static device_method_t ec_timer_methods[] = {
+	DEVMETHOD(device_probe, ec_timer_probe),
+	DEVMETHOD(device_attach, ec_timer_attach),
+	{ 0, 0 }
+};
+
+static driver_t ec_timer_driver = {
+	"timer",
+	ec_timer_methods,
+	sizeof(struct ec_timer_softc),
+};
+
+static devclass_t ec_timer_devclass;
+
+DRIVER_MODULE(timer, econaarm, ec_timer_driver, ec_timer_devclass, 0, 0);


Property changes on: trunk/sys/arm/cavium/cns11xx/timer.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/cavium/cns11xx/uart_bus_ec.c
===================================================================
--- trunk/sys/arm/cavium/cns11xx/uart_bus_ec.c	                        (rev 0)
+++ trunk/sys/arm/cavium/cns11xx/uart_bus_ec.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,77 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (C) 2009 Yohanes Nugroho <yohanes at gmail.com>
+ * 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 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 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: stable/10/sys/arm/cavium/cns11xx/uart_bus_ec.c 264219 2014-04-07 05:33:30Z rpaulo $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+
+#include <machine/bus.h>
+#include <sys/rman.h>
+#include <machine/resource.h>
+
+#include <dev/uart/uart.h>
+#include <dev/uart/uart_bus.h>
+#include <dev/uart/uart_cpu.h>
+
+#include <arm/cavium/cns11xx/econa_reg.h>
+
+static int uart_ec_probe(device_t dev);
+
+static device_method_t uart_ec_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,	uart_ec_probe),
+	DEVMETHOD(device_attach,	uart_bus_attach),
+	DEVMETHOD(device_detach,	uart_bus_detach),
+	{ 0, 0 }
+};
+
+static driver_t uart_ec_driver = {
+	uart_driver_name,
+	uart_ec_methods,
+	sizeof(struct uart_softc),
+};
+
+static int
+uart_ec_probe(device_t dev)
+{
+	struct	uart_softc *sc;
+	int status;
+
+	sc = device_get_softc(dev);
+	sc->sc_class = &uart_ns8250_class;
+	status = uart_bus_probe(dev, EC_UART_REGSHIFT, EC_UART_CLOCK, 0, 0);
+	return (status);
+}
+
+DRIVER_MODULE(uart, econaarm, uart_ec_driver, uart_devclass, 0, 0);


Property changes on: trunk/sys/arm/cavium/cns11xx/uart_bus_ec.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/cavium/cns11xx/uart_cpu_ec.c
===================================================================
--- trunk/sys/arm/cavium/cns11xx/uart_cpu_ec.c	                        (rev 0)
+++ trunk/sys/arm/cavium/cns11xx/uart_cpu_ec.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,85 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (C) 2009 Yohanes Nugroho <yohanes at gmail.com>
+ * All rights reserved.
+ *
+ * Developed by Semihalf.
+ *
+ * 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 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 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_uart.h"
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/cavium/cns11xx/uart_cpu_ec.c 264219 2014-04-07 05:33:30Z rpaulo $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/cons.h>
+
+#include <machine/bus.h>
+
+#include <dev/uart/uart.h>
+#include <dev/uart/uart_cpu.h>
+
+#include <sys/rman.h>
+
+#include <arm/cavium/cns11xx/econa_reg.h>
+#include <arm/cavium/cns11xx//econa_var.h>
+
+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 = &uart_ns8250_class;
+
+	di->ops = uart_getops(class);
+	di->bas.chan = 0;
+	di->bas.bst = obio_tag;
+
+	if (bus_space_map(di->bas.bst, ECONA_IO_BASE + ECONA_UART_BASE,
+	    ECONA_UART_SIZE,
+	    0, &di->bas.bsh) != 0) {
+		return (ENXIO);
+	}
+
+	di->baudrate = 0;
+	di->bas.regshft = EC_UART_REGSHIFT;
+	di->bas.rclk = EC_UART_CLOCK ;
+	di->databits = 8;
+	di->stopbits = 1;
+	di->parity = UART_PARITY_NONE;
+	uart_bus_space_mem = obio_tag;
+	uart_bus_space_io = NULL;
+
+	return (0);
+}


Property changes on: trunk/sys/arm/cavium/cns11xx/uart_cpu_ec.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/conf/APALIS-IMX6
===================================================================
--- trunk/sys/arm/conf/APALIS-IMX6	                        (rev 0)
+++ trunk/sys/arm/conf/APALIS-IMX6	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,31 @@
+# Kernel configuration for Toradex Apalis i.MX6
+#
+# 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: stable/10/sys/arm/conf/APALIS-IMX6 283500 2015-05-24 18:59:45Z ian $
+
+#NO_UNIVERSE
+
+include 	"IMX6"
+ident		APALIS-IMX6
+
+makeoptions	MODULES_OVERRIDE=""
+makeoptions	WITHOUT_MODULES="ahc"
+
+# Flattened Device Tree
+options 	FDT
+options 	FDT_DTB_STATIC
+makeoptions	FDT_DTS_FILE=apalis-imx6.dts


Property changes on: trunk/sys/arm/conf/APALIS-IMX6
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/ARMADAXP
===================================================================
--- trunk/sys/arm/conf/ARMADAXP	                        (rev 0)
+++ trunk/sys/arm/conf/ARMADAXP	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,136 @@
+#
+# Custom kernel for Marvell Armada XP
+#
+# 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: stable/10/sys/arm/conf/ARMADAXP 283387 2015-05-24 14:57:17Z ian $
+
+ident		MV-88F78XX0
+include		"../mv/armadaxp/std.mv78x60"
+
+options 	SOC_MV_ARMADAXP
+
+makeoptions	WERROR="-Werror"
+
+options 	HZ=1000
+#options 	SCHED_ULE		# ULE scheduler
+options 	SCHED_ULE		# ULE scheduler
+options 	PREEMPTION		# Enable kernel thread preemption
+options 	INET			# InterNETworking
+options 	INET6			# IPv6 communications protocols
+options 	SCTP			# Stream Control Transmission Protocol
+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
+options 	UFS_GJOURNAL		# Enable gjournal-based UFS journaling
+options 	QUOTA			# Enable disk quotas for UFS
+options 	NFSCL			# New Network Filesystem Client
+options 	NFSLOCKD		# Network Lock Manager
+options 	NFS_ROOT		# NFS usable as /, requires NFSCL
+options 	MSDOSFS			# MSDOS Filesystem
+options 	CD9660			# ISO 9660 Filesystem
+options 	PROCFS			# Process filesystem (requires PSEUDOFS)
+options 	PSEUDOFS		# Pseudo-filesystem framework
+options 	TMPFS			# Efficient memory filesystem
+options 	GEOM_PART_GPT		# GUID Partition Tables
+options 	GEOM_PART_BSD		# BSD partition scheme
+options 	GEOM_PART_MBR		# MBR partition scheme
+options 	KTRACE			# ktrace(1) support
+options 	SYSVSHM			# SYSV-style shared memory
+options 	SYSVMSG			# SYSV-style message queues
+options 	SYSVSEM			# SYSV-style semaphores
+options 	_KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
+options 	KBD_INSTALL_CDEV	# install a CDEV entry in /dev
+options 	VFP			# Enable floating point hardware support
+options 	SMP			# Enable multiple cores
+
+# Debugging for use in -current
+makeoptions	DEBUG=-g		# Build kernel with gdb(1) debug symbols
+#options 	VERBOSE_SYSINIT		# Enable verbose sysinit messages
+options 	ALT_BREAK_TO_DEBUGGER
+options 	KDB			# Enable kernel debugger support
+# For minimum debugger support (stable branch) use:
+options 	KDB_TRACE		# Print a stack trace for a panic
+# For full debugger support use this instead:
+options 	DDB			# Enable the kernel debugger
+options 	GDB
+#options 	INVARIANTS		# Enable calls of extra sanity checking
+#options 	INVARIANT_SUPPORT	# Extra sanity checks of internal structures, required by INVARIANTS
+#options 	WITNESS			# Enable checks to detect deadlocks and cycles
+#options 	WITNESS_SKIPSPIN	# Don't run witness on spinlocks for speed
+#options 	WITNESS_KDB
+#options 	DIAGNOSTIC
+#options 	KTR
+#options 	KTR_VERBOSE=0
+#options 	KTR_ENTRIES=16384
+#options 	KTR_MASK=(KTR_SPARE2)
+#options 	KTR_COMPILE=KTR_ALL
+
+# NFS root from boopt/dhcp
+options 	BOOTP
+options 	BOOTP_NFSROOT
+options 	BOOTP_NFSV3
+options 	BOOTP_WIRED_TO=mge0
+
+options 	ROOTDEVNAME=\"ufs:/dev/da0p1\"
+
+options 	MUTEX_NOINLINE
+options 	RWLOCK_NOINLINE
+options 	NO_FFS_SNAPSHOT
+options 	NO_SWAPPING
+
+# Pseudo devices
+device		random
+device		pty
+device		loop
+device		md
+
+# USB
+options 	USB_DEBUG		# enable debug msgs
+device		usb
+device		ehci
+device		umass
+device		scbus
+device		pass
+device		da
+
+# SATA
+device		mvs
+
+# Serial ports
+device		uart
+
+# I2C (TWSI)
+device		iic
+device		iicbus
+
+#Network
+device		ether
+device		mge			# Marvell Gigabit Ethernet controller
+device		mii
+device		e1000phy
+device		bpf
+options 	DEVICE_POLLING
+device		vlan
+
+#PCI/PCIE
+device		pci
+
+# Flattened Device Tree
+options 	FDT			# Configure using FDT/DTB data
+options 	FDT_DTB_STATIC
+makeoptions	FDT_DTS_FILE=db78460.dts


Property changes on: trunk/sys/arm/conf/ARMADAXP
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/ARNDALE
===================================================================
--- trunk/sys/arm/conf/ARNDALE	                        (rev 0)
+++ trunk/sys/arm/conf/ARNDALE	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,28 @@
+# Kernel configuration for Arndale Board (Exynos5 Dual development platform).
+#
+# 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: stable/10/sys/arm/conf/ARNDALE 278599 2015-02-11 22:35:32Z ian $
+
+#NO_UNIVERSE
+
+include		"EXYNOS5250"
+ident		ARNDALE
+
+#FDT
+options 	FDT
+options 	FDT_DTB_STATIC
+makeoptions	FDT_DTS_FILE=exynos5250-arndale.dts


Property changes on: trunk/sys/arm/conf/ARNDALE
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/ARNDALE-OCTA
===================================================================
--- trunk/sys/arm/conf/ARNDALE-OCTA	                        (rev 0)
+++ trunk/sys/arm/conf/ARNDALE-OCTA	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,28 @@
+# Kernel configuration for Arndale Octa Board (Exynos 5420)
+#
+# 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: stable/10/sys/arm/conf/ARNDALE-OCTA 278599 2015-02-11 22:35:32Z ian $
+
+#NO_UNIVERSE
+
+include		"EXYNOS5420"
+ident		ARNDALE-OCTA
+
+#FDT
+options 	FDT
+options 	FDT_DTB_STATIC
+makeoptions	FDT_DTS_FILE=exynos5420-arndale-octa.dts


Property changes on: trunk/sys/arm/conf/ARNDALE-OCTA
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/ATMEL
===================================================================
--- trunk/sys/arm/conf/ATMEL	                        (rev 0)
+++ trunk/sys/arm/conf/ATMEL	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,181 @@
+# Kernel configuration to test compile all the atmel bits with one
+# configuration.  This kernel will not (presently) boot.  Do not copy
+# it to create your own custom config file.
+#
+# $FreeBSD: stable/10/sys/arm/conf/ATMEL 283930 2015-06-02 21:24:47Z imp $
+
+ident		ATMEL
+
+include "../at91/std.atmel"
+
+# Typical values for most SoCs and board configurations.  Will not work for
+# at91sam9g45 or on some boards with non u-boot boot loaders.
+makeoptions	KERNPHYSADDR=0x20000000
+makeoptions	KERNVIRTADDR=0xc0000000
+options 	KERNPHYSADDR=0x20000000
+options 	KERNVIRTADDR=0xc0000000
+
+makeoptions	MODULES_OVERRIDE="dtb/atmel"
+
+# list all boards here, but not just yet (no multiboard in mainline).
+options 	ARM_MANY_BOARD
+device		at91_board_bwct
+device		at91_board_ethernut5
+device		at91_board_hl200
+device		at91_board_hl201
+device		at91_board_kb920x
+device		at91_board_qila9g20
+device		at91_board_sam9260ek
+device		at91_board_sam9g20ek
+device		at91_board_sam9x25ek
+device		at91_board_sn9g45
+device		at91_board_tsc4370
+
+#makeoptions	DEBUG=-g		# Build kernel with gdb(1) debug symbols
+
+options 	SCHED_4BSD		# 4BSD scheduler
+#options 	PREEMPTION		# Enable kernel thread preemption
+options 	INET			# InterNETworking
+options 	INET6			# IPv6 communications protocols
+options 	SCTP			# Stream Control Transmission Protocol
+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
+options 	UFS_GJOURNAL		# Enable gjournal-based UFS journaling
+options 	MD_ROOT			# MD is a potential root device
+options 	NFSCL			# New Network Filesystem Client
+options 	NFSD			# New Network Filesystem Server
+options 	NFSLOCKD		# Network Lock Manager
+options 	NFS_ROOT		# NFS usable as /, requires NFSCL
+options 	TMPFS			# Efficient memory filesystem
+options 	MSDOSFS			# MSDOS Filesystem
+options 	CD9660			# ISO 9660 Filesystem
+options 	PROCFS			# Process filesystem (requires PSEUDOFS)
+options 	PSEUDOFS		# Pseudo-filesystem framework
+options 	GEOM_PART_BSD		# BSD partition scheme
+options 	GEOM_PART_MBR		# MBR partition scheme
+options 	GEOM_PART_GPT		# GUID Partition Tables.
+options 	GEOM_LABEL		# Provides labelization
+options 	COMPAT_FREEBSD5		# Compatible with FreeBSD5
+options 	COMPAT_FREEBSD6		# Compatible with FreeBSD6
+options 	COMPAT_FREEBSD7		# Compatible with FreeBSD7
+options 	SCSI_DELAY=5000		# Delay (in ms) before probing SCSI
+options 	KTRACE			# ktrace(1) support
+options 	STACK			# stack(9) support
+options 	SYSVSHM			# SYSV-style shared memory
+options 	SYSVMSG			# SYSV-style message queues
+options 	SYSVSEM			# SYSV-style semaphores
+options 	_KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
+options 	PRINTF_BUFR_SIZE=128	# Prevent printf output being interspersed.
+#options 	HWPMC_HOOKS		# Necessary kernel hooks for hwpmc(4)
+#options 	AUDIT			# Security event auditing
+#options 	CAPABILITY_MODE		# Capsicum capability mode
+#options 	CAPABILITIES		# Capsicum capabilities
+#options 	MAC			# TrustedBSD MAC Framework
+#options 	INCLUDE_CONFIG_FILE	# Include this file in kernel
+
+# required for netbooting
+options 	BOOTP
+options 	BOOTP_COMPAT
+options 	BOOTP_NFSROOT
+options 	BOOTP_NFSV3
+options 	BOOTP_WIRED_TO=ate0
+
+# alternatively, boot from a MMC/SD memory card
+#options 	ROOTDEVNAME=\"ufs:/dev/mmcsd0a\"
+
+# kernel/memory size reduction
+options 	MUTEX_NOINLINE
+options 	NO_FFS_SNAPSHOT
+options 	NO_SWAPPING
+options 	NO_SYSCTL_DESCR
+options 	RWLOCK_NOINLINE
+
+# Debugging support.  Always need this:
+options 	KDB			# Enable kernel debugger support.
+# For minimum debugger support (stable branch) use:
+options 	KDB_TRACE		# Print a stack trace for a panic.
+# For full debugger support use this instead:
+options 	DDB			# Support DDB.
+options 	GDB			# Support remote GDB.
+#options 	DEADLKRES		# Enable the deadlock resolver
+#options 	INVARIANTS		# Enable calls of extra sanity checking
+#options 	INVARIANT_SUPPORT	# Extra sanity checks of internal structures, required by INVARIANTS
+#options 	WITNESS			# Enable checks to detect deadlocks and cycles
+#options 	WITNESS_SKIPSPIN	# Don't run witness on spinlocks for speed
+#options 	MALLOC_DEBUG_MAXZONES=8	# Separate malloc(9) zones
+
+# The `bpf' device enables the Berkeley Packet Filter.
+# Be aware of the administrative consequences of enabling this!
+# Note that 'bpf' is required for DHCP.
+device		bpf			# Berkeley packet filter
+
+# Ethernet
+device		mii			# Minimal MII support
+device		ate			# Atmel AT91 Ethernet friver
+
+# I2C
+device		at91_twi		# Atmel AT91 Two-wire Interface
+device		iic			# I2C generic I/O device driver
+device		iicbus			# I2C bus system
+device		pcf8563			# NXP PCF8563 clock/calendar
+
+# MMC/SD
+device		at91_mci		# Atmel AT91 Multimedia Card Interface
+options 	AT91_MCI_HAS_4WIRE
+device		mmc			# MMC/SD bus
+device		mmcsd			# MMC/SD memory card
+
+# DataFlash
+device		at91_spi		# Atmel AT91 Serial Peripheral Interface
+device		spibus			# SPI bus
+device		at45d			# Atmel AT45D
+device		geom_map		# GEOM partition mapping
+
+# Pseudo devices.
+device		loop			# Network loopback
+device		random			# Entropy device
+device		ether			# Ethernet support
+device		vlan			# 802.1Q VLAN support
+device		tun			# Packet tunnel.
+device		md			# Memory "disks"
+device		gif			# IPv6 and IPv4 tunneling
+device		faith			# IPv6-to-IPv4 relaying (translation)
+#device		firmware		# firmware assist module
+
+# 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 (COM) ports
+device		uart			# Multi-uart driver
+options 	ALT_BREAK_TO_DEBUGGER
+
+# USB support
+options 	USB_DEBUG		# enable debug msgs
+device		ohci			# OHCI USB interface
+device		usb			# USB Bus (required)
+device		umass			# Disks/Mass storage - Requires scbus and da
+
+# USB device (gadget) support
+device		at91_dci		# Atmel's usb device
+device		usfs			# emulate a flash
+device		cdce			# emulate an ethernet
+device		usb_template		# Control of the gadget
+
+# watchdog
+device		at91_wdt		# Atmel AT91 Watchdog Timer
+
+device		at91_rtc
+device		at91_ssc
+#device		at91_tc			# missing?
+
+# NAND Flash - Reference design has Samsung 256MB but others possible
+device		nand			# NAND interface on CS3


Property changes on: trunk/sys/arm/conf/ATMEL
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/AVILA
===================================================================
--- trunk/sys/arm/conf/AVILA	                        (rev 0)
+++ trunk/sys/arm/conf/AVILA	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,158 @@
+# AVILA -- Gateworks Avila XScale board
+# kernel configuration file for FreeBSD/arm
+#
+# For more information on this file, please read 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: stable/10/sys/arm/conf/AVILA 271428 2014-09-11 15:36:36Z ian $
+
+ident		AVILA
+
+include		"../xscale/ixp425/std.ixp425"
+# NB: memory mapping is defined in std.avila
+include		"../xscale/ixp425/std.avila"
+options 	XSCALE_CACHE_READ_WRITE_ALLOCATE
+#To statically compile in device wiring instead of /boot/device.hints
+hints		"AVILA.hints"		# Default places to look for devices.
+makeoptions	MODULES_OVERRIDE=""
+
+makeoptions	DEBUG=-g		# Build kernel with gdb(1) debug symbols
+makeoptions	CONF_CFLAGS=-mcpu=xscale
+#options 	HZ=1000
+options 	HZ=100
+options 	DEVICE_POLLING
+
+# Debugging for use in -current
+options 	KDB
+#options 	GDB
+options 	DDB			# Enable the kernel debugger
+#options 	DEADLKRES		# Enable the deadlock resolver
+#options 	INVARIANTS		# Enable calls of extra sanity checking
+#options 	INVARIANT_SUPPORT	# Extra sanity checks of internal structures, required by INVARIANTS
+#options 	WITNESS			# Enable checks to detect deadlocks and cycles
+#options 	WITNESS_SKIPSPIN	# Don't run witness on spinlocks for speed
+#options 	DIAGNOSTIC
+
+options 	SCHED_4BSD		# 4BSD scheduler
+options 	INET			# InterNETworking
+options 	GEOM_PART_BSD		# BSD partition scheme
+options 	GEOM_PART_MBR		# MBR partition scheme
+options 	TMPFS			# Efficient memory filesystem
+options 	FFS			# Berkeley Fast Filesystem
+options 	SOFTUPDATES		# Enable FFS soft updates support
+options 	NFSCL			# New Network Filesystem Client
+options 	NFS_ROOT		# NFS usable as /, requires NFSCL
+options 	BOOTP
+options 	BOOTP_NFSROOT
+options 	BOOTP_NFSV3
+options 	BOOTP_WIRED_TO=npe0
+#options 	BOOTP_WIRED_TO=ath0
+#options 	BOOTP_WIRED_TO=rl0
+options 	BOOTP_COMPAT
+#options 	PREEMPTION
+#options 	VERBOSE_SYSINIT
+
+# Hardware performance counters
+options 	HWPMC_HOOKS
+device		hwpmc
+
+#device		saarm
+
+device		pci
+device		uart
+
+device		ixpwdog			# watchdog timer
+device		cfi			# flash support
+device		cfid			# flash disk support
+device		geom_redboot		# redboot fis parser
+
+# I2C Bus
+device		iicbus
+device		iicbb
+device		iic
+
+device		ixpiic			# I2C bus glue
+device		ds1672			# DS1672 on I2C bus
+device		ad7418			# AD7418 on I2C bus
+
+device		avila_led
+
+device		gpio
+device		gpioled
+device		avila_gpio		# GPIO pins on J8
+
+device		ata
+device		avila_ata		# Gateworks CF/IDE support
+
+device		npe			# Network Processing Engine
+device		npe_fw
+device		firmware
+device		qmgr			# Q Manager (required by npe)
+device		mii			# NB: required by npe
+device		ether
+device		bpf
+
+device		loop
+device		if_bridge
+
+device		md
+device		random			# Entropy device
+
+# Wireless NIC cards
+device		wlan			# 802.11 support
+options 	IEEE80211_DEBUG
+options 	IEEE80211_SUPPORT_TDMA
+options 	IEEE80211_SUPPORT_MESH
+device		wlan_wep		# 802.11 WEP support
+device		wlan_ccmp		# 802.11 CCMP support
+device		wlan_tkip		# 802.11 TKIP support
+device		wlan_xauth
+
+device		ath			# Atheros NICs
+device		ath_pci			# Atheros pci/cardbus glue
+options 	ATH_DEBUG
+options 	ATH_DIAGAPI
+#options 	ATH_TX99_DIAG
+device		ath_rate_sample		# SampleRate tx rate control for ath
+
+#options 	AH_DEBUG
+#options 	AH_ASSERT
+#device		ath_ar5210
+#device		ath_ar5211
+device		ath_ar5212
+device		ath_rf2413
+device		ath_rf2417
+device		ath_rf2425
+device		ath_rf5111
+device		ath_rf5112
+device		ath_rf5413
+#
+device		ath_ar5416
+options 	AH_SUPPORT_AR5416
+device		ath_ar9160
+device		ath_ar9280
+
+device		usb
+#options 	USB_DEBUG
+device		ohci
+device		ehci
+device		umass
+device		scbus			# SCSI bus (required for ATA/SCSI)
+device		da			# Direct Access (disks)
+device		pass			# Passthrough device (direct ATA/SCSI access)
+
+#device		ural
+#device		zyd
+#device		wlan_amrr


Property changes on: trunk/sys/arm/conf/AVILA
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/AVILA.hints
===================================================================
--- trunk/sys/arm/conf/AVILA.hints	                        (rev 0)
+++ trunk/sys/arm/conf/AVILA.hints	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,53 @@
+# $FreeBSD: stable/10/sys/arm/conf/AVILA.hints 239699 2012-08-26 01:21:02Z gjb $
+
+#
+# Device wiring for the Gateworks Avila 2384.
+#
+
+# DBGU is unit 0
+hint.uart.0.at="ixp0"
+hint.uart.0.addr=0xc8000000
+hint.uart.0.irq=15
+hint.uart.0.flags=0x10
+hint.uart.0.ier_rxbits=0x5d	# NB: need UUE+RTOIE
+# USART0 is unit 1
+hint.uart.1.at="ixp0"
+hint.uart.1.addr=0xc8001000
+hint.uart.1.irq=13
+hint.uart.1.ier_rxbits=0x5d	# NB: need UUE+RTOIE
+
+# NPE Hardware Queue Manager
+hint.ixpqmgr.0.at="ixp0"
+
+# NPE wired NICs, requires ixpqmgr
+hint.npe.0.at="ixp0"
+hint.npe.0.npeid="B"
+hint.npe.0.mac="B"
+hint.npe.0.mii="B"
+hint.npe.0.phy=0
+hint.npe.1.at="ixp0"
+hint.npe.1.npeid="C"
+hint.npe.1.mac="C"
+hint.npe.1.mii="B"
+hint.npe.1.phy=1
+
+# FLASH
+hint.cfi.0.at="ixp0"
+hint.cfi.0.addr=0x50000000
+
+# CF IDE controller
+hint.ata_avila.0.at="ixp0"
+
+# Front Panel LED
+hint.led_avila.0.at="ixp0"
+
+# GPIO pins
+hint.gpio_avila.0.at="ixp0"
+
+# Analog Devices AD7418 temperature sensor
+hint.ad7418.0.at="iicbus0"
+hint.ad7418.0.addr=0x50
+
+# Dallas Semiconductor DS1672 RTC
+hint.ds1672_rtc.0.at="iicbus0"
+hint.ds1672_rtc.0.addr=0xd0


Property changes on: trunk/sys/arm/conf/AVILA.hints
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/BEAGLEBONE
===================================================================
--- trunk/sys/arm/conf/BEAGLEBONE	                        (rev 0)
+++ trunk/sys/arm/conf/BEAGLEBONE	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,161 @@
+#
+# BEAGLEBONE -- Custom configuration for the BeagleBone ARM development
+# platforms, check out http://www.beagleboard.org/bone and
+# http://www.beagleboard.org/black. This kernel config file is used for the
+# original BeagleBone and the BeagleBone Black.
+#
+# 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: stable/10/sys/arm/conf/BEAGLEBONE 287082 2015-08-23 20:50:22Z ian $
+
+ident		BEAGLEBONE
+
+include		"../ti/am335x/std.am335x"
+
+makeoptions	MODULES_EXTRA="dtb/am335x"
+
+options 	HZ=100
+options 	SCHED_4BSD		# 4BSD scheduler
+options 	PREEMPTION		# Enable kernel thread preemption
+options 	INET			# InterNETworking
+options 	INET6			# IPv6 communications protocols
+options 	SCTP			# Stream Control Transmission Protocol
+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
+options 	UFS_GJOURNAL		# Enable gjournal-based UFS journaling
+options 	QUOTA			# Enable disk quotas for UFS
+options 	NFSCL			# New Network Filesystem Client
+options 	NFSLOCKD		# Network Lock Manager
+options 	NFS_ROOT		# NFS usable as /, requires NFSCL
+options 	MSDOSFS			# MSDOS Filesystem
+options 	CD9660			# ISO 9660 Filesystem
+options 	PROCFS			# Process filesystem (requires PSEUDOFS)
+options 	PSEUDOFS		# Pseudo-filesystem framework
+options 	TMPFS			# Efficient memory filesystem
+options 	GEOM_PART_GPT		# GUID Partition Tables
+options 	GEOM_PART_BSD		# BSD partition scheme
+options 	GEOM_PART_MBR		# MBR partition scheme
+options 	GEOM_LABEL		# Provides labelization 
+options 	COMPAT_43		# Compatible with BSD 4.3 [KEEP THIS!]
+options 	SCSI_DELAY=5000		# Delay (in ms) before probing SCSI
+options 	KTRACE			# ktrace(1) support
+options 	SYSVSHM			# SYSV-style shared memory
+options 	SYSVMSG			# SYSV-style message queues
+options 	SYSVSEM			# SYSV-style semaphores
+options 	_KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
+options 	KBD_INSTALL_CDEV	# install a CDEV entry in /dev
+options 	FREEBSD_BOOT_LOADER	# Process metadata passed from loader(8)
+options 	VFP			# Enable floating point hardware support
+
+# Debugging for use in -current
+makeoptions	DEBUG=-g		# Build kernel with gdb(1) debug symbols
+options 	ALT_BREAK_TO_DEBUGGER
+#options 	VERBOSE_SYSINIT		# Enable verbose sysinit messages
+options 	KDB			# Enable kernel debugger support
+# For minimum debugger support (stable branch) use:
+#options 	KDB_TRACE		# Print a stack trace for a panic
+# For full debugger support use this instead:
+options 	DDB			# Enable the kernel debugger
+#options 	INVARIANTS		# Enable calls of extra sanity checking
+#options 	INVARIANT_SUPPORT	# Extra sanity checks of internal structures, required by INVARIANTS
+#options 	WITNESS			# Enable checks to detect deadlocks and cycles
+#options 	WITNESS_SKIPSPIN	# Don't run witness on spinlocks for speed
+#options 	DIAGNOSTIC
+
+# NFS server support
+#options 	NFSD
+
+# NFS root from boopt/dhcp
+#options 	BOOTP
+#options 	BOOTP_NFSROOT
+#options 	BOOTP_COMPAT
+#options 	BOOTP_NFSV3
+#options 	BOOTP_WIRED_TO=cpsw0
+
+# Boot device is 2nd slice on MMC/SD card
+options 	ROOTDEVNAME=\"ufs:mmcsd0s2\"
+
+# MMC/SD/SDIO Card slot support
+device		mmc			# mmc/sd bus
+device		mmcsd			# mmc/sd flash cards
+device		sdhci			# mmc/sd host controller
+
+# I2C support
+device		iicbus
+device		iic
+device		ti_i2c
+device		am335x_pmic		# AM335x Power Management IC (TPC65217)
+
+device		am335x_rtc		# RTC support (power management only)
+
+# Console and misc
+device		uart
+device		uart_ns8250
+device		pty
+device		snp
+device		md
+device		random			# Entropy device
+
+# GPIO
+device		gpio
+device		gpioled
+
+# ADC support
+device		ti_adc
+
+# Watchdog support
+# If we don't enable the watchdog driver, the system could potentially
+# reboot automatically because the boot loader might have enabled the
+# watchdog.
+device		ti_wdt
+
+# TI Programmable Realtime Unit support
+device		ti_pruss
+
+# Mailbox support
+device		ti_mbox
+
+# USB support
+device		usb
+options 	USB_HOST_ALIGN=64	# Align usb buffers to cache line size.
+options 	USB_DEBUG
+#options 	USB_REQ_DEBUG
+#options 	USB_VERBOSE
+device		musb
+device		umass
+device		scbus			# SCSI bus (required for ATA/SCSI)
+device		da			# Direct Access (disks)
+
+# Ethernet
+device		loop
+device		ether
+device		mii
+device		smscphy
+device		cpsw
+device		bpf
+
+# USB Ethernet support, requires miibus
+device		miibus
+device		axe			# ASIX Electronics USB Ethernet
+
+# Device mode support and USFS template
+device		usb_template    	# Control of the gadget
+device		usfs
+
+# Flattened Device Tree
+options 	FDT			# Configure using FDT/DTB data


Property changes on: trunk/sys/arm/conf/BEAGLEBONE
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/BWCT
===================================================================
--- trunk/sys/arm/conf/BWCT	                        (rev 0)
+++ trunk/sys/arm/conf/BWCT	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,114 @@
+# BWCT -- Custom kernel configuration for the AT91RM9200 boards from bwct.de.
+#
+# For more information on this file, please read 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: stable/10/sys/arm/conf/BWCT 266383 2014-05-18 00:21:14Z ian $
+
+#NO_UNIVERSE
+
+ident		BWCT
+
+options 	VERBOSE_INIT_ARM
+
+include		"../at91/std.bwct"
+
+#To statically compile in device wiring instead of /boot/device.hints
+hints		"BWCT.hints"
+makeoptions	MODULES_OVERRIDE=""
+
+#makeoptions	DEBUG=-g		# Build kernel with gdb(1) debug symbols
+options 	DDB
+options 	KDB
+options 	BREAK_TO_DEBUGGER
+options 	ALT_BREAK_TO_DEBUGGER
+
+options 	SCHED_4BSD		# 4BSD scheduler
+options 	INET			# InterNETworking
+#options 	INET6			# IPv6 communications protocols
+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
+#options 	MD_ROOT			# MD is a potential root device
+#options 	MD_ROOT_SIZE=4096	# 4MB ram disk
+#options 	ROOTDEVNAME=\"ufs:md0\"
+#options 	ROOTDEVNAME=\"ufs:/dev/mmcsd0s1a\"
+options 	NFSCL			# New Network Filesystem Client
+#options 	NFSD			# New Network Filesystem Server
+#options 	NFSLOCKD		# Network Lock Manager
+options 	NFS_ROOT		# NFS usable as /, requires NFSCL
+options 	BOOTP_NFSROOT
+options 	BOOTP
+
+options 	GEOM_PART_BSD		# BSD partition scheme
+options 	GEOM_PART_MBR		# MBR partition scheme
+options 	TMPFS			# Efficient memory filesystem
+#options 	MSDOSFS			# MSDOS Filesystem
+#options 	CD9660			# ISO 9660 Filesystem
+#options 	PROCFS			# Process filesystem (requires PSEUDOFS)
+options 	PSEUDOFS		# Pseudo-filesystem framework
+#options 	SCSI_DELAY=5000		# Delay (in ms) before probing SCSI
+#options 	KTRACE			# ktrace(1) support
+options 	SYSVSHM			# SYSV-style shared memory
+options 	SYSVMSG			# SYSV-style message queues
+options 	SYSVSEM			# SYSV-style semaphores
+options 	_KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions
+#options 	NO_SYSCTL_DESCR
+options 	MUTEX_NOINLINE
+options 	RWLOCK_NOINLINE
+options 	NO_FFS_SNAPSHOT
+options 	NO_SWAPPING
+device		loop
+device		random
+device		ether
+device		vlan
+device		uart
+device		ate
+device		mii
+device		rlswitch
+
+# Debugging for use in -current
+#options 	DEADLKRES		# Enable the deadlock resolver
+#options 	INVARIANTS		# Enable calls of extra sanity checking
+#options 	INVARIANT_SUPPORT	# Extra sanity checks of internal structures, required by INVARIANTS
+#options 	WITNESS			# Enable checks to detect deadlocks and cycles
+#options 	WITNESS_SKIPSPIN	# Don't run witness on spinlocks for speed
+#options 	DIAGNOSTIC
+
+device		md
+device		at91_twi		# TWI: Two Wire Interface
+device		at91_spi		# SPI:
+device		at91_ssc
+device		at91_mci
+device		mmc			# mmc/sd bus
+device		mmcsd			# mmc/sd flash cards
+# iic
+device		iic
+device		iicbus
+device		ds1672			# DS1672 on I2C bus
+#device		iicsmb			# smb over i2c bridge
+#device		smbus			# Bus support, required for smb below.
+#device		smb
+# SPI bus
+device		spibus
+#device		at45d			# at45db642 and maybe others
+
+device		bpf			# Berkeley packet filter
+
+#options USB_DEBUG
+#device		ohci
+#device		usb
+#device		umass			# Disks/Mass storage - Requires scbus and da


Property changes on: trunk/sys/arm/conf/BWCT
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/BWCT.hints
===================================================================
--- trunk/sys/arm/conf/BWCT.hints	                        (rev 0)
+++ trunk/sys/arm/conf/BWCT.hints	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,13 @@
+# $FreeBSD: stable/10/sys/arm/conf/BWCT.hints 215124 2010-11-11 15:02:14Z ticso $
+
+# Dallas Semiconductor DS1672 RTC sitting on the I2C bus
+hint.ds1672_rtc.0.at="iicbus0"
+hint.ds1672_rtc.0.addr=0xd0
+
+# National Semiconductor LM75 temperature sensor sitting on the I2C bus
+hint.lm75.0.at="iicbus0"
+hint.lm75.0.addr=0x9e
+
+# Atmel SPIflash sitting on the spibus
+hint.at45d.0.at="spibus0"
+hint.at45d.0.addr=0x00


Property changes on: trunk/sys/arm/conf/BWCT.hints
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/CAMBRIA
===================================================================
--- trunk/sys/arm/conf/CAMBRIA	                        (rev 0)
+++ trunk/sys/arm/conf/CAMBRIA	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,152 @@
+# CAMBRIA -- Gateworks Cambria 235x boards
+# kernel configuration file for FreeBSD/arm
+#
+# For more information on this file, please read 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: stable/10/sys/arm/conf/CAMBRIA 271428 2014-09-11 15:36:36Z ian $
+
+ident		CAMBRIA
+
+include		"../xscale/ixp425/std.ixp435"
+# NB: memory mapping is defined in std.avila
+include		"../xscale/ixp425/std.avila"
+options 	XSCALE_CACHE_READ_WRITE_ALLOCATE
+#To statically compile in device wiring instead of /boot/device.hints
+hints		"CAMBRIA.hints"		# Default places to look for devices.
+
+makeoptions	DEBUG=-g		# Build kernel with gdb(1) debug symbols
+makeoptions	CONF_CFLAGS=-mcpu=xscale
+makeoptions	MODULES_OVERRIDE=""
+#options 	HZ=1000
+options 	HZ=100
+options 	DEVICE_POLLING
+
+# Debugging for use in -current
+options 	KDB
+#options 	GDB
+options 	DDB			# Enable the kernel debugger
+#options 	DEADLKRES		# Enable the deadlock resolver
+#options 	INVARIANTS		# Enable calls of extra sanity checking
+#options 	INVARIANT_SUPPORT	# Extra sanity checks of internal structures, required by INVARIANTS
+#options 	WITNESS			# Enable checks to detect deadlocks and cycles
+#options 	WITNESS_SKIPSPIN	# Don't run witness on spinlocks for speed
+#options 	DIAGNOSTIC
+
+options 	SCHED_4BSD		# 4BSD scheduler
+#options 	PREEMPTION
+options 	INET			# InterNETworking
+options 	GEOM_PART_BSD		# BSD partition scheme
+options 	GEOM_PART_MBR		# MBR partition scheme
+options 	TMPFS			# Efficient memory filesystem
+options 	FFS			# Berkeley Fast Filesystem
+options 	SOFTUPDATES		# Enable FFS soft updates support
+options 	NFSCL			# New Network Filesystem Client
+options 	NFS_ROOT		# NFS usable as /, requires NFSCL
+options 	BOOTP
+options 	BOOTP_NFSROOT
+options 	BOOTP_NFSV3
+options 	BOOTP_WIRED_TO=npe0
+options 	BOOTP_COMPAT
+
+# Hardware performance counters
+options 	HWPMC_HOOKS
+device		hwpmc
+
+#options 	VERBOSE_SYSINIT
+options 	VERBOSE_INIT_ARM
+
+#device		saarm
+
+device		pci
+device		uart
+
+device		ixpwdog			# watchdog timer
+
+options 	IXP4XX_FLASH_SIZE=0x02000000 # stock 2358 comes w/ 32M
+device		cfi			# flash support
+device		cfid			# flash disk support
+device		geom_redboot		# redboot fis parser
+
+# I2C Bus
+device		iicbus
+device		iicbb
+device		iic
+
+device		ixpiic			# I2C bus glue
+device		ds1672			# DS1672 on I2C bus
+device		ad7418			# AD7418 on I2C bus
+
+device		cambria_fled		# Font Panel LED on I2C bus
+device		cambria_led		# 8-LED latch
+
+device		gpio
+device		gpioled
+device		cambria_gpio		# GPIO pins on J11
+
+device		ata
+device		avila_ata		# Gateworks CF/IDE support
+
+device		npe			# Network Processing Engine
+device		npe_fw
+device		firmware
+device		qmgr			# Q Manager (required by npe)
+device		mii			# NB: required by npe
+device		ether
+device		bpf
+
+device		loop
+device		if_bridge
+
+device		md
+device		random			# Entropy device
+
+# Wireless NIC cards
+device		wlan			# 802.11 support
+options 	IEEE80211_DEBUG
+options 	IEEE80211_SUPPORT_TDMA
+options 	IEEE80211_SUPPORT_MESH
+device		wlan_wep		# 802.11 WEP support
+device		wlan_ccmp		# 802.11 CCMP support
+device		wlan_tkip		# 802.11 TKIP support
+device		wlan_xauth
+
+device		ath			# Atheros NICs
+device		ath_pci			# Atheros pci/cardbus glue
+options 	ATH_DEBUG
+options 	ATH_DIAGAPI
+options 	ATH_ENABLE_DFS
+options 	ATH_ENABLE_11N
+#options 	ATH_TX99_DIAG
+device		ath_rate_sample		# SampleRate tx rate control for ath
+
+options 	AH_DEBUG
+options 	AH_PRIVATE_DIAG
+options 	AH_SUPPORT_AR5416	# NB: for 11n descriptor format
+device		ath_hal
+
+# NB: 2 USB 2.0 ports standard
+device		usb
+options 	USB_EHCI_BIG_ENDIAN_DESC # handle big-endian byte order
+#options 	USB_DEBUG
+device		ehci
+device		umass
+device		scbus			# SCSI bus (required for ATA/SCSI)
+device		da			# Direct Access (disks)
+device		pass			# Passthrough device (direct ATA/SCSI access)
+
+#device		ural
+#device		zyd
+#device		wlan_amrr


Property changes on: trunk/sys/arm/conf/CAMBRIA
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/CAMBRIA.hints
===================================================================
--- trunk/sys/arm/conf/CAMBRIA.hints	                        (rev 0)
+++ trunk/sys/arm/conf/CAMBRIA.hints	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,75 @@
+# $FreeBSD: stable/10/sys/arm/conf/CAMBRIA.hints 239699 2012-08-26 01:21:02Z gjb $
+
+#
+# Device wiring for the Gateworks Cambria 2358.
+#
+
+# DBGU is unit 0
+hint.uart.0.at="ixp0"
+hint.uart.0.addr=0xc8000000
+hint.uart.0.irq=15
+hint.uart.0.flags=0x10
+hint.uart.0.ier_rxbits=0x5d	# NB: need UUE+RTOIE
+
+# NB: no UART1 on ixp435
+
+# optional GPS serial port
+#hint.uart.1.at="ixp0"
+#hint.uart.1.addr=0x53fc0000
+#hint.uart.1.irq=20
+#hint.uart.1.ier_rxbits=0x1
+#hint.uart.1.rclk=1843200
+# optional RS485 serial port
+#hint.uart.2.at="ixp0"
+#hint.uart.2.addr=0x53f80000
+#hint.uart.2.irq=21
+#hint.uart.2.rclk=1843200
+
+# NPE Hardware Queue Manager
+hint.ixpqmgr.0.at="ixp0"
+
+# NPE wired NICs, requires ixpqmgr
+hint.npe.0.at="ixp0"
+hint.npe.0.npeid="C"
+hint.npe.0.mac="C"
+hint.npe.0.mii="C"
+hint.npe.0.phy=1
+hint.npe.1.at="ixp0"
+hint.npe.1.npeid="A"
+hint.npe.1.mac="A"
+hint.npe.1.mii="C"
+hint.npe.1.phy=2
+
+# FLASH
+hint.cfi.0.at="ixp0"
+hint.cfi.0.addr=0x50000000
+
+# CF IDE controller
+hint.ata_avila.0.at="ixp0"
+
+# Front Panel LED
+hint.fled.0.at="iicbus0"
+hint.fled.0.addr=0x5a
+
+# Octal LED Latch
+hint.led_cambria.0.at="ixp0"
+
+# GPIO pins
+hint.gpio_cambria.0.at="iicbus0"
+hint.gpio_cambria.0.addr=0x56
+
+# Analog Devices AD7418 temperature sensor
+hint.ad7418.0.at="iicbus0"
+hint.ad7418.0.addr=0x50
+
+# Dallas Semiconductor DS1672 RTC
+hint.ds1672_rtc.0.at="iicbus0"
+hint.ds1672_rtc.0.addr=0xd0
+
+# USB is part of the chip
+hint.ehci.0.at="ixp0"
+hint.ehci.0.addr=0xcd000000
+hint.ehci.0.irq=32
+hint.ehci.1.at="ixp0"
+hint.ehci.1.addr=0xce000000
+hint.ehci.1.irq=33


Property changes on: trunk/sys/arm/conf/CAMBRIA.hints
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/CHROMEBOOK
===================================================================
--- trunk/sys/arm/conf/CHROMEBOOK	                        (rev 0)
+++ trunk/sys/arm/conf/CHROMEBOOK	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,38 @@
+# Kernel configuration for Samsung Chromebook (Exynos5 Dual machine).
+#
+# 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: stable/10/sys/arm/conf/CHROMEBOOK 278599 2015-02-11 22:35:32Z ian $
+
+include		"EXYNOS5250"
+ident		CHROMEBOOK
+
+hints		"CHROMEBOOK.hints"
+
+device		chrome_ec	# Chrome Embedded Controller
+device		chrome_kb	# Chrome Keyboard
+
+# Framebuffer
+device		vt
+device		kbdmux
+options 	SC_DFLT_FONT		# compile font in
+makeoptions	SC_DFLT_FONT=cp437
+device		ukbd
+
+#FDT
+options 	FDT
+options 	FDT_DTB_STATIC
+makeoptions	FDT_DTS_FILE=exynos5250-chromebook.dts


Property changes on: trunk/sys/arm/conf/CHROMEBOOK
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/CHROMEBOOK.hints
===================================================================
--- trunk/sys/arm/conf/CHROMEBOOK.hints	                        (rev 0)
+++ trunk/sys/arm/conf/CHROMEBOOK.hints	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,5 @@
+# $FreeBSD: stable/10/sys/arm/conf/CHROMEBOOK.hints 266341 2014-05-17 19:37:04Z ian $
+
+# Chrome Embedded Controller
+hint.chrome_ec.0.at="iicbus0"
+hint.chrome_ec.0.addr=0x1e


Property changes on: trunk/sys/arm/conf/CHROMEBOOK.hints
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/CNS11XXNAS
===================================================================
--- trunk/sys/arm/conf/CNS11XXNAS	                        (rev 0)
+++ trunk/sys/arm/conf/CNS11XXNAS	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,125 @@
+# CNS11XXNAS -  StarSemi STR9104/Cavium CNS1102 NAS
+# kernel configuration file for FreeBSD/arm
+#
+# For more information on this file, please read 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: stable/10/sys/arm/conf/CNS11XXNAS 283368 2015-05-24 14:25:03Z ian $
+
+ident		CNS11XXNAS
+
+#options 	PHYSADDR=0x10000000
+#options 	KERNPHYSADDR=0x10200000
+#options 	KERNVIRTADDR=0xc0200000	# Used in ldscript.arm
+#options 	FLASHADDR=0x50000000
+#options 	LOADERRAMADDR=0x00000000
+
+include		"../cavium/cns11xx/std.econa"
+
+makeoptions	MODULES_OVERRIDE=""
+
+makeoptions	DEBUG=-g		# Build kernel with gdb(1) debug symbols
+options 	HZ=100
+options 	DEVICE_POLLING
+
+# Debugging for use in -current
+options 	KDB
+#options 	GDB
+options 	DDB			# Enable the kernel debugger
+#options 	DEADLKRES		# Enable the deadlock resolver
+#options 	INVARIANTS		# Enable calls of extra sanity checking
+#options 	INVARIANT_SUPPORT	# Extra sanity checks of internal structures, required by INVARIANTS
+#options 	WITNESS			# Enable checks to detect deadlocks and cycles
+##options 	WITNESS_SKIPSPIN	# Don't run witness on spinlocks for speed
+#options 	DIAGNOSTIC
+
+
+#options 	COMPAT_FREEBSD5
+#options 	COMPAT_FREEBSD6
+#options 	COMPAT_FREEBSD7n
+
+
+options 	SCHED_ULE		# ULE scheduler
+#options 	SCHED_4BSD		# 4BSD scheduler
+options 	GEOM_PART_BSD		# BSD partition scheme
+options 	GEOM_PART_MBR		# MBR partition scheme
+options 	GEOM_PART_GPT		# GUID Partition Tables.
+#options 	GEOM_PART_EBR
+#options 	GEOM_PART_EBR_COMPAT
+options 	GEOM_LABEL		# Provides labelization
+
+
+options 	INET			# InterNETworking
+options 	INET6			# IPv6 communications protocols
+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
+options 	NFSCL			# New Network Filesystem Client
+#options 	NFSD			# New Network Filesystem Server
+#options 	NFSLOCKD		# Network Lock Manager
+options 	NFS_ROOT		# NFS usable as /, requires NFSCL
+options 	TMPFS			# Efficient memory filesystem
+options 	MSDOSFS			# MSDOS Filesystem
+#options 	CD9660			# ISO 9660 Filesystem
+#options 	PROCFS			# Process filesystem (requires PSEUDOFS)
+options 	PSEUDOFS		# Pseudo-filesystem framework
+options 	SCSI_DELAY=5000		# Delay (in ms) before probing SCSI
+options 	KTRACE			# ktrace(1) support
+options 	SYSVSHM			# SYSV-style shared memory
+options 	SYSVMSG			# SYSV-style message queues
+options 	SYSVSEM			# SYSV-style semaphores
+options 	_KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions
+options 	MUTEX_NOINLINE		# Mutex inlines are space hogs
+options 	RWLOCK_NOINLINE		# rwlock inlines are space hogs
+options 	SX_NOINLINE		# sx inliens are space hogs
+#options 	BOOTP
+#options 	BOOTP_NFSROOT
+#options 	BOOTP_NFSV3
+#options 	BOOTP_WIRED_TO=npe0
+#options 	BOOTP_COMPAT
+
+#device		pci
+device		uart
+
+
+device		firmware
+device		mii			# Minimal mii routines
+device		ether
+device		bpf
+
+device		loop
+
+device		md
+device		random			# Entropy device
+
+
+device		usb
+#options 	USB_DEBUG
+device		ohci
+device		ehci
+device		umass
+device		scbus			# SCSI bus (required for ATA/SCSI)
+device		da			# Direct Access (disks)
+device		pass
+device		cfi
+
+#device		udav			# Davicom DM9601E USB
+
+device		geom_label
+device		geom_journal
+device		geom_part_bsd
+
+options 	ROOTDEVNAME=\"ufs:da0s1a\"


Property changes on: trunk/sys/arm/conf/CNS11XXNAS
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/COLIBRI-VF50
===================================================================
--- trunk/sys/arm/conf/COLIBRI-VF50	                        (rev 0)
+++ trunk/sys/arm/conf/COLIBRI-VF50	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,28 @@
+# Kernel configuration for Toradex Colibri VF50 Evaluation 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: stable/10/sys/arm/conf/COLIBRI-VF50 266383 2014-05-18 00:21:14Z ian $
+
+#NO_UNIVERSE
+
+include		"VYBRID"
+ident		COLIBRI-VF50
+
+#FDT
+options 	FDT
+options 	FDT_DTB_STATIC
+makeoptions	FDT_DTS_FILE=vybrid-colibri-vf50.dts


Property changes on: trunk/sys/arm/conf/COLIBRI-VF50
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/COSMIC
===================================================================
--- trunk/sys/arm/conf/COSMIC	                        (rev 0)
+++ trunk/sys/arm/conf/COSMIC	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,28 @@
+# Kernel configuration for Cosmic Board (Freescale Vybrid Family development 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: stable/10/sys/arm/conf/COSMIC 266383 2014-05-18 00:21:14Z ian $
+
+#NO_UNIVERSE
+
+include		"VYBRID"
+ident		COSMIC
+
+#FDT
+options 	FDT
+options 	FDT_DTB_STATIC
+makeoptions	FDT_DTS_FILE=vybrid-cosmic.dts


Property changes on: trunk/sys/arm/conf/COSMIC
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/CRB
===================================================================
--- trunk/sys/arm/conf/CRB	                        (rev 0)
+++ trunk/sys/arm/conf/CRB	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,110 @@
+# GENERIC -- Generic kernel configuration file for FreeBSD/arm
+#
+# For more information on this file, please read 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: stable/10/sys/arm/conf/CRB 278677 2015-02-13 15:32:31Z ian $
+
+ident		CRB
+
+options 	PHYSADDR=0x00000000
+options 	KERNPHYSADDR=0x00200000
+options 	KERNVIRTADDR=0xc0200000	# Used in ldscript.arm
+
+options 	COUNTS_PER_SEC=400000000
+include		"../xscale/i8134x/std.crb"
+makeoptions	MODULES_OVERRIDE=""
+
+#makeoptions	DEBUG=-g		# Build kernel with gdb(1) debug symbols
+makeoptions	CONF_CFLAGS=-mcpu=xscale
+options 	HZ=100
+options 	BREAK_TO_DEBUGGER
+#options 	DEVICE_POLLING
+
+options 	SCHED_4BSD		# 4BSD scheduler
+options 	INET			# InterNETworking
+options 	INET6			# IPv6 communications protocols
+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
+options 	NFSCL			# New Network Filesystem Client
+options 	NFSD			# New Network Filesystem Server
+options 	NFSLOCKD		# Network Lock Manager
+options 	NFS_ROOT		# NFS usable as /, requires NFSCL
+#options 	MSDOSFS			# MSDOS Filesystem
+options 	GEOM_PART_BSD		# BSD partition scheme
+options 	GEOM_PART_MBR		# MBR partition scheme
+options 	TMPFS			# Efficient memory filesystem
+options 	CD9660			# ISO 9660 Filesystem
+#options 	PROCFS			# Process filesystem (requires PSEUDOFS)
+options 	PSEUDOFS		# Pseudo-filesystem framework
+options 	SCSI_DELAY=5000		# Delay (in ms) before probing SCSI
+options 	KTRACE			# ktrace(1) support
+options 	INTR_FILTER
+options 	SYSVSHM			# SYSV-style shared memory
+options 	SYSVMSG			# SYSV-style message queues
+options 	SYSVSEM			# SYSV-style semaphores
+options 	_KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time extensions
+options 	KBD_INSTALL_CDEV	# install a CDEV entry in /dev
+options 	BOOTP
+options 	BOOTP_NFSROOT
+options 	BOOTP_NFSV3
+options 	BOOTP_WIRED_TO=em0
+options 	BOOTP_COMPAT
+#options 	PREEMPTION
+device		loop
+device		ether
+#device		saarm
+device		miibus
+device		rl
+device		em
+device		uart
+device		pci
+
+device		ata
+options 	ATA_STATIC_ID		# Static device numbering
+
+device		scbus			# SCSI bus (required for ATA/SCSI)
+device		cd			# CD
+device		da			# Direct Access (disks)
+device		pass			# Passthrough device (direct ATA/SCSI access)
+
+device		"7seg"
+
+# SCSI Controllers
+
+#options 	AHC_REG_PRETTY_PRINT	# Print register bitfields in debug
+					# output.  Adds ~128k to driver.
+#options 	AHD_REG_PRETTY_PRINT	# Print register bitfields in debug
+					# output.  Adds ~215k to driver.
+
+# Debugging for use in -current
+options 	KDB
+options 	DDB			# Enable the kernel debugger
+#options 	DEADLKRES		# Enable the deadlock resolver
+#options 	INVARIANTS		# Enable calls of extra sanity checking
+#options 	INVARIANT_SUPPORT	# Extra sanity checks of internal structures, required by INVARIANTS
+#options 	WITNESS			# Enable checks to detect deadlocks and cycles
+#options 	WITNESS_SKIPSPIN	# Don't run witness on spinlocks for speed
+#options 	DIAGNOSTIC
+
+options 	XSCALE_CACHE_READ_WRITE_ALLOCATE
+device		md
+device		random			# Entropy device
+
+device		iopwdog
+# Floppy drives
+


Property changes on: trunk/sys/arm/conf/CRB
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/CUBIEBOARD
===================================================================
--- trunk/sys/arm/conf/CUBIEBOARD	                        (rev 0)
+++ trunk/sys/arm/conf/CUBIEBOARD	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,142 @@
+#
+# CUBIEBOARD -- Custom configuration for the CUBIEBOARD ARM development
+# platform, check out http://www.cubieboard.org
+#
+# 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: stable/10/sys/arm/conf/CUBIEBOARD 287082 2015-08-23 20:50:22Z ian $
+
+ident		CUBIEBOARD
+
+include		"../allwinner/std.a10"
+
+options 	HZ=100
+options 	SCHED_4BSD		# 4BSD scheduler
+options 	PREEMPTION		# Enable kernel thread preemption
+options 	INET			# InterNETworking
+options 	INET6			# IPv6 communications protocols
+options 	SCTP			# Stream Control Transmission Protocol
+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
+options 	UFS_GJOURNAL		# Enable gjournal-based UFS journaling
+options 	QUOTA			# Enable disk quotas for UFS
+options 	NFSCL			# New Network Filesystem Client
+options 	NFSLOCKD		# Network Lock Manager
+options 	NFS_ROOT		# NFS usable as /, requires NFSCL
+options 	MSDOSFS			# MSDOS Filesystem
+options 	CD9660			# ISO 9660 Filesystem
+options 	PROCFS			# Process filesystem (requires PSEUDOFS)
+options 	PSEUDOFS		# Pseudo-filesystem framework
+options 	TMPFS			# Efficient memory filesystem
+options 	GEOM_PART_GPT		# GUID Partition Tables
+options 	GEOM_PART_BSD		# BSD partition scheme
+options 	GEOM_PART_MBR		# MBR partition scheme
+options 	COMPAT_43		# Compatible with BSD 4.3 [KEEP THIS!]
+options 	SCSI_DELAY=5000		# Delay (in ms) before probing SCSI
+options 	KTRACE			# ktrace(1) support
+options 	SYSVSHM			# SYSV-style shared memory
+options 	SYSVMSG			# SYSV-style message queues
+options 	SYSVSEM			# SYSV-style semaphores
+options 	_KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
+options 	KBD_INSTALL_CDEV	# install a CDEV entry in /dev
+options 	FREEBSD_BOOT_LOADER	# Process metadata passed from loader(8)
+options 	VFP			# Enable floating point hardware support
+
+# Debugging for use in -current
+makeoptions	DEBUG=-g		# Build kernel with gdb(1) debug symbols
+options 	ALT_BREAK_TO_DEBUGGER
+#options 	VERBOSE_SYSINIT		# Enable verbose sysinit messages
+options 	KDB			# Enable kernel debugger support
+# For minimum debugger support (stable branch) use:
+#options 	KDB_TRACE		# Print a stack trace for a panic
+# For full debugger support use this instead:
+options 	DDB			# Enable the kernel debugger
+#options 	INVARIANTS		# Enable calls of extra sanity checking
+#options 	INVARIANT_SUPPORT	# Extra sanity checks of internal structures, required by INVARIANTS
+#options 	WITNESS			# Enable checks to detect deadlocks and cycles
+#options 	WITNESS_SKIPSPIN	# Don't run witness on spinlocks for speed
+#options 	DIAGNOSTIC
+
+# NFS root from boopt/dhcp
+#options 	BOOTP
+#options 	BOOTP_NFSROOT
+#options 	BOOTP_COMPAT
+#options 	BOOTP_NFSV3
+#options 	BOOTP_WIRED_TO=cpsw0
+
+# Boot device is 2nd slice on MMC/SD card
+options 	ROOTDEVNAME=\"ufs:/dev/da0s2\"
+
+# MMC/SD/SDIO Card slot support
+#device		mmc			# mmc/sd bus
+#device		mmcsd			# mmc/sd flash cards
+
+# ATA controllers
+#device		ahci			# AHCI-compatible SATA controllers
+#device		ata			# Legacy ATA/SATA controllers
+#options 	ATA_STATIC_ID		# Static device numbering
+
+# Console and misc
+device		uart
+device		uart_ns8250
+device		pty
+device		snp
+device		md
+device		random			# Entropy device
+
+# I2C support
+#device		iicbus
+#device		iic
+
+# GPIO
+device		gpio
+
+device		scbus			# SCSI bus (required for ATA/SCSI)
+device		da			# Direct Access (disks)
+device		pass
+
+# USB support
+options 	USB_HOST_ALIGN=64	# Align usb buffers to cache line size.
+device		usb
+options 	USB_DEBUG
+#options 	USB_REQ_DEBUG
+#options 	USB_VERBOSE
+#device		uhci
+#device		ohci
+device		ehci
+
+device		umass
+
+# Ethernet
+device		loop
+device		ether
+device		mii
+device		smscphy
+#device		cpsw
+device		bpf
+
+device		emac
+
+# USB ethernet support, requires miibus
+device		miibus
+
+# Flattened Device Tree
+options 	FDT			# Configure using FDT/DTB data
+options 	FDT_DTB_STATIC
+makeoptions	FDT_DTS_FILE=cubieboard.dts
+


Property changes on: trunk/sys/arm/conf/CUBIEBOARD
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/CUBIEBOARD2
===================================================================
--- trunk/sys/arm/conf/CUBIEBOARD2	                        (rev 0)
+++ trunk/sys/arm/conf/CUBIEBOARD2	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,143 @@
+#
+# CUBIEBOARD2 -- Custom configuration for the CUBIEBOARD2 ARM development
+# platform, check out http://www.cubieboard.org
+#
+# 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: stable/10/sys/arm/conf/CUBIEBOARD2 287082 2015-08-23 20:50:22Z ian $
+
+ident		CUBIEBOARD2
+
+include		"../allwinner/a20/std.a20"
+
+options 	HZ=100
+options 	SCHED_ULE		# ULE scheduler
+options 	PREEMPTION		# Enable kernel thread preemption
+options 	INET			# InterNETworking
+options 	INET6			# IPv6 communications protocols
+options 	SCTP			# Stream Control Transmission Protocol
+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
+options 	UFS_GJOURNAL		# Enable gjournal-based UFS journaling
+options 	QUOTA			# Enable disk quotas for UFS
+options 	NFSCL			# New Network Filesystem Client
+options 	NFSLOCKD		# Network Lock Manager
+options 	NFS_ROOT		# NFS usable as /, requires NFSCL
+options 	MSDOSFS			# MSDOS Filesystem
+options 	CD9660			# ISO 9660 Filesystem
+options 	PROCFS			# Process filesystem (requires PSEUDOFS)
+options 	PSEUDOFS		# Pseudo-filesystem framework
+options 	TMPFS			# Efficient memory filesystem
+options 	GEOM_PART_GPT		# GUID Partition Tables
+options 	GEOM_PART_BSD		# BSD partition scheme
+options 	GEOM_PART_MBR		# MBR partition scheme
+options 	COMPAT_43		# Compatible with BSD 4.3 [KEEP THIS!]
+options 	SCSI_DELAY=5000		# Delay (in ms) before probing SCSI
+options 	KTRACE			# ktrace(1) support
+options 	SYSVSHM			# SYSV-style shared memory
+options 	SYSVMSG			# SYSV-style message queues
+options 	SYSVSEM			# SYSV-style semaphores
+options 	_KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
+options 	KBD_INSTALL_CDEV	# install a CDEV entry in /dev
+options 	FREEBSD_BOOT_LOADER	# Process metadata passed from loader(8)
+options 	VFP			# Enable floating point hardware support
+options 	SMP			# Enable multiple cores
+
+# Debugging for use in -current
+makeoptions	DEBUG=-g		# Build kernel with gdb(1) debug symbols
+options 	ALT_BREAK_TO_DEBUGGER
+#options 	VERBOSE_SYSINIT		# Enable verbose sysinit messages
+options 	KDB			# Enable kernel debugger support
+# For minimum debugger support (stable branch) use:
+#options 	KDB_TRACE		# Print a stack trace for a panic
+# For full debugger support use this instead:
+options 	DDB			# Enable the kernel debugger
+#options 	INVARIANTS		# Enable calls of extra sanity checking
+#options 	INVARIANT_SUPPORT	# Extra sanity checks of internal structures, required by INVARIANTS
+#options 	WITNESS 		# Enable checks to detect deadlocks and cycles
+#options 	WITNESS_SKIPSPIN	# Don't run witness on spinlocks for speed
+#options 	DIAGNOSTIC
+
+# NFS root from boopt/dhcp
+#options 	BOOTP
+#options 	BOOTP_NFSROOT
+#options 	BOOTP_COMPAT
+#options 	BOOTP_NFSV3
+#options 	BOOTP_WIRED_TO=cpsw0
+
+# Boot device is 2nd slice on MMC/SD card
+options 	ROOTDEVNAME=\"ufs:/dev/da0s2\"
+
+# MMC/SD/SDIO Card slot support
+#device		mmc			# mmc/sd bus
+#device		mmcsd			# mmc/sd flash cards
+
+# ATA controllers
+#device		ahci			# AHCI-compatible SATA controllers
+#device		ata			# Legacy ATA/SATA controllers
+#options 	ATA_STATIC_ID		# Static device numbering
+
+# Console and misc
+device		uart
+device		uart_ns8250
+device		pty
+device		snp
+device		md
+device		random			# Entropy device
+
+# I2C support
+#device		iicbus
+#device		iic
+
+# GPIO
+device		gpio
+
+device		scbus			# SCSI bus (required for ATA/SCSI)
+device		da			# Direct Access (disks)
+device		pass
+
+# USB support
+options 	USB_HOST_ALIGN=64	# Align usb buffers to cache line size.
+device		usb
+options 	USB_DEBUG
+#options 	USB_REQ_DEBUG
+#options 	USB_VERBOSE
+#device		uhci
+#device		ohci
+device		ehci
+
+device		umass
+
+# Ethernet
+device		loop
+device		ether
+device		mii
+device		smscphy
+#device		cpsw
+device		bpf
+
+device		emac
+
+# USB ethernet support, requires miibus
+device		miibus
+
+# Flattened Device Tree
+options 	FDT			# Configure using FDT/DTB data
+options 	FDT_DTB_STATIC
+makeoptions	FDT_DTS_FILE=cubieboard2.dts
+


Property changes on: trunk/sys/arm/conf/CUBIEBOARD2
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/DB-78XXX
===================================================================
--- trunk/sys/arm/conf/DB-78XXX	                        (rev 0)
+++ trunk/sys/arm/conf/DB-78XXX	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,94 @@
+#
+# Custom kernel for Marvell DB-78xx boards.
+#
+# $FreeBSD: stable/10/sys/arm/conf/DB-78XXX 283404 2015-05-24 15:21:47Z ian $
+#
+
+ident		DB-88F78XX
+include		"../mv/discovery/std.db78xxx"
+
+options 	SOC_MV_DISCOVERY
+
+#makeoptions	DEBUG=-g		# Build kernel with gdb(1) debug symbols
+makeoptions	WERROR="-Werror"
+
+options 	SCHED_4BSD		# 4BSD scheduler
+options 	INET			# InterNETworking
+options 	INET6			# IPv6 communications protocols
+options 	GEOM_PART_BSD		# BSD partition scheme
+options 	GEOM_PART_MBR		# MBR partition scheme
+options 	TMPFS			# Efficient memory filesystem
+options 	FFS			# Berkeley Fast Filesystem
+options 	NANDFS			# NAND Filesystem
+options 	NFSCL			# New Network Filesystem Client
+options 	NFSLOCKD		# Network Lock Manager
+options 	NFS_ROOT		# NFS usable as /, requires NFSCL
+options 	BOOTP
+options 	BOOTP_NFSROOT
+options 	BOOTP_NFSV3
+options 	BOOTP_WIRED_TO=mge0
+
+#options 	ROOTDEVNAME=\"ufs:/dev/da0a\"
+
+options 	SYSVSHM			# SYSV-style shared memory
+options 	SYSVMSG			# SYSV-style message queues
+options 	SYSVSEM			# SYSV-style semaphores
+options 	_KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time extensions
+options 	MUTEX_NOINLINE
+options 	RWLOCK_NOINLINE
+options 	NO_FFS_SNAPSHOT
+options 	NO_SWAPPING
+
+# Debugging
+options 	ALT_BREAK_TO_DEBUGGER
+options 	DDB
+#options 	DEADLKRES		# Enable the deadlock resolver
+#options 	DIAGNOSTIC
+#options 	INVARIANTS		# Enable calls of extra sanity checking
+#options 	INVARIANT_SUPPORT	# Extra sanity checks of internal structures, required by INVARIANTS
+options 	KDB
+#options 	WITNESS			# Enable checks to detect deadlocks and cycles
+#options 	WITNESS_SKIPSPIN	# Don't run witness on spinlocks for speed
+#options 	WITNESS_KDB
+
+device		pci
+
+# Pseudo devices
+device		loop
+device		md
+device		random
+
+# Serial ports
+device		uart
+
+# Networking
+device		ether
+device		mge			# Marvell Gigabit Ethernet controller
+device		mii
+device		e1000phy
+device		bpf
+
+# USB
+options 	USB_DEBUG		# enable debug msgs
+device		usb
+device		ehci
+device		umass
+device		scbus
+device		pass
+device		da
+
+# I2C (TWSI)
+device		iic
+device		iicbus
+device		ds133x
+
+# SATA
+device		mvs
+
+# NAND
+device		nand
+
+# Flattened Device Tree
+options 	FDT
+options 	FDT_DTB_STATIC
+makeoptions	FDT_DTS_FILE=db78100.dts


Property changes on: trunk/sys/arm/conf/DB-78XXX
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/DB-88F5XXX
===================================================================
--- trunk/sys/arm/conf/DB-88F5XXX	                        (rev 0)
+++ trunk/sys/arm/conf/DB-88F5XXX	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,91 @@
+#
+# Custom kernel for Marvell DB-88F5xxx boards.
+#
+# $FreeBSD: stable/10/sys/arm/conf/DB-88F5XXX 283404 2015-05-24 15:21:47Z ian $
+#
+
+ident		DB-88F5XXX
+include		"../mv/orion/std.db88f5xxx"
+
+options 	SOC_MV_ORION
+
+#makeoptions	DEBUG=-g		# Build kernel with gdb(1) debug symbols
+makeoptions	WERROR="-Werror"
+
+options 	SCHED_4BSD		# 4BSD scheduler
+options 	INET			# InterNETworking
+options 	INET6			# IPv6 communications protocols
+options 	GEOM_PART_BSD		# BSD partition scheme
+options 	GEOM_PART_MBR		# MBR partition scheme
+options 	TMPFS			# Efficient memory filesystem
+options 	FFS			# Berkeley Fast Filesystem
+options 	NFSCL			# New Network Filesystem Client
+options 	NFSLOCKD		# Network Lock Manager
+options 	NFS_ROOT		# NFS usable as /, requires NFSCL
+options 	BOOTP
+options 	BOOTP_NFSROOT
+options 	BOOTP_NFSV3
+options 	BOOTP_WIRED_TO=mge0
+
+#options 	ROOTDEVNAME=\"ufs:/dev/da0a\"
+
+options 	SYSVSHM			# SYSV-style shared memory
+options 	SYSVMSG			# SYSV-style message queues
+options 	SYSVSEM			# SYSV-style semaphores
+options 	_KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time extensions
+options 	MUTEX_NOINLINE
+options 	RWLOCK_NOINLINE
+options 	NO_FFS_SNAPSHOT
+options 	NO_SWAPPING
+
+# Debugging
+options 	ALT_BREAK_TO_DEBUGGER
+options 	DDB
+#options 	DEADLKRES		# Enable the deadlock resolver
+#options 	DIAGNOSTIC
+#options 	INVARIANTS		# Enable calls of extra sanity checking
+#options 	INVARIANT_SUPPORT	# Extra sanity checks of internal structures, required by INVARIANTS
+options 	KDB
+#options 	WITNESS			# Enable checks to detect deadlocks and cycles
+#options 	WITNESS_SKIPSPIN	# Don't run witness on spinlocks for speed
+#options 	WITNESS_KDB
+
+device		pci
+
+# Pseudo devices
+device		md
+device		loop
+device		random
+
+# Serial ports
+device		uart
+
+# Networking
+device		ether
+device		mge			# Marvell Gigabit Ethernet controller
+device		mii
+device		e1000phy
+device		bpf
+options 	DEVICE_POLLING
+options 	HZ=1000
+
+# I2C (TWSI)
+device		iic
+device		iicbus
+device		ds133x
+
+# USB
+options 	USB_DEBUG		# enable debug msgs
+device		usb
+device		ehci
+device		umass
+device		scbus
+device		pass
+device		da
+
+# SATA
+device		mvs
+
+# Flattened Device Tree
+options 	FDT
+makeoptions	FDT_DTS_FILE=db88f5281.dts


Property changes on: trunk/sys/arm/conf/DB-88F5XXX
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/DB-88F6XXX
===================================================================
--- trunk/sys/arm/conf/DB-88F6XXX	                        (rev 0)
+++ trunk/sys/arm/conf/DB-88F6XXX	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,97 @@
+#
+# Custom kernel for Marvell DB-88F6xxx boards.
+#
+# $FreeBSD: stable/10/sys/arm/conf/DB-88F6XXX 283404 2015-05-24 15:21:47Z ian $
+#
+
+ident		DB-88F6XXX
+include		"../mv/kirkwood/std.db88f6xxx"
+
+options 	SOC_MV_KIRKWOOD
+
+#makeoptions	DEBUG=-g		# Build kernel with gdb(1) debug symbols
+makeoptions	WERROR="-Werror"
+
+options 	SCHED_4BSD		# 4BSD scheduler
+options 	INET			# InterNETworking
+options 	INET6			# IPv6 communications protocols
+options 	GEOM_PART_BSD		# BSD partition scheme
+options 	GEOM_PART_MBR		# MBR partition scheme
+options 	TMPFS			# Efficient memory filesystem
+options 	FFS			# Berkeley Fast Filesystem
+options 	NANDFS			# NAND Filesystem
+options 	NFSCL			# New Network Filesystem Client
+options 	NFSLOCKD		# Network Lock Manager
+options 	NFS_ROOT		# NFS usable as /, requires NFSCL
+options 	BOOTP
+options 	BOOTP_NFSROOT
+options 	BOOTP_NFSV3
+options 	BOOTP_WIRED_TO=mge0
+
+#options 	ROOTDEVNAME=\"ufs:/dev/da0a\"
+
+options 	SYSVSHM			# SYSV-style shared memory
+options 	SYSVMSG			# SYSV-style message queues
+options 	SYSVSEM			# SYSV-style semaphores
+options 	_KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time extensions
+options 	MUTEX_NOINLINE
+options 	RWLOCK_NOINLINE
+options 	NO_FFS_SNAPSHOT
+options 	NO_SWAPPING
+
+# Debugging
+options 	ALT_BREAK_TO_DEBUGGER
+options 	DDB
+#options 	DEADLKRES		# Enable the deadlock resolver
+#options 	DIAGNOSTIC
+#options 	INVARIANTS		# Enable calls of extra sanity checking
+#options 	INVARIANT_SUPPORT	# Extra sanity checks of internal structures, required by INVARIANTS
+options 	KDB
+#options 	WITNESS			# Enable checks to detect deadlocks and cycles
+#options 	WITNESS_SKIPSPIN	# Don't run witness on spinlocks for speed
+#options 	WITNESS_KDB
+
+device		pci
+
+# Pseudo devices
+device		loop
+device		md
+device		random
+
+# Serial ports
+device		uart
+
+# Networking
+device		ether
+device		mge			# Marvell Gigabit Ethernet controller
+device		mii
+device		e1000phy
+device		bpf
+
+device		cesa			# Marvell security engine
+device		crypto
+device		cryptodev
+
+# USB
+options 	USB_DEBUG		# enable debug msgs
+device		usb
+device		ehci
+device		umass
+device		scbus
+device		pass
+device		da
+
+# I2C (TWSI)
+device		iic
+device		iicbus
+
+# SATA
+device		mvs
+
+# NAND
+device		nand
+
+# Flattened Device Tree
+options 	FDT
+options 	FDT_DTB_STATIC
+makeoptions	FDT_DTS_FILE=db88f6281.dts


Property changes on: trunk/sys/arm/conf/DB-88F6XXX
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/DEFAULTS
===================================================================
--- trunk/sys/arm/conf/DEFAULTS	                        (rev 0)
+++ trunk/sys/arm/conf/DEFAULTS	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,7 @@
+#
+# DEFAULTS -- Default kernel configuration file for FreeBSD/arm
+#
+# $FreeBSD: stable/10/sys/arm/conf/DEFAULTS 266277 2014-05-17 00:53:12Z ian $
+
+device		mem
+


Property changes on: trunk/sys/arm/conf/DEFAULTS
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/DIGI-CCWMX53
===================================================================
--- trunk/sys/arm/conf/DIGI-CCWMX53	                        (rev 0)
+++ trunk/sys/arm/conf/DIGI-CCWMX53	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,38 @@
+# Kernel configuration for Digi ConnectCore Wi-i.MX53 boards
+#
+# 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: stable/10/sys/arm/conf/DIGI-CCWMX53 283368 2015-05-24 14:25:03Z ian $
+
+#NO_UNIVERSE
+
+include		"IMX53"
+ident		DIGI-CCWMX53
+
+makeoptions	WITHOUT_MODULES="ahc"
+
+# required for netbooting
+#options 	BOOTP
+#options 	BOOTP_COMPAT
+#options 	BOOTP_NFSROOT
+#options 	BOOTP_NFSV3
+#options 	BOOTP_WIRED_TO=ffec0
+
+#options 	ROOTDEVNAME=\"ufs:ada0s2a\"
+
+# Flattened Device Tree
+options 	FDT_DTB_STATIC
+makeoptions	FDT_DTS_FILE=digi-ccwmx53.dts


Property changes on: trunk/sys/arm/conf/DIGI-CCWMX53
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/DOCKSTAR
===================================================================
--- trunk/sys/arm/conf/DOCKSTAR	                        (rev 0)
+++ trunk/sys/arm/conf/DOCKSTAR	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,167 @@
+#
+# Custom kernel for Seagate DockStar (Marvell SheevaPlug based) devices.
+#
+# $FreeBSD: stable/10/sys/arm/conf/DOCKSTAR 287082 2015-08-23 20:50:22Z ian $
+#
+#    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: stable/10/sys/arm/conf/DOCKSTAR 287082 2015-08-23 20:50:22Z ian $
+#
+#NO_UNIVERSE
+
+ident		DOCKSTAR
+
+include		"../mv/kirkwood/std.db88f6xxx"
+
+makeoptions	FDT_DTS_FILE=dockstar.dts
+
+options 	SOC_MV_KIRKWOOD
+
+options 	SCHED_4BSD		# 4BSD scheduler
+options 	INET			# InterNETworking
+options 	INET6			# IPv6 communications protocols
+options 	SOFTUPDATES
+options 	CD9660			# ISO 9660 filesystem
+options 	FFS			# Berkeley Fast Filesystem
+options 	TMPFS			# Efficient memory filesystem
+options 	MSDOSFS			# MS DOS File System (FAT, FAT32)
+options 	NULLFS			# NULL filesystem
+options 	SYSVSHM			# SYSV-style shared memory
+options 	SYSVMSG			# SYSV-style message queues
+options 	SYSVSEM			# SYSV-style semaphores
+options 	_KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time extensions
+options 	GEOM_PART_BSD		# BSD partition scheme
+options 	GEOM_PART_MBR		# MBR partition scheme
+options 	GEOM_ELI		# Disk encryption.
+options 	GEOM_LABEL		# Providers labelization.
+options 	GEOM_PART_GPT		# GPT partitioning
+
+# Flattened Device Tree
+device		fdt
+options 	FDT
+options 	FDT_DTB_STATIC
+
+# Misc pseudo devices
+device		bpf			# Required for DHCP
+device  	faith			# IPv6-to-IPv4 relaying (translation)
+device  	firmware		# firmware(9) required for USB wlan
+device  	gif			# IPv6 and IPv4 tunneling
+device		loop			# Network loopback
+device		md			# Memory/malloc disk
+device		pty			# BSD-style compatibility pseudo ttys
+device		random			# Entropy device
+device		tun			# Packet tunnel.
+device		ether			# Required for all ethernet devices
+device		vlan			# 802.1Q VLAN support
+device		wlan			# 802.11 WLAN support
+
+# cam support for umass and ahci
+device		scbus
+device		pass
+device		da
+
+# Serial ports
+device		uart
+
+# Networking
+device		mge			# Marvell Gigabit Ethernet controller
+device		mii
+device		e1000phy
+
+# USB
+options 	USB_HOST_ALIGN=32	# Align DMA to cacheline
+#options 	USB_DEBUG       	# Compile in USB debug support
+device		usb  			# Basic usb support			
+device		ehci 			# USB host controller
+device		umass			# Mass storage
+device		uhid 			# Human-interface devices
+device		rum  			# Ralink Technology RT2501USB wireless NICs
+device		uath 			# Atheros AR5523 wireless NICs
+device		ural 			# Ralink Technology RT2500USB wireless NICs
+device		zyd  			# ZyDAS zb1211/zb1211b wireless NICs
+device		urtw 			# Realtek RTL8187B/L USB
+device		upgt 			# Conexant/Intersil PrismGT SoftMAC USB
+device		u3g  			# USB-based 3G modems (Option, Huawei, Sierra)
+
+# I2C (TWSI)
+device		iic
+device		iicbus
+
+# Sound
+device		sound
+device		snd_uaudio
+
+#crypto
+device		cesa			# Marvell security engine
+device		crypto
+device		cryptodev
+
+# IPSec
+device		enc
+options 	IPSEC
+options 	IPSEC_NAT_T
+options 	TCP_SIGNATURE		# include support for RFC 2385
+
+# IPFW
+options 	IPFIREWALL
+options 	IPFIREWALL_DEFAULT_TO_ACCEPT
+options 	IPFIREWALL_VERBOSE
+options 	IPFIREWALL_VERBOSE_LIMIT=100
+options 	IPFIREWALL_NAT
+options 	LIBALIAS
+options 	DUMMYNET
+options 	IPDIVERT
+
+#PF 
+device		pf
+device		pflog
+device		pfsync
+
+# ALTQ, required for PF
+options 	ALTQ			# Basic ALTQ support
+options 	ALTQ_CBQ		# Class Based Queueing
+options 	ALTQ_RED		# Random Early Detection
+options 	ALTQ_RIO		# RED In/Out
+options 	ALTQ_HFSC		# Hierarchical Packet Scheduler
+options 	ALTQ_CDNR		# Traffic conditioner
+options 	ALTQ_PRIQ		# Priority Queueing
+options 	ALTQ_NOPCC		# Required if the TSC is unusable
+#options 	ALTQ_DEBUG
+
+# Debugging
+makeoptions	DEBUG=-g		# Build kernel with gdb(1) debug symbols
+options 	ALT_BREAK_TO_DEBUGGER
+options 	DDB
+options 	KDB
+#options 	DIAGNOSTIC
+#options 	INVARIANTS		# Enable calls of extra sanity checking
+#options 	INVARIANT_SUPPORT	# Extra sanity checks of internal structures, required by INVARIANTS
+#options 	WITNESS			# Enable checks to detect deadlocks and cycles
+#options 	WITNESS_SKIPSPIN	# Don't run witness on spinlocks for speed
+#options 	WITNESS_KDB
+
+# Enable these options for nfs root configured via BOOTP.
+options 	NFSCL			# Network Filesystem Client
+options 	NFSLOCKD		# Network Lock Manager
+#options 	NFS_ROOT		# NFS usable as /, requires NFSCLIENT
+#options 	BOOTP
+#options 	BOOTP_NFSROOT
+#options 	BOOTP_NFSV3
+#options 	BOOTP_WIRED_TO=mge0
+
+# If not using BOOTP, use something like one of these...
+#options 	ROOTDEVNAME=\"ufs:/dev/da0a\"
+options 	ROOTDEVNAME=\"ufs:/dev/da0s1a\"
+#options 	ROOTDEVNAME=\"ufs:/dev/da0p10\"
+#options 	ROOTDEVNAME=\"nfs:192.168.0.254/dreamplug\"
+


Property changes on: trunk/sys/arm/conf/DOCKSTAR
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/DREAMPLUG-1001
===================================================================
--- trunk/sys/arm/conf/DREAMPLUG-1001	                        (rev 0)
+++ trunk/sys/arm/conf/DREAMPLUG-1001	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,183 @@
+# Kernel config for GlobalScale Technologies DreamPlug version 1001.
+#
+# This is for units that are version 10, revision 01, with NOR SPI flash.
+# These units are identified with the number "1001" on the S/N label.
+#
+# For more information on this file, please read 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: stable/10/sys/arm/conf/DREAMPLUG-1001 287082 2015-08-23 20:50:22Z ian $
+#
+#NO_UNIVERSE
+
+ident		DREAMPLUG-1001
+
+include		"../mv/kirkwood/std.db88f6xxx"
+
+makeoptions	FDT_DTS_FILE=dreamplug-1001.dts
+
+options 	SOC_MV_KIRKWOOD
+
+options 	SCHED_4BSD		# 4BSD scheduler
+options 	INET			# InterNETworking
+options 	INET6			# IPv6 communications protocols
+options 	SOFTUPDATES
+options 	TMPFS			# Efficient memory filesystem
+options 	CD9660			# ISO 9660 filesystem
+options 	FFS			# Berkeley Fast Filesystem
+options 	MSDOSFS			# MS DOS File System (FAT, FAT32)
+options 	NULLFS			# NULL filesystem
+options 	SYSVSHM			# SYSV-style shared memory
+options 	SYSVMSG			# SYSV-style message queues
+options 	SYSVSEM			# SYSV-style semaphores
+options 	_KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time extensions
+options 	GEOM_PART_BSD		# BSD partition scheme
+options 	GEOM_PART_MBR		# MBR partition scheme
+options 	GEOM_ELI		# Disk encryption.
+options 	GEOM_LABEL		# Providers labelization.
+options 	GEOM_PART_GPT		# GPT partitioning
+
+# Flattened Device Tree
+device		fdt
+options 	FDT
+options 	FDT_DTB_STATIC
+
+# Misc pseudo devices
+device		bpf			# Required for DHCP
+device  	faith			# IPv6-to-IPv4 relaying (translation)
+device		firmware		# firmware(9) required for USB wlan
+device		gif			# IPv6 and IPv4 tunneling
+device		loop			# Network loopback
+device		md			# Memory/malloc disk
+device		pty			# BSD-style compatibility pseudo ttys
+device		random			# Entropy device
+device		tun			# Packet tunnel.
+device		ether			# Required for all ethernet devices
+device		vlan			# 802.1Q VLAN support
+device		wlan			# 802.11 WLAN support
+
+# cam support for umass and ahci
+device		scbus
+device		pass
+device		da
+device		cd
+
+# Serial ports
+device		uart
+
+# Networking
+device		mge			# Marvell Gigabit Ethernet controller
+device		mii
+device		e1000phy
+
+# USB
+options 	USB_HOST_ALIGN=32	# Align DMA to cacheline
+#options 	USB_DEBUG       	# Compile in USB debug support
+device		usb  			# Basic usb support			
+device		ehci 			# USB host controller
+device		umass			# Mass storage
+device		uhid 			# Human-interface devices
+device		rum  			# Ralink Technology RT2501USB wireless NICs
+device		uath 			# Atheros AR5523 wireless NICs
+device		ural 			# Ralink Technology RT2500USB wireless NICs
+device		zyd  			# ZyDAS zb1211/zb1211b wireless NICs
+device		urtw 			# Realtek RTL8187B/L USB
+device		upgt 			# Conexant/Intersil PrismGT SoftMAC USB
+device		u3g  			# USB-based 3G modems (Option, Huawei, Sierra)
+
+# I2C (TWSI)
+device		iic
+device		iicbus
+
+# SATA
+device		mvs
+device		ahci
+
+# Sound
+device		sound
+device		snd_uaudio
+
+#crypto
+device		cesa			# Marvell security engine
+device		crypto
+device		cryptodev
+
+# IPSec
+device		enc
+options 	IPSEC
+options 	IPSEC_NAT_T
+options 	TCP_SIGNATURE		# include support for RFC 2385
+
+# IPFW
+options 	IPFIREWALL
+options 	IPFIREWALL_DEFAULT_TO_ACCEPT
+options 	IPFIREWALL_VERBOSE
+options 	IPFIREWALL_VERBOSE_LIMIT=100
+options 	IPFIREWALL_NAT
+options 	LIBALIAS
+options 	DUMMYNET
+options 	IPDIVERT
+
+#PF 
+device		pf
+device		pflog
+device		pfsync
+
+# ALTQ, required for PF
+options 	ALTQ			# Basic ALTQ support
+options 	ALTQ_CBQ		# Class Based Queueing
+options 	ALTQ_RED		# Random Early Detection
+options 	ALTQ_RIO		# RED In/Out
+options 	ALTQ_HFSC		# Hierarchical Packet Scheduler
+options 	ALTQ_CDNR		# Traffic conditioner
+options 	ALTQ_PRIQ		# Priority Queueing
+options 	ALTQ_NOPCC		# Required if the TSC is unusable
+#options 	ALTQ_DEBUG
+
+# Debugging
+makeoptions	DEBUG=-g		# Build kernel with gdb(1) debug symbols
+options 	ALT_BREAK_TO_DEBUGGER
+options 	DDB
+options 	KDB
+#options 	DIAGNOSTIC
+#options 	INVARIANTS		# Enable calls of extra sanity checking
+#options 	INVARIANT_SUPPORT	# Extra sanity checks of internal structures, required by INVARIANTS
+#options 	WITNESS			# Enable checks to detect deadlocks and cycles
+#options 	WITNESS_SKIPSPIN	# Don't run witness on spinlocks for speed
+#options 	WITNESS_KDB
+
+# Enable these options for nfs root configured via BOOTP.
+options 	NFSCL			# Network Filesystem Client
+options 	NFSLOCKD		# Network Lock Manager
+#options 	NFS_ROOT		# NFS usable as /, requires NFSCLIENT
+#options 	BOOTP
+#options 	BOOTP_NFSROOT
+#options 	BOOTP_NFSV3
+#options 	BOOTP_WIRED_TO=mge0
+
+# If not using BOOTP, use something like one of these...
+#options 	ROOTDEVNAME=\"ufs:/dev/da1a\"
+options 	ROOTDEVNAME=\"ufs:/dev/da1s1a\"
+#options 	ROOTDEVNAME=\"ufs:/dev/da1p10\"
+#options 	ROOTDEVNAME=\"nfs:192.168.0.254/dreamplug\"
+
+# To use this configuration with the (rare) model 1001N (nand flash),
+# create a kernel config file that looks like this:
+#
+# include DREAMPLUG-1001
+# nomakeoptions	FDT_DTS_FILE
+# makeoptions	FDT_DTS_FILE=dreamplug-1001N.dts
+# device 	nand
+


Property changes on: trunk/sys/arm/conf/DREAMPLUG-1001
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/EA3250
===================================================================
--- trunk/sys/arm/conf/EA3250	                        (rev 0)
+++ trunk/sys/arm/conf/EA3250	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,99 @@
+#
+# Custom kernel for EA3250 boards.
+#
+# $FreeBSD: stable/10/sys/arm/conf/EA3250 271428 2014-09-11 15:36:36Z ian $
+#
+
+ident		EA3250
+include		"../lpc/std.lpc"
+hints		"EA3250.hints"
+
+makeoptions	MODULES_OVERRIDE=""
+
+#makeoptions	DEBUG=-g		# Build kernel with gdb(1) debug symbols
+makeoptions	WERROR="-Werror"
+
+options 	SCHED_4BSD		# 4BSD scheduler
+options 	INET			# InterNETworking
+options 	INET6			# IPv6 communications protocols
+options 	FFS			# Berkeley Fast Filesystem
+options 	NFSCL			# Network Filesystem Client
+options 	NFSLOCKD		# Network Lock Manager
+options 	NFS_ROOT		# NFS usable as /, requires NFSCLIENT
+options 	GEOM_PART_BSD		# BSD partition scheme
+options 	GEOM_PART_MBR		# MBR partition scheme
+options 	TMPFS			# Efficient memory filesystem
+options 	MSDOSFS
+options 	BOOTP
+options 	BOOTP_NFSROOT
+options 	BOOTP_NFSV3
+options 	BOOTP_WIRED_TO=lpe0
+
+#options 	ROOTDEVNAME=\"ufs:/dev/da0a\"
+
+options 	SYSVSHM			# SYSV-style shared memory
+options 	SYSVMSG			# SYSV-style message queues
+options 	SYSVSEM			# SYSV-style semaphores
+options 	_KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time extensions
+options 	MUTEX_NOINLINE
+options 	RWLOCK_NOINLINE
+options 	NO_FFS_SNAPSHOT
+options 	NO_SWAPPING
+
+# Debugging
+options 	ALT_BREAK_TO_DEBUGGER
+options 	DDB
+#options 	DEADLKRES		# Enable the deadlock resolver
+#options 	DIAGNOSTIC
+#options 	INVARIANTS		# Enable calls of extra sanity checking
+#options 	INVARIANT_SUPPORT	# Extra sanity checks of internal structures, required by INVARIANTS
+options 	KDB
+#options 	WITNESS			# Enable checks to detect deadlocks and cycles
+#options 	WITNESS_SKIPSPIN	# Don't run witness on spinlocks for speed
+#options 	WITNESS_KDB
+
+# Pseudo devices
+device		loop
+device		md
+device		pty
+device		random
+
+# Serial ports
+device		uart
+
+# Networking
+device		ether
+device		mii
+device		bpf
+device		lpe
+
+# USB
+options 	USB_DEBUG
+device		usb
+device		ohci
+device		umass
+device		scbus
+device		pass
+device		da
+
+device		mmc
+device		mmcsd
+device		lpcmmc
+
+device		gpio
+device		gpioled
+device		lpcgpio
+
+device		spibus
+device		lpcspi
+device		ssd1289
+
+device		lpcfb
+
+# DMAC
+device		dmac
+
+# Flattened Device Tree
+options 	FDT
+options 	FDT_DTB_STATIC
+makeoptions	FDT_DTS_FILE=ea3250.dts


Property changes on: trunk/sys/arm/conf/EA3250
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/EA3250.hints
===================================================================
--- trunk/sys/arm/conf/EA3250.hints	                        (rev 0)
+++ trunk/sys/arm/conf/EA3250.hints	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,4 @@
+# $FreeBSD: stable/10/sys/arm/conf/EA3250.hints 239279 2012-08-15 05:55:16Z gonzo $
+
+hint.ssd1289.0.at="spibus0"
+hint.ssd1289.0.cs=26


Property changes on: trunk/sys/arm/conf/EA3250.hints
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/EB9200
===================================================================
--- trunk/sys/arm/conf/EB9200	                        (rev 0)
+++ trunk/sys/arm/conf/EB9200	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,114 @@
+# EB9200 - Custom kernel for the Embest ATEB9200 AT91RM9200 evaluation board.
+#
+# For more information on this file, please read the handbook section on
+# Kernel Configuration Files:
+#
+#    http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html
+#
+# 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: stable/10/sys/arm/conf/EB9200 278676 2015-02-13 15:27:46Z ian $
+
+#NO_UNIVERSE
+
+ident		EB9200
+
+include		"../at91/std.eb9200"
+# The AT91 platform doesn't use /boot/loader, so we have to statically wire
+# hints.
+hints		"EB9200.hints"
+makeoptions	MODULES_OVERRIDE=""
+
+makeoptions	DEBUG=-g		# Build kernel with gdb(1) debug symbols
+options 	DDB
+options 	KDB
+
+options 	SCHED_4BSD		# 4BSD scheduler
+options 	INET			# InterNETworking
+#options 	INET6			# IPv6 communications protocols
+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
+#options 	MD_ROOT			# MD is a potential root device
+#options 	MD_ROOT_SIZE=4096	# 4MB ram disk
+#options 	ROOTDEVNAME=\"ufs:/dev/da0s1a\"
+options 	NFSCL			# New Network Filesystem Client
+options 	NFSD			# New Network Filesystem Server
+options 	NFSLOCKD		# Network Lock Manager
+options 	NFS_ROOT		# NFS usable as /, requires NFSCL
+options 	BOOTP_NFSROOT
+options 	BOOTP
+
+options 	GEOM_PART_BSD		# BSD partition scheme
+options 	GEOM_PART_MBR		# MBR partition scheme
+options 	TMPFS			# Efficient memory filesystem
+#options 	MSDOSFS			# MSDOS Filesystem
+#options 	CD9660			# ISO 9660 Filesystem
+#options 	PROCFS			# Process filesystem (requires PSEUDOFS)
+options 	PSEUDOFS		# Pseudo-filesystem framework
+#options 	SCSI_DELAY=5000		# Delay (in ms) before probing SCSI
+#options 	KTRACE			# ktrace(1) support
+options 	SYSVSHM			# SYSV-style shared memory
+options 	SYSVMSG			# SYSV-style message queues
+options 	SYSVSEM			# SYSV-style semaphores
+options 	_KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time extensions
+#options 	NO_SYSCTL_DESCR
+# Disable the inlining of mutex, rwlock and sx locks.  These eat up a lot
+# of space.
+options 	MUTEX_NOINLINE
+options 	RWLOCK_NOINLINE
+options 	SX_NOINLINE
+options 	NO_FFS_SNAPSHOT
+options 	NO_SWAPPING
+device		random
+device		loop
+device		ether
+device		uart
+device		ate
+device		miibus
+#device		lxtphy
+
+device		at91_cfata
+device		ata
+
+# Debugging for use in -current
+#options 	DEADLKRES		# Enable the deadlock resolver
+#options 	INVARIANTS		# Enable calls of extra sanity checking
+#options 	INVARIANT_SUPPORT	# Extra sanity checks of internal structures, required by INVARIANTS
+#options 	WITNESS			# Enable checks to detect deadlocks and cycles
+#options 	WITNESS_SKIPSPIN	# Don't run witness on spinlocks for speed
+
+device		md
+device		at91_twi		# TWI: Two Wire Interface
+device		at91_spi		# SPI:
+device		spibus
+# MMC/SD
+device		at91_mci
+device		mmc
+device		mmcsd
+# iic
+device		iic
+device		iicbus
+device		icee
+
+device		bpf
+# USB support
+options 	USB_DEBUG		# enable debug msgs
+device		ohci			# OHCI localbus->USB interface
+device		usb			# USB Bus (required)
+device		umass			# Disks/Mass storage - Requires scbus and da
+# SCSI peripherals
+device		scbus			# SCSI bus (required for ATA/SCSI)
+device		da			# Direct Access (disks)
+device		cd			# CD
+device		pass			# Passthrough device (direct ATA/SCSI access)
+
+# USB device (gadget) support
+#device		at91_dci		# Atmel's usb device
+#device		usfs			# emulate a flash
+#device		cdce			# emulate an ethernet
+#device		usb_template		# Control of the gadget


Property changes on: trunk/sys/arm/conf/EB9200
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/EB9200.hints
===================================================================
--- trunk/sys/arm/conf/EB9200.hints	                        (rev 0)
+++ trunk/sys/arm/conf/EB9200.hints	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,6 @@
+# $FreeBSD: stable/10/sys/arm/conf/EB9200.hints 239324 2012-08-16 05:03:59Z imp $
+
+# should likely list CF here since its address isn't fixed.
+# but since it is at an external chip select, do we use that or the address
+# to configure it as its bus address?  Need to fix arbitrary bus mapping
+# before I can list it here.


Property changes on: trunk/sys/arm/conf/EB9200.hints
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/EFIKA_MX
===================================================================
--- trunk/sys/arm/conf/EFIKA_MX	                        (rev 0)
+++ trunk/sys/arm/conf/EFIKA_MX	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,193 @@
+#
+# Kernel configuration for Efika MX Smarttop/Smartbook boards
+#
+# 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: stable/10/sys/arm/conf/EFIKA_MX 287082 2015-08-23 20:50:22Z ian $
+
+ident		EFIKA_MX
+
+include 	"../freescale/imx/std.imx51"
+
+makeoptions	WITHOUT_MODULES="ahc"
+
+options 	SCHED_4BSD		# 4BSD scheduler
+options 	PREEMPTION		# Enable kernel thread preemption
+options 	INET			# InterNETworking
+options 	INET6			# IPv6 communications protocols
+options 	SCTP			# Stream Control Transmission Protocol
+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
+options 	UFS_GJOURNAL		# Enable gjournal-based UFS journaling
+options 	QUOTA			# Enable disk quotas for UFS
+#options 	MD_ROOT			# MD is a potential root device
+options 	NFSCL			# New Network Filesystem Client
+#options 	NFSD			# New Network Filesystem Server
+options 	NFSLOCKD		# Network Lock Manager
+options 	NFS_ROOT		# NFS usable as /, requires NFSCL
+options 	MSDOSFS			# MSDOS Filesystem
+options 	CD9660			# ISO 9660 Filesystem
+options 	PROCFS			# Process filesystem (requires PSEUDOFS)
+options 	PSEUDOFS		# Pseudo-filesystem framework
+options 	TMPFS			# Efficient memory filesystem
+options 	GEOM_PART_GPT		# GUID Partition Tables
+options 	GEOM_PART_BSD		# BSD partition scheme
+options 	GEOM_PART_MBR		# MBR partition scheme
+options 	GEOM_LABEL		# Provides labelization
+#options 	COMPAT_FREEBSD5		# Compatible with FreeBSD5
+#options 	COMPAT_FREEBSD6		# Compatible with FreeBSD6
+#options 	COMPAT_FREEBSD7		# Compatible with FreeBSD7
+options 	SCSI_DELAY=5000		# Delay (in ms) before probing SCSI
+options 	KTRACE			# ktrace(1) support
+options 	SYSVSHM			# SYSV-style shared memory
+options 	SYSVMSG			# SYSV-style message queues
+options 	SYSVSEM			# SYSV-style semaphores
+options 	_KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
+options 	KBD_INSTALL_CDEV	# install a CDEV entry in /dev
+options 	INCLUDE_CONFIG_FILE	# Include this file in kernel
+options 	VFP			# Enable floating point hardware support
+
+# Debugging for use in -current
+makeoptions	DEBUG=-g		# Build kernel with gdb(1) debug symbols
+options 	ALT_BREAK_TO_DEBUGGER
+#options 	VERBOSE_SYSINIT		# Enable verbose sysinit messages
+options 	KDB			# Enable kernel debugger support
+# For minimum debugger support (stable branch) use:
+#options 	KDB_TRACE		# Print a stack trace for a panic
+# For full debugger support use this instead:
+options 	DDB			# Enable the kernel debugger
+#options 	GDB			# Support remote GDB
+options 	DEADLKRES		# Enable the deadlock resolver
+options 	INVARIANTS		# Enable calls of extra sanity checking
+options 	INVARIANT_SUPPORT	# Extra sanity checks of internal structures, required by INVARIANTS
+options 	WITNESS			# Enable checks to detect deadlocks and cycles
+#options 	WITNESS_SKIPSPIN	# Don't run witness on spinlocks for speed
+
+# NFS root from boopt/dhcp
+#options 	BOOTP
+#options 	BOOTP_NFSROOT
+#options 	BOOTP_COMPAT
+#options 	BOOTP_NFSV3
+#options 	BOOTP_WIRED_TO=ue0
+
+options 	ROOTDEVNAME=\"ufs:ada0s2a\"
+
+
+# kernel/memory size reduction
+#options 	MUTEX_NOINLINE
+#options 	NO_FFS_SNAPSHOT
+#options 	NO_SWAPPING
+#options 	NO_SYSCTL_DESCR
+#options 	RWLOCK_NOINLINE
+
+# Debugging support.  Always need this:
+options 	KDB			# Enable kernel debugger support.
+# For minimum debugger support (stable branch) use:
+#options 	KDB_TRACE		# Print a stack trace for a panic.
+# For full debugger support use this instead:
+options 	DDB			# Support DDB.
+#options 	GDB			# Support remote GDB.
+#options 	DEADLKRES		# Enable the deadlock resolver
+#options 	INVARIANTS		# Enable calls of extra sanity checking
+#options 	INVARIANT_SUPPORT	# Extra sanity checks of internal structures, required by INVARIANTS
+#options 	WITNESS			# Enable checks to detect deadlocks and cycles
+
+# The `bpf' device enables the Berkeley Packet Filter.
+# Be aware of the administrative consequences of enabling this!
+# Note that 'bpf' is required for DHCP.
+device		bpf			# Berkeley packet filter
+
+# Pseudo devices.
+device		loop			# Network loopback
+device		random			# Entropy device
+device		ether			# Ethernet support
+#device		vlan			# 802.1Q VLAN support
+#device		tun			# Packet tunnel.
+#device		md			# Memory "disks"
+#device		gif			# IPv6 and IPv4 tunneling
+#device		faith			# IPv6-to-IPv4 relaying (translation)
+#device		firmware		# firmware assist module
+
+# Serial (COM) ports
+device		uart			# Multi-uart driver
+options 	ALT_BREAK_TO_DEBUGGER
+
+device		ata
+device		atapci			# Only for helper functions
+device		imxata
+options 	ATA_STATIC_ID		# Static device numbering
+
+device		gpio
+device		gpioled
+
+device		fsliic
+device		iic
+device		iicbus
+
+# SCSI peripherals
+device		scbus			# SCSI bus (required for ATA/SCSI)
+device		da			# Direct Access (disks)
+device		cd			# CD
+device		pass			# Passthrough device (direct ATA/SCSI access)
+
+# USB support
+options 	USB_HOST_ALIGN=64	# Align usb buffers to cache line size.
+#options 	USB_DEBUG		# enable debug msgs
+device		ehci			# OHCI USB interface
+device		usb			# USB Bus (required)
+device		umass			# Disks/Mass storage - Requires scbus and da
+device		uhid			# "Human Interface Devices"
+device		u3g
+
+# USB Ethernet, requires miibus
+device		miibus
+device		aue			# ADMtek USB Ethernet
+device		axe			# ASIX Electronics USB Ethernet
+device		cdce			# Generic USB over Ethernet
+device		cue			# CATC USB Ethernet
+device		kue			# Kawasaki LSI USB Ethernet
+device		rue			# RealTek RTL8150 USB Ethernet
+device		udav			# Davicom DM9601E USB
+
+# USB Wireless
+device		rum			# Ralink Technology RT2501USB wireless NICs
+
+# Watchdog timer.
+# WARNING: can't be disabled!!!
+device		imxwdt			# Watchdog
+
+# Wireless NIC cards
+device		wlan			# 802.11 support
+device		wlan_wep		# 802.11 WEP support
+device		wlan_ccmp		# 802.11 CCMP support
+device		wlan_tkip		# 802.11 TKIP support
+device		wlan_amrr		# AMRR transmit rate control algorithm
+
+# Flattened Device Tree
+options 	FDT			# Configure using FDT/DTB data
+options 	FDT_DTB_STATIC
+makeoptions	FDT_DTS_FILE=efikamx.dts
+
+# NOTE: serial console will be disabled if syscons enabled
+# Uncomment following lines for framebuffer/syscons support
+device		sc
+device		kbdmux
+options 	SC_DFLT_FONT		# compile font in
+makeoptions	SC_DFLT_FONT=cp437
+device		ukbd			# Allow keyboard like HIDs to control console
+device		ums


Property changes on: trunk/sys/arm/conf/EFIKA_MX
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/EP80219
===================================================================
--- trunk/sys/arm/conf/EP80219	                        (rev 0)
+++ trunk/sys/arm/conf/EP80219	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,111 @@
+# EP80219 -- Custom kernel configuration file for FreeBSD/arm on the EP80219
+#
+# For more information on this file, please read 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: stable/10/sys/arm/conf/EP80219 278677 2015-02-13 15:32:31Z ian $
+
+ident		EP80219
+
+options 	PHYSADDR=0xa0000000
+options 	KERNPHYSADDR=0xa0200000	
+options 	KERNVIRTADDR=0xc0200000	# Used in ldscript.arm
+
+#options 	ARM32_NEW_VM_LAYOUT
+include	"../xscale/i80321/std.ep80219"
+makeoptions	MODULES_OVERRIDE=""
+
+makeoptions	DEBUG=-g		# Build kernel with gdb(1) debug symbols
+makeoptions	CONF_CFLAGS=-mcpu=xscale
+options 	HZ=100
+#options 	DEVICE_POLLING
+
+options 	SCHED_4BSD		# 4BSD scheduler
+options 	INET			# InterNETworking
+#options 	INET6			# IPv6 communications protocols
+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
+options 	NFSCL			# New Network Filesystem Client
+options 	NFSD			# New Network Filesystem Server
+options 	NFSLOCKD		# Network Lock Manager
+options 	NFS_ROOT		# NFS usable as /, requires NFSCL
+options 	TMPFS			# Efficient memory filesystem
+#options 	MSDOSFS			# MSDOS Filesystem
+options 	CD9660			# ISO 9660 Filesystem
+#options 	PROCFS			# Process filesystem (requires PSEUDOFS)
+options 	PSEUDOFS		# Pseudo-filesystem framework
+options 	SCSI_DELAY=5000		# Delay (in ms) before probing SCSI
+options 	KTRACE			# ktrace(1) support
+options 	SYSVSHM			# SYSV-style shared memory
+options 	SYSVMSG			# SYSV-style message queues
+options 	SYSVSEM			# SYSV-style semaphores
+options 	_KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time extensions
+options 	KBD_INSTALL_CDEV	# install a CDEV entry in /dev
+options 	GEOM_PART_BSD		# BSD partition scheme
+options 	GEOM_PART_MBR		# MBR partition scheme
+options 	GEOM_PART_GPT		# GUID Partition Tables.
+options 	GEOM_LABEL		# Providers labelization.
+
+options 	BOOTP
+options 	BOOTP_NFSROOT
+options 	BOOTP_NFSV3
+options 	BOOTP_WIRED_TO=fxp0
+options 	BOOTP_COMPAT
+#options 	PREEMPTION
+device		loop
+device		ether
+#device		saarm
+device		miibus
+device		fxp
+device		uart
+device		pci
+
+device		ata
+options 	ATA_STATIC_ID		# Static device numbering
+
+device		scbus			# SCSI bus (required for ATA/SCSI)
+device		cd			# CD
+device		da			# Direct Access (disks)
+device		pass			# Passthrough device (direct ATA/SCSI access)
+
+# SCSI Controllers
+
+device		iopwdog			# I80321 Watchdog
+device		dma			# I80321 DMA Controller
+
+# Debugging for use in -current
+options 	KDB
+options 	DDB			# Enable the kernel debugger
+#options 	DEADLKRES		# Enable the deadlock resolver
+#options 	INVARIANTS		# Enable calls of extra sanity checking
+#options 	INVARIANT_SUPPORT	# Extra sanity checks of internal structures, required by INVARIANTS
+#options 	WITNESS			# Enable checks to detect deadlocks and cycles
+#options 	WITNESS_SKIPSPIN	# Don't run witness on spinlocks for speed
+#options 	DIAGNOSTIC
+
+options 	XSCALE_CACHE_READ_WRITE_ALLOCATE
+device		md
+device		random          	# Entropy device
+
+# Floppy drives
+
+options 	INCLUDE_CONFIG_FILE	# Include this file in kernel
+#options 	VERBOSE_SYSINIT
+options 	VERBOSE_INIT_ARM
+
+device		bpf
+#options 	ROOTDEVNAME=\"ufs:ada0s1a\"


Property changes on: trunk/sys/arm/conf/EP80219
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/ETHERNUT5
===================================================================
--- trunk/sys/arm/conf/ETHERNUT5	                        (rev 0)
+++ trunk/sys/arm/conf/ETHERNUT5	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,163 @@
+# Kernel configuration for Ethernut 5 boards
+#
+# 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: stable/10/sys/arm/conf/ETHERNUT5 266383 2014-05-18 00:21:14Z ian $
+
+#NO_UNIVERSE
+
+ident		ETHERNUT5
+
+include "../at91/std.ethernut5"
+
+# To statically compile in device wiring instead of /boot/device.hints
+hints		"ETHERNUT5.hints"
+
+#makeoptions	DEBUG=-g		# Build kernel with gdb(1) debug symbols
+
+options 	SCHED_4BSD		# 4BSD scheduler
+#options 	PREEMPTION		# Enable kernel thread preemption
+options 	INET			# InterNETworking
+#options 	INET6			# IPv6 communications protocols
+#options 	SCTP			# Stream Control Transmission Protocol
+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
+#options 	UFS_GJOURNAL		# Enable gjournal-based UFS journaling
+#options 	MD_ROOT			# MD is a potential root device
+options 	NFSCL			# New Network Filesystem Client
+#options 	NFSD			# New Network Filesystem Server
+options 	NFSLOCKD		# Network Lock Manager
+options 	NFS_ROOT		# NFS usable as /, requires NFSCL
+options 	GEOM_PART_BSD		# BSD partition scheme
+options 	GEOM_PART_MBR		# MBR partition scheme
+options 	TMPFS			# Efficient memory filesystem
+#options 	MSDOSFS			# MSDOS Filesystem
+#options 	CD9660			# ISO 9660 Filesystem
+#options 	PROCFS			# Process filesystem (requires PSEUDOFS)
+#options 	PSEUDOFS		# Pseudo-filesystem framework
+#options 	GEOM_PART_GPT		# GUID Partition Tables.
+#options 	GEOM_LABEL		# Provides labelization
+#options 	COMPAT_FREEBSD5		# Compatible with FreeBSD5
+#options 	COMPAT_FREEBSD6		# Compatible with FreeBSD6
+#options 	COMPAT_FREEBSD7		# Compatible with FreeBSD7
+options 	SCSI_DELAY=5000		# Delay (in ms) before probing SCSI
+options 	KTRACE			# ktrace(1) support
+#options 	STACK			# stack(9) support
+options 	SYSVSHM			# SYSV-style shared memory
+options 	SYSVMSG			# SYSV-style message queues
+options 	SYSVSEM			# SYSV-style semaphores
+options 	_KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
+options 	PRINTF_BUFR_SIZE=128	# Prevent printf output being interspersed.
+#options 	HWPMC_HOOKS		# Necessary kernel hooks for hwpmc(4)
+#options 	AUDIT			# Security event auditing
+#options 	CAPABILITY_MODE		# Capsicum capability mode
+#options 	CAPABILITIES		# Capsicum capabilities
+#options 	MAC			# TrustedBSD MAC Framework
+#options 	INCLUDE_CONFIG_FILE	# Include this file in kernel
+
+# required for netbooting
+options 	BOOTP
+options 	BOOTP_COMPAT
+options 	BOOTP_NFSROOT
+options 	BOOTP_NFSV3
+options 	BOOTP_WIRED_TO=ate0
+
+# alternatively, boot from a MMC/SD memory card
+#options 	ROOTDEVNAME=\"ufs:/dev/mmcsd0a\"
+
+# kernel/memory size reduction
+options 	MUTEX_NOINLINE
+options 	NO_FFS_SNAPSHOT
+options 	NO_SWAPPING
+options 	NO_SYSCTL_DESCR
+options 	RWLOCK_NOINLINE
+
+# Debugging support.  Always need this:
+#options 	KDB			# Enable kernel debugger support.
+# For minimum debugger support (stable branch) use:
+#options 	KDB_TRACE		# Print a stack trace for a panic.
+# For full debugger support use this instead:
+#options 	DDB			# Support DDB.
+#options 	GDB			# Support remote GDB.
+#options 	DEADLKRES		# Enable the deadlock resolver
+#options 	INVARIANTS		# Enable calls of extra sanity checking
+#options 	INVARIANT_SUPPORT	# Extra sanity checks of internal structures, required by INVARIANTS
+#options 	WITNESS			# Enable checks to detect deadlocks and cycles
+#options 	WITNESS_SKIPSPIN	# Don't run witness on spinlocks for speed
+#options 	MALLOC_DEBUG_MAXZONES=8	# Separate malloc(9) zones
+
+# The `bpf' device enables the Berkeley Packet Filter.
+# Be aware of the administrative consequences of enabling this!
+# Note that 'bpf' is required for DHCP.
+device		bpf			# Berkeley packet filter
+
+# Ethernet
+device		mii			# Minimal MII support
+device		ate			# Atmel AT91 Ethernet driver
+
+# I2C
+device		at91_twi		# Atmel AT91 Two-wire Interface
+device		iic			# I2C generic I/O device driver
+device		iicbus			# I2C bus system
+device		pcf8563			# NXP PCF8563 clock/calendar
+
+# MMC/SD
+device		at91_mci		# Atmel AT91 Multimedia Card Interface
+options 	AT91_MCI_HAS_4WIRE
+device		mmc			# MMC/SD bus
+device		mmcsd			# MMC/SD memory card
+
+# DataFlash
+device		at91_spi		# Atmel AT91 Serial Peripheral Interface
+device		spibus			# SPI bus
+device		at45d			# Atmel AT45D
+device		geom_map		# GEOM partition mapping
+
+# Pseudo devices.
+device		loop			# Network loopback
+device		random			# Entropy device
+device		ether			# Ethernet support
+#device		vlan			# 802.1Q VLAN support
+#device		tun			# Packet tunnel.
+#device		md			# Memory "disks"
+#device		gif			# IPv6 and IPv4 tunneling
+#device		faith			# IPv6-to-IPv4 relaying (translation)
+#device		firmware		# firmware assist module
+
+# 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 (COM) ports
+device		uart			# Multi-uart driver
+options 	ALT_BREAK_TO_DEBUGGER
+
+# USB support
+#options 	USB_DEBUG		# enable debug msgs
+device		ohci			# OHCI USB interface
+device		usb			# USB Bus (required)
+#device		umass			# Disks/Mass storage - Requires scbus and da
+
+# watchdog
+device		at91_wdt		# Atmel AT91 Watchdog Timer


Property changes on: trunk/sys/arm/conf/ETHERNUT5
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/ETHERNUT5.hints
===================================================================
--- trunk/sys/arm/conf/ETHERNUT5.hints	                        (rev 0)
+++ trunk/sys/arm/conf/ETHERNUT5.hints	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,51 @@
+# $FreeBSD: stable/10/sys/arm/conf/ETHERNUT5.hints 238786 2012-07-26 05:37:36Z imp $
+
+# Atmel AT45DB21D
+hint.at45d.0.at="spibus0"
+hint.at45d.0.cs=0
+# user 132 kbytes
+hint.map.0.at="flash/spi0"
+hint.map.0.start=0x00000000
+hint.map.0.end=0x00020fff
+hint.map.0.name="user"
+hint.map.0.readonly=1
+# setup 132 kbytes
+hint.map.1.at="flash/spi0"
+hint.map.1.start=0x00021000
+hint.map.1.end=0x00041fff
+hint.map.1.name="setup"
+hint.map.1.readonly=1
+# uboot 528 kbytes
+hint.map.2.at="flash/spi0"
+hint.map.2.start=0x00042000
+hint.map.2.end=0x000c5fff
+hint.map.2.name="uboot"
+hint.map.2.readonly=1
+# kernel 2640 kbytes
+hint.map.3.at="flash/spi0"
+hint.map.3.start=0x000c6000
+hint.map.3.end=0x00359fff
+hint.map.3.name="kernel"
+#hint.map.3.readonly=1
+# nutos 528 kbytes
+hint.map.4.at="flash/spi0"
+hint.map.4.start=0x0035a000
+hint.map.4.end=0x003ddfff
+hint.map.4.name="nutos"
+hint.map.4.readonly=1
+# env 132 kbytes
+hint.map.5.at="flash/spi0"
+hint.map.5.start=0x003de000
+hint.map.5.end=0x003fefff
+hint.map.5.name="env"
+hint.map.5.readonly=1
+# env 132 kbytes
+hint.map.6.at="flash/spi0"
+hint.map.6.start=0x003ff000
+hint.map.6.end=0x0041ffff
+hint.map.6.name="nutoscfg"
+hint.map.6.readonly=1
+
+# NXP PCF8563 clock/calendar
+hint.pcf8563_rtc.0.at="iicbus0"
+hint.pcf8563_rtc.0.addr=0xa2


Property changes on: trunk/sys/arm/conf/ETHERNUT5.hints
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/EXYNOS5.common
===================================================================
--- trunk/sys/arm/conf/EXYNOS5.common	                        (rev 0)
+++ trunk/sys/arm/conf/EXYNOS5.common	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,131 @@
+#
+# Kernel configuration for Samsung Exynos 5 SoC.
+#
+# 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: stable/10/sys/arm/conf/EXYNOS5.common 287082 2015-08-23 20:50:22Z ian $
+
+makeoptions	WERROR="-Werror"
+
+options 	HZ=100
+options 	SCHED_ULE		# ULE scheduler
+options 	PREEMPTION		# Enable kernel thread preemption
+options 	INET			# InterNETworking
+options 	INET6			# IPv6 communications protocols
+options 	SCTP			# Stream Control Transmission Protocol
+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
+options 	UFS_GJOURNAL		# Enable gjournal-based UFS journaling
+options 	QUOTA			# Enable disk quotas for UFS
+options 	NFSCL			# New Network Filesystem Client
+options 	NFSLOCKD		# Network Lock Manager
+options 	NFS_ROOT		# NFS usable as /, requires NFSCL
+options 	MSDOSFS			# MSDOS Filesystem
+options 	CD9660			# ISO 9660 Filesystem
+options 	PROCFS			# Process filesystem (requires PSEUDOFS)
+options 	PSEUDOFS		# Pseudo-filesystem framework
+options 	TMPFS			# Efficient memory filesystem
+options 	GEOM_PART_GPT		# GUID Partition Tables
+options 	GEOM_PART_BSD		# BSD partition scheme
+options 	GEOM_PART_MBR		# MBR partition scheme
+options 	COMPAT_43		# Compatible with BSD 4.3 [KEEP THIS!]
+options 	SCSI_DELAY=5000		# Delay (in ms) before probing SCSI
+options 	KTRACE			# ktrace(1) support
+options 	SYSVSHM			# SYSV-style shared memory
+options 	SYSVMSG			# SYSV-style message queues
+options 	SYSVSEM			# SYSV-style semaphores
+options 	_KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
+options 	KBD_INSTALL_CDEV	# install a CDEV entry in /dev
+options 	FREEBSD_BOOT_LOADER	# Process metadata passed from loader(8)
+options 	VFP			# Enable floating point hardware support
+options 	SMP			# Enable multiple cores
+
+# Debugging for use in -current
+makeoptions	DEBUG=-g		# Build kernel with gdb(1) debug symbols
+options 	ALT_BREAK_TO_DEBUGGER
+#options 	VERBOSE_SYSINIT		# Enable verbose sysinit messages
+options 	KDB			# Enable kernel debugger support
+# For minimum debugger support (stable branch) use:
+#options 	KDB_TRACE		# Print a stack trace for a panic
+# For full debugger support use this instead:
+options 	DDB			# Enable the kernel debugger
+#options 	INVARIANTS		# Enable calls of extra sanity checking
+#options 	INVARIANT_SUPPORT	# Extra sanity checks of internal structures, required by INVARIANTS
+#options 	WITNESS			# Enable checks to detect deadlocks and cycles
+#options 	WITNESS_SKIPSPIN	# Don't run witness on spinlocks for speed
+#options 	DIAGNOSTIC
+
+# NFS root from boopt/dhcp
+#options 	BOOTP
+#options 	BOOTP_NFSROOT
+#options 	BOOTP_COMPAT
+#options 	BOOTP_NFSV3
+#options 	BOOTP_WIRED_TO=ue0
+
+options 	ROOTDEVNAME=\"ufs:/dev/da0\"
+
+# MMC/SD/SDIO Card slot support
+device		mmc			# mmc/sd bus
+device		mmcsd			# mmc/sd flash cards
+device		sdhci			# generic sdhci
+
+# Pseudo devices
+
+device		loop
+device		random
+device		pty
+device		md
+device		gpio
+
+# USB support
+options 	USB_HOST_ALIGN=64	# Align usb buffers to cache line size.
+device		usb
+options 	USB_DEBUG
+#options 	USB_REQ_DEBUG
+#options 	USB_VERBOSE
+#device		musb
+device		ehci
+#device		ohci
+
+device		umass
+device		scbus			# SCSI bus (required for ATA/SCSI)
+device		da			# Direct Access (disks)
+device		pass
+
+# SATA
+#device		ata
+#device		atadisk
+#device		mvs
+
+# Serial ports
+device		uart
+
+# I2C (TWSI)
+device		iic
+device		iicbus
+
+# Ethernet
+device		ether
+device		mii
+device		smsc
+device		smscphy
+
+# USB ethernet support, requires miibus
+device		miibus
+device		axe			# ASIX Electronics USB Ethernet
+device		bpf			# Berkeley packet filter


Property changes on: trunk/sys/arm/conf/EXYNOS5.common
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/EXYNOS5250
===================================================================
--- trunk/sys/arm/conf/EXYNOS5250	                        (rev 0)
+++ trunk/sys/arm/conf/EXYNOS5250	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,25 @@
+# Kernel configuration for Samsung Exynos 5250 boards.
+#
+# 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: stable/10/sys/arm/conf/EXYNOS5250 278599 2015-02-11 22:35:32Z ian $
+
+ident		EXYNOS5250
+include		"EXYNOS5.common"
+include		"../samsung/exynos/std.exynos5250"
+
+#FDT
+options 	FDT


Property changes on: trunk/sys/arm/conf/EXYNOS5250
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/EXYNOS5250.common
===================================================================
--- trunk/sys/arm/conf/EXYNOS5250.common	                        (rev 0)
+++ trunk/sys/arm/conf/EXYNOS5250.common	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,132 @@
+# Kernel configuration for Samsung Exynos 5250 boards.
+#
+# 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: stable/10/sys/arm/conf/EXYNOS5250.common 266341 2014-05-17 19:37:04Z ian $
+
+include		"../samsung/exynos/std.exynos5"
+
+makeoptions	MODULES_OVERRIDE=""
+makeoptions	WITHOUT_MODULES="ahc"
+
+makeoptions	DEBUG=-g		# Build kernel with gdb(1) debug symbols
+makeoptions	WERROR="-Werror"
+
+options 	HZ=100
+options 	SCHED_4BSD		# 4BSD scheduler
+options 	INET			# InterNETworking
+options 	INET6			# IPv6 communications protocols
+options 	GEOM_PART_BSD		# BSD partition scheme
+options 	GEOM_PART_MBR		# MBR partition scheme
+options 	TMPFS			# Efficient memory filesystem
+options 	FFS			# Berkeley Fast Filesystem
+options 	SOFTUPDATES
+options 	UFS_ACL			# Support for access control lists
+options 	UFS_DIRHASH		# Improve performance on big directories
+options 	MSDOSFS			# MSDOS Filesystem
+options 	CD9660			# ISO 9660 Filesystem
+options 	PROCFS			# Process filesystem (requires PSEUDOFS)
+options 	PSEUDOFS		# Pseudo-filesystem framework
+options 	COMPAT_43		# Compatible with BSD 4.3 [KEEP THIS!]
+options 	SCSI_DELAY=5000		# Delay (in ms) before probing SCSI
+options 	KTRACE
+options 	SYSVSHM			# SYSV-style shared memory
+options 	SYSVMSG			# SYSV-style message queues
+options 	SYSVSEM			# SYSV-style semaphores
+options 	_KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time extensions
+options 	KBD_INSTALL_CDEV
+options 	PREEMPTION
+options 	FREEBSD_BOOT_LOADER
+options 	VFP			# vfp/neon
+
+# Debugging
+makeoptions	DEBUG=-g		# Build kernel with gdb(1) debug symbols
+options 	BREAK_TO_DEBUGGER
+#options	VERBOSE_SYSINIT		# Enable verbose sysinit messages
+options 	KDB
+options 	DDB			# Enable the kernel debugger
+#options 	INVARIANTS		# Enable calls of extra sanity checking
+#options 	INVARIANT_SUPPORT	# Extra sanity checks of internal structures, required by INVARIANTS
+#options	WITNESS			# Enable checks to detect deadlocks and cycles
+#options	WITNESS_SKIPSPIN	# Don't run witness on spinlocks for speed
+#options 	DIAGNOSTIC
+
+# NFS support
+options 	NFSCL			# Network Filesystem Client
+options 	NFSLOCKD		# Network Lock Manager
+options 	NFS_ROOT		# NFS usable as /, requires NFSCLIENT
+
+# Uncomment this for NFS root
+#options	NFS_ROOT		# NFS usable as /, requires NFSCL
+#options	BOOTP_NFSROOT
+#options	BOOTP_COMPAT
+#options	BOOTP
+#options	BOOTP_NFSV3
+#options	BOOTP_WIRED_TO=ue0
+
+device		mmc			# mmc/sd bus
+device		mmcsd			# mmc/sd flash cards
+device		sdhci			# generic sdhci
+
+options 	ROOTDEVNAME=\"ufs:/dev/da0\"
+
+#options	SMP
+
+# Pseudo devices
+
+device		loop
+device		random
+device		pty
+device		md
+device		gpio
+
+# USB support
+options 	USB_HOST_ALIGN=64	# Align usb buffers to cache line size.
+device		usb
+options 	USB_DEBUG
+#options	USB_REQ_DEBUG
+#options	USB_VERBOSE
+#device		musb
+device		ehci
+#device		ohci
+
+device		umass
+device		scbus			# SCSI bus (required for SCSI)
+device		da			# Direct Access (disks)
+device		pass
+
+# SATA
+#device		ata
+#device		atadisk
+#device		mvs
+
+# Serial ports
+device		uart
+
+# I2C (TWSI)
+device		iic
+device		iicbus
+
+# Ethernet
+device		ether
+device		mii
+device		smsc
+device		smscphy
+
+# USB ethernet support, requires miibus
+device		miibus
+device		axe			# ASIX Electronics USB Ethernet
+device		bpf			# Berkeley packet filter


Property changes on: trunk/sys/arm/conf/EXYNOS5250.common
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/EXYNOS5420
===================================================================
--- trunk/sys/arm/conf/EXYNOS5420	                        (rev 0)
+++ trunk/sys/arm/conf/EXYNOS5420	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,25 @@
+# Kernel configuration for Samsung Exynos 5420 boards.
+#
+# 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: stable/10/sys/arm/conf/EXYNOS5420 278599 2015-02-11 22:35:32Z ian $
+
+ident		EXYNOS5420
+include		"EXYNOS5.common"
+include		"../samsung/exynos/std.exynos5420"
+
+#FDT
+options 	FDT


Property changes on: trunk/sys/arm/conf/EXYNOS5420
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/GUMSTIX
===================================================================
--- trunk/sys/arm/conf/GUMSTIX	                        (rev 0)
+++ trunk/sys/arm/conf/GUMSTIX	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,94 @@
+# GUMSTIX -- Custom configuration for the Gumstix Basix and Connex boards from
+# gumstix.com
+#
+# For more information on this file, please read 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: stable/10/sys/arm/conf/GUMSTIX 285365 2015-07-10 22:10:00Z gjb $
+
+ident		GUMSTIX
+cpu		CPU_XSCALE_PXA2X0
+
+# This probably wants to move somewhere else.  Maybe we can create a basic
+# PXA2X0 config, then make a GUMSTIX config that includes the basic one,
+# adds the smc and smcphy devices and pulls in this hints file.
+hints		"GUMSTIX.hints"
+
+options 	PHYSADDR=0xa0000000
+options 	KERNPHYSADDR=0xa0200000	
+options 	KERNVIRTADDR=0xc0200000	# Used in ldscript.arm
+
+include		"../xscale/pxa/std.pxa"
+makeoptions	MODULES_OVERRIDE=""
+
+makeoptions	DEBUG=-g		# Build kernel with gdb(1) debug symbols
+options 	HZ=100
+#options 	DEVICE_POLLING
+
+options 	SCHED_4BSD		# 4BSD scheduler
+options 	INET			# InterNETworking
+#options 	INET6			# IPv6 communications protocols
+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
+options 	NFSCL			# New Network Filesystem Client
+#options 	NFSD			# New Network Filesystem Server
+options 	NFS_ROOT		# NFS usable as /, requires NFSCL
+options		GEOM_PART_GPT		# GUID Partition Tables
+options 	GEOM_PART_BSD		# BSD partition scheme
+options 	GEOM_PART_MBR		# MBR partition scheme
+options 	GEOM_LABEL		# Provides labelization 
+options 	TMPFS			# Efficient memory filesystem
+options 	MSDOSFS			# MSDOS Filesystem
+#options 	CD9660			# ISO 9660 Filesystem
+#options 	PROCFS			# Process filesystem (requires PSEUDOFS)
+options 	PSEUDOFS		# Pseudo-filesystem framework
+options 	COMPAT_43		# Compatible with BSD 4.3 [KEEP THIS!]
+options 	SCSI_DELAY=5000		# Delay (in ms) before probing SCSI
+options 	KTRACE			# ktrace(1) support
+options 	SYSVSHM			# SYSV-style shared memory
+options 	SYSVMSG			# SYSV-style message queues
+options 	SYSVSEM			# SYSV-style semaphores
+options 	_KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time extensions
+options 	KBD_INSTALL_CDEV	# install a CDEV entry in /dev
+options 	BOOTP
+options 	BOOTP_NFSROOT
+options 	BOOTP_WIRED_TO=smc0
+options 	BOOTP_COMPAT
+options 	BOOTP_NFSV3
+options 	BOOTP_BLOCKSIZE=4096
+options 	PREEMPTION
+device		loop
+device		ether
+device		mii
+device		mii_bitbang
+device		smc
+device		smcphy
+device		uart
+device		uart_ns8250
+
+# Debugging for use in -current
+options 	KDB
+options 	DDB			# Enable the kernel debugger
+#options 	DEADLKRES		# Enable the deadlock resolver
+#options 	INVARIANTS		# Enable calls of extra sanity checking
+#options 	INVARIANT_SUPPORT	# Extra sanity checks of internal structures, required by INVARIANTS
+#options 	WITNESS			# Enable checks to detect deadlocks and cycles
+#options 	WITNESS_SKIPSPIN	# Don't run witness on spinlocks for speed
+#options 	DIAGNOSTIC
+
+device		md
+device		random			# Entropy device


Property changes on: trunk/sys/arm/conf/GUMSTIX
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/GUMSTIX-QEMU
===================================================================
--- trunk/sys/arm/conf/GUMSTIX-QEMU	                        (rev 0)
+++ trunk/sys/arm/conf/GUMSTIX-QEMU	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,25 @@
+# GUMSTIX-QEMU -- Custom configuration for the QEMU emulated Gumstix target
+#
+# For more information on this file, please read 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: stable/10/sys/arm/conf/GUMSTIX-QEMU 240572 2012-09-16 19:48:48Z jmg $
+
+include 	GUMSTIX
+
+ident		GUMSTIX-QEMU
+
+options 	QEMU_WORKAROUNDS
+nooptions	ARM_CACHE_LOCK_ENABLE	# QEMU does not implement this


Property changes on: trunk/sys/arm/conf/GUMSTIX-QEMU
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/GUMSTIX.hints
===================================================================
--- trunk/sys/arm/conf/GUMSTIX.hints	                        (rev 0)
+++ trunk/sys/arm/conf/GUMSTIX.hints	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,19 @@
+# $FreeBSD: stable/10/sys/arm/conf/GUMSTIX.hints 179595 2008-06-06 05:08:09Z benno $
+
+# Make sure we don't trample important bits in the UART registers.
+hint.uart.0.ier_mask="0xe0"
+hint.uart.0.ier_rxbits="0x1d"
+hint.uart.1.ier_mask="0xe0"
+hint.uart.1.ier_rxbits="0x1d"
+hint.uart.2.ier_mask="0xe0"
+hint.uart.2.ier_rxbits="0x1d"
+
+# SMSC LAN91C111s found on the netCF, netMMC and netDUO boards.
+hint.smc.0.at="smi0"
+hint.smc.0.mem="0x04000300"
+hint.smc.0.size="0x10"
+hint.smc.0.irq="100"
+hint.smc.1.at="smi0"
+hint.smc.1.mem="0x08000300"
+hint.smc.1.size="0x10"
+hint.smc.1.irq="91"


Property changes on: trunk/sys/arm/conf/GUMSTIX.hints
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/HL200
===================================================================
--- trunk/sys/arm/conf/HL200	                        (rev 0)
+++ trunk/sys/arm/conf/HL200	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,144 @@
+# Kernel configuration for the AT91RM9200 based Hot-e configuration file
+#
+# For more information on this file, please read 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: stable/10/sys/arm/conf/HL200 278676 2015-02-13 15:27:46Z ian $
+
+#NO_UNIVERSE
+
+ident		HL200
+
+include "../at91/std.hl200"
+
+#To statically compile in device wiring instead of /boot/device.hints
+hints		"KB920X.hints"
+makeoptions	MODULES_OVERRIDE=""
+
+makeoptions	DEBUG=-g		# Build kernel with gdb(1) debug symbols
+options 	DDB
+options 	KDB
+
+options 	SCHED_4BSD		# 4BSD scheduler
+options 	INET			# InterNETworking
+#options 	INET6			# IPv6 communications protocols
+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
+#options 	MD_ROOT			# MD is a potential root device
+#options 	MD_ROOT_SIZE=4096	# 4MB ram disk
+#options 	ROOTDEVNAME=\"ufs:/dev/mmcsd0s1a\"
+options 	NFSCL			# New Network Filesystem Client
+#options 	NFSD			# New Network Filesystem Server
+#options 	NFSLOCKD		# Network Lock Manager
+options 	NFS_ROOT		# NFS usable as /, requires NFSCL
+options 	BOOTP_NFSROOT
+options 	BOOTP
+options 	BOOTP_NFSV3
+options 	BOOTP_WIRED_TO=ate0
+options 	BOOTP_COMPAT
+
+options 	GEOM_PART_BSD		# BSD partition scheme
+options 	GEOM_PART_MBR		# MBR partition scheme
+options 	TMPFS			# Efficient memory filesystem
+#options 	MSDOSFS			# MSDOS Filesystem
+#options 	CD9660			# ISO 9660 Filesystem
+#options 	PROCFS			# Process filesystem (requires PSEUDOFS)
+options 	PSEUDOFS		# Pseudo-filesystem framework
+#options 	SCSI_DELAY=5000		# Delay (in ms) before probing SCSI
+#options 	KTRACE			# ktrace(1) support
+options 	SYSVSHM			# SYSV-style shared memory
+options 	SYSVMSG			# SYSV-style message queues
+options 	SYSVSEM			# SYSV-style semaphores
+options 	_KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time extensions
+#options 	NO_SYSCTL_DESCR
+options 	MUTEX_NOINLINE
+options 	RWLOCK_NOINLINE
+options 	NO_FFS_SNAPSHOT
+options 	NO_SWAPPING
+device		random
+device		loop
+device		ether
+device		uart
+device		ate
+device		mii
+device		lxtphy
+
+# Debugging for use in -current
+#options 	DEADLKRES		# Enable the deadlock resolver
+#options 	INVARIANTS		# Enable calls of extra sanity checking
+#options 	INVARIANT_SUPPORT	# Extra sanity checks of internal structures, required by INVARIANTS
+#options 	WITNESS			# Enable checks to detect deadlocks and cycles
+#options 	WITNESS_SKIPSPIN	# Don't run witness on spinlocks for speed
+
+device		md
+device		at91_twi		# TWI: Two Wire Interface
+device		at91_spi		# SPI:
+device		spibus
+# MMC/SD
+device		at91_mci
+device		mmc
+device		mmcsd
+# iic
+device		iic
+device		iicbus
+device		icee
+
+device		bpf
+# USB support
+options 	USB_DEBUG		# enable debug msgs
+device		ohci			# OHCI localbus->USB interface
+device		usb			# USB Bus (required)
+#device		udbp			# USB Double Bulk Pipe devices
+device		uhid			# "Human Interface Devices"
+device		ulpt			# Printer
+device		umass			# Disks/Mass storage - Requires scbus and da
+device		urio			# Diamond Rio 500 MP3 player
+# USB Serial devices
+device		uark			# Technologies ARK3116 based serial adapters
+device		ubsa			# Belkin F5U103 and compatible serial adapters
+#device		ubser			# not yet converted.
+device		uftdi			# For FTDI usb serial adapters
+device		uipaq			# Some WinCE based devices
+device		uplcom			# Prolific PL-2303 serial adapters
+device		uslcom			# SI Labs CP2101/CP2102 serial adapters
+device		uvisor			# Visor and Palm devices
+device		uvscom			# USB serial support for DDI pocket's PHS
+# USB Ethernet, requires miibus
+device		miibus
+device		aue			# ADMtek USB Ethernet
+device		axe			# ASIX Electronics USB Ethernet
+device		cdce			# Generic USB over Ethernet
+device		cue			# CATC USB Ethernet
+device		kue			# Kawasaki LSI USB Ethernet
+device		rue			# RealTek RTL8150 USB Ethernet
+device		udav			# Davicom DM9601E USB
+# USB Wireless
+device		rum			# Ralink Technology RT2501USB wireless NICs
+device		uath			# Atheros AR5523 wireless NICs
+device		ural			# Ralink Technology RT2500USB wireless NICs
+device		zyd			# ZyDAS zd1211/zd1211b wireless NICs
+# SCSI peripherals
+device		scbus			# SCSI bus (required for ATA/SCSI)
+device		da			# Direct Access (disks)
+device		cd			# CD
+device		pass			# Passthrough device (direct ATA/SCSI access)
+# Wireless NIC cards
+device		wlan			# 802.11 support
+device		wlan_wep		# 802.11 WEP support
+device		wlan_ccmp		# 802.11 CCMP support
+device		wlan_tkip		# 802.11 TKIP support
+device		wlan_amrr		# AMRR transmit rate control algorithm


Property changes on: trunk/sys/arm/conf/HL200
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/HL201
===================================================================
--- trunk/sys/arm/conf/HL201	                        (rev 0)
+++ trunk/sys/arm/conf/HL201	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,137 @@
+# Kernel configuration for the AT91SAM9G20 based Hot-e configuration file
+#
+# For more information on this file, please read 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: stable/10/sys/arm/conf/HL201 283368 2015-05-24 14:25:03Z ian $
+
+#NO_UNIVERSE
+
+ident		HL201
+
+include "../at91/std.hl201"
+
+#To statically compile in device wiring instead of /boot/device.hints
+hints		"HL201.hints"
+makeoptions	MODULES_OVERRIDE=""
+
+makeoptions	DEBUG=-g		# Build kernel with gdb(1) debug symbols
+options 	DDB
+options 	KDB
+
+options 	SCHED_4BSD		# 4BSD scheduler
+options 	INET			# InterNETworking
+#options 	INET6			# IPv6 communications protocols
+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
+#options 	MD_ROOT			# MD is a potential root device
+#options 	MD_ROOT_SIZE=4096	# 4MB ram disk
+options 	NANDFS			# NAND file system
+options 	ROOTDEVNAME=\"ufs:/dev/mmcsd0s1a\"
+options 	NFSCL			# New Network Filesystem Client
+#options 	NFSD			# New Network Filesystem Server
+#options 	NFSLOCKD		# Network Lock Manager
+options 	NFS_ROOT		# NFS usable as /, requires NFSCL
+#options 	BOOTP_NFSROOT
+#options 	BOOTP
+#options 	BOOTP_NFSV3
+#options 	BOOTP_WIRED_TO=ate0
+#options 	BOOTP_COMPAT
+
+options 	ALT_BREAK_TO_DEBUGGER
+
+options 	GEOM_PART_BSD		# BSD partition scheme
+options 	GEOM_PART_MBR		# MBR partition scheme
+options 	TMPFS			# Efficient memory filesystem
+#options 	MSDOSFS			# MSDOS Filesystem
+#options 	CD9660			# ISO 9660 Filesystem
+#options 	PROCFS			# Process filesystem (requires PSEUDOFS)
+options 	PSEUDOFS		# Pseudo-filesystem framework
+#options 	SCSI_DELAY=5000		# Delay (in ms) before probing SCSI
+#options 	KTRACE			# ktrace(1) support
+options 	SYSVSHM			# SYSV-style shared memory
+options 	SYSVMSG			# SYSV-style message queues
+options 	SYSVSEM			# SYSV-style semaphores
+options 	_KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time extensions
+options 	MUTEX_NOINLINE
+options 	RWLOCK_NOINLINE
+options 	NO_FFS_SNAPSHOT
+options 	NO_SWAPPING
+device		random
+device		loop
+device		ether
+device		uart
+device		ate
+device		mii
+#device		lxtphy
+
+# Debugging for use in -current
+#options 	INVARIANTS		# Enable calls of extra sanity checking
+#options 	INVARIANT_SUPPORT	# Extra sanity checks of internal structures, required by INVARIANTS
+#options 	WITNESS			# Enable checks to detect deadlocks and cycles
+#options 	WITNESS_SKIPSPIN	# Don't run witness on spinlocks for speed
+#options 	DIAGNOSTIC
+
+device		md
+device		bpf
+
+# USB support
+device		ohci			# OHCI localbus->USB interface
+device		usb			# USB Bus (required)
+#device		udbp			# USB Double Bulk Pipe devices
+device		uhid			# "Human Interface Devices"
+#device		ulpt			# Printer
+device		umass			# Disks/Mass storage - Requires scbus and da
+
+# USB Ethernet, requires miibus
+device		miibus
+#device		aue			# ADMtek USB Ethernet
+#device		axe			# ASIX Electronics USB Ethernet
+#device		cdce			# Generic USB over Ethernet
+#device		cue			# CATC USB Ethernet
+#device		kue			# Kawasaki LSI USB Ethernet
+#device		rue			# RealTek RTL8150 USB Ethernet
+device		udav			# Davicom DM9601E USB
+# USB Wireless
+#device		rum			# Ralink Technology RT2501USB wireless NICs
+#device		uath			# Atheros AR5523 wireless NICs
+#device		ural			# Ralink Technology RT2500USB wireless NICs
+#device		zyd			# ZyDAS zd1211/zd1211b wireless NICs
+# SCSI peripherals
+device		scbus			# SCSI bus (required for ATA/SCSI)
+device		da			# Direct Access (disks)
+device		cd			# CD
+device		pass			# Passthrough device (direct ATA/SCSI access)
+# Wireless NIC cards
+#device		wlan			# 802.11 support
+#device		wlan_wep		# 802.11 WEP support
+#device		wlan_ccmp		# 802.11 CCMP support
+#device		wlan_tkip		# 802.11 TKIP support
+#device		wlan_amrr		# AMRR transmit rate control algorithm
+options 	ROOTDEVNAME=\"ufs:da0s1a\"
+
+# NAND Flash - my board as 128MB Samsung part, YMMV.
+device		nand			# NAND interface on CS3
+
+# Coming soon, but not yet
+#options 	FDT
+#options 	FDT_DTB_STATIC
+#makeoptions	FDT_DTS_FILE=hl201.dts
+
+options 	EARLY_PRINTF
+options 	SOCDEV_PA=0xfc000000
+options 	SOCDEV_VA=0xdc000000


Property changes on: trunk/sys/arm/conf/HL201
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/HL201.hints
===================================================================
--- trunk/sys/arm/conf/HL201.hints	                        (rev 0)
+++ trunk/sys/arm/conf/HL201.hints	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,48 @@
+# $FreeBSD: stable/10/sys/arm/conf/HL201.hints 239323 2012-08-16 04:53:30Z imp $
+
+# Atmel AT45DB21D
+hint.at45d.0.at="spibus0"
+hint.at45d.0.cs=0
+# Area 0:	00000000 to 000041FF (RO) Bootstrap
+# Area 1:	00004200 to 000083FF      Environment
+# Area 2:	00008400 to 00041FFF (RO) U-Boot
+# Area 3:	00042000 to 00251FFF      Kernel
+# Area 4:	00252000 to 0083FFFF      FS
+# bootstrap
+hint.map.0.at="flash/spi0"
+hint.map.0.start=0x00000000
+hint.map.0.end=0x000041ff
+hint.map.0.name="bootstrap"
+hint.map.0.readonly=1
+# uboot environment
+hint.map.1.at="flash/spi0"
+hint.map.1.start=0x00004200
+hint.map.1.end=0x00083ff
+hint.map.1.name="uboot-env"
+#hint.map.1.readonly=1
+# uboot
+hint.map.2.at="flash/spi0"
+hint.map.2.start=0x00008400
+hint.map.2.end=0x00041fff
+hint.map.2.name="uboot"
+hint.map.2.readonly=1
+# kernel
+hint.map.3.at="flash/spi0"
+hint.map.3.start=0x00042000
+hint.map.3.end=0x00251fff
+hint.map.3.name="fs"
+#hint.map.3.readonly=1
+# fs
+hint.map.4.at="flash/spi0"
+hint.map.4.start=0x00252000
+hint.map.4.end=0x0083ffff
+hint.map.4.name="fs"
+#hint.map.4.readonly=1
+
+# EEPROM at24c512 - 512kbit 65,536x8 memory
+hint.icee.0.at="iicbus0"
+hint.icee.0.addr=0xa0
+hint.icee.0.type=16
+hint.icee.0.size=65536
+hint.icee.0.rd_sz=128
+hint.icee.0.wr_sz=128


Property changes on: trunk/sys/arm/conf/HL201.hints
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/IMX53
===================================================================
--- trunk/sys/arm/conf/IMX53	                        (rev 0)
+++ trunk/sys/arm/conf/IMX53	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,174 @@
+#
+# Kernel configuration for i.MX53 boards
+#
+# 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: stable/10/sys/arm/conf/IMX53 283368 2015-05-24 14:25:03Z ian $
+
+ident		IMX53
+
+include 	"../freescale/imx/std.imx53"
+
+options 	SCHED_4BSD		# 4BSD scheduler
+options 	PREEMPTION		# Enable kernel thread preemption
+options 	INET			# InterNETworking
+options 	INET6			# IPv6 communications protocols
+options 	SCTP			# Stream Control Transmission Protocol
+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
+options 	UFS_GJOURNAL		# Enable gjournal-based UFS journaling
+options 	QUOTA			# Enable disk quotas for UFS
+options 	NFSCL			# New Network Filesystem Client
+#options 	NFSD			# New Network Filesystem Server
+options 	NFSLOCKD		# Network Lock Manager
+options 	NFS_ROOT		# NFS usable as /, requires NFSCL
+options 	MSDOSFS			# MSDOS Filesystem
+options 	CD9660			# ISO 9660 Filesystem
+options 	PROCFS			# Process filesystem (requires PSEUDOFS)
+options 	PSEUDOFS		# Pseudo-filesystem framework
+options 	TMPFS			# Efficient memory filesystem
+options 	GEOM_PART_GPT		# GUID Partition Tables
+options 	GEOM_PART_BSD		# BSD partition scheme
+options 	GEOM_PART_MBR		# MBR partition scheme
+options 	GEOM_LABEL		# Provides labelization
+#options 	COMPAT_FREEBSD5		# Compatible with FreeBSD5
+#options 	COMPAT_FREEBSD6		# Compatible with FreeBSD6
+#options 	COMPAT_FREEBSD7		# Compatible with FreeBSD7
+options 	SCSI_DELAY=5000		# Delay (in ms) before probing SCSI
+options 	KTRACE			# ktrace(1) support
+options 	SYSVSHM			# SYSV-style shared memory
+options 	SYSVMSG			# SYSV-style message queues
+options 	SYSVSEM			# SYSV-style semaphores
+options 	_KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
+options 	KBD_INSTALL_CDEV	# install a CDEV entry in /dev
+options 	INCLUDE_CONFIG_FILE	# Include this file in kernel
+options 	VFP			# Enable floating point hardware support
+
+# Debugging for use in -current
+makeoptions	DEBUG=-g		# Build kernel with gdb(1) debug symbols
+options 	KDB			# Enable kernel debugger support
+# For minimum debugger support (stable branch) use:
+#options 	KDB_TRACE		# Print a stack trace for a panic
+# For full debugger support use this instead:
+options 	DDB			# Enable the kernel debugger
+#options 	GDB			# Support remote GDB
+options 	DEADLKRES		# Enable the deadlock resolver
+options 	INVARIANTS		# Enable calls of extra sanity checking
+options 	INVARIANT_SUPPORT	# Extra sanity checks of internal structures, required by INVARIANTS
+options 	WITNESS			# Enable checks to detect deadlocks and cycles
+#options 	WITNESS_SKIPSPIN	# Don't run witness on spinlocks for speed
+
+# kernel/memory size reduction
+#options 	MUTEX_NOINLINE
+#options 	NO_FFS_SNAPSHOT
+#options 	NO_SWAPPING
+#options 	NO_SYSCTL_DESCR
+#options 	RWLOCK_NOINLINE
+
+# The `bpf' device enables the Berkeley Packet Filter.
+# Be aware of the administrative consequences of enabling this!
+# Note that 'bpf' is required for DHCP.
+device		bpf			# Berkeley packet filter
+
+# Pseudo devices.
+device		loop			# Network loopback
+device		random			# Entropy device
+device		ether			# Ethernet support
+#device		vlan			# 802.1Q VLAN support
+#device		tun			# Packet tunnel.
+device		md			# Memory "disks"
+#device		gif			# IPv6 and IPv4 tunneling
+#device		faith			# IPv6-to-IPv4 relaying (translation)
+#device		firmware		# firmware assist module
+
+# Ethernet
+device		ffec			# Freescale Fast Ethernet Controller
+device		miibus			# Standard mii bus
+
+# Serial (COM) ports
+device		uart			# Multi-uart driver
+options 	ALT_BREAK_TO_DEBUGGER
+
+device		ata
+device		atapci			# Only for helper functions
+device		imxata
+options 	ATA_STATIC_ID		# Static device numbering
+
+device		gpio
+device		gpioled
+
+device		fsliic
+device		iic
+device		iicbus
+
+# SCSI peripherals
+device		scbus			# SCSI bus (required for ATA/SCSI)
+device		da			# Direct Access (disks)
+device		cd			# CD
+device		pass			# Passthrough device (direct ATA/SCSI access)
+
+# USB support
+options 	USB_HOST_ALIGN=64	# Align usb buffers to cache line size.
+options 	USB_DEBUG		# enable debug msgs
+device		ehci			# OHCI USB interface
+device		usb			# USB Bus (required)
+device		umass			# Disks/Mass storage - Requires scbus and da
+device		uhid			# "Human Interface Devices"
+#device		ukbd			# Allow keyboard like HIDs to control console
+device		ums
+
+# USB Ethernet, requires miibus
+#device		miibus
+#device		aue			# ADMtek USB Ethernet
+#device		axe			# ASIX Electronics USB Ethernet
+#device		cdce			# Generic USB over Ethernet
+#device		cue			# CATC USB Ethernet
+#device		kue			# Kawasaki LSI USB Ethernet
+#device		rue			# RealTek RTL8150 USB Ethernet
+#device		udav			# Davicom DM9601E USB
+
+# USB Wireless
+#device		rum			# Ralink Technology RT2501USB wireless NICs
+
+# Watchdog timer.
+# WARNING: can't be disabled!!!
+device		imxwdt			# Watchdog
+
+# Wireless NIC cards
+device		wlan			# 802.11 support
+device		wlan_wep		# 802.11 WEP support
+device		wlan_ccmp		# 802.11 CCMP support
+device		wlan_tkip		# 802.11 TKIP support
+device		wlan_amrr		# AMRR transmit rate control algorithm
+
+# MMC
+#device  	sdhci			# SD controller
+#device  	mmc			# SD/MMC protocol
+#device  	mmcsd			# SDCard disk device
+
+
+# Flattened Device Tree
+options 	FDT			# Configure using FDT/DTB data
+
+# NOTE: serial console will be disabled if syscons enabled
+# Uncomment following lines for framebuffer/syscons support
+#device		sc
+#device		vt
+#device		kbdmux
+#options 	SC_DFLT_FONT		# compile font in
+#makeoptions	SC_DFLT_FONT=cp437


Property changes on: trunk/sys/arm/conf/IMX53
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/IMX53-QSB
===================================================================
--- trunk/sys/arm/conf/IMX53-QSB	                        (rev 0)
+++ trunk/sys/arm/conf/IMX53-QSB	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,38 @@
+# Kernel configuration for Freescale i.MX53 Quick Start 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: stable/10/sys/arm/conf/IMX53-QSB 283368 2015-05-24 14:25:03Z ian $
+
+#NO_UNIVERSE
+
+include		"IMX53"
+ident		IMX53-QSB
+
+options 	HZ=250			# 4ms scheduling quantum
+
+# required for netbooting
+#options 	BOOTP
+#options 	BOOTP_COMPAT
+#options 	BOOTP_NFSROOT
+#options 	BOOTP_NFSV3
+#options 	BOOTP_WIRED_TO=ue0
+
+#options 	ROOTDEVNAME=\"ufs:ada0s2a\"
+
+# Flattened Device Tree
+options 	FDT_DTB_STATIC
+makeoptions	FDT_DTS_FILE=imx53-qsb.dts


Property changes on: trunk/sys/arm/conf/IMX53-QSB
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/IMX6
===================================================================
--- trunk/sys/arm/conf/IMX6	                        (rev 0)
+++ trunk/sys/arm/conf/IMX6	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,164 @@
+#
+# Kernel configuration for Freescale i.MX6 systems.
+#
+# 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: stable/10/sys/arm/conf/IMX6 287079 2015-08-23 20:16:13Z ian $
+
+ident		IMX6
+include 	"../freescale/imx/std.imx6"
+
+options 	HZ=500			# Scheduling quantum is 2 milliseconds.
+options 	SCHED_ULE		# ULE scheduler
+options 	PREEMPTION		# Enable kernel thread preemption
+options 	INET			# InterNETworking
+options 	INET6			# IPv6 communications protocols
+options 	SCTP			# Stream Control Transmission Protocol
+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
+options 	UFS_GJOURNAL		# Enable gjournal-based UFS journaling
+options 	QUOTA			# Enable disk quotas for UFS
+options 	NFSCL			# New Network Filesystem Client
+#options 	NFSD			# New Network Filesystem Server
+options 	NFSLOCKD		# Network Lock Manager
+options 	NFS_ROOT		# NFS usable as /, requires NFSCL
+options 	MSDOSFS			# MSDOS Filesystem
+options 	CD9660			# ISO 9660 Filesystem
+options 	PROCFS			# Process filesystem (requires PSEUDOFS)
+options 	PSEUDOFS		# Pseudo-filesystem framework
+options 	TMPFS			# Efficient memory filesystem
+options 	GEOM_PART_GPT		# GUID Partition Tables
+options 	GEOM_PART_BSD		# BSD partition scheme
+options 	GEOM_PART_MBR		# MBR partition scheme
+options 	GEOM_LABEL		# Provides labelization
+options 	KTRACE			# ktrace(1) support
+options 	SYSVSHM			# SYSV-style shared memory
+options 	SYSVMSG			# SYSV-style message queues
+options 	SYSVSEM			# SYSV-style semaphores
+options 	_KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
+options 	KBD_INSTALL_CDEV	# install a CDEV entry in /dev
+options 	INCLUDE_CONFIG_FILE	# Include this file in kernel
+options 	FREEBSD_BOOT_LOADER	# Process metadata passed from loader(8)
+options 	VFP			# Enable floating point hardware support
+options 	SMP			# Enable multiple cores
+
+# Debugging for use in -current
+makeoptions	DEBUG=-g		# Build kernel with gdb(1) debug symbols
+options 	KDB			# Enable kernel debugger support
+# For minimum debugger support (stable branch) use:
+#options 	KDB_TRACE		# Print a stack trace for a panic
+# For full debugger support use this instead:
+options 	DDB			# Enable the kernel debugger
+#options 	GDB			# Support remote GDB.
+# Other debugging options...
+options 	ALT_BREAK_TO_DEBUGGER	# Use <CR><tilde><ctrl-b> to enter debugger.
+#options 	DEADLKRES		# Enable the deadlock resolver
+#options 	INVARIANTS		# Enable calls of extra sanity checking
+#options 	INVARIANT_SUPPORT	# Extra sanity checks of internal structures, required by INVARIANTS
+#options 	WITNESS			# Enable checks to detect deadlocks and cycles
+#options 	WITNESS_SKIPSPIN	# Don't run witness on spinlocks for speed
+#options 	DIAGNOSTIC
+
+# NFS root from boopt/dhcp
+#options 	BOOTP
+#options 	BOOTP_NFSROOT
+#options 	BOOTP_COMPAT
+#options 	BOOTP_NFSV3
+#options 	BOOTP_WIRED_TO=ffec0
+
+# U-Boot stuff lives on slice 1, FreeBSD on slice 2.
+options 	ROOTDEVNAME=\"ufs:mmcsd0s2a\"
+
+# Pseudo devices.
+device		loop			# Network loopback
+device		random			# Entropy device
+device		vlan			# 802.1Q VLAN support
+device		tun			# Packet tunnel.
+device		md			# Memory "disks"
+#device  	faith			# IPv6-to-IPv4 relaying (translation)
+#device		gif			# IPv6 and IPv4 tunneling
+#device		firmware		# firmware assist module
+device		ether			# Ethernet support
+device		miibus			# Required for ethernet
+device	 	bpf			# Berkeley packet filter (required for DHCP)
+
+# General-purpose input/output
+device		gpio
+
+# Serial (COM) ports
+device		uart			# Multi-uart driver
+
+# SDCard
+device		sdhci			# SD controller
+device		mmc			# SD/MMC protocol
+device		mmcsd			# SDCard disk device
+
+# SCSI peripherals
+device		scbus			# SCSI bus (required for ATA/SCSI)
+device		da			# Direct Access (disks)
+device		cd			# CD
+device		pass			# Passthrough device (direct ATA/SCSI access)
+
+# USB support
+#options 	USB_DEBUG		# enable debug msgs
+device		ehci			# OHCI USB interface
+device		usb			# USB Bus (required)
+device		umass			# Disks/Mass storage - Requires scbus and da
+device		uhid			# "Human Interface Devices"
+device		u3g			# USB modems
+#device		ukbd			# Allow keyboard like HIDs to control console
+#device		ums			# USB mouse
+
+# USB Ethernet, requires miibus
+#device		aue			# ADMtek USB Ethernet
+#device		axe			# ASIX Electronics USB Ethernet
+#device		cdce			# Generic USB over Ethernet
+#device		cue			# CATC USB Ethernet
+#device		kue			# Kawasaki LSI USB Ethernet
+#device		rue			# RealTek RTL8150 USB Ethernet
+#device		udav			# Davicom DM9601E USB
+
+# USB Wireless
+#device		rum			# Ralink Technology RT2501USB wireless NICs
+
+# Wireless NIC cards
+#device		wlan			# 802.11 support
+#device		wlan_wep		# 802.11 WEP support
+#device		wlan_ccmp		# 802.11 CCMP support
+#device		wlan_tkip		# 802.11 TKIP support
+#device		wlan_amrr		# AMRR transmit rate control algorithm
+
+# NOTE: serial console will be disabled if syscons enabled
+# Uncomment following lines for framebuffer/syscons support
+# Wandboard has no video console support yet.
+#device		sc
+#device		kbdmux
+#options 	SC_DFLT_FONT		# compile font in
+#makeoptions	SC_DFLT_FONT=cp437
+
+# Flattened Device Tree
+options 	FDT			# Configure using FDT/DTB data
+makeoptions	MODULES_EXTRA=dtb/imx6
+
+# SoC-specific devices
+device		ffec			# Freescale Fast Ethernet Controller
+device		fsliic			# Freescale i2c/iic
+device		iic			# iic protocol
+device		iicbus			# iic bus
+device		imxwdt			# Watchdog. WARNING: can't be disabled!!!
+


Property changes on: trunk/sys/arm/conf/IMX6
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/IQ31244
===================================================================
--- trunk/sys/arm/conf/IQ31244	                        (rev 0)
+++ trunk/sys/arm/conf/IQ31244	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,110 @@
+# IQ31244 -- Custom kernel configuration file for FreeBSD/arm on the IQ31244
+#
+# For more information on this file, please read 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: stable/10/sys/arm/conf/IQ31244 278677 2015-02-13 15:32:31Z ian $
+
+ident		IQ31244
+
+options 	PHYSADDR=0xa0000000
+options 	KERNPHYSADDR=0xa0200000	
+options 	KERNVIRTADDR=0xc0200000	# Used in ldscript.arm
+options 	FLASHADDR=0xf0000000
+options 	LOADERRAMADDR=0x00000000
+
+include		"../xscale/i80321/std.iq31244"
+makeoptions	MODULES_OVERRIDE=""
+
+#makeoptions	DEBUG=-g		# Build kernel with gdb(1) debug symbols
+makeoptions	CONF_CFLAGS=-mcpu=xscale
+options 	HZ=100
+#options 	DEVICE_POLLING
+
+options 	SCHED_4BSD		# 4BSD scheduler
+options 	INET			# InterNETworking
+options 	INET6			# IPv6 communications protocols
+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
+options 	NFSCL			# New Network Filesystem Client
+options 	NFSD			# New Network Filesystem Server
+options 	NFSLOCKD		# Network Lock Manager
+options 	NFS_ROOT		# NFS usable as /, requires NFSCL
+options 	GEOM_PART_BSD		# BSD partition scheme
+options 	GEOM_PART_MBR		# MBR partition scheme
+options 	TMPFS			# Efficient memory filesystem
+#options 	MSDOSFS			# MSDOS Filesystem
+options 	CD9660			# ISO 9660 Filesystem
+#options 	PROCFS			# Process filesystem (requires PSEUDOFS)
+options 	PSEUDOFS		# Pseudo-filesystem framework
+options 	SCSI_DELAY=5000		# Delay (in ms) before probing SCSI
+options 	KTRACE			# ktrace(1) support
+options 	SYSVSHM			# SYSV-style shared memory
+options 	SYSVMSG			# SYSV-style message queues
+options 	SYSVSEM			# SYSV-style semaphores
+options 	_KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time extensions
+options 	KBD_INSTALL_CDEV	# install a CDEV entry in /dev
+options 	BOOTP
+options 	BOOTP_NFSROOT
+options 	BOOTP_NFSV3
+options 	BOOTP_WIRED_TO=em0
+options 	BOOTP_COMPAT
+#options 	PREEMPTION
+device		loop
+device		ether
+#device		saarm
+device		miibus
+device		rl
+device		em
+device		uart
+device		pci
+
+device		ata
+options 	ATA_STATIC_ID		# Static device numbering
+
+device		scbus			# SCSI bus (required for ATA/SCSI)
+device		cd			# CD
+device		da			# Direct Access (disks)
+device		pass			# Passthrough device (direct ATA/SCSI access)
+
+# SCSI Controllers
+
+device		iopwdog			# I80321 Watchdog
+device		dma			# I80321 DMA Controller
+device		aau			# I80321 Application Accelerator Unit
+device		"iq31244_7seg"		# IQ31244 7 seg
+#options 	AHC_REG_PRETTY_PRINT	# Print register bitfields in debug
+					# output.  Adds ~128k to driver.
+#options 	AHD_REG_PRETTY_PRINT	# Print register bitfields in debug
+					# output.  Adds ~215k to driver.
+
+# Debugging for use in -current
+options 	KDB
+options 	DDB			# Enable the kernel debugger
+#options 	DEADLKRES		# Enable the deadlock resolver
+#options 	INVARIANTS		# Enable calls of extra sanity checking
+#options 	INVARIANT_SUPPORT	# Extra sanity checks of internal structures, required by INVARIANTS
+#options 	WITNESS			# Enable checks to detect deadlocks and cycles
+#options 	WITNESS_SKIPSPIN	# Don't run witness on spinlocks for speed
+#options 	DIAGNOSTIC
+
+options 	XSCALE_CACHE_READ_WRITE_ALLOCATE
+device		md
+device		random			# Entropy device
+
+# Floppy drives
+


Property changes on: trunk/sys/arm/conf/IQ31244
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/KB920X
===================================================================
--- trunk/sys/arm/conf/KB920X	                        (rev 0)
+++ trunk/sys/arm/conf/KB920X	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,154 @@
+# KB920X -- Custom kernel configuration for the KB9202 (no letter, A and B)
+# AT91RM9200 evaluation boards from kwikbyte.com.
+#
+# For more information on this file, please read 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: stable/10/sys/arm/conf/KB920X 278676 2015-02-13 15:27:46Z ian $
+
+#NO_UNIVERSE
+
+ident		KB920X
+
+include		"../at91/std.kb920x"
+# The AT91 platform doesn't use /boot/loader, so we have to statically wire
+# hints.
+hints		"KB920X.hints"
+makeoptions	MODULES_OVERRIDE=""
+
+makeoptions	DEBUG=-g		# Build kernel with gdb(1) debug symbols
+options 	DDB
+options 	KDB
+
+options 	SCHED_4BSD		# 4BSD scheduler
+options 	INET			# InterNETworking
+#options 	INET6			# IPv6 communications protocols
+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
+#options 	MD_ROOT			# MD is a potential root device
+#options 	MD_ROOT_SIZE=4096	# 4MB ram disk
+options 	ROOTDEVNAME=\"ufs:/dev/mmcsd0s1a\"
+options 	NFSCL			# New Network Filesystem Client
+#options 	NFSD			# New Network Filesystem Server
+#options 	NFSLOCKD		# Network Lock Manager
+#options 	NFS_ROOT		# NFS usable as /, requires NFSCL
+#options 	BOOTP_NFSROOT
+#options 	BOOTP
+
+options 	GEOM_PART_BSD		# BSD partition scheme
+options 	GEOM_PART_MBR		# MBR partition scheme
+options 	TMPFS			# Efficient memory filesystem
+#options 	MSDOSFS			# MSDOS Filesystem
+#options 	CD9660			# ISO 9660 Filesystem
+#options 	PROCFS			# Process filesystem (requires PSEUDOFS)
+options 	PSEUDOFS		# Pseudo-filesystem framework
+#options 	SCSI_DELAY=5000		# Delay (in ms) before probing SCSI
+#options 	KTRACE			# ktrace(1) support
+options 	SYSVSHM			# SYSV-style shared memory
+options 	SYSVMSG			# SYSV-style message queues
+options 	SYSVSEM			# SYSV-style semaphores
+options 	_KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time extensions
+#options 	NO_SYSCTL_DESCR
+# Disable the inlining of mutex, rwlock and sx locks.  These eat up a lot
+# of space.
+options 	MUTEX_NOINLINE
+options 	RWLOCK_NOINLINE
+options 	SX_NOINLINE
+options 	NO_FFS_SNAPSHOT
+options 	NO_SWAPPING
+device		random
+device		loop
+device		ether
+device		uart
+device		ate
+device		mii
+device		lxtphy
+
+# Debugging for use in -current
+#options 	DEADLKRES		# Enable the deadlock resolver
+#options 	INVARIANTS		# Enable calls of extra sanity checking
+#options 	INVARIANT_SUPPORT	# Extra sanity checks of internal structures, required by INVARIANTS
+#options 	WITNESS			# Enable checks to detect deadlocks and cycles
+#options 	WITNESS_SKIPSPIN	# Don't run witness on spinlocks for speed
+
+device		md
+device		at91_twi		# TWI: Two Wire Interface
+device		at91_spi		# SPI:
+device		spibus
+# MMC/SD
+device		at91_mci
+device		mmc
+device		mmcsd
+# iic
+device		iic
+device		iicbus
+device		icee
+
+device		bpf
+# USB support
+options 	USB_DEBUG		# enable debug msgs
+device		ohci			# OHCI localbus->USB interface
+device		usb			# USB Bus (required)
+#device		udbp			# USB Double Bulk Pipe devices
+device		uhid			# "Human Interface Devices"
+device		ulpt			# Printer
+device		umass			# Disks/Mass storage - Requires scbus and da
+device		urio			# Diamond Rio 500 MP3 player
+# USB Serial devices
+device		uark			# Technologies ARK3116 based serial adapters
+device		ubsa			# Belkin F5U103 and compatible serial adapters
+device		uftdi			# For FTDI usb serial adapters
+device		uipaq			# Some WinCE based devices
+device		uplcom			# Prolific PL-2303 serial adapters
+device		uslcom			# SI Labs CP2101/CP2102 serial adapters
+device		uvisor			# Visor and Palm devices
+device		uvscom			# USB serial support for DDI pocket's PHS
+# USB Ethernet, requires miibus
+device		miibus
+device		aue			# ADMtek USB Ethernet
+device		axe			# ASIX Electronics USB Ethernet
+device		cdce			# Generic USB over Ethernet
+device		cue			# CATC USB Ethernet
+device		kue			# Kawasaki LSI USB Ethernet
+device		rue			# RealTek RTL8150 USB Ethernet
+device		udav			# Davicom DM9601E USB
+# USB Wireless
+device		rum			# Ralink Technology RT2501USB wireless NICs
+device		uath			# Atheros AR5523 wireless NICs
+device		ural			# Ralink Technology RT2500USB wireless NICs
+device		zyd			# ZyDAS zd1211/zd1211b wireless NICs
+# SCSI peripherals
+device		scbus			# SCSI bus (required for ATA/SCSI)
+device		da			# Direct Access (disks)
+device		cd			# CD
+device		pass			# Passthrough device (direct ATA/SCSI access)
+# Wireless NIC cards
+device		wlan			# 802.11 support
+device		wlan_wep		# 802.11 WEP support
+device		wlan_ccmp		# 802.11 CCMP support
+device		wlan_tkip		# 802.11 TKIP support
+device		wlan_amrr		# AMRR transmit rate control algorithm
+
+# USB device (gadget) support
+device		at91_dci		# Atmel's usb device
+device		usfs			# emulate a flash
+device		cdce			# emulate an ethernet
+device		usb_template		# Control of the gadget
+
+options 	IEEE80211_SUPPORT_MESH
+
+options 	AH_SUPPORT_AR5416


Property changes on: trunk/sys/arm/conf/KB920X
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/KB920X.hints
===================================================================
--- trunk/sys/arm/conf/KB920X.hints	                        (rev 0)
+++ trunk/sys/arm/conf/KB920X.hints	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,16 @@
+# $FreeBSD: stable/10/sys/arm/conf/KB920X.hints 167858 2007-03-23 23:47:59Z imp $
+#
+# Kwikbyte KB9202A description (will also work for 9202 and might work with
+# a boot loader tweak on the KB9202B).  For the moment, all we list is the
+# eeprom.  The temperature sensor isn't listed.
+#
+
+# boot eeprom at 'default' address of 0xa0
+hint.icee.0.at="iicbus0"
+hint.icee.0.addr=0xa0
+hint.icee.0.type=16
+hint.icee.0.size=16384
+hint.icee.0.rd_sz=256
+hint.icee.0.wr_sz=16
+
+# XXX add temperature sensor


Property changes on: trunk/sys/arm/conf/KB920X.hints
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/LN2410SBC
===================================================================
--- trunk/sys/arm/conf/LN2410SBC	                        (rev 0)
+++ trunk/sys/arm/conf/LN2410SBC	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,89 @@
+# LN2410SBC -- Custom kernel configuration for the LN2410SBC
+#
+# For more information on this file, please read 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: stable/10/sys/arm/conf/LN2410SBC 278726 2015-02-13 22:08:19Z ian $
+
+ident		LN2410SBC
+
+include 	"../samsung/s3c2xx0/std.ln2410sbc"
+#To statically compile in device wiring instead of /boot/device.hints
+#hints		"GENERIC.hints"		# Default places to look for devices.
+makeoptions	MODULES_OVERRIDE=""
+
+device		board_ln2410sbc
+
+makeoptions	DEBUG=-g		# Build kernel with gdb(1) debug symbols
+options 	HZ=100
+options 	DDB
+options 	KDB
+
+options 	SCHED_4BSD		# 4BSD scheduler
+options 	INET			# InterNETworking
+#options 	INET6			# IPv6 communications protocols
+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
+#options 	MD_ROOT			# MD is a potential root device
+#options 	MD_ROOT_SIZE=4096	# 4MB ram disk
+options 	ROOTDEVNAME=\"ufs:da0s1\"
+
+#options 	BOOTP
+#options 	BOOTP_NFSROOT		# NFS mount root filesystem using BOOTP info
+#options 	NFSCL			# New Network Filesystem Client
+#options 	NFS_ROOT		# NFS usable as root device
+
+options 	GEOM_PART_BSD		# BSD partition scheme
+options 	GEOM_PART_MBR		# MBR partition scheme
+options 	TMPFS			# Efficient memory filesystem
+options 	PSEUDOFS		# Pseudo-filesystem framework
+#options 	SCSI_DELAY=5000		# Delay (in ms) before probing SCSI
+options 	KTRACE			# ktrace(1) support
+options 	SYSVSHM			# SYSV-style shared memory
+options 	SYSVMSG			# SYSV-style message queues
+options 	SYSVSEM			# SYSV-style semaphores
+options 	_KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time extensions
+
+options 	MUTEX_NOINLINE
+options 	RWLOCK_NOINLINE
+options 	SX_NOINLINE
+
+options 	NO_FFS_SNAPSHOT
+options 	NO_SWAPPING
+device		random
+
+device		loop
+device		ether
+device		bpf
+
+device		uart
+
+# Debugging for use in -current
+#options 	INVARIANTS		# Enable calls of extra sanity checking
+#options 	INVARIANT_SUPPORT	# Extra sanity checks of internal structures, required by INVARIANTS
+#options 	WITNESS			# Enable checks to detect deadlocks and cycles
+#options 	WITNESS_SKIPSPIN	# Don't run witness on spinlocks for speed
+
+device		md
+
+options 	USB_DEBUG		# enable debug msgs
+device		usb
+device		ohci
+device		umass
+device		scbus			# SCSI bus (required for da)
+device		da			# Direct Access (disks)
+


Property changes on: trunk/sys/arm/conf/LN2410SBC
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/Makefile
===================================================================
--- trunk/sys/arm/conf/Makefile	                        (rev 0)
+++ trunk/sys/arm/conf/Makefile	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,6 @@
+# $MidnightBSD$
+# $FreeBSD: stable/10/sys/arm/conf/Makefile 243581 2012-11-27 01:17:50Z marcel $
+
+TARGET=arm
+
+.include "${.CURDIR}/../../conf/makeLINT.mk"


Property changes on: trunk/sys/arm/conf/Makefile
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/conf/NOTES
===================================================================
--- trunk/sys/arm/conf/NOTES	                        (rev 0)
+++ trunk/sys/arm/conf/NOTES	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,88 @@
+# $FreeBSD: stable/10/sys/arm/conf/NOTES 309447 2016-12-02 22:53:33Z jhb $
+
+machine	arm
+
+cpu	CPU_ARM9
+cpu	CPU_ARM9E
+cpu	CPU_FA526
+cpu 	CPU_XSCALE_80219
+cpu 	CPU_XSCALE_80321
+cpu 	CPU_XSCALE_81342
+cpu 	CPU_XSCALE_IXP425
+cpu 	CPU_XSCALE_IXP435
+cpu	CPU_XSCALE_PXA2X0
+
+files	"../at91/files.at91"
+files	"../cavium/cns11xx/files.econa"
+files	"../mv/files.mv"
+files	"../mv/discovery/files.db78xxx"
+files	"../mv/kirkwood/files.kirkwood"
+files	"../mv/orion/files.db88f5xxx"
+files	"../mv/orion/files.ts7800"
+files	"../samsung/s3c2xx0/files.s3c2xx0"
+files	"../xscale/i80321/files.ep80219"
+files	"../xscale/i80321/files.i80219"
+files	"../xscale/i80321/files.i80321"
+files	"../xscale/i80321/files.iq31244"
+files	"../xscale/i8134x/files.crb"
+files	"../xscale/i8134x/files.i81342"
+files	"../xscale/ixp425/files.avila"
+files	"../xscale/ixp425/files.ixp425"
+files	"../xscale/pxa/files.pxa"
+
+options 	PHYSADDR=0x00000000
+options 	KERNPHYSADDR=0x00000000
+options 	KERNVIRTADDR=0xc0000000
+
+makeoptions	LDFLAGS="-zmuldefs"
+makeoptions	KERNPHYSADDR=0x00000000
+makeoptions	KERNVIRTADDR=0xc0000000
+
+options 	FDT
+
+options 	SOC_MV_DISCOVERY
+options 	SOC_MV_KIRKWOOD
+options 	SOC_MV_ORION
+
+device		pci
+
+device		at91_board_bwct
+device		at91_board_ethernut5
+device		at91_board_hl200
+device		at91_board_hl201
+device		at91_board_kb920x
+device		at91_board_qila9g20
+device		at91_board_sam9260ek
+device		at91_board_sam9g20ek
+device		at91_board_sam9x25ek
+device		at91_board_tsc4370
+device		at91rm9200
+device		nand
+device		board_ln2410sbc
+
+nooptions	SMP
+nooptions	MAXCPU
+
+nooptions	COMPAT_FREEBSD4
+
+nodevice	fdc
+nodevice	sym
+nodevice	ukbd
+
+nodevice	sc
+nodevice	blank_saver
+nodevice	daemon_saver
+nodevice	dragon_saver
+nodevice	fade_saver
+nodevice	fire_saver
+nodevice	green_saver
+nodevice	logo_saver
+nodevice	rain_saver
+nodevice	snake_saver
+nodevice	star_saver
+nodevice	warp_saver
+
+nodevice	cxgbe
+nodevice	cxgbev
+nodevice	snd_cmi
+nodevice	tnt4882


Property changes on: trunk/sys/arm/conf/NOTES
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/NSLU
===================================================================
--- trunk/sys/arm/conf/NSLU	                        (rev 0)
+++ trunk/sys/arm/conf/NSLU	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,119 @@
+# NSLU - kernel configuration file for FreeBSD/arm on Linksys NSLU2
+#
+# For more information on this file, please read 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: stable/10/sys/arm/conf/NSLU 278676 2015-02-13 15:27:46Z ian $
+
+#NO_UNIVERSE
+
+ident		NSLU
+
+# XXX What is defined in std.avila does not exactly match the following:
+#options 	PHYSADDR=0x10000000
+#options 	KERNPHYSADDR=0x10200000	
+#options 	KERNVIRTADDR=0xc0200000	# Used in ldscript.arm
+#options 	FLASHADDR=0x50000000
+#options 	LOADERRAMADDR=0x00000000
+
+include		"../xscale/ixp425/std.ixp425"
+# NB: memory mapping is defined in std.avila (see also comment above)
+include		"../xscale/ixp425/std.avila"
+options 	XSCALE_CACHE_READ_WRITE_ALLOCATE
+#To statically compile in device wiring instead of /boot/device.hints
+hints		"NSLU.hints"		# Default places to look for devices.
+makeoptions	MODULES_OVERRIDE=""
+
+makeoptions	DEBUG=-g		# Build kernel with gdb(1) debug symbols
+makeoptions	CONF_CFLAGS=-mcpu=xscale
+options 	HZ=100
+options 	DEVICE_POLLING
+
+# Debugging for use in -current
+options 	KDB
+#options 	GDB
+options 	DDB			# Enable the kernel debugger
+#options 	DEADLKRES		# Enable the deadlock resolver
+#options 	INVARIANTS		# Enable calls of extra sanity checking
+#options 	INVARIANT_SUPPORT	# Extra sanity checks of internal structures, required by INVARIANTS
+#options 	WITNESS			# Enable checks to detect deadlocks and cycles
+#options 	WITNESS_SKIPSPIN	# Don't run witness on spinlocks for speed
+#options 	DIAGNOSTIC
+
+options 	SCHED_ULE		# ULE scheduler
+options 	INET			# InterNETworking
+options 	INET6			# IPv6 communications protocols
+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
+options 	NFSCL			# New Network Filesystem Client
+options 	NFSD			# New Network Filesystem Server
+options 	NFSLOCKD		# Network Lock Manager
+options 	NFS_ROOT		# NFS usable as /, requires NFSCL
+options 	GEOM_PART_BSD		# BSD partition scheme
+options 	GEOM_PART_MBR		# MBR partition scheme
+options 	TMPFS			# Efficient memory filesystem
+#options 	MSDOSFS			# MSDOS Filesystem
+options 	CD9660			# ISO 9660 Filesystem
+#options 	PROCFS			# Process filesystem (requires PSEUDOFS)
+options 	PSEUDOFS		# Pseudo-filesystem framework
+options 	SCSI_DELAY=5000		# Delay (in ms) before probing SCSI
+options 	KTRACE			# ktrace(1) support
+options 	SYSVSHM			# SYSV-style shared memory
+options 	SYSVMSG			# SYSV-style message queues
+options 	SYSVSEM			# SYSV-style semaphores
+options 	_KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions
+options 	MUTEX_NOINLINE		# Mutex inlines are space hogs
+options 	RWLOCK_NOINLINE		# rwlock inlines are space hogs
+options 	SX_NOINLINE		# sx inliens are space hogs
+options 	BOOTP
+options 	BOOTP_NFSROOT
+options 	BOOTP_NFSV3
+options 	BOOTP_WIRED_TO=npe0
+options 	BOOTP_COMPAT
+
+device		pci
+device		uart
+
+# I2C Bus
+device		iicbus
+device		iicbb
+device		iic
+
+device		ixpiic			# I2C bus glue
+device		ixpwdog			# watchdog timer
+
+device		npe			# Network Processing Engine
+device		npe_fw
+device		firmware
+device		qmgr			# Q Manager (required by npe)
+device		mii			# Minimal mii routines
+device		rlphy			# NSLU2 uses Realtek PHY attached to npe
+device		ether
+device		bpf
+
+device		loop
+
+device		md
+device		random			# Entropy device
+
+device		usb
+options 	USB_DEBUG
+device		ohci
+device		ehci
+device		umass
+device		scbus			# SCSI bus (required for ATA/SCSI)
+device		da			# Direct Access (disks)


Property changes on: trunk/sys/arm/conf/NSLU
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/NSLU.hints
===================================================================
--- trunk/sys/arm/conf/NSLU.hints	                        (rev 0)
+++ trunk/sys/arm/conf/NSLU.hints	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,38 @@
+# $FreeBSD: stable/10/sys/arm/conf/NSLU.hints 191858 2009-05-06 20:24:17Z cognet $
+
+#
+# Device wiring for the Linksys NSLU2
+#
+
+# DBGU is unit 0
+hint.uart.0.at="ixp0"
+hint.uart.0.addr=0xc8000000
+hint.uart.0.irq=15
+hint.uart.0.flags=0x10
+# USART0 is unit 1
+hint.uart.1.at="ixp0"
+hint.uart.1.addr=0xc8001000
+hint.uart.1.irq=13
+
+# NPE Hardware Queue Manager
+hint.ixpqmgr.0.at="ixp0"
+
+# NPE wired NICs, requires ixpqmgr
+hint.npe.0.at="ixp0"
+hint.npe.0.mac="B"
+hint.npe.0.mii="B"
+hint.npe.0.phy=1
+# The second MAC isn't used on the NSLU, but it needs to be configured or
+# we timeout on dhcp packets
+hint.npe.1.at="ixp0"
+#hint.npe.1.mac="B"
+#hint.npe.1.mii="A"
+#hint.npe.1.phy=0
+
+#not yet
+# RTC
+#hint.xrtc.0.at="iicbus0"
+#hint.xrtc.0.addr=0xde
+# Slug LED
+# Slug button
+# Slug Buzzer


Property changes on: trunk/sys/arm/conf/NSLU.hints
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/PANDABOARD
===================================================================
--- trunk/sys/arm/conf/PANDABOARD	                        (rev 0)
+++ trunk/sys/arm/conf/PANDABOARD	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,154 @@
+#
+# PANDABOARD -- Custom configuration for the PandaBoard ARM development
+# platform, check out www.pandaboard.org
+#
+# 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: stable/10/sys/arm/conf/PANDABOARD 287082 2015-08-23 20:50:22Z ian $
+
+ident		PANDABOARD
+
+# This probably wants to move somewhere else.  Maybe we can create a basic
+# OMAP4340 config, then make a PANDABOARD config that includes the basic one,
+# adds the start addresses and custom devices plus pulls in this hints file.
+
+hints		"PANDABOARD.hints"
+
+include 	"../ti/omap4/pandaboard/std.pandaboard"
+
+options 	HZ=100
+options 	SCHED_ULE		# ULE scheduler
+options 	PREEMPTION		# Enable kernel thread preemption
+options 	INET			# InterNETworking
+options 	INET6			# IPv6 communications protocols
+options 	SCTP			# Stream Control Transmission Protocol
+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
+options 	UFS_GJOURNAL		# Enable gjournal-based UFS journaling
+options 	QUOTA			# Enable disk quotas for UFS
+options 	NFSCL			# New Network Filesystem Client
+options 	NFSLOCKD		# Network Lock Manager
+options 	NFS_ROOT		# NFS usable as /, requires NFSCL
+options 	MSDOSFS			# MSDOS Filesystem
+options 	CD9660			# ISO 9660 Filesystem
+options 	PROCFS			# Process filesystem (requires PSEUDOFS)
+options 	PSEUDOFS		# Pseudo-filesystem framework
+options 	TMPFS			# Efficient memory filesystem
+options 	GEOM_PART_GPT		# GUID Partition Tables
+options 	GEOM_PART_BSD		# BSD partition scheme
+options 	GEOM_PART_MBR		# MBR partition scheme
+options 	GEOM_LABEL		# Provides labelization 
+options 	COMPAT_43		# Compatible with BSD 4.3 [KEEP THIS!]
+options 	SCSI_DELAY=5000		# Delay (in ms) before probing SCSI
+options 	KTRACE			# ktrace(1) support
+options 	SYSVSHM			# SYSV-style shared memory
+options 	SYSVMSG			# SYSV-style message queues
+options 	SYSVSEM			# SYSV-style semaphores
+options 	_KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
+options 	KBD_INSTALL_CDEV	# install a CDEV entry in /dev
+options 	FREEBSD_BOOT_LOADER	# Process metadata passed from loader(8)
+options 	VFP			# Enable floating point hardware support
+options 	SMP			# Enable multiple cores
+
+# Debugging for use in -current
+makeoptions	DEBUG=-g		# Build kernel with gdb(1) debug symbols
+options 	ALT_BREAK_TO_DEBUGGER
+#options 	VERBOSE_SYSINIT		# Enable verbose sysinit messages
+options 	KDB			# Enable kernel debugger support
+# For minimum debugger support (stable branch) use:
+#options 	KDB_TRACE		# Print a stack trace for a panic
+# For full debugger support use this instead:
+options 	DDB			# Enable the kernel debugger
+#options 	INVARIANTS		# Enable calls of extra sanity checking
+#options 	INVARIANT_SUPPORT	# Extra sanity checks of internal structures, required by INVARIANTS
+#options 	WITNESS			# Enable checks to detect deadlocks and cycles
+#options 	WITNESS_SKIPSPIN	# Don't run witness on spinlocks for speed
+#options 	DIAGNOSTIC
+
+# NFS root from boopt/dhcp
+#options 	BOOTP
+#options 	BOOTP_NFSROOT
+#options 	BOOTP_COMPAT
+#options 	BOOTP_NFSV3
+#options 	BOOTP_WIRED_TO=ue0
+
+# MMC/SD/SDIO Card slot support
+device		mmc			# mmc/sd bus
+device		mmcsd			# mmc/sd flash cards
+device		sdhci			# mmc/sd host controller
+
+# I2C support
+device		iicbus
+device		iic
+device		ti_i2c
+
+# Console and misc
+device		uart
+device		uart_ns8250
+device		pty
+device		snp
+device		md
+device		random			# Entropy device
+device		pl310			# PL310 L2 cache controller
+
+# GPIO
+device		gpio
+
+# The following enables MFS as root, this seems similar to an initramfs or initrd
+# as used in Linux.
+#options 	MD_ROOT
+#options 	MD_ROOT_SIZE=7560
+
+
+
+# USB support
+device		usb
+options 	USB_HOST_ALIGN=64	# Align usb buffers to cache line size.
+options 	USB_DEBUG
+#options 	USB_REQ_DEBUG
+#options 	USB_VERBOSE
+device		ohci
+device		ehci
+device		umass
+device		scbus			# SCSI bus (required for ATA/SCSI)
+device		da			# Direct Access (disks)
+
+# Ethernet
+device		loop
+device		ether
+device		mii
+device		smc
+device		smcphy
+device		bpf
+
+# USB Ethernet support, requires miibus
+device		miibus
+#device		axe			# ASIX Electronics USB Ethernet
+device		smsc			# SMSC LAN95xx USB Ethernet
+
+
+# OMAP-specific devices
+device		ti_sdma
+device		twl
+device		twl_vreg
+device		twl_clks
+
+# Flattened Device Tree
+options 	FDT			# Configure using FDT/DTB data
+options 	FDT_DTB_STATIC
+makeoptions	FDT_DTS_FILE=pandaboard.dts


Property changes on: trunk/sys/arm/conf/PANDABOARD
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/PANDABOARD.hints
===================================================================
--- trunk/sys/arm/conf/PANDABOARD.hints	                        (rev 0)
+++ trunk/sys/arm/conf/PANDABOARD.hints	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,61 @@
+# $FreeBSD: stable/10/sys/arm/conf/PANDABOARD.hints 239281 2012-08-15 06:31:32Z gonzo $
+
+# USB ECHI 
+
+#
+# TI OMAP Power Management and System Companion Device sitting on the I2C bus
+# hint.tps65950.0.at="iicbus0"
+# hint.tps65950.0.addr=0xd0
+
+
+#
+# Defines the GPIO pin used to detect the Write Protect stat of the MMC/SD card.
+#hint.omap_mmc.0.wp_gpio="23"
+
+
+#
+# If 'phy_reset" is set, then the accompaning PHY is reset using one of the
+# GPIO pins. If the reset GPIO pin is not -1 then the pin will be toggled when
+# the USB driver is loaded.
+hint.ehci.0.phy_reset="0"
+
+#
+# Sets the PHY mode for the individual ports, the following values are allowed
+#   - EHCI_HCD_OMAP3_MODE_UNKNOWN   0
+#   - EHCI_HCD_OMAP3_MODE_PHY       1
+#   - EHCI_HCD_OMAP3_MODE_TLL       2
+hint.ehci.0.phy_mode_0="1"
+hint.ehci.0.phy_mode_1="0"
+hint.ehci.0.phy_mode_2="0"
+
+#
+# If specified the value indicates a pin that is toggled as a heart-beat. The
+# heart beat pusle is triggered every 500ms using the system tick timer.
+hint.omap_clk.0.heartbeat_gpio="150"
+
+
+#
+# Padconf (pinmux) settings - typically this would be set by the boot-loader
+# but can be overridden here.  These hints are applied to the H/W when the
+# SCM module is initialised.
+#
+# The format is:
+#     hint.omap_scm.0.padconf.<padname>=<muxmode:options>
+#
+# Where the options can be one of the following:
+#     output, input, input_pullup, input_pulldown
+#
+
+# Setup the pin settings for the HS USB Host (PHY mode)
+hint.omap4.0.padconf.ag19="usbb1_ulpiphy_stp:output"
+hint.omap4.0.padconf.ae18="usbb1_ulpiphy_clk:input_pulldown"
+hint.omap4.0.padconf.af19="usbb1_ulpiphy_dir:input_pulldown"
+hint.omap4.0.padconf.ae19="usbb1_ulpiphy_nxt:input_pulldown"
+hint.omap4.0.padconf.af18="usbb1_ulpiphy_dat0:input_pulldown"
+hint.omap4.0.padconf.ag18="usbb1_ulpiphy_dat1:input_pulldown"
+hint.omap4.0.padconf.ae17="usbb1_ulpiphy_dat2:input_pulldown"
+hint.omap4.0.padconf.af17="usbb1_ulpiphy_dat3:input_pulldown"
+hint.omap4.0.padconf.ah17="usbb1_ulpiphy_dat4:input_pulldown"
+hint.omap4.0.padconf.ae16="usbb1_ulpiphy_dat5:input_pulldown"
+hint.omap4.0.padconf.af16="usbb1_ulpiphy_dat6:input_pulldown"
+hint.omap4.0.padconf.ag16="usbb1_ulpiphy_dat7:input_pulldown"


Property changes on: trunk/sys/arm/conf/PANDABOARD.hints
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/QILA9G20
===================================================================
--- trunk/sys/arm/conf/QILA9G20	                        (rev 0)
+++ trunk/sys/arm/conf/QILA9G20	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,155 @@
+# Kernel configuration for Calao Syatems QIL-A9G20 development card
+# http://www.calao-systems.com
+#
+# For more information on this file, please read 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: stable/10/sys/arm/conf/QILA9G20 278676 2015-02-13 15:27:46Z ian $
+
+#NO_UNIVERSE
+
+ident		QILA9G20
+
+include "../at91/std.qila9g20"
+
+#To statically compile in device wiring instead of /boot/device.hints
+hints		"QILA9G20.hints"
+makeoptions	MODULES_OVERRIDE=""
+
+makeoptions	DEBUG=-g		# Build kernel with gdb(1) debug symbols
+options 	DDB
+options 	KDB
+
+options 	SCHED_4BSD		# 4BSD scheduler
+options 	INET			# InterNETworking
+#options 	INET6			# IPv6 communications protocols
+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
+#options 	MD_ROOT			# MD is a potential root device
+#options 	MD_ROOT_SIZE=4096	# 4MB ram disk
+options 	NFSCL			# New Network Filesystem Client
+#options 	NFSD			# New Network Filesystem Server
+#options 	NFSLOCKD		# Network Lock Manager
+#options 	NFS_ROOT		# NFS usable as /, requires NFSCL
+#options 	BOOTP_NFSROOT
+#options 	BOOTP
+#options 	BOOTP_NFSV3
+#options 	BOOTP_WIRED_TO=ate0
+#options 	BOOTP_COMPAT
+
+options 	ROOTDEVNAME=\"ufs:/dev/mmcsd0s1a\"
+
+options 	ALT_BREAK_TO_DEBUGGER
+
+options 	GEOM_PART_BSD		# BSD partition scheme
+options 	GEOM_PART_MBR		# MBR partition scheme
+options 	TMPFS			# Efficient memory filesystem
+#options 	MSDOSFS			# MSDOS Filesystem
+#options 	CD9660			# ISO 9660 Filesystem
+#options 	PROCFS			# Process filesystem (requires PSEUDOFS)
+#options 	PSEUDOFS		# Pseudo-filesystem framework
+#options 	SCSI_DELAY=5000		# Delay (in ms) before probing SCSI
+#options 	KTRACE			# ktrace(1) support
+options 	SYSVSHM			# SYSV-style shared memory
+options 	SYSVMSG			# SYSV-style message queues
+options 	SYSVSEM			# SYSV-style semaphores
+options 	_KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions
+options 	MUTEX_NOINLINE
+options 	RWLOCK_NOINLINE
+options 	NO_FFS_SNAPSHOT
+options 	NO_SWAPPING
+
+# Debugging for use in -current
+#options 	INVARIANTS		# Enable calls of extra sanity checking
+#options 	INVARIANT_SUPPORT	# Extra sanity checks of internal structures, required by INVARIANTS
+#options 	WITNESS			# Enable checks to detect deadlocks and cycles
+#options 	WITNESS_SKIPSPIN	# Don't run witness on spinlocks for speed
+#options 	DIAGNOSTIC
+
+device		random
+device		loop
+device		bpf
+device		ether
+device		md
+
+device		uart			# Serial Ports
+
+# Ethernet
+device		ate			# Ethernet Driver	
+device		mii
+option 		AT91_ATE_USE_RMII
+
+device		at91_twi		# TWI: Two Wire Interface (EEPROM)
+device		at91_wdt		# WDT: Watchdog timer
+
+# NOTE: SPI DataFlash and mci/mmc/mmcsd have hardware
+# 	confilict on this card. Use one or the other.
+#       see board_sam9g20ek.c
+
+# SPI: Data Flash
+#device		at91_spi		# SPI:
+#device		spibus
+#device		at45d			# at45db642 and maybe others
+
+# MMC/SD
+device		at91_mci
+device		mmc
+device		mmcsd
+option		AT91_MCI_HAS_4WIRE
+
+# iic
+device		iic
+device		iicbus
+device		icee
+
+# SCSI peripherals
+device		scbus			# SCSI bus (required for ATA/SCSI)
+device		da			# Direct Access (disks)
+device		cd			# CD
+device		pass			# Passthrough device (direct ATA/SCSI access)
+
+# USB support
+device		ohci			# OHCI localbus->USB interface
+device		usb			# USB Bus (required)
+device		umass			# Disks/Mass storage - Requires scbus and da
+device		uhid			# "Human Interface Devices"
+#device		ulpt			# Printer
+#device		udbp			# USB Double Bulk Pipe devices
+
+# USB Ethernet, requires miibus
+device		miibus
+#device		aue			# ADMtek USB Ethernet
+#device		axe			# ASIX Electronics USB Ethernet
+#device		cdce			# Generic USB over Ethernet
+#device		cue			# CATC USB Ethernet
+#device		kue			# Kawasaki LSI USB Ethernet
+#device		rue			# RealTek RTL8150 USB Ethernet
+device		udav			# Davicom DM9601E USB
+
+# USB Wireless
+#device		rum			# Ralink Technology RT2501USB wireless NICs
+#device		uath			# Atheros AR5523 wireless NICs
+#device		ural			# Ralink Technology RT2500USB wireless NICs
+#device		zyd			# ZyDAS zd1211/zd1211b wireless NICs
+
+# Wireless NIC cards
+#device		wlan			# 802.11 support
+#device		wlan_wep		# 802.11 WEP support
+#device		wlan_ccmp		# 802.11 CCMP support
+#device		wlan_tkip		# 802.11 TKIP support
+#device		wlan_amrr		# AMRR transmit rate control algorithm
+


Property changes on: trunk/sys/arm/conf/QILA9G20
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/QILA9G20.hints
===================================================================
--- trunk/sys/arm/conf/QILA9G20.hints	                        (rev 0)
+++ trunk/sys/arm/conf/QILA9G20.hints	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,9 @@
+# $FreeBSD: stable/10/sys/arm/conf/QILA9G20.hints 236988 2012-06-13 04:40:29Z imp $
+# Kernel configuration hits for Calao Syatems QIL-A9G20 development card
+# http://www.calao-systems.com
+
+# STMicroelctrtronics M41T94 Real-Time Clock
+# on SPI0 NPCS0
+
+# STMicroelctrtronics M95640 8k x 8 EEPROM
+# on SPI0 NPCS1


Property changes on: trunk/sys/arm/conf/QILA9G20.hints
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/QUARTZ
===================================================================
--- trunk/sys/arm/conf/QUARTZ	                        (rev 0)
+++ trunk/sys/arm/conf/QUARTZ	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,28 @@
+# Kernel configuration for Device Solutions Quartz Module.
+#
+# 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: stable/10/sys/arm/conf/QUARTZ 266383 2014-05-18 00:21:14Z ian $
+
+#NO_UNIVERSE
+
+include		"VYBRID"
+ident		QUARTZ
+
+#FDT
+options 	FDT
+options 	FDT_DTB_STATIC
+makeoptions	FDT_DTS_FILE=vybrid-quartz.dts


Property changes on: trunk/sys/arm/conf/QUARTZ
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/RADXA
===================================================================
--- trunk/sys/arm/conf/RADXA	                        (rev 0)
+++ trunk/sys/arm/conf/RADXA	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,124 @@
+# RADXA -- Custom configuration for the RADXA ARM development
+# platform, check out http://www.radxa.com
+#
+# For more information on this file, please read 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: stable/10/sys/arm/conf/RADXA 271428 2014-09-11 15:36:36Z ian $
+
+ident		RADXA
+
+include		"../rockchip/std.rk30xx"
+
+makeoptions	MODULES_OVERRIDE=""
+makeoptions	WITHOUT_MODULES="ahc"
+
+options 	HZ=100
+options 	SCHED_4BSD		# 4BSD scheduler
+options 	INET			# InterNETworking
+options 	INET6			# IPv6 communications protocols
+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
+options 	GEOM_PART_BSD		# BSD partition scheme
+options 	GEOM_PART_MBR		# MBR partition scheme
+options 	TMPFS			# Efficient memory filesystem
+options 	MSDOSFS			# MSDOS Filesystem
+options 	CD9660			# ISO 9660 Filesystem
+options 	PROCFS			# Process filesystem (requires PSEUDOFS)
+options 	PSEUDOFS		# Pseudo-filesystem framework
+options 	COMPAT_43		# Compatible with BSD 4.3 [KEEP THIS!]
+options 	SCSI_DELAY=5000		# Delay (in ms) before probing SCSI
+options 	KTRACE			# ktrace(1) support
+options 	SYSVSHM			# SYSV-style shared memory
+options 	SYSVMSG			# SYSV-style message queues
+options 	SYSVSEM			# SYSV-style semaphores
+options 	_KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time extensions
+options 	KBD_INSTALL_CDEV	# install a CDEV entry in /dev
+options 	PREEMPTION
+options 	FREEBSD_BOOT_LOADER
+options 	VFP			# vfp/neon
+
+# Debugging
+makeoptions	DEBUG=-g		# Build kernel with gdb(1) debug symbols
+options 	BREAK_TO_DEBUGGER
+#options	VERBOSE_SYSINIT		# Enable verbose sysinit messages
+options 	KDB
+options 	DDB			# Enable the kernel debugger
+#options	INVARIANTS		# Enable calls of extra sanity checking
+#options	INVARIANT_SUPPORT	# Extra sanity checks of internal structures, required by INVARIANTS
+#options 	WITNESS			# Enable checks to detect deadlocks and cycles
+#options 	WITNESS_SKIPSPIN	# Don't run witness on spinlocks for speed
+#options 	DIAGNOSTIC
+
+# NFS support
+#options	NFSCL
+#options	NFSSERVER		# Network Filesystem Server
+#options	NFSCLIENT		# Network Filesystem Client
+
+# MMC/SD/SDIO card slot support
+#device		mmc			# mmc/sd bus
+#device		mmcsd			# mmc/sd flash cards
+
+# Boot device is 2nd slice on MMC/SD card
+options 	ROOTDEVNAME=\"ufs:/dev/da0s2\"
+
+# Console and misc
+device		uart
+device		uart_ns8250
+device		pty
+device		snp
+device		md
+device		random			# Entropy device
+
+# I2C support
+#device		iicbus
+#device		iic
+
+# GPIO
+device		gpio
+
+device		scbus			# SCSI bus (required for SCSI)
+device		da			# Direct Access (disks)
+device		pass
+
+# USB support
+options 	USB_HOST_ALIGN=32	# Align usb buffers to cache line size.
+device		usb
+options 	USB_DEBUG
+#options	USB_REQ_DEBUG
+#options	USB_VERBOSE
+device		dwcotg			# DWC OTG controller
+
+device		umass
+
+# Ethernet
+device		loop
+device		ether
+device		mii
+device		smscphy
+device		bpf
+
+# USB ethernet support, requires miibus
+device		miibus
+device		udav
+
+# Flattened Device Tree
+options 	FDT
+options 	FDT_DTB_STATIC
+makeoptions	FDT_DTS_FILE=rk3188-radxa.dts
+
+options		SMP			# Enable multiple cores


Property changes on: trunk/sys/arm/conf/RADXA
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/RPI-B
===================================================================
--- trunk/sys/arm/conf/RPI-B	                        (rev 0)
+++ trunk/sys/arm/conf/RPI-B	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,142 @@
+#
+# RPI-B -- Custom configuration for the Raspberry Pi
+#
+# 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: stable/10/sys/arm/conf/RPI-B 287082 2015-08-23 20:50:22Z ian $
+
+ident		RPI-B
+
+include		"../broadcom/bcm2835/std.rpi"
+
+options 	HZ=100
+options 	SCHED_4BSD		# 4BSD scheduler
+options 	PREEMPTION		# Enable kernel thread preemption
+options 	INET			# InterNETworking
+options 	INET6			# IPv6 communications protocols
+options 	SCTP			# Stream Control Transmission Protocol
+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
+options 	UFS_GJOURNAL		# Enable gjournal-based UFS journaling
+options 	QUOTA			# Enable disk quotas for UFS
+options 	NFSCL			# New Network Filesystem Client
+options 	NFSLOCKD		# Network Lock Manager
+options 	NFS_ROOT		# NFS usable as /, requires NFSCL
+options 	MSDOSFS			# MSDOS Filesystem
+options 	CD9660			# ISO 9660 Filesystem
+options 	PROCFS			# Process filesystem (requires PSEUDOFS)
+options 	PSEUDOFS		# Pseudo-filesystem framework
+options 	TMPFS			# Efficient memory filesystem
+options 	GEOM_PART_GPT		# GUID Partition Tables
+options 	GEOM_PART_BSD		# BSD partition scheme
+options 	GEOM_PART_MBR		# MBR partition scheme
+options 	GEOM_LABEL		# Provides labelization 
+options 	COMPAT_43		# Compatible with BSD 4.3 [KEEP THIS!]
+options 	SCSI_DELAY=5000		# Delay (in ms) before probing SCSI
+options 	KTRACE			# ktrace(1) support
+options 	SYSVSHM			# SYSV-style shared memory
+options 	SYSVMSG			# SYSV-style message queues
+options 	SYSVSEM			# SYSV-style semaphores
+options 	_KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
+options 	KBD_INSTALL_CDEV	# install a CDEV entry in /dev
+options 	FREEBSD_BOOT_LOADER	# Process metadata passed from loader(8)
+options 	VFP			# Enable floating point hardware support
+
+# Debugging for use in -current
+makeoptions	DEBUG=-g		# Build kernel with gdb(1) debug symbols
+options 	ALT_BREAK_TO_DEBUGGER
+#options 	VERBOSE_SYSINIT		# Enable verbose sysinit messages
+options 	KDB			# Enable kernel debugger support
+# For minimum debugger support (stable branch) use:
+#options 	KDB_TRACE		# Print a stack trace for a panic
+# For full debugger support use this instead:
+options 	DDB			# Enable the kernel debugger
+options 	INVARIANTS		# Enable calls of extra sanity checking
+options 	INVARIANT_SUPPORT	# Extra sanity checks of internal structures, required by INVARIANTS
+#options 	WITNESS			# Enable checks to detect deadlocks and cycles
+#options 	WITNESS_SKIPSPIN	# Don't run witness on spinlocks for speed
+#options 	DIAGNOSTIC
+
+# NFS root from boopt/dhcp
+#options 	BOOTP
+#options 	BOOTP_NFSROOT
+#options 	BOOTP_COMPAT
+#options 	BOOTP_NFSV3
+#options 	BOOTP_WIRED_TO=ue0
+
+#options 	ROOTDEVNAME=\"ufs:mmcsd0s2\"
+
+device		bpf
+device		loop
+device		ether
+device		uart
+device		pty
+device		snp
+device		pl011
+
+# Comment following lines for boot console on serial port
+device		vt
+device		kbdmux
+device		ukbd
+
+device		sdhci
+device		mmc
+device		mmcsd
+
+device		gpio
+device		gpioled
+
+# I2C
+device		iic
+device		iicbus
+device		bcm2835_bsc
+
+options 	KDB
+options 	DDB			# Enable the kernel debugger
+#options 	INVARIANTS		# Enable calls of extra sanity checking
+#options 	INVARIANT_SUPPORT	# Extra sanity checks of internal structures, required by INVARIANTS
+
+device		md
+device		random			# Entropy device
+
+# USB support
+device		usb
+options 	USB_DEBUG
+device		dwcotg			# DWC OTG controller
+
+# USB storage support
+device		scbus
+device		da
+device		umass
+
+# USB ethernet support
+device		smcphy
+device		mii
+device		smsc
+
+# SPI
+device		spibus
+device		bcm2835_spi
+
+# Flattened Device Tree
+options 	FDT			# Configure using FDT/DTB data
+# Note:  DTB is normally loaded and modified by RPi boot loader, then
+# handed to kernel via U-Boot and ubldr.
+#options 	FDT_DTB_STATIC
+#makeoptions	FDT_DTS_FILE=rpi.dts
+makeoptions	MODULES_EXTRA=dtb/rpi


Property changes on: trunk/sys/arm/conf/RPI-B
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/SAM9260EK
===================================================================
--- trunk/sys/arm/conf/SAM9260EK	                        (rev 0)
+++ trunk/sys/arm/conf/SAM9260EK	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,185 @@
+# Kernel configuration for Atmel SAM9260-EK eval 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: stable/10/sys/arm/conf/SAM9260EK 283368 2015-05-24 14:25:03Z ian $
+
+#NO_UNIVERSE
+
+ident		SAM9260EK
+
+include "../at91/std.sam9260ek"
+
+# To statically compile in device wiring instead of /boot/device.hints
+hints		"SAM9260EK.hints"
+
+#makeoptions	DEBUG=-g		# Build kernel with gdb(1) debug symbols
+makeoptions	MODULES_OVERRIDE=""
+
+options 	SCHED_4BSD		# 4BSD scheduler
+#options 	PREEMPTION		# Enable kernel thread preemption
+options 	INET			# InterNETworking
+#options 	INET6			# IPv6 communications protocols
+#options 	SCTP			# Stream Control Transmission Protocol
+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
+#options 	UFS_GJOURNAL		# Enable gjournal-based UFS journaling
+#options 	MD_ROOT			# MD is a potential root device
+options 	NANDFS			# NAND file system
+options 	NFSCL			# New Network Filesystem Client
+#options 	NFSD			# New Network Filesystem Server
+options 	NFSLOCKD		# Network Lock Manager
+options 	NFS_ROOT		# NFS usable as /, requires NFSCL
+options 	TMPFS			# Efficient memory filesystem
+#options 	MSDOSFS			# MSDOS Filesystem
+#options 	CD9660			# ISO 9660 Filesystem
+#options 	PROCFS			# Process filesystem (requires PSEUDOFS)
+#options 	PSEUDOFS		# Pseudo-filesystem framework
+options 	GEOM_PART_BSD		# BSD partition scheme
+options 	GEOM_PART_MBR		# MBR partition scheme
+#options 	GEOM_PART_GPT		# GUID Partition Tables.
+#options 	GEOM_LABEL		# Provides labelization
+#options 	COMPAT_FREEBSD5		# Compatible with FreeBSD5
+#options 	COMPAT_FREEBSD6		# Compatible with FreeBSD6
+#options 	COMPAT_FREEBSD7		# Compatible with FreeBSD7
+options 	SCSI_DELAY=5000		# Delay (in ms) before probing SCSI
+options 	KTRACE			# ktrace(1) support
+#options 	STACK			# stack(9) support
+options 	SYSVSHM			# SYSV-style shared memory
+options 	SYSVMSG			# SYSV-style message queues
+options 	SYSVSEM			# SYSV-style semaphores
+options 	_KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
+options 	PRINTF_BUFR_SIZE=128	# Prevent printf output being interspersed.
+#options 	HWPMC_HOOKS		# Necessary kernel hooks for hwpmc(4)
+#options 	AUDIT			# Security event auditing
+#options 	CAPABILITY_MODE		# Capsicum capability mode
+#options 	CAPABILITIES		# Capsicum capabilities
+#options 	MAC			# TrustedBSD MAC Framework
+#options 	INCLUDE_CONFIG_FILE	# Include this file in kernel
+
+# required for netbooting
+#options 	BOOTP
+#options 	BOOTP_COMPAT
+#options 	BOOTP_NFSROOT
+#options 	BOOTP_NFSV3
+#options 	BOOTP_WIRED_TO=ate0
+
+# alternatively, boot from a MMC/SD memory card
+#options 	ROOTDEVNAME=\"ufs:/dev/mmcsd0s1a\"
+
+# Alternatively, boot from a USB card.
+options 	ROOTDEVNAME=\"ufs:/dev/da0s1a\"
+
+# kernel/memory size reduction
+options 	MUTEX_NOINLINE
+options 	NO_FFS_SNAPSHOT
+options 	NO_SWAPPING
+options 	NO_SYSCTL_DESCR
+options 	RWLOCK_NOINLINE
+
+# Debugging support.  Always need this:
+#options 	KDB			# Enable kernel debugger support.
+# For minimum debugger support (stable branch) use:
+#options 	KDB_TRACE		# Print a stack trace for a panic.
+# For full debugger support use this instead:
+#options 	DDB			# Support DDB.
+#options 	GDB			# Support remote GDB.
+#options 	DEADLKRES		# Enable the deadlock resolver
+#options 	INVARIANTS		# Enable calls of extra sanity checking
+#options 	INVARIANT_SUPPORT	# Extra sanity checks of internal structures, required by INVARIANTS
+#options 	WITNESS			# Enable checks to detect deadlocks and cycles
+#options 	WITNESS_SKIPSPIN	# Don't run witness on spinlocks for speed
+#options 	MALLOC_DEBUG_MAXZONES=8	# Separate malloc(9) zones
+
+# The `bpf' device enables the Berkeley Packet Filter.
+# Be aware of the administrative consequences of enabling this!
+# Note that 'bpf' is required for DHCP.
+device		bpf			# Berkeley packet filter
+
+# Ethernet
+device		mii			# Minimal MII support
+device		ate			# Atmel AT91 Ethernet driver
+
+# I2C
+device		at91_twi		# Atmel AT91 Two-wire Interface
+device		iic			# I2C generic I/O device driver
+device		iicbus			# I2C bus system
+device		icee			# I2C eeprom
+
+# MMC/SD
+# See comment for DataFlash below
+device		at91_mci		# Atmel AT91 Multimedia Card Interface
+options 	AT91_MCI_HAS_4WIRE	# 4 wires
+options 	AT91_MCI_SLOT_B		# Wired to slot B
+device		mmc			# MMC/SD bus
+device		mmcsd			# MMC/SD memory card
+
+# DataFlash
+# The DataFlash and MMC card are wired together, so we must pick one or the
+# other.  This is due to pin mux, and also due to the design of the
+# SAM9260EK board.  SLOT A wouldn't have this issue.
+#device		at91_spi		# Atmel AT91 Serial Peripheral Interface
+#device		spibus			# SPI bus
+#device		at45d			# Atmel AT45D
+#device		geom_map		# GEOM partition mapping
+
+# Pseudo devices.
+device		loop			# Network loopback
+device		random			# Entropy device
+device		ether			# Ethernet support
+#device		vlan			# 802.1Q VLAN support
+#device		tun			# Packet tunnel.
+#device		md			# Memory "disks"
+#device		gif			# IPv6 and IPv4 tunneling
+#device		faith			# IPv6-to-IPv4 relaying (translation)
+#device		firmware		# firmware assist module
+
+# 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/DVD
+device		pass			# Passthrough device (direct ATA/SCSI access)
+device		ses			# Enclosure Services (SES and SAF-TE)
+#device		ctl			# CAM Target Layer
+
+# Serial (COM) ports
+device		uart			# Multi-uart driver
+options 	ALT_BREAK_TO_DEBUGGER
+
+# USB support
+#options 	USB_DEBUG		# enable debug msgs
+device		ohci			# OHCI USB interface
+device		usb			# USB Bus (required)
+device		umass			# Disks/Mass storage - Requires scbus and da
+
+# watchdog
+device		at91_wdt		# Atmel AT91 Watchdog Timer
+
+# NAND Flash - Reference design has Samsung 256MB but others possible
+device		nand			# NAND interface on CS3
+
+# Coming soon, but not yet
+#options 	FDT
+#options 	FDT_DTB_STATIC
+#makeoptions	FDT_DTS_FILE=sam9260ek.dts
+
+options 	EARLY_PRINTF
+options 	SOCDEV_PA=0xfc000000
+options 	SOCDEV_VA=0xdc000000


Property changes on: trunk/sys/arm/conf/SAM9260EK
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/SAM9260EK.hints
===================================================================
--- trunk/sys/arm/conf/SAM9260EK.hints	                        (rev 0)
+++ trunk/sys/arm/conf/SAM9260EK.hints	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,48 @@
+# $FreeBSD: stable/10/sys/arm/conf/SAM9260EK.hints 238811 2012-07-26 16:34:21Z imp $
+
+# Atmel AT45DB21D
+hint.at45d.0.at="spibus0"
+hint.at45d.0.cs=1
+# Area 0:	00000000 to 000041FF (RO) Bootstrap
+# Area 1:	00004200 to 000083FF      Environment
+# Area 2:	00008400 to 00041FFF (RO) U-Boot
+# Area 3:	00042000 to 00251FFF      Kernel
+# Area 4:	00252000 to 0083FFFF      FS
+# bootstrap
+hint.map.0.at="flash/spi0"
+hint.map.0.start=0x00000000
+hint.map.0.end=0x000041ff
+hint.map.0.name="bootstrap"
+hint.map.0.readonly=1
+# uboot environment
+hint.map.1.at="flash/spi0"
+hint.map.1.start=0x00004200
+hint.map.1.end=0x00083ff
+hint.map.1.name="uboot-env"
+#hint.map.1.readonly=1
+# uboot
+hint.map.2.at="flash/spi0"
+hint.map.2.start=0x00008400
+hint.map.2.end=0x00041fff
+hint.map.2.name="uboot"
+hint.map.2.readonly=1
+# kernel
+hint.map.3.at="flash/spi0"
+hint.map.3.start=0x00042000
+hint.map.3.end=0x00251fff
+hint.map.3.name="fs"
+#hint.map.3.readonly=1
+# fs
+hint.map.4.at="flash/spi0"
+hint.map.4.start=0x00252000
+hint.map.4.end=0x0083ffff
+hint.map.4.name="fs"
+#hint.map.4.readonly=1
+
+# EEPROM at24c512 - 512kbit 65,536x8 memory
+hint.icee.0.at="iicbus0"
+hint.icee.0.addr=0xa0
+hint.icee.0.type=16
+hint.icee.0.size=65536
+hint.icee.0.rd_sz=128
+hint.icee.0.wr_sz=128


Property changes on: trunk/sys/arm/conf/SAM9260EK.hints
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/SAM9G20EK
===================================================================
--- trunk/sys/arm/conf/SAM9G20EK	                        (rev 0)
+++ trunk/sys/arm/conf/SAM9G20EK	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,156 @@
+# Kernel configuration for Atmel AT91SAM9G20EK Rev B. development card
+#
+# For more information on this file, please read 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: stable/10/sys/arm/conf/SAM9G20EK 278676 2015-02-13 15:27:46Z ian $
+
+ident		SAM9G20EK
+
+include "../at91/std.sam9g20ek"
+
+#To statically compile in device wiring instead of /boot/device.hints
+hints		"SAM9G20EK.hints"
+makeoptions	MODULES_OVERRIDE=""
+
+makeoptions	DEBUG=-g		# Build kernel with gdb(1) debug symbols
+options 	DDB
+options 	KDB
+
+options 	SCHED_4BSD		# 4BSD scheduler
+options 	INET			# InterNETworking
+#options 	INET6			# IPv6 communications protocols
+options 	GEOM_PART_BSD		# BSD partition scheme
+options 	GEOM_PART_MBR		# MBR partition scheme
+options 	TMPFS			# Efficient memory filesystem
+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
+#options 	MD_ROOT			# MD is a potential root device
+#options 	MD_ROOT_SIZE=4096	# 4MB ram disk
+options 	NANDFS			# NAND file system
+options 	NFSCL			# New Network Filesystem Client
+#options 	NFSD			# New Network Filesystem Server
+#options 	NFSLOCKD		# Network Lock Manager
+#options 	NFS_ROOT		# NFS usable as /, requires NFSCL
+#options 	BOOTP_NFSROOT
+#options 	BOOTP
+#options 	BOOTP_NFSV3
+#options 	BOOTP_WIRED_TO=ate0
+#options 	BOOTP_COMPAT
+
+options 	ROOTDEVNAME=\"ufs:/dev/mmcsd0s1a\"
+
+options 	ALT_BREAK_TO_DEBUGGER
+
+#options 	MSDOSFS			# MSDOS Filesystem
+#options 	CD9660			# ISO 9660 Filesystem
+#options 	PROCFS			# Process filesystem (requires PSEUDOFS)
+#options 	PSEUDOFS		# Pseudo-filesystem framework
+#options 	SCSI_DELAY=5000		# Delay (in ms) before probing SCSI
+#options 	KTRACE			# ktrace(1) support
+options 	SYSVSHM			# SYSV-style shared memory
+options 	SYSVMSG			# SYSV-style message queues
+options 	SYSVSEM			# SYSV-style semaphores
+options 	_KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time extensions
+options 	MUTEX_NOINLINE
+options 	RWLOCK_NOINLINE
+options 	NO_FFS_SNAPSHOT
+options 	NO_SWAPPING
+
+# Debugging for use in -current
+#options 	INVARIANTS		# Enable calls of extra sanity checking
+#options 	INVARIANT_SUPPORT	# Extra sanity checks of internal structures, required by INVARIANTS
+#options 	WITNESS			# Enable checks to detect deadlocks and cycles
+#options 	WITNESS_SKIPSPIN	# Don't run witness on spinlocks for speed
+#options 	DIAGNOSTIC
+
+device		random
+device		loop
+device		bpf
+device		ether
+device		md
+
+device		uart			# Serial Ports
+
+# Ethernet
+device		ate			# Ethernet Driver	
+device		mii
+option 		AT91_ATE_USE_RMII
+
+device		at91_twi		# TWI: Two Wire Interface (EEPROM)
+device		at91_wdt		# WDT: Watchdog timer
+
+# NAND Flash - Reference design has Samsung 256MB but others possible
+device		nand			# NAND interface on CS3
+
+# NOTE: SPI DataFlash and mci/mmc/mmcsd have hardware
+# 	confilict on this card. Use one or the other.
+#       see board_sam9g20ek.c
+
+# SPI: Data Flash
+#device		at91_spi		# SPI:
+#device		spibus
+#device		at45d			# at45db642 and maybe others
+
+# MMC/SD
+device		at91_mci
+device		mmc
+device		mmcsd
+option		AT91_MCI_SLOT_B
+option		AT91_MCI_HAS_4WIRE
+
+# iic
+device		iic
+device		iicbus
+device		icee
+
+# SCSI peripherals
+device		scbus			# SCSI bus (required for ATA/SCSI)
+device		da			# Direct Access (disks)
+device		cd			# CD
+device		pass			# Passthrough device (direct ATA/SCSI access)
+
+# USB support
+device		ohci			# OHCI localbus->USB interface
+device		usb			# USB Bus (required)
+device		umass			# Disks/Mass storage - Requires scbus and da
+device		uhid			# "Human Interface Devices"
+#device		ulpt			# Printer
+#device		udbp			# USB Double Bulk Pipe devices
+
+# USB Ethernet, requires miibus
+#device		miibus
+#device		aue			# ADMtek USB Ethernet
+#device		axe			# ASIX Electronics USB Ethernet
+#device		cdce			# Generic USB over Ethernet
+#device		cue			# CATC USB Ethernet
+#device		kue			# Kawasaki LSI USB Ethernet
+#device		rue			# RealTek RTL8150 USB Ethernet
+#device		udav			# Davicom DM9601E USB
+
+# USB Wireless
+#device		rum			# Ralink Technology RT2501USB wireless NICs
+#device		uath			# Atheros AR5523 wireless NICs
+#device		ural			# Ralink Technology RT2500USB wireless NICs
+#device		zyd			# ZyDAS zd1211/zd1211b wireless NICs
+
+# Wireless NIC cards
+#device		wlan			# 802.11 support
+#device		wlan_wep		# 802.11 WEP support
+#device		wlan_ccmp		# 802.11 CCMP support
+#device		wlan_tkip		# 802.11 TKIP support
+#device		wlan_amrr		# AMRR transmit rate control algorithm


Property changes on: trunk/sys/arm/conf/SAM9G20EK
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/SAM9G20EK.hints
===================================================================
--- trunk/sys/arm/conf/SAM9G20EK.hints	                        (rev 0)
+++ trunk/sys/arm/conf/SAM9G20EK.hints	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,10 @@
+# $FreeBSD: stable/10/sys/arm/conf/SAM9G20EK.hints 236988 2012-06-13 04:40:29Z imp $
+#
+
+# EEPROM
+hint.icee.0.at="iicbus0"
+hint.icee.0.addr=0xa0
+hint.icee.0.type=16
+hint.icee.0.size=65536
+hint.icee.0.rd_sz=256
+hint.icee.0.wr_sz=256


Property changes on: trunk/sys/arm/conf/SAM9G20EK.hints
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/SAM9X25EK
===================================================================
--- trunk/sys/arm/conf/SAM9X25EK	                        (rev 0)
+++ trunk/sys/arm/conf/SAM9X25EK	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,156 @@
+# Kernel configuration for Atmel AT91SAM9G20EK Rev B. development card 
+#
+# For more information on this file, please read 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: stable/10/sys/arm/conf/SAM9X25EK 278676 2015-02-13 15:27:46Z ian $
+
+#NO_UNIVERSE
+
+ident		SAM9X25EK
+
+include "../at91/std.sam9x25ek"
+
+#To statically compile in device wiring instead of /boot/device.hints
+hints		"SAM9G20EK.hints"
+makeoptions	MODULES_OVERRIDE=""
+
+makeoptions	DEBUG=-g		# Build kernel with gdb(1) debug symbols
+options 	DDB
+options 	KDB
+
+options 	SCHED_4BSD		# 4BSD scheduler
+options 	INET			# InterNETworking
+#options 	INET6			# IPv6 communications protocols
+options 	GEOM_PART_BSD		# BSD partition scheme
+options 	GEOM_PART_MBR		# MBR partition scheme
+options 	TMPFS			# Efficient memory filesystem
+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
+#options 	MD_ROOT			# MD is a potential root device
+#options 	MD_ROOT_SIZE=4096	# 4MB ram disk
+options 	NFSCL			# New Network Filesystem Client
+#options 	NFSD			# New Network Filesystem Server
+#options 	NFSLOCKD		# Network Lock Manager
+#options 	NFS_ROOT		# NFS usable as /, requires NFSCL
+#options 	BOOTP_NFSROOT
+#options 	BOOTP
+#options 	BOOTP_NFSV3
+#options 	BOOTP_WIRED_TO=ate0
+#options 	BOOTP_COMPAT
+
+options 	ROOTDEVNAME=\"ufs:/dev/mmcsd0s1a\"
+
+options 	ALT_BREAK_TO_DEBUGGER
+
+#options 	MSDOSFS			# MSDOS Filesystem
+#options 	CD9660			# ISO 9660 Filesystem
+#options 	PROCFS			# Process filesystem (requires PSEUDOFS)
+#options 	PSEUDOFS		# Pseudo-filesystem framework
+#options 	SCSI_DELAY=5000		# Delay (in ms) before probing SCSI
+#options 	KTRACE			# ktrace(1) support
+options 	SYSVSHM			# SYSV-style shared memory
+options 	SYSVMSG			# SYSV-style message queues
+options 	SYSVSEM			# SYSV-style semaphores
+options 	_KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time extensions
+options 	MUTEX_NOINLINE
+options 	RWLOCK_NOINLINE
+options 	NO_FFS_SNAPSHOT
+options 	NO_SWAPPING
+
+# Debugging for use in -current
+#options 	INVARIANTS		# Enable calls of extra sanity checking
+#options 	INVARIANT_SUPPORT	# Extra sanity checks of internal structures, required by INVARIANTS
+#options 	WITNESS			# Enable checks to detect deadlocks and cycles
+#options 	WITNESS_SKIPSPIN	# Don't run witness on spinlocks for speed
+#options 	DIAGNOSTIC
+
+device		random
+device		pty
+device		loop
+device		bpf
+device		ether
+device		md
+
+device		uart			# Serial Ports
+
+# Ethernet
+device		ate			# Ethernet Driver	
+device		mii
+option 		AT91_ATE_USE_RMII
+
+#device		at91_twi		# TWI: Two Wire Interface (EEPROM)
+device		at91_wdt		# WDT: Watchdog timer
+
+# NOTE: SPI DataFlash and mci/mmc/mmcsd have hardware 
+# 	confilict on this card. Use one or the other.
+#       see board_sam9g20ek.c
+
+# SPI: Data Flash 
+#device		at91_spi		# SPI:
+#device		spibus
+#device		at45d			# at45db642 and maybe others
+
+# MMC/SD
+device		at91_mci
+device		mmc
+device		mmcsd
+#option		AT91_MCI_SLOT_B
+option		AT91_MCI_HAS_4WIRE
+
+# iic
+device		iic
+device		iicbus
+device		icee
+
+# SCSI peripherals
+device		scbus			# SCSI bus (required for ATA/SCSI)
+device		da			# Direct Access (disks)
+device		cd			# CD
+device		pass			# Passthrough device (direct ATA/SCSI access)
+
+# USB support
+#device		ohci			# OHCI localbus->USB interface
+#device		usb			# USB Bus (required)
+#device		umass			# Disks/Mass storage - Requires scbus and da
+#device		uhid			# "Human Interface Devices"
+#device		ulpt			# Printer
+#device		udbp			# USB Double Bulk Pipe devices
+
+# USB Ethernet, requires miibus
+device		miibus
+#device		aue			# ADMtek USB Ethernet
+#device		axe			# ASIX Electronics USB Ethernet
+#device		cdce			# Generic USB over Ethernet
+#device		cue			# CATC USB Ethernet
+#device		kue			# Kawasaki LSI USB Ethernet
+#device		rue			# RealTek RTL8150 USB Ethernet
+#device		udav			# Davicom DM9601E USB
+
+# USB Wireless
+#device		rum			# Ralink Technology RT2501USB wireless NICs
+#device		uath			# Atheros AR5523 wireless NICs
+#device		ural			# Ralink Technology RT2500USB wireless NICs
+#device		zyd			# ZyDAS zd1211/zd1211b wireless NICs
+
+# Wireless NIC cards
+#device		wlan			# 802.11 support
+#device		wlan_wep		# 802.11 WEP support
+#device		wlan_ccmp		# 802.11 CCMP support
+#device		wlan_tkip		# 802.11 TKIP support
+#device		wlan_amrr		# AMRR transmit rate control algorithm
+


Property changes on: trunk/sys/arm/conf/SAM9X25EK
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/SAM9X25EK.hints
===================================================================
--- trunk/sys/arm/conf/SAM9X25EK.hints	                        (rev 0)
+++ trunk/sys/arm/conf/SAM9X25EK.hints	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,10 @@
+# $FreeBSD: stable/10/sys/arm/conf/SAM9X25EK.hints 237742 2012-06-29 04:18:52Z imp $
+#
+
+# EEPROM 
+hint.icee.0.at="iicbus0"
+hint.icee.0.addr=0xa0
+hint.icee.0.type=16
+hint.icee.0.size=65536
+hint.icee.0.rd_sz=256
+hint.icee.0.wr_sz=256


Property changes on: trunk/sys/arm/conf/SAM9X25EK.hints
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/SHEEVAPLUG
===================================================================
--- trunk/sys/arm/conf/SHEEVAPLUG	                        (rev 0)
+++ trunk/sys/arm/conf/SHEEVAPLUG	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,85 @@
+#
+# Custom kernel for Marvell SheevaPlug devices.
+#
+# $FreeBSD: stable/10/sys/arm/conf/SHEEVAPLUG 283404 2015-05-24 15:21:47Z ian $
+#
+#NO_UNIVERSE
+
+ident		SHEEVAPLUG
+include		"../mv/kirkwood/std.db88f6xxx"
+
+options 	SOC_MV_KIRKWOOD
+
+#makeoptions	DEBUG=-g		# Build kernel with gdb(1) debug symbols
+makeoptions	WERROR="-Werror"
+
+options 	SCHED_4BSD		# 4BSD scheduler
+options 	INET			# InterNETworking
+options 	INET6			# IPv6 communications protocols
+options 	GEOM_PART_BSD		# BSD partition scheme
+options 	GEOM_PART_MBR		# MBR partition scheme
+options 	TMPFS			# Efficient memory filesystem
+options 	FFS			# Berkeley Fast Filesystem
+options 	NANDFS			# NAND Filesystem
+options 	NFSCL			# New Network Filesystem Client
+options 	NFSLOCKD		# Network Lock Manager
+options 	NFS_ROOT		# NFS usable as /, requires NFSCL
+options 	BOOTP
+options 	BOOTP_NFSROOT
+options 	BOOTP_NFSV3
+options 	BOOTP_WIRED_TO=mge0
+
+# Root fs on USB device
+#options 	ROOTDEVNAME=\"ufs:/dev/da0a\"
+
+options 	SYSVSHM			# SYSV-style shared memory
+options 	SYSVMSG			# SYSV-style message queues
+options 	SYSVSEM			# SYSV-style semaphores
+options 	_KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time extensions
+options 	MUTEX_NOINLINE
+options 	RWLOCK_NOINLINE
+options 	NO_FFS_SNAPSHOT
+options 	NO_SWAPPING
+
+# Debugging
+options 	ALT_BREAK_TO_DEBUGGER
+options 	DDB
+options 	KDB
+
+# Pseudo devices
+device		random
+device		loop
+
+# Serial ports
+device		uart
+
+# Networking
+device		ether
+device		mge			# Marvell Gigabit Ethernet controller
+device		mii
+device		e1000phy
+device		bpf
+options 	HZ=1000
+options 	DEVICE_POLLING
+device		vlan
+
+device		cesa			# Marvell security engine
+device		crypto
+device		cryptodev
+
+# USB
+options 	USB_DEBUG		# enable debug msgs
+device		usb
+device		ehci
+device		umass
+device		scbus
+device		pass
+device		da
+
+# NAND
+device		nand
+
+# Flattened Device Tree
+options 	FDT
+options 	FDT_DTB_STATIC
+makeoptions	FDT_DTS_FILE=sheevaplug.dts


Property changes on: trunk/sys/arm/conf/SHEEVAPLUG
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/SN9G45
===================================================================
--- trunk/sys/arm/conf/SN9G45	                        (rev 0)
+++ trunk/sys/arm/conf/SN9G45	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,133 @@
+# Kernel configuration for DesignA Electronics Snapper9G45 System on Module
+#
+# For more information on this file, please read 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: stable/10/sys/arm/conf/SN9G45 278676 2015-02-13 15:27:46Z ian $
+
+#NO_UNIVERSE
+
+ident		SN9G45
+
+include "../at91/std.sn9g45"
+
+#To statically compile in device wiring instead of /boot/device.hints
+#hints		"SN9G45.hints"
+makeoptions	MODULES_OVERRIDE=""
+
+makeoptions	DEBUG=-g		# Build kernel with gdb(1) debug symbols
+options 	DDB
+options 	KDB
+
+options 	SCHED_4BSD		# 4BSD scheduler
+options 	INET			# InterNETworking
+#options 	INET6			# IPv6 communications protocols
+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
+#options 	MD_ROOT			# MD is a potential root device
+#options 	MD_ROOT_SIZE=4096	# 4MB ram disk
+options 	NFSCL			# New Network Filesystem Client
+#options 	NFSD			# New Network Filesystem Server
+#options 	NFSLOCKD		# Network Lock Manager
+#options 	NFS_ROOT		# NFS usable as /, requires NFSCL
+#options 	BOOTP_NFSROOT
+#options 	BOOTP
+#options 	BOOTP_NFSV3
+#options 	BOOTP_WIRED_TO=ate0
+#options 	BOOTP_COMPAT
+
+options 	ROOTDEVNAME=\"ufs:/dev/da0s1\"
+
+options 	ALT_BREAK_TO_DEBUGGER
+
+options 	GEOM_PART_BSD		# BSD partition scheme
+options 	GEOM_PART_MBR		# MBR partition scheme
+options 	TMPFS			# Efficient memory filesystem
+#options 	MSDOSFS			# MSDOS Filesystem
+#options 	CD9660			# ISO 9660 Filesystem
+#options 	PROCFS			# Process filesystem (requires PSEUDOFS)
+#options 	PSEUDOFS		# Pseudo-filesystem framework
+options 	SCSI_DELAY=1000		# Delay (in ms) before probing SCSI
+#options 	KTRACE			# ktrace(1) support
+options 	SYSVSHM			# SYSV-style shared memory
+options 	SYSVMSG			# SYSV-style message queues
+options 	SYSVSEM			# SYSV-style semaphores
+options 	_KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time extensions
+options 	MUTEX_NOINLINE
+options 	RWLOCK_NOINLINE
+options 	NO_FFS_SNAPSHOT
+options 	NO_SWAPPING
+
+# Debugging for use in -current
+#options 	INVARIANTS		# Enable calls of extra sanity checking
+#options 	INVARIANT_SUPPORT	# Extra sanity checks of internal structures, required by INVARIANTS
+#options 	WITNESS			# Enable checks to detect deadlocks and cycles
+#options 	WITNESS_SKIPSPIN	# Don't run witness on spinlocks for speed
+#options 	DIAGNOSTIC
+
+device		random
+device		loop
+device		bpf
+device		ether
+device		md
+
+device		uart			# Serial Ports
+
+# Ethernet
+device		ate			# Ethernet Driver	
+device		mii
+option 		AT91_ATE_USE_RMII
+
+device		at91_wdt		# WDT: Watchdog timer
+
+# SCSI peripherals
+device		scbus			# SCSI bus (required for ATA/SCSI)
+device		da			# Direct Access (disks)
+device		cd			# CD
+device		pass			# Passthrough device (direct ATA/SCSI access)
+
+# USB support
+device		ohci			# OHCI localbus->USB interface
+device		usb			# USB Bus (required)
+device		umass			# Disks/Mass storage - Requires scbus and da
+device		uhid			# "Human Interface Devices"
+#device		ulpt			# Printer
+#device		udbp			# USB Double Bulk Pipe devices
+
+# USB Ethernet, requires miibus
+device		miibus
+#device		aue			# ADMtek USB Ethernet
+#device		axe			# ASIX Electronics USB Ethernet
+#device		cdce			# Generic USB over Ethernet
+#device		cue			# CATC USB Ethernet
+#device		kue			# Kawasaki LSI USB Ethernet
+#device		rue			# RealTek RTL8150 USB Ethernet
+device		udav			# Davicom DM9601E USB
+
+# USB Wireless
+#device		rum			# Ralink Technology RT2501USB wireless NICs
+#device		uath			# Atheros AR5523 wireless NICs
+#device		ural			# Ralink Technology RT2500USB wireless NICs
+#device		zyd			# ZyDAS zd1211/zd1211b wireless NICs
+
+# Wireless NIC cards
+#device		wlan			# 802.11 support
+#device		wlan_wep		# 802.11 WEP support
+#device		wlan_ccmp		# 802.11 CCMP support
+#device		wlan_tkip		# 802.11 TKIP support
+#device		wlan_amrr		# AMRR transmit rate control algorithm
+


Property changes on: trunk/sys/arm/conf/SN9G45
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/TS7800
===================================================================
--- trunk/sys/arm/conf/TS7800	                        (rev 0)
+++ trunk/sys/arm/conf/TS7800	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,81 @@
+#
+# Custom kernel for the TS-7800 board.
+#
+# $FreeBSD: stable/10/sys/arm/conf/TS7800 283387 2015-05-24 14:57:17Z ian $
+#
+
+ident		TS7800
+include		"../mv/orion/std.ts7800"
+
+options 	SOC_MV_ORION
+
+#makeoptions	DEBUG=-g		# Build kernel with gdb(1) debug symbols
+makeoptions	WERROR="-Werror"
+
+options 	SCHED_4BSD		# 4BSD scheduler
+options 	INET			# InterNETworking
+options 	INET6			# IPv6 communications protocols
+options 	FFS			# Berkeley Fast Filesystem
+options 	SOFTUPDATES		# Enable FFS soft updates support
+options 	NFSCL			# New Network Filesystem Client
+options 	NFSLOCKD		# Network Lock Manager
+options 	NFS_ROOT		# NFS usable as /, requires NFSCL
+options 	BOOTP
+options 	BOOTP_NFSROOT
+options 	BOOTP_NFSV3
+options 	BOOTP_WIRED_TO=mge0
+
+options 	GEOM_PART_BSD		# BSD partition scheme
+options 	GEOM_PART_MBR		# MBR partition scheme
+options 	TMPFS			# Efficient memory filesystem
+
+options 	SYSVSHM			# SYSV-style shared memory
+options 	SYSVMSG			# SYSV-style message queues
+options 	SYSVSEM			# SYSV-style semaphores
+options 	_KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time extensions
+options 	MUTEX_NOINLINE
+options 	RWLOCK_NOINLINE
+options 	NO_FFS_SNAPSHOT
+options 	NO_SWAPPING
+
+# Debugging
+options 	ALT_BREAK_TO_DEBUGGER
+options 	DDB
+options 	KDB
+options 	GDB			# Support remote GDB.
+
+device		mvs
+device		pci
+
+# Pseudo devices
+device		md
+device		loop
+device		random
+
+# Serial ports
+device		uart
+
+# Networking
+device		ether
+device		mge			# Marvell Gigabit Ethernet controller
+device		mii
+device		e1000phy
+device		bpf
+options 	HZ=1000
+
+# USB
+device		usb
+device		ehci
+device		umass
+device		scbus
+device		pass
+device		da
+
+# SATA
+device		ata
+
+# Flattened Device Tree
+options 	FDT
+options 	FDT_DTB_STATIC
+makeoptions	FDT_DTS_FILE=ts7800.dts
+


Property changes on: trunk/sys/arm/conf/TS7800
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/VERSATILEPB
===================================================================
--- trunk/sys/arm/conf/VERSATILEPB	                        (rev 0)
+++ trunk/sys/arm/conf/VERSATILEPB	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,123 @@
+#
+# VERSATILEPB - Configuration for QEMU version of Versatile Platform 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: stable/10/sys/arm/conf/VERSATILEPB 283368 2015-05-24 14:25:03Z ian $
+
+ident		VERSATILEPB
+machine		arm	armv6
+cpu 		CPU_ARM1176
+
+files		"../versatile/files.versatile"
+makeoptions	MODULES_OVERRIDE=""
+
+options 	KERNVIRTADDR=0xc0100000
+makeoptions	KERNVIRTADDR=0xc0100000
+options 	KERNPHYSADDR=0x00100000
+makeoptions	KERNPHYSADDR=0x00100000
+options 	PHYSADDR=0x00000000
+
+options 	HZ=100
+options 	SCHED_4BSD		# 4BSD scheduler
+options 	PREEMPTION		# Enable kernel thread preemption
+options 	INET			# InterNETworking
+options 	INET6			# IPv6 communications protocols
+options 	SCTP			# Stream Control Transmission Protocol
+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
+options 	UFS_GJOURNAL		# Enable gjournal-based UFS journaling
+options 	QUOTA			# Enable disk quotas for UFS
+options 	NFSCL			# New Network Filesystem Client
+options 	NFSLOCKD		# Network Lock Manager
+options 	NFS_ROOT		# NFS usable as /, requires NFSCL
+options 	MSDOSFS			# MSDOS Filesystem
+options 	CD9660			# ISO 9660 Filesystem
+options 	PROCFS			# Process filesystem (requires PSEUDOFS)
+options 	PSEUDOFS		# Pseudo-filesystem framework
+options 	TMPFS			# Efficient memory filesystem
+options 	GEOM_PART_GPT		# GUID Partition Tables
+options 	GEOM_PART_BSD		# BSD partition scheme
+options 	GEOM_PART_MBR		# MBR partition scheme
+options 	COMPAT_43		# Compatible with BSD 4.3 [KEEP THIS!]
+options 	SCSI_DELAY=5000		# Delay (in ms) before probing SCSI
+options 	KTRACE			# ktrace(1) support
+options 	SYSVSHM			# SYSV-style shared memory
+options 	SYSVMSG			# SYSV-style message queues
+options 	SYSVSEM			# SYSV-style semaphores
+options 	_KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
+options 	KBD_INSTALL_CDEV	# install a CDEV entry in /dev
+options 	FREEBSD_BOOT_LOADER	# Process metadata passed from loader(8)
+options 	LINUX_BOOT_ABI		# Process metadata passed from Linux boot loaders
+options 	VFP			# Enable floating point hardware support
+
+# Debugging for use in -current
+makeoptions	DEBUG=-g		# Build kernel with gdb(1) debug symbols
+options 	KDB			# Enable kernel debugger support
+# For minimum debugger support (stable branch) use:
+#options 	KDB_TRACE		# Print a stack trace for a panic
+# For full debugger support use this instead:
+options 	DDB			# Enable the kernel debugger
+options 	INVARIANTS		# Enable calls of extra sanity checking
+options 	INVARIANT_SUPPORT	# Extra sanity checks of internal structures, required by INVARIANTS
+
+options 	ROOTDEVNAME=\"ufs:da0s1a\"
+
+device		bpf
+device		loop
+device		mii
+device		mii_bitbang
+device		smc
+device		smcphy
+device		ether
+device		uart
+device		pl011
+device		pl190
+
+device		pty
+device		snp
+
+device		pci
+
+# SCSI Controllers
+device		sym			# NCR/Symbios/LSI Logic 53C8XX/53C1010/53C1510D
+
+# ATA/SCSI peripherals
+device		scbus			# SCSI bus (required for ATA/SCSI)
+device		da			# Direct Access (disks)
+device		pass			# Passthrough device (direct ATA/SCSI access)
+
+# NOTE: serial console is disabled if syscons enabled
+# Comment following lines for headless setup
+device		sc
+device		kbdmux
+options 	SC_DFLT_FONT    	# compile font in
+makeoptions	SC_DFLT_FONT=cp437
+
+options 	KDB
+options 	DDB			# Enable the kernel debugger
+#options 	INVARIANTS		# Enable calls of extra sanity checking
+#options 	INVARIANT_SUPPORT	# Extra sanity checks of internal structures, required by INVARIANTS
+
+device		md
+device		random			# Entropy device
+
+# Flattened Device Tree
+options 	FDT			# Configure using FDT/DTB data
+options 	FDT_DTB_STATIC
+makeoptions	FDT_DTS_FILE=versatilepb.dts


Property changes on: trunk/sys/arm/conf/VERSATILEPB
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/VYBRID
===================================================================
--- trunk/sys/arm/conf/VYBRID	                        (rev 0)
+++ trunk/sys/arm/conf/VYBRID	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,154 @@
+#
+# Kernel configuration for Vybrid Family boards.
+#
+# 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: stable/10/sys/arm/conf/VYBRID 287082 2015-08-23 20:50:22Z ian $
+
+ident		VYBRID
+include		"../freescale/vybrid/std.vybrid"
+
+makeoptions	WERROR="-Werror"
+
+options 	HZ=100
+options 	SCHED_4BSD		# 4BSD scheduler
+options 	PREEMPTION		# Enable kernel thread preemption
+options 	INET			# InterNETworking
+options 	INET6			# IPv6 communications protocols
+options 	SCTP			# Stream Control Transmission Protocol
+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
+options 	UFS_GJOURNAL		# Enable gjournal-based UFS journaling
+options 	QUOTA			# Enable disk quotas for UFS
+options 	NFSCL			# New Network Filesystem Client
+options 	NFSLOCKD		# Network Lock Manager
+options 	NFS_ROOT		# NFS usable as /, requires NFSCL
+options 	MSDOSFS			# MSDOS Filesystem
+options 	CD9660			# ISO 9660 Filesystem
+#options 	NANDFS			# NAND Filesystem
+options 	PROCFS			# Process filesystem (requires PSEUDOFS)
+options 	PSEUDOFS		# Pseudo-filesystem framework
+options 	TMPFS			# Efficient memory filesystem
+options 	GEOM_PART_GPT		# GUID Partition Tables
+options 	GEOM_PART_BSD		# BSD partition scheme
+options 	GEOM_PART_MBR		# MBR partition scheme
+options 	COMPAT_43		# Compatible with BSD 4.3 [KEEP THIS!]
+options 	SCSI_DELAY=5000		# Delay (in ms) before probing SCSI
+options 	KTRACE			# ktrace(1) support
+options 	SYSVSHM			# SYSV-style shared memory
+options 	SYSVMSG			# SYSV-style message queues
+options 	SYSVSEM			# SYSV-style semaphores
+options 	_KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
+options 	KBD_INSTALL_CDEV	# install a CDEV entry in /dev
+options 	FREEBSD_BOOT_LOADER	# Process metadata passed from loader(8)
+options 	VFP			# Enable floating point hardware support
+#options 	SMP			# Enable multiple cores
+
+# Debugging for use in -current
+makeoptions	DEBUG=-g		# Build kernel with gdb(1) debug symbols
+options 	ALT_BREAK_TO_DEBUGGER
+#options 	VERBOSE_SYSINIT		# Enable verbose sysinit messages
+options 	KDB			# Enable kernel debugger support
+# For minimum debugger support (stable branch) use:
+#options 	KDB_TRACE		# Print a stack trace for a panic
+# For full debugger support use this instead:
+options 	DDB			# Enable the kernel debugger
+#options 	INVARIANTS		# Enable calls of extra sanity checking
+#options 	INVARIANT_SUPPORT	# Extra sanity checks of internal structures, required by INVARIANTS
+#options 	WITNESS			# Enable checks to detect deadlocks and cycles
+#options 	WITNESS_SKIPSPIN	# Don't run witness on spinlocks for speed
+#options 	DIAGNOSTIC
+
+# NFS root from boopt/dhcp
+#options 	BOOTP
+#options 	BOOTP_NFSROOT
+#options 	BOOTP_COMPAT
+#options 	BOOTP_NFSV3
+#options 	BOOTP_WIRED_TO=ffec0
+
+#options 	ROOTDEVNAME=\"nfs:10.5.0.1:/tftpboot/cosmic\"
+#options 	ROOTDEVNAME=\"nandfs:/dev/gnand0s.root\"
+options 	ROOTDEVNAME=\"ufs:/dev/da0\"
+
+options 	MUTEX_NOINLINE
+options 	RWLOCK_NOINLINE
+options 	NO_FFS_SNAPSHOT
+options 	NO_SWAPPING
+
+# MMC/SD/SDIO Card slot support
+device		mmc			# mmc/sd bus
+device		mmcsd			# mmc/sd flash cards
+device		sdhci			# generic sdhci
+
+# Pseudo devices
+
+device		loop
+device		random
+device		pty
+device		md
+device		gpio
+
+# USB support
+options 	USB_HOST_ALIGN=32	# Align usb buffers to cache line size.
+device		usb
+options 	USB_DEBUG
+#options 	USB_REQ_DEBUG
+#options 	USB_VERBOSE
+#device		musb
+device		ehci
+#device		ohci
+
+device		umass
+device		scbus			# SCSI bus (required for ATA/SCSI)
+device		da			# Direct Access (disks)
+device		pass
+
+# SATA
+#device		ata
+#device		atadisk
+#device		mvs
+
+device		nand
+
+# Serial ports
+device		uart
+
+# I2C (TWSI)
+device		iic
+device		iicbus
+
+# Ethernet
+device		ether
+device		ffec
+
+# USB ethernet support, requires miibus
+device		miibus
+device		axe			# ASIX Electronics USB Ethernet
+device		bpf			# Berkeley packet filter
+
+device		sound
+
+# Framebuffer
+device		vt
+device		kbdmux
+options 	SC_DFLT_FONT		# compile font in
+makeoptions	SC_DFLT_FONT=cp437
+device		ukbd
+
+# Flattened Device Tree
+options 	FDT			# Configure using FDT/DTB data


Property changes on: trunk/sys/arm/conf/VYBRID
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/ZEDBOARD
===================================================================
--- trunk/sys/arm/conf/ZEDBOARD	                        (rev 0)
+++ trunk/sys/arm/conf/ZEDBOARD	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,114 @@
+#
+# ZEDBOARD -- Custom configuration for the Xilinx Zynq-7000 based
+#             ZedBoard (www.zedboard.org)
+#
+# 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: stable/10/sys/arm/conf/ZEDBOARD 287082 2015-08-23 20:50:22Z ian $
+
+ident		ZEDBOARD
+
+include 	"../xilinx/zedboard/std.zedboard"
+
+options 	SCHED_ULE		# ULE scheduler
+options 	PREEMPTION		# Enable kernel thread preemption
+options 	INET			# InterNETworking
+options 	INET6			# IPv6 communications protocols
+options 	SCTP			# Stream Control Transmission Protocol
+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
+options 	UFS_GJOURNAL		# Enable gjournal-based UFS journaling
+options 	QUOTA			# Enable disk quotas for UFS
+options 	NFSCL			# New Network Filesystem Client
+#options 	NFSSD			# Network Filesystem Server
+options 	NFSLOCKD		# Network Lock Manager
+options 	NFS_ROOT		# NFS usable as /, requires NFSCL
+options 	MSDOSFS			# MSDOS Filesystem
+options 	CD9660			# ISO 9660 Filesystem
+options 	PROCFS			# Process filesystem (requires PSEUDOFS)
+options 	PSEUDOFS		# Pseudo-filesystem framework
+options 	TMPFS			# Efficient memory filesystem
+options 	GEOM_PART_GPT		# GUID Partition Tables
+options 	GEOM_PART_BSD		# BSD partition scheme
+options 	GEOM_PART_MBR		# MBR partition scheme
+options 	SCSI_DELAY=5000		# Delay (in ms) before probing SCSI
+options 	KTRACE			# ktrace(1) support
+options 	SYSVSHM			# SYSV-style shared memory
+options 	SYSVMSG			# SYSV-style message queues
+options 	SYSVSEM			# SYSV-style semaphores
+options 	_KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
+options 	KBD_INSTALL_CDEV	# install a CDEV entry in /dev
+options 	FREEBSD_BOOT_LOADER	# Process metadata passed from loader(8)
+options 	VFP			# Enable floating point hardware support
+options 	SMP			# Enable multiple cores
+
+# Debugging for use in -current
+makeoptions	DEBUG=-g		# Build kernel with gdb(1) debug symbols
+options 	ALT_BREAK_TO_DEBUGGER
+options 	KDB			# Enable kernel debugger support
+# For minimum debugger support (stable branch) use:
+#options 	KDB_TRACE		# Print a stack trace for a panic
+# For full debugger support use this instead:
+options 	DDB			# Enable the kernel debugger
+#options 	INVARIANTS		# Enable calls of extra sanity checking
+#options 	INVARIANT_SUPPORT	# Extra sanity checks of internal structures, required by INVARIANTS
+#options 	WITNESS			# Enable checks to detect deadlocks and cycles
+#options 	WITNESS_SKIPSPIN	# Don't run witness on spinlocks for speed
+#options 	DIAGNOSTIC
+
+# NFS root from boopt/dhcp
+#options 	BOOTP
+#options 	BOOTP_NFSROOT
+#options 	BOOTP_COMPAT
+#options 	BOOTP_NFSV3
+
+options 	ROOTDEVNAME=\"ufs:mmcsd0s2a\"
+
+device		loop
+device		random
+device		ether
+device		cgem			# Zynq-7000 gig ethernet device
+device		mii
+device		e1000phy
+device		pty
+device		uart
+device		gpio
+
+device		md
+device		mmc			# mmc/sd bus
+device		mmcsd			# mmc/sd flash cards
+device		sdhci			# generic sdhci
+device		bpf			# Berkeley packet filter
+
+# USB support
+device		usb
+options 	USB_DEBUG
+#options 	USB_REQ_DEBUG
+#options 	USB_VERBOSE
+device		ehci
+device		umass
+device		scbus			# SCSI bus (required for ATA/SCSI)
+device		da			# Direct Access (disks)
+device		axe			# USB-Ethernet
+
+
+# Flattened Device Tree
+options 	FDT			# Configure using FDT/DTB data
+#options 	FDT_DTB_STATIC
+#makeoptions	FDT_DTS_FILE=zedboard.dts
+


Property changes on: trunk/sys/arm/conf/ZEDBOARD
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/conf/genboardid.awk
===================================================================
--- trunk/sys/arm/conf/genboardid.awk	                        (rev 0)
+++ trunk/sys/arm/conf/genboardid.awk	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,55 @@
+#!/bin/awk
+# $FreeBSD: stable/10/sys/arm/conf/genboardid.awk 235234 2012-05-10 18:06:00Z imp $
+
+#-
+# Copyright (c) 2012 M. Warner Losh.  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.
+#
+
+#
+# Generate FreeBSD's board ID's defines from Linux's
+# arm board list.
+#
+# You can grab a new copy any time with:
+# fetch -o sys/arm/conf/mach-types http://www.arm.linux.org.uk/developer/machines/download.php
+#
+BEGIN	{ nr = 0; boardid[nr] = "ARM_BOARD_ID_NONE"; num[nr++] = 0; }
+/^#/	{ next; }
+/^[     ]*$/ { next; }
+
+NF == 4 {
+    boardid[nr] = "ARM_BOARD_ID_"$3;
+    num[nr] = $4;
+    nr++
+}
+
+END	{
+    printf("/* Arm board ID file generated automatically from Linux's mach-types file. */\n\n");
+    printf("#ifndef _SYS_ARM_ARM_BOARDID_H\n");
+    printf("#define _SYS_ARM_ARM_BOARDID_H\n\n");
+    for (i = 0; i < nr; i++) {
+        printf("#define %-30s %d\n", boardid[i], num[i]);
+    }
+    printf("\n#endif /* _SYS_ARM_ARM_BOARDID_H */\n");
+}
+


Property changes on: trunk/sys/arm/conf/genboardid.awk
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/conf/mach-types
===================================================================
--- trunk/sys/arm/conf/mach-types	                        (rev 0)
+++ trunk/sys/arm/conf/mach-types	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,4146 @@
+# Database of machine macros and numbers
+#
+# This file is linux/arch/arm/tools/mach-types
+#
+# Up to date versions of this file can be obtained from:
+#
+#   http://www.arm.linux.org.uk/developer/machines/download.php
+#
+# Please do not send patches to this file; it is automatically generated!
+# To add an entry into this database, please see Documentation/arm/README,
+# or visit:
+#
+#   http://www.arm.linux.org.uk/developer/machines/?action=new
+#
+# Last update: Thu May 10 18:35:23 2012
+#
+# machine_is_xxx	CONFIG_xxxx		MACH_TYPE_xxx		number
+#
+ebsa110			ARCH_EBSA110		EBSA110			0
+riscpc			ARCH_RPC		RISCPC			1
+nexuspci		ARCH_NEXUSPCI		NEXUSPCI		3
+ebsa285			ARCH_EBSA285		EBSA285			4
+netwinder		ARCH_NETWINDER		NETWINDER		5
+cats			ARCH_CATS		CATS			6
+tbox			ARCH_TBOX		TBOX			7
+co285			ARCH_CO285		CO285			8
+clps7110		ARCH_CLPS7110		CLPS7110		9
+archimedes		ARCH_ARC		ARCHIMEDES		10
+a5k			ARCH_A5K		A5K			11
+etoile			ARCH_ETOILE		ETOILE			12
+lacie_nas		ARCH_LACIE_NAS		LACIE_NAS		13
+clps7500		ARCH_CLPS7500		CLPS7500		14
+shark			ARCH_SHARK		SHARK			15
+brutus			SA1100_BRUTUS		BRUTUS			16
+personal_server		ARCH_PERSONAL_SERVER	PERSONAL_SERVER		17
+itsy			SA1100_ITSY		ITSY			18
+l7200			ARCH_L7200		L7200			19
+pleb			SA1100_PLEB		PLEB			20
+integrator		ARCH_INTEGRATOR		INTEGRATOR		21
+h3600			SA1100_H3600		H3600			22
+ixp1200			ARCH_IXP1200		IXP1200			23
+p720t			ARCH_P720T		P720T			24
+assabet			SA1100_ASSABET		ASSABET			25
+victor			SA1100_VICTOR		VICTOR			26
+lart			SA1100_LART		LART			27
+ranger			SA1100_RANGER		RANGER			28
+graphicsclient		SA1100_GRAPHICSCLIENT	GRAPHICSCLIENT		29
+xp860			SA1100_XP860		XP860			30
+cerf			SA1100_CERF		CERF			31
+nanoengine		SA1100_NANOENGINE	NANOENGINE		32
+fpic			SA1100_FPIC		FPIC			33
+extenex1		SA1100_EXTENEX1		EXTENEX1		34
+sherman			SA1100_SHERMAN		SHERMAN			35
+accelent_sa		SA1100_ACCELENT		ACCELENT_SA		36
+accelent_l7200		ARCH_L7200_ACCELENT	ACCELENT_L7200		37
+netport			SA1100_NETPORT		NETPORT			38
+pangolin		SA1100_PANGOLIN		PANGOLIN		39
+yopy			SA1100_YOPY		YOPY			40
+coolidge		SA1100_COOLIDGE		COOLIDGE		41
+huw_webpanel		SA1100_HUW_WEBPANEL	HUW_WEBPANEL		42
+spotme			ARCH_SPOTME		SPOTME			43
+freebird		ARCH_FREEBIRD		FREEBIRD		44
+ti925			ARCH_TI925		TI925			45
+riscstation		ARCH_RISCSTATION	RISCSTATION		46
+cavy			SA1100_CAVY		CAVY			47
+jornada720		SA1100_JORNADA720	JORNADA720		48
+omnimeter		SA1100_OMNIMETER	OMNIMETER		49
+edb7211			ARCH_EDB7211		EDB7211			50
+citygo			SA1100_CITYGO		CITYGO			51
+pfs168			SA1100_PFS168		PFS168			52
+spot			SA1100_SPOT		SPOT			53
+flexanet		SA1100_FLEXANET		FLEXANET		54
+webpal			ARCH_WEBPAL		WEBPAL			55
+linpda			SA1100_LINPDA		LINPDA			56
+anakin			ARCH_ANAKIN		ANAKIN			57
+mvi			SA1100_MVI		MVI			58
+jupiter			SA1100_JUPITER		JUPITER			59
+psionw			ARCH_PSIONW		PSIONW			60
+aln			SA1100_ALN		ALN			61
+epxa			ARCH_CAMELOT		CAMELOT			62
+gds2200			SA1100_GDS2200		GDS2200			63
+netbook			SA1100_PSION_SERIES7	PSION_SERIES7		64
+xfile			SA1100_XFILE		XFILE			65
+accelent_ep9312		ARCH_ACCELENT_EP9312	ACCELENT_EP9312		66
+ic200			ARCH_IC200		IC200			67
+creditlart		SA1100_CREDITLART	CREDITLART		68
+htm			SA1100_HTM		HTM			69
+iq80310			ARCH_IQ80310		IQ80310			70
+freebot			SA1100_FREEBOT		FREEBOT			71
+entel			ARCH_ENTEL		ENTEL			72
+enp3510			ARCH_ENP3510		ENP3510			73
+trizeps			SA1100_TRIZEPS		TRIZEPS			74
+nesa			SA1100_NESA		NESA			75
+venus			ARCH_VENUS		VENUS			76
+tardis			ARCH_TARDIS		TARDIS			77
+mercury			ARCH_MERCURY		MERCURY			78
+empeg			SA1100_EMPEG		EMPEG			79
+adi_evb			ARCH_I80200FCC		I80200FCC		80
+itt_cpb			SA1100_ITT_CPB		ITT_CPB			81
+svc			SA1100_SVC		SVC			82
+alpha2			SA1100_ALPHA2		ALPHA2			84
+alpha1			SA1100_ALPHA1		ALPHA1			85
+netarm			ARCH_NETARM		NETARM			86
+simpad			SA1100_SIMPAD		SIMPAD			87
+pda1			ARCH_PDA1		PDA1			88
+lubbock			ARCH_LUBBOCK		LUBBOCK			89
+aniko			ARCH_ANIKO		ANIKO			90
+clep7212		ARCH_CLEP7212		CLEP7212		91
+cs89712			ARCH_CS89712		CS89712			92
+weararm			SA1100_WEARARM		WEARARM			93
+possio_px		SA1100_POSSIO_PX	POSSIO_PX		94
+sidearm			SA1100_SIDEARM		SIDEARM			95
+stork			SA1100_STORK		STORK			96
+shannon			SA1100_SHANNON		SHANNON			97
+ace			ARCH_ACE		ACE			98
+ballyarm		SA1100_BALLYARM		BALLYARM		99
+simputer		SA1100_SIMPUTER		SIMPUTER		100
+nexterm			SA1100_NEXTERM		NEXTERM			101
+sa1100_elf		SA1100_SA1100_ELF	SA1100_ELF		102
+gator			SA1100_GATOR		GATOR			103
+granite			ARCH_GRANITE		GRANITE			104
+consus			SA1100_CONSUS		CONSUS			105
+aaed2000		ARCH_AAED2000		AAED2000		106
+cdb89712		ARCH_CDB89712		CDB89712		107
+graphicsmaster		SA1100_GRAPHICSMASTER	GRAPHICSMASTER		108
+adsbitsy		SA1100_ADSBITSY		ADSBITSY		109
+pxa_idp			ARCH_PXA_IDP		PXA_IDP			110
+plce			ARCH_PLCE		PLCE			111
+pt_system3		SA1100_PT_SYSTEM3	PT_SYSTEM3		112
+murphy			ARCH_MEDALB		MEDALB			113
+eagle			ARCH_EAGLE		EAGLE			114
+dsc21			ARCH_DSC21		DSC21			115
+dsc24			ARCH_DSC24		DSC24			116
+ti5472			ARCH_TI5472		TI5472			117
+autcpu12		ARCH_AUTCPU12		AUTCPU12		118
+uengine			ARCH_UENGINE		UENGINE			119
+bluestem		SA1100_BLUESTEM		BLUESTEM		120
+xingu8			ARCH_XINGU8		XINGU8			121
+bushstb			ARCH_BUSHSTB		BUSHSTB			122
+epsilon1		SA1100_EPSILON1		EPSILON1		123
+balloon			SA1100_BALLOON		BALLOON			124
+puppy			ARCH_PUPPY		PUPPY			125
+elroy			SA1100_ELROY		ELROY			126
+gms720			ARCH_GMS720		GMS720			127
+s24x			ARCH_S24X		S24X			128
+jtel_clep7312		ARCH_JTEL_CLEP7312	JTEL_CLEP7312		129
+cx821xx			ARCH_CX821XX		CX821XX			130
+edb7312			ARCH_EDB7312		EDB7312			131
+bsa1110			SA1100_BSA1110		BSA1110			132
+powerpin		ARCH_POWERPIN		POWERPIN		133
+openarm			ARCH_OPENARM		OPENARM			134
+whitechapel		SA1100_WHITECHAPEL	WHITECHAPEL		135
+h3100			SA1100_H3100		H3100			136
+h3800			SA1100_H3800		H3800			137
+blue_v1			ARCH_BLUE_V1		BLUE_V1			138
+pxa_cerf		ARCH_PXA_CERF		PXA_CERF		139
+arm7tevb		ARCH_ARM7TEVB		ARM7TEVB		140
+d7400			SA1100_D7400		D7400			141
+piranha			ARCH_PIRANHA		PIRANHA			142
+sbcamelot		SA1100_SBCAMELOT	SBCAMELOT		143
+kings			SA1100_KINGS		KINGS			144
+smdk2400		ARCH_SMDK2400		SMDK2400		145
+collie			SA1100_COLLIE		COLLIE			146
+idr			ARCH_IDR		IDR			147
+badge4			SA1100_BADGE4		BADGE4			148
+webnet			ARCH_WEBNET		WEBNET			149
+d7300			SA1100_D7300		D7300			150
+cep			SA1100_CEP		CEP			151
+fortunet		ARCH_FORTUNET		FORTUNET		152
+vc547x			ARCH_VC547X		VC547X			153
+filewalker		SA1100_FILEWALKER	FILEWALKER		154
+netgateway		SA1100_NETGATEWAY	NETGATEWAY		155
+symbol2800		SA1100_SYMBOL2800	SYMBOL2800		156
+suns			SA1100_SUNS		SUNS			157
+frodo			SA1100_FRODO		FRODO			158
+ms301			SA1100_MACH_TYTE_MS301	MACH_TYTE_MS301		159
+mx1ads			ARCH_MX1ADS		MX1ADS			160
+h7201			ARCH_H7201		H7201			161
+h7202			ARCH_H7202		H7202			162
+amico			ARCH_AMICO		AMICO			163
+iam			SA1100_IAM		IAM			164
+tt530			SA1100_TT530		TT530			165
+sam2400			ARCH_SAM2400		SAM2400			166
+jornada56x		SA1100_JORNADA56X	JORNADA56X		167
+active			SA1100_ACTIVE		ACTIVE			168
+iq80321			ARCH_IQ80321		IQ80321			169
+wid			SA1100_WID		WID			170
+sabinal			ARCH_SABINAL		SABINAL			171
+ixp425_matacumbe	ARCH_IXP425_MATACUMBE	IXP425_MATACUMBE	172
+miniprint		SA1100_MINIPRINT	MINIPRINT		173
+adm510x			ARCH_ADM510X		ADM510X			174
+svs200			SA1100_SVS200		SVS200			175
+atg_tcu			ARCH_ATG_TCU		ATG_TCU			176
+jornada820		SA1100_JORNADA820	JORNADA820		177
+s3c44b0			ARCH_S3C44B0		S3C44B0			178
+margis2			ARCH_MARGIS2		MARGIS2			179
+ks8695			ARCH_KS8695		KS8695			180
+brh			ARCH_BRH		BRH			181
+s3c2410			ARCH_S3C2410		S3C2410			182
+possio_px30		ARCH_POSSIO_PX30	POSSIO_PX30		183
+s3c2800			ARCH_S3C2800		S3C2800			184
+fleetwood		SA1100_FLEETWOOD	FLEETWOOD		185
+omaha			ARCH_OMAHA		OMAHA			186
+ta7			ARCH_TA7		TA7			187
+nova			SA1100_NOVA		NOVA			188
+hmk			ARCH_HMK		HMK			189
+karo			ARCH_KARO		KARO			190
+fester			SA1100_FESTER		FESTER			191
+gpi			ARCH_GPI		GPI			192
+smdk2410		ARCH_SMDK2410		SMDK2410		193
+i519			ARCH_I519		I519			194
+nexio			SA1100_NEXIO		NEXIO			195
+bitbox			SA1100_BITBOX		BITBOX			196
+g200			SA1100_G200		G200			197
+gill			SA1100_GILL		GILL			198
+pxa_mercury		ARCH_PXA_MERCURY	PXA_MERCURY		199
+ceiva			ARCH_CEIVA		CEIVA			200
+fret			SA1100_FRET		FRET			201
+emailphone		SA1100_EMAILPHONE	EMAILPHONE		202
+h3900			ARCH_H3900		H3900			203
+pxa1			ARCH_PXA1		PXA1			204
+koan369			SA1100_KOAN369		KOAN369			205
+cogent			ARCH_COGENT		COGENT			206
+esl_simputer		ARCH_ESL_SIMPUTER	ESL_SIMPUTER		207
+esl_simputer_clr	ARCH_ESL_SIMPUTER_CLR	ESL_SIMPUTER_CLR	208
+esl_simputer_bw		ARCH_ESL_SIMPUTER_BW	ESL_SIMPUTER_BW		209
+hhp_cradle		ARCH_HHP_CRADLE		HHP_CRADLE		210
+he500			ARCH_HE500		HE500			211
+inhandelf2		SA1100_INHANDELF2	INHANDELF2		212
+inhandftip		SA1100_INHANDFTIP	INHANDFTIP		213
+dnp1110			SA1100_DNP1110		DNP1110			214
+pnp1110			SA1100_PNP1110		PNP1110			215
+csb226			ARCH_CSB226		CSB226			216
+arnold			SA1100_ARNOLD		ARNOLD			217
+voiceblue		MACH_VOICEBLUE		VOICEBLUE		218
+jz8028			ARCH_JZ8028		JZ8028			219
+h5400			ARCH_H5400		H5400			220
+forte			SA1100_FORTE		FORTE			221
+acam			SA1100_ACAM		ACAM			222
+abox			SA1100_ABOX		ABOX			223
+atmel			ARCH_ATMEL		ATMEL			224
+sitsang			ARCH_SITSANG		SITSANG			225
+cpu1110lcdnet		SA1100_CPU1110LCDNET	CPU1110LCDNET		226
+mpl_vcma9		ARCH_MPL_VCMA9		MPL_VCMA9		227
+opus_a1			ARCH_OPUS_A1		OPUS_A1			228
+daytona			ARCH_DAYTONA		DAYTONA			229
+killbear		SA1100_KILLBEAR		KILLBEAR		230
+yoho			ARCH_YOHO		YOHO			231
+jasper			ARCH_JASPER		JASPER			232
+dsc25			ARCH_DSC25		DSC25			233
+omap_innovator		MACH_OMAP_INNOVATOR	OMAP_INNOVATOR		234
+mnci			ARCH_RAMSES		RAMSES			235
+s28x			ARCH_S28X		S28X			236
+mport3			ARCH_MPORT3		MPORT3			237
+pxa_eagle250		ARCH_PXA_EAGLE250	PXA_EAGLE250		238
+pdb			ARCH_PDB		PDB			239
+blue_2g			SA1100_BLUE_2G		BLUE_2G			240
+bluearch		SA1100_BLUEARCH		BLUEARCH		241
+ixdp2400		ARCH_IXDP2400		IXDP2400		242
+ixdp2800		ARCH_IXDP2800		IXDP2800		243
+explorer		SA1100_EXPLORER		EXPLORER		244
+ixdp425			ARCH_IXDP425		IXDP425			245
+chimp			ARCH_CHIMP		CHIMP			246
+stork_nest		ARCH_STORK_NEST		STORK_NEST		247
+stork_egg		ARCH_STORK_EGG		STORK_EGG		248
+wismo			SA1100_WISMO		WISMO			249
+ezlinx			ARCH_EZLINX		EZLINX			250
+at91rm9200		ARCH_AT91RM9200		AT91RM9200		251
+adtech_orion		ARCH_ADTECH_ORION	ADTECH_ORION		252
+neptune			ARCH_NEPTUNE		NEPTUNE			253
+hackkit			SA1100_HACKKIT		HACKKIT			254
+pxa_wins30		ARCH_PXA_WINS30		PXA_WINS30		255
+lavinna			SA1100_LAVINNA		LAVINNA			256
+pxa_uengine		ARCH_PXA_UENGINE	PXA_UENGINE		257
+innokom			ARCH_INNOKOM		INNOKOM			258
+bms			ARCH_BMS		BMS			259
+ixcdp1100		ARCH_IXCDP1100		IXCDP1100		260
+prpmc1100		ARCH_PRPMC1100		PRPMC1100		261
+at91rm9200dk		ARCH_AT91RM9200DK	AT91RM9200DK		262
+armstick		ARCH_ARMSTICK		ARMSTICK		263
+armonie			ARCH_ARMONIE		ARMONIE			264
+mport1			ARCH_MPORT1		MPORT1			265
+s3c5410			ARCH_S3C5410		S3C5410			266
+zcp320a			ARCH_ZCP320A		ZCP320A			267
+i_box			ARCH_I_BOX		I_BOX			268
+stlc1502		ARCH_STLC1502		STLC1502		269
+siren			ARCH_SIREN		SIREN			270
+greenlake		ARCH_GREENLAKE		GREENLAKE		271
+argus			ARCH_ARGUS		ARGUS			272
+combadge		SA1100_COMBADGE		COMBADGE		273
+rokepxa			ARCH_ROKEPXA		ROKEPXA			274
+cintegrator		ARCH_CINTEGRATOR	CINTEGRATOR		275
+guidea07		ARCH_GUIDEA07		GUIDEA07		276
+tat257			ARCH_TAT257		TAT257			277
+igp2425			ARCH_IGP2425		IGP2425			278
+bluegrama		ARCH_BLUEGRAMMA		BLUEGRAMMA		279
+ipod			ARCH_IPOD		IPOD			280
+adsbitsyx		ARCH_ADSBITSYX		ADSBITSYX		281
+trizeps2		ARCH_TRIZEPS2		TRIZEPS2		282
+viper			ARCH_VIPER		VIPER			283
+adsbitsyplus		SA1100_ADSBITSYPLUS	ADSBITSYPLUS		284
+adsagc			SA1100_ADSAGC		ADSAGC			285
+stp7312			ARCH_STP7312		STP7312			286
+nx_phnx			MACH_NX_PHNX		NX_PHNX			287
+wep_ep250		ARCH_WEP_EP250		WEP_EP250		288
+inhandelf3		ARCH_INHANDELF3		INHANDELF3		289
+adi_coyote		ARCH_ADI_COYOTE		ADI_COYOTE		290
+iyonix			ARCH_IYONIX		IYONIX			291
+damicam1		ARCH_DAMICAM_SA1110	DAMICAM_SA1110		292
+meg03			ARCH_MEG03		MEG03			293
+pxa_whitechapel		ARCH_PXA_WHITECHAPEL	PXA_WHITECHAPEL		294
+nwsc			ARCH_NWSC		NWSC			295
+nwlarm			ARCH_NWLARM		NWLARM			296
+ixp425_mguard		ARCH_IXP425_MGUARD	IXP425_MGUARD		297
+pxa_netdcu4		ARCH_PXA_NETDCU4	PXA_NETDCU4		298
+ixdp2401		ARCH_IXDP2401		IXDP2401		299
+ixdp2801		ARCH_IXDP2801		IXDP2801		300
+zodiac			ARCH_ZODIAC		ZODIAC			301
+armmodul		ARCH_ARMMODUL		ARMMODUL		302
+ketop			SA1100_KETOP		KETOP			303
+av7200			ARCH_AV7200		AV7200			304
+arch_ti925		ARCH_ARCH_TI925		ARCH_TI925		305
+acq200			ARCH_ACQ200		ACQ200			306
+pt_dafit		SA1100_PT_DAFIT		PT_DAFIT		307
+ihba			ARCH_IHBA		IHBA			308
+quinque			ARCH_QUINQUE		QUINQUE			309
+nimbraone		ARCH_NIMBRAONE		NIMBRAONE		310
+nimbra29x		ARCH_NIMBRA29X		NIMBRA29X		311
+nimbra210		ARCH_NIMBRA210		NIMBRA210		312
+hhp_d95xx		ARCH_HHP_D95XX		HHP_D95XX		313
+labarm			ARCH_LABARM		LABARM			314
+m825xx			ARCH_M825XX		M825XX			315
+m7100			SA1100_M7100		M7100			316
+nipc2			ARCH_NIPC2		NIPC2			317
+fu7202			ARCH_FU7202		FU7202			318
+adsagx			ARCH_ADSAGX		ADSAGX			319
+pxa_pooh		ARCH_PXA_POOH		PXA_POOH		320
+bandon			ARCH_BANDON		BANDON			321
+pcm7210			ARCH_PCM7210		PCM7210			322
+nms9200			ARCH_NMS9200		NMS9200			323
+logodl			ARCH_LOGODL		LOGODL			324
+m7140			SA1100_M7140		M7140			325
+korebot			ARCH_KOREBOT		KOREBOT			326
+iq31244			ARCH_IQ31244		IQ31244			327
+koan393			SA1100_KOAN393		KOAN393			328
+inhandftip3		ARCH_INHANDFTIP3	INHANDFTIP3		329
+gonzo			ARCH_GONZO		GONZO			330
+bast			ARCH_BAST		BAST			331
+scanpass		ARCH_SCANPASS		SCANPASS		332
+ep7312_pooh		ARCH_EP7312_POOH	EP7312_POOH		333
+ta7s			ARCH_TA7S		TA7S			334
+ta7v			ARCH_TA7V		TA7V			335
+icarus			SA1100_ICARUS		ICARUS			336
+h1900			ARCH_H1900		H1900			337
+gemini			SA1100_GEMINI		GEMINI			338
+axim			ARCH_AXIM		AXIM			339
+audiotron		ARCH_AUDIOTRON		AUDIOTRON		340
+h2200			ARCH_H2200		H2200			341
+loox600			ARCH_LOOX600		LOOX600			342
+niop			ARCH_NIOP		NIOP			343
+dm310			ARCH_DM310		DM310			344
+seedpxa_c2		ARCH_SEEDPXA_C2		SEEDPXA_C2		345
+ixp4xx_mguardpci	ARCH_IXP4XX_MGUARD_PCI	IXP4XX_MGUARD_PCI	346
+h1940			ARCH_H1940		H1940			347
+scorpio			ARCH_SCORPIO		SCORPIO			348
+viva			ARCH_VIVA		VIVA			349
+pxa_xcard		ARCH_PXA_XCARD		PXA_XCARD		350
+csb335			ARCH_CSB335		CSB335			351
+ixrd425			ARCH_IXRD425		IXRD425			352
+iq80315			ARCH_IQ80315		IQ80315			353
+nmp7312			ARCH_NMP7312		NMP7312			354
+cx861xx			ARCH_CX861XX		CX861XX			355
+enp2611			ARCH_ENP2611		ENP2611			356
+xda			SA1100_XDA		XDA			357
+csir_ims		ARCH_CSIR_IMS		CSIR_IMS		358
+ixp421_dnaeeth		ARCH_IXP421_DNAEETH	IXP421_DNAEETH		359
+pocketserv9200		ARCH_POCKETSERV9200	POCKETSERV9200		360
+toto			ARCH_TOTO		TOTO			361
+s3c2440			ARCH_S3C2440		S3C2440			362
+ks8695p			ARCH_KS8695P		KS8695P			363
+se4000			ARCH_SE4000		SE4000			364
+quadriceps		ARCH_QUADRICEPS		QUADRICEPS		365
+bronco			ARCH_BRONCO		BRONCO			366
+esl_wireless_tab	ARCH_ESL_WIRELESS_TAB	ESL_WIRELESS_TAB	367
+esl_sofcomp		ARCH_ESL_SOFCOMP	ESL_SOFCOMP		368
+s5c7375			ARCH_S5C7375		S5C7375			369
+spearhead		ARCH_SPEARHEAD		SPEARHEAD		370
+pantera			ARCH_PANTERA		PANTERA			371
+prayoglite		ARCH_PRAYOGLITE		PRAYOGLITE		372
+gumstix			ARCH_GUMSTIX		GUMSTIX			373
+rcube			ARCH_RCUBE		RCUBE			374
+rea_olv			ARCH_REA_OLV		REA_OLV			375
+pxa_iphone		ARCH_PXA_IPHONE		PXA_IPHONE		376
+s3c3410			ARCH_S3C3410		S3C3410			377
+espd_4510b		ARCH_ESPD_4510B		ESPD_4510B		378
+mp1x			ARCH_MP1X		MP1X			379
+at91rm9200tb		ARCH_AT91RM9200TB	AT91RM9200TB		380
+adsvgx			ARCH_ADSVGX		ADSVGX			381
+omap_h2			MACH_OMAP_H2		OMAP_H2			382
+pelee			ARCH_PELEE		PELEE			383
+e740			MACH_E740		E740			384
+iq80331			ARCH_IQ80331		IQ80331			385
+versatile_pb		ARCH_VERSATILE_PB	VERSATILE_PB		387
+kev7a400		MACH_KEV7A400		KEV7A400		388
+lpd7a400		MACH_LPD7A400		LPD7A400		389
+lpd7a404		MACH_LPD7A404		LPD7A404		390
+fujitsu_camelot		ARCH_FUJITSU_CAMELOT	FUJITSU_CAMELOT		391
+janus2m			ARCH_JANUS2M		JANUS2M			392
+embtf			MACH_EMBTF		EMBTF			393
+hpm			MACH_HPM		HPM			394
+smdk2410tk		MACH_SMDK2410TK		SMDK2410TK		395
+smdk2410aj		MACH_SMDK2410AJ		SMDK2410AJ		396
+streetracer		MACH_STREETRACER	STREETRACER		397
+eframe			MACH_EFRAME		EFRAME			398
+csb337			MACH_CSB337		CSB337			399
+pxa_lark		MACH_PXA_LARK		PXA_LARK		400
+pxa_pnp2110		MACH_PNP2110		PNP2110			401
+tcc72x			MACH_TCC72X		TCC72X			402
+altair			MACH_ALTAIR		ALTAIR			403
+kc3			MACH_KC3		KC3			404
+sinteftd		MACH_SINTEFTD		SINTEFTD		405
+mainstone		MACH_MAINSTONE		MAINSTONE		406
+aday4x			MACH_ADAY4X		ADAY4X			407
+lite300			MACH_LITE300		LITE300			408
+s5c7376			MACH_S5C7376		S5C7376			409
+mt02			MACH_MT02		MT02			410
+mport3s			MACH_MPORT3S		MPORT3S			411
+ra_alpha		MACH_RA_ALPHA		RA_ALPHA		412
+xcep			MACH_XCEP		XCEP			413
+arcom_vulcan		MACH_ARCOM_VULCAN	ARCOM_VULCAN		414
+stargate		MACH_STARGATE		STARGATE		415
+armadilloj		MACH_ARMADILLOJ		ARMADILLOJ		416
+elroy_jack		MACH_ELROY_JACK		ELROY_JACK		417
+backend			MACH_BACKEND		BACKEND			418
+s5linbox		MACH_S5LINBOX		S5LINBOX		419
+nomadik			MACH_NOMADIK		NOMADIK			420
+ia_cpu_9200		MACH_IA_CPU_9200	IA_CPU_9200		421
+at91_bja1		MACH_AT91_BJA1		AT91_BJA1		422
+corgi			MACH_CORGI		CORGI			423
+poodle			MACH_POODLE		POODLE			424
+ten			MACH_TEN		TEN			425
+roverp5p		MACH_ROVERP5P		ROVERP5P		426
+sc2700			MACH_SC2700		SC2700			427
+ex_eagle		MACH_EX_EAGLE		EX_EAGLE		428
+nx_pxa12		MACH_NX_PXA12		NX_PXA12		429
+nx_pxa5			MACH_NX_PXA5		NX_PXA5			430
+blackboard2		MACH_BLACKBOARD2	BLACKBOARD2		431
+i819			MACH_I819		I819			432
+ixmb995e		MACH_IXMB995E		IXMB995E		433
+skyrider		MACH_SKYRIDER		SKYRIDER		434
+skyhawk			MACH_SKYHAWK		SKYHAWK			435
+enterprise		MACH_ENTERPRISE		ENTERPRISE		436
+dep2410			MACH_DEP2410		DEP2410			437
+armcore			MACH_ARMCORE		ARMCORE			438
+hobbit			MACH_HOBBIT		HOBBIT			439
+h7210			MACH_H7210		H7210			440
+pxa_netdcu5		MACH_PXA_NETDCU5	PXA_NETDCU5		441
+acc			MACH_ACC		ACC			442
+esl_sarva		MACH_ESL_SARVA		ESL_SARVA		443
+xm250			MACH_XM250		XM250			444
+t6tc1xb			MACH_T6TC1XB		T6TC1XB			445
+ess710			MACH_ESS710		ESS710			446
+mx31ads			MACH_MX31ADS		MX31ADS			447
+himalaya		MACH_HIMALAYA		HIMALAYA		448
+bolfenk			MACH_BOLFENK		BOLFENK			449
+at91rm9200kr		MACH_AT91RM9200KR	AT91RM9200KR		450
+edb9312			MACH_EDB9312		EDB9312			451
+omap_generic		MACH_OMAP_GENERIC	OMAP_GENERIC		452
+aximx3			MACH_AXIMX3		AXIMX3			453
+eb67xdip		MACH_EB67XDIP		EB67XDIP		454
+webtxs			MACH_WEBTXS		WEBTXS			455
+hawk			MACH_HAWK		HAWK			456
+ccat91sbc001		MACH_CCAT91SBC001	CCAT91SBC001		457
+expresso		MACH_EXPRESSO		EXPRESSO		458
+h4000			MACH_H4000		H4000			459
+dino			MACH_DINO		DINO			460
+ml675k			MACH_ML675K		ML675K			461
+edb9301			MACH_EDB9301		EDB9301			462
+edb9315			MACH_EDB9315		EDB9315			463
+reciva_tt		MACH_RECIVA_TT		RECIVA_TT		464
+cstcb01			MACH_CSTCB01		CSTCB01			465
+cstcb1			MACH_CSTCB1		CSTCB1			466
+shadwell		MACH_SHADWELL		SHADWELL		467
+goepel263		MACH_GOEPEL263		GOEPEL263		468
+acq100			MACH_ACQ100		ACQ100			469
+mx1fs2			MACH_MX1FS2		MX1FS2			470
+hiptop_g1		MACH_HIPTOP_G1		HIPTOP_G1		471
+sparky			MACH_SPARKY		SPARKY			472
+ns9750			MACH_NS9750		NS9750			473
+phoenix			MACH_PHOENIX		PHOENIX			474
+vr1000			MACH_VR1000		VR1000			475
+deisterpxa		MACH_DEISTERPXA		DEISTERPXA		476
+bcm1160			MACH_BCM1160		BCM1160			477
+pcm022			MACH_PCM022		PCM022			478
+adsgcx			MACH_ADSGCX		ADSGCX			479
+dreadnaught		MACH_DREADNAUGHT	DREADNAUGHT		480
+dm320			MACH_DM320		DM320			481
+markov			MACH_MARKOV		MARKOV			482
+cos7a400		MACH_COS7A400		COS7A400		483
+milano			MACH_MILANO		MILANO			484
+ue9328			MACH_UE9328		UE9328			485
+uex255			MACH_UEX255		UEX255			486
+ue2410			MACH_UE2410		UE2410			487
+a620			MACH_A620		A620			488
+ocelot			MACH_OCELOT		OCELOT			489
+cheetah			MACH_CHEETAH		CHEETAH			490
+omap_perseus2		MACH_OMAP_PERSEUS2	OMAP_PERSEUS2		491
+zvue			MACH_ZVUE		ZVUE			492
+roverp1			MACH_ROVERP1		ROVERP1			493
+asidial2		MACH_ASIDIAL2		ASIDIAL2		494
+s3c24a0			MACH_S3C24A0		S3C24A0			495
+e800			MACH_E800		E800			496
+e750			MACH_E750		E750			497
+s3c5500			MACH_S3C5500		S3C5500			498
+smdk5500		MACH_SMDK5500		SMDK5500		499
+signalsync		MACH_SIGNALSYNC		SIGNALSYNC		500
+nbc			MACH_NBC		NBC			501
+kodiak			MACH_KODIAK		KODIAK			502
+netbookpro		MACH_NETBOOKPRO		NETBOOKPRO		503
+hw90200			MACH_HW90200		HW90200			504
+condor			MACH_CONDOR		CONDOR			505
+cup			MACH_CUP		CUP			506
+kite			MACH_KITE		KITE			507
+scb9328			MACH_SCB9328		SCB9328			508
+omap_h3			MACH_OMAP_H3		OMAP_H3			509
+omap_h4			MACH_OMAP_H4		OMAP_H4			510
+n10			MACH_N10		N10			511
+montejade		MACH_MONTAJADE		MONTAJADE		512
+sg560			MACH_SG560		SG560			513
+dp1000			MACH_DP1000		DP1000			514
+omap_osk		MACH_OMAP_OSK		OMAP_OSK		515
+rg100v3			MACH_RG100V3		RG100V3			516
+mx2ads			MACH_MX2ADS		MX2ADS			517
+pxa_kilo		MACH_PXA_KILO		PXA_KILO		518
+ixp4xx_eagle		MACH_IXP4XX_EAGLE	IXP4XX_EAGLE		519
+tosa			MACH_TOSA		TOSA			520
+mb2520f			MACH_MB2520F		MB2520F			521
+emc1000			MACH_EMC1000		EMC1000			522
+tidsc25			MACH_TIDSC25		TIDSC25			523
+akcpmxl			MACH_AKCPMXL		AKCPMXL			524
+av3xx			MACH_AV3XX		AV3XX			525
+avila			MACH_AVILA		AVILA			526
+pxa_mpm10		MACH_PXA_MPM10		PXA_MPM10		527
+pxa_kyanite		MACH_PXA_KYANITE	PXA_KYANITE		528
+sgold			MACH_SGOLD		SGOLD			529
+oscar			MACH_OSCAR		OSCAR			530
+epxa4usb2		MACH_EPXA4USB2		EPXA4USB2		531
+xsengine		MACH_XSENGINE		XSENGINE		532
+ip600			MACH_IP600		IP600			533
+mcan2			MACH_MCAN2		MCAN2			534
+ddi_blueridge		MACH_DDI_BLUERIDGE	DDI_BLUERIDGE		535
+skyminder		MACH_SKYMINDER		SKYMINDER		536
+lpd79520		MACH_LPD79520		LPD79520		537
+edb9302			MACH_EDB9302		EDB9302			538
+hw90340			MACH_HW90340		HW90340			539
+cip_box			MACH_CIP_BOX		CIP_BOX			540
+ivpn			MACH_IVPN		IVPN			541
+rsoc2			MACH_RSOC2		RSOC2			542
+husky			MACH_HUSKY		HUSKY			543
+boxer			MACH_BOXER		BOXER			544
+shepherd		MACH_SHEPHERD		SHEPHERD		545
+aml42800aa		MACH_AML42800AA		AML42800AA		546
+lpc2294			MACH_LPC2294		LPC2294			548
+switchgrass		MACH_SWITCHGRASS	SWITCHGRASS		549
+ens_cmu			MACH_ENS_CMU		ENS_CMU			550
+mm6_sdb			MACH_MM6_SDB		MM6_SDB			551
+saturn			MACH_SATURN		SATURN			552
+i30030evb		MACH_I30030EVB		I30030EVB		553
+mxc27530evb		MACH_MXC27530EVB	MXC27530EVB		554
+smdk2800		MACH_SMDK2800		SMDK2800		555
+mtwilson		MACH_MTWILSON		MTWILSON		556
+ziti			MACH_ZITI		ZITI			557
+grandfather		MACH_GRANDFATHER	GRANDFATHER		558
+tengine			MACH_TENGINE		TENGINE			559
+s3c2460			MACH_S3C2460		S3C2460			560
+pdm			MACH_PDM		PDM			561
+h4700			MACH_H4700		H4700			562
+h6300			MACH_H6300		H6300			563
+rz1700			MACH_RZ1700		RZ1700			564
+a716			MACH_A716		A716			565
+estk2440a		MACH_ESTK2440A		ESTK2440A		566
+atwixp425		MACH_ATWIXP425		ATWIXP425		567
+csb336			MACH_CSB336		CSB336			568
+rirm2			MACH_RIRM2		RIRM2			569
+cx23518			MACH_CX23518		CX23518			570
+cx2351x			MACH_CX2351X		CX2351X			571
+computime		MACH_COMPUTIME		COMPUTIME		572
+izarus			MACH_IZARUS		IZARUS			573
+pxa_rts			MACH_RTS		RTS			574
+se5100			MACH_SE5100		SE5100			575
+s3c2510			MACH_S3C2510		S3C2510			576
+csb437tl		MACH_CSB437TL		CSB437TL		577
+slauson			MACH_SLAUSON		SLAUSON			578
+pearlriver		MACH_PEARLRIVER		PEARLRIVER		579
+tdc_p210		MACH_TDC_P210		TDC_P210		580
+sg580			MACH_SG580		SG580			581
+wrsbcarm7		MACH_WRSBCARM7		WRSBCARM7		582
+ipd			MACH_IPD		IPD			583
+pxa_dnp2110		MACH_PXA_DNP2110	PXA_DNP2110		584
+xaeniax			MACH_XAENIAX		XAENIAX			585
+somn4250		MACH_SOMN4250		SOMN4250		586
+pleb2			MACH_PLEB2		PLEB2			587
+cornwallis		MACH_CORNWALLIS		CORNWALLIS		588
+gurney_drv		MACH_GURNEY_DRV		GURNEY_DRV		589
+chaffee			MACH_CHAFFEE		CHAFFEE			590
+rms101			MACH_RMS101		RMS101			591
+rx3715			MACH_RX3715		RX3715			592
+swift			MACH_SWIFT		SWIFT			593
+roverp7			MACH_ROVERP7		ROVERP7			594
+pr818s			MACH_PR818S		PR818S			595
+trxpro			MACH_TRXPRO		TRXPRO			596
+nslu2			MACH_NSLU2		NSLU2			597
+e400			MACH_E400		E400			598
+trab			MACH_TRAB		TRAB			599
+cmc_pu2			MACH_CMC_PU2		CMC_PU2			600
+fulcrum			MACH_FULCRUM		FULCRUM			601
+netgate42x		MACH_NETGATE42X		NETGATE42X		602
+str710			MACH_STR710		STR710			603
+ixdpg425		MACH_IXDPG425		IXDPG425		604
+tomtomgo		MACH_TOMTOMGO		TOMTOMGO		605
+versatile_ab		MACH_VERSATILE_AB	VERSATILE_AB		606
+edb9307			MACH_EDB9307		EDB9307			607
+sg565			MACH_SG565		SG565			608
+lpd79524		MACH_LPD79524		LPD79524		609
+lpd79525		MACH_LPD79525		LPD79525		610
+rms100			MACH_RMS100		RMS100			611
+kb9200			MACH_KB9200		KB9200			612
+sx1			MACH_SX1		SX1			613
+hms39c7092		MACH_HMS39C7092		HMS39C7092		614
+armadillo		MACH_ARMADILLO		ARMADILLO		615
+ipcu			MACH_IPCU		IPCU			616
+loox720			MACH_LOOX720		LOOX720			617
+ixdp465			MACH_IXDP465		IXDP465			618
+ixdp2351		MACH_IXDP2351		IXDP2351		619
+adsvix			MACH_ADSVIX		ADSVIX			620
+dm270			MACH_DM270		DM270			621
+socltplus		MACH_SOCLTPLUS		SOCLTPLUS		622
+ecia			MACH_ECIA		ECIA			623
+cm4008			MACH_CM4008		CM4008			624
+p2001			MACH_P2001		P2001			625
+twister			MACH_TWISTER		TWISTER			626
+mudshark		MACH_MUDSHARK		MUDSHARK		627
+hb2			MACH_HB2		HB2			628
+iq80332			MACH_IQ80332		IQ80332			629
+sendt			MACH_SENDT		SENDT			630
+mx2jazz			MACH_MX2JAZZ		MX2JAZZ			631
+multiio			MACH_MULTIIO		MULTIIO			632
+hrdisplay		MACH_HRDISPLAY		HRDISPLAY		633
+mxc27530ads		MACH_MXC27530ADS	MXC27530ADS		634
+trizeps3		MACH_TRIZEPS3		TRIZEPS3		635
+zefeerdza		MACH_ZEFEERDZA		ZEFEERDZA		636
+zefeerdzb		MACH_ZEFEERDZB		ZEFEERDZB		637
+zefeerdzg		MACH_ZEFEERDZG		ZEFEERDZG		638
+zefeerdzn		MACH_ZEFEERDZN		ZEFEERDZN		639
+zefeerdzq		MACH_ZEFEERDZQ		ZEFEERDZQ		640
+gtwx5715		MACH_GTWX5715		GTWX5715		641
+astro_jack		MACH_ASTRO_JACK		ASTRO_JACK		643
+tip03			MACH_TIP03		TIP03			644
+a9200ec			MACH_A9200EC		A9200EC			645
+pnx0105			MACH_PNX0105		PNX0105			646
+adcpoecpu		MACH_ADCPOECPU		ADCPOECPU		647
+csb637			MACH_CSB637		CSB637			648
+mb9200			MACH_MB9200		MB9200			650
+kulun			MACH_KULUN		KULUN			651
+snapper			MACH_SNAPPER		SNAPPER			652
+optima			MACH_OPTIMA		OPTIMA			653
+dlhsbc			MACH_DLHSBC		DLHSBC			654
+x30			MACH_X30		X30			655
+n30			MACH_N30		N30			656
+manga_ks8695		MACH_MANGA_KS8695	MANGA_KS8695		657
+ajax			MACH_AJAX		AJAX			658
+nec_mp900		MACH_NEC_MP900		NEC_MP900		659
+vvtk1000		MACH_VVTK1000		VVTK1000		661
+kafa			MACH_KAFA		KAFA			662
+vvtk3000		MACH_VVTK3000		VVTK3000		663
+pimx1			MACH_PIMX1		PIMX1			664
+ollie			MACH_OLLIE		OLLIE			665
+skymax			MACH_SKYMAX		SKYMAX			666
+jazz			MACH_JAZZ		JAZZ			667
+tel_t3			MACH_TEL_T3		TEL_T3			668
+aisino_fcr255		MACH_AISINO_FCR255	AISINO_FCR255		669
+btweb			MACH_BTWEB		BTWEB			670
+dbg_lh79520		MACH_DBG_LH79520	DBG_LH79520		671
+cm41xx			MACH_CM41XX		CM41XX			672
+ts72xx			MACH_TS72XX		TS72XX			673
+nggpxa			MACH_NGGPXA		NGGPXA			674
+csb535			MACH_CSB535		CSB535			675
+csb536			MACH_CSB536		CSB536			676
+pxa_trakpod		MACH_PXA_TRAKPOD	PXA_TRAKPOD		677
+praxis			MACH_PRAXIS		PRAXIS			678
+lh75411			MACH_LH75411		LH75411			679
+otom			MACH_OTOM		OTOM			680
+nexcoder_2440		MACH_NEXCODER_2440	NEXCODER_2440		681
+loox410			MACH_LOOX410		LOOX410			682
+westlake		MACH_WESTLAKE		WESTLAKE		683
+nsb			MACH_NSB		NSB			684
+esl_sarva_stn		MACH_ESL_SARVA_STN	ESL_SARVA_STN		685
+esl_sarva_tft		MACH_ESL_SARVA_TFT	ESL_SARVA_TFT		686
+esl_sarva_iad		MACH_ESL_SARVA_IAD	ESL_SARVA_IAD		687
+esl_sarva_acc		MACH_ESL_SARVA_ACC	ESL_SARVA_ACC		688
+typhoon			MACH_TYPHOON		TYPHOON			689
+cnav			MACH_CNAV		CNAV			690
+a730			MACH_A730		A730			691
+netstar			MACH_NETSTAR		NETSTAR			692
+supercon		MACH_PHASEFALE_SUPERCON	PHASEFALE_SUPERCON	693
+shiva1100		MACH_SHIVA1100		SHIVA1100		694
+etexsc			MACH_ETEXSC		ETEXSC			695
+ixdpg465		MACH_IXDPG465		IXDPG465		696
+a9m2410			MACH_A9M2410		A9M2410			697
+a9m2440			MACH_A9M2440		A9M2440			698
+a9m9750			MACH_A9M9750		A9M9750			699
+a9m9360			MACH_A9M9360		A9M9360			700
+unc90			MACH_UNC90		UNC90			701
+eco920			MACH_ECO920		ECO920			702
+satview			MACH_SATVIEW		SATVIEW			703
+roadrunner		MACH_ROADRUNNER		ROADRUNNER		704
+at91rm9200ek		MACH_AT91RM9200EK	AT91RM9200EK		705
+gp32			MACH_GP32		GP32			706
+gem			MACH_GEM		GEM			707
+i858			MACH_I858		I858			708
+hx2750			MACH_HX2750		HX2750			709
+mxc91131evb		MACH_MXC91131EVB	MXC91131EVB		710
+p700			MACH_P700		P700			711
+cpe			MACH_CPE		CPE			712
+spitz			MACH_SPITZ		SPITZ			713
+nimbra340		MACH_NIMBRA340		NIMBRA340		714
+lpc22xx			MACH_LPC22XX		LPC22XX			715
+omap_comet3		MACH_COMET3		COMET3			716
+omap_comet4		MACH_COMET4		COMET4			717
+csb625			MACH_CSB625		CSB625			718
+fortunet2		MACH_FORTUNET2		FORTUNET2		719
+s5h2200			MACH_S5H2200		S5H2200			720
+optorm920		MACH_OPTORM920		OPTORM920		721
+adsbitsyxb		MACH_ADSBITSYXB		ADSBITSYXB		722
+adssphere		MACH_ADSSPHERE		ADSSPHERE		723
+adsportal		MACH_ADSPORTAL		ADSPORTAL		724
+ln2410sbc		MACH_LN2410SBC		LN2410SBC		725
+cb3rufc			MACH_CB3RUFC		CB3RUFC			726
+mp2usb			MACH_MP2USB		MP2USB			727
+ntnp425c		MACH_NTNP425C		NTNP425C		728
+colibri			MACH_COLIBRI		COLIBRI			729
+pcm7220			MACH_PCM7220		PCM7220			730
+gateway7001		MACH_GATEWAY7001	GATEWAY7001		731
+pcm027			MACH_PCM027		PCM027			732
+cmpxa			MACH_CMPXA		CMPXA			733
+anubis			MACH_ANUBIS		ANUBIS			734
+ite8152			MACH_ITE8152		ITE8152			735
+lpc3xxx			MACH_LPC3XXX		LPC3XXX			736
+puppeteer		MACH_PUPPETEER		PUPPETEER		737
+e570			MACH_E570		E570			739
+x50			MACH_X50		X50			740
+recon			MACH_RECON		RECON			741
+xboardgp8		MACH_XBOARDGP8		XBOARDGP8		742
+fpic2			MACH_FPIC2		FPIC2			743
+akita			MACH_AKITA		AKITA			744
+a81			MACH_A81		A81			745
+svm_sc25x		MACH_SVM_SC25X		SVM_SC25X		746
+vt020			MACH_VADATECH020	VADATECH020		747
+tli			MACH_TLI		TLI			748
+edb9315lc		MACH_EDB9315LC		EDB9315LC		749
+passec			MACH_PASSEC		PASSEC			750
+ds_tiger		MACH_DS_TIGER		DS_TIGER		751
+e310			MACH_E310		E310			752
+e330			MACH_E330		E330			753
+rt3000			MACH_RT3000		RT3000			754
+nokia770		MACH_NOKIA770		NOKIA770		755
+pnx0106			MACH_PNX0106		PNX0106			756
+hx21xx			MACH_HX21XX		HX21XX			757
+faraday			MACH_FARADAY		FARADAY			758
+sbc9312			MACH_SBC9312		SBC9312			759
+batman			MACH_BATMAN		BATMAN			760
+jpd201			MACH_JPD201		JPD201			761
+mipsa			MACH_MIPSA		MIPSA			762
+kacom			MACH_KACOM		KACOM			763
+swarcocpu		MACH_SWARCOCPU		SWARCOCPU		764
+swarcodsl		MACH_SWARCODSL		SWARCODSL		765
+blueangel		MACH_BLUEANGEL		BLUEANGEL		766
+hairygrama		MACH_HAIRYGRAMA		HAIRYGRAMA		767
+banff			MACH_BANFF		BANFF			768
+carmeva			MACH_CARMEVA		CARMEVA			769
+sam255			MACH_SAM255		SAM255			770
+ppm10			MACH_PPM10		PPM10			771
+edb9315a		MACH_EDB9315A		EDB9315A		772
+sunset			MACH_SUNSET		SUNSET			773
+stargate2		MACH_STARGATE2		STARGATE2		774
+intelmote2		MACH_INTELMOTE2		INTELMOTE2		775
+trizeps4		MACH_TRIZEPS4		TRIZEPS4		776
+mainstone2		MACH_MAINSTONE2		MAINSTONE2		777
+ez_ixp42x		MACH_EZ_IXP42X		EZ_IXP42X		778
+tapwave_zodiac		MACH_TAPWAVE_ZODIAC	TAPWAVE_ZODIAC		779
+universalmeter		MACH_UNIVERSALMETER	UNIVERSALMETER		780
+hicoarm9		MACH_HICOARM9		HICOARM9		781
+pnx4008			MACH_PNX4008		PNX4008			782
+kws6000			MACH_KWS6000		KWS6000			783
+portux920t		MACH_PORTUX920T		PORTUX920T		784
+ez_x5			MACH_EZ_X5		EZ_X5			785
+omap_rudolph		MACH_OMAP_RUDOLPH	OMAP_RUDOLPH		786
+cpuat91			MACH_CPUAT91		CPUAT91			787
+rea9200			MACH_REA9200		REA9200			788
+acts_pune_sa1110	MACH_ACTS_PUNE_SA1110	ACTS_PUNE_SA1110	789
+ixp425			MACH_IXP425		IXP425			790
+i30030ads		MACH_I30030ADS		I30030ADS		791
+perch			MACH_PERCH		PERCH			792
+eis05r1			MACH_EIS05R1		EIS05R1			793
+pepperpad		MACH_PEPPERPAD		PEPPERPAD		794
+sb3010			MACH_SB3010		SB3010			795
+rm9200			MACH_RM9200		RM9200			796
+dma03			MACH_DMA03		DMA03			797
+road_s101		MACH_ROAD_S101		ROAD_S101		798
+iq81340sc		MACH_IQ81340SC		IQ81340SC		799
+iq_nextgen_b		MACH_IQ_NEXTGEN_B	IQ_NEXTGEN_B		800
+iq81340mc		MACH_IQ81340MC		IQ81340MC		801
+iq_nextgen_d		MACH_IQ_NEXTGEN_D	IQ_NEXTGEN_D		802
+iq_nextgen_e		MACH_IQ_NEXTGEN_E	IQ_NEXTGEN_E		803
+mallow_at91		MACH_MALLOW_AT91	MALLOW_AT91		804
+cybertracker_i		MACH_CYBERTRACKER_I	CYBERTRACKER_I		805
+gesbc931x		MACH_GESBC931X		GESBC931X		806
+centipad		MACH_CENTIPAD		CENTIPAD		807
+armsoc			MACH_ARMSOC		ARMSOC			808
+se4200			MACH_SE4200		SE4200			809
+ems197a			MACH_EMS197A		EMS197A			810
+micro9			MACH_MICRO9		MICRO9			811
+micro9l			MACH_MICRO9L		MICRO9L			812
+uc5471dsp		MACH_UC5471DSP		UC5471DSP		813
+sj5471eng		MACH_SJ5471ENG		SJ5471ENG		814
+none			MACH_CMPXA26X		CMPXA26X		815
+nc1			MACH_NC			NC			816
+omap_palmte		MACH_OMAP_PALMTE	OMAP_PALMTE		817
+ajax52x			MACH_AJAX52X		AJAX52X			818
+siriustar		MACH_SIRIUSTAR		SIRIUSTAR		819
+iodata_hdlg		MACH_IODATA_HDLG	IODATA_HDLG		820
+at91rm9200utl		MACH_AT91RM9200UTL	AT91RM9200UTL		821
+biosafe			MACH_BIOSAFE		BIOSAFE			822
+mp1000			MACH_MP1000		MP1000			823
+parsy			MACH_PARSY		PARSY			824
+ccxp270			MACH_CCXP		CCXP			825
+omap_gsample		MACH_OMAP_GSAMPLE	OMAP_GSAMPLE		826
+realview_eb		MACH_REALVIEW_EB	REALVIEW_EB		827
+samoa			MACH_SAMOA		SAMOA			828
+palmt3			MACH_PALMT3		PALMT3			829
+i878			MACH_I878		I878			830
+borzoi			MACH_BORZOI		BORZOI			831
+gecko			MACH_GECKO		GECKO			832
+ds101			MACH_DS101		DS101			833
+omap_palmtt2		MACH_OMAP_PALMTT2	OMAP_PALMTT2		834
+palmld			MACH_PALMLD		PALMLD			835
+cc9c			MACH_CC9C		CC9C			836
+sbc1670			MACH_SBC1670		SBC1670			837
+ixdp28x5		MACH_IXDP28X5		IXDP28X5		838
+omap_palmtt		MACH_OMAP_PALMTT	OMAP_PALMTT		839
+ml696k			MACH_ML696K		ML696K			840
+arcom_zeus		MACH_ARCOM_ZEUS		ARCOM_ZEUS		841
+osiris			MACH_OSIRIS		OSIRIS			842
+maestro			MACH_MAESTRO		MAESTRO			843
+palmte2			MACH_PALMTE2		PALMTE2			844
+ixbbm			MACH_IXBBM		IXBBM			845
+mx27ads			MACH_MX27ADS		MX27ADS			846
+ax8004			MACH_AX8004		AX8004			847
+at91sam9261ek		MACH_AT91SAM9261EK	AT91SAM9261EK		848
+loft			MACH_LOFT		LOFT			849
+magpie			MACH_MAGPIE		MAGPIE			850
+mx21ads			MACH_MX21ADS		MX21ADS			851
+mb87m3400		MACH_MB87M3400		MB87M3400		852
+mguard_delta		MACH_MGUARD_DELTA	MGUARD_DELTA		853
+davinci_dvdp		MACH_DAVINCI_DVDP	DAVINCI_DVDP		854
+htcuniversal		MACH_HTCUNIVERSAL	HTCUNIVERSAL		855
+tpad			MACH_TPAD		TPAD			856
+roverp3			MACH_ROVERP3		ROVERP3			857
+jornada928		MACH_JORNADA928		JORNADA928		858
+mv88fxx81		MACH_MV88FXX81		MV88FXX81		859
+stmp36xx		MACH_STMP36XX		STMP36XX		860
+sxni79524		MACH_SXNI79524		SXNI79524		861
+ams_delta		MACH_AMS_DELTA		AMS_DELTA		862
+uranium			MACH_URANIUM		URANIUM			863
+ucon			MACH_UCON		UCON			864
+nas100d			MACH_NAS100D		NAS100D			865
+l083			MACH_L083_1000		L083_1000		866
+ezx			MACH_EZX		EZX			867
+pnx5220			MACH_PNX5220		PNX5220			868
+butte			MACH_BUTTE		BUTTE			869
+srm2			MACH_SRM2		SRM2			870
+dsbr			MACH_DSBR		DSBR			871
+crystalball		MACH_CRYSTALBALL	CRYSTALBALL		872
+tinypxa27x		MACH_TINYPXA27X		TINYPXA27X		873
+herbie			MACH_HERBIE		HERBIE			874
+magician		MACH_MAGICIAN		MAGICIAN		875
+cm4002			MACH_CM4002		CM4002			876
+b4			MACH_B4			B4			877
+maui			MACH_MAUI		MAUI			878
+cybertracker_g		MACH_CYBERTRACKER_G	CYBERTRACKER_G		879
+nxdkn			MACH_NXDKN		NXDKN			880
+mio8390			MACH_MIO8390		MIO8390			881
+omi_board		MACH_OMI_BOARD		OMI_BOARD		882
+mx21civ			MACH_MX21CIV		MX21CIV			883
+mahi_cdac		MACH_MAHI_CDAC		MAHI_CDAC		884
+palmtx			MACH_PALMTX		PALMTX			885
+s3c2413			MACH_S3C2413		S3C2413			887
+samsys_ep0		MACH_SAMSYS_EP0		SAMSYS_EP0		888
+wg302v1			MACH_WG302V1		WG302V1			889
+wg302v2			MACH_WG302V2		WG302V2			890
+eb42x			MACH_EB42X		EB42X			891
+iq331es			MACH_IQ331ES		IQ331ES			892
+cosydsp			MACH_COSYDSP		COSYDSP			893
+uplat7d_proto		MACH_UPLAT7D		UPLAT7D			894
+ptdavinci		MACH_PTDAVINCI		PTDAVINCI		895
+mbus			MACH_MBUS		MBUS			896
+nadia2vb		MACH_NADIA2VB		NADIA2VB		897
+r1000			MACH_R1000		R1000			898
+hw90250			MACH_HW90250		HW90250			899
+omap_2430sdp		MACH_OMAP_2430SDP	OMAP_2430SDP		900
+davinci_evm		MACH_DAVINCI_EVM	DAVINCI_EVM		901
+omap_tornado		MACH_OMAP_TORNADO	OMAP_TORNADO		902
+olocreek		MACH_OLOCREEK		OLOCREEK		903
+palmz72			MACH_PALMZ72		PALMZ72			904
+nxdb500			MACH_NXDB500		NXDB500			905
+apf9328			MACH_APF9328		APF9328			906
+omap_wipoq		MACH_OMAP_WIPOQ		OMAP_WIPOQ		907
+omap_twip		MACH_OMAP_TWIP		OMAP_TWIP		908
+treo650			MACH_TREO650		TREO650			909
+acumen			MACH_ACUMEN		ACUMEN			910
+xp100			MACH_XP100		XP100			911
+fs2410			MACH_FS2410		FS2410			912
+pxa270_cerf		MACH_PXA270_CERF	PXA270_CERF		913
+sq2ftlpalm		MACH_SQ2FTLPALM		SQ2FTLPALM		914
+bsemserver		MACH_BSEMSERVER		BSEMSERVER		915
+netclient		MACH_NETCLIENT		NETCLIENT		916
+palmt5			MACH_PALMT5		PALMT5			917
+palmtc			MACH_PALMTC		PALMTC			918
+omap_apollon		MACH_OMAP_APOLLON	OMAP_APOLLON		919
+mxc30030evb		MACH_MXC30030EVB	MXC30030EVB		920
+rea_cpu2		MACH_REA_2D		REA_2D			921
+eti3e524		MACH_TI3E524		TI3E524			922
+ateb9200		MACH_ATEB9200		ATEB9200		923
+auckland		MACH_AUCKLAND		AUCKLAND		924
+ak3220m			MACH_AK3320M		AK3320M			925
+duramax			MACH_DURAMAX		DURAMAX			926
+n35			MACH_N35		N35			927
+pronghorn		MACH_PRONGHORN		PRONGHORN		928
+fundy			MACH_FUNDY		FUNDY			929
+logicpd_pxa270		MACH_LOGICPD_PXA270	LOGICPD_PXA270		930
+cpu777			MACH_CPU777		CPU777			931
+simicon9201		MACH_SIMICON9201	SIMICON9201		932
+leap2_hpm		MACH_LEAP2_HPM		LEAP2_HPM		933
+cm922txa10		MACH_CM922TXA10		CM922TXA10		934
+sandgate		MACH_PXA		PXA			935
+sandgate2		MACH_SANDGATE2		SANDGATE2		936
+sandgate2g		MACH_SANDGATE2G		SANDGATE2G		937
+sandgate2p		MACH_SANDGATE2P		SANDGATE2P		938
+fred_jack		MACH_FRED_JACK		FRED_JACK		939
+ttg_color1		MACH_TTG_COLOR1		TTG_COLOR1		940
+nxeb500hmi		MACH_NXEB500HMI		NXEB500HMI		941
+netdcu8			MACH_NETDCU8		NETDCU8			942
+ng_fvx538		MACH_NG_FVX538		NG_FVX538		944
+ng_fvs338		MACH_NG_FVS338		NG_FVS338		945
+pnx4103			MACH_PNX4103		PNX4103			946
+hesdb			MACH_HESDB		HESDB			947
+xsilo			MACH_XSILO		XSILO			948
+espresso		MACH_ESPRESSO		ESPRESSO		949
+emlc			MACH_EMLC		EMLC			950
+sisteron		MACH_SISTERON		SISTERON		951
+rx1950			MACH_RX1950		RX1950			952
+tsc_venus		MACH_TSC_VENUS		TSC_VENUS		953
+ds101j			MACH_DS101J		DS101J			954
+mxc30030ads		MACH_MXC30030ADS	MXC30030ADS		955
+fujitsu_wimaxsoc	MACH_FUJITSU_WIMAXSOC	FUJITSU_WIMAXSOC	956
+dualpcmodem		MACH_DUALPCMODEM	DUALPCMODEM		957
+gesbc9312		MACH_GESBC9312		GESBC9312		958
+htcapache		MACH_HTCAPACHE		HTCAPACHE		959
+ixdp435			MACH_IXDP435		IXDP435			960
+catprovt100		MACH_CATPROVT100	CATPROVT100		961
+picotux1xx		MACH_PICOTUX1XX		PICOTUX1XX		962
+picotux2xx		MACH_PICOTUX2XX		PICOTUX2XX		963
+dsmg600			MACH_DSMG600		DSMG600			964
+empc2			MACH_EMPC2		EMPC2			965
+ventura			MACH_VENTURA		VENTURA			966
+phidget_sbc		MACH_PHIDGET_SBC	PHIDGET_SBC		967
+ij3k			MACH_IJ3K		IJ3K			968
+pisgah			MACH_PISGAH		PISGAH			969
+omap_fsample		MACH_OMAP_FSAMPLE	OMAP_FSAMPLE		970
+sg720			MACH_SG720		SG720			971
+redfox			MACH_REDFOX		REDFOX			972
+mysh_ep9315_1		MACH_MYSH_EP9315_1	MYSH_EP9315_1		973
+tpf106			MACH_TPF106		TPF106			974
+at91rm9200kg		MACH_AT91RM9200KG	AT91RM9200KG		975
+rcmt2			MACH_SLEDB		SLEDB			976
+ontrack			MACH_ONTRACK		ONTRACK			977
+pm1200			MACH_PM1200		PM1200			978
+ess24562		MACH_ESS24XXX		ESS24XXX		979
+coremp7			MACH_COREMP7		COREMP7			980
+nexcoder_6446		MACH_NEXCODER_6446	NEXCODER_6446		981
+stvc8380		MACH_STVC8380		STVC8380		982
+teklynx			MACH_TEKLYNX		TEKLYNX			983
+carbonado		MACH_CARBONADO		CARBONADO		984
+sysmos_mp730		MACH_SYSMOS_MP730	SYSMOS_MP730		985
+snapper_cl15		MACH_SNAPPER_CL15	SNAPPER_CL15		986
+pgigim			MACH_PGIGIM		PGIGIM			987
+ptx9160p2		MACH_PTX9160P2		PTX9160P2		988
+dcore1			MACH_DCORE1		DCORE1			989
+victorpxa		MACH_VICTORPXA		VICTORPXA		990
+mx2dtb			MACH_MX2DTB		MX2DTB			991
+pxa_irex_er0100		MACH_PXA_IREX_ER0100	PXA_IREX_ER0100		992
+omap_palmz71		MACH_OMAP_PALMZ71	OMAP_PALMZ71		993
+bartec_deg		MACH_BARTEC_DEG		BARTEC_DEG		994
+hw50251			MACH_HW50251		HW50251			995
+ibox			MACH_IBOX		IBOX			996
+atlaslh7a404		MACH_ATLASLH7A404	ATLASLH7A404		997
+pt2026			MACH_PT2026		PT2026			998
+htcalpine		MACH_HTCALPINE		HTCALPINE		999
+bartec_vtu		MACH_BARTEC_VTU		BARTEC_VTU		1000
+vcoreii			MACH_VCOREII		VCOREII			1001
+pdnb3			MACH_PDNB3		PDNB3			1002
+htcbeetles		MACH_HTCBEETLES		HTCBEETLES		1003
+s3c6400			MACH_S3C6400		S3C6400			1004
+s3c2443			MACH_S3C2443		S3C2443			1005
+omap_ldk		MACH_OMAP_LDK		OMAP_LDK		1006
+smdk2460		MACH_SMDK2460		SMDK2460		1007
+smdk2440		MACH_SMDK2440		SMDK2440		1008
+smdk2412		MACH_SMDK2412		SMDK2412		1009
+webbox			MACH_WEBBOX		WEBBOX			1010
+cwwndp			MACH_CWWNDP		CWWNDP			1011
+i839			MACH_DRAGON		DRAGON			1012
+opendo_cpu_board	MACH_OPENDO_CPU_BOARD	OPENDO_CPU_BOARD	1013
+ccm2200			MACH_CCM2200		CCM2200			1014
+etwarm			MACH_ETWARM		ETWARM			1015
+m93030			MACH_M93030		M93030			1016
+cc7u			MACH_CC7U		CC7U			1017
+mtt_ranger		MACH_MTT_RANGER		MTT_RANGER		1018
+nexus			MACH_NEXUS		NEXUS			1019
+desman			MACH_DESMAN		DESMAN			1020
+bkde303			MACH_BKDE303		BKDE303			1021
+smdk2413		MACH_SMDK2413		SMDK2413		1022
+aml_m7200		MACH_AML_M7200		AML_M7200		1023
+aml_m5900		MACH_AML_M5900		AML_M5900		1024
+sg640			MACH_SG640		SG640			1025
+edg79524		MACH_EDG79524		EDG79524		1026
+ai2410			MACH_AI2410		AI2410			1027
+ixp465			MACH_IXP465		IXP465			1028
+balloon3		MACH_BALLOON3		BALLOON3		1029
+heins			MACH_HEINS		HEINS			1030
+mpluseva		MACH_MPLUSEVA		MPLUSEVA		1031
+rt042			MACH_RT042		RT042			1032
+cwiem			MACH_CWIEM		CWIEM			1033
+cm_x270			MACH_CM_X270		CM_X270			1034
+cm_x255			MACH_CM_X255		CM_X255			1035
+esh_at91		MACH_ESH_AT91		ESH_AT91		1036
+sandgate3		MACH_SANDGATE3		SANDGATE3		1037
+primo			MACH_PRIMO		PRIMO			1038
+gemstone		MACH_GEMSTONE		GEMSTONE		1039
+pronghorn_metro		MACH_PRONGHORNMETRO	PRONGHORNMETRO		1040
+sidewinder		MACH_SIDEWINDER		SIDEWINDER		1041
+picomod1		MACH_PICOMOD1		PICOMOD1		1042
+sg590			MACH_SG590		SG590			1043
+akai9307		MACH_AKAI9307		AKAI9307		1044
+fontaine		MACH_FONTAINE		FONTAINE		1045
+wombat			MACH_WOMBAT		WOMBAT			1046
+acq300			MACH_ACQ300		ACQ300			1047
+mod272			MACH_MOD_270		MOD_270			1048
+vmc_vc0820		MACH_VC0820		VC0820			1049
+ani_aim			MACH_ANI_AIM		ANI_AIM			1050
+jellyfish		MACH_JELLYFISH		JELLYFISH		1051
+amanita			MACH_AMANITA		AMANITA			1052
+vlink			MACH_VLINK		VLINK			1053
+dexflex			MACH_DEXFLEX		DEXFLEX			1054
+eigen_ttq		MACH_EIGEN_TTQ		EIGEN_TTQ		1055
+arcom_titan		MACH_ARCOM_TITAN	ARCOM_TITAN		1056
+tabla			MACH_TABLA		TABLA			1057
+mdirac3			MACH_MDIRAC3		MDIRAC3			1058
+mrhfbp2			MACH_MRHFBP2		MRHFBP2			1059
+at91rm9200rb		MACH_AT91RM9200RB	AT91RM9200RB		1060
+ani_apm			MACH_ANI_APM		ANI_APM			1061
+ella1			MACH_ELLA1		ELLA1			1062
+inhand_pxa27x		MACH_INHAND_PXA27X	INHAND_PXA27X		1063
+inhand_pxa25x		MACH_INHAND_PXA25X	INHAND_PXA25X		1064
+empos_xm		MACH_EMPOS_XM		EMPOS_XM		1065
+empos			MACH_EMPOS		EMPOS			1066
+empos_tiny		MACH_EMPOS_TINY		EMPOS_TINY		1067
+empos_sm		MACH_EMPOS_SM		EMPOS_SM		1068
+egret			MACH_EGRET		EGRET			1069
+ostrich			MACH_OSTRICH		OSTRICH			1070
+n50			MACH_N50		N50			1071
+ecbat91			MACH_ECBAT91		ECBAT91			1072
+stareast		MACH_STAREAST		STAREAST		1073
+dspg_dw			MACH_DSPG_DW		DSPG_DW			1074
+onearm			MACH_ONEARM		ONEARM			1075
+mrg110_6		MACH_MRG110_6		MRG110_6		1076
+wrt300nv2		MACH_WRT300NV2		WRT300NV2		1077
+xm_bulverde		MACH_XM_BULVERDE	XM_BULVERDE		1078
+msm6100			MACH_MSM6100		MSM6100			1079
+eti_b1			MACH_ETI_B1		ETI_B1			1080
+za9l_series		MACH_ZILOG_ZA9L		ZILOG_ZA9L		1081
+bit2440			MACH_BIT2440		BIT2440			1082
+nbi			MACH_NBI		NBI			1083
+smdk2443		MACH_SMDK2443		SMDK2443		1084
+vdavinci		MACH_VDAVINCI		VDAVINCI		1085
+atc6			MACH_ATC6		ATC6			1086
+multmdw			MACH_MULTMDW		MULTMDW			1087
+mba2440			MACH_MBA2440		MBA2440			1088
+ecsd			MACH_ECSD		ECSD			1089
+palmz31			MACH_PALMZ31		PALMZ31			1090
+fsg			MACH_FSG		FSG			1091
+razor101		MACH_RAZOR101		RAZOR101		1092
+opera_tdm		MACH_OPERA_TDM		OPERA_TDM		1093
+comcerto		MACH_COMCERTO		COMCERTO		1094
+tb0319			MACH_TB0319		TB0319			1095
+kws8000			MACH_KWS8000		KWS8000			1096
+b2			MACH_B2			B2			1097
+lcl54			MACH_LCL54		LCL54			1098
+at91sam9260ek		MACH_AT91SAM9260EK	AT91SAM9260EK		1099
+glantank		MACH_GLANTANK		GLANTANK		1100
+n2100			MACH_N2100		N2100			1101
+n4100			MACH_N4100		N4100			1102
+rsc4			MACH_VERTICAL_RSC4	VERTICAL_RSC4		1103
+sg8100			MACH_SG8100		SG8100			1104
+im42xx			MACH_IM42XX		IM42XX			1105
+ftxx			MACH_FTXX		FTXX			1106
+lwfusion		MACH_LWFUSION		LWFUSION		1107
+qt2410			MACH_QT2410		QT2410			1108
+kixrp435		MACH_KIXRP435		KIXRP435		1109
+ccw9c			MACH_CCW9C		CCW9C			1110
+dabhs			MACH_DABHS		DABHS			1111
+gzmx			MACH_GZMX		GZMX			1112
+ipnw100ap		MACH_IPNW100AP		IPNW100AP		1113
+cc9p9360dev		MACH_CC9P9360DEV	CC9P9360DEV		1114
+cc9p9750dev		MACH_CC9P9750DEV	CC9P9750DEV		1115
+cc9p9360val		MACH_CC9P9360VAL	CC9P9360VAL		1116
+cc9p9750val		MACH_CC9P9750VAL	CC9P9750VAL		1117
+nx70v			MACH_NX70V		NX70V			1118
+at91rm9200df		MACH_AT91RM9200DF	AT91RM9200DF		1119
+se_pilot2		MACH_SE_PILOT2		SE_PILOT2		1120
+mtcn_t800		MACH_MTCN_T800		MTCN_T800		1121
+vcmx212			MACH_VCMX212		VCMX212			1122
+lynx			MACH_LYNX		LYNX			1123
+at91sam9260id		MACH_AT91SAM9260ID	AT91SAM9260ID		1124
+hw86052			MACH_HW86052		HW86052			1125
+pilz_pmi3		MACH_PILZ_PMI3		PILZ_PMI3		1126
+edb9302a		MACH_EDB9302A		EDB9302A		1127
+edb9307a		MACH_EDB9307A		EDB9307A		1128
+ct_dfs			MACH_CT_DFS		CT_DFS			1129
+pilz_pmi4		MACH_PILZ_PMI4		PILZ_PMI4		1130
+xceednp_ixp		MACH_XCEEDNP_IXP	XCEEDNP_IXP		1131
+smdk2442b		MACH_SMDK2442B		SMDK2442B		1132
+xnode			MACH_XNODE		XNODE			1133
+aidx270			MACH_AIDX270		AIDX270			1134
+rema			MACH_REMA		REMA			1135
+bps1000			MACH_BPS1000		BPS1000			1136
+hw90350			MACH_HW90350		HW90350			1137
+omap_3430sdp		MACH_OMAP_3430SDP	OMAP_3430SDP		1138
+bluetouch		MACH_BLUETOUCH		BLUETOUCH		1139
+vstms			MACH_VSTMS		VSTMS			1140
+xsbase270		MACH_XSBASE270		XSBASE270		1141
+at91sam9260ek_cn	MACH_AT91SAM9260EK_CN	AT91SAM9260EK_CN	1142
+adsturboxb		MACH_ADSTURBOXB		ADSTURBOXB		1143
+oti4110			MACH_OTI4110		OTI4110			1144
+hme_pxa			MACH_HME_PXA		HME_PXA			1145
+deisterdca		MACH_DEISTERDCA		DEISTERDCA		1146
+ces_ssem2		MACH_CES_SSEM2		CES_SSEM2		1147
+ces_mtr			MACH_CES_MTR		CES_MTR			1148
+tds_avng_sbc		MACH_TDS_AVNG_SBC	TDS_AVNG_SBC		1149
+everest			MACH_EVEREST		EVEREST			1150
+pnx4010			MACH_PNX4010		PNX4010			1151
+oxnas			MACH_OXNAS		OXNAS			1152
+fiori			MACH_FIORI		FIORI			1153
+ml1200			MACH_ML1200		ML1200			1154
+pecos			MACH_PECOS		PECOS			1155
+nb2xxx			MACH_NB2XXX		NB2XXX			1156
+hw6900			MACH_HW6900		HW6900			1157
+cdcs_quoll		MACH_CDCS_QUOLL		CDCS_QUOLL		1158
+quicksilver		MACH_QUICKSILVER	QUICKSILVER		1159
+uplat926		MACH_UPLAT926		UPLAT926		1160
+dep2410_dep2410		MACH_DEP2410_THOMAS	DEP2410_THOMAS		1161
+dtk2410			MACH_DTK2410		DTK2410			1162
+chili			MACH_CHILI		CHILI			1163
+demeter			MACH_DEMETER		DEMETER			1164
+dionysus		MACH_DIONYSUS		DIONYSUS		1165
+as352x			MACH_AS352X		AS352X			1166
+service			MACH_SERVICE		SERVICE			1167
+cs_e9301		MACH_CS_E9301		CS_E9301		1168
+micro9m			MACH_MICRO9M		MICRO9M			1169
+ia_mospck		MACH_IA_MOSPCK		IA_MOSPCK		1170
+ql201b			MACH_QL201B		QL201B			1171
+bbm			MACH_BBM		BBM			1174
+exxx			MACH_EXXX		EXXX			1175
+wma11b			MACH_WMA11B		WMA11B			1176
+pelco_atlas		MACH_PELCO_ATLAS	PELCO_ATLAS		1177
+g500			MACH_G500		G500			1178
+bug			MACH_BUG		BUG			1179
+mx33ads			MACH_MX33ADS		MX33ADS			1180
+chub			MACH_CHUB		CHUB			1181
+neo1973_gta01		MACH_NEO1973_GTA01	NEO1973_GTA01		1182
+w90n740			MACH_W90N740		W90N740			1183
+medallion_sa2410	MACH_MEDALLION_SA2410	MEDALLION_SA2410	1184
+ia_cpu_9200_2		MACH_IA_CPU_9200_2	IA_CPU_9200_2		1185
+dimmrm9200		MACH_DIMMRM9200		DIMMRM9200		1186
+pm9261			MACH_PM9261		PM9261			1187
+ml7304			MACH_ML7304		ML7304			1189
+ucp250			MACH_UCP250		UCP250			1190
+intboard		MACH_INTBOARD		INTBOARD		1191
+gulfstream		MACH_GULFSTREAM		GULFSTREAM		1192
+labquest		MACH_LABQUEST		LABQUEST		1193
+vcmx313			MACH_VCMX313		VCMX313			1194
+urg200			MACH_URG200		URG200			1195
+cpux255lcdnet		MACH_CPUX255LCDNET	CPUX255LCDNET		1196
+netdcu9			MACH_NETDCU9		NETDCU9			1197
+netdcu10		MACH_NETDCU10		NETDCU10		1198
+dspg_dga		MACH_DSPG_DGA		DSPG_DGA		1199
+dspg_dvw		MACH_DSPG_DVW		DSPG_DVW		1200
+solos			MACH_SOLOS		SOLOS			1201
+at91sam9263ek		MACH_AT91SAM9263EK	AT91SAM9263EK		1202
+osstbox			MACH_OSSTBOX		OSSTBOX			1203
+kbat9261		MACH_KBAT9261		KBAT9261		1204
+ct1100			MACH_CT1100		CT1100			1205
+akcppxa			MACH_AKCPPXA		AKCPPXA			1206
+ochaya1020		MACH_OCHAYA1020		OCHAYA1020		1207
+hitrack			MACH_HITRACK		HITRACK			1208
+syme1			MACH_SYME1		SYME1			1209
+syhl1			MACH_SYHL1		SYHL1			1210
+empca400		MACH_EMPCA400		EMPCA400		1211
+em7210			MACH_EM7210		EM7210			1212
+htchermes		MACH_HTCHERMES		HTCHERMES		1213
+eti_c1			MACH_ETI_C1		ETI_C1			1214
+ac100			MACH_AC100		AC100			1216
+sneetch			MACH_SNEETCH		SNEETCH			1217
+studentmate		MACH_STUDENTMATE	STUDENTMATE		1218
+zir2410			MACH_ZIR2410		ZIR2410			1219
+zir2413			MACH_ZIR2413		ZIR2413			1220
+dlonip3			MACH_DLONIP3		DLONIP3			1221
+instream		MACH_INSTREAM		INSTREAM		1222
+ambarella		MACH_AMBARELLA		AMBARELLA		1223
+nevis			MACH_NEVIS		NEVIS			1224
+htc_trinity		MACH_HTC_TRINITY	HTC_TRINITY		1225
+ql202b			MACH_QL202B		QL202B			1226
+vpac270			MACH_VPAC270		VPAC270			1227
+rd129			MACH_RD129		RD129			1228
+htcwizard		MACH_HTCWIZARD		HTCWIZARD		1229
+treo680			MACH_TREO680		TREO680			1230
+tecon_tmezon		MACH_TECON_TMEZON	TECON_TMEZON		1231
+zylonite		MACH_ZYLONITE		ZYLONITE		1233
+gene1270		MACH_GENE1270		GENE1270		1234
+zir2412			MACH_ZIR2412		ZIR2412			1235
+mx31lite		MACH_MX31LITE		MX31LITE		1236
+t700wx			MACH_T700WX		T700WX			1237
+vf100			MACH_VF100		VF100			1238
+nsb2			MACH_NSB2		NSB2			1239
+nxhmi_bb		MACH_NXHMI_BB		NXHMI_BB		1240
+nxhmi_re		MACH_NXHMI_RE		NXHMI_RE		1241
+n4100pro		MACH_N4100PRO		N4100PRO		1242
+sam9260			MACH_SAM9260		SAM9260			1243
+omap_treo600		MACH_OMAP_TREO600	OMAP_TREO600		1244
+indy2410		MACH_INDY2410		INDY2410		1245
+nelt_a			MACH_NELT_A		NELT_A			1246
+n311			MACH_N311		N311			1248
+at91sam9260vgk		MACH_AT91SAM9260VGK	AT91SAM9260VGK		1249
+at91leppe		MACH_AT91LEPPE		AT91LEPPE		1250
+at91lepccn		MACH_AT91LEPCCN		AT91LEPCCN		1251
+apc7100			MACH_APC7100		APC7100			1252
+stargazer		MACH_STARGAZER		STARGAZER		1253
+sonata			MACH_SONATA		SONATA			1254
+schmoogie		MACH_SCHMOOGIE		SCHMOOGIE		1255
+aztool			MACH_AZTOOL		AZTOOL			1256
+mioa701			MACH_MIOA701		MIOA701			1257
+sxni9260		MACH_SXNI9260		SXNI9260		1258
+mxc27520evb		MACH_MXC27520EVB	MXC27520EVB		1259
+armadillo5x0		MACH_ARMADILLO5X0	ARMADILLO5X0		1260
+mb9260			MACH_MB9260		MB9260			1261
+mb9263			MACH_MB9263		MB9263			1262
+ipac9302		MACH_IPAC9302		IPAC9302		1263
+cc9p9360js		MACH_CC9P9360JS		CC9P9360JS		1264
+gallium			MACH_GALLIUM		GALLIUM			1265
+msc2410			MACH_MSC2410		MSC2410			1266
+ghi270			MACH_GHI270		GHI270			1267
+davinci_leonardo	MACH_DAVINCI_LEONARDO	DAVINCI_LEONARDO	1268
+oiab			MACH_OIAB		OIAB			1269
+smdk6400		MACH_SMDK6400		SMDK6400		1270
+nokia_n800		MACH_NOKIA_N800		NOKIA_N800		1271
+greenphone		MACH_GREENPHONE		GREENPHONE		1272
+compex42x		MACH_COMPEXWP18		COMPEXWP18		1273
+xmate			MACH_XMATE		XMATE			1274
+energizer		MACH_ENERGIZER		ENERGIZER		1275
+ime1			MACH_IME1		IME1			1276
+sweda_tms		MACH_SWEDATMS		SWEDATMS		1277
+ntnp435c		MACH_NTNP435C		NTNP435C		1278
+spectro2		MACH_SPECTRO2		SPECTRO2		1279
+h6039			MACH_H6039		H6039			1280
+ep80219			MACH_EP80219		EP80219			1281
+samoa_ii		MACH_SAMOA_II		SAMOA_II		1282
+cwmxl			MACH_CWMXL		CWMXL			1283
+as9200			MACH_AS9200		AS9200			1284
+sfx1149			MACH_SFX1149		SFX1149			1285
+navi010			MACH_NAVI010		NAVI010			1286
+multmdp			MACH_MULTMDP		MULTMDP			1287
+scb9520			MACH_SCB9520		SCB9520			1288
+htcathena		MACH_HTCATHENA		HTCATHENA		1289
+xp179			MACH_XP179		XP179			1290
+h4300			MACH_H4300		H4300			1291
+goramo_mlr		MACH_GORAMO_MLR		GORAMO_MLR		1292
+mxc30020evb		MACH_MXC30020EVB	MXC30020EVB		1293
+adsbitsyg5		MACH_ADSBITSYG5		ADSBITSYG5		1294
+adsportalplus		MACH_ADSPORTALPLUS	ADSPORTALPLUS		1295
+mmsp2plus		MACH_MMSP2PLUS		MMSP2PLUS		1296
+em_x270			MACH_EM_X270		EM_X270			1297
+tpp302			MACH_TPP302		TPP302			1298
+tpp104			MACH_TPM104		TPM104			1299
+tpm102			MACH_TPM102		TPM102			1300
+tpm109			MACH_TPM109		TPM109			1301
+fbxo1			MACH_FBXO1		FBXO1			1302
+hxd8			MACH_HXD8		HXD8			1303
+neo1973_gta02		MACH_NEO1973_GTA02	NEO1973_GTA02		1304
+emtest			MACH_EMTEST		EMTEST			1305
+ad6900			MACH_AD6900		AD6900			1306
+europa			MACH_EUROPA		EUROPA			1307
+metroconnect		MACH_METROCONNECT	METROCONNECT		1308
+ez_s2410		MACH_EZ_S2410		EZ_S2410		1309
+ez_s2440		MACH_EZ_S2440		EZ_S2440		1310
+ez_ep9312		MACH_EZ_EP9312		EZ_EP9312		1311
+ez_ep9315		MACH_EZ_EP9315		EZ_EP9315		1312
+ez_x7			MACH_EZ_X7		EZ_X7			1313
+godotdb			MACH_GODOTDB		GODOTDB			1314
+mistral			MACH_MISTRAL		MISTRAL			1315
+msm			MACH_MSM		MSM			1316
+ct5910			MACH_CT5910		CT5910			1317
+ct5912			MACH_CT5912		CT5912			1318
+argonst_mp		MACH_HYNET_INE		HYNET_INE		1319
+hynet_app		MACH_HYNET_APP		HYNET_APP		1320
+msm7200			MACH_MSM7200		MSM7200			1321
+msm7600			MACH_MSM7600		MSM7600			1322
+ceb255			MACH_CEB255		CEB255			1323
+ciel			MACH_CIEL		CIEL			1324
+slm5650			MACH_SLM5650		SLM5650			1325
+at91sam9rlek		MACH_AT91SAM9RLEK	AT91SAM9RLEK		1326
+comtech_router		MACH_COMTECH_ROUTER	COMTECH_ROUTER		1327
+sbc2410x		MACH_SBC2410X		SBC2410X		1328
+at4x0bd			MACH_AT4X0BD		AT4X0BD			1329
+cbifr			MACH_CBIFR		CBIFR			1330
+arcom_quantum		MACH_ARCOM_QUANTUM	ARCOM_QUANTUM		1331
+matrix520		MACH_MATRIX520		MATRIX520		1332
+matrix510		MACH_MATRIX510		MATRIX510		1333
+matrix500		MACH_MATRIX500		MATRIX500		1334
+m501			MACH_M501		M501			1335
+aaeon1270		MACH_AAEON1270		AAEON1270		1336
+matrix500ev		MACH_MATRIX500EV	MATRIX500EV		1337
+pac500			MACH_PAC500		PAC500			1338
+pnx8181			MACH_PNX8181		PNX8181			1339
+colibri320		MACH_COLIBRI320		COLIBRI320		1340
+aztoolbb		MACH_AZTOOLBB		AZTOOLBB		1341
+aztoolg2		MACH_AZTOOLG2		AZTOOLG2		1342
+dvlhost			MACH_DVLHOST		DVLHOST			1343
+zir9200			MACH_ZIR9200		ZIR9200			1344
+zir9260			MACH_ZIR9260		ZIR9260			1345
+cocopah			MACH_COCOPAH		COCOPAH			1346
+nds			MACH_NDS		NDS			1347
+rosencrantz		MACH_ROSENCRANTZ	ROSENCRANTZ		1348
+fttx_odsc		MACH_FTTX_ODSC		FTTX_ODSC		1349
+classe_r6904		MACH_CLASSE_R6904	CLASSE_R6904		1350
+cam60			MACH_CAM60		CAM60			1351
+mxc30031ads		MACH_MXC30031ADS	MXC30031ADS		1352
+datacall		MACH_DATACALL		DATACALL		1353
+at91eb01		MACH_AT91EB01		AT91EB01		1354
+rty			MACH_RTY		RTY			1355
+dwl2100			MACH_DWL2100		DWL2100			1356
+vinsi			MACH_VINSI		VINSI			1357
+db88f5281		MACH_DB88F5281		DB88F5281		1358
+csb726			MACH_CSB726		CSB726			1359
+tik27			MACH_TIK27		TIK27			1360
+mx_uc7420		MACH_MX_UC7420		MX_UC7420		1361
+rirm3			MACH_RIRM3		RIRM3			1362
+pelco_odyssey		MACH_PELCO_ODYSSEY	PELCO_ODYSSEY		1363
+adx_abox		MACH_ADX_ABOX		ADX_ABOX		1365
+adx_tpid		MACH_ADX_TPID		ADX_TPID		1366
+minicheck		MACH_MINICHECK		MINICHECK		1367
+idam			MACH_IDAM		IDAM			1368
+mario_mx		MACH_MARIO_MX		MARIO_MX		1369
+vi1888			MACH_VI1888		VI1888			1370
+zr4230			MACH_ZR4230		ZR4230			1371
+t1_ix_blue		MACH_T1_IX_BLUE		T1_IX_BLUE		1372
+syhq2			MACH_SYHQ2		SYHQ2			1373
+computime_r3		MACH_COMPUTIME_R3	COMPUTIME_R3		1374
+oratis			MACH_ORATIS		ORATIS			1375
+mikko			MACH_MIKKO		MIKKO			1376
+holon			MACH_HOLON		HOLON			1377
+olip8			MACH_OLIP8		OLIP8			1378
+ghi270hg		MACH_GHI270HG		GHI270HG		1379
+davinci_dm6467_evm	MACH_DAVINCI_DM6467_EVM	DAVINCI_DM6467_EVM	1380
+davinci_dm355_evm	MACH_DAVINCI_DM355_EVM	DAVINCI_DM355_EVM	1381
+blackriver		MACH_BLACKRIVER		BLACKRIVER		1383
+sandgate_wp		MACH_SANDGATEWP		SANDGATEWP		1384
+cdotbwsg		MACH_CDOTBWSG		CDOTBWSG		1385
+quark963		MACH_QUARK963		QUARK963		1386
+csb735			MACH_CSB735		CSB735			1387
+littleton		MACH_LITTLETON		LITTLETON		1388
+mio_p550		MACH_MIO_P550		MIO_P550		1389
+motion2440		MACH_MOTION2440		MOTION2440		1390
+imm500			MACH_IMM500		IMM500			1391
+homematic		MACH_HOMEMATIC		HOMEMATIC		1392
+ermine			MACH_ERMINE		ERMINE			1393
+kb9202b			MACH_KB9202B		KB9202B			1394
+hs1xx			MACH_HS1XX		HS1XX			1395
+studentmate2440		MACH_STUDENTMATE2440	STUDENTMATE2440		1396
+arvoo_l1_z1		MACH_ARVOO_L1_Z1	ARVOO_L1_Z1		1397
+dep2410k		MACH_DEP2410K		DEP2410K		1398
+xxsvideo		MACH_XXSVIDEO		XXSVIDEO		1399
+im4004			MACH_IM4004		IM4004			1400
+ochaya1050		MACH_OCHAYA1050		OCHAYA1050		1401
+lep9261			MACH_LEP9261		LEP9261			1402
+svenmeb			MACH_SVENMEB		SVENMEB			1403
+fortunet2ne		MACH_FORTUNET2NE	FORTUNET2NE		1404
+nxhx			MACH_NXHX		NXHX			1406
+realview_pb11mp		MACH_REALVIEW_PB11MP	REALVIEW_PB11MP		1407
+ids500			MACH_IDS500		IDS500			1408
+ors_n725		MACH_ORS_N725		ORS_N725		1409
+hsdarm			MACH_HSDARM		HSDARM			1410
+sha_pon003		MACH_SHA_PON003		SHA_PON003		1411
+sha_pon004		MACH_SHA_PON004		SHA_PON004		1412
+sha_pon007		MACH_SHA_PON007		SHA_PON007		1413
+sha_pon011		MACH_SHA_PON011		SHA_PON011		1414
+h6042			MACH_H6042		H6042			1415
+h6043			MACH_H6043		H6043			1416
+looxc550		MACH_LOOXC550		LOOXC550		1417
+cnty_titan		MACH_CNTY_TITAN		CNTY_TITAN		1418
+app3xx			MACH_APP3XX		APP3XX			1419
+sideoatsgrama		MACH_SIDEOATSGRAMA	SIDEOATSGRAMA		1420
+treo700p		MACH_TREO700P		TREO700P		1421
+treo700w		MACH_TREO700W		TREO700W		1422
+treo750			MACH_TREO750		TREO750			1423
+treo755p		MACH_TREO755P		TREO755P		1424
+ezreganut9200		MACH_EZREGANUT9200	EZREGANUT9200		1425
+sarge			MACH_SARGE		SARGE			1426
+a696			MACH_A696		A696			1427
+turtle1916		MACH_TURTLE		TURTLE			1428
+mx27_3ds		MACH_MX27_3DS		MX27_3DS		1430
+bishop			MACH_BISHOP		BISHOP			1431
+pxx			MACH_PXX		PXX			1432
+redwood			MACH_REDWOOD		REDWOOD			1433
+omap_2430dlp		MACH_OMAP_2430DLP	OMAP_2430DLP		1436
+omap_2430osk		MACH_OMAP_2430OSK	OMAP_2430OSK		1437
+sardine			MACH_SARDINE		SARDINE			1438
+halibut			MACH_HALIBUT		HALIBUT			1439
+trout			MACH_TROUT		TROUT			1440
+goldfish		MACH_GOLDFISH		GOLDFISH		1441
+gesbc2440		MACH_GESBC2440		GESBC2440		1442
+nomad			MACH_NOMAD		NOMAD			1443
+rosalind		MACH_ROSALIND		ROSALIND		1444
+cc9p9215		MACH_CC9P9215		CC9P9215		1445
+cc9p9210		MACH_CC9P9210		CC9P9210		1446
+cc9p9215js		MACH_CC9P9215JS		CC9P9215JS		1447
+cc9p9210js		MACH_CC9P9210JS		CC9P9210JS		1448
+nasffe			MACH_NASFFE		NASFFE			1449
+tn2x0bd			MACH_TN2X0BD		TN2X0BD			1450
+gwmpxa			MACH_GWMPXA		GWMPXA			1451
+exyplus			MACH_EXYPLUS		EXYPLUS			1452
+jadoo21			MACH_JADOO21		JADOO21			1453
+looxn560		MACH_LOOXN560		LOOXN560		1454
+bonsai			MACH_BONSAI		BONSAI			1455
+adsmilgato		MACH_ADSMILGATO		ADSMILGATO		1456
+gba			MACH_GBA		GBA			1457
+h6044			MACH_H6044		H6044			1458
+app			MACH_APP		APP			1459
+tct_hammer		MACH_TCT_HAMMER		TCT_HAMMER		1460
+herald			MACH_HERALD		HERALD			1461
+artemis			MACH_ARTEMIS		ARTEMIS			1462
+htctitan		MACH_HTCTITAN		HTCTITAN		1463
+qranium			MACH_QRANIUM		QRANIUM			1464
+adx_wsc2		MACH_ADX_WSC2		ADX_WSC2		1465
+adx_medcom		MACH_ADX_MEDCOM		ADX_MEDCOM		1466
+bboard			MACH_BBOARD		BBOARD			1467
+cambria			MACH_CAMBRIA		CAMBRIA			1468
+mt7xxx			MACH_MT7XXX		MT7XXX			1469
+matrix512		MACH_MATRIX512		MATRIX512		1470
+matrix522		MACH_MATRIX522		MATRIX522		1471
+ipac5010		MACH_IPAC5010		IPAC5010		1472
+sakura			MACH_SAKURA		SAKURA			1473
+grocx			MACH_GROCX		GROCX			1474
+pm9263			MACH_PM9263		PM9263			1475
+sim_one			MACH_SIM_ONE		SIM_ONE			1476
+acq132			MACH_ACQ132		ACQ132			1477
+datr			MACH_DATR		DATR			1478
+actux1			MACH_ACTUX1		ACTUX1			1479
+actux2			MACH_ACTUX2		ACTUX2			1480
+actux3			MACH_ACTUX3		ACTUX3			1481
+flexit			MACH_FLEXIT		FLEXIT			1482
+bh2x0bd			MACH_BH2X0BD		BH2X0BD			1483
+atb2002			MACH_ATB2002		ATB2002			1484
+xenon			MACH_XENON		XENON			1485
+fm607			MACH_FM607		FM607			1486
+matrix514		MACH_MATRIX514		MATRIX514		1487
+matrix524		MACH_MATRIX524		MATRIX524		1488
+inpod			MACH_INPOD		INPOD			1489
+jive			MACH_JIVE		JIVE			1490
+tll_mx21		MACH_TLL_MX21		TLL_MX21		1491
+sbc2800			MACH_SBC2800		SBC2800			1492
+cc7ucamry		MACH_CC7UCAMRY		CC7UCAMRY		1493
+ubisys_p9_sc15		MACH_UBISYS_P9_SC15	UBISYS_P9_SC15		1494
+ubisys_p9_ssc2d10	MACH_UBISYS_P9_SSC2D10	UBISYS_P9_SSC2D10	1495
+ubisys_p9_rcu3		MACH_UBISYS_P9_RCU3	UBISYS_P9_RCU3		1496
+aml_m8000		MACH_AML_M8000		AML_M8000		1497
+snapper_270		MACH_SNAPPER_270	SNAPPER_270		1498
+omap_bbx		MACH_OMAP_BBX		OMAP_BBX		1499
+ucn2410			MACH_UCN2410		UCN2410			1500
+sam9_l9260		MACH_SAM9_L9260		SAM9_L9260		1501
+eti_c2			MACH_ETI_C2		ETI_C2			1502
+avalanche		MACH_AVALANCHE		AVALANCHE		1503
+realview_pb1176		MACH_REALVIEW_PB1176	REALVIEW_PB1176		1504
+dp1500			MACH_DP1500		DP1500			1505
+apple_iphone		MACH_APPLE_IPHONE	APPLE_IPHONE		1506
+yl9200			MACH_YL9200		YL9200			1507
+rd88f5182		MACH_RD88F5182		RD88F5182		1508
+kurobox_pro		MACH_KUROBOX_PRO	KUROBOX_PRO		1509
+se_poet			MACH_SE_POET		SE_POET			1510
+mx31_3ds		MACH_MX31_3DS		MX31_3DS		1511
+r270			MACH_R270		R270			1512
+armour21		MACH_ARMOUR21		ARMOUR21		1513
+dt2			MACH_DT2		DT2			1514
+vt4			MACH_VT4		VT4			1515
+tyco320			MACH_TYCO320		TYCO320			1516
+adma			MACH_ADMA		ADMA			1517
+wp188			MACH_WP188		WP188			1518
+corsica			MACH_CORSICA		CORSICA			1519
+bigeye			MACH_BIGEYE		BIGEYE			1520
+tll5000			MACH_TLL5000		TLL5000			1522
+bebot			MACH_BEBOT		BEBOT			1523
+qong			MACH_QONG		QONG			1524
+tcompact		MACH_TCOMPACT		TCOMPACT		1525
+puma5			MACH_PUMA5		PUMA5			1526
+elara			MACH_ELARA		ELARA			1527
+ellington		MACH_ELLINGTON		ELLINGTON		1528
+xda_atom		MACH_XDA_ATOM		XDA_ATOM		1529
+energizer2		MACH_ENERGIZER2		ENERGIZER2		1530
+odin			MACH_ODIN		ODIN			1531
+actux4			MACH_ACTUX4		ACTUX4			1532
+esl_omap		MACH_ESL_OMAP		ESL_OMAP		1533
+omap2evm		MACH_OMAP2EVM		OMAP2EVM		1534
+omap3evm		MACH_OMAP3EVM		OMAP3EVM		1535
+adx_pcu57		MACH_ADX_PCU57		ADX_PCU57		1536
+monaco			MACH_MONACO		MONACO			1537
+levante			MACH_LEVANTE		LEVANTE			1538
+tmxipx425		MACH_TMXIPX425		TMXIPX425		1539
+leep			MACH_LEEP		LEEP			1540
+raad			MACH_RAAD		RAAD			1541
+dns323			MACH_DNS323		DNS323			1542
+ap1000			MACH_AP1000		AP1000			1543
+a9sam6432		MACH_A9SAM6432		A9SAM6432		1544
+shiny			MACH_SHINY		SHINY			1545
+omap3_beagle		MACH_OMAP3_BEAGLE	OMAP3_BEAGLE		1546
+csr_bdb2		MACH_CSR_BDB2		CSR_BDB2		1547
+nokia_n810		MACH_NOKIA_N810		NOKIA_N810		1548
+c270			MACH_C270		C270			1549
+sentry			MACH_SENTRY		SENTRY			1550
+pcm038			MACH_PCM038		PCM038			1551
+anc300			MACH_ANC300		ANC300			1552
+htckaiser		MACH_HTCKAISER		HTCKAISER		1553
+sbat100			MACH_SBAT100		SBAT100			1554
+modunorm		MACH_MODUNORM		MODUNORM		1555
+pelos_twarm		MACH_PELOS_TWARM	PELOS_TWARM		1556
+flank			MACH_FLANK		FLANK			1557
+sirloin			MACH_SIRLOIN		SIRLOIN			1558
+brisket			MACH_BRISKET		BRISKET			1559
+chuck			MACH_CHUCK		CHUCK			1560
+otter			MACH_OTTER		OTTER			1561
+davinci_ldk		MACH_DAVINCI_LDK	DAVINCI_LDK		1562
+phreedom		MACH_PHREEDOM		PHREEDOM		1563
+sg310			MACH_SG310		SG310			1564
+ts209			MACH_TS209		TS209			1565
+at91cap9adk		MACH_AT91CAP9ADK	AT91CAP9ADK		1566
+tion9315		MACH_TION9315		TION9315		1567
+mast			MACH_MAST		MAST			1568
+pfw			MACH_PFW		PFW			1569
+yl_p2440		MACH_YL_P2440		YL_P2440		1570
+zsbc32			MACH_ZSBC32		ZSBC32			1571
+omap_pace2		MACH_OMAP_PACE2		OMAP_PACE2		1572
+imx_pace2		MACH_IMX_PACE2		IMX_PACE2		1573
+mx31moboard		MACH_MX31MOBOARD	MX31MOBOARD		1574
+mx37_3ds		MACH_MX37_3DS		MX37_3DS		1575
+rcc			MACH_RCC		RCC			1576
+dmp			MACH_ARM9		ARM9			1577
+vision_ep9307		MACH_VISION_EP9307	VISION_EP9307		1578
+scly1000		MACH_SCLY1000		SCLY1000		1579
+fontel_ep		MACH_FONTEL_EP		FONTEL_EP		1580
+voiceblue3g		MACH_VOICEBLUE3G	VOICEBLUE3G		1581
+tt9200			MACH_TT9200		TT9200			1582
+digi2410		MACH_DIGI2410		DIGI2410		1583
+terastation_pro2	MACH_TERASTATION_PRO2	TERASTATION_PRO2	1584
+linkstation_pro		MACH_LINKSTATION_PRO	LINKSTATION_PRO		1585
+motorola_a780		MACH_MOTOROLA_A780	MOTOROLA_A780		1587
+motorola_e6		MACH_MOTOROLA_E6	MOTOROLA_E6		1588
+motorola_e2		MACH_MOTOROLA_E2	MOTOROLA_E2		1589
+motorola_e680		MACH_MOTOROLA_E680	MOTOROLA_E680		1590
+ur2410			MACH_UR2410		UR2410			1591
+tas9261			MACH_TAS9261		TAS9261			1592
+davinci_hermes_hd	MACH_HERMES_HD		HERMES_HD		1593
+davinci_perseo_hd	MACH_PERSEO_HD		PERSEO_HD		1594
+stargazer2		MACH_STARGAZER2		STARGAZER2		1595
+e350			MACH_E350		E350			1596
+wpcm450			MACH_WPCM450		WPCM450			1597
+cartesio		MACH_CARTESIO		CARTESIO		1598
+toybox			MACH_TOYBOX		TOYBOX			1599
+tx27			MACH_TX27		TX27			1600
+ts409			MACH_TS409		TS409			1601
+p300			MACH_P300		P300			1602
+xdacomet		MACH_XDACOMET		XDACOMET		1603
+dexflex2		MACH_DEXFLEX2		DEXFLEX2		1604
+ow			MACH_OW			OW			1605
+armebs3			MACH_ARMEBS3		ARMEBS3			1606
+u3			MACH_U3			U3			1607
+smdk2450		MACH_SMDK2450		SMDK2450		1608
+rsi_ews			MACH_RSI_EWS		RSI_EWS			1609
+tnb			MACH_TNB		TNB			1610
+toepath			MACH_TOEPATH		TOEPATH			1611
+kb9263			MACH_KB9263		KB9263			1612
+mt7108			MACH_MT7108		MT7108			1613
+smtr2440		MACH_SMTR2440		SMTR2440		1614
+manao			MACH_MANAO		MANAO			1615
+cm_x300			MACH_CM_X300		CM_X300			1616
+gulfstream_kp		MACH_GULFSTREAM_KP	GULFSTREAM_KP		1617
+lanreadyfn522		MACH_LANREADYFN522	LANREADYFN522		1618
+arma37			MACH_ARMA37		ARMA37			1619
+mendel			MACH_MENDEL		MENDEL			1620
+pelco_iliad		MACH_PELCO_ILIAD	PELCO_ILIAD		1621
+unit2p			MACH_UNIT2P		UNIT2P			1622
+inc20otter		MACH_INC20OTTER		INC20OTTER		1623
+at91sam9g20ek		MACH_AT91SAM9G20EK	AT91SAM9G20EK		1624
+sc_ge2			MACH_STORCENTER		STORCENTER		1625
+smdk6410		MACH_SMDK6410		SMDK6410		1626
+u300			MACH_U300		U300			1627
+u500			MACH_U500		U500			1628
+ds9260			MACH_DS9260		DS9260			1629
+riverrock		MACH_RIVERROCK		RIVERROCK		1630
+scibath			MACH_SCIBATH		SCIBATH			1631
+at91sam7se		MACH_AT91SAM7SE512EK	AT91SAM7SE512EK		1632
+wrt350n_v2		MACH_WRT350N_V2		WRT350N_V2		1633
+multimedia		MACH_MULTIMEDIA		MULTIMEDIA		1634
+marvin			MACH_MARVIN		MARVIN			1635
+x500			MACH_X500		X500			1636
+awlug4lcu		MACH_AWLUG4LCU		AWLUG4LCU		1637
+palermoc		MACH_PALERMOC		PALERMOC		1638
+omap_ldp		MACH_OMAP_LDP		OMAP_LDP		1639
+ip500			MACH_IP500		IP500			1640
+ase2			MACH_ASE2		ASE2			1642
+mx35evb			MACH_MX35EVB		MX35EVB			1643
+aml_m8050		MACH_AML_M8050		AML_M8050		1644
+mx35_3ds		MACH_MX35_3DS		MX35_3DS		1645
+mars			MACH_MARS		MARS			1646
+neuros_osd2		MACH_NEUROS_OSD2	NEUROS_OSD2		1647
+badger			MACH_BADGER		BADGER			1648
+trizeps4wl		MACH_TRIZEPS4WL		TRIZEPS4WL		1649
+trizeps5		MACH_TRIZEPS5		TRIZEPS5		1650
+marlin			MACH_MARLIN		MARLIN			1651
+ts78xx			MACH_TS78XX		TS78XX			1652
+hpipaq214		MACH_HPIPAQ214		HPIPAQ214		1653
+at572d940dcm		MACH_AT572D940DCM	AT572D940DCM		1654
+ne1board		MACH_NE1BOARD		NE1BOARD		1655
+zante			MACH_ZANTE		ZANTE			1656
+sffsdr			MACH_SFFSDR		SFFSDR			1657
+tw2662			MACH_TW2662		TW2662			1658
+vf10xx			MACH_VF10XX		VF10XX			1659
+zoran43xx		MACH_ZORAN43XX		ZORAN43XX		1660
+sonix926		MACH_SONIX926		SONIX926		1661
+celestialsemi		MACH_CELESTIALSEMI	CELESTIALSEMI		1662
+cc9m2443js		MACH_CC9M2443JS		CC9M2443JS		1663
+tw5334			MACH_TW5334		TW5334			1664
+omap_htcartemis		MACH_HTCARTEMIS		HTCARTEMIS		1665
+nal_hlite		MACH_NAL_HLITE		NAL_HLITE		1666
+htcvogue		MACH_HTCVOGUE		HTCVOGUE		1667
+smartweb		MACH_SMARTWEB		SMARTWEB		1668
+mv86xx			MACH_MV86XX		MV86XX			1669
+mv87xx			MACH_MV87XX		MV87XX			1670
+songyoungho		MACH_SONGYOUNGHO	SONGYOUNGHO		1671
+younghotema		MACH_YOUNGHOTEMA	YOUNGHOTEMA		1672
+pcm037			MACH_PCM037		PCM037			1673
+mmvp			MACH_MMVP		MMVP			1674
+mmap			MACH_MMAP		MMAP			1675
+ptid2410		MACH_PTID2410		PTID2410		1676
+james_926		MACH_JAMES_926		JAMES_926		1677
+fm6000			MACH_FM6000		FM6000			1678
+db88f6281_bp		MACH_DB88F6281_BP	DB88F6281_BP		1680
+rd88f6192_nas		MACH_RD88F6192_NAS	RD88F6192_NAS		1681
+rd88f6281		MACH_RD88F6281		RD88F6281		1682
+db78x00_bp		MACH_DB78X00_BP		DB78X00_BP		1683
+smdk2416		MACH_SMDK2416		SMDK2416		1685
+oce_spider_si		MACH_OCE_SPIDER_SI	OCE_SPIDER_SI		1686
+oce_spider_sk		MACH_OCE_SPIDER_SK	OCE_SPIDER_SK		1687
+rovern6			MACH_ROVERN6		ROVERN6			1688
+pelco_evolution		MACH_PELCO_EVOLUTION	PELCO_EVOLUTION		1689
+wbd111			MACH_WBD111		WBD111			1690
+elaracpe		MACH_ELARACPE		ELARACPE		1691
+mabv3			MACH_MABV3		MABV3			1692
+mv2120			MACH_MV2120		MV2120			1693
+csb737			MACH_CSB737		CSB737			1695
+mx51_3ds		MACH_MX51_3DS		MX51_3DS		1696
+g900			MACH_G900		G900			1697
+apf27			MACH_APF27		APF27			1698
+ggus2000		MACH_GGUS2000		GGUS2000		1699
+omap_2430_mimic		MACH_OMAP_2430_MIMIC	OMAP_2430_MIMIC		1700
+imx27lite		MACH_IMX27LITE		IMX27LITE		1701
+almex			MACH_ALMEX		ALMEX			1702
+control			MACH_CONTROL		CONTROL			1703
+mba2410			MACH_MBA2410		MBA2410			1704
+volcano			MACH_VOLCANO		VOLCANO			1705
+zenith			MACH_ZENITH		ZENITH			1706
+muchip			MACH_MUCHIP		MUCHIP			1707
+magellan		MACH_MAGELLAN		MAGELLAN		1708
+usb_a9260		MACH_USB_A9260		USB_A9260		1709
+usb_a9263		MACH_USB_A9263		USB_A9263		1710
+qil_a9260		MACH_QIL_A9260		QIL_A9260		1711
+cme9210			MACH_CME9210		CME9210			1712
+hczh4			MACH_HCZH4		HCZH4			1713
+spearbasic		MACH_SPEARBASIC		SPEARBASIC		1714
+dep2440			MACH_DEP2440		DEP2440			1715
+hdl_gxr			MACH_HDL_GXR		HDL_GXR			1716
+hdl_gt			MACH_HDL_GT		HDL_GT			1717
+hdl_4g			MACH_HDL_4G		HDL_4G			1718
+s3c6000			MACH_S3C6000		S3C6000			1719
+mmsp2_mdk		MACH_MMSP2_MDK		MMSP2_MDK		1720
+mpx220			MACH_MPX220		MPX220			1721
+kzm_arm11_01		MACH_KZM_ARM11_01	KZM_ARM11_01		1722
+htc_polaris		MACH_HTC_POLARIS	HTC_POLARIS		1723
+htc_kaiser		MACH_HTC_KAISER		HTC_KAISER		1724
+lg_ks20			MACH_LG_KS20		LG_KS20			1725
+hhgps			MACH_HHGPS		HHGPS			1726
+nokia_n810_wimax	MACH_NOKIA_N810_WIMAX	NOKIA_N810_WIMAX	1727
+insight			MACH_INSIGHT		INSIGHT			1728
+sapphire		MACH_SAPPHIRE		SAPPHIRE		1729
+csb637xo		MACH_CSB637XO		CSB637XO		1730
+evisiong		MACH_EVISIONG		EVISIONG		1731
+stmp37xx		MACH_STMP37XX		STMP37XX		1732
+stmp378x		MACH_STMP378X		STMP378X		1733
+tnt			MACH_TNT		TNT			1734
+tbxt			MACH_TBXT		TBXT			1735
+playmate		MACH_PLAYMATE		PLAYMATE		1736
+pns10			MACH_PNS10		PNS10			1737
+eznavi			MACH_EZNAVI		EZNAVI			1738
+ps4000			MACH_PS4000		PS4000			1739
+ezx_a780		MACH_EZX_A780		EZX_A780		1740
+ezx_e680		MACH_EZX_E680		EZX_E680		1741
+ezx_a1200		MACH_EZX_A1200		EZX_A1200		1742
+ezx_e6			MACH_EZX_E6		EZX_E6			1743
+ezx_e2			MACH_EZX_E2		EZX_E2			1744
+ezx_a910		MACH_EZX_A910		EZX_A910		1745
+cwmx31			MACH_CWMX31		CWMX31			1746
+sl2312			MACH_SL2312		SL2312			1747
+blenny			MACH_BLENNY		BLENNY			1748
+ds107			MACH_DS107		DS107			1749
+dsx07			MACH_DSX07		DSX07			1750
+picocom1		MACH_PICOCOM1		PICOCOM1		1751
+lynx_wolverine		MACH_LYNX_WOLVERINE	LYNX_WOLVERINE		1752
+ubisys_p9_sc19		MACH_UBISYS_P9_SC19	UBISYS_P9_SC19		1753
+kratos_low		MACH_KRATOS_LOW		KRATOS_LOW		1754
+m700			MACH_M700		M700			1755
+edmini_v2		MACH_EDMINI_V2		EDMINI_V2		1756
+zipit2			MACH_ZIPIT2		ZIPIT2			1757
+hslfemtocell		MACH_HSLFEMTOCELL	HSLFEMTOCELL		1758
+daintree_at91		MACH_DAINTREE_AT91	DAINTREE_AT91		1759
+sg560usb		MACH_SG560USB		SG560USB		1760
+omap3_pandora		MACH_OMAP3_PANDORA	OMAP3_PANDORA		1761
+usr8200			MACH_USR8200		USR8200			1762
+s1s65k			MACH_S1S65K		S1S65K			1763
+s2s65a			MACH_S2S65A		S2S65A			1764
+icore			MACH_ICORE		ICORE			1765
+mss2			MACH_MSS2		MSS2			1766
+belmont			MACH_BELMONT		BELMONT			1767
+asusp525		MACH_ASUSP525		ASUSP525		1768
+lb88rc8480		MACH_LB88RC8480		LB88RC8480		1769
+hipxa			MACH_HIPXA		HIPXA			1770
+mx25_3ds		MACH_MX25_3DS		MX25_3DS		1771
+m800			MACH_M800		M800			1772
+omap3530_lv_som		MACH_OMAP3530_LV_SOM	OMAP3530_LV_SOM		1773
+prima_evb		MACH_PRIMA_EVB		PRIMA_EVB		1774
+mx31bt1			MACH_MX31BT1		MX31BT1			1775
+atlas4_evb		MACH_ATLAS4_EVB		ATLAS4_EVB		1776
+mx31cicada		MACH_MX31CICADA		MX31CICADA		1777
+mi424wr			MACH_MI424WR		MI424WR			1778
+axs_ultrax		MACH_AXS_ULTRAX		AXS_ULTRAX		1779
+at572d940deb		MACH_AT572D940DEB	AT572D940DEB		1780
+davinci_da830_evm	MACH_DAVINCI_DA830_EVM	DAVINCI_DA830_EVM	1781
+ep9302			MACH_EP9302		EP9302			1782
+at572d940hfek		MACH_AT572D940HFEB	AT572D940HFEB		1783
+cybook3			MACH_CYBOOK3		CYBOOK3			1784
+wdg002			MACH_WDG002		WDG002			1785
+sg560adsl		MACH_SG560ADSL		SG560ADSL		1786
+nextio_n2800_ica	MACH_NEXTIO_N2800_ICA	NEXTIO_N2800_ICA	1787
+dove_db			MACH_DOVE_DB		DOVE_DB			1788
+vandihud		MACH_VANDIHUD		VANDIHUD		1790
+magx_e8			MACH_MAGX_E8		MAGX_E8			1791
+magx_z6			MACH_MAGX_Z6		MAGX_Z6			1792
+magx_v8			MACH_MAGX_V8		MAGX_V8			1793
+magx_u9			MACH_MAGX_U9		MAGX_U9			1794
+toughcf08		MACH_TOUGHCF08		TOUGHCF08		1795
+zw4400			MACH_ZW4400		ZW4400			1796
+marat91			MACH_MARAT91		MARAT91			1797
+overo			MACH_OVERO		OVERO			1798
+at2440evb		MACH_AT2440EVB		AT2440EVB		1799
+neocore926		MACH_NEOCORE926		NEOCORE926		1800
+wnr854t			MACH_WNR854T		WNR854T			1801
+imx27			MACH_IMX27		IMX27			1802
+moose_db		MACH_MOOSE_DB		MOOSE_DB		1803
+fab4			MACH_FAB4		FAB4			1804
+htcdiamond		MACH_HTCDIAMOND		HTCDIAMOND		1805
+fiona			MACH_FIONA		FIONA			1806
+mxc30030_x		MACH_MXC30030_X		MXC30030_X		1807
+bmp1000			MACH_BMP1000		BMP1000			1808
+logi9200		MACH_LOGI9200		LOGI9200		1809
+tqma31			MACH_TQMA31		TQMA31			1810
+ccw9p9215js		MACH_CCW9P9215JS	CCW9P9215JS		1811
+rd88f5181l_ge		MACH_RD88F5181L_GE	RD88F5181L_GE		1812
+sifmain			MACH_SIFMAIN		SIFMAIN			1813
+sam9_l9261		MACH_SAM9_L9261		SAM9_L9261		1814
+cc9m2443		MACH_CC9M2443		CC9M2443		1815
+xaria300		MACH_XARIA300		XARIA300		1816
+it9200			MACH_IT9200		IT9200			1817
+rd88f5181l_fxo		MACH_RD88F5181L_FXO	RD88F5181L_FXO		1818
+kriss_sensor		MACH_KRISS_SENSOR	KRISS_SENSOR		1819
+pilz_pmi5		MACH_PILZ_PMI5		PILZ_PMI5		1820
+jade			MACH_JADE		JADE			1821
+ks8695_softplc		MACH_KS8695_SOFTPLC	KS8695_SOFTPLC		1822
+gprisc3			MACH_GPRISC3		GPRISC3			1823
+stamp9g20		MACH_STAMP9G20		STAMP9G20		1824
+smdk6430		MACH_SMDK6430		SMDK6430		1825
+smdkc100		MACH_SMDKC100		SMDKC100		1826
+tavorevb		MACH_TAVOREVB		TAVOREVB		1827
+saar			MACH_SAAR		SAAR			1828
+deister_eyecam		MACH_DEISTER_EYECAM	DEISTER_EYECAM		1829
+at91sam9m10g45ek	MACH_AT91SAM9M10G45EK	AT91SAM9M10G45EK	1830
+linkstation_produo	MACH_LINKSTATION_PRODUO	LINKSTATION_PRODUO	1831
+hit_b0			MACH_HIT_B0		HIT_B0			1832
+adx_rmu			MACH_ADX_RMU		ADX_RMU			1833
+xg_cpe_main		MACH_XG_CPE_MAIN	XG_CPE_MAIN		1834
+edb9407a		MACH_EDB9407A		EDB9407A		1835
+dtb9608			MACH_DTB9608		DTB9608			1836
+em104v1			MACH_EM104V1		EM104V1			1837
+demo			MACH_DEMO		DEMO			1838
+logi9260		MACH_LOGI9260		LOGI9260		1839
+mx31_exm32		MACH_MX31_EXM32		MX31_EXM32		1840
+usb_a9g20		MACH_USB_A9G20		USB_A9G20		1841
+picproje2008		MACH_PICPROJE2008	PICPROJE2008		1842
+cs_e9315		MACH_CS_E9315		CS_E9315		1843
+qil_a9g20		MACH_QIL_A9G20		QIL_A9G20		1844
+sha_pon020		MACH_SHA_PON020		SHA_PON020		1845
+nad			MACH_NAD		NAD			1846
+sbc35_a9260		MACH_SBC35_A9260	SBC35_A9260		1847
+sbc35_a9g20		MACH_SBC35_A9G20	SBC35_A9G20		1848
+davinci_beginning	MACH_DAVINCI_BEGINNING	DAVINCI_BEGINNING	1849
+uwc			MACH_UWC		UWC			1850
+mxlads			MACH_MXLADS		MXLADS			1851
+htcnike			MACH_HTCNIKE		HTCNIKE			1852
+deister_pxa270		MACH_DEISTER_PXA270	DEISTER_PXA270		1853
+cme9210js		MACH_CME9210JS		CME9210JS		1854
+cc9p9360		MACH_CC9P9360		CC9P9360		1855
+mocha			MACH_MOCHA		MOCHA			1856
+wapd170ag		MACH_WAPD170AG		WAPD170AG		1857
+linkstation_mini	MACH_LINKSTATION_MINI	LINKSTATION_MINI	1858
+afeb9260		MACH_AFEB9260		AFEB9260		1859
+w90x900			MACH_W90X900		W90X900			1860
+w90x700			MACH_W90X700		W90X700			1861
+kt300ip			MACH_KT300IP		KT300IP			1862
+kt300ip_g20		MACH_KT300IP_G20	KT300IP_G20		1863
+srcm			MACH_SRCM		SRCM			1864
+wlnx_9260		MACH_WLNX_9260		WLNX_9260		1865
+openmoko_gta03		MACH_OPENMOKO_GTA03	OPENMOKO_GTA03		1866
+osprey2			MACH_OSPREY2		OSPREY2			1867
+kbio9260		MACH_KBIO9260		KBIO9260		1868
+ginza			MACH_GINZA		GINZA			1869
+a636n			MACH_A636N		A636N			1870
+imx27ipcam		MACH_IMX27IPCAM		IMX27IPCAM		1871
+nemoc			MACH_NEMOC		NEMOC			1872
+geneva			MACH_GENEVA		GENEVA			1873
+htcpharos		MACH_HTCPHAROS		HTCPHAROS		1874
+neonc			MACH_NEONC		NEONC			1875
+nas7100			MACH_NAS7100		NAS7100			1876
+teuphone		MACH_TEUPHONE		TEUPHONE		1877
+annax_eth2		MACH_ANNAX_ETH2		ANNAX_ETH2		1878
+csb733			MACH_CSB733		CSB733			1879
+bk3			MACH_BK3		BK3			1880
+omap_em32		MACH_OMAP_EM32		OMAP_EM32		1881
+et9261cp		MACH_ET9261CP		ET9261CP		1882
+jasperc			MACH_JASPERC		JASPERC			1883
+issi_arm9		MACH_ISSI_ARM9		ISSI_ARM9		1884
+ued			MACH_UED		UED			1885
+esiblade		MACH_ESIBLADE		ESIBLADE		1886
+eye02			MACH_EYE02		EYE02			1887
+imx27kbd		MACH_IMX27KBD		IMX27KBD		1888
+kixvp435		MACH_KIXVP435		KIXVP435		1890
+kixnp435		MACH_KIXNP435		KIXNP435		1891
+africa			MACH_AFRICA		AFRICA			1892
+nh233			MACH_NH233		NH233			1893
+rd88f6183ap_ge		MACH_RD88F6183AP_GE	RD88F6183AP_GE		1894
+bcm4760			MACH_BCM4760		BCM4760			1895
+eddy_v2			MACH_EDDY_V2		EDDY_V2			1896
+realview_pba8		MACH_REALVIEW_PBA8	REALVIEW_PBA8		1897
+hid_a7			MACH_HID_A7		HID_A7			1898
+hero			MACH_HERO		HERO			1899
+omap_poseidon		MACH_OMAP_POSEIDON	OMAP_POSEIDON		1900
+realview_pbx		MACH_REALVIEW_PBX	REALVIEW_PBX		1901
+micro9s			MACH_MICRO9S		MICRO9S			1902
+mako			MACH_MAKO		MAKO			1903
+xdaflame		MACH_XDAFLAME		XDAFLAME		1904
+phidget_sbc2		MACH_PHIDGET_SBC2	PHIDGET_SBC2		1905
+limestone		MACH_LIMESTONE		LIMESTONE		1906
+iprobe_c32		MACH_IPROBE_C32		IPROBE_C32		1907
+rut100			MACH_RUT100		RUT100			1908
+asusp535		MACH_ASUSP535		ASUSP535		1909
+htcraphael		MACH_HTCRAPHAEL		HTCRAPHAEL		1910
+sygdg1			MACH_SYGDG1		SYGDG1			1911
+sygdg2			MACH_SYGDG2		SYGDG2			1912
+seoul			MACH_SEOUL		SEOUL			1913
+salerno			MACH_SALERNO		SALERNO			1914
+ucn_s3c64xx		MACH_UCN_S3C64XX	UCN_S3C64XX		1915
+msm7201a		MACH_MSM7201A		MSM7201A		1916
+lpr1			MACH_LPR1		LPR1			1917
+armadillo500fx		MACH_ARMADILLO500FX	ARMADILLO500FX		1918
+g3evm			MACH_G3EVM		G3EVM			1919
+z3_dm355		MACH_Z3_DM355		Z3_DM355		1920
+w90p910evb		MACH_W90P910EVB		W90P910EVB		1921
+w90p920evb		MACH_W90P920EVB		W90P920EVB		1922
+w90p950evb		MACH_W90P950EVB		W90P950EVB		1923
+w90n960evb		MACH_W90N960EVB		W90N960EVB		1924
+camhd			MACH_CAMHD		CAMHD			1925
+mvc100			MACH_MVC100		MVC100			1926
+electrum_200		MACH_ELECTRUM_200	ELECTRUM_200		1927
+htcjade			MACH_HTCJADE		HTCJADE			1928
+memphis			MACH_MEMPHIS		MEMPHIS			1929
+imx27sbc		MACH_IMX27SBC		IMX27SBC		1930
+lextar			MACH_LEXTAR		LEXTAR			1931
+mv88f6281gtw_ge		MACH_MV88F6281GTW_GE	MV88F6281GTW_GE		1932
+ncp			MACH_NCP		NCP			1933
+z32an_series		MACH_Z32AN		Z32AN			1934
+tmq_capd		MACH_TMQ_CAPD		TMQ_CAPD		1935
+omap3_wl		MACH_OMAP3_WL		OMAP3_WL		1936
+chumby			MACH_CHUMBY		CHUMBY			1937
+atsarm9			MACH_ATSARM9		ATSARM9			1938
+davinci_dm365_evm	MACH_DAVINCI_DM365_EVM	DAVINCI_DM365_EVM	1939
+bahamas			MACH_BAHAMAS		BAHAMAS			1940
+das			MACH_DAS		DAS			1941
+minidas			MACH_MINIDAS		MINIDAS			1942
+vk1000			MACH_VK1000		VK1000			1943
+centro			MACH_CENTRO		CENTRO			1944
+ctera_2bay		MACH_CTERA_2BAY		CTERA_2BAY		1945
+edgeconnect		MACH_EDGECONNECT	EDGECONNECT		1946
+nd27000			MACH_ND27000		ND27000			1947
+cobra			MACH_GEMALTO_COBRA	GEMALTO_COBRA		1948
+ingelabs_comet		MACH_INGELABS_COMET	INGELABS_COMET		1949
+pollux_wiz		MACH_POLLUX_WIZ		POLLUX_WIZ		1950
+blackstone		MACH_BLACKSTONE		BLACKSTONE		1951
+topaz			MACH_TOPAZ		TOPAZ			1952
+aixle			MACH_AIXLE		AIXLE			1953
+mw998			MACH_MW998		MW998			1954
+nokia_rx51		MACH_NOKIA_RX51		NOKIA_RX51		1955
+vsc5605ev		MACH_VSC5605EV		VSC5605EV		1956
+nt98700dk		MACH_NT98700DK		NT98700DK		1957
+icontact		MACH_ICONTACT		ICONTACT		1958
+swarco_frcpu		MACH_SWARCO_FRCPU	SWARCO_FRCPU		1959
+swarco_scpu		MACH_SWARCO_SCPU	SWARCO_SCPU		1960
+bbox_p16		MACH_BBOX_P16		BBOX_P16		1961
+bstd			MACH_BSTD		BSTD			1962
+sbc2440ii		MACH_SBC2440II		SBC2440II		1963
+pcm034			MACH_PCM034		PCM034			1964
+neso			MACH_NESO		NESO			1965
+wlnx_9g20		MACH_WLNX_9G20		WLNX_9G20		1966
+omap_zoom2		MACH_OMAP_ZOOM2		OMAP_ZOOM2		1967
+totemnova		MACH_TOTEMNOVA		TOTEMNOVA		1968
+c5000			MACH_C5000		C5000			1969
+unipo_at91sam9263	MACH_UNIPO_AT91SAM9263	UNIPO_AT91SAM9263	1970
+ethernut5		MACH_ETHERNUT5		ETHERNUT5		1971
+arm11			MACH_ARM11		ARM11			1972
+cpuat9260		MACH_CPUAT9260		CPUAT9260		1973
+cpupxa255		MACH_CPUPXA255		CPUPXA255		1974
+eukrea_cpuimx27		MACH_EUKREA_CPUIMX27	EUKREA_CPUIMX27		1975
+cheflux			MACH_CHEFLUX		CHEFLUX			1976
+eb_cpux9k2		MACH_EB_CPUX9K2		EB_CPUX9K2		1977
+opcotec			MACH_OPCOTEC		OPCOTEC			1978
+yt			MACH_YT			YT			1979
+motoq			MACH_MOTOQ		MOTOQ			1980
+bsb1			MACH_BSB1		BSB1			1981
+acs5k			MACH_ACS5K		ACS5K			1982
+milan			MACH_MILAN		MILAN			1983
+quartzv2		MACH_QUARTZV2		QUARTZV2		1984
+rsvp			MACH_RSVP		RSVP			1985
+rmp200			MACH_RMP200		RMP200			1986
+snapper_9260		MACH_SNAPPER_9260	SNAPPER_9260		1987
+dsm320			MACH_DSM320		DSM320			1988
+adsgcm			MACH_ADSGCM		ADSGCM			1989
+ase2_400		MACH_ASE2_400		ASE2_400		1990
+pizza			MACH_PIZZA		PIZZA			1991
+spot_ngpl		MACH_SPOT_NGPL		SPOT_NGPL		1992
+armata			MACH_ARMATA		ARMATA			1993
+exeda			MACH_EXEDA		EXEDA			1994
+mx31sf005		MACH_MX31SF005		MX31SF005		1995
+f5d8231_4_v2		MACH_F5D8231_4_V2	F5D8231_4_V2		1996
+q2440			MACH_Q2440		Q2440			1997
+qq2440			MACH_QQ2440		QQ2440			1998
+mini2440		MACH_MINI2440		MINI2440		1999
+colibri300		MACH_COLIBRI300		COLIBRI300		2000
+jades			MACH_JADES		JADES			2001
+spark			MACH_SPARK		SPARK			2002
+benzina			MACH_BENZINA		BENZINA			2003
+blaze			MACH_BLAZE		BLAZE			2004
+linkstation_ls_hgl	MACH_LINKSTATION_LS_HGL	LINKSTATION_LS_HGL	2005
+htckovsky		MACH_HTCKOVSKY		HTCKOVSKY		2006
+sony_prs505		MACH_SONY_PRS505	SONY_PRS505		2007
+hanlin_v3		MACH_HANLIN_V3		HANLIN_V3		2008
+sapphira		MACH_SAPPHIRA		SAPPHIRA		2009
+dack_sda_01		MACH_DACK_SDA_01	DACK_SDA_01		2010
+armbox			MACH_ARMBOX		ARMBOX			2011
+harris_rvp		MACH_HARRIS_RVP		HARRIS_RVP		2012
+ribaldo			MACH_RIBALDO		RIBALDO			2013
+agora			MACH_AGORA		AGORA			2014
+omap3_mini		MACH_OMAP3_MINI		OMAP3_MINI		2015
+a9sam6432_b		MACH_A9SAM6432_B	A9SAM6432_B		2016
+usg2410			MACH_USG2410		USG2410			2017
+pc72052_i10_revb	MACH_PC72052_I10_REVB	PC72052_I10_REVB	2018
+mx35_exm32		MACH_MX35_EXM32		MX35_EXM32		2019
+topas910		MACH_TOPAS910		TOPAS910		2020
+hyena			MACH_HYENA		HYENA			2021
+pospax			MACH_POSPAX		POSPAX			2022
+hdl_gx			MACH_HDL_GX		HDL_GX			2023
+ctera_4bay		MACH_CTERA_4BAY		CTERA_4BAY		2024
+ctera_plug_c		MACH_CTERA_PLUG_C	CTERA_PLUG_C		2025
+crwea_plug_i		MACH_CRWEA_PLUG_I	CRWEA_PLUG_I		2026
+egauge2			MACH_EGAUGE2		EGAUGE2			2027
+didj			MACH_DIDJ		DIDJ			2028
+m_s3c2443		MACH_MEISTER		MEISTER			2029
+htcblackstone		MACH_HTCBLACKSTONE	HTCBLACKSTONE		2030
+cpuat9g20		MACH_CPUAT9G20		CPUAT9G20		2031
+smdk6440		MACH_SMDK6440		SMDK6440		2032
+omap_35xx_mvp		MACH_OMAP_35XX_MVP	OMAP_35XX_MVP		2033
+ctera_plug_i		MACH_CTERA_PLUG_I	CTERA_PLUG_I		2034
+pvg610_100		MACH_PVG610		PVG610			2035
+hprw6815		MACH_HPRW6815		HPRW6815		2036
+omap3_oswald		MACH_OMAP3_OSWALD	OMAP3_OSWALD		2037
+nas4220b		MACH_NAS4220B		NAS4220B		2038
+htcraphael_cdma		MACH_HTCRAPHAEL_CDMA	HTCRAPHAEL_CDMA		2039
+htcdiamond_cdma		MACH_HTCDIAMOND_CDMA	HTCDIAMOND_CDMA		2040
+scaler			MACH_SCALER		SCALER			2041
+zylonite2		MACH_ZYLONITE2		ZYLONITE2		2042
+aspenite		MACH_ASPENITE		ASPENITE		2043
+teton			MACH_TETON		TETON			2044
+ttc_dkb			MACH_TTC_DKB		TTC_DKB			2045
+bishop2			MACH_BISHOP2		BISHOP2			2046
+ippv5			MACH_IPPV5		IPPV5			2047
+farm926			MACH_FARM926		FARM926			2048
+mmccpu			MACH_MMCCPU		MMCCPU			2049
+sgmsfl			MACH_SGMSFL		SGMSFL			2050
+tt8000			MACH_TT8000		TT8000			2051
+zrn4300lp		MACH_ZRN4300LP		ZRN4300LP		2052
+mptc			MACH_MPTC		MPTC			2053
+h6051			MACH_H6051		H6051			2054
+pvg610_101		MACH_PVG610_101		PVG610_101		2055
+stamp9261_pc_evb	MACH_STAMP9261_PC_EVB	STAMP9261_PC_EVB	2056
+pelco_odysseus		MACH_PELCO_ODYSSEUS	PELCO_ODYSSEUS		2057
+tny_a9260		MACH_TNY_A9260		TNY_A9260		2058
+tny_a9g20		MACH_TNY_A9G20		TNY_A9G20		2059
+aesop_mp2530f		MACH_AESOP_MP2530F	AESOP_MP2530F		2060
+dx900			MACH_DX900		DX900			2061
+cpodc2			MACH_CPODC2		CPODC2			2062
+tilt_8925		MACH_TILT_8925		TILT_8925		2063
+davinci_dm357_evm	MACH_DAVINCI_DM357_EVM	DAVINCI_DM357_EVM	2064
+swordfish		MACH_SWORDFISH		SWORDFISH		2065
+corvus			MACH_CORVUS		CORVUS			2066
+taurus			MACH_TAURUS		TAURUS			2067
+axm			MACH_AXM		AXM			2068
+axc			MACH_AXC		AXC			2069
+baby			MACH_BABY		BABY			2070
+mp200			MACH_MP200		MP200			2071
+pcm043			MACH_PCM043		PCM043			2072
+hanlin_v3c		MACH_HANLIN_V3C		HANLIN_V3C		2073
+kbk9g20			MACH_KBK9G20		KBK9G20			2074
+adsturbog5		MACH_ADSTURBOG5		ADSTURBOG5		2075
+avenger_lite1		MACH_AVENGER_LITE1	AVENGER_LITE1		2076
+suc82x			MACH_SUC		SUC			2077
+at91sam7s256		MACH_AT91SAM7S256	AT91SAM7S256		2078
+mendoza			MACH_MENDOZA		MENDOZA			2079
+kira			MACH_KIRA		KIRA			2080
+mx1hbm			MACH_MX1HBM		MX1HBM			2081
+quatro43xx		MACH_QUATRO43XX		QUATRO43XX		2082
+quatro4230		MACH_QUATRO4230		QUATRO4230		2083
+nsb400			MACH_NSB400		NSB400			2084
+drp255			MACH_DRP255		DRP255			2085
+thoth			MACH_THOTH		THOTH			2086
+firestone		MACH_FIRESTONE		FIRESTONE		2087
+asusp750		MACH_ASUSP750		ASUSP750		2088
+ctera_dl		MACH_CTERA_DL		CTERA_DL		2089
+socr			MACH_SOCR		SOCR			2090
+htcoxygen		MACH_HTCOXYGEN		HTCOXYGEN		2091
+heroc			MACH_HEROC		HEROC			2092
+zeno6800		MACH_ZENO6800		ZENO6800		2093
+sc2mcs			MACH_SC2MCS		SC2MCS			2094
+gene100			MACH_GENE100		GENE100			2095
+as353x			MACH_AS353X		AS353X			2096
+sheevaplug		MACH_SHEEVAPLUG		SHEEVAPLUG		2097
+at91sam9g20		MACH_AT91SAM9G20	AT91SAM9G20		2098
+mv88f6192gtw_fe		MACH_MV88F6192GTW_FE	MV88F6192GTW_FE		2099
+cc9200			MACH_CC9200		CC9200			2100
+sm9200			MACH_SM9200		SM9200			2101
+tp9200			MACH_TP9200		TP9200			2102
+snapperdv		MACH_SNAPPERDV		SNAPPERDV		2103
+avengers_lite		MACH_AVENGERS_LITE	AVENGERS_LITE		2104
+avengers_lite1		MACH_AVENGERS_LITE1	AVENGERS_LITE1		2105
+omap3axon		MACH_OMAP3AXON		OMAP3AXON		2106
+ma8xx			MACH_MA8XX		MA8XX			2107
+mp201ek			MACH_MP201EK		MP201EK			2108
+davinci_tux		MACH_DAVINCI_TUX	DAVINCI_TUX		2109
+mpa1600			MACH_MPA1600		MPA1600			2110
+pelco_troy		MACH_PELCO_TROY		PELCO_TROY		2111
+nsb667			MACH_NSB667		NSB667			2112
+rovers5_4mpix		MACH_ROVERS5_4MPIX	ROVERS5_4MPIX		2113
+twocom			MACH_TWOCOM		TWOCOM			2114
+ubisys_p9_rcu3r2	MACH_UBISYS_P9_RCU3R2	UBISYS_P9_RCU3R2	2115
+hero_espresso		MACH_HERO_ESPRESSO	HERO_ESPRESSO		2116
+afeusb			MACH_AFEUSB		AFEUSB			2117
+t830			MACH_T830		T830			2118
+spd8020_cc		MACH_SPD8020_CC		SPD8020_CC		2119
+om_3d7k			MACH_OM_3D7K		OM_3D7K			2120
+picocom2		MACH_PICOCOM2		PICOCOM2		2121
+uwg4mx27		MACH_UWG4MX27		UWG4MX27		2122
+uwg4mx31		MACH_UWG4MX31		UWG4MX31		2123
+cherry			MACH_CHERRY		CHERRY			2124
+mx51_babbage		MACH_MX51_BABBAGE	MX51_BABBAGE		2125
+s3c2440turkiye		MACH_S3C2440TURKIYE	S3C2440TURKIYE		2126
+tx37			MACH_TX37		TX37			2127
+sbc2800_9g20		MACH_SBC2800_9G20	SBC2800_9G20		2128
+benzglb			MACH_BENZGLB		BENZGLB			2129
+benztd			MACH_BENZTD		BENZTD			2130
+cartesio_plus		MACH_CARTESIO_PLUS	CARTESIO_PLUS		2131
+solrad_g20		MACH_SOLRAD_G20		SOLRAD_G20		2132
+mx27wallace		MACH_MX27WALLACE	MX27WALLACE		2133
+fmzwebmodul		MACH_FMZWEBMODUL	FMZWEBMODUL		2134
+rd78x00_masa		MACH_RD78X00_MASA	RD78X00_MASA		2135
+smallogger		MACH_SMALLOGGER		SMALLOGGER		2136
+ccw9p9215		MACH_CCW9P9215		CCW9P9215		2137
+dm355_leopard		MACH_DM355_LEOPARD	DM355_LEOPARD		2138
+ts219			MACH_TS219		TS219			2139
+tny_a9263		MACH_TNY_A9263		TNY_A9263		2140
+apollo			MACH_APOLLO		APOLLO			2141
+at91cap9stk		MACH_AT91CAP9STK	AT91CAP9STK		2142
+spc300			MACH_SPC300		SPC300			2143
+eko			MACH_EKO		EKO			2144
+ccw9m2443		MACH_CCW9M2443		CCW9M2443		2145
+ccw9m2443js		MACH_CCW9M2443JS	CCW9M2443JS		2146
+m2m_router_device	MACH_M2M_ROUTER_DEVICE	M2M_ROUTER_DEVICE	2147
+str9104nas		MACH_STAR9104NAS	STAR9104NAS		2148
+pca100			MACH_PCA100		PCA100			2149
+z3_dm365_mod_01		MACH_Z3_DM365_MOD_01	Z3_DM365_MOD_01		2150
+hipox			MACH_HIPOX		HIPOX			2151
+omap3_piteds		MACH_OMAP3_PITEDS	OMAP3_PITEDS		2152
+bm150r			MACH_BM150R		BM150R			2153
+tbone			MACH_TBONE		TBONE			2154
+merlin			MACH_MERLIN		MERLIN			2155
+falcon			MACH_FALCON		FALCON			2156
+davinci_da850_evm	MACH_DAVINCI_DA850_EVM	DAVINCI_DA850_EVM	2157
+s5p6440			MACH_S5P6440		S5P6440			2158
+at91sam9g10ek		MACH_AT91SAM9G10EK	AT91SAM9G10EK		2159
+omap_4430sdp		MACH_OMAP_4430SDP	OMAP_4430SDP		2160
+lpc313x			MACH_LPC313X		LPC313X			2161
+magx_zn5		MACH_MAGX_ZN5		MAGX_ZN5		2162
+magx_em30		MACH_MAGX_EM30		MAGX_EM30		2163
+magx_ve66		MACH_MAGX_VE66		MAGX_VE66		2164
+meesc			MACH_MEESC		MEESC			2165
+otc570			MACH_OTC570		OTC570			2166
+bcu2412			MACH_BCU2412		BCU2412			2167
+beacon			MACH_BEACON		BEACON			2168
+actia_tgw		MACH_ACTIA_TGW		ACTIA_TGW		2169
+e4430			MACH_E4430		E4430			2170
+ql300			MACH_QL300		QL300			2171
+btmavb101		MACH_BTMAVB101		BTMAVB101		2172
+btmawb101		MACH_BTMAWB101		BTMAWB101		2173
+sq201			MACH_SQ201		SQ201			2174
+quatro45xx		MACH_QUATRO45XX		QUATRO45XX		2175
+openpad			MACH_OPENPAD		OPENPAD			2176
+tx25			MACH_TX25		TX25			2177
+omap3_torpedo		MACH_OMAP3_TORPEDO	OMAP3_TORPEDO		2178
+htcraphael_k		MACH_HTCRAPHAEL_K	HTCRAPHAEL_K		2179
+lal43			MACH_LAL43		LAL43			2181
+htcraphael_cdma500	MACH_HTCRAPHAEL_CDMA500	HTCRAPHAEL_CDMA500	2182
+anw6410			MACH_ANW6410		ANW6410			2183
+htcprophet		MACH_HTCPROPHET		HTCPROPHET		2185
+cfa_10022		MACH_CFA_10022		CFA_10022		2186
+imx27_visstrim_m10	MACH_IMX27_VISSTRIM_M10	IMX27_VISSTRIM_M10	2187
+px2imx27		MACH_PX2IMX27		PX2IMX27		2188
+stm3210e_eval		MACH_STM3210E_EVAL	STM3210E_EVAL		2189
+dvs10			MACH_DVS10		DVS10			2190
+portuxg20		MACH_PORTUXG20		PORTUXG20		2191
+arm_spv			MACH_ARM_SPV		ARM_SPV			2192
+smdkc110		MACH_SMDKC110		SMDKC110		2193
+cabespresso		MACH_CABESPRESSO	CABESPRESSO		2194
+hmc800			MACH_HMC800		HMC800			2195
+sholes			MACH_SHOLES		SHOLES			2196
+btmxc31			MACH_BTMXC31		BTMXC31			2197
+dt501			MACH_DT501		DT501			2198
+ktx			MACH_KTX		KTX			2199
+omap3517evm		MACH_OMAP3517EVM	OMAP3517EVM		2200
+netspace_v2		MACH_NETSPACE_V2	NETSPACE_V2		2201
+netspace_max_v2		MACH_NETSPACE_MAX_V2	NETSPACE_MAX_V2		2202
+d2net_v2		MACH_D2NET_V2		D2NET_V2		2203
+net2big_v2		MACH_NET2BIG_V2		NET2BIG_V2		2204
+net4big_v2		MACH_NET4BIG_V2		NET4BIG_V2		2205
+net5big_v2		MACH_NET5BIG_V2		NET5BIG_V2		2206
+endb2443		MACH_ENDB2443		ENDB2443		2207
+inetspace_v2		MACH_INETSPACE_V2	INETSPACE_V2		2208
+tros			MACH_TROS		TROS			2209
+pelco_homer		MACH_PELCO_HOMER	PELCO_HOMER		2210
+ofsp8			MACH_OFSP8		OFSP8			2211
+at91sam9g45ekes		MACH_AT91SAM9G45EKES	AT91SAM9G45EKES		2212
+guf_cupid		MACH_GUF_CUPID		GUF_CUPID		2213
+eab1r			MACH_EAB1R		EAB1R			2214
+desirec			MACH_DESIREC		DESIREC			2215
+cordoba			MACH_CORDOBA		CORDOBA			2216
+irvine			MACH_IRVINE		IRVINE			2217
+sff772			MACH_SFF772		SFF772			2218
+pelco_milano		MACH_PELCO_MILANO	PELCO_MILANO		2219
+pc7302			MACH_PC7302		PC7302			2220
+bip6000			MACH_BIP6000		BIP6000			2221
+silvermoon		MACH_SILVERMOON		SILVERMOON		2222
+vc0830			MACH_VC0830		VC0830			2223
+dt430			MACH_DT430		DT430			2224
+ji42pf			MACH_JI42PF		JI42PF			2225
+gnet_ksm		MACH_GNET_KSM		GNET_KSM		2226
+gnet_sgm		MACH_GNET_SGM		GNET_SGM		2227
+gnet_sgr		MACH_GNET_SGR		GNET_SGR		2228
+omap3_icetekevm		MACH_OMAP3_ICETEKEVM	OMAP3_ICETEKEVM		2229
+pnp			MACH_PNP		PNP			2230
+ctera_2bay_k		MACH_CTERA_2BAY_K	CTERA_2BAY_K		2231
+ctera_2bay_u		MACH_CTERA_2BAY_U	CTERA_2BAY_U		2232
+sas_c			MACH_SAS_C		SAS_C			2233
+vma2315			MACH_VMA2315		VMA2315			2234
+vcs			MACH_VCS		VCS			2235
+spear600		MACH_SPEAR600		SPEAR600		2236
+spear300		MACH_SPEAR300		SPEAR300		2237
+spear1300		MACH_SPEAR1300		SPEAR1300		2238
+lilly1131		MACH_LILLY1131		LILLY1131		2239
+arvoo_ax301		MACH_ARVOO_AX301	ARVOO_AX301		2240
+mapphone		MACH_MAPPHONE		MAPPHONE		2241
+legend			MACH_LEGEND		LEGEND			2242
+salsa			MACH_SALSA		SALSA			2243
+lounge			MACH_LOUNGE		LOUNGE			2244
+vision			MACH_VISION		VISION			2245
+vmb20			MACH_VMB20		VMB20			2246
+hy2410			MACH_HY2410		HY2410			2247
+hy9315			MACH_HY9315		HY9315			2248
+bullwinkle		MACH_BULLWINKLE		BULLWINKLE		2249
+arm_ultimator2		MACH_ARM_ULTIMATOR2	ARM_ULTIMATOR2		2250
+vs_v210			MACH_VS_V210		VS_V210			2252
+vs_v212			MACH_VS_V212		VS_V212			2253
+hmt			MACH_HMT		HMT			2254
+km_kirkwood		MACH_KM_KIRKWOOD	KM_KIRKWOOD		2255
+vesper			MACH_VESPER		VESPER			2256
+str9			MACH_STR9		STR9			2257
+omap3_wl_ff		MACH_OMAP3_WL_FF	OMAP3_WL_FF		2258
+simcom			MACH_SIMCOM		SIMCOM			2259
+mcwebio			MACH_MCWEBIO		MCWEBIO			2260
+omap3_phrazer		MACH_OMAP3_PHRAZER	OMAP3_PHRAZER		2261
+darwin			MACH_DARWIN		DARWIN			2262
+oratiscomu		MACH_ORATISCOMU		ORATISCOMU		2263
+rtsbc20			MACH_RTSBC20		RTSBC20			2264
+sgh_i780		MACH_I780		I780			2265
+gemini324		MACH_GEMINI324		GEMINI324		2266
+oratislan		MACH_ORATISLAN		ORATISLAN		2267
+oratisalog		MACH_ORATISALOG		ORATISALOG		2268
+oratismadi		MACH_ORATISMADI		ORATISMADI		2269
+oratisot16		MACH_ORATISOT16		ORATISOT16		2270
+oratisdesk		MACH_ORATISDESK		ORATISDESK		2271
+vexpress		MACH_VEXPRESS		VEXPRESS		2272
+sintexo			MACH_SINTEXO		SINTEXO			2273
+cm3389			MACH_CM3389		CM3389			2274
+omap3_cio		MACH_OMAP3_CIO		OMAP3_CIO		2275
+sgh_i900		MACH_SGH_I900		SGH_I900		2276
+bst100			MACH_BST100		BST100			2277
+passion			MACH_PASSION		PASSION			2278
+indesign_at91sam	MACH_INDESIGN_AT91SAM	INDESIGN_AT91SAM	2279
+c4_badger		MACH_C4_BADGER		C4_BADGER		2280
+c4_viper		MACH_C4_VIPER		C4_VIPER		2281
+d2net			MACH_D2NET		D2NET			2282
+bigdisk			MACH_BIGDISK		BIGDISK			2283
+notalvision		MACH_NOTALVISION	NOTALVISION		2284
+omap3_kboc		MACH_OMAP3_KBOC		OMAP3_KBOC		2285
+cyclone			MACH_CYCLONE		CYCLONE			2286
+ninja			MACH_NINJA		NINJA			2287
+at91sam9g20ek_2mmc	MACH_AT91SAM9G20EK_2MMC	AT91SAM9G20EK_2MMC	2288
+bcmring			MACH_BCMRING		BCMRING			2289
+resol_dl2		MACH_RESOL_DL2		RESOL_DL2		2290
+ifosw			MACH_IFOSW		IFOSW			2291
+htcrhodium		MACH_HTCRHODIUM		HTCRHODIUM		2292
+htctopaz		MACH_HTCTOPAZ		HTCTOPAZ		2293
+matrix504		MACH_MATRIX504		MATRIX504		2294
+mrfsa			MACH_MRFSA		MRFSA			2295
+sc_p270			MACH_SC_P270		SC_P270			2296
+atlas5_evb		MACH_ATLAS5_EVB		ATLAS5_EVB		2297
+pelco_lobox		MACH_PELCO_LOBOX	PELCO_LOBOX		2298
+dilax_pcu200		MACH_DILAX_PCU200	DILAX_PCU200		2299
+leonardo		MACH_LEONARDO		LEONARDO		2300
+zoran_approach7		MACH_ZORAN_APPROACH7	ZORAN_APPROACH7		2301
+dp6xx			MACH_DP6XX		DP6XX			2302
+bcm2153_vesper		MACH_BCM2153_VESPER	BCM2153_VESPER		2303
+mahimahi		MACH_MAHIMAHI		MAHIMAHI		2304
+clickc			MACH_CLICKC		CLICKC			2305
+zb_gateway		MACH_ZB_GATEWAY		ZB_GATEWAY		2306
+tazcard			MACH_TAZCARD		TAZCARD			2307
+tazdev			MACH_TAZDEV		TAZDEV			2308
+annax_cb_arm		MACH_ANNAX_CB_ARM	ANNAX_CB_ARM		2309
+annax_dm3		MACH_ANNAX_DM3		ANNAX_DM3		2310
+cerebric		MACH_CEREBRIC		CEREBRIC		2311
+orca			MACH_ORCA		ORCA			2312
+pc9260			MACH_PC9260		PC9260			2313
+ems285a			MACH_EMS285A		EMS285A			2314
+gec2410			MACH_GEC2410		GEC2410			2315
+gec2440			MACH_GEC2440		GEC2440			2316
+mw903			MACH_ARCH_MW903		ARCH_MW903		2317
+mw2440			MACH_MW2440		MW2440			2318
+ecac2378		MACH_ECAC2378		ECAC2378		2319
+tazkiosk		MACH_TAZKIOSK		TAZKIOSK		2320
+whiterabbit_mch		MACH_WHITERABBIT_MCH	WHITERABBIT_MCH		2321
+sbox9263		MACH_SBOX9263		SBOX9263		2322
+smdk6442		MACH_SMDK6442		SMDK6442		2324
+openrd_base		MACH_OPENRD_BASE	OPENRD_BASE		2325
+incredible		MACH_INCREDIBLE		INCREDIBLE		2326
+incrediblec		MACH_INCREDIBLEC	INCREDIBLEC		2327
+heroct			MACH_HEROCT		HEROCT			2328
+mmnet1000		MACH_MMNET1000		MMNET1000		2329
+devkit8000		MACH_DEVKIT8000		DEVKIT8000		2330
+devkit9000		MACH_DEVKIT9000		DEVKIT9000		2331
+mx31txtr		MACH_MX31TXTR		MX31TXTR		2332
+u380			MACH_U380		U380			2333
+oamp3_hualu		MACH_HUALU_BOARD	HUALU_BOARD		2334
+npcmx50			MACH_NPCMX50		NPCMX50			2335
+mx51_efikamx		MACH_MX51_EFIKAMX	MX51_EFIKAMX		2336
+mx51_lange52		MACH_MX51_LANGE52	MX51_LANGE52		2337
+riom			MACH_RIOM		RIOM			2338
+comcas			MACH_COMCAS		COMCAS			2339
+wsi_mx27		MACH_WSI_MX27		WSI_MX27		2340
+cm_t35			MACH_CM_T35		CM_T35			2341
+net2big			MACH_NET2BIG		NET2BIG			2342
+motorola_a1600		MACH_MOTOROLA_A1600	MOTOROLA_A1600		2343
+igep0020		MACH_IGEP0020		IGEP0020		2344
+igep0010		MACH_IGEP0010		IGEP0010		2345
+mv6281gtwge2		MACH_MV6281GTWGE2	MV6281GTWGE2		2346
+scat100			MACH_SCAT100		SCAT100			2347
+sanmina			MACH_SANMINA		SANMINA			2348
+momento			MACH_MOMENTO		MOMENTO			2349
+nuc9xx			MACH_NUC9XX		NUC9XX			2350
+nuc910evb		MACH_NUC910EVB		NUC910EVB		2351
+nuc920evb		MACH_NUC920EVB		NUC920EVB		2352
+nuc950evb		MACH_NUC950EVB		NUC950EVB		2353
+nuc945evb		MACH_NUC945EVB		NUC945EVB		2354
+nuc960evb		MACH_NUC960EVB		NUC960EVB		2355
+nuc932evb		MACH_NUC932EVB		NUC932EVB		2356
+nuc900			MACH_NUC900		NUC900			2357
+sd1soc			MACH_SD1SOC		SD1SOC			2358
+ln2440bc		MACH_LN2440BC		LN2440BC		2359
+rsbc			MACH_RSBC		RSBC			2360
+openrd_client		MACH_OPENRD_CLIENT	OPENRD_CLIENT		2361
+hpipaq11x		MACH_HPIPAQ11X		HPIPAQ11X		2362
+wayland			MACH_WAYLAND		WAYLAND			2363
+acnbsx102		MACH_ACNBSX102		ACNBSX102		2364
+hwat91			MACH_HWAT91		HWAT91			2365
+at91sam9263cs		MACH_AT91SAM9263CS	AT91SAM9263CS		2366
+csb732			MACH_CSB732		CSB732			2367
+u8500			MACH_U8500		U8500			2368
+huqiu			MACH_HUQIU		HUQIU			2369
+mx51_efikasb		MACH_MX51_EFIKASB	MX51_EFIKASB		2370
+pmt1g			MACH_PMT1G		PMT1G			2371
+htcelf			MACH_HTCELF		HTCELF			2372
+armadillo420		MACH_ARMADILLO420	ARMADILLO420		2373
+armadillo440		MACH_ARMADILLO440	ARMADILLO440		2374
+u_chip_dual_arm		MACH_U_CHIP_DUAL_ARM	U_CHIP_DUAL_ARM		2375
+csr_bdb3		MACH_CSR_BDB3		CSR_BDB3		2376
+dolby_cat1018		MACH_DOLBY_CAT1018	DOLBY_CAT1018		2377
+hy9307			MACH_HY9307		HY9307			2378
+aspire_easystore	MACH_A_ES		A_ES			2379
+davinci_irif		MACH_DAVINCI_IRIF	DAVINCI_IRIF		2380
+agama9263		MACH_AGAMA9263		AGAMA9263		2381
+marvell_jasper		MACH_MARVELL_JASPER	MARVELL_JASPER		2382
+flint			MACH_FLINT		FLINT			2383
+tavorevb3		MACH_TAVOREVB3		TAVOREVB3		2384
+sch_m490		MACH_SCH_M490		SCH_M490		2386
+rbl01			MACH_RBL01		RBL01			2387
+omnifi			MACH_OMNIFI		OMNIFI			2388
+otavalo			MACH_OTAVALO		OTAVALO			2389
+htc_excalibur_s620	MACH_HTC_EXCALIBUR_S620	HTC_EXCALIBUR_S620	2391
+htc_opal		MACH_HTC_OPAL		HTC_OPAL		2392
+touchbook		MACH_TOUCHBOOK		TOUCHBOOK		2393
+latte			MACH_LATTE		LATTE			2394
+xa200			MACH_XA200		XA200			2395
+nimrod			MACH_NIMROD		NIMROD			2396
+cc9p9215_3g		MACH_CC9P9215_3G	CC9P9215_3G		2397
+cc9p9215_3gjs		MACH_CC9P9215_3GJS	CC9P9215_3GJS		2398
+tk71			MACH_TK71		TK71			2399
+comham3525		MACH_COMHAM3525		COMHAM3525		2400
+mx31erebus		MACH_MX31EREBUS		MX31EREBUS		2401
+mcardmx27		MACH_MCARDMX27		MCARDMX27		2402
+paradise		MACH_PARADISE		PARADISE		2403
+tide			MACH_TIDE		TIDE			2404
+wzl2440			MACH_WZL2440		WZL2440			2405
+sdrdemo			MACH_SDRDEMO		SDRDEMO			2406
+ethercan2		MACH_ETHERCAN2		ETHERCAN2		2407
+ecmimg20		MACH_ECMIMG20		ECMIMG20		2408
+omap_dragon		MACH_OMAP_DRAGON	OMAP_DRAGON		2409
+halo			MACH_HALO		HALO			2410
+huangshan		MACH_HUANGSHAN		HUANGSHAN		2411
+vl_ma2sc		MACH_VL_MA2SC		VL_MA2SC		2412
+raumfeld_rc		MACH_RAUMFELD_RC	RAUMFELD_RC		2413
+raumfeld_connector	MACH_RAUMFELD_CONNECTOR	RAUMFELD_CONNECTOR	2414
+raumfeld_speaker	MACH_RAUMFELD_SPEAKER	RAUMFELD_SPEAKER	2415
+multibus_master		MACH_MULTIBUS_MASTER	MULTIBUS_MASTER		2416
+multibus_pbk		MACH_MULTIBUS_PBK	MULTIBUS_PBK		2417
+tnetv107x		MACH_TNETV107X		TNETV107X		2418
+snake			MACH_SNAKE		SNAKE			2419
+cwmx27			MACH_CWMX27		CWMX27			2420
+sch_m480		MACH_SCH_M480		SCH_M480		2421
+platypus		MACH_PLATYPUS		PLATYPUS		2422
+pss2			MACH_PSS2		PSS2			2423
+davinci_apm150		MACH_DAVINCI_APM150	DAVINCI_APM150		2424
+str9100			MACH_STR9100		STR9100			2425
+net5big			MACH_NET5BIG		NET5BIG			2426
+seabed9263		MACH_SEABED9263		SEABED9263		2427
+mx51_m2id		MACH_MX51_M2ID		MX51_M2ID		2428
+octvocplus_eb		MACH_OCTVOCPLUS_EB	OCTVOCPLUS_EB		2429
+klk_firefox		MACH_KLK_FIREFOX	KLK_FIREFOX		2430
+klk_wirma_module	MACH_KLK_WIRMA_MODULE	KLK_WIRMA_MODULE	2431
+klk_wirma_mmi		MACH_KLK_WIRMA_MMI	KLK_WIRMA_MMI		2432
+supersonic		MACH_SUPERSONIC		SUPERSONIC		2433
+liberty			MACH_LIBERTY		LIBERTY			2434
+mh355			MACH_MH355		MH355			2435
+pc7802			MACH_PC7802		PC7802			2436
+gnet_sgc		MACH_GNET_SGC		GNET_SGC		2437
+einstein15		MACH_EINSTEIN15		EINSTEIN15		2438
+cmpd			MACH_CMPD		CMPD			2439
+davinci_hase1		MACH_DAVINCI_HASE1	DAVINCI_HASE1		2440
+lgeincitephone		MACH_LGEINCITEPHONE	LGEINCITEPHONE		2441
+ea313x			MACH_EA313X		EA313X			2442
+fwbd_39064		MACH_FWBD_39064		FWBD_39064		2443
+fwbd_390128		MACH_FWBD_390128	FWBD_390128		2444
+pelco_moe		MACH_PELCO_MOE		PELCO_MOE		2445
+minimix27		MACH_MINIMIX27		MINIMIX27		2446
+omap3_thunder		MACH_OMAP3_THUNDER	OMAP3_THUNDER		2447
+passionc		MACH_PASSIONC		PASSIONC		2448
+mx27amata		MACH_MX27AMATA		MX27AMATA		2449
+bgat1			MACH_BGAT1		BGAT1			2450
+buzz			MACH_BUZZ		BUZZ			2451
+mb9g20			MACH_MB9G20		MB9G20			2452
+yushan			MACH_YUSHAN		YUSHAN			2453
+lizard			MACH_LIZARD		LIZARD			2454
+omap3polycom		MACH_OMAP3POLYCOM	OMAP3POLYCOM		2455
+smdkv210		MACH_SMDKV210		SMDKV210		2456
+bravo			MACH_BRAVO		BRAVO			2457
+siogentoo1		MACH_SIOGENTOO1		SIOGENTOO1		2458
+siogentoo2		MACH_SIOGENTOO2		SIOGENTOO2		2459
+sm3k			MACH_SM3K		SM3K			2460
+acer_tempo_f900		MACH_ACER_TEMPO_F900	ACER_TEMPO_F900		2461
+glittertind		MACH_GLITTERTIND	GLITTERTIND		2463
+omap_zoom3		MACH_OMAP_ZOOM3		OMAP_ZOOM3		2464
+omap_3630sdp		MACH_OMAP_3630SDP	OMAP_3630SDP		2465
+cybook2440		MACH_CYBOOK2440		CYBOOK2440		2466
+torino_s		MACH_TORINO_S		TORINO_S		2467
+havana			MACH_HAVANA		HAVANA			2468
+beaumont_11		MACH_BEAUMONT_11	BEAUMONT_11		2469
+vanguard		MACH_VANGUARD		VANGUARD		2470
+s5pc110_draco		MACH_S5PC110_DRACO	S5PC110_DRACO		2471
+cartesio_two		MACH_CARTESIO_TWO	CARTESIO_TWO		2472
+aster			MACH_ASTER		ASTER			2473
+voguesv210		MACH_VOGUESV210		VOGUESV210		2474
+acm500x			MACH_ACM500X		ACM500X			2475
+km9260			MACH_KM9260		KM9260			2476
+nideflexg1		MACH_NIDEFLEXG1		NIDEFLEXG1		2477
+ctera_plug_io		MACH_CTERA_PLUG_IO	CTERA_PLUG_IO		2478
+smartq7			MACH_SMARTQ7		SMARTQ7			2479
+at91sam9g10ek2		MACH_AT91SAM9G10EK2	AT91SAM9G10EK2		2480
+asusp527		MACH_ASUSP527		ASUSP527		2481
+at91sam9g20mpm2		MACH_AT91SAM9G20MPM2	AT91SAM9G20MPM2		2482
+topasa900		MACH_TOPASA900		TOPASA900		2483
+electrum_100		MACH_ELECTRUM_100	ELECTRUM_100		2484
+mx51grb			MACH_MX51GRB		MX51GRB			2485
+xea300			MACH_XEA300		XEA300			2486
+htcstartrek		MACH_HTCSTARTREK	HTCSTARTREK		2487
+lima			MACH_LIMA		LIMA			2488
+csb740			MACH_CSB740		CSB740			2489
+usb_s8815		MACH_USB_S8815		USB_S8815		2490
+watson_efm_plugin	MACH_WATSON_EFM_PLUGIN	WATSON_EFM_PLUGIN	2491
+milkyway		MACH_MILKYWAY		MILKYWAY		2492
+g4evm			MACH_G4EVM		G4EVM			2493
+picomod6		MACH_PICOMOD6		PICOMOD6		2494
+omapl138_hawkboard	MACH_OMAPL138_HAWKBOARD	OMAPL138_HAWKBOARD	2495
+ip6000			MACH_IP6000		IP6000			2496
+ip6010			MACH_IP6010		IP6010			2497
+utm400			MACH_UTM400		UTM400			2498
+omap3_zybex		MACH_OMAP3_ZYBEX	OMAP3_ZYBEX		2499
+wireless_space		MACH_WIRELESS_SPACE	WIRELESS_SPACE		2500
+sx560			MACH_SX560		SX560			2501
+ts41x			MACH_TS41X		TS41X			2502
+elphel10373		MACH_ELPHEL10373	ELPHEL10373		2503
+rhobot			MACH_RHOBOT		RHOBOT			2504
+mx51_refresh		MACH_MX51_REFRESH	MX51_REFRESH		2505
+ls9260			MACH_LS9260		LS9260			2506
+shank			MACH_SHANK		SHANK			2507
+qsd8x50_st1		MACH_QSD8X50_ST1	QSD8X50_ST1		2508
+at91sam9m10ekes		MACH_AT91SAM9M10EKES	AT91SAM9M10EKES		2509
+hiram			MACH_HIRAM		HIRAM			2510
+phy3250			MACH_PHY3250		PHY3250			2511
+ea3250			MACH_EA3250		EA3250			2512
+fdi3250			MACH_FDI3250		FDI3250			2513
+at91sam9263nit		MACH_AT91SAM9263NIT	AT91SAM9263NIT		2515
+ccmx51			MACH_CCMX51		CCMX51			2516
+ccmx51js		MACH_CCMX51JS		CCMX51JS		2517
+ccwmx51			MACH_CCWMX51		CCWMX51			2518
+ccwmx51js		MACH_CCWMX51JS		CCWMX51JS		2519
+mini6410		MACH_MINI6410		MINI6410		2520
+tiny6410		MACH_TINY6410		TINY6410		2521
+nano6410		MACH_NANO6410		NANO6410		2522
+at572d940hfnldb		MACH_AT572D940HFNLDB	AT572D940HFNLDB		2523
+htcleo			MACH_HTCLEO		HTCLEO			2524
+avp13			MACH_AVP13		AVP13			2525
+xxsvideod		MACH_XXSVIDEOD		XXSVIDEOD		2526
+vpnext			MACH_VPNEXT		VPNEXT			2527
+swarco_itc3		MACH_SWARCO_ITC3	SWARCO_ITC3		2528
+tx51			MACH_TX51		TX51			2529
+dolby_cat1021		MACH_DOLBY_CAT1021	DOLBY_CAT1021		2530
+mx28evk			MACH_MX28EVK		MX28EVK			2531
+phoenix260		MACH_PHOENIX260		PHOENIX260		2532
+uvaca_stork		MACH_UVACA_STORK	UVACA_STORK		2533
+smartq5			MACH_SMARTQ5		SMARTQ5			2534
+all3078			MACH_ALL3078		ALL3078			2535
+ctera_2bay_ds		MACH_CTERA_2BAY_DS	CTERA_2BAY_DS		2536
+siogentoo3		MACH_SIOGENTOO3		SIOGENTOO3		2537
+epb5000			MACH_EPB5000		EPB5000			2538
+hy9263			MACH_HY9263		HY9263			2539
+acer_tempo_m900		MACH_ACER_TEMPO_M900	ACER_TEMPO_M900		2540
+acer_tempo_dx650	MACH_ACER_TEMPO_DX900	ACER_TEMPO_DX900	2541
+acer_tempo_x960		MACH_ACER_TEMPO_X960	ACER_TEMPO_X960		2542
+acer_eten_v900		MACH_ACER_ETEN_V900	ACER_ETEN_V900		2543
+acer_eten_x900		MACH_ACER_ETEN_X900	ACER_ETEN_X900		2544
+bonnell			MACH_BONNELL		BONNELL			2545
+oht_mx27		MACH_OHT_MX27		OHT_MX27		2546
+htcquartz		MACH_HTCQUARTZ		HTCQUARTZ		2547
+davinci_dm6467tevm	MACH_DAVINCI_DM6467TEVM	DAVINCI_DM6467TEVM	2548
+c3ax03			MACH_C3AX03		C3AX03			2549
+mxt_td60		MACH_MXT_TD60		MXT_TD60		2550
+esyx			MACH_ESYX		ESYX			2551
+dove_db2		MACH_DOVE_DB2		DOVE_DB2		2552
+bulldog			MACH_BULLDOG		BULLDOG			2553
+derell_me2000		MACH_DERELL_ME2000	DERELL_ME2000		2554
+bcmring_base		MACH_BCMRING_BASE	BCMRING_BASE		2555
+bcmring_evm		MACH_BCMRING_EVM	BCMRING_EVM		2556
+bcmring_evm_jazz	MACH_BCMRING_EVM_JAZZ	BCMRING_EVM_JAZZ	2557
+bcmring_sp		MACH_BCMRING_SP		BCMRING_SP		2558
+bcmring_sv		MACH_BCMRING_SV		BCMRING_SV		2559
+bcmring_sv_jazz		MACH_BCMRING_SV_JAZZ	BCMRING_SV_JAZZ		2560
+bcmring_tablet		MACH_BCMRING_TABLET	BCMRING_TABLET		2561
+bcmring_vp		MACH_BCMRING_VP		BCMRING_VP		2562
+bcmring_evm_seikor	MACH_BCMRING_EVM_SEIKOR	BCMRING_EVM_SEIKOR	2563
+bcmring_sp_wqvga	MACH_BCMRING_SP_WQVGA	BCMRING_SP_WQVGA	2564
+bcmring_custom		MACH_BCMRING_CUSTOM	BCMRING_CUSTOM		2565
+acer_s200		MACH_ACER_S200		ACER_S200		2566
+bt270			MACH_BT270		BT270			2567
+iseo			MACH_ISEO		ISEO			2568
+cezanne			MACH_CEZANNE		CEZANNE			2569
+lucca			MACH_LUCCA		LUCCA			2570
+supersmart		MACH_SUPERSMART		SUPERSMART		2571
+arm11_board		MACH_CS_MISANO		CS_MISANO		2572
+magnolia2		MACH_MAGNOLIA2		MAGNOLIA2		2573
+emxx			MACH_EMXX		EMXX			2574
+outlaw			MACH_OUTLAW		OUTLAW			2575
+riot_bei2		MACH_RIOT_BEI2		RIOT_BEI2		2576
+riot_gx2		MACH_RIOT_VOX		RIOT_VOX		2577
+riot_x37		MACH_RIOT_X37		RIOT_X37		2578
+mega25mx		MACH_MEGA25MX		MEGA25MX		2579
+benzina2		MACH_BENZINA2		BENZINA2		2580
+ignite			MACH_IGNITE		IGNITE			2581
+foggia			MACH_FOGGIA		FOGGIA			2582
+arezzo			MACH_AREZZO		AREZZO			2583
+leica_skywalker		MACH_LEICA_SKYWALKER	LEICA_SKYWALKER		2584
+jacinto2_jamr		MACH_JACINTO2_JAMR	JACINTO2_JAMR		2585
+gts_nova		MACH_GTS_NOVA		GTS_NOVA		2586
+p3600			MACH_P3600		P3600			2587
+dlt2			MACH_DLT2		DLT2			2588
+df3120			MACH_DF3120		DF3120			2589
+ecucore_9g20		MACH_ECUCORE_9G20	ECUCORE_9G20		2590
+nautel_am35xx		MACH_NAUTEL_LPC3240	NAUTEL_LPC3240		2591
+glacier			MACH_GLACIER		GLACIER			2592
+phrazer_bulldog		MACH_PHRAZER_BULLDOG	PHRAZER_BULLDOG		2593
+omap3_bulldog		MACH_OMAP3_BULLDOG	OMAP3_BULLDOG		2594
+pca101			MACH_PCA101		PCA101			2595
+buzzc			MACH_BUZZC		BUZZC			2596
+sasie2			MACH_SASIE2		SASIE2			2597
+smartmeter_dl		MACH_SMARTMETER_DL	SMARTMETER_DL		2599
+wzl6410			MACH_WZL6410		WZL6410			2600
+wzl6410m		MACH_WZL6410M		WZL6410M		2601
+wzl6410f		MACH_WZL6410F		WZL6410F		2602
+wzl6410i		MACH_WZL6410I		WZL6410I		2603
+spacecom1		MACH_SPACECOM1		SPACECOM1		2604
+pingu920		MACH_PINGU920		PINGU920		2605
+bravoc			MACH_BRAVOC		BRAVOC			2606
+vdssw			MACH_VDSSW		VDSSW			2608
+romulus			MACH_ROMULUS		ROMULUS			2609
+omap_magic		MACH_OMAP_MAGIC		OMAP_MAGIC		2610
+eltd100			MACH_ELTD100		ELTD100			2611
+capc7117		MACH_CAPC7117		CAPC7117		2612
+swan			MACH_SWAN		SWAN			2613
+veu			MACH_VEU		VEU			2614
+rm2			MACH_RM2		RM2			2615
+tt2100			MACH_TT2100		TT2100			2616
+venice			MACH_VENICE		VENICE			2617
+pc7323			MACH_PC7323		PC7323			2618
+masp			MACH_MASP		MASP			2619
+fujitsu_tvstbsoc0	MACH_FUJITSU_TVSTBSOC	FUJITSU_TVSTBSOC	2620
+fujitsu_tvstbsoc1	MACH_FUJITSU_TVSTBSOC1	FUJITSU_TVSTBSOC1	2621
+lexikon			MACH_LEXIKON		LEXIKON			2622
+mini2440v2		MACH_MINI2440V2		MINI2440V2		2623
+icontrol		MACH_ICONTROL		ICONTROL		2624
+gplugd			MACH_GPLUGD		GPLUGD			2625
+qsd8x50a_st1_1		MACH_QSD8X50A_ST1_1	QSD8X50A_ST1_1		2626
+qsd8x50a_st1_5		MACH_QSD8X50A_ST1_5	QSD8X50A_ST1_5		2627
+bee			MACH_BEE		BEE			2628
+mx23evk			MACH_MX23EVK		MX23EVK			2629
+ap4evb			MACH_AP4EVB		AP4EVB			2630
+stockholm		MACH_STOCKHOLM		STOCKHOLM		2631
+lpc_h3131		MACH_LPC_H3131		LPC_H3131		2632
+stingray		MACH_STINGRAY		STINGRAY		2633
+kraken			MACH_KRAKEN		KRAKEN			2634
+gw2388			MACH_GW2388		GW2388			2635
+jadecpu			MACH_JADECPU		JADECPU			2636
+carlisle		MACH_CARLISLE		CARLISLE		2637
+lux_sf9			MACH_LUX_SF9		LUX_SF9			2638
+nemid_tb		MACH_NEMID_TB		NEMID_TB		2639
+terrier			MACH_TERRIER		TERRIER			2640
+turbot			MACH_TURBOT		TURBOT			2641
+sanddab			MACH_SANDDAB		SANDDAB			2642
+mx35_cicada		MACH_MX35_CICADA	MX35_CICADA		2643
+ghi2703d		MACH_GHI2703D		GHI2703D		2644
+lux_sfx9		MACH_LUX_SFX9		LUX_SFX9		2645
+lux_sf9g		MACH_LUX_SF9G		LUX_SF9G		2646
+lux_edk9		MACH_LUX_EDK9		LUX_EDK9		2647
+hw90240			MACH_HW90240		HW90240			2648
+dm365_leopard		MACH_DM365_LEOPARD	DM365_LEOPARD		2649
+mityomapl138		MACH_MITYOMAPL138	MITYOMAPL138		2650
+scat110			MACH_SCAT110		SCAT110			2651
+acer_a1			MACH_ACER_A1		ACER_A1			2652
+cmcontrol		MACH_CMCONTROL		CMCONTROL		2653
+pelco_lamar		MACH_PELCO_LAMAR	PELCO_LAMAR		2654
+rfp43			MACH_RFP43		RFP43			2655
+sk86r0301		MACH_SK86R0301		SK86R0301		2656
+ctpxa			MACH_CTPXA		CTPXA			2657
+epb_arm9_a		MACH_EPB_ARM9_A		EPB_ARM9_A		2658
+guruplug		MACH_GURUPLUG		GURUPLUG		2659
+spear310		MACH_SPEAR310		SPEAR310		2660
+spear320		MACH_SPEAR320		SPEAR320		2661
+robotx			MACH_ROBOTX		ROBOTX			2662
+lsxhl			MACH_LSXHL		LSXHL			2663
+smartlite		MACH_SMARTLITE		SMARTLITE		2664
+cws2			MACH_CWS2		CWS2			2665
+m619			MACH_M619		M619			2666
+smartview		MACH_SMARTVIEW		SMARTVIEW		2667
+lsa_salsa		MACH_LSA_SALSA		LSA_SALSA		2668
+kizbox			MACH_KIZBOX		KIZBOX			2669
+htccharmer		MACH_HTCCHARMER		HTCCHARMER		2670
+guf_neso_lt		MACH_GUF_NESO_LT	GUF_NESO_LT		2671
+pm9g45			MACH_PM9G45		PM9G45			2672
+htcpanther		MACH_HTCPANTHER		HTCPANTHER		2673
+htcpanther_cdma		MACH_HTCPANTHER_CDMA	HTCPANTHER_CDMA		2674
+reb01			MACH_REB01		REB01			2675
+aquila			MACH_AQUILA		AQUILA			2676
+spark_sls_hw2		MACH_SPARK_SLS_HW2	SPARK_SLS_HW2		2677
+esata_sheevaplug	MACH_ESATA_SHEEVAPLUG	ESATA_SHEEVAPLUG	2678
+msm7x30_surf		MACH_MSM7X30_SURF	MSM7X30_SURF		2679
+micro2440		MACH_MICRO2440		MICRO2440		2680
+am2440			MACH_AM2440		AM2440			2681
+tq2440			MACH_TQ2440		TQ2440			2682
+ea2478devkit		MACH_EA2478DEVKIT	EA2478DEVKIT		2683
+ak880x			MACH_AK880X		AK880X			2684
+cobra3530		MACH_COBRA3530		COBRA3530		2685
+pmppb			MACH_PMPPB		PMPPB			2686
+u6715			MACH_U6715		U6715			2687
+axar1500_sender		MACH_AXAR1500_SENDER	AXAR1500_SENDER		2688
+g30_dvb			MACH_G30_DVB		G30_DVB			2689
+vc088x			MACH_VC088X		VC088X			2690
+mioa702			MACH_MIOA702		MIOA702			2691
+hpmin			MACH_HPMIN		HPMIN			2692
+ak880xak		MACH_AK880XAK		AK880XAK		2693
+arm926tomap850		MACH_ARM926TOMAP850	ARM926TOMAP850		2694
+lkevm			MACH_LKEVM		LKEVM			2695
+mw6410			MACH_MW6410		MW6410			2696
+terastation_wxl		MACH_TERASTATION_WXL	TERASTATION_WXL		2697
+cpu8000e		MACH_CPU8000E		CPU8000E		2698
+tokyo			MACH_TOKYO		TOKYO			2700
+msm7201a_surf		MACH_MSM7201A_SURF	MSM7201A_SURF		2701
+msm7201a_ffa		MACH_MSM7201A_FFA	MSM7201A_FFA		2702
+msm7x25_surf		MACH_MSM7X25_SURF	MSM7X25_SURF		2703
+msm7x25_ffa		MACH_MSM7X25_FFA	MSM7X25_FFA		2704
+msm7x27_surf		MACH_MSM7X27_SURF	MSM7X27_SURF		2705
+msm7x27_ffa		MACH_MSM7X27_FFA	MSM7X27_FFA		2706
+msm7x30_ffa		MACH_MSM7X30_FFA	MSM7X30_FFA		2707
+qsd8x50_surf		MACH_QSD8X50_SURF	QSD8X50_SURF		2708
+qsd8x50_comet		MACH_QSD8X50_COMET	QSD8X50_COMET		2709
+qsd8x50_ffa		MACH_QSD8X50_FFA	QSD8X50_FFA		2710
+qsd8x50a_surf		MACH_QSD8X50A_SURF	QSD8X50A_SURF		2711
+qsd8x50a_ffa		MACH_QSD8X50A_FFA	QSD8X50A_FFA		2712
+adx_xgcp10		MACH_ADX_XGCP10		ADX_XGCP10		2713
+mcgwumts2a		MACH_MCGWUMTS2A		MCGWUMTS2A		2714
+mobikt			MACH_MOBIKT		MOBIKT			2715
+mx53_evk		MACH_MX53_EVK		MX53_EVK		2716
+igep0030		MACH_IGEP0030		IGEP0030		2717
+axell_h40_h50_ctrl	MACH_AXELL_H40_H50_CTRL	AXELL_H40_H50_CTRL	2718
+dtcommod		MACH_DTCOMMOD		DTCOMMOD		2719
+gould			MACH_GOULD		GOULD			2720
+siberia			MACH_SIBERIA		SIBERIA			2721
+sbc3530			MACH_SBC3530		SBC3530			2722
+qarm			MACH_QARM		QARM			2723
+mips			MACH_MIPS		MIPS			2724
+mx27grb			MACH_MX27GRB		MX27GRB			2725
+sbc8100			MACH_SBC8100		SBC8100			2726
+saarb			MACH_SAARB		SAARB			2727
+omap3mini		MACH_OMAP3MINI		OMAP3MINI		2728
+cnmbook7se		MACH_CNMBOOK7SE		CNMBOOK7SE		2729
+catan			MACH_CATAN		CATAN			2730
+harmony			MACH_HARMONY		HARMONY			2731
+tonga			MACH_TONGA		TONGA			2732
+cybook_orizon		MACH_CYBOOK_ORIZON	CYBOOK_ORIZON		2733
+htcrhodiumcdma		MACH_HTCRHODIUMCDMA	HTCRHODIUMCDMA		2734
+epc_g45			MACH_EPC_G45		EPC_G45			2735
+epc_lpc3250		MACH_EPC_LPC3250	EPC_LPC3250		2736
+mxc91341evb		MACH_MXC91341EVB	MXC91341EVB		2737
+rtw1000			MACH_RTW1000		RTW1000			2738
+bobcat			MACH_BOBCAT		BOBCAT			2739
+trizeps6		MACH_TRIZEPS6		TRIZEPS6		2740
+msm7x30_fluid		MACH_MSM7X30_FLUID	MSM7X30_FLUID		2741
+nedap9263		MACH_NEDAP9263		NEDAP9263		2742
+netgear_ms2110		MACH_NETGEAR_MS2110	NETGEAR_MS2110		2743
+bmx			MACH_BMX		BMX			2744
+netstream		MACH_NETSTREAM		NETSTREAM		2745
+vpnext_rcu		MACH_VPNEXT_RCU		VPNEXT_RCU		2746
+vpnext_mpu		MACH_VPNEXT_MPU		VPNEXT_MPU		2747
+bcmring_tablet_v1	MACH_BCMRING_TABLET_V1	BCMRING_TABLET_V1	2748
+sgarm10			MACH_SGARM10		SGARM10			2749
+cm_t3517		MACH_CM_T3517		CM_T3517		2750
+dig297			MACH_OMAP3_CPS		OMAP3_CPS		2751
+axar1500_receiver	MACH_AXAR1500_RECEIVER	AXAR1500_RECEIVER	2752
+wbd222			MACH_WBD222		WBD222			2753
+mt65xx			MACH_MT65XX		MT65XX			2754
+msm8x60_surf		MACH_MSM8X60_SURF	MSM8X60_SURF		2755
+msm8x60_sim		MACH_MSM8X60_SIM	MSM8X60_SIM		2756
+tcc8000_sdk		MACH_TCC8000_SDK	TCC8000_SDK		2758
+nanos			MACH_NANOS		NANOS			2759
+stamp9g10		MACH_STAMP9G10		STAMP9G10		2760
+stamp9g45		MACH_STAMP9G45		STAMP9G45		2761
+h6053			MACH_H6053		H6053			2762
+smint01			MACH_SMINT01		SMINT01			2763
+prtlvt2			MACH_PRTLVT2		PRTLVT2			2764
+ap420			MACH_AP420		AP420			2765
+davinci_dm365_fc	MACH_DAVINCI_DM365_FC	DAVINCI_DM365_FC	2767
+msm8x55_surf		MACH_MSM8X55_SURF	MSM8X55_SURF		2768
+msm8x55_ffa		MACH_MSM8X55_FFA	MSM8X55_FFA		2769
+esl_vamana		MACH_ESL_VAMANA		ESL_VAMANA		2770
+sbc35			MACH_SBC35		SBC35			2771
+mpx6446			MACH_MPX6446		MPX6446			2772
+oreo_controller		MACH_OREO_CONTROLLER	OREO_CONTROLLER		2773
+kopin_models		MACH_KOPIN_MODELS	KOPIN_MODELS		2774
+ttc_vision2		MACH_TTC_VISION2	TTC_VISION2		2775
+cns3420vb		MACH_CNS3420VB		CNS3420VB		2776
+lpc_evo			MACH_LPC2		LPC2			2777
+olympus			MACH_OLYMPUS		OLYMPUS			2778
+vortex			MACH_VORTEX		VORTEX			2779
+s5pc200			MACH_S5PC200		S5PC200			2780
+ecucore_9263		MACH_ECUCORE_9263	ECUCORE_9263		2781
+smdkc200		MACH_SMDKC200		SMDKC200		2782
+emsiso_sx27		MACH_EMSISO_SX27	EMSISO_SX27		2783
+apx_som9g45_ek		MACH_APX_SOM9G45_EK	APX_SOM9G45_EK		2784
+songshan		MACH_SONGSHAN		SONGSHAN		2785
+tianshan		MACH_TIANSHAN		TIANSHAN		2786
+vpx500			MACH_VPX500		VPX500			2787
+am3517sam		MACH_AM3517SAM		AM3517SAM		2788
+skat91_sim508		MACH_SKAT91_SIM508	SKAT91_SIM508		2789
+skat91_s3e		MACH_SKAT91_S3E		SKAT91_S3E		2790
+omap4_panda		MACH_OMAP4_PANDA	OMAP4_PANDA		2791
+df7220			MACH_DF7220		DF7220			2792
+nemini			MACH_NEMINI		NEMINI			2793
+t8200			MACH_T8200		T8200			2794
+apf51			MACH_APF51		APF51			2795
+dr_rc_unit		MACH_DR_RC_UNIT		DR_RC_UNIT		2796
+bordeaux		MACH_BORDEAUX		BORDEAUX		2797
+catania_b		MACH_CATANIA_B		CATANIA_B		2798
+mx51_ocean		MACH_MX51_OCEAN		MX51_OCEAN		2799
+ti8168evm		MACH_TI8168EVM		TI8168EVM		2800
+neocoreomap		MACH_NEOCOREOMAP	NEOCOREOMAP		2801
+withings_wbp		MACH_WITHINGS_WBP	WITHINGS_WBP		2802
+dbps			MACH_DBPS		DBPS			2803
+pcbfp0001		MACH_PCBFP0001		PCBFP0001		2805
+speedy			MACH_SPEEDY		SPEEDY			2806
+chrysaor		MACH_CHRYSAOR		CHRYSAOR		2807
+tango			MACH_TANGO		TANGO			2808
+synology_dsx11		MACH_SYNOLOGY_DSX11	SYNOLOGY_DSX11		2809
+hanlin_v3ext		MACH_HANLIN_V3EXT	HANLIN_V3EXT		2810
+hanlin_v5		MACH_HANLIN_V5		HANLIN_V5		2811
+hanlin_v3plus		MACH_HANLIN_V3PLUS	HANLIN_V3PLUS		2812
+iriver_story		MACH_IRIVER_STORY	IRIVER_STORY		2813
+irex_iliad		MACH_IREX_ILIAD		IREX_ILIAD		2814
+irex_dr1000		MACH_IREX_DR1000	IREX_DR1000		2815
+teton_bga		MACH_TETON_BGA		TETON_BGA		2816
+snapper9g45		MACH_SNAPPER9G45	SNAPPER9G45		2817
+tam3517			MACH_TAM3517		TAM3517			2818
+pdc100			MACH_PDC100		PDC100			2819
+eukrea_cpuimx25sd	MACH_EUKREA_CPUIMX25SD	EUKREA_CPUIMX25SD	2820
+eukrea_cpuimx35sd	MACH_EUKREA_CPUIMX35SD	EUKREA_CPUIMX35SD	2821
+eukrea_cpuimx51sd	MACH_EUKREA_CPUIMX51SD	EUKREA_CPUIMX51SD	2822
+eukrea_cpuimx51		MACH_EUKREA_CPUIMX51	EUKREA_CPUIMX51		2823
+p565			MACH_P565		P565			2824
+acer_a4			MACH_ACER_A4		ACER_A4			2825
+davinci_dm368_bip	MACH_DAVINCI_DM368_BIP	DAVINCI_DM368_BIP	2826
+eshare			MACH_ESHARE		ESHARE			2827
+wlbargn			MACH_WLBARGN		WLBARGN			2829
+bm170			MACH_BM170		BM170			2830
+netspace_mini_v2	MACH_NETSPACE_MINI_V2	NETSPACE_MINI_V2	2831
+netspace_plug_v2	MACH_NETSPACE_PLUG_V2	NETSPACE_PLUG_V2	2832
+siemens_l1		MACH_SIEMENS_L1		SIEMENS_L1		2833
+elv_lcu1		MACH_ELV_LCU1		ELV_LCU1		2834
+mcu1			MACH_MCU1		MCU1			2835
+omap3_tao3530		MACH_OMAP3_TAO3530	OMAP3_TAO3530		2836
+omap3_pcutouch		MACH_OMAP3_PCUTOUCH	OMAP3_PCUTOUCH		2837
+smdkc210		MACH_SMDKC210		SMDKC210		2838
+omap3_braillo		MACH_OMAP3_BRAILLO	OMAP3_BRAILLO		2839
+spyplug			MACH_SPYPLUG		SPYPLUG			2840
+ginger			MACH_GINGER		GINGER			2841
+tny_t3530		MACH_TNY_T3530		TNY_T3530		2842
+pcaal1			MACH_PCAAL1		PCAAL1			2843
+spade			MACH_SPADE		SPADE			2844
+mxc25_topaz		MACH_MXC25_TOPAZ	MXC25_TOPAZ		2845
+t5325			MACH_T5325		T5325			2846
+gw2361			MACH_GW2361		GW2361			2847
+elog			MACH_ELOG		ELOG			2848
+income			MACH_INCOME		INCOME			2849
+bcm589x			MACH_BCM589X		BCM589X			2850
+etna			MACH_ETNA		ETNA			2851
+hawks			MACH_HAWKS		HAWKS			2852
+meson			MACH_MESON		MESON			2853
+xsbase255		MACH_XSBASE255		XSBASE255		2854
+pvm2030			MACH_PVM2030		PVM2030			2855
+mioa502			MACH_MIOA502		MIOA502			2856
+vvbox_sdorig2		MACH_VVBOX_SDORIG2	VVBOX_SDORIG2		2857
+vvbox_sdlite2		MACH_VVBOX_SDLITE2	VVBOX_SDLITE2		2858
+vvbox_sdpro4		MACH_VVBOX_SDPRO4	VVBOX_SDPRO4		2859
+htc_spv_m700		MACH_HTC_SPV_M700	HTC_SPV_M700		2860
+mx257sx			MACH_MX257SX		MX257SX			2861
+goni			MACH_GONI		GONI			2862
+msm8x55_svlte_ffa	MACH_MSM8X55_SVLTE_FFA	MSM8X55_SVLTE_FFA	2863
+msm8x55_svlte_surf	MACH_MSM8X55_SVLTE_SURF	MSM8X55_SVLTE_SURF	2864
+quickstep		MACH_QUICKSTEP		QUICKSTEP		2865
+dmw96			MACH_DMW96		DMW96			2866
+hammerhead		MACH_HAMMERHEAD		HAMMERHEAD		2867
+trident			MACH_TRIDENT		TRIDENT			2868
+lightning		MACH_LIGHTNING		LIGHTNING		2869
+iconnect		MACH_ICONNECT		ICONNECT		2870
+autobot			MACH_AUTOBOT		AUTOBOT			2871
+coconut			MACH_COCONUT		COCONUT			2872
+durian			MACH_DURIAN		DURIAN			2873
+cayenne			MACH_CAYENNE		CAYENNE			2874
+fuji			MACH_FUJI		FUJI			2875
+synology_6282		MACH_SYNOLOGY_6282	SYNOLOGY_6282		2876
+em1sy			MACH_EM1SY		EM1SY			2877
+m502			MACH_M502		M502			2878
+matrix518		MACH_MATRIX518		MATRIX518		2879
+tiny_gurnard		MACH_TINY_GURNARD	TINY_GURNARD		2880
+spear1310		MACH_SPEAR1310		SPEAR1310		2881
+bv07			MACH_BV07		BV07			2882
+mxt_td61		MACH_MXT_TD61		MXT_TD61		2883
+openrd_ultimate		MACH_OPENRD_ULTIMATE	OPENRD_ULTIMATE		2884
+devixp			MACH_DEVIXP		DEVIXP			2885
+miccpt			MACH_MICCPT		MICCPT			2886
+mic256			MACH_MIC256		MIC256			2887
+as1167			MACH_AS1167		AS1167			2888
+omap3_ibiza		MACH_OMAP3_IBIZA	OMAP3_IBIZA		2889
+u5500			MACH_U5500		U5500			2890
+davinci_picto		MACH_DAVINCI_PICTO	DAVINCI_PICTO		2891
+mecha			MACH_MECHA		MECHA			2892
+bubba3			MACH_BUBBA3		BUBBA3			2893
+pupitre			MACH_PUPITRE		PUPITRE			2894
+tegra_vogue		MACH_TEGRA_VOGUE	TEGRA_VOGUE		2896
+tegra_e1165		MACH_TEGRA_E1165	TEGRA_E1165		2897
+simplenet		MACH_SIMPLENET		SIMPLENET		2898
+ec4350tbm		MACH_EC4350TBM		EC4350TBM		2899
+pec_tc			MACH_PEC_TC		PEC_TC			2900
+pec_hc2			MACH_PEC_HC2		PEC_HC2			2901
+esl_mobilis_a		MACH_ESL_MOBILIS_A	ESL_MOBILIS_A		2902
+esl_mobilis_b		MACH_ESL_MOBILIS_B	ESL_MOBILIS_B		2903
+esl_wave_a		MACH_ESL_WAVE_A		ESL_WAVE_A		2904
+esl_wave_b		MACH_ESL_WAVE_B		ESL_WAVE_B		2905
+unisense_mmm		MACH_UNISENSE_MMM	UNISENSE_MMM		2906
+blueshark		MACH_BLUESHARK		BLUESHARK		2907
+e10			MACH_E10		E10			2908
+app3k_robin		MACH_APP3K_ROBIN	APP3K_ROBIN		2909
+pov15hd			MACH_POV15HD		POV15HD			2910
+stella			MACH_STELLA		STELLA			2911
+linkstation_lschl	MACH_LINKSTATION_LSCHL	LINKSTATION_LSCHL	2913
+netwalker		MACH_NETWALKER		NETWALKER		2914
+acsx106			MACH_ACSX106		ACSX106			2915
+atlas5_c1		MACH_ATLAS5_C1		ATLAS5_C1		2916
+nsb3ast			MACH_NSB3AST		NSB3AST			2917
+gnet_slc		MACH_GNET_SLC		GNET_SLC		2918
+af4000			MACH_AF4000		AF4000			2919
+ark9431			MACH_ARK9431		ARK9431			2920
+fs_s5pc100		MACH_FS_S5PC100		FS_S5PC100		2921
+omap3505nova8		MACH_OMAP3505NOVA8	OMAP3505NOVA8		2922
+omap3621_edp1		MACH_OMAP3621_EDP1	OMAP3621_EDP1		2923
+oratisaes		MACH_ORATISAES		ORATISAES		2924
+smdkv310		MACH_SMDKV310		SMDKV310		2925
+siemens_l0		MACH_SIEMENS_L0		SIEMENS_L0		2926
+ventana			MACH_VENTANA		VENTANA			2927
+wm8505_7in_netbook	MACH_WM8505_7IN_NETBOOK	WM8505_7IN_NETBOOK	2928
+ec4350sdb		MACH_EC4350SDB		EC4350SDB		2929
+mimas			MACH_MIMAS		MIMAS			2930
+titan			MACH_TITAN		TITAN			2931
+craneboard		MACH_CRANEBOARD		CRANEBOARD		2932
+es2440			MACH_ES2440		ES2440			2933
+najay_a9263		MACH_NAJAY_A9263	NAJAY_A9263		2934
+htctornado		MACH_HTCTORNADO		HTCTORNADO		2935
+dimm_mx257		MACH_DIMM_MX257		DIMM_MX257		2936
+jigen301		MACH_JIGEN		JIGEN			2937
+smdk6450		MACH_SMDK6450		SMDK6450		2938
+meno_qng		MACH_MENO_QNG		MENO_QNG		2939
+ns2416			MACH_NS2416		NS2416			2940
+rpc353			MACH_RPC353		RPC353			2941
+tq6410			MACH_TQ6410		TQ6410			2942
+sky6410			MACH_SKY6410		SKY6410			2943
+dynasty			MACH_DYNASTY		DYNASTY			2944
+vivo			MACH_VIVO		VIVO			2945
+bury_bl7582		MACH_BURY_BL7582	BURY_BL7582		2946
+bury_bps5270		MACH_BURY_BPS5270	BURY_BPS5270		2947
+basi			MACH_BASI		BASI			2948
+tn200			MACH_TN200		TN200			2949
+c2mmi			MACH_C2MMI		C2MMI			2950
+meson_6236m		MACH_MESON_6236M	MESON_6236M		2951
+meson_8626m		MACH_MESON_8626M	MESON_8626M		2952
+tube			MACH_TUBE		TUBE			2953
+messina			MACH_MESSINA		MESSINA			2954
+mx50_arm2		MACH_MX50_ARM2		MX50_ARM2		2955
+cetus9263		MACH_CETUS9263		CETUS9263		2956
+brownstone		MACH_BROWNSTONE		BROWNSTONE		2957
+vmx25			MACH_VMX25		VMX25			2958
+vmx51			MACH_VMX51		VMX51			2959
+abacus			MACH_ABACUS		ABACUS			2960
+cm4745			MACH_CM4745		CM4745			2961
+oratislink		MACH_ORATISLINK		ORATISLINK		2962
+davinci_dm365_dvr	MACH_DAVINCI_DM365_DVR	DAVINCI_DM365_DVR	2963
+netviz			MACH_NETVIZ		NETVIZ			2964
+flexibity		MACH_FLEXIBITY		FLEXIBITY		2965
+wlan_computer		MACH_WLAN_COMPUTER	WLAN_COMPUTER		2966
+lpc24xx			MACH_LPC24XX		LPC24XX			2967
+spica			MACH_SPICA		SPICA			2968
+gpsdisplay		MACH_GPSDISPLAY		GPSDISPLAY		2969
+bipnet			MACH_BIPNET		BIPNET			2970
+overo_ctu_inertial	MACH_OVERO_CTU_INERTIAL	OVERO_CTU_INERTIAL	2971
+davinci_dm355_mmm	MACH_DAVINCI_DM355_MMM	DAVINCI_DM355_MMM	2972
+pc9260_v2		MACH_PC9260_V2		PC9260_V2		2973
+ptx7545			MACH_PTX7545		PTX7545			2974
+tm_efdc			MACH_TM_EFDC		TM_EFDC			2975
+omap3_waldo1		MACH_OMAP3_WALDO1	OMAP3_WALDO1		2977
+flyer			MACH_FLYER		FLYER			2978
+tornado3240		MACH_TORNADO3240	TORNADO3240		2979
+soli_01			MACH_SOLI_01		SOLI_01			2980
+omapl138_europalc	MACH_OMAPL138_EUROPALC	OMAPL138_EUROPALC	2981
+helios_v1		MACH_HELIOS_V1		HELIOS_V1		2982
+netspace_lite_v2	MACH_NETSPACE_LITE_V2	NETSPACE_LITE_V2	2983
+ssc			MACH_SSC		SSC			2984
+premierwave_en		MACH_PREMIERWAVE_EN	PREMIERWAVE_EN		2985
+wasabi			MACH_WASABI		WASABI			2986
+mx50_rdp		MACH_MX50_RDP		MX50_RDP		2988
+universal_c210		MACH_UNIVERSAL_C210	UNIVERSAL_C210		2989
+real6410		MACH_REAL6410		REAL6410		2990
+spx_sakura		MACH_SPX_SAKURA		SPX_SAKURA		2991
+ij3k_2440		MACH_IJ3K_2440		IJ3K_2440		2992
+omap3_bc10		MACH_OMAP3_BC10		OMAP3_BC10		2993
+thebe			MACH_THEBE		THEBE			2994
+rv082			MACH_RV082		RV082			2995
+armlguest		MACH_ARMLGUEST		ARMLGUEST		2996
+tjinc1000		MACH_TJINC1000		TJINC1000		2997
+dockstar		MACH_DOCKSTAR		DOCKSTAR		2998
+ax8008			MACH_AX8008		AX8008			2999
+gnet_sgce		MACH_GNET_SGCE		GNET_SGCE		3000
+pxwnas_500_1000		MACH_PXWNAS_500_1000	PXWNAS_500_1000		3001
+ea20			MACH_EA20		EA20			3002
+awm2			MACH_AWM2		AWM2			3003
+ti8148evm		MACH_TI8148EVM		TI8148EVM		3004
+seaboard		MACH_SEABOARD		SEABOARD		3005
+linkstation_chlv2	MACH_LINKSTATION_CHLV2	LINKSTATION_CHLV2	3006
+tera_pro2_rack		MACH_TERA_PRO2_RACK	TERA_PRO2_RACK		3007
+rubys			MACH_RUBYS		RUBYS			3008
+aquarius		MACH_AQUARIUS		AQUARIUS		3009
+mx53_ard		MACH_MX53_ARD		MX53_ARD		3010
+mx53_smd		MACH_MX53_SMD		MX53_SMD		3011
+lswxl			MACH_LSWXL		LSWXL			3012
+dove_avng_v3		MACH_DOVE_AVNG_V3	DOVE_AVNG_V3		3013
+sdi_ess_9263		MACH_SDI_ESS_9263	SDI_ESS_9263		3014
+jocpu550		MACH_JOCPU550		JOCPU550		3015
+msm8x60_rumi3		MACH_MSM8X60_RUMI3	MSM8X60_RUMI3		3016
+msm8x60_ffa		MACH_MSM8X60_FFA	MSM8X60_FFA		3017
+yanomami		MACH_YANOMAMI		YANOMAMI		3018
+gta04			MACH_GTA04		GTA04			3019
+cm_a510			MACH_CM_A510		CM_A510			3020
+omap3_rfs200		MACH_OMAP3_RFS200	OMAP3_RFS200		3021
+kx33xx			MACH_KX33XX		KX33XX			3022
+ptx7510			MACH_PTX7510		PTX7510			3023
+top9000			MACH_TOP9000		TOP9000			3024
+teenote			MACH_TEENOTE		TEENOTE			3025
+ts3			MACH_TS3		TS3			3026
+a0			MACH_A0			A0			3027
+fsm9xxx_surf		MACH_FSM9XXX_SURF	FSM9XXX_SURF		3028
+fsm9xxx_ffa		MACH_FSM9XXX_FFA	FSM9XXX_FFA		3029
+frrhwcdma60w		MACH_FRRHWCDMA60W	FRRHWCDMA60W		3030
+remus			MACH_REMUS		REMUS			3031
+at91cap7xdk		MACH_AT91CAP7XDK	AT91CAP7XDK		3032
+at91cap7stk		MACH_AT91CAP7STK	AT91CAP7STK		3033
+kt_sbc_sam9_1		MACH_KT_SBC_SAM9_1	KT_SBC_SAM9_1		3034
+armada_xp_db		MACH_ARMADA_XP_DB	ARMADA_XP_DB		3036
+spdm			MACH_SPDM		SPDM			3037
+gtib			MACH_GTIB		GTIB			3038
+dgm3240			MACH_DGM3240		DGM3240			3039
+htcmega			MACH_HTCMEGA		HTCMEGA			3041
+tricorder		MACH_TRICORDER		TRICORDER		3042
+tx28			MACH_TX28		TX28			3043
+bstbrd			MACH_BSTBRD		BSTBRD			3044
+pwb3090			MACH_PWB3090		PWB3090			3045
+idea6410		MACH_IDEA6410		IDEA6410		3046
+qbc9263			MACH_QBC9263		QBC9263			3047
+borabora		MACH_BORABORA		BORABORA		3048
+valdez			MACH_VALDEZ		VALDEZ			3049
+ls9g20			MACH_LS9G20		LS9G20			3050
+mios_v1			MACH_MIOS_V1		MIOS_V1			3051
+s5pc110_crespo		MACH_S5PC110_CRESPO	S5PC110_CRESPO		3052
+controltek9g20		MACH_CONTROLTEK9G20	CONTROLTEK9G20		3053
+tin307			MACH_TIN307		TIN307			3054
+tin510			MACH_TIN510		TIN510			3055
+ep3505			MACH_EP3517		EP3517			3056
+bluecheese		MACH_BLUECHEESE		BLUECHEESE		3057
+tem3x30			MACH_TEM3X30		TEM3X30			3058
+harvest_desoto		MACH_HARVEST_DESOTO	HARVEST_DESOTO		3059
+msm8x60_qrdc		MACH_MSM8X60_QRDC	MSM8X60_QRDC		3060
+spear900		MACH_SPEAR900		SPEAR900		3061
+pcontrol_g20		MACH_PCONTROL_G20	PCONTROL_G20		3062
+rdstor			MACH_RDSTOR		RDSTOR			3063
+usdloader		MACH_USDLOADER		USDLOADER		3064
+tsoploader		MACH_TSOPLOADER		TSOPLOADER		3065
+kronos			MACH_KRONOS		KRONOS			3066
+ffcore			MACH_FFCORE		FFCORE			3067
+mone			MACH_MONE		MONE			3068
+unit2s			MACH_UNIT2S		UNIT2S			3069
+acer_a5			MACH_ACER_A5		ACER_A5			3070
+etherpro_isp		MACH_ETHERPRO_ISP	ETHERPRO_ISP		3071
+stretchs7000		MACH_STRETCHS7000	STRETCHS7000		3072
+p87_smartsim		MACH_P87_SMARTSIM	P87_SMARTSIM		3073
+tulip			MACH_TULIP		TULIP			3074
+sunflower		MACH_SUNFLOWER		SUNFLOWER		3075
+rib			MACH_RIB		RIB			3076
+clod			MACH_CLOD		CLOD			3077
+rump			MACH_RUMP		RUMP			3078
+tenderloin		MACH_TENDERLOIN		TENDERLOIN		3079
+shortloin		MACH_SHORTLOIN		SHORTLOIN		3080
+antares			MACH_ANTARES		ANTARES			3082
+wb40n			MACH_WB40N		WB40N			3083
+herring			MACH_HERRING		HERRING			3084
+naxy400			MACH_NAXY400		NAXY400			3085
+naxy1200		MACH_NAXY1200		NAXY1200		3086
+vpr200			MACH_VPR200		VPR200			3087
+bug20			MACH_BUG20		BUG20			3088
+goflexnet		MACH_GOFLEXNET		GOFLEXNET		3089
+torbreck		MACH_TORBRECK		TORBRECK		3090
+saarb_mg1		MACH_SAARB_MG1		SAARB_MG1		3091
+callisto		MACH_CALLISTO		CALLISTO		3092
+multhsu			MACH_MULTHSU		MULTHSU			3093
+saluda			MACH_SALUDA		SALUDA			3094
+pemp_omap3_apollo	MACH_PEMP_OMAP3_APOLLO	PEMP_OMAP3_APOLLO	3095
+vc0718			MACH_VC0718		VC0718			3096
+mvblx			MACH_MVBLX		MVBLX			3097
+inhand_apeiron		MACH_INHAND_APEIRON	INHAND_APEIRON		3098
+inhand_fury		MACH_INHAND_FURY	INHAND_FURY		3099
+inhand_siren		MACH_INHAND_SIREN	INHAND_SIREN		3100
+hdnvp			MACH_HDNVP		HDNVP			3101
+softwinner		MACH_SOFTWINNER		SOFTWINNER		3102
+prima2_evb		MACH_PRIMA2_EVB		PRIMA2_EVB		3103
+nas6210			MACH_NAS6210		NAS6210			3104
+unisdev			MACH_UNISDEV		UNISDEV			3105
+sbca11			MACH_SBCA11		SBCA11			3106
+saga			MACH_SAGA		SAGA			3107
+ns_k330			MACH_NS_K330		NS_K330			3108
+tanna			MACH_TANNA		TANNA			3109
+imate8502		MACH_IMATE8502		IMATE8502		3110
+aspen			MACH_ASPEN		ASPEN			3111
+daintree_cwac		MACH_DAINTREE_CWAC	DAINTREE_CWAC		3112
+zmx25			MACH_ZMX25		ZMX25			3113
+maple1			MACH_MAPLE1		MAPLE1			3114
+qsd8x72_surf		MACH_QSD8X72_SURF	QSD8X72_SURF		3115
+qsd8x72_ffa		MACH_QSD8X72_FFA	QSD8X72_FFA		3116
+abilene			MACH_ABILENE		ABILENE			3117
+eigen_ttr		MACH_EIGEN_TTR		EIGEN_TTR		3118
+iomega_ix2_200		MACH_IOMEGA_IX2_200	IOMEGA_IX2_200		3119
+coretec_vcx7400		MACH_CORETEC_VCX7400	CORETEC_VCX7400		3120
+santiago		MACH_SANTIAGO		SANTIAGO		3121
+mx257sol		MACH_MX257SOL		MX257SOL		3122
+strasbourg		MACH_STRASBOURG		STRASBOURG		3123
+msm8x60_fluid		MACH_MSM8X60_FLUID	MSM8X60_FLUID		3124
+smartqv5		MACH_SMARTQV5		SMARTQV5		3125
+smartqv3		MACH_SMARTQV3		SMARTQV3		3126
+smartqv7		MACH_SMARTQV7		SMARTQV7		3127
+paz00			MACH_PAZ00		PAZ00			3128
+acmenetusfoxg20		MACH_ACMENETUSFOXG20	ACMENETUSFOXG20		3129
+fwbd_0404		MACH_FWBD_0404		FWBD_0404		3131
+hdgu			MACH_HDGU		HDGU			3132
+pyramid			MACH_PYRAMID		PYRAMID			3133
+epiphan			MACH_EPIPHAN		EPIPHAN			3134
+omap_bender		MACH_OMAP_BENDER	OMAP_BENDER		3135
+gurnard			MACH_GURNARD		GURNARD			3136
+gtl_it5100		MACH_GTL_IT5100		GTL_IT5100		3137
+bcm2708			MACH_BCM2708		BCM2708			3138
+mx51_ggc		MACH_MX51_GGC		MX51_GGC		3139
+sharespace		MACH_SHARESPACE		SHARESPACE		3140
+haba_knx_explorer	MACH_HABA_KNX_EXPLORER	HABA_KNX_EXPLORER	3141
+simtec_kirkmod		MACH_SIMTEC_KIRKMOD	SIMTEC_KIRKMOD		3142
+crux			MACH_CRUX		CRUX			3143
+mx51_bravo		MACH_MX51_BRAVO		MX51_BRAVO		3144
+charon			MACH_CHARON		CHARON			3145
+picocom3		MACH_PICOCOM3		PICOCOM3		3146
+picocom4		MACH_PICOCOM4		PICOCOM4		3147
+serrano			MACH_SERRANO		SERRANO			3148
+doubleshot		MACH_DOUBLESHOT		DOUBLESHOT		3149
+evsy			MACH_EVSY		EVSY			3150
+huashan			MACH_HUASHAN		HUASHAN			3151
+lausanne		MACH_LAUSANNE		LAUSANNE		3152
+emerald			MACH_EMERALD		EMERALD			3153
+tqma35			MACH_TQMA35		TQMA35			3154
+marvel			MACH_MARVEL		MARVEL			3155
+manuae			MACH_MANUAE		MANUAE			3156
+chacha			MACH_CHACHA		CHACHA			3157
+lemon			MACH_LEMON		LEMON			3158
+csc			MACH_CSC		CSC			3159
+gira_knxip_router	MACH_GIRA_KNXIP_ROUTER	GIRA_KNXIP_ROUTER	3160
+t20			MACH_T20		T20			3161
+hdmini			MACH_HDMINI		HDMINI			3162
+sciphone_g2		MACH_SCIPHONE_G2	SCIPHONE_G2		3163
+express			MACH_EXPRESS		EXPRESS			3164
+express_kt		MACH_EXPRESS_KT		EXPRESS_KT		3165
+maximasp		MACH_MAXIMASP		MAXIMASP		3166
+nitrogen_imx51		MACH_NITROGEN_IMX51	NITROGEN_IMX51		3167
+nitrogen_imx53		MACH_NITROGEN_IMX53	NITROGEN_IMX53		3168
+sunfire			MACH_SUNFIRE		SUNFIRE			3169
+arowana			MACH_AROWANA		AROWANA			3170
+tegra_daytona		MACH_TEGRA_DAYTONA	TEGRA_DAYTONA		3171
+tegra_swordfish		MACH_TEGRA_SWORDFISH	TEGRA_SWORDFISH		3172
+edison			MACH_EDISON		EDISON			3173
+svp8500v1		MACH_SVP8500V1		SVP8500V1		3174
+svp8500v2		MACH_SVP8500V2		SVP8500V2		3175
+svp5500			MACH_SVP5500		SVP5500			3176
+b5500			MACH_B5500		B5500			3177
+s5500			MACH_S5500		S5500			3178
+icon			MACH_ICON		ICON			3179
+elephant		MACH_ELEPHANT		ELEPHANT		3180
+shooter			MACH_SHOOTER		SHOOTER			3182
+spade_lte		MACH_SPADE_LTE		SPADE_LTE		3183
+philhwani		MACH_PHILHWANI		PHILHWANI		3184
+gsncomm			MACH_GSNCOMM		GSNCOMM			3185
+strasbourg_a2		MACH_STRASBOURG_A2	STRASBOURG_A2		3186
+mmm			MACH_MMM		MMM			3187
+davinci_dm365_bv	MACH_DAVINCI_DM365_BV	DAVINCI_DM365_BV	3188
+ag5evm			MACH_AG5EVM		AG5EVM			3189
+sc575plc		MACH_SC575PLC		SC575PLC		3190
+sc575hmi		MACH_SC575IPC		SC575IPC		3191
+omap3_tdm3730		MACH_OMAP3_TDM3730	OMAP3_TDM3730		3192
+top9000_eval		MACH_TOP9000_EVAL	TOP9000_EVAL		3194
+top9000_su		MACH_TOP9000_SU		TOP9000_SU		3195
+utm300			MACH_UTM300		UTM300			3196
+tsunagi			MACH_TSUNAGI		TSUNAGI			3197
+ts75xx			MACH_TS75XX		TS75XX			3198
+ts47xx			MACH_TS47XX		TS47XX			3200
+da850_k5		MACH_DA850_K5		DA850_K5		3201
+ax502			MACH_AX502		AX502			3202
+igep0032		MACH_IGEP0032		IGEP0032		3203
+antero			MACH_ANTERO		ANTERO			3204
+synergy			MACH_SYNERGY		SYNERGY			3205
+ics_if_voip		MACH_ICS_IF_VOIP	ICS_IF_VOIP		3206
+wlf_cragg_6410		MACH_WLF_CRAGG_6410	WLF_CRAGG_6410		3207
+punica			MACH_PUNICA		PUNICA			3208
+trimslice		MACH_TRIMSLICE		TRIMSLICE		3209
+mx27_wmultra		MACH_MX27_WMULTRA	MX27_WMULTRA		3210
+mackerel		MACH_MACKEREL		MACKEREL		3211
+fa9x27			MACH_FA9X27		FA9X27			3213
+ns2816tb		MACH_NS2816TB		NS2816TB		3214
+ns2816_ntpad		MACH_NS2816_NTPAD	NS2816_NTPAD		3215
+ns2816_ntnb		MACH_NS2816_NTNB	NS2816_NTNB		3216
+kaen			MACH_KAEN		KAEN			3217
+nv1000			MACH_NV1000		NV1000			3218
+nuc950ts		MACH_NUC950TS		NUC950TS		3219
+nokia_rm680		MACH_NOKIA_RM680	NOKIA_RM680		3220
+ast2200			MACH_AST2200		AST2200			3221
+lead			MACH_LEAD		LEAD			3222
+unino1			MACH_UNINO1		UNINO1			3223
+greeco			MACH_GREECO		GREECO			3224
+verdi			MACH_VERDI		VERDI			3225
+dm6446_adbox		MACH_DM6446_ADBOX	DM6446_ADBOX		3226
+quad_salsa		MACH_QUAD_SALSA		QUAD_SALSA		3227
+abb_gma_1_1		MACH_ABB_GMA_1_1	ABB_GMA_1_1		3228
+svcid			MACH_SVCID		SVCID			3229
+msm8960_sim		MACH_MSM8960_SIM	MSM8960_SIM		3230
+msm8960_rumi3		MACH_MSM8960_RUMI3	MSM8960_RUMI3		3231
+icon_g			MACH_ICON_G		ICON_G			3232
+mb3			MACH_MB3		MB3			3233
+gsia18s			MACH_GSIA18S		GSIA18S			3234
+pivicc			MACH_PIVICC		PIVICC			3235
+pcm048			MACH_PCM048		PCM048			3236
+dds			MACH_DDS		DDS			3237
+chalten_xa1		MACH_CHALTEN_XA1	CHALTEN_XA1		3238
+ts48xx			MACH_TS48XX		TS48XX			3239
+tonga2_tfttimer		MACH_TONGA2_TFTTIMER	TONGA2_TFTTIMER		3240
+whistler		MACH_WHISTLER		WHISTLER		3241
+asl_phoenix		MACH_ASL_PHOENIX	ASL_PHOENIX		3242
+at91sam9263otlite	MACH_AT91SAM9263OTLITE	AT91SAM9263OTLITE	3243
+ddplug			MACH_DDPLUG		DDPLUG			3244
+d2plug			MACH_D2PLUG		D2PLUG			3245
+kzm9d			MACH_KZM9D		KZM9D			3246
+verdi_lte		MACH_VERDI_LTE		VERDI_LTE		3247
+nanozoom		MACH_NANOZOOM		NANOZOOM		3248
+dm3730_som_lv		MACH_DM3730_SOM_LV	DM3730_SOM_LV		3249
+dm3730_torpedo		MACH_DM3730_TORPEDO	DM3730_TORPEDO		3250
+anchovy			MACH_ANCHOVY		ANCHOVY			3251
+re2rev20		MACH_RE2REV20		RE2REV20		3253
+re2rev21		MACH_RE2REV21		RE2REV21		3254
+cns21xx			MACH_CNS21XX		CNS21XX			3255
+rider			MACH_RIDER		RIDER			3257
+nsk330			MACH_NSK330		NSK330			3258
+cns2133evb		MACH_CNS2133EVB		CNS2133EVB		3259
+z3_816x_mod		MACH_Z3_816X_MOD	Z3_816X_MOD		3260
+z3_814x_mod		MACH_Z3_814X_MOD	Z3_814X_MOD		3261
+beect			MACH_BEECT		BEECT			3262
+dma_thunderbug		MACH_DMA_THUNDERBUG	DMA_THUNDERBUG		3263
+omn_at91sam9g20		MACH_OMN_AT91SAM9G20	OMN_AT91SAM9G20		3264
+mx25_e2s_uc		MACH_MX25_E2S_UC	MX25_E2S_UC		3265
+mione			MACH_MIONE		MIONE			3266
+top9000_tcu		MACH_TOP9000_TCU	TOP9000_TCU		3267
+top9000_bsl		MACH_TOP9000_BSL	TOP9000_BSL		3268
+kingdom			MACH_KINGDOM		KINGDOM			3269
+armadillo460		MACH_ARMADILLO460	ARMADILLO460		3270
+lq2			MACH_LQ2		LQ2			3271
+sweda_tms2		MACH_SWEDA_TMS2		SWEDA_TMS2		3272
+mx53_loco		MACH_MX53_LOCO		MX53_LOCO		3273
+acer_a8			MACH_ACER_A8		ACER_A8			3275
+acer_gauguin		MACH_ACER_GAUGUIN	ACER_GAUGUIN		3276
+guppy			MACH_GUPPY		GUPPY			3277
+mx61_ard		MACH_MX61_ARD		MX61_ARD		3278
+tx53			MACH_TX53		TX53			3279
+omapl138_case_a3	MACH_OMAPL138_CASE_A3	OMAPL138_CASE_A3	3280
+uemd			MACH_UEMD		UEMD			3281
+ccwmx51mut		MACH_CCWMX51MUT		CCWMX51MUT		3282
+rockhopper		MACH_ROCKHOPPER		ROCKHOPPER		3283
+encore			MACH_ENCORE		ENCORE			3284
+hkdkc100		MACH_HKDKC100		HKDKC100		3285
+ts42xx			MACH_TS42XX		TS42XX			3286
+aebl			MACH_AEBL		AEBL			3287
+wario			MACH_WARIO		WARIO			3288
+gfs_spm			MACH_GFS_SPM		GFS_SPM			3289
+cm_t3730		MACH_CM_T3730		CM_T3730		3290
+isc3			MACH_ISC3		ISC3			3291
+rascal			MACH_RASCAL		RASCAL			3292
+hrefv60			MACH_HREFV60		HREFV60			3293
+tpt_2_0			MACH_TPT_2_0		TPT_2_0			3294
+pydtd			MACH_PYRAMID_TD		PYRAMID_TD		3295
+splendor		MACH_SPLENDOR		SPLENDOR		3296
+guf_vincell		MACH_GUF_PLANET		GUF_PLANET		3297
+msm8x60_qt		MACH_MSM8X60_QT		MSM8X60_QT		3298
+htc_hd_mini		MACH_HTC_HD_MINI	HTC_HD_MINI		3299
+athene			MACH_ATHENE		ATHENE			3300
+deep_r_ek_1		MACH_DEEP_R_EK_1	DEEP_R_EK_1		3301
+vivow_ct		MACH_VIVOW_CT		VIVOW_CT		3302
+nery_1000		MACH_NERY_1000		NERY_1000		3303
+rfl109145_ssrv		MACH_RFL109145_SSRV	RFL109145_SSRV		3304
+nmh			MACH_NMH		NMH			3305
+wn802t			MACH_WN802T		WN802T			3306
+dragonet		MACH_DRAGONET		DRAGONET		3307
+geneva_b4		MACH_GENEVA_B		GENEVA_B		3308
+at91sam9263desk16l	MACH_AT91SAM9263DESK16L	AT91SAM9263DESK16L	3309
+bcmhana_sv		MACH_BCMHANA_SV		BCMHANA_SV		3310
+bcmhana_tablet		MACH_BCMHANA_TABLET	BCMHANA_TABLET		3311
+koi			MACH_KOI		KOI			3312
+ts4800			MACH_TS4800		TS4800			3313
+tqma9263		MACH_TQMA9263		TQMA9263		3314
+holiday			MACH_HOLIDAY		HOLIDAY			3315
+dma_6410		MACH_DMA6410		DMA6410			3316
+pcats_overlay		MACH_PCATS_OVERLAY	PCATS_OVERLAY		3317
+hwgw6410		MACH_HWGW6410		HWGW6410		3318
+shenzhou		MACH_SHENZHOU		SHENZHOU		3319
+cwme9210		MACH_CWME9210		CWME9210		3320
+cwme9210js		MACH_CWME9210JS		CWME9210JS		3321
+pgs_v1			MACH_PGS_SITARA		PGS_SITARA		3322
+colibri_tegra2		MACH_COLIBRI_TEGRA2	COLIBRI_TEGRA2		3323
+w21			MACH_W21		W21			3324
+polysat1		MACH_POLYSAT1		POLYSAT1		3325
+dataway			MACH_DATAWAY		DATAWAY			3326
+cobral138		MACH_COBRAL138		COBRAL138		3327
+roverpcs8		MACH_ROVERPCS8		ROVERPCS8		3328
+marvelc			MACH_MARVELC		MARVELC			3329
+navefihid		MACH_NAVEFIHID		NAVEFIHID		3330
+dm365_cv100		MACH_DM365_CV100	DM365_CV100		3331
+able			MACH_ABLE		ABLE			3332
+legacy			MACH_LEGACY		LEGACY			3333
+icong			MACH_ICONG		ICONG			3334
+rover_g8		MACH_ROVER_G8		ROVER_G8		3335
+t5388p			MACH_T5388P		T5388P			3336
+dingo			MACH_DINGO		DINGO			3337
+goflexhome		MACH_GOFLEXHOME		GOFLEXHOME		3338
+lanreadyfn511		MACH_LANREADYFN511	LANREADYFN511		3340
+omap3_baia		MACH_OMAP3_BAIA		OMAP3_BAIA		3341
+omap3smartdisplay	MACH_OMAP3SMARTDISPLAY	OMAP3SMARTDISPLAY	3342
+xilinx			MACH_XILINX		XILINX			3343
+a2f			MACH_A2F		A2F			3344
+sky25			MACH_SKY25		SKY25			3345
+ccmx53			MACH_CCMX53		CCMX53			3346
+ccmx53js		MACH_CCMX53JS		CCMX53JS		3347
+ccwmx53			MACH_CCWMX53		CCWMX53			3348
+ccwmx53js		MACH_CCWMX53JS		CCWMX53JS		3349
+frisms			MACH_FRISMS		FRISMS			3350
+msm7x27a_ffa		MACH_MSM7X27A_FFA	MSM7X27A_FFA		3351
+msm7x27a_surf		MACH_MSM7X27A_SURF	MSM7X27A_SURF		3352
+msm7x27a_rumi3		MACH_MSM7X27A_RUMI3	MSM7X27A_RUMI3		3353
+dimmsam9g20		MACH_DIMMSAM9G20	DIMMSAM9G20		3354
+dimm_imx28		MACH_DIMM_IMX28		DIMM_IMX28		3355
+amk_a4			MACH_AMK_A4		AMK_A4			3356
+gnet_sgme		MACH_GNET_SGME		GNET_SGME		3357
+shooter_u		MACH_SHOOTER_U		SHOOTER_U		3358
+vmx53			MACH_VMX53		VMX53			3359
+rhino			MACH_RHINO		RHINO			3360
+armlex4210		MACH_ARMLEX4210		ARMLEX4210		3361
+swarcoextmodem		MACH_SWARCOEXTMODEM	SWARCOEXTMODEM		3362
+snowball		MACH_SNOWBALL		SNOWBALL		3363
+pcm049			MACH_PCM049		PCM049			3364
+vigor			MACH_VIGOR		VIGOR			3365
+oslo_amundsen		MACH_OSLO_AMUNDSEN	OSLO_AMUNDSEN		3366
+gsl_diamond		MACH_GSL_DIAMOND	GSL_DIAMOND		3367
+cv2201			MACH_CV2201		CV2201			3368
+cv2202			MACH_CV2202		CV2202			3369
+cv2203			MACH_CV2203		CV2203			3370
+vit_ibox		MACH_VIT_IBOX		VIT_IBOX		3371
+dm6441_esp		MACH_DM6441_ESP		DM6441_ESP		3372
+at91sam9x5ek		MACH_AT91SAM9X5EK	AT91SAM9X5EK		3373
+libra			MACH_LIBRA		LIBRA			3374
+easycrrh		MACH_EASYCRRH		EASYCRRH		3375
+tripel			MACH_TRIPEL		TRIPEL			3376
+endian_mini		MACH_ENDIAN_MINI	ENDIAN_MINI		3377
+xilinx_ep107		MACH_XILINX_EP107	XILINX_EP107		3378
+nuri			MACH_NURI		NURI			3379
+janus			MACH_JANUS		JANUS			3380
+ddnas			MACH_DDNAS		DDNAS			3381
+tag			MACH_TAG		TAG			3382
+tagw			MACH_TAGW		TAGW			3383
+nitrogen_vm_imx51	MACH_NITROGEN_VM_IMX51	NITROGEN_VM_IMX51	3384
+viprinet		MACH_VIPRINET		VIPRINET		3385
+bockw			MACH_BOCKW		BOCKW			3386
+eva2000			MACH_EVA2000		EVA2000			3387
+steelyard		MACH_STEELYARD		STEELYARD		3388
+ea2468devkit		MACH_LPC2468OEM		LPC2468OEM		3389
+sdh001			MACH_MACH_SDH001	MACH_SDH001		3390
+fe2478mblox		MACH_LPC2478MICROBLOX	LPC2478MICROBLOX	3391
+nsslsboard		MACH_NSSLSBOARD		NSSLSBOARD		3392
+geneva_b5		MACH_GENEVA_B5		GENEVA_B5		3393
+spear1340		MACH_SPEAR1340		SPEAR1340		3394
+rexmas			MACH_REXMAS		REXMAS			3395
+msm8960_cdp		MACH_MSM8960_CDP	MSM8960_CDP		3396
+msm8960_mtp		MACH_MSM8960_MDP	MSM8960_MDP		3397
+msm8960_fluid		MACH_MSM8960_FLUID	MSM8960_FLUID		3398
+msm8960_apq		MACH_MSM8960_APQ	MSM8960_APQ		3399
+helios_v2		MACH_HELIOS_V2		HELIOS_V2		3400
+mif10p			MACH_MIF10P		MIF10P			3401
+iam28			MACH_IAM28		IAM28			3402
+picasso			MACH_PICASSO		PICASSO			3403
+mr301a			MACH_MR301A		MR301A			3404
+notle			MACH_NOTLE		NOTLE			3405
+eelx2			MACH_EELX2		EELX2			3406
+moon			MACH_MOON		MOON			3407
+ruby			MACH_RUBY		RUBY			3408
+goldengate		MACH_GOLDENGATE		GOLDENGATE		3409
+ctbu_gen2		MACH_CTBU_GEN2		CTBU_GEN2		3410
+kmp_am17_01		MACH_KMP_AM17_01	KMP_AM17_01		3411
+wtplug			MACH_WTPLUG		WTPLUG			3412
+mx27su2			MACH_MX27SU2		MX27SU2			3413
+nb31			MACH_NB31		NB31			3414
+hjsdu			MACH_HJSDU		HJSDU			3415
+td3_rev1		MACH_TD3_REV1		TD3_REV1		3416
+eag_ci4000		MACH_EAG_CI4000		EAG_CI4000		3417
+net5big_nand_v2		MACH_NET5BIG_NAND_V2	NET5BIG_NAND_V2		3418
+cpx2			MACH_CPX2		CPX2			3419
+net2big_nand_v2		MACH_NET2BIG_NAND_V2	NET2BIG_NAND_V2		3420
+ecuv5			MACH_ECUV5		ECUV5			3421
+hsgx6d			MACH_HSGX6D		HSGX6D			3422
+dawad7			MACH_DAWAD7		DAWAD7			3423
+sam9repeater		MACH_SAM9REPEATER	SAM9REPEATER		3424
+gt_i5700		MACH_GT_I5700		GT_I5700		3425
+ctera_plug_c2		MACH_CTERA_PLUG_C2	CTERA_PLUG_C2		3426
+marvelct		MACH_MARVELCT		MARVELCT		3427
+ag11005			MACH_AG11005		AG11005			3428
+omap_tabletblaze	MACH_OMAP_BLAZE		OMAP_BLAZE		3429
+vangogh			MACH_VANGOGH		VANGOGH			3430
+matrix505		MACH_MATRIX505		MATRIX505		3431
+oce_nigma		MACH_OCE_NIGMA		OCE_NIGMA		3432
+t55			MACH_T55		T55			3433
+bio3k			MACH_BIO3K		BIO3K			3434
+expressct		MACH_EXPRESSCT		EXPRESSCT		3435
+cardhu			MACH_CARDHU		CARDHU			3436
+aruba			MACH_ARUBA		ARUBA			3437
+bonaire			MACH_BONAIRE		BONAIRE			3438
+nuc700evb		MACH_NUC700EVB		NUC700EVB		3439
+nuc710evb		MACH_NUC710EVB		NUC710EVB		3440
+nuc740evb		MACH_NUC740EVB		NUC740EVB		3441
+nuc745evb		MACH_NUC745EVB		NUC745EVB		3442
+transcede		MACH_TRANSCEDE		TRANSCEDE		3443
+mora			MACH_MORA		MORA			3444
+nda_evm			MACH_NDA_EVM		NDA_EVM			3445
+timu			MACH_TIMU		TIMU			3446
+expressh		MACH_EXPRESSH		EXPRESSH		3447
+veridis_a300		MACH_VERIDIS_A300	VERIDIS_A300		3448
+dm368_leopard		MACH_DM368_LEOPARD	DM368_LEOPARD		3449
+omap_mcop		MACH_OMAP_MCOP		OMAP_MCOP		3450
+tritip			MACH_TRITIP		TRITIP			3451
+sm1k			MACH_SM1K		SM1K			3452
+monch			MACH_MONCH		MONCH			3453
+curacao			MACH_CURACAO		CURACAO			3454
+origen			MACH_ORIGEN		ORIGEN			3455
+epc10			MACH_EPC10		EPC10			3456
+sgh_i740		MACH_SGH_I740		SGH_I740		3457
+tuna			MACH_TUNA		TUNA			3458
+mx51_tulip		MACH_MX51_TULIP		MX51_TULIP		3459
+mx51_aster7		MACH_MX51_ASTER7	MX51_ASTER7		3460
+acro37xbrd		MACH_ACRO37XBRD		ACRO37XBRD		3461
+elke			MACH_ELKE		ELKE			3462
+sbc6000x		MACH_SBC6000X		SBC6000X		3463
+r1801e			MACH_R1801E		R1801E			3464
+h1600			MACH_H1600		H1600			3465
+mini210			MACH_MINI210		MINI210			3466
+mini8168		MACH_MINI8168		MINI8168		3467
+pc7308			MACH_PC7308		PC7308			3468
+ge863_pro3_evk		MACH_GE863		GE863			3469
+kmm2m01			MACH_KMM2M01		KMM2M01			3470
+mx51erebus		MACH_MX51EREBUS		MX51EREBUS		3471
+wm8650refboard		MACH_WM8650REFBOARD	WM8650REFBOARD		3472
+tuxrail			MACH_TUXRAIL		TUXRAIL			3473
+arthur			MACH_ARTHUR		ARTHUR			3474
+doorboy			MACH_DOORBOY		DOORBOY			3475
+xarina			MACH_XARINA		XARINA			3476
+roverx7			MACH_ROVERX7		ROVERX7			3477
+sdvr			MACH_SDVR		SDVR			3478
+acer_maya		MACH_ACER_MAYA		ACER_MAYA		3479
+pico			MACH_PICO		PICO			3480
+cwmx233			MACH_CWMX233		CWMX233			3481
+cwam1808		MACH_CWAM1808		CWAM1808		3482
+cwdm365			MACH_CWDM365		CWDM365			3483
+mx51_moray		MACH_MX51_MORAY		MX51_MORAY		3484
+thales_cbc		MACH_THALES_CBC		THALES_CBC		3485
+bluepoint		MACH_BLUEPOINT		BLUEPOINT		3486
+dir665			MACH_DIR665		DIR665			3487
+acmerover1		MACH_ACMEROVER1		ACMEROVER1		3488
+shooter_ct		MACH_SHOOTER_CT		SHOOTER_CT		3489
+bliss			MACH_BLISS		BLISS			3490
+blissc			MACH_BLISSC		BLISSC			3491
+thales_adc		MACH_THALES_ADC		THALES_ADC		3492
+ubisys_p9d_evp		MACH_UBISYS_P9D_EVP	UBISYS_P9D_EVP		3493
+atdgp318		MACH_ATDGP318		ATDGP318		3494
+dma210u			MACH_DMA210U		DMA210U			3495
+em_t3			MACH_EM_T3		EM_T3			3496
+htx3250			MACH_HTX3250		HTX3250			3497
+g50			MACH_G50		G50			3498
+eco5			MACH_ECO5		ECO5			3499
+wintergrasp		MACH_WINTERGRASP	WINTERGRASP		3500
+puro			MACH_PURO		PURO			3501
+shooter_k		MACH_SHOOTER_K		SHOOTER_K		3502
+nspire			MACH_NSPIRE		NSPIRE			3503
+mickxx			MACH_MICKXX		MICKXX			3504
+lxmb			MACH_LXMB		LXMB			3505
+tmdxscbp6618x		MACH_TMDXSCBP6616X	TMDXSCBP6616X		3506
+adam			MACH_ADAM		ADAM			3507
+b1004			MACH_B1004		B1004			3508
+oboea			MACH_OBOEA		OBOEA			3509
+a1015			MACH_A1015		A1015			3510
+robin_vbdt30		MACH_ROBIN_VBDT30	ROBIN_VBDT30		3511
+tegra_enterprise	MACH_TEGRA_ENTERPRISE	TEGRA_ENTERPRISE	3512
+rfl108200_mk10		MACH_RFL108200_MK10	RFL108200_MK10		3513
+rfl108300_mk16		MACH_RFL108300_MK16	RFL108300_MK16		3514
+rover_v7		MACH_ROVER_V7		ROVER_V7		3515
+miphone			MACH_MIPHONE		MIPHONE			3516
+femtobts		MACH_FEMTOBTS		FEMTOBTS		3517
+monopoli		MACH_MONOPOLI		MONOPOLI		3518
+boss			MACH_BOSS		BOSS			3519
+davinci_dm368_vtam	MACH_DAVINCI_DM368_VTAM	DAVINCI_DM368_VTAM	3520
+clcon			MACH_CLCON		CLCON			3521
+nokia_rm696		MACH_NOKIA_RM696	NOKIA_RM696		3522
+tahiti			MACH_TAHITI		TAHITI			3523
+fighter			MACH_FIGHTER		FIGHTER			3524
+sgh_i710		MACH_SGH_I710		SGH_I710		3525
+integreproscb		MACH_INTEGREPROSCB	INTEGREPROSCB		3526
+monza			MACH_MONZA		MONZA			3527
+calimain		MACH_CALIMAIN		CALIMAIN		3528
+mx6q_sabreauto		MACH_MX6Q_SABREAUTO	MX6Q_SABREAUTO		3529
+gma01x			MACH_GMA01X		GMA01X			3530
+sbc51			MACH_SBC51		SBC51			3531
+fit			MACH_FIT		FIT			3532
+steelhead		MACH_STEELHEAD		STEELHEAD		3533
+panther			MACH_PANTHER		PANTHER			3534
+msm8960_liquid		MACH_MSM8960_LIQUID	MSM8960_LIQUID		3535
+lexikonct		MACH_LEXIKONCT		LEXIKONCT		3536
+ns2816_stb		MACH_NS2816_STB		NS2816_STB		3537
+sei_mm2_lpc3250		MACH_SEI_MM2_LPC3250	SEI_MM2_LPC3250		3538
+cmimx53			MACH_CMIMX53		CMIMX53			3539
+sandwich		MACH_SANDWICH		SANDWICH		3540
+chief			MACH_CHIEF		CHIEF			3541
+pogo_e02		MACH_POGO_E02		POGO_E02		3542
+mikrap_x168		MACH_MIKRAP_X168	MIKRAP_X168		3543
+htcmozart		MACH_HTCMOZART		HTCMOZART		3544
+htcgold			MACH_HTCGOLD		HTCGOLD			3545
+mt72xx			MACH_MT72XX		MT72XX			3546
+mx51_ivy		MACH_MX51_IVY		MX51_IVY		3547
+mx51_lvd		MACH_MX51_LVD		MX51_LVD		3548
+omap3_wiser2		MACH_OMAP3_WISER2	OMAP3_WISER2		3549
+dreamplug		MACH_DREAMPLUG		DREAMPLUG		3550
+cobas_c_111		MACH_COBAS_C_111	COBAS_C_111		3551
+cobas_u_411		MACH_COBAS_U_411	COBAS_U_411		3552
+hssd			MACH_HSSD		HSSD			3553
+iom35x			MACH_IOM35X		IOM35X			3554
+psom_omap		MACH_PSOM_OMAP		PSOM_OMAP		3555
+iphone_2g		MACH_IPHONE_2G		IPHONE_2G		3556
+iphone_3g		MACH_IPHONE_3G		IPHONE_3G		3557
+ipod_touch_1g		MACH_IPOD_TOUCH_1G	IPOD_TOUCH_1G		3558
+pharos_tpc		MACH_PHAROS_TPC		PHAROS_TPC		3559
+mx53_hydra		MACH_MX53_HYDRA		MX53_HYDRA		3560
+ns2816_dev_board	MACH_NS2816_DEV_BOARD	NS2816_DEV_BOARD	3561
+iphone_3gs		MACH_IPHONE_3GS		IPHONE_3GS		3562
+iphone_4		MACH_IPHONE_4		IPHONE_4		3563
+ipod_touch_4g		MACH_IPOD_TOUCH_4G	IPOD_TOUCH_4G		3564
+dragon_e1100		MACH_DRAGON_E1100	DRAGON_E1100		3565
+topside			MACH_TOPSIDE		TOPSIDE			3566
+irisiii			MACH_IRISIII		IRISIII			3567
+deto_macarm9		MACH_DETO_MACARM9	DETO_MACARM9		3568
+eti_d1			MACH_ETI_D1		ETI_D1			3569
+som3530sdk		MACH_SOM3530SDK		SOM3530SDK		3570
+oc_engine		MACH_OC_ENGINE		OC_ENGINE		3571
+apq8064_sim		MACH_APQ8064_SIM	APQ8064_SIM		3572
+alps			MACH_ALPS		ALPS			3575
+tny_t3730		MACH_TNY_T3730		TNY_T3730		3576
+geryon_nfe		MACH_GERYON_NFE		GERYON_NFE		3577
+ns2816_ref_board	MACH_NS2816_REF_BOARD	NS2816_REF_BOARD	3578
+silverstone		MACH_SILVERSTONE	SILVERSTONE		3579
+mtt2440			MACH_MTT2440		MTT2440			3580
+ynicdb			MACH_YNICDB		YNICDB			3581
+bct			MACH_BCT		BCT			3582
+tuscan			MACH_TUSCAN		TUSCAN			3583
+xbt_sam9g45		MACH_XBT_SAM9G45	XBT_SAM9G45		3584
+enbw_cmc		MACH_ENBW_CMC		ENBW_CMC		3585
+msm8x60_dragon		MACH_APQ8060_DRAGON	APQ8060_DRAGON		3586
+ch104mx257		MACH_CH104MX257		CH104MX257		3587
+openpri			MACH_OPENPRI		OPENPRI			3588
+am335xevm		MACH_AM335XEVM		AM335XEVM		3589
+picodmb			MACH_PICODMB		PICODMB			3590
+waluigi			MACH_WALUIGI		WALUIGI			3591
+punicag7		MACH_PUNICAG7		PUNICAG7		3592
+ipad_1g			MACH_IPAD_1G		IPAD_1G			3593
+appletv_2g		MACH_APPLETV_2G		APPLETV_2G		3594
+mach_ecog45		MACH_MACH_ECOG45	MACH_ECOG45		3595
+ait_cam_enc_4xx		MACH_AIT_CAM_ENC_4XX	AIT_CAM_ENC_4XX		3596
+runnymede		MACH_RUNNYMEDE		RUNNYMEDE		3597
+play			MACH_PLAY		PLAY			3598
+hw90260			MACH_HW90260		HW90260			3599
+tagh			MACH_TAGH		TAGH			3600
+filbert			MACH_FILBERT		FILBERT			3601
+getinge_netcomv3	MACH_GETINGE_NETCOMV3	GETINGE_NETCOMV3	3602
+cw20			MACH_CW20		CW20			3603
+cinema			MACH_CINEMA		CINEMA			3604
+cinema_tea		MACH_CINEMA_TEA		CINEMA_TEA		3605
+cinema_coffee		MACH_CINEMA_COFFEE	CINEMA_COFFEE		3606
+cinema_juice		MACH_CINEMA_JUICE	CINEMA_JUICE		3607
+linux_pad		MACH_THEPAD		THEPAD			3608
+mx53_mirage2		MACH_MX53_MIRAGE2	MX53_MIRAGE2		3609
+mx53_efikasb		MACH_MX53_EFIKASB	MX53_EFIKASB		3610
+stm_b2000		MACH_STM_B2000		STM_B2000		3612
+m28evk			MACH_M28EVK		M28EVK			3613
+pda			MACH_PDA		PDA			3614
+meraki_mr58		MACH_MERAKI_MR58	MERAKI_MR58		3615
+kota2			MACH_KOTA2		KOTA2			3616
+letcool			MACH_LETCOOL		LETCOOL			3617
+mx27iat			MACH_MX27IAT		MX27IAT			3618
+apollo_td		MACH_APOLLO_TD		APOLLO_TD		3619
+arena			MACH_ARENA		ARENA			3620
+gsngateway		MACH_GSNGATEWAY		GSNGATEWAY		3621
+lf2000			MACH_LF2000		LF2000			3622
+bonito			MACH_BONITO		BONITO			3623
+asymptote		MACH_ASYMPTOTE		ASYMPTOTE		3624
+bst2brd			MACH_BST2BRD		BST2BRD			3625
+tx335s			MACH_TX335S		TX335S			3626
+pelco_tesla		MACH_PELCO_TESLA	PELCO_TESLA		3627
+rrhtestplat		MACH_RRHTESTPLAT	RRHTESTPLAT		3628
+vidtonic_pro		MACH_VIDTONIC_PRO	VIDTONIC_PRO		3629
+pl_apollo		MACH_PL_APOLLO		PL_APOLLO		3630
+pl_phoenix		MACH_PL_PHOENIX		PL_PHOENIX		3631
+m28cu3			MACH_M28CU3		M28CU3			3632
+vvbox_hd		MACH_VVBOX_HD		VVBOX_HD		3633
+coreware_sam9260_	MACH_COREWARE_SAM9260_	COREWARE_SAM9260_	3634
+marmaduke		MACH_MARMADUKE		MARMADUKE		3635
+amg_xlcore_camera	MACH_AMG_XLCORE_CAMERA	AMG_XLCORE_CAMERA	3636
+omap3_egf		MACH_OMAP3_EGF		OMAP3_EGF		3637
+smdk4212		MACH_SMDK4212		SMDK4212		3638
+dnp9200			MACH_DNP9200		DNP9200			3639
+tf101			MACH_TF101		TF101			3640
+omap3silvio		MACH_OMAP3SILVIO	OMAP3SILVIO		3641
+picasso2		MACH_PICASSO2		PICASSO2		3642
+vangogh2		MACH_VANGOGH2		VANGOGH2		3643
+olpc_xo_1_75		MACH_OLPC_XO_1_75	OLPC_XO_1_75		3644
+gx400			MACH_GX400		GX400			3645
+gs300			MACH_GS300		GS300			3646
+acer_a9			MACH_ACER_A9		ACER_A9			3647
+vivow_evm		MACH_VIVOW_EVM		VIVOW_EVM		3648
+veloce_cxq		MACH_VELOCE_CXQ		VELOCE_CXQ		3649
+veloce_cxm		MACH_VELOCE_CXM		VELOCE_CXM		3650
+p1852			MACH_P1852		P1852			3651
+naxy100			MACH_NAXY100		NAXY100			3652
+taishan			MACH_TAISHAN		TAISHAN			3653
+touchlink		MACH_TOUCHLINK		TOUCHLINK		3654
+stm32f103ze		MACH_STM32F103ZE	STM32F103ZE		3655
+mcx			MACH_MCX		MCX			3656
+stm_nmhdk_fli7610	MACH_STM_NMHDK_FLI7610	STM_NMHDK_FLI7610	3657
+top28x			MACH_TOP28X		TOP28X			3658
+okl4vp_microvisor	MACH_OKL4VP_MICROVISOR	OKL4VP_MICROVISOR	3659
+pop			MACH_POP		POP			3660
+layer			MACH_LAYER		LAYER			3661
+trondheim		MACH_TRONDHEIM		TRONDHEIM		3662
+eva			MACH_EVA		EVA			3663
+trust_taurus		MACH_TRUST_TAURUS	TRUST_TAURUS		3664
+ns2816_huashan		MACH_NS2816_HUASHAN	NS2816_HUASHAN		3665
+ns2816_yangcheng	MACH_NS2816_YANGCHENG	NS2816_YANGCHENG	3666
+p852			MACH_P852		P852			3667
+flea3			MACH_FLEA3		FLEA3			3668
+bowfin			MACH_BOWFIN		BOWFIN			3669
+mv88de3100		MACH_MV88DE3100		MV88DE3100		3670
+pia_am35x		MACH_PIA_AM35X		PIA_AM35X		3671
+cedar			MACH_CEDAR		CEDAR			3672
+picasso_e		MACH_PICASSO_E		PICASSO_E		3673
+samsung_e60		MACH_SAMSUNG_E60	SAMSUNG_E60		3674
+msm9615_cdp		MACH_MDM9615		MDM9615			3675
+sdvr_mini		MACH_SDVR_MINI		SDVR_MINI		3676
+omap3_ij3k		MACH_OMAP3_IJ3K		OMAP3_IJ3K		3677
+modasmc1		MACH_MODASMC1		MODASMC1		3678
+apq8064_rumi3		MACH_APQ8064_RUMI3	APQ8064_RUMI3		3679
+matrix506		MACH_MATRIX506		MATRIX506		3680
+msm9615_mtp		MACH_MSM9615_MTP	MSM9615_MTP		3681
+dm36x_spawndc		MACH_DM36X_SPAWNDC	DM36X_SPAWNDC		3682
+sff792			MACH_SFF792		SFF792			3683
+am335xiaevm		MACH_AM335XIAEVM	AM335XIAEVM		3684
+g3c2440			MACH_G3C2440		G3C2440			3685
+tion270			MACH_TION270		TION270			3686
+w22q7arm02		MACH_W22Q7ARM02		W22Q7ARM02		3687
+omap_cat		MACH_OMAP_CAT		OMAP_CAT		3688
+at91sam9n12ek		MACH_AT91SAM9N12EK	AT91SAM9N12EK		3689
+morrison		MACH_MORRISON		MORRISON		3690
+svdu			MACH_SVDU		SVDU			3691
+lpp01			MACH_LPP01		LPP01			3692
+ubc283			MACH_UBC283		UBC283			3693
+zeppelin		MACH_ZEPPELIN		ZEPPELIN		3694
+motus			MACH_MOTUS		MOTUS			3695
+neomainboard		MACH_NEOMAINBOARD	NEOMAINBOARD		3696
+devkit3250		MACH_DEVKIT3250		DEVKIT3250		3697
+devkit7000		MACH_DEVKIT7000		DEVKIT7000		3698
+fmc_uic			MACH_FMC_UIC		FMC_UIC			3699
+fmc_dcm			MACH_FMC_DCM		FMC_DCM			3700
+batwm			MACH_BATWM		BATWM			3701
+atlas6cb		MACH_ATLAS6CB		ATLAS6CB		3702
+quattro_f		MACH_QUATTROF		QUATTROF		3703
+quattro_u		MACH_QUATTROU		QUATTROU		3704
+blue			MACH_BLUE		BLUE			3705
+colorado		MACH_COLORADO		COLORADO		3706
+popc			MACH_POPC		POPC			3707
+promwad_jade		MACH_PROMWAD_JADE	PROMWAD_JADE		3708
+amp			MACH_AMP		AMP			3709
+gnet_amp		MACH_GNET_AMP		GNET_AMP		3710
+toques			MACH_TOQUES		TOQUES			3711
+apx4devkit		MACH_APX4DEVKIT		APX4DEVKIT		3712
+dct_storm		MACH_DCT_STORM		DCT_STORM		3713
+dm8168z3		MACH_Z3			Z3			3714
+owl			MACH_OWL		OWL			3715
+cogent_csb1741		MACH_COGENT_CSB1741	COGENT_CSB1741		3716
+omap3_kiko		MACH_OMAP3		OMAP3			3717
+adillustra610		MACH_ADILLUSTRA610	ADILLUSTRA610		3718
+ecafe_na04		MACH_ECAFE_NA04		ECAFE_NA04		3719
+popct			MACH_POPCT		POPCT			3720
+omap3_helena		MACH_OMAP3_HELENA	OMAP3_HELENA		3721
+ach			MACH_ACH		ACH			3722
+module_dtb		MACH_MODULE_DTB		MODULE_DTB		3723
+ratebox			MACH_RACKBOX		RACKBOX			3724
+oslo_elisabeth		MACH_OSLO_ELISABETH	OSLO_ELISABETH		3725
+tt01			MACH_TT01		TT01			3726
+msm8930_cdp		MACH_MSM8930_CDP	MSM8930_CDP		3727
+msm8930_mtp		MACH_MSM8930_MTP	MSM8930_MTP		3728
+msm8930_fluid		MACH_MSM8930_FLUID	MSM8930_FLUID		3729
+ltu11			MACH_LTU11		LTU11			3730
+am1808_spawnco		MACH_AM1808_SPAWNCO	AM1808_SPAWNCO		3731
+flx6410			MACH_FLX6410		FLX6410			3732
+mx6q_qsb		MACH_MX6Q_QSB		MX6Q_QSB		3733
+mx53_plt424		MACH_MX53_PLT424	MX53_PLT424		3734
+jasmine			MACH_JASMINE		JASMINE			3735
+l138_owlboard_plus	MACH_L138_OWLBOARD_PLUS	L138_OWLBOARD_PLUS	3736
+wr21			MACH_WR21		WR21			3737
+peaboy			MACH_PEABOY		PEABOY			3739
+mx28_plato		MACH_MX28_PLATO		MX28_PLATO		3740
+kacom2			MACH_KACOM2		KACOM2			3741
+slco			MACH_SLCO		SLCO			3742
+imx51pico		MACH_IMX51PICO		IMX51PICO		3743
+glink1			MACH_GLINK1		GLINK1			3744
+diamond			MACH_DIAMOND		DIAMOND			3745
+d9000			MACH_D9000		D9000			3746
+w5300e01		MACH_W5300E01		W5300E01		3747
+im6000			MACH_IM6000		IM6000			3748
+mx51_fred51		MACH_MX51_FRED51	MX51_FRED51		3749
+stm32f2			MACH_STM32F2		STM32F2			3750
+ville			MACH_VILLE		VILLE			3751
+ptip_murnau		MACH_PTIP_MURNAU	PTIP_MURNAU		3752
+ptip_classic		MACH_PTIP_CLASSIC	PTIP_CLASSIC		3753
+mx53grb			MACH_MX53GRB		MX53GRB			3754
+gagarin			MACH_GAGARIN		GAGARIN			3755
+msm7627a_qrd1		MACH_MSM7X27A_QRD1	MSM7X27A_QRD1		3756
+nas2big			MACH_NAS2BIG		NAS2BIG			3757
+superfemto		MACH_SUPERFEMTO		SUPERFEMTO		3758
+teufel			MACH_TEUFEL		TEUFEL			3759
+dinara			MACH_DINARA		DINARA			3760
+vanquish		MACH_VANQUISH		VANQUISH		3761
+zipabox1		MACH_ZIPABOX1		ZIPABOX1		3762
+u9540			MACH_U9540		U9540			3763
+jet			MACH_JET		JET			3764
+smdk4412		MACH_SMDK4412		SMDK4412		3765
+elite			MACH_ELITE		ELITE			3766
+spear320_hmi		MACH_SPEAR320_HMI	SPEAR320_HMI		3767
+ontario			MACH_ONTARIO		ONTARIO			3768
+mx6q_sabrelite		MACH_MX6Q_SABRELITE	MX6Q_SABRELITE		3769
+vc200			MACH_VC200		VC200			3770
+msm7625a_ffa		MACH_MSM7625A_FFA	MSM7625A_FFA		3771
+msm7625a_surf		MACH_MSM7625A_SURF	MSM7625A_SURF		3772
+benthossbp		MACH_BENTHOSSBP		BENTHOSSBP		3773
+smdk5210		MACH_SMDK5210		SMDK5210		3774
+empq2300		MACH_EMPQ2300		EMPQ2300		3775
+minipos			MACH_MINIPOS		MINIPOS			3776
+omap5_sevm		MACH_OMAP5_SEVM		OMAP5_SEVM		3777
+shelter			MACH_SHELTER		SHELTER			3778
+omap3_devkit8500	MACH_OMAP3_DEVKIT8500	OMAP3_DEVKIT8500	3779
+edgetd			MACH_EDGETD		EDGETD			3780
+copperyard		MACH_COPPERYARD		COPPERYARD		3781
+edge_test		MACH_EDGE		EDGE			3782
+edge_u			MACH_EDGE_U		EDGE_U			3783
+edge_td			MACH_EDGE_TD		EDGE_TD			3784
+wdss			MACH_WDSS		WDSS			3785
+dl_pb25			MACH_DL_PB25		DL_PB25			3786
+dss11			MACH_DSS11		DSS11			3787
+cpa			MACH_CPA		CPA			3788
+aptp2000		MACH_APTP2000		APTP2000		3789
+marzen			MACH_MARZEN		MARZEN			3790
+st_turbine		MACH_ST_TURBINE		ST_TURBINE		3791
+gtl_it3300		MACH_GTL_IT3300		GTL_IT3300		3792
+mx6_mule		MACH_MX6_MULE		MX6_MULE		3793
+v7pxa_dt		MACH_V7PXA_DT		V7PXA_DT		3794
+v7mmp_dt		MACH_V7MMP_DT		V7MMP_DT		3795
+dragon7			MACH_DRAGON7		DRAGON7			3796
+krome			MACH_KROME		KROME			3797
+oratisdante		MACH_ORATISDANTE	ORATISDANTE		3798
+fathom			MACH_FATHOM		FATHOM			3799
+dns325			MACH_DNS325		DNS325			3800
+sarnen			MACH_SARNEN		SARNEN			3801
+ubisys_g1		MACH_UBISYS_G1		UBISYS_G1		3802
+mx53_pf1		MACH_MX53_PF1		MX53_PF1		3803
+asanti			MACH_ASANTI		ASANTI			3804
+volta			MACH_VOLTA		VOLTA			3805
+potenza			MACH_S5P6450		S5P6450			3806
+knight			MACH_KNIGHT		KNIGHT			3807
+beaglebone		MACH_BEAGLEBONE		BEAGLEBONE		3808
+becker			MACH_BECKER		BECKER			3809
+fc360			MACH_FC360		FC360			3810
+pmi2_xls		MACH_PMI2_XLS		PMI2_XLS		3811
+taranto			MACH_TARANTO		TARANTO			3812
+plutux			MACH_PLUTUX		PLUTUX			3813
+ipmp_medcom		MACH_IPMP_MEDCOM	IPMP_MEDCOM		3814
+absolut			MACH_ABSOLUT		ABSOLUT			3815
+awpb3			MACH_AWPB3		AWPB3			3816
+nfp32xx_dt		MACH_NFP32XX_DT		NFP32XX_DT		3817
+dl_pb53			MACH_DL_PB53		DL_PB53			3818
+acu_ii			MACH_ACU_II		ACU_II			3819
+avalon			MACH_AVALON		AVALON			3820
+sphinx			MACH_SPHINX		SPHINX			3821
+titan_t			MACH_TITAN_T		TITAN_T			3822
+harvest_boris		MACH_HARVEST_BORIS	HARVEST_BORIS		3823
+mach_msm7x30_m3s	MACH_MACH_MSM7X30_M3S	MACH_MSM7X30_M3S	3824
+smdk5250		MACH_SMDK5250		SMDK5250		3825
+imxt_lite		MACH_IMXT_LITE		IMXT_LITE		3826
+imxt_std		MACH_IMXT_STD		IMXT_STD		3827
+imxt_log		MACH_IMXT_LOG		IMXT_LOG		3828
+imxt_nav		MACH_IMXT_NAV		IMXT_NAV		3829
+imxt_full		MACH_IMXT_FULL		IMXT_FULL		3830
+ag09015			MACH_AG09015		AG09015			3831
+am3517_mt_ventoux	MACH_AM3517_MT_VENTOUX	AM3517_MT_VENTOUX	3832
+dp1arm9			MACH_DP1ARM9		DP1ARM9			3833
+picasso_m		MACH_PICASSO_M		PICASSO_M		3834
+video_gadget		MACH_VIDEO_GADGET	VIDEO_GADGET		3835
+mtt_om3x		MACH_MTT_OM3X		MTT_OM3X		3836
+mx6q_arm2		MACH_MX6Q_ARM2		MX6Q_ARM2		3837
+picosam9g45		MACH_PICOSAM9G45	PICOSAM9G45		3838
+vpm_dm365		MACH_VPM_DM365		VPM_DM365		3839
+bonfire			MACH_BONFIRE		BONFIRE			3840
+mt2p2d			MACH_MT2P2D		MT2P2D			3841
+sigpda01		MACH_SIGPDA01		SIGPDA01		3842
+cn27			MACH_CN27		CN27			3843
+mx25_cwtap		MACH_MX25_CWTAP		MX25_CWTAP		3844
+apf28			MACH_APF28		APF28			3845
+pelco_maxwell		MACH_PELCO_MAXWELL	PELCO_MAXWELL		3846
+ge_phoenix		MACH_GE_PHOENIX		GE_PHOENIX		3847
+empc_a500		MACH_EMPC_A500		EMPC_A500		3848
+ims_arm9		MACH_IMS_ARM9		IMS_ARM9		3849
+mini2416		MACH_MINI2416		MINI2416		3850
+mini2450		MACH_MINI2450		MINI2450		3851
+mini310			MACH_MINI310		MINI310			3852
+spear_hurricane		MACH_SPEAR_HURRICANE	SPEAR_HURRICANE		3853
+mt7208			MACH_MT7208		MT7208			3854
+lpc178x			MACH_LPC178X		LPC178X			3855
+farleys			MACH_FARLEYS		FARLEYS			3856
+efm32gg_dk3750		MACH_EFM32GG_DK3750	EFM32GG_DK3750		3857
+zeus_board		MACH_ZEUS_BOARD		ZEUS_BOARD		3858
+cc51			MACH_CC51		CC51			3859
+fxi_c210		MACH_FXI_C210		FXI_C210		3860
+msm8627_cdp		MACH_MSM8627_CDP	MSM8627_CDP		3861
+msm8627_mtp		MACH_MSM8627_MTP	MSM8627_MTP		3862
+armadillo800eva		MACH_ARMADILLO800EVA	ARMADILLO800EVA		3863
+primou			MACH_PRIMOU		PRIMOU			3864
+primoc			MACH_PRIMOC		PRIMOC			3865
+primoct			MACH_PRIMOCT		PRIMOCT			3866
+a9500			MACH_A9500		A9500			3867
+pue_td			MACH_PULSE_TD		PULSE_TD		3868
+pluto			MACH_PLUTO		PLUTO			3869
+acfx100			MACH_ACFX100		ACFX100			3870
+msm8625_rumi3		MACH_MSM8625_RUMI3	MSM8625_RUMI3		3871
+valente			MACH_VALENTE		VALENTE			3872
+crfs_rfeye		MACH_CRFS_RFEYE		CRFS_RFEYE		3873
+rfeye			MACH_RFEYE		RFEYE			3874
+phidget_sbc3		MACH_PHIDGET_SBC3	PHIDGET_SBC3		3875
+tcw_mika		MACH_TCW_MIKA		TCW_MIKA		3876
+imx28_egf		MACH_IMX28_EGF		IMX28_EGF		3877
+valente_wx		MACH_VALENTE_WX		VALENTE_WX		3878
+huangshans		MACH_HUANGSHANS		HUANGSHANS		3879
+bosphorus1		MACH_BOSPHORUS1		BOSPHORUS1		3880
+prima			MACH_PRIMA		PRIMA			3881
+meson3_skt		MACH_M3_SKT		M3_SKT			3882
+meson3_ref		MACH_M3_REF		M3_REF			3883
+evita_ulk		MACH_EVITA_ULK		EVITA_ULK		3884
+merisc600		MACH_MERISC600		MERISC600		3885
+dolak			MACH_DOLAK		DOLAK			3886
+sbc53			MACH_SBC53		SBC53			3887
+elite_ulk		MACH_ELITE_ULK		ELITE_ULK		3888
+pov2			MACH_POV2		POV2			3889
+ipod_touch_2g		MACH_IPOD_TOUCH_2G	IPOD_TOUCH_2G		3890
+da850_pqab		MACH_DA850_PQAB		DA850_PQAB		3891
+fermi			MACH_FERMI		FERMI			3892
+ccardwmx28		MACH_CCARDWMX28		CCARDWMX28		3893
+ccardmx28		MACH_CCARDMX28		CCARDMX28		3894
+fs20_fcm2050		MACH_FS20_FCM2050	FS20_FCM2050		3895
+kinetis			MACH_KINETIS		KINETIS			3896
+kai			MACH_KAI		KAI			3897
+bcthb2			MACH_BCTHB2		BCTHB2			3898
+inels3_cu		MACH_INELS3_CU		INELS3_CU		3899
+da850_juniper		MACH_JUNIPER		JUNIPER			3900
+da850_apollo		MACH_DA850_APOLLO	DA850_APOLLO		3901
+tracnas			MACH_TRACNAS		TRACNAS			3902
+mityarm335x		MACH_MITYARM335X	MITYARM335X		3903
+xcgz7x			MACH_XCGZ7X		XCGZ7X			3904
+cubox			MACH_CUBOX		CUBOX			3905
+terminator		MACH_TERMINATOR		TERMINATOR		3906
+eye03			MACH_EYE03		EYE03			3907
+kota3			MACH_KOTA3		KOTA3			3908
+mx53_nitrogen_k		MACH_MX5		MX5			3909
+pscpe			MACH_PSCPE		PSCPE			3910
+akt1100			MACH_AKT1100		AKT1100			3911
+pcaaxl2			MACH_PCAAXL2		PCAAXL2			3912
+primodd_ct		MACH_PRIMODD_CT		PRIMODD_CT		3913
+nsbc			MACH_NSBC		NSBC			3914
+meson2_skt		MACH_MESON2_SKT		MESON2_SKT		3915
+meson2_ref		MACH_MESON2_REF		MESON2_REF		3916
+ccardwmx28js		MACH_CCARDWMX28JS	CCARDWMX28JS		3917
+ccardmx28js		MACH_CCARDMX28JS	CCARDMX28JS		3918
+indico			MACH_INDICO		INDICO			3919
+msm8960dt		MACH_MSM8960DT		MSM8960DT		3920
+primods			MACH_PRIMODS		PRIMODS			3921
+beluga_m1388		MACH_BELUGA_M1388	BELUGA_M1388		3922
+primotd			MACH_PRIMOTD		PRIMOTD			3923
+varan_master		MACH_VARAN_MASTER	VARAN_MASTER		3924
+primodd			MACH_PRIMODD		PRIMODD			3925
+jetduo			MACH_JETDUO		JETDUO			3926
+mx53_umobo		MACH_MX53_UMOBO		MX53_UMOBO		3927
+trats			MACH_TRATS		TRATS			3928
+starcraft		MACH_STARCRAFT		STARCRAFT		3929
+qseven_tegra2		MACH_QSEVEN_TEGRA2	QSEVEN_TEGRA2		3930
+lichee_sun4i_devbd	MACH_LICHEE_SUN4I_DEVBD	LICHEE_SUN4I_DEVBD	3931
+movenow			MACH_MOVENOW		MOVENOW			3932
+golf_u			MACH_GOLF_U		GOLF_U			3933
+msm7627a_evb		MACH_MSM7627A_EVB	MSM7627A_EVB		3934
+rambo			MACH_RAMBO		RAMBO			3935
+golfu			MACH_GOLFU		GOLFU			3936
+mango310		MACH_MANGO310		MANGO310		3937
+dns343			MACH_DNS343		DNS343			3938
+var_som_om44		MACH_VAR_SOM_OM44	VAR_SOM_OM44		3939
+naon			MACH_NAON		NAON			3940
+vp4000			MACH_VP4000		VP4000			3941
+impcard			MACH_IMPCARD		IMPCARD			3942
+smoovcam		MACH_SMOOVCAM		SMOOVCAM		3943
+cobham3725		MACH_COBHAM3725		COBHAM3725		3944
+cobham3730		MACH_COBHAM3730		COBHAM3730		3945
+cobham3703		MACH_COBHAM3703		COBHAM3703		3946
+quetzal			MACH_QUETZAL		QUETZAL			3947
+apq8064_cdp		MACH_APQ8064_CDP	APQ8064_CDP		3948
+apq8064_mtp		MACH_APQ8064_MTP	APQ8064_MTP		3949
+apq8064_fluid		MACH_APQ8064_FLUID	APQ8064_FLUID		3950
+apq8064_liquid		MACH_APQ8064_LIQUID	APQ8064_LIQUID		3951
+mango210		MACH_MANGO210		MANGO210		3952
+mango100		MACH_MANGO100		MANGO100		3953
+mango24			MACH_MANGO24		MANGO24			3954
+mango64			MACH_MANGO64		MANGO64			3955
+nsa320			MACH_NSA320		NSA320			3956
+elv_ccu2		MACH_ELV_CCU2		ELV_CCU2		3957
+triton_x00		MACH_TRITON_X00		TRITON_X00		3958
+triton_1500_2000	MACH_TRITON_1500_2000	TRITON_1500_2000	3959
+pogoplugv4		MACH_POGOPLUGV4		POGOPLUGV4		3960
+venus_cl		MACH_VENUS_CL		VENUS_CL		3961
+vulcano_g20		MACH_VULCANO_G20	VULCANO_G20		3962
+sgs_i9100		MACH_SGS_I9100		SGS_I9100		3963
+stsv2			MACH_STSV2		STSV2			3964
+csb1724			MACH_CSB1724		CSB1724			3965
+omapl138_lcdk		MACH_OMAPL138_LCDK	OMAPL138_LCDK		3966
+jel_dd			MACH_JEWEL_DD		JEWEL_DD		3967
+pvd_mx25		MACH_PVD_MX25		PVD_MX25		3968
+meson6_skt		MACH_MESON6_SKT		MESON6_SKT		3969
+meson6_ref		MACH_MESON6_REF		MESON6_REF		3970
+pxm			MACH_PXM		PXM			3971
+stuttgart		MACH_S3			S3			3972
+pogoplugv3		MACH_POGOPLUGV3		POGOPLUGV3		3973
+mlp89626		MACH_MLP89626		MLP89626		3974
+iomegahmndce		MACH_IOMEGAHMNDCE	IOMEGAHMNDCE		3975
+pogoplugv3pci		MACH_POGOPLUGV3PCI	POGOPLUGV3PCI		3976
+bntv250			MACH_BNTV250		BNTV250			3977
+mx53_qseven		MACH_MX53_QSEVEN	MX53_QSEVEN		3978
+gtl_it1100		MACH_GTL_IT1100		GTL_IT1100		3979
+mx6q_sabresd		MACH_MX6Q_SABRESD	MX6Q_SABRESD		3980
+mt4			MACH_MT4		MT4			3981
+jumbo_d			MACH_JUMBO_D		JUMBO_D			3982
+jumbo_i			MACH_JUMBO_I		JUMBO_I			3983
+fs20_dmp		MACH_FS20_DMP		FS20_DMP		3984
+dns320			MACH_DNS320		DNS320			3985
+mx28bacos		MACH_MX28BACOS		MX28BACOS		3986
+tl80			MACH_TL80		TL80			3987
+polatis_nic_1001	MACH_POLATIS_NIC_1001	POLATIS_NIC_1001	3988
+tely			MACH_TELY		TELY			3989
+u8520			MACH_U8520		U8520			3990
+manta			MACH_MANTA		MANTA			3991
+spear1340_lcad		MACH_SPEAR_EM_S900	SPEAR_EM_S900		3992
+mpq8064_cdp		MACH_MPQ8064_CDP	MPQ8064_CDP		3993
+mpq8064_hrd		MACH_MPQ8064_STB	MPQ8064_STB		3994
+mpq8064_dtv		MACH_MPQ8064_DTV	MPQ8064_DTV		3995
+dm368som		MACH_DM368SOM		DM368SOM		3996
+gprisb2			MACH_GPRISB2		GPRISB2			3997
+chammid			MACH_CHAMMID		CHAMMID			3998
+seoul2			MACH_SEOUL2		SEOUL2			3999
+omap4_nooktablet	MACH_OMAP4_NOOKTABLET	OMAP4_NOOKTABLET	4000
+aalto			MACH_AALTO		AALTO			4001
+metro			MACH_METRO		METRO			4002
+cydm3730		MACH_CYDM3730		CYDM3730		4003
+tqma53			MACH_TQMA53		TQMA53			4004
+msm7627a_qrd3		MACH_MSM7627A_QRD3	MSM7627A_QRD3		4005
+mx28_canby		MACH_MX28_CANBY		MX28_CANBY		4006
+tiger			MACH_TIGER		TIGER			4007
+pcats_9307_type_a	MACH_PCATS_9307_TYPE_A	PCATS_9307_TYPE_A	4008
+pcats_9307_type_o	MACH_PCATS_9307_TYPE_O	PCATS_9307_TYPE_O	4009
+pcats_9307_type_r	MACH_PCATS_9307_TYPE_R	PCATS_9307_TYPE_R	4010
+streamplug		MACH_STREAMPLUG		STREAMPLUG		4011
+icechicken_dev		MACH_ICECHICKEN_DEV	ICECHICKEN_DEV		4012
+hedgehog		MACH_HEDGEHOG		HEDGEHOG		4013
+yusend_obc		MACH_YUSEND_OBC		YUSEND_OBC		4014
+imxninja		MACH_IMXNINJA		IMXNINJA		4015
+omap4_jarod		MACH_OMAP4_JAROD	OMAP4_JAROD		4016
+eco5_pk			MACH_ECO5_PK		ECO5_PK			4017
+qj2440			MACH_QJ2440		QJ2440			4018
+mx6q_mercury		MACH_MX6Q_MERCURY	MX6Q_MERCURY		4019
+cm6810			MACH_CM6810		CM6810			4020
+omap4_torpedo		MACH_OMAP4_TORPEDO	OMAP4_TORPEDO		4021
+nsa310			MACH_NSA310		NSA310			4022
+tmx536			MACH_TMX536		TMX536			4023
+ktt20			MACH_KTT20		KTT20			4024
+dragonix		MACH_DRAGONIX		DRAGONIX		4025
+lungching		MACH_LUNGCHING		LUNGCHING		4026
+bulogics		MACH_BULOGICS		BULOGICS		4027
+mx535_sx		MACH_MX535_SX		MX535_SX		4028
+ngui3250		MACH_NGUI3250		NGUI3250		4029
+salutec_dac		MACH_SALUTEC_DAC	SALUTEC_DAC		4030
+loco			MACH_LOCO		LOCO			4031
+ctera_plug_usi		MACH_CTERA_PLUG_USI	CTERA_PLUG_USI		4032
+scepter			MACH_SCEPTER		SCEPTER			4033
+sga			MACH_SGA		SGA			4034
+p_81_j5			MACH_P_81_J5		P_81_J5			4035
+p_81_o4			MACH_P_81_O4		P_81_O4			4036
+msm8625_surf		MACH_MSM8625_SURF	MSM8625_SURF		4037
+carallon_shark		MACH_CARALLON_SHARK	CARALLON_SHARK		4038
+lsgc_icam		MACH_LSGCICAM		LSGCICAM		4039
+ordog			MACH_ORDOG		ORDOG			4040
+puente_io		MACH_PUENTE_IO		PUENTE_IO		4041
+msm8625_evb		MACH_MSM8625_EVB	MSM8625_EVB		4042
+ev_am1707		MACH_EV_AM1707		EV_AM1707		4043
+ev_am1707e2		MACH_EV_AM1707E2	EV_AM1707E2		4044
+ev_am3517e2		MACH_EV_AM3517E2	EV_AM3517E2		4045
+calabria		MACH_CALABRIA		CALABRIA		4046
+ev_imx287		MACH_EV_IMX287		EV_IMX287		4047
+erau			MACH_ERAU		ERAU			4048
+sichuan			MACH_SICHUAN		SICHUAN			4049
+sopdm			MACH_WIRMA3		WIRMA3			4050
+davinci_da850		MACH_DAVINCI_DA850	DAVINCI_DA850		4051
+omap138_trunarc		MACH_OMAP138_TRUNARC	OMAP138_TRUNARC		4052
+bcm4761			MACH_BCM4761		BCM4761			4053
+picasso_e2		MACH_PICASSO_E2		PICASSO_E2		4054
+picasso_mf		MACH_PICASSO_MF		PICASSO_MF		4055
+miro			MACH_MIRO		MIRO			4056
+at91sam9g20ewon3	MACH_AT91SAM9G20EWON3	AT91SAM9G20EWON3	4057
+yoyo			MACH_YOYO		YOYO			4058
+windjkl			MACH_WINDJKL		WINDJKL			4059
+monarudo		MACH_MONARUDO		MONARUDO		4060
+batan			MACH_BATAN		BATAN			4061
+tadao			MACH_TADAO		TADAO			4062
+baso			MACH_BASO		BASO			4063
+mahon			MACH_MAHON		MAHON			4064
+villec2			MACH_VILLEC2		VILLEC2			4065
+asi1230			MACH_ASI1230		ASI1230			4066
+alaska			MACH_ALASKA		ALASKA			4067
+swarco_shdsl2		MACH_SWARCO_SHDSL2	SWARCO_SHDSL2		4068
+oxrtu			MACH_OXRTU		OXRTU			4069
+omap5_panda		MACH_OMAP5_PANDA	OMAP5_PANDA		4070
+imx286			MACH_MX28XDI		MX28XDI			4071
+c8000			MACH_C8000		C8000			4072
+bje_display3_5		MACH_BJE_DISPLAY3_5	BJE_DISPLAY3_5		4073
+picomod7		MACH_PICOMOD7		PICOMOD7		4074
+picocom5		MACH_PICOCOM5		PICOCOM5		4075
+qblissa8		MACH_QBLISSA8		QBLISSA8		4076
+armstonea8		MACH_ARMSTONEA8		ARMSTONEA8		4077
+netdcu14		MACH_NETDCU14		NETDCU14		4078
+at91sam9x5_epiphan	MACH_AT91SAM9X5_EPIPHAN	AT91SAM9X5_EPIPHAN	4079
+p2u			MACH_P2U		P2U			4080
+doris			MACH_DORIS		DORIS			4081
+j49			MACH_J49		J49			4082
+vdss2e			MACH_VDSS2E		VDSS2E			4083
+vc300			MACH_VC300		VC300			4084
+ns115_pad_test		MACH_NS115_PAD_TEST	NS115_PAD_TEST		4085
+ns115_pad_ref		MACH_NS115_PAD_REF	NS115_PAD_REF		4086
+ns115_phone_test	MACH_NS115_PHONE_TEST	NS115_PHONE_TEST	4087
+ns115_phone_ref		MACH_NS115_PHONE_REF	NS115_PHONE_REF		4088
+golfc			MACH_GOLFC		GOLFC			4089
+xerox_olympus		MACH_XEROX_OLYMPUS	XEROX_OLYMPUS		4090
+mx6sl_arm2		MACH_MX6SL_ARM2		MX6SL_ARM2		4091
+csb1701_csb1726		MACH_CSB1701_CSB1726	CSB1701_CSB1726		4092
+at91sam9xeek		MACH_AT91SAM9XEEK	AT91SAM9XEEK		4093
+ebv210			MACH_EBV210		EBV210			4094
+msm7627a_qrd7		MACH_MSM7627A_QRD7	MSM7627A_QRD7		4095
+svthin			MACH_SVTHIN		SVTHIN			4096
+duovero			MACH_DUOVERO		DUOVERO			4097
+chupacabra		MACH_CHUPACABRA		CHUPACABRA		4098
+scorpion		MACH_SCORPION		SCORPION		4099
+davinci_he_hmi10	MACH_DAVINCI_HE_HMI10	DAVINCI_HE_HMI10	4100
+topkick			MACH_TOPKICK		TOPKICK			4101
+m3_auguestrush		MACH_M3_AUGUESTRUSH	M3_AUGUESTRUSH		4102
+ipc335x			MACH_IPC335X		IPC335X			4103
+sun4i			MACH_SUN4I		SUN4I			4104
+imx233_olinuxino	MACH_IMX233_OLINUXINO	IMX233_OLINUXINO	4105
+k2_wl			MACH_K2_WL		K2_WL			4106
+k2_ul			MACH_K2_UL		K2_UL			4107
+k2_cl			MACH_K2_CL		K2_CL			4108
+minbari_w		MACH_MINBARI_W		MINBARI_W		4109
+minbari_m		MACH_MINBARI_M		MINBARI_M		4110
+k035			MACH_K035		K035			4111
+ariel			MACH_ARIEL		ARIEL			4112
+arielsaarc		MACH_ARIELSAARC		ARIELSAARC		4113
+arieldkb		MACH_ARIELDKB		ARIELDKB		4114
+armadillo810		MACH_ARMADILLO810	ARMADILLO810		4115
+tam335x			MACH_TAM335X		TAM335X			4116
+grouper			MACH_GROUPER		GROUPER			4117
+mpcsa21_9g20		MACH_MPCSA21_9G20	MPCSA21_9G20		4118
+m6u_cpu			MACH_M6U_CPU		M6U_CPU			4119
+davinci_dp10		MACH_DAVINCI_DP10	DAVINCI_DP10		4120
+ginkgo			MACH_GINKGO		GINKGO			4121
+cgt_qmx6		MACH_CGT_QMX6		CGT_QMX6		4122
+profpga			MACH_PROFPGA		PROFPGA			4123
+acfx100oc		MACH_ACFX100OC		ACFX100OC		4124
+acfx100nb		MACH_ACFX100NB		ACFX100NB		4125
+capricorn		MACH_CAPRICORN		CAPRICORN		4126
+pisces			MACH_PISCES		PISCES			4127
+aries			MACH_ARIES		ARIES			4128
+cancer			MACH_CANCER		CANCER			4129
+leo			MACH_LEO		LEO			4130
+virgo			MACH_VIRGO		VIRGO			4131
+sagittarius		MACH_SAGITTARIUS	SAGITTARIUS		4132
+devil			MACH_DEVIL		DEVIL			4133
+ballantines		MACH_BALLANTINES	BALLANTINES		4134
+omap3_procerusvpu	MACH_OMAP3_PROCERUSVPU	OMAP3_PROCERUSVPU	4135
+my27			MACH_MY27		MY27			4136
+sun6i			MACH_SUN6I		SUN6I			4137
+sun5i			MACH_SUN5I		SUN5I			4138
+mx512_mx		MACH_MX512_MX		MX512_MX		4139
+kzm9g			MACH_KZM9G		KZM9G			4140
+vdstbn			MACH_VDSTBN		VDSTBN			4141
+cfa10036		MACH_CFA10036		CFA10036		4142
+cfa10049		MACH_CFA10049		CFA10049		4143
+pcm051			MACH_PCM051		PCM051			4144
+vybrid_vf7xx		MACH_VYBRID_VF7XX	VYBRID_VF7XX		4145
+vybrid_vf6xx		MACH_VYBRID_VF6XX	VYBRID_VF6XX		4146
+vybrid_vf5xx		MACH_VYBRID_VF5XX	VYBRID_VF5XX		4147
+vybrid_vf4xx		MACH_VYBRID_VF4XX	VYBRID_VF4XX		4148
+aria_g25		MACH_ARIA_G25		ARIA_G25		4149
+bcm21553		MACH_BCM21553		BCM21553		4150
+smdk5410		MACH_SMDK5410		SMDK5410		4151
+lpc18xx			MACH_LPC18XX		LPC18XX			4152
+oratisparty		MACH_ORATISPARTY	ORATISPARTY		4153
+qseven			MACH_QSEVEN		QSEVEN			4154
+gmv_generic		MACH_GMV_GENERIC	GMV_GENERIC		4155
+th_link_eth		MACH_TH_LINK_ETH	TH_LINK_ETH		4156
+tn_muninn		MACH_TN_MUNINN		TN_MUNINN		4157
+rampage			MACH_RAMPAGE		RAMPAGE			4158
+visstrim_mv10		MACH_VISSTRIM_MV10	VISSTRIM_MV10		4159
+monacotdu		MACH_MONACO_TDU		MONACO_TDU		4160
+monacoul		MACH_MONACO_UL		MONACO_UL		4161
+enrc2u			MACH_ENRC2_U		ENRC2_U			4162
+evitareul		MACH_EVITA_UL		EVITA_UL		4163
+mx28_wilma		MACH_MX28_WILMA		MX28_WILMA		4164
+monacou			MACH_MONACO_U		MONACO_U		4165
+msm8625_ffa		MACH_MSM8625_FFA	MSM8625_FFA		4166
+vpu101			MACH_VPU101		VPU101			4167
+operaul			MACH_OPERA_UL		OPERA_UL		4168
+baileys			MACH_BAILEYS		BAILEYS			4169
+familybox		MACH_FAMILYBOX		FAMILYBOX		4170
+ensemble_mx35		MACH_ENSEMBLE_MX35	ENSEMBLE_MX35		4171
+sc_sps_1		MACH_SC_SPS_1		SC_SPS_1		4172
+ucsimply_sam9260	MACH_UCSIMPLY_SAM9260	UCSIMPLY_SAM9260	4173
+unicorn			MACH_UNICORN		UNICORN			4174
+m9g45a			MACH_M9G45A		M9G45A			4175
+mtwebif			MACH_MTWEBIF		MTWEBIF			4176
+playstone		MACH_PLAYSTONE		PLAYSTONE		4177
+chelsea			MACH_CHELSEA		CHELSEA			4178
+bayern			MACH_BAYERN		BAYERN			4179
+mitwo			MACH_MITWO		MITWO			4180
+mx25_noah		MACH_MX25_NOAH		MX25_NOAH		4181
+stm_b2020		MACH_STM_B2020		STM_B2020		4182
+annax_src		MACH_ANNAX_SRC		ANNAX_SRC		4183
+ionics_stratus		MACH_IONICS_STRATUS	IONICS_STRATUS		4184
+hugo			MACH_HUGO		HUGO			4185
+em300			MACH_EM300		EM300			4186
+mmp3_qseven		MACH_MMP3_QSEVEN	MMP3_QSEVEN		4187
+bosphorus2		MACH_BOSPHORUS2		BOSPHORUS2		4188
+tt2200			MACH_TT2200		TT2200			4189
+ocelot3			MACH_OCELOT3		OCELOT3			4190
+tek_cobra		MACH_TEK_COBRA		TEK_COBRA		4191
+protou			MACH_PROTOU		PROTOU			4192


Property changes on: trunk/sys/arm/conf/mach-types
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/freescale/fsl_ocotp.c
===================================================================
--- trunk/sys/arm/freescale/fsl_ocotp.c	                        (rev 0)
+++ trunk/sys/arm/freescale/fsl_ocotp.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,206 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014 Steven Lawrance <stl at koffein.net>
+ * 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: stable/10/sys/arm/freescale/fsl_ocotp.c 273656 2014-10-26 02:09:58Z ian $");
+
+/*
+ * Access to the Freescale i.MX6 On-Chip One-Time-Programmable Memory
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/rman.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+
+#include <arm/freescale/fsl_ocotpreg.h>
+#include <arm/freescale/fsl_ocotpvar.h>
+
+/*
+ * Find the physical address and size of the ocotp registers and devmap them,
+ * returning a pointer to the virtual address of the base.
+ *
+ * XXX This is temporary until we've worked out all the details of controlling
+ * the load order of devices.  In an ideal world this device would be up and
+ * running before anything that needs it.  When we're at a point to make that
+ * happen, this little block of code, and the few lines in fsl_ocotp_read_4()
+ * that refer to it can be deleted.
+ */
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <dev/fdt/fdt_common.h>
+#include <machine/devmap.h>
+
+static uint32_t   *ocotp_regs;
+static vm_size_t   ocotp_size;
+
+static void
+fsl_ocotp_devmap(void)
+{
+	phandle_t child, root;
+	u_long base, size;
+
+	if ((root = OF_finddevice("/")) == 0)
+		goto fatal;
+	if ((child = fdt_depth_search_compatible(root, "fsl,imx6q-ocotp", 0)) == 0)
+		goto fatal;
+	if (fdt_regsize(child, &base, &size) != 0)
+		goto fatal;
+
+	ocotp_size = (vm_size_t)size;
+
+	if ((ocotp_regs = pmap_mapdev((vm_offset_t)base, ocotp_size)) == NULL)
+		goto fatal;
+
+	return;
+fatal:
+	panic("cannot find/map the ocotp registers");
+}
+/* XXX end of temporary code */
+
+struct ocotp_softc {
+	device_t	dev;
+	struct resource	*mem_res;
+};
+
+static struct ocotp_softc *ocotp_sc;
+
+static inline uint32_t
+RD4(struct ocotp_softc *sc, bus_size_t off)
+{
+
+	return (bus_read_4(sc->mem_res, off));
+}
+
+static int
+ocotp_detach(device_t dev)
+{
+
+	/* The ocotp registers are always accessible. */
+	return (EBUSY);
+}
+
+static int
+ocotp_attach(device_t dev)
+{
+	struct ocotp_softc *sc;
+	int err, rid;
+
+	sc = device_get_softc(dev);
+	sc->dev = dev;
+
+	/* Allocate bus_space resources. */
+	rid = 0;
+	sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	    RF_ACTIVE);
+	if (sc->mem_res == NULL) {
+		device_printf(dev, "Cannot allocate memory resources\n");
+		err = ENXIO;
+		goto out;
+	}
+
+	ocotp_sc = sc;
+
+	/* We're done with the temporary mapping now. */
+	if (ocotp_regs != NULL)
+		pmap_unmapdev((vm_offset_t)ocotp_regs, ocotp_size);
+
+	err = 0;
+
+out:
+	if (err != 0)
+		ocotp_detach(dev);
+
+	return (err);
+}
+
+static int
+ocotp_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (ofw_bus_is_compatible(dev, "fsl,imx6q-ocotp") == 0)
+		return (ENXIO);
+
+	device_set_desc(dev, 
+	    "Freescale On-Chip One-Time-Programmable Memory");
+
+	return (BUS_PROBE_DEFAULT);
+}
+
+uint32_t
+fsl_ocotp_read_4(bus_size_t off)
+{
+
+	if (off > FSL_OCOTP_LAST_REG)
+		panic("fsl_ocotp_read_4: offset out of range");
+
+	/* If we have a softcontext use the regular bus_space read. */
+	if (ocotp_sc != NULL)
+		return (RD4(ocotp_sc, off));
+
+	/*
+	 * Otherwise establish a tempory device mapping if necessary, and read
+	 * the device without any help from bus_space.
+	 *
+	 * XXX Eventually the code from there down can be deleted.
+	 */
+	if (ocotp_regs == NULL)
+		fsl_ocotp_devmap();
+
+	return (ocotp_regs[off / 4]);
+}
+
+static device_method_t ocotp_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,  ocotp_probe),
+	DEVMETHOD(device_attach, ocotp_attach),
+	DEVMETHOD(device_detach, ocotp_detach),
+
+	DEVMETHOD_END
+};
+
+static driver_t ocotp_driver = {
+	"ocotp",
+	ocotp_methods,
+	sizeof(struct ocotp_softc)
+};
+
+static devclass_t ocotp_devclass;
+
+EARLY_DRIVER_MODULE(ocotp, simplebus, ocotp_driver, ocotp_devclass, 0, 0,
+    BUS_PASS_CPU + BUS_PASS_ORDER_FIRST);
+


Property changes on: trunk/sys/arm/freescale/fsl_ocotp.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/fsl_ocotpreg.h
===================================================================
--- trunk/sys/arm/freescale/fsl_ocotpreg.h	                        (rev 0)
+++ trunk/sys/arm/freescale/fsl_ocotpreg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,89 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014 Steven Lawrance <stl at koffein.net>
+ * 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: stable/10/sys/arm/freescale/fsl_ocotpreg.h 266200 2014-05-15 22:35:04Z ian $
+ */
+
+#ifndef	FSL_OCOTPREG_H
+#define	FSL_OCOTPREG_H
+
+#define	FSL_OCOTP_CTRL				0x000
+#define	FSL_OCOTP_CTRL_SET			0x004
+#define	FSL_OCOTP_CTRL_CLR			0x008
+#define	FSL_OCOTP_CTRL_TOG			0x00C
+#define	FSL_OCOTP_TIMING			0x010
+#define	FSL_OCOTP_DATA				0x020
+#define	FSL_OCOTP_READ_CTRL			0x030
+#define	FSL_OCOTP_READ_FUSE_DATA		0x040
+#define	FSL_OCOTP_SW_STICKY			0x050
+#define	FSL_OCOTP_SCS				0x060
+#define	FSL_OCOTP_SCS_SET			0x064
+#define	FSL_OCOTP_SCS_CLR			0x068
+#define	FSL_OCOTP_SCS_TOG			0x06C
+#define	FSL_OCOTP_VERSION			0x090
+#define	FSL_OCOTP_LOCK				0x400
+#define	FSL_OCOTP_CFG0				0x410
+#define	FSL_OCOTP_CFG1				0x420
+#define	FSL_OCOTP_CFG2				0x430
+#define	FSL_OCOTP_CFG3				0x440
+#define	  FSL_OCOTP_CFG3_SPEED_SHIFT		  16
+#define	  FSL_OCOTP_CFG3_SPEED_MASK		  \
+    (0x03 << FSL_OCOTP_CFG3_SPEED_SHIFT)
+#define	  FSL_OCOTP_CFG3_SPEED_792MHZ		  0
+#define	  FSL_OCOTP_CFG3_SPEED_852MHZ		  1
+#define	  FSL_OCOTP_CFG3_SPEED_996MHZ		  2
+#define	  FSL_OCOTP_CFG3_SPEED_1200MHZ		  3
+#define	FSL_OCOTP_CFG4				0x450
+#define	FSL_OCOTP_CFG5				0x460
+#define	FSL_OCOTP_CFG6				0x470
+#define	FSL_OCOTP_MEM0				0x480
+#define	FSL_OCOTP_MEM1				0x490
+#define	FSL_OCOTP_MEM2				0x4A0
+#define	FSL_OCOTP_MEM3				0x4B0
+#define	FSL_OCOTP_ANA0				0x4D0
+#define	FSL_OCOTP_ANA1				0x4E0
+#define	FSL_OCOTP_ANA2				0x4F0
+#define	FSL_OCOTP_SRK0				0x580
+#define	FSL_OCOTP_SRK1				0x590
+#define	FSL_OCOTP_SRK2				0x5A0
+#define	FSL_OCOTP_SRK3				0x5B0
+#define	FSL_OCOTP_SRK4				0x5C0
+#define	FSL_OCOTP_SRK5				0x5D0
+#define	FSL_OCOTP_SRK6				0x5E0
+#define	FSL_OCOTP_SRK7				0x5F0
+#define	FSL_OCOTP_HSJC_RESP0			0x600
+#define	FSL_OCOTP_HSJC_RESP1			0x610
+#define	FSL_OCOTP_MAC0				0x620
+#define	FSL_OCOTP_MAC1				0x630
+#define	FSL_OCOTP_GP1				0x660
+#define	FSL_OCOTP_GP2				0x670
+#define	FSL_OCOTP_MISC_CONF			0x6D0
+#define	FSL_OCOTP_FIELD_RETURN			0x6E0
+#define	FSL_OCOTP_SRK_REVOKE			0x6F0
+
+#define	FSL_OCOTP_LAST_REG			FSL_OCOTP_SRK_REVOKE
+
+#endif


Property changes on: trunk/sys/arm/freescale/fsl_ocotpreg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/fsl_ocotpvar.h
===================================================================
--- trunk/sys/arm/freescale/fsl_ocotpvar.h	                        (rev 0)
+++ trunk/sys/arm/freescale/fsl_ocotpvar.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,35 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014 Steven Lawrance <stl at koffein.net>
+ * 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: stable/10/sys/arm/freescale/fsl_ocotpvar.h 266200 2014-05-15 22:35:04Z ian $
+ */
+
+#ifndef	FSL_OCOTPVAR_H
+#define	FSL_OCOTPVAR_H
+
+uint32_t fsl_ocotp_read_4(bus_size_t _offset);
+
+#endif


Property changes on: trunk/sys/arm/freescale/fsl_ocotpvar.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/imx/console.c
===================================================================
--- trunk/sys/arm/freescale/imx/console.c	                        (rev 0)
+++ trunk/sys/arm/freescale/imx/console.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,178 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012, 2013 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Oleksandr Rybalko under sponsorship
+ * from the FreeBSD Foundation.
+ *
+ * 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.
+ */
+
+/* Simple UART console driver for Freescale i.MX515 */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/freescale/imx/console.c 253914 2013-08-03 13:31:10Z ian $");
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/cons.h>
+#include <sys/consio.h>
+#include <sys/kernel.h>
+
+/* Allow it to be predefined, to be able to use another UART for console */
+#ifndef	IMX_UART_BASE
+#define	IMX_UART_BASE	0xe3fbc000 /* imx51 UART1 */
+#endif
+
+#define	IMX_RXD			0x00
+#define	IMX_TXD			0x40
+
+#define	IMX_UFCR		0x90
+#define	IMX_USR1		0x94
+#define	IMX_USR1_TRDY		(1 << 13)
+
+#define	IMX_USR2		0x98
+#define	IMX_USR2_RDR		(1 << 0)
+#define	IMX_USR2_TXFE		(1 << 14)
+#define	IMX_USR2_TXDC		(1 << 3)
+
+#define	IMX_UTS			0xb4
+#define	IMX_UTS_TXFULL		(1 << 4)
+
+/*
+ * The base address of the uart registers.
+ *
+ * This is global so that it can be changed on the fly from the outside.  For
+ * example, set imx_uart_base=physaddr and then call cninit() as the first two
+ * lines of initarm() and enjoy printf() availability through the tricky bits of
+ * startup.  After initarm() switches from physical to virtual addressing, just
+ * set imx_uart_base=virtaddr and printf keeps working.
+ */
+uint32_t imx_uart_base = IMX_UART_BASE;
+
+/*
+ * uart related funcs
+ */
+static uint32_t
+ub_getreg(uint32_t off)
+{
+
+	return *((volatile uint32_t *)(imx_uart_base + off));
+}
+
+static void
+ub_setreg(uint32_t off, uint32_t val)
+{
+
+	*((volatile uint32_t *)(imx_uart_base + off)) = val;
+}
+
+static int
+ub_tstc(void)
+{
+
+	return ((ub_getreg(IMX_USR2) & IMX_USR2_RDR) ? 1 : 0);
+}
+
+static int
+ub_getc(void)
+{
+
+	while (!ub_tstc());
+		__asm __volatile("nop");
+
+	return (ub_getreg(IMX_RXD) & 0xff);
+}
+
+static void
+ub_putc(unsigned char c)
+{
+
+	if (c == '\n')
+		ub_putc('\r');
+
+	while (ub_getreg(IMX_UTS) & IMX_UTS_TXFULL)
+		__asm __volatile("nop");
+
+	ub_setreg(IMX_TXD, c);
+}
+
+static cn_probe_t	uart_cnprobe;
+static cn_init_t	uart_cninit;
+static cn_term_t	uart_cnterm;
+static cn_getc_t	uart_cngetc;
+static cn_putc_t	uart_cnputc;
+static cn_grab_t	uart_cngrab;
+static cn_ungrab_t	uart_cnungrab;
+
+static void
+uart_cngrab(struct consdev *cp)
+{
+
+}
+
+static void
+uart_cnungrab(struct consdev *cp)
+{
+
+}
+
+
+static void
+uart_cnprobe(struct consdev *cp)
+{
+
+        sprintf(cp->cn_name, "uart");
+        cp->cn_pri = CN_NORMAL;
+}
+
+static void
+uart_cninit(struct consdev *cp)
+{
+
+        /* Init fifo trigger levels to 32 bytes, refclock div to 2. */
+	ub_setreg(IMX_UFCR, 0x00004210);
+}
+
+static void
+uart_cnputc(struct consdev *cp, int c)
+{
+
+	ub_putc(c);
+}
+
+static int
+uart_cngetc(struct consdev * cp)
+{
+
+	return ub_getc();
+}
+
+static void
+uart_cnterm(struct consdev * cp)
+{
+
+}
+
+CONSOLE_DRIVER(uart);


Property changes on: trunk/sys/arm/freescale/imx/console.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/imx/files.imx51
===================================================================
--- trunk/sys/arm/freescale/imx/files.imx51	                        (rev 0)
+++ trunk/sys/arm/freescale/imx/files.imx51	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,52 @@
+# $FreeBSD: stable/10/sys/arm/freescale/imx/files.imx51 278727 2015-02-13 22:32:02Z ian $
+arm/arm/bus_space_asm_generic.S		standard
+arm/arm/bus_space_generic.c		standard
+arm/arm/cpufunc_asm_armv5.S		standard
+arm/arm/cpufunc_asm_arm11.S		standard
+arm/arm/cpufunc_asm_armv7.S		standard
+kern/kern_clocksource.c			standard
+
+# Init
+arm/freescale/imx/imx_common.c		standard
+arm/freescale/imx/imx_machdep.c		standard
+arm/freescale/imx/imx51_machdep.c	standard
+arm/arm/bus_space_base.c		standard
+
+# Dummy serial console
+#arm/freescale/imx/console.c		standard
+
+# TrustZone Interrupt Controller
+arm/freescale/imx/tzic.c		standard
+
+# IOMUX - external pins multiplexor
+arm/freescale/imx/imx_iomux.c		standard
+
+# GPIO
+arm/freescale/imx/imx_gpio.c		optional gpio
+
+# Generic Periodic Timer
+arm/freescale/imx/imx_gpt.c		standard
+
+# Clock Configuration Manager
+arm/freescale/imx/imx51_ccm.c		standard
+
+# i.MX5xx PATA controller
+dev/ata/chipsets/ata-fsl.c		optional imxata
+
+# UART driver
+dev/uart/uart_dev_imx.c			optional uart
+
+# USB OH3 controller (1 OTG, 3 EHCI)
+arm/freescale/imx/imx_nop_usbphy.c	optional echi
+dev/usb/controller/ehci_imx.c		optional ehci
+
+# Watchdog
+arm/freescale/imx/imx_wdog.c		optional imxwdt
+
+# i2c
+arm/freescale/imx/imx_i2c.c		optional fsliic
+
+# IPU - Image Processing Unit (frame buffer also)
+arm/freescale/imx/imx51_ipuv3.c		optional sc
+arm/freescale/imx/imx51_ipuv3_fbd.c	optional vt
+dev/vt/hw/fb/vt_early_fb.c		optional vt


Property changes on: trunk/sys/arm/freescale/imx/files.imx51
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/freescale/imx/files.imx53
===================================================================
--- trunk/sys/arm/freescale/imx/files.imx53	                        (rev 0)
+++ trunk/sys/arm/freescale/imx/files.imx53	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,59 @@
+# $FreeBSD: stable/10/sys/arm/freescale/imx/files.imx53 278727 2015-02-13 22:32:02Z ian $
+arm/arm/bus_space_asm_generic.S		standard
+arm/arm/bus_space_generic.c		standard
+arm/arm/cpufunc_asm_armv5.S		standard
+arm/arm/cpufunc_asm_arm11.S		standard
+arm/arm/cpufunc_asm_armv7.S		standard
+kern/kern_clocksource.c			standard
+
+# Init
+arm/freescale/imx/imx_common.c		standard
+arm/freescale/imx/imx_machdep.c		standard
+arm/freescale/imx/imx53_machdep.c	standard
+arm/arm/bus_space_base.c		standard
+
+# Special serial console for debuging early boot code
+#arm/freescale/imx/console.c		standard
+
+# UART driver (includes serial console support)
+dev/uart/uart_dev_imx.c 		optional uart
+
+# TrustZone Interrupt Controller
+arm/freescale/imx/tzic.c		standard
+
+# IOMUX - external pins multiplexor
+arm/freescale/imx/imx_iomux.c		standard
+
+# GPIO
+arm/freescale/imx/imx_gpio.c		optional gpio
+
+# Generic Periodic Timer
+arm/freescale/imx/imx_gpt.c		standard
+
+# Clock Configuration Manager
+arm/freescale/imx/imx51_ccm.c		standard
+
+# i.MX5xx PATA controller
+dev/ata/chipsets/ata-fsl.c		optional imxata
+
+# SDHCI/MMC
+arm/freescale/imx/imx_sdhci.c		optional sdhci
+
+# USB OH3 controller (1 OTG, 3 EHCI)
+arm/freescale/imx/imx_nop_usbphy.c	optional ehci
+dev/usb/controller/ehci_imx.c		optional ehci
+
+# Watchdog
+arm/freescale/imx/imx_wdog.c		optional imxwdt
+
+# i2c
+arm/freescale/imx/imx_i2c.c		optional fsliic
+
+# IPU - Image Processing Unit (frame buffer also)
+arm/freescale/imx/imx51_ipuv3.c		optional sc
+arm/freescale/imx/imx51_ipuv3_fbd.c	optional vt
+dev/vt/hw/fb/vt_early_fb.c		optional vt
+
+# Fast Ethernet Controller
+dev/ffec/if_ffec.c 			optional ffec
+


Property changes on: trunk/sys/arm/freescale/imx/files.imx53
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/freescale/imx/files.imx6
===================================================================
--- trunk/sys/arm/freescale/imx/files.imx6	                        (rev 0)
+++ trunk/sys/arm/freescale/imx/files.imx6	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,73 @@
+# $FreeBSD: stable/10/sys/arm/freescale/imx/files.imx6 283500 2015-05-24 18:59:45Z ian $
+
+#
+# Standard ARM support.
+#
+arm/arm/bus_space_asm_generic.S		standard
+arm/arm/bus_space_generic.c		standard
+arm/arm/cpufunc_asm_arm11.S		standard
+arm/arm/cpufunc_asm_armv5.S		standard
+arm/arm/cpufunc_asm_armv7.S		standard
+kern/kern_clocksource.c			standard
+
+#
+# Standard imx6 devices and support.
+#
+arm/arm/gic.c				standard
+arm/arm/pl310.c				standard
+arm/arm/bus_space_base.c		standard
+arm/arm/mpcore_timer.c			standard
+arm/freescale/fsl_ocotp.c		standard
+arm/freescale/imx/imx6_anatop.c		standard
+arm/freescale/imx/imx6_ccm.c		standard
+arm/freescale/imx/imx6_machdep.c	standard
+arm/freescale/imx/imx6_mp.c		optional smp
+arm/freescale/imx/imx6_pl310.c		standard
+arm/freescale/imx/imx_iomux.c		standard
+arm/freescale/imx/imx_machdep.c		standard
+arm/freescale/imx/imx_gpt.c		standard
+arm/freescale/imx/imx_gpio.c		optional gpio
+arm/freescale/imx/imx_i2c.c		optional fsliic
+arm/freescale/imx/imx6_sdma.c		optional sdma
+arm/freescale/imx/imx6_audmux.c		optional sound
+arm/freescale/imx/imx6_ssi.c		optional sound
+
+#
+# Optional devices.
+#
+arm/freescale/imx/imx_sdhci.c		optional sdhci
+
+arm/freescale/imx/imx_wdog.c		optional imxwdt
+
+dev/ffec/if_ffec.c			optional ffec
+
+dev/uart/uart_dev_imx.c			optional uart
+
+dev/usb/controller/ehci_imx.c		optional ehci
+arm/freescale/imx/imx6_usbphy.c		optional ehci
+
+#
+# Low-level serial console for debugging early kernel startup.
+#
+#arm/freescale/imx/console.c  		standard
+
+#
+# Not ready yet...
+#
+#arm/freescale/imx/imx51_ipuv3.c  	optional sc
+
+# SDMA firmware
+sdma_fw.c				optional sdma_fw		\
+	compile-with	"${AWK} -f $S/tools/fw_stub.awk sdma-imx6q-to1.bin:sdma_fw -msdma -c${.TARGET}" \
+	no-implicit-rule before-depend local				\
+	clean		"sdma_fw.c"
+sdma-imx6q-to1.fwo			optional sdma_fw		\
+	dependency	"sdma-imx6q-to1.bin"				\
+	compile-with	"${LD} -b binary -d -warn-common -r -d -o ${.TARGET} sdma-imx6q-to1.bin" \
+	no-implicit-rule						\
+	clean		"sdma-imx6q-to1.fwo"
+sdma-imx6q-to1.bin			optional sdma_fw		\
+	dependency	"$S/contrib/dev/imx/sdma-imx6q-to1.bin.uu"	\
+	compile-with	"uudecode < $S/contrib/dev/imx/sdma-imx6q-to1.bin.uu" \
+	no-obj no-implicit-rule						\
+	clean		"sdma-imx6q-to1.bin"


Property changes on: trunk/sys/arm/freescale/imx/files.imx6
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/freescale/imx/imx51_ccm.c
===================================================================
--- trunk/sys/arm/freescale/imx/imx51_ccm.c	                        (rev 0)
+++ trunk/sys/arm/freescale/imx/imx51_ccm.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,590 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: imx51_ccm.c,v 1.1 2012/04/17 09:33:31 bsh Exp $	*/
+/*
+ * Copyright (c) 2010, 2011, 2012  Genetec Corporation.  All rights reserved.
+ * Written by Hashimoto Kenichi for Genetec Corporation.
+ *
+ * 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 GENETEC CORPORATION ``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 GENETEC CORPORATION
+ * 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.
+ */
+
+/*-
+ * Copyright (c) 2012, 2013 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * Portions of this software were developed by Oleksandr Rybalko
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * 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.
+ */
+
+/*
+ * Clock Controller Module (CCM)
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/freescale/imx/imx51_ccm.c 273659 2014-10-26 02:25:34Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+
+#include <arm/freescale/imx/imx51_ccmvar.h>
+#include <arm/freescale/imx/imx51_ccmreg.h>
+#include <arm/freescale/imx/imx51_dpllreg.h>
+#include <arm/freescale/imx/imx_ccmvar.h>
+#include <arm/freescale/imx/imx_machdep.h>
+
+#define	IMXCCMDEBUG
+#undef	IMXCCMDEBUG
+
+#ifndef	IMX51_OSC_FREQ
+#define	IMX51_OSC_FREQ	(24 * 1000 * 1000)	/* 24MHz */
+#endif
+
+#ifndef	IMX51_CKIL_FREQ
+#define	IMX51_CKIL_FREQ	32768
+#endif
+
+struct imxccm_softc {
+	device_t	sc_dev;
+	struct resource *res[7];
+	u_int64_t 	pll_freq[IMX51_N_DPLLS];
+};
+
+struct imxccm_softc *ccm_softc = NULL;
+
+static uint64_t imx51_get_pll_freq(u_int);
+
+static int imxccm_match(device_t);
+static int imxccm_attach(device_t);
+
+static device_method_t imxccm_methods[] = {
+	DEVMETHOD(device_probe, imxccm_match),
+	DEVMETHOD(device_attach, imxccm_attach),
+
+	DEVMETHOD_END
+};
+
+static driver_t imxccm_driver = {
+	"imxccm",
+	imxccm_methods,
+	sizeof(struct imxccm_softc),
+};
+
+static devclass_t imxccm_devclass;
+
+EARLY_DRIVER_MODULE(imxccm, simplebus, imxccm_driver, imxccm_devclass, 0, 0,
+    BUS_PASS_CPU);
+
+static struct resource_spec imxccm_spec[] = {
+	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },	/* Global registers */
+	{ SYS_RES_MEMORY,	1,	RF_ACTIVE },	/* DPLLIP1 */
+	{ SYS_RES_MEMORY,	2,	RF_ACTIVE },	/* DPLLIP2 */
+	{ SYS_RES_MEMORY,	3,	RF_ACTIVE },	/* DPLLIP3 */
+	{ SYS_RES_IRQ,		0,	RF_ACTIVE },    /* 71 */
+	{ SYS_RES_IRQ,		1,	RF_ACTIVE },    /* 72 */
+	{ -1, 0 }
+};
+
+static int
+imxccm_match(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "fsl,imx51-ccm") &&
+	    !ofw_bus_is_compatible(dev, "fsl,imx53-ccm"))
+		return (ENXIO);
+
+	device_set_desc(dev, "Freescale Clock Control Module");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+imxccm_attach(device_t dev)
+{
+	struct imxccm_softc *sc;
+
+	sc = device_get_softc(dev);
+	sc->sc_dev = dev;
+
+	if (bus_alloc_resources(dev, imxccm_spec, sc->res)) {
+		device_printf(dev, "could not allocate resources\n");
+		return (ENXIO);
+	}
+
+	ccm_softc = sc;
+
+	imx51_get_pll_freq(1);
+	imx51_get_pll_freq(2);
+	imx51_get_pll_freq(3);
+
+	device_printf(dev, "PLL1=%lluMHz, PLL2=%lluMHz, PLL3=%lluMHz\n",
+	    sc->pll_freq[0] / 1000000,
+	    sc->pll_freq[1] / 1000000,
+	    sc->pll_freq[2] / 1000000);
+	device_printf(dev, "CPU clock=%d, UART clock=%d\n",
+	    imx51_get_clock(IMX51CLK_ARM_ROOT),
+	    imx51_get_clock(IMX51CLK_UART_CLK_ROOT));
+	device_printf(dev,
+	    "mainbus clock=%d, ahb clock=%d ipg clock=%d perclk=%d\n",
+	    imx51_get_clock(IMX51CLK_MAIN_BUS_CLK),
+	    imx51_get_clock(IMX51CLK_AHB_CLK_ROOT),
+	    imx51_get_clock(IMX51CLK_IPG_CLK_ROOT),
+	    imx51_get_clock(IMX51CLK_PERCLK_ROOT));
+
+
+	return (0);
+}
+
+u_int
+imx51_get_clock(enum imx51_clock clk)
+{
+	u_int freq;
+	u_int sel;
+	uint32_t cacrr;	/* ARM clock root register */
+	uint32_t ccsr;
+	uint32_t cscdr1;
+	uint32_t cscmr1;
+	uint32_t cbcdr;
+	uint32_t cbcmr;
+	uint32_t cdcr;
+
+	if (ccm_softc == NULL)
+		return (0);
+
+	switch (clk) {
+	case IMX51CLK_PLL1:
+	case IMX51CLK_PLL2:
+	case IMX51CLK_PLL3:
+		return ccm_softc->pll_freq[clk-IMX51CLK_PLL1];
+	case IMX51CLK_PLL1SW:
+		ccsr = bus_read_4(ccm_softc->res[0], CCMC_CCSR);
+		if ((ccsr & CCSR_PLL1_SW_CLK_SEL) == 0)
+			return ccm_softc->pll_freq[1-1];
+		/* step clock */
+		/* FALLTHROUGH */
+	case IMX51CLK_PLL1STEP:
+		ccsr = bus_read_4(ccm_softc->res[0], CCMC_CCSR);
+		switch ((ccsr & CCSR_STEP_SEL_MASK) >> CCSR_STEP_SEL_SHIFT) {
+		case 0:
+			return imx51_get_clock(IMX51CLK_LP_APM);
+		case 1:
+			return 0; /* XXX PLL bypass clock */
+		case 2:
+			return ccm_softc->pll_freq[2-1] /
+			    (1 + ((ccsr & CCSR_PLL2_DIV_PODF_MASK) >>
+				CCSR_PLL2_DIV_PODF_SHIFT));
+		case 3:
+			return ccm_softc->pll_freq[3-1] /
+			    (1 + ((ccsr & CCSR_PLL3_DIV_PODF_MASK) >>
+				CCSR_PLL3_DIV_PODF_SHIFT));
+		}
+		/*NOTREACHED*/
+	case IMX51CLK_PLL2SW:
+		ccsr = bus_read_4(ccm_softc->res[0], CCMC_CCSR);
+		if ((ccsr & CCSR_PLL2_SW_CLK_SEL) == 0)
+			return imx51_get_clock(IMX51CLK_PLL2);
+		return 0; /* XXX PLL2 bypass clk */
+	case IMX51CLK_PLL3SW:
+		ccsr = bus_read_4(ccm_softc->res[0], CCMC_CCSR);
+		if ((ccsr & CCSR_PLL3_SW_CLK_SEL) == 0)
+			return imx51_get_clock(IMX51CLK_PLL3);
+		return 0; /* XXX PLL3 bypass clk */
+
+	case IMX51CLK_LP_APM:
+		ccsr = bus_read_4(ccm_softc->res[0], CCMC_CCSR);
+		return (ccsr & CCSR_LP_APM) ?
+			    imx51_get_clock(IMX51CLK_FPM) : IMX51_OSC_FREQ;
+
+	case IMX51CLK_ARM_ROOT:
+		freq = imx51_get_clock(IMX51CLK_PLL1SW);
+		cacrr = bus_read_4(ccm_softc->res[0], CCMC_CACRR);
+		return freq / (cacrr + 1);
+
+		/* ... */
+	case IMX51CLK_MAIN_BUS_CLK_SRC:
+		cbcdr = bus_read_4(ccm_softc->res[0], CCMC_CBCDR);
+		if ((cbcdr & CBCDR_PERIPH_CLK_SEL) == 0)
+			freq = imx51_get_clock(IMX51CLK_PLL2SW);
+		else {
+			freq = 0;
+			cbcmr = bus_read_4(ccm_softc->res[0],  CCMC_CBCMR);
+			switch ((cbcmr & CBCMR_PERIPH_APM_SEL_MASK) >>
+				CBCMR_PERIPH_APM_SEL_SHIFT) {
+			case 0:
+				freq = imx51_get_clock(IMX51CLK_PLL1SW);
+				break;
+			case 1:
+				freq = imx51_get_clock(IMX51CLK_PLL3SW);
+				break;
+			case 2:
+				freq = imx51_get_clock(IMX51CLK_LP_APM);
+				break;
+			case 3:
+				/* XXX: error */
+				break;
+			}
+		}
+		return freq;
+	case IMX51CLK_MAIN_BUS_CLK:
+		freq = imx51_get_clock(IMX51CLK_MAIN_BUS_CLK_SRC);
+		cdcr = bus_read_4(ccm_softc->res[0], CCMC_CDCR);
+		return freq / (1 + ((cdcr & CDCR_PERIPH_CLK_DVFS_PODF_MASK) >>
+			CDCR_PERIPH_CLK_DVFS_PODF_SHIFT));
+	case IMX51CLK_AHB_CLK_ROOT:
+		freq = imx51_get_clock(IMX51CLK_MAIN_BUS_CLK);
+		cbcdr = bus_read_4(ccm_softc->res[0], CCMC_CBCDR);
+		return freq / (1 + ((cbcdr & CBCDR_AHB_PODF_MASK) >>
+				    CBCDR_AHB_PODF_SHIFT));
+	case IMX51CLK_IPG_CLK_ROOT:
+		freq = imx51_get_clock(IMX51CLK_AHB_CLK_ROOT);
+		cbcdr = bus_read_4(ccm_softc->res[0], CCMC_CBCDR);
+		return freq / (1 + ((cbcdr & CBCDR_IPG_PODF_MASK) >>
+				    CBCDR_IPG_PODF_SHIFT));
+
+	case IMX51CLK_PERCLK_ROOT:
+		cbcmr = bus_read_4(ccm_softc->res[0], CCMC_CBCMR);
+		if (cbcmr & CBCMR_PERCLK_IPG_SEL)
+			return imx51_get_clock(IMX51CLK_IPG_CLK_ROOT);
+		if (cbcmr & CBCMR_PERCLK_LP_APM_SEL)
+			freq = imx51_get_clock(IMX51CLK_LP_APM);
+		else
+			freq = imx51_get_clock(IMX51CLK_MAIN_BUS_CLK_SRC);
+		cbcdr = bus_read_4(ccm_softc->res[0], CCMC_CBCDR);
+
+#ifdef IMXCCMDEBUG
+		printf("cbcmr=%x cbcdr=%x\n", cbcmr, cbcdr);
+#endif
+
+		freq /= 1 + ((cbcdr & CBCDR_PERCLK_PRED1_MASK) >>
+			CBCDR_PERCLK_PRED1_SHIFT);
+		freq /= 1 + ((cbcdr & CBCDR_PERCLK_PRED2_MASK) >>
+			CBCDR_PERCLK_PRED2_SHIFT);
+		freq /= 1 + ((cbcdr & CBCDR_PERCLK_PODF_MASK) >>
+			CBCDR_PERCLK_PODF_SHIFT);
+		return freq;
+	case IMX51CLK_UART_CLK_ROOT:
+		cscdr1 = bus_read_4(ccm_softc->res[0], CCMC_CSCDR1);
+		cscmr1 = bus_read_4(ccm_softc->res[0], CCMC_CSCMR1);
+
+#ifdef IMXCCMDEBUG
+		printf("cscdr1=%x cscmr1=%x\n", cscdr1, cscmr1);
+#endif
+
+		sel = (cscmr1 & CSCMR1_UART_CLK_SEL_MASK) >>
+		    CSCMR1_UART_CLK_SEL_SHIFT;
+
+		freq = 0; /* shut up GCC */
+		switch (sel) {
+		case 0:
+		case 1:
+		case 2:
+			freq = imx51_get_clock(IMX51CLK_PLL1SW + sel);
+			break;
+		case 3:
+			freq = imx51_get_clock(IMX51CLK_LP_APM);
+			break;
+		}
+
+		return freq / (1 + ((cscdr1 & CSCDR1_UART_CLK_PRED_MASK) >>
+			CSCDR1_UART_CLK_PRED_SHIFT)) /
+		    (1 + ((cscdr1 & CSCDR1_UART_CLK_PODF_MASK) >>
+			CSCDR1_UART_CLK_PODF_SHIFT));
+	case IMX51CLK_IPU_HSP_CLK_ROOT:
+		freq = 0;
+		cbcmr = bus_read_4(ccm_softc->res[0],  CCMC_CBCMR);
+		switch ((cbcmr & CBCMR_IPU_HSP_CLK_SEL_MASK) >>
+				CBCMR_IPU_HSP_CLK_SEL_SHIFT) {
+			case 0:
+				freq = imx51_get_clock(IMX51CLK_ARM_AXI_A_CLK);
+				break;
+			case 1:
+				freq = imx51_get_clock(IMX51CLK_ARM_AXI_B_CLK);
+				break;
+			case 2:
+				freq = imx51_get_clock(
+					IMX51CLK_EMI_SLOW_CLK_ROOT);
+				break;
+			case 3:
+				freq = imx51_get_clock(IMX51CLK_AHB_CLK_ROOT);
+				break;
+			}
+		return freq;
+	default:
+		device_printf(ccm_softc->sc_dev,
+		    "clock %d: not supported yet\n", clk);
+		return 0;
+	}
+}
+
+
+static uint64_t
+imx51_get_pll_freq(u_int pll_no)
+{
+	uint32_t dp_ctrl;
+	uint32_t dp_op;
+	uint32_t dp_mfd;
+	uint32_t dp_mfn;
+	uint32_t mfi;
+	int32_t mfn;
+	uint32_t mfd;
+	uint32_t pdf;
+	uint32_t ccr;
+	uint64_t freq = 0;
+	u_int ref = 0;
+
+	KASSERT(1 <= pll_no && pll_no <= IMX51_N_DPLLS, ("Wrong PLL id"));
+
+	dp_ctrl = bus_read_4(ccm_softc->res[pll_no], DPLL_DP_CTL);
+
+	if (dp_ctrl & DP_CTL_HFSM) {
+		dp_op = bus_read_4(ccm_softc->res[pll_no], DPLL_DP_HFS_OP);
+		dp_mfd = bus_read_4(ccm_softc->res[pll_no], DPLL_DP_HFS_MFD);
+		dp_mfn = bus_read_4(ccm_softc->res[pll_no], DPLL_DP_HFS_MFN);
+	} else {
+		dp_op = bus_read_4(ccm_softc->res[pll_no], DPLL_DP_OP);
+		dp_mfd = bus_read_4(ccm_softc->res[pll_no], DPLL_DP_MFD);
+		dp_mfn = bus_read_4(ccm_softc->res[pll_no], DPLL_DP_MFN);
+	}
+
+	pdf = dp_op & DP_OP_PDF_MASK;
+	mfi = max(5, (dp_op & DP_OP_MFI_MASK) >> DP_OP_MFI_SHIFT);
+	mfd = dp_mfd;
+	if (dp_mfn & 0x04000000)
+		/* 27bit signed value */
+		mfn = (uint32_t)(0xf8000000 | dp_mfn);
+	else
+		mfn = dp_mfn;
+
+	switch (dp_ctrl &  DP_CTL_REF_CLK_SEL_MASK) {
+	case DP_CTL_REF_CLK_SEL_COSC:
+		/* Internal Oscillator */
+		/* TODO: get from FDT "fsl,imx-osc" */
+		ref = 24000000; /* IMX51_OSC_FREQ */
+		break;
+	case DP_CTL_REF_CLK_SEL_FPM:
+		ccr = bus_read_4(ccm_softc->res[0], CCMC_CCR);
+		if (ccr & CCR_FPM_MULT)
+		/* TODO: get from FDT "fsl,imx-ckil" */
+			ref = 32768 * 1024;
+		else
+		/* TODO: get from FDT "fsl,imx-ckil" */
+			ref = 32768 * 512;
+		break;
+	default:
+		ref = 0;
+	}
+
+	if (dp_ctrl & DP_CTL_REF_CLK_DIV)
+		ref /= 2;
+
+	ref *= 4;
+	freq = (int64_t)ref * mfi + (int64_t)ref * mfn / (mfd + 1);
+	freq /= pdf + 1;
+
+	if (!(dp_ctrl & DP_CTL_DPDCK0_2_EN))
+		freq /= 2;
+
+#ifdef IMXCCMDEBUG
+	printf("ref: %dKHz ", ref);
+	printf("dp_ctl: %08x ", dp_ctrl);
+	printf("pdf: %3d ", pdf);
+	printf("mfi: %3d ", mfi);
+	printf("mfd: %3d ", mfd);
+	printf("mfn: %3d ", mfn);
+	printf("pll: %d\n", (uint32_t)freq);
+#endif
+
+	ccm_softc->pll_freq[pll_no-1] = freq;
+
+	return (freq);
+}
+
+void
+imx51_clk_gating(int clk_src, int mode)
+{
+	int field, group;
+	uint32_t reg;
+
+	group = CCMR_CCGR_MODULE(clk_src);
+	field = clk_src % CCMR_CCGR_NSOURCE;
+	reg = bus_read_4(ccm_softc->res[0], CCMC_CCGR(group));
+	reg &= ~(0x03 << field * 2);
+	reg |= (mode << field * 2);
+	bus_write_4(ccm_softc->res[0], CCMC_CCGR(group), reg);
+}
+
+int
+imx51_get_clk_gating(int clk_src)
+{
+	uint32_t reg;
+
+	reg = bus_read_4(ccm_softc->res[0],
+	    CCMC_CCGR(CCMR_CCGR_MODULE(clk_src)));
+	return ((reg >> (clk_src % CCMR_CCGR_NSOURCE) * 2) & 0x03);
+}
+
+/*
+ * Code from here down is temporary, in lieu of a SoC-independent clock API.
+ */
+
+void
+imx_ccm_usb_enable(device_t dev)
+{
+	uint32_t regval;
+
+	/*
+	 * Select PLL2 as the source for the USB clock.
+	 * The default is PLL3, but U-boot changes it to PLL2.
+	 */
+	regval = bus_read_4(ccm_softc->res[0], CCMC_CSCMR1);
+	regval &= ~CSCMR1_USBOH3_CLK_SEL_MASK;
+	regval |= 1 << CSCMR1_USBOH3_CLK_SEL_SHIFT;
+	bus_write_4(ccm_softc->res[0], CCMC_CSCMR1, regval);
+
+	/*
+	 * Set the USB clock pre-divider to div-by-5, post-divider to div-by-2.
+	 */
+	regval = bus_read_4(ccm_softc->res[0], CCMC_CSCDR1);
+	regval &= ~CSCDR1_USBOH3_CLK_PODF_MASK;
+	regval &= ~CSCDR1_USBOH3_CLK_PRED_MASK;
+	regval |= 4 << CSCDR1_USBOH3_CLK_PRED_SHIFT;
+	regval |= 1 << CSCDR1_USBOH3_CLK_PODF_SHIFT;
+	bus_write_4(ccm_softc->res[0], CCMC_CSCDR1, regval);
+
+	/*
+	 * The same two clocks gates are used on imx51 and imx53.
+	 */
+	imx51_clk_gating(CCGR_USBOH3_IPG_AHB_CLK, CCGR_CLK_MODE_ALWAYS);
+	imx51_clk_gating(CCGR_USBOH3_60M_CLK, CCGR_CLK_MODE_ALWAYS);
+}
+
+void
+imx_ccm_usbphy_enable(device_t dev)
+{
+	uint32_t regval;
+
+	/*
+	 * Select PLL3 as the source for the USBPHY clock.  U-boot does this 
+	 * only for imx53, but the bit exists on imx51.  That seems a bit
+	 * strange, but we'll go with it until more is known.
+	 */
+	if (imx_soc_type() == IMXSOC_53) {
+		regval = bus_read_4(ccm_softc->res[0], CCMC_CSCMR1);
+		regval |= 1 << CSCMR1_USBPHY_CLK_SEL_SHIFT;
+		bus_write_4(ccm_softc->res[0], CCMC_CSCMR1, regval);
+	}
+
+	/*
+	 * For the imx51 there's just one phy gate control, enable it.
+	 */
+	if (imx_soc_type() == IMXSOC_51) {
+		imx51_clk_gating(CCGR_USB_PHY_CLK, CCGR_CLK_MODE_ALWAYS);
+		return;
+	}
+
+	/*
+	 * For imx53 we don't have a full set of clock defines yet, but the
+	 * datasheet says:
+	 *   gate reg 4, bits 13-12 usb ph2 clock (usb_phy2_clk_enable)
+	 *   gate reg 4, bits 11-10 usb ph1 clock (usb_phy1_clk_enable)
+	 *
+	 * We should use the fdt data for the device to figure out which of
+	 * the two we're working on, but for now just turn them both on.
+	 */
+	if (imx_soc_type() == IMXSOC_53) {
+		imx51_clk_gating(__CCGR_NUM(4, 5), CCGR_CLK_MODE_ALWAYS);
+		imx51_clk_gating(__CCGR_NUM(4, 6), CCGR_CLK_MODE_ALWAYS);
+		return;
+	}
+}
+
+uint32_t
+imx_ccm_ipg_hz(void)
+{
+
+	return (imx51_get_clock(IMX51CLK_IPG_CLK_ROOT));
+}
+
+uint32_t
+imx_ccm_sdhci_hz(void)
+{
+
+	return (imx51_get_clock(IMX51CLK_ESDHC1_CLK_ROOT));
+}
+
+uint32_t
+imx_ccm_perclk_hz(void)
+{
+
+	return (imx51_get_clock(IMX51CLK_PERCLK_ROOT));
+}
+
+uint32_t
+imx_ccm_uart_hz(void)
+{
+
+	return (imx51_get_clock(IMX51CLK_UART_CLK_ROOT));
+}
+
+uint32_t
+imx_ccm_ahb_hz(void)
+{
+
+	return (imx51_get_clock(IMX51CLK_AHB_CLK_ROOT));
+}


Property changes on: trunk/sys/arm/freescale/imx/imx51_ccm.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/imx/imx51_ccmreg.h
===================================================================
--- trunk/sys/arm/freescale/imx/imx51_ccmreg.h	                        (rev 0)
+++ trunk/sys/arm/freescale/imx/imx51_ccmreg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,259 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: imx51_ccmreg.h,v 1.1 2012/04/17 09:33:31 bsh Exp $	*/
+/*
+ * Copyright (c) 2011, 2012  Genetec Corporation.  All rights reserved.
+ * Written by Hashimoto Kenichi for Genetec Corporation.
+ *
+ * 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 GENETEC CORPORATION ``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 GENETEC CORPORATION
+ * 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.
+ */
+
+/*-
+ * Copyright (c) 2012, 2013 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * Portions of this software were developed by Oleksandr Rybalko
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * 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: stable/10/sys/arm/freescale/imx/imx51_ccmreg.h 259343 2013-12-13 22:12:37Z ian $
+ */
+
+#ifndef	_IMX51_CCMREG_H
+#define	_IMX51_CCMREG_H
+
+#include <sys/cdefs.h>
+
+/* register offset address */
+
+#define	CCMC_BASE	0x73fd4000
+#define	CCMC_CCR	0x0000
+#define		CCR_FPM_MULT			0x00001000
+#define	CCMC_CCDR	0x0004
+#define	CCMC_CSR	0x0008
+#define	CCMC_CCSR	0x000c
+#define		CCSR_LP_APM			0x00000200
+#define		CCSR_STEP_SEL_SHIFT		7
+#define		CCSR_STEP_SEL_MASK		0x00000180
+#define		CCSR_PLL2_DIV_PODF_SHIFT	5
+#define		CCSR_PLL2_DIV_PODF_MASK		0x00000060
+#define		CCSR_PLL3_DIV_PODF_SHIFT	3
+#define		CCSR_PLL3_DIV_PODF_MASK		0x00000030
+#define		CCSR_PLL1_SW_CLK_SEL		0x00000004
+#define		CCSR_PLL2_SW_CLK_SEL		0x00000002
+#define		CCSR_PLL3_SW_CLK_SEL		0x00000001
+#define	CCMC_CACRR	0x0010
+#define	CCMC_CBCDR	0x0014
+#define		CBCDR_DDR_HIGH_FREQ_CLK_SEL	0x40000000
+#define		CBCDR_DDR_CLK_PODF_SHIFT	27
+#define		CBCDR_DDR_CLK_PODF_MASK		0x38000000
+#define		CBCDR_EMI_CLK_SEL		0x04000000
+#define		CBCDR_PERIPH_CLK_SEL		0x02000000
+#define		CBCDR_EMI_SLOW_PODF_SHIFT	22
+#define		CBCDR_EMI_SLOW_PODF_MASK	0x01c00000
+#define		CBCDR_AXI_B_PODF_SHIFT		19
+#define		CBCDR_AXI_B_PODF_MASK		0x00380000
+#define		CBCDR_AXI_A_PODF_SHIFT		16
+#define		CBCDR_AXI_A_PODF_MASK		0x1fff0000
+#define		CBCDR_NFC_PODF_SHIFT		13
+#define		CBCDR_NFC_PODF_MASK		0x00018000
+#define		CBCDR_AHB_PODF_SHIFT		10
+#define		CBCDR_AHB_PODF_MASK		0x00001c00
+#define		CBCDR_IPG_PODF_SHIFT		8
+#define		CBCDR_IPG_PODF_MASK		0x00000300
+#define		CBCDR_PERCLK_PRED1_SHIFT	6
+#define		CBCDR_PERCLK_PRED1_MASK		0x000000c0
+#define		CBCDR_PERCLK_PRED2_SHIFT	3
+#define		CBCDR_PERCLK_PRED2_MASK		0x00000038
+#define		CBCDR_PERCLK_PODF_SHIFT		0
+#define		CBCDR_PERCLK_PODF_MASK 		0x00000007
+#define	CCMC_CBCMR	0x0018
+#define		CBCMR_PERIPH_APM_SEL_SHIFT	12
+#define		CBCMR_PERIPH_APM_SEL_MASK	0x00003000
+#define		CBCMR_IPU_HSP_CLK_SEL_SHIFT	6
+#define		CBCMR_IPU_HSP_CLK_SEL_MASK	0x000000c0
+#define		CBCMR_PERCLK_LP_APM_SEL		0x00000002
+#define		CBCMR_PERCLK_IPG_SEL		0x00000001
+#define	CCMC_CSCMR1	0x001c
+#define		CSCMR1_UART_CLK_SEL_SHIFT	24
+#define		CSCMR1_UART_CLK_SEL_MASK	0x03000000
+#define		CSCMR1_USBPHY_CLK_SEL_SHIFT	26
+#define		CSCMR1_USBPHY_CLK_SEL_MASK	0x04000000
+#define		CSCMR1_USBOH3_CLK_SEL_SHIFT	22
+#define		CSCMR1_USBOH3_CLK_SEL_MASK	0x00c00000
+#define	CCMC_CSCMR2	0x0020
+#define	CCMC_CSCDR1	0x0024
+#define		CSCDR1_UART_CLK_PRED_SHIFT	3
+#define		CSCDR1_UART_CLK_PRED_MASK	0x00000038
+#define		CSCDR1_UART_CLK_PODF_SHIFT	0
+#define		CSCDR1_UART_CLK_PODF_MASK	0x00000007
+#define		CSCDR1_USBOH3_CLK_PRED_SHIFT	8
+#define		CSCDR1_USBOH3_CLK_PRED_MASK	0x00000700
+#define		CSCDR1_USBOH3_CLK_PODF_SHIFT	6
+#define		CSCDR1_USBOH3_CLK_PODF_MASK	0x000000c0
+#define	CCMC_CS1CDR	0x0028
+#define	CCMC_CS2CDR	0x002c
+#define	CCMC_CDCDR	0x0030
+#define	CCMC_CSCDR2	0x0038
+#define	CCMC_CSCDR3	0x003c
+#define	CCMC_CSCDR4	0x0040
+#define	CCMC_CWDR	0x0044
+#define	CCMC_CDHIPR	0x0048
+#define	CCMC_CDCR	0x004c
+#define		CDCR_PERIPH_CLK_DVFS_PODF_SHIFT	0
+#define		CDCR_PERIPH_CLK_DVFS_PODF_MASK 	0x00000003
+#define	CCMC_CTOR	0x0050
+#define	CCMC_CLPCR	0x0054
+#define	CCMC_CISR	0x0058
+#define	CCMC_CIMR	0x005c
+#define	CCMC_CCOSR	0x0060
+#define	CCMC_CGPR	0x0064
+#define	CCMC_CCGR(n)	(0x0068 + (n) * 4)
+#define	CCMC_CMEOR	0x0084
+
+#define	CCMC_SIZE	0x88
+
+/* CCGR Clock Gate Register */
+
+#define	CCMR_CCGR_NSOURCE	16
+#define	CCMR_CCGR_NGROUPS	7
+#define	CCMR_CCGR_MODULE(clk)	((clk) / CCMR_CCGR_NSOURCE)
+#define	__CCGR_NUM(a, b)	((a) * 16 + (b))
+
+#define	CCGR_ARM_BUS_CLK		__CCGR_NUM(0, 0)
+#define	CCGR_ARM_AXI_CLK		__CCGR_NUM(0, 1)
+#define	CCGR_ARM_DEBUG_CLK		__CCGR_NUM(0, 2)
+#define	CCGR_TZIC_CLK			__CCGR_NUM(0, 3)
+#define	CCGR_DAP_CLK			__CCGR_NUM(0, 4)
+#define	CCGR_TPIU_CLK			__CCGR_NUM(0, 5)
+#define	CCGR_CTI2_CLK			__CCGR_NUM(0, 6)
+#define	CCGR_CTI3_CLK			__CCGR_NUM(0, 7)
+#define	CCGR_AHBMUX1_CLK		__CCGR_NUM(0, 8)
+#define	CCGR_AHBMUX2_CLK		__CCGR_NUM(0, 9)
+#define	CCGR_ROMCP_CLK			__CCGR_NUM(0, 10)
+#define	CCGR_ROM_CLK			__CCGR_NUM(0, 11)
+#define	CCGR_AIPS_TZ1_CLK		__CCGR_NUM(0, 12)
+#define	CCGR_AIPS_TZ2_CLK		__CCGR_NUM(0, 13)
+#define	CCGR_AHB_MAX_CLK		__CCGR_NUM(0, 14)
+#define	CCGR_IIM_CLK			__CCGR_NUM(0, 15)
+#define	CCGR_TMAX1_CLK			__CCGR_NUM(1, 0)
+#define	CCGR_TMAX2_CLK			__CCGR_NUM(1, 1)
+#define	CCGR_TMAX3_CLK			__CCGR_NUM(1, 2)
+#define	CCGR_UART1_CLK			__CCGR_NUM(1, 3)
+#define	CCGR_UART1_SERIAL_CLK		__CCGR_NUM(1, 4)
+#define	CCGR_UART2_CLK			__CCGR_NUM(1, 5)
+#define	CCGR_UART2_SERIAL_CLK		__CCGR_NUM(1, 6)
+#define	CCGR_UART3_CLK			__CCGR_NUM(1, 7)
+#define	CCGR_UART3_SERIAL_CLK		__CCGR_NUM(1, 8)
+#define	CCGR_I2C1_SERIAL_CLK		__CCGR_NUM(1, 9)
+#define	CCGR_I2C2_SERIAL_CLK		__CCGR_NUM(1, 10)
+#define	CCGR_HSI2C_CLK			__CCGR_NUM(1, 11)
+#define	CCGR_HSI2C_SERIAL_CLK		__CCGR_NUM(1, 12)
+#define	CCGR_FIRI_CLK			__CCGR_NUM(1, 13)
+#define	CCGR_FIRI_SERIAL_CLK		__CCGR_NUM(1, 14)
+#define	CCGR_SCC_CLK			__CCGR_NUM(1, 15)
+
+#define	CCGR_USB_PHY_CLK		__CCGR_NUM(2, 0)
+#define	CCGR_EPIT1_CLK			__CCGR_NUM(2, 1)
+#define	CCGR_EPIT1_SERIAL_CLK		__CCGR_NUM(2, 2)
+#define	CCGR_EPIT2_CLK			__CCGR_NUM(2, 3)
+#define	CCGR_EPIT2_SERIAL_CLK		__CCGR_NUM(2, 4)
+#define	CCGR_PWM1_CLK			__CCGR_NUM(2, 5)
+#define	CCGR_PWM1_SERIAL_CLK		__CCGR_NUM(2, 6)
+#define	CCGR_PWM2_CLK			__CCGR_NUM(2, 7)
+#define	CCGR_PWM2_SERIAL_CLK		__CCGR_NUM(2, 8)
+#define	CCGR_GPT_CLK			__CCGR_NUM(2, 9)
+#define	CCGR_GPT_SERIAL_CLK		__CCGR_NUM(2, 10)
+#define	CCGR_OWIRE_CLK			__CCGR_NUM(2, 11)
+#define	CCGR_FEC_CLK			__CCGR_NUM(2, 12)
+#define	CCGR_USBOH3_IPG_AHB_CLK		__CCGR_NUM(2, 13)
+#define	CCGR_USBOH3_60M_CLK		__CCGR_NUM(2, 14)
+#define	CCGR_TVE_CLK			__CCGR_NUM(2, 15)
+
+#define	CCGR_ESDHC1_CLK			__CCGR_NUM(3, 0)
+#define	CCGR_ESDHC1_SERIAL_CLK		__CCGR_NUM(3, 1)
+#define	CCGR_ESDHC2_CLK			__CCGR_NUM(3, 2)
+#define	CCGR_ESDHC2_SERIAL_CLK		__CCGR_NUM(3, 3)
+#define	CCGR_ESDHC3_CLK			__CCGR_NUM(3, 4)
+#define	CCGR_ESDHC3_SERIAL_CLK		__CCGR_NUM(3, 5)
+#define	CCGR_ESDHC4_CLK			__CCGR_NUM(3, 6)
+#define	CCGR_ESDHC4_SERIAL_CLK		__CCGR_NUM(3, 7)
+#define	CCGR_SSI1_CLK			__CCGR_NUM(3, 8)
+#define	CCGR_SSI1_SERIAL_CLK		__CCGR_NUM(3, 9)
+#define	CCGR_SSI2_CLK			__CCGR_NUM(3, 10)
+#define	CCGR_SSI2_SERIAL_CLK		__CCGR_NUM(3, 11)
+#define	CCGR_SSI3_CLK			__CCGR_NUM(3, 12)
+#define	CCGR_SSI3_SERIAL_CLK		__CCGR_NUM(3, 13)
+#define	CCGR_SSI_EXT1_CLK		__CCGR_NUM(3, 14)
+#define	CCGR_SSI_EXT2_CLK		__CCGR_NUM(3, 15)
+
+#define	CCGR_PATA_CLK			__CCGR_NUM(4, 0)
+#define	CCGR_SIM_CLK			__CCGR_NUM(4, 1)
+#define	CCGR_SIM_SERIAL_CLK		__CCGR_NUM(4, 2)
+#define	CCGR_SAHARA_CLK			__CCGR_NUM(4, 3)
+#define	CCGR_RTIC_CLK			__CCGR_NUM(4, 4)
+#define	CCGR_ECSPI1_CLK			__CCGR_NUM(4, 5)
+#define	CCGR_ECSPI1_SERIAL_CLK		__CCGR_NUM(4, 6)
+#define	CCGR_ECSPI2_CLK			__CCGR_NUM(4, 7)
+#define	CCGR_ECSPI2_SERIAL_CLK		__CCGR_NUM(4, 8)
+#define	CCGR_CSPI_CLK			__CCGR_NUM(4, 9)
+#define	CCGR_SRTC_CLK			__CCGR_NUM(4, 10)
+#define	CCGR_SDMA_CLK			__CCGR_NUM(4, 11)
+
+#define	CCGR_SPBA_CLK			__CCGR_NUM(5, 0)
+#define	CCGR_GPU_CLK			__CCGR_NUM(5, 1)
+#define	CCGR_GARB_CLK			__CCGR_NUM(5, 2)
+#define	CCGR_VPU_CLK			__CCGR_NUM(5, 3)
+#define	CCGR_VPU_SERIAL_CLK		__CCGR_NUM(5, 4)
+#define	CCGR_IPU_CLK			__CCGR_NUM(5, 5)
+#define	CCGR_EMI_GARB_CLK		__CCGR_NUM(6, 0)
+#define	CCGR_IPU_DI0_CLK		__CCGR_NUM(6, 1)
+#define	CCGR_IPU_DI1_CLK		__CCGR_NUM(6, 2)
+#define	CCGR_GPU2D_CLK			__CCGR_NUM(6, 3)
+#define	CCGR_SLIMBUS_CLK		__CCGR_NUM(6, 4)
+#define	CCGR_SLIMBUS_SERIAL_CLK		__CCGR_NUM(6, 5)
+
+#define	CCGR_CLK_MODE_OFF		0
+#define	CCGR_CLK_MODE_RUNMODE		1
+#define	CCGR_CLK_MODE_ALWAYS		3
+
+#endif /* _IMX51_CCMREG_H */
+


Property changes on: trunk/sys/arm/freescale/imx/imx51_ccmreg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/imx/imx51_ccmvar.h
===================================================================
--- trunk/sys/arm/freescale/imx/imx51_ccmvar.h	                        (rev 0)
+++ trunk/sys/arm/freescale/imx/imx51_ccmvar.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,111 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: imx51_ccmvar.h,v 1.1 2012/04/17 09:33:31 bsh Exp $	*/
+/*
+ * Copyright (c) 2012  Genetec Corporation.  All rights reserved.
+ * Written by Hashimoto Kenichi for Genetec Corporation.
+ *
+ * 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 GENETEC CORPORATION ``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 GENETEC CORPORATION
+ * 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.
+ */
+
+/*-
+ * Copyright (c) 2012, 2013 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * Portions of this software were developed by Oleksandr Rybalko
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * 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: stable/10/sys/arm/freescale/imx/imx51_ccmvar.h 250357 2013-05-08 09:42:50Z ray $
+ */
+
+#ifndef	_ARM_IMX_IMX51_CCMVAR_H_
+#define	_ARM_IMX_IMX51_CCMVAR_H_
+
+enum imx51_clock {
+	IMX51CLK_FPM,
+	IMX51CLK_PLL1,
+	IMX51CLK_PLL2,
+	IMX51CLK_PLL3,
+	IMX51CLK_PLL1SW,
+	IMX51CLK_PLL2SW,
+	IMX51CLK_PLL3SW,
+	IMX51CLK_PLL1STEP,
+	IMX51CLK_LP_APM,
+	IMX51CLK_ARM_ROOT,
+	IMX51CLK_MAIN_BUS_CLK_SRC,	/* XXX */
+	IMX51CLK_MAIN_BUS_CLK,
+	IMX51CLK_EMI_SLOW_CLK_ROOT,
+	IMX51CLK_ENFC_CLK_ROOT,
+	IMX51CLK_AHB_CLK_ROOT,
+	IMX51CLK_IPG_CLK_ROOT,
+	IMX51CLK_PERCLK_ROOT,
+	IMX51CLK_DDR_CLK_ROOT,
+	IMX51CLK_ARM_AXI_CLK_ROOT,
+	IMX51CLK_ARM_AXI_A_CLK,
+	IMX51CLK_ARM_AXI_B_CLK,
+	IMX51CLK_IPU_HSP_CLK_ROOT,
+	IMX51CLK_CKIL_SYNC_CLK_ROOT,
+	IMX51CLK_USBOH3_CLK_ROOT,
+	IMX51CLK_ESDHC1_CLK_ROOT,
+	IMX51CLK_ESDHC2_CLK_ROOT,
+	IMX51CLK_ESDHC3_CLK_ROOT,
+	IMX51CLK_UART_CLK_ROOT,
+	IMX51CLK_SSI1_CLK_ROOT,
+	IMX51CLK_SSI2_CLK_ROOT,
+	IMX51CLK_SSI_EXT1_CLK_ROOT,
+	IMX51CLK_SSI_EXT2_CLK_ROOT,
+	IMX51CLK_USB_PHY_CLK_ROOT,
+	IMX51CLK_TVE_216_54_CLK_ROOT,
+	IMX51CLK_DI_CLK_ROOT,
+	IMX51CLK_SPDIF0_CLK_ROOT,
+	IMX51CLK_SPDIF1_CLK_ROOT,
+	IMX51CLK_CSPI_CLK_ROOT,
+	IMX51CLK_WRCK_CLK_ROOT,
+	IMX51CLK_LPSR_CLK_ROOT,
+	IMX51CLK_PGC_CLK_ROOT
+};
+
+u_int imx51_get_clock(enum imx51_clock);
+void imx51_clk_gating(int, int);
+int imx51_get_clk_gating(int);
+
+#endif	/* _ARM_IMX_IMX51_CCMVAR_H_ */


Property changes on: trunk/sys/arm/freescale/imx/imx51_ccmvar.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/imx/imx51_dpllreg.h
===================================================================
--- trunk/sys/arm/freescale/imx/imx51_dpllreg.h	                        (rev 0)
+++ trunk/sys/arm/freescale/imx/imx51_dpllreg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,106 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: imx51_dpllreg.h,v 1.1 2012/04/17 09:33:31 bsh Exp $	*/
+/*
+ * Copyright (c) 2012  Genetec Corporation.  All rights reserved.
+ * Written by Hashimoto Kenichi for Genetec Corporation.
+ *
+ * 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 GENETEC CORPORATION ``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 GENETEC CORPORATION
+ * 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.
+ */
+
+/*-
+ * Copyright (c) 2012, 2013 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * Portions of this software were developed by Oleksandr Rybalko
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * 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: stable/10/sys/arm/freescale/imx/imx51_dpllreg.h 250357 2013-05-08 09:42:50Z ray $
+ */
+
+#ifndef	_IMX51_DPLLREG_H
+#define	_IMX51_DPLLREG_H
+
+#include <sys/cdefs.h>
+
+/* register offset address */
+
+#define	IMX51_N_DPLLS		3		/* 1..3 */
+
+#define	DPLL_BASE(n)	      	(0x83F80000 + (0x4000 * ((n)-1)))
+#define	DPLL_SIZE		0x100
+
+#define	DPLL_DP_CTL		0x0000		/* 0x1223 */
+#define	 DP_CTL_LRF		0x00000001
+#define	 DP_CTL_BRM		0x00000002
+#define	 DP_CTL_PLM		0x00000004
+#define	 DP_CTL_RCP		0x00000008
+#define	 DP_CTL_RST		0x00000010
+#define	 DP_CTL_UPEN		0x00000020
+#define	 DP_CTL_PRE		0x00000040
+#define	 DP_CTL_HFSM		0x00000080
+#define	 DP_CTL_REF_CLK_SEL_MASK	0x00000300
+#define	 DP_CTL_REF_CLK_SEL_COSC	0x00000200
+#define	 DP_CTL_REF_CLK_SEL_FPM 	0x00000300
+#define	 DP_CTL_REF_CLK_DIV	0x00000400
+#define	 DP_CTL_DPDCK0_2_EN	0x00001000
+#define	 DP_CTL_HIGHCLK_EN	DP_CTL_DPDCK0_2_EN
+#define	 DP_CTL_MULCTRL		0x00002000
+#define	DPLL_DP_CONFIG		0x0004		/* 2 */
+#define	 DPLL_DP_CONFIG_APEN	0x00000002
+#define	 DPLL_DP_CONFIG_LDREQ	0x00000001
+#define	DPLL_DP_OP		0x0008		/* 0x80 */
+#define	 DP_OP_PDF_SHIFT	0
+#define	 DP_OP_PDF_MASK		(0xf << DP_OP_PDF_SHIFT)
+#define	 DP_OP_MFI_SHIFT	4
+#define	 DP_OP_MFI_MASK		(0xf << DP_OP_MFI_SHIFT)
+#define	DPLL_DP_MFD		0x000C		/* 2 */
+#define	DPLL_DP_MFN		0x0010		/* 1 */
+#define	DPLL_DP_MFNMINUS	0x0014		/* 0 */
+#define	DPLL_DP_MFNPLUS		0x0018		/* 0 */
+#define	DPLL_DP_HFS_OP		0x001C		/* 0x80 */
+#define	DPLL_DP_HFS_MFD		0x0020		/* 2 */
+#define	DPLL_DP_HFS_MFN		0x0024		/* 1 */
+#define	DPLL_DP_TOGC		0x0028		/* 0x20000 */
+#define	DPLL_DP_DESTAT		0x002C		/* 1 */
+
+#endif /* _IMX51_DPLLREG_H */


Property changes on: trunk/sys/arm/freescale/imx/imx51_dpllreg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/imx/imx51_ipuv3.c
===================================================================
--- trunk/sys/arm/freescale/imx/imx51_ipuv3.c	                        (rev 0)
+++ trunk/sys/arm/freescale/imx/imx51_ipuv3.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,898 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Oleksandr Tymoshenko <gonzo at freebsd.org>
+ * Copyright (c) 2012, 2013 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * Portions of this software were developed by Oleksandr Rybalko
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * 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: stable/10/sys/arm/freescale/imx/imx51_ipuv3.c 266365 2014-05-17 22:00:10Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bio.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/endian.h>
+#include <sys/kernel.h>
+#include <sys/kthread.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/queue.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+#include <sys/time.h>
+#include <sys/timetc.h>
+#include <sys/fbio.h>
+#include <sys/consio.h>
+
+#include <sys/kdb.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+#include <machine/fdt.h>
+#include <machine/resource.h>
+#include <machine/intr.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <dev/fb/fbreg.h>
+#include <dev/syscons/syscons.h>
+
+#include <arm/freescale/imx/imx51_ccmvar.h>
+
+#include <arm/freescale/imx/imx51_ipuv3reg.h>
+
+#define	IMX51_IPU_HSP_CLOCK	665000000
+#define	IPU3FB_FONT_HEIGHT	16
+
+struct ipu3sc_softc {
+	device_t		dev;
+	bus_addr_t		pbase;
+	bus_addr_t		vbase;
+
+	bus_space_tag_t		iot;
+	bus_space_handle_t	ioh;
+	bus_space_handle_t	cm_ioh;
+	bus_space_handle_t	dp_ioh;
+	bus_space_handle_t	di0_ioh;
+	bus_space_handle_t	di1_ioh;
+	bus_space_handle_t	dctmpl_ioh;
+	bus_space_handle_t	dc_ioh;
+	bus_space_handle_t	dmfc_ioh;
+	bus_space_handle_t	idmac_ioh;
+	bus_space_handle_t	cpmem_ioh;
+};
+
+struct video_adapter_softc {
+	/* Videoadpater part */
+	video_adapter_t	va;
+
+	intptr_t	fb_addr;
+	intptr_t	fb_paddr;
+	unsigned int	fb_size;
+
+	int		bpp;
+	int		depth;
+	unsigned int	height;
+	unsigned int	width;
+	unsigned int	stride;
+
+	unsigned int	xmargin;
+	unsigned int	ymargin;
+
+	unsigned char	*font;
+	int		initialized;
+};
+
+static struct ipu3sc_softc *ipu3sc_softc;
+static struct video_adapter_softc va_softc;
+
+/* FIXME: not only 2 bytes color supported */
+static uint16_t colors[16] = {
+	0x0000,	/* black */
+	0x001f,	/* blue */
+	0x07e0,	/* green */
+	0x07ff,	/* cyan */
+	0xf800,	/* red */
+	0xf81f,	/* magenta */
+	0x3800,	/* brown */
+	0xc618,	/* light grey */
+	0xc618,	/* XXX: dark grey */
+	0x001f,	/* XXX: light blue */
+	0x07e0,	/* XXX: light green */
+	0x07ff,	/* XXX: light cyan */
+	0xf800,	/* XXX: light red */
+	0xf81f,	/* XXX: light magenta */
+	0xffe0,	/* yellow */
+	0xffff,	/* white */
+};
+static uint32_t colors_24[16] = {
+	0x000000,/* Black	*/
+	0x000080,/* Blue	*/
+	0x008000,/* Green 	*/
+	0x008080,/* Cyan 	*/
+	0x800000,/* Red 	*/
+	0x800080,/* Magenta	*/
+	0xcc6600,/* brown	*/
+	0xC0C0C0,/* Silver 	*/
+	0x808080,/* Gray 	*/
+	0x0000FF,/* Light Blue 	*/
+	0x00FF00,/* Light Green */
+	0x00FFFF,/* Light Cyan 	*/
+	0xFF0000,/* Light Red 	*/
+	0xFF00FF,/* Light Magenta */
+	0xFFFF00,/* Yellow 	*/
+	0xFFFFFF,/* White 	*/
+
+
+};
+
+#define	IPUV3_READ(ipuv3, module, reg)					\
+	bus_space_read_4((ipuv3)->iot, (ipuv3)->module##_ioh, (reg))
+#define	IPUV3_WRITE(ipuv3, module, reg, val)				\
+	bus_space_write_4((ipuv3)->iot, (ipuv3)->module##_ioh, (reg), (val))
+
+#define	CPMEM_CHANNEL_OFFSET(_c)	((_c) * 0x40)
+#define	CPMEM_WORD_OFFSET(_w)		((_w) * 0x20)
+#define	CPMEM_DP_OFFSET(_d)		((_d) * 0x10000)
+#define	IMX_IPU_DP0		0
+#define	IMX_IPU_DP1		1
+#define	CPMEM_CHANNEL(_dp, _ch, _w)					\
+	    (CPMEM_DP_OFFSET(_dp) + CPMEM_CHANNEL_OFFSET(_ch) +		\
+		CPMEM_WORD_OFFSET(_w))
+#define	CPMEM_OFFSET(_dp, _ch, _w, _o)					\
+	    (CPMEM_CHANNEL((_dp), (_ch), (_w)) + (_o))
+
+#define	IPUV3_DEBUG 100
+
+#ifdef IPUV3_DEBUG
+#define	SUBMOD_DUMP_REG(_sc, _m, _l)					\
+	{								\
+		int i;							\
+		printf("*** " #_m " ***\n");				\
+		for (i = 0; i <= (_l); i += 4) {			\
+			if ((i % 32) == 0)				\
+				printf("%04x: ", i & 0xffff);		\
+			printf("0x%08x%c", IPUV3_READ((_sc), _m, i),	\
+			    ((i + 4) % 32)?' ':'\n');			\
+		}							\
+		printf("\n");						\
+	}
+#endif
+
+#ifdef IPUV3_DEBUG
+int ipuv3_debug = IPUV3_DEBUG;
+#define	DPRINTFN(n,x)   if (ipuv3_debug>(n)) printf x; else
+#else
+#define	DPRINTFN(n,x)
+#endif
+
+static int	ipu3_fb_probe(device_t);
+static int	ipu3_fb_attach(device_t);
+
+static int
+ipu3_fb_malloc(struct ipu3sc_softc *sc, size_t size)
+{
+
+	sc->vbase = (uint32_t)contigmalloc(size, M_DEVBUF, M_ZERO, 0, ~0,
+	    PAGE_SIZE, 0);
+	sc->pbase = vtophys(sc->vbase);
+
+	return (0);
+}
+
+static void
+ipu3_fb_init(void *arg)
+{
+	struct ipu3sc_softc *sc = arg;
+	struct video_adapter_softc *va_sc = &va_softc;
+	uint64_t w0sh96;
+	uint32_t w1sh96;
+
+	/* FW W0[137:125] - 96 = [41:29] */
+	/* FH W0[149:138] - 96 = [53:42] */
+	w0sh96 = IPUV3_READ(sc, cpmem, CPMEM_OFFSET(IMX_IPU_DP1, 23, 0, 16));
+	w0sh96 <<= 32;
+	w0sh96 |= IPUV3_READ(sc, cpmem, CPMEM_OFFSET(IMX_IPU_DP1, 23, 0, 12));
+
+	va_sc->width = ((w0sh96 >> 29) & 0x1fff) + 1;
+	va_sc->height = ((w0sh96 >> 42) & 0x0fff) + 1;
+
+	/* SLY W1[115:102] - 96 = [19:6] */
+	w1sh96 = IPUV3_READ(sc, cpmem, CPMEM_OFFSET(IMX_IPU_DP1, 23, 1, 12));
+	va_sc->stride = ((w1sh96 >> 6) & 0x3fff) + 1;
+
+	printf("%dx%d [%d]\n", va_sc->width, va_sc->height, va_sc->stride);
+	va_sc->fb_size = va_sc->height * va_sc->stride;
+
+	ipu3_fb_malloc(sc, va_sc->fb_size);
+
+	/* DP1 + config_ch_23 + word_2 */
+	IPUV3_WRITE(sc, cpmem, CPMEM_OFFSET(IMX_IPU_DP1, 23, 1, 0),
+	    ((sc->pbase >> 3) | ((sc->pbase >> 3) << 29)) & 0xffffffff);
+
+	IPUV3_WRITE(sc, cpmem, CPMEM_OFFSET(IMX_IPU_DP1, 23, 1, 4),
+	    ((sc->pbase >> 3) >> 3) & 0xffffffff);
+
+	va_sc->fb_addr = (intptr_t)sc->vbase;
+	va_sc->fb_paddr = (intptr_t)sc->pbase;
+	va_sc->bpp = va_sc->stride / va_sc->width;
+	va_sc->depth = va_sc->bpp * 8;
+}
+
+static int
+ipu3_fb_probe(device_t dev)
+{
+	int error;
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "fsl,ipu3"))
+		return (ENXIO);
+
+	device_set_desc(dev, "i.MX5x Image Processing Unit v3 (FB)");
+
+	error = sc_probe_unit(device_get_unit(dev), 
+	    device_get_flags(dev) | SC_AUTODETECT_KBD);
+
+	if (error != 0)
+		return (error);
+
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+ipu3_fb_attach(device_t dev)
+{
+	struct ipu3sc_softc *sc = device_get_softc(dev);
+	bus_space_tag_t iot;
+	bus_space_handle_t ioh;
+	phandle_t node;
+	pcell_t reg;
+	int err;
+	uintptr_t base;
+
+	if (ipu3sc_softc)
+		return (ENXIO);
+
+	ipu3sc_softc = sc;
+
+	if (bootverbose)
+		device_printf(dev, "clock gate status is %d\n",
+		    imx51_get_clk_gating(IMX51CLK_IPU_HSP_CLK_ROOT));
+
+	sc->dev = dev;
+
+	err = (sc_attach_unit(device_get_unit(dev),
+	    device_get_flags(dev) | SC_AUTODETECT_KBD));
+
+	if (err) {
+		device_printf(dev, "failed to attach syscons\n");
+		goto fail;
+	}
+
+	sc = device_get_softc(dev);
+	sc->iot = iot = fdtbus_bs_tag;
+
+	/*
+	 * Retrieve the device address based on the start address in the
+	 * DTS.  The DTS for i.MX51 specifies 0x5e000000 as the first register
+	 * address, so we just subtract IPU_CM_BASE to get the offset at which
+	 * the IPU device was memory mapped.
+	 * On i.MX53, the offset is 0.
+	 */
+	node = ofw_bus_get_node(dev);
+	if ((OF_getprop(node, "reg", &reg, sizeof(reg))) <= 0)
+		base = 0;
+	else
+		base = fdt32_to_cpu(reg) - IPU_CM_BASE(0);
+	/* map controller registers */
+	err = bus_space_map(iot, IPU_CM_BASE(base), IPU_CM_SIZE, 0, &ioh);
+	if (err)
+		goto fail_retarn_cm;
+	sc->cm_ioh = ioh;
+
+	/* map Display Multi FIFO Controller registers */
+	err = bus_space_map(iot, IPU_DMFC_BASE(base), IPU_DMFC_SIZE, 0, &ioh);
+	if (err)
+		goto fail_retarn_dmfc;
+	sc->dmfc_ioh = ioh;
+
+	/* map Display Interface 0 registers */
+	err = bus_space_map(iot, IPU_DI0_BASE(base), IPU_DI0_SIZE, 0, &ioh);
+	if (err)
+		goto fail_retarn_di0;
+	sc->di0_ioh = ioh;
+
+	/* map Display Interface 1 registers */
+	err = bus_space_map(iot, IPU_DI1_BASE(base), IPU_DI0_SIZE, 0, &ioh);
+	if (err)
+		goto fail_retarn_di1;
+	sc->di1_ioh = ioh;
+
+	/* map Display Processor registers */
+	err = bus_space_map(iot, IPU_DP_BASE(base), IPU_DP_SIZE, 0, &ioh);
+	if (err)
+		goto fail_retarn_dp;
+	sc->dp_ioh = ioh;
+
+	/* map Display Controller registers */
+	err = bus_space_map(iot, IPU_DC_BASE(base), IPU_DC_SIZE, 0, &ioh);
+	if (err)
+		goto fail_retarn_dc;
+	sc->dc_ioh = ioh;
+
+	/* map Image DMA Controller registers */
+	err = bus_space_map(iot, IPU_IDMAC_BASE(base), IPU_IDMAC_SIZE, 0,
+	    &ioh);
+	if (err)
+		goto fail_retarn_idmac;
+	sc->idmac_ioh = ioh;
+
+	/* map CPMEM registers */
+	err = bus_space_map(iot, IPU_CPMEM_BASE(base), IPU_CPMEM_SIZE, 0,
+	    &ioh);
+	if (err)
+		goto fail_retarn_cpmem;
+	sc->cpmem_ioh = ioh;
+
+	/* map DCTEMPL registers */
+	err = bus_space_map(iot, IPU_DCTMPL_BASE(base), IPU_DCTMPL_SIZE, 0,
+	    &ioh);
+	if (err)
+		goto fail_retarn_dctmpl;
+	sc->dctmpl_ioh = ioh;
+
+#ifdef notyet
+	sc->ih = imx51_ipuv3_intr_establish(IMX51_INT_IPUV3, IPL_BIO,
+	    ipuv3intr, sc);
+	if (sc->ih == NULL) {
+		device_printf(sc->dev,
+		    "unable to establish interrupt at irq %d\n",
+		    IMX51_INT_IPUV3);
+		return (ENXIO);
+	}
+#endif
+
+	/*
+	 * We have to wait until interrupts are enabled. 
+	 * Mailbox relies on it to get data from VideoCore
+	 */
+	ipu3_fb_init(sc);
+
+	return (0);
+
+fail:
+	return (ENXIO);
+fail_retarn_dctmpl:
+	bus_space_unmap(sc->iot, sc->cpmem_ioh, IPU_CPMEM_SIZE);
+fail_retarn_cpmem:
+	bus_space_unmap(sc->iot, sc->idmac_ioh, IPU_IDMAC_SIZE);
+fail_retarn_idmac:
+	bus_space_unmap(sc->iot, sc->dc_ioh, IPU_DC_SIZE);
+fail_retarn_dp:
+	bus_space_unmap(sc->iot, sc->dp_ioh, IPU_DP_SIZE);
+fail_retarn_dc:
+	bus_space_unmap(sc->iot, sc->di1_ioh, IPU_DI1_SIZE);
+fail_retarn_di1:
+	bus_space_unmap(sc->iot, sc->di0_ioh, IPU_DI0_SIZE);
+fail_retarn_di0:
+	bus_space_unmap(sc->iot, sc->dmfc_ioh, IPU_DMFC_SIZE);
+fail_retarn_dmfc:
+	bus_space_unmap(sc->iot, sc->dc_ioh, IPU_CM_SIZE);
+fail_retarn_cm:
+	device_printf(sc->dev,
+	    "failed to map registers (errno=%d)\n", err);
+	return (err);
+}
+
+static device_method_t ipu3_fb_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		ipu3_fb_probe),
+	DEVMETHOD(device_attach,	ipu3_fb_attach),
+
+	{ 0, 0 }
+};
+
+static devclass_t ipu3_fb_devclass;
+
+static driver_t ipu3_fb_driver = {
+	"fb",
+	ipu3_fb_methods,
+	sizeof(struct ipu3sc_softc),
+};
+
+DRIVER_MODULE(ipu3fb, simplebus, ipu3_fb_driver, ipu3_fb_devclass, 0, 0);
+
+/*
+ * Video driver routines and glue.
+ */
+static int			ipu3fb_configure(int);
+static vi_probe_t		ipu3fb_probe;
+static vi_init_t		ipu3fb_init;
+static vi_get_info_t		ipu3fb_get_info;
+static vi_query_mode_t		ipu3fb_query_mode;
+static vi_set_mode_t		ipu3fb_set_mode;
+static vi_save_font_t		ipu3fb_save_font;
+static vi_load_font_t		ipu3fb_load_font;
+static vi_show_font_t		ipu3fb_show_font;
+static vi_save_palette_t	ipu3fb_save_palette;
+static vi_load_palette_t	ipu3fb_load_palette;
+static vi_set_border_t		ipu3fb_set_border;
+static vi_save_state_t		ipu3fb_save_state;
+static vi_load_state_t		ipu3fb_load_state;
+static vi_set_win_org_t		ipu3fb_set_win_org;
+static vi_read_hw_cursor_t	ipu3fb_read_hw_cursor;
+static vi_set_hw_cursor_t	ipu3fb_set_hw_cursor;
+static vi_set_hw_cursor_shape_t	ipu3fb_set_hw_cursor_shape;
+static vi_blank_display_t	ipu3fb_blank_display;
+static vi_mmap_t		ipu3fb_mmap;
+static vi_ioctl_t		ipu3fb_ioctl;
+static vi_clear_t		ipu3fb_clear;
+static vi_fill_rect_t		ipu3fb_fill_rect;
+static vi_bitblt_t		ipu3fb_bitblt;
+static vi_diag_t		ipu3fb_diag;
+static vi_save_cursor_palette_t	ipu3fb_save_cursor_palette;
+static vi_load_cursor_palette_t	ipu3fb_load_cursor_palette;
+static vi_copy_t		ipu3fb_copy;
+static vi_putp_t		ipu3fb_putp;
+static vi_putc_t		ipu3fb_putc;
+static vi_puts_t		ipu3fb_puts;
+static vi_putm_t		ipu3fb_putm;
+
+static video_switch_t ipu3fbvidsw = {
+	.probe			= ipu3fb_probe,
+	.init			= ipu3fb_init,
+	.get_info		= ipu3fb_get_info,
+	.query_mode		= ipu3fb_query_mode,
+	.set_mode		= ipu3fb_set_mode,
+	.save_font		= ipu3fb_save_font,
+	.load_font		= ipu3fb_load_font,
+	.show_font		= ipu3fb_show_font,
+	.save_palette		= ipu3fb_save_palette,
+	.load_palette		= ipu3fb_load_palette,
+	.set_border		= ipu3fb_set_border,
+	.save_state		= ipu3fb_save_state,
+	.load_state		= ipu3fb_load_state,
+	.set_win_org		= ipu3fb_set_win_org,
+	.read_hw_cursor		= ipu3fb_read_hw_cursor,
+	.set_hw_cursor		= ipu3fb_set_hw_cursor,
+	.set_hw_cursor_shape	= ipu3fb_set_hw_cursor_shape,
+	.blank_display		= ipu3fb_blank_display,
+	.mmap			= ipu3fb_mmap,
+	.ioctl			= ipu3fb_ioctl,
+	.clear			= ipu3fb_clear,
+	.fill_rect		= ipu3fb_fill_rect,
+	.bitblt			= ipu3fb_bitblt,
+	.diag			= ipu3fb_diag,
+	.save_cursor_palette	= ipu3fb_save_cursor_palette,
+	.load_cursor_palette	= ipu3fb_load_cursor_palette,
+	.copy			= ipu3fb_copy,
+	.putp			= ipu3fb_putp,
+	.putc			= ipu3fb_putc,
+	.puts			= ipu3fb_puts,
+	.putm			= ipu3fb_putm,
+};
+
+VIDEO_DRIVER(ipu3fb, ipu3fbvidsw, ipu3fb_configure);
+
+extern sc_rndr_sw_t txtrndrsw;
+RENDERER(ipu3fb, 0, txtrndrsw, gfb_set);
+RENDERER_MODULE(ipu3fb, gfb_set);
+
+static uint16_t ipu3fb_static_window[ROW*COL];
+extern u_char dflt_font_16[];
+
+static int
+ipu3fb_configure(int flags)
+{
+	struct video_adapter_softc *sc;
+
+	sc = &va_softc;
+
+	if (sc->initialized)
+		return 0;
+
+	sc->width = 640;
+	sc->height = 480;
+	sc->bpp = 2;
+	sc->stride = sc->width * sc->bpp;
+
+	ipu3fb_init(0, &sc->va, 0);
+
+	sc->initialized = 1;
+
+	return (0);
+}
+
+static int
+ipu3fb_probe(int unit, video_adapter_t **adp, void *arg, int flags)
+{
+
+	return (0);
+}
+
+static int
+ipu3fb_init(int unit, video_adapter_t *adp, int flags)
+{
+	struct video_adapter_softc *sc;
+	video_info_t *vi;
+
+	sc = (struct video_adapter_softc *)adp;
+	vi = &adp->va_info;
+
+	vid_init_struct(adp, "ipu3fb", -1, unit);
+
+	sc->font = dflt_font_16;
+	vi->vi_cheight = IPU3FB_FONT_HEIGHT;
+	vi->vi_cwidth = 8;
+	vi->vi_width = sc->width/8;
+	vi->vi_height = sc->height/vi->vi_cheight;
+
+	/*
+	 * Clamp width/height to syscons maximums
+	 */
+	if (vi->vi_width > COL)
+		vi->vi_width = COL;
+	if (vi->vi_height > ROW)
+		vi->vi_height = ROW;
+
+	sc->xmargin = (sc->width - (vi->vi_width * vi->vi_cwidth)) / 2;
+	sc->ymargin = (sc->height - (vi->vi_height * vi->vi_cheight))/2;
+
+	adp->va_window = (vm_offset_t) ipu3fb_static_window;
+	adp->va_flags |= V_ADP_FONT /* | V_ADP_COLOR | V_ADP_MODECHANGE */;
+	adp->va_line_width = sc->stride;
+	adp->va_buffer_size = sc->fb_size;
+
+	vid_register(&sc->va);
+
+	return (0);
+}
+
+static int
+ipu3fb_get_info(video_adapter_t *adp, int mode, video_info_t *info)
+{
+
+	bcopy(&adp->va_info, info, sizeof(*info));
+	return (0);
+}
+
+static int
+ipu3fb_query_mode(video_adapter_t *adp, video_info_t *info)
+{
+
+	return (0);
+}
+
+static int
+ipu3fb_set_mode(video_adapter_t *adp, int mode)
+{
+
+	return (0);
+}
+
+static int
+ipu3fb_save_font(video_adapter_t *adp, int page, int size, int width,
+    u_char *data, int c, int count)
+{
+
+	return (0);
+}
+
+static int
+ipu3fb_load_font(video_adapter_t *adp, int page, int size, int width,
+    u_char *data, int c, int count)
+{
+	struct video_adapter_softc *sc;
+
+	sc = (struct video_adapter_softc *)adp;
+	sc->font = data;
+
+	return (0);
+}
+
+static int
+ipu3fb_show_font(video_adapter_t *adp, int page)
+{
+
+	return (0);
+}
+
+static int
+ipu3fb_save_palette(video_adapter_t *adp, u_char *palette)
+{
+
+	return (0);
+}
+
+static int
+ipu3fb_load_palette(video_adapter_t *adp, u_char *palette)
+{
+
+	return (0);
+}
+
+static int
+ipu3fb_set_border(video_adapter_t *adp, int border)
+{
+
+	return (ipu3fb_blank_display(adp, border));
+}
+
+static int
+ipu3fb_save_state(video_adapter_t *adp, void *p, size_t size)
+{
+
+	return (0);
+}
+
+static int
+ipu3fb_load_state(video_adapter_t *adp, void *p)
+{
+
+	return (0);
+}
+
+static int
+ipu3fb_set_win_org(video_adapter_t *adp, off_t offset)
+{
+
+	return (0);
+}
+
+static int
+ipu3fb_read_hw_cursor(video_adapter_t *adp, int *col, int *row)
+{
+
+	*col = *row = 0;
+	return (0);
+}
+
+static int
+ipu3fb_set_hw_cursor(video_adapter_t *adp, int col, int row)
+{
+
+	return (0);
+}
+
+static int
+ipu3fb_set_hw_cursor_shape(video_adapter_t *adp, int base, int height,
+    int celsize, int blink)
+{
+
+	return (0);
+}
+
+static int
+ipu3fb_blank_display(video_adapter_t *adp, int mode)
+{
+
+	return (0);
+}
+
+static int
+ipu3fb_mmap(video_adapter_t *adp, vm_ooffset_t offset, vm_paddr_t *paddr,
+    int prot, vm_memattr_t *memattr)
+{
+	struct video_adapter_softc *sc;
+
+	sc = (struct video_adapter_softc *)adp;
+
+	/*
+	 * This might be a legacy VGA mem request: if so, just point it at the
+	 * framebuffer, since it shouldn't be touched
+	 */
+	if (offset < sc->stride * sc->height) {
+		*paddr = sc->fb_paddr + offset;
+		return (0);
+	}
+
+	return (EINVAL);
+}
+
+static int
+ipu3fb_ioctl(video_adapter_t *adp, u_long cmd, caddr_t data)
+{
+	struct video_adapter_softc *sc;
+	struct fbtype *fb;
+
+	sc = (struct video_adapter_softc *)adp;
+
+	switch (cmd) {
+	case FBIOGTYPE:
+		fb = (struct fbtype *)data;
+		fb->fb_type = FBTYPE_PCIMISC;
+		fb->fb_height = sc->height;
+		fb->fb_width = sc->width;
+		fb->fb_depth = sc->depth;
+		if (sc->depth <= 1 || sc->depth > 8)
+			fb->fb_cmsize = 0;
+		else
+			fb->fb_cmsize = 1 << sc->depth;
+		fb->fb_size = sc->fb_size;
+		break;
+	case FBIOSCURSOR:
+		return (ENODEV);
+	default:
+		return (fb_commonioctl(adp, cmd, data));
+	}
+
+	return (0);
+}
+
+static int
+ipu3fb_clear(video_adapter_t *adp)
+{
+
+	return (ipu3fb_blank_display(adp, 0));
+}
+
+static int
+ipu3fb_fill_rect(video_adapter_t *adp, int val, int x, int y, int cx, int cy)
+{
+
+	return (0);
+}
+
+static int
+ipu3fb_bitblt(video_adapter_t *adp, ...)
+{
+
+	return (0);
+}
+
+static int
+ipu3fb_diag(video_adapter_t *adp, int level)
+{
+
+	return (0);
+}
+
+static int
+ipu3fb_save_cursor_palette(video_adapter_t *adp, u_char *palette)
+{
+
+	return (0);
+}
+
+static int
+ipu3fb_load_cursor_palette(video_adapter_t *adp, u_char *palette)
+{
+
+	return (0);
+}
+
+static int
+ipu3fb_copy(video_adapter_t *adp, vm_offset_t src, vm_offset_t dst, int n)
+{
+
+	return (0);
+}
+
+static int
+ipu3fb_putp(video_adapter_t *adp, vm_offset_t off, uint32_t p, uint32_t a,
+    int size, int bpp, int bit_ltor, int byte_ltor)
+{
+
+	return (0);
+}
+
+static int
+ipu3fb_putc(video_adapter_t *adp, vm_offset_t off, uint8_t c, uint8_t a)
+{
+	struct video_adapter_softc *sc;
+	int col, row, bpp;
+	int b, i, j, k;
+	uint8_t *addr;
+	u_char *p;
+	uint32_t fg, bg, color;
+
+	sc = (struct video_adapter_softc *)adp;
+	bpp = sc->bpp;
+
+	if (sc->fb_addr == 0)
+		return (0);
+	row = (off / adp->va_info.vi_width) * adp->va_info.vi_cheight;
+	col = (off % adp->va_info.vi_width) * adp->va_info.vi_cwidth;
+	p = sc->font + c * IPU3FB_FONT_HEIGHT;
+	addr = (uint8_t *)sc->fb_addr
+	    + (row + sc->ymargin) * (sc->stride)
+	    + bpp * (col + sc->xmargin);
+
+	if (bpp == 2) {
+		bg = colors[(a >> 4) & 0x0f];
+		fg = colors[a & 0x0f];
+	} else if (bpp == 3) {
+		bg = colors_24[(a >> 4) & 0x0f];
+		fg = colors_24[a & 0x0f];
+	} else {
+		return (ENXIO);
+	}
+
+	for (i = 0; i < IPU3FB_FONT_HEIGHT; i++) {
+		for (j = 0, k = 7; j < 8; j++, k--) {
+			if ((p[i] & (1 << k)) == 0)
+				color = bg;
+			else
+				color = fg;
+			/* FIXME: BPP maybe different */
+			for (b = 0; b < bpp; b ++)
+				addr[bpp * j + b] =
+				    (color >> (b << 3)) & 0xff;
+		}
+
+		addr += (sc->stride);
+	}
+
+        return (0);
+}
+
+static int
+ipu3fb_puts(video_adapter_t *adp, vm_offset_t off, u_int16_t *s, int len)
+{
+	int i;
+
+	for (i = 0; i < len; i++) 
+		ipu3fb_putc(adp, off + i, s[i] & 0xff, (s[i] & 0xff00) >> 8);
+
+	return (0);
+}
+
+static int
+ipu3fb_putm(video_adapter_t *adp, int x, int y, uint8_t *pixel_image,
+    uint32_t pixel_mask, int size, int width)
+{
+
+	return (0);
+}
+
+/*
+ * Define a stub keyboard driver in case one hasn't been
+ * compiled into the kernel
+ */
+#include <sys/kbio.h>
+#include <dev/kbd/kbdreg.h>
+
+static int dummy_kbd_configure(int flags);
+
+keyboard_switch_t ipu3dummysw;
+
+static int
+dummy_kbd_configure(int flags)
+{
+
+	return (0);
+}
+KEYBOARD_DRIVER(ipu3dummy, ipu3dummysw, dummy_kbd_configure);


Property changes on: trunk/sys/arm/freescale/imx/imx51_ipuv3.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/imx/imx51_ipuv3_fbd.c
===================================================================
--- trunk/sys/arm/freescale/imx/imx51_ipuv3_fbd.c	                        (rev 0)
+++ trunk/sys/arm/freescale/imx/imx51_ipuv3_fbd.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,367 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Oleksandr Tymoshenko <gonzo at freebsd.org>
+ * Copyright (c) 2012, 2013 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * Portions of this software were developed by Oleksandr Rybalko
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * 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: stable/10/sys/arm/freescale/imx/imx51_ipuv3_fbd.c 270262 2014-08-21 10:18:42Z dumbbell $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bio.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/endian.h>
+#include <sys/kernel.h>
+#include <sys/kthread.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/queue.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+#include <sys/time.h>
+#include <sys/timetc.h>
+#include <sys/fbio.h>
+#include <sys/consio.h>
+#include <sys/eventhandler.h>
+
+#include <sys/kdb.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+#include <machine/fdt.h>
+#include <machine/resource.h>
+#include <machine/frame.h>
+#include <machine/intr.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <dev/vt/vt.h>
+#include <dev/vt/colors/vt_termcolors.h>
+
+#include <arm/freescale/imx/imx51_ccmvar.h>
+
+#include <arm/freescale/imx/imx51_ipuv3reg.h>
+
+#include "fb_if.h"
+
+#define	IMX51_IPU_HSP_CLOCK	665000000
+
+struct ipu3sc_softc {
+	device_t		dev;
+	device_t		sc_fbd;		/* fbd child */
+	struct fb_info		sc_info;
+
+	bus_space_tag_t		iot;
+	bus_space_handle_t	ioh;
+	bus_space_handle_t	cm_ioh;
+	bus_space_handle_t	dp_ioh;
+	bus_space_handle_t	di0_ioh;
+	bus_space_handle_t	di1_ioh;
+	bus_space_handle_t	dctmpl_ioh;
+	bus_space_handle_t	dc_ioh;
+	bus_space_handle_t	dmfc_ioh;
+	bus_space_handle_t	idmac_ioh;
+	bus_space_handle_t	cpmem_ioh;
+};
+
+static struct ipu3sc_softc *ipu3sc_softc;
+
+#define	IPUV3_READ(ipuv3, module, reg)					\
+	bus_space_read_4((ipuv3)->iot, (ipuv3)->module##_ioh, (reg))
+#define	IPUV3_WRITE(ipuv3, module, reg, val)				\
+	bus_space_write_4((ipuv3)->iot, (ipuv3)->module##_ioh, (reg), (val))
+
+#define	CPMEM_CHANNEL_OFFSET(_c)	((_c) * 0x40)
+#define	CPMEM_WORD_OFFSET(_w)		((_w) * 0x20)
+#define	CPMEM_DP_OFFSET(_d)		((_d) * 0x10000)
+#define	IMX_IPU_DP0		0
+#define	IMX_IPU_DP1		1
+#define	CPMEM_CHANNEL(_dp, _ch, _w)					\
+	    (CPMEM_DP_OFFSET(_dp) + CPMEM_CHANNEL_OFFSET(_ch) +		\
+		CPMEM_WORD_OFFSET(_w))
+#define	CPMEM_OFFSET(_dp, _ch, _w, _o)					\
+	    (CPMEM_CHANNEL((_dp), (_ch), (_w)) + (_o))
+
+static int	ipu3_fb_probe(device_t);
+static int	ipu3_fb_attach(device_t);
+
+static void
+ipu3_fb_init(struct ipu3sc_softc *sc)
+{
+	uint64_t w0sh96;
+	uint32_t w1sh96;
+
+	/* FW W0[137:125] - 96 = [41:29] */
+	/* FH W0[149:138] - 96 = [53:42] */
+	w0sh96 = IPUV3_READ(sc, cpmem, CPMEM_OFFSET(IMX_IPU_DP1, 23, 0, 16));
+	w0sh96 <<= 32;
+	w0sh96 |= IPUV3_READ(sc, cpmem, CPMEM_OFFSET(IMX_IPU_DP1, 23, 0, 12));
+
+	sc->sc_info.fb_width = ((w0sh96 >> 29) & 0x1fff) + 1;
+	sc->sc_info.fb_height = ((w0sh96 >> 42) & 0x0fff) + 1;
+
+	/* SLY W1[115:102] - 96 = [19:6] */
+	w1sh96 = IPUV3_READ(sc, cpmem, CPMEM_OFFSET(IMX_IPU_DP1, 23, 1, 12));
+	sc->sc_info.fb_stride = ((w1sh96 >> 6) & 0x3fff) + 1;
+
+	printf("%dx%d [%d]\n", sc->sc_info.fb_width, sc->sc_info.fb_height,
+	    sc->sc_info.fb_stride);
+	sc->sc_info.fb_size = sc->sc_info.fb_height * sc->sc_info.fb_stride;
+
+	sc->sc_info.fb_vbase = (intptr_t)contigmalloc(sc->sc_info.fb_size,
+	    M_DEVBUF, M_ZERO, 0, ~0, PAGE_SIZE, 0);
+	sc->sc_info.fb_pbase = (intptr_t)vtophys(sc->sc_info.fb_vbase);
+
+	/* DP1 + config_ch_23 + word_2 */
+	IPUV3_WRITE(sc, cpmem, CPMEM_OFFSET(IMX_IPU_DP1, 23, 1, 0),
+	    (((uint32_t)sc->sc_info.fb_pbase >> 3) |
+	    (((uint32_t)sc->sc_info.fb_pbase >> 3) << 29)) & 0xffffffff);
+
+	IPUV3_WRITE(sc, cpmem, CPMEM_OFFSET(IMX_IPU_DP1, 23, 1, 4),
+	    (((uint32_t)sc->sc_info.fb_pbase >> 3) >> 3) & 0xffffffff);
+
+	/* XXX: fetch or set it from/to IPU. */
+	sc->sc_info.fb_bpp = sc->sc_info.fb_depth = sc->sc_info.fb_stride /
+	    sc->sc_info.fb_width * 8;
+}
+
+/* Use own color map, because of different RGB offset. */
+static int
+ipu3_fb_init_cmap(uint32_t *cmap, int bytespp)
+{
+
+	switch (bytespp) {
+	case 8:
+		return (vt_generate_cons_palette(cmap, COLOR_FORMAT_RGB,
+		    0x7, 5, 0x7, 2, 0x3, 0));
+	case 15:
+		return (vt_generate_cons_palette(cmap, COLOR_FORMAT_RGB,
+		    0x1f, 10, 0x1f, 5, 0x1f, 0));
+	case 16:
+		return (vt_generate_cons_palette(cmap, COLOR_FORMAT_RGB,
+		    0x1f, 11, 0x3f, 5, 0x1f, 0));
+	case 24:
+	case 32: /* Ignore alpha. */
+		return (vt_generate_cons_palette(cmap, COLOR_FORMAT_RGB,
+		    0xff, 0, 0xff, 8, 0xff, 16));
+	default:
+		return (1);
+	}
+}
+
+static int
+ipu3_fb_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "fsl,ipu3"))
+		return (ENXIO);
+
+	device_set_desc(dev, "i.MX5x Image Processing Unit v3 (FB)");
+
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+ipu3_fb_attach(device_t dev)
+{
+	struct ipu3sc_softc *sc = device_get_softc(dev);
+	bus_space_tag_t iot;
+	bus_space_handle_t ioh;
+	phandle_t node;
+	pcell_t reg;
+ 	int err;
+	uintptr_t base;
+
+	ipu3sc_softc = sc;
+
+	if (bootverbose)
+		device_printf(dev, "clock gate status is %d\n",
+		    imx51_get_clk_gating(IMX51CLK_IPU_HSP_CLK_ROOT));
+
+	sc->dev = dev;
+
+	sc = device_get_softc(dev);
+	sc->iot = iot = fdtbus_bs_tag;
+
+	/*
+	 * Retrieve the device address based on the start address in the
+	 * DTS.  The DTS for i.MX51 specifies 0x5e000000 as the first register
+	 * address, so we just subtract IPU_CM_BASE to get the offset at which
+	 * the IPU device was memory mapped.
+	 * On i.MX53, the offset is 0.
+	 */
+	node = ofw_bus_get_node(dev);
+	if ((OF_getprop(node, "reg", &reg, sizeof(reg))) <= 0)
+		base = 0;
+	else
+		base = fdt32_to_cpu(reg) - IPU_CM_BASE(0);
+	/* map controller registers */
+	err = bus_space_map(iot, IPU_CM_BASE(base), IPU_CM_SIZE, 0, &ioh);
+	if (err)
+		goto fail_retarn_cm;
+	sc->cm_ioh = ioh;
+
+	/* map Display Multi FIFO Controller registers */
+	err = bus_space_map(iot, IPU_DMFC_BASE(base), IPU_DMFC_SIZE, 0, &ioh);
+	if (err)
+		goto fail_retarn_dmfc;
+	sc->dmfc_ioh = ioh;
+
+	/* map Display Interface 0 registers */
+	err = bus_space_map(iot, IPU_DI0_BASE(base), IPU_DI0_SIZE, 0, &ioh);
+	if (err)
+		goto fail_retarn_di0;
+	sc->di0_ioh = ioh;
+
+	/* map Display Interface 1 registers */
+	err = bus_space_map(iot, IPU_DI1_BASE(base), IPU_DI0_SIZE, 0, &ioh);
+	if (err)
+		goto fail_retarn_di1;
+	sc->di1_ioh = ioh;
+
+	/* map Display Processor registers */
+	err = bus_space_map(iot, IPU_DP_BASE(base), IPU_DP_SIZE, 0, &ioh);
+	if (err)
+		goto fail_retarn_dp;
+	sc->dp_ioh = ioh;
+
+	/* map Display Controller registers */
+	err = bus_space_map(iot, IPU_DC_BASE(base), IPU_DC_SIZE, 0, &ioh);
+	if (err)
+		goto fail_retarn_dc;
+	sc->dc_ioh = ioh;
+
+	/* map Image DMA Controller registers */
+	err = bus_space_map(iot, IPU_IDMAC_BASE(base), IPU_IDMAC_SIZE, 0,
+	    &ioh);
+	if (err)
+		goto fail_retarn_idmac;
+	sc->idmac_ioh = ioh;
+
+	/* map CPMEM registers */
+	err = bus_space_map(iot, IPU_CPMEM_BASE(base), IPU_CPMEM_SIZE, 0,
+	    &ioh);
+	if (err)
+		goto fail_retarn_cpmem;
+	sc->cpmem_ioh = ioh;
+
+	/* map DCTEMPL registers */
+	err = bus_space_map(iot, IPU_DCTMPL_BASE(base), IPU_DCTMPL_SIZE, 0,
+	    &ioh);
+	if (err)
+		goto fail_retarn_dctmpl;
+	sc->dctmpl_ioh = ioh;
+
+#ifdef notyet
+	sc->ih = imx51_ipuv3_intr_establish(IMX51_INT_IPUV3, IPL_BIO,
+	    ipuv3intr, sc);
+	if (sc->ih == NULL) {
+		device_printf(sc->dev,
+		    "unable to establish interrupt at irq %d\n",
+		    IMX51_INT_IPUV3);
+		return (ENXIO);
+	}
+#endif
+
+	/*
+	 * We have to wait until interrupts are enabled. 
+	 * Mailbox relies on it to get data from VideoCore
+	 */
+	ipu3_fb_init(sc);
+
+	sc->sc_info.fb_name = device_get_nameunit(dev);
+
+	ipu3_fb_init_cmap(sc->sc_info.fb_cmap, sc->sc_info.fb_depth);
+	sc->sc_info.fb_cmsize = 16;
+
+	/* Ask newbus to attach framebuffer device to me. */
+	sc->sc_fbd = device_add_child(dev, "fbd", device_get_unit(dev));
+	if (sc->sc_fbd == NULL)
+		device_printf(dev, "Can't attach fbd device\n");
+
+	return (bus_generic_attach(dev));
+
+fail_retarn_dctmpl:
+	bus_space_unmap(sc->iot, sc->cpmem_ioh, IPU_CPMEM_SIZE);
+fail_retarn_cpmem:
+	bus_space_unmap(sc->iot, sc->idmac_ioh, IPU_IDMAC_SIZE);
+fail_retarn_idmac:
+	bus_space_unmap(sc->iot, sc->dc_ioh, IPU_DC_SIZE);
+fail_retarn_dp:
+	bus_space_unmap(sc->iot, sc->dp_ioh, IPU_DP_SIZE);
+fail_retarn_dc:
+	bus_space_unmap(sc->iot, sc->di1_ioh, IPU_DI1_SIZE);
+fail_retarn_di1:
+	bus_space_unmap(sc->iot, sc->di0_ioh, IPU_DI0_SIZE);
+fail_retarn_di0:
+	bus_space_unmap(sc->iot, sc->dmfc_ioh, IPU_DMFC_SIZE);
+fail_retarn_dmfc:
+	bus_space_unmap(sc->iot, sc->dc_ioh, IPU_CM_SIZE);
+fail_retarn_cm:
+	device_printf(sc->dev,
+	    "failed to map registers (errno=%d)\n", err);
+	return (err);
+}
+
+static struct fb_info *
+ipu3_fb_getinfo(device_t dev)
+{
+	struct ipu3sc_softc *sc = device_get_softc(dev);
+
+	return (&sc->sc_info);
+}
+
+static device_method_t ipu3_fb_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		ipu3_fb_probe),
+	DEVMETHOD(device_attach,	ipu3_fb_attach),
+
+	/* Framebuffer service methods */
+	DEVMETHOD(fb_getinfo,		ipu3_fb_getinfo),
+	{ 0, 0 }
+};
+
+static devclass_t ipu3_fb_devclass;
+
+static driver_t ipu3_fb_driver = {
+	"fb",
+	ipu3_fb_methods,
+	sizeof(struct ipu3sc_softc),
+};
+
+DRIVER_MODULE(fb, simplebus, ipu3_fb_driver, ipu3_fb_devclass, 0, 0);


Property changes on: trunk/sys/arm/freescale/imx/imx51_ipuv3_fbd.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/imx/imx51_ipuv3reg.h
===================================================================
--- trunk/sys/arm/freescale/imx/imx51_ipuv3reg.h	                        (rev 0)
+++ trunk/sys/arm/freescale/imx/imx51_ipuv3reg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,923 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: imx51_ipuv3reg.h,v 1.1 2012/04/17 10:19:57 bsh Exp $	*/
+/*
+ * Copyright (c) 2011, 2012  Genetec Corporation.  All rights reserved.
+ * Written by Hashimoto Kenichi for Genetec Corporation.
+ *
+ * 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 GENETEC CORPORATION ``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 GENETEC CORPORATION
+ * 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.
+ */
+
+/*-
+ * Copyright (c) 2012, 2013 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * Portions of this software were developed by Oleksandr Rybalko
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * 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: stable/10/sys/arm/freescale/imx/imx51_ipuv3reg.h 266365 2014-05-17 22:00:10Z ian $
+ */
+
+#ifndef _ARM_IMX_IMX51_IPUV3REG_H
+#define _ARM_IMX_IMX51_IPUV3REG_H
+
+/* register offset address */
+
+/*
+ * CM
+ * Control Module
+ */
+#define IPU_CM_CONF			0x00000000
+#define  CM_CONF_CSI_SEL		0x80000000
+#define  CM_CONF_IC_INPUT		0x40000000
+#define  CM_CONF_CSI1_DATA_SOURCE	0x20000000
+#define  CM_CONF_CSI0_DATA_SOURCE	0x10000000
+#define  CM_CONF_VDI_DMFC_SYNC		0x08000000
+#define  CM_CONF_IC_DMFC_SYNC		0x04000000
+#define  CM_CONF_IC_DMFC_SEL		0x02000000
+#define  CM_CONF_ISP_DOUBLE_FLOW	0x01000000
+#define  CM_CONF_IDMAC_DISABLE		0x00400000
+#define  CM_CONF_IPU_DIAGBUS_ON		0x00200000
+#define  CM_CONF_IPU_DIAGBUS_MODE	0x001f0000
+#define  CM_CONF_VDI_EN			0x00001000
+#define  CM_CONF_SISG_EN		0x00000800
+#define  CM_CONF_DMFC_EN		0x00000400
+#define  CM_CONF_DC_EN			0x00000200
+#define  CM_CONF_SMFC_EN		0x00000100
+#define  CM_CONF_DI1_EN			0x00000080
+#define  CM_CONF_DI0_EN			0x00000040
+#define  CM_CONF_DP_EN			0x00000020
+#define  CM_CONF_ISP_EN			0x00000010
+#define  CM_CONF_IRT_EN			0x00000008
+#define  CM_CONF_IC_EN			0x00000004
+#define  CM_CONF_CSI1_EN		0x00000002
+#define  CM_CONF_CSI0_EN		0x00000001
+#define IPU_SISG_CTRL0			0x00000004
+#define IPU_SISG_CTRL1			0x00000008
+#define IPU_CM_INT_CTRL_1		0x0000003c
+#define IPU_CM_INT_CTRL_2		0x00000040
+#define IPU_CM_INT_CTRL_3		0x00000044
+#define IPU_CM_INT_CTRL_4		0x00000048
+#define IPU_CM_INT_CTRL_5		0x0000004c
+#define IPU_CM_INT_CTRL_6		0x00000050
+#define IPU_CM_INT_CTRL_7		0x00000054
+#define IPU_CM_INT_CTRL_8		0x00000058
+#define IPU_CM_INT_CTRL_9		0x0000005c
+#define IPU_CM_INT_CTRL_10		0x00000060
+#define IPU_CM_INT_CTRL_11		0x00000064
+#define IPU_CM_INT_CTRL_12		0x00000068
+#define IPU_CM_INT_CTRL_13		0x0000006c
+#define IPU_CM_INT_CTRL_14		0x00000070
+#define IPU_CM_INT_CTRL_15		0x00000074
+#define IPU_CM_SDMA_EVENT_1		0x00000078
+#define IPU_CM_SDMA_EVENT_2		0x0000007c
+#define IPU_CM_SDMA_EVENT_3		0x00000080
+#define IPU_CM_SDMA_EVENT_4		0x00000084
+#define IPU_CM_SDMA_EVENT_7		0x00000088
+#define IPU_CM_SDMA_EVENT_8		0x0000008c
+#define IPU_CM_SDMA_EVENT_11		0x00000090
+#define IPU_CM_SDMA_EVENT_12		0x00000094
+#define IPU_CM_SDMA_EVENT_13		0x00000098
+#define IPU_CM_SDMA_EVENT_14		0x0000009c
+#define IPU_CM_SRM_PRI1			0x000000a0
+#define IPU_CM_SRM_PRI2			0x000000a4
+#define IPU_CM_FS_PROC_FLOW1		0x000000a8
+#define IPU_CM_FS_PROC_FLOW2		0x000000ac
+#define IPU_CM_FS_PROC_FLOW3		0x000000b0
+#define IPU_CM_FS_DISP_FLOW1		0x000000b4
+#define IPU_CM_FS_DISP_FLOW2		0x000000b8
+#define IPU_CM_SKIP			0x000000bc
+#define IPU_CM_DISP_ALT_CONF		0x000000c0
+#define IPU_CM_DISP_GEN			0x000000c4
+#define  CM_DISP_GEN_DI0_COUNTER_RELEASE	0x01000000
+#define  CM_DISP_GEN_DI1_COUNTER_RELEASE	0x00800000
+#define  CM_DISP_GEN_MCU_MAX_BURST_STOP		0x00400000
+#define  CM_DISP_GEN_MCU_T_SHIFT		18
+#define  CM_DISP_GEN_MCU_T(n)		((n) << CM_DISP_GEN_MCU_T_SHIFT)
+#define IPU_CM_DISP_ALT1		0x000000c8
+#define IPU_CM_DISP_ALT2		0x000000cc
+#define IPU_CM_DISP_ALT3		0x000000d0
+#define IPU_CM_DISP_ALT4		0x000000d4
+#define IPU_CM_SNOOP			0x000000d8
+#define IPU_CM_MEM_RST			0x000000dc
+#define  CM_MEM_START			0x80000000
+#define  CM_MEM_EN			0x007fffff
+#define IPU_CM_PM			0x000000e0
+#define IPU_CM_GPR			0x000000e4
+#define  CM_GPR_IPU_CH_BUF1_RDY1_CLR		0x80000000
+#define  CM_GPR_IPU_CH_BUF1_RDY0_CLR		0x40000000
+#define  CM_GPR_IPU_CH_BUF0_RDY1_CLR		0x20000000
+#define  CM_GPR_IPU_CH_BUF0_RDY0_CLR		0x10000000
+#define  CM_GPR_IPU_ALT_CH_BUF1_RDY1_CLR	0x08000000
+#define  CM_GPR_IPU_ALT_CH_BUF1_RDY0_CLR	0x04000000
+#define  CM_GPR_IPU_ALT_CH_BUF0_RDY1_CLR	0x02000000
+#define  CM_GPR_IPU_ALT_CH_BUF0_RDY0_CLR	0x01000000
+#define  CM_GPR_IPU_DI1_CLK_CHANGE_ACK_DIS	0x00800000
+#define  CM_GPR_IPU_DI0_CLK_CHANGE_ACK_DIS	0x00400000
+#define  CM_GPR_IPU_CH_BUF2_RDY1_CLR		0x00200000
+#define  CM_GPR_IPU_CH_BUF2_RDY0_CLR		0x00100000
+#define  CM_GPR_IPU_GP(n)			__BIT((n))
+#define IPU_CM_CH_DB_MODE_SEL_0		0x00000150
+#define IPU_CM_CH_DB_MODE_SEL_1		0x00000154
+#define IPU_CM_ALT_CH_DB_MODE_SEL_0	0x00000168
+#define IPU_CM_ALT_CH_DB_MODE_SEL_1	0x0000016c
+#define IPU_CM_CH_TRB_MODE_SEL_0	0x00000178
+#define IPU_CM_CH_TRB_MODE_SEL_1	0x0000017c
+#define IPU_CM_INT_STAT_1		0x00000200
+#define IPU_CM_INT_STAT_2		0x00000204
+#define IPU_CM_INT_STAT_3		0x00000208
+#define IPU_CM_INT_STAT_4		0x0000020c
+#define IPU_CM_INT_STAT_5		0x00000210
+#define IPU_CM_INT_STAT_6		0x00000214
+#define IPU_CM_INT_STAT_7		0x00000218
+#define IPU_CM_INT_STAT_8		0x0000021c
+#define IPU_CM_INT_STAT_9		0x00000220
+#define IPU_CM_INT_STAT_10		0x00000224
+#define IPU_CM_INT_STAT_11		0x00000228
+#define IPU_CM_INT_STAT_12		0x0000022c
+#define IPU_CM_INT_STAT_13		0x00000230
+#define IPU_CM_INT_STAT_14		0x00000234
+#define IPU_CM_INT_STAT_15		0x00000238
+#define IPU_CM_CUR_BUF_0		0x0000023c
+#define IPU_CM_CUR_BUF_1		0x00000240
+#define IPU_CM_ALT_CUR_BUF_0		0x00000244
+#define IPU_CM_ALT_CUR_BUF_1		0x00000248
+#define IPU_CM_SRM_STAT			0x0000024c
+#define IPU_CM_PROC_TASKS_STAT		0x00000250
+#define IPU_CM_DISP_TASKS_STAT		0x00000254
+#define IPU_CM_TRIPLE_CUR_BUF_0		0x00000258
+#define IPU_CM_TRIPLE_CUR_BUF_1		0x0000025c
+#define IPU_CM_TRIPLE_CUR_BUF_2		0x00000260
+#define IPU_CM_TRIPLE_CUR_BUF_3		0x00000264
+#define IPU_CM_CH_BUF0_RDY0		0x00000268
+#define IPU_CM_CH_BUF0_RDY1		0x0000026c
+#define IPU_CM_CH_BUF1_RDY0		0x00000270
+#define IPU_CM_CH_BUF1_RDY1		0x00000274
+#define IPU_CM_ALT_CH_BUF0_RDY0		0x00000278
+#define IPU_CM_ALT_CH_BUF0_RDY1		0x0000027c
+#define IPU_CM_ALT_CH_BUF1_RDY0		0x00000280
+#define IPU_CM_ALT_CH_BUF1_RDY1		0x00000284
+#define IPU_CM_CH_BUF2_RDY0		0x00000288
+#define IPU_CM_CH_BUF2_RDY1		0x0000028c
+
+/*
+ * IDMAC
+ * Image DMA Controller
+ */
+#define IPU_IDMAC_CONF		0x00000000
+#define IPU_IDMAC_CH_EN_1	0x00000004
+#define IPU_IDMAC_CH_EN_2	0x00000008
+#define IPU_IDMAC_SEP_ALPHA	0x0000000c
+#define IPU_IDMAC_ALT_SEP_ALPHA	0x00000010
+#define IPU_IDMAC_CH_PRI_1	0x00000014
+#define IPU_IDMAC_CH_PRI_2	0x00000018
+#define IPU_IDMAC_WM_EN_1	0x0000001c
+#define IPU_IDMAC_WM_EN_2	0x00000020
+#define IPU_IDMAC_LOCK_EN_1	0x00000024
+#define IPU_IDMAC_LOCK_EN_2	0x00000028
+#define IPU_IDMAC_SUB_ADDR_0	0x0000002c
+#define IPU_IDMAC_SUB_ADDR_1	0x00000030
+#define IPU_IDMAC_SUB_ADDR_2	0x00000034
+#define IPU_IDMAC_SUB_ADDR_3	0x00000038
+#define IPU_IDMAC_SUB_ADDR_4	0x0000003c
+#define IPU_IDMAC_BNDM_EN_1	0x00000040
+#define IPU_IDMAC_BNDM_EN_2	0x00000044
+#define IPU_IDMAC_SC_CORD	0x00000048
+#define IPU_IDMAC_SC_CORD1	0x0000004c
+#define IPU_IDMAC_CH_BUSY_1	0x00000100
+#define IPU_IDMAC_CH_BUSY_2	0x00000104
+
+#define CH_PANNEL_BG	23
+#define CH_PANNEL_FG	27
+
+/*
+ * DP
+ * Display Port
+ */
+#define IPU_DP_DEBUG_CNT	0x000000bc
+#define IPU_DP_DEBUG_STAT	0x000000c0
+
+/*
+ * IC
+ * Image Converter
+ */
+#define IPU_IC_CONF		0x00000000
+#define IPU_IC_PRP_ENC_RSC	0x00000004
+#define IPU_IC_PRP_VF_RSC	0x00000008
+#define IPU_IC_PP_RSC		0x0000000c
+#define IPU_IC_CMBP_1		0x00000010
+#define IPU_IC_CMBP_2		0x00000014
+#define IPU_IC_IDMAC_1		0x00000018
+#define IPU_IC_IDMAC_2		0x0000001c
+#define IPU_IC_IDMAC_3		0x00000020
+#define IPU_IC_IDMAC_4		0x00000024
+
+/*
+ * CSI
+ * Camera Sensor Interface
+ */
+#define IPU_CSI0_SENS_CONF	0x00000000
+#define IPU_CSI0_SENS_FRM_SIZE	0x00000004
+#define IPU_CSI0_ACT_FRM_SIZE	0x00000008
+#define IPU_CSI0_OUT_FRM_CTRL	0x0000000c
+#define IPU_CSI0_TST_CTRL	0x00000010
+#define IPU_CSI0_CCIR_CODE_1	0x00000014
+#define IPU_CSI0_CCIR_CODE_2	0x00000018
+#define IPU_CSI0_CCIR_CODE_3	0x0000001c
+#define IPU_CSI0_DI		0x00000020
+#define IPU_CSI0_SKIP		0x00000024
+#define IPU_CSI0_CPD_CTRL	0x00000028
+#define IPU_CSI0_CPD_OFFSET1	0x000000ec
+#define IPU_CSI0_CPD_OFFSET2	0x000000f0
+
+#define IPU_CSI1_SENS_CONF	0x00000000
+#define IPU_CSI1_SENS_FRM_SIZE	0x00000004
+#define IPU_CSI1_ACT_FRM_SIZE	0x00000008
+#define IPU_CSI1_OUT_FRM_CTRL	0x0000000c
+#define IPU_CSI1_TST_CTRL	0x00000010
+#define IPU_CSI1_CCIR_CODE_1	0x00000014
+#define IPU_CSI1_CCIR_CODE_2	0x00000018
+#define IPU_CSI1_CCIR_CODE_3	0x0000001c
+#define IPU_CSI1_DI		0x00000020
+#define IPU_CSI1_SKIP		0x00000024
+#define IPU_CSI1_CPD_CTRL	0x00000028
+#define IPU_CSI1_CPD_OFFSET1	0x000000ec
+#define IPU_CSI1_CPD_OFFSET2	0x000000f0
+
+/*
+ * DI
+ * Display Interface
+ */
+#define IPU_DI_GENERAL			0x00000000
+#define  DI_GENERAL_DISP_Y_SEL		0x70000000
+#define  DI_GENERAL_CLOCK_STOP_MODE	0x0f000000
+#define  DI_GENERAL_DISP_CLOCK_INIT	0x00800000
+#define  DI_GENERAL_MASK_SEL		0x00400000
+#define  DI_GENERAL_VSYNC_EXT		0x00200000
+#define  DI_GENERAL_CLK_EXT		0x00100000
+#define  DI_GENERAL_WATCHDOG_MODE	0x000c0000
+#define  DI_GENERAL_POLARITY_DISP_CLK	0x00020000
+#define  DI_GENERAL_SYNC_COUNT_SEL	0x0000f000
+#define  DI_GENERAL_ERR_TREATMENT	0x00000800
+#define  DI_GENERAL_ERM_VSYNC_SEL	0x00000400
+#define  DI_GENERAL_POLARITY_CS(n)	(1 << ((n) + 8))
+#define  DI_GENERAL_POLARITY(n)		(1 << ((n) - 1))
+
+#define IPU_DI_BS_CLKGEN0		0x00000004
+#define  DI_BS_CLKGEN0_OFFSET_SHIFT	16
+#define IPU_DI_BS_CLKGEN1		0x00000008
+#define  DI_BS_CLKGEN1_DOWN_SHIFT	16
+#define  DI_BS_CLKGEN1_UP_SHIFT		0
+#define IPU_DI_SW_GEN0(n)		(0x0000000c + ((n) - 1) * 4)
+#define  DI_SW_GEN0_RUN_VAL		0x7ff80000
+#define  DI_SW_GEN0_RUN_RESOL		0x00070000
+#define  DI_SW_GEN0_OFFSET_VAL		0x00007ff8
+#define  DI_SW_GEN0_OFFSET_RESOL	0x00000007
+#define  __DI_SW_GEN0(run_val, run_resol, offset_val, offset_resol)	\
+	(((run_val) << 19) | ((run_resol) << 16) | 			\
+	 ((offset_val) << 3) | (offset_resol))
+#define IPU_DI_SW_GEN1(n)		(0x00000030 + ((n) - 1) * 4)
+#define  DI_SW_GEN1_CNT_POL_GEN_EN	0x60000000
+#define  DI_SW_GEN1_CNT_AUTO_RELOAD	0x10000000
+#define  DI_SW_GEN1_CNT_CLR_SEL		0x0e000000
+#define  DI_SW_GEN1_CNT_DOWN		0x01ff0000
+#define  DI_SW_GEN1_CNT_POL_TRIG_SEL	0x00007000
+#define  DI_SW_GEN1_CNT_POL_CLR_SEL	0x00000e00
+#define  DI_SW_GEN1_CNT_UP		0x000001ff
+#define  __DI_SW_GEN1(pol_gen_en, auto_reload, clr_sel, down, pol_trig_sel, pol_clr_sel, up) \
+	(((pol_gen_en) << 29) | ((auto_reload) << 28) | \
+	 ((clr_sel) << 25) |				\
+	    ((down) << 16) | ((pol_trig_sel) << 12) |	\
+	 ((pol_clr_sel) << 9) | (up))
+#define IPU_DI_SYNC_AS_GEN		0x00000054
+#define  DI_SYNC_AS_GEN_SYNC_START_EN	0x10000000
+#define  DI_SYNC_AS_GEN_VSYNC_SEL	0x0000e000
+#define  DI_SYNC_AS_GEN_VSYNC_SEL_SHIFT	13
+#define  DI_SYNC_AS_GEN_SYNC_STAR	0x00000fff
+#define IPU_DI_DW_GEN(n)		(0x00000058 + (n) * 4)
+#define  DI_DW_GEN_ACCESS_SIZE_SHIFT		24
+#define  DI_DW_GEN_COMPONNENT_SIZE_SHIFT	16
+#define  DI_DW_GEN_PIN_SHIFT(n)			(((n) - 11) * 2)
+#define  DI_DW_GEN_PIN(n)		__BITS(DI_DW_GEN_PIN_SHIFT(n) + 1, \
+					       DI_DW_GEN_PIN_SHIFT(n))
+#define IPU_DI_DW_SET(n, m)	(0x00000088 + (n) * 4 + (m) * 0x30)
+#define  DI_DW_SET_DOWN_SHIFT	16
+#define  DI_DW_SET_UP_SHIFT	0
+#define IPU_DI_STP_REP(n)	(0x00000148 + ((n - 1) / 2) * 4)
+#define  DI_STP_REP_SHIFT(n)	(((n - 1) % 2) * 16)
+#define  DI_STP_REP_MASK(n)	(0x00000fff << DI_STP_REP_SHIFT((n)))
+#define IPU_DI_SER_CONF			0x0000015c
+#define IPU_DI_SSC			0x00000160
+#define IPU_DI_POL			0x00000164
+#define  DI_POL_DRDY_POLARITY_17 	0x00000040
+#define  DI_POL_DRDY_POLARITY_16 	0x00000020
+#define  DI_POL_DRDY_POLARITY_15 	0x00000010
+#define  DI_POL_DRDY_POLARITY_14 	0x00000008
+#define  DI_POL_DRDY_POLARITY_13 	0x00000004
+#define  DI_POL_DRDY_POLARITY_12 	0x00000002
+#define  DI_POL_DRDY_POLARITY_11 	0x00000001
+#define IPU_DI_AW0			0x00000168
+#define IPU_DI_AW1			0x0000016c
+#define IPU_DI_SCR_CONF			0x00000170
+#define IPU_DI_STAT			0x00000174
+
+/*
+ * SMFC
+ * Sensor Multi FIFO Controller
+ */
+#define IPU_SMFC_MAP	0x00000000
+#define IPU_SMFC_WMC	0x00000004
+#define IPU_SMFC_BS	0x00000008
+
+/*
+ * DC
+ * Display Controller
+ */
+#define IPU_DC_READ_CH_CONF	0x00000000
+#define IPU_DC_READ_CH_ADDR	0x00000004
+
+#define IPU_DC_RL0_CH_0		0x00000008
+#define IPU_DC_RL1_CH_0		0x0000000c
+#define IPU_DC_RL2_CH_0		0x00000010
+#define IPU_DC_RL3_CH_0		0x00000014
+#define IPU_DC_RL4_CH_0		0x00000018
+#define IPU_DC_WR_CH_CONF_1	0x0000001c
+#define IPU_DC_WR_CH_ADDR_1	0x00000020
+#define IPU_DC_RL0_CH_1		0x00000024
+#define IPU_DC_RL1_CH_1		0x00000028
+#define IPU_DC_RL2_CH_1		0x0000002c
+#define IPU_DC_RL3_CH_1		0x00000030
+#define IPU_DC_RL4_CH_1		0x00000034
+#define IPU_DC_WR_CH_CONF_2	0x00000038
+#define IPU_DC_WR_CH_ADDR_2	0x0000003c
+#define IPU_DC_RL0_CH_2		0x00000040
+#define IPU_DC_RL1_CH_2		0x00000044
+#define IPU_DC_RL2_CH_2		0x00000048
+#define IPU_DC_RL3_CH_2		0x0000004c
+#define IPU_DC_RL4_CH_2		0x00000050
+#define IPU_DC_CMD_CH_CONF_3	0x00000054
+#define IPU_DC_CMD_CH_CONF_4	0x00000058
+#define IPU_DC_WR_CH_CONF_5	0x0000005c
+#define IPU_DC_WR_CH_ADDR_5	0x00000060
+#define IPU_DC_RL0_CH_5		0x00000064
+#define IPU_DC_RL1_CH_5		0x00000068
+#define IPU_DC_RL2_CH_5		0x0000006c
+#define IPU_DC_RL3_CH_5		0x00000070
+#define IPU_DC_RL4_CH_5		0x00000074
+#define IPU_DC_WR_CH_CONF_6	0x00000078
+#define IPU_DC_WR_CH_ADDR_6	0x0000007c
+#define IPU_DC_RL0_CH_6		0x00000080
+#define IPU_DC_RL1_CH_6		0x00000084
+#define IPU_DC_RL2_CH_6		0x00000088
+#define IPU_DC_RL3_CH_6		0x0000008c
+#define IPU_DC_RL4_CH_6		0x00000090
+#define IPU_DC_WR_CH_CONF1_8	0x00000094
+#define IPU_DC_WR_CH_CONF2_8	0x00000098
+#define IPU_DC_RL1_CH_8		0x0000009c
+#define IPU_DC_RL2_CH_8		0x000000a0
+#define IPU_DC_RL3_CH_8		0x000000a4
+#define IPU_DC_RL4_CH_8		0x000000a8
+#define IPU_DC_RL5_CH_8		0x000000ac
+#define IPU_DC_RL6_CH_8		0x000000b0
+#define IPU_DC_WR_CH_CONF1_9	0x000000b4
+#define IPU_DC_WR_CH_CONF2_9	0x000000b8
+#define IPU_DC_RL1_CH_9		0x000000bc
+#define IPU_DC_RL2_CH_9		0x000000c0
+#define IPU_DC_RL3_CH_9		0x000000c4
+#define IPU_DC_RL4_CH_9		0x000000c8
+#define IPU_DC_RL5_CH_9		0x000000cc
+#define IPU_DC_RL6_CH_9		0x000000d0
+
+#define IPU_DC_RL(chan_base, evt)	((chan_base) + (evt / 2) *0x4)
+#define  DC_RL_CH_0		IPU_DC_RL0_CH_0
+#define  DC_RL_CH_1		IPU_DC_RL0_CH_1
+#define  DC_RL_CH_2		IPU_DC_RL0_CH_2
+#define  DC_RL_CH_5		IPU_DC_RL0_CH_5
+#define  DC_RL_CH_6		IPU_DC_RL0_CH_6
+#define  DC_RL_CH_8		IPU_DC_RL0_CH_8
+
+#define  DC_RL_EVT_NF		0
+#define  DC_RL_EVT_NL		1
+#define  DC_RL_EVT_EOF		2
+#define  DC_RL_EVT_NFIELD	3
+#define  DC_RL_EVT_EOL		4
+#define  DC_RL_EVT_EOFIELD	5
+#define  DC_RL_EVT_NEW_ADDR	6
+#define  DC_RL_EVT_NEW_CHAN	7
+#define  DC_RL_EVT_NEW_DATA	8
+
+#define IPU_DC_GEN		0x000000d4
+#define IPU_DC_DISP_CONF1_0	0x000000d8
+#define IPU_DC_DISP_CONF1_1	0x000000dc
+#define IPU_DC_DISP_CONF1_2	0x000000e0
+#define IPU_DC_DISP_CONF1_3	0x000000e4
+#define IPU_DC_DISP_CONF2_0	0x000000e8
+#define IPU_DC_DISP_CONF2_1	0x000000ec
+#define IPU_DC_DISP_CONF2_2	0x000000f0
+#define IPU_DC_DISP_CONF2_3	0x000000f4
+#define IPU_DC_DI0_CONF_1	0x000000f8
+#define IPU_DC_DI0_CONF_2	0x000000fc
+#define IPU_DC_DI1_CONF_1	0x00000100
+#define IPU_DC_DI1_CONF_2	0x00000104
+
+#define IPU_DC_MAP_CONF_PNTR(n)	(0x00000108 + (n) * 4)
+#define IPU_DC_MAP_CONF_0	0x00000108
+#define IPU_DC_MAP_CONF_1	0x0000010c
+#define IPU_DC_MAP_CONF_2	0x00000110
+#define IPU_DC_MAP_CONF_3	0x00000114
+#define IPU_DC_MAP_CONF_4	0x00000118
+#define IPU_DC_MAP_CONF_5	0x0000011c
+#define IPU_DC_MAP_CONF_6	0x00000120
+#define IPU_DC_MAP_CONF_7	0x00000124
+#define IPU_DC_MAP_CONF_8	0x00000128
+#define IPU_DC_MAP_CONF_9	0x0000012c
+#define IPU_DC_MAP_CONF_10	0x00000130
+#define IPU_DC_MAP_CONF_11	0x00000134
+#define IPU_DC_MAP_CONF_12	0x00000138
+#define IPU_DC_MAP_CONF_13	0x0000013c
+#define IPU_DC_MAP_CONF_14	0x00000140
+
+#define IPU_DC_MAP_CONF_MASK(n)	(0x00000144 + (n) * 4)
+#define IPU_DC_MAP_CONF_15	0x00000144
+#define IPU_DC_MAP_CONF_16	0x00000148
+#define IPU_DC_MAP_CONF_17	0x0000014c
+#define IPU_DC_MAP_CONF_18	0x00000150
+#define IPU_DC_MAP_CONF_19	0x00000154
+#define IPU_DC_MAP_CONF_20	0x00000158
+#define IPU_DC_MAP_CONF_21	0x0000015c
+#define IPU_DC_MAP_CONF_22	0x00000160
+#define IPU_DC_MAP_CONF_23	0x00000164
+#define IPU_DC_MAP_CONF_24	0x00000168
+#define IPU_DC_MAP_CONF_25	0x0000016c
+#define IPU_DC_MAP_CONF_26	0x00000170
+
+#define IPU_DC_UGDE(m, n)	(0x00000174 + (m) * 0x10 + (n) +4)
+#define IPU_DC_UGDE0_0		0x00000174
+#define IPU_DC_UGDE0_1		0x00000178
+#define IPU_DC_UGDE0_2		0x0000017c
+#define IPU_DC_UGDE0_3		0x00000180
+#define IPU_DC_UGDE1_0		0x00000184
+#define IPU_DC_UGDE1_1		0x00000188
+#define IPU_DC_UGDE1_2		0x0000018c
+#define IPU_DC_UGDE1_3		0x00000190
+#define IPU_DC_UGDE2_0		0x00000194
+#define IPU_DC_UGDE2_1		0x00000198
+#define IPU_DC_UGDE2_2		0x0000019c
+#define IPU_DC_UGDE2_3		0x000001a0
+#define IPU_DC_UGDE3_0		0x000001a4
+#define IPU_DC_UGDE3_1		0x000001a8
+#define IPU_DC_UGDE3_2		0x000001ac
+#define IPU_DC_UGDE3_3		0x000001b0
+#define IPU_DC_LLA0		0x000001b4
+#define IPU_DC_LLA1		0x000001b8
+#define IPU_DC_R_LLA0		0x000001bc
+#define IPU_DC_R_LLA1		0x000001c0
+#define IPU_DC_WR_CH_ADDR_5_ALT	0x000001c4
+#define IPU_DC_STAT		0x000001c8
+
+/*
+ * DMFC
+ * Display Multi FIFO Controller
+ */
+#define IPU_DMFC_RD_CHAN		0x00000000
+#define  DMFC_RD_CHAN_PPW_C		0x03000000
+#define  DMFC_RD_CHAN_WM_DR_0		0x00e00000
+#define  DMFC_RD_CHAN_WM_SET_0		0x001c0000
+#define  DMFC_RD_CHAN_WM_EN_0		0x00020000
+#define  DMFC_RD_CHAN_BURST_SIZE_0	0x000000c0
+#define IPU_DMFC_WR_CHAN		0x00000004
+#define  DMFC_WR_CHAN_BUSRT_SIZE_2C	0xc0000000
+#define  DMFC_WR_CHAN_FIFO_SIZE_2C	0x38000000
+#define  DMFC_WR_CHAN_ST_ADDR_2C	0x07000000
+#define  DMFC_WR_CHAN_BURST_SIZE_1C	0x00c00000
+#define  DMFC_WR_CHAN_FIFO_SIZE_1C	0x00380000
+#define  DMFC_WR_CHAN_ST_ADDR_1C	0x00070000
+#define  DMFC_WR_CHAN_BURST_SIZE_2	0x0000c000
+#define  DMFC_WR_CHAN_FIFO_SIZE_2	0x00003800
+#define  DMFC_WR_CHAN_ST_ADDR_2		0x00000700
+#define  DMFC_WR_CHAN_BURST_SIZE_1	0x000000c0
+#define  DMFC_WR_CHAN_FIFO_SIZE_1	0x00000038
+#define  DMFC_WR_CHAN_ST_ADDR_1		0x00000007
+#define IPU_DMFC_WR_CHAN_DEF		0x00000008
+#define  DMFC_WR_CHAN_DEF_WM_CLR_2C	0xe0000000
+#define  DMFC_WR_CHAN_DEF_WM_SET_2C	0x1c000000
+#define  DMFC_WR_CHAN_DEF_WM_EN_2C	0x02000000
+#define  DMFC_WR_CHAN_DEF_WM_CLR_1C	0x00e00000
+#define  DMFC_WR_CHAN_DEF_WM_SET_1C	0x001c0000
+#define  DMFC_WR_CHAN_DEF_WM_EN_1C	0x00020000
+#define  DMFC_WR_CHAN_DEF_WM_CLR_2	0x0000e000
+#define  DMFC_WR_CHAN_DEF_WM_SET_2	0x00001c00
+#define  DMFC_WR_CHAN_DEF_WM_EN_2	0x00000200
+#define  DMFC_WR_CHAN_DEF_WM_CLR_1	0x000000e0
+#define  DMFC_WR_CHAN_DEF_WM_SET_1	0x0000000c
+#define  DMFC_WR_CHAN_DEF_WM_EN_1	0x00000002
+#define IPU_DMFC_DP_CHAN		0x0000000c
+#define  DMFC_DP_CHAN_BUSRT_SIZE_6F	0xc0000000
+#define  DMFC_DP_CHAN_FIFO_SIZE_6F	0x38000000
+#define  DMFC_DP_CHAN_ST_ADDR_6F	0x07000000
+#define  DMFC_DP_CHAN_BURST_SIZE_6B	0x00c00000
+#define  DMFC_DP_CHAN_FIFO_SIZE_6B	0x00380000
+#define  DMFC_DP_CHAN_ST_ADDR_6B	0x00070000
+#define  DMFC_DP_CHAN_BURST_SIZE_5F	0x0000c000
+#define  DMFC_DP_CHAN_FIFO_SIZE_5F	0x00003800
+#define  DMFC_DP_CHAN_ST_ADDR_5F	0x00000700
+#define  DMFC_DP_CHAN_BURST_SIZE_5B	0x000000c0
+#define  DMFC_DP_CHAN_FIFO_SIZE_5B	0x00000038
+#define  DMFC_DP_CHAN_ST_ADDR_5B	0x00000007
+#define IPU_DMFC_DP_CHAN_DEF		0x00000010
+#define  DMFC_DP_CHAN_DEF_WM_CLR_6F	0xe0000000
+#define  DMFC_DP_CHAN_DEF_WM_SET_6F	0x1c000000
+#define  DMFC_DP_CHAN_DEF_WM_EN_6F	0x02000000
+#define  DMFC_DP_CHAN_DEF_WM_CLR_6B	0x00e00000
+#define  DMFC_DP_CHAN_DEF_WM_SET_6B	0x001c0000
+#define  DMFC_DP_CHAN_DEF_WM_EN_6B	0x00020000
+#define  DMFC_DP_CHAN_DEF_WM_CLR_5F	0x0000e000
+#define  DMFC_DP_CHAN_DEF_WM_SET_5F	0x00001c00
+#define  DMFC_DP_CHAN_DEF_WM_EN_5F	0x00000200
+#define  DMFC_DP_CHAN_DEF_WM_CLR_5B	0x000000e0
+#define  DMFC_DP_CHAN_DEF_WM_SET_5B	0x0000001c
+#define  DMFC_DP_CHAN_DEF_WM_EN_5B	0x00000002
+#define IPU_DMFC_GENERAL1		0x00000014
+#define  DMFC_GENERAL1_WAIT4EOT_9	0x01000000
+#define  DMFC_GENERAL1_WAIT4EOT_6F	0x00800000
+#define  DMFC_GENERAL1_WAIT4EOT_6B	0x00400000
+#define  DMFC_GENERAL1_WAIT4EOT_5F	0x00200000
+#define  DMFC_GENERAL1_WAIT4EOT_5B	0x00100000
+#define  DMFC_GENERAL1_WAIT4EOT_4	0x00080000
+#define  DMFC_GENERAL1_WAIT4EOT_3	0x00040000
+#define  DMFC_GENERAL1_WAIT4EOT_2	0x00020000
+#define  DMFC_GENERAL1_WAIT4EOT_1	0x00010000
+#define  DMFC_GENERAL1_WM_CLR_9		0x0000e000
+#define  DMFC_GENERAL1_WM_SET_9		0x00001c00
+#define  DMFC_GENERAL1_BURST_SIZE_9	0x00000060
+#define  DMFC_GENERAL1_DCDP_SYNC_PR	0x00000003
+#define   DCDP_SYNC_PR_FORBIDDEN	0
+#define   DCDP_SYNC_PR_DC_DP		1
+#define   DCDP_SYNC_PR_DP_DC		2
+#define   DCDP_SYNC_PR_ROUNDROBIN	3
+#define IPU_DMFC_GENERAL2		0x00000018
+#define  DMFC_GENERAL2_FRAME_HEIGHT_RD	0x1fff0000
+#define  DMFC_GENERAL2_FRAME_WIDTH_RD	0x00001fff
+#define IPU_DMFC_IC_CTRL		0x0000001c
+#define  DMFC_IC_CTRL_IC_FRAME_HEIGHT_RD	0xfff80000
+#define  DMFC_IC_CTRL_IC_FRAME_WIDTH_RD		0x0007ffc0
+#define  DMFC_IC_CTRL_IC_PPW_C			0x00000030
+#define  DMFC_IC_CTRL_IC_IN_PORT		0x00000007
+#define   IC_IN_PORT_CH28		0
+#define   IC_IN_PORT_CH41		1
+#define   IC_IN_PORT_DISABLE		2
+#define   IC_IN_PORT_CH23		4
+#define   IC_IN_PORT_CH27		5
+#define   IC_IN_PORT_CH24		6
+#define   IC_IN_PORT_CH29		7
+#define IPU_DMFC_WR_CHAN_ALT		0x00000020
+#define IPU_DMFC_WR_CHAN_DEF_ALT	0x00000024
+#define IPU_DMFC_DP_CHAN_ALT		0x00000028
+#define IPU_DMFC_DP_CHAN_DEF_ALT	0x0000002c
+#define  DMFC_DP_CHAN_DEF_ALT_WM_CLR_6F_ALT	0xe0000000
+#define  DMFC_DP_CHAN_DEF_ALT_WM_SET_6F_ALT	0x1c000000
+#define  DMFC_DP_CHAN_DEF_ALT_WM_EN_6F_ALT	0x02000000
+#define  DMFC_DP_CHAN_DEF_ALT_WM_CLR_6B_ALT	0x00e00000
+#define  DMFC_DP_CHAN_DEF_ALT_WM_SET_6B_ALT	0x001c0000
+#define  DMFC_DP_CHAN_DEF_ALT_WM_EN_6B_ALT	0x00020000
+#define  DMFC_DP_CHAN_DEF_ALT_WM_CLR_5B_ALT	0x000000e0
+#define  DMFC_DP_CHAN_DEF_ALT_WM_SET_5B_ALT	0x0000001c
+#define  DMFC_DP_CHAN_DEF_ALT_WM_EN_5B_ALT	0x00000002
+#define IPU_DMFC_GENERAL1_ALT		0x00000030
+#define  DMFC_GENERAL1_ALT_WAIT4EOT_6F_ALT	0x00800000
+#define  DMFC_GENERAL1_ALT_WAIT4EOT_6B_ALT	0x00400000
+#define  DMFC_GENERAL1_ALT_WAIT4EOT_5B_ALT	0x00100000
+#define  DMFC_GENERAL1_ALT_WAIT4EOT_2_ALT	0x00020000
+#define IPU_DMFC_STAT			0x00000034
+#define  DMFC_STAT_IC_BUFFER_EMPTY	0x02000000
+#define  DMFC_STAT_IC_BUFFER_FULL	0x01000000
+#define  DMFC_STAT_FIFO_EMPTY(n)	__BIT(12 + (n))
+#define  DMFC_STAT_FIFO_FULL(n)		__BIT((n))
+
+/*
+ * VCI
+ * Video De Interkacing Module
+ */
+#define IPU_VDI_FSIZE	0x00000000
+#define IPU_VDI_C	0x00000004
+
+/*
+ * DP
+ * Display Processor
+ */
+#define IPU_DP_COM_CONF_SYNC		0x00000000
+#define  DP_FG_EN_SYNC			0x00000001
+#define  DP_DP_GWAM_SYNC		0x00000004
+#define IPU_DP_GRAPH_WIND_CTRL_SYNC	0x00000004
+#define IPU_DP_FG_POS_SYNC		0x00000008
+#define IPU_DP_CUR_POS_SYNC		0x0000000c
+#define IPU_DP_CUR_MAP_SYNC		0x00000010
+#define IPU_DP_CSC_SYNC_0		0x00000054
+#define IPU_DP_CSC_SYNC_1		0x00000058
+#define IPU_DP_CUR_POS_ALT		0x0000005c
+#define IPU_DP_COM_CONF_ASYNC0		0x00000060
+#define IPU_DP_GRAPH_WIND_CTRL_ASYNC0	0x00000064
+#define IPU_DP_FG_POS_ASYNC0		0x00000068
+#define IPU_DP_CUR_POS_ASYNC0		0x0000006c
+#define IPU_DP_CUR_MAP_ASYNC0		0x00000070
+#define IPU_DP_CSC_ASYNC0_0		0x000000b4
+#define IPU_DP_CSC_ASYNC0_1		0x000000b8
+#define IPU_DP_COM_CONF_ASYNC1		0x000000bc
+#define IPU_DP_GRAPH_WIND_CTRL_ASYNC1	0x000000c0
+#define IPU_DP_FG_POS_ASYNC1		0x000000c4
+#define IPU_DP_CUR_POS_ASYNC1		0x000000c8
+#define IPU_DP_CUR_MAP_ASYNC1		0x000000cc
+#define IPU_DP_CSC_ASYNC1_0		0x00000110
+#define IPU_DP_CSC_ASYNC1_1		0x00000114
+
+/* IDMA parameter */
+	/*
+	 * non-Interleaved parameter
+	 *
+	 * param 0: XV W0[ 9: 0]
+	 *          YV W0[18:10]
+	 *          XB W0[31:19]
+	 * param 1: YB W0[43:32]
+	 *          NSB W0[44]
+	 *          CF W0[45]
+	 *          UBO W0[61:46]
+	 * param 2: UBO W0[67:62]
+	 *          VBO W0[89:68]
+	 *          IOX W0[93:90]
+	 *          RDRW W0[94]
+	 *          Reserved W0[95]
+	 * param 3: Reserved W0[112:96]
+	 *          S0 W0[113]
+	 *          BNDM W0[116:114]
+	 *          BM W0[118:117]
+	 *          ROT W0[119]
+	 *          HF W0[120]
+	 *          VF W0[121]
+	 *          THF W0[122]
+	 *          CAP W0[123]
+	 *          CAE W0[124]
+	 *          FW W0[127:125]
+	 * param 4: FW W0[137:128]
+	 *          FH W0[149:138]
+	 * param 5: EBA0 W1[28:0]
+	 *          EBA1 W1[31:29]
+	 * param 6: EBA1 W1[57:32]
+	 *          ILO W1[63:58]
+	 * param 7: ILO W1[77:64]
+	 *          NPB W1[84:78]
+	 *          PFS W1[88:85]
+	 *          ALU W1[89]
+	 *          ALBM W1[92:90]
+	 *          ID W1[94:93]
+	 *          TH W1[95]
+	 * param 8: TH W1[101:96]
+	 *          SLY W1[115:102]
+	 *          WID3 W1[127:125]
+	 * param 9: SLUV W1[141:128]
+	 *          CRE W1[149]
+	 *
+	 * Interleaved parameter
+	 *
+	 * param 0: XV W0[ 9: 0]
+	 *          YV W0[18:10]
+	 *          XB W0[31:19]
+	 * param 1: YB W0[43:32]
+	 *          NSB W0[44]
+	 *          CF W0[45]
+	 *          SX W0[57:46]
+	 *          SY W0[61:58]
+	 * param 2: SY W0[68:62]
+	 *          NS W0[78:69]
+	 *          SDX W0[85:79]
+	 *          SM W0[95:86]
+	 * param 3: SCC W0[96]
+	 *          SCE W0[97]
+	 *          SDY W0[104:98]
+	 *          SDRX W0[105]
+	 *          SDRY W0[106]
+	 *          BPP W0[109:107]
+	 *	    DEC_SEL W0[111:110]
+	 *          DIM W0[112]
+	 *          SO W0[113]
+	 *          BNDM W0[116:114]
+	 *          BM W0[118:117]
+	 *          ROT W0[119]
+	 *          HF W0[120]
+	 *          VF W0[121]
+	 *          THF W0[122]
+	 *          CAP W0[123]
+	 *          CAE W0[124]
+	 *          FW W0[127:125]
+	 * param 4: FW W0[137:128]
+	 *          FH W0[149:138]
+	 * param 5: EBA0 W1[28:0]
+	 *          EBA1 W1[31:29]
+	 * param 6: EBA1 W1[57:32]
+	 *          ILO W1[63:58]
+	 * param 7: ILO W1[77:64]
+	 *          NPB W1[84:78]
+	 *          PFS W1[88:85]
+	 *          ALU W1[89]
+	 *          ALBM W1[92:90]
+	 *          ID W1[94:93]
+	 *          TH W1[95]
+	 * param 8: TH W1[101:96]
+	 *          SL W1[115:102]
+	 *          WID0 W1[118:116]
+	 *          WID1 W1[121:119]
+	 *          WID2 W1[124:122]
+	 *          WID3 W1[127:125]
+	 * param 9: OFS0 W1[132:128]
+	 *          OFS1 W1[137:133]
+	 *          OFS2 W1[142:138]
+	 *          OFS3 W1[147:143]
+	 *          SXYS W1[148]
+	 *          CRE W1[149]
+	 *          DEC_SEL2 W1[150]
+	 */
+
+#define __IDMA_PARAM(word, shift, size) \
+	((((word) & 0xff) << 16) | (((shift) & 0xff) << 8) | ((size) & 0xff))
+
+/* non-Interleaved parameter */
+/* W0 */
+#define IDMAC_Ch_PARAM_XV	__IDMA_PARAM(0,  0, 10)
+#define IDMAC_Ch_PARAM_YV	__IDMA_PARAM(0, 10,  9)
+#define IDMAC_Ch_PARAM_XB	__IDMA_PARAM(0, 19, 13)
+#define IDMAC_Ch_PARAM_YB	__IDMA_PARAM(0, 32, 12)
+#define IDMAC_Ch_PARAM_NSB	__IDMA_PARAM(0, 44,  1)
+#define IDMAC_Ch_PARAM_CF	__IDMA_PARAM(0, 45,  1)
+#define IDMAC_Ch_PARAM_UBO	__IDMA_PARAM(0, 46, 22)
+#define IDMAC_Ch_PARAM_VBO	__IDMA_PARAM(0, 68, 22)
+#define IDMAC_Ch_PARAM_IOX	__IDMA_PARAM(0, 90,  4)
+#define IDMAC_Ch_PARAM_RDRW	__IDMA_PARAM(0, 94,  1)
+#define IDMAC_Ch_PARAM_S0	__IDMA_PARAM(0,113,  1)
+#define IDMAC_Ch_PARAM_BNDM	__IDMA_PARAM(0,114,  3)
+#define IDMAC_Ch_PARAM_BM	__IDMA_PARAM(0,117,  2)
+#define IDMAC_Ch_PARAM_ROT	__IDMA_PARAM(0,119,  1)
+#define IDMAC_Ch_PARAM_HF	__IDMA_PARAM(0,120,  1)
+#define IDMAC_Ch_PARAM_VF	__IDMA_PARAM(0,121,  1)
+#define IDMAC_Ch_PARAM_THF	__IDMA_PARAM(0,122,  1)
+#define IDMAC_Ch_PARAM_CAP	__IDMA_PARAM(0,123,  1)
+#define IDMAC_Ch_PARAM_CAE	__IDMA_PARAM(0,124,  1)
+#define IDMAC_Ch_PARAM_FW	__IDMA_PARAM(0,125, 13)
+#define IDMAC_Ch_PARAM_FH	__IDMA_PARAM(0,138, 12)
+/* W1 */
+#define IDMAC_Ch_PARAM_EBA0	__IDMA_PARAM(1,  0, 29)
+#define IDMAC_Ch_PARAM_EBA1	__IDMA_PARAM(1, 29, 29)
+#define IDMAC_Ch_PARAM_ILO	__IDMA_PARAM(1, 58, 20)
+#define IDMAC_Ch_PARAM_NPB	__IDMA_PARAM(1, 78,  7)
+#define IDMAC_Ch_PARAM_PFS	__IDMA_PARAM(1, 85,  4)
+#define IDMAC_Ch_PARAM_ALU	__IDMA_PARAM(1, 89,  1)
+#define IDMAC_Ch_PARAM_ALBM	__IDMA_PARAM(1, 90,  3)
+#define IDMAC_Ch_PARAM_ID	__IDMA_PARAM(1, 93,  2)
+#define IDMAC_Ch_PARAM_TH	__IDMA_PARAM(1, 95,  7)
+#define IDMAC_Ch_PARAM_SL	__IDMA_PARAM(1,102, 14)
+#define IDMAC_Ch_PARAM_WID3	__IDMA_PARAM(1,125,  3)
+#define IDMAC_Ch_PARAM_SLUV	__IDMA_PARAM(1,128, 14)
+#define IDMAC_Ch_PARAM_CRE	__IDMA_PARAM(1,149,  1)
+
+/* Interleaved parameter */
+/* W0 */
+#define IDMAC_Ch_PARAM_XV	__IDMA_PARAM(0,  0, 10)
+#define IDMAC_Ch_PARAM_YV	__IDMA_PARAM(0, 10,  9)
+#define IDMAC_Ch_PARAM_XB	__IDMA_PARAM(0, 19, 13)
+#define IDMAC_Ch_PARAM_YB	__IDMA_PARAM(0, 32, 12)
+#define IDMAC_Ch_PARAM_NSB	__IDMA_PARAM(0, 44,  1)
+#define IDMAC_Ch_PARAM_CF	__IDMA_PARAM(0, 45,  1)
+#define IDMAC_Ch_PARAM_SX	__IDMA_PARAM(0, 46, 12)
+#define IDMAC_Ch_PARAM_SY	__IDMA_PARAM(0, 58, 11)
+#define IDMAC_Ch_PARAM_NS	__IDMA_PARAM(0, 69, 10)
+#define IDMAC_Ch_PARAM_SDX	__IDMA_PARAM(0, 79,  7)
+#define IDMAC_Ch_PARAM_SM	__IDMA_PARAM(0, 86, 10)
+#define IDMAC_Ch_PARAM_SCC	__IDMA_PARAM(0, 96,  1)
+#define IDMAC_Ch_PARAM_SCE	__IDMA_PARAM(0, 97,  1)
+#define IDMAC_Ch_PARAM_SDY	__IDMA_PARAM(0, 98,  7)
+#define IDMAC_Ch_PARAM_SDRX	__IDMA_PARAM(0,105,  1)
+#define IDMAC_Ch_PARAM_SDRY	__IDMA_PARAM(0,106,  1)
+#define IDMAC_Ch_PARAM_BPP	__IDMA_PARAM(0,107,  3)
+#define IDMAC_Ch_PARAM_DEC_SEL	__IDMA_PARAM(0,110,  2)
+#define IDMAC_Ch_PARAM_DIM	__IDMA_PARAM(0,112,  1)
+#define IDMAC_Ch_PARAM_SO	__IDMA_PARAM(0,113,  1)
+#define IDMAC_Ch_PARAM_BNDM	__IDMA_PARAM(0,114,  3)
+#define IDMAC_Ch_PARAM_BM	__IDMA_PARAM(0,117,  2)
+#define IDMAC_Ch_PARAM_ROT	__IDMA_PARAM(0,119,  1)
+#define IDMAC_Ch_PARAM_HF	__IDMA_PARAM(0,120,  1)
+#define IDMAC_Ch_PARAM_VF	__IDMA_PARAM(0,121,  1)
+#define IDMAC_Ch_PARAM_THF	__IDMA_PARAM(0,122,  1)
+#define IDMAC_Ch_PARAM_CAP	__IDMA_PARAM(0,123,  1)
+#define IDMAC_Ch_PARAM_CAE	__IDMA_PARAM(0,124,  1)
+#define IDMAC_Ch_PARAM_FW	__IDMA_PARAM(0,125, 13)
+#define IDMAC_Ch_PARAM_FH	__IDMA_PARAM(0,138, 12)
+/* W1 */
+#define IDMAC_Ch_PARAM_EBA0	__IDMA_PARAM(1,  0, 29)
+#define IDMAC_Ch_PARAM_EBA1	__IDMA_PARAM(1, 29, 29)
+#define IDMAC_Ch_PARAM_ILO	__IDMA_PARAM(1, 58, 20)
+#define IDMAC_Ch_PARAM_NPB	__IDMA_PARAM(1, 78,  7)
+#define IDMAC_Ch_PARAM_PFS	__IDMA_PARAM(1, 85,  4)
+#define IDMAC_Ch_PARAM_ALU	__IDMA_PARAM(1, 89,  1)
+#define IDMAC_Ch_PARAM_ALBM	__IDMA_PARAM(1, 90,  3)
+#define IDMAC_Ch_PARAM_ID	__IDMA_PARAM(1, 93,  2)
+#define IDMAC_Ch_PARAM_TH	__IDMA_PARAM(1, 95,  7)
+#define IDMAC_Ch_PARAM_SL	__IDMA_PARAM(1,102, 14)
+#define IDMAC_Ch_PARAM_WID0	__IDMA_PARAM(1,116,  3)
+#define IDMAC_Ch_PARAM_WID1	__IDMA_PARAM(1,119,  3)
+#define IDMAC_Ch_PARAM_WID2	__IDMA_PARAM(1,122,  3)
+#define IDMAC_Ch_PARAM_WID3	__IDMA_PARAM(1,125,  3)
+#define IDMAC_Ch_PARAM_OFS0	__IDMA_PARAM(1,128,  5)
+#define IDMAC_Ch_PARAM_OFS1	__IDMA_PARAM(1,133,  5)
+#define IDMAC_Ch_PARAM_OFS2	__IDMA_PARAM(1,138,  5)
+#define IDMAC_Ch_PARAM_OFS3	__IDMA_PARAM(1,143,  5)
+#define IDMAC_Ch_PARAM_SXYS	__IDMA_PARAM(1,148,  1)
+#define IDMAC_Ch_PARAM_CRE	__IDMA_PARAM(1,149,  1)
+#define IDMAC_Ch_PARAM_DEC_SEL2 __IDMA_PARAM(1,150,  1)
+
+/* XXX Temp */
+#define	GPUMEM_BASE	0x20000000
+#define	GPUMEM_SIZE	0x20000
+
+#define	GPU_BASE	0x30000000
+#define	GPU_SIZE	0x10000000
+
+/* 
+ * Image Processing Unit 
+ *
+ * All addresses are relative to the base SoC address. 
+ */
+#define	IPU_CM_BASE(_base)	((_base) + 0x1e000000)
+#define	IPU_CM_SIZE		0x8000
+#define	IPU_IDMAC_BASE(_base)	((_base) + 0x1e008000)
+#define	IPU_IDMAC_SIZE		0x8000
+#define	IPU_DP_BASE(_base)	((_base) + 0x1e018000)
+#define	IPU_DP_SIZE		0x8000
+#define	IPU_IC_BASE(_base)	((_base) + 0x1e020000)
+#define	IPU_IC_SIZE		0x8000
+#define	IPU_IRT_BASE(_base)	((_base) + 0x1e028000)
+#define	IPU_IRT_SIZE		0x8000
+#define	IPU_CSI0_BASE(_base)	((_base) + 0x1e030000)
+#define	IPU_CSI0_SIZE		0x8000
+#define	IPU_CSI1_BASE(_base)	((_base) + 0x1e038000)
+#define	IPU_CSI1_SIZE		0x8000
+#define	IPU_DI0_BASE(_base)	((_base) + 0x1e040000)
+#define	IPU_DI0_SIZE		0x8000
+#define	IPU_DI1_BASE(_base)	((_base) + 0x1e048000)
+#define	IPU_DI1_SIZE		0x8000
+#define	IPU_SMFC_BASE(_base)	((_base) + 0x1e050000)
+#define	IPU_SMFC_SIZE		0x8000
+#define	IPU_DC_BASE(_base)	((_base) + 0x1e058000)
+#define	IPU_DC_SIZE		0x8000
+#define	IPU_DMFC_BASE(_base)	((_base) + 0x1e060000)
+#define	IPU_DMFC_SIZE		0x8000
+#define	IPU_VDI_BASE(_base)	((_base) + 0x1e068000)
+#define	IPU_VDI_SIZE		0x8000
+#define	IPU_CPMEM_BASE(_base)	((_base) + 0x1f000000)
+#define	IPU_CPMEM_SIZE		0x20000
+#define	IPU_LUT_BASE(_base)	((_base) + 0x1f020000)
+#define	IPU_LUT_SIZE		0x20000
+#define	IPU_SRM_BASE(_base)	((_base) + 0x1f040000)
+#define	IPU_SRM_SIZE		0x20000
+#define	IPU_TPM_BASE(_base)	((_base) + 0x1f060000)
+#define	IPU_TPM_SIZE		0x20000
+#define	IPU_DCTMPL_BASE(_base)	((_base) + 0x1f080000)
+#define	IPU_DCTMPL_SIZE		0x20000
+
+#endif /* _ARM_IMX_IMX51_IPUV3REG_H */


Property changes on: trunk/sys/arm/freescale/imx/imx51_ipuv3reg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/imx/imx51_machdep.c
===================================================================
--- trunk/sys/arm/freescale/imx/imx51_machdep.c	                        (rev 0)
+++ trunk/sys/arm/freescale/imx/imx51_machdep.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,103 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Ian Lepore <ian at freebsd.org>
+ * 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: stable/10/sys/arm/freescale/imx/imx51_machdep.c 259365 2013-12-14 00:16:08Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/reboot.h>
+
+#include <vm/vm.h>
+
+#include <machine/bus.h>
+#include <machine/devmap.h>
+#include <machine/machdep.h>
+
+#include <arm/freescale/imx/imx_machdep.h>
+
+vm_offset_t
+initarm_lastaddr(void)
+{
+
+	return (arm_devmap_lastaddr());
+}
+
+void
+initarm_early_init(void)
+{
+
+	/* XXX - Get rid of this stuff soon. */
+	boothowto |= RB_VERBOSE|RB_MULTIPLE;
+	bootverbose = 1;
+}
+
+void
+initarm_gpio_init(void)
+{
+
+}
+
+void
+initarm_late_init(void)
+{
+
+}
+
+/*
+ * Set up static device mappings.  This is hand-optimized platform-specific
+ * config data which covers most of the common on-chip devices with a few 1MB
+ * section mappings.
+ *
+ * Notably missing are entries for GPU, IPU, in general anything video related.
+ */
+int
+initarm_devmap_init(void)
+{
+
+	arm_devmap_add_entry(0x70000000, 0x00100000);
+	arm_devmap_add_entry(0x73f00000, 0x00100000);
+	arm_devmap_add_entry(0x83f00000, 0x00100000);
+
+	return (0);
+}
+
+void
+cpu_reset(void)
+{
+
+	imx_wdog_cpu_reset(0x73F98000);
+}
+
+u_int imx_soc_type()
+{
+	return (IMXSOC_51);
+}
+


Property changes on: trunk/sys/arm/freescale/imx/imx51_machdep.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/imx/imx51_sdmareg.h
===================================================================
--- trunk/sys/arm/freescale/imx/imx51_sdmareg.h	                        (rev 0)
+++ trunk/sys/arm/freescale/imx/imx51_sdmareg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,143 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012, 2013 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Oleksandr Rybalko under sponsorship
+ * from the FreeBSD Foundation.
+ *
+ * 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: stable/10/sys/arm/freescale/imx/imx51_sdmareg.h 250357 2013-05-08 09:42:50Z ray $
+ */
+
+/* Internal Registers definition for Freescale i.MX515 SDMA Core */
+
+/* SDMA Core Instruction Memory Space */
+#define	SDMA_IBUS_ROM_ADDR_BASE	0x0000
+#define	SDMA_IBUS_ROM_ADDR_SIZE	0x07ff
+#define	SDMA_IBUS_RAM_ADDR_BASE	0x1000
+#define	SDMA_IBUS_RAM_ADDR_SIZE	0x1fff
+
+/* SDMA Core Internal Registers */
+#define	SDMA_MC0PTR	0x7000 /* AP (MCU) Channel 0 Pointer R */
+
+#define	SDMA_CCPTR	0x7002 /* Current Channel Pointer R */
+#define		SDMA_ECTL_CCPTR_MASK	0x0000ffff
+#define		SDMA_ECTL_CCPTR_SHIFT	0
+
+#define	SDMA_CCR	0x7003 /* Current Channel Register R */
+#define		SDMA_ECTL_CCR_MASK	0x0000001f
+#define		SDMA_ECTL_CCR_SHIFT	0
+
+#define	SDMA_NCR	0x7004 /* Highest Pending Channel Register R */
+#define		SDMA_ECTL_NCR_MASK	0x0000001f
+#define		SDMA_ECTL_NCR_SHIFT	0
+
+#define	SDMA_EVENTS	0x7005 /* External DMA Requests Mirror R */
+
+#define	SDMA_CCPRI	0x7006 /* Current Channel Priority R */
+#define		SDMA_ECTL_CCPRI_MASK	0x00000007
+#define		SDMA_ECTL_CCPRI_SHIFT	0
+
+#define	SDMA_NCPRI	0x7007 /* Next Channel Priority R */
+#define		SDMA_ECTL_NCPRI_MASK	0x00000007
+#define		SDMA_ECTL_NCPRI_SHIFT	0
+
+#define	SDMA_ECOUNT	0x7009 /* OnCE Event Cell Counter R/W */
+#define		SDMA_ECTL_ECOUNT_MASK	0x0000ffff
+#define		SDMA_ECTL_ECOUNT_SHIFT	0
+
+#define	SDMA_ECTL	0x700A /* OnCE Event Cell Control Register R/W */
+#define		SDMA_ECTL_EN		(1 << 13)
+#define		SDMA_ECTL_CNT		(1 << 12)
+#define		SDMA_ECTL_ECTC_MASK	0x00000c00
+#define		SDMA_ECTL_ECTC_SHIFT	10
+#define		SDMA_ECTL_DTC_MASK	0x00000300
+#define		SDMA_ECTL_DTC_SHIFT	8
+#define		SDMA_ECTL_ATC_MASK	0x000000c0
+#define		SDMA_ECTL_ATC_SHIFT	6
+#define		SDMA_ECTL_ABTC_MASK	0x00000030
+#define		SDMA_ECTL_ABTC_SHIFT	4
+#define		SDMA_ECTL_AATC_MASK	0x0000000c
+#define		SDMA_ECTL_AATC_SHIFT	2
+#define		SDMA_ECTL_ATS_MASK	0x00000003
+#define		SDMA_ECTL_ATS_SHIFT	0
+
+#define	SDMA_EAA	0x700B /* OnCE Event Address Register A R/W */
+#define		SDMA_ECTL_EAA_MASK	0x0000ffff
+#define		SDMA_ECTL_EAA_SHIFT	0
+
+#define	SDMA_EAB	0x700C /* OnCE Event Cell Address Register B R/W */
+#define		SDMA_ECTL_EAB_MASK	0x0000ffff
+#define		SDMA_ECTL_EAB_SHIFT	0
+
+#define	SDMA_EAM	0x700D /* OnCE Event Cell Address Mask R/W */
+#define		SDMA_ECTL_EAM_MASK	0x0000ffff
+#define		SDMA_ECTL_EAM_SHIFT	0
+
+#define	SDMA_ED		0x700E /* OnCE Event Cell Data Register R/W */
+#define	SDMA_EDM	0x700F /* OnCE Event Cell Data Mask R/W */
+#define	SDMA_RTB	0x7018 /* OnCE Real-Time Buffer R/W */
+
+#define	SDMA_TB		0x7019 /* OnCE Trace Buffer R */
+#define		SDMA_TB_TBF		(1 << 28)
+#define		SDMA_TB_TADDR_MASK	0x0fffc000
+#define		SDMA_TB_TADDR_SHIFT	14
+#define		SDMA_TB_CHFADDR_MASK	0x00003fff
+#define		SDMA_TB_CHFADDR_SHIFT	0
+
+#define	SDMA_OSTAT	0x701A /* OnCE Status R */
+#define		SDMA_OSTAT_PST_MASK	0x0000f000
+#define		SDMA_OSTAT_PST_SHIFT	12
+#define		SDMA_OSTAT_RCV		(1 << 11)
+#define		SDMA_OSTAT_EDR		(1 << 10)
+#define		SDMA_OSTAT_ODR		(1 << 9)
+#define		SDMA_OSTAT_SWB		(1 << 8)
+#define		SDMA_OSTAT_MST		(1 << 7)
+#define		SDMA_OSTAT_ECDR_MASK	0x00000007
+#define		SDMA_OSTAT_ECDR_SHIFT	0
+
+#define	SDMA_MCHN0ADDR	0x701C /* Channel 0 Boot Address R */
+#define		SDMA_MCHN0ADDR_SMS_Z	(1 << 14)
+#define		SDMA_MCHN0ADDR_CHN0ADDR_MASK 0x00003fff
+#define		SDMA_MCHN0ADDR_CHN0ADDR_SHIFT 0
+
+#define	SDMA_MODE	0x701D /* Mode Status Register R */
+#define		SDMA_MODE_DSPCtrl	(1 << 3)
+#define		SDMA_MODE_AP_END	(1 << 0)
+
+#define	SDMA_LOCK	0x701E /* Lock Status Register R */
+#define		SDMA_LOCK_LOCK		(1 << 0)
+
+#define	SDMA_EVENTS2	0x701F /* External DMA Requests Mirror #2 R */
+
+#define	SDMA_HE		0x7020 /* AP Enable Register R */
+#define	SDMA_PRIV	0x7022 /* Current Channel BP Privilege Register R */
+#define		SDMA_PRIV_BPPRIV	(1 << 0)
+#define	SDMA_PRF_CNT	0x7023 /* Profile Free Running Register R/W */
+#define		SDMA_PRF_CNT_SEL_MASK	0xc0000000
+#define		SDMA_PRF_CNT_SEL_SHIFT	30
+#define		SDMA_PRF_CNT_EN		(1 << 29)
+#define		SDMA_PRF_CNT_OFL	(1 << 22)
+#define		SDMA_PRF_CNT_COUNTER_MASK 0x003fffff
+#define		SDMA_PRF_CNT_COUNTER_SHIFT 0


Property changes on: trunk/sys/arm/freescale/imx/imx51_sdmareg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/imx/imx51_ssireg.h
===================================================================
--- trunk/sys/arm/freescale/imx/imx51_ssireg.h	                        (rev 0)
+++ trunk/sys/arm/freescale/imx/imx51_ssireg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,181 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012, 2013 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Oleksandr Rybalko under sponsorship
+ * from the FreeBSD Foundation.
+ *
+ * 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: stable/10/sys/arm/freescale/imx/imx51_ssireg.h 250357 2013-05-08 09:42:50Z ray $
+ */
+
+/* Registers definition for Freescale i.MX515 Synchronous Serial Interface */
+
+#define	IMX51_SSI_STX0_REG	0x0000 /* SSI TX Data Register 0 */
+#define	IMX51_SSI_STX1_REG	0x0004 /* SSI TX Data Register 1 */
+#define	IMX51_SSI_SRX0_REG	0x0008 /* SSI RX Data Register 0 */
+#define	IMX51_SSI_SRX1_REG	0x000C /* SSI RX Data Register 1 */
+#define	IMX51_SSI_SCR_REG	0x0010 /* SSI Control Register */
+#define		SSI_SCR_RFR_CLK_DIS	(1 << 11) /* RX FC Disable */
+#define		SSI_SCR_TFR_CLK_DIS	(1 << 10) /* TX FC Disable */
+#define		SSI_SCR_CLK_IST		(1 << 9) /* Clock Idle */
+#define		SSI_SCR_TCH_EN		(1 << 8) /* 2Chan Enable */
+#define		SSI_SCR_SYS_CLK_EN	(1 << 7) /* System Clock En */
+#define		SSI_SCR_MODE_NORMAL	(0 << 5)
+#define		SSI_SCR_MODE_I2S_MASTER	(1 << 5)
+#define		SSI_SCR_MODE_I2S_SLAVE	(2 << 5)
+#define		SSI_SCR_MODE_MASK	(3 << 5)
+#define		SSI_SCR_SYN		(1 << 4) /* Sync Mode */
+#define		SSI_SCR_NET		(1 << 3) /* Network Mode */
+#define		SSI_SCR_RE		(1 << 2) /* RX Enable */
+#define		SSI_SCR_TE		(1 << 1) /* TX Enable */
+#define		SSI_SCR_SSIEN		(1 << 0) /* SSI Enable */
+
+#define	IMX51_SSI_SISR_REG	0x0014 /* SSI Interrupt Status Register */
+#define		SSI_SISR_RFRC		(1 << 24) /* RX Frame Complete */
+#define		SSI_SIR_TFRC		(1 << 23) /* TX Frame Complete */
+#define		SSI_SIR_CMDAU		(1 << 18) /* Command Address Updated */
+#define		SSI_SIR_CMDDU		(1 << 17) /* Command Data Updated */
+#define		SSI_SIR_RXT		(1 << 16) /* RX Tag Updated */
+#define		SSI_SIR_RDR1		(1 << 15) /* RX Data Ready 1 */
+#define		SSI_SIR_RDR0		(1 << 14) /* RX Data Ready 0 */
+#define		SSI_SIR_TDE1		(1 << 13) /* TX Data Reg Empty 1 */
+#define		SSI_SIR_TDE0		(1 << 12) /* TX Data Reg Empty 0 */
+#define		SSI_SIR_ROE1		(1 << 11) /* RXer Overrun Error 1 */
+#define		SSI_SIR_ROE0		(1 << 10) /* RXer Overrun Error 0 */
+#define		SSI_SIR_TUE1		(1 << 9) /* TXer Underrun Error 1 */
+#define		SSI_SIR_TUE0		(1 << 8) /* TXer Underrun Error 0 */
+#define		SSI_SIR_TFS		(1 << 7) /* TX Frame Sync */
+#define		SSI_SIR_RFS		(1 << 6) /* RX Frame Sync */
+#define		SSI_SIR_TLS		(1 << 5) /* TX Last Time Slot */
+#define		SSI_SIR_RLS		(1 << 4) /* RX Last Time Slot */
+#define		SSI_SIR_RFF1		(1 << 3) /* RX FIFO Full 1 */
+#define		SSI_SIR_RFF0		(1 << 2) /* RX FIFO Full 0 */
+#define		SSI_SIR_TFE1		(1 << 1) /* TX FIFO Empty 1 */
+#define		SSI_SIR_TFE0		(1 << 0) /* TX FIFO Empty 0 */
+
+#define	IMX51_SSI_SIER_REG	0x0018 /* SSI Interrupt Enable Register */
+/* 24-23 Enable Bit	(See SISR) */
+#define		SSI_SIER_RDMAE		(1 << 22) /* RX DMA Enable */
+#define		SSI_SIER_RIE		(1 << 21) /* RX Interrupt Enable */
+#define		SSI_SIER_TDMAE		(1 << 20) /* TX DMA Enable */
+#define		SSI_SIER_TIE		(1 << 19) /* TX Interrupt Enable */
+/* 18-0 Enable Bits	(See SISR) */
+
+#define	IMX51_SSI_STCR_REG	0x001C /* SSI TX Configuration Register */
+#define		SSI_STCR_TXBIT0		(1 << 9) /* TX Bit 0 */
+#define		SSI_STCR_TFEN1		(1 << 8) /* TX FIFO Enable 1 */
+#define		SSI_STCR_TFEN0		(1 << 7) /* TX FIFO Enable 0 */
+#define		SSI_STCR_TFDIR		(1 << 6) /* TX Frame Direction */
+#define		SSI_STCR_TXDIR		(1 << 5) /* TX Clock Direction */
+#define		SSI_STCR_TSHFD		(1 << 4) /* TX Shift Direction */
+#define		SSI_STCR_TSCKP		(1 << 3) /* TX Clock Polarity */
+#define		SSI_STCR_TFSI		(1 << 2) /* TX Frame Sync Invert */
+#define		SSI_STCR_TFSL		(1 << 1) /* TX Frame Sync Length */
+#define		SSI_STCR_TEFS		(1 << 0) /* TX Early Frame Sync */
+
+#define	IMX51_SSI_SRCR_REG	0x0020 /* SSI RX Configuration Register */
+#define		SSI_SRCR_RXEXT		(1 << 10) /* RX Data Extension */
+#define		SSI_SRCR_RXBIT0		(1 << 9) /* RX Bit 0 */
+#define		SSI_SRCR_RFEN1		(1 << 8) /* RX FIFO Enable 1 */
+#define		SSI_SRCR_RFEN0		(1 << 7) /* RX FIFO Enable 0 */
+#define		SSI_SRCR_RFDIR		(1 << 6) /* RX Frame Direction */
+#define		SSI_SRCR_RXDIR		(1 << 5) /* RX Clock Direction */
+#define		SSI_SRCR_RSHFD		(1 << 4) /* RX Shift Direction */
+#define		SSI_SRCR_RSCKP		(1 << 3) /* RX Clock Polarity */
+#define		SSI_SRCR_RFSI		(1 << 2) /* RX Frame Sync Invert */
+#define		SSI_SRCR_RFSL		(1 << 1) /* RX Frame Sync Length */
+#define		SSI_SRCR_REFS		(1 << 0) /* RX Early Frame Sync */
+
+#define	IMX51_SSI_STCCR_REG	0x0024 /* TX Clock Control */
+#define	IMX51_SSI_SRCCR_REG	0x0028 /* RX Clock Control */
+#define		SSI_SXCCR_DIV2		(1 << 18) /* Divide By 2 */
+#define		SSI_SXCCR_PSR		(1 << 17) /* Prescaler Range */
+#define		SSI_SXCCR_WL_MASK	0x0001e000
+#define		SSI_SXCCR_WL_SHIFT	13 /* Word Length Control */
+#define		SSI_SXCCR_DC_MASK	0x00001f00
+#define		SSI_SXCCR_DC_SHIFT	8 /* Frame Rate Divider */
+#define		SSI_SXCCR_PM_MASK	0x000000ff
+#define		SSI_SXCCR_PM_SHIFT	0 /* Prescaler Modulus */
+
+#define	IMX51_SSI_SFCSR_REG	0x002C /* SSI FIFO Control/Status Register */
+#define		SSI_SFCSR_RFCNT1_MASK	0xf0000000
+#define		SSI_SFCSR_RFCNT1_SHIFT	28 /* RX FIFO Counter 1 */
+#define		SSI_SFCSR_TFCNT1_MASK	0x0f000000
+#define		SSI_SFCSR_TFCNT1_SHIFT	24 /* TX FIFO Counter 1 */
+#define		SSI_SFCSR_RFWM1_MASK	0x00f00000
+#define		SSI_SFCSR_RFWM1_SHIFT	20 /* RX FIFO Full WaterMark 1 */
+#define		SSI_SFCSR_TFWM1_MASK	0x000f0000
+#define		SSI_SFCSR_TFWM1_SHIFT	16 /* TX FIFO Empty WaterMark 1 */
+#define		SSI_SFCSR_RFCNT0_MASK	0x0000f000
+#define		SSI_SFCSR_RFCNT0_SHIFT	12 /* RX FIFO Counter 0 */
+#define		SSI_SFCSR_TFCNT0_MASK	0x00000f00
+#define		SSI_SFCSR_TFCNT0_SHIFT	8 /* TX FIFO Counter 0 */
+#define		SSI_SFCSR_RFWM0_MASK	0x000000f0
+#define		SSI_SFCSR_RFWM0_SHIFT	4 /* RX FIFO Full WaterMark 0 */
+#define		SSI_SFCSR_TFWM0_MASK	0x0000000f
+#define		SSI_SFCSR_TFWM0_SHIFT	0 /* TX FIFO Empty WaterMark 0 */
+
+#define	IMX51_SSI_STR_REG	0x0030 /* SSI Test Register1 */
+#define		SSI_STR_TEST		(1 << 15) /* Test Mode */
+#define		SSI_STR_RCK2TCK		(1 << 14) /* RX<->TX Clock Loop Back */
+#define		SSI_STR_RFS2TFS		(1 << 13) /* RX<->TX Frame Loop Back */
+#define		SSI_STR_RXSTATE_MASK	0x00001f00
+#define		SSI_STR_RXSTATE_SHIFT	8 /* RXer State Machine Status */
+#define		SSI_STR_TXD2RXD		(1 << 7) /* TX<->RX Data Loop Back */
+#define		SSI_STR_TCK2RCK		(1 << 6) /* TX<->RX Clock Loop Back */
+#define		SSI_STR_TFS2RFS		(1 << 5) /* TX<->RX Frame Loop Back */
+#define		SSI_STR_TXSTATE_MASK	0x0000001f
+#define		SSI_STR_TXSTATE_SHIFT	0 /* TXer State Machine Status */
+
+#define	IMX51_SSI_SOR_REG	0x0034 /* SSI Option Register2 */
+#define		SSI_SOR_CLKOFF		(1 << 6) /* Clock Off */
+#define		SSI_SOR_RX_CLR		(1 << 5) /* RXer Clear */
+#define		SSI_SOR_TX_CLR		(1 << 4) /* TXer Clear */
+#define		SSI_SOR_INIT		(1 << 3) /* Initialize */
+#define		SSI_SOR_WAIT_MASK	0x00000006
+#define		SSI_SOR_INIT_SHIFT	1 /* Wait */
+#define		SSI_SOR_SYNRST		(1 << 0) /* Frame Sync Reset */
+
+#define	IMX51_SSI_SACNT_REG	0x0038 /* SSI AC97 Control Register */
+#define		SSI_SACNT_FRDIV_MASK	0x000007e0
+#define		SSI_SACNT_FRDIV_SHIFT	5 /* Frame Rate Divider */
+#define		SSI_SACNT_WR		(1 << 4) /* Write Command */
+#define		SSI_SACNT_RD		(1 << 3) /* Read Command */
+#define		SSI_SACNT_TIF		(1 << 2) /* Tag in FIFO */
+#define		SSI_SACNT_FV		(1 << 1) /* Fixed/Variable Operation */
+#define		SSI_SACNT_AC97EN	(1 << 0) /* AC97 Mode Enable */
+
+#define	IMX51_SSI_SACADD_REG	0x003C /* SSI AC97 Command Address Register */
+#define		SSI_SACADD_MASK		0x0007ffff
+#define	IMX51_SSI_SACDAT_REG	0x0040 /* SSI AC97 Command Data Register */
+#define		SSI_SACDAT_MASK		0x000fffff
+#define	IMX51_SSI_SATAG_REG	0x0044 /* SSI AC97 Tag Register */
+#define		SSI_SATAG_MASK		0x0000ffff
+#define	IMX51_SSI_STMSK_REG	0x0048 /* SSI TX Time Slot Mask Register */
+#define	IMX51_SSI_SRMSK_REG	0x004C /* SSI RX Time Slot Mask Register */
+#define	IMX51_SSI_SACCST_REG	0x0050 /* SSI AC97 Channel Status Register */
+#define	IMX51_SSI_SACCEN_REG	0x0054 /* SSI AC97 Channel Enable Register */
+#define	IMX51_SSI_SACCDIS_REG	0x0058 /* SSI AC97 Channel Disable Register */
+#define		SSI_SAC_MASK		0x000003ff /* SACCST,SACCEN,SACCDIS */


Property changes on: trunk/sys/arm/freescale/imx/imx51_ssireg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/imx/imx51_tzicreg.h
===================================================================
--- trunk/sys/arm/freescale/imx/imx51_tzicreg.h	                        (rev 0)
+++ trunk/sys/arm/freescale/imx/imx51_tzicreg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,86 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: imx51_tzicreg.h,v 1.1 2010/11/13 07:11:03 bsh Exp $	*/
+/*
+ * Copyright (c) 2010  Genetec Corporation.  All rights reserved.
+ * Written by Hashimoto Kenichi for Genetec Corporation.
+ *
+ * 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 GENETEC CORPORATION ``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 GENETEC CORPORATION
+ * 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.
+ */
+
+/*-
+ * Copyright (c) 2012, 2013 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * Portions of this software were developed by Oleksandr Rybalko
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * 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: stable/10/sys/arm/freescale/imx/imx51_tzicreg.h 263455 2014-03-20 23:48:18Z dim $
+ */
+
+#ifndef _IMX51_TZICREG_H_
+#define	_IMX51_TZICREG_H_
+
+#include <sys/cdefs.h>
+
+#define	TZIC_SIZE		0x4000
+#define	TZIC_INTCNTL		0x0000
+#define		INTCNTL_NSEN_MASK	0x80000000
+#define		INTCNTL_NSEN		0x00010000
+#define		INTCNTL_EN		0x00000001
+#define	TZIC_INTTYPE		0x0004
+#define	TZIC_PRIOMASK		0x000c
+#define	TZIC_SYNCCTRL		0x0010
+#define	TZIC_DSMINT		0x0014
+#define	TZIC_INTSEC(n)		(0x0080 + 0x04 * (n))
+#define	TZIC_ENSET(n)		(0x0100 + 0x04 * (n))
+#define	TZIC_ENCLEAR(n)		(0x0180 + 0x04 * (n))
+#define	TZIC_SRCSET(n)		(0x0200 + 0x04 * (n))
+#define	TZIC_SRCCLAR(n)		(0x0280 + 0x04 * (n))
+#define	TZIC_PRIORITY(n)	(0x0400 + 0x04 * (n))
+#define	TZIC_PND(n)		(0x0d00 + 0x04 * (n))
+#define	TZIC_HIPND(n)		(0x0d80 + 0x04 * (n))
+#define	TZIC_WAKEUP(n)		(0x0e00 + 0x04 * (n))
+#define	TZIC_SWINT		0x0f00
+
+#define	TZIC_INTNUM		128
+#endif /* _IMX51_TZICRREG_H_ */


Property changes on: trunk/sys/arm/freescale/imx/imx51_tzicreg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/imx/imx53_machdep.c
===================================================================
--- trunk/sys/arm/freescale/imx/imx53_machdep.c	                        (rev 0)
+++ trunk/sys/arm/freescale/imx/imx53_machdep.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,103 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Ian Lepore <ian at freebsd.org>
+ * 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: stable/10/sys/arm/freescale/imx/imx53_machdep.c 259365 2013-12-14 00:16:08Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/reboot.h>
+
+#include <vm/vm.h>
+
+#include <machine/bus.h>
+#include <machine/devmap.h>
+#include <machine/machdep.h>
+#include <arm/freescale/imx/imx_machdep.h>
+
+vm_offset_t
+initarm_lastaddr(void)
+{
+
+	return (arm_devmap_lastaddr());
+}
+
+void
+initarm_early_init(void)
+{
+
+	/* XXX - Get rid of this stuff soon. */
+	boothowto |= RB_VERBOSE|RB_MULTIPLE;
+	bootverbose = 1;
+}
+
+void
+initarm_gpio_init(void)
+{
+
+}
+
+void
+initarm_late_init(void)
+{
+
+}
+
+/*
+ * Set up static device mappings.  This is hand-optimized platform-specific
+ * config data which covers most of the common on-chip devices with a few 1MB
+ * section mappings.
+ *
+ * Notably missing are entries for GPU, IPU, in general anything video related.
+ */
+int
+initarm_devmap_init(void)
+{
+
+	arm_devmap_add_entry(0x50000000, 0x00100000);
+	arm_devmap_add_entry(0x53f00000, 0x00100000);
+	arm_devmap_add_entry(0x63f00000, 0x00100000);
+
+	return (0);
+}
+
+void
+cpu_reset(void)
+{
+
+	imx_wdog_cpu_reset(0x53F98000);
+}
+
+u_int imx_soc_type()
+{
+	return (IMXSOC_53);
+}
+
+


Property changes on: trunk/sys/arm/freescale/imx/imx53_machdep.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/imx/imx6_anatop.c
===================================================================
--- trunk/sys/arm/freescale/imx/imx6_anatop.c	                        (rev 0)
+++ trunk/sys/arm/freescale/imx/imx6_anatop.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,810 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Ian Lepore <ian at freebsd.org>
+ * Copyright (c) 2014 Steven Lawrance <stl at koffein.net>
+ * 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: stable/10/sys/arm/freescale/imx/imx6_anatop.c 294678 2016-01-24 19:34:05Z ian $");
+
+/*
+ * Analog PLL and power regulator driver for Freescale i.MX6 family of SoCs.
+ * Also, temperature montoring and cpu frequency control.  It was Freescale who
+ * kitchen-sinked this device, not us. :)
+ *
+ * We don't really do anything with analog PLLs, but the registers for
+ * controlling them belong to the same block as the power regulator registers.
+ * Since the newbus hierarchy makes it hard for anyone other than us to get at
+ * them, we just export a couple public functions to allow the imx6 CCM clock
+ * driver to read and write those registers.
+ *
+ * We also don't do anything about power regulation yet, but when the need
+ * arises, this would be the place for that code to live.
+ *
+ * I have no idea where the "anatop" name comes from.  It's in the standard DTS
+ * source describing i.MX6 SoCs, and in the linux and u-boot code which comes
+ * from Freescale, but it's not in the SoC manual.
+ *
+ * Note that temperature values throughout this code are handled in two types of
+ * units.  Items with '_cnt' in the name use the hardware temperature count
+ * units (higher counts are lower temperatures).  Items with '_val' in the name
+ * are deci-Celcius, which are converted to/from deci-Kelvins in the sysctl
+ * handlers (dK is the standard unit for temperature in sysctl).
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/callout.h>
+#include <sys/kernel.h>
+#include <sys/limits.h>
+#include <sys/sysctl.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/rman.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+
+#include <arm/arm/mpcore_timervar.h>
+#include <arm/freescale/fsl_ocotpreg.h>
+#include <arm/freescale/fsl_ocotpvar.h>
+#include <arm/freescale/imx/imx_ccmvar.h>
+#include <arm/freescale/imx/imx_machdep.h>
+#include <arm/freescale/imx/imx6_anatopreg.h>
+#include <arm/freescale/imx/imx6_anatopvar.h>
+
+static struct resource_spec imx6_anatop_spec[] = {
+	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		0,	RF_ACTIVE },
+	{ -1, 0 }
+};
+#define	MEMRES	0
+#define	IRQRES	1
+
+struct imx6_anatop_softc {
+	device_t	dev;
+	struct resource	*res[2];
+	struct intr_config_hook
+			intr_setup_hook;
+	uint32_t	cpu_curmhz;
+	uint32_t	cpu_curmv;
+	uint32_t	cpu_minmhz;
+	uint32_t	cpu_minmv;
+	uint32_t	cpu_maxmhz;
+	uint32_t	cpu_maxmv;
+	uint32_t	cpu_maxmhz_hw;
+	boolean_t	cpu_overclock_enable;
+	boolean_t	cpu_init_done;
+	uint32_t	refosc_mhz;
+	void		*temp_intrhand;
+	uint32_t	temp_high_val;
+	uint32_t	temp_high_cnt;
+	uint32_t	temp_last_cnt;
+	uint32_t	temp_room_cnt;
+	struct callout	temp_throttle_callout;
+	sbintime_t	temp_throttle_delay;
+	uint32_t	temp_throttle_reset_cnt;
+	uint32_t	temp_throttle_trigger_cnt;
+	uint32_t	temp_throttle_val;
+};
+
+static struct imx6_anatop_softc *imx6_anatop_sc;
+
+/*
+ * Table of "operating points".
+ * These are combinations of frequency and voltage blessed by Freescale.
+ * While the datasheet says the ARM voltage can be as low as 925mV at
+ * 396MHz, it also says that the ARM and SOC voltages can't differ by
+ * more than 200mV, and the minimum SOC voltage is 1150mV, so that
+ * dictates the 950mV entry in this table.
+ */
+static struct oppt {
+	uint32_t	mhz;
+	uint32_t	mv;
+} imx6_oppt_table[] = {
+	{ 396,	 950},
+	{ 792,	1150},
+	{ 852,	1225},
+	{ 996,	1225},
+	{1200,	1275},
+};
+
+/*
+ * Table of CPU max frequencies.  This is used to translate the max frequency
+ * value (0-3) from the ocotp CFG3 register into a mhz value that can be looked
+ * up in the operating points table.
+ */
+static uint32_t imx6_ocotp_mhz_tab[] = {792, 852, 996, 1200};
+
+#define	TZ_ZEROC	2732	/* deci-Kelvin <-> deci-Celcius offset. */
+
+uint32_t
+imx6_anatop_read_4(bus_size_t offset)
+{
+
+	KASSERT(imx6_anatop_sc != NULL, ("imx6_anatop_read_4 sc NULL"));
+
+	return (bus_read_4(imx6_anatop_sc->res[MEMRES], offset));
+}
+
+void
+imx6_anatop_write_4(bus_size_t offset, uint32_t value)
+{
+
+	KASSERT(imx6_anatop_sc != NULL, ("imx6_anatop_write_4 sc NULL"));
+
+	bus_write_4(imx6_anatop_sc->res[MEMRES], offset, value);
+}
+
+static void
+vdd_set(struct imx6_anatop_softc *sc, int mv)
+{
+	int newtarg, newtargSoc, oldtarg;
+	uint32_t delay, pmureg;
+	static boolean_t init_done = false;
+
+	/*
+	 * The datasheet says VDD_PU and VDD_SOC must be equal, and VDD_ARM
+	 * can't be more than 50mV above or 200mV below them.  We keep them the
+	 * same except in the case of the lowest operating point, which is
+	 * handled as a special case below.
+	 */
+
+	pmureg = imx6_anatop_read_4(IMX6_ANALOG_PMU_REG_CORE);
+	oldtarg = pmureg & IMX6_ANALOG_PMU_REG0_TARG_MASK;
+
+	/* Convert mV to target value.  Clamp target to valid range. */
+	if (mv < 725)
+		newtarg = 0x00;
+	else if (mv > 1450)
+		newtarg = 0x1F;
+	else
+		newtarg = (mv - 700) / 25;
+
+	/*
+	 * The SOC voltage can't go below 1150mV, and thus because of the 200mV
+	 * rule, the ARM voltage can't go below 950mV.  The 950 is encoded in
+	 * our oppt table, here we handle the SOC 1150 rule as a special case.
+	 * (1150-700/25=18).
+	 */
+	newtargSoc = (newtarg < 18) ? 18 : newtarg;
+
+	/*
+	 * The first time through the 3 voltages might not be equal so use a
+	 * long conservative delay.  After that we need to delay 3uS for every
+	 * 25mV step upward; we actually delay 6uS because empirically, it works
+	 * and the 3uS per step recommended by the docs doesn't (3uS fails when
+	 * going from 400->1200, but works for smaller changes).
+	 */
+	if (init_done) {
+		if (newtarg == oldtarg)
+			return;
+		else if (newtarg > oldtarg)
+			delay = (newtarg - oldtarg) * 6;
+		else
+			delay = 0;
+	} else {
+		delay = (700 / 25) * 6;
+		init_done = true;
+	}
+
+	/*
+	 * Make the change and wait for it to take effect.
+	 */
+	pmureg &= ~(IMX6_ANALOG_PMU_REG0_TARG_MASK |
+	    IMX6_ANALOG_PMU_REG1_TARG_MASK |
+	    IMX6_ANALOG_PMU_REG2_TARG_MASK);
+
+	pmureg |= newtarg << IMX6_ANALOG_PMU_REG0_TARG_SHIFT;
+	pmureg |= newtarg << IMX6_ANALOG_PMU_REG1_TARG_SHIFT;
+	pmureg |= newtargSoc << IMX6_ANALOG_PMU_REG2_TARG_SHIFT;
+
+	imx6_anatop_write_4(IMX6_ANALOG_PMU_REG_CORE, pmureg);
+	DELAY(delay);
+	sc->cpu_curmv = newtarg * 25 + 700;
+}
+
+static inline uint32_t
+cpufreq_mhz_from_div(struct imx6_anatop_softc *sc, uint32_t corediv, 
+    uint32_t plldiv)
+{
+
+	return ((sc->refosc_mhz * (plldiv / 2)) / (corediv + 1));
+}
+
+static inline void
+cpufreq_mhz_to_div(struct imx6_anatop_softc *sc, uint32_t cpu_mhz,
+    uint32_t *corediv, uint32_t *plldiv)
+{
+
+	*corediv = (cpu_mhz < 650) ? 1 : 0;
+	*plldiv = ((*corediv + 1) * cpu_mhz) / (sc->refosc_mhz / 2);
+}
+
+static inline uint32_t
+cpufreq_actual_mhz(struct imx6_anatop_softc *sc, uint32_t cpu_mhz)
+{
+	uint32_t corediv, plldiv;
+
+	cpufreq_mhz_to_div(sc, cpu_mhz, &corediv, &plldiv);
+	return (cpufreq_mhz_from_div(sc, corediv, plldiv));
+}
+
+static struct oppt *
+cpufreq_nearest_oppt(struct imx6_anatop_softc *sc, uint32_t cpu_newmhz)
+{
+	int d, diff, i, nearest;
+
+	if (cpu_newmhz > sc->cpu_maxmhz_hw && !sc->cpu_overclock_enable)
+		cpu_newmhz = sc->cpu_maxmhz_hw;
+
+	diff = INT_MAX;
+	nearest = 0;
+	for (i = 0; i < nitems(imx6_oppt_table); ++i) {
+		d = abs((int)cpu_newmhz - (int)imx6_oppt_table[i].mhz);
+		if (diff > d) {
+			diff = d;
+			nearest = i;
+		}
+	}
+	return (&imx6_oppt_table[nearest]);
+}
+
+static void 
+cpufreq_set_clock(struct imx6_anatop_softc * sc, struct oppt *op)
+{
+	uint32_t corediv, plldiv, timeout, wrk32;
+
+	/* If increasing the frequency, we must first increase the voltage. */
+	if (op->mhz > sc->cpu_curmhz) {
+		vdd_set(sc, op->mv);
+	}
+
+	/*
+	 * I can't find a documented procedure for changing the ARM PLL divisor,
+	 * but some trial and error came up with this:
+	 *  - Set the bypass clock source to REF_CLK_24M (source #0).
+	 *  - Set the PLL into bypass mode; cpu should now be running at 24mhz.
+	 *  - Change the divisor.
+	 *  - Wait for the LOCK bit to come on; it takes ~50 loop iterations.
+	 *  - Turn off bypass mode; cpu should now be running at the new speed.
+	 */
+	cpufreq_mhz_to_div(sc, op->mhz, &corediv, &plldiv);
+	imx6_anatop_write_4(IMX6_ANALOG_CCM_PLL_ARM_CLR, 
+	    IMX6_ANALOG_CCM_PLL_ARM_CLK_SRC_MASK);
+	imx6_anatop_write_4(IMX6_ANALOG_CCM_PLL_ARM_SET, 
+	    IMX6_ANALOG_CCM_PLL_ARM_BYPASS);
+
+	wrk32 = imx6_anatop_read_4(IMX6_ANALOG_CCM_PLL_ARM);
+	wrk32 &= ~IMX6_ANALOG_CCM_PLL_ARM_DIV_MASK;
+	wrk32 |= plldiv;
+	imx6_anatop_write_4(IMX6_ANALOG_CCM_PLL_ARM, wrk32);
+
+	timeout = 10000;
+	while ((imx6_anatop_read_4(IMX6_ANALOG_CCM_PLL_ARM) &
+	    IMX6_ANALOG_CCM_PLL_ARM_LOCK) == 0)
+		if (--timeout == 0)
+			panic("imx6_set_cpu_clock(): PLL never locked");
+
+	imx6_anatop_write_4(IMX6_ANALOG_CCM_PLL_ARM_CLR, 
+	    IMX6_ANALOG_CCM_PLL_ARM_BYPASS);
+	imx_ccm_set_cacrr(corediv);
+
+	/* If lowering the frequency, it is now safe to lower the voltage. */
+	if (op->mhz < sc->cpu_curmhz)
+		vdd_set(sc, op->mv);
+	sc->cpu_curmhz = op->mhz;
+
+	/* Tell the mpcore timer that its frequency has changed. */
+	arm_tmr_change_frequency(
+	    cpufreq_actual_mhz(sc, sc->cpu_curmhz) * 1000000 / 2);
+}
+
+static int
+cpufreq_sysctl_minmhz(SYSCTL_HANDLER_ARGS)
+{
+	struct imx6_anatop_softc *sc;
+	struct oppt * op;
+	uint32_t temp;
+	int err;
+
+	sc = arg1;
+
+	temp = sc->cpu_minmhz;
+	err = sysctl_handle_int(oidp, &temp, 0, req);
+	if (err != 0 || req->newptr == NULL)
+		return (err);
+
+	op = cpufreq_nearest_oppt(sc, temp);
+	if (op->mhz > sc->cpu_maxmhz)
+		return (ERANGE);
+	else if (op->mhz == sc->cpu_minmhz)
+		return (0);
+
+	/*
+	 * Value changed, update softc.  If the new min is higher than the
+	 * current speed, raise the current speed to match.
+	 */
+	sc->cpu_minmhz = op->mhz;
+	if (sc->cpu_minmhz > sc->cpu_curmhz) {
+		cpufreq_set_clock(sc, op);
+	}
+	return (err);
+}
+
+static int
+cpufreq_sysctl_maxmhz(SYSCTL_HANDLER_ARGS)
+{
+	struct imx6_anatop_softc *sc;
+	struct oppt * op;
+	uint32_t temp;
+	int err;
+
+	sc = arg1;
+
+	temp = sc->cpu_maxmhz;
+	err = sysctl_handle_int(oidp, &temp, 0, req);
+	if (err != 0 || req->newptr == NULL)
+		return (err);
+
+	op = cpufreq_nearest_oppt(sc, temp);
+	if (op->mhz < sc->cpu_minmhz)
+		return (ERANGE);
+	else if (op->mhz == sc->cpu_maxmhz)
+		return (0);
+
+	/*
+	 *  Value changed, update softc and hardware.  The hardware update is
+	 *  unconditional.  We always try to run at max speed, so any change of
+	 *  the max means we need to change the current speed too, regardless of
+	 *  whether it is higher or lower than the old max.
+	 */
+	sc->cpu_maxmhz = op->mhz;
+	cpufreq_set_clock(sc, op);
+
+	return (err);
+}
+
+static void
+cpufreq_initialize(struct imx6_anatop_softc *sc)
+{
+	uint32_t cfg3speed;
+	struct oppt * op;
+
+	SYSCTL_ADD_INT(NULL, SYSCTL_STATIC_CHILDREN(_hw_imx),
+	    OID_AUTO, "cpu_mhz", CTLFLAG_RD, &sc->cpu_curmhz, 0, 
+	    "CPU frequency");
+
+	SYSCTL_ADD_PROC(NULL, SYSCTL_STATIC_CHILDREN(_hw_imx), 
+	    OID_AUTO, "cpu_minmhz", CTLTYPE_INT | CTLFLAG_RWTUN, sc, 0,
+	    cpufreq_sysctl_minmhz, "IU", "Minimum CPU frequency");
+
+	SYSCTL_ADD_PROC(NULL, SYSCTL_STATIC_CHILDREN(_hw_imx),
+	    OID_AUTO, "cpu_maxmhz", CTLTYPE_INT | CTLFLAG_RWTUN, sc, 0,
+	    cpufreq_sysctl_maxmhz, "IU", "Maximum CPU frequency");
+
+	SYSCTL_ADD_INT(NULL, SYSCTL_STATIC_CHILDREN(_hw_imx),
+	    OID_AUTO, "cpu_maxmhz_hw", CTLFLAG_RD, &sc->cpu_maxmhz_hw, 0, 
+	    "Maximum CPU frequency allowed by hardware");
+
+	SYSCTL_ADD_INT(NULL, SYSCTL_STATIC_CHILDREN(_hw_imx),
+	    OID_AUTO, "cpu_overclock_enable", CTLFLAG_RWTUN, 
+	    &sc->cpu_overclock_enable, 0, 
+	    "Allow setting CPU frequency higher than cpu_maxmhz_hw");
+
+	/*
+	 * XXX 24mhz shouldn't be hard-coded, should get this from imx6_ccm
+	 * (even though in the real world it will always be 24mhz).  Oh wait a
+	 * sec, I never wrote imx6_ccm.
+	 */
+	sc->refosc_mhz = 24;
+
+	/*
+	 * Get the maximum speed this cpu can be set to.  The values in the
+	 * OCOTP CFG3 register are not documented in the reference manual.
+	 * The following info was in an archived email found via web search:
+	 *   - 2b'11: 1200000000Hz;
+	 *   - 2b'10: 996000000Hz;
+	 *   - 2b'01: 852000000Hz; -- i.MX6Q Only, exclusive with 996MHz.
+	 *   - 2b'00: 792000000Hz;
+	 * The default hardware max speed can be overridden by a tunable.
+	 */
+	cfg3speed = (fsl_ocotp_read_4(FSL_OCOTP_CFG3) & 
+	    FSL_OCOTP_CFG3_SPEED_MASK) >> FSL_OCOTP_CFG3_SPEED_SHIFT;
+	sc->cpu_maxmhz_hw = imx6_ocotp_mhz_tab[cfg3speed];
+	sc->cpu_maxmhz = sc->cpu_maxmhz_hw;
+
+	TUNABLE_INT_FETCH("hw.imx6.cpu_overclock_enable",
+	    &sc->cpu_overclock_enable);
+
+	TUNABLE_INT_FETCH("hw.imx6.cpu_minmhz", &sc->cpu_minmhz);
+	op = cpufreq_nearest_oppt(sc, sc->cpu_minmhz);
+	sc->cpu_minmhz = op->mhz;
+	sc->cpu_minmv = op->mv;
+
+	TUNABLE_INT_FETCH("hw.imx6.cpu_maxmhz", &sc->cpu_maxmhz);
+	op = cpufreq_nearest_oppt(sc, sc->cpu_maxmhz);
+	sc->cpu_maxmhz = op->mhz;
+	sc->cpu_maxmv = op->mv;
+
+	/*
+	 * Set the CPU to maximum speed.
+	 *
+	 * We won't have thermal throttling until interrupts are enabled, but we
+	 * want to run at full speed through all the device init stuff.  This
+	 * basically assumes that a single core can't overheat before interrupts
+	 * are enabled; empirical testing shows that to be a safe assumption.
+	 */
+	cpufreq_set_clock(sc, op);
+}
+
+static inline uint32_t
+temp_from_count(struct imx6_anatop_softc *sc, uint32_t count)
+{
+
+	return (((sc->temp_high_val - (count - sc->temp_high_cnt) *
+	    (sc->temp_high_val - 250) / 
+	    (sc->temp_room_cnt - sc->temp_high_cnt))));
+}
+
+static inline uint32_t
+temp_to_count(struct imx6_anatop_softc *sc, uint32_t temp)
+{
+
+	return ((sc->temp_room_cnt - sc->temp_high_cnt) * 
+	    (sc->temp_high_val - temp) / (sc->temp_high_val - 250) + 
+	    sc->temp_high_cnt);
+}
+
+static void
+temp_update_count(struct imx6_anatop_softc *sc)
+{
+	uint32_t val;
+
+	val = imx6_anatop_read_4(IMX6_ANALOG_TEMPMON_TEMPSENSE0);
+	if (!(val & IMX6_ANALOG_TEMPMON_TEMPSENSE0_VALID))
+		return;
+	sc->temp_last_cnt =
+	    (val & IMX6_ANALOG_TEMPMON_TEMPSENSE0_TEMP_CNT_MASK) >>
+	    IMX6_ANALOG_TEMPMON_TEMPSENSE0_TEMP_CNT_SHIFT;
+}
+
+static int
+temp_sysctl_handler(SYSCTL_HANDLER_ARGS)
+{
+	struct imx6_anatop_softc *sc = arg1;
+	uint32_t t;
+
+	temp_update_count(sc);
+
+	t = temp_from_count(sc, sc->temp_last_cnt) + TZ_ZEROC;
+
+	return (sysctl_handle_int(oidp, &t, 0, req));
+}
+
+static int
+temp_throttle_sysctl_handler(SYSCTL_HANDLER_ARGS)
+{
+	struct imx6_anatop_softc *sc = arg1;
+	int err;
+	uint32_t temp;
+
+	temp = sc->temp_throttle_val + TZ_ZEROC;
+	err = sysctl_handle_int(oidp, &temp, 0, req);
+	if (temp < TZ_ZEROC)
+		return (ERANGE);
+	temp -= TZ_ZEROC;
+	if (err != 0 || req->newptr == NULL || temp == sc->temp_throttle_val)
+		return (err);
+
+	/* Value changed, update counts in softc and hardware. */
+	sc->temp_throttle_val = temp;
+	sc->temp_throttle_trigger_cnt = temp_to_count(sc, sc->temp_throttle_val);
+	sc->temp_throttle_reset_cnt = temp_to_count(sc, sc->temp_throttle_val - 100);
+	imx6_anatop_write_4(IMX6_ANALOG_TEMPMON_TEMPSENSE0_CLR,
+	    IMX6_ANALOG_TEMPMON_TEMPSENSE0_ALARM_MASK);
+	imx6_anatop_write_4(IMX6_ANALOG_TEMPMON_TEMPSENSE0_SET,
+	    (sc->temp_throttle_trigger_cnt <<
+	     IMX6_ANALOG_TEMPMON_TEMPSENSE0_ALARM_SHIFT));
+	return (err);
+}
+
+static void
+tempmon_gofast(struct imx6_anatop_softc *sc)
+{
+
+	if (sc->cpu_curmhz < sc->cpu_maxmhz) {
+		cpufreq_set_clock(sc, cpufreq_nearest_oppt(sc, sc->cpu_maxmhz));
+	}
+}
+
+static void
+tempmon_goslow(struct imx6_anatop_softc *sc)
+{
+
+	if (sc->cpu_curmhz > sc->cpu_minmhz) {
+		cpufreq_set_clock(sc, cpufreq_nearest_oppt(sc, sc->cpu_minmhz));
+	}
+}
+
+static int
+tempmon_intr(void *arg)
+{
+	struct imx6_anatop_softc *sc = arg;
+
+	/*
+	 * XXX Note that this code doesn't currently run (for some mysterious
+	 * reason we just never get an interrupt), so the real monitoring is
+	 * done by tempmon_throttle_check().
+	 */
+	tempmon_goslow(sc);
+	/* XXX Schedule callout to speed back up eventually. */
+	return (FILTER_HANDLED);
+}
+
+static void
+tempmon_throttle_check(void *arg)
+{
+	struct imx6_anatop_softc *sc = arg;
+
+	/* Lower counts are higher temperatures. */
+	if (sc->temp_last_cnt < sc->temp_throttle_trigger_cnt)
+		tempmon_goslow(sc);
+	else if (sc->temp_last_cnt > (sc->temp_throttle_reset_cnt))
+		tempmon_gofast(sc);
+
+	callout_reset_sbt(&sc->temp_throttle_callout, sc->temp_throttle_delay,
+		0, tempmon_throttle_check, sc, 0);
+
+}
+
+static void
+initialize_tempmon(struct imx6_anatop_softc *sc)
+{
+	uint32_t cal;
+
+	/*
+	 * Fetch calibration data: a sensor count at room temperature (25C),
+	 * a sensor count at a high temperature, and that temperature
+	 */
+	cal = fsl_ocotp_read_4(FSL_OCOTP_ANA1);
+	sc->temp_room_cnt = (cal & 0xFFF00000) >> 20;
+	sc->temp_high_cnt = (cal & 0x000FFF00) >> 8;
+	sc->temp_high_val = (cal & 0x000000FF) * 10;
+
+	/*
+	 * Throttle to a lower cpu freq at 10C below the "hot" temperature, and
+	 * reset back to max cpu freq at 5C below the trigger.
+	 */
+	sc->temp_throttle_val = sc->temp_high_val - 100;
+	sc->temp_throttle_trigger_cnt =
+	    temp_to_count(sc, sc->temp_throttle_val);
+	sc->temp_throttle_reset_cnt = 
+	    temp_to_count(sc, sc->temp_throttle_val - 50);
+
+	/*
+	 * Set the sensor to sample automatically at 16Hz (32.768KHz/0x800), set
+	 * the throttle count, and begin making measurements.
+	 */
+	imx6_anatop_write_4(IMX6_ANALOG_TEMPMON_TEMPSENSE1, 0x0800);
+	imx6_anatop_write_4(IMX6_ANALOG_TEMPMON_TEMPSENSE0,
+	    (sc->temp_throttle_trigger_cnt << 
+	    IMX6_ANALOG_TEMPMON_TEMPSENSE0_ALARM_SHIFT) |
+	    IMX6_ANALOG_TEMPMON_TEMPSENSE0_MEASURE);
+
+	/*
+	 * XXX Note that the alarm-interrupt feature isn't working yet, so
+	 * we'll use a callout handler to check at 10Hz.  Make sure we have an
+	 * initial temperature reading before starting up the callouts so we
+	 * don't get a bogus reading of zero.
+	 */
+	while (sc->temp_last_cnt == 0)
+		temp_update_count(sc);
+	sc->temp_throttle_delay = 100 * SBT_1MS;
+	callout_init(&sc->temp_throttle_callout, 0);
+	callout_reset_sbt(&sc->temp_throttle_callout, sc->temp_throttle_delay, 
+	    0, tempmon_throttle_check, sc, 0);
+
+	SYSCTL_ADD_PROC(NULL, SYSCTL_STATIC_CHILDREN(_hw_imx), 
+	    OID_AUTO, "temperature", CTLTYPE_INT | CTLFLAG_RD, sc, 0,
+	    temp_sysctl_handler, "IK", "Current die temperature");
+	SYSCTL_ADD_PROC(NULL, SYSCTL_STATIC_CHILDREN(_hw_imx), 
+	    OID_AUTO, "throttle_temperature", CTLTYPE_INT | CTLFLAG_RW, sc,
+	    0, temp_throttle_sysctl_handler, "IK", 
+	    "Throttle CPU when exceeding this temperature");
+}
+
+static void
+intr_setup(void *arg)
+{
+	struct imx6_anatop_softc *sc;
+
+	sc = arg;
+	bus_setup_intr(sc->dev, sc->res[IRQRES], INTR_TYPE_MISC | INTR_MPSAFE,
+	    tempmon_intr, NULL, sc, &sc->temp_intrhand);
+	config_intrhook_disestablish(&sc->intr_setup_hook);
+}
+
+static void
+imx6_anatop_new_pass(device_t dev)
+{
+	struct imx6_anatop_softc *sc;
+	const int cpu_init_pass = BUS_PASS_CPU + BUS_PASS_ORDER_MIDDLE;
+
+	/*
+	 * We attach during BUS_PASS_BUS (because some day we will be a
+	 * simplebus that has regulator devices as children), but some of our
+	 * init work cannot be done until BUS_PASS_CPU (we rely on other devices
+	 * that attach on the CPU pass).
+	 */
+	sc = device_get_softc(dev);
+	if (!sc->cpu_init_done && bus_current_pass >= cpu_init_pass) {
+		sc->cpu_init_done = true;
+		cpufreq_initialize(sc);
+		initialize_tempmon(sc);
+		if (bootverbose) {
+			device_printf(sc->dev, "CPU %uMHz @ %umV\n", 
+			    sc->cpu_curmhz, sc->cpu_curmv);
+		}
+	}
+	bus_generic_new_pass(dev);
+}
+
+static int
+imx6_anatop_detach(device_t dev)
+{
+
+	/* This device can never detach. */
+	return (EBUSY);
+}
+
+static int
+imx6_anatop_attach(device_t dev)
+{
+	struct imx6_anatop_softc *sc;
+	int err;
+
+	sc = device_get_softc(dev);
+	sc->dev = dev;
+
+	/* Allocate bus_space resources. */
+	if (bus_alloc_resources(dev, imx6_anatop_spec, sc->res)) {
+		device_printf(dev, "Cannot allocate resources\n");
+		err = ENXIO;
+		goto out;
+	}
+
+	sc->intr_setup_hook.ich_func = intr_setup;
+	sc->intr_setup_hook.ich_arg = sc;
+	config_intrhook_establish(&sc->intr_setup_hook);
+
+	SYSCTL_ADD_UINT(device_get_sysctl_ctx(sc->dev),
+	    SYSCTL_CHILDREN(device_get_sysctl_tree(sc->dev)),
+	    OID_AUTO, "cpu_voltage", CTLFLAG_RD,
+	    &sc->cpu_curmv, 0, "Current CPU voltage in millivolts");
+
+	imx6_anatop_sc = sc;
+
+	/*
+	 * Other code seen on the net sets this SELFBIASOFF flag around the same
+	 * time the temperature sensor is set up, although it's unclear how the
+	 * two are related (if at all).
+	 */
+	imx6_anatop_write_4(IMX6_ANALOG_PMU_MISC0_SET, 
+	    IMX6_ANALOG_PMU_MISC0_SELFBIASOFF);
+
+	/*
+	 * Some day, when we're ready to deal with the actual anatop regulators
+	 * that are described in fdt data as children of this "bus", this would
+	 * be the place to invoke a simplebus helper routine to instantiate the
+	 * children from the fdt data.
+	 */
+
+	err = 0;
+
+out:
+
+	if (err != 0) {
+		bus_release_resources(dev, imx6_anatop_spec, sc->res);
+	}
+
+	return (err);
+}
+
+uint32_t
+pll4_configure_output(uint32_t mfi, uint32_t mfn, uint32_t mfd)
+{
+	int reg;
+
+	/*
+	 * Audio PLL (PLL4).
+	 * PLL output frequency = Fref * (DIV_SELECT + NUM/DENOM)
+	 */
+
+	reg = (IMX6_ANALOG_CCM_PLL_AUDIO_ENABLE);
+	reg &= ~(IMX6_ANALOG_CCM_PLL_AUDIO_DIV_SELECT_MASK << \
+		IMX6_ANALOG_CCM_PLL_AUDIO_DIV_SELECT_SHIFT);
+	reg |= (mfi << IMX6_ANALOG_CCM_PLL_AUDIO_DIV_SELECT_SHIFT);
+	imx6_anatop_write_4(IMX6_ANALOG_CCM_PLL_AUDIO, reg);
+	imx6_anatop_write_4(IMX6_ANALOG_CCM_PLL_AUDIO_NUM, mfn);
+	imx6_anatop_write_4(IMX6_ANALOG_CCM_PLL_AUDIO_DENOM, mfd);
+
+	return (0);
+}
+
+static int
+imx6_anatop_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (ofw_bus_is_compatible(dev, "fsl,imx6q-anatop") == 0)
+		return (ENXIO);
+
+	device_set_desc(dev, "Freescale i.MX6 Analog PLLs and Power");
+
+	return (BUS_PROBE_DEFAULT);
+}
+
+uint32_t 
+imx6_get_cpu_clock()
+{
+	uint32_t corediv, plldiv;
+
+	corediv = imx_ccm_get_cacrr();
+	plldiv = imx6_anatop_read_4(IMX6_ANALOG_CCM_PLL_ARM) &
+	    IMX6_ANALOG_CCM_PLL_ARM_DIV_MASK;
+	return (cpufreq_mhz_from_div(imx6_anatop_sc, corediv, plldiv));
+}
+
+static device_method_t imx6_anatop_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,  imx6_anatop_probe),
+	DEVMETHOD(device_attach, imx6_anatop_attach),
+	DEVMETHOD(device_detach, imx6_anatop_detach),
+
+	/* Bus interface */
+	DEVMETHOD(bus_new_pass,  imx6_anatop_new_pass),
+
+	DEVMETHOD_END
+};
+
+static driver_t imx6_anatop_driver = {
+	"imx6_anatop",
+	imx6_anatop_methods,
+	sizeof(struct imx6_anatop_softc)
+};
+
+static devclass_t imx6_anatop_devclass;
+
+EARLY_DRIVER_MODULE(imx6_anatop, simplebus, imx6_anatop_driver,
+    imx6_anatop_devclass, 0, 0, BUS_PASS_BUS + BUS_PASS_ORDER_MIDDLE);
+EARLY_DRIVER_MODULE(imx6_anatop, ofwbus, imx6_anatop_driver,
+    imx6_anatop_devclass, 0, 0, BUS_PASS_BUS + BUS_PASS_ORDER_MIDDLE);
+


Property changes on: trunk/sys/arm/freescale/imx/imx6_anatop.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/imx/imx6_anatopreg.h
===================================================================
--- trunk/sys/arm/freescale/imx/imx6_anatopreg.h	                        (rev 0)
+++ trunk/sys/arm/freescale/imx/imx6_anatopreg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,192 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Ian Lepore <ian at freebsd.org>
+ * 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: stable/10/sys/arm/freescale/imx/imx6_anatopreg.h 283500 2015-05-24 18:59:45Z ian $
+ */
+
+#ifndef	IMX6_ANATOPREG_H
+#define	IMX6_ANATOPREG_H
+
+#define	IMX6_ANALOG_CCM_PLL_ARM				0x000
+#define	IMX6_ANALOG_CCM_PLL_ARM_SET			0x004
+#define	IMX6_ANALOG_CCM_PLL_ARM_CLR			0x008
+#define	IMX6_ANALOG_CCM_PLL_ARM_TOG			0x00C
+#define	  IMX6_ANALOG_CCM_PLL_ARM_DIV_MASK		  0x7F
+#define	  IMX6_ANALOG_CCM_PLL_ARM_LOCK			  (1U << 31)
+#define	  IMX6_ANALOG_CCM_PLL_ARM_BYPASS		  (1 << 16)
+#define	  IMX6_ANALOG_CCM_PLL_ARM_CLK_SRC_MASK		  (0x03 << 16)
+#define	IMX6_ANALOG_CCM_PLL_USB1			0x010
+#define	IMX6_ANALOG_CCM_PLL_USB1_SET			0x014
+#define	IMX6_ANALOG_CCM_PLL_USB1_CLR			0x018
+#define	IMX6_ANALOG_CCM_PLL_USB1_TOG			0x01C
+#define	   IMX6_ANALOG_CCM_PLL_USB_LOCK			  (1U << 31)
+#define	   IMX6_ANALOG_CCM_PLL_USB_BYPASS		  (1 << 16)
+#define	   IMX6_ANALOG_CCM_PLL_USB_ENABLE		  (1 << 13)
+#define	   IMX6_ANALOG_CCM_PLL_USB_POWER		  (1 << 12)
+#define	   IMX6_ANALOG_CCM_PLL_USB_EN_USB_CLKS		  (1 <<  6)
+#define	IMX6_ANALOG_CCM_PLL_USB2			0x020
+#define	IMX6_ANALOG_CCM_PLL_USB2_SET			0x024
+#define	IMX6_ANALOG_CCM_PLL_USB2_CLR			0x028
+#define	IMX6_ANALOG_CCM_PLL_USB2_TOG			0x02C
+#define	IMX6_ANALOG_CCM_PLL_SYS				0x030
+#define	IMX6_ANALOG_CCM_PLL_SYS_SET			0x034
+#define	IMX6_ANALOG_CCM_PLL_SYS_CLR			0x038
+#define	IMX6_ANALOG_CCM_PLL_SYS_TOG			0x03C
+#define	IMX6_ANALOG_CCM_PLL_SYS_SS			0x040
+#define	IMX6_ANALOG_CCM_PLL_SYS_NUM			0x050
+#define	IMX6_ANALOG_CCM_PLL_SYS_DENOM			0x060
+#define	IMX6_ANALOG_CCM_PLL_AUDIO			0x070
+#define	   IMX6_ANALOG_CCM_PLL_AUDIO_ENABLE		  (1 << 13)
+#define	   IMX6_ANALOG_CCM_PLL_AUDIO_DIV_SELECT_SHIFT	  0
+#define	   IMX6_ANALOG_CCM_PLL_AUDIO_DIV_SELECT_MASK	  0x7f
+#define	IMX6_ANALOG_CCM_PLL_AUDIO_SET			0x074
+#define	IMX6_ANALOG_CCM_PLL_AUDIO_CLR			0x078
+#define	IMX6_ANALOG_CCM_PLL_AUDIO_TOG			0x07C
+#define	IMX6_ANALOG_CCM_PLL_AUDIO_NUM			0x080
+#define	IMX6_ANALOG_CCM_PLL_AUDIO_DENOM			0x090
+#define	IMX6_ANALOG_CCM_PLL_VIDEO			0x0A0
+#define	IMX6_ANALOG_CCM_PLL_VIDEO_SET			0x0A4
+#define	IMX6_ANALOG_CCM_PLL_VIDEO_CLR			0x0A8
+#define	IMX6_ANALOG_CCM_PLL_VIDEO_TOG			0x0AC
+#define	IMX6_ANALOG_CCM_PLL_VIDEO_NUM			0x0B0
+#define	IMX6_ANALOG_CCM_PLL_VIDEO_DENOM			0x0C0
+#define	IMX6_ANALOG_CCM_PLL_MLB				0x0D0
+#define	IMX6_ANALOG_CCM_PLL_MLB_SET			0x0D4
+#define	IMX6_ANALOG_CCM_PLL_MLB_CLR			0x0D8
+#define	IMX6_ANALOG_CCM_PLL_MLB_TOG			0x0DC
+#define	IMX6_ANALOG_CCM_PLL_ENET			0x0E0
+#define	IMX6_ANALOG_CCM_PLL_ENET_SET			0x0E4
+#define	IMX6_ANALOG_CCM_PLL_ENET_CLR			0x0E8
+#define	IMX6_ANALOG_CCM_PLL_ENET_TOG			0x0EC
+#define	IMX6_ANALOG_CCM_PFD_480				0x0F0
+#define	IMX6_ANALOG_CCM_PFD_480_SET			0x0F4
+#define	IMX6_ANALOG_CCM_PFD_480_CLR			0x0F8
+#define	IMX6_ANALOG_CCM_PFD_480_TOG			0x0FC
+#define	IMX6_ANALOG_CCM_PFD_528				0x100
+#define	IMX6_ANALOG_CCM_PFD_528_SET			0x104
+#define	IMX6_ANALOG_CCM_PFD_528_CLR			0x108
+#define	IMX6_ANALOG_CCM_PFD_528_TOG			0x10C
+
+#define	IMX6_ANALOG_PMU_REG_CORE			0x140
+#define	  IMX6_ANALOG_PMU_REG2_TARG_SHIFT		  18
+#define	  IMX6_ANALOG_PMU_REG2_TARG_MASK		   \
+    (0x1f << IMX6_ANALOG_PMU_REG2_TARG_SHIFT)
+#define	  IMX6_ANALOG_PMU_REG1_TARG_SHIFT		   9
+#define	  IMX6_ANALOG_PMU_REG1_TARG_MASK		   \
+    (0x1f << IMX6_ANALOG_PMU_REG1_TARG_SHIFT)
+#define	  IMX6_ANALOG_PMU_REG0_TARG_SHIFT		   0
+#define	  IMX6_ANALOG_PMU_REG0_TARG_MASK		   \
+    (0x1f << IMX6_ANALOG_PMU_REG0_TARG_SHIFT)
+
+#define	IMX6_ANALOG_PMU_MISC0				0x150
+#define	IMX6_ANALOG_PMU_MISC0_SET			0x154
+#define	IMX6_ANALOG_PMU_MISC0_CLR			0x158
+#define	IMX6_ANALOG_PMU_MISC0_TOG			0x15C
+#define	  IMX6_ANALOG_PMU_MISC0_SELFBIASOFF		  (1 << 3)
+
+#define	IMX6_ANALOG_PMU_MISC1				0x160
+#define	IMX6_ANALOG_PMU_MISC1_SET			0x164
+#define	IMX6_ANALOG_PMU_MISC1_CLR			0x168
+#define	IMX6_ANALOG_PMU_MISC1_TOG			0x16C
+#define	  IMX6_ANALOG_PMU_MISC1_IRQ_TEMPSENSE		  (1 << 29)
+
+#define	IMX6_ANALOG_PMU_MISC2				0x170
+#define	IMX6_ANALOG_PMU_MISC2_SET			0x174
+#define	IMX6_ANALOG_PMU_MISC2_CLR			0x178
+#define	IMX6_ANALOG_PMU_MISC2_TOG			0x17C
+
+/*
+ * Note that the ANALOG_CCM_MISCn registers are the same as the PMU_MISCn
+ * registers; some bits conceptually belong to the PMU and some to the CCM.
+ */
+#define	IMX6_ANALOG_CCM_MISC0				IMX6_ANALOG_PMU_MISC0
+#define	IMX6_ANALOG_CCM_MISC0_SET			IMX6_ANALOG_PMU_MISC0_SET
+#define	IMX6_ANALOG_CCM_MISC0_CLR			IMX6_ANALOG_PMU_MISC0_CLR
+#define	IMX6_ANALOG_CCM_MISC0_TOG			IMX6_ANALOG_PMU_MISC0_TOG
+
+#define	IMX6_ANALOG_CCM_MISC2				IMX6_ANALOG_PMU_MISC2
+#define	IMX6_ANALOG_CCM_MISC2_SET			IMX6_ANALOG_PMU_MISC2_SET
+#define	IMX6_ANALOG_CCM_MISC2_CLR			IMX6_ANALOG_PMU_MISC2_CLR
+#define	IMX6_ANALOG_CCM_MISC2_TOG			IMX6_ANALOG_PMU_MISC2_TOG
+
+#define	IMX6_ANALOG_TEMPMON_TEMPSENSE0			0x180
+#define	IMX6_ANALOG_TEMPMON_TEMPSENSE0_SET		0x184
+#define	IMX6_ANALOG_TEMPMON_TEMPSENSE0_CLR		0x188
+#define	IMX6_ANALOG_TEMPMON_TEMPSENSE0_TOG		0x18C
+#define	IMX6_ANALOG_TEMPMON_TEMPSENSE0_TOG		0x18C
+#define	  IMX6_ANALOG_TEMPMON_TEMPSENSE0_ALARM_SHIFT	 20
+#define	  IMX6_ANALOG_TEMPMON_TEMPSENSE0_ALARM_MASK	  \
+    (0xfff << IMX6_ANALOG_TEMPMON_TEMPSENSE0_ALARM_SHIFT)
+#define	  IMX6_ANALOG_TEMPMON_TEMPSENSE0_TEMP_CNT_SHIFT	  8
+#define	  IMX6_ANALOG_TEMPMON_TEMPSENSE0_TEMP_CNT_MASK	  \
+    (0xfff << IMX6_ANALOG_TEMPMON_TEMPSENSE0_TEMP_CNT_SHIFT)
+#define	  IMX6_ANALOG_TEMPMON_TEMPSENSE0_VALID		0x4
+#define	  IMX6_ANALOG_TEMPMON_TEMPSENSE0_MEASURE	0x2
+#define	  IMX6_ANALOG_TEMPMON_TEMPSENSE0_POWER_DOWN	0x1
+
+#define	IMX6_ANALOG_TEMPMON_TEMPSENSE1			0x190
+#define	IMX6_ANALOG_TEMPMON_TEMPSENSE1_SET		0x194
+#define	IMX6_ANALOG_TEMPMON_TEMPSENSE1_CLR		0x198
+#define	IMX6_ANALOG_TEMPMON_TEMPSENSE1_TOG		0x19C
+
+#define	IMX6_ANALOG_USB1_VBUS_DETECT			0x1A0
+#define	IMX6_ANALOG_USB1_VBUS_DETECT_SET		0x1A4
+#define	IMX6_ANALOG_USB1_VBUS_DETECT_CLR		0x1A8
+#define	IMX6_ANALOG_USB1_VBUS_DETECT_TOG		0x1AC
+#define	IMX6_ANALOG_USB1_CHRG_DETECT			0x1B0
+#define	IMX6_ANALOG_USB1_CHRG_DETECT_SET		0x1B4
+#define	IMX6_ANALOG_USB1_CHRG_DETECT_CLR		0x1B8
+#define	IMX6_ANALOG_USB1_CHRG_DETECT_TOG		0x1BC
+#define	  IMX6_ANALOG_USB_CHRG_DETECT_N_ENABLE		  (1 << 20) /* EN_B */
+#define	  IMX6_ANALOG_USB_CHRG_DETECT_N_CHK_CHRG	  (1 << 19) /* CHK_CHRG_B */
+#define	  IMX6_ANALOG_USB_CHRG_DETECT_CHK_CONTACT	  (1 << 18)
+#define	IMX6_ANALOG_USB1_VBUS_DETECT_STAT		0x1C0
+#define	IMX6_ANALOG_USB1_CHRG_DETECT_STAT		0x1D0
+#define	IMX6_ANALOG_USB1_MISC				0x1F0
+#define	IMX6_ANALOG_USB1_MISC_SET			0x1F4
+#define	IMX6_ANALOG_USB1_MISC_CLR			0x1F8
+#define	IMX6_ANALOG_USB1_MISC_TOG			0x1FC
+#define	IMX6_ANALOG_USB2_VBUS_DETECT			0x200
+#define	IMX6_ANALOG_USB2_VBUS_DETECT_SET		0x204
+#define	IMX6_ANALOG_USB2_VBUS_DETECT_CLR		0x208
+#define	IMX6_ANALOG_USB2_VBUS_DETECT_TOG		0x20C
+#define	IMX6_ANALOG_USB2_CHRG_DETECT			0x210
+#define	IMX6_ANALOG_USB2_CHRG_DETECT_SET		0x214
+#define	IMX6_ANALOG_USB2_CHRG_DETECT_CLR		0x218
+#define	IMX6_ANALOG_USB2_CHRG_DETECT_TOG		0x21C
+#define	IMX6_ANALOG_USB2_VBUS_DETECT_STAT		0x220
+#define	IMX6_ANALOG_USB2_CHRG_DETECT_STAT		0x230
+#define	IMX6_ANALOG_USB2_MISC				0x250
+#define	IMX6_ANALOG_USB2_MISC_SET			0x254
+#define	IMX6_ANALOG_USB2_MISC_CLR			0x258
+#define	IMX6_ANALOG_USB2_MISC_TOG			0x25C
+#define	IMX6_ANALOG_DIGPROG				0x260
+#define	IMX6_ANALOG_DIGPROG_SL				0x280
+#define	  IMX6_ANALOG_DIGPROG_SOCTYPE_SHIFT		  16
+#define	  IMX6_ANALOG_DIGPROG_SOCTYPE_MASK		  \
+    (0xff << IMX6_ANALOG_DIGPROG_SOCTYPE_SHIFT)
+
+#endif


Property changes on: trunk/sys/arm/freescale/imx/imx6_anatopreg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/imx/imx6_anatopvar.h
===================================================================
--- trunk/sys/arm/freescale/imx/imx6_anatopvar.h	                        (rev 0)
+++ trunk/sys/arm/freescale/imx/imx6_anatopvar.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,48 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Ian Lepore <ian at freebsd.org>
+ * 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: stable/10/sys/arm/freescale/imx/imx6_anatopvar.h 283500 2015-05-24 18:59:45Z ian $
+ */
+
+#ifndef	IMX6_ANATOPVAR_H
+#define	IMX6_ANATOPVAR_H
+
+/*
+ * All registers controlling various analog aspects of the SoC (such as PLLs or
+ * voltage regulators or USB VBUS detection) are gathered together under the
+ * anatop device (because of newbus hierarchical resource management), but other
+ * drivers such as CMM or USBPHY need access to these registers.  These
+ * functions let them have at the hardware directly.  No effort is made by these
+ * functions to mediate concurrent access.
+ */
+uint32_t imx6_anatop_read_4(bus_size_t _offset);
+void imx6_anatop_write_4(bus_size_t _offset, uint32_t _value);
+
+uint32_t imx6_get_cpu_clock(void);
+
+uint32_t pll4_configure_output(uint32_t mfi, uint32_t mfn, uint32_t mfd);
+
+#endif


Property changes on: trunk/sys/arm/freescale/imx/imx6_anatopvar.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/imx/imx6_audmux.c
===================================================================
--- trunk/sys/arm/freescale/imx/imx6_audmux.c	                        (rev 0)
+++ trunk/sys/arm/freescale/imx/imx6_audmux.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,160 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2015 Ruslan Bukin <br at bsdpad.com>
+ * 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.
+ */
+
+/*
+ * i.MX6 Digital Audio Multiplexer (AUDMUX)
+ * Chapter 16, i.MX 6Dual/6Quad Applications Processor Reference Manual,
+ * Rev. 1, 04/2013
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/freescale/imx/imx6_audmux.c 283500 2015-05-24 18:59:45Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/endian.h>
+#include <sys/rman.h>
+#include <sys/timeet.h>
+#include <sys/timetc.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#define	READ4(_sc, _reg)	\
+	bus_space_read_4(_sc->bst, _sc->bsh, _reg)
+#define	WRITE4(_sc, _reg, _val)	\
+	bus_space_write_4(_sc->bst, _sc->bsh, _reg, _val)
+
+#define	AUDMUX_PTCR(n)	(0x8 * (n - 1))	/* Port Timing Control Register */
+#define	 PTCR_TFS_DIR	(1 << 31)	/* Transmit Frame Sync Direction Control */
+#define	 PTCR_TFSEL_S	27		/* Transmit Frame Sync Select */
+#define	 PTCR_TFSEL_M	0xf
+#define	 PTCR_TCLKDIR	(1 << 26)	/* Transmit Clock Direction Control */
+#define	 PTCR_TCSEL_S	22		/* Transmit Clock Select. */
+#define	 PTCR_TCSEL_M	0xf
+#define	 PTCR_RFS_DIR	(1 << 21)	/* Receive Frame Sync Direction Control */
+#define	 PTCR_SYN	(1 << 11)
+#define	AUDMUX_PDCR(n)	(0x8 * (n - 1) + 0x4)	/* Port Data Control Reg */
+#define	 PDCR_RXDSEL_S		13	/* Receive Data Select */
+#define	 PDCR_RXDSEL_M		0x3
+#define	 PDCR_RXDSEL_PORT(n)	(n - 1)
+
+struct audmux_softc {
+	struct resource		*res[1];
+	bus_space_tag_t		bst;
+	bus_space_handle_t	bsh;
+	void			*ih;
+};
+
+static struct resource_spec audmux_spec[] = {
+	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
+	{ -1, 0 }
+};
+
+static int
+audmux_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "fsl,imx6q-audmux"))
+		return (ENXIO);
+
+	device_set_desc(dev, "i.MX6 Digital Audio Multiplexer");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+audmux_configure(struct audmux_softc *sc,
+	int ssi_port, int audmux_port)
+{
+	uint32_t reg;
+
+	/* Direction: output */
+	reg = (PTCR_TFS_DIR | PTCR_TCLKDIR | PTCR_SYN);
+	WRITE4(sc, AUDMUX_PTCR(audmux_port), reg);
+
+	/* Select source */
+	reg = (PDCR_RXDSEL_PORT(ssi_port) << PDCR_RXDSEL_S);
+	WRITE4(sc, AUDMUX_PDCR(audmux_port), reg);
+
+	return (0);
+}
+
+static int
+audmux_attach(device_t dev)
+{
+	struct audmux_softc *sc;
+
+	sc = device_get_softc(dev);
+
+	if (bus_alloc_resources(dev, audmux_spec, sc->res)) {
+		device_printf(dev, "could not allocate resources\n");
+		return (ENXIO);
+	}
+
+	/* Memory interface */
+	sc->bst = rman_get_bustag(sc->res[0]);
+	sc->bsh = rman_get_bushandle(sc->res[0]);
+
+	/*
+	 * Direct SSI1 output to AUDMUX5 pins.
+	 * TODO: dehardcore this.
+	 */
+	audmux_configure(sc, 1, 5);
+
+	return (0);
+};
+
+static device_method_t audmux_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		audmux_probe),
+	DEVMETHOD(device_attach,	audmux_attach),
+	{ 0, 0 }
+};
+
+static driver_t audmux_driver = {
+	"audmux",
+	audmux_methods,
+	sizeof(struct audmux_softc),
+};
+
+static devclass_t audmux_devclass;
+
+DRIVER_MODULE(audmux, simplebus, audmux_driver, audmux_devclass, 0, 0);


Property changes on: trunk/sys/arm/freescale/imx/imx6_audmux.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/imx/imx6_ccm.c
===================================================================
--- trunk/sys/arm/freescale/imx/imx6_ccm.c	                        (rev 0)
+++ trunk/sys/arm/freescale/imx/imx6_ccm.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,357 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Ian Lepore <ian at freebsd.org>
+ * 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: stable/10/sys/arm/freescale/imx/imx6_ccm.c 283501 2015-05-24 19:00:46Z ian $");
+
+/*
+ * Clocks and power control driver for Freescale i.MX6 family of SoCs.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/rman.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+
+#include <arm/freescale/imx/imx6_anatopreg.h>
+#include <arm/freescale/imx/imx6_anatopvar.h>
+#include <arm/freescale/imx/imx6_ccmreg.h>
+#include <arm/freescale/imx/imx_machdep.h>
+#include <arm/freescale/imx/imx_ccmvar.h>
+
+#ifndef CCGR_CLK_MODE_ALWAYS
+#define	CCGR_CLK_MODE_OFF		0
+#define	CCGR_CLK_MODE_RUNMODE		1
+#define	CCGR_CLK_MODE_ALWAYS		3
+#endif
+
+struct ccm_softc {
+	device_t	dev;
+	struct resource	*mem_res;
+};
+
+static struct ccm_softc *ccm_sc;
+
+static inline uint32_t
+RD4(struct ccm_softc *sc, bus_size_t off)
+{
+
+	return (bus_read_4(sc->mem_res, off));
+}
+
+static inline void
+WR4(struct ccm_softc *sc, bus_size_t off, uint32_t val)
+{
+
+	bus_write_4(sc->mem_res, off, val);
+}
+
+/*
+ * Until we have a fully functional ccm driver which implements the fdt_clock
+ * interface, use the age-old workaround of unconditionally enabling the clocks
+ * for devices we might need to use.  The SoC defaults to most clocks enabled,
+ * but the rom boot code and u-boot disable a few of them.  We turn on only
+ * what's needed to run the chip plus devices we have drivers for, and turn off
+ * devices we don't yet have drivers for.  (Note that USB is not turned on here
+ * because that is one we do when the driver asks for it.)
+ */
+static void
+ccm_init_gates(struct ccm_softc *sc)
+{
+                                        /* Turns on... */
+	WR4(sc, CCM_CCGR0, 0x0000003f); /* ahpbdma, aipstz 1 & 2 busses */
+	WR4(sc, CCM_CCGR1, 0x00300c00); /* gpt, enet */
+	WR4(sc, CCM_CCGR2, 0x0fffffc0); /* ipmux & ipsync (bridges), iomux, i2c */
+	WR4(sc, CCM_CCGR3, 0x3ff00000); /* DDR memory controller */
+	WR4(sc, CCM_CCGR4, 0x0000f300); /* pl301 bus crossbar */
+	WR4(sc, CCM_CCGR5, 0x0ffc00c0); /* uarts, ssi, sdma */
+	WR4(sc, CCM_CCGR6, 0x000000ff); /* usdhc 1-4 */
+}
+
+static int
+ccm_detach(device_t dev)
+{
+	struct ccm_softc *sc;
+
+	sc = device_get_softc(dev);
+
+	if (sc->mem_res != NULL)
+		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->mem_res);
+
+	return (0);
+}
+
+static int
+ccm_attach(device_t dev)
+{
+	struct ccm_softc *sc;
+	int err, rid;
+	uint32_t reg;
+
+	sc = device_get_softc(dev);
+	err = 0;
+
+	/* Allocate bus_space resources. */
+	rid = 0;
+	sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	    RF_ACTIVE);
+	if (sc->mem_res == NULL) {
+		device_printf(dev, "Cannot allocate memory resources\n");
+		err = ENXIO;
+		goto out;
+	}
+
+	ccm_sc = sc;
+
+	/*
+	 * Configure the Low Power Mode setting to leave the ARM core power on
+	 * when a WFI instruction is executed.  This lets the MPCore timers and
+	 * GIC continue to run, which is helpful when the only thing that can
+	 * wake you up is an MPCore Private Timer interrupt delivered via GIC.
+	 *
+	 * XXX Based on the docs, setting CCM_CGPR_INT_MEM_CLK_LPM shouldn't be
+	 * required when the LPM bits are set to LPM_RUN.  But experimentally
+	 * I've experienced a fairly rare lockup when not setting it.  I was
+	 * unable to prove conclusively that the lockup was related to power
+	 * management or that this definitively fixes it.  Revisit this.
+	 */
+	reg = RD4(sc, CCM_CGPR);
+	reg |= CCM_CGPR_INT_MEM_CLK_LPM;
+	WR4(sc, CCM_CGPR, reg);
+	reg = RD4(sc, CCM_CLPCR);
+	reg = (reg & ~CCM_CLPCR_LPM_MASK) | CCM_CLPCR_LPM_RUN;
+	WR4(sc, CCM_CLPCR, reg);
+
+	ccm_init_gates(sc);
+
+	err = 0;
+
+out:
+
+	if (err != 0)
+		ccm_detach(dev);
+
+	return (err);
+}
+
+static int
+ccm_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+        if (ofw_bus_is_compatible(dev, "fsl,imx6q-ccm") == 0)
+		return (ENXIO);
+
+	device_set_desc(dev, "Freescale i.MX6 Clock Control Module");
+
+	return (BUS_PROBE_DEFAULT);
+}
+
+void
+imx_ccm_ssi_configure(device_t _ssidev)
+{
+	struct ccm_softc *sc;
+	uint32_t reg;
+
+	sc = ccm_sc;
+
+	/*
+	 * Select PLL4 (Audio PLL) clock multiplexer as source.
+	 * PLL output frequency = Fref * (DIV_SELECT + NUM/DENOM).
+	 */
+
+	reg = RD4(sc, CCM_CSCMR1);
+	reg &= ~(SSI_CLK_SEL_M << SSI1_CLK_SEL_S);
+	reg |= (SSI_CLK_SEL_PLL4 << SSI1_CLK_SEL_S);
+	reg &= ~(SSI_CLK_SEL_M << SSI2_CLK_SEL_S);
+	reg |= (SSI_CLK_SEL_PLL4 << SSI2_CLK_SEL_S);
+	reg &= ~(SSI_CLK_SEL_M << SSI3_CLK_SEL_S);
+	reg |= (SSI_CLK_SEL_PLL4 << SSI3_CLK_SEL_S);
+	WR4(sc, CCM_CSCMR1, reg);
+
+	/*
+	 * Ensure we have set hardware-default values
+	 * for pre and post dividers.
+	 */
+
+	/* SSI1 and SSI3 */
+	reg = RD4(sc, CCM_CS1CDR);
+	/* Divide by 2 */
+	reg &= ~(SSI_CLK_PODF_MASK << SSI1_CLK_PODF_SHIFT);
+	reg &= ~(SSI_CLK_PODF_MASK << SSI3_CLK_PODF_SHIFT);
+	reg |= (0x1 << SSI1_CLK_PODF_SHIFT);
+	reg |= (0x1 << SSI3_CLK_PODF_SHIFT);
+	/* Divide by 4 */
+	reg &= ~(SSI_CLK_PRED_MASK << SSI1_CLK_PRED_SHIFT);
+	reg &= ~(SSI_CLK_PRED_MASK << SSI3_CLK_PRED_SHIFT);
+	reg |= (0x3 << SSI1_CLK_PRED_SHIFT);
+	reg |= (0x3 << SSI3_CLK_PRED_SHIFT);
+	WR4(sc, CCM_CS1CDR, reg);
+
+	/* SSI2 */
+	reg = RD4(sc, CCM_CS2CDR);
+	/* Divide by 2 */
+	reg &= ~(SSI_CLK_PODF_MASK << SSI2_CLK_PODF_SHIFT);
+	reg |= (0x1 << SSI2_CLK_PODF_SHIFT);
+	/* Divide by 4 */
+	reg &= ~(SSI_CLK_PRED_MASK << SSI2_CLK_PRED_SHIFT);
+	reg |= (0x3 << SSI2_CLK_PRED_SHIFT);
+	WR4(sc, CCM_CS2CDR, reg);
+}
+
+void
+imx_ccm_usb_enable(device_t _usbdev)
+{
+
+	/*
+	 * For imx6, the USBOH3 clock gate is bits 0-1 of CCGR6, so no need for
+	 * shifting and masking here, just set the low-order two bits to ALWAYS.
+	 */
+	WR4(ccm_sc, CCM_CCGR6, RD4(ccm_sc, CCM_CCGR6) | CCGR_CLK_MODE_ALWAYS);
+}
+
+void
+imx_ccm_usbphy_enable(device_t _phydev)
+{
+        /*
+         * XXX Which unit?
+         * Right now it's not clear how to figure from fdt data which phy unit
+         * we're supposed to operate on.  Until this is worked out, just enable
+         * both PHYs.
+         */
+#if 0
+	int phy_num, regoff;
+
+	phy_num = 0; /* XXX */
+
+	switch (phy_num) {
+	case 0:
+		regoff = 0;
+		break;
+	case 1:
+		regoff = 0x10;
+		break;
+	default:
+		device_printf(ccm_sc->dev, "Bad PHY number %u,\n", 
+		    phy_num);
+		return;
+	}
+
+	imx6_anatop_write_4(IMX6_ANALOG_CCM_PLL_USB1 + regoff, 
+	    IMX6_ANALOG_CCM_PLL_USB_ENABLE | 
+	    IMX6_ANALOG_CCM_PLL_USB_POWER |
+	    IMX6_ANALOG_CCM_PLL_USB_EN_USB_CLKS);
+#else
+	imx6_anatop_write_4(IMX6_ANALOG_CCM_PLL_USB1 + 0,
+	    IMX6_ANALOG_CCM_PLL_USB_ENABLE | 
+	    IMX6_ANALOG_CCM_PLL_USB_POWER |
+	    IMX6_ANALOG_CCM_PLL_USB_EN_USB_CLKS);
+
+	imx6_anatop_write_4(IMX6_ANALOG_CCM_PLL_USB1 + 0x10, 
+	    IMX6_ANALOG_CCM_PLL_USB_ENABLE | 
+	    IMX6_ANALOG_CCM_PLL_USB_POWER |
+	    IMX6_ANALOG_CCM_PLL_USB_EN_USB_CLKS);
+#endif
+}
+
+uint32_t
+imx_ccm_ipg_hz(void)
+{
+
+	return (66000000);
+}
+
+uint32_t
+imx_ccm_perclk_hz(void)
+{
+
+	return (66000000);
+}
+
+uint32_t
+imx_ccm_sdhci_hz(void)
+{
+
+	return (200000000);
+}
+
+uint32_t
+imx_ccm_uart_hz(void)
+{
+
+	return (80000000);
+}
+
+uint32_t
+imx_ccm_ahb_hz(void)
+{
+	return (132000000);
+}
+
+uint32_t
+imx_ccm_get_cacrr(void)
+{
+
+	return (RD4(ccm_sc, CCM_CACCR));
+}
+
+void
+imx_ccm_set_cacrr(uint32_t divisor)
+{
+
+	WR4(ccm_sc, CCM_CACCR, divisor);
+}
+
+static device_method_t ccm_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,  ccm_probe),
+	DEVMETHOD(device_attach, ccm_attach),
+	DEVMETHOD(device_detach, ccm_detach),
+
+	DEVMETHOD_END
+};
+
+static driver_t ccm_driver = {
+	"ccm",
+	ccm_methods,
+	sizeof(struct ccm_softc)
+};
+
+static devclass_t ccm_devclass;
+
+EARLY_DRIVER_MODULE(ccm, simplebus, ccm_driver, ccm_devclass, 0, 0, 
+    BUS_PASS_CPU + BUS_PASS_ORDER_EARLY);
+


Property changes on: trunk/sys/arm/freescale/imx/imx6_ccm.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/imx/imx6_ccmreg.h
===================================================================
--- trunk/sys/arm/freescale/imx/imx6_ccmreg.h	                        (rev 0)
+++ trunk/sys/arm/freescale/imx/imx6_ccmreg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,70 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Ian Lepore <ian at freebsd.org>
+ * 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: stable/10/sys/arm/freescale/imx/imx6_ccmreg.h 283501 2015-05-24 19:00:46Z ian $
+ */
+
+#ifndef	IMX6_CCMREG_H
+#define	IMX6_CCMREG_H
+
+#define	CCM_CACCR			0x010
+#define	CCM_CSCMR1			0x01C
+#define	  SSI1_CLK_SEL_S		  10
+#define	  SSI2_CLK_SEL_S		  12
+#define	  SSI3_CLK_SEL_S		  14
+#define	  SSI_CLK_SEL_M			  0x3
+#define	  SSI_CLK_SEL_508_PFD		  0
+#define	  SSI_CLK_SEL_454_PFD		  1
+#define	  SSI_CLK_SEL_PLL4		  2
+#define	CCM_CSCMR2			0x020
+#define	CCM_CS1CDR			0x028
+#define	  SSI1_CLK_PODF_SHIFT		  0
+#define	  SSI1_CLK_PRED_SHIFT		  6
+#define	  SSI3_CLK_PODF_SHIFT		  16
+#define	  SSI3_CLK_PRED_SHIFT		  22
+#define	  SSI_CLK_PODF_MASK		  0x3f
+#define	  SSI_CLK_PRED_MASK		  0x7
+#define	CCM_CS2CDR			0x02C
+#define	  SSI2_CLK_PODF_SHIFT		  0
+#define	  SSI2_CLK_PRED_SHIFT		  6
+#define	CCM_CSCDR2			0x038
+#define	CCM_CLPCR			0x054
+#define	  CCM_CLPCR_LPM_MASK		  0x03
+#define	  CCM_CLPCR_LPM_RUN		  0x00
+#define	  CCM_CLPCR_LPM_WAIT		  0x01
+#define	  CCM_CLPCR_LPM_STOP		  0x02
+#define	CCM_CGPR			0x064
+#define	  CCM_CGPR_INT_MEM_CLK_LPM	  (1 << 17)
+#define	CCM_CCGR0			0x068
+#define	CCM_CCGR1			0x06C
+#define	CCM_CCGR2			0x070
+#define	CCM_CCGR3			0x074
+#define	CCM_CCGR4			0x078
+#define	CCM_CCGR5			0x07C
+#define	CCM_CCGR6			0x080
+#define	CCM_CMEOR			0x088
+
+#endif


Property changes on: trunk/sys/arm/freescale/imx/imx6_ccmreg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/imx/imx6_machdep.c
===================================================================
--- trunk/sys/arm/freescale/imx/imx6_machdep.c	                        (rev 0)
+++ trunk/sys/arm/freescale/imx/imx6_machdep.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,275 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Ian Lepore <ian at freebsd.org>
+ * 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: stable/10/sys/arm/freescale/imx/imx6_machdep.c 294678 2016-01-24 19:34:05Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/reboot.h>
+
+#include <vm/vm.h>
+
+#include <machine/bus.h>
+#include <machine/devmap.h>
+#include <machine/intr.h>
+#include <machine/machdep.h>
+
+#include <arm/arm/mpcore_timervar.h>
+#include <arm/freescale/imx/imx6_anatopreg.h>
+#include <arm/freescale/imx/imx6_anatopvar.h>
+#include <arm/freescale/imx/imx_machdep.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+
+struct fdt_fixup_entry fdt_fixup_table[] = {
+	{ NULL, NULL }
+};
+
+static uint32_t gpio1_node;
+
+/*
+ * Work around the linux workaround for imx6 erratum 006687, in which some
+ * ethernet interrupts don't go to the GPC and thus won't wake the system from
+ * Wait mode. We don't use Wait mode (which halts the GIC, leaving only GPC
+ * interrupts able to wake the system), so we don't experience the bug at all.
+ * The linux workaround is to reconfigure GPIO1_6 as the ENET interrupt by
+ * writing magic values to an undocumented IOMUX register, then letting the gpio
+ * interrupt driver notify the ethernet driver.  We'll be able to do all that
+ * (even though we don't need to) once the INTRNG project is committed and the
+ * imx_gpio driver becomes an interrupt driver.  Until then, this crazy little
+ * workaround watches for requests to map an interrupt 6 with the interrupt
+ * controller node referring to gpio1, and it substitutes the proper ffec
+ * interrupt number.
+ */
+static int
+imx6_decode_fdt(uint32_t iparent, uint32_t *intr, int *interrupt,
+    int *trig, int *pol)
+{
+
+	if (fdt32_to_cpu(intr[0]) == 6 && 
+	    OF_node_from_xref(iparent) == gpio1_node) {
+		*interrupt = 150;
+		*trig = INTR_TRIGGER_CONFORM;
+		*pol  = INTR_POLARITY_CONFORM;
+		return (0);
+	}
+	return (gic_decode_fdt(iparent, intr, interrupt, trig, pol));
+}
+
+fdt_pic_decode_t fdt_pic_table[] = {
+	&imx6_decode_fdt,
+	NULL
+};
+
+vm_offset_t
+initarm_lastaddr(void)
+{
+
+	return (arm_devmap_lastaddr());
+}
+
+void
+initarm_early_init(void)
+{
+	/* Inform the MPCore timer driver that its clock is variable. */
+	arm_tmr_change_frequency(ARM_TMR_FREQUENCY_VARIES);
+}
+
+void
+initarm_gpio_init(void)
+{
+
+}
+
+void
+initarm_late_init(void)
+{
+	const uint32_t IMX6_WDOG_SR_PHYS = 0x020bc004;
+
+	imx_wdog_init_last_reset(IMX6_WDOG_SR_PHYS);
+
+	/* Cache the gpio1 node handle for imx6_decode_fdt() workaround code. */
+	gpio1_node = OF_node_from_xref(
+	    OF_finddevice("/soc/aips-bus at 02000000/gpio at 0209c000"));
+}
+
+/*
+ * Set up static device mappings.
+ *
+ * This attempts to cover the most-used devices with 1MB section mappings, which
+ * is good for performance (uses fewer TLB entries for device access).
+ *
+ * ARMMP covers the interrupt controller, MPCore timers, global timer, and the
+ * L2 cache controller.  Most of the 1MB range is unused reserved space.
+ *
+ * AIPS1/AIPS2 cover most of the on-chip devices such as uart, spi, i2c, etc.
+ *
+ * Notably not mapped right now are HDMI, GPU, and other devices below ARMMP in
+ * the memory map.  When we get support for graphics it might make sense to
+ * static map some of that area.  Be careful with other things in that area such
+ * as OCRAM that probably shouldn't be mapped as PTE_DEVICE memory.
+ */
+int
+initarm_devmap_init(void)
+{
+	const uint32_t IMX6_ARMMP_PHYS = 0x00a00000;
+	const uint32_t IMX6_ARMMP_SIZE = 0x00100000;
+	const uint32_t IMX6_AIPS1_PHYS = 0x02000000;
+	const uint32_t IMX6_AIPS1_SIZE = 0x00100000;
+	const uint32_t IMX6_AIPS2_PHYS = 0x02100000;
+	const uint32_t IMX6_AIPS2_SIZE = 0x00100000;
+
+	arm_devmap_add_entry(IMX6_ARMMP_PHYS, IMX6_ARMMP_SIZE);
+	arm_devmap_add_entry(IMX6_AIPS1_PHYS, IMX6_AIPS1_SIZE);
+	arm_devmap_add_entry(IMX6_AIPS2_PHYS, IMX6_AIPS2_SIZE);
+
+	return (0);
+}
+
+void
+cpu_reset(void)
+{
+	const uint32_t IMX6_WDOG_CR_PHYS = 0x020bc000;
+
+	imx_wdog_cpu_reset(IMX6_WDOG_CR_PHYS);
+}
+
+/*
+ * Determine what flavor of imx6 we're running on.
+ *
+ * This code is based on the way u-boot does it.  Information found on the web
+ * indicates that Freescale themselves were the original source of this logic,
+ * including the strange check for number of CPUs in the SCU configuration
+ * register, which is apparently needed on some revisions of the SOLO.
+ *
+ * According to the documentation, there is such a thing as an i.MX6 Dual
+ * (non-lite flavor).  However, Freescale doesn't seem to have assigned it a
+ * number or provided any logic to handle it in their detection code.
+ *
+ * Note that the ANALOG_DIGPROG and SCU configuration registers are not
+ * documented in the chip reference manual.  (SCU configuration is mentioned,
+ * but not mapped out in detail.)  I think the bottom two bits of the scu config
+ * register may be ncpu-1.
+ *
+ * This hasn't been tested yet on a dual[-lite].
+ *
+ * On a solo:
+ *      digprog    = 0x00610001
+ *      hwsoc      = 0x00000062
+ *      scu config = 0x00000500
+ * On a quad:
+ *      digprog    = 0x00630002
+ *      hwsoc      = 0x00000063
+ *      scu config = 0x00005503
+ */
+u_int imx_soc_type()
+{
+	uint32_t digprog, hwsoc;
+	uint32_t *pcr;
+	static u_int soctype;
+	const vm_offset_t SCU_CONFIG_PHYSADDR = 0x00a00004;
+#define	HWSOC_MX6SL	0x60
+#define	HWSOC_MX6DL	0x61
+#define	HWSOC_MX6SOLO	0x62
+#define	HWSOC_MX6Q	0x63
+
+	if (soctype != 0)
+		return (soctype);
+
+	digprog = imx6_anatop_read_4(IMX6_ANALOG_DIGPROG_SL);
+	hwsoc = (digprog >> IMX6_ANALOG_DIGPROG_SOCTYPE_SHIFT) & 
+	    IMX6_ANALOG_DIGPROG_SOCTYPE_MASK;
+
+	if (hwsoc != HWSOC_MX6SL) {
+		digprog = imx6_anatop_read_4(IMX6_ANALOG_DIGPROG);
+		hwsoc = (digprog & IMX6_ANALOG_DIGPROG_SOCTYPE_MASK) >>
+		    IMX6_ANALOG_DIGPROG_SOCTYPE_SHIFT;
+		/*printf("digprog = 0x%08x\n", digprog);*/
+		if (hwsoc == HWSOC_MX6DL) {
+			pcr = arm_devmap_ptov(SCU_CONFIG_PHYSADDR, 4);
+			if (pcr != NULL) {
+				/*printf("scu config = 0x%08x\n", *pcr);*/
+				if ((*pcr & 0x03) == 0) {
+					hwsoc = HWSOC_MX6SOLO;
+				}
+			}
+		}
+	}
+	/* printf("hwsoc 0x%08x\n", hwsoc); */
+
+	switch (hwsoc) {
+	case HWSOC_MX6SL:
+		soctype = IMXSOC_6SL;
+		break;
+	case HWSOC_MX6SOLO:
+		soctype = IMXSOC_6S;
+		break;
+	case HWSOC_MX6DL:
+		soctype = IMXSOC_6DL;
+		break;
+	case HWSOC_MX6Q :
+		soctype = IMXSOC_6Q;
+		break;
+	default:
+		printf("imx_soc_type: Don't understand hwsoc 0x%02x, "
+		    "digprog 0x%08x; assuming IMXSOC_6Q\n", hwsoc, digprog);
+		soctype = IMXSOC_6Q;
+		break;
+	}
+
+	return (soctype);
+}
+
+/*
+ * Early putc routine for EARLY_PRINTF support.  To use, add to kernel config:
+ *   option SOCDEV_PA=0x02000000
+ *   option SOCDEV_VA=0x02000000
+ *   option EARLY_PRINTF
+ * Resist the temptation to change the #if 0 to #ifdef EARLY_PRINTF here. It
+ * makes sense now, but if multiple SOCs do that it will make early_putc another
+ * duplicate symbol to be eliminated on the path to a generic kernel.
+ */
+#if 0 
+static void 
+imx6_early_putc(int c)
+{
+	volatile uint32_t * UART_STAT_REG = (uint32_t *)0x02020098;
+	volatile uint32_t * UART_TX_REG   = (uint32_t *)0x02020040;
+	const uint32_t      UART_TXRDY    = (1 << 3);
+
+	while ((*UART_STAT_REG & UART_TXRDY) == 0)
+		continue;
+	*UART_TX_REG = c;
+}
+early_putc_t *early_putc = imx6_early_putc;
+#endif
+


Property changes on: trunk/sys/arm/freescale/imx/imx6_machdep.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/imx/imx6_mp.c
===================================================================
--- trunk/sys/arm/freescale/imx/imx6_mp.c	                        (rev 0)
+++ trunk/sys/arm/freescale/imx/imx6_mp.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,179 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014 Juergen Weiss <weiss at uni-mainz.de>
+ * Copyright (c) 2014 Ian Lepore <ian at freebsd.org>
+ * 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 ``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 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: stable/10/sys/arm/freescale/imx/imx6_mp.c 269104 2014-07-25 23:36:39Z ian $");
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/smp.h>
+
+#include <machine/smp.h>
+#include <machine/fdt.h>
+#include <machine/intr.h>
+
+#define	SCU_PHYSBASE			0x00a00000
+#define	SCU_SIZE			0x00001000
+
+#define	SCU_CONTROL_REG			0x00
+#define	  SCU_CONTROL_ENABLE		  (1 << 0)
+#define	SCU_CONFIG_REG			0x04
+#define	  SCU_CONFIG_REG_NCPU_MASK	  0x03
+#define	SCU_CPUPOWER_REG		0x08
+#define	SCU_INV_TAGS_REG		0x0c
+#define	SCU_DIAG_CONTROL		0x30
+#define	  SCU_DIAG_DISABLE_MIGBIT	  (1 << 0)
+#define	SCU_FILTER_START_REG		0x40
+#define	SCU_FILTER_END_REG		0x44
+#define	SCU_SECURE_ACCESS_REG		0x50
+#define	SCU_NONSECURE_ACCESS_REG	0x54
+
+#define	SRC_PHYSBASE			0x020d8000
+#define SRC_SIZE			0x4000
+#define	SRC_CONTROL_REG			0x00
+#define	SRC_CONTROL_C1ENA_SHIFT		  22	/* Bit for Core 1 enable */
+#define	SRC_CONTROL_C1RST_SHIFT		  14	/* Bit for Core 1 reset */
+#define	SRC_GPR0_C1FUNC			0x20	/* Register for Core 1 entry func */
+#define	SRC_GPR1_C1ARG			0x24	/* Register for Core 1 entry arg */
+
+void
+platform_mp_init_secondary(void)
+{
+
+	gic_init_secondary();
+}
+
+void
+platform_mp_setmaxid(void)
+{
+	bus_space_handle_t scu;
+	int hwcpu, ncpu;
+	uint32_t val;
+
+	/* If we've already set the global vars don't bother to do it again. */
+	if (mp_ncpus != 0)
+		return;
+
+	if (bus_space_map(fdtbus_bs_tag, SCU_PHYSBASE, SCU_SIZE, 0, &scu) != 0)
+		panic("Couldn't map the SCU\n");
+	val = bus_space_read_4(fdtbus_bs_tag, scu, SCU_CONFIG_REG);
+	hwcpu = (val & SCU_CONFIG_REG_NCPU_MASK) + 1;
+	bus_space_unmap(fdtbus_bs_tag, scu, SCU_SIZE);
+
+	ncpu = hwcpu;
+	TUNABLE_INT_FETCH("hw.ncpu", &ncpu);
+	if (ncpu < 1 || ncpu > hwcpu)
+		ncpu = hwcpu;
+
+	mp_ncpus = ncpu;
+	mp_maxid = ncpu - 1;
+}
+
+int
+platform_mp_probe(void)
+{
+
+	/* I think platform_mp_setmaxid must get called first, but be safe. */
+	if (mp_ncpus == 0)
+		platform_mp_setmaxid();
+
+	return (mp_ncpus > 1);
+}
+
+void    
+platform_mp_start_ap(void)
+{
+	bus_space_handle_t scu;
+	bus_space_handle_t src;
+
+	uint32_t val;
+	int i;
+
+	if (bus_space_map(fdtbus_bs_tag, SCU_PHYSBASE, SCU_SIZE, 0, &scu) != 0)
+		panic("Couldn't map the SCU\n");
+	if (bus_space_map(fdtbus_bs_tag, SRC_PHYSBASE, SRC_SIZE, 0, &src) != 0)
+		panic("Couldn't map the system reset controller (SRC)\n");
+
+	/*
+	 * Invalidate SCU cache tags.  The 0x0000ffff constant invalidates all
+	 * ways on all cores 0-3.  Per the ARM docs, it's harmless to write to
+	 * the bits for cores that are not present.
+	 */
+	bus_space_write_4(fdtbus_bs_tag, scu, SCU_INV_TAGS_REG, 0x0000ffff);
+
+	/*
+	 * Erratum ARM/MP: 764369 (problems with cache maintenance).
+	 * Setting the "disable-migratory bit" in the undocumented SCU
+	 * Diagnostic Control Register helps work around the problem.
+	 */
+	val = bus_space_read_4(fdtbus_bs_tag, scu, SCU_DIAG_CONTROL);
+	bus_space_write_4(fdtbus_bs_tag, scu, SCU_DIAG_CONTROL, 
+	    val | SCU_DIAG_DISABLE_MIGBIT);
+
+	/*
+	 * Enable the SCU, then clean the cache on this core.  After these two
+	 * operations the cache tag ram in the SCU is coherent with the contents
+	 * of the cache on this core.  The other cores aren't running yet so
+	 * their caches can't contain valid data yet, but we've initialized
+	 * their SCU tag ram above, so they will be coherent from startup.
+	 */
+	val = bus_space_read_4(fdtbus_bs_tag, scu, SCU_CONTROL_REG);
+	bus_space_write_4(fdtbus_bs_tag, scu, SCU_CONTROL_REG, 
+	    val | SCU_CONTROL_ENABLE);
+	cpu_idcache_wbinv_all();
+
+	/*
+	 * For each AP core, set the entry point address and argument registers,
+	 * and set the core-enable and core-reset bits in the control register.
+	 */
+	val = bus_space_read_4(fdtbus_bs_tag, src, SRC_CONTROL_REG);
+	for (i=1; i < mp_ncpus; i++) {
+		bus_space_write_4(fdtbus_bs_tag, src, SRC_GPR0_C1FUNC + 8*i,
+		    pmap_kextract((vm_offset_t)mpentry));
+		bus_space_write_4(fdtbus_bs_tag, src, SRC_GPR1_C1ARG  + 8*i, 0);
+
+		val |= ((1 << (SRC_CONTROL_C1ENA_SHIFT - 1 + i )) |
+		    ( 1 << (SRC_CONTROL_C1RST_SHIFT - 1 + i)));
+
+	}
+	bus_space_write_4(fdtbus_bs_tag, src, SRC_CONTROL_REG, val);
+
+	armv7_sev();
+
+	bus_space_unmap(fdtbus_bs_tag, scu, SCU_SIZE);
+	bus_space_unmap(fdtbus_bs_tag, src, SRC_SIZE);
+}
+
+void
+platform_ipi_send(cpuset_t cpus, u_int ipi)
+{
+
+	pic_ipi_send(cpus, ipi);
+}


Property changes on: trunk/sys/arm/freescale/imx/imx6_mp.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/imx/imx6_pl310.c
===================================================================
--- trunk/sys/arm/freescale/imx/imx6_pl310.c	                        (rev 0)
+++ trunk/sys/arm/freescale/imx/imx6_pl310.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,76 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Olivier Houchard.
+ * 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 ``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 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: stable/10/sys/arm/freescale/imx/imx6_pl310.c 266384 2014-05-18 00:26:42Z ian $");
+
+/*
+ * The machine-dependent part of the arm/pl310 driver for imx6 SoCs.
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/rman.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+
+#include <machine/bus.h>
+#include <machine/pl310.h>
+
+void
+platform_pl310_init(struct pl310_softc *sc)
+{
+	uint32_t reg;
+
+	/*
+	 * Enable power saving modes:
+	 *  - Dynamic Gating stops the clock when the controller is idle.
+	 *  - Standby stops the clock when the cores are in WFI mode.
+	 */
+	reg = pl310_read4(sc, PL310_POWER_CTRL);
+	reg |= POWER_CTRL_ENABLE_GATING | POWER_CTRL_ENABLE_STANDBY;
+	pl310_write4(sc, PL310_POWER_CTRL, reg);
+
+	pl310_set_ram_latency(sc, PL310_TAG_RAM_CTRL,  4, 2, 3);
+	pl310_set_ram_latency(sc, PL310_DATA_RAM_CTRL, 4, 2, 3);
+}
+
+void
+platform_pl310_write_ctrl(struct pl310_softc *sc, uint32_t val)
+{
+
+	pl310_write4(sc, PL310_CTRL, val);
+}
+
+void
+platform_pl310_write_debug(struct pl310_softc *sc, uint32_t val)
+{
+
+	pl310_write4(sc, PL310_DEBUG_CTRL, val);
+}
+


Property changes on: trunk/sys/arm/freescale/imx/imx6_pl310.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/imx/imx6_sdma.c
===================================================================
--- trunk/sys/arm/freescale/imx/imx6_sdma.c	                        (rev 0)
+++ trunk/sys/arm/freescale/imx/imx6_sdma.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,519 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2015 Ruslan Bukin <br at bsdpad.com>
+ * 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.
+ */
+
+/*
+ * i.MX6 Smart Direct Memory Access Controller (sDMA)
+ * Chapter 41, i.MX 6Dual/6Quad Applications Processor Reference Manual,
+ * Rev. 1, 04/2013
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/freescale/imx/imx6_sdma.c 283500 2015-05-24 18:59:45Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/endian.h>
+#include <sys/rman.h>
+#include <sys/timeet.h>
+#include <sys/timetc.h>
+#include <sys/firmware.h>
+
+#include <vm/vm.h>
+#include <vm/vm_extern.h>
+#include <vm/vm_kern.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#include <arm/freescale/imx/imx6_sdma.h>
+
+#define	MAX_BD	(PAGE_SIZE / sizeof(struct sdma_buffer_descriptor))
+
+#define	READ4(_sc, _reg)	\
+	bus_space_read_4(_sc->bst, _sc->bsh, _reg)
+#define	WRITE4(_sc, _reg, _val)	\
+	bus_space_write_4(_sc->bst, _sc->bsh, _reg, _val)
+
+struct sdma_softc *sdma_sc;
+
+static struct resource_spec sdma_spec[] = {
+	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		0,	RF_ACTIVE },
+	{ -1, 0 }
+};
+
+static void
+sdma_intr(void *arg)
+{
+	struct sdma_buffer_descriptor *bd;
+	struct sdma_channel *channel;
+	struct sdma_conf *conf;
+	struct sdma_softc *sc;
+	int pending;
+	int i;
+	int j;
+
+	sc = arg;
+
+	pending = READ4(sc, SDMAARM_INTR);
+
+	/* Ack intr */
+	WRITE4(sc, SDMAARM_INTR, pending);
+
+	for (i = 0; i < SDMA_N_CHANNELS; i++) {
+		if ((pending & (1 << i)) == 0)
+			continue;
+		channel = &sc->channel[i];
+		conf = channel->conf;
+		if (!conf)
+			continue;
+		for (j = 0; j < conf->num_bd; j++) {
+			bd = &channel->bd[j];
+			bd->mode.status |= BD_DONE;
+			if (bd->mode.status & BD_RROR)
+				printf("sDMA error\n");
+		}
+
+		conf->ih(conf->ih_user, 1);
+
+		WRITE4(sc, SDMAARM_HSTART, (1 << i));
+	}
+}
+
+static int
+sdma_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "fsl,imx6q-sdma"))
+		return (ENXIO);
+
+	device_set_desc(dev, "i.MX6 Smart Direct Memory Access Controller");
+	return (BUS_PROBE_DEFAULT);
+}
+
+int
+sdma_start(int chn)
+{
+	struct sdma_softc *sc;
+
+	sc = sdma_sc;
+
+	WRITE4(sc, SDMAARM_HSTART, (1 << chn));
+
+	return (0);
+}
+
+int
+sdma_stop(int chn)
+{
+	struct sdma_softc *sc;
+
+	sc = sdma_sc;
+
+	WRITE4(sc, SDMAARM_STOP_STAT, (1 << chn));
+
+	return (0);
+}
+
+int
+sdma_alloc(void)
+{
+	struct sdma_channel *channel;
+	struct sdma_softc *sc;
+	int found;
+	int chn;
+	int i;
+
+	sc = sdma_sc;
+	found = 0;
+
+	/* Channel 0 can't be used */
+	for (i = 1; i < SDMA_N_CHANNELS; i++) {
+		channel = &sc->channel[i];
+		if (channel->in_use == 0) {
+			channel->in_use = 1;
+			found = 1;
+			break;
+		}
+	}
+
+	if (!found)
+		return (-1);
+
+	chn = i;
+
+	/* Allocate area for buffer descriptors */
+	channel->bd = (void *)kmem_alloc_contig(kernel_arena,
+	    PAGE_SIZE, M_ZERO, 0, ~0, PAGE_SIZE, 0,
+	    VM_MEMATTR_UNCACHEABLE);
+
+	return (chn);
+}
+
+int
+sdma_free(int chn)
+{
+	struct sdma_channel *channel;
+	struct sdma_softc *sc;
+
+	sc = sdma_sc;
+
+	channel = &sc->channel[chn];
+	channel->in_use = 0;
+
+	kmem_free(kernel_arena, (vm_offset_t)channel->bd,
+			PAGE_SIZE);
+
+	return (0);
+}
+
+static int
+sdma_overrides(struct sdma_softc *sc, int chn,
+		int evt, int host, int dsp)
+{
+	int reg;
+
+	/* Ignore sDMA requests */
+	reg = READ4(sc, SDMAARM_EVTOVR);
+	if (evt)
+		reg |= (1 << chn);
+	else
+		reg &= ~(1 << chn);
+	WRITE4(sc, SDMAARM_EVTOVR, reg);
+
+	/* Ignore enable bit (HE) */
+	reg = READ4(sc, SDMAARM_HOSTOVR);
+	if (host)
+		reg |= (1 << chn);
+	else
+		reg &= ~(1 << chn);
+	WRITE4(sc, SDMAARM_HOSTOVR, reg);
+
+	/* Prevent sDMA channel from starting */
+	reg = READ4(sc, SDMAARM_DSPOVR);
+	if (!dsp)
+		reg |= (1 << chn);
+	else
+		reg &= ~(1 << chn);
+	WRITE4(sc, SDMAARM_DSPOVR, reg);
+
+	return (0);
+}
+
+int
+sdma_configure(int chn, struct sdma_conf *conf)
+{
+	struct sdma_buffer_descriptor *bd0;
+	struct sdma_buffer_descriptor *bd;
+	struct sdma_context_data *context;
+	struct sdma_channel *channel;
+	struct sdma_softc *sc;
+#if 0
+	int timeout;
+	int ret;
+#endif
+	int i;
+
+	sc = sdma_sc;
+
+	channel = &sc->channel[chn];
+	channel->conf = conf;
+
+	/* Ensure operation has stopped */
+	sdma_stop(chn);
+
+	/* Set priority and enable the channel */
+	WRITE4(sc, SDMAARM_SDMA_CHNPRI(chn), 1);
+	WRITE4(sc, SDMAARM_CHNENBL(conf->event), (1 << chn));
+
+	sdma_overrides(sc, chn, 0, 0, 0);
+
+	if (conf->num_bd > MAX_BD) {
+		device_printf(sc->dev, "Error: too much buffer"
+				" descriptors requested\n");
+		return (-1);
+	}
+
+	for (i = 0; i < conf->num_bd; i++) {
+		bd = &channel->bd[i];
+		bd->mode.command = conf->command;
+		bd->mode.status = BD_DONE | BD_EXTD | BD_CONT | BD_INTR;
+		if (i == (conf->num_bd - 1))
+			bd->mode.status |= BD_WRAP;
+		bd->mode.count = conf->period;
+		bd->buffer_addr = conf->saddr + (conf->period * i);
+		bd->ext_buffer_addr = 0;
+	}
+
+	sc->ccb[chn].base_bd_ptr = vtophys(channel->bd);
+	sc->ccb[chn].current_bd_ptr = vtophys(channel->bd);
+
+	/*
+	 * Load context.
+	 *
+	 * i.MX6 Reference Manual: Appendix A SDMA Scripts
+	 * A.3.1.7.1 (mcu_2_app)
+	 */
+
+	/*
+	 * TODO: allow using other scripts
+	 */
+	context = sc->context;
+	memset(context, 0, sizeof(*context));
+	context->channel_state.pc = sc->fw_scripts->mcu_2_app_addr;
+
+	/*
+	 * Tx FIFO 0 address (r6)
+	 * Event_mask (r1)
+	 * Event2_mask (r0)
+	 * Watermark level (r7)
+	 */
+
+	if (conf->event > 32) {
+		context->gReg[0] = (1 << (conf->event % 32));
+		context->gReg[1] = 0;
+	} else {
+		context->gReg[0] = 0;
+		context->gReg[1] = (1 << conf->event);
+	}
+
+	context->gReg[6] = conf->daddr;
+	context->gReg[7] = conf->word_length;
+
+	bd0 = sc->bd0;
+	bd0->mode.command = C0_SETDM;
+	bd0->mode.status = BD_DONE | BD_INTR | BD_WRAP | BD_EXTD;
+	bd0->mode.count = sizeof(*context) / 4;
+	bd0->buffer_addr = sc->context_phys;
+	bd0->ext_buffer_addr = 2048 + (sizeof(*context) / 4) * chn;
+
+	WRITE4(sc, SDMAARM_HSTART, 1);
+
+#if 0
+	/* Debug purposes */
+
+	timeout = 1000;
+	while (!(ret = READ4(sc, SDMAARM_INTR) & 1)) {
+		if (timeout-- <= 0)
+			break;
+		DELAY(10);
+	};
+
+	if (!ret) {
+		device_printf(sc->dev, "Failed to load context.\n");
+		return (-1);
+	}
+
+	WRITE4(sc, SDMAARM_INTR, ret);
+
+	device_printf(sc->dev, "Context loaded successfully.\n");
+#endif
+
+	return (0);
+}
+
+static int
+load_firmware(struct sdma_softc *sc)
+{
+	struct sdma_firmware_header *header;
+	const struct firmware *fp;
+
+	fp = firmware_get("sdma_fw");
+	if (fp == NULL) {
+		device_printf(sc->dev, "Can't get firmware.\n");
+		return (-1);
+	}
+
+	header = (struct sdma_firmware_header *)fp->data;
+	if (header->magic != FW_HEADER_MAGIC) {
+		device_printf(sc->dev, "Can't use firmware.\n");
+		return (-1);
+	}
+
+	sc->fw_header = header;
+	sc->fw_scripts = (void *)((char *)header +
+				header->script_addrs_start);
+
+	return (0);
+}
+
+static int
+boot_firmware(struct sdma_softc *sc)
+{
+	struct sdma_buffer_descriptor *bd0;
+	uint32_t *ram_code;
+	int timeout;
+	int ret;
+	int chn;
+	int sz;
+	int i;
+
+	ram_code = (void *)((char *)sc->fw_header +
+			sc->fw_header->ram_code_start);
+
+	/* Make sure SDMA has not started yet */
+	WRITE4(sc, SDMAARM_MC0PTR, 0);
+
+	sz = SDMA_N_CHANNELS * sizeof(struct sdma_channel_control) + \
+	    sizeof(struct sdma_context_data);
+	sc->ccb = (void *)kmem_alloc_contig(kernel_arena,
+	    sz, M_ZERO, 0, ~0, PAGE_SIZE, 0, VM_MEMATTR_UNCACHEABLE);
+	sc->ccb_phys = vtophys(sc->ccb);
+
+	sc->context = (void *)((char *)sc->ccb + \
+	    SDMA_N_CHANNELS * sizeof(struct sdma_channel_control));
+	sc->context_phys = vtophys(sc->context);
+
+	/* Disable all the channels */
+	for (i = 0; i < SDMA_N_EVENTS; i++)
+		WRITE4(sc, SDMAARM_CHNENBL(i), 0);
+
+	/* All channels have priority 0 */
+	for (i = 0; i < SDMA_N_CHANNELS; i++)
+		WRITE4(sc, SDMAARM_SDMA_CHNPRI(i), 0);
+
+	/* Channel 0 is used for booting firmware */
+	chn = 0;
+
+	sc->bd0 = (void *)kmem_alloc_contig(kernel_arena,
+	    PAGE_SIZE, M_ZERO, 0, ~0, PAGE_SIZE, 0,
+	    VM_MEMATTR_UNCACHEABLE);
+	bd0 = sc->bd0;
+	sc->ccb[chn].base_bd_ptr = vtophys(bd0);
+	sc->ccb[chn].current_bd_ptr = vtophys(bd0);
+
+	WRITE4(sc, SDMAARM_SDMA_CHNPRI(chn), 1);
+
+	sdma_overrides(sc, chn, 1, 0, 0);
+
+	/* XXX: not sure what is that */
+	WRITE4(sc, SDMAARM_CHN0ADDR, 0x4050);
+
+	WRITE4(sc, SDMAARM_CONFIG, 0);
+	WRITE4(sc, SDMAARM_MC0PTR, sc->ccb_phys);
+	WRITE4(sc, SDMAARM_CONFIG, CONFIG_CSM);
+	WRITE4(sc, SDMAARM_SDMA_CHNPRI(chn), 1);
+
+	bd0->mode.command = C0_SETPM;
+	bd0->mode.status = BD_DONE | BD_INTR | BD_WRAP | BD_EXTD;
+	bd0->mode.count = sc->fw_header->ram_code_size / 2;
+	bd0->buffer_addr = vtophys(ram_code);
+	bd0->ext_buffer_addr = sc->fw_scripts->ram_code_start_addr;
+
+	WRITE4(sc, SDMAARM_HSTART, 1);
+
+	timeout = 100;
+	while (!(ret = READ4(sc, SDMAARM_INTR) & 1)) {
+		if (timeout-- <= 0)
+			break;
+		DELAY(10);
+	};
+
+	if (ret == 0) {
+		device_printf(sc->dev, "SDMA failed to boot\n");
+		return (-1);
+	}
+
+	WRITE4(sc, SDMAARM_INTR, ret);
+
+#if 0
+	device_printf(sc->dev, "SDMA booted successfully.\n");
+#endif
+
+	/* Debug is disabled */
+	WRITE4(sc, SDMAARM_ONCE_ENB, 0);
+
+	return (0);
+}
+
+static int
+sdma_attach(device_t dev)
+{
+	struct sdma_softc *sc;
+	int err;
+
+	sc = device_get_softc(dev);
+	sc->dev = dev;
+
+	if (bus_alloc_resources(dev, sdma_spec, sc->res)) {
+		device_printf(dev, "could not allocate resources\n");
+		return (ENXIO);
+	}
+
+	/* Memory interface */
+	sc->bst = rman_get_bustag(sc->res[0]);
+	sc->bsh = rman_get_bushandle(sc->res[0]);
+
+	sdma_sc = sc;
+
+	/* Setup interrupt handler */
+	err = bus_setup_intr(dev, sc->res[1], INTR_TYPE_MISC | INTR_MPSAFE,
+	    NULL, sdma_intr, sc, &sc->ih);
+	if (err) {
+		device_printf(dev, "Unable to alloc interrupt resource.\n");
+		return (ENXIO);
+	}
+
+	if (load_firmware(sc) == -1)
+		return (ENXIO);
+
+	if (boot_firmware(sc) == -1)
+		return (ENXIO);
+
+	return (0);
+};
+
+static device_method_t sdma_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		sdma_probe),
+	DEVMETHOD(device_attach,	sdma_attach),
+	{ 0, 0 }
+};
+
+static driver_t sdma_driver = {
+	"sdma",
+	sdma_methods,
+	sizeof(struct sdma_softc),
+};
+
+static devclass_t sdma_devclass;
+
+DRIVER_MODULE(sdma, simplebus, sdma_driver, sdma_devclass, 0, 0);


Property changes on: trunk/sys/arm/freescale/imx/imx6_sdma.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/imx/imx6_sdma.h
===================================================================
--- trunk/sys/arm/freescale/imx/imx6_sdma.h	                        (rev 0)
+++ trunk/sys/arm/freescale/imx/imx6_sdma.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,246 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2015 Ruslan Bukin <br at bsdpad.com>
+ * 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: stable/10/sys/arm/freescale/imx/imx6_sdma.h 283500 2015-05-24 18:59:45Z ian $
+ */
+
+#define	SDMAARM_MC0PTR		0x00	/* ARM platform Channel 0 Pointer */
+#define	SDMAARM_INTR		0x04	/* Channel Interrupts */
+#define	SDMAARM_STOP_STAT	0x08	/* Channel Stop/Channel Status */
+#define	SDMAARM_HSTART		0x0C	/* Channel Start */
+#define	SDMAARM_EVTOVR		0x10	/* Channel Event Override */
+#define	SDMAARM_DSPOVR		0x14	/* Channel BP Override */
+#define	SDMAARM_HOSTOVR		0x18	/* Channel ARM platform Override */
+#define	SDMAARM_EVTPEND		0x1C	/* Channel Event Pending */
+#define	SDMAARM_RESET		0x24	/* Reset Register */
+#define	SDMAARM_EVTERR		0x28	/* DMA Request Error Register */
+#define	SDMAARM_INTRMASK	0x2C	/* Channel ARM platform Interrupt Mask */
+#define	SDMAARM_PSW		0x30	/* Schedule Status */
+#define	SDMAARM_EVTERRDBG	0x34	/* DMA Request Error Register */
+#define	SDMAARM_CONFIG		0x38	/* Configuration Register */
+#define	 CONFIG_CSM		0x3
+#define	SDMAARM_SDMA_LOCK	0x3C	/* SDMA LOCK */
+#define	SDMAARM_ONCE_ENB	0x40	/* OnCE Enable */
+#define	SDMAARM_ONCE_DATA	0x44	/* OnCE Data Register */
+#define	SDMAARM_ONCE_INSTR	0x48	/* OnCE Instruction Register */
+#define	SDMAARM_ONCE_STAT	0x4C	/* OnCE Status Register */
+#define	SDMAARM_ONCE_CMD	0x50	/* OnCE Command Register */
+#define	SDMAARM_ILLINSTADDR	0x58	/* Illegal Instruction Trap Address */
+#define	SDMAARM_CHN0ADDR	0x5C	/* Channel 0 Boot Address */
+#define	SDMAARM_EVT_MIRROR	0x60	/* DMA Requests */
+#define	SDMAARM_EVT_MIRROR2	0x64	/* DMA Requests 2 */
+#define	SDMAARM_XTRIG_CONF1	0x70	/* Cross-Trigger Events Configuration Register 1 */
+#define	SDMAARM_XTRIG_CONF2	0x74	/* Cross-Trigger Events Configuration Register 2 */
+#define	SDMAARM_SDMA_CHNPRI(n)	(0x100 + 0x4 * n)	/* Channel Priority Registers */
+#define	SDMAARM_CHNENBL(n)	(0x200 + 0x4 * n)	/* Channel Enable RAM */
+
+/* SDMA Event Mappings */
+#define	SSI1_RX_1	35
+#define	SSI1_TX_1	36
+#define	SSI1_RX_0	37
+#define	SSI1_TX_0	38
+#define	SSI2_RX_1	39
+#define	SSI2_TX_1	40
+#define	SSI2_RX_0	41
+#define	SSI2_TX_0	42
+#define	SSI3_RX_1	43
+#define	SSI3_TX_1	44
+#define	SSI3_RX_0	45
+#define	SSI3_TX_0	46
+
+#define	C0_ADDR		0x01
+#define	C0_LOAD		0x02
+#define	C0_DUMP		0x03
+#define	C0_SETCTX	0x07
+#define	C0_GETCTX	0x03
+#define	C0_SETDM	0x01
+#define	C0_SETPM	0x04
+#define	C0_GETDM	0x02
+#define	C0_GETPM	0x08
+
+#define	BD_DONE		0x01
+#define	BD_WRAP		0x02
+#define	BD_CONT		0x04
+#define	BD_INTR		0x08
+#define	BD_RROR		0x10
+#define	BD_LAST		0x20
+#define	BD_EXTD		0x80
+
+/* sDMA data transfer length */
+#define	CMD_4BYTES	0
+#define	CMD_3BYTES	3
+#define	CMD_2BYTES	2
+#define	CMD_1BYTES	1
+
+struct sdma_firmware_header {
+	uint32_t	magic;
+	uint32_t	version_major;
+	uint32_t	version_minor;
+	uint32_t	script_addrs_start;
+	uint32_t	num_script_addrs;
+	uint32_t	ram_code_start;
+	uint32_t	ram_code_size;
+};
+
+struct sdma_mode_count {
+	uint16_t count;
+	uint8_t status;
+	uint8_t command;
+};
+
+struct sdma_buffer_descriptor {
+	struct sdma_mode_count	mode;
+	uint32_t		buffer_addr;
+	uint32_t		ext_buffer_addr;
+} __packed;
+
+struct sdma_channel_control {
+	uint32_t	current_bd_ptr;
+	uint32_t	base_bd_ptr;
+	uint32_t	unused[2];
+} __packed;
+
+struct sdma_state_registers {
+	uint32_t	pc     :14;
+	uint32_t	unused1: 1;
+	uint32_t	t      : 1;
+	uint32_t	rpc    :14;
+	uint32_t	unused0: 1;
+	uint32_t	sf     : 1;
+	uint32_t	spc    :14;
+	uint32_t	unused2: 1;
+	uint32_t	df     : 1;
+	uint32_t	epc    :14;
+	uint32_t	lm     : 2;
+} __packed;
+
+struct sdma_context_data {
+	struct sdma_state_registers	channel_state;
+	uint32_t	gReg[8];
+	uint32_t	mda;
+	uint32_t	msa;
+	uint32_t	ms;
+	uint32_t	md;
+	uint32_t	pda;
+	uint32_t	psa;
+	uint32_t	ps;
+	uint32_t	pd;
+	uint32_t	ca;
+	uint32_t	cs;
+	uint32_t	dda;
+	uint32_t	dsa;
+	uint32_t	ds;
+	uint32_t	dd;
+	uint32_t	unused[8];
+} __packed;
+
+/* SDMA firmware script pointers */
+struct sdma_script_start_addrs {
+	int32_t	ap_2_ap_addr;
+	int32_t	ap_2_bp_addr;
+	int32_t	ap_2_ap_fixed_addr;
+	int32_t	bp_2_ap_addr;
+	int32_t	loopback_on_dsp_side_addr;
+	int32_t	mcu_interrupt_only_addr;
+	int32_t	firi_2_per_addr;
+	int32_t	firi_2_mcu_addr;
+	int32_t	per_2_firi_addr;
+	int32_t	mcu_2_firi_addr;
+	int32_t	uart_2_per_addr;
+	int32_t	uart_2_mcu_addr;
+	int32_t	per_2_app_addr;
+	int32_t	mcu_2_app_addr;
+	int32_t	per_2_per_addr;
+	int32_t	uartsh_2_per_addr;
+	int32_t	uartsh_2_mcu_addr;
+	int32_t	per_2_shp_addr;
+	int32_t	mcu_2_shp_addr;
+	int32_t	ata_2_mcu_addr;
+	int32_t	mcu_2_ata_addr;
+	int32_t	app_2_per_addr;
+	int32_t	app_2_mcu_addr;
+	int32_t	shp_2_per_addr;
+	int32_t	shp_2_mcu_addr;
+	int32_t	mshc_2_mcu_addr;
+	int32_t	mcu_2_mshc_addr;
+	int32_t	spdif_2_mcu_addr;
+	int32_t	mcu_2_spdif_addr;
+	int32_t	asrc_2_mcu_addr;
+	int32_t	ext_mem_2_ipu_addr;
+	int32_t	descrambler_addr;
+	int32_t	dptc_dvfs_addr;
+	int32_t	utra_addr;
+	int32_t	ram_code_start_addr;
+	int32_t	mcu_2_ssish_addr;
+	int32_t	ssish_2_mcu_addr;
+	int32_t	hdmi_dma_addr;
+};
+
+#define	SDMA_N_CHANNELS 32
+#define	SDMA_N_EVENTS	48
+#define	FW_HEADER_MAGIC	0x414d4453
+
+struct sdma_channel {
+	struct sdma_conf		*conf;
+	struct sdma_buffer_descriptor	*bd;
+	uint8_t 			in_use;
+};
+
+struct sdma_softc {
+	struct resource			*res[2];
+	bus_space_tag_t			bst;
+	bus_space_handle_t		bsh;
+	device_t			dev;
+	void				*ih;
+	struct sdma_channel_control	*ccb;
+	struct sdma_buffer_descriptor	*bd0;
+	struct sdma_context_data	*context;
+	struct sdma_channel		channel[SDMA_N_CHANNELS];
+	uint32_t			num_bd;
+	uint32_t			ccb_phys;
+	uint32_t			context_phys;
+	struct sdma_firmware_header	*fw_header;
+	struct sdma_script_start_addrs	*fw_scripts;
+};
+
+struct sdma_conf {
+	bus_addr_t	saddr;
+	bus_addr_t	daddr;
+	uint32_t	word_length;
+	uint32_t	nbits;
+	uint32_t	command;
+	uint32_t	num_bd;
+	uint32_t	event;
+	uint32_t	period;
+	uint32_t	(*ih)(void *, int);
+	void		*ih_user;
+};
+
+int sdma_configure(int, struct sdma_conf *);
+int sdma_start(int);
+int sdma_stop(int);
+int sdma_alloc(void);
+int sdma_free(int);


Property changes on: trunk/sys/arm/freescale/imx/imx6_sdma.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/imx/imx6_ssi.c
===================================================================
--- trunk/sys/arm/freescale/imx/imx6_ssi.c	                        (rev 0)
+++ trunk/sys/arm/freescale/imx/imx6_ssi.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,856 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2015 Ruslan Bukin <br at bsdpad.com>
+ * 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.
+ */
+
+/*
+ * i.MX6 Synchronous Serial Interface (SSI)
+ *
+ * Chapter 61, i.MX 6Dual/6Quad Applications Processor Reference Manual,
+ * Rev. 1, 04/2013
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/freescale/imx/imx6_ssi.c 283500 2015-05-24 18:59:45Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/timeet.h>
+#include <sys/timetc.h>
+
+#include <dev/sound/pcm/sound.h>
+#include <dev/sound/chip.h>
+#include <mixer_if.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#include <arm/freescale/imx/imx6_sdma.h>
+#include <arm/freescale/imx/imx6_anatopvar.h>
+#include <arm/freescale/imx/imx_ccmvar.h>
+
+#define	READ4(_sc, _reg)	\
+	bus_space_read_4(_sc->bst, _sc->bsh, _reg)
+#define	WRITE4(_sc, _reg, _val)	\
+	bus_space_write_4(_sc->bst, _sc->bsh, _reg, _val)
+
+#define	SSI_NCHANNELS	1
+
+/* i.MX6 SSI registers */
+
+#define	SSI_STX0	0x00 /* Transmit Data Register n */
+#define	SSI_STX1	0x04 /* Transmit Data Register n */
+#define	SSI_SRX0	0x08 /* Receive Data Register n */
+#define	SSI_SRX1	0x0C /* Receive Data Register n */
+#define	SSI_SCR		0x10 /* Control Register */
+#define	 SCR_I2S_MODE_S	5    /* I2S Mode Select. */
+#define	 SCR_I2S_MODE_M	0x3
+#define	 SCR_SYN	(1 << 4)
+#define	 SCR_NET       	(1 << 3)  /* Network mode */
+#define	 SCR_RE		(1 << 2)  /* Receive Enable. */
+#define	 SCR_TE		(1 << 1)  /* Transmit Enable. */
+#define	 SCR_SSIEN	(1 << 0)  /* SSI Enable */
+#define	SSI_SISR	0x14      /* Interrupt Status Register */
+#define	SSI_SIER	0x18      /* Interrupt Enable Register */
+#define	 SIER_RDMAE	(1 << 22) /* Receive DMA Enable. */
+#define	 SIER_RIE	(1 << 21) /* Receive Interrupt Enable. */
+#define	 SIER_TDMAE	(1 << 20) /* Transmit DMA Enable. */
+#define	 SIER_TIE	(1 << 19) /* Transmit Interrupt Enable. */
+#define	 SIER_TDE0IE	(1 << 12) /* Transmit Data Register Empty 0. */
+#define	 SIER_TUE0IE	(1 << 8)  /* Transmitter Underrun Error 0. */
+#define	 SIER_TFE0IE	(1 << 0)  /* Transmit FIFO Empty 0 IE. */
+#define	SSI_STCR	0x1C	  /* Transmit Configuration Register */
+#define	 STCR_TXBIT0	(1 << 9)  /* Transmit Bit 0 shift MSB/LSB */
+#define	 STCR_TFEN1	(1 << 8)  /* Transmit FIFO Enable 1. */
+#define	 STCR_TFEN0	(1 << 7)  /* Transmit FIFO Enable 0. */
+#define	 STCR_TFDIR	(1 << 6)  /* Transmit Frame Direction. */
+#define	 STCR_TXDIR	(1 << 5)  /* Transmit Clock Direction. */
+#define	 STCR_TSHFD	(1 << 4)  /* Transmit Shift Direction. */
+#define	 STCR_TSCKP	(1 << 3)  /* Transmit Clock Polarity. */
+#define	 STCR_TFSI	(1 << 2)  /* Transmit Frame Sync Invert. */
+#define	 STCR_TFSL	(1 << 1)  /* Transmit Frame Sync Length. */
+#define	 STCR_TEFS	(1 << 0)  /* Transmit Early Frame Sync. */
+#define	SSI_SRCR	0x20      /* Receive Configuration Register */
+#define	SSI_STCCR	0x24      /* Transmit Clock Control Register */
+#define	 STCCR_DIV2	(1 << 18) /* Divide By 2. */
+#define	 STCCR_PSR	(1 << 17) /* Divide clock by 8. */
+#define	 WL3_WL0_S	13
+#define	 WL3_WL0_M	0xf
+#define	 DC4_DC0_S	8
+#define	 DC4_DC0_M	0x1f
+#define	 PM7_PM0_S	0
+#define	 PM7_PM0_M	0xff
+#define	SSI_SRCCR	0x28	/* Receive Clock Control Register */
+#define	SSI_SFCSR	0x2C	/* FIFO Control/Status Register */
+#define	 SFCSR_RFWM1_S	20	/* Receive FIFO Empty WaterMark 1 */
+#define	 SFCSR_RFWM1_M	0xf
+#define	 SFCSR_TFWM1_S	16	/* Transmit FIFO Empty WaterMark 1 */
+#define	 SFCSR_TFWM1_M	0xf
+#define	 SFCSR_RFWM0_S	4	/* Receive FIFO Empty WaterMark 0 */
+#define	 SFCSR_RFWM0_M	0xf
+#define	 SFCSR_TFWM0_S	0	/* Transmit FIFO Empty WaterMark 0 */
+#define	 SFCSR_TFWM0_M	0xf
+#define	SSI_SACNT	0x38	/* AC97 Control Register */
+#define	SSI_SACADD	0x3C	/* AC97 Command Address Register */
+#define	SSI_SACDAT	0x40	/* AC97 Command Data Register */
+#define	SSI_SATAG	0x44	/* AC97 Tag Register */
+#define	SSI_STMSK	0x48	/* Transmit Time Slot Mask Register */
+#define	SSI_SRMSK	0x4C	/* Receive Time Slot Mask Register */
+#define	SSI_SACCST	0x50	/* AC97 Channel Status Register */
+#define	SSI_SACCEN	0x54	/* AC97 Channel Enable Register */
+#define	SSI_SACCDIS	0x58	/* AC97 Channel Disable Register */
+
+static MALLOC_DEFINE(M_SSI, "ssi", "ssi audio");
+
+uint32_t ssi_dma_intr(void *arg, int chn);
+
+struct ssi_rate {
+	uint32_t speed;
+	uint32_t mfi; /* PLL4 Multiplication Factor Integer */
+	uint32_t mfn; /* PLL4 Multiplication Factor Numerator */
+	uint32_t mfd; /* PLL4 Multiplication Factor Denominator */
+	/* More dividers to configure can be added here */
+};
+
+static struct ssi_rate rate_map[] = {
+	{ 192000, 49, 152, 1000 }, /* PLL4 49.152 Mhz */
+	/* TODO: add more frequences */
+	{ 0, 0 },
+};
+
+/*
+ *  i.MX6 example bit clock formula
+ *
+ *  BCLK = 2 channels * 192000 hz * 24 bit = 9216000 hz = 
+ *     (24000000 * (49 + 152/1000.0) / 4 / 4 / 2 / 2 / 2 / 1 / 1)
+ *             ^     ^     ^      ^    ^   ^   ^   ^   ^   ^   ^
+ *             |     |     |      |    |   |   |   |   |   |   |
+ *  Fref ------/     |     |      |    |   |   |   |   |   |   |
+ *  PLL4 div select -/     |      |    |   |   |   |   |   |   |
+ *  PLL4 num --------------/      |    |   |   |   |   |   |   |
+ *  PLL4 denom -------------------/    |   |   |   |   |   |   |
+ *  PLL4 post div ---------------------/   |   |   |   |   |   |
+ *  CCM ssi pre div (CCM_CS1CDR) ----------/   |   |   |   |   |
+ *  CCM ssi post div (CCM_CS1CDR) -------------/   |   |   |   |
+ *  SSI PM7_PM0_S ---------------------------------/   |   |   |
+ *  SSI Fixed divider ---------------------------------/   |   |
+ *  SSI DIV2 ----------------------------------------------/   |
+ *  SSI PSR (prescaler /1 or /8) ------------------------------/
+ *
+ *  MCLK (Master clock) depends on DAC, usually BCLK * 4
+ */
+
+struct sc_info {
+	struct resource		*res[2];
+	bus_space_tag_t		bst;
+	bus_space_handle_t	bsh;
+	device_t		dev;
+	struct mtx		*lock;
+	void			*ih;
+	int			pos;
+	int			dma_size;
+	bus_dma_tag_t		dma_tag;
+	bus_dmamap_t		dma_map;
+	bus_addr_t		buf_base_phys;
+	uint32_t		*buf_base;
+	struct sdma_conf	*conf;
+	struct ssi_rate		*sr;
+	struct sdma_softc	*sdma_sc;
+	int			sdma_ev_rx;
+	int			sdma_ev_tx;
+	int			sdma_channel;
+};
+
+/* Channel registers */
+struct sc_chinfo {
+	struct snd_dbuf		*buffer;
+	struct pcm_channel	*channel;
+	struct sc_pcminfo	*parent;
+
+	/* Channel information */
+	uint32_t	dir;
+	uint32_t	format;
+
+	/* Flags */
+	uint32_t	run;
+};
+
+/* PCM device private data */
+struct sc_pcminfo {
+	device_t		dev;
+	uint32_t		(*ih)(struct sc_pcminfo *scp);
+	uint32_t		chnum;
+	struct sc_chinfo	chan[SSI_NCHANNELS];
+	struct sc_info		*sc;
+};
+
+static struct resource_spec ssi_spec[] = {
+	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		0,	RF_ACTIVE },
+	{ -1, 0 }
+};
+
+static int setup_dma(struct sc_pcminfo *scp);
+static void setup_ssi(struct sc_info *);
+static void ssi_configure_clock(struct sc_info *);
+
+/*
+ * Mixer interface.
+ */
+
+static int
+ssimixer_init(struct snd_mixer *m)
+{
+	struct sc_pcminfo *scp;
+	struct sc_info *sc;
+	int mask;
+
+	scp = mix_getdevinfo(m);
+	sc = scp->sc;
+
+	if (sc == NULL)
+		return -1;
+
+	mask = SOUND_MASK_PCM;
+	mask |= SOUND_MASK_VOLUME;
+
+	snd_mtxlock(sc->lock);
+	pcm_setflags(scp->dev, pcm_getflags(scp->dev) | SD_F_SOFTPCMVOL);
+	mix_setdevs(m, mask);
+	snd_mtxunlock(sc->lock);
+
+	return (0);
+}
+
+static int
+ssimixer_set(struct snd_mixer *m, unsigned dev,
+    unsigned left, unsigned right)
+{
+	struct sc_pcminfo *scp;
+
+	scp = mix_getdevinfo(m);
+
+	/* Here we can configure hardware volume on our DAC */
+
+#if 1
+	device_printf(scp->dev, "ssimixer_set() %d %d\n",
+	    left, right);
+#endif
+
+	return (0);
+}
+
+static kobj_method_t ssimixer_methods[] = {
+	KOBJMETHOD(mixer_init,      ssimixer_init),
+	KOBJMETHOD(mixer_set,       ssimixer_set),
+	KOBJMETHOD_END
+};
+MIXER_DECLARE(ssimixer);
+
+
+/*
+ * Channel interface.
+ */
+
+static void *
+ssichan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b,
+    struct pcm_channel *c, int dir)
+{
+	struct sc_pcminfo *scp;
+	struct sc_chinfo *ch;
+	struct sc_info *sc;
+
+	scp = (struct sc_pcminfo *)devinfo;
+	sc = scp->sc;
+
+	snd_mtxlock(sc->lock);
+	ch = &scp->chan[0];
+	ch->dir = dir;
+	ch->run = 0;
+	ch->buffer = b;
+	ch->channel = c;
+	ch->parent = scp;
+	snd_mtxunlock(sc->lock);
+
+	if (sndbuf_setup(ch->buffer, sc->buf_base, sc->dma_size) != 0) {
+		device_printf(scp->dev, "Can't setup sndbuf.\n");
+		return NULL;
+	}
+
+	return ch;
+}
+
+static int
+ssichan_free(kobj_t obj, void *data)
+{
+	struct sc_chinfo *ch = data;
+	struct sc_pcminfo *scp = ch->parent;
+	struct sc_info *sc = scp->sc;
+
+#if 0
+	device_printf(scp->dev, "ssichan_free()\n");
+#endif
+
+	snd_mtxlock(sc->lock);
+	/* TODO: free channel buffer */
+	snd_mtxunlock(sc->lock);
+
+	return (0);
+}
+
+static int
+ssichan_setformat(kobj_t obj, void *data, uint32_t format)
+{
+	struct sc_chinfo *ch = data;
+
+	ch->format = format;
+
+	return (0);
+}
+
+static uint32_t
+ssichan_setspeed(kobj_t obj, void *data, uint32_t speed)
+{
+	struct sc_pcminfo *scp;
+	struct sc_chinfo *ch;
+	struct ssi_rate *sr;
+	struct sc_info *sc;
+	int threshold;
+	int i;
+
+	ch = data;
+	scp = ch->parent;
+	sc = scp->sc;
+
+	sr = NULL;
+
+	/* First look for equal frequency. */
+	for (i = 0; rate_map[i].speed != 0; i++) {
+		if (rate_map[i].speed == speed)
+			sr = &rate_map[i];
+	}
+
+	/* If no match, just find nearest. */
+	if (sr == NULL) {
+		for (i = 0; rate_map[i].speed != 0; i++) {
+			sr = &rate_map[i];
+			threshold = sr->speed + ((rate_map[i + 1].speed != 0) ?
+			    ((rate_map[i + 1].speed - sr->speed) >> 1) : 0);
+			if (speed < threshold)
+				break;
+		}
+	}
+
+	sc->sr = sr;
+
+	ssi_configure_clock(sc);
+
+	return (sr->speed);
+}
+
+static void
+ssi_configure_clock(struct sc_info *sc)
+{
+	struct ssi_rate *sr;
+
+	sr = sc->sr;
+
+	pll4_configure_output(sr->mfi, sr->mfn, sr->mfd);
+
+	/* Configure other dividers here, if any */
+}
+
+static uint32_t
+ssichan_setblocksize(kobj_t obj, void *data, uint32_t blocksize)
+{
+	struct sc_chinfo *ch = data;
+	struct sc_pcminfo *scp = ch->parent;
+	struct sc_info *sc = scp->sc;
+
+	sndbuf_resize(ch->buffer, sc->dma_size / blocksize, blocksize);
+
+	setup_dma(scp);
+
+	return (sndbuf_getblksz(ch->buffer));
+}
+
+uint32_t
+ssi_dma_intr(void *arg, int chn)
+{
+	struct sc_pcminfo *scp;
+	struct sdma_conf *conf;
+	struct sc_chinfo *ch;
+	struct sc_info *sc;
+	int bufsize;
+
+	scp = arg;
+	ch = &scp->chan[0];
+	sc = scp->sc;
+	conf = sc->conf;
+
+	bufsize = sndbuf_getsize(ch->buffer);
+
+	sc->pos += conf->period;
+	if (sc->pos >= bufsize)
+		sc->pos -= bufsize;
+
+	if (ch->run)
+		chn_intr(ch->channel);
+
+	return (0);
+}
+
+static int
+find_sdma_controller(struct sc_info *sc)
+{
+	struct sdma_softc *sdma_sc;
+	phandle_t node, sdma_node;
+	device_t sdma_dev;
+	int dts_value[8];
+	int len;
+
+	if ((node = ofw_bus_get_node(sc->dev)) == -1)
+		return (ENXIO);
+
+	if ((len = OF_getproplen(node, "dmas")) <= 0)
+		return (ENXIO);
+
+	OF_getprop(node, "dmas", &dts_value, len);
+
+	sc->sdma_ev_rx = fdt32_to_cpu(dts_value[1]);
+	sc->sdma_ev_tx = fdt32_to_cpu(dts_value[5]);
+
+	sdma_node = OF_node_from_xref(fdt32_to_cpu(dts_value[0]));
+
+	sdma_sc = NULL;
+
+	sdma_dev = devclass_get_device(devclass_find("sdma"), 0);
+	if (sdma_dev)
+		sdma_sc = device_get_softc(sdma_dev);
+
+	if (sdma_sc == NULL) {
+		device_printf(sc->dev, "No sDMA found. Can't operate\n");
+		return (ENXIO);
+	};
+
+	sc->sdma_sc = sdma_sc;
+
+	return (0);
+};
+
+static int
+setup_dma(struct sc_pcminfo *scp)
+{
+	struct sdma_conf *conf;
+	struct sc_chinfo *ch;
+	struct sc_info *sc;
+	int fmt;
+
+	ch = &scp->chan[0];
+	sc = scp->sc;
+	conf = sc->conf;
+
+	conf->ih = ssi_dma_intr;
+	conf->ih_user = scp;
+	conf->saddr = sc->buf_base_phys;
+	conf->daddr = rman_get_start(sc->res[0]) + SSI_STX0;
+	conf->event = sc->sdma_ev_tx; /* SDMA TX event */
+	conf->period = sndbuf_getblksz(ch->buffer);
+	conf->num_bd = sndbuf_getblkcnt(ch->buffer);
+
+	/*
+	 * Word Length
+	 * Can be 32, 24, 16 or 8 for sDMA.
+	 *
+	 * SSI supports 24 at max.
+	 */
+
+	fmt = sndbuf_getfmt(ch->buffer);
+
+	if (fmt & AFMT_16BIT) {
+		conf->word_length = 16;
+		conf->command = CMD_2BYTES;
+	} else if (fmt & AFMT_24BIT) {
+		conf->word_length = 24;
+		conf->command = CMD_3BYTES;
+	} else {
+		device_printf(sc->dev, "Unknown format\n");
+		return (-1);
+	}
+
+	return (0);
+}
+
+static int
+ssi_start(struct sc_pcminfo *scp)
+{
+	struct sc_info *sc;
+	int reg;
+
+	sc = scp->sc;
+
+	if (sdma_configure(sc->sdma_channel, sc->conf) != 0) {
+		device_printf(sc->dev, "Can't configure sDMA\n");
+		return (-1);
+	}
+
+	/* Enable DMA interrupt */
+	reg = (SIER_TDMAE);
+	WRITE4(sc, SSI_SIER, reg);
+
+	sdma_start(sc->sdma_channel);
+
+	return (0);
+}
+
+static int
+ssi_stop(struct sc_pcminfo *scp)
+{
+	struct sc_info *sc;
+	int reg;
+
+	sc = scp->sc;
+
+	reg = READ4(sc, SSI_SIER);
+	reg &= ~(SIER_TDMAE);
+	WRITE4(sc, SSI_SIER, reg);
+
+	sdma_stop(sc->sdma_channel);
+
+	bzero(sc->buf_base, sc->dma_size);
+
+	return (0);
+}
+
+static int
+ssichan_trigger(kobj_t obj, void *data, int go)
+{
+	struct sc_pcminfo *scp;
+	struct sc_chinfo *ch;
+	struct sc_info *sc;
+
+	ch = data;
+	scp = ch->parent;
+	sc = scp->sc;
+
+	snd_mtxlock(sc->lock);
+
+	switch (go) {
+	case PCMTRIG_START:
+#if 0
+		device_printf(scp->dev, "trigger start\n");
+#endif
+		ch->run = 1;
+
+		ssi_start(scp);
+
+		break;
+
+	case PCMTRIG_STOP:
+	case PCMTRIG_ABORT:
+#if 0
+		device_printf(scp->dev, "trigger stop or abort\n");
+#endif
+		ch->run = 0;
+
+		ssi_stop(scp);
+
+		break;
+	}
+
+	snd_mtxunlock(sc->lock);
+
+	return (0);
+}
+
+static uint32_t
+ssichan_getptr(kobj_t obj, void *data)
+{
+	struct sc_pcminfo *scp;
+	struct sc_chinfo *ch;
+	struct sc_info *sc;
+
+	ch = data;
+	scp = ch->parent;
+	sc = scp->sc;
+
+	return (sc->pos);
+}
+
+static uint32_t ssi_pfmt[] = {
+	SND_FORMAT(AFMT_S24_LE, 2, 0),
+	0
+};
+
+static struct pcmchan_caps ssi_pcaps = {44100, 192000, ssi_pfmt, 0};
+
+static struct pcmchan_caps *
+ssichan_getcaps(kobj_t obj, void *data)
+{
+
+	return (&ssi_pcaps);
+}
+
+static kobj_method_t ssichan_methods[] = {
+	KOBJMETHOD(channel_init,         ssichan_init),
+	KOBJMETHOD(channel_free,         ssichan_free),
+	KOBJMETHOD(channel_setformat,    ssichan_setformat),
+	KOBJMETHOD(channel_setspeed,     ssichan_setspeed),
+	KOBJMETHOD(channel_setblocksize, ssichan_setblocksize),
+	KOBJMETHOD(channel_trigger,      ssichan_trigger),
+	KOBJMETHOD(channel_getptr,       ssichan_getptr),
+	KOBJMETHOD(channel_getcaps,      ssichan_getcaps),
+	KOBJMETHOD_END
+};
+CHANNEL_DECLARE(ssichan);
+
+static int
+ssi_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "fsl,imx6q-ssi"))
+		return (ENXIO);
+
+	device_set_desc(dev, "i.MX6 Synchronous Serial Interface (SSI)");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static void
+ssi_intr(void *arg)
+{
+	struct sc_pcminfo *scp;
+	struct sc_chinfo *ch;
+	struct sc_info *sc;
+
+	scp = arg;
+	sc = scp->sc;
+	ch = &scp->chan[0];
+
+	/* We don't use SSI interrupt */
+#if 0
+	device_printf(sc->dev, "SSI Intr 0x%08x\n",
+	    READ4(sc, SSI_SISR));
+#endif
+}
+
+static void
+setup_ssi(struct sc_info *sc)
+{
+	int reg;
+
+	reg = READ4(sc, SSI_STCCR);
+	reg &= ~(WL3_WL0_M << WL3_WL0_S);
+	reg |= (0xb << WL3_WL0_S); /* 24 bit */
+	reg &= ~(DC4_DC0_M << DC4_DC0_S);
+	reg |= (1 << DC4_DC0_S); /* 2 words per frame */
+	reg &= ~(STCCR_DIV2); /* Divide by 1 */
+	reg &= ~(STCCR_PSR); /* Divide by 1 */
+	reg &= ~(PM7_PM0_M << PM7_PM0_S);
+	reg |= (1 << PM7_PM0_S); /* Divide by 2 */
+	WRITE4(sc, SSI_STCCR, reg);
+
+	reg = READ4(sc, SSI_SFCSR);
+	reg &= ~(SFCSR_TFWM0_M << SFCSR_TFWM0_S);
+	reg |= (8 << SFCSR_TFWM0_S); /* empty slots */
+	WRITE4(sc, SSI_SFCSR, reg);
+
+	reg = READ4(sc, SSI_STCR);
+	reg |= (STCR_TFEN0);
+	reg &= ~(STCR_TFEN1);
+	reg &= ~(STCR_TSHFD); /* MSB */
+	reg |= (STCR_TXBIT0);
+	reg |= (STCR_TXDIR | STCR_TFDIR);
+	reg |= (STCR_TSCKP); /* falling edge */
+	reg |= (STCR_TFSI);
+	reg &= ~(STCR_TFSI); /* active high frame sync */
+	reg &= ~(STCR_TFSL);
+	reg |= STCR_TEFS;
+	WRITE4(sc, SSI_STCR, reg);
+
+	reg = READ4(sc, SSI_SCR);
+	reg &= ~(SCR_I2S_MODE_M << SCR_I2S_MODE_S); /* Not master */
+	reg |= (SCR_SSIEN | SCR_TE);
+	reg |= (SCR_NET);
+	reg |= (SCR_SYN);
+	WRITE4(sc, SSI_SCR, reg);
+}
+
+static void
+ssi_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int err)
+{
+	bus_addr_t *addr;
+
+	if (err)
+		return;
+
+	addr = (bus_addr_t*)arg;
+	*addr = segs[0].ds_addr;
+}
+
+static int
+ssi_attach(device_t dev)
+{
+	char status[SND_STATUSLEN];
+	struct sc_pcminfo *scp;
+	struct sc_info *sc;
+	int err;
+
+	sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO);
+	sc->dev = dev;
+	sc->sr = &rate_map[0];
+	sc->pos = 0;
+	sc->conf = malloc(sizeof(struct sdma_conf), M_DEVBUF, M_WAITOK | M_ZERO);
+
+	sc->lock = snd_mtxcreate(device_get_nameunit(dev), "ssi softc");
+	if (sc->lock == NULL) {
+		device_printf(dev, "Cant create mtx\n");
+		return (ENXIO);
+	}
+
+	if (bus_alloc_resources(dev, ssi_spec, sc->res)) {
+		device_printf(dev, "could not allocate resources\n");
+		return (ENXIO);
+	}
+
+	/* Memory interface */
+	sc->bst = rman_get_bustag(sc->res[0]);
+	sc->bsh = rman_get_bushandle(sc->res[0]);
+
+	/* SDMA */
+	if (find_sdma_controller(sc)) {
+		device_printf(dev, "could not find active SDMA\n");
+		return (ENXIO);
+	}
+
+	/* Setup PCM */
+	scp = malloc(sizeof(struct sc_pcminfo), M_DEVBUF, M_NOWAIT | M_ZERO);
+	scp->sc = sc;
+	scp->dev = dev;
+
+	/*
+	 * Maximum possible DMA buffer.
+	 * Will be used partialy to match 24 bit word.
+	 */
+	sc->dma_size = 131072;
+
+	/*
+	 * Must use dma_size boundary as modulo feature required.
+	 * Modulo feature allows setup circular buffer.
+	 */
+
+	err = bus_dma_tag_create(
+	    bus_get_dma_tag(sc->dev),
+	    4, sc->dma_size,		/* alignment, boundary */
+	    BUS_SPACE_MAXADDR_32BIT,	/* lowaddr */
+	    BUS_SPACE_MAXADDR,		/* highaddr */
+	    NULL, NULL,			/* filter, filterarg */
+	    sc->dma_size, 1,		/* maxsize, nsegments */
+	    sc->dma_size, 0,		/* maxsegsize, flags */
+	    NULL, NULL,			/* lockfunc, lockarg */
+	    &sc->dma_tag);
+
+	err = bus_dmamem_alloc(sc->dma_tag, (void **)&sc->buf_base,
+	    BUS_DMA_NOWAIT | BUS_DMA_COHERENT, &sc->dma_map);
+	if (err) {
+		device_printf(dev, "cannot allocate framebuffer\n");
+		return (ENXIO);
+	}
+
+	err = bus_dmamap_load(sc->dma_tag, sc->dma_map, sc->buf_base,
+	    sc->dma_size, ssi_dmamap_cb, &sc->buf_base_phys, BUS_DMA_NOWAIT);
+	if (err) {
+		device_printf(dev, "cannot load DMA map\n");
+		return (ENXIO);
+	}
+
+	bzero(sc->buf_base, sc->dma_size);
+
+	/* Setup interrupt handler */
+	err = bus_setup_intr(dev, sc->res[1], INTR_MPSAFE | INTR_TYPE_AV,
+	    NULL, ssi_intr, scp, &sc->ih);
+	if (err) {
+		device_printf(dev, "Unable to alloc interrupt resource.\n");
+		return (ENXIO);
+	}
+
+	pcm_setflags(dev, pcm_getflags(dev) | SD_F_MPSAFE);
+
+	err = pcm_register(dev, scp, 1, 0);
+	if (err) {
+		device_printf(dev, "Can't register pcm.\n");
+		return (ENXIO);
+	}
+
+	scp->chnum = 0;
+	pcm_addchan(dev, PCMDIR_PLAY, &ssichan_class, scp);
+	scp->chnum++;
+
+	snprintf(status, SND_STATUSLEN, "at simplebus");
+	pcm_setstatus(dev, status);
+
+	mixer_init(dev, &ssimixer_class, scp);
+	setup_ssi(sc);
+
+	imx_ccm_ssi_configure(dev);
+
+	sc->sdma_channel = sdma_alloc();
+	if (sc->sdma_channel < 0) {
+		device_printf(sc->dev, "Can't get sDMA channel\n");
+		return (1);
+	}
+
+	return (0);
+}
+
+static device_method_t ssi_pcm_methods[] = {
+	DEVMETHOD(device_probe,		ssi_probe),
+	DEVMETHOD(device_attach,	ssi_attach),
+	{ 0, 0 }
+};
+
+static driver_t ssi_pcm_driver = {
+	"pcm",
+	ssi_pcm_methods,
+	PCM_SOFTC_SIZE,
+};
+
+DRIVER_MODULE(ssi, simplebus, ssi_pcm_driver, pcm_devclass, 0, 0);
+MODULE_DEPEND(ssi, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER);
+MODULE_VERSION(ssi, 1);


Property changes on: trunk/sys/arm/freescale/imx/imx6_ssi.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/imx/imx6_usbphy.c
===================================================================
--- trunk/sys/arm/freescale/imx/imx6_usbphy.c	                        (rev 0)
+++ trunk/sys/arm/freescale/imx/imx6_usbphy.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,193 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Ian Lepore <ian at freebsd.org>
+ * 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: stable/10/sys/arm/freescale/imx/imx6_usbphy.c 266371 2014-05-17 22:29:24Z ian $");
+
+/*
+ * USBPHY driver for Freescale i.MX6 family of SoCs.
+ */
+
+#include "opt_bus.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/rman.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+
+#include <arm/freescale/imx/imx_ccmvar.h>
+#include <arm/freescale/imx/imx6_anatopreg.h>
+#include <arm/freescale/imx/imx6_anatopvar.h>
+
+/*
+ * Hardware register defines.
+ */
+#define	PWD_REG				0x0000
+#define	CTRL_STATUS_REG			0x0030
+#define	CTRL_SET_REG			0x0034
+#define	CTRL_CLR_REG			0x0038
+#define	CTRL_TOGGLE_REG			0x003c
+#define	  CTRL_SFTRST			  (1U << 31)
+#define	  CTRL_CLKGATE			  (1 << 30)
+#define	  CTRL_ENUTMILEVEL3		  (1 << 15)
+#define	  CTRL_ENUTMILEVEL2		  (1 << 14)
+
+struct usbphy_softc {
+	device_t	dev;
+	struct resource	*mem_res;
+	u_int		phy_num;
+};
+
+static int
+usbphy_detach(device_t dev)
+{
+	struct usbphy_softc *sc;
+
+	sc = device_get_softc(dev);
+
+	if (sc->mem_res != NULL)
+		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->mem_res);
+
+	return (0);
+}
+
+static int
+usbphy_attach(device_t dev)
+{
+	struct usbphy_softc *sc;
+	int err, regoff, rid;
+
+	sc = device_get_softc(dev);
+	err = 0;
+
+	/* Allocate bus_space resources. */
+	rid = 0;
+	sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	    RF_ACTIVE);
+	if (sc->mem_res == NULL) {
+		device_printf(dev, "Cannot allocate memory resources\n");
+		err = ENXIO;
+		goto out;
+	}
+
+	/*
+	 * XXX Totally lame way to get the unit number (but not quite as lame as
+	 * adding an ad-hoc property to the fdt data).  This works as long as
+	 * this driver is used for imx6 only.
+	 */
+	const uint32_t PWD_PHY1_REG_PHYSADDR = 0x020c9000;
+	if (BUS_SPACE_PHYSADDR(sc->mem_res, 0) == PWD_PHY1_REG_PHYSADDR) {
+		sc->phy_num = 0;
+		regoff = 0;
+	} else {
+		sc->phy_num = 1;
+		regoff = 0x60;
+	}
+
+	/*
+	 * Based on a note in the u-boot source code, disable charger detection
+	 * to avoid degrading the differential signaling on the DP line.  Note
+	 * that this disables (by design) both charger detection and contact
+	 * detection, because of the screwball mix of active-high and active-low
+	 * bits in this register.
+	 */
+	imx6_anatop_write_4(IMX6_ANALOG_USB1_CHRG_DETECT + regoff, 
+	    IMX6_ANALOG_USB_CHRG_DETECT_N_ENABLE | 
+	    IMX6_ANALOG_USB_CHRG_DETECT_N_CHK_CHRG);
+
+	imx6_anatop_write_4(IMX6_ANALOG_USB1_CHRG_DETECT + regoff, 
+	    IMX6_ANALOG_USB_CHRG_DETECT_N_ENABLE | 
+	    IMX6_ANALOG_USB_CHRG_DETECT_N_CHK_CHRG);
+
+	/* XXX Configure the overcurrent detection here. */
+
+	/*
+	 * Turn on the phy clocks.
+	 */
+	imx_ccm_usbphy_enable(dev);
+
+	/*
+	 * Set the software reset bit, then clear both it and the clock gate bit
+	 * to bring the device out of reset with the clock running.
+	 */
+	bus_write_4(sc->mem_res, CTRL_SET_REG, CTRL_SFTRST);
+	bus_write_4(sc->mem_res, CTRL_CLR_REG, CTRL_SFTRST | CTRL_CLKGATE);
+
+	/* Power up: clear all bits in the powerdown register. */
+	bus_write_4(sc->mem_res, PWD_REG, 0);
+
+	err = 0;
+
+out:
+
+	if (err != 0)
+		usbphy_detach(dev);
+
+	return (err);
+}
+
+static int
+usbphy_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (ofw_bus_is_compatible(dev, "fsl,imx6q-usbphy") == 0)
+		return (ENXIO);
+
+	device_set_desc(dev, "Freescale i.MX6 USB PHY");
+
+	return (BUS_PROBE_DEFAULT);
+}
+
+static device_method_t usbphy_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,  usbphy_probe),
+	DEVMETHOD(device_attach, usbphy_attach),
+	DEVMETHOD(device_detach, usbphy_detach),
+
+	DEVMETHOD_END
+};
+
+static driver_t usbphy_driver = {
+	"usbphy",
+	usbphy_methods,
+	sizeof(struct usbphy_softc)
+};
+
+static devclass_t usbphy_devclass;
+
+DRIVER_MODULE(usbphy, simplebus, usbphy_driver, usbphy_devclass, 0, 0);
+


Property changes on: trunk/sys/arm/freescale/imx/imx6_usbphy.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/imx/imx_ccmvar.h
===================================================================
--- trunk/sys/arm/freescale/imx/imx_ccmvar.h	                        (rev 0)
+++ trunk/sys/arm/freescale/imx/imx_ccmvar.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,61 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014 Ian Lepore <ian at freebsd.org>
+ * 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: stable/10/sys/arm/freescale/imx/imx_ccmvar.h 283501 2015-05-24 19:00:46Z ian $
+ */
+
+#ifndef	IMX_CCMVAR_H
+#define	IMX_CCMVAR_H
+
+/*
+ * We need a clock management system that works across unrelated SoCs and
+ * devices.  For now, to keep imx development moving, define some barebones
+ * functionality that can be shared within the imx family by having each SoC
+ * implement functions with a common name.
+ *
+ * The usb enable functions are best-effort.  They turn on the usb otg, host,
+ * and phy clocks in a SoC-specific manner, but it may take a lot more than that
+ * to make usb work on a given board.  In particular, it can require specific
+ * pinmux setup of gpio pins connected to external phy parts, voltage regulators
+ * and overcurrent detectors, and so on.  On such boards, u-boot or other early
+ * board setup code has to handle those things.
+ */
+
+uint32_t imx_ccm_ipg_hz(void);
+uint32_t imx_ccm_perclk_hz(void);
+uint32_t imx_ccm_sdhci_hz(void);
+uint32_t imx_ccm_uart_hz(void);
+uint32_t imx_ccm_ahb_hz(void);
+
+void imx_ccm_usb_enable(device_t _usbdev);
+void imx_ccm_usbphy_enable(device_t _phydev);
+void imx_ccm_ssi_configure(device_t _ssidev);
+
+/* Routines to get and set the arm clock root divisor register. */
+uint32_t imx_ccm_get_cacrr(void);
+void     imx_ccm_set_cacrr(uint32_t _divisor);
+
+#endif


Property changes on: trunk/sys/arm/freescale/imx/imx_ccmvar.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/imx/imx_common.c
===================================================================
--- trunk/sys/arm/freescale/imx/imx_common.c	                        (rev 0)
+++ trunk/sys/arm/freescale/imx/imx_common.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,76 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (C) 2008-2011 MARVELL INTERNATIONAL LTD.
+ * Copyright (c) 2012, 2013 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * Developed by Semihalf.
+ *
+ * Portions of this software were developed by Oleksandr Rybalko
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * 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.
+ * 3. Neither the name of MARVELL nor the names of contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY 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 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_global.h"
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/freescale/imx/imx_common.c 266277 2014-05-17 00:53:12Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/kdb.h>
+#include <sys/reboot.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+#include <machine/vmparam.h>
+
+struct fdt_fixup_entry fdt_fixup_table[] = {
+	{ NULL, NULL }
+};
+
+static int
+fdt_intc_decode_ic(phandle_t node, pcell_t *intr, int *interrupt, int *trig,
+    int *pol)
+{
+
+	*interrupt = fdt32_to_cpu(intr[0]);
+	*trig = INTR_TRIGGER_CONFORM;
+	*pol = INTR_POLARITY_CONFORM;
+
+	return (0);
+}
+
+fdt_pic_decode_t fdt_pic_table[] = {
+	&fdt_intc_decode_ic,
+	NULL
+};


Property changes on: trunk/sys/arm/freescale/imx/imx_common.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/imx/imx_gpio.c
===================================================================
--- trunk/sys/arm/freescale/imx/imx_gpio.c	                        (rev 0)
+++ trunk/sys/arm/freescale/imx/imx_gpio.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,482 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012, 2013 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Oleksandr Rybalko under sponsorship
+ * from the FreeBSD Foundation.
+ *
+ * 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.
+ */
+
+/*
+ * Freescale i.MX515 GPIO driver.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/freescale/imx/imx_gpio.c 278786 2015-02-14 21:16:19Z loos $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/rman.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/gpio.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include "gpio_if.h"
+
+#define GPIO_LOCK(_sc)		mtx_lock(&(_sc)->sc_mtx)
+#define	GPIO_UNLOCK(_sc)	mtx_unlock(&(_sc)->sc_mtx)
+#define GPIO_LOCK_INIT(_sc)	mtx_init(&_sc->sc_mtx, 			\
+	    device_get_nameunit(_sc->sc_dev), "imx_gpio", MTX_DEF)
+#define GPIO_LOCK_DESTROY(_sc)	mtx_destroy(&_sc->sc_mtx);
+#define GPIO_ASSERT_LOCKED(_sc)	mtx_assert(&_sc->sc_mtx, MA_OWNED);
+#define GPIO_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED);
+
+#define	WRITE4(_sc, _r, _v)						\
+	    bus_space_write_4((_sc)->sc_iot, (_sc)->sc_ioh, (_r), (_v))
+#define	READ4(_sc, _r)							\
+	    bus_space_read_4((_sc)->sc_iot, (_sc)->sc_ioh, (_r))
+#define	SET4(_sc, _r, _m)						\
+	    WRITE4((_sc), (_r), READ4((_sc), (_r)) | (_m))
+#define	CLEAR4(_sc, _r, _m)						\
+	    WRITE4((_sc), (_r), READ4((_sc), (_r)) & ~(_m))
+
+/* Registers definition for Freescale i.MX515 GPIO controller */
+
+#define	IMX_GPIO_DR_REG		0x000 /* Pin Data */
+#define	IMX_GPIO_OE_REG		0x004 /* Set Pin Output */
+#define	IMX_GPIO_PSR_REG	0x008 /* Pad Status */
+#define	IMX_GPIO_ICR1_REG	0x00C /* Interrupt Configuration */
+#define	IMX_GPIO_ICR2_REG	0x010 /* Interrupt Configuration */
+#define		GPIO_ICR_COND_LOW	0
+#define		GPIO_ICR_COND_HIGH	1
+#define		GPIO_ICR_COND_RISE	2
+#define		GPIO_ICR_COND_FALL	3
+#define	IMX_GPIO_IMR_REG	0x014 /* Interrupt Mask Register */
+#define	IMX_GPIO_ISR_REG	0x018 /* Interrupt Status Register */
+#define	IMX_GPIO_EDGE_REG	0x01C /* Edge Detect Register */
+
+#define	DEFAULT_CAPS	(GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)
+#define	NGPIO		32
+
+struct imx51_gpio_softc {
+	device_t		dev;
+	struct mtx		sc_mtx;
+	struct resource		*sc_res[11]; /* 1 x mem, 2 x IRQ, 8 x IRQ */
+	void			*gpio_ih[11]; /* 1 ptr is not a big waste */
+	int			sc_l_irq; /* Last irq resource */
+	bus_space_tag_t		sc_iot;
+	bus_space_handle_t	sc_ioh;
+	int			gpio_npins;
+	struct gpio_pin		gpio_pins[NGPIO];
+};
+
+static struct ofw_compat_data compat_data[] = {
+	{"fsl,imx6q-gpio",  1},
+	{"fsl,imx53-gpio",  1},
+	{"fsl,imx51-gpio",  1},
+	{NULL,	            0}
+};
+
+static struct resource_spec imx_gpio_spec[] = {
+	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		0,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		1,	RF_ACTIVE },
+	{ -1, 0 }
+};
+
+static struct resource_spec imx_gpio0irq_spec[] = {
+	{ SYS_RES_IRQ,		2,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		3,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		4,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		5,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		6,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		7,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		8,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		9,	RF_ACTIVE },
+	{ -1, 0 }
+};
+
+/*
+ * Helpers
+ */
+static void imx51_gpio_pin_configure(struct imx51_gpio_softc *,
+    struct gpio_pin *, uint32_t);
+
+/*
+ * Driver stuff
+ */
+static int imx51_gpio_probe(device_t);
+static int imx51_gpio_attach(device_t);
+static int imx51_gpio_detach(device_t);
+static int imx51_gpio_intr(void *);
+
+/*
+ * GPIO interface
+ */
+static int imx51_gpio_pin_max(device_t, int *);
+static int imx51_gpio_pin_getcaps(device_t, uint32_t, uint32_t *);
+static int imx51_gpio_pin_getflags(device_t, uint32_t, uint32_t *);
+static int imx51_gpio_pin_getname(device_t, uint32_t, char *);
+static int imx51_gpio_pin_setflags(device_t, uint32_t, uint32_t);
+static int imx51_gpio_pin_set(device_t, uint32_t, unsigned int);
+static int imx51_gpio_pin_get(device_t, uint32_t, unsigned int *);
+static int imx51_gpio_pin_toggle(device_t, uint32_t pin);
+
+static void
+imx51_gpio_pin_configure(struct imx51_gpio_softc *sc, struct gpio_pin *pin,
+    unsigned int flags)
+{
+
+	GPIO_LOCK(sc);
+
+	/*
+	 * Manage input/output
+	 */
+	if (flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) {
+		pin->gp_flags &= ~(GPIO_PIN_INPUT|GPIO_PIN_OUTPUT);
+		if (flags & GPIO_PIN_OUTPUT) {
+			pin->gp_flags |= GPIO_PIN_OUTPUT;
+			SET4(sc, IMX_GPIO_OE_REG, (1 << pin->gp_pin));
+		}
+		else {
+			pin->gp_flags |= GPIO_PIN_INPUT;
+			CLEAR4(sc, IMX_GPIO_OE_REG, (1 << pin->gp_pin));
+		}
+	}
+
+	GPIO_UNLOCK(sc);
+}
+
+static int
+imx51_gpio_pin_max(device_t dev, int *maxpin)
+{
+
+	*maxpin = NGPIO - 1;
+	return (0);
+}
+
+static int
+imx51_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
+{
+	struct imx51_gpio_softc *sc;
+	int i;
+
+	sc = device_get_softc(dev);
+	for (i = 0; i < sc->gpio_npins; i++) {
+		if (sc->gpio_pins[i].gp_pin == pin)
+			break;
+	}
+
+	if (i >= sc->gpio_npins)
+		return (EINVAL);
+
+	GPIO_LOCK(sc);
+	*caps = sc->gpio_pins[i].gp_caps;
+	GPIO_UNLOCK(sc);
+
+	return (0);
+}
+
+static int
+imx51_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
+{
+	struct imx51_gpio_softc *sc;
+	int i;
+
+	sc = device_get_softc(dev);
+	for (i = 0; i < sc->gpio_npins; i++) {
+		if (sc->gpio_pins[i].gp_pin == pin)
+			break;
+	}
+
+	if (i >= sc->gpio_npins)
+		return (EINVAL);
+
+	GPIO_LOCK(sc);
+	*flags = sc->gpio_pins[i].gp_flags;
+	GPIO_UNLOCK(sc);
+
+	return (0);
+}
+
+static int
+imx51_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
+{
+	struct imx51_gpio_softc *sc;
+	int i;
+
+	sc = device_get_softc(dev);
+	for (i = 0; i < sc->gpio_npins; i++) {
+		if (sc->gpio_pins[i].gp_pin == pin)
+			break;
+	}
+
+	if (i >= sc->gpio_npins)
+		return (EINVAL);
+
+	GPIO_LOCK(sc);
+	memcpy(name, sc->gpio_pins[i].gp_name, GPIOMAXNAME);
+	GPIO_UNLOCK(sc);
+
+	return (0);
+}
+
+static int
+imx51_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
+{
+	struct imx51_gpio_softc *sc;
+	int i;
+
+	sc = device_get_softc(dev);
+	for (i = 0; i < sc->gpio_npins; i++) {
+		if (sc->gpio_pins[i].gp_pin == pin)
+			break;
+	}
+
+	if (i >= sc->gpio_npins)
+		return (EINVAL);
+
+	imx51_gpio_pin_configure(sc, &sc->gpio_pins[i], flags);
+
+	return (0);
+}
+
+static int
+imx51_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value)
+{
+	struct imx51_gpio_softc *sc;
+	int i;
+
+	sc = device_get_softc(dev);
+	for (i = 0; i < sc->gpio_npins; i++) {
+		if (sc->gpio_pins[i].gp_pin == pin)
+			break;
+	}
+
+	if (i >= sc->gpio_npins)
+		return (EINVAL);
+
+	GPIO_LOCK(sc);
+	if (value)
+		SET4(sc, IMX_GPIO_DR_REG, (1 << i));
+	else
+		CLEAR4(sc, IMX_GPIO_DR_REG, (1 << i));
+	GPIO_UNLOCK(sc);
+
+	return (0);
+}
+
+static int
+imx51_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val)
+{
+	struct imx51_gpio_softc *sc;
+	int i;
+
+	sc = device_get_softc(dev);
+	for (i = 0; i < sc->gpio_npins; i++) {
+		if (sc->gpio_pins[i].gp_pin == pin)
+			break;
+	}
+
+	if (i >= sc->gpio_npins)
+		return (EINVAL);
+
+	GPIO_LOCK(sc);
+	*val = (READ4(sc, IMX_GPIO_DR_REG) >> i) & 1;
+	GPIO_UNLOCK(sc);
+
+	return (0);
+}
+
+static int
+imx51_gpio_pin_toggle(device_t dev, uint32_t pin)
+{
+	struct imx51_gpio_softc *sc;
+	int i;
+
+	sc = device_get_softc(dev);
+	for (i = 0; i < sc->gpio_npins; i++) {
+		if (sc->gpio_pins[i].gp_pin == pin)
+			break;
+	}
+
+	if (i >= sc->gpio_npins)
+		return (EINVAL);
+
+	GPIO_LOCK(sc);
+	WRITE4(sc, IMX_GPIO_DR_REG,
+	    (READ4(sc, IMX_GPIO_DR_REG) ^ (1 << i)));
+	GPIO_UNLOCK(sc);
+
+	return (0);
+}
+
+static int
+imx51_gpio_intr(void *arg)
+{
+	struct imx51_gpio_softc *sc;
+	uint32_t input, value;
+
+	sc = arg;
+	input = READ4(sc, IMX_GPIO_ISR_REG);
+	value = input & READ4(sc, IMX_GPIO_IMR_REG);
+	WRITE4(sc, IMX_GPIO_ISR_REG, input);
+
+	if (!value)
+		goto intr_done;
+
+	/* TODO: interrupt handling */
+
+intr_done:
+	return (FILTER_HANDLED);
+}
+
+static int
+imx51_gpio_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (ofw_bus_search_compatible(dev, compat_data)->ocd_data != 0) {
+		device_set_desc(dev, "Freescale i.MX GPIO Controller");
+		return (BUS_PROBE_DEFAULT);
+	}
+
+	return (ENXIO);
+}
+
+static int
+imx51_gpio_attach(device_t dev)
+{
+	struct imx51_gpio_softc *sc;
+	int i, irq;
+
+	sc = device_get_softc(dev);
+	mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL, MTX_DEF);
+
+	if (bus_alloc_resources(dev, imx_gpio_spec, sc->sc_res)) {
+		device_printf(dev, "could not allocate resources\n");
+		return (ENXIO);
+	}
+
+	sc->dev = dev;
+	sc->gpio_npins = NGPIO;
+	sc->sc_l_irq = 2;
+	sc->sc_iot = rman_get_bustag(sc->sc_res[0]);
+	sc->sc_ioh = rman_get_bushandle(sc->sc_res[0]);
+
+	if (bus_alloc_resources(dev, imx_gpio0irq_spec, &sc->sc_res[3]) == 0) {
+		/*
+		 * First GPIO unit able to serve +8 interrupts for 8 first
+		 * pins.
+		 */
+		sc->sc_l_irq = 10;
+	}
+
+	for (irq = 1; irq <= sc->sc_l_irq; irq ++) {
+		if ((bus_setup_intr(dev, sc->sc_res[irq], INTR_TYPE_MISC,
+		    imx51_gpio_intr, NULL, sc, &sc->gpio_ih[irq]))) {
+			device_printf(dev,
+			    "WARNING: unable to register interrupt handler\n");
+			return (ENXIO);
+		}
+	}
+
+	for (i = 0; i < sc->gpio_npins; i++) {
+ 		sc->gpio_pins[i].gp_pin = i;
+ 		sc->gpio_pins[i].gp_caps = DEFAULT_CAPS;
+ 		sc->gpio_pins[i].gp_flags =
+ 		    (READ4(sc, IMX_GPIO_OE_REG) & (1 << i)) ? GPIO_PIN_OUTPUT:
+ 		    GPIO_PIN_INPUT;
+ 		snprintf(sc->gpio_pins[i].gp_name, GPIOMAXNAME,
+ 		    "imx_gpio%d.%d", device_get_unit(dev), i);
+	}
+
+	device_add_child(dev, "gpioc", -1);
+	device_add_child(dev, "gpiobus", -1);
+
+	return (bus_generic_attach(dev));
+}
+
+static int
+imx51_gpio_detach(device_t dev)
+{
+	struct imx51_gpio_softc *sc;
+
+	sc = device_get_softc(dev);
+
+	KASSERT(mtx_initialized(&sc->sc_mtx), ("gpio mutex not initialized"));
+
+	bus_generic_detach(dev);
+
+	if (sc->sc_res[3])
+		bus_release_resources(dev, imx_gpio0irq_spec, &sc->sc_res[3]);
+
+	if (sc->sc_res[0])
+		bus_release_resources(dev, imx_gpio_spec, sc->sc_res);
+
+	mtx_destroy(&sc->sc_mtx);
+
+	return(0);
+}
+
+static device_method_t imx51_gpio_methods[] = {
+	DEVMETHOD(device_probe,		imx51_gpio_probe),
+	DEVMETHOD(device_attach,	imx51_gpio_attach),
+	DEVMETHOD(device_detach,	imx51_gpio_detach),
+
+	/* GPIO protocol */
+	DEVMETHOD(gpio_pin_max,		imx51_gpio_pin_max),
+	DEVMETHOD(gpio_pin_getname,	imx51_gpio_pin_getname),
+	DEVMETHOD(gpio_pin_getflags,	imx51_gpio_pin_getflags),
+	DEVMETHOD(gpio_pin_getcaps,	imx51_gpio_pin_getcaps),
+	DEVMETHOD(gpio_pin_setflags,	imx51_gpio_pin_setflags),
+	DEVMETHOD(gpio_pin_get,		imx51_gpio_pin_get),
+	DEVMETHOD(gpio_pin_set,		imx51_gpio_pin_set),
+	DEVMETHOD(gpio_pin_toggle,	imx51_gpio_pin_toggle),
+	{0, 0},
+};
+
+static driver_t imx51_gpio_driver = {
+	"gpio",
+	imx51_gpio_methods,
+	sizeof(struct imx51_gpio_softc),
+};
+static devclass_t imx51_gpio_devclass;
+
+DRIVER_MODULE(imx51_gpio, simplebus, imx51_gpio_driver, imx51_gpio_devclass,
+    0, 0);


Property changes on: trunk/sys/arm/freescale/imx/imx_gpio.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/imx/imx_gpt.c
===================================================================
--- trunk/sys/arm/freescale/imx/imx_gpt.c	                        (rev 0)
+++ trunk/sys/arm/freescale/imx/imx_gpt.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,417 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012, 2013 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Oleksandr Rybalko under sponsorship
+ * from the FreeBSD Foundation.
+ *
+ * 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: stable/10/sys/arm/freescale/imx/imx_gpt.c 273681 2014-10-26 04:15:27Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/timeet.h>
+#include <sys/timetc.h>
+#include <sys/watchdog.h>
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#include <machine/fdt.h>
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <arm/freescale/imx/imx_gptvar.h>
+#include <arm/freescale/imx/imx_gptreg.h>
+
+#include <sys/kdb.h>
+#include <arm/freescale/imx/imx_ccmvar.h>
+
+#define	WRITE4(_sc, _r, _v)						\
+	    bus_space_write_4((_sc)->sc_iot, (_sc)->sc_ioh, (_r), (_v))
+#define	READ4(_sc, _r)							\
+	    bus_space_read_4((_sc)->sc_iot, (_sc)->sc_ioh, (_r))
+#define	SET4(_sc, _r, _m)						\
+	    WRITE4((_sc), (_r), READ4((_sc), (_r)) | (_m))
+#define	CLEAR4(_sc, _r, _m)						\
+	    WRITE4((_sc), (_r), READ4((_sc), (_r)) & ~(_m))
+
+static u_int	imx_gpt_get_timecount(struct timecounter *);
+static int	imx_gpt_timer_start(struct eventtimer *, sbintime_t,
+    sbintime_t);
+static int	imx_gpt_timer_stop(struct eventtimer *);
+
+static int imx_gpt_intr(void *);
+static int imx_gpt_probe(device_t);
+static int imx_gpt_attach(device_t);
+
+static struct timecounter imx_gpt_timecounter = {
+	.tc_name           = "iMXGPT",
+	.tc_get_timecount  = imx_gpt_get_timecount,
+	.tc_counter_mask   = ~0u,
+	.tc_frequency      = 0,
+	.tc_quality        = 1000,
+};
+
+/* Global softc pointer for use in DELAY(). */
+struct imx_gpt_softc *imx_gpt_sc = NULL;
+
+/*
+ * Hand-calibrated delay-loop counter.  This was calibrated on an i.MX6 running
+ * at 792mhz.  It will delay a bit too long on slower processors -- that's
+ * better than not delaying long enough.  In practice this is unlikely to get
+ * used much since the clock driver is one of the first to start up, and once
+ * we're attached the delay loop switches to using the timer hardware.
+ */
+static const int imx_gpt_delay_count = 78;
+
+/* Try to divide down an available fast clock to this frequency. */
+#define	TARGET_FREQUENCY	1000000000
+
+/* Don't try to set an event timer period smaller than this. */
+#define	MIN_ET_PERIOD		10LLU
+
+
+static struct resource_spec imx_gpt_spec[] = {
+	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		0,	RF_ACTIVE },
+	{ -1, 0 }
+};
+
+static struct ofw_compat_data compat_data[] = {
+	{"fsl,imx6q-gpt",  1},
+	{"fsl,imx53-gpt",  1},
+	{"fsl,imx51-gpt",  1},
+	{"fsl,imx31-gpt",  1},
+	{"fsl,imx27-gpt",  1},
+	{"fsl,imx25-gpt",  1},
+	{NULL,             0}
+};
+
+static int
+imx_gpt_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (ofw_bus_search_compatible(dev, compat_data)->ocd_data != 0) {
+		device_set_desc(dev, "Freescale i.MX GPT timer");
+		return (BUS_PROBE_DEFAULT);
+	}
+
+	return (ENXIO);
+}
+
+static int
+imx_gpt_attach(device_t dev)
+{
+	struct imx_gpt_softc *sc;
+	int ctlreg, err;
+	uint32_t basefreq, prescale;
+
+	sc = device_get_softc(dev);
+
+	if (bus_alloc_resources(dev, imx_gpt_spec, sc->res)) {
+		device_printf(dev, "could not allocate resources\n");
+		return (ENXIO);
+	}
+
+	sc->sc_dev = dev;
+	sc->sc_iot = rman_get_bustag(sc->res[0]);
+	sc->sc_ioh = rman_get_bushandle(sc->res[0]);
+
+	/*
+	 * For now, just automatically choose a good clock for the hardware
+	 * we're running on.  Eventually we could allow selection from the fdt;
+	 * the code in this driver will cope with any clock frequency.
+	 */
+	sc->sc_clksrc = GPT_CR_CLKSRC_IPG;
+
+	ctlreg = 0;
+
+	switch (sc->sc_clksrc) {
+	case GPT_CR_CLKSRC_32K:
+		basefreq = 32768;
+		break;
+	case GPT_CR_CLKSRC_IPG:
+		basefreq = imx_ccm_ipg_hz();
+		break;
+	case GPT_CR_CLKSRC_IPG_HIGH:
+		basefreq = imx_ccm_ipg_hz() * 2;
+		break;
+	case GPT_CR_CLKSRC_24M:
+		ctlreg |= GPT_CR_24MEN;
+		basefreq = 24000000;
+		break;
+	case GPT_CR_CLKSRC_NONE:/* Can't run without a clock. */
+	case GPT_CR_CLKSRC_EXT:	/* No way to get the freq of an ext clock. */
+	default:
+		device_printf(dev, "Unsupported clock source '%d'\n", 
+		    sc->sc_clksrc);
+		return (EINVAL);
+	}
+
+	/*
+	 * The following setup sequence is from the I.MX6 reference manual,
+	 * "Selecting the clock source".  First, disable the clock and
+	 * interrupts.  This also clears input and output mode bits and in
+	 * general completes several of the early steps in the procedure.
+	 */
+	WRITE4(sc, IMX_GPT_CR, 0);
+	WRITE4(sc, IMX_GPT_IR, 0);
+
+	/* Choose the clock and the power-saving behaviors. */
+	ctlreg |=
+	    sc->sc_clksrc |	/* Use selected clock */
+	    GPT_CR_FRR |	/* Just count (FreeRunner mode) */
+	    GPT_CR_STOPEN |	/* Run in STOP mode */
+	    GPT_CR_DOZEEN |	/* Run in DOZE mode */
+	    GPT_CR_WAITEN |	/* Run in WAIT mode */
+	    GPT_CR_DBGEN;	/* Run in DEBUG mode */
+	WRITE4(sc, IMX_GPT_CR, ctlreg);
+
+	/*
+	 * The datasheet says to do the software reset after choosing the clock
+	 * source.  It says nothing about needing to wait for the reset to
+	 * complete, but the register description does document the fact that
+	 * the reset isn't complete until the SWR bit reads 0, so let's be safe.
+	 * The reset also clears all registers except for a few of the bits in
+	 * CR, but we'll rewrite all the CR bits when we start the counter.
+	 */
+	WRITE4(sc, IMX_GPT_CR, ctlreg | GPT_CR_SWR);
+	while (READ4(sc, IMX_GPT_CR) & GPT_CR_SWR)
+		continue;
+
+	/* Set a prescaler value that gets us near the target frequency. */
+	if (basefreq < TARGET_FREQUENCY) {
+		prescale = 0;
+		sc->clkfreq = basefreq;
+	} else {
+		prescale = basefreq / TARGET_FREQUENCY;
+		sc->clkfreq = basefreq / prescale;
+		prescale -= 1; /* 1..n range is 0..n-1 in hardware. */
+	}
+	WRITE4(sc, IMX_GPT_PR, prescale);
+
+	/* Clear the status register. */
+	WRITE4(sc, IMX_GPT_SR, GPT_IR_ALL);
+
+	/* Start the counter. */
+	WRITE4(sc, IMX_GPT_CR, ctlreg | GPT_CR_EN);
+
+	if (bootverbose)
+		device_printf(dev, "Running on %dKHz clock, base freq %uHz CR=0x%08x, PR=0x%08x\n",
+		    sc->clkfreq / 1000, basefreq, READ4(sc, IMX_GPT_CR), READ4(sc, IMX_GPT_PR));
+
+	/* Setup the timer interrupt. */
+	err = bus_setup_intr(dev, sc->res[1], INTR_TYPE_CLK, imx_gpt_intr,
+	    NULL, sc, &sc->sc_ih);
+	if (err != 0) {
+		bus_release_resources(dev, imx_gpt_spec, sc->res);
+		device_printf(dev, "Unable to setup the clock irq handler, "
+		    "err = %d\n", err);
+		return (ENXIO);
+	}
+
+	/* Register as an eventtimer. */
+	sc->et.et_name = "iMXGPT";
+	sc->et.et_flags = ET_FLAGS_ONESHOT | ET_FLAGS_PERIODIC;
+	sc->et.et_quality = 800;
+	sc->et.et_frequency = sc->clkfreq;
+	sc->et.et_min_period = (MIN_ET_PERIOD << 32) / sc->et.et_frequency;
+	sc->et.et_max_period = (0xfffffffeLLU << 32) / sc->et.et_frequency;
+	sc->et.et_start = imx_gpt_timer_start;
+	sc->et.et_stop = imx_gpt_timer_stop;
+	sc->et.et_priv = sc;
+	et_register(&sc->et);
+
+	/* Register as a timecounter. */
+	imx_gpt_timecounter.tc_frequency = sc->clkfreq;
+	tc_init(&imx_gpt_timecounter);
+
+	/* If this is the first unit, store the softc for use in DELAY. */
+	if (device_get_unit(dev) == 0)
+	    imx_gpt_sc = sc;
+
+	return (0);
+}
+
+static int
+imx_gpt_timer_start(struct eventtimer *et, sbintime_t first, sbintime_t period)
+{
+	struct imx_gpt_softc *sc;
+	uint32_t ticks;
+
+	sc = (struct imx_gpt_softc *)et->et_priv;
+
+	if (period != 0) {
+		sc->sc_period = ((uint32_t)et->et_frequency * period) >> 32;
+		/* Set expected value */
+		WRITE4(sc, IMX_GPT_OCR2, READ4(sc, IMX_GPT_CNT) + sc->sc_period);
+		/* Enable compare register 2 Interrupt */
+		SET4(sc, IMX_GPT_IR, GPT_IR_OF2);
+		return (0);
+	} else if (first != 0) {
+		ticks = ((uint32_t)et->et_frequency * first) >> 32;
+		/* Do not disturb, otherwise event will be lost */
+		spinlock_enter();
+		/* Set expected value */
+		WRITE4(sc, IMX_GPT_OCR3, READ4(sc, IMX_GPT_CNT) + ticks);
+		/* Enable compare register 1 Interrupt */
+		SET4(sc, IMX_GPT_IR, GPT_IR_OF3);
+		/* Now everybody can relax */
+		spinlock_exit();
+		return (0);
+	}
+
+	return (EINVAL);
+}
+
+static int
+imx_gpt_timer_stop(struct eventtimer *et)
+{
+	struct imx_gpt_softc *sc;
+
+	sc = (struct imx_gpt_softc *)et->et_priv;
+
+	/* Disable OF2 Interrupt */
+	CLEAR4(sc, IMX_GPT_IR, GPT_IR_OF2);
+	WRITE4(sc, IMX_GPT_SR, GPT_IR_OF2);
+	sc->sc_period = 0;
+
+	return (0);
+}
+
+int
+imx_gpt_get_timerfreq(struct imx_gpt_softc *sc)
+{
+
+	return (sc->clkfreq);
+}
+
+static int
+imx_gpt_intr(void *arg)
+{
+	struct imx_gpt_softc *sc;
+	uint32_t status;
+
+	sc = (struct imx_gpt_softc *)arg;
+
+	status = READ4(sc, IMX_GPT_SR);
+
+	/*
+	* Clear interrupt status before invoking event callbacks.  The callback
+	* often sets up a new one-shot timer event and if the interval is short
+	* enough it can fire before we get out of this function.  If we cleared
+	* at the bottom we'd miss the interrupt and hang until the clock wraps.
+	*/
+	WRITE4(sc, IMX_GPT_SR, status);
+
+	/* Handle one-shot timer events. */
+	if (status & GPT_IR_OF3) {
+		if (sc->et.et_active) {
+			sc->et.et_event_cb(&sc->et, sc->et.et_arg);
+		}
+	}
+
+	/* Handle periodic timer events. */
+	if (status & GPT_IR_OF2) {
+		if (sc->et.et_active)
+			sc->et.et_event_cb(&sc->et, sc->et.et_arg);
+		if (sc->sc_period != 0)
+			WRITE4(sc, IMX_GPT_OCR2, READ4(sc, IMX_GPT_CNT) +
+			    sc->sc_period);
+	}
+
+	return (FILTER_HANDLED);
+}
+
+u_int
+imx_gpt_get_timecount(struct timecounter *tc)
+{
+
+	if (imx_gpt_sc == NULL)
+		return (0);
+
+	return (READ4(imx_gpt_sc, IMX_GPT_CNT));
+}
+
+static device_method_t imx_gpt_methods[] = {
+	DEVMETHOD(device_probe,		imx_gpt_probe),
+	DEVMETHOD(device_attach,	imx_gpt_attach),
+
+	DEVMETHOD_END
+};
+
+static driver_t imx_gpt_driver = {
+	"imx_gpt",
+	imx_gpt_methods,
+	sizeof(struct imx_gpt_softc),
+};
+
+static devclass_t imx_gpt_devclass;
+
+EARLY_DRIVER_MODULE(imx_gpt, simplebus, imx_gpt_driver, imx_gpt_devclass, 0,
+    0, BUS_PASS_TIMER);
+
+void
+DELAY(int usec)
+{
+	uint64_t curcnt, endcnt, startcnt, ticks;
+
+	/* If the timer hardware is not accessible, just use a loop. */
+	if (imx_gpt_sc == NULL) {
+		while (usec-- > 0)
+			for (ticks = 0; ticks < imx_gpt_delay_count; ++ticks)
+				cpufunc_nullop();
+		return;
+	}
+
+	/*
+	 * Calculate the tick count with 64-bit values so that it works for any
+	 * clock frequency.  Loop until the hardware count reaches start+ticks.
+	 * If the 32-bit hardware count rolls over while we're looping, just
+	 * manually do a carry into the high bits after each read; don't worry
+	 * that doing this on each loop iteration is inefficient -- we're trying
+	 * to waste time here.
+	 */
+	ticks = 1 + ((uint64_t)usec * imx_gpt_sc->clkfreq) / 1000000;
+	curcnt = startcnt = READ4(imx_gpt_sc, IMX_GPT_CNT);
+	endcnt = startcnt + ticks;
+	while (curcnt < endcnt) {
+		curcnt = READ4(imx_gpt_sc, IMX_GPT_CNT);
+		if (curcnt < startcnt)
+			curcnt += 1ULL << 32;
+	}
+}


Property changes on: trunk/sys/arm/freescale/imx/imx_gpt.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/imx/imx_gptreg.h
===================================================================
--- trunk/sys/arm/freescale/imx/imx_gptreg.h	                        (rev 0)
+++ trunk/sys/arm/freescale/imx/imx_gptreg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,102 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012, 2013 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Oleksandr Rybalko under sponsorship
+ * from the FreeBSD Foundation.
+ *
+ * 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: stable/10/sys/arm/freescale/imx/imx_gptreg.h 261455 2014-02-04 03:36:42Z eadler $
+ */
+
+/* Registers definition for Freescale i.MX515 Generic Periodic Timer */
+
+#define	IMX_GPT_CR	0x0000 /* Control Register          R/W */
+#define		GPT_CR_FO3		(1U << 31)
+#define		GPT_CR_FO2		(1 << 30)
+#define		GPT_CR_FO1		(1 << 29)
+#define		GPT_CR_OM3_SHIFT	26
+#define		GPT_CR_OM3_MASK		0x1c000000
+#define		GPT_CR_OM2_SHIFT	23
+#define		GPT_CR_OM2_MASK		0x03800000
+#define		GPT_CR_OM1_SHIFT	20
+#define		GPT_CR_OM1_MASK		0x00700000
+#define		GPT_CR_OMX_NONE		0
+#define		GPT_CR_OMX_TOGGLE	1
+#define		GPT_CR_OMX_CLEAR	2
+#define		GPT_CR_OMX_SET		3
+#define		GPT_CR_OMX_PULSE	4 /* Run CLKSRC on output pin */
+#define		GPT_CR_IM2_SHIFT	18
+#define		GPT_CR_IM2_MASK		0x000c0000
+#define		GPT_CR_IM1_SHIFT	16
+#define		GPT_CR_IM1_MASK		0x00030000
+#define		GPT_CR_IMX_NONE		0
+#define		GPT_CR_IMX_REDGE	1
+#define		GPT_CR_IMX_FEDGE	2
+#define		GPT_CR_IMX_BOTH		3
+#define		GPT_CR_SWR		(1 << 15)
+#define		GPT_CR_24MEN		(1 << 10)
+#define		GPT_CR_FRR		(1 << 9)
+#define		GPT_CR_CLKSRC_NONE	(0 << 6)
+#define		GPT_CR_CLKSRC_IPG	(1 << 6)
+#define		GPT_CR_CLKSRC_IPG_HIGH	(2 << 6)
+#define		GPT_CR_CLKSRC_EXT	(3 << 6)
+#define		GPT_CR_CLKSRC_32K	(4 << 6)
+#define		GPT_CR_CLKSRC_24M	(5 << 6)
+#define		GPT_CR_STOPEN		(1 << 5)
+#define		GPT_CR_DOZEEN		(1 << 4)
+#define		GPT_CR_WAITEN		(1 << 3)
+#define		GPT_CR_DBGEN		(1 << 2)
+#define		GPT_CR_ENMOD		(1 << 1)
+#define		GPT_CR_EN		(1 << 0)
+
+#define	IMX_GPT_PR	0x0004 /* Prescaler Register        R/W */
+#define		GPT_PR_VALUE_SHIFT	0
+#define		GPT_PR_VALUE_MASK	0x00000fff
+#define		GPT_PR_VALUE_SHIFT_24M	12
+#define		GPT_PR_VALUE_MASK_24M	0x0000f000
+
+/* Same map for SR and IR */
+#define	IMX_GPT_SR	0x0008 /* Status Register           R/W */
+#define	IMX_GPT_IR	0x000c /* Interrupt Register        R/W */
+#define		GPT_IR_ROV		(1 << 5)
+#define		GPT_IR_IF2		(1 << 4)
+#define		GPT_IR_IF1		(1 << 3)
+#define		GPT_IR_OF3		(1 << 2)
+#define		GPT_IR_OF2		(1 << 1)
+#define		GPT_IR_OF1		(1 << 0)
+#define		GPT_IR_ALL		\
+			(GPT_IR_ROV |	\
+			GPT_IR_IF2 |	\
+			GPT_IR_IF1 |	\
+			GPT_IR_OF3 |	\
+			GPT_IR_OF2 |	\
+			GPT_IR_OF1)
+
+#define	IMX_GPT_OCR1	0x0010 /* Output Compare Register 1 R/W */
+#define	IMX_GPT_OCR2	0x0014 /* Output Compare Register 2 R/W */
+#define	IMX_GPT_OCR3	0x0018 /* Output Compare Register 3 R/W */
+#define	IMX_GPT_ICR1	0x001c /* Input capture Register 1  RO */
+#define	IMX_GPT_ICR2	0x0020 /* Input capture Register 2  RO */
+#define	IMX_GPT_CNT	0x0024 /* Counter Register          RO */


Property changes on: trunk/sys/arm/freescale/imx/imx_gptreg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/imx/imx_gptvar.h
===================================================================
--- trunk/sys/arm/freescale/imx/imx_gptvar.h	                        (rev 0)
+++ trunk/sys/arm/freescale/imx/imx_gptvar.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,51 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012, 2013 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Oleksandr Rybalko under sponsorship
+ * from the FreeBSD Foundation.
+ *
+ * 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: stable/10/sys/arm/freescale/imx/imx_gptvar.h 250357 2013-05-08 09:42:50Z ray $
+ */
+
+#ifndef _IMXGPTVAR_H
+#define	_IMXGPTVAR_H
+
+struct imx_gpt_softc {
+	device_t 	sc_dev;
+	struct resource *res[2];
+	bus_space_tag_t sc_iot;
+	bus_space_handle_t sc_ioh;
+	void 		*sc_ih;			/* interrupt handler */
+	uint32_t 	sc_period;
+	uint32_t 	sc_clksrc;
+	uint32_t 	clkfreq;
+	struct eventtimer et;
+};
+
+extern struct imx_gpt_softc *imx_gpt_sc;
+
+int imx_gpt_get_timerfreq(struct imx_gpt_softc *);
+#endif	/* _IMXGPTVAR_H */


Property changes on: trunk/sys/arm/freescale/imx/imx_gptvar.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/imx/imx_i2c.c
===================================================================
--- trunk/sys/arm/freescale/imx/imx_i2c.c	                        (rev 0)
+++ trunk/sys/arm/freescale/imx/imx_i2c.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,483 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (C) 2008-2009 Semihalf, Michal Hajduk
+ * Copyright (c) 2012, 2013 The FreeBSD Foundation
+ * Copyright (c) 2015 Ian Lepore <ian at FreeBSD.org>
+ * All rights reserved.
+ *
+ * Portions of this software were developed by Oleksandr Rybalko
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * 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 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 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.
+ */
+
+/*
+ * I2C driver for Freescale i.MX hardware.
+ *
+ * Note that the hardware is capable of running as both a master and a slave.
+ * This driver currently implements only master-mode operations.
+ *
+ * This driver supports multi-master i2c busses, by detecting bus arbitration
+ * loss and returning IIC_EBUSBSY status.  Notably, it does not do any kind of
+ * retries if some other master jumps onto the bus and interrupts one of our
+ * transfer cycles resulting in arbitration loss in mid-transfer.  The caller
+ * must handle retries in a way that makes sense for the slave being addressed.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/freescale/imx/imx_i2c.c 289666 2015-10-20 21:20:34Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/limits.h>
+#include <sys/module.h>
+#include <sys/resource.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+#include <sys/rman.h>
+
+#include <arm/freescale/imx/imx_ccmvar.h>
+
+#include <dev/iicbus/iiconf.h>
+#include <dev/iicbus/iicbus.h>
+#include "iicbus_if.h"
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#define I2C_ADDR_REG		0x00 /* I2C slave address register */
+#define I2C_FDR_REG		0x04 /* I2C frequency divider register */
+#define I2C_CONTROL_REG		0x08 /* I2C control register */
+#define I2C_STATUS_REG		0x0C /* I2C status register */
+#define I2C_DATA_REG		0x10 /* I2C data register */
+#define I2C_DFSRR_REG		0x14 /* I2C Digital Filter Sampling rate */
+
+#define I2CCR_MEN		(1 << 7) /* Module enable */
+#define I2CCR_MSTA		(1 << 5) /* Master/slave mode */
+#define I2CCR_MTX		(1 << 4) /* Transmit/receive mode */
+#define I2CCR_TXAK		(1 << 3) /* Transfer acknowledge */
+#define I2CCR_RSTA		(1 << 2) /* Repeated START */
+
+#define I2CSR_MCF		(1 << 7) /* Data transfer */
+#define I2CSR_MASS		(1 << 6) /* Addressed as a slave */
+#define I2CSR_MBB		(1 << 5) /* Bus busy */
+#define I2CSR_MAL		(1 << 4) /* Arbitration lost */
+#define I2CSR_SRW		(1 << 2) /* Slave read/write */
+#define I2CSR_MIF		(1 << 1) /* Module interrupt */
+#define I2CSR_RXAK		(1 << 0) /* Received acknowledge */
+
+#define I2C_BAUD_RATE_FAST	0x31
+#define I2C_BAUD_RATE_DEF	0x3F
+#define I2C_DFSSR_DIV		0x10
+
+/*
+ * A table of available divisors and the associated coded values to put in the
+ * FDR register to achieve that divisor.. There is no algorithmic relationship I
+ * can see between divisors and the codes that go into the register.  The table
+ * begins and ends with entries that handle insane configuration values.
+ */
+struct clkdiv {
+	u_int divisor;
+	u_int regcode;
+};
+static struct clkdiv clkdiv_table[] = {
+        {    0, 0x20 }, {   22, 0x20 }, {   24, 0x21 }, {   26, 0x22 }, 
+        {   28, 0x23 }, {   30, 0x00 }, {   32, 0x24 }, {   36, 0x25 }, 
+        {   40, 0x26 }, {   42, 0x03 }, {   44, 0x27 }, {   48, 0x28 }, 
+        {   52, 0x05 }, {   56, 0x29 }, {   60, 0x06 }, {   64, 0x2a }, 
+        {   72, 0x2b }, {   80, 0x2c }, {   88, 0x09 }, {   96, 0x2d }, 
+        {  104, 0x0a }, {  112, 0x2e }, {  128, 0x2f }, {  144, 0x0c }, 
+        {  160, 0x30 }, {  192, 0x31 }, {  224, 0x32 }, {  240, 0x0f }, 
+        {  256, 0x33 }, {  288, 0x10 }, {  320, 0x34 }, {  384, 0x35 }, 
+        {  448, 0x36 }, {  480, 0x13 }, {  512, 0x37 }, {  576, 0x14 }, 
+        {  640, 0x38 }, {  768, 0x39 }, {  896, 0x3a }, {  960, 0x17 }, 
+        { 1024, 0x3b }, { 1152, 0x18 }, { 1280, 0x3c }, { 1536, 0x3d }, 
+        { 1792, 0x3e }, { 1920, 0x1b }, { 2048, 0x3f }, { 2304, 0x1c }, 
+        { 2560, 0x1d }, { 3072, 0x1e }, { 3840, 0x1f }, {UINT_MAX, 0x1f} 
+};
+
+static struct ofw_compat_data compat_data[] = {
+	{"fsl,imx6q-i2c",  1},
+	{"fsl,imx-i2c",	   1},
+	{NULL,             0}
+};
+
+struct i2c_softc {
+	device_t		dev;
+	device_t		iicbus;
+	struct resource		*res;
+	int			rid;
+	sbintime_t		byte_time_sbt;
+};
+
+static phandle_t i2c_get_node(device_t, device_t);
+static int i2c_probe(device_t);
+static int i2c_attach(device_t);
+
+static int i2c_repeated_start(device_t, u_char, int);
+static int i2c_start(device_t, u_char, int);
+static int i2c_stop(device_t);
+static int i2c_reset(device_t, u_char, u_char, u_char *);
+static int i2c_read(device_t, char *, int, int *, int, int);
+static int i2c_write(device_t, const char *, int, int *, int);
+
+static device_method_t i2c_methods[] = {
+	DEVMETHOD(device_probe,			i2c_probe),
+	DEVMETHOD(device_attach,		i2c_attach),
+
+	/* OFW methods */
+	DEVMETHOD(ofw_bus_get_node,		i2c_get_node),
+
+	DEVMETHOD(iicbus_callback,		iicbus_null_callback),
+	DEVMETHOD(iicbus_repeated_start,	i2c_repeated_start),
+	DEVMETHOD(iicbus_start,			i2c_start),
+	DEVMETHOD(iicbus_stop,			i2c_stop),
+	DEVMETHOD(iicbus_reset,			i2c_reset),
+	DEVMETHOD(iicbus_read,			i2c_read),
+	DEVMETHOD(iicbus_write,			i2c_write),
+	DEVMETHOD(iicbus_transfer,		iicbus_transfer_gen),
+
+	DEVMETHOD_END
+};
+
+static driver_t i2c_driver = {
+	"iichb",
+	i2c_methods,
+	sizeof(struct i2c_softc),
+};
+static devclass_t  i2c_devclass;
+
+DRIVER_MODULE(i2c, simplebus, i2c_driver, i2c_devclass, 0, 0);
+DRIVER_MODULE(iicbus, i2c, iicbus_driver, iicbus_devclass, 0, 0);
+
+static phandle_t
+i2c_get_node(device_t bus, device_t dev)
+{
+	/*
+	 * Share controller node with iicbus device
+	 */
+	return ofw_bus_get_node(bus);
+}
+
+static __inline void
+i2c_write_reg(struct i2c_softc *sc, bus_size_t off, uint8_t val)
+{
+
+	bus_write_1(sc->res, off, val);
+}
+
+static __inline uint8_t
+i2c_read_reg(struct i2c_softc *sc, bus_size_t off)
+{
+
+	return (bus_read_1(sc->res, off));
+}
+
+static __inline void
+i2c_flag_set(struct i2c_softc *sc, bus_size_t off, uint8_t mask)
+{
+	uint8_t status;
+
+	status = i2c_read_reg(sc, off);
+	status |= mask;
+	i2c_write_reg(sc, off, status);
+}
+
+/* Wait for bus to become busy or not-busy. */
+static int
+wait_for_busbusy(struct i2c_softc *sc, int wantbusy)
+{
+	int retry, srb;
+
+	retry = 1000;
+	while (retry --) {
+		srb = i2c_read_reg(sc, I2C_STATUS_REG) & I2CSR_MBB;
+		if ((srb && wantbusy) || (!srb && !wantbusy))
+			return (IIC_NOERR);
+		DELAY(1);
+	}
+	return (IIC_ETIMEOUT);
+}
+
+/* Wait for transfer to complete, optionally check RXAK. */
+static int
+wait_for_xfer(struct i2c_softc *sc, int checkack)
+{
+	int retry, sr;
+
+	/*
+	 * Sleep for about the time it takes to transfer a byte (with precision
+	 * set to tolerate 5% oversleep).  We calculate the approximate byte
+	 * transfer time when we set the bus speed divisor.  Slaves are allowed
+	 * to do clock-stretching so the actual transfer time can be larger, but
+	 * this gets the bulk of the waiting out of the way without tying up the
+	 * processor the whole time.
+	 */
+	pause_sbt("imxi2c", sc->byte_time_sbt, sc->byte_time_sbt / 20, 0);
+
+	retry = 10000;
+	while (retry --) {
+		sr = i2c_read_reg(sc, I2C_STATUS_REG);
+		if (sr & I2CSR_MIF) {
+                        if (sr & I2CSR_MAL) 
+				return (IIC_EBUSERR);
+			else if (checkack && (sr & I2CSR_RXAK))
+				return (IIC_ENOACK);
+			else
+				return (IIC_NOERR);
+		}
+		DELAY(1);
+	}
+	return (IIC_ETIMEOUT);
+}
+
+/*
+ * Implement the error handling shown in the state diagram of the imx6 reference
+ * manual.  If there was an error, then:
+ *  - Clear master mode (MSTA and MTX).
+ *  - Wait for the bus to become free or for a timeout to happen.
+ *  - Disable the controller.
+ */
+static int
+i2c_error_handler(struct i2c_softc *sc, int error)
+{
+
+	if (error != 0) {
+		i2c_write_reg(sc, I2C_STATUS_REG, 0);
+		i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN);
+		wait_for_busbusy(sc, false);
+		i2c_write_reg(sc, I2C_CONTROL_REG, 0);
+	}
+	return (error);
+}
+
+static int
+i2c_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
+		return (ENXIO);
+
+	device_set_desc(dev, "Freescale i.MX I2C");
+
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+i2c_attach(device_t dev)
+{
+	struct i2c_softc *sc;
+
+	sc = device_get_softc(dev);
+	sc->dev = dev;
+	sc->rid = 0;
+
+	sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->rid,
+	    RF_ACTIVE);
+	if (sc->res == NULL) {
+		device_printf(dev, "could not allocate resources");
+		return (ENXIO);
+	}
+
+	sc->iicbus = device_add_child(dev, "iicbus", -1);
+	if (sc->iicbus == NULL) {
+		device_printf(dev, "could not add iicbus child");
+		return (ENXIO);
+	}
+
+	bus_generic_attach(dev);
+	return (0);
+}
+
+static int
+i2c_repeated_start(device_t dev, u_char slave, int timeout)
+{
+	struct i2c_softc *sc;
+	int error;
+
+	sc = device_get_softc(dev);
+
+	if ((i2c_read_reg(sc, I2C_STATUS_REG) & I2CSR_MBB) == 0) {
+		return (IIC_EBUSERR);
+	}
+
+	/*
+	 * Set repeated start condition, delay (per reference manual, min 156nS)
+	 * before writing slave address, wait for ack after write.
+	 */
+	i2c_flag_set(sc, I2C_CONTROL_REG, I2CCR_RSTA);
+	DELAY(1);
+	i2c_write_reg(sc, I2C_STATUS_REG, 0x0);
+	i2c_write_reg(sc, I2C_DATA_REG, slave);
+	error = wait_for_xfer(sc, true);
+	return (i2c_error_handler(sc, error));
+}
+
+static int
+i2c_start(device_t dev, u_char slave, int timeout)
+{
+	struct i2c_softc *sc;
+	int error;
+
+	sc = device_get_softc(dev);
+
+	i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN);
+	DELAY(10); /* Delay for controller to sample bus state. */
+	if (i2c_read_reg(sc, I2C_STATUS_REG) & I2CSR_MBB) {
+		return (i2c_error_handler(sc, IIC_EBUSERR));
+	}
+	i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN | I2CCR_MSTA | I2CCR_MTX);
+	if ((error = wait_for_busbusy(sc, true)) != IIC_NOERR)
+		return (i2c_error_handler(sc, error));
+	i2c_write_reg(sc, I2C_STATUS_REG, 0);
+	i2c_write_reg(sc, I2C_DATA_REG, slave);
+	error = wait_for_xfer(sc, true);
+	return (i2c_error_handler(sc, error));
+}
+
+static int
+i2c_stop(device_t dev)
+{
+	struct i2c_softc *sc;
+
+	sc = device_get_softc(dev);
+
+	i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN);
+	wait_for_busbusy(sc, false);
+	i2c_write_reg(sc, I2C_CONTROL_REG, 0);
+	return (IIC_NOERR);
+}
+
+static int
+i2c_reset(device_t dev, u_char speed, u_char addr, u_char *oldadr)
+{
+	struct i2c_softc *sc;
+	u_int busfreq, div, i, ipgfreq;
+
+	sc = device_get_softc(dev);
+
+	/*
+	 * Look up the divisor that gives the nearest speed that doesn't exceed
+	 * the configured value for the bus.
+	 */
+	ipgfreq = imx_ccm_ipg_hz();
+	busfreq = IICBUS_GET_FREQUENCY(sc->iicbus, speed);
+	div = (ipgfreq + busfreq - 1) / busfreq;
+	for (i = 0; i < nitems(clkdiv_table); i++) {
+		if (clkdiv_table[i].divisor >= div)
+			break;
+	}
+
+	/*
+	 * Calculate roughly how long it will take to transfer a byte (which
+	 * requires 9 clock cycles) at the new bus speed.  This value is used to
+	 * pause() while waiting for transfer-complete.  With a 66MHz IPG clock
+	 * and the actual i2c bus speeds that leads to, for nominal 100KHz and
+	 * 400KHz bus speeds the transfer times are roughly 104uS and 22uS.
+	 */
+	busfreq = ipgfreq / clkdiv_table[i].divisor;
+	sc->byte_time_sbt = SBT_1US * (9000000 / busfreq);
+
+	/*
+	 * Disable the controller (do the reset), and set the new clock divisor.
+	 */
+	i2c_write_reg(sc, I2C_STATUS_REG, 0x0);
+	i2c_write_reg(sc, I2C_CONTROL_REG, 0x0);
+	i2c_write_reg(sc, I2C_FDR_REG, (uint8_t)clkdiv_table[i].regcode);
+	return (IIC_NOERR);
+}
+
+static int
+i2c_read(device_t dev, char *buf, int len, int *read, int last, int delay)
+{
+	struct i2c_softc *sc;
+	int error, reg;
+
+	sc = device_get_softc(dev);
+	*read = 0;
+
+	if (len) {
+		if (len == 1)
+			i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN |
+			    I2CCR_MSTA | I2CCR_TXAK);
+		else
+			i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN |
+			    I2CCR_MSTA);
+                /* Dummy read to prime the receiver. */
+		i2c_write_reg(sc, I2C_STATUS_REG, 0x0);
+		i2c_read_reg(sc, I2C_DATA_REG);
+	}
+
+	error = 0;
+	*read = 0;
+	while (*read < len) {
+		if ((error = wait_for_xfer(sc, false)) != IIC_NOERR)
+			break;
+		i2c_write_reg(sc, I2C_STATUS_REG, 0x0);
+		if (last) {
+			if (*read == len - 2) {
+				/* NO ACK on last byte */
+				i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN |
+				    I2CCR_MSTA | I2CCR_TXAK);
+			} else if (*read == len - 1) {
+				/* Transfer done, signal stop. */
+				i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN |
+				    I2CCR_TXAK);
+				wait_for_busbusy(sc, false);
+			}
+		}
+		reg = i2c_read_reg(sc, I2C_DATA_REG);
+		*buf++ = reg;
+		(*read)++;
+	}
+
+	return (i2c_error_handler(sc, error));
+}
+
+static int
+i2c_write(device_t dev, const char *buf, int len, int *sent, int timeout)
+{
+	struct i2c_softc *sc;
+	int error;
+
+	sc = device_get_softc(dev);
+
+	error = 0;
+	*sent = 0;
+	while (*sent < len) {
+		i2c_write_reg(sc, I2C_STATUS_REG, 0x0);
+		i2c_write_reg(sc, I2C_DATA_REG, *buf++);
+		if ((error = wait_for_xfer(sc, true)) != IIC_NOERR)
+			break;
+		(*sent)++;
+	}
+
+	return (i2c_error_handler(sc, error));
+}


Property changes on: trunk/sys/arm/freescale/imx/imx_i2c.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/imx/imx_iomux.c
===================================================================
--- trunk/sys/arm/freescale/imx/imx_iomux.c	                        (rev 0)
+++ trunk/sys/arm/freescale/imx/imx_iomux.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,326 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014 Ian Lepore
+ * 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: stable/10/sys/arm/freescale/imx/imx_iomux.c 278732 2015-02-13 23:34:40Z ian $
+ */
+
+/*
+ * Pin mux and pad control driver for imx5 and imx6.
+ *
+ * This driver implements the fdt_pinctrl interface for configuring the gpio and
+ * peripheral pins based on fdt configuration data.
+ *
+ * When the driver attaches, it walks the entire fdt tree and automatically
+ * configures the pins for each device which has a pinctrl-0 property and whose
+ * status is "okay".  In addition it implements the fdt_pinctrl_configure()
+ * method which any other driver can call at any time to reconfigure its pins.
+ *
+ * The nature of the fsl,pins property in fdt data makes this driver's job very
+ * easy.  Instead of representing each pin and pad configuration using symbolic
+ * properties such as pullup-enable="true" and so on, the data simply contains
+ * the addresses of the registers that control the pins, and the raw values to
+ * store in those registers.
+ *
+ * The imx5 and imx6 SoCs also have a small number of "general purpose
+ * registers" in the iomuxc device which are used to control an assortment
+ * of completely unrelated aspects of SoC behavior.  This driver provides other
+ * drivers with direct access to those registers via simple accessor functions.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/fdt/fdt_pinctrl.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <arm/freescale/imx/imx_iomuxvar.h>
+#include <arm/freescale/imx/imx_machdep.h>
+
+struct iomux_softc {
+	device_t	dev;
+	struct resource	*mem_res;
+	u_int		last_gpreg;
+};
+
+static struct iomux_softc *iomux_sc;
+
+static struct ofw_compat_data compat_data[] = {
+	{"fsl,imx6dl-iomuxc",	true},
+	{"fsl,imx6q-iomuxc",	true},
+	{"fsl,imx6sl-iomuxc",	true},
+	{"fsl,imx6sx-iomuxc",	true},
+	{"fsl,imx53-iomuxc",	true},
+	{"fsl,imx51-iomuxc",	true},
+	{NULL,			false},
+};
+
+/*
+ * Each tuple in an fsl,pins property contains these fields.
+ */
+struct pincfg {
+	uint32_t mux_reg;
+	uint32_t padconf_reg;
+	uint32_t input_reg;
+	uint32_t mux_val;
+	uint32_t input_val;
+	uint32_t padconf_val;
+};
+
+#define	PADCONF_NONE	(1U << 31)	/* Do not configure pad. */
+#define	PADCONF_SION	(1U << 30)	/* Force SION bit in mux register. */
+#define	PADMUX_SION	(1U <<  4)	/* The SION bit in the mux register. */
+
+static inline uint32_t
+RD4(struct iomux_softc *sc, bus_size_t off)
+{
+
+	return (bus_read_4(sc->mem_res, off));
+}
+
+static inline void
+WR4(struct iomux_softc *sc, bus_size_t off, uint32_t val)
+{
+
+	bus_write_4(sc->mem_res, off, val);
+}
+
+static void
+iomux_configure_input(struct iomux_softc *sc, uint32_t reg, uint32_t val)
+{
+	u_int select, mask, shift, width;
+
+	/* If register and value are zero, there is nothing to configure. */
+	if (reg == 0 && val == 0)
+		return;
+
+	/*
+	 * If the config value has 0xff in the high byte it is encoded:
+	 * 	31     23      15      7        0
+	 *      | 0xff | shift | width | select |
+	 * We need to mask out the old select value and OR in the new, using a
+	 * mask of the given width and shifting the values up by shift.
+	 */
+	if ((val & 0xff000000) == 0xff000000) {
+		select = val & 0x000000ff;
+		width = (val & 0x0000ff00) >> 8;
+		shift = (val & 0x00ff0000) >> 16;
+		mask  = ((1u << width) - 1) << shift;
+		val = (RD4(sc, reg) & ~mask) | (select << shift);
+	}
+	WR4(sc, reg, val);
+}
+
+static int
+iomux_configure_pins(device_t dev, phandle_t cfgxref)
+{
+	struct iomux_softc *sc;
+	struct pincfg *cfgtuples, *cfg;
+	phandle_t cfgnode;
+	int i, ntuples;
+	uint32_t sion;
+
+	sc = device_get_softc(dev);
+	cfgnode = OF_node_from_xref(cfgxref);
+	ntuples = OF_getencprop_alloc(cfgnode, "fsl,pins", sizeof(*cfgtuples),
+	    (void **)&cfgtuples);
+	if (ntuples < 0)
+		return (ENOENT);
+	if (ntuples == 0)
+		return (0); /* Empty property is not an error. */
+	for (i = 0, cfg = cfgtuples; i < ntuples; i++, cfg++) {
+		sion = (cfg->padconf_val & PADCONF_SION) ? PADMUX_SION : 0;
+		WR4(sc, cfg->mux_reg, cfg->mux_val | sion);
+		iomux_configure_input(sc, cfg->input_reg, cfg->input_val);
+		if ((cfg->padconf_val & PADCONF_NONE) == 0)
+			WR4(sc, cfg->padconf_reg, cfg->padconf_val);
+		if (bootverbose) {
+			char name[32]; 
+			OF_getprop(cfgnode, "name", &name, sizeof(name));
+			printf("%16s: muxreg 0x%04x muxval 0x%02x "
+			    "inpreg 0x%04x inpval 0x%02x "
+			    "padreg 0x%04x padval 0x%08x\n",
+			    name, cfg->mux_reg, cfg->mux_val | sion,
+			    cfg->input_reg, cfg->input_val,
+			    cfg->padconf_reg, cfg->padconf_val);
+		}
+	}
+	free(cfgtuples, M_OFWPROP);
+	return (0);
+}
+
+static int
+iomux_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data)
+		return (ENXIO);
+
+	device_set_desc(dev, "Freescale i.MX pin configuration");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+iomux_detach(device_t dev)
+{
+
+        /* This device is always present. */
+	return (EBUSY);
+}
+
+static int
+iomux_attach(device_t dev)
+{
+	struct iomux_softc * sc;
+	int rid;
+
+	sc = device_get_softc(dev);
+	sc->dev = dev;
+
+	switch (imx_soc_type()) {
+	case IMXSOC_51:
+		sc->last_gpreg = 1;
+		break;
+	case IMXSOC_53:
+		sc->last_gpreg = 2;
+		break;
+	case IMXSOC_6DL:
+	case IMXSOC_6S:
+	case IMXSOC_6SL:
+	case IMXSOC_6Q:
+		sc->last_gpreg = 13;
+		break;
+	default:
+		device_printf(dev, "Unknown SoC type\n");
+		return (ENXIO);
+	}
+
+	rid = 0;
+	sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	    RF_ACTIVE);
+	if (sc->mem_res == NULL) {
+		device_printf(dev, "Cannot allocate memory resources\n");
+		return (ENXIO);
+	}
+
+	iomux_sc = sc;
+
+	/*
+	 * Register as a pinctrl device, and call the convenience function that
+	 * walks the entire device tree invoking FDT_PINCTRL_CONFIGURE() on any
+	 * pinctrl-0 property cells whose xref phandle refers to a configuration
+	 * that is a child node of our node in the tree.
+	 *
+	 * The pinctrl bindings documentation specifically mentions that the
+	 * pinctrl device itself may have a pinctrl-0 property which contains
+	 * static configuration to be applied at device init time.  The tree
+	 * walk will automatically handle this for us when it passes through our
+	 * node in the tree.
+	 */
+	fdt_pinctrl_register(dev, "fsl,pins");
+	fdt_pinctrl_configure_tree(dev);
+
+	return (0);
+}
+
+uint32_t
+imx_iomux_gpr_get(u_int regnum)
+{
+	struct iomux_softc * sc;
+
+	sc = iomux_sc;
+	KASSERT(sc != NULL, ("%s called before attach", __FUNCTION__));
+	KASSERT(regnum >= 0 && regnum <= sc->last_gpreg, 
+	    ("%s bad regnum %u, max %u", __FUNCTION__, regnum, sc->last_gpreg));
+
+	return (RD4(iomux_sc, regnum * 4));
+}
+
+void
+imx_iomux_gpr_set(u_int regnum, uint32_t val)
+{
+	struct iomux_softc * sc;
+
+	sc = iomux_sc;
+	KASSERT(sc != NULL, ("%s called before attach", __FUNCTION__));
+	KASSERT(regnum >= 0 && regnum <= sc->last_gpreg, 
+	    ("%s bad regnum %u, max %u", __FUNCTION__, regnum, sc->last_gpreg));
+
+	WR4(iomux_sc, regnum * 4, val);
+}
+
+void
+imx_iomux_gpr_set_masked(u_int regnum, uint32_t clrbits, uint32_t setbits)
+{
+	struct iomux_softc * sc;
+	uint32_t val;
+
+	sc = iomux_sc;
+	KASSERT(sc != NULL, ("%s called before attach", __FUNCTION__));
+	KASSERT(regnum >= 0 && regnum <= sc->last_gpreg, 
+	    ("%s bad regnum %u, max %u", __FUNCTION__, regnum, sc->last_gpreg));
+
+	val = RD4(iomux_sc, regnum * 4);
+	val = (val & ~clrbits) | setbits;
+	WR4(iomux_sc, regnum * 4, val);
+}
+
+static device_method_t imx_iomux_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,         iomux_probe),
+	DEVMETHOD(device_attach,        iomux_attach),
+	DEVMETHOD(device_detach,        iomux_detach),
+
+        /* fdt_pinctrl interface */
+	DEVMETHOD(fdt_pinctrl_configure,iomux_configure_pins),
+
+	DEVMETHOD_END
+};
+
+static driver_t imx_iomux_driver = {
+	"imx_iomux",
+	imx_iomux_methods,
+	sizeof(struct iomux_softc),
+};
+
+static devclass_t imx_iomux_devclass;
+
+EARLY_DRIVER_MODULE(imx_iomux, simplebus, imx_iomux_driver, 
+    imx_iomux_devclass, 0, 0, BUS_PASS_CPU + BUS_PASS_ORDER_LATE);
+


Property changes on: trunk/sys/arm/freescale/imx/imx_iomux.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/imx/imx_iomuxvar.h
===================================================================
--- trunk/sys/arm/freescale/imx/imx_iomuxvar.h	                        (rev 0)
+++ trunk/sys/arm/freescale/imx/imx_iomuxvar.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,50 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014 Ian Lepore <ian at freebsd.org>
+ * 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: stable/10/sys/arm/freescale/imx/imx_iomuxvar.h 273663 2014-10-26 02:44:41Z ian $
+ */
+
+#ifndef	IMX_IOMUXVAR_H
+#define	IMX_IOMUXVAR_H
+
+/*
+ * IOMUX interface functions
+ */
+void     iomux_set_function(u_int pin, u_int fn);
+void     iomux_set_pad(u_int pin, u_int cfg);
+u_int    iomux_get_pad_config(u_int pin);
+
+/*
+ * The IOMUX Controller device has a small set of "general purpose registers" 
+ * which control various aspects of SoC operation that really have nothing to do
+ * with IO pin assignments or pad control.  These functions let other soc level
+ * code manipulate these values.
+ */
+uint32_t imx_iomux_gpr_get(u_int regnum);
+void     imx_iomux_gpr_set(u_int regnum, uint32_t val);
+void     imx_iomux_gpr_set_masked(u_int regnum, uint32_t clrbits, uint32_t setbits);
+
+#endif


Property changes on: trunk/sys/arm/freescale/imx/imx_iomuxvar.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/imx/imx_machdep.c
===================================================================
--- trunk/sys/arm/freescale/imx/imx_machdep.c	                        (rev 0)
+++ trunk/sys/arm/freescale/imx/imx_machdep.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,121 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Ian Lepore <ian at freebsd.org>
+ * 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: stable/10/sys/arm/freescale/imx/imx_machdep.c 294678 2016-01-24 19:34:05Z ian $");
+
+#define _ARM32_BUS_DMA_PRIVATE
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/reboot.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <machine/armreg.h>
+#include <machine/bus.h>
+#include <machine/devmap.h>
+#include <machine/machdep.h>
+
+#include <arm/freescale/imx/imx_machdep.h>
+#include <arm/freescale/imx/imx_wdogreg.h>
+
+SYSCTL_NODE(_hw, OID_AUTO, imx, CTLFLAG_RW, NULL, "i.MX container");
+
+static int last_reset_status;
+SYSCTL_UINT(_hw_imx, OID_AUTO, last_reset_status, CTLFLAG_RD, 
+    &last_reset_status, 0, "Last reset status register");
+
+SYSCTL_STRING(_hw_imx, OID_AUTO, last_reset_reason, CTLFLAG_RD, 
+    "unknown", 0, "Last reset reason");
+
+struct arm32_dma_range *
+bus_dma_get_range(void)
+{
+
+	return (NULL);
+}
+
+int
+bus_dma_get_range_nb(void)
+{
+
+	return (0);
+}
+
+/*
+ * This code which manipulates the watchdog hardware is here to implement
+ * cpu_reset() because the watchdog is the only way for software to reset the
+ * chip.  Why here and not in imx_wdog.c?  Because there's no requirement that
+ * the watchdog driver be compiled in, but it's nice to be able to reboot even
+ * if it's not.
+ */
+void
+imx_wdog_cpu_reset(vm_offset_t wdcr_physaddr)
+{
+	volatile uint16_t * pcr;
+
+	/*
+	 * Trigger an immediate reset by clearing the SRS bit in the watchdog
+	 * control register.  The reset happens on the next cycle of the wdog
+	 * 32KHz clock, so hang out in a spin loop until the reset takes effect.
+	 */
+	if ((pcr = arm_devmap_ptov(wdcr_physaddr, sizeof(*pcr))) == NULL) {
+		printf("cpu_reset() can't find its control register... locking up now.");
+	} else {
+		*pcr &= ~WDOG_CR_SRS;
+	}
+	for (;;)
+		continue;
+}
+
+void
+imx_wdog_init_last_reset(vm_offset_t wdsr_phys)
+{
+	volatile uint16_t * psr;
+
+	if ((psr = arm_devmap_ptov(wdsr_phys, sizeof(*psr))) == NULL)
+		return;
+	last_reset_status = *psr;
+	if (last_reset_status & WDOG_RSR_SFTW) {
+		sysctl___hw_imx_last_reset_reason.oid_arg1 = "SoftwareReset";
+	} else if (last_reset_status & WDOG_RSR_TOUT) {
+		sysctl___hw_imx_last_reset_reason.oid_arg1 = "WatchdogTimeout";
+	} else if (last_reset_status & WDOG_RSR_POR) {
+		sysctl___hw_imx_last_reset_reason.oid_arg1 = "PowerOnReset";
+	}
+}
+
+u_int
+imx_soc_family(void)
+{
+	return (imx_soc_type() >> IMXSOC_FAMSHIFT);
+}
+
+


Property changes on: trunk/sys/arm/freescale/imx/imx_machdep.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/imx/imx_machdep.h
===================================================================
--- trunk/sys/arm/freescale/imx/imx_machdep.h	                        (rev 0)
+++ trunk/sys/arm/freescale/imx/imx_machdep.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,65 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Ian Lepore <ian at freebsd.org>
+ * 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: stable/10/sys/arm/freescale/imx/imx_machdep.h 294678 2016-01-24 19:34:05Z ian $
+ */
+
+#ifndef	IMX_MACHDEP_H
+#define	IMX_MACHDEP_H
+
+#include <sys/types.h>
+#include <sys/sysctl.h>
+
+SYSCTL_DECL(_hw_imx);
+
+/* Common functions, implemented in imx_machdep.c. */
+
+void imx_wdog_cpu_reset(vm_offset_t _wdcr_phys)  __attribute__((__noreturn__));
+void imx_wdog_init_last_reset(vm_offset_t _wdsr_phys);
+
+/* From here down, routines are implemented in imxNN_machdep.c. */
+
+/*
+ * SoC identity.
+ * According to the documentation, there is such a thing as an i.MX6 Dual
+ * (non-lite flavor).  However, Freescale doesn't seem to have assigned it a
+ * number in their code for determining the SoC type in u-boot.
+ *
+ * To-do: put silicon revision numbers into the low-order bits somewhere.
+ */
+#define	IMXSOC_51	0x51000000
+#define	IMXSOC_53	0x53000000
+#define	IMXSOC_6SL	0x60000000
+#define	IMXSOC_6DL	0x61000000
+#define	IMXSOC_6S	0x62000000
+#define	IMXSOC_6Q	0x63000000
+#define	IMXSOC_FAMSHIFT	28
+
+u_int imx_soc_type(void);
+u_int imx_soc_family(void);
+
+#endif
+


Property changes on: trunk/sys/arm/freescale/imx/imx_machdep.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/imx/imx_nop_usbphy.c
===================================================================
--- trunk/sys/arm/freescale/imx/imx_nop_usbphy.c	                        (rev 0)
+++ trunk/sys/arm/freescale/imx/imx_nop_usbphy.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,122 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Ian Lepore <ian at freebsd.org>
+ * 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: stable/10/sys/arm/freescale/imx/imx_nop_usbphy.c 266371 2014-05-17 22:29:24Z ian $");
+
+/*
+ * USBPHY "no-op" driver for Freescale family of SoCs.  This driver is used on
+ * SoCs which have usbphy hardware whose clocks need to be enabled, but no other
+ * action has to be taken to make the hardware work.
+ */
+
+#include "opt_bus.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/rman.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+
+#include <arm/freescale/imx/imx_ccmvar.h>
+
+/*
+ * Table of supported FDT compat strings.
+ */
+static struct ofw_compat_data compat_data[] = {
+	{"nop-usbphy",		true},
+	{"usb-nop-xceiv",	true},
+	{NULL,		 	false},
+};
+
+struct usbphy_softc {
+	device_t	dev;
+	u_int		phy_num;
+};
+
+static int
+usbphy_detach(device_t dev)
+{
+
+	return (0);
+}
+
+static int
+usbphy_attach(device_t dev)
+{
+	struct usbphy_softc *sc;
+
+	sc = device_get_softc(dev);
+
+	/*
+         * Turn on the phy clocks.
+         */
+	imx_ccm_usbphy_enable(dev);
+
+	return (0);
+}
+
+static int
+usbphy_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (ofw_bus_search_compatible(dev, compat_data)->ocd_data != 0) {
+		device_set_desc(dev, "Freescale USB PHY");
+		return (BUS_PROBE_DEFAULT);
+	}
+
+	return (ENXIO);
+}
+
+static device_method_t usbphy_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,  usbphy_probe),
+	DEVMETHOD(device_attach, usbphy_attach),
+	DEVMETHOD(device_detach, usbphy_detach),
+
+	DEVMETHOD_END
+};
+
+static driver_t usbphy_driver = {
+	"usbphy",
+	usbphy_methods,
+	sizeof(struct usbphy_softc)
+};
+
+static devclass_t usbphy_devclass;
+
+DRIVER_MODULE(usbphy, simplebus, usbphy_driver, usbphy_devclass, 0, 0);
+


Property changes on: trunk/sys/arm/freescale/imx/imx_nop_usbphy.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/imx/imx_sdhci.c
===================================================================
--- trunk/sys/arm/freescale/imx/imx_sdhci.c	                        (rev 0)
+++ trunk/sys/arm/freescale/imx/imx_sdhci.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,839 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Ian Lepore <ian at freebsd.org>
+ * 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: stable/10/sys/arm/freescale/imx/imx_sdhci.c 321946 2017-08-02 20:27:30Z marius $");
+
+/*
+ * SDHCI driver glue for Freescale i.MX SoC family.
+ *
+ * This supports both eSDHC (earlier SoCs) and uSDHC (more recent SoCs).
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/types.h>
+#include <sys/bus.h>
+#include <sys/callout.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+#include <sys/sysctl.h>
+#include <sys/taskqueue.h>
+#include <sys/time.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+#include <machine/intr.h>
+
+#include <arm/freescale/imx/imx_ccmvar.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <dev/mmc/bridge.h>
+
+#include <dev/sdhci/sdhci.h>
+
+#include "mmcbr_if.h"
+#include "sdhci_if.h"
+
+struct imx_sdhci_softc {
+	device_t		dev;
+	struct resource *	mem_res;
+	struct resource *	irq_res;
+	void *			intr_cookie;
+	struct sdhci_slot	slot;
+	struct callout		r1bfix_callout;
+	sbintime_t		r1bfix_timeout_at;
+	uint32_t		baseclk_hz;
+	uint32_t		sdclockreg_freq_bits;
+	uint32_t		cmd_and_mode;
+	uint32_t		r1bfix_intmask;
+	uint8_t			r1bfix_type;
+	uint8_t			hwtype;
+	boolean_t		force_card_present;
+};
+
+#define	R1BFIX_NONE	0	/* No fix needed at next interrupt. */
+#define	R1BFIX_NODATA	1	/* Synthesize DATA_END for R1B w/o data. */
+#define	R1BFIX_AC12	2	/* Wait for busy after auto command 12. */
+
+#define	HWTYPE_NONE	0	/* Hardware not recognized/supported. */
+#define	HWTYPE_ESDHC	1	/* imx5x and earlier. */
+#define	HWTYPE_USDHC	2	/* imx6. */
+
+#define	SDHC_WTMK_LVL		0x44	/* Watermark Level register. */
+#define	USDHC_MIX_CONTROL	0x48	/* Mix(ed) Control register. */
+#define	SDHC_VEND_SPEC		0xC0	/* Vendor-specific register. */
+#define	 SDHC_VEND_FRC_SDCLK_ON	(1 <<  8)
+#define	 SDHC_VEND_IPGEN	(1 << 11)
+#define	 SDHC_VEND_HCKEN	(1 << 12)
+#define	 SDHC_VEND_PEREN	(1 << 13)
+
+#define	SDHC_PRES_STATE		0x24
+#define	  SDHC_PRES_CIHB	  (1 <<  0)
+#define	  SDHC_PRES_CDIHB	  (1 <<  1)
+#define	  SDHC_PRES_DLA		  (1 <<  2)
+#define	  SDHC_PRES_SDSTB	  (1 <<  3)
+#define	  SDHC_PRES_IPGOFF	  (1 <<  4)
+#define	  SDHC_PRES_HCKOFF	  (1 <<  5)
+#define	  SDHC_PRES_PEROFF	  (1 <<  6)
+#define	  SDHC_PRES_SDOFF	  (1 <<  7)
+#define	  SDHC_PRES_WTA		  (1 <<  8)
+#define	  SDHC_PRES_RTA		  (1 <<  9)
+#define	  SDHC_PRES_BWEN	  (1 << 10)
+#define	  SDHC_PRES_BREN	  (1 << 11)
+#define	  SDHC_PRES_RTR		  (1 << 12)
+#define	  SDHC_PRES_CINST	  (1 << 16)
+#define	  SDHC_PRES_CDPL	  (1 << 18)
+#define	  SDHC_PRES_WPSPL	  (1 << 19)
+#define	  SDHC_PRES_CLSL	  (1 << 23)
+#define	  SDHC_PRES_DLSL_SHIFT	  24
+#define	  SDHC_PRES_DLSL_MASK	  (0xffU << SDHC_PRES_DLSL_SHIFT)
+
+#define	SDHC_PROT_CTRL		0x28
+#define	 SDHC_PROT_LED		(1 << 0)
+#define	 SDHC_PROT_WIDTH_1BIT	(0 << 1)
+#define	 SDHC_PROT_WIDTH_4BIT	(1 << 1)
+#define	 SDHC_PROT_WIDTH_8BIT	(2 << 1)
+#define	 SDHC_PROT_WIDTH_MASK	(3 << 1)
+#define	 SDHC_PROT_D3CD		(1 << 3)
+#define	 SDHC_PROT_EMODE_BIG	(0 << 4)
+#define	 SDHC_PROT_EMODE_HALF	(1 << 4)
+#define	 SDHC_PROT_EMODE_LITTLE	(2 << 4)
+#define	 SDHC_PROT_EMODE_MASK	(3 << 4)
+#define	 SDHC_PROT_SDMA		(0 << 8)
+#define	 SDHC_PROT_ADMA1	(1 << 8)
+#define	 SDHC_PROT_ADMA2	(2 << 8)
+#define	 SDHC_PROT_ADMA264	(3 << 8)
+#define	 SDHC_PROT_DMA_MASK	(3 << 8)
+#define	 SDHC_PROT_CDTL		(1 << 6)
+#define	 SDHC_PROT_CDSS		(1 << 7)
+
+#define	SDHC_INT_STATUS		0x30
+
+#define	SDHC_CLK_IPGEN		(1 << 0)
+#define	SDHC_CLK_HCKEN		(1 << 1)
+#define	SDHC_CLK_PEREN		(1 << 2)
+#define	SDHC_CLK_DIVISOR_MASK	0x000000f0
+#define	SDHC_CLK_DIVISOR_SHIFT	4
+#define	SDHC_CLK_PRESCALE_MASK	0x0000ff00
+#define	SDHC_CLK_PRESCALE_SHIFT	8
+
+static struct ofw_compat_data compat_data[] = {
+	{"fsl,imx6q-usdhc",	HWTYPE_USDHC},
+	{"fsl,imx6sl-usdhc",	HWTYPE_USDHC},
+	{"fsl,imx53-esdhc",	HWTYPE_ESDHC},
+	{"fsl,imx51-esdhc",	HWTYPE_ESDHC},
+	{NULL,			HWTYPE_NONE},
+};;
+
+static void imx_sdhc_set_clock(struct imx_sdhci_softc *sc, int enable);
+static void imx_sdhci_r1bfix_func(void *arg);
+
+static inline uint32_t
+RD4(struct imx_sdhci_softc *sc, bus_size_t off)
+{
+
+	return (bus_read_4(sc->mem_res, off));
+}
+
+static inline void
+WR4(struct imx_sdhci_softc *sc, bus_size_t off, uint32_t val)
+{
+
+	bus_write_4(sc->mem_res, off, val);
+}
+
+static uint8_t
+imx_sdhci_read_1(device_t dev, struct sdhci_slot *slot, bus_size_t off)
+{
+	struct imx_sdhci_softc *sc = device_get_softc(dev);
+	uint32_t val32, wrk32;
+
+	/*
+	 * Most of the things in the standard host control register are in the
+	 * hardware's wider protocol control register, but some of the bits are
+	 * moved around.
+	 */
+	if (off == SDHCI_HOST_CONTROL) {
+		wrk32 = RD4(sc, SDHC_PROT_CTRL);
+                val32 = wrk32 & (SDHCI_CTRL_LED | SDHCI_CTRL_CARD_DET |
+		    SDHCI_CTRL_FORCE_CARD);
+		switch (wrk32 & SDHC_PROT_WIDTH_MASK) {
+		case SDHC_PROT_WIDTH_1BIT:
+			/* Value is already 0. */
+			break;
+		case SDHC_PROT_WIDTH_4BIT:
+			val32 |= SDHCI_CTRL_4BITBUS;
+			break;
+		case SDHC_PROT_WIDTH_8BIT:
+			val32 |= SDHCI_CTRL_8BITBUS;
+			break;
+		}
+		switch (wrk32 & SDHC_PROT_DMA_MASK) {
+		case SDHC_PROT_SDMA:
+			/* Value is already 0. */
+			break;
+		case SDHC_PROT_ADMA1:
+                        /* This value is deprecated, should never appear. */
+			break;
+		case SDHC_PROT_ADMA2:
+			val32 |= SDHCI_CTRL_ADMA2;
+			break;
+		case SDHC_PROT_ADMA264:
+			val32 |= SDHCI_CTRL_ADMA264;
+			break;
+		}
+		return val32;
+	}
+
+	/*
+	 * XXX can't find the bus power on/off knob.  For now we have to say the
+	 * power is always on and always set to the same voltage.
+	 */
+	if (off == SDHCI_POWER_CONTROL) {
+                return (SDHCI_POWER_ON | SDHCI_POWER_300);
+	}
+
+
+	return ((RD4(sc, off & ~3) >> (off & 3) * 8) & 0xff);
+}
+
+static uint16_t
+imx_sdhci_read_2(device_t dev, struct sdhci_slot *slot, bus_size_t off)
+{
+	struct imx_sdhci_softc *sc = device_get_softc(dev);
+	uint32_t val32, wrk32;
+
+	if (sc->hwtype == HWTYPE_USDHC) {
+		/*
+		 * The USDHC hardware has nothing in the version register, but
+		 * it's v3 compatible with all our translation code.
+		 */
+		if (off == SDHCI_HOST_VERSION) {
+			return (SDHCI_SPEC_300 << SDHCI_SPEC_VER_SHIFT);
+		}
+		/*
+		 * The USDHC hardware moved the transfer mode bits to the mixed
+		 * control register, fetch them from there.
+		 */
+		if (off == SDHCI_TRANSFER_MODE)
+			return (RD4(sc, USDHC_MIX_CONTROL) & 0x37);
+
+	} else if (sc->hwtype == HWTYPE_ESDHC) {
+
+		/*
+		 * The ESDHC hardware has the typical 32-bit combined "command
+		 * and mode" register that we have to cache so that command
+		 * isn't written until after mode.  On a read, just retrieve the
+		 * cached values last written.
+		 */
+		if (off == SDHCI_TRANSFER_MODE) {
+			return (sc->cmd_and_mode >> 16);
+		} else if (off == SDHCI_COMMAND_FLAGS) {
+			return (sc->cmd_and_mode & 0x0000ffff);
+		}
+	}
+
+	/*
+	 * This hardware only manages one slot.  Synthesize a slot interrupt
+	 * status register... if there are any enabled interrupts active they
+	 * must be coming from our one and only slot.
+	 */
+	if (off == SDHCI_SLOT_INT_STATUS) {
+		val32  = RD4(sc, SDHCI_INT_STATUS);
+		val32 &= RD4(sc, SDHCI_SIGNAL_ENABLE);
+		return (val32 ? 1 : 0);
+	}
+
+	/*
+	 * The clock enable bit is in the vendor register and the clock-stable
+	 * bit is in the present state register.  Transcribe them as if they
+	 * were in the clock control register where they should be.
+	 * XXX Is it important that we distinguish between "internal" and "card"
+	 * clocks?  Probably not; transcribe the card clock status to both bits.
+	 */
+	if (off == SDHCI_CLOCK_CONTROL) {
+		val32 = 0;
+		wrk32 = RD4(sc, SDHC_VEND_SPEC);
+		if (wrk32 & SDHC_VEND_FRC_SDCLK_ON)
+			val32 |= SDHCI_CLOCK_INT_EN | SDHCI_CLOCK_CARD_EN;
+		wrk32 = RD4(sc, SDHC_PRES_STATE);
+		if (wrk32 & SDHC_PRES_SDSTB)
+			val32 |= SDHCI_CLOCK_INT_STABLE;
+		val32 |= sc->sdclockreg_freq_bits;
+		return (val32);
+	}
+
+	return ((RD4(sc, off & ~3) >> (off & 3) * 8) & 0xffff);
+}
+
+static uint32_t
+imx_sdhci_read_4(device_t dev, struct sdhci_slot *slot, bus_size_t off)
+{
+	struct imx_sdhci_softc *sc = device_get_softc(dev);
+	uint32_t val32, wrk32;
+
+	val32 = RD4(sc, off);
+
+	/*
+	 * The hardware leaves the base clock frequency out of the capabilities
+	 * register; fill it in.  The timeout clock is the same as the active
+	 * output sdclock; we indicate that with a quirk setting so don't
+	 * populate the timeout frequency bits.
+	 *
+	 * XXX Turn off (for now) features the hardware can do but this driver
+	 * doesn't yet handle (1.8v, suspend/resume, etc).
+	 */
+	if (off == SDHCI_CAPABILITIES) {
+		val32 &= ~SDHCI_CAN_VDD_180;
+		val32 &= ~SDHCI_CAN_DO_SUSPEND;
+		val32 |= SDHCI_CAN_DO_8BITBUS;
+		val32 |= (sc->baseclk_hz / 1000000) << SDHCI_CLOCK_BASE_SHIFT;
+		return (val32);
+	}
+	
+	/*
+	 * The hardware moves bits around in the present state register to make
+	 * room for all 8 data line state bits.  To translate, mask out all the
+	 * bits which are not in the same position in both registers (this also
+	 * masks out some freescale-specific bits in locations defined as
+	 * reserved by sdhci), then shift the data line and retune request bits
+	 * down to their standard locations.
+	 */
+	if (off == SDHCI_PRESENT_STATE) {
+		wrk32 = val32;
+		val32 &= 0x000F0F07;
+		val32 |= (wrk32 >> 4) & SDHCI_STATE_DAT_MASK;
+		val32 |= (wrk32 >> 9) & SDHCI_RETUNE_REQUEST;
+		if (sc->force_card_present)
+			val32 |= SDHCI_CARD_PRESENT;
+		return (val32);
+	}
+
+	/*
+	 * imx_sdhci_intr() can synthesize a DATA_END interrupt following a
+	 * command with an R1B response, mix it into the hardware status.
+	 */
+	if (off == SDHCI_INT_STATUS) {
+		return (val32 | sc->r1bfix_intmask);
+	}
+
+	return val32;
+}
+
+static void
+imx_sdhci_read_multi_4(device_t dev, struct sdhci_slot *slot, bus_size_t off,
+    uint32_t *data, bus_size_t count)
+{
+	struct imx_sdhci_softc *sc = device_get_softc(dev);
+
+	bus_read_multi_4(sc->mem_res, off, data, count);
+}
+
+static void
+imx_sdhci_write_1(device_t dev, struct sdhci_slot *slot, bus_size_t off, uint8_t val)
+{
+	struct imx_sdhci_softc *sc = device_get_softc(dev);
+	uint32_t val32;
+
+	/*
+	 * Most of the things in the standard host control register are in the
+	 * hardware's wider protocol control register, but some of the bits are
+	 * moved around.
+	 */
+	if (off == SDHCI_HOST_CONTROL) {
+		val32 = RD4(sc, SDHC_PROT_CTRL);
+		val32 &= ~(SDHC_PROT_LED | SDHC_PROT_DMA_MASK |
+		    SDHC_PROT_WIDTH_MASK | SDHC_PROT_CDTL | SDHC_PROT_CDSS);
+		val32 |= (val & SDHCI_CTRL_LED);
+		if (val & SDHCI_CTRL_8BITBUS)
+			val32 |= SDHC_PROT_WIDTH_8BIT;
+		else
+			val32 |= (val & SDHCI_CTRL_4BITBUS);
+		val32 |= (val & (SDHCI_CTRL_SDMA | SDHCI_CTRL_ADMA2)) << 4;
+		val32 |= (val & (SDHCI_CTRL_CARD_DET | SDHCI_CTRL_FORCE_CARD));
+		WR4(sc, SDHC_PROT_CTRL, val32);
+		return;
+	}
+
+	/* XXX I can't find the bus power on/off knob; do nothing. */
+	if (off == SDHCI_POWER_CONTROL) {
+		return;
+	}
+
+	val32 = RD4(sc, off & ~3);
+	val32 &= ~(0xff << (off & 3) * 8);
+	val32 |= (val << (off & 3) * 8);
+
+	WR4(sc, off & ~3, val32);
+}
+
+static void
+imx_sdhci_write_2(device_t dev, struct sdhci_slot *slot, bus_size_t off, uint16_t val)
+{
+	struct imx_sdhci_softc *sc = device_get_softc(dev);
+	uint32_t val32;
+
+	/* The USDHC hardware moved the transfer mode bits to mixed control. */
+	if (sc->hwtype == HWTYPE_USDHC) {
+		if (off == SDHCI_TRANSFER_MODE) {
+			val32 = RD4(sc, USDHC_MIX_CONTROL);
+			val32 &= ~0x3f;
+			val32 |= val & 0x37;
+			// XXX acmd23 not supported here (or by sdhci driver)
+			WR4(sc, USDHC_MIX_CONTROL, val32);
+			return;
+		}
+	} 
+
+	/*
+	 * The clock control stuff is complex enough to have its own routine
+	 * that can both change speeds and en/disable the clock output. Also,
+	 * save the register bits in SDHCI format so that we can play them back
+	 * in the read2 routine without complex decoding.
+	 */
+	if (off == SDHCI_CLOCK_CONTROL) {
+		sc->sdclockreg_freq_bits = val & 0xffc0;
+		if (val & SDHCI_CLOCK_CARD_EN) {
+			imx_sdhc_set_clock(sc, true);
+		} else {
+			imx_sdhc_set_clock(sc, false);
+		}
+		return;
+	}
+
+	/*
+	 * Figure out whether we need to check the DAT0 line for busy status at
+	 * interrupt time.  The controller should be doing this, but for some
+	 * reason it doesn't.  There are two cases:
+	 *  - R1B response with no data transfer should generate a DATA_END (aka
+	 *    TRANSFER_COMPLETE) interrupt after waiting for busy, but if
+	 *    there's no data transfer there's no DATA_END interrupt.  This is
+	 *    documented; they seem to think it's a feature.
+	 *  - R1B response after Auto-CMD12 appears to not work, even though
+	 *    there's a control bit for it (bit 3) in the vendor register.
+	 * When we're starting a command that needs a manual DAT0 line check at
+	 * interrupt time, we leave ourselves a note in r1bfix_type so that we
+	 * can do the extra work in imx_sdhci_intr().
+	 */
+	if (off == SDHCI_COMMAND_FLAGS) {
+		if (val & SDHCI_CMD_DATA) {
+			const uint32_t MBAUTOCMD = SDHCI_TRNS_ACMD12 | SDHCI_TRNS_MULTI;
+			val32 = RD4(sc, USDHC_MIX_CONTROL);
+			if ((val32 & MBAUTOCMD) == MBAUTOCMD)
+				sc->r1bfix_type = R1BFIX_AC12;
+		} else {
+			if ((val & SDHCI_CMD_RESP_MASK) == SDHCI_CMD_RESP_SHORT_BUSY) {
+				WR4(sc, SDHCI_INT_ENABLE, slot->intmask | SDHCI_INT_RESPONSE);
+				WR4(sc, SDHCI_SIGNAL_ENABLE, slot->intmask | SDHCI_INT_RESPONSE);
+				sc->r1bfix_type = R1BFIX_NODATA;
+			}
+		}
+	}
+
+	val32 = RD4(sc, off & ~3);
+	val32 &= ~(0xffff << (off & 3) * 8);
+	val32 |= ((val & 0xffff) << (off & 3) * 8);
+	WR4(sc, off & ~3, val32);	
+}
+
+static void
+imx_sdhci_write_4(device_t dev, struct sdhci_slot *slot, bus_size_t off, uint32_t val)
+{
+	struct imx_sdhci_softc *sc = device_get_softc(dev);
+
+	/* Clear synthesized interrupts, then pass the value to the hardware. */
+	if (off == SDHCI_INT_STATUS) {
+		sc->r1bfix_intmask &= ~val;
+	}
+
+	WR4(sc, off, val);
+}
+
+static void
+imx_sdhci_write_multi_4(device_t dev, struct sdhci_slot *slot, bus_size_t off,
+    uint32_t *data, bus_size_t count)
+{
+	struct imx_sdhci_softc *sc = device_get_softc(dev);
+
+	bus_write_multi_4(sc->mem_res, off, data, count);
+}
+
+static void 
+imx_sdhc_set_clock(struct imx_sdhci_softc *sc, int enable)
+{
+	uint32_t divisor, enable_bits, enable_reg, freq, prescale, val32;
+
+	if (sc->hwtype == HWTYPE_ESDHC) {
+		divisor = (sc->sdclockreg_freq_bits >> SDHCI_DIVIDER_SHIFT) &
+		    SDHCI_DIVIDER_MASK;
+		enable_reg = SDHCI_CLOCK_CONTROL;
+		enable_bits = SDHC_CLK_IPGEN | SDHC_CLK_HCKEN |
+		    SDHC_CLK_PEREN;
+	} else {
+		divisor = (sc->sdclockreg_freq_bits >> SDHCI_DIVIDER_SHIFT) &
+		    SDHCI_DIVIDER_MASK;
+		divisor |= ((sc->sdclockreg_freq_bits >> 
+		    SDHCI_DIVIDER_HI_SHIFT) &
+		    SDHCI_DIVIDER_HI_MASK) << SDHCI_DIVIDER_MASK_LEN;
+		enable_reg = SDHCI_CLOCK_CONTROL;
+		enable_bits = SDHC_VEND_IPGEN | SDHC_VEND_HCKEN |
+		   SDHC_VEND_PEREN;
+	}
+
+	WR4(sc, SDHC_VEND_SPEC, 
+	    RD4(sc, SDHC_VEND_SPEC) & ~SDHC_VEND_FRC_SDCLK_ON);
+	WR4(sc, enable_reg, RD4(sc, enable_reg) & ~enable_bits);
+
+	if (!enable)
+		return;
+
+	if (divisor == 0)
+		freq = sc->baseclk_hz;
+	else
+		freq = sc->baseclk_hz / (2 * divisor);
+
+	for (prescale = 2; freq < sc->baseclk_hz / (prescale * 16);)
+		prescale <<= 1;
+
+	for (divisor = 1; freq < sc->baseclk_hz / (prescale * divisor);)
+		++divisor;
+
+#ifdef DEBUG	
+	device_printf(sc->dev,
+	    "desired SD freq: %d, actual: %d; base %d prescale %d divisor %d\n",
+	    freq, sc->baseclk_hz / (prescale * divisor), sc->baseclk_hz, 
+	    prescale, divisor);
+#endif	
+
+	prescale >>= 1;
+	divisor -= 1;
+
+	val32 = RD4(sc, SDHCI_CLOCK_CONTROL);
+	val32 &= ~SDHC_CLK_DIVISOR_MASK;
+	val32 |= divisor << SDHC_CLK_DIVISOR_SHIFT;
+	val32 &= ~SDHC_CLK_PRESCALE_MASK;
+	val32 |= prescale << SDHC_CLK_PRESCALE_SHIFT;
+	WR4(sc, SDHCI_CLOCK_CONTROL, val32);
+
+	WR4(sc, enable_reg, RD4(sc, enable_reg) | enable_bits);
+	WR4(sc, SDHC_VEND_SPEC, 
+	    RD4(sc, SDHC_VEND_SPEC) | SDHC_VEND_FRC_SDCLK_ON);
+}
+
+static boolean_t
+imx_sdhci_r1bfix_is_wait_done(struct imx_sdhci_softc *sc)
+{
+	uint32_t inhibit;
+
+	mtx_assert(&sc->slot.mtx, MA_OWNED);
+
+	/*
+	 * Check the DAT0 line status using both the DLA (data line active) and
+	 * CDIHB (data inhibit) bits in the present state register.  In theory
+	 * just DLA should do the trick,  but in practice it takes both.  If the
+	 * DAT0 line is still being held and we're not yet beyond the timeout
+	 * point, just schedule another callout to check again later.
+	 */
+	inhibit = RD4(sc, SDHC_PRES_STATE) & (SDHC_PRES_DLA | SDHC_PRES_CDIHB);
+
+	if (inhibit && getsbinuptime() < sc->r1bfix_timeout_at) {
+		callout_reset_sbt(&sc->r1bfix_callout, SBT_1MS, 0, 
+		    imx_sdhci_r1bfix_func, sc, 0);
+		return (false);
+	}
+
+	/*
+	 * If we reach this point with the inhibit bits still set, we've got a
+	 * timeout, synthesize a DATA_TIMEOUT interrupt.  Otherwise the DAT0
+	 * line has been released, and we synthesize a DATA_END, and if the type
+	 * of fix needed was on a command-without-data we also now add in the
+	 * original INT_RESPONSE that we suppressed earlier.
+	 */
+	if (inhibit)
+		sc->r1bfix_intmask |= SDHCI_INT_DATA_TIMEOUT;
+	else {
+		sc->r1bfix_intmask |= SDHCI_INT_DATA_END;
+		if (sc->r1bfix_type == R1BFIX_NODATA)
+			sc->r1bfix_intmask |= SDHCI_INT_RESPONSE;
+	}
+
+	sc->r1bfix_type = R1BFIX_NONE;
+	return (true);
+}
+
+static void
+imx_sdhci_r1bfix_func(void * arg)
+{
+	struct imx_sdhci_softc *sc = arg;
+	boolean_t r1bwait_done;
+
+	mtx_lock(&sc->slot.mtx);
+	r1bwait_done = imx_sdhci_r1bfix_is_wait_done(sc);
+	mtx_unlock(&sc->slot.mtx);
+	if (r1bwait_done)
+		sdhci_generic_intr(&sc->slot);
+}
+
+static void
+imx_sdhci_intr(void *arg)
+{
+	struct imx_sdhci_softc *sc = arg;
+	uint32_t intmask;
+
+	mtx_lock(&sc->slot.mtx);
+
+	/*
+	 * Manually check the DAT0 line for R1B response types that the
+	 * controller fails to handle properly.  The controller asserts the done
+	 * interrupt while the card is still asserting busy with the DAT0 line.
+	 *
+	 * We check DAT0 immediately because most of the time, especially on a
+	 * read, the card will actually be done by time we get here.  If it's
+	 * not, then the wait_done routine will schedule a callout to re-check
+	 * periodically until it is done.  In that case we clear the interrupt
+	 * out of the hardware now so that we can present it later when the DAT0
+	 * line is released.
+	 *
+	 * If we need to wait for the the DAT0 line to be released, we set up a
+	 * timeout point 250ms in the future.  This number comes from the SD
+	 * spec, which allows a command to take that long.  In the real world,
+	 * cards tend to take 10-20ms for a long-running command such as a write
+	 * or erase that spans two pages.
+	 */
+	switch (sc->r1bfix_type) {
+	case R1BFIX_NODATA:
+		intmask = RD4(sc, SDHC_INT_STATUS) & SDHCI_INT_RESPONSE;
+		break;
+	case R1BFIX_AC12:
+		intmask = RD4(sc, SDHC_INT_STATUS) & SDHCI_INT_DATA_END;
+		break;
+	default:
+		intmask = 0;
+		break;
+	}
+	if (intmask) {
+		sc->r1bfix_timeout_at = getsbinuptime() + 250 * SBT_1MS;
+		if (!imx_sdhci_r1bfix_is_wait_done(sc)) {
+			WR4(sc, SDHC_INT_STATUS, intmask);
+			bus_barrier(sc->mem_res, SDHC_INT_STATUS, 4, 
+			    BUS_SPACE_BARRIER_WRITE);
+		}
+	}
+
+	mtx_unlock(&sc->slot.mtx);
+	sdhci_generic_intr(&sc->slot);
+}
+
+static int
+imx_sdhci_get_ro(device_t bus, device_t child)
+{
+
+	return (false);
+}
+
+static int
+imx_sdhci_detach(device_t dev)
+{
+
+	return (EBUSY);
+}
+
+static int
+imx_sdhci_attach(device_t dev)
+{
+	struct imx_sdhci_softc *sc = device_get_softc(dev);
+	int rid, err;
+	phandle_t node;
+
+	sc->dev = dev;
+
+	sc->hwtype = ofw_bus_search_compatible(dev, compat_data)->ocd_data;
+	if (sc->hwtype == HWTYPE_NONE)
+		panic("Impossible: not compatible in imx_sdhci_attach()");
+
+	rid = 0;
+	sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	    RF_ACTIVE);
+	if (!sc->mem_res) {
+		device_printf(dev, "cannot allocate memory window\n");
+		err = ENXIO;
+		goto fail;
+	}
+
+	rid = 0;
+	sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+	    RF_ACTIVE);
+	if (!sc->irq_res) {
+		device_printf(dev, "cannot allocate interrupt\n");
+		err = ENXIO;
+		goto fail;
+	}
+
+	if (bus_setup_intr(dev, sc->irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
+	    NULL, imx_sdhci_intr, sc, &sc->intr_cookie)) {
+		device_printf(dev, "cannot setup interrupt handler\n");
+		err = ENXIO;
+		goto fail;
+	}
+
+	sc->slot.quirks |= SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK;
+
+	/*
+	 * DMA is not really broken, I just haven't implemented it yet.
+	 */
+	sc->slot.quirks |= SDHCI_QUIRK_BROKEN_DMA;
+
+	/*
+	 * Set the buffer watermark level to 128 words (512 bytes) for both read
+	 * and write.  The hardware has a restriction that when the read or
+	 * write ready status is asserted, that means you can read exactly the
+	 * number of words set in the watermark register before you have to
+	 * re-check the status and potentially wait for more data.  The main
+	 * sdhci driver provides no hook for doing status checking on less than
+	 * a full block boundary, so we set the watermark level to be a full
+	 * block.  Reads and writes where the block size is less than the
+	 * watermark size will work correctly too, no need to change the
+	 * watermark for different size blocks.  However, 128 is the maximum
+	 * allowed for the watermark, so PIO is limitted to 512 byte blocks
+	 * (which works fine for SD cards, may be a problem for SDIO some day).
+	 *
+	 * XXX need named constants for this stuff.
+	 */
+	WR4(sc, SDHC_WTMK_LVL, 0x08800880);
+
+	sc->baseclk_hz = imx_ccm_sdhci_hz();
+
+	/*
+	 * If the slot is flagged with the non-removable property, set our flag
+	 * to always force the SDHCI_CARD_PRESENT bit on.
+	 *
+	 * XXX Workaround for gpio-based card detect...
+	 *
+	 * We don't have gpio support yet.  If there's a cd-gpios property just
+	 * force the SDHCI_CARD_PRESENT bit on for now.  If there isn't really a
+	 * card there it will fail to probe at the mmc layer and nothing bad
+	 * happens except instantiating an mmcN device for an empty slot.
+	 */
+	node = ofw_bus_get_node(dev);
+	if (OF_hasprop(node, "non-removable"))
+		sc->force_card_present = true;
+	else if (OF_hasprop(node, "cd-gpios")) {
+		/* XXX put real gpio hookup here. */
+		sc->force_card_present = true;
+	}
+
+	callout_init(&sc->r1bfix_callout, true);
+	sdhci_init_slot(dev, &sc->slot, 0);
+
+	bus_generic_probe(dev);
+	bus_generic_attach(dev);
+
+	sdhci_start_slot(&sc->slot);
+
+	return (0);
+
+fail:
+	if (sc->intr_cookie)
+		bus_teardown_intr(dev, sc->irq_res, sc->intr_cookie);
+	if (sc->irq_res)
+		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq_res);
+	if (sc->mem_res)
+		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->mem_res);
+
+	return (err);
+}
+
+static int
+imx_sdhci_probe(device_t dev)
+{
+
+        if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	switch (ofw_bus_search_compatible(dev, compat_data)->ocd_data) {
+	case HWTYPE_ESDHC:
+		device_set_desc(dev, "Freescale eSDHC controller");
+		return (BUS_PROBE_DEFAULT);
+	case HWTYPE_USDHC:
+		device_set_desc(dev, "Freescale uSDHC controller");
+		return (BUS_PROBE_DEFAULT);
+	default:
+		break;
+	}
+	return (ENXIO);
+}
+
+static device_method_t imx_sdhci_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		imx_sdhci_probe),
+	DEVMETHOD(device_attach,	imx_sdhci_attach),
+	DEVMETHOD(device_detach,	imx_sdhci_detach),
+
+	/* Bus interface */
+	DEVMETHOD(bus_read_ivar,	sdhci_generic_read_ivar),
+	DEVMETHOD(bus_write_ivar,	sdhci_generic_write_ivar),
+
+	/* MMC bridge interface */
+	DEVMETHOD(mmcbr_update_ios,	sdhci_generic_update_ios),
+	DEVMETHOD(mmcbr_request,	sdhci_generic_request),
+	DEVMETHOD(mmcbr_get_ro,		imx_sdhci_get_ro),
+	DEVMETHOD(mmcbr_acquire_host,	sdhci_generic_acquire_host),
+	DEVMETHOD(mmcbr_release_host,	sdhci_generic_release_host),
+
+	/* SDHCI registers accessors */
+	DEVMETHOD(sdhci_read_1,		imx_sdhci_read_1),
+	DEVMETHOD(sdhci_read_2,		imx_sdhci_read_2),
+	DEVMETHOD(sdhci_read_4,		imx_sdhci_read_4),
+	DEVMETHOD(sdhci_read_multi_4,	imx_sdhci_read_multi_4),
+	DEVMETHOD(sdhci_write_1,	imx_sdhci_write_1),
+	DEVMETHOD(sdhci_write_2,	imx_sdhci_write_2),
+	DEVMETHOD(sdhci_write_4,	imx_sdhci_write_4),
+	DEVMETHOD(sdhci_write_multi_4,	imx_sdhci_write_multi_4),
+
+	DEVMETHOD_END
+};
+
+static devclass_t imx_sdhci_devclass;
+
+static driver_t imx_sdhci_driver = {
+	"sdhci_imx",
+	imx_sdhci_methods,
+	sizeof(struct imx_sdhci_softc),
+};
+
+DRIVER_MODULE(sdhci_imx, simplebus, imx_sdhci_driver, imx_sdhci_devclass,
+    NULL, NULL);
+MODULE_DEPEND(sdhci_imx, sdhci, 1, 1, 1);
+MMC_DECLARE_BRIDGE(sdhci_imx);


Property changes on: trunk/sys/arm/freescale/imx/imx_sdhci.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/imx/imx_wdog.c
===================================================================
--- trunk/sys/arm/freescale/imx/imx_wdog.c	                        (rev 0)
+++ trunk/sys/arm/freescale/imx/imx_wdog.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,177 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012, 2013 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Oleksandr Rybalko under sponsorship
+ * from the FreeBSD Foundation.
+ *
+ * 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: stable/10/sys/arm/freescale/imx/imx_wdog.c 287079 2015-08-23 20:16:13Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/time.h>
+#include <sys/bus.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+#include <sys/watchdog.h>
+
+#include <machine/bus.h>
+#include <machine/intr.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+#include <machine/fdt.h>
+
+#include <arm/freescale/imx/imx_wdogreg.h>
+
+struct imx_wdog_softc {
+	struct mtx		sc_mtx;
+	device_t		sc_dev;
+	bus_space_tag_t		sc_bst;
+	bus_space_handle_t	sc_bsh;
+	struct resource		*sc_res[2];
+	uint32_t		sc_timeout;
+};
+
+static struct resource_spec imx_wdog_spec[] = {
+	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		0,	RF_ACTIVE },
+	{ -1, 0 }
+};
+
+static struct ofw_compat_data compat_data[] = {
+	{"fsl,imx6sx-wdt", 1},
+	{"fsl,imx6sl-wdt", 1},
+	{"fsl,imx6q-wdt",  1},
+	{"fsl,imx53-wdt",  1},
+	{"fsl,imx51-wdt",  1},
+	{"fsl,imx50-wdt",  1},
+	{"fsl,imx35-wdt",  1},
+	{"fsl,imx27-wdt",  1},
+	{"fsl,imx25-wdt",  1},
+	{"fsl,imx21-wdt",  1},
+	{NULL,             0}
+};
+
+static void	imx_watchdog(void *, u_int, int *);
+static int	imx_wdog_probe(device_t);
+static int	imx_wdog_attach(device_t);
+
+static device_method_t imx_wdog_methods[] = {
+	DEVMETHOD(device_probe,		imx_wdog_probe),
+	DEVMETHOD(device_attach,	imx_wdog_attach),
+	DEVMETHOD_END
+};
+
+static driver_t imx_wdog_driver = {
+	"imx_wdog",
+	imx_wdog_methods,
+	sizeof(struct imx_wdog_softc),
+};
+static devclass_t imx_wdog_devclass;
+DRIVER_MODULE(imx_wdog, simplebus, imx_wdog_driver, imx_wdog_devclass, 0, 0);
+
+#define	RD2(_sc, _r)							\
+		bus_space_read_2((_sc)->sc_bst, (_sc)->sc_bsh, (_r))
+#define	WR2(_sc, _r, _v)						\
+		bus_space_write_2((_sc)->sc_bst, (_sc)->sc_bsh, (_r), (_v))
+
+static void
+imx_watchdog(void *arg, u_int cmd, int *error)
+{
+	struct imx_wdog_softc *sc;
+	uint16_t reg;
+	u_int timeout;
+
+	sc = arg;
+	mtx_lock(&sc->sc_mtx);
+	if (cmd == 0) {
+		if (bootverbose)
+			device_printf(sc->sc_dev, "Can not be disabled.\n");
+		*error = EOPNOTSUPP;
+	} else {
+		timeout = (u_int)((1ULL << (cmd & WD_INTERVAL)) / 1000000000U);
+		if (timeout > 1 && timeout < 128) {
+			if (timeout != sc->sc_timeout) {
+				sc->sc_timeout = timeout;
+				reg = RD2(sc, WDOG_CR_REG);
+				reg &= ~WDOG_CR_WT_MASK;
+				reg |= (timeout << (WDOG_CR_WT_SHIFT + 1)) &
+				    WDOG_CR_WT_MASK;
+				WR2(sc, WDOG_CR_REG, reg | WDOG_CR_WDE);
+			}
+			/* Refresh counter */
+			WR2(sc, WDOG_SR_REG, WDOG_SR_STEP1);
+			WR2(sc, WDOG_SR_REG, WDOG_SR_STEP2);
+			*error = 0;
+		}
+	}
+	mtx_unlock(&sc->sc_mtx);
+}
+
+static int
+imx_wdog_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
+		return (ENXIO);
+
+	device_set_desc(dev, "Freescale i.MX Watchdog");
+	return (0);
+}
+
+static int
+imx_wdog_attach(device_t dev)
+{
+	struct imx_wdog_softc *sc;
+
+	sc = device_get_softc(dev);
+	sc->sc_dev = dev;
+
+	if (bus_alloc_resources(dev, imx_wdog_spec, sc->sc_res)) {
+		device_printf(dev, "could not allocate resources\n");
+		return (ENXIO);
+	}
+
+	mtx_init(&sc->sc_mtx, device_get_nameunit(dev), "imx_wdt", MTX_DEF);
+
+	sc->sc_dev = dev;
+	sc->sc_bst = rman_get_bustag(sc->sc_res[0]);
+	sc->sc_bsh = rman_get_bushandle(sc->sc_res[0]);
+
+	/* TODO: handle interrupt */
+
+	EVENTHANDLER_REGISTER(watchdog_list, imx_watchdog, sc, 0);
+	return (0);
+}


Property changes on: trunk/sys/arm/freescale/imx/imx_wdog.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/imx/imx_wdogreg.h
===================================================================
--- trunk/sys/arm/freescale/imx/imx_wdogreg.h	                        (rev 0)
+++ trunk/sys/arm/freescale/imx/imx_wdogreg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,63 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012, 2013 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Oleksandr Rybalko under sponsorship
+ * from the FreeBSD Foundation.
+ *
+ * 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: stable/10/sys/arm/freescale/imx/imx_wdogreg.h 294678 2016-01-24 19:34:05Z ian $
+ */
+
+#define	WDOG_CLK_FREQ	32768
+
+#define	WDOG_CR_REG	0x00	/* Control Register */
+#define		WDOG_CR_WT_MASK		0xff00	/* Count of 0.5 sec */
+#define		WDOG_CR_WT_SHIFT	8
+#define		WDOG_CR_WDW		(1 << 7) /* Suspend WDog */
+#define		WDOG_CR_WDA		(1 << 5) /* Don't touch ipp_wdog */
+#define		WDOG_CR_SRS		(1 << 4) /* Don't touch sys_reset */
+#define		WDOG_CR_WDT		(1 << 3) /* Assert ipp_wdog on tout */
+#define		WDOG_CR_WDE		(1 << 2) /* WDog Enable */
+#define		WDOG_CR_WDBG		(1 << 1) /* Suspend when DBG mode */
+#define		WDOG_CR_WDZST		(1 << 0) /* Suspend when LP mode */
+
+#define	WDOG_SR_REG	0x02	/* Service Register */
+#define		WDOG_SR_STEP1		0x5555
+#define		WDOG_SR_STEP2		0xaaaa
+
+#define	WDOG_RSR_REG	0x04	/* Reset Status Register */
+#define		WDOG_RSR_POR		(1 << 4) /* Due to Power-On Reset */
+#define		WDOG_RSR_TOUT		(1 << 1) /* Due WDog timeout reset */
+#define		WDOG_RSR_SFTW		(1 << 0) /* Due Soft reset */
+
+#define	WDOG_ICR_REG	0x06	/* Interrupt Control Register */
+#define		WDOG_ICR_WIE		(1 << 15) /* Enable Interrupt */
+#define		WDOG_ICR_WTIS		(1 << 14) /* Interrupt has occurred */
+#define		WDOG_ICR_WTCT_MASK	0x00ff
+#define		WDOG_ICR_WTCT_SHIFT	0	/* Interrupt hold time */
+
+#define	WDOG_MCR_REG	0x08	/* Miscellaneous Control Register */
+#define		WDOG_MCR_PDE		(1 << 0)
+


Property changes on: trunk/sys/arm/freescale/imx/imx_wdogreg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/imx/std.imx51
===================================================================
--- trunk/sys/arm/freescale/imx/std.imx51	                        (rev 0)
+++ trunk/sys/arm/freescale/imx/std.imx51	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,17 @@
+# $FreeBSD: stable/10/sys/arm/freescale/imx/std.imx51 278601 2015-02-11 22:47:48Z ian $
+machine		arm	armv6
+cpu 		CPU_CORTEXA
+makeoptions	CONF_CFLAGS="-march=armv7a -Wa,-march=armv7a"
+makeoptions	ARM_LITTLE_ENDIAN
+options		ARM_L2_PIPT
+
+options		KERNVIRTADDR=0xc0100000
+makeoptions	KERNVIRTADDR=0xc0100000
+options		KERNPHYSADDR=0x90100000
+makeoptions	KERNPHYSADDR=0x90100000
+options		PHYSADDR=0x90000000
+
+device  	fdt_pinctrl
+
+files "../freescale/imx/files.imx51"
+


Property changes on: trunk/sys/arm/freescale/imx/std.imx51
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/freescale/imx/std.imx53
===================================================================
--- trunk/sys/arm/freescale/imx/std.imx53	                        (rev 0)
+++ trunk/sys/arm/freescale/imx/std.imx53	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,17 @@
+# $FreeBSD: stable/10/sys/arm/freescale/imx/std.imx53 278601 2015-02-11 22:47:48Z ian $
+machine		arm	armv6
+cpu 		CPU_CORTEXA
+makeoptions	CONF_CFLAGS="-march=armv7a -Wa,-march=armv7a"
+makeoptions	ARM_LITTLE_ENDIAN
+options		ARM_L2_PIPT
+
+options		KERNVIRTADDR=0xc0100000
+makeoptions	KERNVIRTADDR=0xc0100000
+options		KERNPHYSADDR=0x70100000
+makeoptions	KERNPHYSADDR=0x70100000
+options		PHYSADDR=0x70000000
+
+device  	fdt_pinctrl
+
+files "../freescale/imx/files.imx53"
+


Property changes on: trunk/sys/arm/freescale/imx/std.imx53
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/freescale/imx/std.imx6
===================================================================
--- trunk/sys/arm/freescale/imx/std.imx6	                        (rev 0)
+++ trunk/sys/arm/freescale/imx/std.imx6	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,20 @@
+# $FreeBSD: stable/10/sys/arm/freescale/imx/std.imx6 278601 2015-02-11 22:47:48Z ian $
+machine		arm	armv6
+cpu 		CPU_CORTEXA
+makeoptions	CONF_CFLAGS="-march=armv7a -Wa,-march=armv7a"
+makeoptions	ARM_LITTLE_ENDIAN
+options		ARM_L2_PIPT
+
+options		KERNVIRTADDR		= 0xc2000000
+makeoptions	KERNVIRTADDR		= 0xc2000000
+options		KERNPHYSADDR		= 0x12000000
+makeoptions	KERNPHYSADDR		= 0x12000000
+options		PHYSADDR		= 0x10000000
+
+options		IPI_IRQ_START=0
+options		IPI_IRQ_END=15
+
+device  	fdt_pinctrl
+
+files "../freescale/imx/files.imx6"
+


Property changes on: trunk/sys/arm/freescale/imx/std.imx6
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/freescale/imx/tzic.c
===================================================================
--- trunk/sys/arm/freescale/imx/tzic.c	                        (rev 0)
+++ trunk/sys/arm/freescale/imx/tzic.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,192 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012, 2013 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Oleksandr Rybalko under sponsorship
+ * from the FreeBSD Foundation.
+ *
+ * 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: stable/10/sys/arm/freescale/imx/tzic.c 266160 2014-05-15 17:30:16Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/ktr.h>
+#include <sys/module.h>
+#include <sys/rman.h>
+#include <sys/pcpu.h>
+#include <sys/proc.h>
+#include <sys/cpuset.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <machine/bus.h>
+#include <machine/intr.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <arm/freescale/imx/imx51_tzicreg.h>
+
+struct tzic_softc {
+	struct resource *	tzic_res[3];
+	bus_space_tag_t		tzic_bst;
+	bus_space_handle_t	tzic_bsh;
+	uint8_t			ver;
+};
+
+static struct resource_spec tzic_spec[] = {
+	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
+	{ -1, 0 }
+};
+
+static struct tzic_softc *tzic_sc = NULL;
+
+#define	tzic_read_4(reg)		\
+    bus_space_read_4(tzic_sc->tzic_bst, tzic_sc->tzic_bsh, reg)
+#define	tzic_write_4(reg, val)		\
+    bus_space_write_4(tzic_sc->tzic_bst, tzic_sc->tzic_bsh, reg, val)
+
+static void tzic_post_filter(void *);
+
+static int
+tzic_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (ofw_bus_is_compatible(dev, "fsl,tzic")) {
+		device_set_desc(dev, "TrustZone Interrupt Controller");
+		return (BUS_PROBE_DEFAULT);
+	}
+	return (ENXIO);
+}
+
+static int
+tzic_attach(device_t dev)
+{
+	struct		tzic_softc *sc = device_get_softc(dev);
+	int		i;
+	uint32_t	reg;
+
+	if (tzic_sc)
+		return (ENXIO);
+
+	if (bus_alloc_resources(dev, tzic_spec, sc->tzic_res)) {
+		device_printf(dev, "could not allocate resources\n");
+		return (ENXIO);
+	}
+
+	arm_post_filter = tzic_post_filter;
+
+	/* Distributor Interface */
+	sc->tzic_bst = rman_get_bustag(sc->tzic_res[0]);
+	sc->tzic_bsh = rman_get_bushandle(sc->tzic_res[0]);
+
+	tzic_sc = sc;
+
+	reg = tzic_read_4(TZIC_INTCNTL);
+	tzic_write_4(TZIC_INTCNTL, INTCNTL_NSEN_MASK|INTCNTL_NSEN|INTCNTL_EN);
+	reg = tzic_read_4(TZIC_INTCNTL);
+	tzic_write_4(TZIC_PRIOMASK, 0x1f);
+	reg = tzic_read_4(TZIC_PRIOMASK);
+
+	tzic_write_4(TZIC_SYNCCTRL, 0x02);
+	reg = tzic_read_4(TZIC_SYNCCTRL);
+
+	/* route all interrupts to IRQ.  secure interrupts are for FIQ */
+	for (i = 0; i < 4; i++)
+		tzic_write_4(TZIC_INTSEC(i), 0xffffffff);
+
+	/* disable all interrupts */
+	for (i = 0; i < 4; i++)
+		tzic_write_4(TZIC_ENCLEAR(i), 0xffffffff);
+
+	return (0);
+}
+
+static device_method_t tzic_methods[] = {
+	DEVMETHOD(device_probe,		tzic_probe),
+	DEVMETHOD(device_attach,	tzic_attach),
+	{ 0, 0 }
+};
+
+static driver_t tzic_driver = {
+	"tzic",
+	tzic_methods,
+	sizeof(struct tzic_softc),
+};
+
+static devclass_t tzic_devclass;
+
+/*
+ * Memory space of controller located outside of device range, so let him to
+ * attach not only to simplebus, but ofwbus also.
+ */
+EARLY_DRIVER_MODULE(tzic, ofwbus, tzic_driver, tzic_devclass, 0, 0,
+    BUS_PASS_INTERRUPT);
+EARLY_DRIVER_MODULE(tzic, simplebus, tzic_driver, tzic_devclass, 0, 0,
+    BUS_PASS_INTERRUPT);
+
+static void
+tzic_post_filter(void *arg)
+{
+
+}
+
+int
+arm_get_next_irq(int last_irq)
+{
+	uint32_t pending;
+	int i, b;
+
+	for (i = 0; i < 4; i++) {
+		pending = tzic_read_4(TZIC_PND(i));
+		for (b = 0; pending != 0 && b < 32; b++)
+			if (pending & (1 << b)) {
+				return (i * 32 + b);
+			}
+	}
+
+	return (-1);
+}
+
+void
+arm_mask_irq(uintptr_t nb)
+{
+
+	tzic_write_4(TZIC_ENCLEAR(nb / 32), (1UL <<(nb % 32)));
+}
+
+void
+arm_unmask_irq(uintptr_t nb)
+{
+
+	tzic_write_4(TZIC_ENSET(nb / 32), (1UL <<(nb % 32)));
+}


Property changes on: trunk/sys/arm/freescale/imx/tzic.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/vybrid/files.vybrid
===================================================================
--- trunk/sys/arm/freescale/vybrid/files.vybrid	                        (rev 0)
+++ trunk/sys/arm/freescale/vybrid/files.vybrid	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,34 @@
+# $FreeBSD: stable/10/sys/arm/freescale/vybrid/files.vybrid 278727 2015-02-13 22:32:02Z ian $
+
+kern/kern_clocksource.c				standard
+
+arm/arm/bus_space_generic.c			standard
+arm/arm/bus_space_asm_generic.S			standard
+arm/arm/cpufunc_asm_armv5.S			standard
+arm/arm/cpufunc_asm_arm10.S			standard
+arm/arm/cpufunc_asm_arm11.S			standard
+arm/arm/cpufunc_asm_armv7.S			standard
+
+arm/arm/bus_space_base.c			standard
+arm/arm/gic.c					standard
+arm/arm/mpcore_timer.c				standard
+
+arm/freescale/vybrid/vf_machdep.c		standard
+arm/freescale/vybrid/vf_common.c		standard
+arm/freescale/vybrid/vf_ccm.c			standard
+arm/freescale/vybrid/vf_anadig.c		standard
+arm/freescale/vybrid/vf_iomuxc.c		standard
+arm/freescale/vybrid/vf_mscm.c			standard
+arm/freescale/vybrid/vf_src.c			standard
+arm/freescale/vybrid/vf_edma.c			standard
+arm/freescale/vybrid/vf_dmamux.c		standard
+arm/freescale/vybrid/vf_port.c			standard
+arm/freescale/vybrid/vf_i2c.c			optional	iicbus
+arm/freescale/vybrid/vf_tcon.c			optional	vt
+arm/freescale/vybrid/vf_dcu4.c			optional	vt
+arm/freescale/vybrid/vf_nfc.c			optional	nand
+arm/freescale/vybrid/vf_ehci.c			optional	ehci
+arm/freescale/vybrid/vf_gpio.c			optional	gpio
+arm/freescale/vybrid/vf_uart.c			optional	uart
+arm/freescale/vybrid/vf_sai.c			optional	sound
+dev/ffec/if_ffec.c				optional	ffec


Property changes on: trunk/sys/arm/freescale/vybrid/files.vybrid
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/freescale/vybrid/std.vybrid
===================================================================
--- trunk/sys/arm/freescale/vybrid/std.vybrid	                        (rev 0)
+++ trunk/sys/arm/freescale/vybrid/std.vybrid	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,19 @@
+# $FreeBSD: stable/10/sys/arm/freescale/vybrid/std.vybrid 278601 2015-02-11 22:47:48Z ian $
+
+makeoption	ARM_LITTLE_ENDIAN
+
+cpu		CPU_CORTEXA
+machine		arm armv6
+makeoptions	CONF_CFLAGS="-march=armv7a -Wa,-march=armv7a"
+
+options		PHYSADDR=0x80000000
+
+makeoptions	KERNPHYSADDR=0x80100000
+options		KERNPHYSADDR=0x80100000
+
+makeoptions	KERNVIRTADDR=0xc0100000
+options		KERNVIRTADDR=0xc0100000
+
+options		ARM_L2_PIPT
+
+files		"../freescale/vybrid/files.vybrid"


Property changes on: trunk/sys/arm/freescale/vybrid/std.vybrid
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/freescale/vybrid/vf_anadig.c
===================================================================
--- trunk/sys/arm/freescale/vybrid/vf_anadig.c	                        (rev 0)
+++ trunk/sys/arm/freescale/vybrid/vf_anadig.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,247 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013-2014 Ruslan Bukin <br at bsdpad.com>
+ * 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.
+ */
+
+/*
+ * Vybrid Family Analog components control digital interface (ANADIG)
+ * Chapter 11, Vybrid Reference Manual, Rev. 5, 07/2013
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/freescale/vybrid/vf_anadig.c 266198 2014-05-15 22:03:24Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/timeet.h>
+#include <sys/timetc.h>
+#include <sys/watchdog.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#include <arm/freescale/vybrid/vf_common.h>
+
+#define	ANADIG_PLL3_CTRL	0x010	/* PLL3 Control */
+#define	ANADIG_PLL7_CTRL	0x020	/* PLL7 Control */
+#define	ANADIG_PLL2_CTRL	0x030	/* PLL2 Control */
+#define	ANADIG_PLL2_SS		0x040	/* PLL2 Spread Spectrum */
+#define	ANADIG_PLL2_NUM		0x050	/* PLL2 Numerator */
+#define	ANADIG_PLL2_DENOM	0x060	/* PLL2 Denominator */
+#define	ANADIG_PLL4_CTRL	0x070	/* PLL4 Control */
+#define	ANADIG_PLL4_NUM		0x080	/* PLL4 Numerator */
+#define	ANADIG_PLL4_DENOM	0x090	/* PLL4 Denominator */
+#define	ANADIG_PLL6_CTRL	0x0A0	/* PLL6 Control */
+#define	ANADIG_PLL6_NUM		0x0B0	/* PLL6 Numerator */
+#define	ANADIG_PLL6_DENOM	0x0C0	/* PLL6 Denominator */
+#define	ANADIG_PLL5_CTRL	0x0E0	/* PLL5 Control */
+#define	ANADIG_PLL3_PFD		0x0F0	/* PLL3 PFD */
+#define	ANADIG_PLL2_PFD		0x100	/* PLL2 PFD */
+#define	ANADIG_REG_1P1		0x110	/* Regulator 1P1 */
+#define	ANADIG_REG_3P0		0x120	/* Regulator 3P0 */
+#define	ANADIG_REG_2P5		0x130	/* Regulator 2P5 */
+#define	ANADIG_ANA_MISC0	0x150	/* Analog Miscellaneous */
+#define	ANADIG_ANA_MISC1	0x160	/* Analog Miscellaneous */
+#define	ANADIG_ANADIG_DIGPROG	0x260	/* Digital Program */
+#define	ANADIG_PLL1_CTRL	0x270	/* PLL1 Control */
+#define	ANADIG_PLL1_SS		0x280	/* PLL1 Spread Spectrum */
+#define	ANADIG_PLL1_NUM		0x290	/* PLL1 Numerator */
+#define	ANADIG_PLL1_DENOM	0x2A0	/* PLL1 Denominator */
+#define	ANADIG_PLL1_PFD		0x2B0	/* PLL1_PFD */
+#define	ANADIG_PLL_LOCK		0x2C0	/* PLL Lock */
+
+#define	USB_VBUS_DETECT(n)		(0x1A0 + 0x60 * n)
+#define	USB_CHRG_DETECT(n)		(0x1B0 + 0x60 * n)
+#define	USB_VBUS_DETECT_STATUS(n)	(0x1C0 + 0x60 * n)
+#define	USB_CHRG_DETECT_STATUS(n)	(0x1D0 + 0x60 * n)
+#define	USB_LOOPBACK(n)			(0x1E0 + 0x60 * n)
+#define	USB_MISC(n)			(0x1F0 + 0x60 * n)
+
+#define	ANADIG_PLL_LOCKED	(1 << 31)
+#define	ENABLE_LINREG		(1 << 0)
+#define	EN_CLK_TO_UTMI		(1 << 30)
+
+#define	CTRL_BYPASS		(1 << 16)
+#define	CTRL_PWR		(1 << 12)
+#define	CTRL_PLL_EN		(1 << 13)
+#define	EN_USB_CLKS		(1 << 6)
+
+#define	PLL4_CTRL_DIV_SEL_S	0
+#define	PLL4_CTRL_DIV_SEL_M	0x7f
+
+struct anadig_softc {
+	struct resource		*res[1];
+	bus_space_tag_t		bst;
+	bus_space_handle_t	bsh;
+};
+
+struct anadig_softc *anadig_sc;
+
+static struct resource_spec anadig_spec[] = {
+	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
+	{ -1, 0 }
+};
+
+static int
+anadig_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "fsl,mvf600-anadig"))
+		return (ENXIO);
+
+	device_set_desc(dev, "Vybrid Family ANADIG Unit");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+enable_pll(struct anadig_softc *sc, int pll_ctrl)
+{
+	int reg;
+
+	reg = READ4(sc, pll_ctrl);
+	reg &= ~(CTRL_BYPASS | CTRL_PWR);
+	if (pll_ctrl == ANADIG_PLL3_CTRL || pll_ctrl == ANADIG_PLL7_CTRL) {
+		/* It is USB PLL. Power bit logic is reversed */
+		reg |= (CTRL_PWR | EN_USB_CLKS);
+	}
+	WRITE4(sc, pll_ctrl, reg);
+
+	/* Wait for PLL lock */
+	while (!(READ4(sc, pll_ctrl) & ANADIG_PLL_LOCKED))
+		;
+
+	reg = READ4(sc, pll_ctrl);
+	reg |= (CTRL_PLL_EN);
+	WRITE4(sc, pll_ctrl, reg);
+
+	return (0);
+}
+
+uint32_t
+pll4_configure_output(uint32_t mfi, uint32_t mfn, uint32_t mfd)
+{
+	struct anadig_softc *sc;
+	int reg;
+
+	sc = anadig_sc;
+
+	/*
+	 * PLLout = Fsys * (MFI+(MFN/MFD))
+	 */
+
+	reg = READ4(sc, ANADIG_PLL4_CTRL);
+	reg &= ~(PLL4_CTRL_DIV_SEL_M << PLL4_CTRL_DIV_SEL_S);
+	reg |= (mfi << PLL4_CTRL_DIV_SEL_S);
+	WRITE4(sc, ANADIG_PLL4_CTRL, reg);
+	WRITE4(sc, ANADIG_PLL4_NUM, mfn);
+	WRITE4(sc, ANADIG_PLL4_DENOM, mfd);
+
+	return (0);
+}
+
+static int
+anadig_attach(device_t dev)
+{
+	struct anadig_softc *sc;
+	int reg;
+
+	sc = device_get_softc(dev);
+
+	if (bus_alloc_resources(dev, anadig_spec, sc->res)) {
+		device_printf(dev, "could not allocate resources\n");
+		return (ENXIO);
+	}
+
+	/* Memory interface */
+	sc->bst = rman_get_bustag(sc->res[0]);
+	sc->bsh = rman_get_bushandle(sc->res[0]);
+
+	anadig_sc = sc;
+
+	/* Enable USB PLLs */
+	enable_pll(sc, ANADIG_PLL3_CTRL);
+	enable_pll(sc, ANADIG_PLL7_CTRL);
+
+	/* Enable other PLLs */
+	enable_pll(sc, ANADIG_PLL1_CTRL);
+	enable_pll(sc, ANADIG_PLL2_CTRL);
+	enable_pll(sc, ANADIG_PLL4_CTRL);
+	enable_pll(sc, ANADIG_PLL5_CTRL);
+	enable_pll(sc, ANADIG_PLL6_CTRL);
+
+	/* Enable USB voltage regulator */
+	reg = READ4(sc, ANADIG_REG_3P0);
+	reg |= (ENABLE_LINREG);
+	WRITE4(sc, ANADIG_REG_3P0, reg);
+
+	/* Give clocks to USB */
+	reg = READ4(sc, USB_MISC(0));
+	reg |= (EN_CLK_TO_UTMI);
+	WRITE4(sc, USB_MISC(0), reg);
+
+	reg = READ4(sc, USB_MISC(1));
+	reg |= (EN_CLK_TO_UTMI);
+	WRITE4(sc, USB_MISC(1), reg);
+
+#if 0
+	printf("USB_ANALOG_USB_MISC(0) == 0x%08x\n",
+	    READ4(sc, USB_ANALOG_USB_MISC(0)));
+	printf("USB_ANALOG_USB_MISC(1) == 0x%08x\n",
+	    READ4(sc, USB_ANALOG_USB_MISC(1)));
+#endif
+
+	return (0);
+}
+
+static device_method_t anadig_methods[] = {
+	DEVMETHOD(device_probe,		anadig_probe),
+	DEVMETHOD(device_attach,	anadig_attach),
+	{ 0, 0 }
+};
+
+static driver_t anadig_driver = {
+	"anadig",
+	anadig_methods,
+	sizeof(struct anadig_softc),
+};
+
+static devclass_t anadig_devclass;
+
+DRIVER_MODULE(anadig, simplebus, anadig_driver, anadig_devclass, 0, 0);


Property changes on: trunk/sys/arm/freescale/vybrid/vf_anadig.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/vybrid/vf_ccm.c
===================================================================
--- trunk/sys/arm/freescale/vybrid/vf_ccm.c	                        (rev 0)
+++ trunk/sys/arm/freescale/vybrid/vf_ccm.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,502 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013-2014 Ruslan Bukin <br at bsdpad.com>
+ * 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.
+ */
+
+/*
+ * Vybrid Family Clock Controller Module (CCM)
+ * Chapter 10, Vybrid Reference Manual, Rev. 5, 07/2013
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/freescale/vybrid/vf_ccm.c 266203 2014-05-16 00:14:50Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/timeet.h>
+#include <sys/timetc.h>
+#include <sys/watchdog.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#include <arm/freescale/vybrid/vf_common.h>
+
+#define	CCM_CCR		0x00	/* Control Register */
+#define	CCM_CSR		0x04	/* Status Register */
+#define	CCM_CCSR	0x08	/* Clock Switcher Register */
+#define	CCM_CACRR	0x0C	/* ARM Clock Root Register */
+#define	CCM_CSCMR1	0x10	/* Serial Clock Multiplexer Register 1 */
+#define	CCM_CSCDR1	0x14	/* Serial Clock Divider Register 1 */
+#define	CCM_CSCDR2	0x18	/* Serial Clock Divider Register 2 */
+#define	CCM_CSCDR3	0x1C	/* Serial Clock Divider Register 3 */
+#define	CCM_CSCMR2	0x20	/* Serial Clock Multiplexer Register 2 */
+#define	CCM_CTOR	0x28	/* Testing Observability Register */
+#define	CCM_CLPCR	0x2C	/* Low Power Control Register */
+#define	CCM_CISR	0x30	/* Interrupt Status Register */
+#define	CCM_CIMR	0x34	/* Interrupt Mask Register */
+#define	CCM_CCOSR	0x38	/* Clock Output Source Register */
+#define	CCM_CGPR	0x3C	/* General Purpose Register */
+
+#define	CCM_CCGRN	12
+#define	CCM_CCGR(n)	(0x40 + (n * 0x04))	/* Clock Gating Register */
+#define	CCM_CMEOR(n)	(0x70 + (n * 0x70))	/* Module Enable Override */
+#define	CCM_CCPGR(n)	(0x90 + (n * 0x04))	/* Platform Clock Gating */
+
+#define	CCM_CPPDSR	0x88	/* PLL PFD Disable Status Register */
+#define	CCM_CCOWR	0x8C	/* CORE Wakeup Register */
+
+#define	PLL3_PFD4_EN	(1 << 31)
+#define	PLL3_PFD3_EN	(1 << 30)
+#define	PLL3_PFD2_EN	(1 << 29)
+#define	PLL3_PFD1_EN	(1 << 28)
+#define	PLL2_PFD4_EN	(1 << 15)
+#define	PLL2_PFD3_EN	(1 << 14)
+#define	PLL2_PFD2_EN	(1 << 13)
+#define	PLL2_PFD1_EN	(1 << 12)
+#define	PLL1_PFD4_EN	(1 << 11)
+#define	PLL1_PFD3_EN	(1 << 10)
+#define	PLL1_PFD2_EN	(1 << 9)
+#define	PLL1_PFD1_EN	(1 << 8)
+
+/* CCM_CCR */
+#define	FIRC_EN		(1 << 16)
+#define	FXOSC_EN	(1 << 12)
+#define	FXOSC_RDY	(1 << 5)
+
+/* CCM_CSCDR1 */
+#define	ENET_TS_EN	(1 << 23)
+#define	RMII_CLK_EN	(1 << 24)
+#define	SAI3_EN		(1 << 19)
+
+/* CCM_CSCDR2 */
+#define	ESAI_EN		(1 << 30)
+#define	ESDHC1_EN	(1 << 29)
+#define	ESDHC0_EN	(1 << 28)
+#define	NFC_EN		(1 << 9)
+#define	ESDHC1_DIV_S	20
+#define	ESDHC1_DIV_M	0xf
+#define	ESDHC0_DIV_S	16
+#define	ESDHC0_DIV_M	0xf
+
+/* CCM_CSCDR3 */
+#define	DCU0_EN			(1 << 19)
+
+#define	QSPI1_EN		(1 << 12)
+#define	QSPI1_DIV		(1 << 11)
+#define	QSPI1_X2_DIV		(1 << 10)
+#define	QSPI1_X4_DIV_M		0x3
+#define	QSPI1_X4_DIV_S		8
+
+#define	QSPI0_EN		(1 << 4)
+#define	QSPI0_DIV		(1 << 3)
+#define	QSPI0_X2_DIV		(1 << 2)
+#define	QSPI0_X4_DIV_M		0x3
+#define	QSPI0_X4_DIV_S		0
+
+#define	SAI3_DIV_SHIFT		12
+#define	SAI3_DIV_MASK		0xf
+#define	ESAI_DIV_SHIFT		24
+#define	ESAI_DIV_MASK		0xf
+
+#define	PLL4_CLK_DIV_SHIFT	6
+#define	PLL4_CLK_DIV_MASK	0x7
+
+#define	IPG_CLK_DIV_SHIFT	11
+#define	IPG_CLK_DIV_MASK	0x3
+
+#define	ESAI_CLK_SEL_SHIFT	20
+#define	ESAI_CLK_SEL_MASK	0x3
+
+#define	SAI3_CLK_SEL_SHIFT	6
+#define	SAI3_CLK_SEL_MASK	0x3
+
+#define	CKO1_EN			(1 << 10)
+#define	CKO1_DIV_MASK		0xf
+#define	CKO1_DIV_SHIFT		6
+#define	CKO1_SEL_MASK		0x3f
+#define	CKO1_SEL_SHIFT		0
+#define	CKO1_PLL4_MAIN		0x6
+#define	CKO1_PLL4_DIVD		0x7
+
+struct clk {
+	uint32_t	reg;
+	uint32_t	enable_reg;
+	uint32_t	div_mask;
+	uint32_t	div_shift;
+	uint32_t	div_val;
+	uint32_t	sel_reg;
+	uint32_t	sel_mask;
+	uint32_t	sel_shift;
+	uint32_t	sel_val;
+};
+
+static struct clk ipg_clk = {
+	.reg = CCM_CACRR,
+	.enable_reg = 0,
+	.div_mask = IPG_CLK_DIV_MASK,
+	.div_shift = IPG_CLK_DIV_SHIFT,
+	.div_val = 1, /* Divide by 2 */
+	.sel_reg = 0,
+	.sel_mask = 0,
+	.sel_shift = 0,
+	.sel_val = 0,
+};
+
+/*
+  PLL4 clock divider (before switching the clocks should be gated)
+  000 Divide by 1 (only if PLL frequency less than or equal to 650 MHz)
+  001 Divide by 4
+  010 Divide by 6
+  011 Divide by 8
+  100 Divide by 10
+  101 Divide by 12
+  110 Divide by 14
+  111 Divide by 16
+*/
+
+static struct clk pll4_clk = {
+	.reg = CCM_CACRR,
+	.enable_reg = 0,
+	.div_mask = PLL4_CLK_DIV_MASK,
+	.div_shift = PLL4_CLK_DIV_SHIFT,
+	.div_val = 5, /* Divide by 12 */
+	.sel_reg = 0,
+	.sel_mask = 0,
+	.sel_shift = 0,
+	.sel_val = 0,
+};
+
+static struct clk sai3_clk = {
+	.reg = CCM_CSCDR1,
+	.enable_reg = SAI3_EN,
+	.div_mask = SAI3_DIV_MASK,
+	.div_shift = SAI3_DIV_SHIFT,
+	.div_val = 1,
+	.sel_reg = CCM_CSCMR1,
+	.sel_mask = SAI3_CLK_SEL_MASK,
+	.sel_shift = SAI3_CLK_SEL_SHIFT,
+	.sel_val = 0x3, /* Divided PLL4 main clock */
+};
+
+static struct clk cko1_clk = {
+	.reg = CCM_CCOSR,
+	.enable_reg = CKO1_EN,
+	.div_mask = CKO1_DIV_MASK,
+	.div_shift = CKO1_DIV_SHIFT,
+	.div_val = 1,
+	.sel_reg = CCM_CCOSR,
+	.sel_mask = CKO1_SEL_MASK,
+	.sel_shift = CKO1_SEL_SHIFT,
+	.sel_val = CKO1_PLL4_DIVD,
+};
+
+static struct clk esdhc0_clk = {
+	.reg = CCM_CSCDR2,
+	.enable_reg = ESDHC0_EN,
+	.div_mask = ESDHC0_DIV_M,
+	.div_shift = ESDHC0_DIV_S,
+	.div_val = 0x9,
+	.sel_reg = 0,
+	.sel_mask = 0,
+	.sel_shift = 0,
+	.sel_val = 0,
+};
+
+static struct clk esdhc1_clk = {
+	.reg = CCM_CSCDR2,
+	.enable_reg = ESDHC1_EN,
+	.div_mask = ESDHC1_DIV_M,
+	.div_shift = ESDHC1_DIV_S,
+	.div_val = 0x9,
+	.sel_reg = 0,
+	.sel_mask = 0,
+	.sel_shift = 0,
+	.sel_val = 0,
+};
+
+static struct clk qspi0_clk = {
+	.reg = CCM_CSCDR3,
+	.enable_reg = QSPI0_EN,
+	.div_mask = 0,
+	.div_shift = 0,
+	.div_val = 0,
+	.sel_reg = 0,
+	.sel_mask = 0,
+	.sel_shift = 0,
+	.sel_val = 0,
+};
+
+static struct clk dcu0_clk = {
+	.reg = CCM_CSCDR3,
+	.enable_reg = DCU0_EN,
+	.div_mask = 0x7,
+	.div_shift = 16, /* DCU0_DIV */
+	.div_val = 0, /* divide by 1 */
+	.sel_reg = 0,
+	.sel_mask = 0,
+	.sel_shift = 0,
+	.sel_val = 0,
+};
+
+static struct clk enet_clk = {
+	.reg = CCM_CSCDR1,
+	.enable_reg = (ENET_TS_EN | RMII_CLK_EN),
+	.div_mask = 0,
+	.div_shift = 0,
+	.div_val = 0,
+	.sel_reg = 0,
+	.sel_mask = 0,
+	.sel_shift = 0,
+	.sel_val = 0,
+};
+
+static struct clk nand_clk = {
+	.reg = CCM_CSCDR2,
+	.enable_reg = NFC_EN,
+	.div_mask = 0,
+	.div_shift = 0,
+	.div_val = 0,
+	.sel_reg = 0,
+	.sel_mask = 0,
+	.sel_shift = 0,
+	.sel_val = 0,
+};
+
+/*
+  Divider to generate ESAI clock
+  0000    Divide by 1
+  0001    Divide by 2
+  ...     ...
+  1111    Divide by 16
+*/
+
+static struct clk esai_clk = {
+	.reg = CCM_CSCDR2,
+	.enable_reg = ESAI_EN,
+	.div_mask = ESAI_DIV_MASK,
+	.div_shift = ESAI_DIV_SHIFT,
+	.div_val = 3, /* Divide by 4 */
+	.sel_reg = CCM_CSCMR1,
+	.sel_mask = ESAI_CLK_SEL_MASK,
+	.sel_shift = ESAI_CLK_SEL_SHIFT,
+	.sel_val = 0x3, /* Divided PLL4 main clock */
+};
+
+struct clock_entry {
+	char		*name;
+	struct clk	*clk;
+};
+
+static struct clock_entry clock_map[] = {
+	{"ipg",		&ipg_clk},
+	{"pll4",	&pll4_clk},
+	{"sai3",	&sai3_clk},
+	{"cko1",	&cko1_clk},
+	{"esdhc0",	&esdhc0_clk},
+	{"esdhc1",	&esdhc1_clk},
+	{"qspi0",	&qspi0_clk},
+	{"dcu0",	&dcu0_clk},
+	{"enet",	&enet_clk},
+	{"nand",	&nand_clk},
+	{"esai",	&esai_clk},
+	{NULL,	NULL}
+};
+
+struct ccm_softc {
+	struct resource		*res[1];
+	bus_space_tag_t		bst;
+	bus_space_handle_t	bsh;
+	device_t		dev;
+};
+
+static struct resource_spec ccm_spec[] = {
+	{ SYS_RES_MEMORY,       0,      RF_ACTIVE },
+	{ -1, 0 }
+};
+
+static int
+ccm_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "fsl,mvf600-ccm"))
+		return (ENXIO);
+
+	device_set_desc(dev, "Vybrid Family CCM Unit");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+set_clock(struct ccm_softc *sc, char *name)
+{
+	struct clk *clk;
+	int reg;
+	int i;
+
+	for (i = 0; clock_map[i].name != NULL; i++) {
+		if (strcmp(clock_map[i].name, name) == 0) {
+#if 0
+			device_printf(sc->dev, "Configuring %s clk\n", name);
+#endif
+			clk = clock_map[i].clk;
+			if (clk->sel_reg != 0) {
+				reg = READ4(sc, clk->sel_reg);
+				reg &= ~(clk->sel_mask << clk->sel_shift);
+				reg |= (clk->sel_val << clk->sel_shift);
+				WRITE4(sc, clk->sel_reg, reg);
+			};
+
+			reg = READ4(sc, clk->reg);
+			reg |= clk->enable_reg;
+			reg &= ~(clk->div_mask << clk->div_shift);
+			reg |= (clk->div_val << clk->div_shift);
+			WRITE4(sc, clk->reg, reg);
+		};
+	};
+
+	return (0);
+}
+
+static int
+ccm_fdt_set(struct ccm_softc *sc)
+{
+	phandle_t child, parent, root;
+	int len;
+	char *fdt_config, *name;
+
+	root = OF_finddevice("/");
+	len = 0;
+	parent = root;
+
+	/* Find 'clock_names' prop in the tree */
+	for (child = OF_child(parent); child != 0; child = OF_peer(child)) {
+
+		/* Find a 'leaf'. Start the search from this node. */
+		while (OF_child(child)) {
+			parent = child;
+			child = OF_child(child);
+		}
+
+		if (!fdt_is_enabled(child))
+			continue;
+
+		if ((len = OF_getproplen(child, "clock_names")) > 0) {
+			len = OF_getproplen(child, "clock_names");
+			OF_getprop_alloc(child, "clock_names", 1,
+			    (void **)&fdt_config);
+
+			while (len > 0) {
+				name = fdt_config;
+				fdt_config += strlen(name) + 1;
+				len -= strlen(name) + 1;
+				set_clock(sc, name);
+			};
+		};
+
+		if (OF_peer(child) == 0) {
+			/* No more siblings. */
+			child = parent;
+			parent = OF_parent(child);
+		}
+	}
+
+	return (0);
+}
+
+static int
+ccm_attach(device_t dev)
+{
+	struct ccm_softc *sc;
+	int reg;
+	int i;
+
+	sc = device_get_softc(dev);
+	sc->dev = dev;
+
+	if (bus_alloc_resources(dev, ccm_spec, sc->res)) {
+		device_printf(dev, "could not allocate resources\n");
+		return (ENXIO);
+	}
+
+	/* Memory interface */
+	sc->bst = rman_get_bustag(sc->res[0]);
+	sc->bsh = rman_get_bushandle(sc->res[0]);
+
+	/* Enable oscillator */
+	reg = READ4(sc, CCM_CCR);
+	reg |= (FIRC_EN | FXOSC_EN);
+	WRITE4(sc, CCM_CCR, reg);
+
+	/* Wait 10 times */
+	for (i = 0; i < 10; i++) {
+		if (READ4(sc, CCM_CSR) & FXOSC_RDY) {
+			device_printf(sc->dev, "On board oscillator is ready.\n");
+			break;
+		}
+
+		cpufunc_nullop();
+	}
+
+	/* Clock is on during all modes, except stop mode. */
+	for (i = 0; i < CCM_CCGRN; i++) {
+		WRITE4(sc, CCM_CCGR(i), 0xffffffff);
+	}
+
+	/* Take and apply FDT clocks */
+	ccm_fdt_set(sc);
+
+	return (0);
+}
+
+static device_method_t ccm_methods[] = {
+	DEVMETHOD(device_probe,		ccm_probe),
+	DEVMETHOD(device_attach,	ccm_attach),
+	{ 0, 0 }
+};
+
+static driver_t ccm_driver = {
+	"ccm",
+	ccm_methods,
+	sizeof(struct ccm_softc),
+};
+
+static devclass_t ccm_devclass;
+
+DRIVER_MODULE(ccm, simplebus, ccm_driver, ccm_devclass, 0, 0);


Property changes on: trunk/sys/arm/freescale/vybrid/vf_ccm.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/vybrid/vf_common.c
===================================================================
--- trunk/sys/arm/freescale/vybrid/vf_common.c	                        (rev 0)
+++ trunk/sys/arm/freescale/vybrid/vf_common.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,87 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Ruslan Bukin <br at bsdpad.com>
+ * 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: stable/10/sys/arm/freescale/vybrid/vf_common.c 258057 2013-11-12 18:02:56Z br $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+
+#include <arm/freescale/vybrid/vf_src.h>
+
+void
+cpu_reset(void)
+{
+	phandle_t src;
+	uint32_t addr, paddr;
+	bus_addr_t vaddr;
+
+	if (src_swreset() == 0)
+		goto end;
+
+	src = OF_finddevice("src");
+	if ((src != 0) && (OF_getprop(src, "reg", &paddr, sizeof(paddr))) > 0) {
+		addr = fdt32_to_cpu(paddr);
+		if (bus_space_map(fdtbus_bs_tag, addr, 0x10, 0, &vaddr) == 0) {
+			bus_space_write_4(fdtbus_bs_tag, vaddr, 0x00, SW_RST);
+		}
+	}
+
+end:
+	while (1);
+}
+
+struct fdt_fixup_entry fdt_fixup_table[] = {
+	{ NULL, NULL }
+};
+
+static int
+fdt_pic_decode_ic(phandle_t node, pcell_t *intr, int *interrupt, int *trig,
+    int *pol)
+{
+
+	if (!fdt_is_compatible(node, "arm,gic"))
+		return (ENXIO);
+
+	*interrupt = fdt32_to_cpu(intr[0]);
+	*trig = INTR_TRIGGER_CONFORM;
+	*pol = INTR_POLARITY_CONFORM;
+	return (0);
+}
+
+fdt_pic_decode_t fdt_pic_table[] = {
+	&fdt_pic_decode_ic,
+	NULL
+};


Property changes on: trunk/sys/arm/freescale/vybrid/vf_common.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/vybrid/vf_common.h
===================================================================
--- trunk/sys/arm/freescale/vybrid/vf_common.h	                        (rev 0)
+++ trunk/sys/arm/freescale/vybrid/vf_common.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,44 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013-2014 Ruslan Bukin <br at bsdpad.com>
+ * 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: stable/10/sys/arm/freescale/vybrid/vf_common.h 266198 2014-05-15 22:03:24Z ian $
+ */
+
+#define	READ4(_sc, _reg)	\
+	bus_space_read_4(_sc->bst, _sc->bsh, _reg)
+#define	WRITE4(_sc, _reg, _val)	\
+	bus_space_write_4(_sc->bst, _sc->bsh, _reg, _val)
+#define	READ2(_sc, _reg)	\
+	bus_space_read_2(_sc->bst, _sc->bsh, _reg)
+#define	WRITE2(_sc, _reg, _val)	\
+	bus_space_write_2(_sc->bst, _sc->bsh, _reg, _val)
+#define	READ1(_sc, _reg)	\
+	bus_space_read_1(_sc->bst, _sc->bsh, _reg)
+#define	WRITE1(_sc, _reg, _val)	\
+	bus_space_write_1(_sc->bst, _sc->bsh, _reg, _val)
+
+uint32_t pll4_configure_output(uint32_t mfi, uint32_t mfn, uint32_t mfd);
+uint32_t tcon_bypass(void);


Property changes on: trunk/sys/arm/freescale/vybrid/vf_common.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/vybrid/vf_dcu4.c
===================================================================
--- trunk/sys/arm/freescale/vybrid/vf_dcu4.c	                        (rev 0)
+++ trunk/sys/arm/freescale/vybrid/vf_dcu4.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,468 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014 Ruslan Bukin <br at bsdpad.com>
+ * 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.
+ */
+
+/*
+ * Vybrid Family Display Control Unit (DCU4)
+ * Chapter 55, Vybrid Reference Manual, Rev. 5, 07/2013
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/freescale/vybrid/vf_dcu4.c 266274 2014-05-16 23:27:18Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/timeet.h>
+#include <sys/timetc.h>
+#include <sys/watchdog.h>
+#include <sys/fbio.h>
+#include <sys/consio.h>
+#include <sys/eventhandler.h>
+#include <sys/gpio.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <dev/vt/vt.h>
+#include <dev/vt/colors/vt_termcolors.h>
+
+#include "gpio_if.h"
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#include "fb_if.h"
+
+#include <arm/freescale/vybrid/vf_common.h>
+
+#define	DCU_CTRLDESCCURSOR1	0x000	/* Control Descriptor Cursor 1 */
+#define	DCU_CTRLDESCCURSOR2	0x004	/* Control Descriptor Cursor 2 */
+#define	DCU_CTRLDESCCURSOR3	0x008	/* Control Descriptor Cursor 3 */
+#define	DCU_CTRLDESCCURSOR4	0x00C	/* Control Descriptor Cursor 4 */
+#define	DCU_DCU_MODE		0x010	/* DCU4 Mode */
+#define	 DCU_MODE_M		0x3
+#define	 DCU_MODE_S		0
+#define	 DCU_MODE_NORMAL	0x1
+#define	 DCU_MODE_TEST		0x2
+#define	 DCU_MODE_COLBAR	0x3
+#define	 RASTER_EN		(1 << 14)	/* Raster scan of pixel data */
+#define	 PDI_EN			(1 << 13)
+#define	 PDI_DE_MODE		(1 << 11)
+#define	 PDI_MODE_M		2
+#define	DCU_BGND		0x014	/* Background */
+#define	DCU_DISP_SIZE		0x018	/* Display Size */
+#define	 DELTA_M		0x7ff
+#define	 DELTA_Y_S		16
+#define	 DELTA_X_S		0
+#define	DCU_HSYN_PARA		0x01C	/* Horizontal Sync Parameter */
+#define	 BP_H_SHIFT		22
+#define	 PW_H_SHIFT		11
+#define	 FP_H_SHIFT		0
+#define	DCU_VSYN_PARA		0x020	/* Vertical Sync Parameter */
+#define	 BP_V_SHIFT		22
+#define	 PW_V_SHIFT		11
+#define	 FP_V_SHIFT		0
+#define	DCU_SYNPOL		0x024	/* Synchronize Polarity */
+#define	 INV_HS			(1 << 0)
+#define	 INV_VS			(1 << 1)
+#define	 INV_PDI_VS		(1 << 8) /* Polarity of PDI input VSYNC. */
+#define	 INV_PDI_HS		(1 << 9) /* Polarity of PDI input HSYNC. */
+#define	 INV_PDI_DE		(1 << 10) /* Polarity of PDI input DE. */
+#define	DCU_THRESHOLD		0x028	/* Threshold */
+#define	 LS_BF_VS_SHIFT		16
+#define	 OUT_BUF_HIGH_SHIFT	8
+#define	 OUT_BUF_LOW_SHIFT	0
+#define	DCU_INT_STATUS		0x02C	/* Interrupt Status */
+#define	DCU_INT_MASK		0x030	/* Interrupt Mask */
+#define	DCU_COLBAR_1		0x034	/* COLBAR_1 */
+#define	DCU_COLBAR_2		0x038	/* COLBAR_2 */
+#define	DCU_COLBAR_3		0x03C	/* COLBAR_3 */
+#define	DCU_COLBAR_4		0x040	/* COLBAR_4 */
+#define	DCU_COLBAR_5		0x044	/* COLBAR_5 */
+#define	DCU_COLBAR_6		0x048	/* COLBAR_6 */
+#define	DCU_COLBAR_7		0x04C	/* COLBAR_7 */
+#define	DCU_COLBAR_8		0x050	/* COLBAR_8 */
+#define	DCU_DIV_RATIO		0x054	/* Divide Ratio */
+#define	DCU_SIGN_CALC_1		0x058	/* Sign Calculation 1 */
+#define	DCU_SIGN_CALC_2		0x05C	/* Sign Calculation 2 */
+#define	DCU_CRC_VAL		0x060	/* CRC Value */
+#define	DCU_PDI_STATUS		0x064	/* PDI Status */
+#define	DCU_PDI_STA_MSK		0x068	/* PDI Status Mask */
+#define	DCU_PARR_ERR_STATUS1	0x06C	/* Parameter Error Status 1 */
+#define	DCU_PARR_ERR_STATUS2	0x070	/* Parameter Error Status 2 */
+#define	DCU_PARR_ERR_STATUS3	0x07C	/* Parameter Error Status 3 */
+#define	DCU_MASK_PARR_ERR_ST1	0x080	/* Mask Parameter Error Status 1 */
+#define	DCU_MASK_PARR_ERR_ST2	0x084	/* Mask Parameter Error Status 2 */
+#define	DCU_MASK_PARR_ERR_ST3	0x090	/* Mask Parameter Error Status 3 */
+#define	DCU_THRESHOLD_INP_BUF_1	0x094	/* Threshold Input 1 */
+#define	DCU_THRESHOLD_INP_BUF_2	0x098	/* Threshold Input 2 */
+#define	DCU_THRESHOLD_INP_BUF_3	0x09C	/* Threshold Input 3 */
+#define	DCU_LUMA_COMP		0x0A0	/* LUMA Component */
+#define	DCU_CHROMA_RED		0x0A4	/* Red Chroma Components */
+#define	DCU_CHROMA_GREEN	0x0A8	/* Green Chroma Components */
+#define	DCU_CHROMA_BLUE		0x0AC	/* Blue Chroma Components */
+#define	DCU_CRC_POS		0x0B0	/* CRC Position */
+#define	DCU_LYR_INTPOL_EN	0x0B4	/* Layer Interpolation Enable */
+#define	DCU_LYR_LUMA_COMP	0x0B8	/* Layer Luminance Component */
+#define	DCU_LYR_CHRM_RED	0x0BC	/* Layer Chroma Red */
+#define	DCU_LYR_CHRM_GRN	0x0C0	/* Layer Chroma Green */
+#define	DCU_LYR_CHRM_BLUE	0x0C4	/* Layer Chroma Blue */
+#define	DCU_COMP_IMSIZE		0x0C8	/* Compression Image Size */
+#define	DCU_UPDATE_MODE		0x0CC	/* Update Mode */
+#define	 READREG		(1 << 30)
+#define	 MODE			(1 << 31)
+#define	DCU_UNDERRUN		0x0D0	/* Underrun */
+#define	DCU_GLBL_PROTECT	0x100	/* Global Protection */
+#define	DCU_SFT_LCK_BIT_L0	0x104	/* Soft Lock Bit Layer 0 */
+#define	DCU_SFT_LCK_BIT_L1	0x108	/* Soft Lock Bit Layer 1 */
+#define	DCU_SFT_LCK_DISP_SIZE	0x10C	/* Soft Lock Display Size */
+#define	DCU_SFT_LCK_HS_VS_PARA	0x110	/* Soft Lock Hsync/Vsync Parameter */
+#define	DCU_SFT_LCK_POL		0x114	/* Soft Lock POL */
+#define	DCU_SFT_LCK_L0_TRANSP	0x118	/* Soft Lock L0 Transparency */
+#define	DCU_SFT_LCK_L1_TRANSP	0x11C	/* Soft Lock L1 Transparency */
+
+/* Control Descriptor */
+#define DCU_CTRLDESCL(n, m)	0x200 + (0x40 * n) + 0x4 * (m - 1)
+#define DCU_CTRLDESCLn_1(n)	DCU_CTRLDESCL(n, 1)
+#define DCU_CTRLDESCLn_2(n)	DCU_CTRLDESCL(n, 2)
+#define DCU_CTRLDESCLn_3(n)	DCU_CTRLDESCL(n, 3)
+#define	 TRANS_SHIFT		20
+#define DCU_CTRLDESCLn_4(n)	DCU_CTRLDESCL(n, 4)
+#define	 BPP_MASK		0xf		/* Bit per pixel Mask */
+#define	 BPP_SHIFT		16		/* Bit per pixel Shift */
+#define	 BPP24			0x5
+#define	 EN_LAYER		(1 << 31)	/* Enable the layer */
+#define DCU_CTRLDESCLn_5(n)	DCU_CTRLDESCL(n, 5)
+#define DCU_CTRLDESCLn_6(n)	DCU_CTRLDESCL(n, 6)
+#define DCU_CTRLDESCLn_7(n)	DCU_CTRLDESCL(n, 7)
+#define DCU_CTRLDESCLn_8(n)	DCU_CTRLDESCL(n, 8)
+#define DCU_CTRLDESCLn_9(n)	DCU_CTRLDESCL(n, 9)
+
+#define	NUM_LAYERS	64
+
+struct panel_info {
+	uint32_t	width;
+	uint32_t	height;
+	uint32_t	h_back_porch;
+	uint32_t	h_pulse_width;
+	uint32_t	h_front_porch;
+	uint32_t	v_back_porch;
+	uint32_t	v_pulse_width;
+	uint32_t	v_front_porch;
+	uint32_t	clk_div;
+	uint32_t	backlight_pin;
+};
+
+struct dcu_softc {
+	struct resource		*res[2];
+	bus_space_tag_t		bst;
+	bus_space_handle_t	bsh;
+	void			*ih;
+	device_t		dev;
+	device_t		sc_fbd;		/* fbd child */
+	struct fb_info		sc_info;
+	struct panel_info	*panel;
+};
+
+static struct resource_spec dcu_spec[] = {
+	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		0,	RF_ACTIVE },
+	{ -1, 0 }
+};
+
+static int
+dcu_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "fsl,mvf600-dcu4"))
+		return (ENXIO);
+
+	device_set_desc(dev, "Vybrid Family Display Control Unit (DCU4)");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static void
+dcu_intr(void *arg)
+{
+	struct dcu_softc *sc;
+	int reg;
+
+	sc = arg;
+
+	/* Ack interrupts */
+	reg = READ4(sc, DCU_INT_STATUS);
+	WRITE4(sc, DCU_INT_STATUS, reg);
+
+	/* TODO interrupt handler */
+}
+
+static int
+get_panel_info(struct dcu_softc *sc, struct panel_info *panel)
+{
+	phandle_t node;
+	pcell_t dts_value[3];
+	int len;
+
+	if ((node = ofw_bus_get_node(sc->dev)) == -1)
+		return (ENXIO);
+
+	/* panel size */
+	if ((len = OF_getproplen(node, "panel-size")) <= 0)
+		return (ENXIO);
+	OF_getprop(node, "panel-size", &dts_value, len);
+	panel->width = fdt32_to_cpu(dts_value[0]);
+	panel->height = fdt32_to_cpu(dts_value[1]);
+
+	/* hsync */
+	if ((len = OF_getproplen(node, "panel-hsync")) <= 0)
+		return (ENXIO);
+	OF_getprop(node, "panel-hsync", &dts_value, len);
+	panel->h_back_porch = fdt32_to_cpu(dts_value[0]);
+	panel->h_pulse_width = fdt32_to_cpu(dts_value[1]);
+	panel->h_front_porch = fdt32_to_cpu(dts_value[2]);
+
+	/* vsync */
+	if ((len = OF_getproplen(node, "panel-vsync")) <= 0)
+		return (ENXIO);
+	OF_getprop(node, "panel-vsync", &dts_value, len);
+	panel->v_back_porch = fdt32_to_cpu(dts_value[0]);
+	panel->v_pulse_width = fdt32_to_cpu(dts_value[1]);
+	panel->v_front_porch = fdt32_to_cpu(dts_value[2]);
+
+	/* clk divider */
+	if ((len = OF_getproplen(node, "panel-clk-div")) <= 0)
+		return (ENXIO);
+	OF_getprop(node, "panel-clk-div", &dts_value, len);
+	panel->clk_div = fdt32_to_cpu(dts_value[0]);
+
+	/* backlight pin */
+	if ((len = OF_getproplen(node, "panel-backlight-pin")) <= 0)
+		return (ENXIO);
+	OF_getprop(node, "panel-backlight-pin", &dts_value, len);
+	panel->backlight_pin = fdt32_to_cpu(dts_value[0]);
+
+	return (0);
+}
+
+static int
+dcu_init(struct dcu_softc *sc)
+{
+	struct panel_info *panel;
+	int reg;
+	int i;
+
+	panel = sc->panel;
+
+	/* Configure DCU */
+	reg = ((sc->sc_info.fb_height) << DELTA_Y_S);
+	reg |= (sc->sc_info.fb_width / 16);
+	WRITE4(sc, DCU_DISP_SIZE, reg);
+
+	reg = (panel->h_back_porch << BP_H_SHIFT);
+	reg |= (panel->h_pulse_width << PW_H_SHIFT);
+	reg |= (panel->h_front_porch << FP_H_SHIFT);
+	WRITE4(sc, DCU_HSYN_PARA, reg);
+
+	reg = (panel->v_back_porch << BP_V_SHIFT);
+	reg |= (panel->v_pulse_width << PW_V_SHIFT);
+	reg |= (panel->v_front_porch << FP_V_SHIFT);
+	WRITE4(sc, DCU_VSYN_PARA, reg);
+
+	WRITE4(sc, DCU_BGND, 0);
+	WRITE4(sc, DCU_DIV_RATIO, panel->clk_div);
+
+	reg = (INV_VS | INV_HS);
+	WRITE4(sc, DCU_SYNPOL, reg);
+
+	/* TODO: export to panel info */
+	reg = (0x3 << LS_BF_VS_SHIFT);
+	reg |= (0x78 << OUT_BUF_HIGH_SHIFT);
+	reg |= (0 << OUT_BUF_LOW_SHIFT);
+	WRITE4(sc, DCU_THRESHOLD, reg);
+
+	/* Mask all the interrupts */
+	WRITE4(sc, DCU_INT_MASK, 0xffffffff);
+
+	/* Reset all layers */
+	for (i = 0; i < NUM_LAYERS; i++) {
+		WRITE4(sc, DCU_CTRLDESCLn_1(i), 0x0);
+		WRITE4(sc, DCU_CTRLDESCLn_2(i), 0x0);
+		WRITE4(sc, DCU_CTRLDESCLn_3(i), 0x0);
+		WRITE4(sc, DCU_CTRLDESCLn_4(i), 0x0);
+		WRITE4(sc, DCU_CTRLDESCLn_5(i), 0x0);
+		WRITE4(sc, DCU_CTRLDESCLn_6(i), 0x0);
+		WRITE4(sc, DCU_CTRLDESCLn_7(i), 0x0);
+		WRITE4(sc, DCU_CTRLDESCLn_8(i), 0x0);
+		WRITE4(sc, DCU_CTRLDESCLn_9(i), 0x0);
+	}
+
+	/* Setup first layer */
+	reg = (sc->sc_info.fb_width | (sc->sc_info.fb_height << 16));
+	WRITE4(sc, DCU_CTRLDESCLn_1(0), reg);
+	WRITE4(sc, DCU_CTRLDESCLn_2(0), 0x0);
+	WRITE4(sc, DCU_CTRLDESCLn_3(0), sc->sc_info.fb_pbase);
+	reg = (BPP24 << BPP_SHIFT);
+	reg |= EN_LAYER;
+	reg |= (0xFF << TRANS_SHIFT); /* completely opaque */
+	WRITE4(sc, DCU_CTRLDESCLn_4(0), reg);
+	WRITE4(sc, DCU_CTRLDESCLn_5(0), 0xffffff);
+	WRITE4(sc, DCU_CTRLDESCLn_6(0), 0x0);
+	WRITE4(sc, DCU_CTRLDESCLn_7(0), 0x0);
+	WRITE4(sc, DCU_CTRLDESCLn_8(0), 0x0);
+	WRITE4(sc, DCU_CTRLDESCLn_9(0), 0x0);
+
+	/* Enable DCU in normal mode */
+	reg = READ4(sc, DCU_DCU_MODE);
+	reg &= ~(DCU_MODE_M << DCU_MODE_S);
+	reg |= (DCU_MODE_NORMAL << DCU_MODE_S);
+	reg |= (RASTER_EN);
+	WRITE4(sc, DCU_DCU_MODE, reg);
+	WRITE4(sc, DCU_UPDATE_MODE, READREG);
+
+	return (0);
+}
+
+static int
+dcu_attach(device_t dev)
+{
+	struct panel_info panel;
+	struct dcu_softc *sc;
+	device_t gpio_dev;
+	int err;
+
+	sc = device_get_softc(dev);
+	sc->dev = dev;
+
+	if (bus_alloc_resources(dev, dcu_spec, sc->res)) {
+		device_printf(dev, "could not allocate resources\n");
+		return (ENXIO);
+	}
+
+	/* Memory interface */
+	sc->bst = rman_get_bustag(sc->res[0]);
+	sc->bsh = rman_get_bushandle(sc->res[0]);
+
+	/* Setup interrupt handler */
+	err = bus_setup_intr(dev, sc->res[1], INTR_TYPE_BIO | INTR_MPSAFE,
+	    NULL, dcu_intr, sc, &sc->ih);
+	if (err) {
+		device_printf(dev, "Unable to alloc interrupt resource.\n");
+		return (ENXIO);
+	}
+
+	if (get_panel_info(sc, &panel)) {
+		device_printf(dev, "Can't get panel info\n");
+		return (ENXIO);
+	}
+
+	sc->panel = &panel;
+
+	/* Bypass timing control (used for raw lcd panels) */
+	tcon_bypass();
+
+	/* Get the GPIO device, we need this to give power to USB */
+	gpio_dev = devclass_get_device(devclass_find("gpio"), 0);
+	if (gpio_dev == NULL) {
+		device_printf(sc->dev, "Error: failed to get the GPIO dev\n");
+		return (1);
+	}
+
+	/* Turn on backlight */
+	/* TODO: Use FlexTimer/PWM */
+	GPIO_PIN_SETFLAGS(gpio_dev, panel.backlight_pin, GPIO_PIN_OUTPUT);
+	GPIO_PIN_SET(gpio_dev, panel.backlight_pin, GPIO_PIN_HIGH);
+
+	sc->sc_info.fb_width = panel.width;
+	sc->sc_info.fb_height = panel.height;
+	sc->sc_info.fb_stride = sc->sc_info.fb_width * 3;
+	sc->sc_info.fb_bpp = sc->sc_info.fb_depth = 24;
+	sc->sc_info.fb_size = sc->sc_info.fb_height * sc->sc_info.fb_stride;
+	sc->sc_info.fb_vbase = (intptr_t)contigmalloc(sc->sc_info.fb_size,
+	    M_DEVBUF, M_ZERO, 0, ~0, PAGE_SIZE, 0);
+	sc->sc_info.fb_pbase = (intptr_t)vtophys(sc->sc_info.fb_vbase);
+
+#if 0
+	printf("%dx%d [%d]\n", sc->sc_info.fb_width, sc->sc_info.fb_height,
+	    sc->sc_info.fb_stride);
+	printf("pbase == 0x%08x\n", sc->sc_info.fb_pbase);
+#endif
+
+	memset((int8_t *)sc->sc_info.fb_vbase, 0x0, sc->sc_info.fb_size);
+
+	dcu_init(sc);
+
+	sc->sc_info.fb_name = device_get_nameunit(dev);
+
+	/* Ask newbus to attach framebuffer device to me. */
+	sc->sc_fbd = device_add_child(dev, "fbd", device_get_unit(dev));
+	if (sc->sc_fbd == NULL)
+		device_printf(dev, "Can't attach fbd device\n");
+
+	if (device_probe_and_attach(sc->sc_fbd) != 0) {
+		device_printf(sc->dev, "Failed to attach fbd device\n");
+	}
+
+	return (0);
+}
+
+static struct fb_info *
+dcu4_fb_getinfo(device_t dev)
+{
+	struct dcu_softc *sc = device_get_softc(dev);
+
+	return (&sc->sc_info);
+}
+
+static device_method_t dcu_methods[] = {
+	DEVMETHOD(device_probe,		dcu_probe),
+	DEVMETHOD(device_attach,	dcu_attach),
+
+	/* Framebuffer service methods */
+	DEVMETHOD(fb_getinfo,		dcu4_fb_getinfo),
+	{ 0, 0 }
+};
+
+static driver_t dcu_driver = {
+	"fb",
+	dcu_methods,
+	sizeof(struct dcu_softc),
+};
+
+static devclass_t dcu_devclass;
+
+DRIVER_MODULE(fb, simplebus, dcu_driver, dcu_devclass, 0, 0);


Property changes on: trunk/sys/arm/freescale/vybrid/vf_dcu4.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/vybrid/vf_dmamux.c
===================================================================
--- trunk/sys/arm/freescale/vybrid/vf_dmamux.c	                        (rev 0)
+++ trunk/sys/arm/freescale/vybrid/vf_dmamux.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,156 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014 Ruslan Bukin <br at bsdpad.com>
+ * 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.
+ */
+
+/*
+ * Vybrid Family Direct Memory Access Multiplexer (DMAMUX)
+ * Chapter 22, Vybrid Reference Manual, Rev. 5, 07/2013
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/freescale/vybrid/vf_dmamux.c 266170 2014-05-15 18:38:19Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/timeet.h>
+#include <sys/timetc.h>
+#include <sys/watchdog.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#include <arm/freescale/vybrid/vf_common.h>
+#include <arm/freescale/vybrid/vf_dmamux.h>
+
+#define	DMAMUX_CHCFG(n)		(0x1 * n)	/* Channels 0-15 Cfg Reg */
+#define	CHCFG_ENBL		(1 << 7)	/* Channel Enable */
+#define	CHCFG_TRIG		(1 << 6)	/* Channel Trigger Enable */
+#define	CHCFG_SOURCE_MASK	0x3f		/* Channel Source (Slot) */
+#define	CHCFG_SOURCE_SHIFT	0
+
+struct dmamux_softc {
+	struct resource		*res[4];
+	bus_space_tag_t		bst[4];
+	bus_space_handle_t	bsh[4];
+};
+
+struct dmamux_softc *dmamux_sc;
+
+static struct resource_spec dmamux_spec[] = {
+	{ SYS_RES_MEMORY,	0,	RF_ACTIVE }, /* DMAMUX0 */
+	{ SYS_RES_MEMORY,	1,	RF_ACTIVE }, /* DMAMUX1 */
+	{ SYS_RES_MEMORY,	2,	RF_ACTIVE }, /* DMAMUX2 */
+	{ SYS_RES_MEMORY,	3,	RF_ACTIVE }, /* DMAMUX3 */
+	{ -1, 0 }
+};
+
+static int
+dmamux_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "fsl,mvf600-dmamux"))
+		return (ENXIO);
+
+	device_set_desc(dev, "Vybrid Family Direct Memory Access Multiplexer");
+	return (BUS_PROBE_DEFAULT);
+}
+
+int
+dmamux_configure(int mux, int source, int channel, int enable)
+{
+	struct dmamux_softc *sc;
+	int reg;
+
+	sc = dmamux_sc;
+
+	MUX_WRITE1(sc, mux, DMAMUX_CHCFG(channel), 0x0);
+
+	reg = 0;
+	if (enable)
+		reg |= (CHCFG_ENBL);
+
+	reg &= ~(CHCFG_SOURCE_MASK << CHCFG_SOURCE_SHIFT);
+	reg |= (source << CHCFG_SOURCE_SHIFT);
+
+	MUX_WRITE1(sc, mux, DMAMUX_CHCFG(channel), reg);
+
+	return (0);
+}
+
+static int
+dmamux_attach(device_t dev)
+{
+	struct dmamux_softc *sc;
+	int i;
+
+	sc = device_get_softc(dev);
+
+	if (bus_alloc_resources(dev, dmamux_spec, sc->res)) {
+		device_printf(dev, "could not allocate resources\n");
+		return (ENXIO);
+	}
+
+	/* Memory interface */
+	for (i = 0; i < 4; i++) {
+		sc->bst[i] = rman_get_bustag(sc->res[i]);
+		sc->bsh[i] = rman_get_bushandle(sc->res[i]);
+	}
+
+	dmamux_sc = sc;
+
+	return (0);
+}
+
+static device_method_t dmamux_methods[] = {
+	DEVMETHOD(device_probe,		dmamux_probe),
+	DEVMETHOD(device_attach,	dmamux_attach),
+	{ 0, 0 }
+};
+
+static driver_t dmamux_driver = {
+	"dmamux",
+	dmamux_methods,
+	sizeof(struct dmamux_softc),
+};
+
+static devclass_t dmamux_devclass;
+
+DRIVER_MODULE(dmamux, simplebus, dmamux_driver, dmamux_devclass, 0, 0);


Property changes on: trunk/sys/arm/freescale/vybrid/vf_dmamux.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/vybrid/vf_dmamux.h
===================================================================
--- trunk/sys/arm/freescale/vybrid/vf_dmamux.h	                        (rev 0)
+++ trunk/sys/arm/freescale/vybrid/vf_dmamux.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,49 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014 Ruslan Bukin <br at bsdpad.com>
+ * 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: stable/10/sys/arm/freescale/vybrid/vf_dmamux.h 266170 2014-05-15 18:38:19Z ian $
+ */
+
+int dmamux_configure(int mux, int source, int channel, int enable);
+
+enum mux_num {
+	MUX0,
+	MUX1,
+	MUX2,
+	MUX3,
+};
+
+enum mux_grp {
+	MUXGRP0, /* MUX[0,3] */
+	MUXGRP1, /* MUX[1,2] */
+};
+
+/* DMAMUX */
+#define	MUX_READ1(_sc, _mux, _reg)				\
+	bus_space_read_1(_sc->bst[_mux], _sc->bsh[_mux], _reg)
+
+#define	MUX_WRITE1(_sc, _mux, _reg, _val)			\
+	bus_space_write_1(_sc->bst[_mux], _sc->bsh[_mux], _reg, _val)


Property changes on: trunk/sys/arm/freescale/vybrid/vf_dmamux.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/vybrid/vf_edma.c
===================================================================
--- trunk/sys/arm/freescale/vybrid/vf_edma.c	                        (rev 0)
+++ trunk/sys/arm/freescale/vybrid/vf_edma.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,339 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014 Ruslan Bukin <br at bsdpad.com>
+ * 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.
+ */
+
+/*
+ * Vybrid Family Enhanced Direct Memory Access Controller (eDMA)
+ * Chapter 21, Vybrid Reference Manual, Rev. 5, 07/2013
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/freescale/vybrid/vf_edma.c 266170 2014-05-15 18:38:19Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/timeet.h>
+#include <sys/timetc.h>
+#include <sys/watchdog.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#include <arm/freescale/vybrid/vf_edma.h>
+#include <arm/freescale/vybrid/vf_dmamux.h>
+#include <arm/freescale/vybrid/vf_common.h>
+
+struct edma_channel {
+	uint32_t	enabled;
+	uint32_t	mux_num;
+	uint32_t	mux_src;
+	uint32_t	mux_chn;
+	uint32_t	(*ih) (void *, int);
+	void		*ih_user;
+};
+
+static struct edma_channel edma_map[EDMA_NUM_CHANNELS];
+
+static struct resource_spec edma_spec[] = {
+	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
+	{ SYS_RES_MEMORY,	1,	RF_ACTIVE }, /* TCD */
+	{ SYS_RES_IRQ,		0,	RF_ACTIVE }, /* Transfer complete */
+	{ SYS_RES_IRQ,		1,	RF_ACTIVE }, /* Error Interrupt */
+	{ -1, 0 }
+};
+
+static int
+edma_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "fsl,mvf600-edma"))
+		return (ENXIO);
+
+	device_set_desc(dev, "Vybrid Family eDMA Controller");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static void
+edma_transfer_complete_intr(void *arg)
+{
+	struct edma_channel *ch;
+	struct edma_softc *sc;
+	int interrupts;
+	int i;
+
+	sc = arg;
+
+	interrupts = READ4(sc, DMA_INT);
+	WRITE1(sc, DMA_CINT, CINT_CAIR);
+
+	for (i = 0; i < EDMA_NUM_CHANNELS; i++) {
+		if (interrupts & (0x1 << i)) {
+			ch = &edma_map[i];
+			if (ch->enabled == 1) {
+				if (ch->ih != NULL) {
+					ch->ih(ch->ih_user, i);
+				}
+			}
+		}
+	}
+}
+
+static void
+edma_err_intr(void *arg)
+{
+	struct edma_softc *sc;
+	int reg;
+
+	sc = arg;
+
+	reg = READ4(sc, DMA_ERR);
+
+#if 0
+	device_printf(sc->dev, "DMA_ERR 0x%08x, ES 0x%08x\n",
+	    reg, READ4(sc, DMA_ES));
+#endif
+
+	WRITE1(sc, DMA_CERR, CERR_CAEI);
+}
+
+static int
+channel_free(struct edma_softc *sc, int chnum)
+{
+	struct edma_channel *ch;
+
+	ch = &edma_map[chnum];
+	ch->enabled = 0;
+
+	dmamux_configure(ch->mux_num, ch->mux_src, ch->mux_chn, 0);
+
+	return (0);
+}
+
+static int
+channel_configure(struct edma_softc *sc, int mux_grp, int mux_src)
+{
+	struct edma_channel *ch;
+	int channel_first;
+	int mux_num;
+	int chnum;
+	int i;
+
+	if ((sc->device_id == 0 && mux_grp == 1) ||	\
+	    (sc->device_id == 1 && mux_grp == 0)) {
+		channel_first = NCHAN_PER_MUX;
+		mux_num = (sc->device_id * 2) + 1;
+	} else {
+		channel_first = 0;
+		mux_num = sc->device_id * 2;
+	};
+
+	/* Take first unused eDMA channel */
+	ch = NULL;
+	for (i = channel_first; i < (channel_first + NCHAN_PER_MUX); i++) {
+		ch = &edma_map[i];
+		if (ch->enabled == 0) {
+			break;
+		}
+		ch = NULL;
+	};
+
+	if (ch == NULL) {
+		/* Can't find free channel */
+		return (-1);
+	};
+
+	chnum = i;
+
+	ch->enabled = 1;
+	ch->mux_num = mux_num;
+	ch->mux_src = mux_src;
+	ch->mux_chn = (chnum - channel_first);	/* 0 to 15 */
+
+	dmamux_configure(ch->mux_num, ch->mux_src, ch->mux_chn, 1);
+
+	return (chnum);
+}
+
+static int
+dma_stop(struct edma_softc *sc, int chnum)
+{
+	int reg;
+
+	reg = READ4(sc, DMA_ERQ);
+	reg &= ~(0x1 << chnum);
+	WRITE4(sc, DMA_ERQ, reg);
+
+	return (0);
+}
+
+static int
+dma_setup(struct edma_softc *sc, struct tcd_conf *tcd)
+{
+	struct edma_channel *ch;
+	int chnum;
+	int reg;
+
+	chnum = tcd->channel;
+
+	ch = &edma_map[chnum];
+	ch->ih = tcd->ih;
+	ch->ih_user = tcd->ih_user;
+
+	TCD_WRITE4(sc, DMA_TCDn_SADDR(chnum), tcd->saddr);
+	TCD_WRITE4(sc, DMA_TCDn_DADDR(chnum), tcd->daddr);
+
+	reg = (tcd->smod << TCD_ATTR_SMOD_SHIFT);
+	reg |= (tcd->dmod << TCD_ATTR_DMOD_SHIFT);
+	reg |= (tcd->ssize << TCD_ATTR_SSIZE_SHIFT);
+	reg |= (tcd->dsize << TCD_ATTR_DSIZE_SHIFT);
+	TCD_WRITE2(sc, DMA_TCDn_ATTR(chnum), reg);
+
+	TCD_WRITE2(sc, DMA_TCDn_SOFF(chnum), tcd->soff);
+	TCD_WRITE2(sc, DMA_TCDn_DOFF(chnum), tcd->doff);
+	TCD_WRITE4(sc, DMA_TCDn_SLAST(chnum), tcd->slast);
+	TCD_WRITE4(sc, DMA_TCDn_DLASTSGA(chnum), tcd->dlast_sga);
+	TCD_WRITE4(sc, DMA_TCDn_NBYTES_MLOFFYES(chnum), tcd->nbytes);
+
+	reg = tcd->nmajor; /* Current Major Iteration Count */
+	TCD_WRITE2(sc, DMA_TCDn_CITER_ELINKNO(chnum), reg);
+	TCD_WRITE2(sc, DMA_TCDn_BITER_ELINKNO(chnum), reg);
+
+	reg = (TCD_CSR_INTMAJOR);
+	if(tcd->majorelink == 1) {
+		reg |= TCD_CSR_MAJORELINK;
+		reg |= (tcd->majorelinkch << TCD_CSR_MAJORELINKCH_SHIFT);
+	}
+	TCD_WRITE2(sc, DMA_TCDn_CSR(chnum), reg);
+
+	/* Enable requests */
+	reg = READ4(sc, DMA_ERQ);
+	reg |= (0x1 << chnum);
+	WRITE4(sc, DMA_ERQ, reg);
+
+	/* Enable error interrupts */
+	reg = READ4(sc, DMA_EEI);
+	reg |= (0x1 << chnum);
+	WRITE4(sc, DMA_EEI, reg);
+
+	return (0);
+}
+
+static int
+dma_request(struct edma_softc *sc, int chnum)
+{
+	int reg;
+
+	/* Start */
+	reg = TCD_READ2(sc, DMA_TCDn_CSR(chnum));
+	reg |= TCD_CSR_START;
+	TCD_WRITE2(sc, DMA_TCDn_CSR(chnum), reg);
+
+	return (0);
+}
+
+static int
+edma_attach(device_t dev)
+{
+	struct edma_softc *sc;
+	phandle_t node;
+	int dts_value;
+	int len;
+
+	sc = device_get_softc(dev);
+	sc->dev = dev;
+
+	if ((node = ofw_bus_get_node(sc->dev)) == -1)
+		return (ENXIO);
+
+	if ((len = OF_getproplen(node, "device-id")) <= 0)
+		return (ENXIO);
+
+	OF_getprop(node, "device-id", &dts_value, len);
+	sc->device_id = fdt32_to_cpu(dts_value);
+
+	sc->dma_stop = dma_stop;
+	sc->dma_setup = dma_setup;
+	sc->dma_request = dma_request;
+	sc->channel_configure = channel_configure;
+	sc->channel_free = channel_free;
+
+	if (bus_alloc_resources(dev, edma_spec, sc->res)) {
+		device_printf(dev, "could not allocate resources\n");
+		return (ENXIO);
+	}
+
+	/* Memory interface */
+	sc->bst = rman_get_bustag(sc->res[0]);
+	sc->bsh = rman_get_bushandle(sc->res[0]);
+	sc->bst_tcd = rman_get_bustag(sc->res[1]);
+	sc->bsh_tcd = rman_get_bushandle(sc->res[1]);
+
+	/* Setup interrupt handlers */
+	if (bus_setup_intr(dev, sc->res[2], INTR_TYPE_BIO | INTR_MPSAFE,
+		NULL, edma_transfer_complete_intr, sc, &sc->tc_ih)) {
+		device_printf(dev, "Unable to alloc DMA intr resource.\n");
+		return (ENXIO);
+	}
+
+	if (bus_setup_intr(dev, sc->res[3], INTR_TYPE_BIO | INTR_MPSAFE,
+		NULL, edma_err_intr, sc, &sc->err_ih)) {
+		device_printf(dev, "Unable to alloc DMA Err intr resource.\n");
+		return (ENXIO);
+	}
+
+	return (0);
+}
+
+static device_method_t edma_methods[] = {
+	DEVMETHOD(device_probe,		edma_probe),
+	DEVMETHOD(device_attach,	edma_attach),
+	{ 0, 0 }
+};
+
+static driver_t edma_driver = {
+	"edma",
+	edma_methods,
+	sizeof(struct edma_softc),
+};
+
+static devclass_t edma_devclass;
+
+DRIVER_MODULE(edma, simplebus, edma_driver, edma_devclass, 0, 0);


Property changes on: trunk/sys/arm/freescale/vybrid/vf_edma.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/vybrid/vf_edma.h
===================================================================
--- trunk/sys/arm/freescale/vybrid/vf_edma.h	                        (rev 0)
+++ trunk/sys/arm/freescale/vybrid/vf_edma.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,187 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014 Ruslan Bukin <br at bsdpad.com>
+ * 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: stable/10/sys/arm/freescale/vybrid/vf_edma.h 266170 2014-05-15 18:38:19Z ian $
+ */
+
+#define	DMA_CR		0x000	/* Control */
+#define	DMA_ES		0x004	/* Error Status */
+#define	DMA_ERQ		0x00C	/* Enable Request */
+#define	DMA_EEI		0x014	/* Enable Error Interrupt */
+#define	DMA_CEEI	0x018	/* Clear Enable Error Interrupt */
+#define	DMA_SEEI	0x019	/* Set Enable Error Interrupt */
+#define	DMA_CERQ	0x01A	/* Clear Enable Request */
+#define	DMA_SERQ	0x01B	/* Set Enable Request */
+#define	DMA_CDNE	0x01C	/* Clear DONE Status Bit */
+#define	DMA_SSRT	0x01D	/* Set START Bit */
+#define	DMA_CERR	0x01E	/* Clear Error */
+#define	 CERR_CAEI	(1 << 6) /* Clear All Error Indicators */
+#define	DMA_CINT	0x01F	/* Clear Interrupt Request */
+#define	 CINT_CAIR	(1 << 6) /* Clear All Interrupt Requests */
+#define	DMA_INT		0x024	/* Interrupt Request */
+#define	DMA_ERR		0x02C	/* Error */
+#define	DMA_HRS		0x034	/* Hardware Request Status */
+#define	DMA_EARS	0x044	/* Enable Asynchronous Request in Stop */
+#define	DMA_DCHPRI3	0x100	/* Channel n Priority */
+#define	DMA_DCHPRI2	0x101	/* Channel n Priority */
+#define	DMA_DCHPRI1	0x102	/* Channel n Priority */
+#define	DMA_DCHPRI0	0x103	/* Channel n Priority */
+#define	DMA_DCHPRI7	0x104	/* Channel n Priority */
+#define	DMA_DCHPRI6	0x105	/* Channel n Priority */
+#define	DMA_DCHPRI5	0x106	/* Channel n Priority */
+#define	DMA_DCHPRI4	0x107	/* Channel n Priority */
+#define	DMA_DCHPRI11	0x108	/* Channel n Priority */
+#define	DMA_DCHPRI10	0x109	/* Channel n Priority */
+#define	DMA_DCHPRI9	0x10A	/* Channel n Priority */
+#define	DMA_DCHPRI8	0x10B	/* Channel n Priority */
+#define	DMA_DCHPRI15	0x10C	/* Channel n Priority */
+#define	DMA_DCHPRI14	0x10D	/* Channel n Priority */
+#define	DMA_DCHPRI13	0x10E	/* Channel n Priority */
+#define	DMA_DCHPRI12	0x10F	/* Channel n Priority */
+#define	DMA_DCHPRI19	0x110	/* Channel n Priority */
+#define	DMA_DCHPRI18	0x111	/* Channel n Priority */
+#define	DMA_DCHPRI17	0x112	/* Channel n Priority */
+#define	DMA_DCHPRI16	0x113	/* Channel n Priority */
+#define	DMA_DCHPRI23	0x114	/* Channel n Priority */
+#define	DMA_DCHPRI22	0x115	/* Channel n Priority */
+#define	DMA_DCHPRI21	0x116	/* Channel n Priority */
+#define	DMA_DCHPRI20	0x117	/* Channel n Priority */
+#define	DMA_DCHPRI27	0x118	/* Channel n Priority */
+#define	DMA_DCHPRI26	0x119	/* Channel n Priority */
+#define	DMA_DCHPRI25	0x11A	/* Channel n Priority */
+#define	DMA_DCHPRI24	0x11B	/* Channel n Priority */
+#define	DMA_DCHPRI31	0x11C	/* Channel n Priority */
+#define	DMA_DCHPRI30	0x11D	/* Channel n Priority */
+#define	DMA_DCHPRI29	0x11E	/* Channel n Priority */
+#define	DMA_DCHPRI28	0x11F	/* Channel n Priority */
+
+#define	DMA_TCDn_SADDR(n)		(0x00 + 0x20 * n)	/* Source Address */
+#define	DMA_TCDn_SOFF(n)		(0x04 + 0x20 * n)	/* Signed Source Address Offset */
+#define	DMA_TCDn_ATTR(n)		(0x06 + 0x20 * n)	/* Transfer Attributes */
+#define	DMA_TCDn_NBYTES_MLNO(n)		(0x08 + 0x20 * n)	/* Minor Byte Count */
+#define	DMA_TCDn_NBYTES_MLOFFNO(n)	(0x08 + 0x20 * n)	/* Signed Minor Loop Offset */
+#define	DMA_TCDn_NBYTES_MLOFFYES(n)	(0x08 + 0x20 * n)	/* Signed Minor Loop Offset */
+#define	DMA_TCDn_SLAST(n)		(0x0C + 0x20 * n)	/* Last Source Address Adjustment */
+#define	DMA_TCDn_DADDR(n)		(0x10 + 0x20 * n)	/* Destination Address */
+#define	DMA_TCDn_DOFF(n)		(0x14 + 0x20 * n)	/* Signed Destination Address Offset */
+#define	DMA_TCDn_CITER_ELINKYES(n)	(0x16 + 0x20 * n)	/* Current Minor Loop Link, Major Loop Count */
+#define	DMA_TCDn_CITER_ELINKNO(n)	(0x16 + 0x20 * n)
+#define	DMA_TCDn_DLASTSGA(n)		(0x18 + 0x20 * n)	/* Last Dst Addr Adjustment/Scatter Gather Address */
+#define	DMA_TCDn_CSR(n)			(0x1C + 0x20 * n)	/* Control and Status */
+#define	DMA_TCDn_BITER_ELINKYES(n)	(0x1E + 0x20 * n)	/* Beginning Minor Loop Link, Major Loop Count */
+#define	DMA_TCDn_BITER_ELINKNO(n)	(0x1E + 0x20 * n)	/* Beginning Minor Loop Link, Major Loop Count */
+
+#define TCD_CSR_START			(1 << 0)
+#define	TCD_CSR_INTMAJOR		(1 << 1)
+#define	TCD_CSR_INTHALF			(1 << 2)
+#define	TCD_CSR_DREQ			(1 << 3)
+#define	TCD_CSR_ESG			(1 << 4)
+#define	TCD_CSR_MAJORELINK		(1 << 5)
+#define	TCD_CSR_ACTIVE			(1 << 6)
+#define	TCD_CSR_DONE			(1 << 7)
+#define	TCD_CSR_MAJORELINKCH_SHIFT	8
+
+#define	TCD_ATTR_SMOD_SHIFT		11	/* Source Address Modulo */
+#define	TCD_ATTR_SSIZE_SHIFT		8	/* Source Data Transfer Size */
+#define	TCD_ATTR_DMOD_SHIFT		3	/* Dst Address Modulo */
+#define	TCD_ATTR_DSIZE_SHIFT		0	/* Dst Data Transfer Size */
+
+#define	TCD_READ4(_sc, _reg)		\
+	bus_space_read_4(_sc->bst_tcd, _sc->bsh_tcd, _reg)
+#define	TCD_WRITE4(_sc, _reg, _val)	\
+	bus_space_write_4(_sc->bst_tcd, _sc->bsh_tcd, _reg, _val)
+#define	TCD_READ2(_sc, _reg)		\
+	bus_space_read_2(_sc->bst_tcd, _sc->bsh_tcd, _reg)
+#define	TCD_WRITE2(_sc, _reg, _val)	\
+	bus_space_write_2(_sc->bst_tcd, _sc->bsh_tcd, _reg, _val)
+#define	TCD_READ1(_sc, _reg)		\
+	bus_space_read_1(_sc->bst_tcd, _sc->bsh_tcd, _reg)
+#define	TCD_WRITE1(_sc, _reg, _val)	\
+	bus_space_write_1(_sc->bst_tcd, _sc->bsh_tcd, _reg, _val)
+
+#define	EDMA_NUM_DEVICES	2
+#define	EDMA_NUM_CHANNELS	32
+#define	NCHAN_PER_MUX		16
+
+struct tcd_conf {
+	bus_addr_t	saddr;
+	bus_addr_t	daddr;
+	uint32_t	nbytes;
+	uint32_t	nmajor;
+	uint32_t	majorelink;
+	uint32_t	majorelinkch;
+	uint32_t	esg;
+	uint32_t	smod;
+	uint32_t	dmod;
+	uint32_t	soff;
+	uint32_t	doff;
+	uint32_t	ssize;
+	uint32_t	dsize;
+	uint32_t	slast;
+	uint32_t	dlast_sga;
+	uint32_t	channel;
+	uint32_t	(*ih)(void *, int);
+	void		*ih_user;
+};
+
+/*
+ * TCD struct is described at
+ * Vybrid Reference Manual, Rev. 5, 07/2013
+ *
+ * Should be used for Scatter/Gathering feature.
+ */
+
+struct TCD {
+	uint32_t	saddr;
+	uint16_t	attr;
+	uint16_t	soff;
+	uint32_t	nbytes;
+	uint32_t	slast;
+	uint32_t	daddr;
+	uint16_t	citer;
+	uint16_t	doff;
+	uint32_t	dlast_sga;
+	uint16_t	biter;
+	uint16_t	csr;
+} __packed;
+
+struct edma_softc {
+	device_t		dev;
+	struct resource		*res[4];
+	bus_space_tag_t		bst;
+	bus_space_handle_t	bsh;
+	bus_space_tag_t		bst_tcd;
+	bus_space_handle_t	bsh_tcd;
+	void			*tc_ih;
+	void			*err_ih;
+	uint32_t		device_id;
+
+	int	(*channel_configure) (struct edma_softc *, int, int);
+	int	(*channel_free) (struct edma_softc *, int);
+	int	(*dma_request) (struct edma_softc *, int);
+	int	(*dma_setup) (struct edma_softc *, struct tcd_conf *);
+	int	(*dma_stop) (struct edma_softc *, int);
+};


Property changes on: trunk/sys/arm/freescale/vybrid/vf_edma.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/vybrid/vf_ehci.c
===================================================================
--- trunk/sys/arm/freescale/vybrid/vf_ehci.c	                        (rev 0)
+++ trunk/sys/arm/freescale/vybrid/vf_ehci.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,421 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Ruslan Bukin <br at bsdpad.com>
+ * 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.
+ */
+
+/*
+ * Vybrid Family Universal Serial Bus (USB) Controller
+ * Chapter 44-45, Vybrid Reference Manual, Rev. 5, 07/2013
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/freescale/vybrid/vf_ehci.c 278278 2015-02-05 20:03:02Z hselasky $");
+
+#include "opt_bus.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/condvar.h>
+#include <sys/rman.h>
+#include <sys/gpio.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <dev/usb/usb.h>
+#include <dev/usb/usbdi.h>
+#include <dev/usb/usb_busdma.h>
+#include <dev/usb/usb_process.h>
+#include <dev/usb/usb_controller.h>
+#include <dev/usb/usb_bus.h>
+#include <dev/usb/controller/ehci.h>
+#include <dev/usb/controller/ehcireg.h>
+
+#include <dev/fdt/fdt_common.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+
+#include "gpio_if.h"
+#include "opt_platform.h"
+
+#define	ENUTMILEVEL3	(1 << 15)
+#define	ENUTMILEVEL2	(1 << 14)
+
+#define	GPIO_USB_PWR	134
+
+#define	USB_ID		0x000	/* Identification register */
+#define	USB_HWGENERAL	0x004	/* Hardware General */
+#define	USB_HWHOST	0x008	/* Host Hardware Parameters */
+#define	USB_HWDEVICE	0x00C	/* Device Hardware Parameters */
+#define	USB_HWTXBUF	0x010	/* TX Buffer Hardware Parameters */
+#define	USB_HWRXBUF	0x014	/* RX Buffer Hardware Parameters */
+#define	USB_HCSPARAMS	0x104	/* Host Controller Structural Parameters */
+
+#define	USBPHY_PWD		0x00	/* PHY Power-Down Register */
+#define	USBPHY_PWD_SET		0x04	/* PHY Power-Down Register */
+#define	USBPHY_PWD_CLR		0x08	/* PHY Power-Down Register */
+#define	USBPHY_PWD_TOG		0x0C	/* PHY Power-Down Register */
+#define	USBPHY_TX		0x10	/* PHY Transmitter Control Register */
+#define	USBPHY_RX		0x20	/* PHY Receiver Control Register */
+#define	USBPHY_RX_SET		0x24	/* PHY Receiver Control Register */
+#define	USBPHY_RX_CLR		0x28	/* PHY Receiver Control Register */
+#define	USBPHY_RX_TOG		0x2C	/* PHY Receiver Control Register */
+#define	USBPHY_CTRL		0x30	/* PHY General Control Register */
+#define	USBPHY_CTRL_SET		0x34	/* PHY General Control Register */
+#define	USBPHY_CTRL_CLR		0x38	/* PHY General Control Register */
+#define	USBPHY_CTRL_TOG		0x3C	/* PHY General Control Register */
+#define	USBPHY_STATUS		0x40	/* PHY Status Register */
+#define	USBPHY_DEBUG		0x50	/* PHY Debug Register */
+#define	USBPHY_DEBUG_SET	0x54	/* PHY Debug Register */
+#define	USBPHY_DEBUG_CLR	0x58	/* PHY Debug Register */
+#define	USBPHY_DEBUG_TOG	0x5C	/* PHY Debug Register */
+#define	USBPHY_DEBUG0_STATUS	0x60	/* UTMI Debug Status Register 0 */
+#define	USBPHY_DEBUG1		0x70	/* UTMI Debug Status Register 1 */
+#define	USBPHY_DEBUG1_SET	0x74	/* UTMI Debug Status Register 1 */
+#define	USBPHY_DEBUG1_CLR	0x78	/* UTMI Debug Status Register 1 */
+#define	USBPHY_DEBUG1_TOG	0x7C	/* UTMI Debug Status Register 1 */
+#define	USBPHY_VERSION		0x80	/* UTMI RTL Version */
+#define	USBPHY_IP		0x90	/* PHY IP Block Register */
+#define	USBPHY_IP_SET		0x94	/* PHY IP Block Register */
+#define	USBPHY_IP_CLR		0x98	/* PHY IP Block Register */
+#define	USBPHY_IP_TOG		0x9C	/* PHY IP Block Register */
+
+#define	USBPHY_CTRL_SFTRST	(1 << 31)
+#define	USBPHY_CTRL_CLKGATE	(1 << 30)
+#define	USBPHY_DEBUG_CLKGATE	(1 << 30)
+
+#define	PHY_READ4(_sc, _reg)		\
+	bus_space_read_4(_sc->bst_phy, _sc->bsh_phy, _reg)
+#define	PHY_WRITE4(_sc, _reg, _val)	\
+	bus_space_write_4(_sc->bst_phy, _sc->bsh_phy, _reg, _val)
+
+#define	USBC_READ4(_sc, _reg)		\
+	bus_space_read_4(_sc->bst_usbc, _sc->bsh_usbc, _reg)
+#define	USBC_WRITE4(_sc, _reg, _val)	\
+	bus_space_write_4(_sc->bst_usbc, _sc->bsh_usbc, _reg, _val)
+
+/* Forward declarations */
+static int	vybrid_ehci_attach(device_t dev);
+static int	vybrid_ehci_detach(device_t dev);
+static int	vybrid_ehci_probe(device_t dev);
+
+struct vybrid_ehci_softc {
+	ehci_softc_t		base;
+	device_t		dev;
+	struct resource		*res[6];
+	bus_space_tag_t		bst_phy;
+	bus_space_handle_t      bsh_phy;
+	bus_space_tag_t		bst_usbc;
+	bus_space_handle_t      bsh_usbc;
+};
+
+static struct resource_spec vybrid_ehci_spec[] = {
+	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
+	{ SYS_RES_MEMORY,	1,	RF_ACTIVE },
+	{ SYS_RES_MEMORY,	2,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		0,	RF_ACTIVE },
+	{ -1, 0 }
+};
+
+static device_method_t ehci_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe, vybrid_ehci_probe),
+	DEVMETHOD(device_attach, vybrid_ehci_attach),
+	DEVMETHOD(device_detach, vybrid_ehci_detach),
+	DEVMETHOD(device_suspend, bus_generic_suspend),
+	DEVMETHOD(device_resume, bus_generic_resume),
+	DEVMETHOD(device_shutdown, bus_generic_shutdown),
+
+	/* Bus interface */
+	DEVMETHOD(bus_print_child, bus_generic_print_child),
+
+	{ 0, 0 }
+};
+
+/* kobj_class definition */
+static driver_t ehci_driver = {
+	"ehci",
+	ehci_methods,
+	sizeof(ehci_softc_t)
+};
+
+static devclass_t ehci_devclass;
+
+DRIVER_MODULE(ehci, simplebus, ehci_driver, ehci_devclass, 0, 0);
+MODULE_DEPEND(ehci, usb, 1, 1, 1);
+
+/*
+ * Public methods
+ */
+static int
+vybrid_ehci_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (ofw_bus_is_compatible(dev, "fsl,mvf600-usb-ehci") == 0)
+		return (ENXIO);
+
+	device_set_desc(dev, "Vybrid Family integrated USB controller");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+phy_init(struct vybrid_ehci_softc *esc)
+{
+	device_t sc_gpio_dev;
+	int reg;
+
+	/* Reset phy */
+	reg = PHY_READ4(esc, USBPHY_CTRL);
+	reg |= (USBPHY_CTRL_SFTRST);
+	PHY_WRITE4(esc, USBPHY_CTRL, reg);
+
+	/* Minimum reset time */
+	DELAY(10000);
+
+	reg &= ~(USBPHY_CTRL_SFTRST | USBPHY_CTRL_CLKGATE);
+	PHY_WRITE4(esc, USBPHY_CTRL, reg);
+
+	reg = (ENUTMILEVEL2 | ENUTMILEVEL3);
+	PHY_WRITE4(esc, USBPHY_CTRL_SET, reg);
+
+	/* Get the GPIO device, we need this to give power to USB */
+	sc_gpio_dev = devclass_get_device(devclass_find("gpio"), 0);
+	if (sc_gpio_dev == NULL) {
+		device_printf(esc->dev, "Error: failed to get the GPIO dev\n");
+		return (1);
+	}
+
+	/* Give power to USB */
+	GPIO_PIN_SETFLAGS(sc_gpio_dev, GPIO_USB_PWR, GPIO_PIN_OUTPUT);
+	GPIO_PIN_SET(sc_gpio_dev, GPIO_USB_PWR, GPIO_PIN_HIGH);
+
+	/* Power up PHY */
+	PHY_WRITE4(esc, USBPHY_PWD, 0x00);
+
+	/* Ungate clocks */
+	reg = PHY_READ4(esc, USBPHY_DEBUG);
+	reg &= ~(USBPHY_DEBUG_CLKGATE);
+	PHY_WRITE4(esc, USBPHY_DEBUG, reg);
+
+#if 0
+	printf("USBPHY_CTRL == 0x%08x\n",
+	    PHY_READ4(esc, USBPHY_CTRL));
+	printf("USBPHY_IP == 0x%08x\n",
+	    PHY_READ4(esc, USBPHY_IP));
+	printf("USBPHY_STATUS == 0x%08x\n",
+	    PHY_READ4(esc, USBPHY_STATUS));
+	printf("USBPHY_DEBUG == 0x%08x\n",
+	    PHY_READ4(esc, USBPHY_DEBUG));
+	printf("USBPHY_DEBUG0_STATUS == 0x%08x\n",
+	    PHY_READ4(esc, USBPHY_DEBUG0_STATUS));
+	printf("USBPHY_DEBUG1 == 0x%08x\n",
+	    PHY_READ4(esc, USBPHY_DEBUG1));
+#endif
+
+	return (0);
+}
+
+static int
+vybrid_ehci_attach(device_t dev)
+{
+	struct vybrid_ehci_softc *esc;
+	ehci_softc_t *sc;
+	bus_space_handle_t bsh;
+	int err;
+	int reg;
+
+	esc = device_get_softc(dev);
+	esc->dev = dev;
+
+	sc = &esc->base;
+	sc->sc_bus.parent = dev;
+	sc->sc_bus.devices = sc->sc_devices;
+	sc->sc_bus.devices_max = EHCI_MAX_DEVICES;
+	sc->sc_bus.dma_bits = 32;
+
+	if (bus_alloc_resources(dev, vybrid_ehci_spec, esc->res)) {
+		device_printf(dev, "could not allocate resources\n");
+		return (ENXIO);
+	}
+
+	/* EHCI registers */
+	sc->sc_io_tag = rman_get_bustag(esc->res[0]);
+	bsh = rman_get_bushandle(esc->res[0]);
+	sc->sc_io_size = rman_get_size(esc->res[0]);
+
+	esc->bst_usbc = rman_get_bustag(esc->res[1]);
+	esc->bsh_usbc = rman_get_bushandle(esc->res[1]);
+
+	esc->bst_phy = rman_get_bustag(esc->res[2]);
+	esc->bsh_phy = rman_get_bushandle(esc->res[2]);
+
+	/* get all DMA memory */
+	if (usb_bus_mem_alloc_all(&sc->sc_bus, USB_GET_DMA_TAG(dev),
+		&ehci_iterate_hw_softc))
+		return (ENXIO);
+
+#if 0
+	printf("USBx_HCSPARAMS is 0x%08x\n",
+	    bus_space_read_4(sc->sc_io_tag, bsh, USB_HCSPARAMS));
+	printf("USB_ID == 0x%08x\n",
+	    bus_space_read_4(sc->sc_io_tag, bsh, USB_ID));
+	printf("USB_HWGENERAL == 0x%08x\n",
+	    bus_space_read_4(sc->sc_io_tag, bsh, USB_HWGENERAL));
+	printf("USB_HWHOST == 0x%08x\n",
+	    bus_space_read_4(sc->sc_io_tag, bsh, USB_HWHOST));
+	printf("USB_HWDEVICE == 0x%08x\n",
+	    bus_space_read_4(sc->sc_io_tag, bsh, USB_HWDEVICE));
+	printf("USB_HWTXBUF == 0x%08x\n",
+	    bus_space_read_4(sc->sc_io_tag, bsh, USB_HWTXBUF));
+	printf("USB_HWRXBUF == 0x%08x\n",
+	    bus_space_read_4(sc->sc_io_tag, bsh, USB_HWRXBUF));
+#endif
+
+	if (phy_init(esc)) {
+		device_printf(dev, "Could not setup PHY\n");
+		return (1);
+	}
+
+	/*
+	 * Set handle to USB related registers subregion used by
+	 * generic EHCI driver.
+	 */
+	err = bus_space_subregion(sc->sc_io_tag, bsh, 0x100,
+	    sc->sc_io_size, &sc->sc_io_hdl);
+	if (err != 0)
+		return (ENXIO);
+
+	/* Setup interrupt handler */
+	err = bus_setup_intr(dev, esc->res[3], INTR_TYPE_BIO | INTR_MPSAFE,
+	    NULL, (driver_intr_t *)ehci_interrupt, sc,
+	    &sc->sc_intr_hdl);
+	if (err) {
+		device_printf(dev, "Could not setup irq, "
+		    "%d\n", err);
+		return (1);
+	}
+
+	/* Add USB device */
+	sc->sc_bus.bdev = device_add_child(dev, "usbus", -1);
+	if (!sc->sc_bus.bdev) {
+		device_printf(dev, "Could not add USB device\n");
+		err = bus_teardown_intr(dev, esc->res[5],
+		    sc->sc_intr_hdl);
+		if (err)
+			device_printf(dev, "Could not tear down irq,"
+			    " %d\n", err);
+		return (1);
+	}
+	device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
+
+	strlcpy(sc->sc_vendor, "Freescale", sizeof(sc->sc_vendor));
+
+	/* Set host mode */
+	reg = bus_space_read_4(sc->sc_io_tag, sc->sc_io_hdl, 0xA8);
+	reg |= 0x3;
+	bus_space_write_4(sc->sc_io_tag, sc->sc_io_hdl, 0xA8, reg);
+
+	/* Set flags */
+	sc->sc_flags |= EHCI_SCFLG_SETMODE | EHCI_SCFLG_NORESTERM;
+
+	err = ehci_init(sc);
+	if (!err) {
+		sc->sc_flags |= EHCI_SCFLG_DONEINIT;
+		err = device_probe_and_attach(sc->sc_bus.bdev);
+	} else {
+		device_printf(dev, "USB init failed err=%d\n", err);
+
+		device_delete_child(dev, sc->sc_bus.bdev);
+		sc->sc_bus.bdev = NULL;
+
+		err = bus_teardown_intr(dev, esc->res[5],
+		    sc->sc_intr_hdl);
+		if (err)
+			device_printf(dev, "Could not tear down irq,"
+			    " %d\n", err);
+		return (1);
+	}
+	return (0);
+}
+
+static int
+vybrid_ehci_detach(device_t dev)
+{
+	struct vybrid_ehci_softc *esc;
+	ehci_softc_t *sc;
+	int err;
+
+	esc = device_get_softc(dev);
+	sc = &esc->base;
+
+	if (sc->sc_flags & EHCI_SCFLG_DONEINIT)
+		return (0);
+
+	/*
+	 * only call ehci_detach() after ehci_init()
+	 */
+	if (sc->sc_flags & EHCI_SCFLG_DONEINIT) {
+		ehci_detach(sc);
+		sc->sc_flags &= ~EHCI_SCFLG_DONEINIT;
+	}
+
+	/*
+	 * Disable interrupts that might have been switched on in
+	 * ehci_init.
+	 */
+	if (sc->sc_io_tag && sc->sc_io_hdl)
+		bus_space_write_4(sc->sc_io_tag, sc->sc_io_hdl,
+		    EHCI_USBINTR, 0);
+
+	if (esc->res[5] && sc->sc_intr_hdl) {
+		err = bus_teardown_intr(dev, esc->res[5],
+		    sc->sc_intr_hdl);
+		if (err) {
+			device_printf(dev, "Could not tear down irq,"
+			    " %d\n", err);
+			return (err);
+		}
+		sc->sc_intr_hdl = NULL;
+	}
+
+	if (sc->sc_bus.bdev) {
+		device_delete_child(dev, sc->sc_bus.bdev);
+		sc->sc_bus.bdev = NULL;
+	}
+
+	/* During module unload there are lots of children leftover */
+	device_delete_children(dev);
+
+	bus_release_resources(dev, vybrid_ehci_spec, esc->res);
+
+	return (0);
+}


Property changes on: trunk/sys/arm/freescale/vybrid/vf_ehci.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/vybrid/vf_gpio.c
===================================================================
--- trunk/sys/arm/freescale/vybrid/vf_gpio.c	                        (rev 0)
+++ trunk/sys/arm/freescale/vybrid/vf_gpio.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,370 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Ruslan Bukin <br at bsdpad.com>
+ * 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.
+ */
+
+/*
+ * Vybrid Family General-Purpose Input/Output (GPIO)
+ * Chapter 7, Vybrid Reference Manual, Rev. 5, 07/2013
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/freescale/vybrid/vf_gpio.c 278786 2015-02-14 21:16:19Z loos $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/timeet.h>
+#include <sys/timetc.h>
+#include <sys/watchdog.h>
+#include <sys/mutex.h>
+#include <sys/gpio.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#include "gpio_if.h"
+
+#include <arm/freescale/vybrid/vf_common.h>
+#include <arm/freescale/vybrid/vf_port.h>
+
+#define	GPIO_PDOR(n)	(0x00 + 0x40 * (n >> 5))
+#define	GPIO_PSOR(n)	(0x04 + 0x40 * (n >> 5))
+#define	GPIO_PCOR(n)	(0x08 + 0x40 * (n >> 5))
+#define	GPIO_PTOR(n)	(0x0C + 0x40 * (n >> 5))
+#define	GPIO_PDIR(n)	(0x10 + 0x40 * (n >> 5))
+
+#define	GPIO_LOCK(_sc)		mtx_lock(&(_sc)->sc_mtx)
+#define	GPIO_UNLOCK(_sc)	mtx_unlock(&(_sc)->sc_mtx)
+
+#define	DEFAULT_CAPS	(GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)
+
+/*
+ * GPIO interface
+ */
+static int vf_gpio_pin_max(device_t, int *);
+static int vf_gpio_pin_getcaps(device_t, uint32_t, uint32_t *);
+static int vf_gpio_pin_getname(device_t, uint32_t, char *);
+static int vf_gpio_pin_getflags(device_t, uint32_t, uint32_t *);
+static int vf_gpio_pin_setflags(device_t, uint32_t, uint32_t);
+static int vf_gpio_pin_set(device_t, uint32_t, unsigned int);
+static int vf_gpio_pin_get(device_t, uint32_t, unsigned int *);
+static int vf_gpio_pin_toggle(device_t, uint32_t pin);
+
+struct vf_gpio_softc {
+	struct resource		*res[1];
+	bus_space_tag_t		bst;
+	bus_space_handle_t	bsh;
+
+	struct mtx		sc_mtx;
+	int			gpio_npins;
+	struct gpio_pin		gpio_pins[NGPIO];
+};
+
+struct vf_gpio_softc *gpio_sc;
+
+static struct resource_spec vf_gpio_spec[] = {
+	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
+	{ -1, 0 }
+};
+
+static int
+vf_gpio_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "fsl,mvf600-gpio"))
+		return (ENXIO);
+
+	device_set_desc(dev, "Vybrid Family GPIO Unit");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+vf_gpio_attach(device_t dev)
+{
+	struct vf_gpio_softc *sc;
+	int i;
+
+	sc = device_get_softc(dev);
+	mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL, MTX_DEF);
+
+	if (bus_alloc_resources(dev, vf_gpio_spec, sc->res)) {
+		device_printf(dev, "could not allocate resources\n");
+		return (ENXIO);
+	}
+
+	/* Memory interface */
+	sc->bst = rman_get_bustag(sc->res[0]);
+	sc->bsh = rman_get_bushandle(sc->res[0]);
+
+	gpio_sc = sc;
+
+	sc->gpio_npins = NGPIO;
+
+	for (i = 0; i < sc->gpio_npins; i++) {
+		sc->gpio_pins[i].gp_pin = i;
+		sc->gpio_pins[i].gp_caps = DEFAULT_CAPS;
+		sc->gpio_pins[i].gp_flags =
+		    (READ4(sc, GPIO_PDOR(i)) & (1 << (i % 32))) ?
+		    GPIO_PIN_OUTPUT: GPIO_PIN_INPUT;
+		snprintf(sc->gpio_pins[i].gp_name, GPIOMAXNAME,
+		    "vf_gpio%d.%d", device_get_unit(dev), i);
+	}
+
+	device_add_child(dev, "gpioc", -1);
+	device_add_child(dev, "gpiobus", -1);
+
+	return (bus_generic_attach(dev));
+}
+
+static int
+vf_gpio_pin_max(device_t dev, int *maxpin)
+{
+
+	*maxpin = NGPIO - 1;
+	return (0);
+}
+
+static int
+vf_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
+{
+	struct vf_gpio_softc *sc;
+	int i;
+
+	sc = device_get_softc(dev);
+	for (i = 0; i < sc->gpio_npins; i++) {
+		if (sc->gpio_pins[i].gp_pin == pin)
+			break;
+	}
+
+	if (i >= sc->gpio_npins)
+		return (EINVAL);
+
+	GPIO_LOCK(sc);
+	memcpy(name, sc->gpio_pins[i].gp_name, GPIOMAXNAME);
+	GPIO_UNLOCK(sc);
+
+	return (0);
+}
+
+static int
+vf_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
+{
+	struct vf_gpio_softc *sc;
+	int i;
+
+	sc = device_get_softc(dev);
+	for (i = 0; i < sc->gpio_npins; i++) {
+		if (sc->gpio_pins[i].gp_pin == pin)
+			break;
+	}
+
+	if (i >= sc->gpio_npins)
+		return (EINVAL);
+
+	GPIO_LOCK(sc);
+	*caps = sc->gpio_pins[i].gp_caps;
+	GPIO_UNLOCK(sc);
+
+	return (0);
+}
+
+static int
+vf_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
+{
+	struct vf_gpio_softc *sc;
+	int i;
+
+	sc = device_get_softc(dev);
+	for (i = 0; i < sc->gpio_npins; i++) {
+		if (sc->gpio_pins[i].gp_pin == pin)
+			break;
+	}
+
+	if (i >= sc->gpio_npins)
+		return (EINVAL);
+
+	GPIO_LOCK(sc);
+	*flags = sc->gpio_pins[i].gp_flags;
+	GPIO_UNLOCK(sc);
+
+	return (0);
+}
+
+static int
+vf_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val)
+{
+	struct vf_gpio_softc *sc;
+	int i;
+
+	sc = device_get_softc(dev);
+	for (i = 0; i < sc->gpio_npins; i++) {
+		if (sc->gpio_pins[i].gp_pin == pin)
+			break;
+	}
+
+	if (i >= sc->gpio_npins)
+		return (EINVAL);
+
+	GPIO_LOCK(sc);
+	*val = (READ4(sc, GPIO_PDOR(i)) & (1 << (i % 32)));
+	GPIO_UNLOCK(sc);
+
+	return (0);
+}
+
+static int
+vf_gpio_pin_toggle(device_t dev, uint32_t pin)
+{
+	struct vf_gpio_softc *sc;
+	int i;
+
+	sc = device_get_softc(dev);
+	for (i = 0; i < sc->gpio_npins; i++) {
+		if (sc->gpio_pins[i].gp_pin == pin)
+			break;
+	}
+
+	if (i >= sc->gpio_npins)
+		return (EINVAL);
+
+	GPIO_LOCK(sc);
+	WRITE4(sc, GPIO_PTOR(i), (1 << (i % 32)));
+	GPIO_UNLOCK(sc);
+
+	return (0);
+}
+
+
+static void
+vf_gpio_pin_configure(struct vf_gpio_softc *sc, struct gpio_pin *pin,
+    unsigned int flags)
+{
+
+	GPIO_LOCK(sc);
+
+	/*
+	 * Manage input/output
+	 */
+	if (flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) {
+		pin->gp_flags &= ~(GPIO_PIN_INPUT|GPIO_PIN_OUTPUT);
+		if (flags & GPIO_PIN_OUTPUT) {
+			pin->gp_flags |= GPIO_PIN_OUTPUT;
+
+		} else {
+			pin->gp_flags |= GPIO_PIN_INPUT;
+			WRITE4(sc, GPIO_PCOR(pin->gp_pin),
+			    (1 << (pin->gp_pin % 32)));
+		}
+	}
+
+	GPIO_UNLOCK(sc);
+}
+
+
+static int
+vf_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
+{
+	struct vf_gpio_softc *sc;
+	int i;
+
+	sc = device_get_softc(dev);
+	for (i = 0; i < sc->gpio_npins; i++) {
+		if (sc->gpio_pins[i].gp_pin == pin)
+			break;
+	}
+
+	if (i >= sc->gpio_npins)
+		return (EINVAL);
+
+	vf_gpio_pin_configure(sc, &sc->gpio_pins[i], flags);
+
+	return (0);
+}
+
+static int
+vf_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value)
+{
+	struct vf_gpio_softc *sc;
+	int i;
+
+	sc = device_get_softc(dev);
+	for (i = 0; i < sc->gpio_npins; i++) {
+		if (sc->gpio_pins[i].gp_pin == pin)
+			break;
+	}
+
+	if (i >= sc->gpio_npins)
+		return (EINVAL);
+
+	GPIO_LOCK(sc);
+	if (value)
+		WRITE4(sc, GPIO_PSOR(i), (1 << (i % 32)));
+	else
+		WRITE4(sc, GPIO_PCOR(i), (1 << (i % 32)));
+	GPIO_UNLOCK(sc);
+
+	return (0);
+}
+
+static device_method_t vf_gpio_methods[] = {
+	DEVMETHOD(device_probe,		vf_gpio_probe),
+	DEVMETHOD(device_attach,	vf_gpio_attach),
+
+	/* GPIO protocol */
+	DEVMETHOD(gpio_pin_max,		vf_gpio_pin_max),
+	DEVMETHOD(gpio_pin_getname,	vf_gpio_pin_getname),
+	DEVMETHOD(gpio_pin_getcaps,	vf_gpio_pin_getcaps),
+	DEVMETHOD(gpio_pin_getflags,	vf_gpio_pin_getflags),
+	DEVMETHOD(gpio_pin_get,		vf_gpio_pin_get),
+	DEVMETHOD(gpio_pin_toggle,	vf_gpio_pin_toggle),
+	DEVMETHOD(gpio_pin_setflags,	vf_gpio_pin_setflags),
+	DEVMETHOD(gpio_pin_set,		vf_gpio_pin_set),
+	{ 0, 0 }
+};
+
+static driver_t vf_gpio_driver = {
+	"gpio",
+	vf_gpio_methods,
+	sizeof(struct vf_gpio_softc),
+};
+
+static devclass_t vf_gpio_devclass;
+
+DRIVER_MODULE(vf_gpio, simplebus, vf_gpio_driver, vf_gpio_devclass, 0, 0);


Property changes on: trunk/sys/arm/freescale/vybrid/vf_gpio.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/vybrid/vf_i2c.c
===================================================================
--- trunk/sys/arm/freescale/vybrid/vf_i2c.c	                        (rev 0)
+++ trunk/sys/arm/freescale/vybrid/vf_i2c.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,472 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014 Ruslan Bukin <br at bsdpad.com>
+ * 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.
+ */
+
+/*
+ * Vybrid Family Inter-Integrated Circuit (I2C)
+ * Chapter 48, Vybrid Reference Manual, Rev. 5, 07/2013
+ */
+
+/*
+ * This driver is based on the I2C driver for i.MX
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/freescale/vybrid/vf_i2c.c 289666 2015-10-20 21:20:34Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/timeet.h>
+#include <sys/timetc.h>
+
+#include <dev/iicbus/iiconf.h>
+#include <dev/iicbus/iicbus.h>
+
+#include "iicbus_if.h"
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#include <arm/freescale/vybrid/vf_common.h>
+
+#define	I2C_IBAD	0x0	/* I2C Bus Address Register */
+#define	I2C_IBFD	0x1	/* I2C Bus Frequency Divider Register */
+#define	I2C_IBCR	0x2	/* I2C Bus Control Register */
+#define	 IBCR_MDIS		(1 << 7) /* Module disable. */
+#define	 IBCR_IBIE		(1 << 6) /* I-Bus Interrupt Enable. */
+#define	 IBCR_MSSL		(1 << 5) /* Master/Slave mode select. */
+#define	 IBCR_TXRX		(1 << 4) /* Transmit/Receive mode select. */
+#define	 IBCR_NOACK		(1 << 3) /* Data Acknowledge disable. */
+#define	 IBCR_RSTA		(1 << 2) /* Repeat Start. */
+#define	 IBCR_DMAEN		(1 << 1) /* DMA Enable. */
+#define	I2C_IBSR	0x3	/* I2C Bus Status Register */
+#define	 IBSR_TCF		(1 << 7) /* Transfer complete. */
+#define	 IBSR_IAAS		(1 << 6) /* Addressed as a slave. */
+#define	 IBSR_IBB		(1 << 5) /* Bus busy. */
+#define	 IBSR_IBAL		(1 << 4) /* Arbitration Lost. */
+#define	 IBSR_SRW		(1 << 2) /* Slave Read/Write. */
+#define	 IBSR_IBIF		(1 << 1) /* I-Bus Interrupt Flag. */
+#define	 IBSR_RXAK		(1 << 0) /* Received Acknowledge. */
+#define	I2C_IBDR	0x4	/* I2C Bus Data I/O Register */
+#define	I2C_IBIC	0x5	/* I2C Bus Interrupt Config Register */
+#define	 IBIC_BIIE		(1 << 7) /* Bus Idle Interrupt Enable bit. */
+#define	I2C_IBDBG	0x6	/* I2C Bus Debug Register */
+
+#ifdef DEBUG
+#define vf_i2c_dbg(_sc, fmt, args...) \
+	device_printf((_sc)->dev, fmt, ##args)
+#else
+#define vf_i2c_dbg(_sc, fmt, args...)
+#endif
+
+static int i2c_repeated_start(device_t, u_char, int);
+static int i2c_start(device_t, u_char, int);
+static int i2c_stop(device_t);
+static int i2c_reset(device_t, u_char, u_char, u_char *);
+static int i2c_read(device_t, char *, int, int *, int, int);
+static int i2c_write(device_t, const char *, int, int *, int);
+
+struct i2c_softc {
+	struct resource		*res[2];
+	bus_space_tag_t		bst;
+	bus_space_handle_t	bsh;
+	device_t		dev;
+	device_t		iicbus;
+	struct mtx		mutex;
+};
+
+static struct resource_spec i2c_spec[] = {
+	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		0,	RF_ACTIVE },
+	{ -1, 0 }
+};
+
+static int
+i2c_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "fsl,mvf600-i2c"))
+		return (ENXIO);
+
+	device_set_desc(dev, "Vybrid Family Inter-Integrated Circuit (I2C)");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+i2c_attach(device_t dev)
+{
+	struct i2c_softc *sc;
+
+	sc = device_get_softc(dev);
+	sc->dev = dev;
+
+	mtx_init(&sc->mutex, device_get_nameunit(dev), "I2C", MTX_DEF);
+
+	if (bus_alloc_resources(dev, i2c_spec, sc->res)) {
+		device_printf(dev, "could not allocate resources\n");
+		return (ENXIO);
+	}
+
+	/* Memory interface */
+	sc->bst = rman_get_bustag(sc->res[0]);
+	sc->bsh = rman_get_bushandle(sc->res[0]);
+
+	WRITE1(sc, I2C_IBIC, IBIC_BIIE);
+
+	sc->iicbus = device_add_child(dev, "iicbus", -1);
+	if (sc->iicbus == NULL) {
+		device_printf(dev, "could not add iicbus child");
+		mtx_destroy(&sc->mutex);
+		return (ENXIO);
+	}
+
+	bus_generic_attach(dev);
+
+	return (0);
+}
+
+/* Wait for transfer interrupt flag */
+static int
+wait_for_iif(struct i2c_softc *sc)
+{
+	int retry;
+
+	retry = 1000;
+	while (retry --) {
+		if (READ1(sc, I2C_IBSR) & IBSR_IBIF) {
+			WRITE1(sc, I2C_IBSR, IBSR_IBIF);
+			return (IIC_NOERR);
+		}
+		DELAY(10);
+	}
+
+	return (IIC_ETIMEOUT);
+}
+
+/* Wait for free bus */
+static int
+wait_for_nibb(struct i2c_softc *sc)
+{
+	int retry;
+
+	retry = 1000;
+	while (retry --) {
+		if ((READ1(sc, I2C_IBSR) & IBSR_IBB) == 0)
+			return (IIC_NOERR);
+		DELAY(10);
+	}
+
+	return (IIC_ETIMEOUT);
+}
+
+/* Wait for transfer complete+interrupt flag */
+static int
+wait_for_icf(struct i2c_softc *sc)
+{
+	int retry;
+
+	retry = 1000;
+	while (retry --) {
+		if (READ1(sc, I2C_IBSR) & IBSR_TCF) {
+			if (READ1(sc, I2C_IBSR) & IBSR_IBIF) {
+				WRITE1(sc, I2C_IBSR, IBSR_IBIF);
+				return (IIC_NOERR);
+			}
+		}
+		DELAY(10);
+	}
+
+	return (IIC_ETIMEOUT);
+}
+
+static int
+i2c_repeated_start(device_t dev, u_char slave, int timeout)
+{
+	struct i2c_softc *sc;
+	int error;
+	int reg;
+
+	sc = device_get_softc(dev);
+
+	vf_i2c_dbg(sc, "i2c repeated start\n");
+
+	mtx_lock(&sc->mutex);
+
+	WRITE1(sc, I2C_IBAD, slave);
+
+	if ((READ1(sc, I2C_IBSR) & IBSR_IBB) == 0) {
+		mtx_unlock(&sc->mutex);
+		return (IIC_EBUSERR);
+	}
+
+	/* Set repeated start condition */
+	DELAY(10);
+
+	reg = READ1(sc, I2C_IBCR);
+	reg |= (IBCR_RSTA | IBCR_IBIE);
+	WRITE1(sc, I2C_IBCR, reg);
+
+	DELAY(10);
+
+	/* Write target address - LSB is R/W bit */
+	WRITE1(sc, I2C_IBDR, slave);
+
+	error = wait_for_iif(sc);
+
+	mtx_unlock(&sc->mutex);
+
+	if (error)
+		return (error);
+
+	return (IIC_NOERR);
+}
+
+static int
+i2c_start(device_t dev, u_char slave, int timeout)
+{
+	struct i2c_softc *sc;
+	int error;
+	int reg;
+
+	sc = device_get_softc(dev);
+
+	vf_i2c_dbg(sc, "i2c start\n");
+
+	mtx_lock(&sc->mutex);
+
+	WRITE1(sc, I2C_IBAD, slave);
+
+	if (READ1(sc, I2C_IBSR) & IBSR_IBB) {
+		mtx_unlock(&sc->mutex);
+		vf_i2c_dbg(sc, "cant i2c start: IIC_EBUSBSY\n");
+		return (IIC_EBUSERR);
+	}
+
+	/* Set start condition */
+	reg = (IBCR_MSSL | IBCR_NOACK | IBCR_IBIE);
+	WRITE1(sc, I2C_IBCR, reg);
+
+	DELAY(100);
+
+	reg |= (IBCR_TXRX);
+	WRITE1(sc, I2C_IBCR, reg);
+
+	/* Write target address - LSB is R/W bit */
+	WRITE1(sc, I2C_IBDR, slave);
+
+	error = wait_for_iif(sc);
+
+	mtx_unlock(&sc->mutex);
+	if (error) {
+		vf_i2c_dbg(sc, "cant i2c start: iif error\n");
+		return (error);
+	}
+
+	return (IIC_NOERR);
+}
+
+static int
+i2c_stop(device_t dev)
+{
+	struct i2c_softc *sc;
+
+	sc = device_get_softc(dev);
+
+	vf_i2c_dbg(sc, "i2c stop\n");
+
+	mtx_lock(&sc->mutex);
+
+	WRITE1(sc, I2C_IBCR, IBCR_NOACK | IBCR_IBIE);
+
+	DELAY(100);
+
+	/* Reset controller if bus still busy after STOP */
+	if (wait_for_nibb(sc) == IIC_ETIMEOUT) {
+		WRITE1(sc, I2C_IBCR, IBCR_MDIS);
+		DELAY(1000);
+		WRITE1(sc, I2C_IBCR, IBCR_NOACK);
+	}
+	mtx_unlock(&sc->mutex);
+
+	return (IIC_NOERR);
+}
+
+static int
+i2c_reset(device_t dev, u_char speed, u_char addr, u_char *oldadr)
+{
+	struct i2c_softc *sc;
+
+	sc = device_get_softc(dev);
+
+	vf_i2c_dbg(sc, "i2c reset\n");
+
+	switch (speed) {
+	case IIC_FAST:
+	case IIC_SLOW:
+	case IIC_UNKNOWN:
+	case IIC_FASTEST:
+	default:
+		break;
+	}
+
+	mtx_lock(&sc->mutex);
+	WRITE1(sc, I2C_IBCR, IBCR_MDIS);
+
+	DELAY(1000);
+
+	WRITE1(sc, I2C_IBFD, 20);
+	WRITE1(sc, I2C_IBCR, 0x0); /* Enable i2c */
+
+	DELAY(1000);
+
+	mtx_unlock(&sc->mutex);
+
+	return (IIC_NOERR);
+}
+
+static int
+i2c_read(device_t dev, char *buf, int len, int *read, int last, int delay)
+{
+	struct i2c_softc *sc;
+	int error;
+
+	sc = device_get_softc(dev);
+
+	vf_i2c_dbg(sc, "i2c read\n");
+
+	*read = 0;
+
+	mtx_lock(&sc->mutex);
+
+	if (len) {
+		if (len == 1)
+			WRITE1(sc, I2C_IBCR, IBCR_IBIE | IBCR_MSSL |	\
+			    IBCR_NOACK);
+		else
+			WRITE1(sc, I2C_IBCR, IBCR_IBIE | IBCR_MSSL);
+
+		/* dummy read */
+		READ1(sc, I2C_IBDR);
+		DELAY(1000);
+	}
+
+	while (*read < len) {
+		error = wait_for_icf(sc);
+		if (error) {
+			mtx_unlock(&sc->mutex);
+			return (error);
+		}
+
+		if ((*read == len - 2) && last) {
+			/* NO ACK on last byte */
+			WRITE1(sc, I2C_IBCR, IBCR_IBIE | IBCR_MSSL |	\
+			    IBCR_NOACK);
+		}
+
+		if ((*read == len - 1) && last) {
+			/* Transfer done, remove master bit */
+			WRITE1(sc, I2C_IBCR, IBCR_IBIE | IBCR_NOACK);
+		}
+
+		*buf++ = READ1(sc, I2C_IBDR);
+		(*read)++;
+	}
+	mtx_unlock(&sc->mutex);
+
+	return (IIC_NOERR);
+}
+
+static int
+i2c_write(device_t dev, const char *buf, int len, int *sent, int timeout)
+{
+	struct i2c_softc *sc;
+	int error;
+
+	sc = device_get_softc(dev);
+
+	vf_i2c_dbg(sc, "i2c write\n");
+
+	*sent = 0;
+
+	mtx_lock(&sc->mutex);
+	while (*sent < len) {
+
+		WRITE1(sc, I2C_IBDR, *buf++);
+
+		error = wait_for_iif(sc);
+		if (error) {
+			mtx_unlock(&sc->mutex);
+			return (error);
+		}
+
+		(*sent)++;
+	}
+	mtx_unlock(&sc->mutex);
+
+	return (IIC_NOERR);
+}
+
+static device_method_t i2c_methods[] = {
+	DEVMETHOD(device_probe,		i2c_probe),
+	DEVMETHOD(device_attach,	i2c_attach),
+
+	DEVMETHOD(iicbus_callback,		iicbus_null_callback),
+	DEVMETHOD(iicbus_repeated_start,	i2c_repeated_start),
+	DEVMETHOD(iicbus_start,			i2c_start),
+	DEVMETHOD(iicbus_stop,			i2c_stop),
+	DEVMETHOD(iicbus_reset,			i2c_reset),
+	DEVMETHOD(iicbus_read,			i2c_read),
+	DEVMETHOD(iicbus_write,			i2c_write),
+	DEVMETHOD(iicbus_transfer,		iicbus_transfer_gen),
+
+	{ 0, 0 }
+};
+
+static driver_t i2c_driver = {
+	"i2c",
+	i2c_methods,
+	sizeof(struct i2c_softc),
+};
+
+static devclass_t i2c_devclass;
+
+DRIVER_MODULE(i2c, simplebus, i2c_driver, i2c_devclass, 0, 0);
+DRIVER_MODULE(iicbus, i2c, iicbus_driver, iicbus_devclass, 0, 0);


Property changes on: trunk/sys/arm/freescale/vybrid/vf_i2c.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/vybrid/vf_iomuxc.c
===================================================================
--- trunk/sys/arm/freescale/vybrid/vf_iomuxc.c	                        (rev 0)
+++ trunk/sys/arm/freescale/vybrid/vf_iomuxc.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,213 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013-2014 Ruslan Bukin <br at bsdpad.com>
+ * 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.
+ */
+
+/*
+ * Vybrid Family Input/Output Multiplexer Controller (IOMUXC)
+ * Chapter 5, Vybrid Reference Manual, Rev. 5, 07/2013
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/freescale/vybrid/vf_iomuxc.c 266203 2014-05-16 00:14:50Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/timeet.h>
+#include <sys/timetc.h>
+#include <sys/watchdog.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#include <arm/freescale/vybrid/vf_iomuxc.h>
+#include <arm/freescale/vybrid/vf_common.h>
+
+#define	MUX_MODE_MASK		7
+#define	MUX_MODE_SHIFT		20
+#define	MUX_MODE_GPIO		0
+#define	MUX_MODE_VBUS_EN_OTG	2
+
+#define	IBE		(1 << 0)	/* Input Buffer Enable Field */
+#define	OBE		(1 << 1)	/* Output Buffer Enable Field. */
+#define	PUE		(1 << 2)	/* Pull / Keep Select Field. */
+#define	PKE		(1 << 3)	/* Pull / Keep Enable Field. */
+#define	HYS		(1 << 9)	/* Hysteresis Enable Field */
+#define	ODE		(1 << 10)	/* Open Drain Enable Field. */
+#define	SRE		(1 << 11)	/* Slew Rate Field. */
+
+#define	SPEED_SHIFT		12
+#define	SPEED_MASK		0x3
+#define	SPEED_LOW		0	/* 50 MHz */
+#define	SPEED_MEDIUM		0x1	/* 100 MHz */
+#define	SPEED_HIGH		0x3	/* 200 MHz */
+
+#define	PUS_SHIFT		4	/* Pull Up / Down Config Field Shift */
+#define	PUS_MASK		0x3
+#define	PUS_100_KOHM_PULL_DOWN	0
+#define	PUS_47_KOHM_PULL_UP	0x1
+#define	PUS_100_KOHM_PULL_UP	0x2
+#define	PUS_22_KOHM_PULL_UP	0x3
+
+#define	DSE_SHIFT		6	/* Drive Strength Field Shift */
+#define	DSE_MASK		0x7
+#define	DSE_DISABLED		0	/* Output driver disabled */
+#define	DSE_150_OHM		0x1
+#define	DSE_75_OHM		0x2
+#define	DSE_50_OHM		0x3
+#define	DSE_37_OHM		0x4
+#define	DSE_30_OHM		0x5
+#define	DSE_25_OHM		0x6
+#define	DSE_20_OHM		0x7
+
+#define	MAX_MUX_LEN		1024
+
+struct iomuxc_softc {
+	struct resource		*tmr_res[1];
+	bus_space_tag_t		bst;
+	bus_space_handle_t	bsh;
+	device_t		dev;
+};
+
+static struct resource_spec iomuxc_spec[] = {
+	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
+	{ -1, 0 }
+};
+
+static int
+iomuxc_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "fsl,mvf600-iomuxc"))
+		return (ENXIO);
+
+	device_set_desc(dev, "Vybrid Family IOMUXC Unit");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+pinmux_set(struct iomuxc_softc *sc)
+{
+	phandle_t child, parent, root;
+	pcell_t iomux_config[MAX_MUX_LEN];
+	int len;
+	int values;
+	int pin;
+	int pin_cfg;
+	int i;
+
+	root = OF_finddevice("/");
+	len = 0;
+	parent = root;
+
+	/* Find 'iomux_config' prop in the nodes */
+	for (child = OF_child(parent); child != 0; child = OF_peer(child)) {
+
+		/* Find a 'leaf'. Start the search from this node. */
+		while (OF_child(child)) {
+			parent = child;
+			child = OF_child(child);
+		}
+
+		if (!fdt_is_enabled(child))
+			continue;
+
+		if ((len = OF_getproplen(child, "iomux_config")) > 0) {
+			OF_getprop(child, "iomux_config", &iomux_config, len);
+
+			values = len / (sizeof(uint32_t));
+			for (i = 0; i < values; i += 2) {
+				pin = fdt32_to_cpu(iomux_config[i]);
+				pin_cfg = fdt32_to_cpu(iomux_config[i+1]);
+#if 0
+				device_printf(sc->dev, "Set pin %d to 0x%08x\n",
+				    pin, pin_cfg);
+#endif
+				WRITE4(sc, IOMUXC(pin), pin_cfg);
+			}
+		}
+
+		if (OF_peer(child) == 0) {
+			/* No more siblings. */
+			child = parent;
+			parent = OF_parent(child);
+		}
+	}
+
+	return (0);
+}
+
+static int
+iomuxc_attach(device_t dev)
+{
+	struct iomuxc_softc *sc;
+
+	sc = device_get_softc(dev);
+	sc->dev = dev;
+
+	if (bus_alloc_resources(dev, iomuxc_spec, sc->tmr_res)) {
+		device_printf(dev, "could not allocate resources\n");
+		return (ENXIO);
+	}
+
+	/* Memory interface */
+	sc->bst = rman_get_bustag(sc->tmr_res[0]);
+	sc->bsh = rman_get_bushandle(sc->tmr_res[0]);
+
+	pinmux_set(sc);
+
+	return (0);
+}
+
+static device_method_t iomuxc_methods[] = {
+	DEVMETHOD(device_probe,		iomuxc_probe),
+	DEVMETHOD(device_attach,	iomuxc_attach),
+	{ 0, 0 }
+};
+
+static driver_t iomuxc_driver = {
+	"iomuxc",
+	iomuxc_methods,
+	sizeof(struct iomuxc_softc),
+};
+
+static devclass_t iomuxc_devclass;
+
+DRIVER_MODULE(iomuxc, simplebus, iomuxc_driver, iomuxc_devclass, 0, 0);


Property changes on: trunk/sys/arm/freescale/vybrid/vf_iomuxc.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/vybrid/vf_iomuxc.h
===================================================================
--- trunk/sys/arm/freescale/vybrid/vf_iomuxc.h	                        (rev 0)
+++ trunk/sys/arm/freescale/vybrid/vf_iomuxc.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,166 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Ruslan Bukin <br at bsdpad.com>
+ * 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: stable/10/sys/arm/freescale/vybrid/vf_iomuxc.h 258057 2013-11-12 18:02:56Z br $
+ */
+
+#define	IOMUXC(n)	(n * 0x04)
+#define	IOMUXCN		135
+#define	IOMUXC_PTA6	0x000	/* Software MUX Pad Control Register 0 */
+#define	IOMUXC_PTA8	0x004	/* Software MUX Pad Control Register 1 */
+#define	IOMUXC_PTA9	0x008	/* Software MUX Pad Control Register 2 */
+#define	IOMUXC_PTA10	0x00C	/* Software MUX Pad Control Register 3 */
+#define	IOMUXC_PTA11	0x010	/* Software MUX Pad Control Register 4 */
+#define	IOMUXC_PTA12	0x014	/* Software MUX Pad Control Register 5 */
+#define	IOMUXC_PTA16	0x018	/* Software MUX Pad Control Register 6 */
+#define	IOMUXC_PTA17	0x01C	/* Software MUX Pad Control Register 7 */
+#define	IOMUXC_PTA18	0x020	/* Software MUX Pad Control Register 8 */
+#define	IOMUXC_PTA19	0x024	/* Software MUX Pad Control Register 9 */
+#define	IOMUXC_PTA20	0x028	/* Software MUX Pad Control Register 10 */
+#define	IOMUXC_PTA21	0x02C	/* Software MUX Pad Control Register 11 */
+#define	IOMUXC_PTA22	0x030	/* Software MUX Pad Control Register 12 */
+#define	IOMUXC_PTA23	0x034	/* Software MUX Pad Control Register 13 */
+#define	IOMUXC_PTA24	0x038	/* Software MUX Pad Control Register 14 */
+#define	IOMUXC_PTA25	0x03C	/* Software MUX Pad Control Register 15 */
+#define	IOMUXC_PTA26	0x040	/* Software MUX Pad Control Register 16 */
+#define	IOMUXC_PTA27	0x044	/* Software MUX Pad Control Register 17 */
+#define	IOMUXC_PTA28	0x048	/* Software MUX Pad Control Register 18 */
+#define	IOMUXC_PTA29	0x04C	/* Software MUX Pad Control Register 19 */
+#define	IOMUXC_PTA30	0x050	/* Software MUX Pad Control Register 20 */
+#define	IOMUXC_PTA31	0x054	/* Software MUX Pad Control Register 21 */
+#define	IOMUXC_PTB0	0x058	/* Software MUX Pad Control Register 22 */
+#define	IOMUXC_PTB1	0x05C	/* Software MUX Pad Control Register 23 */
+#define	IOMUXC_PTB2	0x060	/* Software MUX Pad Control Register 24 */
+#define	IOMUXC_PTB3	0x064	/* Software MUX Pad Control Register 25 */
+#define	IOMUXC_PTB4	0x068	/* Software MUX Pad Control Register 26 */
+#define	IOMUXC_PTB5	0x06C	/* Software MUX Pad Control Register 27 */
+#define	IOMUXC_PTB6	0x070	/* Software MUX Pad Control Register 28 */
+#define	IOMUXC_PTB7	0x074	/* Software MUX Pad Control Register 29 */
+#define	IOMUXC_PTB8	0x078	/* Software MUX Pad Control Register 30 */
+#define	IOMUXC_PTB9	0x07C	/* Software MUX Pad Control Register 31 */
+#define	IOMUXC_PTB10	0x080	/* Software MUX Pad Control Register 32 */
+#define	IOMUXC_PTB11	0x084	/* Software MUX Pad Control Register 33 */
+#define	IOMUXC_PTB12	0x088	/* Software MUX Pad Control Register 34 */
+#define	IOMUXC_PTB13	0x08C	/* Software MUX Pad Control Register 35 */
+#define	IOMUXC_PTB14	0x090	/* Software MUX Pad Control Register 36 */
+#define	IOMUXC_PTB15	0x094	/* Software MUX Pad Control Register 37 */
+#define	IOMUXC_PTB16	0x098	/* Software MUX Pad Control Register 38 */
+#define	IOMUXC_PTB17	0x09C	/* Software MUX Pad Control Register 39 */
+#define	IOMUXC_PTB18	0x0A0	/* Software MUX Pad Control Register 40 */
+#define	IOMUXC_PTB19	0x0A4	/* Software MUX Pad Control Register 41 */
+#define	IOMUXC_PTB20	0x0A8	/* Software MUX Pad Control Register 42 */
+#define	IOMUXC_PTB21	0x0AC	/* Software MUX Pad Control Register 43 */
+#define	IOMUXC_PTB22	0x0B0	/* Software MUX Pad Control Register 44 */
+#define	IOMUXC_PTC0	0x0B4	/* Software MUX Pad Control Register 45 */
+#define	IOMUXC_PTC1	0x0B8	/* Software MUX Pad Control Register 46 */
+#define	IOMUXC_PTC2	0x0BC	/* Software MUX Pad Control Register 47 */
+#define	IOMUXC_PTC3	0x0C0	/* Software MUX Pad Control Register 48 */
+#define	IOMUXC_PTC4	0x0C4	/* Software MUX Pad Control Register 49 */
+#define	IOMUXC_PTC5	0x0C8	/* Software MUX Pad Control Register 50 */
+#define	IOMUXC_PTC6	0x0CC	/* Software MUX Pad Control Register 51 */
+#define	IOMUXC_PTC7	0x0D0	/* Software MUX Pad Control Register 52 */
+#define	IOMUXC_PTC8	0x0D4	/* Software MUX Pad Control Register 53 */
+#define	IOMUXC_PTC9	0x0D8	/* Software MUX Pad Control Register 54 */
+#define	IOMUXC_PTC10	0x0DC	/* Software MUX Pad Control Register 55 */
+#define	IOMUXC_PTC11	0x0E0	/* Software MUX Pad Control Register 56 */
+#define	IOMUXC_PTC12	0x0E4	/* Software MUX Pad Control Register 57 */
+#define	IOMUXC_PTC13	0x0E8	/* Software MUX Pad Control Register 58 */
+#define	IOMUXC_PTC14	0x0EC	/* Software MUX Pad Control Register 59 */
+#define	IOMUXC_PTC15	0x0F0	/* Software MUX Pad Control Register 60 */
+#define	IOMUXC_PTC16	0x0F4	/* Software MUX Pad Control Register 61 */
+#define	IOMUXC_PTC17	0x0F8	/* Software MUX Pad Control Register 62 */
+#define	IOMUXC_PTD31	0x0FC	/* Software MUX Pad Control Register 63 */
+#define	IOMUXC_PTD30	0x100	/* Software MUX Pad Control Register 64 */
+#define	IOMUXC_PTD29	0x104	/* Software MUX Pad Control Register 65 */
+#define	IOMUXC_PTD28	0x108	/* Software MUX Pad Control Register 66 */
+#define	IOMUXC_PTD27	0x10C	/* Software MUX Pad Control Register 67 */
+#define	IOMUXC_PTD26	0x110	/* Software MUX Pad Control Register 68 */
+#define	IOMUXC_PTD25	0x114	/* Software MUX Pad Control Register 69 */
+#define	IOMUXC_PTD24	0x118	/* Software MUX Pad Control Register 70 */
+#define	IOMUXC_PTD23	0x11C	/* Software MUX Pad Control Register 71 */
+#define	IOMUXC_PTD22	0x120	/* Software MUX Pad Control Register 72 */
+#define	IOMUXC_PTD21	0x124	/* Software MUX Pad Control Register 73 */
+#define	IOMUXC_PTD20	0x128	/* Software MUX Pad Control Register 74 */
+#define	IOMUXC_PTD19	0x12C	/* Software MUX Pad Control Register 75 */
+#define	IOMUXC_PTD18	0x130	/* Software MUX Pad Control Register 76 */
+#define	IOMUXC_PTD17	0x134	/* Software MUX Pad Control Register 77 */
+#define	IOMUXC_PTD16	0x138	/* Software MUX Pad Control Register 78 */
+#define	IOMUXC_PTD0	0x13C	/* Software MUX Pad Control Register 79 */
+#define	IOMUXC_PTD1	0x140	/* Software MUX Pad Control Register 80 */
+#define	IOMUXC_PTD2	0x144	/* Software MUX Pad Control Register 81 */
+#define	IOMUXC_PTD3	0x148	/* Software MUX Pad Control Register 82 */
+#define	IOMUXC_PTD4	0x14C	/* Software MUX Pad Control Register 83 */
+#define	IOMUXC_PTD5	0x150	/* Software MUX Pad Control Register 84 */
+#define	IOMUXC_PTD6	0x154	/* Software MUX Pad Control Register 85 */
+#define	IOMUXC_PTD7	0x158	/* Software MUX Pad Control Register 86 */
+#define	IOMUXC_PTD8	0x15C	/* Software MUX Pad Control Register 87 */
+#define	IOMUXC_PTD9	0x160	/* Software MUX Pad Control Register 88 */
+#define	IOMUXC_PTD10	0x164	/* Software MUX Pad Control Register 89 */
+#define	IOMUXC_PTD11	0x168	/* Software MUX Pad Control Register 90 */
+#define	IOMUXC_PTD12	0x16C	/* Software MUX Pad Control Register 91 */
+#define	IOMUXC_PTD13	0x170	/* Software MUX Pad Control Register 92 */
+#define	IOMUXC_PTB23	0x174	/* Software MUX Pad Control Register 93 */
+#define	IOMUXC_PTB24	0x178	/* Software MUX Pad Control Register 94 */
+#define	IOMUXC_PTB25	0x17C	/* Software MUX Pad Control Register 95 */
+#define	IOMUXC_PTB26	0x180	/* Software MUX Pad Control Register 96 */
+#define	IOMUXC_PTB27	0x184	/* Software MUX Pad Control Register 97 */
+#define	IOMUXC_PTB28	0x188	/* Software MUX Pad Control Register 98 */
+#define	IOMUXC_PTC26	0x18C	/* Software MUX Pad Control Register 99 */
+#define	IOMUXC_PTC27	0x190	/* Software MUX Pad Control Register 100 */
+#define	IOMUXC_PTC28	0x194	/* Software MUX Pad Control Register 101 */
+#define	IOMUXC_PTC29	0x198	/* Software MUX Pad Control Register 102 */
+#define	IOMUXC_PTC30	0x19C	/* Software MUX Pad Control Register 103 */
+#define	IOMUXC_PTC31	0x1A0	/* Software MUX Pad Control Register 104 */
+#define	IOMUXC_PTE0	0x1A4	/* Software MUX Pad Control Register 105 */
+#define	IOMUXC_PTE1	0x1A8	/* Software MUX Pad Control Register 106 */
+#define	IOMUXC_PTE2	0x1AC	/* Software MUX Pad Control Register 107 */
+#define	IOMUXC_PTE3	0x1B0	/* Software MUX Pad Control Register 108 */
+#define	IOMUXC_PTE4	0x1B4	/* Software MUX Pad Control Register 109 */
+#define	IOMUXC_PTE5	0x1B8	/* Software MUX Pad Control Register 110 */
+#define	IOMUXC_PTE6	0x1BC	/* Software MUX Pad Control Register 111 */
+#define	IOMUXC_PTE7	0x1C0	/* Software MUX Pad Control Register 112 */
+#define	IOMUXC_PTE8	0x1C4	/* Software MUX Pad Control Register 113 */
+#define	IOMUXC_PTE9	0x1C8	/* Software MUX Pad Control Register 114 */
+#define	IOMUXC_PTE10	0x1CC	/* Software MUX Pad Control Register 115 */
+#define	IOMUXC_PTE11	0x1D0	/* Software MUX Pad Control Register 116 */
+#define	IOMUXC_PTE12	0x1D4	/* Software MUX Pad Control Register 117 */
+#define	IOMUXC_PTE13	0x1D8	/* Software MUX Pad Control Register 118 */
+#define	IOMUXC_PTE14	0x1DC	/* Software MUX Pad Control Register 119 */
+#define	IOMUXC_PTE15	0x1E0	/* Software MUX Pad Control Register 120 */
+#define	IOMUXC_PTE16	0x1E4	/* Software MUX Pad Control Register 121 */
+#define	IOMUXC_PTE17	0x1E8	/* Software MUX Pad Control Register 122 */
+#define	IOMUXC_PTE18	0x1EC	/* Software MUX Pad Control Register 123 */
+#define	IOMUXC_PTE19	0x1F0	/* Software MUX Pad Control Register 124 */
+#define	IOMUXC_PTE20	0x1F4	/* Software MUX Pad Control Register 125 */
+#define	IOMUXC_PTE21	0x1F8	/* Software MUX Pad Control Register 126 */
+#define	IOMUXC_PTE22	0x1FC	/* Software MUX Pad Control Register 127 */
+#define	IOMUXC_PTE23	0x200	/* Software MUX Pad Control Register 128 */
+#define	IOMUXC_PTE24	0x204	/* Software MUX Pad Control Register 129 */
+#define	IOMUXC_PTE25	0x208	/* Software MUX Pad Control Register 130 */
+#define	IOMUXC_PTE26	0x20C	/* Software MUX Pad Control Register 131 */
+#define	IOMUXC_PTE27	0x210	/* Software MUX Pad Control Register 132 */
+#define	IOMUXC_PTE28	0x214	/* Software MUX Pad Control Register 133 */
+#define	IOMUXC_PTA7	0x218	/* Software MUX Pad Control Register 134 */


Property changes on: trunk/sys/arm/freescale/vybrid/vf_iomuxc.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/vybrid/vf_machdep.c
===================================================================
--- trunk/sys/arm/freescale/vybrid/vf_machdep.c	                        (rev 0)
+++ trunk/sys/arm/freescale/vybrid/vf_machdep.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,94 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Ruslan Bukin <br at bsdpad.com>
+ * 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_ddb.h"
+#include "opt_platform.h"
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/freescale/vybrid/vf_machdep.c 258057 2013-11-12 18:02:56Z br $");
+
+#define	_ARM32_BUS_DMA_PRIVATE
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+
+#include <vm/vm.h>
+
+#include <machine/armreg.h>
+#include <machine/bus.h>
+#include <machine/devmap.h>
+#include <machine/machdep.h>
+
+#include <dev/fdt/fdt_common.h>
+
+vm_offset_t
+initarm_lastaddr(void)
+{
+
+	return (arm_devmap_lastaddr());
+}
+
+void
+initarm_early_init(void)
+{
+
+}
+
+void
+initarm_gpio_init(void)
+{
+
+}
+
+void
+initarm_late_init(void)
+{
+
+}
+
+int
+initarm_devmap_init(void)
+{
+
+	arm_devmap_add_entry(0x40000000, 0x100000);
+
+	return (0);
+}
+
+struct arm32_dma_range *
+bus_dma_get_range(void)
+{
+
+	return (NULL);
+}
+
+int
+bus_dma_get_range_nb(void)
+{
+
+	return (0);
+}


Property changes on: trunk/sys/arm/freescale/vybrid/vf_machdep.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/vybrid/vf_mscm.c
===================================================================
--- trunk/sys/arm/freescale/vybrid/vf_mscm.c	                        (rev 0)
+++ trunk/sys/arm/freescale/vybrid/vf_mscm.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,127 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Ruslan Bukin <br at bsdpad.com>
+ * 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.
+ */
+
+/*
+ * Vybrid Family Miscellaneous System Control Module (MSCM)
+ * Chapter 66, Vybrid Reference Manual, Rev. 5, 07/2013
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/freescale/vybrid/vf_mscm.c 266152 2014-05-15 16:11:06Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/timeet.h>
+#include <sys/timetc.h>
+#include <sys/watchdog.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#include <arm/freescale/vybrid/vf_common.h>
+
+#define	VF_NINT	112	/* Total number of interrupts */
+
+/* Int Router Shared Peripheral Routing Control */
+#define	MSCM_IRSPRC(n)	(0x880 + 2 * n)
+
+struct mscm_softc {
+	struct resource		*res[1];
+	bus_space_tag_t		bst;
+	bus_space_handle_t	bsh;
+};
+
+static struct resource_spec mscm_spec[] = {
+	{ SYS_RES_MEMORY,       0,      RF_ACTIVE },
+	{ -1, 0 }
+};
+
+static int
+mscm_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "fsl,mvf600-mscm"))
+		return (ENXIO);
+
+	device_set_desc(dev, "Vybrid Family Miscellaneous System Control Module");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+mscm_attach(device_t dev)
+{
+	struct mscm_softc *sc;
+	int i;
+
+	sc = device_get_softc(dev);
+
+	if (bus_alloc_resources(dev, mscm_spec, sc->res)) {
+		device_printf(dev, "could not allocate resources\n");
+		return (ENXIO);
+	}
+
+	/* Memory interface */
+	sc->bst = rman_get_bustag(sc->res[0]);
+	sc->bsh = rman_get_bushandle(sc->res[0]);
+
+	/* Route all the interrupts to CP0 */
+	for (i = 0; i < VF_NINT; i++)
+		WRITE2(sc, MSCM_IRSPRC(i), 1);
+
+	return (0);
+}
+
+static device_method_t mscm_methods[] = {
+	DEVMETHOD(device_probe,		mscm_probe),
+	DEVMETHOD(device_attach,	mscm_attach),
+	{ 0, 0 }
+};
+
+static driver_t mscm_driver = {
+	"mscm",
+	mscm_methods,
+	sizeof(struct mscm_softc),
+};
+
+static devclass_t mscm_devclass;
+
+DRIVER_MODULE(mscm, simplebus, mscm_driver, mscm_devclass, 0, 0);


Property changes on: trunk/sys/arm/freescale/vybrid/vf_mscm.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/vybrid/vf_nfc.c
===================================================================
--- trunk/sys/arm/freescale/vybrid/vf_nfc.c	                        (rev 0)
+++ trunk/sys/arm/freescale/vybrid/vf_nfc.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,528 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Ruslan Bukin <br at bsdpad.com>
+ * 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.
+ */
+
+/*
+ * Vybrid Family NAND Flash Controller (NFC)
+ * Chapter 31, Vybrid Reference Manual, Rev. 5, 07/2013
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/freescale/vybrid/vf_nfc.c 266152 2014-05-15 16:11:06Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/time.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+#include <dev/nand/nand.h>
+#include <dev/nand/nandbus.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+
+#include "nfc_if.h"
+
+#include <arm/freescale/vybrid/vf_common.h>
+
+enum addr_type {
+	ADDR_NONE,
+	ADDR_ID,
+	ADDR_ROW,
+	ADDR_ROWCOL
+};
+
+struct fsl_nfc_fcm {
+	uint32_t	addr_bits;
+	enum addr_type  addr_type;
+	uint32_t	col_addr_bits;
+	uint32_t	row_addr_bits;
+	u_int		read_ptr;
+	u_int		addr_ptr;
+	u_int		command;
+	u_int		code;
+};
+
+struct vf_nand_softc {
+	struct nand_softc 	nand_dev;
+	bus_space_handle_t 	bsh;
+	bus_space_tag_t		bst;
+	struct resource		*res[2];
+	struct fsl_nfc_fcm	fcm;
+};
+
+static struct resource_spec nfc_spec[] = {
+	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		0,	RF_ACTIVE },
+	{ -1, 0 }
+};
+
+static int	vf_nand_attach(device_t);
+static int	vf_nand_probe(device_t);
+static int	vf_nand_send_command(device_t, uint8_t);
+static int	vf_nand_send_address(device_t, uint8_t);
+static int	vf_nand_start_command(device_t);
+static uint8_t	vf_nand_read_byte(device_t);
+static void	vf_nand_read_buf(device_t, void *, uint32_t);
+static void	vf_nand_write_buf(device_t, void *, uint32_t);
+static int	vf_nand_select_cs(device_t, uint8_t);
+static int	vf_nand_read_rnb(device_t);
+
+#define	CMD_READ_PAGE		0x7EE0
+#define	CMD_PROG_PAGE		0x7FC0
+#define	CMD_PROG_PAGE_DMA	0xFFC8
+#define	CMD_ERASE		0x4EC0
+#define	CMD_READ_ID		0x4804
+#define	CMD_READ_STATUS		0x4068
+#define	CMD_RESET		0x4040
+#define	CMD_RANDOM_IN		0x7140
+#define	CMD_RANDOM_OUT		0x70E0
+
+#define	CMD_BYTE2_PROG_PAGE	0x10
+#define	CMD_BYTE2_PAGE_READ	0x30
+#define	CMD_BYTE2_ERASE		0xD0
+
+#define	NFC_CMD1	0x3F00	/* Flash command 1 */
+#define	NFC_CMD2	0x3F04	/* Flash command 2 */
+#define	NFC_CAR		0x3F08	/* Column address */
+#define	NFC_RAR		0x3F0C	/* Row address */
+#define	NFC_RPT		0x3F10	/* Flash command repeat */
+#define	NFC_RAI		0x3F14	/* Row address increment */
+#define	NFC_SR1		0x3F18	/* Flash status 1 */
+#define	NFC_SR2		0x3F1C	/* Flash status 2 */
+#define	NFC_DMA_CH1	0x3F20	/* DMA channel 1 address */
+#define	NFC_DMACFG	0x3F24	/* DMA configuration */
+#define	NFC_SWAP	0x3F28	/* Cach swap */
+#define	NFC_SECSZ	0x3F2C	/* Sector size */
+#define	NFC_CFG		0x3F30	/* Flash configuration */
+#define	NFC_DMA_CH2	0x3F34	/* DMA channel 2 address */
+#define	NFC_ISR		0x3F38	/* Interrupt status */
+
+#define	ECCMODE_SHIFT		17
+#define	AIAD_SHIFT		5
+#define	AIBN_SHIFT		4
+#define	PAGECOUNT_SHIFT		0
+#define	BITWIDTH_SHIFT		7
+#define	BITWIDTH8		0
+#define	BITWIDTH16		1
+#define	PAGECOUNT_MASK		0xf
+
+#define	CMD2_BYTE1_SHIFT	24
+#define	CMD2_CODE_SHIFT		8
+#define	CMD2_BUFNO_SHIFT	1
+#define	CMD2_START_SHIFT	0
+
+static device_method_t vf_nand_methods[] = {
+	DEVMETHOD(device_probe,		vf_nand_probe),
+	DEVMETHOD(device_attach,	vf_nand_attach),
+	DEVMETHOD(nfc_start_command,	vf_nand_start_command),
+	DEVMETHOD(nfc_send_command,	vf_nand_send_command),
+	DEVMETHOD(nfc_send_address,	vf_nand_send_address),
+	DEVMETHOD(nfc_read_byte,	vf_nand_read_byte),
+	DEVMETHOD(nfc_read_buf,		vf_nand_read_buf),
+	DEVMETHOD(nfc_write_buf,	vf_nand_write_buf),
+	DEVMETHOD(nfc_select_cs,	vf_nand_select_cs),
+	DEVMETHOD(nfc_read_rnb,		vf_nand_read_rnb),
+	{ 0, 0 },
+};
+
+static driver_t vf_nand_driver = {
+	"nand",
+	vf_nand_methods,
+	sizeof(struct vf_nand_softc),
+};
+
+static devclass_t vf_nand_devclass;
+DRIVER_MODULE(vf_nand, simplebus, vf_nand_driver, vf_nand_devclass, 0, 0);
+
+static int
+vf_nand_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "fsl,mvf600-nand"))
+		return (ENXIO);
+
+	device_set_desc(dev, "Vybrid Family NAND controller");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+vf_nand_attach(device_t dev)
+{
+	struct vf_nand_softc *sc;
+	int err;
+	int reg;
+
+	sc = device_get_softc(dev);
+	if (bus_alloc_resources(dev, nfc_spec, sc->res)) {
+		device_printf(dev, "could not allocate resources!\n");
+		return (ENXIO);
+	}
+
+	sc->bst = rman_get_bustag(sc->res[0]);
+	sc->bsh = rman_get_bushandle(sc->res[0]);
+
+	/* Size in bytes of one elementary transfer unit */
+	WRITE4(sc, NFC_SECSZ, 2048);
+
+	/* Flash mode width */
+	reg = READ4(sc, NFC_CFG);
+	reg |= (BITWIDTH16 << BITWIDTH_SHIFT);
+
+	/* No correction, ECC bypass */
+	reg &= ~(0x7 << ECCMODE_SHIFT);
+
+	/* Disable Auto-incrementing of flash row address */
+	reg &= ~(0x1 << AIAD_SHIFT);
+
+	/* Disable Auto-incrementing of buffer numbers */
+	reg &= ~(0x1 << AIBN_SHIFT);
+
+	/*
+	 * Number of virtual pages (in one physical flash page)
+	 * to be programmed or read, etc.
+	 */
+	reg &= ~(PAGECOUNT_MASK);
+	reg |= (1 << PAGECOUNT_SHIFT);
+	WRITE4(sc, NFC_CFG, reg);
+
+	nand_init(&sc->nand_dev, dev, NAND_ECC_NONE, 0, 0, NULL, NULL);
+	err = nandbus_create(dev);
+	return (err);
+}
+
+static int
+vf_nand_start_command(device_t dev)
+{
+	struct vf_nand_softc *sc;
+	struct fsl_nfc_fcm *fcm;
+	int reg;
+
+	sc = device_get_softc(dev);
+	fcm = &sc->fcm;
+
+	nand_debug(NDBG_DRV,"vf_nand: start command %x", fcm->command);
+
+	/* CMD2 */
+	reg = READ4(sc, NFC_CMD2);
+	reg &= ~(0xff << CMD2_BYTE1_SHIFT);
+	reg |= (fcm->command << CMD2_BYTE1_SHIFT);
+	WRITE4(sc, NFC_CMD2, reg);
+
+	/* CMD1 */
+	if ((fcm->command == NAND_CMD_READ) ||
+	    (fcm->command == NAND_CMD_PROG) ||
+	    (fcm->command == NAND_CMD_ERASE)) {
+		reg = READ4(sc, NFC_CMD1);
+		reg &= ~(0xff << 24);
+
+		if (fcm->command == NAND_CMD_READ)
+			reg |= (CMD_BYTE2_PAGE_READ << 24);
+		else if (fcm->command == NAND_CMD_PROG)
+			reg |= (CMD_BYTE2_PROG_PAGE << 24);
+		else if (fcm->command == NAND_CMD_ERASE)
+			reg |= (CMD_BYTE2_ERASE << 24);
+
+		WRITE4(sc, NFC_CMD1, reg);
+	}
+
+	/* We work with 1st buffer */
+	reg = READ4(sc, NFC_CMD2);
+	reg &= ~(0xf << CMD2_BUFNO_SHIFT);
+	reg |= (0 << CMD2_BUFNO_SHIFT);
+	WRITE4(sc, NFC_CMD2, reg);
+
+	/* Cmd CODE */
+	reg = READ4(sc, NFC_CMD2);
+	reg &= ~(0xffff << CMD2_CODE_SHIFT);
+	reg |= (fcm->code << CMD2_CODE_SHIFT);
+	WRITE4(sc, NFC_CMD2, reg);
+
+	/* Col */
+	if (fcm->addr_type == ADDR_ROWCOL) {
+		reg = READ4(sc, NFC_CAR);
+		reg &= ~(0xffff);
+		reg |= fcm->col_addr_bits;
+		nand_debug(NDBG_DRV,"setting CAR to 0x%08x\n", reg);
+		WRITE4(sc, NFC_CAR, reg);
+	}
+
+	/* Row */
+	reg = READ4(sc, NFC_RAR);
+	reg &= ~(0xffffff);
+	if (fcm->addr_type == ADDR_ID)
+		reg |= fcm->addr_bits;
+	else
+		reg |= fcm->row_addr_bits;
+	WRITE4(sc, NFC_RAR, reg);
+
+	/* Start */
+	reg = READ4(sc, NFC_CMD2);
+	reg |= (1 << CMD2_START_SHIFT);
+	WRITE4(sc, NFC_CMD2, reg);
+
+	/* Wait command completion */
+	while (READ4(sc, NFC_CMD2) & (1 << CMD2_START_SHIFT))
+		;
+
+	return (0);
+}
+
+static int
+vf_nand_send_command(device_t dev, uint8_t command)
+{
+	struct vf_nand_softc *sc;
+	struct fsl_nfc_fcm *fcm;
+
+	nand_debug(NDBG_DRV,"vf_nand: send command %x", command);
+
+	sc = device_get_softc(dev);
+	fcm = &sc->fcm;
+
+	if ((command == NAND_CMD_READ_END) ||
+	    (command == NAND_CMD_PROG_END) ||
+	    (command == NAND_CMD_ERASE_END)) {
+		return (0);
+	}
+
+	fcm->command = command;
+
+	fcm->code = 0;
+	fcm->read_ptr = 0;
+	fcm->addr_type = 0;
+	fcm->addr_bits = 0;
+
+	fcm->addr_ptr = 0;
+	fcm->col_addr_bits = 0;
+	fcm->row_addr_bits = 0;
+
+	switch (command) {
+	case NAND_CMD_READ:
+		fcm->code = CMD_READ_PAGE;
+		fcm->addr_type = ADDR_ROWCOL;
+		break;
+	case NAND_CMD_PROG:
+		fcm->code = CMD_PROG_PAGE;
+		fcm->addr_type = ADDR_ROWCOL;
+		break;
+	case NAND_CMD_PROG_END:
+		break;
+	case NAND_CMD_ERASE_END:
+		break;
+	case NAND_CMD_RESET:
+		fcm->code = CMD_RESET;
+		break;
+	case NAND_CMD_READ_ID:
+		fcm->code = CMD_READ_ID;
+		fcm->addr_type = ADDR_ID;
+		break;
+	case NAND_CMD_READ_PARAMETER:
+		fcm->code = CMD_READ_PAGE;
+		fcm->addr_type = ADDR_ID;
+		break;
+	case NAND_CMD_STATUS:
+		fcm->code = CMD_READ_STATUS;
+		break;
+	case NAND_CMD_ERASE:
+		fcm->code = CMD_ERASE;
+		fcm->addr_type = ADDR_ROW;
+		break;
+	default:
+		nand_debug(NDBG_DRV, "unknown command %d\n", command);
+		return (1);
+	}
+
+	return (0);
+}
+
+static int
+vf_nand_send_address(device_t dev, uint8_t addr)
+{
+	struct vf_nand_softc *sc;
+	struct fsl_nfc_fcm *fcm;
+
+	nand_debug(NDBG_DRV,"vf_nand: send address %x", addr);
+	sc = device_get_softc(dev);
+	fcm = &sc->fcm;
+
+	nand_debug(NDBG_DRV, "setting addr #%d to 0x%02x\n", fcm->addr_ptr, addr);
+
+	if (fcm->addr_type == ADDR_ID) {
+		fcm->addr_bits = addr;
+	} else if (fcm->addr_type == ADDR_ROWCOL) {
+
+		if (fcm->addr_ptr < 2)
+			fcm->col_addr_bits |= (addr << (fcm->addr_ptr * 8));
+		else
+			fcm->row_addr_bits |= (addr << ((fcm->addr_ptr - 2) * 8));
+
+	} else if (fcm->addr_type == ADDR_ROW)
+		fcm->row_addr_bits |= (addr << (fcm->addr_ptr * 8));
+
+	fcm->addr_ptr += 1;
+
+	return (0);
+}
+
+static uint8_t
+vf_nand_read_byte(device_t dev)
+{
+	struct vf_nand_softc *sc;
+	struct fsl_nfc_fcm *fcm;
+	uint8_t data;
+	int sr1, sr2;
+	int b;
+
+	sc = device_get_softc(dev);
+	fcm = &sc->fcm;
+
+	sr1 = READ4(sc, NFC_SR1);
+	sr2 = READ4(sc, NFC_SR2);
+
+	data = 0;
+	if (fcm->addr_type == ADDR_ID) {
+		b = 32 - ((fcm->read_ptr + 1) * 8);
+		data = (sr1 >> b) & 0xff;
+		fcm->read_ptr++;
+	} else if (fcm->command == NAND_CMD_STATUS) {
+		data = sr2 & 0xff;
+	}
+
+	nand_debug(NDBG_DRV,"vf_nand: read %x", data);
+	return (data);
+}
+
+static void
+vf_nand_read_buf(device_t dev, void* buf, uint32_t len)
+{
+	struct vf_nand_softc *sc;
+	struct fsl_nfc_fcm *fcm;
+	uint16_t *tmp;
+	uint8_t *b;
+	int i;
+
+	b = (uint8_t*)buf;
+	sc = device_get_softc(dev);
+	fcm = &sc->fcm;
+
+	nand_debug(NDBG_DRV, "vf_nand: read_buf len %d", len);
+
+	if (fcm->command == NAND_CMD_READ_PARAMETER) {
+		tmp = malloc(len, M_DEVBUF, M_NOWAIT);
+		bus_read_region_2(sc->res[0], 0x0, tmp, len);
+
+		for (i = 0; i < len; i += 2) {
+			b[i] = tmp[i+1];
+			b[i+1] = tmp[i];
+		}
+
+		free(tmp, M_DEVBUF);
+
+#ifdef NAND_DEBUG
+		for (i = 0; i < len; i++) {
+			if (!(i % 16))
+				printf("%s", i == 0 ? "vf_nand:\n" : "\n");
+			printf(" %x", b[i]);
+			if (i == len - 1)
+				printf("\n");
+		}
+#endif
+
+	} else {
+
+		for (i = 0; i < len; i++) {
+			b[i] = READ1(sc, i);
+
+#ifdef NAND_DEBUG
+			if (!(i % 16))
+				printf("%s", i == 0 ? "vf_nand:\n" : "\n");
+			printf(" %x", b[i]);
+			if (i == len - 1)
+				printf("\n");
+#endif
+		}
+
+	}
+}
+
+static void
+vf_nand_write_buf(device_t dev, void* buf, uint32_t len)
+{
+	struct vf_nand_softc *sc;
+	struct fsl_nfc_fcm *fcm;
+	uint8_t *b;
+	int i;
+
+	b = (uint8_t*)buf;
+	sc = device_get_softc(dev);
+	fcm = &sc->fcm;
+
+	nand_debug(NDBG_DRV,"vf_nand: write_buf len %d", len);
+
+	for (i = 0; i < len; i++) {
+		WRITE1(sc, i, b[i]);
+
+#ifdef NAND_DEBUG
+		if (!(i % 16))
+			printf("%s", i == 0 ? "vf_nand:\n" : "\n");
+		printf(" %x", b[i]);
+		if (i == len - 1)
+			printf("\n");
+#endif
+
+	}
+}
+
+static int
+vf_nand_select_cs(device_t dev, uint8_t cs)
+{
+
+	if (cs > 0)
+		return (ENODEV);
+
+	return (0);
+}
+
+static int
+vf_nand_read_rnb(device_t dev)
+{
+
+	/* no-op */
+	return (0); /* ready */
+}


Property changes on: trunk/sys/arm/freescale/vybrid/vf_nfc.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/vybrid/vf_port.c
===================================================================
--- trunk/sys/arm/freescale/vybrid/vf_port.c	                        (rev 0)
+++ trunk/sys/arm/freescale/vybrid/vf_port.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,251 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014 Ruslan Bukin <br at bsdpad.com>
+ * 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.
+ */
+
+/*
+ * Vybrid Family Port control and interrupts (PORT)
+ * Chapter 6, Vybrid Reference Manual, Rev. 5, 07/2013
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/freescale/vybrid/vf_port.c 266274 2014-05-16 23:27:18Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/timeet.h>
+#include <sys/timetc.h>
+#include <sys/watchdog.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#include <arm/freescale/vybrid/vf_port.h>
+#include <arm/freescale/vybrid/vf_common.h>
+
+/* Pin Control Register */
+#define PORT_PCR(n)		(0x1000 * (n >> 5) + 0x4 * (n % 32))
+#define	 PCR_IRQC_S	16
+#define	 PCR_IRQC_M	0xF
+#define	 PCR_DMA_RE	0x1
+#define	 PCR_DMA_FE	0x2
+#define	 PCR_DMA_EE	0x3
+#define	 PCR_INT_LZ	0x8
+#define	 PCR_INT_RE	0x9
+#define	 PCR_INT_FE	0xA
+#define	 PCR_INT_EE	0xB
+#define	 PCR_INT_LO	0xC
+#define	 PCR_ISF	(1 << 24)
+#define	PORT0_ISFR	0xA0	/* Interrupt Status Flag Register */
+#define	PORT0_DFER	0xC0	/* Digital Filter Enable Register */
+#define	PORT0_DFCR	0xC4	/* Digital Filter Clock Register */
+#define	PORT0_DFWR	0xC8	/* Digital Filter Width Register */
+
+struct port_event {
+	uint32_t	enabled;
+	uint32_t	mux_num;
+	uint32_t	mux_src;
+	uint32_t	mux_chn;
+	void		(*ih) (void *);
+	void		*ih_user;
+	enum ev_type	pevt;
+};
+
+static struct port_event event_map[NGPIO];
+
+struct port_softc {
+	struct resource		*res[6];
+	bus_space_tag_t		bst;
+	bus_space_handle_t	bsh;
+	void			*gpio_ih[NGPIO];
+};
+
+struct port_softc *port_sc;
+
+static struct resource_spec port_spec[] = {
+	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		0,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		1,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		2,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		3,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		4,	RF_ACTIVE },
+	{ -1, 0 }
+};
+
+static int
+port_intr(void *arg)
+{
+	struct port_event *pev;
+	struct port_softc *sc;
+	int reg;
+	int i;
+
+	sc = arg;
+
+	for (i = 0; i < NGPIO; i++) {
+		reg = READ4(sc, PORT_PCR(i));
+		if (reg & PCR_ISF) {
+
+			/* Clear interrupt */
+			WRITE4(sc, PORT_PCR(i), reg);
+
+			/* Handle event */
+			pev = &event_map[i];
+			if (pev->enabled == 1) {
+				if (pev->ih != NULL) {
+					pev->ih(pev->ih_user);
+				}
+			}
+		}
+	}
+
+	return (FILTER_HANDLED);
+}
+
+int
+port_setup(int pnum, enum ev_type pevt, void (*ih)(void *), void *ih_user)
+{
+	struct port_event *pev;
+	struct port_softc *sc;
+	int reg;
+	int val;
+
+	sc = port_sc;
+
+	switch (pevt) {
+	case DMA_RISING_EDGE:
+		val = PCR_DMA_RE;
+		break;
+	case DMA_FALLING_EDGE:
+		val = PCR_DMA_FE;
+		break;
+	case DMA_EITHER_EDGE:
+		val = PCR_DMA_EE;
+		break;
+	case INT_LOGIC_ZERO:
+		val = PCR_INT_LZ;
+		break;
+	case INT_RISING_EDGE:
+		val = PCR_INT_RE;
+		break;
+	case INT_FALLING_EDGE:
+		val = PCR_INT_FE;
+		break;
+	case INT_EITHER_EDGE:
+		val = PCR_INT_RE;
+		break;
+	case INT_LOGIC_ONE:
+		val = PCR_INT_LO;
+		break;
+	default:
+		return (-1);
+	};
+
+	reg = READ4(sc, PORT_PCR(pnum));
+	reg &= ~(PCR_IRQC_M << PCR_IRQC_S);
+	reg |= (val << PCR_IRQC_S);
+	WRITE4(sc, PORT_PCR(pnum), reg);
+
+	pev = &event_map[pnum];
+	pev->ih = ih;
+	pev->ih_user = ih_user;
+	pev->pevt = pevt;
+	pev->enabled = 1;
+
+	return (0);
+}
+
+static int
+port_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "fsl,mvf600-port"))
+		return (ENXIO);
+
+	device_set_desc(dev, "Vybrid Family Port control and interrupts");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+port_attach(device_t dev)
+{
+	struct port_softc *sc;
+	int irq;
+
+	sc = device_get_softc(dev);
+
+	if (bus_alloc_resources(dev, port_spec, sc->res)) {
+		device_printf(dev, "could not allocate resources\n");
+		return (ENXIO);
+	}
+
+	/* Memory interface */
+	sc->bst = rman_get_bustag(sc->res[0]);
+	sc->bsh = rman_get_bushandle(sc->res[0]);
+
+	port_sc = sc;
+
+	for (irq = 0; irq < NPORTS; irq ++) {
+		if ((bus_setup_intr(dev, sc->res[1 + irq], INTR_TYPE_MISC,
+		    port_intr, NULL, sc, &sc->gpio_ih[irq]))) {
+			device_printf(dev,
+			    "ERROR: Unable to register interrupt handler\n");
+			return (ENXIO);
+		}
+	}
+
+	return (0);
+}
+
+static device_method_t port_methods[] = {
+	DEVMETHOD(device_probe,		port_probe),
+	DEVMETHOD(device_attach,	port_attach),
+	{ 0, 0 }
+};
+
+static driver_t port_driver = {
+	"port",
+	port_methods,
+	sizeof(struct port_softc),
+};
+
+static devclass_t port_devclass;
+
+DRIVER_MODULE(port, simplebus, port_driver, port_devclass, 0, 0);


Property changes on: trunk/sys/arm/freescale/vybrid/vf_port.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/vybrid/vf_port.h
===================================================================
--- trunk/sys/arm/freescale/vybrid/vf_port.h	                        (rev 0)
+++ trunk/sys/arm/freescale/vybrid/vf_port.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,44 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014 Ruslan Bukin <br at bsdpad.com>
+ * 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: stable/10/sys/arm/freescale/vybrid/vf_port.h 266274 2014-05-16 23:27:18Z ian $
+ */
+
+#define	NPORTS		5
+#define	NGPIO		(NPORTS * 32)
+
+enum ev_type {
+	DMA_RISING_EDGE,
+	DMA_FALLING_EDGE,
+	DMA_EITHER_EDGE,
+	INT_LOGIC_ZERO,
+	INT_RISING_EDGE,
+	INT_FALLING_EDGE,
+	INT_EITHER_EDGE,
+	INT_LOGIC_ONE,
+};
+
+int port_setup(int, enum ev_type, void (*ih)(void *), void *ih_user);


Property changes on: trunk/sys/arm/freescale/vybrid/vf_port.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/vybrid/vf_sai.c
===================================================================
--- trunk/sys/arm/freescale/vybrid/vf_sai.c	                        (rev 0)
+++ trunk/sys/arm/freescale/vybrid/vf_sai.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,806 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014 Ruslan Bukin <br at bsdpad.com>
+ * 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.
+ */
+
+/*
+ * Vybrid Family Synchronous Audio Interface (SAI)
+ * Chapter 51, Vybrid Reference Manual, Rev. 5, 07/2013
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/freescale/vybrid/vf_sai.c 273652 2014-10-26 01:30:46Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/timeet.h>
+#include <sys/timetc.h>
+#include <sys/watchdog.h>
+
+#include <dev/sound/pcm/sound.h>
+#include <dev/sound/chip.h>
+#include <mixer_if.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#include <arm/freescale/vybrid/vf_common.h>
+#include <arm/freescale/vybrid/vf_dmamux.h>
+#include <arm/freescale/vybrid/vf_edma.h>
+
+#define	I2S_TCSR	0x00	/* SAI Transmit Control */
+#define	I2S_TCR1	0x04	/* SAI Transmit Configuration 1 */
+#define	I2S_TCR2	0x08	/* SAI Transmit Configuration 2 */
+#define	I2S_TCR3	0x0C	/* SAI Transmit Configuration 3 */
+#define	I2S_TCR4	0x10	/* SAI Transmit Configuration 4 */
+#define	I2S_TCR5	0x14	/* SAI Transmit Configuration 5 */
+#define	I2S_TDR0	0x20	/* SAI Transmit Data */
+#define	I2S_TFR0	0x40	/* SAI Transmit FIFO */
+#define	I2S_TMR		0x60	/* SAI Transmit Mask */
+#define	I2S_RCSR	0x80	/* SAI Receive Control */
+#define	I2S_RCR1	0x84	/* SAI Receive Configuration 1 */
+#define	I2S_RCR2	0x88	/* SAI Receive Configuration 2 */
+#define	I2S_RCR3	0x8C	/* SAI Receive Configuration 3 */
+#define	I2S_RCR4	0x90	/* SAI Receive Configuration 4 */
+#define	I2S_RCR5	0x94	/* SAI Receive Configuration 5 */
+#define	I2S_RDR0	0xA0	/* SAI Receive Data */
+#define	I2S_RFR0	0xC0	/* SAI Receive FIFO */
+#define	I2S_RMR		0xE0	/* SAI Receive Mask */
+
+#define	TCR1_TFW_M	0x1f		/* Transmit FIFO Watermark Mask */
+#define	TCR1_TFW_S	0		/* Transmit FIFO Watermark Shift */
+#define	TCR2_MSEL_M	0x3		/* MCLK Select Mask*/
+#define	TCR2_MSEL_S	26		/* MCLK Select Shift*/
+#define	TCR2_BCP	(1 << 25)	/* Bit Clock Polarity */
+#define	TCR2_BCD	(1 << 24)	/* Bit Clock Direction */
+#define	TCR3_TCE	(1 << 16)	/* Transmit Channel Enable */
+#define	TCR4_FRSZ_M	0x1f		/* Frame size Mask */
+#define	TCR4_FRSZ_S	16		/* Frame size Shift */
+#define	TCR4_SYWD_M	0x1f		/* Sync Width Mask */
+#define	TCR4_SYWD_S	8		/* Sync Width Shift */
+#define	TCR4_MF		(1 << 4)	/* MSB First */
+#define	TCR4_FSE	(1 << 3)	/* Frame Sync Early */
+#define	TCR4_FSP	(1 << 1)	/* Frame Sync Polarity Low */
+#define	TCR4_FSD	(1 << 0)	/* Frame Sync Direction Master */
+#define	TCR5_FBT_M	0x1f		/* First Bit Shifted */
+#define	TCR5_FBT_S	8		/* First Bit Shifted */
+#define	TCR5_W0W_M	0x1f		/* Word 0 Width */
+#define	TCR5_W0W_S	16		/* Word 0 Width */
+#define	TCR5_WNW_M	0x1f		/* Word N Width */
+#define	TCR5_WNW_S	24		/* Word N Width */
+#define	TCSR_TE		(1 << 31)	/* Transmitter Enable */
+#define	TCSR_BCE	(1 << 28)	/* Bit Clock Enable */
+#define	TCSR_FRDE	(1 << 0)	/* FIFO Request DMA Enable */
+
+#define	SAI_NCHANNELS	1
+
+static MALLOC_DEFINE(M_SAI, "sai", "sai audio");
+
+struct sai_rate {
+	uint32_t speed;
+	uint32_t div; /* Bit Clock Divide. Division value is (div + 1) * 2. */
+	uint32_t mfi; /* PLL4 Multiplication Factor Integer */
+	uint32_t mfn; /* PLL4 Multiplication Factor Numerator */
+	uint32_t mfd; /* PLL4 Multiplication Factor Denominator */
+};
+
+/*
+ * Bit clock divider formula
+ * (div + 1) * 2 = MCLK/(nch * LRCLK * bits/1000000),
+ * where:
+ *   MCLK - master clock
+ *   nch - number of channels
+ *   LRCLK - left right clock
+ * e.g. (div + 1) * 2 = 16.9344/(2 * 44100 * 24/1000000)
+ *
+ * Example for 96khz, 24bit, 18.432 Mhz mclk (192fs)
+ * { 96000, 1, 18, 40176000, 93000000 },
+ */
+
+static struct sai_rate rate_map[] = {
+	{ 44100, 7, 33, 80798400, 93000000 }, /* 33.8688 Mhz */
+	{ 96000, 3, 36, 80352000, 93000000 }, /* 36.864 Mhz */
+	{ 192000, 1, 36, 80352000, 93000000 }, /* 36.864 Mhz */
+	{ 0, 0 },
+};
+
+struct sc_info {
+	struct resource		*res[2];
+	bus_space_tag_t		bst;
+	bus_space_handle_t	bsh;
+	device_t		dev;
+	struct mtx		*lock;
+	uint32_t		speed;
+	uint32_t		period;
+	void			*ih;
+	int			pos;
+	int			dma_size;
+	bus_dma_tag_t		dma_tag;
+	bus_dmamap_t		dma_map;
+	bus_addr_t		buf_base_phys;
+	uint32_t		*buf_base;
+	struct tcd_conf		*tcd;
+	struct sai_rate		*sr;
+	struct edma_softc	*edma_sc;
+	int			edma_chnum;
+};
+
+/* Channel registers */
+struct sc_chinfo {
+	struct snd_dbuf		*buffer;
+	struct pcm_channel	*channel;
+	struct sc_pcminfo	*parent;
+
+	/* Channel information */
+	uint32_t	dir;
+	uint32_t	format;
+
+	/* Flags */
+	uint32_t	run;
+};
+
+/* PCM device private data */
+struct sc_pcminfo {
+	device_t		dev;
+	uint32_t		(*ih) (struct sc_pcminfo *scp);
+	uint32_t		chnum;
+	struct sc_chinfo	chan[SAI_NCHANNELS];
+	struct sc_info		*sc;
+};
+
+static struct resource_spec sai_spec[] = {
+	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		0,	RF_ACTIVE },
+	{ -1, 0 }
+};
+
+static int setup_dma(struct sc_pcminfo *scp);
+static void setup_sai(struct sc_info *);
+static void sai_configure_clock(struct sc_info *);
+
+/*
+ * Mixer interface.
+ */
+
+static int
+saimixer_init(struct snd_mixer *m)
+{
+	struct sc_pcminfo *scp;
+	struct sc_info *sc;
+	int mask;
+
+	scp = mix_getdevinfo(m);
+	sc = scp->sc;
+
+	if (sc == NULL)
+		return -1;
+
+	mask = SOUND_MASK_PCM;
+
+	snd_mtxlock(sc->lock);
+	pcm_setflags(scp->dev, pcm_getflags(scp->dev) | SD_F_SOFTPCMVOL);
+	mix_setdevs(m, mask);
+	snd_mtxunlock(sc->lock);
+
+	return (0);
+}
+
+static int
+saimixer_set(struct snd_mixer *m, unsigned dev,
+    unsigned left, unsigned right)
+{
+	struct sc_pcminfo *scp;
+
+	scp = mix_getdevinfo(m);
+
+#if 0
+	device_printf(scp->dev, "saimixer_set() %d %d\n",
+	    left, right);
+#endif
+
+	return (0);
+}
+
+static kobj_method_t saimixer_methods[] = {
+	KOBJMETHOD(mixer_init,      saimixer_init),
+	KOBJMETHOD(mixer_set,       saimixer_set),
+	KOBJMETHOD_END
+};
+MIXER_DECLARE(saimixer);
+
+/*
+ * Channel interface.
+ */
+
+static void *
+saichan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b,
+    struct pcm_channel *c, int dir)
+{
+	struct sc_pcminfo *scp;
+	struct sc_chinfo *ch;
+	struct sc_info *sc;
+
+	scp = (struct sc_pcminfo *)devinfo;
+	sc = scp->sc;
+
+	snd_mtxlock(sc->lock);
+	ch = &scp->chan[0];
+	ch->dir = dir;
+	ch->run = 0;
+	ch->buffer = b;
+	ch->channel = c;
+	ch->parent = scp;
+	snd_mtxunlock(sc->lock);
+
+	if (sndbuf_setup(ch->buffer, sc->buf_base, sc->dma_size) != 0) {
+		device_printf(scp->dev, "Can't setup sndbuf.\n");
+		return NULL;
+	}
+
+	return ch;
+}
+
+static int
+saichan_free(kobj_t obj, void *data)
+{
+	struct sc_chinfo *ch = data;
+	struct sc_pcminfo *scp = ch->parent;
+	struct sc_info *sc = scp->sc;
+
+#if 0
+	device_printf(scp->dev, "saichan_free()\n");
+#endif
+
+	snd_mtxlock(sc->lock);
+	/* TODO: free channel buffer */
+	snd_mtxunlock(sc->lock);
+
+	return (0);
+}
+
+static int
+saichan_setformat(kobj_t obj, void *data, uint32_t format)
+{
+	struct sc_chinfo *ch = data;
+
+	ch->format = format;
+
+	return (0);
+}
+
+static uint32_t
+saichan_setspeed(kobj_t obj, void *data, uint32_t speed)
+{
+	struct sc_pcminfo *scp;
+	struct sc_chinfo *ch;
+	struct sai_rate *sr;
+	struct sc_info *sc;
+	int threshold;
+	int i;
+
+	ch = data;
+	scp = ch->parent;
+	sc = scp->sc;
+
+	sr = NULL;
+
+	/* First look for equal frequency. */
+	for (i = 0; rate_map[i].speed != 0; i++) {
+		if (rate_map[i].speed == speed)
+			sr = &rate_map[i];
+	}
+
+	/* If no match, just find nearest. */
+	if (sr == NULL) {
+		for (i = 0; rate_map[i].speed != 0; i++) {
+			sr = &rate_map[i];
+			threshold = sr->speed + ((rate_map[i + 1].speed != 0) ?
+			    ((rate_map[i + 1].speed - sr->speed) >> 1) : 0);
+			if (speed < threshold)
+				break;
+		}
+	}
+
+	sc->sr = sr;
+
+	sai_configure_clock(sc);
+
+	return (sr->speed);
+}
+
+static void
+sai_configure_clock(struct sc_info *sc)
+{
+	struct sai_rate *sr;
+	int reg;
+
+	sr = sc->sr;
+
+	/*
+	 * Manual says that TCR/RCR registers must not be
+	 * altered when TCSR[TE] is set.
+	 * We ignore it since we have problem sometimes
+	 * after re-enabling transmitter (DMA goes stall).
+	 */
+
+	reg = READ4(sc, I2S_TCR2);
+	reg &= ~(0xff << 0);
+	reg |= (sr->div << 0);
+	WRITE4(sc, I2S_TCR2, reg);
+
+	pll4_configure_output(sr->mfi, sr->mfn, sr->mfd);
+}
+
+static uint32_t
+saichan_setblocksize(kobj_t obj, void *data, uint32_t blocksize)
+{
+	struct sc_chinfo *ch = data;
+	struct sc_pcminfo *scp = ch->parent;
+	struct sc_info *sc = scp->sc;
+
+	sndbuf_resize(ch->buffer, sc->dma_size / blocksize, blocksize);
+
+	sc->period = sndbuf_getblksz(ch->buffer);
+	return (sc->period);
+}
+
+uint32_t sai_dma_intr(void *arg, int chn);
+uint32_t
+sai_dma_intr(void *arg, int chn)
+{
+	struct sc_pcminfo *scp;
+	struct sc_chinfo *ch;
+	struct sc_info *sc;
+	struct tcd_conf *tcd;
+
+	scp = arg;
+	ch = &scp->chan[0];
+
+	sc = scp->sc;
+	tcd = sc->tcd;
+
+	sc->pos += (tcd->nbytes * tcd->nmajor);
+	if (sc->pos >= sc->dma_size)
+		sc->pos -= sc->dma_size;
+
+	if (ch->run)
+		chn_intr(ch->channel);
+
+	return (0);
+}
+
+static int
+find_edma_controller(struct sc_info *sc)
+{
+	struct edma_softc *edma_sc;
+	phandle_t node, edma_node;
+	int edma_src_transmit;
+	int edma_mux_group;
+	int edma_device_id;
+	device_t edma_dev;
+	int dts_value;
+	int len;
+	int i;
+
+	if ((node = ofw_bus_get_node(sc->dev)) == -1)
+		return (ENXIO);
+
+	if ((len = OF_getproplen(node, "edma-controller")) <= 0)
+		return (ENXIO);
+	if ((len = OF_getproplen(node, "edma-src-transmit")) <= 0)
+		return (ENXIO);
+	if ((len = OF_getproplen(node, "edma-mux-group")) <= 0)
+		return (ENXIO);
+
+	OF_getprop(node, "edma-src-transmit", &dts_value, len);
+	edma_src_transmit = fdt32_to_cpu(dts_value);
+	OF_getprop(node, "edma-mux-group", &dts_value, len);
+	edma_mux_group = fdt32_to_cpu(dts_value);
+	OF_getprop(node, "edma-controller", &dts_value, len);
+	edma_node = OF_node_from_xref(fdt32_to_cpu(dts_value));
+
+	if ((len = OF_getproplen(edma_node, "device-id")) <= 0) {
+		return (ENXIO);
+	};
+
+	OF_getprop(edma_node, "device-id", &dts_value, len);
+	edma_device_id = fdt32_to_cpu(dts_value);
+
+	edma_sc = NULL;
+
+	for (i = 0; i < EDMA_NUM_DEVICES; i++) {
+		edma_dev = devclass_get_device(devclass_find("edma"), i);
+		if (edma_dev) {
+			edma_sc = device_get_softc(edma_dev);
+			if (edma_sc->device_id == edma_device_id) {
+				/* found */
+				break;
+			};
+
+			edma_sc = NULL;
+		};
+	};
+
+	if (edma_sc == NULL) {
+		device_printf(sc->dev, "no eDMA. can't operate\n");
+		return (ENXIO);
+	};
+
+	sc->edma_sc = edma_sc;
+
+	sc->edma_chnum = edma_sc->channel_configure(edma_sc, edma_mux_group,
+	    edma_src_transmit);
+	if (sc->edma_chnum < 0) {
+		/* cant setup eDMA */
+		return (ENXIO);
+	};
+
+	return (0);
+};
+
+static int
+setup_dma(struct sc_pcminfo *scp)
+{
+	struct tcd_conf *tcd;
+	struct sc_info *sc;
+
+	sc = scp->sc;
+
+	tcd = malloc(sizeof(struct tcd_conf), M_DEVBUF, M_WAITOK | M_ZERO);
+	tcd->channel = sc->edma_chnum;
+	tcd->ih = sai_dma_intr;
+	tcd->ih_user = scp;
+	tcd->saddr = sc->buf_base_phys;
+	tcd->daddr = rman_get_start(sc->res[0]) + I2S_TDR0;
+
+	/*
+	 * Bytes to transfer per each minor loop.
+	 * Hardware FIFO buffer size is 32x32bits.
+	 */
+	tcd->nbytes = 64;
+
+	tcd->nmajor = 512;
+	tcd->smod = 17;	/* dma_size range */
+	tcd->dmod = 0;
+	tcd->esg = 0;
+	tcd->soff = 0x4;
+	tcd->doff = 0;
+	tcd->ssize = 0x2;
+	tcd->dsize = 0x2;
+	tcd->slast = 0;
+	tcd->dlast_sga = 0;
+
+	sc->tcd = tcd;
+
+	sc->edma_sc->dma_setup(sc->edma_sc, sc->tcd);
+
+	return (0);
+}
+
+static int
+saichan_trigger(kobj_t obj, void *data, int go)
+{
+	struct sc_chinfo *ch = data;
+	struct sc_pcminfo *scp = ch->parent;
+	struct sc_info *sc = scp->sc;
+
+	snd_mtxlock(sc->lock);
+
+	switch (go) {
+	case PCMTRIG_START:
+#if 0
+		device_printf(scp->dev, "trigger start\n");
+#endif
+		ch->run = 1;
+		break;
+
+	case PCMTRIG_STOP:
+	case PCMTRIG_ABORT:
+#if 0
+		device_printf(scp->dev, "trigger stop or abort\n");
+#endif
+		ch->run = 0;
+		break;
+	}
+
+	snd_mtxunlock(sc->lock);
+
+	return (0);
+}
+
+static uint32_t
+saichan_getptr(kobj_t obj, void *data)
+{
+	struct sc_pcminfo *scp;
+	struct sc_chinfo *ch;
+	struct sc_info *sc;
+
+	ch = data;
+	scp = ch->parent;
+	sc = scp->sc;
+
+	return (sc->pos);
+}
+
+static uint32_t sai_pfmt[] = {
+	/*
+	 * eDMA doesn't allow 24-bit coping,
+	 * so we use 32.
+	 */
+	SND_FORMAT(AFMT_S32_LE, 2, 0),
+	0
+};
+
+static struct pcmchan_caps sai_pcaps = {44100, 192000, sai_pfmt, 0};
+
+static struct pcmchan_caps *
+saichan_getcaps(kobj_t obj, void *data)
+{
+
+	return (&sai_pcaps);
+}
+
+static kobj_method_t saichan_methods[] = {
+	KOBJMETHOD(channel_init,         saichan_init),
+	KOBJMETHOD(channel_free,         saichan_free),
+	KOBJMETHOD(channel_setformat,    saichan_setformat),
+	KOBJMETHOD(channel_setspeed,     saichan_setspeed),
+	KOBJMETHOD(channel_setblocksize, saichan_setblocksize),
+	KOBJMETHOD(channel_trigger,      saichan_trigger),
+	KOBJMETHOD(channel_getptr,       saichan_getptr),
+	KOBJMETHOD(channel_getcaps,      saichan_getcaps),
+	KOBJMETHOD_END
+};
+CHANNEL_DECLARE(saichan);
+
+static int
+sai_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "fsl,mvf600-sai"))
+		return (ENXIO);
+
+	device_set_desc(dev, "Vybrid Family Synchronous Audio Interface");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static void
+sai_intr(void *arg)
+{
+	struct sc_pcminfo *scp;
+	struct sc_info *sc;
+
+	scp = arg;
+	sc = scp->sc;
+
+	device_printf(sc->dev, "Error I2S_TCSR == 0x%08x\n",
+	    READ4(sc, I2S_TCSR));
+}
+
+static void
+setup_sai(struct sc_info *sc)
+{
+	int reg;
+
+	/*
+	 * TCR/RCR registers must not be altered when TCSR[TE] is set.
+	 */
+
+	reg = READ4(sc, I2S_TCSR);
+	reg &= ~(TCSR_BCE | TCSR_TE | TCSR_FRDE);
+	WRITE4(sc, I2S_TCSR, reg);
+
+	reg = READ4(sc, I2S_TCR3);
+	reg &= ~(TCR3_TCE);
+	WRITE4(sc, I2S_TCR3, reg);
+
+	reg = (64 << TCR1_TFW_S);
+	WRITE4(sc, I2S_TCR1, reg);
+
+	reg = READ4(sc, I2S_TCR2);
+	reg &= ~(TCR2_MSEL_M << TCR2_MSEL_S);
+	reg |= (1 << TCR2_MSEL_S);
+	reg |= (TCR2_BCP | TCR2_BCD);
+	WRITE4(sc, I2S_TCR2, reg);
+
+	sai_configure_clock(sc);
+
+	reg = READ4(sc, I2S_TCR3);
+	reg |= (TCR3_TCE);
+	WRITE4(sc, I2S_TCR3, reg);
+
+	/* Configure to 32-bit I2S mode */
+	reg = READ4(sc, I2S_TCR4);
+	reg &= ~(TCR4_FRSZ_M << TCR4_FRSZ_S);
+	reg |= (1 << TCR4_FRSZ_S); /* 2 words per frame */
+	reg &= ~(TCR4_SYWD_M << TCR4_SYWD_S);
+	reg |= (23 << TCR4_SYWD_S);
+	reg |= (TCR4_MF | TCR4_FSE | TCR4_FSP | TCR4_FSD);
+	WRITE4(sc, I2S_TCR4, reg);
+
+	reg = READ4(sc, I2S_TCR5);
+	reg &= ~(TCR5_W0W_M << TCR5_W0W_S);
+	reg |= (23 << TCR5_W0W_S);
+	reg &= ~(TCR5_WNW_M << TCR5_WNW_S);
+	reg |= (23 << TCR5_WNW_S);
+	reg &= ~(TCR5_FBT_M << TCR5_FBT_S);
+	reg |= (31 << TCR5_FBT_S);
+	WRITE4(sc, I2S_TCR5, reg);
+
+	/* Enable transmitter */
+	reg = READ4(sc, I2S_TCSR);
+	reg |= (TCSR_BCE | TCSR_TE | TCSR_FRDE);
+	reg |= (1 << 10); /* FEIE */
+	WRITE4(sc, I2S_TCSR, reg);
+}
+
+
+static void
+sai_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int err)
+{
+	bus_addr_t *addr;
+
+	if (err)
+		return;
+
+	addr = (bus_addr_t*)arg;
+	*addr = segs[0].ds_addr;
+}
+
+static int
+sai_attach(device_t dev)
+{
+	char status[SND_STATUSLEN];
+	struct sc_pcminfo *scp;
+	struct sc_info *sc;
+	int err;
+
+	sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO);
+	sc->dev = dev;
+	sc->sr = &rate_map[0];
+	sc->pos = 0;
+
+	sc->lock = snd_mtxcreate(device_get_nameunit(dev), "sai softc");
+	if (sc->lock == NULL) {
+		device_printf(dev, "Cant create mtx\n");
+		return (ENXIO);
+	}
+
+	if (bus_alloc_resources(dev, sai_spec, sc->res)) {
+		device_printf(dev, "could not allocate resources\n");
+		return (ENXIO);
+	}
+
+	/* Memory interface */
+	sc->bst = rman_get_bustag(sc->res[0]);
+	sc->bsh = rman_get_bushandle(sc->res[0]);
+
+	/* eDMA */
+	if (find_edma_controller(sc)) {
+		device_printf(dev, "could not find active eDMA\n");
+		return (ENXIO);
+	}
+
+	/* Setup PCM */
+	scp = malloc(sizeof(struct sc_pcminfo), M_DEVBUF, M_NOWAIT | M_ZERO);
+	scp->sc = sc;
+	scp->dev = dev;
+
+	/* DMA */
+	sc->dma_size = 131072;
+
+	/*
+	 * Must use dma_size boundary as modulo feature required.
+	 * Modulo feature allows setup circular buffer.
+	 */
+
+	err = bus_dma_tag_create(
+	    bus_get_dma_tag(sc->dev),
+	    4, sc->dma_size,		/* alignment, boundary */
+	    BUS_SPACE_MAXADDR_32BIT,	/* lowaddr */
+	    BUS_SPACE_MAXADDR,		/* highaddr */
+	    NULL, NULL,			/* filter, filterarg */
+	    sc->dma_size, 1,		/* maxsize, nsegments */
+	    sc->dma_size, 0,		/* maxsegsize, flags */
+	    NULL, NULL,			/* lockfunc, lockarg */
+	    &sc->dma_tag);
+
+	err = bus_dmamem_alloc(sc->dma_tag, (void **)&sc->buf_base,
+	    BUS_DMA_NOWAIT | BUS_DMA_COHERENT, &sc->dma_map);
+	if (err) {
+		device_printf(dev, "cannot allocate framebuffer\n");
+		return (ENXIO);
+	}
+
+	err = bus_dmamap_load(sc->dma_tag, sc->dma_map, sc->buf_base,
+	    sc->dma_size, sai_dmamap_cb, &sc->buf_base_phys, BUS_DMA_NOWAIT);
+	if (err) {
+		device_printf(dev, "cannot load DMA map\n");
+		return (ENXIO);
+	}
+
+	bzero(sc->buf_base, sc->dma_size);
+
+	/* Setup interrupt handler */
+	err = bus_setup_intr(dev, sc->res[1], INTR_MPSAFE | INTR_TYPE_AV,
+	    NULL, sai_intr, scp, &sc->ih);
+	if (err) {
+		device_printf(dev, "Unable to alloc interrupt resource.\n");
+		return (ENXIO);
+	}
+
+	pcm_setflags(dev, pcm_getflags(dev) | SD_F_MPSAFE);
+
+	err = pcm_register(dev, scp, 1, 0);
+	if (err) {
+		device_printf(dev, "Can't register pcm.\n");
+		return (ENXIO);
+	}
+
+	scp->chnum = 0;
+	pcm_addchan(dev, PCMDIR_PLAY, &saichan_class, scp);
+	scp->chnum++;
+
+	snprintf(status, SND_STATUSLEN, "at simplebus");
+	pcm_setstatus(dev, status);
+
+	mixer_init(dev, &saimixer_class, scp);
+
+	setup_dma(scp);
+	setup_sai(sc);
+
+	return (0);
+}
+
+static device_method_t sai_pcm_methods[] = {
+	DEVMETHOD(device_probe,		sai_probe),
+	DEVMETHOD(device_attach,	sai_attach),
+	{ 0, 0 }
+};
+
+static driver_t sai_pcm_driver = {
+	"pcm",
+	sai_pcm_methods,
+	PCM_SOFTC_SIZE,
+};
+
+DRIVER_MODULE(sai, simplebus, sai_pcm_driver, pcm_devclass, 0, 0);
+MODULE_DEPEND(sai, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER);
+MODULE_VERSION(sai, 1);


Property changes on: trunk/sys/arm/freescale/vybrid/vf_sai.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/vybrid/vf_src.c
===================================================================
--- trunk/sys/arm/freescale/vybrid/vf_src.c	                        (rev 0)
+++ trunk/sys/arm/freescale/vybrid/vf_src.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,151 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Ruslan Bukin <br at bsdpad.com>
+ * 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.
+ */
+
+/*
+ * Vybrid Family System Reset Controller (SRC)
+ * Chapter 18, Vybrid Reference Manual, Rev. 5, 07/2013
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/freescale/vybrid/vf_src.c 266152 2014-05-15 16:11:06Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/timeet.h>
+#include <sys/timetc.h>
+#include <sys/watchdog.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#include <arm/freescale/vybrid/vf_src.h>
+#include <arm/freescale/vybrid/vf_common.h>
+
+#define	SRC_SCR		0x00	/* SRC Control Register */
+#define	SRC_SBMR1	0x04	/* SRC Boot Mode Register 1 */
+#define	SRC_SRSR	0x08	/* SRC Status Register */
+#define	SRC_SECR	0x0C	/* SRC_SECR */
+#define	SRC_SICR	0x14	/* SRC Reset Interrupt Configuration Register */
+#define	SRC_SIMR	0x18	/* SRC Interrupt Masking Register */
+#define	SRC_SBMR2	0x1C	/* SRC Boot Mode Register 2 */
+#define	SRC_GPR0	0x20	/* General Purpose Register */
+#define	SRC_GPR1	0x24	/* General Purpose Register */
+#define	SRC_GPR2	0x28	/* General Purpose Register */
+#define	SRC_GPR3	0x2C	/* General Purpose Register */
+#define	SRC_GPR4	0x30	/* General Purpose Register */
+#define	SRC_MISC0	0x4C	/* MISC0 */
+#define	SRC_MISC1	0x50	/* MISC1 */
+#define	SRC_MISC2	0x54	/* MISC2 */
+#define	SRC_MISC3	0x58	/* MISC3 */
+
+struct src_softc {
+	struct resource		*res[1];
+	bus_space_tag_t		bst;
+	bus_space_handle_t	bsh;
+};
+
+struct src_softc *src_sc;
+
+static struct resource_spec src_spec[] = {
+	{ SYS_RES_MEMORY,       0,      RF_ACTIVE },
+	{ -1, 0 }
+};
+
+int
+src_swreset(void)
+{
+
+	if (src_sc == NULL)
+		return (1);
+
+	WRITE4(src_sc, SRC_SCR, SW_RST);
+
+	return (0);
+}
+
+static int
+src_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "fsl,mvf600-src"))
+		return (ENXIO);
+
+	device_set_desc(dev, "Vybrid Family System Reset Controller");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+src_attach(device_t dev)
+{
+	struct src_softc *sc;
+
+	sc = device_get_softc(dev);
+
+	if (bus_alloc_resources(dev, src_spec, sc->res)) {
+		device_printf(dev, "could not allocate resources\n");
+		return (ENXIO);
+	}
+
+	/* Memory interface */
+	sc->bst = rman_get_bustag(sc->res[0]);
+	sc->bsh = rman_get_bushandle(sc->res[0]);
+
+	src_sc = sc;
+
+	return (0);
+}
+
+static device_method_t src_methods[] = {
+	DEVMETHOD(device_probe,		src_probe),
+	DEVMETHOD(device_attach,	src_attach),
+	{ 0, 0 }
+};
+
+static driver_t src_driver = {
+	"src",
+	src_methods,
+	sizeof(struct src_softc),
+};
+
+static devclass_t src_devclass;
+
+DRIVER_MODULE(src, simplebus, src_driver, src_devclass, 0, 0);


Property changes on: trunk/sys/arm/freescale/vybrid/vf_src.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/vybrid/vf_src.h
===================================================================
--- trunk/sys/arm/freescale/vybrid/vf_src.h	                        (rev 0)
+++ trunk/sys/arm/freescale/vybrid/vf_src.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,31 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Ruslan Bukin <br at bsdpad.com>
+ * 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: stable/10/sys/arm/freescale/vybrid/vf_src.h 258057 2013-11-12 18:02:56Z br $
+ */
+
+#define	SW_RST	(1 << 12)	/* Software reset */
+int src_swreset(void);


Property changes on: trunk/sys/arm/freescale/vybrid/vf_src.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/vybrid/vf_tcon.c
===================================================================
--- trunk/sys/arm/freescale/vybrid/vf_tcon.c	                        (rev 0)
+++ trunk/sys/arm/freescale/vybrid/vf_tcon.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,139 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014 Ruslan Bukin <br at bsdpad.com>
+ * 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.
+ */
+
+/*
+ * Vybrid Family Timing Controller (TCON)
+ * Chapter 58, Vybrid Reference Manual, Rev. 5, 07/2013
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/freescale/vybrid/vf_tcon.c 266155 2014-05-15 16:23:24Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/timeet.h>
+#include <sys/timetc.h>
+#include <sys/watchdog.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#include <arm/freescale/vybrid/vf_common.h>
+
+#define	TCON0_CTRL1	0x00
+#define	TCON_BYPASS	(1 << 29)
+
+struct tcon_softc {
+	struct resource		*res[1];
+	bus_space_tag_t		bst;
+	bus_space_handle_t	bsh;
+};
+
+struct tcon_softc *tcon_sc;
+
+static struct resource_spec tcon_spec[] = {
+	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
+	{ -1, 0 }
+};
+
+uint32_t
+tcon_bypass(void)
+{
+	struct tcon_softc *sc;
+
+	if (tcon_sc == NULL)
+		return (1);
+
+	sc = tcon_sc;
+
+	WRITE4(tcon_sc, TCON0_CTRL1, TCON_BYPASS);
+
+	return (0);
+}
+
+static int
+tcon_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "fsl,mvf600-tcon"))
+		return (ENXIO);
+
+	device_set_desc(dev, "Vybrid Family Timing Controller (TCON)");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+tcon_attach(device_t dev)
+{
+	struct tcon_softc *sc;
+
+	sc = device_get_softc(dev);
+
+	if (bus_alloc_resources(dev, tcon_spec, sc->res)) {
+		device_printf(dev, "could not allocate resources\n");
+		return (ENXIO);
+	}
+
+	/* Memory interface */
+	sc->bst = rman_get_bustag(sc->res[0]);
+	sc->bsh = rman_get_bushandle(sc->res[0]);
+
+	tcon_sc = sc;
+
+	return (0);
+}
+
+static device_method_t tcon_methods[] = {
+	DEVMETHOD(device_probe,		tcon_probe),
+	DEVMETHOD(device_attach,	tcon_attach),
+	{ 0, 0 }
+};
+
+static driver_t tcon_driver = {
+	"tcon",
+	tcon_methods,
+	sizeof(struct tcon_softc),
+};
+
+static devclass_t tcon_devclass;
+
+DRIVER_MODULE(tcon, simplebus, tcon_driver, tcon_devclass, 0, 0);


Property changes on: trunk/sys/arm/freescale/vybrid/vf_tcon.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/freescale/vybrid/vf_uart.c
===================================================================
--- trunk/sys/arm/freescale/vybrid/vf_uart.c	                        (rev 0)
+++ trunk/sys/arm/freescale/vybrid/vf_uart.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,517 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Ruslan Bukin <br at bsdpad.com>
+ * 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.
+ */
+
+/*
+ * Vybrid Family Universal Asynchronous Receiver/Transmitter
+ * Chapter 49, Vybrid Reference Manual, Rev. 5, 07/2013
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/freescale/vybrid/vf_uart.c 283327 2015-05-23 20:54:25Z ian $");
+
+#include "opt_ddb.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/kdb.h>
+#include <machine/bus.h>
+#include <machine/fdt.h>
+
+#include <dev/uart/uart.h>
+#include <dev/uart/uart_cpu.h>
+#include <dev/uart/uart_cpu_fdt.h>
+#include <dev/uart/uart_bus.h>
+
+#include "uart_if.h"
+
+#define	UART_BDH	0x00	/* Baud Rate Registers: High */
+#define	UART_BDL	0x01	/* Baud Rate Registers: Low */
+#define	UART_C1		0x02	/* Control Register 1 */
+#define	UART_C2		0x03	/* Control Register 2 */
+#define	UART_S1		0x04	/* Status Register 1 */
+#define	UART_S2		0x05	/* Status Register 2 */
+#define	UART_C3		0x06	/* Control Register 3 */
+#define	UART_D		0x07	/* Data Register */
+#define	UART_MA1	0x08	/* Match Address Registers 1 */
+#define	UART_MA2	0x09	/* Match Address Registers 2 */
+#define	UART_C4		0x0A	/* Control Register 4 */
+#define	UART_C5		0x0B	/* Control Register 5 */
+#define	UART_ED		0x0C	/* Extended Data Register */
+#define	UART_MODEM	0x0D	/* Modem Register */
+#define	UART_IR		0x0E	/* Infrared Register */
+#define	UART_PFIFO	0x10	/* FIFO Parameters */
+#define	UART_CFIFO	0x11	/* FIFO Control Register */
+#define	UART_SFIFO	0x12	/* FIFO Status Register */
+#define	UART_TWFIFO	0x13	/* FIFO Transmit Watermark */
+#define	UART_TCFIFO	0x14	/* FIFO Transmit Count */
+#define	UART_RWFIFO	0x15	/* FIFO Receive Watermark */
+#define	UART_RCFIFO	0x16	/* FIFO Receive Count */
+#define	UART_C7816	0x18	/* 7816 Control Register */
+#define	UART_IE7816	0x19	/* 7816 Interrupt Enable Register */
+#define	UART_IS7816	0x1A	/* 7816 Interrupt Status Register */
+#define	UART_WP7816T0	0x1B	/* 7816 Wait Parameter Register */
+#define	UART_WP7816T1	0x1B	/* 7816 Wait Parameter Register */
+#define	UART_WN7816	0x1C	/* 7816 Wait N Register */
+#define	UART_WF7816	0x1D	/* 7816 Wait FD Register */
+#define	UART_ET7816	0x1E	/* 7816 Error Threshold Register */
+#define	UART_TL7816	0x1F	/* 7816 Transmit Length Register */
+#define	UART_C6		0x21	/* CEA709.1-B Control Register 6 */
+#define	UART_PCTH	0x22	/* CEA709.1-B Packet Cycle Time Counter High */
+#define	UART_PCTL	0x23	/* CEA709.1-B Packet Cycle Time Counter Low */
+#define	UART_B1T	0x24	/* CEA709.1-B Beta1 Timer */
+#define	UART_SDTH	0x25	/* CEA709.1-B Secondary Delay Timer High */
+#define	UART_SDTL	0x26	/* CEA709.1-B Secondary Delay Timer Low */
+#define	UART_PRE	0x27	/* CEA709.1-B Preamble */
+#define	UART_TPL	0x28	/* CEA709.1-B Transmit Packet Length */
+#define	UART_IE		0x29	/* CEA709.1-B Interrupt Enable Register */
+#define	UART_WB		0x2A	/* CEA709.1-B WBASE */
+#define	UART_S3		0x2B	/* CEA709.1-B Status Register */
+#define	UART_S4		0x2C	/* CEA709.1-B Status Register */
+#define	UART_RPL	0x2D	/* CEA709.1-B Received Packet Length */
+#define	UART_RPREL	0x2E	/* CEA709.1-B Received Preamble Length */
+#define	UART_CPW	0x2F	/* CEA709.1-B Collision Pulse Width */
+#define	UART_RIDT	0x30	/* CEA709.1-B Receive Indeterminate Time */
+#define	UART_TIDT	0x31	/* CEA709.1-B Transmit Indeterminate Time */
+
+#define	UART_C2_TE	(1 << 3)	/* Transmitter Enable */
+#define	UART_C2_TIE	(1 << 7)	/* Transmitter Interrupt Enable */
+#define	UART_C2_RE	(1 << 2)	/* Receiver Enable */
+#define	UART_C2_RIE	(1 << 5)	/* Receiver Interrupt Enable */
+#define	UART_S1_TDRE	(1 << 7)	/* Transmit Data Register Empty Flag */
+#define	UART_S1_RDRF	(1 << 5)	/* Receive Data Register Full Flag */
+#define	UART_S2_LBKDIF	(1 << 7)	/* LIN Break Detect Interrupt Flag */
+
+#define	UART_C4_BRFA	0x1f	/* Baud Rate Fine Adjust */
+#define	UART_BDH_SBR	0x1f	/* UART Baud Rate Bits */
+
+/*
+ * Low-level UART interface.
+ */
+static int vf_uart_probe(struct uart_bas *bas);
+static void vf_uart_init(struct uart_bas *bas, int, int, int, int);
+static void vf_uart_term(struct uart_bas *bas);
+static void vf_uart_putc(struct uart_bas *bas, int);
+static int vf_uart_rxready(struct uart_bas *bas);
+static int vf_uart_getc(struct uart_bas *bas, struct mtx *);
+
+void uart_reinit(struct uart_softc *,int,int);
+
+static struct uart_ops uart_vybrid_ops = {
+	.probe = vf_uart_probe,
+	.init = vf_uart_init,
+	.term = vf_uart_term,
+	.putc = vf_uart_putc,
+	.rxready = vf_uart_rxready,
+	.getc = vf_uart_getc,
+};
+
+static int
+vf_uart_probe(struct uart_bas *bas)
+{
+
+	return (0);
+}
+
+static void
+vf_uart_init(struct uart_bas *bas, int baudrate, int databits,
+    int stopbits, int parity)
+{
+
+}
+
+static void
+vf_uart_term(struct uart_bas *bas)
+{
+
+}
+
+static void
+vf_uart_putc(struct uart_bas *bas, int c)
+{
+
+	while (!(uart_getreg(bas, UART_S1) & UART_S1_TDRE))
+		;
+
+	uart_setreg(bas, UART_D, c);
+}
+
+static int
+vf_uart_rxready(struct uart_bas *bas)
+{
+	int usr1;
+
+	usr1 = uart_getreg(bas, UART_S1);
+	if (usr1 & UART_S1_RDRF) {
+		return (1);
+	}
+
+	return (0);
+}
+
+static int
+vf_uart_getc(struct uart_bas *bas, struct mtx *hwmtx)
+{
+	int c;
+
+	uart_lock(hwmtx);
+
+	while (!(uart_getreg(bas, UART_S1) & UART_S1_RDRF))
+		;
+
+	c = uart_getreg(bas, UART_D);
+	uart_unlock(hwmtx);
+
+	return (c & 0xff);
+}
+
+/*
+ * High-level UART interface.
+ */
+struct vf_uart_softc {
+	struct uart_softc base;
+};
+
+void
+uart_reinit(struct uart_softc *sc, int clkspeed, int baud)
+{
+	struct uart_bas *bas;
+	int sbr;
+	int brfa;
+	int reg;
+
+	bas = &sc->sc_bas;
+	if (!bas) {
+		printf("Error: cant reconfigure bas\n");
+		return;
+	}
+
+	uart_setreg(bas, UART_MODEM, 0x00);
+
+	/*
+	 * Disable transmitter and receiver
+	 * for a while.
+	 */
+	reg = uart_getreg(bas, UART_C2);
+	reg &= ~(UART_C2_RE | UART_C2_TE);
+	uart_setreg(bas, UART_C2, 0x00);
+
+	uart_setreg(bas, UART_C1, 0x00);
+
+	sbr = (uint16_t) (clkspeed / (baud * 16));
+	brfa = (clkspeed / baud) - (sbr * 16);
+
+	reg = uart_getreg(bas, UART_BDH);
+	reg &= ~UART_BDH_SBR;
+	reg |= ((sbr & 0x1f00) >> 8);
+	uart_setreg(bas, UART_BDH, reg);
+
+	reg = sbr & 0x00ff;
+	uart_setreg(bas, UART_BDL, reg);
+
+	reg = uart_getreg(bas, UART_C4);
+	reg &= ~UART_C4_BRFA;
+	reg |= (brfa & UART_C4_BRFA);
+	uart_setreg(bas, UART_C4, reg);
+
+	reg = uart_getreg(bas, UART_C2);
+	reg |= (UART_C2_RE | UART_C2_TE);
+	uart_setreg(bas, UART_C2, reg);
+
+}
+
+static int vf_uart_bus_attach(struct uart_softc *);
+static int vf_uart_bus_detach(struct uart_softc *);
+static int vf_uart_bus_flush(struct uart_softc *, int);
+static int vf_uart_bus_getsig(struct uart_softc *);
+static int vf_uart_bus_ioctl(struct uart_softc *, int, intptr_t);
+static int vf_uart_bus_ipend(struct uart_softc *);
+static int vf_uart_bus_param(struct uart_softc *, int, int, int, int);
+static int vf_uart_bus_probe(struct uart_softc *);
+static int vf_uart_bus_receive(struct uart_softc *);
+static int vf_uart_bus_setsig(struct uart_softc *, int);
+static int vf_uart_bus_transmit(struct uart_softc *);
+
+static kobj_method_t vf_uart_methods[] = {
+	KOBJMETHOD(uart_attach,		vf_uart_bus_attach),
+	KOBJMETHOD(uart_detach,		vf_uart_bus_detach),
+	KOBJMETHOD(uart_flush,		vf_uart_bus_flush),
+	KOBJMETHOD(uart_getsig,		vf_uart_bus_getsig),
+	KOBJMETHOD(uart_ioctl,		vf_uart_bus_ioctl),
+	KOBJMETHOD(uart_ipend,		vf_uart_bus_ipend),
+	KOBJMETHOD(uart_param,		vf_uart_bus_param),
+	KOBJMETHOD(uart_probe,		vf_uart_bus_probe),
+	KOBJMETHOD(uart_receive,	vf_uart_bus_receive),
+	KOBJMETHOD(uart_setsig,		vf_uart_bus_setsig),
+	KOBJMETHOD(uart_transmit,	vf_uart_bus_transmit),
+	{ 0, 0 }
+};
+
+static struct uart_class uart_vybrid_class = {
+	"vybrid",
+	vf_uart_methods,
+	sizeof(struct vf_uart_softc),
+	.uc_ops = &uart_vybrid_ops,
+	.uc_range = 0x100,
+	.uc_rclk = 24000000 /* TODO: get value from CCM */
+};
+
+static struct ofw_compat_data compat_data[] = {
+	{"fsl,mvf600-uart",	(uintptr_t)&uart_vybrid_class},
+	{NULL,			(uintptr_t)NULL},
+};
+UART_FDT_CLASS_AND_DEVICE(compat_data);
+
+static int
+vf_uart_bus_attach(struct uart_softc *sc)
+{
+	struct uart_bas *bas;
+	int reg;
+
+	bas = &sc->sc_bas;
+
+	sc->sc_hwiflow = 0;
+	sc->sc_hwoflow = 0;
+
+	uart_reinit(sc, 66000000, 115200);
+
+	reg = uart_getreg(bas, UART_C2);
+	if (sc->sc_sysdev != NULL && sc->sc_sysdev->type == UART_DEV_CONSOLE) {
+		reg &= ~UART_C2_RIE;
+	} else {
+		reg |= UART_C2_RIE;
+	}
+	uart_setreg(bas, UART_C2, reg);
+
+	return (0);
+}
+
+static int
+vf_uart_bus_detach(struct uart_softc *sc)
+{
+
+	/* TODO */
+	return (0);
+}
+
+static int
+vf_uart_bus_flush(struct uart_softc *sc, int what)
+{
+
+	/* TODO */
+	return (0);
+}
+
+static int
+vf_uart_bus_getsig(struct uart_softc *sc)
+{
+
+	/* TODO */
+	return (0);
+}
+
+static int
+vf_uart_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
+{
+	struct uart_bas *bas;
+	int error;
+
+	bas = &sc->sc_bas;
+	error = 0;
+	uart_lock(sc->sc_hwmtx);
+	switch (request) {
+	case UART_IOCTL_BREAK:
+	/* TODO */
+		break;
+	case UART_IOCTL_BAUD:
+	/* TODO */
+		*(int*)data = 115200;
+		break;
+	default:
+		error = EINVAL;
+		break;
+	}
+	uart_unlock(sc->sc_hwmtx);
+
+	return (error);
+}
+
+static int
+vf_uart_bus_ipend(struct uart_softc *sc)
+{
+	struct uart_bas *bas;
+	int ipend;
+	uint32_t usr1, usr2;
+	int reg;
+	int sfifo;
+
+	bas = &sc->sc_bas;
+	ipend = 0;
+
+	uart_lock(sc->sc_hwmtx);
+
+	usr1 = uart_getreg(bas, UART_S1);
+	usr2 = uart_getreg(bas, UART_S2);
+	sfifo = uart_getreg(bas, UART_SFIFO);
+
+	/* ack usr2 */
+	uart_setreg(bas, UART_S2, usr2);
+
+	if (usr1 & UART_S1_TDRE) {
+		reg = uart_getreg(bas, UART_C2);
+		reg &= ~(UART_C2_TIE);
+		uart_setreg(bas, UART_C2, reg);
+
+		if (sc->sc_txbusy != 0) {
+			ipend |= SER_INT_TXIDLE;
+		}
+	}
+
+	if (usr1 & UART_S1_RDRF) {
+		reg = uart_getreg(bas, UART_C2);
+		reg &= ~(UART_C2_RIE);
+		uart_setreg(bas, UART_C2, reg);
+
+		ipend |= SER_INT_RXREADY;
+	}
+
+	if (usr2 & UART_S2_LBKDIF) {
+		ipend |= SER_INT_BREAK;
+	}
+
+	uart_unlock(sc->sc_hwmtx);
+
+	return (ipend);
+}
+
+static int
+vf_uart_bus_param(struct uart_softc *sc, int baudrate, int databits,
+    int stopbits, int parity)
+{
+
+	uart_lock(sc->sc_hwmtx);
+	vf_uart_init(&sc->sc_bas, baudrate, databits, stopbits, parity);
+	uart_unlock(sc->sc_hwmtx);
+
+	return (0);
+}
+
+static int
+vf_uart_bus_probe(struct uart_softc *sc)
+{
+	int error;
+
+	error = vf_uart_probe(&sc->sc_bas);
+	if (error)
+		return (error);
+
+	sc->sc_rxfifosz = 1;
+	sc->sc_txfifosz = 1;
+
+	device_set_desc(sc->sc_dev, "Vybrid Family UART");
+	return (0);
+}
+
+static int
+vf_uart_bus_receive(struct uart_softc *sc)
+{
+	struct uart_bas *bas;
+	int reg;
+	int c;
+
+	bas = &sc->sc_bas;
+	uart_lock(sc->sc_hwmtx);
+
+	/* Read FIFO */
+	while (uart_getreg(bas, UART_S1) & UART_S1_RDRF) {
+		if (uart_rx_full(sc)) {
+		/* No space left in input buffer */
+			sc->sc_rxbuf[sc->sc_rxput] = UART_STAT_OVERRUN;
+			break;
+		}
+
+		c = uart_getreg(bas, UART_D);
+		uart_rx_put(sc, c);
+	}
+
+	/* Reenable Data Ready interrupt */
+	reg = uart_getreg(bas, UART_C2);
+	reg |= (UART_C2_RIE);
+	uart_setreg(bas, UART_C2, reg);
+
+	uart_unlock(sc->sc_hwmtx);
+	return (0);
+}
+
+static int
+vf_uart_bus_setsig(struct uart_softc *sc, int sig)
+{
+	struct uart_bas *bas;
+	int reg;
+
+	/* TODO: implement (?) */
+
+	/* XXX workaround to have working console on mount prompt */
+	/* Enable RX interrupt */
+	bas = &sc->sc_bas;
+	if (sc->sc_sysdev != NULL && sc->sc_sysdev->type == UART_DEV_CONSOLE) {
+		reg = uart_getreg(bas, UART_C2);
+		reg |= (UART_C2_RIE);
+		uart_setreg(bas, UART_C2, reg);
+	}
+
+	return (0);
+}
+
+static int
+vf_uart_bus_transmit(struct uart_softc *sc)
+{
+	struct uart_bas *bas = &sc->sc_bas;
+	int i;
+	int reg;
+
+	bas = &sc->sc_bas;
+	uart_lock(sc->sc_hwmtx);
+
+	/* Fill TX FIFO */
+	for (i = 0; i < sc->sc_txdatasz; i++) {
+		uart_setreg(bas, UART_D, sc->sc_txbuf[i] & 0xff);
+		uart_barrier(&sc->sc_bas);
+	}
+
+	sc->sc_txbusy = 1;
+
+	/* Call me when ready */
+	reg = uart_getreg(bas, UART_C2);
+	reg |= (UART_C2_TIE);
+	uart_setreg(bas, UART_C2, reg);
+
+	uart_unlock(sc->sc_hwmtx);
+
+	return (0);
+}


Property changes on: trunk/sys/arm/freescale/vybrid/vf_uart.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/_align.h
===================================================================
--- trunk/sys/arm/include/_align.h	                        (rev 0)
+++ trunk/sys/arm/include/_align.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,53 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2001 David E. O'Brien
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ *	from: @(#)param.h	5.8 (Berkeley) 6/28/91
+ * $FreeBSD: stable/10/sys/arm/include/_align.h 196994 2009-09-08 20:45:40Z phk $
+ */
+
+#ifndef _ARM_INCLUDE__ALIGN_H_
+#define	_ARM_INCLUDE__ALIGN_H_
+
+/*
+ * Round p (pointer or byte index) up to a correctly-aligned value
+ * for all data types (int, long, ...).   The result is unsigned int
+ * and must be cast to any desired pointer type.
+ */
+#define	_ALIGNBYTES	(sizeof(int) - 1)
+#define	_ALIGN(p)	(((unsigned)(p) + _ALIGNBYTES) & ~_ALIGNBYTES)
+
+#endif /* !_ARM_INCLUDE__ALIGN_H_ */


Property changes on: trunk/sys/arm/include/_align.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/_bus.h
===================================================================
--- trunk/sys/arm/include/_bus.h	                        (rev 0)
+++ trunk/sys/arm/include/_bus.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,47 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2005 M. Warner Losh.
+ * 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,
+ *    without modification, immediately at the beginning of the file.
+ * 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: stable/10/sys/arm/include/_bus.h 176589 2008-02-26 11:45:32Z rwatson $
+ */
+
+#ifndef ARM_INCLUDE__BUS_H
+#define ARM_INCLUDE__BUS_H
+
+/*
+ * Addresses (in bus space).
+ */
+typedef u_long bus_addr_t;
+typedef u_long bus_size_t;
+
+/*
+ * Access methods for bus space.
+ */
+typedef struct bus_space *bus_space_tag_t;
+typedef u_long bus_space_handle_t;
+
+#endif /* ARM_INCLUDE__BUS_H */


Property changes on: trunk/sys/arm/include/_bus.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/_inttypes.h
===================================================================
--- trunk/sys/arm/include/_inttypes.h	                        (rev 0)
+++ trunk/sys/arm/include/_inttypes.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,214 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Klaus Klein.
+ *
+ * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
+ *
+ *	From: $NetBSD: int_fmtio.h,v 1.2 2001/04/26 16:25:21 kleink Exp $
+ * $FreeBSD: stable/10/sys/arm/include/_inttypes.h 203974 2010-02-16 21:59:17Z imp $
+ */
+
+#ifndef _MACHINE_INTTYPES_H_
+#define _MACHINE_INTTYPES_H_
+
+/*
+ * Macros for format specifiers.
+ */
+
+/* fprintf(3) macros for signed integers. */
+
+#define	PRId8		"d"	/* int8_t */
+#define	PRId16		"d"	/* int16_t */
+#define	PRId32		"d"	/* int32_t */
+#define	PRId64		"lld"	/* int64_t */
+#define	PRIdLEAST8	"d"	/* int_least8_t */
+#define	PRIdLEAST16	"d"	/* int_least16_t */
+#define	PRIdLEAST32	"d"	/* int_least32_t */
+#define	PRIdLEAST64	"lld"	/* int_least64_t */
+#define	PRIdFAST8	"d"	/* int_fast8_t */
+#define	PRIdFAST16	"d"	/* int_fast16_t */
+#define	PRIdFAST32	"d"	/* int_fast32_t */
+#define	PRIdFAST64	"lld"	/* int_fast64_t */
+#define	PRIdMAX		"jd"	/* intmax_t */
+#define	PRIdPTR		"d"	/* intptr_t */
+
+#define	PRIi8		"i"	/* int8_t */
+#define	PRIi16		"i"	/* int16_t */
+#define	PRIi32		"i"	/* int32_t */
+#define	PRIi64		"lli"	/* int64_t */
+#define	PRIiLEAST8	"i"	/* int_least8_t  */
+#define	PRIiLEAST16	"i"	/* int_least16_t */
+#define	PRIiLEAST32	"i"	/* int_least32_t */
+#define	PRIiLEAST64	"lli"	/* int_least64_t */
+#define	PRIiFAST8	"i"	/* int_fast8_t */
+#define	PRIiFAST16	"i"	/* int_fast16_t */
+#define	PRIiFAST32	"i"	/* int_fast32_t */
+#define	PRIiFAST64	"lli"	/* int_fast64_t */
+#define	PRIiMAX		"ji"	/* intmax_t */
+#define	PRIiPTR		"i"	/* intptr_t */
+
+/* fprintf(3) macros for unsigned integers. */
+
+#define	PRIo8		"o"	/* uint8_t */
+#define	PRIo16		"o"	/* uint16_t */
+#define	PRIo32		"o"	/* uint32_t */
+#define	PRIo64		"llo"	/* uint64_t */
+#define	PRIoLEAST8	"o"	/* uint_least8_t */
+#define	PRIoLEAST16	"o"	/* uint_least16_t */
+#define	PRIoLEAST32	"o"	/* uint_least32_t */
+#define	PRIoLEAST64	"llo"	/* uint_least64_t */
+#define	PRIoFAST8	"o"	/* uint_fast8_t */
+#define	PRIoFAST16	"o"	/* uint_fast16_t */
+#define	PRIoFAST32	"o"	/* uint_fast32_t */
+#define	PRIoFAST64	"llo"	/* uint_fast64_t */
+#define	PRIoMAX		"jo"	/* uintmax_t */
+#define	PRIoPTR		"o"	/* uintptr_t */
+
+#define	PRIu8		"u"	/* uint8_t */
+#define	PRIu16		"u"	/* uint16_t */
+#define	PRIu32		"u"	/* uint32_t */
+#define	PRIu64		"llu"	/* uint64_t */
+#define	PRIuLEAST8	"u"	/* uint_least8_t */
+#define	PRIuLEAST16	"u"	/* uint_least16_t */
+#define	PRIuLEAST32	"u"	/* uint_least32_t */
+#define	PRIuLEAST64	"llu"	/* uint_least64_t */
+#define	PRIuFAST8	"u"	/* uint_fast8_t */
+#define	PRIuFAST16	"u"	/* uint_fast16_t */
+#define	PRIuFAST32	"u"	/* uint_fast32_t */
+#define	PRIuFAST64	"llu"	/* uint_fast64_t */
+#define	PRIuMAX		"ju"	/* uintmax_t */
+#define	PRIuPTR		"u"	/* uintptr_t */
+
+#define	PRIx8		"x"	/* uint8_t */
+#define	PRIx16		"x"	/* uint16_t */
+#define	PRIx32		"x"	/* uint32_t */
+#define	PRIx64		"llx"	/* uint64_t */
+#define	PRIxLEAST8	"x"	/* uint_least8_t */
+#define	PRIxLEAST16	"x"	/* uint_least16_t */
+#define	PRIxLEAST32	"x"	/* uint_least32_t */
+#define	PRIxLEAST64	"llx"	/* uint_least64_t */
+#define	PRIxFAST8	"x"	/* uint_fast8_t */
+#define	PRIxFAST16	"x"	/* uint_fast16_t */
+#define	PRIxFAST32	"x"	/* uint_fast32_t */
+#define	PRIxFAST64	"llx"	/* uint_fast64_t */
+#define	PRIxMAX		"jx"	/* uintmax_t */
+#define	PRIxPTR		"x"	/* uintptr_t */
+
+#define	PRIX8		"X"	/* uint8_t */
+#define	PRIX16		"X"	/* uint16_t */
+#define	PRIX32		"X"	/* uint32_t */
+#define	PRIX64		"llX"	/* uint64_t */
+#define	PRIXLEAST8	"X"	/* uint_least8_t */
+#define	PRIXLEAST16	"X"	/* uint_least16_t */
+#define	PRIXLEAST32	"X"	/* uint_least32_t */
+#define	PRIXLEAST64	"llX"	/* uint_least64_t */
+#define	PRIXFAST8	"X"	/* uint_fast8_t */
+#define	PRIXFAST16	"X"	/* uint_fast16_t */
+#define	PRIXFAST32	"X"	/* uint_fast32_t */
+#define	PRIXFAST64	"llX"	/* uint_fast64_t */
+#define	PRIXMAX		"jX"	/* uintmax_t */
+#define	PRIXPTR		"X"	/* uintptr_t */
+
+/* fscanf(3) macros for signed integers. */
+
+#define	SCNd8		"hhd"	/* int8_t */
+#define	SCNd16		"hd"	/* int16_t */
+#define	SCNd32		"d"	/* int32_t */
+#define	SCNd64		"lld"	/* int64_t */
+#define	SCNdLEAST8	"hhd"	/* int_least8_t */
+#define	SCNdLEAST16	"hd"	/* int_least16_t */
+#define	SCNdLEAST32	"d"	/* int_least32_t */
+#define	SCNdLEAST64	"lld"	/* int_least64_t */
+#define	SCNdFAST8	"d"	/* int_fast8_t */
+#define	SCNdFAST16	"d"	/* int_fast16_t */
+#define	SCNdFAST32	"d"	/* int_fast32_t */
+#define	SCNdFAST64	"lld"	/* int_fast64_t */
+#define	SCNdMAX		"jd"	/* intmax_t */
+#define	SCNdPTR		"d"	/* intptr_t */
+
+#define	SCNi8		"hhi"	/* int8_t */
+#define	SCNi16		"hi"	/* int16_t */
+#define	SCNi32		"i"	/* int32_t */
+#define	SCNi64		"lli"	/* int64_t */
+#define	SCNiLEAST8	"hhi"	/* int_least8_t */
+#define	SCNiLEAST16	"hi"	/* int_least16_t */
+#define	SCNiLEAST32	"i"	/* int_least32_t */
+#define	SCNiLEAST64	"lli"	/* int_least64_t */
+#define	SCNiFAST8	"i"	/* int_fast8_t */
+#define	SCNiFAST16	"i"	/* int_fast16_t */
+#define	SCNiFAST32	"i"	/* int_fast32_t */
+#define	SCNiFAST64	"lli"	/* int_fast64_t */
+#define	SCNiMAX		"ji"	/* intmax_t */
+#define	SCNiPTR		"i"	/* intptr_t */
+
+/* fscanf(3) macros for unsigned integers. */
+
+#define	SCNo8		"hho"	/* uint8_t */
+#define	SCNo16		"ho"	/* uint16_t */
+#define	SCNo32		"o"	/* uint32_t */
+#define	SCNo64		"llo"	/* uint64_t */
+#define	SCNoLEAST8	"hho"	/* uint_least8_t */
+#define	SCNoLEAST16	"ho"	/* uint_least16_t */
+#define	SCNoLEAST32	"o"	/* uint_least32_t */
+#define	SCNoLEAST64	"llo"	/* uint_least64_t */
+#define	SCNoFAST8	"o"	/* uint_fast8_t */
+#define	SCNoFAST16	"o"	/* uint_fast16_t */
+#define	SCNoFAST32	"o"	/* uint_fast32_t */
+#define	SCNoFAST64	"llo"	/* uint_fast64_t */
+#define	SCNoMAX		"jo"	/* uintmax_t */
+#define	SCNoPTR		"o"	/* uintptr_t */
+
+#define	SCNu8		"hhu"	/* uint8_t */
+#define	SCNu16		"hu"	/* uint16_t */
+#define	SCNu32		"u"	/* uint32_t */
+#define	SCNu64		"llu"	/* uint64_t */
+#define	SCNuLEAST8	"hhu"	/* uint_least8_t */
+#define	SCNuLEAST16	"hu"	/* uint_least16_t */
+#define	SCNuLEAST32	"u"	/* uint_least32_t */
+#define	SCNuLEAST64	"llu"	/* uint_least64_t */
+#define	SCNuFAST8	"u"	/* uint_fast8_t */
+#define	SCNuFAST16	"u"	/* uint_fast16_t */
+#define	SCNuFAST32	"u"	/* uint_fast32_t */
+#define	SCNuFAST64	"llu"	/* uint_fast64_t */
+#define	SCNuMAX		"ju"	/* uintmax_t */
+#define	SCNuPTR		"u"	/* uintptr_t */
+
+#define	SCNx8		"hhx"	/* uint8_t */
+#define	SCNx16		"hx"	/* uint16_t */
+#define	SCNx32		"x"	/* uint32_t */
+#define	SCNx64		"llx"	/* uint64_t */
+#define	SCNxLEAST8	"hhx"	/* uint_least8_t */
+#define	SCNxLEAST16	"hx"	/* uint_least16_t */
+#define	SCNxLEAST32	"x"	/* uint_least32_t */
+#define	SCNxLEAST64	"llx"	/* uint_least64_t */
+#define	SCNxFAST8	"x"	/* uint_fast8_t */
+#define	SCNxFAST16	"x"	/* uint_fast16_t */
+#define	SCNxFAST32	"x"	/* uint_fast32_t */
+#define	SCNxFAST64	"llx"	/* uint_fast64_t */
+#define	SCNxMAX		"jx"	/* uintmax_t */
+#define	SCNxPTR		"x"	/* uintptr_t */
+
+#endif /* !_MACHINE_INTTYPES_H_ */


Property changes on: trunk/sys/arm/include/_inttypes.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/_limits.h
===================================================================
--- trunk/sys/arm/include/_limits.h	                        (rev 0)
+++ trunk/sys/arm/include/_limits.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,88 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1988, 1993
+ *	The Regents of the University of California.  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.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ *	@(#)limits.h	8.3 (Berkeley) 1/4/94
+ * $FreeBSD: stable/10/sys/arm/include/_limits.h 217145 2011-01-08 11:13:34Z tijl $
+ */
+
+#ifndef _MACHINE__LIMITS_H_
+#define	_MACHINE__LIMITS_H_
+
+/*
+ * According to ANSI (section 2.2.4.2), the values below must be usable by
+ * #if preprocessing directives.  Additionally, the expression must have the
+ * same type as would an expression that is an object of the corresponding
+ * type converted according to the integral promotions.  The subtraction for
+ * INT_MIN, etc., is so the value is not unsigned; e.g., 0x80000000 is an
+ * unsigned int for 32-bit two's complement ANSI compilers (section 3.1.3.2).
+ */
+
+#define	__CHAR_BIT	8		/* number of bits in a char */
+
+#define	__SCHAR_MAX	0x7f		/* max value for a signed char */
+#define	__SCHAR_MIN	(-0x7f - 1)	/* min value for a signed char */
+
+#define	__UCHAR_MAX	0xff		/* max value for an unsigned char */
+
+#define	__USHRT_MAX	0xffff		/* max value for an unsigned short */
+#define	__SHRT_MAX	0x7fff		/* max value for a short */
+#define	__SHRT_MIN	(-0x7fff - 1)	/* min value for a short */
+
+#define	__UINT_MAX	0xffffffff	/* max value for an unsigned int */
+#define	__INT_MAX	0x7fffffff	/* max value for an int */
+#define	__INT_MIN	(-0x7fffffff - 1)	/* min value for an int */
+
+#define	__ULONG_MAX	0xffffffffUL	/* max value for an unsigned long */
+#define	__LONG_MAX	0x7fffffffL	/* max value for a long */
+#define	__LONG_MIN	(-0x7fffffffL - 1)	/* min value for a long */
+
+			/* max value for an unsigned long long */
+#define	__ULLONG_MAX	0xffffffffffffffffULL
+#define	__LLONG_MAX	0x7fffffffffffffffLL	/* max value for a long long */
+#define	__LLONG_MIN	(-0x7fffffffffffffffLL - 1)  /* min for a long long */
+
+#define	__SSIZE_MAX	__INT_MAX	/* max value for a ssize_t */
+
+#define	__SIZE_T_MAX	__UINT_MAX	/* max value for a size_t */
+
+#define	__OFF_MAX	__LLONG_MAX	/* max value for a off_t */
+#define	__OFF_MIN	__LLONG_MIN	/* min value for a off_t */
+
+/* Quads and long longs are the same size.  Ensure they stay in sync. */
+#define	__UQUAD_MAX	__ULLONG_MAX	/* max value for a uquad_t */
+#define	__QUAD_MAX	__LLONG_MAX	/* max value for a quad_t */
+#define	__QUAD_MIN	__LLONG_MIN	/* min value for a quad_t */
+
+#define	__LONG_BIT	32
+#define	__WORD_BIT	32
+
+/* Minimum signal stack size. */
+#define	__MINSIGSTKSZ	(1024 * 4)
+
+#endif /* !_MACHINE__LIMITS_H_ */


Property changes on: trunk/sys/arm/include/_limits.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/_stdint.h
===================================================================
--- trunk/sys/arm/include/_stdint.h	                        (rev 0)
+++ trunk/sys/arm/include/_stdint.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,159 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2001, 2002 Mike Barcroft <mike at FreeBSD.org>
+ * Copyright (c) 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Klaus Klein.
+ *
+ * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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: stable/10/sys/arm/include/_stdint.h 237517 2012-06-24 04:15:58Z andrew $
+ */
+
+#ifndef _MACHINE__STDINT_H_
+#define	_MACHINE__STDINT_H_
+
+#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS)
+
+#define	INT8_C(c)		(c)
+#define	INT16_C(c)		(c)
+#define	INT32_C(c)		(c)
+#define	INT64_C(c)		(c ## LL)
+
+#define	UINT8_C(c)		(c)
+#define	UINT16_C(c)		(c)
+#define	UINT32_C(c)		(c ## U)
+#define	UINT64_C(c)		(c ## ULL)
+
+#define	INTMAX_C(c)		INT64_C(c)
+#define	UINTMAX_C(c)		UINT64_C(c)
+
+#endif /* !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) */
+
+#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS)
+
+/*
+ * ISO/IEC 9899:1999
+ * 7.18.2.1 Limits of exact-width integer types
+ */
+/* Minimum values of exact-width signed integer types. */
+#define	INT8_MIN	(-0x7f-1)
+#define	INT16_MIN	(-0x7fff-1)
+#define	INT32_MIN	(-0x7fffffff-1)
+#define	INT64_MIN	(-0x7fffffffffffffffLL-1)
+
+/* Maximum values of exact-width signed integer types. */
+#define	INT8_MAX	0x7f
+#define	INT16_MAX	0x7fff
+#define	INT32_MAX	0x7fffffff
+#define	INT64_MAX	0x7fffffffffffffffLL
+
+/* Maximum values of exact-width unsigned integer types. */
+#define	UINT8_MAX	0xff
+#define	UINT16_MAX	0xffff
+#define	UINT32_MAX	0xffffffffU
+#define	UINT64_MAX	0xffffffffffffffffULL
+
+/*
+ * ISO/IEC 9899:1999
+ * 7.18.2.2  Limits of minimum-width integer types
+ */
+/* Minimum values of minimum-width signed integer types. */
+#define	INT_LEAST8_MIN	INT8_MIN
+#define	INT_LEAST16_MIN	INT16_MIN
+#define	INT_LEAST32_MIN	INT32_MIN
+#define	INT_LEAST64_MIN	INT64_MIN
+
+/* Maximum values of minimum-width signed integer types. */
+#define	INT_LEAST8_MAX	INT8_MAX
+#define	INT_LEAST16_MAX	INT16_MAX
+#define	INT_LEAST32_MAX	INT32_MAX
+#define	INT_LEAST64_MAX	INT64_MAX
+
+/* Maximum values of minimum-width unsigned integer types. */
+#define	UINT_LEAST8_MAX	 UINT8_MAX
+#define	UINT_LEAST16_MAX UINT16_MAX
+#define	UINT_LEAST32_MAX UINT32_MAX
+#define	UINT_LEAST64_MAX UINT64_MAX
+
+/*
+ * ISO/IEC 9899:1999
+ * 7.18.2.3  Limits of fastest minimum-width integer types
+ */
+/* Minimum values of fastest minimum-width signed integer types. */
+#define	INT_FAST8_MIN	INT32_MIN
+#define	INT_FAST16_MIN	INT32_MIN
+#define	INT_FAST32_MIN	INT32_MIN
+#define	INT_FAST64_MIN	INT64_MIN
+
+/* Maximum values of fastest minimum-width signed integer types. */
+#define	INT_FAST8_MAX	INT32_MAX
+#define	INT_FAST16_MAX	INT32_MAX
+#define	INT_FAST32_MAX	INT32_MAX
+#define	INT_FAST64_MAX	INT64_MAX
+
+/* Maximum values of fastest minimum-width unsigned integer types. */
+#define	UINT_FAST8_MAX	UINT32_MAX
+#define	UINT_FAST16_MAX	UINT32_MAX
+#define	UINT_FAST32_MAX	UINT32_MAX
+#define	UINT_FAST64_MAX	UINT64_MAX
+
+/*
+ * ISO/IEC 9899:1999
+ * 7.18.2.4  Limits of integer types capable of holding object pointers
+ */
+#define	INTPTR_MIN	INT32_MIN
+#define	INTPTR_MAX	INT32_MAX
+#define	UINTPTR_MAX	UINT32_MAX
+
+/*
+ * ISO/IEC 9899:1999
+ * 7.18.2.5  Limits of greatest-width integer types
+ */
+#define	INTMAX_MIN	INT64_MIN
+#define	INTMAX_MAX	INT64_MAX
+#define	UINTMAX_MAX	UINT64_MAX
+
+/*
+ * ISO/IEC 9899:1999
+ * 7.18.3  Limits of other integer types
+ */
+/* Limits of ptrdiff_t. */
+#define	PTRDIFF_MIN	INT32_MIN	
+#define	PTRDIFF_MAX	INT32_MAX
+
+/* Limits of sig_atomic_t. */
+#define	SIG_ATOMIC_MIN	INT32_MIN
+#define	SIG_ATOMIC_MAX	INT32_MAX
+
+/* Limit of size_t. */
+#define	SIZE_MAX	UINT32_MAX
+
+/* Limits of wint_t. */
+#define	WINT_MIN	INT32_MIN
+#define	WINT_MAX	INT32_MAX
+
+#endif /* !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) */
+
+#endif /* !_MACHINE__STDINT_H_ */


Property changes on: trunk/sys/arm/include/_stdint.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/_types.h
===================================================================
--- trunk/sys/arm/include/_types.h	                        (rev 0)
+++ trunk/sys/arm/include/_types.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,133 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2002 Mike Barcroft <mike at FreeBSD.org>
+ * Copyright (c) 1990, 1993
+ *	The Regents of the University of California.  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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ *	From: @(#)ansi.h	8.2 (Berkeley) 1/4/94
+ *	From: @(#)types.h	8.3 (Berkeley) 1/5/94
+ * $FreeBSD: stable/10/sys/arm/include/_types.h 264496 2014-04-15 09:41:52Z tijl $
+ */
+
+#ifndef _MACHINE__TYPES_H_
+#define	_MACHINE__TYPES_H_
+
+#ifndef _SYS_CDEFS_H_
+#error this file needs sys/cdefs.h as a prerequisite
+#endif
+
+/*
+ * Basic types upon which most other types are built.
+ */
+typedef	signed char		__int8_t;
+typedef	unsigned char		__uint8_t;
+typedef	short			__int16_t;
+typedef	unsigned short		__uint16_t;
+typedef	int			__int32_t;
+typedef	unsigned int		__uint32_t;
+#ifndef lint
+__extension__
+#endif
+/* LONGLONG */
+typedef	long long		__int64_t;
+#ifndef lint
+__extension__
+#endif
+/* LONGLONG */
+typedef	unsigned long long	__uint64_t;
+
+/*
+ * Standard type definitions.
+ */
+typedef	__uint32_t	__clock_t;		/* clock()... */
+typedef	__int32_t	__critical_t;
+typedef	double		__double_t;
+typedef	float		__float_t;
+typedef	__int32_t	__intfptr_t;
+typedef	__int64_t	__intmax_t;
+typedef	__int32_t	__intptr_t;
+typedef	__int32_t	__int_fast8_t;
+typedef	__int32_t	__int_fast16_t;
+typedef	__int32_t	__int_fast32_t;
+typedef	__int64_t	__int_fast64_t;
+typedef	__int8_t	__int_least8_t;
+typedef	__int16_t	__int_least16_t;
+typedef	__int32_t	__int_least32_t;
+typedef	__int64_t	__int_least64_t;
+typedef	__int32_t	__ptrdiff_t;		/* ptr1 - ptr2 */
+typedef	__int32_t	__register_t;
+typedef	__int32_t	__segsz_t;		/* segment size (in pages) */
+typedef	__uint32_t	__size_t;		/* sizeof() */
+typedef	__int32_t	__ssize_t;		/* byte count or error */
+typedef	__int64_t	__time_t;		/* time()... */
+typedef	__uint32_t	__uintfptr_t;
+typedef	__uint64_t	__uintmax_t;
+typedef	__uint32_t	__uintptr_t;
+typedef	__uint32_t	__uint_fast8_t;
+typedef	__uint32_t	__uint_fast16_t;
+typedef	__uint32_t	__uint_fast32_t;
+typedef	__uint64_t	__uint_fast64_t;
+typedef	__uint8_t	__uint_least8_t;
+typedef	__uint16_t	__uint_least16_t;
+typedef	__uint32_t	__uint_least32_t;
+typedef	__uint64_t	__uint_least64_t;
+typedef	__uint32_t	__u_register_t;
+typedef	__uint32_t	__vm_offset_t;
+typedef	__int64_t	__vm_ooffset_t;
+typedef	__uint32_t	__vm_paddr_t;
+typedef	__uint64_t	__vm_pindex_t;
+typedef	__uint32_t	__vm_size_t;
+
+#ifdef __ARM_EABI__
+typedef	unsigned int	___wchar_t;
+#define	__WCHAR_MIN	0		/* min value for a wchar_t */
+#define	__WCHAR_MAX	__UINT_MAX	/* max value for a wchar_t */
+#else
+typedef	int		___wchar_t;
+#define	__WCHAR_MIN	__INT_MIN	/* min value for a wchar_t */
+#define	__WCHAR_MAX	__INT_MAX	/* max value for a wchar_t */
+#endif
+
+/*
+ * Unusual type definitions.
+ */
+#ifdef __GNUCLIKE_BUILTIN_VARARGS
+typedef __builtin_va_list	__va_list;	/* internally known to gcc */
+#else
+typedef	char *			__va_list;
+#endif /* __GNUCLIKE_BUILTIN_VARARGS */
+#if defined(__GNUCLIKE_BUILTIN_VAALIST) && !defined(__GNUC_VA_LIST) \
+    && !defined(__NO_GNUC_VA_LIST)
+#define __GNUC_VA_LIST
+typedef __va_list		__gnuc_va_list;	/* compatibility w/GNU headers*/
+#endif
+
+#endif /* !_MACHINE__TYPES_H_ */


Property changes on: trunk/sys/arm/include/_types.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/acle-compat.h
===================================================================
--- trunk/sys/arm/include/acle-compat.h	                        (rev 0)
+++ trunk/sys/arm/include/acle-compat.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,186 @@
+/* $MidnightBSD$ */
+/*
+ * Copyright (c) 2014 ARM Ltd
+ * 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.
+ * 3. The name of the company may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ARM LTD ``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 ARM LTD 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: stable/10/sys/arm/include/acle-compat.h 273827 2014-10-29 16:24:02Z andrew $
+ */
+
+#ifndef __ARM_ARCH
+
+/* ACLE standardises a set of pre-defines that describe the ARM architecture.
+   These were mostly implemented in GCC around GCC-4.8; older versions
+   have no, or only partial support.  To provide a level of backwards
+   compatibility we try to work out what the definitions should be, given
+   the older pre-defines that GCC did produce.  This isn't complete, but
+   it should be enough for use by routines that depend on this header.  */
+
+/* No need to handle ARMv8, GCC had ACLE support before that.  */
+
+#define __ARM_ACLE 101
+
+# ifdef __ARM_ARCH_7__
+/* The common subset of ARMv7 in all profiles.  */
+#  define __ARM_ARCH 7
+#  define __ARM_ARCH_ISA_THUMB 2
+#  define __ARM_FEATURE_CLZ
+#  define __ARM_FEATURE_LDREX 7
+#  define __ARM_FEATURE_UNALIGNED
+# endif
+
+# if defined (__ARM_ARCH_7A__) || defined (__ARM_ARCH_7R__)
+#  define __ARM_ARCH 7
+#  define __ARM_ARCH_ISA_THUMB 2
+#  define __ARM_ARCH_ISA_ARM
+#  define __ARM_FEATURE_CLZ
+#  define __ARM_FEATURE_SIMD32
+#  define __ARM_FEATURE_DSP
+#  define __ARM_FEATURE_QBIT
+#  define __ARM_FEATURE_SAT
+#  define __ARM_FEATURE_LDREX 15
+#  define __ARM_FEATURE_UNALIGNED
+#  ifdef __ARM_ARCH_7A__
+#   define __ARM_ARCH_PROFILE 'A'
+#  else
+#   define __ARM_ARCH_PROFILE 'R'
+#  endif
+# endif
+
+# ifdef __ARM_ARCH_7EM__
+#  define __ARM_ARCH 7
+#  define __ARM_ARCH_ISA_THUMB 2
+#  define __ARM_FEATURE_CLZ
+#  define __ARM_FEATURE_SIMD32
+#  define __ARM_FEATURE_DSP
+#  define __ARM_FEATURE_QBIT
+#  define __ARM_FEATURE_SAT
+#  define __ARM_FEATURE_LDREX 7
+#  define __ARM_FEATURE_UNALIGNED
+#  define __ARM_ARCH_PROFILE 'M'
+# endif
+
+# ifdef __ARM_ARCH_7M__
+#  define __ARM_ARCH 7
+#  define __ARM_ARCH_ISA_THUMB 2
+#  define __ARM_FEATURE_CLZ
+#  define __ARM_FEATURE_QBIT
+#  define __ARM_FEATURE_SAT
+#  define __ARM_FEATURE_LDREX 7
+#  define __ARM_FEATURE_UNALIGNED
+#  define __ARM_ARCH_PROFILE 'M'
+# endif
+
+# ifdef __ARM_ARCH_6T2__
+#  define __ARM_ARCH 6
+#  define __ARM_ARCH_ISA_THUMB 2
+#  define __ARM_ARCH_ISA_ARM
+#  define __ARM_FEATURE_CLZ
+#  define __ARM_FEATURE_SIMD32
+#  define __ARM_FEATURE_DSP
+#  define __ARM_FEATURE_QBIT
+#  define __ARM_FEATURE_SAT
+#  define __ARM_FEATURE_LDREX 4
+#  define __ARM_FEATURE_UNALIGNED
+# endif
+
+# ifdef __ARM_ARCH_6M__
+#  define __ARM_ARCH 6
+#  define __ARM_ARCH_ISA_THUMB 1
+#  define __ARM_ARCH_PROFILE 'M'
+# endif
+
+# if defined (__ARM_ARCH_6__) || defined (__ARM_ARCH_6J__) \
+  || defined (__ARM_ARCH_6K__) || defined (__ARM_ARCH_6Z__) \
+  || defined (__ARM_ARCH_6ZK__)
+#  define __ARM_ARCH 6
+#  define __ARM_ARCH_ISA_THUMB 1
+#  define __ARM_ARCH_ISA_ARM
+#  define __ARM_FEATURE_CLZ
+#  define __ARM_FEATURE_SIMD32
+#  define __ARM_FEATURE_DSP
+#  define __ARM_FEATURE_QBIT
+#  define __ARM_FEATURE_SAT
+#  define __ARM_FEATURE_UNALIGNED
+#  ifndef __thumb__
+#   if defined (__ARM_ARCH_6K__) || defined (__ARM_ARCH_6ZK__)
+#    define __ARM_FEATURE_LDREX 15
+#   else
+#    define __ARM_FEATURE_LDREX 4
+#   endif
+#  endif
+# endif
+
+# if defined (__ARM_ARCH_5TE__) || defined (__ARM_ARCH_5E__)
+#  define __ARM_ARCH 5
+#  define __ARM_ARCH_ISA_ARM
+#  ifdef __ARM_ARCH_5TE__
+#   define __ARM_ARCH_ISA_THUMB 1
+#  endif
+#  define __ARM_FEATURE_CLZ
+#  define __ARM_FEATURE_DSP
+# endif
+
+# if defined (__ARM_ARCH_5T__) || defined (__ARM_ARCH_5__)
+#  define __ARM_ARCH 5
+#  define __ARM_ARCH_ISA_ARM
+#  ifdef __ARM_ARCH_5TE__
+#   define __ARM_ARCH_ISA_THUMB 1
+#  endif
+#  define __ARM_FEATURE_CLZ
+# endif
+
+# ifdef __ARM_ARCH_4T__
+#  define __ARM_ARCH 4
+#  define __ARM_ARCH_ISA_ARM
+#  define __ARM_ARCH_ISA_THUMB 1
+# endif
+
+# ifdef __ARM_ARCH_4__
+#  define __ARM_ARCH 4
+#  define __ARM_ARCH_ISA_ARM
+# endif
+
+# if defined (__ARM_ARCH_3__) || defined (__ARM_ARCH_3M__)
+#  define __ARM_ARCH 3
+#  define __ARM_ARCH_ISA_ARM
+# endif
+
+# ifdef __ARM_ARCH_2__
+#  define __ARM_ARCH 2
+#  define __ARM_ARCH_ISA_ARM
+# endif
+
+# ifdef __ARMEB__
+#  define __ARM_BIG_ENDIAN
+# endif
+
+/* If we still don't know what the target architecture is, then we're
+   probably not using GCC.  */
+# ifndef __ARM_ARCH
+#  error Unable to determine architecture version.
+# endif
+
+#endif /* __ARM_ARCH  */


Property changes on: trunk/sys/arm/include/acle-compat.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/armreg.h
===================================================================
--- trunk/sys/arm/include/armreg.h	                        (rev 0)
+++ trunk/sys/arm/include/armreg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,444 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: armreg.h,v 1.37 2007/01/06 00:50:54 christos Exp $	*/
+
+/*-
+ * Copyright (c) 1998, 2001 Ben Harris
+ * Copyright (c) 1994-1996 Mark Brinicombe.
+ * Copyright (c) 1994 Brini.
+ * All rights reserved.
+ *
+ * This code is derived from software written for Brini by Mark Brinicombe
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Brini.
+ * 4. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BRINI ``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 BRINI 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: stable/10/sys/arm/include/armreg.h 283335 2015-05-23 22:48:54Z ian $
+ */
+
+#ifndef MACHINE_ARMREG_H
+#define MACHINE_ARMREG_H
+
+#include <machine/acle-compat.h>
+
+#define INSN_SIZE	4
+#define INSN_COND_MASK	0xf0000000	/* Condition mask */
+#define PSR_MODE        0x0000001f      /* mode mask */
+#define PSR_USR32_MODE  0x00000010
+#define PSR_FIQ32_MODE  0x00000011
+#define PSR_IRQ32_MODE  0x00000012
+#define PSR_SVC32_MODE  0x00000013
+#define PSR_MON32_MODE	0x00000016
+#define PSR_ABT32_MODE  0x00000017
+#define PSR_HYP32_MODE	0x0000001a
+#define PSR_UND32_MODE  0x0000001b
+#define PSR_SYS32_MODE  0x0000001f
+#define PSR_32_MODE     0x00000010
+#define PSR_T		0x00000020	/* Instruction set bit */
+#define PSR_F		0x00000040	/* FIQ disable bit */
+#define PSR_I		0x00000080	/* IRQ disable bit */
+#define PSR_A		0x00000100	/* Imprecise abort bit */
+#define PSR_E		0x00000200	/* Data endianess bit */
+#define PSR_GE		0x000f0000	/* Greater than or equal to bits */
+#define PSR_J		0x01000000	/* Java bit */
+#define PSR_Q		0x08000000	/* Sticky overflow bit */
+#define PSR_V		0x10000000	/* Overflow bit */
+#define PSR_C		0x20000000	/* Carry bit */
+#define PSR_Z		0x40000000	/* Zero bit */
+#define PSR_N		0x80000000	/* Negative bit */
+#define PSR_FLAGS	0xf0000000	/* Flags mask. */
+
+/* The high-order byte is always the implementor */
+#define CPU_ID_IMPLEMENTOR_MASK	0xff000000
+#define CPU_ID_ARM_LTD		0x41000000 /* 'A' */
+#define CPU_ID_DEC		0x44000000 /* 'D' */
+#define CPU_ID_INTEL		0x69000000 /* 'i' */
+#define	CPU_ID_TI		0x54000000 /* 'T' */
+#define	CPU_ID_FARADAY		0x66000000 /* 'f' */
+
+/* How to decide what format the CPUID is in. */
+#define CPU_ID_ISOLD(x)		(((x) & 0x0000f000) == 0x00000000)
+#define CPU_ID_IS7(x)		(((x) & 0x0000f000) == 0x00007000)
+#define CPU_ID_ISNEW(x)		(!CPU_ID_ISOLD(x) && !CPU_ID_IS7(x))
+
+/* On recent ARMs this byte holds the architecture and variant (sub-model) */
+#define CPU_ID_ARCH_MASK	0x000f0000
+#define CPU_ID_ARCH_V3		0x00000000
+#define CPU_ID_ARCH_V4		0x00010000
+#define CPU_ID_ARCH_V4T		0x00020000
+#define CPU_ID_ARCH_V5		0x00030000
+#define CPU_ID_ARCH_V5T		0x00040000
+#define CPU_ID_ARCH_V5TE	0x00050000
+#define CPU_ID_ARCH_V5TEJ	0x00060000
+#define CPU_ID_ARCH_V6		0x00070000
+#define CPU_ID_CPUID_SCHEME	0x000f0000
+#define CPU_ID_VARIANT_MASK	0x00f00000
+
+/* Next three nybbles are part number */
+#define CPU_ID_PARTNO_MASK	0x0000fff0
+
+/* Intel XScale has sub fields in part number */
+#define CPU_ID_XSCALE_COREGEN_MASK	0x0000e000 /* core generation */
+#define CPU_ID_XSCALE_COREREV_MASK	0x00001c00 /* core revision */
+#define CPU_ID_XSCALE_PRODUCT_MASK	0x000003f0 /* product number */
+
+/* And finally, the revision number. */
+#define CPU_ID_REVISION_MASK	0x0000000f
+
+/* Individual CPUs are probably best IDed by everything but the revision. */
+#define CPU_ID_CPU_MASK		0xfffffff0
+
+/* ARM9 and later CPUs */
+#define CPU_ID_ARM920T		0x41129200
+#define CPU_ID_ARM920T_ALT	0x41009200
+#define CPU_ID_ARM922T		0x41029220
+#define CPU_ID_ARM926EJS	0x41069260
+#define CPU_ID_ARM940T		0x41029400 /* XXX no MMU */
+#define CPU_ID_ARM946ES		0x41049460 /* XXX no MMU */
+#define	CPU_ID_ARM966ES		0x41049660 /* XXX no MMU */
+#define	CPU_ID_ARM966ESR1	0x41059660 /* XXX no MMU */
+#define CPU_ID_ARM1020E		0x4115a200 /* (AKA arm10 rev 1) */
+#define CPU_ID_ARM1022ES	0x4105a220
+#define CPU_ID_ARM1026EJS	0x4106a260
+#define CPU_ID_ARM1136JS	0x4107b360
+#define CPU_ID_ARM1136JSR1	0x4117b360
+#define CPU_ID_ARM1176JZS	0x410fb760
+#define CPU_ID_CORTEXA7 	0x410fc070
+#define CPU_ID_CORTEXA8R1	0x411fc080
+#define CPU_ID_CORTEXA8R2	0x412fc080
+#define CPU_ID_CORTEXA8R3	0x413fc080
+#define CPU_ID_CORTEXA9R1	0x411fc090
+#define CPU_ID_CORTEXA9R2	0x412fc090
+#define CPU_ID_CORTEXA9R3	0x413fc090
+#define CPU_ID_CORTEXA15R0	0x410fc0f0
+#define CPU_ID_CORTEXA15R1	0x411fc0f0
+#define CPU_ID_CORTEXA15R2	0x412fc0f0
+#define CPU_ID_CORTEXA15R3	0x413fc0f0
+#define	CPU_ID_KRAIT		0x510f06f0 /* Snapdragon S4 Pro/APQ8064 */
+#define	CPU_ID_TI925T		0x54029250
+#define CPU_ID_MV88FR131	0x56251310 /* Marvell Feroceon 88FR131 Core */
+#define CPU_ID_MV88FR331	0x56153310 /* Marvell Feroceon 88FR331 Core */
+#define CPU_ID_MV88FR571_VD	0x56155710 /* Marvell Feroceon 88FR571-VD Core (ID from datasheet) */
+
+/*
+ * LokiPlus core has also ID set to 0x41159260 and this define cause execution of unsupported
+ * L2-cache instructions so need to disable it. 0x41159260 is a generic ARM926E-S ID.
+ */
+#ifdef SOC_MV_LOKIPLUS
+#define CPU_ID_MV88FR571_41	0x00000000
+#else
+#define CPU_ID_MV88FR571_41	0x41159260 /* Marvell Feroceon 88FR571-VD Core (actual ID from CPU reg) */
+#endif
+
+#define CPU_ID_MV88SV581X_V7		0x561F5810 /* Marvell Sheeva 88SV581x v7 Core */
+#define CPU_ID_MV88SV584X_V7		0x562F5840 /* Marvell Sheeva 88SV584x v7 Core */
+/* Marvell's CPUIDs with ARM ID in implementor field */
+#define CPU_ID_ARM_88SV581X_V7		0x413FC080 /* Marvell Sheeva 88SV581x v7 Core */
+
+#define	CPU_ID_FA526		0x66015260
+#define	CPU_ID_FA626TE		0x66056260
+#define CPU_ID_80200		0x69052000
+#define CPU_ID_PXA250    	0x69052100 /* sans core revision */
+#define CPU_ID_PXA210    	0x69052120
+#define CPU_ID_PXA250A		0x69052100 /* 1st version Core */
+#define CPU_ID_PXA210A		0x69052120 /* 1st version Core */
+#define CPU_ID_PXA250B		0x69052900 /* 3rd version Core */
+#define CPU_ID_PXA210B		0x69052920 /* 3rd version Core */
+#define CPU_ID_PXA250C		0x69052d00 /* 4th version Core */
+#define CPU_ID_PXA210C		0x69052d20 /* 4th version Core */
+#define	CPU_ID_PXA27X		0x69054110
+#define	CPU_ID_80321_400	0x69052420
+#define	CPU_ID_80321_600	0x69052430
+#define	CPU_ID_80321_400_B0	0x69052c20
+#define	CPU_ID_80321_600_B0	0x69052c30
+#define	CPU_ID_80219_400	0x69052e20 /* A0 stepping/revision. */
+#define	CPU_ID_80219_600	0x69052e30 /* A0 stepping/revision. */
+#define	CPU_ID_81342		0x69056810
+#define	CPU_ID_IXP425		0x690541c0
+#define	CPU_ID_IXP425_533	0x690541c0
+#define	CPU_ID_IXP425_400	0x690541d0
+#define	CPU_ID_IXP425_266	0x690541f0
+#define	CPU_ID_IXP435		0x69054040
+#define	CPU_ID_IXP465		0x69054200
+
+/* CPUID registers */
+#define ARM_PFR0_ARM_ISA_MASK	0x0000000f
+
+#define ARM_PFR0_THUMB_MASK	0x000000f0
+#define ARM_PFR0_THUMB		0x10
+#define ARM_PFR0_THUMB2		0x30
+
+#define ARM_PFR0_JAZELLE_MASK	0x00000f00
+#define ARM_PFR0_THUMBEE_MASK	0x0000f000
+
+#define ARM_PFR1_ARMV4_MASK	0x0000000f
+#define ARM_PFR1_SEC_EXT_MASK	0x000000f0
+#define ARM_PFR1_MICROCTRL_MASK	0x00000f00
+
+/*
+ * Post-ARM3 CP15 registers:
+ *
+ *	1	Control register
+ *
+ *	2	Translation Table Base
+ *
+ *	3	Domain Access Control
+ *
+ *	4	Reserved
+ *
+ *	5	Fault Status
+ *
+ *	6	Fault Address
+ *
+ *	7	Cache/write-buffer Control
+ *
+ *	8	TLB Control
+ *
+ *	9	Cache Lockdown
+ *
+ *	10	TLB Lockdown
+ *
+ *	11	Reserved
+ *
+ *	12	Reserved
+ *
+ *	13	Process ID (for FCSE)
+ *
+ *	14	Reserved
+ *
+ *	15	Implementation Dependent
+ */
+
+/* Some of the definitions below need cleaning up for V3/V4 architectures */
+
+/* CPU control register (CP15 register 1) */
+#define CPU_CONTROL_MMU_ENABLE	0x00000001 /* M: MMU/Protection unit enable */
+#define CPU_CONTROL_AFLT_ENABLE	0x00000002 /* A: Alignment fault enable */
+#define CPU_CONTROL_DC_ENABLE	0x00000004 /* C: IDC/DC enable */
+#define CPU_CONTROL_WBUF_ENABLE 0x00000008 /* W: Write buffer enable */
+#define CPU_CONTROL_32BP_ENABLE 0x00000010 /* P: 32-bit exception handlers */
+#define CPU_CONTROL_32BD_ENABLE 0x00000020 /* D: 32-bit addressing */
+#define CPU_CONTROL_LABT_ENABLE 0x00000040 /* L: Late abort enable */
+#define CPU_CONTROL_BEND_ENABLE 0x00000080 /* B: Big-endian mode */
+#define CPU_CONTROL_SYST_ENABLE 0x00000100 /* S: System protection bit */
+#define CPU_CONTROL_ROM_ENABLE	0x00000200 /* R: ROM protection bit */
+#define CPU_CONTROL_CPCLK	0x00000400 /* F: Implementation defined */
+#define CPU_CONTROL_SW_ENABLE	0x00000400 /* SW: SWP instruction enable */
+#define CPU_CONTROL_BPRD_ENABLE 0x00000800 /* Z: Branch prediction enable */
+#define CPU_CONTROL_IC_ENABLE   0x00001000 /* I: IC enable */
+#define CPU_CONTROL_VECRELOC	0x00002000 /* V: Vector relocation */
+#define CPU_CONTROL_ROUNDROBIN	0x00004000 /* RR: Predictable replacement */
+#define CPU_CONTROL_V4COMPAT	0x00008000 /* L4: ARMv4 compat LDR R15 etc */
+#define CPU_CONTROL_HAF_ENABLE	0x00020000 /* HA: Hardware Access Flag Enable */
+#define CPU_CONTROL_FI_ENABLE	0x00200000 /* FI: Low interrupt latency */
+#define CPU_CONTROL_UNAL_ENABLE 0x00400000 /* U: unaligned data access */
+#define CPU_CONTROL_V6_EXTPAGE	0x00800000 /* XP: ARMv6 extended page tables */
+#define CPU_CONTROL_V_ENABLE	0x01000000 /* VE: Interrupt vectors enable */
+#define CPU_CONTROL_EX_BEND	0x02000000 /* EE: exception endianness */
+#define CPU_CONTROL_L2_ENABLE	0x04000000 /* L2 Cache enabled */
+#define CPU_CONTROL_NMFI	0x08000000 /* NMFI: Non maskable FIQ */
+#define CPU_CONTROL_TR_ENABLE	0x10000000 /* TRE: TEX Remap*/
+#define CPU_CONTROL_AF_ENABLE	0x20000000 /* AFE: Access Flag enable */
+#define CPU_CONTROL_TE_ENABLE	0x40000000 /* TE: Thumb Exception enable */
+
+#define CPU_CONTROL_IDC_ENABLE	CPU_CONTROL_DC_ENABLE
+
+/* ARM11x6 Auxiliary Control Register (CP15 register 1, opcode2 1) */
+#define	ARM11X6_AUXCTL_RS	0x00000001 /* return stack */
+#define	ARM11X6_AUXCTL_DB	0x00000002 /* dynamic branch prediction */
+#define	ARM11X6_AUXCTL_SB	0x00000004 /* static branch prediction */
+#define	ARM11X6_AUXCTL_TR	0x00000008 /* MicroTLB replacement strat. */
+#define	ARM11X6_AUXCTL_EX	0x00000010 /* exclusive L1/L2 cache */
+#define	ARM11X6_AUXCTL_RA	0x00000020 /* clean entire cache disable */
+#define	ARM11X6_AUXCTL_RV	0x00000040 /* block transfer cache disable */
+#define	ARM11X6_AUXCTL_CZ	0x00000080 /* restrict cache size */
+
+/* ARM1136 Auxiliary Control Register (CP15 register 1, opcode2 1) */
+#define ARM1136_AUXCTL_PFI	0x80000000 /* PFI: partial FI mode. */
+					   /* This is an undocumented flag
+					    * used to work around a cache bug
+					    * in r0 steppings. See errata
+					    * 364296.
+					    */
+/* ARM1176 Auxiliary Control Register (CP15 register 1, opcode2 1) */   
+#define	ARM1176_AUXCTL_PHD	0x10000000 /* inst. prefetch halting disable */
+#define	ARM1176_AUXCTL_BFD	0x20000000 /* branch folding disable */
+#define	ARM1176_AUXCTL_FSD	0x40000000 /* force speculative ops disable */
+#define	ARM1176_AUXCTL_FIO	0x80000000 /* low intr latency override */
+
+/* XScale Auxillary Control Register (CP15 register 1, opcode2 1) */
+#define	XSCALE_AUXCTL_K		0x00000001 /* dis. write buffer coalescing */
+#define	XSCALE_AUXCTL_P		0x00000002 /* ECC protect page table access */
+/* Note: XSCale core 3 uses those for LLR DCcahce attributes */
+#define	XSCALE_AUXCTL_MD_WB_RA	0x00000000 /* mini-D$ wb, read-allocate */
+#define	XSCALE_AUXCTL_MD_WB_RWA	0x00000010 /* mini-D$ wb, read/write-allocate */
+#define	XSCALE_AUXCTL_MD_WT	0x00000020 /* mini-D$ wt, read-allocate */
+#define	XSCALE_AUXCTL_MD_MASK	0x00000030
+
+/* Xscale Core 3 only */
+#define XSCALE_AUXCTL_LLR	0x00000400 /* Enable L2 for LLR Cache */
+
+/* Marvell Extra Features Register (CP15 register 1, opcode2 0) */
+#define MV_DC_REPLACE_LOCK	0x80000000 /* Replace DCache Lock */
+#define MV_DC_STREAM_ENABLE	0x20000000 /* DCache Streaming Switch */
+#define MV_WA_ENABLE		0x10000000 /* Enable Write Allocate */
+#define MV_L2_PREFETCH_DISABLE	0x01000000 /* L2 Cache Prefetch Disable */
+#define MV_L2_INV_EVICT_ERR	0x00800000 /* L2 Invalidates Uncorrectable Error Line Eviction */
+#define MV_L2_ENABLE		0x00400000 /* L2 Cache enable */
+#define MV_IC_REPLACE_LOCK	0x00080000 /* Replace ICache Lock */
+#define MV_BGH_ENABLE		0x00040000 /* Branch Global History Register Enable */
+#define MV_BTB_DISABLE		0x00020000 /* Branch Target Buffer Disable */
+#define MV_L1_PARERR_ENABLE	0x00010000 /* L1 Parity Error Enable */
+
+/* Cache type register definitions */
+#define	CPU_CT_ISIZE(x)		((x) & 0xfff)		/* I$ info */
+#define	CPU_CT_DSIZE(x)		(((x) >> 12) & 0xfff)	/* D$ info */
+#define	CPU_CT_S		(1U << 24)		/* split cache */
+#define	CPU_CT_CTYPE(x)		(((x) >> 25) & 0xf)	/* cache type */
+#define	CPU_CT_FORMAT(x)	((x) >> 29)
+/* Cache type register definitions for ARM v7 */
+#define	CPU_CT_IMINLINE(x)	((x) & 0xf)		/* I$ min line size */
+#define	CPU_CT_DMINLINE(x)	(((x) >> 16) & 0xf)	/* D$ min line size */
+
+#define	CPU_CT_CTYPE_WT		0	/* write-through */
+#define	CPU_CT_CTYPE_WB1	1	/* write-back, clean w/ read */
+#define	CPU_CT_CTYPE_WB2	2	/* w/b, clean w/ cp15,7 */
+#define	CPU_CT_CTYPE_WB6	6	/* w/b, cp15,7, lockdown fmt A */
+#define	CPU_CT_CTYPE_WB7	7	/* w/b, cp15,7, lockdown fmt B */
+
+#define	CPU_CT_xSIZE_LEN(x)	((x) & 0x3)		/* line size */
+#define	CPU_CT_xSIZE_M		(1U << 2)		/* multiplier */
+#define	CPU_CT_xSIZE_ASSOC(x)	(((x) >> 3) & 0x7)	/* associativity */
+#define	CPU_CT_xSIZE_SIZE(x)	(((x) >> 6) & 0x7)	/* size */
+
+#define	CPU_CT_ARMV7		0x4
+/* ARM v7 Cache type definitions */
+#define	CPUV7_CT_CTYPE_WT	(1U << 31)
+#define	CPUV7_CT_CTYPE_WB	(1 << 30)
+#define	CPUV7_CT_CTYPE_RA	(1 << 29)
+#define	CPUV7_CT_CTYPE_WA	(1 << 28)
+
+#define	CPUV7_CT_xSIZE_LEN(x)	((x) & 0x7)		/* line size */
+#define	CPUV7_CT_xSIZE_ASSOC(x)	(((x) >> 3) & 0x3ff)	/* associativity */
+#define	CPUV7_CT_xSIZE_SET(x)	(((x) >> 13) & 0x7fff)	/* num sets */
+
+#define	CPU_CLIDR_CTYPE(reg,x)	(((reg) >> ((x) * 3)) & 0x7)
+#define	CPU_CLIDR_LOUIS(reg)	(((reg) >> 21) & 0x7)
+#define	CPU_CLIDR_LOC(reg)	(((reg) >> 24) & 0x7)
+#define	CPU_CLIDR_LOUU(reg)	(((reg) >> 27) & 0x7)
+
+#define	CACHE_ICACHE		1
+#define	CACHE_DCACHE		2
+#define	CACHE_SEP_CACHE		3
+#define	CACHE_UNI_CACHE		4
+
+/* Fault status register definitions */
+#define FAULT_USER      0x10
+
+#if __ARM_ARCH < 6
+#define FAULT_TYPE_MASK 0x0f
+#define FAULT_WRTBUF_0  0x00 /* Vector Exception */
+#define FAULT_WRTBUF_1  0x02 /* Terminal Exception */
+#define FAULT_BUSERR_0  0x04 /* External Abort on Linefetch -- Section */
+#define FAULT_BUSERR_1  0x06 /* External Abort on Linefetch -- Page */
+#define FAULT_BUSERR_2  0x08 /* External Abort on Non-linefetch -- Section */
+#define FAULT_BUSERR_3  0x0a /* External Abort on Non-linefetch -- Page */
+#define FAULT_BUSTRNL1  0x0c /* External abort on Translation -- Level 1 */
+#define FAULT_BUSTRNL2  0x0e /* External abort on Translation -- Level 2 */
+#define FAULT_ALIGN_0   0x01 /* Alignment */
+#define FAULT_ALIGN_1   0x03 /* Alignment */
+#define FAULT_TRANS_S   0x05 /* Translation -- Section */
+#define FAULT_TRANS_F   0x06 /* Translation -- Flag */
+#define FAULT_TRANS_P   0x07 /* Translation -- Page */
+#define FAULT_DOMAIN_S  0x09 /* Domain -- Section */
+#define FAULT_DOMAIN_P  0x0b /* Domain -- Page */
+#define FAULT_PERM_S    0x0d /* Permission -- Section */
+#define FAULT_PERM_P    0x0f /* Permission -- Page */
+
+#define	FAULT_IMPRECISE	0x400	/* Imprecise exception (XSCALE) */
+#define	FAULT_EXTERNAL	0x400	/* External abort (armv6+) */
+#define	FAULT_WNR	0x800	/* Write-not-Read access (armv6+) */
+
+#else /* __ARM_ARCH < 6 */
+
+#define FAULT_ALIGN		0x001	/* Alignment Fault */
+#define FAULT_DEBUG		0x002	/* Debug Event */
+#define FAULT_ACCESS_L1		0x003	/* Access Bit (L1) */
+#define FAULT_ICACHE		0x004	/* Instruction cache maintenance */
+#define FAULT_TRAN_L1		0x005	/* Translation Fault (L1) */
+#define FAULT_ACCESS_L2		0x006	/* Access Bit (L2) */
+#define FAULT_TRAN_L2		0x007	/* Translation Fault (L2) */
+#define FAULT_EA_PREC		0x008	/* External Abort */
+#define FAULT_DOMAIN_L1		0x009	/* Domain Fault (L1) */
+#define FAULT_DOMAIN_L2		0x00B	/* Domain Fault (L2) */
+#define FAULT_EA_TRAN_L1	0x00C	/* External Translation Abort (L1) */
+#define FAULT_PERM_L1		0x00D	/* Permission Fault (L1) */
+#define FAULT_EA_TRAN_L2	0x00E	/* External Translation Abort (L2) */
+#define FAULT_PERM_L2		0x00F	/* Permission Fault (L2) */
+#define FAULT_TLB_CONFLICT	0x010	/* Permission Fault (L2) */
+#define FAULT_EA_IMPREC		0x016	/* Asynchronous External Abort */
+#define FAULT_PE_IMPREC		0x018	/* Asynchronous Parity Error */
+#define FAULT_PARITY		0x019	/* Parity Error */
+#define FAULT_PE_TRAN_L1	0x01C	/* Parity Error on Translation (L1) */
+#define FAULT_PE_TRAN_L2	0x01E	/* Parity Error on Translation (L2) */
+
+#define FSR_TO_FAULT(fsr)	(((fsr) & 0xF) | 			\
+				 ((((fsr) & (1 << 10)) >> (10 - 4))))
+#define FSR_LPAE		(1 <<  9) /* LPAE indicator */
+#define FSR_WNR			(1 << 11) /* Write-not-Read access */
+#define FSR_EXT			(1 << 12) /* DECERR/SLVERR for external*/
+#define FSR_CM			(1 << 13) /* Cache maintenance fault */
+#endif /* !__ARM_ARCH < 6 */
+
+/*
+ * Address of the vector page, low and high versions.
+ */
+#ifndef __ASSEMBLER__
+#define	ARM_VECTORS_LOW		0x00000000U
+#define	ARM_VECTORS_HIGH	0xffff0000U
+#else
+#define	ARM_VECTORS_LOW		0
+#define	ARM_VECTORS_HIGH	0xffff0000
+#endif
+
+/*
+ * ARM Instructions
+ *
+ *       3 3 2 2 2
+ *       1 0 9 8 7                                                     0
+ *      +-------+-------------------------------------------------------+
+ *      | cond  |              instruction dependant                    |
+ *      |c c c c|                                                       |
+ *      +-------+-------------------------------------------------------+
+ */
+
+#define INSN_SIZE		4		/* Always 4 bytes */
+#define INSN_COND_MASK		0xf0000000	/* Condition mask */
+#define INSN_COND_AL		0xe0000000	/* Always condition */
+
+#define THUMB_INSN_SIZE		2		/* Some are 4 bytes.  */
+
+#endif /* !MACHINE_ARMREG_H */


Property changes on: trunk/sys/arm/include/armreg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/asm.h
===================================================================
--- trunk/sys/arm/include/asm.h	                        (rev 0)
+++ trunk/sys/arm/include/asm.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,244 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: asm.h,v 1.5 2003/08/07 16:26:53 agc Exp $	*/
+
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ *	from: @(#)asm.h	5.5 (Berkeley) 5/7/91
+ *
+ * $FreeBSD: stable/10/sys/arm/include/asm.h 278652 2015-02-13 00:49:47Z ian $
+ */
+
+#ifndef _MACHINE_ASM_H_
+#define _MACHINE_ASM_H_
+#include <sys/cdefs.h>
+#include <machine/acle-compat.h>
+#include <machine/sysreg.h>
+
+#define	_C_LABEL(x)	x
+#define	_ASM_LABEL(x)	x
+
+#ifndef _ALIGN_TEXT
+# define _ALIGN_TEXT .align 2
+#endif
+
+#if defined(__ARM_EABI__) && !defined(_STANDALONE)
+#define	STOP_UNWINDING	.cantunwind
+#define	_FNSTART	.fnstart
+#define	_FNEND		.fnend
+#else
+#define	STOP_UNWINDING
+#define	_FNSTART
+#define	_FNEND
+#endif
+
+/*
+ * gas/arm uses @ as a single comment character and thus cannot be used here.
+ * It recognises the # instead of an @ symbol in .type directives.
+ */
+#define	_ASM_TYPE_FUNCTION	#function
+#define	_ASM_TYPE_OBJECT	#object
+
+/* XXX Is this still the right prologue for profiling? */
+#ifdef GPROF
+#define	_PROF_PROLOGUE	\
+	mov ip, lr;	\
+	bl __mcount
+#else
+#define	_PROF_PROLOGUE
+#endif
+
+/*
+ * EENTRY()/EEND() mark "extra" entry/exit points from a function.
+ * LEENTRY()/LEEND() are the the same for local symbols.
+ * The unwind info cannot handle the concept of a nested function, or a function
+ * with multiple .fnstart directives, but some of our assembler code is written
+ * with multiple labels to allow entry at several points.  The EENTRY() macro
+ * defines such an extra entry point without a new .fnstart, so that it's
+ * basically just a label that you can jump to.  The EEND() macro does nothing
+ * at all, except document the exit point associated with the same-named entry.
+ */
+#define	GLOBAL(x)	.global x
+
+#define	_LEENTRY(x) 	.type x,_ASM_TYPE_FUNCTION; x:
+#define	_LEEND(x)	/* nothing */
+#define	_EENTRY(x) 	GLOBAL(x); _LEENTRY(x)
+#define	_EEND(x)	_LEEND(x)
+
+#define	_LENTRY(x)	.text; _ALIGN_TEXT; _LEENTRY(x); _FNSTART
+#define	_LEND(x)	.size x, . - x; _FNEND
+#define	_ENTRY(x)	.text; _ALIGN_TEXT; _EENTRY(x); _FNSTART
+#define	_END(x)		_LEND(x)
+
+#define	ENTRY(y)	_ENTRY(_C_LABEL(y)); _PROF_PROLOGUE
+#define	EENTRY(y)	_EENTRY(_C_LABEL(y));
+#define	ENTRY_NP(y)	_ENTRY(_C_LABEL(y))
+#define	EENTRY_NP(y)	_EENTRY(_C_LABEL(y))
+#define	END(y)		_END(_C_LABEL(y))
+#define	EEND(y)		_EEND(_C_LABEL(y))
+#define	ASENTRY(y)	_ENTRY(_ASM_LABEL(y)); _PROF_PROLOGUE
+#define	ASLENTRY(y)	_LENTRY(_ASM_LABEL(y)); _PROF_PROLOGUE
+#define	ASEENTRY(y)	_EENTRY(_ASM_LABEL(y));
+#define	ASLEENTRY(y)	_LEENTRY(_ASM_LABEL(y));
+#define	ASENTRY_NP(y)	_ENTRY(_ASM_LABEL(y))
+#define	ASLENTRY_NP(y)	_LENTRY(_ASM_LABEL(y))
+#define	ASEENTRY_NP(y)	_EENTRY(_ASM_LABEL(y))
+#define	ASLEENTRY_NP(y)	_LEENTRY(_ASM_LABEL(y))
+#define	ASEND(y)	_END(_ASM_LABEL(y))
+#define	ASLEND(y)	_LEND(_ASM_LABEL(y))
+#define	ASEEND(y)	_EEND(_ASM_LABEL(y))
+#define	ASLEEND(y)	_LEEND(_ASM_LABEL(y))
+
+#define	ASMSTR		.asciz
+
+#if defined(PIC)
+#define	PLT_SYM(x)	PIC_SYM(x, PLT)
+#define	GOT_SYM(x)	PIC_SYM(x, GOT)
+#define	GOT_GET(x,got,sym)	\
+	ldr	x, sym;		\
+	ldr	x, [x, got]
+#define	GOT_INIT(got,gotsym,pclabel) \
+	ldr	got, gotsym;	\
+	pclabel: add	got, got, pc
+#ifdef __thumb__
+#define	GOT_INITSYM(gotsym,pclabel) \
+	.align 2;		\
+	gotsym: .word _C_LABEL(_GLOBAL_OFFSET_TABLE_) - (pclabel+4)
+#else
+#define	GOT_INITSYM(gotsym,pclabel) \
+	.align 2;		\
+	gotsym: .word _C_LABEL(_GLOBAL_OFFSET_TABLE_) - (pclabel+8)
+#endif
+
+#ifdef __STDC__
+#define	PIC_SYM(x,y)	x ## ( ## y ## )
+#else
+#define	PIC_SYM(x,y)	x/**/(/**/y/**/)
+#endif
+
+#else
+#define	PLT_SYM(x)	x
+#define	GOT_SYM(x)	x
+#define	GOT_GET(x,got,sym)	\
+	ldr	x, sym;
+#define	GOT_INIT(got,gotsym,pclabel)
+#define	GOT_INITSYM(gotsym,pclabel)
+#define	PIC_SYM(x,y)	x
+#endif	/* PIC */
+
+#undef __FBSDID
+#if !defined(lint) && !defined(STRIP_FBSDID)
+#define __FBSDID(s)     .ident s
+#else
+#define __FBSDID(s)     /* nothing */
+#endif
+	
+
+#define	WEAK_ALIAS(alias,sym)						\
+	.weak alias;							\
+	alias = sym
+
+#ifdef __STDC__
+#define	WARN_REFERENCES(sym,msg)					\
+	.stabs msg ## ,30,0,0,0 ;					\
+	.stabs __STRING(_C_LABEL(sym)) ## ,1,0,0,0
+#else
+#define	WARN_REFERENCES(sym,msg)					\
+	.stabs msg,30,0,0,0 ;						\
+	.stabs __STRING(sym),1,0,0,0
+#endif /* __STDC__ */
+
+/* Exactly one of the __ARM_ARCH_*__ macros will be defined by the compiler. */
+/* The _ARM_ARCH_* macros are deprecated and will be removed soon. */
+/* This should be moved into another header so it can be used in
+ * both asm and C code. machine/asm.h cannot be included in C code. */
+#if defined (__ARM_ARCH_7__) || defined (__ARM_ARCH_7A__)
+#define _ARM_ARCH_7
+#define _HAVE_ARMv7_INSTRUCTIONS 1
+#endif
+
+#if defined (_HAVE_ARMv7_INSTRUCTIONS) || defined (__ARM_ARCH_6__) || \
+	defined (__ARM_ARCH_6J__) || defined (__ARM_ARCH_6K__) || \
+	defined (__ARM_ARCH_6Z__) || defined (__ARM_ARCH_6ZK__)
+#define _ARM_ARCH_6
+#define _HAVE_ARMv6_INSTRUCTIONS 1
+#endif
+
+#if defined (_HAVE_ARMv6_INSTRUCTIONS) || defined (__ARM_ARCH_5TE__) || \
+    defined (__ARM_ARCH_5TEJ__) || defined (__ARM_ARCH_5E__)
+#define _ARM_ARCH_5E
+#define _HAVE_ARMv5E_INSTRUCTIONS 1
+#endif
+
+#if defined (_HAVE_ARMv5E_INSTRUCTIONS) || defined (__ARM_ARCH_5__) || \
+    defined (__ARM_ARCH_5T__)
+#define _ARM_ARCH_5
+#define _HAVE_ARMv5_INSTRUCTIONS 1
+#endif
+
+#if defined (_HAVE_ARMv5_INSTRUCTIONS) || defined (__ARM_ARCH_4T__)
+#define _ARM_ARCH_4T
+#define _HAVE_ARMv4T_INSTRUCTIONS 1
+#endif
+
+/* FreeBSD requires ARMv4, so this is always set. */
+#define _HAVE_ARMv4_INSTRUCTIONS 1
+
+#if defined (_HAVE_ARMv4T_INSTRUCTIONS)
+# define RET	bx	lr
+# define RETeq	bxeq	lr
+# define RETne	bxne	lr
+# define RETc(c) bx##c	lr
+#else
+# define RET	mov	pc, lr
+# define RETeq	moveq	pc, lr
+# define RETne	movne	pc, lr
+# define RETc(c) mov##c	pc, lr
+#endif
+
+#if __ARM_ARCH >= 7
+#define ISB	isb
+#define DSB	dsb
+#define DMB	dmb
+#define WFI	wfi
+#elif __ARM_ARCH == 6
+#define ISB	mcr CP15_CP15ISB
+#define DSB	mcr CP15_CP15DSB
+#define DMB	mcr CP15_CP15DMB
+#define WFI	mcr CP15_CP15WFI
+#else
+#define ISB	mcr CP15_CP15ISB
+#define DSB	mcr CP15_CP15DSB	/* DSB and DMB are the */
+#define DMB	mcr CP15_CP15DSB	/* same prior to v6.*/
+/* No form of WFI available on v4, define nothing to get an error on use. */
+#endif
+
+#endif /* !_MACHINE_ASM_H_ */


Property changes on: trunk/sys/arm/include/asm.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/asmacros.h
===================================================================
--- trunk/sys/arm/include/asmacros.h	                        (rev 0)
+++ trunk/sys/arm/include/asmacros.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,53 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Olivier Houchard <cognet at FreeBSD.org>
+ * 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: stable/10/sys/arm/include/asmacros.h 266311 2014-05-17 13:53:38Z ian $
+ */
+
+#ifndef	_MACHINE_ASMACROS_H_
+#define	_MACHINE_ASMACROS_H_
+
+#include <machine/asm.h>
+
+#ifdef _KERNEL
+
+#ifdef LOCORE
+#include "opt_global.h"
+
+#ifdef _ARM_ARCH_6
+#define GET_CURTHREAD_PTR(tmp) \
+    	mrc	p15, 0, tmp, c13, c0, 4
+#else
+#define GET_CURTHREAD_PTR(tmp)	\
+	ldr	tmp, =_C_LABEL(__pcpu);\
+	ldr	tmp, [tmp, #PC_CURTHREAD]
+#endif
+
+#endif /* LOCORE */
+
+#endif /* _KERNEL */
+
+#endif /* !_MACHINE_ASMACROS_H_ */


Property changes on: trunk/sys/arm/include/asmacros.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/at91_gpio.h
===================================================================
--- trunk/sys/arm/include/at91_gpio.h	                        (rev 0)
+++ trunk/sys/arm/include/at91_gpio.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,109 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (C) 2006 M. Warner Losh. All rights reserved.
+ * Copyright (C) 2012 Ian Lepore. 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 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 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: stable/10/sys/arm/include/at91_gpio.h 248911 2013-03-29 19:52:57Z ian $
+ */
+
+#ifndef _ARM_AT91_GPIO_H
+#define _ARM_AT91_GPIO_H
+
+#ifndef _KERNEL
+#include <sys/types.h>
+#endif
+#include <sys/ioccom.h>
+
+/* Userland GPIO API for Atmel AT91 series SOC.
+ *
+ * Open /dev/pioN (where N is 0 for PIOA, 1 for PIOB, etc), and use ioctl(2)
+ * calls to configure the pin(s) as needed.
+ *
+ * The userland interrupt support allows you to use read(2) and/or select(2) to
+ * get notified of interrupts on PIO pins for which you enabled interrupt
+ * notifications.  Each time an interrupt occurs on a given pin, that pin number
+ * is written into a buffer as a uint8_t.  Thus, reading from /dev/pioN delivers
+ * info on which interrupt(s) have occurred since the last read.  You can also
+ * use select() to block until an interrupt occurs (you still need to read() to
+ * consume the interrupt number bytes from the buffer.)
+ */
+
+struct at91_gpio_info
+{
+	uint32_t	output_status;	/* Current state of output pins */
+	uint32_t	input_status;	/* 1->out 0->in bitmask */
+	uint32_t	highz_status;	/* 1->highz 0->driven bitmask */
+	uint32_t	pullup_status;	/* 1->floating 0->pullup engaged */
+	uint32_t	glitch_status;	/* 0-> no glitch filter 1->gf */
+	uint32_t	enabled_status;	/* 1->used for pio 0->other */
+	uint32_t	periph_status;	/* 0->A periph 1->B periph */
+	uint32_t	intr_status;	/* 1-> ISR enabled, 0->disabled */
+	uint32_t	extra_status[8];/* Extra status info, device depend */
+};
+
+struct at91_gpio_cfg
+{
+	uint32_t	cfgmask;	/* which things change */
+#define	AT91_GPIO_CFG_INPUT 	0x01	/* configure input/output pins */
+#define	AT91_GPIO_CFG_HI_Z  	0x02	/* HiZ */
+#define	AT91_GPIO_CFG_PULLUP	0x04	/* Enable/disable pullup resistors */
+#define	AT91_GPIO_CFG_GLITCH	0x08	/* Glitch filtering */
+#define	AT91_GPIO_CFG_GPIO  	0x10	/* Use pin for PIO or peripheral */
+#define	AT91_GPIO_CFG_PERIPH	0x20	/* Select which peripheral to use */
+#define	AT91_GPIO_CFG_INTR  	0x40	/* Select pin for interrupts */
+	uint32_t	iomask;		/* Mask of bits to change */
+	uint32_t	input;		/* or output */
+	uint32_t	hi_z;		/* Disable output */
+	uint32_t	pullup;		/* Enable pullup resistor */
+	uint32_t	glitch;		/* Glitch filtering */
+	uint32_t	gpio;		/* Enabled for PIO (1) or periph (0) */
+	uint32_t	periph;		/* Select periph A (0) or periph B (1) */
+	uint32_t	intr;		/* Enable interrupt (1), or not (0) */
+};
+
+struct at91_gpio_bang
+{
+	uint32_t	clockpin;	/* clock pin MASK */
+	uint32_t	datapin; 	/* Data pin MASK */
+	uint32_t	bits;		/* bits to clock out (all 32) */
+};
+
+struct at91_gpio_bang_many
+{
+	uint32_t	clockpin;	/* clock pin MASK */
+	uint32_t	datapin;	/* Data pin MASK */
+	void		*bits;		/* bits to clock out */
+	uint32_t	numbits;	/* Number of bits to clock out */
+};
+
+#define	AT91_GPIO_SET		_IOW('g', 0, uint32_t)			/* Turn bits on */
+#define	AT91_GPIO_CLR		_IOW('g', 1, uint32_t)			/* Turn bits off */
+#define	AT91_GPIO_READ		_IOR('g', 2, uint32_t)			/* Read input bit state */
+#define	AT91_GPIO_INFO		_IOR('g', 3, struct at91_gpio_info)	/* State of pio cfg */
+#define	AT91_GPIO_CFG		_IOW('g', 4, struct at91_gpio_cfg)	/* Configure pio */
+#define	AT91_GPIO_BANG		_IOW('g', 5, struct at91_gpio_bang)	/* bit bang 32 bits */
+#define	AT91_GPIO_BANG_MANY	_IOW('g', 6, struct at91_gpio_bang_many)/* bit bang >32 bits */
+
+#endif /* _ARM_AT91_GPIO_H */
+


Property changes on: trunk/sys/arm/include/at91_gpio.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/atags.h
===================================================================
--- trunk/sys/arm/include/atags.h	                        (rev 0)
+++ trunk/sys/arm/include/atags.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,130 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 M. Warner Losh.
+ * 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: stable/10/sys/arm/include/atags.h 237069 2012-06-14 14:38:55Z imp $
+ */
+
+#ifndef	__MACHINE_ATAGS_H__
+#define __MACHINE_ATAGS_H__
+
+/*
+ * Linux boot ABI compatable ATAG definitions.  All these structures
+ * assume tight packing, but since they are all uint32_t's, I've not
+ * bothered to do the usual alignment dance.
+ */
+
+#define	LBABI_MAX_COMMAND_LINE  1024
+
+struct arm_lbabi_header
+{
+	uint32_t	size;		/* Size of this node, including header */
+	uint32_t	tag;		/* Node type */
+};
+
+#define	ATAG_NONE       0x00000000	/* End of atags list */
+#define	ATAG_CORE	0x54410001	/* List must start with ATAG_CORE */
+#define	ATAG_MEM	0x54410002	/* Multiple ATAG_MEM nodes possible */
+#define	ATAG_VIDEOTEXT	0x54410003	/* Video parameters */
+#define	ATAG_RAMDISK	0x54410004	/* Describes the ramdisk parameters */
+#define	ATAG_INITRD	0x54410005	/* Deprecated ramdisk -- used va not pa */
+#define	ATAG_INITRD2	0x54420005	/* compressed ramdisk image */
+#define	ATAG_SERIAL	0x54410006	/* 64-bits of serial number */
+#define	ATAG_REVISION	0x54410007	/* Board revision */
+#define	ATAG_VIDEOLFB	0x54410008	/* vesafb framebuffer */
+#define	ATAG_CMDLINE	0x54410009	/* Command line */
+
+/*
+ * ATAG_CORE data
+ */
+struct arm_lbabi_core
+{
+	uint32_t flags;			/* bit 0 == read-only */
+	uint32_t pagesize;
+	uint32_t rootdev;
+};
+		
+/*
+ * ATAG_MEM data -- Can be more than one to describe different
+ * banks.
+ */
+struct arm_lbabi_mem32
+{
+	uint32_t size;
+	uint32_t start;			/* start of physical memory */
+};
+
+/* 
+ * ATAG_INITRD2 - Compressed ramdisk image details
+ */
+struct arm_lbabi_initrd
+{
+	uint32_t start;			/* pa of start */
+	uint32_t size;			/* How big the ram disk is */
+};
+
+/*
+ * ATAG_SERIAL - serial number
+ */
+struct arm_lbabi_serial_number
+{
+	uint32_t low;
+	uint32_t high;
+};
+	
+/*
+ * ATAG_REVISION - board revision
+ */
+struct arm_lbabi_revision
+{
+	uint32_t rev;
+};
+	
+/*
+ * ATAG_CMDLINE - Command line from uboot
+ */
+struct arm_lbabi_command_line
+{
+	char command[1];		/* Minimum command length */
+};
+
+struct arm_lbabi_tag 
+{
+	struct arm_lbabi_header tag_hdr;
+	union {
+		struct arm_lbabi_core tag_core;
+		struct arm_lbabi_mem32 tag_mem;
+		struct arm_lbabi_initrd tag_initrd;
+		struct arm_lbabi_serial_number tag_sn;
+		struct arm_lbabi_revision tag_rev;
+		struct arm_lbabi_command_line tag_cmd;
+	} u;
+};
+
+#define	ATAG_TAG(a)  (a)->tag_hdr.tag
+#define ATAG_SIZE(a) (a)->tag_hdr.size
+#define ATAG_NEXT(a) (struct arm_lbabi_tag *)((char *)(a) + ATAG_SIZE(a))
+
+#endif /* __MACHINE_ATAGS_H__ */


Property changes on: trunk/sys/arm/include/atags.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/atomic.h
===================================================================
--- trunk/sys/arm/include/atomic.h	                        (rev 0)
+++ trunk/sys/arm/include/atomic.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,1135 @@
+/* $MidnightBSD$ */
+/* $NetBSD: atomic.h,v 1.1 2002/10/19 12:22:34 bsh Exp $ */
+
+/*-
+ * Copyright (C) 2003-2004 Olivier Houchard
+ * Copyright (C) 1994-1997 Mark Brinicombe
+ * Copyright (C) 1994 Brini
+ * All rights reserved.
+ *
+ * This code is derived from software written for Brini by Mark Brinicombe
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Brini.
+ * 4. The name of Brini may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BRINI ``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 BRINI 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: stable/10/sys/arm/include/atomic.h 283317 2015-05-23 17:30:30Z ian $
+ */
+
+#ifndef	_MACHINE_ATOMIC_H_
+#define	_MACHINE_ATOMIC_H_
+
+#include <sys/types.h>
+#include <machine/armreg.h>
+
+#ifndef _KERNEL
+#include <machine/sysarch.h>
+#else
+#include <machine/cpuconf.h>
+#endif
+
+#if defined (__ARM_ARCH_7__) || defined (__ARM_ARCH_7A__)
+#define isb()  __asm __volatile("isb" : : : "memory")
+#define dsb()  __asm __volatile("dsb" : : : "memory")
+#define dmb()  __asm __volatile("dmb" : : : "memory")
+#elif defined (__ARM_ARCH_6__) || defined (__ARM_ARCH_6J__) || \
+  defined (__ARM_ARCH_6K__) || defined (__ARM_ARCH_6T2__) || \
+  defined (__ARM_ARCH_6Z__) || defined (__ARM_ARCH_6ZK__)
+#define isb()  __asm __volatile("mcr p15, 0, %0, c7, c5, 4" : : "r" (0) : "memory")
+#define dsb()  __asm __volatile("mcr p15, 0, %0, c7, c10, 4" : : "r" (0) : "memory")
+#define dmb()  __asm __volatile("mcr p15, 0, %0, c7, c10, 5" : : "r" (0) : "memory")
+#else
+#define isb()  __asm __volatile("mcr p15, 0, %0, c7, c5, 4" : : "r" (0) : "memory")
+#define dsb()  __asm __volatile("mcr p15, 0, %0, c7, c10, 4" : : "r" (0) : "memory")
+#define dmb()  dsb()
+#endif
+
+#define mb()   dmb()
+#define wmb()  dmb()
+#define rmb()  dmb()
+
+
+
+/*
+ * It would be nice to use _HAVE_ARMv6_INSTRUCTIONS from machine/asm.h
+ * here, but that header can't be included here because this is C
+ * code.  I would like to move the _HAVE_ARMv6_INSTRUCTIONS definition
+ * out of asm.h so it can be used in both asm and C code. - kientzle@
+ */
+#if defined (__ARM_ARCH_7__) || \
+	defined (__ARM_ARCH_7A__)  || \
+	defined (__ARM_ARCH_6__)   || \
+	defined (__ARM_ARCH_6J__)  || \
+	defined (__ARM_ARCH_6K__)  || \
+	defined (__ARM_ARCH_6T2__) || \
+	defined (__ARM_ARCH_6Z__)  || \
+	defined (__ARM_ARCH_6ZK__)
+#define	ARM_HAVE_ATOMIC64
+
+static __inline void
+__do_dmb(void)
+{
+
+#if defined (__ARM_ARCH_7__) || defined (__ARM_ARCH_7A__)
+	__asm __volatile("dmb" : : : "memory");
+#else
+	__asm __volatile("mcr p15, 0, r0, c7, c10, 5" : : : "memory");
+#endif
+}
+
+#define ATOMIC_ACQ_REL_LONG(NAME)					\
+static __inline void							\
+atomic_##NAME##_acq_long(__volatile u_long *p, u_long v)		\
+{									\
+	atomic_##NAME##_long(p, v);					\
+	__do_dmb();							\
+}									\
+									\
+static __inline  void							\
+atomic_##NAME##_rel_long(__volatile u_long *p, u_long v)		\
+{									\
+	__do_dmb();							\
+	atomic_##NAME##_long(p, v);					\
+}
+
+#define	ATOMIC_ACQ_REL(NAME, WIDTH)					\
+static __inline  void							\
+atomic_##NAME##_acq_##WIDTH(__volatile uint##WIDTH##_t *p, uint##WIDTH##_t v)\
+{									\
+	atomic_##NAME##_##WIDTH(p, v);					\
+	__do_dmb();							\
+}									\
+									\
+static __inline  void							\
+atomic_##NAME##_rel_##WIDTH(__volatile uint##WIDTH##_t *p, uint##WIDTH##_t v)\
+{									\
+	__do_dmb();							\
+	atomic_##NAME##_##WIDTH(p, v);					\
+}
+
+static __inline void
+atomic_set_32(volatile uint32_t *address, uint32_t setmask)
+{
+	uint32_t tmp = 0, tmp2 = 0;
+
+	__asm __volatile("1: ldrex %0, [%2]\n"
+	    		    "orr %0, %0, %3\n"
+			    "strex %1, %0, [%2]\n"
+			    "cmp %1, #0\n"
+	                    "it ne\n"
+			    "bne	1b\n"
+			   : "=&r" (tmp), "+r" (tmp2)
+			   , "+r" (address), "+r" (setmask) : : "cc", "memory");
+			     
+}
+
+static __inline void
+atomic_set_64(volatile uint64_t *p, uint64_t val)
+{
+	uint64_t tmp;
+	uint32_t exflag;
+
+	__asm __volatile(
+		"1:          \n"
+		"   ldrexd   %[tmp], [%[ptr]]\n"
+		"   orr      %Q[tmp], %Q[val]\n"
+		"   orr      %R[tmp], %R[val]\n"
+		"   strexd   %[exf], %[tmp], [%[ptr]]\n"
+		"   teq      %[exf], #0\n"
+		"   it ne    \n"
+		"   bne      1b\n"
+		:   [exf]    "=&r"  (exflag), 
+		    [tmp]    "=&r"  (tmp)
+		:   [ptr]    "r"    (p), 
+		    [val]    "r"    (val)
+		:   "cc", "memory");
+}
+
+static __inline void
+atomic_set_long(volatile u_long *address, u_long setmask)
+{
+	u_long tmp = 0, tmp2 = 0;
+
+	__asm __volatile("1: ldrex %0, [%2]\n"
+	    		    "orr %0, %0, %3\n"
+			    "strex %1, %0, [%2]\n"
+			    "cmp %1, #0\n"
+	                    "it ne\n"
+			    "bne	1b\n"
+			   : "=&r" (tmp), "+r" (tmp2)
+			   , "+r" (address), "+r" (setmask) : : "cc", "memory");
+			     
+}
+
+static __inline void
+atomic_clear_32(volatile uint32_t *address, uint32_t setmask)
+{
+	uint32_t tmp = 0, tmp2 = 0;
+
+	__asm __volatile("1: ldrex %0, [%2]\n"
+	    		    "bic %0, %0, %3\n"
+			    "strex %1, %0, [%2]\n"
+			    "cmp %1, #0\n"
+	                    "it ne\n"
+			    "bne	1b\n"
+			   : "=&r" (tmp), "+r" (tmp2)
+			   ,"+r" (address), "+r" (setmask) : : "cc", "memory");
+}
+
+static __inline void
+atomic_clear_64(volatile uint64_t *p, uint64_t val)
+{
+	uint64_t tmp;
+	uint32_t exflag;
+
+	__asm __volatile(
+		"1:          \n"
+		"   ldrexd   %[tmp], [%[ptr]]\n"
+		"   bic      %Q[tmp], %Q[val]\n"
+		"   bic      %R[tmp], %R[val]\n"
+		"   strexd   %[exf], %[tmp], [%[ptr]]\n"
+		"   teq      %[exf], #0\n"
+		"   it ne    \n"
+		"   bne      1b\n"
+		:   [exf]    "=&r"  (exflag), 
+		    [tmp]    "=&r"  (tmp)
+		:   [ptr]    "r"    (p), 
+		    [val]    "r"    (val)
+		:   "cc", "memory");
+}
+
+static __inline void
+atomic_clear_long(volatile u_long *address, u_long setmask)
+{
+	u_long tmp = 0, tmp2 = 0;
+
+	__asm __volatile("1: ldrex %0, [%2]\n"
+	    		    "bic %0, %0, %3\n"
+			    "strex %1, %0, [%2]\n"
+			    "cmp %1, #0\n"
+	                    "it ne\n"
+			    "bne	1b\n"
+			   : "=&r" (tmp), "+r" (tmp2)
+			   ,"+r" (address), "+r" (setmask) : : "cc", "memory");
+}
+
+static __inline u_int32_t
+atomic_cmpset_32(volatile u_int32_t *p, volatile u_int32_t cmpval, volatile u_int32_t newval)
+{
+	uint32_t ret;
+	
+	__asm __volatile("1: ldrex %0, [%1]\n"
+	                 "cmp %0, %2\n"
+	                 "itt ne\n"
+			 "movne %0, #0\n"
+			 "bne 2f\n"
+			 "strex %0, %3, [%1]\n"
+			 "cmp %0, #0\n"
+	                 "ite eq\n"
+			 "moveq %0, #1\n"
+			 "bne	1b\n"
+			 "2:"
+			 : "=&r" (ret)
+			 ,"+r" (p), "+r" (cmpval), "+r" (newval) : : "cc",
+			 "memory");
+	return (ret);
+}
+
+static __inline int
+atomic_cmpset_64(volatile uint64_t *p, uint64_t cmpval, uint64_t newval)
+{
+	uint64_t tmp;
+	uint32_t ret;
+
+	__asm __volatile(
+		"1:          \n"
+		"   ldrexd   %[tmp], [%[ptr]]\n"
+		"   teq      %Q[tmp], %Q[cmpval]\n"
+		"   itee eq  \n"
+		"   teqeq    %R[tmp], %R[cmpval]\n"
+		"   movne    %[ret], #0\n"
+		"   bne      2f\n"
+		"   strexd   %[ret], %[newval], [%[ptr]]\n"
+		"   teq      %[ret], #0\n"
+		"   it ne    \n"
+		"   bne      1b\n"
+		"   mov      %[ret], #1\n"
+		"2:          \n"
+		:   [ret]    "=&r"  (ret), 
+		    [tmp]    "=&r"  (tmp)
+		:   [ptr]    "r"    (p), 
+		    [cmpval] "r"    (cmpval), 
+		    [newval] "r"    (newval)
+		:   "cc", "memory");
+	return (ret);
+}
+
+static __inline u_long
+atomic_cmpset_long(volatile u_long *p, volatile u_long cmpval, volatile u_long newval)
+{
+	u_long ret;
+	
+	__asm __volatile("1: ldrex %0, [%1]\n"
+	                 "cmp %0, %2\n"
+	                 "itt ne\n"
+			 "movne %0, #0\n"
+			 "bne 2f\n"
+			 "strex %0, %3, [%1]\n"
+			 "cmp %0, #0\n"
+	                 "ite eq\n"
+			 "moveq %0, #1\n"
+			 "bne	1b\n"
+			 "2:"
+			 : "=&r" (ret)
+			 ,"+r" (p), "+r" (cmpval), "+r" (newval) : : "cc",
+			 "memory");
+	return (ret);
+}
+
+static __inline u_int32_t
+atomic_cmpset_acq_32(volatile u_int32_t *p, volatile u_int32_t cmpval, volatile u_int32_t newval)
+{
+	u_int32_t ret = atomic_cmpset_32(p, cmpval, newval);
+
+	__do_dmb();
+	return (ret);
+}
+
+static __inline uint64_t
+atomic_cmpset_acq_64(volatile uint64_t *p, volatile uint64_t cmpval, volatile uint64_t newval)
+{
+	uint64_t ret = atomic_cmpset_64(p, cmpval, newval);
+
+	__do_dmb();
+	return (ret);
+}
+
+static __inline u_long
+atomic_cmpset_acq_long(volatile u_long *p, volatile u_long cmpval, volatile u_long newval)
+{
+	u_long ret = atomic_cmpset_long(p, cmpval, newval);
+
+	__do_dmb();
+	return (ret);
+}
+
+static __inline u_int32_t
+atomic_cmpset_rel_32(volatile u_int32_t *p, volatile u_int32_t cmpval, volatile u_int32_t newval)
+{
+	
+	__do_dmb();
+	return (atomic_cmpset_32(p, cmpval, newval));
+}
+
+static __inline uint64_t
+atomic_cmpset_rel_64(volatile uint64_t *p, volatile uint64_t cmpval, volatile uint64_t newval)
+{
+	
+	__do_dmb();
+	return (atomic_cmpset_64(p, cmpval, newval));
+}
+
+static __inline u_long
+atomic_cmpset_rel_long(volatile u_long *p, volatile u_long cmpval, volatile u_long newval)
+{
+	
+	__do_dmb();
+	return (atomic_cmpset_long(p, cmpval, newval));
+}
+
+
+static __inline void
+atomic_add_32(volatile u_int32_t *p, u_int32_t val)
+{
+	uint32_t tmp = 0, tmp2 = 0;
+
+	__asm __volatile("1: ldrex %0, [%2]\n"
+	    		    "add %0, %0, %3\n"
+			    "strex %1, %0, [%2]\n"
+			    "cmp %1, #0\n"
+	                    "it ne\n"
+			    "bne	1b\n"
+			    : "=&r" (tmp), "+r" (tmp2)
+			    ,"+r" (p), "+r" (val) : : "cc", "memory");
+}
+
+static __inline void
+atomic_add_64(volatile uint64_t *p, uint64_t val)
+{
+	uint64_t tmp;
+	uint32_t exflag;
+
+	__asm __volatile(
+		"1:          \n"
+		"   ldrexd   %[tmp], [%[ptr]]\n"
+		"   adds     %Q[tmp], %Q[val]\n"
+		"   adc      %R[tmp], %R[val]\n"
+		"   strexd   %[exf], %[tmp], [%[ptr]]\n"
+		"   teq      %[exf], #0\n"
+		"   it ne    \n"
+		"   bne      1b\n"
+		:   [exf]    "=&r"  (exflag), 
+		    [tmp]    "=&r"  (tmp)
+		:   [ptr]    "r"    (p), 
+		    [val]    "r"    (val)
+		:   "cc", "memory");
+}
+
+static __inline void
+atomic_add_long(volatile u_long *p, u_long val)
+{
+	u_long tmp = 0, tmp2 = 0;
+
+	__asm __volatile("1: ldrex %0, [%2]\n"
+	    		    "add %0, %0, %3\n"
+			    "strex %1, %0, [%2]\n"
+			    "cmp %1, #0\n"
+	                    "it ne\n"
+			    "bne	1b\n"
+			    : "=&r" (tmp), "+r" (tmp2)
+			    ,"+r" (p), "+r" (val) : : "cc", "memory");
+}
+
+static __inline void
+atomic_subtract_32(volatile u_int32_t *p, u_int32_t val)
+{
+	uint32_t tmp = 0, tmp2 = 0;
+
+	__asm __volatile("1: ldrex %0, [%2]\n"
+	    		    "sub %0, %0, %3\n"
+			    "strex %1, %0, [%2]\n"
+			    "cmp %1, #0\n"
+	                    "it ne\n"
+			    "bne	1b\n"
+			    : "=&r" (tmp), "+r" (tmp2)
+			    ,"+r" (p), "+r" (val) : : "cc", "memory");
+}
+
+static __inline void
+atomic_subtract_64(volatile uint64_t *p, uint64_t val)
+{
+	uint64_t tmp;
+	uint32_t exflag;
+
+	__asm __volatile(
+		"1:          \n"
+		"   ldrexd   %[tmp], [%[ptr]]\n"
+		"   subs     %Q[tmp], %Q[val]\n"
+		"   sbc      %R[tmp], %R[val]\n"
+		"   strexd   %[exf], %[tmp], [%[ptr]]\n"
+		"   teq      %[exf], #0\n"
+		"   it ne    \n"
+		"   bne      1b\n"
+		:   [exf]    "=&r"  (exflag), 
+		    [tmp]    "=&r"  (tmp)
+		:   [ptr]    "r"    (p), 
+		    [val]    "r"    (val)
+		:   "cc", "memory");
+}
+
+static __inline void
+atomic_subtract_long(volatile u_long *p, u_long val)
+{
+	u_long tmp = 0, tmp2 = 0;
+
+	__asm __volatile("1: ldrex %0, [%2]\n"
+	    		    "sub %0, %0, %3\n"
+			    "strex %1, %0, [%2]\n"
+			    "cmp %1, #0\n"
+	                    "it ne\n"
+			    "bne	1b\n"
+			    : "=&r" (tmp), "+r" (tmp2)
+			    ,"+r" (p), "+r" (val) : : "cc", "memory");
+}
+
+ATOMIC_ACQ_REL(clear, 32)
+ATOMIC_ACQ_REL(add, 32)
+ATOMIC_ACQ_REL(subtract, 32)
+ATOMIC_ACQ_REL(set, 32)
+ATOMIC_ACQ_REL(clear, 64)
+ATOMIC_ACQ_REL(add, 64)
+ATOMIC_ACQ_REL(subtract, 64)
+ATOMIC_ACQ_REL(set, 64)
+ATOMIC_ACQ_REL_LONG(clear)
+ATOMIC_ACQ_REL_LONG(add)
+ATOMIC_ACQ_REL_LONG(subtract)
+ATOMIC_ACQ_REL_LONG(set)
+
+#undef ATOMIC_ACQ_REL
+#undef ATOMIC_ACQ_REL_LONG
+
+static __inline uint32_t
+atomic_fetchadd_32(volatile uint32_t *p, uint32_t val)
+{
+	uint32_t tmp = 0, tmp2 = 0, ret = 0;
+
+	__asm __volatile("1: ldrex %0, [%3]\n"
+	    		    "add %1, %0, %4\n"
+			    "strex %2, %1, [%3]\n"
+			    "cmp %2, #0\n"
+	                    "it ne\n"
+			    "bne	1b\n"
+			   : "+r" (ret), "=&r" (tmp), "+r" (tmp2)
+			   ,"+r" (p), "+r" (val) : : "cc", "memory");
+	return (ret);
+}
+
+static __inline uint32_t
+atomic_readandclear_32(volatile u_int32_t *p)
+{
+	uint32_t ret, tmp = 0, tmp2 = 0;
+
+	__asm __volatile("1: ldrex %0, [%3]\n"
+	    		 "mov %1, #0\n"
+			 "strex %2, %1, [%3]\n"
+			 "cmp %2, #0\n"
+	                 "it ne\n"
+			 "bne 1b\n"
+			 : "=r" (ret), "=&r" (tmp), "+r" (tmp2)
+			 ,"+r" (p) : : "cc", "memory");
+	return (ret);
+}
+
+static __inline uint32_t
+atomic_load_acq_32(volatile uint32_t *p)
+{
+	uint32_t v;
+
+	v = *p;
+	__do_dmb();
+	return (v);
+}
+
+static __inline void
+atomic_store_rel_32(volatile uint32_t *p, uint32_t v)
+{
+	
+	__do_dmb();
+	*p = v;
+}
+
+static __inline uint64_t
+atomic_fetchadd_64(volatile uint64_t *p, uint64_t val)
+{
+	uint64_t ret, tmp;
+	uint32_t exflag;
+
+	__asm __volatile(
+		"1:          \n"
+		"   ldrexd   %[ret], [%[ptr]]\n"
+		"   adds     %Q[tmp], %Q[ret], %Q[val]\n"
+		"   adc      %R[tmp], %R[ret], %R[val]\n"
+		"   strexd   %[exf], %[tmp], [%[ptr]]\n"
+		"   teq      %[exf], #0\n"
+		"   it ne    \n"
+		"   bne      1b\n"
+		:   [ret]    "=&r"  (ret),
+		    [exf]    "=&r"  (exflag),
+		    [tmp]    "=&r"  (tmp)
+		:   [ptr]    "r"    (p), 
+		    [val]    "r"    (val)
+		:   "cc", "memory");
+	return (ret);
+}
+
+static __inline uint64_t
+atomic_readandclear_64(volatile uint64_t *p)
+{
+	uint64_t ret, tmp;
+	uint32_t exflag;
+
+	__asm __volatile(
+		"1:          \n"
+		"   ldrexd   %[ret], [%[ptr]]\n"
+		"   mov      %Q[tmp], #0\n"
+		"   mov      %R[tmp], #0\n"
+		"   strexd   %[exf], %[tmp], [%[ptr]]\n"
+		"   teq      %[exf], #0\n"
+		"   it ne    \n"
+		"   bne      1b\n"
+		:   [ret]    "=&r"  (ret),
+		    [exf]    "=&r"  (exflag),
+		    [tmp]    "=&r"  (tmp)
+		:   [ptr]    "r"    (p)
+		:   "cc", "memory");
+	return (ret);
+}
+
+static __inline uint64_t
+atomic_load_64(volatile uint64_t *p)
+{
+	uint64_t ret;
+
+	/*
+	 * The only way to atomically load 64 bits is with LDREXD which puts the
+	 * exclusive monitor into the exclusive state, so reset it to open state
+	 * with CLREX because we don't actually need to store anything.
+	 */
+	__asm __volatile(
+		"1:          \n"
+		"   ldrexd   %[ret], [%[ptr]]\n"
+		"   clrex    \n"
+		:   [ret]    "=&r"  (ret)
+		:   [ptr]    "r"    (p)
+		:   "cc", "memory");
+	return (ret);
+}
+
+static __inline uint64_t
+atomic_load_acq_64(volatile uint64_t *p)
+{
+	uint64_t ret;
+
+	ret = atomic_load_64(p);
+	__do_dmb();
+	return (ret);
+}
+
+static __inline void
+atomic_store_64(volatile uint64_t *p, uint64_t val)
+{
+	uint64_t tmp;
+	uint32_t exflag;
+
+	/*
+	 * The only way to atomically store 64 bits is with STREXD, which will
+	 * succeed only if paired up with a preceeding LDREXD using the same
+	 * address, so we read and discard the existing value before storing.
+	 */
+	__asm __volatile(
+		"1:          \n"
+		"   ldrexd   %[tmp], [%[ptr]]\n"
+		"   strexd   %[exf], %[val], [%[ptr]]\n"
+		"   teq      %[exf], #0\n"
+		"   it ne    \n"
+		"   bne      1b\n"
+		:   [tmp]    "=&r"  (tmp),
+		    [exf]    "=&r"  (exflag)
+		:   [ptr]    "r"    (p),
+		    [val]    "r"    (val)
+		:   "cc", "memory");
+}
+
+static __inline void
+atomic_store_rel_64(volatile uint64_t *p, uint64_t val)
+{
+
+	__do_dmb();
+	atomic_store_64(p, val);
+}
+
+static __inline u_long
+atomic_fetchadd_long(volatile u_long *p, u_long val)
+{
+	u_long tmp = 0, tmp2 = 0, ret = 0;
+
+	__asm __volatile("1: ldrex %0, [%3]\n"
+	    		    "add %1, %0, %4\n"
+			    "strex %2, %1, [%3]\n"
+			    "cmp %2, #0\n"
+	                    "it ne\n"
+			    "bne	1b\n"
+			   : "+r" (ret), "=&r" (tmp), "+r" (tmp2)
+			   ,"+r" (p), "+r" (val) : : "cc", "memory");
+	return (ret);
+}
+
+static __inline u_long
+atomic_readandclear_long(volatile u_long *p)
+{
+	u_long ret, tmp = 0, tmp2 = 0;
+
+	__asm __volatile("1: ldrex %0, [%3]\n"
+	    		 "mov %1, #0\n"
+			 "strex %2, %1, [%3]\n"
+			 "cmp %2, #0\n"
+	                 "it ne\n"
+			 "bne 1b\n"
+			 : "=r" (ret), "=&r" (tmp), "+r" (tmp2)
+			 ,"+r" (p) : : "cc", "memory");
+	return (ret);
+}
+
+static __inline u_long
+atomic_load_acq_long(volatile u_long *p)
+{
+	u_long v;
+
+	v = *p;
+	__do_dmb();
+	return (v);
+}
+
+static __inline void
+atomic_store_rel_long(volatile u_long *p, u_long v)
+{
+	
+	__do_dmb();
+	*p = v;
+}
+#else /* < armv6 */
+
+#define __with_interrupts_disabled(expr) \
+	do {						\
+		u_int cpsr_save, tmp;			\
+							\
+		__asm __volatile(			\
+			"mrs  %0, cpsr;"		\
+			"orr  %1, %0, %2;"		\
+			"msr  cpsr_fsxc, %1;"		\
+			: "=r" (cpsr_save), "=r" (tmp)	\
+			: "I" (PSR_I | PSR_F)		\
+		        : "cc" );		\
+		(expr);				\
+		 __asm __volatile(		\
+			"msr  cpsr_fsxc, %0"	\
+			: /* no output */	\
+			: "r" (cpsr_save)	\
+			: "cc" );		\
+	} while(0)
+
+static __inline uint32_t
+__swp(uint32_t val, volatile uint32_t *ptr)
+{
+	__asm __volatile("swp	%0, %2, [%3]"
+	    : "=&r" (val), "=m" (*ptr)
+	    : "r" (val), "r" (ptr), "m" (*ptr)
+	    : "memory");
+	return (val);
+}
+
+
+#ifdef _KERNEL
+#define	ARM_HAVE_ATOMIC64
+
+static __inline void
+atomic_set_32(volatile uint32_t *address, uint32_t setmask)
+{
+	__with_interrupts_disabled(*address |= setmask);
+}
+
+static __inline void
+atomic_set_64(volatile uint64_t *address, uint64_t setmask)
+{
+	__with_interrupts_disabled(*address |= setmask);
+}
+
+static __inline void
+atomic_clear_32(volatile uint32_t *address, uint32_t clearmask)
+{
+	__with_interrupts_disabled(*address &= ~clearmask);
+}
+
+static __inline void
+atomic_clear_64(volatile uint64_t *address, uint64_t clearmask)
+{
+	__with_interrupts_disabled(*address &= ~clearmask);
+}
+
+static __inline u_int32_t
+atomic_cmpset_32(volatile u_int32_t *p, volatile u_int32_t cmpval, volatile u_int32_t newval)
+{
+	int ret;
+	
+	__with_interrupts_disabled(
+	 {
+	    	if (*p == cmpval) {
+			*p = newval;
+			ret = 1;
+		} else {
+			ret = 0;
+		}
+	});
+	return (ret);
+}
+
+static __inline u_int64_t
+atomic_cmpset_64(volatile u_int64_t *p, volatile u_int64_t cmpval, volatile u_int64_t newval)
+{
+	int ret;
+	
+	__with_interrupts_disabled(
+	 {
+	    	if (*p == cmpval) {
+			*p = newval;
+			ret = 1;
+		} else {
+			ret = 0;
+		}
+	});
+	return (ret);
+}
+
+static __inline void
+atomic_add_32(volatile u_int32_t *p, u_int32_t val)
+{
+	__with_interrupts_disabled(*p += val);
+}
+
+static __inline void
+atomic_add_64(volatile u_int64_t *p, u_int64_t val)
+{
+	__with_interrupts_disabled(*p += val);
+}
+
+static __inline void
+atomic_subtract_32(volatile u_int32_t *p, u_int32_t val)
+{
+	__with_interrupts_disabled(*p -= val);
+}
+
+static __inline void
+atomic_subtract_64(volatile u_int64_t *p, u_int64_t val)
+{
+	__with_interrupts_disabled(*p -= val);
+}
+
+static __inline uint32_t
+atomic_fetchadd_32(volatile uint32_t *p, uint32_t v)
+{
+	uint32_t value;
+
+	__with_interrupts_disabled(
+	{
+	    	value = *p;
+		*p += v;
+	});
+	return (value);
+}
+
+static __inline uint64_t
+atomic_fetchadd_64(volatile uint64_t *p, uint64_t v)
+{
+	uint64_t value;
+
+	__with_interrupts_disabled(
+	{
+	    	value = *p;
+		*p += v;
+	});
+	return (value);
+}
+
+static __inline uint64_t
+atomic_load_64(volatile uint64_t *p)
+{
+	uint64_t value;
+
+	__with_interrupts_disabled(value = *p);
+	return (value);
+}
+
+static __inline void
+atomic_store_64(volatile uint64_t *p, uint64_t value)
+{
+	__with_interrupts_disabled(*p = value);
+}
+
+#else /* !_KERNEL */
+
+static __inline u_int32_t
+atomic_cmpset_32(volatile u_int32_t *p, volatile u_int32_t cmpval, volatile u_int32_t newval)
+{
+	register int done, ras_start = ARM_RAS_START;
+
+	__asm __volatile("1:\n"
+	    "adr	%1, 1b\n"
+	    "str	%1, [%0]\n"
+	    "adr	%1, 2f\n"
+	    "str	%1, [%0, #4]\n"
+	    "ldr	%1, [%2]\n"
+	    "cmp	%1, %3\n"
+	    "streq	%4, [%2]\n"
+	    "2:\n"
+	    "mov	%1, #0\n"
+	    "str	%1, [%0]\n"
+	    "mov	%1, #0xffffffff\n"
+	    "str	%1, [%0, #4]\n"
+	    "moveq	%1, #1\n"
+	    "movne	%1, #0\n"
+	    : "+r" (ras_start), "=r" (done)
+	    ,"+r" (p), "+r" (cmpval), "+r" (newval) : : "cc", "memory");
+	return (done);
+}
+
+static __inline void
+atomic_add_32(volatile u_int32_t *p, u_int32_t val)
+{
+	int start, ras_start = ARM_RAS_START;
+
+	__asm __volatile("1:\n"
+	    "adr	%1, 1b\n"
+	    "str	%1, [%0]\n"
+	    "adr	%1, 2f\n"
+	    "str	%1, [%0, #4]\n"
+	    "ldr	%1, [%2]\n"
+	    "add	%1, %1, %3\n"
+	    "str	%1, [%2]\n"
+	    "2:\n"
+	    "mov	%1, #0\n"
+	    "str	%1, [%0]\n"
+	    "mov	%1, #0xffffffff\n"
+	    "str	%1, [%0, #4]\n"
+	    : "+r" (ras_start), "=r" (start), "+r" (p), "+r" (val)
+	    : : "memory");
+}
+
+static __inline void
+atomic_subtract_32(volatile u_int32_t *p, u_int32_t val)
+{
+	int start, ras_start = ARM_RAS_START;
+
+	__asm __volatile("1:\n"
+	    "adr	%1, 1b\n"
+	    "str	%1, [%0]\n"
+	    "adr	%1, 2f\n"
+	    "str	%1, [%0, #4]\n"
+	    "ldr	%1, [%2]\n"
+	    "sub	%1, %1, %3\n"
+	    "str	%1, [%2]\n"
+	    "2:\n"
+	    "mov	%1, #0\n"
+	    "str	%1, [%0]\n"
+	    "mov	%1, #0xffffffff\n"
+	    "str	%1, [%0, #4]\n"
+
+	    : "+r" (ras_start), "=r" (start), "+r" (p), "+r" (val)
+	    : : "memory");
+}
+
+static __inline void
+atomic_set_32(volatile uint32_t *address, uint32_t setmask)
+{
+	int start, ras_start = ARM_RAS_START;
+
+	__asm __volatile("1:\n"
+	    "adr	%1, 1b\n"
+	    "str	%1, [%0]\n"
+	    "adr	%1, 2f\n"
+	    "str	%1, [%0, #4]\n"
+	    "ldr	%1, [%2]\n"
+	    "orr	%1, %1, %3\n"
+	    "str	%1, [%2]\n"
+	    "2:\n"
+	    "mov	%1, #0\n"
+	    "str	%1, [%0]\n"
+	    "mov	%1, #0xffffffff\n"
+	    "str	%1, [%0, #4]\n"
+
+	    : "+r" (ras_start), "=r" (start), "+r" (address), "+r" (setmask)
+	    : : "memory");
+}
+
+static __inline void
+atomic_clear_32(volatile uint32_t *address, uint32_t clearmask)
+{
+	int start, ras_start = ARM_RAS_START;
+
+	__asm __volatile("1:\n"
+	    "adr	%1, 1b\n"
+	    "str	%1, [%0]\n"
+	    "adr	%1, 2f\n"
+	    "str	%1, [%0, #4]\n"
+	    "ldr	%1, [%2]\n"
+	    "bic	%1, %1, %3\n"
+	    "str	%1, [%2]\n"
+	    "2:\n"
+	    "mov	%1, #0\n"
+	    "str	%1, [%0]\n"
+	    "mov	%1, #0xffffffff\n"
+	    "str	%1, [%0, #4]\n"
+	    : "+r" (ras_start), "=r" (start), "+r" (address), "+r" (clearmask)
+	    : : "memory");
+
+}
+
+static __inline uint32_t
+atomic_fetchadd_32(volatile uint32_t *p, uint32_t v)
+{
+	uint32_t start, tmp, ras_start = ARM_RAS_START;
+
+	__asm __volatile("1:\n"
+	    "adr	%1, 1b\n"
+	    "str	%1, [%0]\n"
+	    "adr	%1, 2f\n"
+	    "str	%1, [%0, #4]\n"
+	    "ldr	%1, [%3]\n"
+	    "mov	%2, %1\n"
+	    "add	%2, %2, %4\n"
+	    "str	%2, [%3]\n"
+	    "2:\n"
+	    "mov	%2, #0\n"
+	    "str	%2, [%0]\n"
+	    "mov	%2, #0xffffffff\n"
+	    "str	%2, [%0, #4]\n"
+	    : "+r" (ras_start), "=r" (start), "=r" (tmp), "+r" (p), "+r" (v)
+	    : : "memory");
+	return (start);
+}
+
+#endif /* _KERNEL */
+
+
+static __inline uint32_t
+atomic_readandclear_32(volatile u_int32_t *p)
+{
+
+	return (__swp(0, p));
+}
+
+#define atomic_cmpset_rel_32	atomic_cmpset_32
+#define atomic_cmpset_acq_32	atomic_cmpset_32
+#define atomic_set_rel_32	atomic_set_32
+#define atomic_set_acq_32	atomic_set_32
+#define atomic_clear_rel_32	atomic_clear_32
+#define atomic_clear_acq_32	atomic_clear_32
+#define atomic_add_rel_32	atomic_add_32
+#define atomic_add_acq_32	atomic_add_32
+#define atomic_subtract_rel_32	atomic_subtract_32
+#define atomic_subtract_acq_32	atomic_subtract_32
+#define atomic_store_rel_32	atomic_store_32
+#define atomic_store_rel_long	atomic_store_long
+#define atomic_load_acq_32	atomic_load_32
+#define atomic_load_acq_long	atomic_load_long
+#define atomic_add_acq_long		atomic_add_long
+#define atomic_add_rel_long		atomic_add_long
+#define atomic_subtract_acq_long	atomic_subtract_long
+#define atomic_subtract_rel_long	atomic_subtract_long
+#define atomic_clear_acq_long		atomic_clear_long
+#define atomic_clear_rel_long		atomic_clear_long
+#define atomic_set_acq_long		atomic_set_long
+#define atomic_set_rel_long		atomic_set_long
+#define atomic_cmpset_acq_long		atomic_cmpset_long
+#define atomic_cmpset_rel_long		atomic_cmpset_long
+#define atomic_load_acq_long		atomic_load_long
+#undef __with_interrupts_disabled
+
+static __inline void
+atomic_add_long(volatile u_long *p, u_long v)
+{
+
+	atomic_add_32((volatile uint32_t *)p, v);
+}
+
+static __inline void
+atomic_clear_long(volatile u_long *p, u_long v)
+{
+
+	atomic_clear_32((volatile uint32_t *)p, v);
+}
+
+static __inline int
+atomic_cmpset_long(volatile u_long *dst, u_long old, u_long newe)
+{
+
+	return (atomic_cmpset_32((volatile uint32_t *)dst, old, newe));
+}
+
+static __inline u_long
+atomic_fetchadd_long(volatile u_long *p, u_long v)
+{
+
+	return (atomic_fetchadd_32((volatile uint32_t *)p, v));
+}
+
+static __inline void
+atomic_readandclear_long(volatile u_long *p)
+{
+
+	atomic_readandclear_32((volatile uint32_t *)p);
+}
+
+static __inline void
+atomic_set_long(volatile u_long *p, u_long v)
+{
+
+	atomic_set_32((volatile uint32_t *)p, v);
+}
+
+static __inline void
+atomic_subtract_long(volatile u_long *p, u_long v)
+{
+
+	atomic_subtract_32((volatile uint32_t *)p, v);
+}
+
+
+
+#endif /* Arch >= v6 */
+
+static __inline int
+atomic_load_32(volatile uint32_t *v)
+{
+
+	return (*v);
+}
+
+static __inline void
+atomic_store_32(volatile uint32_t *dst, uint32_t src)
+{
+	*dst = src;
+}
+
+static __inline int
+atomic_load_long(volatile u_long *v)
+{
+
+	return (*v);
+}
+
+static __inline void
+atomic_store_long(volatile u_long *dst, u_long src)
+{
+	*dst = src;
+}
+
+#define atomic_clear_ptr		atomic_clear_32
+#define atomic_set_ptr			atomic_set_32
+#define atomic_cmpset_ptr		atomic_cmpset_32
+#define atomic_cmpset_rel_ptr		atomic_cmpset_rel_32
+#define atomic_cmpset_acq_ptr		atomic_cmpset_acq_32
+#define atomic_store_ptr		atomic_store_32
+#define atomic_store_rel_ptr		atomic_store_rel_32
+
+#define atomic_add_int			atomic_add_32
+#define atomic_add_acq_int		atomic_add_acq_32
+#define atomic_add_rel_int		atomic_add_rel_32
+#define atomic_subtract_int		atomic_subtract_32
+#define atomic_subtract_acq_int		atomic_subtract_acq_32
+#define atomic_subtract_rel_int		atomic_subtract_rel_32
+#define atomic_clear_int		atomic_clear_32
+#define atomic_clear_acq_int		atomic_clear_acq_32
+#define atomic_clear_rel_int		atomic_clear_rel_32
+#define atomic_set_int			atomic_set_32
+#define atomic_set_acq_int		atomic_set_acq_32
+#define atomic_set_rel_int		atomic_set_rel_32
+#define atomic_cmpset_int		atomic_cmpset_32
+#define atomic_cmpset_acq_int		atomic_cmpset_acq_32
+#define atomic_cmpset_rel_int		atomic_cmpset_rel_32
+#define atomic_fetchadd_int		atomic_fetchadd_32
+#define atomic_readandclear_int		atomic_readandclear_32
+#define atomic_load_acq_int		atomic_load_acq_32
+#define atomic_store_rel_int		atomic_store_rel_32
+
+#endif /* _MACHINE_ATOMIC_H_ */


Property changes on: trunk/sys/arm/include/atomic.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/blockio.h
===================================================================
--- trunk/sys/arm/include/blockio.h	                        (rev 0)
+++ trunk/sys/arm/include/blockio.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,57 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: blockio.h,v 1.2 2001/06/02 10:44:56 bjh21 Exp $	*/
+
+/*-
+ * Copyright (c) 2001 Ben Harris
+ * 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.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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: stable/10/sys/arm/include/blockio.h 236992 2012-06-13 05:02:51Z imp $
+ *
+ */
+/*
+ * blockio.h - low level functions for bulk PIO data transfer
+ */
+
+#ifndef _MACHINE_BLOCKIO_H_
+#define _MACHINE_BLOCKIO_H_
+
+/*
+ * All these take three arguments:
+ * I/O address
+ * Memory address
+ * Number of bytes to copy
+ */
+
+void read_multi_1(u_int, void *, u_int);
+void write_multi_1(u_int, const void *, u_int);
+#define read_multi_2 insw16
+#define write_multi_2 outsw16
+
+void insw(u_int, void *, u_int);
+void outsw(u_int, void *, u_int);
+void insw16(u_int, void *, u_int);
+void outsw16(u_int, void *, u_int);
+
+#endif /* !_MACHINE_BLOCKIO_H_ */


Property changes on: trunk/sys/arm/include/blockio.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/board.h
===================================================================
--- trunk/sys/arm/include/board.h	                        (rev 0)
+++ trunk/sys/arm/include/board.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,63 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Warner Losh.  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 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 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: stable/10/sys/arm/include/board.h 238189 2012-07-07 05:02:39Z imp $ */
+
+#ifndef _ARM_INCLUDE_BOARD_H_
+#define _ARM_INCLUDE_BOARD_H_
+
+#include <sys/linker_set.h>
+
+typedef long (arm_board_init_fn)(void);
+
+struct arm_board {
+	int		board_id;	/* Board ID from the boot loader */
+	const char	*board_name;	/* Human readable name */
+	arm_board_init_fn *board_init;	/* Board initialize code */
+};
+ 
+#if defined(ARM_MANY_BOARD)
+
+#include "board_id.h"
+
+#define ARM_BOARD(id, name)     \
+	static struct arm_board this_board = { \
+		.board_id = ARM_BOARD_ID_ ## id, \
+		.board_name = name, \
+		.board_init = board_init, \
+	}; \
+	DATA_SET(arm_boards, this_board);
+#define BOARD_INIT static
+
+#else /* !ARM_MANY_BOARD */
+
+#define ARM_BOARD(id, name)
+extern arm_board_init_fn board_init;
+#define BOARD_INIT
+
+#endif /* ARM_MANY_BOARD */
+
+#endif /* _ARM_INCLUDE_BOARD_H_ */


Property changes on: trunk/sys/arm/include/board.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/bootconfig.h
===================================================================
--- trunk/sys/arm/include/bootconfig.h	                        (rev 0)
+++ trunk/sys/arm/include/bootconfig.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,59 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: bootconfig.h,v 1.1 2001/05/13 13:46:23 bjh21 Exp $	*/
+
+/*-
+ * Copyright (c) 1994 Mark Brinicombe.
+ * Copyright (c) 1994 Brini.
+ * All rights reserved.
+ *
+ * This code is derived from software written for Brini by Mark Brinicombe
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Mark Brinicombe
+ *	for the NetBSD Project.
+ * 4. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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: stable/10/sys/arm/include/bootconfig.h 167752 2007-03-21 03:28:16Z kevlo $
+ */
+
+#ifndef _MACHINE_BOOTCONFIG_H_
+#define _MACHINE_BOOTCONFIG_H_
+
+#ifdef _KERNEL
+#define BOOTOPT_TYPE_BOOLEAN		0
+#define BOOTOPT_TYPE_STRING		1
+#define BOOTOPT_TYPE_INT		2
+#define BOOTOPT_TYPE_BININT		3
+#define BOOTOPT_TYPE_HEXINT		4
+#define BOOTOPT_TYPE_MASK		7
+
+int get_bootconf_option (char *, char *, int, void *);
+
+extern char *boot_args;
+extern char *boot_file;
+#endif	/* _KERNEL */
+
+#endif /* !_MACHINE_BOOTCONFIG_H_ */


Property changes on: trunk/sys/arm/include/bootconfig.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/bus.h
===================================================================
--- trunk/sys/arm/include/bus.h	                        (rev 0)
+++ trunk/sys/arm/include/bus.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,766 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: bus.h,v 1.11 2003/07/28 17:35:54 thorpej Exp $	*/
+
+/*-
+ * Copyright (c) 1996, 1997, 1998, 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
+ * NASA Ames Research Center.
+ *
+ * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
+ */
+
+/*-
+ * Copyright (c) 1996 Charles M. Hannum.  All rights reserved.
+ * Copyright (c) 1996 Christopher G. Demetriou.  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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by Christopher G. Demetriou
+ *	for the NetBSD Project.
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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: stable/10/sys/arm/include/bus.h 278727 2015-02-13 22:32:02Z ian $
+ */
+
+#ifndef _MACHINE_BUS_H_
+#define _MACHINE_BUS_H_
+
+#include <machine/_bus.h>
+
+/*
+ *	int bus_space_map  (bus_space_tag_t t, bus_addr_t addr,
+ *	    bus_size_t size, int flags, bus_space_handle_t *bshp);
+ *
+ * Map a region of bus space.
+ */
+
+#define	BUS_SPACE_MAP_CACHEABLE		0x01
+#define	BUS_SPACE_MAP_LINEAR		0x02
+#define	BUS_SPACE_MAP_PREFETCHABLE     	0x04
+
+/*
+ * Bus space for ARM.
+ *
+ * The functions used most often are grouped together at the beginning to ensure
+ * that all the data fits into a single cache line.  The inline implementations
+ * of single read/write access these values a lot.
+ */
+struct bus_space {
+	/* Read/write single and barrier: the most commonly used functions. */
+	uint8_t	 (*bs_r_1)(bus_space_tag_t, bus_space_handle_t, bus_size_t);
+	uint32_t (*bs_r_4)(bus_space_tag_t, bus_space_handle_t, bus_size_t);
+	void	 (*bs_w_1)(bus_space_tag_t, bus_space_handle_t,
+			   bus_size_t, uint8_t);
+	void	 (*bs_w_4)(bus_space_tag_t, bus_space_handle_t,
+			   bus_size_t, uint32_t);
+	void	 (*bs_barrier)(bus_space_tag_t, bus_space_handle_t,
+			       bus_size_t, bus_size_t, int);
+
+	/* Backlink to parent (if copied), and implementation private data. */
+	struct bus_space *bs_parent;
+	void		 *bs_privdata;
+
+	/* mapping/unmapping */
+	int		(*bs_map) (bus_space_tag_t, bus_addr_t, bus_size_t,
+			    int, bus_space_handle_t *);
+	void		(*bs_unmap) (bus_space_tag_t, bus_space_handle_t, bus_size_t);
+	int		(*bs_subregion) (bus_space_tag_t, bus_space_handle_t,
+			    bus_size_t, bus_size_t, bus_space_handle_t *);
+
+	/* allocation/deallocation */
+	int		(*bs_alloc) (bus_space_tag_t, bus_addr_t, bus_addr_t,
+			    bus_size_t, bus_size_t, bus_size_t, int,
+			    bus_addr_t *, bus_space_handle_t *);
+	void		(*bs_free) (bus_space_tag_t, bus_space_handle_t,
+			    bus_size_t);
+
+	/* Read single, the less commonly used functions. */
+	uint16_t	(*bs_r_2) (bus_space_tag_t, bus_space_handle_t, bus_size_t);
+	uint64_t	(*bs_r_8) (bus_space_tag_t, bus_space_handle_t, bus_size_t);
+
+	/* read multiple */
+	void		(*bs_rm_1) (bus_space_tag_t, bus_space_handle_t, bus_size_t,
+	    uint8_t *, bus_size_t);
+	void		(*bs_rm_2) (bus_space_tag_t, bus_space_handle_t, bus_size_t,
+	    uint16_t *, bus_size_t);
+	void		(*bs_rm_4) (bus_space_tag_t, bus_space_handle_t,
+			    bus_size_t, uint32_t *, bus_size_t);
+	void		(*bs_rm_8) (bus_space_tag_t, bus_space_handle_t,
+			    bus_size_t, uint64_t *, bus_size_t);
+					
+	/* read region */
+	void		(*bs_rr_1) (bus_space_tag_t, bus_space_handle_t,
+			    bus_size_t, uint8_t *, bus_size_t);
+	void		(*bs_rr_2) (bus_space_tag_t, bus_space_handle_t,
+			    bus_size_t, uint16_t *, bus_size_t);
+	void		(*bs_rr_4) (bus_space_tag_t, bus_space_handle_t,
+			    bus_size_t, uint32_t *, bus_size_t);
+	void		(*bs_rr_8) (bus_space_tag_t, bus_space_handle_t,
+			    bus_size_t, uint64_t *, bus_size_t);
+					
+	/* Write single, the less commonly used functions. */
+	void		(*bs_w_2) (bus_space_tag_t, bus_space_handle_t,
+			    bus_size_t, uint16_t);
+	void		(*bs_w_8) (bus_space_tag_t, bus_space_handle_t,
+			    bus_size_t, uint64_t);
+
+	/* write multiple */
+	void		(*bs_wm_1) (bus_space_tag_t, bus_space_handle_t,
+			    bus_size_t, const uint8_t *, bus_size_t);
+	void		(*bs_wm_2) (bus_space_tag_t, bus_space_handle_t,
+			    bus_size_t, const uint16_t *, bus_size_t);
+	void		(*bs_wm_4) (bus_space_tag_t, bus_space_handle_t,
+			    bus_size_t, const uint32_t *, bus_size_t);
+	void		(*bs_wm_8) (bus_space_tag_t, bus_space_handle_t,
+			    bus_size_t, const uint64_t *, bus_size_t);
+					
+	/* write region */
+	void		(*bs_wr_1) (bus_space_tag_t, bus_space_handle_t,
+			    bus_size_t, const uint8_t *, bus_size_t);
+	void		(*bs_wr_2) (bus_space_tag_t, bus_space_handle_t,
+			    bus_size_t, const uint16_t *, bus_size_t);
+	void		(*bs_wr_4) (bus_space_tag_t, bus_space_handle_t,
+			    bus_size_t, const uint32_t *, bus_size_t);
+	void		(*bs_wr_8) (bus_space_tag_t, bus_space_handle_t,
+			    bus_size_t, const uint64_t *, bus_size_t);
+
+	/* set multiple */
+	void		(*bs_sm_1) (bus_space_tag_t, bus_space_handle_t,
+			    bus_size_t, uint8_t, bus_size_t);
+	void		(*bs_sm_2) (bus_space_tag_t, bus_space_handle_t,
+			    bus_size_t, uint16_t, bus_size_t);
+	void		(*bs_sm_4) (bus_space_tag_t, bus_space_handle_t,
+			    bus_size_t, uint32_t, bus_size_t);
+	void		(*bs_sm_8) (bus_space_tag_t, bus_space_handle_t,
+			    bus_size_t, uint64_t, bus_size_t);
+
+	/* set region */
+	void		(*bs_sr_1) (bus_space_tag_t, bus_space_handle_t,
+			    bus_size_t, uint8_t, bus_size_t);
+	void		(*bs_sr_2) (bus_space_tag_t, bus_space_handle_t,
+			    bus_size_t, uint16_t, bus_size_t);
+	void		(*bs_sr_4) (bus_space_tag_t, bus_space_handle_t,
+			    bus_size_t, uint32_t, bus_size_t);
+	void		(*bs_sr_8) (bus_space_tag_t, bus_space_handle_t,
+			    bus_size_t, uint64_t, bus_size_t);
+
+	/* copy */
+	void		(*bs_c_1) (bus_space_tag_t, bus_space_handle_t, bus_size_t,
+			    bus_space_handle_t, bus_size_t, bus_size_t);
+	void		(*bs_c_2) (bus_space_tag_t, bus_space_handle_t, bus_size_t,
+			    bus_space_handle_t, bus_size_t, bus_size_t);
+	void		(*bs_c_4) (bus_space_tag_t, bus_space_handle_t, bus_size_t,
+			    bus_space_handle_t, bus_size_t, bus_size_t);
+	void		(*bs_c_8) (bus_space_tag_t, bus_space_handle_t, bus_size_t,
+			    bus_space_handle_t, bus_size_t, bus_size_t);
+
+	/* read stream (single) */
+	uint8_t	(*bs_r_1_s) (bus_space_tag_t, bus_space_handle_t, bus_size_t);
+	uint16_t	(*bs_r_2_s) (bus_space_tag_t, bus_space_handle_t, bus_size_t);
+	uint32_t	(*bs_r_4_s) (bus_space_tag_t, bus_space_handle_t, bus_size_t);
+	uint64_t	(*bs_r_8_s) (bus_space_tag_t, bus_space_handle_t, bus_size_t);
+
+	/* read multiple stream */
+	void		(*bs_rm_1_s) (bus_space_tag_t, bus_space_handle_t, bus_size_t,
+	    uint8_t *, bus_size_t);
+	void		(*bs_rm_2_s) (bus_space_tag_t, bus_space_handle_t, bus_size_t,
+	    uint16_t *, bus_size_t);
+	void		(*bs_rm_4_s) (bus_space_tag_t, bus_space_handle_t,
+			    bus_size_t, uint32_t *, bus_size_t);
+	void		(*bs_rm_8_s) (bus_space_tag_t, bus_space_handle_t,
+			    bus_size_t, uint64_t *, bus_size_t);
+					
+	/* read region stream */
+	void		(*bs_rr_1_s) (bus_space_tag_t, bus_space_handle_t,
+			    bus_size_t, uint8_t *, bus_size_t);
+	void		(*bs_rr_2_s) (bus_space_tag_t, bus_space_handle_t,
+			    bus_size_t, uint16_t *, bus_size_t);
+	void		(*bs_rr_4_s) (bus_space_tag_t, bus_space_handle_t,
+			    bus_size_t, uint32_t *, bus_size_t);
+	void		(*bs_rr_8_s) (bus_space_tag_t, bus_space_handle_t,
+			    bus_size_t, uint64_t *, bus_size_t);
+					
+	/* write stream (single) */
+	void		(*bs_w_1_s) (bus_space_tag_t, bus_space_handle_t,
+			    bus_size_t, uint8_t);
+	void		(*bs_w_2_s) (bus_space_tag_t, bus_space_handle_t,
+			    bus_size_t, uint16_t);
+	void		(*bs_w_4_s) (bus_space_tag_t, bus_space_handle_t,
+			    bus_size_t, uint32_t);
+	void		(*bs_w_8_s) (bus_space_tag_t, bus_space_handle_t,
+			    bus_size_t, uint64_t);
+
+	/* write multiple stream */
+	void		(*bs_wm_1_s) (bus_space_tag_t, bus_space_handle_t,
+			    bus_size_t, const uint8_t *, bus_size_t);
+	void		(*bs_wm_2_s) (bus_space_tag_t, bus_space_handle_t,
+			    bus_size_t, const uint16_t *, bus_size_t);
+	void		(*bs_wm_4_s) (bus_space_tag_t, bus_space_handle_t,
+			    bus_size_t, const uint32_t *, bus_size_t);
+	void		(*bs_wm_8_s) (bus_space_tag_t, bus_space_handle_t,
+			    bus_size_t, const uint64_t *, bus_size_t);
+					
+	/* write region stream */
+	void		(*bs_wr_1_s) (bus_space_tag_t, bus_space_handle_t,
+			    bus_size_t, const uint8_t *, bus_size_t);
+	void		(*bs_wr_2_s) (bus_space_tag_t, bus_space_handle_t,
+			    bus_size_t, const uint16_t *, bus_size_t);
+	void		(*bs_wr_4_s) (bus_space_tag_t, bus_space_handle_t,
+			    bus_size_t, const uint32_t *, bus_size_t);
+	void		(*bs_wr_8_s) (bus_space_tag_t, bus_space_handle_t,
+			    bus_size_t, const uint64_t *, bus_size_t);
+};
+
+extern bus_space_tag_t arm_base_bs_tag;
+
+/*
+ * Utility macros; INTERNAL USE ONLY.
+ */
+#define	__bs_c(a,b)		__CONCAT(a,b)
+#define	__bs_opname(op,size)	__bs_c(__bs_c(__bs_c(bs_,op),_),size)
+
+#define	__bs_nonsingle(type, sz, t, h, o, a, c)				\
+	(*(t)->__bs_opname(type,sz))((t), h, o, a, c)
+#define	__bs_set(type, sz, t, h, o, v, c)				\
+	(*(t)->__bs_opname(type,sz))((t), h, o, v, c)
+#define	__bs_copy(sz, t, h1, o1, h2, o2, cnt)				\
+	(*(t)->__bs_opname(c,sz))((t), h1, o1, h2, o2, cnt)
+
+#define	__bs_opname_s(op,size)	__bs_c(__bs_c(__bs_c(__bs_c(bs_,op),_),size),_s)
+#define	__bs_rs_s(sz, t, h, o)						\
+	(*(t)->__bs_opname_s(r,sz))((t), h, o)
+#define	__bs_ws_s(sz, t, h, o, v)					\
+	(*(t)->__bs_opname_s(w,sz))((t), h, o, v)
+#define	__bs_nonsingle_s(type, sz, t, h, o, a, c)			\
+	(*(t)->__bs_opname_s(type,sz))((t), h, o, a, c)
+
+
+#define __generate_inline_bs_rs(IFN, MBR, TYP)					\
+	static inline TYP						\
+	IFN(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)	\
+	{								\
+									\
+		if (__predict_true(t->MBR == NULL))			\
+			return (*(volatile TYP *)(h + o));		\
+		else							\
+			return (t->MBR(t, h, o));		\
+	}
+
+#define __generate_inline_bs_ws(IFN, MBR, TYP)					\
+	static inline void						\
+	IFN(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, TYP v)\
+	{								\
+									\
+		if (__predict_true(t->MBR == NULL))			\
+			*(volatile TYP *)(h + o) = v;			\
+		else							\
+			t->MBR(t, h, o, v);			\
+	}
+
+/*
+ * Mapping and unmapping operations.
+ */
+#define	bus_space_map(t, a, s, c, hp)					\
+	(*(t)->bs_map)((t), (a), (s), (c), (hp))
+#define	bus_space_unmap(t, h, s)					\
+	(*(t)->bs_unmap)((t), (h), (s))
+#define	bus_space_subregion(t, h, o, s, hp)				\
+	(*(t)->bs_subregion)((t), (h), (o), (s), (hp))
+
+
+/*
+ * Allocation and deallocation operations.
+ */
+#define	bus_space_alloc(t, rs, re, s, a, b, c, ap, hp)			\
+	(*(t)->bs_alloc)((t), (rs), (re), (s), (a), (b),	\
+	    (c), (ap), (hp))
+#define	bus_space_free(t, h, s)						\
+	(*(t)->bs_free)((t), (h), (s))
+
+/*
+ * Bus barrier operations.
+ */
+#define	bus_space_barrier(t, h, o, l, f)				\
+	(*(t)->bs_barrier)((t), (h), (o), (l), (f))
+
+#define	BUS_SPACE_BARRIER_READ	0x01
+#define	BUS_SPACE_BARRIER_WRITE	0x02
+
+/*
+ * Bus read (single) operations.
+ */
+__generate_inline_bs_rs(bus_space_read_1, bs_r_1, uint8_t);
+__generate_inline_bs_rs(bus_space_read_2, bs_r_2, uint16_t);
+__generate_inline_bs_rs(bus_space_read_4, bs_r_4, uint32_t);
+__generate_inline_bs_rs(bus_space_read_8, bs_r_8, uint64_t);
+
+__generate_inline_bs_rs(bus_space_read_stream_1, bs_r_1_s, uint8_t);           
+__generate_inline_bs_rs(bus_space_read_stream_2, bs_r_2_s, uint16_t);          
+__generate_inline_bs_rs(bus_space_read_stream_4, bs_r_4_s, uint32_t);          
+__generate_inline_bs_rs(bus_space_read_stream_8, bs_r_8_s, uint64_t);          
+
+/*
+ * Bus read multiple operations.
+ */
+#define	bus_space_read_multi_1(t, h, o, a, c)				\
+	__bs_nonsingle(rm,1,(t),(h),(o),(a),(c))
+#define	bus_space_read_multi_2(t, h, o, a, c)				\
+	__bs_nonsingle(rm,2,(t),(h),(o),(a),(c))
+#define	bus_space_read_multi_4(t, h, o, a, c)				\
+	__bs_nonsingle(rm,4,(t),(h),(o),(a),(c))
+#define	bus_space_read_multi_8(t, h, o, a, c)				\
+	__bs_nonsingle(rm,8,(t),(h),(o),(a),(c))
+
+#define	bus_space_read_multi_stream_1(t, h, o, a, c)			\
+	__bs_nonsingle_s(rm,1,(t),(h),(o),(a),(c))
+#define	bus_space_read_multi_stream_2(t, h, o, a, c)			\
+	__bs_nonsingle_s(rm,2,(t),(h),(o),(a),(c))
+#define	bus_space_read_multi_stream_4(t, h, o, a, c)			\
+	__bs_nonsingle_s(rm,4,(t),(h),(o),(a),(c))
+#define	bus_space_read_multi_stream_8(t, h, o, a, c)			\
+	__bs_nonsingle_s(rm,8,(t),(h),(o),(a),(c))
+
+
+/*
+ * Bus read region operations.
+ */
+#define	bus_space_read_region_1(t, h, o, a, c)				\
+	__bs_nonsingle(rr,1,(t),(h),(o),(a),(c))
+#define	bus_space_read_region_2(t, h, o, a, c)				\
+	__bs_nonsingle(rr,2,(t),(h),(o),(a),(c))
+#define	bus_space_read_region_4(t, h, o, a, c)				\
+	__bs_nonsingle(rr,4,(t),(h),(o),(a),(c))
+#define	bus_space_read_region_8(t, h, o, a, c)				\
+	__bs_nonsingle(rr,8,(t),(h),(o),(a),(c))
+
+#define	bus_space_read_region_stream_1(t, h, o, a, c)			\
+	__bs_nonsingle_s(rr,1,(t),(h),(o),(a),(c))
+#define	bus_space_read_region_stream_2(t, h, o, a, c)			\
+	__bs_nonsingle_s(rr,2,(t),(h),(o),(a),(c))
+#define	bus_space_read_region_stream_4(t, h, o, a, c)			\
+	__bs_nonsingle_s(rr,4,(t),(h),(o),(a),(c))
+#define	bus_space_read_region_stream_8(t, h, o, a, c)			\
+	__bs_nonsingle_s(rr,8,(t),(h),(o),(a),(c))
+
+
+/*
+ * Bus write (single) operations.
+ */
+__generate_inline_bs_ws(bus_space_write_1, bs_w_1, uint8_t);
+__generate_inline_bs_ws(bus_space_write_2, bs_w_2, uint16_t);
+__generate_inline_bs_ws(bus_space_write_4, bs_w_4, uint32_t);
+__generate_inline_bs_ws(bus_space_write_8, bs_w_8, uint64_t);
+
+__generate_inline_bs_ws(bus_space_write_stream_1, bs_w_1_s, uint8_t);           
+__generate_inline_bs_ws(bus_space_write_stream_2, bs_w_2_s, uint16_t);          
+__generate_inline_bs_ws(bus_space_write_stream_4, bs_w_4_s, uint32_t);          
+__generate_inline_bs_ws(bus_space_write_stream_8, bs_w_8_s, uint64_t);          
+
+
+/*
+ * Bus write multiple operations.
+ */
+#define	bus_space_write_multi_1(t, h, o, a, c)				\
+	__bs_nonsingle(wm,1,(t),(h),(o),(a),(c))
+#define	bus_space_write_multi_2(t, h, o, a, c)				\
+	__bs_nonsingle(wm,2,(t),(h),(o),(a),(c))
+#define	bus_space_write_multi_4(t, h, o, a, c)				\
+	__bs_nonsingle(wm,4,(t),(h),(o),(a),(c))
+#define	bus_space_write_multi_8(t, h, o, a, c)				\
+	__bs_nonsingle(wm,8,(t),(h),(o),(a),(c))
+
+#define	bus_space_write_multi_stream_1(t, h, o, a, c)			\
+	__bs_nonsingle_s(wm,1,(t),(h),(o),(a),(c))
+#define	bus_space_write_multi_stream_2(t, h, o, a, c)			\
+	__bs_nonsingle_s(wm,2,(t),(h),(o),(a),(c))
+#define	bus_space_write_multi_stream_4(t, h, o, a, c)			\
+	__bs_nonsingle_s(wm,4,(t),(h),(o),(a),(c))
+#define	bus_space_write_multi_stream_8(t, h, o, a, c)			\
+	__bs_nonsingle_s(wm,8,(t),(h),(o),(a),(c))
+
+
+/*
+ * Bus write region operations.
+ */
+#define	bus_space_write_region_1(t, h, o, a, c)				\
+	__bs_nonsingle(wr,1,(t),(h),(o),(a),(c))
+#define	bus_space_write_region_2(t, h, o, a, c)				\
+	__bs_nonsingle(wr,2,(t),(h),(o),(a),(c))
+#define	bus_space_write_region_4(t, h, o, a, c)				\
+	__bs_nonsingle(wr,4,(t),(h),(o),(a),(c))
+#define	bus_space_write_region_8(t, h, o, a, c)				\
+	__bs_nonsingle(wr,8,(t),(h),(o),(a),(c))
+
+#define	bus_space_write_region_stream_1(t, h, o, a, c)			\
+	__bs_nonsingle_s(wr,1,(t),(h),(o),(a),(c))
+#define	bus_space_write_region_stream_2(t, h, o, a, c)			\
+	__bs_nonsingle_s(wr,2,(t),(h),(o),(a),(c))
+#define	bus_space_write_region_stream_4(t, h, o, a, c)			\
+	__bs_nonsingle_s(wr,4,(t),(h),(o),(a),(c))
+#define	bus_space_write_region_stream_8(t, h, o, a, c)			\
+	__bs_nonsingle_s(wr,8,(t),(h),(o),(a),(c))
+
+
+/*
+ * Set multiple operations.
+ */
+#define	bus_space_set_multi_1(t, h, o, v, c)				\
+	__bs_set(sm,1,(t),(h),(o),(v),(c))
+#define	bus_space_set_multi_2(t, h, o, v, c)				\
+	__bs_set(sm,2,(t),(h),(o),(v),(c))
+#define	bus_space_set_multi_4(t, h, o, v, c)				\
+	__bs_set(sm,4,(t),(h),(o),(v),(c))
+#define	bus_space_set_multi_8(t, h, o, v, c)				\
+	__bs_set(sm,8,(t),(h),(o),(v),(c))
+
+
+/*
+ * Set region operations.
+ */
+#define	bus_space_set_region_1(t, h, o, v, c)				\
+	__bs_set(sr,1,(t),(h),(o),(v),(c))
+#define	bus_space_set_region_2(t, h, o, v, c)				\
+	__bs_set(sr,2,(t),(h),(o),(v),(c))
+#define	bus_space_set_region_4(t, h, o, v, c)				\
+	__bs_set(sr,4,(t),(h),(o),(v),(c))
+#define	bus_space_set_region_8(t, h, o, v, c)				\
+	__bs_set(sr,8,(t),(h),(o),(v),(c))
+
+
+/*
+ * Copy operations.
+ */
+#define	bus_space_copy_region_1(t, h1, o1, h2, o2, c)				\
+	__bs_copy(1, t, h1, o1, h2, o2, c)
+#define	bus_space_copy_region_2(t, h1, o1, h2, o2, c)				\
+	__bs_copy(2, t, h1, o1, h2, o2, c)
+#define	bus_space_copy_region_4(t, h1, o1, h2, o2, c)				\
+	__bs_copy(4, t, h1, o1, h2, o2, c)
+#define	bus_space_copy_region_8(t, h1, o1, h2, o2, c)				\
+	__bs_copy(8, t, h1, o1, h2, o2, c)
+
+/*
+ * Macros to provide prototypes for all the functions used in the
+ * bus_space structure
+ */
+
+#define bs_map_proto(f)							\
+int	__bs_c(f,_bs_map) (bus_space_tag_t t, bus_addr_t addr,		\
+	    bus_size_t size, int cacheable, bus_space_handle_t *bshp);
+
+#define bs_unmap_proto(f)						\
+void	__bs_c(f,_bs_unmap) (bus_space_tag_t t, bus_space_handle_t bsh,		\
+	    bus_size_t size);
+
+#define bs_subregion_proto(f)						\
+int	__bs_c(f,_bs_subregion) (bus_space_tag_t t, bus_space_handle_t bsh,	\
+	    bus_size_t offset, bus_size_t size, 			\
+	    bus_space_handle_t *nbshp);
+
+#define bs_alloc_proto(f)						\
+int	__bs_c(f,_bs_alloc) (bus_space_tag_t t, bus_addr_t rstart,		\
+	    bus_addr_t rend, bus_size_t size, bus_size_t align,		\
+	    bus_size_t boundary, int cacheable, bus_addr_t *addrp,	\
+	    bus_space_handle_t *bshp);
+
+#define bs_free_proto(f)						\
+void	__bs_c(f,_bs_free) (bus_space_tag_t t, bus_space_handle_t bsh,	\
+	    bus_size_t size);
+
+#define bs_mmap_proto(f)						\
+int	__bs_c(f,_bs_mmap) (struct cdev *, vm_offset_t, vm_paddr_t *, int);
+
+#define bs_barrier_proto(f)						\
+void	__bs_c(f,_bs_barrier) (bus_space_tag_t t, bus_space_handle_t bsh,	\
+	    bus_size_t offset, bus_size_t len, int flags);
+
+#define	bs_r_1_proto(f)							\
+uint8_t	__bs_c(f,_bs_r_1) (bus_space_tag_t t, bus_space_handle_t bsh,	\
+		    bus_size_t offset);
+
+#define	bs_r_2_proto(f)							\
+uint16_t	__bs_c(f,_bs_r_2) (bus_space_tag_t t, bus_space_handle_t bsh,	\
+		    bus_size_t offset);
+
+#define	bs_r_4_proto(f)							\
+uint32_t	__bs_c(f,_bs_r_4) (bus_space_tag_t t, bus_space_handle_t bsh,	\
+		    bus_size_t offset);
+
+#define	bs_r_8_proto(f)							\
+uint64_t	__bs_c(f,_bs_r_8) (bus_space_tag_t t, bus_space_handle_t bsh,	\
+		    bus_size_t offset);
+
+#define	bs_r_1_s_proto(f)						\
+uint8_t	__bs_c(f,_bs_r_1_s) (bus_space_tag_t t, bus_space_handle_t bsh,	\
+		    bus_size_t offset);
+
+#define	bs_r_2_s_proto(f)						\
+uint16_t	__bs_c(f,_bs_r_2_s) (bus_space_tag_t t, bus_space_handle_t bsh,	\
+		    bus_size_t offset);
+
+#define	bs_r_4_s_proto(f)						\
+uint32_t	__bs_c(f,_bs_r_4_s) (bus_space_tag_t t, bus_space_handle_t bsh,	\
+		    bus_size_t offset);
+
+#define	bs_w_1_proto(f)							\
+void	__bs_c(f,_bs_w_1) (bus_space_tag_t t, bus_space_handle_t bsh,		\
+	    bus_size_t offset, uint8_t value);
+
+#define	bs_w_2_proto(f)							\
+void	__bs_c(f,_bs_w_2) (bus_space_tag_t t, bus_space_handle_t bsh,		\
+	    bus_size_t offset, uint16_t value);
+
+#define	bs_w_4_proto(f)							\
+void	__bs_c(f,_bs_w_4) (bus_space_tag_t t, bus_space_handle_t bsh,		\
+	    bus_size_t offset, uint32_t value);
+
+#define	bs_w_8_proto(f)							\
+void	__bs_c(f,_bs_w_8) (bus_space_tag_t t, bus_space_handle_t bsh,		\
+	    bus_size_t offset, uint64_t value);
+
+#define	bs_w_1_s_proto(f)						\
+void	__bs_c(f,_bs_w_1_s) (bus_space_tag_t t, bus_space_handle_t bsh,		\
+	    bus_size_t offset, uint8_t value);
+
+#define	bs_w_2_s_proto(f)						\
+void	__bs_c(f,_bs_w_2_s) (bus_space_tag_t t, bus_space_handle_t bsh,		\
+	    bus_size_t offset, uint16_t value);
+
+#define	bs_w_4_s_proto(f)						\
+void	__bs_c(f,_bs_w_4_s) (bus_space_tag_t t, bus_space_handle_t bsh,		\
+	    bus_size_t offset, uint32_t value);
+
+#define	bs_rm_1_proto(f)						\
+void	__bs_c(f,_bs_rm_1) (bus_space_tag_t t, bus_space_handle_t bsh,	\
+	    bus_size_t offset, uint8_t *addr, bus_size_t count);
+
+#define	bs_rm_2_proto(f)						\
+void	__bs_c(f,_bs_rm_2) (bus_space_tag_t t, bus_space_handle_t bsh,	\
+	    bus_size_t offset, uint16_t *addr, bus_size_t count);
+
+#define	bs_rm_4_proto(f)						\
+void	__bs_c(f,_bs_rm_4) (bus_space_tag_t t, bus_space_handle_t bsh,	\
+	    bus_size_t offset, uint32_t *addr, bus_size_t count);		
+
+#define	bs_rm_8_proto(f)						\
+void	__bs_c(f,_bs_rm_8) (bus_space_tag_t t, bus_space_handle_t bsh,	\
+	    bus_size_t offset, uint64_t *addr, bus_size_t count);
+
+#define	bs_wm_1_proto(f)						\
+void	__bs_c(f,_bs_wm_1) (bus_space_tag_t t, bus_space_handle_t bsh,	\
+	    bus_size_t offset, const uint8_t *addr, bus_size_t count);
+
+#define	bs_wm_2_proto(f)						\
+void	__bs_c(f,_bs_wm_2) (bus_space_tag_t t, bus_space_handle_t bsh,	\
+	    bus_size_t offset, const uint16_t *addr, bus_size_t count);
+
+#define	bs_wm_4_proto(f)						\
+void	__bs_c(f,_bs_wm_4) (bus_space_tag_t t, bus_space_handle_t bsh,	\
+	    bus_size_t offset, const uint32_t *addr, bus_size_t count);
+
+#define	bs_wm_8_proto(f)						\
+void	__bs_c(f,_bs_wm_8) (bus_space_tag_t t, bus_space_handle_t bsh,	\
+	    bus_size_t offset, const uint64_t *addr, bus_size_t count);
+
+#define	bs_rr_1_proto(f)						\
+void	__bs_c(f, _bs_rr_1) (bus_space_tag_t t, bus_space_handle_t bsh,	\
+	    bus_size_t offset, uint8_t *addr, bus_size_t count);
+
+#define	bs_rr_2_proto(f)						\
+void	__bs_c(f, _bs_rr_2) (bus_space_tag_t t, bus_space_handle_t bsh,	\
+	    bus_size_t offset, uint16_t *addr, bus_size_t count);
+
+#define	bs_rr_4_proto(f)						\
+void	__bs_c(f, _bs_rr_4) (bus_space_tag_t t, bus_space_handle_t bsh,	\
+	    bus_size_t offset, uint32_t *addr, bus_size_t count);
+
+#define	bs_rr_8_proto(f)						\
+void	__bs_c(f, _bs_rr_8) (bus_space_tag_t t, bus_space_handle_t bsh,	\
+	    bus_size_t offset, uint64_t *addr, bus_size_t count);
+
+#define	bs_wr_1_proto(f)						\
+void	__bs_c(f, _bs_wr_1) (bus_space_tag_t t, bus_space_handle_t bsh,	\
+	    bus_size_t offset, const uint8_t *addr, bus_size_t count);
+
+#define	bs_wr_2_proto(f)						\
+void	__bs_c(f, _bs_wr_2) (bus_space_tag_t t, bus_space_handle_t bsh,	\
+	    bus_size_t offset, const uint16_t *addr, bus_size_t count);
+
+#define	bs_wr_4_proto(f)						\
+void	__bs_c(f, _bs_wr_4) (bus_space_tag_t t, bus_space_handle_t bsh,	\
+	    bus_size_t offset, const uint32_t *addr, bus_size_t count);
+
+#define	bs_wr_8_proto(f)						\
+void	__bs_c(f, _bs_wr_8) (bus_space_tag_t t, bus_space_handle_t bsh,	\
+	    bus_size_t offset, const uint64_t *addr, bus_size_t count);
+
+#define	bs_sm_1_proto(f)						\
+void	__bs_c(f,_bs_sm_1) (bus_space_tag_t t, bus_space_handle_t bsh,	\
+	    bus_size_t offset, uint8_t value, bus_size_t count);
+
+#define	bs_sm_2_proto(f)						\
+void	__bs_c(f,_bs_sm_2) (bus_space_tag_t t, bus_space_handle_t bsh,	\
+	    bus_size_t offset, uint16_t value, bus_size_t count);
+
+#define	bs_sm_4_proto(f)						\
+void	__bs_c(f,_bs_sm_4) (bus_space_tag_t t, bus_space_handle_t bsh,	\
+	    bus_size_t offset, uint32_t value, bus_size_t count);
+
+#define	bs_sm_8_proto(f)						\
+void	__bs_c(f,_bs_sm_8) (bus_space_tag_t t, bus_space_handle_t bsh,	\
+	    bus_size_t offset, uint64_t value, bus_size_t count);
+
+#define	bs_sr_1_proto(f)						\
+void	__bs_c(f,_bs_sr_1) (bus_space_tag_t t, bus_space_handle_t bsh,	\
+	    bus_size_t offset, uint8_t value, bus_size_t count);
+
+#define	bs_sr_2_proto(f)						\
+void	__bs_c(f,_bs_sr_2) (bus_space_tag_t t, bus_space_handle_t bsh,	\
+	    bus_size_t offset, uint16_t value, bus_size_t count);
+
+#define	bs_sr_4_proto(f)						\
+void	__bs_c(f,_bs_sr_4) (bus_space_tag_t t, bus_space_handle_t bsh,	\
+	    bus_size_t offset, uint32_t value, bus_size_t count);
+
+#define	bs_sr_8_proto(f)						\
+void	__bs_c(f,_bs_sr_8) (bus_space_tag_t t, bus_space_handle_t bsh,	\
+	    bus_size_t offset, uint64_t value, bus_size_t count);
+
+#define	bs_c_1_proto(f)							\
+void	__bs_c(f,_bs_c_1) (bus_space_tag_t t, bus_space_handle_t bsh1,	\
+	    bus_size_t offset1, bus_space_handle_t bsh2,		\
+	    bus_size_t offset2, bus_size_t count);
+
+#define	bs_c_2_proto(f)							\
+void	__bs_c(f,_bs_c_2) (bus_space_tag_t t, bus_space_handle_t bsh1,	\
+	    bus_size_t offset1, bus_space_handle_t bsh2,		\
+	    bus_size_t offset2, bus_size_t count);
+
+#define	bs_c_4_proto(f)							\
+void	__bs_c(f,_bs_c_4) (bus_space_tag_t t, bus_space_handle_t bsh1,	\
+	    bus_size_t offset1, bus_space_handle_t bsh2,		\
+	    bus_size_t offset2, bus_size_t count);
+
+#define	bs_c_8_proto(f)							\
+void	__bs_c(f,_bs_c_8) (bus_space_tag_t t, bus_space_handle_t bsh1,	\
+	    bus_size_t offset1, bus_space_handle_t bsh2,		\
+	    bus_size_t offset2, bus_size_t count);
+
+#define bs_protos(f)		\
+bs_map_proto(f);		\
+bs_unmap_proto(f);		\
+bs_subregion_proto(f);		\
+bs_alloc_proto(f);		\
+bs_free_proto(f);		\
+bs_mmap_proto(f);		\
+bs_barrier_proto(f);		\
+bs_r_1_proto(f);		\
+bs_r_2_proto(f);		\
+bs_r_4_proto(f);		\
+bs_r_8_proto(f);		\
+bs_r_1_s_proto(f);		\
+bs_r_2_s_proto(f);		\
+bs_r_4_s_proto(f);		\
+bs_w_1_proto(f);		\
+bs_w_2_proto(f);		\
+bs_w_4_proto(f);		\
+bs_w_8_proto(f);		\
+bs_w_1_s_proto(f);		\
+bs_w_2_s_proto(f);		\
+bs_w_4_s_proto(f);		\
+bs_rm_1_proto(f);		\
+bs_rm_2_proto(f);		\
+bs_rm_4_proto(f);		\
+bs_rm_8_proto(f);		\
+bs_wm_1_proto(f);		\
+bs_wm_2_proto(f);		\
+bs_wm_4_proto(f);		\
+bs_wm_8_proto(f);		\
+bs_rr_1_proto(f);		\
+bs_rr_2_proto(f);		\
+bs_rr_4_proto(f);		\
+bs_rr_8_proto(f);		\
+bs_wr_1_proto(f);		\
+bs_wr_2_proto(f);		\
+bs_wr_4_proto(f);		\
+bs_wr_8_proto(f);		\
+bs_sm_1_proto(f);		\
+bs_sm_2_proto(f);		\
+bs_sm_4_proto(f);		\
+bs_sm_8_proto(f);		\
+bs_sr_1_proto(f);		\
+bs_sr_2_proto(f);		\
+bs_sr_4_proto(f);		\
+bs_sr_8_proto(f);		\
+bs_c_1_proto(f);		\
+bs_c_2_proto(f);		\
+bs_c_4_proto(f);		\
+bs_c_8_proto(f);
+
+void generic_bs_unimplemented(void);
+#define	BS_UNIMPLEMENTED	(void *)generic_bs_unimplemented
+
+#define BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t)
+
+#define BUS_SPACE_MAXADDR_24BIT	0xFFFFFF
+#define BUS_SPACE_MAXADDR_32BIT 0xFFFFFFFF
+#define BUS_SPACE_MAXADDR 	0xFFFFFFFF
+#define BUS_SPACE_MAXSIZE_24BIT	0xFFFFFF
+#define BUS_SPACE_MAXSIZE_32BIT	0xFFFFFFFF
+#define BUS_SPACE_MAXSIZE 	0xFFFFFFFF
+
+#define BUS_SPACE_UNRESTRICTED	(~0)
+
+#include <machine/bus_dma.h>
+
+/*
+ * Get the physical address of a bus space memory-mapped resource.
+ * Doing this as a macro is a temporary solution until a more robust fix is
+ * designed.  It also serves to mark the locations needing that fix.
+ */
+#define BUS_SPACE_PHYSADDR(res, offs) \
+	((u_int)(rman_get_start(res)+(offs)))
+
+#endif /* _MACHINE_BUS_H_ */


Property changes on: trunk/sys/arm/include/bus.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/bus_dma.h
===================================================================
--- trunk/sys/arm/include/bus_dma.h	                        (rev 0)
+++ trunk/sys/arm/include/bus_dma.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,102 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: bus.h,v 1.11 2003/07/28 17:35:54 thorpej Exp $	*/
+
+/*-
+ * Copyright (c) 1996, 1997, 1998, 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
+ * NASA Ames Research Center.
+ *
+ * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
+ */
+
+/*-
+ * Copyright (c) 1996 Charles M. Hannum.  All rights reserved.
+ * Copyright (c) 1996 Christopher G. Demetriou.  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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by Christopher G. Demetriou
+ *	for the NetBSD Project.
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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: stable/10/sys/arm/include/bus_dma.h 203974 2010-02-16 21:59:17Z imp $
+ */
+
+#ifndef _ARM_BUS_DMA_H
+#define _ARM_BUS_DMA_H
+
+#include <sys/bus_dma.h>
+
+/* Bus Space DMA macros */
+
+#define BUS_DMA_TAG_VALID(t)    ((t) != (bus_dma_tag_t)0)
+
+#ifdef _ARM32_BUS_DMA_PRIVATE
+/*
+ *	arm32_dma_range
+ *
+ *	This structure describes a valid DMA range.
+ */
+struct arm32_dma_range {
+	bus_addr_t	dr_sysbase;	/* system base address */
+	bus_addr_t	dr_busbase;	/* appears here on bus */
+	bus_size_t	dr_len;		/* length of range */
+};
+
+/* _dm_buftype */
+#define	ARM32_BUFTYPE_INVALID		0
+#define	ARM32_BUFTYPE_LINEAR		1
+#define	ARM32_BUFTYPE_MBUF		2
+#define	ARM32_BUFTYPE_UIO		3
+#define	ARM32_BUFTYPE_RAW		4
+
+struct arm32_dma_range	*bus_dma_get_range(void);
+int	bus_dma_get_range_nb(void);
+
+extern bus_dma_tag_t arm_root_dma_tag;
+
+#endif /* _ARM32_BUS_DMA_PRIVATE */
+
+#endif /* _ARM_BUS_DMA_H */


Property changes on: trunk/sys/arm/include/bus_dma.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/clock.h
===================================================================
--- trunk/sys/arm/include/clock.h	                        (rev 0)
+++ trunk/sys/arm/include/clock.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,33 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2004 Olivier Houchard
+ * 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: stable/10/sys/arm/include/clock.h 162954 2006-10-02 12:59:59Z phk $
+ */
+
+#ifndef	_MACHINE_CLOCK_H_
+#define	_MACHINE_CLOCK_H_
+
+#endif /* !_MACHINE_CLOCK_H_ */


Property changes on: trunk/sys/arm/include/clock.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/counter.h
===================================================================
--- trunk/sys/arm/include/counter.h	                        (rev 0)
+++ trunk/sys/arm/include/counter.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,95 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Konstantin Belousov <kib at FreeBSD.org>
+ * 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: stable/10/sys/arm/include/counter.h 252434 2013-07-01 02:48:27Z kib $
+ */
+
+#ifndef __MACHINE_COUNTER_H__
+#define __MACHINE_COUNTER_H__
+
+#include <sys/pcpu.h>
+#ifdef INVARIANTS
+#include <sys/proc.h>
+#endif
+
+#define	counter_enter()	critical_enter()
+#define	counter_exit()	critical_exit()
+
+#ifdef IN_SUBR_COUNTER_C
+/* XXXKIB non-atomic 64bit read */
+static inline uint64_t
+counter_u64_read_one(uint64_t *p, int cpu)
+{
+
+	return (*(uint64_t *)((char *)p + sizeof(struct pcpu) * cpu));
+}
+
+static inline uint64_t
+counter_u64_fetch_inline(uint64_t *p)
+{
+	uint64_t r;
+	int i;
+
+	r = 0;
+	for (i = 0; i < mp_ncpus; i++)
+		r += counter_u64_read_one((uint64_t *)p, i);
+
+	return (r);
+}
+
+/* XXXKIB non-atomic 64bit store, might interrupt increment */
+static void
+counter_u64_zero_one_cpu(void *arg)
+{
+
+	*((uint64_t *)((char *)arg + sizeof(struct pcpu) *
+	    PCPU_GET(cpuid))) = 0;
+}
+
+static inline void
+counter_u64_zero_inline(counter_u64_t c)
+{
+
+	smp_rendezvous(smp_no_rendevous_barrier, counter_u64_zero_one_cpu,
+	    smp_no_rendevous_barrier, c);
+}
+#endif
+
+#define	counter_u64_add_protected(c, inc)	do {	\
+	CRITICAL_ASSERT(curthread);			\
+	*(uint64_t *)zpcpu_get(c) += (inc);		\
+} while (0)
+
+static inline void
+counter_u64_add(counter_u64_t c, int64_t inc)
+{
+
+	counter_enter();
+	counter_u64_add_protected(c, inc);
+	counter_exit();
+}
+
+#endif	/* ! __MACHINE_COUNTER_H__ */


Property changes on: trunk/sys/arm/include/counter.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/cpu-v6.h
===================================================================
--- trunk/sys/arm/include/cpu-v6.h	                        (rev 0)
+++ trunk/sys/arm/include/cpu-v6.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,442 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright 2014 Svatopluk Kraus <onwahe at gmail.com>
+ * Copyright 2014 Michal Meloun <meloun at miracle.cz>
+ * 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: stable/10/sys/arm/include/cpu-v6.h 283336 2015-05-23 23:05:31Z ian $
+ */
+#ifndef MACHINE_CPU_V6_H
+#define MACHINE_CPU_V6_H
+
+#include "machine/atomic.h"
+#include "machine/cpufunc.h"
+#include "machine/cpuinfo.h"
+#include "machine/sysreg.h"
+
+
+#define CPU_ASID_KERNEL 0
+
+vm_offset_t dcache_wb_pou_checked(vm_offset_t, vm_size_t);
+vm_offset_t icache_inv_pou_checked(vm_offset_t, vm_size_t);
+
+/*
+ * Macros to generate CP15 (system control processor) read/write functions.
+ */
+#define _FX(s...) #s
+
+#define _RF0(fname, aname...)						\
+static __inline register_t						\
+fname(void)								\
+{									\
+	register_t reg;							\
+	__asm __volatile("mrc\t" _FX(aname): "=r" (reg));		\
+	return(reg);							\
+}
+
+#define _WF0(fname, aname...)						\
+static __inline void							\
+fname(void)								\
+{									\
+	__asm __volatile("mcr\t" _FX(aname));				\
+}
+
+#define _WF1(fname, aname...)						\
+static __inline void							\
+fname(register_t reg)							\
+{									\
+	__asm __volatile("mcr\t" _FX(aname):: "r" (reg));		\
+}
+
+/*
+ * Raw CP15  maintenance operations
+ * !!! not for external use !!!
+ */
+
+/* TLB */
+
+_WF0(_CP15_TLBIALL, CP15_TLBIALL)		/* Invalidate entire unified TLB */
+#if __ARM_ARCH >= 7 && defined SMP
+_WF0(_CP15_TLBIALLIS, CP15_TLBIALLIS)		/* Invalidate entire unified TLB IS */
+#endif
+_WF1(_CP15_TLBIASID, CP15_TLBIASID(%0))		/* Invalidate unified TLB by ASID */
+#if __ARM_ARCH >= 7 && defined SMP
+_WF1(_CP15_TLBIASIDIS, CP15_TLBIASIDIS(%0))	/* Invalidate unified TLB by ASID IS */
+#endif
+_WF1(_CP15_TLBIMVAA, CP15_TLBIMVAA(%0))		/* Invalidate unified TLB by MVA, all ASID */
+#if __ARM_ARCH >= 7 && defined SMP
+_WF1(_CP15_TLBIMVAAIS, CP15_TLBIMVAAIS(%0))	/* Invalidate unified TLB by MVA, all ASID IS */
+#endif
+_WF1(_CP15_TLBIMVA, CP15_TLBIMVA(%0))		/* Invalidate unified TLB by MVA */
+
+_WF1(_CP15_TTB_SET, CP15_TTBR0(%0))
+
+/* Cache and Branch predictor */
+
+_WF0(_CP15_BPIALL, CP15_BPIALL)			/* Branch predictor invalidate all */
+#if __ARM_ARCH >= 7 && defined SMP
+_WF0(_CP15_BPIALLIS, CP15_BPIALLIS)		/* Branch predictor invalidate all IS */
+#endif
+_WF1(_CP15_BPIMVA, CP15_BPIMVA(%0))		/* Branch predictor invalidate by MVA */
+_WF1(_CP15_DCCIMVAC, CP15_DCCIMVAC(%0))		/* Data cache clean and invalidate by MVA PoC */
+_WF1(_CP15_DCCISW, CP15_DCCISW(%0))		/* Data cache clean and invalidate by set/way */
+_WF1(_CP15_DCCMVAC, CP15_DCCMVAC(%0))		/* Data cache clean by MVA PoC */
+#if __ARM_ARCH >= 7
+_WF1(_CP15_DCCMVAU, CP15_DCCMVAU(%0))		/* Data cache clean by MVA PoU */
+#endif
+_WF1(_CP15_DCCSW, CP15_DCCSW(%0))		/* Data cache clean by set/way */
+_WF1(_CP15_DCIMVAC, CP15_DCIMVAC(%0))		/* Data cache invalidate by MVA PoC */
+_WF1(_CP15_DCISW, CP15_DCISW(%0))		/* Data cache invalidate by set/way */
+_WF0(_CP15_ICIALLU, CP15_ICIALLU)		/* Instruction cache invalidate all PoU */
+#if __ARM_ARCH >= 7 && defined SMP
+_WF0(_CP15_ICIALLUIS, CP15_ICIALLUIS)		/* Instruction cache invalidate all PoU IS */
+#endif
+_WF1(_CP15_ICIMVAU, CP15_ICIMVAU(%0))		/* Instruction cache invalidate */
+
+/*
+ * Publicly accessible functions
+ */
+
+/* Various control registers */
+
+_RF0(cp15_dfsr_get, CP15_DFSR(%0))
+_RF0(cp15_ifsr_get, CP15_IFSR(%0))
+_WF1(cp15_prrr_set, CP15_PRRR(%0))
+_WF1(cp15_nmrr_set, CP15_NMRR(%0))
+_RF0(cp15_ttbr_get, CP15_TTBR0(%0))
+_RF0(cp15_dfar_get, CP15_DFAR(%0))
+#if __ARM_ARCH >= 7
+_RF0(cp15_ifar_get, CP15_IFAR(%0))
+#endif
+
+/*CPU id registers */
+_RF0(cp15_midr_get, CP15_MIDR(%0))
+_RF0(cp15_ctr_get, CP15_CTR(%0))
+_RF0(cp15_tcmtr_get, CP15_TCMTR(%0))
+_RF0(cp15_tlbtr_get, CP15_TLBTR(%0))
+_RF0(cp15_mpidr_get, CP15_MPIDR(%0))
+_RF0(cp15_revidr_get, CP15_REVIDR(%0))
+_RF0(cp15_aidr_get, CP15_AIDR(%0))
+_RF0(cp15_id_pfr0_get, CP15_ID_PFR0(%0))
+_RF0(cp15_id_pfr1_get, CP15_ID_PFR1(%0))
+_RF0(cp15_id_dfr0_get, CP15_ID_DFR0(%0))
+_RF0(cp15_id_afr0_get, CP15_ID_AFR0(%0))
+_RF0(cp15_id_mmfr0_get, CP15_ID_MMFR0(%0))
+_RF0(cp15_id_mmfr1_get, CP15_ID_MMFR1(%0))
+_RF0(cp15_id_mmfr2_get, CP15_ID_MMFR2(%0))
+_RF0(cp15_id_mmfr3_get, CP15_ID_MMFR3(%0))
+_RF0(cp15_id_isar0_get, CP15_ID_ISAR0(%0))
+_RF0(cp15_id_isar1_get, CP15_ID_ISAR1(%0))
+_RF0(cp15_id_isar2_get, CP15_ID_ISAR2(%0))
+_RF0(cp15_id_isar3_get, CP15_ID_ISAR3(%0))
+_RF0(cp15_id_isar4_get, CP15_ID_ISAR4(%0))
+_RF0(cp15_id_isar5_get, CP15_ID_ISAR5(%0))
+_RF0(cp15_cbar_get, CP15_CBAR(%0))
+
+/* Performance Monitor registers */
+
+#if __ARM_ARCH == 6 && defined(CPU_ARM1176)
+_RF0(cp15_pmccntr_get, CP15_PMCCNTR(%0))
+_WF1(cp15_pmccntr_set, CP15_PMCCNTR(%0))
+#elif __ARM_ARCH > 6
+_RF0(cp15_pmcr_get, CP15_PMCR(%0))
+_WF1(cp15_pmcr_set, CP15_PMCR(%0))
+_RF0(cp15_pmcnten_get, CP15_PMCNTENSET(%0))
+_WF1(cp15_pmcnten_set, CP15_PMCNTENSET(%0))
+_WF1(cp15_pmcnten_clr, CP15_PMCNTENCLR(%0))
+_RF0(cp15_pmovsr_get, CP15_PMOVSR(%0))
+_WF1(cp15_pmovsr_set, CP15_PMOVSR(%0))
+_WF1(cp15_pmswinc_set, CP15_PMSWINC(%0))
+_RF0(cp15_pmselr_get, CP15_PMSELR(%0))
+_WF1(cp15_pmselr_set, CP15_PMSELR(%0))
+_RF0(cp15_pmccntr_get, CP15_PMCCNTR(%0))
+_WF1(cp15_pmccntr_set, CP15_PMCCNTR(%0))
+_RF0(cp15_pmxevtyper_get, CP15_PMXEVTYPER(%0))
+_WF1(cp15_pmxevtyper_set, CP15_PMXEVTYPER(%0))
+_RF0(cp15_pmxevcntr_get, CP15_PMXEVCNTRR(%0))
+_WF1(cp15_pmxevcntr_set, CP15_PMXEVCNTRR(%0))
+_RF0(cp15_pmuserenr_get, CP15_PMUSERENR(%0))
+_WF1(cp15_pmuserenr_set, CP15_PMUSERENR(%0))
+_RF0(cp15_pminten_get, CP15_PMINTENSET(%0))
+_WF1(cp15_pminten_set, CP15_PMINTENSET(%0))
+_WF1(cp15_pminten_clr, CP15_PMINTENCLR(%0))
+#endif
+
+#undef	_FX
+#undef	_RF0
+#undef	_WF0
+#undef	_WF1
+
+/*
+ * TLB maintenance operations.
+ */
+
+/* Local (i.e. not broadcasting ) operations.  */
+
+/* Flush all TLB entries (even global). */
+static __inline void
+tlb_flush_all_local(void)
+{
+
+	dsb();
+	_CP15_TLBIALL();
+	dsb();
+}
+
+/* Flush all not global TLB entries. */
+static __inline void
+tlb_flush_all_ng_local(void)
+{
+
+	dsb();
+	_CP15_TLBIASID(CPU_ASID_KERNEL);
+	dsb();
+}
+
+/* Flush single TLB entry (even global). */
+static __inline void
+tlb_flush_local(vm_offset_t sva)
+{
+
+	dsb();
+	_CP15_TLBIMVA((sva & ~PAGE_MASK ) | CPU_ASID_KERNEL);
+	dsb();
+}
+
+/* Flush range of TLB entries (even global). */
+static __inline void
+tlb_flush_range_local(vm_offset_t sva, vm_size_t size)
+{
+	vm_offset_t va;
+	vm_offset_t eva = sva + size;
+
+	dsb();
+	for (va = sva; va < eva; va += PAGE_SIZE)
+		_CP15_TLBIMVA((va & ~PAGE_MASK ) | CPU_ASID_KERNEL);
+	dsb();
+}
+
+/* Broadcasting operations. */
+#if __ARM_ARCH >= 7 && defined SMP
+
+static __inline void
+tlb_flush_all(void)
+{
+
+	dsb();
+	_CP15_TLBIALLIS();
+	dsb();
+}
+
+static __inline void
+tlb_flush_all_ng(void)
+{
+
+	dsb();
+	_CP15_TLBIASIDIS(CPU_ASID_KERNEL);
+	dsb();
+}
+
+static __inline void
+tlb_flush(vm_offset_t sva)
+{
+
+	dsb();
+	_CP15_TLBIMVAAIS(sva);
+	dsb();
+}
+
+static __inline void
+tlb_flush_range(vm_offset_t sva,  vm_size_t size)
+{
+	vm_offset_t va;
+	vm_offset_t eva = sva + size;
+
+	dsb();
+	for (va = sva; va < eva; va += PAGE_SIZE)
+		_CP15_TLBIMVAAIS(va);
+	dsb();
+}
+#else /* SMP */
+
+#define tlb_flush_all() 		tlb_flush_all_local()
+#define tlb_flush_all_ng() 		tlb_flush_all_ng_local()
+#define tlb_flush(sva) 			tlb_flush_local(sva)
+#define tlb_flush_range(sva, size) 	tlb_flush_range_local(sva, size)
+
+#endif /* SMP */
+
+/*
+ * Cache maintenance operations.
+ */
+
+/*  Sync I and D caches to PoU */
+static __inline void
+icache_sync(vm_offset_t sva, vm_size_t size)
+{
+	vm_offset_t va;
+	vm_offset_t eva = sva + size;
+
+	dsb();
+	for (va = sva; va < eva; va += cpuinfo.dcache_line_size) {
+#if __ARM_ARCH >= 7 && defined SMP
+		_CP15_DCCMVAU(va);
+#else
+		_CP15_DCCMVAC(va);
+#endif
+	}
+	dsb();
+#if __ARM_ARCH >= 7 && defined SMP
+	_CP15_ICIALLUIS();
+#else
+	_CP15_ICIALLU();
+#endif
+	dsb();
+	isb();
+}
+
+/*  Invalidate I cache */
+static __inline void
+icache_inv_all(void)
+{
+#if __ARM_ARCH >= 7 && defined SMP
+	_CP15_ICIALLUIS();
+#else
+	_CP15_ICIALLU();
+#endif
+	dsb();
+	isb();
+}
+
+/* Invalidate branch predictor buffer */
+static __inline void
+bpb_inv_all(void)
+{
+#if __ARM_ARCH >= 7 && defined SMP
+	_CP15_BPIALLIS();
+#else
+	_CP15_BPIALL();
+#endif
+	dsb();
+	isb();
+}
+
+/* Write back D-cache to PoU */
+static __inline void
+dcache_wb_pou(vm_offset_t sva, vm_size_t size)
+{
+	vm_offset_t va;
+	vm_offset_t eva = sva + size;
+
+	dsb();
+	for (va = sva; va < eva; va += cpuinfo.dcache_line_size) {
+#if __ARM_ARCH >= 7 && defined SMP
+		_CP15_DCCMVAU(va);
+#else
+		_CP15_DCCMVAC(va);
+#endif
+	}
+	dsb();
+}
+
+/* Invalidate D-cache to PoC */
+static __inline void
+dcache_inv_poc(vm_offset_t sva, vm_paddr_t pa, vm_size_t size)
+{
+	vm_offset_t va;
+	vm_offset_t eva = sva + size;
+
+	/* invalidate L1 first */
+	for (va = sva; va < eva; va += cpuinfo.dcache_line_size) {
+		_CP15_DCIMVAC(va);
+	}
+	dsb();
+
+	/* then L2 */
+ 	cpu_l2cache_inv_range(pa, size);
+	dsb();
+
+	/* then L1 again */
+	for (va = sva; va < eva; va += cpuinfo.dcache_line_size) {
+		_CP15_DCIMVAC(va);
+	}
+	dsb();
+}
+
+/* Write back D-cache to PoC */
+static __inline void
+dcache_wb_poc(vm_offset_t sva, vm_paddr_t pa, vm_size_t size)
+{
+	vm_offset_t va;
+	vm_offset_t eva = sva + size;
+
+	dsb();
+
+	for (va = sva; va < eva; va += cpuinfo.dcache_line_size) {
+		_CP15_DCCMVAC(va);
+	}
+	dsb();
+
+	cpu_l2cache_wb_range(pa, size);
+}
+
+/* Write back and invalidate D-cache to PoC */
+static __inline void
+dcache_wbinv_poc(vm_offset_t sva, vm_paddr_t pa, vm_size_t size)
+{
+	vm_offset_t va;
+	vm_offset_t eva = sva + size;
+
+	dsb();
+
+	/* write back L1 first */
+	for (va = sva; va < eva; va += cpuinfo.dcache_line_size) {
+		_CP15_DCCMVAC(va);
+	}
+	dsb();
+
+	/* then write back and invalidate L2 */
+	cpu_l2cache_wbinv_range(pa, size);
+
+	/* then invalidate L1 */
+	for (va = sva; va < eva; va += cpuinfo.dcache_line_size) {
+		_CP15_DCIMVAC(va);
+	}
+	dsb();
+}
+
+/* Set TTB0 register */
+static __inline void
+cp15_ttbr_set(uint32_t reg)
+{
+	dsb();
+	_CP15_TTB_SET(reg);
+	dsb();
+	_CP15_BPIALL();
+	dsb();
+	isb();
+	tlb_flush_all_ng_local();
+}
+
+#endif /* !MACHINE_CPU_V6_H */


Property changes on: trunk/sys/arm/include/cpu-v6.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/cpu.h
===================================================================
--- trunk/sys/arm/include/cpu.h	                        (rev 0)
+++ trunk/sys/arm/include/cpu.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,69 @@
+/* $MidnightBSD$ */
+/* $NetBSD: cpu.h,v 1.2 2001/02/23 21:23:52 reinoud Exp $ */
+/* $FreeBSD: stable/10/sys/arm/include/cpu.h 278684 2015-02-13 17:53:11Z ian $ */
+
+#ifndef MACHINE_CPU_H
+#define MACHINE_CPU_H
+
+#include <machine/acle-compat.h>
+#include <machine/armreg.h>
+#include <machine/frame.h>
+
+void	cpu_halt(void);
+void	swi_vm(void *);
+
+#ifdef _KERNEL
+#if __ARM_ARCH >= 6
+#include <machine/cpu-v6.h>
+#endif
+static __inline uint64_t
+get_cyclecount(void)
+{
+#if __ARM_ARCH >= 6
+	return cp15_pmccntr_get();
+#else /* No performance counters, so use binuptime(9). This is slooooow */
+	struct bintime bt;
+
+	binuptime(&bt);
+	return ((uint64_t)bt.sec << 56 | bt.frac >> 8);
+#endif
+}
+#endif
+
+#define TRAPF_USERMODE(frame)	((frame->tf_spsr & PSR_MODE) == PSR_USR32_MODE)
+
+#define TRAPF_PC(tfp)		((tfp)->tf_pc)
+
+#define cpu_getstack(td)	((td)->td_frame->tf_usr_sp)
+#define cpu_setstack(td, sp)	((td)->td_frame->tf_usr_sp = (sp))
+#define cpu_spinwait()		/* nothing */
+
+#define ARM_NVEC		8
+#define ARM_VEC_ALL		0xffffffff
+
+extern vm_offset_t vector_page;
+
+/*
+ * Params passed into initarm. If you change the size of this you will
+ * need to update locore.S to allocate more memory on the stack before
+ * it calls initarm.
+ */
+struct arm_boot_params {
+	register_t	abp_size;	/* Size of this structure */
+	register_t	abp_r0;		/* r0 from the boot loader */
+	register_t	abp_r1;		/* r1 from the boot loader */
+	register_t	abp_r2;		/* r2 from the boot loader */
+	register_t	abp_r3;		/* r3 from the boot loader */
+	vm_offset_t	abp_physaddr;	/* The kernel physical address */
+	vm_offset_t	abp_pagetable;	/* The early page table */
+};
+
+void	arm_vector_init(vm_offset_t, int);
+void	fork_trampoline(void);
+void	identify_arm_cpu(void);
+void	*initarm(struct arm_boot_params *);
+
+extern char btext[];
+extern char etext[];
+int badaddr_read(void *, size_t, void *);
+#endif /* !MACHINE_CPU_H */


Property changes on: trunk/sys/arm/include/cpu.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/cpuconf.h
===================================================================
--- trunk/sys/arm/include/cpuconf.h	                        (rev 0)
+++ trunk/sys/arm/include/cpuconf.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,204 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: cpuconf.h,v 1.8 2003/09/06 08:55:42 rearnsha Exp $	*/
+
+/*-
+ * Copyright (c) 2002 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Jason R. Thorpe for Wasabi Systems, Inc.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed for the NetBSD Project by
+ *	Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
+ * 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: stable/10/sys/arm/include/cpuconf.h 276312 2014-12-27 17:36:49Z ian $
+ *
+ */
+
+#ifndef _MACHINE_CPUCONF_H_
+#define	_MACHINE_CPUCONF_H_
+
+/*
+ * IF YOU CHANGE THIS FILE, MAKE SURE TO UPDATE THE DEFINITION OF
+ * "PMAP_NEEDS_PTE_SYNC" IN <arm/arm32/pmap.h> FOR THE CPU TYPE
+ * YOU ARE ADDING SUPPORT FOR.
+ */
+
+/*
+ * Step 1: Count the number of CPU types configured into the kernel.
+ */
+#define	CPU_NTYPES	(defined(CPU_ARM9) +				\
+			 defined(CPU_ARM9E) +				\
+			 defined(CPU_ARM10) +				\
+			 defined(CPU_ARM1136) +				\
+			 defined(CPU_ARM1176) +				\
+			 defined(CPU_XSCALE_80200) +			\
+			 defined(CPU_XSCALE_80321) +			\
+			 defined(CPU_XSCALE_PXA2X0) +			\
+			 defined(CPU_FA526) +				\
+			 defined(CPU_FA626TE) +				\
+			 defined(CPU_XSCALE_IXP425)) +			\
+			 defined(CPU_CORTEXA) +				\
+			 defined(CPU_KRAIT) +				\
+			 defined(CPU_MV_PJ4B)
+
+/*
+ * Step 2: Determine which ARM architecture versions are configured.
+ */
+#if defined(CPU_ARM9) || defined(CPU_FA526)
+#define	ARM_ARCH_4	1
+#else
+#define	ARM_ARCH_4	0
+#endif
+
+#if (defined(CPU_ARM9E) || defined(CPU_ARM10) ||			\
+     defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) ||		\
+     defined(CPU_XSCALE_80219) || defined(CPU_XSCALE_81342) ||		\
+     defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) ||	\
+     defined(CPU_FA626TE))
+#define	ARM_ARCH_5	1
+#else
+#define	ARM_ARCH_5	0
+#endif
+
+#if !defined(ARM_ARCH_6)
+#if defined(CPU_ARM1136) || defined(CPU_ARM1176)
+#define ARM_ARCH_6	1
+#else
+#define ARM_ARCH_6	0
+#endif
+#endif
+
+#if defined(CPU_CORTEXA) || defined(CPU_KRAIT) || defined(CPU_MV_PJ4B)
+#define ARM_ARCH_7A	1
+#else
+#define ARM_ARCH_7A	0
+#endif
+
+#define	ARM_NARCH	(ARM_ARCH_4 + ARM_ARCH_5 + ARM_ARCH_6 | ARM_ARCH_7A)
+
+/*
+ * Compatibility for userland builds that have no CPUTYPE defined.  Use the ARCH
+ * constants predefined by the compiler to define our old-school arch constants.
+ * This is a stopgap measure to tide us over until the conversion of all code
+ * to the newer ACLE constants defined by ARM (see acle-compat.h).
+ */
+#if ARM_NARCH == 0
+#if defined(__ARM_ARCH_4T__)
+#undef  ARM_ARCH_4
+#undef  ARM_NARCH
+#define ARM_ARCH_4 1
+#define ARM_NARCH  1
+#define CPU_ARM9 1
+#elif defined(__ARM_ARCH_6ZK__)
+#undef  ARM_ARCH_6
+#undef  ARM_NARCH
+#define ARM_ARCH_6 1
+#define ARM_NARCH  1
+#define CPU_ARM1176 1
+#endif
+#endif
+
+#if ARM_NARCH == 0 && !defined(KLD_MODULE) && defined(_KERNEL)
+#error ARM_NARCH is 0
+#endif
+
+#if ARM_ARCH_5 || ARM_ARCH_6 || ARM_ARCH_7A
+/*
+ * We could support Thumb code on v4T, but the lack of clean interworking
+ * makes that hard.
+ */
+#define THUMB_CODE
+#endif
+
+/*
+ * Step 3: Define which MMU classes are configured:
+ *
+ *	ARM_MMU_MEMC		Prehistoric, external memory controller
+ *				and MMU for ARMv2 CPUs.
+ *
+ *      ARM_MMU_GENERIC		Generic ARM MMU, compatible with ARMv4 and v5.
+ *
+ *	ARM_MMU_V6		ARMv6 MMU.
+ *
+ *	ARM_MMU_V7		ARMv7 MMU.
+ *
+ *	ARM_MMU_XSCALE		XScale MMU.  Compatible with generic ARM
+ *				MMU, but also has several extensions which
+ *				require different PTE layout to use.
+ */
+#if (defined(CPU_ARM9) || defined(CPU_ARM9E) ||	\
+     defined(CPU_ARM10) || defined(CPU_FA526) ||	\
+     defined(CPU_FA626TE))
+#define	ARM_MMU_GENERIC		1
+#else
+#define	ARM_MMU_GENERIC		0
+#endif
+
+#if defined(CPU_ARM1136) || defined(CPU_ARM1176)
+#define ARM_MMU_V6		1
+#else
+#define ARM_MMU_V6		0
+#endif
+
+#if defined(CPU_CORTEXA) || defined(CPU_KRAIT) || defined(CPU_MV_PJ4B)
+#define ARM_MMU_V7		1
+#else
+#define ARM_MMU_V7		0
+#endif
+
+#if (defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) ||		\
+     defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) ||	\
+     defined(CPU_XSCALE_80219) || defined(CPU_XSCALE_81342))
+#define	ARM_MMU_XSCALE		1
+#else
+#define	ARM_MMU_XSCALE		0
+#endif
+
+#define	ARM_NMMUS		(ARM_MMU_GENERIC + ARM_MMU_V6 + \
+				 ARM_MMU_V7 + ARM_MMU_XSCALE)
+#if ARM_NMMUS == 0 && !defined(KLD_MODULE) && defined(_KERNEL)
+#error ARM_NMMUS is 0
+#endif
+
+/*
+ * Step 4: Define features that may be present on a subset of CPUs
+ *
+ *	ARM_XSCALE_PMU		Performance Monitoring Unit on 80200 and 80321
+ */
+
+#if (defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) || \
+     defined(CPU_XSCALE_80219) || defined(CPU_XSCALE_81342))
+#define ARM_XSCALE_PMU	1
+#else
+#define ARM_XSCALE_PMU	0
+#endif
+
+#if defined(CPU_XSCALE_81342)
+#define CPU_XSCALE_CORE3
+#endif
+#endif /* _MACHINE_CPUCONF_H_ */


Property changes on: trunk/sys/arm/include/cpuconf.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/cpufunc.h
===================================================================
--- trunk/sys/arm/include/cpufunc.h	                        (rev 0)
+++ trunk/sys/arm/include/cpufunc.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,680 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: cpufunc.h,v 1.29 2003/09/06 09:08:35 rearnsha Exp $	*/
+
+/*-
+ * Copyright (c) 1997 Mark Brinicombe.
+ * Copyright (c) 1997 Causality Limited
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Causality Limited.
+ * 4. The name of Causality Limited may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY CAUSALITY LIMITED ``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 CAUSALITY LIMITED 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.
+ *
+ * RiscBSD kernel project
+ *
+ * cpufunc.h
+ *
+ * Prototypes for cpu, mmu and tlb related functions.
+ *
+ * $FreeBSD: stable/10/sys/arm/include/cpufunc.h 278635 2015-02-12 21:10:24Z ian $
+ */
+
+#ifndef _MACHINE_CPUFUNC_H_
+#define _MACHINE_CPUFUNC_H_
+
+#ifdef _KERNEL
+
+#include <sys/types.h>
+#include <machine/cpuconf.h>
+#include <machine/katelib.h> /* For in[bwl] and out[bwl] */
+
+static __inline void
+breakpoint(void)
+{
+	__asm(".word      0xe7ffffff");
+}
+
+struct cpu_functions {
+
+	/* CPU functions */
+	
+	u_int	(*cf_id)		(void);
+	void	(*cf_cpwait)		(void);
+
+	/* MMU functions */
+
+	u_int	(*cf_control)		(u_int bic, u_int eor);
+	void	(*cf_domains)		(u_int domains);
+	void	(*cf_setttb)		(u_int ttb);
+	u_int	(*cf_faultstatus)	(void);
+	u_int	(*cf_faultaddress)	(void);
+
+	/* TLB functions */
+
+	void	(*cf_tlb_flushID)	(void);	
+	void	(*cf_tlb_flushID_SE)	(u_int va);	
+	void	(*cf_tlb_flushI)	(void);
+	void	(*cf_tlb_flushI_SE)	(u_int va);	
+	void	(*cf_tlb_flushD)	(void);
+	void	(*cf_tlb_flushD_SE)	(u_int va);	
+
+	/*
+	 * Cache operations:
+	 *
+	 * We define the following primitives:
+	 *
+	 *	icache_sync_all		Synchronize I-cache
+	 *	icache_sync_range	Synchronize I-cache range
+	 *
+	 *	dcache_wbinv_all	Write-back and Invalidate D-cache
+	 *	dcache_wbinv_range	Write-back and Invalidate D-cache range
+	 *	dcache_inv_range	Invalidate D-cache range
+	 *	dcache_wb_range		Write-back D-cache range
+	 *
+	 *	idcache_wbinv_all	Write-back and Invalidate D-cache,
+	 *				Invalidate I-cache
+	 *	idcache_wbinv_range	Write-back and Invalidate D-cache,
+	 *				Invalidate I-cache range
+	 *
+	 * Note that the ARM term for "write-back" is "clean".  We use
+	 * the term "write-back" since it's a more common way to describe
+	 * the operation.
+	 *
+	 * There are some rules that must be followed:
+	 *
+	 *	ID-cache Invalidate All:
+	 *		Unlike other functions, this one must never write back.
+	 *		It is used to intialize the MMU when it is in an unknown
+	 *		state (such as when it may have lines tagged as valid
+	 *		that belong to a previous set of mappings).
+	 *                                          
+	 *	I-cache Synch (all or range):
+	 *		The goal is to synchronize the instruction stream,
+	 *		so you may beed to write-back dirty D-cache blocks
+	 *		first.  If a range is requested, and you can't
+	 *		synchronize just a range, you have to hit the whole
+	 *		thing.
+	 *
+	 *	D-cache Write-Back and Invalidate range:
+	 *		If you can't WB-Inv a range, you must WB-Inv the
+	 *		entire D-cache.
+	 *
+	 *	D-cache Invalidate:
+	 *		If you can't Inv the D-cache, you must Write-Back
+	 *		and Invalidate.  Code that uses this operation
+	 *		MUST NOT assume that the D-cache will not be written
+	 *		back to memory.
+	 *
+	 *	D-cache Write-Back:
+	 *		If you can't Write-back without doing an Inv,
+	 *		that's fine.  Then treat this as a WB-Inv.
+	 *		Skipping the invalidate is merely an optimization.
+	 *
+	 *	All operations:
+	 *		Valid virtual addresses must be passed to each
+	 *		cache operation.
+	 */
+	void	(*cf_icache_sync_all)	(void);
+	void	(*cf_icache_sync_range)	(vm_offset_t, vm_size_t);
+
+	void	(*cf_dcache_wbinv_all)	(void);
+	void	(*cf_dcache_wbinv_range) (vm_offset_t, vm_size_t);
+	void	(*cf_dcache_inv_range)	(vm_offset_t, vm_size_t);
+	void	(*cf_dcache_wb_range)	(vm_offset_t, vm_size_t);
+
+	void	(*cf_idcache_inv_all)	(void);
+	void	(*cf_idcache_wbinv_all)	(void);
+	void	(*cf_idcache_wbinv_range) (vm_offset_t, vm_size_t);
+	void	(*cf_l2cache_wbinv_all) (void);
+	void	(*cf_l2cache_wbinv_range) (vm_offset_t, vm_size_t);
+	void	(*cf_l2cache_inv_range)	  (vm_offset_t, vm_size_t);
+	void	(*cf_l2cache_wb_range)	  (vm_offset_t, vm_size_t);
+	void	(*cf_l2cache_drain_writebuf)	  (void);
+
+	/* Other functions */
+
+	void	(*cf_flush_prefetchbuf)	(void);
+	void	(*cf_drain_writebuf)	(void);
+	void	(*cf_flush_brnchtgt_C)	(void);
+	void	(*cf_flush_brnchtgt_E)	(u_int va);
+
+	void	(*cf_sleep)		(int mode);
+
+	/* Soft functions */
+
+	int	(*cf_dataabt_fixup)	(void *arg);
+	int	(*cf_prefetchabt_fixup)	(void *arg);
+
+	void	(*cf_context_switch)	(void);
+
+	void	(*cf_setup)		(char *string);
+};
+
+extern struct cpu_functions cpufuncs;
+extern u_int cputype;
+
+#define cpu_id()		cpufuncs.cf_id()
+#define	cpu_cpwait()		cpufuncs.cf_cpwait()
+
+#define cpu_control(c, e)	cpufuncs.cf_control(c, e)
+#define cpu_domains(d)		cpufuncs.cf_domains(d)
+#define cpu_setttb(t)		cpufuncs.cf_setttb(t)
+#define cpu_faultstatus()	cpufuncs.cf_faultstatus()
+#define cpu_faultaddress()	cpufuncs.cf_faultaddress()
+
+#ifndef SMP
+
+#define	cpu_tlb_flushID()	cpufuncs.cf_tlb_flushID()
+#define	cpu_tlb_flushID_SE(e)	cpufuncs.cf_tlb_flushID_SE(e)
+#define	cpu_tlb_flushI()	cpufuncs.cf_tlb_flushI()
+#define	cpu_tlb_flushI_SE(e)	cpufuncs.cf_tlb_flushI_SE(e)
+#define	cpu_tlb_flushD()	cpufuncs.cf_tlb_flushD()
+#define	cpu_tlb_flushD_SE(e)	cpufuncs.cf_tlb_flushD_SE(e)
+
+#else
+void tlb_broadcast(int);
+
+#if defined(CPU_CORTEXA) || defined(CPU_MV_PJ4B) || defined(CPU_KRAIT)
+#define TLB_BROADCAST	/* No need to explicitely send an IPI */
+#else
+#define TLB_BROADCAST	tlb_broadcast(7)
+#endif
+
+#define	cpu_tlb_flushID() do { \
+	cpufuncs.cf_tlb_flushID(); \
+	TLB_BROADCAST; \
+} while(0)
+
+#define	cpu_tlb_flushID_SE(e) do { \
+	cpufuncs.cf_tlb_flushID_SE(e); \
+	TLB_BROADCAST; \
+} while(0)
+
+
+#define	cpu_tlb_flushI() do { \
+	cpufuncs.cf_tlb_flushI(); \
+	TLB_BROADCAST; \
+} while(0)
+
+
+#define	cpu_tlb_flushI_SE(e) do { \
+	cpufuncs.cf_tlb_flushI_SE(e); \
+	TLB_BROADCAST; \
+} while(0)
+
+
+#define	cpu_tlb_flushD() do { \
+	cpufuncs.cf_tlb_flushD(); \
+	TLB_BROADCAST; \
+} while(0)
+
+
+#define	cpu_tlb_flushD_SE(e) do { \
+	cpufuncs.cf_tlb_flushD_SE(e); \
+	TLB_BROADCAST; \
+} while(0)
+
+#endif
+
+#define	cpu_icache_sync_all()	cpufuncs.cf_icache_sync_all()
+#define	cpu_icache_sync_range(a, s) cpufuncs.cf_icache_sync_range((a), (s))
+
+#define	cpu_dcache_wbinv_all()	cpufuncs.cf_dcache_wbinv_all()
+#define	cpu_dcache_wbinv_range(a, s) cpufuncs.cf_dcache_wbinv_range((a), (s))
+#define	cpu_dcache_inv_range(a, s) cpufuncs.cf_dcache_inv_range((a), (s))
+#define	cpu_dcache_wb_range(a, s) cpufuncs.cf_dcache_wb_range((a), (s))
+
+#define	cpu_idcache_inv_all()	cpufuncs.cf_idcache_inv_all()
+#define	cpu_idcache_wbinv_all()	cpufuncs.cf_idcache_wbinv_all()
+#define	cpu_idcache_wbinv_range(a, s) cpufuncs.cf_idcache_wbinv_range((a), (s))
+#define cpu_l2cache_wbinv_all()	cpufuncs.cf_l2cache_wbinv_all()
+#define cpu_l2cache_wb_range(a, s) cpufuncs.cf_l2cache_wb_range((a), (s))
+#define cpu_l2cache_inv_range(a, s) cpufuncs.cf_l2cache_inv_range((a), (s))
+#define cpu_l2cache_wbinv_range(a, s) cpufuncs.cf_l2cache_wbinv_range((a), (s))
+#define cpu_l2cache_drain_writebuf() cpufuncs.cf_l2cache_drain_writebuf()
+
+#define	cpu_flush_prefetchbuf()	cpufuncs.cf_flush_prefetchbuf()
+#define	cpu_drain_writebuf()	cpufuncs.cf_drain_writebuf()
+#define	cpu_flush_brnchtgt_C()	cpufuncs.cf_flush_brnchtgt_C()
+#define	cpu_flush_brnchtgt_E(e)	cpufuncs.cf_flush_brnchtgt_E(e)
+
+#define cpu_sleep(m)		cpufuncs.cf_sleep(m)
+
+#define cpu_dataabt_fixup(a)		cpufuncs.cf_dataabt_fixup(a)
+#define cpu_prefetchabt_fixup(a)	cpufuncs.cf_prefetchabt_fixup(a)
+#define ABORT_FIXUP_OK		0	/* fixup succeeded */
+#define ABORT_FIXUP_FAILED	1	/* fixup failed */
+#define ABORT_FIXUP_RETURN	2	/* abort handler should return */
+
+#define cpu_setup(a)			cpufuncs.cf_setup(a)
+
+int	set_cpufuncs		(void);
+#define ARCHITECTURE_NOT_PRESENT	1	/* known but not configured */
+#define ARCHITECTURE_NOT_SUPPORTED	2	/* not known */
+
+void	cpufunc_nullop		(void);
+int	cpufunc_null_fixup	(void *);
+int	early_abort_fixup	(void *);
+int	late_abort_fixup	(void *);
+u_int	cpufunc_id		(void);
+u_int	cpufunc_cpuid		(void);
+u_int	cpufunc_control		(u_int clear, u_int bic);
+void	cpufunc_domains		(u_int domains);
+u_int	cpufunc_faultstatus	(void);
+u_int	cpufunc_faultaddress	(void);
+u_int	cpu_pfr			(int);
+
+#if defined(CPU_FA526) || defined(CPU_FA626TE)
+void	fa526_setup		(char *arg);
+void	fa526_setttb		(u_int ttb);
+void	fa526_context_switch	(void);
+void	fa526_cpu_sleep		(int);
+void	fa526_tlb_flushI_SE	(u_int);
+void	fa526_tlb_flushID_SE	(u_int);
+void	fa526_flush_prefetchbuf	(void);
+void	fa526_flush_brnchtgt_E	(u_int);
+
+void	fa526_icache_sync_all	(void);
+void	fa526_icache_sync_range(vm_offset_t start, vm_size_t end);
+void	fa526_dcache_wbinv_all	(void);
+void	fa526_dcache_wbinv_range(vm_offset_t start, vm_size_t end);
+void	fa526_dcache_inv_range	(vm_offset_t start, vm_size_t end);
+void	fa526_dcache_wb_range	(vm_offset_t start, vm_size_t end);
+void	fa526_idcache_wbinv_all(void);
+void	fa526_idcache_wbinv_range(vm_offset_t start, vm_size_t end);
+#endif
+
+
+#ifdef CPU_ARM9
+void	arm9_setttb		(u_int);
+
+void	arm9_tlb_flushID_SE	(u_int va);
+
+void	arm9_icache_sync_all	(void);
+void	arm9_icache_sync_range	(vm_offset_t, vm_size_t);
+
+void	arm9_dcache_wbinv_all	(void);
+void	arm9_dcache_wbinv_range (vm_offset_t, vm_size_t);
+void	arm9_dcache_inv_range	(vm_offset_t, vm_size_t);
+void	arm9_dcache_wb_range	(vm_offset_t, vm_size_t);
+
+void	arm9_idcache_wbinv_all	(void);
+void	arm9_idcache_wbinv_range (vm_offset_t, vm_size_t);
+
+void	arm9_context_switch	(void);
+
+void	arm9_setup		(char *string);
+
+extern unsigned arm9_dcache_sets_max;
+extern unsigned arm9_dcache_sets_inc;
+extern unsigned arm9_dcache_index_max;
+extern unsigned arm9_dcache_index_inc;
+#endif
+
+#if defined(CPU_ARM9E) || defined(CPU_ARM10)
+void	arm10_setttb		(u_int);
+
+void	arm10_tlb_flushID_SE	(u_int);
+void	arm10_tlb_flushI_SE	(u_int);
+
+void	arm10_icache_sync_all	(void);
+void	arm10_icache_sync_range	(vm_offset_t, vm_size_t);
+
+void	arm10_dcache_wbinv_all	(void);
+void	arm10_dcache_wbinv_range (vm_offset_t, vm_size_t);
+void	arm10_dcache_inv_range	(vm_offset_t, vm_size_t);
+void	arm10_dcache_wb_range	(vm_offset_t, vm_size_t);
+
+void	arm10_idcache_wbinv_all	(void);
+void	arm10_idcache_wbinv_range (vm_offset_t, vm_size_t);
+
+void	arm10_context_switch	(void);
+
+void	arm10_setup		(char *string);
+
+extern unsigned arm10_dcache_sets_max;
+extern unsigned arm10_dcache_sets_inc;
+extern unsigned arm10_dcache_index_max;
+extern unsigned arm10_dcache_index_inc;
+
+u_int	sheeva_control_ext 		(u_int, u_int);
+void	sheeva_cpu_sleep		(int);
+void	sheeva_setttb			(u_int);
+void	sheeva_dcache_wbinv_range	(vm_offset_t, vm_size_t);
+void	sheeva_dcache_inv_range		(vm_offset_t, vm_size_t);
+void	sheeva_dcache_wb_range		(vm_offset_t, vm_size_t);
+void	sheeva_idcache_wbinv_range	(vm_offset_t, vm_size_t);
+
+void	sheeva_l2cache_wbinv_range	(vm_offset_t, vm_size_t);
+void	sheeva_l2cache_inv_range	(vm_offset_t, vm_size_t);
+void	sheeva_l2cache_wb_range		(vm_offset_t, vm_size_t);
+void	sheeva_l2cache_wbinv_all	(void);
+#endif
+
+#if defined(CPU_ARM1136) || defined(CPU_ARM1176) || \
+	defined(CPU_MV_PJ4B) || defined(CPU_CORTEXA) || defined(CPU_KRAIT)
+void	arm11_setttb		(u_int);
+void	arm11_sleep		(int);
+
+void	arm11_tlb_flushID_SE	(u_int);
+void	arm11_tlb_flushI_SE	(u_int);
+
+void	arm11_context_switch	(void);
+
+void	arm11_setup		(char *string);
+void	arm11_tlb_flushID	(void);
+void	arm11_tlb_flushI	(void);
+void	arm11_tlb_flushD	(void);
+void	arm11_tlb_flushD_SE	(u_int va);
+
+void	arm11_drain_writebuf	(void);
+
+void	pj4b_setttb			(u_int);
+
+void	pj4b_drain_readbuf		(void);
+void	pj4b_flush_brnchtgt_all		(void);
+void	pj4b_flush_brnchtgt_va		(u_int);
+void	pj4b_sleep			(int);
+
+void	armv6_icache_sync_all		(void);
+void	armv6_icache_sync_range		(vm_offset_t, vm_size_t);
+
+void	armv6_dcache_wbinv_all		(void);
+void	armv6_dcache_wbinv_range	(vm_offset_t, vm_size_t);
+void	armv6_dcache_inv_range		(vm_offset_t, vm_size_t);
+void	armv6_dcache_wb_range		(vm_offset_t, vm_size_t);
+
+void	armv6_idcache_inv_all		(void);
+void	armv6_idcache_wbinv_all		(void);
+void	armv6_idcache_wbinv_range	(vm_offset_t, vm_size_t);
+
+void	armv7_setttb			(u_int);
+void	armv7_tlb_flushID		(void);
+void	armv7_tlb_flushID_SE		(u_int);
+void	armv7_icache_sync_all		(void);
+void	armv7_icache_sync_range		(vm_offset_t, vm_size_t);
+void	armv7_idcache_wbinv_range	(vm_offset_t, vm_size_t);
+void	armv7_idcache_inv_all		(void);
+void	armv7_dcache_wbinv_all		(void);
+void	armv7_idcache_wbinv_all		(void);
+void	armv7_dcache_wbinv_range	(vm_offset_t, vm_size_t);
+void	armv7_dcache_inv_range		(vm_offset_t, vm_size_t);
+void	armv7_dcache_wb_range		(vm_offset_t, vm_size_t);
+void	armv7_cpu_sleep			(int);
+void	armv7_setup			(char *string);
+void	armv7_context_switch		(void);
+void	armv7_drain_writebuf		(void);
+void	armv7_sev			(void);
+void	armv7_sleep			(int unused);
+u_int	armv7_auxctrl			(u_int, u_int);
+void	pj4bv7_setup			(char *string);
+void	pj4b_config			(void);
+
+int	get_core_id			(void);
+
+void	armadaxp_idcache_wbinv_all	(void);
+
+void 	cortexa_setup			(char *);
+#endif
+
+#if defined(CPU_ARM1136) || defined(CPU_ARM1176)
+void    arm11x6_setttb                  (u_int);
+void    arm11x6_idcache_wbinv_all       (void);
+void    arm11x6_dcache_wbinv_all        (void);
+void    arm11x6_icache_sync_all         (void);
+void    arm11x6_flush_prefetchbuf       (void);
+void    arm11x6_icache_sync_range       (vm_offset_t, vm_size_t);
+void    arm11x6_idcache_wbinv_range     (vm_offset_t, vm_size_t);
+void    arm11x6_setup                   (char *string);
+void    arm11x6_sleep                   (int);  /* no ref. for errata */
+#endif
+#if defined(CPU_ARM1136)
+void    arm1136_sleep_rev0              (int);  /* for errata 336501 */
+#endif
+
+#if defined(CPU_ARM9E) || defined (CPU_ARM10)
+void	armv5_ec_setttb(u_int);
+
+void	armv5_ec_icache_sync_all(void);
+void	armv5_ec_icache_sync_range(vm_offset_t, vm_size_t);
+
+void	armv5_ec_dcache_wbinv_all(void);
+void	armv5_ec_dcache_wbinv_range(vm_offset_t, vm_size_t);
+void	armv5_ec_dcache_inv_range(vm_offset_t, vm_size_t);
+void	armv5_ec_dcache_wb_range(vm_offset_t, vm_size_t);
+
+void	armv5_ec_idcache_wbinv_all(void);
+void	armv5_ec_idcache_wbinv_range(vm_offset_t, vm_size_t);
+#endif
+
+#if defined (CPU_ARM10)
+void	armv5_setttb(u_int);
+
+void	armv5_icache_sync_all(void);
+void	armv5_icache_sync_range(vm_offset_t, vm_size_t);
+
+void	armv5_dcache_wbinv_all(void);
+void	armv5_dcache_wbinv_range(vm_offset_t, vm_size_t);
+void	armv5_dcache_inv_range(vm_offset_t, vm_size_t);
+void	armv5_dcache_wb_range(vm_offset_t, vm_size_t);
+
+void	armv5_idcache_wbinv_all(void);
+void	armv5_idcache_wbinv_range(vm_offset_t, vm_size_t);
+
+extern unsigned armv5_dcache_sets_max;
+extern unsigned armv5_dcache_sets_inc;
+extern unsigned armv5_dcache_index_max;
+extern unsigned armv5_dcache_index_inc;
+#endif
+
+#if defined(CPU_ARM9) || defined(CPU_ARM9E) || defined(CPU_ARM10) ||	\
+  defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) ||		\
+  defined(CPU_FA526) || defined(CPU_FA626TE) ||				\
+  defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) ||		\
+  defined(CPU_XSCALE_80219) || defined(CPU_XSCALE_81342)
+
+void	armv4_tlb_flushID	(void);
+void	armv4_tlb_flushI	(void);
+void	armv4_tlb_flushD	(void);
+void	armv4_tlb_flushD_SE	(u_int va);
+
+void	armv4_drain_writebuf	(void);
+void	armv4_idcache_inv_all	(void);
+#endif
+
+#if defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) ||	\
+  defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) ||	\
+  defined(CPU_XSCALE_80219) || defined(CPU_XSCALE_81342)
+void	xscale_cpwait		(void);
+
+void	xscale_cpu_sleep	(int mode);
+
+u_int	xscale_control		(u_int clear, u_int bic);
+
+void	xscale_setttb		(u_int ttb);
+
+void	xscale_tlb_flushID_SE	(u_int va);
+
+void	xscale_cache_flushID	(void);
+void	xscale_cache_flushI	(void);
+void	xscale_cache_flushD	(void);
+void	xscale_cache_flushD_SE	(u_int entry);
+
+void	xscale_cache_cleanID	(void);
+void	xscale_cache_cleanD	(void);
+void	xscale_cache_cleanD_E	(u_int entry);
+
+void	xscale_cache_clean_minidata (void);
+
+void	xscale_cache_purgeID	(void);
+void	xscale_cache_purgeID_E	(u_int entry);
+void	xscale_cache_purgeD	(void);
+void	xscale_cache_purgeD_E	(u_int entry);
+
+void	xscale_cache_syncI	(void);
+void	xscale_cache_cleanID_rng (vm_offset_t start, vm_size_t end);
+void	xscale_cache_cleanD_rng	(vm_offset_t start, vm_size_t end);
+void	xscale_cache_purgeID_rng (vm_offset_t start, vm_size_t end);
+void	xscale_cache_purgeD_rng	(vm_offset_t start, vm_size_t end);
+void	xscale_cache_syncI_rng	(vm_offset_t start, vm_size_t end);
+void	xscale_cache_flushD_rng	(vm_offset_t start, vm_size_t end);
+
+void	xscale_context_switch	(void);
+
+void	xscale_setup		(char *string);
+#endif	/* CPU_XSCALE_80200 || CPU_XSCALE_80321 || CPU_XSCALE_PXA2X0 || CPU_XSCALE_IXP425
+	   CPU_XSCALE_80219 */
+
+#ifdef	CPU_XSCALE_81342
+
+void	xscalec3_l2cache_purge	(void);
+void	xscalec3_cache_purgeID	(void);
+void	xscalec3_cache_purgeD	(void);
+void	xscalec3_cache_cleanID	(void);
+void	xscalec3_cache_cleanD	(void);
+void	xscalec3_cache_syncI	(void);
+
+void	xscalec3_cache_purgeID_rng 	(vm_offset_t start, vm_size_t end);
+void	xscalec3_cache_purgeD_rng	(vm_offset_t start, vm_size_t end);
+void	xscalec3_cache_cleanID_rng	(vm_offset_t start, vm_size_t end);
+void	xscalec3_cache_cleanD_rng	(vm_offset_t start, vm_size_t end);
+void	xscalec3_cache_syncI_rng	(vm_offset_t start, vm_size_t end);
+
+void	xscalec3_l2cache_flush_rng	(vm_offset_t, vm_size_t);
+void	xscalec3_l2cache_clean_rng	(vm_offset_t start, vm_size_t end);
+void	xscalec3_l2cache_purge_rng	(vm_offset_t start, vm_size_t end);
+
+
+void	xscalec3_setttb		(u_int ttb);
+void	xscalec3_context_switch	(void);
+
+#endif /* CPU_XSCALE_81342 */
+
+#define setttb		cpu_setttb
+#define drain_writebuf	cpu_drain_writebuf
+
+/*
+ * Macros for manipulating CPU interrupts
+ */
+static __inline u_int32_t __set_cpsr_c(u_int bic, u_int eor) __attribute__((__unused__));
+
+static __inline u_int32_t
+__set_cpsr_c(u_int bic, u_int eor)
+{
+	u_int32_t	tmp, ret;
+
+	__asm __volatile(
+		"mrs     %0, cpsr\n"	/* Get the CPSR */
+		"bic	 %1, %0, %2\n"	/* Clear bits */
+		"eor	 %1, %1, %3\n"	/* XOR bits */
+		"msr     cpsr_c, %1\n"	/* Set the control field of CPSR */
+	: "=&r" (ret), "=&r" (tmp)
+	: "r" (bic), "r" (eor) : "memory");
+
+	return ret;
+}
+
+#define	ARM_CPSR_F32	(1 << 6)	/* FIQ disable */
+#define	ARM_CPSR_I32	(1 << 7)	/* IRQ disable */
+
+#define disable_interrupts(mask)					\
+	(__set_cpsr_c((mask) & (ARM_CPSR_I32 | ARM_CPSR_F32),		\
+		      (mask) & (ARM_CPSR_I32 | ARM_CPSR_F32)))
+
+#define enable_interrupts(mask)						\
+	(__set_cpsr_c((mask) & (ARM_CPSR_I32 | ARM_CPSR_F32), 0))
+
+#define restore_interrupts(old_cpsr)					\
+	(__set_cpsr_c((ARM_CPSR_I32 | ARM_CPSR_F32),			\
+		      (old_cpsr) & (ARM_CPSR_I32 | ARM_CPSR_F32)))
+
+static __inline register_t
+intr_disable(void)
+{
+	register_t s;
+
+	s = disable_interrupts(ARM_CPSR_I32 | ARM_CPSR_F32);
+	return (s);
+}
+
+static __inline void
+intr_restore(register_t s)
+{
+
+	restore_interrupts(s);
+}
+
+/* Functions to manipulate the CPSR. */
+u_int	SetCPSR(u_int bic, u_int eor);
+u_int	GetCPSR(void);
+
+/*
+ * Functions to manipulate cpu r13
+ * (in arm/arm32/setstack.S)
+ */
+
+void set_stackptr	(u_int mode, u_int address);
+u_int get_stackptr	(u_int mode);
+
+/*
+ * Miscellany
+ */
+
+int get_pc_str_offset	(void);
+
+/*
+ * CPU functions from locore.S
+ */
+
+void cpu_reset		(void) __attribute__((__noreturn__));
+
+/*
+ * Cache info variables.
+ */
+
+/* PRIMARY CACHE VARIABLES */
+extern int	arm_picache_size;
+extern int	arm_picache_line_size;
+extern int	arm_picache_ways;
+
+extern int	arm_pdcache_size;	/* and unified */
+extern int	arm_pdcache_line_size;
+extern int	arm_pdcache_ways;
+
+extern int	arm_pcache_type;
+extern int	arm_pcache_unified;
+
+extern int	arm_dcache_align;
+extern int	arm_dcache_align_mask;
+
+extern u_int	arm_cache_level;
+extern u_int	arm_cache_loc;
+extern u_int	arm_cache_type[14];
+
+#endif	/* _KERNEL */
+#endif	/* _MACHINE_CPUFUNC_H_ */
+
+/* End of cpufunc.h */


Property changes on: trunk/sys/arm/include/cpufunc.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/cpuinfo.h
===================================================================
--- trunk/sys/arm/include/cpuinfo.h	                        (rev 0)
+++ trunk/sys/arm/include/cpuinfo.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,98 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright 2014 Svatopluk Kraus <onwahe at gmail.com>
+ * Copyright 2014 Michal Meloun <meloun at miracle.cz>
+ * 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: stable/10/sys/arm/include/cpuinfo.h 283336 2015-05-23 23:05:31Z ian $
+ */
+
+#ifndef	_MACHINE_CPUINFO_H_
+#define	_MACHINE_CPUINFO_H_
+
+#include <sys/types.h>
+
+struct cpuinfo {
+	/* raw id registers */
+	uint32_t midr;
+	uint32_t ctr;
+	uint32_t tcmtr;
+	uint32_t tlbtr;
+	uint32_t mpidr;
+	uint32_t revidr;
+	uint32_t id_pfr0;
+	uint32_t id_pfr1;
+	uint32_t id_dfr0;
+	uint32_t id_afr0;
+	uint32_t id_mmfr0;
+	uint32_t id_mmfr1;
+	uint32_t id_mmfr2;
+	uint32_t id_mmfr3;
+	uint32_t id_isar0;
+	uint32_t id_isar1;
+	uint32_t id_isar2;
+	uint32_t id_isar3;
+	uint32_t id_isar4;
+	uint32_t id_isar5;
+	uint32_t cbar;
+
+        /* Parsed bits of above registers... */
+
+	/* midr */
+	int implementer;
+	int revision;
+	int architecture;
+	int part_number;
+	int patch;
+
+	/* id_mmfr0 */
+	int outermost_shareability;
+	int shareability_levels;
+	int auxiliary_registers;
+	int innermost_shareability;
+
+	/* id_mmfr1 */
+	int mem_barrier;
+
+	/* id_mmfr3 */
+	int coherent_walk;
+	int maintenance_broadcast;
+
+	/* id_pfr1 */
+	int generic_timer_ext;
+	int virtualization_ext;
+	int security_ext;
+
+	/* L1 cache info */
+	int dcache_line_size;
+	int dcache_line_mask;
+	int icache_line_size;
+	int icache_line_mask;
+};
+
+extern struct cpuinfo cpuinfo;
+
+void cpuinfo_init(void);
+
+#endif	/* _MACHINE_CPUINFO_H_ */


Property changes on: trunk/sys/arm/include/cpuinfo.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/db_machdep.h
===================================================================
--- trunk/sys/arm/include/db_machdep.h	                        (rev 0)
+++ trunk/sys/arm/include/db_machdep.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,99 @@
+/* $MidnightBSD$ */
+/*-
+ * Mach Operating System
+ * Copyright (c) 1991,1990 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ *  Software Distribution Coordinator  or  Software.Distribution at CS.CMU.EDU
+ *  School of Computer Science
+ *  Carnegie Mellon University
+ *  Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ *
+ *	from: FreeBSD: src/sys/i386/include/db_machdep.h,v 1.16 1999/10/04
+ * $FreeBSD: stable/10/sys/arm/include/db_machdep.h 278614 2015-02-12 04:15:55Z ian $
+ */
+
+#ifndef	_MACHINE_DB_MACHDEP_H_
+#define	_MACHINE_DB_MACHDEP_H_
+
+#include <machine/frame.h>
+#include <machine/trap.h>
+#include <machine/armreg.h>
+
+#define T_BREAKPOINT	(1)
+typedef vm_offset_t	db_addr_t;
+typedef int		db_expr_t;
+
+#define	PC_REGS()	((db_addr_t)kdb_thrctx->pcb_regs.sf_pc)
+
+#define	BKPT_INST	(KERNEL_BREAKPOINT)
+#define	BKPT_SIZE	(INSN_SIZE)
+#define	BKPT_SET(inst)	(BKPT_INST)
+
+#define	BKPT_SKIP do {							\
+	kdb_frame->tf_pc += BKPT_SIZE; \
+} while (0)
+
+#define SOFTWARE_SSTEP	1
+
+#define	IS_BREAKPOINT_TRAP(type, code)	(type == T_BREAKPOINT)
+#define	IS_WATCHPOINT_TRAP(type, code)	(0)
+
+
+#define	inst_trap_return(ins)	(0)
+/* ldmxx reg, {..., pc}
+					    01800000  stack mode
+					    000f0000  register
+					    0000ffff  register list */
+/* mov pc, reg
+					    0000000f  register */
+#define	inst_return(ins)	(((ins) & 0x0e108000) == 0x08108000 || \
+				 ((ins) & 0x0ff0fff0) == 0x01a0f000 ||	\
+				 ((ins) & 0x0ffffff0) == 0x012fff10) /* bx */
+/* bl ...
+					    00ffffff  offset>>2 */
+#define	inst_call(ins)		(((ins) & 0x0f000000) == 0x0b000000)
+/* b ...
+					    00ffffff  offset>>2 */
+/* ldr pc, [pc, reg, lsl #2]
+					    0000000f  register */
+
+#define	inst_branch(ins)	(((ins) & 0x0f000000) == 0x0a000000 || \
+				 ((ins) & 0x0fdffff0) == 0x079ff100 || \
+				 ((ins) & 0x0cf0f000) == 0x0490f000 || \
+				 ((ins) & 0x0ffffff0) == 0x012fff30 || /* blx */ \
+				 ((ins) & 0x0de0f000) == 0x0080f000)
+
+#define	inst_load(ins)		(0)
+#define	inst_store(ins)		(0)
+
+#define next_instr_address(pc, bd)	((bd) ? (pc) : ((pc) + INSN_SIZE))
+
+#define	DB_SMALL_VALUE_MAX	(0x7fffffff)
+#define	DB_SMALL_VALUE_MIN	(-0x40001)
+
+#define	DB_ELFSIZE		32
+
+int db_validate_address(vm_offset_t);
+
+u_int branch_taken (u_int insn, u_int pc);
+
+#ifdef __ARMEB__
+#define BYTE_MSF	(1)
+#endif
+#endif /* !_MACHINE_DB_MACHDEP_H_ */


Property changes on: trunk/sys/arm/include/db_machdep.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/devmap.h
===================================================================
--- trunk/sys/arm/include/devmap.h	                        (rev 0)
+++ trunk/sys/arm/include/devmap.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,94 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Ian Lepore <ian at freebsd.org>
+ * 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: stable/10/sys/arm/include/devmap.h 266086 2014-05-14 20:17:31Z ian $
+ */
+
+#ifndef	_MACHINE_DEVMAP_H_
+#define	_MACHINE_DEVMAP_H_
+
+/*
+ * This structure is used by MD code to describe static mappings of devices
+ * which are established as part of bringing up the MMU early in the boot.
+ */
+struct arm_devmap_entry {
+	vm_offset_t	pd_va;		/* virtual address */
+	vm_paddr_t	pd_pa;		/* physical address */
+	vm_size_t	pd_size;	/* size of region */
+	vm_prot_t	pd_prot;	/* protection code */
+	int		pd_cache;	/* cache attributes */
+};
+
+/*
+ * Return the lowest KVA address used in any entry in the registered devmap
+ * table.  This works with whatever table is registered, including the internal
+ * table used by arm_devmap_add_entry() if that routine was used. Platforms can
+ * implement initarm_lastaddr() by calling this if static device mappings are
+ * their only use of high KVA space.
+ */
+vm_offset_t arm_devmap_lastaddr(void);
+
+/*
+ * Automatically allocate KVA (from the top of the address space downwards) and
+ * make static device mapping entries in an internal table.  The internal table
+ * is automatically registered on the first call to this.
+ */
+void arm_devmap_add_entry(vm_paddr_t pa, vm_size_t sz);
+
+/*
+ * Register a platform-local table to be bootstrapped by the generic
+ * initarm() in arm/machdep.c.  This is used by newer code that allocates and
+ * fills in its own local table but does not have its own initarm() routine.
+ */
+void arm_devmap_register_table(const struct arm_devmap_entry * _table);
+
+/*
+ * Establish mappings for all the entries in the table.  This is called
+ * automatically from the common initarm() in arm/machdep.c, and also from the
+ * custom initarm() routines in older code.  If the table pointer is NULL, this
+ * will use the table installed previously by arm_devmap_register_table().
+ */
+void arm_devmap_bootstrap(vm_offset_t _l1pt, 
+    const struct arm_devmap_entry *_table);
+
+/*
+ * Translate between virtual and physical addresses within a region that is
+ * static-mapped by the devmap code.  If the given address range isn't
+ * static-mapped, then ptov returns NULL and vtop returns DEVMAP_PADDR_NOTFOUND.
+ * The latter implies that you can't vtop just the last byte of physical address
+ * space.  This is not as limiting as it might sound, because even if a device
+ * occupies the end of the physical address space, you're only prevented from
+ * doing vtop for that single byte.  If you vtop a size bigger than 1 it works.
+ */
+#define	DEVMAP_PADDR_NOTFOUND	((vm_paddr_t)(-1))
+
+void *     arm_devmap_ptov(vm_paddr_t _pa, vm_size_t _sz);
+vm_paddr_t arm_devmap_vtop(void * _va, vm_size_t _sz);
+
+/* Print the static mapping table; used for bootverbose output. */
+void arm_devmap_print_table(void);
+
+#endif


Property changes on: trunk/sys/arm/include/devmap.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/disassem.h
===================================================================
--- trunk/sys/arm/include/disassem.h	                        (rev 0)
+++ trunk/sys/arm/include/disassem.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,55 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: disassem.h,v 1.4 2001/03/04 04:15:58 matt Exp $	*/
+
+/*-
+ * Copyright (c) 1997 Mark Brinicombe.
+ * Copyright (c) 1997 Causality Limited.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Mark Brinicombe.
+ * 4. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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.
+ *
+ * Define the interface structure required by the disassembler.
+ *
+ * $FreeBSD: stable/10/sys/arm/include/disassem.h 208052 2010-05-14 00:00:19Z cognet $
+ */
+
+#ifndef _MACHINE_DISASSEM_H_
+#define _MACHINE_DISASSEM_H_
+typedef struct {
+	u_int	(*di_readword)(u_int);
+	void	(*di_printaddr)(u_int);	
+	int	(*di_printf)(const char *, ...) __printflike(1, 2);
+} disasm_interface_t;
+
+/* Prototypes for callable functions */
+
+vm_offset_t disasm(const disasm_interface_t *, vm_offset_t, int);
+void disassemble(u_int);
+
+#endif /* !_MACHINE_DISASSEM_H_ */


Property changes on: trunk/sys/arm/include/disassem.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/elf.h
===================================================================
--- trunk/sys/arm/include/elf.h	                        (rev 0)
+++ trunk/sys/arm/include/elf.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,115 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2001 David E. O'Brien
+ * Copyright (c) 1996-1997 John D. Polstra.
+ * 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: stable/10/sys/arm/include/elf.h 269792 2014-08-10 22:26:29Z ian $
+ */
+
+#ifndef _MACHINE_ELF_H_
+#define	_MACHINE_ELF_H_ 1
+
+/*
+ * EABI ELF definitions for the StrongARM architecture.
+ * See "ARM ELF", document no. `SWS ESPC 0003 A-08' for details.
+ */
+
+#include <sys/elf32.h>	/* Definitions common to all 32 bit architectures. */
+
+#define	__ELF_WORD_SIZE	32	/* Used by <sys/elf_generic.h> */
+#include <sys/elf_generic.h>
+
+typedef struct {        /* Auxiliary vector entry on initial stack */
+	int     a_type;                 /* Entry type. */
+	union {
+		long    a_val;          /* Integer value. */
+		void    *a_ptr;         /* Address. */
+		void    (*a_fcn)(void); /* Function pointer (not used). */
+	} a_un;
+} Elf32_Auxinfo;
+
+__ElfType(Auxinfo);
+
+#define	ELF_ARCH	EM_ARM
+
+#define	ELF_MACHINE_OK(x) ((x) == EM_ARM)
+
+/* Unwind info section type */
+#define	PT_ARM_EXIDX (PT_LOPROC + 1)
+
+/*
+ * Relocation types.
+ */
+
+/* Values for a_type. */
+#define AT_NULL         0       /* Terminates the vector. */
+#define AT_IGNORE       1       /* Ignored entry. */
+#define AT_EXECFD       2       /* File descriptor of program to load. */
+#define AT_PHDR         3       /* Program header of program already loaded. */
+#define AT_PHENT        4       /* Size of each program header entry. */
+#define AT_PHNUM        5       /* Number of program header entries. */
+#define AT_PAGESZ       6       /* Page size in bytes. */
+#define AT_BASE         7       /* Interpreter's base address. */
+#define AT_FLAGS        8       /* Flags (unused). */
+#define AT_ENTRY        9       /* Where interpreter should transfer control. */
+#define AT_NOTELF       10      /* Program is not ELF ?? */
+#define AT_UID          11      /* Real uid. */
+#define AT_EUID         12      /* Effective uid. */
+#define AT_GID          13      /* Real gid. */
+#define AT_EGID         14      /* Effective gid. */
+#define	AT_EXECPATH	15	/* Path to the executable. */
+#define	AT_CANARY	16	/* Canary for SSP */
+#define	AT_CANARYLEN	17	/* Length of the canary. */
+#define	AT_OSRELDATE	18	/* OSRELDATE. */
+#define	AT_NCPUS	19	/* Number of CPUs. */
+#define	AT_PAGESIZES	20	/* Pagesizes. */
+#define	AT_PAGESIZESLEN	21	/* Number of pagesizes. */
+#define	AT_TIMEKEEP	22	/* Pointer to timehands. */
+#define	AT_STACKPROT	23	/* Initial stack protection. */
+
+#define AT_COUNT        24      /* Count of defined aux entry types. */
+
+#define	R_ARM_COUNT		33	/* Count of defined relocation types. */
+
+
+/* Define "machine" characteristics */
+#define	ELF_TARG_CLASS	ELFCLASS32
+#ifdef __ARMEB__
+#define	ELF_TARG_DATA	ELFDATA2MSB
+#else
+#define	ELF_TARG_DATA	ELFDATA2LSB
+#endif
+#define	ELF_TARG_MACH	EM_ARM
+#define	ELF_TARG_VER	1
+
+/*
+ * Magic number for the elf trampoline, chosen wisely to be an immediate
+ * value.
+ */
+#define MAGIC_TRAMP_NUMBER	0x5c000003
+
+#define	ET_DYN_LOAD_ADDR 0x12000
+
+#endif /* !_MACHINE_ELF_H_ */


Property changes on: trunk/sys/arm/include/elf.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/endian.h
===================================================================
--- trunk/sys/arm/include/endian.h	                        (rev 0)
+++ trunk/sys/arm/include/endian.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,141 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2001 David E. O'Brien
+ *
+ * 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ *	@(#)endian.h	8.1 (Berkeley) 6/10/93
+ * $NetBSD: endian.h,v 1.7 1999/08/21 05:53:51 simonb Exp $
+ * $FreeBSD: stable/10/sys/arm/include/endian.h 236992 2012-06-13 05:02:51Z imp $
+ */
+
+#ifndef _ENDIAN_H_
+#define	_ENDIAN_H_
+
+#include <sys/_types.h>
+
+/*
+ * Definitions for byte order, according to byte significance from low
+ * address to high.
+ */
+#define _LITTLE_ENDIAN  1234    /* LSB first: i386, vax */
+#define _BIG_ENDIAN     4321    /* MSB first: 68000, ibm, net */
+#define _PDP_ENDIAN     3412    /* LSB first in word, MSW first in long */
+
+#ifdef __ARMEB__
+#define _BYTE_ORDER	_BIG_ENDIAN
+#else
+#define	_BYTE_ORDER	_LITTLE_ENDIAN
+#endif /* __ARMEB__ */
+
+#if __BSD_VISIBLE
+#define LITTLE_ENDIAN   _LITTLE_ENDIAN
+#define BIG_ENDIAN      _BIG_ENDIAN
+#define PDP_ENDIAN      _PDP_ENDIAN
+#define BYTE_ORDER      _BYTE_ORDER
+#endif
+
+#ifdef __ARMEB__
+#define _QUAD_HIGHWORD 0
+#define _QUAD_LOWWORD 1
+#define __ntohl(x)	((__uint32_t)(x))
+#define __ntohs(x)	((__uint16_t)(x))
+#define __htonl(x)	((__uint32_t)(x))
+#define __htons(x)	((__uint16_t)(x))
+#else
+#define _QUAD_HIGHWORD  1
+#define _QUAD_LOWWORD 0
+#define __ntohl(x)        (__bswap32(x))
+#define __ntohs(x)        (__bswap16(x))
+#define __htonl(x)        (__bswap32(x))
+#define __htons(x)        (__bswap16(x))
+#endif /* __ARMEB__ */
+
+static __inline __uint64_t
+__bswap64(__uint64_t _x)
+{
+
+	return ((_x >> 56) | ((_x >> 40) & 0xff00) | ((_x >> 24) & 0xff0000) |
+	    ((_x >> 8) & 0xff000000) | ((_x << 8) & ((__uint64_t)0xff << 32)) |
+	    ((_x << 24) & ((__uint64_t)0xff << 40)) |
+	    ((_x << 40) & ((__uint64_t)0xff << 48)) | ((_x << 56)));
+}
+
+static __inline __uint32_t
+__bswap32_var(__uint32_t v)
+{
+	__uint32_t t1;
+
+	__asm __volatile("eor %1, %0, %0, ror #16\n"
+	    		"bic %1, %1, #0x00ff0000\n"
+			"mov %0, %0, ror #8\n"
+			"eor %0, %0, %1, lsr #8\n"
+			 : "+r" (v), "=r" (t1));
+	
+	return (v);
+}
+
+static __inline __uint16_t
+__bswap16_var(__uint16_t v)
+{
+	__uint32_t ret = v & 0xffff;
+
+	__asm __volatile(
+	    "mov    %0, %0, ror #8\n"
+	    "orr    %0, %0, %0, lsr #16\n"
+	    "bic    %0, %0, %0, lsl #16"
+	    : "+r" (ret));
+	
+	return ((__uint16_t)ret);
+}		
+
+#ifdef __OPTIMIZE__
+
+#define __bswap32_constant(x)	\
+    ((((x) & 0xff000000U) >> 24) |	\
+     (((x) & 0x00ff0000U) >>  8) |	\
+     (((x) & 0x0000ff00U) <<  8) |	\
+     (((x) & 0x000000ffU) << 24))
+
+#define __bswap16_constant(x)	\
+    ((((x) & 0xff00) >> 8) |		\
+     (((x) & 0x00ff) << 8))
+
+#define __bswap16(x)	\
+    ((__uint16_t)(__builtin_constant_p(x) ?	\
+     __bswap16_constant(x) :			\
+     __bswap16_var(x)))
+
+#define __bswap32(x)	\
+    ((__uint32_t)(__builtin_constant_p(x) ? 	\
+     __bswap32_constant(x) :			\
+     __bswap32_var(x)))
+
+#else
+#define __bswap16(x)	__bswap16_var(x)
+#define __bswap32(x)	__bswap32_var(x)
+
+#endif /* __OPTIMIZE__ */
+#endif /* !_ENDIAN_H_ */


Property changes on: trunk/sys/arm/include/endian.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/exec.h
===================================================================
--- trunk/sys/arm/include/exec.h	                        (rev 0)
+++ trunk/sys/arm/include/exec.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,38 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2001 David E. O'Brien
+ * 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.
+ * 3. Neither the name of the author nor the names of any co-contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL 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 REGENTS 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: stable/10/sys/arm/include/exec.h 142107 2005-02-19 21:16:48Z ru $
+ */
+
+#ifndef	_MACHINE_EXEC_H_
+#define	_MACHINE_EXEC_H_
+
+#define	__LDPGSZ	4096
+
+#endif /* !_MACHINE_EXEC_H_ */


Property changes on: trunk/sys/arm/include/exec.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/fdt.h
===================================================================
--- trunk/sys/arm/include/fdt.h	                        (rev 0)
+++ trunk/sys/arm/include/fdt.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,59 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2010 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Semihalf under sponsorship from
+ * the FreeBSD Foundation.
+ *
+ * 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: stable/10/sys/arm/include/fdt.h 266084 2014-05-14 19:18:58Z ian $
+ */
+
+#ifndef _MACHINE_FDT_H_
+#define _MACHINE_FDT_H_
+
+#include <dev/ofw/openfirm.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <machine/bus.h>
+#include <machine/intr.h>
+
+/* Max interrupt number */
+#define FDT_INTR_MAX	NIRQ
+
+/* Map phandle/intpin pair to global IRQ number */
+#define	FDT_MAP_IRQ(node, pin)	(pin)
+
+/*
+ * Bus space tag. XXX endianess info needs to be derived from the blob.
+ */
+extern bus_space_tag_t fdtbus_bs_tag;
+
+struct arm_devmap_entry;
+
+int fdt_localbus_devmap(phandle_t, struct arm_devmap_entry *, int, int *);
+
+#endif /* _MACHINE_FDT_H_ */


Property changes on: trunk/sys/arm/include/fdt.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/fiq.h
===================================================================
--- trunk/sys/arm/include/fiq.h	                        (rev 0)
+++ trunk/sys/arm/include/fiq.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,72 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: fiq.h,v 1.1 2001/12/20 01:20:23 thorpej Exp $	*/
+
+/*-
+ * Copyright (c) 2001 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Jason R. Thorpe for Wasabi Systems, Inc.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed for the NetBSD Project by
+ *	Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
+ * 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: stable/10/sys/arm/include/fiq.h 139735 2005-01-05 21:58:49Z imp $
+ *
+ */
+
+#ifndef _MACHINE_FIQ_H_
+#define	_MACHINE_FIQ_H_
+
+#include <sys/queue.h>
+
+struct fiqregs {
+	u_int	fr_r8;			/* FIQ mode r8 */
+	u_int	fr_r9;			/* FIQ mode r9 */
+	u_int	fr_r10;			/* FIQ mode r10 */
+	u_int	fr_r11;			/* FIQ mode r11 */
+	u_int	fr_r12;			/* FIQ mode r12 */
+	u_int	fr_r13;			/* FIQ mode r13 */
+};
+
+struct fiqhandler {
+	TAILQ_ENTRY(fiqhandler) fh_list;/* link in the FIQ handler stack */
+	void	*fh_func;		/* FIQ handler routine */
+	size_t	fh_size;		/* size of FIQ handler */
+	int	fh_flags;		/* flags; see below */
+	struct fiqregs *fh_regs;	/* pointer to regs structure */
+};
+
+#define	FH_CANPUSH	0x01	/* can push this handler out of the way */
+
+int	fiq_claim(struct fiqhandler *);
+void	fiq_release(struct fiqhandler *);
+
+void	fiq_getregs(struct fiqregs *);
+void	fiq_setregs(struct fiqregs *);
+
+#endif /* _MACHINE_FIQ_H_ */


Property changes on: trunk/sys/arm/include/fiq.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/float.h
===================================================================
--- trunk/sys/arm/include/float.h	                        (rev 0)
+++ trunk/sys/arm/include/float.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,103 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1989 Regents of the University of California.
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ *	from: @(#)float.h	7.1 (Berkeley) 5/8/90
+ * $FreeBSD: stable/10/sys/arm/include/float.h 230475 2012-01-23 06:36:41Z das $
+ */
+
+#ifndef _MACHINE_FLOAT_H_
+#define _MACHINE_FLOAT_H_ 1
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+extern int __flt_rounds(void);
+__END_DECLS
+
+#define FLT_RADIX	2		/* b */
+#ifndef	_ARM_HARD_FLOAT
+#define	FLT_ROUNDS	__flt_rounds()
+#else
+#define	FLT_ROUNDS	(-1)
+#endif
+#if __ISO_C_VISIBLE >= 1999
+#define	FLT_EVAL_METHOD	0
+#define	DECIMAL_DIG	17		/* max precision in decimal digits */
+#endif
+
+#define FLT_MANT_DIG	24		/* p */
+#define FLT_EPSILON	1.19209290E-07F	/* b**(1-p) */
+#define FLT_DIG		6		/* floor((p-1)*log10(b))+(b == 10) */
+#define FLT_MIN_EXP	(-125)		/* emin */
+#define FLT_MIN		1.17549435E-38F	/* b**(emin-1) */
+#define FLT_MIN_10_EXP	(-37)		/* ceil(log10(b**(emin-1))) */
+#define FLT_MAX_EXP	128		/* emax */
+#define FLT_MAX		3.40282347E+38F	/* (1-b**(-p))*b**emax */
+#define FLT_MAX_10_EXP	38		/* floor(log10((1-b**(-p))*b**emax)) */
+#if __ISO_C_VISIBLE >= 2011
+#define	FLT_TRUE_MIN	1.40129846E-45F	/* b**(emin-p) */
+#define	FLT_DECIMAL_DIG	9		/* ceil(1+p*log10(b)) */
+#define	FLT_HAS_SUBNORM	1
+#endif /* __ISO_C_VISIBLE >= 2011 */
+
+#define DBL_MANT_DIG	53
+#define DBL_EPSILON	2.2204460492503131E-16
+#define DBL_DIG		15
+#define DBL_MIN_EXP	(-1021)
+#define DBL_MIN		2.2250738585072014E-308
+#define DBL_MIN_10_EXP	(-307)
+#define DBL_MAX_EXP	1024
+#define DBL_MAX		1.7976931348623157E+308
+#define DBL_MAX_10_EXP	308
+#if __ISO_C_VISIBLE >= 2011
+#define	DBL_TRUE_MIN	4.9406564584124654E-324
+#define	DBL_DECIMAL_DIG	17
+#define	DBL_HAS_SUBNORM	1
+#endif /* __ISO_C_VISIBLE >= 2011 */
+
+#define LDBL_MANT_DIG	DBL_MANT_DIG
+#define LDBL_EPSILON	((long double)DBL_EPSILON)
+#define LDBL_DIG	DBL_DIG
+#define LDBL_MIN_EXP	DBL_MIN_EXP
+#define LDBL_MIN	((long double)DBL_MIN)
+#define LDBL_MIN_10_EXP	DBL_MIN_10_EXP
+#define LDBL_MAX_EXP	DBL_MAX_EXP
+#define LDBL_MAX	((long double)DBL_MAX)
+#define LDBL_MAX_10_EXP	DBL_MAX_10_EXP
+#if __ISO_C_VISIBLE >= 2011
+#define	LDBL_TRUE_MIN	((long double)DBL_TRUE_MIN)
+#define	LDBL_DECIMAL_DIG DBL_DECIMAL_DIG
+#define	LDBL_HAS_SUBNORM DBL_HAS_SUBNORM
+#endif /* __ISO_C_VISIBLE >= 2011 */
+
+#endif /* _MACHINE_FLOAT_H_ */


Property changes on: trunk/sys/arm/include/float.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/floatingpoint.h
===================================================================
--- trunk/sys/arm/include/floatingpoint.h	                        (rev 0)
+++ trunk/sys/arm/include/floatingpoint.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,43 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1993 Andrew Moore, Talke Studio
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ *	from: @(#) floatingpoint.h	1.0 (Berkeley) 9/23/93
+ * $FreeBSD: stable/10/sys/arm/include/floatingpoint.h 129198 2004-05-14 11:46:45Z cognet $
+ */
+
+#ifndef _FLOATINGPOINT_H_
+#define _FLOATINGPOINT_H_
+
+#include <machine/ieeefp.h>
+
+#endif /* !_FLOATINGPOINT_H_ */


Property changes on: trunk/sys/arm/include/floatingpoint.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/fp.h
===================================================================
--- trunk/sys/arm/include/fp.h	                        (rev 0)
+++ trunk/sys/arm/include/fp.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,90 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: fp.h,v 1.1 2001/01/10 19:02:06 bjh21 Exp $	*/
+
+/*-
+ * Copyright (c) 1995 Mark Brinicombe.
+ * Copyright (c) 1995 Brini.
+ * All rights reserved.
+ *
+ * This code is derived from software written for Brini by Mark Brinicombe
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Brini.
+ * 4. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BRINI ``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 BRINI 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.
+ *
+ * RiscBSD kernel project
+ *
+ * fp.h
+ *
+ * FP info
+ *
+ * Created      : 10/10/95
+ *
+ * $FreeBSD: stable/10/sys/arm/include/fp.h 266341 2014-05-17 19:37:04Z ian $
+ */
+
+#ifndef _MACHINE_FP_H
+#define _MACHINE_FP_H
+
+/*
+ * An extended precision floating point number
+ */
+
+typedef struct fp_extended_precision {
+	u_int32_t fp_exponent;
+	u_int32_t fp_mantissa_hi;
+	u_int32_t fp_mantissa_lo;
+} fp_extended_precision_t;
+
+typedef struct fp_extended_precision fp_reg_t;
+
+/*
+ * Information about the FPE-SP state that is stored in the pcb
+ *
+ * This needs to move and be hidden from userland.
+ */
+
+struct vfp_state {
+	u_int64_t reg[32];
+	u_int32_t fpscr;
+	u_int32_t fpexec;
+	u_int32_t fpinst;
+	u_int32_t fpinst2;
+};
+
+/*
+ * Type for a saved FP context, if we want to translate the context to a
+ * user-readable form
+ */
+
+typedef struct {
+	u_int32_t fpsr;
+	fp_extended_precision_t regs[8];
+} fp_state_t;
+
+#endif /* _MACHINE_FP_H_ */
+
+/* End of fp.h */


Property changes on: trunk/sys/arm/include/fp.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/frame.h
===================================================================
--- trunk/sys/arm/include/frame.h	                        (rev 0)
+++ trunk/sys/arm/include/frame.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,136 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: frame.h,v 1.5 2002/10/19 00:10:54 bjh21 Exp $	*/
+
+/*-
+ * Copyright (c) 1994-1997 Mark Brinicombe.
+ * Copyright (c) 1994 Brini.
+ * All rights reserved.
+ *
+ * This code is derived from software written for Brini by Mark Brinicombe
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Brini.
+ * 4. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BRINI ``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 BRINI 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.
+ *
+ * RiscBSD kernel project
+ *
+ * frame.h
+ *
+ * Stack frames structures
+ *
+ * Created      : 30/09/94
+ *
+ * $FreeBSD: stable/10/sys/arm/include/frame.h 278614 2015-02-12 04:15:55Z ian $
+ *
+ */
+
+#ifndef _MACHINE_FRAME_H_
+#define _MACHINE_FRAME_H_
+
+#ifndef _LOCORE
+
+#include <sys/signal.h>
+#include <sys/ucontext.h>
+
+
+/*
+ * Trap frame.  Pushed onto the kernel stack on a trap (synchronous exception).
+ */
+
+struct trapframe {
+	register_t tf_spsr; /* Zero on arm26 */
+	register_t tf_r0;
+	register_t tf_r1;
+	register_t tf_r2;
+	register_t tf_r3;
+	register_t tf_r4;
+	register_t tf_r5;
+	register_t tf_r6;
+	register_t tf_r7;
+	register_t tf_r8;
+	register_t tf_r9;
+	register_t tf_r10;
+	register_t tf_r11;
+	register_t tf_r12;
+	register_t tf_usr_sp;
+	register_t tf_usr_lr;
+	register_t tf_svc_sp; /* Not used on arm26 */
+	register_t tf_svc_lr; /* Not used on arm26 */
+	register_t tf_pc;
+	register_t tf_pad;
+};
+
+/* Register numbers */
+#define tf_r13 tf_usr_sp
+#define tf_r14 tf_usr_lr
+#define tf_r15 tf_pc
+
+/*
+ * Signal frame.  Pushed onto user stack before calling sigcode.
+ * The pointers are used in the trampoline code to locate the ucontext.
+ */
+struct sigframe {
+	siginfo_t       sf_si;          /* actual saved siginfo */
+	ucontext_t      sf_uc;          /* actual saved ucontext */
+};
+
+
+/*
+ * Switch frame.
+ *
+ * It is important this is a multiple of 8 bytes so the stack is correctly
+ * aligned when we create new threads.
+ */
+struct switchframe
+{
+        register_t sf_r4;
+        register_t sf_r5;
+        register_t sf_r6;
+        register_t sf_r7;
+        register_t sf_r8;
+        register_t sf_r9;
+        register_t sf_r10;
+        register_t sf_r11;
+        register_t sf_r12;
+        register_t sf_sp;
+        register_t sf_lr;
+        register_t sf_pc;
+};
+
+
+/*
+ * Stack frame. Used during stack traces (db_trace.c)
+ */
+struct frame {
+	u_int	fr_fp;
+	u_int	fr_sp;
+	u_int	fr_lr;
+	u_int	fr_pc;
+};
+
+#endif /* !_LOCORE */
+
+#endif /* _MACHINE_FRAME_H_ */


Property changes on: trunk/sys/arm/include/frame.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/gdb_machdep.h
===================================================================
--- trunk/sys/arm/include/gdb_machdep.h	                        (rev 0)
+++ trunk/sys/arm/include/gdb_machdep.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,53 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2006 Olivier Houchard
+ * 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 ``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 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: stable/10/sys/arm/include/gdb_machdep.h 160332 2006-07-14 00:50:51Z cognet $
+ */
+
+#ifndef _MACHINE_GDB_MACHDEP_H_
+#define	_MACHINE_GDB_MACHDEP_H_
+
+#define	GDB_BUFSZ	400
+#define	GDB_NREGS	26
+#define	GDB_REG_PC	15
+
+static __inline size_t
+gdb_cpu_regsz(int regnum __unused)
+{
+	return (sizeof(int));
+}
+
+static __inline int
+gdb_cpu_query(void)
+{
+	return (0);
+}
+
+void *gdb_cpu_getreg(int, size_t *);
+void gdb_cpu_setreg(int, void *);
+int gdb_cpu_signal(int, int);
+
+#endif /* !_MACHINE_GDB_MACHDEP_H_ */


Property changes on: trunk/sys/arm/include/gdb_machdep.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/ieee.h
===================================================================
--- trunk/sys/arm/include/ieee.h	                        (rev 0)
+++ trunk/sys/arm/include/ieee.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,166 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: ieee754.h,v 1.4 2003/10/27 02:30:26 simonb Exp $	*/
+
+/*-
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Lawrence Berkeley Laboratory.
+ *
+ * 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ *	@(#)ieee.h	8.1 (Berkeley) 6/11/93
+ *
+ * $FreeBSD: stable/10/sys/arm/include/ieee.h 255361 2013-09-07 14:04:10Z andrew $
+ *
+ */
+
+/*
+ * NOTICE: This is not a standalone file.  To use it, #include it in
+ * your port's ieee.h header.
+ */
+
+#include <machine/endian.h>
+
+/*
+ * <sys/ieee754.h> defines the layout of IEEE 754 floating point types.
+ * Only single-precision and double-precision types are defined here;
+ * extended types, if available, are defined in the machine-dependent
+ * header.
+ */
+
+/*
+ * Define the number of bits in each fraction and exponent.
+ *
+ *		     k	         k+1
+ * Note that  1.0 x 2  == 0.1 x 2      and that denorms are represented
+ *
+ *					  (-exp_bias+1)
+ * as fractions that look like 0.fffff x 2             .  This means that
+ *
+ *			 -126
+ * the number 0.10000 x 2    , for instance, is the same as the normalized
+ *
+ *		-127			   -128
+ * float 1.0 x 2    .  Thus, to represent 2    , we need one leading zero
+ *
+ *				  -129
+ * in the fraction; to represent 2    , we need two, and so on.  This
+ *
+ *						     (-exp_bias-fracbits+1)
+ * implies that the smallest denormalized number is 2
+ *
+ * for whichever format we are talking about: for single precision, for
+ *
+ *						-126		-149
+ * instance, we get .00000000000000000000001 x 2    , or 1.0 x 2    , and
+ *
+ * -149 == -127 - 23 + 1.
+ */
+#define	SNG_EXPBITS	8
+#define	SNG_FRACBITS	23
+
+#define	DBL_EXPBITS	11
+#define	DBL_FRACBITS	52
+
+#if defined(__VFP_FP__) || defined(__ARM_EABI__)
+#define	_IEEE_WORD_ORDER	_BYTE_ORDER
+#else
+#define	_IEEE_WORD_ORDER	_BIG_ENDIAN
+#endif
+
+struct ieee_single {
+#if _BYTE_ORDER == _BIG_ENDIAN
+	u_int	sng_sign:1;
+	u_int	sng_exp:8;
+	u_int	sng_frac:23;
+#else
+	u_int	sng_frac:23;
+	u_int	sng_exp:8;
+	u_int	sng_sign:1;
+#endif
+};
+
+struct ieee_double {
+#if _BYTE_ORDER == _BIG_ENDIAN
+	u_int	dbl_sign:1;
+	u_int	dbl_exp:11;
+	u_int	dbl_frach:20;
+	u_int	dbl_fracl;
+#else
+#if _IEEE_WORD_ORDER == _LITTLE_ENDIAN
+	u_int	dbl_fracl;
+#endif
+	u_int	dbl_frach:20;
+	u_int	dbl_exp:11;
+	u_int	dbl_sign:1;
+#if _IEEE_WORD_ORDER == _BIG_ENDIAN
+	u_int   dbl_fracl;
+#endif
+#endif
+};
+
+/*
+ * Floats whose exponent is in [1..INFNAN) (of whatever type) are
+ * `normal'.  Floats whose exponent is INFNAN are either Inf or NaN.
+ * Floats whose exponent is zero are either zero (iff all fraction
+ * bits are zero) or subnormal values.
+ *
+ * A NaN is a `signalling NaN' if its QUIETNAN bit is clear in its
+ * high fraction; if the bit is set, it is a `quiet NaN'.
+ */
+#define	SNG_EXP_INFNAN	255
+#define	DBL_EXP_INFNAN	2047
+
+#if 0
+#define	SNG_QUIETNAN	(1 << 22)
+#define	DBL_QUIETNAN	(1 << 19)
+#endif
+
+/*
+ * Exponent biases.
+ */
+#define	SNG_EXP_BIAS	127
+#define	DBL_EXP_BIAS	1023
+
+/*
+ * Convenience data structures.
+ */
+union ieee_single_u {
+	float			sngu_f;
+	struct ieee_single	sngu_sng;
+};
+
+union ieee_double_u {
+	double			dblu_d;
+	struct ieee_double	dblu_dbl;
+};


Property changes on: trunk/sys/arm/include/ieee.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/ieeefp.h
===================================================================
--- trunk/sys/arm/include/ieeefp.h	                        (rev 0)
+++ trunk/sys/arm/include/ieeefp.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,54 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: ieeefp.h,v 1.1 2001/01/10 19:02:06 bjh21 Exp $	*/
+/* $FreeBSD: stable/10/sys/arm/include/ieeefp.h 226607 2011-10-21 06:41:46Z das $ */
+/*-
+ * Based on ieeefp.h written by J.T. Conklin, Apr 28, 1995
+ * Public domain.
+ */
+
+#ifndef _MACHINE_IEEEFP_H_
+#define _MACHINE_IEEEFP_H_
+
+/* Deprecated historical FPU control interface */
+
+/* FP exception codes */
+#define FP_EXCEPT_INV	0
+#define FP_EXCEPT_DZ	1
+#define FP_EXCEPT_OFL	2
+#define FP_EXCEPT_UFL	3
+#define FP_EXCEPT_IMP	4
+
+/* Exception type (used by fpsetmask() et al.) */
+
+typedef int fp_except;
+
+/* Bit defines for fp_except */
+
+#define	FP_X_INV	(1 << FP_EXCEPT_INV)	/* invalid operation exception */
+#define	FP_X_DZ		(1 << FP_EXCEPT_DZ)	/* divide-by-zero exception */
+#define	FP_X_OFL	(1 << FP_EXCEPT_OFL)	/* overflow exception */
+#define	FP_X_UFL	(1 << FP_EXCEPT_UFL)	/* underflow exception */
+#define	FP_X_IMP	(1 << FP_EXCEPT_IMP)	/* imprecise (loss of precision; "inexact") */
+
+/* Rounding modes */
+
+typedef enum {
+    FP_RN=0,			/* round to nearest representable number */
+    FP_RP=1,			/* round toward positive infinity */
+    FP_RM=2,			/* round toward negative infinity */
+    FP_RZ=3			/* round to zero (truncate) */
+} fp_rnd_t;
+
+/*
+ * FP precision modes
+ */
+typedef enum {
+	FP_PS=0,	/* 24 bit (single-precision) */
+	FP_PRS,		/* reserved */
+	FP_PD,		/* 53 bit (double-precision) */
+	FP_PE		/* 64 bit (extended-precision) */
+} fp_prec_t;
+
+#define fp_except_t	int
+
+#endif /* _MACHINE_IEEEFP_H_ */


Property changes on: trunk/sys/arm/include/ieeefp.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/in_cksum.h
===================================================================
--- trunk/sys/arm/include/in_cksum.h	                        (rev 0)
+++ trunk/sys/arm/include/in_cksum.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,69 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ *	from tahoe:	in_cksum.c	1.2	86/01/05
+ *	from:		@(#)in_cksum.c	1.3 (Berkeley) 1/19/91
+ *	from: Id: in_cksum.c,v 1.8 1995/12/03 18:35:19 bde Exp
+ * $FreeBSD: stable/10/sys/arm/include/in_cksum.h 236992 2012-06-13 05:02:51Z imp $
+ */
+
+#ifndef _MACHINE_IN_CKSUM_H_
+#define	_MACHINE_IN_CKSUM_H_	1
+
+#include <sys/cdefs.h>
+
+#ifdef _KERNEL
+u_short in_cksum(struct mbuf *m, int len);
+u_short in_addword(u_short sum, u_short b);
+u_short in_cksum_skip(struct mbuf *m, int len, int skip);
+u_int do_cksum(const void *, int);
+#if defined(IPVERSION) && (IPVERSION == 4)
+u_int in_cksum_hdr(const struct ip *);
+#endif
+
+static __inline u_short
+in_pseudo(u_int sum, u_int b, u_int c)
+{
+	__asm __volatile("adds %0, %0, %1\n"
+	    		"adcs %0, %0, %2\n"
+			"adc %0, %0, #0\n"
+			: "+r" (sum)
+			: "r" (b), "r" (c));
+	sum = (sum & 0xffff) + (sum >> 16);
+	if (sum > 0xffff)
+		sum -= 0xffff;
+	return (sum);
+}
+
+#endif /* _KERNEL */
+#endif /* _MACHINE_IN_CKSUM_H_ */


Property changes on: trunk/sys/arm/include/in_cksum.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/intr.h
===================================================================
--- trunk/sys/arm/include/intr.h	                        (rev 0)
+++ trunk/sys/arm/include/intr.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,89 @@
+/* $MidnightBSD$ */
+/* 	$NetBSD: intr.h,v 1.7 2003/06/16 20:01:00 thorpej Exp $	*/
+
+/*-
+ * Copyright (c) 1997 Mark Brinicombe.
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Mark Brinicombe
+ *	for the NetBSD Project.
+ * 4. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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: stable/10/sys/arm/include/intr.h 273672 2014-10-26 03:52:45Z ian $
+ *
+ */
+
+#ifndef _MACHINE_INTR_H_
+#define _MACHINE_INTR_H_
+
+/* XXX move to std.* files? */
+#ifdef CPU_XSCALE_81342
+#define NIRQ		128
+#elif defined(CPU_XSCALE_PXA2X0)
+#include <arm/xscale/pxa/pxareg.h>
+#define	NIRQ		IRQ_GPIO_MAX
+#elif defined(SOC_MV_DISCOVERY)
+#define NIRQ		96
+#elif defined(CPU_ARM9) || defined(SOC_MV_KIRKWOOD) || \
+    defined(CPU_XSCALE_IXP435)
+#define NIRQ		64
+#elif defined(CPU_CORTEXA)
+#define NIRQ		160
+#elif defined(CPU_KRAIT)
+#define NIRQ		288
+#elif defined(CPU_ARM1136) || defined(CPU_ARM1176)
+#define NIRQ		128
+#elif defined(SOC_MV_ARMADAXP)
+#define MAIN_IRQ_NUM		116
+#define ERR_IRQ_NUM		32
+#define ERR_IRQ			(MAIN_IRQ_NUM)
+#define MSI_IRQ_NUM		32
+#define MSI_IRQ			(ERR_IRQ + ERR_IRQ_NUM)
+#define NIRQ			(MAIN_IRQ_NUM + ERR_IRQ_NUM + MSI_IRQ_NUM)
+#else
+#define NIRQ		32
+#endif
+
+
+int arm_get_next_irq(int);
+void arm_mask_irq(uintptr_t);
+void arm_unmask_irq(uintptr_t);
+void arm_intrnames_init(void);
+void arm_setup_irqhandler(const char *, int (*)(void*), void (*)(void*),
+    void *, int, int, void **);
+int arm_remove_irqhandler(int, void *);
+extern void (*arm_post_filter)(void *);
+extern int (*arm_config_irq)(int irq, enum intr_trigger trig,
+    enum intr_polarity pol);
+
+void arm_irq_memory_barrier(uintptr_t);
+
+void gic_init_secondary(void);
+int  gic_decode_fdt(uint32_t iparentnode, uint32_t *intrcells, int *interrupt,
+    int *trig, int *pol);
+
+#endif	/* _MACHINE_INTR_H */


Property changes on: trunk/sys/arm/include/intr.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/katelib.h
===================================================================
--- trunk/sys/arm/include/katelib.h	                        (rev 0)
+++ trunk/sys/arm/include/katelib.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,104 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: katelib.h,v 1.3 2001/11/23 19:21:48 thorpej Exp $	*/
+
+/*-
+ * Copyright (c) 1994-1996 Mark Brinicombe.
+ * Copyright (c) 1994 Brini.
+ * All rights reserved.
+ *
+ * This code is derived from software written for Brini by Mark Brinicombe
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Brini.
+ * 4. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BRINI ``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 BRINI 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.
+ *
+ * RiscBSD kernel project
+ *
+ * katelib.h
+ *
+ * Prototypes for machine specific functions. Most of these
+ * could be inlined.
+ *
+ * This should not really be a separate header file. Eventually I will merge
+ * this into other header files once I have decided where the declarations
+ * should go.
+ *
+ * Created      : 18/09/94
+ *
+ * Based on kate/katelib/prototypes.h
+ *
+ * $FreeBSD: stable/10/sys/arm/include/katelib.h 236992 2012-06-13 05:02:51Z imp $
+ */
+
+/*
+ * USE OF THIS FILE IS DEPRECATED
+ */
+
+#ifndef _MACHINE_KATELIB_H_
+#define _MACHINE_KATELIB_H_
+#include <sys/types.h>
+#include <machine/cpufunc.h>
+
+#ifdef _KERNEL
+
+/* Assembly modules */
+
+/* In blockio.S */
+#include <machine/blockio.h>
+
+/* Macros for reading and writing words, shorts, bytes */
+
+#define WriteWord(a, b) \
+*((volatile unsigned int *)(a)) = (b)
+
+#define ReadWord(a) \
+(*((volatile unsigned int *)(a)))
+
+#define WriteShort(a, b) \
+*((volatile unsigned int *)(a)) = ((b) | ((b) << 16))
+
+#define ReadShort(a) \
+((*((volatile unsigned int *)(a))) & 0xffff)
+
+#define WriteByte(a, b) \
+*((volatile unsigned char *)(a)) = (b)
+
+#define ReadByte(a) \
+(*((volatile unsigned char *)(a)))
+
+/* Define in/out macros */
+
+#define inb(port)		ReadByte((port))
+#define outb(port, byte)	WriteByte((port), (byte))
+#define inw(port)		ReadShort((port))
+#define outw(port, word)	WriteShort((port), (word))
+#define inl(port)		ReadWord((port))
+#define outl(port, lword)	WriteWord((port), (lword))
+
+#endif
+
+#endif /* !_MACHINE_KATELIB_H_ */
+/* End of katelib.h */


Property changes on: trunk/sys/arm/include/katelib.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/kdb.h
===================================================================
--- trunk/sys/arm/include/kdb.h	                        (rev 0)
+++ trunk/sys/arm/include/kdb.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,61 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2004 Marcel Moolenaar
+ * 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 ``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 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: stable/10/sys/arm/include/kdb.h 266373 2014-05-17 22:50:16Z ian $
+ */
+
+#ifndef _MACHINE_KDB_H_
+#define _MACHINE_KDB_H_
+
+#include <machine/frame.h>
+#include <machine/psl.h>
+#include <machine/cpufunc.h>
+
+#define	KDB_STOPPEDPCB(pc)	&stoppcbs[pc->pc_cpuid]
+
+static __inline void
+kdb_cpu_clear_singlestep(void)
+{
+}
+
+static __inline void
+kdb_cpu_set_singlestep(void)
+{
+}
+
+static __inline void
+kdb_cpu_sync_icache(unsigned char *addr, size_t size)
+{
+
+	cpu_icache_sync_range((vm_offset_t)addr, size);
+}
+
+static __inline void
+kdb_cpu_trap(int type, int code)
+{
+}
+
+#endif /* _MACHINE_KDB_H_ */


Property changes on: trunk/sys/arm/include/kdb.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/limits.h
===================================================================
--- trunk/sys/arm/include/limits.h	                        (rev 0)
+++ trunk/sys/arm/include/limits.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,45 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1988, 1993
+ *	The Regents of the University of California.  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.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ *	@(#)limits.h	8.3 (Berkeley) 1/4/94
+ * $FreeBSD: stable/10/sys/arm/include/limits.h 143063 2005-03-02 21:33:29Z joerg $
+ */
+
+#ifndef _MACHINE_LIMITS_H_
+#define	_MACHINE_LIMITS_H_
+
+#include <sys/cdefs.h>
+
+#ifdef __CC_SUPPORTS_WARNING
+#warning "machine/limits.h is deprecated.  Include sys/limits.h instead."
+#endif
+
+#include <sys/limits.h>
+
+#endif /* !_MACHINE_LIMITS_H_ */


Property changes on: trunk/sys/arm/include/limits.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/machdep.h
===================================================================
--- trunk/sys/arm/include/machdep.h	                        (rev 0)
+++ trunk/sys/arm/include/machdep.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,75 @@
+/* $MidnightBSD$ */
+/* $NetBSD: machdep.h,v 1.7 2002/02/21 02:52:21 thorpej Exp $ */
+/* $FreeBSD: stable/10/sys/arm/include/machdep.h 278630 2015-02-12 19:35:46Z ian $ */
+
+#ifndef _MACHDEP_BOOT_MACHDEP_H_
+#define _MACHDEP_BOOT_MACHDEP_H_
+
+/* Structs that need to be initialised by initarm */
+struct pv_addr;
+extern struct pv_addr irqstack;
+extern struct pv_addr undstack;
+extern struct pv_addr abtstack;
+
+/* Define various stack sizes in pages */
+#define IRQ_STACK_SIZE	1
+#define ABT_STACK_SIZE	1
+#define UND_STACK_SIZE	1
+
+/* misc prototypes used by the many arm machdeps */
+struct trapframe;
+void arm_lock_cache_line(vm_offset_t);
+void init_proc0(vm_offset_t kstack);
+void halt(void);
+void abort_handler(struct trapframe *, int );
+void set_stackptrs(int cpu);
+void undefinedinstruction_bounce(struct trapframe *);
+
+/* Early boot related helper functions */
+struct arm_boot_params;
+vm_offset_t default_parse_boot_param(struct arm_boot_params *abp);
+vm_offset_t freebsd_parse_boot_param(struct arm_boot_params *abp);
+vm_offset_t linux_parse_boot_param(struct arm_boot_params *abp);
+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.
+ *
+ *  - platform_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 platform_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);
+
+#endif /* !_MACHINE_MACHDEP_H_ */


Property changes on: trunk/sys/arm/include/machdep.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/md_var.h
===================================================================
--- trunk/sys/arm/include/md_var.h	                        (rev 0)
+++ trunk/sys/arm/include/md_var.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,75 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1995 Bruce D. Evans.
+ * 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.
+ * 3. Neither the name of the author nor the names of contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * 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.
+ *
+ *	from: FreeBSD: src/sys/i386/include/md_var.h,v 1.40 2001/07/12
+ * $FreeBSD: stable/10/sys/arm/include/md_var.h 278730 2015-02-13 23:30:48Z ian $
+ */
+
+#ifndef	_MACHINE_MD_VAR_H_
+#define	_MACHINE_MD_VAR_H_
+
+extern long Maxmem;
+extern char sigcode[];
+extern int szsigcode;
+extern uint32_t *vm_page_dump;
+extern int vm_page_dump_size;
+
+extern int (*_arm_memcpy)(void *, void *, int, int);
+extern int (*_arm_bzero)(void *, int, int);
+
+extern int _min_memcpy_size;
+extern int _min_bzero_size;
+
+#define DST_IS_USER	0x1
+#define SRC_IS_USER	0x2
+#define IS_PHYSICAL	0x4
+
+enum cpu_class {
+	CPU_CLASS_NONE,
+	CPU_CLASS_ARM9TDMI,
+	CPU_CLASS_ARM9ES,
+	CPU_CLASS_ARM9EJS,
+	CPU_CLASS_ARM10E,
+	CPU_CLASS_ARM10EJ,
+	CPU_CLASS_CORTEXA,
+	CPU_CLASS_KRAIT,
+	CPU_CLASS_XSCALE,
+	CPU_CLASS_ARM11J,
+	CPU_CLASS_MARVELL
+};
+extern enum cpu_class cpu_class;
+
+struct dumperinfo;
+extern int busdma_swi_pending;
+void busdma_swi(void);
+void dump_add_page(vm_paddr_t);
+void dump_drop_page(vm_paddr_t);
+void minidumpsys(struct dumperinfo *);
+
+#endif /* !_MACHINE_MD_VAR_H_ */


Property changes on: trunk/sys/arm/include/md_var.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/memdev.h
===================================================================
--- trunk/sys/arm/include/memdev.h	                        (rev 0)
+++ trunk/sys/arm/include/memdev.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,41 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2004 Mark R V Murray
+ * 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
+ *    in this position and unchanged.
+ * 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 AUTHORS ``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 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: stable/10/sys/arm/include/memdev.h 217515 2011-01-17 22:58:28Z jkim $
+ */
+
+#ifndef _MACHINE_MEMDEV_H_
+#define	_MACHINE_MEMDEV_H_
+
+#define	CDEV_MINOR_MEM	0
+#define	CDEV_MINOR_KMEM	1
+
+d_open_t	memopen;
+d_read_t	memrw;
+d_mmap_t	memmmap;
+#define		memioctl	(d_ioctl_t *)NULL
+
+#endif /* _MACHINE_MEMDEV_H_ */


Property changes on: trunk/sys/arm/include/memdev.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/metadata.h
===================================================================
--- trunk/sys/arm/include/metadata.h	                        (rev 0)
+++ trunk/sys/arm/include/metadata.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,36 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2003 Peter Wemm <peter at FreeBSD.org>
+ * 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: stable/10/sys/arm/include/metadata.h 217290 2011-01-11 22:07:39Z marcel $
+ */
+
+#ifndef _MACHINE_METADATA_H_
+#define	_MACHINE_METADATA_H_
+
+#define	MODINFOMD_BOOTINFO	0x1001
+#define	MODINFOMD_DTBP		0x1002
+
+#endif /* !_MACHINE_METADATA_H_ */


Property changes on: trunk/sys/arm/include/metadata.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/minidump.h
===================================================================
--- trunk/sys/arm/include/minidump.h	                        (rev 0)
+++ trunk/sys/arm/include/minidump.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,46 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2006 Peter Wemm
+ * 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 ``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 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.
+ *
+ * From: FreeBSD: src/sys/i386/include/minidump.h,v 1.1 2006/04/21 04:28:43
+ * $FreeBSD: stable/10/sys/arm/include/minidump.h 184728 2008-11-06 16:20:27Z raj $
+ */
+
+#ifndef	_MACHINE_MINIDUMP_H_
+#define	_MACHINE_MINIDUMP_H_ 1
+
+#define	MINIDUMP_MAGIC		"minidump FreeBSD/arm"
+#define	MINIDUMP_VERSION	1
+
+struct minidumphdr {
+	char magic[24];
+	uint32_t version;
+	uint32_t msgbufsize;
+	uint32_t bitmapsize;
+	uint32_t ptesize;
+	uint32_t kernbase;
+};
+
+#endif /* _MACHINE_MINIDUMP_H_ */


Property changes on: trunk/sys/arm/include/minidump.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/ofw_machdep.h
===================================================================
--- trunk/sys/arm/include/ofw_machdep.h	                        (rev 0)
+++ trunk/sys/arm/include/ofw_machdep.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,45 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2009 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Semihalf under sponsorship from
+ * the FreeBSD Foundation.
+ *
+ * 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: stable/10/sys/arm/include/ofw_machdep.h 266084 2014-05-14 19:18:58Z ian $
+ */
+
+#ifndef _MACHINE_OFW_MACHDEP_H_
+#define _MACHINE_OFW_MACHDEP_H_
+
+#include <vm/vm.h>
+
+typedef	uint32_t	cell_t;
+
+struct mem_region {
+	vm_offset_t	mr_start;
+	vm_size_t	mr_size;
+};
+
+#endif /* _MACHINE_OFW_MACHDEP_H_ */


Property changes on: trunk/sys/arm/include/ofw_machdep.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/param.h
===================================================================
--- trunk/sys/arm/include/param.h	                        (rev 0)
+++ trunk/sys/arm/include/param.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,157 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2001 David E. O'Brien
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ *	from: @(#)param.h	5.8 (Berkeley) 6/28/91
+ * $FreeBSD: stable/10/sys/arm/include/param.h 274648 2014-11-18 12:53:32Z kib $
+ */
+
+#ifndef _ARM_INCLUDE_PARAM_H_
+#define	_ARM_INCLUDE_PARAM_H_
+
+/*
+ * Machine dependent constants for StrongARM
+ */
+
+#include <machine/_align.h>
+#include <machine/acle-compat.h>
+
+#define STACKALIGNBYTES	(8 - 1)
+#define STACKALIGN(p)	((u_int)(p) & ~STACKALIGNBYTES)
+
+#define __PCI_REROUTE_INTERRUPT
+
+#if __ARM_ARCH >= 6
+#define	_V6_SUFFIX "v6"
+#else
+#define	_V6_SUFFIX ""
+#endif
+
+#ifdef __ARM_PCS_VFP
+#define	_HF_SUFFIX "hf"
+#else
+#define	_HF_SUFFIX ""
+#endif
+
+#ifdef __ARM_BIG_ENDIAN
+#define	_EB_SUFFIX "eb"
+#else
+#define	_EB_SUFFIX ""
+#endif
+
+#ifndef MACHINE
+#define	MACHINE		"arm"
+#endif
+#ifndef MACHINE_ARCH
+#define	MACHINE_ARCH	"arm" _V6_SUFFIX _HF_SUFFIX _EB_SUFFIX
+#endif
+
+#if defined(SMP) || defined(KLD_MODULE)
+#ifndef MAXCPU
+#define	MAXCPU		4
+#endif
+#else
+#define	MAXCPU		1
+#endif /* SMP || KLD_MODULE */
+
+#ifndef MAXMEMDOM
+#define	MAXMEMDOM	1
+#endif
+
+#define	ALIGNBYTES	_ALIGNBYTES
+#define	ALIGN(p)	_ALIGN(p)
+/*
+ * ALIGNED_POINTER is a boolean macro that checks whether an address
+ * is valid to fetch data elements of type t from on this architecture.
+ * This does not reflect the optimal alignment, just the possibility
+ * (within reasonable limits).
+ */
+#define	ALIGNED_POINTER(p, t)	((((unsigned)(p)) & (sizeof(t)-1)) == 0)
+
+/*
+ * CACHE_LINE_SIZE is the compile-time maximum cache line size for an
+ * architecture.  It should be used with appropriate caution.
+ */
+#define	CACHE_LINE_SHIFT	6
+#define	CACHE_LINE_SIZE		(1 << CACHE_LINE_SHIFT)
+
+#define	PAGE_SHIFT	12
+#define	PAGE_SIZE	(1 << PAGE_SHIFT)	/* Page size */
+#define	PAGE_MASK	(PAGE_SIZE - 1)
+#define	NPTEPG		(PAGE_SIZE/(sizeof (pt_entry_t)))
+
+#define PDR_SHIFT	20 /* log2(NBPDR) */
+#define NBPDR		(1 << PDR_SHIFT)
+#define PDRMASK		(NBPDR - 1)
+#define NPDEPG          (1 << (32 - PDR_SHIFT))
+
+#define	MAXPAGESIZES	2		/* maximum number of supported page sizes */
+
+#ifndef KSTACK_PAGES
+#define KSTACK_PAGES    2
+#endif /* !KSTACK_PAGES */
+
+#ifndef FPCONTEXTSIZE
+#define FPCONTEXTSIZE	(0x100)
+#endif
+
+#ifndef KSTACK_GUARD_PAGES
+#define KSTACK_GUARD_PAGES	1
+#endif /* !KSTACK_GUARD_PAGES */
+
+#define USPACE_SVC_STACK_TOP		(KSTACK_PAGES * PAGE_SIZE)
+
+/*
+ * Mach derived conversion macros
+ */
+#define	trunc_page(x)		((x) & ~PAGE_MASK)
+#define	round_page(x)		(((x) + PAGE_MASK) & ~PAGE_MASK)
+#define	trunc_1mpage(x)		((unsigned)(x) & ~PDRMASK)
+#define	round_1mpage(x)		((((unsigned)(x)) + PDRMASK) & ~PDRMASK)
+
+#define	atop(x)			((unsigned)(x) >> PAGE_SHIFT)
+#define	ptoa(x)			((unsigned)(x) << PAGE_SHIFT)
+
+#define	arm32_btop(x)		((unsigned)(x) >> PAGE_SHIFT)
+#define	arm32_ptob(x)		((unsigned)(x) << PAGE_SHIFT)
+
+#define	pgtok(x)		((x) * (PAGE_SIZE / 1024))
+
+#ifdef _KERNEL
+#define	NO_FUEWORD	1
+#endif
+
+#endif /* !_ARM_INCLUDE_PARAM_H_ */


Property changes on: trunk/sys/arm/include/param.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/pcb.h
===================================================================
--- trunk/sys/arm/include/pcb.h	                        (rev 0)
+++ trunk/sys/arm/include/pcb.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,83 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: pcb.h,v 1.10 2003/10/13 21:46:39 scw Exp $	*/
+
+/*-
+ * Copyright (c) 2001 Matt Thomas <matt at 3am-software.com>.
+ * Copyright (c) 1994 Mark Brinicombe.
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the RiscBSD team.
+ * 4. The name "RiscBSD" nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY RISCBSD ``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 RISCBSD 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: stable/10/sys/arm/include/pcb.h 278614 2015-02-12 04:15:55Z ian $
+ */
+
+#ifndef	_MACHINE_PCB_H_
+#define	_MACHINE_PCB_H_
+
+#include <machine/fp.h>
+#include <machine/frame.h>
+
+
+/*
+ * WARNING!
+ * Keep pcb_regs first for faster access in switch.S
+ */
+struct pcb {
+	struct switchframe pcb_regs;		/* CPU state */
+	u_int	pcb_flags;
+#define	PCB_OWNFPU	0x00000001
+#define PCB_NOALIGNFLT	0x00000002
+	caddr_t	pcb_onfault;			/* On fault handler */
+	vm_offset_t	pcb_pagedir;		/* PT hooks */
+	uint32_t *pcb_pl1vec;			/* PTR to vector_base L1 entry*/
+	uint32_t pcb_l1vec;			/* Value to stuff on ctx sw */
+	u_int	pcb_dacr;			/* Domain Access Control Reg */
+
+	struct vfp_state pcb_vfpstate;          /* VP/NEON state */
+	u_int pcb_vfpcpu;                       /* VP/NEON last cpu */
+} __aligned(8); /* 
+		 * We need the PCB to be aligned on 8 bytes, as we may
+		 * access it using ldrd/strd, and ARM ABI require it
+		 * to by aligned on 8 bytes.
+		 */
+
+/*
+ * No additional data for core dumps.
+ */
+struct md_coredump {
+	int	md_empty;
+};
+
+void	makectx(struct trapframe *tf, struct pcb *pcb);
+
+#ifdef _KERNEL
+
+void    savectx(struct pcb *) __returns_twice;
+#endif	/* _KERNEL */
+
+#endif	/* !_MACHINE_PCB_H_ */


Property changes on: trunk/sys/arm/include/pcb.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/pcpu.h
===================================================================
--- trunk/sys/arm/include/pcpu.h	                        (rev 0)
+++ trunk/sys/arm/include/pcpu.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,126 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1999 Luoqi Chen <luoqi at freebsd.org>
+ * 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.
+ *
+ *	from: FreeBSD: src/sys/i386/include/globaldata.h,v 1.27 2001/04/27
+ * $FreeBSD: stable/10/sys/arm/include/pcpu.h 266277 2014-05-17 00:53:12Z ian $
+ */
+
+#ifndef	_MACHINE_PCPU_H_
+#define	_MACHINE_PCPU_H_
+
+#ifdef _KERNEL
+
+#include <machine/cpuconf.h>
+
+#define	ALT_STACK_SIZE	128
+
+struct vmspace;
+
+#endif	/* _KERNEL */
+
+#ifdef VFP
+#define PCPU_MD_FIELDS							\
+	unsigned int pc_cpu;						\
+	unsigned int pc_vfpsid;						\
+	unsigned int pc_vfpmvfr0;					\
+	unsigned int pc_vfpmvfr1;					\
+	struct pmap *pc_curpmap;					\
+	char __pad[137]
+#else
+#define PCPU_MD_FIELDS							\
+	char __pad[157]
+#endif
+
+#ifdef _KERNEL
+
+struct pcb;
+struct pcpu;
+
+extern struct pcpu *pcpup;
+#if ARM_ARCH_6 || ARM_ARCH_7A
+/* or ARM_TP_ADDRESS 	mark REMOVE ME NOTE */
+
+#define CPU_MASK (0xf)
+
+#ifndef SMP
+#define get_pcpu() (pcpup)
+#else
+#define get_pcpu() __extension__ ({			  		\
+    	int id;								\
+        __asm __volatile("mrc p15, 0, %0, c0, c0, 5" : "=r" (id));	\
+    	(pcpup + (id & CPU_MASK));					\
+    })
+#endif
+	
+static inline struct thread *
+get_curthread(void)
+{
+	void *ret;
+
+	__asm __volatile("mrc p15, 0, %0, c13, c0, 4" : "=r" (ret));
+	return (ret);
+}
+
+static inline void
+set_curthread(struct thread *td)
+{
+
+	__asm __volatile("mcr p15, 0, %0, c13, c0, 4" : : "r" (td));
+}
+
+
+static inline void *
+get_tls(void)
+{
+	void *tls;
+
+	__asm __volatile("mrc p15, 0, %0, c13, c0, 3" : "=r" (tls));
+	return (tls);
+}
+
+static inline void
+set_tls(void *tls)
+{
+
+	__asm __volatile("mcr p15, 0, %0, c13, c0, 3" : : "r" (tls));
+}
+
+#define curthread get_curthread()
+
+#else
+#define get_pcpu()	pcpup
+#endif
+
+#define	PCPU_GET(member)	(get_pcpu()->pc_ ## member)
+#define	PCPU_ADD(member, value)	(get_pcpu()->pc_ ## member += (value))
+#define	PCPU_INC(member)	PCPU_ADD(member, 1)
+#define	PCPU_PTR(member)	(&get_pcpu()->pc_ ## member)
+#define	PCPU_SET(member,value)	(get_pcpu()->pc_ ## member = (value))
+
+void pcpu0_init(void);
+#endif	/* _KERNEL */
+
+#endif	/* !_MACHINE_PCPU_H_ */


Property changes on: trunk/sys/arm/include/pcpu.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/physmem.h
===================================================================
--- trunk/sys/arm/include/physmem.h	                        (rev 0)
+++ trunk/sys/arm/include/physmem.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,92 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014 Ian Lepore <ian at freebsd.org>
+ * 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: stable/10/sys/arm/include/physmem.h 266201 2014-05-15 22:50:06Z ian $
+ */
+
+#ifndef	_MACHINE_PHYSMEM_H_
+#define	_MACHINE_PHYSMEM_H_
+
+/*
+ * The physical address at which the kernel was loaded.
+ */
+extern vm_paddr_t arm_physmem_kernaddr;
+
+/*
+ * Routines to help configure physical ram.
+ *
+ * Multiple regions of contiguous physical ram can be added (in any order).
+ *
+ * Multiple regions of physical ram that should be excluded from crash dumps, or
+ * memory allocation, or both, can be added (in any order).
+ *
+ * After all early kernel init is done and it's time to configure all
+ * remainining non-excluded physical ram for use by other parts of the kernel,
+ * arm_physmem_init_kernel_globals() processes the hardware regions and
+ * exclusion regions to generate the global dump_avail and phys_avail arrays
+ * that communicate physical ram configuration to other parts of the kernel.
+ */
+
+#define	EXFLAG_NODUMP	0x01
+#define	EXFLAG_NOALLOC	0x02
+
+void arm_physmem_hardware_region(vm_paddr_t pa, vm_size_t sz);
+void arm_physmem_exclude_region(vm_paddr_t pa, vm_size_t sz, uint32_t flags);
+void arm_physmem_init_kernel_globals(void);
+void arm_physmem_print_tables(void);
+
+/*
+ * Convenience routines for FDT.
+ */
+
+#ifdef FDT
+
+#include <machine/ofw_machdep.h>
+
+static inline void 
+arm_physmem_hardware_regions(struct mem_region * mrptr, int mrcount)
+{
+	while (mrcount--) {
+		arm_physmem_hardware_region(mrptr->mr_start, mrptr->mr_size);
+		++mrptr;
+	}
+}
+
+static inline void
+arm_physmem_exclude_regions(struct mem_region * mrptr, int mrcount, 
+    uint32_t exflags)
+{
+	while (mrcount--) {
+		arm_physmem_exclude_region(mrptr->mr_start, mrptr->mr_size, 
+		    exflags);
+		++mrptr;
+	}
+}
+
+#endif /* FDT */
+
+#endif
+


Property changes on: trunk/sys/arm/include/physmem.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/pl310.h
===================================================================
--- trunk/sys/arm/include/pl310.h	                        (rev 0)
+++ trunk/sys/arm/include/pl310.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,189 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Olivier Houchard.  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 ``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 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: stable/10/sys/arm/include/pl310.h 270075 2014-08-17 01:28:03Z ian $
+ */
+
+#ifndef PL310_H_
+#define PL310_H_
+
+/**
+ *	PL310 - L2 Cache Controller register offsets.
+ *
+ */
+#define PL310_CACHE_ID			0x000
+#define 	CACHE_ID_RELEASE_SHIFT		0
+#define 	CACHE_ID_RELEASE_MASK		0x3f
+#define 	CACHE_ID_RELEASE_r0p0		0x00
+#define 	CACHE_ID_RELEASE_r1p0		0x02
+#define 	CACHE_ID_RELEASE_r2p0		0x04
+#define 	CACHE_ID_RELEASE_r3p0		0x05
+#define 	CACHE_ID_RELEASE_r3p1		0x06
+#define 	CACHE_ID_RELEASE_r3p2		0x08
+#define 	CACHE_ID_RELEASE_r3p3		0x09
+#define 	CACHE_ID_PARTNUM_SHIFT		6
+#define 	CACHE_ID_PARTNUM_MASK		0xf
+#define 	CACHE_ID_PARTNUM_VALUE		0x3
+#define PL310_CACHE_TYPE		0x004
+#define PL310_CTRL			0x100
+#define		CTRL_ENABLED			0x01
+#define		CTRL_DISABLED			0x00
+#define PL310_AUX_CTRL			0x104
+#define 	AUX_CTRL_MASK			0xc0000fff
+#define 	AUX_CTRL_ASSOCIATIVITY_SHIFT	16
+#define 	AUX_CTRL_WAY_SIZE_SHIFT		17
+#define 	AUX_CTRL_WAY_SIZE_MASK		(0x7 << 17)
+#define 	AUX_CTRL_SHARE_OVERRIDE		(1 << 22)
+#define 	AUX_CTRL_NS_LOCKDOWN		(1 << 26)
+#define 	AUX_CTRL_NS_INT_CTRL		(1 << 27)
+#define 	AUX_CTRL_DATA_PREFETCH		(1 << 28)
+#define 	AUX_CTRL_INSTR_PREFETCH		(1 << 29)
+#define 	AUX_CTRL_EARLY_BRESP		(1 << 30)
+#define PL310_TAG_RAM_CTRL			0x108
+#define PL310_DATA_RAM_CTRL			0x10C
+#define		RAM_CTRL_WRITE_SHIFT		8
+#define		RAM_CTRL_WRITE_MASK		(0x7 << 8)
+#define		RAM_CTRL_READ_SHIFT		4
+#define		RAM_CTRL_READ_MASK		(0x7 << 4)
+#define		RAM_CTRL_SETUP_SHIFT		0
+#define		RAM_CTRL_SETUP_MASK		(0x7 << 0)
+#define PL310_EVENT_COUNTER_CTRL	0x200
+#define		EVENT_COUNTER_CTRL_ENABLED	(1 << 0)
+#define		EVENT_COUNTER_CTRL_C0_RESET	(1 << 1)
+#define		EVENT_COUNTER_CTRL_C1_RESET	(1 << 2)
+#define PL310_EVENT_COUNTER1_CONF	0x204
+#define PL310_EVENT_COUNTER0_CONF	0x208
+#define		EVENT_COUNTER_CONF_NOINTR	0
+#define		EVENT_COUNTER_CONF_INCR		1
+#define		EVENT_COUNTER_CONF_OVFW		2
+#define		EVENT_COUNTER_CONF_NOEV		(0 << 2)
+#define		EVENT_COUNTER_CONF_CO		(1 << 2)
+#define		EVENT_COUNTER_CONF_DRHIT	(2 << 2)
+#define		EVENT_COUNTER_CONF_DRREQ	(3 << 2)
+#define		EVENT_COUNTER_CONF_DWHIT	(4 << 2)
+#define		EVENT_COUNTER_CONF_DWREQ	(5 << 2)
+#define		EVENT_COUNTER_CONF_DWTREQ	(6 << 2)
+#define		EVENT_COUNTER_CONF_DIRHIT	(7 << 2)
+#define		EVENT_COUNTER_CONF_DIRREQ	(8 << 2)
+#define		EVENT_COUNTER_CONF_WA		(9 << 2)
+#define PL310_EVENT_COUNTER1_VAL	0x20C
+#define PL310_EVENT_COUNTER0_VAL	0x210
+#define PL310_INTR_MASK			0x214
+#define PL310_MASKED_INTR_STAT		0x218
+#define PL310_RAW_INTR_STAT		0x21C
+#define PL310_INTR_CLEAR		0x220
+#define		INTR_MASK_ALL			((1 << 9) - 1)
+#define		INTR_MASK_ECNTR			(1 << 0)
+#define		INTR_MASK_PARRT			(1 << 1)
+#define		INTR_MASK_PARRD			(1 << 2)
+#define		INTR_MASK_ERRWT			(1 << 3)
+#define		INTR_MASK_ERRWD			(1 << 4)
+#define		INTR_MASK_ERRRT			(1 << 5)
+#define		INTR_MASK_ERRRD			(1 << 6)
+#define		INTR_MASK_SLVERR		(1 << 7)
+#define		INTR_MASK_DECERR		(1 << 8)
+#define PL310_CACHE_SYNC		0x730
+#define PL310_INV_LINE_PA		0x770
+#define PL310_INV_WAY			0x77C
+#define PL310_CLEAN_LINE_PA		0x7B0
+#define PL310_CLEAN_LINE_IDX		0x7B8
+#define PL310_CLEAN_WAY			0x7BC
+#define PL310_CLEAN_INV_LINE_PA		0x7F0
+#define PL310_CLEAN_INV_LINE_IDX	0x7F8
+#define PL310_CLEAN_INV_WAY		0x7FC
+#define PL310_LOCKDOWN_D_WAY(x)		(0x900 + ((x) * 8))
+#define PL310_LOCKDOWN_I_WAY(x)		(0x904 + ((x) * 8))
+#define PL310_LOCKDOWN_LINE_ENABLE	0x950
+#define PL310_UNLOCK_ALL_LINES_WAY	0x954
+#define PL310_ADDR_FILTER_STAR		0xC00
+#define PL310_ADDR_FILTER_END		0xC04
+#define PL310_DEBUG_CTRL		0xF40
+#define		DEBUG_CTRL_DISABLE_LINEFILL	(1 << 0)
+#define		DEBUG_CTRL_DISABLE_WRITEBACK	(1 << 1)
+#define		DEBUG_CTRL_SPNIDEN		(1 << 2)
+#define PL310_PREFETCH_CTRL		0xF60
+#define		PREFETCH_CTRL_OFFSET_MASK	(0x1f)
+#define		PREFETCH_CTRL_NOTSAMEID		(1 << 21)
+#define		PREFETCH_CTRL_INCR_DL		(1 << 23)
+#define		PREFETCH_CTRL_PREFETCH_DROP	(1 << 24)
+#define		PREFETCH_CTRL_DL_ON_WRAP	(1 << 27)
+#define		PREFETCH_CTRL_DATA_PREFETCH	(1 << 28)
+#define		PREFETCH_CTRL_INSTR_PREFETCH	(1 << 29)
+#define		PREFETCH_CTRL_DL		(1 << 30)
+#define PL310_POWER_CTRL		0xF60
+#define		POWER_CTRL_ENABLE_GATING	(1 << 0)
+#define		POWER_CTRL_ENABLE_STANDBY	(1 << 1)
+
+struct intr_config_hook;
+
+struct pl310_softc {
+	device_t	sc_dev;
+	struct resource *sc_mem_res;
+	struct resource *sc_irq_res;
+	void*		sc_irq_h;
+	int		sc_enabled;
+	struct mtx	sc_mtx;
+	u_int		sc_rtl_revision;
+	struct intr_config_hook *sc_ich;
+};
+
+/**
+ *	pl310_read4 - read a 32-bit value from the PL310 registers
+ *	pl310_write4 - write a 32-bit value from the PL310 registers
+ *	@off: byte offset within the register set to read from
+ *	@val: the value to write into the register
+ *	
+ *
+ *	LOCKING:
+ *	None
+ *
+ *	RETURNS:
+ *	nothing in case of write function, if read function returns the value read.
+ */
+static __inline uint32_t
+pl310_read4(struct pl310_softc *sc, bus_size_t off)
+{
+
+	return bus_read_4(sc->sc_mem_res, off);
+}
+
+static __inline void
+pl310_write4(struct pl310_softc *sc, bus_size_t off, uint32_t val)
+{
+
+	bus_write_4(sc->sc_mem_res, off, val);
+}
+
+void pl310_print_config(struct pl310_softc *sc);
+void pl310_set_ram_latency(struct pl310_softc *sc, uint32_t which_reg,
+    uint32_t read, uint32_t write, uint32_t setup);
+
+void platform_pl310_init(struct pl310_softc *);
+void platform_pl310_write_ctrl(struct pl310_softc *, uint32_t);
+void platform_pl310_write_debug(struct pl310_softc *, uint32_t);
+
+#endif /* PL310_H_ */


Property changes on: trunk/sys/arm/include/pl310.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/pmap.h
===================================================================
--- trunk/sys/arm/include/pmap.h	                        (rev 0)
+++ trunk/sys/arm/include/pmap.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,709 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1991 Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * the Systems Programming Group of the University of Utah Computer
+ * Science Department and William Jolitz of UUNET Technologies Inc.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the University of
+ *      California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ * Derived from hp300 version by Mike Hibler, this version by William
+ * Jolitz uses a recursive map [a pde points to the page directory] to
+ * map the page tables using the pagetables themselves. This is done to
+ * reduce the impact on kernel virtual memory for lots of sparse address
+ * space, and to reduce the cost of memory to each process.
+ *
+ *      from: hp300: @(#)pmap.h 7.2 (Berkeley) 12/16/90
+ *      from: @(#)pmap.h        7.4 (Berkeley) 5/12/91
+ * 	from: FreeBSD: src/sys/i386/include/pmap.h,v 1.70 2000/11/30
+ *
+ * $FreeBSD: stable/10/sys/arm/include/pmap.h 278614 2015-02-12 04:15:55Z ian $
+ */
+
+#ifndef _MACHINE_PMAP_H_
+#define _MACHINE_PMAP_H_
+
+#include <machine/pte.h>
+#include <machine/cpuconf.h>
+/*
+ * Pte related macros
+ */
+#if ARM_ARCH_6 || ARM_ARCH_7A
+#ifdef SMP
+#define PTE_NOCACHE	2
+#else
+#define PTE_NOCACHE	1
+#endif
+#define PTE_CACHE	6
+#define PTE_DEVICE	2
+#define PTE_PAGETABLE	6
+#else
+#define PTE_NOCACHE	1
+#define PTE_CACHE	2
+#define PTE_DEVICE	PTE_NOCACHE
+#define PTE_PAGETABLE	3
+#endif
+
+enum mem_type {
+	STRONG_ORD = 0,
+	DEVICE_NOSHARE,
+	DEVICE_SHARE,
+	NRML_NOCACHE,
+	NRML_IWT_OWT,
+	NRML_IWB_OWB,
+	NRML_IWBA_OWBA
+};
+
+#ifndef LOCORE
+
+#include <sys/queue.h>
+#include <sys/_cpuset.h>
+#include <sys/_lock.h>
+#include <sys/_mutex.h>
+
+#define PDESIZE		sizeof(pd_entry_t)	/* for assembly files */
+#define PTESIZE		sizeof(pt_entry_t)	/* for assembly files */
+
+#ifdef _KERNEL
+
+#define vtophys(va)	pmap_kextract((vm_offset_t)(va))
+
+#endif
+
+#define	pmap_page_get_memattr(m)	((m)->md.pv_memattr)
+#define	pmap_page_is_write_mapped(m)	(((m)->aflags & PGA_WRITEABLE) != 0)
+#if (ARM_MMU_V6 + ARM_MMU_V7) > 0
+boolean_t pmap_page_is_mapped(vm_page_t);
+#else
+#define	pmap_page_is_mapped(m)	(!TAILQ_EMPTY(&(m)->md.pv_list))
+#endif
+void pmap_page_set_memattr(vm_page_t m, vm_memattr_t ma);
+
+/*
+ * Pmap stuff
+ */
+
+/*
+ * This structure is used to hold a virtual<->physical address
+ * association and is used mostly by bootstrap code
+ */
+struct pv_addr {
+	SLIST_ENTRY(pv_addr) pv_list;
+	vm_offset_t	pv_va;
+	vm_paddr_t	pv_pa;
+};
+
+struct	pv_entry;
+struct	pv_chunk;
+
+struct	md_page {
+	int pvh_attrs;
+	vm_memattr_t	 pv_memattr;
+#if (ARM_MMU_V6 + ARM_MMU_V7) == 0
+	vm_offset_t pv_kva;		/* first kernel VA mapping */
+#endif
+	TAILQ_HEAD(,pv_entry)	pv_list;
+};
+
+struct l1_ttable;
+struct l2_dtable;
+
+
+/*
+ * The number of L2 descriptor tables which can be tracked by an l2_dtable.
+ * A bucket size of 16 provides for 16MB of contiguous virtual address
+ * space per l2_dtable. Most processes will, therefore, require only two or
+ * three of these to map their whole working set.
+ */
+#define	L2_BUCKET_LOG2	4
+#define	L2_BUCKET_SIZE	(1 << L2_BUCKET_LOG2)
+/*
+ * Given the above "L2-descriptors-per-l2_dtable" constant, the number
+ * of l2_dtable structures required to track all possible page descriptors
+ * mappable by an L1 translation table is given by the following constants:
+ */
+#define	L2_LOG2		((32 - L1_S_SHIFT) - L2_BUCKET_LOG2)
+#define	L2_SIZE		(1 << L2_LOG2)
+
+struct	pmap {
+	struct mtx		pm_mtx;
+	u_int8_t		pm_domain;
+	struct l1_ttable	*pm_l1;
+	struct l2_dtable	*pm_l2[L2_SIZE];
+	cpuset_t		pm_active;	/* active on cpus */
+	struct pmap_statistics	pm_stats;	/* pmap statictics */
+#if (ARM_MMU_V6 + ARM_MMU_V7) != 0
+	TAILQ_HEAD(,pv_chunk)	pm_pvchunk;	/* list of mappings in pmap */
+#else
+	TAILQ_HEAD(,pv_entry)	pm_pvlist;	/* list of mappings in pmap */
+#endif
+};
+
+typedef struct pmap *pmap_t;
+
+#ifdef _KERNEL
+extern struct pmap	kernel_pmap_store;
+#define kernel_pmap	(&kernel_pmap_store)
+#define pmap_kernel() kernel_pmap
+
+#define	PMAP_ASSERT_LOCKED(pmap) \
+				mtx_assert(&(pmap)->pm_mtx, MA_OWNED)
+#define	PMAP_LOCK(pmap)		mtx_lock(&(pmap)->pm_mtx)
+#define	PMAP_LOCK_DESTROY(pmap)	mtx_destroy(&(pmap)->pm_mtx)
+#define	PMAP_LOCK_INIT(pmap)	mtx_init(&(pmap)->pm_mtx, "pmap", \
+				    NULL, MTX_DEF | MTX_DUPOK)
+#define	PMAP_OWNED(pmap)	mtx_owned(&(pmap)->pm_mtx)
+#define	PMAP_MTX(pmap)		(&(pmap)->pm_mtx)
+#define	PMAP_TRYLOCK(pmap)	mtx_trylock(&(pmap)->pm_mtx)
+#define	PMAP_UNLOCK(pmap)	mtx_unlock(&(pmap)->pm_mtx)
+#endif
+
+
+/*
+ * For each vm_page_t, there is a list of all currently valid virtual
+ * mappings of that page.  An entry is a pv_entry_t, the list is pv_list.
+ */
+typedef struct pv_entry {
+	vm_offset_t     pv_va;          /* virtual address for mapping */
+	TAILQ_ENTRY(pv_entry)   pv_list;
+	int		pv_flags;	/* flags (wired, etc...) */
+#if (ARM_MMU_V6 + ARM_MMU_V7) == 0
+	pmap_t          pv_pmap;        /* pmap where mapping lies */
+	TAILQ_ENTRY(pv_entry)	pv_plist;
+#endif
+} *pv_entry_t;
+
+/*
+ * pv_entries are allocated in chunks per-process.  This avoids the
+ * need to track per-pmap assignments.
+ */
+#define	_NPCM	8
+#define	_NPCPV	252
+
+struct pv_chunk {
+	pmap_t			pc_pmap;
+	TAILQ_ENTRY(pv_chunk)	pc_list;
+	uint32_t		pc_map[_NPCM];	/* bitmap; 1 = free */
+	uint32_t		pc_dummy[3];	/* aligns pv_chunk to 4KB */
+	TAILQ_ENTRY(pv_chunk)	pc_lru;
+	struct pv_entry		pc_pventry[_NPCPV];
+};
+
+#ifdef _KERNEL
+
+boolean_t pmap_get_pde_pte(pmap_t, vm_offset_t, pd_entry_t **, pt_entry_t **);
+
+/*
+ * virtual address to page table entry and
+ * to physical address. Likewise for alternate address space.
+ * Note: these work recursively, thus vtopte of a pte will give
+ * the corresponding pde that in turn maps it.
+ */
+
+/*
+ * The current top of kernel VM.
+ */
+extern vm_offset_t pmap_curmaxkvaddr;
+
+struct pcb;
+
+void	pmap_set_pcb_pagedir(pmap_t, struct pcb *);
+/* Virtual address to page table entry */
+static __inline pt_entry_t *
+vtopte(vm_offset_t va)
+{
+	pd_entry_t *pdep;
+	pt_entry_t *ptep;
+
+	if (pmap_get_pde_pte(pmap_kernel(), va, &pdep, &ptep) == FALSE)
+		return (NULL);
+	return (ptep);
+}
+
+extern vm_paddr_t phys_avail[];
+extern vm_offset_t virtual_avail;
+extern vm_offset_t virtual_end;
+
+void	pmap_bootstrap(vm_offset_t firstaddr, struct pv_addr *l1pt);
+int	pmap_change_attr(vm_offset_t, vm_size_t, int);
+void	pmap_kenter(vm_offset_t va, vm_paddr_t pa);
+void	pmap_kenter_nocache(vm_offset_t va, vm_paddr_t pa);
+void	pmap_kenter_device(vm_offset_t va, vm_paddr_t pa);
+void	*pmap_kenter_temporary(vm_paddr_t pa, int i);
+void 	pmap_kenter_user(vm_offset_t va, vm_paddr_t pa);
+vm_paddr_t pmap_kextract(vm_offset_t va);
+void	pmap_kremove(vm_offset_t);
+void	*pmap_mapdev(vm_offset_t, vm_size_t);
+void	pmap_unmapdev(vm_offset_t, vm_size_t);
+vm_page_t	pmap_use_pt(pmap_t, vm_offset_t);
+void	pmap_debug(int);
+#if (ARM_MMU_V6 + ARM_MMU_V7) == 0
+void	pmap_map_section(vm_offset_t, vm_offset_t, vm_offset_t, int, int);
+#endif
+void	pmap_link_l2pt(vm_offset_t, vm_offset_t, struct pv_addr *);
+vm_size_t	pmap_map_chunk(vm_offset_t, vm_offset_t, vm_offset_t, vm_size_t, int, int);
+void
+pmap_map_entry(vm_offset_t l1pt, vm_offset_t va, vm_offset_t pa, int prot,
+    int cache);
+int pmap_fault_fixup(pmap_t, vm_offset_t, vm_prot_t, int);
+int pmap_dmap_iscurrent(pmap_t pmap);
+
+/*
+ * Definitions for MMU domains
+ */
+#define	PMAP_DOMAINS		15	/* 15 'user' domains (1-15) */
+#define	PMAP_DOMAIN_KERNEL	0	/* The kernel uses domain #0 */
+
+/*
+ * The new pmap ensures that page-tables are always mapping Write-Thru.
+ * Thus, on some platforms we can run fast and loose and avoid syncing PTEs
+ * on every change.
+ *
+ * Unfortunately, not all CPUs have a write-through cache mode.  So we
+ * define PMAP_NEEDS_PTE_SYNC for C code to conditionally do PTE syncs,
+ * and if there is the chance for PTE syncs to be needed, we define
+ * PMAP_INCLUDE_PTE_SYNC so e.g. assembly code can include (and run)
+ * the code.
+ */
+extern int pmap_needs_pte_sync;
+
+/*
+ * These macros define the various bit masks in the PTE.
+ *
+ * We use these macros since we use different bits on different processor
+ * models.
+ */
+
+#define	L1_S_CACHE_MASK_generic	(L1_S_B|L1_S_C)
+#define	L1_S_CACHE_MASK_xscale	(L1_S_B|L1_S_C|L1_S_XSCALE_TEX(TEX_XSCALE_X)|\
+    				L1_S_XSCALE_TEX(TEX_XSCALE_T))
+
+#define	L2_L_CACHE_MASK_generic	(L2_B|L2_C)
+#define	L2_L_CACHE_MASK_xscale	(L2_B|L2_C|L2_XSCALE_L_TEX(TEX_XSCALE_X) | \
+    				L2_XSCALE_L_TEX(TEX_XSCALE_T))
+
+#define	L2_S_PROT_U_generic	(L2_AP(AP_U))
+#define	L2_S_PROT_W_generic	(L2_AP(AP_W))
+#define	L2_S_PROT_MASK_generic	(L2_S_PROT_U|L2_S_PROT_W)
+
+#define	L2_S_PROT_U_xscale	(L2_AP0(AP_U))
+#define	L2_S_PROT_W_xscale	(L2_AP0(AP_W))
+#define	L2_S_PROT_MASK_xscale	(L2_S_PROT_U|L2_S_PROT_W)
+
+#define	L2_S_CACHE_MASK_generic	(L2_B|L2_C)
+#define	L2_S_CACHE_MASK_xscale	(L2_B|L2_C|L2_XSCALE_T_TEX(TEX_XSCALE_X)| \
+    				 L2_XSCALE_T_TEX(TEX_XSCALE_X))
+
+#define	L1_S_PROTO_generic	(L1_TYPE_S | L1_S_IMP)
+#define	L1_S_PROTO_xscale	(L1_TYPE_S)
+
+#define	L1_C_PROTO_generic	(L1_TYPE_C | L1_C_IMP2)
+#define	L1_C_PROTO_xscale	(L1_TYPE_C)
+
+#define	L2_L_PROTO		(L2_TYPE_L)
+
+#define	L2_S_PROTO_generic	(L2_TYPE_S)
+#define	L2_S_PROTO_xscale	(L2_TYPE_XSCALE_XS)
+
+/*
+ * User-visible names for the ones that vary with MMU class.
+ */
+#if (ARM_MMU_V6 + ARM_MMU_V7) != 0
+#define	L2_AP(x)	(L2_AP0(x))
+#else
+#define	L2_AP(x)	(L2_AP0(x) | L2_AP1(x) | L2_AP2(x) | L2_AP3(x))
+#endif
+
+#if (ARM_MMU_V6 + ARM_MMU_V7) != 0
+/*
+ * AP[2:1] access permissions model:
+ *
+ * AP[2](APX)	- Write Disable
+ * AP[1]	- User Enable
+ * AP[0]	- Reference Flag
+ *
+ * AP[2]     AP[1]     Kernel     User
+ *  0          0        R/W        N
+ *  0          1        R/W       R/W
+ *  1          0         R         N
+ *  1          1         R         R
+ *
+ */
+#define	L2_S_PROT_R		(0)		/* kernel read */
+#define	L2_S_PROT_U		(L2_AP0(2))	/* user read */
+#define L2_S_REF		(L2_AP0(1))	/* reference flag */
+
+#define	L2_S_PROT_MASK		(L2_S_PROT_U|L2_S_PROT_R|L2_APX)
+#define	L2_S_EXECUTABLE(pte)	(!(pte & L2_XN))
+#define	L2_S_WRITABLE(pte)	(!(pte & L2_APX))
+#define	L2_S_REFERENCED(pte)	(!!(pte & L2_S_REF))
+
+#ifndef SMP
+#define	L1_S_CACHE_MASK		(L1_S_TEX_MASK|L1_S_B|L1_S_C)
+#define	L2_L_CACHE_MASK		(L2_L_TEX_MASK|L2_B|L2_C)
+#define	L2_S_CACHE_MASK		(L2_S_TEX_MASK|L2_B|L2_C)
+#else
+#define	L1_S_CACHE_MASK		(L1_S_TEX_MASK|L1_S_B|L1_S_C|L1_SHARED)
+#define	L2_L_CACHE_MASK		(L2_L_TEX_MASK|L2_B|L2_C|L2_SHARED)
+#define	L2_S_CACHE_MASK		(L2_S_TEX_MASK|L2_B|L2_C|L2_SHARED)
+#endif  /* SMP */
+
+#define	L1_S_PROTO		(L1_TYPE_S)
+#define	L1_C_PROTO		(L1_TYPE_C)
+#define	L2_S_PROTO		(L2_TYPE_S)
+
+/*
+ * Promotion to a 1MB (SECTION) mapping requires that the corresponding
+ * 4KB (SMALL) page mappings have identical settings for the following fields:
+ */
+#define	L2_S_PROMOTE		(L2_S_REF | L2_SHARED | L2_S_PROT_MASK | \
+				 L2_XN | L2_S_PROTO)
+
+/*
+ * In order to compare 1MB (SECTION) entry settings with the 4KB (SMALL)
+ * page mapping it is necessary to read and shift appropriate bits from
+ * L1 entry to positions of the corresponding bits in the L2 entry.
+ */
+#define L1_S_DEMOTE(l1pd)	((((l1pd) & L1_S_PROTO) >> 0) | \
+				(((l1pd) & L1_SHARED) >> 6) | \
+				(((l1pd) & L1_S_REF) >> 6) | \
+				(((l1pd) & L1_S_PROT_MASK) >> 6) | \
+				(((l1pd) & L1_S_XN) >> 4))
+
+#ifndef SMP
+#define ARM_L1S_STRONG_ORD	(0)
+#define ARM_L1S_DEVICE_NOSHARE	(L1_S_TEX(2))
+#define ARM_L1S_DEVICE_SHARE	(L1_S_B)
+#define ARM_L1S_NRML_NOCACHE	(L1_S_TEX(1))
+#define ARM_L1S_NRML_IWT_OWT	(L1_S_C)
+#define ARM_L1S_NRML_IWB_OWB	(L1_S_C|L1_S_B)
+#define ARM_L1S_NRML_IWBA_OWBA	(L1_S_TEX(1)|L1_S_C|L1_S_B)
+
+#define ARM_L2L_STRONG_ORD	(0)
+#define ARM_L2L_DEVICE_NOSHARE	(L2_L_TEX(2))
+#define ARM_L2L_DEVICE_SHARE	(L2_B)
+#define ARM_L2L_NRML_NOCACHE	(L2_L_TEX(1))
+#define ARM_L2L_NRML_IWT_OWT	(L2_C)
+#define ARM_L2L_NRML_IWB_OWB	(L2_C|L2_B)
+#define ARM_L2L_NRML_IWBA_OWBA	(L2_L_TEX(1)|L2_C|L2_B)
+
+#define ARM_L2S_STRONG_ORD	(0)
+#define ARM_L2S_DEVICE_NOSHARE	(L2_S_TEX(2))
+#define ARM_L2S_DEVICE_SHARE	(L2_B)
+#define ARM_L2S_NRML_NOCACHE	(L2_S_TEX(1))
+#define ARM_L2S_NRML_IWT_OWT	(L2_C)
+#define ARM_L2S_NRML_IWB_OWB	(L2_C|L2_B)
+#define ARM_L2S_NRML_IWBA_OWBA	(L2_S_TEX(1)|L2_C|L2_B)
+#else
+#define ARM_L1S_STRONG_ORD	(0)
+#define ARM_L1S_DEVICE_NOSHARE	(L1_S_TEX(2))
+#define ARM_L1S_DEVICE_SHARE	(L1_S_B)
+#define ARM_L1S_NRML_NOCACHE	(L1_S_TEX(1)|L1_SHARED)
+#define ARM_L1S_NRML_IWT_OWT	(L1_S_C|L1_SHARED)
+#define ARM_L1S_NRML_IWB_OWB	(L1_S_C|L1_S_B|L1_SHARED)
+#define ARM_L1S_NRML_IWBA_OWBA	(L1_S_TEX(1)|L1_S_C|L1_S_B|L1_SHARED)
+
+#define ARM_L2L_STRONG_ORD	(0)
+#define ARM_L2L_DEVICE_NOSHARE	(L2_L_TEX(2))
+#define ARM_L2L_DEVICE_SHARE	(L2_B)
+#define ARM_L2L_NRML_NOCACHE	(L2_L_TEX(1)|L2_SHARED)
+#define ARM_L2L_NRML_IWT_OWT	(L2_C|L2_SHARED)
+#define ARM_L2L_NRML_IWB_OWB	(L2_C|L2_B|L2_SHARED)
+#define ARM_L2L_NRML_IWBA_OWBA	(L2_L_TEX(1)|L2_C|L2_B|L2_SHARED)
+
+#define ARM_L2S_STRONG_ORD	(0)
+#define ARM_L2S_DEVICE_NOSHARE	(L2_S_TEX(2))
+#define ARM_L2S_DEVICE_SHARE	(L2_B)
+#define ARM_L2S_NRML_NOCACHE	(L2_S_TEX(1)|L2_SHARED)
+#define ARM_L2S_NRML_IWT_OWT	(L2_C|L2_SHARED)
+#define ARM_L2S_NRML_IWB_OWB	(L2_C|L2_B|L2_SHARED)
+#define ARM_L2S_NRML_IWBA_OWBA	(L2_S_TEX(1)|L2_C|L2_B|L2_SHARED)
+#endif /* SMP */
+
+#elif ARM_NMMUS > 1
+/* More than one MMU class configured; use variables. */
+#define	L2_S_PROT_U		pte_l2_s_prot_u
+#define	L2_S_PROT_W		pte_l2_s_prot_w
+#define	L2_S_PROT_MASK		pte_l2_s_prot_mask
+
+#define	L1_S_CACHE_MASK		pte_l1_s_cache_mask
+#define	L2_L_CACHE_MASK		pte_l2_l_cache_mask
+#define	L2_S_CACHE_MASK		pte_l2_s_cache_mask
+
+#define	L1_S_PROTO		pte_l1_s_proto
+#define	L1_C_PROTO		pte_l1_c_proto
+#define	L2_S_PROTO		pte_l2_s_proto
+
+#elif ARM_MMU_GENERIC != 0
+#define	L2_S_PROT_U		L2_S_PROT_U_generic
+#define	L2_S_PROT_W		L2_S_PROT_W_generic
+#define	L2_S_PROT_MASK		L2_S_PROT_MASK_generic
+
+#define	L1_S_CACHE_MASK		L1_S_CACHE_MASK_generic
+#define	L2_L_CACHE_MASK		L2_L_CACHE_MASK_generic
+#define	L2_S_CACHE_MASK		L2_S_CACHE_MASK_generic
+
+#define	L1_S_PROTO		L1_S_PROTO_generic
+#define	L1_C_PROTO		L1_C_PROTO_generic
+#define	L2_S_PROTO		L2_S_PROTO_generic
+
+#elif ARM_MMU_XSCALE == 1
+#define	L2_S_PROT_U		L2_S_PROT_U_xscale
+#define	L2_S_PROT_W		L2_S_PROT_W_xscale
+#define	L2_S_PROT_MASK		L2_S_PROT_MASK_xscale
+
+#define	L1_S_CACHE_MASK		L1_S_CACHE_MASK_xscale
+#define	L2_L_CACHE_MASK		L2_L_CACHE_MASK_xscale
+#define	L2_S_CACHE_MASK		L2_S_CACHE_MASK_xscale
+
+#define	L1_S_PROTO		L1_S_PROTO_xscale
+#define	L1_C_PROTO		L1_C_PROTO_xscale
+#define	L2_S_PROTO		L2_S_PROTO_xscale
+
+#endif /* ARM_NMMUS > 1 */
+
+#if defined(CPU_XSCALE_81342) || ARM_ARCH_6 || ARM_ARCH_7A
+#define PMAP_NEEDS_PTE_SYNC	1
+#define PMAP_INCLUDE_PTE_SYNC
+#else
+#define	PMAP_NEEDS_PTE_SYNC	0
+#endif
+
+/*
+ * These macros return various bits based on kernel/user and protection.
+ * Note that the compiler will usually fold these at compile time.
+ */
+#if (ARM_MMU_V6 + ARM_MMU_V7) == 0
+
+#define	L1_S_PROT_U		(L1_S_AP(AP_U))
+#define	L1_S_PROT_W		(L1_S_AP(AP_W))
+#define	L1_S_PROT_MASK		(L1_S_PROT_U|L1_S_PROT_W)
+#define	L1_S_WRITABLE(pd)	((pd) & L1_S_PROT_W)
+
+#define	L1_S_PROT(ku, pr)	((((ku) == PTE_USER) ? L1_S_PROT_U : 0) | \
+				 (((pr) & VM_PROT_WRITE) ? L1_S_PROT_W : 0))
+
+#define	L2_L_PROT_U		(L2_AP(AP_U))
+#define	L2_L_PROT_W		(L2_AP(AP_W))
+#define	L2_L_PROT_MASK		(L2_L_PROT_U|L2_L_PROT_W)
+
+#define	L2_L_PROT(ku, pr)	((((ku) == PTE_USER) ? L2_L_PROT_U : 0) | \
+				 (((pr) & VM_PROT_WRITE) ? L2_L_PROT_W : 0))
+
+#define	L2_S_PROT(ku, pr)	((((ku) == PTE_USER) ? L2_S_PROT_U : 0) | \
+				 (((pr) & VM_PROT_WRITE) ? L2_S_PROT_W : 0))
+#else
+#define	L1_S_PROT_U		(L1_S_AP(AP_U))
+#define	L1_S_PROT_W		(L1_S_APX)		/* Write disable */
+#define	L1_S_PROT_MASK		(L1_S_PROT_W|L1_S_PROT_U)
+#define	L1_S_REF		(L1_S_AP(AP_REF))	/* Reference flag */
+#define	L1_S_WRITABLE(pd)	(!((pd) & L1_S_PROT_W))
+#define	L1_S_EXECUTABLE(pd)	(!((pd) & L1_S_XN))
+#define	L1_S_REFERENCED(pd)	((pd) & L1_S_REF)
+
+#define	L1_S_PROT(ku, pr)	(((((ku) == PTE_KERNEL) ? 0 : L1_S_PROT_U) | \
+				 (((pr) & VM_PROT_WRITE) ? 0 : L1_S_PROT_W) | \
+				 (((pr) & VM_PROT_EXECUTE) ? 0 : L1_S_XN)))
+
+#define	L2_L_PROT_MASK		(L2_APX|L2_AP0(0x3))
+#define	L2_L_PROT(ku, pr)	(L2_L_PROT_MASK & ~((((ku) == PTE_KERNEL) ? L2_S_PROT_U : 0) | \
+				 (((pr) & VM_PROT_WRITE) ? L2_APX : 0)))
+
+#define	L2_S_PROT(ku, pr)	(L2_S_PROT_MASK & ~((((ku) == PTE_KERNEL) ? L2_S_PROT_U : 0) | \
+				 (((pr) & VM_PROT_WRITE) ? L2_APX : 0)))
+
+#endif
+
+/*
+ * Macros to test if a mapping is mappable with an L1 Section mapping
+ * or an L2 Large Page mapping.
+ */
+#define	L1_S_MAPPABLE_P(va, pa, size)					\
+	((((va) | (pa)) & L1_S_OFFSET) == 0 && (size) >= L1_S_SIZE)
+
+#define	L2_L_MAPPABLE_P(va, pa, size)					\
+	((((va) | (pa)) & L2_L_OFFSET) == 0 && (size) >= L2_L_SIZE)
+
+/*
+ * Provide a fallback in case we were not able to determine it at
+ * compile-time.
+ */
+#ifndef PMAP_NEEDS_PTE_SYNC
+#define	PMAP_NEEDS_PTE_SYNC	pmap_needs_pte_sync
+#define	PMAP_INCLUDE_PTE_SYNC
+#endif
+
+#ifdef ARM_L2_PIPT
+#define _sync_l2(pte, size) 	cpu_l2cache_wb_range(vtophys(pte), size)
+#else
+#define _sync_l2(pte, size) 	cpu_l2cache_wb_range(pte, size)
+#endif
+
+#define	PTE_SYNC(pte)							\
+do {									\
+	if (PMAP_NEEDS_PTE_SYNC) {					\
+		cpu_dcache_wb_range((vm_offset_t)(pte), sizeof(pt_entry_t));\
+		cpu_drain_writebuf();					\
+		_sync_l2((vm_offset_t)(pte), sizeof(pt_entry_t));\
+	} else								\
+		cpu_drain_writebuf();					\
+} while (/*CONSTCOND*/0)
+
+#define	PTE_SYNC_RANGE(pte, cnt)					\
+do {									\
+	if (PMAP_NEEDS_PTE_SYNC) {					\
+		cpu_dcache_wb_range((vm_offset_t)(pte),			\
+		    (cnt) << 2); /* * sizeof(pt_entry_t) */		\
+		cpu_drain_writebuf();					\
+		_sync_l2((vm_offset_t)(pte),		 		\
+		    (cnt) << 2); /* * sizeof(pt_entry_t) */		\
+	} else								\
+		cpu_drain_writebuf();					\
+} while (/*CONSTCOND*/0)
+
+extern pt_entry_t		pte_l1_s_cache_mode;
+extern pt_entry_t		pte_l1_s_cache_mask;
+
+extern pt_entry_t		pte_l2_l_cache_mode;
+extern pt_entry_t		pte_l2_l_cache_mask;
+
+extern pt_entry_t		pte_l2_s_cache_mode;
+extern pt_entry_t		pte_l2_s_cache_mask;
+
+extern pt_entry_t		pte_l1_s_cache_mode_pt;
+extern pt_entry_t		pte_l2_l_cache_mode_pt;
+extern pt_entry_t		pte_l2_s_cache_mode_pt;
+
+extern pt_entry_t		pte_l2_s_prot_u;
+extern pt_entry_t		pte_l2_s_prot_w;
+extern pt_entry_t		pte_l2_s_prot_mask;
+
+extern pt_entry_t		pte_l1_s_proto;
+extern pt_entry_t		pte_l1_c_proto;
+extern pt_entry_t		pte_l2_s_proto;
+
+extern void (*pmap_copy_page_func)(vm_paddr_t, vm_paddr_t);
+extern void (*pmap_copy_page_offs_func)(vm_paddr_t a_phys,
+    vm_offset_t a_offs, vm_paddr_t b_phys, vm_offset_t b_offs, int cnt);
+extern void (*pmap_zero_page_func)(vm_paddr_t, int, int);
+
+#if (ARM_MMU_GENERIC + ARM_MMU_V6 + ARM_MMU_V7) != 0 || defined(CPU_XSCALE_81342)
+void	pmap_copy_page_generic(vm_paddr_t, vm_paddr_t);
+void	pmap_zero_page_generic(vm_paddr_t, int, int);
+
+void	pmap_pte_init_generic(void);
+#if defined(CPU_ARM9)
+void	pmap_pte_init_arm9(void);
+#endif /* CPU_ARM9 */
+#if defined(CPU_ARM10)
+void	pmap_pte_init_arm10(void);
+#endif /* CPU_ARM10 */
+#if (ARM_MMU_V6 + ARM_MMU_V7) != 0
+void	pmap_pte_init_mmu_v6(void);
+#endif /* (ARM_MMU_V6 + ARM_MMU_V7) != 0 */
+#endif /* (ARM_MMU_GENERIC + ARM_MMU_V6 + ARM_MMU_V7) != 0 */
+
+#if ARM_MMU_XSCALE == 1
+void	pmap_copy_page_xscale(vm_paddr_t, vm_paddr_t);
+void	pmap_zero_page_xscale(vm_paddr_t, int, int);
+
+void	pmap_pte_init_xscale(void);
+
+void	xscale_setup_minidata(vm_offset_t, vm_offset_t, vm_offset_t);
+
+void	pmap_use_minicache(vm_offset_t, vm_size_t);
+#endif /* ARM_MMU_XSCALE == 1 */
+#if defined(CPU_XSCALE_81342)
+#define ARM_HAVE_SUPERSECTIONS
+#endif
+
+#define PTE_KERNEL	0
+#define PTE_USER	1
+#define	l1pte_valid(pde)	((pde) != 0)
+#define	l1pte_section_p(pde)	(((pde) & L1_TYPE_MASK) == L1_TYPE_S)
+#define	l1pte_page_p(pde)	(((pde) & L1_TYPE_MASK) == L1_TYPE_C)
+#define	l1pte_fpage_p(pde)	(((pde) & L1_TYPE_MASK) == L1_TYPE_F)
+
+#define l2pte_index(v)		(((v) & L2_ADDR_BITS) >> L2_S_SHIFT)
+#define	l2pte_valid(pte)	((pte) != 0)
+#define	l2pte_pa(pte)		((pte) & L2_S_FRAME)
+#define l2pte_minidata(pte)	(((pte) & \
+				 (L2_B | L2_C | L2_XSCALE_T_TEX(TEX_XSCALE_X)))\
+				 == (L2_C | L2_XSCALE_T_TEX(TEX_XSCALE_X)))
+
+/* L1 and L2 page table macros */
+#define pmap_pde_v(pde)		l1pte_valid(*(pde))
+#define pmap_pde_section(pde)	l1pte_section_p(*(pde))
+#define pmap_pde_page(pde)	l1pte_page_p(*(pde))
+#define pmap_pde_fpage(pde)	l1pte_fpage_p(*(pde))
+
+#define	pmap_pte_v(pte)		l2pte_valid(*(pte))
+#define	pmap_pte_pa(pte)	l2pte_pa(*(pte))
+
+/*
+ * Flags that indicate attributes of pages or mappings of pages.
+ *
+ * The PVF_MOD and PVF_REF flags are stored in the mdpage for each
+ * page.  PVF_WIRED, PVF_WRITE, and PVF_NC are kept in individual
+ * pv_entry's for each page.  They live in the same "namespace" so
+ * that we can clear multiple attributes at a time.
+ *
+ * Note the "non-cacheable" flag generally means the page has
+ * multiple mappings in a given address space.
+ */
+#define	PVF_MOD		0x01		/* page is modified */
+#define	PVF_REF		0x02		/* page is referenced */
+#define	PVF_WIRED	0x04		/* mapping is wired */
+#define	PVF_WRITE	0x08		/* mapping is writable */
+#define	PVF_EXEC	0x10		/* mapping is executable */
+#define	PVF_NC		0x20		/* mapping is non-cacheable */
+#define	PVF_MWC		0x40		/* mapping is used multiple times in userland */
+#define	PVF_UNMAN	0x80		/* mapping is unmanaged */
+
+void vector_page_setprot(int);
+
+#define SECTION_CACHE	0x1
+#define SECTION_PT	0x2
+void	pmap_kenter_section(vm_offset_t, vm_paddr_t, int flags);
+#ifdef ARM_HAVE_SUPERSECTIONS
+void	pmap_kenter_supersection(vm_offset_t, uint64_t, int flags);
+#endif
+
+extern char *_tmppt;
+
+void	pmap_postinit(void);
+
+extern vm_paddr_t dump_avail[];
+#endif	/* _KERNEL */
+
+#endif	/* !LOCORE */
+
+#endif	/* !_MACHINE_PMAP_H_ */


Property changes on: trunk/sys/arm/include/pmap.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/pmc_mdep.h
===================================================================
--- trunk/sys/arm/include/pmc_mdep.h	                        (rev 0)
+++ trunk/sys/arm/include/pmc_mdep.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,79 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2009 Rui Paulo <rpaulo at FreeBSD.org>
+ * 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 ``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 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: stable/10/sys/arm/include/pmc_mdep.h 236997 2012-06-13 06:38:25Z fabient $
+ */
+
+#ifndef _MACHINE_PMC_MDEP_H_
+#define	_MACHINE_PMC_MDEP_H_
+
+#define	PMC_MDEP_CLASS_INDEX_XSCALE	1
+/*
+ * On the ARM platform we support the following PMCs.
+ *
+ * XSCALE	Intel XScale processors
+ */
+#include <dev/hwpmc/hwpmc_xscale.h>
+
+union pmc_md_op_pmcallocate {
+	uint64_t	__pad[4];
+};
+
+/* Logging */
+#define	PMCLOG_READADDR		PMCLOG_READ32
+#define	PMCLOG_EMITADDR		PMCLOG_EMIT32
+
+#ifdef	_KERNEL
+union pmc_md_pmc {
+	struct pmc_md_xscale_pmc	pm_xscale;
+};
+
+#define	PMC_IN_KERNEL_STACK(S,START,END)		\
+	((S) >= (START) && (S) < (END))
+#define	PMC_IN_KERNEL(va) (((va) >= USRSTACK) &&	\
+	((va) < VM_MAX_KERNEL_ADDRESS))
+
+#define	PMC_IN_USERSPACE(va) ((va) <= VM_MAXUSER_ADDRESS)
+
+#define	PMC_TRAPFRAME_TO_PC(TF)		((TF)->tf_pc)
+#define	PMC_TRAPFRAME_TO_FP(TF)		((TF)->tf_r11)
+#define	PMC_TRAPFRAME_TO_SVC_SP(TF)	((TF)->tf_svc_sp)
+#define	PMC_TRAPFRAME_TO_USR_SP(TF)	((TF)->tf_usr_sp)
+
+/* Build a fake kernel trapframe from current instruction pointer. */
+#define PMC_FAKE_TRAPFRAME(TF)						\
+	do {								\
+	__asm __volatile("mov %0, pc" : "=r" ((TF)->tf_pc));		\
+	} while (0)
+
+/*
+ * Prototypes
+ */
+struct pmc_mdep *pmc_xscale_initialize(void);
+void		pmc_xscale_finalize(struct pmc_mdep *_md);
+#endif /* _KERNEL */
+
+#endif /* !_MACHINE_PMC_MDEP_H_ */


Property changes on: trunk/sys/arm/include/pmc_mdep.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/proc.h
===================================================================
--- trunk/sys/arm/include/proc.h	                        (rev 0)
+++ trunk/sys/arm/include/proc.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,83 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1991 Regents of the University of California.
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the University of
+ *      California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ *      from: @(#)proc.h        7.1 (Berkeley) 5/15/91
+ *	from: FreeBSD: src/sys/i386/include/proc.h,v 1.11 2001/06/29
+ * $FreeBSD: stable/10/sys/arm/include/proc.h 278656 2015-02-13 02:02:12Z ian $
+ */
+
+#ifndef	_MACHINE_PROC_H_
+#define	_MACHINE_PROC_H_
+
+#include <machine/utrap.h>
+
+struct md_utrap {
+	utrap_entry_t *ut_precise[UT_MAX];	/* must be first */
+	int	ut_refcnt;
+};
+
+struct mdthread {
+	int	md_spinlock_count;	/* (k) */
+	register_t md_saved_cspr;	/* (k) */
+	register_t md_spurflt_addr;     /* (k) Spurious page fault address. */
+	int md_ptrace_instr;
+	int md_ptrace_addr;
+	register_t md_tp;
+	void *md_ras_start;
+	void *md_ras_end;
+};
+
+struct mdproc {
+	struct	md_utrap *md_utrap;
+	void	*md_sigtramp;
+};
+
+#ifdef __ARM_EABI__
+#define	KINFO_PROC_SIZE 816
+#else
+#define	KINFO_PROC_SIZE 792
+#endif
+
+#define MAXARGS	8
+struct syscall_args {
+	u_int code;
+	struct sysent *callp;
+	register_t args[MAXARGS];
+	int narg;
+	u_int nap;
+#ifndef __ARM_EABI__
+	u_int32_t insn;
+#endif
+};
+
+#endif /* !_MACHINE_PROC_H_ */


Property changes on: trunk/sys/arm/include/proc.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/profile.h
===================================================================
--- trunk/sys/arm/include/profile.h	                        (rev 0)
+++ trunk/sys/arm/include/profile.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,126 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ *	@(#)profile.h	8.1 (Berkeley) 6/11/93
+ * $FreeBSD: stable/10/sys/arm/include/profile.h 278652 2015-02-13 00:49:47Z ian $
+ */
+
+#ifndef _MACHINE_PROFILE_H_
+#define	_MACHINE_PROFILE_H_
+
+/*
+ * Config generates something to tell the compiler to align functions on 32
+ * byte boundaries.  A strict alignment is good for keeping the tables small.
+ */
+#define	FUNCTION_ALIGNMENT	16
+
+
+#define	_MCOUNT_DECL void mcount
+
+typedef u_long	fptrdiff_t;
+
+/*
+ * Cannot implement mcount in C as GCC will trash the ip register when it
+ * pushes a trapframe. Pity we cannot insert assembly before the function
+ * prologue.
+ */
+
+#ifndef PLTSYM
+#define	PLTSYM
+#endif
+
+#define	MCOUNT								\
+	__asm__(".text");						\
+	__asm__(".align	2");						\
+	__asm__(".type	__mcount ,%function");				\
+	__asm__(".global	__mcount");				\
+	__asm__("__mcount:");						\
+	/*								\
+	 * Preserve registers that are trashed during mcount		\
+	 */								\
+	__asm__("stmfd	sp!, {r0-r3, ip, lr}");				\
+	/*								\
+	 * find the return address for mcount,				\
+	 * and the return address for mcount's caller.			\
+	 *								\
+	 * frompcindex = pc pushed by call into self.			\
+	 */								\
+	__asm__("mov	r0, ip");					\
+	/*								\
+	 * selfpc = pc pushed by mcount call				\
+	 */								\
+	__asm__("mov	r1, lr");					\
+	/*								\
+	 * Call the real mcount code					\
+	 */								\
+	__asm__("bl	mcount");					\
+	/*								\
+	 * Restore registers that were trashed during mcount		\
+	 */								\
+	__asm__("ldmfd	sp!, {r0-r3, lr, pc}");
+void bintr(void);
+void btrap(void);
+void eintr(void);
+void user(void);
+
+#define	MCOUNT_FROMPC_USER(pc)					\
+	((pc < (uintfptr_t)VM_MAXUSER_ADDRESS) ? (uintfptr_t)user : pc)
+
+#define	MCOUNT_FROMPC_INTR(pc)					\
+	((pc >= (uintfptr_t)btrap && pc < (uintfptr_t)eintr) ?	\
+	    ((pc >= (uintfptr_t)bintr) ? (uintfptr_t)bintr :	\
+		(uintfptr_t)btrap) : ~0U)
+
+
+#ifdef _KERNEL
+
+#define	MCOUNT_DECL(s)	register_t s;
+
+#include <machine/asm.h>
+#include <machine/cpufunc.h>
+/*
+ * splhigh() and splx() are heavyweight, and call mcount().  Therefore
+ * we disabled interrupts (IRQ, but not FIQ) directly on the CPU.
+ *
+ * We're lucky that the CPSR and 's' both happen to be 'int's.
+ */
+#define	MCOUNT_ENTER(s)	{s = intr_disable(); }	/* kill IRQ */
+#define	MCOUNT_EXIT(s)	{intr_restore(s); }	/* restore old value */
+
+void	mcount(uintfptr_t frompc, uintfptr_t selfpc);
+
+#else
+typedef	u_int	uintfptr_t;
+#endif /* _KERNEL */
+
+#endif /* !_MACHINE_PROFILE_H_ */


Property changes on: trunk/sys/arm/include/profile.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/psl.h
===================================================================
--- trunk/sys/arm/include/psl.h	                        (rev 0)
+++ trunk/sys/arm/include/psl.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,83 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: psl.h,v 1.6 2003/06/16 20:00:58 thorpej Exp $	*/
+
+/*-
+ * Copyright (c) 1995 Mark Brinicombe.
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Mark Brinicombe
+ *	for the NetBSD Project.
+ * 4. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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.
+ *
+ * RiscBSD kernel project
+ *
+ * psl.h
+ *
+ * spl prototypes.
+ * Eventually this will become a set of defines.
+ *
+ * Created      : 21/07/95
+ *
+ * $FreeBSD: stable/10/sys/arm/include/psl.h 266084 2014-05-14 19:18:58Z ian $
+ */
+
+#ifndef _MACHINE_PSL_H_
+#define _MACHINE_PSL_H_
+
+/*
+ * These are the different SPL states
+ *
+ * Each state has an interrupt mask associated with it which
+ * indicate which interrupts are allowed.
+ */
+
+#define _SPL_0		0
+#define _SPL_SOFTCLOCK	1
+#define _SPL_SOFTNET	2
+#define _SPL_BIO	3
+#define _SPL_NET	4
+#define _SPL_SOFTSERIAL	5
+#define _SPL_TTY	6
+#define _SPL_VM		7
+#define _SPL_AUDIO	8
+#define _SPL_CLOCK	9
+#define _SPL_STATCLOCK	10
+#define _SPL_HIGH	11
+#define _SPL_SERIAL	12
+#define _SPL_LEVELS	13
+
+#ifdef _KERNEL
+#ifndef _LOCORE
+extern int current_spl_level;
+
+extern u_int spl_masks[_SPL_LEVELS + 1];
+extern u_int spl_smasks[_SPL_LEVELS];
+#endif /* _LOCORE */
+#endif /* _KERNEL */
+
+#endif /* _ARM_PSL_H_ */
+/* End of psl.h */


Property changes on: trunk/sys/arm/include/psl.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/pte.h
===================================================================
--- trunk/sys/arm/include/pte.h	                        (rev 0)
+++ trunk/sys/arm/include/pte.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,357 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: pte.h,v 1.1 2001/11/23 17:39:04 thorpej Exp $	*/
+
+/*-
+ * Copyright (c) 1994 Mark Brinicombe.
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the RiscBSD team.
+ * 4. The name "RiscBSD" nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY RISCBSD ``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 RISCBSD 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: stable/10/sys/arm/include/pte.h 254918 2013-08-26 17:12:30Z raj $
+ */
+
+#ifndef _MACHINE_PTE_H_
+#define _MACHINE_PTE_H_
+
+#ifndef LOCORE
+typedef	uint32_t	pd_entry_t;		/* page directory entry */
+typedef	uint32_t	pt_entry_t;		/* page table entry */
+#endif
+
+#define PG_FRAME	0xfffff000
+
+/* The PT_SIZE definition is misleading... A page table is only 0x400
+ * bytes long. But since VM mapping can only be done to 0x1000 a single
+ * 1KB blocks cannot be steered to a va by itself. Therefore the
+ * pages tables are allocated in blocks of 4. i.e. if a 1 KB block
+ * was allocated for a PT then the other 3KB would also get mapped
+ * whenever the 1KB was mapped.
+ */
+
+#define PT_RSIZE	0x0400		/* Real page table size */
+#define PT_SIZE		0x1000
+#define PD_SIZE		0x4000
+
+/* Page table types and masks */
+#define L1_PAGE		0x01	/* L1 page table mapping */
+#define L1_SECTION	0x02	/* L1 section mapping */
+#define L1_FPAGE	0x03	/* L1 fine page mapping */
+#define L1_MASK		0x03	/* Mask for L1 entry type */
+#define L2_LPAGE	0x01	/* L2 large page (64KB) */
+#define L2_SPAGE	0x02	/* L2 small page (4KB) */
+#define L2_MASK		0x03	/* Mask for L2 entry type */
+#define L2_INVAL	0x00	/* L2 invalid type */
+
+/* L1 and L2 address masks */
+#define L1_ADDR_MASK		0xfffffc00
+#define L2_ADDR_MASK		0xfffff000
+
+/*
+ * The ARM MMU architecture was introduced with ARM v3 (previous ARM
+ * architecture versions used an optional off-CPU memory controller
+ * to perform address translation).
+ *
+ * The ARM MMU consists of a TLB and translation table walking logic.
+ * There is typically one TLB per memory interface (or, put another
+ * way, one TLB per software-visible cache).
+ *
+ * The ARM MMU is capable of mapping memory in the following chunks:
+ *
+ *	1M	Sections (L1 table)
+ *
+ *	64K	Large Pages (L2 table)
+ *
+ *	4K	Small Pages (L2 table)
+ *
+ *	1K	Tiny Pages (L2 table)
+ *
+ * There are two types of L2 tables: Coarse Tables and Fine Tables.
+ * Coarse Tables can map Large and Small Pages.  Fine Tables can
+ * map Tiny Pages.
+ *
+ * Coarse Tables can define 4 Subpages within Large and Small pages.
+ * Subpages define different permissions for each Subpage within
+ * a Page.
+ *
+ * Coarse Tables are 1K in length.  Fine tables are 4K in length.
+ *
+ * The Translation Table Base register holds the pointer to the
+ * L1 Table.  The L1 Table is a 16K contiguous chunk of memory
+ * aligned to a 16K boundary.  Each entry in the L1 Table maps
+ * 1M of virtual address space, either via a Section mapping or
+ * via an L2 Table.
+ *
+ * In addition, the Fast Context Switching Extension (FCSE) is available
+ * on some ARM v4 and ARM v5 processors.  FCSE is a way of eliminating
+ * TLB/cache flushes on context switch by use of a smaller address space
+ * and a "process ID" that modifies the virtual address before being
+ * presented to the translation logic.
+ */
+
+/* ARMv6 super-sections. */
+#define L1_SUP_SIZE	0x01000000	/* 16M */
+#define L1_SUP_OFFSET	(L1_SUP_SIZE - 1)
+#define L1_SUP_FRAME	(~L1_SUP_OFFSET)
+#define L1_SUP_SHIFT	24
+
+#define	L1_S_SIZE	0x00100000	/* 1M */
+#define	L1_S_OFFSET	(L1_S_SIZE - 1)
+#define	L1_S_FRAME	(~L1_S_OFFSET)
+#define	L1_S_SHIFT	20
+
+#define	L2_L_SIZE	0x00010000	/* 64K */
+#define	L2_L_OFFSET	(L2_L_SIZE - 1)
+#define	L2_L_FRAME	(~L2_L_OFFSET)
+#define	L2_L_SHIFT	16
+
+#define	L2_S_SIZE	0x00001000	/* 4K */
+#define	L2_S_OFFSET	(L2_S_SIZE - 1)
+#define	L2_S_FRAME	(~L2_S_OFFSET)
+#define	L2_S_SHIFT	12
+
+#define	L2_T_SIZE	0x00000400	/* 1K */
+#define	L2_T_OFFSET	(L2_T_SIZE - 1)
+#define	L2_T_FRAME	(~L2_T_OFFSET)
+#define	L2_T_SHIFT	10
+
+/*
+ * The NetBSD VM implementation only works on whole pages (4K),
+ * whereas the ARM MMU's Coarse tables are sized in terms of 1K
+ * (16K L1 table, 1K L2 table).
+ *
+ * So, we allocate L2 tables 4 at a time, thus yielding a 4K L2
+ * table.
+ */
+#define	L1_ADDR_BITS	0xfff00000	/* L1 PTE address bits */
+#define	L2_ADDR_BITS	0x000ff000	/* L2 PTE address bits */
+
+#define	L1_TABLE_SIZE	0x4000		/* 16K */
+#define	L2_TABLE_SIZE	0x1000		/* 4K */
+/*
+ * The new pmap deals with the 1KB coarse L2 tables by
+ * allocating them from a pool. Until every port has been converted,
+ * keep the old L2_TABLE_SIZE define lying around. Converted ports
+ * should use L2_TABLE_SIZE_REAL until then.
+ */
+#define	L2_TABLE_SIZE_REAL	0x400	/* 1K */
+
+/* Total number of page table entries in L2 table */
+#define	L2_PTE_NUM_TOTAL	(L2_TABLE_SIZE_REAL / sizeof(pt_entry_t))
+
+/*
+ * ARM L1 Descriptors
+ */
+
+#define	L1_TYPE_INV	0x00		/* Invalid (fault) */
+#define	L1_TYPE_C	0x01		/* Coarse L2 */
+#define	L1_TYPE_S	0x02		/* Section */
+#define	L1_TYPE_F	0x03		/* Fine L2 */
+#define	L1_TYPE_MASK	0x03		/* mask of type bits */
+
+/* L1 Section Descriptor */
+#define	L1_S_B		0x00000004	/* bufferable Section */
+#define	L1_S_C		0x00000008	/* cacheable Section */
+#define	L1_S_IMP	0x00000010	/* implementation defined */
+#define	L1_S_XN		(1 << 4)	/* execute not */
+#define	L1_S_DOM(x)	((x) << 5)	/* domain */
+#define	L1_S_DOM_MASK	L1_S_DOM(0xf)
+#define	L1_S_AP(x)	((x) << 10)	/* access permissions */
+#define	L1_S_ADDR_MASK	0xfff00000	/* phys address of section */
+#define	L1_S_TEX(x)	(((x) & 0x7) << 12)	/* Type Extension */
+#define	L1_S_TEX_MASK	(0x7 << 12)	/* Type Extension */
+#define	L1_S_APX	(1 << 15)
+#define	L1_SHARED	(1 << 16)
+
+#define	L1_S_XSCALE_P	0x00000200	/* ECC enable for this section */
+#define	L1_S_XSCALE_TEX(x) ((x) << 12)	/* Type Extension */
+
+#define L1_S_SUPERSEC	((1) << 18)	/* Section is a super-section. */
+
+/* L1 Coarse Descriptor */
+#define	L1_C_IMP0	0x00000004	/* implementation defined */
+#define	L1_C_IMP1	0x00000008	/* implementation defined */
+#define	L1_C_IMP2	0x00000010	/* implementation defined */
+#define	L1_C_DOM(x)	((x) << 5)	/* domain */
+#define	L1_C_DOM_MASK	L1_C_DOM(0xf)
+#define	L1_C_ADDR_MASK	0xfffffc00	/* phys address of L2 Table */
+
+#define	L1_C_XSCALE_P	0x00000200	/* ECC enable for this section */
+
+/* L1 Fine Descriptor */
+#define	L1_F_IMP0	0x00000004	/* implementation defined */
+#define	L1_F_IMP1	0x00000008	/* implementation defined */
+#define	L1_F_IMP2	0x00000010	/* implementation defined */
+#define	L1_F_DOM(x)	((x) << 5)	/* domain */
+#define	L1_F_DOM_MASK	L1_F_DOM(0xf)
+#define	L1_F_ADDR_MASK	0xfffff000	/* phys address of L2 Table */
+
+#define	L1_F_XSCALE_P	0x00000200	/* ECC enable for this section */
+
+/*
+ * ARM L2 Descriptors
+ */
+
+#define	L2_TYPE_INV	0x00		/* Invalid (fault) */
+#define	L2_TYPE_L	0x01		/* Large Page */
+#define	L2_TYPE_S	0x02		/* Small Page */
+#define	L2_TYPE_T	0x03		/* Tiny Page */
+#define	L2_TYPE_MASK	0x03		/* mask of type bits */
+
+	/*
+	 * This L2 Descriptor type is available on XScale processors
+	 * when using a Coarse L1 Descriptor.  The Extended Small
+	 * Descriptor has the same format as the XScale Tiny Descriptor,
+	 * but describes a 4K page, rather than a 1K page.
+	 */
+#define	L2_TYPE_XSCALE_XS 0x03		/* XScale Extended Small Page */
+
+#define	L2_B		0x00000004	/* Bufferable page */
+#define	L2_C		0x00000008	/* Cacheable page */
+#define	L2_AP0(x)	((x) << 4)	/* access permissions (sp 0) */
+#define	L2_AP1(x)	((x) << 6)	/* access permissions (sp 1) */
+#define	L2_AP2(x)	((x) << 8)	/* access permissions (sp 2) */
+#define	L2_AP3(x)	((x) << 10)	/* access permissions (sp 3) */
+
+#define	L2_SHARED	(1 << 10)
+#define	L2_APX		(1 << 9)
+#define	L2_XN		(1 << 0)
+#define	L2_L_TEX_MASK	(0x7 << 12)	/* Type Extension */
+#define	L2_L_TEX(x)	(((x) & 0x7) << 12)
+#define	L2_S_TEX_MASK	(0x7 << 6)	/* Type Extension */
+#define	L2_S_TEX(x)	(((x) & 0x7) << 6)
+
+#define	L2_XSCALE_L_TEX(x) ((x) << 12)	/* Type Extension */
+#define L2_XSCALE_L_S(x)   (1 << 15)	/* Shared */
+#define	L2_XSCALE_T_TEX(x) ((x) << 6)	/* Type Extension */
+
+/*
+ * Access Permissions for L1 and L2 Descriptors.
+ */
+#define	AP_W		0x01		/* writable */
+#define	AP_REF		0x01		/* referenced flag */
+#define	AP_U		0x02		/* user */
+
+/*
+ * Short-hand for common AP_* constants.
+ *
+ * Note: These values assume the S (System) bit is set and
+ * the R (ROM) bit is clear in CP15 register 1.
+ */
+#define	AP_KR		0x00		/* kernel read */
+#define	AP_KRW		0x01		/* kernel read/write */
+#define	AP_KRWUR	0x02		/* kernel read/write usr read */
+#define	AP_KRWURW	0x03		/* kernel read/write usr read/write */
+
+/*
+ * Domain Types for the Domain Access Control Register.
+ */
+#define	DOMAIN_FAULT	0x00		/* no access */
+#define	DOMAIN_CLIENT	0x01		/* client */
+#define	DOMAIN_RESERVED	0x02		/* reserved */
+#define	DOMAIN_MANAGER	0x03		/* manager */
+
+/*
+ * Type Extension bits for XScale processors.
+ *
+ * Behavior of C and B when X == 0:
+ *
+ * C B  Cacheable  Bufferable  Write Policy  Line Allocate Policy
+ * 0 0      N          N            -                 -
+ * 0 1      N          Y            -                 -
+ * 1 0      Y          Y       Write-through    Read Allocate
+ * 1 1      Y          Y        Write-back      Read Allocate
+ *
+ * Behavior of C and B when X == 1:
+ * C B  Cacheable  Bufferable  Write Policy  Line Allocate Policy
+ * 0 0      -          -            -                 -           DO NOT USE
+ * 0 1      N          Y            -                 -
+ * 1 0  Mini-Data      -            -                 -
+ * 1 1      Y          Y        Write-back       R/W Allocate
+ */
+#define	TEX_XSCALE_X	0x01		/* X modifies C and B */
+#define TEX_XSCALE_E	0x02
+#define TEX_XSCALE_T	0x04
+
+/* Xscale core 3 */
+
+/*
+ *
+ * Cache attributes with L2 present, S = 0
+ * T E X C B   L1 i-cache L1 d-cache L1 DC WP  L2 cacheable write coalesce
+ * 0 0 0 0 0 	N	  N 		- 	N		N
+ * 0 0 0 0 1	N	  N		-	N		Y
+ * 0 0 0 1 0	Y	  Y		WT	N		Y
+ * 0 0 0 1 1	Y	  Y		WB	Y		Y
+ * 0 0 1 0 0	N	  N		-	Y		Y
+ * 0 0 1 0 1	N	  N		-	N		N
+ * 0 0 1 1 0	Y	  Y		-	-		N
+ * 0 0 1 1 1	Y	  Y		WT	Y		Y
+ * 0 1 0 0 0	N	  N		-	N		N
+ * 0 1 0 0 1	N/A	N/A		N/A	N/A		N/A
+ * 0 1 0 1 0	N/A	N/A		N/A	N/A		N/A
+ * 0 1 0 1 1	N/A	N/A		N/A	N/A		N/A
+ * 0 1 1 X X	N/A	N/A		N/A	N/A		N/A
+ * 1 X 0 0 0	N	  N		-	N		Y
+ * 1 X 0 0 1	Y	  N		WB	N		Y
+ * 1 X 0 1 0	Y	  N		WT	N		Y
+ * 1 X 0 1 1	Y	  N		WB	Y		Y
+ * 1 X 1 0 0	N	  N		-	Y		Y
+ * 1 X 1 0 1	Y	  Y		WB	Y		Y
+ * 1 X 1 1 0	Y	  Y		WT	Y		Y
+ * 1 X 1 1 1	Y	  Y		WB	Y		Y
+ *
+ *
+ *
+ *
+  * Cache attributes with L2 present, S = 1
+ * T E X C B   L1 i-cache L1 d-cache L1 DC WP  L2 cacheable write coalesce
+ * 0 0 0 0 0 	N	  N 		- 	N		N
+ * 0 0 0 0 1	N	  N		-	N		Y
+ * 0 0 0 1 0	Y	  Y		-	N		Y
+ * 0 0 0 1 1	Y	  Y		WT	Y		Y
+ * 0 0 1 0 0	N	  N		-	Y		Y
+ * 0 0 1 0 1	N	  N		-	N		N
+ * 0 0 1 1 0	Y	  Y		-	-		N
+ * 0 0 1 1 1	Y	  Y		WT	Y		Y
+ * 0 1 0 0 0	N	  N		-	N		N
+ * 0 1 0 0 1	N/A	N/A		N/A	N/A		N/A
+ * 0 1 0 1 0	N/A	N/A		N/A	N/A		N/A
+ * 0 1 0 1 1	N/A	N/A		N/A	N/A		N/A
+ * 0 1 1 X X	N/A	N/A		N/A	N/A		N/A
+ * 1 X 0 0 0	N	  N		-	N		Y
+ * 1 X 0 0 1	Y	  N		-	N		Y
+ * 1 X 0 1 0	Y	  N		-	N		Y
+ * 1 X 0 1 1	Y	  N		-	Y		Y
+ * 1 X 1 0 0	N	  N		-	Y		Y
+ * 1 X 1 0 1	Y	  Y		WT	Y		Y
+ * 1 X 1 1 0	Y	  Y		WT	Y		Y
+ * 1 X 1 1 1	Y	  Y		WT	Y		Y
+ */
+#endif /* !_MACHINE_PTE_H_ */
+
+/* End of pte.h */


Property changes on: trunk/sys/arm/include/pte.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/ptrace.h
===================================================================
--- trunk/sys/arm/include/ptrace.h	                        (rev 0)
+++ trunk/sys/arm/include/ptrace.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,9 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: ptrace.h,v 1.2 2001/02/23 21:23:52 reinoud Exp $	*/
+/* $FreeBSD: stable/10/sys/arm/include/ptrace.h 129198 2004-05-14 11:46:45Z cognet $ */
+
+#ifndef _MACHINE_PTRACE_H_
+#define _MACHINE_PTRACE_H_
+
+#endif /* !_MACHINE_PTRACE_H */
+


Property changes on: trunk/sys/arm/include/ptrace.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/reg.h
===================================================================
--- trunk/sys/arm/include/reg.h	                        (rev 0)
+++ trunk/sys/arm/include/reg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,35 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: reg.h,v 1.2 2001/02/23 21:23:52 reinoud Exp $	*/
+/* $FreeBSD: stable/10/sys/arm/include/reg.h 137229 2004-11-04 19:20:54Z cognet $ */
+#ifndef MACHINE_REG_H
+#define MACHINE_REG_H
+
+#include <machine/fp.h>
+
+struct reg {
+	unsigned int r[13];
+	unsigned int r_sp;
+	unsigned int r_lr;
+	unsigned int r_pc;
+	unsigned int r_cpsr;
+};
+
+struct fpreg {
+	unsigned int fpr_fpsr;
+	fp_reg_t fpr[8];
+};
+
+struct dbreg {
+	        unsigned int  dr[8];    /* debug registers */
+};
+
+#ifdef _KERNEL
+int     fill_regs(struct thread *, struct reg *);
+int     set_regs(struct thread *, struct reg *);
+int     fill_fpregs(struct thread *, struct fpreg *);
+int     set_fpregs(struct thread *, struct fpreg *);
+int     fill_dbregs(struct thread *, struct dbreg *);
+int     set_dbregs(struct thread *, struct dbreg *);
+#endif
+
+#endif /* !MACHINE_REG_H */


Property changes on: trunk/sys/arm/include/reg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/reloc.h
===================================================================
--- trunk/sys/arm/include/reloc.h	                        (rev 0)
+++ trunk/sys/arm/include/reloc.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,54 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ *	@(#)reloc.h	8.1 (Berkeley) 6/10/93
+ * $FreeBSD: stable/10/sys/arm/include/reloc.h 129198 2004-05-14 11:46:45Z cognet $
+ */
+
+#ifndef _MACHINE_RELOC_H_
+#define _MACHINE_RELOC_H_
+
+/* Relocation format. */
+struct relocation_info {
+	int r_address;			  /* offset in text or data segment */
+	unsigned int   r_symbolnum : 24,  /* ordinal number of add symbol */
+			   r_pcrel :  1,  /* 1 if value should be pc-relative */
+			  r_length :  2,  /* log base 2 of value's width */
+			  r_extern :  1,  /* 1 if need to add symbol to value */
+			 r_baserel :  1,  /* linkage table relative */
+			r_jmptable :  1,  /* relocate to jump table */
+			r_relative :  1,  /* load address relative */
+			    r_copy :  1;  /* run time copy */
+};
+
+#endif


Property changes on: trunk/sys/arm/include/reloc.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/resource.h
===================================================================
--- trunk/sys/arm/include/resource.h	                        (rev 0)
+++ trunk/sys/arm/include/resource.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,47 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright 1998 Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that both the above copyright notice and this
+ * permission notice appear in all copies, that both the above
+ * copyright notice and this permission notice appear in all
+ * supporting documentation, and that the name of M.I.T. not be used
+ * in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.  M.I.T. makes
+ * no representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''.  M.I.T. DISCLAIMS
+ * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
+ * SHALL M.I.T. 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: stable/10/sys/arm/include/resource.h 236992 2012-06-13 05:02:51Z imp $
+ */
+
+#ifndef _MACHINE_RESOURCE_H_
+#define	_MACHINE_RESOURCE_H_	1
+
+/*
+ * Definitions of resource types for Intel Architecture machines
+ * with support for legacy ISA devices and drivers.
+ */
+
+#define	SYS_RES_IRQ	1	/* interrupt lines */
+#define	SYS_RES_DRQ	2	/* isa dma lines */
+#define	SYS_RES_MEMORY	3	/* i/o memory */
+#define	SYS_RES_IOPORT	4	/* i/o ports */
+#define	SYS_RES_GPIO	5	/* general purpose i/o */
+
+#endif /* !_MACHINE_RESOURCE_H_ */


Property changes on: trunk/sys/arm/include/resource.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/runq.h
===================================================================
--- trunk/sys/arm/include/runq.h	                        (rev 0)
+++ trunk/sys/arm/include/runq.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,47 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2001 Jake Burkholder <jake at FreeBSD.org>
+ * 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: stable/10/sys/arm/include/runq.h 139735 2005-01-05 21:58:49Z imp $
+ */
+
+#ifndef	_MACHINE_RUNQ_H_
+#define	_MACHINE_RUNQ_H_
+
+#define	RQB_LEN		(2)		/* Number of priority status words. */
+#define	RQB_L2BPW	(5)		/* Log2(sizeof(rqb_word_t) * NBBY)). */
+#define	RQB_BPW		(1<<RQB_L2BPW)	/* Bits in an rqb_word_t. */
+
+#define	RQB_BIT(pri)	(1 << ((pri) & (RQB_BPW - 1)))
+#define	RQB_WORD(pri)	((pri) >> RQB_L2BPW)
+
+#define	RQB_FFS(word)	(ffs(word) - 1)
+
+/*
+ * Type of run queue status word.
+ */
+typedef	u_int32_t	rqb_word_t;
+
+#endif


Property changes on: trunk/sys/arm/include/runq.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/sc_machdep.h
===================================================================
--- trunk/sys/arm/include/sc_machdep.h	                        (rev 0)
+++ trunk/sys/arm/include/sc_machdep.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,72 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2003 Jake Burkholder.
+ * 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: stable/10/sys/arm/include/sc_machdep.h 239696 2012-08-25 23:59:31Z gonzo $
+ */
+
+#ifndef	_MACHINE_SC_MACHDEP_H_
+#define	_MACHINE_SC_MACHDEP_H_
+
+/* Color attributes for foreground text */
+
+#define	FG_BLACK		0x0
+#define	FG_BLUE			0x1
+#define	FG_GREEN		0x2
+#define	FG_CYAN			0x3
+#define	FG_RED			0x4
+#define	FG_MAGENTA		0x5
+#define	FG_BROWN		0x6
+#define	FG_LIGHTGREY		0x7	/* aka white */
+#define	FG_DARKGREY		0x8
+#define	FG_LIGHTBLUE		0x9
+#define	FG_LIGHTGREEN		0xa
+#define	FG_LIGHTCYAN		0xb
+#define	FG_LIGHTRED		0xc
+#define	FG_LIGHTMAGENTA		0xd
+#define	FG_YELLOW		0xe
+#define	FG_WHITE		0xf	/* aka bright white */
+#define	FG_BLINK		0x80
+
+/* Color attributes for text background */
+
+#define	BG_BLACK		0x00
+#define	BG_BLUE			0x10
+#define	BG_GREEN		0x20
+#define	BG_CYAN			0x30
+#define	BG_RED			0x40
+#define	BG_MAGENTA		0x50
+#define	BG_BROWN		0x60
+#define	BG_LIGHTGREY		0x70
+#define	BG_DARKGREY		0x80
+#define	BG_LIGHTBLUE		0x90
+#define	BG_LIGHTGREEN		0xa0
+#define	BG_LIGHTCYAN		0xb0
+#define	BG_LIGHTRED		0xc0
+#define	BG_LIGHTMAGENTA		0xd0
+#define	BG_YELLOW		0xe0
+#define	BG_WHITE		0xf0
+
+#endif /* !_MACHINE_SC_MACHDEP_H_ */


Property changes on: trunk/sys/arm/include/sc_machdep.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/setjmp.h
===================================================================
--- trunk/sys/arm/include/setjmp.h	                        (rev 0)
+++ trunk/sys/arm/include/setjmp.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,108 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: setjmp.h,v 1.5 2013/01/11 13:56:32 matt Exp $	*/
+/* $FreeBSD: stable/10/sys/arm/include/setjmp.h 251517 2013-06-08 07:16:22Z andrew $ */
+
+/*
+ * machine/setjmp.h: machine dependent setjmp-related information.
+ */
+
+#ifndef _MACHINE_SETJMP_H_
+#define _MACHINE_SETJMP_H_
+
+#define	_JBLEN	64		/* size, in longs, of a jmp_buf */
+
+/*
+ * NOTE: The internal structure of a jmp_buf is *PRIVATE*
+ *       This information is provided as there is software
+ *       that fiddles with this with obtain the stack pointer
+ *	 (yes really ! and its commercial !).
+ *
+ * Description of the setjmp buffer
+ *
+ * word  0	magic number	(dependent on creator)
+ *	13	fpscr		vfp status control register
+ *	14	r4		register 4
+ *	15	r5		register 5
+ *	16	r6		register 6
+ *	17	r7		register 7
+ *	18	r8		register 8
+ *	19	r9		register 9
+ *	20	r10		register 10 (sl)
+ *	21	r11		register 11 (fp)
+ *	22	r12		register 12 (ip)
+ *	23	r13		register 13 (sp)
+ *	24	r14		register 14 (lr)
+ *	25	signal mask	(dependent on magic)
+ *	26	(con't)
+ *	27	(con't)
+ *	28	(con't)
+ *	32-33	d8		(vfp register d8)
+ *	34-35	d9		(vfp register d9)
+ *	36-37	d10		(vfp register d10)
+ *	38-39	d11		(vfp register d11)
+ *	40-41	d12		(vfp register d12)
+ *	42-43	d13		(vfp register d13)
+ *	44-45	d14		(vfp register d14)
+ *	46-47	d15		(vfp register d15)
+ *
+ * The magic number number identifies the jmp_buf and
+ * how the buffer was created as well as providing
+ * a sanity check
+ *
+ * A side note I should mention - Please do not tamper
+ * with the floating point fields. While they are
+ * always saved and restored at the moment this cannot
+ * be garenteed especially if the compiler happens
+ * to be generating soft-float code so no fp
+ * registers will be used.
+ *
+ * Whilst this can be seen an encouraging people to
+ * use the setjmp buffer in this way I think that it
+ * is for the best then if changes occur compiles will
+ * break rather than just having new builds falling over
+ * mysteriously.
+ */
+
+#define _JB_MAGIC__SETJMP	0x4278f500
+#define _JB_MAGIC_SETJMP	0x4278f501
+#define _JB_MAGIC__SETJMP_VFP	0x4278f502
+#define _JB_MAGIC_SETJMP_VFP	0x4278f503
+
+/* Valid for all jmp_buf's */
+
+#define _JB_MAGIC		 0
+#define _JB_REG_FPSCR		13
+#define _JB_REG_R4		14
+#define _JB_REG_R5		15
+#define _JB_REG_R6		16
+#define _JB_REG_R7		17
+#define _JB_REG_R8		18
+#define _JB_REG_R9		19
+#define _JB_REG_R10		20
+#define _JB_REG_R11		21
+#define _JB_REG_R12		22
+#define _JB_REG_R13		23
+#define _JB_REG_R14		24
+
+/* Only valid with the _JB_MAGIC_SETJMP magic */
+
+#define _JB_SIGMASK		25
+
+#define	_JB_REG_D8		32
+#define	_JB_REG_D9		34
+#define	_JB_REG_D10		36
+#define	_JB_REG_D11		38
+#define	_JB_REG_D12		40
+#define	_JB_REG_D13		42
+#define	_JB_REG_D14		44
+#define	_JB_REG_D15		46
+
+#ifndef __ASSEMBLER__
+#if __BSD_VISIBLE || __POSIX_VISIBLE || __XSI_VISIBLE
+typedef struct _sigjmp_buf { int _sjb[_JBLEN + 1]; } sigjmp_buf[1];
+#endif
+
+typedef struct _jmp_buf { int _jb[_JBLEN + 1]; } jmp_buf[1];
+#endif
+
+#endif /* !_MACHINE_SETJMP_H_ */


Property changes on: trunk/sys/arm/include/setjmp.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/sf_buf.h
===================================================================
--- trunk/sys/arm/include/sf_buf.h	                        (rev 0)
+++ trunk/sys/arm/include/sf_buf.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,62 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2003 Alan L. Cox <alc at cs.rice.edu>
+ * 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: stable/10/sys/arm/include/sf_buf.h 266175 2014-05-15 19:09:31Z ian $
+ */
+
+#ifndef _MACHINE_SF_BUF_H_
+#define _MACHINE_SF_BUF_H_
+
+#include <sys/queue.h>
+
+struct vm_page;
+
+struct sf_buf {
+	LIST_ENTRY(sf_buf) list_entry;	/* list of buffers */
+	TAILQ_ENTRY(sf_buf) free_entry;	/* list of buffers */
+	struct		vm_page *m;	/* currently mapped page */
+	vm_offset_t	kva;		/* va of mapping */
+	int		ref_count;	/* usage of this mapping */
+};
+
+static __inline vm_offset_t
+sf_buf_kva(struct sf_buf *sf)
+{
+
+	return (sf->kva);
+}
+
+static __inline struct vm_page *
+sf_buf_page(struct sf_buf *sf)
+{
+
+	return (sf->m);
+}
+
+struct sf_buf *	sf_buf_alloc(struct vm_page *m, int flags);
+void sf_buf_free(struct sf_buf *sf);
+
+#endif /* !_MACHINE_SF_BUF_H_ */


Property changes on: trunk/sys/arm/include/sf_buf.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/sigframe.h
===================================================================
--- trunk/sys/arm/include/sigframe.h	                        (rev 0)
+++ trunk/sys/arm/include/sigframe.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,3 @@
+/* $MidnightBSD$ */
+/* $FreeBSD: stable/10/sys/arm/include/sigframe.h 129198 2004-05-14 11:46:45Z cognet $ */
+#include <machine/frame.h>


Property changes on: trunk/sys/arm/include/sigframe.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/signal.h
===================================================================
--- trunk/sys/arm/include/signal.h	                        (rev 0)
+++ trunk/sys/arm/include/signal.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,51 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1986, 1989, 1991, 1993
+ *      The Regents of the University of California.  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.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ *      @(#)signal.h    8.1 (Berkeley) 6/11/93
+ *	from: FreeBSD: src/sys/i386/include/signal.h,v 1.13 2000/11/09
+ *	from: FreeBSD: src/sys/sparc64/include/signal.h,v 1.6 2001/09/30 18:52:17
+ * $FreeBSD: stable/10/sys/arm/include/signal.h 248153 2013-03-11 10:56:46Z cognet $
+ */
+
+#ifndef	_MACHINE_SIGNAL_H_
+#define	_MACHINE_SIGNAL_H_
+
+#include <sys/cdefs.h>
+
+typedef	long sig_atomic_t;
+
+#if __BSD_VISIBLE
+
+struct sigcontext {
+	int _dummy;
+};
+
+#endif
+
+#endif /* !_MACHINE_SIGNAL_H_ */


Property changes on: trunk/sys/arm/include/signal.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/smp.h
===================================================================
--- trunk/sys/arm/include/smp.h	                        (rev 0)
+++ trunk/sys/arm/include/smp.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,41 @@
+/* $MidnightBSD$ */
+/* $FreeBSD: stable/10/sys/arm/include/smp.h 266374 2014-05-17 23:03:04Z ian $ */
+
+#ifndef _MACHINE_SMP_H_
+#define _MACHINE_SMP_H_
+
+#include <sys/_cpuset.h>
+#include <machine/pcb.h>
+
+#define IPI_AST		0
+#define IPI_PREEMPT	2
+#define IPI_RENDEZVOUS	3
+#define IPI_STOP	4
+#define IPI_STOP_HARD	4
+#define IPI_HARDCLOCK	6
+#define IPI_TLB		7
+
+void	init_secondary(int cpu);
+void	mpentry(void);
+
+void	ipi_all_but_self(u_int ipi);
+void	ipi_cpu(int cpu, u_int ipi);
+void	ipi_selected(cpuset_t cpus, u_int ipi);
+
+/* PIC interface */
+void	pic_ipi_send(cpuset_t cpus, u_int ipi);
+void	pic_ipi_clear(int ipi);
+int	pic_ipi_get(int arg);
+
+/* Platform interface */
+void	platform_mp_setmaxid(void);
+int	platform_mp_probe(void);
+void	platform_mp_start_ap(void);
+void	platform_mp_init_secondary(void);
+
+void	platform_ipi_send(cpuset_t cpus, u_int ipi);
+
+/* global data in mp_machdep.c */
+extern struct pcb               stoppcbs[];
+
+#endif /* !_MACHINE_SMP_H_ */


Property changes on: trunk/sys/arm/include/smp.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/stack.h
===================================================================
--- trunk/sys/arm/include/stack.h	                        (rev 0)
+++ trunk/sys/arm/include/stack.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,43 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2000, 2001 Ben Harris
+ * Copyright (c) 1996 Scott K. Stevens
+ *
+ * Mach Operating System
+ * Copyright (c) 1991,1990 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ *  Software Distribution Coordinator  or  Software.Distribution at CS.CMU.EDU
+ *  School of Computer Science
+ *  Carnegie Mellon University
+ *  Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ *
+ * $FreeBSD: stable/10/sys/arm/include/stack.h 236992 2012-06-13 05:02:51Z imp $
+ */
+
+#ifndef _MACHINE_STACK_H_
+#define	_MACHINE_STACK_H_
+
+#define INKERNEL(va)	(((vm_offset_t)(va)) >= VM_MIN_KERNEL_ADDRESS)
+
+#define FR_SCP	(0)
+#define FR_RLV	(-1)
+#define FR_RSP	(-2)
+#define FR_RFP	(-3)
+
+#endif /* !_MACHINE_STACK_H_ */


Property changes on: trunk/sys/arm/include/stack.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/stdarg.h
===================================================================
--- trunk/sys/arm/include/stdarg.h	                        (rev 0)
+++ trunk/sys/arm/include/stdarg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,82 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2002 David E. O'Brien.  All rights reserved.
+ * Copyright (c) 1991, 1993
+ *	The Regents of the University of California.  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.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ *	@(#)stdarg.h	8.1 (Berkeley) 6/10/93
+ * $FreeBSD: stable/10/sys/arm/include/stdarg.h 162487 2006-09-21 01:37:02Z kan $
+ */
+
+#ifndef _MACHINE_STDARG_H_
+#define	_MACHINE_STDARG_H_
+
+#include <sys/cdefs.h>
+#include <sys/_types.h>
+
+#ifndef _VA_LIST_DECLARED
+#define	_VA_LIST_DECLARED
+typedef	__va_list	va_list;
+#endif
+
+#ifdef __GNUCLIKE_BUILTIN_STDARG
+
+#define	va_start(ap, last) \
+	__builtin_va_start((ap), (last))
+
+#define	va_arg(ap, type) \
+	__builtin_va_arg((ap), type)
+
+#if __ISO_C_VISIBLE >= 1999
+#define	va_copy(dest, src) \
+	__builtin_va_copy((dest), (src))
+#endif
+
+#define	va_end(ap) \
+	__builtin_va_end(ap)
+
+#else	/* !__GNUCLIKE_BUILTIN_STDARG */
+
+#define	__va_size(type) \
+	(((sizeof(type) + sizeof(int) - 1) / sizeof(int)) * sizeof(int))
+
+#ifdef __GNUCLIKE_BUILTIN_NEXT_ARG
+#define va_start(ap, last) \
+	((ap) = (va_list)__builtin_next_arg(last))
+#else	/* !__GNUCLIKE_BUILTIN_NEXT_ARG */
+#define	va_start(ap, last) \
+	((ap) = (va_list)&(last) + __va_size(last))
+#endif	/* __GNUCLIKE_BUILTIN_NEXT_ARG */
+
+#define	va_arg(ap, type) \
+	(*(type *)((ap) += __va_size(type), (ap) - __va_size(type)))
+
+#define	va_end(ap)
+
+#endif /* __GNUCLIKE_BUILTIN_STDARG */
+
+#endif /* !_MACHINE_STDARG_H_ */


Property changes on: trunk/sys/arm/include/stdarg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/swi.h
===================================================================
--- trunk/sys/arm/include/swi.h	                        (rev 0)
+++ trunk/sys/arm/include/swi.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,24 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: swi.h,v 1.1 2002/01/13 15:03:06 bjh21 Exp $	*/
+/* $FreeBSD: stable/10/sys/arm/include/swi.h 139735 2005-01-05 21:58:49Z imp $ */
+
+/*-
+ * This file is in the Public Domain.
+ * Ben Harris, 2002.
+ */
+
+#ifndef _MACHINE_SWI_H_
+#define _MACHINE_SWI_H_
+
+#define SWI_OS_MASK	0xf00000
+#define SWI_OS_RISCOS	0x000000
+#define SWI_OS_RISCIX	0x800000
+#define SWI_OS_LINUX	0x900000
+#define SWI_OS_NETBSD	0xa00000
+#define SWI_OS_ARM	0xf00000
+
+#define SWI_IMB		0xf00000
+#define SWI_IMBrange	0xf00001
+
+#endif /* !_MACHINE_SWI_H_ */
+


Property changes on: trunk/sys/arm/include/swi.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/sysarch.h
===================================================================
--- trunk/sys/arm/include/sysarch.h	                        (rev 0)
+++ trunk/sys/arm/include/sysarch.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,102 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: sysarch.h,v 1.5 2003/09/11 09:40:12 kleink Exp $	*/
+
+/*-
+ * Copyright (c) 1996-1997 Mark Brinicombe.
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Mark Brinicombe.
+ * 4. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY AUTHOR ``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 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: stable/10/sys/arm/include/sysarch.h 266311 2014-05-17 13:53:38Z ian $ */
+
+#ifndef _ARM_SYSARCH_H_
+#define _ARM_SYSARCH_H_
+
+#include <machine/armreg.h>
+/*
+ * The ARM_TP_ADDRESS points to a special purpose page, which is used as local
+ * store for the ARM per-thread data and Restartable Atomic Sequences support.
+ * Put it just above the "high" vectors' page.
+ * The cpu_switch() code assumes ARM_RAS_START is ARM_TP_ADDRESS + 4, and
+ * ARM_RAS_END is ARM_TP_ADDRESS + 8, so if that ever changes, be sure to
+ * update the cpu_switch() (and cpu_throw()) code as well.
+ * In addition, code in arm/include/atomic.h and arm/arm/exception.S
+ * assumes that ARM_RAS_END is at ARM_RAS_START+4, so be sure to update those
+ * if ARM_RAS_END moves in relation to ARM_RAS_START (look for occurrences
+ * of ldr/str rm,[rn, #4]).
+ */
+
+/* ARM_TP_ADDRESS is needed for processors that don't support
+ * the exclusive-access opcodes introduced with ARMv6K. */
+/* TODO: #if !defined(_HAVE_ARMv6K_INSTRUCTIONS) */
+#if !defined (__ARM_ARCH_7__) && \
+	!defined (__ARM_ARCH_7A__) && \
+	!defined (__ARM_ARCH_6K__) &&  \
+	!defined (__ARM_ARCH_6ZK__)
+#define ARM_TP_ADDRESS		(ARM_VECTORS_HIGH + 0x1000)
+#define ARM_RAS_START		(ARM_TP_ADDRESS + 4)
+#define ARM_RAS_END		(ARM_TP_ADDRESS + 8)
+#endif
+
+#ifndef LOCORE
+#ifndef __ASSEMBLER__
+
+#include <sys/cdefs.h>
+
+/*
+ * Pickup definition of uintptr_t
+ */
+#include <sys/stdint.h>
+
+/*
+ * Architecture specific syscalls (arm)
+ */
+
+#define ARM_SYNC_ICACHE		0
+#define ARM_DRAIN_WRITEBUF	1
+#define ARM_SET_TP		2
+#define ARM_GET_TP		3
+
+struct arm_sync_icache_args {
+	uintptr_t	addr;		/* Virtual start address */
+	size_t		len;		/* Region size */
+};
+
+#ifndef _KERNEL
+__BEGIN_DECLS
+int	arm_sync_icache (u_int addr, int len);
+int	arm_drain_writebuf (void);
+int	sysarch(int, void *);
+__END_DECLS
+#endif
+
+#endif /* __ASSEMBLER__ */
+#endif /* LOCORE */
+
+#endif /* !_ARM_SYSARCH_H_ */


Property changes on: trunk/sys/arm/include/sysarch.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/sysreg.h
===================================================================
--- trunk/sys/arm/include/sysreg.h	                        (rev 0)
+++ trunk/sys/arm/include/sysreg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,265 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright 2014 Svatopluk Kraus <onwahe at gmail.com>
+ * Copyright 2014 Michal Meloun <meloun at miracle.cz>
+ * 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: stable/10/sys/arm/include/sysreg.h 278684 2015-02-13 17:53:11Z ian $
+ */
+
+/*
+ * Macros to make working with the System Control Registers simpler.
+ *
+ * Note that when register r0 is hard-coded in these definitions it means the
+ * cp15 operation neither reads nor writes the register, and r0 is used only
+ * because some syntatically-valid register name has to appear at that point to
+ * keep the asm parser happy.
+ */
+
+#ifndef MACHINE_SYSREG_H
+#define	MACHINE_SYSREG_H
+
+#include <machine/acle-compat.h>
+
+/*
+ * CP15 C0 registers
+ */
+#define	CP15_MIDR(rr)		p15, 0, rr, c0, c0,  0 /* Main ID Register */
+#define	CP15_CTR(rr)		p15, 0, rr, c0, c0,  1 /* Cache Type Register */
+#define	CP15_TCMTR(rr)		p15, 0, rr, c0, c0,  2 /* TCM Type Register */
+#define	CP15_TLBTR(rr)		p15, 0, rr, c0, c0,  3 /* TLB Type Register */
+#define	CP15_MPIDR(rr)		p15, 0, rr, c0, c0,  5 /* Multiprocessor Affinity Register */
+#define	CP15_REVIDR(rr)		p15, 0, rr, c0, c0,  6 /* Revision ID Register */
+
+#define	CP15_ID_PFR0(rr)	p15, 0, rr, c0, c1,  0 /* Processor Feature Register 0 */
+#define	CP15_ID_PFR1(rr)	p15, 0, rr, c0, c1,  1 /* Processor Feature Register 1 */
+#define	CP15_ID_DFR0(rr)	p15, 0, rr, c0, c1,  2 /* Debug Feature Register 0 */
+#define	CP15_ID_AFR0(rr)	p15, 0, rr, c0, c1,  3 /* Auxiliary Feature Register  0 */
+#define	CP15_ID_MMFR0(rr)	p15, 0, rr, c0, c1,  4 /* Memory Model Feature Register 0 */
+#define	CP15_ID_MMFR1(rr)	p15, 0, rr, c0, c1,  5 /* Memory Model Feature Register 1 */
+#define	CP15_ID_MMFR2(rr)	p15, 0, rr, c0, c1,  6 /* Memory Model Feature Register 2 */
+#define	CP15_ID_MMFR3(rr)	p15, 0, rr, c0, c1,  7 /* Memory Model Feature Register 3 */
+
+#define	CP15_ID_ISAR0(rr)	p15, 0, rr, c0, c2,  0 /* Instruction Set Attribute Register 0 */
+#define	CP15_ID_ISAR1(rr)	p15, 0, rr, c0, c2,  1 /* Instruction Set Attribute Register 1 */
+#define	CP15_ID_ISAR2(rr)	p15, 0, rr, c0, c2,  2 /* Instruction Set Attribute Register 2 */
+#define	CP15_ID_ISAR3(rr)	p15, 0, rr, c0, c2,  3 /* Instruction Set Attribute Register 3 */
+#define	CP15_ID_ISAR4(rr)	p15, 0, rr, c0, c2,  4 /* Instruction Set Attribute Register 4 */
+#define	CP15_ID_ISAR5(rr)	p15, 0, rr, c0, c2,  5 /* Instruction Set Attribute Register 5 */
+
+#define	CP15_CCSIDR(rr)		p15, 1, rr, c0, c0,  0 /* Cache Size ID Registers */
+#define	CP15_CLIDR(rr)		p15, 1, rr, c0, c0,  1 /* Cache Level ID Register */
+#define	CP15_AIDR(rr)		p15, 1, rr, c0, c0,  7 /* Auxiliary ID Register */
+
+#define	CP15_CSSELR(rr)		p15, 2, rr, c0, c0,  0 /* Cache Size Selection Register */
+
+/*
+ * CP15 C1 registers
+ */
+#define	CP15_SCTLR(rr)		p15, 0, rr, c1, c0,  0 /* System Control Register */
+#define	CP15_ACTLR(rr)		p15, 0, rr, c1, c0,  1 /* IMPLEMENTATION DEFINED Auxiliary Control Register */
+#define	CP15_CPACR(rr)		p15, 0, rr, c1, c0,  2 /* Coprocessor Access Control Register */
+
+#define	CP15_SCR(rr)		p15, 0, rr, c1, c1,  0 /* Secure Configuration Register */
+#define	CP15_SDER(rr)		p15, 0, rr, c1, c1,  1 /* Secure Debug Enable Register */
+#define	CP15_NSACR(rr)		p15, 0, rr, c1, c1,  2 /* Non-Secure Access Control Register */
+
+/*
+ * CP15 C2 registers
+ */
+#define	CP15_TTBR0(rr)		p15, 0, rr, c2, c0,  0 /* Translation Table Base Register 0 */
+#define	CP15_TTBR1(rr)		p15, 0, rr, c2, c0,  1 /* Translation Table Base Register 1 */
+#define	CP15_TTBCR(rr)		p15, 0, rr, c2, c0,  2 /* Translation Table Base Control Register */
+
+/*
+ * CP15 C3 registers
+ */
+#define	CP15_DACR(rr)		p15, 0, rr, c3, c0,  0 /* Domain Access Control Register */
+
+/*
+ * CP15 C5 registers
+ */
+#define	CP15_DFSR(rr)		p15, 0, rr, c5, c0,  0 /* Data Fault Status Register */
+
+#if __ARM_ARCH >= 6
+/* From ARMv6: */
+#define	CP15_IFSR(rr)		p15, 0, rr, c5, c0,  1 /* Instruction Fault Status Register */
+#endif
+#if __ARM_ARCH >= 7
+/* From ARMv7: */
+#define	CP15_ADFSR(rr)		p15, 0, rr, c5, c1,  0 /* Auxiliary Data Fault Status Register */
+#define	CP15_AIFSR(rr)		p15, 0, rr, c5, c1,  1 /* Auxiliary Instruction Fault Status Register */
+#endif
+
+/*
+ * CP15 C6 registers
+ */
+#define	CP15_DFAR(rr)		p15, 0, rr, c6, c0,  0 /* Data Fault Address Register */
+
+#if __ARM_ARCH >= 6
+/* From ARMv6k: */
+#define	CP15_IFAR(rr)		p15, 0, rr, c6, c0,  2 /* Instruction Fault Address Register */
+#endif
+
+/*
+ * CP15 C7 registers
+ */
+#if __ARM_ARCH >= 7 && defined(SMP)
+/* From ARMv7: */
+#define	CP15_ICIALLUIS		p15, 0, r0, c7, c1,  0 /* Instruction cache invalidate all PoU, IS */
+#define	CP15_BPIALLIS		p15, 0, r0, c7, c1,  6 /* Branch predictor invalidate all IS */
+#endif
+
+#define	CP15_PAR		p15, 0, r0, c7, c4,  0 /* Physical Address Register */
+
+#define	CP15_ICIALLU		p15, 0, r0, c7, c5,  0 /* Instruction cache invalidate all PoU */
+#define	CP15_ICIMVAU(rr)	p15, 0, rr, c7, c5,  1 /* Instruction cache invalidate */
+#if __ARM_ARCH == 6
+/* Deprecated in ARMv7 */
+#define	CP15_CP15ISB		p15, 0, r0, c7, c5,  4 /* ISB */
+#endif
+#define	CP15_BPIALL		p15, 0, r0, c7, c5,  6 /* Branch predictor invalidate all */
+#define	CP15_BPIMVA		p15, 0, rr, c7, c5,  7 /* Branch predictor invalidate by MVA */
+
+#if __ARM_ARCH == 6
+/* Only ARMv6: */
+#define	CP15_DCIALL		p15, 0, r0, c7, c6,  0 /* Data cache invalidate all */
+#endif
+#define	CP15_DCIMVAC(rr)	p15, 0, rr, c7, c6,  1 /* Data cache invalidate by MVA PoC */
+#define	CP15_DCISW(rr)		p15, 0, rr, c7, c6,  2 /* Data cache invalidate by set/way */
+
+#define	CP15_ATS1CPR(rr)	p15, 0, rr, c7, c8,  0 /* Stage 1 Current state PL1 read */
+#define	CP15_ATS1CPW(rr)	p15, 0, rr, c7, c8,  1 /* Stage 1 Current state PL1 write */
+#define	CP15_ATS1CUR(rr)	p15, 0, rr, c7, c8,  2 /* Stage 1 Current state unprivileged read */
+#define	CP15_ATS1CUW(rr)	p15, 0, rr, c7, c8,  3 /* Stage 1 Current state unprivileged write */
+
+#if __ARM_ARCH >= 7
+/* From ARMv7: */
+#define	CP15_ATS12NSOPR(rr)	p15, 0, rr, c7, c8,  4 /* Stages 1 and 2 Non-secure only PL1 read */
+#define	CP15_ATS12NSOPW(rr)	p15, 0, rr, c7, c8,  5 /* Stages 1 and 2 Non-secure only PL1 write */
+#define	CP15_ATS12NSOUR(rr)	p15, 0, rr, c7, c8,  6 /* Stages 1 and 2 Non-secure only unprivileged read */
+#define	CP15_ATS12NSOUW(rr)	p15, 0, rr, c7, c8,  7 /* Stages 1 and 2 Non-secure only unprivileged write */
+#endif
+
+#if __ARM_ARCH == 6
+/* Only ARMv6: */
+#define	CP15_DCCALL		p15, 0, r0, c7, c10, 0 /* Data cache clean all */
+#endif
+#define	CP15_DCCMVAC(rr)	p15, 0, rr, c7, c10, 1 /* Data cache clean by MVA PoC */
+#define	CP15_DCCSW(rr)		p15, 0, rr, c7, c10, 2 /* Data cache clean by set/way */
+#if __ARM_ARCH == 6
+/* Only ARMv6: */
+#define	CP15_CP15DSB		p15, 0, r0, c7, c10, 4 /* DSB */
+#define	CP15_CP15DMB		p15, 0, r0, c7, c10, 5 /* DMB */
+#define	CP15_CP15WFI		p15, 0, r0, c7, c0,  4 /* WFI */
+#endif
+
+#if __ARM_ARCH >= 7
+/* From ARMv7: */
+#define	CP15_DCCMVAU(rr)	p15, 0, rr, c7, c11, 1 /* Data cache clean by MVA PoU */
+#endif
+
+#if __ARM_ARCH == 6
+/* Only ARMv6: */
+#define	CP15_DCCIALL		p15, 0, r0, c7, c14, 0 /* Data cache clean and invalidate all */
+#endif
+#define	CP15_DCCIMVAC(rr)	p15, 0, rr, c7, c14, 1 /* Data cache clean and invalidate by MVA PoC */
+#define	CP15_DCCISW(rr)		p15, 0, rr, c7, c14, 2 /* Data cache clean and invalidate by set/way */
+
+/*
+ * CP15 C8 registers
+ */
+#if __ARM_ARCH >= 7 && defined(SMP)
+/* From ARMv7: */
+#define	CP15_TLBIALLIS		p15, 0, r0, c8, c3, 0 /* Invalidate entire unified TLB IS */
+#define	CP15_TLBIMVAIS(rr)	p15, 0, rr, c8, c3, 1 /* Invalidate unified TLB by MVA IS */
+#define	CP15_TLBIASIDIS(rr)	p15, 0, rr, c8, c3, 2 /* Invalidate unified TLB by ASID IS */
+#define	CP15_TLBIMVAAIS(rr)	p15, 0, rr, c8, c3, 3 /* Invalidate unified TLB by MVA, all ASID IS */
+#endif
+
+#define	CP15_TLBIALL		p15, 0, r0, c8, c7, 0 /* Invalidate entire unified TLB */
+#define	CP15_TLBIMVA(rr)	p15, 0, rr, c8, c7, 1 /* Invalidate unified TLB by MVA */
+#define	CP15_TLBIASID(rr)	p15, 0, rr, c8, c7, 2 /* Invalidate unified TLB by ASID */
+
+#if __ARM_ARCH >= 6
+/* From ARMv6: */
+#define	CP15_TLBIMVAA(rr)	p15, 0, rr, c8, c7, 3 /* Invalidate unified TLB by MVA, all ASID */
+#endif
+
+/*
+ * CP15 C9 registers
+ */
+#if __ARM_ARCH == 6 && defined(CPU_ARM1176)
+#define	CP15_PMCCNTR(rr)	p15, 0, rr, c15, c12, 1 /* PM Cycle Count Register */
+#elif __ARM_ARCH > 6
+#define	CP15_PMCR(rr)		p15, 0, rr,  c9, c12, 0 /* Performance Monitor Control Register */
+#define	CP15_PMCNTENSET(rr)	p15, 0, rr,  c9, c12, 1 /* PM Count Enable Set Register */
+#define	CP15_PMCNTENCLR(rr)	p15, 0, rr,  c9, c12, 2 /* PM Count Enable Clear Register */
+#define	CP15_PMOVSR(rr)		p15, 0, rr,  c9, c12, 3 /* PM Overflow Flag Status Register */
+#define	CP15_PMSWINC(rr)	p15, 0, rr,  c9, c12, 4 /* PM Software Increment Register */
+#define	CP15_PMSELR(rr)		p15, 0, rr,  c9, c12, 5 /* PM Event Counter Selection Register */
+#define	CP15_PMCCNTR(rr)	p15, 0, rr,  c9, c13, 0 /* PM Cycle Count Register */
+#define	CP15_PMXEVTYPER(rr)	p15, 0, rr,  c9, c13, 1 /* PM Event Type Select Register */
+#define	CP15_PMXEVCNTRR(rr)	p15, 0, rr,  c9, c13, 2 /* PM Event Count Register */
+#define	CP15_PMUSERENR(rr)	p15, 0, rr,  c9, c14, 0 /* PM User Enable Register */
+#define	CP15_PMINTENSET(rr)	p15, 0, rr,  c9, c14, 1 /* PM Interrupt Enable Set Register */
+#define	CP15_PMINTENCLR(rr)	p15, 0, rr,  c9, c14, 2 /* PM Interrupt Enable Clear Register */
+#endif
+
+/*
+ * CP15 C10 registers
+ */
+/* Without LPAE this is PRRR, with LPAE it's MAIR0 */
+#define	CP15_PRRR(rr)		p15, 0, rr, c10, c2, 0 /* Primary Region Remap Register */
+#define	CP15_MAIR0(rr)		p15, 0, rr, c10, c2, 0 /* Memory Attribute Indirection Register 0 */
+/* Without LPAE this is NMRR, with LPAE it's MAIR1 */
+#define	CP15_NMRR(rr)		p15, 0, rr, c10, c2, 1 /* Normal Memory Remap Register */
+#define	CP15_MAIR1(rr)		p15, 0, rr, c10, c2, 1 /* Memory Attribute Indirection Register 1 */
+
+#define	CP15_AMAIR0(rr)		p15, 0, rr, c10, c3, 0 /* Auxiliary Memory Attribute Indirection Register 0 */
+#define	CP15_AMAIR1(rr)		p15, 0, rr, c10, c3, 1 /* Auxiliary Memory Attribute Indirection Register 1 */
+
+/*
+ * CP15 C12 registers
+ */
+#define	CP15_VBAR(rr)		p15, 0, rr, c12, c0, 0 /* Vector Base Address Register */
+#define	CP15_MVBAR(rr)		p15, 0, rr, c12, c0, 1 /* Monitor Vector Base Address Register */
+
+#define	CP15_ISR(rr)		p15, 0, rr, c12, c1, 0 /* Interrupt Status Register */
+
+/*
+ * CP15 C13 registers
+ */
+#define	CP15_FCSEIDR(rr)	p15, 0, rr, c13, c0, 0 /* FCSE Process ID Register */
+#define	CP15_CONTEXTIDR(rr)	p15, 0, rr, c13, c0, 1 /* Context ID Register */
+#define	CP15_TPIDRURW(rr)	p15, 0, rr, c13, c0, 2 /* User Read/Write Thread ID Register */
+#define	CP15_TPIDRURO(rr)	p15, 0, rr, c13, c0, 3 /* User Read-Only Thread ID Register */
+#define	CP15_TPIDRPRW(rr)	p15, 0, rr, c13, c0, 4 /* PL1 only Thread ID Register */
+
+/*
+ * CP15 C15 registers
+ */
+#define CP15_CBAR(rr)		p15, 4, rr, c15, c0, 0 /* Configuration Base Address Register */
+
+#endif /* !MACHINE_SYSREG_H */


Property changes on: trunk/sys/arm/include/sysreg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/trap.h
===================================================================
--- trunk/sys/arm/include/trap.h	                        (rev 0)
+++ trunk/sys/arm/include/trap.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,11 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: trap.h,v 1.1 2001/02/23 03:48:19 ichiro Exp $	*/
+/* $FreeBSD: stable/10/sys/arm/include/trap.h 140001 2005-01-10 22:43:16Z cognet $ */
+
+#ifndef _MACHINE_TRAP_H_
+#define _MACHINE_TRAP_H_
+#define GDB_BREAKPOINT		0xe6000011
+#define GDB5_BREAKPOINT		0xe7ffdefe
+#define PTRACE_BREAKPOINT	0xe7fffff0
+#define KERNEL_BREAKPOINT	0xe7ffffff
+#endif /* _MACHINE_TRAP_H_ */


Property changes on: trunk/sys/arm/include/trap.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/ucontext.h
===================================================================
--- trunk/sys/arm/include/ucontext.h	                        (rev 0)
+++ trunk/sys/arm/include/ucontext.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,109 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: mcontext.h,v 1.4 2003/10/08 22:43:01 thorpej Exp $	*/
+
+/*-
+ * Copyright (c) 2001, 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Klaus Klein and by Jason R. Thorpe of Wasabi Systems, Inc.
+ *
+ * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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: stable/10/sys/arm/include/ucontext.h 203974 2010-02-16 21:59:17Z imp $
+ */
+
+#ifndef _MACHINE_MCONTEXT_H_
+#define _MACHINE_MCONTEXT_H_
+/*
+ * General register state
+ */
+#define _NGREG		17
+typedef unsigned int	__greg_t;
+typedef __greg_t	__gregset_t[_NGREG];
+
+#define _REG_R0		0
+#define _REG_R1		1
+#define _REG_R2		2
+#define _REG_R3		3
+#define _REG_R4		4
+#define _REG_R5		5
+#define _REG_R6		6
+#define _REG_R7		7
+#define _REG_R8		8
+#define _REG_R9		9
+#define _REG_R10	10
+#define _REG_R11	11
+#define _REG_R12	12
+#define _REG_R13	13
+#define _REG_R14	14
+#define _REG_R15	15
+#define _REG_CPSR	16
+/* Convenience synonyms */
+#define _REG_FP		_REG_R11
+#define _REG_SP		_REG_R13
+#define _REG_LR		_REG_R14
+#define _REG_PC		_REG_R15
+
+/*
+ * Floating point register state
+ */
+/* Note: the storage layout of this structure must be identical to ARMFPE! */
+typedef struct {
+	unsigned int	__fp_fpsr;
+	struct {
+		unsigned int	__fp_exponent;
+		unsigned int	__fp_mantissa_hi;
+		unsigned int	__fp_mantissa_lo;
+	}		__fp_fr[8];
+} __fpregset_t;
+
+typedef struct {
+	unsigned int	__vfp_fpscr;
+	unsigned int	__vfp_fstmx[33];
+	unsigned int	__vfp_fpsid;
+} __vfpregset_t;
+
+typedef struct {
+	__gregset_t	__gregs;
+	union {
+		__fpregset_t __fpregs;
+		__vfpregset_t __vfpregs;
+	} __fpu;
+} mcontext_t;
+
+/* Machine-dependent uc_flags */
+#define	_UC_ARM_VFP	0x00010000	/* FPU field is VFP */
+
+/* used by signal delivery to indicate status of signal stack */
+#define _UC_SETSTACK	0x00020000
+#define _UC_CLRSTACK	0x00040000
+
+#define _UC_MACHINE_PAD	3		/* Padding appended to ucontext_t */
+
+#define _UC_MACHINE_SP(uc)	((uc)->uc_mcontext.__gregs[_REG_SP])
+#define _UC_MACHINE_PC(uc)	((uc)->uc_mcontext.__gregs[_REG_PC])
+#define _UC_MACHINE_INTRV(uc)	((uc)->uc_mcontext.__gregs[_REG_R0])
+
+#define	_UC_MACHINE_SET_PC(uc, pc)	_UC_MACHINE_PC(uc) = (pc)
+
+#endif	/* !_MACHINE_MCONTEXT_H_ */


Property changes on: trunk/sys/arm/include/ucontext.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/undefined.h
===================================================================
--- trunk/sys/arm/include/undefined.h	                        (rev 0)
+++ trunk/sys/arm/include/undefined.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,93 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: undefined.h,v 1.4 2001/12/20 01:20:23 thorpej Exp $	*/
+
+/*-
+ * Copyright (c) 1995-1996 Mark Brinicombe.
+ * Copyright (c) 1995 Brini.
+ * All rights reserved.
+ *
+ * This code is derived from software written for Brini by Mark Brinicombe
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Brini.
+ * 4. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BRINI ``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 BRINI 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.
+ *
+ * RiscBSD kernel project
+ *
+ * undefined.h
+ *
+ * Undefined instruction types, symbols and prototypes
+ *
+ * Created      : 08/02/95
+ *
+ * $FreeBSD: stable/10/sys/arm/include/undefined.h 259329 2013-12-13 20:43:11Z ian $
+ */
+
+
+#ifndef _MACHINE_UNDEFINED_H_
+#define _MACHINE_UNDEFINED_H_
+#ifdef _KERNEL
+
+#include <sys/queue.h>
+
+struct trapframe;
+
+typedef int (*undef_handler_t) (unsigned int, unsigned int, struct trapframe *, int);
+
+#define FP_COPROC	1
+#define FP_COPROC2	2
+#define MAX_COPROCS	16
+
+/* Prototypes for undefined.c */
+
+void *install_coproc_handler (int, undef_handler_t);
+void remove_coproc_handler (void *);
+void undefined_init (void);
+
+/*
+ * XXX Stuff below here is for use before malloc() is available.  Most code
+ * shouldn't use it.
+ */
+
+struct undefined_handler {
+	LIST_ENTRY(undefined_handler) uh_link;
+	undef_handler_t uh_handler;
+};
+
+/*
+ * Handlers installed using install_coproc_handler_static shouldn't be
+ * removed.
+ */
+void install_coproc_handler_static (int, struct undefined_handler *);
+
+/* Calls up to undefined.c from trap handlers */
+void undefinedinstruction(struct trapframe *);
+
+#endif
+
+/* End of undefined.h */
+
+#endif /* _MACHINE_UNDEFINED_H_ */


Property changes on: trunk/sys/arm/include/undefined.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/utrap.h
===================================================================
--- trunk/sys/arm/include/utrap.h	                        (rev 0)
+++ trunk/sys/arm/include/utrap.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,111 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2001 Jake Burkholder.
+ * 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: stable/10/sys/arm/include/utrap.h 129198 2004-05-14 11:46:45Z cognet $
+ */
+
+#ifndef	_MACHINE_UTRAP_H_
+#define	_MACHINE_UTRAP_H_
+
+#define	UT_INSTRUCTION_EXCEPTION	1
+#define	UT_INSTRUCTION_ERROR		2
+#define	UT_INSTRUCTION_PROTECTION	3
+#define	UT_ILLTRAP_INSTRUCTION		4
+#define	UT_ILLEGAL_INSTRUCTION		5
+#define	UT_PRIVILEGED_OPCODE		6
+#define	UT_FP_DISABLED			7
+#define	UT_FP_EXCEPTION_IEEE_754	8
+#define	UT_FP_EXCEPTION_OTHER		9
+#define	UT_TAG_OFERFLOW			10
+#define	UT_DIVISION_BY_ZERO		11
+#define	UT_DATA_EXCEPTION		12
+#define	UT_DATA_ERROR			13
+#define	UT_DATA_PROTECTION		14
+#define	UT_MEM_ADDRESS_NOT_ALIGNED	15
+#define	UT_PRIVILEGED_ACTION		16
+#define	UT_ASYNC_DATA_ERROR		17
+#define	UT_TRAP_INSTRUCTION_16		18
+#define	UT_TRAP_INSTRUCTION_17		19
+#define	UT_TRAP_INSTRUCTION_18		20
+#define	UT_TRAP_INSTRUCTION_19		21
+#define	UT_TRAP_INSTRUCTION_20		22
+#define	UT_TRAP_INSTRUCTION_21		23
+#define	UT_TRAP_INSTRUCTION_22		24
+#define	UT_TRAP_INSTRUCTION_23		25
+#define	UT_TRAP_INSTRUCTION_24		26
+#define	UT_TRAP_INSTRUCTION_25		27
+#define	UT_TRAP_INSTRUCTION_26		28
+#define	UT_TRAP_INSTRUCTION_27		29
+#define	UT_TRAP_INSTRUCTION_28		30
+#define	UT_TRAP_INSTRUCTION_29		31
+#define	UT_TRAP_INSTRUCTION_30		32
+#define	UT_TRAP_INSTRUCTION_31		33
+#define	UT_INSTRUCTION_MISS		34
+#define	UT_DATA_MISS			35
+#define	UT_MAX				36
+
+#define	ST_SUNOS_SYSCALL		0
+#define	ST_BREAKPOINT			1
+#define	ST_DIVISION_BY_ZERO		2
+#define	ST_FLUSH_WINDOWS		3	/* XXX implement! */
+#define	ST_CLEAN_WINDOW			4
+#define	ST_RANGE_CHECK			5
+#define	ST_FIX_ALIGNMENT		6
+#define	ST_INTEGER_OVERFLOW		7
+/* 8 is 32-bit ABI syscall (old solaris syscall?) */
+#define	ST_BSD_SYSCALL			9
+#define	ST_FP_RESTORE			10
+/* 11-15 are available */
+/* 16 is linux 32 bit syscall (but supposed to be reserved, grr) */
+/* 17 is old linux 64 bit syscall (but supposed to be reserved, grr) */
+/* 16-31 are reserved for user applications (utraps) */
+#define	ST_GETCC			32	/* XXX implement! */
+#define	ST_SETCC			33	/* XXX implement! */
+#define	ST_GETPSR			34	/* XXX implement! */
+#define	ST_SETPSR			35	/* XXX implement! */
+/* 36-63 are available */
+#define	ST_SOLARIS_SYSCALL		64
+#define	ST_SYSCALL			65
+#define	ST_SYSCALL32			66
+/* 67 is reserved to OS source licensee */
+/* 68 is return from deferred trap (not supported) */
+/* 69-95 are reserved to SPARC international */
+/* 96-108 are available */
+/* 109 is linux 64 bit syscall */
+/* 110 is linux 64 bit getcontext (?) */
+/* 111 is linux 64 bit setcontext (?) */
+/* 112-255 are available */
+
+#define	UTH_NOCHANGE			(-1)
+
+#ifndef __ASM__
+
+typedef	int utrap_entry_t;
+typedef void *utrap_handler_t;
+
+#endif
+
+#endif


Property changes on: trunk/sys/arm/include/utrap.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/vdso.h
===================================================================
--- trunk/sys/arm/include/vdso.h	                        (rev 0)
+++ trunk/sys/arm/include/vdso.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,35 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright 2012 Konstantin Belousov <kib at FreeBSD.ORG>.
+ * 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 ``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 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: stable/10/sys/arm/include/vdso.h 237433 2012-06-22 07:06:40Z kib $
+ */
+
+#ifndef _ARM_VDSO_H
+#define	_ARM_VDSO_H
+
+#define	VDSO_TIMEHANDS_MD			\
+	uint32_t	th_res[8];
+
+#endif


Property changes on: trunk/sys/arm/include/vdso.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/vfp.h
===================================================================
--- trunk/sys/arm/include/vfp.h	                        (rev 0)
+++ trunk/sys/arm/include/vfp.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,141 @@
+/* $MidnightBSD$ */
+/*
+ * Copyright (c) 2012 Mark Tinguely
+ *
+ * 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: stable/10/sys/arm/include/vfp.h 266341 2014-05-17 19:37:04Z ian $
+ */
+
+
+#ifndef _MACHINE__VFP_H_
+#define _MACHINE__VFP_H_
+
+/* fpsid, fpscr, fpexc are defined in the newer gas */
+#define	VFPSID			cr0
+#define	VFPSCR			cr1
+#define	VMVFR1			cr6
+#define	VMVFR0			cr7
+#define	VFPEXC			cr8
+#define	VFPINST			cr9	/* vfp 1 and 2 except instruction */
+#define	VFPINST2		cr10 	/* vfp 2? */
+
+/* VFPSID */
+#define	VFPSID_IMPLEMENTOR_OFF	24
+#define	VFPSID_IMPLEMENTOR_MASK	(0xff000000)
+#define	VFPSID_HARDSOFT_IMP	(0x00800000)
+#define	VFPSID_SINGLE_PREC	20	 /* version 1 and 2 */
+#define	VFPSID_SUBVERSION_OFF	16
+#define	VFPSID_SUBVERSION2_MASK	(0x000f0000)	 /* version 1 and 2 */
+#define	VFPSID_SUBVERSION3_MASK	(0x007f0000)	 /* version 3 */
+#define	VFP_ARCH1		0x0
+#define	VFP_ARCH2		0x1
+#define	VFP_ARCH3		0x2
+#define	VFPSID_PARTNUMBER_OFF	8
+#define	VFPSID_PARTNUMBER_MASK	(0x0000ff00)
+#define	VFPSID_VARIANT_OFF	4
+#define	VFPSID_VARIANT_MASK	(0x000000f0)
+#define	VFPSID_REVISION_MASK	0x0f
+
+/* VFPSCR */
+#define	VFPSCR_CC_N		(0x80000000)	/* comparison less than */
+#define	VFPSCR_CC_Z		(0x40000000)	/* comparison equal */
+#define	VFPSCR_CC_C		(0x20000000)	/* comparison = > unordered */
+#define	VFPSCR_CC_V		(0x10000000)	/* comparison unordered */
+#define	VFPSCR_QC		(0x08000000)	/* saturation cululative */
+#define	VFPSCR_DN		(0x02000000)	/* default NaN enable */
+#define	VFPSCR_FZ		(0x01000000)	/* flush to zero enabled */
+
+#define	VFPSCR_RMODE_OFF	22		/* rounding mode offset */
+#define	VFPSCR_RMODE_MASK	(0x00c00000)	/* rounding mode mask */
+#define	VFPSCR_RMODE_RN		(0x00000000)	/* round nearest */
+#define	VFPSCR_RMODE_RPI	(0x00400000)	/* round to plus infinity */
+#define	VFPSCR_RMODE_RNI	(0x00800000)	/* round to neg infinity */
+#define	VFPSCR_RMODE_RM		(0x00c00000)	/* round to zero */
+
+#define	VFPSCR_STRIDE_OFF	20		/* vector stride -1 */
+#define	VFPSCR_STRIDE_MASK	(0x00300000)
+#define	VFPSCR_LEN_OFF		16		/* vector length -1 */
+#define	VFPSCR_LEN_MASK		(0x00070000)
+#define	VFPSCR_IDE		(0x00008000)	/* input subnormal exc enable */
+#define	VFPSCR_IXE		(0x00001000)	/* inexact exception enable */
+#define	VFPSCR_UFE		(0x00000800)	/* underflow exception enable */
+#define	VFPSCR_OFE		(0x00000400)	/* overflow exception enable */
+#define	VFPSCR_DNZ		(0x00000200)	/* div by zero exception en */
+#define	VFPSCR_IOE		(0x00000100)	/* invalid op exec enable */
+#define	VFPSCR_IDC		(0x00000080)	/* input subnormal cumul */
+#define	VFPSCR_IXC		(0x00000010)	/* Inexact cumulative flag */
+#define	VFPSCR_UFC		(0x00000008)	/* underflow cumulative flag */
+#define	VFPSCR_OFC		(0x00000004)	/* overflow cumulative flag */
+#define	VFPSCR_DZC		(0x00000002)	/* division by zero flag */
+#define	VFPSCR_IOC		(0x00000001)	/* invalid operation cumul */
+
+/* VFPEXC */
+#define	VFPEXC_EX 		(0x80000000)	/* exception v1 v2 */
+#define	VFPEXC_EN		(0x40000000)	/* vfp enable */
+#define	VFPEXC_FP2V		(0x10000000)	/* FPINST2 valid */
+#define	VFPEXC_INV		(0x00000080)	/* Input exception */
+#define	VFPEXC_UFC		(0x00000008)	/* Underflow exception */
+#define	VFPEXC_OFC		(0x00000004)	/* Overflow exception */
+#define	VFPEXC_IOC		(0x00000001)	/* Invlaid operation */
+
+/* version 3 registers */
+/* VMVFR0 */
+#define	VMVFR0_RM_OFF		28
+#define	VMVFR0_RM_MASK 		(0xf0000000)	/* VFP rounding modes */
+
+#define	VMVFR0_SV_OFF		24
+#define	VMVFR0_SV_MASK		(0x0f000000)	/* VFP short vector supp */
+#define	VMVFR0_SR_OFF		20
+#define	VMVFR0_SR		(0x00f00000)	/* VFP hw sqrt supp */
+#define	VMVFR0_D_OFF		16
+#define	VMVFR0_D_MASK		(0x000f0000)	/* VFP divide supp */
+#define	VMVFR0_TE_OFF		12
+#define	VMVFR0_TE_MASK		(0x0000f000)	/* VFP trap exception supp */
+#define	VMVFR0_DP_OFF		8
+#define	VMVFR0_DP_MASK		(0x00000f00)	/* VFP double prec support */
+#define	VMVFR0_SP_OFF		4
+#define	VMVFR0_SP_MASK		(0x000000f0)	/* VFP single prec support */
+#define	VMVFR0_RB_MASK		(0x0000000f)	/* VFP 64 bit media support */
+
+/* VMVFR1 */
+#define	VMVFR1_SP_OFF		16
+#define	VMVFR1_SP_MASK 		(0x000f0000)	/* Neon single prec support */
+#define VMVFR1_I_OFF		12
+#define	VMVFR1_I_MASK		(0x0000f000)	/* Neon integer support */
+#define VMVFR1_LS_OFF		8
+#define	VMVFR1_LS_MASK		(0x00000f00)	/* Neon ld/st instr support */
+#define VMVFR1_DN_OFF		4
+#define	VMVFR1_DN_MASK		(0x000000f0)	/* Neon prop NaN support */
+#define	VMVFR1_FZ_MASK		(0x0000000f)	/* Neon denormal arith supp */
+
+#define COPROC10		(0x3 << 20)
+#define COPROC11		(0x3 << 22)
+
+#ifndef LOCORE
+void    vfp_init(void);
+void    vfp_store(struct vfp_state *, boolean_t);
+void    vfp_discard(struct thread *);
+#endif
+
+#endif


Property changes on: trunk/sys/arm/include/vfp.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/vm.h
===================================================================
--- trunk/sys/arm/include/vm.h	                        (rev 0)
+++ trunk/sys/arm/include/vm.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,37 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2009 Alan L. Cox <alc at cs.rice.edu>
+ * 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: stable/10/sys/arm/include/vm.h 244414 2012-12-19 00:24:31Z cognet $
+ */
+
+#ifndef _MACHINE_VM_H_
+#define	_MACHINE_VM_H_
+
+/* Memory attribute configuration. */
+#define	VM_MEMATTR_DEFAULT	0
+#define	VM_MEMATTR_UNCACHEABLE	1
+
+#endif /* !_MACHINE_VM_H_ */


Property changes on: trunk/sys/arm/include/vm.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/include/vmparam.h
===================================================================
--- trunk/sys/arm/include/vmparam.h	                        (rev 0)
+++ trunk/sys/arm/include/vmparam.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,176 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: vmparam.h,v 1.26 2003/08/07 16:27:47 agc Exp $	*/
+
+/*-
+ * Copyright (c) 1988 The Regents of the University of California.
+ * 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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: stable/10/sys/arm/include/vmparam.h 283339 2015-05-23 23:27:00Z ian $
+ */
+
+#ifndef	_MACHINE_VMPARAM_H_
+#define	_MACHINE_VMPARAM_H_
+
+/*
+ * Machine dependent constants for ARM.
+ */
+
+/*
+ * Virtual memory related constants, all in bytes
+ */
+#ifndef	MAXTSIZ
+#define	MAXTSIZ		(64UL*1024*1024)	/* max text size */
+#endif
+#ifndef	DFLDSIZ
+#define	DFLDSIZ		(128UL*1024*1024)	/* initial data size limit */
+#endif
+#ifndef	MAXDSIZ
+#define	MAXDSIZ		(512UL*1024*1024)	/* max data size */
+#endif
+#ifndef	DFLSSIZ
+#define	DFLSSIZ		(2UL*1024*1024)		/* initial stack size limit */
+#endif
+#ifndef	MAXSSIZ
+#define	MAXSSIZ		(8UL*1024*1024)		/* max stack size */
+#endif
+#ifndef	SGROWSIZ
+#define	SGROWSIZ	(128UL*1024)		/* amount to grow stack */
+#endif
+
+/*
+ * Address space constants
+ */
+
+/*
+ * The line between user space and kernel space
+ * Mappings >= KERNEL_BASE are constant across all processes
+ */
+#ifndef KERNBASE
+#define	KERNBASE		0xc0000000
+#endif
+
+/*
+ * max number of non-contig chunks of physical RAM you can have
+ */
+
+#define	VM_PHYSSEG_MAX		32
+
+/*
+ * The physical address space may be sparsely populated on some ARM systems.
+ */
+#define	VM_PHYSSEG_SPARSE
+
+/*
+ * Create two free page pools.  Since the ARM kernel virtual address
+ * space does not include a mapping onto the machine's entire physical
+ * memory, VM_FREEPOOL_DIRECT is defined as an alias for the default
+ * pool, VM_FREEPOOL_DEFAULT.
+ */
+#define	VM_NFREEPOOL		2
+#define	VM_FREEPOOL_CACHE	1
+#define	VM_FREEPOOL_DEFAULT	0
+#define	VM_FREEPOOL_DIRECT	0
+
+/*
+ * We need just one free list:  DEFAULT.
+ */
+#define	VM_NFREELIST		1
+#define	VM_FREELIST_DEFAULT	0
+
+/*
+ * The largest allocation size is 1MB.
+ */
+#define	VM_NFREEORDER		9
+
+/*
+ * Enable superpage reservations: 1 level.
+ */
+#ifndef	VM_NRESERVLEVEL
+#define	VM_NRESERVLEVEL		1
+#endif
+
+/*
+ * Level 0 reservations consist of 256 pages.
+ */
+#ifndef	VM_LEVEL_0_ORDER
+#define	VM_LEVEL_0_ORDER	8
+#endif
+
+#define UPT_MAX_ADDRESS		VADDR(UPTPTDI + 3, 0)
+#define UPT_MIN_ADDRESS		VADDR(UPTPTDI, 0)
+
+#define VM_MIN_ADDRESS          (0x00001000)
+#ifndef VM_MAXUSER_ADDRESS
+#define VM_MAXUSER_ADDRESS      KERNBASE
+#endif /* VM_MAXUSER_ADDRESS */
+#define VM_MAX_ADDRESS          VM_MAXUSER_ADDRESS
+
+#define USRSTACK        VM_MAXUSER_ADDRESS
+
+/* initial pagein size of beginning of executable file */
+#ifndef VM_INITIAL_PAGEIN
+#define VM_INITIAL_PAGEIN       16
+#endif
+
+#ifndef VM_MIN_KERNEL_ADDRESS
+#define VM_MIN_KERNEL_ADDRESS KERNBASE
+#endif
+
+#define	VM_MAX_KERNEL_ADDRESS	(vm_max_kernel_address)
+
+/*
+ * How many physical pages per kmem arena virtual page.
+ */
+#ifndef VM_KMEM_SIZE_SCALE
+#define	VM_KMEM_SIZE_SCALE	(3)
+#endif
+
+/*
+ * Optional floor (in bytes) on the size of the kmem arena.
+ */
+#ifndef VM_KMEM_SIZE_MIN
+#define	VM_KMEM_SIZE_MIN	(12 * 1024 * 1024)
+#endif
+
+/*
+ * Optional ceiling (in bytes) on the size of the kmem arena: 40% of the
+ * kernel map.
+ */
+#ifndef VM_KMEM_SIZE_MAX
+#define	VM_KMEM_SIZE_MAX	((vm_max_kernel_address - \
+    VM_MIN_KERNEL_ADDRESS + 1) * 2 / 5)
+#endif
+
+extern vm_offset_t vm_max_kernel_address;
+
+#define	ZERO_REGION_SIZE	(64 * 1024)	/* 64KB */
+
+#ifndef VM_MAX_AUTOTUNE_MAXUSERS
+#define	VM_MAX_AUTOTUNE_MAXUSERS	384
+#endif
+
+#endif	/* _MACHINE_VMPARAM_H_ */


Property changes on: trunk/sys/arm/include/vmparam.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/lpc/files.lpc
===================================================================
--- trunk/sys/arm/lpc/files.lpc	                        (rev 0)
+++ trunk/sys/arm/lpc/files.lpc	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,20 @@
+# $FreeBSD: stable/10/sys/arm/lpc/files.lpc 278727 2015-02-13 22:32:02Z ian $
+arm/arm/bus_space_base.c		standard
+arm/arm/bus_space_generic.c		standard
+arm/arm/cpufunc_asm_arm9.S		standard
+arm/arm/cpufunc_asm_armv5.S		standard
+arm/lpc/lpc_machdep.c			standard
+arm/lpc/lpc_pwr.c			standard
+arm/lpc/lpc_intc.c			standard
+arm/lpc/lpc_timer.c			standard
+arm/lpc/lpc_rtc.c			standard
+arm/lpc/if_lpe.c			optional	lpe
+arm/lpc/lpc_ohci.c			optional	ohci
+arm/lpc/lpc_mmc.c			optional	lpcmmc
+arm/lpc/lpc_fb.c			optional	lpcfb
+arm/lpc/lpc_gpio.c			optional	lpcgpio
+arm/lpc/lpc_spi.c			optional	lpcspi
+arm/lpc/lpc_dmac.c			optional	dmac
+arm/lpc/ssd1289.c			optional	ssd1289
+dev/uart/uart_dev_lpc.c			optional	uart
+kern/kern_clocksource.c			standard


Property changes on: trunk/sys/arm/lpc/files.lpc
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/lpc/if_lpe.c
===================================================================
--- trunk/sys/arm/lpc/if_lpe.c	                        (rev 0)
+++ trunk/sys/arm/lpc/if_lpe.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,1233 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2011 Jakub Wojciech Klama <jceel at FreeBSD.org>
+ * 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: stable/10/sys/arm/lpc/if_lpe.c 266152 2014-05-15 16:11:06Z ian $");
+
+#include <sys/param.h>
+#include <sys/endian.h>
+#include <sys/systm.h>
+#include <sys/sockio.h>
+#include <sys/mbuf.h>
+#include <sys/malloc.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/rman.h>
+#include <sys/bus.h>
+#include <sys/socket.h>
+#include <machine/bus.h>
+#include <machine/intr.h>
+
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <net/ethernet.h>
+#include <net/if_dl.h>
+#include <net/if_media.h>
+#include <net/if_types.h>
+#include <net/if_var.h>
+
+#include <net/bpf.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <dev/mii/mii.h>
+#include <dev/mii/miivar.h>
+
+#include <arm/lpc/lpcreg.h>
+#include <arm/lpc/lpcvar.h>
+#include <arm/lpc/if_lpereg.h>
+
+#include "miibus_if.h"
+
+#ifdef DEBUG
+#define debugf(fmt, args...) do { printf("%s(): ", __func__);   \
+    printf(fmt,##args); } while (0)
+#else
+#define debugf(fmt, args...)
+#endif
+
+struct lpe_dmamap_arg {
+	bus_addr_t		lpe_dma_busaddr;
+};
+
+struct lpe_rxdesc {
+	struct mbuf *		lpe_rxdesc_mbuf;
+	bus_dmamap_t		lpe_rxdesc_dmamap;
+};
+
+struct lpe_txdesc {
+	int			lpe_txdesc_first;
+	struct mbuf *		lpe_txdesc_mbuf;
+	bus_dmamap_t		lpe_txdesc_dmamap;
+};
+
+struct lpe_chain_data {
+	bus_dma_tag_t		lpe_parent_tag;
+	bus_dma_tag_t		lpe_tx_ring_tag;
+	bus_dmamap_t		lpe_tx_ring_map;
+	bus_dma_tag_t		lpe_tx_status_tag;
+	bus_dmamap_t		lpe_tx_status_map;
+	bus_dma_tag_t		lpe_tx_buf_tag;
+	bus_dma_tag_t		lpe_rx_ring_tag;
+	bus_dmamap_t		lpe_rx_ring_map;
+	bus_dma_tag_t		lpe_rx_status_tag;
+	bus_dmamap_t		lpe_rx_status_map;
+	bus_dma_tag_t		lpe_rx_buf_tag;
+	struct lpe_rxdesc	lpe_rx_desc[LPE_RXDESC_NUM];
+	struct lpe_txdesc	lpe_tx_desc[LPE_TXDESC_NUM];
+	int			lpe_tx_prod;
+	int			lpe_tx_last;
+	int			lpe_tx_used;
+};
+
+struct lpe_ring_data {
+	struct lpe_hwdesc *	lpe_rx_ring;
+	struct lpe_hwstatus *	lpe_rx_status;
+	bus_addr_t		lpe_rx_ring_phys;
+	bus_addr_t		lpe_rx_status_phys;
+	struct lpe_hwdesc *	lpe_tx_ring;
+	struct lpe_hwstatus *	lpe_tx_status;
+	bus_addr_t		lpe_tx_ring_phys;
+	bus_addr_t		lpe_tx_status_phys;
+};
+
+struct lpe_softc {
+	struct ifnet *		lpe_ifp;
+	struct mtx		lpe_mtx;
+	phandle_t		lpe_ofw;
+	device_t		lpe_dev;
+	device_t		lpe_miibus;
+	uint8_t			lpe_enaddr[6];
+	struct resource	*	lpe_mem_res;
+	struct resource *	lpe_irq_res;
+	void *			lpe_intrhand;
+	bus_space_tag_t		lpe_bst;
+	bus_space_handle_t	lpe_bsh;
+#define	LPE_FLAG_LINK		(1 << 0)
+	uint32_t		lpe_flags;
+	int			lpe_watchdog_timer;
+	struct callout		lpe_tick;
+	struct lpe_chain_data	lpe_cdata;
+	struct lpe_ring_data	lpe_rdata;
+};
+
+static int lpe_probe(device_t);
+static int lpe_attach(device_t);
+static int lpe_detach(device_t);
+static int lpe_miibus_readreg(device_t, int, int);
+static int lpe_miibus_writereg(device_t, int, int, int);
+static void lpe_miibus_statchg(device_t);
+
+static void lpe_reset(struct lpe_softc *);
+static void lpe_init(void *);
+static void lpe_init_locked(struct lpe_softc *);
+static void lpe_start(struct ifnet *);
+static void lpe_start_locked(struct ifnet *);
+static void lpe_stop(struct lpe_softc *);
+static void lpe_stop_locked(struct lpe_softc *);
+static int lpe_ioctl(struct ifnet *, u_long, caddr_t);
+static void lpe_set_rxmode(struct lpe_softc *);
+static void lpe_set_rxfilter(struct lpe_softc *);
+static void lpe_intr(void *);
+static void lpe_rxintr(struct lpe_softc *);
+static void lpe_txintr(struct lpe_softc *);
+static void lpe_tick(void *);
+static void lpe_watchdog(struct lpe_softc *);
+static int lpe_encap(struct lpe_softc *, struct mbuf **);
+static int lpe_dma_alloc(struct lpe_softc *);
+static int lpe_dma_alloc_rx(struct lpe_softc *);
+static int lpe_dma_alloc_tx(struct lpe_softc *);
+static int lpe_init_rx(struct lpe_softc *);
+static int lpe_init_rxbuf(struct lpe_softc *, int);
+static void lpe_discard_rxbuf(struct lpe_softc *, int);
+static void lpe_dmamap_cb(void *, bus_dma_segment_t *, int, int);
+static int lpe_ifmedia_upd(struct ifnet *);
+static void lpe_ifmedia_sts(struct ifnet *, struct ifmediareq *);
+
+#define	lpe_lock(_sc)		mtx_lock(&(_sc)->lpe_mtx)
+#define	lpe_unlock(_sc)		mtx_unlock(&(_sc)->lpe_mtx)
+#define	lpe_lock_assert(sc)	mtx_assert(&(_sc)->lpe_mtx, MA_OWNED)
+
+#define	lpe_read_4(_sc, _reg)		\
+    bus_space_read_4((_sc)->lpe_bst, (_sc)->lpe_bsh, (_reg))
+#define	lpe_write_4(_sc, _reg, _val)	\
+    bus_space_write_4((_sc)->lpe_bst, (_sc)->lpe_bsh, (_reg), (_val))
+
+#define	LPE_HWDESC_RXERRS	(LPE_HWDESC_CRCERROR | LPE_HWDESC_SYMBOLERROR | \
+    LPE_HWDESC_LENGTHERROR | LPE_HWDESC_ALIGNERROR | LPE_HWDESC_OVERRUN | \
+    LPE_HWDESC_RXNODESCR)
+
+#define	LPE_HWDESC_TXERRS	(LPE_HWDESC_EXCDEFER | LPE_HWDESC_EXCCOLL | \
+    LPE_HWDESC_LATECOLL | LPE_HWDESC_UNDERRUN | LPE_HWDESC_TXNODESCR)
+
+static int
+lpe_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "lpc,ethernet"))
+		return (ENXIO);
+
+	device_set_desc(dev, "LPC32x0 10/100 Ethernet");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+lpe_attach(device_t dev)
+{
+	struct lpe_softc *sc = device_get_softc(dev);
+	struct ifnet *ifp;
+	int rid, i;
+	uint32_t val;
+
+	sc->lpe_dev = dev;
+	sc->lpe_ofw = ofw_bus_get_node(dev);
+
+	i = OF_getprop(sc->lpe_ofw, "local-mac-address", (void *)&sc->lpe_enaddr, 6);
+	if (i != 6) {
+		sc->lpe_enaddr[0] = 0x00;
+		sc->lpe_enaddr[1] = 0x11;
+		sc->lpe_enaddr[2] = 0x22;
+		sc->lpe_enaddr[3] = 0x33;
+		sc->lpe_enaddr[4] = 0x44;
+		sc->lpe_enaddr[5] = 0x55;
+	}
+
+	mtx_init(&sc->lpe_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
+	    MTX_DEF);
+
+	callout_init_mtx(&sc->lpe_tick, &sc->lpe_mtx, 0);
+
+	rid = 0;
+	sc->lpe_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	    RF_ACTIVE);
+	if (!sc->lpe_mem_res) {
+		device_printf(dev, "cannot allocate memory window\n");
+		goto fail;
+	}
+
+	sc->lpe_bst = rman_get_bustag(sc->lpe_mem_res);
+	sc->lpe_bsh = rman_get_bushandle(sc->lpe_mem_res);
+
+	rid = 0;
+	sc->lpe_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+	    RF_ACTIVE);
+	if (!sc->lpe_irq_res) {
+		device_printf(dev, "cannot allocate interrupt\n");
+		goto fail;
+	}
+
+	sc->lpe_ifp = if_alloc(IFT_ETHER);
+	if (!sc->lpe_ifp) {
+		device_printf(dev, "cannot allocated ifnet\n");
+		goto fail;
+	}
+
+	ifp = sc->lpe_ifp;
+
+	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
+	ifp->if_softc = sc;
+	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+	ifp->if_start = lpe_start;
+	ifp->if_ioctl = lpe_ioctl;
+	ifp->if_init = lpe_init;
+	IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
+	ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
+	IFQ_SET_READY(&ifp->if_snd);
+
+	ether_ifattach(ifp, sc->lpe_enaddr);
+
+	if (bus_setup_intr(dev, sc->lpe_irq_res, INTR_TYPE_NET, NULL,
+	    lpe_intr, sc, &sc->lpe_intrhand)) {
+		device_printf(dev, "cannot establish interrupt handler\n");
+		ether_ifdetach(ifp);
+		goto fail;
+	}
+
+	/* Enable Ethernet clock */
+	lpc_pwr_write(dev, LPC_CLKPWR_MACCLK_CTRL,
+	    LPC_CLKPWR_MACCLK_CTRL_REG |
+	    LPC_CLKPWR_MACCLK_CTRL_SLAVE |
+	    LPC_CLKPWR_MACCLK_CTRL_MASTER |
+	    LPC_CLKPWR_MACCLK_CTRL_HDWINF(3));
+
+	/* Reset chip */
+	lpe_reset(sc);
+
+	/* Initialize MII */
+	val = lpe_read_4(sc, LPE_COMMAND);
+	lpe_write_4(sc, LPE_COMMAND, val | LPE_COMMAND_RMII);
+
+	if (mii_attach(dev, &sc->lpe_miibus, ifp, lpe_ifmedia_upd,
+	    lpe_ifmedia_sts, BMSR_DEFCAPMASK, 0x01, 
+	    MII_OFFSET_ANY, 0)) {
+		device_printf(dev, "cannot find PHY\n");
+		goto fail;
+	}
+
+	lpe_dma_alloc(sc);
+
+	return (0);
+
+fail:
+	if (sc->lpe_ifp)
+		if_free(sc->lpe_ifp);
+	if (sc->lpe_intrhand)
+		bus_teardown_intr(dev, sc->lpe_irq_res, sc->lpe_intrhand);
+	if (sc->lpe_irq_res)
+		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->lpe_irq_res);
+	if (sc->lpe_mem_res)
+		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->lpe_mem_res);
+	return (ENXIO);
+}
+
+static int
+lpe_detach(device_t dev)
+{
+	struct lpe_softc *sc = device_get_softc(dev);
+
+	lpe_stop(sc);
+
+	if_free(sc->lpe_ifp);
+	bus_teardown_intr(dev, sc->lpe_irq_res, sc->lpe_intrhand);
+	bus_release_resource(dev, SYS_RES_IRQ, 0, sc->lpe_irq_res);
+	bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->lpe_mem_res);
+
+	return (0);
+}
+
+static int
+lpe_miibus_readreg(device_t dev, int phy, int reg)
+{
+	struct lpe_softc *sc = device_get_softc(dev);
+	uint32_t val;
+	int result;
+
+	lpe_write_4(sc, LPE_MCMD, LPE_MCMD_READ);
+	lpe_write_4(sc, LPE_MADR, 
+	    (reg & LPE_MADR_REGMASK) << LPE_MADR_REGSHIFT |
+	    (phy & LPE_MADR_PHYMASK) << LPE_MADR_PHYSHIFT);
+
+	val = lpe_read_4(sc, LPE_MIND);
+
+	/* Wait until request is completed */
+	while (val & LPE_MIND_BUSY) {
+		val = lpe_read_4(sc, LPE_MIND);
+		DELAY(10);
+	}
+
+	if (val & LPE_MIND_INVALID)
+		return (0);
+
+	lpe_write_4(sc, LPE_MCMD, 0);
+	result = (lpe_read_4(sc, LPE_MRDD) & LPE_MRDD_DATAMASK);
+	debugf("phy=%d reg=%d result=0x%04x\n", phy, reg, result);
+
+	return (result);
+}
+
+static int
+lpe_miibus_writereg(device_t dev, int phy, int reg, int data)
+{
+	struct lpe_softc *sc = device_get_softc(dev);
+	uint32_t val;
+
+	debugf("phy=%d reg=%d data=0x%04x\n", phy, reg, data);
+
+	lpe_write_4(sc, LPE_MCMD, LPE_MCMD_WRITE);
+	lpe_write_4(sc, LPE_MADR, 
+	    (reg & LPE_MADR_REGMASK) << LPE_MADR_REGSHIFT |
+	    (phy & LPE_MADR_PHYMASK) << LPE_MADR_PHYSHIFT);
+
+	lpe_write_4(sc, LPE_MWTD, (data & LPE_MWTD_DATAMASK));
+
+	val = lpe_read_4(sc, LPE_MIND);
+
+	/* Wait until request is completed */
+	while (val & LPE_MIND_BUSY) {
+		val = lpe_read_4(sc, LPE_MIND);
+		DELAY(10);
+	}
+
+	return (0);
+}
+
+static void
+lpe_miibus_statchg(device_t dev)
+{
+	struct lpe_softc *sc = device_get_softc(dev);
+	struct mii_data *mii = device_get_softc(sc->lpe_miibus);
+
+	lpe_lock(sc);
+
+	if ((mii->mii_media_status & IFM_ACTIVE) &&
+	    (mii->mii_media_status & IFM_AVALID))
+		sc->lpe_flags |= LPE_FLAG_LINK;
+	else
+		sc->lpe_flags &= ~LPE_FLAG_LINK;
+
+	lpe_unlock(sc);
+}
+
+static void
+lpe_reset(struct lpe_softc *sc)
+{
+	uint32_t mac1;
+
+	/* Enter soft reset mode */
+	mac1 = lpe_read_4(sc, LPE_MAC1);
+	lpe_write_4(sc, LPE_MAC1, mac1 | LPE_MAC1_SOFTRESET | LPE_MAC1_RESETTX |
+	    LPE_MAC1_RESETMCSTX | LPE_MAC1_RESETRX | LPE_MAC1_RESETMCSRX);
+
+	/* Reset registers, Tx path and Rx path */
+	lpe_write_4(sc, LPE_COMMAND, LPE_COMMAND_REGRESET |
+	    LPE_COMMAND_TXRESET | LPE_COMMAND_RXRESET);
+
+	/* Set station address */
+	lpe_write_4(sc, LPE_SA2, sc->lpe_enaddr[1] << 8 | sc->lpe_enaddr[0]);
+	lpe_write_4(sc, LPE_SA1, sc->lpe_enaddr[3] << 8 | sc->lpe_enaddr[2]);
+	lpe_write_4(sc, LPE_SA0, sc->lpe_enaddr[5] << 8 | sc->lpe_enaddr[4]);
+
+	/* Leave soft reset mode */
+	mac1 = lpe_read_4(sc, LPE_MAC1);
+	lpe_write_4(sc, LPE_MAC1, mac1 & ~(LPE_MAC1_SOFTRESET | LPE_MAC1_RESETTX |
+	    LPE_MAC1_RESETMCSTX | LPE_MAC1_RESETRX | LPE_MAC1_RESETMCSRX));
+}
+
+static void
+lpe_init(void *arg)
+{
+	struct lpe_softc *sc = (struct lpe_softc *)arg;
+
+	lpe_lock(sc);
+	lpe_init_locked(sc);
+	lpe_unlock(sc);
+}
+
+static void
+lpe_init_locked(struct lpe_softc *sc)
+{
+	struct ifnet *ifp = sc->lpe_ifp;
+	uint32_t cmd, mac1;
+
+	lpe_lock_assert(sc);
+
+	if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+		return;
+
+	/* Enable Tx and Rx */
+	cmd = lpe_read_4(sc, LPE_COMMAND);
+	lpe_write_4(sc, LPE_COMMAND, cmd | LPE_COMMAND_RXENABLE |
+	    LPE_COMMAND_TXENABLE | LPE_COMMAND_PASSRUNTFRAME);
+
+	/* Enable receive */
+	mac1 = lpe_read_4(sc, LPE_MAC1);
+	lpe_write_4(sc, LPE_MAC1, /*mac1 |*/ LPE_MAC1_RXENABLE | LPE_MAC1_PASSALL);
+
+	lpe_write_4(sc, LPE_MAC2, LPE_MAC2_CRCENABLE | LPE_MAC2_PADCRCENABLE |
+	    LPE_MAC2_FULLDUPLEX);
+
+	lpe_write_4(sc, LPE_MCFG, LPE_MCFG_CLKSEL(7));
+
+	/* Set up Rx filter */
+	lpe_set_rxmode(sc);
+
+	/* Enable interrupts */
+	lpe_write_4(sc, LPE_INTENABLE, LPE_INT_RXOVERRUN | LPE_INT_RXERROR |
+	    LPE_INT_RXFINISH | LPE_INT_RXDONE | LPE_INT_TXUNDERRUN | 
+	    LPE_INT_TXERROR | LPE_INT_TXFINISH | LPE_INT_TXDONE);
+
+	sc->lpe_cdata.lpe_tx_prod = 0;
+	sc->lpe_cdata.lpe_tx_last = 0;
+	sc->lpe_cdata.lpe_tx_used = 0;
+
+	lpe_init_rx(sc);
+
+	/* Initialize Rx packet and status descriptor heads */
+	lpe_write_4(sc, LPE_RXDESC, sc->lpe_rdata.lpe_rx_ring_phys);
+	lpe_write_4(sc, LPE_RXSTATUS, sc->lpe_rdata.lpe_rx_status_phys);
+	lpe_write_4(sc, LPE_RXDESC_NUMBER, LPE_RXDESC_NUM - 1);
+	lpe_write_4(sc, LPE_RXDESC_CONS, 0);
+
+	/* Initialize Tx packet and status descriptor heads */
+	lpe_write_4(sc, LPE_TXDESC, sc->lpe_rdata.lpe_tx_ring_phys);
+	lpe_write_4(sc, LPE_TXSTATUS, sc->lpe_rdata.lpe_tx_status_phys);
+	lpe_write_4(sc, LPE_TXDESC_NUMBER, LPE_TXDESC_NUM - 1);
+	lpe_write_4(sc, LPE_TXDESC_PROD, 0);
+
+	ifp->if_drv_flags |= IFF_DRV_RUNNING;
+	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+
+	callout_reset(&sc->lpe_tick, hz, lpe_tick, sc);
+}
+
+static void
+lpe_start(struct ifnet *ifp)
+{
+	struct lpe_softc *sc = (struct lpe_softc *)ifp->if_softc;
+
+	lpe_lock(sc);
+	lpe_start_locked(ifp);
+	lpe_unlock(sc);
+}
+
+static void
+lpe_start_locked(struct ifnet *ifp)
+{
+	struct lpe_softc *sc = (struct lpe_softc *)ifp->if_softc;
+	struct mbuf *m_head;
+	int encap = 0;
+
+	lpe_lock_assert(sc);
+
+	while (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
+		if (lpe_read_4(sc, LPE_TXDESC_PROD) ==
+		    lpe_read_4(sc, LPE_TXDESC_CONS) - 5)
+			break;
+
+		/* Dequeue first packet */
+		IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head);
+		if (!m_head)
+			break;
+
+		lpe_encap(sc, &m_head);
+
+		encap++;
+	}
+
+	/* Submit new descriptor list */
+	if (encap) {
+		lpe_write_4(sc, LPE_TXDESC_PROD, sc->lpe_cdata.lpe_tx_prod);
+		sc->lpe_watchdog_timer = 5;
+	}
+	
+}
+
+static int
+lpe_encap(struct lpe_softc *sc, struct mbuf **m_head)
+{
+	struct lpe_txdesc *txd;
+	struct lpe_hwdesc *hwd;
+	bus_dma_segment_t segs[LPE_MAXFRAGS];
+	int i, err, nsegs, prod;
+
+	lpe_lock_assert(sc);
+	M_ASSERTPKTHDR((*m_head));
+
+	prod = sc->lpe_cdata.lpe_tx_prod;
+	txd = &sc->lpe_cdata.lpe_tx_desc[prod];
+
+	debugf("starting with prod=%d\n", prod);
+
+	err = bus_dmamap_load_mbuf_sg(sc->lpe_cdata.lpe_tx_buf_tag,
+	    txd->lpe_txdesc_dmamap, *m_head, segs, &nsegs, BUS_DMA_NOWAIT);
+
+	if (err)
+		return (err);
+
+	if (nsegs == 0) {
+		m_freem(*m_head);
+		*m_head = NULL;
+		return (EIO);
+	}
+
+        bus_dmamap_sync(sc->lpe_cdata.lpe_tx_buf_tag, txd->lpe_txdesc_dmamap,
+          BUS_DMASYNC_PREREAD);
+        bus_dmamap_sync(sc->lpe_cdata.lpe_tx_ring_tag, sc->lpe_cdata.lpe_tx_ring_map,
+            BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
+
+	txd->lpe_txdesc_first = 1;
+	txd->lpe_txdesc_mbuf = *m_head;
+
+	for (i = 0; i < nsegs; i++) {
+		hwd = &sc->lpe_rdata.lpe_tx_ring[prod];
+		hwd->lhr_data = segs[i].ds_addr;
+		hwd->lhr_control = segs[i].ds_len - 1;
+
+		if (i == nsegs - 1) {
+			hwd->lhr_control |= LPE_HWDESC_LASTFLAG;
+			hwd->lhr_control |= LPE_HWDESC_INTERRUPT;
+			hwd->lhr_control |= LPE_HWDESC_CRC;
+			hwd->lhr_control |= LPE_HWDESC_PAD;
+		}
+
+		LPE_INC(prod, LPE_TXDESC_NUM);
+	}
+
+	bus_dmamap_sync(sc->lpe_cdata.lpe_tx_ring_tag, sc->lpe_cdata.lpe_tx_ring_map,
+	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+
+	sc->lpe_cdata.lpe_tx_used += nsegs;
+	sc->lpe_cdata.lpe_tx_prod = prod;
+
+	return (0);
+}
+
+static void
+lpe_stop(struct lpe_softc *sc)
+{
+	lpe_lock(sc);
+	lpe_stop_locked(sc);
+	lpe_unlock(sc);
+}
+
+static void
+lpe_stop_locked(struct lpe_softc *sc)
+{
+	lpe_lock_assert(sc);
+
+	callout_stop(&sc->lpe_tick);
+
+	/* Disable interrupts */
+	lpe_write_4(sc, LPE_INTCLEAR, 0xffffffff);
+
+	/* Stop EMAC */
+	lpe_write_4(sc, LPE_MAC1, 0);
+	lpe_write_4(sc, LPE_MAC2, 0);
+	lpe_write_4(sc, LPE_COMMAND, 0);
+
+	sc->lpe_ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+	sc->lpe_ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
+}
+
+static int
+lpe_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
+{
+	struct lpe_softc *sc = ifp->if_softc;
+	struct mii_data *mii = device_get_softc(sc->lpe_miibus);
+	struct ifreq *ifr = (struct ifreq *)data;
+	int err = 0;
+
+	switch (cmd) {
+	case SIOCSIFFLAGS:
+		lpe_lock(sc);
+		if (ifp->if_flags & IFF_UP) {
+			if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
+				lpe_set_rxmode(sc);
+				lpe_set_rxfilter(sc);
+			} else
+				lpe_init_locked(sc);
+		} else
+			lpe_stop(sc);
+		lpe_unlock(sc);
+		break;
+	case SIOCADDMULTI:
+	case SIOCDELMULTI:
+		if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
+			lpe_lock(sc);
+			lpe_set_rxfilter(sc);
+			lpe_unlock(sc);
+		}
+		break;
+	case SIOCGIFMEDIA:
+	case SIOCSIFMEDIA:
+		err = ifmedia_ioctl(ifp, ifr, &mii->mii_media, cmd);
+		break;
+	default:
+		err = ether_ioctl(ifp, cmd, data);
+		break;
+	}
+
+	return (err);
+}
+
+static void lpe_set_rxmode(struct lpe_softc *sc)
+{
+	struct ifnet *ifp = sc->lpe_ifp;
+	uint32_t rxfilt;
+
+	rxfilt = LPE_RXFILTER_UNIHASH | LPE_RXFILTER_MULTIHASH | LPE_RXFILTER_PERFECT;
+
+	if (ifp->if_flags & IFF_BROADCAST)
+		rxfilt |= LPE_RXFILTER_BROADCAST;
+
+	if (ifp->if_flags & IFF_PROMISC)
+		rxfilt |= LPE_RXFILTER_UNICAST | LPE_RXFILTER_MULTICAST;
+
+	if (ifp->if_flags & IFF_ALLMULTI)
+		rxfilt |= LPE_RXFILTER_MULTICAST;
+
+	lpe_write_4(sc, LPE_RXFILTER_CTRL, rxfilt);
+}
+
+static void lpe_set_rxfilter(struct lpe_softc *sc)
+{
+	struct ifnet *ifp = sc->lpe_ifp;
+	struct ifmultiaddr *ifma;
+	int index;
+	uint32_t hashl, hashh;
+
+	hashl = 0;
+	hashh = 0;
+
+	if_maddr_rlock(ifp);
+	TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
+		if (ifma->ifma_addr->sa_family != AF_LINK)
+			continue;
+
+		index = ether_crc32_be(LLADDR((struct sockaddr_dl *)
+		    ifma->ifma_addr), ETHER_ADDR_LEN) >> 23 & 0x3f;
+
+		if (index > 31)
+			hashh |= (1 << (index - 32));
+		else
+			hashl |= (1 << index);
+	}
+	if_maddr_runlock(ifp);
+
+	/* Program new hash filter */
+	lpe_write_4(sc, LPE_HASHFILTER_L, hashl);
+	lpe_write_4(sc, LPE_HASHFILTER_H, hashh);
+}
+
+static void
+lpe_intr(void *arg)
+{
+	struct lpe_softc *sc = (struct lpe_softc *)arg;
+	uint32_t intstatus;
+
+	debugf("status=0x%08x\n", lpe_read_4(sc, LPE_INTSTATUS));
+
+	lpe_lock(sc);
+
+	while ((intstatus = lpe_read_4(sc, LPE_INTSTATUS))) {
+		if (intstatus & LPE_INT_RXDONE)
+			lpe_rxintr(sc);
+
+		if (intstatus & LPE_INT_TXDONE)
+			lpe_txintr(sc);
+	
+		lpe_write_4(sc, LPE_INTCLEAR, 0xffff);
+	}
+
+	lpe_unlock(sc);
+}
+
+static void
+lpe_rxintr(struct lpe_softc *sc)
+{
+	struct ifnet *ifp = sc->lpe_ifp;
+	struct lpe_hwdesc *hwd;
+	struct lpe_hwstatus *hws;
+	struct lpe_rxdesc *rxd;
+	struct mbuf *m;
+	int prod, cons;
+
+	for (;;) {
+		prod = lpe_read_4(sc, LPE_RXDESC_PROD);
+		cons = lpe_read_4(sc, LPE_RXDESC_CONS);
+		
+		if (prod == cons)
+			break;
+
+		rxd = &sc->lpe_cdata.lpe_rx_desc[cons];
+		hwd = &sc->lpe_rdata.lpe_rx_ring[cons];
+		hws = &sc->lpe_rdata.lpe_rx_status[cons];
+
+		/* Check received frame for errors */
+		if (hws->lhs_info & LPE_HWDESC_RXERRS) {
+			ifp->if_ierrors++;
+			lpe_discard_rxbuf(sc, cons);
+			lpe_init_rxbuf(sc, cons);
+			goto skip;
+		}
+
+		m = rxd->lpe_rxdesc_mbuf;
+		m->m_pkthdr.rcvif = ifp;
+		m->m_data += 2;
+
+		ifp->if_ipackets++;
+
+		lpe_unlock(sc);
+		(*ifp->if_input)(ifp, m);	
+		lpe_lock(sc);
+
+		lpe_init_rxbuf(sc, cons);
+skip:
+		LPE_INC(cons, LPE_RXDESC_NUM);
+		lpe_write_4(sc, LPE_RXDESC_CONS, cons);
+	}
+}
+
+static void
+lpe_txintr(struct lpe_softc *sc)
+{
+	struct ifnet *ifp = sc->lpe_ifp;
+	struct lpe_hwdesc *hwd;
+	struct lpe_hwstatus *hws;
+	struct lpe_txdesc *txd;
+	int cons, last;
+
+	for (;;) {
+		cons = lpe_read_4(sc, LPE_TXDESC_CONS);
+		last = sc->lpe_cdata.lpe_tx_last;
+		
+		if (cons == last)
+			break;
+
+		txd = &sc->lpe_cdata.lpe_tx_desc[last];
+		hwd = &sc->lpe_rdata.lpe_tx_ring[last];
+		hws = &sc->lpe_rdata.lpe_tx_status[last];
+
+		bus_dmamap_sync(sc->lpe_cdata.lpe_tx_buf_tag,
+		    txd->lpe_txdesc_dmamap, BUS_DMASYNC_POSTWRITE);
+
+		ifp->if_collisions += LPE_HWDESC_COLLISIONS(hws->lhs_info);
+
+		if (hws->lhs_info & LPE_HWDESC_TXERRS)
+			ifp->if_oerrors++;
+		else
+			ifp->if_opackets++;
+
+		if (txd->lpe_txdesc_first) {
+			bus_dmamap_unload(sc->lpe_cdata.lpe_tx_buf_tag,
+			    txd->lpe_txdesc_dmamap);	
+
+			m_freem(txd->lpe_txdesc_mbuf);
+			txd->lpe_txdesc_mbuf = NULL;
+			txd->lpe_txdesc_first = 0;
+		}
+
+		sc->lpe_cdata.lpe_tx_used--;
+		LPE_INC(sc->lpe_cdata.lpe_tx_last, LPE_TXDESC_NUM);
+	}
+
+	if (!sc->lpe_cdata.lpe_tx_used)
+		sc->lpe_watchdog_timer = 0;
+}
+
+static void
+lpe_tick(void *arg)
+{
+	struct lpe_softc *sc = (struct lpe_softc *)arg;
+	struct mii_data *mii = device_get_softc(sc->lpe_miibus);
+
+	lpe_lock_assert(sc);
+	
+	mii_tick(mii);
+	lpe_watchdog(sc);
+
+	callout_reset(&sc->lpe_tick, hz, lpe_tick, sc);
+}
+
+static void
+lpe_watchdog(struct lpe_softc *sc)
+{
+	struct ifnet *ifp = sc->lpe_ifp;
+
+	lpe_lock_assert(sc);
+
+	if (sc->lpe_watchdog_timer == 0 || sc->lpe_watchdog_timer--)
+		return;
+
+	/* Chip has stopped responding */
+	device_printf(sc->lpe_dev, "WARNING: chip hangup, restarting...\n");
+	lpe_stop_locked(sc);
+	lpe_init_locked(sc);
+
+	/* Try to resend packets */
+	if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
+		lpe_start_locked(ifp);
+}
+
+static int
+lpe_dma_alloc(struct lpe_softc *sc)
+{
+	int err;
+
+	/* Create parent DMA tag */
+	err = bus_dma_tag_create(
+	    bus_get_dma_tag(sc->lpe_dev),
+	    1, 0,			/* alignment, boundary */
+	    BUS_SPACE_MAXADDR_32BIT,	/* lowaddr */
+	    BUS_SPACE_MAXADDR,		/* highaddr */
+	    NULL, NULL,			/* filter, filterarg */
+	    BUS_SPACE_MAXSIZE_32BIT, 0,	/* maxsize, nsegments */
+	    BUS_SPACE_MAXSIZE_32BIT, 0,	/* maxsegsize, flags */
+	    NULL, NULL,			/* lockfunc, lockarg */
+	    &sc->lpe_cdata.lpe_parent_tag);
+
+	if (err) {
+		device_printf(sc->lpe_dev, "cannot create parent DMA tag\n");
+		return (err);
+	}
+
+	err = lpe_dma_alloc_rx(sc);
+	if (err)
+		return (err);
+
+	err = lpe_dma_alloc_tx(sc);
+	if (err)
+		return (err);
+
+	return (0);
+}
+
+static int
+lpe_dma_alloc_rx(struct lpe_softc *sc)
+{
+	struct lpe_rxdesc *rxd;
+	struct lpe_dmamap_arg ctx;
+	int err, i;
+
+	/* Create tag for Rx ring */
+	err = bus_dma_tag_create(
+	    sc->lpe_cdata.lpe_parent_tag,
+	    LPE_DESC_ALIGN, 0,		/* alignment, boundary */
+	    BUS_SPACE_MAXADDR,		/* lowaddr */
+	    BUS_SPACE_MAXADDR,		/* highaddr */
+	    NULL, NULL,			/* filter, filterarg */
+	    LPE_RXDESC_SIZE, 1,		/* maxsize, nsegments */
+	    LPE_RXDESC_SIZE, 0,		/* maxsegsize, flags */
+	    NULL, NULL,			/* lockfunc, lockarg */
+	    &sc->lpe_cdata.lpe_rx_ring_tag);
+
+	if (err) {
+		device_printf(sc->lpe_dev, "cannot create Rx ring DMA tag\n");
+		goto fail;
+	}
+
+	/* Create tag for Rx status ring */
+	err = bus_dma_tag_create(
+	    sc->lpe_cdata.lpe_parent_tag,
+	    LPE_DESC_ALIGN, 0,		/* alignment, boundary */
+	    BUS_SPACE_MAXADDR,		/* lowaddr */
+	    BUS_SPACE_MAXADDR,		/* highaddr */
+	    NULL, NULL,			/* filter, filterarg */
+	    LPE_RXSTATUS_SIZE, 1,	/* maxsize, nsegments */
+	    LPE_RXSTATUS_SIZE, 0,	/* maxsegsize, flags */
+	    NULL, NULL,			/* lockfunc, lockarg */
+	    &sc->lpe_cdata.lpe_rx_status_tag);
+
+	if (err) {
+		device_printf(sc->lpe_dev, "cannot create Rx status ring DMA tag\n");
+		goto fail;
+	}
+
+	/* Create tag for Rx buffers */
+	err = bus_dma_tag_create(
+	    sc->lpe_cdata.lpe_parent_tag,
+	    LPE_DESC_ALIGN, 0,		/* alignment, boundary */
+	    BUS_SPACE_MAXADDR,		/* lowaddr */
+	    BUS_SPACE_MAXADDR,		/* highaddr */
+	    NULL, NULL,			/* filter, filterarg */
+	    MCLBYTES * LPE_RXDESC_NUM,	/* maxsize */
+	    LPE_RXDESC_NUM,		/* segments */
+	    MCLBYTES, 0,		/* maxsegsize, flags */
+	    NULL, NULL,			/* lockfunc, lockarg */
+	    &sc->lpe_cdata.lpe_rx_buf_tag);
+
+	if (err) {
+		device_printf(sc->lpe_dev, "cannot create Rx buffers DMA tag\n");
+		goto fail;
+	}
+
+	/* Allocate Rx DMA ring */
+	err = bus_dmamem_alloc(sc->lpe_cdata.lpe_rx_ring_tag,
+	    (void **)&sc->lpe_rdata.lpe_rx_ring, BUS_DMA_WAITOK | BUS_DMA_COHERENT |
+	    BUS_DMA_ZERO, &sc->lpe_cdata.lpe_rx_ring_map);
+
+	err = bus_dmamap_load(sc->lpe_cdata.lpe_rx_ring_tag, 
+	    sc->lpe_cdata.lpe_rx_ring_map, sc->lpe_rdata.lpe_rx_ring,
+	    LPE_RXDESC_SIZE, lpe_dmamap_cb, &ctx, 0);
+
+	sc->lpe_rdata.lpe_rx_ring_phys = ctx.lpe_dma_busaddr;
+
+	/* Allocate Rx status ring */
+	err = bus_dmamem_alloc(sc->lpe_cdata.lpe_rx_status_tag,
+	    (void **)&sc->lpe_rdata.lpe_rx_status, BUS_DMA_WAITOK | BUS_DMA_COHERENT |
+	    BUS_DMA_ZERO, &sc->lpe_cdata.lpe_rx_status_map);
+
+	err = bus_dmamap_load(sc->lpe_cdata.lpe_rx_status_tag, 
+	    sc->lpe_cdata.lpe_rx_status_map, sc->lpe_rdata.lpe_rx_status,
+	    LPE_RXDESC_SIZE, lpe_dmamap_cb, &ctx, 0);
+
+	sc->lpe_rdata.lpe_rx_status_phys = ctx.lpe_dma_busaddr;
+
+
+	/* Create Rx buffers DMA map */
+	for (i = 0; i < LPE_RXDESC_NUM; i++) {
+		rxd = &sc->lpe_cdata.lpe_rx_desc[i];
+		rxd->lpe_rxdesc_mbuf = NULL;
+		rxd->lpe_rxdesc_dmamap = NULL;
+
+		err = bus_dmamap_create(sc->lpe_cdata.lpe_rx_buf_tag, 0,
+		    &rxd->lpe_rxdesc_dmamap);
+
+		if (err) {
+			device_printf(sc->lpe_dev, "cannot create Rx DMA map\n");
+			return (err);
+		}
+	}
+
+	return (0);
+fail:
+	return (err);
+}
+
+static int
+lpe_dma_alloc_tx(struct lpe_softc *sc)
+{
+	struct lpe_txdesc *txd;
+	struct lpe_dmamap_arg ctx;
+	int err, i;
+
+	/* Create tag for Tx ring */
+	err = bus_dma_tag_create(
+	    sc->lpe_cdata.lpe_parent_tag,
+	    LPE_DESC_ALIGN, 0,		/* alignment, boundary */
+	    BUS_SPACE_MAXADDR,		/* lowaddr */
+	    BUS_SPACE_MAXADDR,		/* highaddr */
+	    NULL, NULL,			/* filter, filterarg */
+	    LPE_TXDESC_SIZE, 1,		/* maxsize, nsegments */
+	    LPE_TXDESC_SIZE, 0,		/* maxsegsize, flags */
+	    NULL, NULL,			/* lockfunc, lockarg */
+	    &sc->lpe_cdata.lpe_tx_ring_tag);
+
+	if (err) {
+		device_printf(sc->lpe_dev, "cannot create Tx ring DMA tag\n");
+		goto fail;
+	}
+
+	/* Create tag for Tx status ring */
+	err = bus_dma_tag_create(
+	    sc->lpe_cdata.lpe_parent_tag,
+	    LPE_DESC_ALIGN, 0,		/* alignment, boundary */
+	    BUS_SPACE_MAXADDR,		/* lowaddr */
+	    BUS_SPACE_MAXADDR,		/* highaddr */
+	    NULL, NULL,			/* filter, filterarg */
+	    LPE_TXSTATUS_SIZE, 1,	/* maxsize, nsegments */
+	    LPE_TXSTATUS_SIZE, 0,	/* maxsegsize, flags */
+	    NULL, NULL,			/* lockfunc, lockarg */
+	    &sc->lpe_cdata.lpe_tx_status_tag);
+
+	if (err) {
+		device_printf(sc->lpe_dev, "cannot create Tx status ring DMA tag\n");
+		goto fail;
+	}
+
+	/* Create tag for Tx buffers */
+	err = bus_dma_tag_create(
+	    sc->lpe_cdata.lpe_parent_tag,
+	    LPE_DESC_ALIGN, 0,		/* alignment, boundary */
+	    BUS_SPACE_MAXADDR,		/* lowaddr */
+	    BUS_SPACE_MAXADDR,		/* highaddr */
+	    NULL, NULL,			/* filter, filterarg */
+	    MCLBYTES * LPE_TXDESC_NUM,	/* maxsize */
+	    LPE_TXDESC_NUM,		/* segments */
+	    MCLBYTES, 0,		/* maxsegsize, flags */
+	    NULL, NULL,			/* lockfunc, lockarg */
+	    &sc->lpe_cdata.lpe_tx_buf_tag);
+
+	if (err) {
+		device_printf(sc->lpe_dev, "cannot create Tx buffers DMA tag\n");
+		goto fail;
+	}
+
+	/* Allocate Tx DMA ring */
+	err = bus_dmamem_alloc(sc->lpe_cdata.lpe_tx_ring_tag,
+	    (void **)&sc->lpe_rdata.lpe_tx_ring, BUS_DMA_WAITOK | BUS_DMA_COHERENT |
+	    BUS_DMA_ZERO, &sc->lpe_cdata.lpe_tx_ring_map);
+
+	err = bus_dmamap_load(sc->lpe_cdata.lpe_tx_ring_tag, 
+	    sc->lpe_cdata.lpe_tx_ring_map, sc->lpe_rdata.lpe_tx_ring,
+	    LPE_RXDESC_SIZE, lpe_dmamap_cb, &ctx, 0);
+
+	sc->lpe_rdata.lpe_tx_ring_phys = ctx.lpe_dma_busaddr;
+
+	/* Allocate Tx status ring */
+	err = bus_dmamem_alloc(sc->lpe_cdata.lpe_tx_status_tag,
+	    (void **)&sc->lpe_rdata.lpe_tx_status, BUS_DMA_WAITOK | BUS_DMA_COHERENT |
+	    BUS_DMA_ZERO, &sc->lpe_cdata.lpe_tx_status_map);
+
+	err = bus_dmamap_load(sc->lpe_cdata.lpe_tx_status_tag, 
+	    sc->lpe_cdata.lpe_tx_status_map, sc->lpe_rdata.lpe_tx_status,
+	    LPE_RXDESC_SIZE, lpe_dmamap_cb, &ctx, 0);
+
+	sc->lpe_rdata.lpe_tx_status_phys = ctx.lpe_dma_busaddr;
+
+
+	/* Create Tx buffers DMA map */
+	for (i = 0; i < LPE_TXDESC_NUM; i++) {
+		txd = &sc->lpe_cdata.lpe_tx_desc[i];
+		txd->lpe_txdesc_mbuf = NULL;
+		txd->lpe_txdesc_dmamap = NULL;
+		txd->lpe_txdesc_first = 0;
+
+		err = bus_dmamap_create(sc->lpe_cdata.lpe_tx_buf_tag, 0,
+		    &txd->lpe_txdesc_dmamap);
+
+		if (err) {
+			device_printf(sc->lpe_dev, "cannot create Tx DMA map\n");
+			return (err);
+		}
+	}
+
+	return (0);
+fail:
+	return (err);
+}
+
+static int
+lpe_init_rx(struct lpe_softc *sc)
+{
+	int i, err;
+
+	for (i = 0; i < LPE_RXDESC_NUM; i++) {
+		err = lpe_init_rxbuf(sc, i);
+		if (err)
+			return (err);
+	}
+
+	return (0);
+}
+
+static int
+lpe_init_rxbuf(struct lpe_softc *sc, int n)
+{
+	struct lpe_rxdesc *rxd;
+	struct lpe_hwdesc *hwd;
+	struct lpe_hwstatus *hws;
+	struct mbuf *m;
+	bus_dma_segment_t segs[1];
+	int nsegs;
+
+	rxd = &sc->lpe_cdata.lpe_rx_desc[n];
+	hwd = &sc->lpe_rdata.lpe_rx_ring[n];
+	hws = &sc->lpe_rdata.lpe_rx_status[n];
+	m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
+
+	if (!m) {
+		device_printf(sc->lpe_dev, "WARNING: mbufs exhausted!\n");
+		return (ENOBUFS);
+	}
+
+	m->m_len = m->m_pkthdr.len = MCLBYTES;
+
+	bus_dmamap_unload(sc->lpe_cdata.lpe_rx_buf_tag, rxd->lpe_rxdesc_dmamap);
+
+	if (bus_dmamap_load_mbuf_sg(sc->lpe_cdata.lpe_rx_buf_tag, 
+	    rxd->lpe_rxdesc_dmamap, m, segs, &nsegs, 0)) {
+		m_freem(m);
+		return (ENOBUFS);
+	}
+
+	bus_dmamap_sync(sc->lpe_cdata.lpe_rx_buf_tag, rxd->lpe_rxdesc_dmamap, 
+	    BUS_DMASYNC_PREREAD);
+
+	rxd->lpe_rxdesc_mbuf = m;
+	hwd->lhr_data = segs[0].ds_addr + 2;
+	hwd->lhr_control = (segs[0].ds_len - 1) | LPE_HWDESC_INTERRUPT;
+
+	return (0);
+}
+
+static void
+lpe_discard_rxbuf(struct lpe_softc *sc, int n)
+{
+	struct lpe_rxdesc *rxd;
+	struct lpe_hwdesc *hwd;
+
+	rxd = &sc->lpe_cdata.lpe_rx_desc[n];
+	hwd = &sc->lpe_rdata.lpe_rx_ring[n];
+
+	bus_dmamap_unload(sc->lpe_cdata.lpe_rx_buf_tag, rxd->lpe_rxdesc_dmamap);
+
+	hwd->lhr_data = 0;
+	hwd->lhr_control = 0;
+
+	if (rxd->lpe_rxdesc_mbuf) {
+		m_freem(rxd->lpe_rxdesc_mbuf); 
+		rxd->lpe_rxdesc_mbuf = NULL;
+	}
+}
+
+static void
+lpe_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error)
+{
+	struct lpe_dmamap_arg *ctx;
+
+	if (error)
+		return;
+
+	ctx = (struct lpe_dmamap_arg *)arg;
+	ctx->lpe_dma_busaddr = segs[0].ds_addr;
+}
+
+static int
+lpe_ifmedia_upd(struct ifnet *ifp)
+{
+	return (0);
+}
+
+static void
+lpe_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
+{
+	struct lpe_softc *sc = ifp->if_softc;
+	struct mii_data *mii = device_get_softc(sc->lpe_miibus);
+
+	lpe_lock(sc);
+	mii_pollstat(mii);
+	ifmr->ifm_active = mii->mii_media_active;
+	ifmr->ifm_status = mii->mii_media_status;
+	lpe_unlock(sc);
+}
+
+static device_method_t lpe_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		lpe_probe),
+	DEVMETHOD(device_attach,	lpe_attach),
+	DEVMETHOD(device_detach,	lpe_detach),
+
+	/* Bus interface */
+	DEVMETHOD(bus_print_child,	bus_generic_print_child),
+
+	/* MII interface */
+	DEVMETHOD(miibus_readreg,	lpe_miibus_readreg),
+	DEVMETHOD(miibus_writereg,	lpe_miibus_writereg),
+	DEVMETHOD(miibus_statchg,	lpe_miibus_statchg),
+	{ 0, 0 }
+};
+
+static driver_t lpe_driver = {
+	"lpe",
+	lpe_methods,
+	sizeof(struct lpe_softc),
+};
+
+static devclass_t lpe_devclass;
+
+DRIVER_MODULE(lpe, simplebus, lpe_driver, lpe_devclass, 0, 0);
+DRIVER_MODULE(miibus, lpe, miibus_driver, miibus_devclass, 0, 0);
+MODULE_DEPEND(lpe, obio, 1, 1, 1);
+MODULE_DEPEND(lpe, miibus, 1, 1, 1);
+MODULE_DEPEND(lpe, ether, 1, 1, 1);


Property changes on: trunk/sys/arm/lpc/if_lpe.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/lpc/if_lpereg.h
===================================================================
--- trunk/sys/arm/lpc/if_lpereg.h	                        (rev 0)
+++ trunk/sys/arm/lpc/if_lpereg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,209 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2011 Jakub Wojciech Klama <jceel at FreeBSD.org>
+ * 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: stable/10/sys/arm/lpc/if_lpereg.h 261455 2014-02-04 03:36:42Z eadler $
+ */
+
+#ifndef	_ARM_LPC_IF_LPEREG_H
+#define	_ARM_LPC_IF_LPEREG_H
+
+#define	LPE_MAC1		0x000
+#define	LPE_MAC1_RXENABLE	(1 << 0)
+#define	LPE_MAC1_PASSALL	(1 << 1)
+#define	LPE_MAC1_RXFLOWCTRL	(1 << 2)
+#define	LPE_MAC1_TXFLOWCTRL	(1 << 3)
+#define	LPE_MAC1_LOOPBACK	(1 << 4)
+#define	LPE_MAC1_RESETTX	(1 << 8)
+#define	LPE_MAC1_RESETMCSTX	(1 << 9)
+#define	LPE_MAC1_RESETRX	(1 << 10)
+#define	LPE_MAC1_RESETMCSRX	(1 << 11)
+#define	LPE_MAC1_SIMRESET	(1 << 14)
+#define	LPE_MAC1_SOFTRESET	(1 << 15)
+#define	LPE_MAC2		0x004
+#define	LPE_MAC2_FULLDUPLEX	(1 << 0)
+#define	LPE_MAC2_FRAMELENCHECK	(1 << 1)
+#define	LPE_MAC2_HUGEFRAME	(1 << 2)
+#define	LPE_MAC2_DELAYEDCRC	(1 << 3)
+#define	LPE_MAC2_CRCENABLE	(1 << 4)
+#define	LPE_MAC2_PADCRCENABLE	(1 << 5)
+#define	LPE_MAC2_VLANPADENABLE	(1 << 6)
+#define	LPE_MAC2_AUTOPADENABLE	(1 << 7)
+#define	LPE_MAC2_PUREPREAMBLE	(1 << 8)
+#define	LPE_MAC2_LONGPREAMBLE	(1 << 9)
+#define	LPE_MAC2_NOBACKOFF	(1 << 12)
+#define	LPE_MAC2_BACKPRESSURE	(1 << 13)
+#define	LPE_MAC2_EXCESSDEFER	(1 << 14)
+#define	LPE_IPGT		0x008
+#define	LPE_IPGR		0x00c
+#define	LPE_CLRT		0x010
+#define	LPE_MAXF		0x014
+#define	LPE_SUPP		0x018
+#define	LPE_SUPP_SPEED		(1 << 8)
+#define	LPE_TEST		0x01c
+#define	LPE_MCFG		0x020
+#define	LPE_MCFG_SCANINCR	(1 << 0)
+#define	LPE_MCFG_SUPPREAMBLE	(1 << 1)
+#define	LPE_MCFG_CLKSEL(_n)	((_n & 0x7) << 2)
+#define	LPC_MCFG_RESETMII	(1 << 15)
+#define	LPE_MCMD		0x024
+#define	LPE_MCMD_READ		(1 << 0)
+#define	LPE_MCMD_WRITE		(0 << 0)
+#define	LPE_MCMD_SCAN		(1 << 1)
+#define	LPE_MADR		0x028
+#define	LPE_MADR_REGMASK	0x1f
+#define	LPE_MADR_REGSHIFT	0
+#define	LPE_MADR_PHYMASK	0x1f
+#define	LPE_MADR_PHYSHIFT	8
+#define	LPE_MWTD		0x02c
+#define	LPE_MWTD_DATAMASK	0xffff
+#define	LPE_MRDD		0x030
+#define	LPE_MRDD_DATAMASK	0xffff
+#define	LPE_MIND		0x034
+#define	LPE_MIND_BUSY		(1 << 0)
+#define	LPE_MIND_SCANNING	(1 << 1)
+#define	LPE_MIND_INVALID	(1 << 2)
+#define	LPE_MIND_MIIFAIL	(1 << 3)
+#define	LPE_SA0			0x040
+#define	LPE_SA1			0x044
+#define	LPE_SA2			0x048
+#define	LPE_COMMAND		0x100
+#define	LPE_COMMAND_RXENABLE	(1 << 0)
+#define	LPE_COMMAND_TXENABLE	(1 << 1)
+#define	LPE_COMMAND_REGRESET	(1 << 3)
+#define	LPE_COMMAND_TXRESET	(1 << 4)
+#define	LPE_COMMAND_RXRESET	(1 << 5)
+#define	LPE_COMMAND_PASSRUNTFRAME	(1 << 6)
+#define	LPE_COMMAND_PASSRXFILTER	(1 << 7)
+#define	LPE_COMMAND_TXFLOWCTL		(1 << 8)
+#define	LPE_COMMAND_RMII		(1 << 9)
+#define	LPE_COMMAND_FULLDUPLEX		(1 << 10)
+#define	LPE_STATUS		0x104
+#define	LPE_STATUS_RXACTIVE		(1 << 0)
+#define	LPE_STATUS_TXACTIVE		(1 << 1)
+#define	LPE_RXDESC		0x108
+#define	LPE_RXSTATUS		0x10c
+#define	LPE_RXDESC_NUMBER	0x110
+#define	LPE_RXDESC_PROD		0x114
+#define	LPE_RXDESC_CONS		0x118
+#define	LPE_TXDESC		0x11c
+#define	LPE_TXSTATUS		0x120
+#define	LPE_TXDESC_NUMBER	0x124
+#define	LPE_TXDESC_PROD		0x128
+#define	LPE_TXDESC_CONS		0x12c
+#define	LPE_TSV0		0x158
+#define	LPE_TSV1		0x15c
+#define	LPE_RSV			0x160
+#define	LPE_FLOWCONTROL_COUNTER	0x170
+#define	LPE_FLOWCONTROL_STATUS	0x174
+#define	LPE_RXFILTER_CTRL	0x200
+#define	LPE_RXFILTER_UNICAST	(1 << 0)
+#define	LPE_RXFILTER_BROADCAST	(1 << 1)
+#define LPE_RXFILTER_MULTICAST	(1 << 2)
+#define	LPE_RXFILTER_UNIHASH	(1 << 3)
+#define	LPE_RXFILTER_MULTIHASH	(1 << 4)
+#define	LPE_RXFILTER_PERFECT	(1 << 5)
+#define	LPE_RXFILTER_WOL	(1 << 12)
+#define	LPE_RXFILTER_FILTWOL	(1 << 13)
+#define	LPE_RXFILTER_WOL_STATUS	0x204
+#define	LPE_RXFILTER_WOL_CLEAR	0x208
+#define	LPE_HASHFILTER_L	0x210
+#define	LPE_HASHFILTER_H	0x214
+#define	LPE_INTSTATUS		0xfe0
+#define	LPE_INTENABLE		0xfe4
+#define	LPE_INTCLEAR		0xfe8
+#define	LPE_INTSET		0xfec
+#define	LPE_INT_RXOVERRUN	(1 << 0)
+#define	LPE_INT_RXERROR		(1 << 1)
+#define	LPE_INT_RXFINISH	(1 << 2)
+#define	LPE_INT_RXDONE		(1 << 3)
+#define	LPE_INT_TXUNDERRUN	(1 << 4)
+#define	LPE_INT_TXERROR		(1 << 5)
+#define	LPE_INT_TXFINISH	(1 << 6)
+#define	LPE_INT_TXDONE		(1 << 7)
+#define	LPE_INT_SOFTINT		(1 << 12)
+#define	LPE_INTWAKEUPINT	(1 << 13)
+#define	LPE_POWERDOWN		0xff4
+
+#define	LPE_DESC_ALIGN		8
+#define	LPE_TXDESC_NUM		128
+#define	LPE_RXDESC_NUM		128
+#define	LPE_TXDESC_SIZE		(LPE_TXDESC_NUM * sizeof(struct lpe_hwdesc))
+#define	LPE_RXDESC_SIZE		(LPE_RXDESC_NUM * sizeof(struct lpe_hwdesc))
+#define	LPE_TXSTATUS_SIZE	(LPE_TXDESC_NUM * sizeof(struct lpe_hwstatus))
+#define	LPE_RXSTATUS_SIZE	(LPE_RXDESC_NUM * sizeof(struct lpe_hwstatus))
+#define	LPE_MAXFRAGS		8
+
+struct lpe_hwdesc {
+	uint32_t	lhr_data;
+	uint32_t	lhr_control;
+};
+
+struct lpe_hwstatus {
+	uint32_t	lhs_info;
+	uint32_t	lhs_crc;
+};
+
+#define	LPE_INC(x, y)		(x) = ((x) == ((y)-1)) ? 0 : (x)+1
+
+/* These are valid for both Rx and Tx descriptors */
+#define	LPE_HWDESC_SIZE_MASK	(1 << 10)
+#define	LPE_HWDESC_INTERRUPT	(1U << 31)
+
+/* These are valid for Tx descriptors */
+#define	LPE_HWDESC_LAST		(1 << 30)
+#define	LPE_HWDESC_CRC		(1 << 29)
+#define	LPE_HWDESC_PAD		(1 << 28)
+#define	LPE_HWDESC_HUGE		(1 << 27)
+#define	LPE_HWDESC_OVERRIDE	(1 << 26)
+
+/* These are valid for Tx status descriptors */
+#define	LPE_HWDESC_COLLISIONS(_n) (((_n) >> 21) & 0x7)
+#define	LPE_HWDESC_DEFER	(1 << 25)
+#define	LPE_HWDESC_EXCDEFER	(1 << 26)
+#define	LPE_HWDESC_EXCCOLL	(1 << 27)
+#define	LPE_HWDESC_LATECOLL	(1 << 28)
+#define	LPE_HWDESC_UNDERRUN	(1 << 29)
+#define	LPE_HWDESC_TXNODESCR	(1 << 30)
+#define	LPE_HWDESC_ERROR	(1U << 31)
+
+/* These are valid for Rx status descriptors */
+#define	LPE_HWDESC_CONTROL	(1 << 18)
+#define	LPE_HWDESC_VLAN		(1 << 19)
+#define	LPE_HWDESC_FAILFILTER	(1 << 20)
+#define	LPE_HWDESC_MULTICAST	(1 << 21)
+#define	LPE_HWDESC_BROADCAST	(1 << 22)
+#define	LPE_HWDESC_CRCERROR	(1 << 23)
+#define	LPE_HWDESC_SYMBOLERROR	(1 << 24)
+#define	LPE_HWDESC_LENGTHERROR	(1 << 25)
+#define	LPE_HWDESC_RANGEERROR	(1 << 26)
+#define	LPE_HWDESC_ALIGNERROR	(1 << 27)
+#define	LPE_HWDESC_OVERRUN	(1 << 28)
+#define	LPE_HWDESC_RXNODESCR	(1 << 29)
+#define	LPE_HWDESC_LASTFLAG	(1 << 30)
+#define	LPE_HWDESC_ERROR	(1U << 31)
+
+
+#endif	/* _ARM_LPC_IF_LPEREG_H */


Property changes on: trunk/sys/arm/lpc/if_lpereg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/lpc/lpc_dmac.c
===================================================================
--- trunk/sys/arm/lpc/lpc_dmac.c	                        (rev 0)
+++ trunk/sys/arm/lpc/lpc_dmac.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,293 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2011 Jakub Wojciech Klama <jceel at FreeBSD.org>
+ * 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: stable/10/sys/arm/lpc/lpc_dmac.c 266152 2014-05-15 16:11:06Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bio.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/endian.h>
+#include <sys/kernel.h>
+#include <sys/kthread.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/queue.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+#include <sys/time.h>
+#include <sys/timetc.h>
+#include <sys/watchdog.h>
+
+#include <sys/kdb.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <arm/lpc/lpcreg.h>
+#include <arm/lpc/lpcvar.h>
+
+struct lpc_dmac_channel
+{
+	struct lpc_dmac_channel_config *ldc_config;
+	int			ldc_flags;
+};
+
+struct lpc_dmac_softc
+{
+	device_t		ld_dev;
+	struct mtx		ld_mtx;
+	struct resource *	ld_mem_res;
+	struct resource *	ld_irq_res;
+	bus_space_tag_t		ld_bst;
+	bus_space_handle_t	ld_bsh;
+	void *			ld_intrhand;
+	struct lpc_dmac_channel	ld_channels[8];
+};
+
+static struct lpc_dmac_softc *lpc_dmac_sc = NULL;
+
+static int lpc_dmac_probe(device_t);
+static int lpc_dmac_attach(device_t);
+static void lpc_dmac_intr(void *);
+
+#define	lpc_dmac_read_4(_sc, _reg) \
+    bus_space_read_4(_sc->ld_bst, _sc->ld_bsh, _reg)
+#define	lpc_dmac_write_4(_sc, _reg, _value) \
+    bus_space_write_4(_sc->ld_bst, _sc->ld_bsh, _reg, _value)
+#define	lpc_dmac_read_ch_4(_sc, _n, _reg) \
+    bus_space_read_4(_sc->ld_bst, _sc->ld_bsh, (_reg + LPC_DMAC_CHADDR(_n)))
+#define	lpc_dmac_write_ch_4(_sc, _n, _reg, _value) \
+    bus_space_write_4(_sc->ld_bst, _sc->ld_bsh, (_reg + LPC_DMAC_CHADDR(_n)), _value)
+
+static int lpc_dmac_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "lpc,dmac"))
+		return (ENXIO);
+
+	device_set_desc(dev, "LPC32x0 General Purpose DMA controller");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int lpc_dmac_attach(device_t dev)
+{
+	struct lpc_dmac_softc *sc = device_get_softc(dev);
+	int rid;
+
+	rid = 0;
+	sc->ld_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	    RF_ACTIVE);
+	if (!sc->ld_mem_res) {
+		device_printf(dev, "cannot allocate memory window\n");
+		return (ENXIO);
+	}
+
+	sc->ld_bst = rman_get_bustag(sc->ld_mem_res);
+	sc->ld_bsh = rman_get_bushandle(sc->ld_mem_res);
+
+	rid = 0;
+	sc->ld_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+	    RF_ACTIVE);
+	if (!sc->ld_irq_res) {
+		device_printf(dev, "cannot allocate cmd interrupt\n");
+		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->ld_mem_res);
+		return (ENXIO);
+	}
+
+	if (bus_setup_intr(dev, sc->ld_irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
+	    NULL, lpc_dmac_intr, sc, &sc->ld_intrhand))
+	{
+		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->ld_mem_res);
+		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->ld_irq_res);
+		device_printf(dev, "cannot setup interrupt handler\n");
+		return (ENXIO);
+	}
+
+	lpc_dmac_sc = sc;
+
+	lpc_pwr_write(dev, LPC_CLKPWR_DMACLK_CTRL, LPC_CLKPWR_DMACLK_CTRL_EN);
+	lpc_dmac_write_4(sc, LPC_DMAC_CONFIG, LPC_DMAC_CONFIG_ENABLE);
+
+	lpc_dmac_write_4(sc, LPC_DMAC_INTTCCLEAR, 0xff);
+	lpc_dmac_write_4(sc, LPC_DMAC_INTERRCLEAR, 0xff);
+
+	return (0);
+}
+
+static void lpc_dmac_intr(void *arg)
+{
+	struct lpc_dmac_softc *sc = (struct lpc_dmac_softc *)arg;
+	struct lpc_dmac_channel *ch;
+	uint32_t intstat, tcstat, errstat;
+	int i;
+
+	do {
+		intstat = lpc_dmac_read_4(sc, LPC_DMAC_INTSTAT);
+
+		for (i = 0; i < LPC_DMAC_CHNUM; i++) {
+			if ((intstat & (1 << i)) == 0)
+				continue;
+	
+			ch = &sc->ld_channels[i];
+			tcstat = lpc_dmac_read_4(sc, LPC_DMAC_INTTCSTAT);
+			errstat = lpc_dmac_read_4(sc, LPC_DMAC_INTERRSTAT);
+
+			if (tcstat & (1 << i)) {
+				ch->ldc_config->ldc_success_handler(
+				    ch->ldc_config->ldc_handler_arg);
+				lpc_dmac_write_4(sc, LPC_DMAC_INTTCCLEAR, (1 << i));
+			}
+
+			if (errstat & (1 << i)) {
+				ch->ldc_config->ldc_error_handler(
+				    ch->ldc_config->ldc_handler_arg);
+				lpc_dmac_write_4(sc, LPC_DMAC_INTERRCLEAR, (1 << i));
+			}
+		}
+
+	} while (intstat);
+}
+
+int
+lpc_dmac_config_channel(device_t dev, int chno, struct lpc_dmac_channel_config *cfg)
+{
+	struct lpc_dmac_softc *sc = lpc_dmac_sc;
+	struct lpc_dmac_channel *ch;
+
+	if (sc == NULL)
+		return (ENXIO);
+
+	ch = &sc->ld_channels[chno];
+	ch->ldc_config = cfg;
+
+	return 0;
+}
+
+int
+lpc_dmac_setup_transfer(device_t dev, int chno, bus_addr_t src, bus_addr_t dst,
+    bus_size_t size, int flags)
+{
+	struct lpc_dmac_softc *sc = lpc_dmac_sc;
+	struct lpc_dmac_channel *ch;
+	uint32_t ctrl, cfg;
+
+	if (sc == NULL)
+		return (ENXIO);
+
+	ch = &sc->ld_channels[chno];
+
+	ctrl = LPC_DMAC_CH_CONTROL_I |
+	    (ch->ldc_config->ldc_dst_incr ? LPC_DMAC_CH_CONTROL_DI : 0) | 
+	    (ch->ldc_config->ldc_src_incr ? LPC_DMAC_CH_CONTROL_SI : 0) |
+	    LPC_DMAC_CH_CONTROL_DWIDTH(ch->ldc_config->ldc_dst_width) |
+	    LPC_DMAC_CH_CONTROL_SWIDTH(ch->ldc_config->ldc_src_width) |
+	    LPC_DMAC_CH_CONTROL_DBSIZE(ch->ldc_config->ldc_dst_burst) |
+	    LPC_DMAC_CH_CONTROL_SBSIZE(ch->ldc_config->ldc_src_burst) |
+	    size;
+
+	cfg = LPC_DMAC_CH_CONFIG_ITC | LPC_DMAC_CH_CONFIG_IE |
+	    LPC_DMAC_CH_CONFIG_FLOWCNTL(ch->ldc_config->ldc_fcntl) |
+	    LPC_DMAC_CH_CONFIG_DESTP(ch->ldc_config->ldc_dst_periph) |
+	    LPC_DMAC_CH_CONFIG_SRCP(ch->ldc_config->ldc_src_periph) | LPC_DMAC_CH_CONFIG_E;
+	lpc_dmac_write_ch_4(sc, chno, LPC_DMAC_CH_SRCADDR, src);
+	lpc_dmac_write_ch_4(sc, chno, LPC_DMAC_CH_DSTADDR, dst);
+	lpc_dmac_write_ch_4(sc, chno, LPC_DMAC_CH_LLI, 0);
+	lpc_dmac_write_ch_4(sc, chno, LPC_DMAC_CH_CONTROL, ctrl);
+	lpc_dmac_write_ch_4(sc, chno, LPC_DMAC_CH_CONFIG, cfg);
+
+	return 0;
+}
+
+int
+lpc_dmac_enable_channel(device_t dev, int chno)
+{
+	struct lpc_dmac_softc *sc = lpc_dmac_sc;
+	uint32_t cfg;
+
+	if (sc == NULL)
+		return (ENXIO);
+
+	cfg = lpc_dmac_read_ch_4(sc, chno, LPC_DMAC_CH_CONFIG);
+	cfg |= LPC_DMAC_CH_CONFIG_E;
+
+	lpc_dmac_write_ch_4(sc, chno, LPC_DMAC_CH_CONFIG, cfg);
+
+	return 0;
+}
+
+int
+lpc_dmac_disable_channel(device_t dev, int chno)
+{
+	struct lpc_dmac_softc *sc = lpc_dmac_sc;
+	uint32_t cfg;
+
+	if (sc == NULL)
+		return (ENXIO);
+
+	cfg = lpc_dmac_read_ch_4(sc, chno, LPC_DMAC_CH_CONFIG);
+	cfg &= ~LPC_DMAC_CH_CONFIG_E;
+
+	lpc_dmac_write_ch_4(sc, chno, LPC_DMAC_CH_CONFIG, cfg);
+
+	return 0;
+}
+
+int
+lpc_dmac_start_burst(device_t dev, int id)
+{
+	struct lpc_dmac_softc *sc = lpc_dmac_sc;
+
+	lpc_dmac_write_4(sc, LPC_DMAC_SOFTBREQ, (1 << id));
+	return (0);
+}
+
+static device_method_t lpc_dmac_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		lpc_dmac_probe),
+	DEVMETHOD(device_attach,	lpc_dmac_attach),
+
+	{ 0, 0 },
+};
+
+static devclass_t lpc_dmac_devclass;
+
+static driver_t lpc_dmac_driver = {
+	"dmac",
+	lpc_dmac_methods,
+	sizeof(struct lpc_dmac_softc),
+};
+
+DRIVER_MODULE(dmac, simplebus, lpc_dmac_driver, lpc_dmac_devclass, 0, 0);


Property changes on: trunk/sys/arm/lpc/lpc_dmac.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/lpc/lpc_fb.c
===================================================================
--- trunk/sys/arm/lpc/lpc_fb.c	                        (rev 0)
+++ trunk/sys/arm/lpc/lpc_fb.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,470 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2011 Jakub Wojciech Klama <jceel at FreeBSD.org>
+ * 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: stable/10/sys/arm/lpc/lpc_fb.c 266152 2014-05-15 16:11:06Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bio.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/endian.h>
+#include <sys/kernel.h>
+#include <sys/kthread.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/queue.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+#include <sys/time.h>
+#include <sys/timetc.h>
+#include <sys/watchdog.h>
+
+#include <sys/kdb.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+#include <machine/resource.h>
+#include <machine/intr.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <arm/lpc/lpcreg.h>
+#include <arm/lpc/lpcvar.h>
+
+
+struct lpc_fb_dmamap_arg {
+	bus_addr_t		lf_dma_busaddr;
+};
+
+struct lpc_lcd_config {
+	int			lc_xres;
+	int			lc_yres;
+	int			lc_bpp;
+	uint32_t		lc_pixelclock;
+	int			lc_left_margin;
+	int			lc_right_margin;
+	int			lc_upper_margin;
+	int			lc_lower_margin;
+	int			lc_hsync_len;
+	int			lc_vsync_len;
+};
+
+struct lpc_fb_softc {
+	device_t		lf_dev;
+	struct cdev *		lf_cdev;
+	struct mtx		lf_mtx;
+	struct resource *	lf_mem_res;
+	struct resource *	lf_irq_res;
+	bus_space_tag_t		lf_bst;
+	bus_space_handle_t	lf_bsh;
+	void *			lf_intrhand;
+	bus_dma_tag_t		lf_dma_tag;
+	bus_dmamap_t		lf_dma_map;
+	void *			lf_buffer;
+	bus_addr_t		lf_buffer_phys;
+	bus_size_t		lf_buffer_size;
+	struct lpc_lcd_config	lf_lcd_config;
+	int			lf_initialized;
+	int			lf_opened;
+};
+
+extern void ssd1289_configure(void);
+
+#define	lpc_fb_lock(_sc)	mtx_lock(&(_sc)->lf_mtx)
+#define	lpc_fb_unlock(_sc)	mtx_unlock(&(_sc)->lf_mtx)
+#define	lpc_fb_lock_assert(sc)	mtx_assert(&(_sc)->lf_mtx, MA_OWNED)
+
+#define	lpc_fb_read_4(_sc, _reg)		\
+    bus_space_read_4((_sc)->lf_bst, (_sc)->lf_bsh, (_reg))
+#define	lpc_fb_write_4(_sc, _reg, _val)		\
+    bus_space_write_4((_sc)->lf_bst, (_sc)->lf_bsh, (_reg), (_val))
+
+
+
+static int lpc_fb_probe(device_t);
+static int lpc_fb_attach(device_t);
+static void lpc_fb_intr(void *);
+static void lpc_fb_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int err);
+
+static int lpc_fb_fdt_read(phandle_t, const char *, uint32_t *);
+static int lpc_fb_read_lcd_config(phandle_t, struct lpc_lcd_config *);
+
+static int lpc_fb_open(struct cdev *, int, int, struct thread *);
+static int lpc_fb_close(struct cdev *, int, int, struct thread *);
+static int lpc_fb_ioctl(struct cdev *, u_long, caddr_t, int, struct thread *);
+static int lpc_fb_mmap(struct cdev *, vm_ooffset_t, vm_paddr_t *, int, vm_memattr_t *);
+
+static void lpc_fb_blank(struct lpc_fb_softc *);
+
+static struct cdevsw lpc_fb_cdevsw = {
+	.d_open		= lpc_fb_open,
+	.d_close	= lpc_fb_close,
+	.d_ioctl	= lpc_fb_ioctl,
+	.d_mmap		= lpc_fb_mmap,
+	.d_name		= "lpcfb",
+	.d_version	= D_VERSION,
+};
+
+static int
+lpc_fb_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "lpc,fb"))
+		return (ENXIO);
+
+	device_set_desc(dev, "LPC32x0 framebuffer device");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+lpc_fb_attach(device_t dev)
+{
+	struct lpc_fb_softc *sc = device_get_softc(dev);
+	struct lpc_fb_dmamap_arg ctx;
+	phandle_t node;
+	int mode, rid, err = 0;
+
+	sc->lf_dev = dev;
+	mtx_init(&sc->lf_mtx, "lpcfb", "fb", MTX_DEF);
+
+	rid = 0;
+	sc->lf_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	    RF_ACTIVE);
+	if (!sc->lf_mem_res) {
+		device_printf(dev, "cannot allocate memory window\n");
+		return (ENXIO);
+	}
+
+	sc->lf_bst = rman_get_bustag(sc->lf_mem_res);
+	sc->lf_bsh = rman_get_bushandle(sc->lf_mem_res);
+
+	rid = 0;
+	sc->lf_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+	    RF_ACTIVE);
+	if (!sc->lf_irq_res) {
+		device_printf(dev, "cannot allocate interrupt\n");
+		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->lf_mem_res);
+		return (ENXIO);
+	}
+
+	if (bus_setup_intr(dev, sc->lf_irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
+	    NULL, lpc_fb_intr, sc, &sc->lf_intrhand))
+	{
+		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->lf_mem_res);
+		bus_release_resource(dev, SYS_RES_IRQ, 1, sc->lf_irq_res);
+		device_printf(dev, "cannot setup interrupt handler\n");
+		return (ENXIO);
+	}
+
+	node = ofw_bus_get_node(dev);
+
+	err = lpc_fb_read_lcd_config(node, &sc->lf_lcd_config);
+	if (err) {
+		device_printf(dev, "cannot read LCD configuration\n");
+		goto fail;
+	}
+
+	sc->lf_buffer_size = sc->lf_lcd_config.lc_xres * 
+	    sc->lf_lcd_config.lc_yres *
+	    (sc->lf_lcd_config.lc_bpp == 24 ? 3 : 2);
+
+	device_printf(dev, "%dx%d LCD, %d bits per pixel, %dkHz pixel clock\n",
+	    sc->lf_lcd_config.lc_xres, sc->lf_lcd_config.lc_yres,
+	    sc->lf_lcd_config.lc_bpp, sc->lf_lcd_config.lc_pixelclock / 1000);
+
+	err = bus_dma_tag_create(
+	    bus_get_dma_tag(sc->lf_dev),
+	    4, 0,			/* alignment, boundary */
+	    BUS_SPACE_MAXADDR_32BIT,	/* lowaddr */
+	    BUS_SPACE_MAXADDR,		/* highaddr */
+	    NULL, NULL,			/* filter, filterarg */
+	    sc->lf_buffer_size, 1,	/* maxsize, nsegments */
+	    sc->lf_buffer_size, 0,	/* maxsegsize, flags */
+	    NULL, NULL,			/* lockfunc, lockarg */
+	    &sc->lf_dma_tag);
+
+	err = bus_dmamem_alloc(sc->lf_dma_tag, (void **)&sc->lf_buffer,
+	    0, &sc->lf_dma_map);
+	if (err) {
+		device_printf(dev, "cannot allocate framebuffer\n");
+		goto fail;
+	}
+
+	err = bus_dmamap_load(sc->lf_dma_tag, sc->lf_dma_map, sc->lf_buffer,
+	    sc->lf_buffer_size, lpc_fb_dmamap_cb, &ctx, BUS_DMA_NOWAIT);
+	if (err) {
+		device_printf(dev, "cannot load DMA map\n");
+		goto fail;
+	}
+
+	switch (sc->lf_lcd_config.lc_bpp) {
+	case 12:
+		mode = LPC_CLKPWR_LCDCLK_CTRL_MODE_12;
+		break;
+	case 15:
+		mode = LPC_CLKPWR_LCDCLK_CTRL_MODE_15;
+		break;
+	case 16:
+		mode = LPC_CLKPWR_LCDCLK_CTRL_MODE_16;
+		break;
+	case 24:
+		mode = LPC_CLKPWR_LCDCLK_CTRL_MODE_24;
+		break;
+	default:
+		panic("unsupported bpp");
+	}
+
+	lpc_pwr_write(sc->lf_dev, LPC_CLKPWR_LCDCLK_CTRL,
+	    LPC_CLKPWR_LCDCLK_CTRL_MODE(mode) |
+	    LPC_CLKPWR_LCDCLK_CTRL_HCLKEN);
+
+	sc->lf_buffer_phys = ctx.lf_dma_busaddr;
+	sc->lf_cdev = make_dev(&lpc_fb_cdevsw, 0, UID_ROOT, GID_WHEEL,
+	    0600, "lpcfb");
+
+	sc->lf_cdev->si_drv1 = sc;
+
+	return (0);
+fail:
+	return (ENXIO);
+}
+
+static void
+lpc_fb_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int err)
+{
+	struct lpc_fb_dmamap_arg *ctx;
+
+	if (err)
+		return;
+
+	ctx = (struct lpc_fb_dmamap_arg *)arg;
+	ctx->lf_dma_busaddr = segs[0].ds_addr;
+}
+
+static void
+lpc_fb_intr(void *arg)
+{
+}
+
+static int
+lpc_fb_fdt_read(phandle_t node, const char *name, uint32_t *ret)
+{
+	if (OF_getprop(node, name, ret, sizeof(uint32_t)) <= 0)
+		return (ENOENT);
+
+	*ret = fdt32_to_cpu(*ret);
+	return (0);
+}
+
+static int
+lpc_fb_read_lcd_config(phandle_t node, struct lpc_lcd_config *cfg)
+{
+	if (lpc_fb_fdt_read(node, "horizontal-resolution", &cfg->lc_xres))
+		return (ENXIO);
+
+	if (lpc_fb_fdt_read(node, "vertical-resolution", &cfg->lc_yres))
+		return (ENXIO);
+
+	if (lpc_fb_fdt_read(node, "bits-per-pixel", &cfg->lc_bpp))
+		return (ENXIO);
+
+	if (lpc_fb_fdt_read(node, "pixel-clock", &cfg->lc_pixelclock))
+		return (ENXIO);
+
+	if (lpc_fb_fdt_read(node, "left-margin", &cfg->lc_left_margin))
+		return (ENXIO);
+
+	if (lpc_fb_fdt_read(node, "right-margin", &cfg->lc_right_margin))
+		return (ENXIO);
+
+	if (lpc_fb_fdt_read(node, "upper-margin", &cfg->lc_upper_margin))
+		return (ENXIO);
+
+	if (lpc_fb_fdt_read(node, "lower-margin", &cfg->lc_lower_margin))
+		return (ENXIO);
+
+	if (lpc_fb_fdt_read(node, "hsync-len", &cfg->lc_hsync_len))
+		return (ENXIO);
+
+	if (lpc_fb_fdt_read(node, "vsync-len", &cfg->lc_vsync_len))
+		return (ENXIO);
+
+	return (0);
+}
+
+static void
+lpc_fb_setup(struct lpc_fb_softc *sc)
+{
+	struct lpc_lcd_config *cfg = &sc->lf_lcd_config;
+	uint32_t bpp;
+
+	lpc_fb_write_4(sc, LPC_LCD_TIMH,
+	    LPC_LCD_TIMH_PPL(cfg->lc_xres) |
+	    LPC_LCD_TIMH_HSW(cfg->lc_hsync_len - 1) |
+	    LPC_LCD_TIMH_HFP(cfg->lc_right_margin - 1) |
+	    LPC_LCD_TIMH_HBP(cfg->lc_left_margin - 1));
+
+	lpc_fb_write_4(sc, LPC_LCD_TIMV,
+	    LPC_LCD_TIMV_LPP(cfg->lc_yres - 1) |
+	    LPC_LCD_TIMV_VSW(cfg->lc_vsync_len - 1) |
+	    LPC_LCD_TIMV_VFP(cfg->lc_lower_margin) |
+	    LPC_LCD_TIMV_VBP(cfg->lc_upper_margin));
+
+	/* XXX LPC_LCD_POL_PCD_LO */
+	lpc_fb_write_4(sc, LPC_LCD_POL,
+	    LPC_LCD_POL_IHS | LPC_LCD_POL_IVS |
+	    LPC_LCD_POL_CPL(cfg->lc_xres - 1) |
+	    LPC_LCD_POL_PCD_LO(4));
+	
+	lpc_fb_write_4(sc, LPC_LCD_UPBASE, sc->lf_buffer_phys);
+	
+	switch (cfg->lc_bpp) {
+	case 1:
+		bpp = LPC_LCD_CTRL_BPP1;
+		break;
+	case 2:
+		bpp = LPC_LCD_CTRL_BPP2;
+		break;
+	case 4:
+		bpp = LPC_LCD_CTRL_BPP4;
+		break;
+	case 8:
+		bpp = LPC_LCD_CTRL_BPP8;
+		break;
+	case 12:
+		bpp = LPC_LCD_CTRL_BPP12_444;
+		break;
+	case 15:
+		bpp = LPC_LCD_CTRL_BPP16;
+		break;
+	case 16:
+		bpp = LPC_LCD_CTRL_BPP16_565;
+		break;
+	case 24:
+		bpp = LPC_LCD_CTRL_BPP24;
+		break;
+	default:
+		panic("LCD unknown bpp: %d", cfg->lc_bpp);
+	}
+
+	lpc_fb_write_4(sc, LPC_LCD_CTRL,
+	    LPC_LCD_CTRL_LCDVCOMP(1) |
+	    LPC_LCD_CTRL_LCDPWR |
+	    LPC_LCD_CTRL_BGR |
+	    LPC_LCD_CTRL_LCDTFT |
+	    LPC_LCD_CTRL_LCDBPP(bpp) |
+	    LPC_LCD_CTRL_LCDEN);
+}
+
+
+static int
+lpc_fb_open(struct cdev *cdev, int oflags, int devtype, struct thread *td)
+{
+	struct lpc_fb_softc *sc = cdev->si_drv1;
+
+	lpc_fb_lock(sc);
+
+	if (sc->lf_opened)
+		return (EBUSY);
+
+	sc->lf_opened = 1;
+
+	lpc_fb_unlock(sc);
+
+	if (!sc->lf_initialized) {
+		ssd1289_configure();
+		lpc_fb_setup(sc);
+		lpc_fb_blank(sc);
+		sc->lf_initialized = 1;
+	}
+
+	return (0);
+}
+
+static int
+lpc_fb_close(struct cdev *cdev, int fflag, int devtype, struct thread *td)
+{	
+	struct lpc_fb_softc *sc = cdev->si_drv1;
+
+	lpc_fb_lock(sc);
+	sc->lf_opened = 0;
+	lpc_fb_unlock(sc);
+
+	return (0);
+}
+
+static int
+lpc_fb_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int x,
+    struct thread *td)
+{
+	
+	return (EINVAL);
+}
+
+static int
+lpc_fb_mmap(struct cdev *cdev, vm_ooffset_t offset, vm_paddr_t *paddr,
+    int nprot, vm_memattr_t *memattr)
+{
+	struct lpc_fb_softc *sc = cdev->si_drv1;
+
+	*paddr = (vm_paddr_t)(sc->lf_buffer_phys + offset);
+	return (0);
+}
+
+static void
+lpc_fb_blank(struct lpc_fb_softc *sc)
+{
+	memset(sc->lf_buffer, 0xffff, sc->lf_buffer_size);
+}
+
+static device_method_t lpc_fb_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		lpc_fb_probe),
+	DEVMETHOD(device_attach,	lpc_fb_attach),
+
+	{ 0, 0 }
+};
+
+static devclass_t lpc_fb_devclass;
+
+static driver_t lpc_fb_driver = {
+	"lpcfb",
+	lpc_fb_methods,
+	sizeof(struct lpc_fb_softc),
+};
+
+DRIVER_MODULE(lpcfb, simplebus, lpc_fb_driver, lpc_fb_devclass, 0, 0);


Property changes on: trunk/sys/arm/lpc/lpc_fb.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/lpc/lpc_gpio.c
===================================================================
--- trunk/sys/arm/lpc/lpc_gpio.c	                        (rev 0)
+++ trunk/sys/arm/lpc/lpc_gpio.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,557 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2011 Jakub Wojciech Klama <jceel at FreeBSD.org>
+ * 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.
+ *
+ */
+
+/*
+ * GPIO on LPC32x0 consist of 4 ports:
+ * - Port0 with 8 input/output pins
+ * - Port1 with 24 input/output pins
+ * - Port2 with 13 input/output pins
+ * - Port3 with:
+ *   - 26 input pins (GPI_00..GPI_09 + GPI_15..GPI_23 + GPI_25 + GPI_27..GPI_28)
+ *   - 24 output pins (GPO_00..GPO_23)
+ *   - 6 input/output pins (GPIO_00..GPIO_05)
+ *
+ * Pins are mapped to logical pin number as follows:
+ * [0..9] -> GPI_00..GPI_09 		(port 3)
+ * [10..18] -> GPI_15..GPI_23 		(port 3)
+ * [19] -> GPI_25			(port 3)
+ * [20..21] -> GPI_27..GPI_28		(port 3)
+ * [22..45] -> GPO_00..GPO_23		(port 3)
+ * [46..51] -> GPIO_00..GPIO_05		(port 3)
+ * [52..64] -> P2.0..P2.12		(port 2)
+ * [65..88] -> P1.0..P1.23		(port 1)
+ * [89..96] -> P0.0..P0.7		(port 0)
+ *
+ */
+
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/lpc/lpc_gpio.c 278782 2015-02-14 20:37:33Z loos $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bio.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/endian.h>
+#include <sys/kernel.h>
+#include <sys/kthread.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/queue.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+#include <sys/time.h>
+#include <sys/timetc.h>
+#include <sys/watchdog.h>
+#include <sys/gpio.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+#include <machine/resource.h>
+#include <machine/intr.h>
+#include <machine/fdt.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <arm/lpc/lpcreg.h>
+#include <arm/lpc/lpcvar.h>
+
+#include "gpio_if.h"
+
+struct lpc_gpio_softc
+{
+	device_t		lg_dev;
+	struct resource *	lg_res;
+	bus_space_tag_t		lg_bst;
+	bus_space_handle_t	lg_bsh;
+};
+
+struct lpc_gpio_pinmap
+{
+	int			lp_start_idx;
+	int			lp_pin_count;
+	int			lp_port;
+	int			lp_start_bit;
+	int			lp_flags;
+};
+
+static const struct lpc_gpio_pinmap lpc_gpio_pins[] = {
+	{ 0,	10,	3,	0,	GPIO_PIN_INPUT },
+	{ 10,	9,	3,	15,	GPIO_PIN_INPUT },
+	{ 19,	1,	3,	25,	GPIO_PIN_INPUT },
+	{ 20,	2,	3,	27,	GPIO_PIN_INPUT },
+	{ 22,	24,	3,	0,	GPIO_PIN_OUTPUT },
+	/*
+	 * -1 below is to mark special case for Port3 GPIO pins, as they
+	 * have other bits in Port 3 registers as inputs and as outputs
+	 */
+	{ 46,	6,	3,	-1,	GPIO_PIN_INPUT | GPIO_PIN_OUTPUT },
+	{ 52,	13,	2,	0,	GPIO_PIN_INPUT | GPIO_PIN_OUTPUT },
+	{ 65,	24,	1,	0,	GPIO_PIN_INPUT | GPIO_PIN_OUTPUT },
+	{ 89,	8,	0,	0,	GPIO_PIN_INPUT | GPIO_PIN_OUTPUT },
+	{ -1,	-1,	-1,	-1,	-1 },
+};
+
+#define	LPC_GPIO_NPINS				\
+    (LPC_GPIO_P0_COUNT + LPC_GPIO_P1_COUNT +	\
+    LPC_GPIO_P2_COUNT + LPC_GPIO_P3_COUNT)
+
+#define	LPC_GPIO_PIN_IDX(_map, _idx)	\
+    (_idx - _map->lp_start_idx)
+
+#define	LPC_GPIO_PIN_BIT(_map, _idx)	\
+    (_map->lp_start_bit + LPC_GPIO_PIN_IDX(_map, _idx))
+
+static int lpc_gpio_probe(device_t);
+static int lpc_gpio_attach(device_t);
+static int lpc_gpio_detach(device_t);
+
+static int lpc_gpio_pin_max(device_t, int *);
+static int lpc_gpio_pin_getcaps(device_t, uint32_t, uint32_t *);
+static int lpc_gpio_pin_getflags(device_t, uint32_t, uint32_t *);
+static int lpc_gpio_pin_setflags(device_t, uint32_t, uint32_t);
+static int lpc_gpio_pin_getname(device_t, uint32_t, char *);
+static int lpc_gpio_pin_get(device_t, uint32_t, uint32_t *);
+static int lpc_gpio_pin_set(device_t, uint32_t, uint32_t);
+static int lpc_gpio_pin_toggle(device_t, uint32_t);
+
+static const struct lpc_gpio_pinmap *lpc_gpio_get_pinmap(int);
+
+static struct lpc_gpio_softc *lpc_gpio_sc = NULL;
+
+#define	lpc_gpio_read_4(_sc, _reg) \
+    bus_space_read_4(_sc->lg_bst, _sc->lg_bsh, _reg)
+#define	lpc_gpio_write_4(_sc, _reg, _val) \
+    bus_space_write_4(_sc->lg_bst, _sc->lg_bsh, _reg, _val)
+#define	lpc_gpio_get_4(_sc, _test, _reg1, _reg2) \
+    lpc_gpio_read_4(_sc, ((_test) ? _reg1 : _reg2))
+#define	lpc_gpio_set_4(_sc, _test, _reg1, _reg2, _val) \
+    lpc_gpio_write_4(_sc, ((_test) ? _reg1 : _reg2), _val)
+
+static int
+lpc_gpio_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "lpc,gpio"))
+		return (ENXIO);
+
+	device_set_desc(dev, "LPC32x0 GPIO");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+lpc_gpio_attach(device_t dev)
+{
+	struct lpc_gpio_softc *sc = device_get_softc(dev);
+	int rid;
+
+	sc->lg_dev = dev;
+
+	rid = 0;
+	sc->lg_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	    RF_ACTIVE);
+	if (!sc->lg_res) {
+		device_printf(dev, "cannot allocate memory window\n");
+		return (ENXIO);
+	}
+
+	sc->lg_bst = rman_get_bustag(sc->lg_res);
+	sc->lg_bsh = rman_get_bushandle(sc->lg_res);
+
+	lpc_gpio_sc = sc;
+
+	device_add_child(dev, "gpioc", -1);
+	device_add_child(dev, "gpiobus", -1);
+
+	return (bus_generic_attach(dev));
+}
+
+static int
+lpc_gpio_detach(device_t dev)
+{
+	return (EBUSY);
+}
+
+static int
+lpc_gpio_pin_max(device_t dev, int *npins)
+{
+	*npins = LPC_GPIO_NPINS - 1;
+	return (0);
+}
+
+static int
+lpc_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
+{
+	const struct lpc_gpio_pinmap *map;
+
+	if (pin > LPC_GPIO_NPINS)
+		return (ENODEV);
+
+	map = lpc_gpio_get_pinmap(pin);
+
+	*caps = map->lp_flags;
+	return (0);
+}
+
+static int
+lpc_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
+{
+	struct lpc_gpio_softc *sc = device_get_softc(dev);
+	const struct lpc_gpio_pinmap *map;
+	uint32_t state;
+	int dir;
+
+	if (pin > LPC_GPIO_NPINS)
+		return (ENODEV);
+
+	map = lpc_gpio_get_pinmap(pin);
+
+	/* Check whether it's bidirectional pin */
+	if ((map->lp_flags & (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) != 
+	    (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) {
+		*flags = map->lp_flags;
+		return (0);
+	}
+
+	switch (map->lp_port) {
+	case 0:
+		state = lpc_gpio_read_4(sc, LPC_GPIO_P0_DIR_STATE);
+		dir = (state & (1 << LPC_GPIO_PIN_BIT(map, pin)));
+		break;
+	case 1:
+		state = lpc_gpio_read_4(sc, LPC_GPIO_P1_DIR_STATE);
+		dir = (state & (1 << LPC_GPIO_PIN_BIT(map, pin)));
+		break;
+	case 2:
+		state = lpc_gpio_read_4(sc, LPC_GPIO_P2_DIR_STATE);
+		dir = (state & (1 << LPC_GPIO_PIN_BIT(map, pin)));
+		break;
+	case 3:
+		state = lpc_gpio_read_4(sc, LPC_GPIO_P2_DIR_STATE);
+		dir = (state & (1 << (25 + LPC_GPIO_PIN_IDX(map, pin))));
+		break;
+	default:
+		panic("unknown GPIO port");
+	}
+
+	*flags = dir ? GPIO_PIN_OUTPUT : GPIO_PIN_INPUT;
+
+	return (0);
+}
+
+static int
+lpc_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
+{
+	struct lpc_gpio_softc *sc = device_get_softc(dev);
+	const struct lpc_gpio_pinmap *map;
+	uint32_t dir, state;
+
+	if (pin > LPC_GPIO_NPINS)
+		return (ENODEV);
+
+	map = lpc_gpio_get_pinmap(pin);
+
+	/* Check whether it's bidirectional pin */
+	if ((map->lp_flags & (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) != 
+	    (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT))
+		return (ENOTSUP);
+	
+	if (flags & GPIO_PIN_INPUT)
+		dir = 0;
+
+	if (flags & GPIO_PIN_OUTPUT)
+		dir = 1;
+
+	switch (map->lp_port) {
+	case 0:
+		state = (1 << LPC_GPIO_PIN_IDX(map, pin));
+		lpc_gpio_set_4(sc, dir, LPC_GPIO_P0_DIR_SET, 
+		    LPC_GPIO_P0_DIR_CLR, state);
+		break;
+	case 1:
+		state = (1 << LPC_GPIO_PIN_IDX(map, pin));
+		lpc_gpio_set_4(sc, dir, LPC_GPIO_P1_DIR_SET, 
+		    LPC_GPIO_P0_DIR_CLR, state);
+		break;
+	case 2:
+		state = (1 << LPC_GPIO_PIN_IDX(map, pin));
+		lpc_gpio_set_4(sc, dir, LPC_GPIO_P2_DIR_SET, 
+		    LPC_GPIO_P0_DIR_CLR, state);
+		break;
+	case 3:
+		state = (1 << (25 + (pin - map->lp_start_idx)));
+		lpc_gpio_set_4(sc, dir, LPC_GPIO_P2_DIR_SET, 
+		    LPC_GPIO_P0_DIR_CLR, state);
+		break;
+	}
+
+	return (0);
+}
+
+static int
+lpc_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
+{
+	const struct lpc_gpio_pinmap *map;
+	int idx;
+
+	map = lpc_gpio_get_pinmap(pin);
+	idx = LPC_GPIO_PIN_IDX(map, pin);
+
+	switch (map->lp_port) {
+	case 0:
+	case 1:
+	case 2:
+		snprintf(name, GPIOMAXNAME - 1, "P%d.%d", map->lp_port, 
+		    map->lp_start_bit + LPC_GPIO_PIN_IDX(map, pin));
+		break;
+	case 3:
+		if (map->lp_start_bit == -1) {
+			snprintf(name, GPIOMAXNAME - 1, "GPIO_%02d", idx);
+			break;
+		}
+
+		snprintf(name, GPIOMAXNAME - 1, "GP%c_%02d",
+		    (map->lp_flags & GPIO_PIN_INPUT) ? 'I' : 'O',
+		    map->lp_start_bit + idx);
+		break;
+	}
+
+	return (0);
+}
+
+static int
+lpc_gpio_pin_get(device_t dev, uint32_t pin, uint32_t *value)
+{
+	struct lpc_gpio_softc *sc = device_get_softc(dev);
+	const struct lpc_gpio_pinmap *map;
+	uint32_t state, flags;
+	int dir;
+
+	map = lpc_gpio_get_pinmap(pin);
+
+	if (lpc_gpio_pin_getflags(dev, pin, &flags))
+		return (ENXIO);
+
+	if (flags & GPIO_PIN_OUTPUT)
+		dir = 1;
+
+	if (flags & GPIO_PIN_INPUT)
+		dir = 0;
+
+	switch (map->lp_port) {
+	case 0:
+		state = lpc_gpio_get_4(sc, dir, LPC_GPIO_P0_OUTP_STATE,
+		    LPC_GPIO_P0_INP_STATE);
+		*value = !!(state & (1 << LPC_GPIO_PIN_BIT(map, pin)));
+	case 1:
+		state = lpc_gpio_get_4(sc, dir, LPC_GPIO_P1_OUTP_STATE,
+		    LPC_GPIO_P1_INP_STATE);
+		*value = !!(state & (1 << LPC_GPIO_PIN_BIT(map, pin)));
+	case 2:
+		state = lpc_gpio_read_4(sc, LPC_GPIO_P2_INP_STATE);
+		*value = !!(state & (1 << LPC_GPIO_PIN_BIT(map, pin)));
+	case 3:
+		state = lpc_gpio_get_4(sc, dir, LPC_GPIO_P3_OUTP_STATE,
+		    LPC_GPIO_P3_INP_STATE);
+		if (map->lp_start_bit == -1) {
+			if (dir)
+				*value = !!(state & (1 << (25 + 
+				    LPC_GPIO_PIN_IDX(map, pin))));
+			else
+				*value = !!(state & (1 << (10 + 
+				    LPC_GPIO_PIN_IDX(map, pin))));
+		}
+
+		*value = !!(state & (1 << LPC_GPIO_PIN_BIT(map, pin)));
+	}
+
+	return (0);
+}
+
+static int
+lpc_gpio_pin_set(device_t dev, uint32_t pin, uint32_t value)
+{
+	struct lpc_gpio_softc *sc = device_get_softc(dev);
+	const struct lpc_gpio_pinmap *map;
+	uint32_t state, flags;
+
+	map = lpc_gpio_get_pinmap(pin);
+
+	if (lpc_gpio_pin_getflags(dev, pin, &flags))
+		return (ENXIO);
+
+	if ((flags & GPIO_PIN_OUTPUT) == 0)
+		return (EINVAL);
+
+	state = (1 << LPC_GPIO_PIN_BIT(map, pin));
+
+	switch (map->lp_port) {
+	case 0:
+		lpc_gpio_set_4(sc, value, LPC_GPIO_P0_OUTP_SET,
+		    LPC_GPIO_P0_OUTP_CLR, state);
+		break;
+	case 1:
+		lpc_gpio_set_4(sc, value, LPC_GPIO_P1_OUTP_SET,
+		    LPC_GPIO_P1_OUTP_CLR, state);
+		break;
+	case 2:
+		lpc_gpio_set_4(sc, value, LPC_GPIO_P2_OUTP_SET,
+		    LPC_GPIO_P2_OUTP_CLR, state);
+		break;
+	case 3:
+		if (map->lp_start_bit == -1)
+			state = (1 << (25 + LPC_GPIO_PIN_IDX(map, pin)));
+		
+		lpc_gpio_set_4(sc, value, LPC_GPIO_P3_OUTP_SET,
+		    LPC_GPIO_P3_OUTP_CLR, state);
+		break;
+	}
+
+	return (0);
+}
+
+static int
+lpc_gpio_pin_toggle(device_t dev, uint32_t pin)
+{
+	const struct lpc_gpio_pinmap *map;
+	uint32_t flags;
+
+	map = lpc_gpio_get_pinmap(pin);
+
+	if (lpc_gpio_pin_getflags(dev, pin, &flags))
+		return (ENXIO);
+
+	if ((flags & GPIO_PIN_OUTPUT) == 0)
+		return (EINVAL);
+	
+	panic("not implemented yet");
+
+	return (0);
+
+}
+
+static const struct lpc_gpio_pinmap *
+lpc_gpio_get_pinmap(int pin)
+{
+	const struct lpc_gpio_pinmap *map;
+
+	for (map = &lpc_gpio_pins[0]; map->lp_start_idx != -1; map++) {
+		if (pin >= map->lp_start_idx &&
+		    pin < map->lp_start_idx + map->lp_pin_count)
+			return map;
+	}
+
+	panic("pin number %d out of range", pin);
+}
+
+int
+lpc_gpio_set_flags(device_t dev, int pin, int flags)
+{
+	if (lpc_gpio_sc == NULL)
+		return (ENXIO);
+
+	return lpc_gpio_pin_setflags(lpc_gpio_sc->lg_dev, pin, flags);
+}
+
+int
+lpc_gpio_set_state(device_t dev, int pin, int state)
+{
+	if (lpc_gpio_sc == NULL)
+		return (ENXIO);
+
+	return lpc_gpio_pin_set(lpc_gpio_sc->lg_dev, pin, state); 
+}
+
+int
+lpc_gpio_get_state(device_t dev, int pin, int *state)
+{
+	if (lpc_gpio_sc == NULL)
+		return (ENXIO);
+
+	return lpc_gpio_pin_get(lpc_gpio_sc->lg_dev, pin, state);
+}
+
+void
+platform_gpio_init()
+{
+	bus_space_tag_t bst;
+	bus_space_handle_t bsh;
+
+	bst = fdtbus_bs_tag;
+
+	/* Preset SPI devices CS pins to one */
+	bus_space_map(bst, LPC_GPIO_PHYS_BASE, LPC_GPIO_SIZE, 0, &bsh);
+	bus_space_write_4(bst, bsh, LPC_GPIO_P3_OUTP_SET,
+	    1 << (SSD1289_CS_PIN - LPC_GPIO_GPO_00(0)) |
+	    1 << (SSD1289_DC_PIN - LPC_GPIO_GPO_00(0)) |
+	    1 << (ADS7846_CS_PIN - LPC_GPIO_GPO_00(0)));	
+	bus_space_unmap(bst, bsh, LPC_GPIO_SIZE);
+}
+
+static device_method_t lpc_gpio_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		lpc_gpio_probe),
+	DEVMETHOD(device_attach,	lpc_gpio_attach),
+	DEVMETHOD(device_detach,	lpc_gpio_detach),
+
+	/* GPIO interface */
+	DEVMETHOD(gpio_pin_max,		lpc_gpio_pin_max),
+	DEVMETHOD(gpio_pin_getcaps,	lpc_gpio_pin_getcaps),
+	DEVMETHOD(gpio_pin_getflags,	lpc_gpio_pin_getflags),
+	DEVMETHOD(gpio_pin_setflags,	lpc_gpio_pin_setflags),
+	DEVMETHOD(gpio_pin_getname,	lpc_gpio_pin_getname),
+	DEVMETHOD(gpio_pin_set,		lpc_gpio_pin_set),
+	DEVMETHOD(gpio_pin_get,		lpc_gpio_pin_get),
+	DEVMETHOD(gpio_pin_toggle,	lpc_gpio_pin_toggle),
+
+	{ 0, 0 }
+};
+
+static devclass_t lpc_gpio_devclass;
+
+static driver_t lpc_gpio_driver = {
+	"lpcgpio",
+	lpc_gpio_methods,
+	sizeof(struct lpc_gpio_softc),
+};
+
+extern devclass_t gpiobus_devclass, gpioc_devclass;
+extern driver_t gpiobus_driver, gpioc_driver;
+
+DRIVER_MODULE(lpcgpio, simplebus, lpc_gpio_driver, lpc_gpio_devclass, 0, 0);
+DRIVER_MODULE(gpiobus, lpcgpio, gpiobus_driver, gpiobus_devclass, 0, 0);
+DRIVER_MODULE(gpioc, lpcgpio, gpioc_driver, gpioc_devclass, 0, 0);
+MODULE_VERSION(lpcgpio, 1);


Property changes on: trunk/sys/arm/lpc/lpc_gpio.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/lpc/lpc_intc.c
===================================================================
--- trunk/sys/arm/lpc/lpc_intc.c	                        (rev 0)
+++ trunk/sys/arm/lpc/lpc_intc.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,247 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2010 Jakub Wojciech Klama <jceel at FreeBSD.org>
+ * 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: stable/10/sys/arm/lpc/lpc_intc.c 266152 2014-05-15 16:11:06Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/timetc.h>
+#include <machine/bus.h>
+#include <machine/intr.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <arm/lpc/lpcreg.h>
+
+struct lpc_intc_softc {
+	struct resource *	li_res;
+	bus_space_tag_t		li_bst;
+	bus_space_handle_t	li_bsh;
+};
+
+static int lpc_intc_probe(device_t);
+static int lpc_intc_attach(device_t);
+static void lpc_intc_eoi(void *);
+
+static struct lpc_intc_softc *intc_softc = NULL;
+
+#define	intc_read_4(reg)		\
+    bus_space_read_4(intc_softc->li_bst, intc_softc->li_bsh, reg)
+#define	intc_write_4(reg, val)		\
+    bus_space_write_4(intc_softc->li_bst, intc_softc->li_bsh, reg, val)
+
+static int
+lpc_intc_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "lpc,pic"))
+		return (ENXIO);
+
+	device_set_desc(dev, "LPC32x0 Interrupt Controller");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+lpc_intc_attach(device_t dev)
+{
+	struct lpc_intc_softc *sc = device_get_softc(dev);
+	int rid = 0;
+
+	if (intc_softc)
+		return (ENXIO);
+
+	sc->li_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 
+	    RF_ACTIVE);
+	if (!sc->li_res) {
+		device_printf(dev, "could not alloc resources\n");
+		return (ENXIO);
+	}
+
+	sc->li_bst = rman_get_bustag(sc->li_res);
+	sc->li_bsh = rman_get_bushandle(sc->li_res);
+	intc_softc = sc;
+	arm_post_filter = lpc_intc_eoi;
+
+	/* Clear interrupt status registers and disable all interrupts */
+	intc_write_4(LPC_INTC_MIC_ER, 0);
+	intc_write_4(LPC_INTC_SIC1_ER, 0);
+	intc_write_4(LPC_INTC_SIC2_ER, 0);
+	intc_write_4(LPC_INTC_MIC_RSR, ~0);
+	intc_write_4(LPC_INTC_SIC1_RSR, ~0);
+	intc_write_4(LPC_INTC_SIC2_RSR, ~0);
+	return (0);
+}
+
+static device_method_t lpc_intc_methods[] = {
+	DEVMETHOD(device_probe,		lpc_intc_probe),
+	DEVMETHOD(device_attach,	lpc_intc_attach),
+	{ 0, 0 }
+};
+
+static driver_t lpc_intc_driver = {
+	"pic",
+	lpc_intc_methods,
+	sizeof(struct lpc_intc_softc),
+};
+
+static devclass_t lpc_intc_devclass;
+
+DRIVER_MODULE(pic, simplebus, lpc_intc_driver, lpc_intc_devclass, 0, 0);
+
+int
+arm_get_next_irq(int last)
+{
+	uint32_t value;
+	int i;
+
+	/* IRQs 0-31 are mapped to LPC_INTC_MIC_SR */
+	value = intc_read_4(LPC_INTC_MIC_SR);
+	for (i = 0; i < 32; i++) {
+		if (value & (1 << i))
+			return (i);
+	}
+
+	/* IRQs 32-63 are mapped to LPC_INTC_SIC1_SR */
+	value = intc_read_4(LPC_INTC_SIC1_SR);
+	for (i = 0; i < 32; i++) {
+		if (value & (1 << i))
+			return (i + 32);
+	}
+
+	/* IRQs 64-95 are mapped to LPC_INTC_SIC2_SR */
+	value = intc_read_4(LPC_INTC_SIC2_SR);
+	for (i = 0; i < 32; i++) {
+		if (value & (1 << i))
+			return (i + 64);
+	}
+
+	return (-1);
+}
+
+void
+arm_mask_irq(uintptr_t nb)
+{
+	int reg;
+	uint32_t value;
+
+	/* Make sure that interrupt isn't active already */
+	lpc_intc_eoi((void *)nb);
+
+	if (nb > 63) {
+		nb -= 64;
+		reg = LPC_INTC_SIC2_ER;
+	} else if (nb > 31) {
+		nb -= 32;
+		reg = LPC_INTC_SIC1_ER;
+	} else
+		reg = LPC_INTC_MIC_ER;
+
+	/* Clear bit in ER register */
+	value = intc_read_4(reg);
+	value &= ~(1 << nb);
+	intc_write_4(reg, value);
+}
+
+void
+arm_unmask_irq(uintptr_t nb)
+{
+	int reg;
+	uint32_t value;
+
+	if (nb > 63) {
+		nb -= 64;
+		reg = LPC_INTC_SIC2_ER;
+	} else if (nb > 31) {
+		nb -= 32;
+		reg = LPC_INTC_SIC1_ER;
+	} else
+		reg = LPC_INTC_MIC_ER;
+
+	/* Set bit in ER register */
+	value = intc_read_4(reg);
+	value |= (1 << nb);
+	intc_write_4(reg, value);
+}
+
+static void
+lpc_intc_eoi(void *data)
+{
+	int reg;
+	int nb = (int)data;
+	uint32_t value;
+
+	if (nb > 63) {
+		nb -= 64;
+		reg = LPC_INTC_SIC2_RSR;
+	} else if (nb > 31) {
+		nb -= 32;
+		reg = LPC_INTC_SIC1_RSR;
+	} else
+		reg = LPC_INTC_MIC_RSR;
+
+	/* Set bit in RSR register */
+	value = intc_read_4(reg);
+	value |= (1 << nb);
+	intc_write_4(reg, value);
+
+}
+
+struct fdt_fixup_entry fdt_fixup_table[] = {
+	{ NULL, NULL }
+};
+
+static int
+fdt_pic_decode_ic(phandle_t node, pcell_t *intr, int *interrupt, int *trig,
+    int *pol)
+{
+	if (!fdt_is_compatible(node, "lpc,pic"))
+		return (ENXIO);
+
+	*interrupt = fdt32_to_cpu(intr[0]);
+	*trig = INTR_TRIGGER_CONFORM;
+	*pol = INTR_POLARITY_CONFORM;
+	return (0);
+}
+
+fdt_pic_decode_t fdt_pic_table[] = {
+	&fdt_pic_decode_ic,
+	NULL
+};


Property changes on: trunk/sys/arm/lpc/lpc_intc.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/lpc/lpc_machdep.c
===================================================================
--- trunk/sys/arm/lpc/lpc_machdep.c	                        (rev 0)
+++ trunk/sys/arm/lpc/lpc_machdep.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,140 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1994-1998 Mark Brinicombe.
+ * Copyright (c) 1994 Brini.
+ * All rights reserved.
+ *
+ * This code is derived from software written for Brini by Mark Brinicombe
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by Brini.
+ * 4. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BRINI ``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 BRINI 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.
+ *
+ * from: FreeBSD: //depot/projects/arm/src/sys/arm/at91/kb920x_machdep.c, rev 45
+ */
+
+#include "opt_ddb.h"
+#include "opt_platform.h"
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/lpc/lpc_machdep.c 266084 2014-05-14 19:18:58Z ian $");
+
+#define _ARM32_BUS_DMA_PRIVATE
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+#include <machine/devmap.h>
+#include <machine/machdep.h>
+
+#include <arm/lpc/lpcreg.h>
+#include <arm/lpc/lpcvar.h>
+
+#include <dev/fdt/fdt_common.h>
+
+vm_offset_t
+initarm_lastaddr(void)
+{
+
+	return (arm_devmap_lastaddr());
+}
+
+void
+initarm_early_init(void)
+{
+}
+
+void
+initarm_gpio_init(void)
+{
+
+	/*
+	 * Set initial values of GPIO output ports
+	 */
+	platform_gpio_init();
+}
+
+void
+initarm_late_init(void)
+{
+}
+
+/*
+ * Add a single static device mapping.
+ * The values used were taken from the ranges property of the SoC node in the
+ * dts file when this code was converted to arm_devmap_add_entry().
+ */
+int
+initarm_devmap_init(void)
+{
+
+	arm_devmap_add_entry(LPC_DEV_PHYS_BASE, LPC_DEV_SIZE);
+	return (0);
+}
+
+struct arm32_dma_range *
+bus_dma_get_range(void)
+{
+
+	return (NULL);
+}
+
+int
+bus_dma_get_range_nb(void)
+{
+
+	return (0);
+}
+
+void
+cpu_reset(void)
+{
+	bus_space_tag_t bst;
+	bus_space_handle_t bsh;
+
+	bst = fdtbus_bs_tag;
+
+	/* Enable WDT */
+	bus_space_map(bst, LPC_CLKPWR_PHYS_BASE, LPC_CLKPWR_SIZE, 0, &bsh);
+	bus_space_write_4(bst, bsh, LPC_CLKPWR_TIMCLK_CTRL,
+	    LPC_CLKPWR_TIMCLK_CTRL_WATCHDOG);
+	bus_space_unmap(bst, bsh, LPC_CLKPWR_SIZE);
+
+	/* Instant assert of RESETOUT_N with pulse length 1ms */
+	bus_space_map(bst, LPC_WDTIM_PHYS_BASE, LPC_WDTIM_SIZE, 0, &bsh);
+	bus_space_write_4(bst, bsh, LPC_WDTIM_PULSE, 13000);
+	bus_space_write_4(bst, bsh, LPC_WDTIM_MCTRL, 0x70);
+	bus_space_unmap(bst, bsh, LPC_WDTIM_SIZE);
+
+	for (;;)
+		continue;
+}
+


Property changes on: trunk/sys/arm/lpc/lpc_machdep.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/lpc/lpc_mmc.c
===================================================================
--- trunk/sys/arm/lpc/lpc_mmc.c	                        (rev 0)
+++ trunk/sys/arm/lpc/lpc_mmc.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,767 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2011 Jakub Wojciech Klama <jceel at FreeBSD.org>
+ * 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: stable/10/sys/arm/lpc/lpc_mmc.c 318198 2017-05-11 21:01:02Z marius $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+#include <machine/resource.h>
+#include <machine/intr.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <dev/mmc/bridge.h>
+#include <dev/mmc/mmcbrvar.h>
+
+#include <arm/lpc/lpcreg.h>
+#include <arm/lpc/lpcvar.h>
+
+#ifdef DEBUG
+#define debugf(fmt, args...) do { printf("%s(): ", __func__);   \
+    printf(fmt,##args); } while (0)
+#else
+#define debugf(fmt, args...)
+#endif
+
+struct lpc_mmc_dmamap_arg {
+	bus_addr_t		lm_dma_busaddr;
+};
+
+struct lpc_mmc_softc {
+	device_t		lm_dev;
+	struct mtx		lm_mtx;
+	struct resource *	lm_mem_res;
+	struct resource *	lm_irq_res;
+	bus_space_tag_t		lm_bst;
+	bus_space_handle_t	lm_bsh;
+	void *			lm_intrhand;
+	struct mmc_host		lm_host;
+	struct mmc_request *	lm_req;
+	struct mmc_data *	lm_data;
+	uint32_t		lm_flags;
+#define	LPC_SD_FLAGS_IGNORECRC		(1 << 0)
+	int			lm_xfer_direction;
+#define	DIRECTION_READ		0
+#define	DIRECTION_WRITE		1
+	int			lm_xfer_done;
+	int			lm_bus_busy;
+	bus_dma_tag_t		lm_dma_tag;
+	bus_dmamap_t		lm_dma_map;
+	bus_addr_t		lm_buffer_phys;
+	void *			lm_buffer;
+};
+
+#define	LPC_SD_MAX_BLOCKSIZE	1024
+/* XXX */
+#define	LPC_MMC_DMACH_READ	1
+#define	LPC_MMC_DMACH_WRITE	0
+
+
+static int lpc_mmc_probe(device_t);
+static int lpc_mmc_attach(device_t);
+static int lpc_mmc_detach(device_t);
+static void lpc_mmc_intr(void *);
+
+static void lpc_mmc_cmd(struct lpc_mmc_softc *, struct mmc_command *);
+static void lpc_mmc_setup_xfer(struct lpc_mmc_softc *, struct mmc_data *);
+
+static int lpc_mmc_update_ios(device_t, device_t);
+static int lpc_mmc_request(device_t, device_t, struct mmc_request *);
+static int lpc_mmc_get_ro(device_t, device_t);
+static int lpc_mmc_acquire_host(device_t, device_t);
+static int lpc_mmc_release_host(device_t, device_t);
+
+static void lpc_mmc_dma_rxfinish(void *);
+static void lpc_mmc_dma_rxerror(void *);
+static void lpc_mmc_dma_txfinish(void *);
+static void lpc_mmc_dma_txerror(void *);
+
+static void lpc_mmc_dmamap_cb(void *, bus_dma_segment_t *, int, int);
+
+#define	lpc_mmc_lock(_sc)						\
+    mtx_lock(&_sc->lm_mtx);
+#define	lpc_mmc_unlock(_sc)						\
+    mtx_unlock(&_sc->lm_mtx);
+#define	lpc_mmc_read_4(_sc, _reg)					\
+    bus_space_read_4(_sc->lm_bst, _sc->lm_bsh, _reg)
+#define	lpc_mmc_write_4(_sc, _reg, _value)				\
+    bus_space_write_4(_sc->lm_bst, _sc->lm_bsh, _reg, _value)
+
+static struct lpc_dmac_channel_config lpc_mmc_dma_rxconf = {
+	.ldc_fcntl = LPC_DMAC_FLOW_D_P2M,
+	.ldc_src_periph = LPC_DMAC_SD_ID,
+	.ldc_src_width = LPC_DMAC_CH_CONTROL_WIDTH_4,
+	.ldc_src_incr = 0,
+	.ldc_src_burst = LPC_DMAC_CH_CONTROL_BURST_8,
+	.ldc_dst_periph = LPC_DMAC_SD_ID,
+	.ldc_dst_width = LPC_DMAC_CH_CONTROL_WIDTH_4,
+	.ldc_dst_incr = 1,
+	.ldc_dst_burst = LPC_DMAC_CH_CONTROL_BURST_8,
+	.ldc_success_handler = lpc_mmc_dma_rxfinish,
+	.ldc_error_handler = lpc_mmc_dma_rxerror,
+};
+
+static struct lpc_dmac_channel_config lpc_mmc_dma_txconf = {
+	.ldc_fcntl = LPC_DMAC_FLOW_P_M2P,
+	.ldc_src_periph = LPC_DMAC_SD_ID,
+	.ldc_src_width = LPC_DMAC_CH_CONTROL_WIDTH_4,
+	.ldc_src_incr = 1,
+	.ldc_src_burst = LPC_DMAC_CH_CONTROL_BURST_8,
+	.ldc_dst_periph = LPC_DMAC_SD_ID,
+	.ldc_dst_width = LPC_DMAC_CH_CONTROL_WIDTH_4,
+	.ldc_dst_incr = 0,
+	.ldc_dst_burst = LPC_DMAC_CH_CONTROL_BURST_8,
+	.ldc_success_handler = lpc_mmc_dma_txfinish,
+	.ldc_error_handler = lpc_mmc_dma_txerror,
+};
+
+static int
+lpc_mmc_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "lpc,mmc"))
+		return (ENXIO);
+
+	device_set_desc(dev, "LPC32x0 MMC/SD controller");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+lpc_mmc_attach(device_t dev)
+{
+	struct lpc_mmc_softc *sc = device_get_softc(dev);
+	struct lpc_mmc_dmamap_arg ctx;
+	device_t child;
+	int rid, err;
+
+	sc->lm_dev = dev;
+	sc->lm_req = NULL;
+
+	mtx_init(&sc->lm_mtx, "lpcmmc", "mmc", MTX_DEF);
+
+	rid = 0;
+	sc->lm_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	    RF_ACTIVE);
+	if (!sc->lm_mem_res) {
+		device_printf(dev, "cannot allocate memory window\n");
+		return (ENXIO);
+	}
+
+	sc->lm_bst = rman_get_bustag(sc->lm_mem_res);
+	sc->lm_bsh = rman_get_bushandle(sc->lm_mem_res);
+
+	debugf("virtual register space: 0x%08lx\n", sc->lm_bsh);
+
+	rid = 0;
+	sc->lm_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+	    RF_ACTIVE);
+	if (!sc->lm_irq_res) {
+		device_printf(dev, "cannot allocate interrupt\n");
+		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->lm_mem_res);
+		return (ENXIO);
+	}
+
+	if (bus_setup_intr(dev, sc->lm_irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
+	    NULL, lpc_mmc_intr, sc, &sc->lm_intrhand))
+	{
+		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->lm_mem_res);
+		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->lm_irq_res);
+		device_printf(dev, "cannot setup interrupt handler\n");
+		return (ENXIO);
+	}
+
+	sc->lm_host.f_min = 312500;
+	sc->lm_host.f_max = 2500000;
+	sc->lm_host.host_ocr = MMC_OCR_300_310 | MMC_OCR_310_320 |
+	    MMC_OCR_320_330 | MMC_OCR_330_340;
+#if 0
+	sc->lm_host.caps = MMC_CAP_4_BIT_DATA;
+#endif
+
+	lpc_pwr_write(dev, LPC_CLKPWR_MS_CTRL,
+	    LPC_CLKPWR_MS_CTRL_CLOCK_EN | LPC_CLKPWR_MS_CTRL_SD_CLOCK | 1);
+	lpc_mmc_write_4(sc, LPC_SD_POWER, LPC_SD_POWER_CTRL_ON);
+
+	device_set_ivars(dev, &sc->lm_host);
+
+	child = device_add_child(dev, "mmc", -1);
+	if (!child) {
+		device_printf(dev, "attaching MMC bus failed!\n");
+		bus_teardown_intr(dev, sc->lm_irq_res, sc->lm_intrhand);
+		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->lm_mem_res);
+		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->lm_irq_res);
+		return (ENXIO);
+	}
+
+	/* Alloc DMA memory */
+	err = bus_dma_tag_create(
+	    bus_get_dma_tag(sc->lm_dev),
+	    4, 0,			/* alignment, boundary */
+	    BUS_SPACE_MAXADDR_32BIT,	/* lowaddr */
+	    BUS_SPACE_MAXADDR,		/* highaddr */
+	    NULL, NULL,			/* filter, filterarg */
+	    LPC_SD_MAX_BLOCKSIZE, 1,	/* maxsize, nsegments */
+	    LPC_SD_MAX_BLOCKSIZE, 0,	/* maxsegsize, flags */
+	    NULL, NULL,			/* lockfunc, lockarg */
+	    &sc->lm_dma_tag);
+
+	err = bus_dmamem_alloc(sc->lm_dma_tag, (void **)&sc->lm_buffer,
+	    0, &sc->lm_dma_map);
+	if (err) {
+		device_printf(dev, "cannot allocate framebuffer\n");
+		goto fail;
+	}
+
+	err = bus_dmamap_load(sc->lm_dma_tag, sc->lm_dma_map, sc->lm_buffer,
+	    LPC_SD_MAX_BLOCKSIZE, lpc_mmc_dmamap_cb, &ctx, BUS_DMA_NOWAIT);
+	if (err) {
+		device_printf(dev, "cannot load DMA map\n");
+		goto fail;
+	}
+
+	sc->lm_buffer_phys = ctx.lm_dma_busaddr;
+
+	lpc_mmc_dma_rxconf.ldc_handler_arg = (void *)sc;
+	err = lpc_dmac_config_channel(dev, LPC_MMC_DMACH_READ, &lpc_mmc_dma_rxconf);
+	if (err) {
+		device_printf(dev, "cannot allocate RX DMA channel\n");
+		goto fail;
+	}
+
+
+	lpc_mmc_dma_txconf.ldc_handler_arg = (void *)sc;
+	err = lpc_dmac_config_channel(dev, LPC_MMC_DMACH_WRITE, &lpc_mmc_dma_txconf);	
+	if (err) {
+		device_printf(dev, "cannot allocate TX DMA channel\n");
+		goto fail;
+	}
+
+	bus_generic_probe(dev);
+	bus_generic_attach(dev);
+
+	return (0);
+
+fail:
+	if (sc->lm_intrhand)
+		bus_teardown_intr(dev, sc->lm_irq_res, sc->lm_intrhand);
+	if (sc->lm_irq_res)
+		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->lm_irq_res);
+	if (sc->lm_mem_res)
+		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->lm_mem_res);
+	return (err);
+}
+
+static int
+lpc_mmc_detach(device_t dev)
+{
+	return (EBUSY);
+}
+
+static void
+lpc_mmc_intr(void *arg)
+{
+	struct lpc_mmc_softc *sc = (struct lpc_mmc_softc *)arg;
+	struct mmc_command *cmd;
+	uint32_t status;
+
+	status = lpc_mmc_read_4(sc, LPC_SD_STATUS);
+
+	debugf("interrupt: 0x%08x\n", status);
+
+	if (status & LPC_SD_STATUS_CMDCRCFAIL) {
+		cmd = sc->lm_req->cmd;
+		cmd->error = sc->lm_flags & LPC_SD_FLAGS_IGNORECRC
+		    ? MMC_ERR_NONE : MMC_ERR_BADCRC;
+		cmd->resp[0] = lpc_mmc_read_4(sc, LPC_SD_RESP0);
+		sc->lm_req->done(sc->lm_req);
+		sc->lm_req = NULL;
+		lpc_mmc_write_4(sc, LPC_SD_CLEAR, LPC_SD_STATUS_CMDCRCFAIL);	
+	}
+
+	if (status & LPC_SD_STATUS_CMDACTIVE)
+	{
+		debugf("command active\n");
+		cmd = sc->lm_req->cmd;
+		cmd->resp[0] = lpc_mmc_read_4(sc, LPC_SD_RESP0);
+		sc->lm_req->done(sc->lm_req);
+		sc->lm_req = NULL;
+	}
+	
+	if (status & LPC_SD_STATUS_DATATIMEOUT) {
+		device_printf(sc->lm_dev, "data timeout\n");
+		lpc_mmc_write_4(sc, LPC_SD_CLEAR, LPC_SD_STATUS_DATATIMEOUT);
+	}
+
+	if (status & LPC_SD_STATUS_TXUNDERRUN) {
+		device_printf(sc->lm_dev, "TX underrun\n");
+		lpc_mmc_write_4(sc, LPC_SD_CLEAR, LPC_SD_STATUS_TXUNDERRUN);
+	}
+	
+	if (status & LPC_SD_STATUS_CMDRESPEND) {
+		debugf("command response\n");
+		cmd = sc->lm_req->cmd;
+		
+		if (cmd->flags & MMC_RSP_136) {
+			cmd->resp[3] = lpc_mmc_read_4(sc, LPC_SD_RESP3);
+			cmd->resp[2] = lpc_mmc_read_4(sc, LPC_SD_RESP2);
+			cmd->resp[1] = lpc_mmc_read_4(sc, LPC_SD_RESP1);
+		}
+
+		cmd->resp[0] = lpc_mmc_read_4(sc, LPC_SD_RESP0);
+		cmd->error = MMC_ERR_NONE;
+	
+		if (cmd->data && (cmd->data->flags & MMC_DATA_WRITE))
+			lpc_mmc_setup_xfer(sc, sc->lm_req->cmd->data);
+
+		if (!cmd->data) {	
+			sc->lm_req->done(sc->lm_req);
+			sc->lm_req = NULL;
+		}
+
+		lpc_mmc_write_4(sc, LPC_SD_CLEAR, LPC_SD_STATUS_CMDRESPEND);
+	}
+
+	if (status & LPC_SD_STATUS_CMDSENT) {
+		debugf("command sent\n");
+		cmd = sc->lm_req->cmd;
+		cmd->error = MMC_ERR_NONE;
+		sc->lm_req->done(sc->lm_req);
+		sc->lm_req = NULL;
+		lpc_mmc_write_4(sc, LPC_SD_CLEAR, LPC_SD_STATUS_CMDSENT);
+	}
+	
+	if (status & LPC_SD_STATUS_DATAEND) {
+		if (sc->lm_xfer_direction == DIRECTION_READ)
+			lpc_dmac_start_burst(sc->lm_dev, LPC_DMAC_SD_ID);
+
+		lpc_mmc_write_4(sc, LPC_SD_CLEAR, LPC_SD_STATUS_DATAEND);
+	}
+
+	if (status & LPC_SD_STATUS_CMDTIMEOUT) {
+		device_printf(sc->lm_dev, "command response timeout\n");
+		cmd = sc->lm_req->cmd;
+		cmd->error = MMC_ERR_TIMEOUT;
+		sc->lm_req->done(sc->lm_req);
+		sc->lm_req = NULL;
+		lpc_mmc_write_4(sc, LPC_SD_CLEAR, LPC_SD_STATUS_CMDTIMEOUT);
+		return;
+	}
+
+	if (status & LPC_SD_STATUS_STARTBITERR) {
+		device_printf(sc->lm_dev, "start bit error\n");
+		lpc_mmc_write_4(sc, LPC_SD_CLEAR, LPC_SD_STATUS_STARTBITERR);
+	}
+
+	if (status & LPC_SD_STATUS_DATACRCFAIL) {		
+		device_printf(sc->lm_dev, "data CRC error\n");
+		debugf("data buffer: %p\n", sc->lm_buffer);
+		cmd = sc->lm_req->cmd;
+		cmd->error = MMC_ERR_BADCRC;
+		sc->lm_req->done(sc->lm_req);
+		sc->lm_req = NULL;
+
+		if (sc->lm_xfer_direction == DIRECTION_READ)
+			lpc_dmac_start_burst(sc->lm_dev, LPC_DMAC_SD_ID);
+
+		lpc_mmc_write_4(sc, LPC_SD_CLEAR, LPC_SD_STATUS_DATACRCFAIL);
+	}
+
+	if (status & LPC_SD_STATUS_DATABLOCKEND) {
+		debugf("data block end\n");
+		if (sc->lm_xfer_direction == DIRECTION_READ)
+			memcpy(sc->lm_data->data, sc->lm_buffer, sc->lm_data->len);
+
+		if (sc->lm_xfer_direction == DIRECTION_WRITE) {
+			lpc_dmac_disable_channel(sc->lm_dev, LPC_MMC_DMACH_WRITE);
+			lpc_mmc_write_4(sc, LPC_SD_DATACTRL, 0);
+		}
+	
+		sc->lm_req->done(sc->lm_req);
+		sc->lm_req = NULL;
+		lpc_mmc_write_4(sc, LPC_SD_CLEAR, LPC_SD_STATUS_DATABLOCKEND);
+	}
+
+	debugf("done\n");
+}
+
+static int
+lpc_mmc_request(device_t bus, device_t child, struct mmc_request *req)
+{
+	struct lpc_mmc_softc *sc = device_get_softc(bus);
+
+	debugf("request: %p\n", req);
+
+	lpc_mmc_lock(sc);
+	if (sc->lm_req)
+		return (EBUSY);
+
+	sc->lm_req = req;
+
+	if (req->cmd->data && req->cmd->data->flags & MMC_DATA_WRITE) {
+		memcpy(sc->lm_buffer, req->cmd->data->data, req->cmd->data->len);
+		lpc_mmc_cmd(sc, req->cmd);
+		lpc_mmc_unlock(sc);
+		return (0);
+	}
+
+	if (req->cmd->data)
+		lpc_mmc_setup_xfer(sc, req->cmd->data);
+
+	lpc_mmc_cmd(sc, req->cmd);
+	lpc_mmc_unlock(sc);
+
+	return (0);
+}
+
+static void
+lpc_mmc_cmd(struct lpc_mmc_softc *sc, struct mmc_command *cmd)
+{
+	uint32_t cmdreg = 0;
+
+	debugf("cmd: %d arg: 0x%08x\n", cmd->opcode, cmd->arg);
+
+	if (lpc_mmc_read_4(sc, LPC_SD_COMMAND) & LPC_SD_COMMAND_ENABLE) {
+		lpc_mmc_write_4(sc, LPC_SD_COMMAND, 0);
+		DELAY(1000);
+	}
+
+	sc->lm_flags &= ~LPC_SD_FLAGS_IGNORECRC;
+
+	if (cmd->flags & MMC_RSP_PRESENT)
+		cmdreg |= LPC_SD_COMMAND_RESPONSE;
+
+	if (MMC_RSP(cmd->flags) == MMC_RSP_R2)
+		cmdreg |= LPC_SD_COMMAND_LONGRSP;
+
+	if (MMC_RSP(cmd->flags) == MMC_RSP_R3)
+		sc->lm_flags |= LPC_SD_FLAGS_IGNORECRC;
+
+	cmdreg |= LPC_SD_COMMAND_ENABLE;
+	cmdreg |= (cmd->opcode & LPC_SD_COMMAND_CMDINDEXMASK);
+
+	lpc_mmc_write_4(sc, LPC_SD_MASK0, 0xffffffff);
+	lpc_mmc_write_4(sc, LPC_SD_MASK1, 0xffffffff);
+	lpc_mmc_write_4(sc, LPC_SD_ARGUMENT, cmd->arg);
+	lpc_mmc_write_4(sc, LPC_SD_COMMAND, cmdreg);
+}
+
+static void
+lpc_mmc_setup_xfer(struct lpc_mmc_softc *sc, struct mmc_data *data)
+{
+	uint32_t datactrl = 0;
+	int data_words = data->len / 4;
+
+	sc->lm_data = data;
+	sc->lm_xfer_done = 0;
+
+	debugf("data: %p, len: %d, %s\n", data,
+	    data->len, (data->flags & MMC_DATA_READ) ? "read" : "write");
+
+	if (data->flags & MMC_DATA_READ) {
+		sc->lm_xfer_direction = DIRECTION_READ;
+		lpc_dmac_setup_transfer(sc->lm_dev, LPC_MMC_DMACH_READ,
+		    LPC_SD_PHYS_BASE + LPC_SD_FIFO, sc->lm_buffer_phys,
+		    data_words, 0);
+	}
+
+	if (data->flags & MMC_DATA_WRITE) {
+		sc->lm_xfer_direction = DIRECTION_WRITE;
+		lpc_dmac_setup_transfer(sc->lm_dev, LPC_MMC_DMACH_WRITE,
+		    sc->lm_buffer_phys, LPC_SD_PHYS_BASE + LPC_SD_FIFO,
+		    data_words, 0);
+	}
+
+	datactrl |= (sc->lm_xfer_direction 
+	    ? LPC_SD_DATACTRL_WRITE 
+	    : LPC_SD_DATACTRL_READ);
+
+	datactrl |= LPC_SD_DATACTRL_DMAENABLE | LPC_SD_DATACTRL_ENABLE;
+	datactrl |= (ffs(data->len) - 1) << 4;
+
+	debugf("datactrl: 0x%08x\n", datactrl);
+
+	lpc_mmc_write_4(sc, LPC_SD_DATATIMER, 0xFFFF0000);
+	lpc_mmc_write_4(sc, LPC_SD_DATALENGTH, data->len);
+	lpc_mmc_write_4(sc, LPC_SD_DATACTRL, datactrl);
+}
+
+static int
+lpc_mmc_read_ivar(device_t bus, device_t child, int which, 
+    uintptr_t *result)
+{
+	struct lpc_mmc_softc *sc = device_get_softc(bus);
+
+	switch (which) {
+	default:
+		return (EINVAL);
+	case MMCBR_IVAR_BUS_MODE:
+		*(int *)result = sc->lm_host.ios.bus_mode;
+		break;
+	case MMCBR_IVAR_BUS_WIDTH:
+		*(int *)result = sc->lm_host.ios.bus_width;
+		break;
+	case MMCBR_IVAR_CHIP_SELECT:
+		*(int *)result = sc->lm_host.ios.chip_select;
+		break;
+	case MMCBR_IVAR_CLOCK:
+		*(int *)result = sc->lm_host.ios.clock;
+		break;
+	case MMCBR_IVAR_F_MIN:
+		*(int *)result = sc->lm_host.f_min;
+		break;
+	case MMCBR_IVAR_F_MAX:
+		*(int *)result = sc->lm_host.f_max;
+		break;
+	case MMCBR_IVAR_HOST_OCR:
+		*(int *)result = sc->lm_host.host_ocr;
+		break;
+	case MMCBR_IVAR_MODE:
+		*(int *)result = sc->lm_host.mode;
+		break;
+	case MMCBR_IVAR_OCR:
+		*(int *)result = sc->lm_host.ocr;
+		break;
+	case MMCBR_IVAR_POWER_MODE:
+		*(int *)result = sc->lm_host.ios.power_mode;
+		break;
+	case MMCBR_IVAR_VDD:
+		*(int *)result = sc->lm_host.ios.vdd;
+		break;
+	case MMCBR_IVAR_CAPS:
+		*(int *)result = sc->lm_host.caps;
+		break;
+	case MMCBR_IVAR_MAX_DATA:
+		*(int *)result = 1;
+		break;
+	}
+
+	return (0);
+}
+
+static int
+lpc_mmc_write_ivar(device_t bus, device_t child, int which,
+    uintptr_t value)
+{
+	struct lpc_mmc_softc *sc = device_get_softc(bus);
+
+	switch (which) {
+	default:
+		return (EINVAL);
+	case MMCBR_IVAR_BUS_MODE:
+		sc->lm_host.ios.bus_mode = value;
+		break;
+	case MMCBR_IVAR_BUS_WIDTH:
+		sc->lm_host.ios.bus_width = value;
+		break;
+	case MMCBR_IVAR_CHIP_SELECT:
+		sc->lm_host.ios.chip_select = value;
+		break;
+	case MMCBR_IVAR_CLOCK:
+		sc->lm_host.ios.clock = value;
+		break;
+	case MMCBR_IVAR_MODE:
+		sc->lm_host.mode = value;
+		break;
+	case MMCBR_IVAR_OCR:
+		sc->lm_host.ocr = value;
+		break;
+	case MMCBR_IVAR_POWER_MODE:
+		sc->lm_host.ios.power_mode = value;
+		break;
+	case MMCBR_IVAR_VDD:
+		sc->lm_host.ios.vdd = value;
+		break;
+	/* These are read-only */
+	case MMCBR_IVAR_CAPS:
+	case MMCBR_IVAR_HOST_OCR:
+	case MMCBR_IVAR_F_MIN:
+	case MMCBR_IVAR_F_MAX:
+	case MMCBR_IVAR_MAX_DATA:
+		return (EINVAL);
+	}
+	return (0);
+}
+
+static int
+lpc_mmc_update_ios(device_t bus, device_t child)
+{
+	struct lpc_mmc_softc *sc = device_get_softc(bus);
+	struct mmc_ios *ios = &sc->lm_host.ios;
+	uint32_t clkdiv = 0, pwr = 0;
+
+	if (ios->bus_width == bus_width_4)
+		clkdiv |= LPC_SD_CLOCK_WIDEBUS;
+
+	/* Calculate clock divider */
+	clkdiv = (LPC_SD_CLK / (2 * ios->clock)) - 1;
+
+	/* Clock rate should not exceed rate requested in ios */
+	if ((LPC_SD_CLK / (2 * (clkdiv + 1))) > ios->clock)
+		clkdiv++;
+
+	debugf("clock: %dHz, clkdiv: %d\n", ios->clock, clkdiv);
+
+	if (ios->bus_width == bus_width_4) {
+		debugf("using wide bus mode\n");
+		clkdiv |= LPC_SD_CLOCK_WIDEBUS;
+	}
+
+	lpc_mmc_write_4(sc, LPC_SD_CLOCK, clkdiv | LPC_SD_CLOCK_ENABLE);
+
+	switch (ios->power_mode) {
+	case power_off:
+		pwr |= LPC_SD_POWER_CTRL_OFF;
+		break;
+	case power_up:
+		pwr |= LPC_SD_POWER_CTRL_UP;
+		break;
+	case power_on:
+		pwr |= LPC_SD_POWER_CTRL_ON;
+		break;
+	}
+
+	if (ios->bus_mode == opendrain)
+		pwr |= LPC_SD_POWER_OPENDRAIN;
+
+	lpc_mmc_write_4(sc, LPC_SD_POWER, pwr);
+
+	return (0);
+}
+
+static int
+lpc_mmc_get_ro(device_t bus, device_t child)
+{
+
+	return (0);
+}
+
+static int
+lpc_mmc_acquire_host(device_t bus, device_t child)
+{
+	struct lpc_mmc_softc *sc = device_get_softc(bus);
+	int error = 0;
+
+	lpc_mmc_lock(sc);
+	while (sc->lm_bus_busy)
+		error = mtx_sleep(sc, &sc->lm_mtx, PZERO, "mmcah", 0);
+
+	sc->lm_bus_busy++;
+	lpc_mmc_unlock(sc);
+	return (error);
+}
+
+static int
+lpc_mmc_release_host(device_t bus, device_t child)
+{
+	struct lpc_mmc_softc *sc = device_get_softc(bus);
+
+	lpc_mmc_lock(sc);
+	sc->lm_bus_busy--;
+	wakeup(sc);
+	lpc_mmc_unlock(sc);
+	return (0);
+}
+
+static void lpc_mmc_dma_rxfinish(void *arg)
+{
+}
+
+static void lpc_mmc_dma_rxerror(void *arg)
+{
+	struct lpc_mmc_softc *sc = (struct lpc_mmc_softc *)arg;
+	device_printf(sc->lm_dev, "DMA RX error\n");
+}
+
+static void lpc_mmc_dma_txfinish(void *arg)
+{
+}
+
+static void lpc_mmc_dma_txerror(void *arg)
+{
+	struct lpc_mmc_softc *sc = (struct lpc_mmc_softc *)arg;
+	device_printf(sc->lm_dev, "DMA TX error\n");
+}
+
+static void
+lpc_mmc_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int err)
+{
+	struct lpc_mmc_dmamap_arg *ctx;
+
+	if (err)
+		return;
+
+	ctx = (struct lpc_mmc_dmamap_arg *)arg;
+	ctx->lm_dma_busaddr = segs[0].ds_addr;
+}
+
+static device_method_t lpc_mmc_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		lpc_mmc_probe),
+	DEVMETHOD(device_attach,	lpc_mmc_attach),
+	DEVMETHOD(device_detach,	lpc_mmc_detach),
+
+	/* Bus interface */
+	DEVMETHOD(bus_read_ivar,	lpc_mmc_read_ivar),
+	DEVMETHOD(bus_write_ivar,	lpc_mmc_write_ivar),
+
+	/* MMC bridge interface */
+	DEVMETHOD(mmcbr_update_ios,	lpc_mmc_update_ios),
+	DEVMETHOD(mmcbr_request,	lpc_mmc_request),
+	DEVMETHOD(mmcbr_get_ro,		lpc_mmc_get_ro),
+	DEVMETHOD(mmcbr_acquire_host,	lpc_mmc_acquire_host),
+	DEVMETHOD(mmcbr_release_host,	lpc_mmc_release_host),
+
+	DEVMETHOD_END
+};
+
+static devclass_t lpc_mmc_devclass;
+
+static driver_t lpc_mmc_driver = {
+	"lpcmmc",
+	lpc_mmc_methods,
+	sizeof(struct lpc_mmc_softc),
+};
+
+DRIVER_MODULE(lpcmmc, simplebus, lpc_mmc_driver, lpc_mmc_devclass, NULL, NULL);
+MMC_DECLARE_BRIDGE(lpcmmc);


Property changes on: trunk/sys/arm/lpc/lpc_mmc.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/lpc/lpc_ohci.c
===================================================================
--- trunk/sys/arm/lpc/lpc_ohci.c	                        (rev 0)
+++ trunk/sys/arm/lpc/lpc_ohci.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,360 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2011 Jakub Wojciech Klama <jceel at FreeBSD.org>
+ * 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: stable/10/sys/arm/lpc/lpc_ohci.c 278278 2015-02-05 20:03:02Z hselasky $");
+
+#include <sys/stdint.h>
+#include <sys/stddef.h>
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/types.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/bus.h>
+#include <sys/module.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/condvar.h>
+#include <sys/sysctl.h>
+#include <sys/rman.h>
+#include <sys/sx.h>
+#include <sys/unistd.h>
+#include <sys/callout.h>
+#include <sys/malloc.h>
+#include <sys/priv.h>
+
+#include <sys/kdb.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <dev/usb/usb.h>
+#include <dev/usb/usbdi.h>
+
+#include <dev/usb/usb_core.h>
+#include <dev/usb/usb_busdma.h>
+#include <dev/usb/usb_process.h>
+#include <dev/usb/usb_util.h>
+
+#include <dev/usb/usb_controller.h>
+#include <dev/usb/usb_bus.h>
+#include <dev/usb/controller/ohci.h>
+#include <dev/usb/controller/ohcireg.h>
+
+#include <arm/lpc/lpcreg.h>
+#include <arm/lpc/lpcvar.h>
+
+#define	I2C_START_BIT		(1 << 8)
+#define	I2C_STOP_BIT		(1 << 9)
+#define	I2C_READ		0x01
+#define	I2C_WRITE		0x00
+#define	DUMMY_BYTE		0x55
+
+#define	lpc_otg_read_4(_sc, _reg)					\
+    bus_space_read_4(_sc->sc_io_tag, _sc->sc_io_hdl, _reg)
+#define	lpc_otg_write_4(_sc, _reg, _value)				\
+    bus_space_write_4(_sc->sc_io_tag, _sc->sc_io_hdl, _reg, _value)
+#define	lpc_otg_wait_write_4(_sc, _wreg, _sreg, _value)			\
+    do {								\
+    	lpc_otg_write_4(_sc, _wreg, _value);				\
+    	while ((lpc_otg_read_4(_sc, _sreg) & _value) != _value);    	\
+    } while (0);
+
+static int lpc_ohci_probe(device_t dev);
+static int lpc_ohci_attach(device_t dev);
+static int lpc_ohci_detach(device_t dev);
+
+static void lpc_otg_i2c_reset(struct ohci_softc *);
+
+static int lpc_isp3101_read(struct ohci_softc *, int);
+static void lpc_isp3101_write(struct ohci_softc *, int, int);
+static void lpc_isp3101_clear(struct ohci_softc *, int, int);
+static void lpc_isp3101_configure(device_t dev, struct ohci_softc *);
+
+static int
+lpc_ohci_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "lpc,usb-ohci"))
+		return (ENXIO);
+
+	device_set_desc(dev, "LPC32x0 USB OHCI controller");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+lpc_ohci_attach(device_t dev)
+{
+	struct ohci_softc *sc = device_get_softc(dev);
+	int err;
+	int rid;
+	int i = 0;
+	uint32_t usbctrl;
+	uint32_t otgstatus;
+
+	sc->sc_bus.parent = dev;
+	sc->sc_bus.devices = sc->sc_devices;
+	sc->sc_bus.devices_max = OHCI_MAX_DEVICES;
+	sc->sc_bus.dma_bits = 32;
+
+	if (usb_bus_mem_alloc_all(&sc->sc_bus, USB_GET_DMA_TAG(dev),
+	    &ohci_iterate_hw_softc))
+		return (ENOMEM);
+
+	rid = 0;
+	sc->sc_io_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
+	if (!sc->sc_io_res) {
+		device_printf(dev, "cannot map OHCI register space\n");
+		goto fail;
+	}
+
+	sc->sc_io_tag = rman_get_bustag(sc->sc_io_res);
+	sc->sc_io_hdl = rman_get_bushandle(sc->sc_io_res);
+	sc->sc_io_size = rman_get_size(sc->sc_io_res);
+
+	rid = 0;
+	sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE);
+	if (sc->sc_irq_res == NULL) {
+		device_printf(dev, "cannot allocate interrupt\n");
+		goto fail;
+	}
+
+	sc->sc_bus.bdev = device_add_child(dev, "usbus", -1);
+	if (!(sc->sc_bus.bdev))
+		goto fail;
+
+	device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
+	strlcpy(sc->sc_vendor, "NXP", sizeof(sc->sc_vendor));
+
+	err = bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
+	    NULL, (void *)ohci_interrupt, sc, &sc->sc_intr_hdl);
+	if (err) {
+		sc->sc_intr_hdl = NULL;
+		goto fail;
+	}
+
+	usbctrl = lpc_pwr_read(dev, LPC_CLKPWR_USB_CTRL);
+	usbctrl |= LPC_CLKPWR_USB_CTRL_SLAVE_HCLK | LPC_CLKPWR_USB_CTRL_BUSKEEPER;
+	lpc_pwr_write(dev, LPC_CLKPWR_USB_CTRL, usbctrl);
+
+	/* Enable OTG I2C clock */
+	lpc_otg_wait_write_4(sc, LPC_OTG_CLOCK_CTRL,
+	    LPC_OTG_CLOCK_STATUS, LPC_OTG_CLOCK_CTRL_I2C_EN);
+
+	/* Reset OTG I2C bus */
+	lpc_otg_i2c_reset(sc);
+
+	lpc_isp3101_configure(dev, sc);
+
+	/* Configure PLL */
+	usbctrl &= ~(LPC_CLKPWR_USB_CTRL_CLK_EN1 | LPC_CLKPWR_USB_CTRL_CLK_EN2);
+	lpc_pwr_write(dev, LPC_CLKPWR_USB_CTRL, usbctrl);
+
+	usbctrl |= LPC_CLKPWR_USB_CTRL_CLK_EN1;
+	lpc_pwr_write(dev, LPC_CLKPWR_USB_CTRL, usbctrl);
+
+	usbctrl |= LPC_CLKPWR_USB_CTRL_FDBKDIV(192-1);
+	usbctrl |= LPC_CLKPWR_USB_CTRL_POSTDIV(1);
+	usbctrl |= LPC_CLKPWR_USB_CTRL_PLL_PDOWN;
+
+	lpc_pwr_write(dev, LPC_CLKPWR_USB_CTRL, usbctrl);
+	do {
+		usbctrl = lpc_pwr_read(dev, LPC_CLKPWR_USB_CTRL);
+		if (i++ > 100000) {
+			device_printf(dev, "USB OTG PLL doesn't lock!\n");
+			goto fail;
+		}
+	} while ((usbctrl & LPC_CLKPWR_USB_CTRL_PLL_LOCK) == 0);
+
+	usbctrl |= LPC_CLKPWR_USB_CTRL_CLK_EN2;
+	usbctrl |= LPC_CLKPWR_USB_CTRL_HOST_NEED_CLK_EN;
+	lpc_pwr_write(dev, LPC_CLKPWR_USB_CTRL, usbctrl);
+	lpc_otg_wait_write_4(sc, LPC_OTG_CLOCK_CTRL, LPC_OTG_CLOCK_STATUS,
+	    (LPC_OTG_CLOCK_CTRL_AHB_EN | LPC_OTG_CLOCK_CTRL_OTG_EN |
+	    LPC_OTG_CLOCK_CTRL_I2C_EN | LPC_OTG_CLOCK_CTRL_HOST_EN));
+
+	otgstatus = lpc_otg_read_4(sc, LPC_OTG_STATUS);
+	lpc_otg_write_4(sc, LPC_OTG_STATUS, otgstatus |
+	    LPC_OTG_STATUS_HOST_EN);
+
+	lpc_isp3101_write(sc, LPC_ISP3101_OTG_CONTROL_1,
+	    LPC_ISP3101_OTG1_VBUS_DRV);
+
+	err = ohci_init(sc);
+	if (err)
+		goto fail;
+
+	err = device_probe_and_attach(sc->sc_bus.bdev);
+	if (err)
+		goto fail;
+	
+	return (0);
+
+fail:
+	if (sc->sc_intr_hdl)
+		bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_intr_hdl);
+	if (sc->sc_irq_res)
+		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res);
+	if (sc->sc_io_res)
+		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_io_res);
+
+	return (ENXIO);
+}
+
+static int
+lpc_isp3101_read(struct ohci_softc *sc, int reg)
+{
+	int status;
+	int i = 0;
+
+	lpc_otg_write_4(sc, LPC_OTG_I2C_TXRX, 
+	    (LPC_ISP3101_I2C_ADDR << 1) | I2C_START_BIT);
+	lpc_otg_write_4(sc, LPC_OTG_I2C_TXRX, reg);
+	lpc_otg_write_4(sc, LPC_OTG_I2C_TXRX, (LPC_ISP3101_I2C_ADDR << 1) | 
+	    I2C_START_BIT | I2C_READ);
+	lpc_otg_write_4(sc, LPC_OTG_I2C_TXRX, I2C_STOP_BIT | DUMMY_BYTE);
+	
+	do {
+		status = lpc_otg_read_4(sc, LPC_OTG_I2C_STATUS);
+		i++;
+	} while ((status & LPC_OTG_I2C_STATUS_TDI) == 0 || i < 100000);
+
+	lpc_otg_write_4(sc, LPC_OTG_I2C_STATUS, LPC_OTG_I2C_STATUS_TDI);
+
+	return (lpc_otg_read_4(sc, LPC_OTG_I2C_TXRX) & 0xff);
+}
+
+static void
+lpc_otg_i2c_reset(struct ohci_softc *sc)
+{
+	int ctrl;
+	int i = 0;
+
+	lpc_otg_write_4(sc, LPC_OTG_I2C_CLKHI, 0x3f);
+	lpc_otg_write_4(sc, LPC_OTG_I2C_CLKLO, 0x3f);
+
+	ctrl = lpc_otg_read_4(sc, LPC_OTG_I2C_CTRL);
+	lpc_otg_write_4(sc, LPC_OTG_I2C_CTRL, ctrl | LPC_OTG_I2C_CTRL_SRST);
+
+	do {
+		ctrl = lpc_otg_read_4(sc, LPC_OTG_I2C_CTRL);
+		i++;
+	} while (ctrl & LPC_OTG_I2C_CTRL_SRST);
+}
+
+static void
+lpc_isp3101_write(struct ohci_softc *sc, int reg, int value)
+{
+	int status;
+	int i = 0;
+
+	bus_space_write_4(sc->sc_io_tag, sc->sc_io_hdl, LPC_OTG_I2C_TXRX,
+	    (LPC_ISP3101_I2C_ADDR << 1) | I2C_START_BIT);
+	bus_space_write_4(sc->sc_io_tag, sc->sc_io_hdl, LPC_OTG_I2C_TXRX,
+	    (reg | I2C_WRITE));
+	bus_space_write_4(sc->sc_io_tag, sc->sc_io_hdl, LPC_OTG_I2C_TXRX,
+	    (value | I2C_STOP_BIT));
+
+	do {
+		status = bus_space_read_4(sc->sc_io_tag, sc->sc_io_hdl,
+		    LPC_OTG_I2C_STATUS);
+		i++;
+	} while ((status & LPC_OTG_I2C_STATUS_TDI) == 0 || i < 100000);
+
+	bus_space_write_4(sc->sc_io_tag, sc->sc_io_hdl, LPC_OTG_I2C_STATUS,
+	    LPC_OTG_I2C_STATUS_TDI);
+}
+
+static __inline void
+lpc_isp3101_clear(struct ohci_softc *sc, int reg, int value)
+{
+	lpc_isp3101_write(sc, (reg | LPC_ISP3101_REG_CLEAR_ADDR), value);
+}
+
+static void
+lpc_isp3101_configure(device_t dev, struct ohci_softc *sc)
+{
+	lpc_isp3101_clear(sc, LPC_ISP3101_MODE_CONTROL_1, LPC_ISP3101_MC1_UART_EN);
+	lpc_isp3101_clear(sc, LPC_ISP3101_MODE_CONTROL_1, ~LPC_ISP3101_MC1_SPEED_REG);
+	lpc_isp3101_write(sc, LPC_ISP3101_MODE_CONTROL_1, LPC_ISP3101_MC1_SPEED_REG);
+	lpc_isp3101_clear(sc, LPC_ISP3101_MODE_CONTROL_2, ~0);
+	lpc_isp3101_write(sc, LPC_ISP3101_MODE_CONTROL_2,
+	    (LPC_ISP3101_MC2_BI_DI | LPC_ISP3101_MC2_PSW_EN
+	    | LPC_ISP3101_MC2_SPD_SUSP_CTRL));
+
+	lpc_isp3101_clear(sc, LPC_ISP3101_OTG_CONTROL_1, ~0);
+	lpc_isp3101_write(sc, LPC_ISP3101_MODE_CONTROL_1, LPC_ISP3101_MC1_DAT_SE0);
+	lpc_isp3101_write(sc, LPC_ISP3101_OTG_CONTROL_1,
+	    (LPC_ISP3101_OTG1_DM_PULLDOWN | LPC_ISP3101_OTG1_DP_PULLDOWN));
+	
+	lpc_isp3101_clear(sc, LPC_ISP3101_OTG_CONTROL_1,
+	    (LPC_ISP3101_OTG1_DM_PULLUP | LPC_ISP3101_OTG1_DP_PULLUP));
+
+	lpc_isp3101_clear(sc, LPC_ISP3101_OTG_INTR_LATCH, ~0);
+	lpc_isp3101_clear(sc, LPC_ISP3101_OTG_INTR_FALLING, ~0);
+	lpc_isp3101_clear(sc, LPC_ISP3101_OTG_INTR_RISING, ~0);
+
+	device_printf(dev,
+	    "ISP3101 PHY <vendor:0x%04x, product:0x%04x, version:0x%04x>\n",
+	    (lpc_isp3101_read(sc, 0x00) | (lpc_isp3101_read(sc, 0x01) << 8)),
+	    (lpc_isp3101_read(sc, 0x03) | (lpc_isp3101_read(sc, 0x04) << 8)),
+	    (lpc_isp3101_read(sc, 0x14) | (lpc_isp3101_read(sc, 0x15) << 8)));
+}
+
+static int
+lpc_ohci_detach(device_t dev)
+{
+	return (0);
+}
+
+
+static device_method_t lpc_ohci_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		lpc_ohci_probe),
+	DEVMETHOD(device_attach,	lpc_ohci_attach),
+	DEVMETHOD(device_detach,	lpc_ohci_detach),
+	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
+
+	/* Bus interface */
+	DEVMETHOD(bus_print_child,	bus_generic_print_child),
+	{ 0, 0 }
+};
+
+static driver_t lpc_ohci_driver = {
+	"ohci",
+	lpc_ohci_methods,
+	sizeof(struct ohci_softc),
+};
+
+static devclass_t lpc_ohci_devclass;
+
+DRIVER_MODULE(ohci, simplebus, lpc_ohci_driver, lpc_ohci_devclass, 0, 0);
+MODULE_DEPEND(ohci, usb, 1, 1, 1);


Property changes on: trunk/sys/arm/lpc/lpc_ohci.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/lpc/lpc_pll.c
===================================================================
--- trunk/sys/arm/lpc/lpc_pll.c	                        (rev 0)
+++ trunk/sys/arm/lpc/lpc_pll.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,29 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2011 Jakub Wojciech Klama <jceel at FreeBSD.org>
+ * 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: stable/10/sys/arm/lpc/lpc_pll.c 239278 2012-08-15 05:37:10Z gonzo $");


Property changes on: trunk/sys/arm/lpc/lpc_pll.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/lpc/lpc_pwr.c
===================================================================
--- trunk/sys/arm/lpc/lpc_pwr.c	                        (rev 0)
+++ trunk/sys/arm/lpc/lpc_pwr.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,130 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2011 Jakub Wojciech Klama <jceel at FreeBSD.org>
+ * 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: stable/10/sys/arm/lpc/lpc_pwr.c 266152 2014-05-15 16:11:06Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <machine/bus.h>
+#include <machine/intr.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <arm/lpc/lpcreg.h>
+#include <arm/lpc/lpcvar.h>
+
+struct lpc_pwr_softc {
+	device_t		dp_dev;
+	struct resource *	dp_mem_res;
+	bus_space_tag_t		dp_bst;
+	bus_space_handle_t	dp_bsh;
+};
+
+static struct lpc_pwr_softc *lpc_pwr_sc = NULL;
+
+static int lpc_pwr_probe(device_t);
+static int lpc_pwr_attach(device_t);
+
+#define	lpc_pwr_read_4(_sc, _reg)			\
+    bus_space_read_4((_sc)->dp_bst, (_sc)->dp_bsh, _reg)
+#define	lpc_pwr_write_4(_sc, _reg, _val)		\
+    bus_space_write_4((_sc)->dp_bst, (_sc)->dp_bsh, _reg, _val)
+
+static int
+lpc_pwr_probe(device_t dev)
+{
+	
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "lpc,pwr"))
+		return (ENXIO);
+
+	device_set_desc(dev, "LPC32x0 Power Controller");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+lpc_pwr_attach(device_t dev)
+{
+	struct lpc_pwr_softc *sc = device_get_softc(dev);
+	int rid;
+
+	sc->dp_dev = dev;
+
+	rid = 0;
+	sc->dp_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 
+	    RF_ACTIVE);
+	if (!sc->dp_mem_res) {
+		device_printf(dev, "cannot allocate memory window\n");
+		return (ENXIO);
+	}
+
+	sc->dp_bst = rman_get_bustag(sc->dp_mem_res);
+	sc->dp_bsh = rman_get_bushandle(sc->dp_mem_res);
+
+	lpc_pwr_sc = sc;
+
+	return (0);
+}
+
+uint32_t
+lpc_pwr_read(device_t dev, int reg)
+{
+	return (lpc_pwr_read_4(lpc_pwr_sc, reg));
+}
+
+void
+lpc_pwr_write(device_t dev, int reg, uint32_t value)
+{
+	lpc_pwr_write_4(lpc_pwr_sc, reg, value);
+}
+
+static device_method_t lpc_pwr_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		lpc_pwr_probe),
+	DEVMETHOD(device_attach,	lpc_pwr_attach),
+	{ 0, 0 }
+};
+
+static devclass_t lpc_pwr_devclass;
+
+static driver_t lpc_pwr_driver = {
+	"pwr",
+	lpc_pwr_methods,
+	sizeof(struct lpc_pwr_softc),
+};
+
+DRIVER_MODULE(pwr, simplebus, lpc_pwr_driver, lpc_pwr_devclass, 0, 0);


Property changes on: trunk/sys/arm/lpc/lpc_pwr.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/lpc/lpc_rtc.c
===================================================================
--- trunk/sys/arm/lpc/lpc_rtc.c	                        (rev 0)
+++ trunk/sys/arm/lpc/lpc_rtc.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,151 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2011 Jakub Wojciech Klama <jceel at FreeBSD.org>
+ * 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: stable/10/sys/arm/lpc/lpc_rtc.c 266152 2014-05-15 16:11:06Z ian $");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/time.h>
+#include <sys/clock.h>
+#include <sys/resource.h>
+#include <sys/systm.h>
+#include <sys/rman.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <arm/lpc/lpcreg.h>
+
+#include "clock_if.h"
+
+struct lpc_rtc_softc {
+	device_t			lr_dev;
+	struct resource	*		lr_mem_res;
+	bus_space_tag_t			lr_bst;
+	bus_space_handle_t		lr_bsh;
+};
+
+static int lpc_rtc_probe(device_t dev);
+static int lpc_rtc_attach(device_t dev);
+static int lpc_rtc_gettime(device_t dev, struct timespec *ts);
+static int lpc_rtc_settime(device_t, struct timespec *);
+
+static int
+lpc_rtc_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "lpc,rtc"))
+		return (ENXIO);
+
+	device_set_desc(dev, "LPC32x0 real time clock");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+lpc_rtc_attach(device_t dev)
+{
+	struct lpc_rtc_softc *sc = device_get_softc(dev);
+	int rid = 0;
+
+	sc->lr_dev = dev;
+
+	clock_register(dev, 1000000);
+
+	sc->lr_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	    RF_ACTIVE);
+	if (!sc->lr_mem_res) {
+		device_printf(dev, "cannot allocate memory window\n");
+		return (ENXIO);
+	}
+
+	sc->lr_bst = rman_get_bustag(sc->lr_mem_res);
+	sc->lr_bsh = rman_get_bushandle(sc->lr_mem_res);
+
+	return (0);
+}
+
+static int
+lpc_rtc_gettime(device_t dev, struct timespec *ts)
+{
+	struct lpc_rtc_softc *sc = device_get_softc(dev);
+
+	ts->tv_sec = bus_space_read_4(sc->lr_bst, sc->lr_bsh, LPC_RTC_UCOUNT);
+	ts->tv_nsec = 0;
+
+	return (0);
+}
+
+static int
+lpc_rtc_settime(device_t dev, struct timespec *ts)
+{
+	struct lpc_rtc_softc *sc = device_get_softc(dev);
+	uint32_t ctrl;
+
+	/* Stop RTC */
+	ctrl = bus_space_read_4(sc->lr_bst, sc->lr_bsh, LPC_RTC_CTRL);
+	bus_space_write_4(sc->lr_bst, sc->lr_bsh, LPC_RTC_CTRL, ctrl | LPC_RTC_CTRL_DISABLE);
+
+	/* Write actual value */
+	bus_space_write_4(sc->lr_bst, sc->lr_bsh, LPC_RTC_UCOUNT, ts->tv_sec);
+
+	/* Start RTC */
+	ctrl = bus_space_read_4(sc->lr_bst, sc->lr_bsh, LPC_RTC_CTRL);
+	bus_space_write_4(sc->lr_bst, sc->lr_bsh, LPC_RTC_CTRL, ctrl & ~LPC_RTC_CTRL_DISABLE);
+
+	return (0);	
+}
+
+static device_method_t lpc_rtc_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		lpc_rtc_probe),
+	DEVMETHOD(device_attach,	lpc_rtc_attach),
+
+	/* Clock interface */
+	DEVMETHOD(clock_gettime,	lpc_rtc_gettime),
+	DEVMETHOD(clock_settime,	lpc_rtc_settime),
+
+	{ 0, 0 },
+};
+
+static driver_t lpc_rtc_driver = {
+	"rtc",
+	lpc_rtc_methods,
+	sizeof(struct lpc_rtc_softc),
+};
+
+static devclass_t lpc_rtc_devclass;
+
+DRIVER_MODULE(rtc, simplebus, lpc_rtc_driver, lpc_rtc_devclass, 0, 0);


Property changes on: trunk/sys/arm/lpc/lpc_rtc.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/lpc/lpc_spi.c
===================================================================
--- trunk/sys/arm/lpc/lpc_spi.c	                        (rev 0)
+++ trunk/sys/arm/lpc/lpc_spi.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,199 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2011 Jakub Wojciech Klama <jceel at FreeBSD.org>
+ * 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: stable/10/sys/arm/lpc/lpc_spi.c 266152 2014-05-15 16:11:06Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bio.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/endian.h>
+#include <sys/kernel.h>
+#include <sys/kthread.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/queue.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+#include <sys/time.h>
+#include <sys/timetc.h>
+#include <sys/watchdog.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+#include <machine/resource.h>
+#include <machine/intr.h>
+
+#include <dev/spibus/spi.h>
+#include <dev/spibus/spibusvar.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <arm/lpc/lpcreg.h>
+#include <arm/lpc/lpcvar.h>
+
+#include "spibus_if.h"
+
+struct lpc_spi_softc
+{
+	device_t		ls_dev;
+	struct resource *	ls_mem_res;
+	struct resource *	ls_irq_res;
+	bus_space_tag_t		ls_bst;
+	bus_space_handle_t	ls_bsh;
+};
+
+static int lpc_spi_probe(device_t);
+static int lpc_spi_attach(device_t);
+static int lpc_spi_detach(device_t);
+static int lpc_spi_transfer(device_t, device_t, struct spi_command *);
+
+#define	lpc_spi_read_4(_sc, _reg)		\
+    bus_space_read_4(_sc->ls_bst, _sc->ls_bsh, _reg)
+#define	lpc_spi_write_4(_sc, _reg, _val)	\
+    bus_space_write_4(_sc->ls_bst, _sc->ls_bsh, _reg, _val)
+
+static int
+lpc_spi_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "lpc,spi"))
+		return (ENXIO);
+
+	device_set_desc(dev, "LPC32x0 PL022 SPI/SSP controller");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+lpc_spi_attach(device_t dev)
+{
+	struct lpc_spi_softc *sc = device_get_softc(dev);
+	int rid;
+
+	sc->ls_dev = dev;
+
+	rid = 0;
+	sc->ls_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	    RF_ACTIVE);
+	if (!sc->ls_mem_res) {
+		device_printf(dev, "cannot allocate memory window\n");
+		return (ENXIO);
+	}
+
+	sc->ls_bst = rman_get_bustag(sc->ls_mem_res);
+	sc->ls_bsh = rman_get_bushandle(sc->ls_mem_res);
+
+	rid = 0;
+	sc->ls_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+	    RF_ACTIVE);
+	if (!sc->ls_irq_res) {
+		device_printf(dev, "cannot allocate interrupt\n");
+		return (ENXIO);
+	}
+
+	bus_space_write_4(sc->ls_bst, 0xd0028100, 0, (1<<12)|(1<<10)|(1<<9)|(1<<8)|(1<<6)|(1<<5)); 
+	lpc_pwr_write(dev, LPC_CLKPWR_SSP_CTRL, LPC_CLKPWR_SSP_CTRL_SSP0EN);
+	lpc_spi_write_4(sc, LPC_SSP_CR0, LPC_SSP_CR0_DSS(8));
+	lpc_spi_write_4(sc, LPC_SSP_CR1, LPC_SSP_CR1_SSE);
+	lpc_spi_write_4(sc, LPC_SSP_CPSR, 128);
+
+	device_add_child(dev, "spibus", 0);
+	return (bus_generic_attach(dev));
+}
+
+static int
+lpc_spi_detach(device_t dev)
+{
+	return (EBUSY);
+}
+
+static int
+lpc_spi_transfer(device_t dev, device_t child, struct spi_command *cmd)
+{
+	struct lpc_spi_softc *sc = device_get_softc(dev);
+	struct spibus_ivar *devi = SPIBUS_IVAR(child);
+	uint8_t *in_buf, *out_buf;
+	int i;
+
+	/* Set CS active */
+	lpc_gpio_set_state(child, devi->cs, 0);
+
+	/* Wait for FIFO to be ready */
+	while ((lpc_spi_read_4(sc, LPC_SSP_SR) & LPC_SSP_SR_TNF) == 0);
+
+	/* Command */
+	in_buf = cmd->rx_cmd;
+	out_buf = cmd->tx_cmd;
+	for (i = 0; i < cmd->tx_cmd_sz; i++) {
+		lpc_spi_write_4(sc, LPC_SSP_DR, out_buf[i]);
+		in_buf[i] = lpc_spi_read_4(sc, LPC_SSP_DR);
+	}
+
+	/* Data */
+	in_buf = cmd->rx_data;
+	out_buf = cmd->tx_data;
+	for (i = 0; i < cmd->tx_data_sz; i++) {
+		lpc_spi_write_4(sc, LPC_SSP_DR, out_buf[i]);
+		in_buf[i] = lpc_spi_read_4(sc, LPC_SSP_DR);
+	}
+
+	/* Set CS inactive */
+	lpc_gpio_set_state(child, devi->cs, 1);
+
+	return (0);
+}
+
+static device_method_t lpc_spi_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		lpc_spi_probe),
+	DEVMETHOD(device_attach,	lpc_spi_attach),
+	DEVMETHOD(device_detach,	lpc_spi_detach),
+
+	/* SPI interface */
+	DEVMETHOD(spibus_transfer,	lpc_spi_transfer),
+
+	{ 0, 0 }
+};
+
+static devclass_t lpc_spi_devclass;
+
+static driver_t lpc_spi_driver = {
+	"spi",
+	lpc_spi_methods,
+	sizeof(struct lpc_spi_softc),
+};
+
+DRIVER_MODULE(lpcspi, simplebus, lpc_spi_driver, lpc_spi_devclass, 0, 0);


Property changes on: trunk/sys/arm/lpc/lpc_spi.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/lpc/lpc_timer.c
===================================================================
--- trunk/sys/arm/lpc/lpc_timer.c	                        (rev 0)
+++ trunk/sys/arm/lpc/lpc_timer.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,309 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2011 Jakub Wojciech Klama <jceel at FreeBSD.org>
+ * 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: stable/10/sys/arm/lpc/lpc_timer.c 266207 2014-05-16 02:21:51Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/timetc.h>
+#include <sys/timeet.h>
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <arm/lpc/lpcreg.h>
+#include <arm/lpc/lpcvar.h>
+
+struct lpc_timer_softc {
+	device_t		lt_dev;
+	struct eventtimer	lt_et;
+	struct resource	*	lt_res[5];
+	bus_space_tag_t		lt_bst0;
+	bus_space_handle_t	lt_bsh0;
+	bus_space_tag_t		lt_bst1;
+	bus_space_handle_t	lt_bsh1;
+	int			lt_oneshot;
+	uint32_t		lt_period;
+};
+
+static struct resource_spec lpc_timer_spec[] = {
+	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
+	{ SYS_RES_MEMORY,	1,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		0,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		1,	RF_ACTIVE },
+	{ -1, 0 }
+};
+
+static struct lpc_timer_softc *timer_softc = NULL;
+static int lpc_timer_initialized = 0;
+static int lpc_timer_probe(device_t);
+static int lpc_timer_attach(device_t);
+static int lpc_timer_start(struct eventtimer *,
+    sbintime_t first, sbintime_t period);
+static int lpc_timer_stop(struct eventtimer *et);
+static unsigned lpc_get_timecount(struct timecounter *);
+static int lpc_hardclock(void *);
+
+#define	timer0_read_4(sc, reg)			\
+    bus_space_read_4(sc->lt_bst0, sc->lt_bsh0, reg)
+#define	timer0_write_4(sc, reg, val)		\
+    bus_space_write_4(sc->lt_bst0, sc->lt_bsh0, reg, val)
+#define	timer0_clear(sc)			\
+    do {					\
+	    timer0_write_4(sc, LPC_TIMER_TC, 0);	\
+	    timer0_write_4(sc, LPC_TIMER_PR, 0);	\
+	    timer0_write_4(sc, LPC_TIMER_PC, 0);	\
+    } while(0)
+
+#define	timer1_read_4(sc, reg)			\
+    bus_space_read_4(sc->lt_bst1, sc->lt_bsh1, reg)
+#define	timer1_write_4(sc, reg, val)		\
+    bus_space_write_4(sc->lt_bst1, sc->lt_bsh1, reg, val)
+#define	timer1_clear(sc)			\
+    do {					\
+	    timer1_write_4(sc, LPC_TIMER_TC, 0);	\
+	    timer1_write_4(sc, LPC_TIMER_PR, 0);	\
+	    timer1_write_4(sc, LPC_TIMER_PC, 0);	\
+    } while(0)
+
+static struct timecounter lpc_timecounter = {
+	.tc_get_timecount = lpc_get_timecount,
+	.tc_name = "LPC32x0 Timer1",
+	.tc_frequency = 0, /* will be filled later */
+	.tc_counter_mask = ~0u,
+	.tc_quality = 1000,
+};
+
+static int
+lpc_timer_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "lpc,timer"))
+		return (ENXIO);
+
+	device_set_desc(dev, "LPC32x0 timer");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+lpc_timer_attach(device_t dev)
+{
+	void *intrcookie;
+	struct lpc_timer_softc *sc = device_get_softc(dev);
+	phandle_t node;
+	uint32_t freq;
+
+	if (timer_softc)
+		return (ENXIO);
+
+	timer_softc = sc;
+
+	if (bus_alloc_resources(dev, lpc_timer_spec, sc->lt_res)) {
+		device_printf(dev, "could not allocate resources\n");
+		return (ENXIO);
+	}
+
+	sc->lt_bst0 = rman_get_bustag(sc->lt_res[0]);
+	sc->lt_bsh0 = rman_get_bushandle(sc->lt_res[0]);
+	sc->lt_bst1 = rman_get_bustag(sc->lt_res[1]);
+	sc->lt_bsh1 = rman_get_bushandle(sc->lt_res[1]);
+
+	if (bus_setup_intr(dev, sc->lt_res[2], INTR_TYPE_CLK,
+	    lpc_hardclock, NULL, sc, &intrcookie)) {
+		device_printf(dev, "could not setup interrupt handler\n");
+		bus_release_resources(dev, lpc_timer_spec, sc->lt_res);
+		return (ENXIO);
+	}
+
+	/* Enable timer clock */
+	lpc_pwr_write(dev, LPC_CLKPWR_TIMCLK_CTRL1,
+	    LPC_CLKPWR_TIMCLK_CTRL1_TIMER0 |
+	    LPC_CLKPWR_TIMCLK_CTRL1_TIMER1);
+
+	/* Get PERIPH_CLK encoded in parent bus 'bus-frequency' property */
+	node = ofw_bus_get_node(dev);
+	if (OF_getprop(OF_parent(node), "bus-frequency", &freq,
+	    sizeof(pcell_t)) <= 0) {
+		bus_release_resources(dev, lpc_timer_spec, sc->lt_res);
+		bus_teardown_intr(dev, sc->lt_res[2], intrcookie);
+		device_printf(dev, "could not obtain base clock frequency\n");
+		return (ENXIO);
+	}
+
+	freq = fdt32_to_cpu(freq);
+
+	/* Set desired frequency in event timer and timecounter */
+	sc->lt_et.et_frequency = (uint64_t)freq;
+	lpc_timecounter.tc_frequency = (uint64_t)freq;	
+
+	sc->lt_et.et_name = "LPC32x0 Timer0";
+	sc->lt_et.et_flags = ET_FLAGS_PERIODIC | ET_FLAGS_ONESHOT;
+	sc->lt_et.et_quality = 1000;
+	sc->lt_et.et_min_period = (0x00000002LLU << 32) / sc->lt_et.et_frequency;
+	sc->lt_et.et_max_period = (0xfffffffeLLU << 32) / sc->lt_et.et_frequency;
+	sc->lt_et.et_start = lpc_timer_start;
+	sc->lt_et.et_stop = lpc_timer_stop;
+	sc->lt_et.et_priv = sc;
+
+	et_register(&sc->lt_et);
+	tc_init(&lpc_timecounter);
+
+	/* Reset and enable timecounter */
+	timer1_write_4(sc, LPC_TIMER_TCR, LPC_TIMER_TCR_RESET);
+	timer1_write_4(sc, LPC_TIMER_TCR, 0);
+	timer1_clear(sc);
+	timer1_write_4(sc, LPC_TIMER_TCR, LPC_TIMER_TCR_ENABLE);
+
+	/* DELAY() now can work properly */
+	lpc_timer_initialized = 1;
+
+	return (0);
+}
+
+static int
+lpc_timer_start(struct eventtimer *et, sbintime_t first, sbintime_t period)
+{
+	struct lpc_timer_softc *sc = (struct lpc_timer_softc *)et->et_priv;
+	uint32_t ticks;
+
+	if (period == 0) {
+		sc->lt_oneshot = 1;
+		sc->lt_period = 0;
+	} else {
+		sc->lt_oneshot = 0;
+		sc->lt_period = ((uint32_t)et->et_frequency * period) >> 32;
+	}
+
+	if (first == 0)
+		ticks = sc->lt_period;
+	else
+		ticks = ((uint32_t)et->et_frequency * first) >> 32;
+
+	/* Reset timer */
+	timer0_write_4(sc, LPC_TIMER_TCR, LPC_TIMER_TCR_RESET);
+	timer0_write_4(sc, LPC_TIMER_TCR, 0);
+	
+	/* Start timer */
+	timer0_clear(sc);
+	timer0_write_4(sc, LPC_TIMER_MR0, ticks);
+	timer0_write_4(sc, LPC_TIMER_MCR, LPC_TIMER_MCR_MR0I | LPC_TIMER_MCR_MR0S);
+	timer0_write_4(sc, LPC_TIMER_TCR, LPC_TIMER_TCR_ENABLE);
+	return (0);
+}
+
+static int
+lpc_timer_stop(struct eventtimer *et)
+{
+	struct lpc_timer_softc *sc = (struct lpc_timer_softc *)et->et_priv;
+
+	timer0_write_4(sc, LPC_TIMER_TCR, 0);
+	return (0);
+}
+
+static device_method_t lpc_timer_methods[] = {
+	DEVMETHOD(device_probe,		lpc_timer_probe),
+	DEVMETHOD(device_attach,	lpc_timer_attach),
+	{ 0, 0 }
+};
+
+static driver_t lpc_timer_driver = {
+	"timer",
+	lpc_timer_methods,
+	sizeof(struct lpc_timer_softc),
+};
+
+static devclass_t lpc_timer_devclass;
+
+DRIVER_MODULE(timer, simplebus, lpc_timer_driver, lpc_timer_devclass, 0, 0);
+
+static int
+lpc_hardclock(void *arg)
+{
+	struct lpc_timer_softc *sc = (struct lpc_timer_softc *)arg;
+
+	/* Reset pending interrupt */
+	timer0_write_4(sc, LPC_TIMER_IR, 0xffffffff);
+
+	/* Start timer again */
+	if (!sc->lt_oneshot) {
+		timer0_clear(sc);
+		timer0_write_4(sc, LPC_TIMER_MR0, sc->lt_period);
+		timer0_write_4(sc, LPC_TIMER_TCR, LPC_TIMER_TCR_ENABLE);
+	}
+
+	if (sc->lt_et.et_active)
+		sc->lt_et.et_event_cb(&sc->lt_et, sc->lt_et.et_arg);
+
+	return (FILTER_HANDLED);
+}
+
+static unsigned
+lpc_get_timecount(struct timecounter *tc)
+{
+	return timer1_read_4(timer_softc, LPC_TIMER_TC);
+}
+
+void
+DELAY(int usec)
+{
+	uint32_t counter;
+	uint32_t first, last;
+	int val = (lpc_timecounter.tc_frequency / 1000000 + 1) * usec;
+
+	/* Timer is not initialized yet */
+	if (!lpc_timer_initialized) {
+		for (; usec > 0; usec--)
+			for (counter = 100; counter > 0; counter--)
+				;
+		return;
+	}
+
+	first = lpc_get_timecount(&lpc_timecounter);
+	while (val > 0) {
+		last = lpc_get_timecount(&lpc_timecounter);
+		if (last < first) {
+			/* Timer rolled over */
+			last = first;
+		}
+		
+		val -= (last - first);
+		first = last;
+	}
+}


Property changes on: trunk/sys/arm/lpc/lpc_timer.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/lpc/lpcreg.h
===================================================================
--- trunk/sys/arm/lpc/lpcreg.h	                        (rev 0)
+++ trunk/sys/arm/lpc/lpcreg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,666 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2011 Jakub Wojciech Klama <jceel at FreeBSD.org>
+ * 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: stable/10/sys/arm/lpc/lpcreg.h 266084 2014-05-14 19:18:58Z ian $
+ */
+
+#ifndef	_ARM_LPC_LPCREG_H
+#define	_ARM_LPC_LPCREG_H
+
+#define	LPC_DEV_PHYS_BASE		0x40000000
+#define	LPC_DEV_P5_PHYS_BASE		0x20000000
+#define	LPC_DEV_P6_PHYS_BASE		0x30000000
+#define	LPC_DEV_SIZE			0x10000000
+
+/*
+ * Interrupt controller (from UM10326: LPC32x0 User manual, page 87)
+
+ */
+#define	LPC_INTC_MIC_ER			0x0000
+#define	LPC_INTC_MIC_RSR		0x0004
+#define	LPC_INTC_MIC_SR			0x0008
+#define	LPC_INTC_MIC_APR		0x000c
+#define	LPC_INTC_MIC_ATR		0x0010
+#define	LPC_INTC_MIC_ITR		0x0014
+#define	LPC_INTC_SIC1_ER		0x4000
+#define	LPC_INTC_SIC1_RSR		0x4004
+#define	LPC_INTC_SIC1_SR		0x4008
+#define	LPC_INTC_SIC1_APR		0x400c
+#define	LPC_INTC_SIC1_ATR		0x4010
+#define	LPC_INTC_SIC1_ITR		0x4014
+#define	LPC_INTC_SIC2_ER		0x8000
+#define	LPC_INTC_SIC2_RSR		0x8004
+#define	LPC_INTC_SIC2_SR		0x8008
+#define	LPC_INTC_SIC2_APR		0x800c
+#define	LPC_INTC_SIC2_ATR		0x8010
+#define	LPC_INTC_SIC2_ITR		0x8014
+
+
+/*
+ * Timer 0|1|2|3|4|5. (from UM10326: LPC32x0 User manual, page 540)
+ */
+#define	LPC_TIMER_IR			0x00
+#define	LPC_TIMER_TCR			0x04
+#define	LPC_TIMER_TCR_ENABLE		(1 << 0)
+#define	LPC_TIMER_TCR_RESET		(1 << 1)
+#define	LPC_TIMER_TC			0x08
+#define	LPC_TIMER_PR			0x0c
+#define	LPC_TIMER_PC			0x10
+#define	LPC_TIMER_MCR			0x14
+#define	LPC_TIMER_MCR_MR0I		(1 << 0)
+#define	LPC_TIMER_MCR_MR0R		(1 << 1)
+#define	LPC_TIMER_MCR_MR0S		(1 << 2)
+#define	LPC_TIMER_MCR_MR1I		(1 << 3)
+#define	LPC_TIMER_MCR_MR1R		(1 << 4)
+#define	LPC_TIMER_MCR_MR1S		(1 << 5)
+#define	LPC_TIMER_MCR_MR2I		(1 << 6)
+#define	LPC_TIMER_MCR_MR2R		(1 << 7)
+#define	LPC_TIMER_MCR_MR2S		(1 << 8)
+#define	LPC_TIMER_MCR_MR3I		(1 << 9)
+#define	LPC_TIMER_MCR_MR3R		(1 << 10)
+#define	LPC_TIMER_MCR_MR3S		(1 << 11)
+#define	LPC_TIMER_MR0			0x18
+#define	LPC_TIMER_CTCR			0x70
+
+/*
+ * Watchdog timer. (from UM10326: LPC32x0 User manual, page 572)
+ */
+#define	LPC_WDTIM_PHYS_BASE		(LPC_DEV_PHYS_BASE + 0x3c000)
+#define	LPC_WDTIM_INT			0x00
+#define	LPC_WDTIM_CTRL			0x04
+#define	LPC_WDTIM_COUNTER		0x08
+#define	LPC_WDTIM_MCTRL			0x0c
+#define	LPC_WDTIM_MATCH0		0x10
+#define	LPC_WDTIM_EMR			0x14
+#define	LPC_WDTIM_PULSE			0x18
+#define	LPC_WDTIM_RES			0x1c
+#define	LPC_WDTIM_SIZE			0x20
+
+/*
+ * Clocking and power control. (from UM10326: LPC32x0 User manual, page 58)
+ */
+#define	LPC_CLKPWR_PHYS_BASE		(LPC_DEV_PHYS_BASE + 0x4000)
+#define	LPC_CLKPWR_PWR_CTRL		0x44
+#define	LPC_CLKPWR_OSC_CTRL		0x4c
+#define	LPC_CLKPWR_SYSCLK_CTRL		0x50
+#define	LPC_CLKPWR_PLL397_CTRL		0x48
+#define	LPC_CLKPWR_HCLKPLL_CTRL		0x58
+#define	LPC_CLKPWR_HCLKDIV_CTRL		0x40
+#define	LPC_CLKPWR_TEST_CTRL		0xa4
+#define	LPC_CLKPWR_AUTOCLK_CTRL		0xec
+#define	LPC_CLKPWR_START_ER_PIN		0x30
+#define	LPC_CLKPWR_START_ER_INT		0x20
+#define	LPC_CLKPWR_P0_INTR_ER		0x18
+#define	LPC_CLKPWR_START_SR_PIN		0x38
+#define	LPC_CLKPWR_START_SR_INT		0x28
+#define	LPC_CLKPWR_START_RSR_PIN	0x34
+#define	LPC_CLKPWR_START_RSR_INT	0x24
+#define	LPC_CLKPWR_START_APR_PIN	0x3c
+#define	LPC_CLKPWR_START_APR_INT	0x2c
+#define	LPC_CLKPWR_USB_CTRL		0x64
+#define	LPC_CLKPWR_USB_CTRL_SLAVE_HCLK	(1 << 24)
+#define	LPC_CLKPWR_USB_CTRL_I2C_EN	(1 << 23)
+#define	LPC_CLKPWR_USB_CTRL_DEV_NEED_CLK_EN	(1 << 22)
+#define	LPC_CLKPWR_USB_CTRL_HOST_NEED_CLK_EN	(1 << 21)
+#define	LPC_CLKPWR_USB_CTRL_BUSKEEPER	(1 << 19)
+#define	LPC_CLKPWR_USB_CTRL_CLK_EN2	(1 << 18)
+#define	LPC_CLKPWR_USB_CTRL_CLK_EN1	(1 << 17)
+#define	LPC_CLKPWR_USB_CTRL_PLL_PDOWN	(1 << 16)
+#define	LPC_CLKPWR_USB_CTRL_BYPASS	(1 << 15)
+#define	LPC_CLKPWR_USB_CTRL_DIRECT_OUT	(1 << 14)
+#define	LPC_CLKPWR_USB_CTRL_FEEDBACK	(1 << 13)
+#define	LPC_CLKPWR_USB_CTRL_POSTDIV(_x)	((_x & 0x3) << 11)
+#define	LPC_CLKPWR_USB_CTRL_PREDIV(_x)	((_x & 0x3) << 9)
+#define	LPC_CLKPWR_USB_CTRL_FDBKDIV(_x)	(((_x-1) & 0xff) << 1)
+#define	LPC_CLKPWR_USB_CTRL_PLL_LOCK	(1 << 0)
+#define	LPC_CLKPWR_USBDIV_CTRL		0x1c
+#define	LPC_CLKPWR_MS_CTRL		0x80
+#define	LPC_CLKPWR_MS_CTRL_DISABLE_SD	(1 << 10)
+#define	LPC_CLKPWR_MS_CTRL_CLOCK_EN	(1 << 9)
+#define	LPC_CLKPWR_MS_CTRL_MSSDIO23_PAD	(1 << 8)
+#define	LPC_CLKPWR_MS_CTRL_MSSDIO1_PAD	(1 << 7)
+#define	LPC_CLKPWR_MS_CTRL_MSSDIO0_PAD	(1 << 6)
+#define	LPC_CLKPWR_MS_CTRL_SD_CLOCK	(1 << 5)
+#define	LPC_CLKPWR_MS_CTRL_CLKDIV_MASK	0xf
+#define	LPC_CLKPWR_DMACLK_CTRL		0xe8
+#define	LPC_CLKPWR_DMACLK_CTRL_EN	(1 << 0)
+#define	LPC_CLKPWR_FLASHCLK_CTRL	0xc8
+#define	LPC_CLKPWR_MACCLK_CTRL		0x90
+#define	LPC_CLKPWR_MACCLK_CTRL_REG	(1 << 0)
+#define	LPC_CLKPWR_MACCLK_CTRL_SLAVE	(1 << 1)
+#define	LPC_CLKPWR_MACCLK_CTRL_MASTER	(1 << 2)
+#define	LPC_CLKPWR_MACCLK_CTRL_HDWINF(_n) ((_n & 0x3) << 3)
+#define	LPC_CLKPWR_LCDCLK_CTRL		0x54
+#define	LPC_CLKPWR_LCDCLK_CTRL_DISPTYPE	(1 << 8)
+#define	LPC_CLKPWR_LCDCLK_CTRL_MODE(_n)	((_n & 0x3) << 6)
+#define	LPC_CLKPWR_LCDCLK_CTRL_MODE_12	0x0
+#define	LPC_CLKPWR_LCDCLK_CTRL_MODE_15	0x1
+#define	LPC_CLKPWR_LCDCLK_CTRL_MODE_16	0x2
+#define	LPC_CLKPWR_LCDCLK_CTRL_MODE_24	0x3
+#define	LPC_CLKPWR_LCDCLK_CTRL_HCLKEN	(1 << 5)
+#define	LPC_CLKPWR_LCDCLK_CTRL_CLKDIV(_n) ((_n) & 0x1f)
+#define	LPC_CLKPWR_I2S_CTRL		0x7c
+#define	LPC_CLKPWR_SSP_CTRL		0x78
+#define	LPC_CLKPWR_SSP_CTRL_SSP1RXDMA	(1 << 5)
+#define	LPC_CLKPWR_SSP_CTRL_SSP1TXDMA	(1 << 4)
+#define	LPC_CLKPWR_SSP_CTRL_SSP0RXDMA	(1 << 3)
+#define	LPC_CLKPWR_SSP_CTRL_SSP0TXDMA	(1 << 2)
+#define	LPC_CLKPWR_SSP_CTRL_SSP1EN	(1 << 1)
+#define	LPC_CLKPWR_SSP_CTRL_SSP0EN	(1 << 0)
+#define	LPC_CLKPWR_SPI_CTRL		0xc4
+#define	LPC_CLKPWR_I2CCLK_CTRL		0xac
+#define	LPC_CLKPWR_TIMCLK_CTRL1		0xc0
+#define	LPC_CLKPWR_TIMCLK_CTRL1_TIMER4	(1 << 0)
+#define	LPC_CLKPWR_TIMCLK_CTRL1_TIMER5	(1 << 1)
+#define	LPC_CLKPWR_TIMCLK_CTRL1_TIMER0	(1 << 2)
+#define	LPC_CLKPWR_TIMCLK_CTRL1_TIMER1	(1 << 3)
+#define	LPC_CLKPWR_TIMCLK_CTRL1_TIMER2	(1 << 4)
+#define	LPC_CLKPWR_TIMCLK_CTRL1_TIMER3	(1 << 5)
+#define	LPC_CLKPWR_TIMCLK_CTRL1_MOTORCTL	(1 << 6)
+#define	LPC_CLKPWR_TIMCLK_CTRL		0xbc
+#define	LPC_CLKPWR_TIMCLK_CTRL_WATCHDOG	(1 << 0)
+#define	LPC_CLKPWR_TIMCLK_CTRL_HSTIMER	(1 << 1)
+#define	LPC_CLKPWR_ADCLK_CTRL		0xb4
+#define	LPC_CLKPWR_ADCLK_CTRL1		0x60
+#define	LPC_CLKPWR_KEYCLK_CTRL		0xb0
+#define	LPC_CLKPWR_PWMCLK_CTRL		0xb8
+#define	LPC_CLKPWR_UARTCLK_CTRL		0xe4
+#define	LPC_CLKPWR_POS0_IRAM_CTRL	0x110
+#define	LPC_CLKPWR_POS1_IRAM_CTRL	0x114
+#define	LPC_CLKPWR_SIZE			0x118
+
+/* Additional UART registers in CLKPWR address space. */
+#define	LPC_CLKPWR_UART_U3CLK		0xd0
+#define	LPC_CLKPWR_UART_U4CLK		0xd4
+#define	LPC_CLKPWR_UART_U5CLK		0xd8
+#define	LPC_CLKPWR_UART_U6CLK		0xdc
+#define	LPC_CLKPWR_UART_UCLK_HCLK	(1 << 16)
+#define	LPC_CLKPWR_UART_UCLK_X(_n)	(((_n) & 0xff) << 8)
+#define	LPC_CLKPWR_UART_UCLK_Y(_n)	((_n) & 0xff)
+#define	LPC_CLKPWR_UART_IRDACLK		0xe0
+
+/* Additional UART registers */
+#define	LPC_UART_BASE			0x80000
+#define	LPC_UART_CONTROL_BASE		0x54000
+#define	LPC_UART5_BASE			0x90000
+#define	LPC_UART_CTRL			0x00
+#define	LPC_UART_CLKMODE		0x04
+#define	LPC_UART_CLKMODE_UART3(_n)	(((_n) & 0x3) << 4)
+#define	LPC_UART_CLKMODE_UART4(_n)	(((_n) & 0x3) << 6)
+#define	LPC_UART_CLKMODE_UART5(_n)	(((_n) & 0x3) << 8)
+#define	LPC_UART_CLKMODE_UART6(_n)	(((_n) & 0x3) << 10)
+#define	LPC_UART_LOOP			0x08
+#define	LPC_UART_CONTROL_SIZE		0x0c
+#define	LPC_UART_FIFOSIZE		64
+
+/*
+ * Real time clock. (from UM10326: LPC32x0 User manual, page 566)
+ */
+#define	LPC_RTC_UCOUNT			0x00
+#define	LPC_RTC_DCOUNT			0x04
+#define	LPC_RTC_MATCH0			0x08
+#define	LPC_RTC_MATCH1			0x0c
+#define	LPC_RTC_CTRL			0x10
+#define	LPC_RTC_CTRL_ONSW		(1 << 7)
+#define	LPC_RTC_CTRL_DISABLE		(1 << 6)
+#define	LPC_RTC_CTRL_RTCRESET		(1 << 4)
+#define	LPC_RTC_CTRL_MATCH0ONSW		(1 << 3)
+#define	LPC_RTC_CTRL_MATCH1ONSW		(1 << 2)
+#define	LPC_RTC_CTRL_MATCH1INTR		(1 << 1)
+#define	LPC_RTC_CTRL_MATCH0INTR		(1 << 0)
+#define	LPC_RTC_INTSTAT			0x14
+#define	LPC_RTC_KEY			0x18
+#define	LPC_RTC_SRAM_BEGIN		0x80
+#define LPC_RTC_SRAM_END		0xff
+
+/*
+ * MMC/SD controller. (from UM10326: LPC32x0 User manual, page 436)
+ */
+#define	LPC_SD_PHYS_BASE		(LPC_DEV_P5_PHYS_BASE + 0x98000)
+#define	LPC_SD_CLK			(13 * 1000 * 1000)	// 13Mhz
+#define	LPC_SD_POWER			0x00
+#define	LPC_SD_POWER_OPENDRAIN		(1 << 6)
+#define	LPC_SD_POWER_CTRL_OFF		0x00
+#define	LPC_SD_POWER_CTRL_UP		0x02
+#define	LPC_SD_POWER_CTRL_ON		0x03
+#define	LPC_SD_CLOCK			0x04
+#define	LPC_SD_CLOCK_WIDEBUS		(1 << 11)
+#define	LPC_SD_CLOCK_BYPASS		(1 << 10)
+#define	LPC_SD_CLOCK_PWRSAVE		(1 << 9)
+#define	LPC_SD_CLOCK_ENABLE		(1 << 8)
+#define	LPC_SD_CLOCK_CLKDIVMASK		0xff
+#define	LPC_SD_ARGUMENT			0x08
+#define	LPC_SD_COMMAND			0x0c
+#define	LPC_SD_COMMAND_ENABLE		(1 << 10)
+#define	LPC_SD_COMMAND_PENDING		(1 << 9)
+#define	LPC_SD_COMMAND_INTERRUPT	(1 << 8)
+#define	LPC_SD_COMMAND_LONGRSP		(1 << 7)
+#define	LPC_SD_COMMAND_RESPONSE		(1 << 6)
+#define	LPC_SD_COMMAND_CMDINDEXMASK	0x3f
+#define	LPC_SD_RESPCMD			0x10
+#define	LPC_SD_RESP0			0x14
+#define	LPC_SD_RESP1			0x18
+#define	LPC_SD_RESP2			0x1c
+#define	LPC_SD_RESP3			0x20
+#define	LPC_SD_DATATIMER		0x24
+#define	LPC_SD_DATALENGTH		0x28
+#define	LPC_SD_DATACTRL			0x2c
+#define	LPC_SD_DATACTRL_BLOCKSIZESHIFT	4
+#define	LPC_SD_DATACTRL_BLOCKSIZEMASK	0xf
+#define	LPC_SD_DATACTRL_DMAENABLE	(1 << 3)
+#define	LPC_SD_DATACTRL_MODE		(1 << 2)
+#define	LPC_SD_DATACTRL_WRITE		(0 << 1)
+#define	LPC_SD_DATACTRL_READ		(1 << 1)
+#define	LPC_SD_DATACTRL_ENABLE		(1 << 0)
+#define	LPC_SD_DATACNT			0x30
+#define	LPC_SD_STATUS			0x34
+#define	LPC_SD_STATUS_RXDATAAVLBL	(1 << 21)
+#define	LPC_SD_STATUS_TXDATAAVLBL	(1 << 20)
+#define	LPC_SD_STATUS_RXFIFOEMPTY	(1 << 19)
+#define	LPC_SD_STATUS_TXFIFOEMPTY	(1 << 18)
+#define	LPC_SD_STATUS_RXFIFOFULL	(1 << 17)
+#define	LPC_SD_STATUS_TXFIFOFULL	(1 << 16)
+#define	LPC_SD_STATUS_RXFIFOHALFFULL	(1 << 15)
+#define	LPC_SD_STATUS_TXFIFOHALFEMPTY	(1 << 14)
+#define	LPC_SD_STATUS_RXACTIVE		(1 << 13)
+#define	LPC_SD_STATUS_TXACTIVE		(1 << 12)
+#define	LPC_SD_STATUS_CMDACTIVE		(1 << 11)
+#define	LPC_SD_STATUS_DATABLOCKEND	(1 << 10)
+#define	LPC_SD_STATUS_STARTBITERR	(1 << 9)
+#define	LPC_SD_STATUS_DATAEND		(1 << 8)
+#define	LPC_SD_STATUS_CMDSENT		(1 << 7)
+#define	LPC_SD_STATUS_CMDRESPEND	(1 << 6)
+#define	LPC_SD_STATUS_RXOVERRUN		(1 << 5)
+#define	LPC_SD_STATUS_TXUNDERRUN	(1 << 4)
+#define	LPC_SD_STATUS_DATATIMEOUT	(1 << 3)
+#define	LPC_SD_STATUS_CMDTIMEOUT	(1 << 2)
+#define	LPC_SD_STATUS_DATACRCFAIL	(1 << 1)
+#define	LPC_SD_STATUS_CMDCRCFAIL	(1 << 0)
+#define	LPC_SD_CLEAR			0x38
+#define	LPC_SD_MASK0			0x03c
+#define	LPC_SD_MASK1			0x40
+#define	LPC_SD_FIFOCNT			0x48
+#define	LPC_SD_FIFO			0x80
+
+/*
+ * USB OTG controller (from UM10326: LPC32x0 User manual, page 410)
+ */
+#define	LPC_OTG_INT_STATUS		0x100
+#define	LPC_OTG_INT_ENABLE		0x104
+#define	LPC_OTG_INT_SET			0x108
+#define	LPC_OTG_INT_CLEAR		0x10c
+#define	LPC_OTG_STATUS			0x110
+#define	LPC_OTG_STATUS_ATOB_HNP_TRACK	(1 << 9)
+#define	LPC_OTG_STATUS_BTOA_HNP_TACK	(1 << 8)
+#define	LPC_OTG_STATUS_TRANSP_I2C_EN	(1 << 7)
+#define	LPC_OTG_STATUS_TIMER_RESET	(1 << 6)
+#define	LPC_OTG_STATUS_TIMER_EN		(1 << 5)
+#define	LPC_OTG_STATUS_TIMER_MODE	(1 << 4)
+#define	LPC_OTG_STATUS_TIMER_SCALE	(1 << 2)
+#define	LPC_OTG_STATUS_HOST_EN		(1 << 0)
+#define	LPC_OTG_TIMER			0x114
+#define	LPC_OTG_I2C_TXRX		0x300
+#define	LPC_OTG_I2C_STATUS		0x304
+#define	LPC_OTG_I2C_STATUS_TFE		(1 << 11)
+#define	LPC_OTG_I2C_STATUS_TFF		(1 << 10)
+#define	LPC_OTG_I2C_STATUS_RFE		(1 << 9)
+#define	LPC_OTG_I2C_STATUS_RFF		(1 << 8)
+#define	LPC_OTG_I2C_STATUS_SDA		(1 << 7)
+#define	LPC_OTG_I2C_STATUS_SCL		(1 << 6)
+#define	LPC_OTG_I2C_STATUS_ACTIVE	(1 << 5)
+#define	LPC_OTG_I2C_STATUS_DRSI		(1 << 4)
+#define	LPC_OTG_I2C_STATUS_DRMI		(1 << 3)
+#define	LPC_OTG_I2C_STATUS_NAI		(1 << 2)
+#define	LPC_OTG_I2C_STATUS_AFI		(1 << 1)
+#define	LPC_OTG_I2C_STATUS_TDI		(1 << 0)
+#define	LPC_OTG_I2C_CTRL		0x308
+#define	LPC_OTG_I2C_CTRL_SRST		(1 << 8)
+#define	LPC_OTG_I2C_CTRL_TFFIE		(1 << 7)
+#define	LPC_OTG_I2C_CTRL_RFDAIE		(1 << 6)
+#define	LPC_OTG_I2C_CTRL_RFFIE		(1 << 5)
+#define	LPC_OTG_I2C_CTRL_DRSIE		(1 << 4)
+#define	LPC_OTG_I2C_CTRL_DRMIE		(1 << 3)
+#define	LPC_OTG_I2C_CTRL_NAIE		(1 << 2)
+#define	LPC_OTG_I2C_CTRL_AFIE		(1 << 1)
+#define	LPC_OTG_I2C_CTRL_TDIE		(1 << 0)
+#define	LPC_OTG_I2C_CLKHI		0x30c
+#define	LPC_OTG_I2C_CLKLO		0x310
+#define	LPC_OTG_CLOCK_CTRL		0xff4
+#define	LPC_OTG_CLOCK_CTRL_AHB_EN	(1 << 4)
+#define	LPC_OTG_CLOCK_CTRL_OTG_EN	(1 << 3)
+#define	LPC_OTG_CLOCK_CTRL_I2C_EN	(1 << 2)
+#define	LPC_OTG_CLOCK_CTRL_DEV_EN	(1 << 1)
+#define	LPC_OTG_CLOCK_CTRL_HOST_EN	(1 << 0)
+#define	LPC_OTG_CLOCK_STATUS		0xff8
+
+/*
+ * ISP3101 USB transceiver registers
+ */
+#define	LPC_ISP3101_I2C_ADDR		0x2d
+#define	LPC_ISP3101_MODE_CONTROL_1	0x04
+#define	LPC_ISP3101_MC1_SPEED_REG	(1 << 0)
+#define	LPC_ISP3101_MC1_SUSPEND_REG	(1 << 1)
+#define	LPC_ISP3101_MC1_DAT_SE0		(1 << 2)
+#define	LPC_ISP3101_MC1_TRANSPARENT	(1 << 3)
+#define	LPC_ISP3101_MC1_BDIS_ACON_EN	(1 << 4)
+#define	LPC_ISP3101_MC1_OE_INT_EN	(1 << 5)
+#define	LPC_ISP3101_MC1_UART_EN		(1 << 6)
+#define	LPC_ISP3101_MODE_CONTROL_2	0x12
+#define	LPC_ISP3101_MC2_GLOBAL_PWR_DN	(1 << 0)
+#define	LPC_ISP3101_MC2_SPD_SUSP_CTRL	(1 << 1)
+#define	LPC_ISP3101_MC2_BI_DI		(1 << 2)
+#define	LPC_ISP3101_MC2_TRANSP_BDIR0	(1 << 3)
+#define	LPC_ISP3101_MC2_TRANSP_BDIR1	(1 << 4)
+#define	LPC_ISP3101_MC2_AUDIO_EN	(1 << 5)
+#define	LPC_ISP3101_MC2_PSW_EN		(1 << 6)
+#define	LPC_ISP3101_MC2_EN2V7		(1 << 7)
+#define	LPC_ISP3101_OTG_CONTROL_1	0x06
+#define	LPC_ISP3101_OTG1_DP_PULLUP	(1 << 0)
+#define	LPC_ISP3101_OTG1_DM_PULLUP	(1 << 1)
+#define	LPC_ISP3101_OTG1_DP_PULLDOWN	(1 << 2)
+#define	LPC_ISP3101_OTG1_DM_PULLDOWN	(1 << 3)
+#define	LPC_ISP3101_OTG1_ID_PULLDOWN	(1 << 4)
+#define	LPC_ISP3101_OTG1_VBUS_DRV	(1 << 5)
+#define	LPC_ISP3101_OTG1_VBUS_DISCHRG	(1 << 6)
+#define	LPC_ISP3101_OTG1_VBUS_CHRG	(1 << 7)
+#define	LPC_ISP3101_OTG_CONTROL_2	0x10
+#define	LPC_ISP3101_OTG_INTR_LATCH	0x0a
+#define	LPC_ISP3101_OTG_INTR_FALLING	0x0c
+#define	LPC_ISP3101_OTG_INTR_RISING	0x0e
+#define	LPC_ISP3101_REG_CLEAR_ADDR	0x01
+
+/*
+ * LCD Controller (from UM10326: LPC32x0 User manual, page 229)
+ */
+#define	LPC_LCD_TIMH			0x00
+#define	LPC_LCD_TIMH_HBP(_n)		(((_n) & 0xff) << 24)
+#define	LPC_LCD_TIMH_HFP(_n)		(((_n) & 0xff) << 16)
+#define	LPC_LCD_TIMH_HSW(_n)		(((_n) & 0xff) << 8)
+#define	LPC_LCD_TIMH_PPL(_n)		(((_n) / 16 - 1) << 2)
+#define	LPC_LCD_TIMV			0x04
+#define	LPC_LCD_TIMV_VBP(_n)		(((_n) & 0xff) << 24)
+#define	LPC_LCD_TIMV_VFP(_n)		(((_n) & 0xff) << 16)
+#define	LPC_LCD_TIMV_VSW(_n)		(((_n) & 0x3f) << 10)
+#define	LPC_LCD_TIMV_LPP(_n)		((_n) & 0x1ff)
+#define	LPC_LCD_POL			0x08
+#define	LPC_LCD_POL_PCD_HI		(((_n) & 0x1f) << 27)
+#define	LPC_LCD_POL_BCD			(1 << 26)
+#define	LPC_LCD_POL_CPL(_n)		(((_n) & 0x3ff) << 16)
+#define	LPC_LCD_POL_IOE			(1 << 14)
+#define	LPC_LCD_POL_IPC			(1 << 13)
+#define	LPC_LCD_POL_IHS			(1 << 12)
+#define	LPC_LCD_POL_IVS			(1 << 11)
+#define	LPC_LCD_POL_ACB(_n)		((_n & 0x1f) << 6)
+#define	LPC_LCD_POL_CLKSEL		(1 << 5)
+#define	LPC_LCD_POL_PCD_LO(_n)		((_n) & 0x1f)
+#define	LPC_LCD_LE			0x0c
+#define	LPC_LCD_LE_LEE			(1 << 16)
+#define	LPC_LCD_LE_LED			((_n) & 0x7f)
+#define	LPC_LCD_UPBASE			0x10
+#define	LPC_LCD_LPBASE			0x14
+#define	LPC_LCD_CTRL			0x18
+#define	LPC_LCD_CTRL_WATERMARK		(1 << 16)
+#define	LPC_LCD_CTRL_LCDVCOMP(_n)	(((_n) & 0x3) << 12)
+#define	LPC_LCD_CTRL_LCDPWR		(1 << 11)
+#define	LPC_LCD_CTRL_BEPO		(1 << 10)
+#define	LPC_LCD_CTRL_BEBO		(1 << 9)
+#define	LPC_LCD_CTRL_BGR		(1 << 8)
+#define	LPC_LCD_CTRL_LCDDUAL		(1 << 7)
+#define	LPC_LCD_CTRL_LCDMONO8		(1 << 6)
+#define	LPC_LCD_CTRL_LCDTFT		(1 << 5)
+#define	LPC_LCD_CTRL_LCDBW		(1 << 4)
+#define	LPC_LCD_CTRL_LCDBPP(_n)		(((_n) & 0x7) << 1)
+#define	LPC_LCD_CTRL_BPP1		0
+#define	LPC_LCD_CTRL_BPP2		1
+#define	LPC_LCD_CTRL_BPP4		2
+#define	LPC_LCD_CTRL_BPP8		3
+#define	LPC_LCD_CTRL_BPP16		4
+#define	LPC_LCD_CTRL_BPP24		5
+#define	LPC_LCD_CTRL_BPP16_565		6
+#define	LPC_LCD_CTRL_BPP12_444		7
+#define	LPC_LCD_CTRL_LCDEN		(1 << 0)
+#define	LPC_LCD_INTMSK			0x1c
+#define	LPC_LCD_INTRAW			0x20
+#define	LPC_LCD_INTSTAT			0x24
+#define	LPC_LCD_INTCLR			0x28
+#define	LPC_LCD_UPCURR			0x2c
+#define	LPC_LCD_LPCURR			0x30
+#define	LPC_LCD_PAL			0x200
+#define	LPC_LCD_CRSR_IMG		0x800
+#define	LPC_LCD_CRSR_CTRL		0xc00
+#define	LPC_LCD_CRSR_CFG		0xc04
+#define	LPC_LCD_CRSR_PAL0		0xc08
+#define	LPC_LCD_CRSR_PAL1		0xc0c
+#define	LPC_LCD_CRSR_XY			0xc10
+#define	LPC_LCD_CRSR_CLIP		0xc14
+#define	LPC_LCD_CRSR_INTMSK		0xc20
+#define	LPC_LCD_CRSR_INTCLR		0xc24
+#define	LPC_LCD_CRSR_INTRAW		0xc28
+#define	LPC_LCD_CRSR_INTSTAT		0xc2c
+
+/*
+ * SPI interface (from UM10326: LPC32x0 User manual, page 483)
+ */
+#define	LPC_SPI_GLOBAL			0x00
+#define	LPC_SPI_GLOBAL_RST		(1 << 1)
+#define	LPC_SPI_GLOBAL_ENABLE		(1 << 0)
+#define	LPC_SPI_CON			0x04
+#define	LPC_SPI_CON_UNIDIR		(1 << 23)
+#define	LPC_SPI_CON_BHALT		(1 << 22)
+#define	LPC_SPI_CON_BPOL		(1 << 21)
+#define	LPC_SPI_CON_MSB			(1 << 19)
+#define	LPC_SPI_CON_MODE(_n)		((_n & 0x3) << 16)
+#define	LPC_SPI_CON_RXTX		(1 << 15)
+#define	LPC_SPI_CON_THR			(1 << 14)
+#define	LPC_SPI_CON_SHIFT_OFF		(1 << 13)
+#define	LPC_SPI_CON_BITNUM(_n)		((_n & 0xf) << 9)
+#define	LPC_SPI_CON_MS			(1 << 7)
+#define	LPC_SPI_CON_RATE(_n)		(_n & 0x7f)
+#define	LPC_SPI_FRM			0x08
+#define	LPC_SPI_IER			0x0c
+#define	LPC_SPI_IER_INTEOT		(1 << 1)
+#define	LPC_SPI_IER_INTTHR		(1 << 0)
+#define	LPC_SPI_STAT			0x10
+#define	LPC_SPI_STAT_INTCLR		(1 << 8)
+#define	LPC_SPI_STAT_EOT		(1 << 7)
+#define	LPC_SPI_STAT_BUSYLEV		(1 << 6)
+#define	LPC_SPI_STAT_SHIFTACT		(1 << 3)
+#define	LPC_SPI_STAT_BF			(1 << 2)
+#define	LPC_SPI_STAT_THR		(1 << 1)
+#define	LPC_SPI_STAT_BE			(1 << 0)
+#define	LPC_SPI_DAT			0x14
+#define	LPC_SPI_TIM_CTRL		0x400
+#define	LPC_SPI_TIM_COUNT		0x404
+#define	LPC_SPI_TIM_STAT		0x408
+
+/*
+ * SSP interface (from UM10326: LPC32x0 User manual, page 500)
+ */
+#define	LPC_SSP0_BASE			0x4c00
+#define	LPC_SSP1_BASE			0xc000
+#define	LPC_SSP_CR0			0x00
+#define	LPC_SSP_CR0_DSS(_n)		((_n-1) & 0xf)
+#define	LPC_SSP_CR0_TI			(1 << 4)
+#define	LPC_SSP_CR0_MICROWIRE		(1 << 5)
+#define	LPC_SSP_CR0_CPOL		(1 << 6)
+#define	LPC_SSP_CR0_CPHA		(1 << 7)
+#define	LPC_SSP_CR0_SCR(_n)		((_x & & 0xff) << 8)
+#define	LPC_SSP_CR1			0x04
+#define	LPC_SSP_CR1_LBM			(1 << 0)
+#define	LPC_SSP_CR1_SSE			(1 << 1)
+#define	LPC_SSP_CR1_MS			(1 << 2)
+#define	LPC_SSP_CR1_SOD			(1 << 3)
+#define	LPC_SSP_DR			0x08
+#define	LPC_SSP_SR			0x0c
+#define	LPC_SSP_SR_TFE			(1 << 0)
+#define	LPC_SSP_SR_TNF			(1 << 1)
+#define	LPC_SSP_SR_RNE			(1 << 2)
+#define	LPC_SSP_SR_RFF			(1 << 3)
+#define	LPC_SSP_SR_BSY			(1 << 4)
+#define	LPC_SSP_CPSR			0x10
+#define	LPC_SSP_IMSC			0x14
+#define	LPC_SSP_IMSC_RORIM		(1 << 0)
+#define	LPC_SSP_IMSC_RTIM		(1 << 1)
+#define	LPC_SSP_IMSC_RXIM		(1 << 2)
+#define	LPC_SSP_IMSC_TXIM		(1 << 3)
+#define	LPC_SSP_RIS			0x18
+#define	LPC_SSP_RIS_RORRIS		(1 << 0)
+#define	LPC_SSP_RIS_RTRIS		(1 << 1)
+#define	LPC_SSP_RIS_RXRIS		(1 << 2)
+#define	LPC_SSP_RIS_TXRIS		(1 << 3)
+#define	LPC_SSP_MIS			0x1c
+#define	LPC_SSP_ICR			0x20
+#define	LPC_SSP_DMACR			0x24
+
+/*
+ * GPIO (from UM10326: LPC32x0 User manual, page 606)
+ */
+#define	LPC_GPIO_PHYS_BASE		(LPC_DEV_PHYS_BASE + 0x28000)
+#define	LPC_GPIO_P0_COUNT		8
+#define	LPC_GPIO_P1_COUNT		24
+#define	LPC_GPIO_P2_COUNT		13
+#define	LPC_GPIO_P3_COUNT		52
+#define	LPC_GPIO_P0_INP_STATE		0x40
+#define	LPC_GPIO_P0_OUTP_SET		0x44
+#define	LPC_GPIO_P0_OUTP_CLR		0x48
+#define	LPC_GPIO_P0_OUTP_STATE		0x4c
+#define	LPC_GPIO_P0_DIR_SET		0x50
+#define	LPC_GPIO_P0_DIR_CLR		0x54
+#define	LPC_GPIO_P0_DIR_STATE		0x58
+#define	LPC_GPIO_P1_INP_STATE		0x60
+#define	LPC_GPIO_P1_OUTP_SET		0x64
+#define	LPC_GPIO_P1_OUTP_CLR		0x68
+#define	LPC_GPIO_P1_OUTP_STATE		0x6c
+#define	LPC_GPIO_P1_DIR_SET		0x70
+#define	LPC_GPIO_P1_DIR_CLR		0x74
+#define	LPC_GPIO_P1_DIR_STATE		0x78
+#define	LPC_GPIO_P2_INP_STATE		0x1c
+#define	LPC_GPIO_P2_OUTP_SET		0x20
+#define	LPC_GPIO_P2_OUTP_CLR		0x24
+#define	LPC_GPIO_P2_DIR_SET		0x10
+#define	LPC_GPIO_P2_DIR_CLR		0x14
+#define	LPC_GPIO_P2_DIR_STATE		0x14
+#define	LPC_GPIO_P3_INP_STATE		0x00
+#define	LPC_GPIO_P3_OUTP_SET		0x04
+#define	LPC_GPIO_P3_OUTP_CLR		0x08
+#define	LPC_GPIO_P3_OUTP_STATE		0x0c
+#define	LPC_GPIO_SIZE			0x80
+
+/* Aliases for logical pin numbers: */
+#define	LPC_GPIO_GPI_00(_n)		(0 + _n)
+#define	LPC_GPIO_GPI_15(_n)		(10 + _n)
+#define	LPC_GPIO_GPI_25			(19)
+#define	LPC_GPIO_GPI_27(_n)		(20 + _n)
+#define	LPC_GPIO_GPO_00(_n)		(22 + _n)
+#define	LPC_GPIO_GPIO_00(_n)		(46 + _n)
+/* SPI devices chip selects: */
+#define	SSD1289_CS_PIN			LPC_GPIO_GPO_00(4)
+#define	SSD1289_DC_PIN			LPC_GPIO_GPO_00(5)
+#define	ADS7846_CS_PIN			LPC_GPIO_GPO_00(11)
+#define	ADS7846_INTR_PIN		LPC_GPIO_GPIO_00(0)
+
+/*
+ * GPDMA controller (from UM10326: LPC32x0 User manual, page 106)
+ */
+#define	LPC_DMAC_INTSTAT		0x00
+#define	LPC_DMAC_INTTCSTAT		0x04
+#define	LPC_DMAC_INTTCCLEAR		0x08
+#define	LPC_DMAC_INTERRSTAT		0x0c
+#define	LPC_DMAC_INTERRCLEAR		0x10
+#define	LPC_DMAC_RAWINTTCSTAT		0x14
+#define	LPC_DMAC_RAWINTERRSTAT		0x18
+#define	LPC_DMAC_ENABLED_CHANNELS	0x1c
+#define	LPC_DMAC_SOFTBREQ		0x20
+#define	LPC_DMAC_SOFTSREQ		0x24
+#define	LPC_DMAC_SOFTLBREQ		0x28
+#define	LPC_DMAC_SOFTLSREQ		0x2c
+#define	LPC_DMAC_CONFIG			0x30
+#define	LPC_DMAC_CONFIG_M1		(1 << 2)
+#define	LPC_DMAC_CONFIG_M0		(1 << 1)
+#define	LPC_DMAC_CONFIG_ENABLE		(1 << 0)
+#define	LPC_DMAC_CHADDR(_n)		(0x100 + (_n * 0x20))
+#define	LPC_DMAC_CHNUM			8
+#define	LPC_DMAC_CHSIZE			0x20
+#define	LPC_DMAC_CH_SRCADDR		0x00
+#define	LPC_DMAC_CH_DSTADDR		0x04
+#define	LPC_DMAC_CH_LLI			0x08
+#define	LPC_DMAC_CH_LLI_AHB1		(1 << 0)
+#define	LPC_DMAC_CH_CONTROL		0x0c
+#define	LPC_DMAC_CH_CONTROL_I		(1U << 31)
+#define	LPC_DMAC_CH_CONTROL_DI		(1 << 27)
+#define	LPC_DMAC_CH_CONTROL_SI		(1 << 26)
+#define	LPC_DMAC_CH_CONTROL_D		(1 << 25)
+#define	LPC_DMAC_CH_CONTROL_S		(1 << 24)
+#define	LPC_DMAC_CH_CONTROL_WIDTH_4	2
+#define	LPC_DMAC_CH_CONTROL_DWIDTH(_n)	((_n & 0x7) << 21)
+#define	LPC_DMAC_CH_CONTROL_SWIDTH(_n)	((_n & 0x7) << 18)
+#define	LPC_DMAC_CH_CONTROL_BURST_8	2
+#define	LPC_DMAC_CH_CONTROL_DBSIZE(_n)	((_n & 0x7) << 15)
+#define	LPC_DMAC_CH_CONTROL_SBSIZE(_n)	((_n & 0x7) << 12)
+#define	LPC_DMAC_CH_CONTROL_XFERLEN(_n)	(_n & 0xfff) 
+#define	LPC_DMAC_CH_CONFIG		0x10
+#define	LPC_DMAC_CH_CONFIG_H		(1 << 18)
+#define	LPC_DMAC_CH_CONFIG_A		(1 << 17)
+#define	LPC_DMAC_CH_CONFIG_L		(1 << 16)
+#define	LPC_DMAC_CH_CONFIG_ITC		(1 << 15)
+#define	LPC_DMAC_CH_CONFIG_IE		(1 << 14)
+#define	LPC_DMAC_CH_CONFIG_FLOWCNTL(_n)	((_n & 0x7) << 11)
+#define	LPC_DMAC_CH_CONFIG_DESTP(_n)	((_n & 0x1f) << 6)
+#define	LPC_DMAC_CH_CONFIG_SRCP(_n)	((_n & 0x1f) << 1)
+#define	LPC_DMAC_CH_CONFIG_E		(1 << 0)
+
+/* DMA flow control values */
+#define	LPC_DMAC_FLOW_D_M2M		0
+#define	LPC_DMAC_FLOW_D_M2P		1
+#define	LPC_DMAC_FLOW_D_P2M		2
+#define	LPC_DMAC_FLOW_D_P2P		3
+#define	LPC_DMAC_FLOW_DP_P2P		4
+#define	LPC_DMAC_FLOW_P_M2P		5
+#define	LPC_DMAC_FLOW_P_P2M		6
+#define	LPC_DMAC_FLOW_SP_P2P		7
+
+/* DMA peripheral ID's */
+#define	LPC_DMAC_I2S0_DMA0_ID		0
+#define	LPC_DMAC_NAND_ID		1
+#define	LPC_DMAC_IS21_DMA0_ID		2
+#define	LPC_DMAC_SSP1_ID		3
+#define	LPC_DMAC_SPI2_ID		3
+#define	LPC_DMAC_SD_ID			4
+#define	LPC_DMAC_UART1_TX_ID		5
+#define	LPC_DMAC_UART1_RX_ID		6
+#define	LPC_DMAC_UART2_TX_ID		7
+#define	LPC_DMAC_UART2_RX_ID		8
+#define	LPC_DMAC_UART7_TX_ID		9
+#define	LPC_DMAC_UART7_RX_ID		10
+#define	LPC_DMAC_I2S1_DMA1_ID		10
+#define	LPC_DMAC_SPI1_ID		11
+#define	LPC_DMAC_SSP1_TX_ID		11
+#define	LPC_DMAC_NAND2_ID		12
+#define	LPC_DMAC_I2S0_DMA1_ID		13
+#define	LPC_DMAC_SSP0_RX		14
+#define	LPC_DMAC_SSP0_TX		15
+
+#endif	/* _ARM_LPC_LPCREG_H */


Property changes on: trunk/sys/arm/lpc/lpcreg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/lpc/lpcvar.h
===================================================================
--- trunk/sys/arm/lpc/lpcvar.h	                        (rev 0)
+++ trunk/sys/arm/lpc/lpcvar.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,70 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2011 Jakub Wojciech Klama <jceel at FreeBSD.org>
+ * 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: stable/10/sys/arm/lpc/lpcvar.h 239278 2012-08-15 05:37:10Z gonzo $
+ */
+
+#ifndef	_ARM_LPC_LPCVAR_H
+#define	_ARM_LPC_LPCVAR_H
+
+#include <sys/types.h>
+#include <sys/bus.h>
+#include <machine/bus.h>
+
+/* Clocking and power control */
+uint32_t lpc_pwr_read(device_t, int);
+void lpc_pwr_write(device_t, int, uint32_t);
+
+/* GPIO */
+void platform_gpio_init(void);
+int lpc_gpio_set_flags(device_t, int, int);
+int lpc_gpio_set_state(device_t, int, int);
+int lpc_gpio_get_state(device_t, int, int *);
+
+/* DMA */
+struct lpc_dmac_channel_config
+{
+	int		ldc_fcntl;
+	int		ldc_src_periph;
+	int		ldc_src_width;
+	int		ldc_src_incr;
+	int		ldc_src_burst;
+	int		ldc_dst_periph;
+	int		ldc_dst_width;
+	int		ldc_dst_incr;
+	int		ldc_dst_burst;
+	void		(*ldc_success_handler)(void *);
+	void		(*ldc_error_handler)(void *);
+	void *		ldc_handler_arg;
+};
+
+int lpc_dmac_config_channel(device_t, int, struct lpc_dmac_channel_config *);
+int lpc_dmac_setup_transfer(device_t, int, bus_addr_t, bus_addr_t, bus_size_t, int);
+int lpc_dmac_enable_channel(device_t, int);
+int lpc_dmac_disable_channel(device_t, int);
+int lpc_dmac_start_burst(device_t, int);
+
+#endif	/* _ARM_LPC_LPCVAR_H */


Property changes on: trunk/sys/arm/lpc/lpcvar.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/lpc/ssd1289.c
===================================================================
--- trunk/sys/arm/lpc/ssd1289.c	                        (rev 0)
+++ trunk/sys/arm/lpc/ssd1289.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,210 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2011 Jakub Wojciech Klama <jceel at FreeBSD.org>
+ * 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: stable/10/sys/arm/lpc/ssd1289.c 239278 2012-08-15 05:37:10Z gonzo $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bio.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/endian.h>
+#include <sys/kernel.h>
+#include <sys/kthread.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/queue.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+#include <sys/time.h>
+#include <sys/timetc.h>
+#include <sys/watchdog.h>
+
+#include <dev/spibus/spi.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <arm/lpc/lpcreg.h>
+#include <arm/lpc/lpcvar.h>
+
+#include "spibus_if.h"
+
+struct ssd1289_softc
+{
+	device_t		ss_dev;
+};
+
+static int ssd1289_probe(device_t);
+static int ssd1289_attach(device_t);
+
+static __inline void ssd1289_set_dc(struct ssd1289_softc *, int);
+static __inline void ssd1289_spi_send(struct ssd1289_softc *, uint8_t *, int);
+static void ssd1289_write_reg(struct ssd1289_softc *, uint16_t, uint16_t);
+
+static struct ssd1289_softc *ssd1289_sc = NULL;
+
+void ssd1289_configure(void);
+
+static int
+ssd1289_probe(device_t dev)
+{
+#if 0
+	if (!ofw_bus_is_compatible(dev, "ssd1289"))
+		return (ENXIO);
+#endif
+
+	device_set_desc(dev, "Solomon Systech SSD1289 LCD controller");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+ssd1289_attach(device_t dev)
+{
+	struct ssd1289_softc *sc = device_get_softc(dev);
+
+	sc->ss_dev = dev;
+	ssd1289_sc = sc;
+
+	return (0);
+}
+
+void
+ssd1289_configure(void)
+{
+	struct ssd1289_softc *sc = ssd1289_sc;
+
+	/* XXX will be replaced with commented code */
+        ssd1289_write_reg(sc,0x00,0x0001);
+        DELAY(20);
+
+        ssd1289_write_reg(sc,0x03,0xA2A4);
+        ssd1289_write_reg(sc,0x0C,0x0004);
+        ssd1289_write_reg(sc,0x0D,0x0308);
+        ssd1289_write_reg(sc,0x0E,0x3000);
+        DELAY(50);
+
+        ssd1289_write_reg(sc,0x1E,0x00AF);
+        ssd1289_write_reg(sc,0x01,0x2B3F);
+        ssd1289_write_reg(sc,0x02,0x0600);
+        ssd1289_write_reg(sc,0x10,0x0000);
+        ssd1289_write_reg(sc,0x07,0x0233);
+        ssd1289_write_reg(sc,0x0B,0x0039);
+        ssd1289_write_reg(sc,0x0F,0x0000);
+        DELAY(50);
+
+        ssd1289_write_reg(sc,0x30,0x0707);
+        ssd1289_write_reg(sc,0x31,0x0204);
+        ssd1289_write_reg(sc,0x32,0x0204);
+        ssd1289_write_reg(sc,0x33,0x0502);
+        ssd1289_write_reg(sc,0x34,0x0507);
+        ssd1289_write_reg(sc,0x35,0x0204);
+        ssd1289_write_reg(sc,0x36,0x0204);
+        ssd1289_write_reg(sc,0x37,0x0502);
+        ssd1289_write_reg(sc,0x3A,0x0302);
+        ssd1289_write_reg(sc,0x3B,0x0302);
+
+        ssd1289_write_reg(sc,0x23,0x0000);
+        ssd1289_write_reg(sc,0x24,0x0000);
+
+        ssd1289_write_reg(sc,0x48,0x0000);
+        ssd1289_write_reg(sc,0x49,0x013F);
+        ssd1289_write_reg(sc,0x4A,0x0000);
+        ssd1289_write_reg(sc,0x4B,0x0000);
+
+        ssd1289_write_reg(sc,0x41,0x0000);
+        ssd1289_write_reg(sc,0x42,0x0000);
+
+        ssd1289_write_reg(sc,0x44,0xEF00);
+        ssd1289_write_reg(sc,0x45,0x0000);
+        ssd1289_write_reg(sc,0x46,0x013F);
+        DELAY(50);
+
+        ssd1289_write_reg(sc,0x44,0xEF00);
+        ssd1289_write_reg(sc,0x45,0x0000);
+        ssd1289_write_reg(sc,0x4E,0x0000);
+        ssd1289_write_reg(sc,0x4F,0x0000);
+        ssd1289_write_reg(sc,0x46,0x013F);
+}
+
+static __inline void
+ssd1289_spi_send(struct ssd1289_softc *sc, uint8_t *data, int len)
+{
+	struct spi_command cmd;
+	uint8_t buffer[8];
+	cmd.tx_cmd = data;
+	cmd.tx_cmd_sz = len;
+	cmd.rx_cmd = buffer;
+	cmd.rx_cmd_sz = len;
+	cmd.tx_data_sz = 0;
+	cmd.rx_data_sz = 0;
+	SPIBUS_TRANSFER(device_get_parent(sc->ss_dev), sc->ss_dev, &cmd);
+}
+
+static __inline void
+ssd1289_set_dc(struct ssd1289_softc *sc, int value)
+{
+	lpc_gpio_set_state(sc->ss_dev, SSD1289_DC_PIN, value);
+}
+
+static void
+ssd1289_write_reg(struct ssd1289_softc *sc, uint16_t addr, uint16_t value)
+{
+	uint8_t buffer[2];
+
+	ssd1289_set_dc(sc, 0);
+	buffer[0] = 0x00;
+	buffer[1] = addr & 0xff;
+	ssd1289_spi_send(sc, buffer, 2);
+
+	ssd1289_set_dc(sc, 1);
+	buffer[0] = (value >> 8) & 0xff;
+	buffer[1] = value & 0xff;
+	ssd1289_spi_send(sc, buffer, 2);
+}
+
+static device_method_t ssd1289_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		ssd1289_probe),
+	DEVMETHOD(device_attach,	ssd1289_attach),
+
+	{ 0, 0 }
+};
+
+static devclass_t ssd1289_devclass;
+
+static driver_t ssd1289_driver = {
+	"ssd1289",
+	ssd1289_methods,
+	sizeof(struct ssd1289_softc),
+};
+
+DRIVER_MODULE(ssd1289, spibus, ssd1289_driver, ssd1289_devclass, 0, 0);


Property changes on: trunk/sys/arm/lpc/ssd1289.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/lpc/std.lpc
===================================================================
--- trunk/sys/arm/lpc/std.lpc	                        (rev 0)
+++ trunk/sys/arm/lpc/std.lpc	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,14 @@
+# $FreeBSD: stable/10/sys/arm/lpc/std.lpc 266110 2014-05-15 02:41:23Z ian $
+#
+# DM644x
+#
+
+files		"../lpc/files.lpc"
+cpu		CPU_ARM9
+machine 	arm
+makeoptions	CONF_CFLAGS="-march=armv5te"
+options		PHYSADDR=0x80000000
+makeoptions	KERNPHYSADDR=0x80100000
+options		KERNPHYSADDR=0x80100000
+makeoptions	KERNVIRTADDR=0xc0100000
+options		KERNVIRTADDR=0xc0100000


Property changes on: trunk/sys/arm/lpc/std.lpc
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/mv/armadaxp/armadaxp.c
===================================================================
--- trunk/sys/arm/mv/armadaxp/armadaxp.c	                        (rev 0)
+++ trunk/sys/arm/mv/armadaxp/armadaxp.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,308 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2011 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.
+ *
+ * From: FreeBSD: src/sys/arm/mv/kirkwood/sheevaplug.c,v 1.2 2010/06/13 13:28:53
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/mv/armadaxp/armadaxp.c 250293 2013-05-06 14:12:36Z gber $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+
+#include <machine/bus.h>
+#include <machine/armreg.h>
+
+#include <arm/mv/mvwin.h>
+#include <arm/mv/mvreg.h>
+#include <arm/mv/mvvar.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+
+#include <machine/fdt.h>
+
+#define CPU_FREQ_FIELD(sar)	(((0x01 & (sar >> 52)) << 3) | \
+				    (0x07 & (sar >> 21)))
+#define FAB_FREQ_FIELD(sar)	(((0x01 & (sar >> 51)) << 4) | \
+				    (0x0F & (sar >> 24)))
+
+static uint32_t count_l2clk(void);
+void armadaxp_l2_init(void);
+void armadaxp_init_coher_fabric(void);
+int platform_get_ncpus(void);
+
+#define ARMADAXP_L2_BASE		(MV_BASE + 0x8000)
+#define ARMADAXP_L2_CTRL		0x100
+#define L2_ENABLE			(1 << 0)
+#define ARMADAXP_L2_AUX_CTRL		0x104
+#define L2_WBWT_MODE_MASK		(3 << 0)
+#define L2_WBWT_MODE_PAGE		0
+#define L2_WBWT_MODE_WB			1
+#define L2_WBWT_MODE_WT			2
+#define L2_REP_STRAT_MASK		(3 << 27)
+#define L2_REP_STRAT_LSFR		(1 << 27)
+#define L2_REP_STRAT_SEMIPLRU		(3 << 27)
+
+#define ARMADAXP_L2_CNTR_CTRL		0x200
+#define ARMADAXP_L2_CNTR_CONF(x)	(0x204 + (x) * 0xc)
+#define ARMADAXP_L2_CNTR2_VAL_LOW	(0x208 + (x) * 0xc)
+#define ARMADAXP_L2_CNTR2_VAL_HI	(0x20c + (x) * 0xc)
+
+#define ARMADAXP_L2_INT_CAUSE		0x220
+
+#define ARMADAXP_L2_SYNC_BARRIER	0x700
+#define ARMADAXP_L2_INV_WAY		0x778
+#define ARMADAXP_L2_CLEAN_WAY		0x7BC
+#define ARMADAXP_L2_FLUSH_PHYS		0x7F0
+#define ARMADAXP_L2_FLUSH_WAY		0x7FC
+
+#define MV_COHERENCY_FABRIC_BASE	(MV_MBUS_BRIDGE_BASE + 0x200)
+#define COHER_FABRIC_CTRL		0x00
+#define COHER_FABRIC_CONF		0x04
+#define COHER_FABRIC_CFU		0x28
+#define COHER_FABRIC_CIB_CTRL		0x80
+
+/* XXX Make gpio driver optional and remove it */
+struct resource_spec mv_gpio_res[] = {
+	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		0,	RF_ACTIVE },
+	{ -1, 0 }
+};
+
+struct vco_freq_ratio {
+	uint8_t	vco_cpu;	/* VCO to CLK0(CPU) clock ratio */
+	uint8_t	vco_l2c;	/* VCO to NB(L2 cache) clock ratio */
+	uint8_t	vco_hcl;	/* VCO to HCLK(DDR controller) clock ratio */
+	uint8_t	vco_ddr;	/* VCO to DR(DDR memory) clock ratio */
+};
+
+static struct vco_freq_ratio freq_conf_table[] = {
+/*00*/	{ 1, 1,	 4,  2 },
+/*01*/	{ 1, 2,	 2,  2 },
+/*02*/	{ 2, 2,	 6,  3 },
+/*03*/	{ 2, 2,	 3,  3 },
+/*04*/	{ 1, 2,	 3,  3 },
+/*05*/	{ 1, 2,	 4,  2 },
+/*06*/	{ 1, 1,	 2,  2 },
+/*07*/	{ 2, 3,	 6,  6 },
+/*08*/	{ 2, 3,	 5,  5 },
+/*09*/	{ 1, 2,	 6,  3 },
+/*10*/	{ 2, 4,	10,  5 },
+/*11*/	{ 1, 3,	 6,  6 },
+/*12*/	{ 1, 2,	 5,  5 },
+/*13*/	{ 1, 3,	 6,  3 },
+/*14*/	{ 1, 2,	 5,  5 },
+/*15*/	{ 2, 2,	 5,  5 },
+/*16*/	{ 1, 1,	 3,  3 },
+/*17*/	{ 2, 5,	10, 10 },
+/*18*/	{ 1, 3,	 8,  4 },
+/*19*/	{ 1, 1,	 2,  1 },
+/*20*/	{ 2, 3,	 6,  3 },
+/*21*/	{ 1, 2,	 8,  4 },
+/*22*/	{ 2, 5,	10,  5 }
+};
+
+static uint16_t	cpu_clock_table[] = {
+    1000, 1066, 1200, 1333, 1500, 1666, 1800, 2000, 600,  667,  800,  1600,
+    2133, 2200, 2400 };
+
+uint32_t
+get_tclk(void)
+{
+ 	uint32_t cputype;
+
+	cputype = cpufunc_id();
+	cputype &= CPU_ID_CPU_MASK;
+
+	if (cputype == CPU_ID_MV88SV584X_V7)
+		return (TCLK_250MHZ);
+	else
+		return (TCLK_200MHZ);
+}
+
+static uint32_t
+count_l2clk(void)
+{
+	uint64_t sar_reg;
+	uint32_t freq_vco, freq_l2clk;
+	uint8_t  sar_cpu_freq, sar_fab_freq, array_size;
+
+	/* Get value of the SAR register and process it */
+	sar_reg = get_sar_value();
+	sar_cpu_freq = CPU_FREQ_FIELD(sar_reg);
+	sar_fab_freq = FAB_FREQ_FIELD(sar_reg);
+
+	/* Check if CPU frequency field has correct value */
+	array_size = sizeof(cpu_clock_table) / sizeof(cpu_clock_table[0]);
+	if (sar_cpu_freq >= array_size)
+		panic("Reserved value in cpu frequency configuration field: "
+		    "%d", sar_cpu_freq);
+
+	/* Check if fabric frequency field has correct value */
+	array_size = sizeof(freq_conf_table) / sizeof(freq_conf_table[0]);
+	if (sar_fab_freq >= array_size)
+		panic("Reserved value in fabric frequency configuration field: "
+		    "%d", sar_fab_freq);
+
+	/* Get CPU clock frequency */
+	freq_vco = cpu_clock_table[sar_cpu_freq] *
+	    freq_conf_table[sar_fab_freq].vco_cpu;
+
+	/* Get L2CLK clock frequency */
+	freq_l2clk = freq_vco / freq_conf_table[sar_fab_freq].vco_l2c;
+
+	/* Round L2CLK value to integer MHz */
+	if (((freq_vco % freq_conf_table[sar_fab_freq].vco_l2c) * 10 /
+	    freq_conf_table[sar_fab_freq].vco_l2c) >= 5)
+		freq_l2clk++;
+
+	return (freq_l2clk * 1000000);
+}
+
+uint32_t
+get_l2clk(void)
+{
+	static uint32_t	l2clk_freq = 0;
+
+	/* If get_l2clk is called first time get L2CLK value from register */
+	if (l2clk_freq == 0)
+		l2clk_freq = count_l2clk();
+
+	return (l2clk_freq);
+}
+
+static uint32_t
+read_coher_fabric(uint32_t reg)
+{
+
+	return (bus_space_read_4(fdtbus_bs_tag, MV_COHERENCY_FABRIC_BASE, reg));
+}
+
+static void
+write_coher_fabric(uint32_t reg, uint32_t val)
+{
+
+	bus_space_write_4(fdtbus_bs_tag, MV_COHERENCY_FABRIC_BASE, reg, val);
+}
+
+int
+platform_get_ncpus(void)
+{
+#if !defined(SMP)
+	return (1);
+#else
+	return ((read_coher_fabric(COHER_FABRIC_CONF) & 0xf) + 1);
+#endif
+}
+
+void
+armadaxp_init_coher_fabric(void)
+{
+	uint32_t val, cpus, mask;
+
+	cpus = platform_get_ncpus();
+	mask = (1 << cpus) - 1;
+	val = read_coher_fabric(COHER_FABRIC_CTRL);
+	val |= (mask << 24);
+	write_coher_fabric(COHER_FABRIC_CTRL, val);
+
+	val = read_coher_fabric(COHER_FABRIC_CONF);
+	val |= (mask << 24);
+	val |= (1 << 15);
+	write_coher_fabric(COHER_FABRIC_CONF, val);
+}
+
+#define ALL_WAYS	0xffffffff
+
+/* L2 cache configuration registers */
+static uint32_t
+read_l2_cache(uint32_t reg)
+{
+
+	return (bus_space_read_4(fdtbus_bs_tag, ARMADAXP_L2_BASE, reg));
+}
+
+static void
+write_l2_cache(uint32_t reg, uint32_t val)
+{
+
+	bus_space_write_4(fdtbus_bs_tag, ARMADAXP_L2_BASE, reg, val);
+}
+
+static void
+armadaxp_l2_idcache_inv_all(void)
+{
+	write_l2_cache(ARMADAXP_L2_INV_WAY, ALL_WAYS);
+}
+
+void
+armadaxp_l2_init(void)
+{
+	u_int32_t reg;
+
+	/* Set L2 policy */
+	reg = read_l2_cache(ARMADAXP_L2_AUX_CTRL);
+	reg &= ~(L2_WBWT_MODE_MASK);
+	reg &= ~(L2_REP_STRAT_MASK);
+	reg |= L2_REP_STRAT_SEMIPLRU;
+	reg |= L2_WBWT_MODE_WT;
+	write_l2_cache(ARMADAXP_L2_AUX_CTRL, reg);
+
+	/* Invalidate l2 cache */
+	armadaxp_l2_idcache_inv_all();
+
+	/* Clear pending L2 interrupts */
+	write_l2_cache(ARMADAXP_L2_INT_CAUSE, 0x1ff);
+
+	/* Enable l2 cache */
+	reg = read_l2_cache(ARMADAXP_L2_CTRL);
+	write_l2_cache(ARMADAXP_L2_CTRL, reg | L2_ENABLE);
+
+	/*
+	 * For debug purposes
+	 * Configure and enable counter
+	 */
+	write_l2_cache(ARMADAXP_L2_CNTR_CONF(0), 0xf0000 | (4 << 2));
+	write_l2_cache(ARMADAXP_L2_CNTR_CONF(1), 0xf0000 | (2 << 2));
+	write_l2_cache(ARMADAXP_L2_CNTR_CTRL, 0x303);
+
+	/*
+	 * Enable Cache maintenance operation propagation in coherency fabric
+	 * Change point of coherency and point of unification to DRAM.
+	 */
+	reg = read_coher_fabric(COHER_FABRIC_CFU);
+	reg |= (1 << 17) | (1 << 18);
+	write_coher_fabric(COHER_FABRIC_CFU, reg);
+
+	/* Coherent IO Bridge initialization */
+	reg = read_coher_fabric(COHER_FABRIC_CIB_CTRL);
+	reg &= ~(7 << 16);
+	reg |= (7 << 16);
+	write_coher_fabric(COHER_FABRIC_CIB_CTRL, reg);
+}
+


Property changes on: trunk/sys/arm/mv/armadaxp/armadaxp.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/mv/armadaxp/armadaxp_mp.c
===================================================================
--- trunk/sys/arm/mv/armadaxp/armadaxp_mp.c	                        (rev 0)
+++ trunk/sys/arm/mv/armadaxp/armadaxp_mp.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,195 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2011 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.
+ *
+ * $FreeBSD: stable/10/sys/arm/mv/armadaxp/armadaxp_mp.c 283340 2015-05-23 23:35:19Z ian $
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/smp.h>
+
+#include <vm/vm.h>
+#include <vm/vm_kern.h>
+#include <vm/vm_extern.h>
+
+#include <dev/fdt/fdt_common.h>
+
+#include <machine/smp.h>
+#include <machine/fdt.h>
+#include <machine/armreg.h>
+
+#include <arm/mv/mvwin.h>
+
+#define MV_AXP_CPU_DIVCLK_BASE		(MV_BASE + 0x18700)
+#define CPU_DIVCLK_CTRL0		0x00
+#define CPU_DIVCLK_CTRL2_RATIO_FULL0	0x08
+#define CPU_DIVCLK_CTRL2_RATIO_FULL1	0x0c
+#define CPU_DIVCLK_MASK(x)		(~(0xff << (8 * (x))))
+
+#define CPU_PMU(x)			(MV_BASE + 0x22100 + (0x100 * (x)))
+#define CPU_PMU_BOOT			0x24
+
+#define MP				(MV_BASE + 0x20800)
+#define MP_SW_RESET(x)			((x) * 8)
+
+#define CPU_RESUME_CONTROL		(0x20988)
+
+void armadaxp_init_coher_fabric(void);
+int platform_get_ncpus(void);
+
+/* Coherency Fabric registers */
+static uint32_t
+read_cpu_clkdiv(uint32_t reg)
+{
+
+	return (bus_space_read_4(fdtbus_bs_tag, MV_AXP_CPU_DIVCLK_BASE, reg));
+}
+
+static void
+write_cpu_clkdiv(uint32_t reg, uint32_t val)
+{
+
+	bus_space_write_4(fdtbus_bs_tag, MV_AXP_CPU_DIVCLK_BASE, reg, val);
+}
+
+void
+platform_mp_setmaxid(void)
+{
+
+	mp_maxid = 3;
+}
+
+int
+platform_mp_probe(void)
+{
+
+	mp_ncpus = platform_get_ncpus();
+
+	return (mp_ncpus > 1);
+}
+
+void
+platform_mp_init_secondary(void)
+{
+}
+
+void mptramp(void);
+void mptramp_end(void);
+extern vm_offset_t mptramp_pmu_boot;
+
+void
+platform_mp_start_ap(void)
+{
+	uint32_t reg, *src, *dst, cpu_num, div_val, cputype;
+	vm_offset_t pmu_boot_off;
+	/*
+	 * Initialization procedure depends on core revision,
+	 * in this step CHIP ID is checked to choose proper procedure
+	 */
+	cputype = cpufunc_id();
+	cputype &= CPU_ID_CPU_MASK;
+
+	/*
+	 * Set the PA of CPU0 Boot Address Redirect register used in
+	 * mptramp according to the actual SoC registers' base address.
+	 */
+	pmu_boot_off = (CPU_PMU(0) - MV_BASE) + CPU_PMU_BOOT;
+	mptramp_pmu_boot = fdt_immr_pa + pmu_boot_off;
+	dst = pmap_mapdev(0xffff0000, PAGE_SIZE);
+	for (src = (uint32_t *)mptramp; src < (uint32_t *)mptramp_end;
+	    src++, dst++) {
+		*dst = *src;
+	}
+	pmap_unmapdev((vm_offset_t)dst, PAGE_SIZE);
+	if (cputype == CPU_ID_MV88SV584X_V7) {
+		/* Core rev A0 */
+		div_val = read_cpu_clkdiv(CPU_DIVCLK_CTRL2_RATIO_FULL1);
+		div_val &= 0x3f;
+
+		for (cpu_num = 1; cpu_num < mp_ncpus; cpu_num++ ) {
+			reg = read_cpu_clkdiv(CPU_DIVCLK_CTRL2_RATIO_FULL1);
+			reg &= CPU_DIVCLK_MASK(cpu_num);
+			reg |= div_val << (cpu_num * 8);
+			write_cpu_clkdiv(CPU_DIVCLK_CTRL2_RATIO_FULL1, reg);
+		}
+	} else {
+		/* Core rev Z1 */
+		div_val = 0x01;
+
+		if (mp_ncpus > 1) {
+			reg = read_cpu_clkdiv(CPU_DIVCLK_CTRL2_RATIO_FULL0);
+			reg &= CPU_DIVCLK_MASK(3);
+			reg |= div_val << 24;
+			write_cpu_clkdiv(CPU_DIVCLK_CTRL2_RATIO_FULL0, reg);
+		}
+
+		for (cpu_num = 2; cpu_num < mp_ncpus; cpu_num++ ) {
+			reg = read_cpu_clkdiv(CPU_DIVCLK_CTRL2_RATIO_FULL1);
+			reg &= CPU_DIVCLK_MASK(cpu_num);
+			reg |= div_val << (cpu_num * 8);
+			write_cpu_clkdiv(CPU_DIVCLK_CTRL2_RATIO_FULL1, reg);
+		}
+	}
+
+	reg = read_cpu_clkdiv(CPU_DIVCLK_CTRL0);
+	reg |= ((0x1 << (mp_ncpus - 1)) - 1) << 21;
+	write_cpu_clkdiv(CPU_DIVCLK_CTRL0, reg);
+	reg = read_cpu_clkdiv(CPU_DIVCLK_CTRL0);
+	reg |= 0x01000000;
+	write_cpu_clkdiv(CPU_DIVCLK_CTRL0, reg);
+
+	DELAY(100);
+	reg &= ~(0xf << 21);
+	write_cpu_clkdiv(CPU_DIVCLK_CTRL0, reg);
+	DELAY(100);
+
+	bus_space_write_4(fdtbus_bs_tag, MV_BASE, CPU_RESUME_CONTROL, 0);
+
+	for (cpu_num = 1; cpu_num < mp_ncpus; cpu_num++ )
+		bus_space_write_4(fdtbus_bs_tag, CPU_PMU(cpu_num), CPU_PMU_BOOT,
+		    pmap_kextract((vm_offset_t)mpentry));
+
+	cpu_idcache_wbinv_all();
+
+	for (cpu_num = 1; cpu_num < mp_ncpus; cpu_num++ )
+		bus_space_write_4(fdtbus_bs_tag, MP, MP_SW_RESET(cpu_num), 0);
+
+	/* XXX: Temporary workaround for hangup after releasing AP's */
+	wmb();
+	DELAY(10);
+
+	armadaxp_init_coher_fabric();
+}
+
+void
+platform_ipi_send(cpuset_t cpus, u_int ipi)
+{
+
+	pic_ipi_send(cpus, ipi);
+}


Property changes on: trunk/sys/arm/mv/armadaxp/armadaxp_mp.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/mv/armadaxp/files.armadaxp
===================================================================
--- trunk/sys/arm/mv/armadaxp/files.armadaxp	                        (rev 0)
+++ trunk/sys/arm/mv/armadaxp/files.armadaxp	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,8 @@
+# $FreeBSD: stable/10/sys/arm/mv/armadaxp/files.armadaxp 266385 2014-05-18 00:30:04Z ian $
+
+arm/mv/armadaxp/armadaxp.c	standard
+arm/mv/mpic.c			standard
+arm/mv/rtc.c			standard
+arm/mv/armadaxp/armadaxp_mp.c	optional smp
+arm/mv/armadaxp/mptramp.S	optional smp
+


Property changes on: trunk/sys/arm/mv/armadaxp/files.armadaxp
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/mv/armadaxp/mptramp.S
===================================================================
--- trunk/sys/arm/mv/armadaxp/mptramp.S	                        (rev 0)
+++ trunk/sys/arm/mv/armadaxp/mptramp.S	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,62 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright 2011 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 <machine/asm.h>
+#include <machine/armreg.h>
+
+__FBSDID("$FreeBSD: stable/10/sys/arm/mv/armadaxp/mptramp.S 283340 2015-05-23 23:35:19Z ian $");
+
+.global _C_LABEL(mptramp_pmu_boot)
+
+ASENTRY_NP(mptramp)
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c7, 0
+
+	mrs	r3, cpsr
+	bic	r3, r3, #(PSR_MODE)
+	orr	r3, r3, #(PSR_SVC32_MODE)
+        msr	cpsr_fsxc, r3
+
+	mrc	p15, 0, r0, c0, c0, 5
+	and	r0, #0x0f		/* Get CPU ID */
+
+	/* Read boot address for CPU */
+	mov	r1, #0x100
+	mul	r2, r0, r1
+	ldr	r1, mptramp_pmu_boot
+	add	r0, r2, r1
+	ldr	r1, [r0], #0x00
+
+	mov pc, r1
+
+_C_LABEL(mptramp_pmu_boot):
+	.word 0x0
+
+END(mptramp)
+
+	.global _C_LABEL(mptramp_end)
+_C_LABEL(mptramp_end):


Property changes on: trunk/sys/arm/mv/armadaxp/mptramp.S
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/mv/armadaxp/std.armadaxp
===================================================================
--- trunk/sys/arm/mv/armadaxp/std.armadaxp	                        (rev 0)
+++ trunk/sys/arm/mv/armadaxp/std.armadaxp	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,16 @@
+# $FreeBSD: stable/10/sys/arm/mv/armadaxp/std.armadaxp 266110 2014-05-15 02:41:23Z ian $
+
+# kernel gets loaded at 0x00200000 by the loader, but runs at virtual address
+# 0xc0200000.  RAM starts at 0.  We put the pagetable at a reasonable place
+# in memory, but may need to bounce it higher if there's a problem with this.
+# We could paper over this by loading the kernel at 0xc0000000 virtual, but
+# that leads to other complications, so we'll just reclaim the lower region of
+# ram after we're loaded.  Put the page tables for startup at 1MB.
+makeoptions	KERNPHYSADDR=0x00200000
+makeoptions	KERNVIRTADDR=0xc0200000
+
+options		KERNPHYSADDR=0x00200000
+options		KERNVIRTADDR=0xc0200000
+options		PHYSADDR=0x00000000
+
+options		ARM_L2_PIPT


Property changes on: trunk/sys/arm/mv/armadaxp/std.armadaxp
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/mv/armadaxp/std.mv78x60
===================================================================
--- trunk/sys/arm/mv/armadaxp/std.mv78x60	                        (rev 0)
+++ trunk/sys/arm/mv/armadaxp/std.mv78x60	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,5 @@
+# $FreeBSD: stable/10/sys/arm/mv/armadaxp/std.mv78x60 239277 2012-08-15 05:15:49Z gonzo $
+
+include	"../mv/std-pj4b.mv"
+include "../mv/armadaxp/std.armadaxp"
+files	"../mv/armadaxp/files.armadaxp"


Property changes on: trunk/sys/arm/mv/armadaxp/std.mv78x60
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/mv/discovery/discovery.c
===================================================================
--- trunk/sys/arm/mv/discovery/discovery.c	                        (rev 0)
+++ trunk/sys/arm/mv/discovery/discovery.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,112 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (C) 2008 MARVELL INTERNATIONAL LTD.
+ * All rights reserved.
+ *
+ * Developed by Semihalf.
+ *
+ * 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.
+ * 3. Neither the name of MARVELL nor the names of contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY 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 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: stable/10/sys/arm/mv/discovery/discovery.c 235609 2012-05-18 14:41:14Z gber $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+
+#include <arm/mv/mvreg.h>
+#include <arm/mv/mvvar.h>
+#include <arm/mv/mvwin.h>
+
+/*
+ * Virtual address space layout:
+ * -----------------------------
+ * 0x0000_0000 - 0xBFFF_FFFF	: User Process (3 GB)
+ * 0xC000_0000 - virtual_avail	: Kernel Reserved (text, data, page tables,
+ * 				: stack etc.)
+ * virtual-avail - 0xEFFF_FFFF	: KVA (virtual_avail is typically < 0xc0a0_0000)
+ * 0xF000_0000 - 0xF0FF_FFFF	: No-Cache allocation area (16 MB)
+ * 0xF100_0000 - 0xF10F_FFFF	: SoC Integrated devices registers range (1 MB)
+ * 0xF110_0000 - 0xF11F_FFFF	: PCI-Express I/O space (1MB)
+ * 0xF120_0000 - 0xF12F_FFFF	: PCI I/O space (1MB)
+ * 0xF130_0000 - 0xF52F_FFFF	: PCI-Express memory space (64MB)
+ * 0xF530_0000 - 0xF92F_FFFF	: PCI memory space (64MB)
+ * 0xF930_0000 - 0xF93F_FFFF	: Device Bus: BOOT (1 MB)
+ * 0xF940_0000 - 0xF94F_FFFF	: Device Bus: CS0 (1 MB)
+ * 0xF950_0000 - 0xFB4F_FFFF	: Device Bus: CS1 (32 MB)
+ * 0xFB50_0000 - 0xFB5F_FFFF	: Device Bus: CS2 (1 MB)
+ * 0xFB60_0000 - 0xFFFE_FFFF	: Unused (~74MB)
+ * 0xFFFF_0000 - 0xFFFF_0FFF	: 'High' vectors page (4 kB)
+ * 0xFFFF_1000 - 0xFFFF_1FFF	: ARM_TP_ADDRESS/RAS page (4 kB)
+ * 0xFFFF_2000 - 0xFFFF_FFFF	: Unused (56 kB)
+ */
+
+
+struct resource_spec mv_gpio_res[] = {
+	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		0,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		1,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		2,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		3,	RF_ACTIVE },
+	{ -1, 0 }
+};
+
+const struct decode_win idma_win_tbl[] = {
+	{ 0 },
+};
+const struct decode_win *idma_wins = idma_win_tbl;
+int idma_wins_no = 0;
+
+const struct decode_win xor_win_tbl[] = {
+	{ 0 },
+};
+const struct decode_win *xor_wins = xor_win_tbl;
+int xor_wins_no = 0;
+
+uint32_t
+get_tclk(void)
+{
+	uint32_t sar;
+
+	/*
+	 * On Discovery TCLK is can be configured to 166 MHz or 200 MHz.
+	 * Current setting is read from Sample At Reset register.
+	 */
+	sar = bus_space_read_4(fdtbus_bs_tag, MV_MPP_BASE, SAMPLE_AT_RESET_HI);
+	sar = (sar & TCLK_MASK) >> TCLK_SHIFT;
+
+	switch (sar) {
+	case 0:
+		return (TCLK_166MHZ);
+	case 1:
+		return (TCLK_200MHZ);
+	default:
+		panic("Unknown TCLK settings!");
+	}
+}


Property changes on: trunk/sys/arm/mv/discovery/discovery.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/mv/discovery/files.db78xxx
===================================================================
--- trunk/sys/arm/mv/discovery/files.db78xxx	                        (rev 0)
+++ trunk/sys/arm/mv/discovery/files.db78xxx	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,5 @@
+# $FreeBSD: stable/10/sys/arm/mv/discovery/files.db78xxx 239277 2012-08-15 05:15:49Z gonzo $
+
+arm/mv/discovery/discovery.c	standard
+arm/mv/ic.c			standard
+


Property changes on: trunk/sys/arm/mv/discovery/files.db78xxx
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/mv/discovery/std.db78xxx
===================================================================
--- trunk/sys/arm/mv/discovery/std.db78xxx	                        (rev 0)
+++ trunk/sys/arm/mv/discovery/std.db78xxx	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,11 @@
+# $FreeBSD: stable/10/sys/arm/mv/discovery/std.db78xxx 266110 2014-05-15 02:41:23Z ian $
+
+include	"../mv/std.mv"
+files	"../mv/discovery/files.db78xxx"
+
+makeoptions	KERNPHYSADDR=0x00900000
+makeoptions	KERNVIRTADDR=0xc0900000
+
+options		KERNPHYSADDR=0x00900000
+options		KERNVIRTADDR=0xc0900000
+options		PHYSADDR=0x00000000


Property changes on: trunk/sys/arm/mv/discovery/std.db78xxx
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/mv/files.mv
===================================================================
--- trunk/sys/arm/mv/files.mv	                        (rev 0)
+++ trunk/sys/arm/mv/files.mv	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,41 @@
+# $FreeBSD: stable/10/sys/arm/mv/files.mv 287016 2015-08-22 07:32:47Z mav $
+#
+# The Marvell CPU cores
+# - Compliant with V5TE architecture
+# - Super scalar dual issue CPU
+# - Big/Little Endian
+# - MMU/MPU
+# - L1 Cache: Supports streaming and write allocate
+# - Variable pipeline stages
+# - Out-of-order execution
+# - Branch Prediction
+# - JTAG/ICE
+# - Vector Floating Point (VFP) unit
+#
+arm/arm/bus_space_base.c	standard
+arm/arm/bus_space_generic.c	standard
+arm/arm/cpufunc_asm_arm10.S	standard
+arm/arm/cpufunc_asm_arm11.S	standard
+arm/arm/cpufunc_asm_armv5.S	standard
+arm/arm/cpufunc_asm_armv5_ec.S	standard
+arm/arm/cpufunc_asm_armv7.S	standard
+arm/arm/cpufunc_asm_sheeva.S	standard
+arm/arm/cpufunc_asm_pj4b.S	standard
+
+arm/mv/gpio.c			standard
+arm/mv/mv_common.c		standard
+arm/mv/mv_localbus.c		standard
+arm/mv/mv_machdep.c		standard
+arm/mv/mv_pci.c			optional	pci
+arm/mv/mv_ts.c			standard
+arm/mv/timer.c			standard
+arm/mv/twsi.c			optional	iicbus
+
+dev/cesa/cesa.c			optional	cesa
+dev/mge/if_mge.c		optional	mge
+dev/nand/nfc_mv.c		optional	nand
+dev/mvs/mvs_soc.c		optional	mvs
+dev/uart/uart_dev_ns8250.c	optional	uart
+dev/usb/controller/ehci_mv.c	optional	ehci
+
+kern/kern_clocksource.c		standard


Property changes on: trunk/sys/arm/mv/files.mv
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/mv/gpio.c
===================================================================
--- trunk/sys/arm/mv/gpio.c	                        (rev 0)
+++ trunk/sys/arm/mv/gpio.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,662 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2006 Benno Rice.
+ * Copyright (C) 2008 MARVELL INTERNATIONAL LTD.
+ * All rights reserved.
+ *
+ * Adapted and extended for Marvell SoCs by Semihalf.
+ *
+ * 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 ``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 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.
+ *
+ * from: FreeBSD: //depot/projects/arm/src/sys/arm/xscale/pxa2x0/pxa2x0_gpio.c, rev 1
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/mv/gpio.c 273652 2014-10-26 01:30:46Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/interrupt.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/mutex.h>
+#include <sys/rman.h>
+#include <sys/queue.h>
+#include <sys/timetc.h>
+#include <machine/bus.h>
+#include <machine/fdt.h>
+#include <machine/intr.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <arm/mv/mvvar.h>
+#include <arm/mv/mvreg.h>
+
+#define GPIO_MAX_INTR_COUNT	8
+#define GPIO_PINS_PER_REG	32
+
+struct mv_gpio_softc {
+	struct resource *	res[GPIO_MAX_INTR_COUNT + 1];
+	void			*ih_cookie[GPIO_MAX_INTR_COUNT];
+	bus_space_tag_t		bst;
+	bus_space_handle_t	bsh;
+	uint8_t			pin_num;	/* number of GPIO pins */
+	uint8_t			irq_num;	/* number of real IRQs occupied by GPIO controller */
+};
+
+extern struct resource_spec mv_gpio_res[];
+
+static struct mv_gpio_softc *mv_gpio_softc = NULL;
+static uint32_t	gpio_setup[MV_GPIO_MAX_NPINS];
+
+static int	mv_gpio_probe(device_t);
+static int	mv_gpio_attach(device_t);
+static int	mv_gpio_intr(void *);
+
+static void	mv_gpio_intr_handler(int pin);
+static uint32_t	mv_gpio_reg_read(uint32_t reg);
+static void	mv_gpio_reg_write(uint32_t reg, uint32_t val);
+static void	mv_gpio_reg_set(uint32_t reg, uint32_t val);
+static void	mv_gpio_reg_clear(uint32_t reg, uint32_t val);
+
+static void	mv_gpio_blink(uint32_t pin, uint8_t enable);
+static void	mv_gpio_polarity(uint32_t pin, uint8_t enable);
+static void	mv_gpio_level(uint32_t pin, uint8_t enable);
+static void	mv_gpio_edge(uint32_t pin, uint8_t enable);
+static void	mv_gpio_out_en(uint32_t pin, uint8_t enable);
+static void	mv_gpio_int_ack(uint32_t pin);
+static void	mv_gpio_value_set(uint32_t pin, uint8_t val);
+static uint32_t	mv_gpio_value_get(uint32_t pin);
+
+static device_method_t mv_gpio_methods[] = {
+	DEVMETHOD(device_probe,		mv_gpio_probe),
+	DEVMETHOD(device_attach,	mv_gpio_attach),
+	{ 0, 0 }
+};
+
+static driver_t mv_gpio_driver = {
+	"gpio",
+	mv_gpio_methods,
+	sizeof(struct mv_gpio_softc),
+};
+
+static devclass_t mv_gpio_devclass;
+
+DRIVER_MODULE(gpio, simplebus, mv_gpio_driver, mv_gpio_devclass, 0, 0);
+
+typedef int (*gpios_phandler_t)(phandle_t, pcell_t *, int);
+
+struct gpio_ctrl_entry {
+	const char		*compat;
+	gpios_phandler_t	handler;
+};
+
+int mv_handle_gpios_prop(phandle_t ctrl, pcell_t *gpios, int len);
+int gpio_get_config_from_dt(void);
+
+struct gpio_ctrl_entry gpio_controllers[] = {
+	{ "mrvl,gpio", &mv_handle_gpios_prop },
+	{ NULL, NULL }
+};
+
+static int
+mv_gpio_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "mrvl,gpio"))
+		return (ENXIO);
+
+	device_set_desc(dev, "Marvell Integrated GPIO Controller");
+	return (0);
+}
+
+static int
+mv_gpio_attach(device_t dev)
+{
+	int error, i;
+	struct mv_gpio_softc *sc;
+	uint32_t dev_id, rev_id;
+
+	sc = (struct mv_gpio_softc *)device_get_softc(dev);
+	if (sc == NULL)
+		return (ENXIO);
+
+	mv_gpio_softc = sc;
+
+	/* Get chip id and revision */
+	soc_id(&dev_id, &rev_id);
+
+	if (dev_id == MV_DEV_88F5182 ||
+	    dev_id == MV_DEV_88F5281 ||
+	    dev_id == MV_DEV_MV78100 ||
+	    dev_id == MV_DEV_MV78100_Z0 ) {
+		sc->pin_num = 32;
+		sc->irq_num = 4;
+
+	} else if (dev_id == MV_DEV_88F6281 ||
+	    dev_id == MV_DEV_88F6282) {
+		sc->pin_num = 50;
+		sc->irq_num = 7;
+
+	} else {
+		device_printf(dev, "unknown chip id=0x%x\n", dev_id);
+		return (ENXIO);
+	}
+
+	error = bus_alloc_resources(dev, mv_gpio_res, sc->res);
+	if (error) {
+		device_printf(dev, "could not allocate resources\n");
+		return (ENXIO);
+	}
+
+	sc->bst = rman_get_bustag(sc->res[0]);
+	sc->bsh = rman_get_bushandle(sc->res[0]);
+
+	/* Disable and clear all interrupts */
+	bus_space_write_4(sc->bst, sc->bsh, GPIO_INT_EDGE_MASK, 0);
+	bus_space_write_4(sc->bst, sc->bsh, GPIO_INT_LEV_MASK, 0);
+	bus_space_write_4(sc->bst, sc->bsh, GPIO_INT_CAUSE, 0);
+
+	if (sc->pin_num > GPIO_PINS_PER_REG) {
+		bus_space_write_4(sc->bst, sc->bsh,
+		    GPIO_HI_INT_EDGE_MASK, 0);
+		bus_space_write_4(sc->bst, sc->bsh,
+		    GPIO_HI_INT_LEV_MASK, 0);
+		bus_space_write_4(sc->bst, sc->bsh,
+		    GPIO_HI_INT_CAUSE, 0);
+	}
+
+	for (i = 0; i < sc->irq_num; i++) {
+		if (bus_setup_intr(dev, sc->res[1 + i],
+		    INTR_TYPE_MISC, mv_gpio_intr, NULL,
+		    sc, &sc->ih_cookie[i]) != 0) {
+			bus_release_resources(dev, mv_gpio_res, sc->res);
+			device_printf(dev, "could not set up intr %d\n", i);
+			return (ENXIO);
+		}
+	}
+
+	return (platform_gpio_init());
+}
+
+static int
+mv_gpio_intr(void *arg)
+{
+	uint32_t int_cause, gpio_val;
+	uint32_t int_cause_hi, gpio_val_hi = 0;
+	int i;
+
+	int_cause = mv_gpio_reg_read(GPIO_INT_CAUSE);
+	gpio_val = mv_gpio_reg_read(GPIO_DATA_IN);
+	gpio_val &= int_cause;
+	if (mv_gpio_softc->pin_num > GPIO_PINS_PER_REG) {
+		int_cause_hi = mv_gpio_reg_read(GPIO_HI_INT_CAUSE);
+		gpio_val_hi = mv_gpio_reg_read(GPIO_HI_DATA_IN);
+		gpio_val_hi &= int_cause_hi;
+	}
+
+	i = 0;
+	while (gpio_val != 0) {
+		if (gpio_val & 1)
+			mv_gpio_intr_handler(i);
+		gpio_val >>= 1;
+		i++;
+	}
+
+	if (mv_gpio_softc->pin_num > GPIO_PINS_PER_REG) {
+		i = 0;
+		while (gpio_val_hi != 0) {
+			if (gpio_val_hi & 1)
+				mv_gpio_intr_handler(i + GPIO_PINS_PER_REG);
+			gpio_val_hi >>= 1;
+			i++;
+		}
+	}
+
+	return (FILTER_HANDLED);
+}
+
+/*
+ * GPIO interrupt handling
+ */
+
+static struct intr_event *gpio_events[MV_GPIO_MAX_NPINS];
+
+int
+mv_gpio_setup_intrhandler(const char *name, driver_filter_t *filt,
+    void (*hand)(void *), void *arg, int pin, int flags, void **cookiep)
+{
+	struct	intr_event *event;
+	int	error;
+
+	if (pin < 0 || pin >= mv_gpio_softc->pin_num)
+		return (ENXIO);
+	event = gpio_events[pin];
+	if (event == NULL) {
+		error = intr_event_create(&event, (void *)pin, 0, pin,
+		    (void (*)(void *))mv_gpio_intr_mask,
+		    (void (*)(void *))mv_gpio_intr_unmask,
+		    (void (*)(void *))mv_gpio_int_ack,
+		    NULL,
+		    "gpio%d:", pin);
+		if (error != 0)
+			return (error);
+		gpio_events[pin] = event;
+	}
+
+	intr_event_add_handler(event, name, filt, hand, arg,
+	    intr_priority(flags), flags, cookiep);
+	return (0);
+}
+
+void
+mv_gpio_intr_mask(int pin)
+{
+
+	if (pin >= mv_gpio_softc->pin_num)
+		return;
+
+	if (gpio_setup[pin] & MV_GPIO_IN_IRQ_EDGE)
+		mv_gpio_edge(pin, 0);
+	else
+		mv_gpio_level(pin, 0);
+}
+
+void
+mv_gpio_intr_unmask(int pin)
+{
+
+	if (pin >= mv_gpio_softc->pin_num)
+		return;
+
+	if (gpio_setup[pin] & MV_GPIO_IN_IRQ_EDGE)
+		mv_gpio_edge(pin, 1);
+	else
+		mv_gpio_level(pin, 1);
+}
+
+static void
+mv_gpio_intr_handler(int pin)
+{
+	struct intr_event *event;
+
+	event = gpio_events[pin];
+	if (event == NULL || TAILQ_EMPTY(&event->ie_handlers))
+		return;
+
+	intr_event_handle(event, NULL);
+}
+
+static int
+mv_gpio_configure(uint32_t pin, uint32_t flags)
+{
+
+	if (pin >= mv_gpio_softc->pin_num)
+		return (EINVAL);
+
+	if (flags & MV_GPIO_OUT_BLINK)
+		mv_gpio_blink(pin, 1);
+	if (flags & MV_GPIO_IN_POL_LOW)
+		mv_gpio_polarity(pin, 1);
+	if (flags & MV_GPIO_IN_IRQ_EDGE)
+		mv_gpio_edge(pin, 1);
+	if (flags & MV_GPIO_IN_IRQ_LEVEL)
+		mv_gpio_level(pin, 1);
+
+	gpio_setup[pin] = flags;
+
+	return (0);
+}
+
+void
+mv_gpio_out(uint32_t pin, uint8_t val, uint8_t enable)
+{
+
+	mv_gpio_value_set(pin, val);
+	mv_gpio_out_en(pin, enable);
+}
+
+uint8_t
+mv_gpio_in(uint32_t pin)
+{
+
+	return (mv_gpio_value_get(pin) ? 1 : 0);
+}
+
+static uint32_t
+mv_gpio_reg_read(uint32_t reg)
+{
+
+	return (bus_space_read_4(mv_gpio_softc->bst,
+	    mv_gpio_softc->bsh, reg));
+}
+
+static void
+mv_gpio_reg_write(uint32_t reg, uint32_t val)
+{
+
+	bus_space_write_4(mv_gpio_softc->bst,
+	    mv_gpio_softc->bsh, reg, val);
+}
+
+static void
+mv_gpio_reg_set(uint32_t reg, uint32_t pin)
+{
+	uint32_t reg_val;
+
+	reg_val = mv_gpio_reg_read(reg);
+	reg_val |= GPIO(pin);
+	mv_gpio_reg_write(reg, reg_val);
+}
+
+static void
+mv_gpio_reg_clear(uint32_t reg, uint32_t pin)
+{
+	uint32_t reg_val;
+
+	reg_val = mv_gpio_reg_read(reg);
+	reg_val &= ~(GPIO(pin));
+	mv_gpio_reg_write(reg, reg_val);
+}
+
+static void
+mv_gpio_out_en(uint32_t pin, uint8_t enable)
+{
+	uint32_t reg;
+
+	if (pin >= mv_gpio_softc->pin_num)
+		return;
+
+	if (pin >= GPIO_PINS_PER_REG) {
+		reg = GPIO_HI_DATA_OUT_EN_CTRL;
+		pin -= GPIO_PINS_PER_REG;
+	} else
+		reg = GPIO_DATA_OUT_EN_CTRL;
+
+	if (enable)
+		mv_gpio_reg_clear(reg, pin);
+	else
+		mv_gpio_reg_set(reg, pin);
+}
+
+static void
+mv_gpio_blink(uint32_t pin, uint8_t enable)
+{
+	uint32_t reg;
+
+	if (pin >= mv_gpio_softc->pin_num)
+		return;
+
+	if (pin >= GPIO_PINS_PER_REG) {
+		reg = GPIO_HI_BLINK_EN;
+		pin -= GPIO_PINS_PER_REG;
+	} else
+		reg = GPIO_BLINK_EN;
+
+	if (enable)
+		mv_gpio_reg_set(reg, pin);
+	else
+		mv_gpio_reg_clear(reg, pin);
+}
+
+static void
+mv_gpio_polarity(uint32_t pin, uint8_t enable)
+{
+	uint32_t reg;
+
+	if (pin >= mv_gpio_softc->pin_num)
+		return;
+
+	if (pin >= GPIO_PINS_PER_REG) {
+		reg = GPIO_HI_DATA_IN_POLAR;
+		pin -= GPIO_PINS_PER_REG;
+	} else
+		reg = GPIO_DATA_IN_POLAR;
+
+	if (enable)
+		mv_gpio_reg_set(reg, pin);
+	else
+		mv_gpio_reg_clear(reg, pin);
+}
+
+static void
+mv_gpio_level(uint32_t pin, uint8_t enable)
+{
+	uint32_t reg;
+
+	if (pin >= mv_gpio_softc->pin_num)
+		return;
+
+	if (pin >= GPIO_PINS_PER_REG) {
+		reg = GPIO_HI_INT_LEV_MASK;
+		pin -= GPIO_PINS_PER_REG;
+	} else
+		reg = GPIO_INT_LEV_MASK;
+
+	if (enable)
+		mv_gpio_reg_set(reg, pin);
+	else
+		mv_gpio_reg_clear(reg, pin);
+}
+
+static void
+mv_gpio_edge(uint32_t pin, uint8_t enable)
+{
+	uint32_t reg;
+
+	if (pin >= mv_gpio_softc->pin_num)
+		return;
+
+	if (pin >= GPIO_PINS_PER_REG) {
+		reg = GPIO_HI_INT_EDGE_MASK;
+		pin -= GPIO_PINS_PER_REG;
+	} else
+		reg = GPIO_INT_EDGE_MASK;
+
+	if (enable)
+		mv_gpio_reg_set(reg, pin);
+	else
+		mv_gpio_reg_clear(reg, pin);
+}
+
+static void
+mv_gpio_int_ack(uint32_t pin)
+{
+	uint32_t reg;
+
+	if (pin >= mv_gpio_softc->pin_num)
+		return;
+
+	if (pin >= GPIO_PINS_PER_REG) {
+		reg = GPIO_HI_INT_CAUSE;
+		pin -= GPIO_PINS_PER_REG;
+	} else
+		reg = GPIO_INT_CAUSE;
+
+	mv_gpio_reg_clear(reg, pin);
+}
+
+static uint32_t
+mv_gpio_value_get(uint32_t pin)
+{
+	uint32_t reg, reg_val;
+
+	if (pin >= mv_gpio_softc->pin_num)
+		return (0);
+
+	if (pin >= GPIO_PINS_PER_REG) {
+		reg = GPIO_HI_DATA_IN;
+		pin -= GPIO_PINS_PER_REG;
+	} else
+		reg = GPIO_DATA_IN;
+
+	reg_val = mv_gpio_reg_read(reg);
+
+	return (reg_val & GPIO(pin));
+}
+
+static void
+mv_gpio_value_set(uint32_t pin, uint8_t val)
+{
+	uint32_t reg;
+
+	if (pin >= mv_gpio_softc->pin_num)
+		return;
+
+	if (pin >= GPIO_PINS_PER_REG) {
+		reg = GPIO_HI_DATA_OUT;
+		pin -= GPIO_PINS_PER_REG;
+	} else
+		reg = GPIO_DATA_OUT;
+
+	if (val)
+		mv_gpio_reg_set(reg, pin);
+	else
+		mv_gpio_reg_clear(reg, pin);
+}
+
+int
+mv_handle_gpios_prop(phandle_t ctrl, pcell_t *gpios, int len)
+{
+	pcell_t gpio_cells, pincnt;
+	int inc, t, tuples, tuple_size;
+	int dir, flags, pin;
+	u_long gpio_ctrl, size;
+	struct mv_gpio_softc sc;
+
+	pincnt = 0;
+	if (!OF_hasprop(ctrl, "gpio-controller"))
+		/* Node is not a GPIO controller. */
+		return (ENXIO);
+
+	if (OF_getprop(ctrl, "#gpio-cells", &gpio_cells, sizeof(pcell_t)) < 0)
+		return (ENXIO);
+
+	gpio_cells = fdt32_to_cpu(gpio_cells);
+	if (gpio_cells != 3)
+		return (ENXIO);
+
+	tuple_size = gpio_cells * sizeof(pcell_t) + sizeof(phandle_t);
+	tuples = len / tuple_size;
+
+	if (fdt_regsize(ctrl, &gpio_ctrl, &size))
+		return (ENXIO);
+
+	if (OF_getprop(ctrl, "pin-count", &pincnt, sizeof(pcell_t)) < 0)
+		return (ENXIO);
+	sc.pin_num = fdt32_to_cpu(pincnt);
+
+	/*
+	 * Skip controller reference, since controller's phandle is given
+	 * explicitly (in a function argument).
+	 */
+	inc = sizeof(ihandle_t) / sizeof(pcell_t);
+	gpios += inc;
+
+	for (t = 0; t < tuples; t++) {
+		pin = fdt32_to_cpu(gpios[0]);
+		dir = fdt32_to_cpu(gpios[1]);
+		flags = fdt32_to_cpu(gpios[2]);
+
+		mv_gpio_configure(pin, flags);
+
+		if (dir == 1)
+			/* Input. */
+			mv_gpio_out_en(pin, 0);
+		else {
+			/* Output. */
+			if (flags & MV_GPIO_OUT_OPEN_DRAIN)
+				mv_gpio_out(pin, 0, 1);
+
+			if (flags & MV_GPIO_OUT_OPEN_SRC)
+				mv_gpio_out(pin, 1, 1);
+		}
+		gpios += gpio_cells + inc;
+	}
+
+	return (0);
+}
+
+#define MAX_PINS_PER_NODE	5
+#define GPIOS_PROP_CELLS	4
+int
+platform_gpio_init(void)
+{
+	phandle_t child, parent, root, ctrl;
+	pcell_t gpios[MAX_PINS_PER_NODE * GPIOS_PROP_CELLS];
+	struct gpio_ctrl_entry *e;
+	int len, rv;
+
+	root = OF_finddevice("/");
+	len = 0;
+	parent = root;
+
+	/* Traverse through entire tree to find nodes with 'gpios' prop */
+	for (child = OF_child(parent); child != 0; child = OF_peer(child)) {
+
+		/* Find a 'leaf'. Start the search from this node. */
+		while (OF_child(child)) {
+			parent = child;
+			child = OF_child(child);
+		}
+		if ((len = OF_getproplen(child, "gpios")) > 0) {
+
+			if (len > sizeof(gpios))
+				return (ENXIO);
+
+			/* Get 'gpios' property. */
+			OF_getprop(child, "gpios", &gpios, len);
+
+			e = (struct gpio_ctrl_entry *)&gpio_controllers;
+
+			/* Find and call a handler. */
+			for (; e->compat; e++) {
+				/*
+				 * First cell of 'gpios' property should
+				 * contain a ref. to a node defining GPIO
+				 * controller.
+				 */
+				ctrl = OF_node_from_xref(fdt32_to_cpu(gpios[0]));
+
+				if (fdt_is_compatible(ctrl, e->compat))
+					/* Call a handler. */
+					if ((rv = e->handler(ctrl,
+					    (pcell_t *)&gpios, len)))
+						return (rv);
+			}
+		}
+
+		if (OF_peer(child) == 0) {
+			/* No more siblings. */
+			child = parent;
+			parent = OF_parent(child);
+		}
+	}
+	return (0);
+}


Property changes on: trunk/sys/arm/mv/gpio.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/mv/ic.c
===================================================================
--- trunk/sys/arm/mv/ic.c	                        (rev 0)
+++ trunk/sys/arm/mv/ic.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,314 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2006 Benno Rice.
+ * Copyright (C) 2007-2008 MARVELL INTERNATIONAL LTD.
+ * All rights reserved.
+ *
+ * Adapted and extended to Marvell SoCs by Semihalf.
+ *
+ * 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 ``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 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.
+ *
+ * from: FreeBSD: //depot/projects/arm/src/sys/arm/xscale/pxa2x0/pxa2x0_icu.c, rev 1
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/mv/ic.c 266152 2014-05-15 16:11:06Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/ktr.h>
+#include <sys/module.h>
+#include <sys/rman.h>
+#include <machine/bus.h>
+#include <machine/intr.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <arm/mv/mvreg.h>
+#include <arm/mv/mvvar.h>
+
+struct mv_ic_softc {
+	struct resource	*	ic_res[1];
+	bus_space_tag_t		ic_bst;
+	bus_space_handle_t	ic_bsh;
+	int			ic_high_regs;
+	int			ic_error_regs;
+};
+
+static struct resource_spec mv_ic_spec[] = {
+	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
+	{ -1, 0 }
+};
+
+static struct mv_ic_softc *mv_ic_sc = NULL;
+
+static int	mv_ic_probe(device_t);
+static int	mv_ic_attach(device_t);
+
+uint32_t	mv_ic_get_cause(void);
+uint32_t	mv_ic_get_mask(void);
+void		mv_ic_set_mask(uint32_t);
+uint32_t	mv_ic_get_cause_hi(void);
+uint32_t	mv_ic_get_mask_hi(void);
+void		mv_ic_set_mask_hi(uint32_t);
+uint32_t	mv_ic_get_cause_error(void);
+uint32_t	mv_ic_get_mask_error(void);
+void		mv_ic_set_mask_error(uint32_t);
+static void	arm_mask_irq_all(void);
+
+static int
+mv_ic_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "mrvl,pic"))
+		return (ENXIO);
+
+	device_set_desc(dev, "Marvell Integrated Interrupt Controller");
+	return (0);
+}
+
+static int
+mv_ic_attach(device_t dev)
+{
+	struct mv_ic_softc *sc;
+	uint32_t dev_id, rev_id;
+	int error;
+
+	sc = (struct mv_ic_softc *)device_get_softc(dev);
+
+	if (mv_ic_sc != NULL)
+		return (ENXIO);
+	mv_ic_sc = sc;
+
+	soc_id(&dev_id, &rev_id);
+
+	sc->ic_high_regs = 0;
+	sc->ic_error_regs = 0;
+
+	if (dev_id == MV_DEV_88F6281 ||
+	    dev_id == MV_DEV_88F6282 ||
+	    dev_id == MV_DEV_MV78100 ||
+	    dev_id == MV_DEV_MV78100_Z0)
+		sc->ic_high_regs = 1;
+
+	if (dev_id == MV_DEV_MV78100 || dev_id == MV_DEV_MV78100_Z0)
+		sc->ic_error_regs = 1;
+
+	error = bus_alloc_resources(dev, mv_ic_spec, sc->ic_res);
+	if (error) {
+		device_printf(dev, "could not allocate resources\n");
+		return (ENXIO);
+	}
+
+	sc->ic_bst = rman_get_bustag(sc->ic_res[0]);
+	sc->ic_bsh = rman_get_bushandle(sc->ic_res[0]);
+
+	/* Mask all interrupts */
+	arm_mask_irq_all();
+
+	return (0);
+}
+
+static device_method_t mv_ic_methods[] = {
+	DEVMETHOD(device_probe,		mv_ic_probe),
+	DEVMETHOD(device_attach,	mv_ic_attach),
+	{ 0, 0 }
+};
+
+static driver_t mv_ic_driver = {
+	"ic",
+	mv_ic_methods,
+	sizeof(struct mv_ic_softc),
+};
+
+static devclass_t mv_ic_devclass;
+
+DRIVER_MODULE(ic, simplebus, mv_ic_driver, mv_ic_devclass, 0, 0);
+
+int
+arm_get_next_irq(int last)
+{
+	u_int filt, irq;
+	int next;
+
+	filt = ~((last >= 0) ? (2 << last) - 1 : 0);
+	irq = mv_ic_get_cause() & mv_ic_get_mask();
+	if (irq & filt) {
+		next = ffs(irq & filt) - 1;
+		goto out;
+	}
+	if (mv_ic_sc->ic_high_regs) {
+		filt = ~((last >= 32) ? (2 << (last - 32)) - 1 : 0);
+		irq = mv_ic_get_cause_hi() & mv_ic_get_mask_hi();
+		if (irq & filt) {
+			next = ffs(irq & filt) + 31;
+			goto out;
+		}
+	}
+	if (mv_ic_sc->ic_error_regs) {
+		filt = ~((last >= 64) ? (2 << (last - 64)) - 1 : 0);
+		irq = mv_ic_get_cause_error() & mv_ic_get_mask_error();
+		if (irq & filt) {
+			next = ffs(irq & filt) + 63;
+			goto out;
+		}
+	}
+	next = -1;
+
+ out:
+	CTR3(KTR_INTR, "%s: last=%d, next=%d", __func__, last, next);
+	return (next);
+}
+
+static void
+arm_mask_irq_all(void)
+{
+
+	mv_ic_set_mask(0);
+
+	if (mv_ic_sc->ic_high_regs)
+		mv_ic_set_mask_hi(0);
+
+	if (mv_ic_sc->ic_error_regs)
+		mv_ic_set_mask_error(0);
+}
+
+void
+arm_mask_irq(uintptr_t nb)
+{
+	uint32_t	mr;
+
+	if (nb < 32) {
+		mr = mv_ic_get_mask();
+		mr &= ~(1 << nb);
+		mv_ic_set_mask(mr);
+
+	} else if ((nb < 64) && mv_ic_sc->ic_high_regs) {
+		mr = mv_ic_get_mask_hi();
+		mr &= ~(1 << (nb - 32));
+		mv_ic_set_mask_hi(mr);
+
+	} else if ((nb < 96) && mv_ic_sc->ic_error_regs) {
+		mr = mv_ic_get_mask_error();
+		mr &= ~(1 << (nb - 64));
+		mv_ic_set_mask_error(mr);
+	}
+}
+
+void
+arm_unmask_irq(uintptr_t nb)
+{
+	uint32_t	mr;
+
+	if (nb < 32) {
+		mr = mv_ic_get_mask();
+		mr |= (1 << nb);
+		mv_ic_set_mask(mr);
+
+	} else if ((nb < 64) && mv_ic_sc->ic_high_regs) {
+		mr = mv_ic_get_mask_hi();
+		mr |= (1 << (nb - 32));
+		mv_ic_set_mask_hi(mr);
+
+	} else if ((nb < 96) && mv_ic_sc->ic_error_regs) {
+		mr = mv_ic_get_mask_error();
+		mr |= (1 << (nb - 64));
+		mv_ic_set_mask_error(mr);
+	}
+}
+
+void
+mv_ic_set_mask(uint32_t val)
+{
+
+	bus_space_write_4(mv_ic_sc->ic_bst, mv_ic_sc->ic_bsh,
+	    IRQ_MASK, val);
+}
+
+uint32_t
+mv_ic_get_mask(void)
+{
+
+	return (bus_space_read_4(mv_ic_sc->ic_bst,
+	    mv_ic_sc->ic_bsh, IRQ_MASK));
+}
+
+uint32_t
+mv_ic_get_cause(void)
+{
+
+	return (bus_space_read_4(mv_ic_sc->ic_bst,
+	    mv_ic_sc->ic_bsh, IRQ_CAUSE));
+}
+
+void
+mv_ic_set_mask_hi(uint32_t val)
+{
+
+	bus_space_write_4(mv_ic_sc->ic_bst, mv_ic_sc->ic_bsh,
+	    IRQ_MASK_HI, val);
+}
+
+uint32_t
+mv_ic_get_mask_hi(void)
+{
+
+	return (bus_space_read_4(mv_ic_sc->ic_bst,
+	    mv_ic_sc->ic_bsh, IRQ_MASK_HI));
+}
+
+uint32_t
+mv_ic_get_cause_hi(void)
+{
+
+	return (bus_space_read_4(mv_ic_sc->ic_bst,
+	    mv_ic_sc->ic_bsh, IRQ_CAUSE_HI));
+}
+
+void
+mv_ic_set_mask_error(uint32_t val)
+{
+
+	bus_space_write_4(mv_ic_sc->ic_bst, mv_ic_sc->ic_bsh,
+	    IRQ_MASK_ERROR, val);
+}
+
+uint32_t
+mv_ic_get_mask_error(void)
+{
+
+	return (bus_space_read_4(mv_ic_sc->ic_bst,
+	    mv_ic_sc->ic_bsh, IRQ_MASK_ERROR));
+}
+
+uint32_t
+mv_ic_get_cause_error(void)
+{
+
+	return (bus_space_read_4(mv_ic_sc->ic_bst,
+	    mv_ic_sc->ic_bsh, IRQ_CAUSE_ERROR));
+}


Property changes on: trunk/sys/arm/mv/ic.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/mv/kirkwood/files.kirkwood
===================================================================
--- trunk/sys/arm/mv/kirkwood/files.kirkwood	                        (rev 0)
+++ trunk/sys/arm/mv/kirkwood/files.kirkwood	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,5 @@
+# $FreeBSD: stable/10/sys/arm/mv/kirkwood/files.kirkwood 239277 2012-08-15 05:15:49Z gonzo $
+
+arm/mv/ic.c			standard
+arm/mv/rtc.c			standard
+arm/mv/kirkwood/kirkwood.c	standard


Property changes on: trunk/sys/arm/mv/kirkwood/files.kirkwood
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/mv/kirkwood/kirkwood.c
===================================================================
--- trunk/sys/arm/mv/kirkwood/kirkwood.c	                        (rev 0)
+++ trunk/sys/arm/mv/kirkwood/kirkwood.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,82 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (C) 2008 MARVELL INTERNATIONAL LTD.
+ * All rights reserved.
+ *
+ * Developed by Semihalf.
+ *
+ * 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.
+ * 3. Neither the name of MARVELL nor the names of contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY 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 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: stable/10/sys/arm/mv/kirkwood/kirkwood.c 238873 2012-07-28 21:56:24Z hrs $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+
+#include <machine/bus.h>
+
+#include <arm/mv/mvreg.h>
+#include <arm/mv/mvvar.h>
+#include <arm/mv/mvwin.h>
+
+struct resource_spec mv_gpio_res[] = {
+	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		0,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		1,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		2,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		3,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		4,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		5,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		6,	RF_ACTIVE },
+	{ -1, 0 }
+};
+
+const struct decode_win xor_win_tbl[] = {
+	{ 0 },
+};
+const struct decode_win *xor_wins = xor_win_tbl;
+int xor_wins_no = 0;
+
+uint32_t
+get_tclk(void)
+{
+	uint32_t dev, rev;
+
+	/*
+	 * On Kirkwood TCLK is not configurable and depends on silicon
+	 * revision:
+	 * - A0 and A1 have TCLK hardcoded to 200 MHz.
+	 * - Z0 and others have TCLK hardcoded to 166 MHz.
+	 */
+	soc_id(&dev, &rev);
+	if (dev == MV_DEV_88F6281 && (rev == 2 || rev == 3))
+		return (TCLK_200MHZ);
+	if (dev == MV_DEV_88F6282)
+		return (TCLK_200MHZ);
+
+	return (TCLK_166MHZ);
+}


Property changes on: trunk/sys/arm/mv/kirkwood/kirkwood.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/mv/kirkwood/std.db88f6xxx
===================================================================
--- trunk/sys/arm/mv/kirkwood/std.db88f6xxx	                        (rev 0)
+++ trunk/sys/arm/mv/kirkwood/std.db88f6xxx	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,5 @@
+# $FreeBSD: stable/10/sys/arm/mv/kirkwood/std.db88f6xxx 210249 2010-07-19 19:19:33Z raj $
+
+include	"../mv/std.mv"
+include "../mv/kirkwood/std.kirkwood"
+files	"../mv/kirkwood/files.kirkwood"


Property changes on: trunk/sys/arm/mv/kirkwood/std.db88f6xxx
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/mv/kirkwood/std.kirkwood
===================================================================
--- trunk/sys/arm/mv/kirkwood/std.kirkwood	                        (rev 0)
+++ trunk/sys/arm/mv/kirkwood/std.kirkwood	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,14 @@
+# $FreeBSD: stable/10/sys/arm/mv/kirkwood/std.kirkwood 266110 2014-05-15 02:41:23Z ian $
+
+# kernel gets loaded at 0x00900000 by the loader, but runs at virtual address
+# 0xc0900000.  RAM starts at 0.  We put the pagetable at a reasonable place
+# in memory, but may need to bounce it higher if there's a problem with this.
+# We could paper over this by loading the kernel at 0xc0000000 virtual, but
+# that leads to other complications, so we'll just reclaim the lower region of
+# ram after we're loaded.  Put the page tables for startup at 1MB.
+makeoptions	KERNPHYSADDR=0x00900000
+makeoptions	KERNVIRTADDR=0xc0900000
+
+options		KERNPHYSADDR=0x00900000
+options		KERNVIRTADDR=0xc0900000
+options		PHYSADDR=0x00000000


Property changes on: trunk/sys/arm/mv/kirkwood/std.kirkwood
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/mv/mpic.c
===================================================================
--- trunk/sys/arm/mv/mpic.c	                        (rev 0)
+++ trunk/sys/arm/mv/mpic.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,399 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2006 Benno Rice.
+ * Copyright (C) 2007-2011 MARVELL INTERNATIONAL LTD.
+ * Copyright (c) 2012 Semihalf.
+ * All rights reserved.
+ *
+ * Developed by Semihalf.
+ *
+ * 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 ``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 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.
+ *
+ * from: FreeBSD: //depot/projects/arm/src/sys/arm/xscale/pxa2x0/pxa2x0_icu.c, rev 1
+ * from: FreeBSD: src/sys/arm/mv/ic.c,v 1.5 2011/02/08 01:49:30
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/mv/mpic.c 289184 2015-10-12 13:20:17Z andrew $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/cpuset.h>
+#include <sys/ktr.h>
+#include <sys/module.h>
+#include <sys/rman.h>
+
+#include <machine/bus.h>
+#include <machine/intr.h>
+#include <machine/cpufunc.h>
+#include <machine/smp.h>
+
+#include <arm/mv/mvvar.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+#include <dev/fdt/fdt_common.h>
+
+#ifdef DEBUG
+#define debugf(fmt, args...) do { printf("%s(): ", __func__);	\
+    printf(fmt,##args); } while (0)
+#else
+#define debugf(fmt, args...)
+#endif
+
+#define MPIC_INT_ERR			4
+#define MPIC_INT_MSI			96
+
+#define IRQ_MASK		0x3ff
+
+#define MPIC_CTRL		0x0
+#define MPIC_SOFT_INT		0x4
+#define MPIC_SOFT_INT_DRBL1	(1 << 5)
+#define MPIC_ERR_CAUSE		0x20
+#define MPIC_ISE		0x30
+#define MPIC_ICE		0x34
+
+
+#define MPIC_IN_DRBL		0x78
+#define MPIC_IN_DRBL_MASK	0x7c
+#define MPIC_CTP		0xb0
+#define MPIC_CTP		0xb0
+#define MPIC_IIACK		0xb4
+#define MPIC_ISM		0xb8
+#define MPIC_ICM		0xbc
+#define MPIC_ERR_MASK		0xec0
+
+struct mv_mpic_softc {
+	device_t		sc_dev;
+	struct resource	*	mpic_res[3];
+	bus_space_tag_t		mpic_bst;
+	bus_space_handle_t	mpic_bsh;
+	bus_space_tag_t		cpu_bst;
+	bus_space_handle_t	cpu_bsh;
+	bus_space_tag_t		drbl_bst;
+	bus_space_handle_t	drbl_bsh;
+};
+
+static struct resource_spec mv_mpic_spec[] = {
+	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
+	{ SYS_RES_MEMORY,	1,	RF_ACTIVE },
+	{ SYS_RES_MEMORY,	2,	RF_ACTIVE },
+	{ -1, 0 }
+};
+
+static struct mv_mpic_softc *mv_mpic_sc = NULL;
+
+void mpic_send_ipi(int cpus, u_int ipi);
+
+static int	mv_mpic_probe(device_t);
+static int	mv_mpic_attach(device_t);
+uint32_t	mv_mpic_get_cause(void);
+uint32_t	mv_mpic_get_cause_err(void);
+uint32_t	mv_mpic_get_msi(void);
+static void	arm_mask_irq_err(uintptr_t);
+static void	arm_unmask_irq_err(uintptr_t);
+static void	arm_unmask_msi(void);
+
+#define MPIC_CPU_WRITE(softc, reg, val) \
+    bus_space_write_4((softc)->cpu_bst, (softc)->cpu_bsh, (reg), (val))
+#define MPIC_CPU_READ(softc, reg) \
+    bus_space_read_4((softc)->cpu_bst, (softc)->cpu_bsh, (reg))
+
+#define MPIC_DRBL_WRITE(softc, reg, val) \
+    bus_space_write_4((softc)->drbl_bst, (softc)->drbl_bsh, (reg), (val))
+#define MPIC_DRBL_READ(softc, reg) \
+    bus_space_read_4((softc)->drbl_bst, (softc)->drbl_bsh, (reg))
+
+static int
+mv_mpic_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "mrvl,mpic"))
+		return (ENXIO);
+
+	device_set_desc(dev, "Marvell Integrated Interrupt Controller");
+	return (0);
+}
+
+static int
+mv_mpic_attach(device_t dev)
+{
+	struct mv_mpic_softc *sc;
+	int error;
+
+	sc = (struct mv_mpic_softc *)device_get_softc(dev);
+
+	if (mv_mpic_sc != NULL)
+		return (ENXIO);
+	mv_mpic_sc = sc;
+
+	sc->sc_dev = dev;
+
+	error = bus_alloc_resources(dev, mv_mpic_spec, sc->mpic_res);
+	if (error) {
+		device_printf(dev, "could not allocate resources\n");
+		return (ENXIO);
+	}
+
+	sc->mpic_bst = rman_get_bustag(sc->mpic_res[0]);
+	sc->mpic_bsh = rman_get_bushandle(sc->mpic_res[0]);
+
+	sc->cpu_bst = rman_get_bustag(sc->mpic_res[1]);
+	sc->cpu_bsh = rman_get_bushandle(sc->mpic_res[1]);
+
+	sc->drbl_bst = rman_get_bustag(sc->mpic_res[2]);
+	sc->drbl_bsh = rman_get_bushandle(sc->mpic_res[2]);
+
+	bus_space_write_4(mv_mpic_sc->mpic_bst, mv_mpic_sc->mpic_bsh,
+	    MPIC_CTRL, 1);
+	MPIC_CPU_WRITE(mv_mpic_sc, MPIC_CTP, 0);
+
+	arm_unmask_msi();
+
+	return (0);
+}
+
+static device_method_t mv_mpic_methods[] = {
+	DEVMETHOD(device_probe,		mv_mpic_probe),
+	DEVMETHOD(device_attach,	mv_mpic_attach),
+	{ 0, 0 }
+};
+
+static driver_t mv_mpic_driver = {
+	"mpic",
+	mv_mpic_methods,
+	sizeof(struct mv_mpic_softc),
+};
+
+static devclass_t mv_mpic_devclass;
+
+DRIVER_MODULE(mpic, simplebus, mv_mpic_driver, mv_mpic_devclass, 0, 0);
+
+int
+arm_get_next_irq(int last)
+{
+	u_int irq, next = -1;
+
+	irq = mv_mpic_get_cause() & IRQ_MASK;
+	CTR2(KTR_INTR, "%s: irq:%#x", __func__, irq);
+
+	if (irq != IRQ_MASK) {
+		if (irq == MPIC_INT_ERR)
+			irq = mv_mpic_get_cause_err();
+		if (irq == MPIC_INT_MSI)
+			irq = mv_mpic_get_msi();
+		next = irq;
+	}
+
+	CTR3(KTR_INTR, "%s: last=%d, next=%d", __func__, last, next);
+	return (next);
+}
+
+/*
+ * XXX We can make arm_enable_irq to operate on ICE and then mask/unmask only
+ * by ISM/ICM and remove access to ICE in masking operation
+ */
+void
+arm_mask_irq(uintptr_t nb)
+{
+
+	MPIC_CPU_WRITE(mv_mpic_sc, MPIC_CTP, 1);
+
+	if (nb < ERR_IRQ) {
+		bus_space_write_4(mv_mpic_sc->mpic_bst, mv_mpic_sc->mpic_bsh,
+		    MPIC_ICE, nb);
+		MPIC_CPU_WRITE(mv_mpic_sc, MPIC_ISM, nb);
+	} else if (nb < MSI_IRQ)
+		arm_mask_irq_err(nb);
+}
+
+
+static void
+arm_mask_irq_err(uintptr_t nb)
+{
+	uint32_t mask;
+	uint8_t bit_off;
+
+	bit_off = nb - ERR_IRQ;
+	mask = MPIC_CPU_READ(mv_mpic_sc, MPIC_ERR_MASK);
+	mask &= ~(1 << bit_off);
+	MPIC_CPU_WRITE(mv_mpic_sc, MPIC_ERR_MASK, mask);
+}
+
+void
+arm_unmask_irq(uintptr_t nb)
+{
+
+	MPIC_CPU_WRITE(mv_mpic_sc, MPIC_CTP, 0);
+
+	if (nb < ERR_IRQ) {
+		bus_space_write_4(mv_mpic_sc->mpic_bst, mv_mpic_sc->mpic_bsh,
+		    MPIC_ISE, nb);
+		MPIC_CPU_WRITE(mv_mpic_sc, MPIC_ICM, nb);
+	} else if (nb < MSI_IRQ)
+		arm_unmask_irq_err(nb);
+
+	if (nb == 0)
+		MPIC_CPU_WRITE(mv_mpic_sc, MPIC_IN_DRBL_MASK, 0xffffffff);
+}
+
+void
+arm_unmask_irq_err(uintptr_t nb)
+{
+	uint32_t mask;
+	uint8_t bit_off;
+
+	bus_space_write_4(mv_mpic_sc->mpic_bst, mv_mpic_sc->mpic_bsh,
+	    MPIC_ISE, MPIC_INT_ERR);
+	MPIC_CPU_WRITE(mv_mpic_sc, MPIC_ICM, MPIC_INT_ERR);
+
+	bit_off = nb - ERR_IRQ;
+	mask = MPIC_CPU_READ(mv_mpic_sc, MPIC_ERR_MASK);
+	mask |= (1 << bit_off);
+	MPIC_CPU_WRITE(mv_mpic_sc, MPIC_ERR_MASK, mask);
+}
+
+static void
+arm_unmask_msi(void)
+{
+
+	arm_unmask_irq(MPIC_INT_MSI);
+}
+
+uint32_t
+mv_mpic_get_cause(void)
+{
+
+	return (MPIC_CPU_READ(mv_mpic_sc, MPIC_IIACK));
+}
+
+uint32_t
+mv_mpic_get_cause_err(void)
+{
+	uint32_t err_cause;
+	uint8_t bit_off;
+
+	err_cause = bus_space_read_4(mv_mpic_sc->mpic_bst,
+	    mv_mpic_sc->mpic_bsh, MPIC_ERR_CAUSE);
+
+	if (err_cause)
+		bit_off = ffs(err_cause) - 1;
+	else
+		return (-1);
+
+	debugf("%s: irq:%x cause:%x\n", __func__, bit_off, err_cause);
+	return (ERR_IRQ + bit_off);
+}
+
+uint32_t
+mv_mpic_get_msi(void)
+{
+	uint32_t cause;
+	uint8_t bit_off;
+
+	cause = MPIC_DRBL_READ(mv_mpic_sc, 0);
+
+	if (cause)
+		bit_off = ffs(cause) - 1;
+	else
+		return (-1);
+
+	debugf("%s: irq:%x cause:%x\n", __func__, bit_off, cause);
+
+	cause &= ~(1 << bit_off);
+	MPIC_DRBL_WRITE(mv_mpic_sc, 0, cause);
+
+	return (MSI_IRQ + bit_off);
+}
+
+int
+mv_msi_data(int irq, uint64_t *addr, uint32_t *data)
+{
+	u_long phys, base, size;
+	phandle_t node;
+	int error;
+
+	node = ofw_bus_get_node(mv_mpic_sc->sc_dev);
+
+	/* Get physical addres of register space */
+	error = fdt_get_range(OF_parent(node), 0, &phys, &size);
+	if (error) {
+		printf("%s: Cannot get register physical address, err:%d",
+		    __func__, error);
+		return (error);
+	}
+
+	/* Get offset of MPIC register space */
+	error = fdt_regsize(node, &base, &size);
+	if (error) {
+		printf("%s: Cannot get MPIC register offset, err:%d",
+		    __func__, error);
+		return (error);
+	}
+
+	*addr = phys + base + MPIC_SOFT_INT;
+	*data = MPIC_SOFT_INT_DRBL1 | irq;
+
+	return (0);
+}
+
+#if defined(SMP)
+void
+pic_ipi_send(cpuset_t cpus, u_int ipi)
+{
+	uint32_t val, i;
+
+	val = 0x00000000;
+	for (i = 0; i < MAXCPU; i++)
+		if (CPU_ISSET(i, &cpus))
+			val |= (1 << (8 + i));
+	val |= ipi;
+	bus_space_write_4(mv_mpic_sc->mpic_bst, mv_mpic_sc->mpic_bsh,
+	    MPIC_SOFT_INT, val);
+}
+
+int
+pic_ipi_get(int i __unused)
+{
+	uint32_t val;
+	int ipi;
+
+	val = MPIC_CPU_READ(mv_mpic_sc, MPIC_IN_DRBL);
+	if (val) {
+		ipi = ffs(val) - 1;
+		MPIC_CPU_WRITE(mv_mpic_sc, MPIC_IN_DRBL, ~(1 << ipi));
+		return (ipi);
+	}
+
+	return (0x3ff);
+}
+
+void
+pic_ipi_clear(int ipi)
+{
+}
+
+#endif


Property changes on: trunk/sys/arm/mv/mpic.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/mv/mv_common.c
===================================================================
--- trunk/sys/arm/mv/mv_common.c	                        (rev 0)
+++ trunk/sys/arm/mv/mv_common.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,2211 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (C) 2008-2011 MARVELL INTERNATIONAL LTD.
+ * All rights reserved.
+ *
+ * Developed by Semihalf.
+ *
+ * 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.
+ * 3. Neither the name of MARVELL nor the names of contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY 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 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_global.h"
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/mv/mv_common.c 266277 2014-05-17 00:53:12Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/kdb.h>
+#include <sys/reboot.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+#include <machine/vmparam.h>
+
+#include <arm/mv/mvreg.h>
+#include <arm/mv/mvvar.h>
+#include <arm/mv/mvwin.h>
+
+
+MALLOC_DEFINE(M_IDMA, "idma", "idma dma test memory");
+
+#define IDMA_DEBUG
+#undef IDMA_DEBUG
+
+#define MAX_CPU_WIN	5
+
+#ifdef DEBUG
+#define debugf(fmt, args...) do { printf("%s(): ", __func__);	\
+    printf(fmt,##args); } while (0)
+#else
+#define debugf(fmt, args...)
+#endif
+
+#ifdef DEBUG
+#define MV_DUMP_WIN	1
+#else
+#define MV_DUMP_WIN	0
+#endif
+
+static int win_eth_can_remap(int i);
+
+#ifndef SOC_MV_FREY
+static int decode_win_cpu_valid(void);
+#endif
+static int decode_win_usb_valid(void);
+static int decode_win_eth_valid(void);
+static int decode_win_pcie_valid(void);
+static int decode_win_sata_valid(void);
+
+static int decode_win_idma_valid(void);
+static int decode_win_xor_valid(void);
+
+#ifndef SOC_MV_FREY
+static void decode_win_cpu_setup(void);
+#endif
+#ifdef SOC_MV_ARMADAXP
+static int decode_win_sdram_fixup(void);
+#endif
+static void decode_win_usb_setup(u_long);
+static void decode_win_eth_setup(u_long);
+static void decode_win_sata_setup(u_long);
+
+static void decode_win_idma_setup(u_long);
+static void decode_win_xor_setup(u_long);
+
+static void decode_win_usb_dump(u_long);
+static void decode_win_eth_dump(u_long base);
+static void decode_win_idma_dump(u_long base);
+static void decode_win_xor_dump(u_long base);
+
+static int fdt_get_ranges(const char *, void *, int, int *, int *);
+
+static int win_cpu_from_dt(void);
+static int fdt_win_setup(void);
+
+static uint32_t dev_mask = 0;
+static int cpu_wins_no = 0;
+static int eth_port = 0;
+static int usb_port = 0;
+
+static struct decode_win cpu_win_tbl[MAX_CPU_WIN];
+
+const struct decode_win *cpu_wins = cpu_win_tbl;
+
+typedef void (*decode_win_setup_t)(u_long);
+typedef void (*dump_win_t)(u_long);
+
+struct soc_node_spec {
+	const char		*compat;
+	decode_win_setup_t	decode_handler;
+	dump_win_t		dump_handler;
+};
+
+static struct soc_node_spec soc_nodes[] = {
+	{ "mrvl,ge", &decode_win_eth_setup, &decode_win_eth_dump },
+	{ "mrvl,usb-ehci", &decode_win_usb_setup, &decode_win_usb_dump },
+	{ "mrvl,sata", &decode_win_sata_setup, NULL },
+	{ "mrvl,xor", &decode_win_xor_setup, &decode_win_xor_dump },
+	{ "mrvl,idma", &decode_win_idma_setup, &decode_win_idma_dump },
+	{ "mrvl,pcie", &decode_win_pcie_setup, NULL },
+	{ NULL, NULL, NULL },
+};
+
+struct fdt_pm_mask_entry fdt_pm_mask_table[] = {
+	{ "mrvl,ge",		CPU_PM_CTRL_GE(0) },
+	{ "mrvl,ge",		CPU_PM_CTRL_GE(1) },
+	{ "mrvl,usb-ehci",	CPU_PM_CTRL_USB(0) },
+	{ "mrvl,usb-ehci",	CPU_PM_CTRL_USB(1) },
+	{ "mrvl,usb-ehci",	CPU_PM_CTRL_USB(2) },
+	{ "mrvl,xor",		CPU_PM_CTRL_XOR },
+	{ "mrvl,sata",		CPU_PM_CTRL_SATA },
+
+	{ NULL, 0 }
+};
+
+static __inline int
+pm_is_disabled(uint32_t mask)
+{
+#if defined(SOC_MV_KIRKWOOD)
+	return (soc_power_ctrl_get(mask) == mask);
+#else
+	return (soc_power_ctrl_get(mask) == mask ? 0 : 1);
+#endif
+}
+
+/*
+ * Disable device using power management register.
+ * 1 - Device Power On
+ * 0 - Device Power Off
+ * Mask can be set in loader.
+ * EXAMPLE:
+ * loader> set hw.pm-disable-mask=0x2
+ *
+ * Common mask:
+ * |-------------------------------|
+ * | Device | Kirkwood | Discovery |
+ * |-------------------------------|
+ * | USB0   | 0x00008  | 0x020000  |
+ * |-------------------------------|
+ * | USB1   |     -    | 0x040000  |
+ * |-------------------------------|
+ * | USB2   |     -    | 0x080000  |
+ * |-------------------------------|
+ * | GE0    | 0x00001  | 0x000002  |
+ * |-------------------------------|
+ * | GE1    |     -    | 0x000004  |
+ * |-------------------------------|
+ * | IDMA   |     -    | 0x100000  |
+ * |-------------------------------|
+ * | XOR    | 0x10000  | 0x200000  |
+ * |-------------------------------|
+ * | CESA   | 0x20000  | 0x400000  |
+ * |-------------------------------|
+ * | SATA   | 0x04000  | 0x004000  |
+ * --------------------------------|
+ * This feature can be used only on Kirkwood and Discovery
+ * machines.
+ */
+static __inline void
+pm_disable_device(int mask)
+{
+#ifdef DIAGNOSTIC
+	uint32_t reg;
+
+	reg = soc_power_ctrl_get(CPU_PM_CTRL_ALL);
+	printf("Power Management Register: 0%x\n", reg);
+
+	reg &= ~mask;
+	soc_power_ctrl_set(reg);
+	printf("Device %x is disabled\n", mask);
+
+	reg = soc_power_ctrl_get(CPU_PM_CTRL_ALL);
+	printf("Power Management Register: 0%x\n", reg);
+#endif
+}
+
+int
+fdt_pm(phandle_t node)
+{
+	uint32_t cpu_pm_ctrl;
+	int i, ena, compat;
+
+	ena = 1;
+	cpu_pm_ctrl = read_cpu_ctrl(CPU_PM_CTRL);
+	for (i = 0; fdt_pm_mask_table[i].compat != NULL; i++) {
+		if (dev_mask & (1 << i))
+			continue;
+
+		compat = fdt_is_compatible(node, fdt_pm_mask_table[i].compat);
+#if defined(SOC_MV_KIRKWOOD)
+		if (compat && (cpu_pm_ctrl & fdt_pm_mask_table[i].mask)) {
+			dev_mask |= (1 << i);
+			ena = 0;
+			break;
+		} else if (compat) {
+			dev_mask |= (1 << i);
+			break;
+		}
+#else
+		if (compat && (~cpu_pm_ctrl & fdt_pm_mask_table[i].mask)) {
+			dev_mask |= (1 << i);
+			ena = 0;
+			break;
+		} else if (compat) {
+			dev_mask |= (1 << i);
+			break;
+		}
+#endif
+	}
+
+	return (ena);
+}
+
+uint32_t
+read_cpu_ctrl(uint32_t reg)
+{
+
+	return (bus_space_read_4(fdtbus_bs_tag, MV_CPU_CONTROL_BASE, reg));
+}
+
+void
+write_cpu_ctrl(uint32_t reg, uint32_t val)
+{
+
+	bus_space_write_4(fdtbus_bs_tag, MV_CPU_CONTROL_BASE, reg, val);
+}
+
+#if defined(SOC_MV_ARMADAXP)
+uint32_t
+read_cpu_mp_clocks(uint32_t reg)
+{
+
+	return (bus_space_read_4(fdtbus_bs_tag, MV_MP_CLOCKS_BASE, reg));
+}
+
+void
+write_cpu_mp_clocks(uint32_t reg, uint32_t val)
+{
+
+	bus_space_write_4(fdtbus_bs_tag, MV_MP_CLOCKS_BASE, reg, val);
+}
+
+uint32_t
+read_cpu_misc(uint32_t reg)
+{
+
+	return (bus_space_read_4(fdtbus_bs_tag, MV_MISC_BASE, reg));
+}
+
+void
+write_cpu_misc(uint32_t reg, uint32_t val)
+{
+
+	bus_space_write_4(fdtbus_bs_tag, MV_MISC_BASE, reg, val);
+}
+#endif
+
+void
+cpu_reset(void)
+{
+
+#if defined(SOC_MV_ARMADAXP)
+	write_cpu_misc(RSTOUTn_MASK, SOFT_RST_OUT_EN);
+	write_cpu_misc(SYSTEM_SOFT_RESET, SYS_SOFT_RST);
+#else
+	write_cpu_ctrl(RSTOUTn_MASK, SOFT_RST_OUT_EN);
+	write_cpu_ctrl(SYSTEM_SOFT_RESET, SYS_SOFT_RST);
+#endif
+	while (1);
+}
+
+uint32_t
+cpu_extra_feat(void)
+{
+	uint32_t dev, rev;
+	uint32_t ef = 0;
+
+	soc_id(&dev, &rev);
+
+	switch (dev) {
+	case MV_DEV_88F6281:
+	case MV_DEV_88F6282:
+	case MV_DEV_88RC8180:
+	case MV_DEV_MV78100_Z0:
+	case MV_DEV_MV78100:
+		__asm __volatile("mrc p15, 1, %0, c15, c1, 0" : "=r" (ef));
+		break;
+	case MV_DEV_88F5182:
+	case MV_DEV_88F5281:
+		__asm __volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (ef));
+		break;
+	default:
+		if (bootverbose)
+			printf("This ARM Core does not support any extra features\n");
+	}
+
+	return (ef);
+}
+
+/*
+ * Get the power status of device. This feature is only supported on
+ * Kirkwood and Discovery SoCs.
+ */
+uint32_t
+soc_power_ctrl_get(uint32_t mask)
+{
+
+#if !defined(SOC_MV_ORION) && !defined(SOC_MV_LOKIPLUS) && !defined(SOC_MV_FREY)
+	if (mask != CPU_PM_CTRL_NONE)
+		mask &= read_cpu_ctrl(CPU_PM_CTRL);
+
+	return (mask);
+#else
+	return (mask);
+#endif
+}
+
+/*
+ * Set the power status of device. This feature is only supported on
+ * Kirkwood and Discovery SoCs.
+ */
+void
+soc_power_ctrl_set(uint32_t mask)
+{
+
+#if !defined(SOC_MV_ORION) && !defined(SOC_MV_LOKIPLUS)
+	if (mask != CPU_PM_CTRL_NONE)
+		write_cpu_ctrl(CPU_PM_CTRL, mask);
+#endif
+}
+
+void
+soc_id(uint32_t *dev, uint32_t *rev)
+{
+
+	/*
+	 * Notice: system identifiers are available in the registers range of
+	 * PCIE controller, so using this function is only allowed (and
+	 * possible) after the internal registers range has been mapped in via
+	 * pmap_devmap_bootstrap().
+	 */
+	*dev = bus_space_read_4(fdtbus_bs_tag, MV_PCIE_BASE, 0) >> 16;
+	*rev = bus_space_read_4(fdtbus_bs_tag, MV_PCIE_BASE, 8) & 0xff;
+}
+
+static void
+soc_identify(void)
+{
+	uint32_t d, r, size, mode;
+	const char *dev;
+	const char *rev;
+
+	soc_id(&d, &r);
+
+	printf("SOC: ");
+	if (bootverbose)
+		printf("(0x%4x:0x%02x) ", d, r);
+
+	rev = "";
+	switch (d) {
+	case MV_DEV_88F5181:
+		dev = "Marvell 88F5181";
+		if (r == 3)
+			rev = "B1";
+		break;
+	case MV_DEV_88F5182:
+		dev = "Marvell 88F5182";
+		if (r == 2)
+			rev = "A2";
+		break;
+	case MV_DEV_88F5281:
+		dev = "Marvell 88F5281";
+		if (r == 4)
+			rev = "D0";
+		else if (r == 5)
+			rev = "D1";
+		else if (r == 6)
+			rev = "D2";
+		break;
+	case MV_DEV_88F6281:
+		dev = "Marvell 88F6281";
+		if (r == 0)
+			rev = "Z0";
+		else if (r == 2)
+			rev = "A0";
+		else if (r == 3)
+			rev = "A1";
+		break;
+	case MV_DEV_88RC8180:
+		dev = "Marvell 88RC8180";
+		break;
+	case MV_DEV_88RC9480:
+		dev = "Marvell 88RC9480";
+		break;
+	case MV_DEV_88RC9580:
+		dev = "Marvell 88RC9580";
+		break;
+	case MV_DEV_88F6781:
+		dev = "Marvell 88F6781";
+		if (r == 2)
+			rev = "Y0";
+		break;
+	case MV_DEV_88F6282:
+		dev = "Marvell 88F6282";
+		if (r == 0)
+			rev = "A0";
+		else if (r == 1)
+			rev = "A1";
+		break;
+	case MV_DEV_MV78100_Z0:
+		dev = "Marvell MV78100 Z0";
+		break;
+	case MV_DEV_MV78100:
+		dev = "Marvell MV78100";
+		break;
+	case MV_DEV_MV78160:
+		dev = "Marvell MV78160";
+		break;
+	case MV_DEV_MV78260:
+		dev = "Marvell MV78260";
+		break;
+	case MV_DEV_MV78460:
+		dev = "Marvell MV78460";
+		break;
+	default:
+		dev = "UNKNOWN";
+		break;
+	}
+
+	printf("%s", dev);
+	if (*rev != '\0')
+		printf(" rev %s", rev);
+	printf(", TClock %dMHz\n", get_tclk() / 1000 / 1000);
+
+	mode = read_cpu_ctrl(CPU_CONFIG);
+	printf("  Instruction cache prefetch %s, data cache prefetch %s\n",
+	    (mode & CPU_CONFIG_IC_PREF) ? "enabled" : "disabled",
+	    (mode & CPU_CONFIG_DC_PREF) ? "enabled" : "disabled");
+
+	switch (d) {
+	case MV_DEV_88F6281:
+	case MV_DEV_88F6282:
+		mode = read_cpu_ctrl(CPU_L2_CONFIG) & CPU_L2_CONFIG_MODE;
+		printf("  256KB 4-way set-associative %s unified L2 cache\n",
+		    mode ? "write-through" : "write-back");
+		break;
+	case MV_DEV_MV78100:
+		mode = read_cpu_ctrl(CPU_CONTROL);
+		size = mode & CPU_CONTROL_L2_SIZE;
+		mode = mode & CPU_CONTROL_L2_MODE;
+		printf("  %s set-associative %s unified L2 cache\n",
+		    size ? "256KB 4-way" : "512KB 8-way",
+		    mode ? "write-through" : "write-back");
+		break;
+	default:
+		break;
+	}
+}
+
+static void
+platform_identify(void *dummy)
+{
+
+	soc_identify();
+
+	/*
+	 * XXX Board identification e.g. read out from FPGA or similar should
+	 * go here
+	 */
+}
+SYSINIT(platform_identify, SI_SUB_CPU, SI_ORDER_SECOND, platform_identify,
+    NULL);
+
+#ifdef KDB
+static void
+mv_enter_debugger(void *dummy)
+{
+
+	if (boothowto & RB_KDB)
+		kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger");
+}
+SYSINIT(mv_enter_debugger, SI_SUB_CPU, SI_ORDER_ANY, mv_enter_debugger, NULL);
+#endif
+
+int
+soc_decode_win(void)
+{
+	uint32_t dev, rev;
+	int mask, err;
+
+	mask = 0;
+	TUNABLE_INT_FETCH("hw.pm-disable-mask", &mask);
+
+	if (mask != 0)
+		pm_disable_device(mask);
+
+	/* Retrieve data about physical addresses from device tree. */
+	if ((err = win_cpu_from_dt()) != 0)
+		return (err);
+
+	/* Retrieve our ID: some windows facilities vary between SoC models */
+	soc_id(&dev, &rev);
+
+#ifdef SOC_MV_ARMADAXP
+	if ((err = decode_win_sdram_fixup()) != 0)
+		return(err);
+#endif
+
+#ifndef SOC_MV_FREY
+	if (!decode_win_cpu_valid() || !decode_win_usb_valid() ||
+	    !decode_win_eth_valid() || !decode_win_idma_valid() ||
+	    !decode_win_pcie_valid() || !decode_win_sata_valid() ||
+	    !decode_win_xor_valid())
+		return (EINVAL);
+
+	decode_win_cpu_setup();
+#else
+	if (!decode_win_usb_valid() ||
+	    !decode_win_eth_valid() || !decode_win_idma_valid() ||
+	    !decode_win_pcie_valid() || !decode_win_sata_valid() ||
+	    !decode_win_xor_valid())
+		return (EINVAL);
+#endif
+	if (MV_DUMP_WIN)
+		soc_dump_decode_win();
+
+	eth_port = 0;
+	usb_port = 0;
+	if ((err = fdt_win_setup()) != 0)
+		return (err);
+
+	return (0);
+}
+
+/**************************************************************************
+ * Decode windows registers accessors
+ **************************************************************************/
+#if !defined(SOC_MV_FREY)
+WIN_REG_IDX_RD(win_cpu, cr, MV_WIN_CPU_CTRL, MV_MBUS_BRIDGE_BASE)
+WIN_REG_IDX_RD(win_cpu, br, MV_WIN_CPU_BASE, MV_MBUS_BRIDGE_BASE)
+WIN_REG_IDX_RD(win_cpu, remap_l, MV_WIN_CPU_REMAP_LO, MV_MBUS_BRIDGE_BASE)
+WIN_REG_IDX_RD(win_cpu, remap_h, MV_WIN_CPU_REMAP_HI, MV_MBUS_BRIDGE_BASE)
+WIN_REG_IDX_WR(win_cpu, cr, MV_WIN_CPU_CTRL, MV_MBUS_BRIDGE_BASE)
+WIN_REG_IDX_WR(win_cpu, br, MV_WIN_CPU_BASE, MV_MBUS_BRIDGE_BASE)
+WIN_REG_IDX_WR(win_cpu, remap_l, MV_WIN_CPU_REMAP_LO, MV_MBUS_BRIDGE_BASE)
+WIN_REG_IDX_WR(win_cpu, remap_h, MV_WIN_CPU_REMAP_HI, MV_MBUS_BRIDGE_BASE)
+#endif
+
+WIN_REG_BASE_IDX_RD(win_usb, cr, MV_WIN_USB_CTRL)
+WIN_REG_BASE_IDX_RD(win_usb, br, MV_WIN_USB_BASE)
+WIN_REG_BASE_IDX_WR(win_usb, cr, MV_WIN_USB_CTRL)
+WIN_REG_BASE_IDX_WR(win_usb, br, MV_WIN_USB_BASE)
+
+WIN_REG_BASE_IDX_RD(win_eth, br, MV_WIN_ETH_BASE)
+WIN_REG_BASE_IDX_RD(win_eth, sz, MV_WIN_ETH_SIZE)
+WIN_REG_BASE_IDX_RD(win_eth, har, MV_WIN_ETH_REMAP)
+WIN_REG_BASE_IDX_WR(win_eth, br, MV_WIN_ETH_BASE)
+WIN_REG_BASE_IDX_WR(win_eth, sz, MV_WIN_ETH_SIZE)
+WIN_REG_BASE_IDX_WR(win_eth, har, MV_WIN_ETH_REMAP)
+
+WIN_REG_BASE_IDX_RD2(win_xor, br, MV_WIN_XOR_BASE)
+WIN_REG_BASE_IDX_RD2(win_xor, sz, MV_WIN_XOR_SIZE)
+WIN_REG_BASE_IDX_RD2(win_xor, har, MV_WIN_XOR_REMAP)
+WIN_REG_BASE_IDX_RD2(win_xor, ctrl, MV_WIN_XOR_CTRL)
+WIN_REG_BASE_IDX_WR2(win_xor, br, MV_WIN_XOR_BASE)
+WIN_REG_BASE_IDX_WR2(win_xor, sz, MV_WIN_XOR_SIZE)
+WIN_REG_BASE_IDX_WR2(win_xor, har, MV_WIN_XOR_REMAP)
+WIN_REG_BASE_IDX_WR2(win_xor, ctrl, MV_WIN_XOR_CTRL)
+
+WIN_REG_BASE_RD(win_eth, bare, 0x290)
+WIN_REG_BASE_RD(win_eth, epap, 0x294)
+WIN_REG_BASE_WR(win_eth, bare, 0x290)
+WIN_REG_BASE_WR(win_eth, epap, 0x294)
+
+WIN_REG_BASE_IDX_RD(win_pcie, cr, MV_WIN_PCIE_CTRL);
+WIN_REG_BASE_IDX_RD(win_pcie, br, MV_WIN_PCIE_BASE);
+WIN_REG_BASE_IDX_RD(win_pcie, remap, MV_WIN_PCIE_REMAP);
+WIN_REG_BASE_IDX_WR(win_pcie, cr, MV_WIN_PCIE_CTRL);
+WIN_REG_BASE_IDX_WR(win_pcie, br, MV_WIN_PCIE_BASE);
+WIN_REG_BASE_IDX_WR(win_pcie, remap, MV_WIN_PCIE_REMAP);
+WIN_REG_BASE_IDX_RD(pcie_bar, br, MV_PCIE_BAR_BASE);
+WIN_REG_BASE_IDX_WR(pcie_bar, br, MV_PCIE_BAR_BASE);
+WIN_REG_BASE_IDX_WR(pcie_bar, brh, MV_PCIE_BAR_BASE_H);
+WIN_REG_BASE_IDX_WR(pcie_bar, cr, MV_PCIE_BAR_CTRL);
+
+WIN_REG_BASE_IDX_RD(win_idma, br, MV_WIN_IDMA_BASE)
+WIN_REG_BASE_IDX_RD(win_idma, sz, MV_WIN_IDMA_SIZE)
+WIN_REG_BASE_IDX_RD(win_idma, har, MV_WIN_IDMA_REMAP)
+WIN_REG_BASE_IDX_RD(win_idma, cap, MV_WIN_IDMA_CAP)
+WIN_REG_BASE_IDX_WR(win_idma, br, MV_WIN_IDMA_BASE)
+WIN_REG_BASE_IDX_WR(win_idma, sz, MV_WIN_IDMA_SIZE)
+WIN_REG_BASE_IDX_WR(win_idma, har, MV_WIN_IDMA_REMAP)
+WIN_REG_BASE_IDX_WR(win_idma, cap, MV_WIN_IDMA_CAP)
+WIN_REG_BASE_RD(win_idma, bare, 0xa80)
+WIN_REG_BASE_WR(win_idma, bare, 0xa80)
+
+WIN_REG_BASE_IDX_RD(win_sata, cr, MV_WIN_SATA_CTRL);
+WIN_REG_BASE_IDX_RD(win_sata, br, MV_WIN_SATA_BASE);
+WIN_REG_BASE_IDX_WR(win_sata, cr, MV_WIN_SATA_CTRL);
+WIN_REG_BASE_IDX_WR(win_sata, br, MV_WIN_SATA_BASE);
+#ifndef SOC_MV_DOVE
+WIN_REG_IDX_RD(ddr, br, MV_WIN_DDR_BASE, MV_DDR_CADR_BASE)
+WIN_REG_IDX_RD(ddr, sz, MV_WIN_DDR_SIZE, MV_DDR_CADR_BASE)
+WIN_REG_IDX_WR(ddr, br, MV_WIN_DDR_BASE, MV_DDR_CADR_BASE)
+WIN_REG_IDX_WR(ddr, sz, MV_WIN_DDR_SIZE, MV_DDR_CADR_BASE)
+#else
+/*
+ * On 88F6781 (Dove) SoC DDR Controller is accessed through
+ * single MBUS <-> AXI bridge. In this case we provide emulated
+ * ddr_br_read() and ddr_sz_read() functions to keep compatibility
+ * with common decoding windows setup code.
+ */
+
+static inline uint32_t ddr_br_read(int i)
+{
+	uint32_t mmap;
+
+	/* Read Memory Address Map Register for CS i */
+	mmap = bus_space_read_4(fdtbus_bs_tag, MV_DDR_CADR_BASE + (i * 0x10), 0);
+
+	/* Return CS i base address */
+	return (mmap & 0xFF000000);
+}
+
+static inline uint32_t ddr_sz_read(int i)
+{
+	uint32_t mmap, size;
+
+	/* Read Memory Address Map Register for CS i */
+	mmap = bus_space_read_4(fdtbus_bs_tag, MV_DDR_CADR_BASE + (i * 0x10), 0);
+
+	/* Extract size of CS space in 64kB units */
+	size = (1 << ((mmap >> 16) & 0x0F));
+
+	/* Return CS size and enable/disable status */
+	return (((size - 1) << 16) | (mmap & 0x01));
+}
+#endif
+
+#if !defined(SOC_MV_FREY)
+/**************************************************************************
+ * Decode windows helper routines
+ **************************************************************************/
+void
+soc_dump_decode_win(void)
+{
+	uint32_t dev, rev;
+	int i;
+
+	soc_id(&dev, &rev);
+
+	for (i = 0; i < MV_WIN_CPU_MAX; i++) {
+		printf("CPU window#%d: c 0x%08x, b 0x%08x", i,
+		    win_cpu_cr_read(i),
+		    win_cpu_br_read(i));
+
+		if (win_cpu_can_remap(i))
+			printf(", rl 0x%08x, rh 0x%08x",
+			    win_cpu_remap_l_read(i),
+			    win_cpu_remap_h_read(i));
+
+		printf("\n");
+	}
+	printf("Internal regs base: 0x%08x\n",
+	    bus_space_read_4(fdtbus_bs_tag, MV_INTREGS_BASE, 0));
+
+	for (i = 0; i < MV_WIN_DDR_MAX; i++)
+		printf("DDR CS#%d: b 0x%08x, s 0x%08x\n", i,
+		    ddr_br_read(i), ddr_sz_read(i));
+}
+
+/**************************************************************************
+ * CPU windows routines
+ **************************************************************************/
+int
+win_cpu_can_remap(int i)
+{
+	uint32_t dev, rev;
+
+	soc_id(&dev, &rev);
+
+	/* Depending on the SoC certain windows have remap capability */
+	if ((dev == MV_DEV_88F5182 && i < 2) ||
+	    (dev == MV_DEV_88F5281 && i < 4) ||
+	    (dev == MV_DEV_88F6281 && i < 4) ||
+	    (dev == MV_DEV_88F6282 && i < 4) ||
+	    (dev == MV_DEV_88RC8180 && i < 2) ||
+	    (dev == MV_DEV_88F6781 && i < 4) ||
+	    (dev == MV_DEV_MV78100_Z0 && i < 8) ||
+	    ((dev & MV_DEV_FAMILY_MASK) == MV_DEV_DISCOVERY && i < 8))
+		return (1);
+
+	return (0);
+}
+
+/* XXX This should check for overlapping remap fields too.. */
+int
+decode_win_overlap(int win, int win_no, const struct decode_win *wintab)
+{
+	const struct decode_win *tab;
+	int i;
+
+	tab = wintab;
+
+	for (i = 0; i < win_no; i++, tab++) {
+		if (i == win)
+			/* Skip self */
+			continue;
+
+		if ((tab->base + tab->size - 1) < (wintab + win)->base)
+			continue;
+
+		else if (((wintab + win)->base + (wintab + win)->size - 1) <
+		    tab->base)
+			continue;
+		else
+			return (i);
+	}
+
+	return (-1);
+}
+
+static int
+decode_win_cpu_valid(void)
+{
+	int i, j, rv;
+	uint32_t b, e, s;
+
+	if (cpu_wins_no > MV_WIN_CPU_MAX) {
+		printf("CPU windows: too many entries: %d\n", cpu_wins_no);
+		return (0);
+	}
+
+	rv = 1;
+	for (i = 0; i < cpu_wins_no; i++) {
+
+		if (cpu_wins[i].target == 0) {
+			printf("CPU window#%d: DDR target window is not "
+			    "supposed to be reprogrammed!\n", i);
+			rv = 0;
+		}
+
+		if (cpu_wins[i].remap != ~0 && win_cpu_can_remap(i) != 1) {
+			printf("CPU window#%d: not capable of remapping, but "
+			    "val 0x%08x defined\n", i, cpu_wins[i].remap);
+			rv = 0;
+		}
+
+		s = cpu_wins[i].size;
+		b = cpu_wins[i].base;
+		e = b + s - 1;
+		if (s > (0xFFFFFFFF - b + 1)) {
+			/*
+			 * XXX this boundary check should account for 64bit
+			 * and remapping..
+			 */
+			printf("CPU window#%d: no space for size 0x%08x at "
+			    "0x%08x\n", i, s, b);
+			rv = 0;
+			continue;
+		}
+
+		if (b != (b & ~(s - 1))) {
+			printf("CPU window#%d: address 0x%08x is not aligned "
+			    "to 0x%08x\n", i, b, s);
+			rv = 0;
+			continue;
+		}
+
+		j = decode_win_overlap(i, cpu_wins_no, &cpu_wins[0]);
+		if (j >= 0) {
+			printf("CPU window#%d: (0x%08x - 0x%08x) overlaps "
+			    "with #%d (0x%08x - 0x%08x)\n", i, b, e, j,
+			    cpu_wins[j].base,
+			    cpu_wins[j].base + cpu_wins[j].size - 1);
+			rv = 0;
+		}
+	}
+
+	return (rv);
+}
+
+int
+decode_win_cpu_set(int target, int attr, vm_paddr_t base, uint32_t size,
+    vm_paddr_t remap)
+{
+	uint32_t br, cr;
+	int win, i;
+
+	if (remap == ~0) {
+		win = MV_WIN_CPU_MAX - 1;
+		i = -1;
+	} else {
+		win = 0;
+		i = 1;
+	}
+
+	while ((win >= 0) && (win < MV_WIN_CPU_MAX)) {
+		cr = win_cpu_cr_read(win);
+		if ((cr & MV_WIN_CPU_ENABLE_BIT) == 0)
+			break;
+		if ((cr & ((0xff << MV_WIN_CPU_ATTR_SHIFT) |
+		    (0x1f << MV_WIN_CPU_TARGET_SHIFT))) ==
+		    ((attr << MV_WIN_CPU_ATTR_SHIFT) |
+		    (target << MV_WIN_CPU_TARGET_SHIFT)))
+			break;
+		win += i;
+	}
+	if ((win < 0) || (win >= MV_WIN_CPU_MAX) ||
+	    ((remap != ~0) && (win_cpu_can_remap(win) == 0)))
+		return (-1);
+
+	br = base & 0xffff0000;
+	win_cpu_br_write(win, br);
+
+	if (win_cpu_can_remap(win)) {
+		if (remap != ~0) {
+			win_cpu_remap_l_write(win, remap & 0xffff0000);
+			win_cpu_remap_h_write(win, 0);
+		} else {
+			/*
+			 * Remap function is not used for a given window
+			 * (capable of remapping) - set remap field with the
+			 * same value as base.
+			 */
+			win_cpu_remap_l_write(win, base & 0xffff0000);
+			win_cpu_remap_h_write(win, 0);
+		}
+	}
+
+	cr = ((size - 1) & 0xffff0000) | (attr << MV_WIN_CPU_ATTR_SHIFT) |
+	    (target << MV_WIN_CPU_TARGET_SHIFT) | MV_WIN_CPU_ENABLE_BIT;
+	win_cpu_cr_write(win, cr);
+
+	return (0);
+}
+
+static void
+decode_win_cpu_setup(void)
+{
+	int i;
+
+	/* Disable all CPU windows */
+	for (i = 0; i < MV_WIN_CPU_MAX; i++) {
+		win_cpu_cr_write(i, 0);
+		win_cpu_br_write(i, 0);
+		if (win_cpu_can_remap(i)) {
+			win_cpu_remap_l_write(i, 0);
+			win_cpu_remap_h_write(i, 0);
+		}
+	}
+
+	for (i = 0; i < cpu_wins_no; i++)
+		if (cpu_wins[i].target > 0)
+			decode_win_cpu_set(cpu_wins[i].target,
+			    cpu_wins[i].attr, cpu_wins[i].base,
+			    cpu_wins[i].size, cpu_wins[i].remap);
+
+}
+#endif
+
+#ifdef SOC_MV_ARMADAXP
+static int
+decode_win_sdram_fixup(void)
+{
+	struct mem_region mr[FDT_MEM_REGIONS];
+	uint8_t window_valid[MV_WIN_DDR_MAX];
+	int mr_cnt, memsize, err, i, j;
+	uint32_t valid_win_num = 0;
+
+	/* Grab physical memory regions information from device tree. */
+	err = fdt_get_mem_regions(mr, &mr_cnt, &memsize);
+	if (err != 0)
+		return (err);
+
+	for (i = 0; i < MV_WIN_DDR_MAX; i++)
+		window_valid[i] = 0;
+
+	/* Try to match entries from device tree with settings from u-boot */
+	for (i = 0; i < mr_cnt; i++) {
+		for (j = 0; j < MV_WIN_DDR_MAX; j++) {
+			if (ddr_is_active(j) &&
+			    (ddr_base(j) == mr[i].mr_start) &&
+			    (ddr_size(j) == mr[i].mr_size)) {
+				window_valid[j] = 1;
+				valid_win_num++;
+			}
+		}
+	}
+
+	if (mr_cnt != valid_win_num)
+		return (EINVAL);
+
+	/* Destroy windows without corresponding device tree entry */
+	for (j = 0; j < MV_WIN_DDR_MAX; j++) {
+		if (ddr_is_active(j) && (window_valid[j] != 1)) {
+			printf("Disabling SDRAM decoding window: %d\n", j);
+			ddr_disable(j);
+		}
+	}
+
+	return (0);
+}
+#endif
+/*
+ * Check if we're able to cover all active DDR banks.
+ */
+static int
+decode_win_can_cover_ddr(int max)
+{
+	int i, c;
+
+	c = 0;
+	for (i = 0; i < MV_WIN_DDR_MAX; i++)
+		if (ddr_is_active(i))
+			c++;
+
+	if (c > max) {
+		printf("Unable to cover all active DDR banks: "
+		    "%d, available windows: %d\n", c, max);
+		return (0);
+	}
+
+	return (1);
+}
+
+/**************************************************************************
+ * DDR windows routines
+ **************************************************************************/
+int
+ddr_is_active(int i)
+{
+
+	if (ddr_sz_read(i) & 0x1)
+		return (1);
+
+	return (0);
+}
+
+void
+ddr_disable(int i)
+{
+
+	ddr_sz_write(i, 0);
+	ddr_br_write(i, 0);
+}
+
+uint32_t
+ddr_base(int i)
+{
+
+	return (ddr_br_read(i) & 0xff000000);
+}
+
+uint32_t
+ddr_size(int i)
+{
+
+	return ((ddr_sz_read(i) | 0x00ffffff) + 1);
+}
+
+uint32_t
+ddr_attr(int i)
+{
+	uint32_t dev, rev;
+
+	soc_id(&dev, &rev);
+	if (dev == MV_DEV_88RC8180)
+		return ((ddr_sz_read(i) & 0xf0) >> 4);
+	if (dev == MV_DEV_88F6781)
+		return (0);
+
+	return (i == 0 ? 0xe :
+	    (i == 1 ? 0xd :
+	    (i == 2 ? 0xb :
+	    (i == 3 ? 0x7 : 0xff))));
+}
+
+uint32_t
+ddr_target(int i)
+{
+	uint32_t dev, rev;
+
+	soc_id(&dev, &rev);
+	if (dev == MV_DEV_88RC8180) {
+		i = (ddr_sz_read(i) & 0xf0) >> 4;
+		return (i == 0xe ? 0xc :
+		    (i == 0xd ? 0xd :
+		    (i == 0xb ? 0xe :
+		    (i == 0x7 ? 0xf : 0xc))));
+	}
+
+	/*
+	 * On SOCs other than 88RC8180 Mbus unit ID for
+	 * DDR SDRAM controller is always 0x0.
+	 */
+	return (0);
+}
+
+/**************************************************************************
+ * USB windows routines
+ **************************************************************************/
+static int
+decode_win_usb_valid(void)
+{
+
+	return (decode_win_can_cover_ddr(MV_WIN_USB_MAX));
+}
+
+static void
+decode_win_usb_dump(u_long base)
+{
+	int i;
+
+	if (pm_is_disabled(CPU_PM_CTRL_USB(usb_port - 1)))
+		return;
+
+	for (i = 0; i < MV_WIN_USB_MAX; i++)
+		printf("USB window#%d: c 0x%08x, b 0x%08x\n", i,
+		    win_usb_cr_read(base, i), win_usb_br_read(base, i));
+}
+
+/*
+ * Set USB decode windows.
+ */
+static void
+decode_win_usb_setup(u_long base)
+{
+	uint32_t br, cr;
+	int i, j;
+
+
+	if (pm_is_disabled(CPU_PM_CTRL_USB(usb_port)))
+		return;
+
+	usb_port++;
+
+	for (i = 0; i < MV_WIN_USB_MAX; i++) {
+		win_usb_cr_write(base, i, 0);
+		win_usb_br_write(base, i, 0);
+	}
+
+	/* Only access to active DRAM banks is required */
+	for (i = 0; i < MV_WIN_DDR_MAX; i++) {
+		if (ddr_is_active(i)) {
+			br = ddr_base(i);
+			/*
+			 * XXX for 6281 we should handle Mbus write
+			 * burst limit field in the ctrl reg
+			 */
+			cr = (((ddr_size(i) - 1) & 0xffff0000) |
+			    (ddr_attr(i) << 8) |
+			    (ddr_target(i) << 4) | 1);
+
+			/* Set the first free USB window */
+			for (j = 0; j < MV_WIN_USB_MAX; j++) {
+				if (win_usb_cr_read(base, j) & 0x1)
+					continue;
+
+				win_usb_br_write(base, j, br);
+				win_usb_cr_write(base, j, cr);
+				break;
+			}
+		}
+	}
+}
+
+/**************************************************************************
+ * ETH windows routines
+ **************************************************************************/
+
+static int
+win_eth_can_remap(int i)
+{
+
+	/* ETH encode windows 0-3 have remap capability */
+	if (i < 4)
+		return (1);
+
+	return (0);
+}
+
+static int
+eth_bare_read(uint32_t base, int i)
+{
+	uint32_t v;
+
+	v = win_eth_bare_read(base);
+	v &= (1 << i);
+
+	return (v >> i);
+}
+
+static void
+eth_bare_write(uint32_t base, int i, int val)
+{
+	uint32_t v;
+
+	v = win_eth_bare_read(base);
+	v &= ~(1 << i);
+	v |= (val << i);
+	win_eth_bare_write(base, v);
+}
+
+static void
+eth_epap_write(uint32_t base, int i, int val)
+{
+	uint32_t v;
+
+	v = win_eth_epap_read(base);
+	v &= ~(0x3 << (i * 2));
+	v |= (val << (i * 2));
+	win_eth_epap_write(base, v);
+}
+
+static void
+decode_win_eth_dump(u_long base)
+{
+	int i;
+
+	if (pm_is_disabled(CPU_PM_CTRL_GE(eth_port - 1)))
+		return;
+
+	for (i = 0; i < MV_WIN_ETH_MAX; i++) {
+		printf("ETH window#%d: b 0x%08x, s 0x%08x", i,
+		    win_eth_br_read(base, i),
+		    win_eth_sz_read(base, i));
+
+		if (win_eth_can_remap(i))
+			printf(", ha 0x%08x",
+			    win_eth_har_read(base, i));
+
+		printf("\n");
+	}
+	printf("ETH windows: bare 0x%08x, epap 0x%08x\n",
+	    win_eth_bare_read(base),
+	    win_eth_epap_read(base));
+}
+
+#if defined(SOC_MV_LOKIPLUS)
+#define MV_WIN_ETH_DDR_TRGT(n)	0
+#else
+#define MV_WIN_ETH_DDR_TRGT(n)	ddr_target(n)
+#endif
+
+static void
+decode_win_eth_setup(u_long base)
+{
+	uint32_t br, sz;
+	int i, j;
+
+	if (pm_is_disabled(CPU_PM_CTRL_GE(eth_port)))
+		return;
+
+	eth_port++;
+
+	/* Disable, clear and revoke protection for all ETH windows */
+	for (i = 0; i < MV_WIN_ETH_MAX; i++) {
+
+		eth_bare_write(base, i, 1);
+		eth_epap_write(base, i, 0);
+		win_eth_br_write(base, i, 0);
+		win_eth_sz_write(base, i, 0);
+		if (win_eth_can_remap(i))
+			win_eth_har_write(base, i, 0);
+	}
+
+	/* Only access to active DRAM banks is required */
+	for (i = 0; i < MV_WIN_DDR_MAX; i++)
+		if (ddr_is_active(i)) {
+
+			br = ddr_base(i) | (ddr_attr(i) << 8) | MV_WIN_ETH_DDR_TRGT(i);
+			sz = ((ddr_size(i) - 1) & 0xffff0000);
+
+			/* Set the first free ETH window */
+			for (j = 0; j < MV_WIN_ETH_MAX; j++) {
+				if (eth_bare_read(base, j) == 0)
+					continue;
+
+				win_eth_br_write(base, j, br);
+				win_eth_sz_write(base, j, sz);
+
+				/* XXX remapping ETH windows not supported */
+
+				/* Set protection RW */
+				eth_epap_write(base, j, 0x3);
+
+				/* Enable window */
+				eth_bare_write(base, j, 0);
+				break;
+			}
+		}
+}
+
+static int
+decode_win_eth_valid(void)
+{
+
+	return (decode_win_can_cover_ddr(MV_WIN_ETH_MAX));
+}
+
+/**************************************************************************
+ * PCIE windows routines
+ **************************************************************************/
+
+void
+decode_win_pcie_setup(u_long base)
+{
+	uint32_t size = 0, ddrbase = ~0;
+	uint32_t cr, br;
+	int i, j;
+
+	for (i = 0; i < MV_PCIE_BAR_MAX; i++) {
+		pcie_bar_br_write(base, i,
+		    MV_PCIE_BAR_64BIT | MV_PCIE_BAR_PREFETCH_EN);
+		if (i < 3)
+			pcie_bar_brh_write(base, i, 0);
+		if (i > 0)
+			pcie_bar_cr_write(base, i, 0);
+	}
+
+	for (i = 0; i < MV_WIN_PCIE_MAX; i++) {
+		win_pcie_cr_write(base, i, 0);
+		win_pcie_br_write(base, i, 0);
+		win_pcie_remap_write(base, i, 0);
+	}
+
+	/* On End-Point only set BAR size to 1MB regardless of DDR size */
+	if ((bus_space_read_4(fdtbus_bs_tag, base, MV_PCIE_CONTROL)
+	    & MV_PCIE_ROOT_CMPLX) == 0) {
+		pcie_bar_cr_write(base, 1, 0xf0000 | 1);
+		return;
+	}
+
+	for (i = 0; i < MV_WIN_DDR_MAX; i++) {
+		if (ddr_is_active(i)) {
+			/* Map DDR to BAR 1 */
+			cr = (ddr_size(i) - 1) & 0xffff0000;
+			size += ddr_size(i) & 0xffff0000;
+			cr |= (ddr_attr(i) << 8) | (ddr_target(i) << 4) | 1;
+			br = ddr_base(i);
+			if (br < ddrbase)
+				ddrbase = br;
+
+			/* Use the first available PCIE window */
+			for (j = 0; j < MV_WIN_PCIE_MAX; j++) {
+				if (win_pcie_cr_read(base, j) != 0)
+					continue;
+
+				win_pcie_br_write(base, j, br);
+				win_pcie_cr_write(base, j, cr);
+				break;
+			}
+		}
+	}
+
+	/*
+	 * Upper 16 bits in BAR register is interpreted as BAR size
+	 * (in 64 kB units) plus 64kB, so substract 0x10000
+	 * form value passed to register to get correct value.
+	 */
+	size -= 0x10000;
+	pcie_bar_cr_write(base, 1, size | 1);
+	pcie_bar_br_write(base, 1, ddrbase |
+	    MV_PCIE_BAR_64BIT | MV_PCIE_BAR_PREFETCH_EN);
+	pcie_bar_br_write(base, 0, fdt_immr_pa |
+	    MV_PCIE_BAR_64BIT | MV_PCIE_BAR_PREFETCH_EN);
+}
+
+static int
+decode_win_pcie_valid(void)
+{
+
+	return (decode_win_can_cover_ddr(MV_WIN_PCIE_MAX));
+}
+
+/**************************************************************************
+ * IDMA windows routines
+ **************************************************************************/
+#if defined(SOC_MV_ORION) || defined(SOC_MV_DISCOVERY)
+static int
+idma_bare_read(u_long base, int i)
+{
+	uint32_t v;
+
+	v = win_idma_bare_read(base);
+	v &= (1 << i);
+
+	return (v >> i);
+}
+
+static void
+idma_bare_write(u_long base, int i, int val)
+{
+	uint32_t v;
+
+	v = win_idma_bare_read(base);
+	v &= ~(1 << i);
+	v |= (val << i);
+	win_idma_bare_write(base, v);
+}
+
+/*
+ * Sets channel protection 'val' for window 'w' on channel 'c'
+ */
+static void
+idma_cap_write(u_long base, int c, int w, int val)
+{
+	uint32_t v;
+
+	v = win_idma_cap_read(base, c);
+	v &= ~(0x3 << (w * 2));
+	v |= (val << (w * 2));
+	win_idma_cap_write(base, c, v);
+}
+
+/*
+ * Set protection 'val' on all channels for window 'w'
+ */
+static void
+idma_set_prot(u_long base, int w, int val)
+{
+	int c;
+
+	for (c = 0; c < MV_IDMA_CHAN_MAX; c++)
+		idma_cap_write(base, c, w, val);
+}
+
+static int
+win_idma_can_remap(int i)
+{
+
+	/* IDMA decode windows 0-3 have remap capability */
+	if (i < 4)
+		return (1);
+
+	return (0);
+}
+
+void
+decode_win_idma_setup(u_long base)
+{
+	uint32_t br, sz;
+	int i, j;
+
+	if (pm_is_disabled(CPU_PM_CTRL_IDMA))
+		return;
+	/*
+	 * Disable and clear all IDMA windows, revoke protection for all channels
+	 */
+	for (i = 0; i < MV_WIN_IDMA_MAX; i++) {
+
+		idma_bare_write(base, i, 1);
+		win_idma_br_write(base, i, 0);
+		win_idma_sz_write(base, i, 0);
+		if (win_idma_can_remap(i) == 1)
+			win_idma_har_write(base, i, 0);
+	}
+	for (i = 0; i < MV_IDMA_CHAN_MAX; i++)
+		win_idma_cap_write(base, i, 0);
+
+	/*
+	 * Set up access to all active DRAM banks
+	 */
+	for (i = 0; i < MV_WIN_DDR_MAX; i++)
+		if (ddr_is_active(i)) {
+			br = ddr_base(i) | (ddr_attr(i) << 8) | ddr_target(i);
+			sz = ((ddr_size(i) - 1) & 0xffff0000);
+
+			/* Place DDR entries in non-remapped windows */
+			for (j = 0; j < MV_WIN_IDMA_MAX; j++)
+				if (win_idma_can_remap(j) != 1 &&
+				    idma_bare_read(base, j) == 1) {
+
+					/* Configure window */
+					win_idma_br_write(base, j, br);
+					win_idma_sz_write(base, j, sz);
+
+					/* Set protection RW on all channels */
+					idma_set_prot(base, j, 0x3);
+
+					/* Enable window */
+					idma_bare_write(base, j, 0);
+					break;
+				}
+		}
+
+	/*
+	 * Remaining targets -- from statically defined table
+	 */
+	for (i = 0; i < idma_wins_no; i++)
+		if (idma_wins[i].target > 0) {
+			br = (idma_wins[i].base & 0xffff0000) |
+			    (idma_wins[i].attr << 8) | idma_wins[i].target;
+			sz = ((idma_wins[i].size - 1) & 0xffff0000);
+
+			/* Set the first free IDMA window */
+			for (j = 0; j < MV_WIN_IDMA_MAX; j++) {
+				if (idma_bare_read(base, j) == 0)
+					continue;
+
+				/* Configure window */
+				win_idma_br_write(base, j, br);
+				win_idma_sz_write(base, j, sz);
+				if (win_idma_can_remap(j) &&
+				    idma_wins[j].remap >= 0)
+					win_idma_har_write(base, j,
+					    idma_wins[j].remap);
+
+				/* Set protection RW on all channels */
+				idma_set_prot(base, j, 0x3);
+
+				/* Enable window */
+				idma_bare_write(base, j, 0);
+				break;
+			}
+		}
+}
+
+int
+decode_win_idma_valid(void)
+{
+	const struct decode_win *wintab;
+	int c, i, j, rv;
+	uint32_t b, e, s;
+
+	if (idma_wins_no > MV_WIN_IDMA_MAX) {
+		printf("IDMA windows: too many entries: %d\n", idma_wins_no);
+		return (0);
+	}
+	for (i = 0, c = 0; i < MV_WIN_DDR_MAX; i++)
+		if (ddr_is_active(i))
+			c++;
+
+	if (idma_wins_no > (MV_WIN_IDMA_MAX - c)) {
+		printf("IDMA windows: too many entries: %d, available: %d\n",
+		    idma_wins_no, MV_WIN_IDMA_MAX - c);
+		return (0);
+	}
+
+	wintab = idma_wins;
+	rv = 1;
+	for (i = 0; i < idma_wins_no; i++, wintab++) {
+
+		if (wintab->target == 0) {
+			printf("IDMA window#%d: DDR target window is not "
+			    "supposed to be reprogrammed!\n", i);
+			rv = 0;
+		}
+
+		if (wintab->remap >= 0 && win_cpu_can_remap(i) != 1) {
+			printf("IDMA window#%d: not capable of remapping, but "
+			    "val 0x%08x defined\n", i, wintab->remap);
+			rv = 0;
+		}
+
+		s = wintab->size;
+		b = wintab->base;
+		e = b + s - 1;
+		if (s > (0xFFFFFFFF - b + 1)) {
+			/* XXX this boundary check should account for 64bit and
+			 * remapping.. */
+			printf("IDMA window#%d: no space for size 0x%08x at "
+			    "0x%08x\n", i, s, b);
+			rv = 0;
+			continue;
+		}
+
+		j = decode_win_overlap(i, idma_wins_no, &idma_wins[0]);
+		if (j >= 0) {
+			printf("IDMA window#%d: (0x%08x - 0x%08x) overlaps "
+			    "with #%d (0x%08x - 0x%08x)\n", i, b, e, j,
+			    idma_wins[j].base,
+			    idma_wins[j].base + idma_wins[j].size - 1);
+			rv = 0;
+		}
+	}
+
+	return (rv);
+}
+
+void
+decode_win_idma_dump(u_long base)
+{
+	int i;
+
+	if (pm_is_disabled(CPU_PM_CTRL_IDMA))
+		return;
+
+	for (i = 0; i < MV_WIN_IDMA_MAX; i++) {
+		printf("IDMA window#%d: b 0x%08x, s 0x%08x", i,
+		    win_idma_br_read(base, i), win_idma_sz_read(base, i));
+		
+		if (win_idma_can_remap(i))
+			printf(", ha 0x%08x", win_idma_har_read(base, i));
+
+		printf("\n");
+	}
+	for (i = 0; i < MV_IDMA_CHAN_MAX; i++)
+		printf("IDMA channel#%d: ap 0x%08x\n", i,
+		    win_idma_cap_read(base, i));
+	printf("IDMA windows: bare 0x%08x\n", win_idma_bare_read(base));
+}
+#else
+
+/* Provide dummy functions to satisfy the build for SoCs not equipped with IDMA */
+int
+decode_win_idma_valid(void)
+{
+
+	return (1);
+}
+
+void
+decode_win_idma_setup(u_long base)
+{
+}
+
+void
+decode_win_idma_dump(u_long base)
+{
+}
+#endif
+
+/**************************************************************************
+ * XOR windows routines
+ **************************************************************************/
+#if defined(SOC_MV_KIRKWOOD) || defined(SOC_MV_DISCOVERY)
+static int
+xor_ctrl_read(u_long base, int i, int c, int e)
+{
+	uint32_t v;
+	v = win_xor_ctrl_read(base, c, e);
+	v &= (1 << i);
+
+	return (v >> i);
+}
+
+static void
+xor_ctrl_write(u_long base, int i, int c, int e, int val)
+{
+	uint32_t v;
+
+	v = win_xor_ctrl_read(base, c, e);
+	v &= ~(1 << i);
+	v |= (val << i);
+	win_xor_ctrl_write(base, c, e, v);
+}
+
+/*
+ * Set channel protection 'val' for window 'w' on channel 'c'
+ */
+static void
+xor_chan_write(u_long base, int c, int e, int w, int val)
+{
+	uint32_t v;
+
+	v = win_xor_ctrl_read(base, c, e);
+	v &= ~(0x3 << (w * 2 + 16));
+	v |= (val << (w * 2 + 16));
+	win_xor_ctrl_write(base, c, e, v);
+}
+
+/*
+ * Set protection 'val' on all channels for window 'w' on engine 'e'
+ */
+static void
+xor_set_prot(u_long base, int w, int e, int val)
+{
+	int c;
+
+	for (c = 0; c < MV_XOR_CHAN_MAX; c++)
+		xor_chan_write(base, c, e, w, val);
+}
+
+static int
+win_xor_can_remap(int i)
+{
+
+	/* XOR decode windows 0-3 have remap capability */
+	if (i < 4)
+		return (1);
+
+	return (0);
+}
+
+static int
+xor_max_eng(void)
+{
+	uint32_t dev, rev;
+
+	soc_id(&dev, &rev);
+	switch (dev) {
+	case MV_DEV_88F6281:
+	case MV_DEV_88F6282:
+	case MV_DEV_MV78130:
+	case MV_DEV_MV78160:
+	case MV_DEV_MV78230:
+	case MV_DEV_MV78260:
+	case MV_DEV_MV78460:
+		return (2);
+	case MV_DEV_MV78100:
+	case MV_DEV_MV78100_Z0:
+		return (1);
+	default:
+		return (0);
+	}
+}
+
+static void
+xor_active_dram(u_long base, int c, int e, int *window)
+{
+	uint32_t br, sz;
+	int i, m, w;
+
+	/*
+	 * Set up access to all active DRAM banks
+	 */
+	m = xor_max_eng();
+	for (i = 0; i < m; i++)
+		if (ddr_is_active(i)) {
+			br = ddr_base(i) | (ddr_attr(i) << 8) |
+			    ddr_target(i);
+			sz = ((ddr_size(i) - 1) & 0xffff0000);
+
+			/* Place DDR entries in non-remapped windows */
+			for (w = 0; w < MV_WIN_XOR_MAX; w++)
+				if (win_xor_can_remap(w) != 1 &&
+				    (xor_ctrl_read(base, w, c, e) == 0) &&
+				    w > *window) {
+					/* Configure window */
+					win_xor_br_write(base, w, e, br);
+					win_xor_sz_write(base, w, e, sz);
+
+					/* Set protection RW on all channels */
+					xor_set_prot(base, w, e, 0x3);
+
+					/* Enable window */
+					xor_ctrl_write(base, w, c, e, 1);
+					(*window)++;
+					break;
+				}
+		}
+}
+
+void
+decode_win_xor_setup(u_long base)
+{
+	uint32_t br, sz;
+	int i, j, z, e = 1, m, window;
+
+	if (pm_is_disabled(CPU_PM_CTRL_XOR))
+		return;
+
+	/*
+	 * Disable and clear all XOR windows, revoke protection for all
+	 * channels
+	 */
+	m = xor_max_eng();
+	for (j = 0; j < m; j++, e--) {
+
+		/* Number of non-remaped windows */
+		window = MV_XOR_NON_REMAP - 1;
+
+		for (i = 0; i < MV_WIN_XOR_MAX; i++) {
+			win_xor_br_write(base, i, e, 0);
+			win_xor_sz_write(base, i, e, 0);
+		}
+
+		if (win_xor_can_remap(i) == 1)
+			win_xor_har_write(base, i, e, 0);
+
+		for (i = 0; i < MV_XOR_CHAN_MAX; i++) {
+			win_xor_ctrl_write(base, i, e, 0);
+			xor_active_dram(base, i, e, &window);
+		}
+
+		/*
+		 * Remaining targets -- from a statically defined table
+		 */
+		for (i = 0; i < xor_wins_no; i++)
+			if (xor_wins[i].target > 0) {
+				br = (xor_wins[i].base & 0xffff0000) |
+				    (xor_wins[i].attr << 8) |
+				    xor_wins[i].target;
+				sz = ((xor_wins[i].size - 1) & 0xffff0000);
+
+				/* Set the first free XOR window */
+				for (z = 0; z < MV_WIN_XOR_MAX; z++) {
+					if (xor_ctrl_read(base, z, 0, e) &&
+					    xor_ctrl_read(base, z, 1, e))
+						continue;
+
+					/* Configure window */
+					win_xor_br_write(base, z, e, br);
+					win_xor_sz_write(base, z, e, sz);
+					if (win_xor_can_remap(z) &&
+					    xor_wins[z].remap >= 0)
+						win_xor_har_write(base, z, e,
+						    xor_wins[z].remap);
+
+					/* Set protection RW on all channels */
+					xor_set_prot(base, z, e, 0x3);
+
+					/* Enable window */
+					xor_ctrl_write(base, z, 0, e, 1);
+					xor_ctrl_write(base, z, 1, e, 1);
+					break;
+				}
+			}
+	}
+}
+
+int
+decode_win_xor_valid(void)
+{
+	const struct decode_win *wintab;
+	int c, i, j, rv;
+	uint32_t b, e, s;
+
+	if (xor_wins_no > MV_WIN_XOR_MAX) {
+		printf("XOR windows: too many entries: %d\n", xor_wins_no);
+		return (0);
+	}
+	for (i = 0, c = 0; i < MV_WIN_DDR_MAX; i++)
+		if (ddr_is_active(i))
+			c++;
+
+	if (xor_wins_no > (MV_WIN_XOR_MAX - c)) {
+		printf("XOR windows: too many entries: %d, available: %d\n",
+		    xor_wins_no, MV_WIN_IDMA_MAX - c);
+		return (0);
+	}
+
+	wintab = xor_wins;
+	rv = 1;
+	for (i = 0; i < xor_wins_no; i++, wintab++) {
+
+		if (wintab->target == 0) {
+			printf("XOR window#%d: DDR target window is not "
+			    "supposed to be reprogrammed!\n", i);
+			rv = 0;
+		}
+
+		if (wintab->remap >= 0 && win_cpu_can_remap(i) != 1) {
+			printf("XOR window#%d: not capable of remapping, but "
+			    "val 0x%08x defined\n", i, wintab->remap);
+			rv = 0;
+		}
+
+		s = wintab->size;
+		b = wintab->base;
+		e = b + s - 1;
+		if (s > (0xFFFFFFFF - b + 1)) {
+			/*
+			 * XXX this boundary check should account for 64bit
+			 * and remapping..
+			 */
+			printf("XOR window#%d: no space for size 0x%08x at "
+			    "0x%08x\n", i, s, b);
+			rv = 0;
+			continue;
+		}
+
+		j = decode_win_overlap(i, xor_wins_no, &xor_wins[0]);
+		if (j >= 0) {
+			printf("XOR window#%d: (0x%08x - 0x%08x) overlaps "
+			    "with #%d (0x%08x - 0x%08x)\n", i, b, e, j,
+			    xor_wins[j].base,
+			    xor_wins[j].base + xor_wins[j].size - 1);
+			rv = 0;
+		}
+	}
+
+	return (rv);
+}
+
+void
+decode_win_xor_dump(u_long base)
+{
+	int i, j;
+	int e = 1;
+
+	if (pm_is_disabled(CPU_PM_CTRL_XOR))
+		return;
+
+	for (j = 0; j < xor_max_eng(); j++, e--) {
+		for (i = 0; i < MV_WIN_XOR_MAX; i++) {
+			printf("XOR window#%d: b 0x%08x, s 0x%08x", i,
+			    win_xor_br_read(base, i, e), win_xor_sz_read(base, i, e));
+
+			if (win_xor_can_remap(i))
+				printf(", ha 0x%08x", win_xor_har_read(base, i, e));
+
+			printf("\n");
+		}
+		for (i = 0; i < MV_XOR_CHAN_MAX; i++)
+			printf("XOR control#%d: 0x%08x\n", i,
+			    win_xor_ctrl_read(base, i, e));
+	}
+}
+
+#else
+/* Provide dummy functions to satisfy the build for SoCs not equipped with XOR */
+static int
+decode_win_xor_valid(void)
+{
+
+	return (1);
+}
+
+static void
+decode_win_xor_setup(u_long base)
+{
+}
+
+static void
+decode_win_xor_dump(u_long base)
+{
+}
+#endif
+
+/**************************************************************************
+ * SATA windows routines
+ **************************************************************************/
+static void
+decode_win_sata_setup(u_long base)
+{
+	uint32_t cr, br;
+	int i, j;
+
+	if (pm_is_disabled(CPU_PM_CTRL_SATA))
+		return;
+
+	for (i = 0; i < MV_WIN_SATA_MAX; i++) {
+		win_sata_cr_write(base, i, 0);
+		win_sata_br_write(base, i, 0);
+	}
+
+	for (i = 0; i < MV_WIN_DDR_MAX; i++)
+		if (ddr_is_active(i)) {
+			cr = ((ddr_size(i) - 1) & 0xffff0000) |
+			    (ddr_attr(i) << 8) | (ddr_target(i) << 4) | 1;
+			br = ddr_base(i);
+
+			/* Use the first available SATA window */
+			for (j = 0; j < MV_WIN_SATA_MAX; j++) {
+				if ((win_sata_cr_read(base, j) & 1) != 0)
+					continue;
+
+				win_sata_br_write(base, j, br);
+				win_sata_cr_write(base, j, cr);
+				break;
+			}
+		}
+}
+
+static int
+decode_win_sata_valid(void)
+{
+	uint32_t dev, rev;
+
+	soc_id(&dev, &rev);
+	if (dev == MV_DEV_88F5281)
+		return (1);
+
+	return (decode_win_can_cover_ddr(MV_WIN_SATA_MAX));
+}
+
+/**************************************************************************
+ * FDT parsing routines.
+ **************************************************************************/
+
+static int
+fdt_get_ranges(const char *nodename, void *buf, int size, int *tuples,
+    int *tuplesize)
+{
+	phandle_t node;
+	pcell_t addr_cells, par_addr_cells, size_cells;
+	int len, tuple_size, tuples_count;
+
+	node = OF_finddevice(nodename);
+	if (node == -1)
+		return (EINVAL);
+
+	if ((fdt_addrsize_cells(node, &addr_cells, &size_cells)) != 0)
+		return (ENXIO);
+
+	par_addr_cells = fdt_parent_addr_cells(node);
+	if (par_addr_cells > 2)
+		return (ERANGE);
+
+	tuple_size = sizeof(pcell_t) * (addr_cells + par_addr_cells +
+	    size_cells);
+
+	/* Note the OF_getprop_alloc() cannot be used at this early stage. */
+	len = OF_getprop(node, "ranges", buf, size);
+
+	/*
+	 * XXX this does not handle the empty 'ranges;' case, which is
+	 * legitimate and should be allowed.
+	 */
+	tuples_count = len / tuple_size;
+	if (tuples_count <= 0)
+		return (ERANGE);
+
+	if (fdt_ranges_verify(buf, tuples_count, par_addr_cells,
+	    addr_cells, size_cells) != 0)
+		return (ERANGE);
+
+	*tuples = tuples_count;
+	*tuplesize = tuple_size;
+	return (0);
+}
+
+static int
+win_cpu_from_dt(void)
+{
+	pcell_t ranges[48];
+	phandle_t node;
+	int i, entry_size, err, t, tuple_size, tuples;
+	u_long sram_base, sram_size;
+
+	t = 0;
+	/* Retrieve 'ranges' property of '/localbus' node. */
+	if ((err = fdt_get_ranges("/localbus", ranges, sizeof(ranges),
+	    &tuples, &tuple_size)) == 0) {
+		/*
+		 * Fill CPU decode windows table.
+		 */
+		bzero((void *)&cpu_win_tbl, sizeof(cpu_win_tbl));
+
+		entry_size = tuple_size / sizeof(pcell_t);
+		cpu_wins_no = tuples;
+
+		for (i = 0, t = 0; t < tuples; i += entry_size, t++) {
+			cpu_win_tbl[t].target = 1;
+			cpu_win_tbl[t].attr = fdt32_to_cpu(ranges[i + 1]);
+			cpu_win_tbl[t].base = fdt32_to_cpu(ranges[i + 2]);
+			cpu_win_tbl[t].size = fdt32_to_cpu(ranges[i + 3]);
+			cpu_win_tbl[t].remap = ~0;
+			debugf("target = 0x%0x attr = 0x%0x base = 0x%0x "
+			    "size = 0x%0x remap = 0x%0x\n",
+			    cpu_win_tbl[t].target,
+			    cpu_win_tbl[t].attr, cpu_win_tbl[t].base,
+			    cpu_win_tbl[t].size, cpu_win_tbl[t].remap);
+		}
+	}
+
+	/*
+	 * Retrieve CESA SRAM data.
+	 */
+	if ((node = OF_finddevice("sram")) != -1)
+		if (fdt_is_compatible(node, "mrvl,cesa-sram"))
+			goto moveon;
+
+	if ((node = OF_finddevice("/")) == 0)
+		return (ENXIO);
+
+	if ((node = fdt_find_compatible(node, "mrvl,cesa-sram", 0)) == 0)
+		/* SRAM block is not always present. */
+		return (0);
+moveon:
+	sram_base = sram_size = 0;
+	if (fdt_regsize(node, &sram_base, &sram_size) != 0)
+		return (EINVAL);
+
+	cpu_win_tbl[t].target = MV_WIN_CESA_TARGET;
+	cpu_win_tbl[t].attr = MV_WIN_CESA_ATTR(1);
+	cpu_win_tbl[t].base = sram_base;
+	cpu_win_tbl[t].size = sram_size;
+	cpu_win_tbl[t].remap = ~0;
+	cpu_wins_no++;
+	debugf("sram: base = 0x%0lx size = 0x%0lx\n", sram_base, sram_size);
+
+	return (0);
+}
+
+static int
+fdt_win_setup(void)
+{
+	phandle_t node, child;
+	struct soc_node_spec *soc_node;
+	u_long size, base;
+	int err, i;
+
+	node = OF_finddevice("/");
+	if (node == -1)
+		panic("fdt_win_setup: no root node");
+
+	/*
+	 * Traverse through all children of root and simple-bus nodes.
+	 * For each found device retrieve decode windows data (if applicable).
+	 */
+	child = OF_child(node);
+	while (child != 0) {
+		for (i = 0; soc_nodes[i].compat != NULL; i++) {
+
+			soc_node = &soc_nodes[i];
+
+			if (!fdt_is_compatible(child, soc_node->compat))
+				continue;
+
+			err = fdt_regsize(child, &base, &size);
+			if (err != 0)
+				return (err);
+
+			base = (base & 0x000fffff) | fdt_immr_va;
+			if (soc_node->decode_handler != NULL)
+				soc_node->decode_handler(base);
+			else
+				return (ENXIO);
+
+			if (MV_DUMP_WIN && (soc_node->dump_handler != NULL))
+				soc_node->dump_handler(base);
+		}
+
+		/*
+		 * Once done with root-level children let's move down to
+		 * simple-bus and its children.
+		 */
+		child = OF_peer(child);
+		if ((child == 0) && (node == OF_finddevice("/"))) {
+			node = fdt_find_compatible(node, "simple-bus", 1);
+			if (node == 0)
+				return (ENXIO);
+			child = OF_child(node);
+		}
+	}
+
+	return (0);
+}
+
+static void
+fdt_fixup_busfreq(phandle_t root)
+{
+	phandle_t sb;
+	pcell_t freq;
+
+	freq = cpu_to_fdt32(get_tclk());
+
+	/*
+	 * Fix bus speed in cpu node
+	 */
+	if ((sb = OF_finddevice("cpu")) != 0)
+		if (fdt_is_compatible_strict(sb, "ARM,88VS584"))
+			OF_setprop(sb, "bus-frequency", (void *)&freq,
+			    sizeof(freq));
+
+	/*
+	 * This fixup sets the simple-bus bus-frequency property.
+	 */
+	if ((sb = fdt_find_compatible(root, "simple-bus", 1)) != 0)
+		OF_setprop(sb, "bus-frequency", (void *)&freq, sizeof(freq));
+}
+
+static void
+fdt_fixup_ranges(phandle_t root)
+{
+	phandle_t node;
+	pcell_t par_addr_cells, addr_cells, size_cells;
+	pcell_t ranges[3], reg[2], *rangesptr;
+	int len, tuple_size, tuples_count;
+	uint32_t base;
+
+	/* Fix-up SoC ranges according to real fdt_immr_pa */
+	if ((node = fdt_find_compatible(root, "simple-bus", 1)) != 0) {
+		if (fdt_addrsize_cells(node, &addr_cells, &size_cells) == 0 &&
+		    (par_addr_cells = fdt_parent_addr_cells(node) <= 2)) {
+			tuple_size = sizeof(pcell_t) * (par_addr_cells +
+			   addr_cells + size_cells);
+			len = OF_getprop(node, "ranges", ranges,
+			    sizeof(ranges));
+			tuples_count = len / tuple_size;
+			/* Unexpected settings are not supported */
+			if (tuples_count != 1)
+				goto fixup_failed;
+
+			rangesptr = &ranges[0];
+			rangesptr += par_addr_cells;
+			base = fdt_data_get((void *)rangesptr, addr_cells);
+			*rangesptr = cpu_to_fdt32(fdt_immr_pa);
+			if (OF_setprop(node, "ranges", (void *)&ranges[0],
+			    sizeof(ranges)) < 0)
+				goto fixup_failed;
+		}
+	}
+
+	/* Fix-up PCIe reg according to real PCIe registers' PA */
+	if ((node = fdt_find_compatible(root, "mrvl,pcie", 1)) != 0) {
+		if (fdt_addrsize_cells(OF_parent(node), &par_addr_cells,
+		    &size_cells) == 0) {
+			tuple_size = sizeof(pcell_t) * (par_addr_cells +
+			    size_cells);
+			len = OF_getprop(node, "reg", reg, sizeof(reg));
+			tuples_count = len / tuple_size;
+			/* Unexpected settings are not supported */
+			if (tuples_count != 1)
+				goto fixup_failed;
+
+			base = fdt_data_get((void *)&reg[0], par_addr_cells);
+			base &= ~0xFF000000;
+			base |= fdt_immr_pa;
+			reg[0] = cpu_to_fdt32(base);
+			if (OF_setprop(node, "reg", (void *)&reg[0],
+			    sizeof(reg)) < 0)
+				goto fixup_failed;
+		}
+	}
+	/* Fix-up succeeded. May return and continue */
+	return;
+
+fixup_failed:
+	while (1) {
+		/*
+		 * In case of any error while fixing ranges just hang.
+		 *	1. No message can be displayed yet since console
+		 *	   is not initialized.
+		 *	2. Going further will cause failure on bus_space_map()
+		 *	   relying on the wrong ranges or data abort when
+		 *	   accessing PCIe registers.
+		 */
+	}
+}
+
+struct fdt_fixup_entry fdt_fixup_table[] = {
+	{ "mrvl,DB-88F6281", &fdt_fixup_busfreq },
+	{ "mrvl,DB-78460", &fdt_fixup_busfreq },
+	{ "mrvl,DB-78460", &fdt_fixup_ranges },
+	{ NULL, NULL }
+};
+
+static int
+fdt_pic_decode_ic(phandle_t node, pcell_t *intr, int *interrupt, int *trig,
+    int *pol)
+{
+
+	if (!fdt_is_compatible(node, "mrvl,pic") &&
+	    !fdt_is_compatible(node, "mrvl,mpic"))
+		return (ENXIO);
+
+	*interrupt = fdt32_to_cpu(intr[0]);
+	*trig = INTR_TRIGGER_CONFORM;
+	*pol = INTR_POLARITY_CONFORM;
+
+	return (0);
+}
+
+fdt_pic_decode_t fdt_pic_table[] = {
+	&fdt_pic_decode_ic,
+	NULL
+};
+
+uint64_t
+get_sar_value(void)
+{
+	uint32_t sar_low, sar_high;
+
+#if defined(SOC_MV_ARMADAXP)
+	sar_high = bus_space_read_4(fdtbus_bs_tag, MV_MISC_BASE,
+	    SAMPLE_AT_RESET_HI);
+	sar_low = bus_space_read_4(fdtbus_bs_tag, MV_MISC_BASE,
+	    SAMPLE_AT_RESET_LO);
+#else
+	/*
+	 * TODO: Add getting proper values for other SoC configurations
+	 */
+	sar_high = 0;
+	sar_low = 0;
+#endif
+
+	return (((uint64_t)sar_high << 32) | sar_low);
+}


Property changes on: trunk/sys/arm/mv/mv_common.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/mv/mv_localbus.c
===================================================================
--- trunk/sys/arm/mv/mv_localbus.c	                        (rev 0)
+++ trunk/sys/arm/mv/mv_localbus.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,494 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/mv/mv_localbus.c 266386 2014-05-18 00:32:35Z ian $");
+
+#include "opt_platform.h"
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/ktr.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/rman.h>
+#include <sys/malloc.h>
+
+#include <vm/vm.h>
+
+#include <machine/devmap.h>
+#include <machine/fdt.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+#include <dev/ofw/openfirm.h>
+
+#include "dev/fdt/fdt_common.h"
+#include "ofw_bus_if.h"
+
+#include <arm/mv/mvwin.h>
+
+#ifdef DEBUG
+#define debugf(fmt, args...) do { printf("%s(): ", __func__);	\
+    printf(fmt,##args); } while (0)
+#else
+#define debugf(fmt, args...)
+#endif
+
+#define MV_LOCALBUS_MAX_BANKS		8
+#define MV_LOCALBUS_MAX_BANK_CELLS	4
+
+static MALLOC_DEFINE(M_LOCALBUS, "localbus", "localbus devices information");
+
+struct localbus_bank {
+	vm_offset_t	va;		/* VA of the bank */
+	vm_paddr_t	pa;		/* physical address of the bank */
+	vm_size_t	size;		/* bank size */
+	uint8_t		mapped;		/* device memory has mapping */
+};
+
+struct localbus_softc {
+	device_t		sc_dev;
+	bus_space_handle_t	sc_bsh;
+	bus_space_tag_t		sc_bst;
+	int			sc_rid;
+
+	struct localbus_bank	*sc_banks;
+};
+
+struct localbus_devinfo {
+	struct ofw_bus_devinfo	di_ofw;
+	struct resource_list	di_res;
+	int			di_bank;
+};
+
+struct localbus_va_entry {
+	int8_t		bank;
+	vm_offset_t 	va;
+	vm_size_t 	size;
+};
+
+/*
+ * Prototypes.
+ */
+static int localbus_probe(device_t);
+static int localbus_attach(device_t);
+static int localbus_print_child(device_t, device_t);
+
+static struct resource *localbus_alloc_resource(device_t, device_t, int,
+    int *, u_long, u_long, u_long, u_int);
+static struct resource_list *localbus_get_resource_list(device_t, device_t);
+
+static ofw_bus_get_devinfo_t localbus_get_devinfo;
+
+/*
+ * Bus interface definition.
+ */
+static device_method_t localbus_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		localbus_probe),
+	DEVMETHOD(device_attach,	localbus_attach),
+	DEVMETHOD(device_detach,	bus_generic_detach),
+	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
+	DEVMETHOD(device_suspend,	bus_generic_suspend),
+	DEVMETHOD(device_resume,	bus_generic_resume),
+
+	/* Bus interface */
+	DEVMETHOD(bus_print_child,	localbus_print_child),
+	DEVMETHOD(bus_alloc_resource,	localbus_alloc_resource),
+	DEVMETHOD(bus_release_resource,	bus_generic_release_resource),
+	DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
+	DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+	DEVMETHOD(bus_setup_intr,	bus_generic_setup_intr),
+	DEVMETHOD(bus_teardown_intr,	bus_generic_teardown_intr),
+	DEVMETHOD(bus_get_resource_list, localbus_get_resource_list),
+
+	/* OFW bus interface */
+	DEVMETHOD(ofw_bus_get_devinfo,	localbus_get_devinfo),
+	DEVMETHOD(ofw_bus_get_compat,	ofw_bus_gen_get_compat),
+	DEVMETHOD(ofw_bus_get_model,	ofw_bus_gen_get_model),
+	DEVMETHOD(ofw_bus_get_name,	ofw_bus_gen_get_name),
+	DEVMETHOD(ofw_bus_get_node,	ofw_bus_gen_get_node),
+	DEVMETHOD(ofw_bus_get_type,	ofw_bus_gen_get_type),
+
+	{ 0, 0 }
+};
+
+static driver_t localbus_driver = {
+	"localbus",
+	localbus_methods,
+	sizeof(struct localbus_softc)
+};
+
+const struct localbus_va_entry localbus_virtmap[] = {
+	{  0, MV_DEV_BOOT_BASE,		MV_DEV_BOOT_SIZE },
+	{  1, MV_DEV_CS0_BASE,		MV_DEV_CS0_SIZE },
+	{  2, MV_DEV_CS1_BASE,		MV_DEV_CS1_SIZE },
+	{  3, MV_DEV_CS2_BASE,		MV_DEV_CS2_SIZE },
+
+	{ -1, 0, 0 }
+};
+
+static struct localbus_bank localbus_banks[MV_LOCALBUS_MAX_BANKS];
+
+devclass_t localbus_devclass;
+
+DRIVER_MODULE(localbus, ofwbus, localbus_driver, localbus_devclass, 0, 0);
+
+static int
+fdt_localbus_reg_decode(phandle_t node, struct localbus_softc *sc,
+    struct localbus_devinfo *di)
+{
+	u_long start, end, count;
+	pcell_t *reg, *regptr;
+	pcell_t addr_cells, size_cells;
+	int tuple_size, tuples;
+	int i, rv, bank;
+
+	if (fdt_addrsize_cells(OF_parent(node), &addr_cells, &size_cells) != 0)
+		return (ENXIO);
+
+	tuple_size = sizeof(pcell_t) * (addr_cells + size_cells);
+	tuples = OF_getprop_alloc(node, "reg", tuple_size, (void **)&reg);
+	debugf("addr_cells = %d, size_cells = %d\n", addr_cells, size_cells);
+	debugf("tuples = %d, tuple size = %d\n", tuples, tuple_size);
+	if (tuples <= 0)
+		/* No 'reg' property in this node. */
+		return (0);
+
+	regptr = reg;
+	for (i = 0; i < tuples; i++) {
+
+		bank = fdt_data_get((void *)regptr, 1);
+
+		if (bank >= MV_LOCALBUS_MAX_BANKS) {
+			device_printf(sc->sc_dev, "bank number [%d] out of "
+			    "range\n", bank);
+			continue;
+		}
+
+		/*
+		 * If device doesn't have virtual to physical mapping don't add
+		 * resources
+		 */
+		if (!(sc->sc_banks[bank].mapped)) {
+			device_printf(sc->sc_dev, "device [%d]: missing memory "
+			    "mapping\n", bank);
+			continue;
+		}
+
+		di->di_bank = bank;
+		regptr += 1;
+
+		/* Get address/size. */
+		rv = fdt_data_to_res(regptr, addr_cells - 1, size_cells, &start,
+		    &count);
+		if (rv != 0) {
+			resource_list_free(&di->di_res);
+			goto out;
+		}
+
+		/* Check if enough amount of memory is mapped */
+		if (sc->sc_banks[bank].size < count) {
+			device_printf(sc->sc_dev, "device [%d]: not enough "
+			    "memory reserved\n", bank);
+			continue;
+		}
+
+		regptr += addr_cells - 1 + size_cells;
+
+		/* Calculate address range relative to VA base. */
+		start = sc->sc_banks[bank].va + start;
+		end = start + count - 1;
+
+		debugf("reg addr bank = %d, start = %lx, end = %lx, "
+		    "count = %lx\n", bank, start, end, count);
+
+		/* Use bank (CS) cell as rid. */
+		resource_list_add(&di->di_res, SYS_RES_MEMORY, di->di_bank,
+		    start, end, count);
+	}
+	rv = 0;
+out:
+	free(reg, M_OFWPROP);
+	return (rv);
+}
+
+static int
+localbus_probe(device_t dev)
+{
+
+	if (!ofw_bus_is_compatible_strict(dev, "mrvl,lbc"))
+		return (ENXIO);
+
+	device_set_desc(dev, "Marvell device bus");
+
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+localbus_attach(device_t dev)
+{
+	device_t dev_child;
+	struct localbus_softc *sc;
+	struct localbus_devinfo *di;
+	phandle_t dt_node, dt_child;
+
+	sc = device_get_softc(dev);
+	sc->sc_dev = dev;
+	sc->sc_banks = localbus_banks;
+
+	/*
+	 * Walk localbus and add direct subordinates as our children.
+	 */
+	dt_node = ofw_bus_get_node(dev);
+	for (dt_child = OF_child(dt_node); dt_child != 0;
+	    dt_child = OF_peer(dt_child)) {
+
+		/* Check and process 'status' property. */
+		if (!(fdt_is_enabled(dt_child)))
+			continue;
+
+		if (!(fdt_pm_is_enabled(dt_child)))
+			continue;
+
+		di = malloc(sizeof(*di), M_LOCALBUS, M_WAITOK | M_ZERO);
+		if (ofw_bus_gen_setup_devinfo(&di->di_ofw, dt_child) != 0) {
+			free(di, M_LOCALBUS);
+			device_printf(dev, "could not set up devinfo\n");
+			continue;
+		}
+
+		resource_list_init(&di->di_res);
+		if (fdt_localbus_reg_decode(dt_child, sc, di)) {
+			device_printf(dev, "could not process 'reg' "
+			    "property\n");
+			ofw_bus_gen_destroy_devinfo(&di->di_ofw);
+			free(di, M_LOCALBUS);
+			continue;
+		}
+
+		/* Add newbus device for this FDT node */
+		dev_child = device_add_child(dev, NULL, -1);
+		if (dev_child == NULL) {
+			device_printf(dev, "could not add child: %s\n",
+			    di->di_ofw.obd_name);
+			resource_list_free(&di->di_res);
+			ofw_bus_gen_destroy_devinfo(&di->di_ofw);
+			free(di, M_LOCALBUS);
+			continue;
+		}
+#ifdef DEBUG
+		device_printf(dev, "added child: %s\n\n", di->di_ofw.obd_name);
+#endif
+		device_set_ivars(dev_child, di);
+	}
+
+	return (bus_generic_attach(dev));
+}
+
+static int
+localbus_print_child(device_t dev, device_t child)
+{
+	struct localbus_devinfo *di;
+	struct resource_list *rl;
+	int rv;
+
+	di = device_get_ivars(child);
+	rl = &di->di_res;
+
+	rv = 0;
+	rv += bus_print_child_header(dev, child);
+	rv += resource_list_print_type(rl, "mem", SYS_RES_MEMORY, "%#lx");
+	rv += resource_list_print_type(rl, "irq", SYS_RES_IRQ, "%ld");
+	rv += bus_print_child_footer(dev, child);
+
+	return (rv);
+}
+
+static struct resource *
+localbus_alloc_resource(device_t bus, device_t child, int type, int *rid,
+    u_long start, u_long end, u_long count, u_int flags)
+{
+	struct localbus_devinfo *di;
+	struct resource_list_entry *rle;
+
+	/*
+	 * Request for the default allocation with a given rid: use resource
+	 * list stored in the local device info.
+	 */
+	if ((start == 0UL) && (end == ~0UL)) {
+		if ((di = device_get_ivars(child)) == NULL)
+			return (NULL);
+
+		if (type == SYS_RES_IOPORT)
+			type = SYS_RES_MEMORY;
+
+		rid = &di->di_bank;
+		rle = resource_list_find(&di->di_res, type, *rid);
+		if (rle == NULL) {
+			device_printf(bus, "no default resources for "
+			    "rid = %d, type = %d\n", *rid, type);
+			return (NULL);
+		}
+		start = rle->start;
+		end = rle->end;
+		count = rle->count;
+	}
+
+	return (bus_generic_alloc_resource(bus, child, type, rid, start, end,
+	    count, flags));
+}
+
+
+static struct resource_list *
+localbus_get_resource_list(device_t bus, device_t child)
+{
+	struct localbus_devinfo *di;
+
+	di = device_get_ivars(child);
+	return (&di->di_res);
+}
+
+static const struct ofw_bus_devinfo *
+localbus_get_devinfo(device_t bus, device_t child)
+{
+	struct localbus_devinfo *di;
+
+	di = device_get_ivars(child);
+	return (&di->di_ofw);
+}
+
+int
+fdt_localbus_devmap(phandle_t dt_node, struct arm_devmap_entry *fdt_devmap,
+    int banks_max_num, int *banks_added)
+{
+	pcell_t ranges[MV_LOCALBUS_MAX_BANKS * MV_LOCALBUS_MAX_BANK_CELLS];
+	pcell_t *rangesptr;
+	uint32_t tuple_size, bank;
+	vm_paddr_t offset;
+	vm_size_t size;
+	int dev_num, addr_cells, size_cells, par_addr_cells, va_index, i, j, k;
+
+	if ((fdt_addrsize_cells(dt_node, &addr_cells, &size_cells)) != 0)
+		return (EINVAL);
+
+	par_addr_cells = fdt_parent_addr_cells(dt_node);
+	if (par_addr_cells > 2) {
+		/*
+		 * Localbus devmap initialization error: unsupported parent
+		 * #addr-cells
+		 */
+		return (ERANGE);
+	}
+
+	tuple_size = (addr_cells + par_addr_cells + size_cells);
+	if (tuple_size > MV_LOCALBUS_MAX_BANK_CELLS)
+		return (ERANGE);
+
+	tuple_size *= sizeof(pcell_t);
+
+	dev_num = OF_getprop(dt_node, "ranges", ranges, sizeof(ranges));
+ 	if (dev_num <= 0)
+		return (EINVAL);
+
+ 	/* Calculate number of devices attached to bus */
+ 	dev_num = dev_num / tuple_size;
+
+ 	/*
+ 	 * If number of ranges > max number of localbus devices,
+ 	 * additional entries will not be processed
+ 	 */
+ 	dev_num = MIN(dev_num, banks_max_num);
+
+ 	rangesptr = &ranges[0];
+ 	j = 0;
+
+ 	/* Process data from FDT */
+	for (i = 0; i < dev_num; i++) {
+
+		/* First field is bank number */
+		bank = fdt_data_get((void *)rangesptr, 1);
+		rangesptr += 1;
+
+		if (bank < 0 || bank > MV_LOCALBUS_MAX_BANKS) {
+			/* Bank out of range */
+			rangesptr += ((addr_cells - 1) + par_addr_cells +
+			    size_cells);
+			continue;
+		}
+
+		/* Find virtmap entry for this bank */
+		va_index = -1;
+		for (k = 0; localbus_virtmap[k].bank >= 0; k++) {
+			if (localbus_virtmap[k].bank == bank) {
+				va_index = k;
+				break;
+			}
+		}
+
+		/* Check if virtmap entry was found */
+		if (va_index == -1) {
+			rangesptr += ((addr_cells - 1) + par_addr_cells +
+			    size_cells);
+			continue;
+		}
+
+		/* Remaining child's address fields are unused */
+		rangesptr += (addr_cells - 1);
+
+		/* Parent address offset */
+		offset = fdt_data_get((void *)rangesptr, par_addr_cells);
+		rangesptr += par_addr_cells;
+
+		/* Last field is size */
+		size = fdt_data_get((void *)rangesptr, size_cells);
+		rangesptr += size_cells;
+
+		if (size > localbus_virtmap[va_index].size) {
+			/* Not enough space reserved in virtual memory map */
+			continue;
+		}
+
+		fdt_devmap[j].pd_va = localbus_virtmap[va_index].va;
+		fdt_devmap[j].pd_pa = offset;
+		fdt_devmap[j].pd_size = size;
+		fdt_devmap[j].pd_prot = VM_PROT_READ | VM_PROT_WRITE;
+		fdt_devmap[j].pd_cache = PTE_DEVICE;
+
+		/* Copy data to structure used by localbus driver */
+		localbus_banks[bank].va = fdt_devmap[j].pd_va;
+		localbus_banks[bank].pa = fdt_devmap[j].pd_pa;
+		localbus_banks[bank].size = fdt_devmap[j].pd_size;
+		localbus_banks[bank].mapped = 1;
+
+		j++;
+	}
+
+	*banks_added = j;
+	return (0);
+}


Property changes on: trunk/sys/arm/mv/mv_localbus.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/mv/mv_machdep.c
===================================================================
--- trunk/sys/arm/mv/mv_machdep.c	                        (rev 0)
+++ trunk/sys/arm/mv/mv_machdep.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,486 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1994-1998 Mark Brinicombe.
+ * Copyright (c) 1994 Brini.
+ * All rights reserved.
+ *
+ * This code is derived from software written for Brini by Mark Brinicombe
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by Brini.
+ * 4. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BRINI ``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 BRINI 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.
+ *
+ * from: FreeBSD: //depot/projects/arm/src/sys/arm/at91/kb920x_machdep.c, rev 45
+ */
+
+#include "opt_ddb.h"
+#include "opt_platform.h"
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/mv/mv_machdep.c 266386 2014-05-18 00:32:35Z ian $");
+
+#define _ARM32_BUS_DMA_PRIVATE
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <machine/bus.h>
+#include <machine/devmap.h>
+#include <machine/fdt.h>
+#include <machine/machdep.h>
+
+#include <arm/mv/mvreg.h>	/* XXX */
+#include <arm/mv/mvvar.h>	/* XXX eventually this should be eliminated */
+#include <arm/mv/mvwin.h>
+
+#include <dev/fdt/fdt_common.h>
+
+static int platform_mpp_init(void);
+#if defined(SOC_MV_ARMADAXP)
+void armadaxp_init_coher_fabric(void);
+void armadaxp_l2_init(void);
+#endif
+
+#define MPP_PIN_MAX		68
+#define MPP_PIN_CELLS		2
+#define MPP_PINS_PER_REG	8
+#define MPP_SEL(pin,func)	(((func) & 0xf) <<		\
+    (((pin) % MPP_PINS_PER_REG) * 4))
+
+static int
+platform_mpp_init(void)
+{
+	pcell_t pinmap[MPP_PIN_MAX * MPP_PIN_CELLS];
+	int mpp[MPP_PIN_MAX];
+	uint32_t ctrl_val, ctrl_offset;
+	pcell_t reg[4];
+	u_long start, size;
+	phandle_t node;
+	pcell_t pin_cells, *pinmap_ptr, pin_count;
+	ssize_t len;
+	int par_addr_cells, par_size_cells;
+	int tuple_size, tuples, rv, pins, i, j;
+	int mpp_pin, mpp_function;
+
+	/*
+	 * Try to access the MPP node directly i.e. through /aliases/mpp.
+	 */
+	if ((node = OF_finddevice("mpp")) != -1)
+		if (fdt_is_compatible(node, "mrvl,mpp"))
+			goto moveon;
+	/*
+	 * Find the node the long way.
+	 */
+	if ((node = OF_finddevice("/")) == -1)
+		return (ENXIO);
+
+	if ((node = fdt_find_compatible(node, "simple-bus", 0)) == 0)
+		return (ENXIO);
+
+	if ((node = fdt_find_compatible(node, "mrvl,mpp", 0)) == 0)
+		/*
+		 * No MPP node. Fall back to how MPP got set by the
+		 * first-stage loader and try to continue booting.
+		 */
+		return (0);
+moveon:
+	/*
+	 * Process 'reg' prop.
+	 */
+	if ((rv = fdt_addrsize_cells(OF_parent(node), &par_addr_cells,
+	    &par_size_cells)) != 0)
+		return(ENXIO);
+
+	tuple_size = sizeof(pcell_t) * (par_addr_cells + par_size_cells);
+	len = OF_getprop(node, "reg", reg, sizeof(reg));
+	tuples = len / tuple_size;
+	if (tuple_size <= 0)
+		return (EINVAL);
+
+	/*
+	 * Get address/size. XXX we assume only the first 'reg' tuple is used.
+	 */
+	rv = fdt_data_to_res(reg, par_addr_cells, par_size_cells,
+	    &start, &size);
+	if (rv != 0)
+		return (rv);
+	start += fdt_immr_va;
+
+	/*
+	 * Process 'pin-count' and 'pin-map' props.
+	 */
+	if (OF_getprop(node, "pin-count", &pin_count, sizeof(pin_count)) <= 0)
+		return (ENXIO);
+	pin_count = fdt32_to_cpu(pin_count);
+	if (pin_count > MPP_PIN_MAX)
+		return (ERANGE);
+
+	if (OF_getprop(node, "#pin-cells", &pin_cells, sizeof(pin_cells)) <= 0)
+		pin_cells = MPP_PIN_CELLS;
+	pin_cells = fdt32_to_cpu(pin_cells);
+	if (pin_cells > MPP_PIN_CELLS)
+		return (ERANGE);
+	tuple_size = sizeof(pcell_t) * pin_cells;
+
+	bzero(pinmap, sizeof(pinmap));
+	len = OF_getprop(node, "pin-map", pinmap, sizeof(pinmap));
+	if (len <= 0)
+		return (ERANGE);
+	if (len % tuple_size)
+		return (ERANGE);
+	pins = len / tuple_size;
+	if (pins > pin_count)
+		return (ERANGE);
+	/*
+	 * Fill out a "mpp[pin] => function" table. All pins unspecified in
+	 * the 'pin-map' property are defaulted to 0 function i.e. GPIO.
+	 */
+	bzero(mpp, sizeof(mpp));
+	pinmap_ptr = pinmap;
+	for (i = 0; i < pins; i++) {
+		mpp_pin = fdt32_to_cpu(*pinmap_ptr);
+		mpp_function = fdt32_to_cpu(*(pinmap_ptr + 1));
+		mpp[mpp_pin] = mpp_function;
+		pinmap_ptr += pin_cells;
+	}
+
+	/*
+	 * Prepare and program MPP control register values.
+	 */
+	ctrl_offset = 0;
+	for (i = 0; i < pin_count;) {
+		ctrl_val = 0;
+
+		for (j = 0; j < MPP_PINS_PER_REG; j++) {
+			if (i + j == pin_count - 1)
+				break;
+			ctrl_val |= MPP_SEL(i + j, mpp[i + j]);
+		}
+		i += MPP_PINS_PER_REG;
+		bus_space_write_4(fdtbus_bs_tag, start, ctrl_offset,
+		    ctrl_val);
+
+#if defined(SOC_MV_ORION)
+		/*
+		 * Third MPP reg on Orion SoC is placed
+		 * non-linearly (with different offset).
+		 */
+		if (i ==  (2 * MPP_PINS_PER_REG))
+			ctrl_offset = 0x50;
+		else
+#endif
+			ctrl_offset += 4;
+	}
+
+	return (0);
+}
+
+vm_offset_t
+initarm_lastaddr(void)
+{
+
+	return (fdt_immr_va);
+}
+
+void
+initarm_early_init(void)
+{
+
+	if (fdt_immr_addr(MV_BASE) != 0)
+		while (1);
+}
+
+void
+initarm_gpio_init(void)
+{
+
+	/*
+	 * Re-initialise MPP. It is important to call this prior to using
+	 * console as the physical connection can be routed via MPP.
+	 */
+	if (platform_mpp_init() != 0)
+		while (1);
+}
+
+void
+initarm_late_init(void)
+{
+	/*
+	 * Re-initialise decode windows
+	 */
+#if !defined(SOC_MV_FREY)
+	if (soc_decode_win() != 0)
+		printf("WARNING: could not re-initialise decode windows! "
+		    "Running with existing settings...\n");
+#else
+	/* Disable watchdog and timers */
+	write_cpu_ctrl(CPU_TIMERS_BASE + CPU_TIMER_CONTROL, 0);
+#endif
+#if defined(SOC_MV_ARMADAXP)
+#if !defined(SMP)
+	/* For SMP case it should be initialized after APs are booted */
+	armadaxp_init_coher_fabric();
+#endif
+	armadaxp_l2_init();
+#endif
+}
+
+#define FDT_DEVMAP_MAX	(MV_WIN_CPU_MAX + 2)
+static struct arm_devmap_entry fdt_devmap[FDT_DEVMAP_MAX] = {
+	{ 0, 0, 0, 0, 0, }
+};
+
+static int
+platform_sram_devmap(struct arm_devmap_entry *map)
+{
+#if !defined(SOC_MV_ARMADAXP)
+	phandle_t child, root;
+	u_long base, size;
+	/*
+	 * SRAM range.
+	 */
+	if ((child = OF_finddevice("/sram")) != 0)
+		if (fdt_is_compatible(child, "mrvl,cesa-sram") ||
+		    fdt_is_compatible(child, "mrvl,scratchpad"))
+			goto moveon;
+
+	if ((root = OF_finddevice("/")) == 0)
+		return (ENXIO);
+
+	if ((child = fdt_find_compatible(root, "mrvl,cesa-sram", 0)) == 0 &&
+	    (child = fdt_find_compatible(root, "mrvl,scratchpad", 0)) == 0)
+			goto out;
+
+moveon:
+	if (fdt_regsize(child, &base, &size) != 0)
+		return (EINVAL);
+
+	map->pd_va = MV_CESA_SRAM_BASE; /* XXX */
+	map->pd_pa = base;
+	map->pd_size = size;
+	map->pd_prot = VM_PROT_READ | VM_PROT_WRITE;
+	map->pd_cache = PTE_DEVICE;
+
+	return (0);
+out:
+#endif
+	return (ENOENT);
+
+}
+
+/*
+ * 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
+ * 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.
+ */
+int mv_default_fdt_pci_devmap(phandle_t node, struct arm_devmap_entry *devmap,
+    vm_offset_t io_va, vm_offset_t mem_va);
+int
+mv_default_fdt_pci_devmap(phandle_t node, struct arm_devmap_entry *devmap,
+    vm_offset_t io_va, vm_offset_t mem_va)
+{
+
+	return (0);
+}
+__weak_reference(mv_default_fdt_pci_devmap, mv_pci_devmap);
+
+/*
+ * XXX: When device entry in devmap has pd_size smaller than section size,
+ * system will freeze during initialization
+ */
+
+/*
+ * Construct pmap_devmap[] with DT-derived config data.
+ */
+int
+initarm_devmap_init(void)
+{
+	phandle_t root, child;
+	pcell_t bank_count;
+	int i, num_mapped;
+
+	i = 0;
+	arm_devmap_register_table(&fdt_devmap[0]);
+
+#ifdef SOC_MV_ARMADAXP
+	vm_paddr_t cur_immr_pa;
+
+	/*
+	 * Acquire SoC registers' base passed by u-boot and fill devmap
+	 * accordingly. DTB is going to be modified basing on this data
+	 * later.
+	 */
+	__asm __volatile("mrc p15, 4, %0, c15, c0, 0" : "=r" (cur_immr_pa));
+	cur_immr_pa = (cur_immr_pa << 13) & 0xff000000;
+	if (cur_immr_pa != 0)
+		fdt_immr_pa = cur_immr_pa;
+#endif
+	/*
+	 * IMMR range.
+	 */
+	fdt_devmap[i].pd_va = fdt_immr_va;
+	fdt_devmap[i].pd_pa = fdt_immr_pa;
+	fdt_devmap[i].pd_size = fdt_immr_size;
+	fdt_devmap[i].pd_prot = VM_PROT_READ | VM_PROT_WRITE;
+	fdt_devmap[i].pd_cache = PTE_DEVICE;
+	i++;
+
+	/*
+	 * SRAM range.
+	 */
+	if (i < FDT_DEVMAP_MAX)
+		if (platform_sram_devmap(&fdt_devmap[i]) == 0)
+			i++;
+
+	/*
+	 * PCI range(s).
+	 * PCI range(s) and localbus.
+	 */
+	if ((root = OF_finddevice("/")) == -1)
+		return (ENXIO);
+	for (child = OF_child(root); child != 0; child = OF_peer(child)) {
+		if (fdt_is_type(child, "pci") || fdt_is_type(child, "pciep")) {
+			/*
+			 * Check space: each PCI node will consume 2 devmap
+			 * entries.
+			 */
+			if (i + 1 >= FDT_DEVMAP_MAX)
+				return (ENOMEM);
+
+			/*
+			 * XXX this should account for PCI and multiple ranges
+			 * of a given kind.
+			 */
+			if (mv_pci_devmap(child, &fdt_devmap[i], MV_PCI_VA_IO_BASE,
+				    MV_PCI_VA_MEM_BASE) != 0)
+				return (ENXIO);
+			i += 2;
+		}
+
+		if (fdt_is_compatible(child, "mrvl,lbc")) {
+			/* Check available space */
+			if (OF_getprop(child, "bank-count", (void *)&bank_count,
+			    sizeof(bank_count)) <= 0)
+				/* If no property, use default value */
+				bank_count = 1;
+			else
+				bank_count = fdt32_to_cpu(bank_count);
+
+			if ((i + bank_count) >= FDT_DEVMAP_MAX)
+				return (ENOMEM);
+
+			/* Add all localbus ranges to device map */
+			num_mapped = 0;
+
+			if (fdt_localbus_devmap(child, &fdt_devmap[i],
+			    (int)bank_count, &num_mapped) != 0)
+				return (ENXIO);
+
+			i += num_mapped;
+		}
+	}
+
+	return (0);
+}
+
+struct arm32_dma_range *
+bus_dma_get_range(void)
+{
+
+	return (NULL);
+}
+
+int
+bus_dma_get_range_nb(void)
+{
+
+	return (0);
+}
+
+#if defined(CPU_MV_PJ4B)
+#ifdef DDB
+#include <ddb/ddb.h>
+
+DB_SHOW_COMMAND(cp15, db_show_cp15)
+{
+	u_int reg;
+
+	__asm __volatile("mrc p15, 0, %0, c0, c0, 0" : "=r" (reg));
+	db_printf("Cpu ID: 0x%08x\n", reg);
+	__asm __volatile("mrc p15, 0, %0, c0, c0, 1" : "=r" (reg));
+	db_printf("Current Cache Lvl ID: 0x%08x\n",reg);
+
+	__asm __volatile("mrc p15, 0, %0, c1, c0, 0" : "=r" (reg));
+	db_printf("Ctrl: 0x%08x\n",reg);
+	__asm __volatile("mrc p15, 0, %0, c1, c0, 1" : "=r" (reg));
+	db_printf("Aux Ctrl: 0x%08x\n",reg);
+
+	__asm __volatile("mrc p15, 0, %0, c0, c1, 0" : "=r" (reg));
+	db_printf("Processor Feat 0: 0x%08x\n", reg);
+	__asm __volatile("mrc p15, 0, %0, c0, c1, 1" : "=r" (reg));
+	db_printf("Processor Feat 1: 0x%08x\n", reg);
+	__asm __volatile("mrc p15, 0, %0, c0, c1, 2" : "=r" (reg));
+	db_printf("Debug Feat 0: 0x%08x\n", reg);
+	__asm __volatile("mrc p15, 0, %0, c0, c1, 3" : "=r" (reg));
+	db_printf("Auxiliary Feat 0: 0x%08x\n", reg);
+	__asm __volatile("mrc p15, 0, %0, c0, c1, 4" : "=r" (reg));
+	db_printf("Memory Model Feat 0: 0x%08x\n", reg);
+	__asm __volatile("mrc p15, 0, %0, c0, c1, 5" : "=r" (reg));
+	db_printf("Memory Model Feat 1: 0x%08x\n", reg);
+	__asm __volatile("mrc p15, 0, %0, c0, c1, 6" : "=r" (reg));
+	db_printf("Memory Model Feat 2: 0x%08x\n", reg);
+	__asm __volatile("mrc p15, 0, %0, c0, c1, 7" : "=r" (reg));
+	db_printf("Memory Model Feat 3: 0x%08x\n", reg);
+
+	__asm __volatile("mrc p15, 1, %0, c15, c2, 0" : "=r" (reg));
+	db_printf("Aux Func Modes Ctrl 0: 0x%08x\n",reg);
+	__asm __volatile("mrc p15, 1, %0, c15, c2, 1" : "=r" (reg));
+	db_printf("Aux Func Modes Ctrl 1: 0x%08x\n",reg);
+
+	__asm __volatile("mrc p15, 1, %0, c15, c12, 0" : "=r" (reg));
+	db_printf("CPU ID code extension: 0x%08x\n",reg);
+}
+
+DB_SHOW_COMMAND(vtop, db_show_vtop)
+{
+	u_int reg;
+
+	if (have_addr) {
+		__asm __volatile("mcr p15, 0, %0, c7, c8, 0" : : "r" (addr));
+		__asm __volatile("mrc p15, 0, %0, c7, c4, 0" : "=r" (reg));
+		db_printf("Physical address reg: 0x%08x\n",reg);
+	} else
+		db_printf("show vtop <virt_addr>\n");
+}
+#endif /* DDB */
+#endif /* CPU_MV_PJ4B */
+


Property changes on: trunk/sys/arm/mv/mv_machdep.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/mv/mv_pci.c
===================================================================
--- trunk/sys/arm/mv/mv_pci.c	                        (rev 0)
+++ trunk/sys/arm/mv/mv_pci.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,1199 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2008 MARVELL INTERNATIONAL LTD.
+ * Copyright (c) 2010 The FreeBSD Foundation
+ * Copyright (c) 2010-2012 Semihalf
+ * All rights reserved.
+ *
+ * Developed by Semihalf.
+ *
+ * Portions of this software were developed by Semihalf
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * 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.
+ * 3. Neither the name of MARVELL nor the names of contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY 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 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.
+ */
+
+/*
+ * Marvell integrated PCI/PCI-Express controller driver.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/mv/mv_pci.c 283332 2015-05-23 22:33:06Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/queue.h>
+#include <sys/bus.h>
+#include <sys/rman.h>
+#include <sys/endian.h>
+
+#include <machine/fdt.h>
+#include <machine/intr.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_pci.h>
+#include <dev/ofw/ofw_bus_subr.h>
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcib_private.h>
+
+#include "ofw_bus_if.h"
+#include "pcib_if.h"
+
+#include <machine/devmap.h>
+#include <machine/resource.h>
+#include <machine/bus.h>
+
+#include <arm/mv/mvreg.h>
+#include <arm/mv/mvvar.h>
+#include <arm/mv/mvwin.h>
+
+#ifdef DEBUG
+#define debugf(fmt, args...) do { printf(fmt,##args); } while (0)
+#else
+#define debugf(fmt, args...)
+#endif
+
+/*
+ * Code and data related to fdt-based PCI configuration.
+ *
+ * This stuff used to be in dev/fdt/fdt_pci.c and fdt_common.h, but it was
+ * always Marvell-specific so that was deleted and the code now lives here.
+ */
+
+struct mv_pci_range {
+	u_long	base_pci;
+	u_long	base_parent;
+	u_long	len;
+};
+
+#define FDT_RANGES_CELLS	((3 + 3 + 2) * 2)
+
+static void
+mv_pci_range_dump(struct mv_pci_range *range)
+{
+#ifdef DEBUG
+	printf("\n");
+	printf("  base_pci = 0x%08lx\n", range->base_pci);
+	printf("  base_par = 0x%08lx\n", range->base_parent);
+	printf("  len      = 0x%08lx\n", range->len);
+#endif
+}
+
+static int
+mv_pci_ranges_decode(phandle_t node, struct mv_pci_range *io_space,
+    struct mv_pci_range *mem_space)
+{
+	pcell_t ranges[FDT_RANGES_CELLS];
+	struct mv_pci_range *pci_space;
+	pcell_t addr_cells, size_cells, par_addr_cells;
+	pcell_t *rangesptr;
+	pcell_t cell0, cell1, cell2;
+	int tuple_size, tuples, i, rv, offset_cells, len;
+
+	/*
+	 * Retrieve 'ranges' property.
+	 */
+	if ((fdt_addrsize_cells(node, &addr_cells, &size_cells)) != 0)
+		return (EINVAL);
+	if (addr_cells != 3 || size_cells != 2)
+		return (ERANGE);
+
+	par_addr_cells = fdt_parent_addr_cells(node);
+	if (par_addr_cells > 3)
+		return (ERANGE);
+
+	len = OF_getproplen(node, "ranges");
+	if (len > sizeof(ranges))
+		return (ENOMEM);
+
+	if (OF_getprop(node, "ranges", ranges, sizeof(ranges)) <= 0)
+		return (EINVAL);
+
+	tuple_size = sizeof(pcell_t) * (addr_cells + par_addr_cells +
+	    size_cells);
+	tuples = len / tuple_size;
+
+	/*
+	 * Initialize the ranges so that we don't have to worry about
+	 * having them all defined in the FDT. In particular, it is
+	 * perfectly fine not to want I/O space on PCI busses.
+	 */
+	bzero(io_space, sizeof(*io_space));
+	bzero(mem_space, sizeof(*mem_space));
+
+	rangesptr = &ranges[0];
+	offset_cells = 0;
+	for (i = 0; i < tuples; i++) {
+		cell0 = fdt_data_get((void *)rangesptr, 1);
+		rangesptr++;
+		cell1 = fdt_data_get((void *)rangesptr, 1);
+		rangesptr++;
+		cell2 = fdt_data_get((void *)rangesptr, 1);
+		rangesptr++;
+
+		if (cell0 & 0x02000000) {
+			pci_space = mem_space;
+		} else if (cell0 & 0x01000000) {
+			pci_space = io_space;
+		} else {
+			rv = ERANGE;
+			goto out;
+		}
+
+		if (par_addr_cells == 3) {
+			/*
+			 * This is a PCI subnode 'ranges'. Skip cell0 and
+			 * cell1 of this entry and only use cell2.
+			 */
+			offset_cells = 2;
+			rangesptr += offset_cells;
+		}
+
+		if (fdt_data_verify((void *)rangesptr, par_addr_cells -
+		    offset_cells)) {
+			rv = ERANGE;
+			goto out;
+		}
+		pci_space->base_parent = fdt_data_get((void *)rangesptr,
+		    par_addr_cells - offset_cells);
+		rangesptr += par_addr_cells - offset_cells;
+
+		if (fdt_data_verify((void *)rangesptr, size_cells)) {
+			rv = ERANGE;
+			goto out;
+		}
+		pci_space->len = fdt_data_get((void *)rangesptr, size_cells);
+		rangesptr += size_cells;
+
+		pci_space->base_pci = cell2;
+	}
+	rv = 0;
+out:
+	return (rv);
+}
+
+static int
+mv_pci_ranges(phandle_t node, struct mv_pci_range *io_space,
+    struct mv_pci_range *mem_space)
+{
+	int err;
+
+	debugf("Processing PCI node: %x\n", node);
+	if ((err = mv_pci_ranges_decode(node, io_space, mem_space)) != 0) {
+		debugf("could not decode parent PCI node 'ranges'\n");
+		return (err);
+	}
+
+	debugf("Post fixup dump:\n");
+	mv_pci_range_dump(io_space);
+	mv_pci_range_dump(mem_space);
+	return (0);
+}
+
+int
+mv_pci_devmap(phandle_t node, struct arm_devmap_entry *devmap, vm_offset_t io_va,
+    vm_offset_t mem_va)
+{
+	struct mv_pci_range io_space, mem_space;
+	int error;
+
+	if ((error = mv_pci_ranges_decode(node, &io_space, &mem_space)) != 0)
+		return (error);
+
+	devmap->pd_va = (io_va ? io_va : io_space.base_parent);
+	devmap->pd_pa = io_space.base_parent;
+	devmap->pd_size = io_space.len;
+	devmap->pd_prot = VM_PROT_READ | VM_PROT_WRITE;
+	devmap->pd_cache = PTE_DEVICE;
+	devmap++;
+
+	devmap->pd_va = (mem_va ? mem_va : mem_space.base_parent);
+	devmap->pd_pa = mem_space.base_parent;
+	devmap->pd_size = mem_space.len;
+	devmap->pd_prot = VM_PROT_READ | VM_PROT_WRITE;
+	devmap->pd_cache = PTE_DEVICE;
+	return (0);
+}
+
+/*
+ * Code and data related to the Marvell pcib driver.
+ */
+
+#define PCI_CFG_ENA		(1U << 31)
+#define PCI_CFG_BUS(bus)	(((bus) & 0xff) << 16)
+#define PCI_CFG_DEV(dev)	(((dev) & 0x1f) << 11)
+#define PCI_CFG_FUN(fun)	(((fun) & 0x7) << 8)
+#define PCI_CFG_PCIE_REG(reg)	((reg) & 0xfc)
+
+#define PCI_REG_CFG_ADDR	0x0C78
+#define PCI_REG_CFG_DATA	0x0C7C
+
+#define PCIE_REG_CFG_ADDR	0x18F8
+#define PCIE_REG_CFG_DATA	0x18FC
+#define PCIE_REG_CONTROL	0x1A00
+#define   PCIE_CTRL_LINK1X	0x00000001
+#define PCIE_REG_STATUS		0x1A04
+#define PCIE_REG_IRQ_MASK	0x1910
+
+#define PCIE_CONTROL_ROOT_CMPLX	(1 << 1)
+#define PCIE_CONTROL_HOT_RESET	(1 << 24)
+
+#define PCIE_LINK_TIMEOUT	1000000
+
+#define PCIE_STATUS_LINK_DOWN	1
+#define PCIE_STATUS_DEV_OFFS	16
+
+/* Minimum PCI Memory and I/O allocations taken from PCI spec (in bytes) */
+#define PCI_MIN_IO_ALLOC	4
+#define PCI_MIN_MEM_ALLOC	16
+
+#define BITS_PER_UINT32		(NBBY * sizeof(uint32_t))
+
+struct mv_pcib_softc {
+	device_t	sc_dev;
+
+	struct rman	sc_mem_rman;
+	bus_addr_t	sc_mem_base;
+	bus_addr_t	sc_mem_size;
+	uint32_t	sc_mem_map[MV_PCI_MEM_SLICE_SIZE /
+	    (PCI_MIN_MEM_ALLOC * BITS_PER_UINT32)];
+	int		sc_win_target;
+	int		sc_mem_win_attr;
+
+	struct rman	sc_io_rman;
+	bus_addr_t	sc_io_base;
+	bus_addr_t	sc_io_size;
+	uint32_t	sc_io_map[MV_PCI_IO_SLICE_SIZE /
+	    (PCI_MIN_IO_ALLOC * BITS_PER_UINT32)];
+	int		sc_io_win_attr;
+
+	struct resource	*sc_res;
+	bus_space_handle_t sc_bsh;
+	bus_space_tag_t	sc_bst;
+	int		sc_rid;
+
+	struct mtx	sc_msi_mtx;
+	uint32_t	sc_msi_bitmap;
+
+	int		sc_busnr;		/* Host bridge bus number */
+	int		sc_devnr;		/* Host bridge device number */
+	int		sc_type;
+	int		sc_mode;		/* Endpoint / Root Complex */
+
+	struct ofw_bus_iinfo	sc_pci_iinfo;
+};
+
+/* Local forward prototypes */
+static int mv_pcib_decode_win(phandle_t, struct mv_pcib_softc *);
+static void mv_pcib_hw_cfginit(void);
+static uint32_t mv_pcib_hw_cfgread(struct mv_pcib_softc *, u_int, u_int,
+    u_int, u_int, int);
+static void mv_pcib_hw_cfgwrite(struct mv_pcib_softc *, u_int, u_int,
+    u_int, u_int, uint32_t, int);
+static int mv_pcib_init(struct mv_pcib_softc *, int, int);
+static int mv_pcib_init_all_bars(struct mv_pcib_softc *, int, int, int, int);
+static void mv_pcib_init_bridge(struct mv_pcib_softc *, int, int, int);
+static inline void pcib_write_irq_mask(struct mv_pcib_softc *, uint32_t);
+static void mv_pcib_enable(struct mv_pcib_softc *, uint32_t);
+static int mv_pcib_mem_init(struct mv_pcib_softc *);
+
+/* Forward prototypes */
+static int mv_pcib_probe(device_t);
+static int mv_pcib_attach(device_t);
+
+static struct resource *mv_pcib_alloc_resource(device_t, device_t, int, int *,
+    u_long, u_long, u_long, u_int);
+static int mv_pcib_release_resource(device_t, device_t, int, int,
+    struct resource *);
+static int mv_pcib_read_ivar(device_t, device_t, int, uintptr_t *);
+static int mv_pcib_write_ivar(device_t, device_t, int, uintptr_t);
+
+static int mv_pcib_maxslots(device_t);
+static uint32_t mv_pcib_read_config(device_t, u_int, u_int, u_int, u_int, int);
+static void mv_pcib_write_config(device_t, u_int, u_int, u_int, u_int,
+    uint32_t, int);
+static int mv_pcib_route_interrupt(device_t, device_t, int);
+#if defined(SOC_MV_ARMADAXP)
+static int mv_pcib_alloc_msi(device_t, device_t, int, int, int *);
+static int mv_pcib_map_msi(device_t, device_t, int, uint64_t *, uint32_t *);
+static int mv_pcib_release_msi(device_t, device_t, int, int *);
+#endif
+
+/*
+ * Bus interface definitions.
+ */
+static device_method_t mv_pcib_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,			mv_pcib_probe),
+	DEVMETHOD(device_attach,		mv_pcib_attach),
+
+	/* Bus interface */
+	DEVMETHOD(bus_read_ivar,		mv_pcib_read_ivar),
+	DEVMETHOD(bus_write_ivar,		mv_pcib_write_ivar),
+	DEVMETHOD(bus_alloc_resource,		mv_pcib_alloc_resource),
+	DEVMETHOD(bus_release_resource,		mv_pcib_release_resource),
+	DEVMETHOD(bus_activate_resource,	bus_generic_activate_resource),
+	DEVMETHOD(bus_deactivate_resource,	bus_generic_deactivate_resource),
+	DEVMETHOD(bus_setup_intr,		bus_generic_setup_intr),
+	DEVMETHOD(bus_teardown_intr,		bus_generic_teardown_intr),
+
+	/* pcib interface */
+	DEVMETHOD(pcib_maxslots,		mv_pcib_maxslots),
+	DEVMETHOD(pcib_read_config,		mv_pcib_read_config),
+	DEVMETHOD(pcib_write_config,		mv_pcib_write_config),
+	DEVMETHOD(pcib_route_interrupt,		mv_pcib_route_interrupt),
+
+#if defined(SOC_MV_ARMADAXP)
+	DEVMETHOD(pcib_alloc_msi,		mv_pcib_alloc_msi),
+	DEVMETHOD(pcib_release_msi,		mv_pcib_release_msi),
+	DEVMETHOD(pcib_map_msi,			mv_pcib_map_msi),
+#endif
+
+	/* OFW bus interface */
+	DEVMETHOD(ofw_bus_get_compat,   ofw_bus_gen_get_compat),
+	DEVMETHOD(ofw_bus_get_model,    ofw_bus_gen_get_model),
+	DEVMETHOD(ofw_bus_get_name,     ofw_bus_gen_get_name),
+	DEVMETHOD(ofw_bus_get_node,     ofw_bus_gen_get_node),
+	DEVMETHOD(ofw_bus_get_type,     ofw_bus_gen_get_type),
+
+	DEVMETHOD_END
+};
+
+static driver_t mv_pcib_driver = {
+	"pcib",
+	mv_pcib_methods,
+	sizeof(struct mv_pcib_softc),
+};
+
+devclass_t pcib_devclass;
+
+DRIVER_MODULE(pcib, ofwbus, mv_pcib_driver, pcib_devclass, 0, 0);
+
+static struct mtx pcicfg_mtx;
+
+static int
+mv_pcib_probe(device_t self)
+{
+	phandle_t node;
+
+	node = ofw_bus_get_node(self);
+	if (!fdt_is_type(node, "pci"))
+		return (ENXIO);
+
+	if (!(ofw_bus_is_compatible(self, "mrvl,pcie") ||
+	    ofw_bus_is_compatible(self, "mrvl,pci")))
+		return (ENXIO);
+
+	device_set_desc(self, "Marvell Integrated PCI/PCI-E Controller");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+mv_pcib_attach(device_t self)
+{
+	struct mv_pcib_softc *sc;
+	phandle_t node, parnode;
+	uint32_t val, unit;
+	int err;
+
+	sc = device_get_softc(self);
+	sc->sc_dev = self;
+	unit = fdt_get_unit(self);
+
+
+	node = ofw_bus_get_node(self);
+	parnode = OF_parent(node);
+	if (fdt_is_compatible(node, "mrvl,pcie")) {
+		sc->sc_type = MV_TYPE_PCIE;
+		sc->sc_win_target = MV_WIN_PCIE_TARGET(unit);
+		sc->sc_mem_win_attr = MV_WIN_PCIE_MEM_ATTR(unit);
+		sc->sc_io_win_attr = MV_WIN_PCIE_IO_ATTR(unit);
+	} else if (fdt_is_compatible(node, "mrvl,pci")) {
+		sc->sc_type = MV_TYPE_PCI;
+		sc->sc_win_target = MV_WIN_PCI_TARGET;
+		sc->sc_mem_win_attr = MV_WIN_PCI_MEM_ATTR;
+		sc->sc_io_win_attr = MV_WIN_PCI_IO_ATTR;
+	} else
+		return (ENXIO);
+
+	/*
+	 * Retrieve our mem-mapped registers range.
+	 */
+	sc->sc_rid = 0;
+	sc->sc_res = bus_alloc_resource_any(self, SYS_RES_MEMORY, &sc->sc_rid,
+	    RF_ACTIVE);
+	if (sc->sc_res == NULL) {
+		device_printf(self, "could not map memory\n");
+		return (ENXIO);
+	}
+	sc->sc_bst = rman_get_bustag(sc->sc_res);
+	sc->sc_bsh = rman_get_bushandle(sc->sc_res);
+
+	val = bus_space_read_4(sc->sc_bst, sc->sc_bsh, PCIE_REG_CONTROL);
+	sc->sc_mode = (val & PCIE_CONTROL_ROOT_CMPLX ? MV_MODE_ROOT :
+	    MV_MODE_ENDPOINT);
+
+	/*
+	 * Get PCI interrupt info.
+	 */
+	if (sc->sc_mode == MV_MODE_ROOT)
+		ofw_bus_setup_iinfo(node, &sc->sc_pci_iinfo, sizeof(pcell_t));
+
+	/*
+	 * Configure decode windows for PCI(E) access.
+	 */
+	if (mv_pcib_decode_win(node, sc) != 0)
+		return (ENXIO);
+
+	mv_pcib_hw_cfginit();
+
+	/*
+	 * Enable PCIE device.
+	 */
+	mv_pcib_enable(sc, unit);
+
+	/*
+	 * Memory management.
+	 */
+	err = mv_pcib_mem_init(sc);
+	if (err)
+		return (err);
+
+	if (sc->sc_mode == MV_MODE_ROOT) {
+		err = mv_pcib_init(sc, sc->sc_busnr,
+		    mv_pcib_maxslots(sc->sc_dev));
+		if (err)
+			goto error;
+
+		device_add_child(self, "pci", -1);
+	} else {
+		sc->sc_devnr = 1;
+		bus_space_write_4(sc->sc_bst, sc->sc_bsh,
+		    PCIE_REG_STATUS, 1 << PCIE_STATUS_DEV_OFFS);
+		device_add_child(self, "pci_ep", -1);
+	}
+
+	mtx_init(&sc->sc_msi_mtx, "msi_mtx", NULL, MTX_DEF);
+	return (bus_generic_attach(self));
+
+error:
+	/* XXX SYS_RES_ should be released here */
+	rman_fini(&sc->sc_mem_rman);
+	rman_fini(&sc->sc_io_rman);
+
+	return (err);
+}
+
+static void
+mv_pcib_enable(struct mv_pcib_softc *sc, uint32_t unit)
+{
+	uint32_t val;
+#if !defined(SOC_MV_ARMADAXP)
+	int timeout;
+
+	/*
+	 * Check if PCIE device is enabled.
+	 */
+	if (read_cpu_ctrl(CPU_CONTROL) & CPU_CONTROL_PCIE_DISABLE(unit)) {
+		write_cpu_ctrl(CPU_CONTROL, read_cpu_ctrl(CPU_CONTROL) &
+		    ~(CPU_CONTROL_PCIE_DISABLE(unit)));
+
+		timeout = PCIE_LINK_TIMEOUT;
+		val = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
+		    PCIE_REG_STATUS);
+		while (((val & PCIE_STATUS_LINK_DOWN) == 1) && (timeout > 0)) {
+			DELAY(1000);
+			timeout -= 1000;
+			val = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
+			    PCIE_REG_STATUS);
+		}
+	}
+#endif
+
+
+	if (sc->sc_mode == MV_MODE_ROOT) {
+		/*
+		 * Enable PCI bridge.
+		 */
+		val = bus_space_read_4(sc->sc_bst, sc->sc_bsh, PCIR_COMMAND);
+		val |= PCIM_CMD_SERRESPEN | PCIM_CMD_BUSMASTEREN |
+		    PCIM_CMD_MEMEN | PCIM_CMD_PORTEN;
+		bus_space_write_4(sc->sc_bst, sc->sc_bsh, PCIR_COMMAND, val);
+	}
+}
+
+static int
+mv_pcib_mem_init(struct mv_pcib_softc *sc)
+{
+	int err;
+
+	/*
+	 * Memory management.
+	 */
+	sc->sc_mem_rman.rm_type = RMAN_ARRAY;
+	err = rman_init(&sc->sc_mem_rman);
+	if (err)
+		return (err);
+
+	sc->sc_io_rman.rm_type = RMAN_ARRAY;
+	err = rman_init(&sc->sc_io_rman);
+	if (err) {
+		rman_fini(&sc->sc_mem_rman);
+		return (err);
+	}
+
+	err = rman_manage_region(&sc->sc_mem_rman, sc->sc_mem_base,
+	    sc->sc_mem_base + sc->sc_mem_size - 1);
+	if (err)
+		goto error;
+
+	err = rman_manage_region(&sc->sc_io_rman, sc->sc_io_base,
+	    sc->sc_io_base + sc->sc_io_size - 1);
+	if (err)
+		goto error;
+
+	return (0);
+
+error:
+	rman_fini(&sc->sc_mem_rman);
+	rman_fini(&sc->sc_io_rman);
+
+	return (err);
+}
+
+static inline uint32_t
+pcib_bit_get(uint32_t *map, uint32_t bit)
+{
+	uint32_t n = bit / BITS_PER_UINT32;
+
+	bit = bit % BITS_PER_UINT32;
+	return (map[n] & (1 << bit));
+}
+
+static inline void
+pcib_bit_set(uint32_t *map, uint32_t bit)
+{
+	uint32_t n = bit / BITS_PER_UINT32;
+
+	bit = bit % BITS_PER_UINT32;
+	map[n] |= (1 << bit);
+}
+
+static inline uint32_t
+pcib_map_check(uint32_t *map, uint32_t start, uint32_t bits)
+{
+	uint32_t i;
+
+	for (i = start; i < start + bits; i++)
+		if (pcib_bit_get(map, i))
+			return (0);
+
+	return (1);
+}
+
+static inline void
+pcib_map_set(uint32_t *map, uint32_t start, uint32_t bits)
+{
+	uint32_t i;
+
+	for (i = start; i < start + bits; i++)
+		pcib_bit_set(map, i);
+}
+
+/*
+ * The idea of this allocator is taken from ARM No-Cache memory
+ * management code (sys/arm/arm/vm_machdep.c).
+ */
+static bus_addr_t
+pcib_alloc(struct mv_pcib_softc *sc, uint32_t smask)
+{
+	uint32_t bits, bits_limit, i, *map, min_alloc, size;
+	bus_addr_t addr = 0;
+	bus_addr_t base;
+
+	if (smask & 1) {
+		base = sc->sc_io_base;
+		min_alloc = PCI_MIN_IO_ALLOC;
+		bits_limit = sc->sc_io_size / min_alloc;
+		map = sc->sc_io_map;
+		smask &= ~0x3;
+	} else {
+		base = sc->sc_mem_base;
+		min_alloc = PCI_MIN_MEM_ALLOC;
+		bits_limit = sc->sc_mem_size / min_alloc;
+		map = sc->sc_mem_map;
+		smask &= ~0xF;
+	}
+
+	size = ~smask + 1;
+	bits = size / min_alloc;
+
+	for (i = 0; i + bits <= bits_limit; i += bits)
+		if (pcib_map_check(map, i, bits)) {
+			pcib_map_set(map, i, bits);
+			addr = base + (i * min_alloc);
+			return (addr);
+		}
+
+	return (addr);
+}
+
+static int
+mv_pcib_init_bar(struct mv_pcib_softc *sc, int bus, int slot, int func,
+    int barno)
+{
+	uint32_t addr, bar;
+	int reg, width;
+
+	reg = PCIR_BAR(barno);
+
+	/*
+	 * Need to init the BAR register with 0xffffffff before correct
+	 * value can be read.
+	 */
+	mv_pcib_write_config(sc->sc_dev, bus, slot, func, reg, ~0, 4);
+	bar = mv_pcib_read_config(sc->sc_dev, bus, slot, func, reg, 4);
+	if (bar == 0)
+		return (1);
+
+	/* Calculate BAR size: 64 or 32 bit (in 32-bit units) */
+	width = ((bar & 7) == 4) ? 2 : 1;
+
+	addr = pcib_alloc(sc, bar);
+	if (!addr)
+		return (-1);
+
+	if (bootverbose)
+		printf("PCI %u:%u:%u: reg %x: smask=%08x: addr=%08x\n",
+		    bus, slot, func, reg, bar, addr);
+
+	mv_pcib_write_config(sc->sc_dev, bus, slot, func, reg, addr, 4);
+	if (width == 2)
+		mv_pcib_write_config(sc->sc_dev, bus, slot, func, reg + 4,
+		    0, 4);
+
+	return (width);
+}
+
+static void
+mv_pcib_init_bridge(struct mv_pcib_softc *sc, int bus, int slot, int func)
+{
+	bus_addr_t io_base, mem_base;
+	uint32_t io_limit, mem_limit;
+	int secbus;
+
+	io_base = sc->sc_io_base;
+	io_limit = io_base + sc->sc_io_size - 1;
+	mem_base = sc->sc_mem_base;
+	mem_limit = mem_base + sc->sc_mem_size - 1;
+
+	/* Configure I/O decode registers */
+	mv_pcib_write_config(sc->sc_dev, bus, slot, func, PCIR_IOBASEL_1,
+	    io_base >> 8, 1);
+	mv_pcib_write_config(sc->sc_dev, bus, slot, func, PCIR_IOBASEH_1,
+	    io_base >> 16, 2);
+	mv_pcib_write_config(sc->sc_dev, bus, slot, func, PCIR_IOLIMITL_1,
+	    io_limit >> 8, 1);
+	mv_pcib_write_config(sc->sc_dev, bus, slot, func, PCIR_IOLIMITH_1,
+	    io_limit >> 16, 2);
+
+	/* Configure memory decode registers */
+	mv_pcib_write_config(sc->sc_dev, bus, slot, func, PCIR_MEMBASE_1,
+	    mem_base >> 16, 2);
+	mv_pcib_write_config(sc->sc_dev, bus, slot, func, PCIR_MEMLIMIT_1,
+	    mem_limit >> 16, 2);
+
+	/* Disable memory prefetch decode */
+	mv_pcib_write_config(sc->sc_dev, bus, slot, func, PCIR_PMBASEL_1,
+	    0x10, 2);
+	mv_pcib_write_config(sc->sc_dev, bus, slot, func, PCIR_PMBASEH_1,
+	    0x0, 4);
+	mv_pcib_write_config(sc->sc_dev, bus, slot, func, PCIR_PMLIMITL_1,
+	    0xF, 2);
+	mv_pcib_write_config(sc->sc_dev, bus, slot, func, PCIR_PMLIMITH_1,
+	    0x0, 4);
+
+	secbus = mv_pcib_read_config(sc->sc_dev, bus, slot, func,
+	    PCIR_SECBUS_1, 1);
+
+	/* Configure buses behind the bridge */
+	mv_pcib_init(sc, secbus, PCI_SLOTMAX);
+}
+
+static int
+mv_pcib_init(struct mv_pcib_softc *sc, int bus, int maxslot)
+{
+	int slot, func, maxfunc, error;
+	uint8_t hdrtype, command, class, subclass;
+
+	for (slot = 0; slot <= maxslot; slot++) {
+		maxfunc = 0;
+		for (func = 0; func <= maxfunc; func++) {
+			hdrtype = mv_pcib_read_config(sc->sc_dev, bus, slot,
+			    func, PCIR_HDRTYPE, 1);
+
+			if ((hdrtype & PCIM_HDRTYPE) > PCI_MAXHDRTYPE)
+				continue;
+
+			if (func == 0 && (hdrtype & PCIM_MFDEV))
+				maxfunc = PCI_FUNCMAX;
+
+			command = mv_pcib_read_config(sc->sc_dev, bus, slot,
+			    func, PCIR_COMMAND, 1);
+			command &= ~(PCIM_CMD_MEMEN | PCIM_CMD_PORTEN);
+			mv_pcib_write_config(sc->sc_dev, bus, slot, func,
+			    PCIR_COMMAND, command, 1);
+
+			error = mv_pcib_init_all_bars(sc, bus, slot, func,
+			    hdrtype);
+
+			if (error)
+				return (error);
+
+			command |= PCIM_CMD_BUSMASTEREN | PCIM_CMD_MEMEN |
+			    PCIM_CMD_PORTEN;
+			mv_pcib_write_config(sc->sc_dev, bus, slot, func,
+			    PCIR_COMMAND, command, 1);
+
+			/* Handle PCI-PCI bridges */
+			class = mv_pcib_read_config(sc->sc_dev, bus, slot,
+			    func, PCIR_CLASS, 1);
+			subclass = mv_pcib_read_config(sc->sc_dev, bus, slot,
+			    func, PCIR_SUBCLASS, 1);
+
+			if (class != PCIC_BRIDGE ||
+			    subclass != PCIS_BRIDGE_PCI)
+				continue;
+
+			mv_pcib_init_bridge(sc, bus, slot, func);
+		}
+	}
+
+	/* Enable all ABCD interrupts */
+	pcib_write_irq_mask(sc, (0xF << 24));
+
+	return (0);
+}
+
+static int
+mv_pcib_init_all_bars(struct mv_pcib_softc *sc, int bus, int slot,
+    int func, int hdrtype)
+{
+	int maxbar, bar, i;
+
+	maxbar = (hdrtype & PCIM_HDRTYPE) ? 0 : 6;
+	bar = 0;
+
+	/* Program the base address registers */
+	while (bar < maxbar) {
+		i = mv_pcib_init_bar(sc, bus, slot, func, bar);
+		bar += i;
+		if (i < 0) {
+			device_printf(sc->sc_dev,
+			    "PCI IO/Memory space exhausted\n");
+			return (ENOMEM);
+		}
+	}
+
+	return (0);
+}
+
+static struct resource *
+mv_pcib_alloc_resource(device_t dev, device_t child, int type, int *rid,
+    u_long start, u_long end, u_long count, u_int flags)
+{
+	struct mv_pcib_softc *sc = device_get_softc(dev);
+	struct rman *rm = NULL;
+	struct resource *res;
+
+	switch (type) {
+	case SYS_RES_IOPORT:
+		rm = &sc->sc_io_rman;
+		break;
+	case SYS_RES_MEMORY:
+		rm = &sc->sc_mem_rman;
+		break;
+	default:
+		return (BUS_ALLOC_RESOURCE(device_get_parent(dev), dev,
+		    type, rid, start, end, count, flags));
+	};
+
+	if ((start == 0UL) && (end == ~0UL)) {
+		start = sc->sc_mem_base;
+		end = sc->sc_mem_base + sc->sc_mem_size - 1;
+		count = sc->sc_mem_size;
+	}
+
+	if ((start < sc->sc_mem_base) || (start + count - 1 != end) ||
+	    (end > sc->sc_mem_base + sc->sc_mem_size - 1))
+		return (NULL);
+
+	res = rman_reserve_resource(rm, start, end, count, flags, child);
+	if (res == NULL)
+		return (NULL);
+
+	rman_set_rid(res, *rid);
+	rman_set_bustag(res, fdtbus_bs_tag);
+	rman_set_bushandle(res, start);
+
+	if (flags & RF_ACTIVE)
+		if (bus_activate_resource(child, type, *rid, res)) {
+			rman_release_resource(res);
+			return (NULL);
+		}
+
+	return (res);
+}
+
+static int
+mv_pcib_release_resource(device_t dev, device_t child, int type, int rid,
+    struct resource *res)
+{
+
+	if (type != SYS_RES_IOPORT && type != SYS_RES_MEMORY)
+		return (BUS_RELEASE_RESOURCE(device_get_parent(dev), child,
+		    type, rid, res));
+
+	return (rman_release_resource(res));
+}
+
+static int
+mv_pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
+{
+	struct mv_pcib_softc *sc = device_get_softc(dev);
+
+	switch (which) {
+	case PCIB_IVAR_BUS:
+		*result = sc->sc_busnr;
+		return (0);
+	case PCIB_IVAR_DOMAIN:
+		*result = device_get_unit(dev);
+		return (0);
+	}
+
+	return (ENOENT);
+}
+
+static int
+mv_pcib_write_ivar(device_t dev, device_t child, int which, uintptr_t value)
+{
+	struct mv_pcib_softc *sc = device_get_softc(dev);
+
+	switch (which) {
+	case PCIB_IVAR_BUS:
+		sc->sc_busnr = value;
+		return (0);
+	}
+
+	return (ENOENT);
+}
+
+static inline void
+pcib_write_irq_mask(struct mv_pcib_softc *sc, uint32_t mask)
+{
+
+	if (!sc->sc_type != MV_TYPE_PCI)
+		return;
+
+	bus_space_write_4(sc->sc_bst, sc->sc_bsh, PCIE_REG_IRQ_MASK, mask);
+}
+
+static void
+mv_pcib_hw_cfginit(void)
+{
+	static int opened = 0;
+
+	if (opened)
+		return;
+
+	mtx_init(&pcicfg_mtx, "pcicfg", NULL, MTX_SPIN);
+	opened = 1;
+}
+
+static uint32_t
+mv_pcib_hw_cfgread(struct mv_pcib_softc *sc, u_int bus, u_int slot,
+    u_int func, u_int reg, int bytes)
+{
+	uint32_t addr, data, ca, cd;
+
+	ca = (sc->sc_type != MV_TYPE_PCI) ?
+	    PCIE_REG_CFG_ADDR : PCI_REG_CFG_ADDR;
+	cd = (sc->sc_type != MV_TYPE_PCI) ?
+	    PCIE_REG_CFG_DATA : PCI_REG_CFG_DATA;
+	addr = PCI_CFG_ENA | PCI_CFG_BUS(bus) | PCI_CFG_DEV(slot) |
+	    PCI_CFG_FUN(func) | PCI_CFG_PCIE_REG(reg);
+
+	mtx_lock_spin(&pcicfg_mtx);
+	bus_space_write_4(sc->sc_bst, sc->sc_bsh, ca, addr);
+
+	data = ~0;
+	switch (bytes) {
+	case 1:
+		data = bus_space_read_1(sc->sc_bst, sc->sc_bsh,
+		    cd + (reg & 3));
+		break;
+	case 2:
+		data = le16toh(bus_space_read_2(sc->sc_bst, sc->sc_bsh,
+		    cd + (reg & 2)));
+		break;
+	case 4:
+		data = le32toh(bus_space_read_4(sc->sc_bst, sc->sc_bsh,
+		    cd));
+		break;
+	}
+	mtx_unlock_spin(&pcicfg_mtx);
+	return (data);
+}
+
+static void
+mv_pcib_hw_cfgwrite(struct mv_pcib_softc *sc, u_int bus, u_int slot,
+    u_int func, u_int reg, uint32_t data, int bytes)
+{
+	uint32_t addr, ca, cd;
+
+	ca = (sc->sc_type != MV_TYPE_PCI) ?
+	    PCIE_REG_CFG_ADDR : PCI_REG_CFG_ADDR;
+	cd = (sc->sc_type != MV_TYPE_PCI) ?
+	    PCIE_REG_CFG_DATA : PCI_REG_CFG_DATA;
+	addr = PCI_CFG_ENA | PCI_CFG_BUS(bus) | PCI_CFG_DEV(slot) |
+	    PCI_CFG_FUN(func) | PCI_CFG_PCIE_REG(reg);
+
+	mtx_lock_spin(&pcicfg_mtx);
+	bus_space_write_4(sc->sc_bst, sc->sc_bsh, ca, addr);
+
+	switch (bytes) {
+	case 1:
+		bus_space_write_1(sc->sc_bst, sc->sc_bsh,
+		    cd + (reg & 3), data);
+		break;
+	case 2:
+		bus_space_write_2(sc->sc_bst, sc->sc_bsh,
+		    cd + (reg & 2), htole16(data));
+		break;
+	case 4:
+		bus_space_write_4(sc->sc_bst, sc->sc_bsh,
+		    cd, htole32(data));
+		break;
+	}
+	mtx_unlock_spin(&pcicfg_mtx);
+}
+
+static int
+mv_pcib_maxslots(device_t dev)
+{
+	struct mv_pcib_softc *sc = device_get_softc(dev);
+
+	return ((sc->sc_type != MV_TYPE_PCI) ? 1 : PCI_SLOTMAX);
+}
+
+static uint32_t
+mv_pcib_read_config(device_t dev, u_int bus, u_int slot, u_int func,
+    u_int reg, int bytes)
+{
+	struct mv_pcib_softc *sc = device_get_softc(dev);
+
+	/* Return ~0 if link is inactive or trying to read from Root */
+	if ((bus_space_read_4(sc->sc_bst, sc->sc_bsh, PCIE_REG_STATUS) &
+	    PCIE_STATUS_LINK_DOWN) || (slot == 0))
+		return (~0U);
+
+	return (mv_pcib_hw_cfgread(sc, bus, slot, func, reg, bytes));
+}
+
+static void
+mv_pcib_write_config(device_t dev, u_int bus, u_int slot, u_int func,
+    u_int reg, uint32_t val, int bytes)
+{
+	struct mv_pcib_softc *sc = device_get_softc(dev);
+
+	/* Return if link is inactive or trying to write to Root */
+	if ((bus_space_read_4(sc->sc_bst, sc->sc_bsh, PCIE_REG_STATUS) &
+	    PCIE_STATUS_LINK_DOWN) || (slot == 0))
+		return;
+
+	mv_pcib_hw_cfgwrite(sc, bus, slot, func, reg, val, bytes);
+}
+
+static int
+mv_pcib_route_interrupt(device_t bus, device_t dev, int pin)
+{
+	struct mv_pcib_softc *sc;
+	struct ofw_pci_register reg;
+	uint32_t pintr, mintr[4];
+	int icells;
+	phandle_t iparent;
+
+	sc = device_get_softc(bus);
+	pintr = pin;
+
+	/* Fabricate imap information in case this isn't an OFW device */
+	bzero(&reg, sizeof(reg));
+	reg.phys_hi = (pci_get_bus(dev) << OFW_PCI_PHYS_HI_BUSSHIFT) |
+	    (pci_get_slot(dev) << OFW_PCI_PHYS_HI_DEVICESHIFT) |
+	    (pci_get_function(dev) << OFW_PCI_PHYS_HI_FUNCTIONSHIFT);
+
+	icells = ofw_bus_lookup_imap(ofw_bus_get_node(dev), &sc->sc_pci_iinfo,
+	    &reg, sizeof(reg), &pintr, sizeof(pintr), mintr, sizeof(mintr),
+	    &iparent);
+	if (icells > 0)
+		return (ofw_bus_map_intr(dev, iparent, icells, mintr));
+
+	/* Maybe it's a real interrupt, not an intpin */
+	if (pin > 4)
+		return (pin);
+
+	device_printf(bus, "could not route pin %d for device %d.%d\n",
+	    pin, pci_get_slot(dev), pci_get_function(dev));
+	return (PCI_INVALID_IRQ);
+}
+
+static int
+mv_pcib_decode_win(phandle_t node, struct mv_pcib_softc *sc)
+{
+	struct mv_pci_range io_space, mem_space;
+	device_t dev;
+	int error;
+
+	dev = sc->sc_dev;
+
+	if ((error = mv_pci_ranges(node, &io_space, &mem_space)) != 0) {
+		device_printf(dev, "could not retrieve 'ranges' data\n");
+		return (error);
+	}
+
+	/* Configure CPU decoding windows */
+	error = decode_win_cpu_set(sc->sc_win_target,
+	    sc->sc_io_win_attr, io_space.base_parent, io_space.len, ~0);
+	if (error < 0) {
+		device_printf(dev, "could not set up CPU decode "
+		    "window for PCI IO\n");
+		return (ENXIO);
+	}
+	error = decode_win_cpu_set(sc->sc_win_target,
+	    sc->sc_mem_win_attr, mem_space.base_parent, mem_space.len,
+	    mem_space.base_parent);
+	if (error < 0) {
+		device_printf(dev, "could not set up CPU decode "
+		    "windows for PCI MEM\n");
+		return (ENXIO);
+	}
+
+	sc->sc_io_base = io_space.base_parent;
+	sc->sc_io_size = io_space.len;
+
+	sc->sc_mem_base = mem_space.base_parent;
+	sc->sc_mem_size = mem_space.len;
+
+	return (0);
+}
+
+#if defined(SOC_MV_ARMADAXP)
+static int
+mv_pcib_map_msi(device_t dev, device_t child, int irq, uint64_t *addr,
+    uint32_t *data)
+{
+	struct mv_pcib_softc *sc;
+
+	sc = device_get_softc(dev);
+	irq = irq - MSI_IRQ;
+
+	/* validate parameters */
+	if (isclr(&sc->sc_msi_bitmap, irq)) {
+		device_printf(dev, "invalid MSI 0x%x\n", irq);
+		return (EINVAL);
+	}
+
+	mv_msi_data(irq, addr, data);
+
+	debugf("%s: irq: %d addr: %jx data: %x\n",
+	    __func__, irq, *addr, *data);
+
+	return (0);
+}
+
+static int
+mv_pcib_alloc_msi(device_t dev, device_t child, int count,
+    int maxcount __unused, int *irqs)
+{
+	struct mv_pcib_softc *sc;
+	u_int start = 0, i;
+
+	if (powerof2(count) == 0 || count > MSI_IRQ_NUM)
+		return (EINVAL);
+
+	sc = device_get_softc(dev);
+	mtx_lock(&sc->sc_msi_mtx);
+
+	for (start = 0; (start + count) < MSI_IRQ_NUM; start++) {
+		for (i = start; i < start + count; i++) {
+			if (isset(&sc->sc_msi_bitmap, i))
+				break;
+		}
+		if (i == start + count)
+			break;
+	}
+
+	if ((start + count) == MSI_IRQ_NUM) {
+		mtx_unlock(&sc->sc_msi_mtx);
+		return (ENXIO);
+	}
+
+	for (i = start; i < start + count; i++) {
+		setbit(&sc->sc_msi_bitmap, i);
+		*irqs++ = MSI_IRQ + i;
+	}
+	debugf("%s: start: %x count: %x\n", __func__, start, count);
+
+	mtx_unlock(&sc->sc_msi_mtx);
+	return (0);
+}
+
+static int
+mv_pcib_release_msi(device_t dev, device_t child, int count, int *irqs)
+{
+	struct mv_pcib_softc *sc;
+	u_int i;
+
+	sc = device_get_softc(dev);
+	mtx_lock(&sc->sc_msi_mtx);
+
+	for (i = 0; i < count; i++)
+		clrbit(&sc->sc_msi_bitmap, irqs[i] - MSI_IRQ);
+
+	mtx_unlock(&sc->sc_msi_mtx);
+	return (0);
+}
+#endif
+


Property changes on: trunk/sys/arm/mv/mv_pci.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/mv/mv_ts.c
===================================================================
--- trunk/sys/arm/mv/mv_ts.c	                        (rev 0)
+++ trunk/sys/arm/mv/mv_ts.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,182 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Hiroki Sato <hrs at FreeBSD.org>
+ * 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.
+ *
+ * Driver for on-die thermal sensor in 88F6282 and 88F6283.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/mv/mv_ts.c 266152 2014-05-15 16:11:06Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/sysctl.h>
+#include <machine/fdt.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <arm/mv/mvreg.h>
+#include <arm/mv/mvvar.h>
+
+static struct resource_spec mvts_res[] = {
+	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
+	{ -1, 0 }
+};
+
+struct mvts_softc {
+	device_t		sc_dev;
+	struct resource		*sc_res[sizeof(mvts_res)];
+};
+
+static int
+ts_probe(device_t dev)
+{
+	uint32_t d, r;
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "mrvl,ts"))
+		return (ENXIO);
+	soc_id(&d, &r);
+	switch (d) {
+	case MV_DEV_88F6282:
+		break;
+	default:
+		device_printf(dev, "unsupported SoC (ID: 0x%08X)!\n", d);
+		return (ENXIO);
+	}
+	device_set_desc(dev, "Marvell Thermal Sensor");
+
+	return (0);
+}
+
+#define	MV_TEMP_VALID_BIT	(1 << 9)
+#define	MV_TEMP_SENS_OFFS	10
+#define	MV_TEMP_SENS_MASK	0x1ff
+#define	MV_TEMP_SENS_READ_MAX	16
+#define	TZ_ZEROC		2732
+#define	MV_TEMP_CONVERT(x)	((((322 - x) * 100000) / 13625) + TZ_ZEROC)
+
+/*
+ * MSB                                 LSB
+ * 0000 0000 0000 0000 0000 0000 0000 0000
+ *                             ^- valid bit
+ *                  |---------|
+ *                         ^--- temperature (9 bits)
+ */
+
+static int
+ts_sysctl_handler(SYSCTL_HANDLER_ARGS)
+{
+	struct mvts_softc *sc;
+	device_t dev;
+	uint32_t ret, ret0;
+	u_int val;
+	int i;
+
+	dev = (device_t)arg1;
+	sc = device_get_softc(dev);
+	val = TZ_ZEROC;
+
+	ret = bus_read_4(sc->sc_res[0], 0);
+	if ((ret & MV_TEMP_VALID_BIT) == 0) {
+		device_printf(dev, "temperature sensor is broken.\n");
+		goto ts_sysctl_handle_int;
+	}
+	ret0 = 0;
+	for (i = 0; i < MV_TEMP_SENS_READ_MAX; i++) {
+		ret = bus_read_4(sc->sc_res[0], 0);
+		ret = (ret >> MV_TEMP_SENS_OFFS) & MV_TEMP_SENS_MASK;
+
+		/*
+		 * Successive reads should returns the same value except
+		 * for the LSB when the sensor is normal.
+		 */
+		if (((ret0 ^ ret) & 0x1fe) == 0)
+			break;
+		else
+			ret0 = ret;
+	}
+	if (i == MV_TEMP_SENS_READ_MAX) {
+		device_printf(dev, "temperature sensor is unstable.\n");
+		goto ts_sysctl_handle_int;
+	}
+	val = (u_int)MV_TEMP_CONVERT(ret);
+
+ts_sysctl_handle_int:
+	return (sysctl_handle_int(oidp, &val, 0, req));
+}
+
+static int
+ts_attach(device_t dev)
+{
+	struct mvts_softc *sc;
+	struct sysctl_ctx_list *ctx;
+	int error;
+
+	sc = device_get_softc(dev);
+	sc->sc_dev = dev;
+	error = bus_alloc_resources(dev, mvts_res, sc->sc_res);
+	if (error) {
+		device_printf(dev, "could not allocate resources\n");
+		return (ENXIO);
+	}
+	ctx = device_get_sysctl_ctx(dev);
+	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+	    OID_AUTO, "temperature", CTLTYPE_INT | CTLFLAG_RD, dev,
+	    0, ts_sysctl_handler, "IK", "Current Temperature");
+
+	return (0);
+}
+
+static int
+ts_detach(device_t dev)
+{
+
+	return (0);
+}
+
+static device_method_t ts_methods[] = {
+	DEVMETHOD(device_probe,		ts_probe),
+	DEVMETHOD(device_attach,	ts_attach),
+	DEVMETHOD(device_detach,	ts_detach),
+	{0, 0},
+};
+
+static driver_t ts_driver = {
+	"mvts",
+	ts_methods,
+	sizeof(struct mvts_softc),
+};
+
+static devclass_t ts_devclass;
+DRIVER_MODULE(mvts, simplebus, ts_driver, ts_devclass, 0, 0);
+MODULE_VERSION(mvts, 1);


Property changes on: trunk/sys/arm/mv/mv_ts.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/mv/mvreg.h
===================================================================
--- trunk/sys/arm/mv/mvreg.h	                        (rev 0)
+++ trunk/sys/arm/mv/mvreg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,448 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (C) 2007-2011 MARVELL INTERNATIONAL LTD.
+ * All rights reserved.
+ *
+ * Developed by Semihalf.
+ *
+ * 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.
+ * 3. Neither the name of MARVELL nor the names of contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY 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 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: stable/10/sys/arm/mv/mvreg.h 266277 2014-05-17 00:53:12Z ian $
+ */
+
+#ifndef _MVREG_H_
+#define _MVREG_H_
+
+#if defined(SOC_MV_DISCOVERY)
+#define IRQ_CAUSE_ERROR		0x0
+#define IRQ_CAUSE		0x4
+#define IRQ_CAUSE_HI		0x8
+#define IRQ_MASK_ERROR		0xC
+#define IRQ_MASK		0x10
+#define IRQ_MASK_HI		0x14
+#define IRQ_CAUSE_SELECT	0x18
+#define FIQ_MASK_ERROR		0x1C
+#define FIQ_MASK		0x20
+#define FIQ_MASK_HI		0x24
+#define FIQ_CAUSE_SELECT	0x28
+#define ENDPOINT_IRQ_MASK_ERROR(n) 0x2C
+#define ENDPOINT_IRQ_MASK(n)	0x30
+#define ENDPOINT_IRQ_MASK_HI(n)	0x34
+#define ENDPOINT_IRQ_CAUSE_SELECT 0x38
+#elif defined (SOC_MV_LOKIPLUS) || defined (SOC_MV_FREY)
+#define IRQ_CAUSE		0x0
+#define IRQ_MASK		0x4
+#define FIQ_MASK		0x8
+#define ENDPOINT_IRQ_MASK(n)	(0xC + (n) * 4)
+#define IRQ_CAUSE_HI		(-1)		/* Fake defines for unified */
+#define IRQ_MASK_HI		(-1)		/* interrupt controller code */
+#define FIQ_MASK_HI		(-1)
+#define ENDPOINT_IRQ_MASK_HI(n)	(-1)
+#define ENDPOINT_IRQ_MASK_ERROR(n) (-1)
+#define IRQ_CAUSE_ERROR		(-1)
+#define IRQ_MASK_ERROR		(-1)
+#elif defined (SOC_MV_ARMADAXP)
+#define IRQ_CAUSE		0x18
+#define IRQ_MASK		0x30
+#else /* !SOC_MV_DISCOVERY && !SOC_MV_LOKIPLUS */
+#define IRQ_CAUSE		0x0
+#define IRQ_MASK		0x4
+#define FIQ_MASK		0x8
+#define ENDPOINT_IRQ_MASK(n)	0xC
+#define IRQ_CAUSE_HI		0x10
+#define IRQ_MASK_HI		0x14
+#define FIQ_MASK_HI		0x18
+#define ENDPOINT_IRQ_MASK_HI(n)	0x1C
+#define ENDPOINT_IRQ_MASK_ERROR(n) (-1)
+#define IRQ_CAUSE_ERROR		(-1)		/* Fake defines for unified */
+#define IRQ_MASK_ERROR		(-1)		/* interrupt controller code */
+#endif
+
+#if defined(SOC_MV_FREY)
+#define BRIDGE_IRQ_CAUSE	0x118
+#define IRQ_TIMER0		0x00000002
+#define IRQ_TIMER1		0x00000004
+#define IRQ_TIMER_WD		0x00000008
+
+#define BRIDGE_IRQ_MASK		0x11c
+#define IRQ_TIMER0_MASK		0x00000002
+#define IRQ_TIMER1_MASK		0x00000004
+#define IRQ_TIMER_WD_MASK	0x00000008
+#elif defined(SOC_MV_ARMADAXP)
+#define BRIDGE_IRQ_CAUSE	0x68
+#define IRQ_TIMER0		0x00000001
+#define IRQ_TIMER1		0x00000002
+#define IRQ_TIMER_WD		0x00000004
+#else
+#define BRIDGE_IRQ_CAUSE	0x10
+#define IRQ_CPU_SELF		0x00000001
+#define IRQ_TIMER0		0x00000002
+#define IRQ_TIMER1		0x00000004
+#define IRQ_TIMER_WD		0x00000008
+
+#define BRIDGE_IRQ_MASK		0x14
+#define IRQ_CPU_MASK		0x00000001
+#define IRQ_TIMER0_MASK		0x00000002
+#define IRQ_TIMER1_MASK		0x00000004
+#define IRQ_TIMER_WD_MASK	0x00000008
+#endif
+
+#if defined(SOC_MV_LOKIPLUS) || defined(SOC_MV_FREY)
+#define IRQ_CPU_SELF_CLR	IRQ_CPU_SELF
+#define IRQ_TIMER0_CLR		IRQ_TIMER0
+#define IRQ_TIMER1_CLR		IRQ_TIMER1
+#define IRQ_TIMER_WD_CLR	IRQ_TIMER_WD
+#else
+#define IRQ_CPU_SELF_CLR	(~IRQ_CPU_SELF)
+#define IRQ_TIMER0_CLR		(~IRQ_TIMER0)
+#define IRQ_TIMER1_CLR		(~IRQ_TIMER1)
+#define IRQ_TIMER_WD_CLR	(~IRQ_TIMER_WD)
+#endif
+
+/*
+ * System reset
+ */
+#if defined(SOC_MV_ARMADAXP)
+#define RSTOUTn_MASK		0x60
+#define SYSTEM_SOFT_RESET	0x64
+#define WD_RSTOUTn_MASK		0x4
+#define WD_GLOBAL_MASK		0x00000100
+#define WD_CPU0_MASK		0x00000001
+#define SOFT_RST_OUT_EN		0x00000001
+#define SYS_SOFT_RST		0x00000001
+#else
+#define RSTOUTn_MASK		0x8
+#define WD_RST_OUT_EN		0x00000002
+#define SOFT_RST_OUT_EN		0x00000004
+#define SYSTEM_SOFT_RESET	0xc
+#define SYS_SOFT_RST		0x00000001
+#endif
+
+/*
+ * Power Control
+ */
+#if defined(SOC_MV_KIRKWOOD)
+#define CPU_PM_CTRL		0x18
+#else
+#define CPU_PM_CTRL		0x1C
+#endif
+#define CPU_PM_CTRL_NONE	0
+#define CPU_PM_CTRL_ALL		~0x0
+
+#if defined(SOC_MV_KIRKWOOD)
+#define CPU_PM_CTRL_GE0		(1 << 0)
+#define CPU_PM_CTRL_PEX0_PHY	(1 << 1)
+#define CPU_PM_CTRL_PEX0	(1 << 2)
+#define CPU_PM_CTRL_USB0	(1 << 3)
+#define CPU_PM_CTRL_SDIO	(1 << 4)
+#define CPU_PM_CTRL_TSU		(1 << 5)
+#define CPU_PM_CTRL_DUNIT	(1 << 6)
+#define CPU_PM_CTRL_RUNIT	(1 << 7)
+#define CPU_PM_CTRL_XOR0	(1 << 8)
+#define CPU_PM_CTRL_AUDIO	(1 << 9)
+#define CPU_PM_CTRL_SATA0	(1 << 14)
+#define CPU_PM_CTRL_SATA1	(1 << 15)
+#define CPU_PM_CTRL_XOR1	(1 << 16)
+#define CPU_PM_CTRL_CRYPTO	(1 << 17)
+#define CPU_PM_CTRL_GE1		(1 << 19)
+#define CPU_PM_CTRL_TDM		(1 << 20)
+#define CPU_PM_CTRL_XOR		(CPU_PM_CTRL_XOR0 | CPU_PM_CTRL_XOR1)
+#define CPU_PM_CTRL_USB(u)	(CPU_PM_CTRL_USB0)
+#define CPU_PM_CTRL_SATA	(CPU_PM_CTRL_SATA0 | CPU_PM_CTRL_SATA1)
+#define CPU_PM_CTRL_GE(u)	(CPU_PM_CTRL_GE1 * (u) | CPU_PM_CTRL_GE0 * \
+				(1 - (u)))
+#define CPU_PM_CTRL_IDMA	(CPU_PM_CTRL_NONE)
+#elif defined(SOC_MV_DISCOVERY)
+#define CPU_PM_CTRL_GE0		(1 << 1)
+#define CPU_PM_CTRL_GE1		(1 << 2)
+#define CPU_PM_CTRL_PEX00	(1 << 5)
+#define CPU_PM_CTRL_PEX01	(1 << 6)
+#define CPU_PM_CTRL_PEX02	(1 << 7)
+#define CPU_PM_CTRL_PEX03	(1 << 8)
+#define CPU_PM_CTRL_PEX10	(1 << 9)
+#define CPU_PM_CTRL_PEX11	(1 << 10)
+#define CPU_PM_CTRL_PEX12	(1 << 11)
+#define CPU_PM_CTRL_PEX13	(1 << 12)
+#define CPU_PM_CTRL_SATA0_PHY	(1 << 13)
+#define CPU_PM_CTRL_SATA0	(1 << 14)
+#define CPU_PM_CTRL_SATA1_PHY	(1 << 15)
+#define CPU_PM_CTRL_SATA1	(1 << 16)
+#define CPU_PM_CTRL_USB0	(1 << 17)
+#define CPU_PM_CTRL_USB1	(1 << 18)
+#define CPU_PM_CTRL_USB2	(1 << 19)
+#define CPU_PM_CTRL_IDMA	(1 << 20)
+#define CPU_PM_CTRL_XOR		(1 << 21)
+#define CPU_PM_CTRL_CRYPTO	(1 << 22)
+#define CPU_PM_CTRL_DEVICE	(1 << 23)
+#define CPU_PM_CTRL_USB(u)	(1 << (17 + (u)))
+#define CPU_PM_CTRL_SATA	(CPU_PM_CTRL_SATA0 | CPU_PM_CTRL_SATA1)
+#define CPU_PM_CTRL_GE(u)	(CPU_PM_CTRL_GE1 * (u) | CPU_PM_CTRL_GE0 * \
+				(1 - (u)))
+#else
+#define CPU_PM_CTRL_CRYPTO	(CPU_PM_CTRL_NONE)
+#define CPU_PM_CTRL_IDMA	(CPU_PM_CTRL_NONE)
+#define CPU_PM_CTRL_XOR		(CPU_PM_CTRL_NONE)
+#define CPU_PM_CTRL_SATA	(CPU_PM_CTRL_NONE)
+#define CPU_PM_CTRL_USB(u)	(CPU_PM_CTRL_NONE)
+#define CPU_PM_CTRL_GE(u)	(CPU_PM_CTRL_NONE)
+#endif
+
+/*
+ * Timers
+ */
+#define CPU_TIMERS_BASE		0x300
+#define CPU_TIMER_CONTROL	0x0
+#define CPU_TIMER0_EN		0x00000001
+#define CPU_TIMER0_AUTO		0x00000002
+#define CPU_TIMER1_EN		0x00000004
+#define CPU_TIMER1_AUTO		0x00000008
+#define CPU_TIMER_WD_EN		0x00000010
+#define CPU_TIMER_WD_AUTO	0x00000020
+/* 25MHz mode is Armada XP - specific */
+#define CPU_TIMER_WD_25MHZ_EN	0x00000400
+#define CPU_TIMER0_25MHZ_EN	0x00000800
+#define CPU_TIMER1_25MHZ_EN	0x00001000
+#define CPU_TIMER0_REL		0x10
+#define CPU_TIMER0		0x14
+
+/*
+ * SATA
+ */
+#define SATA_CHAN_NUM			2
+
+#define EDMA_REGISTERS_OFFSET		0x2000
+#define EDMA_REGISTERS_SIZE		0x2000
+#define SATA_EDMA_BASE(ch)		(EDMA_REGISTERS_OFFSET + \
+    ((ch) * EDMA_REGISTERS_SIZE))
+
+/* SATAHC registers */
+#define SATA_CR				0x000 /* Configuration Reg. */
+#define SATA_CR_NODMABS			(1 << 8)
+#define SATA_CR_NOEDMABS		(1 << 9)
+#define SATA_CR_NOPRDPBS		(1 << 10)
+#define SATA_CR_COALDIS(ch)		(1 << (24 + ch))
+
+/* Interrupt Coalescing Threshold Reg. */
+#define SATA_ICTR			0x00C
+#define SATA_ICTR_MAX			((1 << 8) - 1)
+
+/* Interrupt Time Threshold Reg. */
+#define SATA_ITTR			0x010
+#define SATA_ITTR_MAX			((1 << 24) - 1)
+
+#define SATA_ICR			0x014 /* Interrupt Cause Reg. */
+#define SATA_ICR_DMADONE(ch)		(1 << (ch))
+#define SATA_ICR_COAL			(1 << 4)
+#define SATA_ICR_DEV(ch)		(1 << (8 + ch))
+
+#define SATA_MICR			0x020 /* Main Interrupt Cause Reg. */
+#define SATA_MICR_ERR(ch)		(1 << (2 * ch))
+#define SATA_MICR_DONE(ch)		(1 << ((2 * ch) + 1))
+#define SATA_MICR_DMADONE(ch)		(1 << (4 + ch))
+#define SATA_MICR_COAL			(1 << 8)
+
+#define SATA_MIMR			0x024 /*  Main Interrupt Mask Reg. */
+
+/* Shadow registers */
+#define SATA_SHADOWR_BASE(ch)		(SATA_EDMA_BASE(ch) + 0x100)
+#define SATA_SHADOWR_CONTROL(ch)	(SATA_EDMA_BASE(ch) + 0x120)
+
+/* SATA registers */
+#define SATA_SATA_SSTATUS(ch)		(SATA_EDMA_BASE(ch) + 0x300)
+#define SATA_SATA_SERROR(ch)		(SATA_EDMA_BASE(ch) + 0x304)
+#define SATA_SATA_SCONTROL(ch)		(SATA_EDMA_BASE(ch) + 0x308)
+#define SATA_SATA_FISICR(ch)		(SATA_EDMA_BASE(ch) + 0x364)
+
+/* EDMA registers */
+#define SATA_EDMA_CFG(ch)		(SATA_EDMA_BASE(ch) + 0x000)
+#define SATA_EDMA_CFG_QL128		(1 << 19)
+#define SATA_EDMA_CFG_HQCACHE		(1 << 22)
+
+#define SATA_EDMA_IECR(ch)		(SATA_EDMA_BASE(ch) + 0x008)
+
+#define SATA_EDMA_IEMR(ch)		(SATA_EDMA_BASE(ch) + 0x00C)
+#define SATA_EDMA_REQBAHR(ch)		(SATA_EDMA_BASE(ch) + 0x010)
+#define SATA_EDMA_REQIPR(ch)		(SATA_EDMA_BASE(ch) + 0x014)
+#define SATA_EDMA_REQOPR(ch)		(SATA_EDMA_BASE(ch) + 0x018)
+#define SATA_EDMA_RESBAHR(ch)		(SATA_EDMA_BASE(ch) + 0x01C)
+#define SATA_EDMA_RESIPR(ch)		(SATA_EDMA_BASE(ch) + 0x020)
+#define SATA_EDMA_RESOPR(ch)		(SATA_EDMA_BASE(ch) + 0x024)
+
+#define SATA_EDMA_CMD(ch)		(SATA_EDMA_BASE(ch) + 0x028)
+#define SATA_EDMA_CMD_ENABLE		(1 << 0)
+#define SATA_EDMA_CMD_DISABLE		(1 << 1)
+#define SATA_EDMA_CMD_RESET		(1 << 2)
+
+#define SATA_EDMA_STATUS(ch)		(SATA_EDMA_BASE(ch) + 0x030)
+#define SATA_EDMA_STATUS_IDLE		(1 << 7)
+
+/* Offset to extract input slot from REQIPR register */
+#define SATA_EDMA_REQIS_OFS		5
+
+/* Offset to extract input slot from RESOPR register */
+#define SATA_EDMA_RESOS_OFS		3
+
+/*
+ * GPIO
+ */
+#define GPIO_DATA_OUT		0x00
+#define GPIO_DATA_OUT_EN_CTRL	0x04
+#define GPIO_BLINK_EN		0x08
+#define GPIO_DATA_IN_POLAR	0x0c
+#define GPIO_DATA_IN		0x10
+#define GPIO_INT_CAUSE		0x14
+#define GPIO_INT_EDGE_MASK	0x18
+#define GPIO_INT_LEV_MASK	0x1c
+
+#define GPIO_HI_DATA_OUT		0x40
+#define GPIO_HI_DATA_OUT_EN_CTRL	0x44
+#define GPIO_HI_BLINK_EN		0x48
+#define GPIO_HI_DATA_IN_POLAR		0x4c
+#define GPIO_HI_DATA_IN			0x50
+#define GPIO_HI_INT_CAUSE		0x54
+#define GPIO_HI_INT_EDGE_MASK		0x58
+#define GPIO_HI_INT_LEV_MASK		0x5c
+
+#define GPIO(n)			(1 << (n))
+#define MV_GPIO_MAX_NPINS	64
+
+#define MV_GPIO_IN_NONE		0x0
+#define MV_GPIO_IN_POL_LOW	(1 << 16)
+#define MV_GPIO_IN_IRQ_EDGE	(2 << 16)
+#define MV_GPIO_IN_IRQ_LEVEL	(4 << 16)
+#define MV_GPIO_OUT_NONE	0x0
+#define MV_GPIO_OUT_BLINK	0x1
+#define MV_GPIO_OUT_OPEN_DRAIN	0x2
+#define MV_GPIO_OUT_OPEN_SRC	0x4
+
+#define IS_GPIO_IRQ(irq)	((irq) >= NIRQ && (irq) < NIRQ + MV_GPIO_MAX_NPINS)
+#define GPIO2IRQ(gpio)		((gpio) + NIRQ)
+#define IRQ2GPIO(irq)		((irq) - NIRQ)
+
+#if defined(SOC_MV_ORION) || defined(SOC_MV_LOKIPLUS)
+#define SAMPLE_AT_RESET		0x10
+#elif defined(SOC_MV_KIRKWOOD)
+#define SAMPLE_AT_RESET		0x30
+#elif defined(SOC_MV_FREY)
+#define SAMPLE_AT_RESET		0x100
+#endif
+#if defined(SOC_MV_DISCOVERY)
+#define SAMPLE_AT_RESET_LO	0x30
+#define SAMPLE_AT_RESET_HI	0x34
+#elif defined(SOC_MV_DOVE)
+#define SAMPLE_AT_RESET_LO	0x14
+#define SAMPLE_AT_RESET_HI	0x18
+#elif defined(SOC_MV_ARMADAXP)
+#define SAMPLE_AT_RESET_LO	0x30
+#define SAMPLE_AT_RESET_HI	0x34
+#endif
+
+/*
+ * Clocks
+ */
+#if defined(SOC_MV_ORION)
+#define TCLK_MASK		0x00000300
+#define TCLK_SHIFT		0x08
+#elif defined(SOC_MV_DISCOVERY)
+#define TCLK_MASK		0x00000180
+#define TCLK_SHIFT		0x07
+#elif defined(SOC_MV_LOKIPLUS)
+#define TCLK_MASK		0x0000F000
+#define TCLK_SHIFT		0x0C
+#endif
+
+#define TCLK_100MHZ		100000000
+#define TCLK_125MHZ		125000000
+#define TCLK_133MHZ		133333333
+#define TCLK_150MHZ		150000000
+#define TCLK_166MHZ		166666667
+#define TCLK_200MHZ		200000000
+#define TCLK_250MHZ		250000000
+#define TCLK_300MHZ		300000000
+#define TCLK_667MHZ		667000000
+
+/*
+ * CPU Cache Configuration
+ */
+
+#define CPU_CONFIG		0x00000000
+#define CPU_CONFIG_IC_PREF	0x00010000
+#define CPU_CONFIG_DC_PREF	0x00020000
+#define CPU_CONTROL		0x00000004
+#define CPU_CONTROL_L2_SIZE	0x00200000	/* Only on Discovery */
+#define CPU_CONTROL_L2_MODE	0x00020000	/* Only on Discovery */
+#define CPU_L2_CONFIG		0x00000028	/* Only on Kirkwood */
+#define CPU_L2_CONFIG_MODE	0x00000010	/* Only on Kirkwood */
+
+/*
+ * PCI Express port control (CPU Control registers)
+ */
+#define CPU_CONTROL_PCIE_DISABLE(n)	(1 << (3 * (n)))
+
+/*
+ * Vendor ID
+ */
+#define PCI_VENDORID_MRVL	0x11AB
+#define PCI_VENDORID_MRVL2	0x1B4B
+
+/*
+ * Chip ID
+ */
+#define MV_DEV_88F5181		0x5181
+#define MV_DEV_88F5182		0x5182
+#define MV_DEV_88F5281		0x5281
+#define MV_DEV_88F6281		0x6281
+#define MV_DEV_88F6282		0x6282
+#define MV_DEV_88F6781		0x6781
+#define MV_DEV_MV78100_Z0	0x6381
+#define MV_DEV_MV78100		0x7810
+#define MV_DEV_MV78130		0x7813
+#define MV_DEV_MV78160		0x7816
+#define MV_DEV_MV78230		0x7823
+#define MV_DEV_MV78260		0x7826
+#define MV_DEV_MV78460		0x7846
+#define MV_DEV_88RC8180		0x8180
+#define MV_DEV_88RC9480		0x9480
+#define MV_DEV_88RC9580		0x9580
+
+#define MV_DEV_FAMILY_MASK	0xff00
+#define MV_DEV_DISCOVERY	0x7800
+
+/*
+ * Doorbell register control
+ */
+#define MV_DRBL_PCIE_TO_CPU	0
+#define MV_DRBL_CPU_TO_PCIE	1
+
+#if defined(SOC_MV_FREY)
+#define MV_DRBL_CAUSE(d,u)	(0x60 + 0x20 * (d) + 0x8 * (u))
+#define MV_DRBL_MASK(d,u)	(0x60 + 0x20 * (d) + 0x8 * (u) + 0x4)
+#define MV_DRBL_MSG(m,d,u)	(0x8 * (u) + 0x20 * (d) + 0x4 * (m))
+#else
+#define MV_DRBL_CAUSE(d,u)	(0x10 * (u) + 0x8 * (d))
+#define MV_DRBL_MASK(d,u)	(0x10 * (u) + 0x8 * (d) + 0x4)
+#define MV_DRBL_MSG(m,d,u)	(0x10 * (u) + 0x8 * (d) + 0x4 * (m) + 0x30)
+#endif
+#endif /* _MVREG_H_ */


Property changes on: trunk/sys/arm/mv/mvreg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/mv/mvvar.h
===================================================================
--- trunk/sys/arm/mv/mvvar.h	                        (rev 0)
+++ trunk/sys/arm/mv/mvvar.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,146 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2002, 2003 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Jason R. Thorpe for Wasabi Systems, Inc.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed for the NetBSD Project by
+ *	Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
+ * 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.
+ *
+ * from: FreeBSD: //depot/projects/arm/src/sys/arm/xscale/pxa2x0/pxa2x0var.h, rev 1
+ *
+ * $FreeBSD: stable/10/sys/arm/mv/mvvar.h 266084 2014-05-14 19:18:58Z ian $
+ */
+
+#ifndef _MVVAR_H_
+#define _MVVAR_H_
+
+#include <sys/rman.h>
+#include <machine/bus.h>
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <machine/vm.h>
+
+#include <dev/ofw/openfirm.h>
+
+#define	MV_TYPE_PCI		0
+#define	MV_TYPE_PCIE		1
+
+#define MV_MODE_ENDPOINT	0
+#define MV_MODE_ROOT		1
+
+struct gpio_config {
+	int		gc_gpio;	/* GPIO number */
+	uint32_t	gc_flags;	/* GPIO flags */
+	int		gc_output;	/* GPIO output value */
+};
+
+struct decode_win {
+	int		target;		/* Mbus unit ID */
+	int		attr;		/* Attributes of the target interface */
+	vm_paddr_t	base;		/* Physical base addr */
+	uint32_t	size;
+	vm_paddr_t	remap;
+};
+
+extern const struct gpio_config mv_gpio_config[];
+extern const struct decode_win *cpu_wins;
+extern const struct decode_win *idma_wins;
+extern const struct decode_win *xor_wins;
+extern int idma_wins_no;
+extern int xor_wins_no;
+
+/* Function prototypes */
+int mv_gpio_setup_intrhandler(const char *name, driver_filter_t *filt,
+    void (*hand)(void *), void *arg, int pin, int flags, void **cookiep);
+void mv_gpio_intr_mask(int pin);
+void mv_gpio_intr_unmask(int pin);
+void mv_gpio_out(uint32_t pin, uint8_t val, uint8_t enable);
+uint8_t mv_gpio_in(uint32_t pin);
+int platform_gpio_init(void);
+
+int soc_decode_win(void);
+void soc_id(uint32_t *dev, uint32_t *rev);
+void soc_dump_decode_win(void);
+uint32_t soc_power_ctrl_get(uint32_t mask);
+void soc_power_ctrl_set(uint32_t mask);
+uint64_t get_sar_value(void);
+
+int decode_win_cpu_set(int target, int attr, vm_paddr_t base, uint32_t size,
+    vm_paddr_t remap);
+int decode_win_overlap(int, int, const struct decode_win *);
+int win_cpu_can_remap(int);
+void decode_win_pcie_setup(u_long);
+
+void ddr_disable(int i);
+int ddr_is_active(int i);
+uint32_t ddr_base(int i);
+uint32_t ddr_size(int i);
+uint32_t ddr_attr(int i);
+uint32_t ddr_target(int i);
+
+uint32_t cpu_extra_feat(void);
+uint32_t get_tclk(void);
+uint32_t get_l2clk(void);
+uint32_t read_cpu_ctrl(uint32_t);
+void write_cpu_ctrl(uint32_t, uint32_t);
+
+#if defined(SOC_MV_ARMADAXP)
+uint32_t read_cpu_mp_clocks(uint32_t reg);
+void write_cpu_mp_clocks(uint32_t reg, uint32_t val);
+uint32_t read_cpu_misc(uint32_t reg);
+void write_cpu_misc(uint32_t reg, uint32_t val);
+#endif
+
+int mv_pcib_bar_win_set(device_t dev, uint32_t base, uint32_t size,
+    uint32_t remap, int winno, int busno);
+int mv_pcib_cpu_win_remap(device_t dev, uint32_t remap, uint32_t size);
+
+void mv_mask_endpoint_irq(uintptr_t nb, int unit);
+void mv_unmask_endpoint_irq(uintptr_t nb, int unit);
+
+int	mv_drbl_get_next_irq(int dir, int unit);
+void	mv_drbl_mask_all(int unit);
+void	mv_drbl_mask_irq(uint32_t irq, int dir, int unit);
+void	mv_drbl_unmask_irq(uint32_t irq, int dir, int unit);
+void	mv_drbl_set_mask(uint32_t val, int dir, int unit);
+uint32_t mv_drbl_get_mask(int dir, int unit);
+void	mv_drbl_set_cause(uint32_t val, int dir, int unit);
+uint32_t mv_drbl_get_cause(int dir, int unit);
+void	mv_drbl_set_msg(uint32_t val, int mnr, int dir, int unit);
+uint32_t mv_drbl_get_msg(int mnr, int dir, int unit);
+
+int	mv_msi_data(int irq, uint64_t *addr, uint32_t *data);
+
+struct arm_devmap_entry;
+
+int mv_pci_devmap(phandle_t, struct arm_devmap_entry *, vm_offset_t,
+    vm_offset_t);
+
+#endif /* _MVVAR_H_ */


Property changes on: trunk/sys/arm/mv/mvvar.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/mv/mvwin.h
===================================================================
--- trunk/sys/arm/mv/mvwin.h	                        (rev 0)
+++ trunk/sys/arm/mv/mvwin.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,391 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (C) 2007-2011 MARVELL INTERNATIONAL LTD.
+ * All rights reserved.
+ *
+ * Developed by Semihalf.
+ *
+ * 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.
+ * 3. Neither the name of MARVELL nor the names of contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY 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 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: stable/10/sys/arm/mv/mvwin.h 250295 2013-05-06 14:54:17Z gber $
+ */
+
+#ifndef _MVWIN_H_
+#define _MVWIN_H_
+
+/*
+ * Decode windows addresses.
+ *
+ * All decoding windows must be aligned to their size, which has to be
+ * a power of 2.
+ */
+
+/*
+ * SoC Integrated devices: 0xF1000000, 16 MB (VA == PA)
+ */
+
+/* SoC Regs */
+#define MV_PHYS_BASE		0xF1000000
+#define MV_SIZE			(1024 * 1024)	/* 1 MB */
+
+/* SRAM */
+#define MV_CESA_SRAM_BASE	0xF1100000
+
+/* AXI Regs */
+#ifdef SOC_MV_DOVE
+#define MV_AXI_PHYS_BASE	0xF1800000
+#define MV_AXI_BASE		MV_AXI_PHYS_BASE
+#define MV_AXI_SIZE		(16 * 1024 * 1024)	/* 16 MB */
+#endif
+
+/*
+ * External devices: 0x80000000, 1 GB (VA == PA)
+ * Includes Device Bus, PCI and PCIE.
+ */
+#if defined(SOC_MV_ORION)
+#define MV_PCI_PORTS	2	/* 1x PCI + 1x PCIE */
+#elif defined(SOC_MV_KIRKWOOD) || defined(SOC_MV_FREY)
+#define MV_PCI_PORTS	1	/* 1x PCIE */
+#elif defined(SOC_MV_DISCOVERY)
+#define MV_PCI_PORTS	8	/* 8x PCIE */
+#elif defined(SOC_MV_DOVE) || defined(SOC_MV_LOKIPLUS)
+#define MV_PCI_PORTS	2	/* 2x PCIE */
+#elif defined(SOC_MV_ARMADAXP)
+#define MV_PCI_PORTS	3	/* 3x PCIE */
+#else
+#error "MV_PCI_PORTS not configured !"
+#endif
+
+/* PCI/PCIE Memory */
+#define MV_PCI_MEM_PHYS_BASE	0x80000000
+#define MV_PCI_MEM_SIZE		(512 * 1024 * 1024)	/* 512 MB */
+#define MV_PCI_MEM_BASE		MV_PCI_MEM_PHYS_BASE
+#define MV_PCI_MEM_SLICE_SIZE	(MV_PCI_MEM_SIZE / MV_PCI_PORTS)
+#define MV_PCI_MEM_SLICE(n)	(MV_PCI_MEM_BASE + ((n) * \
+				    MV_PCI_MEM_SLICE_SIZE))
+/* PCI/PCIE I/O */
+#define MV_PCI_IO_PHYS_BASE	0xBF000000
+#define MV_PCI_IO_SIZE		(16 * 1024 * 1024)	/* 16 MB */
+#define MV_PCI_IO_BASE		MV_PCI_IO_PHYS_BASE
+#define MV_PCI_IO_SLICE_SIZE	(MV_PCI_IO_SIZE / MV_PCI_PORTS)
+#define MV_PCI_IO_SLICE(n)	(MV_PCI_IO_BASE + ((n) * MV_PCI_IO_SLICE_SIZE))
+
+#if defined(SOC_MV_FREY)
+#define MV_PCI_VA_MEM_BASE	MV_PCI_MEM_BASE
+#else
+#define MV_PCI_VA_MEM_BASE	0
+#endif
+#define MV_PCI_VA_IO_BASE	0
+
+/*
+ * Device Bus (VA == PA)
+ */
+#define MV_DEV_BOOT_BASE    0xF9300000
+#define MV_DEV_BOOT_SIZE    (1024 * 1024)   /* 1 MB */
+
+#define MV_DEV_CS0_BASE     0xF9400000
+#define MV_DEV_CS0_SIZE     (1024 * 1024)   /* 1 MB */
+
+#define MV_DEV_CS1_BASE     0xF9500000
+#define MV_DEV_CS1_SIZE     (32 * 1024 * 1024)  /* 32 MB */
+
+#define MV_DEV_CS2_BASE     0xFB500000
+#define MV_DEV_CS2_SIZE     (1024 * 1024)   /* 1 MB */
+
+
+/*
+ * Integrated SoC peripherals addresses
+ */
+#define MV_BASE			MV_PHYS_BASE	/* VA == PA mapping */
+#if defined(SOC_MV_DOVE)
+#define MV_DDR_CADR_BASE	(MV_AXI_BASE + 0x100)
+#elif defined(SOC_MV_LOKIPLUS)
+#define MV_DDR_CADR_BASE	(MV_BASE + 0xF1500)
+#elif defined(SOC_MV_ARMADAXP)
+#define MV_DDR_CADR_BASE	(MV_BASE + 0x20180)
+#else
+#define MV_DDR_CADR_BASE	(MV_BASE + 0x1500)
+#endif
+#define MV_MPP_BASE		(MV_BASE + 0x10000)
+
+#if defined(SOC_MV_ARMADAXP)
+#define MV_MISC_BASE		(MV_BASE + 0x18200)
+#define MV_MBUS_BRIDGE_BASE	(MV_BASE + 0x20000)
+#define MV_INTREGS_BASE		(MV_MBUS_BRIDGE_BASE + 0x80)
+#define MV_MP_CLOCKS_BASE	(MV_MBUS_BRIDGE_BASE + 0x700)
+#define MV_CPU_CONTROL_BASE	(MV_MBUS_BRIDGE_BASE + 0x1800)
+#elif !defined(SOC_MV_FREY)
+#define MV_MBUS_BRIDGE_BASE	(MV_BASE + 0x20000)
+#define MV_INTREGS_BASE		(MV_MBUS_BRIDGE_BASE + 0x80)
+#define MV_CPU_CONTROL_BASE	(MV_MBUS_BRIDGE_BASE + 0x100)
+#else
+#define MV_CPU_CONTROL_BASE	(MV_BASE + 0x10000)
+#endif
+
+#define MV_PCI_BASE		(MV_BASE + 0x30000)
+#define MV_PCI_SIZE		0x2000
+
+#if defined(SOC_MV_FREY)
+#define MV_PCIE_BASE		(MV_BASE + 0x8000)
+#else
+#define MV_PCIE_BASE		(MV_BASE + 0x40000)
+#endif
+#define MV_PCIE_SIZE		0x2000
+
+#define MV_PCIE00_BASE		(MV_PCIE_BASE + 0x00000)
+#define MV_PCIE01_BASE		(MV_PCIE_BASE + 0x04000)
+#define MV_PCIE02_BASE		(MV_PCIE_BASE + 0x08000)
+#define MV_PCIE03_BASE		(MV_PCIE_BASE + 0x0C000)
+#define MV_PCIE10_BASE		(MV_PCIE_BASE + 0x40000)
+#define MV_PCIE11_BASE		(MV_PCIE_BASE + 0x44000)
+#define MV_PCIE12_BASE		(MV_PCIE_BASE + 0x48000)
+#define MV_PCIE13_BASE		(MV_PCIE_BASE + 0x4C000)
+
+#define MV_SDIO_BASE		(MV_BASE + 0x90000)
+#define MV_SDIO_SIZE		0x10000
+
+/*
+ * Decode windows definitions and macros
+ */
+#if defined(SOC_MV_ARMADAXP)
+#define MV_WIN_CPU_CTRL(n)		(((n) < 8) ? 0x10 * (n) :  0x90 + (0x8 * ((n) - 8)))
+#define MV_WIN_CPU_BASE(n)		((((n) < 8) ? 0x10 * (n) :  0x90 + (0x8 * ((n) - 8))) + 0x4)
+#define MV_WIN_CPU_REMAP_LO(n)		(0x10 * (n) +  0x008)
+#define MV_WIN_CPU_REMAP_HI(n)		(0x10 * (n) +  0x00C)
+#else
+#define MV_WIN_CPU_CTRL(n)		(0x10 * (n) + (((n) < 8) ? 0x000 : 0x880))
+#define MV_WIN_CPU_BASE(n)		(0x10 * (n) + (((n) < 8) ? 0x004 : 0x884))
+#define MV_WIN_CPU_REMAP_LO(n)		(0x10 * (n) + (((n) < 8) ? 0x008 : 0x888))
+#define MV_WIN_CPU_REMAP_HI(n)		(0x10 * (n) + (((n) < 8) ? 0x00C : 0x88C))
+#endif
+
+#if defined(SOC_MV_DISCOVERY)
+#define MV_WIN_CPU_MAX			14
+#elif defined(SOC_MV_ARMADAXP)
+#define MV_WIN_CPU_MAX			20
+#else
+#define MV_WIN_CPU_MAX			8
+#endif
+
+#define MV_WIN_CPU_ATTR_SHIFT		8
+#if defined(SOC_MV_LOKIPLUS)
+#define MV_WIN_CPU_TARGET_SHIFT		0
+#define MV_WIN_CPU_ENABLE_BIT		(1 << 5)
+#else
+#define MV_WIN_CPU_TARGET_SHIFT		4
+#define MV_WIN_CPU_ENABLE_BIT		1
+#endif
+
+#if defined(SOC_MV_DOVE)
+#define MV_WIN_DDR_MAX			2
+#else /* SOC_MV_DOVE */
+#if defined(SOC_MV_LOKIPLUS)
+#define MV_WIN_DDR_BASE(n)		(0xc * (n) + 0x4)
+#define MV_WIN_DDR_SIZE(n)		(0xc * (n) + 0x0)
+#else /* SOC_MV_LOKIPLUS */
+#define MV_WIN_DDR_BASE(n)		(0x8 * (n) + 0x0)
+#define MV_WIN_DDR_SIZE(n)		(0x8 * (n) + 0x4)
+#endif /* SOC_MV_LOKIPLUS */
+#define MV_WIN_DDR_MAX			4
+#endif /* SOC_MV_DOVE */
+
+/*
+ * These values are valid only for peripherals decoding windows
+ * Bit in ATTR is zeroed according to CS bank number
+ */
+#define MV_WIN_DDR_ATTR(cs)		(0x0F & ~(0x01 << (cs)))
+#define MV_WIN_DDR_TARGET		0x0
+
+#if defined(SOC_MV_DISCOVERY)
+#define MV_WIN_CESA_TARGET		9
+#define MV_WIN_CESA_ATTR(eng_sel)	1
+#elif defined(SOC_MV_ARMADAXP)
+#define MV_WIN_CESA_TARGET		9
+/*
+ * Bits [2:3] of cesa attribute select engine:
+ * eng_sel:
+ *  1: engine1
+ *  2: engine0
+ */
+#define MV_WIN_CESA_ATTR(eng_sel)	(1 | ((eng_sel) << 2))
+#else
+#define MV_WIN_CESA_TARGET		3
+#define MV_WIN_CESA_ATTR(eng_sel)	0
+#endif
+
+#define MV_WIN_USB_CTRL(n)		(0x10 * (n) + 0x320)
+#define MV_WIN_USB_BASE(n)		(0x10 * (n) + 0x324)
+#define MV_WIN_USB_MAX			4
+
+#define MV_WIN_ETH_BASE(n)		(0x8 * (n) + 0x200)
+#define MV_WIN_ETH_SIZE(n)		(0x8 * (n) + 0x204)
+#define MV_WIN_ETH_REMAP(n)		(0x4 * (n) + 0x280)
+#define MV_WIN_ETH_MAX			6
+
+#define MV_WIN_IDMA_BASE(n)		(0x8 * (n) + 0xa00)
+#define MV_WIN_IDMA_SIZE(n)		(0x8 * (n) + 0xa04)
+#define MV_WIN_IDMA_REMAP(n)		(0x4 * (n) + 0xa60)
+#define MV_WIN_IDMA_CAP(n)		(0x4 * (n) + 0xa70)
+#define MV_WIN_IDMA_MAX			8
+#define MV_IDMA_CHAN_MAX		4
+
+#define MV_WIN_XOR_BASE(n, m)		(0x4 * (n) + 0xa50 + (m) * 0x100)
+#define MV_WIN_XOR_SIZE(n, m)		(0x4 * (n) + 0xa70 + (m) * 0x100)
+#define MV_WIN_XOR_REMAP(n, m)		(0x4 * (n) + 0xa90 + (m) * 0x100)
+#define MV_WIN_XOR_CTRL(n, m)		(0x4 * (n) + 0xa40 + (m) * 0x100)
+#define MV_WIN_XOR_OVERR(n, m)		(0x4 * (n) + 0xaa0 + (m) * 0x100)
+#define MV_WIN_XOR_MAX			8
+#define MV_XOR_CHAN_MAX			2
+#define MV_XOR_NON_REMAP		4
+
+#if defined(SOC_MV_DISCOVERY) || defined(SOC_MV_KIRKWOOD) || defined(SOC_MV_DOVE)
+#define MV_WIN_PCIE_TARGET(n)		4
+#define MV_WIN_PCIE_MEM_ATTR(n)		0xE8
+#define MV_WIN_PCIE_IO_ATTR(n)		0xE0
+#elif defined(SOC_MV_ARMADAXP)
+#define MV_WIN_PCIE_TARGET(n)		(4 + (4 * ((n) % 2)))
+#define MV_WIN_PCIE_MEM_ATTR(n)		(0xE8 + (0x10 * ((n) / 2)))
+#define MV_WIN_PCIE_IO_ATTR(n)		(0xE0 + (0x10 * ((n) / 2)))
+#elif defined(SOC_MV_ORION)
+#define MV_WIN_PCIE_TARGET(n)		4
+#define MV_WIN_PCIE_MEM_ATTR(n)		0x59
+#define MV_WIN_PCIE_IO_ATTR(n)		0x51
+#elif defined(SOC_MV_LOKIPLUS)
+#define MV_WIN_PCIE_TARGET(n)		(3 + (n))
+#define MV_WIN_PCIE_MEM_ATTR(n)		0x59
+#define MV_WIN_PCIE_IO_ATTR(n)		0x51
+#endif
+
+#define MV_WIN_PCI_TARGET		3
+#define MV_WIN_PCI_MEM_ATTR		0x59
+#define MV_WIN_PCI_IO_ATTR		0x51
+
+#define MV_WIN_PCIE_CTRL(n)		(0x10 * (((n) < 5) ? (n) : \
+					    (n) + 1) + 0x1820)
+#define MV_WIN_PCIE_BASE(n)		(0x10 * (((n) < 5) ? (n) : \
+					    (n) + 1) + 0x1824)
+#define MV_WIN_PCIE_REMAP(n)		(0x10 * (((n) < 5) ? (n) : \
+					    (n) + 1) + 0x182C)
+#define MV_WIN_PCIE_MAX			6
+
+#define MV_PCIE_BAR_CTRL(n)		(0x04 * (n) + 0x1800)
+#define MV_PCIE_BAR_BASE(n)		(0x08 * ((n) < 3 ? (n) : 4) + 0x0010)
+#define MV_PCIE_BAR_BASE_H(n)		(0x08 * (n) + 0x0014)
+#define MV_PCIE_BAR_MAX			4
+#define MV_PCIE_BAR_64BIT		(0x4)
+#define MV_PCIE_BAR_PREFETCH_EN		(0x8)
+
+#define MV_PCIE_CONTROL			(0x1a00)
+#define MV_PCIE_ROOT_CMPLX		(1 << 1)
+
+#define	MV_WIN_SATA_CTRL(n)		(0x10 * (n) + 0x30)
+#define	MV_WIN_SATA_BASE(n)		(0x10 * (n) + 0x34)
+#define	MV_WIN_SATA_MAX			4
+
+#define WIN_REG_IDX_RD(pre,reg,off,base)					\
+	static __inline uint32_t						\
+	pre ## _ ## reg ## _read(int i)						\
+	{									\
+		return (bus_space_read_4(fdtbus_bs_tag, base, off(i)));		\
+	}
+
+#define WIN_REG_IDX_RD2(pre,reg,off,base)					\
+	static  __inline uint32_t						\
+	pre ## _ ## reg ## _read(int i, int j)					\
+	{									\
+		return (bus_space_read_4(fdtbus_bs_tag, base, off(i, j)));		\
+	}									\
+
+#define WIN_REG_BASE_IDX_RD(pre,reg,off)					\
+	static __inline uint32_t						\
+	pre ## _ ## reg ## _read(uint32_t base, int i)				\
+	{									\
+		return (bus_space_read_4(fdtbus_bs_tag, base, off(i)));		\
+	}
+
+#define WIN_REG_BASE_IDX_RD2(pre,reg,off)					\
+	static __inline uint32_t						\
+	pre ## _ ## reg ## _read(uint32_t base, int i, int j)				\
+	{									\
+		return (bus_space_read_4(fdtbus_bs_tag, base, off(i, j)));		\
+	}
+
+#define WIN_REG_IDX_WR(pre,reg,off,base)					\
+	static __inline void							\
+	pre ## _ ## reg ## _write(int i, uint32_t val)				\
+	{									\
+		bus_space_write_4(fdtbus_bs_tag, base, off(i), val);			\
+	}
+
+#define WIN_REG_IDX_WR2(pre,reg,off,base)					\
+	static __inline void							\
+	pre ## _ ## reg ## _write(int i, int j, uint32_t val)			\
+	{									\
+		bus_space_write_4(fdtbus_bs_tag, base, off(i, j), val);		\
+	}
+
+#define WIN_REG_BASE_IDX_WR(pre,reg,off)					\
+	static __inline void							\
+	pre ## _ ## reg ## _write(uint32_t base, int i, uint32_t val)		\
+	{									\
+		bus_space_write_4(fdtbus_bs_tag, base, off(i), val);			\
+	}
+
+#define WIN_REG_BASE_IDX_WR2(pre,reg,off)					\
+	static __inline void							\
+	pre ## _ ## reg ## _write(uint32_t base, int i, int j, uint32_t val)		\
+	{									\
+		bus_space_write_4(fdtbus_bs_tag, base, off(i, j), val);			\
+	}
+
+#define WIN_REG_RD(pre,reg,off,base)						\
+	static __inline uint32_t						\
+	pre ## _ ## reg ## _read(void)						\
+	{									\
+		return (bus_space_read_4(fdtbus_bs_tag, base, off));			\
+	}
+
+#define WIN_REG_BASE_RD(pre,reg,off)						\
+	static __inline uint32_t						\
+	pre ## _ ## reg ## _read(uint32_t base)					\
+	{									\
+		return (bus_space_read_4(fdtbus_bs_tag, base, off));			\
+	}
+
+#define WIN_REG_WR(pre,reg,off,base)						\
+	static __inline void							\
+	pre ## _ ## reg ## _write(uint32_t val)					\
+	{									\
+		bus_space_write_4(fdtbus_bs_tag, base, off, val);			\
+	}
+
+#define WIN_REG_BASE_WR(pre,reg,off)						\
+	static __inline void							\
+	pre ## _ ## reg ## _write(uint32_t base, uint32_t val)			\
+	{									\
+		bus_space_write_4(fdtbus_bs_tag, base, off, val);			\
+	}
+
+#endif /* _MVWIN_H_ */


Property changes on: trunk/sys/arm/mv/mvwin.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/mv/orion/db88f5xxx.c
===================================================================
--- trunk/sys/arm/mv/orion/db88f5xxx.c	                        (rev 0)
+++ trunk/sys/arm/mv/orion/db88f5xxx.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,187 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (C) 2008 MARVELL INTERNATIONAL LTD.
+ * All rights reserved.
+ *
+ * Developed by Semihalf.
+ *
+ * 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.
+ * 3. Neither the name of MARVELL nor the names of contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY 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 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: stable/10/sys/arm/mv/orion/db88f5xxx.c 266386 2014-05-18 00:32:35Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <machine/bus.h>
+#include <machine/intr.h>
+#include <machine/pte.h>
+#include <machine/vmparam.h>
+
+#include <arm/mv/mvreg.h>
+#include <arm/mv/mvvar.h>
+#include <arm/mv/mvwin.h>
+
+/*
+ * Virtual address space layout:
+ * -----------------------------
+ * 0x0000_0000 - 0xbfff_ffff	: user process
+ *
+ * 0xc040_0000 - virtual_avail	: kernel reserved (text, data, page tables
+ *				: structures, ARM stacks etc.)
+ * virtual_avail - 0xefff_ffff	: KVA (virtual_avail is typically < 0xc0a0_0000)
+ * 0xf000_0000 - 0xf0ff_ffff	: no-cache allocation area (16MB)
+ * 0xf100_0000 - 0xf10f_ffff	: SoC integrated devices registers range (1MB)
+ * 0xf110_0000 - 0xf11f_ffff	: PCI-Express I/O space (1MB)
+ * 0xf120_0000 - 0xf12f_ffff	: PCI I/O space (1MB)
+ * 0xf130_0000 - 0xf52f_ffff	: PCI-Express memory space (64MB)
+ * 0xf530_0000 - 0xf92f_ffff	: PCI memory space (64MB)
+ * 0xf930_0000 - 0xfffe_ffff	: unused (~108MB)
+ * 0xffff_0000 - 0xffff_0fff	: 'high' vectors page (4KB)
+ * 0xffff_1000 - 0xffff_1fff	: ARM_TP_ADDRESS/RAS page (4KB)
+ * 0xffff_2000 - 0xffff_ffff	: unused (~55KB)
+ */
+
+
+#if 0
+int platform_pci_get_irq(u_int bus, u_int slot, u_int func, u_int pin);
+
+/* Static device mappings. */
+const struct pmap_devmap pmap_devmap[] = {
+	/*
+	 * Map the on-board devices VA == PA so that we can access them
+	 * with the MMU on or off.
+	 */
+	{ /* SoC integrated peripherals registers range */
+		MV_BASE,
+		MV_PHYS_BASE,
+		MV_SIZE,
+		VM_PROT_READ | VM_PROT_WRITE,
+		PTE_DEVICE,
+	},
+	{ /* PCIE I/O */
+		MV_PCIE_IO_BASE,
+		MV_PCIE_IO_PHYS_BASE,
+		MV_PCIE_IO_SIZE,
+		VM_PROT_READ | VM_PROT_WRITE,
+		PTE_DEVICE,
+	},
+	{ /* PCIE Memory */
+		MV_PCIE_MEM_BASE,
+		MV_PCIE_MEM_PHYS_BASE,
+		MV_PCIE_MEM_SIZE,
+		VM_PROT_READ | VM_PROT_WRITE,
+		PTE_DEVICE,
+	},
+	{ /* PCI I/O */
+		MV_PCI_IO_BASE,
+		MV_PCI_IO_PHYS_BASE,
+		MV_PCI_IO_SIZE,
+		VM_PROT_READ | VM_PROT_WRITE,
+		PTE_DEVICE,
+	},
+	{ /* PCI Memory */
+		MV_PCI_MEM_BASE,
+		MV_PCI_MEM_PHYS_BASE,
+		MV_PCI_MEM_SIZE,
+		VM_PROT_READ | VM_PROT_WRITE,
+		PTE_DEVICE,
+	},
+	{ /* 7-seg LED */
+		MV_DEV_CS0_BASE,
+		MV_DEV_CS0_PHYS_BASE,
+		MV_DEV_CS0_SIZE,
+		VM_PROT_READ | VM_PROT_WRITE,
+		PTE_DEVICE,
+	},
+	{ 0, 0, 0, 0, 0, }
+};
+
+/*
+ * The pci_irq_map table consists of 3 columns:
+ * - PCI slot number (less than zero means ANY).
+ * - PCI IRQ pin (less than zero means ANY).
+ * - PCI IRQ (less than zero marks end of table).
+ *
+ * IRQ number from the first matching entry is used to configure PCI device
+ */
+
+/* PCI IRQ Map for DB-88F5281 */
+const struct obio_pci_irq_map pci_irq_map[] = {
+	{ 7, -1, GPIO2IRQ(12) },
+	{ 8, -1, GPIO2IRQ(13) },
+	{ 9, -1, GPIO2IRQ(13) },
+	{ -1, -1, -1 }
+};
+
+/* PCI IRQ Map for DB-88F5182 */
+const struct obio_pci_irq_map pci_irq_map[] = {
+	{ 7, -1, GPIO2IRQ(0) },
+	{ 8, -1, GPIO2IRQ(1) },
+	{ 9, -1, GPIO2IRQ(1) },
+	{ -1, -1, -1 }
+};
+#endif
+
+#if 0
+/*
+ * mv_gpio_config row structure:
+ *	<GPIO number>, <GPIO flags>, <GPIO mode>
+ *
+ * - GPIO pin number (less than zero marks end of table)
+ * - GPIO flags:
+ *	MV_GPIO_BLINK
+ *	MV_GPIO_POLAR_LOW
+ *	MV_GPIO_EDGE
+ *	MV_GPIO_LEVEL
+ * - GPIO mode:
+ *	1	- Output, set to HIGH.
+ *	0	- Output, set to LOW.
+ *	-1	- Input.
+ */
+
+/* GPIO Configuration for DB-88F5281 */
+const struct gpio_config mv_gpio_config[] = {
+	{ 12, MV_GPIO_POLAR_LOW | MV_GPIO_LEVEL, -1 },
+	{ 13, MV_GPIO_POLAR_LOW | MV_GPIO_LEVEL, -1 },
+	{ -1, -1, -1 }
+};
+
+#if 0
+/* GPIO Configuration for DB-88F5182 */
+const struct gpio_config mv_gpio_config[] = {
+	{ 0, MV_GPIO_POLAR_LOW | MV_GPIO_LEVEL, -1 },
+	{ 1, MV_GPIO_POLAR_LOW | MV_GPIO_LEVEL, -1 },
+	{ -1, -1, -1 }
+};
+#endif
+
+#endif


Property changes on: trunk/sys/arm/mv/orion/db88f5xxx.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/mv/orion/files.db88f5xxx
===================================================================
--- trunk/sys/arm/mv/orion/files.db88f5xxx	                        (rev 0)
+++ trunk/sys/arm/mv/orion/files.db88f5xxx	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,5 @@
+# $FreeBSD: stable/10/sys/arm/mv/orion/files.db88f5xxx 239277 2012-08-15 05:15:49Z gonzo $
+
+arm/mv/ic.c			standard
+arm/mv/orion/orion.c		standard
+arm/mv/orion/db88f5xxx.c	standard


Property changes on: trunk/sys/arm/mv/orion/files.db88f5xxx
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/mv/orion/files.ts7800
===================================================================
--- trunk/sys/arm/mv/orion/files.ts7800	                        (rev 0)
+++ trunk/sys/arm/mv/orion/files.ts7800	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,5 @@
+# $FreeBSD: stable/10/sys/arm/mv/orion/files.ts7800 239277 2012-08-15 05:15:49Z gonzo $
+
+arm/mv/ic.c			standard
+arm/mv/orion/orion.c	standard
+


Property changes on: trunk/sys/arm/mv/orion/files.ts7800
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/mv/orion/orion.c
===================================================================
--- trunk/sys/arm/mv/orion/orion.c	                        (rev 0)
+++ trunk/sys/arm/mv/orion/orion.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,103 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (C) 2008 MARVELL INTERNATIONAL LTD.
+ * All rights reserved.
+ *
+ * Developed by Semihalf.
+ *
+ * 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.
+ * 3. Neither the name of MARVELL nor the names of contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY 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 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: stable/10/sys/arm/mv/orion/orion.c 209131 2010-06-13 13:28:53Z raj $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+
+#include <arm/mv/mvreg.h>
+#include <arm/mv/mvvar.h>
+#include <arm/mv/mvwin.h>
+
+#if 0
+extern const struct obio_pci_irq_map pci_irq_map[];
+const struct obio_pci mv_pci_info[] = {
+	{ MV_TYPE_PCIE,
+		MV_PCIE_BASE,	MV_PCIE_SIZE,
+		MV_PCIE_IO_BASE, MV_PCIE_IO_SIZE,	4, 0x51,
+		MV_PCIE_MEM_BASE, MV_PCIE_MEM_SIZE,	4, 0x59,
+		NULL, MV_INT_PEX0
+	},
+
+	{ MV_TYPE_PCI,
+		MV_PCI_BASE, MV_PCI_SIZE,
+		MV_PCI_IO_BASE, MV_PCI_IO_SIZE,		3, 0x51,
+		MV_PCI_MEM_BASE, MV_PCI_MEM_SIZE,	3, 0x59,
+		pci_irq_map, -1
+	},
+
+	{ 0, 0, 0 }
+};
+#endif
+
+struct resource_spec mv_gpio_res[] = {
+	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		0,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		1,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		2,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		3,	RF_ACTIVE },
+	{ -1, 0 }
+};
+
+const struct decode_win idma_win_tbl[] = {
+	{ 0 },
+};
+const struct decode_win *idma_wins = idma_win_tbl;
+int idma_wins_no = 0;
+
+uint32_t
+get_tclk(void)
+{
+	uint32_t sar;
+
+	/*
+	 * On Orion TCLK is can be configured to 150 MHz or 166 MHz.
+	 * Current setting is read from Sample At Reset register.
+	 */
+	/* XXX MPP addr should be retrieved from the DT */
+	sar = bus_space_read_4(fdtbus_bs_tag, MV_MPP_BASE, SAMPLE_AT_RESET);
+	sar = (sar & TCLK_MASK) >> TCLK_SHIFT;
+	switch (sar) {
+	case 1:
+		return (TCLK_150MHZ);
+	case 2:
+		return (TCLK_166MHZ);
+	default:
+		panic("Unknown TCLK settings!");
+	}
+}


Property changes on: trunk/sys/arm/mv/orion/orion.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/mv/orion/std.db88f5xxx
===================================================================
--- trunk/sys/arm/mv/orion/std.db88f5xxx	                        (rev 0)
+++ trunk/sys/arm/mv/orion/std.db88f5xxx	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,11 @@
+# $FreeBSD: stable/10/sys/arm/mv/orion/std.db88f5xxx 266110 2014-05-15 02:41:23Z ian $
+
+include	"../mv/std.mv"
+files	"../mv/orion/files.db88f5xxx"
+
+makeoptions	KERNPHYSADDR=0x00900000
+makeoptions	KERNVIRTADDR=0xc0900000
+
+options		KERNPHYSADDR=0x00900000
+options		KERNVIRTADDR=0xc0900000
+options		PHYSADDR=0x00000000


Property changes on: trunk/sys/arm/mv/orion/std.db88f5xxx
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/mv/orion/std.ts7800
===================================================================
--- trunk/sys/arm/mv/orion/std.ts7800	                        (rev 0)
+++ trunk/sys/arm/mv/orion/std.ts7800	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,14 @@
+# $FreeBSD: stable/10/sys/arm/mv/orion/std.ts7800 266110 2014-05-15 02:41:23Z ian $
+
+include	"../mv/std.mv"
+files	"../mv/orion/files.ts7800"
+
+makeoptions	KERNPHYSADDR=0x00900000
+makeoptions	KERNVIRTADDR=0xc0900000
+
+options		KERNPHYSADDR=0x00900000
+options 	KERNVIRTADDR=0xc0900000
+options		PHYSADDR=0x00000000
+options   LOADERRAMADDR=0x00000000
+options   FLASHADDR=0x00008000
+


Property changes on: trunk/sys/arm/mv/orion/std.ts7800
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/mv/rtc.c
===================================================================
--- trunk/sys/arm/mv/rtc.c	                        (rev 0)
+++ trunk/sys/arm/mv/rtc.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,194 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (C) 2008 MARVELL INTERNATIONAL LTD.
+ * All rights reserved.
+ *
+ * Developed by Semihalf.
+ *
+ * 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.
+ * 3. Neither the name of MARVELL nor the names of contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY 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 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: stable/10/sys/arm/mv/rtc.c 266152 2014-05-15 16:11:06Z ian $");
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/lock.h>
+#include <sys/time.h>
+#include <sys/clock.h>
+#include <sys/resource.h>
+#include <sys/systm.h>
+#include <sys/rman.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include "clock_if.h"
+
+#define MV_RTC_TIME_REG		0x00
+#define MV_RTC_DATE_REG		0x04
+#define YEAR_BASE		2000
+
+struct mv_rtc_softc {
+	device_t dev;
+	struct resource *res[1];
+};
+
+static struct resource_spec res_spec[] = {
+	{ SYS_RES_MEMORY, 0, RF_ACTIVE },
+	{ -1, 0 }
+};
+
+static int mv_rtc_probe(device_t dev);
+static int mv_rtc_attach(device_t dev);
+
+static int mv_rtc_gettime(device_t dev, struct timespec *ts);
+static int mv_rtc_settime(device_t dev, struct timespec *ts);
+
+static uint32_t mv_rtc_reg_read(struct mv_rtc_softc *sc, bus_size_t off);
+static int mv_rtc_reg_write(struct mv_rtc_softc *sc, bus_size_t off,
+    uint32_t val);
+
+static device_method_t mv_rtc_methods[] = {
+	DEVMETHOD(device_probe,		mv_rtc_probe),
+	DEVMETHOD(device_attach,	mv_rtc_attach),
+
+	DEVMETHOD(clock_gettime,	mv_rtc_gettime),
+	DEVMETHOD(clock_settime,	mv_rtc_settime),
+
+	{ 0, 0 },
+};
+
+static driver_t mv_rtc_driver = {
+	"rtc",
+	mv_rtc_methods,
+	sizeof(struct mv_rtc_softc),
+};
+static devclass_t mv_rtc_devclass;
+
+DRIVER_MODULE(mv_rtc, simplebus, mv_rtc_driver, mv_rtc_devclass, 0, 0);
+
+static int
+mv_rtc_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "mrvl,rtc"))
+		return (ENXIO);
+
+	device_set_desc(dev, "Marvell Integrated RTC");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+mv_rtc_attach(device_t dev)
+{
+	struct mv_rtc_softc *sc;
+
+	sc = device_get_softc(dev);
+	sc->dev = dev;
+
+	clock_register(dev, 1000000);
+
+	if (bus_alloc_resources(dev, res_spec, sc->res)) {
+		device_printf(dev, "could not allocate resources\n");
+		return (ENXIO);
+	}
+
+	return (0);
+}
+
+static int
+mv_rtc_gettime(device_t dev, struct timespec *ts)
+{
+	struct clocktime ct;
+	struct mv_rtc_softc *sc;
+	uint32_t val;
+
+	sc = device_get_softc(dev);
+
+	val = mv_rtc_reg_read(sc, MV_RTC_TIME_REG);
+
+	ct.nsec = 0;
+	ct.sec = FROMBCD(val & 0x7f);
+	ct.min = FROMBCD((val & 0x7f00) >> 8);
+	ct.hour = FROMBCD((val & 0x3f0000) >> 16);
+	ct.dow = FROMBCD((val & 0x7000000) >> 24) - 1;
+
+	val = mv_rtc_reg_read(sc, MV_RTC_DATE_REG);
+
+	ct.day = FROMBCD(val & 0x7f);
+	ct.mon = FROMBCD((val & 0x1f00) >> 8);
+	ct.year = YEAR_BASE + FROMBCD((val & 0xff0000) >> 16);
+
+	return (clock_ct_to_ts(&ct, ts));
+}
+
+static int
+mv_rtc_settime(device_t dev, struct timespec *ts)
+{
+	struct clocktime ct;
+	struct mv_rtc_softc *sc;
+	uint32_t val;
+
+	sc = device_get_softc(dev);
+
+	/* Resolution: 1 sec */
+	if (ts->tv_nsec >= 500000000)
+		ts->tv_sec++;
+	ts->tv_nsec = 0;
+	clock_ts_to_ct(ts, &ct);
+
+	val = TOBCD(ct.sec) | (TOBCD(ct.min) << 8) |
+	    (TOBCD(ct.hour) << 16) | (TOBCD( ct.dow + 1) << 24);
+	mv_rtc_reg_write(sc, MV_RTC_TIME_REG, val);
+
+	val = TOBCD(ct.day) | (TOBCD(ct.mon) << 8) |
+	    (TOBCD(ct.year - YEAR_BASE) << 16);
+	mv_rtc_reg_write(sc, MV_RTC_DATE_REG, val);
+
+	return (0);
+}
+
+static uint32_t
+mv_rtc_reg_read(struct mv_rtc_softc *sc, bus_size_t off)
+{
+
+	return (bus_read_4(sc->res[0], off));
+}
+
+static int
+mv_rtc_reg_write(struct mv_rtc_softc *sc, bus_size_t off, uint32_t val)
+{
+
+	bus_write_4(sc->res[0], off, val);
+	return (0);
+}


Property changes on: trunk/sys/arm/mv/rtc.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/mv/std-pj4b.mv
===================================================================
--- trunk/sys/arm/mv/std-pj4b.mv	                        (rev 0)
+++ trunk/sys/arm/mv/std-pj4b.mv	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,12 @@
+# $FreeBSD: stable/10/sys/arm/mv/std-pj4b.mv 294690 2016-01-24 22:17:05Z ian $
+
+files		"../mv/files.mv"
+cpu		CPU_MV_PJ4B
+machine 	arm	armv6
+makeoptions	CONF_CFLAGS="-march=armv7a -Wa,-march=armv7a"
+
+# This was originally defined as "(KERNBASE-(1024*1024*1024))" but that
+# (in opt_global.h) clashed with the value emitted by genassym which
+# reduces the original macro text to its numeric value.  The only way
+# to avoid that is to define it here as the numeric value genassym emits.
+options		VM_MAXUSER_ADDRESS="0x80000000"


Property changes on: trunk/sys/arm/mv/std-pj4b.mv
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/mv/std.mv
===================================================================
--- trunk/sys/arm/mv/std.mv	                        (rev 0)
+++ trunk/sys/arm/mv/std.mv	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,7 @@
+# $FreeBSD: stable/10/sys/arm/mv/std.mv 239362 2012-08-18 05:48:19Z andrew $
+
+files		"../mv/files.mv"
+cpu		CPU_ARM9E
+machine 	arm
+makeoptions	CONF_CFLAGS="-march=armv5te"
+options		FREEBSD_BOOT_LOADER


Property changes on: trunk/sys/arm/mv/std.mv
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/mv/timer.c
===================================================================
--- trunk/sys/arm/mv/timer.c	                        (rev 0)
+++ trunk/sys/arm/mv/timer.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,448 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2006 Benno Rice.
+ * Copyright (C) 2007-2008 MARVELL INTERNATIONAL LTD.
+ * All rights reserved.
+ *
+ * Adapted to Marvell SoC by Semihalf.
+ *
+ * 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 ``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 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.
+ *
+ * from: FreeBSD: //depot/projects/arm/src/sys/arm/xscale/pxa2x0/pxa2x0_timer.c, rev 1
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/mv/timer.c 266207 2014-05-16 02:21:51Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/timeet.h>
+#include <sys/timetc.h>
+#include <sys/watchdog.h>
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#include <arm/mv/mvreg.h>
+#include <arm/mv/mvvar.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#define INITIAL_TIMECOUNTER	(0xffffffff)
+#define MAX_WATCHDOG_TICKS	(0xffffffff)
+
+#if defined(SOC_MV_ARMADAXP)
+#define MV_CLOCK_SRC		25000000	/* Timers' 25MHz mode */
+#else
+#define MV_CLOCK_SRC		get_tclk()
+#endif
+
+struct mv_timer_softc {
+	struct resource	*	timer_res[2];
+	bus_space_tag_t		timer_bst;
+	bus_space_handle_t	timer_bsh;
+	struct mtx		timer_mtx;
+	struct eventtimer	et;
+};
+
+static struct resource_spec mv_timer_spec[] = {
+	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		0,	RF_ACTIVE },
+	{ -1, 0 }
+};
+
+static struct mv_timer_softc *timer_softc = NULL;
+static int timers_initialized = 0;
+
+static int	mv_timer_probe(device_t);
+static int	mv_timer_attach(device_t);
+
+static int	mv_hardclock(void *);
+static unsigned mv_timer_get_timecount(struct timecounter *);
+
+static uint32_t	mv_get_timer_control(void);
+static void	mv_set_timer_control(uint32_t);
+static uint32_t	mv_get_timer(uint32_t);
+static void	mv_set_timer(uint32_t, uint32_t);
+static void	mv_set_timer_rel(uint32_t, uint32_t);
+static void	mv_watchdog_enable(void);
+static void	mv_watchdog_disable(void);
+static void	mv_watchdog_event(void *, unsigned int, int *);
+static int	mv_timer_start(struct eventtimer *et,
+    sbintime_t first, sbintime_t period);
+static int	mv_timer_stop(struct eventtimer *et);
+static void	mv_setup_timers(void);
+
+static struct timecounter mv_timer_timecounter = {
+	.tc_get_timecount = mv_timer_get_timecount,
+	.tc_name = "CPUTimer1",
+	.tc_frequency = 0,	/* This is assigned on the fly in the init sequence */
+	.tc_counter_mask = ~0u,
+	.tc_quality = 1000,
+};
+
+static int
+mv_timer_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "mrvl,timer"))
+		return (ENXIO);
+
+	device_set_desc(dev, "Marvell CPU Timer");
+	return (0);
+}
+
+static int
+mv_timer_attach(device_t dev)
+{
+	int	error;
+	void	*ihl;
+	struct	mv_timer_softc *sc;
+#if !defined(SOC_MV_ARMADAXP)
+	uint32_t irq_cause, irq_mask;
+#endif
+
+	if (timer_softc != NULL)
+		return (ENXIO);
+
+	sc = (struct mv_timer_softc *)device_get_softc(dev);
+	timer_softc = sc;
+
+	error = bus_alloc_resources(dev, mv_timer_spec, sc->timer_res);
+	if (error) {
+		device_printf(dev, "could not allocate resources\n");
+		return (ENXIO);
+	}
+
+	sc->timer_bst = rman_get_bustag(sc->timer_res[0]);
+	sc->timer_bsh = rman_get_bushandle(sc->timer_res[0]);
+
+	mtx_init(&timer_softc->timer_mtx, "watchdog", NULL, MTX_DEF);
+	mv_watchdog_disable();
+	EVENTHANDLER_REGISTER(watchdog_list, mv_watchdog_event, sc, 0);
+
+	if (bus_setup_intr(dev, sc->timer_res[1], INTR_TYPE_CLK,
+	    mv_hardclock, NULL, sc, &ihl) != 0) {
+		bus_release_resources(dev, mv_timer_spec, sc->timer_res);
+		device_printf(dev, "Could not setup interrupt.\n");
+		return (ENXIO);
+	}
+
+	mv_setup_timers();
+#if !defined(SOC_MV_ARMADAXP)
+	irq_cause = read_cpu_ctrl(BRIDGE_IRQ_CAUSE);
+        irq_cause &= IRQ_TIMER0_CLR;
+
+	write_cpu_ctrl(BRIDGE_IRQ_CAUSE, irq_cause);
+	irq_mask = read_cpu_ctrl(BRIDGE_IRQ_MASK);
+	irq_mask |= IRQ_TIMER0_MASK;
+	irq_mask &= ~IRQ_TIMER1_MASK;
+	write_cpu_ctrl(BRIDGE_IRQ_MASK, irq_mask);
+#endif
+	sc->et.et_name = "CPUTimer0";
+	sc->et.et_flags = ET_FLAGS_PERIODIC | ET_FLAGS_ONESHOT;
+	sc->et.et_quality = 1000;
+
+	sc->et.et_frequency = MV_CLOCK_SRC;
+	sc->et.et_min_period = (0x00000002LLU << 32) / sc->et.et_frequency;
+	sc->et.et_max_period = (0xfffffffeLLU << 32) / sc->et.et_frequency;
+	sc->et.et_start = mv_timer_start;
+	sc->et.et_stop = mv_timer_stop;
+	sc->et.et_priv = sc;
+	et_register(&sc->et);
+	mv_timer_timecounter.tc_frequency = MV_CLOCK_SRC;
+	tc_init(&mv_timer_timecounter);
+
+	return (0);
+}
+
+static int
+mv_hardclock(void *arg)
+{
+	struct	mv_timer_softc *sc;
+	uint32_t irq_cause;
+
+	irq_cause = read_cpu_ctrl(BRIDGE_IRQ_CAUSE);
+	irq_cause &= IRQ_TIMER0_CLR;
+	write_cpu_ctrl(BRIDGE_IRQ_CAUSE, irq_cause);
+
+	sc = (struct mv_timer_softc *)arg;
+	if (sc->et.et_active)
+		sc->et.et_event_cb(&sc->et, sc->et.et_arg);
+
+	return (FILTER_HANDLED);
+}
+
+static device_method_t mv_timer_methods[] = {
+	DEVMETHOD(device_probe, mv_timer_probe),
+	DEVMETHOD(device_attach, mv_timer_attach),
+
+	{ 0, 0 }
+};
+
+static driver_t mv_timer_driver = {
+	"timer",
+	mv_timer_methods,
+	sizeof(struct mv_timer_softc),
+};
+
+static devclass_t mv_timer_devclass;
+
+DRIVER_MODULE(timer, simplebus, mv_timer_driver, mv_timer_devclass, 0, 0);
+
+static unsigned
+mv_timer_get_timecount(struct timecounter *tc)
+{
+
+	return (INITIAL_TIMECOUNTER - mv_get_timer(1));
+}
+
+void
+DELAY(int usec)
+{
+	uint32_t	val, val_temp;
+	int32_t		nticks;
+
+	if (!timers_initialized) {
+		for (; usec > 0; usec--)
+			for (val = 100; val > 0; val--)
+				__asm __volatile("nop" ::: "memory");
+		return;
+	}
+
+	val = mv_get_timer(1);
+	nticks = ((MV_CLOCK_SRC / 1000000 + 1) * usec);
+
+	while (nticks > 0) {
+		val_temp = mv_get_timer(1);
+		if (val > val_temp)
+			nticks -= (val - val_temp);
+		else
+			nticks -= (val + (INITIAL_TIMECOUNTER - val_temp));
+
+		val = val_temp;
+	}
+}
+
+static uint32_t
+mv_get_timer_control(void)
+{
+
+	return (bus_space_read_4(timer_softc->timer_bst,
+	    timer_softc->timer_bsh, CPU_TIMER_CONTROL));
+}
+
+static void
+mv_set_timer_control(uint32_t val)
+{
+
+	bus_space_write_4(timer_softc->timer_bst,
+	    timer_softc->timer_bsh, CPU_TIMER_CONTROL, val);
+}
+
+static uint32_t
+mv_get_timer(uint32_t timer)
+{
+
+	return (bus_space_read_4(timer_softc->timer_bst,
+	    timer_softc->timer_bsh, CPU_TIMER0 + timer * 0x8));
+}
+
+static void
+mv_set_timer(uint32_t timer, uint32_t val)
+{
+
+	bus_space_write_4(timer_softc->timer_bst,
+	    timer_softc->timer_bsh, CPU_TIMER0 + timer * 0x8, val);
+}
+
+static void
+mv_set_timer_rel(uint32_t timer, uint32_t val)
+{
+
+	bus_space_write_4(timer_softc->timer_bst,
+	    timer_softc->timer_bsh, CPU_TIMER0_REL + timer * 0x8, val);
+}
+
+static void
+mv_watchdog_enable(void)
+{
+	uint32_t val, irq_cause;
+#if !defined(SOC_MV_ARMADAXP)
+	uint32_t irq_mask;
+#endif
+
+	irq_cause = read_cpu_ctrl(BRIDGE_IRQ_CAUSE);
+	irq_cause &= IRQ_TIMER_WD_CLR;
+	write_cpu_ctrl(BRIDGE_IRQ_CAUSE, irq_cause);
+
+#if defined(SOC_MV_ARMADAXP)
+	val = read_cpu_mp_clocks(WD_RSTOUTn_MASK);
+	val |= (WD_GLOBAL_MASK | WD_CPU0_MASK);
+	write_cpu_mp_clocks(WD_RSTOUTn_MASK, val);
+#else
+	irq_mask = read_cpu_ctrl(BRIDGE_IRQ_MASK);
+	irq_mask |= IRQ_TIMER_WD_MASK;
+	write_cpu_ctrl(BRIDGE_IRQ_MASK, irq_mask);
+
+	val = read_cpu_ctrl(RSTOUTn_MASK);
+	val |= WD_RST_OUT_EN;
+	write_cpu_ctrl(RSTOUTn_MASK, val);
+#endif
+
+	val = mv_get_timer_control();
+	val |= CPU_TIMER_WD_EN | CPU_TIMER_WD_AUTO;
+#if defined(SOC_MV_ARMADAXP)
+	val |= CPU_TIMER_WD_25MHZ_EN;
+#endif
+	mv_set_timer_control(val);
+}
+
+static void
+mv_watchdog_disable(void)
+{
+	uint32_t val, irq_cause;
+#if !defined(SOC_MV_ARMADAXP)
+	uint32_t irq_mask;
+#endif
+
+	val = mv_get_timer_control();
+	val &= ~(CPU_TIMER_WD_EN | CPU_TIMER_WD_AUTO);
+	mv_set_timer_control(val);
+
+#if defined(SOC_MV_ARMADAXP)
+	val = read_cpu_mp_clocks(WD_RSTOUTn_MASK);
+	val &= ~(WD_GLOBAL_MASK | WD_CPU0_MASK);
+	write_cpu_mp_clocks(WD_RSTOUTn_MASK, val);
+#else
+	val = read_cpu_ctrl(RSTOUTn_MASK);
+	val &= ~WD_RST_OUT_EN;
+	write_cpu_ctrl(RSTOUTn_MASK, val);
+
+	irq_mask = read_cpu_ctrl(BRIDGE_IRQ_MASK);
+	irq_mask &= ~(IRQ_TIMER_WD_MASK);
+	write_cpu_ctrl(BRIDGE_IRQ_MASK, irq_mask);
+#endif
+
+	irq_cause = read_cpu_ctrl(BRIDGE_IRQ_CAUSE);
+	irq_cause &= IRQ_TIMER_WD_CLR;
+	write_cpu_ctrl(BRIDGE_IRQ_CAUSE, irq_cause);
+}
+
+
+/*
+ * Watchdog event handler.
+ */
+static void
+mv_watchdog_event(void *arg, unsigned int cmd, int *error)
+{
+	uint64_t ns;
+	uint64_t ticks;
+
+	mtx_lock(&timer_softc->timer_mtx);
+	if (cmd == 0)
+		mv_watchdog_disable();
+	else {
+		/*
+		 * Watchdog timeout is in nanosecs, calculation according to
+		 * watchdog(9)
+		 */
+		ns = (uint64_t)1 << (cmd & WD_INTERVAL);
+		ticks = (uint64_t)(ns * MV_CLOCK_SRC) / 1000000000;
+		if (ticks > MAX_WATCHDOG_TICKS)
+			mv_watchdog_disable();
+		else {
+			/* Timer 2 is the watchdog */
+			mv_set_timer(2, ticks);
+			mv_watchdog_enable();
+			*error = 0;
+		}
+	}
+	mtx_unlock(&timer_softc->timer_mtx);
+}
+
+static int
+mv_timer_start(struct eventtimer *et, sbintime_t first, sbintime_t period)
+{
+	struct	mv_timer_softc *sc;
+	uint32_t val, val1;
+
+	/* Calculate dividers. */
+	sc = (struct mv_timer_softc *)et->et_priv;
+	if (period != 0)
+		val = ((uint32_t)sc->et.et_frequency * period) >> 32;
+	else
+		val = 0;
+	if (first != 0)
+		val1 = ((uint32_t)sc->et.et_frequency * first) >> 32;
+	else
+		val1 = val;
+
+	/* Apply configuration. */
+	mv_set_timer_rel(0, val);
+	mv_set_timer(0, val1);
+	val = mv_get_timer_control();
+	val |= CPU_TIMER0_EN;
+	if (period != 0)
+		val |= CPU_TIMER0_AUTO;
+	else
+		val &= ~CPU_TIMER0_AUTO;
+	mv_set_timer_control(val);
+	return (0);
+}
+
+static int
+mv_timer_stop(struct eventtimer *et)
+{
+	uint32_t val;
+
+	val = mv_get_timer_control();
+	val &= ~(CPU_TIMER0_EN | CPU_TIMER0_AUTO);
+	mv_set_timer_control(val);
+	return (0);
+}
+
+static void
+mv_setup_timers(void)
+{
+	uint32_t val;
+
+	mv_set_timer_rel(1, INITIAL_TIMECOUNTER);
+	mv_set_timer(1, INITIAL_TIMECOUNTER);
+	val = mv_get_timer_control();
+	val &= ~(CPU_TIMER0_EN | CPU_TIMER0_AUTO);
+	val |= CPU_TIMER1_EN | CPU_TIMER1_AUTO;
+#if defined(SOC_MV_ARMADAXP)
+	/* Enable 25MHz mode */
+	val |= CPU_TIMER0_25MHZ_EN | CPU_TIMER1_25MHZ_EN;
+#endif
+	mv_set_timer_control(val);
+	timers_initialized = 1;
+}


Property changes on: trunk/sys/arm/mv/timer.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/mv/twsi.c
===================================================================
--- trunk/sys/arm/mv/twsi.c	                        (rev 0)
+++ trunk/sys/arm/mv/twsi.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,642 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (C) 2008 MARVELL INTERNATIONAL LTD.
+ * All rights reserved.
+ *
+ * Developed by Semihalf.
+ *
+ * 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.
+ * 3. Neither the name of MARVELL nor the names of contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY 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 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.
+ */
+
+/*
+ * Driver for the TWSI (aka I2C, aka IIC) bus controller found on Marvell
+ * SoCs. Supports master operation only, and works in polling mode.
+ *
+ * Calls to DELAY() are needed per Application Note AN-179 "TWSI Software
+ * Guidelines for Discovery(TM), Horizon (TM) and Feroceon(TM) Devices".
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/mv/twsi.c 266152 2014-05-15 16:11:06Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/resource.h>
+
+#include <machine/_inttypes.h>
+#include <machine/bus.h>
+#include <machine/resource.h>
+
+#include <sys/rman.h>
+
+#include <sys/lock.h>
+#include <sys/mutex.h>
+
+#include <dev/iicbus/iiconf.h>
+#include <dev/iicbus/iicbus.h>
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <arm/mv/mvreg.h>
+#include <arm/mv/mvvar.h>
+
+#include "iicbus_if.h"
+
+#define MV_TWSI_NAME		"twsi"
+#define	IICBUS_DEVNAME		"iicbus"
+
+#define TWSI_SLAVE_ADDR		0x00
+#define TWSI_EXT_SLAVE_ADDR	0x10
+#define TWSI_DATA		0x04
+
+#define TWSI_CONTROL		0x08
+#define TWSI_CONTROL_ACK	(1 << 2)
+#define TWSI_CONTROL_IFLG	(1 << 3)
+#define TWSI_CONTROL_STOP	(1 << 4)
+#define TWSI_CONTROL_START	(1 << 5)
+#define TWSI_CONTROL_TWSIEN	(1 << 6)
+#define TWSI_CONTROL_INTEN	(1 << 7)
+
+#define TWSI_STATUS			0x0c
+#define TWSI_STATUS_START		0x08
+#define TWSI_STATUS_RPTD_START		0x10
+#define TWSI_STATUS_ADDR_W_ACK		0x18
+#define TWSI_STATUS_DATA_WR_ACK		0x28
+#define TWSI_STATUS_ADDR_R_ACK		0x40
+#define TWSI_STATUS_DATA_RD_ACK		0x50
+#define TWSI_STATUS_DATA_RD_NOACK	0x58
+
+#define TWSI_BAUD_RATE		0x0c
+#define	TWSI_BAUD_RATE_PARAM(M,N)	((((M) << 3) | ((N) & 0x7)) & 0x7f)
+#define	TWSI_BAUD_RATE_RAW(C,M,N)	((C)/((10*(M+1))<<(N+1)))
+#define	TWSI_BAUD_RATE_SLOW		50000	/* 50kHz */
+#define	TWSI_BAUD_RATE_FAST		100000	/* 100kHz */
+
+#define TWSI_SOFT_RESET		0x1c
+
+#define TWSI_DEBUG
+#undef TWSI_DEBUG
+
+#ifdef  TWSI_DEBUG
+#define debugf(fmt, args...) do { printf("%s(): ", __func__); printf(fmt,##args); } while (0)
+#else
+#define debugf(fmt, args...)
+#endif
+
+struct mv_twsi_softc {
+	device_t	dev;
+	struct resource	*res[1];	/* SYS_RES_MEMORY */
+	struct mtx	mutex;
+	device_t	iicbus;
+};
+
+static struct mv_twsi_baud_rate {
+	uint32_t	raw;
+	int		param;
+	int		m;
+	int		n;
+} baud_rate[IIC_FASTEST + 1];
+
+static int mv_twsi_probe(device_t);
+static int mv_twsi_attach(device_t);
+static int mv_twsi_detach(device_t);
+
+static int mv_twsi_reset(device_t dev, u_char speed, u_char addr,
+    u_char *oldaddr);
+static int mv_twsi_repeated_start(device_t dev, u_char slave, int timeout);
+static int mv_twsi_start(device_t dev, u_char slave, int timeout);
+static int mv_twsi_stop(device_t dev);
+static int mv_twsi_read(device_t dev, char *buf, int len, int *read, int last,
+    int delay);
+static int mv_twsi_write(device_t dev, const char *buf, int len, int *sent,
+    int timeout);
+
+static struct resource_spec res_spec[] = {
+	{ SYS_RES_MEMORY, 0, RF_ACTIVE },
+	{ -1, 0 }
+};
+
+static device_method_t mv_twsi_methods[] = {
+	/* device interface */
+	DEVMETHOD(device_probe,		mv_twsi_probe),
+	DEVMETHOD(device_attach,	mv_twsi_attach),
+	DEVMETHOD(device_detach,	mv_twsi_detach),
+
+	/* iicbus interface */
+	DEVMETHOD(iicbus_callback, iicbus_null_callback),
+	DEVMETHOD(iicbus_repeated_start, mv_twsi_repeated_start),
+	DEVMETHOD(iicbus_start,		mv_twsi_start),
+	DEVMETHOD(iicbus_stop,		mv_twsi_stop),
+	DEVMETHOD(iicbus_write,		mv_twsi_write),
+	DEVMETHOD(iicbus_read,		mv_twsi_read),
+	DEVMETHOD(iicbus_reset,		mv_twsi_reset),
+	DEVMETHOD(iicbus_transfer,	iicbus_transfer_gen),
+	{ 0, 0 }
+};
+
+static devclass_t mv_twsi_devclass;
+
+static driver_t mv_twsi_driver = {
+	MV_TWSI_NAME,
+	mv_twsi_methods,
+	sizeof(struct mv_twsi_softc),
+};
+
+DRIVER_MODULE(twsi, simplebus, mv_twsi_driver, mv_twsi_devclass, 0, 0);
+DRIVER_MODULE(iicbus, twsi, iicbus_driver, iicbus_devclass, 0, 0);
+MODULE_DEPEND(twsi, iicbus, 1, 1, 1);
+
+static __inline uint32_t
+TWSI_READ(struct mv_twsi_softc *sc, bus_size_t off)
+{
+
+	return (bus_read_4(sc->res[0], off));
+}
+
+static __inline void
+TWSI_WRITE(struct mv_twsi_softc *sc, bus_size_t off, uint32_t val)
+{
+
+	bus_write_4(sc->res[0], off, val);
+}
+
+static __inline void
+twsi_control_clear(struct mv_twsi_softc *sc, uint32_t mask)
+{
+	uint32_t val;
+
+	val = TWSI_READ(sc, TWSI_CONTROL);
+	val &= ~mask;
+	TWSI_WRITE(sc, TWSI_CONTROL, val);
+}
+
+static __inline void
+twsi_control_set(struct mv_twsi_softc *sc, uint32_t mask)
+{
+	uint32_t val;
+
+	val = TWSI_READ(sc, TWSI_CONTROL);
+	val |= mask;
+	TWSI_WRITE(sc, TWSI_CONTROL, val);
+}
+
+static __inline void
+twsi_clear_iflg(struct mv_twsi_softc *sc)
+{
+
+	DELAY(1000);
+	twsi_control_clear(sc, TWSI_CONTROL_IFLG);
+	DELAY(1000);
+}
+
+
+/*
+ * timeout given in us
+ * returns
+ *   0 on sucessfull mask change
+ *   non-zero on timeout
+ */
+static int
+twsi_poll_ctrl(struct mv_twsi_softc *sc, int timeout, uint32_t mask)
+{
+
+	timeout /= 10;
+	while (!(TWSI_READ(sc, TWSI_CONTROL) & mask)) {
+		DELAY(10);
+		if (--timeout < 0)
+			return (timeout);
+	}
+	return (0);
+}
+
+
+/*
+ * 'timeout' is given in us. Note also that timeout handling is not exact --
+ * twsi_locked_start() total wait can be more than 2 x timeout
+ * (twsi_poll_ctrl() is called twice). 'mask' can be either TWSI_STATUS_START
+ * or TWSI_STATUS_RPTD_START
+ */
+static int
+twsi_locked_start(device_t dev, struct mv_twsi_softc *sc, int32_t mask,
+    u_char slave, int timeout)
+{
+	int read_access, iflg_set = 0;
+	uint32_t status;
+
+	mtx_assert(&sc->mutex, MA_OWNED);
+
+	if (mask == TWSI_STATUS_RPTD_START)
+		/* read IFLG to know if it should be cleared later; from NBSD */
+		iflg_set = TWSI_READ(sc, TWSI_CONTROL) & TWSI_CONTROL_IFLG;
+
+	twsi_control_set(sc, TWSI_CONTROL_START);
+
+	if (mask == TWSI_STATUS_RPTD_START && iflg_set) {
+		debugf("IFLG set, clearing\n");
+		twsi_clear_iflg(sc);
+	}
+
+	/*
+	 * Without this delay we timeout checking IFLG if the timeout is 0.
+	 * NBSD driver always waits here too.
+	 */
+	DELAY(1000);
+
+	if (twsi_poll_ctrl(sc, timeout, TWSI_CONTROL_IFLG)) {
+		debugf("timeout sending %sSTART condition\n",
+		    mask == TWSI_STATUS_START ? "" : "repeated ");
+		return (IIC_ETIMEOUT);
+	}
+
+	status = TWSI_READ(sc, TWSI_STATUS);
+	if (status != mask) {
+		debugf("wrong status (%02x) after sending %sSTART condition\n",
+		    status, mask == TWSI_STATUS_START ? "" : "repeated ");
+		return (IIC_ESTATUS);
+	}
+
+	TWSI_WRITE(sc, TWSI_DATA, slave);
+	DELAY(1000);
+	twsi_clear_iflg(sc);
+
+	if (twsi_poll_ctrl(sc, timeout, TWSI_CONTROL_IFLG)) {
+		debugf("timeout sending slave address\n");
+		return (IIC_ETIMEOUT);
+	}
+	
+	read_access = (slave & 0x1) ? 1 : 0;
+	status = TWSI_READ(sc, TWSI_STATUS);
+	if (status != (read_access ?
+	    TWSI_STATUS_ADDR_R_ACK : TWSI_STATUS_ADDR_W_ACK)) {
+		debugf("no ACK (status: %02x) after sending slave address\n",
+		    status);
+		return (IIC_ENOACK);
+	}
+
+	return (IIC_NOERR);
+}
+
+static int
+mv_twsi_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "mrvl,twsi"))
+		return (ENXIO);
+
+	device_set_desc(dev, "Marvell Integrated I2C Bus Controller");
+	return (BUS_PROBE_DEFAULT);
+}
+
+#define	ABSSUB(a,b)	(((a) > (b)) ? (a) - (b) : (b) - (a))
+static void
+mv_twsi_cal_baud_rate(const uint32_t target, struct mv_twsi_baud_rate *rate)
+{
+	uint32_t clk, cur, diff, diff0;
+	int m, n, m0, n0;
+
+	/* Calculate baud rate. */
+	m0 = n0 = 4;	/* Default values on reset */
+	diff0 = 0xffffffff;
+	clk = get_tclk();
+
+	for (n = 0; n < 8; n++) {
+		for (m = 0; m < 16; m++) {
+			cur = TWSI_BAUD_RATE_RAW(clk,m,n);
+			diff = ABSSUB(target, cur);
+			if (diff < diff0) {
+				m0 = m;
+				n0 = n;
+				diff0 = diff;
+			}
+		}
+	}
+	rate->raw = TWSI_BAUD_RATE_RAW(clk, m0, n0);
+	rate->param = TWSI_BAUD_RATE_PARAM(m0, n0);
+	rate->m = m0;
+	rate->n = n0;
+}
+
+static int
+mv_twsi_attach(device_t dev)
+{
+	struct mv_twsi_softc *sc;
+	phandle_t child, iicbusnode;
+	device_t childdev;
+	struct iicbus_ivar *devi;
+	char dname[32];	/* 32 is taken from struct u_device */
+	uint32_t paddr;
+	int len, error;
+
+	sc = device_get_softc(dev);
+	sc->dev = dev;
+	bzero(baud_rate, sizeof(baud_rate));
+
+	mtx_init(&sc->mutex, device_get_nameunit(dev), MV_TWSI_NAME, MTX_DEF);
+
+	/* Allocate IO resources */
+	if (bus_alloc_resources(dev, res_spec, sc->res)) {
+		device_printf(dev, "could not allocate resources\n");
+		mv_twsi_detach(dev);
+		return (ENXIO);
+	}
+
+	mv_twsi_cal_baud_rate(TWSI_BAUD_RATE_SLOW, &baud_rate[IIC_SLOW]);
+	mv_twsi_cal_baud_rate(TWSI_BAUD_RATE_FAST, &baud_rate[IIC_FAST]);
+	if (bootverbose)
+		device_printf(dev, "calculated baud rates are:\n"
+		    " %" PRIu32 " kHz (M=%d, N=%d) for slow,\n"
+		    " %" PRIu32 " kHz (M=%d, N=%d) for fast.\n",
+		    baud_rate[IIC_SLOW].raw / 1000,
+		    baud_rate[IIC_SLOW].m,
+		    baud_rate[IIC_SLOW].n,
+		    baud_rate[IIC_FAST].raw / 1000,
+		    baud_rate[IIC_FAST].m,
+		    baud_rate[IIC_FAST].n);
+
+	sc->iicbus = device_add_child(dev, IICBUS_DEVNAME, -1);
+	if (sc->iicbus == NULL) {
+		device_printf(dev, "could not add iicbus child\n");
+		mv_twsi_detach(dev);
+		return (ENXIO);
+	}
+	/* Attach iicbus. */
+	bus_generic_attach(dev);
+
+	iicbusnode = 0;
+	/* Find iicbus as the child devices in the device tree. */
+	for (child = OF_child(ofw_bus_get_node(dev)); child != 0;
+	    child = OF_peer(child)) {
+		len = OF_getproplen(child, "model");
+		if (len <= 0 || len > sizeof(dname) - 1)
+			continue;
+		error = OF_getprop(child, "model", &dname, len);
+		dname[len + 1] = '\0';
+		if (error == -1)
+			continue;
+		len = strlen(dname);
+		if (len == strlen(IICBUS_DEVNAME) &&
+		    strncasecmp(dname, IICBUS_DEVNAME, len) == 0) {
+			iicbusnode = child;
+			break; 
+		}
+	}
+	if (iicbusnode == 0)
+		goto attach_end;
+
+	/* Attach child devices onto iicbus. */
+	for (child = OF_child(iicbusnode); child != 0; child = OF_peer(child)) {
+		/* Get slave address. */
+		error = OF_getprop(child, "i2c-address", &paddr, sizeof(paddr));
+		if (error == -1)
+			error = OF_getprop(child, "reg", &paddr, sizeof(paddr));
+		if (error == -1)
+			continue;
+
+		/* Get device driver name. */
+		len = OF_getproplen(child, "model");
+		if (len <= 0 || len > sizeof(dname) - 1)
+			continue;
+		OF_getprop(child, "model", &dname, len);
+		dname[len + 1] = '\0';
+
+		if (bootverbose)
+			device_printf(dev, "adding a device %s at %d.\n",
+			    dname, fdt32_to_cpu(paddr));
+		childdev = BUS_ADD_CHILD(sc->iicbus, 0, dname, -1);
+		devi = IICBUS_IVAR(childdev);
+		devi->addr = fdt32_to_cpu(paddr);
+	}
+
+attach_end:
+	bus_generic_attach(sc->iicbus);
+
+	return (0);
+}
+
+static int
+mv_twsi_detach(device_t dev)
+{
+	struct mv_twsi_softc *sc;
+	int rv;
+
+	sc = device_get_softc(dev);
+
+	if ((rv = bus_generic_detach(dev)) != 0)
+		return (rv);
+
+	if (sc->iicbus != NULL)
+		if ((rv = device_delete_child(dev, sc->iicbus)) != 0)
+			return (rv);
+
+	bus_release_resources(dev, res_spec, sc->res);
+
+	mtx_destroy(&sc->mutex);
+	return (0);
+}
+
+/*
+ * Only slave mode supported, disregard [old]addr
+ */
+static int
+mv_twsi_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
+{
+	struct mv_twsi_softc *sc;
+	uint32_t param;
+
+	sc = device_get_softc(dev);
+
+	switch (speed) {
+	case IIC_SLOW:
+	case IIC_FAST:
+		param = baud_rate[speed].param;
+		break;
+	case IIC_FASTEST:
+	case IIC_UNKNOWN:
+	default:
+		param = baud_rate[IIC_FAST].param;
+		break;
+	}
+
+	mtx_lock(&sc->mutex);
+	TWSI_WRITE(sc, TWSI_SOFT_RESET, 0x0);
+	DELAY(2000);
+	TWSI_WRITE(sc, TWSI_BAUD_RATE, param);
+	TWSI_WRITE(sc, TWSI_CONTROL, TWSI_CONTROL_TWSIEN | TWSI_CONTROL_ACK);
+	DELAY(1000);
+	mtx_unlock(&sc->mutex);
+
+	return (0);
+}
+
+/*
+ * timeout is given in us
+ */
+static int
+mv_twsi_repeated_start(device_t dev, u_char slave, int timeout)
+{
+	struct mv_twsi_softc *sc;
+	int rv;
+
+	sc = device_get_softc(dev);
+
+	mtx_lock(&sc->mutex);
+	rv = twsi_locked_start(dev, sc, TWSI_STATUS_RPTD_START, slave,
+	    timeout);
+	mtx_unlock(&sc->mutex);
+
+	if (rv) {
+		mv_twsi_stop(dev);
+		return (rv);
+	} else
+		return (IIC_NOERR);
+}
+
+/*
+ * timeout is given in us
+ */
+static int
+mv_twsi_start(device_t dev, u_char slave, int timeout)
+{
+	struct mv_twsi_softc *sc;
+	int rv;
+
+	sc = device_get_softc(dev);
+
+	mtx_lock(&sc->mutex);
+	rv = twsi_locked_start(dev, sc, TWSI_STATUS_START, slave, timeout);
+	mtx_unlock(&sc->mutex);
+
+	if (rv) {
+		mv_twsi_stop(dev);
+		return (rv);
+	} else
+		return (IIC_NOERR);
+}
+
+static int
+mv_twsi_stop(device_t dev)
+{
+	struct mv_twsi_softc *sc;
+
+	sc = device_get_softc(dev);
+
+	mtx_lock(&sc->mutex);
+	twsi_control_set(sc, TWSI_CONTROL_STOP);
+	DELAY(1000);
+	twsi_clear_iflg(sc);
+	mtx_unlock(&sc->mutex);
+
+	return (IIC_NOERR);
+}
+
+static int
+mv_twsi_read(device_t dev, char *buf, int len, int *read, int last, int delay)
+{
+	struct mv_twsi_softc *sc;
+	uint32_t status;
+	int last_byte, rv;
+
+	sc = device_get_softc(dev);
+
+	mtx_lock(&sc->mutex);
+	*read = 0;
+	while (*read < len) {
+		/*
+		 * Check if we are reading last byte of the last buffer,
+		 * do not send ACK then, per I2C specs
+		 */
+		last_byte = ((*read == len - 1) && last) ? 1 : 0;
+		if (last_byte)
+			twsi_control_clear(sc, TWSI_CONTROL_ACK);
+		else
+			twsi_control_set(sc, TWSI_CONTROL_ACK);
+
+		DELAY (1000);
+		twsi_clear_iflg(sc);
+
+		if (twsi_poll_ctrl(sc, delay, TWSI_CONTROL_IFLG)) {
+			debugf("timeout reading data\n");
+			rv = IIC_ETIMEOUT;
+			goto out;
+		}
+
+		status = TWSI_READ(sc, TWSI_STATUS);
+		if (status != (last_byte ?
+		    TWSI_STATUS_DATA_RD_NOACK : TWSI_STATUS_DATA_RD_ACK)) {
+			debugf("wrong status (%02x) while reading\n", status);
+			rv = IIC_ESTATUS;
+			goto out;
+		}
+
+		*buf++ = TWSI_READ(sc, TWSI_DATA);
+		(*read)++;
+	}
+	rv = IIC_NOERR;
+out:
+	mtx_unlock(&sc->mutex);
+	return (rv);
+}
+
+static int
+mv_twsi_write(device_t dev, const char *buf, int len, int *sent, int timeout)
+{
+	struct mv_twsi_softc *sc;
+	uint32_t status;
+	int rv;
+
+	sc = device_get_softc(dev);
+
+	mtx_lock(&sc->mutex);
+	*sent = 0;
+	while (*sent < len) {
+		TWSI_WRITE(sc, TWSI_DATA, *buf++);
+
+		twsi_clear_iflg(sc);
+		if (twsi_poll_ctrl(sc, timeout, TWSI_CONTROL_IFLG)) {
+			debugf("timeout writing data\n");
+			rv = IIC_ETIMEOUT;
+			goto out;
+		}
+
+		status = TWSI_READ(sc, TWSI_STATUS);
+		if (status != TWSI_STATUS_DATA_WR_ACK) {
+			debugf("wrong status (%02x) while writing\n", status);
+			rv = IIC_ESTATUS;
+			goto out;
+		}
+		(*sent)++;
+	}
+	rv = IIC_NOERR;
+out:
+	mtx_unlock(&sc->mutex);
+	return (rv);
+}


Property changes on: trunk/sys/arm/mv/twsi.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/rockchip/files.rk30xx
===================================================================
--- trunk/sys/arm/rockchip/files.rk30xx	                        (rev 0)
+++ trunk/sys/arm/rockchip/files.rk30xx	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,22 @@
+# $FreeBSD: stable/10/sys/arm/rockchip/files.rk30xx 278727 2015-02-13 22:32:02Z ian $
+kern/kern_clocksource.c			standard
+
+arm/arm/bus_space_asm_generic.S		standard
+arm/arm/bus_space_generic.c		standard
+arm/arm/cpufunc_asm_armv5.S		standard
+arm/arm/cpufunc_asm_arm10.S		standard
+arm/arm/cpufunc_asm_arm11.S		standard
+arm/arm/cpufunc_asm_armv7.S		standard
+
+arm/arm/gic.c				standard
+arm/arm/mpcore_timer.c			standard
+
+arm/arm/bus_space_base.c		standard
+arm/rockchip/rk30xx_common.c		standard
+arm/rockchip/rk30xx_machdep.c		standard
+arm/rockchip/rk30xx_pmu.c		standard
+arm/rockchip/rk30xx_grf.c		standard
+arm/rockchip/rk30xx_wdog.c		standard
+arm/rockchip/rk30xx_gpio.c		optional	gpio
+dev/usb/controller/dwc_otg_fdt.c	optional	dwcotg
+arm/rockchip/rk30xx_mp.c		optional	smp


Property changes on: trunk/sys/arm/rockchip/files.rk30xx
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/rockchip/rk30xx_common.c
===================================================================
--- trunk/sys/arm/rockchip/rk30xx_common.c	                        (rev 0)
+++ trunk/sys/arm/rockchip/rk30xx_common.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,65 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Ganbold Tsagaankhuu <ganbold at freebsd.org>
+ * 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: stable/10/sys/arm/rockchip/rk30xx_common.c 266337 2014-05-17 18:53:36Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+#include <machine/vmparam.h>
+
+struct fdt_fixup_entry fdt_fixup_table[] = {
+	{ NULL, NULL }
+};
+
+static int
+fdt_aintc_decode_ic(phandle_t node, pcell_t *intr, int *interrupt, int *trig,
+    int *pol)
+{
+
+	if (!fdt_is_compatible(node, "arm,gic"))
+		return (ENXIO);
+
+	*interrupt = fdt32_to_cpu(intr[0]);
+	*trig = INTR_TRIGGER_CONFORM;
+	*pol = INTR_POLARITY_CONFORM;
+
+	return (0);
+}
+
+fdt_pic_decode_t fdt_pic_table[] = {
+	&fdt_aintc_decode_ic,
+	NULL
+};


Property changes on: trunk/sys/arm/rockchip/rk30xx_common.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/rockchip/rk30xx_gpio.c
===================================================================
--- trunk/sys/arm/rockchip/rk30xx_gpio.c	                        (rev 0)
+++ trunk/sys/arm/rockchip/rk30xx_gpio.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,663 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Ganbold Tsagaankhuu <ganbold at freebsd.org>
+ * Copyright (c) 2012 Oleksandr Tymoshenko <gonzo at freebsd.org>
+ * Copyright (c) 2012 Luiz Otavio O Souza.
+ * 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: stable/10/sys/arm/rockchip/rk30xx_gpio.c 278786 2015-02-14 21:16:19Z loos $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/rman.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/gpio.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+#include <machine/resource.h>
+#include <machine/fdt.h>
+#include <machine/intr.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include "gpio_if.h"
+
+#include "rk30xx_grf.h"
+#include "rk30xx_pmu.h"
+
+/*
+ * RK3188 has 4 banks of gpio.
+ * 32 pins per bank
+ * PA0 - PA7 | PB0 - PB7
+ * PC0 - PC7 | PD0 - PD7
+ */
+
+#define	RK30_GPIO_PINS		128
+#define	RK30_GPIO_DEFAULT_CAPS	(GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | \
+    GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN)
+
+#define	RK30_GPIO_NONE			0
+#define	RK30_GPIO_PULLUP		1
+#define	RK30_GPIO_PULLDOWN		2
+
+#define	RK30_GPIO_INPUT			0
+#define	RK30_GPIO_OUTPUT		1
+
+struct rk30_gpio_softc {
+	device_t		sc_dev;
+	struct mtx		sc_mtx;
+	struct resource *	sc_mem_res;
+	struct resource *	sc_irq_res;
+	bus_space_tag_t		sc_bst;
+	bus_space_handle_t	sc_bsh;
+	void *			sc_intrhand;
+	int			sc_gpio_npins;
+	struct gpio_pin		sc_gpio_pins[RK30_GPIO_PINS];
+};
+
+static struct rk30_gpio_softc *rk30_gpio_sc = NULL;
+
+typedef int (*gpios_phandler_t)(phandle_t, pcell_t *, int);
+
+struct gpio_ctrl_entry {
+	const char		*compat;
+	gpios_phandler_t	handler;
+};
+
+int rk30_gpios_prop_handle(phandle_t ctrl, pcell_t *gpios, int len);
+static int rk30_gpio_init(void);
+
+struct gpio_ctrl_entry gpio_controllers[] = {
+	{ "rockchip,rk30xx-gpio", &rk30_gpios_prop_handle },
+	{ "rockchip,rk30xx-gpio", &rk30_gpios_prop_handle },
+	{ "rockchip,rk30xx-gpio", &rk30_gpios_prop_handle },
+	{ "rockchip,rk30xx-gpio", &rk30_gpios_prop_handle },
+	{ NULL, NULL }
+};
+
+#define	RK30_GPIO_LOCK(_sc)		mtx_lock(&_sc->sc_mtx)
+#define	RK30_GPIO_UNLOCK(_sc)		mtx_unlock(&_sc->sc_mtx)
+#define	RK30_GPIO_LOCK_ASSERT(_sc)	mtx_assert(&_sc->sc_mtx, MA_OWNED)
+
+#define	RK30_GPIO_SWPORT_DR		0x00
+#define	RK30_GPIO_SWPORT_DDR		0x04
+#define	RK30_GPIO_INTEN			0x30
+#define	RK30_GPIO_INTMASK		0x34
+#define	RK30_GPIO_INTTYPE_LEVEL		0x38
+#define	RK30_GPIO_INT_POLARITY		0x3c
+#define	RK30_GPIO_INT_STATUS		0x40
+#define	RK30_GPIO_INT_RAWSTATUS		0x44
+#define	RK30_GPIO_DEBOUNCE		0x48
+#define	RK30_GPIO_PORTS_EOI		0x4c
+#define	RK30_GPIO_EXT_PORT		0x50
+#define	RK30_GPIO_LS_SYNC		0x60
+
+#define	RK30_GPIO_WRITE(_sc, _off, _val)		\
+    bus_space_write_4(_sc->sc_bst, _sc->sc_bsh, _off, _val)
+#define	RK30_GPIO_READ(_sc, _off)			\
+    bus_space_read_4(_sc->sc_bst, _sc->sc_bsh, _off)
+
+static uint32_t
+rk30_gpio_get_function(struct rk30_gpio_softc *sc, uint32_t pin)
+{
+	uint32_t bank, func, offset;
+
+	bank = pin / 32;
+	pin = pin % 32;
+	offset = 1 << pin;
+
+	func = RK30_GPIO_READ(sc, RK30_GPIO_SWPORT_DDR);
+	func &= offset;
+
+	return (func);
+}
+
+static uint32_t
+rk30_gpio_func_flag(uint32_t nfunc)
+{
+
+	switch (nfunc) {
+	case RK30_GPIO_INPUT:
+		return (GPIO_PIN_INPUT);
+	case RK30_GPIO_OUTPUT:
+		return (GPIO_PIN_OUTPUT);
+	}
+	return (0);
+}
+
+static void
+rk30_gpio_set_function(struct rk30_gpio_softc *sc, uint32_t pin, uint32_t f)
+{
+	uint32_t bank, data, offset;
+
+	/* Must be called with lock held. */
+	RK30_GPIO_LOCK_ASSERT(sc);
+
+	bank = pin / 32;
+	pin = pin % 32;
+	offset = 1 << pin;
+
+	data = RK30_GPIO_READ(sc, RK30_GPIO_SWPORT_DDR);
+	if (f)
+		data |= offset;
+	else
+		data &= ~offset;
+	RK30_GPIO_WRITE(sc, RK30_GPIO_SWPORT_DDR, data);
+}
+
+static void
+rk30_gpio_set_pud(struct rk30_gpio_softc *sc, uint32_t pin, uint32_t state)
+{
+	uint32_t bank;
+
+	bank = pin / 32;
+
+	/* Must be called with lock held. */
+	RK30_GPIO_LOCK_ASSERT(sc);
+
+	if (bank == 0 && pin < 12)
+		rk30_pmu_gpio_pud(pin, state);
+	else
+		rk30_grf_gpio_pud(bank, pin, state);
+}
+
+static void
+rk30_gpio_pin_configure(struct rk30_gpio_softc *sc, struct gpio_pin *pin,
+    unsigned int flags)
+{
+
+	RK30_GPIO_LOCK(sc);
+
+	/*
+	 * Manage input/output.
+	 */
+	if (flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) {
+		pin->gp_flags &= ~(GPIO_PIN_INPUT|GPIO_PIN_OUTPUT);
+		if (flags & GPIO_PIN_OUTPUT) {
+			pin->gp_flags |= GPIO_PIN_OUTPUT;
+			rk30_gpio_set_function(sc, pin->gp_pin,
+			    RK30_GPIO_OUTPUT);
+		} else {
+			pin->gp_flags |= GPIO_PIN_INPUT;
+			rk30_gpio_set_function(sc, pin->gp_pin,
+			    RK30_GPIO_INPUT);
+		}
+	}
+
+	/* Manage Pull-up/pull-down. */
+	pin->gp_flags &= ~(GPIO_PIN_PULLUP|GPIO_PIN_PULLDOWN);
+	if (flags & (GPIO_PIN_PULLUP|GPIO_PIN_PULLDOWN)) {
+		if (flags & GPIO_PIN_PULLUP) {
+			pin->gp_flags |= GPIO_PIN_PULLUP;
+			rk30_gpio_set_pud(sc, pin->gp_pin, 
+			    RK30_GPIO_PULLUP);
+		} else {
+			pin->gp_flags |= GPIO_PIN_PULLDOWN;
+			rk30_gpio_set_pud(sc, pin->gp_pin, 
+			    RK30_GPIO_PULLDOWN);
+		}
+	} else
+		rk30_gpio_set_pud(sc, pin->gp_pin, RK30_GPIO_NONE);
+
+	RK30_GPIO_UNLOCK(sc);
+}
+
+static int
+rk30_gpio_pin_max(device_t dev, int *maxpin)
+{
+
+	*maxpin = RK30_GPIO_PINS - 1;
+	return (0);
+}
+
+static int
+rk30_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
+{
+	struct rk30_gpio_softc *sc = device_get_softc(dev);
+	int i;
+
+	for (i = 0; i < sc->sc_gpio_npins; i++) {
+		if (sc->sc_gpio_pins[i].gp_pin == pin)
+			break;
+	}
+
+	if (i >= sc->sc_gpio_npins)
+		return (EINVAL);
+
+	RK30_GPIO_LOCK(sc);
+	*caps = sc->sc_gpio_pins[i].gp_caps;
+	RK30_GPIO_UNLOCK(sc);
+
+	return (0);
+}
+
+static int
+rk30_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
+{
+	struct rk30_gpio_softc *sc = device_get_softc(dev);
+	int i;
+
+	for (i = 0; i < sc->sc_gpio_npins; i++) {
+		if (sc->sc_gpio_pins[i].gp_pin == pin)
+			break;
+	}
+
+	if (i >= sc->sc_gpio_npins)
+		return (EINVAL);
+
+	RK30_GPIO_LOCK(sc);
+	*flags = sc->sc_gpio_pins[i].gp_flags;
+	RK30_GPIO_UNLOCK(sc);
+
+	return (0);
+}
+
+static int
+rk30_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
+{
+	struct rk30_gpio_softc *sc = device_get_softc(dev);
+	int i;
+
+	for (i = 0; i < sc->sc_gpio_npins; i++) {
+		if (sc->sc_gpio_pins[i].gp_pin == pin)
+			break;
+	}
+
+	if (i >= sc->sc_gpio_npins)
+		return (EINVAL);
+
+	RK30_GPIO_LOCK(sc);
+	memcpy(name, sc->sc_gpio_pins[i].gp_name, GPIOMAXNAME);
+	RK30_GPIO_UNLOCK(sc);
+
+	return (0);
+}
+
+static int
+rk30_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
+{
+	struct rk30_gpio_softc *sc = device_get_softc(dev);
+	int i;
+
+	for (i = 0; i < sc->sc_gpio_npins; i++) {
+		if (sc->sc_gpio_pins[i].gp_pin == pin)
+			break;
+	}
+
+	if (i >= sc->sc_gpio_npins)
+		return (EINVAL);
+
+	rk30_gpio_pin_configure(sc, &sc->sc_gpio_pins[i], flags);
+
+	return (0);
+}
+
+static int
+rk30_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value)
+{
+	struct rk30_gpio_softc *sc = device_get_softc(dev);
+	uint32_t bank, offset, data;
+	int i;
+
+	for (i = 0; i < sc->sc_gpio_npins; i++) {
+		if (sc->sc_gpio_pins[i].gp_pin == pin)
+			break;
+	}
+
+	if (i >= sc->sc_gpio_npins)
+		return (EINVAL);
+
+	bank = pin / 32;
+	pin = pin % 32;
+	offset = 1 << pin;
+
+	RK30_GPIO_LOCK(sc);
+	data = RK30_GPIO_READ(sc, RK30_GPIO_SWPORT_DDR);
+	data |= offset;
+	RK30_GPIO_WRITE(sc, RK30_GPIO_SWPORT_DDR, data);
+
+	data = RK30_GPIO_READ(sc, RK30_GPIO_SWPORT_DR);
+	if (value)
+		data |= offset;
+	else
+		data &= ~offset;
+	RK30_GPIO_WRITE(sc, RK30_GPIO_SWPORT_DR, data);
+	RK30_GPIO_UNLOCK(sc);
+
+	return (0);
+}
+
+static int
+rk30_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val)
+{
+	struct rk30_gpio_softc *sc = device_get_softc(dev);
+	uint32_t bank, offset, reg_data;
+	int i;
+
+	for (i = 0; i < sc->sc_gpio_npins; i++) {
+		if (sc->sc_gpio_pins[i].gp_pin == pin)
+			break;
+	}
+
+	if (i >= sc->sc_gpio_npins)
+		return (EINVAL);
+
+	bank = pin / 32;
+	pin = pin % 32;
+	offset = 1 << pin;
+
+	RK30_GPIO_LOCK(sc);
+	reg_data = RK30_GPIO_READ(sc, RK30_GPIO_EXT_PORT);
+	RK30_GPIO_UNLOCK(sc);
+	*val = (reg_data & offset) ? 1 : 0;
+
+	return (0);
+}
+
+static int
+rk30_gpio_pin_toggle(device_t dev, uint32_t pin)
+{
+	struct rk30_gpio_softc *sc = device_get_softc(dev);
+	uint32_t bank, data, offset;
+	int i;
+
+	for (i = 0; i < sc->sc_gpio_npins; i++) {
+		if (sc->sc_gpio_pins[i].gp_pin == pin)
+			break;
+	}
+
+	if (i >= sc->sc_gpio_npins)
+		return (EINVAL);
+
+	bank = pin / 32;
+	pin = pin % 32;
+	offset = 1 << pin;
+
+	RK30_GPIO_LOCK(sc);
+	data = RK30_GPIO_READ(sc, RK30_GPIO_SWPORT_DDR);
+	if (data & offset)
+		data &= ~offset;
+	else
+		data |= offset;
+	RK30_GPIO_WRITE(sc, RK30_GPIO_SWPORT_DDR, data);
+
+	data = RK30_GPIO_READ(sc, RK30_GPIO_SWPORT_DR);
+	if (data & offset)
+		data &= ~offset;
+	else
+		data |= offset;
+	RK30_GPIO_WRITE(sc, RK30_GPIO_SWPORT_DR, data);
+	RK30_GPIO_UNLOCK(sc);
+
+	return (0);
+}
+
+static int
+rk30_gpio_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "rockchip,rk30xx-gpio"))
+		return (ENXIO);
+
+	device_set_desc(dev, "Rockchip RK30XX GPIO controller");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+rk30_gpio_attach(device_t dev)
+{
+	struct rk30_gpio_softc *sc = device_get_softc(dev);
+	uint32_t func;
+	int i, rid;
+	phandle_t gpio;
+
+	if (rk30_gpio_sc)
+		return (ENXIO);
+
+	sc->sc_dev = dev;
+
+	mtx_init(&sc->sc_mtx, "rk30 gpio", "gpio", MTX_DEF);
+
+	rid = 0;
+	sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	    RF_ACTIVE);
+	if (!sc->sc_mem_res) {
+		device_printf(dev, "cannot allocate memory window\n");
+		return (ENXIO);
+	}
+
+	sc->sc_bst = rman_get_bustag(sc->sc_mem_res);
+	sc->sc_bsh = rman_get_bushandle(sc->sc_mem_res);
+
+	rid = 0;
+	sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+	    RF_ACTIVE);
+	if (!sc->sc_irq_res) {
+		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
+		device_printf(dev, "cannot allocate interrupt\n");
+		return (ENXIO);
+	}
+
+	/* Find our node. */
+	gpio = ofw_bus_get_node(sc->sc_dev);
+
+	if (!OF_hasprop(gpio, "gpio-controller"))
+		/* Node is not a GPIO controller. */
+		goto fail;
+
+	/* Initialize the software controlled pins. */
+	for (i = 0; i < RK30_GPIO_PINS; i++) {
+		snprintf(sc->sc_gpio_pins[i].gp_name, GPIOMAXNAME,
+		    "pin %d", i);
+		func = rk30_gpio_get_function(sc, i);
+		sc->sc_gpio_pins[i].gp_pin = i;
+		sc->sc_gpio_pins[i].gp_caps = RK30_GPIO_DEFAULT_CAPS;
+		sc->sc_gpio_pins[i].gp_flags = rk30_gpio_func_flag(func);
+	}
+	sc->sc_gpio_npins = i;
+
+	device_add_child(dev, "gpioc", -1);
+	device_add_child(dev, "gpiobus", -1);
+
+	rk30_gpio_sc = sc;
+
+	rk30_gpio_init();
+	
+	return (bus_generic_attach(dev));
+
+fail:
+	if (sc->sc_irq_res)
+		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res);
+	if (sc->sc_mem_res)
+		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
+	return (ENXIO);
+}
+
+static int
+rk30_gpio_detach(device_t dev)
+{
+
+	return (EBUSY);
+}
+
+static device_method_t rk30_gpio_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		rk30_gpio_probe),
+	DEVMETHOD(device_attach,	rk30_gpio_attach),
+	DEVMETHOD(device_detach,	rk30_gpio_detach),
+
+	/* GPIO protocol */
+	DEVMETHOD(gpio_pin_max,		rk30_gpio_pin_max),
+	DEVMETHOD(gpio_pin_getname,	rk30_gpio_pin_getname),
+	DEVMETHOD(gpio_pin_getflags,	rk30_gpio_pin_getflags),
+	DEVMETHOD(gpio_pin_getcaps,	rk30_gpio_pin_getcaps),
+	DEVMETHOD(gpio_pin_setflags,	rk30_gpio_pin_setflags),
+	DEVMETHOD(gpio_pin_get,		rk30_gpio_pin_get),
+	DEVMETHOD(gpio_pin_set,		rk30_gpio_pin_set),
+	DEVMETHOD(gpio_pin_toggle,	rk30_gpio_pin_toggle),
+
+	DEVMETHOD_END
+};
+
+static devclass_t rk30_gpio_devclass;
+
+static driver_t rk30_gpio_driver = {
+	"gpio",
+	rk30_gpio_methods,
+	sizeof(struct rk30_gpio_softc),
+};
+
+DRIVER_MODULE(rk30_gpio, simplebus, rk30_gpio_driver, rk30_gpio_devclass, 0, 0);
+
+int
+rk30_gpios_prop_handle(phandle_t ctrl, pcell_t *gpios, int len)
+{
+	struct rk30_gpio_softc *sc;
+	pcell_t gpio_cells;
+	int inc, t, tuples, tuple_size;
+	int dir, flags, pin, i;
+	u_long gpio_ctrl, size;
+
+	sc = rk30_gpio_sc;
+	if (sc == NULL)
+		return ENXIO;
+
+	if (OF_getprop(ctrl, "#gpio-cells", &gpio_cells, sizeof(pcell_t)) < 0)
+		return (ENXIO);
+
+	gpio_cells = fdt32_to_cpu(gpio_cells);
+	if (gpio_cells != 2)
+		return (ENXIO);
+
+	tuple_size = gpio_cells * sizeof(pcell_t) + sizeof(phandle_t);
+	tuples = len / tuple_size;
+
+	if (fdt_regsize(ctrl, &gpio_ctrl, &size))
+		return (ENXIO);
+
+	/*
+	 * Skip controller reference, since controller's phandle is given
+	 * explicitly (in a function argument).
+	 */
+	inc = sizeof(ihandle_t) / sizeof(pcell_t);
+	gpios += inc;
+	for (t = 0; t < tuples; t++) {
+		pin = fdt32_to_cpu(gpios[0]);
+		dir = fdt32_to_cpu(gpios[1]);
+		flags = fdt32_to_cpu(gpios[2]);
+
+		for (i = 0; i < sc->sc_gpio_npins; i++) {
+			if (sc->sc_gpio_pins[i].gp_pin == pin)
+				break;
+		}
+		if (i >= sc->sc_gpio_npins)
+			return (EINVAL);
+
+		rk30_gpio_pin_configure(sc, &sc->sc_gpio_pins[i], flags);
+
+		if (dir == 1) {
+			/* Input. */
+			rk30_gpio_pin_set(sc->sc_dev, pin, RK30_GPIO_INPUT);
+		} else {
+			/* Output. */
+			rk30_gpio_pin_set(sc->sc_dev, pin, RK30_GPIO_OUTPUT);
+		}
+		gpios += gpio_cells + inc;
+	}
+
+	return (0);
+}
+
+#define	MAX_PINS_PER_NODE	5
+#define	GPIOS_PROP_CELLS	4
+
+static int
+rk30_gpio_init(void)
+{
+	phandle_t child, parent, root, ctrl;
+	pcell_t gpios[MAX_PINS_PER_NODE * GPIOS_PROP_CELLS];
+	struct gpio_ctrl_entry *e;
+	int len, rv;
+
+	root = OF_finddevice("/");
+	len = 0;
+	parent = root;
+
+	/* Traverse through entire tree to find nodes with 'gpios' prop */
+	for (child = OF_child(parent); child != 0; child = OF_peer(child)) {
+
+		/* Find a 'leaf'. Start the search from this node. */
+		while (OF_child(child)) {
+			parent = child;
+			child = OF_child(child);
+		}
+		if ((len = OF_getproplen(child, "gpios")) > 0) {
+
+			if (len > sizeof(gpios))
+				return (ENXIO);
+
+			/* Get 'gpios' property. */
+			OF_getprop(child, "gpios", &gpios, len);
+
+			e = (struct gpio_ctrl_entry *)&gpio_controllers;
+
+			/* Find and call a handler. */
+			for (; e->compat; e++) {
+				/*
+				 * First cell of 'gpios' property should
+				 * contain a ref. to a node defining GPIO
+				 * controller.
+				 */
+				ctrl = OF_node_from_xref(fdt32_to_cpu(gpios[0]));
+
+				if (fdt_is_compatible(ctrl, e->compat))
+					/* Call a handler. */
+					if ((rv = e->handler(ctrl,
+					    (pcell_t *)&gpios, len)))
+						return (rv);
+			}
+		}
+
+		if (OF_peer(child) == 0) {
+			/* No more siblings. */
+			child = parent;
+			parent = OF_parent(child);
+		}
+	}
+	return (0);
+}


Property changes on: trunk/sys/arm/rockchip/rk30xx_gpio.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/rockchip/rk30xx_grf.c
===================================================================
--- trunk/sys/arm/rockchip/rk30xx_grf.c	                        (rev 0)
+++ trunk/sys/arm/rockchip/rk30xx_grf.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,133 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Ganbold Tsagaankhuu <ganbold at freebsd.org>
+ * 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.
+ */
+
+/* General Register File for Rockchip RK30xx */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/rockchip/rk30xx_grf.c 266337 2014-05-17 18:53:36Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/timeet.h>
+#include <sys/timetc.h>
+#include <sys/watchdog.h>
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+
+#include "rk30xx_grf.h"
+
+struct rk30_grf_softc {
+	struct resource		*res;
+	bus_space_tag_t		bst;
+	bus_space_handle_t	bsh;
+};
+
+static struct rk30_grf_softc *rk30_grf_sc = NULL;
+
+#define	grf_read_4(sc, reg)		\
+	bus_space_read_4((sc)->bst, (sc)->bsh, (reg))
+#define	grf_write_4(sc, reg, val)	\
+	bus_space_write_4((sc)->bst, (sc)->bsh, (reg), (val))
+
+static int
+rk30_grf_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (ofw_bus_is_compatible(dev, "rockchip,rk30xx-grf")) {
+		device_set_desc(dev, "RK30XX General Register File");
+		return(BUS_PROBE_DEFAULT);
+	}
+
+	return (ENXIO);
+}
+
+static int
+rk30_grf_attach(device_t dev)
+{
+	struct rk30_grf_softc *sc = device_get_softc(dev);
+	int rid = 0;
+
+	if (rk30_grf_sc)
+		return (ENXIO);
+
+	sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
+	if (!sc->res) {
+		device_printf(dev, "could not allocate resource\n");
+		return (ENXIO);
+	}
+
+	sc->bst = rman_get_bustag(sc->res);
+	sc->bsh = rman_get_bushandle(sc->res);
+
+	rk30_grf_sc = sc;
+
+	return (0);
+}
+
+static device_method_t rk30_grf_methods[] = {
+	DEVMETHOD(device_probe,		rk30_grf_probe),
+	DEVMETHOD(device_attach,	rk30_grf_attach),
+	{ 0, 0 }
+};
+
+static driver_t rk30_grf_driver = {
+	"rk30_grf",
+	rk30_grf_methods,
+	sizeof(struct rk30_grf_softc),
+};
+
+static devclass_t rk30_grf_devclass;
+
+DRIVER_MODULE(rk30_grf, simplebus, rk30_grf_driver, rk30_grf_devclass, 0, 0);
+
+void
+rk30_grf_gpio_pud(uint32_t bank, uint32_t pin, uint32_t state)
+{
+	uint32_t offset;
+
+	offset = GRF_GPIO0B_PULL - 4 + (bank * 16) + ((pin / 8) * 4);
+	pin = (7 - (pin % 8)) * 2;
+	grf_write_4(rk30_grf_sc, offset, (0x3 << (16 + pin)) | (state << pin));
+}
+


Property changes on: trunk/sys/arm/rockchip/rk30xx_grf.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/rockchip/rk30xx_grf.h
===================================================================
--- trunk/sys/arm/rockchip/rk30xx_grf.h	                        (rev 0)
+++ trunk/sys/arm/rockchip/rk30xx_grf.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,142 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Ganbold Tsagaankhuu <ganbold at freebsd.org>
+ * 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: stable/10/sys/arm/rockchip/rk30xx_grf.h 266337 2014-05-17 18:53:36Z ian $
+ */
+
+#ifndef _RK30_GRF_H_
+#define	_RK30_GRF_H_
+
+#define	RK30_GRF_BASE		0xF0008000
+
+#define	GRF_GPIO0L_DIR		0x0000
+#define	GRF_GPIO0H_DIR		0x0004
+#define	GRF_GPIO1L_DIR		0x0008
+#define	GRF_GPIO1H_DIR		0x000c
+#define	GRF_GPIO2L_DIR		0x0010
+#define	GRF_GPIO2H_DIR		0x0014
+#define	GRF_GPIO3L_DIR		0x0018
+#define	GRF_GPIO3H_DIR		0x001c
+#define	GRF_GPIO0L_DO		0x0020
+#define	GRF_GPIO0H_DO		0x0024
+#define	GRF_GPIO1L_DO		0x0028
+#define	GRF_GPIO1H_DO		0x002c
+#define	GRF_GPIO2L_DO		0x0030
+#define	GRF_GPIO2H_DO		0x0034
+#define	GRF_GPIO3L_DO		0x0038
+#define	GRF_GPIO3H_DO		0x003c
+#define	GRF_GPIO0L_EN		0x0040
+#define	GRF_GPIO0H_EN		0x0044
+#define	GRF_GPIO1L_EN		0x0048
+#define	GRF_GPIO1H_EN		0x004c
+#define	GRF_GPIO2L_EN		0x0050
+#define	GRF_GPIO2H_EN		0x0054
+#define	GRF_GPIO3L_EN		0x0058
+#define	GRF_GPIO3H_EN		0x005c
+
+#define	GRF_GPIO0C_IOMUX	0x0068
+#define	GRF_GPIO0D_IOMUX	0x006c
+#define	GRF_GPIO1A_IOMUX	0x0070
+#define	GRF_GPIO1B_IOMUX	0x0074
+#define	GRF_GPIO1C_IOMUX	0x0078
+#define	GRF_GPIO1D_IOMUX	0x007c
+#define	GRF_GPIO2A_IOMUX	0x0080
+#define	GRF_GPIO2B_IOMUX	0x0084
+#define	GRF_GPIO2C_IOMUX	0x0088
+#define	GRF_GPIO2D_IOMUX	0x008c
+#define	GRF_GPIO3A_IOMUX	0x0090
+#define	GRF_GPIO3B_IOMUX	0x0094
+#define	GRF_GPIO3C_IOMUX	0x0098
+#define	GRF_GPIO3D_IOMUX	0x009c
+#define	GRF_SOC_CON0		0x00a0
+#define	GRF_SOC_CON1		0x00a4
+#define	GRF_SOC_CON2		0x00a8
+#define	GRF_SOC_STATUS0		0x00ac
+#define	GRF_DMAC1_CON0		0x00b0
+#define	GRF_DMAC1_CON1		0x00b4
+#define	GRF_DMAC1_CON2		0x00b8
+#define	GRF_DMAC2_CON0		0x00bc
+#define	GRF_DMAC2_CON1		0x00c0
+#define	GRF_DMAC2_CON2		0x00c4
+#define	GRF_DMAC2_CON3		0x00c8
+#define	GRF_CPU_CON0		0x00cc
+#define	GRF_CPU_CON1		0x00d0
+#define	GRF_CPU_CON2		0x00d4
+#define	GRF_CPU_CON3		0x00d8
+#define	GRF_CPU_CON4		0x00dc
+#define	GRF_CPU_CON5		0x00e0
+
+#define	GRF_DDRC_CON0		0x00ec
+#define	GRF_DDRC_STAT		0x00f0
+#define	GRF_IO_CON0		0x00f4
+#define	GRF_IO_CON1		0x00f8
+#define	GRF_IO_CON2		0x00fc
+#define	GRF_IO_CON3		0x0100
+#define	GRF_IO_CON4		0x0104
+#define	GRF_SOC_STATUS1		0x0108
+#define	GRF_UOC0_CON0		0x010c
+#define	GRF_UOC0_CON1		0x0110
+#define	GRF_UOC0_CON2		0x0114
+#define	GRF_UOC0_CON3		0x0118
+#define	GRF_UOC1_CON0		0x011c
+#define	GRF_UOC1_CON1		0x0120
+#define	GRF_UOC1_CON2		0x0124
+#define	GRF_UOC1_CON3		0x0128
+#define	GRF_UOC2_CON0		0x012c
+#define	GRF_UOC2_CON1		0x0130
+
+#define	GRF_UOC3_CON0		0x0138
+#define	GRF_UOC3_CON1		0x013c
+#define	GRF_HSIC_STAT		0x0140
+#define	GRF_OS_REG0		0x0144
+#define	GRF_OS_REG1		0x0148
+#define	GRF_OS_REG2		0x014c
+#define	GRF_OS_REG3		0x0150
+#define	GRF_OS_REG4		0x0154
+#define	GRF_OS_REG5		0x0158
+#define	GRF_OS_REG6		0x015c
+#define	GRF_OS_REG7		0x0160
+#define	GRF_GPIO0B_PULL		0x0164
+#define	GRF_GPIO0C_PULL		0x0168
+#define	GRF_GPIO0D_PULL		0x016c
+#define	GRF_GPIO1A_PULL		0x0170
+#define	GRF_GPIO1B_PULL		0x0174
+#define	GRF_GPIO1C_PULL		0x0178
+#define	GRF_GPIO1D_PULL		0x017c
+#define	GRF_GPIO2A_PULL		0x0180
+#define	GRF_GPIO2B_PULL		0x0184
+#define	GRF_GPIO2C_PULL		0x0188
+#define	GRF_GPIO2D_PULL		0x018c
+#define	GRF_GPIO3A_PULL		0x0190
+#define	GRF_GPIO3B_PULL		0x0194
+#define	GRF_GPIO3C_PULL		0x0198
+#define	GRF_GPIO3D_PULL		0x019c
+#define	GRF_FLASH_DATA_PULL	0x01a0
+#define	GRF_FLASH_CMD_PULL	0x01a4
+
+void rk30_grf_gpio_pud(uint32_t bank, uint32_t pin, uint32_t state);
+
+#endif /* _RK30_GRF_H_ */


Property changes on: trunk/sys/arm/rockchip/rk30xx_grf.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/rockchip/rk30xx_machdep.c
===================================================================
--- trunk/sys/arm/rockchip/rk30xx_machdep.c	                        (rev 0)
+++ trunk/sys/arm/rockchip/rk30xx_machdep.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,113 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Ganbold Tsagaankhuu <ganbold at freebsd.org>
+ * All rights reserved.
+ *
+ * This code is derived from software written for Brini by Mark Brinicombe
+ *
+ * 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.
+ *
+ * from: FreeBSD: //depot/projects/arm/src/sys/arm/ti/ti_machdep.c
+ */
+
+#include "opt_ddb.h"
+#include "opt_platform.h"
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/rockchip/rk30xx_machdep.c 266397 2014-05-18 13:05:07Z ian $");
+
+#define _ARM32_BUS_DMA_PRIVATE
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <machine/armreg.h>
+#include <machine/bus.h>
+#include <machine/devmap.h>
+#include <machine/machdep.h>
+
+#include <dev/fdt/fdt_common.h>
+
+vm_offset_t
+initarm_lastaddr(void)
+{
+
+	return (arm_devmap_lastaddr());
+}
+
+void
+initarm_early_init(void)
+{
+
+}
+
+void
+initarm_gpio_init(void)
+{
+}
+
+void
+initarm_late_init(void)
+{
+
+	/* Enable cache */
+	cpufunc_control(CPU_CONTROL_DC_ENABLE|CPU_CONTROL_IC_ENABLE,
+	    CPU_CONTROL_DC_ENABLE|CPU_CONTROL_IC_ENABLE);
+}
+
+/*
+ * Set up static device mappings.
+ */
+int
+initarm_devmap_init(void)
+{
+
+	arm_devmap_add_entry(0x10000000, 0x00200000);
+	arm_devmap_add_entry(0x20000000, 0x00100000);
+	
+	return (0);
+}
+
+struct arm32_dma_range *
+bus_dma_get_range(void)
+{
+
+	return (NULL);
+}
+
+int
+bus_dma_get_range_nb(void)
+{
+
+	return (0);
+}
+
+void
+cpu_reset()
+{
+
+	printf("No cpu_reset implementation!\n");
+	while (1);
+}


Property changes on: trunk/sys/arm/rockchip/rk30xx_machdep.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/rockchip/rk30xx_mp.c
===================================================================
--- trunk/sys/arm/rockchip/rk30xx_mp.c	                        (rev 0)
+++ trunk/sys/arm/rockchip/rk30xx_mp.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,193 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014 Ganbold Tsagaankhuu <ganbold at freebsd.org>
+ * 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 ``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 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: stable/10/sys/arm/rockchip/rk30xx_mp.c 266397 2014-05-18 13:05:07Z ian $");
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/smp.h>
+
+#include <machine/smp.h>
+#include <machine/fdt.h>
+#include <machine/intr.h>
+
+#define	SCU_PHYSBASE			0x1013c000
+#define	SCU_SIZE			0x100
+
+#define	SCU_CONTROL_REG			0x00
+#define	SCU_CONTROL_ENABLE		(1 << 0)
+#define	SCU_STANDBY_EN			(1 << 5)
+#define	SCU_CONFIG_REG			0x04
+#define	SCU_CONFIG_REG_NCPU_MASK	0x03
+#define	SCU_CPUPOWER_REG		0x08
+#define	SCU_INV_TAGS_REG		0x0c
+
+#define	SCU_FILTER_START_REG		0x10
+#define	SCU_FILTER_END_REG		0x14
+#define	SCU_SECURE_ACCESS_REG		0x18
+#define	SCU_NONSECURE_ACCESS_REG	0x1c
+
+#define	IMEM_PHYSBASE			0x10080000
+#define	IMEM_SIZE			0x20
+
+#define	PMU_PHYSBASE			0x20004000
+#define	PMU_SIZE			0x100
+#define	PMU_PWRDN_CON			0x08
+#define	PMU_PWRDN_SCU			(1 << 4)
+
+extern char 	*mpentry_addr;
+static void 	 rk30xx_boot2(void);
+
+static void
+rk30xx_boot2(void)
+{
+
+	__asm __volatile(
+			   "ldr pc, 1f\n"
+			   ".globl mpentry_addr\n"
+			   "mpentry_addr:\n"
+			"1: .space 4\n");
+}
+
+void
+platform_mp_init_secondary(void)
+{
+
+	gic_init_secondary();
+}
+
+void
+platform_mp_setmaxid(void)
+{
+	bus_space_handle_t scu;
+	int ncpu;
+	uint32_t val;
+
+	if (mp_ncpus != 0)
+		return;
+
+	if (bus_space_map(fdtbus_bs_tag, SCU_PHYSBASE, SCU_SIZE, 0, &scu) != 0)
+		panic("Could not map the SCU");
+
+	val = bus_space_read_4(fdtbus_bs_tag, scu, SCU_CONFIG_REG);
+	ncpu = (val & SCU_CONFIG_REG_NCPU_MASK) + 1;
+	bus_space_unmap(fdtbus_bs_tag, scu, SCU_SIZE);
+
+	mp_ncpus = ncpu;
+	mp_maxid = ncpu - 1;
+}
+
+int
+platform_mp_probe(void)
+{
+
+	if (mp_ncpus == 0)
+		platform_mp_setmaxid();
+
+	return (mp_ncpus > 1);
+}
+
+void
+platform_mp_start_ap(void)
+{
+	bus_space_handle_t scu;
+	bus_space_handle_t imem;
+	bus_space_handle_t pmu;
+	uint32_t val;
+	int i;
+
+	if (bus_space_map(fdtbus_bs_tag, SCU_PHYSBASE, SCU_SIZE, 0, &scu) != 0)
+		panic("Could not map the SCU");
+	if (bus_space_map(fdtbus_bs_tag, IMEM_PHYSBASE,
+	    IMEM_SIZE, 0, &imem) != 0)
+		panic("Could not map the IMEM");
+	if (bus_space_map(fdtbus_bs_tag, PMU_PHYSBASE, PMU_SIZE, 0, &pmu) != 0)
+		panic("Could not map the PMU");
+
+	/*
+	 * Invalidate SCU cache tags.  The 0x0000ffff constant invalidates all
+	 * ways on all cores 0-3. Per the ARM docs, it's harmless to write to
+	 * the bits for cores that are not present.
+	 */
+	bus_space_write_4(fdtbus_bs_tag, scu, SCU_INV_TAGS_REG, 0x0000ffff);
+
+	/* Make sure all cores except the first are off */
+	val = bus_space_read_4(fdtbus_bs_tag, pmu, PMU_PWRDN_CON);
+	for (i = 1; i < mp_ncpus; i++)
+		val |= 1 << i;
+	bus_space_write_4(fdtbus_bs_tag, pmu, PMU_PWRDN_CON, val);
+
+	/* Enable SCU power domain */
+	val = bus_space_read_4(fdtbus_bs_tag, pmu, PMU_PWRDN_CON);
+	val &= ~PMU_PWRDN_SCU;
+	bus_space_write_4(fdtbus_bs_tag, pmu, PMU_PWRDN_CON, val);
+
+	/* Enable SCU */
+	val = bus_space_read_4(fdtbus_bs_tag, scu, SCU_CONTROL_REG);
+	bus_space_write_4(fdtbus_bs_tag, scu, SCU_CONTROL_REG,
+	    val | SCU_CONTROL_ENABLE);
+
+	/*
+	 * Cores will execute the code which resides at the start of
+	 * the on-chip bootram/sram after power-on. This sram region
+	 * should be reserved and the trampoline code that directs
+	 * the core to the real startup code in ram should be copied
+	 * into this sram region.
+	 *
+	 * First set boot function for the sram code.
+	 */
+	mpentry_addr = (char *)pmap_kextract((vm_offset_t)mpentry);
+
+	/* Copy trampoline to sram, that runs during startup of the core */
+	bus_space_write_region_4(fdtbus_bs_tag, imem, 0,
+	    (uint32_t *)&rk30xx_boot2, 8);
+
+	cpu_idcache_wbinv_all();
+	cpu_l2cache_wbinv_all();
+
+	/* Start all cores */
+	val = bus_space_read_4(fdtbus_bs_tag, pmu, PMU_PWRDN_CON);
+	for (i = 1; i < mp_ncpus; i++)
+		val &= ~(1 << i);
+	bus_space_write_4(fdtbus_bs_tag, pmu, PMU_PWRDN_CON, val);
+
+	armv7_sev();
+
+	bus_space_unmap(fdtbus_bs_tag, scu, SCU_SIZE);
+	bus_space_unmap(fdtbus_bs_tag, imem, IMEM_SIZE);
+	bus_space_unmap(fdtbus_bs_tag, pmu, PMU_SIZE);
+}
+
+void
+platform_ipi_send(cpuset_t cpus, u_int ipi)
+{
+
+	pic_ipi_send(cpus, ipi);
+}


Property changes on: trunk/sys/arm/rockchip/rk30xx_mp.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/rockchip/rk30xx_pmu.c
===================================================================
--- trunk/sys/arm/rockchip/rk30xx_pmu.c	                        (rev 0)
+++ trunk/sys/arm/rockchip/rk30xx_pmu.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,133 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Ganbold Tsagaankhuu <ganbold at freebsd.org>
+ * 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.
+ */
+
+/* PMU for Rockchip RK30xx */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/rockchip/rk30xx_pmu.c 266337 2014-05-17 18:53:36Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/timeet.h>
+#include <sys/timetc.h>
+#include <sys/watchdog.h>
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+
+#include "rk30xx_pmu.h"
+
+struct rk30_pmu_softc {
+	struct resource		*res;
+	bus_space_tag_t		bst;
+	bus_space_handle_t	bsh;
+};
+
+static struct rk30_pmu_softc *rk30_pmu_sc = NULL;
+
+#define	pmu_read_4(sc, reg)		\
+	bus_space_read_4((sc)->bst, (sc)->bsh, (reg))
+#define	pmu_write_4(sc, reg, val)	\
+	bus_space_write_4((sc)->bst, (sc)->bsh, (reg), (val))
+
+static int
+rk30_pmu_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (ofw_bus_is_compatible(dev, "rockchip,rk30xx-pmu")) {
+		device_set_desc(dev, "RK30XX PMU");
+		return(BUS_PROBE_DEFAULT);
+	}
+
+	return (ENXIO);
+}
+
+static int
+rk30_pmu_attach(device_t dev)
+{
+	struct rk30_pmu_softc *sc = device_get_softc(dev);
+	int rid = 0;
+
+	if (rk30_pmu_sc)
+		return (ENXIO);
+
+	sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
+	if (!sc->res) {
+		device_printf(dev, "could not allocate resource\n");
+		return (ENXIO);
+	}
+
+	sc->bst = rman_get_bustag(sc->res);
+	sc->bsh = rman_get_bushandle(sc->res);
+
+	rk30_pmu_sc = sc;
+
+	return (0);
+}
+
+static device_method_t rk30_pmu_methods[] = {
+	DEVMETHOD(device_probe,		rk30_pmu_probe),
+	DEVMETHOD(device_attach,	rk30_pmu_attach),
+	{ 0, 0 }
+};
+
+static driver_t rk30_pmu_driver = {
+	"rk30_pmu",
+	rk30_pmu_methods,
+	sizeof(struct rk30_pmu_softc),
+};
+
+static devclass_t rk30_pmu_devclass;
+
+DRIVER_MODULE(rk30_pmu, simplebus, rk30_pmu_driver, rk30_pmu_devclass, 0, 0);
+
+void
+rk30_pmu_gpio_pud(uint32_t pin, uint32_t state)
+{
+	uint32_t offset;
+
+	offset = PMU_GPIO0A_PULL + ((pin / 8) * 4);
+	pin = (pin % 8) * 2;
+	pmu_write_4(rk30_pmu_sc, offset, (0x3 << (16 + pin)) | (state << pin));
+}
+


Property changes on: trunk/sys/arm/rockchip/rk30xx_pmu.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/rockchip/rk30xx_pmu.h
===================================================================
--- trunk/sys/arm/rockchip/rk30xx_pmu.h	                        (rev 0)
+++ trunk/sys/arm/rockchip/rk30xx_pmu.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,61 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Ganbold Tsagaankhuu <ganbold at freebsd.org>
+ * 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: stable/10/sys/arm/rockchip/rk30xx_pmu.h 266337 2014-05-17 18:53:36Z ian $
+ */
+
+#ifndef _RK30_PMU_H_
+#define	_RK30_PMU_H_
+
+#define	RK30_PMU_BASE			0xF0004000
+
+#define	PMU_WAKEUP_CFG0			0x00
+#define	PMU_WAKEUP_CFG1			0x04
+#define	PMU_PWRDN_CON			0x08
+#define	PMU_PWRDN_ST			0x0c
+#define	PMU_INT_CON			0x10
+#define	PMU_INT_ST			0x14
+#define	PMU_MISC_CON			0x18
+#define	PMU_OSC_CNT			0x1c
+#define	PMU_PLL_CNT			0x20
+#define	PMU_PMU_CNT			0x24
+#define	PMU_DDRIO_PWRON_CNT		0x28
+#define	PMU_WAKEUP_RST_CLR_CNT		0x2c
+#define	PMU_SCU_PWRDWN_CNT		0x30
+#define	PMU_SCU_PWRUP_CNT		0x34
+#define	PMU_MISC_CON1			0x38
+#define	PMU_GPIO0_CON			0x3c
+#define	PMU_SYS_REG0			0x40
+#define	PMU_SYS_REG1			0x44
+#define	PMU_SYS_REG2			0x48
+#define	PMU_SYS_REG3			0x4c
+#define	PMU_STOP_INT_DLY		0x60
+#define	PMU_GPIO0A_PULL			0x64
+#define	PMU_GPIO0B_PULL			0x68
+
+void rk30_pmu_gpio_pud(uint32_t pin, uint32_t state);
+
+#endif /* _RK30_PMU_H_ */


Property changes on: trunk/sys/arm/rockchip/rk30xx_pmu.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/rockchip/rk30xx_wdog.c
===================================================================
--- trunk/sys/arm/rockchip/rk30xx_wdog.c	                        (rev 0)
+++ trunk/sys/arm/rockchip/rk30xx_wdog.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,202 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Ganbold Tsagaankhuu <ganbold at freebsd.org>
+ * 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: stable/10/sys/arm/rockchip/rk30xx_wdog.c 266337 2014-05-17 18:53:36Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/watchdog.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/rman.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+#include <machine/cpufunc.h>
+#include <machine/machdep.h>
+#include <machine/fdt.h>
+
+#include <arm/rockchip/rk30xx_wdog.h>
+
+#ifndef	RK30_WDT_BASE
+#define	RK30_WDT_BASE		0x2004c000
+#define	RK30_WDT_PSIZE		0x100
+#endif
+
+#define	RK30_WDT_READ(_sc, _r)		bus_read_4((_sc)->res, (_r))
+#define	RK30_WDT_WRITE(_sc, _r, _v)	bus_write_4((_sc)->res, (_r), (_v))
+
+#define	WDOG_CTRL		0x00
+#define	WDOG_CTRL_EN		(1 << 0)
+#define	WDOG_CTRL_RSP_MODE	(1 << 1)
+#define	WDOG_CTRL_RST_PULSE	(4 << 2)
+#define	WDOG_CTRL_RST		0xa
+#define	WDOG_TORR		0x04
+#define	WDOG_TORR_INTVL_SHIFT	0
+#define	WDOG_CCVR		0x08
+#define	WDOG_CRR		0x0c
+#define	WDOG_CRR_PWD		0x76
+#define	WDOG_STAT		0x10
+#define	WDOG_EOI		0x14
+
+static struct rk30_wd_softc *rk30_wd_sc = NULL;
+
+struct rk30_wd_softc {
+	device_t		dev;
+	struct resource		*res;
+	struct mtx		mtx;
+	int			freq;
+};
+
+static void rk30_wd_watchdog_fn(void *private, u_int cmd, int *error);
+
+static int
+rk30_wd_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (ofw_bus_is_compatible(dev, "rockchip,rk30xx-wdt")) {
+		device_set_desc(dev, "Rockchip RK30XX Watchdog");
+		return (BUS_PROBE_DEFAULT);
+	}
+
+	return (ENXIO);
+}
+
+static int
+rk30_wd_attach(device_t dev)
+{
+	struct rk30_wd_softc *sc;
+	int rid;
+	phandle_t node;
+	pcell_t cell;
+
+	if (rk30_wd_sc != NULL)
+		return (ENXIO);
+
+	sc = device_get_softc(dev);
+	sc->dev = dev;
+
+	node = ofw_bus_get_node(sc->dev);
+	if (OF_getencprop(node, "clock-frequency", &cell, sizeof(cell)) > 0)
+		sc->freq = cell / 1000000;
+	else
+		return (ENXIO);
+
+	rid = 0;
+	sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
+	if (sc->res == NULL) {
+		device_printf(dev, "could not allocate memory resource\n");
+		return (ENXIO);
+	}
+
+	rk30_wd_sc = sc;
+	mtx_init(&sc->mtx, "RK30XX Watchdog", "rk30_wd", MTX_DEF);
+	EVENTHANDLER_REGISTER(watchdog_list, rk30_wd_watchdog_fn, sc, 0);
+
+	return (0);
+}
+
+static void
+rk30_wd_watchdog_fn(void *private, u_int cmd, int *error)
+{
+	struct rk30_wd_softc *sc;
+	uint64_t ms, m, max;
+	int i;
+
+	sc = private;
+	mtx_lock(&sc->mtx);
+
+	cmd &= WD_INTERVAL;
+
+	if (cmd > 0) {
+		ms = ((uint64_t)1 << (cmd & WD_INTERVAL)) / 1000000;
+		m = 0xffff / sc->freq;
+		max = 0x7fffffff / sc->freq + 1;
+		i = 0;
+		while (m < max && m < ms) {
+			m <<= 1;
+			i++;
+		}
+		if (m < max) {
+			RK30_WDT_WRITE(sc, WDOG_TORR,
+			    i << WDOG_TORR_INTVL_SHIFT);
+			RK30_WDT_WRITE(sc, WDOG_CTRL,
+			    WDOG_CTRL_EN | WDOG_CTRL_RSP_MODE |
+			    WDOG_CTRL_RST_PULSE);
+			RK30_WDT_WRITE(sc, WDOG_CRR, WDOG_CRR_PWD);
+			*error = 0;
+		} else {
+			device_printf(sc->dev, "Can not be disabled\n");
+			mtx_unlock(&sc->mtx);
+			RK30_WDT_WRITE(sc, WDOG_CTRL, WDOG_CTRL_RST);
+			return;
+		}
+	}
+	else
+		RK30_WDT_WRITE(sc, WDOG_CTRL, WDOG_CTRL_RST);
+
+	mtx_unlock(&sc->mtx);
+}
+
+void
+rk30_wd_watchdog_reset()
+{
+	bus_space_handle_t bsh;
+
+	bus_space_map(fdtbus_bs_tag, RK30_WDT_BASE, RK30_WDT_PSIZE, 0, &bsh);
+	bus_space_write_4(fdtbus_bs_tag, bsh, WDOG_TORR, 0);
+	bus_space_write_4(fdtbus_bs_tag, bsh, WDOG_CTRL,
+	    WDOG_CTRL_EN | WDOG_CTRL_RSP_MODE | WDOG_CTRL_RST_PULSE);
+
+	while (1);
+}
+
+static device_method_t rk30_wd_methods[] = {
+	DEVMETHOD(device_probe, rk30_wd_probe),
+	DEVMETHOD(device_attach, rk30_wd_attach),
+
+	DEVMETHOD_END
+};
+
+static driver_t rk30_wd_driver = {
+	"rk30_wd",
+	rk30_wd_methods,
+	sizeof(struct rk30_wd_softc),
+};
+static devclass_t rk30_wd_devclass;
+
+DRIVER_MODULE(rk30_wd, simplebus, rk30_wd_driver, rk30_wd_devclass, 0, 0);


Property changes on: trunk/sys/arm/rockchip/rk30xx_wdog.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/rockchip/rk30xx_wdog.h
===================================================================
--- trunk/sys/arm/rockchip/rk30xx_wdog.h	                        (rev 0)
+++ trunk/sys/arm/rockchip/rk30xx_wdog.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,36 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Ganbold Tsagaankhuu <ganbold at freebsd.org>
+ * 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: stable/10/sys/arm/rockchip/rk30xx_wdog.h 266337 2014-05-17 18:53:36Z ian $
+ *
+ */
+#ifndef	__RK30XX_WDOG_H__
+#define	__RK30XX_WDOG_H__
+
+void rk30_wd_watchdog_reset(void);
+
+#endif /*__RK30XX_WDOG_H__*/
+


Property changes on: trunk/sys/arm/rockchip/rk30xx_wdog.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/rockchip/std.rk30xx
===================================================================
--- trunk/sys/arm/rockchip/std.rk30xx	                        (rev 0)
+++ trunk/sys/arm/rockchip/std.rk30xx	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,26 @@
+# Rockchip rk30xx common options
+#$FreeBSD: stable/10/sys/arm/rockchip/std.rk30xx 278601 2015-02-11 22:47:48Z ian $
+
+cpu		CPU_CORTEXA
+machine		arm armv6
+makeoptions	CONF_CFLAGS="-march=armv7a -Wa,-march=armv7a"
+makeoption	ARM_LITTLE_ENDIAN
+
+# Physical memory starts at 0x60400000.  We assume images are loaded at
+# 0x60400000.
+#
+#
+options		PHYSADDR=0x60000000
+
+makeoptions	KERNPHYSADDR=0x60400000
+options		KERNPHYSADDR=0x60400000
+
+makeoptions	KERNVIRTADDR=0xc0400000
+options		KERNVIRTADDR=0xc0400000
+
+options		ARM_L2_PIPT
+
+options		IPI_IRQ_START=0
+options		IPI_IRQ_END=15
+
+files		"../rockchip/files.rk30xx"


Property changes on: trunk/sys/arm/rockchip/std.rk30xx
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/samsung/exynos/chrome_ec.c
===================================================================
--- trunk/sys/arm/samsung/exynos/chrome_ec.c	                        (rev 0)
+++ trunk/sys/arm/samsung/exynos/chrome_ec.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,267 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014 Ruslan Bukin <br at bsdpad.com>
+ * 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 EXPREC OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNEC 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 BUSINEC 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.
+ */
+
+/*
+ * Samsung Chromebook Embedded Controller
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/samsung/exynos/chrome_ec.c 266341 2014-05-17 19:37:04Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/timeet.h>
+#include <sys/timetc.h>
+#include <sys/watchdog.h>
+#include <sys/gpio.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#include <dev/iicbus/iiconf.h>
+
+#include "iicbus_if.h"
+#include "gpio_if.h"
+
+#include <arm/samsung/exynos/chrome_ec.h>
+
+/* TODO: export to DTS */
+#define OUR_GPIO	177
+#define EC_GPIO		168
+
+struct ec_softc {
+	device_t	dev;
+};
+
+struct ec_softc *ec_sc;
+
+/*
+ * bus_claim, bus_release
+ * both functions used for bus arbitration
+ * in multi-master mode
+ */
+
+static int
+bus_claim(struct ec_softc *sc)
+{
+	device_t gpio_dev;
+	int status;
+
+	gpio_dev = devclass_get_device(devclass_find("gpio"), 0);
+        if (gpio_dev == NULL) {
+		device_printf(sc->dev, "cant find gpio_dev\n");
+		return (1);
+	}
+
+	/* Say we want the bus */
+	GPIO_PIN_SET(gpio_dev, OUR_GPIO, GPIO_PIN_LOW);
+
+	/* Check EC decision */
+	GPIO_PIN_GET(gpio_dev, EC_GPIO, &status);
+
+	if (status == 1) {
+		/* Okay. We have bus */
+		return (0);
+	}
+
+	/* EC is master */
+	return (-1);
+}
+
+static int
+bus_release(struct ec_softc *sc)
+{
+	device_t gpio_dev;
+
+	gpio_dev = devclass_get_device(devclass_find("gpio"), 0);
+        if (gpio_dev == NULL) {
+		device_printf(sc->dev, "cant find gpio_dev\n");
+		return (1);
+	}
+
+	GPIO_PIN_SET(gpio_dev, OUR_GPIO, GPIO_PIN_HIGH);
+
+	return (0);
+}
+
+static int
+ec_probe(device_t dev)
+{
+
+	device_set_desc(dev, "Chromebook Embedded Controller");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+fill_checksum(uint8_t *data_out, int len)
+{
+	int res;
+	int i;
+
+	res = 0;
+	for (i = 0; i < len; i++) {
+		res += data_out[i];
+	}
+
+	data_out[len] = (res & 0xff);
+
+	return (0);
+}
+
+int
+ec_command(uint8_t cmd, uint8_t *dout, uint8_t dout_len,
+    uint8_t *dinp, uint8_t dinp_len)
+{
+	struct ec_softc *sc;
+	uint8_t *msg_dout;
+	uint8_t *msg_dinp;
+	int ret;
+	int i;
+
+	msg_dout = malloc(dout_len + 4, M_DEVBUF, M_NOWAIT);
+	msg_dinp = malloc(dinp_len + 4, M_DEVBUF, M_NOWAIT);
+
+	if (ec_sc == NULL)
+		return (-1);
+
+	sc = ec_sc;
+
+	msg_dout[0] = EC_CMD_VERSION0;
+	msg_dout[1] = cmd;
+	msg_dout[2] = dout_len;
+
+	for (i = 0; i < dout_len; i++) {
+		msg_dout[i + 3] = dout[i];
+	};
+
+	fill_checksum(msg_dout, dout_len + 3);
+
+	struct iic_msg msgs[] = {
+		{ 0x1e, IIC_M_WR, dout_len + 4, msg_dout, },
+		{ 0x1e, IIC_M_RD, dinp_len + 4, msg_dinp, },
+	};
+
+	ret = iicbus_transfer(sc->dev, msgs, 2);
+	if (ret != 0) {
+		device_printf(sc->dev, "i2c transfer returned %d\n", ret);
+		free(msg_dout, M_DEVBUF);
+		free(msg_dinp, M_DEVBUF);
+		return (-1);
+	}
+
+	for (i = 0; i < dinp_len; i++) {
+		dinp[i] = msg_dinp[i + 3];
+	};
+
+	free(msg_dout, M_DEVBUF);
+	free(msg_dinp, M_DEVBUF);
+	return (0);
+}
+
+int ec_hello(void)
+{
+	uint8_t data_in[4];
+	uint8_t data_out[4];
+
+	data_in[0] = 0x40;
+	data_in[1] = 0x30;
+	data_in[2] = 0x20;
+	data_in[3] = 0x10;
+
+	ec_command(EC_CMD_MKBP_STATE, data_in, 4,
+	    data_out, 4);
+
+	return (0);
+}
+
+static int
+ec_attach(device_t dev)
+{
+	struct ec_softc *sc;
+
+	sc = device_get_softc(dev);
+	sc->dev = dev;
+
+	ec_sc = sc;
+
+	/*
+	 * Claim the bus.
+	 *
+	 * We don't know cases when EC is master,
+	 * so hold the bus forever for us.
+	 *
+	 */
+
+	if (bus_claim(sc) != 0) {
+		return (ENXIO);
+	}
+
+	return (0);
+}
+
+static int
+ec_detach(device_t dev)
+{
+	struct ec_softc *sc;
+
+	sc = device_get_softc(dev);
+
+	bus_release(sc);
+
+	return (0);
+}
+
+static device_method_t ec_methods[] = {
+	DEVMETHOD(device_probe,		ec_probe),
+	DEVMETHOD(device_attach,	ec_attach),
+	DEVMETHOD(device_detach,	ec_detach),
+	{ 0, 0 }
+};
+
+static driver_t ec_driver = {
+	"chrome_ec",
+	ec_methods,
+	sizeof(struct ec_softc),
+};
+
+static devclass_t ec_devclass;
+
+DRIVER_MODULE(chrome_ec, iicbus, ec_driver, ec_devclass, 0, 0);
+MODULE_VERSION(chrome_ec, 1);
+MODULE_DEPEND(chrome_ec, iicbus, 1, 1, 1);


Property changes on: trunk/sys/arm/samsung/exynos/chrome_ec.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/samsung/exynos/chrome_ec.h
===================================================================
--- trunk/sys/arm/samsung/exynos/chrome_ec.h	                        (rev 0)
+++ trunk/sys/arm/samsung/exynos/chrome_ec.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,37 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014 Ruslan Bukin <br at bsdpad.com>
+ * 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: stable/10/sys/arm/samsung/exynos/chrome_ec.h 266341 2014-05-17 19:37:04Z ian $
+ */
+
+#define	EC_CMD_HELLO		0x01
+#define	EC_CMD_GET_VERSION	0x02
+#define	EC_CMD_MKBP_STATE	0x60
+#define	EC_CMD_VERSION0		0xdc
+
+int ec_command(uint8_t cmd, uint8_t *dout, uint8_t dout_len,
+    uint8_t *dinp, uint8_t dinp_len);
+int ec_hello(void);


Property changes on: trunk/sys/arm/samsung/exynos/chrome_ec.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/samsung/exynos/chrome_kb.c
===================================================================
--- trunk/sys/arm/samsung/exynos/chrome_kb.c	                        (rev 0)
+++ trunk/sys/arm/samsung/exynos/chrome_kb.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,792 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014 Ruslan Bukin <br at bsdpad.com>
+ * 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.
+ */
+
+/*
+ * Samsung Chromebook Keyboard
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/samsung/exynos/chrome_kb.c 266352 2014-05-17 20:52:10Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/proc.h>
+#include <sys/sched.h>
+#include <sys/kdb.h>
+#include <sys/timeet.h>
+#include <sys/timetc.h>
+#include <sys/mutex.h>
+#include <sys/gpio.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <sys/ioccom.h>
+#include <sys/filio.h>
+#include <sys/tty.h>
+#include <sys/kbio.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#include "gpio_if.h"
+
+#include <arm/samsung/exynos/chrome_ec.h>
+#include <arm/samsung/exynos/chrome_kb.h>
+
+#include <arm/samsung/exynos/exynos5_combiner.h>
+#include <arm/samsung/exynos/exynos5_pad.h>
+
+#define	CKB_LOCK()	mtx_lock(&Giant)
+#define	CKB_UNLOCK()	mtx_unlock(&Giant)
+
+#ifdef	INVARIANTS
+/*
+ * Assert that the lock is held in all contexts
+ * where the code can be executed.
+ */
+#define	CKB_LOCK_ASSERT()	mtx_assert(&Giant, MA_OWNED)
+/*
+ * Assert that the lock is held in the contexts
+ * where it really has to be so.
+ */
+#define	CKB_CTX_LOCK_ASSERT()			 	\
+	do {						\
+		if (!kdb_active && panicstr == NULL)	\
+			mtx_assert(&Giant, MA_OWNED);	\
+	} while (0)
+#else
+#define CKB_LOCK_ASSERT()	(void)0
+#define CKB_CTX_LOCK_ASSERT()	(void)0
+#endif
+
+/*
+ * Define a stub keyboard driver in case one hasn't been
+ * compiled into the kernel
+ */
+#include <sys/kbio.h>
+#include <dev/kbd/kbdreg.h>
+#include <dev/kbd/kbdtables.h>
+
+#define	CKB_NFKEY		12
+#define	CKB_FLAG_COMPOSE	0x1
+#define	CKB_FLAG_POLLING	0x2
+#define	KBD_DRIVER_NAME		"ckbd"
+
+/* TODO: take interrupt from DTS */
+#define	KB_GPIO_INT		146
+
+struct ckb_softc {
+	keyboard_t sc_kbd;
+	keymap_t sc_keymap;
+	accentmap_t sc_accmap;
+	fkeytab_t sc_fkeymap[CKB_NFKEY];
+
+	struct resource*	sc_mem_res;
+	struct resource*	sc_irq_res;
+	void*			sc_intr_hl;
+
+	int	sc_mode;	/* input mode (K_XLATE,K_RAW,K_CODE) */
+	int	sc_state;	/* shift/lock key state */
+	int	sc_accents;	/* accent key index (> 0) */
+	int	sc_flags;	/* flags */
+
+	struct callout		sc_repeat_callout;
+	int			sc_repeat_key;
+	int			sc_repeating;
+
+	int			flag;
+	int			rows;
+	int			cols;
+	device_t		dev;
+	struct thread		*sc_poll_thread;
+
+	uint8_t			*scan_local;
+	uint8_t			*scan;
+};
+
+/* prototypes */
+static int	ckb_set_typematic(keyboard_t *, int);
+static uint32_t	ckb_read_char(keyboard_t *, int);
+static void	ckb_clear_state(keyboard_t *);
+static int	ckb_ioctl(keyboard_t *, u_long, caddr_t);
+static int	ckb_enable(keyboard_t *);
+static int	ckb_disable(keyboard_t *);
+
+static void
+ckb_repeat(void *arg)
+{
+	struct ckb_softc *sc;
+
+	sc = arg;
+
+	if (KBD_IS_ACTIVE(&sc->sc_kbd) && KBD_IS_BUSY(&sc->sc_kbd)) {
+		if (sc->sc_repeat_key != -1) {
+			sc->sc_repeating = 1;
+			sc->sc_kbd.kb_callback.kc_func(&sc->sc_kbd,
+			    KBDIO_KEYINPUT, sc->sc_kbd.kb_callback.kc_arg);
+		}
+	}
+}
+
+/* detect a keyboard, not used */
+static int
+ckb__probe(int unit, void *arg, int flags)
+{
+
+	return (ENXIO);
+}
+
+/* reset and initialize the device, not used */
+static int
+ckb_init(int unit, keyboard_t **kbdp, void *arg, int flags)
+{
+
+	return (ENXIO);
+}
+
+/* test the interface to the device, not used */
+static int
+ckb_test_if(keyboard_t *kbd)
+{
+
+	return (0);
+}
+
+/* finish using this keyboard, not used */
+static int
+ckb_term(keyboard_t *kbd)
+{
+
+	return (ENXIO);
+}
+
+/* keyboard interrupt routine, not used */
+static int
+ckb_intr(keyboard_t *kbd, void *arg)
+{
+
+        return (0);
+}
+
+/* lock the access to the keyboard, not used */
+static int
+ckb_lock(keyboard_t *kbd, int lock)
+{
+
+        return (1);
+}
+
+/* clear the internal state of the keyboard */
+static void
+ckb_clear_state(keyboard_t *kbd)
+{
+	struct ckb_softc *sc;
+
+	sc = kbd->kb_data;
+
+	CKB_CTX_LOCK_ASSERT();
+
+	sc->sc_flags &= ~(CKB_FLAG_COMPOSE | CKB_FLAG_POLLING);
+	sc->sc_state &= LOCK_MASK; /* preserve locking key state */
+	sc->sc_accents = 0;
+}
+
+/* save the internal state, not used */
+static int
+ckb_get_state(keyboard_t *kbd, void *buf, size_t len)
+{
+
+	return (len == 0) ? 1 : -1;
+}
+
+/* set the internal state, not used */
+static int
+ckb_set_state(keyboard_t *kbd, void *buf, size_t len)
+{
+
+	return (EINVAL);
+}
+
+
+/* check if data is waiting */
+static int
+ckb_check(keyboard_t *kbd)
+{
+	struct ckb_softc *sc;
+	int i;
+
+	sc = kbd->kb_data;
+
+	CKB_CTX_LOCK_ASSERT();
+
+	if (!KBD_IS_ACTIVE(kbd))
+		return (0);
+
+	if (sc->sc_flags & CKB_FLAG_POLLING) {
+		return (1);
+	};
+
+	for (i = 0; i < sc->cols; i++)
+		if (sc->scan_local[i] != sc->scan[i]) {
+			return (1);
+		};
+
+	if (sc->sc_repeating)
+		return (1);
+
+	return (0);
+}
+
+/* check if char is waiting */
+static int
+ckb_check_char_locked(keyboard_t *kbd)
+{
+	CKB_CTX_LOCK_ASSERT();
+
+	if (!KBD_IS_ACTIVE(kbd))
+		return (0);
+
+	return (ckb_check(kbd));
+}
+
+static int
+ckb_check_char(keyboard_t *kbd)
+{
+	int result;
+
+	CKB_LOCK();
+	result = ckb_check_char_locked(kbd);
+	CKB_UNLOCK();
+
+	return (result);
+}
+
+/* read one byte from the keyboard if it's allowed */
+/* Currently unused. */
+static int
+ckb_read(keyboard_t *kbd, int wait)
+{
+	CKB_CTX_LOCK_ASSERT();
+
+	if (!KBD_IS_ACTIVE(kbd))
+		return (-1);
+
+	printf("Implement ME: %s\n", __func__);
+	return (0);
+}
+
+int scantokey(int i, int j);
+
+int
+scantokey(int i, int j)
+{
+	int k;
+
+	for (k = 0; k < KEYMAP_LEN; k++)
+		if ((keymap[k].col == i) && (keymap[k].row == j))
+			return (keymap[k].key);
+
+	return (0);
+}
+
+/* read char from the keyboard */
+static uint32_t
+ckb_read_char_locked(keyboard_t *kbd, int wait)
+{
+	struct ckb_softc *sc;
+	int i,j;
+	uint16_t key;
+	int oldbit;
+	int newbit;
+
+	sc = kbd->kb_data;
+
+	CKB_CTX_LOCK_ASSERT();
+
+	if (!KBD_IS_ACTIVE(kbd))
+		return (NOKEY);
+
+	if (sc->sc_repeating) {
+		sc->sc_repeating = 0;
+		callout_reset(&sc->sc_repeat_callout, hz / 10,
+                    ckb_repeat, sc);
+		return (sc->sc_repeat_key);
+	};
+
+	if (sc->sc_flags & CKB_FLAG_POLLING) {
+		/* TODO */
+	};
+
+	for (i = 0; i < sc->cols; i++) {
+		for (j = 0; j < sc->rows; j++) {
+			oldbit = (sc->scan_local[i] & (1 << j));
+			newbit = (sc->scan[i] & (1 << j));
+
+			if (oldbit == newbit)
+				continue;
+
+			key = scantokey(i,j);
+			if (key == 0) {
+				continue;
+			};
+
+			if (newbit > 0) {
+				/* key pressed */
+				sc->scan_local[i] |= (1 << j);
+
+				/* setup repeating */
+				sc->sc_repeat_key = key;
+				callout_reset(&sc->sc_repeat_callout,
+				    hz / 2, ckb_repeat, sc);
+
+			} else {
+				/* key released */
+				sc->scan_local[i] &= ~(1 << j);
+
+				/* release flag */
+				key |= 0x80;
+
+				/* unsetup repeating */
+				sc->sc_repeat_key = -1;
+				callout_stop(&sc->sc_repeat_callout);
+			}
+
+			return (key);
+		}
+	}
+
+	return (NOKEY);
+}
+
+/* Currently wait is always false. */
+static uint32_t
+ckb_read_char(keyboard_t *kbd, int wait)
+{
+	uint32_t keycode;
+
+	CKB_LOCK();
+	keycode = ckb_read_char_locked(kbd, wait);
+	CKB_UNLOCK();
+
+	return (keycode);
+}
+
+
+/* some useful control functions */
+static int
+ckb_ioctl_locked(keyboard_t *kbd, u_long cmd, caddr_t arg)
+{
+	struct ckb_softc *sc;
+	int i;
+
+	sc = kbd->kb_data;
+
+	CKB_LOCK_ASSERT();
+
+	switch (cmd) {
+	case KDGKBMODE:		/* get keyboard mode */
+		*(int *)arg = sc->sc_mode;
+		break;
+
+	case KDSKBMODE:		/* set keyboard mode */
+		switch (*(int *)arg) {
+		case K_XLATE:
+			if (sc->sc_mode != K_XLATE) {
+				/* make lock key state and LED state match */
+				sc->sc_state &= ~LOCK_MASK;
+				sc->sc_state |= KBD_LED_VAL(kbd);
+			}
+			/* FALLTHROUGH */
+		case K_RAW:
+		case K_CODE:
+			if (sc->sc_mode != *(int *)arg) {
+				if ((sc->sc_flags & CKB_FLAG_POLLING) == 0)
+					ckb_clear_state(kbd);
+				sc->sc_mode = *(int *)arg;
+			}
+			break;
+		default:
+			return (EINVAL);
+		}
+		break;
+
+	case KDGETLED:			/* get keyboard LED */
+		*(int *)arg = KBD_LED_VAL(kbd);
+		break;
+
+	case KDSETLED:			/* set keyboard LED */
+		/* NOTE: lock key state in "sc_state" won't be changed */
+		if (*(int *)arg & ~LOCK_MASK)
+			return (EINVAL);
+
+		i = *(int *)arg;
+
+		/* replace CAPS LED with ALTGR LED for ALTGR keyboards */
+		if (sc->sc_mode == K_XLATE &&
+		    kbd->kb_keymap->n_keys > ALTGR_OFFSET) {
+			if (i & ALKED)
+				i |= CLKED;
+			else
+				i &= ~CLKED;
+		}
+		if (KBD_HAS_DEVICE(kbd)) {
+			/* Configure LED */
+		}
+
+		KBD_LED_VAL(kbd) = *(int *)arg;
+		break;
+	case KDGKBSTATE:		/* get lock key state */
+		*(int *)arg = sc->sc_state & LOCK_MASK;
+		break;
+
+	case KDSKBSTATE:		/* set lock key state */
+		if (*(int *)arg & ~LOCK_MASK) {
+			return (EINVAL);
+		}
+		sc->sc_state &= ~LOCK_MASK;
+		sc->sc_state |= *(int *)arg;
+
+		/* set LEDs and quit */
+		return (ckb_ioctl(kbd, KDSETLED, arg));
+
+	case KDSETREPEAT:		/* set keyboard repeat rate (new
+					 * interface) */
+
+		if (!KBD_HAS_DEVICE(kbd)) {
+			return (0);
+		}
+		if (((int *)arg)[1] < 0) {
+			return (EINVAL);
+		}
+		if (((int *)arg)[0] < 0) {
+			return (EINVAL);
+		}
+		if (((int *)arg)[0] < 200)	/* fastest possible value */
+			kbd->kb_delay1 = 200;
+		else
+			kbd->kb_delay1 = ((int *)arg)[0];
+		kbd->kb_delay2 = ((int *)arg)[1];
+		return (0);
+
+	case KDSETRAD:			/* set keyboard repeat rate (old
+					 * interface) */
+		return (ckb_set_typematic(kbd, *(int *)arg));
+
+	case PIO_KEYMAP:		/* set keyboard translation table */
+	case OPIO_KEYMAP:		/* set keyboard translation table
+					 * (compat) */
+	case PIO_KEYMAPENT:		/* set keyboard translation table
+					 * entry */
+	case PIO_DEADKEYMAP:		/* set accent key translation table */
+		sc->sc_accents = 0;
+		/* FALLTHROUGH */
+	default:
+		return (genkbd_commonioctl(kbd, cmd, arg));
+	}
+
+	return (0);
+}
+
+static int
+ckb_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg)
+{
+	int result;
+
+	/*
+	 * XXX KDGKBSTATE, KDSKBSTATE and KDSETLED can be called from any
+	 * context where printf(9) can be called, which among other things
+	 * includes interrupt filters and threads with any kinds of locks
+	 * already held.  For this reason it would be dangerous to acquire
+	 * the Giant here unconditionally.  On the other hand we have to
+	 * have it to handle the ioctl.
+	 * So we make our best effort to auto-detect whether we can grab
+	 * the Giant or not.  Blame syscons(4) for this.
+	 */
+	switch (cmd) {
+	case KDGKBSTATE:
+	case KDSKBSTATE:
+	case KDSETLED:
+		if (!mtx_owned(&Giant) && !SCHEDULER_STOPPED())
+			return (EDEADLK);	/* best I could come up with */
+		/* FALLTHROUGH */
+	default:
+		CKB_LOCK();
+		result = ckb_ioctl_locked(kbd, cmd, arg);
+		CKB_UNLOCK();
+		return (result);
+	}
+}
+
+
+/*
+ * Enable the access to the device; until this function is called,
+ * the client cannot read from the keyboard.
+ */
+static int
+ckb_enable(keyboard_t *kbd)
+{
+
+	CKB_LOCK();
+	KBD_ACTIVATE(kbd);
+	CKB_UNLOCK();
+
+	return (0);
+}
+
+/* disallow the access to the device */
+static int
+ckb_disable(keyboard_t *kbd)
+{
+
+	CKB_LOCK();
+	KBD_DEACTIVATE(kbd);
+	CKB_UNLOCK();
+
+	return (0);
+}
+
+/* local functions */
+
+static int
+ckb_set_typematic(keyboard_t *kbd, int code)
+{
+	static const int delays[] = {250, 500, 750, 1000};
+	static const int rates[] = {34, 38, 42, 46, 50, 55, 59, 63,
+		68, 76, 84, 92, 100, 110, 118, 126,
+		136, 152, 168, 184, 200, 220, 236, 252,
+	272, 304, 336, 368, 400, 440, 472, 504};
+
+	if (code & ~0x7f) {
+		return (EINVAL);
+	}
+	kbd->kb_delay1 = delays[(code >> 5) & 3];
+	kbd->kb_delay2 = rates[code & 0x1f];
+	return (0);
+}
+
+static int
+ckb_poll(keyboard_t *kbd, int on)
+{
+	struct ckb_softc *sc;
+
+	sc = kbd->kb_data;
+
+	CKB_LOCK();
+	if (on) {
+		sc->sc_flags |= CKB_FLAG_POLLING;
+		sc->sc_poll_thread = curthread;
+	} else {
+		sc->sc_flags &= ~CKB_FLAG_POLLING;
+	}
+	CKB_UNLOCK();
+
+	return (0);
+}
+
+/* local functions */
+
+static int dummy_kbd_configure(int flags);
+
+keyboard_switch_t ckbdsw = {
+	.probe = &ckb__probe,
+	.init = &ckb_init,
+	.term = &ckb_term,
+	.intr = &ckb_intr,
+	.test_if = &ckb_test_if,
+	.enable = &ckb_enable,
+	.disable = &ckb_disable,
+	.read = &ckb_read,
+	.check = &ckb_check,
+	.read_char = &ckb_read_char,
+	.check_char = &ckb_check_char,
+	.ioctl = &ckb_ioctl,
+	.lock = &ckb_lock,
+	.clear_state = &ckb_clear_state,
+	.get_state = &ckb_get_state,
+	.set_state = &ckb_set_state,
+	.get_fkeystr = &genkbd_get_fkeystr,
+	.poll = &ckb_poll,
+	.diag = &genkbd_diag,
+};
+
+static int
+dummy_kbd_configure(int flags)
+{
+
+	return (0);
+}
+
+KEYBOARD_DRIVER(ckbd, ckbdsw, dummy_kbd_configure);
+
+static int
+parse_dts(struct ckb_softc *sc)
+{
+	phandle_t node;
+	pcell_t dts_value;
+	int len;
+
+	if ((node = ofw_bus_get_node(sc->dev)) == -1)
+		return (ENXIO);
+
+	if ((len = OF_getproplen(node, "keypad,num-rows")) <= 0)
+		return (ENXIO);
+	OF_getprop(node, "keypad,num-rows", &dts_value, len);
+	sc->rows = fdt32_to_cpu(dts_value);
+
+	if ((len = OF_getproplen(node, "keypad,num-columns")) <= 0)
+		return (ENXIO);
+	OF_getprop(node, "keypad,num-columns", &dts_value, len);
+	sc->cols = fdt32_to_cpu(dts_value);
+
+	if ((sc->rows == 0) || (sc->cols == 0))
+		return (ENXIO);
+
+	return (0);
+}
+
+void
+ckb_ec_intr(void *arg)
+{
+	struct ckb_softc *sc;
+
+	sc = arg;
+
+	if (sc->sc_flags & CKB_FLAG_POLLING)
+		return;
+
+	ec_command(EC_CMD_MKBP_STATE, sc->scan, sc->cols,
+	    sc->scan, sc->cols);
+
+	(sc->sc_kbd.kb_callback.kc_func) (&sc->sc_kbd, KBDIO_KEYINPUT,
+	    sc->sc_kbd.kb_callback.kc_arg);
+};
+
+static int
+chrome_kb_attach(device_t dev)
+{
+	struct ckb_softc *sc;
+	keyboard_t *kbd;
+	int error;
+	int rid;
+	int i;
+
+	sc = device_get_softc(dev);
+
+	sc->dev = dev;
+
+	if ((error = parse_dts(sc)) != 0)
+		return error;
+
+#if 0
+	device_printf(sc->dev, "Keyboard matrix [%dx%d]\n",
+	    sc->cols, sc->rows);
+#endif
+
+	/* TODO: take interrupt from DTS */
+	pad_setup_intr(KB_GPIO_INT, ckb_ec_intr, sc);
+
+	kbd = &sc->sc_kbd;
+	rid = 0;
+
+	sc->scan_local = malloc(sc->cols, M_DEVBUF, M_NOWAIT);
+	sc->scan = malloc(sc->cols, M_DEVBUF, M_NOWAIT);
+
+	for (i = 0; i < sc->cols; i++) {
+		sc->scan_local[i] = 0;
+		sc->scan[i] = 0;
+	};
+
+	kbd_init_struct(kbd, KBD_DRIVER_NAME, KB_OTHER,
+	    device_get_unit(dev), 0, 0, 0);
+	kbd->kb_data = (void *)sc;
+
+	sc->sc_keymap = key_map;
+        sc->sc_accmap = accent_map;
+	for (i = 0; i < CKB_NFKEY; i++) {
+		sc->sc_fkeymap[i] = fkey_tab[i];
+        }
+
+	kbd_set_maps(kbd, &sc->sc_keymap, &sc->sc_accmap,
+	    sc->sc_fkeymap, CKB_NFKEY);
+
+	KBD_FOUND_DEVICE(kbd);
+	ckb_clear_state(kbd);
+	KBD_PROBE_DONE(kbd);
+
+	callout_init(&sc->sc_repeat_callout, 0);
+
+	KBD_INIT_DONE(kbd);
+
+	if (kbd_register(kbd) < 0) {
+		return (ENXIO);
+	};
+	KBD_CONFIG_DONE(kbd);
+
+	return (0);
+}
+
+static int
+chrome_kb_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (ofw_bus_is_compatible(dev, "google,cros-ec-keyb")) {
+		device_set_desc(dev, "Chrome EC Keyboard");
+		return (BUS_PROBE_DEFAULT);
+	}
+
+	return (ENXIO);
+}
+
+static device_method_t chrome_kb_methods[] = {
+	DEVMETHOD(device_probe,		chrome_kb_probe),
+	DEVMETHOD(device_attach,	chrome_kb_attach),
+	{ 0, 0 }
+};
+
+static driver_t chrome_kb_driver = {
+	"chrome_kb",
+	chrome_kb_methods,
+	sizeof(struct ckb_softc),
+};
+
+static devclass_t chrome_kb_devclass;
+
+DRIVER_MODULE(chrome_kb, simplebus, chrome_kb_driver,
+    chrome_kb_devclass, 0, 0);


Property changes on: trunk/sys/arm/samsung/exynos/chrome_kb.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/samsung/exynos/chrome_kb.h
===================================================================
--- trunk/sys/arm/samsung/exynos/chrome_kb.h	                        (rev 0)
+++ trunk/sys/arm/samsung/exynos/chrome_kb.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,123 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014 Ruslan Bukin <br at bsdpad.com>
+ * 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: stable/10/sys/arm/samsung/exynos/chrome_kb.h 266341 2014-05-17 19:37:04Z ian $
+ */
+
+void ckb_ec_intr(void *);
+
+struct key {
+	uint8_t row;
+	uint8_t col;
+	uint8_t key;
+};
+
+#define	KEYMAP_LEN	75
+
+struct key keymap[KEYMAP_LEN] = {
+	{ 0x00, 0x01, 0x7d }, /* lmeta */
+	{ 0x00, 0x02, 0x3b }, /* F1 */
+	{ 0x00, 0x03, 0x30 }, /* B */
+	{ 0x00, 0x04, 0x44 }, /* F10 */
+	{ 0x00, 0x06, 0x31 }, /* N */
+	{ 0x00, 0x08, 0x0d }, /* = */
+	{ 0x00, 0x0a, 0x64 }, /* ralt */
+
+	{ 0x01, 0x01, 0x01 }, /* escape */
+	{ 0x01, 0x02, 0x3e }, /* F4 */
+	{ 0x01, 0x03, 0x22 }, /* G */
+	{ 0x01, 0x04, 0x41 }, /* F7 */
+	{ 0x01, 0x06, 0x23 }, /* H */
+	{ 0x01, 0x08, 0x28 }, /* ' */
+	{ 0x01, 0x09, 0x43 }, /* F9 */
+	{ 0x01, 0x0b, 0x0e }, /* backspace */
+
+	{ 0x02, 0x00, 0x1d }, /* lctrl */
+	{ 0x02, 0x01, 0x0f }, /* tab */
+	{ 0x02, 0x02, 0x3d }, /* F3 */
+	{ 0x02, 0x03, 0x14 }, /* t */
+	{ 0x02, 0x04, 0x40 }, /* F6 */
+	{ 0x02, 0x05, 0x1b }, /* ] */
+	{ 0x02, 0x06, 0x15 }, /* y */
+	{ 0x02, 0x07, 0x56 }, /* 102nd */
+	{ 0x02, 0x08, 0x1a }, /* [ */
+	{ 0x02, 0x09, 0x42 }, /* F8 */
+
+	{ 0x03, 0x01, 0x29 }, /* grave */
+	{ 0x03, 0x02, 0x3c }, /* F2 */
+	{ 0x03, 0x03, 0x06 }, /* 5 */
+	{ 0x03, 0x04, 0x3f }, /* F5 */
+	{ 0x03, 0x06, 0x07 }, /* 6 */
+	{ 0x03, 0x08, 0x0c }, /* - */
+	{ 0x03, 0x0b, 0x2b }, /* \ */
+
+	{ 0x04, 0x00, 0x61 }, /* rctrl */
+	{ 0x04, 0x01, 0x1e }, /* a */
+	{ 0x04, 0x02, 0x20 }, /* d */
+	{ 0x04, 0x03, 0x21 }, /* f */
+	{ 0x04, 0x04, 0x1f }, /* s */
+	{ 0x04, 0x05, 0x25 }, /* k */
+	{ 0x04, 0x06, 0x24 }, /* j */
+	{ 0x04, 0x08, 0x27 }, /* ; */
+	{ 0x04, 0x09, 0x26 }, /* l */
+	{ 0x04, 0x0a, 0x2b }, /* \ */
+	{ 0x04, 0x0b, 0x1c }, /* enter */
+
+	{ 0x05, 0x01, 0x2c }, /* z */
+	{ 0x05, 0x02, 0x2e }, /* c */
+	{ 0x05, 0x03, 0x2f }, /* v */
+	{ 0x05, 0x04, 0x2d }, /* x */
+	{ 0x05, 0x05, 0x33 }, /* , */
+	{ 0x05, 0x06, 0x32 }, /* m */
+	{ 0x05, 0x07, 0x2a }, /* lsh */
+	{ 0x05, 0x08, 0x35 }, /* / */
+	{ 0x05, 0x09, 0x34 }, /* . */
+	{ 0x05, 0x0B, 0x39 }, /* space */
+
+	{ 0x06, 0x01, 0x02 }, /* 1 */
+	{ 0x06, 0x02, 0x04 }, /* 3 */
+	{ 0x06, 0x03, 0x05 }, /* 4 */
+	{ 0x06, 0x04, 0x03 }, /* 2 */
+	{ 0x06, 0x05, 0x09 }, /* 8 */
+	{ 0x06, 0x06, 0x08 }, /* 7 */
+	{ 0x06, 0x08, 0x0b }, /* 0 */
+	{ 0x06, 0x09, 0x0a }, /* 9 */
+	{ 0x06, 0x0a, 0x38 }, /* lalt */
+	{ 0x06, 0x0b, 0x64 }, /* down */
+	{ 0x06, 0x0c, 0x62 }, /* right */
+
+	{ 0x07, 0x01, 0x10 }, /* q */
+	{ 0x07, 0x02, 0x12 }, /* e */
+	{ 0x07, 0x03, 0x13 }, /* r */
+	{ 0x07, 0x04, 0x11 }, /* w */
+	{ 0x07, 0x05, 0x17 }, /* i */
+	{ 0x07, 0x06, 0x16 }, /* u */
+	{ 0x07, 0x07, 0x36 }, /* rsh */
+	{ 0x07, 0x08, 0x19 }, /* p */
+	{ 0x07, 0x09, 0x18 }, /* o */
+	{ 0x07, 0x0b, 0x5F }, /* up */
+	{ 0x07, 0x0c, 0x61 }, /* left */
+};


Property changes on: trunk/sys/arm/samsung/exynos/chrome_kb.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/samsung/exynos/exynos5_combiner.c
===================================================================
--- trunk/sys/arm/samsung/exynos/exynos5_combiner.c	                        (rev 0)
+++ trunk/sys/arm/samsung/exynos/exynos5_combiner.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,305 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014 Ruslan Bukin <br at bsdpad.com>
+ * 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.
+ */
+
+/*
+ * Samsung Exynos 5 Interrupt Combiner
+ * Chapter 7, Exynos 5 Dual User's Manual Public Rev 1.00
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/samsung/exynos/exynos5_combiner.c 266341 2014-05-17 19:37:04Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/timeet.h>
+#include <sys/timetc.h>
+#include <sys/watchdog.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#include <arm/samsung/exynos/exynos5_common.h>
+#include <arm/samsung/exynos/exynos5_combiner.h>
+
+#define NGRP		32
+#define ITABLE_LEN	24
+
+#define	IESR(n)	(0x10 * n + 0x0)	/* Interrupt enable set */
+#define	IECR(n)	(0x10 * n + 0x4)	/* Interrupt enable clear */
+#define	ISTR(n)	(0x10 * n + 0x8)	/* Interrupt status */
+#define	IMSR(n)	(0x10 * n + 0xC)	/* Interrupt masked status */
+#define	CIPSR	0x100			/* Combined interrupt pending */
+
+struct combiner_softc {
+	struct resource		*res[1 + NGRP];
+	bus_space_tag_t		bst;
+	bus_space_handle_t	bsh;
+	void			*ih[NGRP];
+	device_t		dev;
+};
+
+struct combiner_softc *combiner_sc;
+
+static struct resource_spec combiner_spec[] = {
+	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		0,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		1,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		2,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		3,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		4,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		5,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		6,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		7,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		8,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		9,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		10,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		11,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		12,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		13,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		14,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		15,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		16,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		17,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		18,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		19,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		20,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		21,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		22,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		23,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		24,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		25,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		26,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		27,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		28,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		29,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		30,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		31,	RF_ACTIVE },
+	{ -1, 0 }
+};
+
+struct combiner_entry {
+	int combiner_id;
+	int bit;
+	char *source_name;
+};
+
+static struct combiner_entry interrupt_table[ITABLE_LEN] = {
+	{ 63, 1, "EINT[15]" },
+	{ 63, 0, "EINT[14]" },
+	{ 62, 1, "EINT[13]" },
+	{ 62, 0, "EINT[12]" },
+	{ 61, 1, "EINT[11]" },
+	{ 61, 0, "EINT[10]" },
+	{ 60, 1, "EINT[9]" },
+	{ 60, 0, "EINT[8]" },
+	{ 59, 1, "EINT[7]" },
+	{ 59, 0, "EINT[6]" },
+	{ 58, 1, "EINT[5]" },
+	{ 58, 0, "EINT[4]" },
+	{ 57, 3, "MCT_G3" },
+	{ 57, 2, "MCT_G2" },
+	{ 57, 1, "EINT[3]" },
+	{ 57, 0, "EINT[2]" },
+	{ 56, 6, "SYSMMU_G2D[1]" },
+	{ 56, 5, "SYSMMU_G2D[0]" },
+	{ 56, 2, "SYSMMU_FIMC_LITE1[1]" },
+	{ 56, 1, "SYSMMU_FIMC_LITE1[0]" },
+	{ 56, 0, "EINT[1]" },
+	{ 55, 4, "MCT_G1" },
+	{ 55, 3, "MCT_G0" },
+	{ 55, 0, "EINT[0]" },
+
+	/* TODO: add groups 54-32 */
+};
+
+struct combined_intr {
+	uint32_t	enabled;
+	void		(*ih) (void *);
+	void		*ih_user;
+};
+
+static struct combined_intr intr_map[32][8];
+
+static void
+combiner_intr(void *arg)
+{
+	struct combiner_softc *sc;
+	void (*ih) (void *);
+	void *ih_user;
+	int enabled;
+	int intrs;
+	int shift;
+	int cirq;
+	int grp;
+	int i,n;
+
+	sc = arg;
+
+	intrs = READ4(sc, CIPSR);
+	for (grp = 0; grp < 32; grp++) {
+		if (intrs & (1 << grp)) {
+			n = (grp / 4);
+			shift = (grp % 4) * 8;
+
+			cirq = READ4(sc, ISTR(n));
+			for (i = 0; i < 8; i++) {
+				if (cirq & (1 << (i + shift))) {
+					ih = intr_map[grp][i].ih;
+					ih_user = intr_map[grp][i].ih_user;
+					enabled = intr_map[grp][i].enabled;
+					if (enabled && (ih != NULL)) {
+						ih(ih_user);
+					}
+				}
+			}
+		}
+	}
+}
+
+void
+combiner_setup_intr(char *source_name, void (*ih)(void *), void *ih_user)
+{
+	struct combiner_entry *entry;
+	struct combined_intr *cirq;
+	struct combiner_softc *sc;
+	int shift;
+	int reg;
+	int grp;
+	int n;
+	int i;
+
+	sc = combiner_sc;
+
+	if (sc == NULL) {
+		device_printf(sc->dev, "Error: combiner is not attached\n");
+		return;
+	}
+
+	entry = NULL;
+
+	for (i = 0; i < ITABLE_LEN; i++) {
+		if (strcmp(interrupt_table[i].source_name, source_name) == 0) {
+			entry = &interrupt_table[i];
+		}
+	}
+
+	if (entry == NULL) {
+		device_printf(sc->dev, "Can't find interrupt name %s\n",
+		    source_name);
+		return;
+	}
+
+#if 0
+	device_printf(sc->dev, "Setting up interrupt %s\n", source_name);
+#endif
+
+	grp = entry->combiner_id - 32;
+
+	cirq = &intr_map[grp][entry->bit];
+	cirq->enabled = 1;
+	cirq->ih = ih;
+	cirq->ih_user = ih_user;
+
+	n = grp / 4;
+	shift = (grp % 4) * 8 + entry->bit;
+
+	reg = (1 << shift);
+	WRITE4(sc, IESR(n), reg);
+}
+
+static int
+combiner_probe(device_t dev)
+{
+
+	if (!ofw_bus_is_compatible(dev, "exynos,combiner"))
+		return (ENXIO);
+
+	device_set_desc(dev, "Samsung Exynos 5 Interrupt Combiner");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+combiner_attach(device_t dev)
+{
+	struct combiner_softc *sc;
+	int err;
+	int i;
+
+	sc = device_get_softc(dev);
+	sc->dev = dev;
+
+	if (bus_alloc_resources(dev, combiner_spec, sc->res)) {
+		device_printf(dev, "could not allocate resources\n");
+		return (ENXIO);
+	}
+
+	/* Memory interface */
+	sc->bst = rman_get_bustag(sc->res[0]);
+	sc->bsh = rman_get_bushandle(sc->res[0]);
+
+	combiner_sc = sc;
+
+        /* Setup interrupt handler */
+	for (i = 0; i < NGRP; i++) {
+		err = bus_setup_intr(dev, sc->res[1+i], INTR_TYPE_BIO | \
+		    INTR_MPSAFE, NULL, combiner_intr, sc, &sc->ih[i]);
+		if (err) {
+			device_printf(dev, "Unable to alloc int resource.\n");
+			return (ENXIO);
+		}
+	}
+
+	return (0);
+}
+
+static device_method_t combiner_methods[] = {
+	DEVMETHOD(device_probe,		combiner_probe),
+	DEVMETHOD(device_attach,	combiner_attach),
+	{ 0, 0 }
+};
+
+static driver_t combiner_driver = {
+	"combiner",
+	combiner_methods,
+	sizeof(struct combiner_softc),
+};
+
+static devclass_t combiner_devclass;
+
+DRIVER_MODULE(combiner, simplebus, combiner_driver, combiner_devclass, 0, 0);


Property changes on: trunk/sys/arm/samsung/exynos/exynos5_combiner.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/samsung/exynos/exynos5_combiner.h
===================================================================
--- trunk/sys/arm/samsung/exynos/exynos5_combiner.h	                        (rev 0)
+++ trunk/sys/arm/samsung/exynos/exynos5_combiner.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,30 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014 Ruslan Bukin <br at bsdpad.com>
+ * 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: stable/10/sys/arm/samsung/exynos/exynos5_combiner.h 266341 2014-05-17 19:37:04Z ian $
+ */
+
+void combiner_setup_intr(char *source_name, void (*ih)(void *), void *ih_user);


Property changes on: trunk/sys/arm/samsung/exynos/exynos5_combiner.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/samsung/exynos/exynos5_common.c
===================================================================
--- trunk/sys/arm/samsung/exynos/exynos5_common.c	                        (rev 0)
+++ trunk/sys/arm/samsung/exynos/exynos5_common.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,74 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Ruslan Bukin <br at bsdpad.com>
+ * 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: stable/10/sys/arm/samsung/exynos/exynos5_common.c 266277 2014-05-17 00:53:12Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+
+void
+cpu_reset(void)
+{
+	bus_space_handle_t bsh;
+
+	bus_space_map(fdtbus_bs_tag, 0x10040400, 0x1000, 0, &bsh);
+	bus_space_write_4(fdtbus_bs_tag, bsh, 0, 1);
+
+	while (1);
+}
+
+struct fdt_fixup_entry fdt_fixup_table[] = {
+	{ NULL, NULL }
+};
+
+static int
+fdt_pic_decode_ic(phandle_t node, pcell_t *intr, int *interrupt, int *trig,
+    int *pol)
+{
+
+	if (!fdt_is_compatible(node, "arm,gic"))
+		return (ENXIO);
+
+	*interrupt = fdt32_to_cpu(intr[0]);
+	*trig = INTR_TRIGGER_CONFORM;
+	*pol = INTR_POLARITY_CONFORM;
+	return (0);
+}
+
+fdt_pic_decode_t fdt_pic_table[] = {
+	&fdt_pic_decode_ic,
+	NULL
+};


Property changes on: trunk/sys/arm/samsung/exynos/exynos5_common.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/samsung/exynos/exynos5_common.h
===================================================================
--- trunk/sys/arm/samsung/exynos/exynos5_common.h	                        (rev 0)
+++ trunk/sys/arm/samsung/exynos/exynos5_common.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,41 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014 Ruslan Bukin <br at bsdpad.com>
+ * 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: stable/10/sys/arm/samsung/exynos/exynos5_common.h 266332 2014-05-17 17:54:38Z ian $
+ */
+
+#define	READ4(_sc, _reg)	\
+	bus_space_read_4(_sc->bst, _sc->bsh, _reg)
+#define	WRITE4(_sc, _reg, _val)	\
+	bus_space_write_4(_sc->bst, _sc->bsh, _reg, _val)
+#define	READ2(_sc, _reg)	\
+	bus_space_read_2(_sc->bst, _sc->bsh, _reg)
+#define	WRITE2(_sc, _reg, _val)	\
+	bus_space_write_2(_sc->bst, _sc->bsh, _reg, _val)
+#define	READ1(_sc, _reg)	\
+	bus_space_read_1(_sc->bst, _sc->bsh, _reg)
+#define	WRITE1(_sc, _reg, _val)	\
+	bus_space_write_1(_sc->bst, _sc->bsh, _reg, _val)


Property changes on: trunk/sys/arm/samsung/exynos/exynos5_common.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/samsung/exynos/exynos5_ehci.c
===================================================================
--- trunk/sys/arm/samsung/exynos/exynos5_ehci.c	                        (rev 0)
+++ trunk/sys/arm/samsung/exynos/exynos5_ehci.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,371 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Ruslan Bukin <br at bsdpad.com>
+ * 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: stable/10/sys/arm/samsung/exynos/exynos5_ehci.c 278278 2015-02-05 20:03:02Z hselasky $");
+
+#include "opt_bus.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/condvar.h>
+#include <sys/rman.h>
+#include <sys/gpio.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <dev/usb/usb.h>
+#include <dev/usb/usbdi.h>
+#include <dev/usb/usb_busdma.h>
+#include <dev/usb/usb_process.h>
+#include <dev/usb/usb_controller.h>
+#include <dev/usb/usb_bus.h>
+#include <dev/usb/controller/ehci.h>
+#include <dev/usb/controller/ehcireg.h>
+
+#include <dev/fdt/fdt_common.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+
+#include "gpio_if.h"
+
+#include "opt_platform.h"
+
+/* GPIO control */
+#define	GPIO_OUTPUT	1
+#define	GPIO_INPUT	0
+#define	PIN_USB		161
+
+/* PWR control */
+#define	EXYNOS5_PWR_USBHOST_PHY		0x708
+#define	PHY_POWER_ON			1
+#define	PHY_POWER_OFF			0
+
+/* SYSREG */
+#define	EXYNOS5_SYSREG_USB2_PHY	0x0
+#define	USB2_MODE_HOST		0x1
+
+/* USB HOST */
+#define	HOST_CTRL_CLK_24MHZ	(5 << 16)
+#define	HOST_CTRL_CLK_MASK	(7 << 16)
+#define	HOST_CTRL_SIDDQ		(1 << 6)
+#define	HOST_CTRL_SLEEP		(1 << 5)
+#define	HOST_CTRL_SUSPEND	(1 << 4)
+#define	HOST_CTRL_RESET_LINK	(1 << 1)
+#define	HOST_CTRL_RESET_PHY	(1 << 0)
+#define	HOST_CTRL_RESET_PHY_ALL	(1U << 31)
+
+/* Forward declarations */
+static int	exynos_ehci_attach(device_t dev);
+static int	exynos_ehci_detach(device_t dev);
+static int	exynos_ehci_probe(device_t dev);
+
+struct exynos_ehci_softc {
+	device_t		dev;
+	ehci_softc_t		base;
+	struct resource		*res[5];
+	bus_space_tag_t		host_bst;
+	bus_space_tag_t		pwr_bst;
+	bus_space_tag_t		sysreg_bst;
+	bus_space_handle_t	host_bsh;
+	bus_space_handle_t	pwr_bsh;
+	bus_space_handle_t	sysreg_bsh;
+
+};
+
+static struct resource_spec exynos_ehci_spec[] = {
+	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
+	{ SYS_RES_MEMORY,	1,	RF_ACTIVE },
+	{ SYS_RES_MEMORY,	2,	RF_ACTIVE },
+	{ SYS_RES_MEMORY,	3,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		0,	RF_ACTIVE },
+	{ -1, 0 }
+};
+
+static device_method_t ehci_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe, exynos_ehci_probe),
+	DEVMETHOD(device_attach, exynos_ehci_attach),
+	DEVMETHOD(device_detach, exynos_ehci_detach),
+	DEVMETHOD(device_suspend, bus_generic_suspend),
+	DEVMETHOD(device_resume, bus_generic_resume),
+	DEVMETHOD(device_shutdown, bus_generic_shutdown),
+
+	/* Bus interface */
+	DEVMETHOD(bus_print_child, bus_generic_print_child),
+
+	{ 0, 0 }
+};
+
+/* kobj_class definition */
+static driver_t ehci_driver = {
+	"ehci",
+	ehci_methods,
+	sizeof(ehci_softc_t)
+};
+
+static devclass_t ehci_devclass;
+
+DRIVER_MODULE(ehci, simplebus, ehci_driver, ehci_devclass, 0, 0);
+MODULE_DEPEND(ehci, usb, 1, 1, 1);
+
+/*
+ * Public methods
+ */
+static int
+exynos_ehci_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (ofw_bus_is_compatible(dev, "exynos,usb-ehci") == 0)
+		return (ENXIO);
+
+	device_set_desc(dev, "Exynos integrated USB controller");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+gpio_ctrl(struct exynos_ehci_softc *esc, int dir, int power)
+{
+	device_t gpio_dev;
+
+	/* Get the GPIO device, we need this to give power to USB */
+	gpio_dev = devclass_get_device(devclass_find("gpio"), 0);
+	if (gpio_dev == NULL) {
+		device_printf(esc->dev, "cant find gpio_dev\n");
+		return (1);
+	}
+
+	if (power)
+		GPIO_PIN_SET(gpio_dev, PIN_USB, GPIO_PIN_HIGH);
+	else
+		GPIO_PIN_SET(gpio_dev, PIN_USB, GPIO_PIN_LOW);
+
+	if (dir)
+		GPIO_PIN_SETFLAGS(gpio_dev, PIN_USB, GPIO_PIN_OUTPUT);
+	else
+		GPIO_PIN_SETFLAGS(gpio_dev, PIN_USB, GPIO_PIN_INPUT);
+
+	return (0);
+}
+
+static int
+phy_init(struct exynos_ehci_softc *esc)
+{
+	int reg;
+
+	gpio_ctrl(esc, GPIO_INPUT, 1);
+
+	/* set USB HOST mode */
+	bus_space_write_4(esc->sysreg_bst, esc->sysreg_bsh,
+	    EXYNOS5_SYSREG_USB2_PHY, USB2_MODE_HOST);
+
+	/* Power ON phy */
+	bus_space_write_4(esc->pwr_bst, esc->pwr_bsh,
+	    EXYNOS5_PWR_USBHOST_PHY, PHY_POWER_ON);
+
+	reg = bus_space_read_4(esc->host_bst, esc->host_bsh, 0x0);
+	reg &= ~(HOST_CTRL_CLK_MASK |
+	    HOST_CTRL_RESET_PHY |
+	    HOST_CTRL_RESET_PHY_ALL |
+	    HOST_CTRL_SIDDQ |
+	    HOST_CTRL_SUSPEND |
+	    HOST_CTRL_SLEEP);
+
+	reg |= (HOST_CTRL_CLK_24MHZ |
+	    HOST_CTRL_RESET_LINK);
+	bus_space_write_4(esc->host_bst, esc->host_bsh, 0x0, reg);
+
+	DELAY(10);
+
+	reg = bus_space_read_4(esc->host_bst, esc->host_bsh, 0x0);
+	reg &= ~(HOST_CTRL_RESET_LINK);
+	bus_space_write_4(esc->host_bst, esc->host_bsh, 0x0, reg);
+
+	gpio_ctrl(esc, GPIO_OUTPUT, 1);
+
+	return (0);
+}
+
+static int
+exynos_ehci_attach(device_t dev)
+{
+	struct exynos_ehci_softc *esc;
+	ehci_softc_t *sc;
+	bus_space_handle_t bsh;
+	int err;
+
+	esc = device_get_softc(dev);
+	esc->dev = dev;
+	sc = &esc->base;
+	sc->sc_bus.parent = dev;
+	sc->sc_bus.devices = sc->sc_devices;
+	sc->sc_bus.devices_max = EHCI_MAX_DEVICES;
+	sc->sc_bus.dma_bits = 32;
+
+	if (bus_alloc_resources(dev, exynos_ehci_spec, esc->res)) {
+		device_printf(dev, "could not allocate resources\n");
+		return (ENXIO);
+	}
+
+	/* EHCI registers */
+	sc->sc_io_tag = rman_get_bustag(esc->res[0]);
+	bsh = rman_get_bushandle(esc->res[0]);
+	sc->sc_io_size = rman_get_size(esc->res[0]);
+
+	/* EHCI HOST ctrl registers */
+	esc->host_bst = rman_get_bustag(esc->res[1]);
+	esc->host_bsh = rman_get_bushandle(esc->res[1]);
+
+	/* PWR registers */
+	esc->pwr_bst = rman_get_bustag(esc->res[2]);
+	esc->pwr_bsh = rman_get_bushandle(esc->res[2]);
+
+	/* SYSREG */
+	esc->sysreg_bst = rman_get_bustag(esc->res[3]);
+	esc->sysreg_bsh = rman_get_bushandle(esc->res[3]);
+
+	/* get all DMA memory */
+	if (usb_bus_mem_alloc_all(&sc->sc_bus, USB_GET_DMA_TAG(dev),
+		&ehci_iterate_hw_softc))
+		return (ENXIO);
+
+	/*
+	 * Set handle to USB related registers subregion used by
+	 * generic EHCI driver.
+	 */
+	err = bus_space_subregion(sc->sc_io_tag, bsh, 0x0,
+	    sc->sc_io_size, &sc->sc_io_hdl);
+	if (err != 0)
+		return (ENXIO);
+
+	phy_init(esc);
+
+	/* Setup interrupt handler */
+	err = bus_setup_intr(dev, esc->res[4], INTR_TYPE_BIO | INTR_MPSAFE,
+	    NULL, (driver_intr_t *)ehci_interrupt, sc,
+	    &sc->sc_intr_hdl);
+	if (err) {
+		device_printf(dev, "Could not setup irq, "
+		    "%d\n", err);
+		return (1);
+	}
+
+	/* Add USB device */
+	sc->sc_bus.bdev = device_add_child(dev, "usbus", -1);
+	if (!sc->sc_bus.bdev) {
+		device_printf(dev, "Could not add USB device\n");
+		err = bus_teardown_intr(dev, esc->res[4],
+		    sc->sc_intr_hdl);
+		if (err)
+			device_printf(dev, "Could not tear down irq,"
+			    " %d\n", err);
+		return (1);
+	}
+	device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
+
+	strlcpy(sc->sc_vendor, "Samsung", sizeof(sc->sc_vendor));
+
+	err = ehci_init(sc);
+	if (!err) {
+		sc->sc_flags |= EHCI_SCFLG_DONEINIT;
+		err = device_probe_and_attach(sc->sc_bus.bdev);
+	} else {
+		device_printf(dev, "USB init failed err=%d\n", err);
+
+		device_delete_child(dev, sc->sc_bus.bdev);
+		sc->sc_bus.bdev = NULL;
+
+		err = bus_teardown_intr(dev, esc->res[4],
+		    sc->sc_intr_hdl);
+		if (err)
+			device_printf(dev, "Could not tear down irq,"
+			    " %d\n", err);
+		return (1);
+	}
+	return (0);
+}
+
+static int
+exynos_ehci_detach(device_t dev)
+{
+	struct exynos_ehci_softc *esc;
+	ehci_softc_t *sc;
+	int err;
+
+	esc = device_get_softc(dev);
+	sc = &esc->base;
+
+	if (sc->sc_flags & EHCI_SCFLG_DONEINIT)
+		return (0);
+
+	/*
+	 * only call ehci_detach() after ehci_init()
+	 */
+	if (sc->sc_flags & EHCI_SCFLG_DONEINIT) {
+		ehci_detach(sc);
+		sc->sc_flags &= ~EHCI_SCFLG_DONEINIT;
+	}
+
+	/*
+	 * Disable interrupts that might have been switched on in
+	 * ehci_init.
+	 */
+	if (sc->sc_io_tag && sc->sc_io_hdl)
+		bus_space_write_4(sc->sc_io_tag, sc->sc_io_hdl,
+		    EHCI_USBINTR, 0);
+
+	if (esc->res[4] && sc->sc_intr_hdl) {
+		err = bus_teardown_intr(dev, esc->res[4],
+		    sc->sc_intr_hdl);
+		if (err) {
+			device_printf(dev, "Could not tear down irq,"
+			    " %d\n", err);
+			return (err);
+		}
+		sc->sc_intr_hdl = NULL;
+	}
+
+	if (sc->sc_bus.bdev) {
+		device_delete_child(dev, sc->sc_bus.bdev);
+		sc->sc_bus.bdev = NULL;
+	}
+
+	/* During module unload there are lots of children leftover */
+	device_delete_children(dev);
+
+	bus_release_resources(dev, exynos_ehci_spec, esc->res);
+
+	return (0);
+}


Property changes on: trunk/sys/arm/samsung/exynos/exynos5_ehci.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/samsung/exynos/exynos5_fimd.c
===================================================================
--- trunk/sys/arm/samsung/exynos/exynos5_fimd.c	                        (rev 0)
+++ trunk/sys/arm/samsung/exynos/exynos5_fimd.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,414 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014 Ruslan Bukin <br at bsdpad.com>
+ * 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.
+ */
+
+/*
+ * Samsung Exynos 5 Display Controller
+ * Chapter 15, Exynos 5 Dual User's Manual Public Rev 1.00
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/samsung/exynos/exynos5_fimd.c 266358 2014-05-17 21:26:33Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/timeet.h>
+#include <sys/timetc.h>
+#include <sys/watchdog.h>
+#include <sys/fbio.h>
+#include <sys/consio.h>
+#include <sys/eventhandler.h>
+#include <sys/gpio.h>
+
+#include <vm/vm.h>
+#include <vm/vm_extern.h>
+#include <vm/vm_kern.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <dev/vt/vt.h>
+#include <dev/vt/colors/vt_termcolors.h>
+
+#include <arm/samsung/exynos/exynos5_common.h>
+
+#include "gpio_if.h"
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#include "fb_if.h"
+
+#define	FIMDBYPASS_DISP1	(1 << 15)
+
+#define	VIDCON0		(0x0)
+#define	VIDCON0_ENVID	(1 << 1)
+#define	VIDCON0_ENVID_F	(1 << 0)
+#define	CLKVAL_F	0xb
+#define	CLKVAL_F_OFFSET	6
+
+#define	WINCON0		0x0020
+#define	WINCON1		0x0024
+#define	WINCON2		0x0028
+#define	WINCON3		0x002C
+#define	WINCON4		0x0030
+
+#define	ENLOCAL_F			(1 << 22)
+#define	BPPMODE_F_RGB_16BIT_565		0x5
+#define	BPPMODE_F_OFFSET		2
+#define	ENWIN_F_ENABLE			(1 << 0)
+#define	HALF_WORD_SWAP_EN		(1 << 16)
+
+#define	SHADOWCON	0x0034
+#define	CHANNEL0_EN	(1 << 0)
+
+#define	VIDOSD0A	0x0040
+#define	VIDOSD0B	0x0044
+#define	VIDOSD0C	0x0048
+
+#define	VIDW00ADD0B0	0x00A0
+#define	VIDW00ADD0B1	0x00A4
+#define	VIDW00ADD0B2	0x20A0
+#define	VIDW00ADD1B0	0x00D0
+#define	VIDW00ADD1B1	0x00D4
+#define	VIDW00ADD1B2	0x20D0
+
+#define	VIDW00ADD2	0x0100
+#define	VIDW01ADD2	0x0104
+#define	VIDW02ADD2	0x0108
+#define	VIDW03ADD2	0x010C
+#define	VIDW04ADD2	0x0110
+
+#define	VIDCON1		(0x04)
+#define	VIDTCON0	0x0010
+#define	VIDTCON1	0x0014
+#define	VIDTCON2	0x0018
+#define	VIDTCON3	0x001C
+
+#define	VIDINTCON0	0x0130
+#define	VIDINTCON1	0x0134
+
+#define	VSYNC_PULSE_WIDTH_VAL		0x3
+#define	VSYNC_PULSE_WIDTH_OFFSET	0
+#define	V_FRONT_PORCH_VAL		0x3
+#define	V_FRONT_PORCH_OFFSET		8
+#define	V_BACK_PORCH_VAL		0x3
+#define	V_BACK_PORCH_OFFSET		16
+
+#define	HSYNC_PULSE_WIDTH_VAL		0x3
+#define	HSYNC_PULSE_WIDTH_OFFSET	0
+#define	H_FRONT_PORCH_VAL		0x3
+#define	H_FRONT_PORCH_OFFSET		8
+#define	H_BACK_PORCH_VAL		0x3
+#define	H_BACK_PORCH_OFFSET		16
+
+#define	HOZVAL_OFFSET		0
+#define	LINEVAL_OFFSET		11
+
+#define	OSD_RIGHTBOTX_F_OFFSET		11
+#define	OSD_RIGHTBOTY_F_OFFSET		0
+
+#define	DPCLKCON	0x27c
+#define	DPCLKCON_EN	(1 << 1)
+
+#define	DREAD4(_sc, _reg)         \
+	bus_space_read_4(_sc->bst_disp, _sc->bsh_disp, _reg)
+#define	DWRITE4(_sc, _reg, _val)  \
+	bus_space_write_4(_sc->bst_disp, _sc->bsh_disp, _reg, _val)
+
+struct panel_info {
+	uint32_t	width;
+	uint32_t	height;
+	uint32_t	h_back_porch;
+	uint32_t	h_pulse_width;
+	uint32_t	h_front_porch;
+	uint32_t	v_back_porch;
+	uint32_t	v_pulse_width;
+	uint32_t	v_front_porch;
+	uint32_t	clk_div;
+	uint32_t	backlight_pin;
+	uint32_t	fixvclk;
+	uint32_t	ivclk;
+	uint32_t	clkval_f;
+};
+
+struct fimd_softc {
+	struct resource		*res[3];
+	bus_space_tag_t		bst;
+	bus_space_handle_t	bsh;
+	bus_space_tag_t		bst_disp;
+	bus_space_handle_t	bsh_disp;
+	bus_space_tag_t		bst_sysreg;
+	bus_space_handle_t	bsh_sysreg;
+
+	void			*ih;
+	device_t		dev;
+	device_t		sc_fbd;		/* fbd child */
+	struct fb_info		sc_info;
+	struct panel_info	*panel;
+};
+
+static struct resource_spec fimd_spec[] = {
+	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },	/* Timer registers */
+	{ SYS_RES_MEMORY,	1,	RF_ACTIVE },	/* FIMD */
+	{ SYS_RES_MEMORY,	2,	RF_ACTIVE },	/* DISP */
+	{ -1, 0 }
+};
+
+static int
+fimd_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "exynos,fimd"))
+		return (ENXIO);
+
+	device_set_desc(dev, "Samsung Exynos 5 Display Controller");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+get_panel_info(struct fimd_softc *sc, struct panel_info *panel)
+{
+	phandle_t node;
+	pcell_t dts_value[3];
+	int len;
+
+	if ((node = ofw_bus_get_node(sc->dev)) == -1)
+		return (ENXIO);
+
+	/* panel size */
+	if ((len = OF_getproplen(node, "panel-size")) <= 0)
+		return (ENXIO);
+	OF_getprop(node, "panel-size", &dts_value, len);
+	panel->width = fdt32_to_cpu(dts_value[0]);
+	panel->height = fdt32_to_cpu(dts_value[1]);
+
+	/* hsync */
+	if ((len = OF_getproplen(node, "panel-hsync")) <= 0)
+		return (ENXIO);
+	OF_getprop(node, "panel-hsync", &dts_value, len);
+	panel->h_back_porch = fdt32_to_cpu(dts_value[0]);
+	panel->h_pulse_width = fdt32_to_cpu(dts_value[1]);
+	panel->h_front_porch = fdt32_to_cpu(dts_value[2]);
+
+	/* vsync */
+	if ((len = OF_getproplen(node, "panel-vsync")) <= 0)
+		return (ENXIO);
+	OF_getprop(node, "panel-vsync", &dts_value, len);
+	panel->v_back_porch = fdt32_to_cpu(dts_value[0]);
+	panel->v_pulse_width = fdt32_to_cpu(dts_value[1]);
+	panel->v_front_porch = fdt32_to_cpu(dts_value[2]);
+
+	/* clk divider */
+	if ((len = OF_getproplen(node, "panel-clk-div")) <= 0)
+		return (ENXIO);
+	OF_getprop(node, "panel-clk-div", &dts_value, len);
+	panel->clk_div = fdt32_to_cpu(dts_value[0]);
+
+	/* backlight pin */
+	if ((len = OF_getproplen(node, "panel-backlight-pin")) <= 0)
+		return (ENXIO);
+	OF_getprop(node, "panel-backlight-pin", &dts_value, len);
+	panel->backlight_pin = fdt32_to_cpu(dts_value[0]);
+
+	return (0);
+}
+
+static int
+fimd_init(struct fimd_softc *sc)
+{
+	struct panel_info *panel;
+	int reg;
+
+	panel = sc->panel;
+
+	/* fb_init */
+	reg = panel->ivclk | panel->fixvclk;
+	DWRITE4(sc,VIDCON1,reg);
+
+	reg = (VIDCON0_ENVID | VIDCON0_ENVID_F);
+	reg |= (panel->clkval_f << CLKVAL_F_OFFSET);
+	WRITE4(sc,VIDCON0,reg);
+
+	reg = (panel->v_pulse_width << VSYNC_PULSE_WIDTH_OFFSET);
+	reg |= (panel->v_front_porch << V_FRONT_PORCH_OFFSET);
+	reg |= (panel->v_back_porch << V_BACK_PORCH_OFFSET);
+	DWRITE4(sc,VIDTCON0,reg);
+
+	reg = (panel->h_pulse_width << HSYNC_PULSE_WIDTH_OFFSET);
+	reg |= (panel->h_front_porch << H_FRONT_PORCH_OFFSET);
+	reg |= (panel->h_back_porch << H_BACK_PORCH_OFFSET);
+	DWRITE4(sc,VIDTCON1,reg);
+
+	reg = ((panel->width - 1) << HOZVAL_OFFSET);
+	reg |= ((panel->height - 1) << LINEVAL_OFFSET);
+	DWRITE4(sc,VIDTCON2,reg);
+
+	reg = sc->sc_info.fb_pbase;
+	WRITE4(sc, VIDW00ADD0B0, reg);
+	reg += (sc->sc_info.fb_stride * (sc->sc_info.fb_height + 1));
+	WRITE4(sc, VIDW00ADD1B0, reg);
+	WRITE4(sc, VIDW00ADD2, sc->sc_info.fb_stride);
+
+	reg = ((panel->width - 1) << OSD_RIGHTBOTX_F_OFFSET);
+	reg |= ((panel->height - 1) << OSD_RIGHTBOTY_F_OFFSET);
+	WRITE4(sc,VIDOSD0B,reg);
+
+	reg = panel->width * panel->height;
+	WRITE4(sc,VIDOSD0C,reg);
+
+	reg = READ4(sc, SHADOWCON);
+	reg |= CHANNEL0_EN;
+	reg &= ~(1 << 5); /* disable local path for channel0 */
+	WRITE4(sc,SHADOWCON,reg);
+
+	reg = BPPMODE_F_RGB_16BIT_565 << BPPMODE_F_OFFSET;
+	reg |= ENWIN_F_ENABLE | HALF_WORD_SWAP_EN; /* Note: swap=0 when ENLOCAL==1 */
+	reg &= ~ENLOCAL_F; /* use DMA */
+	WRITE4(sc,WINCON0,reg);
+
+	/* Enable DisplayPort Clk */
+	WRITE4(sc, DPCLKCON, DPCLKCON_EN);
+
+	return (0);
+}
+
+static int
+fimd_attach(device_t dev)
+{
+	struct panel_info panel;
+	struct fimd_softc *sc;
+	device_t gpio_dev;
+	int reg;
+
+	sc = device_get_softc(dev);
+	sc->dev = dev;
+
+	if (bus_alloc_resources(dev, fimd_spec, sc->res)) {
+		device_printf(dev, "could not allocate resources\n");
+		return (ENXIO);
+	}
+
+	/* Memory interface */
+	sc->bst = rman_get_bustag(sc->res[0]);
+	sc->bsh = rman_get_bushandle(sc->res[0]);
+	sc->bst_disp = rman_get_bustag(sc->res[1]);
+	sc->bsh_disp = rman_get_bushandle(sc->res[1]);
+	sc->bst_sysreg = rman_get_bustag(sc->res[2]);
+	sc->bsh_sysreg = rman_get_bushandle(sc->res[2]);
+
+	if (get_panel_info(sc, &panel)) {
+		device_printf(dev, "Can't get panel info\n");
+		return (ENXIO);
+	}
+
+	panel.fixvclk = 0;
+	panel.ivclk = 0;
+	panel.clkval_f = 2;
+
+	sc->panel = &panel;
+
+	/* Get the GPIO device, we need this to give power to USB */
+	gpio_dev = devclass_get_device(devclass_find("gpio"), 0);
+	if (gpio_dev == NULL) {
+		/* TODO */
+	}
+
+	reg = bus_space_read_4(sc->bst_sysreg, sc->bsh_sysreg, 0x214);
+	reg |= FIMDBYPASS_DISP1;
+	bus_space_write_4(sc->bst_sysreg, sc->bsh_sysreg, 0x214, reg);
+
+	sc->sc_info.fb_width = panel.width;
+	sc->sc_info.fb_height = panel.height;
+	sc->sc_info.fb_stride = sc->sc_info.fb_width * 2;
+	sc->sc_info.fb_bpp = sc->sc_info.fb_depth = 16;
+	sc->sc_info.fb_size = sc->sc_info.fb_height * sc->sc_info.fb_stride;
+	sc->sc_info.fb_vbase = (intptr_t)kmem_alloc_contig(kernel_arena,
+	    sc->sc_info.fb_size, M_ZERO, 0, ~0, PAGE_SIZE, 0, VM_MEMATTR_UNCACHEABLE);
+	sc->sc_info.fb_pbase = (intptr_t)vtophys(sc->sc_info.fb_vbase);
+
+#if 0
+	printf("%dx%d [%d]\n", sc->sc_info.fb_width, sc->sc_info.fb_height,
+	    sc->sc_info.fb_stride);
+	printf("pbase == 0x%08x\n", sc->sc_info.fb_pbase);
+#endif
+
+	memset((int8_t *)sc->sc_info.fb_vbase, 0x0, sc->sc_info.fb_size);
+
+	fimd_init(sc);
+
+	sc->sc_info.fb_name = device_get_nameunit(dev);
+
+	/* Ask newbus to attach framebuffer device to me. */
+	sc->sc_fbd = device_add_child(dev, "fbd", device_get_unit(dev));
+	if (sc->sc_fbd == NULL)
+		device_printf(dev, "Can't attach fbd device\n");
+
+	if (device_probe_and_attach(sc->sc_fbd) != 0) {
+		device_printf(sc->dev, "Failed to attach fbd device\n");
+	}
+
+	return (0);
+}
+
+static struct fb_info *
+fimd_fb_getinfo(device_t dev)
+{
+	struct fimd_softc *sc = device_get_softc(dev);
+
+	return (&sc->sc_info);
+}
+
+static device_method_t fimd_methods[] = {
+	DEVMETHOD(device_probe,		fimd_probe),
+	DEVMETHOD(device_attach,	fimd_attach),
+
+	/* Framebuffer service methods */
+	DEVMETHOD(fb_getinfo,		fimd_fb_getinfo),
+	{ 0, 0 }
+};
+
+static driver_t fimd_driver = {
+	"fb",
+	fimd_methods,
+	sizeof(struct fimd_softc),
+};
+
+static devclass_t fimd_devclass;
+
+DRIVER_MODULE(fb, simplebus, fimd_driver, fimd_devclass, 0, 0);


Property changes on: trunk/sys/arm/samsung/exynos/exynos5_fimd.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/samsung/exynos/exynos5_i2c.c
===================================================================
--- trunk/sys/arm/samsung/exynos/exynos5_i2c.c	                        (rev 0)
+++ trunk/sys/arm/samsung/exynos/exynos5_i2c.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,477 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014 Ruslan Bukin <br at bsdpad.com>
+ * 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.
+ */
+
+/*
+ * Samsung Exynos 5 Inter-Integrated Circuit (I2C)
+ * Chapter 13, Exynos 5 Dual User's Manual Public Rev 1.00
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/samsung/exynos/exynos5_i2c.c 289666 2015-10-20 21:20:34Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/timeet.h>
+#include <sys/timetc.h>
+
+#include <dev/iicbus/iiconf.h>
+#include <dev/iicbus/iicbus.h>
+
+#include "iicbus_if.h"
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#include <arm/samsung/exynos/exynos5_common.h>
+
+#define	I2CCON		0x00	/* Control register */
+#define	 ACKGEN		(1 << 7) /* Acknowledge Enable */
+/*
+ * Source Clock of I2C-bus Transmit Clock Prescaler
+ *
+ * 0 = I2CCLK = fPCLK/16
+ * 1 = I2CCLK = fPCLK/512
+ */
+#define	 I2CCLK		(1 << 6)
+#define	 IRQ_EN		(1 << 5)	/* Tx/Rx Interrupt Enable/Disable */
+#define	 IPEND		(1 << 4)	/* Tx/Rx Interrupt Pending Flag */
+#define	 CLKVAL_M	0xf		/* Transmit Clock Prescaler Mask */
+#define	 CLKVAL_S	0
+#define	I2CSTAT		0x04		/* Control/status register */
+#define	 I2CMODE_M	0x3		/* Master/Slave Tx/Rx Mode Select */
+#define	 I2CMODE_S	6
+#define	 I2CMODE_SR	0x0		/* Slave Receive Mode */
+#define	 I2CMODE_ST	0x1		/* Slave Transmit Mode */
+#define	 I2CMODE_MR	0x2		/* Master Receive Mode */
+#define	 I2CMODE_MT	0x3		/* Master Transmit Mode */
+#define	 I2CSTAT_BSY	(1 << 5)	/* Busy Signal Status bit */
+#define	 I2C_START_STOP	(1 << 5)	/* Busy Signal Status bit */
+#define	 RXTX_EN	(1 << 4)	/* Data Output Enable/Disable */
+#define	 ARBST		(1 << 3)	/* Arbitration status flag */
+#define	 ADDAS		(1 << 2)	/* Address-as-slave Status Flag */
+#define	 ADDZERO	(1 << 1)	/* Address Zero Status Flag */
+#define	 ACKRECVD	(1 << 0)	/* Last-received Bit Status Flag */
+#define	I2CADD		0x08		/* Address register */
+#define	I2CDS		0x0C		/* Transmit/receive data shift */
+#define	I2CLC		0x10		/* Multi-master line control */
+#define	 FILTER_EN	(1 << 2)	/* Filter Enable bit */
+#define	 SDAOUT_DELAY_M	0x3		/* SDA Line Delay Length */
+#define	 SDAOUT_DELAY_S	0
+
+#ifdef DEBUG
+#define DPRINTF(fmt, args...) \
+	printf(fmt, ##args)
+#else
+#define DPRINTF(fmt, args...)
+#endif
+
+static int i2c_start(device_t, u_char, int);
+static int i2c_stop(device_t);
+static int i2c_reset(device_t, u_char, u_char, u_char *);
+static int i2c_read(device_t, char *, int, int *, int, int);
+static int i2c_write(device_t, const char *, int, int *, int);
+
+struct i2c_softc {
+	struct resource		*res[2];
+	bus_space_tag_t		bst;
+	bus_space_handle_t	bsh;
+	device_t		dev;
+	device_t		iicbus;
+	struct mtx		mutex;
+	void			*ih;
+	int			intr;
+};
+
+static struct resource_spec i2c_spec[] = {
+	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		0,	RF_ACTIVE },
+	{ -1, 0 }
+};
+
+static int
+i2c_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "exynos,i2c"))
+		return (ENXIO);
+
+	device_set_desc(dev, "Samsung Exynos 5 I2C controller");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+clear_ipend(struct i2c_softc *sc)
+{
+	int reg;
+
+	reg = READ1(sc, I2CCON);
+	reg &= ~(IPEND);
+	WRITE1(sc, I2CCON, reg);
+
+	return (0);
+}
+
+static int
+i2c_attach(device_t dev)
+{
+	struct i2c_softc *sc;
+	int reg;
+
+	sc = device_get_softc(dev);
+	sc->dev = dev;
+
+	mtx_init(&sc->mutex, device_get_nameunit(dev), "I2C", MTX_DEF);
+
+	if (bus_alloc_resources(dev, i2c_spec, sc->res)) {
+		device_printf(dev, "could not allocate resources\n");
+		return (ENXIO);
+	}
+
+	/* Memory interface */
+	sc->bst = rman_get_bustag(sc->res[0]);
+	sc->bsh = rman_get_bushandle(sc->res[0]);
+
+	sc->iicbus = device_add_child(dev, "iicbus", -1);
+	if (sc->iicbus == NULL) {
+		device_printf(dev, "could not add iicbus child");
+		mtx_destroy(&sc->mutex);
+		return (ENXIO);
+	}
+
+	WRITE1(sc, I2CSTAT, 0);
+	WRITE1(sc, I2CADD, 0x00);
+
+	/* Mode */
+	reg = (RXTX_EN);
+        reg |= (I2CMODE_MT << I2CMODE_S);
+	WRITE1(sc, I2CSTAT, reg);
+
+	bus_generic_attach(dev);
+
+	return (0);
+}
+
+static int
+wait_for_iif(struct i2c_softc *sc)
+{
+	int retry;
+	int reg;
+
+	retry = 1000;
+	while (retry --) {
+		reg = READ1(sc, I2CCON);
+		if (reg & IPEND) {
+			return (IIC_NOERR);
+		}
+		DELAY(50);
+	}
+
+	return (IIC_ETIMEOUT);
+}
+
+static int
+wait_for_nibb(struct i2c_softc *sc)
+{
+	int retry;
+
+	retry = 1000;
+	while (retry --) {
+		if ((READ1(sc, I2CSTAT) & I2CSTAT_BSY) == 0)
+			return (IIC_NOERR);
+		DELAY(10);
+	}
+
+	return (IIC_ETIMEOUT);
+}
+
+static int
+is_ack(struct i2c_softc *sc)
+{
+	int stat;
+
+	stat = READ1(sc, I2CSTAT);
+	if (!(stat & 1)) {
+		/* ACK received */
+		return (1);
+	}
+
+	return (0);
+}
+
+static int
+i2c_start(device_t dev, u_char slave, int timeout)
+{
+	struct i2c_softc *sc;
+	int error;
+	int reg;
+
+	sc = device_get_softc(dev);
+
+	DPRINTF("i2c start\n");
+
+	mtx_lock(&sc->mutex);
+
+#if 0
+	DPRINTF("I2CCON == 0x%08x\n", READ1(sc, I2CCON));
+	DPRINTF("I2CSTAT == 0x%08x\n", READ1(sc, I2CSTAT));
+#endif
+
+	if (slave & 1) {
+		slave &= ~(1);
+		slave <<= 1;
+		slave |= 1;
+	} else {
+		slave <<= 1;
+	}
+
+	error = wait_for_nibb(sc);
+	if (error) {
+		mtx_unlock(&sc->mutex);
+		DPRINTF("cant i2c start: IIC_EBUSERR\n");
+		return (IIC_EBUSERR);
+	}
+
+	reg = READ1(sc, I2CCON);
+	reg |= (IRQ_EN | ACKGEN);
+	WRITE1(sc, I2CCON, reg);
+
+	WRITE1(sc, I2CDS, slave);
+	DELAY(50);
+
+	reg = (RXTX_EN);
+	reg |= I2C_START_STOP;
+	reg |= (I2CMODE_MT << I2CMODE_S);
+	WRITE1(sc, I2CSTAT, reg);
+
+	error = wait_for_iif(sc);
+	if (error) {
+		DPRINTF("cant i2c start: iif error\n");
+
+		mtx_unlock(&sc->mutex);
+		return (error);
+	}
+
+	if (!is_ack(sc)) {
+		DPRINTF("cant i2c start: no ack\n");
+
+		mtx_unlock(&sc->mutex);
+		return (IIC_ENOACK);
+	};
+
+	mtx_unlock(&sc->mutex);
+	return (IIC_NOERR);
+}
+
+static int
+i2c_stop(device_t dev)
+{
+	struct i2c_softc *sc;
+	int reg;
+	int error;
+
+	sc = device_get_softc(dev);
+
+	DPRINTF("i2c stop\n");
+
+	mtx_lock(&sc->mutex);
+
+	reg = READ1(sc, I2CSTAT);
+	int mode = (reg >> I2CMODE_S) & I2CMODE_M;
+
+	reg = (RXTX_EN);
+	reg |= (mode << I2CMODE_S);
+	WRITE1(sc, I2CSTAT, reg);
+
+	clear_ipend(sc);
+
+	error = wait_for_nibb(sc);
+	if (error) {
+		DPRINTF("cant i2c stop: nibb error\n");
+		return (error);
+	}
+
+	mtx_unlock(&sc->mutex);
+	return (IIC_NOERR);
+}
+
+static int
+i2c_reset(device_t dev, u_char speed, u_char addr, u_char *oldadr)
+{
+	struct i2c_softc *sc;
+
+	sc = device_get_softc(dev);
+
+	DPRINTF("i2c reset\n");
+
+	mtx_lock(&sc->mutex);
+
+	/* TODO */
+
+	mtx_unlock(&sc->mutex);
+
+	return (IIC_NOERR);
+}
+
+static int
+i2c_read(device_t dev, char *buf, int len,
+    int *read, int last, int delay)
+{
+	struct i2c_softc *sc;
+	int error;
+	int reg;
+	uint8_t d;
+
+	sc = device_get_softc(dev);
+
+	DPRINTF("i2c read\n");
+
+	reg = (RXTX_EN);
+	reg |= (I2CMODE_MR << I2CMODE_S);
+	reg |= I2C_START_STOP;
+	WRITE1(sc, I2CSTAT, reg);
+
+	*read = 0;
+	mtx_lock(&sc->mutex);
+
+	/* dummy read */
+	READ1(sc, I2CDS);
+
+	DPRINTF("Read ");
+	while (*read < len) {
+
+		/* Do not ack last read */
+		if (*read == (len - 1)) {
+			reg = READ1(sc, I2CCON);
+			reg &= ~(ACKGEN);
+			WRITE1(sc, I2CCON, reg);
+		};
+
+		clear_ipend(sc);
+
+		error = wait_for_iif(sc);
+		if (error) {
+			DPRINTF("cant i2c read: iif error\n");
+			mtx_unlock(&sc->mutex);
+			return (error);
+		}
+
+		d = READ1(sc, I2CDS);
+		DPRINTF("0x%02x ", d);
+		*buf++ = d;
+		(*read)++;
+	}
+	DPRINTF("\n");
+
+	mtx_unlock(&sc->mutex);
+	return (IIC_NOERR);
+}
+
+static int
+i2c_write(device_t dev, const char *buf, int len, int *sent, int timeout)
+{
+	struct i2c_softc *sc;
+	int error;
+
+	sc = device_get_softc(dev);
+
+	DPRINTF("i2c write\n");
+
+	*sent = 0;
+
+	mtx_lock(&sc->mutex);
+
+	DPRINTF("writing ");
+	while (*sent < len) {
+		uint8_t d = *buf++;
+		DPRINTF("0x%02x ", d);
+
+		WRITE1(sc, I2CDS, d);
+		DELAY(50);
+
+		clear_ipend(sc);
+
+		error = wait_for_iif(sc);
+		if (error) {
+			DPRINTF("cant i2c write: iif error\n");
+			mtx_unlock(&sc->mutex);
+			return (error);
+		}
+
+		if (!is_ack(sc)) {
+			DPRINTF("cant i2c write: no ack\n");
+			mtx_unlock(&sc->mutex);
+			return (IIC_ENOACK);
+		};
+
+		(*sent)++;
+	}
+	DPRINTF("\n");
+
+	mtx_unlock(&sc->mutex);
+	return (IIC_NOERR);
+}
+
+static device_method_t i2c_methods[] = {
+	DEVMETHOD(device_probe,		i2c_probe),
+	DEVMETHOD(device_attach,	i2c_attach),
+
+	DEVMETHOD(iicbus_callback,		iicbus_null_callback),
+	DEVMETHOD(iicbus_start,			i2c_start),
+	DEVMETHOD(iicbus_stop,			i2c_stop),
+	DEVMETHOD(iicbus_reset,			i2c_reset),
+	DEVMETHOD(iicbus_read,			i2c_read),
+	DEVMETHOD(iicbus_write,			i2c_write),
+	DEVMETHOD(iicbus_transfer,		iicbus_transfer_gen),
+
+	{ 0, 0 }
+};
+
+static driver_t i2c_driver = {
+	"i2c",
+	i2c_methods,
+	sizeof(struct i2c_softc),
+};
+
+static devclass_t i2c_devclass;
+
+DRIVER_MODULE(i2c, simplebus, i2c_driver, i2c_devclass, 0, 0);
+DRIVER_MODULE(iicbus, i2c, iicbus_driver, iicbus_devclass, 0, 0);


Property changes on: trunk/sys/arm/samsung/exynos/exynos5_i2c.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/samsung/exynos/exynos5_machdep.c
===================================================================
--- trunk/sys/arm/samsung/exynos/exynos5_machdep.c	                        (rev 0)
+++ trunk/sys/arm/samsung/exynos/exynos5_machdep.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,95 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Ruslan Bukin <br at bsdpad.com>
+ * 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_ddb.h"
+#include "opt_platform.h"
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/samsung/exynos/exynos5_machdep.c 266275 2014-05-16 23:49:40Z ian $");
+
+#define	_ARM32_BUS_DMA_PRIVATE
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+
+#include <vm/vm.h>
+
+#include <machine/armreg.h>
+#include <machine/bus.h>
+#include <machine/devmap.h>
+#include <machine/machdep.h>
+
+#include <dev/fdt/fdt_common.h>
+
+vm_offset_t
+initarm_lastaddr(void)
+{
+
+	return (arm_devmap_lastaddr());
+}
+
+void
+initarm_early_init(void)
+{
+
+}
+
+void
+initarm_gpio_init(void)
+{
+
+}
+
+void
+initarm_late_init(void)
+{
+
+}
+
+int
+initarm_devmap_init(void)
+{
+
+	/* UART */
+	arm_devmap_add_entry(0x12C00000, 0x100000);
+
+	return (0);
+}
+
+struct arm32_dma_range *
+bus_dma_get_range(void)
+{
+
+	return (NULL);
+}
+
+int
+bus_dma_get_range_nb(void)
+{
+
+	return (0);
+}


Property changes on: trunk/sys/arm/samsung/exynos/exynos5_machdep.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/samsung/exynos/exynos5_mct.c
===================================================================
--- trunk/sys/arm/samsung/exynos/exynos5_mct.c	                        (rev 0)
+++ trunk/sys/arm/samsung/exynos/exynos5_mct.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,140 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Ruslan Bukin <br at bsdpad.com>
+ * 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.
+ */
+
+/*
+ * This module just enables Exynos MCT, so ARMv7 Generic Timer will works
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/samsung/exynos/exynos5_mct.c 266332 2014-05-17 17:54:38Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/timeet.h>
+#include <sys/timetc.h>
+#include <sys/watchdog.h>
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+
+#define	MCT_CTRL_START		(1 << 8)
+#define	MCT_CTRL		(0x240)
+#define	MCT_WRITE_STAT		(0x24C)
+
+struct arm_tmr_softc {
+	struct resource		*tmr_res[1];
+	bus_space_tag_t		bst;
+	bus_space_handle_t	bsh;
+};
+
+static struct resource_spec arm_tmr_spec[] = {
+	{ SYS_RES_MEMORY,       0,      RF_ACTIVE },    /* Timer registers */
+	{ -1, 0 }
+};
+
+static int
+arm_tmr_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "exynos,mct"))
+		return (ENXIO);
+
+	device_set_desc(dev, "Exynos MPCore Timer");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+arm_tmr_attach(device_t dev)
+{
+	struct arm_tmr_softc *sc;
+	int reg, i;
+	int mask;
+
+	sc = device_get_softc(dev);
+
+	if (bus_alloc_resources(dev, arm_tmr_spec, sc->tmr_res)) {
+		device_printf(dev, "could not allocate resources\n");
+		return (ENXIO);
+	}
+
+	/* Timer interface */
+	sc->bst = rman_get_bustag(sc->tmr_res[0]);
+	sc->bsh = rman_get_bushandle(sc->tmr_res[0]);
+
+	reg = bus_space_read_4(sc->bst, sc->bsh, MCT_CTRL);
+	reg |= MCT_CTRL_START;
+	bus_space_write_4(sc->bst, sc->bsh, MCT_CTRL, reg);
+
+	mask = (1 << 16);
+
+	/* Wait 10 times until written value is applied */
+	for (i = 0; i < 10; i++) {
+		reg = bus_space_read_4(sc->bst, sc->bsh, MCT_WRITE_STAT);
+		if (reg & mask) {
+			bus_space_write_4(sc->bst, sc->bsh,
+			    MCT_WRITE_STAT, mask);
+			return (0);
+		}
+		cpufunc_nullop();
+	}
+
+	/* NOTREACHED */
+
+	panic("Can't enable timer\n");
+}
+
+static device_method_t arm_tmr_methods[] = {
+	DEVMETHOD(device_probe,		arm_tmr_probe),
+	DEVMETHOD(device_attach,	arm_tmr_attach),
+	{ 0, 0 }
+};
+
+static driver_t arm_tmr_driver = {
+	"mct",
+	arm_tmr_methods,
+	sizeof(struct arm_tmr_softc),
+};
+
+static devclass_t arm_tmr_devclass;
+
+DRIVER_MODULE(mct, simplebus, arm_tmr_driver, arm_tmr_devclass, 0, 0);


Property changes on: trunk/sys/arm/samsung/exynos/exynos5_mct.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/samsung/exynos/exynos5_mp.c
===================================================================
--- trunk/sys/arm/samsung/exynos/exynos5_mp.c	                        (rev 0)
+++ trunk/sys/arm/samsung/exynos/exynos5_mp.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,90 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Ruslan Bukin <br at bsdpad.com>
+ * 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: stable/10/sys/arm/samsung/exynos/exynos5_mp.c 266203 2014-05-16 00:14:50Z ian $");
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/smp.h>
+
+#include <machine/smp.h>
+#include <machine/fdt.h>
+#include <machine/intr.h>
+
+#define	EXYNOS_SYSRAM			0x02020000
+
+void
+platform_mp_init_secondary(void)
+{
+
+	gic_init_secondary();
+}
+
+void
+platform_mp_setmaxid(void)
+{
+
+	mp_maxid = 1;
+}
+
+int
+platform_mp_probe(void)
+{
+
+	mp_ncpus = 2;
+	return (1);
+}
+
+void
+platform_mp_start_ap(void)
+{
+	bus_addr_t sysram;
+	int err;
+
+	err = bus_space_map(fdtbus_bs_tag, EXYNOS_SYSRAM, 0x100, 0, &sysram);
+	if (err != 0)
+		panic("Couldn't map sysram\n");
+
+	bus_space_write_4(fdtbus_bs_tag, sysram, 0x0,
+	    pmap_kextract((vm_offset_t)mpentry));
+
+	cpu_idcache_wbinv_all();
+	cpu_l2cache_wbinv_all();
+
+	armv7_sev();
+	bus_space_unmap(fdtbus_bs_tag, sysram, 0x100);
+}
+
+void
+platform_ipi_send(cpuset_t cpus, u_int ipi)
+{
+
+	pic_ipi_send(cpus, ipi);
+}


Property changes on: trunk/sys/arm/samsung/exynos/exynos5_mp.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/samsung/exynos/exynos5_pad.c
===================================================================
--- trunk/sys/arm/samsung/exynos/exynos5_pad.c	                        (rev 0)
+++ trunk/sys/arm/samsung/exynos/exynos5_pad.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,708 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014 Ruslan Bukin <br at bsdpad.com>
+ * 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.
+ */
+
+/*
+ * Samsung Exynos 5 Pad Control
+ * Chapter 4, Exynos 5 Dual User's Manual Public Rev 1.00
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/samsung/exynos/exynos5_pad.c 278786 2015-02-14 21:16:19Z loos $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/timeet.h>
+#include <sys/timetc.h>
+#include <sys/watchdog.h>
+#include <sys/mutex.h>
+#include <sys/gpio.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#include "gpio_if.h"
+
+#include <arm/samsung/exynos/exynos5_combiner.h>
+#include <arm/samsung/exynos/exynos5_pad.h>
+
+#define	GPIO_LOCK(_sc)		mtx_lock(&(_sc)->sc_mtx)
+#define	GPIO_UNLOCK(_sc)	mtx_unlock(&(_sc)->sc_mtx)
+
+#define	DEFAULT_CAPS	(GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)
+
+#define	NPORTS	4
+#define	NGRP	40
+#define	NGPIO	253
+#define	NINTS	16
+
+#define	PIN_IN	0
+#define	PIN_OUT	1
+
+#define	READ4(_sc, _port, _reg)						\
+	bus_space_read_4(_sc->bst[_port], _sc->bsh[_port], _reg)
+#define	WRITE4(_sc, _port, _reg, _val)					\
+	bus_space_write_4(_sc->bst[_port], _sc->bsh[_port], _reg, _val)
+
+/*
+ * GPIO interface
+ */
+static int pad_pin_max(device_t, int *);
+static int pad_pin_getcaps(device_t, uint32_t, uint32_t *);
+static int pad_pin_getname(device_t, uint32_t, char *);
+static int pad_pin_getflags(device_t, uint32_t, uint32_t *);
+static int pad_pin_setflags(device_t, uint32_t, uint32_t);
+static int pad_pin_set(device_t, uint32_t, unsigned int);
+static int pad_pin_get(device_t, uint32_t, unsigned int *);
+static int pad_pin_toggle(device_t, uint32_t pin);
+
+struct pad_softc {
+	struct resource		*res[NPORTS+4];
+	bus_space_tag_t		bst[NPORTS];
+	bus_space_handle_t	bsh[NPORTS];
+	struct mtx		sc_mtx;
+	int			gpio_npins;
+	struct gpio_pin		gpio_pins[NGPIO];
+	void			*gpio_ih[NPORTS+4];
+	device_t		dev;
+};
+
+struct pad_softc *gpio_sc;
+
+static struct resource_spec pad_spec[] = {
+	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
+	{ SYS_RES_MEMORY,	1,	RF_ACTIVE },
+	{ SYS_RES_MEMORY,	2,	RF_ACTIVE },
+	{ SYS_RES_MEMORY,	3,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		0,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		1,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		2,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		3,	RF_ACTIVE },
+	{ -1, 0 }
+};
+
+struct pad_intr {
+	uint32_t	enabled;
+	void		(*ih) (void *);
+	void		*ih_user;
+};
+
+static struct pad_intr intr_map[NGPIO];
+
+struct interrupt_entry {
+	int gpio_number;
+	char *combiner_source_name;
+};
+
+struct interrupt_entry interrupt_table[NINTS] = {
+	{ 147, "EINT[15]" },
+	{ 146, "EINT[14]" },
+	{ 145, "EINT[13]" },
+	{ 144, "EINT[12]" },
+	{ 143, "EINT[11]" },
+	{ 142, "EINT[10]" },
+	{ 141, "EINT[9]" },
+	{ 140, "EINT[8]" },
+	{ 139, "EINT[7]" },
+	{ 138, "EINT[6]" },
+	{ 137, "EINT[5]" },
+	{ 136, "EINT[4]" },
+	{ 135, "EINT[3]" },
+	{ 134, "EINT[2]" },
+	{ 133, "EINT[1]" },
+	{ 132, "EINT[0]" },
+};
+
+struct gpio_bank {
+	char		*name;
+	uint32_t	port;
+	uint32_t	con;
+	uint32_t	ngpio;
+	uint32_t	ext_int_grp;
+	uint32_t	ext_con;
+	uint32_t	ext_flt_con;
+	uint32_t	mask;
+	uint32_t	pend;
+};
+
+/*
+ * 253 multi-functional input/output ports
+ */
+
+static struct gpio_bank gpio_map[] = {
+	/* first 132 gpio */
+	{ "gpa0", 0, 0x000, 8,  1, 0x700, 0x800, 0x900, 0xA00 },
+	{ "gpa1", 0, 0x020, 6,  2, 0x704, 0x808, 0x904, 0xA04 },
+	{ "gpa2", 0, 0x040, 8,  3, 0x708, 0x810, 0x908, 0xA08 },
+	{ "gpb0", 0, 0x060, 5,  4, 0x70C, 0x818, 0x90C, 0xA0C },
+	{ "gpb1", 0, 0x080, 5,  5, 0x710, 0x820, 0x910, 0xA10 },
+	{ "gpb2", 0, 0x0A0, 4,  6, 0x714, 0x828, 0x914, 0xA14 },
+	{ "gpb3", 0, 0x0C0, 4,  7, 0x718, 0x830, 0x918, 0xA18 },
+	{ "gpc0", 0, 0x0E0, 7,  8, 0x71C, 0x838, 0x91C, 0xA1C },
+	{ "gpc1", 0, 0x100, 4,  9, 0x720, 0x840, 0x920, 0xA20 },
+	{ "gpc2", 0, 0x120, 7, 10, 0x724, 0x848, 0x924, 0xA24 },
+	{ "gpc3", 0, 0x140, 7, 11, 0x728, 0x850, 0x928, 0xA28 },
+	{ "gpd0", 0, 0x160, 4, 12, 0x72C, 0x858, 0x92C, 0xA2C },
+	{ "gpd1", 0, 0x180, 8, 13, 0x730, 0x860, 0x930, 0xA30 },
+	{ "gpy0", 0, 0x1A0, 6,  0,     0,     0,     0,     0 },
+	{ "gpy1", 0, 0x1C0, 4,  0,     0,     0,     0,     0 },
+	{ "gpy2", 0, 0x1E0, 6,  0,     0,     0,     0,     0 },
+	{ "gpy3", 0, 0x200, 8,  0,     0,     0,     0,     0 },
+	{ "gpy4", 0, 0x220, 8,  0,     0,     0,     0,     0 },
+	{ "gpy5", 0, 0x240, 8,  0,     0,     0,     0,     0 },
+	{ "gpy6", 0, 0x260, 8,  0,     0,     0,     0,     0 },
+	{ "gpc4", 0, 0x2E0, 7, 30, 0x734, 0x868, 0x934, 0xA34 },
+
+	/* next 32 */
+	{ "gpx0", 0, 0xC00, 8, 40, 0xE00, 0xE80, 0xF00, 0xF40 },
+	{ "gpx1", 0, 0xC20, 8, 41, 0xE04, 0xE88, 0xF04, 0xF44 },
+	{ "gpx2", 0, 0xC40, 8, 42, 0xE08, 0xE90, 0xF08, 0xF48 },
+	{ "gpx3", 0, 0xC60, 8, 43, 0xE0C, 0xE98, 0xF0C, 0xF4C },
+
+	{ "gpe0", 1, 0x000, 8, 14, 0x700, 0x800, 0x900, 0xA00 },
+	{ "gpe1", 1, 0x020, 2, 15, 0x704, 0x808, 0x904, 0xA04 },
+	{ "gpf0", 1, 0x040, 4, 16, 0x708, 0x810, 0x908, 0xA08 },
+	{ "gpf1", 1, 0x060, 4, 17, 0x70C, 0x818, 0x90C, 0xA0C },
+	{ "gpg0", 1, 0x080, 8, 18, 0x710, 0x820, 0x910, 0xA10 },
+	{ "gpg1", 1, 0x0A0, 8, 19, 0x714, 0x828, 0x914, 0xA14 },
+	{ "gpg2", 1, 0x0C0, 2, 20, 0x718, 0x830, 0x918, 0xA18 },
+	{ "gph0", 1, 0x0E0, 4, 21, 0x71C, 0x838, 0x91C, 0xA1C },
+	{ "gph1", 1, 0x100, 8, 22, 0x720, 0x840, 0x920, 0xA20 },
+
+	{ "gpv0", 2, 0x000, 8, 60, 0x700, 0x800, 0x900, 0xA00 },
+	{ "gpv1", 2, 0x020, 8, 61, 0x704, 0x808, 0x904, 0xA04 },
+	{ "gpv2", 2, 0x060, 8, 62, 0x708, 0x810, 0x908, 0xA08 },
+	{ "gpv3", 2, 0x080, 8, 63, 0x70C, 0x818, 0x90C, 0xA0C },
+	{ "gpv4", 2, 0x0C0, 2, 64, 0x710, 0x820, 0x910, 0xA10 },
+
+	{ "gpz",  3, 0x000, 7, 50, 0x700, 0x800, 0x900, 0xA00 },
+};
+
+static int
+get_bank(int gpio_number, struct gpio_bank *bank, int *pin_shift)
+{
+	int ngpio;
+	int i;
+	int n;
+
+	n = 0;
+	for (i = 0; i < NGRP; i++) {
+		ngpio = gpio_map[i].ngpio;
+
+		if ((n + ngpio) >= gpio_number) {
+			*bank = gpio_map[i];
+			*pin_shift = (gpio_number - n);
+			return (0);
+		};
+
+		n += ngpio;
+	};
+
+	return (-1);
+}
+
+static int
+port_intr(void *arg)
+{
+	struct port_softc *sc;
+
+	sc = arg;
+
+	return (FILTER_HANDLED);
+}
+
+static void
+ext_intr(void *arg)
+{
+	struct pad_softc *sc;
+	void (*ih) (void *);
+	void *ih_user;
+	int ngpio;
+	int found;
+	int reg;
+	int i,j;
+	int n,k;
+
+	sc = arg;
+
+	n = 0;
+	for (i = 0; i < NGRP; i++) {
+		found = 0;
+		ngpio = gpio_map[i].ngpio;
+
+		if (gpio_map[i].pend == 0) {
+			n += ngpio;
+			continue;
+		}
+
+		reg = READ4(sc, gpio_map[i].port, gpio_map[i].pend);
+
+		for (j = 0; j < ngpio; j++) {
+			if (reg & (1 << j)) {
+				found = 1;
+
+				k = (n + j);
+				if (intr_map[k].enabled == 1) {
+					ih = intr_map[k].ih;
+					ih_user = intr_map[k].ih_user;
+					ih(ih_user);
+				}
+			}
+		}
+
+		if (found) {
+			/* ACK */
+			WRITE4(sc, gpio_map[i].port, gpio_map[i].pend, reg);
+		}
+
+		n += ngpio;
+	}
+}
+
+int
+pad_setup_intr(int gpio_number, void (*ih)(void *), void *ih_user)
+{
+	struct interrupt_entry *entry;
+	struct pad_intr *pad_irq;
+	struct gpio_bank bank;
+	struct pad_softc *sc;
+	int pin_shift;
+	int reg;
+	int i;
+
+	sc = gpio_sc;
+
+	if (sc == NULL) {
+		device_printf(sc->dev, "Error: pad is not attached\n");
+		return (-1);
+	}
+
+	if (get_bank(gpio_number, &bank, &pin_shift) != 0)
+		return (-1);
+
+	entry = NULL;
+	for (i = 0; i < NINTS; i++)
+		if (interrupt_table[i].gpio_number == gpio_number)
+			entry = &interrupt_table[i];
+
+	if (entry == NULL) {
+		device_printf(sc->dev, "Cant find interrupt source for %d\n",
+		    gpio_number);
+		return (-1);
+	}
+
+#if 0
+	printf("Request interrupt name %s\n", entry->combiner_source_name);
+#endif
+
+	pad_irq = &intr_map[gpio_number];
+	pad_irq->enabled = 1;
+	pad_irq->ih = ih;
+	pad_irq->ih_user = ih_user;
+
+	/* Setup port as external interrupt source */
+	reg = READ4(sc, bank.port, bank.con);
+	reg |= (0xf << (pin_shift * 4));
+#if 0
+	printf("writing 0x%08x to 0x%08x\n", reg, bank.con);
+#endif
+	WRITE4(sc, bank.port, bank.con, reg);
+
+	/*
+	 * Configure interrupt pin
+	 *
+	 * 0x0 = Sets Low level
+	 * 0x1 = Sets High level
+	 * 0x2 = Triggers Falling edge
+	 * 0x3 = Triggers Rising edge
+	 * 0x4 = Triggers Both edge
+	 *
+	 * TODO: add parameter. For now configure as 0x0
+	 */
+	reg = READ4(sc, bank.port, bank.ext_con);
+	reg &= ~(0x7 << (pin_shift * 4));
+	WRITE4(sc, bank.port, bank.ext_con, reg);
+
+	/* Unmask */
+	reg = READ4(sc, bank.port, bank.mask);
+	reg &= ~(1 << pin_shift);
+	WRITE4(sc, bank.port, bank.mask, reg);
+
+	combiner_setup_intr(entry->combiner_source_name, ext_intr, sc);
+
+	return (0);
+}
+
+static int
+pad_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "exynos,pad"))
+		return (ENXIO);
+
+	device_set_desc(dev, "Exynos Pad Control");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+pad_attach(device_t dev)
+{
+	struct gpio_bank bank;
+	struct pad_softc *sc;
+	int pin_shift;
+	int reg;
+	int i;
+
+	sc = device_get_softc(dev);
+	mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL, MTX_DEF);
+
+	if (bus_alloc_resources(dev, pad_spec, sc->res)) {
+		device_printf(dev, "could not allocate resources\n");
+		return (ENXIO);
+	}
+
+	/* Memory interface */
+
+	for (i = 0; i < NPORTS; i++) {
+		sc->bst[i] = rman_get_bustag(sc->res[i]);
+		sc->bsh[i] = rman_get_bushandle(sc->res[i]);
+	};
+
+	sc->dev = dev;
+	sc->gpio_npins = NGPIO;
+
+	gpio_sc = sc;
+
+	for (i = 0; i < NPORTS; i++) {
+		if ((bus_setup_intr(dev, sc->res[NPORTS + i],
+			    INTR_TYPE_BIO | INTR_MPSAFE, port_intr,
+			    NULL, sc, &sc->gpio_ih[i]))) {
+			device_printf(dev,
+			    "ERROR: Unable to register interrupt handler\n");
+			return (ENXIO);
+		}
+	};
+
+	for (i = 0; i < sc->gpio_npins; i++) {
+		sc->gpio_pins[i].gp_pin = i;
+		sc->gpio_pins[i].gp_caps = DEFAULT_CAPS;
+
+		if (get_bank(i, &bank, &pin_shift) != 0)
+			continue;
+
+		pin_shift *= 4;
+
+		reg = READ4(sc, bank.port, bank.con);
+		if (reg & (PIN_OUT << pin_shift))
+			sc->gpio_pins[i].gp_flags = GPIO_PIN_OUTPUT;
+		else
+			sc->gpio_pins[i].gp_flags = GPIO_PIN_INPUT;
+
+		/* TODO: add other pin statuses */
+
+		snprintf(sc->gpio_pins[i].gp_name, GPIOMAXNAME,
+		    "pad%d.%d", device_get_unit(dev), i);
+	}
+
+	device_add_child(dev, "gpioc", -1);
+	device_add_child(dev, "gpiobus", -1);
+
+	return (bus_generic_attach(dev));
+}
+
+static int
+pad_pin_max(device_t dev, int *maxpin)
+{
+
+	*maxpin = NGPIO - 1;
+	return (0);
+}
+
+static int
+pad_pin_getname(device_t dev, uint32_t pin, char *name)
+{
+	struct pad_softc *sc;
+	int i;
+
+	sc = device_get_softc(dev);
+	for (i = 0; i < sc->gpio_npins; i++) {
+		if (sc->gpio_pins[i].gp_pin == pin)
+			break;
+	}
+
+	if (i >= sc->gpio_npins)
+		return (EINVAL);
+
+	GPIO_LOCK(sc);
+	memcpy(name, sc->gpio_pins[i].gp_name, GPIOMAXNAME);
+	GPIO_UNLOCK(sc);
+
+	return (0);
+}
+
+static int
+pad_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
+{
+	struct pad_softc *sc;
+	int i;
+
+	sc = device_get_softc(dev);
+	for (i = 0; i < sc->gpio_npins; i++) {
+		if (sc->gpio_pins[i].gp_pin == pin)
+			break;
+	}
+
+	if (i >= sc->gpio_npins)
+		return (EINVAL);
+
+	GPIO_LOCK(sc);
+	*caps = sc->gpio_pins[i].gp_caps;
+	GPIO_UNLOCK(sc);
+
+	return (0);
+}
+
+static int
+pad_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
+{
+	struct pad_softc *sc;
+	int i;
+
+	sc = device_get_softc(dev);
+	for (i = 0; i < sc->gpio_npins; i++) {
+		if (sc->gpio_pins[i].gp_pin == pin)
+			break;
+	}
+
+	if (i >= sc->gpio_npins)
+		return (EINVAL);
+
+	GPIO_LOCK(sc);
+	*flags = sc->gpio_pins[i].gp_flags;
+	GPIO_UNLOCK(sc);
+
+	return (0);
+}
+
+static int
+pad_pin_get(device_t dev, uint32_t pin, unsigned int *val)
+{
+	struct gpio_bank bank;
+	struct pad_softc *sc;
+	int pin_shift;
+	int i;
+
+	sc = device_get_softc(dev);
+	for (i = 0; i < sc->gpio_npins; i++) {
+		if (sc->gpio_pins[i].gp_pin == pin)
+			break;
+	}
+
+	if (i >= sc->gpio_npins)
+		return (EINVAL);
+
+	if (get_bank(pin, &bank, &pin_shift) != 0)
+		return (EINVAL);
+
+	GPIO_LOCK(sc);
+	if (READ4(sc, bank.port, bank.con + 0x4) & (1 << pin_shift))
+		*val = 1;
+	else
+		*val = 0;
+	GPIO_UNLOCK(sc);
+
+	return (0);
+}
+
+static int
+pad_pin_toggle(device_t dev, uint32_t pin)
+{
+	struct gpio_bank bank;
+	struct pad_softc *sc;
+	int pin_shift;
+	int reg;
+	int i;
+
+	sc = device_get_softc(dev);
+	for (i = 0; i < sc->gpio_npins; i++) {
+		if (sc->gpio_pins[i].gp_pin == pin)
+			break;
+	}
+
+	if (i >= sc->gpio_npins)
+		return (EINVAL);
+
+	if (get_bank(pin, &bank, &pin_shift) != 0)
+		return (EINVAL);
+
+	GPIO_LOCK(sc);
+	reg = READ4(sc, bank.port, bank.con + 0x4);
+	if (reg & (1 << pin_shift))
+		reg &= ~(1 << pin_shift);
+	else
+		reg |= (1 << pin_shift);
+	WRITE4(sc, bank.port, bank.con + 0x4, reg);
+	GPIO_UNLOCK(sc);
+
+	return (0);
+}
+
+
+static void
+pad_pin_configure(struct pad_softc *sc, struct gpio_pin *pin,
+    unsigned int flags)
+{
+	struct gpio_bank bank;
+	int pin_shift;
+	int reg;
+
+	GPIO_LOCK(sc);
+
+	/*
+	 * Manage input/output
+	 */
+	if (flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) {
+		pin->gp_flags &= ~(GPIO_PIN_INPUT|GPIO_PIN_OUTPUT);
+
+		if (get_bank(pin->gp_pin, &bank, &pin_shift) != 0)
+			return;
+
+		pin_shift *= 4;
+
+#if 0
+		printf("bank is 0x%08x pin_shift %d\n", bank.con, pin_shift);
+#endif
+
+		if (flags & GPIO_PIN_OUTPUT) {
+			pin->gp_flags |= GPIO_PIN_OUTPUT;
+			reg = READ4(sc, bank.port, bank.con);
+			reg &= ~(0xf << pin_shift);
+			reg |= (PIN_OUT << pin_shift);
+			WRITE4(sc, bank.port, bank.con, reg);
+		} else {
+			pin->gp_flags |= GPIO_PIN_INPUT;
+			reg = READ4(sc, bank.port, bank.con);
+			reg &= ~(0xf << pin_shift);
+			WRITE4(sc, bank.port, bank.con, reg);
+		}
+	}
+
+	GPIO_UNLOCK(sc);
+}
+
+
+static int
+pad_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
+{
+	struct pad_softc *sc;
+	int i;
+
+	sc = device_get_softc(dev);
+	for (i = 0; i < sc->gpio_npins; i++) {
+		if (sc->gpio_pins[i].gp_pin == pin)
+			break;
+	}
+
+	if (i >= sc->gpio_npins)
+		return (EINVAL);
+
+	pad_pin_configure(sc, &sc->gpio_pins[i], flags);
+
+	return (0);
+}
+
+static int
+pad_pin_set(device_t dev, uint32_t pin, unsigned int value)
+{
+	struct pad_softc *sc;
+	struct gpio_bank bank;
+	int pin_shift;
+	int reg;
+	int i;
+
+	sc = device_get_softc(dev);
+	for (i = 0; i < sc->gpio_npins; i++) {
+		if (sc->gpio_pins[i].gp_pin == pin)
+			break;
+	}
+
+	if (i >= sc->gpio_npins)
+		return (EINVAL);
+
+	if (get_bank(pin, &bank, &pin_shift) != 0)
+		return (EINVAL);
+
+	GPIO_LOCK(sc);
+	reg = READ4(sc, bank.port, bank.con + 0x4);
+	reg &= ~(PIN_OUT << pin_shift);
+	if (value)
+		reg |= (PIN_OUT << pin_shift);
+	WRITE4(sc, bank.port, bank.con + 0x4, reg);
+	GPIO_UNLOCK(sc);
+
+	return (0);
+}
+
+static device_method_t pad_methods[] = {
+	DEVMETHOD(device_probe,		pad_probe),
+	DEVMETHOD(device_attach,	pad_attach),
+
+	/* GPIO protocol */
+	DEVMETHOD(gpio_pin_max,		pad_pin_max),
+	DEVMETHOD(gpio_pin_getname,	pad_pin_getname),
+	DEVMETHOD(gpio_pin_getcaps,	pad_pin_getcaps),
+	DEVMETHOD(gpio_pin_getflags,	pad_pin_getflags),
+	DEVMETHOD(gpio_pin_get,		pad_pin_get),
+	DEVMETHOD(gpio_pin_toggle,	pad_pin_toggle),
+	DEVMETHOD(gpio_pin_setflags,	pad_pin_setflags),
+	DEVMETHOD(gpio_pin_set,		pad_pin_set),
+	{ 0, 0 }
+};
+
+static driver_t pad_driver = {
+	"gpio",
+	pad_methods,
+	sizeof(struct pad_softc),
+};
+
+static devclass_t pad_devclass;
+
+DRIVER_MODULE(pad, simplebus, pad_driver, pad_devclass, 0, 0);


Property changes on: trunk/sys/arm/samsung/exynos/exynos5_pad.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/samsung/exynos/exynos5_pad.h
===================================================================
--- trunk/sys/arm/samsung/exynos/exynos5_pad.h	                        (rev 0)
+++ trunk/sys/arm/samsung/exynos/exynos5_pad.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,30 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014 Ruslan Bukin <br at bsdpad.com>
+ * 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: stable/10/sys/arm/samsung/exynos/exynos5_pad.h 266341 2014-05-17 19:37:04Z ian $
+ */
+
+int pad_setup_intr(int gpio_number, void (*ih)(void *), void *ih_user);


Property changes on: trunk/sys/arm/samsung/exynos/exynos5_pad.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/samsung/exynos/exynos_uart.c
===================================================================
--- trunk/sys/arm/samsung/exynos/exynos_uart.c	                        (rev 0)
+++ trunk/sys/arm/samsung/exynos/exynos_uart.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,390 @@
+/* $MidnightBSD$ */
+/*
+ * Copyright (c) 2003 Marcel Moolenaar
+ * Copyright (c) 2007-2009 Andrew Turner
+ * Copyright (c) 2013 Ruslan Bukin <br at bsdpad.com>
+ * 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 ``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 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: stable/10/sys/arm/samsung/exynos/exynos_uart.c 283327 2015-05-23 20:54:25Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/cons.h>
+#include <sys/tty.h>
+#include <sys/rman.h>
+#include <machine/bus.h>
+#include <machine/intr.h>
+
+#include <dev/uart/uart.h>
+#include <dev/uart/uart_cpu.h>
+#include <dev/uart/uart_cpu_fdt.h>
+#include <dev/uart/uart_bus.h>
+
+#include <arm/samsung/exynos/exynos_uart.h>
+
+#include "uart_if.h"
+
+#define	DEF_CLK		100000000
+
+static int sscomspeed(long, long);
+static int exynos4210_uart_param(struct uart_bas *, int, int, int, int);
+
+/*
+ * Low-level UART interface.
+ */
+static int exynos4210_probe(struct uart_bas *bas);
+static void exynos4210_init(struct uart_bas *bas, int, int, int, int);
+static void exynos4210_term(struct uart_bas *bas);
+static void exynos4210_putc(struct uart_bas *bas, int);
+static int exynos4210_rxready(struct uart_bas *bas);
+static int exynos4210_getc(struct uart_bas *bas, struct mtx *mtx);
+
+extern SLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs;
+
+static int
+sscomspeed(long speed, long frequency)
+{
+	int x;
+
+	if (speed <= 0 || frequency <= 0)
+		return (-1);
+	x = (frequency / 16) / speed;
+	return (x-1);
+}
+
+static int
+exynos4210_uart_param(struct uart_bas *bas, int baudrate, int databits,
+    int stopbits, int parity)
+{
+	int brd, ulcon;
+
+	ulcon = 0;
+
+	switch(databits) {
+	case 5:
+		ulcon |= ULCON_LENGTH_5;
+		break;
+	case 6:
+		ulcon |= ULCON_LENGTH_6;
+		break;
+	case 7:
+		ulcon |= ULCON_LENGTH_7;
+		break;
+	case 8:
+		ulcon |= ULCON_LENGTH_8;
+		break;
+	default:
+		return (EINVAL);
+	}
+
+	switch (parity) {
+	case UART_PARITY_NONE:
+		ulcon |= ULCON_PARITY_NONE;
+		break;
+	case UART_PARITY_ODD:
+		ulcon |= ULCON_PARITY_ODD;
+		break;
+	case UART_PARITY_EVEN:
+		ulcon |= ULCON_PARITY_EVEN;
+		break;
+	case UART_PARITY_MARK:
+	case UART_PARITY_SPACE:
+	default:
+		return (EINVAL);
+	}
+
+	if (stopbits == 2)
+		ulcon |= ULCON_STOP;
+
+	uart_setreg(bas, SSCOM_ULCON, ulcon);
+
+	brd = sscomspeed(baudrate, bas->rclk);
+	uart_setreg(bas, SSCOM_UBRDIV, brd);
+
+	return (0);
+}
+
+struct uart_ops uart_exynos4210_ops = {
+	.probe = exynos4210_probe,
+	.init = exynos4210_init,
+	.term = exynos4210_term,
+	.putc = exynos4210_putc,
+	.rxready = exynos4210_rxready,
+	.getc = exynos4210_getc,
+};
+
+static int
+exynos4210_probe(struct uart_bas *bas)
+{
+
+	return (0);
+}
+
+static void
+exynos4210_init(struct uart_bas *bas, int baudrate, int databits, int stopbits,
+    int parity)
+{
+
+	if (bas->rclk == 0)
+		bas->rclk = DEF_CLK;
+
+	KASSERT(bas->rclk != 0, ("exynos4210_init: Invalid rclk"));
+
+	uart_setreg(bas, SSCOM_UCON, 0);
+	uart_setreg(bas, SSCOM_UFCON,
+	    UFCON_TXTRIGGER_8 | UFCON_RXTRIGGER_8 |
+	    UFCON_TXFIFO_RESET | UFCON_RXFIFO_RESET |
+	    UFCON_FIFO_ENABLE);
+	exynos4210_uart_param(bas, baudrate, databits, stopbits, parity);
+
+	/* Enable UART. */
+	uart_setreg(bas, SSCOM_UCON, UCON_TXMODE_INT | UCON_RXMODE_INT |
+	    UCON_TOINT);
+	uart_setreg(bas, SSCOM_UMCON, UMCON_RTS);
+}
+
+static void
+exynos4210_term(struct uart_bas *bas)
+{
+	/* XXX */
+}
+
+static void
+exynos4210_putc(struct uart_bas *bas, int c)
+{
+
+	while ((bus_space_read_4(bas->bst, bas->bsh, SSCOM_UFSTAT) &
+		UFSTAT_TXFULL) == UFSTAT_TXFULL)
+		continue;
+
+	uart_setreg(bas, SSCOM_UTXH, c);
+}
+
+static int
+exynos4210_rxready(struct uart_bas *bas)
+{
+
+	return ((uart_getreg(bas, SSCOM_UTRSTAT) & UTRSTAT_RXREADY) ==
+	    UTRSTAT_RXREADY);
+}
+
+static int
+exynos4210_getc(struct uart_bas *bas, struct mtx *mtx)
+{
+	int utrstat;
+
+	utrstat = bus_space_read_1(bas->bst, bas->bsh, SSCOM_UTRSTAT);
+	while (!(utrstat & UTRSTAT_RXREADY)) {
+		utrstat = bus_space_read_1(bas->bst, bas->bsh, SSCOM_UTRSTAT);
+		continue;
+	}
+
+	return (bus_space_read_1(bas->bst, bas->bsh, SSCOM_URXH));
+}
+
+static int exynos4210_bus_probe(struct uart_softc *sc);
+static int exynos4210_bus_attach(struct uart_softc *sc);
+static int exynos4210_bus_flush(struct uart_softc *, int);
+static int exynos4210_bus_getsig(struct uart_softc *);
+static int exynos4210_bus_ioctl(struct uart_softc *, int, intptr_t);
+static int exynos4210_bus_ipend(struct uart_softc *);
+static int exynos4210_bus_param(struct uart_softc *, int, int, int, int);
+static int exynos4210_bus_receive(struct uart_softc *);
+static int exynos4210_bus_setsig(struct uart_softc *, int);
+static int exynos4210_bus_transmit(struct uart_softc *);
+
+static kobj_method_t exynos4210_methods[] = {
+	KOBJMETHOD(uart_probe,		exynos4210_bus_probe),
+	KOBJMETHOD(uart_attach, 	exynos4210_bus_attach),
+	KOBJMETHOD(uart_flush,		exynos4210_bus_flush),
+	KOBJMETHOD(uart_getsig,		exynos4210_bus_getsig),
+	KOBJMETHOD(uart_ioctl,		exynos4210_bus_ioctl),
+	KOBJMETHOD(uart_ipend,		exynos4210_bus_ipend),
+	KOBJMETHOD(uart_param,		exynos4210_bus_param),
+	KOBJMETHOD(uart_receive,	exynos4210_bus_receive),
+	KOBJMETHOD(uart_setsig,		exynos4210_bus_setsig),
+	KOBJMETHOD(uart_transmit,	exynos4210_bus_transmit),
+
+	{0, 0 }
+};
+
+int
+exynos4210_bus_probe(struct uart_softc *sc)
+{
+
+	sc->sc_txfifosz = 16;
+	sc->sc_rxfifosz = 16;
+
+	return (0);
+}
+
+static int
+exynos4210_bus_attach(struct uart_softc *sc)
+{
+
+	sc->sc_hwiflow = 0;
+	sc->sc_hwoflow = 0;
+
+	return (0);
+}
+
+static int
+exynos4210_bus_transmit(struct uart_softc *sc)
+{
+	int i;
+	int reg;
+
+	uart_lock(sc->sc_hwmtx);
+
+	for (i = 0; i < sc->sc_txdatasz; i++) {
+		exynos4210_putc(&sc->sc_bas, sc->sc_txbuf[i]);
+		uart_barrier(&sc->sc_bas);
+	}
+
+	sc->sc_txbusy = 1;
+
+	uart_unlock(sc->sc_hwmtx);
+
+	/* unmask TX interrupt */
+	reg = bus_space_read_4(sc->sc_bas.bst, sc->sc_bas.bsh, SSCOM_UINTM);
+	reg &= ~(1 << 2);
+	bus_space_write_4(sc->sc_bas.bst, sc->sc_bas.bsh, SSCOM_UINTM, reg);
+
+	return (0);
+}
+
+static int
+exynos4210_bus_setsig(struct uart_softc *sc, int sig)
+{
+
+	return (0);
+}
+
+static int
+exynos4210_bus_receive(struct uart_softc *sc)
+{
+	struct uart_bas *bas;
+
+	bas = &sc->sc_bas;
+	while (bus_space_read_4(bas->bst, bas->bsh,
+		SSCOM_UFSTAT) & UFSTAT_RXCOUNT)
+		uart_rx_put(sc, uart_getreg(&sc->sc_bas, SSCOM_URXH));
+
+	return (0);
+}
+
+static int
+exynos4210_bus_param(struct uart_softc *sc, int baudrate, int databits,
+    int stopbits, int parity)
+{
+	int error;
+
+	if (sc->sc_bas.rclk == 0)
+		sc->sc_bas.rclk = DEF_CLK;
+
+	KASSERT(sc->sc_bas.rclk != 0, ("exynos4210_init: Invalid rclk"));
+
+	uart_lock(sc->sc_hwmtx);
+	error = exynos4210_uart_param(&sc->sc_bas, baudrate, databits, stopbits,
+	    parity);
+	uart_unlock(sc->sc_hwmtx);
+
+	return (error);
+}
+
+static int
+exynos4210_bus_ipend(struct uart_softc *sc)
+{
+	uint32_t ints;
+	uint32_t txempty, rxready;
+	int reg;
+	int ipend;
+
+	uart_lock(sc->sc_hwmtx);
+	ints = bus_space_read_4(sc->sc_bas.bst, sc->sc_bas.bsh, SSCOM_UINTP);
+	bus_space_write_4(sc->sc_bas.bst, sc->sc_bas.bsh, SSCOM_UINTP, ints);
+
+	txempty = (1 << 2);
+	rxready = (1 << 0);
+
+	ipend = 0;
+	if ((ints & txempty) > 0) {
+		if (sc->sc_txbusy != 0)
+			ipend |= SER_INT_TXIDLE;
+
+		/* mask TX interrupt */
+		reg = bus_space_read_4(sc->sc_bas.bst, sc->sc_bas.bsh,
+		    SSCOM_UINTM);
+		reg |= (1 << 2);
+		bus_space_write_4(sc->sc_bas.bst, sc->sc_bas.bsh,
+		    SSCOM_UINTM, reg);
+	}
+
+	if ((ints & rxready) > 0) {
+		ipend |= SER_INT_RXREADY;
+	}
+
+	uart_unlock(sc->sc_hwmtx);
+	return (ipend);
+}
+
+static int
+exynos4210_bus_flush(struct uart_softc *sc, int what)
+{
+
+	return (0);
+}
+
+static int
+exynos4210_bus_getsig(struct uart_softc *sc)
+{
+
+	return (0);
+}
+
+static int
+exynos4210_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
+{
+
+	return (EINVAL);
+}
+
+static struct uart_class uart_exynos4210_class = {
+	"exynos4210 class",
+	exynos4210_methods,
+	1,
+	.uc_ops = &uart_exynos4210_ops,
+	.uc_range = 8,
+	.uc_rclk = 0,
+};
+
+static struct ofw_compat_data compat_data[] = {
+	{"exynos",		(uintptr_t)&uart_exynos4210_class},
+	{NULL,			(uintptr_t)NULL},
+};
+UART_FDT_CLASS_AND_DEVICE(compat_data);


Property changes on: trunk/sys/arm/samsung/exynos/exynos_uart.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/samsung/exynos/exynos_uart.h
===================================================================
--- trunk/sys/arm/samsung/exynos/exynos_uart.h	                        (rev 0)
+++ trunk/sys/arm/samsung/exynos/exynos_uart.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,127 @@
+/* $MidnightBSD$ */
+/* $NetBSD: s3c2xx0reg.h,v 1.4 2004/02/12 03:47:29 bsh Exp $ */
+
+/*-
+ * Copyright (c) 2002, 2003 Fujitsu Component Limited
+ * Copyright (c) 2002, 2003 Genetec Corporation
+ * 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.
+ * 3. Neither the name of The Fujitsu Component Limited nor the name of
+ *    Genetec corporation may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY FUJITSU COMPONENT LIMITED AND GENETEC
+ * CORPORATION ``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 FUJITSU COMPONENT LIMITED OR GENETEC
+ * CORPORATION 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: stable/10/sys/arm/samsung/exynos/exynos_uart.h 283322 2015-05-23 19:50:14Z ian $
+ */
+
+/* s3c2410-specific registers */
+#define	UMCON_AFC		(1 << 4)	/* auto flow control */
+#define	UMSTAT_DCTS		(1 << 2)	/* CTS change */
+#define	ULCON_IR		(1 << 6)
+#define	ULCON_PARITY_SHIFT	3
+
+/*
+ * Exynos-specific
+ *
+ * UFSTAT_TXFULL register differs between Exynos and others.
+ * Others have UFSTAT_TXFULL  (1 << 9)
+ */
+#define	UFSTAT_TXFULL		(1 << 24)
+
+#define	SSCOM_UINTM		0x038
+#define	SSCOM_UINTP		0x030
+
+/* common for s3c2800 and s3c24x0 */
+#define	SSCOM_ULCON		0x00		/* UART line control */
+#define	 ULCON_PARITY_NONE	(0 << ULCON_PARITY_SHIFT)
+#define	 ULCON_PARITY_ODD	(4 << ULCON_PARITY_SHIFT)
+#define	 ULCON_PARITY_EVEN	(5 << ULCON_PARITY_SHIFT)
+#define	 ULCON_PARITY_ONE	(6 << ULCON_PARITY_SHIFT)
+#define	 ULCON_PARITY_ZERO	(7 << ULCON_PARITY_SHIFT)
+#define	 ULCON_STOP		(1 << 2)
+#define	 ULCON_LENGTH_5		0
+#define	 ULCON_LENGTH_6		1
+#define	 ULCON_LENGTH_7		2
+#define	 ULCON_LENGTH_8		3
+#define	SSCOM_UCON		0x04		/* UART control */
+#define	 UCON_TXINT_TYPE	(1 << 9)	/* Tx interrupt. 0=pulse,1=level */
+#define	 UCON_TXINT_TYPE_LEVEL	UCON_TXINT_TYPE
+#define	 UCON_TXINT_TYPE_PULSE	0
+#define	 UCON_RXINT_TYPE	(1 << 8)	/* Rx interrupt */
+#define	 UCON_RXINT_TYPE_LEVEL	UCON_RXINT_TYPE
+#define	 UCON_RXINT_TYPE_PULSE	0
+#define	 UCON_TOINT		(1 << 7)	/* Rx timeout interrupt */
+#define	 UCON_ERRINT		(1 << 6)	/* receive error interrupt */
+#define	 UCON_LOOP		(1 << 5)	/* loopback */
+#define	 UCON_SBREAK		(1 << 4)	/* send break */
+#define	 UCON_TXMODE_DISABLE	(0 << 2)
+#define	 UCON_TXMODE_INT	(1 << 2)
+#define	 UCON_TXMODE_DMA	(2 << 2)
+#define	 UCON_TXMODE_MASK	(3 << 2)
+#define	 UCON_RXMODE_DISABLE	(0 << 0)
+#define	 UCON_RXMODE_INT	(1 << 0)
+#define	 UCON_RXMODE_DMA	(2 << 0)
+#define	 UCON_RXMODE_MASK	(3 << 0)
+#define	SSCOM_UFCON		0x08		/* FIFO control */
+#define	 UFCON_TXTRIGGER_0	(0 << 6)
+#define	 UFCON_TXTRIGGER_4	(1 << 6)
+#define	 UFCON_TXTRIGGER_8	(2 << 6)
+#define	 UFCON_TXTRIGGER_16	(3 << 6)
+#define	 UFCON_RXTRIGGER_4	(0 << 4)
+#define	 UFCON_RXTRIGGER_8	(1 << 4)
+#define	 UFCON_RXTRIGGER_12	(2 << 4)
+#define	 UFCON_RXTRIGGER_16	(3 << 4)
+#define	 UFCON_TXFIFO_RESET	(1 << 2)
+#define	 UFCON_RXFIFO_RESET	(1 << 1)
+#define	 UFCON_FIFO_ENABLE	(1 << 0)
+#define	SSCOM_UMCON		0x0c		/* MODEM control */
+#define	 UMCON_RTS		(1 << 0)	/* Request to send */
+#define	SSCOM_UTRSTAT		0x10		/* Status register */
+#define	 UTRSTAT_TXSHIFTER_EMPTY	( 1<< 2)
+#define	 UTRSTAT_TXEMPTY	(1 << 1)	/* TX fifo or buffer empty */
+#define	 UTRSTAT_RXREADY	(1 << 0)	/* RX fifo or buffer is not empty */
+#define	SSCOM_UERSTAT		0x14		/* Error status register */
+#define	 UERSTAT_BREAK		(1 << 3)	/* Break signal, not 2410 */
+#define	 UERSTAT_FRAME		(1 << 2)	/* Frame error */
+#define	 UERSTAT_PARITY		(1 << 1)	/* Parity error, not 2410 */
+#define	 UERSTAT_OVERRUN	(1 << 0)	/* Overrun */
+#define	 UERSTAT_ALL_ERRORS \
+	(UERSTAT_OVERRUN|UERSTAT_BREAK|UERSTAT_FRAME|UERSTAT_PARITY)
+#define	SSCOM_UFSTAT		0x18		/* Fifo status register */
+#define	 UFSTAT_RXFULL		(1 <<8)		/* Rx fifo full */
+#define	 UFSTAT_TXCOUNT_SHIFT	4		/* TX FIFO count */
+#define	 UFSTAT_TXCOUNT		(0x0f << UFSTAT_TXCOUNT_SHIFT)
+#define	 UFSTAT_RXCOUNT_SHIFT	0		/* RX FIFO count */
+#define	 UFSTAT_RXCOUNT		(0x0f << UFSTAT_RXCOUNT_SHIFT)
+#define	SSCOM_UMSTAT		0x1c		/* Modem status register */
+#define	 UMSTAT_CTS		(1 << 0)	/* Clear to send */
+#if _BYTE_ORDER == _LITTLE_ENDIAN
+#define	SSCOM_UTXH		0x20		/* Transmit data register */
+#define	SSCOM_URXH		0x24		/* Receive data register */
+#else
+#define	SSCOM_UTXH		0x23		/* Transmit data register */
+#define	SSCOM_URXH		0x27		/* Receive data register */
+#endif
+#define	SSCOM_UBRDIV		0x28		/* baud-reate divisor */
+#define	SSCOM_SIZE		0x2c


Property changes on: trunk/sys/arm/samsung/exynos/exynos_uart.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/samsung/exynos/files.exynos5
===================================================================
--- trunk/sys/arm/samsung/exynos/files.exynos5	                        (rev 0)
+++ trunk/sys/arm/samsung/exynos/files.exynos5	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,31 @@
+# $FreeBSD: stable/10/sys/arm/samsung/exynos/files.exynos5 283322 2015-05-23 19:50:14Z ian $
+
+kern/kern_clocksource.c				standard
+
+arm/arm/bus_space_generic.c			standard
+arm/arm/bus_space_asm_generic.S			standard
+arm/arm/cpufunc_asm_armv5.S			standard
+arm/arm/cpufunc_asm_arm10.S			standard
+arm/arm/cpufunc_asm_arm11.S			standard
+arm/arm/cpufunc_asm_armv7.S			standard
+
+arm/arm/bus_space_base.c			standard
+arm/arm/gic.c					standard
+arm/arm/generic_timer.c				standard
+
+arm/samsung/exynos/exynos5_mct.c		standard
+arm/samsung/exynos/exynos5_mp.c			optional	smp
+arm/samsung/exynos/exynos5_common.c		standard
+arm/samsung/exynos/exynos5_machdep.c		standard
+arm/samsung/exynos/exynos5_combiner.c		standard
+arm/samsung/exynos/exynos5_pad.c		optional	gpio
+arm/samsung/exynos/exynos_uart.c		optional	uart
+arm/samsung/exynos/exynos5_ehci.c		optional	ehci
+arm/samsung/exynos/exynos5_fimd.c		optional	vt
+arm/samsung/exynos/exynos5_i2c.c		optional	iicbus
+
+# chromebook drivers
+arm/samsung/exynos/chrome_ec.c			optional	chrome_ec
+arm/samsung/exynos/chrome_kb.c			optional	chrome_kb
+
+#dev/sdhci/sdhci_fdt.c				optional	sdhci


Property changes on: trunk/sys/arm/samsung/exynos/files.exynos5
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/samsung/exynos/std.exynos5250
===================================================================
--- trunk/sys/arm/samsung/exynos/std.exynos5250	                        (rev 0)
+++ trunk/sys/arm/samsung/exynos/std.exynos5250	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,22 @@
+# $FreeBSD: stable/10/sys/arm/samsung/exynos/std.exynos5250 278601 2015-02-11 22:47:48Z ian $
+
+makeoption	ARM_LITTLE_ENDIAN
+
+cpu		CPU_CORTEXA
+machine		arm armv6
+makeoptions	CONF_CFLAGS="-march=armv7a -Wa,-march=armv7a"
+
+options		PHYSADDR=0x40000000
+
+makeoptions	KERNPHYSADDR=0x40f00000
+options		KERNPHYSADDR=0x40f00000
+
+makeoptions	KERNVIRTADDR=0xc0f00000
+options		KERNVIRTADDR=0xc0f00000
+
+options		ARM_L2_PIPT
+
+options		IPI_IRQ_START=0
+options		IPI_IRQ_END=15
+
+files		"../samsung/exynos/files.exynos5"


Property changes on: trunk/sys/arm/samsung/exynos/std.exynos5250
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/samsung/exynos/std.exynos5420
===================================================================
--- trunk/sys/arm/samsung/exynos/std.exynos5420	                        (rev 0)
+++ trunk/sys/arm/samsung/exynos/std.exynos5420	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,22 @@
+# $FreeBSD: stable/10/sys/arm/samsung/exynos/std.exynos5420 278601 2015-02-11 22:47:48Z ian $
+
+makeoption	ARM_LITTLE_ENDIAN
+
+cpu		CPU_CORTEXA
+machine		arm armv6
+makeoptions	CONF_CFLAGS="-march=armv7a -Wa,-march=armv7a"
+
+options		PHYSADDR=0x20000000
+
+makeoptions	KERNPHYSADDR=0x20f00000
+options		KERNPHYSADDR=0x20f00000
+
+makeoptions	KERNVIRTADDR=0xc0f00000
+options		KERNVIRTADDR=0xc0f00000
+
+options		ARM_L2_PIPT
+
+options		IPI_IRQ_START=0
+options		IPI_IRQ_END=15
+
+files		"../samsung/exynos/files.exynos5"


Property changes on: trunk/sys/arm/samsung/exynos/std.exynos5420
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/samsung/s3c2xx0/board_ln2410sbc.c
===================================================================
--- trunk/sys/arm/samsung/s3c2xx0/board_ln2410sbc.c	                        (rev 0)
+++ trunk/sys/arm/samsung/s3c2xx0/board_ln2410sbc.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,46 @@
+/* $MidnightBSD$ */
+/*
+ * Copyright (C) 2009 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/samsung/s3c2xx0/board_ln2410sbc.c 272103 2014-09-25 11:38:26Z gavin $");
+#include <sys/param.h>
+#include <sys/systm.h>
+
+#include <arm/samsung/s3c2xx0/s3c2410reg.h>
+#include <arm/samsung/s3c2xx0/s3c2xx0board.h>
+
+extern vm_offset_t s3c2410_uart_vaddr;
+
+long
+board_init(void)
+{
+	s3c2410_uart_vaddr = S3C24X0_UART_BASE(0);
+
+	return (64 * 1024 * 1024);
+}
+


Property changes on: trunk/sys/arm/samsung/s3c2xx0/board_ln2410sbc.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/samsung/s3c2xx0/files.s3c2xx0
===================================================================
--- trunk/sys/arm/samsung/s3c2xx0/files.s3c2xx0	                        (rev 0)
+++ trunk/sys/arm/samsung/s3c2xx0/files.s3c2xx0	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,15 @@
+# $FreeBSD: stable/10/sys/arm/samsung/s3c2xx0/files.s3c2xx0 278727 2015-02-13 22:32:02Z ian $
+arm/arm/bus_space_base.c	standard
+arm/arm/bus_space_asm_generic.S	standard
+arm/arm/bus_space_generic.c	standard
+arm/arm/cpufunc_asm_arm9.S	standard
+arm/samsung/s3c2xx0/board_ln2410sbc.c	optional	board_ln2410sbc
+arm/samsung/s3c2xx0/s3c24x0_rtc.c	standard
+arm/samsung/s3c2xx0/s3c24x0_machdep.c	standard
+arm/samsung/s3c2xx0/s3c24x0.c   	standard
+arm/samsung/s3c2xx0/s3c24x0_clk.c	standard
+arm/samsung/s3c2xx0/uart_bus_s3c2410.c	optional	uart
+arm/samsung/s3c2xx0/uart_cpu_s3c2410.c	optional	uart
+arm/samsung/s3c2xx0/uart_dev_s3c2410.c	optional	uart
+
+dev/usb/controller/ohci_s3c24x0.c	optional	ohci


Property changes on: trunk/sys/arm/samsung/s3c2xx0/files.s3c2xx0
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/samsung/s3c2xx0/s3c2410reg.h
===================================================================
--- trunk/sys/arm/samsung/s3c2xx0/s3c2410reg.h	                        (rev 0)
+++ trunk/sys/arm/samsung/s3c2xx0/s3c2410reg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,97 @@
+/* $MidnightBSD$ */
+/* $NetBSD: s3c2410reg.h,v 1.6 2004/02/12 03:52:46 bsh Exp $ */
+
+/*-
+ * Copyright (c) 2003, 2004  Genetec corporation.  All rights reserved.
+ * Written by Hiroyuki Bessho for Genetec corporation.
+ *
+ * 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.
+ * 3. The name of Genetec corporation may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GENETEC CORP. ``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 GENETEC CORP.
+ * 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: stable/10/sys/arm/samsung/s3c2xx0/s3c2410reg.h 272103 2014-09-25 11:38:26Z gavin $
+ */
+
+
+/*
+ * Samsung S3C2410X processor is ARM920T based integrated CPU
+ *
+ * Reference:
+ *  S3C2410X User's Manual
+ */
+#ifndef _ARM_S3C2XX0_S3C2410REG_H_
+#define	_ARM_S3C2XX0_S3C2410REG_H_
+
+/* common definitions for S3C2410 and S3C2440 */
+#include <arm/samsung/s3c2xx0/s3c24x0reg.h>
+
+/*
+ * Memory Map
+ */
+#define	S3C2410_BANK_SIZE 	0x08000000
+#define	S3C2410_BANK_START(n)	(S3C2410_BANK_SIZE*(n))
+#define	S3C2410_SDRAM_START	S3C2410_BANK_START(6)
+
+
+/* interrupt control */
+#define	S3C2410_SUBIRQ_MAX	(S3C24X0_SUBIRQ_MIN+10)
+
+/* Clock control */
+/* CLKMAN_CLKCON */
+#define	 S3C2410_CLKCON_SM	(1<<0)	/* 1=transition to SPECIAL mode */
+/* CLKMAN_CLKDIVN */
+#define	 S3C2410_CLKDIVN_HDIVN	(1<<1)	/* hclk=fclk/2 */
+
+/* NAND Flash controller */
+#define	S3C2410_NANDFC_SIZE	0x18
+/* NANDFC_NFCONF */
+#define	 S3C2410_NFCONF_ENABLE	(1<<15)	/* NAND controller enabled */
+#define	 S3C2410_NFCONF_ECC	(1<<12)	/* Initialize ECC decoder/encoder */
+#define	 S3C2410_NFCONF_FCE	(1<<11)	/* Flash chip enabled */
+#define	 S3C2410_NFCONF_TACLS	(7<<8)	/* CLE and ALE duration */
+#define	 S3C2410_NFCONF_TWRPH0	(7<<4)	/* TWRPH0 duration */
+#define	 S3C2410_NFCONF_TWRPH1	(7<<0)	/* TWRPH1 duration */
+#define	S3C2410_NANDFC_NFCMD 	0x04	/* command */
+#define	S3C2410_NANDFC_NFADDR 	0x08	/* address */
+#define	S3C2410_NANDFC_NFDATA 	0x0c	/* data */
+#define	S3C2410_NANDFC_NFSTAT 	0x10	/* operation status */
+#define	S3C2410_NANDFC_NFECC	0x14	/* ecc */
+
+/* MMC/SD */
+/* SDI_CON */
+#define  S3C2410_CON_FIFO_RESET		(1<<1)
+
+/* GPIO */
+#define	S3C2410_GPIO_SIZE	0xb4
+
+/* SD interface */
+#define	S3C2410_SDI_SIZE 	0x44
+#define  DCON_STOP		(1<<14) /* Force the transfer to stop */
+#define S3C2410_SDI_DAT		0x3c
+#define S3C2410_SDI_IMSK	0x40 /* Interrupt mask */
+#define  S3C2410_SDI_IMASK_ALL	0x3ffdf
+
+/* ADC */
+#define	S3C2410_ADC_SIZE 	0x14
+
+#endif /* _ARM_S3C2XX0_S3C2410REG_H_ */


Property changes on: trunk/sys/arm/samsung/s3c2xx0/s3c2410reg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/samsung/s3c2xx0/s3c2410var.h
===================================================================
--- trunk/sys/arm/samsung/s3c2xx0/s3c2410var.h	                        (rev 0)
+++ trunk/sys/arm/samsung/s3c2xx0/s3c2410var.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,50 @@
+/* $MidnightBSD$ */
+/* $NetBSD: s3c2410var.h,v 1.2 2003/08/29 12:57:50 bsh Exp $ */
+
+/*-
+ * Copyright (c) 2003  Genetec corporation.  All rights reserved.
+ * Written by Hiroyuki Bessho for Genetec corporation.
+ *
+ * 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.
+ * 3. The name of Genetec corporation may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GENETEC CORP. ``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 GENETEC CORP.
+ * 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: stable/10/sys/arm/samsung/s3c2xx0/s3c2410var.h 272103 2014-09-25 11:38:26Z gavin $
+ */
+
+#ifndef _ARM_S3C2410VAR_H_
+#define _ARM_S3C2410VAR_H_
+
+#include <arm/samsung/s3c2xx0/s3c24x0var.h>
+
+int	s3c2410_sscom_cnattach(bus_space_tag_t, int, int, int, tcflag_t);
+int	s3c2410_sscom_kgdb_attach(bus_space_tag_t, int, int, int, tcflag_t);
+void	s3c2410_intr_init(struct s3c24x0_softc *);
+void	s3c2410_softreset(void);
+
+void	s3c2410_mask_subinterrupts(int);
+void	s3c2410_unmask_subinterrupts(int);
+
+void	*s3c2410_extint_establish(int, int, int, int (*)(void *), void *);
+void	s3c2410_setup_extint(int, int);
+#endif /* _ARM_S3C2410VAR_H_ */


Property changes on: trunk/sys/arm/samsung/s3c2xx0/s3c2410var.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/samsung/s3c2xx0/s3c2440reg.h
===================================================================
--- trunk/sys/arm/samsung/s3c2xx0/s3c2440reg.h	                        (rev 0)
+++ trunk/sys/arm/samsung/s3c2xx0/s3c2440reg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,110 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (C) 2009 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: stable/10/sys/arm/samsung/s3c2xx0/s3c2440reg.h 272103 2014-09-25 11:38:26Z gavin $
+ */
+
+/*
+ * Samsung S3C2440X processor is ARM920T based integrated CPU
+ *
+ * Reference:
+ *  S3C2440A/S3C2442B User's Manual
+ */
+#ifndef _ARM_S3C2XX0_S3C2440REG_H_
+#define	_ARM_S3C2XX0_S3C2440REG_H_
+
+/* common definitions for S3C2410 and S3C2440 */
+#include <arm/samsung/s3c2xx0/s3c24x0reg.h>
+
+/*
+ * Memory Map
+ */
+#define	S3C2440_BANK_SIZE 	0x08000000
+#define	S3C2440_BANK_START(n)	(S3C2410_BANK_SIZE*(n))
+#define	S3C2440_SDRAM_START	S3C2410_BANK_START(6)
+
+
+/* interrupt control */
+#define	S3C2440_SUBIRQ_MAX	(S3C24X0_SUBIRQ_MIN+10)
+
+/* Clock control */
+/* CLKMAN_CLKCON */
+#define	 S3C2440_CLKCON_STOP	(1<<0)	/* 1=transition to STOP mode */
+/* CLKMAN_CLKDIVN */
+#define	 S3C2440_CLKDIVN_HDIVN	(3<<1)	/* hclk */
+#define S3C2440_CLKMAN_CAMDIVN	0x18
+#define  S3C2440_CAMDIVN_HCLK4_HALF	(1<<9)
+#define  S3C2440_CAMDIVN_HCLK3_HALF	(1<<8)
+
+/* NAND Flash controller */
+#define S3C2440_NANDFC_SIZE	0x40
+
+#define S3C2440_NANDFC_NFCONT	0x04
+#define  S3C2440_NFCONT_LOCK_TIGHT	(1<<13) /* Lock part of the NAND */
+#define  S3C2440_NFCONT_SOFT_LOCK	(1<<12) /* Soft lock part of the NAND */
+#define  S3C2440_NFCONT_ILLEGAL_ACC_INT	(1<<10) /* Illegal access interrupt */
+#define  S3C2440_NFCONT_RNB_INT		(1<<9) /* RnB transition interrupt */
+#define  S3C2440_NFCONT_RNB_TRANS_MODE	(1<<8) /* RnB transition mode */
+#define  S3C2440_NFCONT_SPARE_ECC_LOCK	(1<<6) /* Lock spare ECC generation */
+#define  S3C2440_NFCONT_MAIN_ECC_LOCK	(1<<5) /* Lock main ECC generation */
+#define  S3C2440_NFCONT_INIT_ECC	(1<<4) /* Init ECC encoder/decoder */
+#define  S3C2440_NFCONT_NCE		(1<<1) /* NAND Chip select */
+#define  S3C2440_NFCONT_ENABLE		(1<<0) /* Enable the controller */
+#define S3C2440_NANDFC_NFCMMD	0x08
+#define S3C2440_NANDFC_NFADDR	0x0c
+#define S3C2440_NANDFC_NFDATA	0x10
+#define S3C2440_NANDFC_NFSTAT	0x20
+
+/* MMC/SD */
+/* SDI_CON */
+#define  S3C2440_CON_RESET		(1<<8)
+#define  S3C2440_CON_CLOCK_TYPE		(1<<5)
+/* SDI_FSTA */
+#define  S3c2440_FSTA_RESET		(1<<16)
+#define  S3C2440_FSTA_FAIL_ERROR_MSK	(3<<14)
+#define  S3C2440_FSTA_FAIL_NONE		(0<<14)
+#define  S3C2440_FSTA_FAIL_FIFO		(1<<14)
+#define  S3C2440_FSTA_FAIL_LAST_TRANS	(2<<14)
+
+/* GPIO */
+#define	S3C2440_GPIO_SIZE	0xd0
+
+/* SD interface */
+#define	S3C2410_SDI_SIZE 	0x44
+#define  DCON_START		(1<<14) /* Start the data transfer */
+#define S3C2440_SDI_IMSK	0x3c /* Interrupt mask */
+#define  S3C2440_SDI_IMASK_ALL	0x3C7C0
+#define S3C2440_SDI_DAT		0x40
+
+/* ADC */
+#define	 ADCTSC_UD_SEN		(1<<8)
+#define	S3C2440_ADC_SIZE 	0x18
+
+/* UART */
+#define  S3C2440_UFSTAT_TXCOUNT	(0x3f << 8)
+#define  S3C2440_UFSTAT_RXCOUNT	(0x3f << 0)
+
+#endif /* _ARM_S3C2XX0_S3C2440REG_H_ */


Property changes on: trunk/sys/arm/samsung/s3c2xx0/s3c2440reg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/samsung/s3c2xx0/s3c24x0.c
===================================================================
--- trunk/sys/arm/samsung/s3c2xx0/s3c24x0.c	                        (rev 0)
+++ trunk/sys/arm/samsung/s3c2xx0/s3c24x0.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,803 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: s3c2410.c,v 1.4 2003/08/27 03:46:05 bsh Exp $ */
+
+/*
+ * Copyright (c) 2003  Genetec corporation.  All rights reserved.
+ * Written by Hiroyuki Bessho for Genetec corporation.
+ *
+ * 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.
+ * 3. The name of Genetec corporation may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GENETEC CORP. ``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 GENETEC CORP.
+ * 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: stable/10/sys/arm/samsung/s3c2xx0/s3c24x0.c 278727 2015-02-13 22:32:02Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/reboot.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <machine/armreg.h>
+#include <machine/cpu.h>
+#include <machine/bus.h>
+
+#include <machine/cpufunc.h>
+#include <machine/intr.h>
+#include <arm/samsung/s3c2xx0/s3c2410reg.h>
+#include <arm/samsung/s3c2xx0/s3c2440reg.h>
+#include <arm/samsung/s3c2xx0/s3c24x0var.h>
+#include <sys/rman.h>
+
+#define S3C2XX0_XTAL_CLK 12000000
+
+bus_space_tag_t s3c2xx0_bs_tag;
+
+#define IPL_LEVELS 13
+u_int irqmasks[IPL_LEVELS];
+
+static struct {
+	uint32_t	idcode;
+	const char	*name;
+	s3c2xx0_cpu	cpu;
+} s3c2x0_cpu_id[] = {
+	{ CHIPID_S3C2410A, "S3C2410A", CPU_S3C2410 },
+	{ CHIPID_S3C2440A, "S3C2440A", CPU_S3C2440 },
+	{ CHIPID_S3C2442B, "S3C2442B", CPU_S3C2440 },
+
+	{ 0, NULL }
+};
+
+static struct {
+	const char *name;
+	int prio;
+	int unit;
+	struct {
+		int type;
+		u_long start;
+		u_long count;
+	} res[2];
+} s3c24x0_children[] = {
+	{ "rtc", 0, -1, {
+		{ SYS_RES_IOPORT, S3C24X0_RTC_PA_BASE, S3C24X0_RTC_SIZE },
+		{ 0 },
+	} },
+	{ "timer", 0, -1, { { 0 }, } },
+	{ "uart", 1, 0, {
+		{ SYS_RES_IRQ, S3C24X0_INT_UART0, 1 },
+		{ SYS_RES_IOPORT, S3C24X0_UART_PA_BASE(0),
+		  S3C24X0_UART_BASE(1) - S3C24X0_UART_BASE(0) },
+	} },
+	{ "uart", 1, 1, {
+		{ SYS_RES_IRQ, S3C24X0_INT_UART1, 1 },
+		{ SYS_RES_IOPORT, S3C24X0_UART_PA_BASE(1),
+		  S3C24X0_UART_BASE(2) - S3C24X0_UART_BASE(1) },
+	} },
+	{ "uart", 1, 2, {
+		{ SYS_RES_IRQ, S3C24X0_INT_UART2, 1 },
+		{ SYS_RES_IOPORT, S3C24X0_UART_PA_BASE(2),
+		  S3C24X0_UART_BASE(3) - S3C24X0_UART_BASE(2) },
+	} },
+	{ "ohci", 0, -1, {
+		{ SYS_RES_IRQ, S3C24X0_INT_USBH, 0 },
+		{ SYS_RES_IOPORT, S3C24X0_USBHC_PA_BASE, S3C24X0_USBHC_SIZE },
+	} },
+	{ NULL },
+};
+
+
+/* prototypes */
+static device_t s3c24x0_add_child(device_t, int, const char *, int);
+
+static int	s3c24x0_probe(device_t);
+static int	s3c24x0_attach(device_t);
+static void	s3c24x0_identify(driver_t *, device_t);
+static int	s3c24x0_setup_intr(device_t, device_t, struct resource *, int,
+        driver_filter_t *, driver_intr_t *, void *, void **);
+static int	s3c24x0_teardown_intr(device_t, device_t, struct resource *,
+	void *);
+static int	s3c24x0_config_intr(device_t, int, enum intr_trigger,
+	enum intr_polarity);
+static struct resource *s3c24x0_alloc_resource(device_t, device_t, int, int *,
+        u_long, u_long, u_long, u_int);
+static int s3c24x0_activate_resource(device_t, device_t, int, int,
+        struct resource *);
+static int s3c24x0_release_resource(device_t, device_t, int, int,
+        struct resource *);
+static struct resource_list *s3c24x0_get_resource_list(device_t, device_t);
+
+static void s3c24x0_identify_cpu(device_t);
+
+static device_method_t s3c24x0_methods[] = {
+	DEVMETHOD(device_probe, s3c24x0_probe),
+	DEVMETHOD(device_attach, s3c24x0_attach),
+	DEVMETHOD(device_identify, s3c24x0_identify),
+	DEVMETHOD(bus_setup_intr, s3c24x0_setup_intr),
+	DEVMETHOD(bus_teardown_intr, s3c24x0_teardown_intr),
+	DEVMETHOD(bus_config_intr, s3c24x0_config_intr),
+	DEVMETHOD(bus_alloc_resource, s3c24x0_alloc_resource),
+	DEVMETHOD(bus_activate_resource, s3c24x0_activate_resource),
+	DEVMETHOD(bus_release_resource,	s3c24x0_release_resource),
+	DEVMETHOD(bus_get_resource_list,s3c24x0_get_resource_list),
+	DEVMETHOD(bus_set_resource,	bus_generic_rl_set_resource),
+	DEVMETHOD(bus_get_resource,	bus_generic_rl_get_resource),
+	{0, 0},
+};
+
+static driver_t s3c24x0_driver = {
+	"s3c24x0",
+	s3c24x0_methods,
+	sizeof(struct s3c24x0_softc),
+};
+static devclass_t s3c24x0_devclass;
+
+DRIVER_MODULE(s3c24x0, nexus, s3c24x0_driver, s3c24x0_devclass, 0, 0);
+
+struct s3c2xx0_softc *s3c2xx0_softc = NULL;
+
+static device_t
+s3c24x0_add_child(device_t bus, int prio, const char *name, int unit)
+{
+	device_t child;
+	struct s3c2xx0_ivar *ivar;
+
+	child = device_add_child_ordered(bus, prio, name, unit);
+	if (child == NULL)
+		return (NULL);
+
+	ivar = malloc(sizeof(*ivar), M_DEVBUF, M_NOWAIT | M_ZERO);
+	if (ivar == NULL) {
+		device_delete_child(bus, child);
+		printf("Can't add alloc ivar\n");
+		return (NULL);
+	}
+	device_set_ivars(child, ivar);
+	resource_list_init(&ivar->resources);
+
+	return (child);
+}
+
+static void
+s3c24x0_enable_ext_intr(unsigned int irq)
+{
+	uint32_t reg, value;
+	int offset;
+
+	if (irq <= 7) {
+		reg = GPIO_PFCON;
+		offset = irq * 2;
+	} else if (irq <= 23) {
+		reg = GPIO_PGCON;
+		offset = (irq - 8) * 2;
+	} else
+		return;
+
+	/* Make the pin an interrupt source */
+	value = bus_space_read_4(s3c2xx0_softc->sc_iot,
+	    s3c2xx0_softc->sc_gpio_ioh, reg);
+	value &= ~(3 << offset);
+	value |= 2 << offset;
+	bus_space_write_4(s3c2xx0_softc->sc_iot, s3c2xx0_softc->sc_gpio_ioh,
+	    reg, value);
+}
+
+static int
+s3c24x0_setup_intr(device_t dev, device_t child,
+        struct resource *ires,  int flags, driver_filter_t *filt,
+	driver_intr_t *intr, void *arg, void **cookiep)
+{
+	int error, irq;
+
+	error = BUS_SETUP_INTR(device_get_parent(dev), child, ires, flags, filt,
+	    intr, arg, cookiep);
+	if (error != 0)
+		return (error);
+
+	for (irq = rman_get_start(ires); irq <= rman_get_end(ires); irq++) {
+		if (irq >= S3C24X0_EXTIRQ_MIN && irq <= S3C24X0_EXTIRQ_MAX) {
+			/* Enable the external interrupt pin */
+			s3c24x0_enable_ext_intr(irq - S3C24X0_EXTIRQ_MIN);
+		}
+	}
+	return (0);
+}
+
+static int
+s3c24x0_teardown_intr(device_t dev, device_t child, struct resource *res,
+	void *cookie)
+{
+	return (BUS_TEARDOWN_INTR(device_get_parent(dev), child, res, cookie));
+}
+
+static int
+s3c24x0_config_intr(device_t dev, int irq, enum intr_trigger trig,
+	enum intr_polarity pol)
+{
+	uint32_t mask, reg, value;
+	int offset;
+
+	/* Only external interrupts can be configured */
+	if (irq < S3C24X0_EXTIRQ_MIN || irq > S3C24X0_EXTIRQ_MAX)
+		return (EINVAL);
+
+	/* There is no standard trigger or polarity for the bus */
+	if (trig == INTR_TRIGGER_CONFORM || pol == INTR_POLARITY_CONFORM)
+		return (EINVAL);
+
+	irq -= S3C24X0_EXTIRQ_MIN;
+
+	/* Get the bits to set */
+	mask = 0;
+	if (pol == INTR_POLARITY_LOW) {
+		mask = 2;
+	} else if (pol == INTR_POLARITY_HIGH) {
+		mask = 4;
+	}
+	if (trig == INTR_TRIGGER_LEVEL) {
+		mask >>= 2;
+	}
+
+	/* Get the register to set */
+	if (irq <= 7) {
+		reg = GPIO_EXTINT(0);
+		offset = irq * 4;
+	} else if (irq <= 15) {
+		reg = GPIO_EXTINT(1);
+		offset = (irq - 8) * 4;
+	} else if (irq <= 23) {
+		reg = GPIO_EXTINT(2);
+		offset = (irq - 16) * 4;
+	} else {
+		return (EINVAL);
+	}
+
+	/* Set the new signaling method */
+	value = bus_space_read_4(s3c2xx0_softc->sc_iot,
+	    s3c2xx0_softc->sc_gpio_ioh, reg);
+	value &= ~(7 << offset);
+	value |= mask << offset;
+	bus_space_write_4(s3c2xx0_softc->sc_iot,
+	    s3c2xx0_softc->sc_gpio_ioh, reg, value);
+
+	return (0);
+}
+
+static struct resource *
+s3c24x0_alloc_resource(device_t bus, device_t child, int type, int *rid,
+        u_long start, u_long end, u_long count, u_int flags)
+{
+	struct resource_list_entry *rle;
+	struct s3c2xx0_ivar *ivar = device_get_ivars(child);
+	struct resource_list *rl = &ivar->resources;
+	struct resource *res = NULL;
+
+	if (device_get_parent(child) != bus)
+		return (BUS_ALLOC_RESOURCE(device_get_parent(bus), child,
+		    type, rid, start, end, count, flags));
+
+	rle = resource_list_find(rl, type, *rid);
+	if (rle != NULL) {
+		/* There is a resource list. Use it */
+		if (rle->res)
+			panic("Resource rid %d type %d already in use", *rid,
+			    type);
+		if (start == 0UL && end == ~0UL) {
+			start = rle->start;
+			count = ulmax(count, rle->count);
+			end = ulmax(rle->end, start + count - 1);
+		}
+		/*
+		 * When allocating an irq with children irq's really
+		 * allocate the children as it is those we are interested
+		 * in receiving, not the parent.
+		 */
+		if (type == SYS_RES_IRQ && start == end) {
+			switch (start) {
+			case S3C24X0_INT_ADCTC:
+				start = S3C24X0_INT_TC;
+				end = S3C24X0_INT_ADC;
+				break;
+#ifdef S3C2440_INT_CAM
+			case S3C2440_INT_CAM:
+				start = S3C2440_INT_CAM_C;
+				end = S3C2440_INT_CAM_P;
+				break;
+#endif
+			default:
+				break;
+			}
+			count = end - start + 1;
+		}
+	}
+
+	switch (type) {
+	case SYS_RES_IRQ:
+		res = rman_reserve_resource(
+		    &s3c2xx0_softc->s3c2xx0_irq_rman, start, end,
+		    count, flags, child);
+		break;
+
+	case SYS_RES_IOPORT:
+	case SYS_RES_MEMORY:
+		res = rman_reserve_resource(
+		    &s3c2xx0_softc->s3c2xx0_mem_rman,
+		    start, end, count, flags, child);
+		if (res == NULL)
+			panic("Unable to map address space %#lX-%#lX", start,
+			    end);
+
+		rman_set_bustag(res, s3c2xx0_bs_tag);
+		rman_set_bushandle(res, start);
+		if (flags & RF_ACTIVE) {
+			if (bus_activate_resource(child, type, *rid, res)) {
+				rman_release_resource(res);
+				return (NULL);
+			}
+		}
+		break;
+	}
+
+	if (res != NULL) {
+		rman_set_rid(res, *rid);
+		if (rle != NULL) {
+			rle->res = res;
+			rle->start = rman_get_start(res);
+			rle->end = rman_get_end(res);
+			rle->count = count;
+		}
+	}
+
+	return (res);
+}
+
+static int
+s3c24x0_activate_resource(device_t bus, device_t child, int type, int rid,
+        struct resource *r)
+{
+	bus_space_handle_t p;
+	int error;
+
+	if (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) {
+		error = bus_space_map(rman_get_bustag(r),
+		    rman_get_bushandle(r), rman_get_size(r), 0, &p);
+		if (error)
+			return (error);
+		rman_set_bushandle(r, p);
+	}
+	return (rman_activate_resource(r));
+}
+
+static int
+s3c24x0_release_resource(device_t bus, device_t child, int type, int rid,
+        struct resource *r)
+{
+	struct s3c2xx0_ivar *ivar = device_get_ivars(child);
+	struct resource_list *rl = &ivar->resources;
+	struct resource_list_entry *rle;
+
+	if (rl == NULL)
+		return (EINVAL);
+
+	rle = resource_list_find(rl, type, rid);
+	if (rle == NULL)
+		return (EINVAL);
+
+	rman_release_resource(r);
+	rle->res = NULL;
+
+	return 0;
+}
+
+static struct resource_list *
+s3c24x0_get_resource_list(device_t dev, device_t child)
+{
+	struct s3c2xx0_ivar *ivar;
+
+	ivar = device_get_ivars(child);
+	return (&(ivar->resources));
+}
+
+void
+s3c24x0_identify(driver_t *driver, device_t parent)
+{
+	
+	BUS_ADD_CHILD(parent, 0, "s3c24x0", 0);
+}
+
+int
+s3c24x0_probe(device_t dev)
+{
+	return (BUS_PROBE_NOWILDCARD);
+}
+
+int
+s3c24x0_attach(device_t dev)
+{
+	struct s3c24x0_softc *sc = device_get_softc(dev);
+	bus_space_tag_t iot;
+	device_t child;
+	unsigned int i, j;
+	u_long irqmax;
+
+	s3c2xx0_bs_tag = arm_base_bs_tag;
+	s3c2xx0_softc = &(sc->sc_sx);
+	sc->sc_sx.sc_iot = iot = s3c2xx0_bs_tag;
+	s3c2xx0_softc->s3c2xx0_irq_rman.rm_type = RMAN_ARRAY;
+	s3c2xx0_softc->s3c2xx0_irq_rman.rm_descr = "S3C24X0 IRQs";
+	s3c2xx0_softc->s3c2xx0_mem_rman.rm_type = RMAN_ARRAY;
+	s3c2xx0_softc->s3c2xx0_mem_rman.rm_descr = "S3C24X0 Device Registers";
+	/* Manage the registor memory space */
+	if ((rman_init(&s3c2xx0_softc->s3c2xx0_mem_rman) != 0) ||
+	    (rman_manage_region(&s3c2xx0_softc->s3c2xx0_mem_rman,
+	      S3C24X0_DEV_VA_OFFSET,
+	      S3C24X0_DEV_VA_OFFSET + S3C24X0_DEV_VA_SIZE) != 0) ||
+	    (rman_manage_region(&s3c2xx0_softc->s3c2xx0_mem_rman,
+	      S3C24X0_DEV_START, S3C24X0_DEV_STOP) != 0))
+		panic("s3c24x0_attach: failed to set up register rman");
+
+	/* These are needed for things without a proper device to attach to */
+	sc->sc_sx.sc_intctl_ioh = S3C24X0_INTCTL_BASE;
+	sc->sc_sx.sc_gpio_ioh = S3C24X0_GPIO_BASE;
+	sc->sc_sx.sc_clkman_ioh = S3C24X0_CLKMAN_BASE;
+	sc->sc_sx.sc_wdt_ioh = S3C24X0_WDT_BASE;
+	sc->sc_timer_ioh = S3C24X0_TIMER_BASE;
+
+	/*
+	 * Identify the CPU
+	 */
+	s3c24x0_identify_cpu(dev);
+
+	/*
+	 * Manage the interrupt space.
+	 * We need to put this after s3c24x0_identify_cpu as the avaliable
+	 * interrupts change depending on which CPU we have.
+	 */
+	if (sc->sc_sx.sc_cpu == CPU_S3C2410)
+		irqmax = S3C2410_SUBIRQ_MAX;
+	else
+		irqmax = S3C2440_SUBIRQ_MAX;
+	if (rman_init(&s3c2xx0_softc->s3c2xx0_irq_rman) != 0 ||
+	    rman_manage_region(&s3c2xx0_softc->s3c2xx0_irq_rman, 0,
+	    irqmax) != 0 ||
+	    rman_manage_region(&s3c2xx0_softc->s3c2xx0_irq_rman,
+	    S3C24X0_EXTIRQ_MIN, S3C24X0_EXTIRQ_MAX))
+		panic("s3c24x0_attach: failed to set up IRQ rman");
+
+	/* calculate current clock frequency */
+	s3c24x0_clock_freq(&sc->sc_sx);
+	device_printf(dev, "fclk %d MHz hclk %d MHz pclk %d MHz\n",
+	       sc->sc_sx.sc_fclk / 1000000, sc->sc_sx.sc_hclk / 1000000,
+	       sc->sc_sx.sc_pclk / 1000000);
+
+	/*
+	 * Attach children devices
+	 */
+
+	for (i = 0; s3c24x0_children[i].name != NULL; i++) {
+		child = s3c24x0_add_child(dev, s3c24x0_children[i].prio,
+		    s3c24x0_children[i].name, s3c24x0_children[i].unit);
+		for (j = 0; j < sizeof(s3c24x0_children[i].res) /
+		     sizeof(s3c24x0_children[i].res[0]) &&
+		     s3c24x0_children[i].res[j].type != 0; j++) {
+			bus_set_resource(child,
+			    s3c24x0_children[i].res[j].type, 0,
+			    s3c24x0_children[i].res[j].start,
+			    s3c24x0_children[i].res[j].count);
+		}
+	}
+
+	bus_generic_probe(dev);
+	bus_generic_attach(dev);
+
+	return (0);
+}
+
+static void
+s3c24x0_identify_cpu(device_t dev)
+{
+	struct s3c24x0_softc *sc = device_get_softc(dev);
+	uint32_t idcode;
+	int i;
+
+	idcode = bus_space_read_4(sc->sc_sx.sc_iot, sc->sc_sx.sc_gpio_ioh,
+	    GPIO_GSTATUS1);
+
+	for (i = 0; s3c2x0_cpu_id[i].name != NULL; i++) {
+		if (s3c2x0_cpu_id[i].idcode == idcode)
+			break;
+	}
+	if (s3c2x0_cpu_id[i].name == NULL)
+		panic("Unknown CPU detected ((Chip ID: %#X)", idcode);
+	device_printf(dev, "Found %s CPU (Chip ID: %#X)\n",
+	    s3c2x0_cpu_id[i].name, idcode);
+	sc->sc_sx.sc_cpu = s3c2x0_cpu_id[i].cpu;
+}
+
+/*
+ * fill sc_pclk, sc_hclk, sc_fclk from values of clock controller register.
+ *
+ * s3c24{1,4}0_clock_freq2() is meant to be called from kernel startup routines.
+ * s3c24x0_clock_freq() is for after kernel initialization is done.
+ *
+ * Because they can be called before bus_space is available we need to use
+ * volatile pointers rather than bus_space_read.
+ */
+void
+s3c2410_clock_freq2(vm_offset_t clkman_base, int *fclk, int *hclk, int *pclk)
+{
+	uint32_t pllcon, divn;
+	unsigned int mdiv, pdiv, sdiv;
+	unsigned int f, h, p;
+
+	pllcon = *(volatile uint32_t *)(clkman_base + CLKMAN_MPLLCON);
+	divn = *(volatile uint32_t *)(clkman_base + CLKMAN_CLKDIVN);
+
+	mdiv = (pllcon & PLLCON_MDIV_MASK) >> PLLCON_MDIV_SHIFT;
+	pdiv = (pllcon & PLLCON_PDIV_MASK) >> PLLCON_PDIV_SHIFT;
+	sdiv = (pllcon & PLLCON_SDIV_MASK) >> PLLCON_SDIV_SHIFT;
+
+	f = ((mdiv + 8) * S3C2XX0_XTAL_CLK) / ((pdiv + 2) * (1 << sdiv));
+	h = f;
+	if (divn & S3C2410_CLKDIVN_HDIVN)
+		h /= 2;
+	p = h;
+	if (divn & CLKDIVN_PDIVN)
+		p /= 2;
+
+	if (fclk) *fclk = f;
+	if (hclk) *hclk = h;
+	if (pclk) *pclk = p;
+}
+
+void
+s3c2440_clock_freq2(vm_offset_t clkman_base, int *fclk, int *hclk, int *pclk)
+{
+	uint32_t pllcon, divn, camdivn;
+	unsigned int mdiv, pdiv, sdiv;
+	unsigned int f, h, p;
+
+	pllcon = *(volatile uint32_t *)(clkman_base + CLKMAN_MPLLCON);
+	divn = *(volatile uint32_t *)(clkman_base + CLKMAN_CLKDIVN);
+	camdivn = *(volatile uint32_t *)(clkman_base + S3C2440_CLKMAN_CAMDIVN);
+
+	mdiv = (pllcon & PLLCON_MDIV_MASK) >> PLLCON_MDIV_SHIFT;
+	pdiv = (pllcon & PLLCON_PDIV_MASK) >> PLLCON_PDIV_SHIFT;
+	sdiv = (pllcon & PLLCON_SDIV_MASK) >> PLLCON_SDIV_SHIFT;
+
+	f = (2 * (mdiv + 8) * S3C2XX0_XTAL_CLK) / ((pdiv + 2) * (1 << sdiv));
+	h = f;
+	switch((divn >> 1) & 3) {
+	case 0:
+		break;
+	case 1:
+		h /= 2;
+		break;
+	case 2:
+		if ((camdivn & S3C2440_CAMDIVN_HCLK4_HALF) ==
+		    S3C2440_CAMDIVN_HCLK4_HALF)
+			h /= 8;
+		else
+			h /= 4;
+		break;
+	case 3:
+		if ((camdivn & S3C2440_CAMDIVN_HCLK3_HALF) ==
+		    S3C2440_CAMDIVN_HCLK3_HALF)
+			h /= 6;
+		else
+			h /= 3;
+		break;
+	}
+	p = h;
+	if (divn & CLKDIVN_PDIVN)
+		p /= 2;
+
+	if (fclk) *fclk = f;
+	if (hclk) *hclk = h;
+	if (pclk) *pclk = p;
+}
+
+void
+s3c24x0_clock_freq(struct s3c2xx0_softc *sc)
+{
+	vm_offset_t va;
+	
+	va = sc->sc_clkman_ioh;
+	switch(sc->sc_cpu) {
+	case CPU_S3C2410:
+		s3c2410_clock_freq2(va, &sc->sc_fclk, &sc->sc_hclk,
+		    &sc->sc_pclk);
+		break;
+	case CPU_S3C2440:
+		s3c2440_clock_freq2(va, &sc->sc_fclk, &sc->sc_hclk,
+		    &sc->sc_pclk);
+		break;
+	}
+}
+
+void
+cpu_reset(void)
+{
+	(void) disable_interrupts(PSR_I|PSR_F);
+
+	bus_space_write_4(s3c2xx0_bs_tag, s3c2xx0_softc->sc_wdt_ioh, WDT_WTCON,
+	    WTCON_ENABLE | WTCON_CLKSEL_16 | WTCON_ENRST);
+	for(;;);
+}
+
+void
+s3c24x0_sleep(int mode __unused)
+{
+	int reg;
+
+	reg = bus_space_read_4(s3c2xx0_bs_tag, s3c2xx0_softc->sc_clkman_ioh,
+	    CLKMAN_CLKCON);
+	bus_space_write_4(s3c2xx0_bs_tag, s3c2xx0_softc->sc_clkman_ioh,
+	    CLKMAN_CLKCON, reg | CLKCON_IDLE);
+}
+
+
+int
+arm_get_next_irq(int last __unused)
+{
+	uint32_t intpnd;
+	int irq, subirq;
+
+	if ((irq = bus_space_read_4(s3c2xx0_bs_tag,
+	    s3c2xx0_softc->sc_intctl_ioh, INTCTL_INTOFFSET)) != 0) {
+
+		/* Clear the pending bit */
+		intpnd = bus_space_read_4(s3c2xx0_bs_tag,
+		    s3c2xx0_softc->sc_intctl_ioh, INTCTL_INTPND);
+		bus_space_write_4(s3c2xx0_bs_tag, s3c2xx0_softc->sc_intctl_ioh,
+		    INTCTL_SRCPND, intpnd);
+		bus_space_write_4(s3c2xx0_bs_tag, s3c2xx0_softc->sc_intctl_ioh,
+		    INTCTL_INTPND, intpnd);
+
+		switch (irq) {
+		case S3C24X0_INT_ADCTC:
+		case S3C24X0_INT_UART0:
+		case S3C24X0_INT_UART1:
+		case S3C24X0_INT_UART2:
+			/* Find the sub IRQ */
+			subirq = 0x7ff;
+			subirq &= bus_space_read_4(s3c2xx0_bs_tag,
+			    s3c2xx0_softc->sc_intctl_ioh, INTCTL_SUBSRCPND);
+			subirq &= ~(bus_space_read_4(s3c2xx0_bs_tag,
+			    s3c2xx0_softc->sc_intctl_ioh, INTCTL_INTSUBMSK));
+			if (subirq == 0)
+				return (irq);
+
+			subirq = ffs(subirq) - 1;
+
+			/* Clear the sub irq pending bit */
+			bus_space_write_4(s3c2xx0_bs_tag,
+			    s3c2xx0_softc->sc_intctl_ioh, INTCTL_SUBSRCPND,
+			    (1 << subirq));
+
+			/*
+			 * Return the parent IRQ for UART
+			 * as it is all we ever need
+			 */
+			if (subirq <= 8)
+				return (irq);
+
+			return (S3C24X0_SUBIRQ_MIN + subirq);
+
+		case S3C24X0_INT_0:
+		case S3C24X0_INT_1:
+		case S3C24X0_INT_2:
+		case S3C24X0_INT_3:
+			/* There is a 1:1 mapping to the IRQ we are handling */
+			return S3C24X0_INT_EXT(irq);
+
+		case S3C24X0_INT_4_7:
+		case S3C24X0_INT_8_23:
+			/* Find the external interrupt being called */
+			subirq = 0x7fffff;
+			subirq &= bus_space_read_4(s3c2xx0_bs_tag,
+			    s3c2xx0_softc->sc_gpio_ioh, GPIO_EINTPEND);
+			subirq &= ~bus_space_read_4(s3c2xx0_bs_tag,
+			    s3c2xx0_softc->sc_gpio_ioh, GPIO_EINTMASK);
+			if (subirq == 0)
+				return (irq);
+
+			subirq = ffs(subirq) - 1;
+
+			/* Clear the external irq pending bit */
+			bus_space_write_4(s3c2xx0_bs_tag,
+			    s3c2xx0_softc->sc_gpio_ioh, GPIO_EINTPEND,
+			    (1 << subirq));
+
+			return S3C24X0_INT_EXT(subirq);
+		}
+
+		return (irq);
+	}
+	return (-1);
+}
+
+void
+arm_mask_irq(uintptr_t irq)
+{
+	u_int32_t mask;
+
+	if (irq >= S3C24X0_INT_EXT(0) && irq <= S3C24X0_INT_EXT(3)) {
+		/* External interrupt 0..3 are directly mapped to irq 0..3 */
+		irq -= S3C24X0_EXTIRQ_MIN;
+	}
+	if (irq < S3C24X0_SUBIRQ_MIN) {
+		mask = bus_space_read_4(s3c2xx0_bs_tag,
+		    s3c2xx0_softc->sc_intctl_ioh, INTCTL_INTMSK);
+		mask |= (1 << irq);
+		bus_space_write_4(s3c2xx0_bs_tag,
+		    s3c2xx0_softc->sc_intctl_ioh, INTCTL_INTMSK, mask);
+	} else if (irq < S3C24X0_EXTIRQ_MIN) {
+		mask = bus_space_read_4(s3c2xx0_bs_tag,
+		    s3c2xx0_softc->sc_intctl_ioh, INTCTL_INTSUBMSK);
+		mask |= (1 << (irq - S3C24X0_SUBIRQ_MIN));
+		bus_space_write_4(s3c2xx0_bs_tag,
+		    s3c2xx0_softc->sc_intctl_ioh, INTCTL_INTSUBMSK, mask);
+	} else {
+		mask = bus_space_read_4(s3c2xx0_bs_tag,
+		    s3c2xx0_softc->sc_gpio_ioh, GPIO_EINTMASK);
+		mask |= (1 << (irq - S3C24X0_EXTIRQ_MIN));
+		bus_space_write_4(s3c2xx0_bs_tag,
+		    s3c2xx0_softc->sc_intctl_ioh, GPIO_EINTMASK, mask);
+	}
+}
+
+void
+arm_unmask_irq(uintptr_t irq)
+{
+	u_int32_t mask;
+
+	if (irq >= S3C24X0_INT_EXT(0) && irq <= S3C24X0_INT_EXT(3)) {
+		/* External interrupt 0..3 are directly mapped to irq 0..3 */
+		irq -= S3C24X0_EXTIRQ_MIN;
+	}
+	if (irq < S3C24X0_SUBIRQ_MIN) {
+		mask = bus_space_read_4(s3c2xx0_bs_tag,
+		    s3c2xx0_softc->sc_intctl_ioh, INTCTL_INTMSK);
+		mask &= ~(1 << irq);
+		bus_space_write_4(s3c2xx0_bs_tag,
+		    s3c2xx0_softc->sc_intctl_ioh, INTCTL_INTMSK, mask);
+	} else if (irq < S3C24X0_EXTIRQ_MIN) {
+		mask = bus_space_read_4(s3c2xx0_bs_tag,
+		    s3c2xx0_softc->sc_intctl_ioh, INTCTL_INTSUBMSK);
+		mask &= ~(1 << (irq - S3C24X0_SUBIRQ_MIN));
+		bus_space_write_4(s3c2xx0_bs_tag,
+		    s3c2xx0_softc->sc_intctl_ioh, INTCTL_INTSUBMSK, mask);
+	} else {
+		mask = bus_space_read_4(s3c2xx0_bs_tag,
+		    s3c2xx0_softc->sc_gpio_ioh, GPIO_EINTMASK);
+		mask &= ~(1 << (irq - S3C24X0_EXTIRQ_MIN));
+		bus_space_write_4(s3c2xx0_bs_tag,
+		    s3c2xx0_softc->sc_intctl_ioh, GPIO_EINTMASK, mask);
+	}
+}


Property changes on: trunk/sys/arm/samsung/s3c2xx0/s3c24x0.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/samsung/s3c2xx0/s3c24x0_clk.c
===================================================================
--- trunk/sys/arm/samsung/s3c2xx0/s3c24x0_clk.c	                        (rev 0)
+++ trunk/sys/arm/samsung/s3c2xx0/s3c24x0_clk.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,288 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: s3c24x0_clk.c,v 1.6 2005/12/24 20:06:52 perry Exp $ */
+
+/*
+ * Copyright (c) 2003  Genetec corporation.  All rights reserved.
+ * Written by Hiroyuki Bessho for Genetec corporation.
+ *
+ * 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.
+ * 3. The name of Genetec corporation may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GENETEC CORP. ``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 GENETEC CORP.
+ * 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: stable/10/sys/arm/samsung/s3c2xx0/s3c24x0_clk.c 272103 2014-09-25 11:38:26Z gavin $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/time.h>
+#include <sys/bus.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+#include <sys/timetc.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+#include <machine/frame.h>
+#include <machine/resource.h>
+#include <machine/intr.h>
+#include <arm/samsung/s3c2xx0/s3c24x0reg.h>
+#include <arm/samsung/s3c2xx0/s3c24x0var.h>
+
+struct s3c24x0_timer_softc {
+	device_t	dev;
+} timer_softc;
+
+static unsigned s3c24x0_timer_get_timecount(struct timecounter *tc);
+
+static struct timecounter s3c24x0_timer_timecounter = {
+	s3c24x0_timer_get_timecount,	/* get_timecount */
+	NULL,				/* no poll_pps */
+	~0u,				/* counter_mask */
+	3686400,			/* frequency */
+	"s3c24x0 timer",		/* name */
+	1000				/* quality */
+};
+
+static int
+s3c24x0_timer_probe(device_t dev)
+{
+
+	device_set_desc(dev, "s3c24x0 timer");
+	return (0);
+}
+
+static int
+s3c24x0_timer_attach(device_t dev)
+{
+	timer_softc.dev = dev;
+
+	/* We need to do this here for devices that expect DELAY to work */
+	return (0);
+}
+
+static device_method_t s3c24x0_timer_methods[] = {
+	DEVMETHOD(device_probe, s3c24x0_timer_probe),
+	DEVMETHOD(device_attach, s3c24x0_timer_attach),
+	{0, 0},
+};
+
+static driver_t s3c24x0_timer_driver = {
+	"timer",
+	s3c24x0_timer_methods,
+	sizeof(struct s3c24x0_timer_softc),
+};
+static devclass_t s3c24x0_timer_devclass;
+
+DRIVER_MODULE(s3c24x0timer, s3c24x0, s3c24x0_timer_driver,
+    s3c24x0_timer_devclass, 0, 0);
+
+#define TIMER_FREQUENCY(pclk) ((pclk)/16) /* divider=1/16 */
+
+static unsigned int timer4_reload_value;
+static unsigned int timer4_prescaler;
+static unsigned int timer4_mseccount;
+static volatile uint32_t s3c24x0_base;
+
+#define usec_to_counter(t)	\
+	((timer4_mseccount*(t))/1000)
+
+#define counter_to_usec(c,pclk)	\
+	(((c)*timer4_prescaler*1000)/(TIMER_FREQUENCY(pclk)/1000))
+
+static inline int
+read_timer(struct s3c24x0_softc *sc)
+{
+	int count;
+
+	do {
+		count = bus_space_read_2(sc->sc_sx.sc_iot, sc->sc_timer_ioh,
+		    TIMER_TCNTO(4));
+	} while ( __predict_false(count > timer4_reload_value) );
+
+	return count;
+}
+
+static unsigned
+s3c24x0_timer_get_timecount(struct timecounter *tc)
+{
+	struct s3c24x0_softc *sc = (struct s3c24x0_softc *)s3c2xx0_softc;
+	int value;
+
+	value = bus_space_read_2(sc->sc_sx.sc_iot, sc->sc_timer_ioh,
+	    TIMER_TCNTO(4));
+	return (s3c24x0_base - value);
+}
+
+static int
+clock_intr(void *arg)
+{
+	struct trapframe *fp = arg;
+
+	atomic_add_32(&s3c24x0_base, timer4_reload_value);
+
+	hardclock(TRAPF_USERMODE(fp), TRAPF_PC(fp));
+	return (FILTER_HANDLED);
+}
+
+void
+cpu_initclocks(void)
+{
+	struct s3c24x0_softc *sc = (struct s3c24x0_softc *)s3c2xx0_softc;
+	long tc;
+	struct resource *irq;
+	int rid = 0;
+	void *ihl;
+	int err, prescaler;
+	int pclk = s3c2xx0_softc->sc_pclk;
+	bus_space_tag_t iot = sc->sc_sx.sc_iot;
+	bus_space_handle_t ioh = sc->sc_timer_ioh;
+	uint32_t  reg;
+	device_t dev = timer_softc.dev;
+
+	/* We have already been initialized */
+	if (timer4_reload_value != 0)
+		return;
+
+#define	time_constant(hz)	(TIMER_FREQUENCY(pclk) /(hz)/ prescaler)
+#define calc_time_constant(hz)					\
+	do {							\
+		prescaler = 1;					\
+		do {						\
+			++prescaler;				\
+			tc = time_constant(hz);			\
+		} while( tc > 65536 );				\
+	} while(0)
+
+
+	/* Use the channels 4 and 3 for hardclock and statclock, respectively */
+
+	/* stop all timers */
+	bus_space_write_4(iot, ioh, TIMER_TCON, 0);
+
+	/* calc suitable prescaler value */
+	calc_time_constant(hz);
+
+	timer4_prescaler = prescaler;
+	timer4_reload_value = TIMER_FREQUENCY(pclk) / hz / prescaler;
+	timer4_mseccount = TIMER_FREQUENCY(pclk)/timer4_prescaler/1000 ;
+
+	bus_space_write_4(iot, ioh, TIMER_TCNTB(4),
+	    ((prescaler - 1) << 16) | (timer4_reload_value - 1));
+
+	printf("clock: hz=%d PCLK=%d prescaler=%d tc=%ld\n",
+	    hz, pclk, prescaler, tc);
+
+	irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, S3C24X0_INT_TIMER4,
+		S3C24X0_INT_TIMER4, 1, RF_ACTIVE);
+	if (!irq)
+		panic("Unable to allocate the clock irq handler.\n");
+
+	err = bus_setup_intr(dev, irq, INTR_TYPE_CLK,
+	    clock_intr, NULL, NULL, &ihl);
+	if (err != 0)
+		panic("Unable to setup the clock irq handler.\n");
+
+	/* set prescaler1 */
+	reg = bus_space_read_4(iot, ioh, TIMER_TCFG0);
+	bus_space_write_4(iot, ioh, TIMER_TCFG0,
+			  (reg & ~0xff00) | ((prescaler-1) << 8));
+
+	/* divider 1/16 for ch #4 */
+	reg = bus_space_read_4(iot, ioh, TIMER_TCFG1);
+	bus_space_write_4(iot, ioh, TIMER_TCFG1,
+			  (reg & ~(TCFG1_MUX_MASK(4))) |
+			  (TCFG1_MUX_DIV16 << TCFG1_MUX_SHIFT(4)) );
+
+
+	/* start timers */
+	reg = bus_space_read_4(iot, ioh, TIMER_TCON);
+	reg &= ~(TCON_MASK(4));
+
+	/* load the time constant */
+	bus_space_write_4(iot, ioh, TIMER_TCON, reg | TCON_MANUALUPDATE(4));
+	/* set auto reload and start */
+	bus_space_write_4(iot, ioh, TIMER_TCON, reg |
+	    TCON_AUTORELOAD(4) | TCON_START(4) );
+
+	s3c24x0_timer_timecounter.tc_frequency = TIMER_FREQUENCY(pclk) /
+	    timer4_prescaler;
+	tc_init(&s3c24x0_timer_timecounter);
+}
+
+/*
+ * DELAY:
+ *
+ *	Delay for at least N microseconds.
+ */
+void
+DELAY(int n)
+{
+	struct s3c24x0_softc *sc = (struct s3c24x0_softc *) s3c2xx0_softc;
+	int v0, v1, delta;
+	u_int ucnt;
+
+	if (timer4_reload_value == 0) {
+		/* not initialized yet */
+		while ( n-- > 0 ){
+			int m;
+
+			for (m = 0; m < 100; ++m )
+				;
+		}
+		return;
+	}
+
+	/* read down counter */
+	v0 = read_timer(sc);
+
+	ucnt = usec_to_counter(n);
+
+	while( ucnt > 0 ) {
+		v1 = read_timer(sc);
+		delta = v0 - v1;
+		if ( delta < 0 )
+			delta += timer4_reload_value;
+
+		if((u_int)delta < ucnt){
+			ucnt -= (u_int)delta;
+			v0 = v1;
+		}
+		else {
+			ucnt = 0;
+		}
+	}
+}
+
+void
+cpu_startprofclock(void)
+{
+}
+
+void
+cpu_stopprofclock(void)
+{
+}


Property changes on: trunk/sys/arm/samsung/s3c2xx0/s3c24x0_clk.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/samsung/s3c2xx0/s3c24x0_machdep.c
===================================================================
--- trunk/sys/arm/samsung/s3c2xx0/s3c24x0_machdep.c	                        (rev 0)
+++ trunk/sys/arm/samsung/s3c2xx0/s3c24x0_machdep.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,405 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1994-1998 Mark Brinicombe.
+ * Copyright (c) 1994 Brini.
+ * All rights reserved.
+ *
+ * This code is derived from software written for Brini by Mark Brinicombe
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by Brini.
+ * 4. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BRINI ``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 BRINI 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.
+ *
+ * RiscBSD kernel project
+ *
+ * machdep.c
+ *
+ * Machine dependant functions for kernel setup
+ *
+ * This file needs a lot of work.
+ *
+ * Created      : 17/09/94
+ */
+
+#include "opt_ddb.h"
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/samsung/s3c2xx0/s3c24x0_machdep.c 272103 2014-09-25 11:38:26Z gavin $");
+
+#define _ARM32_BUS_DMA_PRIVATE
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/sysproto.h>
+#include <sys/signalvar.h>
+#include <sys/imgact.h>
+#include <sys/kernel.h>
+#include <sys/ktr.h>
+#include <sys/linker.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/mutex.h>
+#include <sys/pcpu.h>
+#include <sys/proc.h>
+#include <sys/ptrace.h>
+#include <sys/cons.h>
+#include <sys/bio.h>
+#include <sys/bus.h>
+#include <sys/buf.h>
+#include <sys/exec.h>
+#include <sys/kdb.h>
+#include <sys/msgbuf.h>
+#include <machine/physmem.h>
+#include <machine/reg.h>
+#include <machine/cpu.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/vm_object.h>
+#include <vm/vm_page.h>
+#include <vm/vm_map.h>
+#include <machine/devmap.h>
+#include <machine/vmparam.h>
+#include <machine/pcb.h>
+#include <machine/undefined.h>
+#include <machine/machdep.h>
+#include <machine/metadata.h>
+#include <machine/armreg.h>
+#include <machine/bus.h>
+#include <sys/reboot.h>
+
+#include <arm/samsung/s3c2xx0/s3c24x0var.h>
+#include <arm/samsung/s3c2xx0/s3c2410reg.h>
+#include <arm/samsung/s3c2xx0/s3c2xx0board.h>
+
+/* Page table for mapping proc0 zero page */
+#define KERNEL_PT_SYS		0
+#define KERNEL_PT_KERN		1	
+#define KERNEL_PT_KERN_NUM	44
+/* L2 table for mapping after kernel */
+#define KERNEL_PT_AFKERNEL	KERNEL_PT_KERN + KERNEL_PT_KERN_NUM
+#define	KERNEL_PT_AFKERNEL_NUM	5
+
+/* this should be evenly divisable by PAGE_SIZE / L2_TABLE_SIZE_REAL (or 4) */
+#define NUM_KERNEL_PTS		(KERNEL_PT_AFKERNEL + KERNEL_PT_AFKERNEL_NUM)
+
+extern int s3c2410_pclk;
+
+struct pv_addr kernel_pt_table[NUM_KERNEL_PTS];
+
+/* Physical and virtual addresses for some global pages */
+
+struct pv_addr systempage;
+struct pv_addr msgbufpv;
+struct pv_addr irqstack;
+struct pv_addr undstack;
+struct pv_addr abtstack;
+struct pv_addr kernelstack;
+
+#define	_A(a)	((a) & ~L1_S_OFFSET)
+#define	_S(s)	(((s) + L1_S_SIZE - 1) & ~(L1_S_SIZE-1))
+
+/* Static device mappings. */
+static const struct arm_devmap_entry s3c24x0_devmap[] = {
+	/*
+	 * Map the devices we need early on.
+	 */
+	{
+		_A(S3C24X0_CLKMAN_BASE),
+		_A(S3C24X0_CLKMAN_PA_BASE),
+		_S(S3C24X0_CLKMAN_SIZE),
+		VM_PROT_READ|VM_PROT_WRITE,
+		PTE_DEVICE,
+	},
+	{
+		_A(S3C24X0_GPIO_BASE),
+		_A(S3C24X0_GPIO_PA_BASE),
+		_S(S3C2410_GPIO_SIZE),
+		VM_PROT_READ|VM_PROT_WRITE,
+		PTE_DEVICE,
+	},
+	{
+		_A(S3C24X0_INTCTL_BASE),
+		_A(S3C24X0_INTCTL_PA_BASE),
+		_S(S3C24X0_INTCTL_SIZE),
+		VM_PROT_READ|VM_PROT_WRITE,
+		PTE_DEVICE,
+	},
+	{
+		_A(S3C24X0_TIMER_BASE),
+		_A(S3C24X0_TIMER_PA_BASE),
+		_S(S3C24X0_TIMER_SIZE),
+		VM_PROT_READ|VM_PROT_WRITE,
+		PTE_DEVICE,
+	},
+	{
+		_A(S3C24X0_UART0_BASE),
+		_A(S3C24X0_UART0_PA_BASE),
+		_S(S3C24X0_UART_PA_BASE(3) - S3C24X0_UART0_PA_BASE),
+		VM_PROT_READ|VM_PROT_WRITE,
+		PTE_DEVICE,
+	},
+	{
+		_A(S3C24X0_WDT_BASE),
+		_A(S3C24X0_WDT_PA_BASE),
+		_S(S3C24X0_WDT_SIZE),
+		VM_PROT_READ|VM_PROT_WRITE,
+		PTE_DEVICE,
+	},
+	{
+		0,
+		0,
+		0,
+		0,
+		0,
+	}
+};
+
+#undef	_A
+#undef	_S
+
+#define	ioreg_read32(a)  	(*(volatile uint32_t *)(a))
+#define	ioreg_write32(a,v)	(*(volatile uint32_t *)(a)=(v))
+
+struct arm32_dma_range s3c24x0_range = {
+	.dr_sysbase = 0,
+	.dr_busbase = 0,
+	.dr_len = 0,
+};
+
+struct arm32_dma_range *
+bus_dma_get_range(void)
+{
+
+	if (s3c24x0_range.dr_len == 0) {
+		s3c24x0_range.dr_sysbase = dump_avail[0];
+		s3c24x0_range.dr_busbase = dump_avail[0];
+		s3c24x0_range.dr_len = dump_avail[1] - dump_avail[0];
+	}
+	return (&s3c24x0_range);
+}
+
+int
+bus_dma_get_range_nb(void)
+{
+	return (1);
+}
+
+void *
+initarm(struct arm_boot_params *abp)
+{
+	struct pv_addr	kernel_l1pt;
+	int loop;
+	u_int l1pagetable;
+	vm_offset_t freemempos;
+	vm_offset_t afterkern;
+	vm_offset_t lastaddr;
+
+	int i;
+	uint32_t memsize;
+
+	boothowto = 0;  /* Likely not needed */
+	lastaddr = parse_boot_param(abp);
+	arm_physmem_kernaddr = abp->abp_physaddr;
+	i = 0;
+	set_cpufuncs();
+	cpufuncs.cf_sleep = s3c24x0_sleep;
+
+	pcpu0_init();
+
+	/* Do basic tuning, hz etc */
+	init_param1();
+
+#define KERNEL_TEXT_BASE (KERNBASE)
+	freemempos = (lastaddr + PAGE_MASK) & ~PAGE_MASK;
+	/* Define a macro to simplify memory allocation */
+#define valloc_pages(var, np)			\
+	alloc_pages((var).pv_va, (np));		\
+	(var).pv_pa = (var).pv_va + (abp->abp_physaddr - KERNVIRTADDR);
+
+#define alloc_pages(var, np)			\
+	(var) = freemempos;			\
+	freemempos += (np * PAGE_SIZE);		\
+	memset((char *)(var), 0, ((np) * PAGE_SIZE));
+
+	while (((freemempos - L1_TABLE_SIZE) & (L1_TABLE_SIZE - 1)) != 0)
+		freemempos += PAGE_SIZE;
+	valloc_pages(kernel_l1pt, L1_TABLE_SIZE / PAGE_SIZE);
+	for (loop = 0; loop < NUM_KERNEL_PTS; ++loop) {
+		if (!(loop % (PAGE_SIZE / L2_TABLE_SIZE_REAL))) {
+			valloc_pages(kernel_pt_table[loop],
+			    L2_TABLE_SIZE / PAGE_SIZE);
+		} else {
+			kernel_pt_table[loop].pv_va = freemempos -
+			    (loop % (PAGE_SIZE / L2_TABLE_SIZE_REAL)) *
+			    L2_TABLE_SIZE_REAL;
+			kernel_pt_table[loop].pv_pa =
+			    kernel_pt_table[loop].pv_va - KERNVIRTADDR +
+			    abp->abp_physaddr;
+		}
+	}
+	/*
+	 * Allocate a page for the system page mapped to V0x00000000
+	 * This page will just contain the system vectors and can be
+	 * shared by all processes.
+	 */
+	valloc_pages(systempage, 1);
+
+	/* Allocate stacks for all modes */
+	valloc_pages(irqstack, IRQ_STACK_SIZE);
+	valloc_pages(abtstack, ABT_STACK_SIZE);
+	valloc_pages(undstack, UND_STACK_SIZE);
+	valloc_pages(kernelstack, KSTACK_PAGES);
+	valloc_pages(msgbufpv, round_page(msgbufsize) / PAGE_SIZE);
+	/*
+	 * Now we start construction of the L1 page table
+	 * We start by mapping the L2 page tables into the L1.
+	 * This means that we can replace L1 mappings later on if necessary
+	 */
+	l1pagetable = kernel_l1pt.pv_va;
+
+	/* Map the L2 pages tables in the L1 page table */
+	pmap_link_l2pt(l1pagetable, ARM_VECTORS_HIGH,
+	    &kernel_pt_table[KERNEL_PT_SYS]);
+	for (i = 0; i < KERNEL_PT_KERN_NUM; i++)
+		pmap_link_l2pt(l1pagetable, KERNBASE + i * L1_S_SIZE,
+		    &kernel_pt_table[KERNEL_PT_KERN + i]);
+	pmap_map_chunk(l1pagetable, KERNBASE, PHYSADDR,
+	   (((uint32_t)(lastaddr) - KERNBASE) + PAGE_SIZE) & ~(PAGE_SIZE - 1),
+	    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+	afterkern = round_page((lastaddr + L1_S_SIZE) & ~(L1_S_SIZE
+	    - 1));
+	for (i = 0; i < KERNEL_PT_AFKERNEL_NUM; i++) {
+		pmap_link_l2pt(l1pagetable, afterkern + i * L1_S_SIZE,
+		    &kernel_pt_table[KERNEL_PT_AFKERNEL + i]);
+	}
+
+	/* Map the vector page. */
+	pmap_map_entry(l1pagetable, ARM_VECTORS_HIGH, systempage.pv_pa,
+	    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+	/* Map the stack pages */
+	pmap_map_chunk(l1pagetable, irqstack.pv_va, irqstack.pv_pa,
+	    IRQ_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+	pmap_map_chunk(l1pagetable, abtstack.pv_va, abtstack.pv_pa,
+	    ABT_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+	pmap_map_chunk(l1pagetable, undstack.pv_va, undstack.pv_pa,
+	    UND_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+	pmap_map_chunk(l1pagetable, kernelstack.pv_va, kernelstack.pv_pa,
+	    KSTACK_PAGES * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+
+	pmap_map_chunk(l1pagetable, kernel_l1pt.pv_va, kernel_l1pt.pv_pa,
+	    L1_TABLE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE);
+	pmap_map_chunk(l1pagetable, msgbufpv.pv_va, msgbufpv.pv_pa,
+	    msgbufsize, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+
+
+	for (loop = 0; loop < NUM_KERNEL_PTS; ++loop) {
+		pmap_map_chunk(l1pagetable, kernel_pt_table[loop].pv_va,
+		    kernel_pt_table[loop].pv_pa, L2_TABLE_SIZE,
+		    VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE);
+	}
+
+	arm_devmap_bootstrap(l1pagetable, s3c24x0_devmap);
+
+	cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT);
+	setttb(kernel_l1pt.pv_pa);
+	cpu_tlb_flushID();
+	cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2));
+
+	/*
+	 * Pages were allocated during the secondary bootstrap for the
+	 * stacks for different CPU modes.
+	 * We must now set the r13 registers in the different CPU modes to
+	 * point to these stacks.
+	 * Since the ARM stacks use STMFD etc. we must set r13 to the top end
+	 * of the stack memory.
+	 */
+
+	cpu_control(CPU_CONTROL_MMU_ENABLE, CPU_CONTROL_MMU_ENABLE);
+	set_stackptrs(0);
+
+	/*
+	 * We must now clean the cache again....
+	 * Cleaning may be done by reading new data to displace any
+	 * dirty data in the cache. This will have happened in setttb()
+	 * but since we are boot strapping the addresses used for the read
+	 * may have just been remapped and thus the cache could be out
+	 * of sync. A re-clean after the switch will cure this.
+	 * After booting there are no gross relocations of the kernel thus
+	 * this problem will not occur after initarm().
+	 */
+	cpu_idcache_wbinv_all();
+	cpu_setup("");
+
+	/* Disable all peripheral interrupts */
+	ioreg_write32(S3C24X0_INTCTL_BASE + INTCTL_INTMSK, ~0);
+	memsize = board_init();
+	/* Find pclk for uart */
+	switch(ioreg_read32(S3C24X0_GPIO_BASE + GPIO_GSTATUS1) >> 16) {
+	case 0x3241:
+		s3c2410_clock_freq2(S3C24X0_CLKMAN_BASE, NULL, NULL,
+		    &s3c2410_pclk);
+		break;
+	case 0x3244:
+		s3c2440_clock_freq2(S3C24X0_CLKMAN_BASE, NULL, NULL,
+		    &s3c2410_pclk);
+		break;
+	}
+	cninit();
+
+	undefined_init();
+	
+	init_proc0(kernelstack.pv_va);			
+	
+	arm_vector_init(ARM_VECTORS_HIGH, ARM_VEC_ALL);
+
+	pmap_curmaxkvaddr = afterkern + 0x100000 * (KERNEL_PT_KERN_NUM - 1);
+	vm_max_kernel_address = KERNVIRTADDR + 3 * memsize;
+	pmap_bootstrap(freemempos, &kernel_l1pt);
+	msgbufp = (void*)msgbufpv.pv_va;
+	msgbufinit(msgbufp, msgbufsize);
+	mutex_init();
+
+	/*
+	 * Add the physical ram we have available.
+	 *
+	 * Exclude the kernel, and all the things we allocated which immediately
+	 * follow the kernel, from the VM allocation pool but not from crash
+	 * dumps.  virtual_avail is a global variable which tracks the kva we've
+	 * "allocated" while setting up pmaps.
+	 *
+	 * Prepare the list of physical memory available to the vm subsystem.
+	 */
+	arm_physmem_hardware_region(PHYSADDR, memsize);
+	arm_physmem_exclude_region(abp->abp_physaddr, 
+	    virtual_avail - KERNVIRTADDR, EXFLAG_NOALLOC);
+	arm_physmem_init_kernel_globals();
+
+	init_param2(physmem);
+	kdb_init();
+
+	return ((void *)(kernelstack.pv_va + USPACE_SVC_STACK_TOP -
+	    sizeof(struct pcb)));
+}


Property changes on: trunk/sys/arm/samsung/s3c2xx0/s3c24x0_machdep.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/samsung/s3c2xx0/s3c24x0_rtc.c
===================================================================
--- trunk/sys/arm/samsung/s3c2xx0/s3c24x0_rtc.c	                        (rev 0)
+++ trunk/sys/arm/samsung/s3c2xx0/s3c24x0_rtc.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,163 @@
+/* $MidnightBSD$ */
+/*
+ * Copyright (C) 2010 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/samsung/s3c2xx0/s3c24x0_rtc.c 272103 2014-09-25 11:38:26Z gavin $");
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/time.h>
+#include <sys/clock.h>
+#include <sys/resource.h>
+#include <sys/systm.h>
+#include <sys/rman.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+
+#include <machine/bus.h>
+
+#include <arm/samsung/s3c2xx0/s3c24x0reg.h>
+
+#include "clock_if.h"
+
+#define YEAR_BASE		2000
+
+struct s3c2xx0_rtc_softc {
+	struct resource *mem_res;
+};
+
+static int
+s3c2xx0_rtc_probe(device_t dev)
+{
+
+	device_set_desc(dev, "Samsung Integrated RTC");
+	return (0);
+}
+
+static int
+s3c2xx0_rtc_attach(device_t dev)
+{
+	struct s3c2xx0_rtc_softc *sc;
+	int error, rid;
+
+	sc = device_get_softc(dev);
+ 	error = 0;
+
+	rid = 0;
+	sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid,
+	    RF_ACTIVE);
+	if (sc->mem_res == NULL) {
+		error = ENOMEM;
+		goto out;
+	}
+
+	bus_write_1(sc->mem_res, RTC_RTCCON, RTCCON_RTCEN);
+	clock_register(dev, 1000000);
+
+out:
+	return (error);
+}
+
+static int
+s3c2xx0_rtc_gettime(device_t dev, struct timespec *ts)
+{
+	struct s3c2xx0_rtc_softc *sc;
+	struct clocktime ct;
+
+#define READ_TIME() do {						\
+	ct.year = YEAR_BASE + FROMBCD(bus_read_1(sc->mem_res, RTC_BCDYEAR)); \
+	ct.mon = FROMBCD(bus_read_1(sc->mem_res, RTC_BCDMON));		\
+	ct.dow = FROMBCD(bus_read_1(sc->mem_res, RTC_BCDDAY));		\
+	ct.day = FROMBCD(bus_read_1(sc->mem_res, RTC_BCDDATE));		\
+	ct.hour = FROMBCD(bus_read_1(sc->mem_res, RTC_BCDHOUR));	\
+	ct.min = FROMBCD(bus_read_1(sc->mem_res, RTC_BCDMIN));		\
+	ct.sec = FROMBCD(bus_read_1(sc->mem_res, RTC_BCDSEC));		\
+} while (0)
+
+	sc = device_get_softc(dev);
+
+	ct.nsec = 0;
+	READ_TIME();
+	/*
+	 * Check if we could have read incorrect values
+	 * as the values could have changed.
+	 */
+	if (ct.sec == 0) {
+		READ_TIME();
+	}
+
+	ct.dow = -1;
+
+#undef READ_TIME
+	return (clock_ct_to_ts(&ct, ts));
+}
+
+static int
+s3c2xx0_rtc_settime(device_t dev, struct timespec *ts)
+{
+	struct s3c2xx0_rtc_softc *sc;
+	struct clocktime ct;
+
+	sc = device_get_softc(dev);
+
+	/* Resolution: 1 sec */
+	if (ts->tv_nsec >= 500000000)
+		ts->tv_sec++;
+	ts->tv_nsec = 0;
+	clock_ts_to_ct(ts, &ct);
+
+	bus_write_1(sc->mem_res, RTC_BCDSEC, TOBCD(ct.sec));
+	bus_write_1(sc->mem_res, RTC_BCDMIN, TOBCD(ct.min));
+	bus_write_1(sc->mem_res, RTC_BCDHOUR, TOBCD(ct.hour));
+	bus_write_1(sc->mem_res, RTC_BCDDATE, TOBCD(ct.day));
+	bus_write_1(sc->mem_res, RTC_BCDDAY, TOBCD(ct.dow));
+	bus_write_1(sc->mem_res, RTC_BCDMON, TOBCD(ct.mon));
+	bus_write_1(sc->mem_res, RTC_BCDYEAR, TOBCD(ct.year - YEAR_BASE));
+
+	return (0);
+}
+
+static device_method_t s3c2xx0_rtc_methods[] = {
+	DEVMETHOD(device_probe,		s3c2xx0_rtc_probe),
+	DEVMETHOD(device_attach,	s3c2xx0_rtc_attach),
+
+	DEVMETHOD(clock_gettime,	s3c2xx0_rtc_gettime),
+	DEVMETHOD(clock_settime,	s3c2xx0_rtc_settime),
+
+	{ 0, 0 },
+};
+
+static driver_t s3c2xx0_rtc_driver = {
+	"rtc",
+	s3c2xx0_rtc_methods,
+	sizeof(struct s3c2xx0_rtc_softc),
+};
+static devclass_t s3c2xx0_rtc_devclass;
+
+DRIVER_MODULE(s3c2xx0_rtc, s3c24x0, s3c2xx0_rtc_driver, s3c2xx0_rtc_devclass,
+    0, 0);
+


Property changes on: trunk/sys/arm/samsung/s3c2xx0/s3c24x0_rtc.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/samsung/s3c2xx0/s3c24x0reg.h
===================================================================
--- trunk/sys/arm/samsung/s3c2xx0/s3c24x0reg.h	                        (rev 0)
+++ trunk/sys/arm/samsung/s3c2xx0/s3c24x0reg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,719 @@
+/* $MidnightBSD$ */
+/* $NetBSD: s3c24x0reg.h,v 1.7 2004/02/12 03:52:46 bsh Exp $ */
+
+/*-
+ * Copyright (c) 2003  Genetec corporation  All rights reserved.
+ * Written by Hiroyuki Bessho for Genetec corporation.
+ *
+ * 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.
+ * 3. The name of Genetec corporation may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GENETEC CORP. ``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 GENETEC CORP.
+ * 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: stable/10/sys/arm/samsung/s3c2xx0/s3c24x0reg.h 272103 2014-09-25 11:38:26Z gavin $
+ */
+
+
+/*
+ * Samsung S3C2410X/2400 processor is ARM920T based integrated CPU
+ *
+ * Reference:
+ *  S3C2410X User's Manual
+ *  S3C2400 User's Manual
+ */
+#ifndef _ARM_S3C2XX0_S3C24X0REG_H_
+#define	_ARM_S3C2XX0_S3C24X0REG_H_
+
+/* common definitions for S3C2800, S3C2410 and S3C2440 */
+#include <arm/samsung/s3c2xx0/s3c2xx0reg.h>
+
+/*
+ * Map the device registers into kernel space.
+ *
+ * As most devices use less than 1 page of memory reduce
+ * the distance between allocations by right shifting
+ * S3C24X0_DEV_SHIFT bits. Because the UART takes 3*0x4000
+ * bytes the upper limit on S3C24X0_DEV_SHIFT is 4.
+ * TODO: Fix the UART code so we can increase this value.
+ */
+#define	S3C24X0_DEV_START	0x48000000
+#define	S3C24X0_DEV_STOP	0x60000000
+#define	S3C24X0_DEV_VA_OFFSET	0xD8000000
+#define	S3C24X0_DEV_SHIFT	4
+#define	S3C24X0_DEV_PA_SIZE	(S3C24X0_DEV_STOP - S3C24X0_DEV_START)
+#define	S3C24X0_DEV_VA_SIZE	(S3C24X0_DEV_PA_SIZE >> S3C24X0_DEV_SHIFT)
+#define	S3C24X0_DEV_PA_TO_VA(x)	((x >> S3C24X0_DEV_SHIFT) - S3C24X0_DEV_START + S3C24X0_DEV_VA_OFFSET)
+
+/*
+ * Physical address of integrated peripherals
+ */
+#define	S3C24X0_MEMCTL_PA_BASE	0x48000000 /* memory controller */
+#define	S3C24X0_MEMCTL_BASE	S3C24X0_DEV_PA_TO_VA(S3C24X0_MEMCTL_PA_BASE)
+#define	S3C24X0_USBHC_PA_BASE 	0x49000000 /* USB Host controller */
+#define	S3C24X0_USBHC_BASE	S3C24X0_DEV_PA_TO_VA(S3C24X0_USBHC_PA_BASE)
+#define	S3C24X0_INTCTL_PA_BASE	0x4a000000 /* Interrupt controller */
+#define	S3C24X0_INTCTL_BASE	S3C24X0_DEV_PA_TO_VA(S3C24X0_INTCTL_PA_BASE)
+#define	S3C24X0_INTCTL_SIZE	0x20
+#define	S3C24X0_DMAC_PA_BASE	0x4b000000
+#define	S3C24X0_DMAC_BASE	S3C24X0_DEV_PA_TO_VA(S3C24X0_DMAC_PA_BASE)
+#define	S3C24X0_DMAC_SIZE 	0xe4
+#define	S3C24X0_CLKMAN_PA_BASE	0x4c000000 /* clock & power management */
+#define	S3C24X0_CLKMAN_BASE	S3C24X0_DEV_PA_TO_VA(S3C24X0_CLKMAN_PA_BASE)
+#define	S3C24X0_LCDC_PA_BASE 	0x4d000000 /* LCD controller */
+#define	S3C24X0_LCDC_BASE 	S3C24X0_DEV_PA_TO_VA(S3C24X0_LCDC_PA_BASE)
+#define	S3C24X0_LCDC_SIZE	0x64
+#define	S3C24X0_NANDFC_PA_BASE	0x4e000000 /* NAND Flash controller */
+#define	S3C24X0_NANDFC_BASE	S3C24X0_DEV_PA_TO_VA(S3C24X0_NANDFC_PA_BASE)
+#define	S3C24X0_UART0_PA_BASE	0x50000000
+#define	S3C24X0_UART0_BASE	S3C24X0_DEV_PA_TO_VA(S3C24X0_UART0_PA_BASE)
+#define	S3C24X0_UART_PA_BASE(n)	(S3C24X0_UART0_PA_BASE+0x4000*(n))
+#define	S3C24X0_UART_BASE(n)	(S3C24X0_UART0_BASE+0x4000*(n))
+#define	S3C24X0_TIMER_PA_BASE 	0x51000000
+#define	S3C24X0_TIMER_BASE 	S3C24X0_DEV_PA_TO_VA(S3C24X0_TIMER_PA_BASE)
+#define	S3C24X0_USBDC_PA_BASE 	0x5200140
+#define	S3C24X0_USBDC_BASE 	S3C24X0_DEV_PA_TO_VA(S3C24X0_USBDC_PA_BASE)
+#define	S3C24X0_USBDC_SIZE 	0x130
+#define	S3C24X0_WDT_PA_BASE 	0x53000000
+#define	S3C24X0_WDT_BASE 	S3C24X0_DEV_PA_TO_VA(S3C24X0_WDT_PA_BASE)
+#define	S3C24X0_IIC_PA_BASE 	0x54000000
+#define	S3C24X0_IIC_BASE 	S3C24X0_DEV_PA_TO_VA(S3C24X0_IIC_PA_BASE)
+#define	S3C24X0_IIS_PA_BASE 	0x55000000
+#define	S3C24X0_IIS_BASE 	S3C24X0_DEV_PA_TO_VA(S3C24X0_IIS_PA_BASE)
+#define	S3C24X0_GPIO_PA_BASE	0x56000000
+#define	S3C24X0_GPIO_BASE	S3C24X0_DEV_PA_TO_VA(S3C24X0_GPIO_PA_BASE)
+#define	S3C24X0_RTC_PA_BASE	0x57000000
+#define	S3C24X0_RTC_BASE	S3C24X0_DEV_PA_TO_VA(S3C24X0_RTC_PA_BASE)
+#define	S3C24X0_RTC_SIZE	0x8C
+#define	S3C24X0_ADC_PA_BASE 	0x58000000
+#define	S3C24X0_ADC_BASE 	S3C24X0_DEV_PA_TO_VA(S3C24X0_ADC_PA_BASE)
+#define	S3C24X0_SPI0_PA_BASE 	0x59000000
+#define	S3C24X0_SPI0_BASE 	S3C24X0_DEV_PA_TO_VA(S3C24X0_SPI0_PA_BASE)
+#define	S3C24X0_SPI1_PA_BASE 	0x59000020
+#define	S3C24X0_SPI1_BASE 	S3C24X0_DEV_PA_TO_VA(S3C24X0_SPI1_PA_BASE)
+#define	S3C24X0_SDI_PA_BASE 	0x5a000000 /* SD Interface */
+#define	S3C24X0_SDI_BASE 	S3C24X0_DEV_PA_TO_VA(S3C24X0_SDI_PA_BASE)
+
+#define	S3C24X0_REG_BASE	0x48000000
+#define	S3C24X0_REG_SIZE	0x13000000
+
+/* Memory controller */
+#define	MEMCTL_BWSCON   	0x00	/* Bus width and wait status */
+#define	 BWSCON_DW0_SHIFT	1 	/* bank0 is odd */
+#define	 BWSCON_BANK_SHIFT(n)	(4*(n))	/* for bank 1..7 */
+#define	 BWSCON_DW_MASK 	0x03
+#define	 BWSCON_DW_8 		0
+#define	 BWSCON_DW_16 		1
+#define	 BWSCON_DW_32 		2
+#define	 BWSCON_WS		0x04	/* WAIT enable for the bank */
+#define	 BWSCON_ST		0x08	/* SRAM use UB/LB for the bank */
+
+#define	MEMCTL_BANKCON0 	0x04	/* Boot ROM control */
+#define	MEMCTL_BANKCON(n)	(0x04+4*(n)) /* BANKn control */
+#define	 BANKCON_MT_SHIFT 	15
+#define	 BANKCON_MT_ROM 	(0<<BANKCON_MT_SHIFT)
+#define	 BANKCON_MT_DRAM 	(3<<BANKCON_MT_SHIFT)
+#define	 BANKCON_TACS_SHIFT 	13	/* address set-up time to nGCS */
+#define	 BANKCON_TCOS_SHIFT 	11	/* CS set-up to nOE */
+#define	 BANKCON_TACC_SHIFT 	8	/* CS set-up to nOE */
+#define	 BANKCON_TOCH_SHIFT 	6	/* CS hold time from OE */
+#define	 BANKCON_TCAH_SHIFT 	4	/* address hold time from OE */
+#define	 BANKCON_TACP_SHIFT 	2	/* page mode access cycle */
+#define	 BANKCON_TACP_2 	(0<<BANKCON_TACP_SHIFT)
+#define	 BANKCON_TACP_3  	(1<<BANKCON_TACP_SHIFT)
+#define	 BANKCON_TACP_4  	(2<<BANKCON_TACP_SHIFT)
+#define	 BANKCON_TACP_6  	(3<<BANKCON_TACP_SHIFT)
+#define	 BANKCON_PMC_4   	(1<<0)
+#define	 BANKCON_PMC_8   	(2<<0)
+#define	 BANKCON_PMC_16   	(3<<0)
+#define	 BANKCON_TRCD_SHIFT 	2	/* RAS to CAS delay */
+#define	 BANKCON_TRCD_2  	(0<<2)
+#define	 BANKCON_TRCD_3  	(1<<2)
+#define	 BANKCON_TRCD_4  	(2<<2)
+#define	 BANKCON_SCAN_8 	(0<<0)	/* Column address number */
+#define	 BANKCON_SCAN_9 	(1<<0)
+#define	 BANKCON_SCAN_10 	(2<<0)
+#define	MEMCTL_REFRESH   	0x24	/* DRAM?SDRAM Refresh */
+#define	 REFRESH_REFEN 		(1<<23)
+#define	 REFRESH_TREFMD  	(1<<22)	/* 1=self refresh */
+#define	 REFRESH_TRP_2 		(0<<20)
+#define	 REFRESH_TRP_3 		(1<<20)
+#define	 REFRESH_TRP_4 		(2<<20)
+#define	 REFRESH_TRC_4 		(0<<18)
+#define	 REFRESH_TRC_5 		(1<<18)
+#define	 REFRESH_TRC_6 		(2<<18)
+#define	 REFRESH_TRC_7 		(3<<18)
+#define	 REFRESH_COUNTER_MASK	0x3ff
+#define	MEMCTL_BANKSIZE 	0x28 	/* Flexible Bank size */
+#define	MEMCTL_MRSRB6    	0x2c	/* SDRAM Mode register */
+#define	MEMCTL_MRSRB7    	0x30
+#define	 MRSR_CL_SHIFT		4	/* CAS Latency */
+
+#define	S3C24X0_MEMCTL_SIZE	0x34
+
+/* USB Host controller */
+#define	S3C24X0_USBHC_SIZE	0x5c
+
+/* Interrupt controller */
+#define	INTCTL_PRIORITY 	0x0c	/* IRQ Priority control */
+#define	INTCTL_INTPND   	0x10	/* Interrupt request status */
+#define	INTCTL_INTOFFSET	0x14	/* Interrupt request source */
+#define	INTCTL_SUBSRCPND 	0x18	/* sub source pending */
+#define	INTCTL_INTSUBMSK  	0x1c	/* sub mask */
+
+/* Interrupt source */
+#define	S3C24X0_INT_ADCTC 	31	/* ADC (and TC for 2410) */
+#define	S3C24X0_INT_RTC  	30	/* RTC alarm */
+#define	S3C24X0_INT_SPI1	29	/* SPI 1 */
+#define	S3C24X0_INT_UART0	28	/* UART0 */
+#define	S3C24X0_INT_IIC  	27
+#define	S3C24X0_INT_USBH	26	/* USB Host */
+#define	S3C24X0_INT_USBD	25	/* USB Device */
+#define	S3C24X0_INT_UART1	23	/* UART0  (2410 only) */
+#define	S3C24X0_INT_SPI0  	22	/* SPI 0 */
+#define	S3C24X0_INT_SDI 	21
+#define	S3C24X0_INT_DMA3	20
+#define	S3C24X0_INT_DMA2	19
+#define	S3C24X0_INT_DMA1	18
+#define	S3C24X0_INT_DMA0	17
+#define	S3C24X0_INT_LCD 	16
+
+#define	S3C24X0_INT_UART2 	15	/* UART2 int (2410) */
+#define	S3C24X0_INT_TIMER4	14
+#define	S3C24X0_INT_TIMER3	13
+#define	S3C24X0_INT_TIMER2	12
+#define	S3C24X0_INT_TIMER1	11
+#define	S3C24X0_INT_TIMER0	10
+#define	S3C24X0_INT_TIMER(n)	(10+(n)) /* timer interrupt [4:0] */
+#define	S3C24X0_INT_WDT 	9	/* Watch dog timer */
+#define	S3C24X0_INT_TICK 	8
+#define	S3C24X0_INT_BFLT 	7	/* Battery fault */
+#define	S3C24X0_INT_8_23	5	/* Ext int 8..23 */
+#define	S3C24X0_INT_4_7 	4	/* Ext int 4..7 */
+#define	S3C24X0_INT_3		3
+#define	S3C24X0_INT_2		2
+#define	S3C24X0_INT_1		1
+#define	S3C24X0_INT_0		0
+
+/* 24{1,4}0 has more than 32 interrupt sources.  These are sub-sources
+ * that are OR-ed into main interrupt sources, and controlled via
+ * SUBSRCPND and  SUBSRCMSK registers */
+#define	S3C24X0_SUBIRQ_MIN	32
+
+/* cascaded to INT_ADCTC */
+#define	S3C24X0_INT_ADC		(S3C24X0_SUBIRQ_MIN+10)	/* AD converter */
+#define	S3C24X0_INT_TC 		(S3C24X0_SUBIRQ_MIN+9)	/* Touch screen */
+/* cascaded to INT_UART2 */
+#define	S3C24X0_INT_ERR2	(S3C24X0_SUBIRQ_MIN+8)	/* UART2 Error */
+#define	S3C24X0_INT_TXD2	(S3C24X0_SUBIRQ_MIN+7)	/* UART2 Tx */
+#define	S3C24X0_INT_RXD2	(S3C24X0_SUBIRQ_MIN+6)	/* UART2 Rx */
+/* cascaded to INT_UART1 */
+#define	S3C24X0_INT_ERR1	(S3C24X0_SUBIRQ_MIN+5)	/* UART1 Error */
+#define	S3C24X0_INT_TXD1	(S3C24X0_SUBIRQ_MIN+4)	/* UART1 Tx */
+#define	S3C24X0_INT_RXD1	(S3C24X0_SUBIRQ_MIN+3)	/* UART1 Rx */
+/* cascaded to INT_UART0 */
+#define	S3C24X0_INT_ERR0	(S3C24X0_SUBIRQ_MIN+2)	/* UART0 Error */
+#define	S3C24X0_INT_TXD0	(S3C24X0_SUBIRQ_MIN+1)	/* UART0 Tx */
+#define	S3C24X0_INT_RXD0	(S3C24X0_SUBIRQ_MIN+0)	/* UART0 Rx */
+
+/*
+ * Support for external interrupts. We use values from 48
+ * to allow new CPU's to allocate new subirq's.
+ */
+#define	S3C24X0_EXTIRQ_MIN	48
+#define	S3C24X0_EXTIRQ_COUNT	24
+#define	S3C24X0_EXTIRQ_MAX	(S3C24X0_EXTIRQ_MIN + S3C24X0_EXTIRQ_COUNT - 1)
+#define	S3C24X0_INT_EXT(n)	(S3C24X0_EXTIRQ_MIN + (n))
+
+/* DMA controller */
+/* XXX */
+
+/* Clock & power manager */
+#define	CLKMAN_LOCKTIME 0x00	/* PLL lock time */
+#define	CLKMAN_MPLLCON 	0x04	/* MPLL control */
+#define	CLKMAN_UPLLCON 	0x08	/* UPLL control */
+#define	 PLLCON_MDIV_SHIFT	12
+#define	 PLLCON_MDIV_MASK	(0xff<<PLLCON_MDIV_SHIFT)
+#define	 PLLCON_PDIV_SHIFT	4
+#define	 PLLCON_PDIV_MASK	(0x3f<<PLLCON_PDIV_SHIFT)
+#define	 PLLCON_SDIV_SHIFT	0
+#define	 PLLCON_SDIV_MASK	(0x03<<PLLCON_SDIV_SHIFT)
+#define	CLKMAN_CLKCON	0x0c
+#define	 CLKCON_SPI 	(1<<18)
+#define	 CLKCON_IIS 	(1<<17)
+#define	 CLKCON_IIC 	(1<<16)
+#define	 CLKCON_ADC 	(1<<15)
+#define	 CLKCON_RTC 	(1<<14)
+#define	 CLKCON_GPIO 	(1<<13)
+#define	 CLKCON_UART2 	(1<<12)
+#define	 CLKCON_UART1 	(1<<11)
+#define	 CLKCON_UART0	(1<<10)	/* PCLK to UART0 */
+#define	 CLKCON_SDI	(1<<9)
+#define	 CLKCON_TIMER	(1<<8)	/* PCLK to TIMER */
+#define	 CLKCON_USBD	(1<<7)	/* PCLK to USB device controller */
+#define	 CLKCON_USBH	(1<<6)	/* PCLK to USB host controller */
+#define	 CLKCON_LCDC	(1<<5)	/* PCLK to LCD controller */
+#define	 CLKCON_NANDFC	(1<<4)	/* PCLK to NAND Flash controller */
+#define	 CLKCON_IDLE	(1<<2)	/* 1=transition to IDLE mode */
+#define	CLKMAN_CLKSLOW	0x10
+#define	CLKMAN_CLKDIVN	0x14
+#define	 CLKDIVN_PDIVN	(1<<0)	/* pclk=hclk/2 */
+
+#define	CLKMAN_CLKSLOW	0x10	/* slow clock controll */
+#define	 CLKSLOW_UCLK 	(1<<7)	/* 1=UPLL off */
+#define	 CLKSLOW_MPLL 	(1<<5)	/* 1=PLL off */
+#define	 CLKSLOW_SLOW	(1<<4)	/* 1: Enable SLOW mode */
+#define	 CLKSLOW_VAL_MASK  0x0f	/* divider value for slow clock */
+
+#define	CLKMAN_CLKDIVN	0x14	/* Software reset control */
+#define	 CLKDIVN_PDIVN	(1<<0)
+
+#define	S3C24X0_CLKMAN_SIZE	0x18
+
+/* LCD controller */
+#define	LCDC_LCDCON1	0x00	/* control 1 */
+#define	 LCDCON1_ENVID   	(1<<0)	/* enable video */
+#define	 LCDCON1_BPPMODE_SHIFT 	1
+#define	 LCDCON1_BPPMODE_MASK	(0x0f<<LCDCON1_BPPMODE_SHIFT)
+#define	 LCDCON1_BPPMODE_STN1	(0x0<<LCDCON1_BPPMODE_SHIFT)
+#define	 LCDCON1_BPPMODE_STN2	(0x1<<LCDCON1_BPPMODE_SHIFT)
+#define	 LCDCON1_BPPMODE_STN4	(0x2<<LCDCON1_BPPMODE_SHIFT)
+#define	 LCDCON1_BPPMODE_STN8	(0x3<<LCDCON1_BPPMODE_SHIFT)
+#define	 LCDCON1_BPPMODE_STN12	(0x4<<LCDCON1_BPPMODE_SHIFT)
+#define	 LCDCON1_BPPMODE_TFT1	(0x8<<LCDCON1_BPPMODE_SHIFT)
+#define	 LCDCON1_BPPMODE_TFT2	(0x9<<LCDCON1_BPPMODE_SHIFT)
+#define	 LCDCON1_BPPMODE_TFT4	(0xa<<LCDCON1_BPPMODE_SHIFT)
+#define	 LCDCON1_BPPMODE_TFT8	(0xb<<LCDCON1_BPPMODE_SHIFT)
+#define	 LCDCON1_BPPMODE_TFT16	(0xc<<LCDCON1_BPPMODE_SHIFT)
+#define	 LCDCON1_BPPMODE_TFT24	(0xd<<LCDCON1_BPPMODE_SHIFT)
+#define	 LCDCON1_BPPMODE_TFTX	(0x8<<LCDCON1_BPPMODE_SHIFT)
+
+#define	 LCDCON1_PNRMODE_SHIFT	5
+#define	 LCDCON1_PNRMODE_MASK	(0x3<<LCDCON1_PNRMODE_SHIFT)
+#define	 LCDCON1_PNRMODE_DUALSTN4    (0x0<<LCDCON1_PNRMODE_SHIFT)
+#define	 LCDCON1_PNRMODE_SINGLESTN4  (0x1<<LCDCON1_PNRMODE_SHIFT)
+#define	 LCDCON1_PNRMODE_SINGLESTN8  (0x2<<LCDCON1_PNRMODE_SHIFT)
+#define	 LCDCON1_PNRMODE_TFT         (0x3<<LCDCON1_PNRMODE_SHIFT)
+
+#define	 LCDCON1_MMODE  	(1<<7) /* VM toggle rate */
+#define	 LCDCON1_CLKVAL_SHIFT 	8
+#define	 LCDCON1_CLKVAL_MASK	(0x3ff<<LCDCON1_CLKVAL_SHIFT)
+#define	 LCDCON1_LINCNT_SHIFT 	18
+#define	 LCDCON1_LINCNT_MASK	(0x3ff<<LCDCON1_LINCNT_SHIFT)
+
+#define	LCDC_LCDCON2	0x04	/* control 2 */
+#define	 LCDCON2_VPSW_SHIFT	0 	/* TFT Vsync pulse width */
+#define	 LCDCON2_VPSW_MASK	(0x3f<<LCDCON2_VPSW_SHIFT)
+#define	 LCDCON2_VFPD_SHIFT	6 	/* TFT V front porch */
+#define	 LCDCON2_VFPD_MASK	(0xff<<LCDCON2_VFPD_SHIFT)
+#define	 LCDCON2_LINEVAL_SHIFT	14 	/* Vertical size */
+#define	 LCDCON2_LINEVAL_MASK	(0x3ff<<LCDCON2_LINEVAL_SHIFT)
+#define	 LCDCON2_VBPD_SHIFT	24 	/* TFT V back porch */
+#define	 LCDCON2_VBPD_MASK	(0xff<<LCDCON2_VBPD_SHIFT)
+
+#define	LCDC_LCDCON3	0x08	/* control 2 */
+#define	 LCDCON3_HFPD_SHIFT	0 	/* TFT H front porch */
+#define	 LCDCON3_HFPD_MASK	(0xff<<LCDCON3_VPFD_SHIFT)
+#define	 LCDCON3_LINEBLANK_SHIFT  0 	/* STN H blank time */
+#define	 LCDCON3_LINEBLANK_MASK	  (0xff<<LCDCON3_LINEBLANK_SHIFT)
+#define	 LCDCON3_HOZVAL_SHIFT	8 	/* Horizontal size */
+#define	 LCDCON3_HOZVAL_MASK	(0x7ff<<LCDCON3_HOZVAL_SHIFT)
+#define	 LCDCON3_HBPD_SHIFT	19 	/* TFT H back porch */
+#define	 LCDCON3_HBPD_MASK	(0x7f<<LCDCON3_HPBD_SHIFT)
+#define	 LCDCON3_WDLY_SHIFT	19	/* STN vline delay */
+#define	 LCDCON3_WDLY_MASK	(0x03<<LCDCON3_WDLY_SHIFT)
+#define	 LCDCON3_WDLY_16	(0x00<<LCDCON3_WDLY_SHIFT)
+#define	 LCDCON3_WDLY_32	(0x01<<LCDCON3_WDLY_SHIFT)
+#define	 LCDCON3_WDLY_64	(0x02<<LCDCON3_WDLY_SHIFT)
+#define	 LCDCON3_WDLY_128	(0x03<<LCDCON3_WDLY_SHIFT)
+
+#define	LCDC_LCDCON4	0x0c	/* control 4 */
+#define	 LCDCON4_HPSW_SHIFT	0 	/* TFT Hsync pulse width */
+#define	 LCDCON4_HPSW_MASK	(0xff<<LCDCON4_HPSW_SHIFT)
+#define	 LCDCON4_WLH_SHIFT	0	/* STN VLINE high width */
+#define	 LCDCON4_WLH_MASK	(0x03<<LCDCON4_WLH_SHIFT)
+#define	 LCDCON4_WLH_16 	(0x00<<LCDCON4_WLH_SHIFT)
+#define	 LCDCON4_WLH_32  	(0x01<<LCDCON4_WLH_SHIFT)
+#define	 LCDCON4_WLH_64  	(0x02<<LCDCON4_WLH_SHIFT)
+#define	 LCDCON4_WLH_128	(0x03<<LCDCON4_WLH_SHIFT)
+
+#define	 LCDCON4_MVAL_SHIFT	8	/* STN VM toggle rate */
+#define	 LCDCON4_MVAL_MASK	(0xff<<LCDCON4_MVAL_SHIFT)
+
+#define	LCDC_LCDCON5	0x10	/* control 5 */
+#define	 LCDCON5_HWSWP		(1<<0)	/* half-word swap */
+#define	 LCDCON5_BSWP 		(1<<1)	/* byte swap */
+#define	 LCDCON5_ENLEND		(1<<2)	/* TFT: enable LEND signal */
+#define	 LCDCON5_PWREN		(1<<3)	/* enable PWREN signale */
+#define	 LCDCON5_INVLEND	(1<<4)	/* TFT: LEND signal polarity */
+#define	 LCDCON5_INVPWREN	(1<<5)	/* PWREN signal polarity */
+#define	 LCDCON5_INVVDEN	(1<<6)	/* VDEN signal polarity */
+#define	 LCDCON5_INVVD		(1<<7)	/* video data signal polarity */
+#define	 LCDCON5_INVVFRAME	(1<<8)	/* VFRAME/VSYNC signal polarity */
+#define	 LCDCON5_INVVLINE	(1<<9)	/* VLINE/HSYNC signal polarity */
+#define	 LCDCON5_INVVCLK	(1<<10)	/* VCLK signal polarity */
+#define	 LCDCON5_INVVCLK_RISING	LCDCON5_INVVCLK
+#define	 LCDCON5_INVVCLK_FALLING  0
+#define	 LCDCON5_FRM565  	(1<<11)	/* RGB:565 format*/
+#define	 LCDCON5_FRM555I	0	/* RGBI:5551 format */
+#define	 LCDCON5_BPP24BL	(1<<12)	/* bit order for bpp24 */
+
+#define	 LCDCON5_HSTATUS_SHIFT	17 /* TFT: horizontal status */
+#define	 LCDCON5_HSTATUS_MASK	(0x03<<LCDCON5_HSTATUS_SHIFT)
+#define	 LCDCON5_HSTATUS_HSYNC	(0x00<<LCDCON5_HSTATUS_SHIFT)
+#define	 LCDCON5_HSTATUS_BACKP	(0x01<<LCDCON5_HSTATUS_SHIFT)
+#define	 LCDCON5_HSTATUS_ACTIVE	(0x02<<LCDCON5_HSTATUS_SHIFT)
+#define	 LCDCON5_HSTATUS_FRONTP	(0x03<<LCDCON5_HSTATUS_SHIFT)
+
+#define	 LCDCON5_VSTATUS_SHIFT	19 /* TFT: vertical status */
+#define	 LCDCON5_VSTATUS_MASK	(0x03<<LCDCON5_VSTATUS_SHIFT)
+#define	 LCDCON5_VSTATUS_HSYNC	(0x00<<LCDCON5_VSTATUS_SHIFT)
+#define	 LCDCON5_VSTATUS_BACKP	(0x01<<LCDCON5_VSTATUS_SHIFT)
+#define	 LCDCON5_VSTATUS_ACTIVE	(0x02<<LCDCON5_VSTATUS_SHIFT)
+#define	 LCDCON5_VSTATUS_FRONTP	(0x03<<LCDCON5_VSTATUS_SHIFT)
+
+#define	LCDC_LCDSADDR1	0x14	/* frame buffer start address */
+#define	LCDC_LCDSADDR2	0x18
+#define	LCDC_LCDSADDR3	0x1c
+#define	 LCDSADDR3_OFFSIZE_SHIFT     11
+#define	 LCDSADDR3_PAGEWIDTH_SHIFT   0
+
+#define	LCDC_REDLUT	0x20	/* STN: red lookup table */
+#define	LCDC_GREENLUT	0x24	/* STN: green lookup table */
+#define	LCDC_BLUELUT	0x28	/* STN: blue lookup table */
+#define	LCDC_DITHMODE	0x4c	/* STN: dithering mode */
+
+#define	LCDC_TPAL	0x50	/* TFT: temporary palette */
+#define	 TPAL_TPALEN		(1<<24)
+#define	 TPAL_RED_SHIFT  	16
+#define	 TPAL_GREEN_SHIFT	8
+#define	 TPAL_BLUE_SHIFT 	0
+
+#define	LCDC_LCDINTPND	0x54
+#define	LCDC_LCDSRCPND	0x58
+#define	LCDC_LCDINTMSK	0x5c
+#define	 LCDINT_FICNT	(1<<0)	/* FIFO trigger interrupt pending */
+#define	 LCDINT_FRSYN	(1<<1)	/* frame sync interrupt pending */
+#define	 LCDINT_FIWSEL	(1<<2)	/* FIFO trigger level: 1=8 words, 0=4 words*/
+
+#define	LCDC_LPCSEL	0x60	/* LPC3600 mode  */
+#define	 LPCSEL_LPC_EN		(1<<0)	/* enable LPC3600 mode */
+#define	 LPCSEL_RES_SEL		(1<<1)	/* 1=240x320 0=320x240 */
+#define	 LPCSEL_MODE_SEL	(1<<2)
+#define	 LPCSEL_CPV_SEL		(1<<3)
+
+
+#define	LCDC_PALETTE		0x0400
+#define	LCDC_PALETTE_SIZE	0x0400
+
+/* NAND Flash controller */
+#define	NANDFC_NFCONF	0x00	/* Configuration */
+/* NANDFC_NFSTAT */
+#define	 NFSTAT_READY	(1<<0)	/* NAND flash memory ready/busy status */
+
+
+/* MMC/SD */
+#define	SDI_CON		0x00
+#define	 CON_BYTEORDER		(1<<4)
+#define	 CON_SDIO_INTR		(1<<3)
+#define	 CON_READWAIT_EN	(1<<2)
+#define	 CON_CLOCK_EN		(1<<0)
+#define	SDI_PRE		0x04
+#define	SDI_CARG	0x08
+#define	SDI_CCON	0x0c
+#define	 CCON_ABORDCMD		(1<<12) /* Abort SDIO CMD12/52 */
+#define	 CCON_WITHDATA  	(1<<11) /* CMD with data */
+#define	 CCON_LONGRSP		(1<<10) /* 136 bit response */
+#define	 CCON_WAITRSP		(1<<9)  /* Host waits for response */
+#define	 CCON_CMD_START		(1<<8)
+#define	 CCON_CMDINDEX_MASK	(0x7F) /* Command number index */
+#define	SDI_CSTA	0x10
+#define	 CSTA_RSPCRCFAIL	(1<<12)
+#define	 CSTA_CMDSENT		(1<<11)
+#define	 CSTA_CMDTOUT		(1<<10)
+#define	 CSTA_RSPFIN		(1<<9)
+/* All the bits to be cleared */
+#define	 CSTA_ALL_CLEAR		(CSTA_RSPCRCFAIL | CSTA_CMDSENT | \
+				 CSTA_CMDTOUT | CSTA_RSPFIN)
+#define	 CSTA_ERROR		(CSTA_RSPCRCFAIL | CSTA_CMDTOUT)
+#define	 CSTA_CMDON		(1<<8)
+#define	SDI_RSP0	0x14
+#define	SDI_RSP1	0x18
+#define	SDI_RSP2	0x1c
+#define	SDI_RSP3	0x20
+#define	SDI_DTIMER	0x24
+#define	SDI_BSIZE	0x28
+#define	SDI_DCON	0x2c
+#define	 DCON_PRDTYPE		(1<<21)
+#define	 DCON_TARSP		(1<<20) /* Transmit after response */
+#define	 DCON_RACMD		(1<<19) /* Receive after command */
+#define	 DCON_BACMD		(1<<18) /* Busy after command */
+#define	 DCON_BLKMODE		(1<<17) /* Stream/Block mode */
+#define	 DCON_WIDEBUS		(1<<16) /* Standard/Wide bus */
+#define	 DCON_ENDMA		(1<<15) /* DMA Enable */
+/* Determine the direction of the data transfer */
+#define	 DCON_DATA_READY	(0<<12) /* No transfer */
+#define	 DCON_ONLYBUST		(1<<12) /* Check if busy */
+#define	 DCON_DATA_RECEIVE	(2<<12) /* Receive data from SD */
+#define	 DCON_DATA_TRANSMIT	(3<<12) /* Send data to SD */
+#define	 DCON_BLKNUM_MASK	(0x7FF) /* Block number */
+#define	SDI_DCNT	0x30
+#define	SDI_DSTA	0x34
+#define	SDI_FSTA	0x38
+#define	 FSTA_TX_AVAIL		(1<<13)
+#define	 FSTA_RX_AVAIL		(1<<12)
+#define	 FSTA_TX_FIFO_HALF_FULL	(1<<11)
+#define	 FSTA_TX_FIFO_EMPTY	(1<<10)
+#define	 FSTA_RX_FIFO_LAST_DATA	(1<<9)
+#define	 FSTA_RX_FIFO_FULL	(1<<8)
+#define	 FSTA_RX_FIFO_HALF_FULL	(1<<7)
+#define	 FSTA_FIFO_COUNT_MSK	(0x7F)
+
+/* Timer */
+#define	TIMER_TCFG0 	0x00	/* Timer configuration */
+#define	TIMER_TCFG1	0x04
+#define	 TCFG1_MUX_SHIFT(n)	(4*(n))
+#define	 TCFG1_MUX_MASK(n)	(0x0f << TCFG1_MUX_SHIFT(n))
+#define	 TCFG1_MUX_DIV2		0
+#define	 TCFG1_MUX_DIV4		1
+#define	 TCFG1_MUX_DIV8		2
+#define	 TCFG1_MUX_DIV16	3
+#define	 TCFG1_MUX_EXT 		4
+#define	TIMER_TCON 	0x08	/* control */
+#define	 TCON_SHIFT(n)		(4 * ((n)==0 ? 0 : (n)+1))
+#define	 TCON_START(n)		(1 << TCON_SHIFT(n))
+#define	 TCON_MANUALUPDATE(n)	(1 << (TCON_SHIFT(n) + 1))
+#define	 TCON_INVERTER(n)	(1 << (TCON_SHIFT(n) + 2))
+#define	 __TCON_AUTORELOAD(n)	(1 << (TCON_SHIFT(n) + 3)) /* n=0..3 */
+#define	 TCON_AUTORELOAD4 	(1<<22)	       /* stupid hardware design */
+#define	 TCON_AUTORELOAD(n)	\
+	((n)==4 ? TCON_AUTORELOAD4 : __TCON_AUTORELOAD(n))
+#define	 TCON_MASK(n)		(0x0f << TCON_SHIFT(n))
+#define	TIMER_TCNTB(n) 	 (0x0c+0x0c*(n))	/* count buffer */
+#define	TIMER_TCMPB(n)	 (0x10+0x0c*(n))	/* compare buffer */
+#define	__TIMER_TCNTO(n) (0x14+0x0c*(n))	/* count observation */
+#define	TIMER_TCNTO4	0x40
+#define	TIMER_TCNTO(n)	((n)==4 ? TIMER_TCNTO4 : __TIMER_TCNTO(n))
+
+#define	S3C24X0_TIMER_SIZE	0x44
+
+/* UART */
+/* diffs to s3c2800 */
+/* SSCOM_UMCON */
+#define	 UMCON_AFC	(1<<4)	/* auto flow control */
+/* SSCOM_UMSTAT */
+#define	 UMSTAT_DCTS	(1<<2)	/* CTS change */
+/* SSCOM_UMSTAT */
+#define	 ULCON_IR  	(1<<6)
+#define	 ULCON_PARITY_SHIFT  3
+
+#define	S3C24X0_UART_SIZE 	0x2c
+
+/* USB device */
+/* XXX */
+
+/* Watch dog timer */
+#define	WDT_WTCON 	0x00	/* WDT mode */
+#define	 WTCON_PRESCALE_SHIFT	8
+#define	 WTCON_PRESCALE	(0xff<<WTCON_PRESCALE_SHIFT)
+#define	 WTCON_ENABLE   (1<<5)
+#define	 WTCON_CLKSEL	(3<<3)
+#define	 WTCON_CLKSEL_16  (0<<3)
+#define	 WTCON_CLKSEL_32  (1<<3)
+#define	 WTCON_CLKSEL_64  (2<<3)
+#define	 WTCON_CLKSEL_128 (3<<3)
+#define	 WTCON_ENINT    (1<<2)
+#define	 WTCON_ENRST	(1<<0)
+
+#define	 WTCON_WDTSTOP	0
+	
+#define	WDT_WTDAT 	0x04	/* timer data */
+#define	WDT_WTCNT 	0x08	/* timer count */
+
+#define	S3C24X0_WDT_SIZE 	0x0c
+
+/* IIC */
+#define	S3C24X0_IIC_SIZE 	0x0c
+
+
+/* IIS */
+#define	S3C24X0_IIS_SIZE 	0x14
+
+/* GPIO */
+#define	GPIO_PACON	0x00	/* port A configuration */
+#define	GPIO_PADAT	0x04	/* port A data */
+
+#define	GPIO_PBCON	0x10
+/* These are only used on port B-H on 2410 & B-H,J on 2440 */
+#define	 PCON_INPUT	0	/* Input port */
+#define	 PCON_OUTPUT	1	/* Output port */
+#define	 PCON_ALTFUN	2	/* Alternate function */
+#define	 PCON_ALTFUN2	3	/* Alternate function */
+#define	GPIO_PBDAT	0x14
+/* This is different between 2440 and 2442 (pull up vs pull down): */
+#define	GPIO_PBUP 	0x18	/* 2410 & 2440 */
+#define	GPIO_PBDOWN	0x18	/* 2442 */
+
+#define	GPIO_PCCON	0x20
+#define	GPIO_PCDAT	0x24
+#define	GPIO_PCUP	0x28	/* 2410 & 2440 */
+#define	GPIO_PCDOWN	0x28	/* 2442 */
+
+#define	GPIO_PDCON	0x30
+#define	GPIO_PDDAT	0x34
+#define	GPIO_PDUP	0x38	/* 2410 & 2440 */
+#define	GPIO_PDDOWN	0x38	/* 2442 */
+
+#define	GPIO_PECON	0x40
+#define	 PECON_INPUT(x)		(0<<((x)*2)) /* Pin is used for input */
+#define	 PECON_OUTPUT(x)	(1<<((x)*2)) /* Pin is used for output */
+#define	 PECON_FUNC_A(x)	(2<<((x)*2)) /* Pin is used for function 'A' */
+#define	 PECON_FUNC_B(x)	(3<<((x)*2)) /* Pin is used for function 'B' */
+#define	 PECON_MASK(x)		(3<<((x)*2))
+#define	GPIO_PEDAT	0x44
+#define	GPIO_PEUP	0x48	/* 2410 & 2440 */
+#define	GPIO_PEDOWN	0x48	/* 2442 */
+#define	 PEUD_ENABLE(x)		(~(1<<(x))) /* Enable the pull Up/Down */
+#define	 PEUD_DISABLE(x)	(1<<(x)) /* Disable the pull Up/Down */
+
+#define	GPIO_PFCON	0x50
+#define	GPIO_PFDAT	0x54
+#define	GPIO_PFUP	0x58	/* 2410 & 2440 */
+#define	GPIO_PFDOWN	0x58	/* 2442 */
+
+#define	GPIO_PGCON	0x60
+#define	GPIO_PGDAT	0x64
+#define	GPIO_PGUP	0x68	/* 2410 & 2440 */
+#define	GPIO_PGDOWN	0x68	/* 2442 */
+
+#define	GPIO_PHCON	0x70
+#define	GPIO_PHDAT	0x74
+#define	GPIO_PHUP	0x78	/* 2410 & 2440 */
+#define	GPIO_PHDOWN	0x78	/* 2442 */
+
+#define	GPIO_MISCCR 	0x80	/* miscellaneous control */
+#define	GPIO_DCLKCON 	0x84	/* DCLK 0/1 */
+#define	GPIO_EXTINT(n)	(0x88+4*(n))	/* external int control 0/1/2 */
+#define	GPIO_EINTFLT(n)	(0x94+4*(n))	/* external int filter control 0..3 */
+#define	 EXTINTR_LOW	 0x00
+#define	 EXTINTR_HIGH	 0x01
+#define	 EXTINTR_FALLING 0x02
+#define	 EXTINTR_RISING  0x04
+#define	 EXTINTR_BOTH    0x06
+#define	GPIO_EINTMASK	0xa4
+#define	GPIO_EINTPEND	0xa8
+#define	GPIO_GSTATUS0	0xac	/* external pin status */
+#define	GPIO_GSTATUS1	0xb0	/* Chip ID */
+#define	 CHIPID_S3C2410A	0x32410002
+#define	 CHIPID_S3C2440A	0x32440001
+#define	 CHIPID_S3C2442B	0x32440AAB
+#define	GPIO_GSTATUS2	0xb4	/* Reset status */
+#define	GPIO_GSTATUS3	0xb8
+#define	GPIO_GSTATUS4	0xbc
+
+#define	GPIO_SET_FUNC(v,port,func)	\
+		(((v) & ~(3<<(2*(port))))|((func)<<(2*(port))))
+
+/* ADC */
+#define	ADC_ADCCON	0x00
+#define	 ADCCON_ENABLE_START	(1<<0)
+#define	 ADCCON_READ_START	(1<<1)
+#define	 ADCCON_STDBM    	(1<<2)
+#define	 ADCCON_SEL_MUX_SHIFT	3
+#define	 ADCCON_SEL_MUX_MASK	(0x7<<ADCCON_SEL_MUX_SHIFT)
+#define	 ADCCON_PRSCVL_SHIFT	6
+#define	 ADCCON_PRSCVL_MASK	(0xff<<ADCCON_PRSCVL_SHIFT)
+#define	 ADCCON_PRSCEN  	(1<<14)
+#define	 ADCCON_ECFLG   	(1<<15)
+
+#define	ADC_ADCTSC 	0x04
+#define	 ADCTSC_XY_PST   	0x03
+#define	 ADCTSC_AUTO_PST    	(1<<2)
+#define	 ADCTSC_PULL_UP		(1<<3)
+#define	 ADCTSC_XP_SEN		(1<<4)
+#define	 ADCTSC_XM_SEN		(1<<5)
+#define	 ADCTSC_YP_SEN		(1<<6)
+#define	 ADCTSC_YM_SEN		(1<<7)
+#define	ADC_ADCDLY	0x08
+#define	ADC_ADCDAT0	0x0c
+#define	ADC_ADCDAT1	0x10
+
+#define	ADCDAT_DATAMASK  	0x3ff
+
+/* RTC */
+#define	RTC_RTCCON		0x40
+#define	 RTCCON_RTCEN		(1<<0)
+#define	 RTCCON_CLKSEL		(1<<1)
+#define	 RTCCON_CNTSEL		(1<<2)
+#define	 RTCCON_CLKRST		(1<<3)
+#define	RTC_TICNT0		0x44
+/* TICNT1 on 2440 */
+#define	RTC_RTCALM		0x50
+#define	RTC_ALMSEC		0x54
+#define	RTC_ALMMIN		0x58
+#define	RTC_ALMHOUR		0x5C
+#define	RTC_ALMDATE		0x60
+#define	RTC_ALMMON		0x64
+#define	RTC_ALMYEAR		0x68
+/* RTCRST on 2410 */
+#define	RTC_BCDSEC		0x70
+#define	RTC_BCDMIN		0x74
+#define	RTC_BCDHOUR		0x78
+#define	RTC_BCDDATE		0x7C
+#define	RTC_BCDDAY		0x80
+#define	RTC_BCDMON		0x84
+#define	RTC_BCDYEAR		0x88
+
+
+/* SPI */
+#define	S3C24X0_SPI_SIZE 	0x20
+
+#define	SPI_SPCON		0x00
+#define	 SPCON_TAGD		(1<<0) /* Tx auto garbage */
+#define	 SPCON_CPHA		(1<<1)
+#define	 SPCON_CPOL		(1<<2)
+#define	 SPCON_IDLELOW_RISING	  (0|0)
+#define	 SPCON_IDLELOW_FALLING	  (0|SPCON_CPHA)
+#define	 SPCON_IDLEHIGH_FALLING  (SPCON_CPOL|0)
+#define	 SPCON_IDLEHIGH_RISING	  (SPCON_CPOL|SPCON_CPHA)
+#define	 SPCON_MSTR		(1<<3)
+#define	 SPCON_ENSCK		(1<<4)
+#define	 SPCON_SMOD_SHIFT	5
+#define	 SPCON_SMOD_MASK	(0x03<<SPCON_SMOD_SHIFT)
+#define	 SPCON_SMOD_POLL	(0x00<<SPCON_SMOD_SHIFT)
+#define	 SPCON_SMOD_INT 	(0x01<<SPCON_SMOD_SHIFT)
+#define	 SPCON_SMOD_DMA 	(0x02<<SPCON_SMOD_SHIFT)
+
+#define	SPI_SPSTA		0x04 /* status register */
+#define	 SPSTA_REDY		(1<<0) /* ready */
+#define	 SPSTA_MULF		(1<<1) /* multi master error */
+#define	 SPSTA_DCOL		(1<<2) /* Data collision error */
+
+#define	SPI_SPPIN		0x08
+#define	 SPPIN_KEEP		(1<<0)
+#define	 SPPIN_ENMUL		(1<<2) /* multi master error detect */
+
+#define	SPI_SPPRE		0x0c /* prescaler */
+#define	SPI_SPTDAT		0x10 /* tx data */
+#define	SPI_SPRDAT		0x14 /* rx data */
+
+
+#endif /* _ARM_S3C2XX0_S3C24X0REG_H_ */


Property changes on: trunk/sys/arm/samsung/s3c2xx0/s3c24x0reg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/samsung/s3c2xx0/s3c24x0var.h
===================================================================
--- trunk/sys/arm/samsung/s3c2xx0/s3c24x0var.h	                        (rev 0)
+++ trunk/sys/arm/samsung/s3c2xx0/s3c24x0var.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,52 @@
+/* $MidnightBSD$ */
+/* $NetBSD: s3c24x0var.h,v 1.1 2003/07/31 19:49:44 bsh Exp $ */
+
+/*-
+ * Copyright (c) 2003  Genetec corporation.  All rights reserved.
+ * Written by Hiroyuki Bessho for Genetec corporation.
+ *
+ * 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.
+ * 3. The name of Genetec corporation may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GENETEC CORP. ``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 GENETEC CORP.
+ * 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: stable/10/sys/arm/samsung/s3c2xx0/s3c24x0var.h 272103 2014-09-25 11:38:26Z gavin $
+ */
+
+#ifndef _ARM_S3C24X0VAR_H_
+#define _ARM_S3C24X0VAR_H_
+
+#include <arm/samsung/s3c2xx0/s3c2xx0var.h>
+
+struct s3c24x0_softc {
+	struct s3c2xx0_softc  sc_sx;
+
+	bus_space_handle_t  sc_timer_ioh; /* Timer control registers */
+};
+
+void	s3c24x0_clock_freq(struct s3c2xx0_softc *);
+void	s3c2410_clock_freq2(vm_offset_t, int *, int *, int *);
+void	s3c2440_clock_freq2(vm_offset_t, int *, int *, int *);
+
+void	s3c24x0_sleep(int);
+
+#endif /* _ARM_S3C24X0VAR_H_ */


Property changes on: trunk/sys/arm/samsung/s3c2xx0/s3c24x0var.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/samsung/s3c2xx0/s3c2xx0board.h
===================================================================
--- trunk/sys/arm/samsung/s3c2xx0/s3c2xx0board.h	                        (rev 0)
+++ trunk/sys/arm/samsung/s3c2xx0/s3c2xx0board.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,37 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2008 Warner Losh.  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 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 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: stable/10/sys/arm/samsung/s3c2xx0/s3c2xx0board.h 205354 2010-03-20 03:39:35Z imp $ */
+
+#ifndef _ARM_S3C2XX0_S3C2XX0BOARD_H_
+#define _ARM_S3C2XX0_S3C2XX0BOARD_H_
+
+/*
+ * These routines are expected to be provided by the board files.
+ */
+long board_init(void);
+
+#endif /* _ARM_S3C2XX0_S3C2XX0BOARD_H_ */


Property changes on: trunk/sys/arm/samsung/s3c2xx0/s3c2xx0board.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/samsung/s3c2xx0/s3c2xx0reg.h
===================================================================
--- trunk/sys/arm/samsung/s3c2xx0/s3c2xx0reg.h	                        (rev 0)
+++ trunk/sys/arm/samsung/s3c2xx0/s3c2xx0reg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,140 @@
+/* $MidnightBSD$ */
+/* $NetBSD: s3c2xx0reg.h,v 1.4 2004/02/12 03:47:29 bsh Exp $ */
+
+/*-
+ * Copyright (c) 2002, 2003 Fujitsu Component Limited
+ * Copyright (c) 2002, 2003 Genetec Corporation
+ * 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.
+ * 3. Neither the name of The Fujitsu Component Limited nor the name of
+ *    Genetec corporation may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY FUJITSU COMPONENT LIMITED AND GENETEC
+ * CORPORATION ``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 FUJITSU COMPONENT LIMITED OR GENETEC
+ * CORPORATION 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: stable/10/sys/arm/samsung/s3c2xx0/s3c2xx0reg.h 205354 2010-03-20 03:39:35Z imp $
+ */
+
+
+/*
+ * Register definitions common to S3C2800 and S3C24[01]0
+ */
+#ifndef _ARM_S3C2XX0_S3C2XX0REG_H_
+#define	_ARM_S3C2XX0_S3C2XX0REG_H_
+
+/* UART */
+/*
+ * S3C2800, 2410 and 2400 have a common built-in UART block. However,
+ * there are small diffs in bit position of some registers.
+ * Following definitions can be foune in s3c{2800,24x0}reg.h for
+ * that reason.
+ *
+ *  ULCON_IR                 (Infra-red mode)
+ *  ULCON_PARITY_SHIFT       (Parity mode bit position)
+ *  UMCON_AFC                (Auto flow control)
+ *  UMSTAT_DCTS              (CTS change)
+ */
+
+#define	SSCOM_ULCON 0x00 /* UART line control */
+/*       ULCON_PARITY_SHIFT and ULCON_IR is defined in s3c{2800,24x0}reg.h */
+#define	 ULCON_PARITY_NONE  (0<<ULCON_PARITY_SHIFT)
+#define	 ULCON_PARITY_ODD   (4<<ULCON_PARITY_SHIFT)
+#define	 ULCON_PARITY_EVEN  (5<<ULCON_PARITY_SHIFT)
+#define	 ULCON_PARITY_ONE   (6<<ULCON_PARITY_SHIFT)
+#define	 ULCON_PARITY_ZERO  (7<<ULCON_PARITY_SHIFT)
+#define	 ULCON_STOP	(1<<2)
+#define	 ULCON_LENGTH_5 0
+#define	 ULCON_LENGTH_6 1
+#define	 ULCON_LENGTH_7 2
+#define	 ULCON_LENGTH_8 3
+#define	SSCOM_UCON	0x04	/* UART control */
+#define	 UCON_TXINT_TYPE	(1<<9)	/* Tx interrupt. 0=pulse,1=level */
+#define	 UCON_TXINT_TYPE_LEVEL  UCON_TXINT_TYPE
+#define	 UCON_TXINT_TYPE_PULSE  0
+#define	 UCON_RXINT_TYPE	(1<<8)	/* Rx interrupt */
+#define	 UCON_RXINT_TYPE_LEVEL  UCON_RXINT_TYPE
+#define	 UCON_RXINT_TYPE_PULSE  0
+#define	 UCON_TOINT	(1<<7)	/* Rx timeout interrupt */
+#define	 UCON_ERRINT	(1<<6)	/* receive error interrupt */
+#define	 UCON_LOOP	(1<<5)	/* loopback */
+#define	 UCON_SBREAK	(1<<4)	/* send break */
+#define	 UCON_TXMODE_DISABLE (0<<2)
+#define	 UCON_TXMODE_INT     (1<<2)
+#define	 UCON_TXMODE_DMA     (2<<2)
+#define	 UCON_TXMODE_MASK    (3<<2)
+#define	 UCON_RXMODE_DISABLE (0<<0)
+#define	 UCON_RXMODE_INT     (1<<0)
+#define	 UCON_RXMODE_DMA     (2<<0)
+#define	 UCON_RXMODE_MASK    (3<<0)
+#define	SSCOM_UFCON	0x08	/* FIFO control */
+#define	 UFCON_TXTRIGGER_0	(0<<6)
+#define	 UFCON_TXTRIGGER_4	(1<<6)
+#define	 UFCON_TXTRIGGER_8	(2<<6)
+#define	 UFCON_TXTRIGGER_16	(3<<6)
+#define	 UFCON_RXTRIGGER_4	(0<<4)
+#define	 UFCON_RXTRIGGER_8	(1<<4)
+#define	 UFCON_RXTRIGGER_12	(2<<4)
+#define	 UFCON_RXTRIGGER_16	(3<<4)
+#define	 UFCON_TXFIFO_RESET	(1<<2)
+#define	 UFCON_RXFIFO_RESET	(1<<1)
+#define	 UFCON_FIFO_ENABLE	(1<<0)
+#define	SSCOM_UMCON	0x0c	/* MODEM control */
+/*       UMCON_AFC is defined in s3c{2800,24x0}reg.h */
+#define	 UMCON_RTS	(1<<0)	/* Request to send */
+#define	SSCOM_UTRSTAT	0x10	/* Status register */
+#define	 UTRSTAT_TXSHIFTER_EMPTY   (1<<2)
+#define	 UTRSTAT_TXEMPTY           (1<<1) /* TX fifo or buffer empty */
+#define	 UTRSTAT_RXREADY	   (1<<0) /* RX fifo or buffer is not empty */
+#define	SSCOM_UERSTAT	0x14	/* Error status register */
+#define	 UERSTAT_BREAK	  (1<<3) /* Break signal, not 2410 */
+#define	 UERSTAT_FRAME	  (1<<2) /* Frame error */
+#define	 UERSTAT_PARITY	  (1<<1) /* Parity error, not 2410 */
+#define	 UERSTAT_OVERRUN  (1<<0) /* Overrun */
+#define	 UERSTAT_ALL_ERRORS \
+    (UERSTAT_OVERRUN|UERSTAT_BREAK|UERSTAT_FRAME|UERSTAT_PARITY)
+#define	SSCOM_UFSTAT	0x18	/* Fifo status register */
+#define	 UFSTAT_TXFULL	  (1<<9) /* Tx fifo full */
+#define	 UFSTAT_RXFULL	  (1<<8) /* Rx fifo full */
+#define	 UFSTAT_TXCOUNT_SHIFT 4		/* TX FIFO count */
+#define	 UFSTAT_TXCOUNT	  (0x0f<<UFSTAT_TXCOUNT_SHIFT)
+#define	 UFSTAT_RXCOUNT_SHIFT 0		/* RX FIFO count */
+#define	 UFSTAT_RXCOUNT	  (0x0f<<UFSTAT_RXCOUNT_SHIFT)
+#define	SSCOM_UMSTAT	0x1c	/* Modem status register */
+/*       UMSTAT_DCTS is defined in s3c{2800,24x0}reg.h */
+#define	 UMSTAT_CTS	  (1<<0) /* Clear to send */
+#if _BYTE_ORDER == _LITTLE_ENDIAN
+#define	SSCOM_UTXH	0x20	/* Transmit data register */
+#define	SSCOM_URXH	0x24	/* Receive data register */
+#else
+#define	SSCOM_UTXH	0x23	/* Transmit data register */
+#define	SSCOM_URXH	0x27	/* Receive data register */
+#endif
+#define	SSCOM_UBRDIV	0x28	/* baud-reate divisor */
+#define	SSCOM_SIZE  0x2c
+
+/* Interrupt controller (Common to S3c2800/2400X/2410X) */
+#define	INTCTL_SRCPND	0x00	/* Interrupt request status */
+#define	INTCTL_INTMOD	0x04	/* Interrupt mode (FIQ/IRQ) */
+#define	INTCTL_INTMSK	0x08	/* Interrupt mask */
+
+#endif /* _ARM_S3C2XX0_S3C2XX0REG_H_ */


Property changes on: trunk/sys/arm/samsung/s3c2xx0/s3c2xx0reg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/samsung/s3c2xx0/s3c2xx0var.h
===================================================================
--- trunk/sys/arm/samsung/s3c2xx0/s3c2xx0var.h	                        (rev 0)
+++ trunk/sys/arm/samsung/s3c2xx0/s3c2xx0var.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,85 @@
+/* $MidnightBSD$ */
+/* $NetBSD: s3c2xx0var.h,v 1.3 2003/08/05 11:26:54 bsh Exp $ */
+
+/*-
+ * Copyright (c) 2002 Fujitsu Component Limited
+ * Copyright (c) 2002 Genetec Corporation
+ * 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.
+ * 3. Neither the name of The Fujitsu Component Limited nor the name of
+ *    Genetec corporation may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY FUJITSU COMPONENT LIMITED AND GENETEC
+ * CORPORATION ``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 FUJITSU COMPONENT LIMITED OR GENETEC
+ * CORPORATION 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: stable/10/sys/arm/samsung/s3c2xx0/s3c2xx0var.h 278727 2015-02-13 22:32:02Z ian $
+ */
+
+#ifndef _ARM_S3C2XX0VAR_H_
+#define _ARM_S3C2XX0VAR_H_
+
+#include <machine/bus.h>
+#include <sys/rman.h>
+
+typedef enum {
+	CPU_S3C2410,
+	CPU_S3C2440,
+} s3c2xx0_cpu;
+
+struct s3c2xx0_softc {
+	device_t	   	sc_dev;
+
+	s3c2xx0_cpu		sc_cpu;
+
+	bus_space_tag_t  	sc_iot;
+
+	bus_space_handle_t	sc_intctl_ioh;
+	bus_space_handle_t	sc_gpio_ioh;  	/* GPIO */
+	bus_space_handle_t	sc_clkman_ioh; 	/* Clock manager */
+	bus_space_handle_t	sc_wdt_ioh; 	/* Watchdog Timer */
+
+	bus_dma_tag_t  		sc_dmat;
+
+	/* clock frequency */
+	int sc_fclk;			/* CPU clock */
+	int sc_hclk;			/* AHB bus clock */
+	int sc_pclk;			/* peripheral clock */
+
+	struct rman s3c2xx0_irq_rman;
+	struct rman s3c2xx0_mem_rman;
+};
+
+struct s3c2xx0_ivar {
+	struct resource_list resources;
+};
+
+typedef void *s3c2xx0_chipset_tag_t;
+
+extern bus_space_tag_t s3c2xx0_bs_tag;
+extern struct s3c2xx0_softc *s3c2xx0_softc;
+extern struct arm32_bus_dma_tag s3c2xx0_bus_dma;
+
+/* Platform needs to provide this */
+bus_dma_tag_t s3c2xx0_bus_dma_init(struct arm32_bus_dma_tag *);
+
+#endif /* _ARM_S3C2XX0VAR_H_ */


Property changes on: trunk/sys/arm/samsung/s3c2xx0/s3c2xx0var.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/samsung/s3c2xx0/std.ln2410sbc
===================================================================
--- trunk/sys/arm/samsung/s3c2xx0/std.ln2410sbc	                        (rev 0)
+++ trunk/sys/arm/samsung/s3c2xx0/std.ln2410sbc	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,10 @@
+#$FreeBSD: stable/10/sys/arm/samsung/s3c2xx0/std.ln2410sbc 272103 2014-09-25 11:38:26Z gavin $
+include "../samsung/s3c2xx0/std.s3c2410"
+
+makeoptions	KERNPHYSADDR=0x30000000
+makeoptions	KERNVIRTADDR=0xc0000000
+options		KERNPHYSADDR=0x30000000	
+options		KERNVIRTADDR=0xc0000000
+options		PHYSADDR=0x30000000
+options		NO_EVENTTIMERS
+


Property changes on: trunk/sys/arm/samsung/s3c2xx0/std.ln2410sbc
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/samsung/s3c2xx0/std.s3c2410
===================================================================
--- trunk/sys/arm/samsung/s3c2xx0/std.s3c2410	                        (rev 0)
+++ trunk/sys/arm/samsung/s3c2xx0/std.s3c2410	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,8 @@
+# $FreeBSD: stable/10/sys/arm/samsung/s3c2xx0/std.s3c2410 272103 2014-09-25 11:38:26Z gavin $
+
+files	"../samsung/s3c2xx0/files.s3c2xx0"
+cpu	CPU_ARM9
+machine 	arm
+
+makeoptions	CONF_CFLAGS=-mcpu=arm920t
+options		NO_EVENTTIMERS


Property changes on: trunk/sys/arm/samsung/s3c2xx0/std.s3c2410
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/samsung/s3c2xx0/uart_bus_s3c2410.c
===================================================================
--- trunk/sys/arm/samsung/s3c2xx0/uart_bus_s3c2410.c	                        (rev 0)
+++ trunk/sys/arm/samsung/s3c2xx0/uart_bus_s3c2410.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,61 @@
+/* $MidnightBSD$ */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/samsung/s3c2xx0/uart_bus_s3c2410.c 283327 2015-05-23 20:54:25Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
+#include <machine/resource.h>
+
+#include <dev/uart/uart.h>
+#include <dev/uart/uart_bus.h>
+#include <dev/uart/uart_cpu.h>
+
+#include <arm/samsung/s3c2xx0/s3c24x0reg.h>
+
+#include "uart_if.h"
+
+extern struct uart_class uart_s3c2410_class;
+
+static int uart_s3c2410_probe(device_t dev);
+
+static device_method_t uart_s3c2410_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		uart_s3c2410_probe),
+	DEVMETHOD(device_attach,	uart_bus_attach),
+	DEVMETHOD(device_detach,	uart_bus_detach),
+	{ 0, 0 }
+};
+
+static driver_t uart_s3c2410_driver = {
+	uart_driver_name,
+	uart_s3c2410_methods,
+	sizeof(struct uart_softc),
+};
+
+extern SLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs;
+static int
+uart_s3c2410_probe(device_t dev)
+{
+	struct uart_devinfo *sysdev;
+	struct uart_softc *sc;
+	int unit;
+
+	sc = device_get_softc(dev);
+	sc->sc_class = &uart_s3c2410_class;
+
+	unit = device_get_unit(dev);
+	sysdev = SLIST_FIRST(&uart_sysdevs);
+	if (S3C24X0_UART_BASE(unit) == sysdev->bas.bsh) {
+		sc->sc_sysdev = sysdev;
+		bcopy(&sc->sc_sysdev->bas, &sc->sc_bas, sizeof(sc->sc_bas));
+	}
+	return(uart_bus_probe(dev, 0, 0, 0, unit));
+}
+
+DRIVER_MODULE(uart, s3c24x0, uart_s3c2410_driver, uart_devclass, 0, 0);


Property changes on: trunk/sys/arm/samsung/s3c2xx0/uart_bus_s3c2410.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/samsung/s3c2xx0/uart_cpu_s3c2410.c
===================================================================
--- trunk/sys/arm/samsung/s3c2xx0/uart_cpu_s3c2410.c	                        (rev 0)
+++ trunk/sys/arm/samsung/s3c2xx0/uart_cpu_s3c2410.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,77 @@
+/* $MidnightBSD$ */
+/*
+ * Copyright (c) 2003 Marcel Moolenaar
+ * Copyright (c) 2007 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 ``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 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: stable/10/sys/arm/samsung/s3c2xx0/uart_cpu_s3c2410.c 283327 2015-05-23 20:54:25Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/cons.h>
+#include <machine/bus.h>
+
+#include <dev/uart/uart.h>
+#include <dev/uart/uart_cpu.h>
+
+#include <arm/samsung/s3c2xx0/s3c2xx0var.h>
+
+extern struct uart_class uart_s3c2410_class;
+
+bus_space_tag_t uart_bus_space_io;
+bus_space_tag_t uart_bus_space_mem;
+
+vm_offset_t s3c2410_uart_vaddr;
+unsigned int s3c2410_pclk;
+
+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)
+{
+	if (devtype != UART_DEV_CONSOLE)
+		return (ENXIO);
+
+	di->ops = uart_getops(&uart_s3c2410_class);
+	di->bas.chan = 0;
+	di->bas.bst = s3c2xx0_bs_tag;
+	di->bas.bsh = s3c2410_uart_vaddr;
+	di->bas.regshft = 0;
+	di->bas.rclk = s3c2410_pclk;
+	di->baudrate = 115200;
+	di->databits = 8;
+	di->stopbits = 1;
+	di->parity = UART_PARITY_NONE;
+	uart_bus_space_io = s3c2xx0_bs_tag;
+	uart_bus_space_mem = NULL;
+	
+	return (0);
+}


Property changes on: trunk/sys/arm/samsung/s3c2xx0/uart_cpu_s3c2410.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/samsung/s3c2xx0/uart_dev_s3c2410.c
===================================================================
--- trunk/sys/arm/samsung/s3c2xx0/uart_dev_s3c2410.c	                        (rev 0)
+++ trunk/sys/arm/samsung/s3c2xx0/uart_dev_s3c2410.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,406 @@
+/* $MidnightBSD$ */
+/*
+ * Copyright (c) 2003 Marcel Moolenaar
+ * Copyright (c) 2007-2009 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 ``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 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: stable/10/sys/arm/samsung/s3c2xx0/uart_dev_s3c2410.c 272103 2014-09-25 11:38:26Z gavin $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/cons.h>
+#include <sys/tty.h>
+#include <sys/rman.h>
+#include <machine/bus.h>
+#include <machine/intr.h>
+
+#include <dev/uart/uart.h>
+#include <dev/uart/uart_cpu.h>
+#include <dev/uart/uart_bus.h>
+#include <arm/samsung/s3c2xx0/s3c2440reg.h>
+#include <arm/samsung/s3c2xx0/uart_dev_s3c2410.h>
+#include <arm/samsung/s3c2xx0/s3c2xx0reg.h>
+#include <arm/samsung/s3c2xx0/s3c2xx0var.h>
+#include "uart_if.h"
+
+/* Finds the subirq from the parent */
+#define get_sub_irq(parent, offset) \
+	((parent == S3C24X0_INT_UART0) ? S3C24X0_SUBIRQ_MIN + offset : \
+	((parent == S3C24X0_INT_UART1) ? S3C24X0_SUBIRQ_MIN + 3 + offset : \
+	  S3C24X0_SUBIRQ_MIN + 6 + offset))
+#define RX_OFF	0
+#define TX_OFF	1
+#define ERR_OFF	2
+
+extern unsigned int s3c2410_pclk;
+
+static int sscomspeed(long, long);
+static int s3c24x0_uart_param(struct uart_bas *, int, int, int, int);
+
+/*
+ * Low-level UART interface.
+ */
+static int s3c2410_probe(struct uart_bas *bas);
+static void s3c2410_init(struct uart_bas *bas, int, int, int, int);
+static void s3c2410_term(struct uart_bas *bas);
+static void s3c2410_putc(struct uart_bas *bas, int);
+static int s3c2410_rxready(struct uart_bas *bas);
+static int s3c2410_getc(struct uart_bas *bas, struct mtx *mtx);
+
+extern SLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs;
+
+static int
+sscomspeed(long speed, long frequency)
+{
+	int x;
+
+	if (speed <= 0 || frequency <= 0)
+		return -1;
+	x = (frequency / 16) / speed;
+	return x-1;
+}
+
+static int
+s3c24x0_uart_param(struct uart_bas *bas, int baudrate, int databits,
+    int stopbits, int parity)
+{
+	int brd, ulcon;
+
+	ulcon = 0;
+
+	switch(databits) {
+	case 5:
+		ulcon |= ULCON_LENGTH_5;
+		break;
+	case 6:
+		ulcon |= ULCON_LENGTH_6;
+		break;
+	case 7:
+		ulcon |= ULCON_LENGTH_7;
+		break;
+	case 8:
+		ulcon |= ULCON_LENGTH_8;
+		break;
+	default:
+		return (EINVAL);
+	}
+
+	switch (parity) {
+	case UART_PARITY_NONE:
+		ulcon |= ULCON_PARITY_NONE;
+		break;
+	case UART_PARITY_ODD:
+		ulcon |= ULCON_PARITY_ODD;
+		break;
+	case UART_PARITY_EVEN:
+		ulcon |= ULCON_PARITY_EVEN;
+		break;
+	case UART_PARITY_MARK:
+	case UART_PARITY_SPACE:
+	default:
+		return (EINVAL);
+	}
+
+	if (stopbits == 2)
+		ulcon |= ULCON_STOP;
+
+	uart_setreg(bas, SSCOM_ULCON, ulcon);
+
+	brd = sscomspeed(baudrate, bas->rclk);
+	uart_setreg(bas, SSCOM_UBRDIV, brd);
+
+	return (0);
+}
+
+struct uart_ops uart_s3c2410_ops = {
+	.probe = s3c2410_probe,
+	.init = s3c2410_init,
+	.term = s3c2410_term,
+	.putc = s3c2410_putc,
+	.rxready = s3c2410_rxready,
+	.getc = s3c2410_getc,
+};
+
+static int
+s3c2410_probe(struct uart_bas *bas)
+{
+	return (0);
+}
+
+static void
+s3c2410_init(struct uart_bas *bas, int baudrate, int databits, int stopbits,
+    int parity)
+{
+	if (bas->rclk == 0)
+		bas->rclk = s3c2410_pclk;
+	KASSERT(bas->rclk != 0, ("s3c2410_init: Invalid rclk"));
+
+	uart_setreg(bas, SSCOM_UCON, 0);
+	uart_setreg(bas, SSCOM_UFCON,
+	    UFCON_TXTRIGGER_8 | UFCON_RXTRIGGER_8 |
+	    UFCON_TXFIFO_RESET | UFCON_RXFIFO_RESET |
+	    UFCON_FIFO_ENABLE);
+	s3c24x0_uart_param(bas, baudrate, databits, stopbits, parity);
+
+	/* Enable UART. */
+	uart_setreg(bas, SSCOM_UCON, UCON_TXMODE_INT | UCON_RXMODE_INT |
+	    UCON_TOINT);
+	uart_setreg(bas, SSCOM_UMCON, UMCON_RTS);
+}
+
+static void
+s3c2410_term(struct uart_bas *bas)
+{
+	/* XXX */
+}
+
+static void
+s3c2410_putc(struct uart_bas *bas, int c)
+{
+	while ((bus_space_read_4(bas->bst, bas->bsh, SSCOM_UFSTAT) &
+	    UFSTAT_TXFULL) == UFSTAT_TXFULL)
+		continue;
+
+	uart_setreg(bas, SSCOM_UTXH, c);
+}
+
+static int
+s3c2410_rxready(struct uart_bas *bas)
+{
+	return ((uart_getreg(bas, SSCOM_UTRSTAT) & UTRSTAT_RXREADY) ==
+	    UTRSTAT_RXREADY);
+}
+
+static int
+s3c2410_getc(struct uart_bas *bas, struct mtx *mtx)
+{
+	while (!sscom_rxrdy(bas->bst, bas->bsh))
+		continue;
+
+	return sscom_getc(bas->bst, bas->bsh);
+}
+static int s3c2410_bus_probe(struct uart_softc *sc);
+static int s3c2410_bus_attach(struct uart_softc *sc);
+static int s3c2410_bus_flush(struct uart_softc *, int);
+static int s3c2410_bus_getsig(struct uart_softc *);
+static int s3c2410_bus_ioctl(struct uart_softc *, int, intptr_t);
+static int s3c2410_bus_ipend(struct uart_softc *);
+static int s3c2410_bus_param(struct uart_softc *, int, int, int, int);
+static int s3c2410_bus_receive(struct uart_softc *);
+static int s3c2410_bus_setsig(struct uart_softc *, int);
+static int s3c2410_bus_transmit(struct uart_softc *);
+static void s3c2410_bus_grab(struct uart_softc *);
+static void s3c2410_bus_ungrab(struct uart_softc *);
+
+static kobj_method_t s3c2410_methods[] = {
+	KOBJMETHOD(uart_probe,		s3c2410_bus_probe),
+	KOBJMETHOD(uart_attach, 	s3c2410_bus_attach),
+	KOBJMETHOD(uart_flush,		s3c2410_bus_flush),
+	KOBJMETHOD(uart_getsig,		s3c2410_bus_getsig),
+	KOBJMETHOD(uart_ioctl,		s3c2410_bus_ioctl),
+	KOBJMETHOD(uart_ipend,		s3c2410_bus_ipend),
+	KOBJMETHOD(uart_param,		s3c2410_bus_param),
+	KOBJMETHOD(uart_receive,	s3c2410_bus_receive),
+	KOBJMETHOD(uart_setsig,		s3c2410_bus_setsig),
+	KOBJMETHOD(uart_transmit,	s3c2410_bus_transmit),
+	KOBJMETHOD(uart_grab,		s3c2410_bus_grab),
+	KOBJMETHOD(uart_ungrab,		s3c2410_bus_ungrab),
+	
+	{0, 0 }
+};
+
+int
+s3c2410_bus_probe(struct uart_softc *sc)
+{
+	switch(s3c2xx0_softc->sc_cpu) {
+	case CPU_S3C2410:
+		sc->sc_txfifosz = 16;
+		sc->sc_rxfifosz = 16;
+		break;
+	case CPU_S3C2440:
+		sc->sc_txfifosz = 64;
+		sc->sc_rxfifosz = 64;
+		break;
+	default:
+		return (ENXIO);
+	}
+
+	return (0);
+}
+
+static int
+s3c2410_bus_attach(struct uart_softc *sc)
+{
+	uintptr_t irq;
+
+	sc->sc_hwiflow = 0;
+	sc->sc_hwoflow = 0;
+
+	irq = rman_get_start(sc->sc_ires);
+	arm_unmask_irq(irq);
+	arm_unmask_irq(get_sub_irq(irq, RX_OFF));
+	arm_unmask_irq(get_sub_irq(irq, TX_OFF));
+	arm_unmask_irq(get_sub_irq(irq, ERR_OFF));
+
+	return (0);
+}
+
+static int
+s3c2410_bus_transmit(struct uart_softc *sc)
+{
+	uintptr_t irq;
+
+	uart_lock(sc->sc_hwmtx);
+
+	for (int i = 0; i < sc->sc_txdatasz; i++) {
+		s3c2410_putc(&sc->sc_bas, sc->sc_txbuf[i]);
+		uart_barrier(&sc->sc_bas);
+	}
+
+	sc->sc_txbusy = 1;
+
+	uart_unlock(sc->sc_hwmtx);
+
+	irq = rman_get_start(sc->sc_ires);
+	arm_unmask_irq(get_sub_irq(irq, TX_OFF));
+
+	return (0);
+}
+
+static int
+s3c2410_bus_setsig(struct uart_softc *sc, int sig)
+{
+	return (0);
+}
+
+static int
+s3c2410_bus_receive(struct uart_softc *sc)
+{
+	
+	uart_rx_put(sc, uart_getreg(&sc->sc_bas, SSCOM_URXH));
+	return (0);
+}
+
+static int
+s3c2410_bus_param(struct uart_softc *sc, int baudrate, int databits,
+    int stopbits, int parity)
+{
+	int error;
+
+	if (sc->sc_bas.rclk == 0)
+		sc->sc_bas.rclk = s3c2410_pclk;
+	KASSERT(sc->sc_bas.rclk != 0, ("s3c2410_init: Invalid rclk"));
+
+	uart_lock(sc->sc_hwmtx);
+	error = s3c24x0_uart_param(&sc->sc_bas, baudrate, databits, stopbits,
+	    parity);
+	uart_unlock(sc->sc_hwmtx);
+
+	return (error);
+}
+
+static int
+s3c2410_bus_ipend(struct uart_softc *sc)
+{
+	uint32_t ufstat, txmask, rxmask;
+	uintptr_t irq;
+	int ipend = 0;
+
+	uart_lock(sc->sc_hwmtx);
+	ufstat = bus_space_read_4(sc->sc_bas.bst, sc->sc_bas.bsh, SSCOM_UFSTAT);
+	uart_unlock(sc->sc_hwmtx);
+
+	txmask = rxmask = 0;
+	switch (s3c2xx0_softc->sc_cpu) {
+	case CPU_S3C2410:
+		txmask = UFSTAT_TXCOUNT;
+		rxmask = UFSTAT_RXCOUNT;
+		break;
+	case CPU_S3C2440:
+		txmask = S3C2440_UFSTAT_TXCOUNT;
+		rxmask = S3C2440_UFSTAT_RXCOUNT;
+		break;
+	}
+	if ((ufstat & txmask) == 0) {
+		if (sc->sc_txbusy != 0)
+			ipend |= SER_INT_TXIDLE;
+		irq = rman_get_start(sc->sc_ires);
+		arm_mask_irq(get_sub_irq(irq, TX_OFF));
+	}
+	if ((ufstat & rxmask) > 0) {
+		ipend |= SER_INT_RXREADY;
+	}
+
+	return (ipend);
+}
+
+static int
+s3c2410_bus_flush(struct uart_softc *sc, int what)
+{
+	return (0);
+}
+
+static int
+s3c2410_bus_getsig(struct uart_softc *sc)
+{
+	return (0);
+}
+
+static int
+s3c2410_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
+{
+	return (EINVAL);
+}
+
+
+static void
+s3c2410_bus_grab(struct uart_softc *sc)
+{
+	uintptr_t irq;
+
+	irq = rman_get_start(sc->sc_ires);
+	arm_mask_irq(get_sub_irq(irq, RX_OFF));
+}
+
+static void
+s3c2410_bus_ungrab(struct uart_softc *sc)
+{
+	uintptr_t irq;
+
+	irq = rman_get_start(sc->sc_ires);
+	arm_unmask_irq(get_sub_irq(irq, RX_OFF));
+}
+
+struct uart_class uart_s3c2410_class = {
+	"s3c2410 class",
+	s3c2410_methods,
+	1,
+	.uc_ops = &uart_s3c2410_ops,
+	.uc_range = 8,
+	.uc_rclk = 0,
+};


Property changes on: trunk/sys/arm/samsung/s3c2xx0/uart_dev_s3c2410.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/samsung/s3c2xx0/uart_dev_s3c2410.h
===================================================================
--- trunk/sys/arm/samsung/s3c2xx0/uart_dev_s3c2410.h	                        (rev 0)
+++ trunk/sys/arm/samsung/s3c2xx0/uart_dev_s3c2410.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,89 @@
+/* $MidnightBSD$ */
+/* $NetBSD: sscom_var.h,v 1.5 2003/08/04 12:28:49 bsh Exp $ */
+
+/*-
+ * Copyright (c) 2002, 2003 Fujitsu Component Limited
+ * Copyright (c) 2002, 2003 Genetec Corporation
+ * 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.
+ * 3. Neither the name of The Fujitsu Component Limited nor the name of
+ *    Genetec corporation may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY FUJITSU COMPONENT LIMITED AND GENETEC
+ * CORPORATION ``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 FUJITSU COMPONENT LIMITED OR GENETEC
+ * CORPORATION 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.
+ */
+/* derived from sys/dev/ic/comvar.h */
+
+/*-
+ * Copyright (c) 1996 Christopher G. Demetriou.  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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by Christopher G. Demetriou
+ *	for the NetBSD Project.
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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: stable/10/sys/arm/samsung/s3c2xx0/uart_dev_s3c2410.h 205354 2010-03-20 03:39:35Z imp $
+ */
+
+#ifndef _ARM_S3C2XX0_SSCOM_VAR_H
+#define _ARM_S3C2XX0_SSCOM_VAR_H
+
+
+/* Hardware flag masks */
+#define	SSCOM_HW_FLOW		0x02
+#define	SSCOM_HW_DEV_OK		0x04
+#define	SSCOM_HW_CONSOLE	0x08
+#define	SSCOM_HW_KGDB		0x10
+#define SSCOM_HW_TXINT		0x20
+#define SSCOM_HW_RXINT		0x40
+
+/* Buffer size for character buffer */
+#define	SSCOM_RING_SIZE	2048
+
+#define sscom_rxrdy(iot,ioh) \
+	(bus_space_read_1((iot), (ioh), SSCOM_UTRSTAT) & UTRSTAT_RXREADY)
+#define sscom_getc(iot,ioh) bus_space_read_1((iot), (ioh), SSCOM_URXH)
+#define sscom_geterr(iot,ioh) bus_space_read_1((iot), (ioh), SSCOM_UERSTAT)
+
+#endif /* _ARM_S3C2XX0_SSCOM_VAR_H */


Property changes on: trunk/sys/arm/samsung/s3c2xx0/uart_dev_s3c2410.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/aintc.c
===================================================================
--- trunk/sys/arm/ti/aintc.c	                        (rev 0)
+++ trunk/sys/arm/ti/aintc.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,196 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Damjan Marion <dmarion at Freebsd.org>
+ * All rights reserved.
+ *
+ * Based on OMAP3 INTC code by Ben Gray
+ *
+ * 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: stable/10/sys/arm/ti/aintc.c 283329 2015-05-23 21:12:51Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/ktr.h>
+#include <sys/module.h>
+#include <sys/rman.h>
+#include <machine/bus.h>
+#include <machine/intr.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#define INTC_REVISION		0x00
+#define INTC_SYSCONFIG		0x10
+#define INTC_SYSSTATUS		0x14
+#define INTC_SIR_IRQ		0x40
+#define INTC_CONTROL		0x48
+#define INTC_THRESHOLD		0x68
+#define INTC_MIR_CLEAR(x)	(0x88 + ((x) * 0x20))
+#define INTC_MIR_SET(x)		(0x8C + ((x) * 0x20))
+#define INTC_ISR_SET(x)		(0x90 + ((x) * 0x20))
+#define INTC_ISR_CLEAR(x)	(0x94 + ((x) * 0x20))
+
+struct ti_aintc_softc {
+	device_t		sc_dev;
+	struct resource *	aintc_res[3];
+	bus_space_tag_t		aintc_bst;
+	bus_space_handle_t	aintc_bsh;
+	uint8_t			ver;
+};
+
+static struct resource_spec ti_aintc_spec[] = {
+	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
+	{ -1, 0 }
+};
+
+
+static struct ti_aintc_softc *ti_aintc_sc = NULL;
+
+#define	aintc_read_4(_sc, reg)		\
+    bus_space_read_4((_sc)->aintc_bst, (_sc)->aintc_bsh, (reg))
+#define	aintc_write_4(_sc, reg, val)		\
+    bus_space_write_4((_sc)->aintc_bst, (_sc)->aintc_bsh, (reg), (val))
+
+
+static void
+aintc_post_filter(void *arg)
+{
+
+	arm_irq_memory_barrier(0);
+	aintc_write_4(ti_aintc_sc, INTC_CONTROL, 1); /* EOI */
+}
+
+static int
+ti_aintc_probe(device_t dev)
+{
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+
+	if (!ofw_bus_is_compatible(dev, "ti,aintc"))
+		return (ENXIO);
+	device_set_desc(dev, "TI AINTC Interrupt Controller");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+ti_aintc_attach(device_t dev)
+{
+	struct		ti_aintc_softc *sc = device_get_softc(dev);
+	uint32_t x;
+
+	sc->sc_dev = dev;
+
+	if (ti_aintc_sc)
+		return (ENXIO);
+
+	if (bus_alloc_resources(dev, ti_aintc_spec, sc->aintc_res)) {
+		device_printf(dev, "could not allocate resources\n");
+		return (ENXIO);
+	}
+
+	sc->aintc_bst = rman_get_bustag(sc->aintc_res[0]);
+	sc->aintc_bsh = rman_get_bushandle(sc->aintc_res[0]);
+
+	ti_aintc_sc = sc;
+
+	x = aintc_read_4(sc, INTC_REVISION);
+	device_printf(dev, "Revision %u.%u\n",(x >> 4) & 0xF, x & 0xF);
+
+	/* SoftReset */
+	aintc_write_4(sc, INTC_SYSCONFIG, 2);
+
+	/* Wait for reset to complete */
+	while(!(aintc_read_4(sc, INTC_SYSSTATUS) & 1));
+
+	/*Set Priority Threshold */
+	aintc_write_4(sc, INTC_THRESHOLD, 0xFF);
+
+	arm_post_filter = aintc_post_filter;
+
+	return (0);
+}
+
+static device_method_t ti_aintc_methods[] = {
+	DEVMETHOD(device_probe,		ti_aintc_probe),
+	DEVMETHOD(device_attach,	ti_aintc_attach),
+	{ 0, 0 }
+};
+
+static driver_t ti_aintc_driver = {
+	"aintc",
+	ti_aintc_methods,
+	sizeof(struct ti_aintc_softc),
+};
+
+static devclass_t ti_aintc_devclass;
+
+DRIVER_MODULE(aintc, simplebus, ti_aintc_driver, ti_aintc_devclass, 0, 0);
+
+int
+arm_get_next_irq(int last_irq)
+{
+	struct ti_aintc_softc *sc = ti_aintc_sc;
+	uint32_t active_irq;
+
+	/* Get the next active interrupt */
+	active_irq = aintc_read_4(sc, INTC_SIR_IRQ);
+
+	/* Check for spurious interrupt */
+	if ((active_irq & 0xffffff80)) {
+		device_printf(sc->sc_dev,
+		    "Spurious interrupt detected (0x%08x)\n", active_irq);
+		aintc_write_4(sc, INTC_SIR_IRQ, 0);
+		return -1;
+	}
+
+	if (active_irq != last_irq)
+		return active_irq;
+	else
+		return -1;
+}
+
+void
+arm_mask_irq(uintptr_t nb)
+{
+	struct ti_aintc_softc *sc = ti_aintc_sc;
+
+	aintc_write_4(sc, INTC_MIR_SET(nb >> 5), (1UL << (nb & 0x1F)));
+	aintc_write_4(sc, INTC_CONTROL, 1); /* EOI */
+}
+
+void
+arm_unmask_irq(uintptr_t nb)
+{
+	struct ti_aintc_softc *sc = ti_aintc_sc;
+
+	arm_irq_memory_barrier(nb);
+	aintc_write_4(sc, INTC_MIR_CLEAR(nb >> 5), (1UL << (nb & 0x1F)));
+}


Property changes on: trunk/sys/arm/ti/aintc.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/am335x/am335x_dmtimer.c
===================================================================
--- trunk/sys/arm/ti/am335x/am335x_dmtimer.c	                        (rev 0)
+++ trunk/sys/arm/ti/am335x/am335x_dmtimer.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,680 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Damjan Marion <dmarion at Freebsd.org>
+ * 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: stable/10/sys/arm/ti/am335x/am335x_dmtimer.c 287040 2015-08-23 17:54:48Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/taskqueue.h>
+#include <sys/timeet.h>
+#include <sys/timepps.h>
+#include <sys/timetc.h>
+#include <sys/watchdog.h>
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+
+#include <arm/ti/ti_prcm.h>
+#include <arm/ti/ti_scm.h>
+
+#define	AM335X_NUM_TIMERS	8
+
+#define	DMT_TIDR		0x00		/* Identification Register */
+#define	DMT_TIOCP_CFG		0x10		/* OCP Configuration Reg */
+#define	  DMT_TIOCP_RESET	  (1 << 0)	/* TIOCP perform soft reset */
+#define	DMT_IQR_EOI		0x20		/* IRQ End-Of-Interrupt Reg */
+#define	DMT_IRQSTATUS_RAW	0x24		/* IRQSTATUS Raw Reg */
+#define	DMT_IRQSTATUS		0x28		/* IRQSTATUS Reg */
+#define	DMT_IRQENABLE_SET	0x2c		/* IRQSTATUS Set Reg */
+#define	DMT_IRQENABLE_CLR	0x30		/* IRQSTATUS Clear Reg */
+#define	DMT_IRQWAKEEN		0x34		/* IRQ Wakeup Enable Reg */
+#define	  DMT_IRQ_MAT		  (1 << 0)	/* IRQ: Match */
+#define	  DMT_IRQ_OVF		  (1 << 1)	/* IRQ: Overflow */
+#define	  DMT_IRQ_TCAR		  (1 << 2)	/* IRQ: Capture */
+#define	  DMT_IRQ_MASK		  (DMT_IRQ_TCAR | DMT_IRQ_OVF | DMT_IRQ_MAT)
+#define	DMT_TCLR		0x38		/* Control Register */
+#define	  DMT_TCLR_START	  (1 << 0)	/* Start timer */
+#define	  DMT_TCLR_AUTOLOAD	  (1 << 1)	/* Auto-reload on overflow */
+#define	  DMT_TCLR_PRES_MASK	  (7 << 2)	/* Prescaler mask */
+#define	  DMT_TCLR_PRES_ENABLE	  (1 << 5)	/* Prescaler enable */
+#define	  DMT_TCLR_COMP_ENABLE	  (1 << 6)	/* Compare enable */
+#define	  DMT_TCLR_PWM_HIGH	  (1 << 7)	/* PWM default output high */
+#define	  DMT_TCLR_CAPTRAN_MASK	  (3 << 8)	/* Capture transition mask */
+#define	  DMT_TCLR_CAPTRAN_NONE	  (0 << 8)	/* Capture: none */
+#define	  DMT_TCLR_CAPTRAN_LOHI	  (1 << 8)	/* Capture lo->hi transition */
+#define	  DMT_TCLR_CAPTRAN_HILO	  (2 << 8)	/* Capture hi->lo transition */
+#define	  DMT_TCLR_CAPTRAN_BOTH	  (3 << 8)	/* Capture both transitions */
+#define	  DMT_TCLR_TRGMODE_MASK	  (3 << 10)	/* Trigger output mode mask */
+#define	  DMT_TCLR_TRGMODE_NONE	  (0 << 10)	/* Trigger off */
+#define	  DMT_TCLR_TRGMODE_OVFL	  (1 << 10)	/* Trigger on overflow */
+#define	  DMT_TCLR_TRGMODE_BOTH	  (2 << 10)	/* Trigger on match + ovflow */
+#define	  DMT_TCLR_PWM_PTOGGLE	  (1 << 12)	/* PWM toggles */
+#define	  DMT_TCLR_CAP_MODE_2ND	  (1 << 13)	/* Capture second event mode */
+#define	  DMT_TCLR_GPO_CFG	  (1 << 14)	/* (no descr in datasheet) */
+#define	DMT_TCRR		0x3C		/* Counter Register */
+#define	DMT_TLDR		0x40		/* Load Reg */
+#define	DMT_TTGR		0x44		/* Trigger Reg */
+#define	DMT_TWPS		0x48		/* Write Posted Status Reg */
+#define	DMT_TMAR		0x4C		/* Match Reg */
+#define	DMT_TCAR1		0x50		/* Capture Reg */
+#define	DMT_TSICR		0x54		/* Synchr. Interface Ctrl Reg */
+#define	  DMT_TSICR_RESET	  (1 << 1)	/* TSICR perform soft reset */
+#define	DMT_TCAR2		0x48		/* Capture Reg */
+
+/*
+ * Use timer 2 for the eventtimer.  When PPS support is not compiled in, there's
+ * no need to use a timer that has an associated capture-input pin, so use timer
+ * 3 for timecounter.  When PPS is compiled in we ignore the default and use
+ * whichever of timers 4-7 have the capture pin configured.
+ */
+#define	DEFAULT_ET_TIMER	2
+#define	DEFAULT_TC_TIMER	3
+
+struct am335x_dmtimer_softc {
+	struct resource *	tmr_mem_res[AM335X_NUM_TIMERS];
+	struct resource *	tmr_irq_res[AM335X_NUM_TIMERS];
+	uint32_t		sysclk_freq;
+	uint32_t		tc_num;		/* Which timer number is tc. */
+	uint32_t		tc_tclr;	/* Cached tc TCLR register. */
+	struct resource *	tc_memres;	/* Resources for tc timer. */
+	uint32_t		et_num;		/* Which timer number is et. */
+	uint32_t		et_tclr;	/* Cached et TCLR register. */
+	struct resource *	et_memres;	/* Resources for et timer. */
+	int			pps_curmode;	/* Edge mode now set in hw. */
+	struct task 		pps_task;	/* For pps_event handling. */
+	struct cdev *		pps_cdev;
+	struct pps_state 	pps;
+	struct timecounter	tc;
+	struct eventtimer	et;
+};
+
+static struct am335x_dmtimer_softc *am335x_dmtimer_sc;
+
+static struct resource_spec am335x_dmtimer_mem_spec[] = {
+	{ SYS_RES_MEMORY,   0,  RF_ACTIVE },
+	{ SYS_RES_MEMORY,   1,  RF_ACTIVE },
+	{ SYS_RES_MEMORY,   2,  RF_ACTIVE },
+	{ SYS_RES_MEMORY,   3,  RF_ACTIVE },
+	{ SYS_RES_MEMORY,   4,  RF_ACTIVE },
+	{ SYS_RES_MEMORY,   5,  RF_ACTIVE },
+	{ SYS_RES_MEMORY,   6,  RF_ACTIVE },
+	{ SYS_RES_MEMORY,   7,  RF_ACTIVE },
+	{ -1,               0,  0 }
+};
+static struct resource_spec am335x_dmtimer_irq_spec[] = {
+	{ SYS_RES_IRQ,      0,  RF_ACTIVE },
+	{ SYS_RES_IRQ,      1,  RF_ACTIVE },
+	{ SYS_RES_IRQ,      2,  RF_ACTIVE },
+	{ SYS_RES_IRQ,      3,  RF_ACTIVE },
+	{ SYS_RES_IRQ,      4,  RF_ACTIVE },
+	{ SYS_RES_IRQ,      5,  RF_ACTIVE },
+	{ SYS_RES_IRQ,      6,  RF_ACTIVE },
+	{ SYS_RES_IRQ,      7,  RF_ACTIVE },
+	{ -1,               0,  0 }
+};
+
+static inline uint32_t
+am335x_dmtimer_tc_read_4(struct am335x_dmtimer_softc *sc, uint32_t reg)
+{
+
+	return (bus_read_4(sc->tc_memres, reg));
+}
+
+static inline void
+am335x_dmtimer_tc_write_4(struct am335x_dmtimer_softc *sc, uint32_t reg,
+    uint32_t val)
+{
+
+	bus_write_4(sc->tc_memres, reg, val);
+}
+
+static inline uint32_t
+am335x_dmtimer_et_read_4(struct am335x_dmtimer_softc *sc, uint32_t reg)
+{
+
+	return (bus_read_4(sc->et_memres, reg));
+}
+
+static inline void
+am335x_dmtimer_et_write_4(struct am335x_dmtimer_softc *sc, uint32_t reg,
+    uint32_t val)
+{
+
+	bus_write_4(sc->et_memres, reg, val);
+}
+
+/*
+ * PPS driver routines, included when the kernel is built with option PPS_SYNC.
+ *
+ * Note that this PPS driver does not use an interrupt.  Instead it uses the
+ * hardware's ability to latch the timer's count register in response to a
+ * signal on an IO pin.  Each of timers 4-7 have an associated pin, and this
+ * code allows any one of those to be used.
+ *
+ * The timecounter routines in kern_tc.c call the pps poll routine periodically
+ * to see if a new counter value has been latched.  When a new value has been
+ * latched, the only processing done in the poll routine is to capture the
+ * current set of timecounter timehands (done with pps_capture()) and the
+ * latched value from the timer.  The remaining work (done by pps_event()) is
+ * scheduled to be done later in a non-interrupt context.
+ */
+
+#define	PPS_CDEV_NAME	"dmtpps"
+
+static void
+am335x_dmtimer_set_capture_mode(struct am335x_dmtimer_softc *sc, bool force_off)
+{
+	int newmode;
+
+	if (force_off)
+		newmode = 0;
+	else
+		newmode = sc->pps.ppsparam.mode & PPS_CAPTUREBOTH;
+
+	if (newmode == sc->pps_curmode)
+		return;
+
+	sc->pps_curmode = newmode;
+	sc->tc_tclr &= ~DMT_TCLR_CAPTRAN_MASK;
+	switch (newmode) {
+	case PPS_CAPTUREASSERT:
+		sc->tc_tclr |= DMT_TCLR_CAPTRAN_LOHI;
+		break;
+	case PPS_CAPTURECLEAR:
+		sc->tc_tclr |= DMT_TCLR_CAPTRAN_HILO;
+		break;
+	default:
+		/* It can't be BOTH, so it's disabled. */
+		break;
+	}
+	am335x_dmtimer_tc_write_4(sc, DMT_TCLR, sc->tc_tclr);
+}
+
+static void
+am335x_dmtimer_tc_poll_pps(struct timecounter *tc)
+{
+	struct am335x_dmtimer_softc *sc;
+
+	sc = tc->tc_priv;
+
+	/*
+	 * Note that we don't have the TCAR interrupt enabled, but the hardware
+	 * still provides the status bits in the "RAW" status register even when
+	 * they're masked from generating an irq.  However, when clearing the
+	 * TCAR status to re-arm the capture for the next second, we have to
+	 * write to the IRQ status register, not the RAW register.  Quirky.
+	 */
+	if (am335x_dmtimer_tc_read_4(sc, DMT_IRQSTATUS_RAW) & DMT_IRQ_TCAR) {
+		pps_capture(&sc->pps);
+		sc->pps.capcount = am335x_dmtimer_tc_read_4(sc, DMT_TCAR1);
+		am335x_dmtimer_tc_write_4(sc, DMT_IRQSTATUS, DMT_IRQ_TCAR);
+		taskqueue_enqueue_fast(taskqueue_fast, &sc->pps_task);
+	}
+}
+
+static void
+am335x_dmtimer_process_pps_event(void *arg, int pending)
+{
+	struct am335x_dmtimer_softc *sc;
+
+	sc = arg;
+
+	/* This is the task function that gets enqueued by poll_pps.  Once the
+	 * time has been captured in the hw interrupt context, the remaining
+	 * (more expensive) work to process the event is done later in a
+	 * non-fast-interrupt context.
+	 *
+	 * We only support capture of the rising or falling edge, not both at
+	 * once; tell the kernel to process whichever mode is currently active.
+	 */
+	pps_event(&sc->pps, sc->pps.ppsparam.mode & PPS_CAPTUREBOTH);
+}
+
+static int
+am335x_dmtimer_pps_open(struct cdev *dev, int flags, int fmt, 
+    struct thread *td)
+{
+	struct am335x_dmtimer_softc *sc;
+
+	sc = dev->si_drv1;
+
+	/* Enable capture on open.  Harmless if already open. */
+	am335x_dmtimer_set_capture_mode(sc, 0);
+
+	return 0;
+}
+
+static	int
+am335x_dmtimer_pps_close(struct cdev *dev, int flags, int fmt, 
+    struct thread *td)
+{
+	struct am335x_dmtimer_softc *sc;
+
+	sc = dev->si_drv1;
+
+	/*
+	 * Disable capture on last close.  Use the force-off flag to override
+	 * the configured mode and turn off the hardware capture.
+	 */
+	am335x_dmtimer_set_capture_mode(sc, 1);
+
+	return 0;
+}
+
+static int
+am335x_dmtimer_pps_ioctl(struct cdev *dev, u_long cmd, caddr_t data, 
+    int flags, struct thread *td)
+{
+	struct am335x_dmtimer_softc *sc;
+	int err;
+
+	sc = dev->si_drv1;
+
+	/*
+	 * The hardware has a "capture both edges" mode, but we can't do
+	 * anything useful with it in terms of PPS capture, so don't even try.
+	 */
+	if ((sc->pps.ppsparam.mode & PPS_CAPTUREBOTH) == PPS_CAPTUREBOTH)
+		return (EINVAL);
+
+	/* Let the kernel do the heavy lifting for ioctl. */
+	err = pps_ioctl(cmd, data, &sc->pps);
+	if (err != 0)
+		return (err);
+
+	/*
+	 * The capture mode could have changed, set the hardware to whatever
+	 * mode is now current.  Effectively a no-op if nothing changed.
+	 */
+	am335x_dmtimer_set_capture_mode(sc, 0);
+
+	return (err);
+}
+
+static struct cdevsw am335x_dmtimer_pps_cdevsw = {
+	.d_version =    D_VERSION,
+	.d_open =       am335x_dmtimer_pps_open,
+	.d_close =      am335x_dmtimer_pps_close,
+	.d_ioctl =      am335x_dmtimer_pps_ioctl,
+	.d_name =       PPS_CDEV_NAME,
+};
+
+/*
+ * Set up the PPS cdev and the the kernel timepps stuff.
+ *
+ * Note that this routine cannot touch the hardware, because bus space resources
+ * are not fully set up yet when this is called.
+ */
+static int
+am335x_dmtimer_pps_init(device_t dev, struct am335x_dmtimer_softc *sc)
+{
+	int i, timer_num, unit;
+	unsigned int padstate;
+	const char * padmux;
+	struct padinfo {
+		char * ballname;
+		char * muxname;
+		int    timer_num;
+	} padinfo[] = {
+		{"GPMC_ADVn_ALE", "timer4", 4}, 
+		{"GPMC_BEn0_CLE", "timer5", 5},
+		{"GPMC_WEn",      "timer6", 6},
+		{"GPMC_OEn_REn",  "timer7", 7},
+	};
+
+	/*
+	 * Figure out which pin the user has set up for pps.  We'll use the
+	 * first timer that has an external caputure pin configured as input.
+	 *
+	 * XXX The hieroglyphic "(padstate & (0x01 << 5)))" checks that the pin
+	 * is configured for input.  The right symbolic values aren't exported
+	 * yet from ti_scm.h.
+	 */
+	timer_num = 0;
+	for (i = 0; i < nitems(padinfo) && timer_num == 0; ++i) {
+		if (ti_scm_padconf_get(padinfo[i].ballname, &padmux, 
+		    &padstate) == 0) {
+			if (strcasecmp(padinfo[i].muxname, padmux) == 0 &&
+			    (padstate & (0x01 << 5)))
+				timer_num = padinfo[i].timer_num;
+		}
+	}
+
+	if (timer_num == 0) {
+		device_printf(dev, "No DMTimer found with capture pin "
+		    "configured as input; PPS driver disabled.\n");
+		return (DEFAULT_TC_TIMER);
+	}
+
+	/*
+	 * Indicate our capabilities (pretty much just capture of either edge).
+	 * Have the kernel init its part of the pps_state struct and add its
+	 * capabilities.
+	 */
+	sc->pps.ppscap = PPS_CAPTUREBOTH;
+	pps_init(&sc->pps);
+
+	/*
+	 * Set up to capture the PPS via timecounter polling, and init the task
+	 * that does deferred pps_event() processing after capture.
+	 */
+	sc->tc.tc_poll_pps = am335x_dmtimer_tc_poll_pps;
+	TASK_INIT(&sc->pps_task, 0, am335x_dmtimer_process_pps_event, sc);
+
+	/* Create the PPS cdev.  */
+	unit = device_get_unit(dev);
+	sc->pps_cdev = make_dev(&am335x_dmtimer_pps_cdevsw, unit, 
+	    UID_ROOT, GID_WHEEL, 0600, PPS_CDEV_NAME);
+	sc->pps_cdev->si_drv1 = sc;
+
+	device_printf(dev, "Using DMTimer%d for PPS device /dev/%s%d\n", 
+	    timer_num, PPS_CDEV_NAME, unit);
+
+	return (timer_num);
+}
+
+/*
+ * End of PPS driver code.
+ */
+
+static unsigned
+am335x_dmtimer_tc_get_timecount(struct timecounter *tc)
+{
+	struct am335x_dmtimer_softc *sc;
+
+	sc = tc->tc_priv;
+
+	return (am335x_dmtimer_tc_read_4(sc, DMT_TCRR));
+}
+
+static int
+am335x_dmtimer_start(struct eventtimer *et, sbintime_t first, sbintime_t period)
+{
+	struct am335x_dmtimer_softc *sc;
+	uint32_t initial_count, reload_count;
+
+	sc = et->et_priv;
+
+	/*
+	 * Stop the timer before changing it.  This routine will often be called
+	 * while the timer is still running, to either lengthen or shorten the
+	 * current event time.  We need to ensure the timer doesn't expire while
+	 * we're working with it.
+	 *
+	 * Also clear any pending interrupt status, because it's at least
+	 * theoretically possible that we're running in a primary interrupt
+	 * context now, and a timer interrupt could be pending even before we
+	 * stopped the timer.  The more likely case is that we're being called
+	 * from the et_event_cb() routine dispatched from our own handler, but
+	 * it's not clear to me that that's the only case possible.
+	 */
+	sc->et_tclr &= ~(DMT_TCLR_START | DMT_TCLR_AUTOLOAD);
+	am335x_dmtimer_et_write_4(sc, DMT_TCLR, sc->et_tclr);
+	am335x_dmtimer_et_write_4(sc, DMT_IRQSTATUS, DMT_IRQ_OVF);
+
+	if (period != 0) {
+		reload_count = ((uint32_t)et->et_frequency * period) >> 32;
+		sc->et_tclr |= DMT_TCLR_AUTOLOAD;
+	} else {
+		reload_count = 0;
+	}
+
+	if (first != 0)
+		initial_count = ((uint32_t)et->et_frequency * first) >> 32;
+	else
+		initial_count = reload_count;
+
+	/*
+	 * Set auto-reload and current-count values.  This timer hardware counts
+	 * up from the initial/reload value and interrupts on the zero rollover.
+	 */
+	am335x_dmtimer_et_write_4(sc, DMT_TLDR, 0xFFFFFFFF - reload_count);
+	am335x_dmtimer_et_write_4(sc, DMT_TCRR, 0xFFFFFFFF - initial_count);
+
+	/* Enable overflow interrupt, and start the timer. */
+	am335x_dmtimer_et_write_4(sc, DMT_IRQENABLE_SET, DMT_IRQ_OVF);
+	sc->et_tclr |= DMT_TCLR_START;
+	am335x_dmtimer_et_write_4(sc, DMT_TCLR, sc->et_tclr);
+
+	return (0);
+}
+
+static int
+am335x_dmtimer_stop(struct eventtimer *et)
+{
+	struct am335x_dmtimer_softc *sc;
+
+	sc = et->et_priv;
+
+	/* Stop timer, disable and clear interrupt. */
+	sc->et_tclr &= ~(DMT_TCLR_START | DMT_TCLR_AUTOLOAD);
+	am335x_dmtimer_et_write_4(sc, DMT_TCLR, sc->et_tclr);
+	am335x_dmtimer_et_write_4(sc, DMT_IRQENABLE_CLR, DMT_IRQ_OVF);
+	am335x_dmtimer_et_write_4(sc, DMT_IRQSTATUS, DMT_IRQ_OVF);
+	return (0);
+}
+
+static int
+am335x_dmtimer_intr(void *arg)
+{
+	struct am335x_dmtimer_softc *sc;
+
+	sc = arg;
+
+	/* Ack the interrupt, and invoke the callback if it's still enabled. */
+	am335x_dmtimer_et_write_4(sc, DMT_IRQSTATUS, DMT_IRQ_OVF);
+	if (sc->et.et_active)
+		sc->et.et_event_cb(&sc->et, sc->et.et_arg);
+
+	return (FILTER_HANDLED);
+}
+
+static int
+am335x_dmtimer_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (ofw_bus_is_compatible(dev, "ti,am335x-dmtimer")) {
+		device_set_desc(dev, "AM335x DMTimer");
+		return(BUS_PROBE_DEFAULT);
+	}
+
+	return (ENXIO);
+}
+
+static int
+am335x_dmtimer_attach(device_t dev)
+{
+	struct am335x_dmtimer_softc *sc;
+	void *ihl;
+	int err;
+
+	/*
+	 * Note that if this routine returns an error status rather than running
+	 * to completion it makes no attempt to clean up allocated resources;
+	 * the system is essentially dead anyway without functional timers.
+	 */
+
+	sc = device_get_softc(dev);
+
+	if (am335x_dmtimer_sc != NULL)
+		return (EINVAL);
+
+	/* Get the base clock frequency. */
+	err = ti_prcm_clk_get_source_freq(SYS_CLK, &sc->sysclk_freq);
+	if (err) {
+		device_printf(dev, "Error: could not get sysclk frequency\n");
+		return (ENXIO);
+	}
+
+	/* Request the memory resources. */
+	err = bus_alloc_resources(dev, am335x_dmtimer_mem_spec,
+		sc->tmr_mem_res);
+	if (err) {
+		device_printf(dev, "Error: could not allocate mem resources\n");
+		return (ENXIO);
+	}
+
+	/* Request the IRQ resources. */
+	err = bus_alloc_resources(dev, am335x_dmtimer_irq_spec,
+		sc->tmr_irq_res);
+	if (err) {
+		device_printf(dev, "Error: could not allocate irq resources\n");
+		return (ENXIO);
+	}
+
+	/*
+	 * Use the default eventtimer.  Let the PPS init routine decide which
+	 * timer to use for the timecounter.
+	 */
+	sc->et_num = DEFAULT_ET_TIMER;
+	sc->tc_num = am335x_dmtimer_pps_init(dev, sc);
+
+	sc->et_memres = sc->tmr_mem_res[sc->et_num];
+	sc->tc_memres = sc->tmr_mem_res[sc->tc_num];
+
+	/* Enable clocks and power on the chosen devices. */
+	err  = ti_prcm_clk_set_source(DMTIMER0_CLK + sc->et_num, SYSCLK_CLK);
+	err |= ti_prcm_clk_enable(DMTIMER0_CLK + sc->et_num);
+	err |= ti_prcm_clk_set_source(DMTIMER0_CLK + sc->tc_num, SYSCLK_CLK);
+	err |= ti_prcm_clk_enable(DMTIMER0_CLK + sc->tc_num);
+	if (err) {
+		device_printf(dev, "Error: could not enable timer clock\n");
+		return (ENXIO);
+	}
+
+	/* Setup eventtimer interrupt handler. */
+	if (bus_setup_intr(dev, sc->tmr_irq_res[sc->et_num], INTR_TYPE_CLK,
+			am335x_dmtimer_intr, NULL, sc, &ihl) != 0) {
+		device_printf(dev, "Unable to setup the clock irq handler.\n");
+		return (ENXIO);
+	}
+
+	/* Set up timecounter, start it, register it. */
+	am335x_dmtimer_tc_write_4(sc, DMT_TSICR, DMT_TSICR_RESET);
+	while (am335x_dmtimer_tc_read_4(sc, DMT_TIOCP_CFG) & DMT_TIOCP_RESET)
+		continue;
+
+	sc->tc_tclr |= DMT_TCLR_START | DMT_TCLR_AUTOLOAD;
+	am335x_dmtimer_tc_write_4(sc, DMT_TLDR, 0);
+	am335x_dmtimer_tc_write_4(sc, DMT_TCRR, 0);
+	am335x_dmtimer_tc_write_4(sc, DMT_TCLR, sc->tc_tclr);
+
+	sc->tc.tc_name           = "AM335x Timecounter";
+	sc->tc.tc_get_timecount  = am335x_dmtimer_tc_get_timecount;
+	sc->tc.tc_counter_mask   = ~0u;
+	sc->tc.tc_frequency      = sc->sysclk_freq;
+	sc->tc.tc_quality        = 1000;
+	sc->tc.tc_priv           = sc;
+	tc_init(&sc->tc);
+
+	sc->et.et_name = "AM335x Eventtimer";
+	sc->et.et_flags = ET_FLAGS_PERIODIC | ET_FLAGS_ONESHOT;
+	sc->et.et_quality = 1000;
+	sc->et.et_frequency = sc->sysclk_freq;
+	sc->et.et_min_period =
+	    ((0x00000005LLU << 32) / sc->et.et_frequency);
+	sc->et.et_max_period =
+	    (0xfffffffeLLU << 32) / sc->et.et_frequency;
+	sc->et.et_start = am335x_dmtimer_start;
+	sc->et.et_stop = am335x_dmtimer_stop;
+	sc->et.et_priv = sc;
+	et_register(&sc->et);
+
+	/* Store a pointer to the softc for use in DELAY(). */
+	am335x_dmtimer_sc = sc;
+
+	return (0);
+}
+
+static device_method_t am335x_dmtimer_methods[] = {
+	DEVMETHOD(device_probe,		am335x_dmtimer_probe),
+	DEVMETHOD(device_attach,	am335x_dmtimer_attach),
+	{ 0, 0 }
+};
+
+static driver_t am335x_dmtimer_driver = {
+	"am335x_dmtimer",
+	am335x_dmtimer_methods,
+	sizeof(struct am335x_dmtimer_softc),
+};
+
+static devclass_t am335x_dmtimer_devclass;
+
+DRIVER_MODULE(am335x_dmtimer, simplebus, am335x_dmtimer_driver, am335x_dmtimer_devclass, 0, 0);
+MODULE_DEPEND(am335x_dmtimer, am335x_prcm, 1, 1, 1);
+
+void
+DELAY(int usec)
+{
+	struct am335x_dmtimer_softc *sc;
+	int32_t counts;
+	uint32_t first, last;
+
+	sc = am335x_dmtimer_sc;
+
+	if (sc == NULL) {
+		for (; usec > 0; usec--)
+			for (counts = 200; counts > 0; counts--)
+				/* Prevent gcc from optimizing  out the loop */
+				cpufunc_nullop();
+		return;
+	}
+
+	/* Get the number of times to count */
+	counts = (usec + 1) * (sc->sysclk_freq / 1000000);
+
+	first = am335x_dmtimer_tc_read_4(sc, DMT_TCRR);
+
+	while (counts > 0) {
+		last = am335x_dmtimer_tc_read_4(sc, DMT_TCRR);
+		if (last > first) {
+			counts -= (int32_t)(last - first);
+		} else {
+			counts -= (int32_t)((0xFFFFFFFF - first) + last);
+		}
+		first = last;
+	}
+}
+


Property changes on: trunk/sys/arm/ti/am335x/am335x_dmtimer.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/am335x/am335x_lcd.c
===================================================================
--- trunk/sys/arm/ti/am335x/am335x_lcd.c	                        (rev 0)
+++ trunk/sys/arm/ti/am335x/am335x_lcd.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,693 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright 2013 Oleksandr Tymoshenko <gonzo at freebsd.org>
+ * 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: stable/10/sys/arm/ti/am335x/am335x_lcd.c 266152 2014-05-15 16:11:06Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/clock.h>
+#include <sys/time.h>
+#include <sys/bus.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+#include <sys/sysctl.h>
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+/* syscons bits */
+#include <sys/fbio.h>
+#include <sys/consio.h>
+
+#include <machine/bus.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <dev/fb/fbreg.h>
+#include <dev/syscons/syscons.h>
+
+#include <arm/ti/ti_prcm.h>
+#include <arm/ti/ti_scm.h>
+
+#include "am335x_lcd.h"
+#include "am335x_pwm.h"
+
+#define	LCD_PID			0x00
+#define	LCD_CTRL		0x04
+#define		CTRL_DIV_MASK		0xff
+#define		CTRL_DIV_SHIFT		8
+#define		CTRL_AUTO_UFLOW_RESTART	(1 << 1)
+#define		CTRL_RASTER_MODE	1
+#define		CTRL_LIDD_MODE		0
+#define	LCD_LIDD_CTRL		0x0C
+#define	LCD_LIDD_CS0_CONF	0x10
+#define	LCD_LIDD_CS0_ADDR	0x14
+#define	LCD_LIDD_CS0_DATA	0x18
+#define	LCD_LIDD_CS1_CONF	0x1C
+#define	LCD_LIDD_CS1_ADDR	0x20
+#define	LCD_LIDD_CS1_DATA	0x24
+#define	LCD_RASTER_CTRL		0x28
+#define		RASTER_CTRL_TFT24_UNPACKED	(1 << 26)
+#define		RASTER_CTRL_TFT24		(1 << 25)
+#define		RASTER_CTRL_STN565		(1 << 24)
+#define		RASTER_CTRL_TFTPMAP		(1 << 23)
+#define		RASTER_CTRL_NIBMODE		(1 << 22)
+#define		RASTER_CTRL_PALMODE_SHIFT	20
+#define		PALETTE_PALETTE_AND_DATA	0x00
+#define		PALETTE_PALETTE_ONLY		0x01
+#define		PALETTE_DATA_ONLY		0x02
+#define		RASTER_CTRL_REQDLY_SHIFT	12
+#define		RASTER_CTRL_MONO8B		(1 << 9)
+#define		RASTER_CTRL_RBORDER		(1 << 8)
+#define		RASTER_CTRL_LCDTFT		(1 << 7)
+#define		RASTER_CTRL_LCDBW		(1 << 1)
+#define		RASTER_CTRL_LCDEN		(1 << 0)
+#define	LCD_RASTER_TIMING_0	0x2C
+#define		RASTER_TIMING_0_HBP_SHIFT	24
+#define		RASTER_TIMING_0_HFP_SHIFT	16
+#define		RASTER_TIMING_0_HSW_SHIFT	10
+#define		RASTER_TIMING_0_PPLLSB_SHIFT	4
+#define		RASTER_TIMING_0_PPLMSB_SHIFT	3
+#define	LCD_RASTER_TIMING_1	0x30
+#define		RASTER_TIMING_1_VBP_SHIFT	24
+#define		RASTER_TIMING_1_VFP_SHIFT	16
+#define		RASTER_TIMING_1_VSW_SHIFT	10
+#define		RASTER_TIMING_1_LPP_SHIFT	0
+#define	LCD_RASTER_TIMING_2	0x34
+#define		RASTER_TIMING_2_HSWHI_SHIFT	27
+#define		RASTER_TIMING_2_LPP_B10_SHIFT	26
+#define		RASTER_TIMING_2_PHSVS		(1 << 25)
+#define		RASTER_TIMING_2_PHSVS_RISE	(1 << 24)
+#define		RASTER_TIMING_2_PHSVS_FALL	(0 << 24)
+#define		RASTER_TIMING_2_IOE		(1 << 23)
+#define		RASTER_TIMING_2_IPC		(1 << 22)
+#define		RASTER_TIMING_2_IHS		(1 << 21)
+#define		RASTER_TIMING_2_IVS		(1 << 20)
+#define		RASTER_TIMING_2_ACBI_SHIFT	16
+#define		RASTER_TIMING_2_ACB_SHIFT	8
+#define		RASTER_TIMING_2_HBPHI_SHIFT	4
+#define		RASTER_TIMING_2_HFPHI_SHIFT	0
+#define	LCD_RASTER_SUBPANEL	0x38
+#define	LCD_RASTER_SUBPANEL2	0x3C
+#define	LCD_LCDDMA_CTRL		0x40
+#define		LCDDMA_CTRL_DMA_MASTER_PRIO_SHIFT		16
+#define		LCDDMA_CTRL_TH_FIFO_RDY_SHIFT	8
+#define		LCDDMA_CTRL_BURST_SIZE_SHIFT	4
+#define		LCDDMA_CTRL_BYTES_SWAP		(1 << 3)
+#define		LCDDMA_CTRL_BE			(1 << 1)
+#define		LCDDMA_CTRL_FB0_ONLY		0
+#define		LCDDMA_CTRL_FB0_FB1		(1 << 0)
+#define	LCD_LCDDMA_FB0_BASE	0x44
+#define	LCD_LCDDMA_FB0_CEILING	0x48
+#define	LCD_LCDDMA_FB1_BASE	0x4C
+#define	LCD_LCDDMA_FB1_CEILING	0x50
+#define	LCD_SYSCONFIG		0x54
+#define		SYSCONFIG_STANDBY_FORCE		(0 << 4)
+#define		SYSCONFIG_STANDBY_NONE		(1 << 4)
+#define		SYSCONFIG_STANDBY_SMART		(2 << 4)
+#define		SYSCONFIG_IDLE_FORCE		(0 << 2)
+#define		SYSCONFIG_IDLE_NONE		(1 << 2)
+#define		SYSCONFIG_IDLE_SMART		(2 << 2)
+#define	LCD_IRQSTATUS_RAW	0x58
+#define	LCD_IRQSTATUS		0x5C
+#define	LCD_IRQENABLE_SET	0x60
+#define	LCD_IRQENABLE_CLEAR	0x64
+#define		IRQ_EOF1		(1 << 9)
+#define		IRQ_EOF0		(1 << 8)
+#define		IRQ_PL			(1 << 6)
+#define		IRQ_FUF			(1 << 5)
+#define		IRQ_ACB			(1 << 3)
+#define		IRQ_SYNC_LOST		(1 << 2)
+#define		IRQ_RASTER_DONE		(1 << 1)
+#define		IRQ_FRAME_DONE		(1 << 0)
+#define	LCD_CLKC_ENABLE		0x6C
+#define		CLKC_ENABLE_DMA		(1 << 2)
+#define		CLKC_ENABLE_LDID	(1 << 1)
+#define		CLKC_ENABLE_CORE	(1 << 0)
+#define	LCD_CLKC_RESET		0x70
+#define		CLKC_RESET_MAIN		(1 << 3)
+#define		CLKC_RESET_DMA		(1 << 2)
+#define		CLKC_RESET_LDID		(1 << 1)
+#define		CLKC_RESET_CORE		(1 << 0)
+
+#define	LCD_LOCK(_sc)		mtx_lock(&(_sc)->sc_mtx)
+#define	LCD_UNLOCK(_sc)		mtx_unlock(&(_sc)->sc_mtx)
+#define	LCD_LOCK_INIT(_sc)	mtx_init(&(_sc)->sc_mtx, \
+    device_get_nameunit(_sc->sc_dev), "am335x_lcd", MTX_DEF)
+#define	LCD_LOCK_DESTROY(_sc)	mtx_destroy(&(_sc)->sc_mtx);
+
+#define	LCD_READ4(_sc, reg)	bus_read_4((_sc)->sc_mem_res, reg);
+#define	LCD_WRITE4(_sc, reg, value)	\
+    bus_write_4((_sc)->sc_mem_res, reg, value);
+
+
+/* Backlight is controlled by eCAS interface on PWM unit 0 */
+#define	PWM_UNIT	0
+#define	PWM_PERIOD	100
+
+struct am335x_lcd_softc {
+	device_t		sc_dev;
+	struct resource		*sc_mem_res;
+	struct resource		*sc_irq_res;
+	void			*sc_intr_hl;
+	struct mtx		sc_mtx;
+	int			sc_backlight;
+	struct sysctl_oid	*sc_oid;
+
+	/* Framebuffer */
+	bus_dma_tag_t		sc_dma_tag;
+	bus_dmamap_t		sc_dma_map;
+	size_t			sc_fb_size;
+	bus_addr_t		sc_fb_phys;
+	uint8_t			*sc_fb_base;
+};
+
+static void
+am335x_fb_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int err)
+{
+	bus_addr_t *addr;
+
+	if (err)
+		return;
+
+	addr = (bus_addr_t*)arg;
+	*addr = segs[0].ds_addr;
+}
+
+static uint32_t
+am335x_lcd_calc_divisor(uint32_t reference, uint32_t freq)
+{
+	uint32_t div;
+	/* Raster mode case: divisors are in range from 2 to 255 */
+	for (div = 2; div < 255; div++)
+		if (reference/div <= freq)
+			return (div);
+
+	return (255);
+}
+
+static int
+am335x_lcd_sysctl_backlight(SYSCTL_HANDLER_ARGS)
+{
+	struct am335x_lcd_softc *sc = (struct am335x_lcd_softc*)arg1;
+	int error;
+	int backlight;
+       
+	backlight = sc->sc_backlight;;
+	error = sysctl_handle_int(oidp, &backlight, 0, req);
+
+	if (error != 0 || req->newptr == NULL)
+		return (error);
+
+	if (backlight < 0)
+		backlight = 0;
+	if (backlight > 100)
+		backlight = 100;
+
+	LCD_LOCK(sc);
+	error = am335x_pwm_config_ecas(PWM_UNIT, PWM_PERIOD,
+	    backlight*PWM_PERIOD/100);
+	if (error == 0)
+		sc->sc_backlight = backlight;
+	LCD_UNLOCK(sc);
+
+	return (error);
+}
+
+static int
+am335x_read_panel_property(device_t dev, const char *name, uint32_t *val)
+{
+	phandle_t node;
+	pcell_t cell;
+
+	node = ofw_bus_get_node(dev);
+	if ((OF_getprop(node, name, &cell, sizeof(cell))) <= 0) {
+		device_printf(dev, "missing '%s' attribute in LCD panel info\n",
+		    name);
+		return (ENXIO);
+	}
+
+	*val = fdt32_to_cpu(cell);
+
+	return (0);
+}
+
+static int
+am335x_read_panel_info(device_t dev, struct panel_info *panel)
+{
+	int error;
+
+	error = 0;
+	if ((error = am335x_read_panel_property(dev,
+	    "panel_width", &panel->panel_width)))
+		goto out;
+
+	if ((error = am335x_read_panel_property(dev,
+	    "panel_height", &panel->panel_height)))
+		goto out;
+
+	if ((error = am335x_read_panel_property(dev,
+	    "panel_hfp", &panel->panel_hfp)))
+		goto out;
+
+	if ((error = am335x_read_panel_property(dev,
+	    "panel_hbp", &panel->panel_hbp)))
+		goto out;
+
+	if ((error = am335x_read_panel_property(dev,
+	    "panel_hsw", &panel->panel_hsw)))
+		goto out;
+
+	if ((error = am335x_read_panel_property(dev,
+	    "panel_vfp", &panel->panel_vfp)))
+		goto out;
+
+	if ((error = am335x_read_panel_property(dev,
+	    "panel_vbp", &panel->panel_vbp)))
+		goto out;
+
+	if ((error = am335x_read_panel_property(dev,
+	    "panel_vsw", &panel->panel_vsw)))
+		goto out;
+
+	if ((error = am335x_read_panel_property(dev,
+	    "panel_pxl_clk", &panel->panel_pxl_clk)))
+		goto out;
+
+	if ((error = am335x_read_panel_property(dev,
+	    "panel_invert_pxl_clk", &panel->panel_invert_pxl_clk)))
+		goto out;
+
+	if ((error = am335x_read_panel_property(dev,
+	    "ac_bias", &panel->ac_bias)))
+		goto out;
+
+	if ((error = am335x_read_panel_property(dev,
+	    "ac_bias_intrpt", &panel->ac_bias_intrpt)))
+		goto out;
+
+	if ((error = am335x_read_panel_property(dev,
+	    "dma_burst_sz", &panel->dma_burst_sz)))
+		goto out;
+
+	if ((error = am335x_read_panel_property(dev,
+	    "bpp", &panel->bpp)))
+		goto out;
+
+	if ((error = am335x_read_panel_property(dev,
+	    "fdd", &panel->fdd)))
+		goto out;
+
+	if ((error = am335x_read_panel_property(dev,
+	    "invert_line_clock", &panel->invert_line_clock)))
+		goto out;
+
+	if ((error = am335x_read_panel_property(dev,
+	    "invert_frm_clock", &panel->invert_frm_clock)))
+		goto out;
+
+	if ((error = am335x_read_panel_property(dev,
+	    "sync_edge", &panel->sync_edge)))
+		goto out;
+
+	error = am335x_read_panel_property(dev,
+	    "sync_ctrl", &panel->sync_ctrl);
+
+out:
+	return (error);
+}
+
+static void
+am335x_lcd_intr(void *arg)
+{
+	struct am335x_lcd_softc *sc = arg;
+	uint32_t reg; 
+
+	reg = LCD_READ4(sc, LCD_IRQSTATUS);
+	LCD_WRITE4(sc, LCD_IRQSTATUS, reg);
+
+	if (reg & IRQ_SYNC_LOST) {
+		reg = LCD_READ4(sc, LCD_RASTER_CTRL);
+		reg &= ~RASTER_CTRL_LCDEN;
+		LCD_WRITE4(sc, LCD_RASTER_CTRL, reg); 
+
+		reg = LCD_READ4(sc, LCD_RASTER_CTRL);
+		reg |= RASTER_CTRL_LCDEN;
+		LCD_WRITE4(sc, LCD_RASTER_CTRL, reg); 
+		return;
+	}
+
+	if (reg & IRQ_PL) {
+		reg = LCD_READ4(sc, LCD_RASTER_CTRL);
+		reg &= ~RASTER_CTRL_LCDEN;
+		LCD_WRITE4(sc, LCD_RASTER_CTRL, reg); 
+
+		reg = LCD_READ4(sc, LCD_RASTER_CTRL);
+		reg |= RASTER_CTRL_LCDEN;
+		LCD_WRITE4(sc, LCD_RASTER_CTRL, reg); 
+		return;
+	}
+
+	if (reg & IRQ_EOF0) {
+		LCD_WRITE4(sc, LCD_LCDDMA_FB0_BASE, sc->sc_fb_phys); 
+		LCD_WRITE4(sc, LCD_LCDDMA_FB0_CEILING, sc->sc_fb_phys + sc->sc_fb_size - 1); 
+		reg &= ~IRQ_EOF0;
+	}
+
+	if (reg & IRQ_EOF1) {
+		LCD_WRITE4(sc, LCD_LCDDMA_FB1_BASE, sc->sc_fb_phys); 
+		LCD_WRITE4(sc, LCD_LCDDMA_FB1_CEILING, sc->sc_fb_phys + sc->sc_fb_size - 1); 
+		reg &= ~IRQ_EOF1;
+	}
+
+	if (reg & IRQ_FUF) {
+		/* TODO: Handle FUF */
+	}
+
+	if (reg & IRQ_ACB) {
+		/* TODO: Handle ACB */
+	}
+}
+
+static int
+am335x_lcd_probe(device_t dev)
+{
+	int err;
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "ti,am335x-lcd"))
+		return (ENXIO);
+
+	device_set_desc(dev, "AM335x LCD controller");
+
+	err = sc_probe_unit(device_get_unit(dev), 
+	    device_get_flags(dev) | SC_AUTODETECT_KBD);
+	if (err != 0)
+		return (err);
+
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+am335x_lcd_attach(device_t dev)
+{
+	struct am335x_lcd_softc *sc;
+	int rid;
+	int div;
+	struct panel_info panel;
+	uint32_t reg, timing0, timing1, timing2;
+	struct sysctl_ctx_list *ctx;
+	struct sysctl_oid *tree;
+	uint32_t burst_log;
+	int err;
+	size_t dma_size;
+
+	sc = device_get_softc(dev);
+	sc->sc_dev = dev;
+
+	if (am335x_read_panel_info(dev, &panel))
+		return (ENXIO);
+
+	int ref_freq = 0;
+	ti_prcm_clk_enable(LCDC_CLK);
+	if (ti_prcm_clk_get_source_freq(LCDC_CLK, &ref_freq)) {
+		device_printf(dev, "Can't get reference frequency\n");
+		return (ENXIO);
+	}
+
+	rid = 0;
+	sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	    RF_ACTIVE);
+	if (!sc->sc_mem_res) {
+		device_printf(dev, "cannot allocate memory window\n");
+		return (ENXIO);
+	}
+
+	rid = 0;
+	sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+	    RF_ACTIVE);
+	if (!sc->sc_irq_res) {
+		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
+		device_printf(dev, "cannot allocate interrupt\n");
+		return (ENXIO);
+	}
+
+	if (bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
+			NULL, am335x_lcd_intr, sc,
+			&sc->sc_intr_hl) != 0) {
+		bus_release_resource(dev, SYS_RES_IRQ, rid,
+		    sc->sc_irq_res);
+		bus_release_resource(dev, SYS_RES_MEMORY, rid,
+		    sc->sc_mem_res);
+		device_printf(dev, "Unable to setup the irq handler.\n");
+		return (ENXIO);
+	}
+
+	LCD_LOCK_INIT(sc);
+
+	/* Panle initialization */
+	dma_size = round_page(panel.panel_width*panel.panel_height*panel.bpp/8);
+
+	/*
+	 * Now allocate framebuffer memory
+	 */
+	err = bus_dma_tag_create(
+	    bus_get_dma_tag(dev),
+	    4, 0,		/* alignment, boundary */
+	    BUS_SPACE_MAXADDR_32BIT,	/* lowaddr */
+	    BUS_SPACE_MAXADDR,		/* highaddr */
+	    NULL, NULL,			/* filter, filterarg */
+	    dma_size, 1,			/* maxsize, nsegments */
+	    dma_size, 0,			/* maxsegsize, flags */
+	    NULL, NULL,			/* lockfunc, lockarg */
+	    &sc->sc_dma_tag);
+	if (err)
+		goto fail;
+
+	err = bus_dmamem_alloc(sc->sc_dma_tag, (void **)&sc->sc_fb_base,
+	    BUS_DMA_COHERENT, &sc->sc_dma_map);
+
+	if (err) {
+		device_printf(dev, "cannot allocate framebuffer\n");
+		goto fail;
+	}
+
+	err = bus_dmamap_load(sc->sc_dma_tag, sc->sc_dma_map, sc->sc_fb_base,
+	    dma_size, am335x_fb_dmamap_cb, &sc->sc_fb_phys, BUS_DMA_NOWAIT);
+
+	if (err) {
+		device_printf(dev, "cannot load DMA map\n");
+		goto fail;
+	}
+
+	/* Make sure it's blank */
+	memset(sc->sc_fb_base, 0x00, dma_size);
+
+	/* Calculate actual FB Size */
+	sc->sc_fb_size = panel.panel_width*panel.panel_height*panel.bpp/8;
+
+	/* Only raster mode is supported */
+	reg = CTRL_RASTER_MODE;
+	div = am335x_lcd_calc_divisor(ref_freq, panel.panel_pxl_clk);
+	reg |= (div << CTRL_DIV_SHIFT);
+	LCD_WRITE4(sc, LCD_CTRL, reg); 
+
+	/* Set timing */
+	timing0 = timing1 = timing2 = 0;
+
+	/* Horizontal back porch */
+	timing0 |= (panel.panel_hbp & 0xff) << RASTER_TIMING_0_HBP_SHIFT;
+	timing2 |= ((panel.panel_hbp >> 8) & 3) << RASTER_TIMING_2_HBPHI_SHIFT;
+	/* Horizontal front porch */
+	timing0 |= (panel.panel_hfp & 0xff) << RASTER_TIMING_0_HFP_SHIFT;
+	timing2 |= ((panel.panel_hfp >> 8) & 3) << RASTER_TIMING_2_HFPHI_SHIFT;
+	/* Horizontal sync width */
+	timing0 |= (panel.panel_hsw & 0x3f) << RASTER_TIMING_0_HSW_SHIFT;
+	timing2 |= ((panel.panel_hsw >> 6) & 0xf) << RASTER_TIMING_2_HSWHI_SHIFT;
+
+	/* Vertical back porch, front porch, sync width */
+	timing1 |= (panel.panel_vbp & 0xff) << RASTER_TIMING_1_VBP_SHIFT;
+	timing1 |= (panel.panel_vfp & 0xff) << RASTER_TIMING_1_VFP_SHIFT;
+	timing1 |= (panel.panel_vsw & 0x3f) << RASTER_TIMING_1_VSW_SHIFT;
+
+	/* Pixels per line */
+	timing0 |= (((panel.panel_width - 1) >> 10) & 1)
+	    << RASTER_TIMING_0_PPLMSB_SHIFT;
+	timing0 |= (((panel.panel_width - 1) >> 4) & 0x3f)
+	    << RASTER_TIMING_0_PPLLSB_SHIFT;
+
+	/* Lines per panel */
+	timing1 |= ((panel.panel_height - 1) & 0x3ff) 
+	    << RASTER_TIMING_1_LPP_SHIFT;
+	timing2 |= (((panel.panel_height - 1) >> 10 ) & 1) 
+	    << RASTER_TIMING_2_LPP_B10_SHIFT;
+
+	/* clock signal settings */
+	if (panel.sync_ctrl)
+		timing2 |= RASTER_TIMING_2_PHSVS;
+	if (panel.sync_edge)
+		timing2 |= RASTER_TIMING_2_PHSVS_RISE;
+	else
+		timing2 |= RASTER_TIMING_2_PHSVS_FALL;
+	if (panel.invert_line_clock)
+		timing2 |= RASTER_TIMING_2_IHS;
+	if (panel.invert_frm_clock)
+		timing2 |= RASTER_TIMING_2_IVS;
+	if (panel.panel_invert_pxl_clk)
+		timing2 |= RASTER_TIMING_2_IPC;
+
+	/* AC bias */
+	timing2 |= (panel.ac_bias << RASTER_TIMING_2_ACB_SHIFT);
+	timing2 |= (panel.ac_bias_intrpt << RASTER_TIMING_2_ACBI_SHIFT);
+
+	LCD_WRITE4(sc, LCD_RASTER_TIMING_0, timing0); 
+	LCD_WRITE4(sc, LCD_RASTER_TIMING_1, timing1); 
+	LCD_WRITE4(sc, LCD_RASTER_TIMING_2, timing2); 
+
+	/* DMA settings */
+	reg = LCDDMA_CTRL_FB0_FB1;
+	/* Find power of 2 for current burst size */
+	switch (panel.dma_burst_sz) {
+	case 1:
+		burst_log = 0;
+		break;
+	case 2:
+		burst_log = 1;
+		break;
+	case 4:
+		burst_log = 2;
+		break;
+	case 8:
+		burst_log = 3;
+		break;
+	case 16:
+	default:
+		burst_log = 4;
+		break;
+	}
+	reg |= (burst_log << LCDDMA_CTRL_BURST_SIZE_SHIFT);
+	/* XXX: FIFO TH */
+	reg |= (0 << LCDDMA_CTRL_TH_FIFO_RDY_SHIFT);
+	LCD_WRITE4(sc, LCD_LCDDMA_CTRL, reg); 
+
+	LCD_WRITE4(sc, LCD_LCDDMA_FB0_BASE, sc->sc_fb_phys); 
+	LCD_WRITE4(sc, LCD_LCDDMA_FB0_CEILING, sc->sc_fb_phys + sc->sc_fb_size - 1); 
+	LCD_WRITE4(sc, LCD_LCDDMA_FB1_BASE, sc->sc_fb_phys); 
+	LCD_WRITE4(sc, LCD_LCDDMA_FB1_CEILING, sc->sc_fb_phys + sc->sc_fb_size - 1); 
+
+	/* Enable LCD */
+	reg = RASTER_CTRL_LCDTFT;
+	reg |= (panel.fdd << RASTER_CTRL_REQDLY_SHIFT);
+	reg |= (PALETTE_DATA_ONLY << RASTER_CTRL_PALMODE_SHIFT);
+	if (panel.bpp >= 24)
+		reg |= RASTER_CTRL_TFT24;
+	if (panel.bpp == 32)
+		reg |= RASTER_CTRL_TFT24_UNPACKED;
+	LCD_WRITE4(sc, LCD_RASTER_CTRL, reg); 
+
+	LCD_WRITE4(sc, LCD_CLKC_ENABLE,
+	    CLKC_ENABLE_DMA | CLKC_ENABLE_LDID | CLKC_ENABLE_CORE);
+
+	LCD_WRITE4(sc, LCD_CLKC_RESET, CLKC_RESET_MAIN);
+	DELAY(100);
+	LCD_WRITE4(sc, LCD_CLKC_RESET, 0);
+
+	reg = IRQ_EOF1 | IRQ_EOF0 | IRQ_FUF | IRQ_PL |
+	    IRQ_ACB | IRQ_SYNC_LOST |  IRQ_RASTER_DONE |
+	    IRQ_FRAME_DONE;
+	LCD_WRITE4(sc, LCD_IRQENABLE_SET, reg);
+
+	reg = LCD_READ4(sc, LCD_RASTER_CTRL);
+ 	reg |= RASTER_CTRL_LCDEN;
+	LCD_WRITE4(sc, LCD_RASTER_CTRL, reg); 
+
+	LCD_WRITE4(sc, LCD_SYSCONFIG,
+	    SYSCONFIG_STANDBY_SMART | SYSCONFIG_IDLE_SMART); 
+
+	/* Init backlight interface */
+	ctx = device_get_sysctl_ctx(sc->sc_dev);
+	tree = device_get_sysctl_tree(sc->sc_dev);
+	sc->sc_oid = SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
+	    "backlight", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
+	    am335x_lcd_sysctl_backlight, "I", "LCD backlight");
+	sc->sc_backlight = 0;
+	/* Check if eCAS interface is available at this point */
+	if (am335x_pwm_config_ecas(PWM_UNIT,
+	    PWM_PERIOD, PWM_PERIOD) == 0)
+		sc->sc_backlight = 100;
+
+	err = (sc_attach_unit(device_get_unit(dev),
+	    device_get_flags(dev) | SC_AUTODETECT_KBD));
+
+	if (err) {
+		device_printf(dev, "failed to attach syscons\n");
+		goto fail;
+	}
+
+	am335x_lcd_syscons_setup((vm_offset_t)sc->sc_fb_base, sc->sc_fb_phys, &panel);
+
+	return (0);
+
+fail:
+	return (err);
+}
+
+static int
+am335x_lcd_detach(device_t dev)
+{
+	/* Do not let unload driver */
+	return (EBUSY);
+}
+
+static device_method_t am335x_lcd_methods[] = {
+	DEVMETHOD(device_probe,		am335x_lcd_probe),
+	DEVMETHOD(device_attach,	am335x_lcd_attach),
+	DEVMETHOD(device_detach,	am335x_lcd_detach),
+
+	DEVMETHOD_END
+};
+
+static driver_t am335x_lcd_driver = {
+	"am335x_lcd",
+	am335x_lcd_methods,
+	sizeof(struct am335x_lcd_softc),
+};
+
+static devclass_t am335x_lcd_devclass;
+
+DRIVER_MODULE(am335x_lcd, simplebus, am335x_lcd_driver, am335x_lcd_devclass, 0, 0);
+MODULE_VERSION(am335x_lcd, 1);
+MODULE_DEPEND(am335x_lcd, simplebus, 1, 1, 1);


Property changes on: trunk/sys/arm/ti/am335x/am335x_lcd.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/am335x/am335x_lcd.h
===================================================================
--- trunk/sys/arm/ti/am335x/am335x_lcd.h	                        (rev 0)
+++ trunk/sys/arm/ti/am335x/am335x_lcd.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,57 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Oleksandr Tymoshenko <gonzo at freebsd.org>
+ * 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: stable/10/sys/arm/ti/am335x/am335x_lcd.h 251018 2013-05-27 00:23:01Z gonzo $
+ */
+#ifndef __AM335X_LCD_H__
+#define __AM335X_LCD_H__
+
+struct panel_info {
+	uint32_t panel_width;
+	uint32_t panel_height;
+	uint32_t panel_hfp;
+	uint32_t panel_hbp;
+	uint32_t panel_hsw;
+	uint32_t panel_vfp;
+	uint32_t panel_vbp;
+	uint32_t panel_vsw;
+	uint32_t ac_bias;
+	uint32_t ac_bias_intrpt;
+	uint32_t dma_burst_sz;
+	uint32_t bpp;
+	uint32_t fdd;
+	uint32_t invert_line_clock;
+	uint32_t invert_frm_clock;
+	uint32_t sync_edge;
+	uint32_t sync_ctrl;
+	uint32_t panel_pxl_clk;
+	uint32_t panel_invert_pxl_clk;	
+};
+
+int am335x_lcd_syscons_setup(vm_offset_t vaddr, vm_paddr_t paddr,
+    struct panel_info *panel);
+
+#endif /* __AM335X_LCD_H__ */


Property changes on: trunk/sys/arm/ti/am335x/am335x_lcd.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/am335x/am335x_lcd_syscons.c
===================================================================
--- trunk/sys/arm/ti/am335x/am335x_lcd_syscons.c	                        (rev 0)
+++ trunk/sys/arm/ti/am335x/am335x_lcd_syscons.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,793 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Oleksandr Tymoshenko <gonzo at freebsd.org>
+ * 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: stable/10/sys/arm/ti/am335x/am335x_lcd_syscons.c 259329 2013-12-13 20:43:11Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/endian.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+#include <sys/fbio.h>
+#include <sys/consio.h>
+
+#include <sys/kdb.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+#include <machine/resource.h>
+#include <machine/intr.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <dev/fb/fbreg.h>
+#include <dev/syscons/syscons.h>
+
+#include "am335x_lcd.h"
+
+struct video_adapter_softc {
+	/* Videoadpater part */
+	video_adapter_t	va;
+	int		console;
+
+	intptr_t	fb_addr;
+	intptr_t	fb_paddr;
+	unsigned int	fb_size;
+
+	unsigned int	height;
+	unsigned int	width;
+	unsigned int	depth;
+	unsigned int	stride;
+
+	unsigned int	xmargin;
+	unsigned int	ymargin;
+
+	unsigned char	*font;
+	int		initialized;
+};
+
+struct argb {
+	uint8_t		a;
+	uint8_t		r;
+	uint8_t		g;
+	uint8_t		b;
+};
+
+static struct argb am335x_syscons_palette[16] = {
+	{0x00, 0x00, 0x00, 0x00},
+	{0x00, 0x00, 0x00, 0xaa},
+	{0x00, 0x00, 0xaa, 0x00},
+	{0x00, 0x00, 0xaa, 0xaa},
+	{0x00, 0xaa, 0x00, 0x00},
+	{0x00, 0xaa, 0x00, 0xaa},
+	{0x00, 0xaa, 0x55, 0x00},
+	{0x00, 0xaa, 0xaa, 0xaa},
+	{0x00, 0x55, 0x55, 0x55},
+	{0x00, 0x55, 0x55, 0xff},
+	{0x00, 0x55, 0xff, 0x55},
+	{0x00, 0x55, 0xff, 0xff},
+	{0x00, 0xff, 0x55, 0x55},
+	{0x00, 0xff, 0x55, 0xff},
+	{0x00, 0xff, 0xff, 0x55},
+	{0x00, 0xff, 0xff, 0xff}
+};
+
+/* mouse pointer from dev/syscons/scgfbrndr.c */
+static u_char mouse_pointer[16] = {
+        0x00, 0x40, 0x60, 0x70, 0x78, 0x7c, 0x7e, 0x68,
+        0x0c, 0x0c, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00
+};
+
+#define	AM335X_FONT_HEIGHT	16
+
+#define FB_WIDTH		640
+#define FB_HEIGHT		480
+#define FB_DEPTH		24
+
+static struct video_adapter_softc va_softc;
+
+static int am335x_syscons_configure(int flags);
+
+/*
+ * Video driver routines and glue.
+ */
+static vi_probe_t		am335x_syscons_probe;
+static vi_init_t		am335x_syscons_init;
+static vi_get_info_t		am335x_syscons_get_info;
+static vi_query_mode_t		am335x_syscons_query_mode;
+static vi_set_mode_t		am335x_syscons_set_mode;
+static vi_save_font_t		am335x_syscons_save_font;
+static vi_load_font_t		am335x_syscons_load_font;
+static vi_show_font_t		am335x_syscons_show_font;
+static vi_save_palette_t	am335x_syscons_save_palette;
+static vi_load_palette_t	am335x_syscons_load_palette;
+static vi_set_border_t		am335x_syscons_set_border;
+static vi_save_state_t		am335x_syscons_save_state;
+static vi_load_state_t		am335x_syscons_load_state;
+static vi_set_win_org_t		am335x_syscons_set_win_org;
+static vi_read_hw_cursor_t	am335x_syscons_read_hw_cursor;
+static vi_set_hw_cursor_t	am335x_syscons_set_hw_cursor;
+static vi_set_hw_cursor_shape_t	am335x_syscons_set_hw_cursor_shape;
+static vi_blank_display_t	am335x_syscons_blank_display;
+static vi_mmap_t		am335x_syscons_mmap;
+static vi_ioctl_t		am335x_syscons_ioctl;
+static vi_clear_t		am335x_syscons_clear;
+static vi_fill_rect_t		am335x_syscons_fill_rect;
+static vi_bitblt_t		am335x_syscons_bitblt;
+static vi_diag_t		am335x_syscons_diag;
+static vi_save_cursor_palette_t	am335x_syscons_save_cursor_palette;
+static vi_load_cursor_palette_t	am335x_syscons_load_cursor_palette;
+static vi_copy_t		am335x_syscons_copy;
+static vi_putp_t		am335x_syscons_putp;
+static vi_putc_t		am335x_syscons_putc;
+static vi_puts_t		am335x_syscons_puts;
+static vi_putm_t		am335x_syscons_putm;
+
+static video_switch_t am335x_sysconsvidsw = {
+	.probe			= am335x_syscons_probe,
+	.init			= am335x_syscons_init,
+	.get_info		= am335x_syscons_get_info,
+	.query_mode		= am335x_syscons_query_mode,
+	.set_mode		= am335x_syscons_set_mode,
+	.save_font		= am335x_syscons_save_font,
+	.load_font		= am335x_syscons_load_font,
+	.show_font		= am335x_syscons_show_font,
+	.save_palette		= am335x_syscons_save_palette,
+	.load_palette		= am335x_syscons_load_palette,
+	.set_border		= am335x_syscons_set_border,
+	.save_state		= am335x_syscons_save_state,
+	.load_state		= am335x_syscons_load_state,
+	.set_win_org		= am335x_syscons_set_win_org,
+	.read_hw_cursor		= am335x_syscons_read_hw_cursor,
+	.set_hw_cursor		= am335x_syscons_set_hw_cursor,
+	.set_hw_cursor_shape	= am335x_syscons_set_hw_cursor_shape,
+	.blank_display		= am335x_syscons_blank_display,
+	.mmap			= am335x_syscons_mmap,
+	.ioctl			= am335x_syscons_ioctl,
+	.clear			= am335x_syscons_clear,
+	.fill_rect		= am335x_syscons_fill_rect,
+	.bitblt			= am335x_syscons_bitblt,
+	.diag			= am335x_syscons_diag,
+	.save_cursor_palette	= am335x_syscons_save_cursor_palette,
+	.load_cursor_palette	= am335x_syscons_load_cursor_palette,
+	.copy			= am335x_syscons_copy,
+	.putp			= am335x_syscons_putp,
+	.putc			= am335x_syscons_putc,
+	.puts			= am335x_syscons_puts,
+	.putm			= am335x_syscons_putm,
+};
+
+VIDEO_DRIVER(am335x_syscons, am335x_sysconsvidsw, am335x_syscons_configure);
+
+static vr_init_t am335x_rend_init;
+static vr_clear_t am335x_rend_clear;
+static vr_draw_border_t am335x_rend_draw_border;
+static vr_draw_t am335x_rend_draw;
+static vr_set_cursor_t am335x_rend_set_cursor;
+static vr_draw_cursor_t am335x_rend_draw_cursor;
+static vr_blink_cursor_t am335x_rend_blink_cursor;
+static vr_set_mouse_t am335x_rend_set_mouse;
+static vr_draw_mouse_t am335x_rend_draw_mouse;
+
+/*
+ * We use our own renderer; this is because we must emulate a hardware
+ * cursor.
+ */
+static sc_rndr_sw_t am335x_rend = {
+	am335x_rend_init,
+	am335x_rend_clear,
+	am335x_rend_draw_border,
+	am335x_rend_draw,
+	am335x_rend_set_cursor,
+	am335x_rend_draw_cursor,
+	am335x_rend_blink_cursor,
+	am335x_rend_set_mouse,
+	am335x_rend_draw_mouse
+};
+
+RENDERER(am335x_syscons, 0, am335x_rend, gfb_set);
+RENDERER_MODULE(am335x_syscons, gfb_set);
+
+static void
+am335x_rend_init(scr_stat* scp)
+{
+}
+
+static void
+am335x_rend_clear(scr_stat* scp, int c, int attr)
+{
+}
+
+static void
+am335x_rend_draw_border(scr_stat* scp, int color)
+{
+}
+
+static void
+am335x_rend_draw(scr_stat* scp, int from, int count, int flip)
+{
+	video_adapter_t* adp = scp->sc->adp;
+	int i, c, a;
+
+	if (!flip) {
+		/* Normal printing */
+		vidd_puts(adp, from, (uint16_t*)sc_vtb_pointer(&scp->vtb, from), count);
+	} else {	
+		/* This is for selections and such: invert the color attribute */
+		for (i = count; i-- > 0; ++from) {
+			c = sc_vtb_getc(&scp->vtb, from);
+			a = sc_vtb_geta(&scp->vtb, from) >> 8;
+			vidd_putc(adp, from, c, (a >> 4) | ((a & 0xf) << 4));
+		}
+	}
+}
+
+static void
+am335x_rend_set_cursor(scr_stat* scp, int base, int height, int blink)
+{
+}
+
+static void
+am335x_rend_draw_cursor(scr_stat* scp, int off, int blink, int on, int flip)
+{
+	video_adapter_t* adp = scp->sc->adp;
+	struct video_adapter_softc *sc;
+	int row, col;
+	uint8_t *addr;
+	int i, j, bytes;
+
+	sc = (struct video_adapter_softc *)adp;
+
+	if (scp->curs_attr.height <= 0)
+		return;
+
+	if (sc->fb_addr == 0)
+		return;
+
+	if (off >= adp->va_info.vi_width * adp->va_info.vi_height)
+		return;
+
+	/* calculate the coordinates in the video buffer */
+	row = (off / adp->va_info.vi_width) * adp->va_info.vi_cheight;
+	col = (off % adp->va_info.vi_width) * adp->va_info.vi_cwidth;
+
+	addr = (uint8_t *)sc->fb_addr
+	    + (row + sc->ymargin)*(sc->stride)
+	    + (sc->depth/8) * (col + sc->xmargin);
+
+	bytes = sc->depth/8;
+
+	/* our cursor consists of simply inverting the char under it */
+	for (i = 0; i < adp->va_info.vi_cheight; i++) {
+		for (j = 0; j < adp->va_info.vi_cwidth; j++) {
+			switch (sc->depth) {
+			case 32:
+			case 24:
+				addr[bytes*j + 2] ^= 0xff;
+				/* FALLTHROUGH */
+			case 16:
+				addr[bytes*j + 1] ^= 0xff;
+				addr[bytes*j] ^= 0xff;
+				break;
+			default:
+				break;
+			}
+		}
+
+		addr += sc->stride;
+	}
+}
+
+static void
+am335x_rend_blink_cursor(scr_stat* scp, int at, int flip)
+{
+}
+
+static void
+am335x_rend_set_mouse(scr_stat* scp)
+{
+}
+
+static void
+am335x_rend_draw_mouse(scr_stat* scp, int x, int y, int on)
+{
+	vidd_putm(scp->sc->adp, x, y, mouse_pointer, 0xffffffff, 16, 8);
+}
+
+static uint16_t am335x_syscons_static_window[ROW*COL];
+extern u_char dflt_font_16[];
+
+/*
+ * Update videoadapter settings after changing resolution
+ */
+static void
+am335x_syscons_update_margins(video_adapter_t *adp)
+{
+	struct video_adapter_softc *sc;
+	video_info_t *vi;
+
+	sc = (struct video_adapter_softc *)adp;
+	vi = &adp->va_info;
+
+	sc->xmargin = (sc->width - (vi->vi_width * vi->vi_cwidth)) / 2;
+	sc->ymargin = (sc->height - (vi->vi_height * vi->vi_cheight))/2;
+}
+
+static phandle_t
+am335x_syscons_find_panel_node(phandle_t start)
+{
+	phandle_t child;
+	phandle_t result;
+
+	for (child = OF_child(start); child != 0; child = OF_peer(child)) {
+		if (fdt_is_compatible(child, "ti,am335x-lcd"))
+			return (child);
+		if ((result = am335x_syscons_find_panel_node(child)))
+			return (result);
+	}
+
+	return (0);
+}
+
+static int
+am335x_syscons_configure(int flags)
+{
+	struct video_adapter_softc *va_sc;
+
+	va_sc = &va_softc;
+	phandle_t display, root;
+	pcell_t cell;
+
+	if (va_sc->initialized)
+		return (0);
+
+	va_sc->width = 0;
+	va_sc->height = 0;
+
+	/*
+	 * It seems there is no way to let syscons framework know
+	 * that framebuffer resolution has changed. So just try
+	 * to fetch data from FDT and go with defaults if failed
+	 */
+	root = OF_finddevice("/");
+	if ((root != 0) && 
+	    (display = am335x_syscons_find_panel_node(root))) {
+		if ((OF_getprop(display, "panel_width", 
+		    &cell, sizeof(cell))) > 0)
+			va_sc->width = (int)fdt32_to_cpu(cell);
+
+		if ((OF_getprop(display, "panel_height", 
+		    &cell, sizeof(cell))) > 0)
+			va_sc->height = (int)fdt32_to_cpu(cell);
+	}
+
+	if (va_sc->width == 0)
+		va_sc->width = FB_WIDTH;
+	if (va_sc->height == 0)
+		va_sc->height = FB_HEIGHT;
+
+	am335x_syscons_init(0, &va_sc->va, 0);
+
+	va_sc->initialized = 1;
+
+	return (0);
+}
+
+static int
+am335x_syscons_probe(int unit, video_adapter_t **adp, void *arg, int flags)
+{
+
+	return (0);
+}
+
+static int
+am335x_syscons_init(int unit, video_adapter_t *adp, int flags)
+{
+	struct video_adapter_softc *sc;
+	video_info_t *vi;
+
+	sc = (struct video_adapter_softc *)adp;
+	vi = &adp->va_info;
+
+	vid_init_struct(adp, "am335x_syscons", -1, unit);
+
+	sc->font = dflt_font_16;
+	vi->vi_cheight = AM335X_FONT_HEIGHT;
+	vi->vi_cwidth = 8;
+
+	vi->vi_width = sc->width/8;
+	vi->vi_height = sc->height/vi->vi_cheight;
+
+	/*
+	 * Clamp width/height to syscons maximums
+	 */
+	if (vi->vi_width > COL)
+		vi->vi_width = COL;
+	if (vi->vi_height > ROW)
+		vi->vi_height = ROW;
+
+	sc->xmargin = (sc->width - (vi->vi_width * vi->vi_cwidth)) / 2;
+	sc->ymargin = (sc->height - (vi->vi_height * vi->vi_cheight))/2;
+
+
+	adp->va_window = (vm_offset_t) am335x_syscons_static_window;
+	adp->va_flags |= V_ADP_FONT /* | V_ADP_COLOR | V_ADP_MODECHANGE */;
+
+	vid_register(&sc->va);
+
+	return (0);
+}
+
+static int
+am335x_syscons_get_info(video_adapter_t *adp, int mode, video_info_t *info)
+{
+	bcopy(&adp->va_info, info, sizeof(*info));
+	return (0);
+}
+
+static int
+am335x_syscons_query_mode(video_adapter_t *adp, video_info_t *info)
+{
+	return (0);
+}
+
+static int
+am335x_syscons_set_mode(video_adapter_t *adp, int mode)
+{
+	return (0);
+}
+
+static int
+am335x_syscons_save_font(video_adapter_t *adp, int page, int size, int width,
+    u_char *data, int c, int count)
+{
+	return (0);
+}
+
+static int
+am335x_syscons_load_font(video_adapter_t *adp, int page, int size, int width,
+    u_char *data, int c, int count)
+{
+	struct video_adapter_softc *sc = (struct video_adapter_softc *)adp;
+
+	sc->font = data;
+
+	return (0);
+}
+
+static int
+am335x_syscons_show_font(video_adapter_t *adp, int page)
+{
+	return (0);
+}
+
+static int
+am335x_syscons_save_palette(video_adapter_t *adp, u_char *palette)
+{
+	return (0);
+}
+
+static int
+am335x_syscons_load_palette(video_adapter_t *adp, u_char *palette)
+{
+	return (0);
+}
+
+static int
+am335x_syscons_set_border(video_adapter_t *adp, int border)
+{
+	return (am335x_syscons_blank_display(adp, border));
+}
+
+static int
+am335x_syscons_save_state(video_adapter_t *adp, void *p, size_t size)
+{
+	return (0);
+}
+
+static int
+am335x_syscons_load_state(video_adapter_t *adp, void *p)
+{
+	return (0);
+}
+
+static int
+am335x_syscons_set_win_org(video_adapter_t *adp, off_t offset)
+{
+	return (0);
+}
+
+static int
+am335x_syscons_read_hw_cursor(video_adapter_t *adp, int *col, int *row)
+{
+	*col = *row = 0;
+
+	return (0);
+}
+
+static int
+am335x_syscons_set_hw_cursor(video_adapter_t *adp, int col, int row)
+{
+	return (0);
+}
+
+static int
+am335x_syscons_set_hw_cursor_shape(video_adapter_t *adp, int base, int height,
+    int celsize, int blink)
+{
+	return (0);
+}
+
+static int
+am335x_syscons_blank_display(video_adapter_t *adp, int mode)
+{
+
+	struct video_adapter_softc *sc;
+
+	sc = (struct video_adapter_softc *)adp;
+	if (sc && sc->fb_addr)
+		memset((void*)sc->fb_addr, 0, sc->fb_size);
+
+	return (0);
+}
+
+static int
+am335x_syscons_mmap(video_adapter_t *adp, vm_ooffset_t offset, vm_paddr_t *paddr,
+    int prot, vm_memattr_t *memattr)
+{
+	struct video_adapter_softc *sc;
+
+	sc = (struct video_adapter_softc *)adp;
+
+	/*
+	 * This might be a legacy VGA mem request: if so, just point it at the
+	 * framebuffer, since it shouldn't be touched
+	 */
+	if (offset < sc->stride*sc->height) {
+		*paddr = sc->fb_paddr + offset;
+		return (0);
+	}
+
+	return (EINVAL);
+}
+
+static int
+am335x_syscons_ioctl(video_adapter_t *adp, u_long cmd, caddr_t data)
+{
+	struct video_adapter_softc *sc;
+	struct fbtype *fb;
+
+	sc = (struct video_adapter_softc *)adp;
+
+	switch (cmd) {
+	case FBIOGTYPE:
+		fb = (struct fbtype *)data;
+		fb->fb_type = FBTYPE_PCIMISC;
+		fb->fb_height = sc->height;
+		fb->fb_width = sc->width;
+		fb->fb_depth = sc->depth;
+		if (sc->depth <= 1 || sc->depth > 8)
+			fb->fb_cmsize = 0;
+		else
+			fb->fb_cmsize = 1 << sc->depth;
+		fb->fb_size = sc->fb_size;
+		break;
+	default:
+		return (fb_commonioctl(adp, cmd, data));
+	}
+
+	return (0);
+}
+
+static int
+am335x_syscons_clear(video_adapter_t *adp)
+{
+
+	return (am335x_syscons_blank_display(adp, 0));
+}
+
+static int
+am335x_syscons_fill_rect(video_adapter_t *adp, int val, int x, int y, int cx, int cy)
+{
+
+	return (0);
+}
+
+static int
+am335x_syscons_bitblt(video_adapter_t *adp, ...)
+{
+
+	return (0);
+}
+
+static int
+am335x_syscons_diag(video_adapter_t *adp, int level)
+{
+
+	return (0);
+}
+
+static int
+am335x_syscons_save_cursor_palette(video_adapter_t *adp, u_char *palette)
+{
+
+	return (0);
+}
+
+static int
+am335x_syscons_load_cursor_palette(video_adapter_t *adp, u_char *palette)
+{
+
+	return (0);
+}
+
+static int
+am335x_syscons_copy(video_adapter_t *adp, vm_offset_t src, vm_offset_t dst, int n)
+{
+
+	return (0);
+}
+
+static int
+am335x_syscons_putp(video_adapter_t *adp, vm_offset_t off, uint32_t p, uint32_t a,
+    int size, int bpp, int bit_ltor, int byte_ltor)
+{
+
+	return (0);
+}
+
+static int
+am335x_syscons_putc(video_adapter_t *adp, vm_offset_t off, uint8_t c, uint8_t a)
+{
+	struct video_adapter_softc *sc;
+	int row;
+	int col;
+	int i, j, k;
+	uint8_t *addr;
+	u_char *p;
+	uint8_t fg, bg, color;
+	uint16_t rgb;
+
+	sc = (struct video_adapter_softc *)adp;
+
+	if (sc->fb_addr == 0)
+		return (0);
+
+	row = (off / adp->va_info.vi_width) * adp->va_info.vi_cheight;
+	col = (off % adp->va_info.vi_width) * adp->va_info.vi_cwidth;
+	p = sc->font + c*AM335X_FONT_HEIGHT;
+	addr = (uint8_t *)sc->fb_addr
+	    + (row + sc->ymargin)*(sc->stride)
+	    + (sc->depth/8) * (col + sc->xmargin);
+
+	fg = a & 0xf ;
+	bg = (a >> 4) & 0xf;
+
+	for (i = 0; i < AM335X_FONT_HEIGHT; i++) {
+		for (j = 0, k = 7; j < 8; j++, k--) {
+			if ((p[i] & (1 << k)) == 0)
+				color = bg;
+			else
+				color = fg;
+
+			switch (sc->depth) {
+			case 32:
+				addr[4*j+0] = am335x_syscons_palette[color].r;
+				addr[4*j+1] = am335x_syscons_palette[color].g;
+				addr[4*j+2] = am335x_syscons_palette[color].b;
+				addr[4*j+3] = am335x_syscons_palette[color].a;
+				break;
+			case 24:
+				addr[3*j] = am335x_syscons_palette[color].r;
+				addr[3*j+1] = am335x_syscons_palette[color].g;
+				addr[3*j+2] = am335x_syscons_palette[color].b;
+				break;
+			case 16:
+				rgb = (am335x_syscons_palette[color].r >> 3) << 11;
+				rgb |= (am335x_syscons_palette[color].g >> 2) << 5;
+				rgb |= (am335x_syscons_palette[color].b >> 3);
+				addr[2*j] = rgb & 0xff;
+				addr[2*j + 1] = (rgb >> 8) & 0xff;
+			default:
+				/* Not supported yet */
+				break;
+			}
+		}
+
+		addr += (sc->stride);
+	}
+
+        return (0);
+}
+
+static int
+am335x_syscons_puts(video_adapter_t *adp, vm_offset_t off, u_int16_t *s, int len)
+{
+	int i;
+
+	for (i = 0; i < len; i++) 
+		am335x_syscons_putc(adp, off + i, s[i] & 0xff, (s[i] & 0xff00) >> 8);
+
+	return (0);
+}
+
+static int
+am335x_syscons_putm(video_adapter_t *adp, int x, int y, uint8_t *pixel_image,
+    uint32_t pixel_mask, int size, int width)
+{
+
+	return (0);
+}
+
+/* Initialization function */
+int am335x_lcd_syscons_setup(vm_offset_t vaddr, vm_paddr_t paddr,
+    struct panel_info *panel)
+{
+	struct video_adapter_softc *va_sc = &va_softc;
+
+	va_sc->fb_addr = vaddr;
+	va_sc->fb_paddr = paddr;
+	va_sc->depth = panel->bpp;
+	va_sc->stride = panel->bpp*panel->panel_width/8;
+
+	va_sc->width = panel->panel_width;
+	va_sc->height = panel->panel_height;
+	va_sc->fb_size = va_sc->width * va_sc->height
+	    * va_sc->depth/8;
+	am335x_syscons_update_margins(&va_sc->va);
+
+	return (0);
+}
+
+/*
+ * Define a stub keyboard driver in case one hasn't been
+ * compiled into the kernel
+ */
+#include <sys/kbio.h>
+#include <dev/kbd/kbdreg.h>
+
+static int dummy_kbd_configure(int flags);
+
+keyboard_switch_t am335x_dummysw;
+
+static int
+dummy_kbd_configure(int flags)
+{
+
+	return (0);
+}
+KEYBOARD_DRIVER(am335x_dummy, am335x_dummysw, dummy_kbd_configure);


Property changes on: trunk/sys/arm/ti/am335x/am335x_lcd_syscons.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/am335x/am335x_pmic.c
===================================================================
--- trunk/sys/arm/ti/am335x/am335x_pmic.c	                        (rev 0)
+++ trunk/sys/arm/ti/am335x/am335x_pmic.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,212 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Damjan Marion <dmarion at Freebsd.org>
+ * 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: stable/10/sys/arm/ti/am335x/am335x_pmic.c 278079 2015-02-02 12:48:13Z loos $");
+/*
+* TPS65217 PMIC companion chip for AM335x SoC sitting on I2C bus
+*/
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/eventhandler.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/clock.h>
+#include <sys/time.h>
+#include <sys/bus.h>
+#include <sys/reboot.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+
+#include <dev/iicbus/iicbus.h>
+#include <dev/iicbus/iiconf.h>
+
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <arm/ti/am335x/am335x_rtcvar.h>
+
+#include "iicbus_if.h"
+
+#define TPS65217A		0x7
+#define TPS65217B		0xF
+#define TPS65217C		0xE
+#define TPS65217D		0x6
+
+/* TPS65217 Reisters */
+#define TPS65217_CHIPID_REG	0x00
+#define TPS65217_STATUS_REG	0x0A
+#define	TPS65217_STATUS_OFF		(1U << 7)
+#define	TPS65217_STATUS_ACPWR		(1U << 3)
+#define	TPS65217_STATUS_USBPWR		(1U << 2)
+#define	TPS65217_STATUS_BT		(1U << 0)
+
+#define MAX_IIC_DATA_SIZE	2
+
+
+struct am335x_pmic_softc {
+	device_t		sc_dev;
+	uint32_t		sc_addr;
+	struct intr_config_hook enum_hook;
+};
+
+static void am335x_pmic_shutdown(void *, int);
+
+static int
+am335x_pmic_read(device_t dev, uint8_t addr, uint8_t *data, uint8_t size)
+{
+	struct am335x_pmic_softc *sc = device_get_softc(dev);
+	struct iic_msg msg[] = {
+		{ sc->sc_addr, IIC_M_WR, 1, &addr },
+		{ sc->sc_addr, IIC_M_RD, size, data },
+	};
+	return (iicbus_transfer(dev, msg, 2));
+}
+
+static int
+am335x_pmic_write(device_t dev, uint8_t address, uint8_t *data, uint8_t size)
+{
+	uint8_t buffer[MAX_IIC_DATA_SIZE + 1];
+	struct am335x_pmic_softc *sc = device_get_softc(dev);
+	struct iic_msg msg[] = {
+		{ sc->sc_addr, IIC_M_WR, size + 1, buffer },
+	};
+
+	if (size > MAX_IIC_DATA_SIZE)
+		return (ENOMEM);
+
+	buffer[0] = address;
+	memcpy(buffer + 1, data, size);
+
+	return (iicbus_transfer(dev, msg, 1));
+}
+
+static int
+am335x_pmic_probe(device_t dev)
+{
+	struct am335x_pmic_softc *sc;
+
+	if (!ofw_bus_is_compatible(dev, "ti,am335x-pmic"))
+		return (ENXIO);
+
+	sc = device_get_softc(dev);
+	sc->sc_dev = dev;
+	sc->sc_addr = iicbus_get_addr(dev);
+
+	device_set_desc(dev, "TI TPS65217 Power Management IC");
+
+	return (0);
+}
+
+static void
+am335x_pmic_start(void *xdev)
+{
+	struct am335x_pmic_softc *sc;
+	device_t dev = (device_t)xdev;
+	uint8_t reg;
+	char name[20];
+	char pwr[4][11] = {"Unknown", "USB", "AC", "USB and AC"};
+
+	sc = device_get_softc(dev);
+
+	am335x_pmic_read(dev, TPS65217_CHIPID_REG, &reg, 1);
+	switch (reg>>4) {
+		case TPS65217A:
+			sprintf(name, "TPS65217A ver 1.%u", reg & 0xF);
+			break;
+		case TPS65217B:
+			sprintf(name, "TPS65217B ver 1.%u", reg & 0xF);
+			break;
+		case TPS65217C:
+			sprintf(name, "TPS65217C ver 1.%u", reg & 0xF);
+			break;
+		case TPS65217D:
+			sprintf(name, "TPS65217D ver 1.%u", reg & 0xF);
+			break;
+		default:
+			sprintf(name, "Unknown PMIC");
+	}
+
+	am335x_pmic_read(dev, TPS65217_STATUS_REG, &reg, 1);
+	device_printf(dev, "%s powered by %s\n", name, pwr[(reg>>2)&0x03]);
+
+	EVENTHANDLER_REGISTER(shutdown_final, am335x_pmic_shutdown, dev,
+	    SHUTDOWN_PRI_LAST);
+
+	config_intrhook_disestablish(&sc->enum_hook);
+}
+
+static int
+am335x_pmic_attach(device_t dev)
+{
+	struct am335x_pmic_softc *sc;
+
+	sc = device_get_softc(dev);
+
+	sc->enum_hook.ich_func = am335x_pmic_start;
+	sc->enum_hook.ich_arg = dev;
+
+	if (config_intrhook_establish(&sc->enum_hook) != 0)
+		return (ENOMEM);
+
+	return (0);
+}
+
+static void
+am335x_pmic_shutdown(void *xdev, int howto)
+{
+	device_t dev;
+	uint8_t reg;
+
+	if (!(howto & RB_POWEROFF))
+		return;
+	dev = (device_t)xdev;
+	/* Set the OFF bit on status register to start the shutdown sequence. */
+	reg = TPS65217_STATUS_OFF;
+	am335x_pmic_write(dev, TPS65217_STATUS_REG, &reg, 1);
+	/* Toggle pmic_pwr_enable to shutdown the PMIC. */
+	am335x_rtc_pmic_pwr_toggle();
+}
+
+static device_method_t am335x_pmic_methods[] = {
+	DEVMETHOD(device_probe,		am335x_pmic_probe),
+	DEVMETHOD(device_attach,	am335x_pmic_attach),
+	{0, 0},
+};
+
+static driver_t am335x_pmic_driver = {
+	"am335x_pmic",
+	am335x_pmic_methods,
+	sizeof(struct am335x_pmic_softc),
+};
+
+static devclass_t am335x_pmic_devclass;
+
+DRIVER_MODULE(am335x_pmic, iicbus, am335x_pmic_driver, am335x_pmic_devclass, 0, 0);
+MODULE_VERSION(am335x_pmic, 1);
+MODULE_DEPEND(am335x_pmic, iicbus, 1, 1, 1);


Property changes on: trunk/sys/arm/ti/am335x/am335x_pmic.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/am335x/am335x_prcm.c
===================================================================
--- trunk/sys/arm/ti/am335x/am335x_prcm.c	                        (rev 0)
+++ trunk/sys/arm/ti/am335x/am335x_prcm.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,799 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Damjan Marion <dmarion at Freebsd.org>
+ * 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: stable/10/sys/arm/ti/am335x/am335x_prcm.c 278432 2015-02-09 02:49:10Z rpaulo $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/timeet.h>
+#include <sys/timetc.h>
+#include <sys/watchdog.h>
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#include <arm/ti/tivar.h>
+#include <arm/ti/ti_scm.h>
+#include <arm/ti/ti_prcm.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+
+#define CM_PER				0
+#define CM_PER_L4LS_CLKSTCTRL		(CM_PER + 0x000)
+#define CM_PER_L3S_CLKSTCTRL		(CM_PER + 0x004)
+#define CM_PER_L3_CLKSTCTRL		(CM_PER + 0x00C)
+#define CM_PER_CPGMAC0_CLKCTRL		(CM_PER + 0x014)
+#define CM_PER_LCDC_CLKCTRL		(CM_PER + 0x018)
+#define CM_PER_USB0_CLKCTRL		(CM_PER + 0x01C)
+#define CM_PER_TPTC0_CLKCTRL		(CM_PER + 0x024)
+#define CM_PER_UART5_CLKCTRL		(CM_PER + 0x038)
+#define CM_PER_MMC0_CLKCTRL		(CM_PER + 0x03C)
+#define CM_PER_I2C2_CLKCTRL		(CM_PER + 0x044)
+#define CM_PER_I2C1_CLKCTRL		(CM_PER + 0x048)
+#define CM_PER_UART1_CLKCTRL		(CM_PER + 0x06C)
+#define CM_PER_UART2_CLKCTRL		(CM_PER + 0x070)
+#define CM_PER_UART3_CLKCTRL		(CM_PER + 0x074)
+#define CM_PER_UART4_CLKCTRL		(CM_PER + 0x078)
+#define CM_PER_TIMER7_CLKCTRL		(CM_PER + 0x07C)
+#define CM_PER_TIMER2_CLKCTRL		(CM_PER + 0x080)
+#define CM_PER_TIMER3_CLKCTRL		(CM_PER + 0x084)
+#define CM_PER_TIMER4_CLKCTRL		(CM_PER + 0x088)
+#define CM_PER_GPIO1_CLKCTRL		(CM_PER + 0x0AC)
+#define CM_PER_GPIO2_CLKCTRL		(CM_PER + 0x0B0)
+#define CM_PER_GPIO3_CLKCTRL		(CM_PER + 0x0B4)
+#define CM_PER_TPCC_CLKCTRL		(CM_PER + 0x0BC)
+#define CM_PER_EPWMSS1_CLKCTRL		(CM_PER + 0x0CC)
+#define CM_PER_EPWMSS0_CLKCTRL		(CM_PER + 0x0D4)
+#define CM_PER_EPWMSS2_CLKCTRL		(CM_PER + 0x0D8)
+#define CM_PER_L3_INSTR_CLKCTRL		(CM_PER + 0x0DC)
+#define CM_PER_L3_CLKCTRL		(CM_PER + 0x0E0)
+#define	CM_PER_PRUSS_CLKCTRL		(CM_PER + 0x0E8)
+#define CM_PER_TIMER5_CLKCTRL		(CM_PER + 0x0EC)
+#define CM_PER_TIMER6_CLKCTRL		(CM_PER + 0x0F0)
+#define CM_PER_MMC1_CLKCTRL		(CM_PER + 0x0F4)
+#define CM_PER_MMC2_CLKCTRL		(CM_PER + 0x0F8)
+#define CM_PER_TPTC1_CLKCTRL		(CM_PER + 0x0FC)
+#define CM_PER_TPTC2_CLKCTRL		(CM_PER + 0x100)
+#define	CM_PER_SPINLOCK0_CLKCTRL	(CM_PER + 0x10C)
+#define	CM_PER_MAILBOX0_CLKCTRL		(CM_PER + 0x110)
+#define CM_PER_OCPWP_L3_CLKSTCTRL	(CM_PER + 0x12C)
+#define CM_PER_OCPWP_CLKCTRL		(CM_PER + 0x130)
+#define CM_PER_CPSW_CLKSTCTRL		(CM_PER + 0x144)
+#define	CM_PER_PRUSS_CLKSTCTRL		(CM_PER + 0x140)
+
+#define CM_WKUP				0x400
+#define CM_WKUP_CLKSTCTRL		(CM_WKUP + 0x000)
+#define CM_WKUP_CONTROL_CLKCTRL		(CM_WKUP + 0x004)
+#define CM_WKUP_GPIO0_CLKCTRL		(CM_WKUP + 0x008)
+#define CM_WKUP_CM_L3_AON_CLKSTCTRL	(CM_WKUP + 0x01C)
+#define CM_WKUP_CM_CLKSEL_DPLL_MPU	(CM_WKUP + 0x02C)
+#define CM_WKUP_CM_IDLEST_DPLL_DISP	(CM_WKUP + 0x048)
+#define CM_WKUP_CM_CLKSEL_DPLL_DISP	(CM_WKUP + 0x054)
+#define CM_WKUP_CM_CLKDCOLDO_DPLL_PER	(CM_WKUP + 0x07C)
+#define CM_WKUP_CM_CLKMODE_DPLL_DISP	(CM_WKUP + 0x098)
+#define CM_WKUP_I2C0_CLKCTRL		(CM_WKUP + 0x0B8)
+#define CM_WKUP_ADC_TSC_CLKCTRL		(CM_WKUP + 0x0BC)
+
+#define CM_DPLL				0x500
+#define CLKSEL_TIMER7_CLK		(CM_DPLL + 0x004)
+#define CLKSEL_TIMER2_CLK		(CM_DPLL + 0x008)
+#define CLKSEL_TIMER3_CLK		(CM_DPLL + 0x00C)
+#define CLKSEL_TIMER4_CLK		(CM_DPLL + 0x010)
+#define CLKSEL_TIMER5_CLK		(CM_DPLL + 0x018)
+#define CLKSEL_TIMER6_CLK		(CM_DPLL + 0x01C)
+#define	CLKSEL_PRUSS_OCP_CLK		(CM_DPLL + 0x030)
+
+#define	CM_RTC				0x800
+#define	CM_RTC_RTC_CLKCTRL		(CM_RTC + 0x000)
+#define	CM_RTC_CLKSTCTRL		(CM_RTC + 0x004)
+
+#define	PRM_PER				0xC00
+#define	PRM_PER_RSTCTRL			(PRM_PER + 0x00)
+
+#define PRM_DEVICE_OFFSET		0xF00
+#define PRM_RSTCTRL			(PRM_DEVICE_OFFSET + 0x00)
+
+struct am335x_prcm_softc {
+	struct resource *	res[2];
+	bus_space_tag_t		bst;
+	bus_space_handle_t	bsh;
+};
+
+static struct resource_spec am335x_prcm_spec[] = {
+	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
+	{ -1, 0 }
+};
+
+static struct am335x_prcm_softc *am335x_prcm_sc = NULL;
+
+static int am335x_clk_noop_activate(struct ti_clock_dev *clkdev);
+static int am335x_clk_generic_activate(struct ti_clock_dev *clkdev);
+static int am335x_clk_gpio_activate(struct ti_clock_dev *clkdev);
+static int am335x_clk_noop_deactivate(struct ti_clock_dev *clkdev);
+static int am335x_clk_generic_deactivate(struct ti_clock_dev *clkdev);
+static int am335x_clk_noop_set_source(struct ti_clock_dev *clkdev, clk_src_t clksrc);
+static int am335x_clk_generic_set_source(struct ti_clock_dev *clkdev, clk_src_t clksrc);
+static int am335x_clk_hsmmc_get_source_freq(struct ti_clock_dev *clkdev,  unsigned int *freq);
+static int am335x_clk_get_sysclk_freq(struct ti_clock_dev *clkdev, unsigned int *freq);
+static int am335x_clk_get_arm_fclk_freq(struct ti_clock_dev *clkdev, unsigned int *freq);
+static int am335x_clk_get_arm_disp_freq(struct ti_clock_dev *clkdev, unsigned int *freq);
+static void am335x_prcm_reset(void);
+static int am335x_clk_cpsw_activate(struct ti_clock_dev *clkdev);
+static int am335x_clk_musb0_activate(struct ti_clock_dev *clkdev);
+static int am335x_clk_lcdc_activate(struct ti_clock_dev *clkdev);
+static int am335x_clk_pruss_activate(struct ti_clock_dev *clkdev);
+
+#define AM335X_NOOP_CLOCK_DEV(i) \
+	{	.id = (i), \
+		.clk_activate = am335x_clk_noop_activate, \
+		.clk_deactivate = am335x_clk_noop_deactivate, \
+		.clk_set_source = am335x_clk_noop_set_source, \
+		.clk_accessible = NULL, \
+		.clk_get_source_freq = NULL \
+	}
+
+#define AM335X_GENERIC_CLOCK_DEV(i) \
+	{	.id = (i), \
+		.clk_activate = am335x_clk_generic_activate, \
+		.clk_deactivate = am335x_clk_generic_deactivate, \
+		.clk_set_source = am335x_clk_generic_set_source, \
+		.clk_accessible = NULL, \
+		.clk_get_source_freq = NULL \
+	}
+
+#define AM335X_GPIO_CLOCK_DEV(i) \
+	{	.id = (i), \
+		.clk_activate = am335x_clk_gpio_activate, \
+		.clk_deactivate = am335x_clk_generic_deactivate, \
+		.clk_set_source = am335x_clk_generic_set_source, \
+		.clk_accessible = NULL, \
+		.clk_get_source_freq = NULL \
+	}
+
+#define AM335X_MMCHS_CLOCK_DEV(i) \
+	{	.id = (i), \
+		.clk_activate = am335x_clk_generic_activate, \
+		.clk_deactivate = am335x_clk_generic_deactivate, \
+		.clk_set_source = am335x_clk_generic_set_source, \
+		.clk_accessible = NULL, \
+		.clk_get_source_freq = am335x_clk_hsmmc_get_source_freq \
+	}
+
+struct ti_clock_dev ti_clk_devmap[] = {
+	/* System clocks */
+	{	.id                  = SYS_CLK,
+		.clk_activate        = NULL,
+		.clk_deactivate      = NULL,
+		.clk_set_source      = NULL,
+		.clk_accessible      = NULL,
+		.clk_get_source_freq = am335x_clk_get_sysclk_freq,
+	},
+	/* MPU (ARM) core clocks */
+	{	.id                  = MPU_CLK,
+		.clk_activate        = NULL,
+		.clk_deactivate      = NULL,
+		.clk_set_source      = NULL,
+		.clk_accessible      = NULL,
+		.clk_get_source_freq = am335x_clk_get_arm_fclk_freq,
+	},
+	/* CPSW Ethernet Switch core clocks */
+	{	.id                  = CPSW_CLK,
+		.clk_activate        = am335x_clk_cpsw_activate,
+		.clk_deactivate      = NULL,
+		.clk_set_source      = NULL,
+		.clk_accessible      = NULL,
+		.clk_get_source_freq = NULL,
+	},
+
+	/* Mentor USB HS controller core clocks */
+	{	.id                  = MUSB0_CLK,
+		.clk_activate        = am335x_clk_musb0_activate,
+		.clk_deactivate      = NULL,
+		.clk_set_source      = NULL,
+		.clk_accessible      = NULL,
+		.clk_get_source_freq = NULL,
+	},
+
+	/* LCD controller clocks */
+	{	.id                  = LCDC_CLK,
+		.clk_activate        = am335x_clk_lcdc_activate,
+		.clk_deactivate      = NULL,
+		.clk_set_source      = NULL,
+		.clk_accessible      = NULL,
+		.clk_get_source_freq = am335x_clk_get_arm_disp_freq,
+	},
+
+        /* UART.  Uart0 clock cannot be controlled. */
+	AM335X_NOOP_CLOCK_DEV(UART0_CLK),
+	AM335X_GENERIC_CLOCK_DEV(UART1_CLK),
+	AM335X_GENERIC_CLOCK_DEV(UART2_CLK),
+	AM335X_GENERIC_CLOCK_DEV(UART3_CLK),
+	AM335X_GENERIC_CLOCK_DEV(UART4_CLK),
+	AM335X_GENERIC_CLOCK_DEV(UART5_CLK),
+
+	/* DMTimer */
+	AM335X_GENERIC_CLOCK_DEV(DMTIMER2_CLK),
+	AM335X_GENERIC_CLOCK_DEV(DMTIMER3_CLK),
+	AM335X_GENERIC_CLOCK_DEV(DMTIMER4_CLK),
+	AM335X_GENERIC_CLOCK_DEV(DMTIMER5_CLK),
+	AM335X_GENERIC_CLOCK_DEV(DMTIMER6_CLK),
+	AM335X_GENERIC_CLOCK_DEV(DMTIMER7_CLK),
+
+	/* GPIO */
+	AM335X_GPIO_CLOCK_DEV(GPIO0_CLK),
+	AM335X_GPIO_CLOCK_DEV(GPIO1_CLK),
+	AM335X_GPIO_CLOCK_DEV(GPIO2_CLK),
+	AM335X_GPIO_CLOCK_DEV(GPIO3_CLK),
+
+	/* I2C */
+	AM335X_GENERIC_CLOCK_DEV(I2C0_CLK),
+	AM335X_GENERIC_CLOCK_DEV(I2C1_CLK),
+	AM335X_GENERIC_CLOCK_DEV(I2C2_CLK),
+
+	/* TSC_ADC */
+	AM335X_GENERIC_CLOCK_DEV(TSC_ADC_CLK),
+
+	/* EDMA */
+	AM335X_GENERIC_CLOCK_DEV(EDMA_TPCC_CLK),
+	AM335X_GENERIC_CLOCK_DEV(EDMA_TPTC0_CLK),
+	AM335X_GENERIC_CLOCK_DEV(EDMA_TPTC1_CLK),
+	AM335X_GENERIC_CLOCK_DEV(EDMA_TPTC2_CLK),
+
+	/* MMCHS */
+	AM335X_MMCHS_CLOCK_DEV(MMC0_CLK),
+	AM335X_MMCHS_CLOCK_DEV(MMC1_CLK),
+	AM335X_MMCHS_CLOCK_DEV(MMC2_CLK),
+
+	/* PWMSS */
+	AM335X_GENERIC_CLOCK_DEV(PWMSS0_CLK),
+	AM335X_GENERIC_CLOCK_DEV(PWMSS1_CLK),
+	AM335X_GENERIC_CLOCK_DEV(PWMSS2_CLK),
+
+	/* System Mailbox clock */
+	AM335X_GENERIC_CLOCK_DEV(MAILBOX0_CLK),
+
+	/* SPINLOCK */
+	AM335X_GENERIC_CLOCK_DEV(SPINLOCK0_CLK),
+
+	/* PRU-ICSS */
+	{	.id		     = PRUSS_CLK,
+		.clk_activate	     = am335x_clk_pruss_activate,
+		.clk_deactivate      = NULL,
+		.clk_set_source      = NULL,
+		.clk_accessible      = NULL,
+		.clk_get_source_freq = NULL,
+	},
+
+	/* RTC */
+	AM335X_GENERIC_CLOCK_DEV(RTC_CLK),
+
+	{  INVALID_CLK_IDENT, NULL, NULL, NULL, NULL }
+};
+
+struct am335x_clk_details {
+	clk_ident_t	id;
+	uint32_t	clkctrl_reg;
+	uint32_t	clksel_reg;
+};
+
+#define _CLK_DETAIL(i, c, s) \
+	{	.id = (i), \
+		.clkctrl_reg = (c), \
+		.clksel_reg = (s), \
+	}
+
+static struct am335x_clk_details g_am335x_clk_details[] = {
+
+        /* UART. UART0 clock not controllable. */
+	_CLK_DETAIL(UART0_CLK, 0, 0),
+	_CLK_DETAIL(UART1_CLK, CM_PER_UART1_CLKCTRL, 0),
+	_CLK_DETAIL(UART2_CLK, CM_PER_UART2_CLKCTRL, 0),
+	_CLK_DETAIL(UART3_CLK, CM_PER_UART3_CLKCTRL, 0),
+	_CLK_DETAIL(UART4_CLK, CM_PER_UART4_CLKCTRL, 0),
+	_CLK_DETAIL(UART5_CLK, CM_PER_UART5_CLKCTRL, 0),
+
+	/* DMTimer modules */
+	_CLK_DETAIL(DMTIMER2_CLK, CM_PER_TIMER2_CLKCTRL, CLKSEL_TIMER2_CLK),
+	_CLK_DETAIL(DMTIMER3_CLK, CM_PER_TIMER3_CLKCTRL, CLKSEL_TIMER3_CLK),
+	_CLK_DETAIL(DMTIMER4_CLK, CM_PER_TIMER4_CLKCTRL, CLKSEL_TIMER4_CLK),
+	_CLK_DETAIL(DMTIMER5_CLK, CM_PER_TIMER5_CLKCTRL, CLKSEL_TIMER5_CLK),
+	_CLK_DETAIL(DMTIMER6_CLK, CM_PER_TIMER6_CLKCTRL, CLKSEL_TIMER6_CLK),
+	_CLK_DETAIL(DMTIMER7_CLK, CM_PER_TIMER7_CLKCTRL, CLKSEL_TIMER7_CLK),
+
+	/* GPIO modules */
+	_CLK_DETAIL(GPIO0_CLK, CM_WKUP_GPIO0_CLKCTRL, 0),
+	_CLK_DETAIL(GPIO1_CLK, CM_PER_GPIO1_CLKCTRL, 0),
+	_CLK_DETAIL(GPIO2_CLK, CM_PER_GPIO2_CLKCTRL, 0),
+	_CLK_DETAIL(GPIO3_CLK, CM_PER_GPIO3_CLKCTRL, 0),
+
+	/* I2C modules */
+	_CLK_DETAIL(I2C0_CLK, CM_WKUP_I2C0_CLKCTRL, 0),
+	_CLK_DETAIL(I2C1_CLK, CM_PER_I2C1_CLKCTRL, 0),
+	_CLK_DETAIL(I2C2_CLK, CM_PER_I2C2_CLKCTRL, 0),
+
+	/* TSC_ADC module */
+	_CLK_DETAIL(TSC_ADC_CLK, CM_WKUP_ADC_TSC_CLKCTRL, 0),
+
+	/* EDMA modules */
+	_CLK_DETAIL(EDMA_TPCC_CLK, CM_PER_TPCC_CLKCTRL, 0),
+	_CLK_DETAIL(EDMA_TPTC0_CLK, CM_PER_TPTC0_CLKCTRL, 0),
+	_CLK_DETAIL(EDMA_TPTC1_CLK, CM_PER_TPTC1_CLKCTRL, 0),
+	_CLK_DETAIL(EDMA_TPTC2_CLK, CM_PER_TPTC2_CLKCTRL, 0),
+
+	/* MMCHS modules*/
+	_CLK_DETAIL(MMC0_CLK, CM_PER_MMC0_CLKCTRL, 0),
+	_CLK_DETAIL(MMC1_CLK, CM_PER_MMC1_CLKCTRL, 0),
+	_CLK_DETAIL(MMC2_CLK, CM_PER_MMC1_CLKCTRL, 0),
+
+	/* PWMSS modules */
+	_CLK_DETAIL(PWMSS0_CLK, CM_PER_EPWMSS0_CLKCTRL, 0),
+	_CLK_DETAIL(PWMSS1_CLK, CM_PER_EPWMSS1_CLKCTRL, 0),
+	_CLK_DETAIL(PWMSS2_CLK, CM_PER_EPWMSS2_CLKCTRL, 0),
+
+	_CLK_DETAIL(MAILBOX0_CLK, CM_PER_MAILBOX0_CLKCTRL, 0),
+	_CLK_DETAIL(SPINLOCK0_CLK, CM_PER_SPINLOCK0_CLKCTRL, 0),
+
+	/* RTC module */
+	_CLK_DETAIL(RTC_CLK, CM_RTC_RTC_CLKCTRL, 0),
+
+	{ INVALID_CLK_IDENT, 0},
+};
+
+/* Read/Write macros */
+#define prcm_read_4(reg)		\
+	bus_space_read_4(am335x_prcm_sc->bst, am335x_prcm_sc->bsh, reg)
+#define prcm_write_4(reg, val)		\
+	bus_space_write_4(am335x_prcm_sc->bst, am335x_prcm_sc->bsh, reg, val)
+
+void am335x_prcm_setup_dmtimer(int);
+
+static int
+am335x_prcm_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (ofw_bus_is_compatible(dev, "am335x,prcm")) {
+		device_set_desc(dev, "AM335x Power and Clock Management");
+		return(BUS_PROBE_DEFAULT);
+	}
+
+	return (ENXIO);
+}
+
+static int
+am335x_prcm_attach(device_t dev)
+{
+	struct am335x_prcm_softc *sc = device_get_softc(dev);
+	unsigned int sysclk, fclk;
+
+	if (am335x_prcm_sc)
+		return (ENXIO);
+
+	if (bus_alloc_resources(dev, am335x_prcm_spec, sc->res)) {
+		device_printf(dev, "could not allocate resources\n");
+		return (ENXIO);
+	}
+
+	sc->bst = rman_get_bustag(sc->res[0]);
+	sc->bsh = rman_get_bushandle(sc->res[0]);
+
+	am335x_prcm_sc = sc;
+	ti_cpu_reset = am335x_prcm_reset;
+
+	am335x_clk_get_sysclk_freq(NULL, &sysclk);
+	am335x_clk_get_arm_fclk_freq(NULL, &fclk);
+	device_printf(dev, "Clocks: System %u.%01u MHz, CPU %u MHz\n",
+		sysclk/1000000, (sysclk % 1000000)/100000, fclk/1000000);
+
+	return (0);
+}
+
+static device_method_t am335x_prcm_methods[] = {
+	DEVMETHOD(device_probe,		am335x_prcm_probe),
+	DEVMETHOD(device_attach,	am335x_prcm_attach),
+	{ 0, 0 }
+};
+
+static driver_t am335x_prcm_driver = {
+	"am335x_prcm",
+	am335x_prcm_methods,
+	sizeof(struct am335x_prcm_softc),
+};
+
+static devclass_t am335x_prcm_devclass;
+
+DRIVER_MODULE(am335x_prcm, simplebus, am335x_prcm_driver,
+	am335x_prcm_devclass, 0, 0);
+MODULE_DEPEND(am335x_prcm, ti_scm, 1, 1, 1);
+
+static struct am335x_clk_details*
+am335x_clk_details(clk_ident_t id)
+{
+	struct am335x_clk_details *walker;
+
+	for (walker = g_am335x_clk_details; walker->id != INVALID_CLK_IDENT; walker++) {
+		if (id == walker->id)
+			return (walker);
+	}
+
+	return NULL;
+}
+
+static int
+am335x_clk_noop_activate(struct ti_clock_dev *clkdev)
+{
+
+	return (0);
+}
+
+static int
+am335x_clk_generic_activate(struct ti_clock_dev *clkdev)
+{
+	struct am335x_prcm_softc *sc = am335x_prcm_sc;
+	struct am335x_clk_details* clk_details;
+
+	if (sc == NULL)
+		return ENXIO;
+
+	clk_details = am335x_clk_details(clkdev->id);
+
+	if (clk_details == NULL)
+		return (ENXIO);
+
+	/* set *_CLKCTRL register MODULEMODE[1:0] to enable(2) */
+	prcm_write_4(clk_details->clkctrl_reg, 2);
+	while ((prcm_read_4(clk_details->clkctrl_reg) & 0x3) != 2)
+		DELAY(10);
+
+	return (0);
+}
+
+static int
+am335x_clk_gpio_activate(struct ti_clock_dev *clkdev)
+{
+	struct am335x_prcm_softc *sc = am335x_prcm_sc;
+	struct am335x_clk_details* clk_details;
+
+	if (sc == NULL)
+		return ENXIO;
+
+	clk_details = am335x_clk_details(clkdev->id);
+
+	if (clk_details == NULL)
+		return (ENXIO);
+
+	/* set *_CLKCTRL register MODULEMODE[1:0] to enable(2) */
+	/* set *_CLKCTRL register OPTFCLKEN_GPIO_1_G DBCLK[18] to FCLK_EN(1) */
+	prcm_write_4(clk_details->clkctrl_reg, 2 | (1 << 18));
+	while ((prcm_read_4(clk_details->clkctrl_reg) &
+	    (3 | (1 << 18) )) != (2 | (1 << 18)))
+		DELAY(10);
+
+	return (0);
+}
+
+static int
+am335x_clk_noop_deactivate(struct ti_clock_dev *clkdev)
+{
+
+	return(0);
+}
+
+static int
+am335x_clk_generic_deactivate(struct ti_clock_dev *clkdev)
+{
+	struct am335x_prcm_softc *sc = am335x_prcm_sc;
+	struct am335x_clk_details* clk_details;
+
+	if (sc == NULL)
+		return ENXIO;
+
+	clk_details = am335x_clk_details(clkdev->id);
+
+	if (clk_details == NULL)
+		return (ENXIO);
+
+	/* set *_CLKCTRL register MODULEMODE[1:0] to disable(0) */
+	prcm_write_4(clk_details->clkctrl_reg, 0);
+	while ((prcm_read_4(clk_details->clkctrl_reg) & 0x3) != 0)
+		DELAY(10);
+
+	return (0);
+}
+
+static int
+am335x_clk_noop_set_source(struct ti_clock_dev *clkdev, clk_src_t clksrc)
+{
+
+	return (0);
+}
+
+static int
+am335x_clk_generic_set_source(struct ti_clock_dev *clkdev, clk_src_t clksrc)
+{
+	struct am335x_prcm_softc *sc = am335x_prcm_sc;
+	struct am335x_clk_details* clk_details;
+	uint32_t reg;
+
+	if (sc == NULL)
+		return ENXIO;
+
+	clk_details = am335x_clk_details(clkdev->id);
+
+	if (clk_details == NULL)
+		return (ENXIO);
+
+	switch (clksrc) {
+		case EXT_CLK:
+			reg = 0; /* SEL2: TCLKIN clock */
+			break;
+		case SYSCLK_CLK:
+			reg = 1; /* SEL1: CLK_M_OSC clock */
+			break;
+		case F32KHZ_CLK:
+			reg = 2; /* SEL3: CLK_32KHZ clock */
+			break;
+		default:
+			return (ENXIO);
+	}
+
+	prcm_write_4(clk_details->clksel_reg, reg);
+	while ((prcm_read_4(clk_details->clksel_reg) & 0x3) != reg)
+		DELAY(10);
+
+	return (0);
+}
+
+static int
+am335x_clk_hsmmc_get_source_freq(struct ti_clock_dev *clkdev,  unsigned int *freq)
+{
+	*freq = 96000000;
+	return (0);
+}
+
+static int
+am335x_clk_get_sysclk_freq(struct ti_clock_dev *clkdev, unsigned int *freq)
+{
+	uint32_t ctrl_status;
+
+	/* Read the input clock freq from the control module */
+	/* control_status reg (0x40) */
+	if (ti_scm_reg_read_4(0x40, &ctrl_status))
+		return ENXIO;
+
+	switch ((ctrl_status>>22) & 0x3) {
+	case 0x0:
+		/* 19.2Mhz */
+		*freq = 19200000;
+		break;
+	case 0x1:
+		/* 24Mhz */
+		*freq = 24000000;
+		break;
+	case 0x2:
+		/* 25Mhz */
+		*freq = 25000000;
+		break;
+	case 0x3:
+		/* 26Mhz */
+		*freq = 26000000;
+		break;
+	}
+
+	return (0);
+}
+
+#define DPLL_BYP_CLKSEL(reg)	((reg>>23) & 1)
+#define DPLL_DIV(reg)		((reg & 0x7f)+1)
+#define DPLL_MULT(reg)		((reg>>8) & 0x7FF)
+
+static int
+am335x_clk_get_arm_fclk_freq(struct ti_clock_dev *clkdev, unsigned int *freq)
+{
+	uint32_t reg;
+	uint32_t sysclk;
+
+	reg = prcm_read_4(CM_WKUP_CM_CLKSEL_DPLL_MPU);
+
+	/*Check if we are running in bypass */
+	if (DPLL_BYP_CLKSEL(reg))
+		return ENXIO;
+
+	am335x_clk_get_sysclk_freq(NULL, &sysclk);
+	*freq = DPLL_MULT(reg) * (sysclk / DPLL_DIV(reg));
+	return(0);
+}
+
+static int
+am335x_clk_get_arm_disp_freq(struct ti_clock_dev *clkdev, unsigned int *freq)
+{
+	uint32_t reg;
+	uint32_t sysclk;
+
+	reg = prcm_read_4(CM_WKUP_CM_CLKSEL_DPLL_DISP);
+
+	/*Check if we are running in bypass */
+	if (DPLL_BYP_CLKSEL(reg))
+		return ENXIO;
+
+	am335x_clk_get_sysclk_freq(NULL, &sysclk);
+	*freq = DPLL_MULT(reg) * (sysclk / DPLL_DIV(reg));
+	return(0);
+}
+
+static void
+am335x_prcm_reset(void)
+{
+	prcm_write_4(PRM_RSTCTRL, (1<<1));
+}
+
+static int
+am335x_clk_cpsw_activate(struct ti_clock_dev *clkdev)
+{
+	struct am335x_prcm_softc *sc = am335x_prcm_sc;
+
+	if (sc == NULL)
+		return ENXIO;
+
+	/* set MODULENAME to ENABLE */
+	prcm_write_4(CM_PER_CPGMAC0_CLKCTRL, 2);
+
+	/* wait for IDLEST to become Func(0) */
+	while(prcm_read_4(CM_PER_CPGMAC0_CLKCTRL) & (3<<16));
+
+	/*set CLKTRCTRL to SW_WKUP(2) */
+	prcm_write_4(CM_PER_CPSW_CLKSTCTRL, 2);
+
+	/* wait for 125 MHz OCP clock to become active */
+	while((prcm_read_4(CM_PER_CPSW_CLKSTCTRL) & (1<<4)) == 0);
+	return(0);
+}
+
+static int
+am335x_clk_musb0_activate(struct ti_clock_dev *clkdev)
+{
+	struct am335x_prcm_softc *sc = am335x_prcm_sc;
+
+	if (sc == NULL)
+		return ENXIO;
+
+	/* set ST_DPLL_CLKDCOLDO(9) to CLK_GATED(1) */
+	/* set DPLL_CLKDCOLDO_GATE_CTRL(8) to CLK_ENABLE(1)*/
+        prcm_write_4(CM_WKUP_CM_CLKDCOLDO_DPLL_PER, 0x300);
+
+	/*set MODULEMODE to ENABLE(2) */
+	prcm_write_4(CM_PER_USB0_CLKCTRL, 2);
+
+	/* wait for MODULEMODE to become ENABLE(2) */
+	while ((prcm_read_4(CM_PER_USB0_CLKCTRL) & 0x3) != 2)
+		DELAY(10);
+
+	/* wait for IDLEST to become Func(0) */
+	while(prcm_read_4(CM_PER_USB0_CLKCTRL) & (3<<16))
+		DELAY(10);
+
+	return(0);
+}
+
+static int
+am335x_clk_lcdc_activate(struct ti_clock_dev *clkdev)
+{
+	struct am335x_prcm_softc *sc = am335x_prcm_sc;
+
+	if (sc == NULL)
+		return (ENXIO);
+
+	/* Bypass mode */
+	prcm_write_4(CM_WKUP_CM_CLKMODE_DPLL_DISP, 0x4);
+
+	/* Make sure it's in bypass mode */
+	while (!(prcm_read_4(CM_WKUP_CM_IDLEST_DPLL_DISP)
+	    & (1 << 8)))
+		DELAY(10);
+
+	/*
+	 * For now set frequency to  5xSYSFREQ 
+	 * More flexible control might be required
+	 */
+	prcm_write_4(CM_WKUP_CM_CLKSEL_DPLL_DISP, (5 << 8) | 0);
+
+	/* Locked mode */
+	prcm_write_4(CM_WKUP_CM_CLKMODE_DPLL_DISP, 0x7);
+
+	int timeout = 10000;
+	while ((!(prcm_read_4(CM_WKUP_CM_IDLEST_DPLL_DISP)
+	    & (1 << 0))) && timeout--)
+		DELAY(10);
+
+	/*set MODULEMODE to ENABLE(2) */
+	prcm_write_4(CM_PER_LCDC_CLKCTRL, 2);
+
+	/* wait for MODULEMODE to become ENABLE(2) */
+	while ((prcm_read_4(CM_PER_LCDC_CLKCTRL) & 0x3) != 2)
+		DELAY(10);
+
+	/* wait for IDLEST to become Func(0) */
+	while(prcm_read_4(CM_PER_LCDC_CLKCTRL) & (3<<16))
+		DELAY(10);
+
+	return (0);
+}
+
+static int
+am335x_clk_pruss_activate(struct ti_clock_dev *clkdev)
+{
+	struct am335x_prcm_softc *sc = am335x_prcm_sc;
+
+	if (sc == NULL)
+		return (ENXIO);
+
+	/* Set MODULEMODE to ENABLE(2) */
+	prcm_write_4(CM_PER_PRUSS_CLKCTRL, 2);
+
+	/* Wait for MODULEMODE to become ENABLE(2) */
+	while ((prcm_read_4(CM_PER_PRUSS_CLKCTRL) & 0x3) != 2)
+		DELAY(10);
+
+	/* Set CLKTRCTRL to SW_WKUP(2) */
+	prcm_write_4(CM_PER_PRUSS_CLKSTCTRL, 2);
+
+	/* Wait for the 200 MHz OCP clock to become active */
+	while ((prcm_read_4(CM_PER_PRUSS_CLKSTCTRL) & (1<<4)) == 0)
+		DELAY(10);
+
+	/* Wait for the 200 MHz IEP clock to become active */
+	while ((prcm_read_4(CM_PER_PRUSS_CLKSTCTRL) & (1<<5)) == 0)
+		DELAY(10);
+
+	/* Wait for the 192 MHz UART clock to become active */
+	while ((prcm_read_4(CM_PER_PRUSS_CLKSTCTRL) & (1<<6)) == 0)
+		DELAY(10);
+
+	/* Select L3F as OCP clock */
+	prcm_write_4(CLKSEL_PRUSS_OCP_CLK, 0);
+	while ((prcm_read_4(CLKSEL_PRUSS_OCP_CLK) & 0x3) != 0)
+		DELAY(10);
+
+	/* Clear the RESET bit */
+	prcm_write_4(PRM_PER_RSTCTRL, prcm_read_4(PRM_PER_RSTCTRL) & ~2);
+
+	return (0);
+}


Property changes on: trunk/sys/arm/ti/am335x/am335x_prcm.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/am335x/am335x_pwm.c
===================================================================
--- trunk/sys/arm/ti/am335x/am335x_pwm.c	                        (rev 0)
+++ trunk/sys/arm/ti/am335x/am335x_pwm.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,543 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Oleksandr Tymoshenko <gonzo at freebsd.org>
+ * 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: stable/10/sys/arm/ti/am335x/am335x_pwm.c 270237 2014-08-20 17:57:23Z loos $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/limits.h>
+#include <sys/lock.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+#include <sys/sysctl.h>
+
+#include <machine/bus.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <arm/ti/ti_prcm.h>
+#include <arm/ti/ti_scm.h>
+
+#include "am335x_pwm.h"
+#include "am335x_scm.h"
+
+/* In ticks */
+#define	DEFAULT_PWM_PERIOD	1000
+#define	PWM_CLOCK		100000000UL
+
+#define	PWM_LOCK(_sc)		mtx_lock(&(_sc)->sc_mtx)
+#define	PWM_UNLOCK(_sc)		mtx_unlock(&(_sc)->sc_mtx)
+#define	PWM_LOCK_INIT(_sc)	mtx_init(&(_sc)->sc_mtx, \
+    device_get_nameunit(_sc->sc_dev), "am335x_pwm softc", MTX_DEF)
+#define	PWM_LOCK_DESTROY(_sc)	mtx_destroy(&(_sc)->sc_mtx)
+
+static struct resource_spec am335x_pwm_mem_spec[] = {
+	{ SYS_RES_MEMORY, 0, RF_ACTIVE }, /* PWMSS */
+	{ SYS_RES_MEMORY, 1, RF_ACTIVE }, /* eCAP */
+	{ SYS_RES_MEMORY, 2, RF_ACTIVE }, /* eQEP */
+	{ SYS_RES_MEMORY, 3, RF_ACTIVE }, /*ePWM */
+	{ -1, 0, 0 }
+};
+
+#define	PWMSS_READ4(_sc, reg)	bus_read_4((_sc)->sc_mem_res[0], reg);
+#define	PWMSS_WRITE4(_sc, reg, value)	\
+    bus_write_4((_sc)->sc_mem_res[0], reg, value);
+
+#define	ECAP_READ2(_sc, reg)	bus_read_2((_sc)->sc_mem_res[1], reg);
+#define	ECAP_WRITE2(_sc, reg, value)	\
+    bus_write_2((_sc)->sc_mem_res[1], reg, value);
+#define	ECAP_READ4(_sc, reg)	bus_read_4((_sc)->sc_mem_res[1], reg);
+#define	ECAP_WRITE4(_sc, reg, value)	\
+    bus_write_4((_sc)->sc_mem_res[1], reg, value);
+
+#define	EPWM_READ2(_sc, reg)	bus_read_2((_sc)->sc_mem_res[3], reg);
+#define	EPWM_WRITE2(_sc, reg, value)	\
+    bus_write_2((_sc)->sc_mem_res[3], reg, value);
+
+#define	PWMSS_IDVER		0x00
+#define	PWMSS_SYSCONFIG		0x04
+#define	PWMSS_CLKCONFIG		0x08
+#define		CLKCONFIG_EPWMCLK_EN	(1 << 8)
+#define	PWMSS_CLKSTATUS		0x0C
+
+#define	ECAP_TSCTR		0x00
+#define	ECAP_CAP1		0x08
+#define	ECAP_CAP2		0x0C
+#define	ECAP_CAP3		0x10
+#define	ECAP_CAP4		0x14
+#define	ECAP_ECCTL2		0x2A
+#define		ECCTL2_MODE_APWM		(1 << 9)
+#define		ECCTL2_SYNCO_SEL		(3 << 6)
+#define		ECCTL2_TSCTRSTOP_FREERUN	(1 << 4)
+
+#define	EPWM_TBCTL		0x00
+#define		TBCTL_FREERUN		(2 << 14)
+#define		TBCTL_PHDIR_UP		(1 << 13)
+#define		TBCTL_PHDIR_DOWN	(0 << 13)
+#define		TBCTL_CLKDIV(x)		((x) << 10)
+#define		TBCTL_CLKDIV_MASK	(3 << 10)
+#define		TBCTL_HSPCLKDIV(x)	((x) << 7)
+#define		TBCTL_HSPCLKDIV_MASK	(3 << 7)
+#define		TBCTL_SYNCOSEL_DISABLED	(3 << 4)
+#define		TBCTL_PRDLD_SHADOW	(0 << 3)
+#define		TBCTL_PRDLD_IMMEDIATE	(0 << 3)
+#define		TBCTL_PHSEN_ENABLED	(1 << 2)
+#define		TBCTL_PHSEN_DISABLED	(0 << 2)
+#define		TBCTL_CTRMODE_MASK	(3)
+#define		TBCTL_CTRMODE_UP	(0 << 0)
+#define		TBCTL_CTRMODE_DOWN	(1 << 0)
+#define		TBCTL_CTRMODE_UPDOWN	(2 << 0)
+#define		TBCTL_CTRMODE_FREEZE	(3 << 0)
+
+#define	EPWM_TBSTS		0x02
+#define	EPWM_TBPHSHR		0x04
+#define	EPWM_TBPHS		0x06
+#define	EPWM_TBCNT		0x08
+#define	EPWM_TBPRD		0x0a
+/* Counter-compare */
+#define	EPWM_CMPCTL		0x0e
+#define		CMPCTL_SHDWBMODE_SHADOW		(1 << 6)
+#define		CMPCTL_SHDWBMODE_IMMEDIATE	(0 << 6)
+#define		CMPCTL_SHDWAMODE_SHADOW		(1 << 4)
+#define		CMPCTL_SHDWAMODE_IMMEDIATE	(0 << 4)
+#define		CMPCTL_LOADBMODE_ZERO		(0 << 2)
+#define		CMPCTL_LOADBMODE_PRD		(1 << 2)
+#define		CMPCTL_LOADBMODE_EITHER		(2 << 2)
+#define		CMPCTL_LOADBMODE_FREEZE		(3 << 2)
+#define		CMPCTL_LOADAMODE_ZERO		(0 << 0)
+#define		CMPCTL_LOADAMODE_PRD		(1 << 0)
+#define		CMPCTL_LOADAMODE_EITHER		(2 << 0)
+#define		CMPCTL_LOADAMODE_FREEZE		(3 << 0)
+#define	EPWM_CMPAHR		0x10
+#define	EPWM_CMPA		0x12
+#define	EPWM_CMPB		0x14
+/* CMPCTL_LOADAMODE_ZERO */
+#define	EPWM_AQCTLA		0x16
+#define	EPWM_AQCTLB		0x18
+#define		AQCTL_CBU_NONE		(0 << 8)
+#define		AQCTL_CBU_CLEAR		(1 << 8)
+#define		AQCTL_CBU_SET		(2 << 8)
+#define		AQCTL_CBU_TOGGLE	(3 << 8)
+#define		AQCTL_CAU_NONE		(0 << 4)
+#define		AQCTL_CAU_CLEAR		(1 << 4)
+#define		AQCTL_CAU_SET		(2 << 4)
+#define		AQCTL_CAU_TOGGLE	(3 << 4)
+#define		AQCTL_ZRO_NONE		(0 << 0)
+#define		AQCTL_ZRO_CLEAR		(1 << 0)
+#define		AQCTL_ZRO_SET		(2 << 0)
+#define		AQCTL_ZRO_TOGGLE	(3 << 0)
+#define	EPWM_AQSFRC		0x1a
+#define	EPWM_AQCSFRC		0x1c
+
+/* Trip-Zone module */
+#define	EPWM_TZCTL		0x28
+#define	EPWM_TZFLG		0x2C
+/* High-Resolution PWM */
+#define	EPWM_HRCTL		0x40
+#define		HRCTL_DELMODE_BOTH	3
+#define		HRCTL_DELMODE_FALL	2
+#define		HRCTL_DELMODE_RISE	1
+
+static device_probe_t am335x_pwm_probe;
+static device_attach_t am335x_pwm_attach;
+static device_detach_t am335x_pwm_detach;
+        
+static int am335x_pwm_clkdiv[8] = { 1, 2, 4, 8, 16, 32, 64, 128 };
+
+struct am335x_pwm_softc {
+	device_t		sc_dev;
+	struct mtx		sc_mtx;
+	struct resource		*sc_mem_res[4];
+	int			sc_id;
+	/* sysctl for configuration */
+	int			sc_pwm_clkdiv;
+	int			sc_pwm_freq;
+	struct sysctl_oid	*sc_clkdiv_oid;
+	struct sysctl_oid	*sc_freq_oid;
+	struct sysctl_oid	*sc_period_oid;
+	struct sysctl_oid	*sc_chanA_oid;
+	struct sysctl_oid	*sc_chanB_oid;
+	uint32_t		sc_pwm_period;
+	uint32_t		sc_pwm_dutyA;
+	uint32_t		sc_pwm_dutyB;
+};
+
+static device_method_t am335x_pwm_methods[] = {
+	DEVMETHOD(device_probe,		am335x_pwm_probe),
+	DEVMETHOD(device_attach,	am335x_pwm_attach),
+	DEVMETHOD(device_detach,	am335x_pwm_detach),
+
+	DEVMETHOD_END
+};
+
+static driver_t am335x_pwm_driver = {
+	"am335x_pwm",
+	am335x_pwm_methods,
+	sizeof(struct am335x_pwm_softc),
+};
+
+static devclass_t am335x_pwm_devclass;
+
+/*
+ * API function to set period/duty cycles for ECASx 
+ */
+int
+am335x_pwm_config_ecas(int unit, int period, int duty)
+{
+	device_t dev;
+	struct am335x_pwm_softc *sc;
+	uint16_t reg;
+
+	dev = devclass_get_device(am335x_pwm_devclass, unit);
+	if (dev == NULL)
+		return (ENXIO);
+
+	if (duty > period)
+		return (EINVAL);
+
+	if (period == 0)
+		return (EINVAL);
+
+	sc = device_get_softc(dev);
+	PWM_LOCK(sc);
+
+	reg = ECAP_READ2(sc, ECAP_ECCTL2);
+	reg |= ECCTL2_MODE_APWM | ECCTL2_TSCTRSTOP_FREERUN | ECCTL2_SYNCO_SEL;
+	ECAP_WRITE2(sc, ECAP_ECCTL2, reg);
+
+	/* CAP3 in APWM mode is APRD shadow register */
+	ECAP_WRITE4(sc, ECAP_CAP3, period - 1);
+
+	/* CAP4 in APWM mode is ACMP shadow register */
+	ECAP_WRITE4(sc, ECAP_CAP4, duty);
+	/* Restart counter */
+	ECAP_WRITE4(sc, ECAP_TSCTR, 0);
+
+	PWM_UNLOCK(sc);
+
+	return (0);
+}
+
+static void
+am335x_pwm_freq(struct am335x_pwm_softc *sc)
+{
+	int clkdiv;
+
+	clkdiv = am335x_pwm_clkdiv[sc->sc_pwm_clkdiv];
+	sc->sc_pwm_freq = PWM_CLOCK / (1 * clkdiv) / sc->sc_pwm_period;
+}
+
+static int
+am335x_pwm_sysctl_freq(SYSCTL_HANDLER_ARGS)
+{
+	int clkdiv, error, freq, i, period;
+	struct am335x_pwm_softc *sc;
+	uint32_t reg;
+
+	sc = (struct am335x_pwm_softc *)arg1;
+
+	PWM_LOCK(sc);
+	freq = sc->sc_pwm_freq;
+	PWM_UNLOCK(sc);
+
+	error = sysctl_handle_int(oidp, &freq, sizeof(freq), req);
+	if (error != 0 || req->newptr == NULL)
+		return (error);
+
+	if (freq > PWM_CLOCK)
+		freq = PWM_CLOCK;
+
+	PWM_LOCK(sc);
+	if (freq != sc->sc_pwm_freq) {
+		for (i = nitems(am335x_pwm_clkdiv) - 1; i >= 0; i--) {
+			clkdiv = am335x_pwm_clkdiv[i];
+			period = PWM_CLOCK / clkdiv / freq;
+			if (period > USHRT_MAX)
+				break;
+			sc->sc_pwm_clkdiv = i;
+			sc->sc_pwm_period = period;
+		}
+		/* Reset the duty cycle settings. */
+		sc->sc_pwm_dutyA = 0;
+		sc->sc_pwm_dutyB = 0;
+		EPWM_WRITE2(sc, EPWM_CMPA, sc->sc_pwm_dutyA);
+		EPWM_WRITE2(sc, EPWM_CMPB, sc->sc_pwm_dutyB);
+		/* Update the clkdiv settings. */
+		reg = EPWM_READ2(sc, EPWM_TBCTL);
+		reg &= ~TBCTL_CLKDIV_MASK;
+		reg |= TBCTL_CLKDIV(sc->sc_pwm_clkdiv);
+		EPWM_WRITE2(sc, EPWM_TBCTL, reg);
+		/* Update the period settings. */
+		EPWM_WRITE2(sc, EPWM_TBPRD, sc->sc_pwm_period - 1);
+		am335x_pwm_freq(sc);
+	}
+	PWM_UNLOCK(sc);
+
+	return (0);
+}
+
+static int
+am335x_pwm_sysctl_clkdiv(SYSCTL_HANDLER_ARGS)
+{
+	int error, i, clkdiv;
+	struct am335x_pwm_softc *sc;
+	uint32_t reg;
+
+	sc = (struct am335x_pwm_softc *)arg1;
+
+	PWM_LOCK(sc);
+	clkdiv = am335x_pwm_clkdiv[sc->sc_pwm_clkdiv];
+	PWM_UNLOCK(sc);
+
+	error = sysctl_handle_int(oidp, &clkdiv, sizeof(clkdiv), req);
+	if (error != 0 || req->newptr == NULL)
+		return (error);
+
+	PWM_LOCK(sc);
+	if (clkdiv != am335x_pwm_clkdiv[sc->sc_pwm_clkdiv]) {
+		for (i = 0; i < nitems(am335x_pwm_clkdiv); i++)
+			if (clkdiv >= am335x_pwm_clkdiv[i])
+				sc->sc_pwm_clkdiv = i;
+
+		reg = EPWM_READ2(sc, EPWM_TBCTL);
+		reg &= ~TBCTL_CLKDIV_MASK;
+		reg |= TBCTL_CLKDIV(sc->sc_pwm_clkdiv);
+		EPWM_WRITE2(sc, EPWM_TBCTL, reg);
+		am335x_pwm_freq(sc);
+	}
+	PWM_UNLOCK(sc);
+
+	return (0);
+}
+
+static int
+am335x_pwm_sysctl_duty(SYSCTL_HANDLER_ARGS)
+{
+	struct am335x_pwm_softc *sc = (struct am335x_pwm_softc*)arg1;
+	int error;
+	uint32_t duty;
+       
+	if (oidp == sc->sc_chanA_oid)
+		duty = sc->sc_pwm_dutyA;
+	else
+		duty = sc->sc_pwm_dutyB;
+	error = sysctl_handle_int(oidp, &duty, 0, req);
+
+	if (error != 0 || req->newptr == NULL)
+		return (error);
+
+	if (duty > sc->sc_pwm_period) {
+		device_printf(sc->sc_dev, "Duty cycle can't be greater then period\n");
+		return (EINVAL);
+	}
+
+	PWM_LOCK(sc);
+	if (oidp == sc->sc_chanA_oid) {
+		sc->sc_pwm_dutyA = duty;
+		EPWM_WRITE2(sc, EPWM_CMPA, sc->sc_pwm_dutyA);
+	}
+	else {
+		sc->sc_pwm_dutyB = duty;
+		EPWM_WRITE2(sc, EPWM_CMPB, sc->sc_pwm_dutyB);
+	}
+	PWM_UNLOCK(sc);
+
+	return (error);
+}
+
+static int
+am335x_pwm_sysctl_period(SYSCTL_HANDLER_ARGS)
+{
+	struct am335x_pwm_softc *sc = (struct am335x_pwm_softc*)arg1;
+	int error;
+	uint32_t period;
+       
+	period = sc->sc_pwm_period;
+	error = sysctl_handle_int(oidp, &period, 0, req);
+
+	if (error != 0 || req->newptr == NULL)
+		return (error);
+
+	if (period < 1)
+		return (EINVAL);
+
+	if (period > USHRT_MAX)
+		period = USHRT_MAX;
+
+	PWM_LOCK(sc);
+	/* Reset the duty cycle settings. */
+	sc->sc_pwm_dutyA = 0;
+	sc->sc_pwm_dutyB = 0;
+	EPWM_WRITE2(sc, EPWM_CMPA, sc->sc_pwm_dutyA);
+	EPWM_WRITE2(sc, EPWM_CMPB, sc->sc_pwm_dutyB);
+	/* Update the period settings. */
+	sc->sc_pwm_period = period;
+	EPWM_WRITE2(sc, EPWM_TBPRD, period - 1);
+	am335x_pwm_freq(sc);
+	PWM_UNLOCK(sc);
+
+	return (error);
+}
+
+static int
+am335x_pwm_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "ti,am335x-pwm"))
+		return (ENXIO);
+
+	device_set_desc(dev, "AM335x PWM");
+
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+am335x_pwm_attach(device_t dev)
+{
+	struct am335x_pwm_softc *sc;
+	int err;
+	uint32_t reg;
+	phandle_t node;
+	pcell_t did;
+	struct sysctl_ctx_list *ctx;
+	struct sysctl_oid *tree;
+
+	sc = device_get_softc(dev);
+	sc->sc_dev = dev;
+	/* Get the PWM module id */
+	node = ofw_bus_get_node(dev);
+	if ((OF_getprop(node, "pwm-device-id", &did, sizeof(did))) <= 0) {
+		device_printf(dev, "missing pwm-device-id attribute in FDT\n");
+		return (ENXIO);
+	}
+	sc->sc_id = fdt32_to_cpu(did);
+
+	PWM_LOCK_INIT(sc);
+
+	err = bus_alloc_resources(dev, am335x_pwm_mem_spec,
+	    sc->sc_mem_res);
+	if (err) {
+		device_printf(dev, "cannot allocate memory resources\n");
+		goto fail;
+	}
+
+	ti_prcm_clk_enable(PWMSS0_CLK + sc->sc_id);
+	ti_scm_reg_read_4(SCM_PWMSS_CTRL, &reg);
+	reg |= (1 << sc->sc_id);
+	ti_scm_reg_write_4(SCM_PWMSS_CTRL, reg);
+
+	/* Init backlight interface */
+	ctx = device_get_sysctl_ctx(sc->sc_dev);
+	tree = device_get_sysctl_tree(sc->sc_dev);
+
+	sc->sc_clkdiv_oid = SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
+	    "clkdiv", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
+	    am335x_pwm_sysctl_clkdiv, "I", "PWM clock prescaler");
+
+	sc->sc_freq_oid = SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
+	    "freq", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
+	    am335x_pwm_sysctl_freq, "I", "PWM frequency");
+
+	sc->sc_period_oid = SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
+	    "period", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
+	    am335x_pwm_sysctl_period, "I", "PWM period");
+
+	sc->sc_chanA_oid = SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
+	    "dutyA", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
+	    am335x_pwm_sysctl_duty, "I", "Channel A duty cycles");
+
+	sc->sc_chanB_oid = SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
+	    "dutyB", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
+	    am335x_pwm_sysctl_duty, "I", "Channel B duty cycles");
+
+	/* CONFIGURE EPWM1 */
+	reg = EPWM_READ2(sc, EPWM_TBCTL);
+	reg &= ~(TBCTL_CLKDIV_MASK | TBCTL_HSPCLKDIV_MASK);
+	EPWM_WRITE2(sc, EPWM_TBCTL, reg);
+
+	sc->sc_pwm_period = DEFAULT_PWM_PERIOD;
+	sc->sc_pwm_dutyA = 0;
+	sc->sc_pwm_dutyB = 0;
+	am335x_pwm_freq(sc);
+
+	EPWM_WRITE2(sc, EPWM_TBPRD, sc->sc_pwm_period - 1);
+	EPWM_WRITE2(sc, EPWM_CMPA, sc->sc_pwm_dutyA);
+	EPWM_WRITE2(sc, EPWM_CMPB, sc->sc_pwm_dutyB);
+
+	EPWM_WRITE2(sc, EPWM_AQCTLA, (AQCTL_ZRO_SET | AQCTL_CAU_CLEAR));
+	EPWM_WRITE2(sc, EPWM_AQCTLB, (AQCTL_ZRO_SET | AQCTL_CBU_CLEAR));
+
+	/* START EPWM */
+	reg &= ~TBCTL_CTRMODE_MASK;
+	reg |= TBCTL_CTRMODE_UP | TBCTL_FREERUN;
+	EPWM_WRITE2(sc, EPWM_TBCTL, reg);
+
+	EPWM_WRITE2(sc, EPWM_TZCTL, 0xf);
+	reg = EPWM_READ2(sc, EPWM_TZFLG);
+
+	return (0);
+fail:
+	PWM_LOCK_DESTROY(sc);
+	if (sc->sc_mem_res[0])
+		bus_release_resources(dev, am335x_pwm_mem_spec,
+		    sc->sc_mem_res);
+
+	return(ENXIO);
+}
+
+static int
+am335x_pwm_detach(device_t dev)
+{
+	struct am335x_pwm_softc *sc;
+
+	sc = device_get_softc(dev);
+
+	PWM_LOCK(sc);
+	if (sc->sc_mem_res[0])
+		bus_release_resources(dev, am335x_pwm_mem_spec,
+		    sc->sc_mem_res);
+	PWM_UNLOCK(sc);
+
+	PWM_LOCK_DESTROY(sc);
+
+	return (0);
+}
+
+DRIVER_MODULE(am335x_pwm, simplebus, am335x_pwm_driver, am335x_pwm_devclass, 0, 0);
+MODULE_VERSION(am335x_pwm, 1);
+MODULE_DEPEND(am335x_pwm, simplebus, 1, 1, 1);


Property changes on: trunk/sys/arm/ti/am335x/am335x_pwm.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/am335x/am335x_pwm.h
===================================================================
--- trunk/sys/arm/ti/am335x/am335x_pwm.h	                        (rev 0)
+++ trunk/sys/arm/ti/am335x/am335x_pwm.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,34 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Oleksandr Tymoshenko <gonzo at freebsd.org>
+ * 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: stable/10/sys/arm/ti/am335x/am335x_pwm.h 251017 2013-05-27 00:13:27Z gonzo $
+ */
+#ifndef __AM335X_PWM_H__
+#define __AM335X_PWM_H__
+
+int am335x_pwm_config_ecas(int unit, int period, int duty);
+
+#endif /* __AM335X_PWM_H__ */


Property changes on: trunk/sys/arm/ti/am335x/am335x_pwm.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/am335x/am335x_reg.h
===================================================================
--- trunk/sys/arm/ti/am335x/am335x_reg.h	                        (rev 0)
+++ trunk/sys/arm/ti/am335x/am335x_reg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,42 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Damjan Marion <dmarion at Freebsd.org>
+ * 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: stable/10/sys/arm/ti/am335x/am335x_reg.h 239281 2012-08-15 06:31:32Z gonzo $
+ */
+
+#ifndef _AM335X_REG_H_
+#define _AM335X_REG_H_
+
+#define AM335X_L4_WKUP_BASE			0x44C00000
+#define AM335X_L4_WKUP_SIZE			0x400000
+
+#define AM335X_CONTROL_BASE			AM335X_L4_WKUP_BASE + 0x210000
+#define AM335X_CONTROL_SIZE			0x2000
+#define AM335X_CONTROL_DEVICE_ID		0x0600
+#define AM335X_CONTROL_DEV_FEATURE		0x0604
+
+#endif
+


Property changes on: trunk/sys/arm/ti/am335x/am335x_reg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/am335x/am335x_rtc.c
===================================================================
--- trunk/sys/arm/ti/am335x/am335x_rtc.c	                        (rev 0)
+++ trunk/sys/arm/ti/am335x/am335x_rtc.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,212 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2015 Luiz Otavio O Souza <loos at FreeBSD.org>
+ * 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: stable/10/sys/arm/ti/am335x/am335x_rtc.c 279462 2015-03-01 00:57:01Z dim $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/clock.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/rman.h>
+
+#include <machine/bus.h>
+
+#include <dev/ofw/ofw_bus_subr.h>
+#include <arm/ti/ti_prcm.h>
+#include <arm/ti/am335x/am335x_rtcvar.h>
+#include <arm/ti/am335x/am335x_rtcreg.h>
+
+#define	RTC_LOCK(_sc)		mtx_lock(&(_sc)->sc_mtx)
+#define	RTC_UNLOCK(_sc)		mtx_unlock(&(_sc)->sc_mtx)
+#define	RTC_LOCK_INIT(_sc)	mtx_init(&(_sc)->sc_mtx, \
+    device_get_nameunit(_sc->sc_dev), "am335x_rtc", MTX_DEF)
+#define	RTC_LOCK_DESTROY(_sc)	mtx_destroy(&(_sc)->sc_mtx)
+
+#define	RTC_READ4(_sc, reg)		\
+	bus_read_4((_sc)->sc_mem_res, reg)
+#define	RTC_WRITE4(_sc, reg, value)	\
+	bus_write_4((_sc)->sc_mem_res, reg, value)
+
+#define	RTC_MAXIRQS		2
+
+struct am335x_rtc_softc {
+	device_t		sc_dev;
+	struct mtx		sc_mtx;
+	struct resource		*sc_irq_res[RTC_MAXIRQS];
+	struct resource		*sc_mem_res;
+};
+
+static struct am335x_rtc_softc *rtc_sc = NULL;
+static struct resource_spec am335x_rtc_irq_spec[] = {
+	{ SYS_RES_IRQ, 0,  RF_ACTIVE },
+	{ SYS_RES_IRQ, 1,  RF_ACTIVE },
+	{ -1, 0,  0 }
+};
+
+static int
+am335x_rtc_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+	if (!ofw_bus_is_compatible(dev, "ti,da830-rtc"))
+		return (ENXIO);
+	device_set_desc(dev, "AM335x RTC (power management mode)");
+
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+am335x_rtc_attach(device_t dev)
+{
+	int rid;
+	struct am335x_rtc_softc *sc;
+	uint32_t rev;
+
+	if (rtc_sc != NULL)
+		return (ENXIO);
+	rtc_sc = sc = device_get_softc(dev);
+	sc->sc_dev = dev;
+	rid = 0;
+	sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	    RF_ACTIVE);
+	if (!sc->sc_mem_res) {
+		device_printf(dev, "cannot allocate memory resources\n");
+		return (ENXIO);
+	}
+	if (bus_alloc_resources(dev, am335x_rtc_irq_spec, sc->sc_irq_res) != 0) {
+		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
+		device_printf(dev, "cannot allocate irq resources\n");
+		return (ENXIO);
+	}
+	RTC_LOCK_INIT(sc);
+
+	/* Enable the RTC module. */
+	ti_prcm_clk_enable(RTC_CLK);
+	rev = RTC_READ4(sc, RTC_REVISION);
+	device_printf(dev, "AM335X RTC v%d.%d.%d\n",
+            (rev >> 8) & 0x7, (rev >> 6) & 0x3, rev & 0x3f);
+	/* Unlock the RTC. */
+	RTC_WRITE4(sc, RTC_KICK0R, RTC_KICK0R_PASS);
+	RTC_WRITE4(sc, RTC_KICK1R, RTC_KICK1R_PASS);
+	/* Stop the RTC, we don't need it right now. */
+	RTC_WRITE4(sc, RTC_CTRL, 0);
+	/* Disable interrupts. */
+	RTC_WRITE4(sc, RTC_INTR, 0);
+	/* Ack any pending interrupt. */
+	RTC_WRITE4(sc, RTC_STATUS, RTC_STATUS_ALARM2 | RTC_STATUS_ALARM);
+	/* Enable external clock (xtal) and 32 kHz clock. */
+	RTC_WRITE4(sc, RTC_OSC, RTC_OSC_32KCLK_EN | RTC_OSC_32KCLK_SEL);
+	/* Enable pmic_pwr_enable. */
+	RTC_WRITE4(sc, RTC_PMIC, PMIC_PWR_ENABLE);
+
+	return (0);
+}
+
+static int
+am335x_rtc_detach(device_t dev)
+{
+	struct am335x_rtc_softc *sc;
+
+	sc = device_get_softc(dev);
+	if (sc->sc_irq_res[0] != NULL)
+		bus_release_resources(dev, am335x_rtc_irq_spec, sc->sc_irq_res);
+	if (sc->sc_mem_res)
+		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
+	RTC_LOCK_DESTROY(sc);
+
+	return (0);
+}
+
+void
+am335x_rtc_pmic_pwr_toggle(void)
+{
+	int timeout;
+	struct clocktime ct;
+	struct timespec ts;
+
+	/*
+	 * We stop the RTC so we don't need to check the STATUS.BUSY bit
+	 * before update ALARM2 registers.
+	 */
+	timeout = 10;
+	RTC_WRITE4(rtc_sc, RTC_CTRL, 0);
+	while (--timeout && RTC_READ4(rtc_sc, RTC_STATUS) & RTC_STATUS_RUN)
+		DELAY(100);
+	if (timeout == 0) {
+		device_printf(rtc_sc->sc_dev, "RTC does not stop.\n");
+		return;
+	}
+	/* Program the ALARM2 to fire in 2 seconds. */
+	ct.dow = 0;
+	ct.nsec = 0;
+	ct.sec = FROMBCD(RTC_READ4(rtc_sc, RTC_SECONDS) & 0x7f);
+	ct.min = FROMBCD(RTC_READ4(rtc_sc, RTC_MINUTES) & 0x7f);
+	ct.hour = FROMBCD(RTC_READ4(rtc_sc, RTC_HOURS) & 0x3f);
+	ct.day = FROMBCD(RTC_READ4(rtc_sc, RTC_DAYS) & 0x3f);
+	ct.mon = FROMBCD(RTC_READ4(rtc_sc, RTC_MONTHS) & 0x1f);
+	ct.year = FROMBCD(RTC_READ4(rtc_sc, RTC_YEARS) & 0xff);
+	ct.year += POSIX_BASE_YEAR;
+	clock_ct_to_ts(&ct, &ts);
+	ts.tv_sec += 2;
+	clock_ts_to_ct(&ts, &ct);
+	RTC_WRITE4(rtc_sc, RTC_ALARM2_SECONDS, TOBCD(ct.sec));
+	RTC_WRITE4(rtc_sc, RTC_ALARM2_MINUTES, TOBCD(ct.min));
+	RTC_WRITE4(rtc_sc, RTC_ALARM2_HOURS, TOBCD(ct.hour));
+	RTC_WRITE4(rtc_sc, RTC_ALARM2_DAYS, TOBCD(ct.day));
+	RTC_WRITE4(rtc_sc, RTC_ALARM2_MONTHS, TOBCD(ct.mon));
+	RTC_WRITE4(rtc_sc, RTC_ALARM2_YEARS, TOBCD(ct.year - POSIX_BASE_YEAR));
+	/* Enable ALARM2 interrupt. */
+	RTC_WRITE4(rtc_sc, RTC_INTR, RTC_INTR_ALARM2);
+	/* Start count. */
+	RTC_WRITE4(rtc_sc, RTC_CTRL, RTC_CTRL_RUN);
+}
+
+static device_method_t am335x_rtc_methods[] = {
+	DEVMETHOD(device_probe,		am335x_rtc_probe),
+	DEVMETHOD(device_attach,	am335x_rtc_attach),
+	DEVMETHOD(device_detach,	am335x_rtc_detach),
+
+	DEVMETHOD_END
+};
+
+static driver_t am335x_rtc_driver = {
+	"am335x_rtc",
+	am335x_rtc_methods,
+	sizeof(struct am335x_rtc_softc),
+};
+
+static devclass_t am335x_rtc_devclass;
+
+DRIVER_MODULE(am335x_rtc, simplebus, am335x_rtc_driver, am335x_rtc_devclass, 0, 0);
+MODULE_VERSION(am335x_rtc, 1);
+MODULE_DEPEND(am335x_rtc, simplebus, 1, 1, 1);


Property changes on: trunk/sys/arm/ti/am335x/am335x_rtc.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/am335x/am335x_rtcreg.h
===================================================================
--- trunk/sys/arm/ti/am335x/am335x_rtcreg.h	                        (rev 0)
+++ trunk/sys/arm/ti/am335x/am335x_rtcreg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,77 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright 2015 Luiz Otavio O Souza <loos at FreeBSD.org>
+ * 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: stable/10/sys/arm/ti/am335x/am335x_rtcreg.h 278079 2015-02-02 12:48:13Z loos $
+ */
+
+#ifndef _AM335X_RTCREG_H_
+#define _AM335X_RTCREG_H_
+
+#define	RTC_SECONDS		0x00
+#define	RTC_MINUTES		0x04
+#define	RTC_HOURS		0x08
+#define	RTC_DAYS		0x0c
+#define	RTC_MONTHS		0x10
+#define	RTC_YEARS		0x14
+#define	RTC_WEEK		0x18
+#define	RTC_CTRL		0x40
+#define	RTC_CTRL_DISABLE		(1U << 6)
+#define	RTC_CTRL_RUN			(1U << 0)
+#define	RTC_STATUS		0x44
+#define	RTC_STATUS_ALARM2		(1U << 7)
+#define	RTC_STATUS_ALARM		(1U << 6)
+#define	RTC_STATUS_1D_EVENT		(1U << 5)
+#define	RTC_STATUS_1H_EVENT		(1U << 4)
+#define	RTC_STATUS_1M_EVENT		(1U << 3)
+#define	RTC_STATUS_1S_EVENT		(1U << 2)
+#define	RTC_STATUS_RUN			(1U << 1)
+#define	RTC_STATUS_BUSY			(1U << 0)
+#define	RTC_INTR		0x48
+#define	RTC_INTR_ALARM2			(1U << 4)
+#define	RTC_INTR_ALARM			(1U << 3)
+#define	RTC_INTR_TIMER			(1U << 2)
+#define	RTC_OSC			0x54
+#define	RTC_OSC_32KCLK_EN		(1U << 6)
+#define	RTC_OSC_OSC32K_GZ		(1U << 4)
+#define	RTC_OSC_32KCLK_SEL		(1U << 3)
+#define	RTC_OSC_RES_SELECT		(1U << 2)
+#define	RTC_OSC_SW2			(1U << 1)
+#define	RTC_OSC_SW1			(1U << 0)
+#define	RTC_KICK0R		0x6c
+#define	RTC_KICK0R_PASS			0x83e70b13
+#define	RTC_KICK1R		0x70
+#define	RTC_KICK1R_PASS			0x95a4f1e0
+#define	RTC_REVISION		0x74
+#define	RTC_ALARM2_SECONDS	0x80
+#define	RTC_ALARM2_MINUTES	0x84
+#define	RTC_ALARM2_HOURS	0x88
+#define	RTC_ALARM2_DAYS		0x8c
+#define	RTC_ALARM2_MONTHS	0x90
+#define	RTC_ALARM2_YEARS	0x94
+#define	RTC_PMIC		0x98
+#define	PMIC_PWR_ENABLE			(1U << 16)
+
+#endif /* _AM335X_RTCREG_H_ */


Property changes on: trunk/sys/arm/ti/am335x/am335x_rtcreg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/am335x/am335x_rtcvar.h
===================================================================
--- trunk/sys/arm/ti/am335x/am335x_rtcvar.h	                        (rev 0)
+++ trunk/sys/arm/ti/am335x/am335x_rtcvar.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,35 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright 2015 Luiz Otavio O Souza <loos at freebsd.org>
+ * 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: stable/10/sys/arm/ti/am335x/am335x_rtcvar.h 278079 2015-02-02 12:48:13Z loos $
+ */
+
+#ifndef _AM335X_RTCVAR_H_
+#define _AM335X_RTCVAR_H_
+
+void am335x_rtc_pmic_pwr_toggle(void);
+
+#endif /* _AM335X_RTCVAR_H_ */


Property changes on: trunk/sys/arm/ti/am335x/am335x_rtcvar.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/am335x/am335x_scm.h
===================================================================
--- trunk/sys/arm/ti/am335x/am335x_scm.h	                        (rev 0)
+++ trunk/sys/arm/ti/am335x/am335x_scm.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,39 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Oleksandr Tymoshenko <gonzo at freebsd.org>
+ * 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: stable/10/sys/arm/ti/am335x/am335x_scm.h 251016 2013-05-27 00:09:04Z gonzo $
+ */
+#ifndef __AM335X_SCM_H__
+#define __AM335X_SCM_H__
+
+/* AM335x-specific registers for control module (scm) */
+#define	SCM_USB_CTRL0	0x620
+#define	SCM_USB_STS0	0x624
+#define	SCM_USB_CTRL1	0x628
+#define	SCM_USB_STS1	0x62C
+#define	SCM_PWMSS_CTRL	0x664
+
+#endif /* __AM335X_SCM_H__ */


Property changes on: trunk/sys/arm/ti/am335x/am335x_scm.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/am335x/am335x_scm_padconf.c
===================================================================
--- trunk/sys/arm/ti/am335x/am335x_scm_padconf.c	                        (rev 0)
+++ trunk/sys/arm/ti/am335x/am335x_scm_padconf.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,365 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Damjan Marion <dmarion at FreeBSD.org>
+ * 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: stable/10/sys/arm/ti/am335x/am335x_scm_padconf.c 279467 2015-03-01 01:08:14Z dim $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+#include <machine/resource.h>
+#include <machine/intr.h>
+#include <sys/gpio.h>
+
+#include <arm/ti/tivar.h>
+#include <arm/ti/ti_scm.h>
+
+#define _PIN(r, b, gp, gm, m0, m1, m2, m3, m4, m5, m6, m7) \
+	{	.reg_off = r, \
+		.gpio_pin = gp, \
+		.gpio_mode = gm, \
+		.ballname = b, \
+		.muxmodes[0] = m0, \
+		.muxmodes[1] = m1, \
+		.muxmodes[2] = m2, \
+		.muxmodes[3] = m3, \
+		.muxmodes[4] = m4, \
+		.muxmodes[5] = m5, \
+		.muxmodes[6] = m6, \
+		.muxmodes[7] = m7, \
+	}
+
+#define SLEWCTRL	(0x01 << 6) /* faster(0) or slower(1) slew rate. */
+#define RXACTIVE	(0x01 << 5) /* Input enable value for the Pad */
+#define PULLTYPESEL	(0x01 << 4) /* Pad pullup/pulldown type selection */
+#define PULLUDEN	(0x01 << 3) /* Pullup/pulldown disabled */
+
+#define PADCONF_OUTPUT			(0)
+#define PADCONF_OUTPUT_PULLUP		(PULLTYPESEL)
+#define PADCONF_INPUT			(RXACTIVE | PULLUDEN)
+#define PADCONF_INPUT_PULLUP		(RXACTIVE | PULLTYPESEL)
+#define PADCONF_INPUT_PULLDOWN		(RXACTIVE)
+#define PADCONF_INPUT_PULLUP_SLOW	(PADCONF_INPUT_PULLUP | SLEWCTRL)
+
+const struct ti_scm_padstate ti_padstate_devmap[] = {
+	{"output",		PADCONF_OUTPUT },
+	{"output_pullup",	PADCONF_OUTPUT_PULLUP },
+	{"input",		PADCONF_INPUT },
+	{"input_pulldown",	PADCONF_INPUT_PULLDOWN },
+	{"input_pullup",	PADCONF_INPUT_PULLUP },
+	{"i2c",			PADCONF_INPUT_PULLUP_SLOW },
+	{ .state = NULL }
+};
+
+const struct ti_scm_padconf ti_padconf_devmap[] = {
+	_PIN(0x800, "GPMC_AD0",		32, 7,"gpmc_ad0", "mmc1_dat0", NULL, NULL, NULL, NULL, NULL, "gpio1_0"),
+	_PIN(0x804, "GPMC_AD1",		33, 7,"gpmc_ad1", "mmc1_dat1", NULL, NULL, NULL, NULL, NULL, "gpio1_1"),
+	_PIN(0x808, "GPMC_AD2",		34, 7,"gpmc_ad2", "mmc1_dat2", NULL, NULL, NULL, NULL, NULL, "gpio1_2"),
+	_PIN(0x80C, "GPMC_AD3",		35, 7,"gpmc_ad3", "mmc1_dat3", NULL, NULL, NULL, NULL, NULL, "gpio1_3"),
+	_PIN(0x810, "GPMC_AD4",		36, 7,"gpmc_ad4", "mmc1_dat4", NULL, NULL, NULL, NULL, NULL, "gpio1_4"),
+	_PIN(0x814, "GPMC_AD5",		37, 7,"gpmc_ad5", "mmc1_dat5", NULL, NULL, NULL, NULL, NULL, "gpio1_5"),
+	_PIN(0x818, "GPMC_AD6",		38, 7,"gpmc_ad6", "mmc1_dat6", NULL, NULL, NULL, NULL, NULL, "gpio1_6"),
+	_PIN(0x81C, "GPMC_AD7",		39, 7,"gpmc_ad7", "mmc1_dat7", NULL, NULL, NULL, NULL, NULL, "gpio1_7"),
+	_PIN(0x820, "GPMC_AD8",		22, 7, "gpmc_ad8", "lcd_data23", "mmc1_dat0", "mmc2_dat4", "ehrpwm2A", NULL, NULL, "gpio0_22"),
+	_PIN(0x824, "GPMC_AD9",		23, 7, "gpmc_ad9", "lcd_data22", "mmc1_dat1", "mmc2_dat5", "ehrpwm2B", NULL, NULL, "gpio0_23"),
+	_PIN(0x828, "GPMC_AD10",	26, 7, "gpmc_ad10", "lcd_data21", "mmc1_dat2", "mmc2_dat6", "ehrpwm2_tripzone_in", NULL, NULL, "gpio0_26"),
+	_PIN(0x82C, "GPMC_AD11",	27, 7, "gpmc_ad11", "lcd_data20", "mmc1_dat3", "mmc2_dat7", "ehrpwm0_synco", NULL, NULL, "gpio0_27"),
+	_PIN(0x830, "GPMC_AD12",	44, 7, "gpmc_ad12", "lcd_data19", "mmc1_dat4", "mmc2_dat0", "eQEP2A_in", "pr1_mii0_txd2", "pr1_pru0_pru_r30_14", "gpio1_12"),
+	_PIN(0x834, "GPMC_AD13",	45, 7, "gpmc_ad13", "lcd_data18", "mmc1_dat5", "mmc2_dat1", "eQEP2B_in", "pr1_mii0_txd1", "pr1_pru0_pru_r30_15", "gpio1_13"),
+	_PIN(0x838, "GPMC_AD14",	46, 7, "gpmc_ad14", "lcd_data17", "mmc1_dat6", "mmc2_dat2", "eQEP2_index", "pr1_mii0_txd0", "pr1_pru0_pru_r31_14", "gpio1_14"),
+	_PIN(0x83C, "GPMC_AD15",	47, 7, "gpmc_ad15", "lcd_data16", "mmc1_dat7", "mmc2_dat3", "eQEP2_strobe", "pr1_ecap0_ecap_capin_apwm_o", "pr1_pru0_pru_r31_15", "gpio1_15"),
+	_PIN(0x840, "GPMC_A0",		48, 7, "gpmc_a0", "gmii2_txen", "rgmii2_tctl", "rmii2_txen", "gpmc_a16", "pr1_mii_mt1_clk", "ehrpwm1_tripzone_input", "gpio1_16"),
+	_PIN(0x844, "GPMC_A1",		49, 7, "gpmc_a1", "gmii2_rxdv", "rgmii2_rctl", "mmc2_dat0", "gpmc_a17", "pr1_mii1_txd3", "ehrpwm0_synco", "gpio1_17"),
+	_PIN(0x848, "GPMC_A2",		50, 7, "gpmc_a2", "gmii2_txd3", "rgmii2_td3", "mmc2_dat1", "gpmc_a18", "pr1_mii1_txd2", "ehrpwm1A", "gpio1_18"),
+	_PIN(0x84C, "GPMC_A3",		51, 7, "gpmc_a3", "gmii2_txd2", "rgmii2_td2", "mmc2_dat2", "gpmc_a19", "pr1_mii1_txd1", "ehrpwm1B", "gpio1_19"),
+	_PIN(0x850, "GPMC_A4",		52, 7, "gpmc_a4", "gmii2_txd1", "rgmii2_td1", "rmii2_tdx1", "gpmc_a20", "pr1_mii1_txd0", "eQEP1A_in", "gpio1_20"),
+	_PIN(0x854, "GPMC_A5",		53, 7, "gpmc_a5", "gmii2_txd0", "rgmii2_td0", "rmii2_txd0", "gpmc_a21", "pr1_mii1_rxd3", "eQEP1B_in", "gpio1_21"),
+	_PIN(0x858, "GPMC_A6",		54, 7, "gpmc_a6", "gmii2_txclk", "rgmii2_tclk", "mmc2_dat4", "gpmc_a22", "pr1_mii1_rxd2", "eQEP1_index", "gpio1_22"),
+	_PIN(0x85C, "GPMC_A7",		55, 7, "gpmc_a7", "gmii2_rxclk", "rgmii2_rclk", "mmc2_dat5", "gpmc_a23", "pr1_mii1_rxd1", "eQEP1_strobe", "gpio1_23"),
+	_PIN(0x860, "GPMC_A8",		56, 7, "gpmc_a8", "gmii2_rxd3", "rgmii2_rd3", "mmc2_dat6", "gpmc_a24", "pr1_mii1_rxd0", "mcasp0_aclkx", "gpio1_24"),
+	_PIN(0x864, "GPMC_A9",		57, 7, "gmpc_a9", "gmii2_rxd2", "rgmii2_rd2", "mmc2_dat7 / rmii2_crs_dv", "gpmc_a25", "pr1_mii_mr1_clk", "mcasp0_fsx", "gpio1_25"),
+	_PIN(0x868, "GPMC_A10",		58, 7, "gmpc_a10", "gmii2_rxd1", "rgmii2_rd1", "rmii2_rxd1", "gpmc_a26", "pr1_mii1_rxdv", "mcasp0_arx0", "gpio1_26"),
+	_PIN(0x86C, "GPMC_A11",		59, 7, "gmpc_a11", "gmii2_rxd0", "rgmii2_rd0", "rmii2_rxd0", "gpmc_a27", "pr1_mii1_rxer", "mcasp0_axr1", "gpio1_27"),
+	_PIN(0x870, "GPMC_WAIT0",	30, 7, "gpmc_wait0", "gmii2_crs", "gpmc_csn4", "rmii2_crs_dv", "mmc1_sdcd", "pr1_mii1_col", "uart4_rxd", "gpio0_30"),
+	_PIN(0x874, "GPMC_WPn",		31, 7, "gpmc_wpn", "gmii2_rxerr", "gpmc_csn5", "rmii2_rxerr", "mmc2_sdcd", "pr1_mii1_txen", "uart4_txd", "gpio0_31"),
+	_PIN(0x878, "GPMC_BEn1",	60, 7, "gpmc_be1n", "gmii2_col", "gmpc_csn6","mmc2_dat3", "gpmc_dir", "pr1_mii1_rxlink", "mcasp0_aclkr", "gpio1_28"),
+	_PIN(0x87c, "GPMC_CSn0",	61, 7, "gpmc_csn0", NULL, NULL, NULL, NULL, NULL, NULL, "gpio1_29"),
+	_PIN(0x880, "GPMC_CSn1",	62, 7, "gpmc_csn1", "gpmc_clk", "mmc1_clk", "pr1_edio_data_in6", "pr1_edio_data_out6", "pr1_pru1_pru_r30_12", "pr1_pru1_pru_r31_12", "gpio1_30"),
+	_PIN(0x884, "GPMC_CSn2",	63, 7, "gpmc_csn2", "gpmc_be1n", "mmc1_cmd", "pr1_edio_data_in7", "pr1_edio_data_out7", "pr1_pru1_pru_r30_13", "pr1_pru1_pru_r31_13", "gpio1_31"),
+	_PIN(0x888, "GPMC_CSn3",	64, 7, "gpmc_csn3", "gpmc_a3", "rmii2_crs_dv", "mmc2_cmd", "pr1_mii0_crs", "pr1_mdio_data", "EMU4", "gpio2_0"),
+	_PIN(0x88c, "GPMC_CLK",		65, 7, "gpmc_clk", "lcd_memory_clk", "gpmc_wait1", "mmc2_clk", "pr1_mii1_crs", "pr1_mdio_mdclk", "mcasp0_fsr", "gpio2_1"),
+	_PIN(0x890, "GPMC_ADVn_ALE",	66, 7, "gpmc_advn_ale", NULL, "timer4", NULL, NULL, NULL, NULL, "gpio2_2"),
+	_PIN(0x894, "GPMC_OEn_REn",	67, 7, "gpmc_oen_ren", NULL, "timer7", NULL, NULL, NULL, NULL, "gpio2_3"),
+	_PIN(0x898, "GPMC_WEn",		68, 7, "gpmc_wen", NULL, "timer6", NULL, NULL, NULL, NULL, "gpio2_4"),
+	_PIN(0x89c, "GPMC_BEn0_CLE",	67, 7, "gpmc_ben0_cle", NULL, "timer5", NULL, NULL, NULL, NULL, "gpio2_5"),
+	_PIN(0x8a0, "LCD_DATA0",	68, 7, "lcd_data0", "gpmc_a0", "pr1_mii_mt0_clk", "ehrpwm2A", NULL, "pr1_pru1_pru_r30_0", "pr1_pru1_pru_r31_0", "gpio2_6"),
+	_PIN(0x8a4, "LCD_DATA1",	69, 7, "lcd_data1", "gpmc_a1", "pr1_mii0_txen", "ehrpwm2B", NULL, "pr1_pru1_pru_r30_1", "pr1_pru1_pru_r31_1", "gpio2_7"),
+	_PIN(0x8a8, "LCD_DATA2",	70, 7, "lcd_data2", "gpmc_a2", "pr1_mii0_txd3", "ehrpwm2_tripzone_input", NULL, "pr1_pru1_pru_r30_2", "pr1_pru1_pru_r31_2", "gpio2_8"),
+	_PIN(0x8ac, "LCD_DATA3",	71, 7, "lcd_data3", "gpmc_a3", "pr1_mii0_txd2", "ehrpwm0_synco", NULL, "pr1_pru1_pru_r30_3", "pr1_pru1_pru_r31_3", "gpio2_9"),
+	_PIN(0x8b0, "LCD_DATA4",	72, 7, "lcd_data4", "gpmc_a4", "pr1_mii0_txd1", "eQEP2A_in", NULL, "pr1_pru1_pru_r30_4", "pr1_pru1_pru_r31_4", "gpio2_10"),
+	_PIN(0x8b4, "LCD_DATA5",	73, 7, "lcd_data5", "gpmc_a5", "pr1_mii0_txd0", "eQEP2B_in", NULL, "pr1_pru1_pru_r30_5", "pr1_pru1_pru_r31_5", "gpio2_11"),
+	_PIN(0x8b8, "LCD_DATA6",	74, 7, "lcd_data6", "gpmc_a6", "pr1_edio_data_in6", "eQEP2_index", "pr1_edio_data_out6", "pr1_pru1_pru_r30_6", "pr1_pru1_pru_r31_6", "gpio2_12"),
+	_PIN(0x8bc, "LCD_DATA7",	75, 7, "lcd_data7", "gpmc_a7", "pr1_edio_data_in7", "eQEP2_strobe", "pr1_edio_data_out7", "pr1_pru1_pru_r30_7", "pr1_pru1_pru_r31_7", "gpio2_13"),
+	_PIN(0x8c0, "LCD_DATA8",	76, 7, "lcd_data8", "gpmc_a12", "ehrpwm1_tripzone_input", "mcasp0_aclkx", "uart5_txd", "pr1_mii0_rxd3", "uart2_ctsn", "gpio2_14"),
+	_PIN(0x8c4, "LCD_DATA9",	76, 7, "lcd_data9", "gpmc_a13", "ehrpwm0_synco", "mcasp0_fsx", "uart5_rxd", "pr1_mii0_rxd2", "uart2_rtsn", "gpio2_15"),
+	_PIN(0x8c8, "LCD_DATA10",	77, 7, "lcd_data10", "gpmc_a14", "ehrpwm1A", "mcasp0_axr0", NULL, "pr1_mii0_rxd1", "uart3_ctsn", "gpio2_16"),
+	_PIN(0x8cc, "LCD_DATA11",	78, 7, "lcd_data11", "gpmc_a15", "ehrpwm1B", "mcasp0_ahclkr", "mcasp0_axr2", "pr1_mii0_rxd0", "uart3_rtsn", "gpio2_17"),
+	_PIN(0x8d0, "LCD_DATA12",	8, 7, "lcd_data12", "gpmc_a16", "eQEP1A_in", "mcasp0_aclkr", "mcasp0_axr2", "pr1_mii0_rxlink", "uart4_ctsn", "gpio0_8"),
+	_PIN(0x8d4, "LCD_DATA13",	9, 7, "lcd_data13", "gpmc_a17", "eQEP1B_in", "mcasp0_fsr", "mcasp0_axr3", "pr1_mii0_rxer", "uart4_rtsn", "gpio0_9"),
+	_PIN(0x8d8, "LCD_DATA14",	10, 7, "lcd_data14", "gpmc_a18", "eQEP1_index", "mcasp0_axr1", "uart5_rxd", "pr1_mii_mr0_clk", "uart5_ctsn", "gpio0_10"),
+	_PIN(0x8dc, "LCD_DATA15",	11, 7, "lcd_data15", "gpmc_a19", "eQEP1_strobe", "mcasp0_ahclkx", "mcasp0_axr3", "pr1_mii0_rxdv", "uart5_rtsn", "gpio0_11"),
+	_PIN(0x8e0, "LCD_VSYNC",	86, 7, "lcd_vsync", "gpmc_a8", "gpmc_a1", "pr1_edio_data_in2", "pr1_edio_data_out2", "pr1_pru1_pru_r30_8", "pr1_pru1_pru_r31_8", "gpio2_22"),
+	_PIN(0x8e4, "LCD_HSYNC",	87, 7, "lcd_hsync", "gmpc_a9", "gpmc_a2", "pr1_edio_data_in3", "pr1_edio_data_out3", "pr1_pru1_pru_r30_9", "pr1_pru1_pru_r31_9", "gpio2_23"),
+	_PIN(0x8e8, "LCD_PCLK",		88, 7, "lcd_pclk", "gpmc_a10", "pr1_mii0_crs", "pr1_edio_data_in4", "pr1_edio_data_out4", "pr1_pru1_pru_r30_10", "pr1_pru1_pru_r31_10", "gpio2_24"),
+	_PIN(0x8ec, "LCD_AC_BIAS_EN",	89, 7, "lcd_ac_bias_en", "gpmc_a11", "pr1_mii1_crs", "pr1_edio_data_in5", "pr1_edio_data_out5", "pr1_pru1_pru_r30_11", "pr1_pru1_pru_r31_11", "gpio2_25"),
+	_PIN(0x8f0, "MMC0_DAT3",	90, 7, "mmc0_dat3", "gpmc_a20", "uart4_ctsn", "timer5", "uart1_dcdn", "pr1_pru0_pru_r30_8", "pr1_pru0_pru_r31_8", "gpio2_26"),
+	_PIN(0x8f4, "MMC0_DAT2",	91, 7, "mmc0_dat2", "gpmc_a21", "uart4_rtsn", "timer6", "uart1_dsrn", "pr1_pru0_pru_r30_9", "pr1_pru0_pru_r31_9", "gpio2_27"),
+	_PIN(0x8f8, "MMC0_DAT1",	92, 7, "mmc0_dat1", "gpmc_a22", "uart5_ctsn", "uart3_rxd", "uart1_dtrn", "pr1_pru0_pru_r30_10", "pr1_pru0_pru_r31_10", "gpio2_28"),
+	_PIN(0x8fc, "MMC0_DAT0",	93, 7, "mmc0_dat0", "gpmc_a23", "uart5_rtsn", "uart3_txd", "uart1_rin", "pr1_pru0_pru_r30_11", "pr1_pru0_pru_r31_11", "gpio2_29"),
+	_PIN(0x900, "MMC0_CLK",		94, 7, "mmc0_clk", "gpmc_a24", "uart3_ctsn", "uart2_rxd", "dcan1_tx", "pr1_pru0_pru_r30_12", "pr1_pru0_pru_r31_12", "gpio2_30"),
+	_PIN(0x904, "MMC0_CMD",		95, 7, "mmc0_cmd", "gpmc_a25", "uart3_rtsn", "uart2_txd", "dcan1_rx", "pr1_pru0_pru_r30_13", "pr1_pru0_pru_r31_13", "gpio2_31"),
+	_PIN(0x908, "MII1_COL",		96, 7, "gmii1_col", "rmii2_refclk", "spi1_sclk", "uart5_rxd", "mcasp1_axr2", "mmc2_dat3", "mcasp0_axr2", "gpio3_0"),
+	_PIN(0x90c, "MII1_CRS",		97, 7, "gmii1_crs", "rmii1_crs_dv", "spi1_d0", "I2C1_SDA", "mcasp1_aclkx", "uart5_ctsn", "uart2_rxd", "gpio3_1"),
+	_PIN(0x910, "MII1_RX_ER",	98, 7, "gmii1_rxerr", "rmii1_rxerr", "spi1_d1", "I2C1_SCL", "mcasp1_fsx", "uart5_rtsn", "uart2_txd", "gpio3_2"),
+	_PIN(0x914, "MII1_TX_EN",	99, 7, "gmii1_txen", "rmii1_txen", "rgmii1_tctl", "timer4", "mcasp1_axr0", "eQEP0_index", "mmc2_cmd", "gpio3_3"),
+	_PIN(0x918, "MII1_RX_DV",	100, 7, "gmii1_rxdv", "cd_memory_clk", "rgmii1_rctl", "uart5_txd", "mcasp1_aclkx", "mmc2_dat0", "mcasp0_aclkr", "gpio3_4"),
+	_PIN(0x91c, "MII1_TXD3",	16, 7, "gmii1_txd3", "dcan0_tx", "rgmii1_td3", "uart4_rxd", "mcasp1_fsx", "mmc2_dat1", "mcasp0_fsr", "gpio0_16"),
+	_PIN(0x920, "MII1_TXD2",	17, 7, "gmii1_txd2", "dcan0_rx", "rgmii1_td2", "uart4_txd", "mcasp1_axr0", "mmc2_dat2", "mcasp0_ahclkx", "gpio0_17"),
+	_PIN(0x924, "MII1_TXD1",	21, 7, "gmii1_txd1", "rmii1_txd1", "rgmii1_td1", "mcasp1_fsr", "mcasp1_axr1", "eQEP0A_in", "mmc1_cmd", "gpio0_21"),
+	_PIN(0x928, "MII1_TXD0",	28, 7, "gmii1_txd0", "rmii1_txd0", "rgmii1_td0", "mcasp1_axr2", "mcasp1_aclkr", "eQEP0B_in", "mmc1_clk", "gpio0_28"),
+	_PIN(0x92c, "MII1_TX_CLK",	105, 7, "gmii1_txclk", "uart2_rxd", "rgmii1_tclk", "mmc0_dat7", "mmc1_dat0", "uart1_dcdn", "mcasp0_aclkx", "gpio3_9"),
+	_PIN(0x930, "MII1_RX_CLK",	106, 7, "gmii1_rxclk", "uart2_txd", "rgmii1_rclk", "mmc0_dat6", "mmc1_dat1", "uart1_dsrn", "mcasp0_fsx", "gpio3_10"),
+	_PIN(0x934, "MII1_RXD3",	82, 7, "gmii1_rxd3", "uart3_rxd", "rgmii1_rd3", "mmc0_dat5", "mmc1_dat2", "uart1_dtrn", "mcasp0_axr0", "gpio2_18"),
+	_PIN(0x938, "MII1_RXD2",	83, 7, "gmii1_rxd2", "uart3_txd", "rgmii1_rd2", "mmc0_dat4", "mmc1_dat3", "uart1_rin", "mcasp0_axr1", "gpio2_19"),
+	_PIN(0x93c, "MII1_RXD1",	84, 7, "gmii1_rxd1", "rmii1_rxd1", "rgmii1_rd1", "mcasp1_axr3", "mcasp1_fsr", "eQEP0_strobe", "mmc2_clk", "gpio2_20"),
+	_PIN(0x940, "MII1_RXD0",	85, 7, "gmii1_rxd0", "rmii1_rxd0", "rgmii1_rd0", "mcasp1_ahclkx", "mcasp1_ahclkr", "mcasp1_aclkr", "mcasp0_axr3", "gpio2_21"),
+	_PIN(0x944, "RMII1_REF_CLK",	29, 7, "rmii1_refclk", "xdma_event_intr2", "spi1_cs0", "uart5_txd", "mcasp1_axr3", "mmc0_pow", "mcasp1_ahclkx", "gpio0_29"),
+	_PIN(0x948, "MDIO",		0, 7, "mdio_data", "timer6", "uart5_rxd", "uart3_ctsn", "mmc0_sdcd","mmc1_cmd", "mmc2_cmd","gpio0_0"),
+	_PIN(0x94c, "MDC",		1, 7, "mdio_clk", "timer5", "uart5_txd", "uart3_rtsn", "mmc0_sdwp", "mmc1_clk", "mmc2_clk", "gpio0_1"),
+	_PIN(0x950, "SPI0_SCLK",	2, 7, "spi0_sclk", "uart2_rxd", "I2C2_SDA", "ehrpwm0A", "pr1_uart0_cts_n", "pr1_edio_sof", "EMU2", "gpio0_2"),
+	_PIN(0x954, "SPI0_D0",		3, 7, "spi0_d0", "uart2_txd", "I2C2_SCL", "ehrpwm0B", "pr1_uart0_rts_n", "pr1_edio_latch_in", "EMU3", "gpio0_3"),
+	_PIN(0x958, "SPI0_D1",		4, 7, "spi0_d1", "mmc1_sdwp", "I2C1_SDA", "ehrpwm0_tripzone_input", "pr1_uart0_rxd", "pr1_edio_data_in0", "pr1_edio_data_out0", "gpio0_4"),
+	_PIN(0x95c, "SPI0_CS0",		5, 7, "spi0_cs0", "mmc2_sdwp", "I2C1_SCL", "ehrpwm0_synci", "pr1_uart0_txd", "pr1_edio_data_in1", "pr1_edio_data_out1", "gpio0_5"),
+	_PIN(0x960, "SPI0_CS1",		6, 7, "spi0_cs1", "uart3_rxd", "eCAP1_in_PWM1_out", "mcc0_pow", "xdm_event_intr2", "mmc0_sdcd", "EMU4", "gpio0_6"),
+	_PIN(0x964, "ECAP0_IN_PWM0_OUT",7, 7, "eCAP0_in_PWM0_out", "uart3_txd", "spi1_cs1", "pr1_ecap0_ecap_capin_apwm_o", "spi1_sclk", "mmc0_sdwp", "xdma_event_intr2", "gpio0_7"),
+	_PIN(0x968, "UART0_CTSn",	40, 7, "uart0_ctsn", "uart4_rxd", "dcan1_tx", "I2C1_SDA", "spi1_d0", "timer7", "pr1_edc_sync0_out", "gpio1_8"),
+	_PIN(0x96c, "UART0_RTSn",	41, 7, "uart0_rtsn", "uart4_txd", "dcan1_rx", "I2C1_SCL", "spi1_d1", "spi1_cs0", "pr1_edc_sync1_out", "gpio1_9"),
+	_PIN(0x970, "UART0_rxd",	42, 7, "uart0_rxd", "spi1_cs0", "dcan0_tx", "I2C2_SDA", "eCAP2_in_PWM2_out", "pr1_pru1_pru_r30_14", "pr1_pru1_pru_r31_14", "gpio1_10"),
+	_PIN(0x974, "UART0_txd",	43, 7, "uart0_txd", "spi1_cs1", "dcan0_rx", "I2C2_SCL", "eCAP1_in_PWM1_out", "pr1_pru1_pru_r30_15", "pr1_pru1_pru_r31_15", "gpio1_11"),
+	_PIN(0x978, "UART1_CTSn",	12, 7, "uart1_ctsn", "timer6_mux1", "dcan0_tx", "I2C2_SDA", "spi1_cs0", "pr1_uart0_cts_n", "pr1_edc_latch0_in", "gpio0_12"),
+	_PIN(0x97c, "UART1_RTSn",	13, 7, "uart1_rtsn", "timer5_mux1", "dcan0_rx", "I2C2_SCL", "spi1_cs1", "pr1_uart0_rts_n", "pr1_edc_latch1_in", "gpio0_13"),
+	_PIN(0x980, "UART1_RXD",	14, 7, "uart1_rxd", "mmc1_sdwp", "dcan1_tx", "I2C1_SDA", NULL, "pr1_uart0_rxd", "pr1_pru1_pru_r31_16", "gpio0_14"),
+	_PIN(0x984, "UART1_TXD",	15, 7, "uart1_txd", "mmc2_sdwp", "dcan1_rx", "I2C1_SCL", NULL, "pr1_uart0_txd", "pr1_pru0_pru_r31_16", "gpio0_15"),
+	_PIN(0x988, "I2C0_SDA",		101, 7, "I2C0_SDA", "timer4", "uart2_ctsn", "eCAP2_in_PWM2_out", NULL, NULL, NULL, "gpio3_5"),
+	_PIN(0x98c, "I2C0_SCL",		102, 7, "I2C0_SCL", "timer7", "uart2_rtsn", "eCAP1_in_PWM1_out", NULL, NULL, NULL, "gpio3_6"),
+	_PIN(0x990, "MCASP0_ACLKX",	110, 7, "mcasp0_aclkx", "ehrpwm0A", NULL, "spi1_sclk", "mmc0_sdcd", "pr1_pru0_pru_r30_0", "pr1_pru0_pru_r31_0", "gpio3_14"),
+	_PIN(0x994, "MCASP0_FSX",	111, 7, "mcasp0_fsx", "ehrpwm0B", NULL, "spi1_d0", "mmc1_sdcd", "pr1_pru0_pru_r30_1", "pr1_pru0_pru_r31_1", "gpio3_15"),
+	_PIN(0x998, "MCASP0_AXR0",	112, 7, "mcasp0_axr0", "ehrpwm0_tripzone_input", NULL, "spi1_d1", "mmc2_sdcd", "pr1_pru0_pru_r30_2", "pr1_pru0_pru_r31_2", "gpio3_16"),
+	_PIN(0x99c, "MCASP0_AHCLKR",	113, 7, "mcasp0_ahclkr", "ehrpwm0_synci", "mcasp0_axr2", "spi1_cs0", "eCAP2_in_PWM2_out", "pr1_pru0_pru_r30_3", "pr1_pru0_pru_r31_3", "gpio3_17"),
+	_PIN(0x9a0, "MCASP0_ACLKR",	114, 7, "mcasp0_aclkr", "eQEP0A_in", "mcasp0_axr2", "mcasp1_aclkx", "mmc0_sdwp", "pr1_pru0_pru_r30_4", "pr1_pru0_pru_r31_4", "gpio3_18"),
+	_PIN(0x9a4, "MCASP0_FSR",	115, 7, "mcasp0_fsr", "eQEP0B_in", "mcasp0_axr3", "mcasp1_fsx", "EMU2", "pr1_pru0_pru_r30_5", "pr1_pru0_pru_r31_5", "gpio3_19"),
+	_PIN(0x9a8, "MCASP0_AXR1",	116, 7, "mcasp0_axr1", "eQEP0_index", NULL, "mcasp1_axr0", "EMU3", "pr1_pru0_pru_r30_6", "pr1_pru0_pru_r31_6", "gpio3_20"),
+	_PIN(0x9ac, "MCASP0_AHCLKX",	117, 7, "mcasp0_ahclkx", "eQEP0_strobe", "mcasp0_axr3", "mcasp1_axr1", "EMU4", "pr1_pru0_pru_r30_7", "pr1_pru0_pru_r31_7", "gpio3_21"),
+	_PIN(0x9b0, "XDMA_EVENT_INTR0",	19, 7, "xdma_event_intr0", NULL, "timer4", "clkout1", "spi1_cs1", "pr1_pru1_pru_r31_16", "EMU2", "gpio0_19"),
+	_PIN(0x9b4, "XDMA_EVENT_INTR1",	20, 7, "xdma_event_intr1", NULL, "tclkin", "clkout2", "timer7", "pr1_pru0_pru_r31_16", "EMU3", "gpio0_20"),
+#if 0
+	_PIN(0x9b8, "nresetin_out",	0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0x9bc, "porz",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0x9c0, "nnmi",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0x9c4, "osc0_in",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0x9c8, "osc0_out",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0x9cc, "osc0_vss",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0x9d0, "tms",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0x9d4, "tdi",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0x9d8, "tdo",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0x9dc, "tck",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0x9e0, "ntrst",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+#endif
+	_PIN(0x9e4, "EMU0",		103, 7, "EMU0", NULL, NULL, NULL, NULL, NULL, NULL, "gpio3_7"),
+	_PIN(0x9e8, "EMU1",		104, 0, "EMU1", NULL, NULL, NULL, NULL, NULL, NULL, "gpio3_8"),
+#if 0
+	_PIN(0x9ec, "osc1_in",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0x9f0, "osc1_out",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0x9f4, "osc1_vss",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0x9f8, "rtc_porz",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0x9fc, "pmic_power_en",	0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xa00, "ext_wakeup",	0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xa04, "enz_kaldo_1p8v",	0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+#endif
+	_PIN(0xa08, "USB0_DM",		0, 0, "USB0_DM", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xa0c, "USB0_DP",		0, 0, "USB0_DP", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xa10, "USB0_CE",		0, 0, "USB0_CE", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xa14, "USB0_ID",		0, 0, "USB0_ID", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xa18, "USB0_VBUS",	0, 0, "USB0_VBUS", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xa1c, "USB0_DRVVBUS",	18, 7, "USB0_DRVVBUS", NULL, NULL, NULL, NULL, NULL, NULL, "gpio0_18"),
+	_PIN(0xa20, "USB1_DM",		0, 0, "USB1_DM", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xa24, "USB1_DP",		0, 0, "USB1_DP", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xa28, "USB1_CE",		0, 0, "USB1_CE", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xa2c, "USB1_ID",		0, 0, "USB1_ID", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xa30, "USB1_VBUS",	0, 0, "USB1_VBUS", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xa34, "USB1_DRVVBUS",	109, 7, "USB1_DRVVBUS", NULL, NULL, NULL, NULL, NULL, NULL, "gpio3_13"),
+#if 0
+	_PIN(0xa38, "ddr_resetn",	0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xa3c, "ddr_csn0",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xa40, "ddr_cke",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xa44, "ddr_ck",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xa48, "ddr_nck",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xa4c, "ddr_casn",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xa50, "ddr_rasn",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xa54, "ddr_wen",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xa58, "ddr_ba0",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xa5c, "ddr_ba1",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xa60, "ddr_ba2",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xa64, "ddr_a0",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xa68, "ddr_a1",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xa6c, "ddr_a2",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xa70, "ddr_a3",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xa74, "ddr_a4",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xa78, "ddr_a5",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xa7c, "ddr_a6",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xa80, "ddr_a7",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xa84, "ddr_a8",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xa88, "ddr_a9",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xa8c, "ddr_a10",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xa90, "ddr_a11",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xa94, "ddr_a12",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xa98, "ddr_a13",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xa9c, "ddr_a14",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xaa0, "ddr_a15",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xaa4, "ddr_odt",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xaa8, "ddr_d0",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xaac, "ddr_d1",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xab0, "ddr_d2",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xab4, "ddr_d3",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xab8, "ddr_d4",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xabc, "ddr_d5",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xac0, "ddr_d6",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xac4, "ddr_d7",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xac8, "ddr_d8",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xacc, "ddr_d9",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xad0, "ddr_d10",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xad4, "ddr_d11",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xad8, "ddr_d12",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xadc, "ddr_d13",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xae0, "ddr_d14",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xae4, "ddr_d15",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xae8, "ddr_dqm0",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xaec, "ddr_dqm1",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xaf0, "ddr_dqs0",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xaf4, "ddr_dqsn0",	0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xaf8, "ddr_dqs1",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xafc, "ddr_dqsn1",	0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xb00, "ddr_vref",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xb04, "ddr_vtp",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xb08, "ddr_strben0",	0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xb0c, "ddr_strben1",	0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xb2c, "ain0",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xb28, "ain1",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xb24, "ain2",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xb20, "ain3",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xb1c, "ain4",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xb18, "ain5",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xb14, "ain6",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xb10, "ain7",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xb30, "vrefp",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xb34, "vrefn",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xb38, "avdd",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xb3c, "avss",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xb40, "iforce",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xb44, "vsense",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PIN(0xb48, "testout",		0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+#endif
+	{  .ballname = NULL  },
+};
+
+const struct ti_scm_device ti_scm_dev = {
+	.padconf_muxmode_mask	= 0x7,
+	.padconf_sate_mask	= 0x78,
+	.padstate		= ti_padstate_devmap,
+	.padconf		= ti_padconf_devmap,
+};
+
+int
+ti_scm_padconf_set_gpioflags(uint32_t gpio, uint32_t flags)
+{
+	unsigned int state = 0;
+	if (flags & GPIO_PIN_OUTPUT) {
+		if (flags & GPIO_PIN_PULLUP)
+			state = PADCONF_OUTPUT_PULLUP;
+		else
+			state = PADCONF_OUTPUT;
+	} else if (flags & GPIO_PIN_INPUT) {
+		if (flags & GPIO_PIN_PULLUP)
+			state = PADCONF_INPUT_PULLUP;
+		else if (flags & GPIO_PIN_PULLDOWN)
+			state = PADCONF_INPUT_PULLDOWN;
+		else
+			state = PADCONF_INPUT;
+	}
+	return ti_scm_padconf_set_gpiomode(gpio, state);
+}
+
+void
+ti_scm_padconf_get_gpioflags(uint32_t gpio, uint32_t *flags)
+{
+	unsigned int state;
+	if (ti_scm_padconf_get_gpiomode(gpio, &state) != 0)
+		*flags = 0;
+	else {
+		switch (state) {
+			case PADCONF_OUTPUT:
+				*flags = GPIO_PIN_OUTPUT;
+				break;
+			case PADCONF_OUTPUT_PULLUP:
+				*flags = GPIO_PIN_OUTPUT | GPIO_PIN_PULLUP;
+				break;
+			case PADCONF_INPUT:
+				*flags = GPIO_PIN_INPUT;
+				break;
+			case PADCONF_INPUT_PULLUP:
+				*flags = GPIO_PIN_INPUT | GPIO_PIN_PULLUP;
+				break;
+			case PADCONF_INPUT_PULLDOWN:
+				*flags = GPIO_PIN_INPUT | GPIO_PIN_PULLDOWN;
+				break;
+			default:
+				*flags = 0;
+				break;
+		}
+	}
+}
+


Property changes on: trunk/sys/arm/ti/am335x/am335x_scm_padconf.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/am335x/am335x_usbss.c
===================================================================
--- trunk/sys/arm/ti/am335x/am335x_usbss.c	                        (rev 0)
+++ trunk/sys/arm/ti/am335x/am335x_usbss.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,496 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Oleksandr Tymoshenko <gonzo at freebsd.org>
+ *
+ * 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: stable/10/sys/arm/ti/am335x/am335x_usbss.c 278278 2015-02-05 20:03:02Z hselasky $");
+
+#include <sys/stdint.h>
+#include <sys/stddef.h>
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/types.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/bus.h>
+#include <sys/module.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/condvar.h>
+#include <sys/sysctl.h>
+#include <sys/sx.h>
+#include <sys/unistd.h>
+#include <sys/callout.h>
+#include <sys/malloc.h>
+#include <sys/priv.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <dev/usb/usb.h>
+#include <dev/usb/usbdi.h>
+
+#include <dev/usb/usb_core.h>
+#include <dev/usb/usb_busdma.h>
+#include <dev/usb/usb_process.h>
+#include <dev/usb/usb_util.h>
+
+#define	USB_DEBUG_VAR usbssdebug
+
+#include <dev/usb/usb_controller.h>
+#include <dev/usb/usb_bus.h>
+#include <dev/usb/controller/musb_otg.h>
+#include <dev/usb/usb_debug.h>
+
+#include <sys/rman.h>
+
+#include <arm/ti/ti_prcm.h>
+#include <arm/ti/ti_scm.h>
+#include <arm/ti/am335x/am335x_scm.h>
+
+#define	AM335X_USB_PORTS	2
+
+#define	USBSS_REVREG		0x00
+#define	USBSS_SYSCONFIG		0x10
+#define		USBSS_SYSCONFIG_SRESET		1
+
+#define USBCTRL_REV		0x00
+#define USBCTRL_CTRL		0x14
+#define USBCTRL_STAT		0x18
+#define USBCTRL_IRQ_STAT0	0x30
+#define		IRQ_STAT0_RXSHIFT	16
+#define		IRQ_STAT0_TXSHIFT	0
+#define USBCTRL_IRQ_STAT1	0x34
+#define 	IRQ_STAT1_DRVVBUS	(1 << 8)
+#define USBCTRL_INTEN_SET0	0x38
+#define USBCTRL_INTEN_SET1	0x3C
+#define 	USBCTRL_INTEN_USB_ALL	0x1ff
+#define 	USBCTRL_INTEN_USB_SOF	(1 << 3)
+#define USBCTRL_INTEN_CLR0	0x40
+#define USBCTRL_INTEN_CLR1	0x44
+#define USBCTRL_UTMI		0xE0
+#define		USBCTRL_UTMI_FSDATAEXT		(1 << 1)
+#define USBCTRL_MODE		0xE8
+#define 	USBCTRL_MODE_IDDIG		(1 << 8)
+#define 	USBCTRL_MODE_IDDIGMUX		(1 << 7)
+
+/* USBSS resource + 2 MUSB ports */
+
+#define RES_USBSS	0
+#define RES_USBCTRL(i)	(3*i+1)
+#define RES_USBPHY(i)	(3*i+2)
+#define RES_USBCORE(i)	(3*i+3)
+
+#define	USB_WRITE4(sc, idx, reg, val)	do {		\
+	bus_write_4((sc)->sc_mem_res[idx], (reg), (val));	\
+} while (0)
+
+#define	USB_READ4(sc, idx, reg) bus_read_4((sc)->sc_mem_res[idx], (reg))
+
+#define	USBSS_WRITE4(sc, reg, val)		\
+    USB_WRITE4((sc), RES_USBSS, (reg), (val))
+#define	USBSS_READ4(sc, reg)			\
+    USB_READ4((sc), RES_USBSS, (reg))
+#define	USBCTRL_WRITE4(sc, unit, reg, val)	\
+    USB_WRITE4((sc), RES_USBCTRL(unit), (reg), (val))
+#define	USBCTRL_READ4(sc, unit, reg)		\
+    USB_READ4((sc), RES_USBCTRL(unit), (reg))
+#define	USBPHY_WRITE4(sc, unit, reg, val)	\
+    USB_WRITE4((sc), RES_USBPHY(unit), (reg), (val))
+#define	USBPHY_READ4(sc, unit, reg)		\
+    USB_READ4((sc), RES_USBPHY(unit), (reg))
+
+static struct resource_spec am335x_musbotg_mem_spec[] = {
+	{ SYS_RES_MEMORY,   0,  RF_ACTIVE },
+	{ SYS_RES_MEMORY,   1,  RF_ACTIVE },
+	{ SYS_RES_MEMORY,   2,  RF_ACTIVE },
+	{ SYS_RES_MEMORY,   3,  RF_ACTIVE },
+	{ SYS_RES_MEMORY,   4,  RF_ACTIVE },
+	{ SYS_RES_MEMORY,   5,  RF_ACTIVE },
+	{ SYS_RES_MEMORY,   6,  RF_ACTIVE },
+	{ -1,               0,  0 }
+};
+
+static struct resource_spec am335x_musbotg_irq_spec[] = {
+	{ SYS_RES_IRQ,      0,  RF_ACTIVE },
+	{ SYS_RES_IRQ,      1,  RF_ACTIVE },
+	{ SYS_RES_IRQ,      2,  RF_ACTIVE },
+	{ -1,               0,  0 }
+};
+
+#ifdef USB_DEBUG
+static int usbssdebug = 0;
+
+static SYSCTL_NODE(_hw_usb, OID_AUTO, am335x_usbss, CTLFLAG_RW, 0, "AM335x USBSS");
+SYSCTL_INT(_hw_usb_am335x_usbss, OID_AUTO, debug, CTLFLAG_RW,
+    &usbssdebug, 0, "Debug level");
+#endif
+
+static device_probe_t musbotg_probe;
+static device_attach_t musbotg_attach;
+static device_detach_t musbotg_detach;
+
+struct musbotg_super_softc {
+	struct musbotg_softc	sc_otg[AM335X_USB_PORTS];
+	struct resource		*sc_mem_res[AM335X_USB_PORTS*3+1];
+	struct resource		*sc_irq_res[AM335X_USB_PORTS+1];
+	void			*sc_intr_hdl;
+};
+
+static void
+musbotg_vbus_poll(struct musbotg_super_softc *sc, int port)
+{
+	uint32_t stat;
+
+	if (sc->sc_otg[port].sc_mode == MUSB2_DEVICE_MODE)
+		musbotg_vbus_interrupt(&sc->sc_otg[port], 1);
+	else {
+		stat = USBCTRL_READ4(sc, port, USBCTRL_STAT);
+		musbotg_vbus_interrupt(&sc->sc_otg[port], stat & 1);
+	}
+}
+
+/*
+ * Arg to musbotg_clocks_on and musbot_clocks_off is
+ * a uint32_t * pointing to the SCM register offset.
+ */
+static uint32_t USB_CTRL[] = {SCM_USB_CTRL0, SCM_USB_CTRL1};
+
+static void
+musbotg_clocks_on(void *arg)
+{
+	uint32_t c, reg = *(uint32_t *)arg;
+
+	ti_scm_reg_read_4(reg, &c);
+	c &= ~3; /* Enable power */
+	c |= 1 << 19; /* VBUS detect enable */
+	c |= 1 << 20; /* Session end enable */
+	ti_scm_reg_write_4(reg, c);
+}
+
+static void
+musbotg_clocks_off(void *arg)
+{
+	uint32_t c, reg = *(uint32_t *)arg;
+
+	/* Disable power to PHY */
+	ti_scm_reg_read_4(reg, &c);
+	ti_scm_reg_write_4(reg, c | 3);
+}
+
+static void
+musbotg_ep_int_set(struct musbotg_softc *sc, int ep, int on)
+{
+	struct musbotg_super_softc *ssc = sc->sc_platform_data;
+	uint32_t epmask;
+
+	epmask = ((1 << ep) << IRQ_STAT0_RXSHIFT);
+	epmask |= ((1 << ep) << IRQ_STAT0_TXSHIFT);
+	if (on)
+		USBCTRL_WRITE4(ssc, sc->sc_id,
+		    USBCTRL_INTEN_SET0, epmask);
+	else
+		USBCTRL_WRITE4(ssc, sc->sc_id,
+		    USBCTRL_INTEN_CLR0, epmask);
+}
+
+static void
+musbotg_usbss_interrupt(void *arg)
+{
+	panic("USBSS real interrupt");
+}
+
+static void
+musbotg_wrapper_interrupt(void *arg)
+{
+	struct musbotg_softc *sc = arg;
+	struct musbotg_super_softc *ssc = sc->sc_platform_data;
+	uint32_t stat, stat0, stat1;
+	stat = USBCTRL_READ4(ssc, sc->sc_id, USBCTRL_STAT);
+	stat0 = USBCTRL_READ4(ssc, sc->sc_id, USBCTRL_IRQ_STAT0);
+	stat1 = USBCTRL_READ4(ssc, sc->sc_id, USBCTRL_IRQ_STAT1);
+	if (stat0)
+		USBCTRL_WRITE4(ssc, sc->sc_id, USBCTRL_IRQ_STAT0, stat0);
+	if (stat1)
+		USBCTRL_WRITE4(ssc, sc->sc_id, USBCTRL_IRQ_STAT1, stat1);
+
+	DPRINTFN(4, "port%d: stat0=%08x stat1=%08x, stat=%08x\n",
+	    sc->sc_id, stat0, stat1, stat);
+
+	if (stat1 & IRQ_STAT1_DRVVBUS)
+		musbotg_vbus_interrupt(sc, stat & 1);
+
+	musbotg_interrupt(arg, ((stat0 >> 16) & 0xffff),
+	    stat0 & 0xffff, stat1 & 0xff);
+}
+
+static int
+musbotg_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "ti,musb-am33xx"))
+		return (ENXIO);
+
+	device_set_desc(dev, "TI AM33xx integrated USB OTG controller");
+	
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+musbotg_attach(device_t dev)
+{
+	struct musbotg_super_softc *sc = device_get_softc(dev);
+	int err;
+	int i;
+	uint32_t rev, reg;
+
+	/* Request the memory resources */
+	err = bus_alloc_resources(dev, am335x_musbotg_mem_spec,
+		sc->sc_mem_res);
+	if (err) {
+		device_printf(dev,
+		    "Error: could not allocate mem resources\n");
+		return (ENXIO);
+	}
+
+	/* Request the IRQ resources */
+	err = bus_alloc_resources(dev, am335x_musbotg_irq_spec,
+		sc->sc_irq_res);
+	if (err) {
+		device_printf(dev,
+		    "Error: could not allocate irq resources\n");
+		return (ENXIO);
+	}
+
+	/* Enable device clocks. */
+	ti_prcm_clk_enable(MUSB0_CLK);
+
+	/*
+	 * Reset USBSS, USB0 and USB1.
+	 * The registers of USB subsystem must not be accessed while the
+	 * reset pulse is active (200ns).
+	 */
+	USBSS_WRITE4(sc, USBSS_SYSCONFIG, USBSS_SYSCONFIG_SRESET);
+	DELAY(100);
+	i = 10;
+	while (USBSS_READ4(sc, USBSS_SYSCONFIG) & USBSS_SYSCONFIG_SRESET) {
+		DELAY(100);
+		if (i-- == 0) {
+			device_printf(dev, "reset timeout.\n");
+			return (ENXIO);
+		}
+	}
+
+	/* Read the module revision. */
+	rev = USBSS_READ4(sc, USBSS_REVREG);
+	device_printf(dev, "TI AM335X USBSS v%d.%d.%d\n",
+	    (rev >> 8) & 7, (rev >> 6) & 3, rev & 63);
+
+	err = bus_setup_intr(dev, sc->sc_irq_res[0],
+	    INTR_TYPE_BIO | INTR_MPSAFE,
+	    NULL, (driver_intr_t *)musbotg_usbss_interrupt, sc,
+	    &sc->sc_intr_hdl);
+	
+	if (err) {
+		sc->sc_intr_hdl = NULL;
+	    	device_printf(dev, "Failed to setup USBSS interrupt\n");
+		goto error;
+	}
+
+	for (i = 0; i < AM335X_USB_PORTS; i++) {
+		/* setup MUSB OTG USB controller interface softc */
+		sc->sc_otg[i].sc_clocks_on = &musbotg_clocks_on;
+		sc->sc_otg[i].sc_clocks_off = &musbotg_clocks_off;
+		sc->sc_otg[i].sc_clocks_arg = &USB_CTRL[i];
+
+		sc->sc_otg[i].sc_ep_int_set = musbotg_ep_int_set;
+
+		/* initialise some bus fields */
+		sc->sc_otg[i].sc_bus.parent = dev;
+		sc->sc_otg[i].sc_bus.devices = sc->sc_otg[i].sc_devices;
+		sc->sc_otg[i].sc_bus.devices_max = MUSB2_MAX_DEVICES;
+		sc->sc_otg[i].sc_bus.dma_bits = 32;
+
+		/* get all DMA memory */
+		if (usb_bus_mem_alloc_all(&sc->sc_otg[i].sc_bus,
+		    USB_GET_DMA_TAG(dev), NULL)) {
+		    	device_printf(dev,
+			    "Failed allocate bus mem for musb%d\n", i);
+			return (ENOMEM);
+		}
+		sc->sc_otg[i].sc_io_res = sc->sc_mem_res[RES_USBCORE(i)];
+		sc->sc_otg[i].sc_io_tag =
+		    rman_get_bustag(sc->sc_otg[i].sc_io_res);
+		sc->sc_otg[i].sc_io_hdl =
+		    rman_get_bushandle(sc->sc_otg[i].sc_io_res);
+		sc->sc_otg[i].sc_io_size =
+		    rman_get_size(sc->sc_otg[i].sc_io_res);
+
+		sc->sc_otg[i].sc_irq_res = sc->sc_irq_res[i+1];
+
+		sc->sc_otg[i].sc_bus.bdev = device_add_child(dev, "usbus", -1);
+		if (!(sc->sc_otg[i].sc_bus.bdev)) {
+		    	device_printf(dev, "No busdev for musb%d\n", i);
+			goto error;
+		}
+		device_set_ivars(sc->sc_otg[i].sc_bus.bdev,
+		    &sc->sc_otg[i].sc_bus);
+
+		err = bus_setup_intr(dev, sc->sc_otg[i].sc_irq_res,
+		    INTR_TYPE_BIO | INTR_MPSAFE,
+		    NULL, (driver_intr_t *)musbotg_wrapper_interrupt,
+		    &sc->sc_otg[i], &sc->sc_otg[i].sc_intr_hdl);
+		if (err) {
+			sc->sc_otg[i].sc_intr_hdl = NULL;
+		    	device_printf(dev,
+			    "Failed to setup interrupt for musb%d\n", i);
+			goto error;
+		}
+
+		sc->sc_otg[i].sc_id = i;
+		sc->sc_otg[i].sc_platform_data = sc;
+		if (i == 0)
+			sc->sc_otg[i].sc_mode = MUSB2_DEVICE_MODE;
+		else
+			sc->sc_otg[i].sc_mode = MUSB2_HOST_MODE;
+
+		/*
+		 * software-controlled function
+		 */
+		
+		if (sc->sc_otg[i].sc_mode == MUSB2_HOST_MODE) {
+			reg = USBCTRL_READ4(sc, i, USBCTRL_MODE);
+			reg |= USBCTRL_MODE_IDDIGMUX;
+			reg &= ~USBCTRL_MODE_IDDIG;
+			USBCTRL_WRITE4(sc, i, USBCTRL_MODE, reg);
+			USBCTRL_WRITE4(sc, i, USBCTRL_UTMI,
+			    USBCTRL_UTMI_FSDATAEXT);
+		} else {
+			reg = USBCTRL_READ4(sc, i, USBCTRL_MODE);
+			reg |= USBCTRL_MODE_IDDIGMUX;
+			reg |= USBCTRL_MODE_IDDIG;
+			USBCTRL_WRITE4(sc, i, USBCTRL_MODE, reg);
+		}
+
+		reg = USBCTRL_INTEN_USB_ALL & ~USBCTRL_INTEN_USB_SOF;
+		USBCTRL_WRITE4(sc, i, USBCTRL_INTEN_SET1, reg);
+		USBCTRL_WRITE4(sc, i, USBCTRL_INTEN_CLR0, 0xffffffff);
+
+		err = musbotg_init(&sc->sc_otg[i]);
+		if (!err)
+			err = device_probe_and_attach(sc->sc_otg[i].sc_bus.bdev);
+
+		if (err)
+			goto error;
+
+		/* poll VBUS one time */
+		musbotg_vbus_poll(sc, i);
+	}
+
+	return (0);
+
+error:
+	musbotg_detach(dev);
+	return (ENXIO);
+}
+
+static int
+musbotg_detach(device_t dev)
+{
+	struct musbotg_super_softc *sc = device_get_softc(dev);
+	device_t bdev;
+	int err;
+	int i;
+
+	for (i = 0; i < AM335X_USB_PORTS; i++) {
+		if (sc->sc_otg[i].sc_bus.bdev) {
+			bdev = sc->sc_otg[i].sc_bus.bdev;
+			device_detach(bdev);
+			device_delete_child(dev, bdev);
+		}
+
+		if (sc->sc_otg[i].sc_irq_res && sc->sc_otg[i].sc_intr_hdl) {
+			/*
+			 * only call musbotg_uninit() after musbotg_init()
+			 */
+			musbotg_uninit(&sc->sc_otg[i]);
+
+			err = bus_teardown_intr(dev, sc->sc_otg[i].sc_irq_res,
+			    sc->sc_otg[i].sc_intr_hdl);
+			sc->sc_otg[i].sc_intr_hdl = NULL;
+		}
+
+		usb_bus_mem_free_all(&sc->sc_otg[i].sc_bus, NULL);
+	}
+
+	if (sc->sc_intr_hdl) {
+	 	bus_teardown_intr(dev, sc->sc_irq_res[0],
+		    sc->sc_intr_hdl);
+		sc->sc_intr_hdl = NULL;
+	}
+
+
+	/* Free resources if any */
+	if (sc->sc_mem_res[0])
+		bus_release_resources(dev, am335x_musbotg_mem_spec,
+		    sc->sc_mem_res);
+
+	if (sc->sc_irq_res[0])
+		bus_release_resources(dev, am335x_musbotg_irq_spec,
+		    sc->sc_irq_res);
+
+	/* during module unload there are lots of children leftover */
+	device_delete_children(dev);
+
+	return (0);
+}
+
+static device_method_t musbotg_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe, musbotg_probe),
+	DEVMETHOD(device_attach, musbotg_attach),
+	DEVMETHOD(device_detach, musbotg_detach),
+	DEVMETHOD(device_suspend, bus_generic_suspend),
+	DEVMETHOD(device_resume, bus_generic_resume),
+	DEVMETHOD(device_shutdown, bus_generic_shutdown),
+
+	DEVMETHOD_END
+};
+
+static driver_t musbotg_driver = {
+	.name = "musbotg",
+	.methods = musbotg_methods,
+	.size = sizeof(struct musbotg_super_softc),
+};
+
+static devclass_t musbotg_devclass;
+
+DRIVER_MODULE(musbotg, simplebus, musbotg_driver, musbotg_devclass, 0, 0);
+MODULE_DEPEND(musbotg, usb, 1, 1, 1);


Property changes on: trunk/sys/arm/ti/am335x/am335x_usbss.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/am335x/files.am335x
===================================================================
--- trunk/sys/arm/ti/am335x/files.am335x	                        (rev 0)
+++ trunk/sys/arm/ti/am335x/files.am335x	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,18 @@
+#$FreeBSD: stable/10/sys/arm/ti/am335x/files.am335x 278079 2015-02-02 12:48:13Z loos $
+
+arm/ti/aintc.c				standard
+
+arm/ti/am335x/am335x_dmtimer.c		standard
+arm/ti/am335x/am335x_lcd.c		optional	sc
+arm/ti/am335x/am335x_lcd_syscons.c	optional	sc
+arm/ti/am335x/am335x_pmic.c		optional	am335x_pmic
+arm/ti/am335x/am335x_prcm.c		standard
+arm/ti/am335x/am335x_pwm.c		standard
+arm/ti/am335x/am335x_rtc.c		optional	am335x_rtc
+arm/ti/am335x/am335x_scm_padconf.c	standard
+arm/ti/am335x/am335x_usbss.c		optional	musb fdt
+
+arm/ti/ti_edma3.c			standard
+arm/ti/ti_sdhci.c 			optional	sdhci
+#arm/ti/ti_mmchs.c 			optional	mmc
+arm/ti/cpsw/if_cpsw.c			optional	cpsw


Property changes on: trunk/sys/arm/ti/am335x/files.am335x
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/ti/am335x/std.am335x
===================================================================
--- trunk/sys/arm/ti/am335x/std.am335x	                        (rev 0)
+++ trunk/sys/arm/ti/am335x/std.am335x	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,19 @@
+# AM335x generic configuration
+#$FreeBSD: stable/10/sys/arm/ti/am335x/std.am335x 266110 2014-05-15 02:41:23Z ian $
+files		"../ti/am335x/files.am335x"
+include		"../ti/std.ti"
+makeoption	ARM_LITTLE_ENDIAN
+
+# Physical memory starts at 0x80000000.  We assume images are loaded at
+# 0x80200000, e.g. from u-boot with 'fatload mmc 0 0x80200000 kernel.bin'
+#
+#
+options		PHYSADDR=0x80000000
+options		KERNPHYSADDR=0x80200000
+makeoptions	KERNPHYSADDR=0x80200000
+options		KERNVIRTADDR=0xc0200000		# Used in ldscript.arm
+makeoptions	KERNVIRTADDR=0xc0200000
+
+options		SOC_TI_AM335X
+
+options		ARM_L2_PIPT


Property changes on: trunk/sys/arm/ti/am335x/std.am335x
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/ti/cpsw/if_cpsw.c
===================================================================
--- trunk/sys/arm/ti/cpsw/if_cpsw.c	                        (rev 0)
+++ trunk/sys/arm/ti/cpsw/if_cpsw.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,2198 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Damjan Marion <dmarion at Freebsd.org>
+ * 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.
+ */
+
+/*
+ * TI Common Platform Ethernet Switch (CPSW) Driver
+ * Found in TI8148 "DaVinci" and AM335x "Sitara" SoCs.
+ *
+ * This controller is documented in the AM335x Technical Reference
+ * Manual, in the TMS320DM814x DaVinci Digital Video Processors TRM
+ * and in the TMS320C6452 3 Port Switch Ethernet Subsystem TRM.
+ *
+ * It is basically a single Ethernet port (port 0) wired internally to
+ * a 3-port store-and-forward switch connected to two independent
+ * "sliver" controllers (port 1 and port 2).  You can operate the
+ * controller in a variety of different ways by suitably configuring
+ * the slivers and the Address Lookup Engine (ALE) that routes packets
+ * between the ports.
+ *
+ * This code was developed and tested on a BeagleBone with
+ * an AM335x SoC.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/ti/cpsw/if_cpsw.c 276875 2015-01-09 02:51:06Z loos $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/endian.h>
+#include <sys/mbuf.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/socket.h>
+#include <sys/sysctl.h>
+
+#include <net/ethernet.h>
+#include <net/bpf.h>
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <net/if_dl.h>
+#include <net/if_media.h>
+#include <net/if_types.h>
+#include <net/if_var.h>
+#include <net/if_vlan_var.h>
+
+#include <netinet/in_systm.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+
+#include <sys/sockio.h>
+#include <sys/bus.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
+#include <machine/resource.h>
+
+#include <dev/mii/mii.h>
+#include <dev/mii/miivar.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include "if_cpswreg.h"
+#include "if_cpswvar.h"
+ 
+#include <arm/ti/ti_scm.h>
+
+#include "miibus_if.h"
+
+/* Device probe/attach/detach. */
+static int cpsw_probe(device_t);
+static void cpsw_init_slots(struct cpsw_softc *);
+static int cpsw_attach(device_t);
+static void cpsw_free_slot(struct cpsw_softc *, struct cpsw_slot *);
+static int cpsw_detach(device_t);
+
+/* Device Init/shutdown. */
+static void cpsw_init(void *);
+static void cpsw_init_locked(void *);
+static int cpsw_shutdown(device_t);
+static void cpsw_shutdown_locked(struct cpsw_softc *);
+
+/* Device Suspend/Resume. */
+static int cpsw_suspend(device_t);
+static int cpsw_resume(device_t);
+
+/* Ioctl. */
+static int cpsw_ioctl(struct ifnet *, u_long command, caddr_t data);
+
+static int cpsw_miibus_readreg(device_t, int phy, int reg);
+static int cpsw_miibus_writereg(device_t, int phy, int reg, int value);
+
+/* Send/Receive packets. */
+static void cpsw_intr_rx(void *arg);
+static struct mbuf *cpsw_rx_dequeue(struct cpsw_softc *);
+static void cpsw_rx_enqueue(struct cpsw_softc *);
+static void cpsw_start(struct ifnet *);
+static void cpsw_tx_enqueue(struct cpsw_softc *);
+static int cpsw_tx_dequeue(struct cpsw_softc *);
+
+/* Misc interrupts and watchdog. */
+static void cpsw_intr_rx_thresh(void *);
+static void cpsw_intr_misc(void *);
+static void cpsw_tick(void *);
+static void cpsw_ifmedia_sts(struct ifnet *, struct ifmediareq *);
+static int cpsw_ifmedia_upd(struct ifnet *);
+static void cpsw_tx_watchdog(struct cpsw_softc *);
+
+/* ALE support */
+static void cpsw_ale_read_entry(struct cpsw_softc *, uint16_t idx, uint32_t *ale_entry);
+static void cpsw_ale_write_entry(struct cpsw_softc *, uint16_t idx, uint32_t *ale_entry);
+static int cpsw_ale_mc_entry_set(struct cpsw_softc *, uint8_t portmap, uint8_t *mac);
+static int cpsw_ale_update_addresses(struct cpsw_softc *, int purge);
+static void cpsw_ale_dump_table(struct cpsw_softc *);
+
+/* Statistics and sysctls. */
+static void cpsw_add_sysctls(struct cpsw_softc *);
+static void cpsw_stats_collect(struct cpsw_softc *);
+static int cpsw_stats_sysctl(SYSCTL_HANDLER_ARGS);
+
+/*
+ * Arbitrary limit on number of segments in an mbuf to be transmitted.
+ * Packets with more segments than this will be defragmented before
+ * they are queued.
+ */
+#define CPSW_TXFRAGS 8
+
+
+/*
+ * TODO: The CPSW subsystem (CPSW_SS) can drive two independent PHYs
+ * as separate Ethernet ports.  To properly support this, we should
+ * break this into two separate devices: a CPSW_SS device that owns
+ * the interrupts and actually talks to the CPSW hardware, and a
+ * separate CPSW Ethernet child device for each Ethernet port.  The RX
+ * interrupt, for example, would be part of CPSW_SS; it would receive
+ * a packet, note the input port, and then dispatch it to the child
+ * device's interface queue.  Similarly for transmit.
+ *
+ * It's not clear to me whether the device tree should be restructured
+ * with a cpsw_ss node and two child nodes.  That would allow specifying
+ * MAC addresses for each port, for example, but might be overkill.
+ *
+ * Unfortunately, I don't have hardware right now that supports two
+ * Ethernet ports via CPSW.
+ */
+
+static device_method_t cpsw_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		cpsw_probe),
+	DEVMETHOD(device_attach,	cpsw_attach),
+	DEVMETHOD(device_detach,	cpsw_detach),
+	DEVMETHOD(device_shutdown,	cpsw_shutdown),
+	DEVMETHOD(device_suspend,	cpsw_suspend),
+	DEVMETHOD(device_resume,	cpsw_resume),
+	/* MII interface */
+	DEVMETHOD(miibus_readreg,	cpsw_miibus_readreg),
+	DEVMETHOD(miibus_writereg,	cpsw_miibus_writereg),
+	{ 0, 0 }
+};
+
+static driver_t cpsw_driver = {
+	"cpsw",
+	cpsw_methods,
+	sizeof(struct cpsw_softc),
+};
+
+static devclass_t cpsw_devclass;
+
+DRIVER_MODULE(cpsw, simplebus, cpsw_driver, cpsw_devclass, 0, 0);
+DRIVER_MODULE(miibus, cpsw, miibus_driver, miibus_devclass, 0, 0);
+MODULE_DEPEND(cpsw, ether, 1, 1, 1);
+MODULE_DEPEND(cpsw, miibus, 1, 1, 1);
+
+static struct resource_spec res_spec[] = {
+	{ SYS_RES_MEMORY, 0, RF_ACTIVE },
+	{ SYS_RES_IRQ, 0, RF_ACTIVE | RF_SHAREABLE },
+	{ SYS_RES_IRQ, 1, RF_ACTIVE | RF_SHAREABLE },
+	{ SYS_RES_IRQ, 2, RF_ACTIVE | RF_SHAREABLE },
+	{ SYS_RES_IRQ, 3, RF_ACTIVE | RF_SHAREABLE },
+	{ -1, 0 }
+};
+
+/* Number of entries here must match size of stats
+ * array in struct cpsw_softc. */
+static struct cpsw_stat {
+	int	reg;
+	char *oid;
+} cpsw_stat_sysctls[CPSW_SYSCTL_COUNT] = {
+	{0x00, "GoodRxFrames"},
+	{0x04, "BroadcastRxFrames"},
+	{0x08, "MulticastRxFrames"},
+	{0x0C, "PauseRxFrames"},
+	{0x10, "RxCrcErrors"},
+	{0x14, "RxAlignErrors"},
+	{0x18, "OversizeRxFrames"},
+	{0x1c, "RxJabbers"},
+	{0x20, "ShortRxFrames"},
+	{0x24, "RxFragments"},
+	{0x30, "RxOctets"},
+	{0x34, "GoodTxFrames"},
+	{0x38, "BroadcastTxFrames"},
+	{0x3c, "MulticastTxFrames"},
+	{0x40, "PauseTxFrames"},
+	{0x44, "DeferredTxFrames"},
+	{0x48, "CollisionsTxFrames"},
+	{0x4c, "SingleCollisionTxFrames"},
+	{0x50, "MultipleCollisionTxFrames"},
+	{0x54, "ExcessiveCollisions"},
+	{0x58, "LateCollisions"},
+	{0x5c, "TxUnderrun"},
+	{0x60, "CarrierSenseErrors"},
+	{0x64, "TxOctets"},
+	{0x68, "RxTx64OctetFrames"},
+	{0x6c, "RxTx65to127OctetFrames"},
+	{0x70, "RxTx128to255OctetFrames"},
+	{0x74, "RxTx256to511OctetFrames"},
+	{0x78, "RxTx512to1024OctetFrames"},
+	{0x7c, "RxTx1024upOctetFrames"},
+	{0x80, "NetOctets"},
+	{0x84, "RxStartOfFrameOverruns"},
+	{0x88, "RxMiddleOfFrameOverruns"},
+	{0x8c, "RxDmaOverruns"}
+};
+
+/*
+ * Basic debug support.
+ */
+
+#define IF_DEBUG(sc)  if (sc->cpsw_if_flags & IFF_DEBUG)
+
+static void
+cpsw_debugf_head(const char *funcname)
+{
+	int t = (int)(time_second % (24 * 60 * 60));
+
+	printf("%02d:%02d:%02d %s ", t / (60 * 60), (t / 60) % 60, t % 60, funcname);
+}
+
+#include <machine/stdarg.h>
+static void
+cpsw_debugf(const char *fmt, ...)
+{
+	va_list ap;
+
+	va_start(ap, fmt);
+	vprintf(fmt, ap);
+	va_end(ap);
+	printf("\n");
+
+}
+
+#define CPSW_DEBUGF(a) do {					\
+	IF_DEBUG(sc) {						\
+		cpsw_debugf_head(__func__);			\
+		cpsw_debugf a;					\
+	}							\
+} while (0)
+
+
+/*
+ * Locking macros
+ */
+#define CPSW_TX_LOCK(sc) do {					\
+		mtx_assert(&(sc)->rx.lock, MA_NOTOWNED);		\
+		mtx_lock(&(sc)->tx.lock);				\
+} while (0)
+
+#define CPSW_TX_UNLOCK(sc)	mtx_unlock(&(sc)->tx.lock)
+#define CPSW_TX_LOCK_ASSERT(sc)	mtx_assert(&(sc)->tx.lock, MA_OWNED)
+
+#define CPSW_RX_LOCK(sc) do {					\
+		mtx_assert(&(sc)->tx.lock, MA_NOTOWNED);		\
+		mtx_lock(&(sc)->rx.lock);				\
+} while (0)
+
+#define CPSW_RX_UNLOCK(sc)		mtx_unlock(&(sc)->rx.lock)
+#define CPSW_RX_LOCK_ASSERT(sc)	mtx_assert(&(sc)->rx.lock, MA_OWNED)
+
+#define CPSW_GLOBAL_LOCK(sc) do {					\
+		if ((mtx_owned(&(sc)->tx.lock) ? 1 : 0) !=	\
+		    (mtx_owned(&(sc)->rx.lock) ? 1 : 0)) {		\
+			panic("cpsw deadlock possibility detection!");	\
+		}							\
+		mtx_lock(&(sc)->tx.lock);				\
+		mtx_lock(&(sc)->rx.lock);				\
+} while (0)
+
+#define CPSW_GLOBAL_UNLOCK(sc) do {					\
+		CPSW_RX_UNLOCK(sc);				\
+		CPSW_TX_UNLOCK(sc);				\
+} while (0)
+
+#define CPSW_GLOBAL_LOCK_ASSERT(sc) do {				\
+		CPSW_TX_LOCK_ASSERT(sc);				\
+		CPSW_RX_LOCK_ASSERT(sc);				\
+} while (0)
+
+/*
+ * Read/Write macros
+ */
+#define	cpsw_read_4(sc, reg)		bus_read_4(sc->res[0], reg)
+#define	cpsw_write_4(sc, reg, val)	bus_write_4(sc->res[0], reg, val)
+
+#define	cpsw_cpdma_bd_offset(i)	(CPSW_CPPI_RAM_OFFSET + ((i)*16))
+
+#define	cpsw_cpdma_bd_paddr(sc, slot)				\
+	BUS_SPACE_PHYSADDR(sc->res[0], slot->bd_offset)
+#define	cpsw_cpdma_read_bd(sc, slot, val)				\
+	bus_read_region_4(sc->res[0], slot->bd_offset, (uint32_t *) val, 4)
+#define	cpsw_cpdma_write_bd(sc, slot, val)				\
+	bus_write_region_4(sc->res[0], slot->bd_offset, (uint32_t *) val, 4)
+#define	cpsw_cpdma_write_bd_next(sc, slot, next_slot)			\
+	cpsw_write_4(sc, slot->bd_offset, cpsw_cpdma_bd_paddr(sc, next_slot))
+#define	cpsw_cpdma_read_bd_flags(sc, slot)		\
+	bus_read_2(sc->res[0], slot->bd_offset + 14)
+#define	cpsw_write_hdp_slot(sc, queue, slot)				\
+	cpsw_write_4(sc, (queue)->hdp_offset, cpsw_cpdma_bd_paddr(sc, slot))
+#define	CP_OFFSET (CPSW_CPDMA_TX_CP(0) - CPSW_CPDMA_TX_HDP(0))
+#define	cpsw_read_cp(sc, queue)				\
+	cpsw_read_4(sc, (queue)->hdp_offset + CP_OFFSET) 
+#define	cpsw_write_cp(sc, queue, val)				\
+	cpsw_write_4(sc, (queue)->hdp_offset + CP_OFFSET, (val))
+#define	cpsw_write_cp_slot(sc, queue, slot)		\
+	cpsw_write_cp(sc, queue, cpsw_cpdma_bd_paddr(sc, slot))
+
+#if 0
+/* XXX temporary function versions for debugging. */
+static void
+cpsw_write_hdp_slotX(struct cpsw_softc *sc, struct cpsw_queue *queue, struct cpsw_slot *slot)
+{
+	uint32_t reg = queue->hdp_offset;
+	uint32_t v = cpsw_cpdma_bd_paddr(sc, slot);
+	CPSW_DEBUGF(("HDP <=== 0x%08x (was 0x%08x)", v, cpsw_read_4(sc, reg)));
+	cpsw_write_4(sc, reg, v);
+}
+
+static void
+cpsw_write_cp_slotX(struct cpsw_softc *sc, struct cpsw_queue *queue, struct cpsw_slot *slot)
+{
+	uint32_t v = cpsw_cpdma_bd_paddr(sc, slot);
+	CPSW_DEBUGF(("CP <=== 0x%08x (expecting 0x%08x)", v, cpsw_read_cp(sc, queue)));
+	cpsw_write_cp(sc, queue, v);
+}
+#endif
+
+/*
+ * Expanded dump routines for verbose debugging.
+ */
+static void
+cpsw_dump_slot(struct cpsw_softc *sc, struct cpsw_slot *slot)
+{
+	static const char *flags[] = {"SOP", "EOP", "Owner", "EOQ",
+	    "TDownCmplt", "PassCRC", "Long", "Short", "MacCtl", "Overrun",
+	    "PktErr1", "PortEn/PktErr0", "RxVlanEncap", "Port2", "Port1",
+	    "Port0"};
+	struct cpsw_cpdma_bd bd;
+	const char *sep;
+	int i;
+
+	cpsw_cpdma_read_bd(sc, slot, &bd);
+	printf("BD Addr: 0x%08x   Next: 0x%08x\n", cpsw_cpdma_bd_paddr(sc, slot), bd.next);
+	printf("  BufPtr: 0x%08x   BufLen: 0x%08x\n", bd.bufptr, bd.buflen);
+	printf("  BufOff: 0x%08x   PktLen: 0x%08x\n", bd.bufoff, bd.pktlen);
+	printf("  Flags: ");
+	sep = "";
+	for (i = 0; i < 16; ++i) {
+		if (bd.flags & (1 << (15 - i))) {
+			printf("%s%s", sep, flags[i]);
+			sep = ",";
+		}
+	}
+	printf("\n");
+	if (slot->mbuf) {
+		printf("  Ether:  %14D\n",
+		    (char *)(slot->mbuf->m_hdr.mh_data), " ");
+		printf("  Packet: %16D\n",
+		    (char *)(slot->mbuf->m_hdr.mh_data) + 14, " ");
+	}
+}
+
+#define CPSW_DUMP_SLOT(cs, slot) do {				\
+	IF_DEBUG(sc) {						\
+		cpsw_dump_slot(sc, slot);			\
+	}							\
+} while (0)
+
+
+static void
+cpsw_dump_queue(struct cpsw_softc *sc, struct cpsw_slots *q)
+{
+	struct cpsw_slot *slot;
+	int i = 0;
+	int others = 0;
+
+	STAILQ_FOREACH(slot, q, next) {
+		if (i > 4)
+			++others;
+		else
+			cpsw_dump_slot(sc, slot);
+		++i;
+	}
+	if (others)
+		printf(" ... and %d more.\n", others);
+	printf("\n");
+}
+
+#define CPSW_DUMP_QUEUE(sc, q) do {				\
+	IF_DEBUG(sc) {						\
+		cpsw_dump_queue(sc, q);				\
+	}							\
+} while (0)
+
+
+/*
+ *
+ * Device Probe, Attach, Detach.
+ *
+ */
+
+static int
+cpsw_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "ti,cpsw"))
+		return (ENXIO);
+
+	device_set_desc(dev, "3-port Switch Ethernet Subsystem");
+	return (BUS_PROBE_DEFAULT);
+}
+
+
+static void
+cpsw_init_slots(struct cpsw_softc *sc)
+{
+	struct cpsw_slot *slot;
+	int i;
+
+	STAILQ_INIT(&sc->avail);
+
+	/* Put the slot descriptors onto the global avail list. */
+	for (i = 0; i < sizeof(sc->_slots) / sizeof(sc->_slots[0]); i++) {
+		slot = &sc->_slots[i];
+		slot->bd_offset = cpsw_cpdma_bd_offset(i);
+		STAILQ_INSERT_TAIL(&sc->avail, slot, next);
+	}
+}
+
+/*
+ * bind an interrupt, add the relevant info to sc->interrupts
+ */
+static int
+cpsw_attach_interrupt(struct cpsw_softc *sc, struct resource *res, driver_intr_t *handler, const char *description)
+{
+	void **pcookie;
+	int error;
+
+	sc->interrupts[sc->interrupt_count].res = res;
+	sc->interrupts[sc->interrupt_count].description = description;
+	pcookie = &sc->interrupts[sc->interrupt_count].ih_cookie;
+
+	error = bus_setup_intr(sc->dev, res, INTR_TYPE_NET | INTR_MPSAFE,
+	    NULL, *handler, sc, pcookie);
+	if (error)
+		device_printf(sc->dev,
+		    "could not setup %s\n", description);
+	else
+		++sc->interrupt_count;
+	return (error);
+}
+
+/*
+ * teardown everything in sc->interrupts.
+ */
+static void
+cpsw_detach_interrupts(struct cpsw_softc *sc)
+{
+	int error;
+	int i;
+
+	for (i = 0; i < sizeof(sc->interrupts) / sizeof(sc->interrupts[0]); ++i) {
+		if (!sc->interrupts[i].ih_cookie)
+			continue;
+		error = bus_teardown_intr(sc->dev,
+		    sc->interrupts[i].res, sc->interrupts[i].ih_cookie);
+		if (error)
+			device_printf(sc->dev, "could not release %s\n",
+			    sc->interrupts[i].description);
+		sc->interrupts[i].ih_cookie = NULL;
+	}
+}
+
+static int
+cpsw_add_slots(struct cpsw_softc *sc, struct cpsw_queue *queue, int requested)
+{
+	const int max_slots = sizeof(sc->_slots) / sizeof(sc->_slots[0]);
+	struct cpsw_slot *slot;
+	int i;
+
+	if (requested < 0)
+		requested = max_slots;
+
+	for (i = 0; i < requested; ++i) {
+		slot = STAILQ_FIRST(&sc->avail);
+		if (slot == NULL)
+			return (0);
+		if (bus_dmamap_create(sc->mbuf_dtag, 0, &slot->dmamap)) {
+			if_printf(sc->ifp, "failed to create dmamap\n");
+			return (ENOMEM);
+		}
+		STAILQ_REMOVE_HEAD(&sc->avail, next);
+		STAILQ_INSERT_TAIL(&queue->avail, slot, next);
+		++queue->avail_queue_len;
+		++queue->queue_slots;
+	}
+	return (0);
+}
+
+static int
+cpsw_attach(device_t dev)
+{
+	bus_dma_segment_t segs[1];
+	struct cpsw_softc *sc = device_get_softc(dev);
+	struct mii_softc *miisc;
+	struct ifnet *ifp;
+	void *phy_sc;
+	int error, phy, nsegs;
+	uint32_t reg;
+
+	CPSW_DEBUGF((""));
+
+	getbinuptime(&sc->attach_uptime);
+	sc->dev = dev;
+	sc->node = ofw_bus_get_node(dev);
+
+	/* Get phy address from fdt */
+	if (fdt_get_phyaddr(sc->node, sc->dev, &phy, &phy_sc) != 0) {
+		device_printf(dev, "failed to get PHY address from FDT\n");
+		return (ENXIO);
+	}
+	/* Initialize mutexes */
+	mtx_init(&sc->tx.lock, device_get_nameunit(dev),
+	    "cpsw TX lock", MTX_DEF);
+	mtx_init(&sc->rx.lock, device_get_nameunit(dev),
+	    "cpsw RX lock", MTX_DEF);
+
+	/* Allocate IO and IRQ resources */
+	error = bus_alloc_resources(dev, res_spec, sc->res);
+	if (error) {
+		device_printf(dev, "could not allocate resources\n");
+		cpsw_detach(dev);
+		return (ENXIO);
+	}
+
+	reg = cpsw_read_4(sc, CPSW_SS_IDVER);
+	device_printf(dev, "CPSW SS Version %d.%d (%d)\n", (reg >> 8 & 0x7),
+		reg & 0xFF, (reg >> 11) & 0x1F);
+
+	cpsw_add_sysctls(sc);
+
+	/* Allocate a busdma tag and DMA safe memory for mbufs. */
+	error = bus_dma_tag_create(
+		bus_get_dma_tag(sc->dev),	/* parent */
+		1, 0,				/* alignment, boundary */
+		BUS_SPACE_MAXADDR_32BIT,	/* lowaddr */
+		BUS_SPACE_MAXADDR,		/* highaddr */
+		NULL, NULL,			/* filtfunc, filtfuncarg */
+		MCLBYTES, CPSW_TXFRAGS,		/* maxsize, nsegments */
+		MCLBYTES, 0,			/* maxsegsz, flags */
+		NULL, NULL,			/* lockfunc, lockfuncarg */
+		&sc->mbuf_dtag);		/* dmatag */
+	if (error) {
+		device_printf(dev, "bus_dma_tag_create failed\n");
+		cpsw_detach(dev);
+		return (error);
+	}
+
+	/* Allocate network interface */
+	ifp = sc->ifp = if_alloc(IFT_ETHER);
+	if (ifp == NULL) {
+		device_printf(dev, "if_alloc() failed\n");
+		cpsw_detach(dev);
+		return (ENOMEM);
+	}
+
+	/* Allocate the null mbuf and pre-sync it. */
+	sc->null_mbuf = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
+	memset(sc->null_mbuf->m_hdr.mh_data, 0, sc->null_mbuf->m_ext.ext_size);
+	bus_dmamap_create(sc->mbuf_dtag, 0, &sc->null_mbuf_dmamap);
+	bus_dmamap_load_mbuf_sg(sc->mbuf_dtag, sc->null_mbuf_dmamap,
+	    sc->null_mbuf, segs, &nsegs, BUS_DMA_NOWAIT);
+	bus_dmamap_sync(sc->mbuf_dtag, sc->null_mbuf_dmamap,
+	    BUS_DMASYNC_PREWRITE);
+	sc->null_mbuf_paddr = segs[0].ds_addr;
+
+	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
+	ifp->if_softc = sc;
+	ifp->if_flags = IFF_SIMPLEX | IFF_MULTICAST | IFF_BROADCAST;
+	ifp->if_capabilities = IFCAP_VLAN_MTU | IFCAP_HWCSUM; //FIXME VLAN?
+	ifp->if_capenable = ifp->if_capabilities;
+
+	ifp->if_init = cpsw_init;
+	ifp->if_start = cpsw_start;
+	ifp->if_ioctl = cpsw_ioctl;
+
+	cpsw_init_slots(sc);
+
+	/* Allocate slots to TX and RX queues. */
+	STAILQ_INIT(&sc->rx.avail);
+	STAILQ_INIT(&sc->rx.active);
+	STAILQ_INIT(&sc->tx.avail);
+	STAILQ_INIT(&sc->tx.active);
+	// For now:  128 slots to TX, rest to RX.
+	// XXX TODO: start with 32/64 and grow dynamically based on demand.
+	if (cpsw_add_slots(sc, &sc->tx, 128) || cpsw_add_slots(sc, &sc->rx, -1)) {
+		device_printf(dev, "failed to allocate dmamaps\n");
+		cpsw_detach(dev);
+		return (ENOMEM);
+	}
+	device_printf(dev, "Initial queue size TX=%d RX=%d\n",
+	    sc->tx.queue_slots, sc->rx.queue_slots);
+
+	ifp->if_snd.ifq_drv_maxlen = sc->tx.queue_slots;
+	IFQ_SET_MAXLEN(&ifp->if_snd, ifp->if_snd.ifq_drv_maxlen);
+	IFQ_SET_READY(&ifp->if_snd);
+
+	sc->tx.hdp_offset = CPSW_CPDMA_TX_HDP(0);
+	sc->rx.hdp_offset = CPSW_CPDMA_RX_HDP(0);
+
+	/* Get high part of MAC address from control module (mac_id0_hi) */
+	/* TODO: Get MAC ID1 as well as MAC ID0. */
+	ti_scm_reg_read_4(0x634, &reg);
+	sc->mac_addr[0] = reg & 0xFF;
+	sc->mac_addr[1] = (reg >>  8) & 0xFF;
+	sc->mac_addr[2] = (reg >> 16) & 0xFF;
+	sc->mac_addr[3] = (reg >> 24) & 0xFF;
+
+	/* Get low part of MAC address from control module (mac_id0_lo) */
+	ti_scm_reg_read_4(0x630, &reg);
+	sc->mac_addr[4] = reg & 0xFF;
+	sc->mac_addr[5] = (reg >>  8) & 0xFF;
+
+	/* Initialze MDIO - ENABLE, PREAMBLE=0, FAULTENB, CLKDIV=0xFF */
+	/* TODO Calculate MDCLK=CLK/(CLKDIV+1) */
+	cpsw_write_4(sc, MDIOCONTROL, 1 << 30 | 1 << 18 | 0xFF);
+
+	/* Clear ALE */
+	cpsw_write_4(sc, CPSW_ALE_CONTROL, 1 << 30);
+
+	/* Attach PHY(s) */
+	error = mii_attach(dev, &sc->miibus, ifp, cpsw_ifmedia_upd,
+	    cpsw_ifmedia_sts, BMSR_DEFCAPMASK, phy, MII_OFFSET_ANY, 0);
+	if (error) {
+		device_printf(dev, "attaching PHYs failed\n");
+		cpsw_detach(dev);
+		return (error);
+	}
+	sc->mii = device_get_softc(sc->miibus);
+
+	/* Tell the MAC where to find the PHY so autoneg works */
+	miisc = LIST_FIRST(&sc->mii->mii_phys);
+
+	/* Select PHY and enable interrupts */
+	cpsw_write_4(sc, MDIOUSERPHYSEL0, 1 << 6 | (miisc->mii_phy & 0x1F));
+	
+	/* Note: We don't use sc->res[3] (TX interrupt) */
+	if (cpsw_attach_interrupt(sc, sc->res[1],
+		cpsw_intr_rx_thresh, "CPSW RX threshold interrupt") ||
+	    cpsw_attach_interrupt(sc, sc->res[2],
+		cpsw_intr_rx, "CPSW RX interrupt") ||
+	    cpsw_attach_interrupt(sc, sc->res[4],
+		cpsw_intr_misc, "CPSW misc interrupt")) {
+		cpsw_detach(dev);
+		return (ENXIO);
+	}
+
+	ether_ifattach(ifp, sc->mac_addr);
+	callout_init(&sc->watchdog.callout, 0);
+
+	return (0);
+}
+
+static void
+cpsw_free_slot(struct cpsw_softc *sc, struct cpsw_slot *slot)
+{
+	int error;
+
+	if (slot->dmamap) {
+		error = bus_dmamap_destroy(sc->mbuf_dtag, slot->dmamap);
+		KASSERT(error == 0, ("Mapping still active"));
+		slot->dmamap = NULL;
+	}
+	if (slot->mbuf) {
+		m_freem(slot->mbuf);
+		slot->mbuf = NULL;
+	}
+}
+
+static int
+cpsw_detach(device_t dev)
+{
+	struct cpsw_softc *sc = device_get_softc(dev);
+	int error, i;
+
+	CPSW_DEBUGF((""));
+
+	/* Stop controller and free TX queue */
+	if (device_is_attached(dev)) {
+		ether_ifdetach(sc->ifp);
+		CPSW_GLOBAL_LOCK(sc);
+		cpsw_shutdown_locked(sc);
+		CPSW_GLOBAL_UNLOCK(sc);
+		callout_drain(&sc->watchdog.callout);
+	}
+
+	bus_generic_detach(dev);
+	if (sc->miibus)
+		device_delete_child(dev, sc->miibus);
+
+	/* Stop and release all interrupts */
+	cpsw_detach_interrupts(sc);
+
+	/* Free dmamaps and mbufs */
+	for (i = 0; i < sizeof(sc->_slots) / sizeof(sc->_slots[0]); ++i)
+		cpsw_free_slot(sc, &sc->_slots[i]);
+	if (sc->null_mbuf_dmamap) {
+		error = bus_dmamap_destroy(sc->mbuf_dtag, sc->null_mbuf_dmamap);
+		KASSERT(error == 0, ("Mapping still active"));
+	}
+	if (sc->null_mbuf)
+		m_freem(sc->null_mbuf);
+
+	/* Free DMA tag */
+	error = bus_dma_tag_destroy(sc->mbuf_dtag);
+	KASSERT(error == 0, ("Unable to destroy DMA tag"));
+
+	/* Free IO memory handler */
+	bus_release_resources(dev, res_spec, sc->res);
+
+	if (sc->ifp != NULL)
+		if_free(sc->ifp);
+
+	/* Destroy mutexes */
+	mtx_destroy(&sc->rx.lock);
+	mtx_destroy(&sc->tx.lock);
+
+	return (0);
+}
+
+/*
+ *
+ * Init/Shutdown.
+ *
+ */
+
+static void
+cpsw_reset(struct cpsw_softc *sc)
+{
+	int i;
+
+	/* Reset RMII/RGMII wrapper. */
+	cpsw_write_4(sc, CPSW_WR_SOFT_RESET, 1);
+	while (cpsw_read_4(sc, CPSW_WR_SOFT_RESET) & 1)
+		;
+
+	/* Disable TX and RX interrupts for all cores. */
+	for (i = 0; i < 3; ++i) {
+		cpsw_write_4(sc, CPSW_WR_C_RX_THRESH_EN(i), 0x00);
+		cpsw_write_4(sc, CPSW_WR_C_TX_EN(i), 0x00);
+		cpsw_write_4(sc, CPSW_WR_C_RX_EN(i), 0x00);
+		cpsw_write_4(sc, CPSW_WR_C_MISC_EN(i), 0x00);
+	}
+
+	/* Reset CPSW subsystem. */
+	cpsw_write_4(sc, CPSW_SS_SOFT_RESET, 1);
+	while (cpsw_read_4(sc, CPSW_SS_SOFT_RESET) & 1)
+		;
+
+	/* Reset Sliver port 1 and 2 */
+	for (i = 0; i < 2; i++) {
+		/* Reset */
+		cpsw_write_4(sc, CPSW_SL_SOFT_RESET(i), 1);
+		while (cpsw_read_4(sc, CPSW_SL_SOFT_RESET(i)) & 1)
+			;
+	}
+
+	/* Reset DMA controller. */
+	cpsw_write_4(sc, CPSW_CPDMA_SOFT_RESET, 1);
+	while (cpsw_read_4(sc, CPSW_CPDMA_SOFT_RESET) & 1)
+		;
+
+	/* Disable TX & RX DMA */
+	cpsw_write_4(sc, CPSW_CPDMA_TX_CONTROL, 0);
+	cpsw_write_4(sc, CPSW_CPDMA_RX_CONTROL, 0);
+
+	/* Clear all queues. */
+	for (i = 0; i < 8; i++) {
+		cpsw_write_4(sc, CPSW_CPDMA_TX_HDP(i), 0);
+		cpsw_write_4(sc, CPSW_CPDMA_RX_HDP(i), 0);
+		cpsw_write_4(sc, CPSW_CPDMA_TX_CP(i), 0);
+		cpsw_write_4(sc, CPSW_CPDMA_RX_CP(i), 0);
+	}
+
+	/* Clear all interrupt Masks */
+	cpsw_write_4(sc, CPSW_CPDMA_RX_INTMASK_CLEAR, 0xFFFFFFFF);
+	cpsw_write_4(sc, CPSW_CPDMA_TX_INTMASK_CLEAR, 0xFFFFFFFF);
+}
+
+static void
+cpsw_init(void *arg)
+{
+	struct cpsw_softc *sc = arg;
+
+	CPSW_DEBUGF((""));
+	CPSW_GLOBAL_LOCK(sc);
+	cpsw_init_locked(arg);
+	CPSW_GLOBAL_UNLOCK(sc);
+}
+
+static void
+cpsw_init_locked(void *arg)
+{
+	struct ifnet *ifp;
+	struct cpsw_softc *sc = arg;
+	struct cpsw_slot *slot;
+	uint32_t i;
+
+	CPSW_DEBUGF((""));
+	ifp = sc->ifp;
+	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
+		return;
+
+	getbinuptime(&sc->init_uptime);
+
+	/* Reset the controller. */
+	cpsw_reset(sc);
+
+	/* Enable ALE */
+	cpsw_write_4(sc, CPSW_ALE_CONTROL, 1 << 31 | 1 << 4);
+
+	/* Init Sliver port 1 and 2 */
+	for (i = 0; i < 2; i++) {
+		/* Set Slave Mapping */
+		cpsw_write_4(sc, CPSW_SL_RX_PRI_MAP(i), 0x76543210);
+		cpsw_write_4(sc, CPSW_PORT_P_TX_PRI_MAP(i + 1), 0x33221100);
+		cpsw_write_4(sc, CPSW_SL_RX_MAXLEN(i), 0x5f2);
+		/* Set MACCONTROL for ports 0,1: IFCTL_B(16), IFCTL_A(15),
+		   GMII_EN(5), FULLDUPLEX(1) */
+		/* TODO: Docs claim that IFCTL_B and IFCTL_A do the same thing? */
+		/* Huh?  Docs call bit 0 "Loopback" some places, "FullDuplex" others. */
+		cpsw_write_4(sc, CPSW_SL_MACCONTROL(i), 1 << 15 | 1 << 5 | 1);
+	}
+
+	/* Set Host Port Mapping */
+	cpsw_write_4(sc, CPSW_PORT_P0_CPDMA_TX_PRI_MAP, 0x76543210);
+	cpsw_write_4(sc, CPSW_PORT_P0_CPDMA_RX_CH_MAP, 0);
+
+	/* Initialize ALE: all ports set to forwarding(3), initialize addrs */
+	for (i = 0; i < 3; i++)
+		cpsw_write_4(sc, CPSW_ALE_PORTCTL(i), 3);
+	cpsw_ale_update_addresses(sc, 1);
+
+	cpsw_write_4(sc, CPSW_SS_PTYPE, 0);
+
+	/* Enable statistics for ports 0, 1 and 2 */
+	cpsw_write_4(sc, CPSW_SS_STAT_PORT_EN, 7);
+
+	/* Experiment:  Turn off flow control */
+	/* This seems to fix the watchdog resets that have plagued
+	   earlier versions of this driver; I'm not yet sure if there
+	   are negative effects yet. */
+	cpsw_write_4(sc, CPSW_SS_FLOW_CONTROL, 0);
+
+	/* Make IP hdr aligned with 4 */
+	cpsw_write_4(sc, CPSW_CPDMA_RX_BUFFER_OFFSET, 2);
+
+	/* Initialize RX Buffer Descriptors */
+	cpsw_write_4(sc, CPSW_CPDMA_RX_FREEBUFFER(0), 0);
+
+	/* Enable TX & RX DMA */
+	cpsw_write_4(sc, CPSW_CPDMA_TX_CONTROL, 1);
+	cpsw_write_4(sc, CPSW_CPDMA_RX_CONTROL, 1);
+
+	/* Enable Interrupts for core 0 */
+	cpsw_write_4(sc, CPSW_WR_C_RX_THRESH_EN(0), 0xFF);
+	cpsw_write_4(sc, CPSW_WR_C_RX_EN(0), 0xFF);
+	cpsw_write_4(sc, CPSW_WR_C_MISC_EN(0), 0x3F);
+
+	/* Enable host Error Interrupt */
+	cpsw_write_4(sc, CPSW_CPDMA_DMA_INTMASK_SET, 3);
+
+	/* Enable interrupts for RX Channel 0 */
+	cpsw_write_4(sc, CPSW_CPDMA_RX_INTMASK_SET, 1);
+
+	/* Initialze MDIO - ENABLE, PREAMBLE=0, FAULTENB, CLKDIV=0xFF */
+	/* TODO Calculate MDCLK=CLK/(CLKDIV+1) */
+	cpsw_write_4(sc, MDIOCONTROL, 1 << 30 | 1 << 18 | 0xFF);
+
+	/* Select MII in GMII_SEL, Internal Delay mode */
+	//ti_scm_reg_write_4(0x650, 0);
+
+	/* Initialize active queues. */
+	slot = STAILQ_FIRST(&sc->tx.active);
+	if (slot != NULL)
+		cpsw_write_hdp_slot(sc, &sc->tx, slot);
+	slot = STAILQ_FIRST(&sc->rx.active);
+	if (slot != NULL)
+		cpsw_write_hdp_slot(sc, &sc->rx, slot);
+	cpsw_rx_enqueue(sc);
+
+	/* Activate network interface */
+	sc->rx.running = 1;
+	sc->tx.running = 1;
+	sc->watchdog.timer = 0;
+	callout_reset(&sc->watchdog.callout, hz, cpsw_tick, sc);
+	sc->ifp->if_drv_flags |= IFF_DRV_RUNNING;
+	sc->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+
+}
+
+static int
+cpsw_shutdown(device_t dev)
+{
+	struct cpsw_softc *sc = device_get_softc(dev);
+
+	CPSW_DEBUGF((""));
+	CPSW_GLOBAL_LOCK(sc);
+	cpsw_shutdown_locked(sc);
+	CPSW_GLOBAL_UNLOCK(sc);
+	return (0);
+}
+
+static void
+cpsw_rx_teardown_locked(struct cpsw_softc *sc)
+{
+	struct mbuf *received, *next;
+	int i = 0;
+
+	CPSW_DEBUGF(("starting RX teardown"));
+	cpsw_write_4(sc, CPSW_CPDMA_RX_TEARDOWN, 0);
+	for (;;) {
+		received = cpsw_rx_dequeue(sc);
+		CPSW_GLOBAL_UNLOCK(sc);
+		while (received != NULL) {
+			next = received->m_nextpkt;
+			received->m_nextpkt = NULL;
+			(*sc->ifp->if_input)(sc->ifp, received);
+			received = next;
+		}
+		CPSW_GLOBAL_LOCK(sc);
+		if (!sc->rx.running) {
+			CPSW_DEBUGF(("finished RX teardown (%d retries)", i));
+			return;
+		}
+		if (++i > 10) {
+			if_printf(sc->ifp, "Unable to cleanly shutdown receiver\n");
+			return;
+		}
+		DELAY(10);
+	}
+}
+
+static void
+cpsw_tx_teardown_locked(struct cpsw_softc *sc)
+{
+	int i = 0;
+
+	CPSW_DEBUGF(("starting TX teardown"));
+	cpsw_write_4(sc, CPSW_CPDMA_TX_TEARDOWN, 0);
+	cpsw_tx_dequeue(sc);
+	while (sc->tx.running && ++i < 10) {
+		DELAY(10);
+		cpsw_tx_dequeue(sc);
+	}
+	if (sc->tx.running)
+		if_printf(sc->ifp, "Unable to cleanly shutdown transmitter\n");
+	CPSW_DEBUGF(("finished TX teardown (%d retries, %d idle buffers)",
+	    i, sc->tx.active_queue_len));
+}
+
+static void
+cpsw_shutdown_locked(struct cpsw_softc *sc)
+{
+	struct ifnet *ifp;
+
+	CPSW_DEBUGF((""));
+	CPSW_GLOBAL_LOCK_ASSERT(sc);
+	ifp = sc->ifp;
+
+	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+		return;
+
+	/* Disable interface */
+	ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
+	ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+
+	/* Stop ticker */
+	callout_stop(&sc->watchdog.callout);
+
+	/* Tear down the RX/TX queues. */
+	cpsw_rx_teardown_locked(sc);
+	cpsw_tx_teardown_locked(sc);
+
+	/* Capture stats before we reset controller. */
+	cpsw_stats_collect(sc);
+
+	cpsw_reset(sc);
+}
+
+/*
+ *  Suspend/Resume.
+ */
+
+static int
+cpsw_suspend(device_t dev)
+{
+	struct cpsw_softc *sc = device_get_softc(dev);
+
+	CPSW_DEBUGF((""));
+	CPSW_GLOBAL_LOCK(sc);
+	cpsw_shutdown_locked(sc);
+	CPSW_GLOBAL_UNLOCK(sc);
+	return (0);
+}
+
+static int
+cpsw_resume(device_t dev)
+{
+	struct cpsw_softc *sc = device_get_softc(dev);
+
+	CPSW_DEBUGF(("UNIMPLEMENTED"));
+	return (0);
+}
+
+/*
+ *
+ *  IOCTL
+ *
+ */
+
+static void
+cpsw_set_promisc(struct cpsw_softc *sc, int set)
+{
+	/*
+	 * Enabling promiscuous mode requires two bits of work: First,
+	 * ALE_BYPASS needs to be enabled.  That disables the ALE
+	 * forwarding logic and causes every packet to be sent to the
+	 * host port.  That makes us promiscuous wrt received packets.
+	 *
+	 * With ALE forwarding disabled, the transmitter needs to set
+	 * an explicit output port on every packet to route it to the
+	 * correct egress.  This should be doable for systems such as
+	 * BeagleBone where only one egress port is actually wired to
+	 * a PHY.  If you have both egress ports wired up, life gets a
+	 * lot more interesting.
+	 *
+	 * Hmmm.... NetBSD driver uses ALE_BYPASS always and doesn't
+	 * seem to set explicit egress ports.  Does that mean they
+	 * are always promiscuous?
+	 */
+	if (set) {
+		printf("Promiscuous mode unimplemented\n");
+	}
+}
+
+static void
+cpsw_set_allmulti(struct cpsw_softc *sc, int set)
+{
+	if (set) {
+		printf("All-multicast mode unimplemented\n");
+	}
+}
+
+static int
+cpsw_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
+{
+	struct cpsw_softc *sc = ifp->if_softc;
+	struct ifreq *ifr = (struct ifreq *)data;
+	int error;
+	uint32_t changed;
+
+	error = 0;
+
+	switch (command) {
+	case SIOCSIFFLAGS:
+		CPSW_GLOBAL_LOCK(sc);
+		if (ifp->if_flags & IFF_UP) {
+			if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
+				changed = ifp->if_flags ^ sc->cpsw_if_flags;
+				CPSW_DEBUGF(("SIOCSIFFLAGS: UP & RUNNING (changed=0x%x)", changed));
+				if (changed & IFF_PROMISC)
+					cpsw_set_promisc(sc,
+					    ifp->if_flags & IFF_PROMISC);
+				if (changed & IFF_ALLMULTI)
+					cpsw_set_allmulti(sc,
+					    ifp->if_flags & IFF_ALLMULTI);
+			} else {
+				CPSW_DEBUGF(("SIOCSIFFLAGS: UP but not RUNNING; starting up"));
+				cpsw_init_locked(sc);
+			}
+		} else if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
+			CPSW_DEBUGF(("SIOCSIFFLAGS: not UP but RUNNING; shutting down"));
+			cpsw_shutdown_locked(sc);
+		}
+
+		sc->cpsw_if_flags = ifp->if_flags;
+		CPSW_GLOBAL_UNLOCK(sc);
+		break;
+	case SIOCADDMULTI:
+		cpsw_ale_update_addresses(sc, 0);
+		break;
+	case SIOCDELMULTI:
+		/* Ugh.  DELMULTI doesn't provide the specific address
+		   being removed, so the best we can do is remove
+		   everything and rebuild it all. */
+		cpsw_ale_update_addresses(sc, 1);
+		break;
+	case SIOCGIFMEDIA:
+	case SIOCSIFMEDIA:
+		error = ifmedia_ioctl(ifp, ifr, &sc->mii->mii_media, command);
+		break;
+	default:
+		error = ether_ioctl(ifp, command, data);
+	}
+	return (error);
+}
+
+/*
+ *
+ * MIIBUS
+ *
+ */
+static int
+cpsw_miibus_ready(struct cpsw_softc *sc)
+{
+	uint32_t r, retries = CPSW_MIIBUS_RETRIES;
+
+	while (--retries) {
+		r = cpsw_read_4(sc, MDIOUSERACCESS0);
+		if ((r & 1 << 31) == 0)
+			return 1;
+		DELAY(CPSW_MIIBUS_DELAY);
+	}
+	return 0;
+}
+
+static int
+cpsw_miibus_readreg(device_t dev, int phy, int reg)
+{
+	struct cpsw_softc *sc = device_get_softc(dev);
+	uint32_t cmd, r;
+
+	if (!cpsw_miibus_ready(sc)) {
+		device_printf(dev, "MDIO not ready to read\n");
+		return 0;
+	}
+
+	/* Set GO, reg, phy */
+	cmd = 1 << 31 | (reg & 0x1F) << 21 | (phy & 0x1F) << 16;
+	cpsw_write_4(sc, MDIOUSERACCESS0, cmd);
+
+	if (!cpsw_miibus_ready(sc)) {
+		device_printf(dev, "MDIO timed out during read\n");
+		return 0;
+	}
+
+	r = cpsw_read_4(sc, MDIOUSERACCESS0);
+	if((r & 1 << 29) == 0) {
+		device_printf(dev, "Failed to read from PHY.\n");
+		r = 0;
+	}
+	return (r & 0xFFFF);
+}
+
+static int
+cpsw_miibus_writereg(device_t dev, int phy, int reg, int value)
+{
+	struct cpsw_softc *sc = device_get_softc(dev);
+	uint32_t cmd;
+
+	if (!cpsw_miibus_ready(sc)) {
+		device_printf(dev, "MDIO not ready to write\n");
+		return 0;
+	}
+
+	/* Set GO, WRITE, reg, phy, and value */
+	cmd = 3 << 30 | (reg & 0x1F) << 21 | (phy & 0x1F) << 16
+	    | (value & 0xFFFF);
+	cpsw_write_4(sc, MDIOUSERACCESS0, cmd);
+
+	if (!cpsw_miibus_ready(sc)) {
+		device_printf(dev, "MDIO timed out during write\n");
+		return 0;
+	}
+
+	if((cpsw_read_4(sc, MDIOUSERACCESS0) & (1 << 29)) == 0)
+		device_printf(dev, "Failed to write to PHY.\n");
+
+	return 0;
+}
+
+/*
+ *
+ * Transmit/Receive Packets.
+ *
+ */
+
+
+static void
+cpsw_intr_rx(void *arg)
+{
+	struct cpsw_softc *sc = arg;
+	struct mbuf *received, *next;
+
+	CPSW_RX_LOCK(sc);
+	received = cpsw_rx_dequeue(sc);
+	cpsw_rx_enqueue(sc);
+	cpsw_write_4(sc, CPSW_CPDMA_CPDMA_EOI_VECTOR, 1);
+	CPSW_RX_UNLOCK(sc);
+	
+	while (received != NULL) {
+		next = received->m_nextpkt;
+		received->m_nextpkt = NULL;
+		(*sc->ifp->if_input)(sc->ifp, received);
+		received = next;
+	}
+}
+
+static struct mbuf *
+cpsw_rx_dequeue(struct cpsw_softc *sc)
+{
+	struct cpsw_cpdma_bd bd;
+	struct cpsw_slot *slot;
+	struct ifnet *ifp;
+	struct mbuf *mb_head, *mb_tail;
+	int removed = 0;
+
+	ifp = sc->ifp;
+	mb_head = mb_tail = NULL;
+
+	/* Pull completed packets off hardware RX queue. */
+	while ((slot = STAILQ_FIRST(&sc->rx.active)) != NULL) {
+		cpsw_cpdma_read_bd(sc, slot, &bd);
+		if (bd.flags & CPDMA_BD_OWNER)
+			break; /* Still in use by hardware */
+
+		CPSW_DEBUGF(("Removing received packet from RX queue"));
+		++removed;
+		STAILQ_REMOVE_HEAD(&sc->rx.active, next);
+		STAILQ_INSERT_TAIL(&sc->rx.avail, slot, next);
+
+		bus_dmamap_sync(sc->mbuf_dtag, slot->dmamap, BUS_DMASYNC_POSTREAD);
+		bus_dmamap_unload(sc->mbuf_dtag, slot->dmamap);
+
+		if (bd.flags & CPDMA_BD_TDOWNCMPLT) {
+			CPSW_DEBUGF(("RX teardown in progress"));
+			m_freem(slot->mbuf);
+			slot->mbuf = NULL;
+			cpsw_write_cp(sc, &sc->rx, 0xfffffffc);
+			sc->rx.running = 0;
+			break;
+		}
+
+		cpsw_write_cp_slot(sc, &sc->rx, slot);
+
+		/* Set up mbuf */
+		/* TODO: track SOP/EOP bits to assemble a full mbuf
+		   out of received fragments. */
+		slot->mbuf->m_hdr.mh_data += bd.bufoff;
+		slot->mbuf->m_hdr.mh_len = bd.pktlen - 4;
+		slot->mbuf->m_pkthdr.len = bd.pktlen - 4;
+		slot->mbuf->m_flags |= M_PKTHDR;
+		slot->mbuf->m_pkthdr.rcvif = ifp;
+		slot->mbuf->m_nextpkt = NULL;
+
+		if ((ifp->if_capenable & IFCAP_RXCSUM) != 0) {
+			/* check for valid CRC by looking into pkt_err[5:4] */
+			if ((bd.flags & CPDMA_BD_PKT_ERR_MASK) == 0) {
+				slot->mbuf->m_pkthdr.csum_flags |= CSUM_IP_CHECKED;
+				slot->mbuf->m_pkthdr.csum_flags |= CSUM_IP_VALID;
+				slot->mbuf->m_pkthdr.csum_data = 0xffff;
+			}
+		}
+
+		/* Add mbuf to packet list to be returned. */
+		if (mb_tail) {
+			mb_tail->m_nextpkt = slot->mbuf;
+		} else {
+			mb_head = slot->mbuf;
+		}
+		mb_tail = slot->mbuf;
+		slot->mbuf = NULL;
+	}
+
+	if (removed != 0) {
+		sc->rx.queue_removes += removed;
+		sc->rx.active_queue_len -= removed;
+		sc->rx.avail_queue_len += removed;
+		if (sc->rx.avail_queue_len > sc->rx.max_avail_queue_len)
+			sc->rx.max_avail_queue_len = sc->rx.avail_queue_len;
+	}
+	return (mb_head);
+}
+
+static void
+cpsw_rx_enqueue(struct cpsw_softc *sc)
+{
+	bus_dma_segment_t seg[1];
+	struct cpsw_cpdma_bd bd;
+	struct ifnet *ifp = sc->ifp;
+	struct cpsw_slots tmpqueue = STAILQ_HEAD_INITIALIZER(tmpqueue);
+	struct cpsw_slot *slot, *prev_slot = NULL;
+	struct cpsw_slot *last_old_slot, *first_new_slot;
+	int error, nsegs, added = 0;
+
+	/* Register new mbufs with hardware. */
+	while ((slot = STAILQ_FIRST(&sc->rx.avail)) != NULL) {
+		if (slot->mbuf == NULL) {
+			slot->mbuf = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
+			if (slot->mbuf == NULL) {
+				if_printf(sc->ifp, "Unable to fill RX queue\n");
+				break;
+			}
+			slot->mbuf->m_len =
+			    slot->mbuf->m_pkthdr.len =
+			    slot->mbuf->m_ext.ext_size;
+		}
+
+		error = bus_dmamap_load_mbuf_sg(sc->mbuf_dtag, slot->dmamap,
+		    slot->mbuf, seg, &nsegs, BUS_DMA_NOWAIT);
+
+		KASSERT(nsegs == 1, ("More than one segment (nsegs=%d)", nsegs));
+		KASSERT(error == 0, ("DMA error (error=%d)", error));
+		if (error != 0 || nsegs != 1) {
+			if_printf(ifp,
+			    "%s: Can't prep RX buf for DMA (nsegs=%d, error=%d)\n",
+			    __func__, nsegs, error);
+			bus_dmamap_unload(sc->mbuf_dtag, slot->dmamap);
+			m_freem(slot->mbuf);
+			slot->mbuf = NULL;
+			break;
+		}
+
+		bus_dmamap_sync(sc->mbuf_dtag, slot->dmamap, BUS_DMASYNC_PREREAD);
+
+		/* Create and submit new rx descriptor*/
+		bd.next = 0;
+		bd.bufptr = seg->ds_addr;
+		bd.bufoff = 0;
+		bd.buflen = MCLBYTES - 1;
+		bd.pktlen = bd.buflen;
+		bd.flags = CPDMA_BD_OWNER;
+		cpsw_cpdma_write_bd(sc, slot, &bd);
+		++added;
+
+		if (prev_slot != NULL)
+			cpsw_cpdma_write_bd_next(sc, prev_slot, slot);
+		prev_slot = slot;
+		STAILQ_REMOVE_HEAD(&sc->rx.avail, next);
+		sc->rx.avail_queue_len--;
+		STAILQ_INSERT_TAIL(&tmpqueue, slot, next);
+	}
+
+	if (added == 0)
+		return;
+
+	CPSW_DEBUGF(("Adding %d buffers to RX queue", added));
+
+	/* Link new entries to hardware RX queue. */
+	last_old_slot = STAILQ_LAST(&sc->rx.active, cpsw_slot, next);
+	first_new_slot = STAILQ_FIRST(&tmpqueue);
+	STAILQ_CONCAT(&sc->rx.active, &tmpqueue);
+	if (first_new_slot == NULL) {
+		return;
+	} else if (last_old_slot == NULL) {
+		/* Start a fresh queue. */
+		cpsw_write_hdp_slot(sc, &sc->rx, first_new_slot);
+	} else {
+		/* Add buffers to end of current queue. */
+		cpsw_cpdma_write_bd_next(sc, last_old_slot, first_new_slot);
+		/* If underrun, restart queue. */
+		if (cpsw_cpdma_read_bd_flags(sc, last_old_slot) & CPDMA_BD_EOQ) {
+			cpsw_write_hdp_slot(sc, &sc->rx, first_new_slot);
+		}
+	}
+	sc->rx.queue_adds += added;
+	sc->rx.active_queue_len += added;
+	if (sc->rx.active_queue_len > sc->rx.max_active_queue_len) {
+		sc->rx.max_active_queue_len = sc->rx.active_queue_len;
+	}
+}
+
+static void
+cpsw_start(struct ifnet *ifp)
+{
+	struct cpsw_softc *sc = ifp->if_softc;
+
+	CPSW_TX_LOCK(sc);
+	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) && sc->tx.running) {
+		cpsw_tx_enqueue(sc);
+		cpsw_tx_dequeue(sc);
+	}
+	CPSW_TX_UNLOCK(sc);
+}
+
+static void
+cpsw_tx_enqueue(struct cpsw_softc *sc)
+{
+	bus_dma_segment_t segs[CPSW_TXFRAGS];
+	struct cpsw_cpdma_bd bd;
+	struct cpsw_slots tmpqueue = STAILQ_HEAD_INITIALIZER(tmpqueue);
+	struct cpsw_slot *slot, *prev_slot = NULL;
+	struct cpsw_slot *last_old_slot, *first_new_slot;
+	struct mbuf *m0;
+	int error, nsegs, seg, added = 0, padlen;
+
+	/* Pull pending packets from IF queue and prep them for DMA. */
+	while ((slot = STAILQ_FIRST(&sc->tx.avail)) != NULL) {
+		IF_DEQUEUE(&sc->ifp->if_snd, m0);
+		if (m0 == NULL)
+			break;
+
+		slot->mbuf = m0;
+		padlen = ETHER_MIN_LEN - slot->mbuf->m_pkthdr.len;
+		if (padlen < 0)
+			padlen = 0;
+
+		/* Create mapping in DMA memory */
+		error = bus_dmamap_load_mbuf_sg(sc->mbuf_dtag, slot->dmamap,
+		    slot->mbuf, segs, &nsegs, BUS_DMA_NOWAIT);
+		/* If the packet is too fragmented, try to simplify. */
+		if (error == EFBIG ||
+		    (error == 0 &&
+			nsegs + (padlen > 0 ? 1 : 0) > sc->tx.avail_queue_len)) {
+			bus_dmamap_unload(sc->mbuf_dtag, slot->dmamap);
+			if (padlen > 0) /* May as well add padding. */
+				m_append(slot->mbuf, padlen,
+				    sc->null_mbuf->m_hdr.mh_data);
+			m0 = m_defrag(slot->mbuf, M_NOWAIT);
+			if (m0 == NULL) {
+				if_printf(sc->ifp,
+				    "Can't defragment packet; dropping\n");
+				m_freem(slot->mbuf);
+			} else {
+				CPSW_DEBUGF(("Requeueing defragmented packet"));
+				IF_PREPEND(&sc->ifp->if_snd, m0);
+			}
+			slot->mbuf = NULL;
+			continue;
+		}
+		if (error != 0) {
+			if_printf(sc->ifp,
+			    "%s: Can't setup DMA (error=%d), dropping packet\n",
+			    __func__, error);
+			bus_dmamap_unload(sc->mbuf_dtag, slot->dmamap);
+			m_freem(slot->mbuf);
+			slot->mbuf = NULL;
+			break;
+		}
+
+		bus_dmamap_sync(sc->mbuf_dtag, slot->dmamap,
+				BUS_DMASYNC_PREWRITE);
+
+
+		CPSW_DEBUGF(("Queueing TX packet: %d segments + %d pad bytes",
+			nsegs, padlen));
+
+		/* If there is only one segment, the for() loop
+		 * gets skipped and the single buffer gets set up
+		 * as both SOP and EOP. */
+		/* Start by setting up the first buffer */
+		bd.next = 0;
+		bd.bufptr = segs[0].ds_addr;
+		bd.bufoff = 0;
+		bd.buflen = segs[0].ds_len;
+		bd.pktlen = m_length(slot->mbuf, NULL) + padlen;
+		bd.flags =  CPDMA_BD_SOP | CPDMA_BD_OWNER;
+		for (seg = 1; seg < nsegs; ++seg) {
+			/* Save the previous buffer (which isn't EOP) */
+			cpsw_cpdma_write_bd(sc, slot, &bd);
+			if (prev_slot != NULL)
+				cpsw_cpdma_write_bd_next(sc, prev_slot, slot);
+			prev_slot = slot;
+			STAILQ_REMOVE_HEAD(&sc->tx.avail, next);
+			sc->tx.avail_queue_len--;
+			STAILQ_INSERT_TAIL(&tmpqueue, slot, next);
+			++added;
+			slot = STAILQ_FIRST(&sc->tx.avail);
+
+			/* Setup next buffer (which isn't SOP) */
+			bd.next = 0;
+			bd.bufptr = segs[seg].ds_addr;
+			bd.bufoff = 0;
+			bd.buflen = segs[seg].ds_len;
+			bd.pktlen = 0;
+			bd.flags = CPDMA_BD_OWNER;
+		}
+		/* Save the final buffer. */
+		if (padlen <= 0)
+			bd.flags |= CPDMA_BD_EOP;
+		cpsw_cpdma_write_bd(sc, slot, &bd);
+		if (prev_slot != NULL)
+			cpsw_cpdma_write_bd_next(sc, prev_slot, slot);
+		prev_slot = slot;
+		STAILQ_REMOVE_HEAD(&sc->tx.avail, next);
+		sc->tx.avail_queue_len--;
+		STAILQ_INSERT_TAIL(&tmpqueue, slot, next);
+		++added;
+
+		if (padlen > 0) {
+			slot = STAILQ_FIRST(&sc->tx.avail);
+			STAILQ_REMOVE_HEAD(&sc->tx.avail, next);
+			sc->tx.avail_queue_len--;
+			STAILQ_INSERT_TAIL(&tmpqueue, slot, next);
+			++added;
+
+			/* Setup buffer of null pad bytes (definitely EOP) */
+			cpsw_cpdma_write_bd_next(sc, prev_slot, slot);
+			prev_slot = slot;
+			bd.next = 0;
+			bd.bufptr = sc->null_mbuf_paddr;
+			bd.bufoff = 0;
+			bd.buflen = padlen;
+			bd.pktlen = 0;
+			bd.flags = CPDMA_BD_EOP | CPDMA_BD_OWNER;
+			cpsw_cpdma_write_bd(sc, slot, &bd);
+			++nsegs;
+		}
+
+		if (nsegs > sc->tx.longest_chain)
+			sc->tx.longest_chain = nsegs;
+
+		// TODO: Should we defer the BPF tap until
+		// after all packets are queued?
+		BPF_MTAP(sc->ifp, m0);
+	}
+
+	/* Attach the list of new buffers to the hardware TX queue. */
+	last_old_slot = STAILQ_LAST(&sc->tx.active, cpsw_slot, next);
+	first_new_slot = STAILQ_FIRST(&tmpqueue);
+	STAILQ_CONCAT(&sc->tx.active, &tmpqueue);
+	if (first_new_slot == NULL) {
+		return;
+	} else if (last_old_slot == NULL) {
+		/* Start a fresh queue. */
+		cpsw_write_hdp_slot(sc, &sc->tx, first_new_slot);
+	} else {
+		/* Add buffers to end of current queue. */
+		cpsw_cpdma_write_bd_next(sc, last_old_slot, first_new_slot);
+		/* If underrun, restart queue. */
+		if (cpsw_cpdma_read_bd_flags(sc, last_old_slot) & CPDMA_BD_EOQ) {
+			cpsw_write_hdp_slot(sc, &sc->tx, first_new_slot);
+		}
+	}
+	sc->tx.queue_adds += added;
+	sc->tx.active_queue_len += added;
+	if (sc->tx.active_queue_len > sc->tx.max_active_queue_len) {
+		sc->tx.max_active_queue_len = sc->tx.active_queue_len;
+	}
+}
+
+static int
+cpsw_tx_dequeue(struct cpsw_softc *sc)
+{
+	struct cpsw_slot *slot, *last_removed_slot = NULL;
+	uint32_t flags, removed = 0;
+
+	slot = STAILQ_FIRST(&sc->tx.active);
+	if (slot == NULL && cpsw_read_cp(sc, &sc->tx) == 0xfffffffc) {
+		CPSW_DEBUGF(("TX teardown of an empty queue"));
+		cpsw_write_cp(sc, &sc->tx, 0xfffffffc);
+		sc->tx.running = 0;
+		return (0);
+	}
+
+	/* Pull completed buffers off the hardware TX queue. */
+	while (slot != NULL) {
+		flags = cpsw_cpdma_read_bd_flags(sc, slot);
+		if (flags & CPDMA_BD_OWNER)
+			break; /* Hardware is still using this packet. */
+
+		CPSW_DEBUGF(("TX removing completed packet"));
+		bus_dmamap_sync(sc->mbuf_dtag, slot->dmamap, BUS_DMASYNC_POSTWRITE);
+		bus_dmamap_unload(sc->mbuf_dtag, slot->dmamap);
+		m_freem(slot->mbuf);
+		slot->mbuf = NULL;
+
+		/* Dequeue any additional buffers used by this packet. */
+		while (slot != NULL && slot->mbuf == NULL) {
+			STAILQ_REMOVE_HEAD(&sc->tx.active, next);
+			STAILQ_INSERT_TAIL(&sc->tx.avail, slot, next);
+			++removed;
+			last_removed_slot = slot;
+			slot = STAILQ_FIRST(&sc->tx.active);
+		}
+
+		/* TearDown complete is only marked on the SOP for the packet. */
+		if (flags & CPDMA_BD_TDOWNCMPLT) {
+			CPSW_DEBUGF(("TX teardown in progress"));
+			cpsw_write_cp(sc, &sc->tx, 0xfffffffc);
+			// TODO: Increment a count of dropped TX packets
+			sc->tx.running = 0;
+			break;
+		}
+	}
+
+	if (removed != 0) {
+		cpsw_write_cp_slot(sc, &sc->tx, last_removed_slot);
+		sc->tx.queue_removes += removed;
+		sc->tx.active_queue_len -= removed;
+		sc->tx.avail_queue_len += removed;
+		if (sc->tx.avail_queue_len > sc->tx.max_avail_queue_len)
+			sc->tx.max_avail_queue_len = sc->tx.avail_queue_len;
+	}
+	return (removed);
+}
+
+/*
+ *
+ * Miscellaneous interrupts.
+ *
+ */
+
+static void
+cpsw_intr_rx_thresh(void *arg)
+{
+	struct cpsw_softc *sc = arg;
+	uint32_t stat = cpsw_read_4(sc, CPSW_WR_C_RX_THRESH_STAT(0));
+
+	CPSW_DEBUGF(("stat=%x", stat));
+	cpsw_write_4(sc, CPSW_CPDMA_CPDMA_EOI_VECTOR, 0);
+}
+
+static void
+cpsw_intr_misc_host_error(struct cpsw_softc *sc)
+{
+	uint32_t intstat;
+	uint32_t dmastat;
+	int txerr, rxerr, txchan, rxchan;
+
+	printf("\n\n");
+	device_printf(sc->dev,
+	    "HOST ERROR:  PROGRAMMING ERROR DETECTED BY HARDWARE\n");
+	printf("\n\n");
+	intstat = cpsw_read_4(sc, CPSW_CPDMA_DMA_INTSTAT_MASKED);
+	device_printf(sc->dev, "CPSW_CPDMA_DMA_INTSTAT_MASKED=0x%x\n", intstat);
+	dmastat = cpsw_read_4(sc, CPSW_CPDMA_DMASTATUS);
+	device_printf(sc->dev, "CPSW_CPDMA_DMASTATUS=0x%x\n", dmastat);
+
+	txerr = (dmastat >> 20) & 15;
+	txchan = (dmastat >> 16) & 7;
+	rxerr = (dmastat >> 12) & 15;
+	rxchan = (dmastat >> 8) & 7;
+
+	switch (txerr) {
+	case 0: break;
+	case 1:	printf("SOP error on TX channel %d\n", txchan);
+		break;
+	case 2:	printf("Ownership bit not set on SOP buffer on TX channel %d\n", txchan);
+		break;
+	case 3:	printf("Zero Next Buffer but not EOP on TX channel %d\n", txchan);
+		break;
+	case 4:	printf("Zero Buffer Pointer on TX channel %d\n", txchan);
+		break;
+	case 5:	printf("Zero Buffer Length on TX channel %d\n", txchan);
+		break;
+	case 6:	printf("Packet length error on TX channel %d\n", txchan);
+		break;
+	default: printf("Unknown error on TX channel %d\n", txchan);
+		break;
+	}
+
+	if (txerr != 0) {
+		printf("CPSW_CPDMA_TX%d_HDP=0x%x\n",
+		    txchan, cpsw_read_4(sc, CPSW_CPDMA_TX_HDP(txchan)));
+		printf("CPSW_CPDMA_TX%d_CP=0x%x\n",
+		    txchan, cpsw_read_4(sc, CPSW_CPDMA_TX_CP(txchan)));
+		cpsw_dump_queue(sc, &sc->tx.active);
+	}
+
+	switch (rxerr) {
+	case 0: break;
+	case 2:	printf("Ownership bit not set on RX channel %d\n", rxchan);
+		break;
+	case 4:	printf("Zero Buffer Pointer on RX channel %d\n", rxchan);
+		break;
+	case 5:	printf("Zero Buffer Length on RX channel %d\n", rxchan);
+		break;
+	case 6:	printf("Buffer offset too big on RX channel %d\n", rxchan);
+		break;
+	default: printf("Unknown RX error on RX channel %d\n", rxchan);
+		break;
+	}
+
+	if (rxerr != 0) {
+		printf("CPSW_CPDMA_RX%d_HDP=0x%x\n",
+		    rxchan, cpsw_read_4(sc,CPSW_CPDMA_RX_HDP(rxchan)));
+		printf("CPSW_CPDMA_RX%d_CP=0x%x\n",
+		    rxchan, cpsw_read_4(sc, CPSW_CPDMA_RX_CP(rxchan)));
+		cpsw_dump_queue(sc, &sc->rx.active);
+	}
+
+	printf("\nALE Table\n");
+	cpsw_ale_dump_table(sc);
+
+	// XXX do something useful here??
+	panic("CPSW HOST ERROR INTERRUPT");
+
+	// Suppress this interrupt in the future.
+	cpsw_write_4(sc, CPSW_CPDMA_DMA_INTMASK_CLEAR, intstat);
+	printf("XXX HOST ERROR INTERRUPT SUPPRESSED\n");
+	// The watchdog will probably reset the controller
+	// in a little while.  It will probably fail again.
+}
+
+static void
+cpsw_intr_misc(void *arg)
+{
+	struct cpsw_softc *sc = arg;
+	uint32_t stat = cpsw_read_4(sc, CPSW_WR_C_MISC_STAT(0));
+
+	if (stat & 16)
+		CPSW_DEBUGF(("Time sync event interrupt unimplemented"));
+	if (stat & 8)
+		cpsw_stats_collect(sc);
+	if (stat & 4)
+		cpsw_intr_misc_host_error(sc);
+	if (stat & 2)
+		CPSW_DEBUGF(("MDIO link change interrupt unimplemented"));
+	if (stat & 1)
+		CPSW_DEBUGF(("MDIO operation completed interrupt unimplemented"));
+	cpsw_write_4(sc, CPSW_CPDMA_CPDMA_EOI_VECTOR, 3);
+}
+
+/*
+ *
+ * Periodic Checks and Watchdog.
+ *
+ */
+
+static void
+cpsw_tick(void *msc)
+{
+	struct cpsw_softc *sc = msc;
+
+	/* Check for TX timeout */
+	cpsw_tx_watchdog(sc);
+
+	/* Check for media type change */
+	mii_tick(sc->mii);
+	if(sc->cpsw_media_status != sc->mii->mii_media.ifm_media) {
+		printf("%s: media type changed (ifm_media=%x)\n", __func__, 
+			sc->mii->mii_media.ifm_media);
+		cpsw_ifmedia_upd(sc->ifp);
+	}
+
+	/* Schedule another timeout one second from now */
+	callout_reset(&sc->watchdog.callout, hz, cpsw_tick, sc);
+}
+
+static void
+cpsw_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
+{
+	struct cpsw_softc *sc = ifp->if_softc;
+	struct mii_data *mii;
+
+	CPSW_DEBUGF((""));
+	CPSW_TX_LOCK(sc);
+
+	mii = sc->mii;
+	mii_pollstat(mii);
+
+	ifmr->ifm_active = mii->mii_media_active;
+	ifmr->ifm_status = mii->mii_media_status;
+
+	CPSW_TX_UNLOCK(sc);
+}
+
+static int
+cpsw_ifmedia_upd(struct ifnet *ifp)
+{
+	struct cpsw_softc *sc = ifp->if_softc;
+
+	CPSW_DEBUGF((""));
+	if (ifp->if_flags & IFF_UP) {
+		CPSW_GLOBAL_LOCK(sc);
+		sc->cpsw_media_status = sc->mii->mii_media.ifm_media;
+		mii_mediachg(sc->mii);
+		cpsw_init_locked(sc);
+		CPSW_GLOBAL_UNLOCK(sc);
+	}
+
+	return (0);
+}
+
+static void
+cpsw_tx_watchdog_full_reset(struct cpsw_softc *sc)
+{
+	cpsw_debugf_head("CPSW watchdog");
+	if_printf(sc->ifp, "watchdog timeout\n");
+	cpsw_shutdown_locked(sc);
+	cpsw_init_locked(sc);
+}
+
+static void
+cpsw_tx_watchdog(struct cpsw_softc *sc)
+{
+	struct ifnet *ifp = sc->ifp;
+
+	CPSW_GLOBAL_LOCK(sc);
+	if (sc->tx.active_queue_len == 0 || (ifp->if_flags & IFF_UP) == 0 ||
+	    (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || !sc->tx.running) {
+		sc->watchdog.timer = 0; /* Nothing to do. */
+	} else if (sc->tx.queue_removes > sc->tx.queue_removes_at_last_tick) {
+		sc->watchdog.timer = 0;  /* Stuff done while we weren't looking. */
+	} else if (cpsw_tx_dequeue(sc) > 0) {
+		sc->watchdog.timer = 0;  /* We just did something. */
+	} else {
+		/* There was something to do but it didn't get done. */
+		++sc->watchdog.timer;
+		if (sc->watchdog.timer > 2) {
+			sc->watchdog.timer = 0;
+			++ifp->if_oerrors;
+			++sc->watchdog.resets;
+			cpsw_tx_watchdog_full_reset(sc);
+		}
+	}
+	sc->tx.queue_removes_at_last_tick = sc->tx.queue_removes;
+	CPSW_GLOBAL_UNLOCK(sc);
+}
+
+/*
+ *
+ * ALE support routines.
+ *
+ */
+
+static void
+cpsw_ale_read_entry(struct cpsw_softc *sc, uint16_t idx, uint32_t *ale_entry)
+{
+	cpsw_write_4(sc, CPSW_ALE_TBLCTL, idx & 1023);
+	ale_entry[0] = cpsw_read_4(sc, CPSW_ALE_TBLW0);
+	ale_entry[1] = cpsw_read_4(sc, CPSW_ALE_TBLW1);
+	ale_entry[2] = cpsw_read_4(sc, CPSW_ALE_TBLW2);
+}
+
+static void
+cpsw_ale_write_entry(struct cpsw_softc *sc, uint16_t idx, uint32_t *ale_entry)
+{
+	cpsw_write_4(sc, CPSW_ALE_TBLW0, ale_entry[0]);
+	cpsw_write_4(sc, CPSW_ALE_TBLW1, ale_entry[1]);
+	cpsw_write_4(sc, CPSW_ALE_TBLW2, ale_entry[2]);
+	cpsw_write_4(sc, CPSW_ALE_TBLCTL, 1 << 31 | (idx & 1023));
+}
+
+static int
+cpsw_ale_remove_all_mc_entries(struct cpsw_softc *sc)
+{
+	int i;
+	uint32_t ale_entry[3];
+
+	/* First two entries are link address and broadcast. */
+	for (i = 2; i < CPSW_MAX_ALE_ENTRIES; i++) {
+		cpsw_ale_read_entry(sc, i, ale_entry);
+		if (((ale_entry[1] >> 28) & 3) == 1 && /* Address entry */
+		    ((ale_entry[1] >> 8) & 1) == 1) { /* MCast link addr */
+			ale_entry[0] = ale_entry[1] = ale_entry[2] = 0;
+			cpsw_ale_write_entry(sc, i, ale_entry);
+		}
+	}
+	return CPSW_MAX_ALE_ENTRIES;
+}
+
+static int
+cpsw_ale_mc_entry_set(struct cpsw_softc *sc, uint8_t portmap, uint8_t *mac)
+{
+	int free_index = -1, matching_index = -1, i;
+	uint32_t ale_entry[3];
+
+	/* Find a matching entry or a free entry. */
+	for (i = 0; i < CPSW_MAX_ALE_ENTRIES; i++) {
+		cpsw_ale_read_entry(sc, i, ale_entry);
+
+		/* Entry Type[61:60] is 0 for free entry */ 
+		if (free_index < 0 && ((ale_entry[1] >> 28) & 3) == 0) {
+			free_index = i;
+		}
+
+		if ((((ale_entry[1] >> 8) & 0xFF) == mac[0]) &&
+		    (((ale_entry[1] >> 0) & 0xFF) == mac[1]) &&
+		    (((ale_entry[0] >>24) & 0xFF) == mac[2]) &&
+		    (((ale_entry[0] >>16) & 0xFF) == mac[3]) &&
+		    (((ale_entry[0] >> 8) & 0xFF) == mac[4]) &&
+		    (((ale_entry[0] >> 0) & 0xFF) == mac[5])) {
+			matching_index = i;
+			break;
+		}
+	}
+
+	if (matching_index < 0) {
+		if (free_index < 0)
+			return (ENOMEM);
+		i = free_index;
+	}
+
+	/* Set MAC address */
+	ale_entry[0] = mac[2] << 24 | mac[3] << 16 | mac[4] << 8 | mac[5];
+	ale_entry[1] = mac[0] << 8 | mac[1];
+
+	/* Entry type[61:60] is addr entry(1), Mcast fwd state[63:62] is fw(3)*/
+	ale_entry[1] |= 0xd0 << 24;
+
+	/* Set portmask [68:66] */
+	ale_entry[2] = (portmap & 7) << 2;
+
+	cpsw_ale_write_entry(sc, i, ale_entry);
+
+	return 0;
+}
+
+static void
+cpsw_ale_dump_table(struct cpsw_softc *sc) {
+	int i;
+	uint32_t ale_entry[3];
+	for (i = 0; i < CPSW_MAX_ALE_ENTRIES; i++) {
+		cpsw_ale_read_entry(sc, i, ale_entry);
+		if (ale_entry[0] || ale_entry[1] || ale_entry[2]) {
+			printf("ALE[%4u] %08x %08x %08x ", i, ale_entry[0],
+				ale_entry[1], ale_entry[2]);
+			printf("mac: %02x:%02x:%02x:%02x:%02x:%02x ",
+				(ale_entry[1] >> 8) & 0xFF,
+				(ale_entry[1] >> 0) & 0xFF,
+				(ale_entry[0] >>24) & 0xFF,
+				(ale_entry[0] >>16) & 0xFF,
+				(ale_entry[0] >> 8) & 0xFF,
+				(ale_entry[0] >> 0) & 0xFF);
+			printf(((ale_entry[1] >> 8) & 1) ? "mcast " : "ucast ");
+			printf("type: %u ", (ale_entry[1] >> 28) & 3);
+			printf("port: %u ", (ale_entry[2] >> 2) & 7);
+			printf("\n");
+		}
+	}
+	printf("\n");
+}
+
+static int
+cpsw_ale_update_addresses(struct cpsw_softc *sc, int purge)
+{
+	uint8_t *mac;
+	uint32_t ale_entry[3];
+	struct ifnet *ifp = sc->ifp;
+	struct ifmultiaddr *ifma;
+	int i;
+
+	/* Route incoming packets for our MAC address to Port 0 (host). */
+	/* For simplicity, keep this entry at table index 0 in the ALE. */
+        if_addr_rlock(ifp);
+	mac = LLADDR((struct sockaddr_dl *)ifp->if_addr->ifa_addr);
+	ale_entry[0] = mac[2] << 24 | mac[3] << 16 | mac[4] << 8 | mac[5];
+	ale_entry[1] = 0x10 << 24 | mac[0] << 8 | mac[1]; /* addr entry + mac */
+	ale_entry[2] = 0; /* port = 0 */
+	cpsw_ale_write_entry(sc, 0, ale_entry);
+
+	/* Set outgoing MAC Address for Ports 1 and 2. */
+	for (i = 1; i < 3; ++i) {
+		cpsw_write_4(sc, CPSW_PORT_P_SA_HI(i),
+		    mac[3] << 24 | mac[2] << 16 | mac[1] << 8 | mac[0]);
+		cpsw_write_4(sc, CPSW_PORT_P_SA_LO(i),
+		    mac[5] << 8 | mac[4]);
+	}
+        if_addr_runlock(ifp);
+
+	/* Keep the broadcast address at table entry 1. */
+	ale_entry[0] = 0xffffffff; /* Lower 32 bits of MAC */
+	ale_entry[1] = 0xd000ffff; /* FW (3 << 30), Addr entry (1 << 24), upper 16 bits of Mac */ 
+	ale_entry[2] = 0x0000001c; /* Forward to all ports */
+	cpsw_ale_write_entry(sc, 1, ale_entry);
+
+	/* SIOCDELMULTI doesn't specify the particular address
+	   being removed, so we have to remove all and rebuild. */
+	if (purge)
+		cpsw_ale_remove_all_mc_entries(sc);
+
+        /* Set other multicast addrs desired. */
+        if_maddr_rlock(ifp);
+        TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
+                if (ifma->ifma_addr->sa_family != AF_LINK)
+                        continue;
+		cpsw_ale_mc_entry_set(sc, 7,
+		    LLADDR((struct sockaddr_dl *)ifma->ifma_addr));
+        }
+        if_maddr_runlock(ifp);
+
+	return (0);
+}
+
+/*
+ *
+ * Statistics and Sysctls.
+ *
+ */
+
+#if 0
+static void
+cpsw_stats_dump(struct cpsw_softc *sc)
+{
+	int i;
+	uint32_t r;
+
+	for (i = 0; i < CPSW_SYSCTL_COUNT; ++i) {
+		r = cpsw_read_4(sc, CPSW_STATS_OFFSET +
+		    cpsw_stat_sysctls[i].reg);
+		CPSW_DEBUGF(("%s: %ju + %u = %ju", cpsw_stat_sysctls[i].oid,
+			     (intmax_t)sc->shadow_stats[i], r,
+			     (intmax_t)sc->shadow_stats[i] + r));
+	}
+}
+#endif
+
+static void
+cpsw_stats_collect(struct cpsw_softc *sc)
+{
+	int i;
+	uint32_t r;
+
+	CPSW_DEBUGF(("Controller shadow statistics updated."));
+
+	for (i = 0; i < CPSW_SYSCTL_COUNT; ++i) {
+		r = cpsw_read_4(sc, CPSW_STATS_OFFSET +
+		    cpsw_stat_sysctls[i].reg);
+		sc->shadow_stats[i] += r;
+		cpsw_write_4(sc, CPSW_STATS_OFFSET + cpsw_stat_sysctls[i].reg, r);
+	}
+}
+
+static int
+cpsw_stats_sysctl(SYSCTL_HANDLER_ARGS)
+{
+	struct cpsw_softc *sc;
+	struct cpsw_stat *stat;
+	uint64_t result;
+
+	sc = (struct cpsw_softc *)arg1;
+	stat = &cpsw_stat_sysctls[oidp->oid_number];
+	result = sc->shadow_stats[oidp->oid_number];
+	result += cpsw_read_4(sc, CPSW_STATS_OFFSET + stat->reg);
+	return (sysctl_handle_64(oidp, &result, 0, req));
+}
+
+static int
+cpsw_stat_attached(SYSCTL_HANDLER_ARGS)
+{
+	struct cpsw_softc *sc;
+	struct bintime t;
+	unsigned result;
+
+	sc = (struct cpsw_softc *)arg1;
+	getbinuptime(&t);
+	bintime_sub(&t, &sc->attach_uptime);
+	result = t.sec;
+	return (sysctl_handle_int(oidp, &result, 0, req));
+}
+
+static int
+cpsw_stat_uptime(SYSCTL_HANDLER_ARGS)
+{
+	struct cpsw_softc *sc;
+	struct bintime t;
+	unsigned result;
+
+	sc = (struct cpsw_softc *)arg1;
+	if (sc->ifp->if_drv_flags & IFF_DRV_RUNNING) {
+		getbinuptime(&t);
+		bintime_sub(&t, &sc->init_uptime);
+		result = t.sec;
+	} else
+		result = 0;
+	return (sysctl_handle_int(oidp, &result, 0, req));
+}
+
+static void
+cpsw_add_queue_sysctls(struct sysctl_ctx_list *ctx, struct sysctl_oid *node, struct cpsw_queue *queue)
+{
+	struct sysctl_oid_list *parent;
+
+	parent = SYSCTL_CHILDREN(node);
+	SYSCTL_ADD_INT(ctx, parent, OID_AUTO, "totalBuffers",
+	    CTLFLAG_RD, &queue->queue_slots, 0,
+	    "Total buffers currently assigned to this queue");
+	SYSCTL_ADD_INT(ctx, parent, OID_AUTO, "activeBuffers",
+	    CTLFLAG_RD, &queue->active_queue_len, 0,
+	    "Buffers currently registered with hardware controller");
+	SYSCTL_ADD_INT(ctx, parent, OID_AUTO, "maxActiveBuffers",
+	    CTLFLAG_RD, &queue->max_active_queue_len, 0,
+	    "Max value of activeBuffers since last driver reset");
+	SYSCTL_ADD_INT(ctx, parent, OID_AUTO, "availBuffers",
+	    CTLFLAG_RD, &queue->avail_queue_len, 0,
+	    "Buffers allocated to this queue but not currently "
+	    "registered with hardware controller");
+	SYSCTL_ADD_INT(ctx, parent, OID_AUTO, "maxAvailBuffers",
+	    CTLFLAG_RD, &queue->max_avail_queue_len, 0,
+	    "Max value of availBuffers since last driver reset");
+	SYSCTL_ADD_UINT(ctx, parent, OID_AUTO, "totalEnqueued",
+	    CTLFLAG_RD, &queue->queue_adds, 0,
+	    "Total buffers added to queue");
+	SYSCTL_ADD_UINT(ctx, parent, OID_AUTO, "totalDequeued",
+	    CTLFLAG_RD, &queue->queue_removes, 0,
+	    "Total buffers removed from queue");
+	SYSCTL_ADD_UINT(ctx, parent, OID_AUTO, "longestChain",
+	    CTLFLAG_RD, &queue->longest_chain, 0,
+	    "Max buffers used for a single packet");
+}
+
+static void
+cpsw_add_watchdog_sysctls(struct sysctl_ctx_list *ctx, struct sysctl_oid *node, struct cpsw_softc *sc)
+{
+	struct sysctl_oid_list *parent;
+
+	parent = SYSCTL_CHILDREN(node);
+	SYSCTL_ADD_INT(ctx, parent, OID_AUTO, "resets",
+	    CTLFLAG_RD, &sc->watchdog.resets, 0,
+	    "Total number of watchdog resets");
+}
+
+static void
+cpsw_add_sysctls(struct cpsw_softc *sc)
+{
+	struct sysctl_ctx_list *ctx;
+	struct sysctl_oid *stats_node, *queue_node, *node;
+	struct sysctl_oid_list *parent, *stats_parent, *queue_parent;
+	int i;
+
+	ctx = device_get_sysctl_ctx(sc->dev);
+	parent = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->dev));
+
+	SYSCTL_ADD_PROC(ctx, parent, OID_AUTO, "attachedSecs",
+	    CTLTYPE_UINT | CTLFLAG_RD, sc, 0, cpsw_stat_attached, "IU",
+	    "Time since driver attach");
+
+	SYSCTL_ADD_PROC(ctx, parent, OID_AUTO, "uptime",
+	    CTLTYPE_UINT | CTLFLAG_RD, sc, 0, cpsw_stat_uptime, "IU",
+	    "Seconds since driver init");
+
+	stats_node = SYSCTL_ADD_NODE(ctx, parent, OID_AUTO, "stats",
+				     CTLFLAG_RD, NULL, "CPSW Statistics");
+	stats_parent = SYSCTL_CHILDREN(stats_node);
+	for (i = 0; i < CPSW_SYSCTL_COUNT; ++i) {
+		SYSCTL_ADD_PROC(ctx, stats_parent, i,
+				cpsw_stat_sysctls[i].oid,
+				CTLTYPE_U64 | CTLFLAG_RD, sc, 0,
+				cpsw_stats_sysctl, "IU",
+				cpsw_stat_sysctls[i].oid);
+	}
+
+	queue_node = SYSCTL_ADD_NODE(ctx, parent, OID_AUTO, "queue",
+	    CTLFLAG_RD, NULL, "CPSW Queue Statistics");
+	queue_parent = SYSCTL_CHILDREN(queue_node);
+
+	node = SYSCTL_ADD_NODE(ctx, queue_parent, OID_AUTO, "tx",
+	    CTLFLAG_RD, NULL, "TX Queue Statistics");
+	cpsw_add_queue_sysctls(ctx, node, &sc->tx);
+
+	node = SYSCTL_ADD_NODE(ctx, queue_parent, OID_AUTO, "rx",
+	    CTLFLAG_RD, NULL, "RX Queue Statistics");
+	cpsw_add_queue_sysctls(ctx, node, &sc->rx);
+
+	node = SYSCTL_ADD_NODE(ctx, parent, OID_AUTO, "watchdog",
+	    CTLFLAG_RD, NULL, "Watchdog Statistics");
+	cpsw_add_watchdog_sysctls(ctx, node, sc);
+}
+


Property changes on: trunk/sys/arm/ti/cpsw/if_cpsw.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/cpsw/if_cpswreg.h
===================================================================
--- trunk/sys/arm/ti/cpsw/if_cpswreg.h	                        (rev 0)
+++ trunk/sys/arm/ti/cpsw/if_cpswreg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,138 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Damjan Marion <dmarion at Freebsd.org>
+ * 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: stable/10/sys/arm/ti/cpsw/if_cpswreg.h 246276 2013-02-03 01:08:01Z kientzle $
+ */
+
+#ifndef	_IF_CPSWREG_H
+#define	_IF_CPSWREG_H
+
+#define CPSW_SS_OFFSET			0x0000
+#define CPSW_SS_IDVER			(CPSW_SS_OFFSET + 0x00)
+#define CPSW_SS_SOFT_RESET		(CPSW_SS_OFFSET + 0x08)
+#define CPSW_SS_STAT_PORT_EN		(CPSW_SS_OFFSET + 0x0C)
+#define CPSW_SS_PTYPE			(CPSW_SS_OFFSET + 0x10)
+#define	CPSW_SS_FLOW_CONTROL		(CPSW_SS_OFFSET + 0x24)
+
+#define CPSW_PORT_OFFSET		0x0100
+#define	CPSW_PORT_P_MAX_BLKS(p)		(CPSW_PORT_OFFSET + 0x08 + ((p) * 0x100))
+#define	CPSW_PORT_P_BLK_CNT(p)		(CPSW_PORT_OFFSET + 0x0C + ((p) * 0x100))
+#define CPSW_PORT_P_TX_PRI_MAP(p)	(CPSW_PORT_OFFSET + 0x118 + ((p-1) * 0x100))
+#define CPSW_PORT_P0_CPDMA_TX_PRI_MAP	(CPSW_PORT_OFFSET + 0x01C)
+#define CPSW_PORT_P0_CPDMA_RX_CH_MAP	(CPSW_PORT_OFFSET + 0x020)
+#define CPSW_PORT_P_SA_LO(p)		(CPSW_PORT_OFFSET + 0x120 + ((p-1) * 0x100))
+#define CPSW_PORT_P_SA_HI(p)		(CPSW_PORT_OFFSET + 0x124 + ((p-1) * 0x100))
+
+#define CPSW_CPDMA_OFFSET		0x0800
+#define CPSW_CPDMA_TX_CONTROL		(CPSW_CPDMA_OFFSET + 0x04)
+#define CPSW_CPDMA_TX_TEARDOWN		(CPSW_CPDMA_OFFSET + 0x08)
+#define CPSW_CPDMA_RX_CONTROL		(CPSW_CPDMA_OFFSET + 0x14)
+#define CPSW_CPDMA_RX_TEARDOWN		(CPSW_CPDMA_OFFSET + 0x18)
+#define CPSW_CPDMA_SOFT_RESET		(CPSW_CPDMA_OFFSET + 0x1c)
+#define CPSW_CPDMA_DMACONTROL		(CPSW_CPDMA_OFFSET + 0x20)
+#define CPSW_CPDMA_DMASTATUS		(CPSW_CPDMA_OFFSET + 0x24)
+#define CPSW_CPDMA_RX_BUFFER_OFFSET	(CPSW_CPDMA_OFFSET + 0x28)
+#define CPSW_CPDMA_TX_INTSTAT_RAW	(CPSW_CPDMA_OFFSET + 0x80)
+#define CPSW_CPDMA_TX_INTSTAT_MASKED	(CPSW_CPDMA_OFFSET + 0x84)
+#define CPSW_CPDMA_TX_INTMASK_SET	(CPSW_CPDMA_OFFSET + 0x88)
+#define CPSW_CPDMA_TX_INTMASK_CLEAR	(CPSW_CPDMA_OFFSET + 0x8C)
+#define CPSW_CPDMA_CPDMA_EOI_VECTOR	(CPSW_CPDMA_OFFSET + 0x94)
+#define CPSW_CPDMA_RX_INTSTAT_RAW	(CPSW_CPDMA_OFFSET + 0xA0)
+#define CPSW_CPDMA_RX_INTSTAT_MASKED	(CPSW_CPDMA_OFFSET + 0xA4)
+#define CPSW_CPDMA_RX_INTMASK_SET	(CPSW_CPDMA_OFFSET + 0xA8)
+#define CPSW_CPDMA_RX_INTMASK_CLEAR	(CPSW_CPDMA_OFFSET + 0xAc)
+#define CPSW_CPDMA_DMA_INTSTAT_RAW	(CPSW_CPDMA_OFFSET + 0xB0)
+#define CPSW_CPDMA_DMA_INTSTAT_MASKED	(CPSW_CPDMA_OFFSET + 0xB4)
+#define CPSW_CPDMA_DMA_INTMASK_SET	(CPSW_CPDMA_OFFSET + 0xB8)
+#define CPSW_CPDMA_DMA_INTMASK_CLEAR	(CPSW_CPDMA_OFFSET + 0xBC)
+#define CPSW_CPDMA_RX_FREEBUFFER(p)	(CPSW_CPDMA_OFFSET + 0x0e0 + ((p) * 0x04))
+
+#define CPSW_STATS_OFFSET		0x0900
+
+#define CPSW_STATERAM_OFFSET		0x0A00
+#define CPSW_CPDMA_TX_HDP(p)		(CPSW_STATERAM_OFFSET + 0x00 + ((p) * 0x04))
+#define CPSW_CPDMA_RX_HDP(p)		(CPSW_STATERAM_OFFSET + 0x20 + ((p) * 0x04))
+#define CPSW_CPDMA_TX_CP(p)		(CPSW_STATERAM_OFFSET + 0x40 + ((p) * 0x04))
+#define CPSW_CPDMA_RX_CP(p)		(CPSW_STATERAM_OFFSET + 0x60 + ((p) * 0x04))
+
+#define CPSW_CPTS_OFFSET		0x0C00
+
+#define CPSW_ALE_OFFSET			0x0D00
+#define CPSW_ALE_CONTROL		(CPSW_ALE_OFFSET + 0x08)
+#define CPSW_ALE_TBLCTL			(CPSW_ALE_OFFSET + 0x20)
+#define CPSW_ALE_TBLW2			(CPSW_ALE_OFFSET + 0x34)
+#define CPSW_ALE_TBLW1			(CPSW_ALE_OFFSET + 0x38)
+#define CPSW_ALE_TBLW0			(CPSW_ALE_OFFSET + 0x3C)
+#define CPSW_ALE_PORTCTL(p)		(CPSW_ALE_OFFSET + 0x40 + ((p) * 0x04))
+
+/* SL1 is at 0x0D80, SL2 is at 0x0DC0 */
+#define CPSW_SL_OFFSET			0x0D80
+#define CPSW_SL_MACCONTROL(p)		(CPSW_SL_OFFSET + (0x40 * (p)) + 0x04)
+#define CPSW_SL_MACSTATUS(p)		(CPSW_SL_OFFSET + (0x40 * (p)) + 0x08)
+#define CPSW_SL_SOFT_RESET(p)		(CPSW_SL_OFFSET + (0x40 * (p)) + 0x0C)
+#define CPSW_SL_RX_MAXLEN(p)		(CPSW_SL_OFFSET + (0x40 * (p)) + 0x10)
+#define CPSW_SL_RX_PAUSE(p)		(CPSW_SL_OFFSET + (0x40 * (p)) + 0x18)
+#define CPSW_SL_TX_PAUSE(p)		(CPSW_SL_OFFSET + (0x40 * (p)) + 0x1C)
+#define CPSW_SL_RX_PRI_MAP(p)		(CPSW_SL_OFFSET + (0x40 * (p)) + 0x24)
+
+#define MDIO_OFFSET			0x1000
+#define MDIOCONTROL			(MDIO_OFFSET + 0x04)
+#define MDIOUSERACCESS0			(MDIO_OFFSET + 0x80)
+#define MDIOUSERPHYSEL0			(MDIO_OFFSET + 0x84)
+
+#define CPSW_WR_OFFSET			0x1200
+#define CPSW_WR_SOFT_RESET		(CPSW_WR_OFFSET + 0x04)
+#define CPSW_WR_CONTROL			(CPSW_WR_OFFSET + 0x08)
+#define CPSW_WR_INT_CONTROL		(CPSW_WR_OFFSET + 0x0c)
+#define CPSW_WR_C_RX_THRESH_EN(p)	(CPSW_WR_OFFSET + (0x10 * (p)) + 0x10)
+#define CPSW_WR_C_RX_EN(p)		(CPSW_WR_OFFSET + (0x10 * (p)) + 0x14)
+#define CPSW_WR_C_TX_EN(p)		(CPSW_WR_OFFSET + (0x10 * (p)) + 0x18)
+#define CPSW_WR_C_MISC_EN(p)		(CPSW_WR_OFFSET + (0x10 * (p)) + 0x1C)
+#define CPSW_WR_C_RX_THRESH_STAT(p)	(CPSW_WR_OFFSET + (0x10 * (p)) + 0x40)
+#define CPSW_WR_C_RX_STAT(p)		(CPSW_WR_OFFSET + (0x10 * (p)) + 0x44)
+#define CPSW_WR_C_TX_STAT(p)		(CPSW_WR_OFFSET + (0x10 * (p)) + 0x48)
+#define CPSW_WR_C_MISC_STAT(p)		(CPSW_WR_OFFSET + (0x10 * (p)) + 0x4C)
+
+#define CPSW_CPPI_RAM_OFFSET		0x2000
+#define	CPSW_CPPI_RAM_SIZE		0x2000
+
+#define CPDMA_BD_SOP		(1<<15)
+#define CPDMA_BD_EOP		(1<<14)
+#define CPDMA_BD_OWNER		(1<<13)
+#define CPDMA_BD_EOQ		(1<<12)
+#define CPDMA_BD_TDOWNCMPLT	(1<<11)
+#define CPDMA_BD_PKT_ERR_MASK	(3<< 4)
+
+struct cpsw_cpdma_bd {
+	volatile uint32_t next;
+	volatile uint32_t bufptr;
+	volatile uint16_t buflen;
+	volatile uint16_t bufoff;
+	volatile uint16_t pktlen;
+	volatile uint16_t flags;
+};
+
+#endif /*_IF_CPSWREG_H */


Property changes on: trunk/sys/arm/ti/cpsw/if_cpswreg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/cpsw/if_cpswvar.h
===================================================================
--- trunk/sys/arm/ti/cpsw/if_cpswvar.h	                        (rev 0)
+++ trunk/sys/arm/ti/cpsw/if_cpswvar.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,125 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Damjan Marion <dmarion at Freebsd.org>
+ * 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: stable/10/sys/arm/ti/cpsw/if_cpswvar.h 246276 2013-02-03 01:08:01Z kientzle $
+ */
+
+#ifndef	_IF_CPSWVAR_H
+#define	_IF_CPSWVAR_H
+
+#define CPSW_INTR_COUNT		4
+
+/* MII BUS  */
+#define CPSW_MIIBUS_RETRIES	5
+#define CPSW_MIIBUS_DELAY	1000
+
+#define CPSW_MAX_ALE_ENTRIES	1024
+
+#define CPSW_SYSCTL_COUNT 34
+
+struct cpsw_slot {
+	uint32_t bd_offset;  /* Offset of corresponding BD within CPPI RAM. */
+	bus_dmamap_t dmamap;
+	struct mbuf *mbuf;
+	STAILQ_ENTRY(cpsw_slot) next;
+};
+STAILQ_HEAD(cpsw_slots, cpsw_slot);
+
+struct cpsw_queue {
+	struct mtx	lock;
+	int		running;
+	struct cpsw_slots active;
+	struct cpsw_slots avail;
+	uint32_t	queue_adds; /* total bufs added */
+	uint32_t	queue_removes; /* total bufs removed */
+	uint32_t	queue_removes_at_last_tick; /* Used by watchdog */
+	int		queue_slots;
+	int		active_queue_len;
+	int		max_active_queue_len;
+	int		avail_queue_len;
+	int		max_avail_queue_len;
+	int		longest_chain; /* Largest # segments in a single packet. */
+	int		hdp_offset;
+};
+
+struct cpsw_softc {
+	struct ifnet	*ifp;
+	phandle_t	node;
+	device_t	dev;
+	struct bintime	attach_uptime; /* system uptime when attach happened. */
+	struct bintime	init_uptime; /* system uptime when init happened. */
+
+	/* TODO: We should set up a child structure for each port;
+	   store mac, phy information, etc, in that structure. */
+	uint8_t		mac_addr[ETHER_ADDR_LEN];
+
+	device_t	miibus;
+	struct mii_data	*mii;
+	/* We expect 1 memory resource and 4 interrupts from the device tree. */
+	struct resource	*res[1 + CPSW_INTR_COUNT];
+
+	/* Interrupts get recorded here as we initialize them. */
+	/* Interrupt teardown just walks this list. */
+	struct {
+		struct resource *res;
+		void		*ih_cookie;
+		const char *description;
+	} interrupts[CPSW_INTR_COUNT];
+	int		interrupt_count;
+
+	uint32_t	cpsw_if_flags;
+	int		cpsw_media_status;
+
+	struct {
+		int resets;
+		int timer;
+		struct callout	callout;
+	} watchdog;
+
+	bus_dma_tag_t	mbuf_dtag;
+
+	/* An mbuf full of nulls for TX padding. */
+	bus_dmamap_t null_mbuf_dmamap;
+	struct mbuf *null_mbuf;
+	bus_addr_t null_mbuf_paddr;
+
+	/* RX and TX buffer tracking */
+	struct cpsw_queue rx, tx;
+
+	/* 64-bit versions of 32-bit hardware statistics counters */
+	uint64_t shadow_stats[CPSW_SYSCTL_COUNT];
+
+	/* CPPI STATERAM has 512 slots for building TX/RX queues. */
+	/* TODO: Size here supposedly varies with different versions
+	   of the controller.  Check DaVinci specs and find a good
+	   way to adjust this.  One option is to have a separate
+	   Device Tree parameter for number slots; another option
+	   is to calculate it from the memory size in the device tree. */
+	struct cpsw_slot _slots[CPSW_CPPI_RAM_SIZE / sizeof(struct cpsw_cpdma_bd)];
+	struct cpsw_slots avail;
+};
+
+#endif /*_IF_CPSWVAR_H */


Property changes on: trunk/sys/arm/ti/cpsw/if_cpswvar.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/files.ti
===================================================================
--- trunk/sys/arm/ti/files.ti	                        (rev 0)
+++ trunk/sys/arm/ti/files.ti	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,28 @@
+#$FreeBSD: stable/10/sys/arm/ti/files.ti 278727 2015-02-13 22:32:02Z ian $
+
+kern/kern_clocksource.c				standard
+
+arm/arm/bus_space_base.c			standard
+arm/arm/bus_space_generic.c			standard
+arm/arm/bus_space_asm_generic.S			standard
+arm/arm/cpufunc_asm_armv5.S			standard
+arm/arm/cpufunc_asm_arm10.S			standard
+arm/arm/cpufunc_asm_arm11.S			standard
+arm/arm/cpufunc_asm_armv7.S			standard
+
+arm/ti/ti_common.c				standard
+arm/ti/ti_cpuid.c				standard
+arm/ti/ti_machdep.c				standard
+arm/ti/ti_prcm.c				standard
+arm/ti/ti_scm.c					standard
+dev/mbox/mbox_if.m				optional	ti_mbox
+arm/ti/ti_mbox.c				optional	ti_mbox
+arm/ti/ti_pruss.c				optional	ti_pruss
+arm/ti/ti_wdt.c					optional	ti_wdt
+arm/ti/ti_adc.c					optional	ti_adc
+arm/ti/ti_gpio.c				optional	gpio
+arm/ti/ti_i2c.c					optional	ti_i2c
+
+dev/uart/uart_dev_ti8250.c			optional	uart
+dev/uart/uart_dev_ns8250.c			optional	uart
+


Property changes on: trunk/sys/arm/ti/files.ti
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/ti/omap3/omap3_reg.h
===================================================================
--- trunk/sys/arm/ti/omap3/omap3_reg.h	                        (rev 0)
+++ trunk/sys/arm/ti/omap3/omap3_reg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,781 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2011
+ *	Ben Gray <ben.r.gray at gmail.com>.
+ * 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 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 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: stable/10/sys/arm/ti/omap3/omap3_reg.h 239281 2012-08-15 06:31:32Z gonzo $
+ */
+
+/*
+ * Texas Instruments - OMAP3xxx series processors
+ *
+ * Reference:
+ *  OMAP35x Applications Processor
+ *   Technical Reference Manual
+ *  (omap35xx_techref.pdf)
+ *
+ *
+ * Note:
+ *  The devices are mapped into address above 0xD000_0000 as the kernel space
+ *  memory is at 0xC000_0000 and above.  The first 256MB after this is reserved
+ *  for the size of the kernel, everything above that is reserved for SoC
+ *  devices.
+ *
+ */
+#ifndef _OMAP35XX_REG_H_
+#define _OMAP35XX_REG_H_
+
+#ifndef _LOCORE
+#include <sys/types.h>		/* for uint32_t */
+#endif
+
+
+
+
+#define OMAP35XX_SDRAM0_START		0x80000000UL
+#define OMAP35XX_SDRAM1_START		0xA0000000UL
+#define	OMAP35XX_SDRAM_BANKS		2
+#define	OMAP35XX_SDRAM_BANK_SIZE	0x20000000UL
+
+
+/* Physical/Virtual address for SDRAM controller */
+
+#define OMAP35XX_SMS_VBASE			0x6C000000UL
+#define OMAP35XX_SMS_HWBASE			0x6C000000UL
+#define	OMAP35XX_SMS_SIZE			0x01000000UL
+
+#define OMAP35XX_SDRC_VBASE			0x6D000000UL
+#define OMAP35XX_SDRC_HWBASE		0x6D000000UL
+#define	OMAP35XX_SDRC_SIZE			0x01000000UL
+
+
+
+/* Physical/Virtual address for I/O space */
+
+#define	OMAP35XX_L3_VBASE			0xD0000000UL
+#define	OMAP35XX_L3_HWBASE			0x68000000UL
+#define	OMAP35XX_L3_SIZE			0x01000000UL
+
+#define	OMAP35XX_L4_CORE_VBASE		0xE8000000UL
+#define	OMAP35XX_L4_CORE_HWBASE		0x48000000UL
+#define	OMAP35XX_L4_CORE_SIZE		0x01000000UL
+
+#define	OMAP35XX_L4_WAKEUP_VBASE	0xE8300000UL
+#define	OMAP35XX_L4_WAKEUP_HWBASE	0x48300000UL
+#define	OMAP35XX_L4_WAKEUP_SIZE		0x00040000UL
+
+#define	OMAP35XX_L4_PERIPH_VBASE	0xE9000000UL
+#define	OMAP35XX_L4_PERIPH_HWBASE	0x49000000UL
+#define	OMAP35XX_L4_PERIPH_SIZE		0x00100000UL
+
+
+/*
+ * L4-CORE Physical/Virtual addresss offsets
+ */
+#define	OMAP35XX_SCM_OFFSET			0x00002000UL
+#define	OMAP35XX_CM_OFFSET			0x00004000UL
+#define OMAP35XX_SDMA_OFFSET		0x00056000UL
+#define	OMAP35XX_I2C3_OFFSET		0x00060000UL
+#define	OMAP35XX_USB_TLL_OFFSET     0x00062000UL
+#define	OMAP35XX_USB_UHH_OFFSET     0x00064000UL
+#define	OMAP35XX_USB_EHCI_OFFSET    0x00064800UL
+
+
+#define	OMAP35XX_UART1_OFFSET		0x0006A000UL
+#define	OMAP35XX_UART2_OFFSET		0x0006C000UL
+#define	OMAP35XX_I2C1_OFFSET		0x00070000UL
+#define	OMAP35XX_I2C2_OFFSET		0x00072000UL
+#define	OMAP35XX_MCBSP1_OFFSET		0x00074000UL
+#define	OMAP35XX_GPTIMER10_OFFSET	0x00086000UL
+#define	OMAP35XX_GPTIMER11_OFFSET	0x00088000UL
+#define	OMAP35XX_MCBSP5_OFFSET		0x00096000UL
+#define	OMAP35XX_MMU1_OFFSET		0x000BD400UL
+#define	OMAP35XX_INTCPS_OFFSET		0x00200000UL
+
+
+/*
+ * L4-WAKEUP Physical/Virtual addresss offsets
+ */
+#define OMAP35XX_PRM_OFFSET			0x00006000UL
+#define	OMAP35XX_GPIO1_OFFSET		0x00010000UL
+#define	OMAP35XX_GPTIMER1_OFFSET	0x00018000UL
+
+
+
+/*
+ * L4-PERIPH Physical/Virtual addresss offsets
+ */
+#define	OMAP35XX_UART3_OFFSET		0x00020000UL
+#define	OMAP35XX_MCBSP2_OFFSET		0x00022000UL
+#define	OMAP35XX_MCBSP3_OFFSET		0x00024000UL
+#define	OMAP35XX_MCBSP4_OFFSET		0x00026000UL
+#define	OMAP35XX_SIDETONE_MCBSP2_OFFSET		0x00028000UL
+#define	OMAP35XX_SIDETONE_MCBSP3_OFFSET		0x0002A000UL
+#define	OMAP35XX_GPTIMER2_OFFSET	0x00032000UL
+#define	OMAP35XX_GPTIMER3_OFFSET	0x00034000UL
+#define	OMAP35XX_GPTIMER4_OFFSET	0x00036000UL
+#define	OMAP35XX_GPTIMER5_OFFSET	0x00038000UL
+#define	OMAP35XX_GPTIMER6_OFFSET	0x0003A000UL
+#define	OMAP35XX_GPTIMER7_OFFSET	0x0003C000UL
+#define	OMAP35XX_GPTIMER8_OFFSET	0x0003E000UL
+#define	OMAP35XX_GPTIMER9_OFFSET	0x00040000UL
+#define	OMAP35XX_GPIO2_OFFSET		0x00050000UL
+#define	OMAP35XX_GPIO3_OFFSET		0x00052000UL
+#define	OMAP35XX_GPIO4_OFFSET		0x00054000UL
+#define	OMAP35XX_GPIO5_OFFSET		0x00056000UL
+#define	OMAP35XX_GPIO6_OFFSET		0x00058000UL
+
+
+
+
+
+
+/*
+ * System Control Module
+ */
+#define	OMAP35XX_SCM_HWBASE				(OMAP35XX_L4_CORE_HWBASE + OMAP35XX_SCM_OFFSET)
+#define OMAP35XX_SCM_VBASE				(OMAP35XX_L4_CORE_VBASE + OMAP35XX_SCM_OFFSET)
+#define OMAP35XX_SCM_SIZE				0x00001000UL
+
+#define OMAP35XX_SCM_REVISION			0x00000000UL
+#define OMAP35XX_SCM_SYSCONFIG			0x00000010UL
+#define OMAP35XX_SCM_PADCONFS_BASE		0x00000030UL
+#define OMAP35XX_SCM_DEVCONF0			0x00000274UL
+#define OMAP35XX_SCM_MEM_DFTRW0			0x00000278UL
+
+
+
+
+/*
+ *
+ */
+#define	OMAP35XX_CM_HWBASE				(OMAP35XX_L4_CORE_HWBASE + OMAP35XX_CM_OFFSET)
+#define OMAP35XX_CM_VBASE				(OMAP35XX_L4_CORE_VBASE + OMAP35XX_CM_OFFSET)
+#define OMAP35XX_CM_SIZE				0x00001500UL
+
+#define OMAP35XX_CM_CORE_OFFSET			0x00000A00UL
+#define OMAP35XX_CM_CORE_SIZE			0x00000100UL
+#define OMAP35XX_CM_FCLKEN1_CORE		(OMAP35XX_CM_CORE_OFFSET + 0x0000UL)
+#define OMAP35XX_CM_FCLKEN3_CORE		(OMAP35XX_CM_CORE_OFFSET + 0x0008UL)
+#define OMAP35XX_CM_ICLKEN1_CORE		(OMAP35XX_CM_CORE_OFFSET + 0x0010UL)
+#define OMAP35XX_CM_ICLKEN2_CORE		(OMAP35XX_CM_CORE_OFFSET + 0x0014UL)
+#define OMAP35XX_CM_ICLKEN3_CORE		(OMAP35XX_CM_CORE_OFFSET + 0x0018UL)
+#define OMAP35XX_CM_IDLEST1_CORE		(OMAP35XX_CM_CORE_OFFSET + 0x0020UL)
+#define OMAP35XX_CM_IDLEST2_CORE		(OMAP35XX_CM_CORE_OFFSET + 0x0024UL)
+#define OMAP35XX_CM_IDLEST3_CORE		(OMAP35XX_CM_CORE_OFFSET + 0x0028UL)
+#define OMAP35XX_CM_AUTOIDLE1_CORE		(OMAP35XX_CM_CORE_OFFSET + 0x0030UL)
+#define OMAP35XX_CM_AUTOIDLE2_CORE		(OMAP35XX_CM_CORE_OFFSET + 0x0034UL)
+#define OMAP35XX_CM_AUTOIDLE3_CORE		(OMAP35XX_CM_CORE_OFFSET + 0x0038UL)
+#define OMAP35XX_CM_CLKSEL_CORE			(OMAP35XX_CM_CORE_OFFSET + 0x0040UL)
+#define OMAP35XX_CM_CLKSTCTRL_CORE		(OMAP35XX_CM_CORE_OFFSET + 0x0048UL)
+#define OMAP35XX_CM_CLKSTST_CORE		(OMAP35XX_CM_CORE_OFFSET + 0x004CUL)
+
+#define OMAP35XX_CM_WKUP_OFFSET			0x00000C00UL
+#define OMAP35XX_CM_WKUP_SIZE			0x00000100UL
+#define OMAP35XX_CM_FCLKEN_WKUP			(OMAP35XX_CM_WKUP_OFFSET + 0x0000UL)
+#define OMAP35XX_CM_ICLKEN_WKUP			(OMAP35XX_CM_WKUP_OFFSET + 0x0010UL)
+#define OMAP35XX_CM_IDLEST_WKUP			(OMAP35XX_CM_WKUP_OFFSET + 0x0020UL)
+#define OMAP35XX_CM_AUTOIDLE_WKUP		(OMAP35XX_CM_WKUP_OFFSET + 0x0030UL)
+#define OMAP35XX_CM_CLKSEL_WKUP			(OMAP35XX_CM_WKUP_OFFSET + 0x0040UL)
+
+#define OMAP35XX_CM_PLL_OFFSET			0x00000D00UL
+#define OMAP35XX_CM_PLL_SIZE			0x00000100UL
+#define OMAP35XX_CM_CLKEN_PLL			(OMAP35XX_CM_PLL_OFFSET + 0x0000UL)
+#define OMAP35XX_CM_CLKEN2_PLL			(OMAP35XX_CM_PLL_OFFSET + 0x0004UL)
+#define OMAP35XX_CM_IDLEST_CKGEN		(OMAP35XX_CM_PLL_OFFSET + 0x0020UL)
+#define OMAP35XX_CM_IDLEST2_CKGEN		(OMAP35XX_CM_PLL_OFFSET + 0x0024UL)
+#define OMAP35XX_CM_AUTOIDLE_PLL		(OMAP35XX_CM_PLL_OFFSET + 0x0030UL)
+#define OMAP35XX_CM_AUTOIDLE2_PLL		(OMAP35XX_CM_PLL_OFFSET + 0x0034UL)
+#define OMAP35XX_CM_CLKSEL1_PLL			(OMAP35XX_CM_PLL_OFFSET + 0x0040UL)
+#define OMAP35XX_CM_CLKSEL2_PLL			(OMAP35XX_CM_PLL_OFFSET + 0x0044UL)
+#define OMAP35XX_CM_CLKSEL3_PLL			(OMAP35XX_CM_PLL_OFFSET + 0x0048UL)
+#define OMAP35XX_CM_CLKSEL4_PLL			(OMAP35XX_CM_PLL_OFFSET + 0x004CUL)
+#define OMAP35XX_CM_CLKSEL5_PLL			(OMAP35XX_CM_PLL_OFFSET + 0x0050UL)
+#define OMAP35XX_CM_CLKOUT_CTRL			(OMAP35XX_CM_PLL_OFFSET + 0x0070UL)
+
+#define OMAP35XX_CM_PER_OFFSET			0x00001000UL
+#define OMAP35XX_CM_PER_SIZE			0x00000100UL
+#define OMAP35XX_CM_FCLKEN_PER			(OMAP35XX_CM_PER_OFFSET + 0x0000UL)
+#define OMAP35XX_CM_ICLKEN_PER			(OMAP35XX_CM_PER_OFFSET + 0x0010UL)
+#define OMAP35XX_CM_IDLEST_PER			(OMAP35XX_CM_PER_OFFSET + 0x0020UL)
+#define OMAP35XX_CM_AUTOIDLE_PER 		(OMAP35XX_CM_PER_OFFSET + 0x0030UL)
+#define OMAP35XX_CM_CLKSEL_PER			(OMAP35XX_CM_PER_OFFSET + 0x0040UL)
+#define OMAP35XX_CM_SLEEPDEP_PER		(OMAP35XX_CM_PER_OFFSET + 0x0044UL)
+#define OMAP35XX_CM_CLKSTCTRL_PER		(OMAP35XX_CM_PER_OFFSET + 0x0048UL)
+#define OMAP35XX_CM_CLKSTST_PER			(OMAP35XX_CM_PER_OFFSET + 0x004CUL)
+
+#define OMAP35XX_CM_USBHOST_OFFSET		0x00001400UL
+#define OMAP35XX_CM_USBHOST_SIZE		0x00000100UL
+#define OMAP35XX_CM_FCLKEN_USBHOST		(OMAP35XX_CM_USBHOST_OFFSET + 0x0000UL)
+#define OMAP35XX_CM_ICLKEN_USBHOST		(OMAP35XX_CM_USBHOST_OFFSET + 0x0010UL)
+#define OMAP35XX_CM_IDLEST_USBHOST		(OMAP35XX_CM_USBHOST_OFFSET + 0x0020UL)
+#define OMAP35XX_CM_AUTOIDLE_USBHOST	(OMAP35XX_CM_USBHOST_OFFSET + 0x0030UL)
+#define OMAP35XX_CM_SLEEPDEP_USBHOST	(OMAP35XX_CM_USBHOST_OFFSET + 0x0044UL)
+#define OMAP35XX_CM_CLKSTCTRL_USBHOST	(OMAP35XX_CM_USBHOST_OFFSET + 0x0048UL)
+#define OMAP35XX_CM_CLKSTST_USBHOST		(OMAP35XX_CM_USBHOST_OFFSET + 0x004CUL)
+
+
+
+
+/*
+ *
+ */
+#define	OMAP35XX_PRM_HWBASE				(OMAP35XX_L4_WAKEUP_HWBASE + OMAP35XX_PRM_OFFSET)
+#define OMAP35XX_PRM_VBASE				(OMAP35XX_L4_WAKEUP_VBASE + OMAP35XX_PRM_OFFSET)
+#define OMAP35XX_PRM_SIZE				0x00001600UL
+
+#define OMAP35XX_PRM_CLKCTRL_OFFSET		0x00000D00UL
+#define OMAP35XX_PRM_CLKCTRL_SIZE		0x00000100UL
+#define OMAP35XX_PRM_CLKSEL				(OMAP35XX_PRM_CLKCTRL_OFFSET + 0x0040UL)
+#define OMAP35XX_PRM_CLKOUT_CTRL		(OMAP35XX_PRM_CLKCTRL_OFFSET + 0x0070UL)
+
+#define OMAP35XX_PRM_GLOBAL_OFFSET		0x00001200UL
+#define OMAP35XX_PRM_GLOBAL_SIZE		0x00000100UL
+#define OMAP35XX_PRM_CLKSRC_CTRL		(OMAP35XX_PRM_GLOBAL_OFFSET + 0x0070UL)
+
+
+
+
+
+/*
+ * Uarts
+ */
+#define	OMAP35XX_UART1_HWBASE			(OMAP35XX_L4_CORE_HWBASE + OMAP35XX_UART1_OFFSET)
+#define	OMAP35XX_UART1_VBASE			(OMAP35XX_L4_CORE_VBASE  + OMAP35XX_UART1_OFFSET)
+#define	OMAP35XX_UART1_SIZE				0x00001000UL
+
+#define	OMAP35XX_UART2_HWBASE			(OMAP35XX_L4_CORE_HWBASE + OMAP35XX_UART2_OFFSET)
+#define	OMAP35XX_UART2_VBASE			(OMAP35XX_L4_CORE_VBASE  + OMAP35XX_UART2_OFFSET)
+#define	OMAP35XX_UART2_SIZE				0x00001000UL
+
+#define OMAP35XX_UART3_HWBASE			(OMAP35XX_L4_PERIPH_HWBASE + OMAP35XX_UART3_OFFSET)
+#define OMAP35XX_UART3_VBASE			(OMAP35XX_L4_PERIPH_VBASE  + OMAP35XX_UART3_OFFSET)
+#define	OMAP35XX_UART3_SIZE				0x00001000UL
+
+
+
+
+/*
+ * I2C Modules
+ */
+#define	OMAP35XX_I2C1_HWBASE			(OMAP35XX_L4_CORE_HWBASE + OMAP35XX_I2C1_OFFSET)
+#define	OMAP35XX_I2C1_VBASE				(OMAP35XX_L4_CORE_VBASE  + OMAP35XX_I2C1_OFFSET)
+#define	OMAP35XX_I2C1_SIZE				0x00000080UL
+
+#define	OMAP35XX_I2C2_HWBASE			(OMAP35XX_L4_CORE_HWBASE + OMAP35XX_I2C2_OFFSET)
+#define	OMAP35XX_I2C2_VBASE				(OMAP35XX_L4_CORE_VBASE  + OMAP35XX_I2C2_OFFSET)
+#define	OMAP35XX_I2C2_SIZE				0x00000080UL
+
+#define	OMAP35XX_I2C3_HWBASE			(OMAP35XX_L4_CORE_HWBASE + OMAP35XX_I2C3_OFFSET)
+#define	OMAP35XX_I2C3_VBASE				(OMAP35XX_L4_CORE_VBASE  + OMAP35XX_I2C3_OFFSET)
+#define	OMAP35XX_I2C3_SIZE				0x00000080UL
+
+#define	OMAP35XX_I2C_IE					0x04
+#define	OMAP35XX_I2C_STAT				0x08
+#define	OMAP35XX_I2C_WE					0x0C
+#define	OMAP35XX_I2C_SYSS				0x10
+#define	OMAP35XX_I2C_BUF				0x14
+#define	OMAP35XX_I2C_CNT				0x18
+#define	OMAP35XX_I2C_DATA				0x1C
+#define	OMAP35XX_I2C_SYSC				0x20
+#define	OMAP35XX_I2C_CON				0x24
+#define	OMAP35XX_I2C_OA0				0x28
+#define	OMAP35XX_I2C_SA					0x2C
+#define	OMAP35XX_I2C_PSC				0x30
+#define	OMAP35XX_I2C_SCLL				0x34
+#define	OMAP35XX_I2C_SCLH				0x38
+#define	OMAP35XX_I2C_SYSTEST			0x3C
+#define	OMAP35XX_I2C_BUFSTAT			0x40
+#define	OMAP35XX_I2C_OA1				0x44
+#define	OMAP35XX_I2C_OA2				0x48
+#define	OMAP35XX_I2C_OA3				0x4C
+#define	OMAP35XX_I2C_ACTOA				0x50
+#define	OMAP35XX_I2C_SBLOCK				0x54
+
+
+
+/*
+ * McBSP Modules
+ */
+#define	OMAP35XX_MCBSP1_HWBASE			(OMAP35XX_L4_CORE_HWBASE + OMAP35XX_MCBSP1_OFFSET)
+#define	OMAP35XX_MCBSP1_VBASE			(OMAP35XX_L4_CORE_VBASE  + OMAP35XX_MCBSP1_OFFSET)
+#define	OMAP35XX_MCBSP1_SIZE			0x00001000UL
+
+#define	OMAP35XX_MCBSP2_HWBASE			(OMAP35XX_L4_PERIPH_HWBASE + OMAP35XX_MCBSP2_OFFSET)
+#define	OMAP35XX_MCBSP2_VBASE			(OMAP35XX_L4_PERIPH_VBASE  + OMAP35XX_MCBSP2_OFFSET)
+#define	OMAP35XX_MCBSP2_SIZE			0x00001000UL
+
+#define	OMAP35XX_MCBSP3_HWBASE			(OMAP35XX_L4_PERIPH_HWBASE + OMAP35XX_MCBSP3_OFFSET)
+#define	OMAP35XX_MCBSP3_VBASE			(OMAP35XX_L4_PERIPH_VBASE  + OMAP35XX_MCBSP3_OFFSET)
+#define	OMAP35XX_MCBSP3_SIZE			0x00001000UL
+
+#define	OMAP35XX_MCBSP4_HWBASE			(OMAP35XX_L4_PERIPH_HWBASE + OMAP35XX_MCBSP4_OFFSET)
+#define	OMAP35XX_MCBSP4_VBASE			(OMAP35XX_L4_PERIPH_VBASE  + OMAP35XX_MCBSP4_OFFSET)
+#define	OMAP35XX_MCBSP4_SIZE			0x00001000UL
+
+#define	OMAP35XX_MCBSP5_HWBASE			(OMAP35XX_L4_CORE_HWBASE + OMAP35XX_MCBSP5_OFFSET)
+#define	OMAP35XX_MCBSP5_VBASE			(OMAP35XX_L4_CORE_VBASE  + OMAP35XX_MCBSP5_OFFSET)
+#define	OMAP35XX_MCBSP5_SIZE			0x00001000UL
+
+#define	OMAP35XX_MCBSP_DRR				0x0000
+#define	OMAP35XX_MCBSP_DXR				0x0008
+#define	OMAP35XX_MCBSP_SPCR2			0x0010
+#define	OMAP35XX_MCBSP_SPCR1			0x0014
+#define	OMAP35XX_MCBSP_RCR2				0x0018
+#define	OMAP35XX_MCBSP_RCR1				0x001C
+#define	OMAP35XX_MCBSP_XCR2				0x0020
+#define	OMAP35XX_MCBSP_XCR1				0x0024
+#define	OMAP35XX_MCBSP_SRGR2			0x0028
+#define	OMAP35XX_MCBSP_SRGR1			0x002C
+#define	OMAP35XX_MCBSP_MCR2				0x0030
+#define	OMAP35XX_MCBSP_MCR1				0x0034
+#define	OMAP35XX_MCBSP_RCERA			0x0038
+#define	OMAP35XX_MCBSP_RCERB			0x003C
+#define	OMAP35XX_MCBSP_XCERA			0x0040
+#define	OMAP35XX_MCBSP_XCERB			0x0044
+#define	OMAP35XX_MCBSP_PCR				0x0048
+#define	OMAP35XX_MCBSP_RCERC			0x004C
+#define	OMAP35XX_MCBSP_RCERD			0x0050
+#define	OMAP35XX_MCBSP_XCERC			0x0054
+#define	OMAP35XX_MCBSP_XCERD			0x0058
+#define	OMAP35XX_MCBSP_RCERE			0x005C
+#define	OMAP35XX_MCBSP_RCERF			0x0060
+#define	OMAP35XX_MCBSP_XCERE			0x0064
+#define	OMAP35XX_MCBSP_XCERF			0x0068
+#define	OMAP35XX_MCBSP_RCERG			0x006C
+#define	OMAP35XX_MCBSP_RCERH			0x0070
+#define	OMAP35XX_MCBSP_XCERG			0x0074
+#define	OMAP35XX_MCBSP_XCERH			0x0078
+#define	OMAP35XX_MCBSP_RINTCLR			0x0080
+#define	OMAP35XX_MCBSP_XINTCLR			0x0084
+#define	OMAP35XX_MCBSP_ROVFLCLR			0x0088
+#define	OMAP35XX_MCBSP_SYSCONFIG		0x008C
+#define	OMAP35XX_MCBSP_THRSH2			0x0090
+#define	OMAP35XX_MCBSP_THRSH1			0x0094
+#define	OMAP35XX_MCBSP_IRQSTATUS		0x00A0
+#define	OMAP35XX_MCBSP_IRQENABLE		0x00A4
+#define	OMAP35XX_MCBSP_WAKEUPEN			0x00A8
+#define	OMAP35XX_MCBSP_XCCR				0x00AC
+#define	OMAP35XX_MCBSP_RCCR				0x00B0
+#define	OMAP35XX_MCBSP_XBUFFSTAT		0x00B4
+#define	OMAP35XX_MCBSP_RBUFFSTAT		0x00B8
+#define	OMAP35XX_MCBSP_SSELCR			0x00BC
+#define	OMAP35XX_MCBSP_STATUS			0x00C0
+
+
+
+/*
+ * USB TTL Module
+ */
+#define	OMAP35XX_USBTLL_HWBASE			(OMAP35XX_L4_CORE_HWBASE + OMAP35XX_USBTLL_OFFSET)
+#define	OMAP35XX_USBTLL_VBASE			(OMAP35XX_L4_CORE_VBASE  + OMAP35XX_USBTLL_OFFSET)
+#define	OMAP35XX_USBTLL_SIZE			0x00001000UL
+
+#define	OMAP35XX_USBTLL_REVISION						0x0000
+#define	OMAP35XX_USBTLL_SYSCONFIG						0x0010
+#define	OMAP35XX_USBTLL_SYSSTATUS						0x0014
+#define	OMAP35XX_USBTLL_IRQSTATUS						0x0018
+#define	OMAP35XX_USBTLL_IRQENABLE						0x001C
+#define	OMAP35XX_USBTLL_TLL_SHARED_CONF					0x0030
+#define	OMAP35XX_USBTLL_TLL_CHANNEL_CONF(i)				(0x0040 + (0x04 * (i)))
+#define	OMAP35XX_USBTLL_ULPI_VENDOR_ID_LO(i)			(0x0800 + (0x100 * (i)))
+#define	OMAP35XX_USBTLL_ULPI_VENDOR_ID_HI(i)			(0x0801 + (0x100 * (i)))
+#define	OMAP35XX_USBTLL_ULPI_PRODUCT_ID_LO(i)			(0x0802 + (0x100 * (i)))
+#define	OMAP35XX_USBTLL_ULPI_PRODUCT_ID_HI(i)			(0x0803 + (0x100 * (i)))
+#define	OMAP35XX_USBTLL_ULPI_FUNCTION_CTRL(i)			(0x0804 + (0x100 * (i)))
+#define	OMAP35XX_USBTLL_ULPI_FUNCTION_CTRL_SET(i)		(0x0805 + (0x100 * (i)))
+#define	OMAP35XX_USBTLL_ULPI_FUNCTION_CTRL_CLR(i)		(0x0806 + (0x100 * (i)))
+#define	OMAP35XX_USBTLL_ULPI_INTERFACE_CTRL(i)			(0x0807 + (0x100 * (i)))
+#define	OMAP35XX_USBTLL_ULPI_INTERFACE_CTRL_SET(i)		(0x0808 + (0x100 * (i)))
+#define	OMAP35XX_USBTLL_ULPI_INTERFACE_CTRL_CLR(i)		(0x0809 + (0x100 * (i)))
+#define	OMAP35XX_USBTLL_ULPI_OTG_CTRL(i)				(0x080A + (0x100 * (i)))
+#define	OMAP35XX_USBTLL_ULPI_OTG_CTRL_SET(i)			(0x080B + (0x100 * (i)))
+#define	OMAP35XX_USBTLL_ULPI_OTG_CTRL_CLR(i)			(0x080C + (0x100 * (i)))
+#define	OMAP35XX_USBTLL_ULPI_USB_INT_EN_RISE(i)			(0x080D + (0x100 * (i)))
+#define	OMAP35XX_USBTLL_ULPI_USB_INT_EN_RISE_SET(i)		(0x080E + (0x100 * (i)))
+#define	OMAP35XX_USBTLL_ULPI_USB_INT_EN_RISE_CLR(i)		(0x080F + (0x100 * (i)))
+#define	OMAP35XX_USBTLL_ULPI_USB_INT_EN_FALL(i)			(0x0810 + (0x100 * (i)))
+#define	OMAP35XX_USBTLL_ULPI_USB_INT_EN_FALL_SET(i)		(0x0811 + (0x100 * (i)))
+#define	OMAP35XX_USBTLL_ULPI_USB_INT_EN_FALL_CLR(i)		(0x0812 + (0x100 * (i)))
+#define	OMAP35XX_USBTLL_ULPI_USB_INT_STATUS(i)			(0x0813 + (0x100 * (i)))
+#define	OMAP35XX_USBTLL_ULPI_USB_INT_LATCH(i)			(0x0814 + (0x100 * (i)))
+#define	OMAP35XX_USBTLL_ULPI_DEBUG(i)					(0x0815 + (0x100 * (i)))
+#define	OMAP35XX_USBTLL_ULPI_SCRATCH_REGISTER(i)		(0x0816 + (0x100 * (i)))
+#define	OMAP35XX_USBTLL_ULPI_SCRATCH_REGISTER_SET(i)	(0x0817 + (0x100 * (i)))
+#define	OMAP35XX_USBTLL_ULPI_SCRATCH_REGISTER_CLR(i)	(0x0818 + (0x100 * (i)))
+#define	OMAP35XX_USBTLL_ULPI_EXTENDED_SET_ACCESS(i)		(0x082F + (0x100 * (i)))
+#define	OMAP35XX_USBTLL_ULPI_UTMI_VCONTROL_EN(i)		(0x0830 + (0x100 * (i)))
+#define	OMAP35XX_USBTLL_ULPI_UTMI_VCONTROL_EN_SET(i)	(0x0831 + (0x100 * (i)))
+#define	OMAP35XX_USBTLL_ULPI_UTMI_VCONTROL_EN_CLR(i)	(0x0832 + (0x100 * (i)))
+#define	OMAP35XX_USBTLL_ULPI_UTMI_VCONTROL_STATUS(i)	(0x0833 + (0x100 * (i)))
+#define	OMAP35XX_USBTLL_ULPI_UTMI_VCONTROL_LATCH(i)		(0x0834 + (0x100 * (i)))
+#define	OMAP35XX_USBTLL_ULPI_UTMI_VSTATUS(i)			(0x0835 + (0x100 * (i)))
+#define	OMAP35XX_USBTLL_ULPI_UTMI_VSTATUS_SET(i)		(0x0836 + (0x100 * (i)))
+#define	OMAP35XX_USBTLL_ULPI_UTMI_VSTATUS_CLR(i)		(0x0837 + (0x100 * (i)))
+#define	OMAP35XX_USBTLL_ULPI_USB_INT_LATCH_NOCLR(i)		(0x0838 + (0x100 * (i)))
+#define	OMAP35XX_USBTLL_ULPI_VENDOR_INT_EN(i)			(0x083B + (0x100 * (i)))
+#define	OMAP35XX_USBTLL_ULPI_VENDOR_INT_EN_SET(i)		(0x083C + (0x100 * (i)))
+#define	OMAP35XX_USBTLL_ULPI_VENDOR_INT_EN_CLR(i)		(0x083D + (0x100 * (i)))
+#define	OMAP35XX_USBTLL_ULPI_VENDOR_INT_STATUS(i)		(0x083E + (0x100 * (i)))
+#define	OMAP35XX_USBTLL_ULPI_VENDOR_INT_LATCH(i)		(0x083F + (0x100 * (i)))
+
+
+/*
+ * USB Host Module
+ */
+#define	OMAP35XX_USB_TLL_HWBASE         (OMAP35XX_L4_CORE_HWBASE + OMAP35XX_USB_TLL_OFFSET)
+#define	OMAP35XX_USB_TLL_VBASE          (OMAP35XX_L4_CORE_VBASE + OMAP35XX_USB_TLL_OFFSET)
+#define OMAP35XX_USB_TLL_SIZE           0x00001000UL
+
+#define	OMAP35XX_USB_EHCI_HWBASE        (OMAP35XX_L4_CORE_HWBASE + OMAP35XX_USB_EHCI_OFFSET)
+#define	OMAP35XX_USB_EHCI_VBASE         (OMAP35XX_L4_CORE_VBASE + OMAP35XX_USB_EHCI_OFFSET)
+#define OMAP35XX_USB_EHCI_SIZE          0x00000400UL
+
+#define	OMAP35XX_USB_UHH_HWBASE         (OMAP35XX_L4_CORE_HWBASE + OMAP35XX_USB_UHH_OFFSET)
+#define	OMAP35XX_USB_UHH_VBASE          (OMAP35XX_L4_CORE_VBASE + OMAP35XX_USB_UHH_OFFSET)
+#define OMAP35XX_USB_UHH_SIZE           0x00000400UL
+
+
+
+
+
+/*
+ * SDRAM Controler (SDRC)
+ *  PA 0x6D00_0000
+ */
+
+#define OMAP35XX_SDRC_SYSCONFIG			(OMAP35XX_SDRC_VBASE + 0x10)
+#define OMAP35XX_SDRC_SYSSTATUS			(OMAP35XX_SDRC_VBASE + 0x14)
+#define OMAP35XX_SDRC_CS_CFG			(OMAP35XX_SDRC_VBASE + 0x40)
+#define OMAP35XX_SDRC_SHARING			(OMAP35XX_SDRC_VBASE + 0x44)
+#define OMAP35XX_SDRC_ERR_ADDR			(OMAP35XX_SDRC_VBASE + 0x48)
+#define OMAP35XX_SDRC_ERR_TYPE			(OMAP35XX_SDRC_VBASE + 0x4C)
+#define OMAP35XX_SDRC_DLLA_CTRL			(OMAP35XX_SDRC_VBASE + 0x60)
+#define OMAP35XX_SDRC_DLLA_STATUS		(OMAP35XX_SDRC_VBASE + 0x64)
+#define OMAP35XX_SDRC_POWER_REG			(OMAP35XX_SDRC_VBASE + 0x70)
+#define OMAP35XX_SDRC_MCFG(p)			(OMAP35XX_SDRC_VBASE + 0x80 + (0x30 * (p)))
+#define OMAP35XX_SDRC_MR(p)				(OMAP35XX_SDRC_VBASE + 0x84 + (0x30 * (p)))
+#define OMAP35XX_SDRC_EMR2(p)			(OMAP35XX_SDRC_VBASE + 0x8C + (0x30 * (p)))
+#define OMAP35XX_SDRC_ACTIM_CTRLA(p)	(OMAP35XX_SDRC_VBASE + 0x9C + (0x28 * (p)))
+#define OMAP35XX_SDRC_ACTIM_CTRLB(p)	(OMAP35XX_SDRC_VBASE + 0xA0 + (0x28 * (p)))
+#define OMAP35XX_SDRC_RFR_CTRL(p)		(OMAP35XX_SDRC_VBASE + 0xA4 + (0x30 * (p)))
+#define OMAP35XX_SDRC_MANUAL(p)			(OMAP35XX_SDRC_VBASE + 0xA8 + (0x30 * (p)))
+
+
+/*
+ * SDMA Offset
+ *  PA 0x4805 6000
+ */
+
+#define	OMAP35XX_SDMA_HWBASE			(OMAP35XX_L4_CORE_HWBASE + OMAP35XX_SDMA_OFFSET)
+#define	OMAP35XX_SDMA_VBASE				(OMAP35XX_L4_CORE_VBASE  + OMAP35XX_SDMA_OFFSET)
+#define	OMAP35XX_SDMA_SIZE				0x00001000UL
+
+
+
+/*
+ * Interrupt Controller Unit.
+ *  PA 0x4820_0000
+ */
+
+#define	OMAP35XX_INTCPS_HWBASE			(OMAP35XX_L4_CORE_HWBASE + OMAP35XX_INTCPS_OFFSET)
+#define	OMAP35XX_INTCPS_VBASE			(OMAP35XX_L4_CORE_VBASE  + OMAP35XX_INTCPS_OFFSET)
+#define	OMAP35XX_INTCPS_SIZE			0x00001000UL
+
+#define	OMAP35XX_INTCPS_SYSCONFIG		(OMAP35XX_INTCPS_VBASE + 0x10)
+#define	OMAP35XX_INTCPS_SYSSTATUS		(OMAP35XX_INTCPS_VBASE + 0x14)
+#define	OMAP35XX_INTCPS_SIR_IRQ			(OMAP35XX_INTCPS_VBASE + 0x40)
+#define	OMAP35XX_INTCPS_SIR_FIQ			(OMAP35XX_INTCPS_VBASE + 0x44)
+#define	OMAP35XX_INTCPS_CONTROL			(OMAP35XX_INTCPS_VBASE + 0x48)
+#define	OMAP35XX_INTCPS_PROTECTION		(OMAP35XX_INTCPS_VBASE + 0x4C)
+#define	OMAP35XX_INTCPS_IDLE			(OMAP35XX_INTCPS_VBASE + 0x50)
+#define	OMAP35XX_INTCPS_IRQ_PRIORITY	(OMAP35XX_INTCPS_VBASE + 0x60)
+#define	OMAP35XX_INTCPS_FIQ_PRIORITY	(OMAP35XX_INTCPS_VBASE + 0x64)
+#define	OMAP35XX_INTCPS_THRESHOLD		(OMAP35XX_INTCPS_VBASE + 0x68)
+#define OMAP35XX_INTCPS_ITR(n)			(OMAP35XX_INTCPS_VBASE + 0x80 + (0x20 * (n)))
+#define OMAP35XX_INTCPS_MIR(n)			(OMAP35XX_INTCPS_VBASE + 0x84 + (0x20 * (n)))
+#define OMAP35XX_INTCPS_MIR_CLEAR(n)	(OMAP35XX_INTCPS_VBASE + 0x88 + (0x20 * (n)))
+#define OMAP35XX_INTCPS_MIR_SET(n)		(OMAP35XX_INTCPS_VBASE + 0x8C + (0x20 * (n)))
+#define OMAP35XX_INTCPS_ISR_SET(n)		(OMAP35XX_INTCPS_VBASE + 0x90 + (0x20 * (n)))
+#define OMAP35XX_INTCPS_ISR_CLEAR(n)	(OMAP35XX_INTCPS_VBASE + 0x94 + (0x20 * (n)))
+#define OMAP35XX_INTCPS_PENDING_IRQ(n)	(OMAP35XX_INTCPS_VBASE + 0x98 + (0x20 * (n)))
+#define OMAP35XX_INTCPS_PENDING_FIQ(n)	(OMAP35XX_INTCPS_VBASE + 0x9C + (0x20 * (n)))
+#define OMAP35XX_INTCPS_ILR(m)			(OMAP35XX_INTCPS_VBASE + 0x100 + (0x4 * (m)))
+
+
+#define	OMAP35XX_IRQ_EMUINT			0	/* MPU emulation(2) */
+#define	OMAP35XX_IRQ_COMMTX			1	/* MPU emulation(2) */
+#define	OMAP35XX_IRQ_COMMRX			2	/* MPU emulation(2) */
+#define	OMAP35XX_IRQ_BENCH			3	/* MPU emulation(2) */
+#define	OMAP35XX_IRQ_MCBSP2_ST		4	/* Sidetone MCBSP2 overflow */
+#define	OMAP35XX_IRQ_MCBSP3_ST		5	/* Sidetone MCBSP3 overflow */
+#define	OMAP35XX_IRQ_SSM_ABORT		6	/* MPU subsystem secure state-machine abort (2) */
+#define	OMAP35XX_IRQ_SYS_NIRQ		7	/* External source (active low) */
+#define	OMAP35XX_IRQ_RESERVED8		8	/* RESERVED */
+#define	OMAP35XX_IRQ_SMX_DBG		9	/* SMX error for debug */
+#define	OMAP35XX_IRQ_SMX_APP		10	/* SMX error for application */
+#define	OMAP35XX_IRQ_PRCM_MPU		11	/* PRCM module IRQ */
+#define	OMAP35XX_IRQ_SDMA0			12	/* System DMA request 0(3) */
+#define	OMAP35XX_IRQ_SDMA1			13	/* System DMA request 1(3) */
+#define	OMAP35XX_IRQ_SDMA2			14	/* System DMA request 2 */
+#define	OMAP35XX_IRQ_SDMA3			15	/* System DMA request 3 */
+#define	OMAP35XX_IRQ_MCBSP1			16	/* McBSP module 1 IRQ (3) */
+#define	OMAP35XX_IRQ_MCBSP2			17	/* McBSP module 2 IRQ (3) */
+#define	OMAP35XX_IRQ_SR1			18	/* SmartReflexâ„¢ 1 */
+#define	OMAP35XX_IRQ_SR2			19	/* SmartReflexâ„¢ 2 */
+#define	OMAP35XX_IRQ_GPMC			20	/* General-purpose memory controller module */
+#define	OMAP35XX_IRQ_SGX			21	/* 2D/3D graphics module */
+#define	OMAP35XX_IRQ_MCBSP3			22	/* McBSP module 3(3) */
+#define	OMAP35XX_IRQ_MCBSP4			23	/* McBSP module 4(3) */
+#define	OMAP35XX_IRQ_CAM0			24	/* Camera interface request 0 */
+#define	OMAP35XX_IRQ_DSS			25	/* Display subsystem module(3) */
+#define	OMAP35XX_IRQ_MAIL_U0		26	/* Mailbox user 0 request */
+#define	OMAP35XX_IRQ_MCBSP5_IRQ1	27	/*  McBSP module 5 (3) */
+#define	OMAP35XX_IRQ_IVA2_MMU		28	/* IVA2 MMU */
+#define	OMAP35XX_IRQ_GPIO1_MPU		29	/* GPIO module 1(3) */
+#define	OMAP35XX_IRQ_GPIO2_MPU		30	/* GPIO module 2(3) */
+#define	OMAP35XX_IRQ_GPIO3_MPU		31	/* GPIO module 3(3) */
+#define	OMAP35XX_IRQ_GPIO4_MPU		32	/* GPIO module 4(3) */
+#define	OMAP35XX_IRQ_GPIO5_MPU		33	/* GPIO module 5(3) */
+#define	OMAP35XX_IRQ_GPIO6_MPU		34	/* GPIO module 6(3) */
+#define	OMAP35XX_IRQ_USIM			35	/* USIM interrupt (HS devices only) (4) */
+#define	OMAP35XX_IRQ_WDT3			36	/* Watchdog timer module 3 overflow */
+#define	OMAP35XX_IRQ_GPT1			37	/* General-purpose timer module 1 */
+#define	OMAP35XX_IRQ_GPT2			38	/* General-purpose timer module 2 */
+#define	OMAP35XX_IRQ_GPT3			39	/* General-purpose timer module 3 */
+#define	OMAP35XX_IRQ_GPT4			40	/* General-purpose timer module 4 */
+#define	OMAP35XX_IRQ_GPT5			41	/* General-purpose timer module 5(3) */
+#define	OMAP35XX_IRQ_GPT6			42	/* General-purpose timer module 6(3) */
+#define	OMAP35XX_IRQ_GPT7			43	/* General-purpose timer module 7(3) */
+#define	OMAP35XX_IRQ_GPT8			44	/* General-purpose timer module 8(3) */
+#define	OMAP35XX_IRQ_GPT9			45	/* General-purpose timer module 9 */
+#define	OMAP35XX_IRQ_GPT10			46	/* General-purpose timer module 10 */
+#define	OMAP35XX_IRQ_GPT11			47	/* General-purpose timer module 11 */
+#define	OMAP35XX_IRQ_SPI4			48	/* McSPI module 4 */
+#define	OMAP35XX_IRQ_SHA1MD5_2		49	/* SHA-1/MD5 crypto-accelerator 2 (HS devices only)(4) */
+#define	OMAP35XX_IRQ_FPKA_IRQREADY_N	50	/* PKA crypto-accelerator (HS devices only) (4) */
+#define	OMAP35XX_IRQ_SHA2MD5		51	/* SHA-2/MD5 crypto-accelerator 1 (HS devices only) (4) */
+#define	OMAP35XX_IRQ_RNG			52	/* RNG module (HS devices only) (4) */
+#define	OMAP35XX_IRQ_MG				53	/* MG function (3) */
+#define	OMAP35XX_IRQ_MCBSP4_TX		54	/* McBSP module 4 transmit(3) */
+#define	OMAP35XX_IRQ_MCBSP4_RX		55	/* McBSP module 4 receive(3) */
+#define	OMAP35XX_IRQ_I2C1			56	/* I2C module 1 */
+#define	OMAP35XX_IRQ_I2C2			57	/* I2C module 2 */
+#define	OMAP35XX_IRQ_HDQ			58	/* HDQ / One-wire */
+#define	OMAP35XX_IRQ_MCBSP1_TX		59	/* McBSP module 1 transmit(3) */
+#define	OMAP35XX_IRQ_MCBSP1_RX		60	/* McBSP module 1 receive(3) */
+#define	OMAP35XX_IRQ_I2C3			61	/* I2C module 3 */
+#define	OMAP35XX_IRQ_McBSP2_TX		62	/* McBSP module 2 transmit(3) */
+#define	OMAP35XX_IRQ_McBSP2_RX		63	/* McBSP module 2 receive(3) */
+#define	OMAP35XX_IRQ_FPKA_IRQRERROR_N	64	/* PKA crypto-accelerator (HS devices only) (4) */
+#define	OMAP35XX_IRQ_SPI1			65	/* McSPI module 1 */
+#define	OMAP35XX_IRQ_SPI2			66	/* McSPI module 2 */
+#define	OMAP35XX_IRQ_RESERVED67		67	/* RESERVED */
+#define	OMAP35XX_IRQ_RESERVED68		68	/* RESERVED */
+#define	OMAP35XX_IRQ_RESERVED69		69	/* RESERVED */
+#define	OMAP35XX_IRQ_RESERVED70		70	/* RESERVED */
+#define	OMAP35XX_IRQ_RESERVED71		71	/* RESERVED */
+#define	OMAP35XX_IRQ_UART1			72	/* UART module 1 */
+#define	OMAP35XX_IRQ_UART2			73	/* UART module 2 */
+#define	OMAP35XX_IRQ_UART3			74	/* UART module 3 (also infrared)(3) */
+#define	OMAP35XX_IRQ_PBIAS			75	/* Merged interrupt for PBIASlite1 and 2 */
+#define	OMAP35XX_IRQ_OHCI			76	/* OHCI controller HSUSB MP Host Interrupt */
+#define	OMAP35XX_IRQ_EHCI			77	/* EHCI controller HSUSB MP Host Interrupt */
+#define	OMAP35XX_IRQ_TLL			78	/* HSUSB MP TLL Interrupt */
+#define	OMAP35XX_IRQ_PARTHASH		79	/* SHA2/MD5 crypto-accelerator 1 (HS devices only) (4) */
+#define	OMAP35XX_IRQ_RESERVED80		80	/* Reserved */
+#define	OMAP35XX_IRQ_MCBSP5_TX		81	/* McBSP module 5 transmit(3) */
+#define	OMAP35XX_IRQ_MCBSP5_RX		82	/* McBSP module 5 receive(3) */
+#define	OMAP35XX_IRQ_MMC1			83	/* MMC/SD module 1 */
+#define	OMAP35XX_IRQ_MS				84	/* MS-PROâ„¢ module */
+#define	OMAP35XX_IRQ_RESERVED85		85	/* Reserved */
+#define	OMAP35XX_IRQ_MMC2			86	/* MMC/SD module 2 */
+#define	OMAP35XX_IRQ_MPU_ICR		87	/* MPU ICR */
+#define	OMAP35XX_IRQ_RESERVED		88	/* RESERVED */
+#define	OMAP35XX_IRQ_MCBSP3_TX		89	/* McBSP module 3 transmit(3) */
+#define	OMAP35XX_IRQ_MCBSP3_RX		90	/* McBSP module 3 receive(3) */
+#define	OMAP35XX_IRQ_SPI3			91	/* McSPI module 3 */
+#define	OMAP35XX_IRQ_HSUSB_MC_NINT	92	/* High-Speed USB OTG controller */
+#define	OMAP35XX_IRQ_HSUSB_DMA_NINT	93	/* High-Speed USB OTG DMA controller */
+#define	OMAP35XX_IRQ_MMC3			94	/* MMC/SD module 3 */
+#define	OMAP35XX_IRQ_GPT12			95	/* General-purpose timer module 12 */
+
+
+
+
+/*
+ * General Purpose Timers
+ */
+#define OMAP35XX_GPTIMER1_VBASE     (OMAP35XX_L4_WAKEUP_VBASE + OMAP35XX_GPTIMER1_OFFSET)
+#define OMAP35XX_GPTIMER1_HWBASE    (OMAP35XX_L4_WAKEUP_HWBASE + OMAP35XX_GPTIMER1_OFFSET)
+#define OMAP35XX_GPTIMER2_VBASE     (OMAP35XX_L4_PERIPH_VBASE + OMAP35XX_GPTIMER2_OFFSET)
+#define OMAP35XX_GPTIMER2_HWBASE    (OMAP35XX_L4_PERIPH_HWBASE + OMAP35XX_GPTIMER2_OFFSET)
+#define OMAP35XX_GPTIMER3_VBASE     (OMAP35XX_L4_PERIPH_VBASE + OMAP35XX_GPTIMER3_OFFSET)
+#define OMAP35XX_GPTIMER3_HWBASE    (OMAP35XX_L4_PERIPH_HWBASE + OMAP35XX_GPTIMER3_OFFSET)
+#define OMAP35XX_GPTIMER4_VBASE     (OMAP35XX_L4_PERIPH_VBASE + OMAP35XX_GPTIMER4_OFFSET)
+#define OMAP35XX_GPTIMER4_HWBASE    (OMAP35XX_L4_PERIPH_HWBASE + OMAP35XX_GPTIMER4_OFFSET)
+#define OMAP35XX_GPTIMER5_VBASE     (OMAP35XX_L4_PERIPH_VBASE + OMAP35XX_GPTIMER5_OFFSET)
+#define OMAP35XX_GPTIMER5_HWBASE    (OMAP35XX_L4_PERIPH_HWBASE + OMAP35XX_GPTIMER5_OFFSET)
+#define OMAP35XX_GPTIMER6_VBASE     (OMAP35XX_L4_PERIPH_VBASE + OMAP35XX_GPTIMER6_OFFSET)
+#define OMAP35XX_GPTIMER6_HWBASE    (OMAP35XX_L4_PERIPH_HWBASE + OMAP35XX_GPTIMER6_OFFSET)
+#define OMAP35XX_GPTIMER7_VBASE     (OMAP35XX_L4_PERIPH_VBASE + OMAP35XX_GPTIMER7_OFFSET)
+#define OMAP35XX_GPTIMER7_HWBASE    (OMAP35XX_L4_PERIPH_HWBASE + OMAP35XX_GPTIMER7_OFFSET)
+#define OMAP35XX_GPTIMER8_VBASE     (OMAP35XX_L4_PERIPH_VBASE + OMAP35XX_GPTIMER8_OFFSET)
+#define OMAP35XX_GPTIMER8_HWBASE    (OMAP35XX_L4_PERIPH_HWBASE + OMAP35XX_GPTIMER8_OFFSET)
+#define OMAP35XX_GPTIMER9_VBASE     (OMAP35XX_L4_PERIPH_VBASE + OMAP35XX_GPTIMER9_OFFSET)
+#define OMAP35XX_GPTIMER9_HWBASE    (OMAP35XX_L4_PERIPH_HWBASE + OMAP35XX_GPTIMER9_OFFSET)
+#define OMAP35XX_GPTIMER10_VBASE    (OMAP35XX_L4_CORE_VBASE + OMAP35XX_GPTIMER10_OFFSET)
+#define OMAP35XX_GPTIMER10_HWBASE   (OMAP35XX_L4_CORE_HWBASE + OMAP35XX_GPTIMER10_OFFSET)
+#define OMAP35XX_GPTIMER11_VBASE    (OMAP35XX_L4_CORE_VBASE + OMAP35XX_GPTIMER11_OFFSET)
+#define OMAP35XX_GPTIMER11_HWBASE   (OMAP35XX_L4_CORE_HWBASE + OMAP35XX_GPTIMER11_OFFSET)
+#define OMAP35XX_GPTIMER12_VBASE    0x48304000UL   /* GPTIMER12 */
+#define OMAP35XX_GPTIMER_SIZE       0x00001000UL
+
+
+
+/* Timer register offsets */
+#define OMAP35XX_GPTIMER_TIOCP_CFG	0x010
+#define OMAP35XX_GPTIMER_TISTAT		0x014
+#define OMAP35XX_GPTIMER_TISR		0x018
+#define OMAP35XX_GPTIMER_TIER		0x01C
+#define OMAP35XX_GPTIMER_TWER		0x020
+#define OMAP35XX_GPTIMER_TCLR		0x024
+#define OMAP35XX_GPTIMER_TCRR		0x028
+#define OMAP35XX_GPTIMER_TLDR		0x02C
+#define OMAP35XX_GPTIMER_TTGR		0x030
+#define OMAP35XX_GPTIMER_TWPS		0x034
+#define OMAP35XX_GPTIMER_TMAR		0x038
+#define OMAP35XX_GPTIMER_TCAR1		0x03C
+#define OMAP35XX_GPTIMER_TSICR		0x040
+#define OMAP35XX_GPTIMER_TCAR2		0x044
+#define OMAP35XX_GPTIMER_TPIR		0x048
+#define OMAP35XX_GPTIMER_TNIR		0x04C
+#define OMAP35XX_GPTIMER_TCVR		0x050
+#define OMAP35XX_GPTIMER_TOCR		0x054
+#define OMAP35XX_GPTIMER_TOWR		0x058
+
+/* Bit values */
+#define MAT_IT_FLAG		0x01
+#define OVF_IT_FLAG		0x02
+#define TCAR_IT_FLAG	0x04
+
+
+
+/*
+ * GPIO - General Purpose IO
+ */
+
+/* Base addresses for the GPIO modules */
+#define	OMAP35XX_GPIO1_HWBASE		(OMAP35XX_L4_WAKEUP_HWBASE + OMAP35XX_GPIO1_OFFSET)
+#define	OMAP35XX_GPIO1_VBASE		(OMAP35XX_L4_WAKEUP_VBASE  + OMAP35XX_GPIO1_OFFSET)
+#define	OMAP35XX_GPIO1_SIZE			0x00001000UL
+#define	OMAP35XX_GPIO2_HWBASE		(OMAP35XX_L4_PERIPH_HWBASE + OMAP35XX_GPIO2_OFFSET)
+#define	OMAP35XX_GPIO2_VBASE		(OMAP35XX_L4_PERIPH_VBASE  + OMAP35XX_GPIO2_OFFSET)
+#define	OMAP35XX_GPIO2_SIZE			0x00001000UL
+#define	OMAP35XX_GPIO3_HWBASE		(OMAP35XX_L4_PERIPH_HWBASE + OMAP35XX_GPIO3_OFFSET)
+#define	OMAP35XX_GPIO3_VBASE		(OMAP35XX_L4_PERIPH_VBASE  + OMAP35XX_GPIO3_OFFSET)
+#define	OMAP35XX_GPIO3_SIZE			0x00001000UL
+#define	OMAP35XX_GPIO4_HWBASE		(OMAP35XX_L4_PERIPH_HWBASE + OMAP35XX_GPIO4_OFFSET)
+#define	OMAP35XX_GPIO4_VBASE		(OMAP35XX_L4_PERIPH_VBASE  + OMAP35XX_GPIO4_OFFSET)
+#define	OMAP35XX_GPIO4_SIZE			0x00001000UL
+#define	OMAP35XX_GPIO5_HWBASE		(OMAP35XX_L4_PERIPH_HWBASE + OMAP35XX_GPIO5_OFFSET)
+#define	OMAP35XX_GPIO5_VBASE		(OMAP35XX_L4_PERIPH_VBASE  + OMAP35XX_GPIO5_OFFSET)
+#define	OMAP35XX_GPIO5_SIZE			0x00001000UL
+#define	OMAP35XX_GPIO6_HWBASE		(OMAP35XX_L4_PERIPH_HWBASE + OMAP35XX_GPIO6_OFFSET)
+#define	OMAP35XX_GPIO6_VBASE		(OMAP35XX_L4_PERIPH_VBASE  + OMAP35XX_GPIO6_OFFSET)
+#define	OMAP35XX_GPIO6_SIZE			0x00001000UL
+
+
+
+/* Register offsets within the banks above */
+#define OMAP35XX_GPIO_SYSCONFIG			0x010
+#define OMAP35XX_GPIO_SYSSTATUS			0x014
+#define OMAP35XX_GPIO_IRQSTATUS1		0x018
+#define OMAP35XX_GPIO_IRQENABLE1		0x01C
+#define OMAP35XX_GPIO_WAKEUPENABLE		0x020
+#define OMAP35XX_GPIO_IRQSTATUS2		0x028
+#define OMAP35XX_GPIO_IRQENABLE2		0x02C
+#define OMAP35XX_GPIO_CTRL				0x030
+#define OMAP35XX_GPIO_OE				0x034
+#define OMAP35XX_GPIO_DATAIN			0x038
+#define OMAP35XX_GPIO_DATAOUT			0x03C
+#define OMAP35XX_GPIO_LEVELDETECT0		0x040
+#define OMAP35XX_GPIO_LEVELDETECT1		0x044
+#define OMAP35XX_GPIO_RISINGDETECT		0x048
+#define OMAP35XX_GPIO_FALLINGDETECT		0x04C
+#define OMAP35XX_GPIO_DEBOUNCENABLE		0x050
+#define OMAP35XX_GPIO_DEBOUNCINGTIME	0x054
+#define OMAP35XX_GPIO_CLEARIRQENABLE1	0x060
+#define OMAP35XX_GPIO_SETIRQENABLE1		0x064
+#define OMAP35XX_GPIO_CLEARIRQENABLE2	0x070
+#define OMAP35XX_GPIO_SETIRQENABLE2		0x074
+#define OMAP35XX_GPIO_CLEARWKUENA		0x080
+#define OMAP35XX_GPIO_SETWKUENA			0x084
+#define OMAP35XX_GPIO_CLEARDATAOUT		0x090
+#define OMAP35XX_GPIO_SETDATAOUT		0x094
+
+
+/*
+ * MMC/SD/SDIO
+ */
+
+/* Base addresses for the MMC/SD/SDIO modules */
+#define	OMAP35XX_MMCHS1_HWBASE		(OMAP35XX_L4_CORE_HWBASE + 0x0009C000)
+#define	OMAP35XX_MMCHS1_VBASE		(OMAP35XX_L4_CORE_VBASE + 0x0009C000)
+#define	OMAP35XX_MMCHS2_HWBASE		(OMAP35XX_L4_CORE_HWBASE + 0x000B4000)
+#define	OMAP35XX_MMCHS2_VBASE		(OMAP35XX_L4_CORE_VBASE + 0x000B4000)
+#define	OMAP35XX_MMCHS3_HWBASE		(OMAP35XX_L4_CORE_HWBASE + 0x000AD000)
+#define	OMAP35XX_MMCHS3_VBASE		(OMAP35XX_L4_CORE_VBASE + 0x000AD000)
+#define	OMAP35XX_MMCHS_SIZE			0x00000200UL
+
+/* Register offsets within each of the MMC/SD/SDIO controllers */
+#define OMAP35XX_MMCHS_SYSCONFIG	0x010
+#define OMAP35XX_MMCHS_SYSSTATUS	0x014
+#define OMAP35XX_MMCHS_CSRE			0x024
+#define OMAP35XX_MMCHS_SYSTEST		0x028
+#define OMAP35XX_MMCHS_CON			0x02C
+#define OMAP35XX_MMCHS_PWCNT		0x030
+#define OMAP35XX_MMCHS_BLK			0x104
+#define OMAP35XX_MMCHS_ARG			0x108
+#define OMAP35XX_MMCHS_CMD			0x10C
+#define OMAP35XX_MMCHS_RSP10		0x110
+#define OMAP35XX_MMCHS_RSP32		0x114
+#define OMAP35XX_MMCHS_RSP54		0x118
+#define OMAP35XX_MMCHS_RSP76		0x11C
+#define OMAP35XX_MMCHS_DATA			0x120
+#define OMAP35XX_MMCHS_PSTATE		0x124
+#define OMAP35XX_MMCHS_HCTL			0x128
+#define OMAP35XX_MMCHS_SYSCTL		0x12C
+#define OMAP35XX_MMCHS_STAT			0x130
+#define OMAP35XX_MMCHS_IE			0x134
+#define OMAP35XX_MMCHS_ISE			0x138
+#define OMAP35XX_MMCHS_AC12			0x13C
+#define OMAP35XX_MMCHS_CAPA			0x140
+#define OMAP35XX_MMCHS_CUR_CAPA		0x148
+#define OMAP35XX_MMCHS_REV			0x1FC
+
+
+
+#endif /* _OMAP35XX_REG_H_ */


Property changes on: trunk/sys/arm/ti/omap3/omap3_reg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/omap4/files.omap4
===================================================================
--- trunk/sys/arm/ti/omap4/files.omap4	                        (rev 0)
+++ trunk/sys/arm/ti/omap4/files.omap4	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,20 @@
+#$FreeBSD: stable/10/sys/arm/ti/omap4/files.omap4 266751 2014-05-27 15:30:24Z ian $
+
+arm/arm/gic.c					standard
+arm/arm/mpcore_timer.c				standard
+arm/ti/ti_smc.S					standard
+
+arm/ti/usb/omap_ehci.c				optional	usb ehci
+arm/ti/ti_sdma.c				optional	ti_sdma
+arm/ti/ti_sdhci.c 				optional	sdhci
+#arm/ti/ti_mmchs.c				optional	mmc
+
+arm/ti/omap4/omap4_l2cache.c			optional	pl310
+arm/ti/omap4/omap4_prcm_clks.c			standard
+arm/ti/omap4/omap4_scm_padconf.c		standard
+arm/ti/omap4/omap4_mp.c				optional	smp
+
+arm/ti/twl/twl.c				optional	twl
+arm/ti/twl/twl_vreg.c				optional	twl twl_vreg
+arm/ti/twl/twl_clks.c				optional	twl twl_clks
+


Property changes on: trunk/sys/arm/ti/omap4/files.omap4
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/ti/omap4/omap4_l2cache.c
===================================================================
--- trunk/sys/arm/ti/omap4/omap4_l2cache.c	                        (rev 0)
+++ trunk/sys/arm/ti/omap4/omap4_l2cache.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,83 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Olivier Houchard.  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 ``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 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: stable/10/sys/arm/ti/omap4/omap4_l2cache.c 266375 2014-05-17 23:07:26Z ian $");
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/rman.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+
+#include <arm/ti/ti_smc.h>
+#include <arm/ti/omap4/omap4_smc.h>
+#include <machine/bus.h>
+#include <machine/pl310.h>
+
+void
+platform_pl310_init(struct pl310_softc *sc)
+{
+	uint32_t aux, prefetch;
+
+	aux = pl310_read4(sc, PL310_AUX_CTRL);
+	prefetch = pl310_read4(sc, PL310_PREFETCH_CTRL);
+
+	/*
+	 * Disable instruction prefetch
+	 */
+	prefetch &= ~PREFETCH_CTRL_INSTR_PREFETCH;
+	aux &= ~AUX_CTRL_INSTR_PREFETCH;
+
+	// prefetch &= ~PREFETCH_CTRL_DATA_PREFETCH;
+	// aux &= ~AUX_CTRL_DATA_PREFETCH;
+
+	/*
+	 * Make sure data prefetch is on
+	 */
+	prefetch |= PREFETCH_CTRL_DATA_PREFETCH;
+	aux |= AUX_CTRL_DATA_PREFETCH;
+
+	/*
+	 * TODO: add tunable for prefetch offset
+	 * and experiment with performance
+	 */
+
+	ti_smc0(aux, 0, WRITE_AUXCTRL_REG);
+	ti_smc0(prefetch, 0, WRITE_PREFETCH_CTRL_REG);
+}
+
+void
+platform_pl310_write_ctrl(struct pl310_softc *sc, uint32_t val)
+{
+	ti_smc0(val, 0, L2CACHE_WRITE_CTRL_REG);
+}
+
+void
+platform_pl310_write_debug(struct pl310_softc *sc, uint32_t val)
+{
+	ti_smc0(val, 0, L2CACHE_WRITE_DEBUG_REG);
+}


Property changes on: trunk/sys/arm/ti/omap4/omap4_l2cache.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/omap4/omap4_mp.c
===================================================================
--- trunk/sys/arm/ti/omap4/omap4_mp.c	                        (rev 0)
+++ trunk/sys/arm/ti/omap4/omap4_mp.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,85 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Olivier Houchard.  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 ``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 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: stable/10/sys/arm/ti/omap4/omap4_mp.c 266203 2014-05-16 00:14:50Z ian $");
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/smp.h>
+
+#include <machine/smp.h>
+#include <machine/fdt.h>
+#include <machine/intr.h>
+
+#include <arm/ti/ti_smc.h>
+#include <arm/ti/omap4/omap4_smc.h>
+
+void
+platform_mp_init_secondary(void)
+{
+	gic_init_secondary();
+}
+
+void
+platform_mp_setmaxid(void)
+{
+
+        mp_maxid = 1;
+}
+
+int
+platform_mp_probe(void)
+{
+
+	mp_ncpus = 2;
+	return (1);
+}
+
+void    
+platform_mp_start_ap(void)
+{
+	bus_addr_t scu_addr;
+
+	if (bus_space_map(fdtbus_bs_tag, 0x48240000, 0x1000, 0, &scu_addr) != 0)
+		panic("Couldn't map the SCU\n");
+	/* Enable the SCU */
+	*(volatile unsigned int *)scu_addr |= 1;
+	//*(volatile unsigned int *)(scu_addr + 0x30) |= 1;
+	cpu_idcache_wbinv_all();
+	cpu_l2cache_wbinv_all();
+	ti_smc0(0x200, 0xfffffdff, MODIFY_AUX_CORE_0);
+	ti_smc0(pmap_kextract((vm_offset_t)mpentry), 0, WRITE_AUX_CORE_1);
+	armv7_sev();
+	bus_space_unmap(fdtbus_bs_tag, scu_addr, 0x1000);
+}
+
+void
+platform_ipi_send(cpuset_t cpus, u_int ipi)
+{
+	pic_ipi_send(cpus, ipi);
+}


Property changes on: trunk/sys/arm/ti/omap4/omap4_mp.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/omap4/omap4_prcm_clks.c
===================================================================
--- trunk/sys/arm/ti/omap4/omap4_prcm_clks.c	                        (rev 0)
+++ trunk/sys/arm/ti/omap4/omap4_prcm_clks.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,1429 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2011
+ *	Ben Gray <ben.r.gray at gmail.com>.
+ * 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.
+ * 3. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BEN GRAY ``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 BEN GRAY 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: stable/10/sys/arm/ti/omap4/omap4_prcm_clks.c 283338 2015-05-23 23:08:54Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+#include <machine/resource.h>
+#include <machine/intr.h>
+
+#include <arm/arm/mpcore_timervar.h>
+#include <arm/ti/tivar.h>
+#include <arm/ti/ti_prcm.h>
+#include <arm/ti/omap4/omap4_reg.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+/*
+ *	This file defines the clock configuration for the OMAP4xxx series of
+ *	devices.
+ *
+ *	How This is Suppose to Work
+ *	===========================
+ *	- There is a top level omap_prcm module that defines all OMAP SoC drivers
+ *	should use to enable/disable the system clocks regardless of the version
+ *	of OMAP device they are running on.  This top level PRCM module is just
+ *	a thin shim to chip specific functions that perform the donkey work of
+ *	configuring the clock - this file is the 'donkey' for OMAP44xx devices.
+ *
+ *	- The key bit in this file is the omap_clk_devmap array, it's
+ *	used by the omap_prcm driver to determine what clocks are valid and which
+ *	functions to call to manipulate them.
+ *
+ *	- In essence you just need to define some callbacks for each of the
+ *	clocks and then you're done.
+ *
+ *	- The other thing that is worth noting is that when the omap_prcm device
+ *	is registered you typically pass in some memory ranges which are the
+ *	SYS_MEMORY resources.  These resources are in turn allocated using 
+ *	bus_allocate_resources(...) and the resource handles are passed to all
+ *	individual clock callback handlers. 
+ *
+ *
+ *
+ *	OMAP4 devices are different from the previous OMAP3 devices in that there
+ *	is no longer a separate functional and interface clock for each module,
+ *	instead there is typically an interface clock that spans many modules.
+ */
+
+#define FREQ_96MHZ    96000000
+#define FREQ_64MHZ    64000000
+#define FREQ_48MHZ    48000000
+#define FREQ_32KHZ    32000
+
+/**
+ *	We need three memory regions to cover all the clock configuration registers.
+ *	
+ *	   PRM Instance -  0x4A30 6000 : 0x4A30 8000
+ *	   CM1 Instance -  0x4A00 4000 : 0x4A00 5000
+ *	   CM2 Instance -  0x4A00 8000 : 0x4A00 A000
+ *
+ */
+#define PRM_INSTANCE_MEM_REGION    0
+#define CM1_INSTANCE_MEM_REGION    1
+#define CM2_INSTANCE_MEM_REGION    2
+
+/**
+ *	Address offsets from the PRM memory region to the top level clock control
+ *	registers.
+ */
+#define CKGEN_PRM_OFFSET               0x00000100UL
+#define MPU_PRM_OFFSET                 0x00000300UL
+#define DSP_PRM_OFFSET                 0x00000400UL
+#define ABE_PRM_OFFSET                 0x00000500UL
+#define ALWAYS_ON_PRM_OFFSET           0x00000600UL
+#define CORE_PRM_OFFSET                0x00000700UL
+#define IVAHD_PRM_OFFSET               0x00000F00UL
+#define CAM_PRM_OFFSET                 0x00001000UL
+#define DSS_PRM_OFFSET                 0x00001100UL
+#define SGX_PRM_OFFSET                 0x00001200UL
+#define L3INIT_PRM_OFFSET              0x00001300UL
+#define L4PER_PRM_OFFSET               0x00001400UL
+#define WKUP_PRM_OFFSET                0x00001700UL
+#define WKUP_CM_OFFSET                 0x00001800UL
+#define EMU_PRM_OFFSET                 0x00001900UL
+#define EMU_CM_OFFSET                  0x00001A00UL
+#define DEVICE_PRM_OFFSET              0x00001B00UL
+#define INSTR_PRM_OFFSET               0x00001F00UL
+
+#define CM_ABE_DSS_SYS_CLKSEL_OFFSET   (CKGEN_PRM_OFFSET + 0x0000UL)
+#define CM_L4_WKUP_CLKSELL_OFFSET      (CKGEN_PRM_OFFSET + 0x0008UL)
+#define CM_ABE_PLL_REF_CLKSEL_OFFSET   (CKGEN_PRM_OFFSET + 0x000CUL)
+#define CM_SYS_CLKSEL_OFFSET           (CKGEN_PRM_OFFSET + 0x0010UL)
+
+/**
+ *	Address offsets from the CM1 memory region to the top level clock control
+ *	registers.
+ */
+#define CKGEN_CM1_OFFSET               0x00000100UL
+#define MPU_CM1_OFFSET                 0x00000300UL
+#define DSP_CM1_OFFSET                 0x00000400UL
+#define ABE_CM1_OFFSET                 0x00000500UL
+#define RESTORE_CM1_OFFSET             0x00000E00UL
+#define INSTR_CM1_OFFSET               0x00000F00UL
+
+#define CM_CLKSEL_DPLL_MPU             (CKGEN_CM1_OFFSET + 0x006CUL)
+
+/**
+ *	Address offsets from the CM2 memory region to the top level clock control
+ *	registers.
+ */
+#define INTRCONN_SOCKET_CM2_OFFSET     0x00000000UL
+#define CKGEN_CM2_OFFSET               0x00000100UL
+#define ALWAYS_ON_CM2_OFFSET           0x00000600UL
+#define CORE_CM2_OFFSET                0x00000700UL
+#define IVAHD_CM2_OFFSET               0x00000F00UL
+#define CAM_CM2_OFFSET                 0x00001000UL
+#define DSS_CM2_OFFSET                 0x00001100UL
+#define SGX_CM2_OFFSET                 0x00001200UL
+#define L3INIT_CM2_OFFSET              0x00001300UL
+#define L4PER_CM2_OFFSET               0x00001400UL
+#define RESTORE_CM2_OFFSET             0x00001E00UL
+#define INSTR_CM2_OFFSET               0x00001F00UL
+
+#define CLKCTRL_MODULEMODE_MASK       0x00000003UL
+#define CLKCTRL_MODULEMODE_DISABLE    0x00000000UL
+#define CLKCTRL_MODULEMODE_AUTO       0x00000001UL
+#define CLKCTRL_MODULEMODE_ENABLE     0x00000001UL
+
+#define CLKCTRL_IDLEST_MASK           0x00030000UL
+#define CLKCTRL_IDLEST_ENABLED        0x00000000UL
+#define CLKCTRL_IDLEST_WAKING         0x00010000UL
+#define CLKCTRL_IDLEST_IDLE           0x00020000UL
+#define CLKCTRL_IDLEST_DISABLED       0x00030000UL
+
+static struct resource_spec omap4_scm_res_spec[] = {
+	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },	/* Control memory window */
+	{ SYS_RES_MEMORY,	1,	RF_ACTIVE },	/* Control memory window */
+	{ SYS_RES_MEMORY,	2,	RF_ACTIVE },	/* Control memory window */
+	{ -1, 0 }
+};
+
+struct omap4_prcm_softc {
+	struct resource	*sc_res[3];
+};
+
+static struct omap4_prcm_softc *omap4_prcm_sc;
+
+static int omap4_clk_generic_activate(struct ti_clock_dev *clkdev);
+static int omap4_clk_generic_deactivate(struct ti_clock_dev *clkdev);
+static int omap4_clk_generic_accessible(struct ti_clock_dev *clkdev);
+static int omap4_clk_generic_set_source(struct ti_clock_dev *clkdev, clk_src_t clksrc);
+static int omap4_clk_generic_get_source_freq(struct ti_clock_dev *clkdev, unsigned int *freq);
+
+static int omap4_clk_gptimer_set_source(struct ti_clock_dev *clkdev, clk_src_t clksrc);
+static int omap4_clk_gptimer_get_source_freq(struct ti_clock_dev *clkdev, unsigned int *freq);
+
+static int omap4_clk_hsmmc_set_source(struct ti_clock_dev *clkdev, clk_src_t clksrc);
+static int omap4_clk_hsmmc_get_source_freq(struct ti_clock_dev *clkdev, unsigned int *freq);
+
+static int omap4_clk_hsusbhost_set_source(struct ti_clock_dev *clkdev, clk_src_t clksrc);
+static int omap4_clk_hsusbhost_activate(struct ti_clock_dev *clkdev);
+static int omap4_clk_hsusbhost_deactivate(struct ti_clock_dev *clkdev);
+static int omap4_clk_hsusbhost_accessible(struct ti_clock_dev *clkdev);
+
+static int omap4_clk_get_sysclk_freq(struct ti_clock_dev *clkdev, unsigned int *freq);
+static int omap4_clk_get_arm_fclk_freq(struct ti_clock_dev *clkdev, unsigned int *freq);
+
+/**
+ *	omap_clk_devmap - Array of clock devices available on OMAP4xxx devices
+ *
+ *	This map only defines which clocks are valid and the callback functions
+ *	for clock activate, deactivate, etc.  It is used by the top level omap_prcm
+ *	driver.
+ *
+ *	The actual details of the clocks (config registers, bit fields, sources,
+ *	etc) are in the private g_omap3_clk_details array below.
+ *
+ */
+
+#define OMAP4_GENERIC_CLOCK_DEV(i) \
+	{	.id = (i), \
+		.clk_activate = omap4_clk_generic_activate, \
+		.clk_deactivate = omap4_clk_generic_deactivate, \
+		.clk_set_source = omap4_clk_generic_set_source, \
+		.clk_accessible = omap4_clk_generic_accessible, \
+		.clk_get_source_freq = omap4_clk_generic_get_source_freq \
+	}
+
+#define OMAP4_GPTIMER_CLOCK_DEV(i) \
+	{	.id = (i), \
+		.clk_activate = omap4_clk_generic_activate, \
+		.clk_deactivate = omap4_clk_generic_deactivate, \
+		.clk_set_source = omap4_clk_gptimer_set_source, \
+		.clk_accessible = omap4_clk_generic_accessible, \
+		.clk_get_source_freq = omap4_clk_gptimer_get_source_freq \
+	}
+
+#define OMAP4_HSMMC_CLOCK_DEV(i) \
+	{	.id = (i), \
+		.clk_activate = omap4_clk_generic_activate, \
+		.clk_deactivate = omap4_clk_generic_deactivate, \
+		.clk_set_source = omap4_clk_hsmmc_set_source, \
+		.clk_accessible = omap4_clk_generic_accessible, \
+		.clk_get_source_freq = omap4_clk_hsmmc_get_source_freq \
+	}
+
+#define OMAP4_HSUSBHOST_CLOCK_DEV(i) \
+	{	.id = (i), \
+		.clk_activate = omap4_clk_hsusbhost_activate, \
+		.clk_deactivate = omap4_clk_hsusbhost_deactivate, \
+		.clk_set_source = omap4_clk_hsusbhost_set_source, \
+		.clk_accessible = omap4_clk_hsusbhost_accessible, \
+		.clk_get_source_freq = NULL \
+	}
+
+
+struct ti_clock_dev ti_clk_devmap[] = {
+
+	/* System clocks */
+	{	.id                  = SYS_CLK,
+		.clk_activate        = NULL,
+		.clk_deactivate      = NULL,
+		.clk_set_source      = NULL,
+		.clk_accessible      = NULL,
+		.clk_get_source_freq = omap4_clk_get_sysclk_freq,
+	},
+	/* MPU (ARM) core clocks */
+	{	.id                  = MPU_CLK,
+		.clk_activate        = NULL,
+		.clk_deactivate      = NULL,
+		.clk_set_source      = NULL,
+		.clk_accessible      = NULL,
+		.clk_get_source_freq = omap4_clk_get_arm_fclk_freq,
+	},
+
+
+	/* UART device clocks */
+	OMAP4_GENERIC_CLOCK_DEV(UART1_CLK),
+	OMAP4_GENERIC_CLOCK_DEV(UART2_CLK),
+	OMAP4_GENERIC_CLOCK_DEV(UART3_CLK),
+	OMAP4_GENERIC_CLOCK_DEV(UART4_CLK),
+	
+	/* Timer device source clocks */
+	OMAP4_GPTIMER_CLOCK_DEV(GPTIMER1_CLK),
+	OMAP4_GPTIMER_CLOCK_DEV(GPTIMER2_CLK),
+	OMAP4_GPTIMER_CLOCK_DEV(GPTIMER3_CLK),
+	OMAP4_GPTIMER_CLOCK_DEV(GPTIMER4_CLK),
+	OMAP4_GPTIMER_CLOCK_DEV(GPTIMER5_CLK),
+	OMAP4_GPTIMER_CLOCK_DEV(GPTIMER6_CLK),
+	OMAP4_GPTIMER_CLOCK_DEV(GPTIMER7_CLK),
+	OMAP4_GPTIMER_CLOCK_DEV(GPTIMER8_CLK),
+	OMAP4_GPTIMER_CLOCK_DEV(GPTIMER9_CLK),
+	OMAP4_GPTIMER_CLOCK_DEV(GPTIMER10_CLK),
+	OMAP4_GPTIMER_CLOCK_DEV(GPTIMER11_CLK),
+	
+	/* MMC device clocks (MMC1 and MMC2 can have different input clocks) */
+	OMAP4_HSMMC_CLOCK_DEV(MMC1_CLK),
+	OMAP4_HSMMC_CLOCK_DEV(MMC2_CLK),
+	OMAP4_GENERIC_CLOCK_DEV(MMC3_CLK),
+	OMAP4_GENERIC_CLOCK_DEV(MMC4_CLK),
+	OMAP4_GENERIC_CLOCK_DEV(MMC5_CLK),
+
+	/* USB HS (high speed TLL, EHCI and OHCI) */
+	OMAP4_HSUSBHOST_CLOCK_DEV(USBTLL_CLK),
+	OMAP4_HSUSBHOST_CLOCK_DEV(USBHSHOST_CLK),
+	OMAP4_HSUSBHOST_CLOCK_DEV(USBFSHOST_CLK),
+	OMAP4_HSUSBHOST_CLOCK_DEV(USBP1_PHY_CLK),
+	OMAP4_HSUSBHOST_CLOCK_DEV(USBP2_PHY_CLK),
+	OMAP4_HSUSBHOST_CLOCK_DEV(USBP1_UTMI_CLK),
+	OMAP4_HSUSBHOST_CLOCK_DEV(USBP2_UTMI_CLK),
+	OMAP4_HSUSBHOST_CLOCK_DEV(USBP1_HSIC_CLK),
+	OMAP4_HSUSBHOST_CLOCK_DEV(USBP2_HSIC_CLK),
+	
+	/* GPIO */
+	OMAP4_GENERIC_CLOCK_DEV(GPIO1_CLK),
+	OMAP4_GENERIC_CLOCK_DEV(GPIO2_CLK),
+	OMAP4_GENERIC_CLOCK_DEV(GPIO3_CLK),
+	OMAP4_GENERIC_CLOCK_DEV(GPIO4_CLK),
+	OMAP4_GENERIC_CLOCK_DEV(GPIO5_CLK),
+	OMAP4_GENERIC_CLOCK_DEV(GPIO6_CLK),
+	
+	/* sDMA */
+	OMAP4_GENERIC_CLOCK_DEV(SDMA_CLK),	
+
+	/* I2C */
+	OMAP4_GENERIC_CLOCK_DEV(I2C1_CLK),
+	OMAP4_GENERIC_CLOCK_DEV(I2C2_CLK),
+	OMAP4_GENERIC_CLOCK_DEV(I2C3_CLK),
+	OMAP4_GENERIC_CLOCK_DEV(I2C4_CLK),
+
+	{  INVALID_CLK_IDENT, NULL, NULL, NULL, NULL }
+};
+
+/**
+ *	omap4_clk_details - Stores details for all the different clocks supported
+ *
+ *	Whenever an operation on a clock is being performed (activated, deactivated,
+ *	etc) this array is looked up to find the correct register and bit(s) we
+ *	should be modifying.
+ *
+ */
+struct omap4_clk_details {
+	clk_ident_t id;
+	
+	uint32_t    mem_region;
+	uint32_t    clksel_reg;
+	
+	int32_t     src_freq;
+	
+	uint32_t    enable_mode;
+};
+
+#define OMAP4_GENERIC_CLOCK_DETAILS(i, f, m, r, e) \
+	{	.id = (i), \
+		.mem_region = (m), \
+		.clksel_reg = (r), \
+		.src_freq = (f), \
+		.enable_mode = (e), \
+	}
+
+static struct omap4_clk_details g_omap4_clk_details[] = {
+
+	/* UART */
+	OMAP4_GENERIC_CLOCK_DETAILS(UART1_CLK, FREQ_48MHZ, CM2_INSTANCE_MEM_REGION,
+		(L4PER_CM2_OFFSET + 0x0140), CLKCTRL_MODULEMODE_ENABLE),
+	OMAP4_GENERIC_CLOCK_DETAILS(UART2_CLK, FREQ_48MHZ, CM2_INSTANCE_MEM_REGION,
+		(L4PER_CM2_OFFSET + 0x0148), CLKCTRL_MODULEMODE_ENABLE),
+	OMAP4_GENERIC_CLOCK_DETAILS(UART3_CLK, FREQ_48MHZ, CM2_INSTANCE_MEM_REGION,
+		(L4PER_CM2_OFFSET + 0x0140), CLKCTRL_MODULEMODE_ENABLE),
+	OMAP4_GENERIC_CLOCK_DETAILS(UART4_CLK, FREQ_48MHZ, CM2_INSTANCE_MEM_REGION,
+		(L4PER_CM2_OFFSET + 0x0148), CLKCTRL_MODULEMODE_ENABLE),
+
+	/* General purpose timers */
+	OMAP4_GENERIC_CLOCK_DETAILS(GPTIMER1_CLK,  -1, PRM_INSTANCE_MEM_REGION,
+		(WKUP_CM_OFFSET + 0x040), CLKCTRL_MODULEMODE_ENABLE),
+	OMAP4_GENERIC_CLOCK_DETAILS(GPTIMER2_CLK,  -1, CM2_INSTANCE_MEM_REGION,
+		(L4PER_CM2_OFFSET + 0x038), CLKCTRL_MODULEMODE_ENABLE),
+	OMAP4_GENERIC_CLOCK_DETAILS(GPTIMER3_CLK,  -1, CM2_INSTANCE_MEM_REGION,
+		(L4PER_CM2_OFFSET + 0x040), CLKCTRL_MODULEMODE_ENABLE),
+	OMAP4_GENERIC_CLOCK_DETAILS(GPTIMER4_CLK,  -1, CM2_INSTANCE_MEM_REGION,
+		(L4PER_CM2_OFFSET + 0x048), CLKCTRL_MODULEMODE_ENABLE),
+	OMAP4_GENERIC_CLOCK_DETAILS(GPTIMER5_CLK,  -1, CM1_INSTANCE_MEM_REGION,
+		(ABE_CM1_OFFSET + 0x068), CLKCTRL_MODULEMODE_ENABLE),
+	OMAP4_GENERIC_CLOCK_DETAILS(GPTIMER6_CLK,  -1, CM1_INSTANCE_MEM_REGION,
+		(ABE_CM1_OFFSET + 0x070), CLKCTRL_MODULEMODE_ENABLE),
+	OMAP4_GENERIC_CLOCK_DETAILS(GPTIMER7_CLK,  -1, CM1_INSTANCE_MEM_REGION,
+		(ABE_CM1_OFFSET + 0x078), CLKCTRL_MODULEMODE_ENABLE),
+	OMAP4_GENERIC_CLOCK_DETAILS(GPTIMER8_CLK,  -1, CM1_INSTANCE_MEM_REGION,
+		(ABE_CM1_OFFSET + 0x080), CLKCTRL_MODULEMODE_ENABLE),
+	OMAP4_GENERIC_CLOCK_DETAILS(GPTIMER9_CLK,  -1, CM2_INSTANCE_MEM_REGION,
+		(L4PER_CM2_OFFSET + 0x050), CLKCTRL_MODULEMODE_ENABLE),
+	OMAP4_GENERIC_CLOCK_DETAILS(GPTIMER10_CLK, -1, CM2_INSTANCE_MEM_REGION,
+		(L4PER_CM2_OFFSET + 0x028), CLKCTRL_MODULEMODE_ENABLE),
+	OMAP4_GENERIC_CLOCK_DETAILS(GPTIMER11_CLK, -1, CM2_INSTANCE_MEM_REGION,
+		(L4PER_CM2_OFFSET + 0x030), CLKCTRL_MODULEMODE_ENABLE),
+
+	/* HSMMC (MMC1 and MMC2 can have different input clocks) */
+	OMAP4_GENERIC_CLOCK_DETAILS(MMC1_CLK, -1, CM2_INSTANCE_MEM_REGION,
+		(L3INIT_CM2_OFFSET + 0x028), /*CLKCTRL_MODULEMODE_ENABLE*/2),
+	OMAP4_GENERIC_CLOCK_DETAILS(MMC2_CLK, -1, CM2_INSTANCE_MEM_REGION,
+		(L3INIT_CM2_OFFSET + 0x030), /*CLKCTRL_MODULEMODE_ENABLE*/2),
+	OMAP4_GENERIC_CLOCK_DETAILS(MMC3_CLK, FREQ_48MHZ, CM2_INSTANCE_MEM_REGION,
+		(L4PER_CM2_OFFSET + 0x120), /*CLKCTRL_MODULEMODE_ENABLE*/2),
+	OMAP4_GENERIC_CLOCK_DETAILS(MMC4_CLK, FREQ_48MHZ, CM2_INSTANCE_MEM_REGION,
+		(L4PER_CM2_OFFSET + 0x128), /*CLKCTRL_MODULEMODE_ENABLE*/2),
+	OMAP4_GENERIC_CLOCK_DETAILS(MMC5_CLK, FREQ_48MHZ, CM2_INSTANCE_MEM_REGION,
+	       (L4PER_CM2_OFFSET + 0x160), /*CLKCTRL_MODULEMODE_ENABLE*/1),
+	
+	/* GPIO modules */
+	OMAP4_GENERIC_CLOCK_DETAILS(GPIO1_CLK, -1, PRM_INSTANCE_MEM_REGION,
+		(WKUP_CM_OFFSET + 0x038), CLKCTRL_MODULEMODE_AUTO),
+	OMAP4_GENERIC_CLOCK_DETAILS(GPIO2_CLK, -1, CM2_INSTANCE_MEM_REGION,
+		(L4PER_CM2_OFFSET + 0x060), CLKCTRL_MODULEMODE_AUTO),
+	OMAP4_GENERIC_CLOCK_DETAILS(GPIO3_CLK, -1, CM2_INSTANCE_MEM_REGION,
+		(L4PER_CM2_OFFSET + 0x068), CLKCTRL_MODULEMODE_AUTO),
+	OMAP4_GENERIC_CLOCK_DETAILS(GPIO4_CLK, -1, CM2_INSTANCE_MEM_REGION,
+		(L4PER_CM2_OFFSET + 0x070), CLKCTRL_MODULEMODE_AUTO),
+	OMAP4_GENERIC_CLOCK_DETAILS(GPIO5_CLK, -1, CM2_INSTANCE_MEM_REGION,
+		(L4PER_CM2_OFFSET + 0x078), CLKCTRL_MODULEMODE_AUTO),
+	OMAP4_GENERIC_CLOCK_DETAILS(GPIO6_CLK, -1, CM2_INSTANCE_MEM_REGION,
+		(L4PER_CM2_OFFSET + 0x080), CLKCTRL_MODULEMODE_AUTO),
+		
+	/* sDMA block */
+	OMAP4_GENERIC_CLOCK_DETAILS(SDMA_CLK, -1, CM2_INSTANCE_MEM_REGION,
+		(CORE_CM2_OFFSET + 0x300), CLKCTRL_MODULEMODE_AUTO),
+
+	/* I2C modules */
+	OMAP4_GENERIC_CLOCK_DETAILS(I2C1_CLK, -1, CM2_INSTANCE_MEM_REGION,
+		(L4PER_CM2_OFFSET + 0x0A0), CLKCTRL_MODULEMODE_ENABLE),
+	OMAP4_GENERIC_CLOCK_DETAILS(I2C2_CLK, -1, CM2_INSTANCE_MEM_REGION,
+		(L4PER_CM2_OFFSET + 0x0A8), CLKCTRL_MODULEMODE_ENABLE),
+	OMAP4_GENERIC_CLOCK_DETAILS(I2C3_CLK, -1, CM2_INSTANCE_MEM_REGION,
+		(L4PER_CM2_OFFSET + 0x0B0), CLKCTRL_MODULEMODE_ENABLE),
+	OMAP4_GENERIC_CLOCK_DETAILS(I2C4_CLK, -1, CM2_INSTANCE_MEM_REGION,
+		(L4PER_CM2_OFFSET + 0x0B8), CLKCTRL_MODULEMODE_ENABLE),
+
+	{ INVALID_CLK_IDENT, 0, 0, 0, 0 },
+};
+
+/**
+ *	MAX_MODULE_ENABLE_WAIT - the number of loops to wait for the module to come
+ *	alive.
+ *
+ */
+#define MAX_MODULE_ENABLE_WAIT    100
+	
+/**
+ *	ARRAY_SIZE - Macro to return the number of elements in a static const array.
+ *
+ */
+#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
+
+/**
+ *	omap4_clk_details - writes a 32-bit value to one of the timer registers
+ *	@timer: Timer device context
+ *	@off: The offset of a register from the timer register address range
+ *	@val: The value to write into the register
+ *
+ *
+ *	RETURNS:
+ *	nothing
+ */
+static struct omap4_clk_details*
+omap4_clk_details(clk_ident_t id)
+{
+	struct omap4_clk_details *walker;
+
+	for (walker = g_omap4_clk_details; walker->id != INVALID_CLK_IDENT; walker++) {
+		if (id == walker->id)
+			return (walker);
+	}
+
+	return NULL;
+}
+	
+/**
+ *	omap4_clk_generic_activate - checks if a module is accessible
+ *	@module: identifier for the module to check, see omap3_prcm.h for a list
+ *	         of possible modules.
+ *	         Example: OMAP3_MODULE_MMC1
+ *	
+ *	
+ *
+ *	LOCKING:
+ *	Inherits the locks from the omap_prcm driver, no internal locking.
+ *
+ *	RETURNS:
+ *	Returns 0 on success or a positive error code on failure.
+ */
+static int
+omap4_clk_generic_activate(struct ti_clock_dev *clkdev)
+{
+	struct omap4_prcm_softc *sc = omap4_prcm_sc;
+	struct omap4_clk_details* clk_details;
+	struct resource* clk_mem_res;
+	uint32_t clksel;
+	unsigned int i;
+
+	if (sc == NULL)
+		return ENXIO;
+
+	clk_details = omap4_clk_details(clkdev->id);
+
+	if (clk_details == NULL)
+		return (ENXIO);
+
+	clk_mem_res = sc->sc_res[clk_details->mem_region];
+
+	if (clk_mem_res == NULL)
+		return (EINVAL);
+	
+	/* All the 'generic' clocks have a CLKCTRL register which is more or less
+	 * generic - the have at least two fielda called MODULEMODE and IDLEST.
+	 */
+	clksel = bus_read_4(clk_mem_res, clk_details->clksel_reg);
+	clksel &= ~CLKCTRL_MODULEMODE_MASK;
+	clksel |=  clk_details->enable_mode;
+	bus_write_4(clk_mem_res, clk_details->clksel_reg, clksel);
+
+	/* Now poll on the IDLEST register to tell us if the module has come up.
+	 * TODO: We need to take into account the parent clocks.
+	 */
+	
+	/* Try MAX_MODULE_ENABLE_WAIT number of times to check if enabled */
+	for (i = 0; i < MAX_MODULE_ENABLE_WAIT; i++) {
+		clksel = bus_read_4(clk_mem_res, clk_details->clksel_reg);
+		if ((clksel & CLKCTRL_IDLEST_MASK) == CLKCTRL_IDLEST_ENABLED)
+			break;
+		DELAY(10);
+	}
+		
+	/* Check the enabled state */
+	if ((clksel & CLKCTRL_IDLEST_MASK) != CLKCTRL_IDLEST_ENABLED) {
+		printf("Error: failed to enable module with clock %d\n", clkdev->id);
+		printf("Error: 0x%08x => 0x%08x\n", clk_details->clksel_reg, clksel);
+		return (ETIMEDOUT);
+	}
+	
+	return (0);
+}
+
+/**
+ *	omap4_clk_generic_deactivate - checks if a module is accessible
+ *	@module: identifier for the module to check, see omap3_prcm.h for a list
+ *	         of possible modules.
+ *	         Example: OMAP3_MODULE_MMC1
+ *	
+ *	
+ *
+ *	LOCKING:
+ *	Inherits the locks from the omap_prcm driver, no internal locking.
+ *
+ *	RETURNS:
+ *	Returns 0 on success or a positive error code on failure.
+ */
+static int
+omap4_clk_generic_deactivate(struct ti_clock_dev *clkdev)
+{
+	struct omap4_prcm_softc *sc = omap4_prcm_sc;
+	struct omap4_clk_details* clk_details;
+	struct resource* clk_mem_res;
+	uint32_t clksel;
+
+	if (sc == NULL)
+		return ENXIO;
+
+	clk_details = omap4_clk_details(clkdev->id);
+
+	if (clk_details == NULL)
+		return (ENXIO);
+
+	clk_mem_res = sc->sc_res[clk_details->mem_region];
+
+	if (clk_mem_res == NULL)
+		return (EINVAL);
+	
+	/* All the 'generic' clocks have a CLKCTRL register which is more or less
+	 * generic - the have at least two fielda called MODULEMODE and IDLEST.
+	 */
+	clksel = bus_read_4(clk_mem_res, clk_details->clksel_reg);
+	clksel &= ~CLKCTRL_MODULEMODE_MASK;
+	clksel |=  CLKCTRL_MODULEMODE_DISABLE;
+	bus_write_4(clk_mem_res, clk_details->clksel_reg, clksel);
+
+	return (0);
+}
+
+/**
+ *	omap4_clk_generic_set_source - checks if a module is accessible
+ *	@module: identifier for the module to check, see omap3_prcm.h for a list
+ *	         of possible modules.
+ *	         Example: OMAP3_MODULE_MMC1
+ *	
+ *	
+ *
+ *	LOCKING:
+ *	Inherits the locks from the omap_prcm driver, no internal locking.
+ *
+ *	RETURNS:
+ *	Returns 0 on success or a positive error code on failure.
+ */
+static int
+omap4_clk_generic_set_source(struct ti_clock_dev *clkdev,
+                             clk_src_t clksrc)
+{
+
+	return (0);
+}
+
+/**
+ *	omap4_clk_generic_accessible - checks if a module is accessible
+ *	@module: identifier for the module to check, see omap3_prcm.h for a list
+ *	         of possible modules.
+ *	         Example: OMAP3_MODULE_MMC1
+ *	
+ *	
+ *
+ *	LOCKING:
+ *	Inherits the locks from the omap_prcm driver, no internal locking.
+ *
+ *	RETURNS:
+ *	Returns 0 on success or a negative error code on failure.
+ */
+static int
+omap4_clk_generic_accessible(struct ti_clock_dev *clkdev)
+{
+	struct omap4_prcm_softc *sc = omap4_prcm_sc;
+	struct omap4_clk_details* clk_details;
+	struct resource* clk_mem_res;
+	uint32_t clksel;
+
+	if (sc == NULL)
+		return ENXIO;
+
+	clk_details = omap4_clk_details(clkdev->id);
+
+	if (clk_details == NULL)
+		return (ENXIO);
+
+	clk_mem_res = sc->sc_res[clk_details->mem_region];
+
+	if (clk_mem_res == NULL)
+		return (EINVAL);
+	
+	clksel = bus_read_4(clk_mem_res, clk_details->clksel_reg);
+		
+	/* Check the enabled state */
+	if ((clksel & CLKCTRL_IDLEST_MASK) != CLKCTRL_IDLEST_ENABLED)
+		return (0);
+	
+	return (1);
+}
+
+/**
+ *	omap4_clk_generic_get_source_freq - checks if a module is accessible
+ *	@module: identifier for the module to check, see omap3_prcm.h for a list
+ *	         of possible modules.
+ *	         Example: OMAP3_MODULE_MMC1
+ *	
+ *	
+ *
+ *	LOCKING:
+ *	Inherits the locks from the omap_prcm driver, no internal locking.
+ *
+ *	RETURNS:
+ *	Returns 0 on success or a negative error code on failure.
+ */
+static int
+omap4_clk_generic_get_source_freq(struct ti_clock_dev *clkdev,
+                                  unsigned int *freq
+                                  )
+{
+	struct omap4_clk_details* clk_details = omap4_clk_details(clkdev->id);
+
+	if (clk_details == NULL)
+		return (ENXIO);
+	
+	/* Simply return the stored frequency */
+	if (freq)
+		*freq = (unsigned int)clk_details->src_freq;
+	
+	return (0);
+}
+
+
+/**
+ *	omap4_clk_gptimer_set_source - checks if a module is accessible
+ *	@module: identifier for the module to check, see omap3_prcm.h for a list
+ *	         of possible modules.
+ *	         Example: OMAP3_MODULE_MMC1
+ *	
+ *	
+ *
+ *	LOCKING:
+ *	Inherits the locks from the omap_prcm driver, no internal locking.
+ *
+ *	RETURNS:
+ *	Returns 0 on success or a negative error code on failure.
+ */
+static int
+omap4_clk_gptimer_set_source(struct ti_clock_dev *clkdev,
+                             clk_src_t clksrc)
+{
+	struct omap4_prcm_softc *sc = omap4_prcm_sc;
+	struct omap4_clk_details* clk_details;
+	struct resource* clk_mem_res;
+
+	if (sc == NULL)
+		return ENXIO;
+
+	clk_details = omap4_clk_details(clkdev->id);
+
+	if (clk_details == NULL)
+		return (ENXIO);
+
+	clk_mem_res = sc->sc_res[clk_details->mem_region];
+
+	if (clk_mem_res == NULL)
+		return (EINVAL);
+	
+	/* TODO: Implement */
+	
+	return (0);
+}
+
+/**
+ *	omap4_clk_gptimer_get_source_freq - checks if a module is accessible
+ *	@module: identifier for the module to check, see omap3_prcm.h for a list
+ *	         of possible modules.
+ *	         Example: OMAP3_MODULE_MMC1
+ *	
+ *	
+ *
+ *	LOCKING:
+ *	Inherits the locks from the omap_prcm driver, no internal locking.
+ *
+ *	RETURNS:
+ *	Returns 0 on success or a negative error code on failure.
+ */
+static int
+omap4_clk_gptimer_get_source_freq(struct ti_clock_dev *clkdev,
+                                  unsigned int *freq
+                                  )
+{
+	struct omap4_prcm_softc *sc = omap4_prcm_sc;
+	struct omap4_clk_details* clk_details;
+	struct resource* clk_mem_res;
+	uint32_t clksel;
+	unsigned int src_freq;
+
+	if (sc == NULL)
+		return ENXIO;
+
+	clk_details = omap4_clk_details(clkdev->id);
+
+	if (clk_details == NULL)
+		return (ENXIO);
+
+	clk_mem_res = sc->sc_res[clk_details->mem_region];
+
+	if (clk_mem_res == NULL)
+		return (EINVAL);
+	
+	/* Need to read the CLKSEL field to determine the clock source */
+	clksel = bus_read_4(clk_mem_res, clk_details->clksel_reg);
+	if (clksel & (0x1UL << 24))
+		src_freq = FREQ_32KHZ;
+	else
+		omap4_clk_get_sysclk_freq(NULL, &src_freq);
+	
+	/* Return the frequency */
+	if (freq)
+		*freq = src_freq;
+	
+	return (0);
+}
+
+/**
+ *	omap4_clk_hsmmc_set_source - sets the source clock (freq)
+ *	@clkdev: pointer to the clockdev structure (id field will contain clock id)
+ *	
+ *	The MMC 1 and 2 clocks can be source from either a 64MHz or 96MHz clock.
+ *
+ *	LOCKING:
+ *	Inherits the locks from the omap_prcm driver, no internal locking.
+ *
+ *	RETURNS:
+ *	Returns 0 on success or a negative error code on failure.
+ */
+static int
+omap4_clk_hsmmc_set_source(struct ti_clock_dev *clkdev,
+                           clk_src_t clksrc)
+{
+	struct omap4_prcm_softc *sc = omap4_prcm_sc;
+	struct omap4_clk_details* clk_details;
+	struct resource* clk_mem_res;
+	uint32_t clksel;
+
+	if (sc == NULL)
+		return ENXIO;
+
+	clk_details = omap4_clk_details(clkdev->id);
+
+	if (clk_details == NULL)
+		return (ENXIO);
+
+	clk_mem_res = sc->sc_res[clk_details->mem_region];
+
+	if (clk_mem_res == NULL)
+		return (EINVAL);
+		
+	/* For MMC modules 3, 4 & 5 you can't change the freq, it's always 48MHz */
+	if ((clkdev->id == MMC3_CLK) || (clkdev->id == MMC4_CLK) ||
+	    (clkdev->id == MMC5_CLK)) {
+		if (clksrc != F48MHZ_CLK)
+			return (EINVAL);
+		return 0;
+	}
+
+	
+	clksel = bus_read_4(clk_mem_res, clk_details->clksel_reg);
+
+	/* Bit 24 is set if 96MHz clock or cleared for 64MHz clock */
+	if (clksrc == F64MHZ_CLK)
+		clksel &= ~(0x1UL << 24);
+	else if (clksrc == F96MHZ_CLK)
+		clksel |= (0x1UL << 24);
+	else
+		return (EINVAL);
+		
+	bus_write_4(clk_mem_res, clk_details->clksel_reg, clksel);
+	
+	return (0);
+}
+
+/**
+ *	omap4_clk_hsmmc_get_source_freq - checks if a module is accessible
+ *	@clkdev: pointer to the clockdev structure (id field will contain clock id)
+ *	
+ *	
+ *
+ *	LOCKING:
+ *	Inherits the locks from the omap_prcm driver, no internal locking.
+ *
+ *	RETURNS:
+ *	Returns 0 on success or a negative error code on failure.
+ */
+static int
+omap4_clk_hsmmc_get_source_freq(struct ti_clock_dev *clkdev,
+                                unsigned int *freq
+                                )
+{
+	struct omap4_prcm_softc *sc = omap4_prcm_sc;
+	struct omap4_clk_details* clk_details;
+	struct resource* clk_mem_res;
+	uint32_t clksel;
+	unsigned int src_freq;
+
+	if (sc == NULL)
+		return ENXIO;
+
+	clk_details = omap4_clk_details(clkdev->id);
+
+	if (clk_details == NULL)
+		return (ENXIO);
+
+	clk_mem_res = sc->sc_res[clk_details->mem_region];
+
+	if (clk_mem_res == NULL)
+		return (EINVAL);
+	
+	switch (clkdev->id) {
+	case MMC1_CLK:
+	case MMC2_CLK:
+		/* Need to read the CLKSEL field to determine the clock source */
+		clksel = bus_read_4(clk_mem_res, clk_details->clksel_reg);
+		if (clksel & (0x1UL << 24))
+			src_freq = FREQ_96MHZ;
+		else
+			src_freq = FREQ_64MHZ;
+		break;
+	case MMC3_CLK:
+	case MMC4_CLK:
+	case MMC5_CLK:
+		src_freq = FREQ_48MHZ;
+		break;
+	default:
+		return (EINVAL);
+	}
+		
+	/* Return the frequency */
+	if (freq)
+		*freq = src_freq;
+	
+	return (0);
+}
+
+/**
+ *	omap4_clk_get_sysclk_freq - gets the sysclk frequency
+ *	@sc: pointer to the clk module/device context
+ *
+ *	Read the clocking information from the power-control/boot-strap registers,
+ *  and stored in two global variables.
+ *
+ *	RETURNS:
+ *	nothing, values are saved in global variables
+ */
+static int
+omap4_clk_get_sysclk_freq(struct ti_clock_dev *clkdev,
+                          unsigned int *freq)
+{
+	uint32_t clksel;
+	uint32_t sysclk;
+	struct omap4_prcm_softc *sc = omap4_prcm_sc;
+	
+	if (sc == NULL)
+		return ENXIO;
+
+	/* Read the input clock freq from the configuration register (CM_SYS_CLKSEL) */
+	clksel = bus_read_4(sc->sc_res[PRM_INSTANCE_MEM_REGION], CM_SYS_CLKSEL_OFFSET);
+	switch (clksel & 0x7) {
+	case 0x1:
+		/* 12Mhz */
+		sysclk = 12000000;
+		break;
+	case 0x3:
+		/* 16.8Mhz */
+		sysclk = 16800000;
+		break;
+	case 0x4:
+		/* 19.2Mhz */
+		sysclk = 19200000;
+		break;
+	case 0x5:
+		/* 26Mhz */
+		sysclk = 26000000;
+		break;
+	case 0x7:
+		/* 38.4Mhz */
+		sysclk = 38400000;
+		break;
+	default:
+		panic("%s: Invalid clock freq", __func__);
+	}
+
+	/* Return the value */
+	if (freq)
+		*freq = sysclk;
+		
+	return (0);
+}
+
+/**
+ *	omap4_clk_get_arm_fclk_freq - gets the MPU clock frequency
+ *	@clkdev: ignored
+ *	@freq: pointer which upon return will contain the freq in hz
+ *	@mem_res: array of allocated memory resources
+ *
+ *	Reads the frequency setting information registers and returns the value
+ *	in the freq variable.
+ *
+ *	RETURNS:
+ *	returns 0 on success, a positive error code on failure.
+ */
+static int
+omap4_clk_get_arm_fclk_freq(struct ti_clock_dev *clkdev,
+                            unsigned int *freq)
+{
+	uint32_t clksel;
+	uint32_t pll_mult, pll_div;
+	uint32_t mpuclk, sysclk;
+	struct omap4_prcm_softc *sc = omap4_prcm_sc;
+
+	if (sc == NULL)
+		return ENXIO;
+
+	/* Read the clksel register which contains the DPLL multiple and divide
+	 * values.  These are applied to the sysclk.
+	 */
+	clksel = bus_read_4(sc->sc_res[CM1_INSTANCE_MEM_REGION], CM_CLKSEL_DPLL_MPU);
+
+	pll_mult = ((clksel >> 8) & 0x7ff);
+	pll_div = (clksel & 0x7f) + 1;
+	
+	
+	/* Get the system clock freq */
+	omap4_clk_get_sysclk_freq(NULL, &sysclk);
+
+
+	/* Calculate the MPU freq */
+	mpuclk = ((uint64_t)sysclk * pll_mult) / pll_div;
+
+	/* Return the value */
+	if (freq)
+		*freq = mpuclk;
+		
+	return (0);
+}
+
+/**
+ *	omap4_clk_hsusbhost_activate - activates the USB clocks for the given module
+ *	@clkdev: pointer to the clock device structure.
+ *	@mem_res: array of memory resources allocated by the top level PRCM driver.
+ *	
+ *	The USB clocking setup seems to be a bit more tricky than the other modules,
+ *	to start with the clocking diagram for the HS host module shows 13 different
+ *	clocks.  So to try and make it easier to follow the clocking activation
+ *	and deactivation is handled in it's own set of callbacks.
+ *
+ *	LOCKING:
+ *	Inherits the locks from the omap_prcm driver, no internal locking.
+ *
+ *	RETURNS:
+ *	Returns 0 on success or a positive error code on failure.
+ */
+
+struct dpll_param {
+	unsigned int m;
+	unsigned int n;
+	unsigned int m2;
+	unsigned int m3;
+	unsigned int m4;
+	unsigned int m5;
+	unsigned int m6;
+	unsigned int m7;
+};
+/* USB parameters */
+struct dpll_param usb_dpll_param[7] = {
+	/* 12M values */
+	{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
+	/* 13M values */
+	{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
+	/* 16.8M values */
+	{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
+	/* 19.2M values */
+	{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
+	/* 26M values */
+	{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
+	/* 27M values */
+	{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
+	/* 38.4M values */
+#ifdef CONFIG_OMAP4_SDC
+	{0x32, 0x1, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0},
+#else
+	{0x32, 0x1, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0},
+#endif
+};
+static int
+omap4_clk_hsusbhost_activate(struct ti_clock_dev *clkdev)
+{
+	struct omap4_prcm_softc *sc = omap4_prcm_sc;
+	struct resource* clk_mem_res;
+	uint32_t clksel_reg_off;
+	uint32_t clksel;
+	unsigned int i;
+
+	if (sc == NULL)
+		return ENXIO;
+
+	switch (clkdev->id) {
+	case USBTLL_CLK:
+		/* For the USBTLL module we need to enable the following clocks:
+		 *  - INIT_L4_ICLK  (will be enabled by bootloader)
+		 *  - TLL_CH0_FCLK
+		 *  - TLL_CH1_FCLK
+		 */
+
+		/* We need the CM_L3INIT_HSUSBTLL_CLKCTRL register in CM2 register set */
+		clk_mem_res = sc->sc_res[CM2_INSTANCE_MEM_REGION];
+		clksel_reg_off = L3INIT_CM2_OFFSET + 0x68;
+	
+		/* Enable the module and also enable the optional func clocks for
+		 * channels 0 & 1 (is this needed ?)
+		 */
+		clksel = bus_read_4(clk_mem_res, clksel_reg_off);
+		clksel &= ~CLKCTRL_MODULEMODE_MASK;
+		clksel |=  CLKCTRL_MODULEMODE_ENABLE;
+		
+		clksel |= (0x1 << 8); /* USB-HOST optional clock: USB_CH0_CLK */
+		clksel |= (0x1 << 9); /* USB-HOST optional clock: USB_CH1_CLK */
+		break;
+
+	case USBHSHOST_CLK:
+	case USBP1_PHY_CLK:
+	case USBP2_PHY_CLK:
+	case USBP1_UTMI_CLK:
+	case USBP2_UTMI_CLK:
+	case USBP1_HSIC_CLK:
+	case USBP2_HSIC_CLK:
+		/* For the USB HS HOST module we need to enable the following clocks:
+		 *  - INIT_L4_ICLK     (will be enabled by bootloader)
+		 *  - INIT_L3_ICLK     (will be enabled by bootloader)
+		 *  - INIT_48MC_FCLK
+		 *  - UTMI_ROOT_GFCLK  (UTMI only, create a new clock for that ?)
+		 *  - UTMI_P1_FCLK     (UTMI only, create a new clock for that ?)
+		 *  - UTMI_P2_FCLK     (UTMI only, create a new clock for that ?)
+		 *  - HSIC_P1_60       (HSIC only, create a new clock for that ?)
+		 *  - HSIC_P1_480      (HSIC only, create a new clock for that ?)
+		 *  - HSIC_P2_60       (HSIC only, create a new clock for that ?)
+		 *  - HSIC_P2_480      (HSIC only, create a new clock for that ?)
+		 */
+
+		/* We need the CM_L3INIT_HSUSBHOST_CLKCTRL register in CM2 register set */
+		clk_mem_res = sc->sc_res[CM2_INSTANCE_MEM_REGION];
+		clksel_reg_off = L3INIT_CM2_OFFSET + 0x58;
+		clksel = bus_read_4(clk_mem_res, clksel_reg_off);	
+		/* Enable the module and also enable the optional func clocks */
+		if (clkdev->id == USBHSHOST_CLK) {
+			clksel &= ~CLKCTRL_MODULEMODE_MASK;
+			clksel |=  /*CLKCTRL_MODULEMODE_ENABLE*/2;
+
+			clksel |= (0x1 << 15); /* USB-HOST clock control: FUNC48MCLK */
+		}
+		
+		else if (clkdev->id == USBP1_UTMI_CLK)
+			clksel |= (0x1 << 8);  /* UTMI_P1_CLK */
+		else if (clkdev->id == USBP2_UTMI_CLK)
+			clksel |= (0x1 << 9);  /* UTMI_P2_CLK */
+
+		else if (clkdev->id == USBP1_HSIC_CLK)
+			clksel |= (0x5 << 11);  /* HSIC60M_P1_CLK + HSIC480M_P1_CLK */
+		else if (clkdev->id == USBP2_HSIC_CLK)
+			clksel |= (0x5 << 12);  /* HSIC60M_P2_CLK + HSIC480M_P2_CLK */
+		
+		break;
+	
+	default:
+		return (EINVAL);
+	}
+	
+	bus_write_4(clk_mem_res, clksel_reg_off, clksel);
+	
+	/* Try MAX_MODULE_ENABLE_WAIT number of times to check if enabled */
+	for (i = 0; i < MAX_MODULE_ENABLE_WAIT; i++) {
+		clksel = bus_read_4(clk_mem_res, clksel_reg_off);
+		if ((clksel & CLKCTRL_IDLEST_MASK) == CLKCTRL_IDLEST_ENABLED)
+			break;
+	}
+		
+	/* Check the enabled state */
+	if ((clksel & CLKCTRL_IDLEST_MASK) != CLKCTRL_IDLEST_ENABLED) {
+		printf("Error: HERE failed to enable module with clock %d\n", clkdev->id);
+		printf("Error: 0x%08x => 0x%08x\n", clksel_reg_off, clksel);
+		return (ETIMEDOUT);
+	}
+	
+	return (0);
+}
+
+/**
+ *	omap4_clk_generic_deactivate - checks if a module is accessible
+ *	@clkdev: pointer to the clock device structure.
+ *	@mem_res: array of memory resources allocated by the top level PRCM driver.
+ *	
+ *	
+ *
+ *	LOCKING:
+ *	Inherits the locks from the omap_prcm driver, no internal locking.
+ *
+ *	RETURNS:
+ *	Returns 0 on success or a positive error code on failure.
+ */
+static int
+omap4_clk_hsusbhost_deactivate(struct ti_clock_dev *clkdev)
+{
+	struct omap4_prcm_softc *sc = omap4_prcm_sc;
+	struct resource* clk_mem_res;
+	uint32_t clksel_reg_off;
+	uint32_t clksel;
+
+	if (sc == NULL)
+		return ENXIO;
+
+	switch (clkdev->id) {
+	case USBTLL_CLK:
+		/* We need the CM_L3INIT_HSUSBTLL_CLKCTRL register in CM2 register set */
+		clk_mem_res = sc->sc_res[CM2_INSTANCE_MEM_REGION];
+		clksel_reg_off = L3INIT_CM2_OFFSET + 0x68;
+	
+		clksel = bus_read_4(clk_mem_res, clksel_reg_off);
+		clksel &= ~CLKCTRL_MODULEMODE_MASK;
+		clksel |=  CLKCTRL_MODULEMODE_DISABLE;
+		break;
+
+	case USBHSHOST_CLK:
+	case USBP1_PHY_CLK:
+	case USBP2_PHY_CLK:
+	case USBP1_UTMI_CLK:
+	case USBP2_UTMI_CLK:
+	case USBP1_HSIC_CLK:
+	case USBP2_HSIC_CLK:
+		/* For the USB HS HOST module we need to enable the following clocks:
+		 *  - INIT_L4_ICLK     (will be enabled by bootloader)
+		 *  - INIT_L3_ICLK     (will be enabled by bootloader)
+		 *  - INIT_48MC_FCLK
+		 *  - UTMI_ROOT_GFCLK  (UTMI only, create a new clock for that ?)
+		 *  - UTMI_P1_FCLK     (UTMI only, create a new clock for that ?)
+		 *  - UTMI_P2_FCLK     (UTMI only, create a new clock for that ?)
+		 *  - HSIC_P1_60       (HSIC only, create a new clock for that ?)
+		 *  - HSIC_P1_480      (HSIC only, create a new clock for that ?)
+		 *  - HSIC_P2_60       (HSIC only, create a new clock for that ?)
+		 *  - HSIC_P2_480      (HSIC only, create a new clock for that ?)
+		 */
+
+		/* We need the CM_L3INIT_HSUSBHOST_CLKCTRL register in CM2 register set */
+		clk_mem_res = sc->sc_res[CM2_INSTANCE_MEM_REGION];
+		clksel_reg_off = L3INIT_CM2_OFFSET + 0x58;
+		clksel = bus_read_4(clk_mem_res, clksel_reg_off);
+
+		/* Enable the module and also enable the optional func clocks */
+		if (clkdev->id == USBHSHOST_CLK) {
+			clksel &= ~CLKCTRL_MODULEMODE_MASK;
+			clksel |=  CLKCTRL_MODULEMODE_DISABLE;
+
+			clksel &= ~(0x1 << 15); /* USB-HOST clock control: FUNC48MCLK */
+		}
+		
+		else if (clkdev->id == USBP1_UTMI_CLK)
+			clksel &= ~(0x1 << 8);  /* UTMI_P1_CLK */
+		else if (clkdev->id == USBP2_UTMI_CLK)
+			clksel &= ~(0x1 << 9);  /* UTMI_P2_CLK */
+
+		else if (clkdev->id == USBP1_HSIC_CLK)
+			clksel &= ~(0x5 << 11);  /* HSIC60M_P1_CLK + HSIC480M_P1_CLK */
+		else if (clkdev->id == USBP2_HSIC_CLK)
+			clksel &= ~(0x5 << 12);  /* HSIC60M_P2_CLK + HSIC480M_P2_CLK */
+		
+		break;
+	
+	default:
+		return (EINVAL);
+	}
+	
+	bus_write_4(clk_mem_res, clksel_reg_off, clksel);
+
+	return (0);
+}
+
+/**
+ *	omap4_clk_hsusbhost_accessible - checks if a module is accessible
+ *	@clkdev: pointer to the clock device structure.
+ *	@mem_res: array of memory resources allocated by the top level PRCM driver.
+ *	
+ *	
+ *
+ *	LOCKING:
+ *	Inherits the locks from the omap_prcm driver, no internal locking.
+ *
+ *	RETURNS:
+ *	Returns 0 if module is not enable, 1 if module is enabled or a negative
+ *	error code on failure.
+ */
+static int
+omap4_clk_hsusbhost_accessible(struct ti_clock_dev *clkdev)
+{
+	struct omap4_prcm_softc *sc = omap4_prcm_sc;
+	struct resource* clk_mem_res;
+	uint32_t clksel_reg_off;
+	uint32_t clksel;
+
+	if (sc == NULL)
+		return ENXIO;
+
+	if (clkdev->id == USBTLL_CLK) {
+		/* We need the CM_L3INIT_HSUSBTLL_CLKCTRL register in CM2 register set */
+		clk_mem_res = sc->sc_res[CM2_INSTANCE_MEM_REGION];
+		clksel_reg_off = L3INIT_CM2_OFFSET + 0x68;
+	}
+	else if (clkdev->id == USBHSHOST_CLK) {
+		/* We need the CM_L3INIT_HSUSBHOST_CLKCTRL register in CM2 register set */
+		clk_mem_res = sc->sc_res[CM2_INSTANCE_MEM_REGION];
+		clksel_reg_off = L3INIT_CM2_OFFSET + 0x58;
+	}
+	else {
+		return (EINVAL);
+	}
+
+	clksel = bus_read_4(clk_mem_res, clksel_reg_off);
+		
+	/* Check the enabled state */
+	if ((clksel & CLKCTRL_IDLEST_MASK) != CLKCTRL_IDLEST_ENABLED)
+		return (0);
+	
+	return (1);
+}
+
+/**
+ *	omap4_clk_hsusbhost_set_source - sets the source clocks
+ *	@clkdev: pointer to the clock device structure.
+ *	@clksrc: the clock source ID for the given clock.
+ *	@mem_res: array of memory resources allocated by the top level PRCM driver.
+ *	
+ *	
+ *
+ *	LOCKING:
+ *	Inherits the locks from the omap_prcm driver, no internal locking.
+ *
+ *	RETURNS:
+ *	Returns 0 if sucessful otherwise a negative error code on failure.
+ */
+static int
+omap4_clk_hsusbhost_set_source(struct ti_clock_dev *clkdev,
+                               clk_src_t clksrc)
+{
+	struct omap4_prcm_softc *sc = omap4_prcm_sc;
+	struct resource* clk_mem_res;
+	uint32_t clksel_reg_off;
+	uint32_t clksel;
+	unsigned int bit;
+
+	if (sc == NULL)
+		return ENXIO;
+
+	if (clkdev->id == USBP1_PHY_CLK)
+		bit = 24;
+	else if (clkdev->id != USBP2_PHY_CLK)
+		bit = 25;
+	else
+		return (EINVAL);
+	
+	/* We need the CM_L3INIT_HSUSBHOST_CLKCTRL register in CM2 register set */
+	clk_mem_res = sc->sc_res[CM2_INSTANCE_MEM_REGION];
+	clksel_reg_off = L3INIT_CM2_OFFSET + 0x58;
+	clksel = bus_read_4(clk_mem_res, clksel_reg_off);
+	
+	/* Set the clock source to either external or internal */
+	if (clksrc == EXT_CLK)
+		clksel |= (0x1 << bit);
+	else
+		clksel &= ~(0x1 << bit);
+	
+	bus_write_4(clk_mem_res, clksel_reg_off, clksel);
+
+	return (0);
+}
+
+#define PRM_RSTCTRL		0x1b00
+#define PRM_RSTCTRL_RESET	0x2
+
+static void
+omap4_prcm_reset(void)
+{
+	struct omap4_prcm_softc *sc = omap4_prcm_sc;
+	bus_write_4(sc->sc_res[0], PRM_RSTCTRL,
+	    bus_read_4(sc->sc_res[0], PRM_RSTCTRL) | PRM_RSTCTRL_RESET);
+	bus_read_4(sc->sc_res[0], PRM_RSTCTRL);
+}
+
+/**
+ *	omap4_prcm_probe - probe function for the driver
+ *	@dev: prcm device handle
+ *
+ *	Simply sets the name of the driver module.
+ *
+ *	LOCKING:
+ *	None
+ *
+ *	RETURNS:
+ *	Always returns 0
+ */
+static int
+omap4_prcm_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "ti,omap4_prcm"))
+		return (ENXIO);
+
+	device_set_desc(dev, "TI OMAP Power, Reset and Clock Management");
+	return (0);
+}
+
+/**
+ *	omap_prcm_attach - attach function for the driver
+ *	@dev: prcm device handle
+ *
+ *	Allocates and sets up the driver context, this simply entails creating a
+ *	bus mappings for the PRCM register set.
+ *
+ *	LOCKING:
+ *	None
+ *
+ *	RETURNS:
+ *	Always returns 0
+ */
+
+extern uint32_t platform_arm_tmr_freq;
+
+static int
+omap4_prcm_attach(device_t dev)
+{
+	struct omap4_prcm_softc *sc = device_get_softc(dev);
+	unsigned int freq;
+
+	if (bus_alloc_resources(dev, omap4_scm_res_spec, sc->sc_res)) {
+		device_printf(dev, "could not allocate resources\n");
+		return (ENXIO);
+	}
+
+	omap4_prcm_sc = sc;
+	ti_cpu_reset = omap4_prcm_reset;
+	omap4_clk_get_arm_fclk_freq(NULL, &freq);
+	arm_tmr_change_frequency(freq / 2);
+
+	return (0);
+}
+
+static device_method_t omap4_prcm_methods[] = {
+	DEVMETHOD(device_probe, omap4_prcm_probe),
+	DEVMETHOD(device_attach, omap4_prcm_attach),
+	{0, 0},
+};
+
+static driver_t omap4_prcm_driver = {
+	"omap4_prcm",
+	omap4_prcm_methods,
+	sizeof(struct omap4_prcm_softc),
+};
+
+static devclass_t omap4_prcm_devclass;
+
+EARLY_DRIVER_MODULE(omap4_prcm, simplebus, omap4_prcm_driver,
+    omap4_prcm_devclass, 0, 0, BUS_PASS_TIMER + BUS_PASS_ORDER_EARLY);
+MODULE_VERSION(omap4_prcm, 1);


Property changes on: trunk/sys/arm/ti/omap4/omap4_prcm_clks.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/omap4/omap4_reg.h
===================================================================
--- trunk/sys/arm/ti/omap4/omap4_reg.h	                        (rev 0)
+++ trunk/sys/arm/ti/omap4/omap4_reg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,587 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2011
+ *	Ben Gray <ben.r.gray at gmail.com>.
+ * 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 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 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: stable/10/sys/arm/ti/omap4/omap4_reg.h 239281 2012-08-15 06:31:32Z gonzo $
+ */
+
+/*
+ * Texas Instruments - OMAP44xx series processors
+ *
+ * Reference:
+ *  OMAP44xx Applications Processor
+ *   Technical Reference Manual
+ *  (omap44xx_techref.pdf)
+ *
+ *
+ * Note:
+ *  The devices are mapped into address above 0xD000_0000 as the kernel space
+ *  memory is at 0xC000_0000 and above.  The first 256MB after this is reserved
+ *  for the size of the kernel, everything above that is reserved for SoC
+ *  devices.
+ *
+ */
+#ifndef _OMAP44XX_REG_H_
+#define _OMAP44XX_REG_H_
+
+#ifndef _LOCORE
+#include <sys/types.h>		/* for uint32_t */
+#endif
+
+
+
+
+
+/* Physical/Virtual address for SDRAM controller */
+
+#define OMAP44XX_SMS_VBASE			0x6C000000UL
+#define OMAP44XX_SMS_HWBASE			0x6C000000UL
+#define OMAP44XX_SMS_SIZE			0x01000000UL
+
+#define OMAP44XX_SDRC_VBASE			0x6D000000UL
+#define OMAP44XX_SDRC_HWBASE		0x6D000000UL
+#define OMAP44XX_SDRC_SIZE			0x01000000UL
+
+
+
+/* Physical/Virtual address for I/O space */
+
+#define OMAP44XX_L3_EMU_VBASE		0xD4000000UL
+#define OMAP44XX_L3_EMU_HWBASE		0x54000000UL
+#define OMAP44XX_L3_EMU_SIZE		0x00200000UL
+
+#define OMAP44XX_L3_EMIF1_VBASE     0xEC000000UL
+#define OMAP44XX_L3_EMIF1_HWBASE    0x4C000000UL
+#define OMAP44XX_L3_EMIF1_SIZE      0x01000000UL
+
+#define OMAP44XX_L3_EMIF2_VBASE     0xED000000UL
+#define OMAP44XX_L3_EMIF2_HWBASE    0x4D000000UL
+#define OMAP44XX_L3_EMIF2_SIZE      0x01000000UL
+
+
+#define OMAP44XX_L4_CORE_VBASE		0xEA000000UL
+#define OMAP44XX_L4_CORE_HWBASE		0x4A000000UL
+#define OMAP44XX_L4_CORE_SIZE		0x01000000UL
+
+#define OMAP44XX_L4_WAKEUP_VBASE	0xEA300000UL
+#define OMAP44XX_L4_WAKEUP_HWBASE	0x4A300000UL
+#define OMAP44XX_L4_WAKEUP_SIZE		0x00040000UL
+
+#define OMAP44XX_L4_PERIPH_VBASE	0xE8000000UL
+#define OMAP44XX_L4_PERIPH_HWBASE	0x48000000UL
+#define OMAP44XX_L4_PERIPH_SIZE		0x01000000UL
+
+#define OMAP44XX_L4_ABE_VBASE		0xE9000000UL
+#define OMAP44XX_L4_ABE_HWBASE		0x49000000UL
+#define OMAP44XX_L4_ABE_SIZE		0x00100000UL
+
+
+/* Physical/Virtual address for MPU Subsystem space */
+
+#define OMAP44XX_MPU_SUBSYS_VBASE   (OMAP44XX_L4_PERIPH_VBASE + 0x00240000UL)
+#define OMAP44XX_MPU_SUBSYS_HWBASE  (OMAP44XX_L4_PERIPH_HWBASE + 0x00240000UL)
+#define OMAP44XX_MPU_SUBSYS_SIZE    0x00004000UL
+
+/*
+ * MPU Subsystem addresss offsets
+ */
+#define OMAP44XX_SCU_OFFSET                     0x00000000UL
+#define OMAP44XX_GIC_CPU_OFFSET                 0x00000100UL
+#define OMAP44XX_GBL_TIMER_OFFSET               0x00000200UL
+#define OMAP44XX_PRV_TIMER_OFFSET               0x00000600UL
+#define OMAP44XX_GIC_DIST_OFFSET                0x00001000UL
+#define OMAP44XX_PL310_OFFSET                   0x00002000UL
+#define OMAP44XX_CORTEXA9_SOCKET_PRCM_OFFSET    0x00003000UL
+#define OMAP44XX_CORTEXA9_PRM_OFFSET            0x00003200UL
+#define OMAP44XX_CORTEXA9_CPU0_OFFSET           0x00003400UL
+#define OMAP44XX_CORTEXA9_CPU1_OFFSET           0x00003800UL
+
+#define OMAP44XX_SCU_HWBASE         (OMAP44XX_MPU_SUBSYS_HWBASE + OMAP44XX_SCU_OFFSET)
+#define OMAP44XX_SCU_VBASE          (OMAP44XX_MPU_SUBSYS_VBASE  + OMAP44XX_SCU_OFFSET)
+#define OMAP44XX_SCU_SIZE           0x00000080UL
+#define OMAP44XX_GIC_CPU_HWBASE     (OMAP44XX_MPU_SUBSYS_HWBASE + OMAP44XX_GIC_CPU_OFFSET)
+#define OMAP44XX_GIC_CPU_VBASE      (OMAP44XX_MPU_SUBSYS_VBASE  + OMAP44XX_GIC_CPU_OFFSET)
+#define OMAP44XX_GIC_CPU_SIZE       0x00000100UL
+#define OMAP44XX_GBL_TIMER_HWBASE   (OMAP44XX_MPU_SUBSYS_HWBASE + OMAP44XX_GBL_TIMER_OFFSET)
+#define OMAP44XX_GBL_TIMER_VBASE    (OMAP44XX_MPU_SUBSYS_VBASE  + OMAP44XX_GBL_TIMER_OFFSET)
+#define OMAP44XX_GBL_TIMER_SIZE     0x00000100UL
+#define OMAP44XX_PRV_TIMER_HWBASE   (OMAP44XX_MPU_SUBSYS_HWBASE + OMAP44XX_PRV_TIMER_OFFSET)
+#define OMAP44XX_PRV_TIMER_VBASE    (OMAP44XX_MPU_SUBSYS_VBASE  + OMAP44XX_PRV_TIMER_OFFSET)
+#define OMAP44XX_PRV_TIMER_SIZE     0x00000100UL
+#define OMAP44XX_GIC_DIST_HWBASE    (OMAP44XX_MPU_SUBSYS_HWBASE + OMAP44XX_GIC_DIST_OFFSET)
+#define OMAP44XX_GIC_DIST_VBASE     (OMAP44XX_MPU_SUBSYS_VBASE  + OMAP44XX_GIC_DIST_OFFSET)
+#define OMAP44XX_GIC_DIST_SIZE      0x00000100UL
+#define OMAP44XX_PL310_HWBASE       (OMAP44XX_MPU_SUBSYS_HWBASE + OMAP44XX_PL310_OFFSET)
+#define OMAP44XX_PL310_VBASE        (OMAP44XX_MPU_SUBSYS_VBASE  + OMAP44XX_PL310_OFFSET)
+#define OMAP44XX_PL310_SIZE         0x00001000UL
+
+
+
+
+/*
+ * L4-CORE Physical/Virtual addresss offsets
+ */
+#define OMAP44XX_SCM_OFFSET         0x00002000UL
+#define OMAP44XX_CM_OFFSET          0x00004000UL
+#define OMAP44XX_SDMA_OFFSET        0x00056000UL
+#define OMAP44XX_USB_TLL_OFFSET     0x00062000UL
+#define OMAP44XX_USB_UHH_OFFSET     0x00064000UL
+#define OMAP44XX_USB_OHCI_OFFSET    0x00064800UL
+#define OMAP44XX_USB_EHCI_OFFSET    0x00064C00UL
+#define OMAP44XX_MCBSP1_OFFSET      0x00074000UL
+#define OMAP44XX_MCBSP5_OFFSET      0x00096000UL
+#define OMAP44XX_SCM_PADCONF_OFFSET 0x00100000UL
+
+/*
+ * L4-WAKEUP Physical/Virtual addresss offsets
+ */
+#define OMAP44XX_PRM_OFFSET         0x00006000UL
+#define OMAP44XX_SCRM_OFFSET        0x0000A000UL
+#define OMAP44XX_GPIO1_OFFSET       0x00010000UL
+#define OMAP44XX_GPTIMER1_OFFSET    0x00018000UL
+
+
+
+/*
+ * L4-PERIPH Physical/Virtual addresss offsets
+ */
+#define OMAP44XX_UART3_OFFSET		0x00020000UL
+#define OMAP44XX_GPTIMER2_OFFSET	0x00032000UL
+#define OMAP44XX_GPTIMER3_OFFSET	0x00034000UL
+#define OMAP44XX_GPTIMER4_OFFSET	0x00036000UL
+#define OMAP44XX_GPTIMER9_OFFSET	0x0003E000UL
+#define OMAP44XX_GPIO2_OFFSET		0x00055000UL
+#define OMAP44XX_GPIO3_OFFSET		0x00057000UL
+#define OMAP44XX_GPIO4_OFFSET		0x00059000UL
+#define OMAP44XX_GPIO5_OFFSET		0x0005B000UL
+#define OMAP44XX_GPIO6_OFFSET		0x0005D000UL
+#define OMAP44XX_I2C3_OFFSET		0x00060000UL
+#define OMAP44XX_UART1_OFFSET		0x0006A000UL
+#define OMAP44XX_UART2_OFFSET		0x0006C000UL
+#define OMAP44XX_UART4_OFFSET		0x0006E000UL
+#define OMAP44XX_I2C1_OFFSET		0x00070000UL
+#define OMAP44XX_I2C2_OFFSET		0x00072000UL
+#define OMAP44XX_SLIMBUS2_OFFSET	0x00076000UL
+#define OMAP44XX_ELM_OFFSET			0x00078000UL
+#define OMAP44XX_GPTIMER10_OFFSET	0x00086000UL
+#define OMAP44XX_GPTIMER11_OFFSET	0x00088000UL
+#define OMAP44XX_MCBSP4_OFFSET		0x00096000UL
+#define OMAP44XX_MCSPI1_OFFSET		0x00098000UL
+#define OMAP44XX_MCSPI2_OFFSET		0x0009A000UL
+#define OMAP44XX_MMCHS1_OFFSET		0x0009C000UL
+#define OMAP44XX_MMCSD3_OFFSET		0x000AD000UL
+#define OMAP44XX_MMCHS2_OFFSET		0x000B4000UL
+#define OMAP44XX_MMCSD4_OFFSET		0x000D1000UL
+#define OMAP44XX_MMCSD5_OFFSET		0x000D5000UL
+#define OMAP44XX_I2C4_OFFSET		0x00350000UL
+
+/* The following are registers defined as part of the ARM MPCORE system,
+ * they are not SoC components rather registers that control the MPCORE core.
+ */
+// #define OMAP44XX_SCU_OFFSET			0x48240000	/* Snoop control unit */
+// #define OMAP44XX_GIC_PROC_OFFSET	0x48240100	/* Interrupt controller unit */
+// #define OMAP44XX_MPU_TIMER_OFFSET	0x48240600
+// #define OMAP44XX_GIC_INTR_OFFSET	0x48241000
+// #define OMAP44XX_PL310_OFFSET		0x48242000	/* L2 Cache controller */
+
+
+/*
+ * L4-ABE Physical/Virtual addresss offsets
+ */
+#define OMAP44XX_GPTIMER5_OFFSET	0x00038000UL
+#define OMAP44XX_GPTIMER6_OFFSET	0x0003A000UL
+#define OMAP44XX_GPTIMER7_OFFSET	0x0003C000UL
+#define OMAP44XX_GPTIMER8_OFFSET	0x0003E000UL
+
+
+
+
+
+/*
+ * System Control Module
+ */
+#define OMAP44XX_SCM_HWBASE				(OMAP44XX_L4_CORE_HWBASE + OMAP44XX_SCM_OFFSET)
+#define OMAP44XX_SCM_VBASE				(OMAP44XX_L4_CORE_VBASE + OMAP44XX_SCM_OFFSET)
+#define OMAP44XX_SCM_SIZE				0x00001000UL
+
+
+
+/*
+ *
+ */
+#define OMAP44XX_CM_HWBASE				(OMAP44XX_L4_CORE_HWBASE + OMAP44XX_CM_OFFSET)
+#define OMAP44XX_CM_VBASE				(OMAP44XX_L4_CORE_VBASE + OMAP44XX_CM_OFFSET)
+#define OMAP44XX_CM_SIZE				0x00001500UL
+
+
+/*
+ *
+ */
+#define OMAP44XX_PRM_HWBASE				(OMAP44XX_L4_WAKEUP_HWBASE + OMAP44XX_PRM_OFFSET)
+#define OMAP44XX_PRM_VBASE				(OMAP44XX_L4_WAKEUP_VBASE + OMAP44XX_PRM_OFFSET)
+#define OMAP44XX_PRM_SIZE				0x00001600UL
+
+/*
+ *
+ */
+#define OMAP44XX_SCRM_HWBASE            (OMAP44XX_L4_WAKEUP_HWBASE + OMAP44XX_SCRM_OFFSET)
+#define OMAP44XX_SCRM_VBASE             (OMAP44XX_L4_WAKEUP_VBASE + OMAP44XX_SCRM_OFFSET)
+#define OMAP44XX_SCRM_SIZE              0x00000800UL
+
+
+
+/*
+ * Uarts
+ */
+#define OMAP44XX_UART1_HWBASE			(OMAP44XX_L4_CORE_HWBASE + OMAP44XX_UART1_OFFSET)
+#define OMAP44XX_UART1_VBASE			(OMAP44XX_L4_CORE_VBASE  + OMAP44XX_UART1_OFFSET)
+#define OMAP44XX_UART1_SIZE				0x00001000UL
+#define OMAP44XX_UART2_HWBASE			(OMAP44XX_L4_CORE_HWBASE + OMAP44XX_UART2_OFFSET)
+#define OMAP44XX_UART2_VBASE			(OMAP44XX_L4_CORE_VBASE  + OMAP44XX_UART2_OFFSET)
+#define OMAP44XX_UART2_SIZE				0x00001000UL
+#define OMAP44XX_UART3_HWBASE			(OMAP44XX_L4_PERIPH_HWBASE + OMAP44XX_UART3_OFFSET)
+#define OMAP44XX_UART3_VBASE			(OMAP44XX_L4_PERIPH_VBASE  + OMAP44XX_UART3_OFFSET)
+#define OMAP44XX_UART3_SIZE				0x00001000UL
+#define OMAP44XX_UART4_HWBASE			(OMAP44XX_L4_PERIPH_HWBASE + OMAP44XX_UART4_OFFSET)
+#define OMAP44XX_UART4_VBASE			(OMAP44XX_L4_PERIPH_VBASE  + OMAP44XX_UART4_OFFSET)
+#define OMAP44XX_UART4_SIZE				0x00001000UL
+
+
+
+
+/*
+ * I2C Modules
+ */
+#define OMAP44XX_I2C1_HWBASE			(OMAP44XX_L4_CORE_HWBASE + OMAP44XX_I2C1_OFFSET)
+#define OMAP44XX_I2C1_VBASE				(OMAP44XX_L4_CORE_VBASE  + OMAP44XX_I2C1_OFFSET)
+#define OMAP44XX_I2C1_SIZE				0x00000080UL
+#define OMAP44XX_I2C2_HWBASE			(OMAP44XX_L4_CORE_HWBASE + OMAP44XX_I2C2_OFFSET)
+#define OMAP44XX_I2C2_VBASE				(OMAP44XX_L4_CORE_VBASE  + OMAP44XX_I2C2_OFFSET)
+#define OMAP44XX_I2C2_SIZE				0x00000080UL
+#define OMAP44XX_I2C3_HWBASE			(OMAP44XX_L4_CORE_HWBASE + OMAP44XX_I2C3_OFFSET)
+#define OMAP44XX_I2C3_VBASE				(OMAP44XX_L4_CORE_VBASE  + OMAP44XX_I2C3_OFFSET)
+#define OMAP44XX_I2C3_SIZE				0x00000080UL
+
+
+
+/*
+ * McBSP Modules
+ */
+#define OMAP44XX_MCBSP1_HWBASE			(OMAP44XX_L4_CORE_HWBASE + OMAP44XX_MCBSP1_OFFSET)
+#define OMAP44XX_MCBSP1_VBASE			(OMAP44XX_L4_CORE_VBASE  + OMAP44XX_MCBSP1_OFFSET)
+#define OMAP44XX_MCBSP1_SIZE			0x00001000UL
+#define OMAP44XX_MCBSP2_HWBASE			(OMAP44XX_L4_PERIPH_HWBASE + OMAP44XX_MCBSP2_OFFSET)
+#define OMAP44XX_MCBSP2_VBASE			(OMAP44XX_L4_PERIPH_VBASE  + OMAP44XX_MCBSP2_OFFSET)
+#define OMAP44XX_MCBSP2_SIZE			0x00001000UL
+#define OMAP44XX_MCBSP3_HWBASE			(OMAP44XX_L4_PERIPH_HWBASE + OMAP44XX_MCBSP3_OFFSET)
+#define OMAP44XX_MCBSP3_VBASE			(OMAP44XX_L4_PERIPH_VBASE  + OMAP44XX_MCBSP3_OFFSET)
+#define OMAP44XX_MCBSP3_SIZE			0x00001000UL
+#define OMAP44XX_MCBSP4_HWBASE			(OMAP44XX_L4_PERIPH_HWBASE + OMAP44XX_MCBSP4_OFFSET)
+#define OMAP44XX_MCBSP4_VBASE			(OMAP44XX_L4_PERIPH_VBASE  + OMAP44XX_MCBSP4_OFFSET)
+#define OMAP44XX_MCBSP4_SIZE			0x00001000UL
+#define OMAP44XX_MCBSP5_HWBASE			(OMAP44XX_L4_CORE_HWBASE + OMAP44XX_MCBSP5_OFFSET)
+#define OMAP44XX_MCBSP5_VBASE			(OMAP44XX_L4_CORE_VBASE  + OMAP44XX_MCBSP5_OFFSET)
+#define OMAP44XX_MCBSP5_SIZE			0x00001000UL
+
+
+
+/*
+ * USB TTL Module
+ */
+#define OMAP44XX_USB_TLL_HWBASE         (OMAP44XX_L4_CORE_HWBASE + OMAP44XX_USB_TLL_OFFSET)
+#define OMAP44XX_USB_TLL_VBASE          (OMAP44XX_L4_CORE_VBASE  + OMAP44XX_USB_TLL_OFFSET)
+#define OMAP44XX_USB_TLL_SIZE           0x00001000UL
+
+/*
+ * USB Host Module
+ */
+#define OMAP44XX_USB_UHH_HWBASE         (OMAP44XX_L4_CORE_HWBASE + OMAP44XX_USB_UHH_OFFSET)
+#define OMAP44XX_USB_UHH_VBASE          (OMAP44XX_L4_CORE_VBASE  + OMAP44XX_USB_UHH_OFFSET)
+#define OMAP44XX_USB_UHH_SIZE           0x00000700UL
+
+/*
+ * USB OHCI Module
+ */
+#define OMAP44XX_USB_OHCI_HWBASE        (OMAP44XX_L4_CORE_HWBASE + OMAP44XX_USB_OHCI_OFFSET)
+#define OMAP44XX_USB_OHCI_VBASE         (OMAP44XX_L4_CORE_VBASE  + OMAP44XX_USB_OHCI_OFFSET)
+#define OMAP44XX_USB_OHCI_SIZE          0x00000400UL
+
+/*
+ * USB EHCI Module
+ */
+#define OMAP44XX_USB_EHCI_HWBASE        (OMAP44XX_L4_CORE_HWBASE + OMAP44XX_USB_EHCI_OFFSET)
+#define OMAP44XX_USB_EHCI_VBASE         (OMAP44XX_L4_CORE_VBASE  + OMAP44XX_USB_EHCI_OFFSET)
+#define OMAP44XX_USB_EHCI_SIZE          0x0000400UL
+
+
+
+
+
+/*
+ * SDMA Offset
+ *  PA 0x4805 6000
+ */
+
+#define OMAP44XX_SDMA_HWBASE			(OMAP44XX_L4_CORE_HWBASE + OMAP44XX_SDMA_OFFSET)
+#define OMAP44XX_SDMA_VBASE				(OMAP44XX_L4_CORE_VBASE  + OMAP44XX_SDMA_OFFSET)
+#define OMAP44XX_SDMA_SIZE				0x00001000UL
+
+
+
+/*
+ * Interrupt Controller Unit.
+ *
+ *    Refer to the omap4_intr.c file for interrupt controller (GIC)
+ *    implementation.
+ *
+ *    Note:
+ *    - 16 Interprocessor interrupts (IPI): ID[15:0]
+ *    - 2 private Timer/Watchdog interrupts: ID[30:29]
+ *    - 2 legacy nFIQ & nIRQ: one per CPU, bypasses the interrupt distributor
+ *      logic and directly drives interrupt requests into CPU if used in
+ *      legacy mode (else treated like other interrupts lines with ID28
+ *      and ID31 respectively)
+ *    - 128 hardware interrupts: ID[159:32] (rising-edge or high-level sensitive).
+ */
+#define OMAP44XX_HARDIRQ(x)         (32 + (x))
+
+#define OMAP44XX_IRQ_L2CACHE        OMAP44XX_HARDIRQ(0)     /* L2 cache controller interrupt */
+#define OMAP44XX_IRQ_CTI_0          OMAP44XX_HARDIRQ(1)     /* Cross-trigger module 0 (CTI0) interrupt */
+#define OMAP44XX_IRQ_CTI_1          OMAP44XX_HARDIRQ(2)     /* Cross-trigger module 1 (CTI1) interrupt */
+#define OMAP44XX_IRQ_RESERVED3      OMAP44XX_HARDIRQ(3)     /* RESERVED */
+#define OMAP44XX_IRQ_ELM            OMAP44XX_HARDIRQ(4)     /* Error location process completion */
+#define OMAP44XX_IRQ_RESERVED5      OMAP44XX_HARDIRQ(5)     /* RESERVED */
+#define OMAP44XX_IRQ_RESERVED6      OMAP44XX_HARDIRQ(6)     /* RESERVED */
+#define OMAP44XX_IRQ_SYS_NIRQ       OMAP44XX_HARDIRQ(7)     /* External source (active low) */
+#define OMAP44XX_IRQ_RESERVED8      OMAP44XX_HARDIRQ(8)     /* RESERVED */
+#define OMAP44XX_IRQ_L3_DBG         OMAP44XX_HARDIRQ(9)     /* L3 interconnect debug error */
+#define OMAP44XX_IRQ_L3_APP         OMAP44XX_HARDIRQ(10)    /* L3 interconnect application error */
+#define OMAP44XX_IRQ_PRCM_MPU       OMAP44XX_HARDIRQ(11)    /* PRCM module IRQ */
+#define OMAP44XX_IRQ_SDMA0          OMAP44XX_HARDIRQ(12)    /* System DMA request 0(3) */
+#define OMAP44XX_IRQ_SDMA1          OMAP44XX_HARDIRQ(13)    /* System DMA request 1(3) */
+#define OMAP44XX_IRQ_SDMA2          OMAP44XX_HARDIRQ(14)    /* System DMA request 2 */
+#define OMAP44XX_IRQ_SDMA3          OMAP44XX_HARDIRQ(15)    /* System DMA request 3 */
+#define OMAP44XX_IRQ_MCBSP4         OMAP44XX_HARDIRQ(16)    /* McBSP module 4 IRQ */
+#define OMAP44XX_IRQ_MCBSP1         OMAP44XX_HARDIRQ(17)    /* McBSP module 1 IRQ */
+#define OMAP44XX_IRQ_SR1            OMAP44XX_HARDIRQ(18)    /* SmartReflexâ„¢ 1 */
+#define OMAP44XX_IRQ_SR2            OMAP44XX_HARDIRQ(19)    /* SmartReflexâ„¢ 2 */
+#define OMAP44XX_IRQ_GPMC           OMAP44XX_HARDIRQ(20)    /* General-purpose memory controller module */
+#define OMAP44XX_IRQ_SGX            OMAP44XX_HARDIRQ(21)    /* 2D/3D graphics module */
+#define OMAP44XX_IRQ_MCBSP2         OMAP44XX_HARDIRQ(22)    /* McBSP module 2 */
+#define OMAP44XX_IRQ_MCBSP3         OMAP44XX_HARDIRQ(23)    /* McBSP module 3 */
+#define OMAP44XX_IRQ_ISS5           OMAP44XX_HARDIRQ(24)    /* Imaging subsystem interrupt 5 */
+#define OMAP44XX_IRQ_DSS            OMAP44XX_HARDIRQ(25)    /* Display subsystem module(3) */
+#define OMAP44XX_IRQ_MAIL_U0        OMAP44XX_HARDIRQ(26)    /* Mailbox user 0 request */
+#define OMAP44XX_IRQ_C2C_SSCM       OMAP44XX_HARDIRQ(27)    /* C2C status interrupt */
+#define OMAP44XX_IRQ_DSP_MMU        OMAP44XX_HARDIRQ(28)    /* DSP MMU */
+#define OMAP44XX_IRQ_GPIO1_MPU      OMAP44XX_HARDIRQ(29)    /* GPIO module 1(3) */
+#define OMAP44XX_IRQ_GPIO2_MPU      OMAP44XX_HARDIRQ(30)    /* GPIO module 2(3) */
+#define OMAP44XX_IRQ_GPIO3_MPU      OMAP44XX_HARDIRQ(31)    /* GPIO module 3(3) */
+#define OMAP44XX_IRQ_GPIO4_MPU      OMAP44XX_HARDIRQ(32)    /* GPIO module 4(3) */
+#define OMAP44XX_IRQ_GPIO5_MPU      OMAP44XX_HARDIRQ(33)    /* GPIO module 5(3) */
+#define OMAP44XX_IRQ_GPIO6_MPU      OMAP44XX_HARDIRQ(34)    /* GPIO module 6(3) */
+#define OMAP44XX_IRQ_RESERVED35     OMAP44XX_HARDIRQ(35)    /* RESERVED */
+#define OMAP44XX_IRQ_WDT3           OMAP44XX_HARDIRQ(36)    /* Watchdog timer module 3 overflow */
+#define OMAP44XX_IRQ_GPT1           OMAP44XX_HARDIRQ(37)    /* General-purpose timer module 1 */
+#define OMAP44XX_IRQ_GPT2           OMAP44XX_HARDIRQ(38)    /* General-purpose timer module 2 */
+#define OMAP44XX_IRQ_GPT3           OMAP44XX_HARDIRQ(39)    /* General-purpose timer module 3 */
+#define OMAP44XX_IRQ_GPT4           OMAP44XX_HARDIRQ(40)    /* General-purpose timer module 4 */
+#define OMAP44XX_IRQ_GPT5           OMAP44XX_HARDIRQ(41)    /* General-purpose timer module 5 */
+#define OMAP44XX_IRQ_GPT6           OMAP44XX_HARDIRQ(42)    /* General-purpose timer module 6 */
+#define OMAP44XX_IRQ_GPT7           OMAP44XX_HARDIRQ(43)    /* General-purpose timer module 7 */
+#define OMAP44XX_IRQ_GPT8           OMAP44XX_HARDIRQ(44)    /* General-purpose timer module 8 */
+#define OMAP44XX_IRQ_GPT9           OMAP44XX_HARDIRQ(45)    /* General-purpose timer module 9 */
+#define OMAP44XX_IRQ_GPT10          OMAP44XX_HARDIRQ(46)    /* General-purpose timer module 10 */
+#define OMAP44XX_IRQ_GPT11          OMAP44XX_HARDIRQ(47)    /* General-purpose timer module 11 */
+#define OMAP44XX_IRQ_MCSPI4         OMAP44XX_HARDIRQ(48)    /* McSPI module 4 */
+#define OMAP44XX_IRQ_RESERVED49     OMAP44XX_HARDIRQ(49)    /* RESERVED */
+#define OMAP44XX_IRQ_RESERVED50     OMAP44XX_HARDIRQ(50)    /* RESERVED */
+#define OMAP44XX_IRQ_RESERVED51     OMAP44XX_HARDIRQ(51)    /* RESERVED */
+#define OMAP44XX_IRQ_RESERVED52     OMAP44XX_HARDIRQ(52)    /* RESERVED */
+#define OMAP44XX_IRQ_DSS_DSI1       OMAP44XX_HARDIRQ(53)    /* Display Subsystem DSI1 interrupt */
+#define OMAP44XX_IRQ_RESERVED54     OMAP44XX_HARDIRQ(54)    /* RESERVED */
+#define OMAP44XX_IRQ_RESERVED55     OMAP44XX_HARDIRQ(55)    /* RESERVED */
+#define OMAP44XX_IRQ_I2C1           OMAP44XX_HARDIRQ(56)    /* I2C module 1 */
+#define OMAP44XX_IRQ_I2C2           OMAP44XX_HARDIRQ(57)    /* I2C module 2 */
+#define OMAP44XX_IRQ_HDQ            OMAP44XX_HARDIRQ(58)    /* HDQ / One-wire */
+#define OMAP44XX_IRQ_MMC5           OMAP44XX_HARDIRQ(59)    /* MMC5 interrupt */
+#define OMAP44XX_IRQ_RESERVED60     OMAP44XX_HARDIRQ(60)    /* RESERVED */
+#define OMAP44XX_IRQ_I2C3           OMAP44XX_HARDIRQ(61)    /* I2C module 3 */
+#define OMAP44XX_IRQ_I2C4           OMAP44XX_HARDIRQ(62)    /* I2C module 4 */
+#define OMAP44XX_IRQ_RESERVED63     OMAP44XX_HARDIRQ(63)    /* RESERVED */
+#define OMAP44XX_IRQ_RESERVED64     OMAP44XX_HARDIRQ(64)    /* RESERVED */
+#define OMAP44XX_IRQ_MCSPI1         OMAP44XX_HARDIRQ(65)    /* McSPI module 1 */
+#define OMAP44XX_IRQ_MCSPI2         OMAP44XX_HARDIRQ(66)    /* McSPI module 2 */
+#define OMAP44XX_IRQ_HSI_P1         OMAP44XX_HARDIRQ(67)    /* HSI Port 1 interrupt */
+#define OMAP44XX_IRQ_HSI_P2         OMAP44XX_HARDIRQ(68)    /* HSI Port 2 interrupt */
+#define OMAP44XX_IRQ_FDIF_3         OMAP44XX_HARDIRQ(69)    /* Face detect interrupt 3 */
+#define OMAP44XX_IRQ_UART4          OMAP44XX_HARDIRQ(70)    /* UART module 4 interrupt */
+#define OMAP44XX_IRQ_HSI_DMA        OMAP44XX_HARDIRQ(71)    /* HSI DMA engine MPU request */
+#define OMAP44XX_IRQ_UART1          OMAP44XX_HARDIRQ(72)    /* UART module 1 */
+#define OMAP44XX_IRQ_UART2          OMAP44XX_HARDIRQ(73)    /* UART module 2 */
+#define OMAP44XX_IRQ_UART3          OMAP44XX_HARDIRQ(74)    /* UART module 3 (also infrared)(3) */
+#define OMAP44XX_IRQ_PBIAS          OMAP44XX_HARDIRQ(75)    /* Merged interrupt for PBIASlite1 and 2 */
+#define OMAP44XX_IRQ_OHCI           OMAP44XX_HARDIRQ(76)    /* OHCI controller HSUSB MP Host Interrupt */
+#define OMAP44XX_IRQ_EHCI           OMAP44XX_HARDIRQ(77)    /* EHCI controller HSUSB MP Host Interrupt */
+#define OMAP44XX_IRQ_TLL            OMAP44XX_HARDIRQ(78)    /* HSUSB MP TLL Interrupt */
+#define OMAP44XX_IRQ_RESERVED79     OMAP44XX_HARDIRQ(79)    /* RESERVED */
+#define OMAP44XX_IRQ_WDT2           OMAP44XX_HARDIRQ(80)    /* WDTIMER2 interrupt */
+#define OMAP44XX_IRQ_RESERVED81     OMAP44XX_HARDIRQ(81)    /* RESERVED */
+#define OMAP44XX_IRQ_RESERVED82     OMAP44XX_HARDIRQ(82)    /* RESERVED */
+#define OMAP44XX_IRQ_MMC1           OMAP44XX_HARDIRQ(83)    /* MMC/SD module 1 */
+#define OMAP44XX_IRQ_DSS_DSI2       OMAP44XX_HARDIRQ(84)    /* Display subsystem DSI2 interrupt */
+#define OMAP44XX_IRQ_RESERVED85     OMAP44XX_HARDIRQ(85)    /* Reserved */
+#define OMAP44XX_IRQ_MMC2           OMAP44XX_HARDIRQ(86)    /* MMC/SD module 2 */
+#define OMAP44XX_IRQ_MPU_ICR        OMAP44XX_HARDIRQ(87)    /* MPU ICR */
+#define OMAP44XX_IRQ_C2C_GPI        OMAP44XX_HARDIRQ(88)    /* C2C GPI interrupt */
+#define OMAP44XX_IRQ_FSUSB          OMAP44XX_HARDIRQ(89)    /* FS-USB - host controller Interrupt */
+#define OMAP44XX_IRQ_FSUSB_SMI      OMAP44XX_HARDIRQ(90)    /* FS-USB - host controller SMI Interrupt */
+#define OMAP44XX_IRQ_MCSPI3         OMAP44XX_HARDIRQ(91)    /* McSPI module 3 */
+#define OMAP44XX_IRQ_HSUSB_OTG      OMAP44XX_HARDIRQ(92)    /* High-Speed USB OTG controller */
+#define OMAP44XX_IRQ_HSUSB_OTG_DMA  OMAP44XX_HARDIRQ(93)    /* High-Speed USB OTG DMA controller */
+#define OMAP44XX_IRQ_MMC3           OMAP44XX_HARDIRQ(94)    /* MMC/SD module 3 */
+#define OMAP44XX_IRQ_RESERVED95     OMAP44XX_HARDIRQ(95)    /* RESERVED */
+#define OMAP44XX_IRQ_MMC4           OMAP44XX_HARDIRQ(96)    /* MMC4 interrupt */
+#define OMAP44XX_IRQ_SLIMBUS1       OMAP44XX_HARDIRQ(97)    /* SLIMBUS1 interrupt */
+#define OMAP44XX_IRQ_SLIMBUS2       OMAP44XX_HARDIRQ(98)    /* SLIMBUS2 interrupt */
+#define OMAP44XX_IRQ_ABE            OMAP44XX_HARDIRQ(99)    /* Audio back-end interrupt */
+#define OMAP44XX_IRQ_CORTEXM3_MMU   OMAP44XX_HARDIRQ(100)   /* Cortex-M3 MMU interrupt */
+#define OMAP44XX_IRQ_DSS_HDMI       OMAP44XX_HARDIRQ(101)   /* Display subsystem HDMI interrupt */
+#define OMAP44XX_IRQ_SR_IVA         OMAP44XX_HARDIRQ(102)   /* SmartReflex IVA interrupt */
+#define OMAP44XX_IRQ_IVAHD1         OMAP44XX_HARDIRQ(103)   /* Sync interrupt from iCONT2 (vDMA) */
+#define OMAP44XX_IRQ_IVAHD2         OMAP44XX_HARDIRQ(104)   /* Sync interrupt from iCONT1 */
+#define OMAP44XX_IRQ_RESERVED105    OMAP44XX_HARDIRQ(105)   /* RESERVED */
+#define OMAP44XX_IRQ_RESERVED106    OMAP44XX_HARDIRQ(106)   /* RESERVED */
+#define OMAP44XX_IRQ_IVAHD_MAILBOX0 OMAP44XX_HARDIRQ(107)   /* IVAHD mailbox interrupt */
+#define OMAP44XX_IRQ_RESERVED108    OMAP44XX_HARDIRQ(108)   /* RESERVED */
+#define OMAP44XX_IRQ_MCASP1         OMAP44XX_HARDIRQ(109)   /* McASP1 transmit interrupt */
+#define OMAP44XX_IRQ_EMIF1          OMAP44XX_HARDIRQ(110)   /* EMIF1 interrupt */
+#define OMAP44XX_IRQ_EMIF2          OMAP44XX_HARDIRQ(111)   /* EMIF2 interrupt */
+#define OMAP44XX_IRQ_MCPDM          OMAP44XX_HARDIRQ(112)   /* MCPDM interrupt */
+#define OMAP44XX_IRQ_DMM            OMAP44XX_HARDIRQ(113)   /* DMM interrupt */
+#define OMAP44XX_IRQ_DMIC           OMAP44XX_HARDIRQ(114)   /* DMIC interrupt */
+#define OMAP44XX_IRQ_RESERVED115    OMAP44XX_HARDIRQ(115)   /* RESERVED */
+#define OMAP44XX_IRQ_RESERVED116    OMAP44XX_HARDIRQ(116)   /* RESERVED */
+#define OMAP44XX_IRQ_RESERVED117    OMAP44XX_HARDIRQ(117)   /* RESERVED */
+#define OMAP44XX_IRQ_RESERVED118    OMAP44XX_HARDIRQ(118)   /* RESERVED */
+#define OMAP44XX_IRQ_SYS_NIRQ2      OMAP44XX_HARDIRQ(119)   /* External source 2 (active low) */
+#define OMAP44XX_IRQ_KBD            OMAP44XX_HARDIRQ(120)   /* Keyboard controller interrupt */
+#define OMAP44XX_IRQ_RESERVED121    OMAP44XX_HARDIRQ(121)   /* RESERVED */
+#define OMAP44XX_IRQ_RESERVED122    OMAP44XX_HARDIRQ(122)   /* RESERVED */
+#define OMAP44XX_IRQ_RESERVED123    OMAP44XX_HARDIRQ(123)   /* RESERVED */
+#define OMAP44XX_IRQ_RESERVED124    OMAP44XX_HARDIRQ(124)   /* RESERVED */
+#define OMAP44XX_IRQ_RESERVED125    OMAP44XX_HARDIRQ(125)   /* RESERVED */
+#define OMAP44XX_IRQ_RESERVED126    OMAP44XX_HARDIRQ(126)   /* RESERVED */
+#define OMAP44XX_IRQ_RESERVED127    OMAP44XX_HARDIRQ(127)   /* RESERVED */
+
+
+
+/*
+ * General Purpose Timers
+ */
+#define OMAP44XX_GPTIMER1_VBASE		(OMAP44XX_L4_WAKEUP_VBASE + OMAP44XX_GPTIMER1_OFFSET)
+#define OMAP44XX_GPTIMER1_HWBASE	(OMAP44XX_L4_WAKEUP_HWBASE + OMAP44XX_GPTIMER1_OFFSET)
+#define OMAP44XX_GPTIMER2_VBASE		(OMAP44XX_L4_PERIPH_VBASE + OMAP44XX_GPTIMER2_OFFSET)
+#define OMAP44XX_GPTIMER2_HWBASE	(OMAP44XX_L4_PERIPH_HWBASE + OMAP44XX_GPTIMER2_OFFSET)
+#define OMAP44XX_GPTIMER3_VBASE		(OMAP44XX_L4_PERIPH_VBASE + OMAP44XX_GPTIMER3_OFFSET)
+#define OMAP44XX_GPTIMER3_HWBASE	(OMAP44XX_L4_PERIPH_HWBASE + OMAP44XX_GPTIMER3_OFFSET)
+#define OMAP44XX_GPTIMER4_VBASE		(OMAP44XX_L4_PERIPH_VBASE + OMAP44XX_GPTIMER4_OFFSET)
+#define OMAP44XX_GPTIMER4_HWBASE	(OMAP44XX_L4_PERIPH_HWBASE + OMAP44XX_GPTIMER4_OFFSET)
+#define OMAP44XX_GPTIMER5_VBASE		(OMAP44XX_L4_ABE_VBASE + OMAP44XX_GPTIMER5_OFFSET)
+#define OMAP44XX_GPTIMER5_HWBASE	(OMAP44XX_L4_ABE_HWBASE + OMAP44XX_GPTIMER5_OFFSET)
+#define OMAP44XX_GPTIMER6_VBASE		(OMAP44XX_L4_ABE_VBASE + OMAP44XX_GPTIMER6_OFFSET)
+#define OMAP44XX_GPTIMER6_HWBASE	(OMAP44XX_L4_ABE_HWBASE + OMAP44XX_GPTIMER6_OFFSET)
+#define OMAP44XX_GPTIMER7_VBASE		(OMAP44XX_L4_ABE_VBASE + OMAP44XX_GPTIMER7_OFFSET)
+#define OMAP44XX_GPTIMER7_HWBASE	(OMAP44XX_L4_ABE_HWBASE + OMAP44XX_GPTIMER7_OFFSET)
+#define OMAP44XX_GPTIMER8_VBASE		(OMAP44XX_L4_ABE_VBASE + OMAP44XX_GPTIMER8_OFFSET)
+#define OMAP44XX_GPTIMER8_HWBASE	(OMAP44XX_L4_ABE_HWBASE + OMAP44XX_GPTIMER8_OFFSET)
+#define OMAP44XX_GPTIMER9_VBASE		(OMAP44XX_L4_PERIPH_VBASE + OMAP44XX_GPTIMER9_OFFSET)
+#define OMAP44XX_GPTIMER9_HWBASE    (OMAP44XX_L4_PERIPH_HWBASE + OMAP44XX_GPTIMER9_OFFSET)
+#define OMAP44XX_GPTIMER10_VBASE	(OMAP44XX_L4_PERIPH_VBASE + OMAP44XX_GPTIMER10_OFFSET)
+#define OMAP44XX_GPTIMER10_HWBASE	(OMAP44XX_L4_PERIPH_HWBASE + OMAP44XX_GPTIMER10_OFFSET)
+#define OMAP44XX_GPTIMER11_VBASE	(OMAP44XX_L4_PERIPH_VBASE + OMAP44XX_GPTIMER11_OFFSET)
+#define OMAP44XX_GPTIMER11_HWBASE	(OMAP44XX_L4_PERIPH_HWBASE + OMAP44XX_GPTIMER11_OFFSET)
+#define OMAP44XX_GPTIMER_SIZE		0x00001000UL
+
+
+
+/*
+ * GPIO - General Purpose IO
+ */
+
+/* Base addresses for the GPIO modules */
+#define OMAP44XX_GPIO1_HWBASE		(OMAP44XX_L4_WAKEUP_HWBASE + OMAP44XX_GPIO1_OFFSET)
+#define OMAP44XX_GPIO1_VBASE		(OMAP44XX_L4_WAKEUP_VBASE  + OMAP44XX_GPIO1_OFFSET)
+#define OMAP44XX_GPIO1_SIZE			0x00001000UL
+#define OMAP44XX_GPIO2_HWBASE		(OMAP44XX_L4_PERIPH_HWBASE + OMAP44XX_GPIO2_OFFSET)
+#define OMAP44XX_GPIO2_VBASE		(OMAP44XX_L4_PERIPH_VBASE  + OMAP44XX_GPIO2_OFFSET)
+#define OMAP44XX_GPIO2_SIZE			0x00001000UL
+#define OMAP44XX_GPIO3_HWBASE		(OMAP44XX_L4_PERIPH_HWBASE + OMAP44XX_GPIO3_OFFSET)
+#define OMAP44XX_GPIO3_VBASE		(OMAP44XX_L4_PERIPH_VBASE  + OMAP44XX_GPIO3_OFFSET)
+#define OMAP44XX_GPIO3_SIZE			0x00001000UL
+#define OMAP44XX_GPIO4_HWBASE		(OMAP44XX_L4_PERIPH_HWBASE + OMAP44XX_GPIO4_OFFSET)
+#define OMAP44XX_GPIO4_VBASE		(OMAP44XX_L4_PERIPH_VBASE  + OMAP44XX_GPIO4_OFFSET)
+#define OMAP44XX_GPIO4_SIZE			0x00001000UL
+#define OMAP44XX_GPIO5_HWBASE		(OMAP44XX_L4_PERIPH_HWBASE + OMAP44XX_GPIO5_OFFSET)
+#define OMAP44XX_GPIO5_VBASE		(OMAP44XX_L4_PERIPH_VBASE  + OMAP44XX_GPIO5_OFFSET)
+#define OMAP44XX_GPIO5_SIZE			0x00001000UL
+#define OMAP44XX_GPIO6_HWBASE		(OMAP44XX_L4_PERIPH_HWBASE + OMAP44XX_GPIO6_OFFSET)
+#define OMAP44XX_GPIO6_VBASE		(OMAP44XX_L4_PERIPH_VBASE  + OMAP44XX_GPIO6_OFFSET)
+#define OMAP44XX_GPIO6_SIZE			0x00001000UL
+
+
+/*
+ * MMC/SD/SDIO
+ */
+
+/* Base addresses for the MMC/SD/SDIO modules */
+#define OMAP44XX_MMCHS1_HWBASE   (OMAP44XX_L4_PERIPH_HWBASE + OMAP44XX_MMCHS1_OFFSET)
+#define OMAP44XX_MMCHS1_VBASE    (OMAP44XX_L4_PERIPH_VBASE + OMAP44XX_MMCHS1_OFFSET)
+#define OMAP44XX_MMCHS2_HWBASE   (OMAP44XX_L4_PERIPH_HWBASE + OMAP44XX_MMCHS2_OFFSET)
+#define OMAP44XX_MMCHS2_VBASE    (OMAP44XX_L4_PERIPH_VBASE + OMAP44XX_MMCHS2_OFFSET)
+#define OMAP44XX_MMCHS3_HWBASE   (OMAP44XX_L4_PERIPH_HWBASE + OMAP44XX_MMCSD3_OFFSET)
+#define OMAP44XX_MMCHS3_VBASE    (OMAP44XX_L4_PERIPH_VBASE + OMAP44XX_MMCSD3_OFFSET)
+#define OMAP44XX_MMCHS4_HWBASE   (OMAP44XX_L4_PERIPH_HWBASE + OMAP44XX_MMCSD4_OFFSET)
+#define OMAP44XX_MMCHS4_VBASE    (OMAP44XX_L4_PERIPH_VBASE + OMAP44XX_MMCSD4_OFFSET)
+#define OMAP44XX_MMCHS5_HWBASE   (OMAP44XX_L4_PERIPH_HWBASE + OMAP44XX_MMCSD5_OFFSET)
+#define OMAP44XX_MMCHS5_VBASE    (OMAP44XX_L4_PERIPH_VBASE + OMAP44XX_MMCSD5_OFFSET)
+#define OMAP44XX_MMCHS_SIZE      0x00001000UL
+
+
+
+/*
+ * SCM - System Control Module
+ */
+
+/* Base addresses for the SC modules */
+#define OMAP44XX_SCM_PADCONF_HWBASE (OMAP44XX_L4_CORE_HWBASE + OMAP44XX_SCM_PADCONF_OFFSET)
+#define OMAP44XX_SCM_PADCONF_VBASE  (OMAP44XX_L4_CORE_VBASE + OMAP44XX_SCM_PADCONF_OFFSET)
+#define OMAP44XX_SCM_PADCONF_SIZE   0x00001000UL
+
+
+
+
+#endif /* _OMAP44XX_REG_H_ */


Property changes on: trunk/sys/arm/ti/omap4/omap4_reg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/omap4/omap4_scm_padconf.c
===================================================================
--- trunk/sys/arm/ti/omap4/omap4_scm_padconf.c	                        (rev 0)
+++ trunk/sys/arm/ti/omap4/omap4_scm_padconf.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,405 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2011
+ *	Ben Gray <ben.r.gray at gmail.com>.
+ * 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.
+ * 3. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BEN GRAY ``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 BEN GRAY 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: stable/10/sys/arm/ti/omap4/omap4_scm_padconf.c 279467 2015-03-01 01:08:14Z dim $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+#include <machine/resource.h>
+#include <machine/intr.h>
+#include <sys/gpio.h>
+
+#include <arm/ti/tivar.h>
+#include <arm/ti/ti_scm.h>
+#include <arm/ti/omap4/omap4var.h>
+#include <arm/ti/omap4/omap4_reg.h>
+
+
+/*
+ *	This file defines the pin mux configuration for the OMAP4xxx series of
+ *	devices.
+ *
+ *	How This is Suppose to Work
+ *	===========================
+ *	- There is a top level ti_scm module (System Control Module) that is
+ *	the interface for all omap drivers, which can use it to change the mux
+ *	settings for individual pins.  (That said, typically the pin mux settings
+ *	are set to defaults by the 'hints' and then not altered by the driver).
+ *
+ *	- For this to work the top level driver needs all the pin info, and hence
+ *	this is where this file comes in.  Here we define all the pin information
+ *	that is supplied to the top level driver.
+ *
+ */
+
+#define CONTROL_PADCONF_WAKEUP_EVENT     (1UL << 15)
+#define CONTROL_PADCONF_WAKEUP_ENABLE    (1UL << 14)
+#define CONTROL_PADCONF_OFF_PULL_UP      (1UL << 13)
+#define CONTROL_PADCONF_OFF_PULL_ENABLE  (1UL << 12)
+#define CONTROL_PADCONF_OFF_OUT_HIGH     (1UL << 11)
+#define CONTROL_PADCONF_OFF_OUT_ENABLE   (1UL << 10)
+#define CONTROL_PADCONF_OFF_ENABLE       (1UL << 9)
+#define CONTROL_PADCONF_INPUT_ENABLE     (1UL << 8)
+#define CONTROL_PADCONF_PULL_UP          (1UL << 4)
+#define CONTROL_PADCONF_PULL_ENABLE      (1UL << 3)
+#define CONTROL_PADCONF_MUXMODE_MASK     (0x7)
+
+#define CONTROL_PADCONF_SATE_MASK        ( CONTROL_PADCONF_WAKEUP_EVENT \
+                                         | CONTROL_PADCONF_WAKEUP_ENABLE \
+                                         | CONTROL_PADCONF_OFF_PULL_UP \
+                                         | CONTROL_PADCONF_OFF_PULL_ENABLE \
+                                         | CONTROL_PADCONF_OFF_OUT_HIGH \
+                                         | CONTROL_PADCONF_OFF_OUT_ENABLE \
+                                         | CONTROL_PADCONF_OFF_ENABLE \
+                                         | CONTROL_PADCONF_INPUT_ENABLE \
+                                         | CONTROL_PADCONF_PULL_UP \
+                                         | CONTROL_PADCONF_PULL_ENABLE )
+
+/* Active pin states */
+#define PADCONF_PIN_OUTPUT              0
+#define PADCONF_PIN_INPUT               CONTROL_PADCONF_INPUT_ENABLE
+#define PADCONF_PIN_INPUT_PULLUP        ( CONTROL_PADCONF_INPUT_ENABLE \
+                                        | CONTROL_PADCONF_PULL_ENABLE \
+                                        | CONTROL_PADCONF_PULL_UP)
+#define PADCONF_PIN_INPUT_PULLDOWN      ( CONTROL_PADCONF_INPUT_ENABLE \
+                                        | CONTROL_PADCONF_PULL_ENABLE )
+
+/* Off mode states */
+#define PADCONF_PIN_OFF_NONE            0
+#define PADCONF_PIN_OFF_OUTPUT_HIGH	    ( CONTROL_PADCONF_OFF_ENABLE \
+                                        | CONTROL_PADCONF_OFF_OUT_ENABLE \
+                                        | CONTROL_PADCONF_OFF_OUT_HIGH)
+#define PADCONF_PIN_OFF_OUTPUT_LOW      ( CONTROL_PADCONF_OFF_ENABLE \
+                                        | CONTROL_PADCONF_OFF_OUT_ENABLE)
+#define PADCONF_PIN_OFF_INPUT_PULLUP    ( CONTROL_PADCONF_OFF_ENABLE \
+                                        | CONTROL_PADCONF_OFF_PULL_ENABLE \
+                                        | CONTROL_PADCONF_OFF_PULL_UP)
+#define PADCONF_PIN_OFF_INPUT_PULLDOWN  ( CONTROL_PADCONF_OFF_ENABLE \
+                                        | CONTROL_PADCONF_OFF_PULL_ENABLE)
+#define PADCONF_PIN_OFF_WAKEUPENABLE	CONTROL_PADCONF_WAKEUP_ENABLE
+
+
+#define _PINDEF(r, b, gp, gm, m0, m1, m2, m3, m4, m5, m6, m7) \
+	{	.reg_off = r, \
+		.gpio_pin = gp, \
+		.gpio_mode = gm, \
+		.ballname = b, \
+		.muxmodes[0] = m0, \
+		.muxmodes[1] = m1, \
+		.muxmodes[2] = m2, \
+		.muxmodes[3] = m3, \
+		.muxmodes[4] = m4, \
+		.muxmodes[5] = m5, \
+		.muxmodes[6] = m6, \
+		.muxmodes[7] = m7, \
+	}
+
+const struct ti_scm_padstate ti_padstate_devmap[] = {
+	{"output",		PADCONF_PIN_OUTPUT},
+	{"input",		PADCONF_PIN_INPUT},
+	{"input_pullup",	PADCONF_PIN_INPUT_PULLUP},
+	{"input_pulldown",	PADCONF_PIN_INPUT_PULLDOWN},
+	{ .state = NULL }
+};
+
+/*
+ * Table 18-10, p. 3470
+ */
+const struct ti_scm_padconf ti_padconf_devmap[] = {
+	_PINDEF(0x0040,  "c12",   0, 0, "gpmc_ad0", "sdmmc2_dat0", NULL, NULL, NULL, NULL, NULL, NULL),
+	_PINDEF(0x0042,  "d12",   0, 0, "gpmc_ad1", "sdmmc2_dat1", NULL, NULL, NULL, NULL, NULL, NULL),
+	_PINDEF(0x0044,  "c13",   0, 0, "gpmc_ad2", "sdmmc2_dat2", NULL, NULL, NULL, NULL, NULL, NULL),
+	_PINDEF(0x0046,  "d13",   0, 0, "gpmc_ad3", "sdmmc2_dat3", NULL, NULL, NULL, NULL, NULL, NULL),
+	_PINDEF(0x0048,  "c15",   0, 0, "gpmc_ad4", "sdmmc2_dat4", "sdmmc2_dir_dat0", NULL, NULL, NULL, NULL, NULL),
+	_PINDEF(0x004a,  "d15",   0, 0, "gpmc_ad5", "sdmmc2_dat5", "sdmmc2_dir_dat1", NULL, NULL, NULL, NULL, NULL),
+	_PINDEF(0x004c,  "a16",   0, 0, "gpmc_ad6", "sdmmc2_dat6", "sdmmc2_dir_cmd", NULL, NULL, NULL, NULL, NULL),
+	_PINDEF(0x004e,  "b16",   0, 0, "gpmc_ad7", "sdmmc2_dat7", "sdmmc2_clk_fdbk", NULL, NULL, NULL, NULL, NULL),
+	_PINDEF(0x0050,  "c16",  32, 3, "gpmc_ad8", "kpd_row0", "c2c_data15", "gpio_32", NULL, "sdmmc1_dat0", NULL, NULL),
+	_PINDEF(0x0052,  "d16",  33, 3, "gpmc_ad9", "kpd_row1", "c2c_data14", "gpio_33", NULL, "sdmmc1_dat1", NULL, NULL),
+	_PINDEF(0x0054,  "c17",  34, 3, "gpmc_ad10", "kpd_row2", "c2c_data13", "gpio_34", NULL, "sdmmc1_dat2", NULL, NULL),
+	_PINDEF(0x0056,  "d17",  35, 3, "gpmc_ad11", "kpd_row3", "c2c_data12", "gpio_35", NULL, "sdmmc1_dat3", NULL, NULL),
+	_PINDEF(0x0058,  "c18",  36, 3, "gpmc_ad12", "kpd_col0", "c2c_data11", "gpio_36", NULL, "sdmmc1_dat4", NULL, NULL),
+	_PINDEF(0x005a,  "d18",  37, 3, "gpmc_ad13", "kpd_col1", "c2c_data10", "gpio_37", NULL, "sdmmc1_dat5", NULL, NULL),
+	_PINDEF(0x005c,  "c19",  38, 3, "gpmc_ad14", "kpd_col2", "c2c_data9", "gpio_38", NULL, "sdmmc1_dat6", NULL, NULL),
+	_PINDEF(0x005e,  "d19",  39, 3, "gpmc_ad15", "kpd_col3", "c2c_data8", "gpio_39", NULL, "sdmmc1_dat7", NULL, NULL),
+	_PINDEF(0x0060,  "b17",  40, 3, "gpmc_a16", "kpd_row4", "c2c_datain0", "gpio_40", "venc_656_data0", NULL, NULL, "safe_mode"),
+	_PINDEF(0x0062,  "a18",  41, 3, "gpmc_a17", "kpd_row5", "c2c_datain1", "gpio_41", "venc_656_data1", NULL, NULL, "safe_mode"),
+	_PINDEF(0x0064,  "b18",  42, 3, "gpmc_a18", "kpd_row6", "c2c_datain2", "gpio_42", "venc_656_data2", NULL, NULL, "safe_mode"),
+	_PINDEF(0x0066,  "a19",  43, 3, "gpmc_a19", "kpd_row7", "c2c_datain3", "gpio_43", "venc_656_data3", NULL, NULL, "safe_mode"),
+	_PINDEF(0x0068,  "b19",  44, 3, "gpmc_a20", "kpd_col4", "c2c_datain4", "gpio_44", "venc_656_data4", NULL, NULL, "safe_mode"),
+	_PINDEF(0x006a,  "b20",  45, 3, "gpmc_a21", "kpd_col5", "c2c_datain5", "gpio_45", "venc_656_data5", NULL, NULL, "safe_mode"),
+	_PINDEF(0x006c,  "a21",  46, 3, "gpmc_a22", "kpd_col6", "c2c_datain6", "gpio_46", "venc_656_data6", NULL, NULL, "safe_mode"),
+	_PINDEF(0x006e,  "b21",  47, 3, "gpmc_a23", "kpd_col7", "c2c_datain7", "gpio_47", "venc_656_data7", NULL, NULL, "safe_mode"),
+	_PINDEF(0x0070,  "c20",  48, 3, "gpmc_a24", "kpd_col8", "c2c_clkout0", "gpio_48", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x0072,  "d20",  49, 3, "gpmc_a25", NULL, "c2c_clkout1", "gpio_49", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x0074,  "b25",  50, 3, "gpmc_ncs0", NULL, NULL, "gpio_50", "sys_ndmareq0", NULL, NULL, NULL),
+	_PINDEF(0x0076,  "c21",  51, 3, "gpmc_ncs1", NULL, "c2c_dataout6", "gpio_51", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x0078,  "d21",  52, 3, "gpmc_ncs2", "kpd_row8", "c2c_dataout7", "gpio_52", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x007a,  "c22",  53, 3, "gpmc_ncs3", "gpmc_dir", "c2c_dataout4", "gpio_53", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x007c,  "c25",  54, 3, "gpmc_nwp", "dsi1_te0", NULL, "gpio_54", "sys_ndmareq1", NULL, NULL, NULL),
+	_PINDEF(0x007e,  "b22",  55, 3, "gpmc_clk", NULL, NULL, "gpio_55", "sys_ndmareq2", "sdmmc1_cmd", NULL, NULL),
+	_PINDEF(0x0080,  "d25",  56, 3, "gpmc_nadv_ale", "dsi1_te1", NULL, "gpio_56", "sys_ndmareq3", "sdmmc1_clk", NULL, NULL),
+	_PINDEF(0x0082,  "b11",   0, 0, "gpmc_noe", "sdmmc2_clk", NULL, NULL, NULL, NULL, NULL, NULL),
+	_PINDEF(0x0084,  "b12",   0, 0, "gpmc_nwe", "sdmmc2_cmd", NULL, NULL, NULL, NULL, NULL, NULL),
+	_PINDEF(0x0086,  "c23",  59, 3, "gpmc_nbe0_cle", "dsi2_te0", NULL, "gpio_59", NULL, NULL, NULL, NULL),
+	_PINDEF(0x0088,  "d22",  60, 3, "gpmc_nbe1", NULL, "c2c_dataout5", "gpio_60", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x008a,  "b26",  61, 3, "gpmc_wait0", "dsi2_te1", NULL, "gpio_61", NULL, NULL, NULL, NULL),
+	_PINDEF(0x008c,  "b23",  62, 3, "gpmc_wait1", NULL, "c2c_dataout2", "gpio_62", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x008e,  "d23", 100, 3, "gpmc_wait2", "usbc1_icusb_txen", "c2c_dataout3", "gpio_100", "sys_ndmareq0", NULL, NULL, "safe_mode"),
+	_PINDEF(0x0090,  "a24", 101, 3, "gpmc_ncs4", "dsi1_te0", "c2c_clkin0", "gpio_101", "sys_ndmareq1", NULL, NULL, "safe_mode"),
+	_PINDEF(0x0092,  "b24", 102, 3, "gpmc_ncs5", "dsi1_te1", "c2c_clkin1", "gpio_102", "sys_ndmareq2", NULL, NULL, "safe_mode"),
+	_PINDEF(0x0094,  "c24", 103, 3, "gpmc_ncs6", "dsi2_te0", "c2c_dataout0", "gpio_103", "sys_ndmareq3", NULL, NULL, "safe_mode"),
+	_PINDEF(0x0096,  "d24", 104, 3, "gpmc_ncs7", "dsi2_te1", "c2c_dataout1", "gpio_104", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x0098,   "b9",  63, 3, "hdmi_hpd", NULL, NULL, "gpio_63", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x009a,  "b10",  64, 3, "hdmi_cec", NULL, NULL, "gpio_64", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x009c,   "a8",  65, 3, "hdmi_ddc_scl", NULL, NULL, "gpio_65", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x009e,   "b8",  66, 3, "hdmi_ddc_sda", NULL, NULL, "gpio_66", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x00a0,  "r26",   0, 0, "csi21_dx0", NULL, NULL, "gpi_67", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x00a2,  "r25",   0, 0, "csi21_dy0", NULL, NULL, "gpi_68", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x00a4,  "t26",   0, 0, "csi21_dx1", NULL, NULL, "gpi_69", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x00a6,  "t25",   0, 0, "csi21_dy1", NULL, NULL, "gpi_70", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x00a8,  "u26",   0, 0, "csi21_dx2", NULL, NULL, "gpi_71", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x00aa,  "u25",   0, 0, "csi21_dy2", NULL, NULL, "gpi_72", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x00ac,  "v26",   0, 0, "csi21_dx3", NULL, NULL, "gpi_73", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x00ae,  "v25",   0, 0, "csi21_dy3", NULL, NULL, "gpi_74", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x00b0,  "w26",   0, 0, "csi21_dx4", NULL, NULL, "gpi_75", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x00b2,  "w25",   0, 0, "csi21_dy4", NULL, NULL, "gpi_76", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x00b4,  "m26",   0, 0, "csi22_dx0", NULL, NULL, "gpi_77", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x00b6,  "m25",   0, 0, "csi22_dy0", NULL, NULL, "gpi_78", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x00b8,  "n26",   0, 0, "csi22_dx1", NULL, NULL, "gpi_79", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x00ba,  "n25",   0, 0, "csi22_dy1", NULL, NULL, "gpi_80", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x00bc,  "t27",  81, 3, "cam_shutter", NULL, NULL, "gpio_81", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x00be,  "u27",  82, 3, "cam_strobe", NULL, NULL, "gpio_82", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x00c0,  "v27",  83, 3, "cam_globalreset", NULL, NULL, "gpio_83", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x00c2, "ae18",  84, 3, "usbb1_ulpitll_clk", "hsi1_cawake", NULL, "gpio_84", "usbb1_ulpiphy_clk", NULL, "hw_dbg20", "safe_mode"),
+	_PINDEF(0x00c4, "ag19",  85, 3, "usbb1_ulpitll_stp", "hsi1_cadata", "mcbsp4_clkr", "gpio_85", "usbb1_ulpiphy_stp", "usbb1_mm_rxdp", "hw_dbg21", "safe_mode"),
+	_PINDEF(0x00c6, "af19",  86, 3, "usbb1_ulpitll_dir", "hsi1_caflag", "mcbsp4_fsr", "gpio_86", "usbb1_ulpiphy_dir", NULL, "hw_dbg22", "safe_mode"),
+	_PINDEF(0x00c8, "ae19",  87, 3, "usbb1_ulpitll_nxt", "hsi1_acready", "mcbsp4_fsx", "gpio_87", "usbb1_ulpiphy_nxt", "usbb1_mm_rxdm", "hw_dbg23", "safe_mode"),
+	_PINDEF(0x00ca, "af18",  88, 3, "usbb1_ulpitll_dat0", "hsi1_acwake", "mcbsp4_clkx", "gpio_88", "usbb1_ulpiphy_dat0", "usbb1_mm_txen", "hw_dbg24", "safe_mode"),
+	_PINDEF(0x00cc, "ag18",  89, 3, "usbb1_ulpitll_dat1", "hsi1_acdata", "mcbsp4_dx", "gpio_89", "usbb1_ulpiphy_dat1", "usbb1_mm_txdat", "hw_dbg25", "safe_mode"),
+	_PINDEF(0x00ce, "ae17",  90, 3, "usbb1_ulpitll_dat2", "hsi1_acflag", "mcbsp4_dr", "gpio_90", "usbb1_ulpiphy_dat2", "usbb1_mm_txse0", "hw_dbg26", "safe_mode"),
+	_PINDEF(0x00d0, "af17",  91, 3, "usbb1_ulpitll_dat3", "hsi1_caready", NULL, "gpio_91", "usbb1_ulpiphy_dat3", "usbb1_mm_rxrcv", "hw_dbg27", "safe_mode"),
+	_PINDEF(0x00d2, "ah17",  92, 3, "usbb1_ulpitll_dat4", "dmtimer8_pwm_evt", "abe_mcbsp3_dr", "gpio_92", "usbb1_ulpiphy_dat4", NULL, "hw_dbg28", "safe_mode"),
+	_PINDEF(0x00d4, "ae16",  93, 3, "usbb1_ulpitll_dat5", "dmtimer9_pwm_evt", "abe_mcbsp3_dx", "gpio_93", "usbb1_ulpiphy_dat5", NULL, "hw_dbg29", "safe_mode"),
+	_PINDEF(0x00d6, "af16",  94, 3, "usbb1_ulpitll_dat6", "dmtimer10_pwm_evt", "abe_mcbsp3_clkx", "gpio_94", "usbb1_ulpiphy_dat6", "abe_dmic_din3", "hw_dbg30", "safe_mode"),
+	_PINDEF(0x00d8, "ag16",  95, 3, "usbb1_ulpitll_dat7", "dmtimer11_pwm_evt", "abe_mcbsp3_fsx", "gpio_95", "usbb1_ulpiphy_dat7", "abe_dmic_clk3", "hw_dbg31", "safe_mode"),
+	_PINDEF(0x00da, "af14",  96, 3, "usbb1_hsic_data", NULL, NULL, "gpio_96", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x00dc, "ae14",  97, 3, "usbb1_hsic_strobe", NULL, NULL, "gpio_97", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x00de,   "h2",  98, 3, "usbc1_icusb_dp", NULL, NULL, "gpio_98", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x00e0,   "h3",  99, 3, "usbc1_icusb_dm", NULL, NULL, "gpio_99", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x00e2,   "d2", 100, 3, "sdmmc1_clk", NULL, "dpm_emu19", "gpio_100", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x00e4,   "e3", 101, 3, "sdmmc1_cmd", NULL, "uart1_rx", "gpio_101", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x00e6,   "e4", 102, 3, "sdmmc1_dat0", NULL, "dpm_emu18", "gpio_102", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x00e8,   "e2", 103, 3, "sdmmc1_dat1", NULL, "dpm_emu17", "gpio_103", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x00ea,   "e1", 104, 3, "sdmmc1_dat2", NULL, "dpm_emu16", "gpio_104", "jtag_tms_tmsc", NULL, NULL, "safe_mode"),
+	_PINDEF(0x00ec,   "f4", 105, 3, "sdmmc1_dat3", NULL, "dpm_emu15", "gpio_105", "jtag_tck", NULL, NULL, "safe_mode"),
+	_PINDEF(0x00ee,   "f3", 106, 3, "sdmmc1_dat4", NULL, NULL, "gpio_106", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x00f0,   "f1", 107, 3, "sdmmc1_dat5", NULL, NULL, "gpio_107", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x00f2,   "g4", 108, 3, "sdmmc1_dat6", NULL, NULL, "gpio_108", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x00f4,   "g3", 109, 3, "sdmmc1_dat7", NULL, NULL, "gpio_109", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x00f6, "ad27", 110, 3, "abe_mcbsp2_clkx", "mcspi2_clk", "abe_mcasp_ahclkx", "gpio_110", "usbb2_mm_rxdm", NULL, NULL, "safe_mode"),
+	_PINDEF(0x00f8, "ad26", 111, 3, "abe_mcbsp2_dr", "mcspi2_somi", "abe_mcasp_axr", "gpio_111", "usbb2_mm_rxdp", NULL, NULL, "safe_mode"),
+	_PINDEF(0x00fa, "ad25", 112, 3, "abe_mcbsp2_dx", "mcspi2_simo", "abe_mcasp_amute", "gpio_112", "usbb2_mm_rxrcv", NULL, NULL, "safe_mode"),
+	_PINDEF(0x00fc, "ac28", 113, 3, "abe_mcbsp2_fsx", "mcspi2_cs0", "abe_mcasp_afsx", "gpio_113", "usbb2_mm_txen", NULL, NULL, "safe_mode"),
+	_PINDEF(0x00fe, "ac26", 114, 3, "abe_mcbsp1_clkx", "abe_slimbus1_clock", NULL, "gpio_114", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x0100, "ac25", 115, 3, "abe_mcbsp1_dr", "abe_slimbus1_data", NULL, "gpio_115", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x0102, "ab25", 116, 3, "abe_mcbsp1_dx", "sdmmc3_dat2", "abe_mcasp_aclkx", "gpio_116", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x0104, "ac27", 117, 3, "abe_mcbsp1_fsx", "sdmmc3_dat3", "abe_mcasp_amutein", "gpio_117", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x0106, "ag25",   0, 0, "abe_pdm_ul_data", "abe_mcbsp3_dr", NULL, NULL, NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x0108, "af25",   0, 0, "abe_pdm_dl_data", "abe_mcbsp3_dx", NULL, NULL, NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x010a, "ae25",   0, 0, "abe_pdm_frame", "abe_mcbsp3_clkx", NULL, NULL, NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x010c, "af26",   0, 0, "abe_pdm_lb_clk", "abe_mcbsp3_fsx", NULL, NULL, NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x010e, "ah26", 118, 3, "abe_clks", NULL, NULL, "gpio_118", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x0110, "ae24", 119, 3, "abe_dmic_clk1", NULL, NULL, "gpio_119", "usbb2_mm_txse0", "uart4_cts", NULL, "safe_mode"),
+	_PINDEF(0x0112, "af24", 120, 3, "abe_dmic_din1", NULL, NULL, "gpio_120", "usbb2_mm_txdat", "uart4_rts", NULL, "safe_mode"),
+	_PINDEF(0x0114, "ag24", 121, 3, "abe_dmic_din2", "slimbus2_clock", "abe_mcasp_axr", "gpio_121", NULL, "dmtimer11_pwm_evt", NULL, "safe_mode"),
+	_PINDEF(0x0116, "ah24", 122, 3, "abe_dmic_din3", "slimbus2_data", "abe_dmic_clk2", "gpio_122", NULL, "dmtimer9_pwm_evt", NULL, "safe_mode"),
+	_PINDEF(0x0118, "ab26", 123, 3, "uart2_cts", "sdmmc3_clk", NULL, "gpio_123", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x011a, "ab27", 124, 3, "uart2_rts", "sdmmc3_cmd", NULL, "gpio_124", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x011c, "aa25", 125, 3, "uart2_rx", "sdmmc3_dat0", NULL, "gpio_125", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x011e, "aa26", 126, 3, "uart2_tx", "sdmmc3_dat1", NULL, "gpio_126", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x0120, "aa27", 127, 3, "hdq_sio", "i2c3_sccb", "i2c2_sccb", "gpio_127", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x0122, "ae28",   0, 0, "i2c1_scl", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PINDEF(0x0124, "ae26",   0, 0, "i2c1_sda", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PINDEF(0x0126,  "c26", 128, 3, "i2c2_scl", "uart1_rx", NULL, "gpio_128", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x0128,  "d26", 129, 3, "i2c2_sda", "uart1_tx", NULL, "gpio_129", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x012a,  "w27", 130, 3, "i2c3_scl", NULL, NULL, "gpio_130", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x012c,  "y27", 131, 3, "i2c3_sda", NULL, NULL, "gpio_131", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x012e, "ag21", 132, 3, "i2c4_scl", NULL, NULL, "gpio_132", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x0130, "ah22", 133, 3, "i2c4_sda", NULL, NULL, "gpio_133", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x0132, "af22", 134, 3, "mcspi1_clk", NULL, NULL, "gpio_134", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x0134, "ae22", 135, 3, "mcspi1_somi", NULL, NULL, "gpio_135", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x0136, "ag22", 136, 3, "mcspi1_simo", NULL, NULL, "gpio_136", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x0138, "ae23", 137, 3, "mcspi1_cs0", NULL, NULL, "gpio_137", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x013a, "af23", 138, 3, "mcspi1_cs1", "uart1_rx", NULL, "gpio_138", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x013c, "ag23", 139, 3, "mcspi1_cs2", "uart1_cts", "slimbus2_clock", "gpio_139", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x013e, "ah23", 140, 3, "mcspi1_cs3", "uart1_rts", "slimbus2_data", "gpio_140", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x0140,  "f27", 141, 3, "uart3_cts_rctx", "uart1_tx", NULL, "gpio_141", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x0142,  "f28", 142, 3, "uart3_rts_sd", NULL, NULL, "gpio_142", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x0144,  "g27", 143, 3, "uart3_rx_irrx", "dmtimer8_pwm_evt", NULL, "gpio_143", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x0146,  "g28", 144, 3, "uart3_tx_irtx", "dmtimer9_pwm_evt", NULL, "gpio_144", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x0148,  "ae5", 145, 3, "sdmmc5_clk", "mcspi2_clk", "usbc1_icusb_dp", "gpio_145", NULL, "sdmmc2_clk", NULL, "safe_mode"),
+	_PINDEF(0x014a,  "af5", 146, 3, "sdmmc5_cmd", "mcspi2_simo", "usbc1_icusb_dm", "gpio_146", NULL, "sdmmc2_cmd", NULL, "safe_mode"),
+	_PINDEF(0x014c,  "ae4", 147, 3, "sdmmc5_dat0", "mcspi2_somi", "usbc1_icusb_rcv", "gpio_147", NULL, "sdmmc2_dat0", NULL, "safe_mode"),
+	_PINDEF(0x014e,  "af4", 148, 3, "sdmmc5_dat1", NULL, "usbc1_icusb_txen", "gpio_148", NULL, "sdmmc2_dat1", NULL, "safe_mode"),
+	_PINDEF(0x0150,  "ag3", 149, 3, "sdmmc5_dat2", "mcspi2_cs1", NULL, "gpio_149", NULL, "sdmmc2_dat2", NULL, "safe_mode"),
+	_PINDEF(0x0152,  "af3", 150, 3, "sdmmc5_dat3", "mcspi2_cs0", NULL, "gpio_150", NULL, "sdmmc2_dat3", NULL, "safe_mode"),
+	_PINDEF(0x0154, "ae21", 151, 3, "mcspi4_clk", "sdmmc4_clk", "kpd_col6", "gpio_151", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x0156, "af20", 152, 3, "mcspi4_simo", "sdmmc4_cmd", "kpd_col7", "gpio_152", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x0158, "af21", 153, 3, "mcspi4_somi", "sdmmc4_dat0", "kpd_row6", "gpio_153", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x015a, "ae20", 154, 3, "mcspi4_cs0", "sdmmc4_dat3", "kpd_row7", "gpio_154", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x015c, "ag20", 155, 3, "uart4_rx", "sdmmc4_dat2", "kpd_row8", "gpio_155", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x015e, "ah19", 156, 3, "uart4_tx", "sdmmc4_dat1", "kpd_col8", "gpio_156", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x0160, "ag12", 157, 3, "usbb2_ulpitll_clk", "usbb2_ulpiphy_clk", "sdmmc4_cmd", "gpio_157", "hsi2_cawake", NULL, NULL, "safe_mode"),
+	_PINDEF(0x0162, "af12", 158, 3, "usbb2_ulpitll_stp", "usbb2_ulpiphy_stp", "sdmmc4_clk", "gpio_158", "hsi2_cadata", "dispc2_data23", NULL, "safe_mode"),
+	_PINDEF(0x0164, "ae12", 159, 3, "usbb2_ulpitll_dir", "usbb2_ulpiphy_dir", "sdmmc4_dat0", "gpio_159", "hsi2_caflag", "dispc2_data22", NULL, "safe_mode"),
+	_PINDEF(0x0166, "ag13", 160, 3, "usbb2_ulpitll_nxt", "usbb2_ulpiphy_nxt", "sdmmc4_dat1", "gpio_160", "hsi2_acready", "dispc2_data21", NULL, "safe_mode"),
+	_PINDEF(0x0168, "ae11", 161, 3, "usbb2_ulpitll_dat0", "usbb2_ulpiphy_dat0", "sdmmc4_dat2", "gpio_161", "hsi2_acwake", "dispc2_data20", "usbb2_mm_txen", "safe_mode"),
+	_PINDEF(0x016a, "af11", 162, 3, "usbb2_ulpitll_dat1", "usbb2_ulpiphy_dat1", "sdmmc4_dat3", "gpio_162", "hsi2_acdata", "dispc2_data19", "usbb2_mm_txdat", "safe_mode"),
+	_PINDEF(0x016c, "ag11", 163, 3, "usbb2_ulpitll_dat2", "usbb2_ulpiphy_dat2", "sdmmc3_dat2", "gpio_163", "hsi2_acflag", "dispc2_data18", "usbb2_mm_txse0", "safe_mode"),
+	_PINDEF(0x016e, "ah11", 164, 3, "usbb2_ulpitll_dat3", "usbb2_ulpiphy_dat3", "sdmmc3_dat1", "gpio_164", "hsi2_caready", "dispc2_data15", "rfbi_data15", "safe_mode"),
+	_PINDEF(0x0170, "ae10", 165, 3, "usbb2_ulpitll_dat4", "usbb2_ulpiphy_dat4", "sdmmc3_dat0", "gpio_165", "mcspi3_somi", "dispc2_data14", "rfbi_data14", "safe_mode"),
+	_PINDEF(0x0172, "af10", 166, 3, "usbb2_ulpitll_dat5", "usbb2_ulpiphy_dat5", "sdmmc3_dat3", "gpio_166", "mcspi3_cs0", "dispc2_data13", "rfbi_data13", "safe_mode"),
+	_PINDEF(0x0174, "ag10", 167, 3, "usbb2_ulpitll_dat6", "usbb2_ulpiphy_dat6", "sdmmc3_cmd", "gpio_167", "mcspi3_simo", "dispc2_data12", "rfbi_data12", "safe_mode"),
+	_PINDEF(0x0176,  "ae9", 168, 3, "usbb2_ulpitll_dat7", "usbb2_ulpiphy_dat7", "sdmmc3_clk", "gpio_168", "mcspi3_clk", "dispc2_data11", "rfbi_data11", "safe_mode"),
+	_PINDEF(0x0178, "af13", 169, 3, "usbb2_hsic_data", NULL, NULL, "gpio_169", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x017a, "ae13", 170, 3, "usbb2_hsic_strobe", NULL, NULL, "gpio_170", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x017c,  "g26", 171, 3, "kpd_col3", "kpd_col0", NULL, "gpio_171", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x017e,  "g25", 172, 3, "kpd_col4", "kpd_col1", NULL, "gpio_172", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x0180,  "h26", 173, 3, "kpd_col5", "kpd_col2", NULL, "gpio_173", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x0182,  "h25", 174, 3, "kpd_col0", "kpd_col3", NULL, "gpio_174", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x0184,  "j27",   0, 0, "kpd_col1", "kpd_col4", NULL, "gpio_0", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x0186,  "h27",   1, 3, "kpd_col2", "kpd_col5", NULL, "gpio_1", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x0188,  "j26", 175, 3, "kpd_row3", "kpd_row0", NULL, "gpio_175", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x018a,  "j25", 176, 3, "kpd_row4", "kpd_row1", NULL, "gpio_176", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x018c,  "k26", 177, 3, "kpd_row5", "kpd_row2", NULL, "gpio_177", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x018e,  "k25", 178, 3, "kpd_row0", "kpd_row3", NULL, "gpio_178", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x0190,  "l27",   2, 3, "kpd_row1", "kpd_row4", NULL, "gpio_2", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x0192,  "k27",   3, 3, "kpd_row2", "kpd_row5", NULL, "gpio_3", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x0194,   "c3",   0, 0, "usba0_otg_ce", NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	_PINDEF(0x0196,   "b5",   0, 0, "usba0_otg_dp", "uart3_rx_irrx", "uart2_rx", NULL, NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x0198,   "b4",   0, 0, "usba0_otg_dm", "uart3_tx_irtx", "uart2_tx", NULL, NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x019a, "aa28", 181, 3, "fref_clk1_out", NULL, NULL, "gpio_181", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x019c,  "y28", 182, 3, "fref_clk2_out", NULL, NULL, "gpio_182", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x019e,  "ae6",   0, 0, "sys_nirq1", NULL, NULL, NULL, NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x01a0,  "af6", 183, 3, "sys_nirq2", NULL, NULL, "gpio_183", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x01a2,  "f26", 184, 3, "sys_boot0", NULL, NULL, "gpio_184", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x01a4,  "e27", 185, 3, "sys_boot1", NULL, NULL, "gpio_185", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x01a6,  "e26", 186, 3, "sys_boot2", NULL, NULL, "gpio_186", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x01a8,  "e25", 187, 3, "sys_boot3", NULL, NULL, "gpio_187", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x01aa,  "d28", 188, 3, "sys_boot4", NULL, NULL, "gpio_188", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x01ac,  "d27", 189, 3, "sys_boot5", NULL, NULL, "gpio_189", NULL, NULL, NULL, "safe_mode"),
+	_PINDEF(0x01ae,   "m2",  11, 3, "dpm_emu0", NULL, NULL, "gpio_11", NULL, NULL, "hw_dbg0", "safe_mode"),
+	_PINDEF(0x01b0,   "n2",  12, 3, "dpm_emu1", NULL, NULL, "gpio_12", NULL, NULL, "hw_dbg1", "safe_mode"),
+	_PINDEF(0x01b2,   "p2",  13, 3, "dpm_emu2", "usba0_ulpiphy_clk", NULL, "gpio_13", NULL, "dispc2_fid", "hw_dbg2", "safe_mode"),
+	_PINDEF(0x01b4,   "v1",  14, 3, "dpm_emu3", "usba0_ulpiphy_stp", NULL, "gpio_14", "rfbi_data10", "dispc2_data10", "hw_dbg3", "safe_mode"),
+	_PINDEF(0x01b6,   "v2",  15, 3, "dpm_emu4", "usba0_ulpiphy_dir", NULL, "gpio_15", "rfbi_data9", "dispc2_data9", "hw_dbg4", "safe_mode"),
+	_PINDEF(0x01b8,   "w1",  16, 3, "dpm_emu5", "usba0_ulpiphy_nxt", NULL, "gpio_16", "rfbi_te_vsync0", "dispc2_data16", "hw_dbg5", "safe_mode"),
+	_PINDEF(0x01ba,   "w2",  17, 3, "dpm_emu6", "usba0_ulpiphy_dat0", "uart3_tx_irtx", "gpio_17", "rfbi_hsync0", "dispc2_data17", "hw_dbg6", "safe_mode"),
+	_PINDEF(0x01bc,   "w3",  18, 3, "dpm_emu7", "usba0_ulpiphy_dat1", "uart3_rx_irrx", "gpio_18", "rfbi_cs0", "dispc2_hsync", "hw_dbg7", "safe_mode"),
+	_PINDEF(0x01be,   "w4",  19, 3, "dpm_emu8", "usba0_ulpiphy_dat2", "uart3_rts_sd", "gpio_19", "rfbi_re", "dispc2_pclk", "hw_dbg8", "safe_mode"),
+	_PINDEF(0x01c0,   "y2",  20, 3, "dpm_emu9", "usba0_ulpiphy_dat3", "uart3_cts_rctx", "gpio_20", "rfbi_we", "dispc2_vsync", "hw_dbg9", "safe_mode"),
+	_PINDEF(0x01c2,   "y3",  21, 3, "dpm_emu10", "usba0_ulpiphy_dat4", NULL, "gpio_21", "rfbi_a0", "dispc2_de", "hw_dbg10", "safe_mode"),
+	_PINDEF(0x01c4,   "y4",  22, 3, "dpm_emu11", "usba0_ulpiphy_dat5", NULL, "gpio_22", "rfbi_data8", "dispc2_data8", "hw_dbg11", "safe_mode"),
+	_PINDEF(0x01c6,  "aa1",  23, 3, "dpm_emu12", "usba0_ulpiphy_dat6", NULL, "gpio_23", "rfbi_data7", "dispc2_data7", "hw_dbg12", "safe_mode"),
+	_PINDEF(0x01c8,  "aa2",  24, 3, "dpm_emu13", "usba0_ulpiphy_dat7", NULL, "gpio_24", "rfbi_data6", "dispc2_data6", "hw_dbg13", "safe_mode"),
+	_PINDEF(0x01ca,  "aa3",  25, 3, "dpm_emu14", "sys_drm_msecure", "uart1_rx", "gpio_25", "rfbi_data5", "dispc2_data5", "hw_dbg14", "safe_mode"),
+	_PINDEF(0x01cc,  "aa4",  26, 3, "dpm_emu15", "sys_secure_indicator", NULL, "gpio_26", "rfbi_data4", "dispc2_data4", "hw_dbg15", "safe_mode"),
+	_PINDEF(0x01ce,  "ab2",  27, 3, "dpm_emu16", "dmtimer8_pwm_evt", "dsi1_te0", "gpio_27", "rfbi_data3", "dispc2_data3", "hw_dbg16", "safe_mode"),
+	_PINDEF(0x01d0,  "ab3",  28, 3, "dpm_emu17", "dmtimer9_pwm_evt", "dsi1_te1", "gpio_28", "rfbi_data2", "dispc2_data2", "hw_dbg17", "safe_mode"),
+	_PINDEF(0x01d2,  "ab4", 190, 3, "dpm_emu18", "dmtimer10_pwm_evt", "dsi2_te0", "gpio_190", "rfbi_data1", "dispc2_data1", "hw_dbg18", "safe_mode"),
+	_PINDEF(0x01d4,  "ac4", 191, 3, "dpm_emu19", "dmtimer11_pwm_evt", "dsi2_te1", "gpio_191", "rfbi_data0", "dispc2_data0", "hw_dbg19", "safe_mode"),
+	{  .ballname = NULL  },
+};
+
+const struct ti_scm_device ti_scm_dev = {
+	.padconf_muxmode_mask	= CONTROL_PADCONF_MUXMODE_MASK,
+	.padconf_sate_mask	= CONTROL_PADCONF_SATE_MASK,
+	.padstate		= ti_padstate_devmap,
+	.padconf		= ti_padconf_devmap,
+};
+
+int
+ti_scm_padconf_set_gpioflags(uint32_t gpio, uint32_t flags)
+{
+	unsigned int state = 0;
+	/* First the SCM driver needs to be told to put the pad into GPIO mode */
+	if (flags & GPIO_PIN_OUTPUT)
+		state = PADCONF_PIN_OUTPUT;
+	else if (flags & GPIO_PIN_INPUT) {
+		if (flags & GPIO_PIN_PULLUP)
+			state = PADCONF_PIN_INPUT_PULLUP;
+		else if (flags & GPIO_PIN_PULLDOWN)
+			state = PADCONF_PIN_INPUT_PULLDOWN;
+		else
+			state = PADCONF_PIN_INPUT;
+	}
+	return ti_scm_padconf_set_gpiomode(gpio, state);
+}
+
+void
+ti_scm_padconf_get_gpioflags(uint32_t gpio, uint32_t *flags)
+{
+	unsigned int state;
+	/* Get the current pin state */
+	if (ti_scm_padconf_get_gpiomode(gpio, &state) != 0)
+		*flags = 0;
+	else {
+		switch (state) {
+			case PADCONF_PIN_OUTPUT:
+				*flags = GPIO_PIN_OUTPUT;
+				break;
+			case PADCONF_PIN_INPUT:
+				*flags = GPIO_PIN_INPUT;
+				break;
+			case PADCONF_PIN_INPUT_PULLUP:
+				*flags = GPIO_PIN_INPUT | GPIO_PIN_PULLUP;
+				break;
+			case PADCONF_PIN_INPUT_PULLDOWN:
+				*flags = GPIO_PIN_INPUT | GPIO_PIN_PULLDOWN;
+				break;
+			default:
+				*flags = 0;
+				break;
+		}
+	}
+}
+


Property changes on: trunk/sys/arm/ti/omap4/omap4_scm_padconf.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/omap4/omap4_smc.h
===================================================================
--- trunk/sys/arm/ti/omap4/omap4_smc.h	                        (rev 0)
+++ trunk/sys/arm/ti/omap4/omap4_smc.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,53 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Olivier Houchard.  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 ``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 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: stable/10/sys/arm/ti/omap4/omap4_smc.h 244914 2012-12-31 21:19:44Z gonzo $
+ */
+
+#ifndef OMAP4_SMC_H_
+#define OMAP4_SMC_H_
+/* Define the various function IDs used by the OMAP4 */
+#define L2CACHE_WRITE_DEBUG_REG		0x100
+#define L2CACHE_CLEAN_INV_RANG		0x101
+#define L2CACHE_WRITE_CTRL_REG		0x102
+#define READ_AUX_CORE_REGS		0x103
+#define MODIFY_AUX_CORE_0		0x104
+#define WRITE_AUX_CORE_1		0x105
+#define READ_WKG_CTRL_REG		0x106
+#define CLEAR_WKG_CTRL_REG		0x107
+#define SET_POWER_STATUS_REG		0x108
+#define WRITE_AUXCTRL_REG		0x109
+#define LOCKDOWN_TLB			0x10a
+#define SELECT_TLB_ENTRY_FOR_WRITE	0x10b
+#define READ_TLB_VA_ENTRY		0x10c
+#define WRITE_TLB_VA_ENTRY		0x10d
+#define READ_TLB_PA_ENTRY		0x10e
+#define WRITE_TLB_PA_ENTRY		0x10f
+#define READ_TLB_ATTR_ENTRY		0x110
+#define WRITE_TLB_ATTR_ENTRY		0x111
+#define WRITE_LATENCY_CTRL_REG		0x112
+#define WRITE_PREFETCH_CTRL_REG		0x113
+#endif /* OMAP4_SMC_H_ */


Property changes on: trunk/sys/arm/ti/omap4/omap4_smc.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/omap4/omap4var.h
===================================================================
--- trunk/sys/arm/ti/omap4/omap4var.h	                        (rev 0)
+++ trunk/sys/arm/ti/omap4/omap4var.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,92 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2010
+ *	Ben Gray <ben.r.gray at gmail.com>.
+ * 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.
+ * 3. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BEN GRAY ``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 BEN GRAY 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: stable/10/sys/arm/ti/omap4/omap4var.h 239281 2012-08-15 06:31:32Z gonzo $
+ */
+
+#ifndef _OMAP4VAR_H_
+#define	_OMAP4VAR_H_
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/time.h>
+#include <sys/bus.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+#include <sys/sysctl.h>
+#include <sys/endian.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+#include <machine/resource.h>
+#include <machine/intr.h>
+
+
+void omap4_mask_all_intr(void);
+void omap4_post_filter_intr(void *arg);
+
+struct omap4_softc {
+	device_t sc_dev;
+	bus_space_tag_t sc_iotag;
+    
+	/* Handles for the two generic interrupt controller (GIC) register mappings */
+	bus_space_handle_t sc_gic_cpu_ioh;
+	bus_space_handle_t sc_gic_dist_ioh;
+	
+	/* Handle for the PL310 L2 cache controller */
+	bus_space_handle_t sc_pl310_ioh;
+	
+	/* Handle for the global and provate timer register set in the Cortex core */
+	bus_space_handle_t sc_prv_timer_ioh;
+	bus_space_handle_t sc_gbl_timer_ioh;
+	
+	/* SCM access */
+	struct resource *sc_scm_mem;
+	int sc_scm_rid;
+};
+
+struct omap4_intr_conf {
+	int            num;
+	unsigned int   priority;
+	unsigned int   target_cpu;
+};
+
+int omap4_setup_intr_controller(device_t dev,
+    const struct omap4_intr_conf *irqs);
+int omap4_setup_gic_cpu(unsigned int prio_mask);
+
+void omap4_init_timer(device_t dev);
+
+int omap4_setup_l2cache_controller(struct omap4_softc *sc);
+void omap4_smc_call(uint32_t fn, uint32_t arg);
+
+#endif /* _OMAP4VAR_H_ */


Property changes on: trunk/sys/arm/ti/omap4/omap4var.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/omap4/pandaboard/files.pandaboard
===================================================================
--- trunk/sys/arm/ti/omap4/pandaboard/files.pandaboard	                        (rev 0)
+++ trunk/sys/arm/ti/omap4/pandaboard/files.pandaboard	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,3 @@
+# $FreeBSD: stable/10/sys/arm/ti/omap4/pandaboard/files.pandaboard 239281 2012-08-15 06:31:32Z gonzo $
+
+arm/ti/omap4/pandaboard/pandaboard.c		standard


Property changes on: trunk/sys/arm/ti/omap4/pandaboard/files.pandaboard
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/ti/omap4/pandaboard/pandaboard.c
===================================================================
--- trunk/sys/arm/ti/omap4/pandaboard/pandaboard.c	                        (rev 0)
+++ trunk/sys/arm/ti/omap4/pandaboard/pandaboard.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,210 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2011
+ *	Ben Gray <ben.r.gray at gmail.com>.
+ * 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.
+ * 3. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BEN GRAY ``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 BEN GRAY 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: stable/10/sys/arm/ti/omap4/pandaboard/pandaboard.c 259329 2013-12-13 20:43:11Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <machine/bus.h>
+#include <machine/pte.h>
+#include <machine/vmparam.h>
+#include <machine/fdt.h>
+
+#include <arm/ti/omap4/omap4var.h>
+#include <arm/ti/omap4/omap4_reg.h>
+
+/* Registers in the SCRM that control the AUX clocks */
+#define SCRM_ALTCLKSRC			     (0x110)
+#define SCRM_AUXCLK0                         (0x0310)
+#define SCRM_AUXCLK1                         (0x0314)
+#define SCRM_AUXCLK2                         (0x0318)
+#define SCRM_AUXCLK3                         (0x031C)
+
+/* Some of the GPIO register set */
+#define GPIO1_OE                             (0x0134)
+#define GPIO1_CLEARDATAOUT                   (0x0190)
+#define GPIO1_SETDATAOUT                     (0x0194)
+#define GPIO2_OE                             (0x0134)
+#define GPIO2_CLEARDATAOUT                   (0x0190)
+#define GPIO2_SETDATAOUT                     (0x0194)
+
+/* Some of the PADCONF register set */
+#define CONTROL_WKUP_PAD0_FREF_CLK3_OUT  (0x058)
+#define CONTROL_CORE_PAD1_KPD_COL2       (0x186)
+#define CONTROL_CORE_PAD0_GPMC_WAIT1     (0x08C)
+
+#define REG_WRITE32(r, x)    *((volatile uint32_t*)(r)) = (uint32_t)(x)
+#define REG_READ32(r)        *((volatile uint32_t*)(r))
+
+#define REG_WRITE16(r, x)    *((volatile uint16_t*)(r)) = (uint16_t)(x)
+#define REG_READ16(r)        *((volatile uint16_t*)(r))
+
+/**
+ *	usb_hub_init - initialises and resets the external USB hub
+ *	
+ *	The USB hub needs to be held in reset while the power is being applied
+ *	and the reference clock is enabled at 19.2MHz.  The following is the
+ *	layout of the USB hub taken from the Pandaboard reference manual.
+ *
+ *
+ *	   .-------------.         .--------------.         .----------------.
+ *	   |  OMAP4430   |         |   USB3320C   |         |    LAN9514     |
+ *	   |             |         |              |         | USB Hub / Eth  |
+ *	   |         CLK | <------ | CLKOUT       |         |                |
+ *	   |         STP | ------> | STP          |         |                |
+ *	   |         DIR | <------ | DIR          |         |                |
+ *	   |         NXT | <------ | NXT          |         |                |
+ *	   |        DAT0 | <-----> | DAT0         |         |                |
+ *	   |        DAT1 | <-----> | DAT1      DP | <-----> | DP             |
+ *	   |        DAT2 | <-----> | DAT2      DM | <-----> | DM             |
+ *	   |        DAT3 | <-----> | DAT3         |         |                |
+ *	   |        DAT4 | <-----> | DAT4         |         |                |
+ *	   |        DAT5 | <-----> | DAT5         |  +----> | N_RESET        |
+ *	   |        DAT6 | <-----> | DAT6         |  |      |                |
+ *	   |        DAT7 | <-----> | DAT7         |  |      |                |
+ *	   |             |         |              |  |  +-> | VDD33IO        |
+ *	   |    AUX_CLK3 | ------> | REFCLK       |  |  +-> | VDD33A         |
+ *	   |             |         |              |  |  |   |                |
+ *	   |     GPIO_62 | --+---> | RESET        |  |  |   |                |
+ *	   |             |   |     |              |  |  |   |                |
+ *	   |             |   |     '--------------'  |  |   '----------------'
+ *	   |             |   |     .--------------.  |  |
+ *	   |             |   '---->| VOLT CONVERT |--'  |
+ *	   |             |         '--------------'     |
+ *	   |             |                              |
+ *	   |             |         .--------------.     |
+ *	   |      GPIO_1 | ------> |   TPS73633   |-----'
+ *	   |             |         '--------------'
+ *	   '-------------'
+ *	
+ *
+ *	RETURNS:
+ *	nothing.
+ */
+static void
+usb_hub_init(void)
+{
+	bus_space_handle_t scrm_addr, gpio1_addr, gpio2_addr, scm_addr;
+
+	if (bus_space_map(fdtbus_bs_tag, OMAP44XX_SCRM_HWBASE,
+	    OMAP44XX_SCRM_SIZE, 0, &scrm_addr) != 0)
+		panic("Couldn't map SCRM registers");
+	if (bus_space_map(fdtbus_bs_tag, OMAP44XX_GPIO1_HWBASE, 
+	    OMAP44XX_GPIO1_SIZE, 0, &gpio1_addr) != 0)
+		panic("Couldn't map GPIO1 registers");
+	if (bus_space_map(fdtbus_bs_tag, OMAP44XX_GPIO2_HWBASE,
+	    OMAP44XX_GPIO2_SIZE, 0, &gpio2_addr) != 0)
+		panic("Couldn't map GPIO2 registers");
+	if (bus_space_map(fdtbus_bs_tag, OMAP44XX_SCM_PADCONF_HWBASE,
+	    OMAP44XX_SCM_PADCONF_SIZE, 0, &scm_addr) != 0)
+		panic("Couldn't map SCM Padconf registers");
+
+	
+
+	/* Need to set FREF_CLK3_OUT to 19.2 MHz and pump it out on pin GPIO_WK31.
+	 * We know the SYS_CLK is 38.4Mhz and therefore to get the needed 19.2Mhz,
+	 * just use a 2x divider and ensure the SYS_CLK is used as the source.
+	 */
+	REG_WRITE32(scrm_addr + SCRM_AUXCLK3, (1 << 16) |    /* Divider of 2 */
+	                          (0 << 1) |     /* Use the SYS_CLK as the source */
+	                          (1 << 8));     /* Enable the clock */
+
+	/* Enable the clock out to the pin (GPIO_WK31). 
+	 *   muxmode=fref_clk3_out, pullup/down=disabled, input buffer=disabled,
+	 *   wakeup=disabled.
+	 */
+	REG_WRITE16(scm_addr + CONTROL_WKUP_PAD0_FREF_CLK3_OUT, 0x0000);
+
+
+	/* Disable the power to the USB hub, drive GPIO1 low */
+	REG_WRITE32(gpio1_addr + GPIO1_OE, REG_READ32(gpio1_addr + 
+	    GPIO1_OE) & ~(1UL << 1));
+	REG_WRITE32(gpio1_addr + GPIO1_CLEARDATAOUT, (1UL << 1));
+	REG_WRITE16(scm_addr + CONTROL_CORE_PAD1_KPD_COL2, 0x0003);
+	
+	
+	/* Reset the USB PHY and Hub using GPIO_62 */
+	REG_WRITE32(gpio2_addr + GPIO2_OE, 
+	    REG_READ32(gpio2_addr + GPIO2_OE) & ~(1UL << 30));
+	REG_WRITE32(gpio2_addr + GPIO2_CLEARDATAOUT, (1UL << 30));
+	REG_WRITE16(scm_addr + CONTROL_CORE_PAD0_GPMC_WAIT1, 0x0003);
+	DELAY(10);
+	REG_WRITE32(gpio2_addr + GPIO2_SETDATAOUT, (1UL << 30));
+
+	
+	/* Enable power to the hub (GPIO_1) */
+	REG_WRITE32(gpio1_addr + GPIO1_SETDATAOUT, (1UL << 1));
+	bus_space_unmap(fdtbus_bs_tag, scrm_addr, OMAP44XX_SCRM_SIZE);
+	bus_space_unmap(fdtbus_bs_tag, gpio1_addr, OMAP44XX_GPIO1_SIZE);
+	bus_space_unmap(fdtbus_bs_tag, gpio2_addr, OMAP44XX_GPIO2_SIZE);
+	bus_space_unmap(fdtbus_bs_tag, scm_addr, OMAP44XX_SCM_PADCONF_SIZE);
+}
+
+/**
+ *	board_init - initialises the pandaboard
+ *	@dummy: ignored
+ * 
+ *	This function is called before any of the driver are initialised, which is
+ *	annoying because it means we can't use the SCM, PRCM and GPIO modules which
+ *	would really be useful.
+ *
+ *	So we don't have:
+ *	   - any drivers
+ *	   - no interrupts
+ *
+ *	What we do have:
+ *	   - virt/phys mappings from the devmap (see omap4.c)
+ *	   - 
+ *
+ *
+ *	So we are hamstrung without the useful drivers and we have to go back to
+ *	direct register manupulation. Luckly we don't have to do to much, basically
+ *	just setup the usb hub/ethernet.
+ *
+ */
+static void
+board_init(void *dummy)
+{
+	/* Initialise the USB phy and hub */
+	usb_hub_init();
+	
+	/*
+	 * XXX Board identification e.g. read out from FPGA or similar should
+	 * go here
+	 */
+}
+
+SYSINIT(board_init, SI_SUB_CPU, SI_ORDER_THIRD, board_init, NULL);


Property changes on: trunk/sys/arm/ti/omap4/pandaboard/pandaboard.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/omap4/pandaboard/std.pandaboard
===================================================================
--- trunk/sys/arm/ti/omap4/pandaboard/std.pandaboard	                        (rev 0)
+++ trunk/sys/arm/ti/omap4/pandaboard/std.pandaboard	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,4 @@
+# $FreeBSD: stable/10/sys/arm/ti/omap4/pandaboard/std.pandaboard 239281 2012-08-15 06:31:32Z gonzo $
+
+include	"../ti/omap4/std.omap4"
+files	"../ti/omap4/pandaboard/files.pandaboard"


Property changes on: trunk/sys/arm/ti/omap4/pandaboard/std.pandaboard
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/ti/omap4/std.omap4
===================================================================
--- trunk/sys/arm/ti/omap4/std.omap4	                        (rev 0)
+++ trunk/sys/arm/ti/omap4/std.omap4	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,23 @@
+# Omap4430 generic configuration
+#$FreeBSD: stable/10/sys/arm/ti/omap4/std.omap4 266110 2014-05-15 02:41:23Z ian $
+files		"../ti/omap4/files.omap4"
+include		"../ti/std.ti"
+makeoption	ARM_LITTLE_ENDIAN
+
+# Physical memory starts at 0x80000000.  We assume images are loaded at
+# 0x80200000, e.g. from u-boot with 'fatload mmc 0 0x80200000 kernel.bin'
+#
+#
+options		PHYSADDR=0x80000000
+options		KERNPHYSADDR=0x80200000
+makeoptions	KERNPHYSADDR=0x80200000
+options		KERNVIRTADDR=0xc0200000		# Used in ldscript.arm
+makeoptions	KERNVIRTADDR=0xc0200000
+
+options		SOC_OMAP4
+
+options		ARM_L2_PIPT
+
+options		IPI_IRQ_START=0
+options		IPI_IRQ_END=15
+


Property changes on: trunk/sys/arm/ti/omap4/std.omap4
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/ti/std.ti
===================================================================
--- trunk/sys/arm/ti/std.ti	                        (rev 0)
+++ trunk/sys/arm/ti/std.ti	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,7 @@
+# $FreeBSD: stable/10/sys/arm/ti/std.ti 278601 2015-02-11 22:47:48Z ian $
+
+cpu 		CPU_CORTEXA
+machine 	arm	armv6
+makeoptions	CONF_CFLAGS="-march=armv7a -Wa,-march=armv7a"
+
+files		"../ti/files.ti"


Property changes on: trunk/sys/arm/ti/std.ti
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/ti/ti_adc.c
===================================================================
--- trunk/sys/arm/ti/ti_adc.c	                        (rev 0)
+++ trunk/sys/arm/ti/ti_adc.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,595 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright 2014 Luiz Otavio O Souza <loos at freebsd.org>
+ * 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: stable/10/sys/arm/ti/ti_adc.c 270238 2014-08-20 18:10:12Z loos $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+
+#include <sys/kernel.h>
+#include <sys/limits.h>
+#include <sys/lock.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+#include <sys/sysctl.h>
+
+#include <machine/bus.h>
+
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <arm/ti/ti_prcm.h>
+#include <arm/ti/ti_adcreg.h>
+#include <arm/ti/ti_adcvar.h>
+
+/* Define our 8 steps, one for each input channel. */
+static struct ti_adc_input ti_adc_inputs[TI_ADC_NPINS] = {
+	{ .stepconfig = ADC_STEPCFG1, .stepdelay = ADC_STEPDLY1 },
+	{ .stepconfig = ADC_STEPCFG2, .stepdelay = ADC_STEPDLY2 },
+	{ .stepconfig = ADC_STEPCFG3, .stepdelay = ADC_STEPDLY3 },
+	{ .stepconfig = ADC_STEPCFG4, .stepdelay = ADC_STEPDLY4 },
+	{ .stepconfig = ADC_STEPCFG5, .stepdelay = ADC_STEPDLY5 },
+	{ .stepconfig = ADC_STEPCFG6, .stepdelay = ADC_STEPDLY6 },
+	{ .stepconfig = ADC_STEPCFG7, .stepdelay = ADC_STEPDLY7 },
+	{ .stepconfig = ADC_STEPCFG8, .stepdelay = ADC_STEPDLY8 },
+};
+
+static int ti_adc_samples[5] = { 0, 2, 4, 8, 16 };
+
+static void
+ti_adc_enable(struct ti_adc_softc *sc)
+{
+
+	TI_ADC_LOCK_ASSERT(sc);
+
+	if (sc->sc_last_state == 1)
+		return;
+
+	/* Enable the FIFO0 threshold and the end of sequence interrupt. */
+	ADC_WRITE4(sc, ADC_IRQENABLE_SET,
+	    ADC_IRQ_FIFO0_THRES | ADC_IRQ_END_OF_SEQ);
+
+	/* Enable the ADC.  Run thru enabled steps, start the conversions. */
+	ADC_WRITE4(sc, ADC_CTRL, ADC_READ4(sc, ADC_CTRL) | ADC_CTRL_ENABLE);
+
+	sc->sc_last_state = 1;
+}
+
+static void
+ti_adc_disable(struct ti_adc_softc *sc)
+{
+	int count;
+	uint32_t data;
+
+	TI_ADC_LOCK_ASSERT(sc);
+
+	if (sc->sc_last_state == 0)
+		return;
+
+	/* Disable all the enabled steps. */
+	ADC_WRITE4(sc, ADC_STEPENABLE, 0);
+
+	/* Disable the ADC. */
+	ADC_WRITE4(sc, ADC_CTRL, ADC_READ4(sc, ADC_CTRL) & ~ADC_CTRL_ENABLE);
+
+	/* Disable the FIFO0 threshold and the end of sequence interrupt. */
+	ADC_WRITE4(sc, ADC_IRQENABLE_CLR,
+	    ADC_IRQ_FIFO0_THRES | ADC_IRQ_END_OF_SEQ);
+
+	/* ACK any pending interrupt. */
+	ADC_WRITE4(sc, ADC_IRQSTATUS, ADC_READ4(sc, ADC_IRQSTATUS));
+
+	/* Drain the FIFO data. */
+	count = ADC_READ4(sc, ADC_FIFO0COUNT) & ADC_FIFO_COUNT_MSK;
+	while (count > 0) {
+		data = ADC_READ4(sc, ADC_FIFO0DATA);
+		count = ADC_READ4(sc, ADC_FIFO0COUNT) & ADC_FIFO_COUNT_MSK;
+	}
+
+	sc->sc_last_state = 0;
+}
+
+static int
+ti_adc_setup(struct ti_adc_softc *sc)
+{
+	int ain;
+	uint32_t enabled;
+
+	TI_ADC_LOCK_ASSERT(sc);
+
+	/* Check for enabled inputs. */
+	enabled = 0;
+	for (ain = 0; ain < TI_ADC_NPINS; ain++) {
+		if (ti_adc_inputs[ain].enable)
+			enabled |= (1U << (ain + 1));
+	}
+
+	/* Set the ADC global status. */
+	if (enabled != 0) {
+		ti_adc_enable(sc);
+		/* Update the enabled steps. */
+		if (enabled != ADC_READ4(sc, ADC_STEPENABLE))
+			ADC_WRITE4(sc, ADC_STEPENABLE, enabled);
+	} else
+		ti_adc_disable(sc);
+
+	return (0);
+}
+
+static void
+ti_adc_input_setup(struct ti_adc_softc *sc, int32_t ain)
+{
+	struct ti_adc_input *input;
+	uint32_t reg, val;
+
+	TI_ADC_LOCK_ASSERT(sc);
+
+	input = &ti_adc_inputs[ain];
+	reg = input->stepconfig;
+	val = ADC_READ4(sc, reg);
+
+	/* Set single ended operation. */
+	val &= ~ADC_STEP_DIFF_CNTRL;
+
+	/* Set the negative voltage reference. */
+	val &= ~ADC_STEP_RFM_MSK;
+	val |= ADC_STEP_RFM_VREFN << ADC_STEP_RFM_SHIFT;
+
+	/* Set the positive voltage reference. */
+	val &= ~ADC_STEP_RFP_MSK;
+	val |= ADC_STEP_RFP_VREFP << ADC_STEP_RFP_SHIFT;
+
+	/* Set the samples average. */
+	val &= ~ADC_STEP_AVG_MSK;
+	val |= input->samples << ADC_STEP_AVG_SHIFT;
+
+	/* Select the desired input. */
+	val &= ~ADC_STEP_INP_MSK;
+	val |= ain << ADC_STEP_INP_SHIFT;
+
+	/* Set the ADC to one-shot mode. */
+	val &= ~ADC_STEP_MODE_MSK;
+
+	ADC_WRITE4(sc, reg, val);
+}
+
+static void
+ti_adc_reset(struct ti_adc_softc *sc)
+{
+	int ain;
+
+	TI_ADC_LOCK_ASSERT(sc);
+
+	/* Disable all the inputs. */
+	for (ain = 0; ain < TI_ADC_NPINS; ain++)
+		ti_adc_inputs[ain].enable = 0;
+}
+
+static int
+ti_adc_clockdiv_proc(SYSCTL_HANDLER_ARGS)
+{
+	int error, reg;
+	struct ti_adc_softc *sc;
+
+	sc = (struct ti_adc_softc *)arg1;
+
+	TI_ADC_LOCK(sc);
+	reg = (int)ADC_READ4(sc, ADC_CLKDIV) + 1;
+	TI_ADC_UNLOCK(sc);
+
+	error = sysctl_handle_int(oidp, &reg, sizeof(reg), req);
+	if (error != 0 || req->newptr == NULL)
+		return (error);
+
+	/*
+	 * The actual written value is the prescaler setting - 1.
+	 * Enforce a minimum value of 10 (i.e. 9) which limits the maximum
+	 * ADC clock to ~2.4Mhz (CLK_M_OSC / 10).
+	 */
+	reg--;
+	if (reg < 9)
+		reg = 9;
+	if (reg > USHRT_MAX)
+		reg = USHRT_MAX;
+
+	TI_ADC_LOCK(sc);
+	/* Disable the ADC. */
+	ti_adc_disable(sc);
+	/* Update the ADC prescaler setting. */
+	ADC_WRITE4(sc, ADC_CLKDIV, reg);
+	/* Enable the ADC again. */
+	ti_adc_setup(sc);
+	TI_ADC_UNLOCK(sc);
+
+	return (0);
+}
+
+static int
+ti_adc_enable_proc(SYSCTL_HANDLER_ARGS)
+{
+	int error;
+	int32_t enable;
+	struct ti_adc_softc *sc;
+	struct ti_adc_input *input;
+
+	input = (struct ti_adc_input *)arg1;
+	sc = input->sc;
+
+	enable = input->enable;
+	error = sysctl_handle_int(oidp, &enable, sizeof(enable),
+	    req);
+	if (error != 0 || req->newptr == NULL)
+		return (error);
+
+	if (enable)
+		enable = 1;
+
+	TI_ADC_LOCK(sc);
+	/* Setup the ADC as needed. */
+	if (input->enable != enable) {
+		input->enable = enable;
+		ti_adc_setup(sc);
+		if (input->enable == 0)
+			input->value = 0;
+	}
+	TI_ADC_UNLOCK(sc);
+
+	return (0);
+}
+
+static int
+ti_adc_open_delay_proc(SYSCTL_HANDLER_ARGS)
+{
+	int error, reg;
+	struct ti_adc_softc *sc;
+	struct ti_adc_input *input;
+
+	input = (struct ti_adc_input *)arg1;
+	sc = input->sc;
+
+	TI_ADC_LOCK(sc);
+	reg = (int)ADC_READ4(sc, input->stepdelay) & ADC_STEP_OPEN_DELAY;
+	TI_ADC_UNLOCK(sc);
+
+	error = sysctl_handle_int(oidp, &reg, sizeof(reg), req);
+	if (error != 0 || req->newptr == NULL)
+		return (error);
+
+	if (reg < 0)
+		reg = 0;
+
+	TI_ADC_LOCK(sc);
+	ADC_WRITE4(sc, input->stepdelay, reg & ADC_STEP_OPEN_DELAY);
+	TI_ADC_UNLOCK(sc);
+
+	return (0);
+}
+
+static int
+ti_adc_samples_avg_proc(SYSCTL_HANDLER_ARGS)
+{
+	int error, samples, i;
+	struct ti_adc_softc *sc;
+	struct ti_adc_input *input;
+
+	input = (struct ti_adc_input *)arg1;
+	sc = input->sc;
+
+	if (input->samples > nitems(ti_adc_samples))
+		input->samples = nitems(ti_adc_samples);
+	samples = ti_adc_samples[input->samples];
+
+	error = sysctl_handle_int(oidp, &samples, 0, req);
+	if (error != 0 || req->newptr == NULL)
+		return (error);
+
+	TI_ADC_LOCK(sc);
+	if (samples != ti_adc_samples[input->samples]) {
+		input->samples = 0;
+		for (i = 0; i < nitems(ti_adc_samples); i++)
+			if (samples >= ti_adc_samples[i])
+				input->samples = i;
+		ti_adc_input_setup(sc, input->input);
+	}
+	TI_ADC_UNLOCK(sc);
+
+	return (error);
+}
+
+static void
+ti_adc_read_data(struct ti_adc_softc *sc)
+{
+	int count, ain;
+	struct ti_adc_input *input;
+	uint32_t data;
+
+	TI_ADC_LOCK_ASSERT(sc);
+
+	/* Read the available data. */
+	count = ADC_READ4(sc, ADC_FIFO0COUNT) & ADC_FIFO_COUNT_MSK;
+	while (count > 0) {
+		data = ADC_READ4(sc, ADC_FIFO0DATA);
+		ain = (data & ADC_FIFO_STEP_ID_MSK) >> ADC_FIFO_STEP_ID_SHIFT;
+		input = &ti_adc_inputs[ain];
+		if (input->enable == 0)
+			input->value = 0;
+		else
+			input->value = (int32_t)(data & ADC_FIFO_DATA_MSK);
+		count = ADC_READ4(sc, ADC_FIFO0COUNT) & ADC_FIFO_COUNT_MSK;
+	}
+}
+
+static void
+ti_adc_intr(void *arg)
+{
+	struct ti_adc_softc *sc;
+	uint32_t status;
+
+	sc = (struct ti_adc_softc *)arg;
+
+	status = ADC_READ4(sc, ADC_IRQSTATUS);
+	if (status == 0)
+		return;
+	if (status & ~(ADC_IRQ_FIFO0_THRES | ADC_IRQ_END_OF_SEQ))
+		device_printf(sc->sc_dev, "stray interrupt: %#x\n", status);
+
+	TI_ADC_LOCK(sc);
+	/* ACK the interrupt. */
+	ADC_WRITE4(sc, ADC_IRQSTATUS, status);
+
+	/* Read the available data. */
+	if (status & ADC_IRQ_FIFO0_THRES)
+		ti_adc_read_data(sc);
+
+	/* Start the next conversion ? */
+	if (status & ADC_IRQ_END_OF_SEQ)
+		ti_adc_setup(sc);
+	TI_ADC_UNLOCK(sc);
+}
+
+static void
+ti_adc_sysctl_init(struct ti_adc_softc *sc)
+{
+	char pinbuf[3];
+	struct sysctl_ctx_list *ctx;
+	struct sysctl_oid *tree_node, *inp_node, *inpN_node;
+	struct sysctl_oid_list *tree, *inp_tree, *inpN_tree;
+	int ain;
+
+	/*
+	 * Add per-pin sysctl tree/handlers.
+	 */
+	ctx = device_get_sysctl_ctx(sc->sc_dev);
+	tree_node = device_get_sysctl_tree(sc->sc_dev);
+	tree = SYSCTL_CHILDREN(tree_node);
+	SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "clockdiv",
+	    CTLFLAG_RW | CTLTYPE_UINT,  sc, 0,
+	    ti_adc_clockdiv_proc, "IU", "ADC clock prescaler");
+	inp_node = SYSCTL_ADD_NODE(ctx, tree, OID_AUTO, "ain",
+	    CTLFLAG_RD, NULL, "ADC inputs");
+	inp_tree = SYSCTL_CHILDREN(inp_node);
+
+	for (ain = 0; ain < TI_ADC_NPINS; ain++) {
+
+		snprintf(pinbuf, sizeof(pinbuf), "%d", ain);
+		inpN_node = SYSCTL_ADD_NODE(ctx, inp_tree, OID_AUTO, pinbuf,
+		    CTLFLAG_RD, NULL, "ADC input");
+		inpN_tree = SYSCTL_CHILDREN(inpN_node);
+
+		SYSCTL_ADD_PROC(ctx, inpN_tree, OID_AUTO, "enable",
+		    CTLFLAG_RW | CTLTYPE_UINT, &ti_adc_inputs[ain], 0,
+		    ti_adc_enable_proc, "IU", "Enable ADC input");
+		SYSCTL_ADD_PROC(ctx, inpN_tree, OID_AUTO, "open_delay",
+		    CTLFLAG_RW | CTLTYPE_UINT,  &ti_adc_inputs[ain], 0,
+		    ti_adc_open_delay_proc, "IU", "ADC open delay");
+		SYSCTL_ADD_PROC(ctx, inpN_tree, OID_AUTO, "samples_avg",
+		    CTLFLAG_RW | CTLTYPE_UINT,  &ti_adc_inputs[ain], 0,
+		    ti_adc_samples_avg_proc, "IU", "ADC samples average");
+		SYSCTL_ADD_INT(ctx, inpN_tree, OID_AUTO, "input",
+		    CTLFLAG_RD, &ti_adc_inputs[ain].value, 0,
+		    "Converted raw value for the ADC input");
+	}
+}
+
+static void
+ti_adc_inputs_init(struct ti_adc_softc *sc)
+{
+	int ain;
+	struct ti_adc_input *input;
+
+	TI_ADC_LOCK(sc);
+	for (ain = 0; ain < TI_ADC_NPINS; ain++) {
+		input = &ti_adc_inputs[ain];
+		input->sc = sc;
+		input->input = ain;
+		input->value = 0;
+		input->enable = 0;
+		input->samples = 0;
+		ti_adc_input_setup(sc, ain);
+	}
+	TI_ADC_UNLOCK(sc);
+}
+
+static void
+ti_adc_idlestep_init(struct ti_adc_softc *sc)
+{
+	uint32_t val;
+
+	val = ADC_READ4(sc, ADC_IDLECONFIG);
+
+	/* Set single ended operation. */
+	val &= ~ADC_STEP_DIFF_CNTRL;
+
+	/* Set the negative voltage reference. */
+	val &= ~ADC_STEP_RFM_MSK;
+	val |= ADC_STEP_RFM_VREFN << ADC_STEP_RFM_SHIFT;
+
+	/* Set the positive voltage reference. */
+	val &= ~ADC_STEP_RFP_MSK;
+	val |= ADC_STEP_RFP_VREFP << ADC_STEP_RFP_SHIFT;
+
+	/* Connect the input to VREFN. */
+	val &= ~ADC_STEP_INP_MSK;
+	val |= ADC_STEP_IN_VREFN << ADC_STEP_INP_SHIFT;
+
+	ADC_WRITE4(sc, ADC_IDLECONFIG, val);
+}
+
+static int
+ti_adc_probe(device_t dev)
+{
+
+	if (!ofw_bus_is_compatible(dev, "ti,adc"))
+		return (ENXIO);
+	device_set_desc(dev, "TI ADC controller");
+
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+ti_adc_attach(device_t dev)
+{
+	int err, rid;
+	struct ti_adc_softc *sc;
+	uint32_t reg, rev;
+
+	sc = device_get_softc(dev);
+	sc->sc_dev = dev;
+
+	rid = 0;
+	sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	    RF_ACTIVE);
+	if (!sc->sc_mem_res) {
+		device_printf(dev, "cannot allocate memory window\n");
+		return (ENXIO);
+	}
+
+	rid = 0;
+	sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+	    RF_ACTIVE);
+	if (!sc->sc_irq_res) {
+		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
+		device_printf(dev, "cannot allocate interrupt\n");
+		return (ENXIO);
+	}
+
+	if (bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
+	    NULL, ti_adc_intr, sc, &sc->sc_intrhand) != 0) {
+		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res);
+		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
+		device_printf(dev, "Unable to setup the irq handler.\n");
+		return (ENXIO);
+	}
+
+	/* Activate the ADC_TSC module. */
+	err = ti_prcm_clk_enable(TSC_ADC_CLK);
+	if (err)
+		return (err);
+
+	/* Check the ADC revision. */
+	rev = ADC_READ4(sc, ADC_REVISION);
+	device_printf(dev,
+	    "scheme: %#x func: %#x rtl: %d rev: %d.%d custom rev: %d\n",
+	    (rev & ADC_REV_SCHEME_MSK) >> ADC_REV_SCHEME_SHIFT,
+	    (rev & ADC_REV_FUNC_MSK) >> ADC_REV_FUNC_SHIFT,
+	    (rev & ADC_REV_RTL_MSK) >> ADC_REV_RTL_SHIFT,
+	    (rev & ADC_REV_MAJOR_MSK) >> ADC_REV_MAJOR_SHIFT,
+	    rev & ADC_REV_MINOR_MSK,
+	    (rev & ADC_REV_CUSTOM_MSK) >> ADC_REV_CUSTOM_SHIFT);
+
+	/*
+	 * Disable the step write protect and make it store the step ID for
+	 * the captured data on FIFO.
+	 */
+	reg = ADC_READ4(sc, ADC_CTRL);
+	ADC_WRITE4(sc, ADC_CTRL, reg | ADC_CTRL_STEP_WP | ADC_CTRL_STEP_ID);
+
+	/*
+	 * Set the ADC prescaler to 2400 (yes, the actual value written here
+	 * is 2400 - 1).
+	 * This sets the ADC clock to ~10Khz (CLK_M_OSC / 2400).
+	 */
+	ADC_WRITE4(sc, ADC_CLKDIV, 2399);
+
+	TI_ADC_LOCK_INIT(sc);
+
+	ti_adc_idlestep_init(sc);
+	ti_adc_inputs_init(sc);
+	ti_adc_sysctl_init(sc);
+
+	return (0);
+}
+
+static int
+ti_adc_detach(device_t dev)
+{
+	struct ti_adc_softc *sc;
+
+	sc = device_get_softc(dev);
+
+	/* Turn off the ADC. */
+	TI_ADC_LOCK(sc);
+	ti_adc_reset(sc);
+	ti_adc_setup(sc);
+	TI_ADC_UNLOCK(sc);
+
+	TI_ADC_LOCK_DESTROY(sc);
+
+	if (sc->sc_intrhand)
+		bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_intrhand);
+	if (sc->sc_irq_res)
+		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res);
+	if (sc->sc_mem_res)
+		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
+
+	return (bus_generic_detach(dev));
+}
+
+static device_method_t ti_adc_methods[] = {
+	DEVMETHOD(device_probe,		ti_adc_probe),
+	DEVMETHOD(device_attach,	ti_adc_attach),
+	DEVMETHOD(device_detach,	ti_adc_detach),
+
+	DEVMETHOD_END
+};
+
+static driver_t ti_adc_driver = {
+	"ti_adc",
+	ti_adc_methods,
+	sizeof(struct ti_adc_softc),
+};
+
+static devclass_t ti_adc_devclass;
+
+DRIVER_MODULE(ti_adc, simplebus, ti_adc_driver, ti_adc_devclass, 0, 0);
+MODULE_VERSION(ti_adc, 1);
+MODULE_DEPEND(ti_adc, simplebus, 1, 1, 1);


Property changes on: trunk/sys/arm/ti/ti_adc.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/ti_adcreg.h
===================================================================
--- trunk/sys/arm/ti/ti_adcreg.h	                        (rev 0)
+++ trunk/sys/arm/ti/ti_adcreg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,121 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright 2014 Luiz Otavio O Souza <loos at freebsd.org>
+ * 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: stable/10/sys/arm/ti/ti_adcreg.h 270238 2014-08-20 18:10:12Z loos $
+ */
+
+#ifndef _TI_ADCREG_H_
+#define _TI_ADCREG_H_
+
+#define	ADC_REVISION		0x000
+#define	ADC_REV_SCHEME_MSK		0xc0000000
+#define	ADC_REV_SCHEME_SHIFT		30
+#define	ADC_REV_FUNC_MSK		0x0fff0000
+#define	ADC_REV_FUNC_SHIFT		16
+#define	ADC_REV_RTL_MSK			0x0000f800
+#define	ADC_REV_RTL_SHIFT		11
+#define	ADC_REV_MAJOR_MSK		0x00000700
+#define	ADC_REV_MAJOR_SHIFT		8
+#define	ADC_REV_CUSTOM_MSK		0x000000c0
+#define	ADC_REV_CUSTOM_SHIFT		6
+#define	ADC_REV_MINOR_MSK		0x0000003f
+#define	ADC_SYSCFG		0x010
+#define	ADC_SYSCFG_IDLE_MSK		0x000000c0
+#define	ADC_SYSCFG_IDLE_SHIFT		2
+#define	ADC_IRQSTATUS_RAW	0x024
+#define	ADC_IRQSTATUS		0x028
+#define	ADC_IRQENABLE_SET	0x02c
+#define	ADC_IRQENABLE_CLR	0x030
+#define	ADC_IRQ_HW_PEN_SYNC		(1 << 10)
+#define	ADC_IRQ_PEN_UP			(1 << 9)
+#define	ADC_IRQ_OUT_RANGE		(1 << 8)
+#define	ADC_IRQ_FIFO1_UNDR		(1 << 7)
+#define	ADC_IRQ_FIFO1_OVERR		(1 << 6)
+#define	ADC_IRQ_FIFO1_THRES		(1 << 5)
+#define	ADC_IRQ_FIFO0_UNDR		(1 << 4)
+#define	ADC_IRQ_FIFO0_OVERR		(1 << 3)
+#define	ADC_IRQ_FIFO0_THRES		(1 << 2)
+#define	ADC_IRQ_END_OF_SEQ		(1 << 1)
+#define	ADC_IRQ_HW_PEN_ASYNC		(1 << 0)
+#define	ADC_CTRL		0x040
+#define	ADC_CTRL_STEP_WP		(1 << 2)
+#define	ADC_CTRL_STEP_ID		(1 << 1)
+#define	ADC_CTRL_ENABLE			(1 << 0)
+#define	ADC_STAT		0x044
+#define	ADC_CLKDIV		0x04c
+#define	ADC_STEPENABLE		0x054
+#define	ADC_IDLECONFIG		0x058
+#define	ADC_STEPCFG1		0x064
+#define	ADC_STEPDLY1		0x068
+#define	ADC_STEPCFG2		0x06c
+#define	ADC_STEPDLY2		0x070
+#define	ADC_STEPCFG3		0x074
+#define	ADC_STEPDLY3		0x078
+#define	ADC_STEPCFG4		0x07c
+#define	ADC_STEPDLY4		0x080
+#define	ADC_STEPCFG5		0x084
+#define	ADC_STEPDLY5		0x088
+#define	ADC_STEPCFG6		0x08c
+#define	ADC_STEPDLY6		0x090
+#define	ADC_STEPCFG7		0x094
+#define	ADC_STEPDLY7		0x098
+#define	ADC_STEPCFG8		0x09c
+#define	ADC_STEPDLY8		0x0a0
+#define	ADC_STEP_DIFF_CNTRL		(1 << 25)
+#define	ADC_STEP_RFM_MSK		0x01800000
+#define	ADC_STEP_RFM_SHIFT		23
+#define	ADC_STEP_RFM_VSSA		0
+#define	ADC_STEP_RFM_XNUR		1
+#define	ADC_STEP_RFM_YNLR		2
+#define	ADC_STEP_RFM_VREFN		3
+#define	ADC_STEP_INP_MSK		0x00780000
+#define	ADC_STEP_INP_SHIFT		19
+#define	ADC_STEP_INM_MSK		0x00078000
+#define	ADC_STEP_INM_SHIFT		15
+#define	ADC_STEP_IN_VREFN		8
+#define	ADC_STEP_RFP_MSK		0x00007000
+#define	ADC_STEP_RFP_SHIFT		12
+#define	ADC_STEP_RFP_VDDA		0
+#define	ADC_STEP_RFP_XPUL		1
+#define	ADC_STEP_RFP_YPLL		2
+#define	ADC_STEP_RFP_VREFP		3
+#define	ADC_STEP_RFP_INTREF		4
+#define	ADC_STEP_AVG_MSK		0x0000001c
+#define	ADC_STEP_AVG_SHIFT		2
+#define	ADC_STEP_MODE_MSK		0x00000003
+#define	ADC_STEP_MODE_ONESHOT		0x00000000
+#define	ADC_STEP_MODE_CONTINUOUS	0x00000001
+#define	ADC_STEP_SAMPLE_DELAY		0xff000000
+#define	ADC_STEP_OPEN_DELAY		0x0003ffff
+#define	ADC_FIFO0COUNT		0x0e4
+#define	ADC_FIFO0THRESHOLD	0x0e8
+#define	ADC_FIFO0DATA		0x100
+#define	ADC_FIFO_COUNT_MSK		0x0000007f
+#define	ADC_FIFO_STEP_ID_MSK		0x000f0000
+#define	ADC_FIFO_STEP_ID_SHIFT		16
+#define	ADC_FIFO_DATA_MSK		0x00000fff
+
+#endif /* _TI_ADCREG_H_ */


Property changes on: trunk/sys/arm/ti/ti_adcreg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/ti_adcvar.h
===================================================================
--- trunk/sys/arm/ti/ti_adcvar.h	                        (rev 0)
+++ trunk/sys/arm/ti/ti_adcvar.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,70 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright 2014 Luiz Otavio O Souza <loos at freebsd.org>
+ * 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: stable/10/sys/arm/ti/ti_adcvar.h 270238 2014-08-20 18:10:12Z loos $
+ */
+
+#ifndef _TI_ADCVAR_H_
+#define _TI_ADCVAR_H_
+
+#define	TI_ADC_NPINS	8
+
+#define	ADC_READ4(_sc, reg)	bus_read_4((_sc)->sc_mem_res, reg)
+#define	ADC_WRITE4(_sc, reg, value)	\
+	bus_write_4((_sc)->sc_mem_res, reg, value)
+
+struct ti_adc_softc {
+	device_t		sc_dev;
+	int			sc_last_state;
+	struct mtx		sc_mtx;
+	struct resource		*sc_mem_res;
+	struct resource		*sc_irq_res;
+	void			*sc_intrhand;
+};
+
+struct ti_adc_input {
+	int32_t			enable;		/* input enabled */
+	int32_t			samples;	/* samples average */
+	int32_t			input;		/* input number */
+	int32_t			value;		/* raw converted value */
+	uint32_t		stepconfig;	/* step config register */
+	uint32_t		stepdelay;	/* step delay register */
+	struct ti_adc_softc	*sc;		/* pointer to adc softc */
+};
+
+#define	TI_ADC_LOCK(_sc)		\
+	mtx_lock(&(_sc)->sc_mtx)
+#define	TI_ADC_UNLOCK(_sc)		\
+	mtx_unlock(&(_sc)->sc_mtx)
+#define	TI_ADC_LOCK_INIT(_sc)	\
+	mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->sc_dev), \
+	    "ti_adc", MTX_DEF)
+#define	TI_ADC_LOCK_DESTROY(_sc)	\
+	mtx_destroy(&_sc->sc_mtx);
+#define	TI_ADC_LOCK_ASSERT(_sc)	\
+	mtx_assert(&(_sc)->sc_mtx, MA_OWNED)
+
+#endif /* _TI_ADCVAR_H_ */


Property changes on: trunk/sys/arm/ti/ti_adcvar.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/ti_common.c
===================================================================
--- trunk/sys/arm/ti/ti_common.c	                        (rev 0)
+++ trunk/sys/arm/ti/ti_common.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,99 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (C) 2008-2011 MARVELL INTERNATIONAL LTD.
+ * All rights reserved.
+ *
+ * Developed by Semihalf.
+ *
+ * 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.
+ * 3. Neither the name of MARVELL nor the names of contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY 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 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_global.h"
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/ti/ti_common.c 266277 2014-05-17 00:53:12Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/kdb.h>
+#include <sys/reboot.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+#include <machine/vmparam.h>
+
+struct fdt_fixup_entry fdt_fixup_table[] = {
+	{ NULL, NULL }
+};
+
+#ifdef SOC_OMAP4
+static int
+fdt_gic_decode_ic(phandle_t node, pcell_t *intr, int *interrupt, int *trig,
+    int *pol)
+{
+
+	if (!fdt_is_compatible(node, "arm,gic"))
+		return (ENXIO);
+
+	*interrupt = fdt32_to_cpu(intr[0]);
+	*trig = INTR_TRIGGER_CONFORM;
+	*pol = INTR_POLARITY_CONFORM;
+
+	return (0);
+}
+#endif
+
+#ifdef SOC_TI_AM335X
+static int
+fdt_aintc_decode_ic(phandle_t node, pcell_t *intr, int *interrupt, int *trig,
+    int *pol)
+{
+
+	if (!fdt_is_compatible(node, "ti,aintc"))
+		return (ENXIO);
+
+	*interrupt = fdt32_to_cpu(intr[0]);
+	*trig = INTR_TRIGGER_CONFORM;
+	*pol = INTR_POLARITY_CONFORM;
+
+	return (0);
+}
+#endif
+
+fdt_pic_decode_t fdt_pic_table[] = {
+#ifdef SOC_OMAP4
+	&fdt_gic_decode_ic,
+#endif
+#ifdef SOC_TI_AM335X
+	&fdt_aintc_decode_ic,
+#endif
+	NULL
+};


Property changes on: trunk/sys/arm/ti/ti_common.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/ti_cpuid.c
===================================================================
--- trunk/sys/arm/ti/ti_cpuid.c	                        (rev 0)
+++ trunk/sys/arm/ti/ti_cpuid.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,331 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2011
+ *	Ben Gray <ben.r.gray at gmail.com>.
+ * 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 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 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: stable/10/sys/arm/ti/ti_cpuid.c 259329 2013-12-13 20:43:11Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+#include <machine/resource.h>
+#include <machine/intr.h>
+
+#include <arm/ti/tivar.h>
+#include <arm/ti/ti_cpuid.h>
+
+#include <arm/ti/omap4/omap4_reg.h>
+#include <arm/ti/omap3/omap3_reg.h>
+#include <arm/ti/am335x/am335x_reg.h>
+
+#define OMAP4_STD_FUSE_DIE_ID_0    0x2200
+#define OMAP4_ID_CODE              0x2204
+#define OMAP4_STD_FUSE_DIE_ID_1    0x2208
+#define OMAP4_STD_FUSE_DIE_ID_2    0x220C
+#define OMAP4_STD_FUSE_DIE_ID_3    0x2210
+#define OMAP4_STD_FUSE_PROD_ID_0   0x2214
+#define OMAP4_STD_FUSE_PROD_ID_1   0x2218
+
+#define OMAP3_ID_CODE              0xA204
+
+static uint32_t chip_revision = 0xffffffff;
+
+/**
+ *	ti_revision - Returns the revision number of the device
+ *
+ *	Simply returns an identifier for the revision of the chip we are running
+ *	on.
+ *
+ *	RETURNS
+ *	A 32-bit identifier for the current chip
+ */
+uint32_t
+ti_revision(void)
+{
+	return chip_revision;
+}
+
+/**
+ *	omap4_get_revision - determines omap4 revision
+ *
+ *	Reads the registers to determine the revision of the chip we are currently
+ *	running on.  Stores the information in global variables.
+ *
+ *
+ */
+static void
+omap4_get_revision(void)
+{
+	uint32_t id_code;
+	uint32_t revision;
+	uint32_t hawkeye;
+	bus_space_handle_t bsh;
+
+	/* The chip revsion is read from the device identification registers and
+	 * the JTAG (?) tap registers, which are located in address 0x4A00_2200 to
+	 * 0x4A00_2218.  This is part of the L4_CORE memory range and should have
+	 * been mapped in by the machdep.c code.
+	 *
+	 *   STD_FUSE_DIE_ID_0    0x4A00 2200
+	 *   ID_CODE              0x4A00 2204   (this is the only one we need)
+	 *   STD_FUSE_DIE_ID_1    0x4A00 2208
+	 *   STD_FUSE_DIE_ID_2    0x4A00 220C
+	 *   STD_FUSE_DIE_ID_3    0x4A00 2210
+	 *   STD_FUSE_PROD_ID_0   0x4A00 2214
+	 *   STD_FUSE_PROD_ID_1   0x4A00 2218
+	 */
+	/* FIXME Should we map somewhere else? */
+	bus_space_map(fdtbus_bs_tag,OMAP44XX_L4_CORE_HWBASE, 0x4000, 0, &bsh);
+	id_code = bus_space_read_4(fdtbus_bs_tag, bsh, OMAP4_ID_CODE);
+	bus_space_unmap(fdtbus_bs_tag, bsh, 0x4000);
+
+	hawkeye = ((id_code >> 12) & 0xffff);
+	revision = ((id_code >> 28) & 0xf);
+
+	/* Apparently according to the linux code there were some ES2.0 samples that
+	 * have the wrong id code and report themselves as ES1.0 silicon.  So used
+	 * the ARM cpuid to get the correct revision.
+	 */
+	if (revision == 0) {
+		id_code = cpufunc_id();
+		revision = (id_code & 0xf) - 1;
+	}
+
+	switch (hawkeye) {
+	case 0xB852:
+		switch (revision) {
+		case 0:
+			chip_revision = OMAP4430_REV_ES1_0;
+			break;
+		case 1:
+			chip_revision = OMAP4430_REV_ES2_1;
+			break;
+		default:
+			chip_revision = OMAP4430_REV_UNKNOWN;
+			break;
+		}
+		break;
+
+	case 0xB95C:
+		switch (revision) {
+		case 3:
+			chip_revision = OMAP4430_REV_ES2_1;
+			break;
+		case 4:
+			chip_revision = OMAP4430_REV_ES2_2;
+			break;
+		case 6:
+			chip_revision = OMAP4430_REV_ES2_3;
+			break;
+		default:
+			chip_revision = OMAP4430_REV_UNKNOWN;
+			break;
+		}
+		break;
+
+	case 0xB94E:
+		switch (revision) {
+		case 0:
+			chip_revision = OMAP4460_REV_ES1_0;
+			break;
+		case 2:
+			chip_revision = OMAP4460_REV_ES1_1;
+			break;
+		default:
+			chip_revision = OMAP4460_REV_UNKNOWN;
+			break;
+		}
+		break;
+
+	case 0xB975:
+		switch (revision) {
+		case 0:
+			chip_revision = OMAP4470_REV_ES1_0;
+			break;
+		default:
+			chip_revision = OMAP4470_REV_UNKNOWN;
+			break;
+		}
+		break;
+
+	default:
+		/* Default to the latest revision if we can't determine type */
+		chip_revision = OMAP_UNKNOWN_DEV;
+		break;
+	}
+	if (chip_revision != OMAP_UNKNOWN_DEV) {
+		printf("Texas Instruments OMAP%04x Processor, Revision ES%u.%u\n",
+		    OMAP_REV_DEVICE(chip_revision), OMAP_REV_MAJOR(chip_revision), 
+		    OMAP_REV_MINOR(chip_revision));
+	}
+	else {
+		printf("Texas Instruments unknown OMAP chip: %04x, rev %d\n",
+		    hawkeye, revision); 
+	}
+}
+
+/**
+ *	omap3_get_revision - determines omap3 revision
+ *
+ *	Reads the registers to determine the revision of the chip we are currently
+ *	running on.  Stores the information in global variables.
+ *
+ *	WARNING: This function currently only really works for OMAP3530 devices.
+ *
+ *
+ *
+ */
+static void
+omap3_get_revision(void)
+{
+	uint32_t id_code;
+	uint32_t revision;
+	uint32_t hawkeye;
+	bus_space_handle_t bsh;
+
+	/* The chip revsion is read from the device identification registers and
+	 * the JTAG (?) tap registers, which are located in address 0x4A00_2200 to
+	 * 0x4A00_2218.  This is part of the L4_CORE memory range and should have
+	 * been mapped in by the machdep.c code.
+	 *
+	 *   CONTROL_IDCODE       0x4830 A204   (this is the only one we need)
+	 *
+	 *
+	 */
+	bus_space_map(fdtbus_bs_tag, OMAP35XX_L4_WAKEUP_HWBASE, 0x10000, 0, &bsh);
+	id_code = bus_space_read_4(fdtbus_bs_tag, bsh, OMAP3_ID_CODE);
+	bus_space_unmap(fdtbus_bs_tag, bsh, 0x10000);
+
+	hawkeye = ((id_code >> 12) & 0xffff);
+	revision = ((id_code >> 28) & 0xf);
+
+	switch (hawkeye) {
+	case 0xB6D6:
+		chip_revision = OMAP3350_REV_ES1_0;
+		break;
+	case 0xB7AE:
+		if (revision == 1)
+			chip_revision = OMAP3530_REV_ES2_0;
+		else if (revision == 2)
+			chip_revision = OMAP3530_REV_ES2_1;
+		else if (revision == 3)
+			chip_revision = OMAP3530_REV_ES3_0;
+		else if (revision == 4)
+			chip_revision = OMAP3530_REV_ES3_1;
+		else if (revision == 7)
+			chip_revision = OMAP3530_REV_ES3_1_2;
+		break;
+	default:
+		/* Default to the latest revision if we can't determine type */
+		chip_revision = OMAP3530_REV_ES3_1_2;
+		break;
+	}
+	printf("Texas Instruments OMAP%04x Processor, Revision ES%u.%u\n",
+		OMAP_REV_DEVICE(chip_revision), OMAP_REV_MAJOR(chip_revision), 
+		OMAP_REV_MINOR(chip_revision));
+}
+
+static void
+am335x_get_revision(void)
+{
+	uint32_t dev_feature;
+	uint8_t cpu_last_char;
+	bus_space_handle_t bsh;
+
+	bus_space_map(fdtbus_bs_tag, AM335X_CONTROL_BASE, AM335X_CONTROL_SIZE, 0, &bsh);
+	chip_revision = bus_space_read_4(fdtbus_bs_tag, bsh, AM335X_CONTROL_DEVICE_ID);
+	dev_feature = bus_space_read_4(fdtbus_bs_tag, bsh, AM335X_CONTROL_DEV_FEATURE);
+	bus_space_unmap(fdtbus_bs_tag, bsh, AM335X_CONTROL_SIZE);
+
+	switch (dev_feature) {
+		case 0x00FF0382:
+			cpu_last_char='2';
+			break;
+		case 0x20FF0382:
+			cpu_last_char='4';
+			break;
+		case 0x00FF0383:
+			cpu_last_char='6';
+			break;
+		case 0x00FE0383:
+			cpu_last_char='7';
+			break;
+		case 0x20FF0383:
+			cpu_last_char='8';
+			break;
+		case 0x20FE0383:
+			cpu_last_char='9';
+			break;
+		default:
+			cpu_last_char='x';
+	}
+
+	printf("Texas Instruments AM335%c Processor, Revision ES1.%u\n",
+		cpu_last_char, AM335X_DEVREV(chip_revision));
+}
+
+/**
+ *	ti_cpu_ident - attempts to identify the chip we are running on
+ *	@dummy: ignored
+ *
+ *	This function is called before any of the driver are initialised, however
+ *	the basic virt to phys maps have been setup in machdep.c so we can still
+ *	access the required registers, we just have to use direct register reads
+ *	and writes rather than going through the bus stuff.
+ *
+ *
+ */
+static void
+ti_cpu_ident(void *dummy)
+{
+	switch(ti_chip()) {
+	case CHIP_OMAP_3:
+		omap3_get_revision();
+		break;
+	case CHIP_OMAP_4:
+		omap4_get_revision();
+		break;
+	case CHIP_AM335X:
+		am335x_get_revision();
+		break;
+	default:
+		panic("Unknown chip type, fixme!\n");
+	}
+}
+
+SYSINIT(ti_cpu_ident, SI_SUB_CPU, SI_ORDER_SECOND, ti_cpu_ident, NULL);


Property changes on: trunk/sys/arm/ti/ti_cpuid.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/ti_cpuid.h
===================================================================
--- trunk/sys/arm/ti/ti_cpuid.h	                        (rev 0)
+++ trunk/sys/arm/ti/ti_cpuid.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,90 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2011
+ *	Ben Gray <ben.r.gray at gmail.com>.
+ * 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 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 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: stable/10/sys/arm/ti/ti_cpuid.h 245137 2013-01-07 23:30:53Z gonzo $
+ */
+
+#ifndef _TI_CPUID_H_
+#define	_TI_CPUID_H_
+
+#define	OMAP_MAKEREV(d, a, b, c) \
+	(uint32_t)(((d) << 16) | (((a) & 0xf) << 8) | (((b) & 0xf) << 4) | ((c) & 0xf))
+
+#define	OMAP_REV_DEVICE(x)	(((x) >> 16) & 0xffff)
+#define	OMAP_REV_MAJOR(x)	(((x) >> 8) & 0xf)
+#define	OMAP_REV_MINOR(x)	(((x) >> 4) & 0xf)
+#define	OMAP_REV_MINOR_MINOR(x)	(((x) >> 0) & 0xf)
+
+#define	OMAP3350_DEV		0x3530
+#define	OMAP3350_REV_ES1_0	OMAP_MAKEREV(OMAP3350_DEV, 1, 0, 0)
+#define	OMAP3530_REV_ES2_0	OMAP_MAKEREV(OMAP3350_DEV, 2, 0, 0)
+#define	OMAP3530_REV_ES2_1	OMAP_MAKEREV(OMAP3350_DEV, 2, 1, 0)
+#define	OMAP3530_REV_ES3_0	OMAP_MAKEREV(OMAP3350_DEV, 3, 0, 0)
+#define	OMAP3530_REV_ES3_1	OMAP_MAKEREV(OMAP3350_DEV, 3, 1, 0)
+#define	OMAP3530_REV_ES3_1_2	OMAP_MAKEREV(OMAP3350_DEV, 3, 1, 2)
+
+#define	OMAP4430_DEV		0x4430
+#define	OMAP4430_REV_ES1_0	OMAP_MAKEREV(OMAP4430_DEV, 1, 0, 0)
+#define	OMAP4430_REV_ES2_0	OMAP_MAKEREV(OMAP4430_DEV, 2, 0, 0)
+#define	OMAP4430_REV_ES2_1	OMAP_MAKEREV(OMAP4430_DEV, 2, 1, 0)
+#define	OMAP4430_REV_ES2_2	OMAP_MAKEREV(OMAP4430_DEV, 2, 2, 0)
+#define	OMAP4430_REV_ES2_3	OMAP_MAKEREV(OMAP4430_DEV, 2, 3, 0)
+#define	OMAP4430_REV_UNKNOWN	OMAP_MAKEREV(OMAP4430_DEV, 9, 9, 9)
+
+#define	OMAP4460_DEV		0x4460
+#define	OMAP4460_REV_ES1_0	OMAP_MAKEREV(OMAP4460_DEV, 1, 0, 0)
+#define	OMAP4460_REV_ES1_1	OMAP_MAKEREV(OMAP4460_DEV, 1, 1, 0)
+#define	OMAP4460_REV_UNKNOWN	OMAP_MAKEREV(OMAP4460_DEV, 9, 9, 9)
+
+#define	OMAP4470_DEV		0x4470
+#define	OMAP4470_REV_ES1_0	OMAP_MAKEREV(OMAP4470_DEV, 1, 0, 0)
+#define	OMAP4470_REV_UNKNOWN	OMAP_MAKEREV(OMAP4470_DEV, 9, 9, 9)
+
+#define	OMAP_UNKNOWN_DEV	OMAP_MAKEREV(0x9999, 9, 9, 9)
+
+#define	AM335X_DEVREV(x)	((x) >> 28)
+
+#define	CHIP_OMAP_3	0
+#define	CHIP_OMAP_4	1
+#define	CHIP_AM335X	2
+
+static __inline int ti_chip(void)
+{
+#if defined(SOC_OMAP4)
+	return CHIP_OMAP_4;
+#elif defined(SOC_OMAP3)
+	return CHIP_OMAP_3;
+#elif defined(SOC_TI_AM335X)
+	return CHIP_AM335X;
+#else
+#  error Chip type not defined, ensure SOC_xxxx is defined
+#endif
+}
+
+uint32_t ti_revision(void);
+
+#endif  /* _TI_CPUID_H_ */


Property changes on: trunk/sys/arm/ti/ti_cpuid.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/ti_edma3.c
===================================================================
--- trunk/sys/arm/ti/ti_edma3.c	                        (rev 0)
+++ trunk/sys/arm/ti/ti_edma3.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,429 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (c) 2012 Damjan Marion <dmarion at Freebsd.org>
+ * 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.
+ * 3. Neither the name of authors nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * 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: stable/10/sys/arm/ti/ti_edma3.c 266152 2014-05-15 16:11:06Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/endian.h>
+#include <sys/mbuf.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/socket.h>
+#include <sys/sysctl.h>
+
+#include <sys/sockio.h>
+#include <sys/bus.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
+#include <machine/resource.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <arm/ti/ti_scm.h>
+#include <arm/ti/ti_prcm.h>
+
+#include <arm/ti/ti_edma3.h>
+
+#define TI_EDMA3_NUM_TCS		3
+#define TI_EDMA3_NUM_IRQS		3
+#define TI_EDMA3_NUM_DMA_CHS		64
+#define TI_EDMA3_NUM_QDMA_CHS		8
+
+#define TI_EDMA3CC_PID			0x000
+#define TI_EDMA3CC_DCHMAP(p)		(0x100 + ((p)*4))
+#define TI_EDMA3CC_DMAQNUM(n)		(0x240 + ((n)*4))
+#define TI_EDMA3CC_QDMAQNUM		0x260
+#define TI_EDMA3CC_EMCR			0x308
+#define TI_EDMA3CC_EMCRH		0x30C
+#define TI_EDMA3CC_QEMCR		0x314
+#define TI_EDMA3CC_CCERR		0x318
+#define TI_EDMA3CC_CCERRCLR		0x31C
+#define TI_EDMA3CC_DRAE(p)		(0x340 + ((p)*8))
+#define TI_EDMA3CC_DRAEH(p)		(0x344 + ((p)*8))
+#define TI_EDMA3CC_QRAE(p)		(0x380 + ((p)*4))
+#define TI_EDMA3CC_S_ESR(p)		(0x2010 + ((p)*0x200))
+#define TI_EDMA3CC_S_ESRH(p)		(0x2014 + ((p)*0x200))
+#define TI_EDMA3CC_S_SECR(p)		(0x2040 + ((p)*0x200))
+#define TI_EDMA3CC_S_SECRH(p)		(0x2044 + ((p)*0x200))
+#define TI_EDMA3CC_S_EESR(p)		(0x2030 + ((p)*0x200))
+#define TI_EDMA3CC_S_EESRH(p)		(0x2034 + ((p)*0x200))
+#define TI_EDMA3CC_S_IESR(p)		(0x2060 + ((p)*0x200))
+#define TI_EDMA3CC_S_IESRH(p)		(0x2064 + ((p)*0x200))
+#define TI_EDMA3CC_S_IPR(p)		(0x2068 + ((p)*0x200))
+#define TI_EDMA3CC_S_IPRH(p)		(0x206C + ((p)*0x200))
+#define TI_EDMA3CC_S_QEESR(p)		(0x208C + ((p)*0x200))
+
+#define TI_EDMA3CC_PARAM_OFFSET		0x4000
+#define TI_EDMA3CC_OPT(p)		(TI_EDMA3CC_PARAM_OFFSET + 0x0 + ((p)*0x20))
+
+#define TI_EDMA3CC_DMAQNUM_SET(c,q)	((0x7 & (q)) << (((c) % 8) * 4))
+#define TI_EDMA3CC_DMAQNUM_CLR(c)	(~(0x7 << (((c) % 8) * 4)))
+#define TI_EDMA3CC_QDMAQNUM_SET(c,q)	((0x7 & (q)) << ((c) * 4))
+#define TI_EDMA3CC_QDMAQNUM_CLR(c)	(~(0x7 << ((c) * 4)))
+
+#define TI_EDMA3CC_OPT_TCC_CLR		(~(0x3F000))
+#define TI_EDMA3CC_OPT_TCC_SET(p)	(((0x3F000 >> 12) & (p)) << 12)
+
+struct ti_edma3_softc {
+	device_t		sc_dev;
+	struct resource *	mem_res[TI_EDMA3_NUM_TCS+1];
+	struct resource *	irq_res[TI_EDMA3_NUM_IRQS];
+	void			*ih_cookie[TI_EDMA3_NUM_IRQS];
+};
+
+static struct ti_edma3_softc *ti_edma3_sc = NULL;
+
+static struct resource_spec ti_edma3_mem_spec[] = {
+	{ SYS_RES_MEMORY,   0,  RF_ACTIVE },
+	{ SYS_RES_MEMORY,   1,  RF_ACTIVE },
+	{ SYS_RES_MEMORY,   2,  RF_ACTIVE },
+	{ SYS_RES_MEMORY,   3,  RF_ACTIVE },
+	{ -1,               0,  0 }
+};
+static struct resource_spec ti_edma3_irq_spec[] = {
+	{ SYS_RES_IRQ,      0,  RF_ACTIVE },
+	{ SYS_RES_IRQ,      1,  RF_ACTIVE },
+	{ SYS_RES_IRQ,      2,  RF_ACTIVE },
+	{ -1,               0,  0 }
+};
+
+/* Read/Write macros */
+#define ti_edma3_cc_rd_4(reg)		bus_read_4(ti_edma3_sc->mem_res[0], reg)
+#define ti_edma3_cc_wr_4(reg, val)	bus_write_4(ti_edma3_sc->mem_res[0], reg, val)
+#define ti_edma3_tc_rd_4(c, reg)	bus_read_4(ti_edma3_sc->mem_res[c+1], reg)
+#define ti_edma3_tc_wr_4(c, reg, val)	bus_write_4(ti_edma3_sc->mem_res[c+1], reg, val)
+
+static void ti_edma3_intr_comp(void *arg);
+static void ti_edma3_intr_mperr(void *arg);
+static void ti_edma3_intr_err(void *arg);
+
+static struct {
+	driver_intr_t *handler;
+	char * description;
+} ti_edma3_intrs[TI_EDMA3_NUM_IRQS] = {
+	{ ti_edma3_intr_comp,	"EDMA Completion Interrupt" },
+	{ ti_edma3_intr_mperr,	"EDMA Memory Protection Error Interrupt" },
+	{ ti_edma3_intr_err,	"EDMA Error Interrupt" },
+};
+
+static int
+ti_edma3_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "ti,edma3"))
+		return (ENXIO);
+
+	device_set_desc(dev, "TI EDMA Controller");
+	return (0);
+}
+
+static int
+ti_edma3_attach(device_t dev)
+{
+	struct ti_edma3_softc *sc = device_get_softc(dev);
+	uint32_t reg;
+	int err;
+	int i;
+
+	if (ti_edma3_sc)
+		return (ENXIO);
+
+	ti_edma3_sc = sc;
+	sc->sc_dev = dev;
+
+	/* Request the memory resources */
+	err = bus_alloc_resources(dev, ti_edma3_mem_spec, sc->mem_res);
+	if (err) {
+		device_printf(dev, "Error: could not allocate mem resources\n");
+		return (ENXIO);
+	}
+
+	/* Request the IRQ resources */
+	err = bus_alloc_resources(dev, ti_edma3_irq_spec, sc->irq_res);
+	if (err) {
+		device_printf(dev, "Error: could not allocate irq resources\n");
+		return (ENXIO);
+	}
+
+	/* Enable Channel Controller */
+	ti_prcm_clk_enable(EDMA_TPCC_CLK);
+
+	reg = ti_edma3_cc_rd_4(TI_EDMA3CC_PID);
+
+	device_printf(dev, "EDMA revision %08x\n", reg);
+
+
+	/* Attach interrupt handlers */
+	for (i = 0; i < TI_EDMA3_NUM_IRQS; ++i) {
+		err = bus_setup_intr(dev, sc->irq_res[i], INTR_TYPE_MISC |
+		    INTR_MPSAFE, NULL, *ti_edma3_intrs[i].handler,
+		    sc, &sc->ih_cookie[i]);
+		if (err) {
+			device_printf(dev, "could not setup %s\n",
+			    ti_edma3_intrs[i].description);
+			return (err);
+		}
+	}
+
+	return (0);
+}
+
+static device_method_t ti_edma3_methods[] = {
+	DEVMETHOD(device_probe, ti_edma3_probe),
+	DEVMETHOD(device_attach, ti_edma3_attach),
+	{0, 0},
+};
+
+static driver_t ti_edma3_driver = {
+	"ti_edma3",
+	ti_edma3_methods,
+	sizeof(struct ti_edma3_softc),
+};
+static devclass_t ti_edma3_devclass;
+
+DRIVER_MODULE(ti_edma3, simplebus, ti_edma3_driver, ti_edma3_devclass, 0, 0);
+MODULE_DEPEND(ti_edma3, ti_prcm, 1, 1, 1);
+
+static void
+ti_edma3_intr_comp(void *arg)
+{
+	printf("%s: unimplemented\n", __func__);
+}
+
+static void
+ti_edma3_intr_mperr(void *arg)
+{
+	printf("%s: unimplemented\n", __func__);
+}
+
+static void
+ti_edma3_intr_err(void *arg)
+{
+	printf("%s: unimplemented\n", __func__);
+}
+
+void
+ti_edma3_init(unsigned int eqn)
+{
+	uint32_t reg;
+	int i;
+
+	/* on AM335x Event queue 0 is always mapped to Transfer Controller 0,
+	 * event queue 1 to TC2, etc. So we are asking PRCM to power on specific
+	 * TC based on what event queue we need to initialize */
+	ti_prcm_clk_enable(EDMA_TPTC0_CLK + eqn);
+
+	/* Clear Event Missed Regs */
+	ti_edma3_cc_wr_4(TI_EDMA3CC_EMCR, 0xFFFFFFFF);
+	ti_edma3_cc_wr_4(TI_EDMA3CC_EMCRH, 0xFFFFFFFF);
+	ti_edma3_cc_wr_4(TI_EDMA3CC_QEMCR, 0xFFFFFFFF);
+
+	/* Clear Error Reg */
+	ti_edma3_cc_wr_4(TI_EDMA3CC_CCERRCLR, 0xFFFFFFFF);
+
+	/* Enable DMA channels 0-63 */
+	ti_edma3_cc_wr_4(TI_EDMA3CC_DRAE(0), 0xFFFFFFFF);
+	ti_edma3_cc_wr_4(TI_EDMA3CC_DRAEH(0), 0xFFFFFFFF);
+
+	for (i = 0; i < 64; i++) {
+		ti_edma3_cc_wr_4(TI_EDMA3CC_DCHMAP(i), i<<5);
+	}
+
+	/* Initialize the DMA Queue Number Registers */
+	for (i = 0; i < TI_EDMA3_NUM_DMA_CHS; i++) {
+		reg = ti_edma3_cc_rd_4(TI_EDMA3CC_DMAQNUM(i>>3));
+		reg &= TI_EDMA3CC_DMAQNUM_CLR(i);
+		reg |= TI_EDMA3CC_DMAQNUM_SET(i, eqn);
+		ti_edma3_cc_wr_4(TI_EDMA3CC_DMAQNUM(i>>3), reg);
+	}
+
+	/* Enable the QDMA Region access for all channels */
+	ti_edma3_cc_wr_4(TI_EDMA3CC_QRAE(0), (1 << TI_EDMA3_NUM_QDMA_CHS) - 1);
+
+	/*Initialize QDMA Queue Number Registers */
+	for (i = 0; i < TI_EDMA3_NUM_QDMA_CHS; i++) {
+		reg = ti_edma3_cc_rd_4(TI_EDMA3CC_QDMAQNUM);
+		reg &= TI_EDMA3CC_QDMAQNUM_CLR(i);
+		reg |= TI_EDMA3CC_QDMAQNUM_SET(i, eqn);
+		ti_edma3_cc_wr_4(TI_EDMA3CC_QDMAQNUM, reg);
+	}
+}
+
+#ifdef notyet
+int
+ti_edma3_enable_event_intr(unsigned int ch)
+{
+	uint32_t reg;
+
+	if (ch >= TI_EDMA3_NUM_DMA_CHS)
+		return (EINVAL);
+
+	if (ch < 32) {
+		ti_edma3_cc_wr_4(TI_EDMA3CC_S_IESR(0), 1 << ch);
+	} else {
+		ti_edma3_cc_wr_4(TI_EDMA3CC_S_IESRH(0), 1 << (ch - 32));
+	}
+	return 0;
+}
+#endif
+
+int
+ti_edma3_request_dma_ch(unsigned int ch, unsigned int tccn, unsigned int eqn)
+{
+	uint32_t reg;
+
+	if (ch >= TI_EDMA3_NUM_DMA_CHS)
+		return (EINVAL);
+
+	/* Enable the DMA channel in the DRAE/DRAEH registers */
+	if (ch < 32) {
+		reg = ti_edma3_cc_rd_4(TI_EDMA3CC_DRAE(0));
+		reg |= (0x01 << ch);
+		ti_edma3_cc_wr_4(TI_EDMA3CC_DRAE(0), reg);
+	} else {
+		reg = ti_edma3_cc_rd_4(TI_EDMA3CC_DRAEH(0));
+		reg |= (0x01 << (ch - 32));
+		ti_edma3_cc_wr_4(TI_EDMA3CC_DRAEH(0), reg);
+	}
+
+	/* Associate DMA Channel to Event Queue */
+	reg = ti_edma3_cc_rd_4(TI_EDMA3CC_DMAQNUM(ch >> 3));
+	reg &= TI_EDMA3CC_DMAQNUM_CLR(ch);
+	reg |= TI_EDMA3CC_DMAQNUM_SET((ch), eqn);
+	ti_edma3_cc_wr_4(TI_EDMA3CC_DMAQNUM(ch >> 3), reg);
+
+	/* Set TCC in corresponding PaRAM Entry */
+	reg = ti_edma3_cc_rd_4(TI_EDMA3CC_OPT(ch));
+	reg &= TI_EDMA3CC_OPT_TCC_CLR;
+	reg |= TI_EDMA3CC_OPT_TCC_SET(ch);
+	ti_edma3_cc_wr_4(TI_EDMA3CC_OPT(ch), reg);
+
+	return 0;
+}
+
+int
+ti_edma3_request_qdma_ch(unsigned int ch, unsigned int tccn, unsigned int eqn)
+{
+	uint32_t reg;
+
+	if (ch >= TI_EDMA3_NUM_DMA_CHS)
+		return (EINVAL);
+
+	/* Enable the QDMA channel in the QRAE registers */
+	reg = ti_edma3_cc_rd_4(TI_EDMA3CC_QRAE(0));
+	reg |= (0x01 << ch);
+	ti_edma3_cc_wr_4(TI_EDMA3CC_QRAE(0), reg);
+
+	/* Associate QDMA Channel to Event Queue */
+	reg = ti_edma3_cc_rd_4(TI_EDMA3CC_QDMAQNUM);
+	reg |= TI_EDMA3CC_QDMAQNUM_SET(ch, eqn);
+	ti_edma3_cc_wr_4(TI_EDMA3CC_QDMAQNUM, reg);
+
+	/* Set TCC in corresponding PaRAM Entry */
+	reg = ti_edma3_cc_rd_4(TI_EDMA3CC_OPT(ch));
+	reg &= TI_EDMA3CC_OPT_TCC_CLR;
+	reg |= TI_EDMA3CC_OPT_TCC_SET(ch);
+	ti_edma3_cc_wr_4(TI_EDMA3CC_OPT(ch), reg);
+
+	return 0;
+}
+
+int
+ti_edma3_enable_transfer_manual(unsigned int ch)
+{
+	if (ch >= TI_EDMA3_NUM_DMA_CHS)
+		return (EINVAL);
+
+	/* set corresponding bit in ESR/ESRH to set a event */
+	if (ch < 32) {
+		ti_edma3_cc_wr_4(TI_EDMA3CC_S_ESR(0), 1 <<  ch);
+	} else {
+		ti_edma3_cc_wr_4(TI_EDMA3CC_S_ESRH(0), 1 <<  (ch - 32));
+	}
+
+	return 0;
+}
+
+int
+ti_edma3_enable_transfer_qdma(unsigned int ch)
+{
+	if (ch >= TI_EDMA3_NUM_QDMA_CHS)
+		return (EINVAL);
+
+	/* set corresponding bit in QEESR to enable QDMA event */
+	ti_edma3_cc_wr_4(TI_EDMA3CC_S_QEESR(0), (1 << ch));
+
+	return 0;
+}
+
+int
+ti_edma3_enable_transfer_event(unsigned int ch)
+{
+	if (ch >= TI_EDMA3_NUM_DMA_CHS)
+		return (EINVAL);
+
+	/* Clear SECR(H) & EMCR(H) to clean any previous NULL request
+	 * and set corresponding bit in EESR to enable DMA event */
+	if(ch < 32) {
+		ti_edma3_cc_wr_4(TI_EDMA3CC_S_SECR(0), (1 << ch));
+		ti_edma3_cc_wr_4(TI_EDMA3CC_EMCR, (1 << ch));
+		ti_edma3_cc_wr_4(TI_EDMA3CC_S_EESR(0), (1 << ch));
+	} else {
+		ti_edma3_cc_wr_4(TI_EDMA3CC_S_SECRH(0), 1 << (ch - 32));
+		ti_edma3_cc_wr_4(TI_EDMA3CC_EMCRH, 1 << (ch - 32));
+		ti_edma3_cc_wr_4(TI_EDMA3CC_S_EESRH(0), 1 << (ch - 32));
+	}
+
+	return 0;
+}
+
+void
+ti_edma3_param_write(unsigned int ch, struct ti_edma3cc_param_set *prs)
+{
+	bus_write_region_4(ti_edma3_sc->mem_res[0], TI_EDMA3CC_OPT(ch),
+	    (uint32_t *) prs, 8);
+}
+
+void
+ti_edma3_param_read(unsigned int ch, struct ti_edma3cc_param_set *prs)
+{
+	bus_read_region_4(ti_edma3_sc->mem_res[0], TI_EDMA3CC_OPT(ch),
+	    (uint32_t *) prs, 8);
+}


Property changes on: trunk/sys/arm/ti/ti_edma3.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/ti_edma3.h
===================================================================
--- trunk/sys/arm/ti/ti_edma3.h	                        (rev 0)
+++ trunk/sys/arm/ti/ti_edma3.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,82 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Damjan Marion <dmarion at Freebsd.org>
+ * 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: stable/10/sys/arm/ti/ti_edma3.h 239281 2012-08-15 06:31:32Z gonzo $
+ */
+
+#ifndef _TI_EDMA3_H_
+#define _TI_EDMA3_H_
+
+/* Direct Mapped EDMA3 Events */
+#define TI_EDMA3_EVENT_SDTXEVT1			2
+#define TI_EDMA3_EVENT_SDRXEVT1			3
+#define TI_EDMA3_EVENT_SDTXEVT0			24
+#define TI_EDMA3_EVENT_SDRXEVT0			25
+
+struct ti_edma3cc_param_set {
+	struct {
+		uint32_t sam:1;		/* Source address mode */
+		uint32_t dam:1;		/* Destination address mode */
+		uint32_t syncdim:1;	/* Transfer synchronization dimension */
+		uint32_t static_set:1;	/* Static Set */
+		uint32_t :4;
+		uint32_t fwid:3;	/* FIFO Width */
+		uint32_t tccmode:1;	/* Transfer complete code mode */
+		uint32_t tcc:6;		/* Transfer complete code */
+		uint32_t :2;
+		uint32_t tcinten:1;	/* Transfer complete interrupt enable */
+		uint32_t itcinten:1;	/* Intermediate xfer completion intr. ena */
+		uint32_t tcchen:1;	/* Transfer complete chaining enable */
+		uint32_t itcchen:1;	/* Intermediate xfer completion chaining ena */
+		uint32_t privid:4;	/* Privilege identification */
+		uint32_t :3;
+		uint32_t priv:1;	/* Privilege level */
+	} opt;
+	uint32_t src;			/* Channel Source Address */
+	uint16_t acnt;			/* Count for 1st Dimension */
+	uint16_t bcnt;			/* Count for 2nd Dimension */
+	uint32_t dst;			/* Channel Destination Address */
+	int16_t srcbidx;		/* Source B Index */
+	int16_t dstbidx;		/* Destination B Index */
+	uint16_t link;			/* Link Address */
+	uint16_t bcntrld;		/* BCNT Reload */
+	int16_t srccidx;		/* Source C Index */
+	int16_t dstcidx;		/* Destination C Index */
+	uint16_t ccnt;			/* Count for 3rd Dimension */
+	uint16_t reserved;		/* Reserved */
+};
+
+void ti_edma3_init(unsigned int eqn);
+int ti_edma3_request_dma_ch(unsigned int ch, unsigned int tccn, unsigned int eqn);
+int ti_edma3_request_qdma_ch(unsigned int ch, unsigned int tccn, unsigned int eqn);
+int ti_edma3_enable_transfer_manual(unsigned int ch);
+int ti_edma3_enable_transfer_qdma(unsigned int ch);
+int ti_edma3_enable_transfer_event(unsigned int ch);
+
+void ti_edma3_param_write(unsigned int ch, struct ti_edma3cc_param_set *prs);
+void ti_edma3_param_read(unsigned int ch, struct ti_edma3cc_param_set *prs);
+
+#endif /* _TI_EDMA3_H_ */


Property changes on: trunk/sys/arm/ti/ti_edma3.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/ti_gpio.c
===================================================================
--- trunk/sys/arm/ti/ti_gpio.c	                        (rev 0)
+++ trunk/sys/arm/ti/ti_gpio.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,897 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2011
+ *	Ben Gray <ben.r.gray at gmail.com>.
+ * 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 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 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.
+ */
+
+/**
+ *	Very simple GPIO (general purpose IO) driver module for TI OMAP SoC's.
+ *
+ *	Currently this driver only does the basics, get a value on a pin & set a
+ *	value on a pin. Hopefully over time I'll expand this to be a bit more generic
+ *	and support interrupts and other various bits on the SoC can do ... in the
+ *	meantime this is all you get.
+ *
+ *	Beware the OMA datasheet(s) lists GPIO banks 1-6, whereas I've used 0-5 here
+ *	in the code.
+ *
+ *
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/ti/ti_gpio.c 278786 2015-02-14 21:16:19Z loos $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/rman.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/gpio.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+
+#include <arm/ti/ti_scm.h>
+#include <arm/ti/ti_prcm.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include "gpio_if.h"
+
+/* Register definitions */
+#define	TI_GPIO_REVISION		0x0000
+#define	TI_GPIO_SYSCONFIG		0x0010
+#if defined(SOC_OMAP3)
+#define	TI_GPIO_SYSSTATUS		0x0014
+#define	TI_GPIO_IRQSTATUS1		0x0018
+#define	TI_GPIO_IRQENABLE1		0x001C
+#define	TI_GPIO_WAKEUPENABLE		0x0020
+#define	TI_GPIO_IRQSTATUS2		0x0028
+#define	TI_GPIO_IRQENABLE2		0x002C
+#define	TI_GPIO_CTRL			0x0030
+#define	TI_GPIO_OE			0x0034
+#define	TI_GPIO_DATAIN			0x0038
+#define	TI_GPIO_DATAOUT			0x003C
+#define	TI_GPIO_LEVELDETECT0		0x0040
+#define	TI_GPIO_LEVELDETECT1		0x0044
+#define	TI_GPIO_RISINGDETECT		0x0048
+#define	TI_GPIO_FALLINGDETECT		0x004C
+#define	TI_GPIO_DEBOUNCENABLE		0x0050
+#define	TI_GPIO_DEBOUNCINGTIME		0x0054
+#define	TI_GPIO_CLEARIRQENABLE1		0x0060
+#define	TI_GPIO_SETIRQENABLE1		0x0064
+#define	TI_GPIO_CLEARIRQENABLE2		0x0070
+#define	TI_GPIO_SETIRQENABLE2		0x0074
+#define	TI_GPIO_CLEARWKUENA		0x0080
+#define	TI_GPIO_SETWKUENA		0x0084
+#define	TI_GPIO_CLEARDATAOUT		0x0090
+#define	TI_GPIO_SETDATAOUT		0x0094
+#elif defined(SOC_OMAP4) || defined(SOC_TI_AM335X)
+#define	TI_GPIO_IRQSTATUS_RAW_0		0x0024
+#define	TI_GPIO_IRQSTATUS_RAW_1		0x0028
+#define	TI_GPIO_IRQSTATUS_0		0x002C
+#define	TI_GPIO_IRQSTATUS_1		0x0030
+#define	TI_GPIO_IRQSTATUS_SET_0		0x0034
+#define	TI_GPIO_IRQSTATUS_SET_1		0x0038
+#define	TI_GPIO_IRQSTATUS_CLR_0		0x003C
+#define	TI_GPIO_IRQSTATUS_CLR_1		0x0040
+#define	TI_GPIO_IRQWAKEN_0		0x0044
+#define	TI_GPIO_IRQWAKEN_1		0x0048
+#define	TI_GPIO_SYSSTATUS		0x0114
+#define	TI_GPIO_IRQSTATUS1		0x0118
+#define	TI_GPIO_IRQENABLE1		0x011C
+#define	TI_GPIO_WAKEUPENABLE		0x0120
+#define	TI_GPIO_IRQSTATUS2		0x0128
+#define	TI_GPIO_IRQENABLE2		0x012C
+#define	TI_GPIO_CTRL			0x0130
+#define	TI_GPIO_OE			0x0134
+#define	TI_GPIO_DATAIN			0x0138
+#define	TI_GPIO_DATAOUT			0x013C
+#define	TI_GPIO_LEVELDETECT0		0x0140
+#define	TI_GPIO_LEVELDETECT1		0x0144
+#define	TI_GPIO_RISINGDETECT		0x0148
+#define	TI_GPIO_FALLINGDETECT		0x014C
+#define	TI_GPIO_DEBOUNCENABLE		0x0150
+#define	TI_GPIO_DEBOUNCINGTIME		0x0154
+#define	TI_GPIO_CLEARWKUPENA		0x0180
+#define	TI_GPIO_SETWKUENA		0x0184
+#define	TI_GPIO_CLEARDATAOUT		0x0190
+#define	TI_GPIO_SETDATAOUT		0x0194
+#else
+#error "Unknown SoC"
+#endif
+
+/* Other SoC Specific definitions */
+#if defined(SOC_OMAP3)
+#define	MAX_GPIO_BANKS			6
+#define	FIRST_GPIO_BANK			1
+#define	INTR_PER_BANK			1
+#define	TI_GPIO_REV			0x00000025
+#elif defined(SOC_OMAP4)
+#define	MAX_GPIO_BANKS			6
+#define	FIRST_GPIO_BANK			1
+#define	INTR_PER_BANK			1
+#define	TI_GPIO_REV			0x50600801
+#elif defined(SOC_TI_AM335X)
+#define	MAX_GPIO_BANKS			4
+#define	FIRST_GPIO_BANK			0
+#define	INTR_PER_BANK			2
+#define	TI_GPIO_REV			0x50600801
+#endif
+#define	PINS_PER_BANK			32
+#define	MAX_GPIO_INTRS			MAX_GPIO_BANKS * INTR_PER_BANK
+
+/**
+ *	ti_gpio_mem_spec - Resource specification used when allocating resources
+ *	ti_gpio_irq_spec - Resource specification used when allocating resources
+ *
+ *	This driver module can have up to six independent memory regions, each
+ *	region typically controls 32 GPIO pins.
+ *
+ *	On OMAP3 and OMAP4 there is only one physical interrupt line per bank,
+ *	but there are two set of registers which control the interrupt delivery
+ *	to internal subsystems.  The first set of registers control the
+ *	interrupts delivery to the MPU and the second set control the
+ *	interrupts delivery to the DSP.
+ *
+ *	On AM335x there are two physical interrupt lines for each GPIO module.
+ *	Each interrupt line is controlled by a set of registers.
+ */
+static struct resource_spec ti_gpio_mem_spec[] = {
+	{ SYS_RES_MEMORY,   0,  RF_ACTIVE },
+	{ SYS_RES_MEMORY,   1,  RF_ACTIVE | RF_OPTIONAL },
+	{ SYS_RES_MEMORY,   2,  RF_ACTIVE | RF_OPTIONAL },
+	{ SYS_RES_MEMORY,   3,  RF_ACTIVE | RF_OPTIONAL },
+#if !defined(SOC_TI_AM335X)
+	{ SYS_RES_MEMORY,   4,  RF_ACTIVE | RF_OPTIONAL },
+	{ SYS_RES_MEMORY,   5,  RF_ACTIVE | RF_OPTIONAL },
+#endif
+	{ -1,               0,  0 }
+};
+static struct resource_spec ti_gpio_irq_spec[] = {
+	{ SYS_RES_IRQ,      0,  RF_ACTIVE },
+	{ SYS_RES_IRQ,      1,  RF_ACTIVE | RF_OPTIONAL },
+	{ SYS_RES_IRQ,      2,  RF_ACTIVE | RF_OPTIONAL },
+	{ SYS_RES_IRQ,      3,  RF_ACTIVE | RF_OPTIONAL },
+	{ SYS_RES_IRQ,      4,  RF_ACTIVE | RF_OPTIONAL },
+	{ SYS_RES_IRQ,      5,  RF_ACTIVE | RF_OPTIONAL },
+#if defined(SOC_TI_AM335X)
+	{ SYS_RES_IRQ,      6,  RF_ACTIVE | RF_OPTIONAL },
+	{ SYS_RES_IRQ,      7,  RF_ACTIVE | RF_OPTIONAL },
+#endif
+	{ -1,               0,  0 }
+};
+
+/**
+ *	Structure that stores the driver context.
+ *
+ *	This structure is allocated during driver attach.
+ */
+struct ti_gpio_softc {
+	device_t		sc_dev;
+
+	/*
+	 * The memory resource(s) for the PRCM register set, when the device is
+	 * created the caller can assign up to 6 memory regions depending on
+	 * the SoC type.
+	 */
+	struct resource		*sc_mem_res[MAX_GPIO_BANKS];
+	struct resource		*sc_irq_res[MAX_GPIO_INTRS];
+
+	/* The handle for the register IRQ handlers. */
+	void			*sc_irq_hdl[MAX_GPIO_INTRS];
+
+	/*
+	 * The following describes the H/W revision of each of the GPIO banks.
+	 */
+	uint32_t		sc_revision[MAX_GPIO_BANKS];
+
+	struct mtx		sc_mtx;
+};
+
+/**
+ *	Macros for driver mutex locking
+ */
+#define	TI_GPIO_LOCK(_sc)		mtx_lock(&(_sc)->sc_mtx)
+#define	TI_GPIO_UNLOCK(_sc)		mtx_unlock(&(_sc)->sc_mtx)
+#define	TI_GPIO_LOCK_INIT(_sc)		\
+	mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->sc_dev), \
+	    "ti_gpio", MTX_DEF)
+#define	TI_GPIO_LOCK_DESTROY(_sc)	mtx_destroy(&_sc->sc_mtx)
+#define	TI_GPIO_ASSERT_LOCKED(_sc)	mtx_assert(&_sc->sc_mtx, MA_OWNED)
+#define	TI_GPIO_ASSERT_UNLOCKED(_sc)	mtx_assert(&_sc->sc_mtx, MA_NOTOWNED)
+
+/**
+ *	ti_gpio_read_4 - reads a 16-bit value from one of the PADCONFS registers
+ *	@sc: GPIO device context
+ *	@bank: The bank to read from
+ *	@off: The offset of a register from the GPIO register address range
+ *
+ *
+ *	RETURNS:
+ *	32-bit value read from the register.
+ */
+static inline uint32_t
+ti_gpio_read_4(struct ti_gpio_softc *sc, unsigned int bank, bus_size_t off)
+{
+	return (bus_read_4(sc->sc_mem_res[bank], off));
+}
+
+/**
+ *	ti_gpio_write_4 - writes a 32-bit value to one of the PADCONFS registers
+ *	@sc: GPIO device context
+ *	@bank: The bank to write to
+ *	@off: The offset of a register from the GPIO register address range
+ *	@val: The value to write into the register
+ *
+ *	RETURNS:
+ *	nothing
+ */
+static inline void
+ti_gpio_write_4(struct ti_gpio_softc *sc, unsigned int bank, bus_size_t off,
+                 uint32_t val)
+{
+	bus_write_4(sc->sc_mem_res[bank], off, val);
+}
+
+static inline void
+ti_gpio_intr_clr(struct ti_gpio_softc *sc, unsigned int bank, uint32_t mask)
+{
+
+	/* We clear both set of registers. */
+#if defined(SOC_OMAP4) || defined(SOC_TI_AM335X)
+	ti_gpio_write_4(sc, bank, TI_GPIO_IRQSTATUS_CLR_0, mask);
+	ti_gpio_write_4(sc, bank, TI_GPIO_IRQSTATUS_CLR_1, mask);
+#else
+	ti_gpio_write_4(sc, bank, TI_GPIO_CLEARIRQENABLE1, mask);
+	ti_gpio_write_4(sc, bank, TI_GPIO_CLEARIRQENABLE2, mask);
+#endif
+}
+
+/**
+ *	ti_gpio_pin_max - Returns the maximum number of GPIO pins
+ *	@dev: gpio device handle
+ *	@maxpin: pointer to a value that upon return will contain the maximum number
+ *	         of pins in the device.
+ *
+ *
+ *	LOCKING:
+ *	Internally locks the context
+ *
+ *	RETURNS:
+ *	Returns 0 on success otherwise an error code
+ */
+static int
+ti_gpio_pin_max(device_t dev, int *maxpin)
+{
+	struct ti_gpio_softc *sc = device_get_softc(dev);
+	unsigned int i;
+	unsigned int banks = 0;
+
+	TI_GPIO_LOCK(sc);
+
+	/* Calculate how many valid banks we have and then multiply that by 32 to
+	 * give use the total number of pins.
+	 */
+	for (i = 0; i < MAX_GPIO_BANKS; i++) {
+		if (sc->sc_mem_res[i] != NULL)
+			banks++;
+	}
+
+	*maxpin = (banks * PINS_PER_BANK) - 1;
+
+	TI_GPIO_UNLOCK(sc);
+
+	return (0);
+}
+
+/**
+ *	ti_gpio_pin_getcaps - Gets the capabilties of a given pin
+ *	@dev: gpio device handle
+ *	@pin: the number of the pin
+ *	@caps: pointer to a value that upon return will contain the capabilities
+ *
+ *	Currently all pins have the same capability, notably:
+ *	  - GPIO_PIN_INPUT
+ *	  - GPIO_PIN_OUTPUT
+ *	  - GPIO_PIN_PULLUP
+ *	  - GPIO_PIN_PULLDOWN
+ *
+ *	LOCKING:
+ *	Internally locks the context
+ *
+ *	RETURNS:
+ *	Returns 0 on success otherwise an error code
+ */
+static int
+ti_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
+{
+	struct ti_gpio_softc *sc = device_get_softc(dev);
+	uint32_t bank = (pin / PINS_PER_BANK);
+
+	TI_GPIO_LOCK(sc);
+
+	/* Sanity check the pin number is valid */
+	if ((bank >= MAX_GPIO_BANKS) || (sc->sc_mem_res[bank] == NULL)) {
+		TI_GPIO_UNLOCK(sc);
+		return (EINVAL);
+	}
+
+	*caps = (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT |GPIO_PIN_PULLUP |
+	    GPIO_PIN_PULLDOWN);
+
+	TI_GPIO_UNLOCK(sc);
+
+	return (0);
+}
+
+/**
+ *	ti_gpio_pin_getflags - Gets the current flags of a given pin
+ *	@dev: gpio device handle
+ *	@pin: the number of the pin
+ *	@flags: upon return will contain the current flags of the pin
+ *
+ *	Reads the current flags of a given pin, here we actually read the H/W
+ *	registers to determine the flags, rather than storing the value in the
+ *	setflags call.
+ *
+ *	LOCKING:
+ *	Internally locks the context
+ *
+ *	RETURNS:
+ *	Returns 0 on success otherwise an error code
+ */
+static int
+ti_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
+{
+	struct ti_gpio_softc *sc = device_get_softc(dev);
+	uint32_t bank = (pin / PINS_PER_BANK);
+
+	TI_GPIO_LOCK(sc);
+
+	/* Sanity check the pin number is valid */
+	if ((bank >= MAX_GPIO_BANKS) || (sc->sc_mem_res[bank] == NULL)) {
+		TI_GPIO_UNLOCK(sc);
+		return (EINVAL);
+	}
+
+	/* Get the current pin state */
+	ti_scm_padconf_get_gpioflags(pin, flags);
+
+	TI_GPIO_UNLOCK(sc);
+
+	return (0);
+}
+
+/**
+ *	ti_gpio_pin_getname - Gets the name of a given pin
+ *	@dev: gpio device handle
+ *	@pin: the number of the pin
+ *	@name: buffer to put the name in
+ *
+ *	The driver simply calls the pins gpio_n, where 'n' is obviously the number
+ *	of the pin.
+ *
+ *	LOCKING:
+ *	Internally locks the context
+ *
+ *	RETURNS:
+ *	Returns 0 on success otherwise an error code
+ */
+static int
+ti_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
+{
+	struct ti_gpio_softc *sc = device_get_softc(dev);
+	uint32_t bank = (pin / PINS_PER_BANK);
+
+	TI_GPIO_LOCK(sc);
+
+	/* Sanity check the pin number is valid */
+	if ((bank >= MAX_GPIO_BANKS) || (sc->sc_mem_res[bank] == NULL)) {
+		TI_GPIO_UNLOCK(sc);
+		return (EINVAL);
+	}
+
+	/* Set a very simple name */
+	snprintf(name, GPIOMAXNAME, "gpio_%u", pin);
+	name[GPIOMAXNAME - 1] = '\0';
+
+	TI_GPIO_UNLOCK(sc);
+
+	return (0);
+}
+
+/**
+ *	ti_gpio_pin_setflags - Sets the flags for a given pin
+ *	@dev: gpio device handle
+ *	@pin: the number of the pin
+ *	@flags: the flags to set
+ *
+ *	The flags of the pin correspond to things like input/output mode, pull-ups,
+ *	pull-downs, etc.  This driver doesn't support all flags, only the following:
+ *	  - GPIO_PIN_INPUT
+ *	  - GPIO_PIN_OUTPUT
+ *	  - GPIO_PIN_PULLUP
+ *	  - GPIO_PIN_PULLDOWN
+ *
+ *	LOCKING:
+ *	Internally locks the context
+ *
+ *	RETURNS:
+ *	Returns 0 on success otherwise an error code
+ */
+static int
+ti_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
+{
+	struct ti_gpio_softc *sc = device_get_softc(dev);
+	uint32_t bank = (pin / PINS_PER_BANK);
+	uint32_t mask = (1UL << (pin % PINS_PER_BANK));
+	uint32_t reg_val;
+
+	TI_GPIO_LOCK(sc);
+
+	/* Sanity check the pin number is valid */
+	if ((bank >= MAX_GPIO_BANKS) || (sc->sc_mem_res[bank] == NULL)) {
+		TI_GPIO_UNLOCK(sc);
+		return (EINVAL);
+	}
+
+	/* Set the GPIO mode and state */
+	if (ti_scm_padconf_set_gpioflags(pin, flags) != 0) {
+		TI_GPIO_UNLOCK(sc);
+		return (EINVAL);
+	}
+
+	/* If configuring as an output set the "output enable" bit */
+	reg_val = ti_gpio_read_4(sc, bank, TI_GPIO_OE);
+	if (flags & GPIO_PIN_INPUT)
+		reg_val |= mask;
+	else
+		reg_val &= ~mask;
+	ti_gpio_write_4(sc, bank, TI_GPIO_OE, reg_val);
+
+	TI_GPIO_UNLOCK(sc);
+	
+	return (0);
+}
+
+/**
+ *	ti_gpio_pin_set - Sets the current level on a GPIO pin
+ *	@dev: gpio device handle
+ *	@pin: the number of the pin
+ *	@value: non-zero value will drive the pin high, otherwise the pin is
+ *	        driven low.
+ *
+ *
+ *	LOCKING:
+ *	Internally locks the context
+ *
+ *	RETURNS:
+ *	Returns 0 on success otherwise a error code
+ */
+static int
+ti_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value)
+{
+	struct ti_gpio_softc *sc = device_get_softc(dev);
+	uint32_t bank = (pin / PINS_PER_BANK);
+	uint32_t mask = (1UL << (pin % PINS_PER_BANK));
+
+	TI_GPIO_LOCK(sc);
+
+	/* Sanity check the pin number is valid */
+	if ((bank >= MAX_GPIO_BANKS) || (sc->sc_mem_res[bank] == NULL)) {
+		TI_GPIO_UNLOCK(sc);
+		return (EINVAL);
+	}
+
+	ti_gpio_write_4(sc, bank, (value == GPIO_PIN_LOW) ? TI_GPIO_CLEARDATAOUT
+	    : TI_GPIO_SETDATAOUT, mask);
+
+	TI_GPIO_UNLOCK(sc);
+
+	return (0);
+}
+
+/**
+ *	ti_gpio_pin_get - Gets the current level on a GPIO pin
+ *	@dev: gpio device handle
+ *	@pin: the number of the pin
+ *	@value: pointer to a value that upond return will contain the pin value
+ *
+ *	The pin must be configured as an input pin beforehand, otherwise this
+ *	function will fail.
+ *
+ *	LOCKING:
+ *	Internally locks the context
+ *
+ *	RETURNS:
+ *	Returns 0 on success otherwise a error code
+ */
+static int
+ti_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *value)
+{
+	struct ti_gpio_softc *sc = device_get_softc(dev);
+	uint32_t bank = (pin / PINS_PER_BANK);
+	uint32_t mask = (1UL << (pin % PINS_PER_BANK));
+	uint32_t val = 0;
+
+	TI_GPIO_LOCK(sc);
+
+	/* Sanity check the pin number is valid */
+	if ((bank >= MAX_GPIO_BANKS) || (sc->sc_mem_res[bank] == NULL)) {
+		TI_GPIO_UNLOCK(sc);
+		return (EINVAL);
+	}
+
+	/* Sanity check the pin is not configured as an output */
+	val = ti_gpio_read_4(sc, bank, TI_GPIO_OE);
+
+	/* Read the value on the pin */
+	if (val & mask)
+		*value = (ti_gpio_read_4(sc, bank, TI_GPIO_DATAIN) & mask) ? 1 : 0;
+	else
+		*value = (ti_gpio_read_4(sc, bank, TI_GPIO_DATAOUT) & mask) ? 1 : 0;
+
+	TI_GPIO_UNLOCK(sc);
+
+	return (0);
+}
+
+/**
+ *	ti_gpio_pin_toggle - Toggles a given GPIO pin
+ *	@dev: gpio device handle
+ *	@pin: the number of the pin
+ *
+ *
+ *	LOCKING:
+ *	Internally locks the context
+ *
+ *	RETURNS:
+ *	Returns 0 on success otherwise a error code
+ */
+static int
+ti_gpio_pin_toggle(device_t dev, uint32_t pin)
+{
+	struct ti_gpio_softc *sc = device_get_softc(dev);
+	uint32_t bank = (pin / PINS_PER_BANK);
+	uint32_t mask = (1UL << (pin % PINS_PER_BANK));
+	uint32_t val;
+
+	TI_GPIO_LOCK(sc);
+
+	/* Sanity check the pin number is valid */
+	if ((bank >= MAX_GPIO_BANKS) || (sc->sc_mem_res[bank] == NULL)) {
+		TI_GPIO_UNLOCK(sc);
+		return (EINVAL);
+	}
+
+	/* Toggle the pin */
+	val = ti_gpio_read_4(sc, bank, TI_GPIO_DATAOUT);
+	if (val & mask)
+		ti_gpio_write_4(sc, bank, TI_GPIO_CLEARDATAOUT, mask);
+	else
+		ti_gpio_write_4(sc, bank, TI_GPIO_SETDATAOUT, mask);
+
+	TI_GPIO_UNLOCK(sc);
+
+	return (0);
+}
+
+/**
+ *	ti_gpio_intr - ISR for all GPIO modules
+ *	@arg: the soft context pointer
+ *
+ *	Unsused
+ *
+ *	LOCKING:
+ *	Internally locks the context
+ *
+ */
+static void
+ti_gpio_intr(void *arg)
+{
+	struct ti_gpio_softc *sc = arg;
+
+	TI_GPIO_LOCK(sc);
+	/* TODO: something useful */
+	TI_GPIO_UNLOCK(sc);
+}
+
+/**
+ *	ti_gpio_probe - probe function for the driver
+ *	@dev: gpio device handle
+ *
+ *	Simply sets the name of the driver
+ *
+ *	LOCKING:
+ *	None
+ *
+ *	RETURNS:
+ *	Always returns 0
+ */
+static int
+ti_gpio_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "ti,gpio"))
+		return (ENXIO);
+
+	device_set_desc(dev, "TI General Purpose I/O (GPIO)");
+
+	return (0);
+}
+
+static int
+ti_gpio_attach_intr(device_t dev)
+{
+	int i;
+	struct ti_gpio_softc *sc;
+
+	sc = device_get_softc(dev);
+	for (i = 0; i < MAX_GPIO_INTRS; i++) {
+		if (sc->sc_irq_res[i] == NULL)
+			break;
+
+		/*
+		 * Register our interrupt handler for each of the IRQ resources.
+		 */
+		if (bus_setup_intr(dev, sc->sc_irq_res[i],
+		    INTR_TYPE_MISC | INTR_MPSAFE, NULL, ti_gpio_intr, sc,
+		    &sc->sc_irq_hdl[i]) != 0) {
+			device_printf(dev,
+			    "WARNING: unable to register interrupt handler\n");
+			return (-1);
+		}
+	}
+
+	return (0);
+}
+
+static int
+ti_gpio_detach_intr(device_t dev)
+{
+	int i;
+	struct ti_gpio_softc *sc;
+
+	/* Teardown our interrupt handlers. */
+	sc = device_get_softc(dev);
+	for (i = 0; i < MAX_GPIO_INTRS; i++) {
+		if (sc->sc_irq_res[i] == NULL)
+			break;
+
+		if (sc->sc_irq_hdl[i]) {
+			bus_teardown_intr(dev, sc->sc_irq_res[i],
+			    sc->sc_irq_hdl[i]);
+		}
+	}
+
+	return (0);
+}
+
+static int
+ti_gpio_bank_init(device_t dev, int bank)
+{
+	int pin;
+	struct ti_gpio_softc *sc;
+	uint32_t flags, reg_oe;
+
+	sc = device_get_softc(dev);
+
+	/* Enable the interface and functional clocks for the module. */
+	ti_prcm_clk_enable(GPIO0_CLK + FIRST_GPIO_BANK + bank);
+
+	/*
+	 * Read the revision number of the module.  TI don't publish the
+	 * actual revision numbers, so instead the values have been
+	 * determined by experimentation.
+	 */
+	sc->sc_revision[bank] = ti_gpio_read_4(sc, bank, TI_GPIO_REVISION);
+
+	/* Check the revision. */
+	if (sc->sc_revision[bank] != TI_GPIO_REV) {
+		device_printf(dev, "Warning: could not determine the revision "
+		    "of %u GPIO module (revision:0x%08x)\n",
+		    bank, sc->sc_revision[bank]);
+		return (EINVAL);
+	}
+
+	/* Disable interrupts for all pins. */
+	ti_gpio_intr_clr(sc, bank, 0xffffffff);
+
+	/* Init OE register based on pads configuration. */
+	reg_oe = 0xffffffff;
+	for (pin = 0; pin < PINS_PER_BANK; pin++) {
+		ti_scm_padconf_get_gpioflags(PINS_PER_BANK * bank + pin,
+		    &flags);
+		if (flags & GPIO_PIN_OUTPUT)
+			reg_oe &= ~(1UL << pin);
+	}
+	ti_gpio_write_4(sc, bank, TI_GPIO_OE, reg_oe);
+
+	return (0);
+}
+
+/**
+ *	ti_gpio_attach - attach function for the driver
+ *	@dev: gpio device handle
+ *
+ *	Allocates and sets up the driver context for all GPIO banks.  This function
+ *	expects the memory ranges and IRQs to already be allocated to the driver.
+ *
+ *	LOCKING:
+ *	None
+ *
+ *	RETURNS:
+ *	Always returns 0
+ */
+static int
+ti_gpio_attach(device_t dev)
+{
+	struct ti_gpio_softc *sc;
+	unsigned int i;
+	int err;
+
+ 	sc = device_get_softc(dev);
+	sc->sc_dev = dev;
+
+	TI_GPIO_LOCK_INIT(sc);
+
+	/* There are up to 6 different GPIO register sets located in different
+	 * memory areas on the chip.  The memory range should have been set for
+	 * the driver when it was added as a child.
+	 */
+	if (bus_alloc_resources(dev, ti_gpio_mem_spec, sc->sc_mem_res) != 0) {
+		device_printf(dev, "Error: could not allocate mem resources\n");
+		return (ENXIO);
+	}
+
+	/* Request the IRQ resources */
+	if (bus_alloc_resources(dev, ti_gpio_irq_spec, sc->sc_irq_res) != 0) {
+		bus_release_resources(dev, ti_gpio_mem_spec, sc->sc_mem_res);
+		device_printf(dev, "Error: could not allocate irq resources\n");
+		return (ENXIO);
+	}
+
+	/* Setup the IRQ resources */
+	if (ti_gpio_attach_intr(dev) != 0) {
+		ti_gpio_detach_intr(dev);
+		bus_release_resources(dev, ti_gpio_irq_spec, sc->sc_irq_res);
+		bus_release_resources(dev, ti_gpio_mem_spec, sc->sc_mem_res);
+		return (ENXIO);
+	}
+
+	/* We need to go through each block and ensure the clocks are running and
+	 * the module is enabled.  It might be better to do this only when the
+	 * pins are configured which would result in less power used if the GPIO
+	 * pins weren't used ... 
+	 */
+	for (i = 0; i < MAX_GPIO_BANKS; i++) {
+		if (sc->sc_mem_res[i] != NULL) {
+			/* Initialize the GPIO module. */
+			err = ti_gpio_bank_init(dev, i);
+			if (err != 0) {
+				ti_gpio_detach_intr(dev);
+				bus_release_resources(dev, ti_gpio_irq_spec,
+				    sc->sc_irq_res);
+				bus_release_resources(dev, ti_gpio_mem_spec,
+				    sc->sc_mem_res);
+				return (err);
+			}
+		}
+	}
+
+	/* Finish of the probe call */
+	device_add_child(dev, "gpioc", -1);
+	device_add_child(dev, "gpiobus", -1);
+
+	return (bus_generic_attach(dev));
+}
+
+/**
+ *	ti_gpio_detach - detach function for the driver
+ *	@dev: scm device handle
+ *
+ *	Allocates and sets up the driver context, this simply entails creating a
+ *	bus mappings for the SCM register set.
+ *
+ *	LOCKING:
+ *	None
+ *
+ *	RETURNS:
+ *	Always returns 0
+ */
+static int
+ti_gpio_detach(device_t dev)
+{
+	struct ti_gpio_softc *sc = device_get_softc(dev);
+	unsigned int i;
+
+	KASSERT(mtx_initialized(&sc->sc_mtx), ("gpio mutex not initialized"));
+
+	/* Disable all interrupts */
+	for (i = 0; i < MAX_GPIO_BANKS; i++) {
+		if (sc->sc_mem_res[i] != NULL)
+			ti_gpio_intr_clr(sc, i, 0xffffffff);
+	}
+
+	bus_generic_detach(dev);
+
+	/* Release the memory and IRQ resources. */
+	ti_gpio_detach_intr(dev);
+	bus_release_resources(dev, ti_gpio_irq_spec, sc->sc_irq_res);
+	bus_release_resources(dev, ti_gpio_mem_spec, sc->sc_mem_res);
+
+	TI_GPIO_LOCK_DESTROY(sc);
+
+	return (0);
+}
+
+static phandle_t
+ti_gpio_get_node(device_t bus, device_t dev)
+{
+
+	/* We only have one child, the GPIO bus, which needs our own node. */
+	return (ofw_bus_get_node(bus));
+}
+
+static device_method_t ti_gpio_methods[] = {
+	DEVMETHOD(device_probe, ti_gpio_probe),
+	DEVMETHOD(device_attach, ti_gpio_attach),
+	DEVMETHOD(device_detach, ti_gpio_detach),
+
+	/* GPIO protocol */
+	DEVMETHOD(gpio_pin_max, ti_gpio_pin_max),
+	DEVMETHOD(gpio_pin_getname, ti_gpio_pin_getname),
+	DEVMETHOD(gpio_pin_getflags, ti_gpio_pin_getflags),
+	DEVMETHOD(gpio_pin_getcaps, ti_gpio_pin_getcaps),
+	DEVMETHOD(gpio_pin_setflags, ti_gpio_pin_setflags),
+	DEVMETHOD(gpio_pin_get, ti_gpio_pin_get),
+	DEVMETHOD(gpio_pin_set, ti_gpio_pin_set),
+	DEVMETHOD(gpio_pin_toggle, ti_gpio_pin_toggle),
+
+	/* ofw_bus interface */
+	DEVMETHOD(ofw_bus_get_node, ti_gpio_get_node),
+
+	{0, 0},
+};
+
+static driver_t ti_gpio_driver = {
+	"gpio",
+	ti_gpio_methods,
+	sizeof(struct ti_gpio_softc),
+};
+static devclass_t ti_gpio_devclass;
+
+DRIVER_MODULE(ti_gpio, simplebus, ti_gpio_driver, ti_gpio_devclass, 0, 0);


Property changes on: trunk/sys/arm/ti/ti_gpio.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/ti_i2c.c
===================================================================
--- trunk/sys/arm/ti/ti_i2c.c	                        (rev 0)
+++ trunk/sys/arm/ti/ti_i2c.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,982 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2011 Ben Gray <ben.r.gray at gmail.com>.
+ * Copyright (c) 2014 Luiz Otavio O Souza <loos at freebsd.org>.
+ * 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 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 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.
+ */
+
+/**
+ * Driver for the I2C module on the TI SoC.
+ *
+ * This driver is heavily based on the TWI driver for the AT91 (at91_twi.c).
+ *
+ * CAUTION: The I2Ci registers are limited to 16 bit and 8 bit data accesses,
+ * 32 bit data access is not allowed and can corrupt register content.
+ *
+ * This driver currently doesn't use DMA for the transfer, although I hope to
+ * incorporate that sometime in the future.  The idea being that for transaction
+ * larger than a certain size the DMA engine is used, for anything less the
+ * normal interrupt/fifo driven option is used.
+ *
+ *
+ * WARNING: This driver uses mtx_sleep and interrupts to perform transactions,
+ * which means you can't do a transaction during startup before the interrupts
+ * have been enabled.  Hint - the freebsd function config_intrhook_establish().
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/ti/ti_i2c.c 276278 2014-12-27 02:37:52Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/mbuf.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/rman.h>
+#include <sys/sysctl.h>
+#include <machine/bus.h>
+
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <arm/ti/ti_cpuid.h>
+#include <arm/ti/ti_prcm.h>
+#include <arm/ti/ti_i2c.h>
+
+#include <dev/iicbus/iiconf.h>
+#include <dev/iicbus/iicbus.h>
+
+#include "iicbus_if.h"
+
+/**
+ *	I2C device driver context, a pointer to this is stored in the device
+ *	driver structure.
+ */
+struct ti_i2c_softc
+{
+	device_t		sc_dev;
+	uint32_t		device_id;
+	struct resource*	sc_irq_res;
+	struct resource*	sc_mem_res;
+	device_t		sc_iicbus;
+
+	void*			sc_irq_h;
+
+	struct mtx		sc_mtx;
+
+	struct iic_msg*		sc_buffer;
+	int			sc_bus_inuse;
+	int			sc_buffer_pos;
+	int			sc_error;
+	int			sc_fifo_trsh;
+
+	uint16_t		sc_con_reg;
+	uint16_t		sc_rev;
+};
+
+struct ti_i2c_clock_config
+{
+	u_int   frequency;	/* Bus frequency in Hz */
+	uint8_t psc;		/* Fast/Standard mode prescale divider */
+	uint8_t scll;		/* Fast/Standard mode SCL low time */
+	uint8_t sclh;		/* Fast/Standard mode SCL high time */
+	uint8_t hsscll;		/* High Speed mode SCL low time */
+	uint8_t hssclh;		/* High Speed mode SCL high time */
+};
+
+#if defined(SOC_OMAP3)
+#error "Unsupported SoC"
+#endif
+
+#if defined(SOC_OMAP4)
+/*
+ * OMAP4 i2c bus clock is 96MHz / ((psc + 1) * (scll + 7 + sclh + 5)).
+ * The prescaler values for 100KHz and 400KHz modes come from the table in the
+ * OMAP4 TRM.  The table doesn't list 1MHz; these values should give that speed.
+ */
+static struct ti_i2c_clock_config ti_omap4_i2c_clock_configs[] = {
+	{  100000, 23,  13,  15,  0,  0},
+	{  400000,  9,   5,   7,  0,  0},
+	{ 1000000,  3,   5,   7,  0,  0},
+/*	{ 3200000,  1, 113, 115,  7, 10}, - HS mode */
+	{       0 /* Table terminator */ }
+};
+#endif
+
+#if defined(SOC_TI_AM335X)
+/*
+ * AM335x i2c bus clock is 48MHZ / ((psc + 1) * (scll + 7 + sclh + 5))
+ * In all cases we prescale the clock to 24MHz as recommended in the manual.
+ */
+static struct ti_i2c_clock_config ti_am335x_i2c_clock_configs[] = {
+	{  100000, 1, 111, 117, 0, 0},
+	{  400000, 1,  23,  25, 0, 0},
+	{ 1000000, 1,   5,   7, 0, 0},
+	{       0 /* Table terminator */ }
+};
+#endif
+
+/**
+ *	Locking macros used throughout the driver
+ */
+#define	TI_I2C_LOCK(_sc)		mtx_lock(&(_sc)->sc_mtx)
+#define	TI_I2C_UNLOCK(_sc)		mtx_unlock(&(_sc)->sc_mtx)
+#define	TI_I2C_LOCK_INIT(_sc)						\
+	mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->sc_dev),	\
+	    "ti_i2c", MTX_DEF)
+#define	TI_I2C_LOCK_DESTROY(_sc)	mtx_destroy(&_sc->sc_mtx)
+#define	TI_I2C_ASSERT_LOCKED(_sc)	mtx_assert(&_sc->sc_mtx, MA_OWNED)
+#define	TI_I2C_ASSERT_UNLOCKED(_sc)	mtx_assert(&_sc->sc_mtx, MA_NOTOWNED)
+
+#ifdef DEBUG
+#define	ti_i2c_dbg(_sc, fmt, args...)					\
+	device_printf((_sc)->sc_dev, fmt, ##args)
+#else
+#define	ti_i2c_dbg(_sc, fmt, args...)
+#endif
+
+/**
+ *	ti_i2c_read_2 - reads a 16-bit value from one of the I2C registers
+ *	@sc: I2C device context
+ *	@off: the byte offset within the register bank to read from.
+ *
+ *
+ *	LOCKING:
+ *	No locking required
+ *
+ *	RETURNS:
+ *	16-bit value read from the register.
+ */
+static inline uint16_t
+ti_i2c_read_2(struct ti_i2c_softc *sc, bus_size_t off)
+{
+
+	return (bus_read_2(sc->sc_mem_res, off));
+}
+
+/**
+ *	ti_i2c_write_2 - writes a 16-bit value to one of the I2C registers
+ *	@sc: I2C device context
+ *	@off: the byte offset within the register bank to read from.
+ *	@val: the value to write into the register
+ *
+ *	LOCKING:
+ *	No locking required
+ *
+ *	RETURNS:
+ *	16-bit value read from the register.
+ */
+static inline void
+ti_i2c_write_2(struct ti_i2c_softc *sc, bus_size_t off, uint16_t val)
+{
+
+	bus_write_2(sc->sc_mem_res, off, val);
+}
+
+static int
+ti_i2c_transfer_intr(struct ti_i2c_softc* sc, uint16_t status)
+{
+	int amount, done, i;
+
+	done = 0;
+	amount = 0;
+	/* Check for the error conditions. */
+	if (status & I2C_STAT_NACK) {
+		/* No ACK from slave. */
+		ti_i2c_dbg(sc, "NACK\n");
+		ti_i2c_write_2(sc, I2C_REG_STATUS, I2C_STAT_NACK);
+		sc->sc_error = ENXIO;
+	} else if (status & I2C_STAT_AL) {
+		/* Arbitration lost. */
+		ti_i2c_dbg(sc, "Arbitration lost\n");
+		ti_i2c_write_2(sc, I2C_REG_STATUS, I2C_STAT_AL);
+		sc->sc_error = ENXIO;
+	}
+
+	/* Check if we have finished. */
+	if (status & I2C_STAT_ARDY) {
+		/* Register access ready - transaction complete basically. */
+		ti_i2c_dbg(sc, "ARDY transaction complete\n");
+		if (sc->sc_error != 0 && sc->sc_buffer->flags & IIC_M_NOSTOP) {
+			ti_i2c_write_2(sc, I2C_REG_CON,
+			    sc->sc_con_reg | I2C_CON_STP);
+		}
+		ti_i2c_write_2(sc, I2C_REG_STATUS,
+		    I2C_STAT_ARDY | I2C_STAT_RDR | I2C_STAT_RRDY |
+		    I2C_STAT_XDR | I2C_STAT_XRDY);
+		return (1);
+	}
+
+	if (sc->sc_buffer->flags & IIC_M_RD) {
+		/* Read some data. */
+		if (status & I2C_STAT_RDR) {
+			/*
+			 * Receive draining interrupt - last data received.
+			 * The set FIFO threshold wont be reached to trigger
+			 * RRDY.
+			 */
+			ti_i2c_dbg(sc, "Receive draining interrupt\n");
+
+			/*
+			 * Drain the FIFO.  Read the pending data in the FIFO.
+			 */
+			amount = sc->sc_buffer->len - sc->sc_buffer_pos;
+		} else if (status & I2C_STAT_RRDY) {
+			/*
+			 * Receive data ready interrupt - FIFO has reached the
+			 * set threshold.
+			 */
+			ti_i2c_dbg(sc, "Receive data ready interrupt\n");
+
+			amount = min(sc->sc_fifo_trsh,
+			    sc->sc_buffer->len - sc->sc_buffer_pos);
+		}
+
+		/* Read the bytes from the fifo. */
+		for (i = 0; i < amount; i++)
+			sc->sc_buffer->buf[sc->sc_buffer_pos++] = 
+			    (uint8_t)(ti_i2c_read_2(sc, I2C_REG_DATA) & 0xff);
+
+		if (status & I2C_STAT_RDR)
+			ti_i2c_write_2(sc, I2C_REG_STATUS, I2C_STAT_RDR);
+		if (status & I2C_STAT_RRDY)
+			ti_i2c_write_2(sc, I2C_REG_STATUS, I2C_STAT_RRDY);
+
+	} else {
+		/* Write some data. */
+		if (status & I2C_STAT_XDR) {
+			/*
+			 * Transmit draining interrupt - FIFO level is below
+			 * the set threshold and the amount of data still to
+			 * be transferred wont reach the set FIFO threshold.
+			 */
+			ti_i2c_dbg(sc, "Transmit draining interrupt\n");
+
+			/*
+			 * Drain the TX data.  Write the pending data in the
+			 * FIFO.
+			 */
+			amount = sc->sc_buffer->len - sc->sc_buffer_pos;
+		} else if (status & I2C_STAT_XRDY) {
+			/*
+			 * Transmit data ready interrupt - the FIFO level
+			 * is below the set threshold.
+			 */
+			ti_i2c_dbg(sc, "Transmit data ready interrupt\n");
+
+			amount = min(sc->sc_fifo_trsh,
+			    sc->sc_buffer->len - sc->sc_buffer_pos);
+		}
+
+		/* Write the bytes from the fifo. */
+		for (i = 0; i < amount; i++)
+			ti_i2c_write_2(sc, I2C_REG_DATA,
+			    sc->sc_buffer->buf[sc->sc_buffer_pos++]);
+
+		if (status & I2C_STAT_XDR)
+			ti_i2c_write_2(sc, I2C_REG_STATUS, I2C_STAT_XDR);
+		if (status & I2C_STAT_XRDY)
+			ti_i2c_write_2(sc, I2C_REG_STATUS, I2C_STAT_XRDY);
+	}
+
+	return (done);
+}
+
+/**
+ *	ti_i2c_intr - interrupt handler for the I2C module
+ *	@dev: i2c device handle
+ *
+ *
+ *
+ *	LOCKING:
+ *	Called from timer context
+ *
+ *	RETURNS:
+ *	EH_HANDLED or EH_NOT_HANDLED
+ */
+static void
+ti_i2c_intr(void *arg)
+{
+	int done;
+	struct ti_i2c_softc *sc;
+	uint16_t events, status;
+
+ 	sc = (struct ti_i2c_softc *)arg;
+
+	TI_I2C_LOCK(sc);
+
+	status = ti_i2c_read_2(sc, I2C_REG_STATUS);
+	if (status == 0) {
+		TI_I2C_UNLOCK(sc);
+		return;
+	}
+
+	/* Save enabled interrupts. */
+	events = ti_i2c_read_2(sc, I2C_REG_IRQENABLE_SET);
+
+	/* We only care about enabled interrupts. */
+	status &= events;
+
+	done = 0;
+
+	if (sc->sc_buffer != NULL)
+		done = ti_i2c_transfer_intr(sc, status);
+	else {
+		ti_i2c_dbg(sc, "Transfer interrupt without buffer\n");
+		sc->sc_error = EINVAL;
+		done = 1;
+	}
+
+	if (done)
+		/* Wakeup the process that started the transaction. */
+		wakeup(sc);
+
+	TI_I2C_UNLOCK(sc);
+}
+
+/**
+ *	ti_i2c_transfer - called to perform the transfer
+ *	@dev: i2c device handle
+ *	@msgs: the messages to send/receive
+ *	@nmsgs: the number of messages in the msgs array
+ *
+ *
+ *	LOCKING:
+ *	Internally locked
+ *
+ *	RETURNS:
+ *	0 on function succeeded
+ *	EINVAL if invalid message is passed as an arg
+ */
+static int
+ti_i2c_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
+{
+	int err, i, repstart, timeout;
+	struct ti_i2c_softc *sc;
+	uint16_t reg;
+
+ 	sc = device_get_softc(dev);
+	TI_I2C_LOCK(sc);
+
+	/* If the controller is busy wait until it is available. */
+	while (sc->sc_bus_inuse == 1)
+		mtx_sleep(sc, &sc->sc_mtx, 0, "i2cbuswait", 0);
+
+	/* Now we have control over the I2C controller. */
+	sc->sc_bus_inuse = 1;
+
+	err = 0;
+	repstart = 0;
+	for (i = 0; i < nmsgs; i++) {
+
+		sc->sc_buffer = &msgs[i];
+		sc->sc_buffer_pos = 0;
+		sc->sc_error = 0;
+
+		/* Zero byte transfers aren't allowed. */
+		if (sc->sc_buffer == NULL || sc->sc_buffer->buf == NULL ||
+		    sc->sc_buffer->len == 0) {
+			err = EINVAL;
+			break;
+		}
+
+		/* Check if the i2c bus is free. */
+		if (repstart == 0) {
+			/*
+			 * On repeated start we send the START condition while
+			 * the bus _is_ busy.
+			 */
+			timeout = 0;
+			while (ti_i2c_read_2(sc, I2C_REG_STATUS_RAW) & I2C_STAT_BB) {
+				if (timeout++ > 100) {
+					err = EBUSY;
+					goto out;
+				}
+				DELAY(1000);
+			}
+			timeout = 0;
+		} else
+			repstart = 0;
+
+		if (sc->sc_buffer->flags & IIC_M_NOSTOP)
+			repstart = 1;
+
+		/* Set the slave address. */
+		ti_i2c_write_2(sc, I2C_REG_SA, msgs[i].slave >> 1);
+
+		/* Write the data length. */
+		ti_i2c_write_2(sc, I2C_REG_CNT, sc->sc_buffer->len);
+
+		/* Clear the RX and the TX FIFO. */
+		reg = ti_i2c_read_2(sc, I2C_REG_BUF);
+		reg |= I2C_BUF_RXFIFO_CLR | I2C_BUF_TXFIFO_CLR;
+		ti_i2c_write_2(sc, I2C_REG_BUF, reg);
+
+		reg = sc->sc_con_reg | I2C_CON_STT;
+		if (repstart == 0)
+			reg |= I2C_CON_STP;
+		if ((sc->sc_buffer->flags & IIC_M_RD) == 0)
+			reg |= I2C_CON_TRX;
+		ti_i2c_write_2(sc, I2C_REG_CON, reg);
+
+		/* Wait for an event. */
+		err = mtx_sleep(sc, &sc->sc_mtx, 0, "i2ciowait", hz);
+		if (err == 0)
+			err = sc->sc_error;
+
+		if (err)
+			break;
+	}
+
+out:
+	if (timeout == 0) {
+		while (ti_i2c_read_2(sc, I2C_REG_STATUS_RAW) & I2C_STAT_BB) {
+			if (timeout++ > 100)
+				break;
+			DELAY(1000);
+		}
+	}
+	/* Put the controller in master mode again. */
+	if ((ti_i2c_read_2(sc, I2C_REG_CON) & I2C_CON_MST) == 0)
+		ti_i2c_write_2(sc, I2C_REG_CON, sc->sc_con_reg);
+
+	sc->sc_buffer = NULL;
+	sc->sc_bus_inuse = 0;
+
+	/* Wake up the processes that are waiting for the bus. */
+	wakeup(sc);
+
+	TI_I2C_UNLOCK(sc);
+
+	return (err);
+}
+
+/**
+ *	ti_i2c_callback - as we only provide iicbus_transfer() interface
+ * 		we don't need to implement the serialization here.
+ *	@dev: i2c device handle
+ *
+ *
+ *
+ *	LOCKING:
+ *	Called from timer context
+ *
+ *	RETURNS:
+ *	EH_HANDLED or EH_NOT_HANDLED
+ */
+static int
+ti_i2c_callback(device_t dev, int index, caddr_t data)
+{
+	int error = 0;
+
+	switch (index) {
+		case IIC_REQUEST_BUS:
+			break;
+
+		case IIC_RELEASE_BUS:
+			break;
+
+		default:
+			error = EINVAL;
+	}
+
+	return (error);
+}
+
+static int
+ti_i2c_reset(struct ti_i2c_softc *sc, u_char speed)
+{
+	int timeout;
+	struct ti_i2c_clock_config *clkcfg;
+	u_int busfreq;
+	uint16_t fifo_trsh, reg, scll, sclh;
+
+	switch (ti_chip()) {
+#ifdef SOC_OMAP4
+	case CHIP_OMAP_4:
+		clkcfg = ti_omap4_i2c_clock_configs;
+		break;
+#endif
+#ifdef SOC_TI_AM335X
+	case CHIP_AM335X:
+		clkcfg = ti_am335x_i2c_clock_configs;
+		break;
+#endif
+	default:
+		panic("Unknown Ti SoC, unable to reset the i2c");
+	}
+
+	/*
+	 * If we haven't attached the bus yet, just init at the default slow
+	 * speed.  This lets us get the hardware initialized enough to attach
+	 * the bus which is where the real speed configuration is handled. After
+	 * the bus is attached, get the configured speed from it.  Search the
+	 * configuration table for the best speed we can do that doesn't exceed
+	 * the requested speed.
+	 */
+	if (sc->sc_iicbus == NULL)
+		busfreq = 100000;
+	else
+		busfreq = IICBUS_GET_FREQUENCY(sc->sc_iicbus, speed);
+	for (;;) {
+		if (clkcfg[1].frequency == 0 || clkcfg[1].frequency > busfreq)
+			break;
+		clkcfg++;
+	}
+
+	/*
+	 * 23.1.4.3 - HS I2C Software Reset
+	 *    From OMAP4 TRM at page 4068.
+	 *
+	 * 1. Ensure that the module is disabled.
+	 */
+	sc->sc_con_reg = 0;
+	ti_i2c_write_2(sc, I2C_REG_CON, sc->sc_con_reg);
+
+	/* 2. Issue a softreset to the controller. */
+	bus_write_2(sc->sc_mem_res, I2C_REG_SYSC, I2C_REG_SYSC_SRST);
+
+	/*
+	 * 3. Enable the module.
+	 *    The I2Ci.I2C_SYSS[0] RDONE bit is asserted only after the module
+	 *    is enabled by setting the I2Ci.I2C_CON[15] I2C_EN bit to 1.
+	 */
+	ti_i2c_write_2(sc, I2C_REG_CON, I2C_CON_I2C_EN);
+
+ 	/* 4. Wait for the software reset to complete. */
+	timeout = 0;
+	while ((ti_i2c_read_2(sc, I2C_REG_SYSS) & I2C_SYSS_RDONE) == 0) {
+		if (timeout++ > 100)
+			return (EBUSY);
+		DELAY(100);
+	}
+
+	/*
+	 * Disable the I2C controller once again, now that the reset has
+	 * finished.
+	 */
+	ti_i2c_write_2(sc, I2C_REG_CON, sc->sc_con_reg);
+
+	/*
+	 * The following sequence is taken from the OMAP4 TRM at page 4077.
+	 *
+	 * 1. Enable the functional and interface clocks (see Section
+	 *    23.1.5.1.1.1.1).  Done at ti_i2c_activate().
+	 *
+	 * 2. Program the prescaler to obtain an approximately 12MHz internal
+	 *    sampling clock (I2Ci_INTERNAL_CLK) by programming the
+	 *    corresponding value in the I2Ci.I2C_PSC[3:0] PSC field.
+	 *    This value depends on the frequency of the functional clock
+	 *    (I2Ci_FCLK).  Because this frequency is 96MHz, the
+	 *    I2Ci.I2C_PSC[7:0] PSC field value is 0x7.
+	 */
+	ti_i2c_write_2(sc, I2C_REG_PSC, clkcfg->psc);
+
+	/*
+	 * 3. Program the I2Ci.I2C_SCLL[7:0] SCLL and I2Ci.I2C_SCLH[7:0] SCLH
+	 *    bit fields to obtain a bit rate of 100 Kbps, 400 Kbps or 1Mbps.
+	 *    These values depend on the internal sampling clock frequency
+	 *    (see Table 23-8).
+	 */
+	scll = clkcfg->scll & I2C_SCLL_MASK;
+	sclh = clkcfg->sclh & I2C_SCLH_MASK;
+
+	/*
+	 * 4. (Optional) Program the I2Ci.I2C_SCLL[15:8] HSSCLL and
+	 *    I2Ci.I2C_SCLH[15:8] HSSCLH fields to obtain a bit rate of
+	 *    400K bps or 3.4M bps (for the second phase of HS mode).  These
+	 *    values depend on the internal sampling clock frequency (see
+	 *    Table 23-8).
+	 *
+	 * 5. (Optional) If a bit rate of 3.4M bps is used and the bus line
+	 *    capacitance exceeds 45 pF, (see Section 18.4.8, PAD Functional
+	 *    Multiplexing and Configuration).
+	 */
+	switch (ti_chip()) {
+#ifdef SOC_OMAP4
+	case CHIP_OMAP_4:
+		if ((clkcfg->hsscll + clkcfg->hssclh) > 0) {
+			scll |= clkcfg->hsscll << I2C_HSSCLL_SHIFT;
+			sclh |= clkcfg->hssclh << I2C_HSSCLH_SHIFT;
+			sc->sc_con_reg |= I2C_CON_OPMODE_HS;
+		}
+		break;
+#endif
+	}
+
+	/* Write the selected bit rate. */
+	ti_i2c_write_2(sc, I2C_REG_SCLL, scll);
+	ti_i2c_write_2(sc, I2C_REG_SCLH, sclh);
+
+	/*
+	 * 6. Configure the Own Address of the I2C controller by storing it in
+	 *    the I2Ci.I2C_OA0 register.  Up to four Own Addresses can be
+	 *    programmed in the I2Ci.I2C_OAi registers (where i = 0, 1, 2, 3)
+	 *    for each I2C controller.
+	 *
+	 * Note: For a 10-bit address, set the corresponding expand Own Address
+	 * bit in the I2Ci.I2C_CON register.
+	 *
+	 * Driver currently always in single master mode so ignore this step.
+	 */
+
+	/*
+	 * 7. Set the TX threshold (in transmitter mode) and the RX threshold
+	 *    (in receiver mode) by setting the I2Ci.I2C_BUF[5:0]XTRSH field to
+	 *    (TX threshold - 1) and the I2Ci.I2C_BUF[13:8]RTRSH field to (RX
+	 *    threshold - 1), where the TX and RX thresholds are greater than
+	 *    or equal to 1.
+	 *
+	 * The threshold is set to 5 for now.
+	 */
+	fifo_trsh = (sc->sc_fifo_trsh - 1) & I2C_BUF_TRSH_MASK;
+	reg = fifo_trsh | (fifo_trsh << I2C_BUF_RXTRSH_SHIFT);
+	ti_i2c_write_2(sc, I2C_REG_BUF, reg);
+
+	/*
+	 * 8. Take the I2C controller out of reset by setting the
+	 *    I2Ci.I2C_CON[15] I2C_EN bit to 1.
+	 *
+	 * 23.1.5.1.1.1.2 - Initialize the I2C Controller
+	 *
+	 * To initialize the I2C controller, perform the following steps:
+	 *
+	 * 1. Configure the I2Ci.I2C_CON register:
+	 *     . For master or slave mode, set the I2Ci.I2C_CON[10] MST bit
+	 *       (0: slave, 1: master).
+	 *     . For transmitter or receiver mode, set the I2Ci.I2C_CON[9] TRX
+	 *       bit (0: receiver, 1: transmitter).
+	 */
+
+	/* Enable the I2C controller in master mode. */
+	sc->sc_con_reg |= I2C_CON_I2C_EN | I2C_CON_MST;
+	ti_i2c_write_2(sc, I2C_REG_CON, sc->sc_con_reg);
+
+	/*
+	 * 2. If using an interrupt to transmit/receive data, set the
+	 *    corresponding bit in the I2Ci.I2C_IE register (the I2Ci.I2C_IE[4]
+	 *    XRDY_IE bit for the transmit interrupt, the I2Ci.I2C_IE[3] RRDY
+	 *    bit for the receive interrupt).
+	 */
+
+	/* Set the interrupts we want to be notified. */
+	reg = I2C_IE_XDR |	/* Transmit draining interrupt. */
+	    I2C_IE_XRDY |	/* Transmit Data Ready interrupt. */
+	    I2C_IE_RDR |	/* Receive draining interrupt. */
+	    I2C_IE_RRDY |	/* Receive Data Ready interrupt. */
+	    I2C_IE_ARDY |	/* Register Access Ready interrupt. */
+	    I2C_IE_NACK |	/* No Acknowledgment interrupt. */
+	    I2C_IE_AL;		/* Arbitration lost interrupt. */
+
+	/* Enable the interrupts. */
+	ti_i2c_write_2(sc, I2C_REG_IRQENABLE_SET, reg);
+
+	/*
+	 * 3. If using DMA to receive/transmit data, set to 1 the corresponding
+	 *    bit in the I2Ci.I2C_BUF register (the I2Ci.I2C_BUF[15] RDMA_EN
+	 *    bit for the receive DMA channel, the I2Ci.I2C_BUF[7] XDMA_EN bit
+	 *    for the transmit DMA channel).
+	 *
+	 * Not using DMA for now, so ignore this.
+	 */
+
+	return (0);
+}
+
+static int
+ti_i2c_iicbus_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
+{
+	struct ti_i2c_softc *sc;
+	int err;
+
+	sc = device_get_softc(dev);
+	TI_I2C_LOCK(sc);
+	err = ti_i2c_reset(sc, speed);
+	TI_I2C_UNLOCK(sc);
+	if (err)
+		return (err);
+
+	return (IIC_ENOADDR);
+}
+
+static int
+ti_i2c_activate(device_t dev)
+{
+	clk_ident_t clk;
+	int err;
+	struct ti_i2c_softc *sc;
+
+	sc = (struct ti_i2c_softc*)device_get_softc(dev);
+
+	/*
+	 * 1. Enable the functional and interface clocks (see Section
+	 * 23.1.5.1.1.1.1).
+	 */
+	clk = I2C0_CLK + sc->device_id;
+	err = ti_prcm_clk_enable(clk);
+	if (err)
+		return (err);
+
+	return (ti_i2c_reset(sc, IIC_UNKNOWN));
+}
+
+/**
+ *	ti_i2c_deactivate - deactivates the controller and releases resources
+ *	@dev: i2c device handle
+ *
+ *
+ *
+ *	LOCKING:
+ *	Assumed called in an atomic context.
+ *
+ *	RETURNS:
+ *	nothing
+ */
+static void
+ti_i2c_deactivate(device_t dev)
+{
+	struct ti_i2c_softc *sc = device_get_softc(dev);
+	clk_ident_t clk;
+
+	/* Disable the controller - cancel all transactions. */
+	ti_i2c_write_2(sc, I2C_REG_IRQENABLE_CLR, 0xffff);
+	ti_i2c_write_2(sc, I2C_REG_STATUS, 0xffff);
+	ti_i2c_write_2(sc, I2C_REG_CON, 0);
+
+	/* Release the interrupt handler. */
+	if (sc->sc_irq_h != NULL) {
+		bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_irq_h);
+		sc->sc_irq_h = NULL;
+	}
+
+	bus_generic_detach(sc->sc_dev);
+
+	/* Unmap the I2C controller registers. */
+	if (sc->sc_mem_res != NULL) {
+		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
+		sc->sc_mem_res = NULL;
+	}
+
+	/* Release the IRQ resource. */
+	if (sc->sc_irq_res != NULL) {
+		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res);
+		sc->sc_irq_res = NULL;
+	}
+
+	/* Finally disable the functional and interface clocks. */
+	clk = I2C0_CLK + sc->device_id;
+	ti_prcm_clk_disable(clk);
+}
+
+static int
+ti_i2c_sysctl_clk(SYSCTL_HANDLER_ARGS)
+{
+	device_t dev;
+	int clk, psc, sclh, scll;
+	struct ti_i2c_softc *sc;
+
+	dev = (device_t)arg1;
+	sc = device_get_softc(dev);
+
+	TI_I2C_LOCK(sc);
+	/* Get the system prescaler value. */
+	psc = (int)ti_i2c_read_2(sc, I2C_REG_PSC) + 1;
+
+	/* Get the bitrate. */
+	scll = (int)ti_i2c_read_2(sc, I2C_REG_SCLL) & I2C_SCLL_MASK;
+	sclh = (int)ti_i2c_read_2(sc, I2C_REG_SCLH) & I2C_SCLH_MASK;
+
+	clk = I2C_CLK / psc / (scll + 7 + sclh + 5);
+	TI_I2C_UNLOCK(sc);
+
+	return (sysctl_handle_int(oidp, &clk, 0, req));
+}
+
+static int
+ti_i2c_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+	if (!ofw_bus_is_compatible(dev, "ti,i2c"))
+		return (ENXIO);
+	device_set_desc(dev, "TI I2C Controller");
+
+	return (0);
+}
+
+static int
+ti_i2c_attach(device_t dev)
+{
+	int err, rid;
+	phandle_t node;
+	struct ti_i2c_softc *sc;
+	struct sysctl_ctx_list *ctx;
+	struct sysctl_oid_list *tree;
+	uint16_t fifosz;
+
+ 	sc = device_get_softc(dev);
+	sc->sc_dev = dev;
+
+	/* Get the i2c device id from FDT. */
+	node = ofw_bus_get_node(dev);
+	if ((OF_getencprop(node, "i2c-device-id", &sc->device_id,
+	    sizeof(sc->device_id))) <= 0) {
+		device_printf(dev, "missing i2c-device-id attribute in FDT\n");
+		return (ENXIO);
+	}
+
+	/* Get the memory resource for the register mapping. */
+	rid = 0;
+	sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	    RF_ACTIVE);
+	if (sc->sc_mem_res == NULL) {
+		device_printf(dev, "Cannot map registers.\n");
+		return (ENXIO);
+	}
+
+	/* Allocate our IRQ resource. */
+	rid = 0;
+	sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+	    RF_ACTIVE | RF_SHAREABLE);
+	if (sc->sc_irq_res == NULL) {
+		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
+		device_printf(dev, "Cannot allocate interrupt.\n");
+		return (ENXIO);
+	}
+
+	TI_I2C_LOCK_INIT(sc);
+
+	/* First of all, we _must_ activate the H/W. */
+	err = ti_i2c_activate(dev);
+	if (err) {
+		device_printf(dev, "ti_i2c_activate failed\n");
+		goto out;
+	}
+
+	/* Read the version number of the I2C module */
+	sc->sc_rev = ti_i2c_read_2(sc, I2C_REG_REVNB_HI) & 0xff;
+
+	/* Get the fifo size. */
+	fifosz = ti_i2c_read_2(sc, I2C_REG_BUFSTAT);
+	fifosz >>= I2C_BUFSTAT_FIFODEPTH_SHIFT;
+	fifosz &= I2C_BUFSTAT_FIFODEPTH_MASK;
+
+	device_printf(dev, "I2C revision %d.%d FIFO size: %d bytes\n",
+	    sc->sc_rev >> 4, sc->sc_rev & 0xf, 8 << fifosz);
+
+	/* Set the FIFO threshold to 5 for now. */
+	sc->sc_fifo_trsh = 5;
+
+	ctx = device_get_sysctl_ctx(dev);
+	tree = SYSCTL_CHILDREN(device_get_sysctl_tree(dev));
+	SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "i2c_clock",
+	    CTLFLAG_RD | CTLTYPE_UINT | CTLFLAG_MPSAFE, dev, 0,
+	    ti_i2c_sysctl_clk, "IU", "I2C bus clock");
+
+	/* Activate the interrupt. */
+	err = bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
+	    NULL, ti_i2c_intr, sc, &sc->sc_irq_h);
+	if (err)
+		goto out;
+
+	/* Attach the iicbus. */
+	if ((sc->sc_iicbus = device_add_child(dev, "iicbus", -1)) == NULL) {
+		device_printf(dev, "could not allocate iicbus instance\n");
+		err = ENXIO;
+		goto out;
+	}
+
+	/* Probe and attach the iicbus */
+	bus_generic_attach(dev);
+
+out:
+	if (err) {
+		ti_i2c_deactivate(dev);
+		TI_I2C_LOCK_DESTROY(sc);
+	}
+
+	return (err);
+}
+
+static int
+ti_i2c_detach(device_t dev)
+{
+	struct ti_i2c_softc *sc;
+	int rv;
+
+ 	sc = device_get_softc(dev);
+	ti_i2c_deactivate(dev);
+	TI_I2C_LOCK_DESTROY(sc);
+	if (sc->sc_iicbus &&
+	    (rv = device_delete_child(dev, sc->sc_iicbus)) != 0)
+		return (rv);
+
+	return (0);
+}
+
+static phandle_t
+ti_i2c_get_node(device_t bus, device_t dev)
+{
+
+	/* Share controller node with iibus device. */
+	return (ofw_bus_get_node(bus));
+}
+
+static device_method_t ti_i2c_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		ti_i2c_probe),
+	DEVMETHOD(device_attach,	ti_i2c_attach),
+	DEVMETHOD(device_detach,	ti_i2c_detach),
+
+	/* OFW methods */
+	DEVMETHOD(ofw_bus_get_node,	ti_i2c_get_node),
+
+	/* iicbus interface */
+	DEVMETHOD(iicbus_callback,	ti_i2c_callback),
+	DEVMETHOD(iicbus_reset,		ti_i2c_iicbus_reset),
+	DEVMETHOD(iicbus_transfer,	ti_i2c_transfer),
+
+	DEVMETHOD_END
+};
+
+static driver_t ti_i2c_driver = {
+	"iichb",
+	ti_i2c_methods,
+	sizeof(struct ti_i2c_softc),
+};
+
+static devclass_t ti_i2c_devclass;
+
+DRIVER_MODULE(ti_iic, simplebus, ti_i2c_driver, ti_i2c_devclass, 0, 0);
+DRIVER_MODULE(iicbus, ti_iic, iicbus_driver, iicbus_devclass, 0, 0);
+
+MODULE_DEPEND(ti_iic, ti_prcm, 1, 1, 1);
+MODULE_DEPEND(ti_iic, iicbus, 1, 1, 1);


Property changes on: trunk/sys/arm/ti/ti_i2c.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/ti_i2c.h
===================================================================
--- trunk/sys/arm/ti/ti_i2c.h	                        (rev 0)
+++ trunk/sys/arm/ti/ti_i2c.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,132 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2011
+ *	Ben Gray <ben.r.gray at gmail.com>.
+ * 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 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 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: stable/10/sys/arm/ti/ti_i2c.h 273735 2014-10-27 12:18:07Z loos $
+ */
+
+#ifndef _TI_I2C_H_
+#define	_TI_I2C_H_
+
+/**
+ * Header file for the OMAP I2C driver.
+ *
+ * Simply contains register bit flags.
+ */
+
+/*
+ * OMAP4 I2C Registers, Summary 1
+ */
+#define	I2C_REG_IE		0x84
+#define		I2C_IE_XDR		(1UL << 14)   /* Transmit draining interrupt */
+#define		I2C_IE_RDR		(1UL << 13)   /* Receive draining interrupt */
+#define		I2C_IE_AAS		(1UL << 9)    /* Addressed as Slave interrupt */
+#define		I2C_IE_BF		(1UL << 8)    /* Bus Free interrupt */
+#define		I2C_IE_AERR		(1UL << 7)    /* Access Error interrupt */
+#define		I2C_IE_STC		(1UL << 6)    /* Start Condition interrupt */
+#define		I2C_IE_GC		(1UL << 5)    /* General Call interrupt */
+#define		I2C_IE_XRDY		(1UL << 4)    /* Transmit Data Ready interrupt */
+#define		I2C_IE_RRDY		(1UL << 3)    /* Receive Data Ready interrupt */
+#define		I2C_IE_ARDY		(1UL << 2)    /* Register Access Ready interrupt */
+#define		I2C_IE_NACK		(1UL << 1)    /* No Acknowledgment interrupt */
+#define		I2C_IE_AL		(1UL << 0)    /* Arbitration Lost interrupt */
+#define	I2C_REG_STAT		0x88
+#define		I2C_STAT_XDR		(1UL << 14)
+#define		I2C_STAT_RDR		(1UL << 13)
+#define		I2C_STAT_BB		(1UL << 12)
+#define		I2C_STAT_ROVR		(1UL << 11)
+#define		I2C_STAT_XUDF		(1UL << 10)
+#define		I2C_STAT_AAS		(1UL << 9)
+#define		I2C_STAT_BF		(1UL << 8)
+#define		I2C_STAT_AERR		(1UL << 7)
+#define		I2C_STAT_STC		(1UL << 6)
+#define		I2C_STAT_GC		(1UL << 5)
+#define		I2C_STAT_XRDY		(1UL << 4)
+#define		I2C_STAT_RRDY		(1UL << 3)
+#define		I2C_STAT_ARDY		(1UL << 2)
+#define		I2C_STAT_NACK		(1UL << 1)
+#define		I2C_STAT_AL		(1UL << 0)
+#define	I2C_REG_SYSS		0x90
+#define		I2C_SYSS_RDONE		(1UL << 0)
+#define	I2C_REG_BUF		0x94
+#define		I2C_BUF_RXFIFO_CLR	(1UL << 14)
+#define		I2C_BUF_TXFIFO_CLR	(1UL << 6)
+#define		I2C_BUF_RXTRSH_SHIFT	8
+#define		I2C_BUF_TRSH_MASK	0x3f
+#define	I2C_REG_CNT		0x98
+#define	I2C_REG_DATA		0x9c
+#define	I2C_REG_CON		0xa4
+#define		I2C_CON_I2C_EN		(1UL << 15)
+#define		I2C_CON_OPMODE_STD	(0UL << 12)
+#define		I2C_CON_OPMODE_HS	(1UL << 12)
+#define		I2C_CON_OPMODE_SCCB	(2UL << 12)
+#define		I2C_CON_OPMODE_MASK	(3UL << 13)
+#define		I2C_CON_I2C_STB		(1UL << 11)
+#define		I2C_CON_MST		(1UL << 10)
+#define		I2C_CON_TRX		(1UL << 9)
+#define		I2C_CON_XSA		(1UL << 8)
+#define		I2C_CON_XOA0		(1UL << 7)
+#define		I2C_CON_XOA1		(1UL << 6)
+#define		I2C_CON_XOA2		(1UL << 5)
+#define		I2C_CON_XOA3		(1UL << 4)
+#define		I2C_CON_STP		(1UL << 1)
+#define		I2C_CON_STT		(1UL << 0)
+#define	I2C_REG_OA0		0xa8
+#define	I2C_REG_SA		0xac
+#define	I2C_REG_PSC		0xb0
+#define		I2C_PSC_MASK		0xff
+#define	I2C_REG_SCLL		0xb4
+#define		I2C_SCLL_MASK		0xff
+#define		I2C_HSSCLL_SHIFT	8
+#define	I2C_REG_SCLH		0xb8
+#define		I2C_SCLH_MASK		0xff
+#define		I2C_HSSCLH_SHIFT	8
+#define	I2C_REG_SYSTEST		0xbc
+#define	I2C_REG_BUFSTAT		0xc0
+#define		I2C_BUFSTAT_FIFODEPTH_MASK	0x3
+#define		I2C_BUFSTAT_FIFODEPTH_SHIFT	14
+#define	I2C_REG_OA1		0xc4
+#define	I2C_REG_OA2		0xc8
+#define	I2C_REG_OA3		0xcc
+#define	I2C_REG_ACTOA		0xd0
+#define	I2C_REG_SBLOCK		0xd4
+
+/*
+ * OMAP4 I2C Registers, Summary 2 
+ */
+#define	I2C_REG_REVNB_LO	0x00
+#define	I2C_REG_REVNB_HI	0x04
+#define	I2C_REG_SYSC		0x10
+#define		I2C_REG_SYSC_SRST	(1UL << 1)
+#define	I2C_REG_STATUS_RAW	0x24
+#define	I2C_REG_STATUS		0x28
+#define	I2C_REG_IRQENABLE_SET	0x2C
+#define	I2C_REG_IRQENABLE_CLR	0x30
+
+#define	I2C_CLK			96000000UL	/* 96MHz */
+#define	I2C_ICLK		12000000UL	/* 12MHz */
+
+#endif /* _TI_I2C_H_ */


Property changes on: trunk/sys/arm/ti/ti_i2c.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/ti_machdep.c
===================================================================
--- trunk/sys/arm/ti/ti_machdep.c	                        (rev 0)
+++ trunk/sys/arm/ti/ti_machdep.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,129 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 1994-1998 Mark Brinicombe.
+ * Copyright (c) 1994 Brini.
+ * All rights reserved.
+ *
+ * This code is derived from software written for Brini by Mark Brinicombe
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by Brini.
+ * 4. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BRINI ``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 BRINI 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.
+ *
+ * from: FreeBSD: //depot/projects/arm/src/sys/arm/at91/kb920x_machdep.c, rev 45
+ */
+
+#include "opt_platform.h"
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/ti/ti_machdep.c 266084 2014-05-14 19:18:58Z ian $");
+
+#define _ARM32_BUS_DMA_PRIVATE
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <machine/bus.h>
+#include <machine/devmap.h>
+#include <machine/machdep.h>
+
+#include <arm/ti/omap4/omap4_reg.h>
+
+void (*ti_cpu_reset)(void) = NULL;
+
+vm_offset_t
+initarm_lastaddr(void)
+{
+
+	return (arm_devmap_lastaddr());
+}
+
+void
+initarm_early_init(void)
+{
+}
+
+void
+initarm_gpio_init(void)
+{
+}
+
+void
+initarm_late_init(void)
+{
+}
+
+/*
+ * Construct static devmap entries to map out the most frequently used
+ * peripherals using 1mb section mappings.
+ */
+int
+initarm_devmap_init(void)
+{
+#if defined(SOC_OMAP4)
+	arm_devmap_add_entry(0x48000000, 0x01000000); /*16mb L4_PER devices */
+	arm_devmap_add_entry(0x4A000000, 0x01000000); /*16mb L4_CFG devices */
+#elif defined(SOC_TI_AM335X)
+	arm_devmap_add_entry(0x44C00000, 0x00400000); /* 4mb L4_WKUP devices*/
+	arm_devmap_add_entry(0x47400000, 0x00100000); /* 1mb USB            */
+	arm_devmap_add_entry(0x47800000, 0x00100000); /* 1mb mmchs2         */
+	arm_devmap_add_entry(0x48000000, 0x01000000); /*16mb L4_PER devices */
+	arm_devmap_add_entry(0x49000000, 0x00100000); /* 1mb edma3          */
+	arm_devmap_add_entry(0x49800000, 0x00300000); /* 3mb edma3          */
+	arm_devmap_add_entry(0x4A000000, 0x01000000); /*16mb L4_FAST devices*/
+#else
+#error "Unknown SoC"
+#endif
+	return (0);
+}
+
+struct arm32_dma_range *
+bus_dma_get_range(void)
+{
+
+	return (NULL);
+}
+
+int
+bus_dma_get_range_nb(void)
+{
+
+	return (0);
+}
+
+void
+cpu_reset()
+{
+	if (ti_cpu_reset)
+		(*ti_cpu_reset)();
+	else
+		printf("no cpu_reset implementation\n");
+	printf("Reset failed!\n");
+	while (1);
+}


Property changes on: trunk/sys/arm/ti/ti_machdep.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/ti_mbox.c
===================================================================
--- trunk/sys/arm/ti/ti_mbox.c	                        (rev 0)
+++ trunk/sys/arm/ti/ti_mbox.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,267 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Rui Paulo <rpaulo at FreeBSD.org>
+ * 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 ``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 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: stable/10/sys/arm/ti/ti_mbox.c 266152 2014-05-15 16:11:06Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/timeet.h>
+#include <sys/timetc.h>
+#include <sys/watchdog.h>
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/frame.h>
+#include <machine/intr.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+
+#include <arm/ti/ti_mbox.h>
+#include <arm/ti/ti_prcm.h>
+
+#include "mbox_if.h"
+
+#define DEBUG
+#ifdef DEBUG
+#define	DPRINTF(fmt, ...)	do {	\
+	printf("%s: ", __func__);	\
+	printf(fmt, __VA_ARGS__);	\
+} while (0)
+#else
+#define	DPRINTF(fmt, ...)
+#endif
+
+static device_probe_t		ti_mbox_probe;
+static device_attach_t		ti_mbox_attach;
+static device_detach_t		ti_mbox_detach;
+static void			ti_mbox_intr(void *);
+static int			ti_mbox_read(device_t, int, uint32_t *);
+static int			ti_mbox_write(device_t, int, uint32_t);
+
+struct ti_mbox_softc {
+	struct mtx		sc_mtx;
+	struct resource		*sc_mem_res;
+	struct resource		*sc_irq_res;
+	void			*sc_intr;
+	bus_space_tag_t		sc_bt;
+	bus_space_handle_t	sc_bh;
+};
+
+#define	TI_MBOX_LOCK(sc)	mtx_lock(&(sc)->sc_mtx)
+#define	TI_MBOX_UNLOCK(sc)	mtx_unlock(&(sc)->sc_mtx)
+
+static device_method_t ti_mbox_methods[] = {
+	DEVMETHOD(device_probe,		ti_mbox_probe),
+	DEVMETHOD(device_attach,	ti_mbox_attach),
+	DEVMETHOD(device_detach,	ti_mbox_detach),
+
+	DEVMETHOD(mbox_read,		ti_mbox_read),
+	DEVMETHOD(mbox_write,		ti_mbox_write),
+
+	DEVMETHOD_END
+};
+
+static driver_t ti_mbox_driver = {
+	"ti_mbox",
+	ti_mbox_methods,
+	sizeof(struct ti_mbox_softc)
+};
+
+static devclass_t ti_mbox_devclass;
+
+DRIVER_MODULE(ti_mbox, simplebus, ti_mbox_driver, ti_mbox_devclass, 0, 0);
+
+static __inline uint32_t
+ti_mbox_reg_read(struct ti_mbox_softc *sc, uint16_t reg)
+{
+	return (bus_space_read_4(sc->sc_bt, sc->sc_bh, reg));
+}
+
+static __inline void
+ti_mbox_reg_write(struct ti_mbox_softc *sc, uint16_t reg, uint32_t val)
+{
+	bus_space_write_4(sc->sc_bt, sc->sc_bh, reg, val);
+}
+
+static int
+ti_mbox_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (ofw_bus_is_compatible(dev, "ti,system-mbox")) {
+		device_set_desc(dev, "TI System Mailbox");
+		return (BUS_PROBE_DEFAULT);
+	}
+
+	return (ENXIO);
+}
+
+static int
+ti_mbox_attach(device_t dev)
+{
+	struct ti_mbox_softc *sc;
+	int rid, delay, chan;
+	uint32_t rev, sysconfig;
+
+	if (ti_prcm_clk_enable(MAILBOX0_CLK) != 0) {
+		device_printf(dev, "could not enable MBOX clock\n");
+		return (ENXIO);
+	}
+	sc = device_get_softc(dev);
+	rid = 0;
+	mtx_init(&sc->sc_mtx, "TI mbox", NULL, MTX_DEF);
+	sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	    RF_ACTIVE);
+	if (sc->sc_mem_res == NULL) {
+		device_printf(dev, "could not allocate memory resource\n");
+		return (ENXIO);
+	}
+	sc->sc_bt = rman_get_bustag(sc->sc_mem_res);
+	sc->sc_bh = rman_get_bushandle(sc->sc_mem_res);
+	rid = 0;
+	sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+	    RF_ACTIVE);
+	if (sc->sc_irq_res == NULL) {
+		device_printf(dev, "could not allocate interrupt resource\n");
+		ti_mbox_detach(dev);
+		return (ENXIO);
+	}
+	if (bus_setup_intr(dev, sc->sc_irq_res, INTR_MPSAFE | INTR_TYPE_MISC,
+	    NULL, ti_mbox_intr, sc, &sc->sc_intr) != 0) {
+		device_printf(dev, "unable to setup the interrupt handler\n");
+		ti_mbox_detach(dev);
+		return (ENXIO);
+	}
+	/*
+	 * Reset the controller.
+	 */
+	sysconfig = ti_mbox_reg_read(sc, TI_MBOX_SYSCONFIG);
+	DPRINTF("initial sysconfig %d\n", sysconfig);
+	sysconfig |= TI_MBOX_SYSCONFIG_SOFTRST;
+	delay = 100;
+	while (ti_mbox_reg_read(sc, TI_MBOX_SYSCONFIG) & 
+	    TI_MBOX_SYSCONFIG_SOFTRST) {
+		delay--;
+		DELAY(10);
+	}
+	if (delay == 0) {
+		device_printf(dev, "controller reset failed\n");
+		ti_mbox_detach(dev);
+		return (ENXIO);
+	}
+	/*
+	 * Enable smart idle mode.
+	 */
+	ti_mbox_reg_write(sc, TI_MBOX_SYSCONFIG,
+	    ti_mbox_reg_read(sc, TI_MBOX_SYSCONFIG) | TI_MBOX_SYSCONFIG_SMARTIDLE);
+	rev = ti_mbox_reg_read(sc, TI_MBOX_REVISION);
+	DPRINTF("rev %d\n", rev);
+	device_printf(dev, "revision %d.%d\n", (rev >> 8) & 0x4, rev & 0x40);
+	/*
+	 * Enable message interrupts.
+	 */
+	for (chan = 0; chan < 8; chan++)
+		ti_mbox_reg_write(sc, TI_MBOX_IRQENABLE_SET(chan), 1);
+
+	return (0);
+}
+
+static int
+ti_mbox_detach(device_t dev)
+{
+	struct ti_mbox_softc *sc;
+
+	sc = device_get_softc(dev);
+	if (sc->sc_intr)
+		bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_intr);
+	if (sc->sc_irq_res)
+		bus_release_resource(dev, SYS_RES_IRQ, rman_get_rid(sc->sc_irq_res),
+		    sc->sc_irq_res);
+	if (sc->sc_mem_res)
+		bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(sc->sc_mem_res),
+		    sc->sc_mem_res);
+
+	return (0);
+}
+
+static void
+ti_mbox_intr(void *arg)
+{
+	struct ti_mbox_softc *sc;
+
+	sc = arg;
+	DPRINTF("interrupt %p", sc);
+}
+
+static int
+ti_mbox_read(device_t dev, int chan, uint32_t *data)
+{
+	struct ti_mbox_softc *sc;
+
+	if (chan < 0 || chan > 7)
+		return (EINVAL);
+	sc = device_get_softc(dev);
+
+	return (ti_mbox_reg_read(sc, TI_MBOX_MESSAGE(chan)));
+}
+
+static int
+ti_mbox_write(device_t dev, int chan, uint32_t data)
+{
+	int limit = 500;
+	struct ti_mbox_softc *sc;
+
+	if (chan < 0 || chan > 7)
+		return (EINVAL);
+	sc = device_get_softc(dev);
+	TI_MBOX_LOCK(sc);
+	/* XXX implement interrupt method */
+	while (ti_mbox_reg_read(sc, TI_MBOX_FIFOSTATUS(chan)) == 1 && 
+	    limit--) {
+		DELAY(10);
+	}
+	if (limit == 0) {
+		device_printf(dev, "FIFOSTAUS%d stuck\n", chan);
+		TI_MBOX_UNLOCK(sc);
+		return (EAGAIN);
+	}
+	ti_mbox_reg_write(sc, TI_MBOX_MESSAGE(chan), data);
+
+	return (0);
+}


Property changes on: trunk/sys/arm/ti/ti_mbox.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/ti_mbox.h
===================================================================
--- trunk/sys/arm/ti/ti_mbox.h	                        (rev 0)
+++ trunk/sys/arm/ti/ti_mbox.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,45 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Rui Paulo <rpaulo at FreeBSD.org>
+ * 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 ``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 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: stable/10/sys/arm/ti/ti_mbox.h 266098 2014-05-14 23:57:07Z ian $
+ */
+
+#ifndef _TI_MBOX_H_
+#define _TI_MBOX_H_
+
+#define	TI_MBOX_REVISION		0x00
+#define	TI_MBOX_SYSCONFIG		0x10
+#define	TI_MBOX_SYSCONFIG_SOFTRST	0x01
+#define	TI_MBOX_SYSCONFIG_SMARTIDLE	(0x02 << 2)
+#define	TI_MBOX_MESSAGE(n)		(0x40 + (n) * 0x4)
+#define	TI_MBOX_FIFOSTATUS(n)		(0x80 + (n) * 0x4)
+#define	TI_MBOX_MSGSTATUS(n)		(0xc0 + (n) * 0x4)
+#define	TI_MBOX_IRQSTATUS_RAW(n)	(0x100 + (n) * 0x10)
+#define	TI_MBOX_IRQSTATUS_CLR(n)	(0x104 + (n) * 0x10)
+#define	TI_MBOX_IRQENABLE_SET(n)	(0x108 + (n) * 0x10)
+#define	TI_MBOX_IRQENABLE_CLR(n)	(0x10c + (n) * 0x10)
+
+#endif /* _TI_MBOX_H_ */


Property changes on: trunk/sys/arm/ti/ti_mbox.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/ti_mmchs.c
===================================================================
--- trunk/sys/arm/ti/ti_mmchs.c	                        (rev 0)
+++ trunk/sys/arm/ti/ti_mmchs.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,1844 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2011
+ *	Ben Gray <ben.r.gray at gmail.com>.
+ * 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 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 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.
+ */
+
+/**
+ * Driver for the MMC/SD/SDIO module on the TI OMAP series of SoCs.
+ *
+ * This driver is heavily based on the SD/MMC driver for the AT91 (at91_mci.c).
+ *
+ * It's important to realise that the MMC state machine is already in the kernel
+ * and this driver only exposes the specific interfaces of the controller.
+ *
+ * This driver is still very much a work in progress, I've verified that basic
+ * sector reading can be performed. But I've yet to test it with a file system
+ * or even writing.  In addition I've only tested the driver with an SD card,
+ * I've no idea if MMC cards work.
+ *
+ */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/ti/ti_mmchs.c 266159 2014-05-15 16:59:47Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bio.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/endian.h>
+#include <sys/kernel.h>
+#include <sys/kthread.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/queue.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+#include <sys/time.h>
+#include <sys/timetc.h>
+#include <sys/gpio.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+#include <machine/resource.h>
+#include <machine/intr.h>
+
+#include <dev/mmc/bridge.h>
+#include <dev/mmc/mmcreg.h>
+#include <dev/mmc/mmcbrvar.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include "gpio_if.h"
+
+#include "mmcbr_if.h"
+#include "mmcbus_if.h"
+
+#include <arm/ti/ti_sdma.h>
+#include <arm/ti/ti_edma3.h>
+#include <arm/ti/ti_mmchs.h>
+#include <arm/ti/ti_cpuid.h>
+#include <arm/ti/ti_prcm.h>
+
+#include <arm/ti/twl/twl.h>
+#include <arm/ti/twl/twl_vreg.h>
+
+#ifdef DEBUG
+#define ti_mmchs_dbg(sc, fmt, args...) \
+	device_printf((sc)->sc_dev, fmt, ## args);
+#else
+#define ti_mmchs_dbg(sc, fmt, args...)
+#endif
+
+/**
+ *	Structure that stores the driver context
+ */
+struct ti_mmchs_softc {
+	device_t		sc_dev;
+	uint32_t		device_id;
+	struct resource*	sc_irq_res;
+	struct resource*	sc_mem_res;
+
+	void*			sc_irq_h;
+
+	bus_dma_tag_t		sc_dmatag;
+	bus_dmamap_t		sc_dmamap;
+	int			sc_dmamapped;
+
+	unsigned int		sc_dmach_rd;
+	unsigned int		sc_dmach_wr;
+	int			dma_rx_trig;
+	int			dma_tx_trig;
+
+	device_t		sc_gpio_dev;
+	int			sc_wp_gpio_pin;  /* GPIO pin for MMC write protect */
+
+	device_t		sc_vreg_dev;
+	const char*		sc_vreg_name;
+
+	struct mtx		sc_mtx;
+
+	struct mmc_host		host;
+	struct mmc_request*	req;
+	struct mmc_command*	curcmd;
+
+	int			flags;
+#define CMD_STARTED     1
+#define STOP_STARTED    2
+
+	int			bus_busy;  /* TODO: Needed ? */
+
+	void*			sc_cmd_data_vaddr;
+	int			sc_cmd_data_len;
+
+	/* The offset applied to each of the register base addresses, OMAP4
+	 * register sets are offset 0x100 from the OMAP3 series.
+	 */
+	unsigned long		sc_reg_off;
+
+	/* The physical address of the MMCHS_DATA register, used for the DMA xfers */
+	unsigned long		sc_data_reg_paddr;
+
+	/* The reference clock frequency */
+	unsigned int		sc_ref_freq;
+
+	enum mmc_power_mode	sc_cur_power_mode;
+};
+
+/**
+ *	Macros for driver mutex locking
+ */
+#define TI_MMCHS_LOCK(_sc)              mtx_lock(&(_sc)->sc_mtx)
+#define	TI_MMCHS_UNLOCK(_sc)            mtx_unlock(&(_sc)->sc_mtx)
+#define TI_MMCHS_LOCK_INIT(_sc) \
+	mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->sc_dev), \
+	         "ti_mmchs", MTX_DEF)
+#define TI_MMCHS_LOCK_DESTROY(_sc)      mtx_destroy(&_sc->sc_mtx);
+#define TI_MMCHS_ASSERT_LOCKED(_sc)     mtx_assert(&_sc->sc_mtx, MA_OWNED);
+#define TI_MMCHS_ASSERT_UNLOCKED(_sc)   mtx_assert(&_sc->sc_mtx, MA_NOTOWNED);
+
+static void ti_mmchs_start(struct ti_mmchs_softc *sc);
+
+/**
+ *	ti_mmchs_read_4 - reads a 32-bit value from a register
+ *	ti_mmchs_write_4 - writes a 32-bit value to a register
+ *	@sc: pointer to the driver context
+ *	@off: register offset to read from
+ *	@val: the value to write into the register
+ *
+ *	LOCKING:
+ *	None
+ *
+ *	RETURNS:
+ *	The 32-bit value read from the register
+ */
+static inline uint32_t
+ti_mmchs_read_4(struct ti_mmchs_softc *sc, bus_size_t off)
+{
+	return bus_read_4(sc->sc_mem_res, (sc->sc_reg_off + off));
+}
+
+static inline void
+ti_mmchs_write_4(struct ti_mmchs_softc *sc, bus_size_t off, uint32_t val)
+{
+	bus_write_4(sc->sc_mem_res, (sc->sc_reg_off + off), val);
+}
+
+/**
+ *	ti_mmchs_reset_controller -
+ *	@arg: caller supplied arg
+ *	@segs: array of segments (although in our case should only be one)
+ *	@nsegs: number of segments (in our case should be 1)
+ *	@error:
+ *
+ *
+ *
+ */
+static void
+ti_mmchs_reset_controller(struct ti_mmchs_softc *sc, uint32_t bit)
+{
+	unsigned long attempts;
+	uint32_t sysctl;
+
+	ti_mmchs_dbg(sc, "reseting controller - bit 0x%08x\n", bit);
+
+	sysctl = ti_mmchs_read_4(sc, MMCHS_SYSCTL);
+	ti_mmchs_write_4(sc, MMCHS_SYSCTL, sysctl | bit);
+	/* 
+	 * AM335x and OMAP4 >= ES2 have an updated reset logic.
+	 * Monitor a 0->1 transition first.
+	 */
+	if ((ti_chip() == CHIP_AM335X) || 
+	    ((ti_chip() == CHIP_OMAP_4) && (ti_revision() > OMAP4430_REV_ES1_0))) {
+		attempts = 10000;
+		while (!(ti_mmchs_read_4(sc, MMCHS_SYSCTL) & bit) && (attempts-- > 0))
+			continue;
+	}
+
+	attempts = 10000;
+	while ((ti_mmchs_read_4(sc, MMCHS_SYSCTL) & bit) && (attempts-- > 0))
+		continue;
+
+	if (ti_mmchs_read_4(sc, MMCHS_SYSCTL) & bit)
+		device_printf(sc->sc_dev, "Error - Timeout waiting on controller reset\n");
+}
+
+/**
+ *	ti_mmchs_getaddr - called by the DMA function to simply return the phys addr
+ *	@arg: caller supplied arg
+ *	@segs: array of segments (although in our case should only be one)
+ *	@nsegs: number of segments (in our case should be 1)
+ *	@error:
+ *
+ *	This function is called by bus_dmamap_load() after it has compiled an array
+ *	of segments, each segment is a phsyical chunk of memory. However in our case
+ *	we should only have one segment, because we don't (yet?) support DMA scatter
+ *	gather. To ensure we only have one segment, the DMA tag was created by
+ *	bus_dma_tag_create() (called from ti_mmchs_attach) with nsegments set to 1.
+ *
+ */
+static void
+ti_mmchs_getaddr(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
+{
+	if (error != 0)
+		return;
+
+	*(bus_addr_t *)arg = segs[0].ds_addr;
+}
+
+#ifndef SOC_TI_AM335X
+/**
+ *	ti_mmchs_dma_intr - interrupt handler for DMA events triggered by the controller
+ *	@ch: the dma channel number
+ *	@status: bit field of the status bytes
+ *	@data: callback data, in this case a pointer to the controller struct
+ *
+ *
+ *	LOCKING:
+ *	Called from interrupt context
+ *
+ */
+static void
+ti_mmchs_dma_intr(unsigned int ch, uint32_t status, void *data)
+{
+	/* Ignore for now ... we don't need this interrupt as we already have the
+	 * interrupt from the MMC controller.
+	 */
+}
+#endif
+
+/**
+ *	ti_mmchs_intr_xfer_compl - called if a 'transfer complete' IRQ was received
+ *	@sc: pointer to the driver context
+ *	@cmd: the command that was sent previously
+ *
+ *	This function is simply responsible for syncing up the DMA buffer.
+ *
+ *	LOCKING:
+ *	Called from interrupt context
+ *
+ *	RETURNS:
+ *	Return value indicates if the transaction is complete, not done = 0, done != 0
+ */
+static int
+ti_mmchs_intr_xfer_compl(struct ti_mmchs_softc *sc, struct mmc_command *cmd)
+{
+	uint32_t cmd_reg;
+
+	/* Read command register to test whether this command was a read or write. */
+	cmd_reg = ti_mmchs_read_4(sc, MMCHS_CMD);
+
+	/* Sync-up the DMA buffer so the caller can access the new memory */
+	if (cmd_reg & MMCHS_CMD_DDIR) {
+		bus_dmamap_sync(sc->sc_dmatag, sc->sc_dmamap, BUS_DMASYNC_POSTREAD);
+		bus_dmamap_unload(sc->sc_dmatag, sc->sc_dmamap);
+	}
+	else {
+		bus_dmamap_sync(sc->sc_dmatag, sc->sc_dmamap, BUS_DMASYNC_POSTWRITE);
+		bus_dmamap_unload(sc->sc_dmatag, sc->sc_dmamap);
+	}
+	sc->sc_dmamapped--;
+
+	/* Debugging dump of the data received */
+#if 0
+	{
+		int i;
+		uint8_t *p = (uint8_t*) sc->sc_cmd_data_vaddr;
+		for (i=0; i<sc->sc_cmd_data_len; i++) {
+			if ((i % 16) == 0)
+				printf("\n0x%04x : ", i);
+			printf("%02X ", *p++);
+		}
+		printf("\n");
+	}
+#endif
+
+	/* We are done, transfer complete */
+	return 1;
+}
+
+/**
+ *	ti_mmchs_intr_cmd_compl - called if a 'command complete' IRQ was received
+ *	@sc: pointer to the driver context
+ *	@cmd: the command that was sent previously
+ *
+ *
+ *	LOCKING:
+ *	Called from interrupt context
+ *
+ *	RETURNS:
+ *	Return value indicates if the transaction is complete, not done = 0, done != 0
+ */
+static int
+ti_mmchs_intr_cmd_compl(struct ti_mmchs_softc *sc, struct mmc_command *cmd)
+{
+	uint32_t cmd_reg;
+
+	/* Copy the response into the request struct ... if a response was
+	 * expected */
+	if (cmd != NULL && (cmd->flags & MMC_RSP_PRESENT)) {
+		if (cmd->flags & MMC_RSP_136) {
+			cmd->resp[3] = ti_mmchs_read_4(sc, MMCHS_RSP10);
+			cmd->resp[2] = ti_mmchs_read_4(sc, MMCHS_RSP32);
+			cmd->resp[1] = ti_mmchs_read_4(sc, MMCHS_RSP54);
+			cmd->resp[0] = ti_mmchs_read_4(sc, MMCHS_RSP76);
+		} else {
+			cmd->resp[0] = ti_mmchs_read_4(sc, MMCHS_RSP10);
+		}
+	}
+
+	/* Check if the command was expecting some data transfer, if not
+	 * we are done. */
+	cmd_reg = ti_mmchs_read_4(sc, MMCHS_CMD);
+	return ((cmd_reg & MMCHS_CMD_DP) == 0);
+}
+
+/**
+ *	ti_mmchs_intr_error - handles error interrupts
+ *	@sc: pointer to the driver context
+ *	@cmd: the command that was sent previously
+ *	@stat_reg: the value that was in the status register
+ *
+ *
+ *	LOCKING:
+ *	Called from interrupt context
+ *
+ *	RETURNS:
+ *	Return value indicates if the transaction is complete, not done = 0, done != 0
+ */
+static int
+ti_mmchs_intr_error(struct ti_mmchs_softc *sc, struct mmc_command *cmd,
+					 uint32_t stat_reg)
+{
+	ti_mmchs_dbg(sc, "error in xfer - stat 0x%08x\n", stat_reg);
+
+	/* Ignore CRC errors on CMD2 and ACMD47, per relevant standards */
+	if ((stat_reg & MMCHS_STAT_CCRC) && (cmd->opcode == MMC_SEND_OP_COND ||
+	    cmd->opcode == ACMD_SD_SEND_OP_COND))
+		cmd->error = MMC_ERR_NONE;
+	else if (stat_reg & (MMCHS_STAT_CTO | MMCHS_STAT_DTO))
+		cmd->error = MMC_ERR_TIMEOUT;
+	else if (stat_reg & (MMCHS_STAT_CCRC | MMCHS_STAT_DCRC))
+		cmd->error = MMC_ERR_BADCRC;
+	else
+		cmd->error = MMC_ERR_FAILED;
+
+	/* If a dma transaction we should also stop the dma transfer */
+	if (ti_mmchs_read_4(sc, MMCHS_CMD) & MMCHS_CMD_DE) {
+
+		/* Abort the DMA transfer (DDIR bit tells direction) */
+		if (ti_mmchs_read_4(sc, MMCHS_CMD) & MMCHS_CMD_DDIR)
+#ifdef SOC_TI_AM335X
+			printf("%s: DMA unimplemented\n", __func__);
+#else
+			ti_sdma_stop_xfer(sc->sc_dmach_rd);
+#endif
+		else
+#ifdef SOC_TI_AM335X
+			printf("%s: DMA unimplemented\n", __func__);
+#else
+			ti_sdma_stop_xfer(sc->sc_dmach_wr);
+#endif
+
+		/* If an error occure abort the DMA operation and free the dma map */
+		if ((sc->sc_dmamapped > 0) && (cmd->error != MMC_ERR_NONE)) {
+			bus_dmamap_unload(sc->sc_dmatag, sc->sc_dmamap);
+			sc->sc_dmamapped--;
+		}
+	}
+
+	/* Command error occured? ... if so issue a soft reset for the cmd fsm */
+	if (stat_reg & (MMCHS_STAT_CCRC | MMCHS_STAT_CTO)) {
+		ti_mmchs_reset_controller(sc, MMCHS_SYSCTL_SRC);
+	}
+
+	/* Data error occured? ... if so issue a soft reset for the data line */
+	if (stat_reg & (MMCHS_STAT_DEB | MMCHS_STAT_DCRC | MMCHS_STAT_DTO)) {
+		ti_mmchs_reset_controller(sc, MMCHS_SYSCTL_SRD);
+	}
+
+	/* On any error the command is cancelled ... so we are done */
+	return 1;
+}
+
+/**
+ *	ti_mmchs_intr - interrupt handler for MMC/SD/SDIO controller
+ *	@arg: pointer to the driver context
+ *
+ *	Interrupt handler for the MMC/SD/SDIO controller, responsible for handling
+ *	the IRQ and clearing the status flags.
+ *
+ *	LOCKING:
+ *	Called from interrupt context
+ *
+ *	RETURNS:
+ *	nothing
+ */
+static void
+ti_mmchs_intr(void *arg)
+{
+	struct ti_mmchs_softc *sc = (struct ti_mmchs_softc *) arg;
+	uint32_t stat_reg;
+	int done = 0;
+
+	TI_MMCHS_LOCK(sc);
+
+	stat_reg = ti_mmchs_read_4(sc, MMCHS_STAT) & (ti_mmchs_read_4(sc,
+	    MMCHS_IE) | MMCHS_STAT_ERRI);
+
+	if (sc->curcmd == NULL) {
+		device_printf(sc->sc_dev, "Error: current cmd NULL, already done?\n");
+		ti_mmchs_write_4(sc, MMCHS_STAT, stat_reg);
+		TI_MMCHS_UNLOCK(sc);
+		return;
+	}
+
+	if (stat_reg & MMCHS_STAT_ERRI) {
+		/* An error has been tripped in the status register */
+		done = ti_mmchs_intr_error(sc, sc->curcmd, stat_reg);
+
+	} else {
+
+		/* NOTE: This implementation could be a bit inefficent, I don't think
+		 * it is necessary to handle both the 'command complete' and 'transfer
+		 * complete' for data transfers ... presumably just transfer complete
+		 * is enough.
+		 */
+
+		/* No error */
+		sc->curcmd->error = MMC_ERR_NONE;
+
+		/* Check if the command completed */
+		if (stat_reg & MMCHS_STAT_CC) {
+			done = ti_mmchs_intr_cmd_compl(sc, sc->curcmd);
+		}
+
+		/* Check if the transfer has completed */
+		if (stat_reg & MMCHS_STAT_TC) {
+			done = ti_mmchs_intr_xfer_compl(sc, sc->curcmd);
+		}
+
+	}
+
+	/* Clear all the interrupt status bits by writing the value back */
+	ti_mmchs_write_4(sc, MMCHS_STAT, stat_reg);
+
+	/* This may mark the command as done if there is no stop request */
+	/* TODO: This is a bit ugly, needs fix-up */
+	if (done) {
+		ti_mmchs_start(sc);
+	}
+
+	TI_MMCHS_UNLOCK(sc);
+}
+
+#ifdef SOC_TI_AM335X
+static void
+ti_mmchs_edma3_rx_xfer_setup(struct ti_mmchs_softc *sc, uint32_t src_paddr,
+    uint32_t dst_paddr, uint16_t blk_size, uint16_t num_blks)
+{
+	struct ti_edma3cc_param_set ps;
+
+	bzero(&ps, sizeof(struct ti_edma3cc_param_set));
+	ps.src		= src_paddr;
+	ps.dst		= dst_paddr;
+	ps.dstbidx	= 4;
+	ps.dstcidx	= blk_size;
+	ps.acnt		= 4;
+	ps.bcnt		= blk_size/4;
+	ps.ccnt		= num_blks;
+	ps.link		= 0xffff;
+	ps.opt.tcc	= sc->dma_rx_trig;
+	ps.opt.tcinten	= 1;
+	ps.opt.fwid	= 2; /* fifo width is 32 */
+	ps.opt.sam	= 1;
+	ps.opt.syncdim	= 1;
+
+	ti_edma3_param_write(sc->dma_rx_trig, &ps);
+	ti_edma3_enable_transfer_event(sc->dma_rx_trig);
+}
+
+static void
+ti_mmchs_edma3_tx_xfer_setup(struct ti_mmchs_softc *sc, uint32_t src_paddr,
+    uint32_t dst_paddr, uint16_t blk_size, uint16_t num_blks)
+{
+	struct ti_edma3cc_param_set ps;
+
+	bzero(&ps, sizeof(struct ti_edma3cc_param_set));
+	ps.src		= src_paddr;
+	ps.dst		= dst_paddr;
+	ps.srccidx	= blk_size;
+	ps.bcnt		= blk_size/4;
+	ps.ccnt		= num_blks;
+	ps.srcbidx	= 4;
+	ps.acnt		= 0x4;
+	ps.link		= 0xffff;
+	ps.opt.tcc	= sc->dma_tx_trig;
+	ps.opt.tcinten	= 1;
+	ps.opt.fwid	= 2; /* fifo width is 32 */
+	ps.opt.dam	= 1;
+	ps.opt.syncdim	= 1;
+
+	ti_edma3_param_write(sc->dma_tx_trig, &ps);
+	ti_edma3_enable_transfer_event(sc->dma_tx_trig);
+}
+#endif
+
+/**
+ *	ti_mmchs_start_cmd - starts the given command
+ *	@sc: pointer to the driver context
+ *	@cmd: the command to start
+ *
+ *	The call tree for this function is
+ *		- ti_mmchs_start_cmd
+ *			- ti_mmchs_start
+ *				- ti_mmchs_request
+ *
+ *	LOCKING:
+ *	Caller should be holding the OMAP_MMC lock.
+ *
+ *	RETURNS:
+ *	nothing
+ */
+static void
+ti_mmchs_start_cmd(struct ti_mmchs_softc *sc, struct mmc_command *cmd)
+{
+	uint32_t cmd_reg, con_reg, ise_reg;
+	struct mmc_data *data;
+	struct mmc_request *req;
+	void *vaddr;
+	bus_addr_t paddr;
+#ifndef SOC_TI_AM335X
+	uint32_t pktsize;
+#endif
+	sc->curcmd = cmd;
+	data = cmd->data;
+	req = cmd->mrq;
+
+	/* Ensure the STR and MIT bits are cleared, these are only used for special
+	 * command types.
+	 */
+	con_reg = ti_mmchs_read_4(sc, MMCHS_CON);
+	con_reg &= ~(MMCHS_CON_STR | MMCHS_CON_MIT);
+
+	/* Load the command into bits 29:24 of the CMD register */
+	cmd_reg = (uint32_t)(cmd->opcode & 0x3F) << 24;
+
+	/* Set the default set of interrupts */
+	ise_reg = (MMCHS_STAT_CERR | MMCHS_STAT_CTO | MMCHS_STAT_CC | MMCHS_STAT_CEB);
+
+	/* Enable CRC checking if requested */
+	if (cmd->flags & MMC_RSP_CRC)
+		ise_reg |= MMCHS_STAT_CCRC;
+
+	/* Enable reply index checking if the response supports it */
+	if (cmd->flags & MMC_RSP_OPCODE)
+		ise_reg |= MMCHS_STAT_CIE;
+
+	/* Set the expected response length */
+	if (MMC_RSP(cmd->flags) == MMC_RSP_NONE) {
+		cmd_reg |= MMCHS_CMD_RSP_TYPE_NO;
+	} else {
+		if (cmd->flags & MMC_RSP_136)
+			cmd_reg |= MMCHS_CMD_RSP_TYPE_136;
+		else if (cmd->flags & MMC_RSP_BUSY)
+			cmd_reg |= MMCHS_CMD_RSP_TYPE_48_BSY;
+		else
+			cmd_reg |= MMCHS_CMD_RSP_TYPE_48;
+
+		/* Enable command index/crc checks if necessary expected */
+		if (cmd->flags & MMC_RSP_CRC)
+			cmd_reg |= MMCHS_CMD_CCCE;
+		if (cmd->flags & MMC_RSP_OPCODE)
+			cmd_reg |= MMCHS_CMD_CICE;
+	}
+
+	/* Set the bits for the special commands CMD12 (MMC_STOP_TRANSMISSION) and
+	 * CMD52 (SD_IO_RW_DIRECT) */
+	if (cmd->opcode == MMC_STOP_TRANSMISSION)
+		cmd_reg |= MMCHS_CMD_CMD_TYPE_IO_ABORT;
+
+	/* Check if there is any data to write */
+	if (data == NULL) {
+		/* Clear the block count */
+		ti_mmchs_write_4(sc, MMCHS_BLK, 0);
+
+		/* The no data case is fairly simple */
+		ti_mmchs_write_4(sc, MMCHS_CON, con_reg);
+		ti_mmchs_write_4(sc, MMCHS_IE, ise_reg);
+		ti_mmchs_write_4(sc, MMCHS_ISE, ise_reg);
+		ti_mmchs_write_4(sc, MMCHS_ARG, cmd->arg);
+		ti_mmchs_write_4(sc, MMCHS_CMD, cmd_reg);
+		return;
+	}
+
+	/* Indicate that data is present */
+	cmd_reg |= MMCHS_CMD_DP | MMCHS_CMD_MSBS | MMCHS_CMD_BCE;
+
+	/* Indicate a read operation */
+	if (data->flags & MMC_DATA_READ)
+		cmd_reg |= MMCHS_CMD_DDIR;
+
+	/* Streaming mode */
+	if (data->flags & MMC_DATA_STREAM) {
+		con_reg |= MMCHS_CON_STR;
+	}
+
+	/* Multi-block mode */
+	if (data->flags & MMC_DATA_MULTI) {
+		cmd_reg |= MMCHS_CMD_MSBS;
+	}
+
+	/* Enable extra interrupt sources for the transfer */
+	ise_reg |= (MMCHS_STAT_TC | MMCHS_STAT_DTO | MMCHS_STAT_DEB | MMCHS_STAT_CEB);
+	if (cmd->flags & MMC_RSP_CRC)
+		ise_reg |= MMCHS_STAT_DCRC;
+
+	/* Enable the DMA transfer bit */
+	cmd_reg |= MMCHS_CMD_DE;
+
+	/* Set the block size and block count */
+	ti_mmchs_write_4(sc, MMCHS_BLK, (1 << 16) | data->len);
+
+	/* Setup the DMA stuff */
+	if (data->flags & (MMC_DATA_READ | MMC_DATA_WRITE)) {
+
+		vaddr = data->data;
+		data->xfer_len = 0;
+
+		/* Map the buffer buf into bus space using the dmamap map. */
+		if (bus_dmamap_load(sc->sc_dmatag, sc->sc_dmamap, vaddr, data->len,
+		    ti_mmchs_getaddr, &paddr, 0) != 0) {
+
+			if (req->cmd->flags & STOP_STARTED)
+				req->stop->error = MMC_ERR_NO_MEMORY;
+			else
+				req->cmd->error = MMC_ERR_NO_MEMORY;
+			sc->req = NULL;
+			sc->curcmd = NULL;
+			req->done(req);
+			return;
+		}
+
+#ifndef SOC_TI_AM335X
+		/* Calculate the packet size, the max packet size is 512 bytes
+		 * (or 128 32-bit elements).
+		 */
+		pktsize = min((data->len / 4), (512 / 4));
+#endif
+		/* Sync the DMA buffer and setup the DMA controller */
+		if (data->flags & MMC_DATA_READ) {
+			bus_dmamap_sync(sc->sc_dmatag, sc->sc_dmamap, BUS_DMASYNC_PREREAD);
+#ifdef SOC_TI_AM335X
+			ti_mmchs_edma3_rx_xfer_setup(sc, sc->sc_data_reg_paddr, 
+			    paddr, data->len, 1);
+#else
+			ti_sdma_start_xfer_packet(sc->sc_dmach_rd, sc->sc_data_reg_paddr,
+			    paddr, 1, (data->len / 4), pktsize);
+#endif
+		} else {
+			bus_dmamap_sync(sc->sc_dmatag, sc->sc_dmamap, BUS_DMASYNC_PREWRITE);
+#ifdef SOC_TI_AM335X
+			ti_mmchs_edma3_tx_xfer_setup(sc, paddr,
+			    sc->sc_data_reg_paddr, data->len, 1);
+#else
+			ti_sdma_start_xfer_packet(sc->sc_dmach_wr, paddr,
+			    sc->sc_data_reg_paddr, 1, (data->len / 4), pktsize);
+#endif
+		}
+
+		/* Increase the mapped count */
+		sc->sc_dmamapped++;
+
+		sc->sc_cmd_data_vaddr = vaddr;
+		sc->sc_cmd_data_len = data->len;
+	}
+
+	/* Finally kick off the command */
+	ti_mmchs_write_4(sc, MMCHS_CON, con_reg);
+	ti_mmchs_write_4(sc, MMCHS_IE, ise_reg);
+	ti_mmchs_write_4(sc, MMCHS_ISE, ise_reg);
+	ti_mmchs_write_4(sc, MMCHS_ARG, cmd->arg);
+	ti_mmchs_write_4(sc, MMCHS_CMD, cmd_reg);
+
+	/* and we're done */
+}
+
+/**
+ *	ti_mmchs_start - starts a request stored in the driver context
+ *	@sc: pointer to the driver context
+ *
+ *	This function is called by ti_mmchs_request() in response to a read/write
+ *	request from the MMC core module.
+ *
+ *	LOCKING:
+ *	Caller should be holding the OMAP_MMC lock.
+ *
+ *	RETURNS:
+ *	nothing
+ */
+static void
+ti_mmchs_start(struct ti_mmchs_softc *sc)
+{
+	struct mmc_request *req;
+
+	/* Sanity check we have a request */
+	req = sc->req;
+	if (req == NULL)
+		return;
+
+	/* assert locked */
+	if (!(sc->flags & CMD_STARTED)) {
+		sc->flags |= CMD_STARTED;
+		ti_mmchs_start_cmd(sc, req->cmd);
+		return;
+	}
+
+	if (!(sc->flags & STOP_STARTED) && req->stop) {
+		sc->flags |= STOP_STARTED;
+		ti_mmchs_start_cmd(sc, req->stop);
+		return;
+	}
+
+	/* We must be done -- bad idea to do this while locked? */
+	sc->req = NULL;
+	sc->curcmd = NULL;
+	req->done(req);
+}
+
+/**
+ *	ti_mmchs_request - entry point for all read/write/cmd requests
+ *	@brdev: mmc bridge device handle
+ *	@reqdev: the device doing the requesting ?
+ *	@req: the action requested
+ *
+ *	LOCKING:
+ *	None, internally takes the OMAP_MMC lock.
+ *
+ *	RETURNS:
+ *	0 on success
+ *	EBUSY if the driver is already performing a request
+ */
+static int
+ti_mmchs_request(device_t brdev, device_t reqdev, struct mmc_request *req)
+{
+	struct ti_mmchs_softc *sc = device_get_softc(brdev);
+
+	TI_MMCHS_LOCK(sc);
+
+	/*
+	 * XXX do we want to be able to queue up multiple commands?
+	 * XXX sounds like a good idea, but all protocols are sync, so
+	 * XXX maybe the idea is naive...
+	 */
+	if (sc->req != NULL) {
+		TI_MMCHS_UNLOCK(sc);
+		return (EBUSY);
+	}
+
+	/* Store the request and start the command */
+	sc->req = req;
+	sc->flags = 0;
+	ti_mmchs_start(sc);
+
+	TI_MMCHS_UNLOCK(sc);
+
+	return (0);
+}
+
+/**
+ *	ti_mmchs_get_ro - returns the status of the read-only setting
+ *	@brdev: mmc bridge device handle
+ *	@reqdev: device doing the request
+ *
+ *	This function is relies on hint'ed values to determine which GPIO is used
+ *	to determine if the write protect is enabled. On the BeagleBoard the pin
+ *	is GPIO_23.
+ *
+ *	LOCKING:
+ *	-
+ *
+ *	RETURNS:
+ *	0 if not read-only
+ *	1 if read only
+ */
+static int
+ti_mmchs_get_ro(device_t brdev, device_t reqdev)
+{
+	struct ti_mmchs_softc *sc = device_get_softc(brdev);
+	unsigned int readonly = 0;
+
+	TI_MMCHS_LOCK(sc);
+
+	if ((sc->sc_wp_gpio_pin != -1) && (sc->sc_gpio_dev != NULL)) {
+		if (GPIO_PIN_GET(sc->sc_gpio_dev, sc->sc_wp_gpio_pin, &readonly) != 0)
+			readonly = 0;
+		else
+			readonly = (readonly == 0) ? 0 : 1;
+	}
+
+	TI_MMCHS_UNLOCK(sc);
+
+	return (readonly);
+}
+
+/**
+ *	ti_mmchs_send_init_stream - sets bus/controller settings
+ *	@brdev: mmc bridge device handle
+ *	@reqdev: device doing the request
+ *
+ *	Send init stream sequence to card before sending IDLE command
+ *
+ *	LOCKING:
+ *
+ *
+ *	RETURNS:
+ *	0 if function succeeded
+ */
+static void
+ti_mmchs_send_init_stream(struct ti_mmchs_softc *sc)
+{
+	unsigned long timeout;
+	uint32_t ie, ise, con;
+
+	ti_mmchs_dbg(sc, "Performing init sequence\n");
+
+	/* Prior to issuing any command, the MMCHS controller has to execute a
+	 * special INIT procedure. The MMCHS controller has to generate a clock
+	 * during 1ms. During the INIT procedure, the MMCHS controller generates 80
+	 * clock periods. In order to keep the 1ms gap, the MMCHS controller should
+	 * be configured to generate a clock whose frequency is smaller or equal to
+	 * 80 KHz. If the MMCHS controller divider bitfield width doesn't allow to
+	 * choose big values, the MMCHS controller driver should perform the INIT
+	 * procedure twice or three times. Twice is generally enough.
+	 *
+	 * The INIt procedure is executed by setting MMCHS1.MMCHS_CON[1] INIT
+	 * bitfield to 1 and by sending a dummy command, writing 0x00000000 in
+	 * MMCHS1.MMCHS_CMD register.
+	 */
+
+	/* Disable interrupt status events but enable interrupt generation.
+	 * This doesn't seem right to me, but if the interrupt generation is not
+	 * enabled the CC bit doesn't seem to be set in the STAT register.
+	 */
+
+	/* Enable interrupt generation */
+	ie = ti_mmchs_read_4(sc, MMCHS_IE);
+	ti_mmchs_write_4(sc, MMCHS_IE, 0x307F0033);
+
+	/* Disable generation of status events (stops interrupt triggering) */
+	ise = ti_mmchs_read_4(sc, MMCHS_ISE);
+	ti_mmchs_write_4(sc, MMCHS_ISE, 0);
+
+	/* Set the initialise stream bit */
+	con = ti_mmchs_read_4(sc, MMCHS_CON);
+	con |= MMCHS_CON_INIT;
+	ti_mmchs_write_4(sc, MMCHS_CON, con);
+
+	/* Write a dummy command 0x00 */
+	ti_mmchs_write_4(sc, MMCHS_CMD, 0x00000000);
+
+	/* Loop waiting for the command to finish */
+	timeout = hz;
+	do {
+		pause("MMCINIT", 1);
+		if (timeout-- == 0) {
+			device_printf(sc->sc_dev, "Error: first stream init timed out\n");
+			break;
+		}
+	} while (!(ti_mmchs_read_4(sc, MMCHS_STAT) & MMCHS_STAT_CC));
+
+	/* Clear the command complete status bit */
+	ti_mmchs_write_4(sc, MMCHS_STAT, MMCHS_STAT_CC);
+
+	/* Write another dummy command 0x00 */
+	ti_mmchs_write_4(sc, MMCHS_CMD, 0x00000000);
+
+	/* Loop waiting for the second command to finish */
+	timeout = hz;
+	do {
+		pause("MMCINIT", 1);
+		if (timeout-- == 0) {
+			device_printf(sc->sc_dev, "Error: second stream init timed out\n");
+			break;
+		}
+	} while (!(ti_mmchs_read_4(sc, MMCHS_STAT) & MMCHS_STAT_CC));
+
+	/* Clear the stream init bit */
+	con &= ~MMCHS_CON_INIT;
+	ti_mmchs_write_4(sc, MMCHS_CON, con);
+
+	/* Clear the status register, then restore the IE and ISE registers */
+	ti_mmchs_write_4(sc, MMCHS_STAT, 0xffffffff);
+	ti_mmchs_read_4(sc, MMCHS_STAT);
+
+	ti_mmchs_write_4(sc, MMCHS_ISE, ise);
+	ti_mmchs_write_4(sc, MMCHS_IE, ie);
+}
+
+/**
+ *	ti_mmchs_update_ios - sets bus/controller settings
+ *	@brdev: mmc bridge device handle
+ *	@reqdev: device doing the request
+ *
+ *	Called to set the bus and controller settings that need to be applied to
+ *	the actual HW.  Currently this function just sets the bus width and the
+ *	clock speed.
+ *
+ *	LOCKING:
+ *
+ *
+ *	RETURNS:
+ *	0 if function succeeded
+ */
+static int
+ti_mmchs_update_ios(device_t brdev, device_t reqdev)
+{
+	struct ti_mmchs_softc *sc;
+	struct mmc_host *host;
+	struct mmc_ios *ios;
+	uint32_t clkdiv;
+	uint32_t hctl_reg;
+	uint32_t con_reg;
+	uint32_t sysctl_reg;
+#ifndef SOC_TI_AM335X
+	uint16_t mv;
+#endif
+	unsigned long timeout;
+	int do_card_init = 0;
+
+	sc = device_get_softc(brdev);
+	host = &sc->host;
+	ios = &host->ios;
+
+	/* Read the initial values of the registers */
+	hctl_reg = ti_mmchs_read_4(sc, MMCHS_HCTL);
+	con_reg = ti_mmchs_read_4(sc, MMCHS_CON);
+
+	/* Set the bus width */
+	switch (ios->bus_width) {
+		case bus_width_1:
+			hctl_reg &= ~MMCHS_HCTL_DTW;
+			con_reg &= ~MMCHS_CON_DW8;
+			break;
+		case bus_width_4:
+			hctl_reg |= MMCHS_HCTL_DTW;
+			con_reg &= ~MMCHS_CON_DW8;
+			break;
+		case bus_width_8:
+			con_reg |= MMCHS_CON_DW8;
+			break;
+	}
+
+	/* Finally write all these settings back to the registers */
+	ti_mmchs_write_4(sc, MMCHS_HCTL, hctl_reg);
+	ti_mmchs_write_4(sc, MMCHS_CON, con_reg);
+
+	/* Check if we need to change the external voltage regulator */
+	if (sc->sc_cur_power_mode != ios->power_mode) {
+
+		if (ios->power_mode == power_up) {
+
+			/* Set the power level */
+			hctl_reg = ti_mmchs_read_4(sc, MMCHS_HCTL);
+			hctl_reg &= ~(MMCHS_HCTL_SDVS_MASK | MMCHS_HCTL_SDBP);
+
+			if ((ios->vdd == -1) || (ios->vdd >= vdd_240)) {
+#ifndef SOC_TI_AM335X
+				mv = 3000;
+#endif
+				hctl_reg |= MMCHS_HCTL_SDVS_V30;
+			} else {
+#ifndef SOC_TI_AM335X
+				mv = 1800;
+#endif
+				hctl_reg |= MMCHS_HCTL_SDVS_V18;
+			}
+
+			ti_mmchs_write_4(sc, MMCHS_HCTL, hctl_reg);
+
+#ifdef SOC_TI_AM335X
+			printf("%s: TWL unimplemented\n", __func__);
+#else
+			/* Set the desired voltage on the regulator */
+			if (sc->sc_vreg_dev && sc->sc_vreg_name)
+				twl_vreg_set_voltage(sc->sc_vreg_dev, sc->sc_vreg_name, mv);
+#endif
+			/* Enable the bus power */
+			ti_mmchs_write_4(sc, MMCHS_HCTL, (hctl_reg | MMCHS_HCTL_SDBP));
+			timeout = hz;
+			while (!(ti_mmchs_read_4(sc, MMCHS_HCTL) & MMCHS_HCTL_SDBP)) {
+				if (timeout-- == 0)
+					break;
+				pause("MMC_PWRON", 1);
+			}
+
+		} else if (ios->power_mode == power_off) {
+			/* Disable the bus power */
+			hctl_reg = ti_mmchs_read_4(sc, MMCHS_HCTL);
+			ti_mmchs_write_4(sc, MMCHS_HCTL, (hctl_reg & ~MMCHS_HCTL_SDBP));
+
+#ifdef SOC_TI_AM335X
+			printf("%s: TWL unimplemented\n", __func__);
+#else
+			/* Turn the power off on the voltage regulator */
+			if (sc->sc_vreg_dev && sc->sc_vreg_name)
+				twl_vreg_set_voltage(sc->sc_vreg_dev, sc->sc_vreg_name, 0);
+#endif
+		} else if (ios->power_mode == power_on) {
+			/* Force a card re-initialisation sequence */
+			do_card_init = 1;
+		}
+
+		/* Save the new power state */
+		sc->sc_cur_power_mode = ios->power_mode;
+	}
+
+	/* need the MMCHS_SYSCTL register */
+	sysctl_reg = ti_mmchs_read_4(sc, MMCHS_SYSCTL);
+
+	/* Just in case this hasn't been setup before, set the timeout to the default */
+	sysctl_reg &= ~MMCHS_SYSCTL_DTO_MASK;
+	sysctl_reg |= MMCHS_SYSCTL_DTO(0xe);
+
+	/* Disable the clock output while configuring the new clock */
+	sysctl_reg &= ~(MMCHS_SYSCTL_ICE | MMCHS_SYSCTL_CEN);
+	ti_mmchs_write_4(sc, MMCHS_SYSCTL, sysctl_reg);
+
+	/* bus mode? */
+	if (ios->clock == 0) {
+		clkdiv = 0;
+	} else {
+		clkdiv = sc->sc_ref_freq / ios->clock;
+		if (clkdiv < 1)
+			clkdiv = 1;
+		if ((sc->sc_ref_freq / clkdiv) > ios->clock)
+			clkdiv += 1;
+		if (clkdiv > 250)
+			clkdiv = 250;
+	}
+
+	/* Set the new clock divider */
+	sysctl_reg &= ~MMCHS_SYSCTL_CLKD_MASK;
+	sysctl_reg |= MMCHS_SYSCTL_CLKD(clkdiv);
+
+	/* Write the new settings ... */
+	ti_mmchs_write_4(sc, MMCHS_SYSCTL, sysctl_reg);
+	/* ... write the internal clock enable bit ... */
+	ti_mmchs_write_4(sc, MMCHS_SYSCTL, sysctl_reg | MMCHS_SYSCTL_ICE);
+	/* ... wait for the clock to stablise ... */
+	while (((sysctl_reg = ti_mmchs_read_4(sc, MMCHS_SYSCTL)) &
+	    MMCHS_SYSCTL_ICS) == 0) {
+		continue;
+	}
+	/* ... then enable */
+	sysctl_reg |= MMCHS_SYSCTL_CEN;
+	ti_mmchs_write_4(sc, MMCHS_SYSCTL, sysctl_reg);
+
+	/* If the power state has changed to 'power_on' then run the init sequence*/
+	if (do_card_init) {
+		ti_mmchs_send_init_stream(sc);
+	}
+
+	/* Set the bus mode (opendrain or normal) */
+	con_reg = ti_mmchs_read_4(sc, MMCHS_CON);
+	if (ios->bus_mode == opendrain)
+		con_reg |= MMCHS_CON_OD;
+	else
+		con_reg &= ~MMCHS_CON_OD;
+	ti_mmchs_write_4(sc, MMCHS_CON, con_reg);
+
+	return (0);
+}
+
+/**
+ *	ti_mmchs_acquire_host -
+ *	@brdev: mmc bridge device handle
+ *	@reqdev: device doing the request
+ *
+ *	TODO: Is this function needed ?
+ *
+ *	LOCKING:
+ *	none
+ *
+ *	RETURNS:
+ *	0 function succeeded
+ *
+ */
+static int
+ti_mmchs_acquire_host(device_t brdev, device_t reqdev)
+{
+	struct ti_mmchs_softc *sc = device_get_softc(brdev);
+	int err = 0;
+
+	TI_MMCHS_LOCK(sc);
+
+	while (sc->bus_busy) {
+		msleep(sc, &sc->sc_mtx, PZERO, "mmc", hz / 5);
+	}
+
+	sc->bus_busy++;
+
+	TI_MMCHS_UNLOCK(sc);
+
+	return (err);
+}
+
+/**
+ *	ti_mmchs_release_host -
+ *	@brdev: mmc bridge device handle
+ *	@reqdev: device doing the request
+ *
+ *	TODO: Is this function needed ?
+ *
+ *	LOCKING:
+ *	none
+ *
+ *	RETURNS:
+ *	0 function succeeded
+ *
+ */
+static int
+ti_mmchs_release_host(device_t brdev, device_t reqdev)
+{
+	struct ti_mmchs_softc *sc = device_get_softc(brdev);
+
+	TI_MMCHS_LOCK(sc);
+
+	sc->bus_busy--;
+	wakeup(sc);
+
+	TI_MMCHS_UNLOCK(sc);
+
+	return (0);
+}
+
+/**
+ *	ti_mmchs_read_ivar - returns driver conf variables
+ *	@bus:
+ *	@child:
+ *	@which: The variable to get the result for
+ *	@result: Upon return will store the variable value
+ *
+ *
+ *
+ *	LOCKING:
+ *	None, caller must hold locks
+ *
+ *	RETURNS:
+ *	0 on success
+ *	EINVAL if the variable requested is invalid
+ */
+static int
+ti_mmchs_read_ivar(device_t bus, device_t child, int which, uintptr_t *result)
+{
+	struct ti_mmchs_softc *sc = device_get_softc(bus);
+
+	switch (which) {
+		case MMCBR_IVAR_BUS_MODE:
+			*(int *)result = sc->host.ios.bus_mode;
+			break;
+		case MMCBR_IVAR_BUS_WIDTH:
+			*(int *)result = sc->host.ios.bus_width;
+			break;
+		case MMCBR_IVAR_CHIP_SELECT:
+			*(int *)result = sc->host.ios.chip_select;
+			break;
+		case MMCBR_IVAR_CLOCK:
+			*(int *)result = sc->host.ios.clock;
+			break;
+		case MMCBR_IVAR_F_MIN:
+			*(int *)result = sc->host.f_min;
+			break;
+		case MMCBR_IVAR_F_MAX:
+			*(int *)result = sc->host.f_max;
+			break;
+		case MMCBR_IVAR_HOST_OCR:
+			*(int *)result = sc->host.host_ocr;
+			break;
+		case MMCBR_IVAR_MODE:
+			*(int *)result = sc->host.mode;
+			break;
+		case MMCBR_IVAR_OCR:
+			*(int *)result = sc->host.ocr;
+			break;
+		case MMCBR_IVAR_POWER_MODE:
+			*(int *)result = sc->host.ios.power_mode;
+			break;
+		case MMCBR_IVAR_VDD:
+			*(int *)result = sc->host.ios.vdd;
+			break;
+		case MMCBR_IVAR_CAPS:
+			*(int *)result = sc->host.caps;
+			break;
+		case MMCBR_IVAR_MAX_DATA:
+			*(int *)result = 1;
+			break;
+		default:
+			return (EINVAL);
+	}
+	return (0);
+}
+
+/**
+ *	ti_mmchs_write_ivar - writes a driver conf variables
+ *	@bus:
+ *	@child:
+ *	@which: The variable to set
+ *	@value: The value to write into the variable
+ *
+ *
+ *
+ *	LOCKING:
+ *	None, caller must hold locks
+ *
+ *	RETURNS:
+ *	0 on success
+ *	EINVAL if the variable requested is invalid
+ */
+static int
+ti_mmchs_write_ivar(device_t bus, device_t child, int which, uintptr_t value)
+{
+	struct ti_mmchs_softc *sc = device_get_softc(bus);
+
+	switch (which) {
+		case MMCBR_IVAR_BUS_MODE:
+			sc->host.ios.bus_mode = value;
+			break;
+		case MMCBR_IVAR_BUS_WIDTH:
+			sc->host.ios.bus_width = value;
+			break;
+		case MMCBR_IVAR_CHIP_SELECT:
+			sc->host.ios.chip_select = value;
+			break;
+		case MMCBR_IVAR_CLOCK:
+			sc->host.ios.clock = value;
+			break;
+		case MMCBR_IVAR_MODE:
+			sc->host.mode = value;
+			break;
+		case MMCBR_IVAR_OCR:
+			sc->host.ocr = value;
+			break;
+		case MMCBR_IVAR_POWER_MODE:
+			sc->host.ios.power_mode = value;
+			break;
+		case MMCBR_IVAR_VDD:
+			sc->host.ios.vdd = value;
+			break;
+			/* These are read-only */
+		case MMCBR_IVAR_CAPS:
+		case MMCBR_IVAR_HOST_OCR:
+		case MMCBR_IVAR_F_MIN:
+		case MMCBR_IVAR_F_MAX:
+		case MMCBR_IVAR_MAX_DATA:
+			return (EINVAL);
+		default:
+			return (EINVAL);
+	}
+	return (0);
+}
+
+/**
+ *	ti_mmchs_hw_init - initialises the MMC/SD/SIO controller
+ *	@dev: mmc device handle
+ *
+ *	Called by the driver attach function during driver initialisation. This
+ *	function is responsibly to setup the controller ready for transactions.
+ *
+ *	LOCKING:
+ *	No locking, assumed to only be called during initialisation.
+ *
+ *	RETURNS:
+ *	nothing
+ */
+static void
+ti_mmchs_hw_init(device_t dev)
+{
+	struct ti_mmchs_softc *sc = device_get_softc(dev);
+	clk_ident_t clk;
+	unsigned long timeout;
+	uint32_t sysctl;
+	uint32_t capa;
+	uint32_t con, sysconfig;
+
+	/* 1: Enable the controller and interface/functional clocks */
+	clk = MMC0_CLK + sc->device_id;
+
+	if (ti_prcm_clk_enable(clk) != 0) {
+		device_printf(dev, "Error: failed to enable MMC clock\n");
+		return;
+	}
+
+	/* 1a: Get the frequency of the source clock */
+	if (ti_prcm_clk_get_source_freq(clk, &sc->sc_ref_freq) != 0) {
+		device_printf(dev, "Error: failed to get source clock freq\n");
+		return;
+	}
+
+	/* 2: Issue a softreset to the controller */
+	sysconfig = ti_mmchs_read_4(sc, MMCHS_SYSCONFIG);
+	sysconfig |= MMCHS_SYSCONFIG_SRST;
+	ti_mmchs_write_4(sc, MMCHS_SYSCONFIG, sysconfig);
+	timeout = 100;
+	while ((ti_mmchs_read_4(sc, MMCHS_SYSSTATUS) & 0x01) == 0x0) {
+		DELAY(1000);
+		if (timeout-- == 0) {
+			device_printf(dev, "Error: reset operation timed out\n");
+			return;
+		}
+	}
+
+	/* 3: Reset both the command and data state machines */
+	sysctl = ti_mmchs_read_4(sc, MMCHS_SYSCTL);
+	ti_mmchs_write_4(sc, MMCHS_SYSCTL, sysctl | MMCHS_SYSCTL_SRA);
+	timeout = 100;
+	while ((ti_mmchs_read_4(sc, MMCHS_SYSCTL) & MMCHS_SYSCTL_SRA) != 0x0) {
+		DELAY(1000);
+		if (timeout-- == 0) {
+			device_printf(dev, "Error: reset operation timed out\n");
+			return;
+		}
+	}
+
+	/* 4: Set initial host configuration (1-bit mode, pwroff) and capabilities */
+	ti_mmchs_write_4(sc, MMCHS_HCTL, MMCHS_HCTL_SDVS_V30);
+
+	capa = ti_mmchs_read_4(sc, MMCHS_CAPA);
+	ti_mmchs_write_4(sc, MMCHS_CAPA, capa | MMCHS_CAPA_VS30 | MMCHS_CAPA_VS18);
+
+	/* 5: Set the initial bus configuration
+	 *       0  CTPL_MMC_SD      : Control Power for DAT1 line
+	 *       0  WPP_ACTIVE_HIGH  : Write protect polarity
+	 *       0  CDP_ACTIVE_HIGH  : Card detect polarity
+	 *       0  CTO_ENABLED      : MMC interrupt command
+	 *       0  DW8_DISABLED     : 8-bit mode MMC select
+	 *       0  MODE_FUNC        : Mode select
+	 *       0  STREAM_DISABLED  : Stream command
+	 *       0  HR_DISABLED      : Broadcast host response
+	 *       0  INIT_DISABLED    : Send initialization stream
+	 *       0  OD_DISABLED      : No Open Drain
+	 */
+	con = ti_mmchs_read_4(sc, MMCHS_CON) & MMCHS_CON_DVAL_MASK;
+	ti_mmchs_write_4(sc, MMCHS_CON, con);
+
+}
+
+/**
+ *	ti_mmchs_fini - shutdown the MMC/SD/SIO controller
+ *	@dev: mmc device handle
+ *
+ *	Responsible for shutting done the MMC controller, this function may be
+ *	called as part of a reset sequence.
+ *
+ *	LOCKING:
+ *	No locking, assumed to be called during tear-down/reset.
+ *
+ *	RETURNS:
+ *	nothing
+ */
+static void
+ti_mmchs_hw_fini(device_t dev)
+{
+	struct ti_mmchs_softc *sc = device_get_softc(dev);
+
+	/* Disable all interrupts */
+	ti_mmchs_write_4(sc, MMCHS_ISE, 0x00000000);
+	ti_mmchs_write_4(sc, MMCHS_IE, 0x00000000);
+
+	/* Disable the functional and interface clocks */
+	ti_prcm_clk_disable(MMC0_CLK + sc->device_id);
+}
+
+/**
+ *	ti_mmchs_init_dma_channels - initalise the DMA channels
+ *	@sc: driver soft context
+ *
+ *	Attempts to activate an RX and TX DMA channel for the MMC device.
+ *
+ *	LOCKING:
+ *	No locking, assumed to be called during tear-down/reset.
+ *
+ *	RETURNS:
+ *	0 on success, a negative error code on failure.
+ */
+static int
+ti_mmchs_init_dma_channels(struct ti_mmchs_softc *sc)
+{
+#ifdef SOC_TI_AM335X
+	switch (sc->device_id) {
+		case 0:
+			sc->dma_tx_trig = TI_EDMA3_EVENT_SDTXEVT0;
+			sc->dma_rx_trig = TI_EDMA3_EVENT_SDRXEVT0;
+			break;
+		case 1:
+			sc->dma_tx_trig = TI_EDMA3_EVENT_SDTXEVT1;
+			sc->dma_rx_trig = TI_EDMA3_EVENT_SDRXEVT1;
+			break;
+		default:
+			return(EINVAL);
+	}
+
+#define EVTQNUM		0
+	/* TODO EDMA3 have 3 queues, so we need some queue allocation call */
+	ti_edma3_init(EVTQNUM);
+	ti_edma3_request_dma_ch(sc->dma_tx_trig, sc->dma_tx_trig, EVTQNUM);
+	ti_edma3_request_dma_ch(sc->dma_rx_trig, sc->dma_rx_trig, EVTQNUM);
+#else
+	int err;
+	uint32_t rev;
+
+	/* Get the current chip revision */
+	rev = ti_revision();
+	if ((OMAP_REV_DEVICE(rev) != OMAP4430_DEV) && (sc->device_id > 3))
+		return(EINVAL);
+
+	/* Get the DMA MMC triggers */
+	switch (sc->device_id) {
+		case 1:
+			sc->dma_tx_trig = 60;
+			sc->dma_rx_trig = 61;
+			break;
+		case 2:
+			sc->dma_tx_trig = 46;
+			sc->dma_rx_trig = 47;
+			break;
+		case 3:
+			sc->dma_tx_trig = 76;
+			sc->dma_rx_trig = 77;
+			break;
+		/* The following are OMAP4 only */
+		case 4:
+			sc->dma_tx_trig = 56;
+			sc->dma_rx_trig = 57;
+			break;
+		case 5:
+			sc->dma_tx_trig = 58;
+			sc->dma_rx_trig = 59;
+			break;
+		default:
+			return(EINVAL);
+	}
+
+	/* Activate a RX channel from the OMAP DMA driver */
+	err = ti_sdma_activate_channel(&sc->sc_dmach_rd, ti_mmchs_dma_intr, sc);
+	if (err != 0)
+		return(err);
+
+	/* Setup the RX channel for MMC data transfers */
+	ti_sdma_set_xfer_burst(sc->sc_dmach_rd, TI_SDMA_BURST_NONE,
+	    TI_SDMA_BURST_64);
+	ti_sdma_set_xfer_data_type(sc->sc_dmach_rd, TI_SDMA_DATA_32BITS_SCALAR);
+	ti_sdma_sync_params(sc->sc_dmach_rd, sc->dma_rx_trig,
+	    TI_SDMA_SYNC_PACKET | TI_SDMA_SYNC_TRIG_ON_SRC);
+	ti_sdma_set_addr_mode(sc->sc_dmach_rd, TI_SDMA_ADDR_CONSTANT,
+	    TI_SDMA_ADDR_POST_INCREMENT);
+
+	/* Activate and configure the TX DMA channel */
+	err = ti_sdma_activate_channel(&sc->sc_dmach_wr, ti_mmchs_dma_intr, sc);
+	if (err != 0)
+		return(err);
+
+	/* Setup the TX channel for MMC data transfers */
+	ti_sdma_set_xfer_burst(sc->sc_dmach_wr, TI_SDMA_BURST_64,
+	    TI_SDMA_BURST_NONE);
+	ti_sdma_set_xfer_data_type(sc->sc_dmach_wr, TI_SDMA_DATA_32BITS_SCALAR);
+	ti_sdma_sync_params(sc->sc_dmach_wr, sc->dma_tx_trig,
+	    TI_SDMA_SYNC_PACKET | TI_SDMA_SYNC_TRIG_ON_DST);
+	ti_sdma_set_addr_mode(sc->sc_dmach_wr, TI_SDMA_ADDR_POST_INCREMENT,
+	    TI_SDMA_ADDR_CONSTANT);
+#endif
+	return(0);
+}
+
+/**
+ *	ti_mmchs_deactivate - deactivates the driver
+ *	@dev: mmc device handle
+ *
+ *	Unmaps the register set and releases the IRQ resource.
+ *
+ *	LOCKING:
+ *	None required
+ *
+ *	RETURNS:
+ *	nothing
+ */
+static void
+ti_mmchs_deactivate(device_t dev)
+{
+	struct ti_mmchs_softc *sc= device_get_softc(dev);
+
+	/* Remove the IRQ handler */
+	if (sc->sc_irq_h != NULL) {
+		bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_irq_h);
+		sc->sc_irq_h = NULL;
+	}
+
+	/* Do the generic detach */
+	bus_generic_detach(sc->sc_dev);
+
+#ifdef SOC_TI_AM335X
+	printf("%s: DMA unimplemented\n", __func__);
+#else
+	/* Deactivate the DMA channels */
+	ti_sdma_deactivate_channel(sc->sc_dmach_rd);
+	ti_sdma_deactivate_channel(sc->sc_dmach_wr);
+#endif
+
+	/* Unmap the MMC controller registers */
+	if (sc->sc_mem_res != 0) {
+		bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(sc->sc_irq_res),
+		    sc->sc_mem_res);
+		sc->sc_mem_res = NULL;
+	}
+
+	/* Release the IRQ resource */
+	if (sc->sc_irq_res != NULL) {
+		bus_release_resource(dev, SYS_RES_IRQ, rman_get_rid(sc->sc_irq_res),
+		    sc->sc_irq_res);
+		sc->sc_irq_res = NULL;
+	}
+
+	return;
+}
+
+/**
+ *	ti_mmchs_activate - activates the driver
+ *	@dev: mmc device handle
+ *
+ *	Maps in the register set and requests an IRQ handler for the MMC controller.
+ *
+ *	LOCKING:
+ *	None required
+ *
+ *	RETURNS:
+ *	0 on sucess
+ *	ENOMEM if failed to map register set
+ */
+static int
+ti_mmchs_activate(device_t dev)
+{
+	struct ti_mmchs_softc *sc = device_get_softc(dev);
+	int rid;
+	int err;
+
+	/* Get the memory resource for the register mapping */
+	rid = 0;
+	sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	    RF_ACTIVE);
+	if (sc->sc_mem_res == NULL)
+		panic("%s: Cannot map registers", device_get_name(dev));
+
+	/* Allocate an IRQ resource for the MMC controller */
+	rid = 0;
+	sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+	    RF_ACTIVE | RF_SHAREABLE);
+	if (sc->sc_irq_res == NULL)
+		goto errout;
+
+	/* Allocate DMA tags and maps */
+	err = bus_dma_tag_create(bus_get_dma_tag(dev), 1, 0,
+	    BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL,
+	    NULL, MAXPHYS, 1, MAXPHYS, BUS_DMA_ALLOCNOW, NULL,
+	    NULL, &sc->sc_dmatag);
+	if (err != 0)
+		goto errout;
+
+	err = bus_dmamap_create(sc->sc_dmatag, 0,  &sc->sc_dmamap);
+	if (err != 0)
+		goto errout;
+
+	/* Initialise the DMA channels to be used by the controller */
+	err = ti_mmchs_init_dma_channels(sc);
+	if (err != 0)
+		goto errout;
+
+	/* Set the register offset */
+	if (ti_chip() == CHIP_OMAP_3)
+		sc->sc_reg_off = OMAP3_MMCHS_REG_OFFSET;
+	else if (ti_chip() == CHIP_OMAP_4)
+		sc->sc_reg_off = OMAP4_MMCHS_REG_OFFSET;
+	else if (ti_chip() == CHIP_AM335X)
+		sc->sc_reg_off = AM335X_MMCHS_REG_OFFSET;
+	else
+		panic("Unknown OMAP device\n");
+
+	/* Get the physical address of the MMC data register, needed for DMA */
+	sc->sc_data_reg_paddr = BUS_SPACE_PHYSADDR(sc->sc_mem_res, 
+	    sc->sc_reg_off + MMCHS_DATA);
+
+	/* Set the initial power state to off */
+	sc->sc_cur_power_mode = power_off;
+
+	return (0);
+
+errout:
+	ti_mmchs_deactivate(dev);
+	return (ENOMEM);
+}
+
+/**
+ *	ti_mmchs_probe - probe function for the driver
+ *	@dev: mmc device handle
+ *
+ *
+ *
+ *	RETURNS:
+ *	always returns 0
+ */
+static int
+ti_mmchs_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "ti,mmchs"))
+		return (ENXIO);
+
+	device_set_desc(dev, "TI MMC/SD/SDIO High Speed Interface");
+	return (0);
+}
+
+/**
+ *	ti_mmchs_attach - attach function for the driver
+ *	@dev: mmc device handle
+ *
+ *	Driver initialisation, sets-up the bus mappings, DMA mapping/channels and
+ *	the actual controller by calling ti_mmchs_init().
+ *
+ *	RETURNS:
+ *	Returns 0 on success or a negative error code.
+ */
+static int
+ti_mmchs_attach(device_t dev)
+{
+	struct ti_mmchs_softc *sc = device_get_softc(dev);
+	int unit = device_get_unit(dev);
+	phandle_t node;
+	pcell_t did;
+	int err;
+
+	/* Save the device and bus tag */
+	sc->sc_dev = dev;
+
+	/* Get the mmchs device id from FDT */
+	node = ofw_bus_get_node(dev);
+	if ((OF_getprop(node, "mmchs-device-id", &did, sizeof(did))) <= 0) {
+	    device_printf(dev, "missing mmchs-device-id attribute in FDT\n");
+		return (ENXIO);
+	}
+	sc->device_id = fdt32_to_cpu(did);
+
+	/* Initiate the mtex lock */
+	TI_MMCHS_LOCK_INIT(sc);
+
+	/* Indicate the DMA channels haven't yet been allocated */
+	sc->sc_dmach_rd = (unsigned int)-1;
+	sc->sc_dmach_wr = (unsigned int)-1;
+
+	/* Get the hint'ed write detect pin */
+	/* TODO: take this from FDT */
+	if (resource_int_value("ti_mmchs", unit, "wp_gpio", &sc->sc_wp_gpio_pin) != 0){
+		sc->sc_wp_gpio_pin = -1;
+	} else {
+		/* Get the GPIO device, we need this for the write protect pin */
+		sc->sc_gpio_dev = devclass_get_device(devclass_find("gpio"), 0);
+		if (sc->sc_gpio_dev == NULL)
+			device_printf(dev, "Error: failed to get the GPIO device\n");
+		else
+			GPIO_PIN_SETFLAGS(sc->sc_gpio_dev, sc->sc_wp_gpio_pin,
+			                  GPIO_PIN_INPUT);
+	}
+
+	/* Get the TWL voltage regulator device, we need this to for setting the
+	 * voltage of the bus on certain OMAP platforms.
+	 */
+	sc->sc_vreg_name = NULL;
+
+	/* TODO: add voltage regulator knob to FDT */
+#ifdef notyet
+	sc->sc_vreg_dev = devclass_get_device(devclass_find("twl_vreg"), 0);
+	if (sc->sc_vreg_dev == NULL) {
+		device_printf(dev, "Error: failed to get the votlage regulator"
+		    " device\n");
+		sc->sc_vreg_name = NULL;
+	}
+#endif
+
+	/* Activate the device */
+	err = ti_mmchs_activate(dev);
+	if (err)
+		goto out;
+
+	/* Initialise the controller */
+	ti_mmchs_hw_init(dev);
+
+	/* Activate the interrupt and attach a handler */
+	err = bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
+	    NULL, ti_mmchs_intr, sc, &sc->sc_irq_h);
+	if (err != 0)
+		goto out;
+
+	/* Add host details */
+	sc->host.f_min = sc->sc_ref_freq / 1023;
+	sc->host.f_max = sc->sc_ref_freq;
+	sc->host.host_ocr = MMC_OCR_290_300 | MMC_OCR_300_310;
+	sc->host.caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA;
+
+	device_add_child(dev, "mmc", 0);
+
+	err = bus_generic_attach(dev);
+
+out:
+	if (err) {
+		TI_MMCHS_LOCK_DESTROY(sc);
+		ti_mmchs_deactivate(dev);
+
+#ifdef SOC_TI_AM335X
+		printf("%s: DMA unimplemented\n", __func__);
+#else
+		if (sc->sc_dmach_rd != (unsigned int)-1)
+			ti_sdma_deactivate_channel(sc->sc_dmach_rd);
+		if (sc->sc_dmach_wr != (unsigned int)-1)
+			ti_sdma_deactivate_channel(sc->sc_dmach_wr);
+#endif
+	}
+
+	return (err);
+}
+
+/**
+ *	ti_mmchs_detach - dettach function for the driver
+ *	@dev: mmc device handle
+ *
+ *	Shutdowns the controll and release resources allocated by the driver.
+ *
+ *	RETURNS:
+ *	Always returns 0.
+ */
+static int
+ti_mmchs_detach(device_t dev)
+{
+#ifndef SOC_TI_AM335X
+	struct ti_mmchs_softc *sc = device_get_softc(dev);
+#endif
+
+	ti_mmchs_hw_fini(dev);
+	ti_mmchs_deactivate(dev);
+
+#ifdef SOC_TI_AM335X
+		printf("%s: DMA unimplemented\n", __func__);
+#else
+	ti_sdma_deactivate_channel(sc->sc_dmach_wr);
+	ti_sdma_deactivate_channel(sc->sc_dmach_rd);
+#endif
+
+	return (0);
+}
+
+static device_method_t ti_mmchs_methods[] = {
+	/* device_if */
+	DEVMETHOD(device_probe, ti_mmchs_probe),
+	DEVMETHOD(device_attach, ti_mmchs_attach),
+	DEVMETHOD(device_detach, ti_mmchs_detach),
+
+	/* Bus interface */
+	DEVMETHOD(bus_read_ivar,	ti_mmchs_read_ivar),
+	DEVMETHOD(bus_write_ivar,	ti_mmchs_write_ivar),
+
+	/* mmcbr_if - MMC state machine callbacks */
+	DEVMETHOD(mmcbr_update_ios, ti_mmchs_update_ios),
+	DEVMETHOD(mmcbr_request, ti_mmchs_request),
+	DEVMETHOD(mmcbr_get_ro, ti_mmchs_get_ro),
+	DEVMETHOD(mmcbr_acquire_host, ti_mmchs_acquire_host),
+	DEVMETHOD(mmcbr_release_host, ti_mmchs_release_host),
+
+	{0, 0},
+};
+
+static driver_t ti_mmchs_driver = {
+	"ti_mmchs",
+	ti_mmchs_methods,
+	sizeof(struct ti_mmchs_softc),
+};
+static devclass_t ti_mmchs_devclass;
+
+DRIVER_MODULE(ti_mmchs, simplebus, ti_mmchs_driver, ti_mmchs_devclass, 0, 0);
+MODULE_DEPEND(ti_mmchs, ti_prcm, 1, 1, 1);
+#ifdef SOC_TI_AM335X
+MODULE_DEPEND(ti_mmchs, ti_edma, 1, 1, 1);
+#else
+MODULE_DEPEND(ti_mmchs, ti_sdma, 1, 1, 1);
+#endif
+MODULE_DEPEND(ti_mmchs, ti_gpio, 1, 1, 1);
+
+/* FIXME: MODULE_DEPEND(ti_mmchs, twl_vreg, 1, 1, 1); */


Property changes on: trunk/sys/arm/ti/ti_mmchs.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/ti_mmchs.h
===================================================================
--- trunk/sys/arm/ti/ti_mmchs.h	                        (rev 0)
+++ trunk/sys/arm/ti/ti_mmchs.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,177 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2011
+ *	Ben Gray <ben.r.gray at gmail.com>.
+ * 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 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 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: stable/10/sys/arm/ti/ti_mmchs.h 252863 2013-07-06 04:18:34Z rpaulo $
+ */
+#ifndef _TI_MMCHS_H_
+#define _TI_MMCHS_H_
+
+/**
+ * Header file for the TI MMC/SD/SDIO driver.
+ *
+ * Simply contains register addresses and bit flags.
+ */
+
+/* Register offsets within each of the MMC/SD/SDIO controllers */
+#define MMCHS_SYSCONFIG             0x010
+#define MMCHS_SYSSTATUS             0x014
+#define MMCHS_CSRE                  0x024
+#define MMCHS_SYSTEST               0x028
+#define MMCHS_CON                   0x02C
+#define MMCHS_PWCNT                 0x030
+#define MMCHS_BLK                   0x104
+#define MMCHS_ARG                   0x108
+#define MMCHS_CMD                   0x10C
+#define MMCHS_RSP10                 0x110
+#define MMCHS_RSP32                 0x114
+#define MMCHS_RSP54                 0x118
+#define MMCHS_RSP76                 0x11C
+#define MMCHS_DATA                  0x120
+#define MMCHS_PSTATE                0x124
+#define MMCHS_HCTL                  0x128
+#define MMCHS_SYSCTL                0x12C
+#define MMCHS_STAT                  0x130
+#define MMCHS_IE                    0x134
+#define MMCHS_ISE                   0x138
+#define MMCHS_AC12                  0x13C
+#define MMCHS_CAPA                  0x140
+#define MMCHS_CUR_CAPA              0x148
+#define MMCHS_REV                   0x1FC
+
+/* OMAP4 and OMAP4 have different register addresses */
+#define OMAP3_MMCHS_REG_OFFSET      0x000
+#define OMAP4_MMCHS_REG_OFFSET      0x100
+#define AM335X_MMCHS_REG_OFFSET     0x100
+
+/* Register bit settings */
+#define	MMCHS_SYSCONFIG_CLK_FUN	    (2 << 8)
+#define	MMCHS_SYSCONFIG_CLK_IFC	    (1 << 8)
+#define	MMCHS_SYSCONFIG_SIDL	    (2 << 3)
+#define	MMCHS_SYSCONFIG_ENW	    (1 << 2)
+#define	MMCHS_SYSCONFIG_SRST	    (1 << 1)
+#define	MMCHS_SYSCONFIG_AIDL	    (1 << 0)
+#define MMCHS_STAT_BADA             (1UL << 29)
+#define MMCHS_STAT_CERR             (1UL << 28)
+#define MMCHS_STAT_ACE              (1UL << 24)
+#define MMCHS_STAT_DEB              (1UL << 22)
+#define MMCHS_STAT_DCRC             (1UL << 21)
+#define MMCHS_STAT_DTO              (1UL << 20)
+#define MMCHS_STAT_CIE              (1UL << 19)
+#define MMCHS_STAT_CEB              (1UL << 18)
+#define MMCHS_STAT_CCRC             (1UL << 17)
+#define MMCHS_STAT_CTO              (1UL << 16)
+#define MMCHS_STAT_ERRI             (1UL << 15)
+#define MMCHS_STAT_OBI              (1UL << 9)
+#define MMCHS_STAT_CIRQ             (1UL << 8)
+#define MMCHS_STAT_BRR              (1UL << 5)
+#define MMCHS_STAT_BWR              (1UL << 4)
+#define MMCHS_STAT_BGE              (1UL << 2)
+#define MMCHS_STAT_TC               (1UL << 1)
+#define MMCHS_STAT_CC               (1UL << 0)
+
+#define MMCHS_STAT_CLEAR_MASK       0x3BFF8337UL
+
+#define MMCHS_SYSCTL_SRD            (1UL << 26)
+#define MMCHS_SYSCTL_SRC            (1UL << 25)
+#define MMCHS_SYSCTL_SRA            (1UL << 24)
+#define MMCHS_SYSCTL_DTO(x)         (((x) & 0xf) << 16)
+#define MMCHS_SYSCTL_DTO_MASK       MMCHS_SYSCTL_DTO(0xf)
+#define MMCHS_SYSCTL_CLKD(x)        (((x) & 0x3ff) << 6)
+#define MMCHS_SYSCTL_CLKD_MASK      MMCHS_SYSCTL_CLKD(0x3ff)
+#define MMCHS_SYSCTL_CEN            (1UL << 2)
+#define MMCHS_SYSCTL_ICS            (1UL << 1)
+#define MMCHS_SYSCTL_ICE            (1UL << 0)
+
+#define MMCHS_HCTL_OBWE             (1UL << 27)
+#define MMCHS_HCTL_REM              (1UL << 26)
+#define MMCHS_HCTL_INS              (1UL << 25)
+#define MMCHS_HCTL_IWE              (1UL << 24)
+#define MMCHS_HCTL_IBG              (1UL << 19)
+#define MMCHS_HCTL_RWC              (1UL << 18)
+#define MMCHS_HCTL_CR               (1UL << 17)
+#define MMCHS_HCTL_SBGR             (1UL << 16)
+#define MMCHS_HCTL_SDVS_MASK        (7UL << 9)
+#define MMCHS_HCTL_SDVS_V18         (5UL << 9)
+#define MMCHS_HCTL_SDVS_V30         (6UL << 9)
+#define MMCHS_HCTL_SDVS_V33         (7UL << 9)
+#define MMCHS_HCTL_SDBP             (1UL << 8)
+#define MMCHS_HCTL_DTW              (1UL << 1)
+
+#define MMCHS_CAPA_VS18             (1UL << 26)
+#define MMCHS_CAPA_VS30             (1UL << 25)
+#define MMCHS_CAPA_VS33             (1UL << 24)
+
+#define MMCHS_CMD_CMD_TYPE_IO_ABORT (3UL << 21)
+#define MMCHS_CMD_CMD_TYPE_FUNC_SEL (2UL << 21)
+#define MMCHS_CMD_CMD_TYPE_SUSPEND  (1UL << 21)
+#define MMCHS_CMD_CMD_TYPE_OTHERS   (0UL << 21)
+#define MMCHS_CMD_CMD_TYPE_MASK     (3UL << 22)
+
+#define MMCHS_CMD_DP                (1UL << 21)
+#define MMCHS_CMD_CICE              (1UL << 20)
+#define MMCHS_CMD_CCCE              (1UL << 19)
+
+#define MMCHS_CMD_RSP_TYPE_MASK     (3UL << 16)
+#define MMCHS_CMD_RSP_TYPE_NO       (0UL << 16)
+#define MMCHS_CMD_RSP_TYPE_136      (1UL << 16)
+#define MMCHS_CMD_RSP_TYPE_48       (2UL << 16)
+#define MMCHS_CMD_RSP_TYPE_48_BSY   (3UL << 16)
+
+#define MMCHS_CMD_MSBS              (1UL << 5)
+#define MMCHS_CMD_DDIR              (1UL << 4)
+#define MMCHS_CMD_ACEN              (1UL << 2)
+#define MMCHS_CMD_BCE               (1UL << 1)
+#define MMCHS_CMD_DE                (1UL << 0)
+
+#define MMCHS_CON_CLKEXTFREE        (1UL << 16)
+#define MMCHS_CON_PADEN             (1UL << 15)
+#define MMCHS_CON_OBIE              (1UL << 14)
+#define MMCHS_CON_OBIP              (1UL << 13)
+#define MMCHS_CON_CEATA             (1UL << 12)
+#define MMCHS_CON_CTPL              (1UL << 11)
+
+#define MMCHS_CON_DVAL_8_4MS        (3UL << 9)
+#define MMCHS_CON_DVAL_1MS          (2UL << 9)
+#define MMCHS_CON_DVAL_231US        (1UL << 9)
+#define MMCHS_CON_DVAL_33US         (0UL << 9)
+#define MMCHS_CON_DVAL_MASK         (3UL << 9)
+
+#define MMCHS_CON_WPP               (1UL << 8)
+#define MMCHS_CON_CDP               (1UL << 7)
+#define MMCHS_CON_MIT               (1UL << 6)
+#define MMCHS_CON_DW8               (1UL << 5)
+#define MMCHS_CON_MODE              (1UL << 4)
+#define MMCHS_CON_STR               (1UL << 3)
+#define MMCHS_CON_HR                (1UL << 2)
+#define MMCHS_CON_INIT              (1UL << 1)
+#define MMCHS_CON_OD                (1UL << 0)
+
+#define MMCHS_CAPA_VS18             (1UL << 26)
+#define MMCHS_CAPA_VS30             (1UL << 25)
+#define MMCHS_CAPA_VS33             (1UL << 24)
+
+#endif  /* _TI_MMCHS_H_ */


Property changes on: trunk/sys/arm/ti/ti_mmchs.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/ti_prcm.c
===================================================================
--- trunk/sys/arm/ti/ti_prcm.c	                        (rev 0)
+++ trunk/sys/arm/ti/ti_prcm.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,309 @@
+/* $MidnightBSD$ */
+/*
+ * Copyright (c) 2010
+ *	Ben Gray <ben.r.gray at gmail.com>.
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Ben Gray.
+ * 4. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BEN GRAY ``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 BEN GRAY 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.
+ */
+
+/**
+ * Power, Reset and Clock Managment Module
+ *
+ * This is a very simple driver wrapper around the PRCM set of registers in
+ * the OMAP3 chip. It allows you to turn on and off things like the functional
+ * and interface clocks to the various on-chip modules.
+ *
+ */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/ti/ti_prcm.c 259329 2013-12-13 20:43:11Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+#include <machine/resource.h>
+#include <machine/intr.h>
+
+#include <arm/ti/ti_prcm.h>
+
+/**
+ *	ti_clk_devmap - Array of clock devices, should be defined one per SoC 
+ *
+ *	This array is typically defined in one of the targeted *_prcm_clk.c
+ *	files and is specific to the given SoC platform.  Each entry in the array
+ *	corresponds to an individual clock device.
+ */
+extern struct ti_clock_dev ti_clk_devmap[];
+
+/**
+ *	ti_prcm_clk_dev - returns a pointer to the clock device with given id
+ *	@clk: the ID of the clock device to get
+ *
+ *	Simply iterates through the clk_devmap global array and returns a pointer
+ *	to the clock device if found. 
+ *
+ *	LOCKING:
+ *	None
+ *
+ *	RETURNS:
+ *	The pointer to the clock device on success, on failure NULL is returned.
+ */
+static struct ti_clock_dev *
+ti_prcm_clk_dev(clk_ident_t clk)
+{
+	struct ti_clock_dev *clk_dev;
+	
+	/* Find the clock within the devmap - it's a bit inefficent having a for 
+	 * loop for this, but this function should only called when a driver is 
+	 * being activated so IMHO not a big issue.
+	 */
+	clk_dev = &(ti_clk_devmap[0]);
+	while (clk_dev->id != INVALID_CLK_IDENT) {
+		if (clk_dev->id == clk) {
+			return (clk_dev);
+		}
+		clk_dev++;
+	}
+
+	/* Sanity check we managed to find the clock */
+	printf("ti_prcm: Failed to find clock device (%d)\n", clk);
+	return (NULL);
+}
+
+/**
+ *	ti_prcm_clk_valid - enables a clock for a particular module
+ *	@clk: identifier for the module to enable, see ti_prcm.h for a list
+ *	      of possible modules.
+ *	         Example: OMAP3_MODULE_MMC1_ICLK or OMAP3_MODULE_GPTIMER10_FCLK.
+ *	
+ *	This function can enable either a functional or interface clock.
+ *
+ *	The real work done to enable the clock is really done in the callback
+ *	function associated with the clock, this function is simply a wrapper
+ *	around that.
+ *
+ *	LOCKING:
+ *	Internally locks the driver context.
+ *
+ *	RETURNS:
+ *	Returns 0 on success or positive error code on failure.
+ */
+int
+ti_prcm_clk_valid(clk_ident_t clk)
+{
+	int ret = 0;
+
+	if (ti_prcm_clk_dev(clk) == NULL)
+		ret = EINVAL;
+	
+	return (ret);
+}
+
+
+/**
+ *	ti_prcm_clk_enable - enables a clock for a particular module
+ *	@clk: identifier for the module to enable, see ti_prcm.h for a list
+ *	      of possible modules.
+ *	         Example: OMAP3_MODULE_MMC1_ICLK or OMAP3_MODULE_GPTIMER10_FCLK.
+ *	
+ *	This function can enable either a functional or interface clock.
+ *
+ *	The real work done to enable the clock is really done in the callback
+ *	function associated with the clock, this function is simply a wrapper
+ *	around that.
+ *
+ *	LOCKING:
+ *	Internally locks the driver context.
+ *
+ *	RETURNS:
+ *	Returns 0 on success or positive error code on failure.
+ */
+int
+ti_prcm_clk_enable(clk_ident_t clk)
+{
+	struct ti_clock_dev *clk_dev;
+	int ret;
+
+	/* Find the clock within the devmap - it's a bit inefficent having a for 
+	 * loop for this, but this function should only called when a driver is 
+	 * being activated so IMHO not a big issue.
+	 */
+	clk_dev = ti_prcm_clk_dev(clk);
+
+	/* Sanity check we managed to find the clock */
+	if (clk_dev == NULL)
+		return (EINVAL);
+
+	/* Activate the clock */
+	if (clk_dev->clk_activate)
+		ret = clk_dev->clk_activate(clk_dev);
+	else
+		ret = EINVAL;
+
+	return (ret);
+}
+
+
+/**
+ *	ti_prcm_clk_disable - disables a clock for a particular module
+ *	@clk: identifier for the module to enable, see ti_prcm.h for a list
+ *	      of possible modules.
+ *	         Example: OMAP3_MODULE_MMC1_ICLK or OMAP3_MODULE_GPTIMER10_FCLK.
+ *	
+ *	This function can enable either a functional or interface clock.
+ *
+ *	The real work done to enable the clock is really done in the callback
+ *	function associated with the clock, this function is simply a wrapper
+ *	around that.
+ *
+ *	LOCKING:
+ *	Internally locks the driver context.
+ *
+ *	RETURNS:
+ *	Returns 0 on success or positive error code on failure.
+ */
+int
+ti_prcm_clk_disable(clk_ident_t clk)
+{
+	struct ti_clock_dev *clk_dev;
+	int ret;
+
+	/* Find the clock within the devmap - it's a bit inefficent having a for 
+	 * loop for this, but this function should only called when a driver is 
+	 * being activated so IMHO not a big issue.
+	 */
+	clk_dev = ti_prcm_clk_dev(clk);
+
+	/* Sanity check we managed to find the clock */
+	if (clk_dev == NULL)
+		return (EINVAL);
+
+	/* Activate the clock */
+	if (clk_dev->clk_deactivate)
+		ret = clk_dev->clk_deactivate(clk_dev);
+	else
+		ret = EINVAL;
+	
+	return (ret);
+}
+
+/**
+ *	ti_prcm_clk_set_source - sets the source 
+ *	@clk: identifier for the module to enable, see ti_prcm.h for a list
+ *	      of possible modules.
+ *	         Example: OMAP3_MODULE_MMC1_ICLK or OMAP3_MODULE_GPTIMER10_FCLK.
+ *	
+ *	This function can enable either a functional or interface clock.
+ *
+ *	The real work done to enable the clock is really done in the callback
+ *	function associated with the clock, this function is simply a wrapper
+ *	around that.
+ *
+ *	LOCKING:
+ *	Internally locks the driver context.
+ *
+ *	RETURNS:
+ *	Returns 0 on success or positive error code on failure.
+ */
+int
+ti_prcm_clk_set_source(clk_ident_t clk, clk_src_t clksrc)
+{
+	struct ti_clock_dev *clk_dev;
+	int ret;
+
+	/* Find the clock within the devmap - it's a bit inefficent having a for 
+	 * loop for this, but this function should only called when a driver is 
+	 * being activated so IMHO not a big issue.
+	 */
+	clk_dev = ti_prcm_clk_dev(clk);
+
+	/* Sanity check we managed to find the clock */
+	if (clk_dev == NULL)
+		return (EINVAL);
+
+	/* Activate the clock */
+	if (clk_dev->clk_set_source)
+		ret = clk_dev->clk_set_source(clk_dev, clksrc);
+	else
+		ret = EINVAL;
+
+	return (ret);
+}
+
+
+/**
+ *	ti_prcm_clk_get_source_freq - gets the source clock frequency
+ *	@clk: identifier for the module to enable, see ti_prcm.h for a list
+ *	      of possible modules.
+ *	@freq: pointer to an integer that upon return will contain the src freq
+ *	
+ *	This function returns the frequency of the source clock.
+ *
+ *	The real work done to enable the clock is really done in the callback
+ *	function associated with the clock, this function is simply a wrapper
+ *	around that.
+ *
+ *	LOCKING:
+ *	Internally locks the driver context.
+ *
+ *	RETURNS:
+ *	Returns 0 on success or positive error code on failure.
+ */
+int
+ti_prcm_clk_get_source_freq(clk_ident_t clk, unsigned int *freq)
+{
+	struct ti_clock_dev *clk_dev;
+	int ret;
+
+	/* Find the clock within the devmap - it's a bit inefficent having a for 
+	 * loop for this, but this function should only called when a driver is 
+	 * being activated so IMHO not a big issue.
+	 */
+	clk_dev = ti_prcm_clk_dev(clk);
+
+	/* Sanity check we managed to find the clock */
+	if (clk_dev == NULL)
+		return (EINVAL);
+
+	/* Get the source frequency of the clock */
+	if (clk_dev->clk_get_source_freq)
+		ret = clk_dev->clk_get_source_freq(clk_dev, freq);
+	else
+		ret = EINVAL;
+	
+	return (ret);
+}


Property changes on: trunk/sys/arm/ti/ti_prcm.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/ti_prcm.h
===================================================================
--- trunk/sys/arm/ti/ti_prcm.h	                        (rev 0)
+++ trunk/sys/arm/ti/ti_prcm.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,212 @@
+/* $MidnightBSD$ */
+/*
+ * Copyright (c) 2010
+ *	Ben Gray <ben.r.gray at gmail.com>.
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Ben Gray.
+ * 4. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BEN GRAY ``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 BEN GRAY 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: stable/10/sys/arm/ti/ti_prcm.h 278079 2015-02-02 12:48:13Z loos $
+ */
+
+
+/*
+ * Texas Instruments - OMAP3xxx series processors
+ *
+ * Reference:
+ *  OMAP35x Applications Processor
+ *   Technical Reference Manual
+ *  (omap35xx_techref.pdf)
+ */
+#ifndef _TI_PRCM_H_
+#define _TI_PRCM_H_
+
+typedef enum {
+
+	/* System clocks, typically you can only call ti_prcm_clk_get_source_freq()
+	 * on these clocks as they are enabled by default.
+	 */
+	SYS_CLK = 1,
+
+	/* The MPU (ARM) core clock */
+	MPU_CLK = 20,
+
+	/* MMC modules */
+	MMC0_CLK = 100,
+	MMC1_CLK,
+	MMC2_CLK,
+	MMC3_CLK,
+	MMC4_CLK,
+	MMC5_CLK,
+
+	/* I2C modules */
+	I2C0_CLK = 200,
+	I2C1_CLK,
+	I2C2_CLK,
+	I2C3_CLK,
+	I2C4_CLK,
+
+	/* USB module(s) */
+	USBTLL_CLK = 300,
+	USBHSHOST_CLK,
+	USBFSHOST_CLK,
+	USBP1_PHY_CLK,
+	USBP2_PHY_CLK,
+	USBP1_UTMI_CLK,
+	USBP2_UTMI_CLK,
+	USBP1_HSIC_CLK,
+	USBP2_HSIC_CLK,
+
+	/* UART modules */
+	UART0_CLK = 400,
+	UART1_CLK,
+	UART2_CLK,
+	UART3_CLK,
+	UART4_CLK,
+	UART5_CLK,
+	UART6_CLK,
+	UART7_CLK,
+	UART8_CLK,
+
+	/* General purpose timer modules */
+	GPTIMER1_CLK = 500,
+	GPTIMER2_CLK,
+	GPTIMER3_CLK,
+	GPTIMER4_CLK,
+	GPTIMER5_CLK,
+	GPTIMER6_CLK,
+	GPTIMER7_CLK,
+	GPTIMER8_CLK,
+	GPTIMER9_CLK,
+	GPTIMER10_CLK,
+	GPTIMER11_CLK,
+	GPTIMER12_CLK,
+
+	/* McBSP module(s) */
+	MCBSP1_CLK = 600,
+	MCBSP2_CLK,
+	MCBSP3_CLK,
+	MCBSP4_CLK,
+	MCBSP5_CLK,
+
+	/* General purpose I/O modules */
+	GPIO0_CLK = 700,
+	GPIO1_CLK,
+	GPIO2_CLK,
+	GPIO3_CLK,
+	GPIO4_CLK,
+	GPIO5_CLK,
+	GPIO6_CLK,
+
+	/* sDMA module */
+	SDMA_CLK = 800,
+
+	/* DMTimer modules */
+	DMTIMER0_CLK = 900,
+	DMTIMER1_CLK,
+	DMTIMER2_CLK,
+	DMTIMER3_CLK,
+	DMTIMER4_CLK,
+	DMTIMER5_CLK,
+	DMTIMER6_CLK,
+	DMTIMER7_CLK,
+
+	/* CPSW modules */
+	CPSW_CLK = 1000,
+
+	/* Mentor USB modules */
+	MUSB0_CLK = 1100,
+
+	/* EDMA module */
+	EDMA_TPCC_CLK = 1200,
+	EDMA_TPTC0_CLK,
+	EDMA_TPTC1_CLK,
+	EDMA_TPTC2_CLK,
+
+	/* LCD controller module */
+	LCDC_CLK = 1300,
+
+	/* PWM modules */
+	PWMSS0_CLK = 1400,
+	PWMSS1_CLK,
+	PWMSS2_CLK,
+
+	/* Mailbox modules */
+	MAILBOX0_CLK = 1500,
+
+	/* Spinlock modules */
+	SPINLOCK0_CLK = 1600,
+
+	PRUSS_CLK = 1700,
+
+	TSC_ADC_CLK = 1800,
+
+	/* RTC module */
+	RTC_CLK = 1900,
+
+	INVALID_CLK_IDENT
+
+} clk_ident_t;
+
+/*
+ *
+ */
+typedef enum {
+	SYSCLK_CLK,   /* System clock */
+	EXT_CLK,
+
+	F32KHZ_CLK,   /* 32KHz clock */
+	F48MHZ_CLK,   /* 48MHz clock */
+	F64MHZ_CLK,   /* 64MHz clock */
+	F96MHZ_CLK,   /* 96MHz clock */
+
+} clk_src_t;
+
+struct ti_clock_dev {
+	/* The profile of the timer */
+	clk_ident_t  id;
+
+	/* A bunch of callbacks associated with the clock device */
+	int (*clk_activate)(struct ti_clock_dev *clkdev);
+	int (*clk_deactivate)(struct ti_clock_dev *clkdev);
+	int (*clk_set_source)(struct ti_clock_dev *clkdev,
+	    clk_src_t clksrc);
+	int (*clk_accessible)(struct ti_clock_dev *clkdev);
+	int (*clk_get_source_freq)(struct ti_clock_dev *clkdev,
+	    unsigned int *freq);
+};
+
+int ti_prcm_clk_valid(clk_ident_t clk);
+int ti_prcm_clk_enable(clk_ident_t clk);
+int ti_prcm_clk_disable(clk_ident_t clk);
+int ti_prcm_clk_accessible(clk_ident_t clk);
+int ti_prcm_clk_disable_autoidle(clk_ident_t clk);
+int ti_prcm_clk_set_source(clk_ident_t clk, clk_src_t clksrc);
+int ti_prcm_clk_get_source_freq(clk_ident_t clk, unsigned int *freq);
+void ti_prcm_reset(void);
+
+#endif   /* _TI_PRCM_H_ */


Property changes on: trunk/sys/arm/ti/ti_prcm.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/ti_pruss.c
===================================================================
--- trunk/sys/arm/ti/ti_pruss.c	                        (rev 0)
+++ trunk/sys/arm/ti/ti_pruss.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,307 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Rui Paulo <rpaulo at FreeBSD.org>
+ * 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 ``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 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: stable/10/sys/arm/ti/ti_pruss.c 278432 2015-02-09 02:49:10Z rpaulo $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/event.h>
+#include <sys/selinfo.h>
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/frame.h>
+#include <machine/intr.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+
+#include <arm/ti/ti_prcm.h>
+#include <arm/ti/ti_pruss.h>
+
+#define DEBUG
+#ifdef DEBUG
+#define	DPRINTF(fmt, ...)	do {	\
+	printf("%s: ", __func__);	\
+	printf(fmt, __VA_ARGS__);	\
+} while (0)
+#else
+#define	DPRINTF(fmt, ...)
+#endif
+
+static device_probe_t		ti_pruss_probe;
+static device_attach_t		ti_pruss_attach;
+static device_detach_t		ti_pruss_detach;
+static void			ti_pruss_intr(void *);
+static d_open_t			ti_pruss_open;
+static d_mmap_t			ti_pruss_mmap;
+static void 			ti_pruss_kq_read_detach(struct knote *);
+static int 			ti_pruss_kq_read_event(struct knote *, long);
+static d_kqfilter_t		ti_pruss_kqfilter;
+
+#define	TI_PRUSS_IRQS	8
+struct ti_pruss_softc {
+	struct mtx		sc_mtx;
+	struct resource 	*sc_mem_res;
+	struct resource 	*sc_irq_res[TI_PRUSS_IRQS];
+	void            	*sc_intr[TI_PRUSS_IRQS];
+	bus_space_tag_t		sc_bt;
+	bus_space_handle_t	sc_bh;
+	struct cdev		*sc_pdev;
+	struct selinfo		sc_selinfo;
+};
+
+static struct cdevsw ti_pruss_cdevsw = {
+	.d_version =	D_VERSION,
+	.d_name =	"ti_pruss",
+	.d_open =	ti_pruss_open,
+	.d_mmap =	ti_pruss_mmap,
+	.d_kqfilter =	ti_pruss_kqfilter,
+};
+
+static device_method_t ti_pruss_methods[] = {
+	DEVMETHOD(device_probe,		ti_pruss_probe),
+	DEVMETHOD(device_attach,	ti_pruss_attach),
+	DEVMETHOD(device_detach,	ti_pruss_detach),
+
+	DEVMETHOD_END
+};
+
+static driver_t ti_pruss_driver = {
+	"ti_pruss",
+	ti_pruss_methods,
+	sizeof(struct ti_pruss_softc)
+};
+
+static devclass_t ti_pruss_devclass;
+
+DRIVER_MODULE(ti_pruss, simplebus, ti_pruss_driver, ti_pruss_devclass, 0, 0);
+
+static struct resource_spec ti_pruss_irq_spec[] = {
+	{ SYS_RES_IRQ,	    0,  RF_ACTIVE },
+	{ SYS_RES_IRQ,	    1,  RF_ACTIVE },
+	{ SYS_RES_IRQ,	    2,  RF_ACTIVE },
+	{ SYS_RES_IRQ,	    3,  RF_ACTIVE },
+	{ SYS_RES_IRQ,	    4,  RF_ACTIVE },
+	{ SYS_RES_IRQ,	    5,  RF_ACTIVE },
+	{ SYS_RES_IRQ,	    6,  RF_ACTIVE },
+	{ SYS_RES_IRQ,	    7,  RF_ACTIVE },
+	{ -1,               0,  0 }
+};
+
+static struct ti_pruss_irq_arg {
+	int 		       irq;
+	struct ti_pruss_softc *sc;
+} ti_pruss_irq_args[TI_PRUSS_IRQS];
+
+static __inline uint32_t
+ti_pruss_reg_read(struct ti_pruss_softc *sc, uint32_t reg)
+{
+	return (bus_space_read_4(sc->sc_bt, sc->sc_bh, reg));
+}
+
+static __inline void
+ti_pruss_reg_write(struct ti_pruss_softc *sc, uint32_t reg, uint32_t val)
+{
+	bus_space_write_4(sc->sc_bt, sc->sc_bh, reg, val);
+}
+
+static int
+ti_pruss_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (ofw_bus_is_compatible(dev, "ti,pruss-v1") ||
+	    ofw_bus_is_compatible(dev, "ti,pruss-v2")) {
+		device_set_desc(dev, "TI Programmable Realtime Unit Subsystem");
+		return (BUS_PROBE_DEFAULT);
+	}
+
+	return (ENXIO);
+}
+
+static int
+ti_pruss_attach(device_t dev)
+{
+	struct ti_pruss_softc *sc;
+	int rid, i;
+
+	if (ti_prcm_clk_enable(PRUSS_CLK) != 0) {
+		device_printf(dev, "could not enable PRUSS clock\n");
+		return (ENXIO);
+	}
+	sc = device_get_softc(dev);
+	rid = 0;
+	mtx_init(&sc->sc_mtx, "TI PRUSS", NULL, MTX_DEF);
+	sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	    RF_ACTIVE);
+	if (sc->sc_mem_res == NULL) {
+		device_printf(dev, "could not allocate memory resource\n");
+		return (ENXIO);
+	}
+	sc->sc_bt = rman_get_bustag(sc->sc_mem_res);
+	sc->sc_bh = rman_get_bushandle(sc->sc_mem_res);
+	if (bus_alloc_resources(dev, ti_pruss_irq_spec, sc->sc_irq_res) != 0) {
+		device_printf(dev, "could not allocate interrupt resource\n");
+		ti_pruss_detach(dev);
+		return (ENXIO);
+	}
+	for (i = 0; i < TI_PRUSS_IRQS; i++) {
+		ti_pruss_irq_args[i].irq = i;
+		ti_pruss_irq_args[i].sc = sc;
+		if (bus_setup_intr(dev, sc->sc_irq_res[i],
+		    INTR_MPSAFE | INTR_TYPE_MISC,
+		    NULL, ti_pruss_intr, &ti_pruss_irq_args[i],
+		    &sc->sc_intr[i]) != 0) {
+			device_printf(dev,
+			    "unable to setup the interrupt handler\n");
+			ti_pruss_detach(dev);
+			return (ENXIO);
+		}
+	}
+	if (ti_pruss_reg_read(sc, PRUSS_AM18XX_INTC) == PRUSS_AM18XX_REV)
+		device_printf(dev, "AM18xx PRU-ICSS\n");
+	else if (ti_pruss_reg_read(sc, PRUSS_AM33XX_INTC) == PRUSS_AM33XX_REV)
+		device_printf(dev, "AM33xx PRU-ICSS\n");
+
+	sc->sc_pdev = make_dev(&ti_pruss_cdevsw, 0, UID_ROOT, GID_WHEEL,
+	    0600, "pruss%d", device_get_unit(dev));
+	sc->sc_pdev->si_drv1 = dev;
+
+	return (0);
+}
+
+static int
+ti_pruss_detach(device_t dev)
+{
+	struct ti_pruss_softc *sc;
+	int i;
+
+	sc = device_get_softc(dev);
+	for (i = 0; i < TI_PRUSS_IRQS; i++) {
+		if (sc->sc_intr[i])
+			bus_teardown_intr(dev, sc->sc_irq_res[i], sc->sc_intr[i]);
+		if (sc->sc_irq_res[i])
+			bus_release_resource(dev, SYS_RES_IRQ,
+			    rman_get_rid(sc->sc_irq_res[i]),
+			    sc->sc_irq_res[i]);
+	}
+	if (sc->sc_mem_res)
+		bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(sc->sc_mem_res),
+		    sc->sc_mem_res);
+	if (sc->sc_pdev)
+		destroy_dev(sc->sc_pdev);
+
+	return (0);
+}
+
+static void
+ti_pruss_intr(void *arg)
+{
+	struct ti_pruss_irq_arg *iap;
+	struct ti_pruss_softc *sc;
+
+	iap = arg;
+	sc = iap->sc;
+	DPRINTF("interrupt %p", sc);
+	KNOTE_UNLOCKED(&sc->sc_selinfo.si_note, iap->irq);
+}
+
+static int
+ti_pruss_open(struct cdev *cdev __unused, int oflags __unused,
+    int devtype __unused, struct thread *td __unused)
+{
+	return (0);
+}
+
+static int
+ti_pruss_mmap(struct cdev *cdev, vm_ooffset_t offset, vm_paddr_t *paddr,
+    int nprot, vm_memattr_t *memattr)
+{
+	device_t dev = cdev->si_drv1;
+	struct ti_pruss_softc *sc = device_get_softc(dev);
+
+	if (offset > rman_get_size(sc->sc_mem_res))
+		return (-1);
+	*paddr = rman_get_start(sc->sc_mem_res) + offset;
+	*memattr = VM_MEMATTR_UNCACHEABLE;
+
+	return (0);
+}
+
+static struct filterops ti_pruss_kq_read = {
+	.f_isfd = 1,
+	.f_detach = ti_pruss_kq_read_detach,
+	.f_event = ti_pruss_kq_read_event,
+};
+
+static void
+ti_pruss_kq_read_detach(struct knote *kn)
+{
+	struct ti_pruss_softc *sc = kn->kn_hook;
+
+	knlist_remove(&sc->sc_selinfo.si_note, kn, 0);
+}
+
+static int
+ti_pruss_kq_read_event(struct knote *kn, long hint)
+{
+	kn->kn_data = hint;
+
+	return (hint);
+}
+
+static int
+ti_pruss_kqfilter(struct cdev *cdev, struct knote *kn)
+{
+	device_t dev = cdev->si_drv1;
+	struct ti_pruss_softc *sc = device_get_softc(dev);
+
+	switch (kn->kn_filter) {
+	case EVFILT_READ:
+		kn->kn_hook = sc;
+		kn->kn_fop = &ti_pruss_kq_read;
+		knlist_add(&sc->sc_selinfo.si_note, kn, 1);
+		break;
+	default:
+		return (EINVAL);
+	}
+
+	return (0);
+}


Property changes on: trunk/sys/arm/ti/ti_pruss.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/ti_pruss.h
===================================================================
--- trunk/sys/arm/ti/ti_pruss.h	                        (rev 0)
+++ trunk/sys/arm/ti/ti_pruss.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,37 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Rui Paulo <rpaulo at FreeBSD.org>
+ * 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 ``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 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: stable/10/sys/arm/ti/ti_pruss.h 266098 2014-05-14 23:57:07Z ian $
+ */
+#ifndef _TI_PRUSS_H_
+#define _TI_PRUSS_H_
+
+#define	PRUSS_AM18XX_INTC	0x04000
+#define	PRUSS_AM18XX_REV	0x4e825900
+#define	PRUSS_AM33XX_REV	0x4e82A900
+#define	PRUSS_AM33XX_INTC	0x20000
+
+#endif /* _TI_PRUSS_H_ */


Property changes on: trunk/sys/arm/ti/ti_pruss.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/ti_scm.c
===================================================================
--- trunk/sys/arm/ti/ti_scm.c	                        (rev 0)
+++ trunk/sys/arm/ti/ti_scm.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,504 @@
+/* $MidnightBSD$ */
+/*
+ * Copyright (c) 2010
+ *	Ben Gray <ben.r.gray at gmail.com>.
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Ben Gray.
+ * 4. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BEN GRAY ``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 BEN GRAY 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.
+ */
+
+/**
+ *	SCM - System Control Module
+ *
+ *	Hopefully in the end this module will contain a bunch of utility functions
+ *	for configuring and querying the general system control registers, but for
+ *	now it only does pin(pad) multiplexing.
+ *
+ *	This is different from the GPIO module in that it is used to configure the
+ *	pins between modules not just GPIO input/output.
+ *
+ *	This file contains the generic top level driver, however it relies on chip
+ *	specific settings and therefore expects an array of ti_scm_padconf structs
+ *	call ti_padconf_devmap to be located somewhere in the kernel.
+ *
+ */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/ti/ti_scm.c 266152 2014-05-15 16:11:06Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+#include <machine/resource.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include "ti_scm.h"
+
+static struct resource_spec ti_scm_res_spec[] = {
+	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },	/* Control memory window */
+	{ -1, 0 }
+};
+
+static struct ti_scm_softc *ti_scm_sc;
+
+#define	ti_scm_read_2(sc, reg)		\
+    bus_space_read_2((sc)->sc_bst, (sc)->sc_bsh, (reg))
+#define	ti_scm_write_2(sc, reg, val)		\
+    bus_space_write_2((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
+#define	ti_scm_read_4(sc, reg)		\
+    bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
+#define	ti_scm_write_4(sc, reg, val)		\
+    bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
+
+
+/**
+ *	ti_padconf_devmap - Array of pins, should be defined one per SoC
+ *
+ *	This array is typically defined in one of the targeted *_scm_pinumx.c
+ *	files and is specific to the given SoC platform. Each entry in the array
+ *	corresponds to an individual pin.
+ */
+extern const struct ti_scm_device ti_scm_dev;
+
+
+/**
+ *	ti_scm_padconf_from_name - searches the list of pads and returns entry
+ *	                             with matching ball name.
+ *	@ballname: the name of the ball
+ *
+ *	RETURNS:
+ *	A pointer to the matching padconf or NULL if the ball wasn't found.
+ */
+static const struct ti_scm_padconf*
+ti_scm_padconf_from_name(const char *ballname)
+{
+	const struct ti_scm_padconf *padconf;
+
+	padconf = ti_scm_dev.padconf;
+	while (padconf->ballname != NULL) {
+		if (strcmp(ballname, padconf->ballname) == 0)
+			return(padconf);
+		padconf++;
+	}
+	
+	return (NULL);
+}
+
+/**
+ *	ti_scm_padconf_set_internal - sets the muxmode and state for a pad/pin
+ *	@padconf: pointer to the pad structure
+ *	@muxmode: the name of the mode to use for the pin, i.e. "uart1_rx"
+ *	@state: the state to put the pad/pin in, i.e. PADCONF_PIN_???
+ *	
+ *
+ *	LOCKING:
+ *	Internally locks it's own context.
+ *
+ *	RETURNS:
+ *	0 on success.
+ *	EINVAL if pin requested is outside valid range or already in use.
+ */
+static int
+ti_scm_padconf_set_internal(struct ti_scm_softc *sc,
+    const struct ti_scm_padconf *padconf,
+    const char *muxmode, unsigned int state)
+{
+	unsigned int mode;
+	uint16_t reg_val;
+
+	/* populate the new value for the PADCONF register */
+	reg_val = (uint16_t)(state & ti_scm_dev.padconf_sate_mask);
+
+	/* find the new mode requested */
+	for (mode = 0; mode < 8; mode++) {
+		if ((padconf->muxmodes[mode] != NULL) &&
+		    (strcmp(padconf->muxmodes[mode], muxmode) == 0)) {
+			break;
+		}
+	}
+
+	/* couldn't find the mux mode */
+	if (mode >= 8) {
+		printf("Invalid mode \"%s\"\n", muxmode);
+		return (EINVAL);
+	}
+
+	/* set the mux mode */
+	reg_val |= (uint16_t)(mode & ti_scm_dev.padconf_muxmode_mask);
+	
+	if (bootverbose)
+		device_printf(sc->sc_dev, "setting internal %x for %s\n", 
+		    reg_val, muxmode);
+	/* write the register value (16-bit writes) */
+	ti_scm_write_2(sc, padconf->reg_off, reg_val);
+	
+	return (0);
+}
+
+/**
+ *	ti_scm_padconf_set - sets the muxmode and state for a pad/pin
+ *	@padname: the name of the pad, i.e. "c12"
+ *	@muxmode: the name of the mode to use for the pin, i.e. "uart1_rx"
+ *	@state: the state to put the pad/pin in, i.e. PADCONF_PIN_???
+ *	
+ *
+ *	LOCKING:
+ *	Internally locks it's own context.
+ *
+ *	RETURNS:
+ *	0 on success.
+ *	EINVAL if pin requested is outside valid range or already in use.
+ */
+int
+ti_scm_padconf_set(const char *padname, const char *muxmode, unsigned int state)
+{
+	const struct ti_scm_padconf *padconf;
+
+	if (!ti_scm_sc)
+		return (ENXIO);
+
+	/* find the pin in the devmap */
+	padconf = ti_scm_padconf_from_name(padname);
+	if (padconf == NULL)
+		return (EINVAL);
+	
+	return (ti_scm_padconf_set_internal(ti_scm_sc, padconf, muxmode, state));
+}
+
+/**
+ *	ti_scm_padconf_get - gets the muxmode and state for a pad/pin
+ *	@padname: the name of the pad, i.e. "c12"
+ *	@muxmode: upon return will contain the name of the muxmode of the pin
+ *	@state: upon return will contain the state of the pad/pin
+ *	
+ *
+ *	LOCKING:
+ *	Internally locks it's own context.
+ *
+ *	RETURNS:
+ *	0 on success.
+ *	EINVAL if pin requested is outside valid range or already in use.
+ */
+int
+ti_scm_padconf_get(const char *padname, const char **muxmode,
+    unsigned int *state)
+{
+	const struct ti_scm_padconf *padconf;
+	uint16_t reg_val;
+
+	if (!ti_scm_sc)
+		return (ENXIO);
+
+	/* find the pin in the devmap */
+	padconf = ti_scm_padconf_from_name(padname);
+	if (padconf == NULL)
+		return (EINVAL);
+	
+	/* read the register value (16-bit reads) */
+	reg_val = ti_scm_read_2(ti_scm_sc, padconf->reg_off);
+
+	/* save the state */
+	if (state)
+		*state = (reg_val & ti_scm_dev.padconf_sate_mask);
+
+	/* save the mode */
+	if (muxmode)
+		*muxmode = padconf->muxmodes[(reg_val & ti_scm_dev.padconf_muxmode_mask)];
+	
+	return (0);
+}
+
+/**
+ *	ti_scm_padconf_set_gpiomode - converts a pad to GPIO mode.
+ *	@gpio: the GPIO pin number (0-195)
+ *	@state: the state to put the pad/pin in, i.e. PADCONF_PIN_???
+ *
+ *	
+ *
+ *	LOCKING:
+ *	Internally locks it's own context.
+ *
+ *	RETURNS:
+ *	0 on success.
+ *	EINVAL if pin requested is outside valid range or already in use.
+ */
+int
+ti_scm_padconf_set_gpiomode(uint32_t gpio, unsigned int state)
+{
+	const struct ti_scm_padconf *padconf;
+	uint16_t reg_val;
+
+	if (!ti_scm_sc)
+		return (ENXIO);
+	
+	/* find the gpio pin in the padconf array */
+	padconf = ti_scm_dev.padconf;
+	while (padconf->ballname != NULL) {
+		if (padconf->gpio_pin == gpio)
+			break;
+		padconf++;
+	}
+	if (padconf->ballname == NULL)
+		return (EINVAL);
+
+	/* populate the new value for the PADCONF register */
+	reg_val = (uint16_t)(state & ti_scm_dev.padconf_sate_mask);
+
+	/* set the mux mode */
+	reg_val |= (uint16_t)(padconf->gpio_mode & ti_scm_dev.padconf_muxmode_mask);
+
+	/* write the register value (16-bit writes) */
+	ti_scm_write_2(ti_scm_sc, padconf->reg_off, reg_val);
+
+	return (0);
+}
+
+/**
+ *	ti_scm_padconf_get_gpiomode - gets the current GPIO mode of the pin
+ *	@gpio: the GPIO pin number (0-195)
+ *	@state: upon return will contain the state
+ *
+ *	
+ *
+ *	LOCKING:
+ *	Internally locks it's own context.
+ *
+ *	RETURNS:
+ *	0 on success.
+ *	EINVAL if pin requested is outside valid range or not configured as GPIO.
+ */
+int
+ti_scm_padconf_get_gpiomode(uint32_t gpio, unsigned int *state)
+{
+	const struct ti_scm_padconf *padconf;
+	uint16_t reg_val;
+
+	if (!ti_scm_sc)
+		return (ENXIO);
+	
+	/* find the gpio pin in the padconf array */
+	padconf = ti_scm_dev.padconf;
+	while (padconf->ballname != NULL) {
+		if (padconf->gpio_pin == gpio)
+			break;
+		padconf++;
+	}
+	if (padconf->ballname == NULL)
+		return (EINVAL);
+
+	/* read the current register settings */
+	reg_val = ti_scm_read_2(ti_scm_sc, padconf->reg_off);
+	
+	/* check to make sure the pins is configured as GPIO in the first state */
+	if ((reg_val & ti_scm_dev.padconf_muxmode_mask) != padconf->gpio_mode)
+		return (EINVAL);
+	
+	/* read and store the reset of the state, i.e. pull-up, pull-down, etc */
+	if (state)
+		*state = (reg_val & ti_scm_dev.padconf_sate_mask);
+	
+	return (0);
+}
+
+/**
+ *	ti_scm_padconf_init_from_hints - processes the hints for padconf
+ *	@sc: the driver soft context
+ *
+ *	
+ *
+ *	LOCKING:
+ *	Internally locks it's own context.
+ *
+ *	RETURNS:
+ *	0 on success.
+ *	EINVAL if pin requested is outside valid range or already in use.
+ */
+static int
+ti_scm_padconf_init_from_fdt(struct ti_scm_softc *sc)
+{
+	const struct ti_scm_padconf *padconf;
+	const struct ti_scm_padstate *padstates;
+	int err;
+	phandle_t node;
+	int len;
+	char *fdt_pad_config;
+	int i;
+	char *padname, *muxname, *padstate;
+
+	node = ofw_bus_get_node(sc->sc_dev);
+	len = OF_getproplen(node, "scm-pad-config");
+        OF_getprop_alloc(node, "scm-pad-config", 1, (void **)&fdt_pad_config);
+
+	i = len;
+	while (i > 0) {
+		padname = fdt_pad_config;
+		fdt_pad_config += strlen(padname) + 1;
+		i -= strlen(padname) + 1;
+		if (i <= 0)
+			break;
+
+		muxname = fdt_pad_config;
+		fdt_pad_config += strlen(muxname) + 1;
+		i -= strlen(muxname) + 1;
+		if (i <= 0)
+			break;
+
+		padstate = fdt_pad_config;
+		fdt_pad_config += strlen(padstate) + 1;
+		i -= strlen(padstate) + 1;
+		if (i < 0)
+			break;
+
+		padconf = ti_scm_dev.padconf;
+
+		while (padconf->ballname != NULL) {
+			if (strcmp(padconf->ballname, padname) == 0) {
+				padstates = ti_scm_dev.padstate;
+				err = 1;
+				while (padstates->state != NULL) {
+					if (strcmp(padstates->state, padstate) == 0) {
+						err = ti_scm_padconf_set_internal(sc,
+						    padconf, muxname, padstates->reg);
+					}
+					padstates++;
+				}
+				if (err)
+					device_printf(sc->sc_dev,
+					    "err: failed to configure "
+					    "pin \"%s\" as \"%s\"\n",
+					    padconf->ballname,
+					    muxname);
+			}
+			padconf++;
+		}
+	}
+	return (0);
+}
+
+/*
+ * Device part of OMAP SCM driver
+ */
+
+static int
+ti_scm_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "ti,scm"))
+		return (ENXIO);
+
+	device_set_desc(dev, "TI Control Module");
+	return (BUS_PROBE_DEFAULT);
+}
+
+/**
+ *	ti_scm_attach - attaches the timer to the simplebus
+ *	@dev: new device
+ *
+ *	Reserves memory and interrupt resources, stores the softc structure
+ *	globally and registers both the timecount and eventtimer objects.
+ *
+ *	RETURNS
+ *	Zero on sucess or ENXIO if an error occuried.
+ */
+static int
+ti_scm_attach(device_t dev)
+{
+	struct ti_scm_softc *sc = device_get_softc(dev);
+
+	if (ti_scm_sc)
+		return (ENXIO);
+
+	sc->sc_dev = dev;
+
+	if (bus_alloc_resources(dev, ti_scm_res_spec, sc->sc_res)) {
+		device_printf(dev, "could not allocate resources\n");
+		return (ENXIO);
+	}
+
+	/* Global timer interface */
+	sc->sc_bst = rman_get_bustag(sc->sc_res[0]);
+	sc->sc_bsh = rman_get_bushandle(sc->sc_res[0]);
+
+	ti_scm_sc = sc;
+
+	ti_scm_padconf_init_from_fdt(sc);
+
+	return (0);
+}
+
+int
+ti_scm_reg_read_4(uint32_t reg, uint32_t *val)
+{
+	if (!ti_scm_sc)
+		return (ENXIO);
+
+	*val = ti_scm_read_4(ti_scm_sc, reg);
+	return (0);
+}
+
+int
+ti_scm_reg_write_4(uint32_t reg, uint32_t val)
+{
+	if (!ti_scm_sc)
+		return (ENXIO);
+
+	ti_scm_write_4(ti_scm_sc, reg, val);
+	return (0);
+}
+
+
+static device_method_t ti_scm_methods[] = {
+	DEVMETHOD(device_probe,		ti_scm_probe),
+	DEVMETHOD(device_attach,	ti_scm_attach),
+	{ 0, 0 }
+};
+
+static driver_t ti_scm_driver = {
+	"ti_scm",
+	ti_scm_methods,
+	sizeof(struct ti_scm_softc),
+};
+
+static devclass_t ti_scm_devclass;
+
+DRIVER_MODULE(ti_scm, simplebus, ti_scm_driver, ti_scm_devclass, 0, 0);


Property changes on: trunk/sys/arm/ti/ti_scm.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/ti_scm.h
===================================================================
--- trunk/sys/arm/ti/ti_scm.h	                        (rev 0)
+++ trunk/sys/arm/ti/ti_scm.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,85 @@
+/* $MidnightBSD$ */
+/*
+ * Copyright (c) 2010
+ *	Ben Gray <ben.r.gray at gmail.com>.
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Ben Gray.
+ * 4. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BEN GRAY ``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 BEN GRAY 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: stable/10/sys/arm/ti/ti_scm.h 279467 2015-03-01 01:08:14Z dim $
+ */
+
+
+/**
+ *	Functions to configure the PIN multiplexing on the chip.
+ *
+ *	This is different from the GPIO module in that it is used to configure the
+ *	pins between modules not just GPIO input output.
+ *
+ */
+#ifndef _TI_SCM_H_
+#define _TI_SCM_H_
+
+struct ti_scm_padconf {
+	uint16_t    reg_off;
+	uint16_t    gpio_pin;
+	uint16_t    gpio_mode;
+	const char  *ballname;
+	const char  *muxmodes[8];
+};
+
+struct ti_scm_padstate {
+	const char  *state;
+	uint16_t    reg;
+};
+
+struct ti_scm_device {
+	uint16_t		padconf_muxmode_mask;
+	uint16_t		padconf_sate_mask;
+	const struct ti_scm_padstate	*padstate;
+	const struct ti_scm_padconf	*padconf;
+};
+
+struct ti_scm_softc {
+	device_t		sc_dev;
+	struct resource *	sc_res[4];
+	bus_space_tag_t		sc_bst;
+	bus_space_handle_t	sc_bsh;
+};
+
+int ti_scm_padconf_set(const char *padname, const char *muxmode, 
+    unsigned int state);
+int ti_scm_padconf_get(const char *padname, const char **muxmode,
+    unsigned int *state);
+int ti_scm_padconf_set_gpiomode(uint32_t gpio, unsigned int state);
+int ti_scm_padconf_get_gpiomode(uint32_t gpio, unsigned int *state);
+int ti_scm_padconf_set_gpioflags(uint32_t gpio, uint32_t flags);
+void ti_scm_padconf_get_gpioflags(uint32_t gpio, uint32_t *flags);
+int ti_scm_reg_read_4(uint32_t reg, uint32_t *val);
+int ti_scm_reg_write_4(uint32_t reg, uint32_t val);
+
+#endif /* _TI_SCM_H_ */


Property changes on: trunk/sys/arm/ti/ti_scm.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/ti_sdhci.c
===================================================================
--- trunk/sys/arm/ti/ti_sdhci.c	                        (rev 0)
+++ trunk/sys/arm/ti/ti_sdhci.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,726 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Ian Lepore <ian at freebsd.org>
+ * Copyright (c) 2011 Ben Gray <ben.r.gray at gmail.com>.
+ * 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: stable/10/sys/arm/ti/ti_sdhci.c 318198 2017-05-11 21:01:02Z marius $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/gpio.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+#include <sys/sysctl.h>
+#include <sys/taskqueue.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+#include <machine/intr.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <dev/mmc/bridge.h>
+#include <dev/mmc/mmcreg.h>
+#include <dev/mmc/mmcbrvar.h>
+
+#include <dev/sdhci/sdhci.h>
+#include "sdhci_if.h"
+
+#include <arm/ti/ti_cpuid.h>
+#include <arm/ti/ti_prcm.h>
+#include "gpio_if.h"
+
+struct ti_sdhci_softc {
+	device_t		dev;
+	device_t		gpio_dev;
+	struct resource *	mem_res;
+	struct resource *	irq_res;
+	void *			intr_cookie;
+	struct sdhci_slot	slot;
+	uint32_t		mmchs_device_id;
+	uint32_t		mmchs_reg_off;
+	uint32_t		sdhci_reg_off;
+	uint32_t		baseclk_hz;
+	uint32_t		wp_gpio_pin;
+	uint32_t		cmd_and_mode;
+	uint32_t		sdhci_clkdiv;
+	boolean_t		disable_highspeed;
+	boolean_t		force_card_present;
+};
+
+/*
+ * Table of supported FDT compat strings.
+ *
+ * Note that "ti,mmchs" is our own invention, and should be phased out in favor
+ * of the documented names.
+ *
+ * Note that vendor Beaglebone dtsi files use "ti,omap3-hsmmc" for the am335x.
+ */
+static struct ofw_compat_data compat_data[] = {
+	{"ti,omap3-hsmmc",	1},
+	{"ti,omap4-hsmmc",	1},
+	{"ti,mmchs",		1},
+	{NULL,		 	0},
+};
+
+/*
+ * The MMCHS hardware has a few control and status registers at the beginning of
+ * the device's memory map, followed by the standard sdhci register block.
+ * Different SoCs have the register blocks at different offsets from the
+ * beginning of the device.  Define some constants to map out the registers we
+ * access, and the various per-SoC offsets.  The SDHCI_REG_OFFSET is how far
+ * beyond the MMCHS block the SDHCI block is found; it's the same on all SoCs.
+ */
+#define	OMAP3_MMCHS_REG_OFFSET		0x000
+#define	OMAP4_MMCHS_REG_OFFSET		0x100
+#define	AM335X_MMCHS_REG_OFFSET		0x100
+#define	SDHCI_REG_OFFSET		0x100
+
+#define	MMCHS_SYSCONFIG			0x010
+#define	  MMCHS_SYSCONFIG_RESET		  (1 << 1)
+#define	MMCHS_SYSSTATUS			0x014
+#define	  MMCHS_SYSSTATUS_RESETDONE	  (1 << 0)
+#define	MMCHS_CON			0x02C
+#define	  MMCHS_CON_DW8			  (1 << 5)
+#define	  MMCHS_CON_DVAL_8_4MS		  (3 << 9)
+#define	  MMCHS_CON_OD			  (1 << 0)
+#define MMCHS_SYSCTL			0x12C
+#define   MMCHS_SYSCTL_CLKD_MASK	   0x3FF
+#define   MMCHS_SYSCTL_CLKD_SHIFT	   6
+#define	MMCHS_SD_CAPA			0x140
+#define	  MMCHS_SD_CAPA_VS18		  (1 << 26)
+#define	  MMCHS_SD_CAPA_VS30		  (1 << 25)
+#define	  MMCHS_SD_CAPA_VS33		  (1 << 24)
+
+static inline uint32_t
+ti_mmchs_read_4(struct ti_sdhci_softc *sc, bus_size_t off)
+{
+
+	return (bus_read_4(sc->mem_res, off + sc->mmchs_reg_off));
+}
+
+static inline void
+ti_mmchs_write_4(struct ti_sdhci_softc *sc, bus_size_t off, uint32_t val)
+{
+
+	bus_write_4(sc->mem_res, off + sc->mmchs_reg_off, val);
+}
+
+static inline uint32_t
+RD4(struct ti_sdhci_softc *sc, bus_size_t off)
+{
+
+	return (bus_read_4(sc->mem_res, off + sc->sdhci_reg_off));
+}
+
+static inline void
+WR4(struct ti_sdhci_softc *sc, bus_size_t off, uint32_t val)
+{
+
+	bus_write_4(sc->mem_res, off + sc->sdhci_reg_off, val);
+}
+
+static uint8_t
+ti_sdhci_read_1(device_t dev, struct sdhci_slot *slot, bus_size_t off)
+{
+	struct ti_sdhci_softc *sc = device_get_softc(dev);
+
+	return ((RD4(sc, off & ~3) >> (off & 3) * 8) & 0xff);
+}
+
+static uint16_t
+ti_sdhci_read_2(device_t dev, struct sdhci_slot *slot, bus_size_t off)
+{
+	struct ti_sdhci_softc *sc = device_get_softc(dev);
+	uint32_t clkdiv, val32;
+
+	/*
+	 * The MMCHS hardware has a non-standard interpretation of the sdclock
+	 * divisor bits.  It uses the same bit positions as SDHCI 3.0 (15..6)
+	 * but doesn't split them into low:high fields.  Instead they're a
+	 * single number in the range 0..1023 and the number is exactly the
+	 * clock divisor (with 0 and 1 both meaning divide by 1).  The SDHCI
+	 * driver code expects a v2.0 or v3.0 divisor.  The shifting and masking
+	 * here extracts the MMCHS representation from the hardware word, cleans
+	 * those bits out, applies the 2N adjustment, and plugs the result into
+	 * the bit positions for the 2.0 or 3.0 divisor in the returned register
+	 * value. The ti_sdhci_write_2() routine performs the opposite
+	 * transformation when the SDHCI driver writes to the register.
+	 */
+	if (off == SDHCI_CLOCK_CONTROL) {
+		val32 = RD4(sc, SDHCI_CLOCK_CONTROL);
+		clkdiv = ((val32 >> MMCHS_SYSCTL_CLKD_SHIFT) &
+		    MMCHS_SYSCTL_CLKD_MASK) / 2;
+		val32 &= ~(MMCHS_SYSCTL_CLKD_MASK << MMCHS_SYSCTL_CLKD_SHIFT);
+		val32 |= (clkdiv & SDHCI_DIVIDER_MASK) << SDHCI_DIVIDER_SHIFT;
+		if (slot->version >= SDHCI_SPEC_300)
+			val32 |= ((clkdiv >> SDHCI_DIVIDER_MASK_LEN) &
+			    SDHCI_DIVIDER_HI_MASK) << SDHCI_DIVIDER_HI_SHIFT;
+		return (val32 & 0xffff);
+	}
+
+	/*
+	 * Standard 32-bit handling of command and transfer mode.
+	 */
+	if (off == SDHCI_TRANSFER_MODE) {
+		return (sc->cmd_and_mode >> 16);
+	} else if (off == SDHCI_COMMAND_FLAGS) {
+		return (sc->cmd_and_mode & 0x0000ffff);
+	}
+
+	return ((RD4(sc, off & ~3) >> (off & 3) * 8) & 0xffff);
+}
+
+static uint32_t
+ti_sdhci_read_4(device_t dev, struct sdhci_slot *slot, bus_size_t off)
+{
+	struct ti_sdhci_softc *sc = device_get_softc(dev);
+	uint32_t val32;
+
+	val32 = RD4(sc, off);
+
+	/*
+	 * If we need to disallow highspeed mode due to the OMAP4 erratum, strip
+	 * that flag from the returned capabilities.
+	 */
+	if (off == SDHCI_CAPABILITIES && sc->disable_highspeed)
+		val32 &= ~SDHCI_CAN_DO_HISPD;
+
+	/*
+	 * Force the card-present state if necessary.
+	 */
+	if (off == SDHCI_PRESENT_STATE && sc->force_card_present)
+		val32 |= SDHCI_CARD_PRESENT;
+
+	return (val32);
+}
+
+static void
+ti_sdhci_read_multi_4(device_t dev, struct sdhci_slot *slot, bus_size_t off,
+    uint32_t *data, bus_size_t count)
+{
+	struct ti_sdhci_softc *sc = device_get_softc(dev);
+
+	bus_read_multi_4(sc->mem_res, off + sc->sdhci_reg_off, data, count);
+}
+
+static void
+ti_sdhci_write_1(device_t dev, struct sdhci_slot *slot, bus_size_t off, 
+    uint8_t val)
+{
+	struct ti_sdhci_softc *sc = device_get_softc(dev);
+	uint32_t val32;
+
+	val32 = RD4(sc, off & ~3);
+	val32 &= ~(0xff << (off & 3) * 8);
+	val32 |= (val << (off & 3) * 8);
+
+	WR4(sc, off & ~3, val32);
+}
+
+static void
+ti_sdhci_write_2(device_t dev, struct sdhci_slot *slot, bus_size_t off, 
+    uint16_t val)
+{
+	struct ti_sdhci_softc *sc = device_get_softc(dev);
+	uint32_t clkdiv, val32;
+
+	/*
+	 * Translate between the hardware and SDHCI 2.0 or 3.0 representations
+	 * of the clock divisor.  See the comments in ti_sdhci_read_2() for
+	 * details.
+	 */
+	if (off == SDHCI_CLOCK_CONTROL) {
+		clkdiv = (val >> SDHCI_DIVIDER_SHIFT) & SDHCI_DIVIDER_MASK;
+		if (slot->version >= SDHCI_SPEC_300)
+			clkdiv |= ((val >> SDHCI_DIVIDER_HI_SHIFT) &
+			    SDHCI_DIVIDER_HI_MASK) << SDHCI_DIVIDER_MASK_LEN;
+		clkdiv *= 2;
+		if (clkdiv > MMCHS_SYSCTL_CLKD_MASK)
+			clkdiv = MMCHS_SYSCTL_CLKD_MASK;
+		val32 = RD4(sc, SDHCI_CLOCK_CONTROL);
+		val32 &= 0xffff0000;
+		val32 |= val & ~(MMCHS_SYSCTL_CLKD_MASK <<
+		    MMCHS_SYSCTL_CLKD_SHIFT);
+		val32 |= clkdiv << MMCHS_SYSCTL_CLKD_SHIFT;
+		WR4(sc, SDHCI_CLOCK_CONTROL, val32);
+		return;
+	}
+
+	/*
+	 * Standard 32-bit handling of command and transfer mode.
+	 */
+	if (off == SDHCI_TRANSFER_MODE) {
+		sc->cmd_and_mode = (sc->cmd_and_mode & 0xffff0000) |
+		    ((uint32_t)val & 0x0000ffff);
+		return;
+	} else if (off == SDHCI_COMMAND_FLAGS) {
+		sc->cmd_and_mode = (sc->cmd_and_mode & 0x0000ffff) |
+		    ((uint32_t)val << 16);
+		WR4(sc, SDHCI_TRANSFER_MODE, sc->cmd_and_mode);
+		return;
+	}
+
+	val32 = RD4(sc, off & ~3);
+	val32 &= ~(0xffff << (off & 3) * 8);
+	val32 |= ((val & 0xffff) << (off & 3) * 8);
+	WR4(sc, off & ~3, val32);	
+}
+
+static void
+ti_sdhci_write_4(device_t dev, struct sdhci_slot *slot, bus_size_t off, 
+    uint32_t val)
+{
+	struct ti_sdhci_softc *sc = device_get_softc(dev);
+
+	WR4(sc, off, val);
+}
+
+static void
+ti_sdhci_write_multi_4(device_t dev, struct sdhci_slot *slot, bus_size_t off,
+    uint32_t *data, bus_size_t count)
+{
+	struct ti_sdhci_softc *sc = device_get_softc(dev);
+
+	bus_write_multi_4(sc->mem_res, off + sc->sdhci_reg_off, data, count);
+}
+
+static void
+ti_sdhci_intr(void *arg)
+{
+	struct ti_sdhci_softc *sc = arg;
+
+	sdhci_generic_intr(&sc->slot);
+}
+
+static int
+ti_sdhci_update_ios(device_t brdev, device_t reqdev)
+{
+	struct ti_sdhci_softc *sc = device_get_softc(brdev);
+	struct sdhci_slot *slot;
+	struct mmc_ios *ios;
+	uint32_t val32, newval32;
+
+	slot = device_get_ivars(reqdev);
+	ios = &slot->host.ios;
+
+	/*
+	 * There is an 8-bit-bus bit in the MMCHS control register which, when
+	 * set, overrides the 1 vs 4 bit setting in the standard SDHCI
+	 * registers.  Set that bit first according to whether an 8-bit bus is
+	 * requested, then let the standard driver handle everything else.
+	 */
+	val32 = ti_mmchs_read_4(sc, MMCHS_CON);
+	newval32  = val32;
+
+	if (ios->bus_width == bus_width_8)
+		newval32 |= MMCHS_CON_DW8;
+	else
+		newval32 &= ~MMCHS_CON_DW8;
+
+	if (ios->bus_mode == opendrain)
+		newval32 |= MMCHS_CON_OD;
+	else /* if (ios->bus_mode == pushpull) */
+		newval32 &= ~MMCHS_CON_OD;
+
+	if (newval32 != val32)
+		ti_mmchs_write_4(sc, MMCHS_CON, newval32);
+
+	return (sdhci_generic_update_ios(brdev, reqdev));
+}
+
+static int
+ti_sdhci_get_ro(device_t brdev, device_t reqdev)
+{
+	struct ti_sdhci_softc *sc = device_get_softc(brdev);
+	unsigned int readonly = 0;
+
+	/* If a gpio pin is configured, read it. */
+	if (sc->gpio_dev != NULL) {
+		GPIO_PIN_GET(sc->gpio_dev, sc->wp_gpio_pin, &readonly);
+	}
+
+	return (readonly);
+}
+
+static int
+ti_sdhci_detach(device_t dev)
+{
+
+	return (EBUSY);
+}
+
+static void
+ti_sdhci_hw_init(device_t dev)
+{
+	struct ti_sdhci_softc *sc = device_get_softc(dev);
+	clk_ident_t clk;
+	uint32_t regval;
+	unsigned long timeout;
+
+	/* Enable the controller and interface/functional clocks */
+	clk = MMC0_CLK + sc->mmchs_device_id;
+	if (ti_prcm_clk_enable(clk) != 0) {
+		device_printf(dev, "Error: failed to enable MMC clock\n");
+		return;
+	}
+
+	/* Get the frequency of the source clock */
+	if (ti_prcm_clk_get_source_freq(clk, &sc->baseclk_hz) != 0) {
+		device_printf(dev, "Error: failed to get source clock freq\n");
+		return;
+	}
+
+	/* Issue a softreset to the controller */
+	ti_mmchs_write_4(sc, MMCHS_SYSCONFIG, MMCHS_SYSCONFIG_RESET);
+	timeout = 1000;
+	while (!(ti_mmchs_read_4(sc, MMCHS_SYSSTATUS) &
+	    MMCHS_SYSSTATUS_RESETDONE)) {
+		if (--timeout == 0) {
+			device_printf(dev,
+			    "Error: Controller reset operation timed out\n");
+			break;
+		}
+		DELAY(100);
+	}
+
+	/*
+	 * Reset the command and data state machines and also other aspects of
+	 * the controller such as bus clock and power.
+	 *
+	 * If we read the software reset register too fast after writing it we
+	 * can get back a zero that means the reset hasn't started yet rather
+	 * than that the reset is complete. Per TI recommendations, work around
+	 * it by reading until we see the reset bit asserted, then read until
+	 * it's clear. We also set the SDHCI_QUIRK_WAITFOR_RESET_ASSERTED quirk
+	 * so that the main sdhci driver uses this same logic in its resets.
+	 */
+	ti_sdhci_write_1(dev, NULL, SDHCI_SOFTWARE_RESET, SDHCI_RESET_ALL);
+	timeout = 10000;
+	while ((ti_sdhci_read_1(dev, NULL, SDHCI_SOFTWARE_RESET) &
+	    SDHCI_RESET_ALL) != SDHCI_RESET_ALL) {
+		if (--timeout == 0) {
+			break;
+		}
+		DELAY(1);
+	}
+	timeout = 10000;
+	while ((ti_sdhci_read_1(dev, NULL, SDHCI_SOFTWARE_RESET) &
+	    SDHCI_RESET_ALL)) {
+		if (--timeout == 0) {
+			device_printf(dev,
+			    "Error: Software reset operation timed out\n");
+			break;
+		}
+		DELAY(100);
+	}
+
+	/*
+	 * The attach() routine has examined fdt data and set flags in
+	 * slot.host.caps to reflect what voltages we can handle.  Set those
+	 * values in the CAPA register.  The manual says that these values can
+	 * only be set once, "before initialization" whatever that means, and
+	 * that they survive a reset.  So maybe doing this will be a no-op if
+	 * u-boot has already initialized the hardware.
+	 */
+	regval = ti_mmchs_read_4(sc, MMCHS_SD_CAPA);
+	if (sc->slot.host.caps & MMC_OCR_LOW_VOLTAGE)
+		regval |= MMCHS_SD_CAPA_VS18;
+	if (sc->slot.host.caps & (MMC_OCR_290_300 | MMC_OCR_300_310))
+		regval |= MMCHS_SD_CAPA_VS30;
+	ti_mmchs_write_4(sc, MMCHS_SD_CAPA, regval);
+
+	/* Set initial host configuration (1-bit, std speed, pwr off). */
+	ti_sdhci_write_1(dev, NULL, SDHCI_HOST_CONTROL, 0);
+	ti_sdhci_write_1(dev, NULL, SDHCI_POWER_CONTROL, 0);
+
+	/* Set the initial controller configuration. */
+	ti_mmchs_write_4(sc, MMCHS_CON, MMCHS_CON_DVAL_8_4MS);
+}
+
+static int
+ti_sdhci_attach(device_t dev)
+{
+	struct ti_sdhci_softc *sc = device_get_softc(dev);
+	int rid, err;
+	pcell_t prop;
+	phandle_t node;
+
+	sc->dev = dev;
+
+	/*
+	 * Get the MMCHS device id from FDT.  If it's not there use the newbus
+	 * unit number (which will work as long as the devices are in order and
+	 * none are skipped in the fdt).  Note that this is a property we made
+	 * up and added in freebsd, it doesn't exist in the published bindings.
+	 */
+	node = ofw_bus_get_node(dev);
+	if ((OF_getprop(node, "mmchs-device-id", &prop, sizeof(prop))) <= 0) {
+		sc->mmchs_device_id = device_get_unit(dev);
+		device_printf(dev, "missing mmchs-device-id attribute in FDT, "
+		    "using unit number (%d)", sc->mmchs_device_id);
+	} else
+		sc->mmchs_device_id = fdt32_to_cpu(prop);
+
+	/*
+	 * The hardware can inherently do dual-voltage (1p8v, 3p0v) on the first
+	 * device, and only 1p8v on other devices unless an external transceiver
+	 * is used.  The only way we could know about a transceiver is fdt data.
+	 * Note that we have to do this before calling ti_sdhci_hw_init() so
+	 * that it can set the right values in the CAPA register, which can only
+	 * be done once and never reset.
+	 */
+	sc->slot.host.caps |= MMC_OCR_LOW_VOLTAGE;
+	if (sc->mmchs_device_id == 0 || OF_hasprop(node, "ti,dual-volt")) {
+		sc->slot.host.caps |= MMC_OCR_290_300 | MMC_OCR_300_310;
+	}
+
+	/*
+	 * See if we've got a GPIO-based write detect pin.  This is not the
+	 * standard documented property for this, we added it in freebsd.
+	 */
+	if ((OF_getprop(node, "mmchs-wp-gpio-pin", &prop, sizeof(prop))) <= 0)
+		sc->wp_gpio_pin = 0xffffffff;
+	else
+		sc->wp_gpio_pin = fdt32_to_cpu(prop);
+
+	if (sc->wp_gpio_pin != 0xffffffff) {
+		sc->gpio_dev = devclass_get_device(devclass_find("gpio"), 0);
+		if (sc->gpio_dev == NULL) 
+			device_printf(dev, "Error: No GPIO device, "
+			    "Write Protect pin will not function\n");
+		else
+			GPIO_PIN_SETFLAGS(sc->gpio_dev, sc->wp_gpio_pin,
+			                  GPIO_PIN_INPUT);
+	}
+
+	/*
+	 * Set the offset from the device's memory start to the MMCHS registers.
+	 * Also for OMAP4 disable high speed mode due to erratum ID i626.
+	 */
+	if (ti_chip() == CHIP_OMAP_3)
+		sc->mmchs_reg_off = OMAP3_MMCHS_REG_OFFSET;
+	else if (ti_chip() == CHIP_OMAP_4) {
+		sc->mmchs_reg_off = OMAP4_MMCHS_REG_OFFSET;
+		sc->disable_highspeed = true;
+        } else if (ti_chip() == CHIP_AM335X)
+		sc->mmchs_reg_off = AM335X_MMCHS_REG_OFFSET;
+	else
+		panic("Unknown OMAP device\n");
+
+	/*
+	 * The standard SDHCI registers are at a fixed offset (the same on all
+	 * SoCs) beyond the MMCHS registers.
+	 */
+	sc->sdhci_reg_off = sc->mmchs_reg_off + SDHCI_REG_OFFSET;
+
+	/* Resource setup. */
+	rid = 0;
+	sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	    RF_ACTIVE);
+	if (!sc->mem_res) {
+		device_printf(dev, "cannot allocate memory window\n");
+		err = ENXIO;
+		goto fail;
+	}
+
+	rid = 0;
+	sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+	    RF_ACTIVE);
+	if (!sc->irq_res) {
+		device_printf(dev, "cannot allocate interrupt\n");
+		err = ENXIO;
+		goto fail;
+	}
+
+	if (bus_setup_intr(dev, sc->irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
+	    NULL, ti_sdhci_intr, sc, &sc->intr_cookie)) {
+		device_printf(dev, "cannot setup interrupt handler\n");
+		err = ENXIO;
+		goto fail;
+	}
+
+	/* Initialise the MMCHS hardware. */
+	ti_sdhci_hw_init(dev);
+
+	/*
+	 * The capabilities register can only express base clock frequencies in
+	 * the range of 0-63MHz for a v2.0 controller.  Since our clock runs
+	 * faster than that, the hardware sets the frequency to zero in the
+	 * register.  When the register contains zero, the sdhci driver expects
+	 * slot.max_clk to already have the right value in it.
+	 */
+	sc->slot.max_clk = sc->baseclk_hz;
+
+	/*
+	 * The MMCHS timeout counter is based on the output sdclock.  Tell the
+	 * sdhci driver to recalculate the timeout clock whenever the output
+	 * sdclock frequency changes.
+	 */
+	sc->slot.quirks |= SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK;
+
+	/*
+	 * The MMCHS hardware shifts the 136-bit response data (in violation of
+	 * the spec), so tell the sdhci driver not to do the same in software.
+	 */
+	sc->slot.quirks |= SDHCI_QUIRK_DONT_SHIFT_RESPONSE;
+
+	/*
+	 * Reset bits are broken, have to wait to see the bits asserted
+	 * before waiting to see them de-asserted.
+	 */
+	sc->slot.quirks |= SDHCI_QUIRK_WAITFOR_RESET_ASSERTED;
+	
+	/*
+	 * The controller waits for busy responses.
+	 */
+	sc->slot.quirks |= SDHCI_QUIRK_WAIT_WHILE_BUSY;
+
+	/*
+	 * DMA is not really broken, I just haven't implemented it yet.
+	 */
+	sc->slot.quirks |= SDHCI_QUIRK_BROKEN_DMA;
+
+	/*
+	 *  Set up the hardware and go.  Note that this sets many of the
+	 *  slot.host.* fields, so we have to do this before overriding any of
+	 *  those values based on fdt data, below.
+	 */
+	sdhci_init_slot(dev, &sc->slot, 0);
+
+	/*
+	 * The SDHCI controller doesn't realize it, but we can support 8-bit
+	 * even though we're not a v3.0 controller.  If there's an fdt bus-width
+	 * property, honor it.
+	 */
+	if (OF_getencprop(node, "bus-width", &prop, sizeof(prop)) > 0) {
+		sc->slot.host.caps &= ~(MMC_CAP_4_BIT_DATA | 
+		    MMC_CAP_8_BIT_DATA);
+		switch (prop) {
+		case 8:
+			sc->slot.host.caps |= MMC_CAP_8_BIT_DATA;
+			/* FALLTHROUGH */
+		case 4:
+			sc->slot.host.caps |= MMC_CAP_4_BIT_DATA;
+			break;
+		case 1:
+			break;
+		default:
+			device_printf(dev, "Bad bus-width value %u\n", prop);
+			break;
+		}
+	}
+
+	/*
+	 * If the slot is flagged with the non-removable property, set our flag
+	 * to always force the SDHCI_CARD_PRESENT bit on.
+	 */
+	node = ofw_bus_get_node(dev);
+	if (OF_hasprop(node, "non-removable"))
+		sc->force_card_present = true;
+
+	bus_generic_probe(dev);
+	bus_generic_attach(dev);
+
+	sdhci_start_slot(&sc->slot);
+
+	return (0);
+
+fail:
+	if (sc->intr_cookie)
+		bus_teardown_intr(dev, sc->irq_res, sc->intr_cookie);
+	if (sc->irq_res)
+		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq_res);
+	if (sc->mem_res)
+		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->mem_res);
+
+	return (err);
+}
+
+static int
+ti_sdhci_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (ofw_bus_search_compatible(dev, compat_data)->ocd_data != 0) {
+		device_set_desc(dev, "TI MMCHS (SDHCI 2.0)");
+		return (BUS_PROBE_DEFAULT);
+	}
+
+	return (ENXIO);
+}
+
+static device_method_t ti_sdhci_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		ti_sdhci_probe),
+	DEVMETHOD(device_attach,	ti_sdhci_attach),
+	DEVMETHOD(device_detach,	ti_sdhci_detach),
+
+	/* Bus interface */
+	DEVMETHOD(bus_read_ivar,	sdhci_generic_read_ivar),
+	DEVMETHOD(bus_write_ivar,	sdhci_generic_write_ivar),
+
+	/* MMC bridge interface */
+	DEVMETHOD(mmcbr_update_ios,	ti_sdhci_update_ios),
+	DEVMETHOD(mmcbr_request,	sdhci_generic_request),
+	DEVMETHOD(mmcbr_get_ro,		ti_sdhci_get_ro),
+	DEVMETHOD(mmcbr_acquire_host,	sdhci_generic_acquire_host),
+	DEVMETHOD(mmcbr_release_host,	sdhci_generic_release_host),
+
+	/* SDHCI registers accessors */
+	DEVMETHOD(sdhci_read_1,		ti_sdhci_read_1),
+	DEVMETHOD(sdhci_read_2,		ti_sdhci_read_2),
+	DEVMETHOD(sdhci_read_4,		ti_sdhci_read_4),
+	DEVMETHOD(sdhci_read_multi_4,	ti_sdhci_read_multi_4),
+	DEVMETHOD(sdhci_write_1,	ti_sdhci_write_1),
+	DEVMETHOD(sdhci_write_2,	ti_sdhci_write_2),
+	DEVMETHOD(sdhci_write_4,	ti_sdhci_write_4),
+	DEVMETHOD(sdhci_write_multi_4,	ti_sdhci_write_multi_4),
+
+	DEVMETHOD_END
+};
+
+static devclass_t ti_sdhci_devclass;
+
+static driver_t ti_sdhci_driver = {
+	"sdhci_ti",
+	ti_sdhci_methods,
+	sizeof(struct ti_sdhci_softc),
+};
+
+DRIVER_MODULE(sdhci_ti, simplebus, ti_sdhci_driver, ti_sdhci_devclass, NULL,
+    NULL);
+MODULE_DEPEND(sdhci_ti, sdhci, 1, 1, 1);
+MMC_DECLARE_BRIDGE(sdhci_ti);


Property changes on: trunk/sys/arm/ti/ti_sdhci.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/ti_sdma.c
===================================================================
--- trunk/sys/arm/ti/ti_sdma.c	                        (rev 0)
+++ trunk/sys/arm/ti/ti_sdma.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,1251 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2011
+ *	Ben Gray <ben.r.gray at gmail.com>.
+ * 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 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 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: stable/10/sys/arm/ti/ti_sdma.c 266152 2014-05-15 16:11:06Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/interrupt.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/mutex.h>
+#include <sys/rman.h>
+#include <sys/queue.h>
+#include <sys/taskqueue.h>
+#include <sys/timetc.h>
+#include <machine/bus.h>
+#include <machine/intr.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <arm/ti/ti_cpuid.h>
+#include <arm/ti/ti_prcm.h>
+#include <arm/ti/ti_sdma.h>
+#include <arm/ti/ti_sdmareg.h>
+
+/**
+ *	Kernel functions for using the DMA controller
+ *
+ *
+ *	DMA TRANSFERS:
+ *	A DMA transfer block consists of a number of frames (FN). Each frame
+ *	consists of a number of elements, and each element can have a size of 8, 16,
+ *	or 32 bits.
+ *
+ *	OMAP44xx and newer chips support linked list (aka scatter gather) transfers,
+ *	where a linked list of source/destination pairs can be placed in memory
+ *	for the H/W to process.  Earlier chips only allowed you to chain multiple
+ *	channels together.  However currently this linked list feature is not
+ *	supported by the driver.
+ *
+ */
+
+/**
+ *	Data structure per DMA channel.
+ *
+ *
+ */
+struct ti_sdma_channel {
+
+	/* 
+	 * The configuration registers for the given channel, these are modified
+	 * by the set functions and only written to the actual registers when a
+	 * transaction is started.
+	 */
+	uint32_t		reg_csdp;
+	uint32_t		reg_ccr;
+	uint32_t		reg_cicr;
+
+	/* Set when one of the configuration registers above change */
+	uint32_t		need_reg_write;
+
+	/* Callback function used when an interrupt is tripped on the given channel */
+	void (*callback)(unsigned int ch, uint32_t ch_status, void *data);
+
+	/* Callback data passed in the callback ... duh */
+	void*			callback_data;
+
+};
+
+/**
+ *	DMA driver context, allocated and stored globally, this driver is not
+ *	intetned to ever be unloaded (see ti_sdma_sc).
+ *
+ */
+struct ti_sdma_softc {
+	device_t		sc_dev;
+	struct resource*	sc_irq_res;
+	struct resource*	sc_mem_res;
+
+	/* 
+	 * I guess in theory we should have a mutex per DMA channel for register
+	 * modifications. But since we know we are never going to be run on a SMP
+	 * system, we can use just the single lock for all channels.
+	 */
+	struct mtx		sc_mtx;
+
+	/* Stores the H/W revision read from the registers */
+	uint32_t		sc_hw_rev;
+
+	/* 
+	 * Bits in the sc_active_channels data field indicate if the channel has
+	 * been activated.
+	 */
+	uint32_t		sc_active_channels;
+
+	struct ti_sdma_channel sc_channel[NUM_DMA_CHANNELS];
+
+};
+
+static struct ti_sdma_softc *ti_sdma_sc = NULL;
+
+/**
+ *	Macros for driver mutex locking
+ */
+#define TI_SDMA_LOCK(_sc)             mtx_lock_spin(&(_sc)->sc_mtx)
+#define TI_SDMA_UNLOCK(_sc)           mtx_unlock_spin(&(_sc)->sc_mtx)
+#define TI_SDMA_LOCK_INIT(_sc) \
+	mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->sc_dev), \
+	         "ti_sdma", MTX_SPIN)
+#define TI_SDMA_LOCK_DESTROY(_sc)     mtx_destroy(&_sc->sc_mtx);
+#define TI_SDMA_ASSERT_LOCKED(_sc)    mtx_assert(&_sc->sc_mtx, MA_OWNED);
+#define TI_SDMA_ASSERT_UNLOCKED(_sc)  mtx_assert(&_sc->sc_mtx, MA_NOTOWNED);
+
+/**
+ *	Function prototypes
+ *
+ */
+static void ti_sdma_intr(void *);
+
+/**
+ *	ti_sdma_read_4 - reads a 32-bit value from one of the DMA registers
+ *	@sc: DMA device context
+ *	@off: The offset of a register from the DMA register address range
+ *
+ *
+ *	RETURNS:
+ *	32-bit value read from the register.
+ */
+static inline uint32_t
+ti_sdma_read_4(struct ti_sdma_softc *sc, bus_size_t off)
+{
+	return bus_read_4(sc->sc_mem_res, off);
+}
+
+/**
+ *	ti_sdma_write_4 - writes a 32-bit value to one of the DMA registers
+ *	@sc: DMA device context
+ *	@off: The offset of a register from the DMA register address range
+ *
+ *
+ *	RETURNS:
+ *	32-bit value read from the register.
+ */
+static inline void
+ti_sdma_write_4(struct ti_sdma_softc *sc, bus_size_t off, uint32_t val)
+{
+	bus_write_4(sc->sc_mem_res, off, val);
+}
+
+/**
+ *	ti_sdma_is_omap3_rev - returns true if H/W is from OMAP3 series
+ *	@sc: DMA device context
+ *
+ */
+static inline int
+ti_sdma_is_omap3_rev(struct ti_sdma_softc *sc)
+{
+	return (sc->sc_hw_rev == DMA4_OMAP3_REV);
+}
+
+/**
+ *	ti_sdma_is_omap4_rev - returns true if H/W is from OMAP4 series
+ *	@sc: DMA device context
+ *
+ */
+static inline int
+ti_sdma_is_omap4_rev(struct ti_sdma_softc *sc)
+{
+	return (sc->sc_hw_rev == DMA4_OMAP4_REV);
+}
+
+/**
+ *	ti_sdma_intr - interrupt handler for all 4 DMA IRQs
+ *	@arg: ignored
+ *
+ *	Called when any of the four DMA IRQs are triggered.
+ *
+ *	LOCKING:
+ *	DMA registers protected by internal mutex
+ *
+ *	RETURNS:
+ *	nothing
+ */
+static void
+ti_sdma_intr(void *arg)
+{
+	struct ti_sdma_softc *sc = ti_sdma_sc;
+	uint32_t intr;
+	uint32_t csr;
+	unsigned int ch, j;
+	struct ti_sdma_channel* channel;
+
+	TI_SDMA_LOCK(sc);
+
+	for (j = 0; j < NUM_DMA_IRQS; j++) {
+
+		/* Get the flag interrupts (enabled) */
+		intr = ti_sdma_read_4(sc, DMA4_IRQSTATUS_L(j));
+		intr &= ti_sdma_read_4(sc, DMA4_IRQENABLE_L(j));
+		if (intr == 0x00000000)
+			continue;
+
+		/* Loop through checking the status bits */
+		for (ch = 0; ch < NUM_DMA_CHANNELS; ch++) {
+			if (intr & (1 << ch)) {
+				channel = &sc->sc_channel[ch];
+
+				/* Read the CSR regsiter and verify we don't have a spurious IRQ */
+				csr = ti_sdma_read_4(sc, DMA4_CSR(ch));
+				if (csr == 0) {
+					device_printf(sc->sc_dev, "Spurious DMA IRQ for channel "
+					              "%d\n", ch);
+					continue;
+				}
+
+				/* Sanity check this channel is active */
+				if ((sc->sc_active_channels & (1 << ch)) == 0) {
+					device_printf(sc->sc_dev, "IRQ %d for a non-activated "
+					              "channel %d\n", j, ch);
+					continue;
+				}
+
+				/* Check the status error codes */
+				if (csr & DMA4_CSR_DROP)
+					device_printf(sc->sc_dev, "Synchronization event drop "
+					              "occurred during the transfer on channel %u\n",
+								  ch);
+				if (csr & DMA4_CSR_SECURE_ERR)
+					device_printf(sc->sc_dev, "Secure transaction error event "
+					              "on channel %u\n", ch);
+				if (csr & DMA4_CSR_MISALIGNED_ADRS_ERR)
+					device_printf(sc->sc_dev, "Misaligned address error event "
+					              "on channel %u\n", ch);
+				if (csr & DMA4_CSR_TRANS_ERR) {
+					device_printf(sc->sc_dev, "Transaction error event on "
+					              "channel %u\n", ch);
+					/* 
+					 * Apparently according to linux code, there is an errata
+					 * that says the channel is not disabled upon this error.
+					 * They explicitly disable the channel here .. since I
+					 * haven't seen the errata, I'm going to ignore for now.
+					 */
+				}
+
+				/* Clear the status flags for the IRQ */
+				ti_sdma_write_4(sc, DMA4_CSR(ch), DMA4_CSR_CLEAR_MASK);
+				ti_sdma_write_4(sc, DMA4_IRQSTATUS_L(j), (1 << ch));
+
+				/* Call the callback for the given channel */
+				if (channel->callback)
+					channel->callback(ch, csr, channel->callback_data);
+			}
+		}
+	}
+
+	TI_SDMA_UNLOCK(sc);
+
+	return;
+}
+
+/**
+ *	ti_sdma_activate_channel - activates a DMA channel
+ *	@ch: upon return contains the channel allocated
+ *	@callback: a callback function to associate with the channel
+ *	@data: optional data supplied when the callback is called
+ *
+ *	Simply activates a channel be enabling and writing default values to the
+ *	channel's register set.  It doesn't start a transaction, just populates the
+ *	internal data structures and sets defaults.
+ *
+ *	Note this function doesn't enable interrupts, for that you need to call
+ *	ti_sdma_enable_channel_irq(). If not using IRQ to detect the end of the
+ *	transfer, you can use ti_sdma_status_poll() to detect a change in the
+ *	status.
+ *
+ *	A channel must be activated before any of the other DMA functions can be
+ *	called on it.
+ *
+ *	LOCKING:
+ *	DMA registers protected by internal mutex
+ *
+ *	RETURNS:
+ *	0 on success, otherwise an error code
+ */
+int
+ti_sdma_activate_channel(unsigned int *ch,
+                          void (*callback)(unsigned int ch, uint32_t status, void *data),
+                          void *data)
+{
+	struct ti_sdma_softc *sc = ti_sdma_sc;
+	struct ti_sdma_channel *channel = NULL;
+	uint32_t addr;
+	unsigned int i;
+
+	/* Sanity check */
+	if (sc == NULL)
+		return (ENOMEM);
+
+	if (ch == NULL)
+		return (EINVAL);
+
+	TI_SDMA_LOCK(sc);
+
+	/* Check to see if all channels are in use */
+	if (sc->sc_active_channels == 0xffffffff) {
+		TI_SDMA_UNLOCK(sc);
+		return (ENOMEM);
+	}
+
+	/* Find the first non-active channel */
+	for (i = 0; i < NUM_DMA_CHANNELS; i++) {
+		if (!(sc->sc_active_channels & (0x1 << i))) {
+			sc->sc_active_channels |= (0x1 << i);
+			*ch = i;
+			break;
+		}
+	}
+
+	/* Get the channel struct and populate the fields */
+	channel = &sc->sc_channel[*ch];
+
+	channel->callback = callback;
+	channel->callback_data = data;
+
+	channel->need_reg_write = 1;
+
+	/* Set the default configuration for the DMA channel */
+	channel->reg_csdp = DMA4_CSDP_DATA_TYPE(0x2)
+		| DMA4_CSDP_SRC_BURST_MODE(0)
+		| DMA4_CSDP_DST_BURST_MODE(0)
+		| DMA4_CSDP_SRC_ENDIANISM(0)
+		| DMA4_CSDP_DST_ENDIANISM(0)
+		| DMA4_CSDP_WRITE_MODE(0)
+		| DMA4_CSDP_SRC_PACKED(0)
+		| DMA4_CSDP_DST_PACKED(0);
+
+	channel->reg_ccr = DMA4_CCR_DST_ADDRESS_MODE(1)
+		| DMA4_CCR_SRC_ADDRESS_MODE(1)
+		| DMA4_CCR_READ_PRIORITY(0)
+		| DMA4_CCR_WRITE_PRIORITY(0)
+		| DMA4_CCR_SYNC_TRIGGER(0)
+		| DMA4_CCR_FRAME_SYNC(0)
+		| DMA4_CCR_BLOCK_SYNC(0);
+
+	channel->reg_cicr = DMA4_CICR_TRANS_ERR_IE
+		| DMA4_CICR_SECURE_ERR_IE
+		| DMA4_CICR_SUPERVISOR_ERR_IE
+		| DMA4_CICR_MISALIGNED_ADRS_ERR_IE;
+
+	/* Clear all the channel registers, this should abort any transaction */
+	for (addr = DMA4_CCR(*ch); addr <= DMA4_COLOR(*ch); addr += 4)
+		ti_sdma_write_4(sc, addr, 0x00000000);
+
+	TI_SDMA_UNLOCK(sc);
+
+	return 0;
+}
+
+/**
+ *	ti_sdma_deactivate_channel - deactivates a channel
+ *	@ch: the channel to deactivate
+ *
+ *
+ *
+ *	LOCKING:
+ *	DMA registers protected by internal mutex
+ *
+ *	RETURNS:
+ *	EH_HANDLED or EH_NOT_HANDLED
+ */
+int
+ti_sdma_deactivate_channel(unsigned int ch)
+{
+	struct ti_sdma_softc *sc = ti_sdma_sc;
+	unsigned int j;
+	unsigned int addr;
+
+	/* Sanity check */
+	if (sc == NULL)
+		return (ENOMEM);
+
+	TI_SDMA_LOCK(sc);
+
+	/* First check if the channel is currently active */
+	if ((sc->sc_active_channels & (1 << ch)) == 0) {
+		TI_SDMA_UNLOCK(sc);
+		return (EBUSY);
+	}
+
+	/* Mark the channel as inactive */
+	sc->sc_active_channels &= ~(1 << ch);
+
+	/* Disable all DMA interrupts for the channel. */
+	ti_sdma_write_4(sc, DMA4_CICR(ch), 0);
+
+	/* Make sure the DMA transfer is stopped. */
+	ti_sdma_write_4(sc, DMA4_CCR(ch), 0);
+
+	/* Clear the CSR register and IRQ status register */
+	ti_sdma_write_4(sc, DMA4_CSR(ch), DMA4_CSR_CLEAR_MASK);
+	for (j = 0; j < NUM_DMA_IRQS; j++) {
+		ti_sdma_write_4(sc, DMA4_IRQSTATUS_L(j), (1 << ch));
+	}
+
+	/* Clear all the channel registers, this should abort any transaction */
+	for (addr = DMA4_CCR(ch); addr <= DMA4_COLOR(ch); addr += 4)
+		ti_sdma_write_4(sc, addr, 0x00000000);
+
+	TI_SDMA_UNLOCK(sc);
+
+	return 0;
+}
+
+/**
+ *	ti_sdma_disable_channel_irq - disables IRQ's on the given channel
+ *	@ch: the channel to disable IRQ's on
+ *
+ *	Disable interupt generation for the given channel.
+ *
+ *	LOCKING:
+ *	DMA registers protected by internal mutex
+ *
+ *	RETURNS:
+ *	EH_HANDLED or EH_NOT_HANDLED
+ */
+int
+ti_sdma_disable_channel_irq(unsigned int ch)
+{
+	struct ti_sdma_softc *sc = ti_sdma_sc;
+	uint32_t irq_enable;
+	unsigned int j;
+
+	/* Sanity check */
+	if (sc == NULL)
+		return (ENOMEM);
+
+	TI_SDMA_LOCK(sc);
+
+	if ((sc->sc_active_channels & (1 << ch)) == 0) {
+		TI_SDMA_UNLOCK(sc);
+		return (EINVAL);
+	}
+
+	/* Disable all the individual error conditions */
+	sc->sc_channel[ch].reg_cicr = 0x0000;
+	ti_sdma_write_4(sc, DMA4_CICR(ch), 0x0000);
+
+	/* Disable the channel interrupt enable */
+	for (j = 0; j < NUM_DMA_IRQS; j++) {
+		irq_enable = ti_sdma_read_4(sc, DMA4_IRQENABLE_L(j));
+		irq_enable &= ~(1 << ch);
+
+		ti_sdma_write_4(sc, DMA4_IRQENABLE_L(j), irq_enable);
+	}
+
+	/* Indicate the registers need to be rewritten on the next transaction */
+	sc->sc_channel[ch].need_reg_write = 1;
+
+	TI_SDMA_UNLOCK(sc);
+
+	return (0);
+}
+
+/**
+ *	ti_sdma_disable_channel_irq - enables IRQ's on the given channel
+ *	@ch: the channel to enable IRQ's on
+ *	@flags: bitmask of interrupt types to enable
+ *
+ *	Flags can be a bitmask of the following options:
+ *		DMA_IRQ_FLAG_DROP
+ *		DMA_IRQ_FLAG_HALF_FRAME_COMPL
+ *		DMA_IRQ_FLAG_FRAME_COMPL
+ *		DMA_IRQ_FLAG_START_LAST_FRAME
+ *		DMA_IRQ_FLAG_BLOCK_COMPL
+ *		DMA_IRQ_FLAG_ENDOF_PKT
+ *		DMA_IRQ_FLAG_DRAIN
+ *
+ *
+ *	LOCKING:
+ *	DMA registers protected by internal mutex
+ *
+ *	RETURNS:
+ *	EH_HANDLED or EH_NOT_HANDLED
+ */
+int
+ti_sdma_enable_channel_irq(unsigned int ch, uint32_t flags)
+{
+	struct ti_sdma_softc *sc = ti_sdma_sc;
+	uint32_t irq_enable;
+
+	/* Sanity check */
+	if (sc == NULL)
+		return (ENOMEM);
+
+	TI_SDMA_LOCK(sc);
+
+	if ((sc->sc_active_channels & (1 << ch)) == 0) {
+		TI_SDMA_UNLOCK(sc);
+		return (EINVAL);
+	}
+
+	/* Always enable the error interrupts if we have interrupts enabled */
+	flags |= DMA4_CICR_TRANS_ERR_IE | DMA4_CICR_SECURE_ERR_IE |
+	         DMA4_CICR_SUPERVISOR_ERR_IE | DMA4_CICR_MISALIGNED_ADRS_ERR_IE;
+
+	sc->sc_channel[ch].reg_cicr = flags;
+
+	/* Write the values to the register */
+	ti_sdma_write_4(sc, DMA4_CICR(ch), flags);
+
+	/* Enable the channel interrupt enable */
+	irq_enable = ti_sdma_read_4(sc, DMA4_IRQENABLE_L(0));
+	irq_enable |= (1 << ch);
+
+	ti_sdma_write_4(sc, DMA4_IRQENABLE_L(0), irq_enable);
+
+	/* Indicate the registers need to be rewritten on the next transaction */
+	sc->sc_channel[ch].need_reg_write = 1;
+
+	TI_SDMA_UNLOCK(sc);
+
+	return (0);
+}
+
+/**
+ *	ti_sdma_get_channel_status - returns the status of a given channel
+ *	@ch: the channel number to get the status of
+ *	@status: upon return will contain the status bitmask, see below for possible
+ *	         values.
+ *
+ *	      DMA_STATUS_DROP
+ *	      DMA_STATUS_HALF
+ *	      DMA_STATUS_FRAME
+ *	      DMA_STATUS_LAST
+ *	      DMA_STATUS_BLOCK
+ *	      DMA_STATUS_SYNC
+ *	      DMA_STATUS_PKT
+ *	      DMA_STATUS_TRANS_ERR
+ *	      DMA_STATUS_SECURE_ERR
+ *	      DMA_STATUS_SUPERVISOR_ERR
+ *	      DMA_STATUS_MISALIGNED_ADRS_ERR
+ *	      DMA_STATUS_DRAIN_END
+ *
+ *
+ *	LOCKING:
+ *	DMA registers protected by internal mutex
+ *
+ *	RETURNS:
+ *	EH_HANDLED or EH_NOT_HANDLED
+ */
+int
+ti_sdma_get_channel_status(unsigned int ch, uint32_t *status)
+{
+	struct ti_sdma_softc *sc = ti_sdma_sc;
+	uint32_t csr;
+
+	/* Sanity check */
+	if (sc == NULL)
+		return (ENOMEM);
+
+	TI_SDMA_LOCK(sc);
+
+	if ((sc->sc_active_channels & (1 << ch)) == 0) {
+		TI_SDMA_UNLOCK(sc);
+		return (EINVAL);
+	}
+
+	TI_SDMA_UNLOCK(sc);
+
+	csr = ti_sdma_read_4(sc, DMA4_CSR(ch));
+
+	if (status != NULL)
+		*status = csr;
+
+	return (0);
+}
+
+/**
+ *	ti_sdma_start_xfer - starts a DMA transfer
+ *	@ch: the channel number to set the endianess of
+ *	@src_paddr: the source phsyical address
+ *	@dst_paddr: the destination phsyical address
+ *	@frmcnt: the number of frames per block
+ *	@elmcnt: the number of elements in a frame, an element is either an 8, 16
+ *           or 32-bit value as defined by ti_sdma_set_xfer_burst()
+ *
+ *
+ *	LOCKING:
+ *	DMA registers protected by internal mutex
+ *
+ *	RETURNS:
+ *	EH_HANDLED or EH_NOT_HANDLED
+ */
+int
+ti_sdma_start_xfer(unsigned int ch, unsigned int src_paddr,
+                    unsigned long dst_paddr,
+                    unsigned int frmcnt, unsigned int elmcnt)
+{
+	struct ti_sdma_softc *sc = ti_sdma_sc;
+	struct ti_sdma_channel *channel;
+	uint32_t ccr;
+
+	/* Sanity check */
+	if (sc == NULL)
+		return (ENOMEM);
+
+	TI_SDMA_LOCK(sc);
+
+	if ((sc->sc_active_channels & (1 << ch)) == 0) {
+		TI_SDMA_UNLOCK(sc);
+		return (EINVAL);
+	}
+
+	channel = &sc->sc_channel[ch];
+
+	/* a) Write the CSDP register */
+	ti_sdma_write_4(sc, DMA4_CSDP(ch),
+	    channel->reg_csdp | DMA4_CSDP_WRITE_MODE(1));
+
+	/* b) Set the number of element per frame CEN[23:0] */
+	ti_sdma_write_4(sc, DMA4_CEN(ch), elmcnt);
+
+	/* c) Set the number of frame per block CFN[15:0] */
+	ti_sdma_write_4(sc, DMA4_CFN(ch), frmcnt);
+
+	/* d) Set the Source/dest start address index CSSA[31:0]/CDSA[31:0] */
+	ti_sdma_write_4(sc, DMA4_CSSA(ch), src_paddr);
+	ti_sdma_write_4(sc, DMA4_CDSA(ch), dst_paddr);
+
+	/* e) Write the CCR register */
+	ti_sdma_write_4(sc, DMA4_CCR(ch), channel->reg_ccr);
+
+	/* f)  - Set the source element index increment CSEI[15:0] */
+	ti_sdma_write_4(sc, DMA4_CSE(ch), 0x0001);
+
+	/*     - Set the source frame index increment CSFI[15:0] */
+	ti_sdma_write_4(sc, DMA4_CSF(ch), 0x0001);
+
+	/*     - Set the destination element index increment CDEI[15:0]*/
+	ti_sdma_write_4(sc, DMA4_CDE(ch), 0x0001);
+
+	/* - Set the destination frame index increment CDFI[31:0] */
+	ti_sdma_write_4(sc, DMA4_CDF(ch), 0x0001);
+
+	/* Clear the status register */
+	ti_sdma_write_4(sc, DMA4_CSR(ch), 0x1FFE);
+
+	/* Write the start-bit and away we go */
+	ccr = ti_sdma_read_4(sc, DMA4_CCR(ch));
+	ccr |= (1 << 7);
+	ti_sdma_write_4(sc, DMA4_CCR(ch), ccr);
+
+	/* Clear the reg write flag */
+	channel->need_reg_write = 0;
+
+	TI_SDMA_UNLOCK(sc);
+
+	return (0);
+}
+
+/**
+ *	ti_sdma_start_xfer_packet - starts a packet DMA transfer
+ *	@ch: the channel number to use for the transfer
+ *	@src_paddr: the source physical address
+ *	@dst_paddr: the destination physical address
+ *	@frmcnt: the number of frames to transfer
+ *	@elmcnt: the number of elements in a frame, an element is either an 8, 16
+ *           or 32-bit value as defined by ti_sdma_set_xfer_burst()
+ *	@pktsize: the number of elements in each transfer packet
+ *
+ *	The @frmcnt and @elmcnt define the overall number of bytes to transfer,
+ *	typically @frmcnt is 1 and @elmcnt contains the total number of elements.
+ *	@pktsize is the size of each individual packet, there might be multiple
+ *	packets per transfer.  i.e. for the following with element size of 32-bits
+ *
+ *		frmcnt = 1, elmcnt = 512, pktsize = 128
+ *
+ *	       Total transfer bytes = 1 * 512 = 512 elements or 2048 bytes
+ *	       Packets transfered   = 128 / 512 = 4
+ *
+ *
+ *	LOCKING:
+ *	DMA registers protected by internal mutex
+ *
+ *	RETURNS:
+ *	EH_HANDLED or EH_NOT_HANDLED
+ */
+int
+ti_sdma_start_xfer_packet(unsigned int ch, unsigned int src_paddr,
+                           unsigned long dst_paddr, unsigned int frmcnt,
+                           unsigned int elmcnt, unsigned int pktsize)
+{
+	struct ti_sdma_softc *sc = ti_sdma_sc;
+	struct ti_sdma_channel *channel;
+	uint32_t ccr;
+
+	/* Sanity check */
+	if (sc == NULL)
+		return (ENOMEM);
+
+	TI_SDMA_LOCK(sc);
+
+	if ((sc->sc_active_channels & (1 << ch)) == 0) {
+		TI_SDMA_UNLOCK(sc);
+		return (EINVAL);
+	}
+
+	channel = &sc->sc_channel[ch];
+
+	/* a) Write the CSDP register */
+	if (channel->need_reg_write)
+		ti_sdma_write_4(sc, DMA4_CSDP(ch),
+		    channel->reg_csdp | DMA4_CSDP_WRITE_MODE(1));
+
+	/* b) Set the number of elements to transfer CEN[23:0] */
+	ti_sdma_write_4(sc, DMA4_CEN(ch), elmcnt);
+
+	/* c) Set the number of frames to transfer CFN[15:0] */
+	ti_sdma_write_4(sc, DMA4_CFN(ch), frmcnt);
+
+	/* d) Set the Source/dest start address index CSSA[31:0]/CDSA[31:0] */
+	ti_sdma_write_4(sc, DMA4_CSSA(ch), src_paddr);
+	ti_sdma_write_4(sc, DMA4_CDSA(ch), dst_paddr);
+
+	/* e) Write the CCR register */
+	ti_sdma_write_4(sc, DMA4_CCR(ch),
+	    channel->reg_ccr | DMA4_CCR_PACKET_TRANS);
+
+	/* f)  - Set the source element index increment CSEI[15:0] */
+	ti_sdma_write_4(sc, DMA4_CSE(ch), 0x0001);
+
+	/*     - Set the packet size, this is dependent on the sync source */
+	if (channel->reg_ccr & DMA4_CCR_SEL_SRC_DST_SYNC(1))
+		ti_sdma_write_4(sc, DMA4_CSF(ch), pktsize);
+	else
+		ti_sdma_write_4(sc, DMA4_CDF(ch), pktsize);
+
+	/* - Set the destination frame index increment CDFI[31:0] */
+	ti_sdma_write_4(sc, DMA4_CDE(ch), 0x0001);
+
+	/* Clear the status register */
+	ti_sdma_write_4(sc, DMA4_CSR(ch), 0x1FFE);
+
+	/* Write the start-bit and away we go */
+	ccr = ti_sdma_read_4(sc, DMA4_CCR(ch));
+	ccr |= (1 << 7);
+	ti_sdma_write_4(sc, DMA4_CCR(ch), ccr);
+
+	/* Clear the reg write flag */
+	channel->need_reg_write = 0;
+
+	TI_SDMA_UNLOCK(sc);
+
+	return (0);
+}
+
+/**
+ *	ti_sdma_stop_xfer - stops any currently active transfers
+ *	@ch: the channel number to set the endianess of
+ *
+ *	This function call is effectively a NOP if no transaction is in progress.
+ *
+ *	LOCKING:
+ *	DMA registers protected by internal mutex
+ *
+ *	RETURNS:
+ *	EH_HANDLED or EH_NOT_HANDLED
+ */
+int
+ti_sdma_stop_xfer(unsigned int ch)
+{
+	struct ti_sdma_softc *sc = ti_sdma_sc;
+	unsigned int j;
+
+	/* Sanity check */
+	if (sc == NULL)
+		return (ENOMEM);
+
+	TI_SDMA_LOCK(sc);
+
+	if ((sc->sc_active_channels & (1 << ch)) == 0) {
+		TI_SDMA_UNLOCK(sc);
+		return (EINVAL);
+	}
+
+	/* Disable all DMA interrupts for the channel. */
+	ti_sdma_write_4(sc, DMA4_CICR(ch), 0);
+
+	/* Make sure the DMA transfer is stopped. */
+	ti_sdma_write_4(sc, DMA4_CCR(ch), 0);
+
+	/* Clear the CSR register and IRQ status register */
+	ti_sdma_write_4(sc, DMA4_CSR(ch), DMA4_CSR_CLEAR_MASK);
+	for (j = 0; j < NUM_DMA_IRQS; j++) {
+		ti_sdma_write_4(sc, DMA4_IRQSTATUS_L(j), (1 << ch));
+	}
+
+	/* Configuration registers need to be re-written on the next xfer */
+	sc->sc_channel[ch].need_reg_write = 1;
+
+	TI_SDMA_UNLOCK(sc);
+
+	return (0);
+}
+
+/**
+ *	ti_sdma_set_xfer_endianess - sets the endianess of subsequent transfers
+ *	@ch: the channel number to set the endianess of
+ *	@src: the source endianess (either DMA_ENDIAN_LITTLE or DMA_ENDIAN_BIG)
+ *	@dst: the destination endianess (either DMA_ENDIAN_LITTLE or DMA_ENDIAN_BIG)
+ *
+ *
+ *	LOCKING:
+ *	DMA registers protected by internal mutex
+ *
+ *	RETURNS:
+ *	EH_HANDLED or EH_NOT_HANDLED
+ */
+int
+ti_sdma_set_xfer_endianess(unsigned int ch, unsigned int src, unsigned int dst)
+{
+	struct ti_sdma_softc *sc = ti_sdma_sc;
+
+	/* Sanity check */
+	if (sc == NULL)
+		return (ENOMEM);
+
+	TI_SDMA_LOCK(sc);
+
+	if ((sc->sc_active_channels & (1 << ch)) == 0) {
+		TI_SDMA_UNLOCK(sc);
+		return (EINVAL);
+	}
+
+	sc->sc_channel[ch].reg_csdp &= ~DMA4_CSDP_SRC_ENDIANISM(1);
+	sc->sc_channel[ch].reg_csdp |= DMA4_CSDP_SRC_ENDIANISM(src);
+
+	sc->sc_channel[ch].reg_csdp &= ~DMA4_CSDP_DST_ENDIANISM(1);
+	sc->sc_channel[ch].reg_csdp |= DMA4_CSDP_DST_ENDIANISM(dst);
+
+	sc->sc_channel[ch].need_reg_write = 1;
+
+	TI_SDMA_UNLOCK(sc);
+
+	return 0;
+}
+
+/**
+ *	ti_sdma_set_xfer_burst - sets the source and destination element size
+ *	@ch: the channel number to set the burst settings of
+ *	@src: the source endianess (either DMA_BURST_NONE, DMA_BURST_16, DMA_BURST_32
+ *	      or DMA_BURST_64)
+ *	@dst: the destination endianess (either DMA_BURST_NONE, DMA_BURST_16,
+ *	      DMA_BURST_32 or DMA_BURST_64)
+ *
+ *	This function sets the size of the elements for all subsequent transfers.
+ *
+ *	LOCKING:
+ *	DMA registers protected by internal mutex
+ *
+ *	RETURNS:
+ *	EH_HANDLED or EH_NOT_HANDLED
+ */
+int
+ti_sdma_set_xfer_burst(unsigned int ch, unsigned int src, unsigned int dst)
+{
+	struct ti_sdma_softc *sc = ti_sdma_sc;
+
+	/* Sanity check */
+	if (sc == NULL)
+		return (ENOMEM);
+
+	TI_SDMA_LOCK(sc);
+
+	if ((sc->sc_active_channels & (1 << ch)) == 0) {
+		TI_SDMA_UNLOCK(sc);
+		return (EINVAL);
+	}
+
+	sc->sc_channel[ch].reg_csdp &= ~DMA4_CSDP_SRC_BURST_MODE(0x3);
+	sc->sc_channel[ch].reg_csdp |= DMA4_CSDP_SRC_BURST_MODE(src);
+
+	sc->sc_channel[ch].reg_csdp &= ~DMA4_CSDP_DST_BURST_MODE(0x3);
+	sc->sc_channel[ch].reg_csdp |= DMA4_CSDP_DST_BURST_MODE(dst);
+
+	sc->sc_channel[ch].need_reg_write = 1;
+
+	TI_SDMA_UNLOCK(sc);
+
+	return 0;
+}
+
+/**
+ *	ti_sdma_set_xfer_data_type - driver attach function
+ *	@ch: the channel number to set the endianess of
+ *	@type: the xfer data type (either DMA_DATA_8BITS_SCALAR, DMA_DATA_16BITS_SCALAR
+ *	       or DMA_DATA_32BITS_SCALAR)
+ *
+ *
+ *	LOCKING:
+ *	DMA registers protected by internal mutex
+ *
+ *	RETURNS:
+ *	EH_HANDLED or EH_NOT_HANDLED
+ */
+int
+ti_sdma_set_xfer_data_type(unsigned int ch, unsigned int type)
+{
+	struct ti_sdma_softc *sc = ti_sdma_sc;
+
+	/* Sanity check */
+	if (sc == NULL)
+		return (ENOMEM);
+
+	TI_SDMA_LOCK(sc);
+
+	if ((sc->sc_active_channels & (1 << ch)) == 0) {
+		TI_SDMA_UNLOCK(sc);
+		return (EINVAL);
+	}
+
+	sc->sc_channel[ch].reg_csdp &= ~DMA4_CSDP_DATA_TYPE(0x3);
+	sc->sc_channel[ch].reg_csdp |= DMA4_CSDP_DATA_TYPE(type);
+
+	sc->sc_channel[ch].need_reg_write = 1;
+
+	TI_SDMA_UNLOCK(sc);
+
+	return 0;
+}
+
+/**
+ *	ti_sdma_set_callback - driver attach function
+ *	@dev: dma device handle
+ *
+ *
+ *
+ *	LOCKING:
+ *	DMA registers protected by internal mutex
+ *
+ *	RETURNS:
+ *	EH_HANDLED or EH_NOT_HANDLED
+ */
+int
+ti_sdma_set_callback(unsigned int ch,
+                      void (*callback)(unsigned int ch, uint32_t status, void *data),
+                      void *data)
+{
+	struct ti_sdma_softc *sc = ti_sdma_sc;
+
+	/* Sanity check */
+	if (sc == NULL)
+		return (ENOMEM);
+
+	TI_SDMA_LOCK(sc);
+
+	if ((sc->sc_active_channels & (1 << ch)) == 0) {
+		TI_SDMA_UNLOCK(sc);
+		return (EINVAL);
+	}
+
+	sc->sc_channel[ch].callback = callback;
+	sc->sc_channel[ch].callback_data = data;
+
+	sc->sc_channel[ch].need_reg_write = 1;
+
+	TI_SDMA_UNLOCK(sc);
+
+	return 0;
+}
+
+/**
+ *	ti_sdma_sync_params - sets channel sync settings
+ *	@ch: the channel number to set the sync on
+ *	@trigger: the number of the sync trigger, this depends on what other H/W
+ *	          module is triggering/receiving the DMA transactions
+ *	@mode: flags describing the sync mode to use, it may have one or more of
+ *	          the following bits set; TI_SDMA_SYNC_FRAME,
+ *	          TI_SDMA_SYNC_BLOCK, TI_SDMA_SYNC_TRIG_ON_SRC.
+ *
+ *
+ *
+ *	LOCKING:
+ *	DMA registers protected by internal mutex
+ *
+ *	RETURNS:
+ *	EH_HANDLED or EH_NOT_HANDLED
+ */
+int
+ti_sdma_sync_params(unsigned int ch, unsigned int trigger, unsigned int mode)
+{
+	struct ti_sdma_softc *sc = ti_sdma_sc;
+	uint32_t ccr;
+
+	/* Sanity check */
+	if (sc == NULL)
+		return (ENOMEM);
+
+	TI_SDMA_LOCK(sc);
+
+	if ((sc->sc_active_channels & (1 << ch)) == 0) {
+		TI_SDMA_UNLOCK(sc);
+		return (EINVAL);
+	}
+
+	ccr = sc->sc_channel[ch].reg_ccr;
+
+	ccr &= ~DMA4_CCR_SYNC_TRIGGER(0x7F);
+	ccr |= DMA4_CCR_SYNC_TRIGGER(trigger + 1);
+
+	if (mode & TI_SDMA_SYNC_FRAME)
+		ccr |= DMA4_CCR_FRAME_SYNC(1);
+	else
+		ccr &= ~DMA4_CCR_FRAME_SYNC(1);
+
+	if (mode & TI_SDMA_SYNC_BLOCK)
+		ccr |= DMA4_CCR_BLOCK_SYNC(1);
+	else
+		ccr &= ~DMA4_CCR_BLOCK_SYNC(1);
+
+	if (mode & TI_SDMA_SYNC_TRIG_ON_SRC)
+		ccr |= DMA4_CCR_SEL_SRC_DST_SYNC(1);
+	else
+		ccr &= ~DMA4_CCR_SEL_SRC_DST_SYNC(1);
+
+	sc->sc_channel[ch].reg_ccr = ccr;
+
+	sc->sc_channel[ch].need_reg_write = 1;
+
+	TI_SDMA_UNLOCK(sc);
+
+	return 0;
+}
+
+/**
+ *	ti_sdma_set_addr_mode - driver attach function
+ *	@ch: the channel number to set the endianess of
+ *	@rd_mode: the xfer source addressing mode (either DMA_ADDR_CONSTANT,
+ *	          DMA_ADDR_POST_INCREMENT, DMA_ADDR_SINGLE_INDEX or
+ *	          DMA_ADDR_DOUBLE_INDEX)
+ *	@wr_mode: the xfer destination addressing mode (either DMA_ADDR_CONSTANT,
+ *	          DMA_ADDR_POST_INCREMENT, DMA_ADDR_SINGLE_INDEX or
+ *	          DMA_ADDR_DOUBLE_INDEX)
+ *
+ *
+ *	LOCKING:
+ *	DMA registers protected by internal mutex
+ *
+ *	RETURNS:
+ *	EH_HANDLED or EH_NOT_HANDLED
+ */
+int
+ti_sdma_set_addr_mode(unsigned int ch, unsigned int src_mode,
+                       unsigned int dst_mode)
+{
+	struct ti_sdma_softc *sc = ti_sdma_sc;
+	uint32_t ccr;
+
+	/* Sanity check */
+	if (sc == NULL)
+		return (ENOMEM);
+
+	TI_SDMA_LOCK(sc);
+
+	if ((sc->sc_active_channels & (1 << ch)) == 0) {
+		TI_SDMA_UNLOCK(sc);
+		return (EINVAL);
+	}
+
+	ccr = sc->sc_channel[ch].reg_ccr;
+
+	ccr &= ~DMA4_CCR_SRC_ADDRESS_MODE(0x3);
+	ccr |= DMA4_CCR_SRC_ADDRESS_MODE(src_mode);
+
+	ccr &= ~DMA4_CCR_DST_ADDRESS_MODE(0x3);
+	ccr |= DMA4_CCR_DST_ADDRESS_MODE(dst_mode);
+
+	sc->sc_channel[ch].reg_ccr = ccr;
+
+	sc->sc_channel[ch].need_reg_write = 1;
+
+	TI_SDMA_UNLOCK(sc);
+
+	return 0;
+}
+
+/**
+ *	ti_sdma_probe - driver probe function
+ *	@dev: dma device handle
+ *
+ *
+ *
+ *	RETURNS:
+ *	Always returns 0.
+ */
+static int
+ti_sdma_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "ti,sdma"))
+		return (ENXIO);
+
+	device_set_desc(dev, "TI sDMA Controller");
+	return (0);
+}
+
+/**
+ *	ti_sdma_attach - driver attach function
+ *	@dev: dma device handle
+ *
+ *	Initialises memory mapping/pointers to the DMA register set and requests
+ *	IRQs. This is effectively the setup function for the driver.
+ *
+ *	RETURNS:
+ *	0 on success or a negative error code failure.
+ */
+static int
+ti_sdma_attach(device_t dev)
+{
+	struct ti_sdma_softc *sc = device_get_softc(dev);
+	unsigned int timeout;
+	unsigned int i;
+	int      rid;
+	void    *ihl;
+	int      err;
+
+	/* Setup the basics */
+	sc->sc_dev = dev;
+
+	/* No channels active at the moment */
+	sc->sc_active_channels = 0x00000000;
+
+	/* Mutex to protect the shared data structures */
+	TI_SDMA_LOCK_INIT(sc);
+
+	/* Get the memory resource for the register mapping */
+	rid = 0;
+	sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
+	if (sc->sc_mem_res == NULL)
+		panic("%s: Cannot map registers", device_get_name(dev));
+
+	/* Enable the interface and functional clocks */
+	ti_prcm_clk_enable(SDMA_CLK);
+
+	/* Read the sDMA revision register and sanity check it's known */
+	sc->sc_hw_rev = ti_sdma_read_4(sc, DMA4_REVISION);
+	device_printf(dev, "sDMA revision %08x\n", sc->sc_hw_rev);
+
+	if (!ti_sdma_is_omap4_rev(sc) && !ti_sdma_is_omap3_rev(sc)) {
+		device_printf(sc->sc_dev, "error - unknown sDMA H/W revision\n");
+		return (EINVAL);
+	}
+
+	/* Disable all interrupts */
+	for (i = 0; i < NUM_DMA_IRQS; i++) {
+		ti_sdma_write_4(sc, DMA4_IRQENABLE_L(i), 0x00000000);
+	}
+
+	/* Soft-reset is only supported on pre-OMAP44xx devices */
+	if (ti_sdma_is_omap3_rev(sc)) {
+
+		/* Soft-reset */
+		ti_sdma_write_4(sc, DMA4_OCP_SYSCONFIG, 0x0002);
+
+		/* Set the timeout to 100ms*/
+		timeout = (hz < 10) ? 1 : ((100 * hz) / 1000);
+
+		/* Wait for DMA reset to complete */
+		while ((ti_sdma_read_4(sc, DMA4_SYSSTATUS) & 0x1) == 0x0) {
+
+			/* Sleep for a tick */
+			pause("DMARESET", 1);
+
+			if (timeout-- == 0) {
+				device_printf(sc->sc_dev, "sDMA reset operation timed out\n");
+				return (EINVAL);
+			}
+		}
+	}
+
+	/* 
+	 * Install interrupt handlers for the for possible interrupts. Any channel
+	 * can trip one of the four IRQs
+	 */
+	rid = 0;
+	sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+	    RF_ACTIVE | RF_SHAREABLE);
+	if (sc->sc_irq_res == NULL)
+		panic("Unable to setup the dma irq handler.\n");
+
+	err = bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
+	    NULL, ti_sdma_intr, NULL, &ihl);
+	if (err)
+		panic("%s: Cannot register IRQ", device_get_name(dev));
+
+	/* Store the DMA structure globally ... this driver should never be unloaded */
+	ti_sdma_sc = sc;
+
+	return (0);
+}
+
+static device_method_t ti_sdma_methods[] = {
+	DEVMETHOD(device_probe, ti_sdma_probe),
+	DEVMETHOD(device_attach, ti_sdma_attach),
+	{0, 0},
+};
+
+static driver_t ti_sdma_driver = {
+	"ti_sdma",
+	ti_sdma_methods,
+	sizeof(struct ti_sdma_softc),
+};
+static devclass_t ti_sdma_devclass;
+
+DRIVER_MODULE(ti_sdma, simplebus, ti_sdma_driver, ti_sdma_devclass, 0, 0);
+MODULE_DEPEND(ti_sdma, ti_prcm, 1, 1, 1);


Property changes on: trunk/sys/arm/ti/ti_sdma.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/ti_sdma.h
===================================================================
--- trunk/sys/arm/ti/ti_sdma.h	                        (rev 0)
+++ trunk/sys/arm/ti/ti_sdma.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,112 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2011
+ *	Ben Gray <ben.r.gray at gmail.com>.
+ * 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 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 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: stable/10/sys/arm/ti/ti_sdma.h 239281 2012-08-15 06:31:32Z gonzo $
+ */
+
+/**
+ * sDMA device driver interface for the TI SoC
+ *
+ * See the ti_sdma.c file for implementation details.
+ *
+ * Reference:
+ *  OMAP35x Applications Processor
+ *   Technical Reference Manual
+ *  (omap35xx_techref.pdf)
+ */
+#ifndef _TI_DMA_H_
+#define _TI_DMA_H_
+
+#define TI_SDMA_ENDIAN_BIG          0x1
+#define TI_SDMA_ENDIAN_LITTLE       0x0
+
+#define TI_SDMA_BURST_NONE          0x0
+#define TI_SDMA_BURST_16            0x1
+#define TI_SDMA_BURST_32            0x2
+#define TI_SDMA_BURST_64            0x3
+
+#define TI_SDMA_DATA_8BITS_SCALAR   0x0
+#define TI_SDMA_DATA_16BITS_SCALAR  0x1
+#define TI_SDMA_DATA_32BITS_SCALAR  0x2
+
+#define TI_SDMA_ADDR_CONSTANT       0x0
+#define TI_SDMA_ADDR_POST_INCREMENT 0x1
+#define TI_SDMA_ADDR_SINGLE_INDEX   0x2
+#define TI_SDMA_ADDR_DOUBLE_INDEX   0x3
+
+/**
+ * Status flags for the DMA callback
+ *
+ */
+#define TI_SDMA_STATUS_DROP                  (1UL << 1)
+#define TI_SDMA_STATUS_HALF                  (1UL << 2)
+#define TI_SDMA_STATUS_FRAME                 (1UL << 3)
+#define TI_SDMA_STATUS_LAST                  (1UL << 4)
+#define TI_SDMA_STATUS_BLOCK                 (1UL << 5)
+#define TI_SDMA_STATUS_SYNC                  (1UL << 6)
+#define TI_SDMA_STATUS_PKT                   (1UL << 7)
+#define TI_SDMA_STATUS_TRANS_ERR             (1UL << 8)
+#define TI_SDMA_STATUS_SECURE_ERR            (1UL << 9)
+#define TI_SDMA_STATUS_SUPERVISOR_ERR        (1UL << 10)
+#define TI_SDMA_STATUS_MISALIGNED_ADRS_ERR   (1UL << 11)
+#define TI_SDMA_STATUS_DRAIN_END             (1UL << 12)
+
+#define TI_SDMA_SYNC_FRAME                   (1UL << 0)
+#define TI_SDMA_SYNC_BLOCK                   (1UL << 1)
+#define TI_SDMA_SYNC_PACKET                  (TI_SDMA_SYNC_FRAME | TI_SDMA_SYNC_BLOCK)
+#define TI_SDMA_SYNC_TRIG_ON_SRC             (1UL << 8)
+#define TI_SDMA_SYNC_TRIG_ON_DST             (1UL << 9)
+
+#define TI_SDMA_IRQ_FLAG_DROP                (1UL << 1)
+#define TI_SDMA_IRQ_FLAG_HALF_FRAME_COMPL    (1UL << 2)
+#define TI_SDMA_IRQ_FLAG_FRAME_COMPL         (1UL << 3)
+#define TI_SDMA_IRQ_FLAG_START_LAST_FRAME    (1UL << 4)
+#define TI_SDMA_IRQ_FLAG_BLOCK_COMPL         (1UL << 5)
+#define TI_SDMA_IRQ_FLAG_ENDOF_PKT           (1UL << 7)
+#define TI_SDMA_IRQ_FLAG_DRAIN               (1UL << 12)
+
+int ti_sdma_activate_channel(unsigned int *ch,
+    void (*callback)(unsigned int ch, uint32_t status, void *data), void *data);
+int ti_sdma_deactivate_channel(unsigned int ch);
+int ti_sdma_start_xfer(unsigned int ch, unsigned int src_paddr,
+    unsigned long dst_paddr, unsigned int frmcnt, unsigned int elmcnt);
+int ti_sdma_start_xfer_packet(unsigned int ch, unsigned int src_paddr,
+    unsigned long dst_paddr, unsigned int frmcnt, unsigned int elmcnt, 
+    unsigned int pktsize);
+int ti_sdma_stop_xfer(unsigned int ch);
+int ti_sdma_enable_channel_irq(unsigned int ch, uint32_t flags);
+int ti_sdma_disable_channel_irq(unsigned int ch);
+int ti_sdma_get_channel_status(unsigned int ch, uint32_t *status);
+int ti_sdma_set_xfer_endianess(unsigned int ch, unsigned int src, unsigned int dst);
+int ti_sdma_set_xfer_burst(unsigned int ch, unsigned int src, unsigned int dst);
+int ti_sdma_set_xfer_data_type(unsigned int ch, unsigned int type);
+int ti_sdma_set_callback(unsigned int ch,
+    void (*callback)(unsigned int ch, uint32_t status, void *data), void *data);
+int ti_sdma_sync_params(unsigned int ch, unsigned int trigger, unsigned int mode);
+int ti_sdma_set_addr_mode(unsigned int ch, unsigned int src_mode, unsigned int dst_mode);
+
+#endif /* _TI_SDMA_H_ */


Property changes on: trunk/sys/arm/ti/ti_sdma.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/ti_sdmareg.h
===================================================================
--- trunk/sys/arm/ti/ti_sdmareg.h	                        (rev 0)
+++ trunk/sys/arm/ti/ti_sdmareg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,134 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2011
+ *	Ben Gray <ben.r.gray at gmail.com>.
+ * 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 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 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: stable/10/sys/arm/ti/ti_sdmareg.h 239281 2012-08-15 06:31:32Z gonzo $
+ */
+#ifndef	__TI_SDMAREG_H__
+#define	__TI_SDMAREG_H__
+
+/**
+ * The number of DMA channels possible on the controller.
+ */
+#define NUM_DMA_CHANNELS	32
+#define NUM_DMA_IRQS		4
+
+/**
+ * Register offsets
+ */
+#define DMA4_REVISION                            0x0000
+#define DMA4_IRQSTATUS_L(j)                     (0x0008 + ((j) * 0x4))
+#define DMA4_IRQENABLE_L(j)                     (0x0018 + ((j) * 0x4))
+#define DMA4_SYSSTATUS                           0x0028
+#define DMA4_OCP_SYSCONFIG                       0x002C
+#define DMA4_CAPS_0                              0x0064
+#define DMA4_CAPS_2                              0x006C
+#define DMA4_CAPS_3                              0x0070
+#define DMA4_CAPS_4                              0x0074
+#define DMA4_GCR                                 0x0078
+#define DMA4_CCR(i)                             (0x0080 + ((i) * 0x60))
+#define DMA4_CLNK_CTRL(i)                       (0x0084 + ((i) * 0x60))
+#define DMA4_CICR(i)                            (0x0088 + ((i) * 0x60))
+#define DMA4_CSR(i)                             (0x008C + ((i) * 0x60))
+#define DMA4_CSDP(i)                            (0x0090 + ((i) * 0x60))
+#define DMA4_CEN(i)                             (0x0094 + ((i) * 0x60))
+#define DMA4_CFN(i)                             (0x0098 + ((i) * 0x60))
+#define DMA4_CSSA(i)                            (0x009C + ((i) * 0x60))
+#define DMA4_CDSA(i)                            (0x00A0 + ((i) * 0x60))
+#define DMA4_CSE(i)                             (0x00A4 + ((i) * 0x60))
+#define DMA4_CSF(i)                             (0x00A8 + ((i) * 0x60))
+#define DMA4_CDE(i)                             (0x00AC + ((i) * 0x60))
+#define DMA4_CDF(i)                             (0x00B0 + ((i) * 0x60))
+#define DMA4_CSAC(i)                            (0x00B4 + ((i) * 0x60))
+#define DMA4_CDAC(i)                            (0x00B8 + ((i) * 0x60))
+#define DMA4_CCEN(i)                            (0x00BC + ((i) * 0x60))
+#define DMA4_CCFN(i)                            (0x00C0 + ((i) * 0x60))
+#define DMA4_COLOR(i)                           (0x00C4 + ((i) * 0x60))
+
+/* The following register are only defined on OMAP44xx (and newer?) */
+#define DMA4_CDP(i)                             (0x00D0 + ((i) * 0x60))
+#define DMA4_CNDP(i)                            (0x00D4 + ((i) * 0x60))
+#define DMA4_CCDN(i)                            (0x00D8 + ((i) * 0x60))
+
+/**
+ * Various register field settings
+ */
+#define DMA4_CSDP_DATA_TYPE(x)                  (((x) & 0x3) << 0)
+#define DMA4_CSDP_SRC_BURST_MODE(x)             (((x) & 0x3) << 7)
+#define DMA4_CSDP_DST_BURST_MODE(x)             (((x) & 0x3) << 14)
+#define DMA4_CSDP_SRC_ENDIANISM(x)              (((x) & 0x1) << 21)
+#define DMA4_CSDP_DST_ENDIANISM(x)              (((x) & 0x1) << 19)
+#define DMA4_CSDP_WRITE_MODE(x)                 (((x) & 0x3) << 16)
+#define DMA4_CSDP_SRC_PACKED(x)                 (((x) & 0x1) << 6)
+#define DMA4_CSDP_DST_PACKED(x)                 (((x) & 0x1) << 13)
+
+#define DMA4_CCR_DST_ADDRESS_MODE(x)            (((x) & 0x3) << 14)
+#define DMA4_CCR_SRC_ADDRESS_MODE(x)            (((x) & 0x3) << 12)
+#define DMA4_CCR_READ_PRIORITY(x)               (((x) & 0x1) << 6)
+#define DMA4_CCR_WRITE_PRIORITY(x)              (((x) & 0x1) << 26)
+#define DMA4_CCR_SYNC_TRIGGER(x)                ((((x) & 0x60) << 14) \
+                                                 | ((x) & 0x1f))
+#define	DMA4_CCR_FRAME_SYNC(x)                  (((x) & 0x1) << 5)
+#define	DMA4_CCR_BLOCK_SYNC(x)                  (((x) & 0x1) << 18)
+#define DMA4_CCR_SEL_SRC_DST_SYNC(x)            (((x) & 0x1) << 24)
+
+#define DMA4_CCR_PACKET_TRANS                   (DMA4_CCR_FRAME_SYNC(1) | \
+                                                 DMA4_CCR_BLOCK_SYNC(1) )
+
+#define DMA4_CSR_DROP                           (1UL << 1)
+#define DMA4_CSR_HALF                           (1UL << 2)
+#define DMA4_CSR_FRAME                          (1UL << 3)
+#define DMA4_CSR_LAST                           (1UL << 4)
+#define DMA4_CSR_BLOCK                          (1UL << 5)
+#define DMA4_CSR_SYNC                           (1UL << 6)
+#define DMA4_CSR_PKT                            (1UL << 7)
+#define DMA4_CSR_TRANS_ERR                      (1UL << 8)
+#define DMA4_CSR_SECURE_ERR                     (1UL << 9)
+#define DMA4_CSR_SUPERVISOR_ERR                 (1UL << 10)
+#define DMA4_CSR_MISALIGNED_ADRS_ERR            (1UL << 11)
+#define DMA4_CSR_DRAIN_END                      (1UL << 12)
+#define DMA4_CSR_CLEAR_MASK                     (0xffe)
+
+#define DMA4_CICR_DROP_IE                       (1UL << 1)
+#define DMA4_CICR_HALF_IE                       (1UL << 2)
+#define DMA4_CICR_FRAME_IE                      (1UL << 3)
+#define DMA4_CICR_LAST_IE                       (1UL << 4)
+#define DMA4_CICR_BLOCK_IE                      (1UL << 5)
+#define DMA4_CICR_PKT_IE                        (1UL << 7)
+#define DMA4_CICR_TRANS_ERR_IE                  (1UL << 8)
+#define DMA4_CICR_SECURE_ERR_IE                 (1UL << 9)
+#define DMA4_CICR_SUPERVISOR_ERR_IE             (1UL << 10)
+#define DMA4_CICR_MISALIGNED_ADRS_ERR_IE        (1UL << 11)
+#define DMA4_CICR_DRAIN_IE                      (1UL << 12)
+
+/**
+ *	The following H/W revision values were found be experimentation, TI don't
+ *	publish the revision numbers.  The TRM says "TI internal Data".
+ */
+#define DMA4_OMAP3_REV                          0x00000040
+#define DMA4_OMAP4_REV                          0x00010900
+
+#endif	/* __TI_SDMAREG_H__ */


Property changes on: trunk/sys/arm/ti/ti_sdmareg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/ti_smc.S
===================================================================
--- trunk/sys/arm/ti/ti_smc.S	                        (rev 0)
+++ trunk/sys/arm/ti/ti_smc.S	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,41 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Olivier Houchard.  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 ``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 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 <machine/armreg.h>
+#include <machine/asm.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/ti/ti_smc.S 275767 2014-12-14 16:28:53Z andrew $");
+
+	.cpu cortex-a8
+	.arch_extension sec
+
+/* Issue a smc #0 call */
+/* r0 and r1 contains the eventual arguments, r2 contains the function ID */
+ENTRY(ti_smc0)
+	stmfd	sp!, {r4-r12, lr}
+	mov	r12, r2 /* the rom expects the function ID in r12 */
+	dsb
+	smc	#0
+	ldmfd	sp!, {r4-r12, pc}
+	


Property changes on: trunk/sys/arm/ti/ti_smc.S
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/ti_smc.h
===================================================================
--- trunk/sys/arm/ti/ti_smc.h	                        (rev 0)
+++ trunk/sys/arm/ti/ti_smc.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,34 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Olivier Houchard.  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 ``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 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: stable/10/sys/arm/ti/ti_smc.h 239281 2012-08-15 06:31:32Z gonzo $
+ */
+
+#ifndef TI_SMC_H_
+#define TI_SMC_H_
+uint32_t ti_smc0(uint32_t r0, uint32_t r1, uint32_t function_id);
+#endif /* TI_SMC_H_ */


Property changes on: trunk/sys/arm/ti/ti_smc.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/ti_wdt.c
===================================================================
--- trunk/sys/arm/ti/ti_wdt.c	                        (rev 0)
+++ trunk/sys/arm/ti/ti_wdt.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,278 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014 Rui Paulo <rpaulo at FreeBSD.org>
+ * 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 ``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 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: stable/10/sys/arm/ti/ti_wdt.c 276290 2014-12-27 05:11:34Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/event.h>
+#include <sys/selinfo.h>
+#include <sys/watchdog.h>
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/frame.h>
+#include <machine/intr.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+
+#include <arm/ti/ti_prcm.h>
+#include <arm/ti/ti_wdt.h>
+
+#ifdef DEBUG
+#define	DPRINTF(fmt, ...)	do {	\
+	printf("%s: ", __func__);	\
+	printf(fmt, __VA_ARGS__);	\
+} while (0)
+#else
+#define	DPRINTF(fmt, ...)
+#endif
+
+static device_probe_t		ti_wdt_probe;
+static device_attach_t		ti_wdt_attach;
+static device_detach_t		ti_wdt_detach;
+static void			ti_wdt_intr(void *);
+static void			ti_wdt_event(void *, unsigned int, int *);
+
+struct ti_wdt_softc {
+	struct resource 	*sc_mem_res;
+	struct resource 	*sc_irq_res;
+	void            	*sc_intr;
+	bus_space_tag_t		sc_bt;
+	bus_space_handle_t	sc_bh;
+	eventhandler_tag	sc_ev_tag;
+};
+
+static device_method_t ti_wdt_methods[] = {
+	DEVMETHOD(device_probe,		ti_wdt_probe),
+	DEVMETHOD(device_attach,	ti_wdt_attach),
+	DEVMETHOD(device_detach,	ti_wdt_detach),
+
+	DEVMETHOD_END
+};
+
+static driver_t ti_wdt_driver = {
+	"ti_wdt",
+	ti_wdt_methods,
+	sizeof(struct ti_wdt_softc)
+};
+
+static devclass_t ti_wdt_devclass;
+
+DRIVER_MODULE(ti_wdt, simplebus, ti_wdt_driver, ti_wdt_devclass, 0, 0);
+
+static __inline uint32_t
+ti_wdt_reg_read(struct ti_wdt_softc *sc, uint32_t reg)
+{
+
+	return (bus_space_read_4(sc->sc_bt, sc->sc_bh, reg));
+}
+
+static __inline void
+ti_wdt_reg_write(struct ti_wdt_softc *sc, uint32_t reg, uint32_t val)
+{
+
+	bus_space_write_4(sc->sc_bt, sc->sc_bh, reg, val);
+}
+
+/*
+ * Wait for the write to a specific synchronised register to complete.
+ */
+static __inline void
+ti_wdt_reg_wait(struct ti_wdt_softc *sc, uint32_t bit)
+{
+
+	while (ti_wdt_reg_read(sc, TI_WDT_WWPS) & bit)
+		DELAY(10);
+}
+
+static __inline void
+ti_wdt_disable(struct ti_wdt_softc *sc)
+{
+
+	DPRINTF("disabling watchdog %p\n", sc);
+	ti_wdt_reg_write(sc, TI_WDT_WSPR, 0xAAAA);
+	ti_wdt_reg_wait(sc, TI_W_PEND_WSPR);
+	ti_wdt_reg_write(sc, TI_WDT_WSPR, 0x5555);
+	ti_wdt_reg_wait(sc, TI_W_PEND_WSPR);
+}
+
+static __inline void
+ti_wdt_enable(struct ti_wdt_softc *sc)
+{
+
+	DPRINTF("enabling watchdog %p\n", sc);
+	ti_wdt_reg_write(sc, TI_WDT_WSPR, 0xBBBB);
+	ti_wdt_reg_wait(sc, TI_W_PEND_WSPR);
+	ti_wdt_reg_write(sc, TI_WDT_WSPR, 0x4444);
+	ti_wdt_reg_wait(sc, TI_W_PEND_WSPR);
+}
+
+static int
+ti_wdt_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+	if (ofw_bus_is_compatible(dev, "ti,omap3-wdt")) {
+		device_set_desc(dev, "TI Watchdog Timer");
+		return (BUS_PROBE_DEFAULT);
+	}
+
+	return (ENXIO);
+}
+
+static int
+ti_wdt_attach(device_t dev)
+{
+	struct ti_wdt_softc *sc;
+	int rid;
+
+	sc = device_get_softc(dev);
+	rid = 0;
+	sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	    RF_ACTIVE);
+	if (sc->sc_mem_res == NULL) {
+		device_printf(dev, "could not allocate memory resource\n");
+		return (ENXIO);
+	}
+	sc->sc_bt = rman_get_bustag(sc->sc_mem_res);
+	sc->sc_bh = rman_get_bushandle(sc->sc_mem_res);
+	sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE);
+	if (sc->sc_irq_res == NULL) {
+		device_printf(dev, "could not allocate interrupt resource\n");
+		ti_wdt_detach(dev);
+		return (ENXIO);
+	}
+	if (bus_setup_intr(dev, sc->sc_irq_res, INTR_MPSAFE | INTR_TYPE_MISC,
+		NULL, ti_wdt_intr, sc,  &sc->sc_intr) != 0) {
+		device_printf(dev,
+		    "unable to setup the interrupt handler\n");
+		ti_wdt_detach(dev);
+		return (ENXIO);
+	}
+	/* Reset, enable interrupts and stop the watchdog. */
+	ti_wdt_reg_write(sc, TI_WDT_WDSC,
+	    ti_wdt_reg_read(sc, TI_WDT_WDSC) | TI_WDSC_SR);
+	while (ti_wdt_reg_read(sc, TI_WDT_WDSC) & TI_WDSC_SR)
+		DELAY(10);
+	ti_wdt_reg_write(sc, TI_WDT_WIRQENSET, TI_IRQ_EN_OVF | TI_IRQ_EN_DLY);
+	ti_wdt_disable(sc);
+	if (bootverbose)
+		device_printf(dev, "revision: 0x%x\n",
+		    ti_wdt_reg_read(sc, TI_WDT_WIDR));
+	sc->sc_ev_tag = EVENTHANDLER_REGISTER(watchdog_list, ti_wdt_event, sc,
+	    0);
+
+	return (0);
+}
+
+static int
+ti_wdt_detach(device_t dev)
+{
+	struct ti_wdt_softc *sc;
+
+	sc = device_get_softc(dev);
+	if (sc->sc_ev_tag)
+		EVENTHANDLER_DEREGISTER(watchdog_list, sc->sc_ev_tag);
+	if (sc->sc_intr)
+		bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_intr);
+	if (sc->sc_irq_res)
+		bus_release_resource(dev, SYS_RES_IRQ,
+		    rman_get_rid(sc->sc_irq_res), sc->sc_irq_res);
+	if (sc->sc_mem_res)
+		bus_release_resource(dev, SYS_RES_MEMORY,
+		    rman_get_rid(sc->sc_mem_res),  sc->sc_mem_res);
+
+	return (0);
+}
+
+static void
+ti_wdt_intr(void *arg)
+{
+	struct ti_wdt_softc *sc;
+
+	sc = arg;
+	DPRINTF("interrupt %p", sc);
+	ti_wdt_reg_write(sc, TI_WDT_WIRQSTAT, TI_IRQ_EV_OVF | TI_IRQ_EV_DLY);
+	/* TODO: handle interrupt */
+}
+
+static void
+ti_wdt_event(void *arg, unsigned int cmd, int *error)
+{
+	struct ti_wdt_softc *sc;
+	uint8_t s;
+	uint32_t wldr;
+	uint32_t ptv;
+
+	sc = arg;
+	ti_wdt_disable(sc);
+	if (cmd == WD_TO_NEVER) {
+		*error = 0;
+		return;
+	}
+	DPRINTF("cmd 0x%x\n", cmd);
+	cmd &= WD_INTERVAL;
+	if (cmd < WD_TO_1SEC) {
+		*error = EINVAL;
+		return;
+	}
+	s = 1 << (cmd - WD_TO_1SEC);
+	DPRINTF("seconds %u\n", s);
+	/*
+	 * Leave the pre-scaler with its default values:
+	 * PTV = 0 == 2**0 == 1
+	 * PRE = 1 (enabled)
+	 *
+	 * Compute the load register value assuming a 32kHz clock.
+	 * See OVF_Rate in the WDT section of the AM335x TRM.
+	 */
+	ptv = 0;
+	wldr = 0xffffffff - (s * (32768 / (1 << ptv))) + 1;
+	DPRINTF("wldr 0x%x\n", wldr);
+	ti_wdt_reg_write(sc, TI_WDT_WLDR, wldr);
+	/*
+	 * Trigger a timer reload.
+	 */
+	ti_wdt_reg_write(sc, TI_WDT_WTGR,
+	    ti_wdt_reg_read(sc, TI_WDT_WTGR) + 1);
+	ti_wdt_reg_wait(sc, TI_W_PEND_WTGR);
+	ti_wdt_enable(sc);
+	*error = 0;
+}


Property changes on: trunk/sys/arm/ti/ti_wdt.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/ti_wdt.h
===================================================================
--- trunk/sys/arm/ti/ti_wdt.h	                        (rev 0)
+++ trunk/sys/arm/ti/ti_wdt.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,75 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014 Rui Paulo <rpaulo at FreeBSD.org>
+ * 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 ``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 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: stable/10/sys/arm/ti/ti_wdt.h 273624 2014-10-25 02:05:21Z rpaulo $
+ */
+#ifndef _TI_WDT_H_
+#define _TI_WDT_H_
+
+/* TI WDT registers */
+#define	TI_WDT_WIDR		0x00	/* Watchdog Identification Register */
+#define	TI_WDT_WDSC		0x10	/* Watchdog System Control Register */
+#define	TI_WDT_WDST		0x14	/* Watchdog Status Register */
+#define	TI_WDT_WISR		0x18	/* Watchdog Interrupt Status Register */
+#define	TI_WDT_WIER		0x1c	/* Watchdog Interrupt Enable Register */
+#define	TI_WDT_WCLR		0x24	/* Watchdog Control Register */
+#define	TI_WDT_WCRR		0x28	/* Watchdog Counter Register */
+#define	TI_WDT_WLDR		0x2c	/* Watchdog Load Register */
+#define	TI_WDT_WTGR		0x30	/* Watchdog Trigger Register */
+#define	TI_WDT_WWPS		0x34	/* Watchdog Write Posting Register */
+#define	TI_WDT_WDLY		0x44	/* Watchdog Delay Configuration Reg */
+#define	TI_WDT_WSPR		0x48	/* Watchdog Start/Stop Register */
+#define	TI_WDT_WIRQSTATRAW	0x54	/* Watchdog Raw Interrupt Status Reg. */
+#define	TI_WDT_WIRQSTAT		0x58	/* Watchdog Int. Status Register */
+#define	TI_WDT_WIRQENSET	0x5c	/* Watchdog Int. Enable Set Register */
+#define	TI_WDT_WIRQENCLR	0x60	/* Watchdog Int. Enable Clear Reg. */
+
+/* WDT_WDSC Register */
+#define	TI_WDSC_SR		(1 << 1) /* Soft reset */
+
+/*
+ * WDT_WWPS Register
+ *
+ * Writes to some registers require synchronisation with a different clock
+ * domain.  The WDT_WWPS register is the place where this synchronisation
+ * happens.
+ */
+#define	TI_W_PEND_WCLR		(1 << 0)
+#define	TI_W_PEND_WCRR		(1 << 1)
+#define	TI_W_PEND_WLDR		(1 << 2)
+#define	TI_W_PEND_WTGR		(1 << 3)
+#define	TI_W_PEND_WSPR		(1 << 4)
+#define	TI_W_PEND_WDLY		(1 << 5)
+
+/* WDT_WIRQENSET Register */
+#define	TI_IRQ_EN_OVF		(1 << 0)	/* Overflow interrupt */
+#define	TI_IRQ_EN_DLY		(1 << 1)	/* Delay interrupt */
+
+/* WDT_WIRQSTAT Register */
+#define	TI_IRQ_EV_OVF		(1 << 0)	/* Overflow event */
+#define	TI_IRQ_EV_DLY		(1 << 1)	/* Delay event */
+
+#endif /* _TI_WDT_H_ */


Property changes on: trunk/sys/arm/ti/ti_wdt.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/tivar.h
===================================================================
--- trunk/sys/arm/ti/tivar.h	                        (rev 0)
+++ trunk/sys/arm/ti/tivar.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,42 @@
+/* $MidnightBSD$ */
+/*
+ * Copyright (c) 2010
+ *	Ben Gray <ben.r.gray at gmail.com>.
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Ben Gray.
+ * 4. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BEN GRAY ``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 BEN GRAY 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: stable/10/sys/arm/ti/tivar.h 239281 2012-08-15 06:31:32Z gonzo $
+ */
+
+#ifndef _TIVAR_H_
+#define	_TIVAR_H_
+
+/* board-dependent reset function implementation */
+extern void (*ti_cpu_reset)(void);
+
+#endif /* _TIVAR_H_ */


Property changes on: trunk/sys/arm/ti/tivar.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/twl/twl.c
===================================================================
--- trunk/sys/arm/ti/twl/twl.c	                        (rev 0)
+++ trunk/sys/arm/ti/twl/twl.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,464 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2011
+ *	Ben Gray <ben.r.gray at gmail.com>.
+ * 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 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 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: stable/10/sys/arm/ti/twl/twl.c 259329 2013-12-13 20:43:11Z ian $");
+
+/*
+ * Texas Instruments TWL4030/TWL5030/TWL60x0/TPS659x0 Power Management and
+ * Audio CODEC devices.
+ *
+ * This code is based on the Linux TWL multifunctional device driver, which is
+ * copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * These chips are typically used as support ICs for the OMAP range of embedded
+ * ARM processes/SOC from Texas Instruments.  They are typically used to control
+ * on board voltages, however some variants have other features like audio
+ * codecs, USB OTG transceivers, RTC, PWM, etc.
+ *
+ * This driver acts as a bus for more specific companion devices.
+ *
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+#include <sys/sysctl.h>
+#include <sys/mutex.h>
+#include <sys/malloc.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+#include <machine/resource.h>
+#include <machine/intr.h>
+
+#include <dev/iicbus/iicbus.h>
+#include <dev/iicbus/iiconf.h>
+
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include "arm/ti/twl/twl.h"
+
+/* TWL device IDs */
+#define TWL_DEVICE_UNKNOWN          0xffff
+#define TWL_DEVICE_4030             0x4030
+#define TWL_DEVICE_6025             0x6025
+#define TWL_DEVICE_6030             0x6030
+
+/* Each TWL device typically has more than one I2C address */
+#define TWL_MAX_SUBADDRS            4
+
+/* The maxium number of bytes that can be written in one call */
+#define TWL_MAX_IIC_DATA_SIZE       63
+
+/* The TWL devices typically use 4 I2C address for the different internal
+ * register sets, plus one SmartReflex I2C address.
+ */
+#define TWL_CHIP_ID0                0x48
+#define TWL_CHIP_ID1                0x49
+#define TWL_CHIP_ID2                0x4A
+#define TWL_CHIP_ID3                0x4B
+
+#define TWL_SMARTREFLEX_CHIP_ID     0x12
+
+#define TWL_INVALID_CHIP_ID         0xff
+
+struct twl_softc {
+	device_t		sc_dev;
+	struct mtx		sc_mtx;
+	unsigned int	sc_type;
+
+	uint8_t			sc_subaddr_map[TWL_MAX_SUBADDRS];
+
+	struct intr_config_hook	sc_scan_hook;
+
+	device_t		sc_vreg;
+	device_t		sc_clks;
+};
+
+/**
+ *	Macros for driver mutex locking
+ */
+#define TWL_LOCK(_sc)             mtx_lock(&(_sc)->sc_mtx)
+#define	TWL_UNLOCK(_sc)           mtx_unlock(&(_sc)->sc_mtx)
+#define TWL_LOCK_INIT(_sc) \
+	mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->sc_dev), \
+	         "twl", MTX_DEF)
+#define TWL_LOCK_DESTROY(_sc)     mtx_destroy(&_sc->sc_mtx);
+#define TWL_ASSERT_LOCKED(_sc)    mtx_assert(&_sc->sc_mtx, MA_OWNED);
+#define TWL_ASSERT_UNLOCKED(_sc)  mtx_assert(&_sc->sc_mtx, MA_NOTOWNED);
+
+
+/**
+ *	twl_is_4030 - returns true if the device is TWL4030
+ *	twl_is_6025 - returns true if the device is TWL6025
+ *	twl_is_6030 - returns true if the device is TWL6030
+ *	@sc: device soft context
+ *
+ *	Returns a non-zero value if the device matches.
+ *
+ *	RETURNS:
+ *	Returns a non-zero value if the device matches, otherwise zero.
+ */
+int
+twl_is_4030(device_t dev)
+{
+	struct twl_softc *sc = device_get_softc(dev);
+	return (sc->sc_type == TWL_DEVICE_4030);
+}
+
+int
+twl_is_6025(device_t dev)
+{
+	struct twl_softc *sc = device_get_softc(dev);
+	return (sc->sc_type == TWL_DEVICE_6025);
+}
+
+int
+twl_is_6030(device_t dev)
+{
+	struct twl_softc *sc = device_get_softc(dev);
+	return (sc->sc_type == TWL_DEVICE_6030);
+}
+
+
+/**
+ *	twl_read - read one or more registers from the TWL device
+ *	@sc: device soft context
+ *	@nsub: the sub-module to read from
+ *	@reg: the register offset within the module to read
+ *	@buf: buffer to store the bytes in
+ *	@cnt: the number of bytes to read
+ *
+ *	Reads one or more registers and stores the result in the suppled buffer.
+ *
+ *	RETURNS:
+ *	Zero on success or an error code on failure.
+ */
+int
+twl_read(device_t dev, uint8_t nsub, uint8_t reg, uint8_t *buf, uint16_t cnt)
+{
+	struct twl_softc *sc;
+	struct iic_msg msg[2];
+	uint8_t addr;
+	int rc;
+
+	sc = device_get_softc(dev);
+
+	TWL_LOCK(sc);
+	addr = sc->sc_subaddr_map[nsub];
+	TWL_UNLOCK(sc);
+
+	if (addr == TWL_INVALID_CHIP_ID)
+		return (EIO);
+
+
+	/* Set the address to read from */
+	msg[0].slave = addr;
+	msg[0].flags = IIC_M_WR | IIC_M_NOSTOP;
+	msg[0].len = 1;
+	msg[0].buf = ®
+	/* Read the data back */
+	msg[1].slave = addr;
+	msg[1].flags = IIC_M_RD;
+	msg[1].len = cnt;
+	msg[1].buf = buf;
+
+	rc = iicbus_transfer(dev, msg, 2);
+	if (rc != 0) {
+		device_printf(dev, "iicbus read failed (adr:0x%02x, reg:0x%02x)\n",
+		              addr, reg);
+		return (EIO);
+	}
+
+	return (0);
+}
+
+/**
+ *	twl_write - writes one or more registers to the TWL device
+ *	@sc: device soft context
+ *	@nsub: the sub-module to read from
+ *	@reg: the register offset within the module to read
+ *	@buf: data to write
+ *	@cnt: the number of bytes to write
+ *
+ *	Writes one or more registers.
+ *
+ *	RETURNS:
+ *	Zero on success or a negative error code on failure.
+ */
+int
+twl_write(device_t dev, uint8_t nsub, uint8_t reg, uint8_t *buf, uint16_t cnt)
+{
+	struct twl_softc *sc;
+	struct iic_msg msg;
+	uint8_t addr;
+	uint8_t tmp_buf[TWL_MAX_IIC_DATA_SIZE + 1];
+	int rc;
+
+	if (cnt > TWL_MAX_IIC_DATA_SIZE)
+		return (ENOMEM);
+
+	/* Set the register address as the first byte */
+	tmp_buf[0] = reg;
+	memcpy(&tmp_buf[1], buf, cnt);
+
+	sc = device_get_softc(dev);
+
+	TWL_LOCK(sc);
+	addr = sc->sc_subaddr_map[nsub];
+	TWL_UNLOCK(sc);
+
+	if (addr == TWL_INVALID_CHIP_ID)
+		return (EIO);
+
+
+	/* Setup the transfer and execute it */
+	msg.slave = addr;
+	msg.flags = IIC_M_WR;
+	msg.len = cnt + 1;
+	msg.buf = tmp_buf;
+
+	rc = iicbus_transfer(dev, &msg, 1);
+	if (rc != 0) {
+		device_printf(sc->sc_dev, "iicbus write failed (adr:0x%02x, reg:0x%02x)\n",
+		              addr, reg);
+		return (EIO);
+	}
+
+	return (0);
+}
+
+/**
+ *	twl_test_present - checks if a device with given address is present
+ *	@sc: device soft context
+ *	@addr: the address of the device to scan for
+ *
+ *	Sends just the address byte and checks for an ACK. If no ACK then device
+ *	is assumed to not be present.
+ *
+ *	RETURNS:
+ *	EIO if device is not present, otherwise 0 is returned.
+ */
+static int
+twl_test_present(struct twl_softc *sc, uint8_t addr)
+{
+	struct iic_msg msg;
+	uint8_t tmp;
+
+	/* Set the address to read from */
+	msg.slave = addr;
+	msg.flags = IIC_M_RD;
+	msg.len = 1;
+	msg.buf = &tmp;
+
+	if (iicbus_transfer(sc->sc_dev, &msg, 1) != 0)
+		return (EIO);
+
+	return (0);
+}
+
+/**
+ *	twl_scan - scans the i2c bus for sub modules
+ *	@dev: the twl device
+ *
+ *	TWL devices don't just have one i2c slave address, rather they have up to
+ *	5 other addresses, each is for separate modules within the device. This
+ *	function scans the bus for 4 possible sub-devices and stores the info
+ *	internally.
+ *
+ */
+static void
+twl_scan(void *dev)
+{
+	struct twl_softc *sc;
+	unsigned i;
+	uint8_t devs[TWL_MAX_SUBADDRS];
+	uint8_t base = TWL_CHIP_ID0;
+
+	sc = device_get_softc((device_t)dev);
+
+	memset(devs, TWL_INVALID_CHIP_ID, TWL_MAX_SUBADDRS);
+
+	/* Try each of the addresses (0x48, 0x49, 0x4a & 0x4b) to determine which
+	 * sub modules we have.
+	 */
+	for (i = 0; i < TWL_MAX_SUBADDRS; i++) {
+		if (twl_test_present(sc, (base + i)) == 0) {
+			devs[i] = (base + i);
+			device_printf(sc->sc_dev, "Found (sub)device at 0x%02x\n", (base + i));
+		}
+	}
+
+	TWL_LOCK(sc);
+	memcpy(sc->sc_subaddr_map, devs, TWL_MAX_SUBADDRS);
+	TWL_UNLOCK(sc);
+
+	/* Finished with the interrupt hook */
+	config_intrhook_disestablish(&sc->sc_scan_hook);
+}
+
+/**
+ *	twl_probe - 
+ *	@dev: the twl device
+ *
+ *	Scans the FDT for a match for the device, possible compatible device
+ *	strings are; "ti,twl6030", "ti,twl6025", "ti,twl4030".  
+ *
+ *	The FDT compat string also determines the type of device (it is currently
+ *	not possible to dynamically determine the device type).
+ *
+ */
+static int
+twl_probe(device_t dev)
+{
+	phandle_t node;
+	const char *compat;
+	int len, l;
+	struct twl_softc *sc;
+
+	if ((compat = ofw_bus_get_compat(dev)) == NULL)
+		return (ENXIO);
+
+	if ((node = ofw_bus_get_node(dev)) == 0)
+		return (ENXIO);
+
+	/* Get total 'compatible' prop len */
+	if ((len = OF_getproplen(node, "compatible")) <= 0)
+		return (ENXIO);
+
+	sc = device_get_softc(dev);
+	sc->sc_dev = dev;
+	sc->sc_type = TWL_DEVICE_UNKNOWN;
+
+	while (len > 0) {
+		if (strncasecmp(compat, "ti,twl6030", 10) == 0)
+			sc->sc_type = TWL_DEVICE_6030;
+		else if (strncasecmp(compat, "ti,twl6025", 10) == 0)
+			sc->sc_type = TWL_DEVICE_6025;
+		else if (strncasecmp(compat, "ti,twl4030", 10) == 0)
+			sc->sc_type = TWL_DEVICE_4030;
+		
+		if (sc->sc_type != TWL_DEVICE_UNKNOWN)
+			break;
+
+		/* Slide to the next sub-string. */
+		l = strlen(compat) + 1;
+		compat += l;
+		len -= l;
+	}
+	
+	switch (sc->sc_type) {
+	case TWL_DEVICE_4030:
+		device_set_desc(dev, "TI TWL4030/TPS659x0 Companion IC");
+		break;
+	case TWL_DEVICE_6025:
+		device_set_desc(dev, "TI TWL6025 Companion IC");
+		break;
+	case TWL_DEVICE_6030:
+		device_set_desc(dev, "TI TWL6030 Companion IC");
+		break;
+	case TWL_DEVICE_UNKNOWN:
+	default:
+		return (ENXIO);
+	}
+	
+	return (0);
+}
+
+static int
+twl_attach(device_t dev)
+{
+	struct twl_softc *sc;
+
+	sc = device_get_softc(dev);
+	sc->sc_dev = dev;
+
+	TWL_LOCK_INIT(sc);
+
+	/* We have to wait until interrupts are enabled. I2C read and write
+	 * only works if the interrupts are available.
+	 */
+	sc->sc_scan_hook.ich_func = twl_scan;
+	sc->sc_scan_hook.ich_arg = dev;
+
+	if (config_intrhook_establish(&sc->sc_scan_hook) != 0)
+		return (ENOMEM);
+
+	/* FIXME: should be in DTS file */
+	if ((sc->sc_vreg = device_add_child(dev, "twl_vreg", -1)) == NULL)
+		device_printf(dev, "could not allocate twl_vreg instance\n");
+	if ((sc->sc_clks = device_add_child(dev, "twl_clks", -1)) == NULL)
+		device_printf(dev, "could not allocate twl_clks instance\n");
+
+	return (bus_generic_attach(dev));
+}
+
+static int
+twl_detach(device_t dev)
+{
+	struct twl_softc *sc;
+
+	sc = device_get_softc(dev);
+
+	if (sc->sc_vreg)
+		device_delete_child(dev, sc->sc_vreg);
+	if (sc->sc_clks)
+		device_delete_child(dev, sc->sc_clks);
+	
+
+	TWL_LOCK_DESTROY(sc);
+
+	return (0);
+}
+
+static device_method_t twl_methods[] = {
+	DEVMETHOD(device_probe,		twl_probe),
+	DEVMETHOD(device_attach,	twl_attach),
+	DEVMETHOD(device_detach,	twl_detach),
+
+	{0, 0},
+};
+
+static driver_t twl_driver = {
+	"twl",
+	twl_methods,
+	sizeof(struct twl_softc),
+};
+static devclass_t twl_devclass;
+
+DRIVER_MODULE(twl, iicbus, twl_driver, twl_devclass, 0, 0);
+MODULE_VERSION(twl, 1);


Property changes on: trunk/sys/arm/ti/twl/twl.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/twl/twl.h
===================================================================
--- trunk/sys/arm/ti/twl/twl.h	                        (rev 0)
+++ trunk/sys/arm/ti/twl/twl.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,40 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2011
+ *	Ben Gray <ben.r.gray at gmail.com>.
+ * 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 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 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: stable/10/sys/arm/ti/twl/twl.h 239281 2012-08-15 06:31:32Z gonzo $
+ */
+#ifndef _TWL_H_
+#define _TWL_H_
+
+int twl_read(device_t dev, uint8_t nsub, uint8_t reg, uint8_t *buf, uint16_t cnt);
+int twl_write(device_t dev, uint8_t nsub, uint8_t reg, uint8_t *buf, uint16_t cnt);
+
+int twl_is_4030(device_t dev);
+int twl_is_6025(device_t dev);
+int twl_is_6030(device_t dev);
+
+#endif /* _TWL_H_ */


Property changes on: trunk/sys/arm/ti/twl/twl.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/twl/twl_clks.c
===================================================================
--- trunk/sys/arm/ti/twl/twl_clks.c	                        (rev 0)
+++ trunk/sys/arm/ti/twl/twl_clks.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,675 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012
+ *	Ben Gray <bgray at freebsd.org>.
+ * 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 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 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: stable/10/sys/arm/ti/twl/twl_clks.c 259329 2013-12-13 20:43:11Z ian $");
+
+/*
+ * Texas Instruments TWL4030/TWL5030/TWL60x0/TPS659x0 Power Management.
+ *
+ * This driver covers the external clocks, allows for enabling &
+ * disabling their output.
+ *
+ *
+ *
+ * FLATTENED DEVICE TREE (FDT)
+ * Startup override settings can be specified in the FDT, if they are they
+ * should be under the twl parent device and take the following form:
+ *
+ *    external-clocks = "name1", "state1",
+ *                      "name2", "state2",
+ *                      etc;
+ *
+ * Each override should be a pair, the first entry is the name of the clock
+ * the second is the state to set, possible strings are either "on" or "off".
+ *
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+#include <sys/sysctl.h>
+#include <sys/sx.h>
+#include <sys/malloc.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+#include <machine/resource.h>
+#include <machine/intr.h>
+
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+
+#include "twl.h"
+#include "twl_clks.h"
+
+
+static int twl_clks_debug = 1;
+
+
+/*
+ * Power Groups bits for the 4030 and 6030 devices
+ */
+#define TWL4030_P3_GRP		0x80	/* Peripherals, power group */
+#define TWL4030_P2_GRP		0x40	/* Modem power group */
+#define TWL4030_P1_GRP		0x20	/* Application power group (FreeBSD control) */
+
+#define TWL6030_P3_GRP		0x04	/* Modem power group */
+#define TWL6030_P2_GRP		0x02	/* Connectivity power group */
+#define TWL6030_P1_GRP		0x01	/* Application power group (FreeBSD control) */
+
+/*
+ * Register offsets within a clk regulator register set
+ */
+#define TWL_CLKS_GRP		0x00	/* Regulator GRP register */
+#define TWL_CLKS_STATE		0x02	/* TWL6030 only */
+
+
+
+/**
+ *  Support voltage regulators for the different IC's
+ */
+struct twl_clock {
+	const char	*name;
+	uint8_t		subdev;
+	uint8_t		regbase;
+};
+
+static const struct twl_clock twl4030_clocks[] = {
+	{ "32kclkout", 0, 0x8e },
+	{ NULL, 0, 0x00 } 
+};
+
+static const struct twl_clock twl6030_clocks[] = {
+	{ "clk32kg",     0, 0xbc },
+	{ "clk32kao",    0, 0xb9 },
+	{ "clk32kaudio", 0, 0xbf },
+	{ NULL, 0, 0x00 } 
+};
+
+#define TWL_CLKS_MAX_NAMELEN  32
+
+struct twl_clk_entry {
+	LIST_ENTRY(twl_clk_entry) link;
+	struct sysctl_oid *oid;
+	char		       name[TWL_CLKS_MAX_NAMELEN];
+	uint8_t            sub_dev;  /* the sub-device number for the clock */
+	uint8_t            reg_off;  /* register base address of the clock */
+};
+
+struct twl_clks_softc {
+	device_t           sc_dev;   /* twl_clk device */
+	device_t           sc_pdev;  /* parent device (twl) */
+	struct sx          sc_sx;    /* internal locking */
+	struct intr_config_hook sc_init_hook;
+	LIST_HEAD(twl_clk_list, twl_clk_entry) sc_clks_list;
+};
+
+/**
+ *	Macros for driver shared locking
+ */
+#define TWL_CLKS_XLOCK(_sc)			sx_xlock(&(_sc)->sc_sx)
+#define	TWL_CLKS_XUNLOCK(_sc)		sx_xunlock(&(_sc)->sc_sx)
+#define TWL_CLKS_SLOCK(_sc)			sx_slock(&(_sc)->sc_sx)
+#define	TWL_CLKS_SUNLOCK(_sc)		sx_sunlock(&(_sc)->sc_sx)
+#define TWL_CLKS_LOCK_INIT(_sc)		sx_init(&(_sc)->sc_sx, "twl_clks")
+#define TWL_CLKS_LOCK_DESTROY(_sc)	sx_destroy(&(_sc)->sc_sx);
+
+#define TWL_CLKS_ASSERT_LOCKED(_sc)	sx_assert(&(_sc)->sc_sx, SA_LOCKED);
+
+#define TWL_CLKS_LOCK_UPGRADE(_sc)               \
+	do {                                         \
+		while (!sx_try_upgrade(&(_sc)->sc_sx))   \
+			pause("twl_clks_ex", (hz / 100));    \
+	} while(0)
+#define TWL_CLKS_LOCK_DOWNGRADE(_sc)	sx_downgrade(&(_sc)->sc_sx);
+
+
+
+
+/**
+ *	twl_clks_read_1 - read single register from the TWL device
+ *	twl_clks_write_1 - writes a single register in the TWL device
+ *	@sc: device context
+ *	@clk: the clock device we're reading from / writing to
+ *	@off: offset within the clock's register set
+ *	@val: the value to write or a pointer to a variable to store the result
+ *
+ *	RETURNS:
+ *	Zero on success or an error code on failure.
+ */
+static inline int
+twl_clks_read_1(struct twl_clks_softc *sc, struct twl_clk_entry *clk,
+	uint8_t off, uint8_t *val)
+{
+	return (twl_read(sc->sc_pdev, clk->sub_dev, clk->reg_off + off, val, 1));
+}
+
+static inline int
+twl_clks_write_1(struct twl_clks_softc *sc, struct twl_clk_entry *clk,
+	uint8_t off, uint8_t val)
+{
+	return (twl_write(sc->sc_pdev, clk->sub_dev, clk->reg_off + off, &val, 1));
+}
+
+
+/**
+ *	twl_clks_is_enabled - determines if a clock is enabled
+ *	@dev: TWL CLK device
+ *	@name: the name of the clock
+ *	@enabled: upon return will contain the 'enabled' state
+ *
+ *	LOCKING:
+ *	Internally the function takes and releases the TWL lock.
+ *
+ *	RETURNS:
+ *	Zero on success or a negative error code on failure.
+ */
+int
+twl_clks_is_enabled(device_t dev, const char *name, int *enabled)
+{
+	struct twl_clks_softc *sc = device_get_softc(dev);
+	struct twl_clk_entry *clk;
+	int found = 0;
+	int err;
+	uint8_t grp, state;
+
+	TWL_CLKS_SLOCK(sc);
+
+	LIST_FOREACH(clk, &sc->sc_clks_list, link) {
+		if (strcmp(clk->name, name) == 0) {
+			found = 1;
+			break;
+		}
+	}
+
+	if (!found) {
+		TWL_CLKS_SUNLOCK(sc);
+		return (EINVAL);
+	}
+
+
+	if (twl_is_4030(sc->sc_pdev)) {
+
+		err = twl_clks_read_1(sc, clk, TWL_CLKS_GRP, &grp);
+		if (!err)
+			*enabled = (grp & TWL4030_P1_GRP);
+
+	} else if (twl_is_6030(sc->sc_pdev) || twl_is_6025(sc->sc_pdev)) {
+
+		TWL_CLKS_LOCK_UPGRADE(sc);
+
+		/* Check the clock is in the application group */
+		if (twl_is_6030(sc->sc_pdev)) {
+			err = twl_clks_read_1(sc, clk, TWL_CLKS_GRP, &grp);
+			if (err) {
+				TWL_CLKS_LOCK_DOWNGRADE(sc);
+				goto done;
+			}
+			
+			if (!(grp & TWL6030_P1_GRP)) {
+				TWL_CLKS_LOCK_DOWNGRADE(sc);
+				*enabled = 0; /* disabled */
+				goto done;
+			}
+		}
+
+		/* Read the application mode state and verify it's ON */
+		err = twl_clks_read_1(sc, clk, TWL_CLKS_STATE, &state);
+		if (!err)
+			*enabled = ((state & 0x0C) == 0x04);
+			
+		TWL_CLKS_LOCK_DOWNGRADE(sc);
+
+	} else {
+		err = EINVAL;
+	}
+
+done:
+	TWL_CLKS_SUNLOCK(sc);
+	return (err);
+}
+
+
+/**
+ *	twl_clks_set_state - enables/disables a clock output
+ *	@sc: device context
+ *	@clk: the clock entry to enable/disable
+ *	@enable: non-zero the clock is enabled, zero the clock is disabled
+ *
+ *	LOCKING:
+ *	The TWL CLK lock must be held before this function is called.
+ *
+ *	RETURNS:
+ *	Zero on success or an error code on failure.
+ */
+static int
+twl_clks_set_state(struct twl_clks_softc *sc, struct twl_clk_entry *clk,
+	int enable)
+{
+	int xlocked;
+	int err;
+	uint8_t grp;
+
+	TWL_CLKS_ASSERT_LOCKED(sc);
+
+	/* Upgrade the lock to exclusive because about to perform read-mod-write */
+	xlocked = sx_xlocked(&sc->sc_sx);
+	if (!xlocked)
+		TWL_CLKS_LOCK_UPGRADE(sc);
+
+	err = twl_clks_read_1(sc, clk, TWL_CLKS_GRP, &grp);
+	if (err)
+		goto done;
+
+	if (twl_is_4030(sc->sc_pdev)) {
+
+		/* On the TWL4030 we just need to ensure the clock is in the right
+		 * power domain, don't need to turn on explicitly like TWL6030.
+		 */
+		if (enable)
+			grp |= TWL4030_P1_GRP;
+		else
+			grp &= ~(TWL4030_P1_GRP | TWL4030_P2_GRP | TWL4030_P3_GRP);
+		
+		err = twl_clks_write_1(sc, clk, TWL_CLKS_GRP, grp);
+
+	} else if (twl_is_6030(sc->sc_pdev) || twl_is_6025(sc->sc_pdev)) {
+
+		/* Make sure the clock belongs to at least the APP power group */
+		if (twl_is_6030(sc->sc_pdev) && !(grp & TWL6030_P1_GRP)) {
+			grp |= TWL6030_P1_GRP;
+			err = twl_clks_write_1(sc, clk, TWL_CLKS_GRP, grp);
+			if (err)
+				goto done;
+		}
+
+		/* On TWL6030 we need to make sure we disable power for all groups */
+		if (twl_is_6030(sc->sc_pdev))
+			grp = TWL6030_P1_GRP | TWL6030_P2_GRP | TWL6030_P3_GRP;
+		else
+			grp = 0x00;
+
+		/* Set the state of the clock */
+		if (enable)
+			err = twl_clks_write_1(sc, clk, TWL_CLKS_STATE, (grp << 5) | 0x01);
+		else
+			err = twl_clks_write_1(sc, clk, TWL_CLKS_STATE, (grp << 5));
+
+	} else {
+		
+		err = EINVAL;
+	}
+
+done:
+	if (!xlocked)
+		TWL_CLKS_LOCK_DOWNGRADE(sc);
+
+	if ((twl_clks_debug > 1) && !err)
+		device_printf(sc->sc_dev, "%s : %sabled\n", clk->name,
+			enable ? "en" : "dis");
+
+	return (err);
+}
+
+
+/**
+ *	twl_clks_disable - disables a clock output
+ *	@dev: TWL clk device
+*	@name: the name of the clock
+ *
+ *	LOCKING:
+ *	Internally the function takes and releases the TWL lock.
+ *
+ *	RETURNS:
+*	Zero on success or an error code on failure.
+ */
+int
+twl_clks_disable(device_t dev, const char *name)
+{
+	struct twl_clks_softc *sc = device_get_softc(dev);
+	struct twl_clk_entry *clk;
+	int err = EINVAL;
+
+	TWL_CLKS_SLOCK(sc);
+
+	LIST_FOREACH(clk, &sc->sc_clks_list, link) {
+		if (strcmp(clk->name, name) == 0) {
+			err = twl_clks_set_state(sc, clk, 0);
+			break;
+		}
+	}
+	
+	TWL_CLKS_SUNLOCK(sc);
+	return (err);
+}
+
+/**
+ *	twl_clks_enable - enables a clock output
+ *	@dev: TWL clk device
+ *	@name: the name of the clock
+ *
+ *	LOCKING:
+ *	Internally the function takes and releases the TWL CLKS lock.
+ *
+ *	RETURNS:
+ *	Zero on success or an error code on failure.
+ */
+int
+twl_clks_enable(device_t dev, const char *name)
+{
+	struct twl_clks_softc *sc = device_get_softc(dev);
+	struct twl_clk_entry *clk;
+	int err = EINVAL;
+
+	TWL_CLKS_SLOCK(sc);
+
+	LIST_FOREACH(clk, &sc->sc_clks_list, link) {
+		if (strcmp(clk->name, name) == 0) {
+			err = twl_clks_set_state(sc, clk, 1);
+			break;
+		}
+	}
+	
+	TWL_CLKS_SUNLOCK(sc);
+	return (err);
+}
+
+/**
+ *	twl_clks_sysctl_clock - reads the state of the clock
+ *	@SYSCTL_HANDLER_ARGS: arguments for the callback
+ *
+ *	Returns the clock status; disabled is zero and enabled is non-zero.
+ *
+ *	LOCKING:
+ *	It's expected the TWL lock is held while this function is called.
+ *
+ *	RETURNS:
+ *	EIO if device is not present, otherwise 0 is returned.
+ */
+static int
+twl_clks_sysctl_clock(SYSCTL_HANDLER_ARGS)
+{
+	struct twl_clks_softc *sc = (struct twl_clks_softc*)arg1;
+	int err;
+	int enabled = 0;
+
+	if ((err = twl_clks_is_enabled(sc->sc_dev, oidp->oid_name, &enabled)) != 0)
+		return err;
+	
+	return sysctl_handle_int(oidp, &enabled, 0, req);
+}
+
+/**
+ *	twl_clks_add_clock - adds single clock sysctls for the device
+ *	@sc: device soft context
+ *	@name: the name of the regulator
+ *	@nsub: the number of the subdevice
+ *	@regbase: the base address of the clocks registers
+ *
+ *	Adds a single clock to the device and also a sysctl interface for 
+ *	querying it's status.
+ *
+ *	LOCKING:
+ *	It's expected the exclusive lock is held while this function is called.
+ *
+ *	RETURNS:
+ *	Pointer to the new clock entry on success, otherwise NULL on failure.
+ */
+static struct twl_clk_entry*
+twl_clks_add_clock(struct twl_clks_softc *sc, const char *name,
+	uint8_t nsub, uint8_t regbase)
+{
+	struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev);
+	struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev);
+	struct twl_clk_entry *new;
+
+	TWL_CLKS_ASSERT_LOCKED(sc);
+
+	new = malloc(sizeof(struct twl_clk_entry), M_DEVBUF, M_NOWAIT | M_ZERO);
+	if (new == NULL)
+		return (NULL);
+
+
+	strncpy(new->name, name, TWL_CLKS_MAX_NAMELEN);
+	new->name[TWL_CLKS_MAX_NAMELEN - 1] = '\0';
+
+	new->sub_dev = nsub;
+	new->reg_off = regbase;
+
+
+
+	/* Add a sysctl entry for the clock */
+	new->oid = SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, name,
+	    CTLTYPE_INT | CTLFLAG_RD, sc, 0,
+	    twl_clks_sysctl_clock, "I", "external clock");
+
+	/* Finally add the regulator to list of supported regulators */
+	LIST_INSERT_HEAD(&sc->sc_clks_list, new, link);
+
+	return (new);
+}
+
+/**
+ *	twl_clks_add_clocks - populates the internal list of clocks
+ *	@sc: device soft context
+ *	@chip: the name of the chip used in the hints
+ *	@clks the list of clocks supported by the device
+ *
+ *	Loops over the list of clocks and adds them to the device context. Also
+ *	scans the FDT to determine if there are any clocks that should be
+ *	enabled/disabled automatically.
+ *
+ *	LOCKING:
+ *	Internally takes the exclusive lock while adding the clocks to the
+ *	device context.
+ *
+ *	RETURNS:
+ *	Always returns 0.
+ */
+static int
+twl_clks_add_clocks(struct twl_clks_softc *sc, const struct twl_clock *clks)
+{
+	int err;
+	const struct twl_clock *walker;
+	struct twl_clk_entry *entry;
+	phandle_t child;
+	char rnames[256];
+	char *name, *state;
+	int len = 0, prop_len;
+	int enable;
+
+
+	TWL_CLKS_XLOCK(sc);
+
+	/* Add the regulators from the list */
+	walker = &clks[0];
+	while (walker->name != NULL) {
+
+		/* Add the regulator to the list */
+		entry = twl_clks_add_clock(sc, walker->name, walker->subdev,
+		    walker->regbase);
+		if (entry == NULL)
+			continue;
+
+		walker++;
+	}
+
+	/* Check for any FDT settings that need to be applied */
+	child = ofw_bus_get_node(sc->sc_pdev);
+	if (child) {
+
+		prop_len = OF_getprop(child, "external-clocks", rnames, sizeof(rnames));
+		while (len < prop_len) {
+			name = rnames + len;
+			len += strlen(name) + 1;
+			if ((len >= prop_len) || (name[0] == '\0'))
+				break;
+			
+			state = rnames + len;
+			len += strlen(state) + 1;
+			if (state[0] == '\0')
+				break;
+			
+			enable = !strncmp(state, "on", 2);
+			
+			LIST_FOREACH(entry, &sc->sc_clks_list, link) {
+				if (strcmp(entry->name, name) == 0) {
+					twl_clks_set_state(sc, entry, enable);
+					break;
+				}
+			}
+		}
+	}
+	
+	TWL_CLKS_XUNLOCK(sc);
+
+	
+	if (twl_clks_debug) {
+		LIST_FOREACH(entry, &sc->sc_clks_list, link) {
+			err = twl_clks_is_enabled(sc->sc_dev, entry->name, &enable);
+			if (!err)
+				device_printf(sc->sc_dev, "%s : %s\n", entry->name,
+					enable ? "on" : "off");
+		}
+	}
+
+	return (0);
+}
+
+/**
+ *	twl_clks_init - initialises the list of clocks
+ *	@dev: the twl_clks device
+ *
+ *	This function is called as an intrhook once interrupts have been enabled,
+ *	this is done so that the driver has the option to enable/disable a clock
+ *	based on settings providied in the FDT.
+ *
+ *	LOCKING:
+ *	May takes the exclusive lock in the function.
+ */
+static void
+twl_clks_init(void *dev)
+{
+	struct twl_clks_softc *sc;
+
+	sc = device_get_softc((device_t)dev);
+
+	if (twl_is_4030(sc->sc_pdev))
+		twl_clks_add_clocks(sc, twl4030_clocks);
+	else if (twl_is_6030(sc->sc_pdev) || twl_is_6025(sc->sc_pdev))
+		twl_clks_add_clocks(sc, twl6030_clocks);
+
+	config_intrhook_disestablish(&sc->sc_init_hook);
+}
+
+static int
+twl_clks_probe(device_t dev)
+{
+	if (twl_is_4030(device_get_parent(dev)))
+		device_set_desc(dev, "TI TWL4030 PMIC External Clocks");
+	else if (twl_is_6025(device_get_parent(dev)) ||
+	         twl_is_6030(device_get_parent(dev)))
+		device_set_desc(dev, "TI TWL6025/TWL6030 PMIC External Clocks");
+	else
+		return (ENXIO);
+
+	return (0);
+}
+
+static int
+twl_clks_attach(device_t dev)
+{
+	struct twl_clks_softc *sc;
+
+	sc = device_get_softc(dev);
+	sc->sc_dev = dev;
+	sc->sc_pdev = device_get_parent(dev);
+
+	TWL_CLKS_LOCK_INIT(sc);
+
+	LIST_INIT(&sc->sc_clks_list);
+
+
+	sc->sc_init_hook.ich_func = twl_clks_init;
+	sc->sc_init_hook.ich_arg = dev;
+
+	if (config_intrhook_establish(&sc->sc_init_hook) != 0)
+		return (ENOMEM);
+
+	return (0);
+}
+
+static int
+twl_clks_detach(device_t dev)
+{
+	struct twl_clks_softc *sc;
+	struct twl_clk_entry *clk;
+	struct twl_clk_entry *tmp;
+
+	sc = device_get_softc(dev);
+
+	TWL_CLKS_XLOCK(sc);
+
+	LIST_FOREACH_SAFE(clk, &sc->sc_clks_list, link, tmp) {
+		LIST_REMOVE(clk, link);
+		sysctl_remove_oid(clk->oid, 1, 0);
+		free(clk, M_DEVBUF);
+	}
+
+	TWL_CLKS_XUNLOCK(sc);
+
+	TWL_CLKS_LOCK_DESTROY(sc);
+
+	return (0);
+}
+
+static device_method_t twl_clks_methods[] = {
+	DEVMETHOD(device_probe,		twl_clks_probe),
+	DEVMETHOD(device_attach,	twl_clks_attach),
+	DEVMETHOD(device_detach,	twl_clks_detach),
+
+	{0, 0},
+};
+
+static driver_t twl_clks_driver = {
+	"twl_clks",
+	twl_clks_methods,
+	sizeof(struct twl_clks_softc),
+};
+
+static devclass_t twl_clks_devclass;
+
+DRIVER_MODULE(twl_clks, twl, twl_clks_driver, twl_clks_devclass, 0, 0);
+MODULE_VERSION(twl_clks, 1);


Property changes on: trunk/sys/arm/ti/twl/twl_clks.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/twl/twl_clks.h
===================================================================
--- trunk/sys/arm/ti/twl/twl_clks.h	                        (rev 0)
+++ trunk/sys/arm/ti/twl/twl_clks.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,39 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012
+ *	Ben Gray <bgray at freebsd.org>.
+ * 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 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 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: stable/10/sys/arm/ti/twl/twl_clks.h 239281 2012-08-15 06:31:32Z gonzo $
+ */
+#ifndef _TWL_CLKS_H_
+#define _TWL_CLKS_H_
+
+
+int twl_clks_enable(device_t dev, const char *name);
+int twl_clks_disable(device_t dev, const char *name);
+int twl_clks_is_enabled(device_t dev, const char *name, int *enabled);
+
+
+#endif /* _TWL_CLKS_H_ */


Property changes on: trunk/sys/arm/ti/twl/twl_clks.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/twl/twl_vreg.c
===================================================================
--- trunk/sys/arm/ti/twl/twl_vreg.c	                        (rev 0)
+++ trunk/sys/arm/ti/twl/twl_vreg.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,1055 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2011
+ *	Ben Gray <ben.r.gray at gmail.com>.
+ * 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 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 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: stable/10/sys/arm/ti/twl/twl_vreg.c 263456 2014-03-21 00:19:20Z dim $");
+
+/*
+ * Texas Instruments TWL4030/TWL5030/TWL60x0/TPS659x0 Power Management.
+ *
+ * This driver covers the voltages regulators (LDO), allows for enabling &
+ * disabling the voltage output and adjusting the voltage level.
+ *
+ * Voltage regulators can belong to different power groups, in this driver we
+ * put the regulators under our control in the "Application power group".
+ *
+ *
+ * FLATTENED DEVICE TREE (FDT)
+ * Startup override settings can be specified in the FDT, if they are they
+ * should be under the twl parent device and take the following form:
+ *
+ *    voltage-regulators = "name1", "millivolts1",
+ *                         "name2", "millivolts2";
+ *
+ * Each override should be a pair, the first entry is the name of the regulator
+ * the second is the voltage (in millivolts) to set for the given regulator.
+ *
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+#include <sys/sysctl.h>
+#include <sys/sx.h>
+#include <sys/malloc.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+#include <machine/resource.h>
+#include <machine/intr.h>
+
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+
+#include "twl.h"
+#include "twl_vreg.h"
+
+static int twl_vreg_debug = 1;
+
+
+/*
+ * Power Groups bits for the 4030 and 6030 devices
+ */
+#define TWL4030_P3_GRP		0x80	/* Peripherals, power group */
+#define TWL4030_P2_GRP		0x40	/* Modem power group */
+#define TWL4030_P1_GRP		0x20	/* Application power group (FreeBSD control) */
+
+#define TWL6030_P3_GRP		0x04	/* Modem power group */
+#define TWL6030_P2_GRP		0x02	/* Connectivity power group */
+#define TWL6030_P1_GRP		0x01	/* Application power group (FreeBSD control) */
+
+/*
+ * Register offsets within a LDO regulator register set
+ */
+#define TWL_VREG_GRP		0x00	/* Regulator GRP register */
+#define TWL_VREG_STATE		0x02
+#define TWL_VREG_VSEL		0x03	/* Voltage select register */
+
+#define UNDF  0xFFFF
+
+static const uint16_t twl6030_voltages[] = {
+	0000, 1000, 1100, 1200, 1300, 1400, 1500, 1600,
+	1700, 1800, 1900, 2000, 2100, 2200, 2300, 2400,
+	2500, 2600, 2700, 2800, 2900, 3000, 3100, 3200,
+	3300, UNDF, UNDF, UNDF, UNDF, UNDF, UNDF, 2750
+};
+
+static const uint16_t twl4030_vaux1_voltages[] = {
+	1500, 1800, 2500, 2800, 3000, 3000, 3000, 3000
+};
+static const uint16_t twl4030_vaux2_voltages[] = {
+	1700, 1700, 1900, 1300, 1500, 1800, 2000, 2500,
+	2100, 2800, 2200, 2300, 2400, 2400, 2400, 2400
+};
+static const uint16_t twl4030_vaux3_voltages[] = {
+	1500, 1800, 2500, 2800, 3000, 3000, 3000, 3000
+};
+static const uint16_t twl4030_vaux4_voltages[] = {
+	700,  1000, 1200, 1300, 1500, 1800, 1850, 2500,
+	2600, 2800, 2850, 3000, 3150, 3150, 3150, 3150
+};
+static const uint16_t twl4030_vmmc1_voltages[] = {
+	1850, 2850, 3000, 3150
+};
+static const uint16_t twl4030_vmmc2_voltages[] = {
+	1000, 1000, 1200, 1300, 1500, 1800, 1850, 2500,
+	2600, 2800, 2850, 3000, 3150, 3150, 3150, 3150
+};
+static const uint16_t twl4030_vpll1_voltages[] = {
+	1000, 1200, 1300, 1800, 2800, 3000, 3000, 3000
+};
+static const uint16_t twl4030_vpll2_voltages[] = {
+	700,  1000, 1200, 1300, 1500, 1800, 1850, 2500,
+	2600, 2800, 2850, 3000, 3150, 3150, 3150, 3150
+};
+static const uint16_t twl4030_vsim_voltages[] = {
+	1000, 1200, 1300, 1800, 2800, 3000, 3000, 3000
+};
+static const uint16_t twl4030_vdac_voltages[] = {
+	1200, 1300, 1800, 1800
+};
+#if 0 /* vdd1, vdd2, vdio, not currently used. */
+static const uint16_t twl4030_vdd1_voltages[] = {
+	800, 1450
+};
+static const uint16_t twl4030_vdd2_voltages[] = {
+	800, 1450, 1500
+};
+static const uint16_t twl4030_vio_voltages[] = {
+	1800, 1850
+};
+#endif
+static const uint16_t twl4030_vintana2_voltages[] = {
+	2500, 2750
+};
+
+/**
+ *  Support voltage regulators for the different IC's
+ */
+struct twl_regulator {
+	const char	*name;
+	uint8_t		subdev;
+	uint8_t		regbase;
+
+	uint16_t	fixedvoltage;
+
+	const uint16_t	*voltages;
+	uint32_t	num_voltages;
+};
+
+#define TWL_REGULATOR_ADJUSTABLE(name, subdev, reg, voltages) \
+	{ name, subdev, reg, 0, voltages, (sizeof(voltages)/sizeof(voltages[0])) }
+#define TWL_REGULATOR_FIXED(name, subdev, reg, voltage) \
+	{ name, subdev, reg, voltage, NULL, 0 }
+
+static const struct twl_regulator twl4030_regulators[] = {
+	TWL_REGULATOR_ADJUSTABLE("vaux1",    0, 0x17, twl4030_vaux1_voltages),
+	TWL_REGULATOR_ADJUSTABLE("vaux2",    0, 0x1B, twl4030_vaux2_voltages),
+	TWL_REGULATOR_ADJUSTABLE("vaux3",    0, 0x1F, twl4030_vaux3_voltages),
+	TWL_REGULATOR_ADJUSTABLE("vaux4",    0, 0x23, twl4030_vaux4_voltages),
+	TWL_REGULATOR_ADJUSTABLE("vmmc1",    0, 0x27, twl4030_vmmc1_voltages),
+	TWL_REGULATOR_ADJUSTABLE("vmmc2",    0, 0x2B, twl4030_vmmc2_voltages),
+	TWL_REGULATOR_ADJUSTABLE("vpll1",    0, 0x2F, twl4030_vpll1_voltages),
+	TWL_REGULATOR_ADJUSTABLE("vpll2",    0, 0x33, twl4030_vpll2_voltages),
+	TWL_REGULATOR_ADJUSTABLE("vsim",     0, 0x37, twl4030_vsim_voltages),
+	TWL_REGULATOR_ADJUSTABLE("vdac",     0, 0x3B, twl4030_vdac_voltages),
+	TWL_REGULATOR_ADJUSTABLE("vintana2", 0, 0x43, twl4030_vintana2_voltages),
+	TWL_REGULATOR_FIXED("vintana1", 0, 0x3F, 1500),
+	TWL_REGULATOR_FIXED("vintdig",  0, 0x47, 1500),
+	TWL_REGULATOR_FIXED("vusb1v5",  0, 0x71, 1500),
+	TWL_REGULATOR_FIXED("vusb1v8",  0, 0x74, 1800),
+	TWL_REGULATOR_FIXED("vusb3v1",  0, 0x77, 3100),
+	{ NULL, 0, 0x00, 0, NULL, 0 }
+};
+
+static const struct twl_regulator twl6030_regulators[] = {
+	TWL_REGULATOR_ADJUSTABLE("vaux1", 0, 0x84, twl6030_voltages),
+	TWL_REGULATOR_ADJUSTABLE("vaux2", 0, 0x89, twl6030_voltages),
+	TWL_REGULATOR_ADJUSTABLE("vaux3", 0, 0x8C, twl6030_voltages),
+	TWL_REGULATOR_ADJUSTABLE("vmmc",  0, 0x98, twl6030_voltages),
+	TWL_REGULATOR_ADJUSTABLE("vpp",   0, 0x9C, twl6030_voltages),
+	TWL_REGULATOR_ADJUSTABLE("vusim", 0, 0xA4, twl6030_voltages),
+	TWL_REGULATOR_FIXED("vmem",  0, 0x64, 1800),
+	TWL_REGULATOR_FIXED("vusb",  0, 0xA0, 3300),
+	TWL_REGULATOR_FIXED("v1v8",  0, 0x46, 1800),
+	TWL_REGULATOR_FIXED("v2v1",  0, 0x4C, 2100),
+	TWL_REGULATOR_FIXED("v1v29", 0, 0x40, 1290),
+	TWL_REGULATOR_FIXED("vcxio", 0, 0x90, 1800),
+	TWL_REGULATOR_FIXED("vdac",  0, 0x94, 1800),
+	TWL_REGULATOR_FIXED("vana",  0, 0x80, 2100),
+	{ NULL, 0, 0x00, 0, NULL, 0 } 
+};
+
+#define TWL_VREG_MAX_NAMELEN  32
+
+struct twl_regulator_entry {
+	LIST_ENTRY(twl_regulator_entry) entries;
+	char                 name[TWL_VREG_MAX_NAMELEN];
+	struct sysctl_oid   *oid;
+	uint8_t          sub_dev;           /* TWL sub-device group */
+	uint8_t          reg_off;           /* base register offset for the LDO */
+	uint16_t         fixed_voltage;	    /* the (milli)voltage if LDO is fixed */ 
+	const uint16_t  *supp_voltages;     /* pointer to an array of possible voltages */
+	uint32_t         num_supp_voltages; /* the number of supplied voltages */
+};
+
+struct twl_vreg_softc {
+	device_t        sc_dev;
+	device_t        sc_pdev;
+	struct sx       sc_sx;
+
+	struct intr_config_hook sc_init_hook;
+	LIST_HEAD(twl_regulator_list, twl_regulator_entry) sc_vreg_list;
+};
+
+
+#define TWL_VREG_XLOCK(_sc)			sx_xlock(&(_sc)->sc_sx)
+#define	TWL_VREG_XUNLOCK(_sc)		sx_xunlock(&(_sc)->sc_sx)
+#define TWL_VREG_SLOCK(_sc)			sx_slock(&(_sc)->sc_sx)
+#define	TWL_VREG_SUNLOCK(_sc)		sx_sunlock(&(_sc)->sc_sx)
+#define TWL_VREG_LOCK_INIT(_sc)		sx_init(&(_sc)->sc_sx, "twl_vreg")
+#define TWL_VREG_LOCK_DESTROY(_sc)	sx_destroy(&(_sc)->sc_sx);
+
+#define TWL_VREG_ASSERT_LOCKED(_sc)	sx_assert(&(_sc)->sc_sx, SA_LOCKED);
+
+#define TWL_VREG_LOCK_UPGRADE(_sc)               \
+	do {                                         \
+		while (!sx_try_upgrade(&(_sc)->sc_sx))   \
+			pause("twl_vreg_ex", (hz / 100));    \
+	} while(0)
+#define TWL_VREG_LOCK_DOWNGRADE(_sc)	sx_downgrade(&(_sc)->sc_sx);
+
+
+
+
+/**
+ *	twl_vreg_read_1 - read single register from the TWL device
+ *	twl_vreg_write_1 - write a single register in the TWL device
+ *	@sc: device context
+ *	@clk: the clock device we're reading from / writing to
+ *	@off: offset within the clock's register set
+ *	@val: the value to write or a pointer to a variable to store the result
+ *
+ *	RETURNS:
+ *	Zero on success or an error code on failure.
+ */
+static inline int
+twl_vreg_read_1(struct twl_vreg_softc *sc, struct twl_regulator_entry *regulator,
+	uint8_t off, uint8_t *val)
+{
+	return (twl_read(sc->sc_pdev, regulator->sub_dev, 
+	    regulator->reg_off + off, val, 1));
+}
+
+static inline int
+twl_vreg_write_1(struct twl_vreg_softc *sc, struct twl_regulator_entry *regulator,
+	uint8_t off, uint8_t val)
+{
+	return (twl_write(sc->sc_pdev, regulator->sub_dev,
+	    regulator->reg_off + off, &val, 1));
+}
+
+/**
+ *	twl_millivolt_to_vsel - gets the vsel bit value to write into the register
+ *	                        for a desired voltage and regulator
+ *	@sc: the device soft context
+ *	@regulator: pointer to the regulator device
+ *	@millivolts: the millivolts to find the bit value for
+ *	@vsel: upon return will contain the corresponding register value
+ *
+ *	Accepts a (milli)voltage value and tries to find the closest match to the
+ *	actual supported voltages for the given regulator.  If a match is found
+ *	within 100mv of the target, @vsel is written with the match and 0 is
+ *	returned. If no voltage match is found the function returns an non-zero
+ *	value.
+ *
+ *	RETURNS:
+ *	Zero on success or an error code on failure.
+ */
+static int
+twl_vreg_millivolt_to_vsel(struct twl_vreg_softc *sc,
+	struct twl_regulator_entry *regulator, int millivolts, uint8_t *vsel)
+{
+	int delta, smallest_delta;
+	unsigned i, closest_idx;
+
+	TWL_VREG_ASSERT_LOCKED(sc);
+
+	if (regulator->supp_voltages == NULL)
+		return (EINVAL);
+
+	/* Loop over the support voltages and try and find the closest match */
+	closest_idx = 0;
+	smallest_delta = 0x7fffffff;
+	for (i = 0; i < regulator->num_supp_voltages; i++) {
+
+		/* Ignore undefined values */
+		if (regulator->supp_voltages[i] == UNDF)
+			continue;
+
+		/* Calculate the difference */
+		delta = millivolts - (int)regulator->supp_voltages[i];
+		if (abs(delta) < smallest_delta) {
+			smallest_delta = abs(delta);
+			closest_idx = i;
+		}
+	}
+
+	/* Check we got a voltage that was within 100mv of the actual target, this
+	 * is just a value I picked out of thin air.
+	 */
+	if ((smallest_delta > 100) && (closest_idx < 0x100))
+		return (EINVAL);
+
+	*vsel = closest_idx;
+	return (0);
+}
+
+/**
+ *	twl_vreg_is_regulator_enabled - returns the enabled status of the regulator
+ *	@sc: the device soft context
+ *	@regulator: pointer to the regulator device
+ *	@enabled: stores the enabled status, zero disabled, non-zero enabled
+ *
+ *	LOCKING:
+ *	On entry expects the TWL VREG lock to be held. Will upgrade the lock to
+ *	exclusive if not already but, if so, it will be downgraded again before
+ *	returning.
+ *
+ *	RETURNS:
+ *	Zero on success or an error code on failure.
+ */
+static int
+twl_vreg_is_regulator_enabled(struct twl_vreg_softc *sc,
+	struct twl_regulator_entry *regulator, int *enabled)
+{
+	int err;
+	uint8_t grp;
+	uint8_t state;
+	int xlocked;
+	
+	if (enabled == NULL)
+		return (EINVAL);
+
+	TWL_VREG_ASSERT_LOCKED(sc);
+
+	xlocked = sx_xlocked(&sc->sc_sx);
+	if (!xlocked)
+		TWL_VREG_LOCK_UPGRADE(sc);
+
+	/* The status reading is different for the different devices */
+	if (twl_is_4030(sc->sc_pdev)) {
+
+		err = twl_vreg_read_1(sc, regulator, TWL_VREG_GRP, &state);
+		if (err)
+			goto done;
+
+		*enabled = (state & TWL4030_P1_GRP);
+
+	} else if (twl_is_6030(sc->sc_pdev) || twl_is_6025(sc->sc_pdev)) {
+
+		/* Check the regulator is in the application group */
+		if (twl_is_6030(sc->sc_pdev)) {
+			err = twl_vreg_read_1(sc, regulator, TWL_VREG_GRP, &grp);
+			if (err)
+				goto done;
+
+			if (!(grp & TWL6030_P1_GRP)) {
+				*enabled = 0; /* disabled */
+				goto done;
+			}
+		}
+
+		/* Read the application mode state and verify it's ON */
+		err = twl_vreg_read_1(sc, regulator, TWL_VREG_STATE, &state);
+		if (err)
+			goto done;
+
+		*enabled = ((state & 0x0C) == 0x04);
+
+	} else {
+		err = EINVAL;
+	}
+
+done:
+	if (!xlocked)
+		TWL_VREG_LOCK_DOWNGRADE(sc);
+
+	return (err);
+}
+
+/**
+ *	twl_vreg_disable_regulator - disables a voltage regulator
+ *	@sc: the device soft context
+ *	@regulator: pointer to the regulator device
+ *
+ *	Disables the regulator which will stop the output drivers.
+ *
+ *	LOCKING:
+ *	On entry expects the TWL VREG lock to be held. Will upgrade the lock to
+ *	exclusive if not already but, if so, it will be downgraded again before
+ *	returning.
+ *
+ *	RETURNS:
+ *	Zero on success or a positive error code on failure.
+ */
+static int
+twl_vreg_disable_regulator(struct twl_vreg_softc *sc,
+	struct twl_regulator_entry *regulator)
+{
+	int err = 0;
+	uint8_t grp;
+	int xlocked;
+
+	TWL_VREG_ASSERT_LOCKED(sc);
+
+	xlocked = sx_xlocked(&sc->sc_sx);
+	if (!xlocked)
+		TWL_VREG_LOCK_UPGRADE(sc);
+
+	if (twl_is_4030(sc->sc_pdev)) {
+
+		/* Read the regulator CFG_GRP register */
+		err = twl_vreg_read_1(sc, regulator, TWL_VREG_GRP, &grp);
+		if (err)
+			goto done;
+
+		/* On the TWL4030 we just need to remove the regulator from all the
+		 * power groups.
+		 */
+		grp &= ~(TWL4030_P1_GRP | TWL4030_P2_GRP | TWL4030_P3_GRP);
+		err = twl_vreg_write_1(sc, regulator, TWL_VREG_GRP, grp);
+
+	} else if (twl_is_6030(sc->sc_pdev) || twl_is_6025(sc->sc_pdev)) {
+
+		/* On TWL6030 we need to make sure we disable power for all groups */
+		if (twl_is_6030(sc->sc_pdev))
+			grp = TWL6030_P1_GRP | TWL6030_P2_GRP | TWL6030_P3_GRP;
+		else
+			grp = 0x00;
+
+		/* Write the resource state to "OFF" */
+		err = twl_vreg_write_1(sc, regulator, TWL_VREG_STATE, (grp << 5));
+	}
+
+done:
+	if (!xlocked)
+		TWL_VREG_LOCK_DOWNGRADE(sc);
+	
+	return (err);
+}
+
+/**
+ *	twl_vreg_enable_regulator - enables the voltage regulator
+ *	@sc: the device soft context
+ *	@regulator: pointer to the regulator device
+ *
+ *	Enables the regulator which will enable the voltage out at the currently
+ *	set voltage.  Set the voltage before calling this function to avoid
+ *	driving the voltage too high/low by mistake.
+ *
+ *	LOCKING:
+ *	On entry expects the TWL VREG lock to be held. Will upgrade the lock to
+ *	exclusive if not already but, if so, it will be downgraded again before
+ *	returning.
+ *
+ *	RETURNS:
+ *	Zero on success or a positive error code on failure.
+ */
+static int
+twl_vreg_enable_regulator(struct twl_vreg_softc *sc,
+    struct twl_regulator_entry *regulator)
+{
+	int err;
+	uint8_t grp;
+	int xlocked;
+
+	TWL_VREG_ASSERT_LOCKED(sc);
+
+	xlocked = sx_xlocked(&sc->sc_sx);
+	if (!xlocked)
+		TWL_VREG_LOCK_UPGRADE(sc);
+
+
+	err = twl_vreg_read_1(sc, regulator, TWL_VREG_GRP, &grp);
+	if (err)
+		goto done;
+
+	/* Enable the regulator by ensuring it's in the application power group
+	 * and is in the "on" state.
+	 */
+	if (twl_is_4030(sc->sc_pdev)) {
+
+		/* On the TWL4030 we just need to ensure the regulator is in the right
+		 * power domain, don't need to turn on explicitly like TWL6030.
+		 */
+		grp |= TWL4030_P1_GRP;
+		err = twl_vreg_write_1(sc, regulator, TWL_VREG_GRP, grp);
+
+	} else if (twl_is_6030(sc->sc_pdev) || twl_is_6025(sc->sc_pdev)) {
+
+		if (twl_is_6030(sc->sc_pdev) && !(grp & TWL6030_P1_GRP)) {
+			grp |= TWL6030_P1_GRP;
+			err = twl_vreg_write_1(sc, regulator, TWL_VREG_GRP, grp);
+			if (err)
+				goto done;
+		}
+
+		/* Write the resource state to "ON" */
+		err = twl_vreg_write_1(sc, regulator, TWL_VREG_STATE, (grp << 5) | 0x01);
+	}
+
+done:
+	if (!xlocked)
+		TWL_VREG_LOCK_DOWNGRADE(sc);
+	
+	return (err);
+}
+
+/**
+ *	twl_vreg_write_regulator_voltage - sets the voltage level on a regulator
+ *	@sc: the device soft context
+ *	@regulator: pointer to the regulator structure
+ *	@millivolts: the voltage to set
+ *
+ *	Sets the voltage output on a given regulator, if the regulator is not
+ *	enabled, it will be enabled.
+ *
+ *	LOCKING:
+ *	On entry expects the TWL VREG lock to be held, may upgrade the lock to
+ *	exclusive but if so it will be downgraded once again before returning.
+ *
+ *	RETURNS:
+ *	Zero on success or an error code on failure.
+ */
+static int
+twl_vreg_write_regulator_voltage(struct twl_vreg_softc *sc,
+    struct twl_regulator_entry *regulator, int millivolts)
+{
+	int err;
+	uint8_t vsel;
+	int xlocked;
+
+	TWL_VREG_ASSERT_LOCKED(sc);
+
+	/* If millivolts is zero then we simply disable the output */
+	if (millivolts == 0)
+		return (twl_vreg_disable_regulator(sc, regulator));
+
+	/* If the regulator has a fixed voltage then check the setting matches
+	 * and simply enable.
+	 */
+	if (regulator->supp_voltages == NULL || regulator->num_supp_voltages == 0) {
+		if (millivolts != regulator->fixed_voltage)
+			return (EINVAL);
+
+		return (twl_vreg_enable_regulator(sc, regulator));
+	}
+
+	/* Get the VSEL value for the given voltage */
+	err = twl_vreg_millivolt_to_vsel(sc, regulator, millivolts, &vsel);
+	if (err)
+		return (err);
+
+	
+	/* Need to upgrade because writing the voltage and enabling should be atomic */
+	xlocked = sx_xlocked(&sc->sc_sx);
+	if (!xlocked)
+		TWL_VREG_LOCK_UPGRADE(sc);
+
+
+	/* Set voltage and enable (atomically) */
+	err = twl_vreg_write_1(sc, regulator, TWL_VREG_VSEL, (vsel & 0x1f));
+	if (!err) {
+		err = twl_vreg_enable_regulator(sc, regulator);
+	}
+
+	if (!xlocked)
+		TWL_VREG_LOCK_DOWNGRADE(sc);
+
+	if ((twl_vreg_debug > 1) && !err)
+		device_printf(sc->sc_dev, "%s : setting voltage to %dmV (vsel: 0x%x)\n",
+		    regulator->name, millivolts, vsel);
+
+	return (err);
+}
+
+/**
+ *	twl_vreg_read_regulator_voltage - reads the voltage on a given regulator
+ *	@sc: the device soft context
+ *	@regulator: pointer to the regulator structure
+ *	@millivolts: upon return will contain the voltage on the regulator
+ *
+ *	LOCKING:
+ *	On entry expects the TWL VREG lock to be held. It will upgrade the lock to
+ *	exclusive if not already, but if so, it will be downgraded again before
+ *	returning.
+ *
+ *	RETURNS:
+ *	Zero on success, or otherwise an error code.
+ */
+static int
+twl_vreg_read_regulator_voltage(struct twl_vreg_softc *sc,
+    struct twl_regulator_entry *regulator, int *millivolts)
+{
+	int err;
+	int en = 0;
+	int xlocked;
+	uint8_t vsel;
+	
+	TWL_VREG_ASSERT_LOCKED(sc);
+	
+	/* Need to upgrade the lock because checking enabled state and voltage
+	 * should be atomic.
+	 */
+	xlocked = sx_xlocked(&sc->sc_sx);
+	if (!xlocked)
+		TWL_VREG_LOCK_UPGRADE(sc);
+
+
+	/* Check if the regulator is currently enabled */
+	err = twl_vreg_is_regulator_enabled(sc, regulator, &en);
+	if (err)
+		goto done;
+
+	*millivolts = 0;	
+	if (!en)
+		goto done;
+
+
+	/* Not all voltages are adjustable */
+	if (regulator->supp_voltages == NULL || !regulator->num_supp_voltages) {
+		*millivolts = regulator->fixed_voltage;
+		goto done;
+	}
+
+	/* For variable voltages read the voltage register */
+	err = twl_vreg_read_1(sc, regulator, TWL_VREG_VSEL, &vsel);
+	if (err)
+		goto done;
+
+	vsel &= (regulator->num_supp_voltages - 1);
+	if (regulator->supp_voltages[vsel] == UNDF) {
+		err = EINVAL;
+		goto done;
+	}
+
+	*millivolts = regulator->supp_voltages[vsel];
+
+done:
+	if (!xlocked)
+		TWL_VREG_LOCK_DOWNGRADE(sc);
+	
+	if ((twl_vreg_debug > 1) && !err)
+		device_printf(sc->sc_dev, "%s : reading voltage is %dmV (vsel: 0x%x)\n",
+		    regulator->name, *millivolts, vsel);
+
+	return (err);
+}
+
+/**
+ *	twl_vreg_get_voltage - public interface to read the voltage on a regulator
+ *	@dev: TWL VREG device
+ *	@name: the name of the regulator to read the voltage of
+ *	@millivolts: pointer to an integer that upon return will contain the mV
+ *
+ *	If the regulator is disabled the function will set the @millivolts to zero.
+ *
+ *	LOCKING:
+ *	Internally the function takes and releases the TWL VREG lock.
+ *
+ *	RETURNS:
+ *	Zero on success or a negative error code on failure.
+ */
+int
+twl_vreg_get_voltage(device_t dev, const char *name, int *millivolts)
+{
+	struct twl_vreg_softc *sc;
+	struct twl_regulator_entry *regulator;
+	int err = EINVAL;
+
+	if (millivolts == NULL)
+		return (EINVAL);
+
+	sc = device_get_softc(dev);
+
+	TWL_VREG_SLOCK(sc);
+
+	LIST_FOREACH(regulator, &sc->sc_vreg_list, entries) {
+		if (strcmp(regulator->name, name) == 0) {
+			err = twl_vreg_read_regulator_voltage(sc, regulator, millivolts);
+			break;
+		}
+	}
+
+	TWL_VREG_SUNLOCK(sc);
+
+	return (err);
+}
+
+/**
+ *	twl_vreg_set_voltage - public interface to write the voltage on a regulator
+ *	@dev: TWL VREG device
+ *	@name: the name of the regulator to read the voltage of
+ *	@millivolts: the voltage to set in millivolts
+ *
+ *	Sets the output voltage on a given regulator. If the regulator is a fixed
+ *	voltage reg then the @millivolts value should match the fixed voltage. If
+ *	a variable regulator then the @millivolt value must fit within the max/min
+ *	range of the given regulator.
+ *
+ *	LOCKING:
+ *	Internally the function takes and releases the TWL VREG lock.
+ *
+ *	RETURNS:
+ *	Zero on success or a negative error code on failure.
+ */
+int
+twl_vreg_set_voltage(device_t dev, const char *name, int millivolts)
+{
+	struct twl_vreg_softc *sc;
+	struct twl_regulator_entry *regulator;
+	int err = EINVAL;
+
+	sc = device_get_softc(dev);
+
+	TWL_VREG_SLOCK(sc);
+
+	LIST_FOREACH(regulator, &sc->sc_vreg_list, entries) {
+		if (strcmp(regulator->name, name) == 0) {
+			err = twl_vreg_write_regulator_voltage(sc, regulator, millivolts);
+			break;
+		}
+	}
+
+	TWL_VREG_SUNLOCK(sc);
+
+	return (err);
+}
+
+/**
+ *	twl_sysctl_voltage - reads or writes the voltage for a regulator
+ *	@SYSCTL_HANDLER_ARGS: arguments for the callback
+ *
+ *	Callback for the sysctl entry for the regulator, simply used to return
+ *	the voltage on a particular regulator.
+ *
+ *	LOCKING:
+ *	Takes the TWL_VREG shared lock internally.
+ *
+ *	RETURNS:
+ *	Zero on success or an error code on failure.
+ */
+static int
+twl_vreg_sysctl_voltage(SYSCTL_HANDLER_ARGS)
+{
+	struct twl_vreg_softc *sc = (struct twl_vreg_softc*)arg1;
+	struct twl_regulator_entry *regulator;
+	int voltage;
+	int found = 0;
+
+	TWL_VREG_SLOCK(sc);
+
+	/* Find the regulator with the matching name */
+	LIST_FOREACH(regulator, &sc->sc_vreg_list, entries) {
+		if (strcmp(regulator->name, oidp->oid_name) == 0) {
+			found = 1;
+			break;
+		}
+	}
+
+	/* Sanity check that we found the regulator */
+	if (!found) {
+		TWL_VREG_SUNLOCK(sc);
+		return (EINVAL);
+	}
+
+	twl_vreg_read_regulator_voltage(sc, regulator, &voltage);
+
+	TWL_VREG_SUNLOCK(sc);
+
+	return sysctl_handle_int(oidp, &voltage, 0, req);
+}
+
+/**
+ *	twl_add_regulator - adds single voltage regulator sysctls for the device
+ *	@sc: device soft context
+ *	@name: the name of the regulator
+ *	@nsub: the number of the subdevice
+ *	@regbase: the base address of the voltage regulator registers
+ *	@fixed_voltage: if a fixed voltage regulator this defines it's voltage
+ *	@voltages: if a variable voltage regulator, an array of possible voltages
+ *	@num_voltages: the number of entries @voltages
+ *
+ *	Adds a voltage regulator to the device and also a sysctl interface for the
+ *	regulator.
+ *
+ *	LOCKING:
+ *	The TWL_VEG exclusive lock must be held while this function is called.
+ *
+ *	RETURNS:
+ *	Pointer to the new regulator entry on success, otherwise on failure NULL.
+ */
+static struct twl_regulator_entry*
+twl_vreg_add_regulator(struct twl_vreg_softc *sc, const char *name,
+	uint8_t nsub, uint8_t regbase, uint16_t fixed_voltage,
+	const uint16_t *voltages, uint32_t num_voltages)
+{
+	struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev);
+	struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev);
+	struct twl_regulator_entry *new;
+
+	new = malloc(sizeof(struct twl_regulator_entry), M_DEVBUF, M_NOWAIT | M_ZERO);
+	if (new == NULL)
+		return (NULL);
+
+
+	strncpy(new->name, name, TWL_VREG_MAX_NAMELEN);
+	new->name[TWL_VREG_MAX_NAMELEN - 1] = '\0';
+
+	new->sub_dev = nsub;
+	new->reg_off = regbase;
+
+	new->fixed_voltage = fixed_voltage;
+
+	new->supp_voltages = voltages;
+	new->num_supp_voltages = num_voltages;
+
+
+	/* Add a sysctl entry for the voltage */
+	new->oid = SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, name,
+	    CTLTYPE_INT | CTLFLAG_RD, sc, 0,
+	    twl_vreg_sysctl_voltage, "I", "voltage regulator");
+
+	/* Finally add the regulator to list of supported regulators */
+	LIST_INSERT_HEAD(&sc->sc_vreg_list, new, entries);
+
+	return (new);
+}
+
+/**
+ *	twl_vreg_add_regulators - adds any voltage regulators to the device
+ *	@sc: device soft context
+ *	@chip: the name of the chip used in the hints
+ *	@regulators: the list of possible voltage regulators
+ *
+ *	Loops over the list of regulators and matches up with the FDT values,
+ *	adjusting the actual voltage based on the supplied values.
+ *
+ *	LOCKING:
+ *	The TWL_VEG exclusive lock must be held while this function is called.
+ *
+ *	RETURNS:
+ *	Always returns 0.
+ */
+static int
+twl_vreg_add_regulators(struct twl_vreg_softc *sc,
+	const struct twl_regulator *regulators)
+{
+	int err;
+	int millivolts;
+	const struct twl_regulator *walker;
+	struct twl_regulator_entry *entry;
+	phandle_t child;
+	char rnames[256];
+	char *name, *voltage;
+	int len = 0, prop_len;
+
+
+	/* Add the regulators from the list */
+	walker = &regulators[0];
+	while (walker->name != NULL) {
+
+		/* Add the regulator to the list */
+		entry = twl_vreg_add_regulator(sc, walker->name, walker->subdev,
+		    walker->regbase, walker->fixedvoltage,
+		    walker->voltages, walker->num_voltages);
+		if (entry == NULL)
+			continue;
+
+		walker++;
+	}
+
+
+	/* Check if the FDT is telling us to set any voltages */
+	child = ofw_bus_get_node(sc->sc_pdev);
+	if (child) {
+
+		prop_len = OF_getprop(child, "voltage-regulators", rnames, sizeof(rnames));
+		while (len < prop_len) {
+			name = rnames + len;
+			len += strlen(name) + 1;
+			if ((len >= prop_len) || (name[0] == '\0'))
+				break;
+			
+			voltage = rnames + len;
+			len += strlen(voltage) + 1;
+			if (voltage[0] == '\0')
+				break;
+			
+			millivolts = strtoul(voltage, NULL, 0);
+			
+			LIST_FOREACH(entry, &sc->sc_vreg_list, entries) {
+				if (strcmp(entry->name, name) == 0) {
+					twl_vreg_write_regulator_voltage(sc, entry, millivolts);
+					break;
+				}
+			}
+		}
+	}
+	
+	
+	if (twl_vreg_debug) {
+		LIST_FOREACH(entry, &sc->sc_vreg_list, entries) {
+			err = twl_vreg_read_regulator_voltage(sc, entry, &millivolts);
+			if (!err)
+				device_printf(sc->sc_dev, "%s : %d mV\n", entry->name, millivolts);
+		}
+	}
+
+	return (0);
+}
+
+/**
+ *	twl_vreg_init - initialises the list of regulators
+ *	@dev: the twl_vreg device
+ *
+ *	This function is called as an intrhook once interrupts have been enabled,
+ *	this is done so that the driver has the option to enable/disable or set
+ *	the voltage level based on settings providied in the FDT.
+ *
+ *	LOCKING:
+ *	Takes the exclusive lock in the function.
+ */
+static void
+twl_vreg_init(void *dev)
+{
+	struct twl_vreg_softc *sc;
+
+	sc = device_get_softc((device_t)dev);
+
+	TWL_VREG_XLOCK(sc);
+
+	if (twl_is_4030(sc->sc_pdev))
+		twl_vreg_add_regulators(sc, twl4030_regulators);
+	else if (twl_is_6030(sc->sc_pdev) || twl_is_6025(sc->sc_pdev))
+		twl_vreg_add_regulators(sc, twl6030_regulators);
+
+	TWL_VREG_XUNLOCK(sc);
+
+	config_intrhook_disestablish(&sc->sc_init_hook);
+}
+
+static int
+twl_vreg_probe(device_t dev)
+{
+	if (twl_is_4030(device_get_parent(dev)))
+		device_set_desc(dev, "TI TWL4030 PMIC Voltage Regulators");
+	else if (twl_is_6025(device_get_parent(dev)) ||
+	         twl_is_6030(device_get_parent(dev)))
+		device_set_desc(dev, "TI TWL6025/TWL6030 PMIC Voltage Regulators");
+	else
+		return (ENXIO);
+
+	return (0);
+}
+
+static int
+twl_vreg_attach(device_t dev)
+{
+	struct twl_vreg_softc *sc;
+
+	sc = device_get_softc(dev);
+	sc->sc_dev = dev;
+	sc->sc_pdev = device_get_parent(dev);
+
+	TWL_VREG_LOCK_INIT(sc);
+
+	LIST_INIT(&sc->sc_vreg_list);
+
+	/* We have to wait until interrupts are enabled. I2C read and write
+	 * only works if the interrupts are available.
+	 */
+	sc->sc_init_hook.ich_func = twl_vreg_init;
+	sc->sc_init_hook.ich_arg = dev;
+
+	if (config_intrhook_establish(&sc->sc_init_hook) != 0)
+		return (ENOMEM);
+
+	return (0);
+}
+
+static int
+twl_vreg_detach(device_t dev)
+{
+	struct twl_vreg_softc *sc;
+	struct twl_regulator_entry *regulator;
+	struct twl_regulator_entry *tmp;
+
+	sc = device_get_softc(dev);
+
+	/* Take the lock and free all the added regulators */
+	TWL_VREG_XLOCK(sc);
+
+	LIST_FOREACH_SAFE(regulator, &sc->sc_vreg_list, entries, tmp) {
+		LIST_REMOVE(regulator, entries);
+		sysctl_remove_oid(regulator->oid, 1, 0);
+		free(regulator, M_DEVBUF);
+	}
+
+	TWL_VREG_XUNLOCK(sc);
+
+	TWL_VREG_LOCK_DESTROY(sc);
+
+	return (0);
+}
+
+static device_method_t twl_vreg_methods[] = {
+	DEVMETHOD(device_probe,		twl_vreg_probe),
+	DEVMETHOD(device_attach,	twl_vreg_attach),
+	DEVMETHOD(device_detach,	twl_vreg_detach),
+
+	{0, 0},
+};
+
+static driver_t twl_vreg_driver = {
+	"twl_vreg",
+	twl_vreg_methods,
+	sizeof(struct twl_vreg_softc),
+};
+
+static devclass_t twl_vreg_devclass;
+
+DRIVER_MODULE(twl_vreg, twl, twl_vreg_driver, twl_vreg_devclass, 0, 0);
+MODULE_VERSION(twl_vreg, 1);


Property changes on: trunk/sys/arm/ti/twl/twl_vreg.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/twl/twl_vreg.h
===================================================================
--- trunk/sys/arm/ti/twl/twl_vreg.h	                        (rev 0)
+++ trunk/sys/arm/ti/twl/twl_vreg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,37 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2011
+ *	Ben Gray <ben.r.gray at gmail.com>.
+ * 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 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 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: stable/10/sys/arm/ti/twl/twl_vreg.h 239281 2012-08-15 06:31:32Z gonzo $
+ */
+#ifndef _TWL_VREG_H_
+#define _TWL_VREG_H_
+
+
+int twl_vreg_get_voltage(device_t dev, const char *name, int *millivolts);
+int twl_vreg_set_voltage(device_t dev, const char *name, int millivolts);
+
+#endif /* _TWL_VREG_H_ */


Property changes on: trunk/sys/arm/ti/twl/twl_vreg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/usb/omap_ehci.c
===================================================================
--- trunk/sys/arm/ti/usb/omap_ehci.c	                        (rev 0)
+++ trunk/sys/arm/ti/usb/omap_ehci.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,1017 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2011
+ *	Ben Gray <ben.r.gray at gmail.com>.
+ * 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 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 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.
+ */
+
+/**
+ * Driver for the High Speed USB EHCI module on the TI OMAP3530 SoC.
+ *
+ * WARNING: I've only tried this driver on a limited number of USB peripherals,
+ * it is still very raw and bound to have numerous bugs in it.
+ *
+ * This driver is based on the FreeBSD IXP4xx EHCI driver with a lot of the
+ * setup sequence coming from the Linux community and their EHCI driver for
+ * OMAP.  Without these as a base I don't think I would have been able to get
+ * this driver working.
+ *
+ * The driver only contains the EHCI parts, the module also supports OHCI and
+ * USB on-the-go (OTG), currently neither are supported.
+ *
+ * CAUTION: This driver was written to run on the beaglebaord dev board, so I
+ * have made some assumptions about the type of PHY used and some of the other
+ * settings.  Bare that in mind if you intend to use this driver on another
+ * platform.
+ *
+ * NOTE: This module uses a few different clocks, one being a 60Mhz clock for
+ * the TTL part of the module.  This clock is derived from DPPL5 which must be
+ * configured prior to loading this driver - it is not configured by the
+ * bootloader.  It took me a long time to figure this out, and caused much
+ * frustration.  This PLL is now setup in the timer/clocks part of the BSP,
+ * check out the omap_prcm_setup_dpll5() function in omap_prcm.c for more info.
+ *
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/ti/usb/omap_ehci.c 308402 2016-11-07 09:19:04Z hselasky $");
+
+#include "opt_bus.h"
+
+#include <sys/stdint.h>
+#include <sys/stddef.h>
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/types.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/bus.h>
+#include <sys/rman.h>
+#include <sys/linker_set.h>
+#include <sys/module.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/condvar.h>
+#include <sys/sysctl.h>
+#include <sys/sx.h>
+#include <sys/unistd.h>
+#include <sys/callout.h>
+#include <sys/malloc.h>
+#include <sys/priv.h>
+#include <sys/gpio.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <dev/usb/usb.h>
+#include <dev/usb/usbdi.h>
+
+#include <dev/usb/usb_core.h>
+#include <dev/usb/usb_busdma.h>
+#include <dev/usb/usb_process.h>
+#include <dev/usb/usb_util.h>
+
+#include <dev/usb/usb_controller.h>
+#include <dev/usb/usb_bus.h>
+#include <dev/usb/controller/ehci.h>
+#include <dev/usb/controller/ehcireg.h>
+
+#include <arm/ti/tivar.h>
+#include <arm/ti/ti_prcm.h>
+#include <arm/ti/ti_scm.h>
+
+#include <arm/ti/usb/omap_usb.h>
+
+#include "gpio_if.h"
+
+struct omap_ehci_softc {
+	ehci_softc_t        base;	/* storage for EHCI code */
+
+	device_t            sc_dev;
+	device_t            sc_gpio_dev;
+
+	/* TLL register set */
+	struct resource*    tll_mem_res;
+
+	/* UHH register set */
+	struct resource*    uhh_mem_res;
+
+	/* The revision of the HS USB HOST read from UHH_REVISION */
+	uint32_t            ehci_rev;
+
+	/* The following details are provided by conf hints */
+	int                 port_mode[3];
+	int                 phy_reset[3];
+	int                 reset_gpio_pin[3];
+};
+
+static device_attach_t omap_ehci_attach;
+static device_detach_t omap_ehci_detach;
+static device_shutdown_t omap_ehci_shutdown;
+static device_suspend_t omap_ehci_suspend;
+static device_resume_t omap_ehci_resume;
+
+/**
+ *	omap_tll_read_4 - read a 32-bit value from the USBTLL registers
+ *	omap_tll_write_4 - write a 32-bit value from the USBTLL registers
+ *	omap_tll_readb - read an 8-bit value from the USBTLL registers
+ *	omap_tll_writeb - write an 8-bit value from the USBTLL registers
+ *	@sc: omap ehci device context
+ *	@off: byte offset within the register set to read from
+ *	@val: the value to write into the register
+ *	
+ *
+ *	LOCKING:
+ *	None
+ *
+ *	RETURNS:
+ *	nothing in case of write function, if read function returns the value read.
+ */
+static inline uint32_t
+omap_tll_read_4(struct omap_ehci_softc *sc, bus_size_t off)
+{
+	return bus_read_4(sc->tll_mem_res, off);
+}
+
+static inline void
+omap_tll_write_4(struct omap_ehci_softc *sc, bus_size_t off, uint32_t val)
+{
+	bus_write_4(sc->tll_mem_res, off, val);
+}
+
+static inline uint8_t
+omap_tll_readb(struct omap_ehci_softc *sc, bus_size_t off)
+{
+	return bus_read_1(sc->tll_mem_res, off);
+}
+
+static inline void
+omap_tll_writeb(struct omap_ehci_softc *sc, bus_size_t off, uint8_t val)
+{
+	bus_write_1(sc->tll_mem_res, off, val);
+}
+
+/**
+ *	omap_ehci_read_4 - read a 32-bit value from the EHCI registers
+ *	omap_ehci_write_4 - write a 32-bit value from the EHCI registers
+ *	@sc: omap ehci device context
+ *	@off: byte offset within the register set to read from
+ *	@val: the value to write into the register
+ *	
+ *
+ *	LOCKING:
+ *	None
+ *
+ *	RETURNS:
+ *	nothing in case of write function, if read function returns the value read.
+ */
+static inline uint32_t
+omap_ehci_read_4(struct omap_ehci_softc *sc, bus_size_t off)
+{
+	return (bus_read_4(sc->base.sc_io_res, off));
+}
+static inline void
+omap_ehci_write_4(struct omap_ehci_softc *sc, bus_size_t off, uint32_t val)
+{
+	bus_write_4(sc->base.sc_io_res, off, val);
+}
+
+/**
+ *	omap_uhh_read_4 - read a 32-bit value from the UHH registers
+ *	omap_uhh_write_4 - write a 32-bit value from the UHH registers
+ *	@sc: omap ehci device context
+ *	@off: byte offset within the register set to read from
+ *	@val: the value to write into the register
+ *	
+ *
+ *	LOCKING:
+ *	None
+ *
+ *	RETURNS:
+ *	nothing in case of write function, if read function returns the value read.
+ */
+static inline uint32_t
+omap_uhh_read_4(struct omap_ehci_softc *sc, bus_size_t off)
+{
+	return bus_read_4(sc->uhh_mem_res, off);
+}
+static inline void
+omap_uhh_write_4(struct omap_ehci_softc *sc, bus_size_t off, uint32_t val)
+{
+	bus_write_4(sc->uhh_mem_res, off, val);
+}
+
+/**
+ *	omap_ehci_utmi_init - initialises the UTMI part of the controller
+ *	@isc: omap ehci device context
+ *
+ *	
+ *
+ *	LOCKING:
+ *	none
+ *
+ *	RETURNS:
+ *	nothing
+ */
+static void
+omap_ehci_utmi_init(struct omap_ehci_softc *isc, unsigned int en_mask)
+{
+	unsigned int i;
+	uint32_t reg;
+	
+	/* There are 3 TLL channels, one per USB controller so set them all up the
+	 * same, SDR mode, bit stuffing and no autoidle.
+	 */
+	for (i=0; i<3; i++) {
+		reg = omap_tll_read_4(isc, OMAP_USBTLL_TLL_CHANNEL_CONF(i));
+		
+		reg &= ~(TLL_CHANNEL_CONF_UTMIAUTOIDLE
+				 | TLL_CHANNEL_CONF_ULPINOBITSTUFF
+				 | TLL_CHANNEL_CONF_ULPIDDRMODE);
+		
+		omap_tll_write_4(isc, OMAP_USBTLL_TLL_CHANNEL_CONF(i), reg);
+	}
+	
+	/* Program the common TLL register */
+	reg = omap_tll_read_4(isc, OMAP_USBTLL_TLL_SHARED_CONF);
+
+	reg &= ~( TLL_SHARED_CONF_USB_90D_DDR_EN
+			| TLL_SHARED_CONF_USB_DIVRATIO_MASK);
+	reg |=  ( TLL_SHARED_CONF_FCLK_IS_ON
+			| TLL_SHARED_CONF_USB_DIVRATIO_2
+			| TLL_SHARED_CONF_USB_180D_SDR_EN);
+	
+	omap_tll_write_4(isc, OMAP_USBTLL_TLL_SHARED_CONF, reg);
+	
+	/* Enable channels now */
+	for (i = 0; i < 3; i++) {
+		reg = omap_tll_read_4(isc, OMAP_USBTLL_TLL_CHANNEL_CONF(i));
+		
+		/* Enable only the reg that is needed */
+		if ((en_mask & (1 << i)) == 0)
+			continue;
+		
+		reg |= TLL_CHANNEL_CONF_CHANEN;
+		omap_tll_write_4(isc, OMAP_USBTLL_TLL_CHANNEL_CONF(i), reg);
+	}
+}
+
+/**
+ *	omap_ehci_soft_phy_reset - resets the phy using the reset command
+ *	@isc: omap ehci device context
+ *	@port: port to send the reset over
+ *	
+ *
+ *	LOCKING:
+ *	none
+ *
+ *	RETURNS:
+ *	nothing
+ */
+static void 
+omap_ehci_soft_phy_reset(struct omap_ehci_softc *isc, unsigned int port)
+{
+	unsigned long timeout = (hz < 10) ? 1 : ((100 * hz) / 1000);
+	uint32_t reg;
+
+	reg = ULPI_FUNC_CTRL_RESET
+		/* FUNCTION_CTRL_SET register */
+		| (ULPI_SET(ULPI_FUNC_CTRL) << OMAP_USBHOST_INSNREG05_ULPI_REGADD_SHIFT)
+		/* Write */
+		| (2 << OMAP_USBHOST_INSNREG05_ULPI_OPSEL_SHIFT)
+		/* PORTn */
+		| ((port + 1) << OMAP_USBHOST_INSNREG05_ULPI_PORTSEL_SHIFT)
+		/* start ULPI access*/
+		| (1 << OMAP_USBHOST_INSNREG05_ULPI_CONTROL_SHIFT);
+
+	omap_ehci_write_4(isc, OMAP_USBHOST_INSNREG05_ULPI, reg);
+
+	/* Wait for ULPI access completion */
+	while ((omap_ehci_read_4(isc, OMAP_USBHOST_INSNREG05_ULPI)
+	       & (1 << OMAP_USBHOST_INSNREG05_ULPI_CONTROL_SHIFT))) {
+
+		/* Sleep for a tick */
+		pause("USBPHY_RESET", 1);
+		
+		if (timeout-- == 0) {
+			device_printf(isc->sc_dev, "PHY reset operation timed out\n");
+			break;
+		}
+	}
+}
+ 
+
+/**
+ *	omap_ehci_init - initialises the USB host EHCI controller
+ *	@isc: omap ehci device context
+ *
+ *	This initialisation routine is quite heavily based on the work done by the
+ *	OMAP Linux team (for which I thank them very much).  The init sequence is
+ *	almost identical, diverging only for the FreeBSD specifics.
+ *
+ *	LOCKING:
+ *	none
+ *
+ *	RETURNS:
+ *	0 on success, a negative error code on failure.
+ */
+static int
+omap_ehci_init(struct omap_ehci_softc *isc)
+{
+	unsigned long timeout;
+	int ret = 0;
+	uint8_t tll_ch_mask = 0;
+	uint32_t reg = 0;
+	int reset_performed = 0;
+	int i;
+	
+	device_printf(isc->sc_dev, "Starting TI EHCI USB Controller\n");
+	
+	
+	/* Enable Clocks for high speed USBHOST */
+	ti_prcm_clk_enable(USBHSHOST_CLK);
+	
+	/* Hold the PHY in reset while configuring */
+	for (int i = 0; i < 3; i++) {
+		if (isc->phy_reset[i]) {
+			/* Configure the GPIO to drive low (hold in reset) */
+			if ((isc->reset_gpio_pin[i] != -1) && (isc->sc_gpio_dev != NULL)) {
+				GPIO_PIN_SETFLAGS(isc->sc_gpio_dev, isc->reset_gpio_pin[i],
+				    GPIO_PIN_OUTPUT);
+				GPIO_PIN_SET(isc->sc_gpio_dev, isc->reset_gpio_pin[i],
+				    GPIO_PIN_LOW);
+				reset_performed = 1;
+			}
+		}
+	}
+
+	/* Hold the PHY in RESET for enough time till DIR is high */
+	if (reset_performed)
+		DELAY(10);
+
+	/* Read the UHH revision */
+	isc->ehci_rev = omap_uhh_read_4(isc, OMAP_USBHOST_UHH_REVISION);
+	device_printf(isc->sc_dev, "UHH revision 0x%08x\n", isc->ehci_rev);
+	
+	/* Initilise the low level interface module(s) */
+	if (isc->ehci_rev == OMAP_EHCI_REV1) {
+
+		/* Enable the USB TLL */
+		ti_prcm_clk_enable(USBTLL_CLK);
+
+		/* Perform TLL soft reset, and wait until reset is complete */
+		omap_tll_write_4(isc, OMAP_USBTLL_SYSCONFIG, TLL_SYSCONFIG_SOFTRESET);
+	
+		/* Set the timeout to 100ms*/
+		timeout = (hz < 10) ? 1 : ((100 * hz) / 1000);
+
+		/* Wait for TLL reset to complete */
+		while ((omap_tll_read_4(isc, OMAP_USBTLL_SYSSTATUS) & 
+		        TLL_SYSSTATUS_RESETDONE) == 0x00) {
+
+			/* Sleep for a tick */
+			pause("USBRESET", 1);
+		
+			if (timeout-- == 0) {
+				device_printf(isc->sc_dev, "TLL reset operation timed out\n");
+				ret = EINVAL;
+				goto err_sys_status;
+			}
+		}
+	
+		device_printf(isc->sc_dev, "TLL RESET DONE\n");
+		
+		/* CLOCKACTIVITY = 1 : OCP-derived internal clocks ON during idle
+		 * SIDLEMODE = 2     : Smart-idle mode. Sidleack asserted after Idlereq
+		 *                     assertion when no more activity on the USB.
+		 * ENAWAKEUP = 1     : Wakeup generation enabled
+		 */
+		omap_tll_write_4(isc, OMAP_USBTLL_SYSCONFIG, TLL_SYSCONFIG_ENAWAKEUP |
+		                                            TLL_SYSCONFIG_AUTOIDLE |
+		                                            TLL_SYSCONFIG_SIDLE_SMART_IDLE |
+		                                            TLL_SYSCONFIG_CACTIVITY);
+
+	} else if (isc->ehci_rev == OMAP_EHCI_REV2) {
+	
+		/* For OMAP44xx devices you have to enable the per-port clocks:
+		 *  PHY_MODE  - External ULPI clock
+		 *  TTL_MODE  - Internal UTMI clock
+		 *  HSIC_MODE - Internal 480Mhz and 60Mhz clocks
+		 */
+		if (isc->ehci_rev == OMAP_EHCI_REV2) {
+			if (isc->port_mode[0] == EHCI_HCD_OMAP_MODE_PHY) {
+				ti_prcm_clk_set_source(USBP1_PHY_CLK, EXT_CLK);
+				ti_prcm_clk_enable(USBP1_PHY_CLK);
+			} else if (isc->port_mode[0] == EHCI_HCD_OMAP_MODE_TLL)
+				ti_prcm_clk_enable(USBP1_UTMI_CLK);
+			else if (isc->port_mode[0] == EHCI_HCD_OMAP_MODE_HSIC)
+				ti_prcm_clk_enable(USBP1_HSIC_CLK);
+
+			if (isc->port_mode[1] == EHCI_HCD_OMAP_MODE_PHY) {
+				ti_prcm_clk_set_source(USBP2_PHY_CLK, EXT_CLK);
+				ti_prcm_clk_enable(USBP2_PHY_CLK);
+			} else if (isc->port_mode[1] == EHCI_HCD_OMAP_MODE_TLL)
+				ti_prcm_clk_enable(USBP2_UTMI_CLK);
+			else if (isc->port_mode[1] == EHCI_HCD_OMAP_MODE_HSIC)
+				ti_prcm_clk_enable(USBP2_HSIC_CLK);
+		}
+	}
+
+	/* Put UHH in SmartIdle/SmartStandby mode */
+	reg = omap_uhh_read_4(isc, OMAP_USBHOST_UHH_SYSCONFIG);
+	if (isc->ehci_rev == OMAP_EHCI_REV1) {
+		reg &= ~(UHH_SYSCONFIG_SIDLEMODE_MASK |
+		         UHH_SYSCONFIG_MIDLEMODE_MASK);
+		reg |= (UHH_SYSCONFIG_ENAWAKEUP |
+		        UHH_SYSCONFIG_AUTOIDLE |
+		        UHH_SYSCONFIG_CLOCKACTIVITY |
+		        UHH_SYSCONFIG_SIDLEMODE_SMARTIDLE |
+		        UHH_SYSCONFIG_MIDLEMODE_SMARTSTANDBY);
+	} else if (isc->ehci_rev == OMAP_EHCI_REV2) {
+		reg &= ~UHH_SYSCONFIG_IDLEMODE_MASK;
+		reg |=  UHH_SYSCONFIG_IDLEMODE_NOIDLE;
+		reg &= ~UHH_SYSCONFIG_STANDBYMODE_MASK;
+		reg |=  UHH_SYSCONFIG_STANDBYMODE_NOSTDBY;
+	}
+	omap_uhh_write_4(isc, OMAP_USBHOST_UHH_SYSCONFIG, reg);
+	device_printf(isc->sc_dev, "OMAP_UHH_SYSCONFIG: 0x%08x\n", reg);
+
+	reg = omap_uhh_read_4(isc, OMAP_USBHOST_UHH_HOSTCONFIG);
+	
+	/* Setup ULPI bypass and burst configurations */
+	reg |= (UHH_HOSTCONFIG_ENA_INCR4 |
+			UHH_HOSTCONFIG_ENA_INCR8 |
+			UHH_HOSTCONFIG_ENA_INCR16);
+	reg &= ~UHH_HOSTCONFIG_ENA_INCR_ALIGN;
+	
+	if (isc->ehci_rev == OMAP_EHCI_REV1) {
+		if (isc->port_mode[0] == EHCI_HCD_OMAP_MODE_UNKNOWN)
+			reg &= ~UHH_HOSTCONFIG_P1_CONNECT_STATUS;
+		if (isc->port_mode[1] == EHCI_HCD_OMAP_MODE_UNKNOWN)
+			reg &= ~UHH_HOSTCONFIG_P2_CONNECT_STATUS;
+		if (isc->port_mode[2] == EHCI_HCD_OMAP_MODE_UNKNOWN)
+			reg &= ~UHH_HOSTCONFIG_P3_CONNECT_STATUS;
+	
+		/* Bypass the TLL module for PHY mode operation */
+		if ((isc->port_mode[0] == EHCI_HCD_OMAP_MODE_PHY) ||
+		    (isc->port_mode[1] == EHCI_HCD_OMAP_MODE_PHY) ||
+		    (isc->port_mode[2] == EHCI_HCD_OMAP_MODE_PHY))
+			reg &= ~UHH_HOSTCONFIG_P1_ULPI_BYPASS;
+		else
+			reg |= UHH_HOSTCONFIG_P1_ULPI_BYPASS;
+			
+	} else if (isc->ehci_rev == OMAP_EHCI_REV2) {
+		reg |=  UHH_HOSTCONFIG_APP_START_CLK;
+		
+		/* Clear port mode fields for PHY mode*/
+		reg &= ~UHH_HOSTCONFIG_P1_MODE_MASK;
+		reg &= ~UHH_HOSTCONFIG_P2_MODE_MASK;
+
+		if (isc->port_mode[0] == EHCI_HCD_OMAP_MODE_TLL)
+			reg |= UHH_HOSTCONFIG_P1_MODE_UTMI_PHY;
+		else if (isc->port_mode[0] == EHCI_HCD_OMAP_MODE_HSIC)
+			reg |= UHH_HOSTCONFIG_P1_MODE_HSIC;
+
+		if (isc->port_mode[1] == EHCI_HCD_OMAP_MODE_TLL)
+			reg |= UHH_HOSTCONFIG_P2_MODE_UTMI_PHY;
+		else if (isc->port_mode[1] == EHCI_HCD_OMAP_MODE_HSIC)
+			reg |= UHH_HOSTCONFIG_P2_MODE_HSIC;
+	}
+
+	omap_uhh_write_4(isc, OMAP_USBHOST_UHH_HOSTCONFIG, reg);
+	device_printf(isc->sc_dev, "UHH setup done, uhh_hostconfig=0x%08x\n", reg);
+	
+
+	/* I found the code and comments in the Linux EHCI driver - thanks guys :)
+	 *
+	 * "An undocumented "feature" in the OMAP3 EHCI controller, causes suspended
+	 * ports to be taken out of suspend when the USBCMD.Run/Stop bit is cleared
+	 * (for example when we do ehci_bus_suspend). This breaks suspend-resume if
+	 * the root-hub is allowed to suspend. Writing 1 to this undocumented
+	 * register bit disables this feature and restores normal behavior."
+	 */
+#if 0
+	omap_ehci_write_4(isc, OMAP_USBHOST_INSNREG04,
+	                 OMAP_USBHOST_INSNREG04_DISABLE_UNSUSPEND);
+#endif
+
+	/* If any of the ports are configured in TLL mode, enable them */
+	if ((isc->port_mode[0] == EHCI_HCD_OMAP_MODE_TLL) ||
+		(isc->port_mode[1] == EHCI_HCD_OMAP_MODE_TLL) ||
+		(isc->port_mode[2] == EHCI_HCD_OMAP_MODE_TLL)) {
+		
+		if (isc->port_mode[0] == EHCI_HCD_OMAP_MODE_TLL)
+			tll_ch_mask |= 0x1;
+		if (isc->port_mode[1] == EHCI_HCD_OMAP_MODE_TLL)
+			tll_ch_mask |= 0x2;
+		if (isc->port_mode[2] == EHCI_HCD_OMAP_MODE_TLL)
+			tll_ch_mask |= 0x4;
+		
+		/* Enable UTMI mode for required TLL channels */
+		omap_ehci_utmi_init(isc, tll_ch_mask);
+	}
+
+
+	/* Release the PHY reset signal now we have configured everything */
+	if (reset_performed) {
+
+		/* Delay for 10ms */
+		DELAY(10000);
+		
+		for (i = 0; i < 3; i++) {
+			/* Release reset */
+	
+			if (isc->phy_reset[i] && (isc->reset_gpio_pin[i] != -1) 
+			    && (isc->sc_gpio_dev != NULL)) {
+				GPIO_PIN_SET(isc->sc_gpio_dev, 
+					isc->reset_gpio_pin[i], GPIO_PIN_HIGH);
+			}
+		}
+	}
+
+	/* Set the interrupt threshold control, it controls the maximum rate at
+	 * which the host controller issues interrupts.  We set it to 1 microframe
+	 * at startup - the default is 8 mircoframes (equates to 1ms).
+	 */
+	reg = omap_ehci_read_4(isc, OMAP_USBHOST_USBCMD);
+	reg &= 0xff00ffff;
+	reg |= (1 << 16);
+	omap_ehci_write_4(isc, OMAP_USBHOST_USBCMD, reg);
+
+	/* Soft reset the PHY using PHY reset command over ULPI */
+	if (isc->port_mode[0] == EHCI_HCD_OMAP_MODE_PHY)
+		omap_ehci_soft_phy_reset(isc, 0);
+	if (isc->port_mode[1] == EHCI_HCD_OMAP_MODE_PHY)
+		omap_ehci_soft_phy_reset(isc, 1);	
+
+	return(0);
+
+err_sys_status:
+	
+	/* Disable the TLL clocks */
+	ti_prcm_clk_disable(USBTLL_CLK);
+	
+	/* Disable Clocks for USBHOST */
+	ti_prcm_clk_disable(USBHSHOST_CLK);
+
+	return(ret);
+}
+
+
+/**
+ *	omap_ehci_fini - shutdown the EHCI controller
+ *	@isc: omap ehci device context
+ *
+ *	
+ *
+ *	LOCKING:
+ *	none
+ *
+ *	RETURNS:
+ *	0 on success, a negative error code on failure.
+ */
+static void
+omap_ehci_fini(struct omap_ehci_softc *isc)
+{
+	unsigned long timeout;
+	
+	device_printf(isc->sc_dev, "Stopping TI EHCI USB Controller\n");
+	
+	/* Set the timeout */
+	if (hz < 10)
+		timeout = 1;
+	else
+		timeout = (100 * hz) / 1000;
+
+	/* Reset the UHH, OHCI and EHCI modules */
+	omap_uhh_write_4(isc, OMAP_USBHOST_UHH_SYSCONFIG, 0x0002);
+	while ((omap_uhh_read_4(isc, OMAP_USBHOST_UHH_SYSSTATUS) & 0x07) == 0x00) {
+		/* Sleep for a tick */
+		pause("USBRESET", 1);
+		
+		if (timeout-- == 0) {
+			device_printf(isc->sc_dev, "operation timed out\n");
+			break;
+		}
+	}
+	
+
+	/* Set the timeout */
+	if (hz < 10)
+		timeout = 1;
+	else
+		timeout = (100 * hz) / 1000;
+
+	/* Reset the TLL module */
+	omap_tll_write_4(isc, OMAP_USBTLL_SYSCONFIG, 0x0002);
+	while ((omap_tll_read_4(isc, OMAP_USBTLL_SYSSTATUS) & (0x01)) == 0x00) {
+		/* Sleep for a tick */
+		pause("USBRESET", 1);
+		
+		if (timeout-- == 0) {
+			device_printf(isc->sc_dev, "operation timed out\n");
+			break;
+		}
+	}
+
+
+	/* Disable functional and interface clocks for the TLL and HOST modules */
+	ti_prcm_clk_disable(USBTLL_CLK);
+	ti_prcm_clk_disable(USBHSHOST_CLK);
+
+	device_printf(isc->sc_dev, "Clock to USB host has been disabled\n");
+	
+}
+
+
+
+/**
+ *	omap_ehci_suspend - suspends the bus
+ *	@dev: omap ehci device
+ *	
+ *	Effectively boilerplate EHCI suspend code.
+ *
+ *	TODO: There is a lot more we could do here - i.e. force the controller into
+ *	idle mode and disable all the clocks for start.
+ *
+ *	LOCKING:
+ *	none
+ *
+ *	RETURNS:
+ *	0 on success or a positive error code
+ */
+static int
+omap_ehci_suspend(device_t dev)
+{
+	int err;
+	
+	err = bus_generic_suspend(dev);
+	if (err)
+		return (err);
+	return (0);
+}
+
+
+/**
+ *	omap_ehci_resume - resumes a suspended bus
+ *	@dev: omap ehci device
+ *	
+ *	Effectively boilerplate EHCI resume code.
+ *
+ *	LOCKING:
+ *	none
+ *
+ *	RETURNS:
+ *	0 on success or a positive error code on failure
+ */
+static int
+omap_ehci_resume(device_t dev)
+{
+	
+	bus_generic_resume(dev);
+	
+	return (0);
+}
+
+
+/**
+ *	omap_ehci_shutdown - starts the given command
+ *	@dev: 
+ *	
+ *	Effectively boilerplate EHCI shutdown code.
+ *
+ *	LOCKING:
+ *	none.
+ *
+ *	RETURNS:
+ *	0 on success or a positive error code on failure
+ */
+static int
+omap_ehci_shutdown(device_t dev)
+{
+	int err;
+	
+	err = bus_generic_shutdown(dev);
+	if (err)
+		return (err);
+	
+	return (0);
+}
+
+
+/**
+ *	omap_ehci_probe - starts the given command
+ *	@dev: 
+ *	
+ *	Effectively boilerplate EHCI resume code.
+ *
+ *	LOCKING:
+ *	Caller should be holding the OMAP3_MMC lock.
+ *
+ *	RETURNS:
+ *	EH_HANDLED or EH_NOT_HANDLED
+ */
+static int
+omap_ehci_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "ti,usb-ehci"))
+		return (ENXIO);
+
+	device_set_desc(dev, OMAP_EHCI_HC_DEVSTR);
+	
+	return (BUS_PROBE_DEFAULT);
+}
+
+/**
+ *	omap_ehci_attach - driver entry point, sets up the ECHI controller/driver
+ *	@dev: the new device handle
+ *	
+ *	Sets up bus spaces, interrupt handles, etc for the EHCI controller.  It also
+ *	parses the resource hints and calls omap_ehci_init() to initialise the
+ *	H/W.
+ *
+ *	LOCKING:
+ *	none
+ *
+ *	RETURNS:
+ *	0 on success or a positive error code on failure.
+ */
+static int
+omap_ehci_attach(device_t dev)
+{
+	struct omap_ehci_softc *isc = device_get_softc(dev);
+	phandle_t node;
+	/* 3 ports with 3 cells per port */
+	pcell_t phyconf[3 * 3];
+	pcell_t *phyconf_ptr;
+	ehci_softc_t *sc = &isc->base;
+	int err;
+	int rid;
+	int len, tuple_size;
+	int i;
+
+	/* initialise some bus fields */
+	sc->sc_bus.parent = dev;
+	sc->sc_bus.devices = sc->sc_devices;
+	sc->sc_bus.devices_max = EHCI_MAX_DEVICES;
+	sc->sc_bus.dma_bits = 32;
+
+	/* save the device */
+	isc->sc_dev = dev;
+	
+	/* get all DMA memory */
+	if (usb_bus_mem_alloc_all(&sc->sc_bus, USB_GET_DMA_TAG(dev),
+	                          &ehci_iterate_hw_softc)) {
+		return (ENOMEM);
+	}
+	
+	/* When the EHCI driver is added to the tree it is expected that 3
+	 * memory resources and 1 interrupt resource is assigned. The memory
+	 * resources should be:
+	 *   0 => EHCI register range
+	 *   1 => UHH register range
+	 *   2 => TLL register range
+	 *
+	 * The interrupt resource is just the single interupt for the controller.
+	 */
+
+	/* Allocate resource for the EHCI register set */
+	rid = 0;
+	sc->sc_io_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
+	if (!sc->sc_io_res) {
+		device_printf(dev, "Error: Could not map EHCI memory\n");
+		goto error;
+	}
+	/* Request an interrupt resource */
+	rid = 0;
+	sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE);
+	if (sc->sc_irq_res == NULL) {
+		device_printf(dev, "Error: could not allocate irq\n");
+		goto error;
+	}
+
+	/* Allocate resource for the UHH register set */
+	rid = 1;
+	isc->uhh_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
+	if (!isc->uhh_mem_res) {
+		device_printf(dev, "Error: Could not map UHH memory\n");
+		goto error;
+	}
+	/* Allocate resource for the TLL register set */
+	rid = 2;
+	isc->tll_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
+	if (!isc->tll_mem_res) {
+		device_printf(dev, "Error: Could not map TLL memory\n");
+		goto error;
+	}
+	
+	/* Add this device as a child of the USBus device */
+	sc->sc_bus.bdev = device_add_child(dev, "usbus", -1);
+	if (!sc->sc_bus.bdev) {
+		device_printf(dev, "Error: could not add USB device\n");
+		goto error;
+	}
+
+	device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
+	device_set_desc(sc->sc_bus.bdev, OMAP_EHCI_HC_DEVSTR);
+	
+	/* Set the vendor name */
+	sprintf(sc->sc_vendor, "Texas Instruments");
+	
+	/* Get the GPIO device, we may need this if the driver needs to toggle
+	 * some pins for external PHY resets.
+	 */
+	isc->sc_gpio_dev = devclass_get_device(devclass_find("gpio"), 0);
+	if (isc->sc_gpio_dev == NULL) {
+		device_printf(dev, "Error: failed to get the GPIO device\n");
+		goto error;
+	}
+	
+	/* Set the defaults for the hints */
+	for (i = 0; i < 3; i++) {
+		isc->phy_reset[i] = 0;
+		isc->port_mode[i] = EHCI_HCD_OMAP_MODE_UNKNOWN;
+		isc->reset_gpio_pin[i] = -1;
+	}
+
+	tuple_size = sizeof(pcell_t) * 3;
+	node = ofw_bus_get_node(dev);
+	len = OF_getprop(node, "phy-config", phyconf, sizeof(phyconf));
+	if (len > 0) {
+		if (len % tuple_size)
+			goto error;
+		if ((len / tuple_size) != 3)
+			goto error;
+
+		phyconf_ptr = phyconf;
+		for (i = 0; i < 3; i++) {
+			isc->port_mode[i] = fdt32_to_cpu(*phyconf_ptr);
+			isc->phy_reset[i] = fdt32_to_cpu(*(phyconf_ptr + 1));
+			isc->reset_gpio_pin[i] = fdt32_to_cpu(*(phyconf_ptr + 2));
+
+			phyconf_ptr += 3;
+		}
+	}
+	
+	/* Initialise the ECHI registers */
+	err = omap_ehci_init(isc);
+	if (err) {
+		device_printf(dev, "Error: could not setup OMAP EHCI, %d\n", err);
+		goto error;
+	}
+		
+
+	/* Set the tag and size of the register set in the EHCI context */
+	sc->sc_io_hdl = rman_get_bushandle(sc->sc_io_res);
+	sc->sc_io_tag = rman_get_bustag(sc->sc_io_res);
+	sc->sc_io_size = rman_get_size(sc->sc_io_res);
+
+
+	/* Setup the interrupt */
+	err = bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
+						 NULL, (driver_intr_t *)ehci_interrupt, sc, &sc->sc_intr_hdl);
+	if (err) {
+		device_printf(dev, "Error: could not setup irq, %d\n", err);
+		sc->sc_intr_hdl = NULL;
+		goto error;
+	}
+	
+	
+	/* Finally we are ready to kick off the ECHI host controller */
+	err = ehci_init(sc);
+	if (err == 0) {
+		err = device_probe_and_attach(sc->sc_bus.bdev);
+	}
+	if (err) {
+		device_printf(dev, "Error: USB init failed err=%d\n", err);
+		goto error;
+	}
+	
+	return (0);
+	
+error:
+	omap_ehci_detach(dev);
+	return (ENXIO);
+}
+
+/**
+ *	omap_ehci_detach - detach the device and cleanup the driver
+ *	@dev: device handle
+ *	
+ *	Clean-up routine where everything initialised in omap_ehci_attach is
+ *	freed and cleaned up.  This function calls omap_ehci_fini() to shutdown
+ *	the on-chip module.
+ *
+ *	LOCKING:
+ *	none
+ *
+ *	RETURNS:
+ *	Always returns 0 (success).
+ */
+static int
+omap_ehci_detach(device_t dev)
+{
+	struct omap_ehci_softc *isc = device_get_softc(dev);
+	ehci_softc_t *sc = &isc->base;
+	int err;
+	
+	/* during module unload there are lots of children leftover */
+	device_delete_children(dev);
+	
+	/*
+	 * disable interrupts that might have been switched on in ehci_init
+	 */
+	if (sc->sc_io_res) {
+		EWRITE4(sc, EHCI_USBINTR, 0);
+	}
+	
+	if (sc->sc_irq_res && sc->sc_intr_hdl) {
+		/*
+		 * only call ehci_detach() after ehci_init()
+		 */
+		ehci_detach(sc);
+		
+		err = bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_intr_hdl);
+		if (err)
+			device_printf(dev, "Error: could not tear down irq, %d\n", err);
+		sc->sc_intr_hdl = NULL;
+	}
+	
+	/* Free the resources stored in the base EHCI handler */
+	if (sc->sc_irq_res) {
+		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res);
+		sc->sc_irq_res = NULL;
+	}
+	if (sc->sc_io_res) {
+		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_io_res);
+		sc->sc_io_res = NULL;
+	}
+
+	/* Release the other register set memory maps */
+	if (isc->tll_mem_res) {
+		bus_release_resource(dev, SYS_RES_MEMORY, 0, isc->tll_mem_res);
+		isc->tll_mem_res = NULL;
+	}
+	if (isc->uhh_mem_res) {
+		bus_release_resource(dev, SYS_RES_MEMORY, 0, isc->uhh_mem_res);
+		isc->uhh_mem_res = NULL;
+	}
+
+	usb_bus_mem_free_all(&sc->sc_bus, &ehci_iterate_hw_softc);
+	
+	omap_ehci_fini(isc);
+	
+	return (0);
+}
+
+static device_method_t ehci_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe, omap_ehci_probe),
+	DEVMETHOD(device_attach, omap_ehci_attach),
+	DEVMETHOD(device_detach, omap_ehci_detach),
+	DEVMETHOD(device_suspend, omap_ehci_suspend),
+	DEVMETHOD(device_resume, omap_ehci_resume),
+	DEVMETHOD(device_shutdown, omap_ehci_shutdown),
+	
+	/* Bus interface */
+	DEVMETHOD(bus_print_child, bus_generic_print_child),
+	
+	{0, 0}
+};
+
+static driver_t ehci_driver = {
+	"ehci",
+	ehci_methods,
+	sizeof(struct omap_ehci_softc),
+};
+
+static devclass_t ehci_devclass;
+
+DRIVER_MODULE(ehci, simplebus, ehci_driver, ehci_devclass, 0, 0);


Property changes on: trunk/sys/arm/ti/usb/omap_ehci.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/ti/usb/omap_usb.h
===================================================================
--- trunk/sys/arm/ti/usb/omap_usb.h	                        (rev 0)
+++ trunk/sys/arm/ti/usb/omap_usb.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,265 @@
+/* $MidnightBSD$ */
+/*
+ * Copyright (c) 2010
+ *	Ben Gray <ben.r.gray at gmail.com>.
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Ben Gray.
+ * 4. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BEN GRAY ``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 BEN GRAY 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: stable/10/sys/arm/ti/usb/omap_usb.h 239281 2012-08-15 06:31:32Z gonzo $
+ */
+
+#ifndef _OMAP_USB_H_
+#define	_OMAP_USB_H_
+
+/*
+ * USB TTL Module
+ */
+#define	OMAP_USBTLL_REVISION                        0x0000
+#define	OMAP_USBTLL_SYSCONFIG                       0x0010
+#define	OMAP_USBTLL_SYSSTATUS                       0x0014
+#define	OMAP_USBTLL_IRQSTATUS                       0x0018
+#define	OMAP_USBTLL_IRQENABLE                       0x001C
+#define	OMAP_USBTLL_TLL_SHARED_CONF                 0x0030
+#define	OMAP_USBTLL_TLL_CHANNEL_CONF(i)             (0x0040 + (0x04 * (i)))
+#define	OMAP_USBTLL_SAR_CNTX(i)                     (0x0400 + (0x04 * (i)))
+#define	OMAP_USBTLL_ULPI_VENDOR_ID_LO(i)            (0x0800 + (0x100 * (i)))
+#define	OMAP_USBTLL_ULPI_VENDOR_ID_HI(i)            (0x0801 + (0x100 * (i)))
+#define	OMAP_USBTLL_ULPI_PRODUCT_ID_LO(i)           (0x0802 + (0x100 * (i)))
+#define	OMAP_USBTLL_ULPI_PRODUCT_ID_HI(i)           (0x0803 + (0x100 * (i)))
+#define	OMAP_USBTLL_ULPI_FUNCTION_CTRL(i)           (0x0804 + (0x100 * (i)))
+#define	OMAP_USBTLL_ULPI_FUNCTION_CTRL_SET(i)       (0x0805 + (0x100 * (i)))
+#define	OMAP_USBTLL_ULPI_FUNCTION_CTRL_CLR(i)       (0x0806 + (0x100 * (i)))
+#define	OMAP_USBTLL_ULPI_INTERFACE_CTRL(i)          (0x0807 + (0x100 * (i)))
+#define	OMAP_USBTLL_ULPI_INTERFACE_CTRL_SET(i)      (0x0808 + (0x100 * (i)))
+#define	OMAP_USBTLL_ULPI_INTERFACE_CTRL_CLR(i)      (0x0809 + (0x100 * (i)))
+#define	OMAP_USBTLL_ULPI_OTG_CTRL(i)                (0x080A + (0x100 * (i)))
+#define	OMAP_USBTLL_ULPI_OTG_CTRL_SET(i)            (0x080B + (0x100 * (i)))
+#define	OMAP_USBTLL_ULPI_OTG_CTRL_CLR(i)            (0x080C + (0x100 * (i)))
+#define	OMAP_USBTLL_ULPI_USB_INT_EN_RISE(i)         (0x080D + (0x100 * (i)))
+#define	OMAP_USBTLL_ULPI_USB_INT_EN_RISE_SET(i)     (0x080E + (0x100 * (i)))
+#define	OMAP_USBTLL_ULPI_USB_INT_EN_RISE_CLR(i)     (0x080F + (0x100 * (i)))
+#define	OMAP_USBTLL_ULPI_USB_INT_EN_FALL(i)         (0x0810 + (0x100 * (i)))
+#define	OMAP_USBTLL_ULPI_USB_INT_EN_FALL_SET(i)     (0x0811 + (0x100 * (i)))
+#define	OMAP_USBTLL_ULPI_USB_INT_EN_FALL_CLR(i)     (0x0812 + (0x100 * (i)))
+#define	OMAP_USBTLL_ULPI_USB_INT_STATUS(i)          (0x0813 + (0x100 * (i)))
+#define	OMAP_USBTLL_ULPI_USB_INT_LATCH(i)           (0x0814 + (0x100 * (i)))
+#define	OMAP_USBTLL_ULPI_DEBUG(i)                   (0x0815 + (0x100 * (i)))
+#define	OMAP_USBTLL_ULPI_SCRATCH_REGISTER(i)        (0x0816 + (0x100 * (i)))
+#define	OMAP_USBTLL_ULPI_SCRATCH_REGISTER_SET(i)    (0x0817 + (0x100 * (i)))
+#define	OMAP_USBTLL_ULPI_SCRATCH_REGISTER_CLR(i)    (0x0818 + (0x100 * (i)))
+#define	OMAP_USBTLL_ULPI_EXTENDED_SET_ACCESS(i)     (0x082F + (0x100 * (i)))
+#define	OMAP_USBTLL_ULPI_UTMI_VCONTROL_EN(i)        (0x0830 + (0x100 * (i)))
+#define	OMAP_USBTLL_ULPI_UTMI_VCONTROL_EN_SET(i)    (0x0831 + (0x100 * (i)))
+#define	OMAP_USBTLL_ULPI_UTMI_VCONTROL_EN_CLR(i)    (0x0832 + (0x100 * (i)))
+#define	OMAP_USBTLL_ULPI_UTMI_VCONTROL_STATUS(i)    (0x0833 + (0x100 * (i)))
+#define	OMAP_USBTLL_ULPI_UTMI_VCONTROL_LATCH(i)     (0x0834 + (0x100 * (i)))
+#define	OMAP_USBTLL_ULPI_UTMI_VSTATUS(i)            (0x0835 + (0x100 * (i)))
+#define	OMAP_USBTLL_ULPI_UTMI_VSTATUS_SET(i)        (0x0836 + (0x100 * (i)))
+#define	OMAP_USBTLL_ULPI_UTMI_VSTATUS_CLR(i)        (0x0837 + (0x100 * (i)))
+#define	OMAP_USBTLL_ULPI_USB_INT_LATCH_NOCLR(i)     (0x0838 + (0x100 * (i)))
+#define	OMAP_USBTLL_ULPI_VENDOR_INT_EN(i)           (0x083B + (0x100 * (i)))
+#define	OMAP_USBTLL_ULPI_VENDOR_INT_EN_SET(i)       (0x083C + (0x100 * (i)))
+#define	OMAP_USBTLL_ULPI_VENDOR_INT_EN_CLR(i)       (0x083D + (0x100 * (i)))
+#define	OMAP_USBTLL_ULPI_VENDOR_INT_STATUS(i)       (0x083E + (0x100 * (i)))
+#define	OMAP_USBTLL_ULPI_VENDOR_INT_LATCH(i)        (0x083F + (0x100 * (i)))
+
+
+/*
+ * USB Host Module
+ */
+
+/* UHH */
+#define	OMAP_USBHOST_UHH_REVISION                   0x0000
+#define	OMAP_USBHOST_UHH_SYSCONFIG                  0x0010
+#define	OMAP_USBHOST_UHH_SYSSTATUS                  0x0014
+#define	OMAP_USBHOST_UHH_HOSTCONFIG                 0x0040
+#define	OMAP_USBHOST_UHH_DEBUG_CSR                  0x0044
+
+/* EHCI */
+#define	OMAP_USBHOST_HCCAPBASE                      0x0000
+#define	OMAP_USBHOST_HCSPARAMS                      0x0004
+#define	OMAP_USBHOST_HCCPARAMS                      0x0008
+#define	OMAP_USBHOST_USBCMD                         0x0010
+#define	OMAP_USBHOST_USBSTS                         0x0014
+#define	OMAP_USBHOST_USBINTR                        0x0018
+#define	OMAP_USBHOST_FRINDEX                        0x001C
+#define	OMAP_USBHOST_CTRLDSSEGMENT                  0x0020
+#define	OMAP_USBHOST_PERIODICLISTBASE               0x0024
+#define	OMAP_USBHOST_ASYNCLISTADDR                  0x0028
+#define	OMAP_USBHOST_CONFIGFLAG                     0x0050
+#define	OMAP_USBHOST_PORTSC(i)                      (0x0054 + (0x04 * (i)))
+#define	OMAP_USBHOST_INSNREG00                      0x0090
+#define	OMAP_USBHOST_INSNREG01                      0x0094
+#define	OMAP_USBHOST_INSNREG02                      0x0098
+#define	OMAP_USBHOST_INSNREG03                      0x009C
+#define	OMAP_USBHOST_INSNREG04                      0x00A0
+#define	OMAP_USBHOST_INSNREG05_UTMI                 0x00A4
+#define	OMAP_USBHOST_INSNREG05_ULPI                 0x00A4
+#define	OMAP_USBHOST_INSNREG06                      0x00A8
+#define	OMAP_USBHOST_INSNREG07                      0x00AC
+#define	OMAP_USBHOST_INSNREG08                      0x00B0
+
+#define OMAP_USBHOST_INSNREG04_DISABLE_UNSUSPEND   (1 << 5)
+
+#define OMAP_USBHOST_INSNREG05_ULPI_CONTROL_SHIFT   31
+#define OMAP_USBHOST_INSNREG05_ULPI_PORTSEL_SHIFT   24
+#define OMAP_USBHOST_INSNREG05_ULPI_OPSEL_SHIFT     22
+#define OMAP_USBHOST_INSNREG05_ULPI_REGADD_SHIFT    16
+#define OMAP_USBHOST_INSNREG05_ULPI_EXTREGADD_SHIFT 8
+#define OMAP_USBHOST_INSNREG05_ULPI_WRDATA_SHIFT    0
+
+
+
+
+
+/* TLL Register Set */
+#define	TLL_SYSCONFIG_CACTIVITY                 (1UL << 8)
+#define	TLL_SYSCONFIG_SIDLE_SMART_IDLE          (2UL << 3)
+#define	TLL_SYSCONFIG_SIDLE_NO_IDLE             (1UL << 3)
+#define	TLL_SYSCONFIG_SIDLE_FORCED_IDLE         (0UL << 3)
+#define	TLL_SYSCONFIG_ENAWAKEUP                 (1UL << 2)
+#define	TLL_SYSCONFIG_SOFTRESET                 (1UL << 1)
+#define	TLL_SYSCONFIG_AUTOIDLE                  (1UL << 0)
+
+#define	TLL_SYSSTATUS_RESETDONE                 (1UL << 0)
+
+#define TLL_SHARED_CONF_USB_90D_DDR_EN          (1UL << 6)
+#define TLL_SHARED_CONF_USB_180D_SDR_EN         (1UL << 5)
+#define TLL_SHARED_CONF_USB_DIVRATIO_MASK       (7UL << 2)
+#define TLL_SHARED_CONF_USB_DIVRATIO_128        (7UL << 2)
+#define TLL_SHARED_CONF_USB_DIVRATIO_64         (6UL << 2)
+#define TLL_SHARED_CONF_USB_DIVRATIO_32         (5UL << 2)
+#define TLL_SHARED_CONF_USB_DIVRATIO_16         (4UL << 2)
+#define TLL_SHARED_CONF_USB_DIVRATIO_8          (3UL << 2)
+#define TLL_SHARED_CONF_USB_DIVRATIO_4          (2UL << 2)
+#define TLL_SHARED_CONF_USB_DIVRATIO_2          (1UL << 2)
+#define TLL_SHARED_CONF_USB_DIVRATIO_1          (0UL << 2)
+#define TLL_SHARED_CONF_FCLK_REQ                (1UL << 1)
+#define TLL_SHARED_CONF_FCLK_IS_ON              (1UL << 0)
+
+#define TLL_CHANNEL_CONF_DRVVBUS                (1UL << 16)
+#define TLL_CHANNEL_CONF_CHRGVBUS               (1UL << 15)
+#define TLL_CHANNEL_CONF_ULPINOBITSTUFF         (1UL << 11)
+#define TLL_CHANNEL_CONF_ULPIAUTOIDLE           (1UL << 10)
+#define TLL_CHANNEL_CONF_UTMIAUTOIDLE           (1UL << 9)
+#define TLL_CHANNEL_CONF_ULPIDDRMODE            (1UL << 8)
+#define TLL_CHANNEL_CONF_ULPIOUTCLKMODE         (1UL << 7)
+#define TLL_CHANNEL_CONF_TLLFULLSPEED           (1UL << 6)
+#define TLL_CHANNEL_CONF_TLLCONNECT             (1UL << 5)
+#define TLL_CHANNEL_CONF_TLLATTACH              (1UL << 4)
+#define TLL_CHANNEL_CONF_UTMIISADEV             (1UL << 3)
+#define TLL_CHANNEL_CONF_CHANEN                 (1UL << 0)
+
+
+/* UHH Register Set */
+#define UHH_SYSCONFIG_MIDLEMODE_MASK            (3UL << 12)
+#define UHH_SYSCONFIG_MIDLEMODE_SMARTSTANDBY    (2UL << 12)
+#define UHH_SYSCONFIG_MIDLEMODE_NOSTANDBY       (1UL << 12)
+#define UHH_SYSCONFIG_MIDLEMODE_FORCESTANDBY    (0UL << 12)
+#define UHH_SYSCONFIG_CLOCKACTIVITY             (1UL << 8)
+#define UHH_SYSCONFIG_SIDLEMODE_MASK            (3UL << 3)
+#define UHH_SYSCONFIG_SIDLEMODE_SMARTIDLE       (2UL << 3)
+#define UHH_SYSCONFIG_SIDLEMODE_NOIDLE          (1UL << 3)
+#define UHH_SYSCONFIG_SIDLEMODE_FORCEIDLE       (0UL << 3)
+#define UHH_SYSCONFIG_ENAWAKEUP                 (1UL << 2)
+#define UHH_SYSCONFIG_SOFTRESET                 (1UL << 1)
+#define UHH_SYSCONFIG_AUTOIDLE                  (1UL << 0)
+
+#define UHH_HOSTCONFIG_APP_START_CLK            (1UL << 31)
+#define UHH_HOSTCONFIG_P3_CONNECT_STATUS        (1UL << 10)
+#define UHH_HOSTCONFIG_P2_CONNECT_STATUS        (1UL << 9)
+#define UHH_HOSTCONFIG_P1_CONNECT_STATUS        (1UL << 8)
+#define UHH_HOSTCONFIG_ENA_INCR_ALIGN           (1UL << 5)
+#define UHH_HOSTCONFIG_ENA_INCR16               (1UL << 4)
+#define UHH_HOSTCONFIG_ENA_INCR8                (1UL << 3)
+#define UHH_HOSTCONFIG_ENA_INCR4                (1UL << 2)
+#define UHH_HOSTCONFIG_AUTOPPD_ON_OVERCUR_EN    (1UL << 1)
+#define UHH_HOSTCONFIG_P1_ULPI_BYPASS           (1UL << 0)
+
+/* The following are on rev2 (OMAP44xx) of the EHCI only */ 
+#define UHH_SYSCONFIG_IDLEMODE_MASK             (3UL << 2)
+#define UHH_SYSCONFIG_IDLEMODE_NOIDLE           (1UL << 2)
+#define UHH_SYSCONFIG_STANDBYMODE_MASK          (3UL << 4)
+#define UHH_SYSCONFIG_STANDBYMODE_NOSTDBY       (1UL << 4)
+
+#define UHH_HOSTCONFIG_P1_MODE_MASK             (3UL << 16)
+#define UHH_HOSTCONFIG_P1_MODE_ULPI_PHY         (0UL << 16)
+#define UHH_HOSTCONFIG_P1_MODE_UTMI_PHY         (1UL << 16)
+#define UHH_HOSTCONFIG_P1_MODE_HSIC             (3UL << 16)
+#define UHH_HOSTCONFIG_P2_MODE_MASK             (3UL << 18)
+#define UHH_HOSTCONFIG_P2_MODE_ULPI_PHY         (0UL << 18)
+#define UHH_HOSTCONFIG_P2_MODE_UTMI_PHY         (1UL << 18)
+#define UHH_HOSTCONFIG_P2_MODE_HSIC             (3UL << 18)
+
+#define ULPI_FUNC_CTRL_RESET                    (1 << 5)
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * Macros for Set and Clear
+ * See ULPI 1.1 specification to find the registers with Set and Clear offsets
+ */
+#define ULPI_SET(a)                             (a + 1)
+#define ULPI_CLR(a)                             (a + 2)
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * Register Map
+ */
+#define ULPI_VENDOR_ID_LOW                      0x00
+#define ULPI_VENDOR_ID_HIGH                     0x01
+#define ULPI_PRODUCT_ID_LOW                     0x02
+#define ULPI_PRODUCT_ID_HIGH                    0x03
+#define ULPI_FUNC_CTRL                          0x04
+#define ULPI_IFC_CTRL                           0x07
+#define ULPI_OTG_CTRL                           0x0a
+#define ULPI_USB_INT_EN_RISE                    0x0d
+#define ULPI_USB_INT_EN_FALL                    0x10
+#define ULPI_USB_INT_STS                        0x13
+#define ULPI_USB_INT_LATCH                      0x14
+#define ULPI_DEBUG                              0x15
+#define ULPI_SCRATCH                            0x16
+
+/* 
+ * Values of UHH_REVISION - Note: these are not given in the TRM but taken
+ * from the linux OMAP EHCI driver (thanks guys).  It has been verified on
+ * a Panda and Beagle board.
+ */
+#define OMAP_EHCI_REV1  0x00000010      /* OMAP3 */
+#define OMAP_EHCI_REV2  0x50700100      /* OMAP4 */
+
+#define EHCI_VENDORID_OMAP3     0x42fa05
+#define OMAP_EHCI_HC_DEVSTR    "TI OMAP USB 2.0 controller"
+
+#define EHCI_HCD_OMAP_MODE_UNKNOWN  0
+#define EHCI_HCD_OMAP_MODE_PHY      1
+#define EHCI_HCD_OMAP_MODE_TLL      2
+#define EHCI_HCD_OMAP_MODE_HSIC     3
+
+#endif	/* _OMAP_USB_H_ */


Property changes on: trunk/sys/arm/ti/usb/omap_usb.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/versatile/files.versatile
===================================================================
--- trunk/sys/arm/versatile/files.versatile	                        (rev 0)
+++ trunk/sys/arm/versatile/files.versatile	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,21 @@
+# $FreeBSD: stable/10/sys/arm/versatile/files.versatile 278727 2015-02-13 22:32:02Z ian $
+
+arm/arm/bus_space_base.c 			standard
+arm/arm/bus_space_asm_generic.S			standard
+arm/arm/bus_space_generic.c                     standard
+arm/arm/cpufunc_asm_arm11.S                     standard
+arm/arm/cpufunc_asm_arm11x6.S			standard
+arm/arm/cpufunc_asm_armv5.S                     standard
+arm/arm/cpufunc_asm_armv6.S                     standard
+
+arm/versatile/pl050.c				optional sc
+arm/versatile/sp804.c				standard
+arm/versatile/versatile_machdep.c		standard
+arm/versatile/versatile_clcd.c			optional sc
+arm/versatile/versatile_common.c		standard
+arm/versatile/versatile_pci.c			optional pci
+arm/versatile/versatile_sic.c			standard
+arm/versatile/versatile_timer.c			standard
+arm/versatile/if_smc_fdt.c			optional smc
+
+kern/kern_clocksource.c                         standard


Property changes on: trunk/sys/arm/versatile/files.versatile
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/versatile/if_smc_fdt.c
===================================================================
--- trunk/sys/arm/versatile/if_smc_fdt.c	                        (rev 0)
+++ trunk/sys/arm/versatile/if_smc_fdt.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,136 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2008 Benno Rice
+ * 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 ``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 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: stable/10/sys/arm/versatile/if_smc_fdt.c 266152 2014-05-15 16:11:06Z ian $");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/socket.h>
+#include <sys/systm.h>
+#include <sys/taskqueue.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+
+#include <net/ethernet.h>
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <net/if_media.h>
+
+#include <dev/smc/if_smcvar.h>
+
+#include <dev/mii/mii.h>
+#include <dev/mii/miivar.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include "miibus_if.h"
+
+static int		smc_fdt_probe(device_t);
+static int		smc_fdt_attach(device_t);
+static int		smc_fdt_detach(device_t);
+
+static int
+smc_fdt_probe(device_t dev)
+{
+	struct	smc_softc *sc;
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (ofw_bus_is_compatible(dev, "smsc,lan91c111")) {
+		sc = device_get_softc(dev);
+		sc->smc_usemem = 1;
+
+		if (smc_probe(dev) != 0) {
+			return (ENXIO);
+		}
+
+		return (0);
+	}
+
+	return (ENXIO);
+}
+
+static int
+smc_fdt_attach(device_t dev)
+{
+	int	err;
+ 	struct	smc_softc *sc;
+
+	sc = device_get_softc(dev);
+
+	err = smc_attach(dev);
+	if (err) {
+		return (err);
+	}
+
+	return (0);
+}
+
+static int
+smc_fdt_detach(device_t dev)
+{
+
+	smc_detach(dev);
+
+	return (0);
+}
+
+static device_method_t smc_fdt_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		smc_fdt_probe),
+	DEVMETHOD(device_attach,	smc_fdt_attach),
+	DEVMETHOD(device_detach,	smc_fdt_detach),
+
+	/* MII interface */
+	DEVMETHOD(miibus_readreg,	smc_miibus_readreg),
+	DEVMETHOD(miibus_writereg,	smc_miibus_writereg),
+	DEVMETHOD(miibus_statchg,	smc_miibus_statchg),
+
+	{ 0, 0 }
+};
+
+static driver_t smc_fdt_driver = {
+	"smc",
+	smc_fdt_methods,
+	sizeof(struct smc_softc),
+};
+
+extern devclass_t smc_devclass;
+
+DRIVER_MODULE(smc, simplebus, smc_fdt_driver, smc_devclass, 0, 0);
+DRIVER_MODULE(miibus, smc, miibus_driver, miibus_devclass, 0, 0);
+MODULE_DEPEND(smc, fdt, 1, 1, 1);
+MODULE_DEPEND(smc, ether, 1, 1, 1);
+MODULE_DEPEND(smc, miibus, 1, 1, 1);


Property changes on: trunk/sys/arm/versatile/if_smc_fdt.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/versatile/pl050.c
===================================================================
--- trunk/sys/arm/versatile/pl050.c	                        (rev 0)
+++ trunk/sys/arm/versatile/pl050.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,716 @@
+/* $MidnightBSD$ */
+/*
+ * Copyright (c) 2012 Oleksandr Tymoshenko <gonzo at freebsd.org>
+ * All rights reserved.
+ *
+ * Based on dev/usb/input/ukbd.c  
+ *
+ * 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: stable/10/sys/arm/versatile/pl050.c 266152 2014-05-15 16:11:06Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/proc.h>
+#include <sys/sched.h>
+#include <sys/kdb.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <sys/ioccom.h>
+#include <sys/filio.h>
+#include <sys/tty.h>
+#include <sys/kbio.h>
+
+#include <dev/kbd/kbdreg.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+
+#include <dev/kbd/kbdtables.h>
+
+#define	KMI_LOCK()	mtx_lock(&Giant)
+#define	KMI_UNLOCK()	mtx_unlock(&Giant)
+
+#ifdef	INVARIANTS
+/*
+ * Assert that the lock is held in all contexts
+ * where the code can be executed.
+ */
+#define	KMI_LOCK_ASSERT()	mtx_assert(&Giant, MA_OWNED)
+/*
+ * Assert that the lock is held in the contexts
+ * where it really has to be so.
+ */
+#define	KMI_CTX_LOCK_ASSERT()			 	\
+	do {						\
+		if (!kdb_active && panicstr == NULL)	\
+			mtx_assert(&Giant, MA_OWNED);	\
+	} while (0)
+#else
+#define KMI_LOCK_ASSERT()	(void)0
+#define KMI_CTX_LOCK_ASSERT()	(void)0
+#endif
+
+#define	KMICR		0x00
+#define		KMICR_TYPE_NONPS2	(1 << 5)
+#define		KMICR_RXINTREN		(1 << 4)
+#define		KMICR_TXINTREN		(1 << 3)
+#define		KMICR_EN		(1 << 2)
+#define		KMICR_FKMID		(1 << 1)
+#define		KMICR_FKMIC		(1 << 0)
+#define	KMISTAT		0x04
+#define		KMISTAT_TXEMPTY		(1 << 6)
+#define		KMISTAT_TXBUSY		(1 << 5)
+#define		KMISTAT_RXFULL		(1 << 4)
+#define		KMISTAT_RXBUSY		(1 << 3)
+#define		KMISTAT_RXPARITY	(1 << 2)
+#define		KMISTAT_KMIC		(1 << 1)
+#define		KMISTAT_KMID		(1 << 0)
+#define	KMIDATA		0x08
+#define	KMICLKDIV	0x0C
+#define	KMIIR		0x10
+#define		KMIIR_TXINTR		(1 << 1)
+#define		KMIIR_RXINTR		(1 << 0)
+
+#define	KMI_DRIVER_NAME          "kmi"
+#define	KMI_NFKEY        (sizeof(fkey_tab)/sizeof(fkey_tab[0]))	/* units */
+
+struct kmi_softc {
+	keyboard_t sc_kbd;
+	keymap_t sc_keymap;
+	accentmap_t sc_accmap;
+	fkeytab_t sc_fkeymap[KMI_NFKEY];
+
+	struct resource*	sc_mem_res;
+	struct resource*	sc_irq_res;
+	void*			sc_intr_hl;
+
+	int			sc_mode;		/* input mode (K_XLATE,K_RAW,K_CODE) */
+	int			sc_state;		/* shift/lock key state */
+	int			sc_accents;		/* accent key index (> 0) */
+	uint32_t		sc_flags;		/* flags */
+#define	KMI_FLAG_COMPOSE	0x00000001
+#define	KMI_FLAG_POLLING	0x00000002
+
+	struct			thread *sc_poll_thread;
+};
+
+/* Read/Write macros for Timer used as timecounter */
+#define pl050_kmi_read_4(sc, reg)		\
+	bus_read_4((sc)->sc_mem_res, (reg))
+
+#define pl050_kmi_write_4(sc, reg, val)	\
+	bus_write_4((sc)->sc_mem_res, (reg), (val))
+
+/* prototypes */
+static void	kmi_set_leds(struct kmi_softc *, uint8_t);
+static int	kmi_set_typematic(keyboard_t *, int);
+static uint32_t	kmi_read_char(keyboard_t *, int);
+static void	kmi_clear_state(keyboard_t *);
+static int	kmi_ioctl(keyboard_t *, u_long, caddr_t);
+static int	kmi_enable(keyboard_t *);
+static int	kmi_disable(keyboard_t *);
+
+/* early keyboard probe, not supported */
+static int
+kmi_configure(int flags)
+{
+	return (0);
+}
+
+/* detect a keyboard, not used */
+static int
+kmi_probe(int unit, void *arg, int flags)
+{
+	return (ENXIO);
+}
+
+/* reset and initialize the device, not used */
+static int
+kmi_init(int unit, keyboard_t **kbdp, void *arg, int flags)
+{
+	return (ENXIO);
+}
+
+/* test the interface to the device, not used */
+static int
+kmi_test_if(keyboard_t *kbd)
+{
+	return (0);
+}
+
+/* finish using this keyboard, not used */
+static int
+kmi_term(keyboard_t *kbd)
+{
+	return (ENXIO);
+}
+
+/* keyboard interrupt routine, not used */
+static int
+kmi_intr(keyboard_t *kbd, void *arg)
+{
+
+	return (0);
+}
+
+/* lock the access to the keyboard, not used */
+static int
+kmi_lock(keyboard_t *kbd, int lock)
+{
+	return (1);
+}
+
+/*
+ * Enable the access to the device; until this function is called,
+ * the client cannot read from the keyboard.
+ */
+static int
+kmi_enable(keyboard_t *kbd)
+{
+
+	KMI_LOCK();
+	KBD_ACTIVATE(kbd);
+	KMI_UNLOCK();
+
+	return (0);
+}
+
+/* disallow the access to the device */
+static int
+kmi_disable(keyboard_t *kbd)
+{
+
+	KMI_LOCK();
+	KBD_DEACTIVATE(kbd);
+	KMI_UNLOCK();
+
+	return (0);
+}
+
+/* check if data is waiting */
+static int
+kmi_check(keyboard_t *kbd)
+{
+	struct kmi_softc *sc = kbd->kb_data;
+	uint32_t reg;
+
+	KMI_CTX_LOCK_ASSERT();
+
+	if (!KBD_IS_ACTIVE(kbd))
+		return (0);
+
+	reg = pl050_kmi_read_4(sc, KMIIR);
+	return (reg & KMIIR_RXINTR);
+}
+
+/* check if char is waiting */
+static int
+kmi_check_char_locked(keyboard_t *kbd)
+{
+	KMI_CTX_LOCK_ASSERT();
+
+	if (!KBD_IS_ACTIVE(kbd))
+		return (0);
+
+	return (kmi_check(kbd));
+}
+
+static int
+kmi_check_char(keyboard_t *kbd)
+{
+	int result;
+
+	KMI_LOCK();
+	result = kmi_check_char_locked(kbd);
+	KMI_UNLOCK();
+
+	return (result);
+}
+
+/* read one byte from the keyboard if it's allowed */
+/* Currently unused. */
+static int
+kmi_read(keyboard_t *kbd, int wait)
+{
+	KMI_CTX_LOCK_ASSERT();
+
+	if (!KBD_IS_ACTIVE(kbd))
+		return (-1);
+
+	++(kbd->kb_count);
+	printf("Implement ME: %s\n", __func__);
+	return (0);
+}
+
+/* read char from the keyboard */
+static uint32_t
+kmi_read_char_locked(keyboard_t *kbd, int wait)
+{
+	struct kmi_softc *sc = kbd->kb_data;
+	uint32_t reg, data;
+
+	KMI_CTX_LOCK_ASSERT();
+
+	if (!KBD_IS_ACTIVE(kbd))
+		return (NOKEY);
+
+	reg = pl050_kmi_read_4(sc, KMIIR);
+	if (reg & KMIIR_RXINTR) {
+		data = pl050_kmi_read_4(sc, KMIDATA);
+		return (data);
+	}
+
+	++kbd->kb_count;
+	return (NOKEY);
+}
+
+/* Currently wait is always false. */
+static uint32_t
+kmi_read_char(keyboard_t *kbd, int wait)
+{
+	uint32_t keycode;
+
+	KMI_LOCK();
+	keycode = kmi_read_char_locked(kbd, wait);
+	KMI_UNLOCK();
+
+	return (keycode);
+}
+
+/* some useful control functions */
+static int
+kmi_ioctl_locked(keyboard_t *kbd, u_long cmd, caddr_t arg)
+{
+	struct kmi_softc *sc = kbd->kb_data;
+	int i;
+#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
+    defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
+	int ival;
+
+#endif
+
+	KMI_LOCK_ASSERT();
+
+	switch (cmd) {
+	case KDGKBMODE:		/* get keyboard mode */
+		*(int *)arg = sc->sc_mode;
+		break;
+#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
+    defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
+	case _IO('K', 7):
+		ival = IOCPARM_IVAL(arg);
+		arg = (caddr_t)&ival;
+		/* FALLTHROUGH */
+#endif
+	case KDSKBMODE:		/* set keyboard mode */
+		switch (*(int *)arg) {
+		case K_XLATE:
+			if (sc->sc_mode != K_XLATE) {
+				/* make lock key state and LED state match */
+				sc->sc_state &= ~LOCK_MASK;
+				sc->sc_state |= KBD_LED_VAL(kbd);
+			}
+			/* FALLTHROUGH */
+		case K_RAW:
+		case K_CODE:
+			if (sc->sc_mode != *(int *)arg) {
+				if ((sc->sc_flags & KMI_FLAG_POLLING) == 0)
+					kmi_clear_state(kbd);
+				sc->sc_mode = *(int *)arg;
+			}
+			break;
+		default:
+			return (EINVAL);
+		}
+		break;
+
+	case KDGETLED:			/* get keyboard LED */
+		*(int *)arg = KBD_LED_VAL(kbd);
+		break;
+#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
+    defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
+	case _IO('K', 66):
+		ival = IOCPARM_IVAL(arg);
+		arg = (caddr_t)&ival;
+		/* FALLTHROUGH */
+#endif
+	case KDSETLED:			/* set keyboard LED */
+		/* NOTE: lock key state in "sc_state" won't be changed */
+		if (*(int *)arg & ~LOCK_MASK)
+			return (EINVAL);
+
+		i = *(int *)arg;
+
+		/* replace CAPS LED with ALTGR LED for ALTGR keyboards */
+		if (sc->sc_mode == K_XLATE &&
+		    kbd->kb_keymap->n_keys > ALTGR_OFFSET) {
+			if (i & ALKED)
+				i |= CLKED;
+			else
+				i &= ~CLKED;
+		}
+		if (KBD_HAS_DEVICE(kbd))
+			kmi_set_leds(sc, i);
+
+		KBD_LED_VAL(kbd) = *(int *)arg;
+		break;
+	case KDGKBSTATE:		/* get lock key state */
+		*(int *)arg = sc->sc_state & LOCK_MASK;
+		break;
+#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
+    defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
+	case _IO('K', 20):
+		ival = IOCPARM_IVAL(arg);
+		arg = (caddr_t)&ival;
+		/* FALLTHROUGH */
+#endif
+	case KDSKBSTATE:		/* set lock key state */
+		if (*(int *)arg & ~LOCK_MASK) {
+			return (EINVAL);
+		}
+		sc->sc_state &= ~LOCK_MASK;
+		sc->sc_state |= *(int *)arg;
+
+		/* set LEDs and quit */
+		return (kmi_ioctl(kbd, KDSETLED, arg));
+
+	case KDSETREPEAT:		/* set keyboard repeat rate (new
+					 * interface) */
+		if (!KBD_HAS_DEVICE(kbd)) {
+			return (0);
+		}
+		if (((int *)arg)[1] < 0) {
+			return (EINVAL);
+		}
+		if (((int *)arg)[0] < 0) {
+			return (EINVAL);
+		}
+		if (((int *)arg)[0] < 200)	/* fastest possible value */
+			kbd->kb_delay1 = 200;
+		else
+			kbd->kb_delay1 = ((int *)arg)[0];
+		kbd->kb_delay2 = ((int *)arg)[1];
+		return (0);
+
+#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
+    defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
+	case _IO('K', 67):
+		ival = IOCPARM_IVAL(arg);
+		arg = (caddr_t)&ival;
+		/* FALLTHROUGH */
+#endif
+	case KDSETRAD:			/* set keyboard repeat rate (old
+					 * interface) */
+		return (kmi_set_typematic(kbd, *(int *)arg));
+
+	case PIO_KEYMAP:		/* set keyboard translation table */
+	case OPIO_KEYMAP:		/* set keyboard translation table
+					 * (compat) */
+	case PIO_KEYMAPENT:		/* set keyboard translation table
+					 * entry */
+	case PIO_DEADKEYMAP:		/* set accent key translation table */
+		sc->sc_accents = 0;
+		/* FALLTHROUGH */
+	default:
+		return (genkbd_commonioctl(kbd, cmd, arg));
+	}
+
+	return (0);
+}
+
+static int
+kmi_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg)
+{
+	int result;
+
+	/*
+	 * XXX KDGKBSTATE, KDSKBSTATE and KDSETLED can be called from any
+	 * context where printf(9) can be called, which among other things
+	 * includes interrupt filters and threads with any kinds of locks
+	 * already held.  For this reason it would be dangerous to acquire
+	 * the Giant here unconditionally.  On the other hand we have to
+	 * have it to handle the ioctl.
+	 * So we make our best effort to auto-detect whether we can grab
+	 * the Giant or not.  Blame syscons(4) for this.
+	 */
+	switch (cmd) {
+	case KDGKBSTATE:
+	case KDSKBSTATE:
+	case KDSETLED:
+		if (!mtx_owned(&Giant) && !SCHEDULER_STOPPED())
+			return (EDEADLK);	/* best I could come up with */
+		/* FALLTHROUGH */
+	default:
+		KMI_LOCK();
+		result = kmi_ioctl_locked(kbd, cmd, arg);
+		KMI_UNLOCK();
+		return (result);
+	}
+}
+
+
+/* clear the internal state of the keyboard */
+static void
+kmi_clear_state(keyboard_t *kbd)
+{
+	struct kmi_softc *sc = kbd->kb_data;
+
+	KMI_CTX_LOCK_ASSERT();
+
+	sc->sc_flags &= ~(KMI_FLAG_COMPOSE | KMI_FLAG_POLLING);
+	sc->sc_state &= LOCK_MASK;	/* preserve locking key state */
+	sc->sc_accents = 0;
+}
+
+/* save the internal state, not used */
+static int
+kmi_get_state(keyboard_t *kbd, void *buf, size_t len)
+{
+	return (len == 0) ? 1 : -1;
+}
+
+/* set the internal state, not used */
+static int
+kmi_set_state(keyboard_t *kbd, void *buf, size_t len)
+{
+	return (EINVAL);
+}
+
+static int
+kmi_poll(keyboard_t *kbd, int on)
+{
+	struct kmi_softc *sc = kbd->kb_data;
+
+	KMI_LOCK();
+	if (on) {
+		sc->sc_flags |= KMI_FLAG_POLLING;
+		sc->sc_poll_thread = curthread;
+	} else {
+		sc->sc_flags &= ~KMI_FLAG_POLLING;
+	}
+	KMI_UNLOCK();
+
+	return (0);
+}
+
+/* local functions */
+
+static void
+kmi_set_leds(struct kmi_softc *sc, uint8_t leds)
+{
+
+	KMI_LOCK_ASSERT();
+
+	/* start transfer, if not already started */
+	printf("Implement me: %s\n", __func__);
+}
+
+static int
+kmi_set_typematic(keyboard_t *kbd, int code)
+{
+	static const int delays[] = {250, 500, 750, 1000};
+	static const int rates[] = {34, 38, 42, 46, 50, 55, 59, 63,
+		68, 76, 84, 92, 100, 110, 118, 126,
+		136, 152, 168, 184, 200, 220, 236, 252,
+	272, 304, 336, 368, 400, 440, 472, 504};
+
+	if (code & ~0x7f) {
+		return (EINVAL);
+	}
+	kbd->kb_delay1 = delays[(code >> 5) & 3];
+	kbd->kb_delay2 = rates[code & 0x1f];
+	return (0);
+}
+
+static keyboard_switch_t kmisw = {
+	.probe = &kmi_probe,
+	.init = &kmi_init,
+	.term = &kmi_term,
+	.intr = &kmi_intr,
+	.test_if = &kmi_test_if,
+	.enable = &kmi_enable,
+	.disable = &kmi_disable,
+	.read = &kmi_read,
+	.check = &kmi_check,
+	.read_char = &kmi_read_char,
+	.check_char = &kmi_check_char,
+	.ioctl = &kmi_ioctl,
+	.lock = &kmi_lock,
+	.clear_state = &kmi_clear_state,
+	.get_state = &kmi_get_state,
+	.set_state = &kmi_set_state,
+	.get_fkeystr = &genkbd_get_fkeystr,
+	.poll = &kmi_poll,
+	.diag = &genkbd_diag,
+};
+
+KEYBOARD_DRIVER(kmi, kmisw, kmi_configure);
+
+static void
+pl050_kmi_intr(void *arg)
+{
+	struct kmi_softc *sc = arg;
+	uint32_t c;
+
+	KMI_CTX_LOCK_ASSERT();
+
+	if ((sc->sc_flags & KMI_FLAG_POLLING) != 0)
+		return;
+
+	if (KBD_IS_ACTIVE(&sc->sc_kbd) &&
+	    KBD_IS_BUSY(&sc->sc_kbd)) {
+		/* let the callback function process the input */
+		(sc->sc_kbd.kb_callback.kc_func) (&sc->sc_kbd, KBDIO_KEYINPUT,
+		    sc->sc_kbd.kb_callback.kc_arg);
+	} else {
+		/* read and discard the input, no one is waiting for it */
+		do {
+			c = kmi_read_char_locked(&sc->sc_kbd, 0);
+		} while (c != NOKEY);
+	}
+
+}
+
+static int
+pl050_kmi_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (ofw_bus_is_compatible(dev, "arm,pl050")) {
+		device_set_desc(dev, "PL050 Keyboard/Mouse Interface");
+		return (BUS_PROBE_DEFAULT);
+	}
+
+	return (ENXIO);
+}
+
+static int
+pl050_kmi_attach(device_t dev)
+{
+	struct kmi_softc *sc = device_get_softc(dev);
+	keyboard_t *kbd;
+	int rid;
+	int i;
+
+	kbd = &sc->sc_kbd;
+	rid = 0;
+
+	sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
+	if (sc->sc_mem_res == NULL) {
+		device_printf(dev, "could not allocate memory resource\n");
+		return (ENXIO);
+	}
+
+	/* Request the IRQ resources */
+	sc->sc_irq_res =  bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE);
+	if (sc->sc_irq_res == NULL) {
+		device_printf(dev, "Error: could not allocate irq resources\n");
+		return (ENXIO);
+	}
+
+	/* Setup and enable the timer */
+	if (bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_CLK,
+			NULL, pl050_kmi_intr, sc,
+			&sc->sc_intr_hl) != 0) {
+		bus_release_resource(dev, SYS_RES_IRQ, rid,
+			sc->sc_irq_res);
+		device_printf(dev, "Unable to setup the clock irq handler.\n");
+		return (ENXIO);
+	}
+
+	/* TODO: clock & divisor */
+
+	pl050_kmi_write_4(sc, KMICR, KMICR_EN | KMICR_RXINTREN);
+
+	kbd_init_struct(kbd, KMI_DRIVER_NAME, KB_OTHER, 
+			device_get_unit(dev), 0, 0, 0);
+	kbd->kb_data = (void *)sc;
+
+	sc->sc_keymap = key_map;
+	sc->sc_accmap = accent_map;
+	for (i = 0; i < KMI_NFKEY; i++) {
+		sc->sc_fkeymap[i] = fkey_tab[i];
+	}
+
+	kbd_set_maps(kbd, &sc->sc_keymap, &sc->sc_accmap,
+	    sc->sc_fkeymap, KMI_NFKEY);
+
+	KBD_FOUND_DEVICE(kbd);
+	kmi_clear_state(kbd);
+	KBD_PROBE_DONE(kbd);
+
+	KBD_INIT_DONE(kbd);
+
+	if (kbd_register(kbd) < 0) {
+		goto detach;
+	}
+	KBD_CONFIG_DONE(kbd);
+
+#ifdef KBD_INSTALL_CDEV
+	if (kbd_attach(kbd)) {
+		goto detach;
+	}
+#endif
+
+	if (bootverbose) {
+		genkbd_diag(kbd, bootverbose);
+	}
+	return (0);
+
+detach:
+	return (ENXIO);
+
+}
+
+static device_method_t pl050_kmi_methods[] = {
+	DEVMETHOD(device_probe,		pl050_kmi_probe),
+	DEVMETHOD(device_attach,	pl050_kmi_attach),
+	{ 0, 0 }
+};
+
+static driver_t pl050_kmi_driver = {
+	"kmi",
+	pl050_kmi_methods,
+	sizeof(struct kmi_softc),
+};
+
+static devclass_t pl050_kmi_devclass;
+
+DRIVER_MODULE(pl050_kmi, simplebus, pl050_kmi_driver, pl050_kmi_devclass, 0, 0);


Property changes on: trunk/sys/arm/versatile/pl050.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/versatile/sp804.c
===================================================================
--- trunk/sys/arm/versatile/sp804.c	                        (rev 0)
+++ trunk/sys/arm/versatile/sp804.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,363 @@
+/* $MidnightBSD$ */
+/*
+ * Copyright (c) 2012 Oleksandr Tymoshenko <gonzo at freebsd.org>
+ * Copyright (c) 2012 Damjan Marion <dmarion at freebsd.org>
+ * 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: stable/10/sys/arm/versatile/sp804.c 266152 2014-05-15 16:11:06Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/timeet.h>
+#include <sys/timetc.h>
+#include <sys/watchdog.h>
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+
+#define	SP804_TIMER1_LOAD	0x00
+#define	SP804_TIMER1_VALUE	0x04
+#define	SP804_TIMER1_CONTROL	0x08
+#define		TIMER_CONTROL_EN	(1 << 7)
+#define		TIMER_CONTROL_FREERUN	(0 << 6)
+#define		TIMER_CONTROL_PERIODIC	(1 << 6)
+#define		TIMER_CONTROL_INTREN	(1 << 5)
+#define		TIMER_CONTROL_DIV1	(0 << 2)
+#define		TIMER_CONTROL_DIV16	(1 << 2)
+#define		TIMER_CONTROL_DIV256	(2 << 2)
+#define		TIMER_CONTROL_32BIT	(1 << 1)
+#define		TIMER_CONTROL_ONESHOT	(1 << 0)
+#define	SP804_TIMER1_INTCLR	0x0C
+#define	SP804_TIMER1_RIS	0x10
+#define	SP804_TIMER1_MIS	0x14
+#define	SP804_TIMER1_BGLOAD	0x18
+#define	SP804_TIMER2_LOAD	0x20
+#define	SP804_TIMER2_VALUE	0x24
+#define	SP804_TIMER2_CONTROL	0x28
+#define	SP804_TIMER2_INTCLR	0x2C
+#define	SP804_TIMER2_RIS	0x30
+#define	SP804_TIMER2_MIS	0x34
+#define	SP804_TIMER2_BGLOAD	0x38
+
+#define	SP804_PERIPH_ID0	0xFE0
+#define	SP804_PERIPH_ID1	0xFE4
+#define	SP804_PERIPH_ID2	0xFE8
+#define	SP804_PERIPH_ID3	0xFEC
+#define	SP804_PRIMECELL_ID0	0xFF0
+#define	SP804_PRIMECELL_ID1	0xFF4
+#define	SP804_PRIMECELL_ID2	0xFF8
+#define	SP804_PRIMECELL_ID3	0xFFC
+
+#define	DEFAULT_FREQUENCY	1000000
+/*
+ * QEMU seems to have problem with full frequency
+ */
+#define	DEFAULT_DIVISOR		16
+#define	DEFAULT_CONTROL_DIV	TIMER_CONTROL_DIV16
+
+struct sp804_timer_softc {
+	struct resource*	mem_res;
+	struct resource*	irq_res;
+	void*			intr_hl;
+	uint32_t		sysclk_freq;
+	bus_space_tag_t		bst;
+	bus_space_handle_t	bsh;
+	struct timecounter	tc;
+	bool			et_enabled;
+	struct eventtimer	et;
+	int			timer_initialized;
+};
+
+/* Read/Write macros for Timer used as timecounter */
+#define sp804_timer_tc_read_4(reg)		\
+	bus_space_read_4(sc->bst, sc->bsh, reg)
+
+#define sp804_timer_tc_write_4(reg, val)	\
+	bus_space_write_4(sc->bst, sc->bsh, reg, val)
+
+static unsigned sp804_timer_tc_get_timecount(struct timecounter *);
+
+static unsigned
+sp804_timer_tc_get_timecount(struct timecounter *tc)
+{
+	struct sp804_timer_softc *sc = tc->tc_priv;
+	return 0xffffffff - sp804_timer_tc_read_4(SP804_TIMER1_VALUE);
+}
+
+static int
+sp804_timer_start(struct eventtimer *et, sbintime_t first, sbintime_t period)
+{
+	struct sp804_timer_softc *sc = et->et_priv;
+	uint32_t count, reg;
+
+	if (first != 0) {
+		sc->et_enabled = 1;
+
+		count = ((uint32_t)et->et_frequency * first) >> 32;
+
+		sp804_timer_tc_write_4(SP804_TIMER2_LOAD, count);
+		reg = TIMER_CONTROL_32BIT | TIMER_CONTROL_INTREN |
+		    TIMER_CONTROL_PERIODIC | DEFAULT_CONTROL_DIV |
+		    TIMER_CONTROL_EN;
+		sp804_timer_tc_write_4(SP804_TIMER2_CONTROL, reg);
+
+		return (0);
+	} 
+
+	if (period != 0) {
+		panic("period");
+	}
+
+	return (EINVAL);
+}
+
+static int
+sp804_timer_stop(struct eventtimer *et)
+{
+	struct sp804_timer_softc *sc = et->et_priv;
+	uint32_t reg;
+
+	sc->et_enabled = 0;
+	reg = sp804_timer_tc_read_4(SP804_TIMER2_CONTROL);
+	reg &= ~(TIMER_CONTROL_EN);
+	sp804_timer_tc_write_4(SP804_TIMER2_CONTROL, reg);
+
+	return (0);
+}
+
+static int
+sp804_timer_intr(void *arg)
+{
+	struct sp804_timer_softc *sc = arg;
+	static uint32_t prev = 0;
+	uint32_t x = 0;
+
+	x = sp804_timer_tc_read_4(SP804_TIMER1_VALUE);
+
+	prev =x ;
+	sp804_timer_tc_write_4(SP804_TIMER2_INTCLR, 1);
+	if (sc->et_enabled) {
+		if (sc->et.et_active) {
+			sc->et.et_event_cb(&sc->et, sc->et.et_arg);
+		}
+	}
+
+	return (FILTER_HANDLED);
+}
+
+static int
+sp804_timer_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (ofw_bus_is_compatible(dev, "arm,sp804")) {
+		device_set_desc(dev, "SP804 System Timer");
+		return (BUS_PROBE_DEFAULT);
+	}
+
+	return (ENXIO);
+}
+
+static int
+sp804_timer_attach(device_t dev)
+{
+	struct sp804_timer_softc *sc = device_get_softc(dev);
+	int rid = 0;
+	int i;
+	uint32_t id, reg;
+	phandle_t node;
+	pcell_t clock;
+
+	sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
+	if (sc->mem_res == NULL) {
+		device_printf(dev, "could not allocate memory resource\n");
+		return (ENXIO);
+	}
+
+	sc->bst = rman_get_bustag(sc->mem_res);
+	sc->bsh = rman_get_bushandle(sc->mem_res);
+
+	/* Request the IRQ resources */
+	sc->irq_res =  bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE);
+	if (sc->irq_res == NULL) {
+		device_printf(dev, "Error: could not allocate irq resources\n");
+		return (ENXIO);
+	}
+
+	sc->sysclk_freq = DEFAULT_FREQUENCY;
+	/* Get the base clock frequency */
+	node = ofw_bus_get_node(dev);
+	if ((OF_getprop(node, "clock-frequency", &clock, sizeof(clock))) > 0) {
+		sc->sysclk_freq = fdt32_to_cpu(clock);
+	}
+
+	/* Setup and enable the timer */
+	if (bus_setup_intr(dev, sc->irq_res, INTR_TYPE_CLK,
+			sp804_timer_intr, NULL, sc,
+			&sc->intr_hl) != 0) {
+		bus_release_resource(dev, SYS_RES_IRQ, rid,
+			sc->irq_res);
+		device_printf(dev, "Unable to setup the clock irq handler.\n");
+		return (ENXIO);
+	}
+
+	sp804_timer_tc_write_4(SP804_TIMER1_CONTROL, 0);
+	sp804_timer_tc_write_4(SP804_TIMER2_CONTROL, 0);
+
+	/*
+	 * Timer 1, timecounter
+	 */
+	sc->tc.tc_frequency = sc->sysclk_freq;
+	sc->tc.tc_name = "SP804 Time Counter";
+	sc->tc.tc_get_timecount = sp804_timer_tc_get_timecount;
+	sc->tc.tc_poll_pps = NULL;
+	sc->tc.tc_counter_mask = ~0u;
+	sc->tc.tc_quality = 1000;
+	sc->tc.tc_priv = sc;
+
+	sp804_timer_tc_write_4(SP804_TIMER1_VALUE, 0xffffffff);
+	sp804_timer_tc_write_4(SP804_TIMER1_LOAD, 0xffffffff);
+	reg = TIMER_CONTROL_PERIODIC | TIMER_CONTROL_32BIT;
+	sp804_timer_tc_write_4(SP804_TIMER1_CONTROL, reg);
+	reg |= TIMER_CONTROL_EN;
+	sp804_timer_tc_write_4(SP804_TIMER1_CONTROL, reg);
+	tc_init(&sc->tc);
+
+	/* 
+	 * Timer 2, event timer
+	 */
+	sc->et_enabled = 0;
+	sc->et.et_name = malloc(64, M_DEVBUF, M_NOWAIT | M_ZERO);
+	sprintf(sc->et.et_name, "SP804 Event Timer %d",
+		device_get_unit(dev));
+	sc->et.et_flags = ET_FLAGS_PERIODIC | ET_FLAGS_ONESHOT;
+	sc->et.et_quality = 1000;
+	sc->et.et_frequency = sc->sysclk_freq / DEFAULT_DIVISOR;
+	sc->et.et_min_period = (0x00000002LLU << 32) / sc->et.et_frequency;
+	sc->et.et_max_period = (0xfffffffeLLU << 32) / sc->et.et_frequency;
+	sc->et.et_start = sp804_timer_start;
+	sc->et.et_stop = sp804_timer_stop;
+	sc->et.et_priv = sc;
+	et_register(&sc->et);
+
+	id = 0;
+	for (i = 3; i >= 0; i--) {
+		id = (id << 8) | 
+		     (sp804_timer_tc_read_4(SP804_PERIPH_ID0 + i*4) & 0xff);
+	}
+
+	device_printf(dev, "peripheral ID: %08x\n", id);
+
+	id = 0;
+	for (i = 3; i >= 0; i--) {
+		id = (id << 8) | 
+		     (sp804_timer_tc_read_4(SP804_PRIMECELL_ID0 + i*4) & 0xff);
+	}
+
+	device_printf(dev, "PrimeCell ID: %08x\n", id);
+
+	sc->timer_initialized = 1;
+
+	return (0);
+}
+
+static device_method_t sp804_timer_methods[] = {
+	DEVMETHOD(device_probe,		sp804_timer_probe),
+	DEVMETHOD(device_attach,	sp804_timer_attach),
+	{ 0, 0 }
+};
+
+static driver_t sp804_timer_driver = {
+	"timer",
+	sp804_timer_methods,
+	sizeof(struct sp804_timer_softc),
+};
+
+static devclass_t sp804_timer_devclass;
+
+DRIVER_MODULE(sp804_timer, simplebus, sp804_timer_driver, sp804_timer_devclass, 0, 0);
+
+void
+DELAY(int usec)
+{
+	int32_t counts;
+	uint32_t first, last;
+	device_t timer_dev;
+	struct sp804_timer_softc *sc;
+	int timer_initialized = 0;
+
+	timer_dev = devclass_get_device(sp804_timer_devclass, 0);
+
+	if (timer_dev) {
+		sc = device_get_softc(timer_dev);
+
+		if (sc)
+			timer_initialized = sc->timer_initialized;
+	}
+
+	if (!timer_initialized) {
+		/*
+		 * Timer is not initialized yet
+		 */
+		for (; usec > 0; usec--)
+			for (counts = 200; counts > 0; counts--)
+				/* Prevent gcc from optimizing  out the loop */
+				cpufunc_nullop();
+		return;
+	}
+
+	/* Get the number of times to count */
+	counts = usec * ((sc->tc.tc_frequency / 1000000) + 1);
+
+	first = sp804_timer_tc_get_timecount(&sc->tc);
+
+	while (counts > 0) {
+		last = sp804_timer_tc_get_timecount(&sc->tc);
+		if (last == first)
+			continue;
+		if (last>first) {
+			counts -= (int32_t)(last - first);
+		} else {
+			counts -= (int32_t)((0xFFFFFFFF - first) + last);
+		}
+		first = last;
+	}
+}


Property changes on: trunk/sys/arm/versatile/sp804.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/versatile/versatile_clcd.c
===================================================================
--- trunk/sys/arm/versatile/versatile_clcd.c	                        (rev 0)
+++ trunk/sys/arm/versatile/versatile_clcd.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,962 @@
+/* $MidnightBSD$ */
+/*
+ * Copyright (c) 2012 Oleksandr Tymoshenko <gonzo at freebsd.org>
+ * 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: stable/10/sys/arm/versatile/versatile_clcd.c 266152 2014-05-15 16:11:06Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/fbio.h>
+#include <sys/consio.h>
+#include <sys/kdb.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <dev/fb/fbreg.h>
+#include <dev/syscons/syscons.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+
+#define	PL110_VENDOR_ARM926PXP	1
+
+#define	MEM_SYS		0
+#define	MEM_CLCD	1
+#define MEM_REGIONS	2
+
+#define	SYS_CLCD		0x00
+#define		SYS_CLCD_CLCDID_SHIFT	0x08
+#define		SYS_CLCD_CLCDID_MASK	0x1f
+#define		SYS_CLCD_PWR3V5VSWITCH	(1 << 4)
+#define		SYS_CLCD_VDDPOSSWITCH 	(1 << 3)
+#define		SYS_CLCD_NLCDIOON  	(1 << 2)
+#define		SYS_CLCD_LCD_MODE_MASK	0x03
+
+#define	CLCD_MODE_RGB888	0x0
+#define	CLCD_MODE_RGB555	0x01
+#define	CLCD_MODE_RBG565	0x02
+#define	CLCD_MODE_RGB565	0x03
+
+#define	CLCDC_TIMING0		0x00
+#define	CLCDC_TIMING1		0x04
+#define	CLCDC_TIMING2		0x08
+#define	CLCDC_TIMING3		0x0C
+#define	CLCDC_TIMING3		0x0C
+#define	CLCDC_UPBASE		0x10
+#define	CLCDC_LPBASE		0x14
+#ifdef PL110_VENDOR_ARM926PXP
+#define	CLCDC_CONTROL		0x18
+#define	CLCDC_IMSC		0x1C
+#else
+#define	CLCDC_IMSC		0x18
+#define	CLCDC_CONTROL		0x1C
+#endif
+#define		CONTROL_WATERMARK	(1 << 16)
+#define		CONTROL_VCOMP_VS	(0 << 12)
+#define		CONTROL_VCOMP_BP	(1 << 12)
+#define		CONTROL_VCOMP_SAV	(2 << 12)
+#define		CONTROL_VCOMP_FP	(3 << 12)
+#define		CONTROL_PWR		(1 << 11)
+#define		CONTROL_BEPO		(1 << 10)
+#define		CONTROL_BEBO		(1 << 9)
+#define		CONTROL_BGR		(1 << 8)
+#define		CONTROL_DUAL		(1 << 7)
+#define		CONTROL_MONO8		(1 << 6)
+#define		CONTROL_TFT		(1 << 5)
+#define		CONTROL_BW		(1 << 4)
+#define		CONTROL_BPP1		(0x00 << 1)
+#define		CONTROL_BPP2		(0x01 << 1)
+#define		CONTROL_BPP4		(0x02 << 1)
+#define		CONTROL_BPP8		(0x03 << 1)
+#define		CONTROL_BPP16		(0x04 << 1)
+#define		CONTROL_BPP24		(0x05 << 1)
+#define		CONTROL_EN	(1 << 0)
+#define	CLCDC_RIS		0x20
+#define	CLCDC_MIS		0x24
+#define		INTR_MBERR		(1 << 4)
+#define		INTR_VCOMP		(1 << 3)
+#define		INTR_LNB		(1 << 2)
+#define		INTR_FUF		(1 << 1)
+#define	CLCDC_ICR		0x28
+
+#ifdef DEBUG
+#define dprintf(fmt, args...) do { printf("%s(): ", __func__);   \
+    printf(fmt,##args); } while (0)
+#else
+#define dprintf(fmt, args...)
+#endif
+
+#define	versatile_clcdc_sys_read_4(sc, reg)	\
+	bus_read_4((sc)->mem_res[MEM_SYS], (reg))
+#define	versatile_clcdc_sys_write_4(sc, reg, val)	\
+	bus_write_4((sc)->mem_res[MEM_SYS], (reg), (val))
+
+#define	versatile_clcdc_read_4(sc, reg)	\
+	bus_read_4((sc)->mem_res[MEM_CLCD], (reg))
+#define	versatile_clcdc_write_4(sc, reg, val)	\
+	bus_write_4((sc)->mem_res[MEM_CLCD], (reg), (val))
+
+struct versatile_clcdc_softc {
+	struct resource*	mem_res[MEM_REGIONS];
+
+	struct mtx		mtx;
+
+	int			width;
+	int			height;
+	int			mode;
+
+	bus_dma_tag_t		dma_tag;
+	bus_dmamap_t		dma_map;
+	bus_addr_t		fb_phys;
+	uint8_t			*fb_base;
+
+};
+
+struct video_adapter_softc {
+	/* Videoadpater part */
+	video_adapter_t	va;
+	int		console;
+
+	intptr_t	fb_addr;
+	unsigned int	fb_size;
+
+	unsigned int	height;
+	unsigned int	width;
+	unsigned int	depth;
+	unsigned int	stride;
+
+	unsigned int	xmargin;
+	unsigned int	ymargin;
+
+	unsigned char	*font;
+	int		initialized;
+};
+
+struct argb {
+	uint8_t		a;
+	uint8_t		r;
+	uint8_t		g;
+	uint8_t		b;
+};
+
+static struct argb versatilefb_palette[16] = {
+	{0x00, 0x00, 0x00, 0x00},
+	{0x00, 0x00, 0x00, 0xaa},
+	{0x00, 0x00, 0xaa, 0x00},
+	{0x00, 0x00, 0xaa, 0xaa},
+	{0x00, 0xaa, 0x00, 0x00},
+	{0x00, 0xaa, 0x00, 0xaa},
+	{0x00, 0xaa, 0x55, 0x00},
+	{0x00, 0xaa, 0xaa, 0xaa},
+	{0x00, 0x55, 0x55, 0x55},
+	{0x00, 0x55, 0x55, 0xff},
+	{0x00, 0x55, 0xff, 0x55},
+	{0x00, 0x55, 0xff, 0xff},
+	{0x00, 0xff, 0x55, 0x55},
+	{0x00, 0xff, 0x55, 0xff},
+	{0x00, 0xff, 0xff, 0x55},
+	{0x00, 0xff, 0xff, 0xff}
+};
+
+/* mouse pointer from dev/syscons/scgfbrndr.c */
+static u_char mouse_pointer[16] = {
+        0x00, 0x40, 0x60, 0x70, 0x78, 0x7c, 0x7e, 0x68,
+        0x0c, 0x0c, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00
+};
+
+#define FB_WIDTH		640
+#define FB_HEIGHT		480
+#define FB_DEPTH		16
+
+#define	VERSATILE_FONT_HEIGHT	16
+
+static struct video_adapter_softc va_softc;
+
+static struct resource_spec versatile_clcdc_mem_spec[] = {
+	{ SYS_RES_MEMORY, 0, RF_ACTIVE },
+	{ SYS_RES_MEMORY, 1, RF_ACTIVE },
+	{ -1, 0, 0 }
+};
+
+static int versatilefb_configure(int);
+static void versatilefb_update_margins(video_adapter_t *adp);
+
+static void
+versatile_fb_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int err)
+{
+	bus_addr_t *addr;
+
+	if (err)
+		return;
+
+	addr = (bus_addr_t*)arg;
+	*addr = segs[0].ds_addr;
+}
+
+static int
+versatile_clcdc_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (ofw_bus_is_compatible(dev, "arm,pl110")) {
+		device_set_desc(dev, "PL110 CLCD controller");
+		return (BUS_PROBE_DEFAULT);
+	}
+
+	return (ENXIO);
+}
+
+static int
+versatile_clcdc_attach(device_t dev)
+{
+	struct versatile_clcdc_softc *sc = device_get_softc(dev);
+	struct video_adapter_softc *va_sc = &va_softc;
+	int err;
+	uint32_t reg;
+	int clcdid;
+	int dma_size;
+
+	/* Request memory resources */
+	err = bus_alloc_resources(dev, versatile_clcdc_mem_spec,
+		sc->mem_res);
+	if (err) {
+		device_printf(dev, "Error: could not allocate memory resources\n");
+		return (ENXIO);
+	}
+
+	reg = versatile_clcdc_sys_read_4(sc, SYS_CLCD);
+	clcdid = (reg >> SYS_CLCD_CLCDID_SHIFT) & SYS_CLCD_CLCDID_MASK;
+	switch (clcdid) {
+		case 31:
+			device_printf(dev, "QEMU VGA 640x480\n");
+			sc->width = 640;
+			sc->height = 480;
+			break;
+		default:
+			device_printf(dev, "Unsupported: %d\n", clcdid);
+			goto fail;
+	}
+
+	reg &= ~SYS_CLCD_LCD_MODE_MASK;
+	reg |= CLCD_MODE_RGB565;
+	sc->mode = CLCD_MODE_RGB565;
+	versatile_clcdc_sys_write_4(sc, SYS_CLCD, reg);
+	dma_size = sc->width*sc->height*2;
+
+	/*
+	 * Power on LCD
+	 */
+	reg |= SYS_CLCD_PWR3V5VSWITCH | SYS_CLCD_NLCDIOON;
+	versatile_clcdc_sys_write_4(sc, SYS_CLCD, reg);
+
+	/*
+	 * XXX: hardcoded timing for VGA. For other modes/panels
+	 * we need to keep table of timing register values
+	 */
+	/*
+	 * XXX: set SYS_OSC1 
+	 */
+	versatile_clcdc_write_4(sc, CLCDC_TIMING0, 0x3F1F3F9C);
+	versatile_clcdc_write_4(sc, CLCDC_TIMING1, 0x090B61DF);
+	versatile_clcdc_write_4(sc, CLCDC_TIMING2, 0x067F1800);
+	/* XXX: timing 3? */
+
+	/*
+	 * Now allocate framebuffer memory
+	 */
+	err = bus_dma_tag_create(
+	    bus_get_dma_tag(dev),
+	    4, 0,		/* alignment, boundary */
+	    BUS_SPACE_MAXADDR_32BIT,	/* lowaddr */
+	    BUS_SPACE_MAXADDR,		/* highaddr */
+	    NULL, NULL,			/* filter, filterarg */
+	    dma_size, 1,		/* maxsize, nsegments */
+	    dma_size, 0,		/* maxsegsize, flags */
+	    NULL, NULL,			/* lockfunc, lockarg */
+	    &sc->dma_tag);
+
+	err = bus_dmamem_alloc(sc->dma_tag, (void **)&sc->fb_base,
+	    0, &sc->dma_map);
+	if (err) {
+		device_printf(dev, "cannot allocate framebuffer\n");
+		goto fail;
+	}
+
+	err = bus_dmamap_load(sc->dma_tag, sc->dma_map, sc->fb_base,
+	    dma_size, versatile_fb_dmamap_cb, &sc->fb_phys, BUS_DMA_NOWAIT);
+
+	if (err) {
+		device_printf(dev, "cannot load DMA map\n");
+		goto fail;
+	}
+
+	/* Make sure it's blank */
+	memset(sc->fb_base, 0x00, dma_size);
+
+	versatile_clcdc_write_4(sc, CLCDC_UPBASE, sc->fb_phys);
+
+	err = (sc_attach_unit(device_get_unit(dev),
+	    device_get_flags(dev) | SC_AUTODETECT_KBD));
+
+	if (err) {
+		device_printf(dev, "failed to attach syscons\n");
+		goto fail;
+	}
+
+	/*
+	 * XXX: hardcoded for VGA
+	 */
+	reg = CONTROL_VCOMP_BP | CONTROL_TFT | CONTROL_BGR | CONTROL_EN;
+	reg |= CONTROL_BPP16;
+	versatile_clcdc_write_4(sc, CLCDC_CONTROL, reg);
+	DELAY(20);
+	reg |= CONTROL_PWR;
+	versatile_clcdc_write_4(sc, CLCDC_CONTROL, reg);
+
+	va_sc->fb_addr = (vm_offset_t)sc->fb_base;
+	va_sc->fb_size = dma_size;
+	va_sc->width = sc->width;
+	va_sc->height = sc->height;
+	va_sc->depth = 16;
+	va_sc->stride = sc->width * 2;
+	versatilefb_update_margins(&va_sc->va);
+
+	return (0);
+
+fail:
+	if (sc->fb_base)
+		bus_dmamem_free(sc->dma_tag, sc->fb_base, sc->dma_map);
+	if (sc->dma_map)
+		bus_dmamap_destroy(sc->dma_tag, sc->dma_map);
+	if (sc->dma_tag)
+		bus_dma_tag_destroy(sc->dma_tag);
+	return (err);
+}
+
+static device_method_t versatile_clcdc_methods[] = {
+	DEVMETHOD(device_probe,		versatile_clcdc_probe),
+	DEVMETHOD(device_attach,	versatile_clcdc_attach),
+
+	DEVMETHOD_END
+};
+
+static driver_t versatile_clcdc_driver = {
+	"clcdc",
+	versatile_clcdc_methods,
+	sizeof(struct versatile_clcdc_softc),
+};
+
+static devclass_t versatile_clcdc_devclass;
+
+DRIVER_MODULE(versatile_clcdc, simplebus, versatile_clcdc_driver, versatile_clcdc_devclass, 0, 0);
+
+/*
+ * Video driver routines and glue.
+ */
+static vi_probe_t		versatilefb_probe;
+static vi_init_t		versatilefb_init;
+static vi_get_info_t		versatilefb_get_info;
+static vi_query_mode_t		versatilefb_query_mode;
+static vi_set_mode_t		versatilefb_set_mode;
+static vi_save_font_t		versatilefb_save_font;
+static vi_load_font_t		versatilefb_load_font;
+static vi_show_font_t		versatilefb_show_font;
+static vi_save_palette_t	versatilefb_save_palette;
+static vi_load_palette_t	versatilefb_load_palette;
+static vi_set_border_t		versatilefb_set_border;
+static vi_save_state_t		versatilefb_save_state;
+static vi_load_state_t		versatilefb_load_state;
+static vi_set_win_org_t		versatilefb_set_win_org;
+static vi_read_hw_cursor_t	versatilefb_read_hw_cursor;
+static vi_set_hw_cursor_t	versatilefb_set_hw_cursor;
+static vi_set_hw_cursor_shape_t	versatilefb_set_hw_cursor_shape;
+static vi_blank_display_t	versatilefb_blank_display;
+static vi_mmap_t		versatilefb_mmap;
+static vi_ioctl_t		versatilefb_ioctl;
+static vi_clear_t		versatilefb_clear;
+static vi_fill_rect_t		versatilefb_fill_rect;
+static vi_bitblt_t		versatilefb_bitblt;
+static vi_diag_t		versatilefb_diag;
+static vi_save_cursor_palette_t	versatilefb_save_cursor_palette;
+static vi_load_cursor_palette_t	versatilefb_load_cursor_palette;
+static vi_copy_t		versatilefb_copy;
+static vi_putp_t		versatilefb_putp;
+static vi_putc_t		versatilefb_putc;
+static vi_puts_t		versatilefb_puts;
+static vi_putm_t		versatilefb_putm;
+
+static video_switch_t versatilefbvidsw = {
+	.probe			= versatilefb_probe,
+	.init			= versatilefb_init,
+	.get_info		= versatilefb_get_info,
+	.query_mode		= versatilefb_query_mode,
+	.set_mode		= versatilefb_set_mode,
+	.save_font		= versatilefb_save_font,
+	.load_font		= versatilefb_load_font,
+	.show_font		= versatilefb_show_font,
+	.save_palette		= versatilefb_save_palette,
+	.load_palette		= versatilefb_load_palette,
+	.set_border		= versatilefb_set_border,
+	.save_state		= versatilefb_save_state,
+	.load_state		= versatilefb_load_state,
+	.set_win_org		= versatilefb_set_win_org,
+	.read_hw_cursor		= versatilefb_read_hw_cursor,
+	.set_hw_cursor		= versatilefb_set_hw_cursor,
+	.set_hw_cursor_shape	= versatilefb_set_hw_cursor_shape,
+	.blank_display		= versatilefb_blank_display,
+	.mmap			= versatilefb_mmap,
+	.ioctl			= versatilefb_ioctl,
+	.clear			= versatilefb_clear,
+	.fill_rect		= versatilefb_fill_rect,
+	.bitblt			= versatilefb_bitblt,
+	.diag			= versatilefb_diag,
+	.save_cursor_palette	= versatilefb_save_cursor_palette,
+	.load_cursor_palette	= versatilefb_load_cursor_palette,
+	.copy			= versatilefb_copy,
+	.putp			= versatilefb_putp,
+	.putc			= versatilefb_putc,
+	.puts			= versatilefb_puts,
+	.putm			= versatilefb_putm,
+};
+
+VIDEO_DRIVER(versatilefb, versatilefbvidsw, versatilefb_configure);
+
+static vr_init_t clcdr_init;
+static vr_clear_t clcdr_clear;
+static vr_draw_border_t clcdr_draw_border;
+static vr_draw_t clcdr_draw;
+static vr_set_cursor_t clcdr_set_cursor;
+static vr_draw_cursor_t clcdr_draw_cursor;
+static vr_blink_cursor_t clcdr_blink_cursor;
+static vr_set_mouse_t clcdr_set_mouse;
+static vr_draw_mouse_t clcdr_draw_mouse;
+
+/*
+ * We use our own renderer; this is because we must emulate a hardware
+ * cursor.
+ */
+static sc_rndr_sw_t clcdrend = {
+	clcdr_init,
+	clcdr_clear,
+	clcdr_draw_border,
+	clcdr_draw,
+	clcdr_set_cursor,
+	clcdr_draw_cursor,
+	clcdr_blink_cursor,
+	clcdr_set_mouse,
+	clcdr_draw_mouse
+};
+
+RENDERER(versatilefb, 0, clcdrend, gfb_set);
+RENDERER_MODULE(versatilefb, gfb_set);
+
+static void
+clcdr_init(scr_stat* scp)
+{
+}
+
+static void
+clcdr_clear(scr_stat* scp, int c, int attr)
+{
+}
+
+static void
+clcdr_draw_border(scr_stat* scp, int color)
+{
+}
+
+static void
+clcdr_draw(scr_stat* scp, int from, int count, int flip)
+{
+	video_adapter_t* adp = scp->sc->adp;
+	int i, c, a;
+
+	if (!flip) {
+		/* Normal printing */
+		vidd_puts(adp, from, (uint16_t*)sc_vtb_pointer(&scp->vtb, from), count);
+	} else {	
+		/* This is for selections and such: invert the color attribute */
+		for (i = count; i-- > 0; ++from) {
+			c = sc_vtb_getc(&scp->vtb, from);
+			a = sc_vtb_geta(&scp->vtb, from) >> 8;
+			vidd_putc(adp, from, c, (a >> 4) | ((a & 0xf) << 4));
+		}
+	}
+}
+
+static void
+clcdr_set_cursor(scr_stat* scp, int base, int height, int blink)
+{
+}
+
+static void
+clcdr_draw_cursor(scr_stat* scp, int off, int blink, int on, int flip)
+{
+	video_adapter_t* adp = scp->sc->adp;
+	struct video_adapter_softc *sc;
+	int row, col;
+	uint8_t *addr;
+	int i,j;
+
+	sc = (struct video_adapter_softc *)adp;
+
+	if (scp->curs_attr.height <= 0)
+		return;
+
+	if (sc->fb_addr == 0)
+		return;
+
+	if (off >= adp->va_info.vi_width * adp->va_info.vi_height)
+		return;
+
+	/* calculate the coordinates in the video buffer */
+	row = (off / adp->va_info.vi_width) * adp->va_info.vi_cheight;
+	col = (off % adp->va_info.vi_width) * adp->va_info.vi_cwidth;
+
+	addr = (uint8_t *)sc->fb_addr
+	    + (row + sc->ymargin)*(sc->stride)
+	    + (sc->depth/8) * (col + sc->xmargin);
+
+	/* our cursor consists of simply inverting the char under it */
+	for (i = 0; i < adp->va_info.vi_cheight; i++) {
+		for (j = 0; j < adp->va_info.vi_cwidth; j++) {
+
+			addr[2*j] ^= 0xff;
+			addr[2*j + 1] ^= 0xff;
+		}
+
+		addr += sc->stride;
+	}
+}
+
+static void
+clcdr_blink_cursor(scr_stat* scp, int at, int flip)
+{
+}
+
+static void
+clcdr_set_mouse(scr_stat* scp)
+{
+}
+
+static void
+clcdr_draw_mouse(scr_stat* scp, int x, int y, int on)
+{
+	vidd_putm(scp->sc->adp, x, y, mouse_pointer, 0xffffffff, 16, 8);
+
+}
+
+static uint16_t versatilefb_static_window[ROW*COL];
+extern u_char dflt_font_16[];
+
+/*
+ * Update videoadapter settings after changing resolution
+ */
+static void
+versatilefb_update_margins(video_adapter_t *adp)
+{
+	struct video_adapter_softc *sc;
+	video_info_t *vi;
+
+	sc = (struct video_adapter_softc *)adp;
+	vi = &adp->va_info;
+
+	sc->xmargin = (sc->width - (vi->vi_width * vi->vi_cwidth)) / 2;
+	sc->ymargin = (sc->height - (vi->vi_height * vi->vi_cheight))/2;
+}
+
+static int
+versatilefb_configure(int flags)
+{
+	struct video_adapter_softc *va_sc;
+
+	va_sc = &va_softc;
+
+	if (va_sc->initialized)
+		return (0);
+
+	va_sc->width = FB_WIDTH;
+	va_sc->height = FB_HEIGHT;
+	va_sc->depth = FB_DEPTH;
+
+	versatilefb_init(0, &va_sc->va, 0);
+
+	va_sc->initialized = 1;
+
+	return (0);
+}
+
+static int
+versatilefb_probe(int unit, video_adapter_t **adp, void *arg, int flags)
+{
+
+	return (0);
+}
+
+static int
+versatilefb_init(int unit, video_adapter_t *adp, int flags)
+{
+	struct video_adapter_softc *sc;
+	video_info_t *vi;
+
+	sc = (struct video_adapter_softc *)adp;
+	vi = &adp->va_info;
+
+	vid_init_struct(adp, "versatilefb", -1, unit);
+
+	sc->font = dflt_font_16;
+	vi->vi_cheight = VERSATILE_FONT_HEIGHT;
+	vi->vi_cwidth = 8;
+
+	vi->vi_width = sc->width/8;
+	vi->vi_height = sc->height/vi->vi_cheight;
+
+	/*
+	 * Clamp width/height to syscons maximums
+	 */
+	if (vi->vi_width > COL)
+		vi->vi_width = COL;
+	if (vi->vi_height > ROW)
+		vi->vi_height = ROW;
+
+	sc->xmargin = (sc->width - (vi->vi_width * vi->vi_cwidth)) / 2;
+	sc->ymargin = (sc->height - (vi->vi_height * vi->vi_cheight))/2;
+
+
+	adp->va_window = (vm_offset_t) versatilefb_static_window;
+	adp->va_flags |= V_ADP_FONT /* | V_ADP_COLOR | V_ADP_MODECHANGE */;
+
+	vid_register(&sc->va);
+
+	return (0);
+}
+
+static int
+versatilefb_get_info(video_adapter_t *adp, int mode, video_info_t *info)
+{
+	bcopy(&adp->va_info, info, sizeof(*info));
+	return (0);
+}
+
+static int
+versatilefb_query_mode(video_adapter_t *adp, video_info_t *info)
+{
+	return (0);
+}
+
+static int
+versatilefb_set_mode(video_adapter_t *adp, int mode)
+{
+	return (0);
+}
+
+static int
+versatilefb_save_font(video_adapter_t *adp, int page, int size, int width,
+    u_char *data, int c, int count)
+{
+	return (0);
+}
+
+static int
+versatilefb_load_font(video_adapter_t *adp, int page, int size, int width,
+    u_char *data, int c, int count)
+{
+	struct video_adapter_softc *sc = (struct video_adapter_softc *)adp;
+
+	sc->font = data;
+
+	return (0);
+}
+
+static int
+versatilefb_show_font(video_adapter_t *adp, int page)
+{
+	return (0);
+}
+
+static int
+versatilefb_save_palette(video_adapter_t *adp, u_char *palette)
+{
+	return (0);
+}
+
+static int
+versatilefb_load_palette(video_adapter_t *adp, u_char *palette)
+{
+	return (0);
+}
+
+static int
+versatilefb_set_border(video_adapter_t *adp, int border)
+{
+	return (versatilefb_blank_display(adp, border));
+}
+
+static int
+versatilefb_save_state(video_adapter_t *adp, void *p, size_t size)
+{
+	return (0);
+}
+
+static int
+versatilefb_load_state(video_adapter_t *adp, void *p)
+{
+	return (0);
+}
+
+static int
+versatilefb_set_win_org(video_adapter_t *adp, off_t offset)
+{
+	return (0);
+}
+
+static int
+versatilefb_read_hw_cursor(video_adapter_t *adp, int *col, int *row)
+{
+	*col = *row = 0;
+
+	return (0);
+}
+
+static int
+versatilefb_set_hw_cursor(video_adapter_t *adp, int col, int row)
+{
+
+	return (0);
+}
+
+static int
+versatilefb_set_hw_cursor_shape(video_adapter_t *adp, int base, int height,
+    int celsize, int blink)
+{
+	return (0);
+}
+
+static int
+versatilefb_blank_display(video_adapter_t *adp, int mode)
+{
+
+	struct video_adapter_softc *sc;
+
+	sc = (struct video_adapter_softc *)adp;
+	if (sc && sc->fb_addr)
+		memset((void*)sc->fb_addr, 0, sc->fb_size);
+
+	return (0);
+}
+
+static int
+versatilefb_mmap(video_adapter_t *adp, vm_ooffset_t offset, vm_paddr_t *paddr,
+    int prot, vm_memattr_t *memattr)
+{
+	struct video_adapter_softc *sc;
+
+	sc = (struct video_adapter_softc *)adp;
+
+	/*
+	 * This might be a legacy VGA mem request: if so, just point it at the
+	 * framebuffer, since it shouldn't be touched
+	 */
+	if (offset < sc->stride*sc->height) {
+		*paddr = sc->fb_addr + offset;
+		return (0);
+	}
+
+	return (EINVAL);
+}
+
+static int
+versatilefb_ioctl(video_adapter_t *adp, u_long cmd, caddr_t data)
+{
+
+	return (0);
+}
+
+static int
+versatilefb_clear(video_adapter_t *adp)
+{
+
+	return (versatilefb_blank_display(adp, 0));
+}
+
+static int
+versatilefb_fill_rect(video_adapter_t *adp, int val, int x, int y, int cx, int cy)
+{
+
+	return (0);
+}
+
+static int
+versatilefb_bitblt(video_adapter_t *adp, ...)
+{
+
+	return (0);
+}
+
+static int
+versatilefb_diag(video_adapter_t *adp, int level)
+{
+
+	return (0);
+}
+
+static int
+versatilefb_save_cursor_palette(video_adapter_t *adp, u_char *palette)
+{
+
+	return (0);
+}
+
+static int
+versatilefb_load_cursor_palette(video_adapter_t *adp, u_char *palette)
+{
+
+	return (0);
+}
+
+static int
+versatilefb_copy(video_adapter_t *adp, vm_offset_t src, vm_offset_t dst, int n)
+{
+
+	return (0);
+}
+
+static int
+versatilefb_putp(video_adapter_t *adp, vm_offset_t off, uint32_t p, uint32_t a,
+    int size, int bpp, int bit_ltor, int byte_ltor)
+{
+
+	return (0);
+}
+
+static int
+versatilefb_putc(video_adapter_t *adp, vm_offset_t off, uint8_t c, uint8_t a)
+{
+	struct video_adapter_softc *sc;
+	int row;
+	int col;
+	int i, j, k;
+	uint8_t *addr;
+	u_char *p;
+	uint8_t fg, bg, color;
+	uint16_t rgb;
+
+	sc = (struct video_adapter_softc *)adp;
+
+	if (sc->fb_addr == 0)
+		return (0);
+
+	if (off >= adp->va_info.vi_width * adp->va_info.vi_height)
+		return (0);
+
+	row = (off / adp->va_info.vi_width) * adp->va_info.vi_cheight;
+	col = (off % adp->va_info.vi_width) * adp->va_info.vi_cwidth;
+	p = sc->font + c*VERSATILE_FONT_HEIGHT;
+	addr = (uint8_t *)sc->fb_addr
+	    + (row + sc->ymargin)*(sc->stride)
+	    + (sc->depth/8) * (col + sc->xmargin);
+
+	fg = a & 0xf ;
+	bg = (a >> 4) & 0xf;
+
+	for (i = 0; i < VERSATILE_FONT_HEIGHT; i++) {
+		for (j = 0, k = 7; j < 8; j++, k--) {
+			if ((p[i] & (1 << k)) == 0)
+				color = bg;
+			else
+				color = fg;
+
+			switch (sc->depth) {
+			case 16:
+				rgb = (versatilefb_palette[color].r >> 3) << 11;
+				rgb |= (versatilefb_palette[color].g >> 2) << 5;
+				rgb |= (versatilefb_palette[color].b >> 3);
+				addr[2*j] = rgb & 0xff;
+				addr[2*j + 1] = (rgb >> 8) & 0xff;
+			default:
+				/* Not supported yet */
+				break;
+			}
+		}
+
+		addr += (sc->stride);
+	}
+
+        return (0);
+}
+
+static int
+versatilefb_puts(video_adapter_t *adp, vm_offset_t off, u_int16_t *s, int len)
+{
+	int i;
+
+	for (i = 0; i < len; i++) 
+		versatilefb_putc(adp, off + i, s[i] & 0xff, (s[i] & 0xff00) >> 8);
+
+	return (0);
+}
+
+static int
+versatilefb_putm(video_adapter_t *adp, int x, int y, uint8_t *pixel_image,
+    uint32_t pixel_mask, int size, int width)
+{
+
+	return (0);
+}
+
+/*
+ * Define a stub keyboard driver in case one hasn't been
+ * compiled into the kernel
+ */
+#include <sys/kbio.h>
+#include <dev/kbd/kbdreg.h>
+
+static int dummy_kbd_configure(int flags);
+
+keyboard_switch_t bcmdummysw;
+
+static int
+dummy_kbd_configure(int flags)
+{
+
+	return (0);
+}
+KEYBOARD_DRIVER(bcmdummy, bcmdummysw, dummy_kbd_configure);


Property changes on: trunk/sys/arm/versatile/versatile_clcd.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/versatile/versatile_common.c
===================================================================
--- trunk/sys/arm/versatile/versatile_common.c	                        (rev 0)
+++ trunk/sys/arm/versatile/versatile_common.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,76 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (C) 2008-2011 MARVELL INTERNATIONAL LTD.
+ * All rights reserved.
+ *
+ * Developed by Semihalf.
+ *
+ * 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.
+ * 3. Neither the name of MARVELL nor the names of contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY 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 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_global.h"
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/versatile/versatile_common.c 266277 2014-05-17 00:53:12Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/kdb.h>
+#include <sys/reboot.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+#include <machine/vmparam.h>
+
+struct fdt_fixup_entry fdt_fixup_table[] = {
+	{ NULL, NULL }
+};
+
+static int
+fdt_intc_decode_ic(phandle_t node, pcell_t *intr, int *interrupt, int *trig,
+    int *pol)
+{
+
+	if (!fdt_is_compatible(node, "arm,versatile-vic"))
+		return (ENXIO);
+
+	*interrupt = fdt32_to_cpu(intr[0]);
+	*trig = INTR_TRIGGER_CONFORM;
+	*pol = INTR_POLARITY_CONFORM;
+
+	return (0);
+}
+
+
+fdt_pic_decode_t fdt_pic_table[] = {
+	&fdt_intc_decode_ic,
+	NULL
+};


Property changes on: trunk/sys/arm/versatile/versatile_common.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/versatile/versatile_machdep.c
===================================================================
--- trunk/sys/arm/versatile/versatile_machdep.c	                        (rev 0)
+++ trunk/sys/arm/versatile/versatile_machdep.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,128 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Oleksandr Tymoshenko.
+ * All rights reserved.
+ *
+ * This code is derived from software written for Brini by Mark Brinicombe
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by Brini.
+ * 4. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BRINI ``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 BRINI 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_ddb.h"
+#include "opt_platform.h"
+#include "opt_global.h"
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/versatile/versatile_machdep.c 259365 2013-12-14 00:16:08Z ian $");
+
+#define _ARM32_BUS_DMA_PRIVATE
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <machine/bus.h>
+#include <machine/devmap.h>
+#include <machine/machdep.h>
+
+#include <dev/fdt/fdt_common.h>
+
+/* Start of address space used for bootstrap map */
+#define DEVMAP_BOOTSTRAP_MAP_START	0xE0000000
+
+vm_offset_t
+initarm_lastaddr(void)
+{
+
+	return (DEVMAP_BOOTSTRAP_MAP_START);
+}
+
+void
+initarm_early_init(void)
+{
+
+}
+
+void
+initarm_gpio_init(void)
+{
+}
+
+void
+initarm_late_init(void)
+{
+}
+
+#define FDT_DEVMAP_MAX	(2)		/* FIXME */
+static struct arm_devmap_entry fdt_devmap[FDT_DEVMAP_MAX] = {
+	{ 0, 0, 0, 0, 0, },
+	{ 0, 0, 0, 0, 0, }
+};
+
+
+/*
+ * Construct pmap_devmap[] with DT-derived config data.
+ */
+int
+initarm_devmap_init(void)
+{
+	int i = 0;
+	fdt_devmap[i].pd_va = 0xf0100000;
+	fdt_devmap[i].pd_pa = 0x10100000;
+	fdt_devmap[i].pd_size = 0x01000000;       /* 1 MB */
+	fdt_devmap[i].pd_prot = VM_PROT_READ | VM_PROT_WRITE;
+	fdt_devmap[i].pd_cache = PTE_DEVICE;
+
+	arm_devmap_register_table(&fdt_devmap[0]);
+	return (0);
+}
+
+struct arm32_dma_range *
+bus_dma_get_range(void)
+{
+
+	return (NULL);
+}
+
+int
+bus_dma_get_range_nb(void)
+{
+
+	return (0);
+}
+
+void
+cpu_reset()
+{
+	printf("cpu_reset\n");
+	while (1);
+}
+


Property changes on: trunk/sys/arm/versatile/versatile_machdep.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/versatile/versatile_pci.c
===================================================================
--- trunk/sys/arm/versatile/versatile_pci.c	                        (rev 0)
+++ trunk/sys/arm/versatile/versatile_pci.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,518 @@
+/* $MidnightBSD$ */
+/*
+ * Copyright (c) 2012 Oleksandr Tymoshenko <gonzo at freebsd.org>
+ * 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: stable/10/sys/arm/versatile/versatile_pci.c 278727 2015-02-13 22:32:02Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/watchdog.h>
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcireg.h>
+
+#include <dev/pci/pcib_private.h>
+#include "pcib_if.h"
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+
+#define	MEM_SYS		0
+#define	MEM_CORE	1
+#define	MEM_BASE	2
+#define	MEM_CONF_BASE	3
+#define MEM_REGIONS	4
+
+#define	SYS_PCICTL		0x00
+
+#define	PCI_CORE_IMAP0		0x00
+#define	PCI_CORE_IMAP1		0x04
+#define	PCI_CORE_IMAP2		0x08
+#define	PCI_CORE_SELFID		0x0C
+#define	PCI_CORE_SMAP0		0x10
+#define	PCI_CORE_SMAP1		0x14
+#define	PCI_CORE_SMAP2		0x18
+
+#define	VERSATILE_PCI_DEV	0x030010ee
+#define	VERSATILE_PCI_CLASS	0x0b400000
+
+#define	PCI_IO_WINDOW		0x44000000
+#define	PCI_IO_SIZE		0x0c000000
+#define	PCI_NPREFETCH_WINDOW	0x50000000
+#define	PCI_NPREFETCH_SIZE	0x10000000
+#define	PCI_PREFETCH_WINDOW	0x60000000
+#define	PCI_PREFETCH_SIZE	0x10000000
+
+#define	VERSATILE_PCI_IRQ_START	27
+#define	VERSATILE_PCI_IRQ_END	30
+
+#ifdef DEBUG
+#define dprintf(fmt, args...) do { printf("%s(): ", __func__);   \
+    printf(fmt,##args); } while (0)
+#else
+#define dprintf(fmt, args...)
+#endif
+
+
+#define	versatile_pci_sys_read_4(reg)	\
+	bus_read_4(sc->mem_res[MEM_SYS], (reg))
+#define	versatile_pci_sys_write_4(reg, val)	\
+	bus_write_4(sc->mem_res[MEM_SYS], (reg), (val))
+
+#define	versatile_pci_core_read_4(reg)	\
+	bus_read_4(sc->mem_res[MEM_CORE], (reg))
+#define	versatile_pci_core_write_4(reg, val)	\
+	bus_write_4(sc->mem_res[MEM_CORE], (reg), (val))
+
+#define	versatile_pci_read_4(reg)	\
+	bus_read_4(sc->mem_res[MEM_BASE], (reg))
+#define	versatile_pci_write_4(reg, val)	\
+	bus_write_4(sc->mem_res[MEM_BASE], (reg), (val))
+
+#define	versatile_pci_conf_read_4(reg)	\
+	bus_read_4(sc->mem_res[MEM_CONF_BASE], (reg))
+#define	versatile_pci_conf_write_4(reg, val)	\
+	bus_write_4(sc->mem_res[MEM_CONF_BASE], (reg), (val))
+#define	versatile_pci_conf_write_2(reg, val)	\
+	bus_write_2(sc->mem_res[MEM_CONF_BASE], (reg), (val))
+#define	versatile_pci_conf_write_1(reg, val)	\
+	bus_write_1(sc->mem_res[MEM_CONF_BASE], (reg), (val))
+
+struct versatile_pci_softc {
+	struct resource*	mem_res[MEM_REGIONS];
+	struct resource*	irq_res;
+	void*			intr_hl;
+
+	int			pcib_slot;
+
+	/* Bus part */
+	int			busno;
+	struct rman		io_rman;
+	struct rman		irq_rman;
+	struct rman		mem_rman;
+
+	struct mtx		mtx;
+};
+
+static struct resource_spec versatile_pci_mem_spec[] = {
+	{ SYS_RES_MEMORY, 0, RF_ACTIVE },
+	{ SYS_RES_MEMORY, 1, RF_ACTIVE },
+	{ SYS_RES_MEMORY, 2, RF_ACTIVE },
+	{ SYS_RES_MEMORY, 3, RF_ACTIVE },
+	{ -1, 0, 0 }
+};
+
+static int
+versatile_pci_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (ofw_bus_is_compatible(dev, "versatile,pci")) {
+		device_set_desc(dev, "Versatile PCI controller");
+		return (BUS_PROBE_DEFAULT);
+	}
+
+	return (ENXIO);
+}
+
+static int
+versatile_pci_attach(device_t dev)
+{
+	struct versatile_pci_softc *sc = device_get_softc(dev);
+	int err;
+	int slot;
+	uint32_t vendordev_id, class_id;
+	uint32_t val;
+
+	/* Request memory resources */
+	err = bus_alloc_resources(dev, versatile_pci_mem_spec,
+		sc->mem_res);
+	if (err) {
+		device_printf(dev, "Error: could not allocate memory resources\n");
+		return (ENXIO);
+	}
+
+	/*
+	 * Setup memory windows
+	 */
+	versatile_pci_core_write_4(PCI_CORE_IMAP0, (PCI_IO_WINDOW >> 28));
+	versatile_pci_core_write_4(PCI_CORE_IMAP1, (PCI_NPREFETCH_WINDOW >> 28));
+	versatile_pci_core_write_4(PCI_CORE_IMAP2, (PCI_PREFETCH_WINDOW >> 28));
+
+	/*
+	 * XXX: this is SDRAM offset >> 28
+	 * Unused as of QEMU 1.5
+	 */
+	versatile_pci_core_write_4(PCI_CORE_SMAP0, (PCI_IO_WINDOW >> 28));
+	versatile_pci_core_write_4(PCI_CORE_SMAP1, (PCI_NPREFETCH_WINDOW >> 28));
+	versatile_pci_core_write_4(PCI_CORE_SMAP2, (PCI_NPREFETCH_WINDOW >> 28));
+
+	versatile_pci_sys_write_4(SYS_PCICTL, 1);
+
+	for (slot = 0; slot <= PCI_SLOTMAX; slot++) {
+		vendordev_id = versatile_pci_read_4((slot << 11) + PCIR_DEVVENDOR);
+		class_id = versatile_pci_read_4((slot << 11) + PCIR_REVID);
+		if ((vendordev_id == VERSATILE_PCI_DEV) &&
+		    (class_id == VERSATILE_PCI_CLASS))
+			break;
+	}
+
+	if (slot == (PCI_SLOTMAX + 1)) {
+		bus_release_resources(dev, versatile_pci_mem_spec,
+		    sc->mem_res);
+		device_printf(dev, "Versatile PCI core not found\n");
+		return (ENXIO);
+	}
+
+	sc->pcib_slot = slot;
+	device_printf(dev, "PCI core at slot #%d\n", slot);
+
+	versatile_pci_core_write_4(PCI_CORE_SELFID, slot);
+	val = versatile_pci_conf_read_4((slot << 11) + PCIR_COMMAND);
+	val |= (PCIM_CMD_BUSMASTEREN | PCIM_CMD_MEMEN | PCIM_CMD_MWRICEN);
+	versatile_pci_conf_write_4((slot << 11) + PCIR_COMMAND, val);
+
+	/* Again SDRAM start >> 28  */
+	versatile_pci_write_4((slot << 11) + PCIR_BAR(0), 0);
+	versatile_pci_write_4((slot << 11) + PCIR_BAR(1), 0);
+	versatile_pci_write_4((slot << 11) + PCIR_BAR(2), 0);
+
+	/* Prepare resource managers */
+	sc->mem_rman.rm_type = RMAN_ARRAY;
+	sc->mem_rman.rm_descr = "versatile PCI memory window";
+	if (rman_init(&sc->mem_rman) != 0 || 
+	    rman_manage_region(&sc->mem_rman, PCI_NPREFETCH_WINDOW, 
+		PCI_NPREFETCH_WINDOW + PCI_NPREFETCH_SIZE - 1) != 0) {
+		panic("versatile_pci_attach: failed to set up memory rman");
+	}
+
+	bootverbose = 1;
+	sc->io_rman.rm_type = RMAN_ARRAY;
+	sc->io_rman.rm_descr = "versatile PCI IO window";
+	if (rman_init(&sc->io_rman) != 0 || 
+	    rman_manage_region(&sc->io_rman, PCI_IO_WINDOW, 
+		PCI_IO_WINDOW + PCI_IO_SIZE - 1) != 0) {
+		panic("versatile_pci_attach: failed to set up I/O rman");
+	}
+
+	sc->irq_rman.rm_type = RMAN_ARRAY;
+	sc->irq_rman.rm_descr = "versatile PCI IRQs";
+	if (rman_init(&sc->irq_rman) != 0 ||
+	    rman_manage_region(&sc->irq_rman, VERSATILE_PCI_IRQ_START, 
+	        VERSATILE_PCI_IRQ_END) != 0) {
+		panic("versatile_pci_attach: failed to set up IRQ rman");
+	}
+
+	mtx_init(&sc->mtx, device_get_nameunit(dev), "versatilepci",
+			MTX_SPIN);
+
+	val = versatile_pci_conf_read_4((12 << 11) + PCIR_COMMAND);
+
+	for (slot = 0; slot <= PCI_SLOTMAX; slot++) {
+		vendordev_id = versatile_pci_read_4((slot << 11) + PCIR_DEVVENDOR);
+		class_id = versatile_pci_read_4((slot << 11) + PCIR_REVID);
+
+		if (slot == sc->pcib_slot)
+			continue;
+
+		if ((vendordev_id == 0xffffffff) &&
+		    (class_id == 0xffffffff))
+			continue;
+
+		val = versatile_pci_conf_read_4((slot << 11) + PCIR_COMMAND);
+		val |= PCIM_CMD_MEMEN | PCIM_CMD_PORTEN;
+		versatile_pci_conf_write_4((slot << 11) + PCIR_COMMAND, val);
+	}
+
+	device_add_child(dev, "pci", 0);
+	return (bus_generic_attach(dev));
+}
+
+static int
+versatile_pci_read_ivar(device_t dev, device_t child, int which,
+    uintptr_t *result)
+{
+	struct versatile_pci_softc *sc = device_get_softc(dev);
+
+	switch (which) {
+	case PCIB_IVAR_DOMAIN:
+		*result = 0;
+		return (0);
+	case PCIB_IVAR_BUS:
+		*result = sc->busno;
+		return (0);
+	}
+
+	return (ENOENT);
+}
+
+static int
+versatile_pci_write_ivar(device_t dev, device_t child, int which,
+    uintptr_t result)
+{
+	struct versatile_pci_softc * sc = device_get_softc(dev);
+
+	switch (which) {
+	case PCIB_IVAR_BUS:
+		sc->busno = result;
+		return (0);
+	}
+
+	return (ENOENT);
+}
+
+static struct resource *
+versatile_pci_alloc_resource(device_t bus, device_t child, int type, int *rid,
+    u_long start, u_long end, u_long count, u_int flags)
+{
+
+	struct versatile_pci_softc *sc = device_get_softc(bus);
+	struct resource *rv;
+	struct rman *rm;
+
+	dprintf("Alloc resources %d, %08lx..%08lx, %ld\n", type, start, end, count);
+
+	switch (type) {
+	case SYS_RES_IOPORT:
+		rm = &sc->io_rman;
+		break;
+	case SYS_RES_IRQ:
+		rm = &sc->irq_rman;
+		break;
+	case SYS_RES_MEMORY:
+		rm = &sc->mem_rman;
+		break;
+	default:
+		return (NULL);
+	}
+
+	rv = rman_reserve_resource(rm, start, end, count, flags, child);
+
+	if (rv == NULL)
+		return (NULL);
+
+	rman_set_rid(rv, *rid);
+
+	if (flags & RF_ACTIVE) {
+		if (bus_activate_resource(child, type, *rid, rv)) {
+			rman_release_resource(rv);
+			return (NULL);
+		}
+	}
+	return (rv);
+}
+
+static int
+versatile_pci_activate_resource(device_t bus, device_t child, int type, int rid,
+    struct resource *r)
+{
+	vm_offset_t vaddr;
+	int res;
+
+	switch(type) {
+	case SYS_RES_MEMORY:
+	case SYS_RES_IOPORT:
+		vaddr = (vm_offset_t)pmap_mapdev(rman_get_start(r),
+				rman_get_size(r));
+		rman_set_bushandle(r, vaddr);
+		rman_set_bustag(r, arm_base_bs_tag);
+		res = rman_activate_resource(r);
+		break;
+	case SYS_RES_IRQ:
+		res = (BUS_ACTIVATE_RESOURCE(device_get_parent(bus),
+		    child, type, rid, r));
+		break;
+	default:
+		res = ENXIO;
+		break;
+	}
+
+	return (res);
+}
+
+static int
+versatile_pci_setup_intr(device_t bus, device_t child, struct resource *ires,
+	    int flags, driver_filter_t *filt, driver_intr_t *handler,
+	    void *arg, void **cookiep)
+{
+
+	return BUS_SETUP_INTR(device_get_parent(bus), bus, ires, flags,
+	    filt, handler, arg, cookiep);
+}
+
+static int
+versatile_pci_teardown_intr(device_t dev, device_t child, struct resource *ires,
+    void *cookie)
+{
+
+	return BUS_TEARDOWN_INTR(device_get_parent(dev), dev, ires, cookie);
+}
+
+
+
+static int
+versatile_pci_maxslots(device_t dev)
+{
+
+	return (PCI_SLOTMAX);
+}
+
+static int
+versatile_pci_route_interrupt(device_t pcib, device_t device, int pin)
+{
+
+	return (27 + ((pci_get_slot(device) + pin - 1) & 3));
+}
+
+static uint32_t
+versatile_pci_read_config(device_t dev, u_int bus, u_int slot, u_int func,
+    u_int reg, int bytes)
+{
+	struct versatile_pci_softc *sc = device_get_softc(dev);
+	uint32_t data;
+	uint32_t shift, mask;
+	uint32_t addr;
+
+	if (sc->pcib_slot == slot) {
+		switch (bytes) {
+			case 4: 
+				return (0xffffffff);
+				break;
+			case 2:
+				return (0xffff);
+				break;
+			case 1:
+				return (0xff);
+				break;
+		}
+	}
+
+	addr = (bus << 16) | (slot << 11) | (func << 8) | (reg & ~3);
+
+	/* register access is 32-bit aligned */
+	shift = (reg & 3) * 8;
+
+	/* Create a mask based on the width, post-shift */
+	if (bytes == 2)
+		mask = 0xffff;
+	else if (bytes == 1)
+		mask = 0xff;
+	else
+		mask = 0xffffffff;
+
+	dprintf("%s: tag (%x, %x, %x) reg %d(%d)\n", __func__, bus, slot, 
+	    func, reg, bytes);
+
+	mtx_lock_spin(&sc->mtx);
+	data = versatile_pci_conf_read_4(addr);
+	mtx_unlock_spin(&sc->mtx);
+
+	/* get request bytes from 32-bit word */
+	data = (data >> shift) & mask;
+
+	dprintf("%s: read 0x%x\n", __func__, data);
+
+	return (data);
+}
+
+static void
+versatile_pci_write_config(device_t dev, u_int bus, u_int slot, u_int func,
+    u_int reg, uint32_t data, int bytes)
+{
+
+	struct versatile_pci_softc *sc = device_get_softc(dev);
+	uint32_t addr;
+
+	dprintf("%s: tag (%x, %x, %x) reg %d(%d)\n", __func__, bus, slot,
+	    func, reg, bytes);
+
+	if (sc->pcib_slot == slot)
+		return;
+
+	addr = (bus << 16) | (slot << 11) | (func << 8) | reg;
+	mtx_lock_spin(&sc->mtx);
+	switch (bytes) {
+		case 4: 
+			versatile_pci_conf_write_4(addr, data);
+			break;
+		case 2:
+			versatile_pci_conf_write_2(addr, data);
+			break;
+		case 1:
+			versatile_pci_conf_write_1(addr, data);
+			break;
+	}
+	mtx_unlock_spin(&sc->mtx);
+}
+
+static device_method_t versatile_pci_methods[] = {
+	DEVMETHOD(device_probe,		versatile_pci_probe),
+	DEVMETHOD(device_attach,	versatile_pci_attach),
+
+	/* Bus interface */
+	DEVMETHOD(bus_read_ivar,	versatile_pci_read_ivar),
+	DEVMETHOD(bus_write_ivar,	versatile_pci_write_ivar),
+	DEVMETHOD(bus_alloc_resource,	versatile_pci_alloc_resource),
+	DEVMETHOD(bus_release_resource,	bus_generic_release_resource),
+	DEVMETHOD(bus_activate_resource, versatile_pci_activate_resource),
+	DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+	DEVMETHOD(bus_setup_intr,	versatile_pci_setup_intr),
+	DEVMETHOD(bus_teardown_intr,	versatile_pci_teardown_intr),
+
+	/* pcib interface */
+	DEVMETHOD(pcib_maxslots,	versatile_pci_maxslots),
+	DEVMETHOD(pcib_read_config,	versatile_pci_read_config),
+	DEVMETHOD(pcib_write_config,	versatile_pci_write_config),
+	DEVMETHOD(pcib_route_interrupt,	versatile_pci_route_interrupt),
+
+	DEVMETHOD_END
+};
+
+static driver_t versatile_pci_driver = {
+	"pcib",
+	versatile_pci_methods,
+	sizeof(struct versatile_pci_softc),
+};
+
+static devclass_t versatile_pci_devclass;
+
+DRIVER_MODULE(versatile_pci, simplebus, versatile_pci_driver, versatile_pci_devclass, 0, 0);


Property changes on: trunk/sys/arm/versatile/versatile_pci.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/versatile/versatile_sic.c
===================================================================
--- trunk/sys/arm/versatile/versatile_sic.c	                        (rev 0)
+++ trunk/sys/arm/versatile/versatile_sic.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,138 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Oleksandr Tymoshenko <gonzo at freebsd.org>
+ * 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: stable/10/sys/arm/versatile/versatile_sic.c 266152 2014-05-15 16:11:06Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/ktr.h>
+#include <sys/module.h>
+#include <sys/rman.h>
+#include <machine/bus.h>
+#include <machine/intr.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#ifdef  DEBUG
+#define dprintf(fmt, args...) printf(fmt, ##args)
+#else
+#define dprintf(fmt, args...)
+#endif
+
+#define	SIC_STATUS	0x00
+#define	SIC_RAWSTAT	0x04
+#define	SIC_ENABLE	0x08
+#define	SIC_ENSET	0x08
+#define	SIC_ENCLR	0x0C
+#define	SIC_SOFTINTSET	0x10
+#define	SIC_SOFTINTCLR	0x14
+#define	SIC_PICENABLE	0x20
+#define	SIC_PICENSET	0x20
+#define	SIC_PICENCLR	0x24
+
+struct versatile_sic_softc {
+	device_t		sc_dev;
+	struct resource *	mem_res;
+};
+
+#define	sic_read_4(sc, reg)			\
+    bus_read_4(sc->mem_res, (reg))
+#define	sic_write_4(sc, reg, val)		\
+    bus_write_4(sc->mem_res, (reg), (val))
+
+static int
+versatile_sic_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "arm,versatile-sic"))
+		return (ENXIO);
+	device_set_desc(dev, "ARM Versatile SIC");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+versatile_sic_attach(device_t dev)
+{
+	struct		versatile_sic_softc *sc = device_get_softc(dev);
+	uint32_t	pass_irqs;
+	int		rid;
+
+	sc->sc_dev = dev;
+
+	/* Request memory resources */
+	rid = 0;
+	sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+	    RF_ACTIVE);
+	if (sc->mem_res == NULL) {
+		device_printf(dev, "Error: could not allocate memory resources\n");
+		return (ENXIO);
+	}
+
+	/* Disable all interrupts on SIC */
+	sic_write_4(sc, SIC_ENCLR, 0xffffffff);
+
+	/* 
+	 * XXX: Enable IRQ3 for KMI
+	 * Should be replaced by proper interrupts cascading
+	 */
+	sic_write_4(sc, SIC_ENSET, (1 << 3));
+
+	/*
+	 * Let PCI and Ethernet interrupts pass through
+	 * IRQ25, IRQ27..IRQ31
+	 */
+	pass_irqs = (0x1f << 27) | (1 << 25);
+	sic_write_4(sc, SIC_PICENSET, pass_irqs);
+
+	return (0);
+}
+
+static device_method_t versatile_sic_methods[] = {
+	DEVMETHOD(device_probe,		versatile_sic_probe),
+	DEVMETHOD(device_attach,	versatile_sic_attach),
+	{ 0, 0 }
+};
+
+static driver_t versatile_sic_driver = {
+	"sic",
+	versatile_sic_methods,
+	sizeof(struct versatile_sic_softc),
+};
+
+static devclass_t versatile_sic_devclass;
+
+DRIVER_MODULE(sic, simplebus, versatile_sic_driver, versatile_sic_devclass, 0, 0);


Property changes on: trunk/sys/arm/versatile/versatile_sic.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/versatile/versatile_timer.c
===================================================================
--- trunk/sys/arm/versatile/versatile_timer.c	                        (rev 0)
+++ trunk/sys/arm/versatile/versatile_timer.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,59 @@
+/* $MidnightBSD$ */
+/*
+ * Copyright (c) 2012 Oleksandr Tymoshenko <gonzo at freebsd.org>
+ * 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: stable/10/sys/arm/versatile/versatile_timer.c 259329 2013-12-13 20:43:11Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/timeet.h>
+#include <sys/timetc.h>
+#include <sys/watchdog.h>
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+
+void
+cpu_initclocks(void)
+{
+	cpu_initclocks_bsp();
+}
+
+


Property changes on: trunk/sys/arm/versatile/versatile_timer.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xilinx/files.zynq7
===================================================================
--- trunk/sys/arm/xilinx/files.zynq7	                        (rev 0)
+++ trunk/sys/arm/xilinx/files.zynq7	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,31 @@
+#
+# files.zynq7
+#
+# $FreeBSD: stable/10/sys/arm/xilinx/files.zynq7 278727 2015-02-13 22:32:02Z ian $
+
+kern/kern_clocksource.c				standard
+
+arm/arm/bus_space_base.c			standard
+arm/arm/bus_space_generic.c			standard
+arm/arm/bus_space_asm_generic.S			standard
+arm/arm/cpufunc_asm_armv5.S			standard
+arm/arm/cpufunc_asm_arm10.S			standard
+arm/arm/cpufunc_asm_arm11.S			standard
+arm/arm/cpufunc_asm_armv7.S			standard
+
+arm/arm/gic.c					standard
+arm/arm/mpcore_timer.c				standard
+arm/arm/pl310.c					standard
+
+arm/xilinx/zy7_machdep.c			standard
+arm/xilinx/zy7_l2cache.c			standard
+arm/xilinx/zy7_slcr.c				standard
+arm/xilinx/zy7_devcfg.c				standard
+arm/xilinx/zy7_mp.c				optional smp
+
+dev/cadence/if_cgem.c				optional cgem
+dev/sdhci/sdhci_fdt.c				optional sdhci
+arm/xilinx/zy7_ehci.c 				optional ehci
+arm/xilinx/uart_dev_cdnc.c			optional uart
+arm/xilinx/zy7_gpio.c				optional gpio
+


Property changes on: trunk/sys/arm/xilinx/files.zynq7
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/xilinx/std.zynq7
===================================================================
--- trunk/sys/arm/xilinx/std.zynq7	                        (rev 0)
+++ trunk/sys/arm/xilinx/std.zynq7	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,25 @@
+#
+# std.zynq7		- Generic configuration for Xilinx Zynq-7000 PS.
+#
+# $FreeBSD: stable/10/sys/arm/xilinx/std.zynq7 278601 2015-02-11 22:47:48Z ian $
+
+cpu		CPU_CORTEXA
+machine		arm	armv6
+makeoptions	CONF_CFLAGS="-march=armv7a -Wa,-march=armv7a"
+
+files		"../xilinx/files.zynq7"
+
+# Physical memory starts at 0x00000000.  We assume images are loaded at
+# 0x00100000, e.g. from u-boot with 'fatload mmc 0 0x100000 kernel.bin'
+#
+#
+options		PHYSADDR=0x00000000
+options		KERNPHYSADDR=0x00100000
+makeoptions	KERNPHYSADDR=0x00100000
+options		KERNVIRTADDR=0xc0100000		# Used in ldscript.arm
+makeoptions	KERNVIRTADDR=0xc0100000
+
+options		ARM_L2_PIPT
+
+options		IPI_IRQ_START=0
+options		IPI_IRQ_END=15


Property changes on: trunk/sys/arm/xilinx/std.zynq7
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/xilinx/uart_dev_cdnc.c
===================================================================
--- trunk/sys/arm/xilinx/uart_dev_cdnc.c	                        (rev 0)
+++ trunk/sys/arm/xilinx/uart_dev_cdnc.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,717 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2005 M. Warner Losh
+ * Copyright (c) 2005 Olivier Houchard
+ * Copyright (c) 2012 Thomas Skibo
+ * 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 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 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.
+ */
+
+/* A driver for the Cadence AMBA UART as used by the Xilinx Zynq-7000.
+ *
+ * Reference: Zynq-7000 All Programmable SoC Technical Reference Manual.
+ * (v1.4) November 16, 2012.  Xilinx doc UG585.  UART is covered in Ch. 19
+ * and register definitions are in appendix B.33.
+ */
+
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/xilinx/uart_dev_cdnc.c 283327 2015-05-23 20:54:25Z ian $");
+
+#include "opt_global.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/cons.h>
+#include <sys/tty.h>
+#include <machine/bus.h>
+
+#include <dev/uart/uart.h>
+#include <dev/uart/uart_cpu.h>
+#include <dev/uart/uart_cpu_fdt.h>
+#include <dev/uart/uart_bus.h>
+
+#include "uart_if.h"
+
+#define	UART_FIFO_SIZE	64
+
+#define	RD4(bas, reg)		\
+	bus_space_read_4((bas)->bst, (bas)->bsh, uart_regofs((bas), (reg)))
+#define	WR4(bas, reg, value)	\
+	bus_space_write_4((bas)->bst, (bas)->bsh, uart_regofs((bas), (reg)), \
+			  (value))
+
+/* Register definitions for Cadence UART Controller.
+ */
+#define CDNC_UART_CTRL_REG	0x00		/* Control Register. */
+#define CDNC_UART_CTRL_REG_STOPBRK	(1<<8)
+#define CDNC_UART_CTRL_REG_STARTBRK	(1<<7)
+#define CDNC_UART_CTRL_REG_TORST	(1<<6)
+#define CDNC_UART_CTRL_REG_TX_DIS	(1<<5)
+#define CDNC_UART_CTRL_REG_TX_EN	(1<<4)
+#define CDNC_UART_CTRL_REG_RX_DIS	(1<<3)
+#define CDNC_UART_CTRL_REG_RX_EN	(1<<2)
+#define CDNC_UART_CTRL_REG_TXRST	(1<<1)
+#define CDNC_UART_CTRL_REG_RXRST	(1<<0)
+
+#define CDNC_UART_MODE_REG	0x04		/* Mode Register. */
+#define CDNC_UART_MODE_REG_CHMOD_R_LOOP	(3<<8)	/* [9:8] - channel mode */
+#define CDNC_UART_MODE_REG_CHMOD_L_LOOP	(2<<8)
+#define CDNC_UART_MODE_REG_CHMOD_AUTECHO (1<<8)
+#define CDNC_UART_MODE_REG_STOP2	(2<<6)	/* [7:6] - stop bits */
+#define CDNC_UART_MODE_REG_PAR_NONE	(4<<3)	/* [5:3] - parity type */
+#define CDNC_UART_MODE_REG_PAR_MARK	(3<<3)
+#define CDNC_UART_MODE_REG_PAR_SPACE	(2<<3)
+#define CDNC_UART_MODE_REG_PAR_ODD	(1<<3)
+#define CDNC_UART_MODE_REG_PAR_EVEN	(0<<3)
+#define CDNC_UART_MODE_REG_6BIT		(3<<1)	/* [2:1] - character len */
+#define CDNC_UART_MODE_REG_7BIT		(2<<1)
+#define CDNC_UART_MODE_REG_8BIT		(0<<1)
+#define CDNC_UART_MODE_REG_CLKSEL	(1<<0)
+
+#define CDNC_UART_IEN_REG	0x08		/* Interrupt registers. */
+#define CDNC_UART_IDIS_REG	0x0C
+#define CDNC_UART_IMASK_REG	0x10
+#define CDNC_UART_ISTAT_REG	0x14
+#define CDNC_UART_INT_TXOVR		(1<<12)
+#define CDNC_UART_INT_TXNRLYFUL		(1<<11)	/* tx "nearly" full */
+#define CDNC_UART_INT_TXTRIG		(1<<10)
+#define CDNC_UART_INT_DMSI		(1<<9)	/* delta modem status */
+#define CDNC_UART_INT_RXTMOUT		(1<<8)
+#define CDNC_UART_INT_PARITY		(1<<7)
+#define CDNC_UART_INT_FRAMING		(1<<6)
+#define CDNC_UART_INT_RXOVR		(1<<5)
+#define CDNC_UART_INT_TXFULL		(1<<4)
+#define CDNC_UART_INT_TXEMPTY		(1<<3)
+#define CDNC_UART_INT_RXFULL		(1<<2)
+#define CDNC_UART_INT_RXEMPTY		(1<<1)
+#define CDNC_UART_INT_RXTRIG		(1<<0)
+#define CDNC_UART_INT_ALL		0x1FFF
+
+#define CDNC_UART_BAUDGEN_REG	0x18
+#define CDNC_UART_RX_TIMEO_REG	0x1C
+#define CDNC_UART_RX_WATER_REG	0x20
+
+#define CDNC_UART_MODEM_CTRL_REG 0x24
+#define CDNC_UART_MODEM_CTRL_REG_FCM	(1<<5)	/* automatic flow control */
+#define CDNC_UART_MODEM_CTRL_REG_RTS	(1<<1)
+#define CDNC_UART_MODEM_CTRL_REG_DTR	(1<<0)
+
+#define CDNC_UART_MODEM_STAT_REG 0x28
+#define CDNC_UART_MODEM_STAT_REG_FCMS	(1<<8)	/* flow control mode (rw) */
+#define CDNC_UART_MODEM_STAT_REG_DCD	(1<<7)
+#define CDNC_UART_MODEM_STAT_REG_RI	(1<<6)
+#define CDNC_UART_MODEM_STAT_REG_DSR	(1<<5)
+#define CDNC_UART_MODEM_STAT_REG_CTS	(1<<4)
+#define CDNC_UART_MODEM_STAT_REG_DDCD	(1<<3)	/* change in DCD (w1tc) */
+#define CDNC_UART_MODEM_STAT_REG_TERI	(1<<2)	/* trail edge ring (w1tc) */
+#define CDNC_UART_MODEM_STAT_REG_DDSR	(1<<1)	/* change in DSR (w1tc) */
+#define CDNC_UART_MODEM_STAT_REG_DCTS	(1<<0)	/* change in CTS (w1tc) */
+
+#define CDNC_UART_CHAN_STAT_REG	0x2C		/* Channel status register. */
+#define CDNC_UART_CHAN_STAT_REG_TXNRLYFUL (1<<14) /* tx "nearly" full */
+#define CDNC_UART_CHAN_STAT_REG_TXTRIG	(1<<13)
+#define CDNC_UART_CHAN_STAT_REG_FDELT	(1<<12)
+#define CDNC_UART_CHAN_STAT_REG_TXACTIVE (1<<11)
+#define CDNC_UART_CHAN_STAT_REG_RXACTIVE (1<<10)
+#define CDNC_UART_CHAN_STAT_REG_TXFULL	(1<<4)
+#define CDNC_UART_CHAN_STAT_REG_TXEMPTY	(1<<3)
+#define CDNC_UART_CHAN_STAT_REG_RXEMPTY	(1<<1)
+#define CDNC_UART_CHAN_STAT_REG_RXTRIG	(1<<0)
+
+#define CDNC_UART_FIFO		0x30		/* Data FIFO (tx and rx) */
+#define CDNC_UART_BAUDDIV_REG	0x34
+#define CDNC_UART_FLOWDEL_REG	0x38
+#define CDNC_UART_TX_WATER_REG	0x44
+
+
+/*
+ * Low-level UART interface.
+ */
+static int cdnc_uart_probe(struct uart_bas *bas);
+static void cdnc_uart_init(struct uart_bas *bas, int, int, int, int);
+static void cdnc_uart_term(struct uart_bas *bas);
+static void cdnc_uart_putc(struct uart_bas *bas, int);
+static int cdnc_uart_rxready(struct uart_bas *bas);
+static int cdnc_uart_getc(struct uart_bas *bas, struct mtx *mtx);
+
+extern SLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs;
+
+static struct uart_ops cdnc_uart_ops = {
+	.probe = cdnc_uart_probe,
+	.init = cdnc_uart_init,
+	.term = cdnc_uart_term,
+	.putc = cdnc_uart_putc,
+	.rxready = cdnc_uart_rxready,
+	.getc = cdnc_uart_getc,
+};
+
+#define	SIGCHG(c, i, s, d)				\
+	if (c) {					\
+		i |= (i & s) ? s : s | d;		\
+	} else {					\
+		i = (i & s) ? (i & ~s) | d : i;		\
+	}
+
+static int
+cdnc_uart_probe(struct uart_bas *bas)
+{
+
+	return (0);
+}
+
+static int
+cdnc_uart_set_baud(struct uart_bas *bas, int baudrate)
+{
+	uint32_t baudgen, bauddiv;
+	uint32_t best_bauddiv, best_baudgen, best_error;
+	uint32_t baud_out, err;
+
+	best_bauddiv = 0;
+	best_baudgen = 0;
+	best_error = ~0;
+
+	/* Try all possible bauddiv values and pick best match. */
+	for (bauddiv = 4; bauddiv <= 255; bauddiv++) {
+		baudgen = (bas->rclk + (baudrate * (bauddiv + 1)) / 2) /
+			(baudrate * (bauddiv + 1));
+		if (baudgen < 1 || baudgen > 0xffff)
+			continue;
+
+		baud_out = bas->rclk / (baudgen * (bauddiv + 1));
+		err = baud_out > baudrate ?
+			baud_out - baudrate : baudrate - baud_out;
+
+		if (err < best_error) {
+			best_error = err;
+			best_bauddiv = bauddiv;
+			best_baudgen = baudgen;
+		}
+	}
+
+	if (best_bauddiv > 0) {
+		WR4(bas, CDNC_UART_BAUDDIV_REG, best_bauddiv);
+		WR4(bas, CDNC_UART_BAUDGEN_REG, best_baudgen);
+		return (0);
+	} else
+		return (-1); /* out of range */
+}
+
+static int
+cdnc_uart_set_params(struct uart_bas *bas, int baudrate, int databits,
+		      int stopbits, int parity)
+{
+	uint32_t mode_reg_value = 0;
+
+	switch (databits) {
+	case 6:
+		mode_reg_value |= CDNC_UART_MODE_REG_6BIT;
+		break;
+	case 7:
+		mode_reg_value |= CDNC_UART_MODE_REG_7BIT;
+		break;
+	case 8:
+	default:
+		mode_reg_value |= CDNC_UART_MODE_REG_8BIT;
+		break;
+	}
+
+	if (stopbits == 2)
+		mode_reg_value |= CDNC_UART_MODE_REG_STOP2;
+
+	switch (parity) {
+	case UART_PARITY_MARK:
+		mode_reg_value |= CDNC_UART_MODE_REG_PAR_MARK;
+		break;
+	case UART_PARITY_SPACE:
+		mode_reg_value |= CDNC_UART_MODE_REG_PAR_SPACE;
+		break;
+	case UART_PARITY_ODD:
+		mode_reg_value |= CDNC_UART_MODE_REG_PAR_ODD;
+		break;
+	case UART_PARITY_EVEN:
+		mode_reg_value |= CDNC_UART_MODE_REG_PAR_EVEN;
+		break;
+	case UART_PARITY_NONE:
+	default:
+		mode_reg_value |= CDNC_UART_MODE_REG_PAR_NONE;
+		break;		
+	}
+
+	WR4(bas, CDNC_UART_MODE_REG, mode_reg_value);
+
+	if (baudrate > 0 && cdnc_uart_set_baud(bas, baudrate) < 0)
+		return (EINVAL);
+
+	return(0);
+}
+
+static void
+cdnc_uart_hw_init(struct uart_bas *bas)
+{
+
+	/* Reset RX and TX. */
+	WR4(bas, CDNC_UART_CTRL_REG,
+	    CDNC_UART_CTRL_REG_RXRST | CDNC_UART_CTRL_REG_TXRST);
+
+	/* Interrupts all off. */
+	WR4(bas, CDNC_UART_IDIS_REG, CDNC_UART_INT_ALL);
+	WR4(bas, CDNC_UART_ISTAT_REG, CDNC_UART_INT_ALL);
+
+	/* Clear delta bits. */
+	WR4(bas, CDNC_UART_MODEM_STAT_REG,
+	    CDNC_UART_MODEM_STAT_REG_DDCD | CDNC_UART_MODEM_STAT_REG_TERI |
+	    CDNC_UART_MODEM_STAT_REG_DDSR | CDNC_UART_MODEM_STAT_REG_DCTS);
+
+	/* RX FIFO water level, stale timeout */
+	WR4(bas, CDNC_UART_RX_WATER_REG, UART_FIFO_SIZE/2);
+	WR4(bas, CDNC_UART_RX_TIMEO_REG, 10);
+
+	/* TX FIFO water level (not used.) */
+	WR4(bas, CDNC_UART_TX_WATER_REG, UART_FIFO_SIZE/2);
+
+	/* Bring RX and TX online. */
+	WR4(bas, CDNC_UART_CTRL_REG,
+	    CDNC_UART_CTRL_REG_RX_EN | CDNC_UART_CTRL_REG_TX_EN |
+	    CDNC_UART_CTRL_REG_TORST | CDNC_UART_CTRL_REG_STOPBRK);
+
+	/* Set DTR and RTS. */
+	WR4(bas, CDNC_UART_MODEM_CTRL_REG, CDNC_UART_MODEM_CTRL_REG_DTR |
+	    CDNC_UART_MODEM_CTRL_REG_RTS);
+}
+
+/*
+ * Initialize this device for use as a console.
+ */
+static void
+cdnc_uart_init(struct uart_bas *bas, int baudrate, int databits, int stopbits,
+	      int parity)
+{
+
+	/* Initialize hardware. */
+	cdnc_uart_hw_init(bas);
+
+	/* Set baudrate, parameters. */
+	(void)cdnc_uart_set_params(bas, baudrate, databits, stopbits, parity);
+}
+
+/*
+ * Free resources now that we're no longer the console.  This appears to
+ * be never called, and I'm unsure quite what to do if I am called.
+ */
+static void
+cdnc_uart_term(struct uart_bas *bas)
+{
+
+	/* XXX */
+}
+
+/*
+ * Put a character of console output (so we do it here polling rather than
+ * interrutp driven).
+ */
+static void
+cdnc_uart_putc(struct uart_bas *bas, int c)
+{
+
+	/* Wait for room. */
+	while ((RD4(bas,CDNC_UART_CHAN_STAT_REG) &
+		CDNC_UART_CHAN_STAT_REG_TXFULL) != 0)
+		;
+
+	WR4(bas, CDNC_UART_FIFO, c);
+
+	while ((RD4(bas,CDNC_UART_CHAN_STAT_REG) &
+		CDNC_UART_CHAN_STAT_REG_TXEMPTY) == 0)
+		;
+}
+
+/*
+ * Check for a character available.
+ */
+static int
+cdnc_uart_rxready(struct uart_bas *bas)
+{
+
+	return ((RD4(bas, CDNC_UART_CHAN_STAT_REG) &
+		 CDNC_UART_CHAN_STAT_REG_RXEMPTY) == 0);
+}
+
+/*
+ * Block waiting for a character.
+ */
+static int
+cdnc_uart_getc(struct uart_bas *bas, struct mtx *mtx)
+{
+	int c;
+
+	uart_lock(mtx);
+
+	while ((RD4(bas, CDNC_UART_CHAN_STAT_REG) &
+		CDNC_UART_CHAN_STAT_REG_RXEMPTY) != 0) {
+		uart_unlock(mtx);
+		DELAY(4);
+		uart_lock(mtx);
+	}
+	
+	c = RD4(bas, CDNC_UART_FIFO);
+	
+	uart_unlock(mtx);
+
+	c &= 0xff;
+	return (c);
+}
+
+/*****************************************************************************/
+/*
+ * High-level UART interface.
+ */
+
+static int cdnc_uart_bus_probe(struct uart_softc *sc);
+static int cdnc_uart_bus_attach(struct uart_softc *sc);
+static int cdnc_uart_bus_flush(struct uart_softc *, int);
+static int cdnc_uart_bus_getsig(struct uart_softc *);
+static int cdnc_uart_bus_ioctl(struct uart_softc *, int, intptr_t);
+static int cdnc_uart_bus_ipend(struct uart_softc *);
+static int cdnc_uart_bus_param(struct uart_softc *, int, int, int, int);
+static int cdnc_uart_bus_receive(struct uart_softc *);
+static int cdnc_uart_bus_setsig(struct uart_softc *, int);
+static int cdnc_uart_bus_transmit(struct uart_softc *);
+static void cdnc_uart_bus_grab(struct uart_softc *);
+static void cdnc_uart_bus_ungrab(struct uart_softc *);
+
+static kobj_method_t cdnc_uart_bus_methods[] = {
+	KOBJMETHOD(uart_probe,		cdnc_uart_bus_probe),
+	KOBJMETHOD(uart_attach, 	cdnc_uart_bus_attach),
+	KOBJMETHOD(uart_flush,		cdnc_uart_bus_flush),
+	KOBJMETHOD(uart_getsig,		cdnc_uart_bus_getsig),
+	KOBJMETHOD(uart_ioctl,		cdnc_uart_bus_ioctl),
+	KOBJMETHOD(uart_ipend,		cdnc_uart_bus_ipend),
+	KOBJMETHOD(uart_param,		cdnc_uart_bus_param),
+	KOBJMETHOD(uart_receive,	cdnc_uart_bus_receive),
+	KOBJMETHOD(uart_setsig,		cdnc_uart_bus_setsig),
+	KOBJMETHOD(uart_transmit,	cdnc_uart_bus_transmit),
+	KOBJMETHOD(uart_grab,		cdnc_uart_bus_grab),
+	KOBJMETHOD(uart_ungrab,		cdnc_uart_bus_ungrab),
+	
+	KOBJMETHOD_END
+};
+
+int
+cdnc_uart_bus_probe(struct uart_softc *sc)
+{
+
+	sc->sc_txfifosz = UART_FIFO_SIZE;
+	sc->sc_rxfifosz = UART_FIFO_SIZE;
+	sc->sc_hwiflow = 0;
+	sc->sc_hwoflow = 0;
+
+	device_set_desc(sc->sc_dev, "Cadence UART");
+
+	return (0);
+}
+
+static int
+cdnc_uart_bus_attach(struct uart_softc *sc)
+{
+	struct uart_bas *bas = &sc->sc_bas;
+	struct uart_devinfo *di;
+
+	if (sc->sc_sysdev != NULL) {
+		di = sc->sc_sysdev;
+		(void)cdnc_uart_set_params(bas, di->baudrate, di->databits,
+					   di->stopbits, di->parity);
+	} else
+		cdnc_uart_hw_init(bas);
+
+	(void)cdnc_uart_bus_getsig(sc);
+
+	/* Enable interrupts. */
+	WR4(bas, CDNC_UART_IEN_REG,
+	    CDNC_UART_INT_RXTRIG | CDNC_UART_INT_RXTMOUT |
+	    CDNC_UART_INT_TXOVR | CDNC_UART_INT_RXOVR |
+	    CDNC_UART_INT_DMSI);
+
+	return (0);
+}
+
+static int
+cdnc_uart_bus_transmit(struct uart_softc *sc)
+{
+	int i;
+	struct uart_bas *bas = &sc->sc_bas;
+
+	uart_lock(sc->sc_hwmtx);
+
+	/* Clear sticky TXEMPTY status bit. */
+	WR4(bas, CDNC_UART_ISTAT_REG, CDNC_UART_INT_TXEMPTY);
+
+	for (i = 0; i < sc->sc_txdatasz; i++)
+		WR4(bas, CDNC_UART_FIFO, sc->sc_txbuf[i]);
+
+	/* Enable TX empty interrupt. */
+	WR4(bas, CDNC_UART_IEN_REG, CDNC_UART_INT_TXEMPTY);
+	sc->sc_txbusy = 1;
+
+	uart_unlock(sc->sc_hwmtx);
+
+	return (0);
+}
+
+static int
+cdnc_uart_bus_setsig(struct uart_softc *sc, int sig)
+{
+	struct uart_bas *bas = &sc->sc_bas;
+	uint32_t new, old, modem_ctrl;
+
+	do {
+		old = sc->sc_hwsig;
+		new = old;
+		if (sig & SER_DDTR) {
+			SIGCHG(sig & SER_DTR, new, SER_DTR, SER_DDTR);
+		}
+		if (sig & SER_DRTS) {
+			SIGCHG(sig & SER_RTS, new, SER_RTS, SER_DRTS);
+		}
+	} while (!atomic_cmpset_32(&sc->sc_hwsig, old, new));
+	uart_lock(sc->sc_hwmtx);
+	modem_ctrl = RD4(bas, CDNC_UART_MODEM_CTRL_REG) &
+		~(CDNC_UART_MODEM_CTRL_REG_DTR | CDNC_UART_MODEM_CTRL_REG_RTS);
+	if ((new & SER_DTR) != 0)
+		modem_ctrl |= CDNC_UART_MODEM_CTRL_REG_DTR;
+	if ((new & SER_RTS) != 0)
+		modem_ctrl |= CDNC_UART_MODEM_CTRL_REG_RTS;
+	WR4(bas, CDNC_UART_MODEM_CTRL_REG, modem_ctrl);
+
+	uart_unlock(sc->sc_hwmtx);
+	return (0);
+}
+
+static int
+cdnc_uart_bus_receive(struct uart_softc *sc)
+{
+	struct uart_bas *bas = &sc->sc_bas;
+	uint32_t status;
+	int c, c_status = 0;
+
+	uart_lock(sc->sc_hwmtx);
+
+	/* Check for parity or framing errors and clear the status bits. */
+	status = RD4(bas, CDNC_UART_ISTAT_REG);
+	if ((status & (CDNC_UART_INT_FRAMING | CDNC_UART_INT_PARITY)) != 0) {
+		WR4(bas, CDNC_UART_ISTAT_REG,
+		    status & (CDNC_UART_INT_FRAMING | CDNC_UART_INT_PARITY));
+		if ((status & CDNC_UART_INT_PARITY) != 0)
+			c_status |= UART_STAT_PARERR;
+		if ((status & CDNC_UART_INT_FRAMING) != 0)
+			c_status |= UART_STAT_FRAMERR;
+	}
+
+	while ((RD4(bas, CDNC_UART_CHAN_STAT_REG) &
+		CDNC_UART_CHAN_STAT_REG_RXEMPTY) == 0) {
+		c = RD4(bas, CDNC_UART_FIFO) & 0xff;
+#ifdef KDB
+		/* Detect break and drop into debugger. */
+		if (c == 0 && (c_status & UART_STAT_FRAMERR) != 0 &&
+		    sc->sc_sysdev != NULL &&
+		    sc->sc_sysdev->type == UART_DEV_CONSOLE) {
+			kdb_break();
+			WR4(bas, CDNC_UART_ISTAT_REG, CDNC_UART_INT_FRAMING);
+		}
+#endif
+		uart_rx_put(sc, c | c_status);
+	}
+
+	uart_unlock(sc->sc_hwmtx);
+
+	return (0);
+}
+
+static int
+cdnc_uart_bus_param(struct uart_softc *sc, int baudrate, int databits,
+		   int stopbits, int parity)
+{
+
+	return (cdnc_uart_set_params(&sc->sc_bas, baudrate,
+				    databits, stopbits, parity));
+}
+
+static int
+cdnc_uart_bus_ipend(struct uart_softc *sc)
+{
+	int ipend = 0;
+	struct uart_bas *bas = &sc->sc_bas;
+	uint32_t istatus;
+
+	uart_lock(sc->sc_hwmtx);
+
+	istatus = RD4(bas, CDNC_UART_ISTAT_REG);
+
+	/* Clear interrupt bits. */
+	WR4(bas, CDNC_UART_ISTAT_REG, istatus &
+	    (CDNC_UART_INT_RXTRIG | CDNC_UART_INT_RXTMOUT |
+	     CDNC_UART_INT_TXOVR | CDNC_UART_INT_RXOVR |
+	     CDNC_UART_INT_TXEMPTY | CDNC_UART_INT_DMSI));
+
+	/* Receive data. */
+	if ((istatus & (CDNC_UART_INT_RXTRIG | CDNC_UART_INT_RXTMOUT)) != 0)
+		ipend |= SER_INT_RXREADY;
+
+	/* Transmit fifo empty. */
+	if (sc->sc_txbusy && (istatus & CDNC_UART_INT_TXEMPTY) != 0) {
+		/* disable txempty interrupt. */
+		WR4(bas, CDNC_UART_IDIS_REG, CDNC_UART_INT_TXEMPTY);
+		ipend |= SER_INT_TXIDLE;
+	}
+
+	/* TX Overflow. */
+	if ((istatus & CDNC_UART_INT_TXOVR) != 0)
+		ipend |= SER_INT_OVERRUN;
+
+	/* RX Overflow. */
+	if ((istatus & CDNC_UART_INT_RXOVR) != 0)
+		ipend |= SER_INT_OVERRUN;
+
+	/* Modem signal change. */
+	if ((istatus & CDNC_UART_INT_DMSI) != 0) {
+		WR4(bas, CDNC_UART_MODEM_STAT_REG,
+		    CDNC_UART_MODEM_STAT_REG_DDCD |
+		    CDNC_UART_MODEM_STAT_REG_TERI |
+		    CDNC_UART_MODEM_STAT_REG_DDSR |
+		    CDNC_UART_MODEM_STAT_REG_DCTS);
+		ipend |= SER_INT_SIGCHG;
+	}
+
+	uart_unlock(sc->sc_hwmtx);
+	return (ipend);
+}
+
+static int
+cdnc_uart_bus_flush(struct uart_softc *sc, int what)
+{
+
+	return (0);
+}
+
+static int
+cdnc_uart_bus_getsig(struct uart_softc *sc)
+{
+	struct uart_bas *bas = &sc->sc_bas;
+	uint32_t new, old, sig;
+	uint8_t modem_status;
+
+	do {
+		old = sc->sc_hwsig;
+		sig = old;
+		uart_lock(sc->sc_hwmtx);
+		modem_status = RD4(bas, CDNC_UART_MODEM_STAT_REG);
+		uart_unlock(sc->sc_hwmtx);
+		SIGCHG(modem_status & CDNC_UART_MODEM_STAT_REG_DSR,
+		       sig, SER_DSR, SER_DDSR);
+		SIGCHG(modem_status & CDNC_UART_MODEM_STAT_REG_CTS,
+		       sig, SER_CTS, SER_DCTS);
+		SIGCHG(modem_status & CDNC_UART_MODEM_STAT_REG_DCD,
+		       sig, SER_DCD, SER_DDCD);
+		SIGCHG(modem_status & CDNC_UART_MODEM_STAT_REG_RI,
+		       sig, SER_RI,  SER_DRI);
+		new = sig & ~SER_MASK_DELTA;
+	} while (!atomic_cmpset_32(&sc->sc_hwsig, old, new));
+	return (sig);
+}
+
+static int
+cdnc_uart_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
+{
+	struct uart_bas *bas = &sc->sc_bas;
+	uint32_t uart_ctrl, modem_ctrl;
+	int error = 0;
+
+	uart_lock(sc->sc_hwmtx);
+
+	switch (request) {
+	case UART_IOCTL_BREAK:
+		uart_ctrl = RD4(bas, CDNC_UART_CTRL_REG);
+		if (data) {
+			uart_ctrl |= CDNC_UART_CTRL_REG_STARTBRK;
+			uart_ctrl &= ~CDNC_UART_CTRL_REG_STOPBRK;
+		} else {
+			uart_ctrl |= CDNC_UART_CTRL_REG_STOPBRK;
+			uart_ctrl &= ~CDNC_UART_CTRL_REG_STARTBRK;
+		}
+		WR4(bas, CDNC_UART_CTRL_REG, uart_ctrl);
+		break;
+	case UART_IOCTL_IFLOW:
+		modem_ctrl = RD4(bas, CDNC_UART_MODEM_CTRL_REG);
+		if (data)
+			modem_ctrl |= CDNC_UART_MODEM_CTRL_REG_RTS;
+		else
+			modem_ctrl &= ~CDNC_UART_MODEM_CTRL_REG_RTS;
+		WR4(bas, CDNC_UART_MODEM_CTRL_REG, modem_ctrl);
+		break;
+	default:
+		error = EINVAL;
+		break;
+	}
+
+	uart_unlock(sc->sc_hwmtx);
+
+	return (error);
+}
+
+static void
+cdnc_uart_bus_grab(struct uart_softc *sc)
+{
+
+	/* Enable interrupts. */
+	WR4(&sc->sc_bas, CDNC_UART_IEN_REG,
+	    CDNC_UART_INT_TXOVR | CDNC_UART_INT_RXOVR |
+	    CDNC_UART_INT_DMSI);
+}
+
+static void
+cdnc_uart_bus_ungrab(struct uart_softc *sc)
+{
+
+	/* Enable interrupts. */
+	WR4(&sc->sc_bas, CDNC_UART_IEN_REG,
+	    CDNC_UART_INT_RXTRIG | CDNC_UART_INT_RXTMOUT |
+	    CDNC_UART_INT_TXOVR | CDNC_UART_INT_RXOVR |
+	    CDNC_UART_INT_DMSI);
+}
+
+static struct uart_class uart_cdnc_class = {
+	"cdnc_uart",
+	cdnc_uart_bus_methods,
+	sizeof(struct uart_softc),
+	.uc_ops = &cdnc_uart_ops,
+	.uc_range = 8
+};
+
+static struct ofw_compat_data compat_data[] = {
+	{"cadence,uart",	(uintptr_t)&uart_cdnc_class},
+	{NULL,			(uintptr_t)NULL},
+};
+UART_FDT_CLASS_AND_DEVICE(compat_data);


Property changes on: trunk/sys/arm/xilinx/uart_dev_cdnc.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xilinx/zedboard/files.zedboard
===================================================================
--- trunk/sys/arm/xilinx/zedboard/files.zedboard	                        (rev 0)
+++ trunk/sys/arm/xilinx/zedboard/files.zedboard	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,9 @@
+#
+# files.zedboard
+#
+# $FreeBSD: stable/10/sys/arm/xilinx/zedboard/files.zedboard 249997 2013-04-27 22:38:29Z wkoszek $
+
+#   We'll need board specific files once we start implementing drivers
+#   for Zedboard PL peripherals such as HDMI, VGA, or Audio Codecs.  For
+#   now, nothing is needed.
+#


Property changes on: trunk/sys/arm/xilinx/zedboard/files.zedboard
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/xilinx/zedboard/std.zedboard
===================================================================
--- trunk/sys/arm/xilinx/zedboard/std.zedboard	                        (rev 0)
+++ trunk/sys/arm/xilinx/zedboard/std.zedboard	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,8 @@
+#
+# std.zedboard
+#
+# $FreeBSD: stable/10/sys/arm/xilinx/zedboard/std.zedboard 249997 2013-04-27 22:38:29Z wkoszek $
+
+include "../xilinx/std.zynq7"
+files	"../xilinx/zedboard/files.zedboard"
+


Property changes on: trunk/sys/arm/xilinx/zedboard/std.zedboard
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/xilinx/zy7_devcfg.c
===================================================================
--- trunk/sys/arm/xilinx/zy7_devcfg.c	                        (rev 0)
+++ trunk/sys/arm/xilinx/zy7_devcfg.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,669 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Thomas Skibo
+ * 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: stable/10/sys/arm/xilinx/zy7_devcfg.c 266379 2014-05-17 23:25:20Z ian $
+ */
+
+/* 
+ * Zynq-7000 Devcfg driver.  This allows programming the PL (FPGA) section
+ * of Zynq.
+ *
+ * Reference: Zynq-7000 All Programmable SoC Technical Reference Manual.
+ * (v1.4) November 16, 2012.  Xilinx doc UG585.  PL Configuration is
+ * covered in section 6.4.5.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/xilinx/zy7_devcfg.c 266379 2014-05-17 23:25:20Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/sysctl.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+#include <sys/uio.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+#include <machine/stdarg.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <arm/xilinx/zy7_slcr.h>
+
+struct zy7_devcfg_softc {
+	device_t	dev;
+	struct mtx	sc_mtx;
+	struct resource	*mem_res;
+	struct resource *irq_res;
+	struct cdev	*sc_ctl_dev;
+	void		*intrhandle;
+
+	bus_dma_tag_t	dma_tag;
+	bus_dmamap_t	dma_map;
+
+	int		is_open;
+};
+
+static struct zy7_devcfg_softc *zy7_devcfg_softc_p;
+
+#define DEVCFG_SC_LOCK(sc)		mtx_lock(&(sc)->sc_mtx)
+#define	DEVCFG_SC_UNLOCK(sc)		mtx_unlock(&(sc)->sc_mtx)
+#define DEVCFG_SC_LOCK_INIT(sc) \
+	mtx_init(&(sc)->sc_mtx, device_get_nameunit((sc)->dev),	\
+	    "zy7_devcfg", MTX_DEF)
+#define DEVCFG_SC_LOCK_DESTROY(sc)	mtx_destroy(&(sc)->sc_mtx);
+#define DEVCFG_SC_ASSERT_LOCKED(sc)	mtx_assert(&(sc)->sc_mtx, MA_OWNED);
+
+#define RD4(sc, off) 		(bus_read_4((sc)->mem_res, (off)))
+#define WR4(sc, off, val) 	(bus_write_4((sc)->mem_res, (off), (val)))
+
+SYSCTL_NODE(_hw, OID_AUTO, fpga, CTLFLAG_RD, 0,	\
+	    "Xilinx Zynq-7000 PL (FPGA) section");
+
+static int zy7_devcfg_sysctl_pl_done(SYSCTL_HANDLER_ARGS);
+SYSCTL_PROC(_hw_fpga, OID_AUTO, pl_done, CTLTYPE_INT | CTLFLAG_RD, NULL, 0,
+	    zy7_devcfg_sysctl_pl_done, "I", "PL section config DONE signal");
+
+static int zy7_en_level_shifters = 1;
+SYSCTL_INT(_hw_fpga, OID_AUTO, en_level_shifters, CTLFLAG_RW,
+	   &zy7_en_level_shifters, 0,
+	   "Enable PS-PL level shifters after device config");
+
+static int zy7_ps_vers = 0;
+SYSCTL_INT(_hw, OID_AUTO, ps_vers, CTLFLAG_RD, &zy7_ps_vers, 0,
+	   "Zynq-7000 PS version");
+
+
+/* cdev entry points. */
+static int zy7_devcfg_open(struct cdev *, int, int, struct thread *);
+static int zy7_devcfg_write(struct cdev *, struct uio *, int);
+static int zy7_devcfg_close(struct cdev *, int, int, struct thread *);
+
+
+struct cdevsw zy7_devcfg_cdevsw = {
+	.d_version =	D_VERSION,
+	.d_open =	zy7_devcfg_open,
+	.d_write =	zy7_devcfg_write,
+	.d_close =	zy7_devcfg_close,
+	.d_name =	"devcfg",
+};
+
+/* Devcfg block registers. */
+#define ZY7_DEVCFG_CTRL			0x0000
+#define   ZY7_DEVCFG_CTRL_FORCE_RST		(1<<31)
+#define   ZY7_DEVCFG_CTRL_PCFG_PROG_B		(1<<30)
+#define   ZY7_DEVCFG_CTRL_PCFG_POR_CNT_4K	(1<<29)
+#define   ZY7_DEVCFG_CTRL_PCAP_PR		(1<<27)
+#define   ZY7_DEVCFG_CTRL_PCAP_MODE		(1<<26)
+#define   ZY7_DEVCFG_CTRL_QTR_PCAP_RATE_EN	(1<<25)
+#define   ZY7_DEVCFG_CTRL_MULTIBOOT_EN		(1<<24)
+#define   ZY7_DEVCFG_CTRL_JTAG_CHAIN_DIS	(1<<23)
+#define   ZY7_DEVCFG_CTRL_USER_MODE		(1<<15)
+#define   ZY7_DEVCFG_CTRL_RESVD_WR11		(3<<13)	/* always write 11 */
+#define   ZY7_DEVCFG_CTRL_PCFG_AES_FUSE		(1<<12)
+#define   ZY7_DEVCFG_CTRL_PCFG_AES_EN_MASK	(7<<9)	/* all 1's or 0's */
+#define   ZY7_DEVCFG_CTRL_SEU_EN		(1<<8)
+#define   ZY7_DEVCFG_CTRL_SEC_EN		(1<<7)
+#define   ZY7_DEVCFG_CTRL_SPNIDEN		(1<<6)
+#define   ZY7_DEVCFG_CTRL_SPIDEN		(1<<5)
+#define   ZY7_DEVCFG_CTRL_NIDEN			(1<<4)
+#define   ZY7_DEVCFG_CTRL_DBGEN			(1<<3)
+#define   ZY7_DEVCFG_CTRL_DAP_EN_MASK		(7<<0)	/* all 1's to enable */
+
+#define ZY7_DEVCFG_LOCK			0x004
+#define   ZY7_DEVCFG_LOCK_AES_FUSE_LOCK		(1<<4)
+#define   ZY7_DEVCFG_LOCK_AES_EN		(1<<3)
+#define   ZY7_DEVCFG_LOCK_SEU_LOCK		(1<<2)
+#define   ZY7_DEVCFG_LOCK_SEC_LOCK		(1<<1)
+#define   ZY7_DEVCFG_LOCK_DBG_LOCK		(1<<0)
+
+#define ZY7_DEVCFG_CFG			0x008
+#define   ZY7_DEVCFG_CFG_RFIFO_TH_MASK		(3<<10)
+#define   ZY7_DEVCFG_CFG_WFIFO_TH_MASK		(3<<8)
+#define   ZY7_DEVCFG_CFG_RCLK_EDGE		(1<<7)
+#define   ZY7_DEVCFG_CFG_WCLK_EDGE		(1<<6)
+#define   ZY7_DEVCFG_CFG_DIS_SRC_INC		(1<<5)
+#define   ZY7_DEVCFG_CFG_DIS_DST_INC		(1<<4)
+
+#define ZY7_DEVCFG_INT_STATUS		0x00C
+#define ZY7_DEVCFG_INT_MASK		0x010
+#define   ZY7_DEVCFG_INT_PSS_GTS_USR_B		(1<<31)
+#define   ZY7_DEVCFG_INT_PSS_FST_CFG_B		(1<<30)
+#define   ZY7_DEVCFG_INT_PSS_GPWRDWN_B		(1<<29)
+#define   ZY7_DEVCFG_INT_PSS_GTS_CFG_B		(1<<28)
+#define   ZY7_DEVCFG_INT_CFG_RESET_B		(1<<27)
+#define   ZY7_DEVCFG_INT_AXI_WTO		(1<<23)	/* axi write timeout */
+#define   ZY7_DEVCFG_INT_AXI_WERR		(1<<22)	/* axi write err */
+#define   ZY7_DEVCFG_INT_AXI_RTO		(1<<21)	/* axi read timeout */
+#define   ZY7_DEVCFG_INT_AXI_RERR		(1<<20)	/* axi read err */
+#define   ZY7_DEVCFG_INT_RX_FIFO_OV		(1<<18)	/* rx fifo overflow */
+#define   ZY7_DEVCFG_INT_WR_FIFO_LVL		(1<<17)	/* wr fifo < level */
+#define   ZY7_DEVCFG_INT_RD_FIFO_LVL		(1<<16)	/* rd fifo >= level */
+#define   ZY7_DEVCFG_INT_DMA_CMD_ERR		(1<<15)
+#define   ZY7_DEVCFG_INT_DMA_Q_OV		(1<<14)
+#define   ZY7_DEVCFG_INT_DMA_DONE		(1<<13)
+#define   ZY7_DEVCFG_INT_DMA_PCAP_DONE		(1<<12)
+#define   ZY7_DEVCFG_INT_P2D_LEN_ERR		(1<<11)
+#define   ZY7_DEVCFG_INT_PCFG_HMAC_ERR		(1<<6)
+#define   ZY7_DEVCFG_INT_PCFG_SEU_ERR		(1<<5)
+#define   ZY7_DEVCFG_INT_PCFG_POR_B		(1<<4)
+#define   ZY7_DEVCFG_INT_PCFG_CFG_RST		(1<<3)
+#define   ZY7_DEVCFG_INT_PCFG_DONE		(1<<2)
+#define   ZY7_DEVCFG_INT_PCFG_INIT_PE		(1<<1)
+#define   ZY7_DEVCFG_INT_PCFG_INIT_NE		(1<<0)
+#define   ZY7_DEVCFG_INT_ERRORS			0x00f0f860
+#define   ZY7_DEVCFG_INT_ALL			0xf8f7f87f
+
+#define ZY7_DEVCFG_STATUS		0x014
+#define   ZY7_DEVCFG_STATUS_DMA_CMD_Q_F		(1<<31)	/* cmd queue full */
+#define   ZY7_DEVCFG_STATUS_DMA_CMD_Q_E		(1<<30) /* cmd queue empty */
+#define   ZY7_DEVCFG_STATUS_DONE_COUNT_MASK	(3<<28)
+#define   ZY7_DEVCFG_STATUS_DONE_COUNT_SHIFT	28
+#define   ZY7_DEVCFG_STATUS_RX_FIFO_LVL_MASK	(0x1f<<20)
+#define   ZY7_DEVCFG_STATUS_RX_FIFO_LVL_SHIFT	20
+#define   ZY7_DEVCFG_STATUS_TX_FIFO_LVL_MASK	(0x7f<<12)
+#define   ZY7_DEVCFG_STATUS_TX_FIFO_LVL_SHIFT	12
+#define   ZY7_DEVCFG_STATUS_PSS_GTS_USR_B	(1<<11)
+#define   ZY7_DEVCFG_STATUS_PSS_FST_CFG_B	(1<<10)
+#define   ZY7_DEVCFG_STATUS_PSS_GPWRDWN_B	(1<<9)
+#define   ZY7_DEVCFG_STATUS_PSS_GTS_CFG_B	(1<<8)
+#define   ZY7_DEVCFG_STATUS_ILL_APB_ACCE	(1<<6)
+#define   ZY7_DEVCFG_STATUS_PSS_CFG_RESET_B	(1<<5)
+#define   ZY7_DEVCFG_STATUS_PCFG_INIT		(1<<4)
+#define   ZY7_DEVCFG_STATUS_EFUSE_BBRAM_KEY_DIS	(1<<3)
+#define   ZY7_DEVCFG_STATUS_EFUSE_SEC_EN	(1<<2)
+#define   ZY7_DEVCFG_STATUS_EFUSE_JTAG_DIS	(1<<1)
+
+#define ZY7_DEVCFG_DMA_SRC_ADDR		0x018
+#define ZY7_DEVCFG_DMA_DST_ADDR		0x01c
+#define   ZY7_DEVCFG_DMA_ADDR_WAIT_PCAP	1
+#define   ZY7_DEVCFG_DMA_ADDR_ILLEGAL		0xffffffff
+
+#define ZY7_DEVCFG_DMA_SRC_LEN		0x020	/* in 4-byte words. */
+#define ZY7_DEVCFG_DMA_SRC_LEN_MAX		0x7ffffff
+#define ZY7_DEVCFG_DMA_DST_LEN		0x024
+#define ZY7_DEVCFG_ROM_SHADOW		0x028
+#define ZY7_DEVCFG_MULTIBOOT_ADDR	0x02c
+#define ZY7_DEVCFG_SW_ID		0x030
+#define ZY7_DEVCFG_UNLOCK		0x034
+#define ZY7_DEVCFG_UNLOCK_MAGIC			0x757bdf0d
+#define ZY7_DEVCFG_MCTRL		0x080
+#define   ZY7_DEVCFG_MCTRL_PS_VERS_MASK		(0xf<<28)
+#define   ZY7_DEVCFG_MCTRL_PS_VERS_SHIFT	28
+#define   ZY7_DEVCFG_MCTRL_PCFG_POR_B		(1<<8)
+#define   ZY7_DEVCFG_MCTRL_INT_PCAP_LPBK	(1<<4)
+#define ZY7_DEVCFG_XADCIF_CFG		0x100
+#define ZY7_DEVCFG_XADCIF_INT_STAT	0x104
+#define ZY7_DEVCFG_XADCIF_INT_MASK	0x108
+#define ZY7_DEVCFG_XADCIF_MSTS		0x10c
+#define ZY7_DEVCFG_XADCIF_CMD_FIFO	0x110
+#define ZY7_DEVCFG_XADCIF_RD_FIFO	0x114
+#define ZY7_DEVCFG_XADCIF_MCTL		0x118
+
+
+/* Enable programming the PL through PCAP. */
+static void
+zy7_devcfg_init_hw(struct zy7_devcfg_softc *sc)
+{
+
+	DEVCFG_SC_ASSERT_LOCKED(sc);
+
+	/* Set devcfg control register. */
+	WR4(sc, ZY7_DEVCFG_CTRL,
+	    ZY7_DEVCFG_CTRL_PCFG_PROG_B |
+	    ZY7_DEVCFG_CTRL_PCAP_PR |
+	    ZY7_DEVCFG_CTRL_PCAP_MODE |
+	    ZY7_DEVCFG_CTRL_USER_MODE |
+	    ZY7_DEVCFG_CTRL_RESVD_WR11 |
+	    ZY7_DEVCFG_CTRL_SPNIDEN |
+	    ZY7_DEVCFG_CTRL_SPIDEN |
+	    ZY7_DEVCFG_CTRL_NIDEN |
+	    ZY7_DEVCFG_CTRL_DBGEN |
+	    ZY7_DEVCFG_CTRL_DAP_EN_MASK);
+
+	/* Turn off internal PCAP loopback. */
+	WR4(sc, ZY7_DEVCFG_MCTRL, RD4(sc, ZY7_DEVCFG_MCTRL) &
+	    ~ZY7_DEVCFG_MCTRL_INT_PCAP_LPBK);
+}
+
+/* Clear previous configuration of the PL by asserting PROG_B. */
+static int
+zy7_devcfg_reset_pl(struct zy7_devcfg_softc *sc)
+{
+	uint32_t devcfg_ctl;
+	int tries, err;
+
+	DEVCFG_SC_ASSERT_LOCKED(sc);
+
+	devcfg_ctl = RD4(sc, ZY7_DEVCFG_CTRL);
+
+	/* Clear sticky bits and set up INIT signal positive edge interrupt. */
+	WR4(sc, ZY7_DEVCFG_INT_STATUS, ZY7_DEVCFG_INT_ALL);
+	WR4(sc, ZY7_DEVCFG_INT_MASK, ~ZY7_DEVCFG_INT_PCFG_INIT_PE);
+
+	/* Deassert PROG_B (active low). */
+	devcfg_ctl |= ZY7_DEVCFG_CTRL_PCFG_PROG_B;
+	WR4(sc, ZY7_DEVCFG_CTRL, devcfg_ctl);
+
+	/*
+	 * Wait for INIT to assert.  If it is already asserted, we may not get
+	 * an edge interrupt so cancel it and continue.
+	 */
+	if ((RD4(sc, ZY7_DEVCFG_STATUS) &
+	     ZY7_DEVCFG_STATUS_PCFG_INIT) != 0) {
+		/* Already asserted.  Cancel interrupt. */
+		WR4(sc, ZY7_DEVCFG_INT_MASK, ~0);
+	}
+	else {
+		/* Wait for positive edge interrupt. */
+		err = mtx_sleep(sc, &sc->sc_mtx, PCATCH, "zy7i1", hz);
+		if (err != 0)
+			return (err);
+	}
+	
+	/* Reassert PROG_B (active low). */
+	devcfg_ctl &= ~ZY7_DEVCFG_CTRL_PCFG_PROG_B;
+	WR4(sc, ZY7_DEVCFG_CTRL, devcfg_ctl);
+
+	/* Wait for INIT deasserted.  This happens almost instantly. */
+	tries = 0;
+	while ((RD4(sc, ZY7_DEVCFG_STATUS) &
+		ZY7_DEVCFG_STATUS_PCFG_INIT) != 0) {
+		if (++tries >= 100)
+			return (EIO);
+		DELAY(5);
+	}
+
+	/* Clear sticky bits and set up INIT positive edge interrupt. */
+	WR4(sc, ZY7_DEVCFG_INT_STATUS, ZY7_DEVCFG_INT_ALL);
+	WR4(sc, ZY7_DEVCFG_INT_MASK, ~ZY7_DEVCFG_INT_PCFG_INIT_PE);
+
+	/* Deassert PROG_B again. */
+	devcfg_ctl |= ZY7_DEVCFG_CTRL_PCFG_PROG_B;
+	WR4(sc, ZY7_DEVCFG_CTRL, devcfg_ctl);
+
+	/*
+	 * Wait for INIT asserted indicating FPGA internal initialization
+	 * is complete.
+	 */
+	err = mtx_sleep(sc, &sc->sc_mtx, PCATCH, "zy7i2", hz);
+	if (err != 0)
+		return (err);
+
+	/* Clear sticky DONE bit in interrupt status. */
+	WR4(sc, ZY7_DEVCFG_INT_STATUS, ZY7_DEVCFG_INT_ALL);
+
+	return (0);
+}
+
+/* Callback function for bus_dmamap_load(). */
+static void
+zy7_dma_cb2(void *arg, bus_dma_segment_t *seg, int nsegs, int error)
+{
+	if (!error && nsegs == 1)
+		*(bus_addr_t *)arg = seg[0].ds_addr;
+}
+
+
+static int
+zy7_devcfg_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
+{
+	struct zy7_devcfg_softc *sc = dev->si_drv1;
+	int err;
+
+	DEVCFG_SC_LOCK(sc);
+	if (sc->is_open) {
+		DEVCFG_SC_UNLOCK(sc);
+		return (EBUSY);
+	}
+
+	sc->dma_map = NULL;
+	err = bus_dma_tag_create(bus_get_dma_tag(sc->dev), 4, 0,
+				 BUS_SPACE_MAXADDR_32BIT,
+				 BUS_SPACE_MAXADDR,
+				 NULL, NULL,
+				 PAGE_SIZE,
+				 1,
+				 PAGE_SIZE,
+				 0,
+				 busdma_lock_mutex,
+				 &sc->sc_mtx,
+				 &sc->dma_tag);
+	if (err) {
+		DEVCFG_SC_UNLOCK(sc);
+		return (err);
+	}
+
+	sc->is_open = 1;
+	DEVCFG_SC_UNLOCK(sc);
+	return (0);
+}
+
+static int
+zy7_devcfg_write(struct cdev *dev, struct uio *uio, int ioflag)
+{
+	struct zy7_devcfg_softc *sc = dev->si_drv1;
+	void *dma_mem;
+	bus_addr_t dma_physaddr;
+	int segsz, err;
+
+	DEVCFG_SC_LOCK(sc);
+
+	/* First write?  Reset PL. */
+	if (uio->uio_offset == 0 && uio->uio_resid > 0)	{
+		zy7_devcfg_init_hw(sc);
+		zy7_slcr_preload_pl();
+		err = zy7_devcfg_reset_pl(sc);
+		if (err != 0) {
+			DEVCFG_SC_UNLOCK(sc);
+			return (err);
+		}
+	}
+
+	/* Allocate dma memory and load. */
+	err = bus_dmamem_alloc(sc->dma_tag, &dma_mem, BUS_DMA_NOWAIT,
+			       &sc->dma_map);
+	if (err != 0) {
+		DEVCFG_SC_UNLOCK(sc);
+		return (err);
+	}
+	err = bus_dmamap_load(sc->dma_tag, sc->dma_map, dma_mem, PAGE_SIZE,
+			      zy7_dma_cb2, &dma_physaddr, 0);
+	if (err != 0) {
+		bus_dmamem_free(sc->dma_tag, dma_mem, sc->dma_map);
+		DEVCFG_SC_UNLOCK(sc);
+		return (err);
+	}
+
+	while (uio->uio_resid > 0) {
+		/* If DONE signal has been set, we shouldn't write anymore. */
+		if ((RD4(sc, ZY7_DEVCFG_INT_STATUS) &
+		     ZY7_DEVCFG_INT_PCFG_DONE) != 0) {
+			err = EIO;
+			break;
+		}
+
+		/* uiomove the data from user buffer to our dma map. */
+		segsz = MIN(PAGE_SIZE, uio->uio_resid);
+		DEVCFG_SC_UNLOCK(sc);
+		err = uiomove(dma_mem, segsz, uio);
+		DEVCFG_SC_LOCK(sc);
+		if (err != 0)
+			break;
+
+		/* Flush the cache to memory. */
+		bus_dmamap_sync(sc->dma_tag, sc->dma_map,
+				BUS_DMASYNC_PREWRITE);
+
+		/* Program devcfg's DMA engine.  The ordering of these
+		 * register writes is critical.
+		 */
+		if (uio->uio_resid > segsz)
+			WR4(sc, ZY7_DEVCFG_DMA_SRC_ADDR,
+			    (uint32_t) dma_physaddr);
+		else
+			WR4(sc, ZY7_DEVCFG_DMA_SRC_ADDR,
+			    (uint32_t) dma_physaddr |
+			    ZY7_DEVCFG_DMA_ADDR_WAIT_PCAP);
+		WR4(sc, ZY7_DEVCFG_DMA_DST_ADDR, ZY7_DEVCFG_DMA_ADDR_ILLEGAL);
+		WR4(sc, ZY7_DEVCFG_DMA_SRC_LEN, (segsz+3)/4);
+		WR4(sc, ZY7_DEVCFG_DMA_DST_LEN, 0);
+
+		/* Now clear done bit and set up DMA done interrupt. */
+		WR4(sc, ZY7_DEVCFG_INT_STATUS, ZY7_DEVCFG_INT_ALL);
+		WR4(sc, ZY7_DEVCFG_INT_MASK, ~ZY7_DEVCFG_INT_DMA_DONE);
+
+		/* Wait for DMA done interrupt. */
+		err = mtx_sleep(sc->dma_map, &sc->sc_mtx, PCATCH,
+				"zy7dma", hz);
+		if (err != 0)
+			break;
+
+		bus_dmamap_sync(sc->dma_tag, sc->dma_map,
+				BUS_DMASYNC_POSTWRITE);
+
+		/* Check DONE signal. */
+		if ((RD4(sc, ZY7_DEVCFG_INT_STATUS) &
+		     ZY7_DEVCFG_INT_PCFG_DONE) != 0)
+			zy7_slcr_postload_pl(zy7_en_level_shifters);
+	}
+
+	bus_dmamap_unload(sc->dma_tag, sc->dma_map);
+	bus_dmamem_free(sc->dma_tag, dma_mem, sc->dma_map);
+	DEVCFG_SC_UNLOCK(sc);
+	return (err);
+}
+
+static int
+zy7_devcfg_close(struct cdev *dev, int fflag, int devtype, struct thread *td)
+{
+	struct zy7_devcfg_softc *sc = dev->si_drv1;
+
+	DEVCFG_SC_LOCK(sc);
+	sc->is_open = 0;
+	bus_dma_tag_destroy(sc->dma_tag);
+	DEVCFG_SC_UNLOCK(sc);
+
+	return (0);
+}
+
+
+static void
+zy7_devcfg_intr(void *arg)
+{
+	struct zy7_devcfg_softc *sc = (struct zy7_devcfg_softc *)arg;
+	uint32_t istatus, imask;
+
+	DEVCFG_SC_LOCK(sc);
+
+	istatus = RD4(sc, ZY7_DEVCFG_INT_STATUS);
+	imask = ~RD4(sc, ZY7_DEVCFG_INT_MASK);
+
+	/* Turn interrupt off. */
+	WR4(sc, ZY7_DEVCFG_INT_MASK, ~0);
+
+	if ((istatus & imask) == 0) {
+		DEVCFG_SC_UNLOCK(sc);
+		return;
+	}
+
+	/* DMA done? */
+	if ((istatus & ZY7_DEVCFG_INT_DMA_DONE) != 0)
+		wakeup(sc->dma_map);
+
+	/* INIT_B positive edge? */
+	if ((istatus & ZY7_DEVCFG_INT_PCFG_INIT_PE) != 0)
+		wakeup(sc);
+
+	DEVCFG_SC_UNLOCK(sc);
+}
+
+/* zy7_devcfg_sysctl_pl_done() returns status of the PL_DONE signal.
+ */
+static int
+zy7_devcfg_sysctl_pl_done(SYSCTL_HANDLER_ARGS)
+{
+	struct zy7_devcfg_softc *sc = zy7_devcfg_softc_p;
+	int pl_done = 0;
+
+	if (sc) {
+		DEVCFG_SC_LOCK(sc);
+
+		/* PCFG_DONE bit is sticky.  Clear it before checking it. */
+		WR4(sc, ZY7_DEVCFG_INT_STATUS, ZY7_DEVCFG_INT_PCFG_DONE);
+		pl_done = ((RD4(sc, ZY7_DEVCFG_INT_STATUS) &
+			    ZY7_DEVCFG_INT_PCFG_DONE) != 0);
+
+		DEVCFG_SC_UNLOCK(sc);
+	}
+	return (sysctl_handle_int(oidp, &pl_done, 0, req));
+}
+
+static int
+zy7_devcfg_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "xlnx,zy7_devcfg"))
+		return (ENXIO);
+
+	device_set_desc(dev, "Zynq devcfg block");
+	return (0);
+}
+
+static int zy7_devcfg_detach(device_t dev);
+
+static int
+zy7_devcfg_attach(device_t dev)
+{
+	struct zy7_devcfg_softc *sc = device_get_softc(dev);
+	int rid, err;
+
+	/* Allow only one attach. */
+	if (zy7_devcfg_softc_p != NULL)
+		return (ENXIO);
+
+	sc->dev = dev;
+
+	DEVCFG_SC_LOCK_INIT(sc);
+
+	/* Get memory resource. */
+	rid = 0;
+	sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+					     RF_ACTIVE);
+	if (sc->mem_res == NULL) {
+		device_printf(dev, "could not allocate memory resources.\n");
+		zy7_devcfg_detach(dev);
+		return (ENOMEM);
+	}
+
+	/* Allocate IRQ. */
+	rid = 0;
+	sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+					     RF_ACTIVE);
+	if (sc->irq_res == NULL) {
+		device_printf(dev, "cannot allocate IRQ\n");
+		zy7_devcfg_detach(dev);
+		return (ENOMEM);
+	}
+
+	/* Activate the interrupt. */
+	err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
+			     NULL, zy7_devcfg_intr, sc, &sc->intrhandle);
+	if (err) {
+		device_printf(dev, "cannot setup IRQ\n");
+		zy7_devcfg_detach(dev);
+		return (err);
+	}
+
+	/* Create /dev/devcfg */
+	sc->sc_ctl_dev = make_dev(&zy7_devcfg_cdevsw, 0,
+			  UID_ROOT, GID_WHEEL, 0600, "devcfg");
+	if (sc->sc_ctl_dev == NULL) {
+		device_printf(dev, "failed to create /dev/devcfg");
+		zy7_devcfg_detach(dev);
+		return (ENXIO);
+	}
+	sc->sc_ctl_dev->si_drv1 = sc;
+
+	zy7_devcfg_softc_p = sc;
+
+	/* Unlock devcfg registers. */
+	WR4(sc, ZY7_DEVCFG_UNLOCK, ZY7_DEVCFG_UNLOCK_MAGIC);
+
+	/* Make sure interrupts are completely disabled. */
+	WR4(sc, ZY7_DEVCFG_INT_STATUS, ZY7_DEVCFG_INT_ALL);
+	WR4(sc, ZY7_DEVCFG_INT_MASK, 0xffffffff);
+
+	/* Get PS_VERS for SYSCTL. */
+	zy7_ps_vers = (RD4(sc, ZY7_DEVCFG_MCTRL) &
+		       ZY7_DEVCFG_MCTRL_PS_VERS_MASK) >>
+		ZY7_DEVCFG_MCTRL_PS_VERS_SHIFT;
+
+	return (0);
+}
+
+static int
+zy7_devcfg_detach(device_t dev)
+{
+	struct zy7_devcfg_softc *sc = device_get_softc(dev);
+
+	if (device_is_attached(dev))
+		bus_generic_detach(dev);
+
+	/* Get rid of /dev/devcfg0. */
+	if (sc->sc_ctl_dev != NULL)
+		destroy_dev(sc->sc_ctl_dev);
+
+	/* Teardown and release interrupt. */
+	if (sc->irq_res != NULL) {
+		if (sc->intrhandle)
+			bus_teardown_intr(dev, sc->irq_res, sc->intrhandle);
+		bus_release_resource(dev, SYS_RES_IRQ,
+			     rman_get_rid(sc->irq_res), sc->irq_res);
+	}
+
+	/* Release memory resource. */
+	if (sc->mem_res != NULL)
+		bus_release_resource(dev, SYS_RES_MEMORY,
+			     rman_get_rid(sc->mem_res), sc->mem_res);
+
+	zy7_devcfg_softc_p = NULL;
+
+	DEVCFG_SC_LOCK_DESTROY(sc);
+
+	return (0);
+}
+
+static device_method_t zy7_devcfg_methods[] = {
+	/* device_if */
+	DEVMETHOD(device_probe, 	zy7_devcfg_probe),
+	DEVMETHOD(device_attach, 	zy7_devcfg_attach),
+	DEVMETHOD(device_detach, 	zy7_devcfg_detach),
+
+	DEVMETHOD_END
+};
+
+static driver_t zy7_devcfg_driver = {
+	"zy7_devcfg",
+	zy7_devcfg_methods,
+	sizeof(struct zy7_devcfg_softc),
+};
+static devclass_t zy7_devcfg_devclass;
+
+DRIVER_MODULE(zy7_devcfg, simplebus, zy7_devcfg_driver, zy7_devcfg_devclass, \
+	      0, 0);
+MODULE_DEPEND(zy7_devcfg, zy7_slcr, 1, 1, 1);


Property changes on: trunk/sys/arm/xilinx/zy7_devcfg.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xilinx/zy7_ehci.c
===================================================================
--- trunk/sys/arm/xilinx/zy7_ehci.c	                        (rev 0)
+++ trunk/sys/arm/xilinx/zy7_ehci.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,364 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012-2013 Thomas Skibo
+ * 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: stable/10/sys/arm/xilinx/zy7_ehci.c 308402 2016-11-07 09:19:04Z hselasky $
+ */
+
+/*
+ * A host-controller driver for Zynq-7000's USB OTG controller.
+ *
+ * Reference: Zynq-7000 All Programmable SoC Technical Reference Manual.
+ * (v1.4) November 16, 2012.  Xilinx doc UG585.  Ch. 15 covers the USB
+ * controller and register definitions are in appendix B.34.
+ */
+
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/xilinx/zy7_ehci.c 308402 2016-11-07 09:19:04Z hselasky $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/condvar.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+#include <machine/stdarg.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <dev/usb/usb.h>
+#include <dev/usb/usbdi.h>
+
+#include <dev/usb/usb_core.h>
+#include <dev/usb/usb_busdma.h>
+#include <dev/usb/usb_process.h>
+#include <dev/usb/usb_util.h>
+
+#include <dev/usb/usb_controller.h>
+#include <dev/usb/usb_bus.h>
+#include <dev/usb/controller/ehci.h>
+#include <dev/usb/controller/ehcireg.h>
+
+
+/* Register definitions. */
+#define ZY7_USB_ID				0x0000
+#define ZY7_USB_HWGENERAL			0x0004
+#define ZY7_USB_HWHOST				0x0008
+#define ZY7_USB_HWDEVICE			0x000c
+#define ZY7_USB_HWTXBUF				0x0010
+#define ZY7_USB_HWRXBUF				0x0014
+#define ZY7_USB_GPTIMER0LD			0x0080
+#define ZY7_USB_GPTIMER0CTRL			0x0084
+#define ZY7_USB_GPTIMER1LD			0x0088
+#define ZY7_USB_GPTIMER1CTRL			0x008c
+#define ZY7_USB_SBUSCFG				0x0090
+#define ZY7_USB_CAPLENGTH_HCIVERSION		0x0100
+#define ZY7_USB_HCSPARAMS			0x0104
+#define ZY7_USB_HCCPARAMS			0x0108
+#define ZY7_USB_DCIVERSION			0x0120
+#define ZY7_USB_DCCPARAMS			0x0124
+#define ZY7_USB_USBCMD				0x0140
+#define ZY7_USB_USBSTS				0x0144
+#define ZY7_USB_USBINTR				0x0148
+#define ZY7_USB_FRINDEX				0x014c
+#define ZY7_USB_PERIODICLISTBASE_DEICEADDR 	0x0154
+#define ZY7_USB_ASYNCLISTADDR_ENDPOINTLISTADDR 	0x0158
+#define ZY7_USB_TTCTRL				0x015c
+#define ZY7_USB_BURSTSIZE			0x0160
+#define ZY7_USB_TXFILLTUNING			0x0164
+#define   ZY7_USB_TXFILLTUNING_TXFIFOTHRES_SHFT		16
+#define   ZY7_USB_TXFILLTUNING_TXFIFOTHRES_MASK		(0x3f<<16)
+#define ZY7_USB_TXTFILLTUNING			0x0168
+#define ZY7_USB_IC_USB				0x016c
+#define ZY7_USB_ULPI_VIEWPORT			0x0170
+#define   ZY7_USB_ULPI_VIEWPORT_WU			(1<<31)
+#define   ZY7_USB_ULPI_VIEWPORT_RUN			(1<<30)
+#define   ZY7_USB_ULPI_VIEWPORT_RW			(1<<29)
+#define   ZY7_USB_ULPI_VIEWPORT_SS			(1<<27)
+#define   ZY7_USB_ULPI_VIEWPORT_PORT_MASK		(7<<24)
+#define   ZY7_USB_ULPI_VIEWPORT_PORT_SHIFT		24
+#define   ZY7_USB_ULPI_VIEWPORT_ADDR_MASK		(0xff<<16)
+#define   ZY7_USB_ULPI_VIEWPORT_ADDR_SHIFT		16
+#define   ZY7_USB_ULPI_VIEWPORT_DATARD_MASK		(0xff<<8)
+#define   ZY7_USB_ULPI_VIEWPORT_DATARD_SHIFT		8
+#define   ZY7_USB_ULPI_VIEWPORT_DATAWR_MASK		(0xff<<0)
+#define   ZY7_USB_ULPI_VIEWPORT_DATAWR_SHIFT		0
+#define ZY7_USB_ENDPTNAK			0x0178
+#define ZY7_USB_ENDPTNAKEN			0x017c
+#define ZY7_USB_CONFIGFLAG			0x0180
+#define ZY7_USB_PORTSC(n)			(0x0180+4*(n))
+#define   ZY7_USB_PORTSC_PTS_MASK			(3<<30)
+#define   ZY7_USB_PORTSC_PTS_SHIFT			30
+#define   ZY7_USB_PORTSC_PTS_UTMI			(0<<30)
+#define   ZY7_USB_PORTSC_PTS_ULPI			(2<<30)
+#define   ZY7_USB_PORTSC_PTS_SERIAL			(3<<30)
+#define   ZY7_USB_PORTSC_PTW				(1<<28)
+#define   ZY7_USB_PORTSC_PTS2				(1<<25)
+#define ZY7_USB_OTGSC				0x01a4
+#define ZY7_USB_USBMODE				0x01a8
+#define ZY7_USB_ENDPTSETUPSTAT			0x01ac
+#define ZY7_USB_ENDPTPRIME			0x01b0
+#define ZY7_USB_ENDPTFLUSH			0x01b4
+#define ZY7_USB_ENDPTSTAT			0x01b8
+#define ZY7_USB_ENDPTCOMPLETE			0x01bc
+#define ZY7_USB_ENDPTCTRL(n)			(0x01c0+4*(n))
+
+#define EHCI_REG_OFFSET	ZY7_USB_CAPLENGTH_HCIVERSION
+#define EHCI_REG_SIZE	0x100
+
+static int
+zy7_phy_config(device_t dev, bus_space_tag_t io_tag, bus_space_handle_t bsh)
+{
+	phandle_t node;
+	char buf[64];
+	uint32_t portsc;
+	int tries;
+
+	node = ofw_bus_get_node(dev);
+
+	if (OF_getprop(node, "phy_type", buf, sizeof(buf)) > 0) {
+		portsc = bus_space_read_4(io_tag, bsh, ZY7_USB_PORTSC(1));
+		portsc &= ~(ZY7_USB_PORTSC_PTS_MASK | ZY7_USB_PORTSC_PTW |
+			    ZY7_USB_PORTSC_PTS2);
+
+		if (strcmp(buf,"ulpi") == 0)
+			portsc |= ZY7_USB_PORTSC_PTS_ULPI;
+		else if (strcmp(buf,"utmi") == 0)
+			portsc |= ZY7_USB_PORTSC_PTS_UTMI;
+		else if (strcmp(buf,"utmi-wide") == 0)
+			portsc |= (ZY7_USB_PORTSC_PTS_UTMI |
+				   ZY7_USB_PORTSC_PTW);
+		else if (strcmp(buf, "serial") == 0)
+			portsc |= ZY7_USB_PORTSC_PTS_SERIAL;
+
+		bus_space_write_4(io_tag, bsh, ZY7_USB_PORTSC(1), portsc);
+	}
+
+	if (OF_getprop(node, "phy_vbus_ext", buf, sizeof(buf)) >= 0) {
+
+		/* Tell PHY that VBUS is supplied externally. */
+		bus_space_write_4(io_tag, bsh, ZY7_USB_ULPI_VIEWPORT,
+				  ZY7_USB_ULPI_VIEWPORT_RUN |
+				  ZY7_USB_ULPI_VIEWPORT_RW |
+				  (0 << ZY7_USB_ULPI_VIEWPORT_PORT_SHIFT) |
+				  (0x0b << ZY7_USB_ULPI_VIEWPORT_ADDR_SHIFT) |
+				  (0x60 << ZY7_USB_ULPI_VIEWPORT_DATAWR_SHIFT)
+			);
+
+		tries = 100;
+		while ((bus_space_read_4(io_tag, bsh, ZY7_USB_ULPI_VIEWPORT) &
+			ZY7_USB_ULPI_VIEWPORT_RUN) != 0) {
+			if (--tries < 0)
+				return (-1);
+			DELAY(1);
+		}
+	}
+
+	return (0);
+}
+
+static int
+zy7_ehci_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "xlnx,zy7_ehci"))
+		return (ENXIO);
+
+	device_set_desc(dev, "Zynq-7000 EHCI USB 2.0 controller");
+	return (0);
+}
+
+static int zy7_ehci_detach(device_t dev);
+
+static int
+zy7_ehci_attach(device_t dev)
+{
+	ehci_softc_t *sc = device_get_softc(dev);
+	bus_space_handle_t bsh;
+	int err, rid;
+	
+	/* initialize some bus fields */
+	sc->sc_bus.parent = dev;
+	sc->sc_bus.devices = sc->sc_devices;
+	sc->sc_bus.devices_max = EHCI_MAX_DEVICES;
+	sc->sc_bus.dma_bits = 32;
+
+	/* get all DMA memory */
+	if (usb_bus_mem_alloc_all(&sc->sc_bus,
+	    USB_GET_DMA_TAG(dev), &ehci_iterate_hw_softc))
+		return (ENOMEM);
+
+	/* Allocate memory. */
+	rid = 0;
+	sc->sc_io_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
+					       &rid, RF_ACTIVE);
+	if (sc->sc_io_res == NULL) {
+		device_printf(dev, "Can't allocate memory");
+		zy7_ehci_detach(dev);
+		return (ENOMEM);
+	}
+
+	sc->sc_io_tag = rman_get_bustag(sc->sc_io_res);
+	bsh = rman_get_bushandle(sc->sc_io_res);
+	sc->sc_io_size = EHCI_REG_SIZE;
+
+	if (bus_space_subregion(sc->sc_io_tag, bsh, EHCI_REG_OFFSET,
+				sc->sc_io_size, &sc->sc_io_hdl) != 0)
+		panic("%s: unable to subregion USB host registers",
+		      device_get_name(dev));
+
+	/* Allocate IRQ. */
+	rid = 0;
+	sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+						RF_ACTIVE);
+	if (sc->sc_irq_res == NULL) {
+		device_printf(dev, "Can't allocate IRQ\n");
+		zy7_ehci_detach(dev);
+		return (ENOMEM);
+	}
+
+	/* Add USB device */
+	sc->sc_bus.bdev = device_add_child(dev, "usbus", -1);
+	if (!sc->sc_bus.bdev) {
+		device_printf(dev, "Could not add USB device\n");
+		zy7_ehci_detach(dev);
+		return (ENXIO);
+	}
+	device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
+	device_set_desc(sc->sc_bus.bdev, "Zynq-7000 ehci USB 2.0 controller");
+
+	strcpy(sc->sc_vendor, "Xilinx"); /* or IP vendor? */
+
+	/* Activate the interrupt */
+	err = bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
+			     NULL, (driver_intr_t *)ehci_interrupt, sc,
+			     &sc->sc_intr_hdl);
+	if (err) {
+		device_printf(dev, "Cannot setup IRQ\n");
+		zy7_ehci_detach(dev);
+		return (err);
+	}
+
+	/* Customization. */
+	sc->sc_flags |= EHCI_SCFLG_SETMODE | EHCI_SCFLG_TT |
+		EHCI_SCFLG_NORESTERM;
+
+	/* Modify FIFO burst threshold from 2 to 8. */
+	bus_space_write_4(sc->sc_io_tag, bsh,
+			  ZY7_USB_TXFILLTUNING,
+			  8 << ZY7_USB_TXFILLTUNING_TXFIFOTHRES_SHFT);
+
+	/* Handle PHY options. */
+	if (zy7_phy_config(dev, sc->sc_io_tag, bsh) < 0) {
+		device_printf(dev, "Cannot config phy!\n");
+		zy7_ehci_detach(dev);
+		return (EIO);
+	}
+
+	/* Init ehci. */
+	err = ehci_init(sc);
+	if (!err) {
+		sc->sc_flags |= EHCI_SCFLG_DONEINIT;
+		err = device_probe_and_attach(sc->sc_bus.bdev);
+	}
+	if (err) {
+		device_printf(dev, "USB init failed err=%d\n", err);
+		zy7_ehci_detach(dev);
+		return (err);
+	}
+
+	return (0);
+}
+
+static int
+zy7_ehci_detach(device_t dev)
+{
+	ehci_softc_t *sc = device_get_softc(dev);
+
+	/* during module unload there are lots of children leftover */
+	device_delete_children(dev);
+	
+	sc->sc_flags &= ~EHCI_SCFLG_DONEINIT;
+
+	if (sc->sc_irq_res && sc->sc_intr_hdl)
+		/* call ehci_detach() after ehci_init() called after
+		 * successful bus_setup_intr().
+		 */
+		ehci_detach(sc);
+
+	if (sc->sc_irq_res) {
+		if (sc->sc_intr_hdl != NULL)
+			bus_teardown_intr(dev, sc->sc_irq_res,
+					  sc->sc_intr_hdl);
+		bus_release_resource(dev, SYS_RES_IRQ,
+			     rman_get_rid(sc->sc_irq_res), sc->sc_irq_res);
+	}
+
+	if (sc->sc_io_res)
+		bus_release_resource(dev, SYS_RES_MEMORY,
+			     rman_get_rid(sc->sc_io_res), sc->sc_io_res);
+	usb_bus_mem_free_all(&sc->sc_bus, &ehci_iterate_hw_softc);
+
+	return (0);
+}
+
+static device_method_t ehci_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		zy7_ehci_probe),
+	DEVMETHOD(device_attach, 	zy7_ehci_attach),
+	DEVMETHOD(device_detach, 	zy7_ehci_detach),
+	DEVMETHOD(device_suspend, 	bus_generic_suspend),
+	DEVMETHOD(device_resume, 	bus_generic_resume),
+	DEVMETHOD(device_shutdown, 	bus_generic_shutdown),
+
+	/* Bus interface */
+	DEVMETHOD(bus_print_child, bus_generic_print_child),
+
+	DEVMETHOD_END
+};
+
+static driver_t ehci_driver = {
+	"ehci",
+	ehci_methods,
+	sizeof(struct ehci_softc),
+};
+static devclass_t ehci_devclass;
+
+DRIVER_MODULE(ehci, simplebus, ehci_driver, ehci_devclass, NULL, NULL);
+MODULE_DEPEND(ehci, usb, 1, 1, 1);


Property changes on: trunk/sys/arm/xilinx/zy7_ehci.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xilinx/zy7_gpio.c
===================================================================
--- trunk/sys/arm/xilinx/zy7_gpio.c	                        (rev 0)
+++ trunk/sys/arm/xilinx/zy7_gpio.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,389 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Thomas Skibo
+ * 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: stable/10/sys/arm/xilinx/zy7_gpio.c 278782 2015-02-14 20:37:33Z loos $
+ */
+
+/*
+ * A GPIO driver for Xilinx Zynq-7000.
+ *
+ * The GPIO peripheral on Zynq allows controlling 114 general purpose I/Os.
+ *
+ * Pins 53-0 are sent to the MIO.  Any MIO pins not used by a PS peripheral are
+ * available as a GPIO pin.  Pins 64-127 are sent to the PL (FPGA) section of
+ * Zynq as EMIO signals.
+ *
+ * The hardware provides a way to use IOs as interrupt sources but the
+ * gpio framework doesn't seem to have hooks for this.
+ *
+ * Reference: Zynq-7000 All Programmable SoC Technical Reference Manual.
+ * (v1.4) November 16, 2012.  Xilinx doc UG585.  GPIO is covered in
+ * chater 14.  Register definitions are in appendix B.19.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/xilinx/zy7_gpio.c 278782 2015-02-14 20:37:33Z loos $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/conf.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+#include <sys/gpio.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+#include <machine/stdarg.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include "gpio_if.h"
+
+#define NUMBANKS	4
+#define MAXPIN		(32*NUMBANKS)
+
+#define MIO_PIN		0	/* pins 0-53 go to MIO */
+#define NUM_MIO_PINS	54
+#define EMIO_PIN	64	/* pins 64-127 go to PL */
+#define NUM_EMIO_PINS	64
+
+#define VALID_PIN(u)	(((u) >= MIO_PIN && (u) < MIO_PIN + NUM_MIO_PINS) || \
+			 ((u) >= EMIO_PIN && (u) < EMIO_PIN + NUM_EMIO_PINS))
+
+#define ZGPIO_LOCK(sc)			mtx_lock(&(sc)->sc_mtx)
+#define	ZGPIO_UNLOCK(sc)		mtx_unlock(&(sc)->sc_mtx)
+#define ZGPIO_LOCK_INIT(sc) \
+	mtx_init(&(sc)->sc_mtx, device_get_nameunit((sc)->dev),	\
+	    "gpio", MTX_DEF)
+#define ZGPIO_LOCK_DESTROY(_sc)	mtx_destroy(&_sc->sc_mtx);
+
+struct zy7_gpio_softc {
+	device_t	dev;
+	struct mtx	sc_mtx;
+	struct resource *mem_res;	/* Memory resource */
+};
+
+#define WR4(sc, off, val)	bus_write_4((sc)->mem_res, (off), (val))
+#define RD4(sc, off)		bus_read_4((sc)->mem_res, (off))
+
+
+/* Xilinx Zynq-7000 GPIO register definitions:
+ */
+#define ZY7_GPIO_MASK_DATA_LSW(b)	(0x0000+8*(b))	/* maskable wr lo */
+#define ZY7_GPIO_MASK_DATA_MSW(b)	(0x0004+8*(b))	/* maskable wr hi */
+#define ZY7_GPIO_DATA(b)		(0x0040+4*(b))	/* in/out data */
+#define ZY7_GPIO_DATA_RO(b)		(0x0060+4*(b))	/* input data */
+
+#define ZY7_GPIO_DIRM(b)		(0x0204+0x40*(b)) /* direction mode */
+#define ZY7_GPIO_OEN(b)			(0x0208+0x40*(b)) /* output enable */
+#define ZY7_GPIO_INT_MASK(b)		(0x020c+0x40*(b)) /* int mask */
+#define ZY7_GPIO_INT_EN(b)		(0x0210+0x40*(b)) /* int enable */
+#define ZY7_GPIO_INT_DIS(b)		(0x0214+0x40*(b)) /* int disable */
+#define ZY7_GPIO_INT_STAT(b)		(0x0218+0x40*(b)) /* int status */
+#define ZY7_GPIO_INT_TYPE(b)		(0x021c+0x40*(b)) /* int type */
+#define ZY7_GPIO_INT_POLARITY(b)	(0x0220+0x40*(b)) /* int polarity */
+#define ZY7_GPIO_INT_ANY(b)		(0x0224+0x40*(b)) /* any edge */
+
+
+static int
+zy7_gpio_pin_max(device_t dev, int *maxpin)
+{
+
+	*maxpin = MAXPIN;
+	return (0);
+}
+
+/* Get a specific pin's capabilities. */
+static int
+zy7_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
+{
+
+	if (!VALID_PIN(pin))
+		return (EINVAL);
+
+	*caps = (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | GPIO_PIN_TRISTATE);
+
+	return (0);
+}
+
+/* Get a specific pin's name. */
+static int
+zy7_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
+{
+
+	if (!VALID_PIN(pin))
+		return (EINVAL);
+
+	if (pin < NUM_MIO_PINS) {
+		snprintf(name, GPIOMAXNAME, "MIO_%d", pin);
+		name[GPIOMAXNAME - 1] = '\0';
+	} else {
+		snprintf(name, GPIOMAXNAME, "EMIO_%d", pin - EMIO_PIN);
+		name[GPIOMAXNAME - 1] = '\0';
+	}
+
+	return (0);
+}
+
+/* Get a specific pin's current in/out/tri state. */
+static int
+zy7_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
+{
+	struct zy7_gpio_softc *sc = device_get_softc(dev);
+
+	if (!VALID_PIN(pin))
+		return (EINVAL);
+
+	ZGPIO_LOCK(sc);
+
+	if ((RD4(sc, ZY7_GPIO_DIRM(pin >> 5)) & (1 << (pin & 31))) != 0) {
+		/* output */
+		if ((RD4(sc, ZY7_GPIO_OEN(pin >> 5)) & (1 << (pin & 31))) == 0)
+			*flags = (GPIO_PIN_OUTPUT | GPIO_PIN_TRISTATE);
+		else
+			*flags = GPIO_PIN_OUTPUT;
+	} else
+		/* input */
+		*flags = GPIO_PIN_INPUT;
+
+	ZGPIO_UNLOCK(sc);
+
+	return (0);
+}
+
+/* Set a specific pin's in/out/tri state. */
+static int
+zy7_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
+{
+	struct zy7_gpio_softc *sc = device_get_softc(dev);
+
+	if (!VALID_PIN(pin))
+		return (EINVAL);
+
+	ZGPIO_LOCK(sc);
+
+	if ((flags & GPIO_PIN_OUTPUT) != 0) {
+		/* Output.  Set or reset OEN too. */
+		WR4(sc, ZY7_GPIO_DIRM(pin >> 5),
+		    RD4(sc, ZY7_GPIO_DIRM(pin >> 5)) | (1 << (pin & 31)));
+
+		if ((flags & GPIO_PIN_TRISTATE) != 0)
+			WR4(sc, ZY7_GPIO_OEN(pin >> 5),
+			    RD4(sc, ZY7_GPIO_OEN(pin >> 5)) &
+			    ~(1 << (pin & 31)));
+		else
+			WR4(sc, ZY7_GPIO_OEN(pin >> 5),
+			    RD4(sc, ZY7_GPIO_OEN(pin >> 5)) |
+			    (1 << (pin & 31)));
+	} else {
+		/* Input.  Turn off OEN. */
+		WR4(sc, ZY7_GPIO_DIRM(pin >> 5),
+		    RD4(sc, ZY7_GPIO_DIRM(pin >> 5)) & ~(1 << (pin & 31)));
+		WR4(sc, ZY7_GPIO_OEN(pin >> 5),
+		    RD4(sc, ZY7_GPIO_OEN(pin >> 5)) & ~(1 << (pin & 31)));
+	}
+		
+	ZGPIO_UNLOCK(sc);
+
+	return (0);
+}
+
+/* Set a specific output pin's value. */
+static int
+zy7_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value)
+{
+	struct zy7_gpio_softc *sc = device_get_softc(dev);
+
+	if (!VALID_PIN(pin) || value > 1)
+		return (EINVAL);
+
+	/* Fancy register tricks allow atomic set or reset. */
+	if ((pin & 16) != 0)
+		WR4(sc, ZY7_GPIO_MASK_DATA_MSW(pin >> 5),
+		    (0xffff0000 ^ (0x10000 << (pin & 15))) |
+		    (value << (pin & 15)));
+	else
+		WR4(sc, ZY7_GPIO_MASK_DATA_LSW(pin >> 5),
+		    (0xffff0000 ^ (0x10000 << (pin & 15))) |
+		    (value << (pin & 15)));
+
+	return (0);
+}
+
+/* Get a specific pin's input value. */
+static int
+zy7_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *value)
+{
+	struct zy7_gpio_softc *sc = device_get_softc(dev);
+
+	if (!VALID_PIN(pin))
+		return (EINVAL);
+
+	*value = (RD4(sc, ZY7_GPIO_DATA_RO(pin >> 5)) >> (pin & 31)) & 1;
+
+	return (0);
+}
+
+/* Toggle a pin's output value. */
+static int
+zy7_gpio_pin_toggle(device_t dev, uint32_t pin)
+{
+	struct zy7_gpio_softc *sc = device_get_softc(dev);
+
+	if (!VALID_PIN(pin))
+		return (EINVAL);
+
+	ZGPIO_LOCK(sc);
+
+	WR4(sc, ZY7_GPIO_DATA(pin >> 5),
+	    RD4(sc, ZY7_GPIO_DATA(pin >> 5)) ^ (1 << (pin & 31)));
+
+	ZGPIO_UNLOCK(sc);
+
+	return (0);
+}
+
+static int
+zy7_gpio_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "xlnx,zy7_gpio"))
+		return (ENXIO);
+
+	device_set_desc(dev, "Zynq-7000 GPIO driver");
+	return (0);
+}
+
+static void
+zy7_gpio_hw_reset(struct zy7_gpio_softc *sc)
+{
+	int i;
+
+	for (i = 0; i < NUMBANKS; i++) {
+		WR4(sc, ZY7_GPIO_DATA(i), 0);
+		WR4(sc, ZY7_GPIO_DIRM(i), 0);
+		WR4(sc, ZY7_GPIO_OEN(i), 0);
+		WR4(sc, ZY7_GPIO_INT_DIS(i), 0xffffffff);
+		WR4(sc, ZY7_GPIO_INT_POLARITY(i), 0);
+		WR4(sc, ZY7_GPIO_INT_TYPE(i),
+		    i == 1 ? 0x003fffff : 0xffffffff);
+		WR4(sc, ZY7_GPIO_INT_ANY(i), 0);
+		WR4(sc, ZY7_GPIO_INT_STAT(i), 0xffffffff);
+	}
+}
+
+static int zy7_gpio_detach(device_t dev);
+
+static int
+zy7_gpio_attach(device_t dev)
+{
+	struct zy7_gpio_softc *sc = device_get_softc(dev);
+	int rid;
+
+	sc->dev = dev;
+
+	ZGPIO_LOCK_INIT(sc);
+
+	/* Allocate memory. */
+	rid = 0;
+	sc->mem_res = bus_alloc_resource_any(dev,
+		     SYS_RES_MEMORY, &rid, RF_ACTIVE);
+	if (sc->mem_res == NULL) {
+		device_printf(dev, "Can't allocate memory for device");
+		zy7_gpio_detach(dev);
+		return (ENOMEM);
+	}
+
+	/* Completely reset. */
+	zy7_gpio_hw_reset(sc);
+
+	device_add_child(dev, "gpioc", -1);
+	device_add_child(dev, "gpiobus", -1);
+
+	return (bus_generic_attach(dev));
+}
+
+static int
+zy7_gpio_detach(device_t dev)
+{
+	struct zy7_gpio_softc *sc = device_get_softc(dev);
+
+	bus_generic_detach(dev);
+
+	if (sc->mem_res != NULL) {
+		/* Release memory resource. */
+		bus_release_resource(dev, SYS_RES_MEMORY,
+				     rman_get_rid(sc->mem_res), sc->mem_res);
+	}
+
+	ZGPIO_LOCK_DESTROY(sc);
+
+	return (0);
+}
+
+static device_method_t zy7_gpio_methods[] = {
+	/* device_if */
+	DEVMETHOD(device_probe, 	zy7_gpio_probe),
+	DEVMETHOD(device_attach, 	zy7_gpio_attach),
+	DEVMETHOD(device_detach, 	zy7_gpio_detach),
+
+	/* GPIO protocol */
+	DEVMETHOD(gpio_pin_max, 	zy7_gpio_pin_max),
+	DEVMETHOD(gpio_pin_getname, 	zy7_gpio_pin_getname),
+	DEVMETHOD(gpio_pin_getflags, 	zy7_gpio_pin_getflags),
+	DEVMETHOD(gpio_pin_getcaps, 	zy7_gpio_pin_getcaps),
+	DEVMETHOD(gpio_pin_setflags, 	zy7_gpio_pin_setflags),
+	DEVMETHOD(gpio_pin_get, 	zy7_gpio_pin_get),
+	DEVMETHOD(gpio_pin_set, 	zy7_gpio_pin_set),
+	DEVMETHOD(gpio_pin_toggle, 	zy7_gpio_pin_toggle),
+
+	DEVMETHOD_END
+};
+
+static driver_t zy7_gpio_driver = {
+	"zy7_gpio",
+	zy7_gpio_methods,
+	sizeof(struct zy7_gpio_softc),
+};
+static devclass_t zy7_gpio_devclass;
+
+extern devclass_t gpiobus_devclass, gpioc_devclass;
+extern driver_t gpiobus_driver, gpioc_driver;
+
+DRIVER_MODULE(zy7_gpio, simplebus, zy7_gpio_driver, zy7_gpio_devclass, \
+	      NULL, NULL);
+DRIVER_MODULE(gpiobus, zy7_gpio, gpiobus_driver, gpiobus_devclass, 0, 0);
+DRIVER_MODULE(gpioc, zy7_gpio, gpioc_driver, gpioc_devclass, 0, 0);


Property changes on: trunk/sys/arm/xilinx/zy7_gpio.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xilinx/zy7_l2cache.c
===================================================================
--- trunk/sys/arm/xilinx/zy7_l2cache.c	                        (rev 0)
+++ trunk/sys/arm/xilinx/zy7_l2cache.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,61 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Thomas Skibo
+ * 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: stable/10/sys/arm/xilinx/zy7_l2cache.c 250015 2013-04-28 07:00:36Z wkoszek $
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/xilinx/zy7_l2cache.c 250015 2013-04-28 07:00:36Z wkoszek $");
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/rman.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+
+#include <machine/bus.h>
+#include <machine/pl310.h>
+
+void
+platform_pl310_init(struct pl310_softc *softc)
+{
+}
+
+void
+platform_pl310_write_ctrl(struct pl310_softc *sc, uint32_t val)
+{
+
+	pl310_write4(sc, PL310_CTRL, val);
+}
+
+void
+platform_pl310_write_debug(struct pl310_softc *sc, uint32_t val)
+{
+
+	pl310_write4(sc, PL310_DEBUG_CTRL, val);
+}


Property changes on: trunk/sys/arm/xilinx/zy7_l2cache.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xilinx/zy7_machdep.c
===================================================================
--- trunk/sys/arm/xilinx/zy7_machdep.c	                        (rev 0)
+++ trunk/sys/arm/xilinx/zy7_machdep.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,147 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Thomas Skibo
+ * 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: stable/10/sys/arm/xilinx/zy7_machdep.c 266379 2014-05-17 23:25:20Z ian $
+ */
+
+/*
+ * Machine dependent code for Xilinx Zynq-7000 Soc.
+ *
+ * Reference: Zynq-7000 All Programmable SoC Technical Reference Manual.
+ * (v1.4) November 16, 2012.  Xilinx doc UG585.
+ */
+
+#include "opt_global.h"
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/xilinx/zy7_machdep.c 266379 2014-05-17 23:25:20Z ian $");
+
+#define _ARM32_BUS_DMA_PRIVATE
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <dev/fdt/fdt_common.h>
+
+#include <machine/bus.h>
+#include <machine/devmap.h>
+#include <machine/machdep.h>
+
+#include <arm/xilinx/zy7_reg.h>
+
+void (*zynq7_cpu_reset)(void);
+
+vm_offset_t
+initarm_lastaddr(void)
+{
+
+	return (arm_devmap_lastaddr());
+}
+
+void
+initarm_early_init(void)
+{
+
+}
+
+void
+initarm_gpio_init(void)
+{
+}
+
+void
+initarm_late_init(void)
+{
+}
+
+/*
+ * Set up static device mappings.  Not strictly necessary -- simplebus will
+ * dynamically establish mappings as needed -- but doing it this way gets us
+ * nice efficient 1MB section mappings.
+ */
+int
+initarm_devmap_init(void)
+{
+
+	arm_devmap_add_entry(ZYNQ7_PSIO_HWBASE, ZYNQ7_PSIO_SIZE);
+	arm_devmap_add_entry(ZYNQ7_PSCTL_HWBASE, ZYNQ7_PSCTL_SIZE);
+
+	return (0);
+}
+
+
+struct fdt_fixup_entry fdt_fixup_table[] = {
+	{ NULL, NULL }
+};
+
+static int
+fdt_gic_decode_ic(phandle_t node, pcell_t *intr, int *interrupt, int *trig,
+    int *pol)
+{
+
+	if (!fdt_is_compatible(node, "arm,gic"))
+		return (ENXIO);
+
+	*interrupt = fdt32_to_cpu(intr[0]);
+	*trig = INTR_TRIGGER_CONFORM;
+	*pol = INTR_POLARITY_CONFORM;
+
+	return (0);
+}
+
+fdt_pic_decode_t fdt_pic_table[] = {
+	&fdt_gic_decode_ic,
+	NULL
+};
+
+
+struct arm32_dma_range *
+bus_dma_get_range(void)
+{
+
+	return (NULL);
+}
+
+int
+bus_dma_get_range_nb(void)
+{
+
+	return (0);
+}
+
+void
+cpu_reset()
+{
+	if (zynq7_cpu_reset != NULL)
+		(*zynq7_cpu_reset)();
+
+	printf("cpu_reset: no platform cpu_reset.  hanging.\n");
+	for (;;)
+		;
+}


Property changes on: trunk/sys/arm/xilinx/zy7_machdep.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xilinx/zy7_mp.c
===================================================================
--- trunk/sys/arm/xilinx/zy7_mp.c	                        (rev 0)
+++ trunk/sys/arm/xilinx/zy7_mp.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,117 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Thomas Skibo.  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 ``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 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: stable/10/sys/arm/xilinx/zy7_mp.c 278701 2015-02-13 20:21:13Z ian $");
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/smp.h>
+
+#include <machine/smp.h>
+#include <machine/fdt.h>
+#include <machine/intr.h>
+
+#include <arm/xilinx/zy7_reg.h>
+
+#define	ZYNQ7_CPU1_ENTRY	0xfffffff0
+
+#define	SCU_CONTROL_REG		0xf8f00000
+#define	   SCU_CONTROL_ENABLE	(1 << 0)
+
+void
+platform_mp_init_secondary(void)
+{
+
+	gic_init_secondary();
+}
+
+void
+platform_mp_setmaxid(void)
+{
+
+	mp_maxid = 1;
+}
+
+int
+platform_mp_probe(void)
+{
+
+	mp_ncpus = 2;
+	return (1);
+}
+
+void    
+platform_mp_start_ap(void)
+{
+	bus_space_handle_t scu_handle;
+	bus_space_handle_t ocm_handle;
+	uint32_t scu_ctrl;
+
+	/* Map in SCU control register. */
+	if (bus_space_map(fdtbus_bs_tag, SCU_CONTROL_REG, 4,
+			  0, &scu_handle) != 0)
+		panic("platform_mp_start_ap: Couldn't map SCU config reg\n");
+
+	/* Set SCU enable bit. */
+	scu_ctrl = bus_space_read_4(fdtbus_bs_tag, scu_handle, 0);
+	scu_ctrl |= SCU_CONTROL_ENABLE;
+	bus_space_write_4(fdtbus_bs_tag, scu_handle, 0, scu_ctrl);
+
+	bus_space_unmap(fdtbus_bs_tag, scu_handle, 4);
+
+	/* Map in magic location to give entry address to CPU1. */
+	if (bus_space_map(fdtbus_bs_tag, ZYNQ7_CPU1_ENTRY, 4,
+	    0, &ocm_handle) != 0)
+		panic("platform_mp_start_ap: Couldn't map OCM\n");
+
+	/* Write start address for CPU1. */
+	bus_space_write_4(fdtbus_bs_tag, ocm_handle, 0,
+	    pmap_kextract((vm_offset_t)mpentry));
+
+	bus_space_unmap(fdtbus_bs_tag, ocm_handle, 4);
+
+	/*
+	 * The SCU is enabled above but I think the second CPU doesn't
+	 * turn on filtering until after the wake-up below. I think that's why
+	 * things don't work if I don't put these cache ops here.  Also, the
+	 * magic location, 0xfffffff0, isn't in the SCU's filtering range so it
+	 * needs a write-back too.
+	 */
+	cpu_idcache_wbinv_all();
+	cpu_l2cache_wbinv_all();
+
+	/* Wake up CPU1. */
+	armv7_sev();
+}
+
+void
+platform_ipi_send(cpuset_t cpus, u_int ipi)
+{
+
+	pic_ipi_send(cpus, ipi);
+}


Property changes on: trunk/sys/arm/xilinx/zy7_mp.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xilinx/zy7_reg.h
===================================================================
--- trunk/sys/arm/xilinx/zy7_reg.h	                        (rev 0)
+++ trunk/sys/arm/xilinx/zy7_reg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,73 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012-2013 Thomas Skibo
+ * 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: stable/10/sys/arm/xilinx/zy7_reg.h 266379 2014-05-17 23:25:20Z ian $
+ */
+
+/*
+ * Address regions of Zynq-7000.  
+ * Reference: Zynq-7000 All Programmable SoC Technical Reference Manual.
+ * (v1.4) November 16, 2012.  Xilinx doc UG585.
+ */
+
+#ifndef _ZY7_REG_H_
+#define _ZY7_REG_H_
+
+/* PL AXI buses:  General Purpose Port #0, M_AXI_GP0. */
+#define ZYNQ7_PLGP0_HWBASE	0x40000000
+#define ZYNQ7_PLGP0_SIZE	0x40000000
+
+/* PL AXI buses:  General Purpose Port #1, M_AXI_GP1. */
+#define ZYNQ7_PLGP1_HWBASE	0x80000000
+#define ZYNQ7_PLGP1_SIZE	0x40000000
+
+/* I/O Peripheral registers. */
+#define ZYNQ7_PSIO_HWBASE	0xE0000000
+#define ZYNQ7_PSIO_SIZE		0x00300000
+
+/* UART0 and UART1 */
+#define ZYNQ7_UART0_HWBASE	(ZYNQ7_PSIO_HWBASE)
+#define ZYNQ7_UART0_SIZE	0x1000
+
+#define ZYNQ7_UART1_HWBASE	(ZYNQ7_PSIO_HWBASE+0x1000)
+#define ZYNQ7_UART1_SIZE	0x1000
+
+
+/* SMC Memories not mapped for now. */
+#define ZYNQ7_SMC_HWBASE	0xE1000000
+#define ZYNQ7_SMC_SIZE		0x05000000
+
+/* SLCR, PS system, and CPU private registers combined in this region. */
+#define ZYNQ7_PSCTL_HWBASE	0xF8000000
+#define ZYNQ7_PSCTL_SIZE	0x01000000
+
+#define ZYNQ7_SLCR_HWBASE	(ZYNQ7_PSCTL_HWBASE)
+#define ZYNQ7_SLCR_SIZE		0x1000
+
+#define ZYNQ7_DEVCFG_HWBASE	(ZYNQ7_PSCTL_HWBASE+0x7000)
+#define ZYNQ7_DEVCFG_SIZE	0x1000
+
+#endif /* _ZY7_REG_H_ */


Property changes on: trunk/sys/arm/xilinx/zy7_reg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xilinx/zy7_slcr.c
===================================================================
--- trunk/sys/arm/xilinx/zy7_slcr.c	                        (rev 0)
+++ trunk/sys/arm/xilinx/zy7_slcr.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,425 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Thomas Skibo
+ * 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: stable/10/sys/arm/xilinx/zy7_slcr.c 273645 2014-10-25 20:34:10Z ian $
+ */
+
+/*
+ * Zynq-700 SLCR driver.  Provides hooks for cpu_reset and PL control stuff.
+ * In the future, maybe MIO control, clock control, etc. could go here.
+ *
+ * Reference: Zynq-7000 All Programmable SoC Technical Reference Manual.
+ * (v1.4) November 16, 2012.  Xilinx doc UG585.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/xilinx/zy7_slcr.c 273645 2014-10-25 20:34:10Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/resource.h>
+#include <sys/sysctl.h>
+#include <sys/rman.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+#include <machine/stdarg.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <arm/xilinx/zy7_slcr.h>
+
+struct zy7_slcr_softc {
+	device_t	dev;
+	struct mtx	sc_mtx;
+	struct resource	*mem_res;
+};
+
+static struct zy7_slcr_softc *zy7_slcr_softc_p;
+extern void (*zynq7_cpu_reset);
+
+#define ZSLCR_LOCK(sc)		mtx_lock(&(sc)->sc_mtx)
+#define	ZSLCR_UNLOCK(sc)		mtx_unlock(&(sc)->sc_mtx)
+#define ZSLCR_LOCK_INIT(sc) \
+	mtx_init(&(sc)->sc_mtx, device_get_nameunit((sc)->dev),	\
+	    "zy7_slcr", MTX_DEF)
+#define ZSLCR_LOCK_DESTROY(_sc)	mtx_destroy(&_sc->sc_mtx);
+
+#define RD4(sc, off) 		(bus_read_4((sc)->mem_res, (off)))
+#define WR4(sc, off, val) 	(bus_write_4((sc)->mem_res, (off), (val)))
+
+#define ZYNQ_DEFAULT_PS_CLK_FREQUENCY	33333333	/* 33.3 Mhz */
+
+
+SYSCTL_NODE(_hw, OID_AUTO, zynq, CTLFLAG_RD, 0, "Xilinx Zynq-7000");
+
+static char zynq_bootmode[64];
+SYSCTL_STRING(_hw_zynq, OID_AUTO, bootmode, CTLFLAG_RD, zynq_bootmode, 0,
+	      "Zynq boot mode");
+
+static char zynq_pssid[100];
+SYSCTL_STRING(_hw_zynq, OID_AUTO, pssid, CTLFLAG_RD, zynq_pssid, 0,
+	   "Zynq PSS IDCODE");
+
+static uint32_t zynq_reboot_status;
+SYSCTL_INT(_hw_zynq, OID_AUTO, reboot_status, CTLFLAG_RD, &zynq_reboot_status,
+	   0, "Zynq REBOOT_STATUS register");
+
+static int ps_clk_frequency;
+SYSCTL_INT(_hw_zynq, OID_AUTO, ps_clk_frequency, CTLFLAG_RD, &ps_clk_frequency,
+	   0, "Zynq PS_CLK Frequency");
+
+static int io_pll_frequency;
+SYSCTL_INT(_hw_zynq, OID_AUTO, io_pll_frequency, CTLFLAG_RD, &io_pll_frequency,
+	   0, "Zynq IO PLL Frequency");
+
+static int arm_pll_frequency;
+SYSCTL_INT(_hw_zynq, OID_AUTO, arm_pll_frequency, CTLFLAG_RD,
+	   &arm_pll_frequency, 0, "Zynq ARM PLL Frequency");
+
+static int ddr_pll_frequency;
+SYSCTL_INT(_hw_zynq, OID_AUTO, ddr_pll_frequency, CTLFLAG_RD,
+	   &ddr_pll_frequency, 0, "Zynq DDR PLL Frequency");
+
+static void
+zy7_slcr_unlock(struct zy7_slcr_softc *sc)
+{
+
+	/* Unlock SLCR with magic number. */
+	WR4(sc, ZY7_SLCR_UNLOCK, ZY7_SLCR_UNLOCK_MAGIC);
+}
+
+static void
+zy7_slcr_lock(struct zy7_slcr_softc *sc)
+{
+
+	/* Lock SLCR with magic number. */
+	WR4(sc, ZY7_SLCR_LOCK, ZY7_SLCR_LOCK_MAGIC);
+}
+
+
+static void
+zy7_slcr_cpu_reset(void)
+{
+	struct zy7_slcr_softc *sc = zy7_slcr_softc_p;
+
+	/* Unlock SLCR registers. */
+	zy7_slcr_unlock(sc);
+
+	/* This has something to do with a work-around so the fsbl will load
+	 * the bitstream after soft-reboot.  It's very important.
+	 */
+	WR4(sc, ZY7_SLCR_REBOOT_STAT,
+	    RD4(sc, ZY7_SLCR_REBOOT_STAT) & 0xf0ffffff);
+
+	/* Soft reset */
+	WR4(sc, ZY7_SLCR_PSS_RST_CTRL, ZY7_SLCR_PSS_RST_CTRL_SOFT_RESET);
+
+	for (;;)
+		;
+}
+
+/* Assert PL resets and disable level shifters in preparation of programming
+ * the PL (FPGA) section.  Called from zy7_devcfg.c.
+ */
+void
+zy7_slcr_preload_pl(void)
+{
+	struct zy7_slcr_softc *sc = zy7_slcr_softc_p;
+
+	if (!sc)
+		return;
+
+	ZSLCR_LOCK(sc);
+
+	/* Unlock SLCR registers. */
+	zy7_slcr_unlock(sc);
+
+	/* Assert top level output resets. */
+	WR4(sc, ZY7_SLCR_FPGA_RST_CTRL, ZY7_SLCR_FPGA_RST_CTRL_RST_ALL);
+
+	/* Disable all level shifters. */
+	WR4(sc, ZY7_SLCR_LVL_SHFTR_EN, 0);
+
+	/* Lock SLCR registers. */
+	zy7_slcr_lock(sc);
+
+	ZSLCR_UNLOCK(sc);
+}
+
+/* After PL configuration, enable level shifters and deassert top-level
+ * PL resets.  Called from zy7_devcfg.c.  Optionally, the level shifters
+ * can be left disabled but that's rare of an FPGA application. That option
+ * is controled by a sysctl in the devcfg driver.
+ */
+void
+zy7_slcr_postload_pl(int en_level_shifters)
+{
+	struct zy7_slcr_softc *sc = zy7_slcr_softc_p;
+
+	if (!sc)
+		return;
+
+	ZSLCR_LOCK(sc);
+
+	/* Unlock SLCR registers. */
+	zy7_slcr_unlock(sc);
+
+	if (en_level_shifters)
+		/* Enable level shifters. */
+		WR4(sc, ZY7_SLCR_LVL_SHFTR_EN, ZY7_SLCR_LVL_SHFTR_EN_ALL);
+
+	/* Deassert top level output resets. */
+	WR4(sc, ZY7_SLCR_FPGA_RST_CTRL, 0);
+
+	/* Lock SLCR registers. */
+	zy7_slcr_lock(sc);
+
+	ZSLCR_UNLOCK(sc);
+}
+
+/* Override cgem_set_refclk() in gigabit ethernet driver
+ * (sys/dev/cadence/if_cgem.c).  This function is called to
+ * request a change in the gem's reference clock speed.
+ */
+int
+cgem_set_ref_clk(int unit, int frequency)
+{
+	struct zy7_slcr_softc *sc = zy7_slcr_softc_p;
+	int div0, div1;
+
+	if (!sc)
+		return (-1);
+
+	/* Find suitable divisor pairs.  Round result to nearest khz
+	 * to test for match.
+	 */
+	for (div1 = 1; div1 <= ZY7_SLCR_GEM_CLK_CTRL_DIVISOR1_MAX; div1++) {
+		div0 = (io_pll_frequency + div1 * frequency / 2) /
+			div1 / frequency;
+		if (div0 > 0 && div0 <= ZY7_SLCR_GEM_CLK_CTRL_DIVISOR_MAX &&
+		    ((io_pll_frequency / div0 / div1) + 500) / 1000 ==
+		    (frequency + 500) / 1000)
+			break;
+	}
+
+	if (div1 > ZY7_SLCR_GEM_CLK_CTRL_DIVISOR1_MAX)
+		return (-1);
+
+	ZSLCR_LOCK(sc);
+
+	/* Unlock SLCR registers. */
+	zy7_slcr_unlock(sc);
+
+	/* Modify GEM reference clock. */
+	WR4(sc, unit ? ZY7_SLCR_GEM1_CLK_CTRL : ZY7_SLCR_GEM0_CLK_CTRL,
+	    (div1 << ZY7_SLCR_GEM_CLK_CTRL_DIVISOR1_SHIFT) |
+	    (div0 << ZY7_SLCR_GEM_CLK_CTRL_DIVISOR_SHIFT) |
+	    ZY7_SLCR_GEM_CLK_CTRL_SRCSEL_IO_PLL |
+	    ZY7_SLCR_GEM_CLK_CTRL_CLKACT);
+
+	/* Lock SLCR registers. */
+	zy7_slcr_lock(sc);
+
+	ZSLCR_UNLOCK(sc);
+
+	return (0);
+}
+
+static int
+zy7_slcr_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "xlnx,zy7_slcr"))
+		return (ENXIO);
+
+	device_set_desc(dev, "Zynq-7000 slcr block");
+	return (0);
+}
+
+static int
+zy7_slcr_attach(device_t dev)
+{
+	struct zy7_slcr_softc *sc = device_get_softc(dev);
+	int rid;
+	phandle_t node;
+	pcell_t cell;
+	uint32_t bootmode;
+	uint32_t pss_idcode;
+	uint32_t arm_pll_ctrl;
+	uint32_t ddr_pll_ctrl;
+	uint32_t io_pll_ctrl;
+	static char *bootdev_names[] = {
+		"JTAG", "Quad-SPI", "NOR", "(3?)",
+		"NAND", "SD Card", "(6?)", "(7?)"
+	};
+
+	/* Allow only one attach. */
+	if (zy7_slcr_softc_p != NULL)
+		return (ENXIO);
+
+	sc->dev = dev;
+
+	ZSLCR_LOCK_INIT(sc);
+
+	/* Get memory resource. */
+	rid = 0;
+	sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+					     RF_ACTIVE);
+	if (sc->mem_res == NULL) {
+		device_printf(dev, "could not allocate memory resources.\n");
+		return (ENOMEM);
+	}
+
+	/* Hook up cpu_reset. */
+	zy7_slcr_softc_p = sc;
+	zynq7_cpu_reset = zy7_slcr_cpu_reset;
+
+	/* Read info and set sysctls. */
+	bootmode = RD4(sc, ZY7_SLCR_BOOT_MODE);
+	snprintf(zynq_bootmode, sizeof(zynq_bootmode),
+		 "0x%x: boot device: %s", bootmode,
+		 bootdev_names[bootmode & ZY7_SLCR_BOOT_MODE_BOOTDEV_MASK]);
+
+	pss_idcode = RD4(sc, ZY7_SLCR_PSS_IDCODE);
+	snprintf(zynq_pssid, sizeof(zynq_pssid),
+		 "0x%x: manufacturer: 0x%x device: 0x%x "
+		 "family: 0x%x sub-family: 0x%x rev: 0x%x",
+		 pss_idcode,
+		 (pss_idcode & ZY7_SLCR_PSS_IDCODE_MNFR_ID_MASK) >>
+		 ZY7_SLCR_PSS_IDCODE_MNFR_ID_SHIFT,
+		 (pss_idcode & ZY7_SLCR_PSS_IDCODE_DEVICE_MASK) >>
+		 ZY7_SLCR_PSS_IDCODE_DEVICE_SHIFT,
+		 (pss_idcode & ZY7_SLCR_PSS_IDCODE_FAMILY_MASK) >>
+		 ZY7_SLCR_PSS_IDCODE_FAMILY_SHIFT,
+		 (pss_idcode & ZY7_SLCR_PSS_IDCODE_SUB_FAMILY_MASK) >>
+		 ZY7_SLCR_PSS_IDCODE_SUB_FAMILY_SHIFT,
+		 (pss_idcode & ZY7_SLCR_PSS_IDCODE_REVISION_MASK) >>
+		 ZY7_SLCR_PSS_IDCODE_REVISION_SHIFT);
+
+	zynq_reboot_status = RD4(sc, ZY7_SLCR_REBOOT_STAT);
+
+	/* Derive PLL frequencies from PS_CLK. */
+	node = ofw_bus_get_node(dev);
+	if (OF_getprop(node, "clock-frequency", &cell, sizeof(cell)) > 0)
+		ps_clk_frequency = fdt32_to_cpu(cell);
+	else
+		ps_clk_frequency = ZYNQ_DEFAULT_PS_CLK_FREQUENCY;
+
+	arm_pll_ctrl = RD4(sc, ZY7_SLCR_ARM_PLL_CTRL);
+	ddr_pll_ctrl = RD4(sc, ZY7_SLCR_DDR_PLL_CTRL);
+	io_pll_ctrl = RD4(sc, ZY7_SLCR_IO_PLL_CTRL);
+
+	/* Determine ARM PLL frequency. */
+	if (((arm_pll_ctrl & ZY7_SLCR_PLL_CTRL_BYPASS_QUAL) == 0 &&
+	     (arm_pll_ctrl & ZY7_SLCR_PLL_CTRL_BYPASS_FORCE) != 0) ||
+	    ((arm_pll_ctrl & ZY7_SLCR_PLL_CTRL_BYPASS_QUAL) != 0 &&
+	     (bootmode & ZY7_SLCR_BOOT_MODE_PLL_BYPASS) != 0))
+		/* PLL is bypassed. */
+		arm_pll_frequency = ps_clk_frequency;
+	else
+		arm_pll_frequency = ps_clk_frequency *
+			((arm_pll_ctrl & ZY7_SLCR_PLL_CTRL_FDIV_MASK) >>
+			 ZY7_SLCR_PLL_CTRL_FDIV_SHIFT);
+
+	/* Determine DDR PLL frequency. */
+	if (((ddr_pll_ctrl & ZY7_SLCR_PLL_CTRL_BYPASS_QUAL) == 0 &&
+	     (ddr_pll_ctrl & ZY7_SLCR_PLL_CTRL_BYPASS_FORCE) != 0) ||
+	    ((ddr_pll_ctrl & ZY7_SLCR_PLL_CTRL_BYPASS_QUAL) != 0 &&
+	     (bootmode & ZY7_SLCR_BOOT_MODE_PLL_BYPASS) != 0))
+		/* PLL is bypassed. */
+		ddr_pll_frequency = ps_clk_frequency;
+	else
+		ddr_pll_frequency = ps_clk_frequency *
+			((ddr_pll_ctrl & ZY7_SLCR_PLL_CTRL_FDIV_MASK) >>
+			 ZY7_SLCR_PLL_CTRL_FDIV_SHIFT);
+
+	/* Determine IO PLL frequency. */
+	if (((io_pll_ctrl & ZY7_SLCR_PLL_CTRL_BYPASS_QUAL) == 0 &&
+	     (io_pll_ctrl & ZY7_SLCR_PLL_CTRL_BYPASS_FORCE) != 0) ||
+	    ((io_pll_ctrl & ZY7_SLCR_PLL_CTRL_BYPASS_QUAL) != 0 &&
+	     (bootmode & ZY7_SLCR_BOOT_MODE_PLL_BYPASS) != 0))
+		/* PLL is bypassed. */
+		io_pll_frequency = ps_clk_frequency;
+	else
+		io_pll_frequency = ps_clk_frequency *
+			((io_pll_ctrl & ZY7_SLCR_PLL_CTRL_FDIV_MASK) >>
+			 ZY7_SLCR_PLL_CTRL_FDIV_SHIFT);
+
+	/* Lock SLCR registers. */
+	zy7_slcr_lock(sc);
+
+	return (0);
+}
+
+static int
+zy7_slcr_detach(device_t dev)
+{
+	struct zy7_slcr_softc *sc = device_get_softc(dev);
+
+	bus_generic_detach(dev);
+
+	/* Release memory resource. */
+	if (sc->mem_res != NULL)
+		bus_release_resource(dev, SYS_RES_MEMORY,
+			     rman_get_rid(sc->mem_res), sc->mem_res);
+
+	zy7_slcr_softc_p = NULL;
+	zynq7_cpu_reset = NULL;
+
+	ZSLCR_LOCK_DESTROY(sc);
+
+	return (0);
+}
+
+static device_method_t zy7_slcr_methods[] = {
+	/* device_if */
+	DEVMETHOD(device_probe, 	zy7_slcr_probe),
+	DEVMETHOD(device_attach, 	zy7_slcr_attach),
+	DEVMETHOD(device_detach, 	zy7_slcr_detach),
+
+	DEVMETHOD_END
+};
+
+static driver_t zy7_slcr_driver = {
+	"zy7_slcr",
+	zy7_slcr_methods,
+	sizeof(struct zy7_slcr_softc),
+};
+static devclass_t zy7_slcr_devclass;
+
+DRIVER_MODULE(zy7_slcr, simplebus, zy7_slcr_driver, zy7_slcr_devclass, 0, 0);
+MODULE_VERSION(zy7_slcr, 1);


Property changes on: trunk/sys/arm/xilinx/zy7_slcr.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xilinx/zy7_slcr.h
===================================================================
--- trunk/sys/arm/xilinx/zy7_slcr.h	                        (rev 0)
+++ trunk/sys/arm/xilinx/zy7_slcr.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,293 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Thomas Skibo
+ * 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: stable/10/sys/arm/xilinx/zy7_slcr.h 273645 2014-10-25 20:34:10Z ian $
+ */
+
+/*
+ * Defines for Zynq-7000 SLCR registers.
+ *
+ * Most of these registers are initialized by the First Stage Boot
+ * Loader and are not modified by the kernel.
+ *
+ * Reference: Zynq-7000 All Programmable SoC Technical Reference Manual.
+ * (v1.4) November 16, 2012.  Xilinx doc UG585.  SLCR register definitions
+ * are in appendix B.28.
+ */
+
+
+#ifndef _ZY7_SLCR_H_
+#define _ZY7_SLCR_H_
+
+#define ZY7_SCLR_SCL			0x0000
+#define ZY7_SLCR_LOCK			0x0004
+#define   ZY7_SLCR_LOCK_MAGIC				0x767b
+#define ZY7_SLCR_UNLOCK			0x0008
+#define   ZY7_SLCR_UNLOCK_MAGIC				0xdf0d
+#define ZY7_SLCR_LOCKSTA		0x000c
+
+/* PLL controls. */
+#define ZY7_SLCR_ARM_PLL_CTRL		0x0100
+#define ZY7_SLCR_DDR_PLL_CTRL		0x0104
+#define ZY7_SLCR_IO_PLL_CTRL		0x0108
+#define   ZY7_SLCR_PLL_CTRL_RESET			(1<<0)
+#define   ZY7_SLCR_PLL_CTRL_PWRDWN			(1<<1)
+#define   ZY7_SLCR_PLL_CTRL_BYPASS_QUAL			(1<<3)
+#define   ZY7_SLCR_PLL_CTRL_BYPASS_FORCE		(1<<4)
+#define   ZY7_SLCR_PLL_CTRL_FDIV_SHIFT			12
+#define   ZY7_SLCR_PLL_CTRL_FDIV_MASK			(0x7f<<12)
+#define ZY7_SLCR_PLL_STATUS		0x010c
+#define   ZY7_SLCR_PLL_STAT_ARM_PLL_LOCK		(1<<0)
+#define   ZY7_SLCR_PLL_STAT_DDR_PLL_LOCK		(1<<1)
+#define   ZY7_SLCR_PLL_STAT_IO_PLL_LOCK			(1<<2)
+#define   ZY7_SLCR_PLL_STAT_ARM_PLL_STABLE		(1<<3)
+#define   ZY7_SLCR_PLL_STAT_DDR_PLL_STABLE		(1<<4)
+#define   ZY7_SLCR_PLL_STAT_IO_PLL_STABLE		(1<<5)
+#define ZY7_SLCR_ARM_PLL_CFG		0x0110
+#define ZY7_SLCR_DDR_PLL_CFG		0x0114
+#define ZY7_SLCR_IO_PLL_CFG		0x0118
+#define   ZY7_SLCR_PLL_CFG_RES_SHIFT			4
+#define   ZY7_SLCR_PLL_CFG_RES_MASK			(0xf<<4)
+#define   ZY7_SLCR_PLL_CFG_PLL_CP_SHIFT			8
+#define   ZY7_SLCR_PLL_CFG_PLL_CP_MASK			(0xf<<8)
+#define   ZY7_SLCR_PLL_CFG_LOCK_CNT_SHIFT		12
+#define   ZY7_SLCR_PLL_CFG_LOCK_CNT_MASK		(0x3ff<<12)
+
+/* Clock controls. */
+#define ZY7_SLCR_ARM_CLK_CTRL		0x0120
+#define   ZY7_SLCR_ARM_CLK_CTRL_CPU_PERI_CLKACT		(1<<28)
+#define   ZY7_SLCR_ARM_CLK_CTRL_CPU_1XCLKACT		(1<<27)
+#define   ZY7_SLCR_ARM_CLK_CTRL_CPU_2XCLKACT		(1<<26)
+#define   ZY7_SLCR_ARM_CLK_CTRL_CPU_3OR2XCLKACT 	(1<<25)
+#define   ZY7_SLCR_ARM_CLK_CTRL_CPU_6OR4XCLKACT 	(1<<24)
+#define   ZY7_SLCR_ARM_CLK_CTRL_SRCSEL_MASK		(3<<4)
+#define   ZY7_SLCR_ARM_CLK_CTRL_SRCSEL_ARM_PLL		(0<<4)
+#define   ZY7_SLCR_ARM_CLK_CTRL_SRCSEL_DDR_PLL		(2<<4)
+#define   ZY7_SLCR_ARM_CLK_CTRL_SRCSEL_IO_PLL		(3<<4)
+#define   ZY7_SLCR_ARM_CLK_CTRL_DIVISOR_SHIFT		8
+#define   ZY7_SLCR_ARM_CLK_CTRL_DIVISOR_MASK		(0x3f<<8)
+#define ZY7_SLCR_DDR_CLK_CTRL		0x0124
+#define   ZY7_SLCR_DDR_CLK_CTRL_2XCLK_DIV_SHIFT 	26
+#define   ZY7_SLCR_DDR_CLK_CTRL_2XCLK_DIV_MASK		(0x3f<<26)
+#define   ZY7_SLCR_DDR_CLK_CTRL_3XCLK_DIV_SHIFT		20
+#define   ZY7_SLCR_DDR_CLK_CTRL_3XCLK_DIV_MASK		(0x3f<<20)
+#define   ZY7_SLCR_DDR_CLK_CTRL_2XCLKACT		(1<<1)
+#define   ZY7_SLCR_DDR_CLK_CTRL_3XCLKACT		(1<<0)
+#define ZY7_SLCR_DCI_CLK_CTRL		0x0128
+#define   ZY7_SLCR_DCI_CLK_CTRL_DIVISOR1_SHIFT		20
+#define   ZY7_SLCR_DCI_CLK_CTRL_DIVISOR1_MASK		(0x3f<<20)
+#define   ZY7_SLCR_DCI_CLK_CTRL_DIVISOR0_SHIFT		8
+#define   ZY7_SLCR_DCI_CLK_CTRL_DIVISOR0_MASK		(0x3f<<8)
+#define   ZY7_SLCR_DCI_CLK_CTRL_CLKACT			(1<<0)
+#define ZY7_SLCR_APER_CLK_CTRL		0x012c	/* amba periph clk ctrl */
+#define   ZY7_SLCR_APER_CLK_CTRL_SMC_CPU_1XCLKACT	(1<<24)
+#define   ZY7_SLCR_APER_CLK_CTRL_LQSPI_CPU_1XCLKACT	(1<<23)
+#define   ZY7_SLCR_APER_CLK_CTRL_GPIO_CPU_1XCLKACT	(1<<22)
+#define   ZY7_SLCR_APER_CLK_CTRL_UART1_CPU_1XCLKACT	(1<<21)
+#define   ZY7_SLCR_APER_CLK_CTRL_UART0_CPU_1XCLKACT	(1<<20)
+#define   ZY7_SLCR_APER_CLK_CTRL_I2C1_CPU_1XCLKACT	(1<<19)
+#define   ZY7_SLCR_APER_CLK_CTRL_I2C0_CPU_1XCLKACT	(1<<18)
+#define   ZY7_SLCR_APER_CLK_CTRL_CAN1_CPU_1XCLKACT	(1<<17)
+#define   ZY7_SLCR_APER_CLK_CTRL_CAN0_CPU_1XCLKACT	(1<<16)
+#define   ZY7_SLCR_APER_CLK_CTRL_SPI1_CPU_1XCLKACT	(1<<15)
+#define   ZY7_SLCR_APER_CLK_CTRL_SPI0_CPU_1XCLKACT	(1<<14)
+#define   ZY7_SLCR_APER_CLK_CTRL_SDI1_CPU_1XCLKACT	(1<<11)
+#define   ZY7_SLCR_APER_CLK_CTRL_SDI0_CPU_1XCLKACT	(1<<10)
+#define   ZY7_SLCR_APER_CLK_CTRL_GEM1_CPU_1XCLKACT	(1<<7)
+#define   ZY7_SLCR_APER_CLK_CTRL_GEM0_CPU_1XCLKACT	(1<<6)
+#define   ZY7_SLCR_APER_CLK_CTRL_USB1_CPU_1XCLKACT	(1<<3)
+#define   ZY7_SLCR_APER_CLK_CTRL_USB0_CPU_1XCLKACT	(1<<2)
+#define   ZY7_SLCR_APER_CLK_CTRL_DMA_CPU_1XCLKACT	(1<<0)
+#define ZY7_SLCR_USB0_CLK_CTRL		0x0130
+#define ZY7_SLCR_USB1_CLK_CTRL		0x0134
+#define ZY7_SLCR_GEM0_RCLK_CTRL		0x0138
+#define ZY7_SLCR_GEM1_RCLK_CTRL		0x013c
+#define ZY7_SLCR_GEM0_CLK_CTRL		0x0140
+#define ZY7_SLCR_GEM1_CLK_CTRL		0x0144
+#define   ZY7_SLCR_GEM_CLK_CTRL_DIVISOR1_MASK		(0x3f<<20)
+#define   ZY7_SLCR_GEM_CLK_CTRL_DIVISOR1_SHIFT		20
+#define   ZY7_SLCR_GEM_CLK_CTRL_DIVISOR1_MAX		0x3f
+#define   ZY7_SLCR_GEM_CLK_CTRL_DIVISOR_MASK		(0x3f<<8)
+#define   ZY7_SLCR_GEM_CLK_CTRL_DIVISOR_SHIFT		8
+#define   ZY7_SLCR_GEM_CLK_CTRL_DIVISOR_MAX		0x3f
+#define   ZY7_SLCR_GEM_CLK_CTRL_SRCSEL_MASK		(7<<4)
+#define   ZY7_SLCR_GEM_CLK_CTRL_SRCSEL_IO_PLL		(0<<4)
+#define   ZY7_SLCR_GEM_CLK_CTRL_SRCSEL_ARM_PLL		(2<<4)
+#define   ZY7_SLCR_GEM_CLK_CTRL_SRCSEL_DDR_PLL		(3<<4)
+#define   ZY7_SLCR_GEM_CLK_CTRL_SRCSEL_EMIO_CLK		(4<<4)
+#define   ZY7_SLCR_GEM_CLK_CTRL_CLKACT			1
+#define ZY7_SLCR_SMC_CLK_CTRL		0x0148
+#define ZY7_SLCR_LQSPI_CLK_CTRL		0x014c
+#define ZY7_SLCR_SDIO_CLK_CTRL		0x0150
+#define ZY7_SLCR_UART_CLK_CTRL		0x0154
+#define ZY7_SLCR_SPI_CLK_CTRL		0x0158
+#define ZY7_SLCR_CAN_CLK_CTRL		0x015c
+#define ZY7_SLCR_CAN_MIOCLK_CTRL	0x0160
+#define ZY7_SLCR_DBG_CLK_CTRL		0x0164
+#define ZY7_SLCR_PCAP_CLK_CTRL		0x0168
+#define ZY7_SLCR_TOPSW_CLK_CTRL		0x016c	/* central intercnn clk ctrl */
+#define ZY7_SLCR_FPGA0_CLK_CTRL		0x0170
+#define ZY7_SLCR_FPGA1_CLK_CTRL		0x0180
+#define ZY7_SLCR_FPGA2_CLK_CTRL		0x0190
+#define ZY7_SLCR_FPGA3_CLK_CTRL		0x01a0
+#define ZY7_SLCR_CLK_621_TRUE		0x01c4	/* cpu clock ratio mode */
+
+/* Reset controls. */
+#define ZY7_SLCR_PSS_RST_CTRL		0x0200
+#define   ZY7_SLCR_PSS_RST_CTRL_SOFT_RESET		(1<<0)
+#define ZY7_SLCR_DDR_RST_CTRL		0x0204
+#define ZY7_SLCR_TOPSW_RST_CTRL		0x0208
+#define ZY7_SLCR_DMAC_RST_CTRL		0x020c
+#define ZY7_SLCR_USB_RST_CTRL		0x0210
+#define ZY7_SLCR_GEM_RST_CTRL		0x0214
+#define ZY7_SLCR_SDIO_RST_CTRL		0x0218
+#define ZY7_SLCR_SPI_RST_CTRL		0x021c
+#define ZY7_SLCR_CAN_RST_CTRL		0x0220
+#define ZY7_SLCR_I2C_RST_CTRL		0x0224
+#define ZY7_SLCR_UART_RST_CTRL		0x0228
+#define ZY7_SLCR_GPIO_RST_CTRL		0x022c
+#define ZY7_SLCR_LQSPI_RST_CTRL		0x0230
+#define ZY7_SLCR_SMC_RST_CTRL		0x0234
+#define ZY7_SLCR_OCM_RST_CTRL		0x0238
+#define ZY7_SLCR_DEVCI_RST_CTRL		0x023c
+#define ZY7_SLCR_FPGA_RST_CTRL		0x0240
+#define   ZY7_SLCR_FPGA_RST_CTRL_FPGA3_OUT_RST		(1<<3)
+#define   ZY7_SLCR_FPGA_RST_CTRL_FPGA2_OUT_RST		(1<<2)
+#define   ZY7_SLCR_FPGA_RST_CTRL_FPGA1_OUT_RST		(1<<1)
+#define   ZY7_SLCR_FPGA_RST_CTRL_FPGA0_OUT_RST		(1<<0)
+#define   ZY7_SLCR_FPGA_RST_CTRL_RST_ALL		0xf
+#define ZY7_SLCR_A9_CPU_RST_CTRL	0x0244
+#define ZY7_SLCR_RS_AWDT_CTRL		0x024c
+
+#define ZY7_SLCR_REBOOT_STAT		0x0258
+#define   ZY7_SLCR_REBOOT_STAT_STATE_MASK		(0xff<<24)
+#define   ZY7_SLCR_REBOOT_STAT_POR			(1<<22)
+#define   ZY7_SLCR_REBOOT_STAT_SRST_B			(1<<21)
+#define   ZY7_SLCR_REBOOT_STAT_DBG_RST			(1<<20)
+#define   ZY7_SLCR_REBOOT_STAT_SLC_RST			(1<<19)
+#define   ZY7_SLCR_REBOOT_STAT_AWDT1_RST		(1<<18)
+#define   ZY7_SLCR_REBOOT_STAT_AWDT0_RST		(1<<17)
+#define   ZY7_SLCR_REBOOT_STAT_SWDT_RST			(1<<16)
+#define   ZY7_SLCR_REBOOT_STAT_BOOTROM_ERR_CODE_MASK 	(0xffff)
+#define ZY7_SLCR_BOOT_MODE		0x025c
+#define   ZY7_SLCR_BOOT_MODE_PLL_BYPASS			(1<<4)
+#define   ZY7_SLCR_BOOT_MODE_JTAG_INDEP			(1<<3)
+#define   ZY7_SLCR_BOOT_MODE_BOOTDEV_MASK		7
+#define   ZY7_SLCR_BOOT_MODE_BOOTDEV_JTAG		0
+#define   ZY7_SLCR_BOOT_MODE_BOOTDEV_QUAD_SPI		1
+#define   ZY7_SLCR_BOOT_MODE_BOOTDEV_NOR		2
+#define   ZY7_SLCR_BOOT_MODE_BOOTDEV_NAND		4
+#define   ZY7_SLCR_BOOT_MODE_BOOTDEV_SD_CARD		5
+#define ZY7_SLCR_APU_CTRL		0x0300
+#define ZY7_SLCR_WDT_CLK_SEL		0x0304
+
+#define ZY7_SLCR_PSS_IDCODE		0x0530
+#define   ZY7_SLCR_PSS_IDCODE_REVISION_MASK		(0xf<<28)
+#define   ZY7_SLCR_PSS_IDCODE_REVISION_SHIFT		28
+#define   ZY7_SLCR_PSS_IDCODE_FAMILY_MASK		(0x7f<<21)
+#define   ZY7_SLCR_PSS_IDCODE_FAMILY_SHIFT		21
+#define   ZY7_SLCR_PSS_IDCODE_SUB_FAMILY_MASK		(0xf<<17)
+#define   ZY7_SLCR_PSS_IDCODE_SUB_FAMILY_SHIFT		17
+#define   ZY7_SLCR_PSS_IDCODE_DEVICE_MASK		(0x1f<<12)
+#define   ZY7_SLCR_PSS_IDCODE_DEVICE_SHIFT		12
+#define   ZY7_SLCR_PSS_IDCODE_MNFR_ID_MASK		(0x7ff<<1)
+#define   ZY7_SLCR_PSS_IDCODE_MNFR_ID_SHIFT		1
+
+#define ZY7_SLCR_DDR_URGENT		0x0600
+#define ZY7_SLCR_DDR_CAL_START		0x060c
+#define ZY7_SLCR_DDR_REF_START		0x0614
+#define ZY7_SLCR_DDR_CMD_STA		0x0618
+#define ZY7_SLCR_DDR_URGENT_SEL		0x061c
+#define ZY7_SLCR_DDR_DFI_STATUS		0x0620
+
+/* MIO Pin controls */
+#define ZY7_SLCR_MIO_PIN(n)		(0x0700+(n)*4)		/* 0-53 */
+#define   ZY7_SLCR_MIO_PIN_RCVR_DIS			(1<<13)
+#define   ZY7_SLCR_MIO_PIN_PULLUP_EN			(1<<12)
+#define   ZY7_SLCR_MIO_PIN_IO_TYPE_MASK			(7<<9)
+#define   ZY7_SLCR_MIO_PIN_IO_TYPE_LVTTL		(0<<9)
+#define   ZY7_SLCR_MIO_PIN_IO_TYPE_LVCMOS18		(1<<9)
+#define   ZY7_SLCR_MIO_PIN_IO_TYPE_LVCMOS25		(2<<9)
+#define   ZY7_SLCR_MIO_PIN_IO_TYPE_LVCMOS33		(3<<9)
+#define   ZY7_SLCR_MIO_PIN_IO_TYPE_HSTL			(4<<9)
+#define   ZY7_SLCR_MIO_PIN_L2_SEL_MASK			(3<<3)
+#define   ZY7_SLCR_MIO_PIN_L2_SEL_L3_MUX		(0<<3)
+#define   ZY7_SLCR_MIO_PIN_L2_SEL_SRAM_NOR_CS0		(1<<3)
+#define   ZY7_SLCR_MIO_PIN_L2_SEL_NAND_CS		(2<<3)
+#define   ZY7_SLCR_MIO_PIN_L2_SEL_SDIO0_PC		(3<<3)
+#define   ZY7_SLCR_MIO_PIN_L1_SEL			(1<<2)
+#define   ZY7_SLCR_MIO_PIN_L0_SEL			(1<<1)
+#define   ZY7_SLCR_MIO_PIN_TRI_EN			(1<<0)
+
+#define ZY7_SLCR_MIO_LOOPBACK		0x0804
+#define   ZY7_SLCR_MIO_LOOPBACK_I2C0_I2C1		(1<<3)
+#define   ZY7_SLCR_MIO_LOOPBACK_CAN0_CAN1		(1<<2)
+#define   ZY7_SLCR_MIO_LOOPBACK_UA0_UA1			(1<<1)
+#define   ZY7_SLCR_MIO_LOOPBACK_SPI0_SPI1		(1<<0)
+#define ZY7_SLCR_MIO_MST_TRI0		0x080c
+#define ZY7_SLCR_MIO_MST_TRI1		0x0810
+#define ZY7_SLCR_SD0_WP_CD_SEL		0x0830
+#define ZY7_SLCR_SD1_WP_CD_SEL		0x0834
+
+/* PS-PL level shifter control. */
+#define ZY7_SLCR_LVL_SHFTR_EN		0x900
+#define   ZY7_SLCR_LVL_SHFTR_EN_USER_LVL_IN_EN_0	(1<<3)	/* PL to PS */
+#define   ZY7_SLCR_LVL_SHFTR_EN_USER_LVL_OUT_EN_0	(1<<2)	/* PS to PL */
+#define   ZY7_SLCR_LVL_SHFTR_EN_USER_LVL_IN_EN_1	(1<<1)	/* PL to PS */
+#define   ZY7_SLCR_LVL_SHFTR_EN_USER_LVL_OUT_EN_1	(1<<0)	/* PS to PL */
+#define   ZY7_SLCR_LVL_SHFTR_EN_ALL			0xf
+
+#define ZY7_SLCR_OCM_CFG		0x0910
+
+#define ZY7_SLCR_GPIOB_CTRL		0x0b00
+#define ZY7_SLCR_GPIOB_CFG_CMOS18	0x0b04
+#define ZY7_SLCR_GPIOB_CFG_CMOS25	0x0b08
+#define ZY7_SLCR_GPIOB_CFG_CMOS33	0x0b0c
+#define ZY7_SLCR_GPIOB_CFG_LVTTL	0x0b10
+#define ZY7_SLCR_GPIOB_CFG_HSTL		0x0b14
+#define ZY7_SLCR_GPIOB_DRVR_BIAS_CTRL	0x0b18
+
+#define ZY7_SLCR_DDRIOB_ADDR0		0x0b40
+#define ZY7_SLCR_DDRIOB_ADDR1		0x0b44
+#define ZY7_SLCR_DDRIOB_DATA0		0x0b48
+#define ZY7_SLCR_DDRIOB_DATA1		0x0b4c
+#define ZY7_SLCR_DDRIOB_DIFF0		0x0b50
+#define ZY7_SLCR_DDRIOB_DIFF1		0x0b54
+#define ZY7_SLCR_DDRIOB_CLK		0x0b58
+#define ZY7_SLCR_DDRIOB_DRIVE_SLEW_ADDR	0x0b5c
+#define ZY7_SLCR_DDRIOB_DRIVE_SLEW_DATA	0x0b60
+#define ZY7_SLCR_DDRIOB_DRIVE_SLEW_DIFF	0x0b64
+#define ZY7_SLCR_DDRIOB_DRIVE_SLEW_CLK 	0x0b68
+#define ZY7_SLCR_DDRIOB_DDR_CTRL	0x0b6c
+#define ZY7_SLCR_DDRIOB_DCI_CTRL	0x0b70
+#define ZY7_SLCR_DDRIOB_DCI_STATUS	0x0b74
+
+#ifdef _KERNEL
+extern void zy7_slcr_preload_pl(void);
+extern void zy7_slcr_postload_pl(int en_level_shifters);
+extern int cgem_set_ref_clk(int unit, int frequency);
+#endif
+#endif /* _ZY7_SLCR_H_ */


Property changes on: trunk/sys/arm/xilinx/zy7_slcr.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/i80321/ep80219_machdep.c
===================================================================
--- trunk/sys/arm/xscale/i80321/ep80219_machdep.c	                        (rev 0)
+++ trunk/sys/arm/xscale/i80321/ep80219_machdep.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,397 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: hpc_machdep.c,v 1.70 2003/09/16 08:18:22 agc Exp $	*/
+
+/*-
+ * Copyright (c) 1994-1998 Mark Brinicombe.
+ * Copyright (c) 1994 Brini.
+ * All rights reserved.
+ *
+ * This code is derived from software written for Brini by Mark Brinicombe
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by Brini.
+ * 4. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BRINI ``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 BRINI 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.
+ *
+ * RiscBSD kernel project
+ *
+ * machdep.c
+ *
+ * Machine dependant functions for kernel setup
+ *
+ * This file needs a lot of work.
+ *
+ * Created      : 17/09/94
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/xscale/i80321/ep80219_machdep.c 278727 2015-02-13 22:32:02Z ian $");
+
+#define _ARM32_BUS_DMA_PRIVATE
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/sysproto.h>
+#include <sys/signalvar.h>
+#include <sys/imgact.h>
+#include <sys/kernel.h>
+#include <sys/ktr.h>
+#include <sys/linker.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/mutex.h>
+#include <sys/pcpu.h>
+#include <sys/proc.h>
+#include <sys/ptrace.h>
+#include <sys/cons.h>
+#include <sys/bio.h>
+#include <sys/bus.h>
+#include <sys/buf.h>
+#include <sys/exec.h>
+#include <sys/kdb.h>
+#include <sys/msgbuf.h>
+#include <machine/reg.h>
+#include <machine/cpu.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/vm_object.h>
+#include <vm/vm_page.h>
+#include <vm/vm_map.h>
+#include <machine/devmap.h>
+#include <machine/vmparam.h>
+#include <machine/pcb.h>
+#include <machine/undefined.h>
+#include <machine/machdep.h>
+#include <machine/metadata.h>
+#include <machine/armreg.h>
+#include <machine/bus.h>
+#include <machine/physmem.h>
+#include <sys/reboot.h>
+
+#include <arm/xscale/i80321/i80321reg.h>
+#include <arm/xscale/i80321/i80321var.h>
+#include <arm/xscale/i80321/iq80321reg.h>
+#include <arm/xscale/i80321/obiovar.h>
+
+#define	KERNEL_PT_SYS		0	/* Page table for mapping proc0 zero page */
+#define	KERNEL_PT_IOPXS		1
+#define	KERNEL_PT_BEFOREKERN	2
+#define	KERNEL_PT_AFKERNEL	3	/* L2 table for mapping after kernel */
+#define	KERNEL_PT_AFKERNEL_NUM	9
+
+/* this should be evenly divisable by PAGE_SIZE / L2_TABLE_SIZE_REAL (or 4) */
+#define NUM_KERNEL_PTS		(KERNEL_PT_AFKERNEL + KERNEL_PT_AFKERNEL_NUM)
+
+struct pv_addr kernel_pt_table[NUM_KERNEL_PTS];
+
+/* Physical and virtual addresses for some global pages */
+
+struct pv_addr systempage;
+struct pv_addr msgbufpv;
+struct pv_addr irqstack;
+struct pv_addr undstack;
+struct pv_addr abtstack;
+struct pv_addr kernelstack;
+struct pv_addr minidataclean;
+
+
+/* #define IQ80321_OBIO_BASE 0xfe800000UL */
+/* #define IQ80321_OBIO_SIZE 0x00100000UL */
+
+/* Static device mappings. */
+static const struct arm_devmap_entry ep80219_devmap[] = {
+	/*
+	 * Map the on-board devices VA == PA so that we can access them
+	 * with the MMU on or off.
+	 */
+	{
+		IQ80321_OBIO_BASE,
+		IQ80321_OBIO_BASE,
+		IQ80321_OBIO_SIZE,
+		VM_PROT_READ|VM_PROT_WRITE,
+		PTE_DEVICE,
+	},
+	{
+		IQ80321_IOW_VBASE,
+		VERDE_OUT_XLATE_IO_WIN0_BASE,
+		VERDE_OUT_XLATE_IO_WIN_SIZE,
+		VM_PROT_READ|VM_PROT_WRITE,
+		PTE_DEVICE,
+	},	
+	{
+		IQ80321_80321_VBASE,
+		VERDE_PMMR_BASE,
+		VERDE_PMMR_SIZE,
+		VM_PROT_READ|VM_PROT_WRITE,
+		PTE_DEVICE,
+	},
+	{
+		0,
+		0,
+		0,
+		0,
+		0,
+	}
+};
+
+extern vm_offset_t xscale_cache_clean_addr;
+
+void *
+initarm(struct arm_boot_params *abp)
+{
+	struct pv_addr  kernel_l1pt;
+	struct pv_addr  dpcpu;
+	int loop, i;
+	u_int l1pagetable;
+	vm_offset_t freemempos;
+	vm_offset_t freemem_pt;
+	vm_offset_t afterkern;
+	vm_offset_t freemem_after;
+	vm_offset_t lastaddr;
+	uint32_t memsize, memstart;
+
+	lastaddr = parse_boot_param(abp);
+	arm_physmem_kernaddr = abp->abp_physaddr;
+	set_cpufuncs();
+	pcpu_init(pcpup, 0, sizeof(struct pcpu));
+	PCPU_SET(curthread, &thread0);
+
+	/* Do basic tuning, hz etc */
+	init_param1();
+
+	freemempos = 0xa0200000;
+	/* Define a macro to simplify memory allocation */
+#define	valloc_pages(var, np)			\
+	alloc_pages((var).pv_pa, (np));		\
+	(var).pv_va = (var).pv_pa + 0x20000000;
+
+#define alloc_pages(var, np)			\
+	freemempos -= (np * PAGE_SIZE);		\
+	(var) = freemempos;		\
+	memset((char *)(var), 0, ((np) * PAGE_SIZE));
+
+	while (((freemempos - L1_TABLE_SIZE) & (L1_TABLE_SIZE - 1)) != 0)
+		freemempos -= PAGE_SIZE;
+	valloc_pages(kernel_l1pt, L1_TABLE_SIZE / PAGE_SIZE);
+	for (loop = 0; loop < NUM_KERNEL_PTS; ++loop) {
+		if (!(loop % (PAGE_SIZE / L2_TABLE_SIZE_REAL))) {
+			valloc_pages(kernel_pt_table[loop],
+			    L2_TABLE_SIZE / PAGE_SIZE);
+		} else {
+			kernel_pt_table[loop].pv_pa = freemempos +
+			    (loop % (PAGE_SIZE / L2_TABLE_SIZE_REAL)) *
+			    L2_TABLE_SIZE_REAL;
+			kernel_pt_table[loop].pv_va =
+			    kernel_pt_table[loop].pv_pa + 0x20000000;
+		}
+	}
+	freemem_pt = freemempos;
+	freemempos = 0xa0100000;
+	/*
+	 * Allocate a page for the system page mapped to V0x00000000
+	 * This page will just contain the system vectors and can be
+	 * shared by all processes.
+	 */
+	valloc_pages(systempage, 1);
+
+	/* Allocate dynamic per-cpu area. */
+	valloc_pages(dpcpu, DPCPU_SIZE / PAGE_SIZE);
+	dpcpu_init((void *)dpcpu.pv_va, 0);
+
+	/* Allocate stacks for all modes */
+	valloc_pages(irqstack, IRQ_STACK_SIZE);
+	valloc_pages(abtstack, ABT_STACK_SIZE);
+	valloc_pages(undstack, UND_STACK_SIZE);
+	valloc_pages(kernelstack, KSTACK_PAGES);
+	alloc_pages(minidataclean.pv_pa, 1);
+	valloc_pages(msgbufpv, round_page(msgbufsize) / PAGE_SIZE);
+	/*
+	 * Allocate memory for the l1 and l2 page tables. The scheme to avoid
+	 * wasting memory by allocating the l1pt on the first 16k memory was
+	 * taken from NetBSD rpc_machdep.c. NKPT should be greater than 12 for
+	 * this to work (which is supposed to be the case).
+	 */
+
+	/*
+	 * Now we start construction of the L1 page table
+	 * We start by mapping the L2 page tables into the L1.
+	 * This means that we can replace L1 mappings later on if necessary
+	 */
+	l1pagetable = kernel_l1pt.pv_va;
+
+	/* Map the L2 pages tables in the L1 page table */
+	pmap_link_l2pt(l1pagetable, ARM_VECTORS_HIGH & ~(0x00100000 - 1),
+	    &kernel_pt_table[KERNEL_PT_SYS]);
+	pmap_link_l2pt(l1pagetable, IQ80321_IOPXS_VBASE,
+	    &kernel_pt_table[KERNEL_PT_IOPXS]);
+	pmap_link_l2pt(l1pagetable, KERNBASE,
+	    &kernel_pt_table[KERNEL_PT_BEFOREKERN]);
+	pmap_map_chunk(l1pagetable, KERNBASE, IQ80321_SDRAM_START, 0x100000,
+	    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+	pmap_map_chunk(l1pagetable, KERNBASE + 0x100000, IQ80321_SDRAM_START + 0x100000,
+	    0x100000, VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE);
+	pmap_map_chunk(l1pagetable, KERNBASE + 0x200000, IQ80321_SDRAM_START + 0x200000,
+	    (((uint32_t)(lastaddr) - KERNBASE - 0x200000) + L1_S_SIZE) & ~(L1_S_SIZE - 1),
+	    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+	freemem_after = ((int)lastaddr + PAGE_SIZE) & ~(PAGE_SIZE - 1);
+	afterkern = round_page(((vm_offset_t)lastaddr + L1_S_SIZE) & ~(L1_S_SIZE
+	    - 1));
+	for (i = 0; i < KERNEL_PT_AFKERNEL_NUM; i++) {
+		pmap_link_l2pt(l1pagetable, afterkern + i * 0x00100000,
+		    &kernel_pt_table[KERNEL_PT_AFKERNEL + i]);
+	}
+	pmap_map_entry(l1pagetable, afterkern, minidataclean.pv_pa,
+	    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+	
+
+	/* Map the Mini-Data cache clean area. */
+	xscale_setup_minidata(l1pagetable, afterkern,
+	    minidataclean.pv_pa);
+
+	/* Map the vector page. */
+	pmap_map_entry(l1pagetable, ARM_VECTORS_HIGH, systempage.pv_pa,
+	    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+	arm_devmap_bootstrap(l1pagetable, ep80219_devmap);
+	/*
+	 * Give the XScale global cache clean code an appropriately
+	 * sized chunk of unmapped VA space starting at 0xff000000
+	 * (our device mappings end before this address).
+	 */
+	xscale_cache_clean_addr = 0xff000000U;
+
+	cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT);
+	setttb(kernel_l1pt.pv_pa);
+	cpu_tlb_flushID();
+	cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2));
+	/*
+	 * Pages were allocated during the secondary bootstrap for the
+	 * stacks for different CPU modes.
+	 * We must now set the r13 registers in the different CPU modes to
+	 * point to these stacks.
+	 * Since the ARM stacks use STMFD etc. we must set r13 to the top end
+	 * of the stack memory.
+	 */
+	set_stackptrs(0);
+
+	/*
+	 * We must now clean the cache again....
+	 * Cleaning may be done by reading new data to displace any
+	 * dirty data in the cache. This will have happened in setttb()
+	 * but since we are boot strapping the addresses used for the read
+	 * may have just been remapped and thus the cache could be out
+	 * of sync. A re-clean after the switch will cure this.
+	 * After booting there are no gross relocations of the kernel thus
+	 * this problem will not occur after initarm().
+	 */
+	cpu_idcache_wbinv_all();
+	cpu_setup("");
+
+	/*
+	 * Fetch the SDRAM start/size from the i80321 SDRAM configration
+	 * registers.
+	 */
+	i80321_calibrate_delay();
+	i80321_sdram_bounds(obio_bs_tag, IQ80321_80321_VBASE + VERDE_MCU_BASE,
+	    &memstart, &memsize);
+	physmem = memsize / PAGE_SIZE;
+	cninit();
+
+	undefined_init();
+				
+	init_proc0(kernelstack.pv_va);
+	
+	/* Enable MMU, I-cache, D-cache, write buffer. */
+
+	arm_vector_init(ARM_VECTORS_HIGH, ARM_VEC_ALL);
+	vm_max_kernel_address = 0xd0000000;
+	pmap_bootstrap(pmap_curmaxkvaddr, &kernel_l1pt);
+	msgbufp = (void*)msgbufpv.pv_va;
+	msgbufinit(msgbufp, msgbufsize);
+	mutex_init();
+	
+	/*
+	 * Add the physical ram we have available.
+	 *
+	 * Exclude the kernel (and all the things we allocated which immediately
+	 * follow the kernel) from the VM allocation pool but not from crash
+	 * dumps.  virtual_avail is a global variable which tracks the kva we've
+	 * "allocated" while setting up pmaps.
+	 *
+	 * Prepare the list of physical memory available to the vm subsystem.
+	 */
+	arm_physmem_hardware_region(IQ80321_SDRAM_START, memsize);
+	arm_physmem_exclude_region(abp->abp_physaddr, 
+	    virtual_avail - KERNVIRTADDR, EXFLAG_NOALLOC);
+	arm_physmem_init_kernel_globals();
+
+	init_param2(physmem);
+	kdb_init();
+	return ((void *)(kernelstack.pv_va + USPACE_SVC_STACK_TOP -
+	    sizeof(struct pcb)));
+}
+
+extern int
+machdep_pci_route_interrupt(device_t pcib, device_t dev, int pin)
+{
+	int bus;
+	int device;
+	int func;
+	uint32_t busno;
+	struct i80321_pci_softc *sc = device_get_softc(pcib);
+	bus = pci_get_bus(dev);
+	device = pci_get_slot(dev);
+	func = pci_get_function(dev);
+	busno = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_PCIXSR);
+	busno = PCIXSR_BUSNO(busno);
+	if (busno == 0xff)
+		busno = 0;
+	if (bus != busno)
+		goto no_mapping;
+	switch (device) {
+		/* EP80219 PCI */
+	case 1: /* Ethernet i82555 10/100 */
+		printf("Device %d routed to irq %d\n", device, ICU_INT_XINT(0));
+		return (ICU_INT_XINT(0));
+	case 2: /* UART */
+		printf("Device %d routed to irq %d\n", device, ICU_INT_XINT(1));
+		return (ICU_INT_XINT(1));
+	case 3:
+		/*
+		 * The S-ATA chips are behind the bridge, and all of
+		 * the S-ATA interrupts are wired together.
+		 */
+		printf("Device %d routed to irq %d\n", device, ICU_INT_XINT(2));
+		return (ICU_INT_XINT(2));
+	case 4: /* MINI-PIC_INT */
+		printf("Device %d routed to irq %d\n", device, ICU_INT_XINT(3));
+		return( ICU_INT_XINT(3));
+	default:
+no_mapping:
+		printf("No mapping for %d/%d/%d/%c\n", bus, device, func, pin);
+		
+	}
+	return (0);
+
+}


Property changes on: trunk/sys/arm/xscale/i80321/ep80219_machdep.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/i80321/files.ep80219
===================================================================
--- trunk/sys/arm/xscale/i80321/files.ep80219	                        (rev 0)
+++ trunk/sys/arm/xscale/i80321/files.ep80219	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,11 @@
+#$FreeBSD: stable/10/sys/arm/xscale/i80321/files.ep80219 278727 2015-02-13 22:32:02Z ian $
+#
+#
+# EP80219 Board Specific
+#
+arm/xscale/i80321/iq80321.c		standard
+arm/xscale/i80321/ep80219_machdep.c	standard
+arm/xscale/i80321/obio.c		standard
+arm/xscale/i80321/uart_cpu_i80321.c	optional	uart
+arm/xscale/i80321/uart_bus_i80321.c	optional	uart
+dev/uart/uart_dev_ns8250.c		optional	uart


Property changes on: trunk/sys/arm/xscale/i80321/files.ep80219
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/xscale/i80321/files.i80219
===================================================================
--- trunk/sys/arm/xscale/i80321/files.i80219	                        (rev 0)
+++ trunk/sys/arm/xscale/i80321/files.i80219	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,14 @@
+#$FreeBSD: stable/10/sys/arm/xscale/i80321/files.i80219 278727 2015-02-13 22:32:02Z ian $
+#
+# IOP Specific
+# 
+arm/arm/bus_space_base.c		standard
+arm/arm/bus_space_generic.c		standard
+arm/arm/cpufunc_asm_xscale.S		standard
+arm/xscale/i80321/i80321.c		standard
+arm/xscale/i80321/i80321_dma.c		optional	dma
+arm/xscale/i80321/i80321_mcu.c		standard
+arm/xscale/i80321/i80321_pci.c		optional	pci
+arm/xscale/i80321/i80321_space.c	standard
+arm/xscale/i80321/i80321_timer.c	standard
+arm/xscale/i80321/i80321_wdog.c		optional	iopwdog


Property changes on: trunk/sys/arm/xscale/i80321/files.i80219
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/xscale/i80321/files.i80321
===================================================================
--- trunk/sys/arm/xscale/i80321/files.i80321	                        (rev 0)
+++ trunk/sys/arm/xscale/i80321/files.i80321	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,12 @@
+#$FreeBSD: stable/10/sys/arm/xscale/i80321/files.i80321 278727 2015-02-13 22:32:02Z ian $
+arm/arm/bus_space_base.c		standard
+arm/arm/bus_space_generic.c		standard
+arm/arm/cpufunc_asm_xscale.S		standard
+arm/xscale/i80321/i80321.c		standard
+arm/xscale/i80321/i80321_aau.c		optional	aau
+arm/xscale/i80321/i80321_dma.c		optional	dma
+arm/xscale/i80321/i80321_mcu.c		standard
+arm/xscale/i80321/i80321_pci.c		optional	pci
+arm/xscale/i80321/i80321_space.c	standard
+arm/xscale/i80321/i80321_timer.c	standard
+arm/xscale/i80321/i80321_wdog.c		optional	iopwdog


Property changes on: trunk/sys/arm/xscale/i80321/files.i80321
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/xscale/i80321/files.iq31244
===================================================================
--- trunk/sys/arm/xscale/i80321/files.iq31244	                        (rev 0)
+++ trunk/sys/arm/xscale/i80321/files.iq31244	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,8 @@
+#$FreeBSD: stable/10/sys/arm/xscale/i80321/files.iq31244 278727 2015-02-13 22:32:02Z ian $
+arm/xscale/i80321/iq80321.c		standard
+arm/xscale/i80321/iq31244_machdep.c	standard
+arm/xscale/i80321/iq31244_7seg.c	optional	iq31244_7seg
+arm/xscale/i80321/obio.c		standard
+arm/xscale/i80321/uart_cpu_i80321.c	optional	uart
+arm/xscale/i80321/uart_bus_i80321.c	optional	uart
+dev/uart/uart_dev_ns8250.c		optional	uart


Property changes on: trunk/sys/arm/xscale/i80321/files.iq31244
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/xscale/i80321/i80321.c
===================================================================
--- trunk/sys/arm/xscale/i80321/i80321.c	                        (rev 0)
+++ trunk/sys/arm/xscale/i80321/i80321.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,251 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: i80321.c,v 1.15 2003/10/06 16:06:05 thorpej Exp $	*/
+
+/*-
+ * Copyright (c) 2002 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Jason R. Thorpe for Wasabi Systems, Inc.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed for the NetBSD Project by
+ *	Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
+ * 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.
+ */
+
+/*
+ * Autoconfiguration support for the Intel i80321 I/O Processor.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/xscale/i80321/i80321.c 236987 2012-06-13 04:38:09Z imp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+
+#define	_ARM32_BUS_DMA_PRIVATE
+#include <machine/bus.h>
+#include <machine/intr.h>
+
+#include <arm/xscale/i80321/i80321reg.h>
+#include <arm/xscale/i80321/i80321var.h>
+#include <arm/xscale/i80321/i80321_intr.h>
+
+#include <dev/pci/pcireg.h>
+
+volatile uint32_t intr_enabled;
+uint32_t intr_steer = 0;
+/*
+ * Statically-allocated bus_space stucture used to access the
+ * i80321's own registers.
+ */
+struct bus_space i80321_bs_tag;
+
+/*
+ * There can be only one i80321, so we keep a global pointer to
+ * the softc, so board-specific code can use features of the
+ * i80321 without having to have a handle on the softc itself.
+ */
+struct i80321_softc *i80321_softc;
+
+#define PCI_MAPREG_MEM_ADDR(x) ((x) & 0xfffffff0)
+/*
+ * i80321_attach:
+ *
+ *	Board-independent attach routine for the i80321.
+ */
+void
+i80321_attach(struct i80321_softc *sc)
+{
+
+	i80321_softc = sc;
+	uint32_t preg;
+
+	/* We expect the Memory Controller to be already sliced off. */
+
+	/*
+	 * Program the Inbound windows.
+	 */
+	bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IALR0,
+	    (0xffffffff - (sc->sc_iwin[0].iwin_size - 1)) & 0xffffffc0);
+	bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IATVR0,
+	    sc->sc_iwin[0].iwin_xlate);
+	if (sc->sc_is_host) {
+		bus_space_write_4(sc->sc_st, sc->sc_atu_sh,
+		    PCIR_BARS, sc->sc_iwin[0].iwin_base_lo);
+		bus_space_write_4(sc->sc_st, sc->sc_atu_sh,
+		    PCIR_BARS + 0x04, sc->sc_iwin[0].iwin_base_hi);
+	} else {
+		sc->sc_iwin[0].iwin_base_lo = bus_space_read_4(sc->sc_st,
+		    sc->sc_atu_sh, PCIR_BARS);
+		sc->sc_iwin[0].iwin_base_hi = bus_space_read_4(sc->sc_st,
+		    sc->sc_atu_sh, PCIR_BARS + 0x04);
+		sc->sc_iwin[0].iwin_base_lo =
+		    PCI_MAPREG_MEM_ADDR(sc->sc_iwin[0].iwin_base_lo);
+	}
+
+	bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IALR1,
+	    (0xffffffff - (sc->sc_iwin[1].iwin_size - 1)) & 0xffffffc0);
+
+	/* no xlate for window 1 */
+	if (sc->sc_is_host) {
+		bus_space_write_4(sc->sc_st, sc->sc_atu_sh,
+		    PCIR_BARS + 0x08, sc->sc_iwin[1].iwin_base_lo);
+		bus_space_write_4(sc->sc_st, sc->sc_atu_sh,
+		    PCIR_BARS + 0x0c, sc->sc_iwin[1].iwin_base_hi);
+	} else {
+		sc->sc_iwin[1].iwin_base_lo = bus_space_read_4(sc->sc_st,
+		    sc->sc_atu_sh, PCIR_BARS + 0x08);
+		sc->sc_iwin[1].iwin_base_hi = bus_space_read_4(sc->sc_st,
+		    sc->sc_atu_sh, PCIR_BARS + 0x0c);
+		sc->sc_iwin[1].iwin_base_lo =
+		    PCI_MAPREG_MEM_ADDR(sc->sc_iwin[1].iwin_base_lo);
+	}
+
+	bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IALR2,
+	    (0xffffffff - (sc->sc_iwin[2].iwin_size - 1)) & 0xffffffc0);
+	bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IATVR2,
+	    sc->sc_iwin[2].iwin_xlate);
+
+	if (sc->sc_is_host) {
+		bus_space_write_4(sc->sc_st, sc->sc_atu_sh,
+		    PCIR_BARS + 0x10, sc->sc_iwin[2].iwin_base_lo);
+		bus_space_write_4(sc->sc_st, sc->sc_atu_sh,
+		    PCIR_BARS + 0x14, sc->sc_iwin[2].iwin_base_hi);
+	} else {
+		sc->sc_iwin[2].iwin_base_lo = bus_space_read_4(sc->sc_st,
+		    sc->sc_atu_sh, PCIR_BARS + 0x10);
+		sc->sc_iwin[2].iwin_base_hi = bus_space_read_4(sc->sc_st,
+		    sc->sc_atu_sh, PCIR_BARS + 0x14);
+		sc->sc_iwin[2].iwin_base_lo =
+		    PCI_MAPREG_MEM_ADDR(sc->sc_iwin[2].iwin_base_lo);
+	}
+	bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IALR3,
+	    (0xffffffff - (sc->sc_iwin[3].iwin_size - 1)) & 0xffffffc0);
+	bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IATVR3,
+	    sc->sc_iwin[3].iwin_xlate);
+
+	if (sc->sc_is_host) {
+		bus_space_write_4(sc->sc_st, sc->sc_atu_sh,
+		    ATU_IABAR3, sc->sc_iwin[3].iwin_base_lo);
+		bus_space_write_4(sc->sc_st, sc->sc_atu_sh,
+		    ATU_IAUBAR3, sc->sc_iwin[3].iwin_base_hi);
+	} else {
+		sc->sc_iwin[3].iwin_base_lo = bus_space_read_4(sc->sc_st,
+		    sc->sc_atu_sh, ATU_IABAR3);
+		sc->sc_iwin[3].iwin_base_hi = bus_space_read_4(sc->sc_st,
+		    sc->sc_atu_sh, ATU_IAUBAR3);
+		sc->sc_iwin[3].iwin_base_lo =
+		    PCI_MAPREG_MEM_ADDR(sc->sc_iwin[3].iwin_base_lo);
+	}
+	/*
+	 * Mask (disable) the ATU interrupt sources.
+	 * XXX May want to revisit this if we encounter
+	 * XXX an application that wants it.
+	 */
+	bus_space_write_4(sc->sc_st, sc->sc_atu_sh,
+	    ATU_ATUIMR,
+	    ATUIMR_IMW1BU|ATUIMR_ISCEM|ATUIMR_RSCEM|ATUIMR_PST|
+	    ATUIMR_DPE|ATUIMR_P_SERR_ASRT|ATUIMR_PMA|ATUIMR_PTAM|
+	    ATUIMR_PTAT|ATUIMR_PMPE);
+
+	/*
+	 * Program the outbound windows.
+	 */
+	bus_space_write_4(sc->sc_st, sc->sc_atu_sh,
+	    ATU_OIOWTVR, sc->sc_ioout_xlate);
+
+	if (!sc->sc_is_host) {
+		sc->sc_owin[0].owin_xlate_lo = sc->sc_iwin[1].iwin_base_lo;
+		sc->sc_owin[0].owin_xlate_hi = sc->sc_iwin[1].iwin_base_hi;
+	}
+	bus_space_write_4(sc->sc_st, sc->sc_atu_sh,
+	    ATU_OMWTVR0, sc->sc_owin[0].owin_xlate_lo);
+	bus_space_write_4(sc->sc_st, sc->sc_atu_sh,
+	    ATU_OUMWTVR0, sc->sc_owin[0].owin_xlate_hi);
+
+	bus_space_write_4(sc->sc_st, sc->sc_atu_sh,
+	    ATU_OMWTVR1, sc->sc_owin[1].owin_xlate_lo);
+	bus_space_write_4(sc->sc_st, sc->sc_atu_sh,
+	    ATU_OUMWTVR1, sc->sc_owin[1].owin_xlate_hi);
+
+	/*
+	 * Set up the ATU configuration register.  All we do
+	 * right now is enable Outbound Windows.
+	 */
+	bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_ATUCR,
+	    ATUCR_OUT_EN);
+
+	/*
+	 * Enable bus mastering, memory access, SERR, and parity
+	 * checking on the ATU.
+	 */
+	if (sc->sc_is_host) {
+		preg = bus_space_read_4(sc->sc_st, sc->sc_atu_sh,
+		    PCIR_COMMAND);
+		preg |= PCIM_CMD_MEMEN |
+		    PCIM_CMD_BUSMASTEREN | PCIM_CMD_PERRESPEN |
+		    PCIM_CMD_SERRESPEN;
+		bus_space_write_4(sc->sc_st, sc->sc_atu_sh,
+		    PCIR_COMMAND, preg);
+	}
+	/* Initialize the bus space tags. */
+	i80321_io_bs_init(&sc->sc_pci_iot, sc);
+	i80321_mem_bs_init(&sc->sc_pci_memt, sc);
+	intr_enabled = 0;
+	i80321_set_intrmask();
+	i80321_set_intrsteer();
+}
+
+
+static __inline uint32_t
+i80321_iintsrc_read(void)
+{
+	uint32_t iintsrc;
+		
+	__asm __volatile("mrc p6, 0, %0, c8, c0, 0"
+	    : "=r" (iintsrc));
+	
+	/*
+	 * The IINTSRC register shows bits that are active even
+	 * if they are masked in INTCTL, so we have to mask them
+	 * off with the interrupts we consider enabled.
+	 */
+	return (iintsrc & intr_enabled);
+}
+
+int
+arm_get_next_irq(int last __unused)
+{
+	int irq;
+
+	if ((irq = i80321_iintsrc_read()))
+		return (ffs(irq) - 1);
+	return (-1);
+}


Property changes on: trunk/sys/arm/xscale/i80321/i80321.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/i80321/i80321_aau.c
===================================================================
--- trunk/sys/arm/xscale/i80321/i80321_aau.c	                        (rev 0)
+++ trunk/sys/arm/xscale/i80321/i80321_aau.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,293 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2005 Olivier Houchard.  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 ``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 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: stable/10/sys/arm/xscale/i80321/i80321_aau.c 236987 2012-06-13 04:38:09Z imp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/proc.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/vm_map.h>
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/md_var.h>
+
+#include <arm/xscale/i80321/i80321reg.h>
+#include <arm/xscale/i80321/i80321var.h>
+#include <arm/xscale/i80321/iq80321reg.h>
+#include <arm/xscale/i80321/iq80321var.h>
+#include <arm/xscale/i80321/i80321_intr.h>
+
+typedef struct i80321_aaudesc_s {
+	vm_paddr_t next_desc;
+	uint32_t sar[4];
+	vm_paddr_t local_addr;
+	vm_size_t count;
+	uint32_t descr_ctrl;
+} __packed	i80321_aaudesc_t;
+
+typedef struct i80321_aauring_s {
+	i80321_aaudesc_t *desc;
+	vm_paddr_t phys_addr;
+	bus_dmamap_t map;
+} i80321_aauring_t;
+
+#define AAU_RING_SIZE 64
+
+struct i80321_aau_softc {
+	bus_space_tag_t sc_st;
+	bus_space_handle_t sc_aau_sh;
+	bus_dma_tag_t dmatag;
+	i80321_aauring_t aauring[AAU_RING_SIZE];
+	int flags;
+#define BUSY	0x1
+	int unit;
+	struct mtx mtx;
+};
+
+static int
+i80321_aau_probe(device_t dev)
+{
+	device_set_desc(dev, "I80321 AAU");
+	return (0);
+}
+
+static struct i80321_aau_softc *aau_softc;
+
+static void
+i80321_mapphys(void *arg, bus_dma_segment_t *segs, int nseg, int error)
+{
+	vm_paddr_t *addr = (vm_paddr_t *)arg;
+
+	*addr = segs->ds_addr;
+}
+
+#define AAU_REG_WRITE(softc, reg, val) \
+    bus_space_write_4((softc)->sc_st, (softc)->sc_aau_sh, \
+	(reg), (val))
+#define AAU_REG_READ(softc, reg) \
+    bus_space_read_4((softc)->sc_st, (softc)->sc_aau_sh, \
+	(reg))
+
+static int aau_bzero(void *, int, int);
+
+static int
+i80321_aau_attach(device_t dev)
+{
+	struct i80321_aau_softc *softc = device_get_softc(dev);
+	struct i80321_softc *sc = device_get_softc(device_get_parent(dev));
+	struct i80321_aaudesc_s *aaudescs;
+
+	mtx_init(&softc->mtx, "AAU mtx", NULL, MTX_SPIN);
+	softc->sc_st = sc->sc_st;
+	if (bus_space_subregion(softc->sc_st, sc->sc_sh, VERDE_AAU_BASE,
+	    VERDE_AAU_SIZE, &softc->sc_aau_sh) != 0)
+		panic("%s: unable to subregion AAU registers",
+		    device_get_name(dev));
+	if (bus_dma_tag_create(NULL, sizeof(i80321_aaudesc_t), 0,
+	    BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL,
+	    AAU_RING_SIZE * sizeof(i80321_aaudesc_t),
+	    1, sizeof(i80321_aaudesc_t), BUS_DMA_ALLOCNOW, busdma_lock_mutex,
+	    &Giant, &softc->dmatag))
+		panic("Couldn't create a dma tag");
+	if (bus_dmamem_alloc(softc->dmatag, (void **)&aaudescs,
+    	    BUS_DMA_NOWAIT | BUS_DMA_COHERENT, &softc->aauring[0].map))
+		panic("Couldn't alloc dma memory");
+
+	for (int i = 0; i < AAU_RING_SIZE; i++) {
+		if (i > 0)
+			if (bus_dmamap_create(softc->dmatag, 0,
+			    &softc->aauring[i].map))
+				panic("Couldn't create dma map");
+		softc->aauring[i].desc = &aaudescs[i];
+		bus_dmamap_load(softc->dmatag, softc->aauring[i].map,
+		    softc->aauring[i].desc, sizeof(i80321_aaudesc_t),
+		    i80321_mapphys, &softc->aauring[i].phys_addr, 0);
+		bzero(softc->aauring[i].desc, sizeof(i80321_aaudesc_t));
+	}
+	aau_softc = softc;
+	_arm_bzero = aau_bzero;
+	_min_bzero_size = 1024;
+	return (0);
+}
+
+static __inline void
+test_virt_addr(void *addr, int len)
+{
+	int to_nextpage;
+
+	while (len > 0) {
+		*(char *)addr = 0;
+		to_nextpage = ((vm_offset_t)addr & ~PAGE_MASK) +
+		    PAGE_SIZE - (vm_offset_t)addr;
+		if (to_nextpage >= len)
+			break;
+		len -= to_nextpage;
+		addr = (void *)((vm_offset_t)addr + to_nextpage);
+	}
+}
+
+static int
+aau_bzero(void *dst, int len, int flags)
+{
+	struct i80321_aau_softc *sc = aau_softc;
+	i80321_aaudesc_t *desc;
+	int ret;
+	int csr;
+	int descnb = 0;
+	int tmplen = len;
+	int to_nextpagedst;
+	int min_hop;
+	vm_paddr_t pa, tmppa;
+
+	if (!sc)
+		return (-1);
+	mtx_lock_spin(&sc->mtx);
+	if (sc->flags & BUSY) {
+		mtx_unlock_spin(&sc->mtx);
+		return (-1);
+	}
+	sc->flags |= BUSY;
+	mtx_unlock_spin(&sc->mtx);
+	desc = sc->aauring[0].desc;
+	if (flags & IS_PHYSICAL) {
+		desc->local_addr = (vm_paddr_t)dst;
+		desc->next_desc = 0;
+		desc->count = len;
+		desc->descr_ctrl = 2 << 1 | 1 << 31; /* Fill, enable dest write */
+		bus_dmamap_sync(sc->dmatag, sc->aauring[0].map,
+		    BUS_DMASYNC_PREWRITE);
+	} else {
+		test_virt_addr(dst, len);
+		if ((vm_offset_t)dst & (31))
+			cpu_dcache_wb_range((vm_offset_t)dst & ~31, 32);
+		if (((vm_offset_t)dst + len) & 31)
+			cpu_dcache_wb_range(((vm_offset_t)dst + len) & ~31,
+			    32);
+		cpu_dcache_inv_range((vm_offset_t)dst, len);
+		while (tmplen > 0) {
+			pa = vtophys(dst);
+			to_nextpagedst = ((vm_offset_t)dst & ~PAGE_MASK) +
+			    PAGE_SIZE - (vm_offset_t)dst;
+			while (to_nextpagedst < tmplen) {
+				tmppa = vtophys((vm_offset_t)dst +
+				    to_nextpagedst);
+				if (tmppa != pa + to_nextpagedst)
+					break;
+				to_nextpagedst += PAGE_SIZE;
+			}
+			min_hop = to_nextpagedst;
+			if (min_hop < 64) {
+				tmplen -= min_hop;
+				bzero(dst, min_hop);
+				cpu_dcache_wbinv_range((vm_offset_t)dst,
+				    min_hop);
+
+				dst = (void *)((vm_offset_t)dst + min_hop);
+				if (tmplen <= 0 && descnb > 0) {
+					sc->aauring[descnb - 1].desc->next_desc
+					    = 0;
+					bus_dmamap_sync(sc->dmatag,
+					    sc->aauring[descnb - 1].map,
+					    BUS_DMASYNC_PREWRITE);
+				}
+				continue;
+			}
+			desc->local_addr = pa;
+			desc->count = tmplen > min_hop ? min_hop : tmplen;
+			desc->descr_ctrl = 2 << 1 | 1 << 31; /* Fill, enable dest write */;
+			if (min_hop < tmplen) {
+				tmplen -= min_hop;
+				dst = (void *)((vm_offset_t)dst + min_hop);
+			} else
+				tmplen = 0;
+			if (descnb + 1 >= AAU_RING_SIZE) {
+				mtx_lock_spin(&sc->mtx);
+				sc->flags &= ~BUSY;
+				mtx_unlock_spin(&sc->mtx);
+				return (-1);
+			}
+			if (tmplen > 0) {
+				desc->next_desc = sc->aauring[descnb + 1].
+				    phys_addr;
+				bus_dmamap_sync(sc->dmatag,
+				    sc->aauring[descnb].map,
+				    BUS_DMASYNC_PREWRITE);
+				desc = sc->aauring[descnb + 1].desc;
+				descnb++;
+			} else {
+				desc->next_desc = 0;
+				bus_dmamap_sync(sc->dmatag,
+				    sc->aauring[descnb].map,
+				    BUS_DMASYNC_PREWRITE);
+			}
+									
+		}
+
+	}
+	AAU_REG_WRITE(sc, 0x0c /* Descriptor addr */,
+	    sc->aauring[0].phys_addr);
+	AAU_REG_WRITE(sc, 0 /* Control register */, 1 << 0/* Start transfer */);
+	while ((csr = AAU_REG_READ(sc, 0x4)) & (1 << 10));
+	/* Wait until it's done. */
+	if (csr & (1 << 5)) /* error */
+		ret = -1;
+	else
+		ret = 0;
+	/* Clear the interrupt. */
+	AAU_REG_WRITE(sc, 0x4, csr);
+	/* Stop the AAU. */
+	AAU_REG_WRITE(sc, 0, 0);
+	mtx_lock_spin(&sc->mtx);
+	sc->flags &= ~BUSY;
+	mtx_unlock_spin(&sc->mtx);
+	return (ret);
+}
+
+static device_method_t i80321_aau_methods[] = {
+	DEVMETHOD(device_probe, i80321_aau_probe),
+	DEVMETHOD(device_attach, i80321_aau_attach),
+	{0, 0},
+};
+
+static driver_t i80321_aau_driver = {
+	"i80321_aau",
+	i80321_aau_methods,
+	sizeof(struct i80321_aau_softc),
+};
+
+static devclass_t i80321_aau_devclass;
+
+DRIVER_MODULE(i80321_aau, iq, i80321_aau_driver, i80321_aau_devclass, 0, 0);


Property changes on: trunk/sys/arm/xscale/i80321/i80321_aau.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/i80321/i80321_dma.c
===================================================================
--- trunk/sys/arm/xscale/i80321/i80321_dma.c	                        (rev 0)
+++ trunk/sys/arm/xscale/i80321/i80321_dma.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,352 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2005 Olivier Houchard.  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 ``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 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: stable/10/sys/arm/xscale/i80321/i80321_dma.c 236987 2012-06-13 04:38:09Z imp $");
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/proc.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/vm_map.h>
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/md_var.h>
+
+#include <arm/xscale/i80321/i80321reg.h>
+#include <arm/xscale/i80321/i80321var.h>
+#include <arm/xscale/i80321/iq80321reg.h>
+#include <arm/xscale/i80321/iq80321var.h>
+#include <arm/xscale/i80321/i80321_intr.h>
+
+typedef struct i80321_dmadesc_s {
+	vm_paddr_t next_desc;
+	vm_paddr_t low_pciaddr;
+	vm_paddr_t high_pciaddr;
+	vm_paddr_t local_addr;
+	vm_size_t count;
+	uint32_t descr_ctrl;
+	uint64_t unused;
+} __packed	i80321_dmadesc_t;
+
+typedef struct i80321_dmaring_s {
+	i80321_dmadesc_t *desc;
+	vm_paddr_t phys_addr;
+	bus_dmamap_t map;
+} i80321_dmaring_t;
+
+#define DMA_RING_SIZE 64
+
+struct i80321_dma_softc {
+	bus_space_tag_t sc_st;
+	bus_space_handle_t sc_dma_sh;
+	bus_dma_tag_t dmatag;
+	i80321_dmaring_t dmaring[DMA_RING_SIZE];
+	int flags;
+#define BUSY	0x1
+	int unit;
+	struct mtx mtx;
+};
+
+static int
+i80321_dma_probe(device_t dev)
+{
+	device_set_desc(dev, "I80321 DMA Unit");
+	return (0);
+}
+
+static struct i80321_dma_softc *softcs[2]; /* XXX */
+
+static void
+i80321_mapphys(void *arg, bus_dma_segment_t *segs, int nseg, int error)
+{
+	vm_paddr_t *addr = (vm_paddr_t *)arg;
+
+	*addr = segs->ds_addr;
+}
+
+#define DMA_REG_WRITE(softc, reg, val) \
+    bus_space_write_4((softc)->sc_st, (softc)->sc_dma_sh, \
+	(reg), (val))
+#define DMA_REG_READ(softc, reg) \
+    bus_space_read_4((softc)->sc_st, (softc)->sc_dma_sh, \
+	(reg))
+
+#define DMA_CLEAN_MASK (0x2|0x4|0x8|0x20|0x100|0x200)
+static int dma_memcpy(void *, void *, int, int);
+
+static int
+i80321_dma_attach(device_t dev)
+{
+	struct i80321_dma_softc *softc = device_get_softc(dev);
+	struct i80321_softc *sc = device_get_softc(device_get_parent(dev));
+	int unit = device_get_unit(dev);
+	i80321_dmadesc_t *dmadescs;
+
+	mtx_init(&softc->mtx, "DMA engine mtx", NULL, MTX_SPIN);
+	softc->sc_st = sc->sc_st;
+	if (bus_space_subregion(softc->sc_st, sc->sc_sh, unit == 0 ?
+	    VERDE_DMA_BASE0 : VERDE_DMA_BASE1, VERDE_DMA_SIZE,
+	    &softc->sc_dma_sh) != 0)
+		panic("%s: unable to subregion DMA registers",
+		    device_get_name(dev));
+	if (bus_dma_tag_create(NULL, sizeof(i80321_dmadesc_t),
+	    0, BUS_SPACE_MAXADDR,  BUS_SPACE_MAXADDR, NULL, NULL,
+	    DMA_RING_SIZE * sizeof(i80321_dmadesc_t), 1,
+	    sizeof(i80321_dmadesc_t), BUS_DMA_ALLOCNOW, busdma_lock_mutex,
+	    &Giant, &softc->dmatag))
+		panic("Couldn't create a dma tag");
+	DMA_REG_WRITE(softc, 0, 0);
+	if (bus_dmamem_alloc(softc->dmatag, (void **)&dmadescs,
+    	    BUS_DMA_NOWAIT | BUS_DMA_COHERENT, &softc->dmaring[0].map))
+		panic("Couldn't alloc dma memory");
+	for (int i = 0; i < DMA_RING_SIZE; i++) {
+		if (i > 0)
+			if (bus_dmamap_create(softc->dmatag, 0,
+			    &softc->dmaring[i].map))
+				panic("Couldn't alloc dmamap");
+		softc->dmaring[i].desc = &dmadescs[i];	
+		bus_dmamap_load(softc->dmatag, softc->dmaring[i].map,
+		    softc->dmaring[i].desc, sizeof(i80321_dmadesc_t),
+		    i80321_mapphys, &softc->dmaring[i].phys_addr, 0);
+	}
+	softc->unit = unit;
+	softcs[unit] = softc;
+	_arm_memcpy = dma_memcpy;
+	_min_memcpy_size = 1024;
+	return (0);
+}
+
+static __inline int
+virt_addr_is_valid(void *addr, int len, int write, int is_kernel)
+{
+	int to_nextpage;
+	char tmp = 0;
+
+	while (len > 0) {
+		if (write) {
+			if (is_kernel)
+				*(char *)addr = 0;
+			else if (subyte(addr, 0) != 0) {
+				return (0);
+			}
+		} else {
+			if (is_kernel)
+				badaddr_read(addr, 1, &tmp);
+			else if (fubyte(addr) == -1) {
+				return (0);
+			}
+		}
+		to_nextpage = ((vm_offset_t)addr & ~PAGE_MASK) +
+		    PAGE_SIZE - (vm_offset_t)addr;
+		if (to_nextpage >= len)
+			break;
+		len -= to_nextpage;
+		addr = (void *)((vm_offset_t)addr + to_nextpage);
+	}
+	return (1);
+}
+
+static int
+dma_memcpy(void *dst, void *src, int len, int flags)
+{
+	struct i80321_dma_softc *sc;
+	i80321_dmadesc_t *desc;
+	int ret;
+	int csr;
+	int descnb = 0;
+	int tmplen = len;
+	int to_nextpagesrc, to_nextpagedst;
+	int min_hop;
+	vm_paddr_t pa, pa2, tmppa;
+	pmap_t pmap = vmspace_pmap(curthread->td_proc->p_vmspace);
+
+	if (!softcs[0] || !softcs[1])
+		return (-1);
+	mtx_lock_spin(&softcs[0]->mtx);
+	if (softcs[0]->flags & BUSY) {
+		mtx_unlock_spin(&softcs[0]->mtx);
+		mtx_lock_spin(&softcs[1]->mtx);
+		if (softcs[1]->flags & BUSY) {
+			mtx_unlock(&softcs[1]->mtx);
+			return (-1);
+		}
+		sc = softcs[1];
+	} else
+		sc = softcs[0];
+	sc->flags |= BUSY;
+	mtx_unlock_spin(&sc->mtx);
+	desc = sc->dmaring[0].desc;
+	if (flags & IS_PHYSICAL) {
+		desc->next_desc = 0;
+		desc->low_pciaddr = (vm_paddr_t)src;
+		desc->high_pciaddr = 0;
+		desc->local_addr = (vm_paddr_t)dst;
+		desc->count = len;
+		desc->descr_ctrl = 1 << 6; /* Local memory to local memory. */
+		bus_dmamap_sync(sc->dmatag,
+		    sc->dmaring[0].map,
+		    BUS_DMASYNC_PREWRITE);
+	} else {
+		if (!virt_addr_is_valid(dst, len, 1, !(flags & DST_IS_USER)) ||
+		    !virt_addr_is_valid(src, len, 0, !(flags & SRC_IS_USER))) {
+			mtx_lock_spin(&sc->mtx);
+			sc->flags &= ~BUSY;
+			mtx_unlock_spin(&sc->mtx);
+			return (-1);
+		}
+		cpu_dcache_wb_range((vm_offset_t)src, len);
+		if ((vm_offset_t)dst & (31))
+			cpu_dcache_wb_range((vm_offset_t)dst & ~31, 32);
+		if (((vm_offset_t)dst + len) & 31)
+			cpu_dcache_wb_range(((vm_offset_t)dst + len) & ~31,
+			    32);
+		cpu_dcache_inv_range((vm_offset_t)dst, len);
+		while (tmplen > 0) {
+			pa = (flags & SRC_IS_USER) ?
+			    pmap_extract(pmap, (vm_offset_t)src) :
+				    vtophys(src);
+			pa2 = (flags & DST_IS_USER) ?
+			    pmap_extract(pmap, (vm_offset_t)dst) :
+				    vtophys(dst);
+			to_nextpagesrc = ((vm_offset_t)src & ~PAGE_MASK) +
+			    PAGE_SIZE - (vm_offset_t)src;
+			to_nextpagedst = ((vm_offset_t)dst & ~PAGE_MASK) +
+			    PAGE_SIZE - (vm_offset_t)dst;
+			while (to_nextpagesrc < tmplen) {
+				tmppa = (flags & SRC_IS_USER) ?
+				    pmap_extract(pmap, (vm_offset_t)src +
+				    to_nextpagesrc) :
+					    vtophys((vm_offset_t)src +
+						to_nextpagesrc);
+				if (tmppa != pa + to_nextpagesrc)
+					break;
+				to_nextpagesrc += PAGE_SIZE;
+			}
+			while (to_nextpagedst < tmplen) {
+				tmppa = (flags & DST_IS_USER) ?
+				    pmap_extract(pmap, (vm_offset_t)dst +
+				    to_nextpagedst) :
+					    vtophys((vm_offset_t)dst +
+						to_nextpagedst);
+				if (tmppa != pa2 + to_nextpagedst)
+					break;
+				to_nextpagedst += PAGE_SIZE;
+			}
+			min_hop = to_nextpagedst > to_nextpagesrc ?
+			    to_nextpagesrc : to_nextpagedst;
+			if (min_hop < 64) {
+				tmplen -= min_hop;
+				memcpy(dst, src, min_hop);
+				cpu_dcache_wbinv_range((vm_offset_t)dst,
+				    min_hop);
+
+				src = (void *)((vm_offset_t)src + min_hop);
+				dst = (void *)((vm_offset_t)dst + min_hop);
+				if (tmplen <= 0 && descnb > 0) {
+					sc->dmaring[descnb - 1].desc->next_desc
+					    = 0;
+					bus_dmamap_sync(sc->dmatag,
+					    sc->dmaring[descnb - 1].map,
+					    BUS_DMASYNC_PREWRITE);
+				}
+				continue;
+			}
+			desc->low_pciaddr = pa;
+			desc->high_pciaddr = 0;
+			desc->local_addr = pa2;
+			desc->count = tmplen > min_hop ? min_hop : tmplen;
+			desc->descr_ctrl = 1 << 6;
+			if (min_hop < tmplen) {
+				tmplen -= min_hop;
+				src = (void *)((vm_offset_t)src + min_hop);
+				dst = (void *)((vm_offset_t)dst + min_hop);
+			} else
+				tmplen = 0;
+			if (descnb + 1 >= DMA_RING_SIZE) {
+				mtx_lock_spin(&sc->mtx);
+				sc->flags &= ~BUSY;
+				mtx_unlock_spin(&sc->mtx);
+				return (-1);
+			}
+			if (tmplen > 0) {
+				desc->next_desc = sc->dmaring[descnb + 1].
+				    phys_addr;
+				bus_dmamap_sync(sc->dmatag,
+				    sc->dmaring[descnb].map,
+				    BUS_DMASYNC_PREWRITE);
+				desc = sc->dmaring[descnb + 1].desc;
+				descnb++;
+			} else {
+				desc->next_desc = 0;
+				bus_dmamap_sync(sc->dmatag,
+				    sc->dmaring[descnb].map,
+				    BUS_DMASYNC_PREWRITE);
+			}
+									
+		}
+
+	}
+	DMA_REG_WRITE(sc, 4 /* Status register */,
+	    DMA_REG_READ(sc, 4) | DMA_CLEAN_MASK);
+	DMA_REG_WRITE(sc, 0x10 /* Descriptor addr */,
+	    sc->dmaring[0].phys_addr);
+	DMA_REG_WRITE(sc, 0 /* Control register */, 1 | 2/* Start transfer */);
+	while ((csr = DMA_REG_READ(sc, 0x4)) & (1 << 10));
+	/* Wait until it's done. */
+	if (csr & 0x2e) /* error */
+		ret = -1;
+	else
+		ret = 0;
+	DMA_REG_WRITE(sc, 0, 0);
+	mtx_lock_spin(&sc->mtx);
+	sc->flags &= ~BUSY;
+	mtx_unlock_spin(&sc->mtx);
+	return (ret);
+}
+
+static device_method_t i80321_dma_methods[] = {
+	DEVMETHOD(device_probe, i80321_dma_probe),
+	DEVMETHOD(device_attach, i80321_dma_attach),
+	{0, 0},
+};
+
+static driver_t i80321_dma_driver = {
+	"i80321_dma",
+	i80321_dma_methods,
+	sizeof(struct i80321_dma_softc),
+};
+
+static devclass_t i80321_dma_devclass;
+
+DRIVER_MODULE(i80321_dma, iq, i80321_dma_driver, i80321_dma_devclass, 0, 0);


Property changes on: trunk/sys/arm/xscale/i80321/i80321_dma.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/i80321/i80321_intr.h
===================================================================
--- trunk/sys/arm/xscale/i80321/i80321_intr.h	                        (rev 0)
+++ trunk/sys/arm/xscale/i80321/i80321_intr.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,166 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: i80321_intr.h,v 1.5 2004/01/12 10:25:06 scw Exp $	*/
+
+/*-
+ * Copyright (c) 2001, 2002 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Jason R. Thorpe for Wasabi Systems, Inc.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed for the NetBSD Project by
+ *	Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
+ * 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: stable/10/sys/arm/xscale/i80321/i80321_intr.h 278613 2015-02-12 03:50:33Z ian $
+ *
+ */
+
+#ifndef _I80321_INTR_H_
+#define _I80321_INTR_H_
+
+#define	ARM_IRQ_HANDLER	_C_LABEL(i80321_intr_dispatch)
+
+#ifndef _LOCORE
+
+#include <machine/armreg.h>
+#include <machine/cpufunc.h>
+
+#include <arm/xscale/i80321/i80321reg.h>
+
+void i80321_do_pending(void);
+
+extern __volatile uint32_t intr_enabled;
+extern uint32_t intr_steer;
+
+static __inline void __attribute__((__unused__))
+i80321_set_intrmask(void)
+{
+
+	__asm __volatile("mcr p6, 0, %0, c0, c0, 0"
+		:
+		: "r" (intr_enabled & ICU_INT_HWMASK));
+}
+
+static __inline void
+i80321_set_intrsteer(void)
+{
+
+	__asm __volatile("mcr p6, 0, %0, c4, c0, 0"
+	    :
+	    : "r" (intr_steer & ICU_INT_HWMASK));
+}
+
+#if defined ( CPU_XSCALE_80219 )
+#define INT_SWMASK														\
+	((1U << ICU_INT_bit26) |											\
+	 (1U << ICU_INT_bit25) |											\
+	 (1U << ICU_INT_bit23) |											\
+	 (1U << ICU_INT_bit22) |											\
+	 (1U << ICU_INT_bit7)  |											\
+	 (1U << ICU_INT_bit6)  |											\
+	 (1U << ICU_INT_bit5)  |											\
+	 (1U << ICU_INT_bit4))
+#else
+#define INT_SWMASK                                                      \
+        ((1U << ICU_INT_bit26) | (1U << ICU_INT_bit22) |                \
+         (1U << ICU_INT_bit5)  | (1U << ICU_INT_bit4))
+#endif
+
+#if 0
+static __inline void __attribute__((__unused__))
+i80321_splx(int new)
+{
+	extern __volatile uint32_t intr_enabled;
+	extern __volatile int current_spl_level;
+	extern __volatile int i80321_ipending;
+	extern void i80321_do_pending(void);
+	int oldirqstate, hwpend;
+
+	/* Don't let the compiler re-order this code with preceding code */
+	__insn_barrier();
+
+	current_spl_level = new;
+
+	hwpend = (i80321_ipending & ICU_INT_HWMASK) & ~new;
+	if (hwpend != 0) {
+		oldirqstate = disable_interrupts(PSR_I);
+		intr_enabled |= hwpend;
+		i80321_set_intrmask();
+		restore_interrupts(oldirqstate);
+	}
+
+	if ((i80321_ipending & INT_SWMASK) & ~new)
+		i80321_do_pending();
+}
+
+static __inline int __attribute__((__unused__))
+i80321_splraise(int ipl)
+{
+	extern __volatile int current_spl_level;
+	extern int i80321_imask[];
+	int	old;
+
+	old = current_spl_level;
+	current_spl_level |= i80321_imask[ipl];
+
+	/* Don't let the compiler re-order this code with subsequent code */
+	__insn_barrier();
+
+	return (old);
+}
+
+static __inline int __attribute__((__unused__))
+i80321_spllower(int ipl)
+{
+	extern __volatile int current_spl_level;
+	extern int i80321_imask[];
+	int old = current_spl_level;
+
+	i80321_splx(i80321_imask[ipl]);
+	return(old);
+}
+
+#endif
+#if !defined(EVBARM_SPL_NOINLINE)
+
+#define splx(new)		i80321_splx(new)
+#define	_spllower(ipl)		i80321_spllower(ipl)
+#define	_splraise(ipl)		i80321_splraise(ipl)
+void	_setsoftintr(int);
+
+#else
+
+int	_splraise(int);
+int	_spllower(int);
+void	splx(int);
+void	_setsoftintr(int);
+
+#endif /* ! EVBARM_SPL_NOINLINE */
+
+#endif /* _LOCORE */
+
+#endif /* _I80321_INTR_H_ */


Property changes on: trunk/sys/arm/xscale/i80321/i80321_intr.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/i80321/i80321_mcu.c
===================================================================
--- trunk/sys/arm/xscale/i80321/i80321_mcu.c	                        (rev 0)
+++ trunk/sys/arm/xscale/i80321/i80321_mcu.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,91 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: i80321_mcu.c,v 1.2 2003/07/15 00:24:54 lukem Exp $	*/
+
+/*-
+ * Copyright (c) 2001, 2002 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Jason R. Thorpe for Wasabi Systems, Inc.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed for the NetBSD Project by
+ *	Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
+ * 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.
+ */
+
+/*
+ * Intel i80321 I/O Processor memory controller support.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/xscale/i80321/i80321_mcu.c 139735 2005-01-05 21:58:49Z imp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+
+#include <machine/bus.h>
+
+#include <arm/xscale/i80321/i80321reg.h>
+#include <arm/xscale/i80321/i80321var.h>
+
+/*
+ * i80321_sdram_bounds:
+ *
+ *	Retrieve the start and size of SDRAM.
+ */
+void
+i80321_sdram_bounds(bus_space_tag_t st, bus_space_handle_t sh,
+    vm_paddr_t *start, vm_size_t *size)
+{
+	uint32_t sdbr, sbr0, sbr1;
+	uint32_t bank0, bank1;
+
+	sdbr = bus_space_read_4(st, sh, MCU_SDBR);
+	sbr0 = bus_space_read_4(st, sh, MCU_SBR0);
+	sbr1 = bus_space_read_4(st, sh, MCU_SBR1);
+
+#ifdef VERBOSE_INIT_ARM
+	printf("i80321: SBDR = 0x%08x SBR0 = 0x%08x SBR1 = 0x%08x\n",
+	    sdbr, sbr0, sbr1);
+#endif
+
+	*start = sdbr;
+
+	sdbr = (sdbr >> 25) & 0x1f;
+
+	sbr0 &= 0x3f;
+	sbr1 &= 0x3f;
+
+	bank0 = (sbr0 - sdbr) << 25;
+	bank1 = (sbr1 - sbr0) << 25;
+
+#ifdef VERBOSE_INIT_ARM
+	printf("i80321: BANK0 = 0x%08x BANK1 = 0x%08x\n", bank0, bank1);
+#endif
+
+	*size = bank0 + bank1;
+}


Property changes on: trunk/sys/arm/xscale/i80321/i80321_mcu.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/i80321/i80321_pci.c
===================================================================
--- trunk/sys/arm/xscale/i80321/i80321_pci.c	                        (rev 0)
+++ trunk/sys/arm/xscale/i80321/i80321_pci.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,402 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: i80321_pci.c,v 1.4 2003/07/15 00:24:54 lukem Exp $	*/
+
+/*-
+ * Copyright (c) 2001, 2002 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Jason R. Thorpe for Wasabi Systems, Inc.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed for the NetBSD Project by
+ *	Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
+ * 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.
+ */
+
+/*
+ * PCI configuration support for i80321 I/O Processor chip.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/xscale/i80321/i80321_pci.c 259329 2013-12-13 20:43:11Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/rman.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/pcb.h>
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/vm_extern.h>
+
+#include <arm/xscale/i80321/i80321reg.h>
+#include <arm/xscale/i80321/i80321var.h>
+#include <arm/xscale/i80321/i80321_intr.h>
+
+#include <dev/pci/pcib_private.h>
+#include "pcib_if.h"
+
+#include <dev/pci/pcireg.h>
+extern struct i80321_softc *i80321_softc;
+
+static int
+i80321_pci_probe(device_t dev)
+{
+	device_set_desc(dev, "i80321 PCI bus");
+	return (0);
+}
+
+static int
+i80321_pci_attach(device_t dev)
+{
+
+	uint32_t busno;
+	struct i80321_pci_softc *sc = device_get_softc(dev);
+
+	sc->sc_st = i80321_softc->sc_st;
+	sc->sc_atu_sh = i80321_softc->sc_atu_sh;
+	busno = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_PCIXSR);
+	busno = PCIXSR_BUSNO(busno);
+	if (busno == 0xff)
+		busno = 0;
+	sc->sc_dev = dev;
+	sc->sc_busno = busno;
+	sc->sc_pciio = &i80321_softc->sc_pci_iot;
+	sc->sc_pcimem = &i80321_softc->sc_pci_memt;
+	sc->sc_mem = i80321_softc->sc_owin[0].owin_xlate_lo +
+	    VERDE_OUT_XLATE_MEM_WIN_SIZE;
+	
+	sc->sc_io = i80321_softc->sc_iow_vaddr;
+	/* Initialize memory and i/o rmans. */
+	sc->sc_io_rman.rm_type = RMAN_ARRAY;
+	sc->sc_io_rman.rm_descr = "I80321 PCI I/O Ports";
+	if (rman_init(&sc->sc_io_rman) != 0 ||
+		rman_manage_region(&sc->sc_io_rman,
+		sc->sc_io,
+		    sc->sc_io +
+		    VERDE_OUT_XLATE_IO_WIN_SIZE) != 0) {
+		panic("i80321_pci_probe: failed to set up I/O rman");
+	}
+	sc->sc_mem_rman.rm_type = RMAN_ARRAY;
+	sc->sc_mem_rman.rm_descr = "I80321 PCI Memory";
+	if (rman_init(&sc->sc_mem_rman) != 0 ||
+	    rman_manage_region(&sc->sc_mem_rman,
+	    0, VERDE_OUT_XLATE_MEM_WIN_SIZE) != 0) {
+		panic("i80321_pci_probe: failed to set up memory rman");
+	}
+	sc->sc_irq_rman.rm_type = RMAN_ARRAY;
+	sc->sc_irq_rman.rm_descr = "i80321 PCI IRQs";
+	if (rman_init(&sc->sc_irq_rman) != 0 ||
+	    rman_manage_region(&sc->sc_irq_rman, 26, 32) != 0)
+		panic("i80321_pci_probe: failed to set up IRQ rman");
+	device_add_child(dev, "pci",busno);
+	return (bus_generic_attach(dev));
+}
+
+static int
+i80321_pci_maxslots(device_t dev)
+{
+	return (PCI_SLOTMAX);
+}
+
+
+
+static int
+i80321_pci_conf_setup(struct i80321_pci_softc *sc, int bus, int slot, int func,
+    int reg, uint32_t *addr)
+{
+	uint32_t busno;
+
+	busno = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_PCIXSR);
+	busno = PCIXSR_BUSNO(busno);
+	if (busno == 0xff)
+		busno = 0;
+
+	/*
+	 * If the bus # is the same as our own, then use Type 0 cycles,
+	 * else use Type 1.
+	 *
+	 * XXX We should filter out all non-private devices here!
+	 * XXX How does private space interact with PCI-PCI bridges?
+	 */
+	if (bus == busno) {
+		if (slot > (31 - 16))
+			return (1);
+		/*
+		 * NOTE: PCI-X requires that that devices updated their
+		 * PCIXSR on every config write with the device number
+		 * specified in AD[15:11].  If we don't set this field,
+		 * each device could end of thinking it is at device 0,
+		 * which can cause a number of problems.  Doing this
+		 * unconditionally should be OK when only PCI devices
+		 * are present.
+		 */
+		bus &= 0xff;
+		slot &= 0x1f;
+		func &= 0x07;
+		
+		*addr = (1U << (slot + 16)) |
+		    (slot << 11) | (func << 8) | reg;
+	} else {
+		*addr = (bus << 16) | (slot << 11) | (func << 8) | reg | 1;
+	}
+
+	return (0);
+}
+
+static u_int32_t
+i80321_pci_read_config(device_t dev, u_int bus, u_int slot, u_int func,
+    u_int reg, int bytes)
+{
+	struct i80321_pci_softc *sc = device_get_softc(dev);
+	uint32_t isr;
+	uint32_t addr;
+	u_int32_t ret = 0;
+	vm_offset_t va;
+	int err = 0;
+	if (i80321_pci_conf_setup(sc, bus, slot, func, reg & ~3, &addr))
+		return (-1);
+	bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OCCAR,
+	    addr);
+
+	va = sc->sc_atu_sh;
+	switch (bytes) {
+	case 1:
+		err = badaddr_read((void*)(va + ATU_OCCDR + (reg & 3)), 1, &ret);
+		break;
+	case 2:
+		err = badaddr_read((void*)(va + ATU_OCCDR + (reg & 3)), 2, &ret);
+		break;
+	case 4:
+		err = badaddr_read((void *)(va + ATU_OCCDR), 4, &ret);
+		break;
+	default:
+		printf("i80321_read_config: invalid size %d\n", bytes);
+		ret = -1;
+	}
+	if (err) {
+
+		isr = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_ATUISR);
+		bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_ATUISR,
+		    isr & (ATUISR_P_SERR_DET|ATUISR_PMA|ATUISR_PTAM|
+		    ATUISR_PTAT|ATUISR_PMPE));
+		return (-1);
+	}
+	return (ret);
+}
+
+static void
+i80321_pci_write_config(device_t dev, u_int bus, u_int slot, u_int func,
+    u_int reg, u_int32_t data, int bytes)
+{
+	struct i80321_pci_softc *sc = device_get_softc(dev);
+	uint32_t addr;
+
+	if (i80321_pci_conf_setup(sc, bus, slot, func, reg & ~3, &addr))
+		return;
+
+
+	bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OCCAR,
+	    addr);
+	switch (bytes) {
+	case 1:
+		bus_space_write_1(sc->sc_st, sc->sc_atu_sh, ATU_OCCDR +
+		    (reg & 3), data);
+		break;
+	case 2:
+		bus_space_write_2(sc->sc_st, sc->sc_atu_sh, ATU_OCCDR +
+		    (reg & 3), data);
+		break;
+	case 4:
+		bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OCCDR, data);
+		break;
+	default:
+		printf("i80321_pci_write_config: Invalid size : %d\n", bytes);
+	}
+
+}
+
+static int
+i80321_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
+{
+	struct i80321_pci_softc *sc = device_get_softc(dev);
+	switch (which) {
+	case PCIB_IVAR_DOMAIN:
+		*result = 0;
+		return (0);
+	case PCIB_IVAR_BUS:
+		*result = sc->sc_busno;
+		return (0);
+		
+	}
+	return (ENOENT);
+}
+
+static int
+i80321_write_ivar(device_t dev, device_t child, int which, uintptr_t result)
+{
+	struct i80321_pci_softc * sc = device_get_softc(dev);
+
+	switch (which) {
+	case PCIB_IVAR_DOMAIN:
+		return (EINVAL);
+	case PCIB_IVAR_BUS:
+		sc->sc_busno = result;
+		return (0);
+	}
+	return (ENOENT);
+}
+
+static struct resource *
+i80321_pci_alloc_resource(device_t bus, device_t child, int type, int *rid,
+    u_long start, u_long end, u_long count, u_int flags)
+{
+	struct i80321_pci_softc *sc = device_get_softc(bus);	
+	struct resource *rv;
+	struct rman *rm;
+	bus_space_tag_t bt = NULL;
+	bus_space_handle_t bh = 0;
+
+	switch (type) {
+	case SYS_RES_IRQ:
+		rm = &sc->sc_irq_rman;
+		break;
+	case SYS_RES_MEMORY:
+		rm = &sc->sc_mem_rman;
+		bt = sc->sc_pcimem;
+		bh = (start >= 0x80000000 && start < 0x84000000) ? 0x80000000 :
+		    sc->sc_mem;
+		start &= (0x1000000 - 1);
+		end &= (0x1000000 - 1);
+		break;
+	case SYS_RES_IOPORT:
+		rm = &sc->sc_io_rman;
+		bt = sc->sc_pciio;
+		bh = sc->sc_io;
+		if (start < sc->sc_io) {
+			start = start - 0x90000000 + sc->sc_io;
+			end = end - 0x90000000 + sc->sc_io;
+		}
+		break;
+	default:
+		return (NULL);
+	}
+
+	rv = rman_reserve_resource(rm, start, end, count, flags, child);
+	if (rv == NULL)
+		return (NULL);
+	rman_set_rid(rv, *rid);
+	if (type != SYS_RES_IRQ) {
+		if (type == SYS_RES_MEMORY)
+			bh += (rman_get_start(rv));
+		rman_set_bustag(rv, bt);
+		rman_set_bushandle(rv, bh);
+		if (flags & RF_ACTIVE) {
+			if (bus_activate_resource(child, type, *rid, rv)) {
+				rman_release_resource(rv);
+				return (NULL);
+			}
+		}
+	}
+	return (rv);
+}
+
+static int
+i80321_pci_activate_resource(device_t bus, device_t child, int type, int rid,
+    struct resource *r)
+{
+	u_long p;
+	int error;
+	
+	if (type == SYS_RES_MEMORY) {
+		error = bus_space_map(rman_get_bustag(r),
+		    rman_get_bushandle(r), rman_get_size(r), 0, &p);
+		if (error)
+			return (error);
+		rman_set_bushandle(r, p);
+	
+	}
+	return (rman_activate_resource(r));
+}
+
+static int
+i80321_pci_setup_intr(device_t dev, device_t child,
+    struct resource *ires, int flags, driver_filter_t *filt,
+    driver_intr_t *intr, void *arg, void **cookiep)
+{
+	return (BUS_SETUP_INTR(device_get_parent(dev), child, ires, flags,
+	    filt, intr, arg, cookiep));
+}
+
+static int
+i80321_pci_teardown_intr(device_t dev, device_t child, struct resource *res,
+    void *cookie)
+{
+	return (BUS_TEARDOWN_INTR(device_get_parent(dev), child, res, cookie));
+}
+
+static device_method_t i80321_pci_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		i80321_pci_probe),
+	DEVMETHOD(device_attach,	i80321_pci_attach),
+	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
+	DEVMETHOD(device_suspend,	bus_generic_suspend),
+	DEVMETHOD(device_resume,	bus_generic_resume),
+
+	/* Bus interface */
+	DEVMETHOD(bus_read_ivar,	i80321_read_ivar),
+	DEVMETHOD(bus_write_ivar,	i80321_write_ivar),
+	DEVMETHOD(bus_alloc_resource,	i80321_pci_alloc_resource),
+	DEVMETHOD(bus_release_resource,	bus_generic_release_resource),
+	DEVMETHOD(bus_activate_resource, i80321_pci_activate_resource),
+	DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+	DEVMETHOD(bus_setup_intr,	i80321_pci_setup_intr),
+	DEVMETHOD(bus_teardown_intr,	i80321_pci_teardown_intr),
+
+	/* pcib interface */
+	DEVMETHOD(pcib_maxslots,	i80321_pci_maxslots),
+	DEVMETHOD(pcib_read_config,	i80321_pci_read_config),
+	DEVMETHOD(pcib_write_config,	i80321_pci_write_config),
+	DEVMETHOD(pcib_route_interrupt,	machdep_pci_route_interrupt),
+
+	DEVMETHOD_END
+};
+
+static driver_t i80321_pci_driver = {
+	"pcib",
+	i80321_pci_methods,
+	sizeof(struct i80321_pci_softc),
+};
+
+static devclass_t i80321_pci_devclass;
+
+DRIVER_MODULE(ipci, iq, i80321_pci_driver, i80321_pci_devclass, 0, 0);


Property changes on: trunk/sys/arm/xscale/i80321/i80321_pci.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/i80321/i80321_space.c
===================================================================
--- trunk/sys/arm/xscale/i80321/i80321_space.c	                        (rev 0)
+++ trunk/sys/arm/xscale/i80321/i80321_space.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,210 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: i80321_space.c,v 1.6 2003/10/06 15:43:35 thorpej Exp $	*/
+
+/*-
+ * Copyright (c) 2001, 2002 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Jason R. Thorpe for Wasabi Systems, Inc.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed for the NetBSD Project by
+ *	Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
+ * 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.
+ */
+
+/*
+ * bus_space functions for i80321 I/O Processor.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/xscale/i80321/i80321_space.c 278727 2015-02-13 22:32:02Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+
+#include <machine/pcb.h>
+
+#include <vm/vm.h>
+#include <vm/vm_kern.h>
+#include <vm/pmap.h>
+#include <vm/vm_page.h>
+#include <vm/vm_extern.h>
+
+#include <machine/bus.h>
+
+#include <arm/xscale/i80321/i80321reg.h>
+#include <arm/xscale/i80321/i80321var.h>
+
+/* Prototypes for all the bus_space structure functions */
+bs_protos(i80321);
+bs_protos(i80321_io);
+bs_protos(i80321_mem);
+
+void
+i80321_bs_init(bus_space_tag_t bs, void *cookie)
+{
+
+	*bs = *arm_base_bs_tag;
+	bs->bs_privdata = cookie;
+}
+
+void
+i80321_io_bs_init(bus_space_tag_t bs, void *cookie)
+{
+
+	*bs = *arm_base_bs_tag;
+	bs->bs_privdata = cookie;
+
+	bs->bs_map = i80321_io_bs_map;
+	bs->bs_unmap = i80321_io_bs_unmap;
+	bs->bs_alloc = i80321_io_bs_alloc;
+	bs->bs_free = i80321_io_bs_free;
+
+}
+
+void
+i80321_mem_bs_init(bus_space_tag_t bs, void *cookie)
+{
+
+	*bs = *arm_base_bs_tag;
+	bs->bs_privdata = cookie;
+
+	bs->bs_map = i80321_mem_bs_map;
+	bs->bs_unmap = i80321_mem_bs_unmap;
+	bs->bs_alloc = i80321_mem_bs_alloc;
+	bs->bs_free = i80321_mem_bs_free;
+
+}
+
+/* *** Routines shared by i80321, PCI IO, and PCI MEM. *** */
+
+int
+i80321_bs_subregion(bus_space_tag_t tag, bus_space_handle_t bsh, bus_size_t offset,
+    bus_size_t size, bus_space_handle_t *nbshp)
+{
+
+	*nbshp = bsh + offset;
+	return (0);
+}
+
+void
+i80321_bs_barrier(bus_space_tag_t tag, bus_space_handle_t bsh, bus_size_t offset,
+    bus_size_t len, int flags)
+{
+
+	/* Nothing to do. */
+}
+
+/* *** Routines for PCI IO. *** */
+
+extern struct i80321_softc *i80321_softc;
+int
+i80321_io_bs_map(bus_space_tag_t tag, bus_addr_t bpa, bus_size_t size, int flags,
+    bus_space_handle_t *bshp)
+{
+	struct i80321_softc *sc = i80321_softc;
+	vm_offset_t winvaddr;
+	uint32_t busbase;
+
+	if (bpa >= sc->sc_ioout_xlate &&
+	    bpa < (sc->sc_ioout_xlate + VERDE_OUT_XLATE_IO_WIN_SIZE)) {
+		busbase = sc->sc_ioout_xlate;
+		winvaddr = sc->sc_iow_vaddr;
+	} else
+		return (EINVAL);
+
+	if ((bpa + size) >= (busbase + VERDE_OUT_XLATE_IO_WIN_SIZE))
+		return (EINVAL);
+
+	/*
+	 * Found the window -- PCI I/O space is mapped at a fixed
+	 * virtual address by board-specific code.  Translate the
+	 * bus address to the virtual address.
+	 */
+	*bshp = winvaddr + (bpa - busbase);
+
+	return (0);
+}
+
+void
+i80321_io_bs_unmap(bus_space_tag_t tag, bus_space_handle_t h, bus_size_t size)
+{
+
+	/* Nothing to do. */
+}
+
+int
+i80321_io_bs_alloc(bus_space_tag_t tag, bus_addr_t rstart, bus_addr_t rend,
+    bus_size_t size, bus_size_t alignment, bus_size_t boundary, int flags,
+    bus_addr_t *bpap, bus_space_handle_t *bshp)
+{
+
+	panic("i80321_io_bs_alloc(): not implemented");
+}
+
+void
+i80321_io_bs_free(bus_space_tag_t tag, bus_space_handle_t bsh, bus_size_t size)
+{
+
+	panic("i80321_io_bs_free(): not implemented");
+}
+
+
+/* *** Routines for PCI MEM. *** */
+extern int badaddr_read(void *, int, void *);
+int
+i80321_mem_bs_map(bus_space_tag_t tag, bus_addr_t bpa, bus_size_t size, int flags,
+    bus_space_handle_t *bshp)
+{
+
+	*bshp = (vm_offset_t)pmap_mapdev(bpa, size);
+	return (0);
+}
+
+void
+i80321_mem_bs_unmap(bus_space_tag_t tag, bus_space_handle_t h, bus_size_t size)
+{
+
+	pmap_unmapdev((vm_offset_t)h, size);
+}
+
+int
+i80321_mem_bs_alloc(bus_space_tag_t tag, bus_addr_t rstart, bus_addr_t rend,
+    bus_size_t size, bus_size_t alignment, bus_size_t boundary, int flags,
+    bus_addr_t *bpap, bus_space_handle_t *bshp)
+{
+
+	panic("i80321_mem_bs_alloc(): not implemented");
+}
+
+void
+i80321_mem_bs_free(bus_space_tag_t tag, bus_space_handle_t bsh, bus_size_t size)
+{
+
+	panic("i80321_mem_bs_free(): not implemented");
+}


Property changes on: trunk/sys/arm/xscale/i80321/i80321_space.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/i80321/i80321_timer.c
===================================================================
--- trunk/sys/arm/xscale/i80321/i80321_timer.c	                        (rev 0)
+++ trunk/sys/arm/xscale/i80321/i80321_timer.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,486 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: i80321_timer.c,v 1.7 2003/07/27 04:52:28 thorpej Exp $	*/
+
+/*-
+ * Copyright (c) 2001, 2002 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Jason R. Thorpe for Wasabi Systems, Inc.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed for the NetBSD Project by
+ *	Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
+ * 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.
+ */
+
+/*
+ * Timer/clock support for the Intel i80321 I/O processor.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/xscale/i80321/i80321_timer.c 278613 2015-02-12 03:50:33Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/time.h>
+#include <sys/bus.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+#include <sys/timetc.h>
+
+#include <machine/armreg.h>
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+#include <machine/frame.h>
+#include <machine/resource.h>
+#include <machine/intr.h>
+#include <arm/xscale/i80321/i80321reg.h>
+#include <arm/xscale/i80321/i80321var.h>
+
+#ifdef CPU_XSCALE_81342
+#define ICU_INT_TIMER0	(8) /* XXX: Can't include i81342reg.h because
+			       definitions overrides the ones from i80321reg.h
+			       */
+#endif
+#include "opt_timer.h"
+
+void (*i80321_hardclock_hook)(void) = NULL;
+struct i80321_timer_softc {
+	device_t	dev;
+} timer_softc;
+
+
+static unsigned i80321_timer_get_timecount(struct timecounter *tc);
+	
+
+static uint32_t counts_per_hz;
+
+#if defined(XSCALE_DISABLE_CCNT) || defined(CPU_XSCALE_81342)
+static uint32_t offset;
+static uint32_t last = -1;
+#endif
+
+static int ticked = 0;
+
+#ifndef COUNTS_PER_SEC
+#define	COUNTS_PER_SEC		200000000	/* 200MHz */
+#endif
+
+#define	COUNTS_PER_USEC		(COUNTS_PER_SEC / 1000000)
+
+static struct timecounter i80321_timer_timecounter = {
+	i80321_timer_get_timecount, /* get_timecount */
+	NULL,			    /* no poll_pps */
+	~0u,			    /* counter_mask */
+#if defined(XSCALE_DISABLE_CCNT) || defined(CPU_XSCALE_81342)
+	COUNTS_PER_SEC,
+#else
+	COUNTS_PER_SEC * 3,	 	   /* frequency */
+#endif
+	"i80321 timer",		    /* name */
+	1000			    /* quality */
+};
+
+static int
+i80321_timer_probe(device_t dev)
+{
+
+	device_set_desc(dev, "i80321 timer");
+	return (0);
+}
+
+static int
+i80321_timer_attach(device_t dev)
+{
+	timer_softc.dev = dev;
+
+	return (0);
+}
+
+static device_method_t i80321_timer_methods[] = {
+	DEVMETHOD(device_probe, i80321_timer_probe),
+	DEVMETHOD(device_attach, i80321_timer_attach),
+	{0, 0},
+};
+
+static driver_t i80321_timer_driver = {
+	"itimer",
+	i80321_timer_methods,
+	sizeof(struct i80321_timer_softc),
+};
+static devclass_t i80321_timer_devclass;
+
+DRIVER_MODULE(itimer, iq, i80321_timer_driver, i80321_timer_devclass, 0, 0);
+
+int	clockhandler(void *);
+
+
+static __inline uint32_t
+tmr1_read(void)
+{
+	uint32_t rv;
+
+#ifdef CPU_XSCALE_81342
+	__asm __volatile("mrc p6, 0, %0, c1, c9, 0"
+#else
+	__asm __volatile("mrc p6, 0, %0, c1, c1, 0"
+#endif
+		: "=r" (rv));
+	return (rv);
+}
+
+static __inline void
+tmr1_write(uint32_t val)
+{
+
+
+#ifdef CPU_XSCALE_81342
+	__asm __volatile("mcr p6, 0, %0, c1, c9, 0"
+#else
+	__asm __volatile("mcr p6, 0, %0, c1, c1, 0"
+#endif
+		:
+		: "r" (val));
+}
+
+static __inline uint32_t
+tcr1_read(void)
+{
+	uint32_t rv;
+
+#ifdef CPU_XSCALE_81342
+	__asm __volatile("mrc p6, 0, %0, c3, c9, 0"
+#else
+	__asm __volatile("mrc p6, 0, %0, c3, c1, 0"
+#endif
+		: "=r" (rv));
+	return (rv);
+}
+static __inline void
+tcr1_write(uint32_t val)
+{
+
+#ifdef CPU_XSCALE_81342
+	__asm __volatile("mcr p6, 0, %0, c3, c9, 0"
+#else
+	__asm __volatile("mcr p6, 0, %0, c3, c1, 0"
+#endif
+		:
+		: "r" (val));
+}
+
+static __inline void
+trr1_write(uint32_t val)
+{
+
+#ifdef CPU_XSCALE_81342
+	__asm __volatile("mcr p6, 0, %0, c5, c9, 0"
+#else
+	__asm __volatile("mcr p6, 0, %0, c5, c1, 0"
+#endif
+		:
+		: "r" (val));
+}
+
+static __inline uint32_t
+tmr0_read(void)
+{
+	uint32_t rv;
+
+#ifdef CPU_XSCALE_81342
+	__asm __volatile("mrc p6, 0, %0, c0, c9, 0"
+#else
+	__asm __volatile("mrc p6, 0, %0, c0, c1, 0"
+#endif
+		: "=r" (rv));
+	return (rv);
+}
+
+static __inline void
+tmr0_write(uint32_t val)
+{
+
+#ifdef CPU_XSCALE_81342
+	__asm __volatile("mcr p6, 0, %0, c0, c9, 0"
+#else
+	__asm __volatile("mcr p6, 0, %0, c0, c1, 0"
+#endif
+		:
+		: "r" (val));
+}
+
+static __inline uint32_t
+tcr0_read(void)
+{
+	uint32_t rv;
+
+#ifdef CPU_XSCALE_81342
+	__asm __volatile("mrc p6, 0, %0, c2, c9, 0"
+#else
+	__asm __volatile("mrc p6, 0, %0, c2, c1, 0"
+#endif
+		: "=r" (rv));
+	return (rv);
+}
+static __inline void
+tcr0_write(uint32_t val)
+{
+
+#ifdef CPU_XSCALE_81342
+	__asm __volatile("mcr p6, 0, %0, c2, c9, 0"
+#else
+	__asm __volatile("mcr p6, 0, %0, c2, c1, 0"
+#endif
+		:
+		: "r" (val));
+}
+
+static __inline void
+trr0_write(uint32_t val)
+{
+
+#ifdef CPU_XSCALE_81342
+	__asm __volatile("mcr p6, 0, %0, c4, c9, 0"
+#else
+	__asm __volatile("mcr p6, 0, %0, c4, c1, 0"
+#endif
+		:
+		: "r" (val));
+}
+
+static __inline void
+tisr_write(uint32_t val)
+{
+
+#ifdef CPU_XSCALE_81342
+	__asm __volatile("mcr p6, 0, %0, c6, c9, 0"
+#else
+	__asm __volatile("mcr p6, 0, %0, c6, c1, 0"
+#endif
+		:
+		: "r" (val));
+}
+
+static __inline uint32_t
+tisr_read(void)
+{
+	int ret;
+	
+#ifdef CPU_XSCALE_81342
+	__asm __volatile("mrc p6, 0, %0, c6, c9, 0" : "=r" (ret));
+#else
+	__asm __volatile("mrc p6, 0, %0, c6, c1, 0" : "=r" (ret));
+#endif
+	return (ret);
+}
+
+static unsigned
+i80321_timer_get_timecount(struct timecounter *tc)
+{
+#if defined(XSCALE_DISABLE_CCNT) || defined(CPU_XSCALE_81342)
+	uint32_t cur = tcr0_read();
+
+	if (cur > last && last != -1) {
+		offset += counts_per_hz;
+		if (ticked > 0)
+			ticked--;
+	}
+	if (ticked) {
+		offset += ticked * counts_per_hz;
+		ticked = 0;
+	}
+	return (counts_per_hz - cur + offset);
+#else
+	uint32_t ret;
+
+	__asm __volatile("mrc p14, 0, %0, c1, c0, 0\n"
+	    : "=r" (ret));
+	return (ret);
+#endif
+}
+
+/*
+ * i80321_calibrate_delay:
+ *
+ *	Calibrate the delay loop.
+ */
+void
+i80321_calibrate_delay(void)
+{
+
+	/*
+	 * Just use hz=100 for now -- we'll adjust it, if necessary,
+	 * in cpu_initclocks().
+	 */
+	counts_per_hz = COUNTS_PER_SEC / 100;
+
+	tmr0_write(0);			/* stop timer */
+	tisr_write(TISR_TMR0);		/* clear interrupt */
+	trr0_write(counts_per_hz);	/* reload value */
+	tcr0_write(counts_per_hz);	/* current value */
+
+	tmr0_write(TMRx_ENABLE|TMRx_RELOAD|TMRx_CSEL_CORE);
+}
+
+/*
+ * cpu_initclocks:
+ *
+ *	Initialize the clock and get them going.
+ */
+void
+cpu_initclocks(void)
+{
+	u_int oldirqstate;
+	struct resource *irq;
+	int rid = 0;
+	void *ihl;
+	device_t dev = timer_softc.dev;
+
+	if (hz < 50 || COUNTS_PER_SEC % hz) {
+		printf("Cannot get %d Hz clock; using 100 Hz\n", hz);
+		hz = 100;
+	}
+	tick = 1000000 / hz;	/* number of microseconds between interrupts */
+
+	/*
+	 * We only have one timer available; stathz and profhz are
+	 * always left as 0 (the upper-layer clock code deals with
+	 * this situation).
+	 */
+	if (stathz != 0)
+		printf("Cannot get %d Hz statclock\n", stathz);
+	stathz = 0;
+
+	if (profhz != 0)
+		printf("Cannot get %d Hz profclock\n", profhz);
+	profhz = 0;
+
+	/* Report the clock frequency. */
+
+	oldirqstate = disable_interrupts(PSR_I);
+
+	irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid,
+#ifdef CPU_XSCALE_81342
+	    ICU_INT_TIMER0, ICU_INT_TIMER0,
+#else
+	    ICU_INT_TMR0, ICU_INT_TMR0,
+#endif
+	    1, RF_ACTIVE);
+	if (!irq)
+		panic("Unable to setup the clock irq handler.\n");
+	else
+		bus_setup_intr(dev, irq, INTR_TYPE_CLK, clockhandler, NULL,
+		    NULL, &ihl);
+	tmr0_write(0);			/* stop timer */
+	tisr_write(TISR_TMR0);		/* clear interrupt */
+
+	counts_per_hz = COUNTS_PER_SEC / hz;
+
+	trr0_write(counts_per_hz);	/* reload value */
+	tcr0_write(counts_per_hz);	/* current value */
+	tmr0_write(TMRx_ENABLE|TMRx_RELOAD|TMRx_CSEL_CORE);
+
+	tc_init(&i80321_timer_timecounter);
+	restore_interrupts(oldirqstate);
+	rid = 0;
+#if !defined(XSCALE_DISABLE_CCNT) && !defined(CPU_XSCALE_81342)
+	/* Enable the clock count register. */
+	__asm __volatile("mrc p14, 0, %0, c0, c0, 0\n" : "=r" (rid));
+	rid &= ~(1 <<  3);
+	rid |= (1 << 2) | 1;
+	__asm __volatile("mcr p14, 0, %0, c0, c0, 0\n"
+	    : : "r" (rid));
+#endif
+}
+
+
+/*
+ * DELAY:
+ *
+ *	Delay for at least N microseconds.
+ */
+void
+DELAY(int n)
+{
+	uint32_t cur, last, delta, usecs;
+
+	/*
+	 * This works by polling the timer and counting the
+	 * number of microseconds that go by.
+	 */
+	last = tcr0_read();
+	delta = usecs = 0;
+
+	while (n > usecs) {
+		cur = tcr0_read();
+
+		/* Check to see if the timer has wrapped around. */
+		if (last < cur)
+			delta += (last + (counts_per_hz - cur));
+		else
+			delta += (last - cur);
+
+		last = cur;
+
+		if (delta >= COUNTS_PER_USEC) {
+			usecs += delta / COUNTS_PER_USEC;
+			delta %= COUNTS_PER_USEC;
+		}
+	}
+}
+
+/*
+ * clockhandler:
+ *
+ *	Handle the hardclock interrupt.
+ */
+int
+clockhandler(void *arg)
+{
+	struct trapframe *frame = arg;
+
+	ticked++;
+	tisr_write(TISR_TMR0);
+	hardclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
+
+	if (i80321_hardclock_hook != NULL)
+		(*i80321_hardclock_hook)();
+	return (FILTER_HANDLED);
+}
+
+void
+cpu_startprofclock(void)
+{
+}
+
+void
+cpu_stopprofclock(void)
+{
+	
+}


Property changes on: trunk/sys/arm/xscale/i80321/i80321_timer.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/i80321/i80321_wdog.c
===================================================================
--- trunk/sys/arm/xscale/i80321/i80321_wdog.c	                        (rev 0)
+++ trunk/sys/arm/xscale/i80321/i80321_wdog.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,155 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: i80321_wdog.c,v 1.6 2003/07/15 00:24:54 lukem Exp $	*/
+
+/*-
+ * Copyright (c) 2005 Olivier Houchard
+ * Copyright (c) 2002 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Jason R. Thorpe for Wasabi Systems, Inc.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed for the NetBSD Project by
+ *	Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
+ * 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.
+ */
+
+/*
+ * Watchdog timer support for the Intel i80321 I/O processor.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/xscale/i80321/i80321_wdog.c 171627 2007-07-27 14:52:04Z cognet $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/watchdog.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+
+#include <machine/bus.h>
+#include <machine/cpufunc.h>
+#include <machine/machdep.h>
+
+#include <arm/xscale/i80321/i80321reg.h>
+#include <arm/xscale/i80321/i80321var.h>
+
+
+struct iopwdog_softc {
+	device_t dev;
+	int armed;
+	int wdog_period;
+};
+
+static __inline void
+wdtcr_write(uint32_t val)
+{
+
+#ifdef CPU_XSCALE_81342
+	__asm __volatile("mcr p6, 0, %0, c7, c9, 0"
+#else
+	__asm __volatile("mcr p6, 0, %0, c7, c1, 0"
+#endif
+		:
+		: "r" (val));
+}
+
+static void
+iopwdog_tickle(void *arg)
+{
+	struct iopwdog_softc *sc = arg;
+
+	if (!sc->armed)
+		return;
+	wdtcr_write(WDTCR_ENABLE1);
+	wdtcr_write(WDTCR_ENABLE2);
+}
+
+static int
+iopwdog_probe(device_t dev)
+{
+	struct iopwdog_softc *sc = device_get_softc(dev);
+	char buf[128];
+
+	/*
+	 * XXX Should compute the period based on processor speed.
+	 * For a 600MHz XScale core, the wdog must be tickled approx.
+	 * every 7 seconds.
+	 */
+
+	sc->wdog_period = 7;
+	sprintf(buf, "i80321 Watchdog, must be tickled every %d seconds",
+	    sc->wdog_period);
+	device_set_desc_copy(dev, buf);
+
+	return (0);
+}
+
+static void
+iopwdog_watchdog_fn(void *private, u_int cmd, int *error)
+{
+	struct iopwdog_softc *sc = private;
+
+	cmd &= WD_INTERVAL;
+	if (cmd > 0 && cmd <= 63
+	    && (uint64_t)1<<cmd <= (uint64_t)sc->wdog_period * 1000000000) {
+		/* Valid value -> Enable watchdog */
+		iopwdog_tickle(sc);
+		sc->armed = 1;
+		*error = 0;
+	} else {
+		/* Can't disable this watchdog! */
+		if (sc->armed)
+			*error = EOPNOTSUPP;
+	}
+}
+
+static int
+iopwdog_attach(device_t dev)
+{
+	struct iopwdog_softc *sc = device_get_softc(dev);
+	
+	sc->dev = dev;
+	sc->armed = 0;
+	EVENTHANDLER_REGISTER(watchdog_list, iopwdog_watchdog_fn, sc, 0);
+	return (0);
+}
+
+static device_method_t iopwdog_methods[] = {
+	DEVMETHOD(device_probe, iopwdog_probe),
+	DEVMETHOD(device_attach, iopwdog_attach),
+	{0, 0},
+};
+
+static driver_t iopwdog_driver = {
+	"iopwdog",
+	iopwdog_methods,
+	sizeof(struct iopwdog_softc),
+};
+static devclass_t iopwdog_devclass;
+
+DRIVER_MODULE(iopwdog, iq, iopwdog_driver, iopwdog_devclass, 0, 0);


Property changes on: trunk/sys/arm/xscale/i80321/i80321_wdog.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/i80321/i80321reg.h
===================================================================
--- trunk/sys/arm/xscale/i80321/i80321reg.h	                        (rev 0)
+++ trunk/sys/arm/xscale/i80321/i80321reg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,548 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: i80321reg.h,v 1.14 2003/12/19 10:08:11 gavan Exp $	*/
+
+/*-
+ * Copyright (c) 2002 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Jason R. Thorpe for Wasabi Systems, Inc.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed for the NetBSD Project by
+ *	Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
+ * 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: stable/10/sys/arm/xscale/i80321/i80321reg.h 236987 2012-06-13 04:38:09Z imp $
+ *
+ */
+
+#ifndef _ARM_XSCALE_I80321REG_H_
+#define _ARM_XSCALE_I80321REG_H_
+
+/*
+ * Register definitions for the Intel 80321 (``Verde'') I/O processor,
+ * based on the XScale core.
+ */
+
+/*
+ * Base i80321 memory map:
+ *
+ *	0x0000.0000 - 0x7fff.ffff	ATU Outbound Direct Addressing Window
+ *	0x8000.0000 - 0x9001.ffff	ATU Outbound Translation Windows
+ *	0x9002.0000 - 0xffff.dfff	External Memory
+ *	0xffff.e000 - 0xffff.e8ff	Peripheral Memory Mapped Registers
+ *	0xffff.e900 - 0xffff.ffff	Reserved
+ */
+
+#define	VERDE_OUT_DIRECT_WIN_BASE	0x00000000UL
+#define	VERDE_OUT_DIRECT_WIN_SIZE	0x80000000UL
+
+#define	VERDE_OUT_XLATE_MEM_WIN_SIZE	0x04000000UL
+#define	VERDE_OUT_XLATE_IO_WIN_SIZE	0x00010000UL
+
+#define	VERDE_OUT_XLATE_MEM_WIN0_BASE	0x80000000UL
+#define	VERDE_OUT_XLATE_MEM_WIN1_BASE	0x84000000UL
+
+#define	VERDE_OUT_XLATE_IO_WIN0_BASE	0x90000000UL
+
+#define	VERDE_EXTMEM_BASE		0x90020000UL
+
+#define	VERDE_PMMR_BASE			0xffffe000UL
+#define	VERDE_PMMR_SIZE			0x00001700UL
+
+/*
+ * Peripheral Memory Mapped Registers.  Defined as offsets
+ * from the VERDE_PMMR_BASE.
+ */
+#define	VERDE_ATU_BASE			0x0100
+#define	VERDE_ATU_SIZE			0x0100
+
+#define	VERDE_MU_BASE			0x0300
+#define	VERDE_MU_SIZE			0x0100
+
+#define	VERDE_DMA_BASE			0x0400
+#define	VERDE_DMA_BASE0			(VERDE_DMA_BASE + 0x00)
+#define	VERDE_DMA_BASE1			(VERDE_DMA_BASE + 0x40)
+#define	VERDE_DMA_SIZE			0x0100
+#define	VERDE_DMA_CHSIZE		0x0040
+
+#define	VERDE_MCU_BASE			0x0500
+#define	VERDE_MCU_SIZE			0x0100
+
+#if defined(CPU_XSCALE_80321)
+#define	VERDE_SSP_BASE			0x0600
+#define	VERDE_SSP_SIZE			0x0080
+#endif
+
+#define	VERDE_PBIU_BASE			0x0680
+#define	VERDE_PBIU_SIZE			0x0080
+
+#if defined(CPU_XSCALE_80321)
+#define	VERDE_AAU_BASE			0x0800
+#define	VERDE_AAU_SIZE			0x0100
+#endif
+
+#define	VERDE_I2C_BASE			0x1680
+#define	VERDE_I2C_BASE0			(VERDE_I2C_BASE + 0x00)
+#define	VERDE_I2C_BASE1			(VERDE_I2C_BASE + 0x20)
+#define	VERDE_I2C_SIZE			0x0080
+#define	VERDE_I2C_CHSIZE		0x0020
+
+/*
+ * Address Translation Unit
+ */
+	/* 0x00 - 0x38 -- PCI configuration space header */
+#define	ATU_IALR0	0x40	/* Inbound ATU Limit 0 */
+#define	ATU_IATVR0	0x44	/* Inbound ATU Xlate Value 0 */
+#define	ATU_ERLR	0x48	/* Expansion ROM Limit */
+#define	ATU_ERTVR	0x4c	/* Expansion ROM Xlate Value */
+#define	ATU_IALR1	0x50	/* Inbound ATU Limit 1 */
+#define	ATU_IALR2	0x54	/* Inbound ATU Limit 2 */
+#define	ATU_IATVR2	0x58	/* Inbound ATU Xlate Value 2 */
+#define	ATU_OIOWTVR	0x5c	/* Outbound I/O Window Xlate Value */
+#define	ATU_OMWTVR0	0x60	/* Outbound Mem Window Xlate Value 0 */
+#define	ATU_OUMWTVR0	0x64	/* Outbound Mem Window Xlate Value 0 Upper */
+#define	ATU_OMWTVR1	0x68	/* Outbound Mem Window Xlate Value 1 */
+#define	ATU_OUMWTVR1	0x6c	/* Outbound Mem Window Xlate Value 1 Upper */
+#define	ATU_OUDWTVR	0x78	/* Outbound Mem Direct Xlate Value Upper */
+#define	ATU_ATUCR	0x80	/* ATU Configuration */
+#define	ATU_PCSR	0x84	/* PCI Configuration and Status */
+#define	ATU_ATUISR	0x88	/* ATU Interrupt Status */
+#define	ATU_ATUIMR	0x8c	/* ATU Interrupt Mask */
+#define	ATU_IABAR3	0x90	/* Inbound ATU Base Address 3 */
+#define	ATU_IAUBAR3	0x94	/* Inbound ATU Base Address 3 Upper */
+#define	ATU_IALR3	0x98	/* Inbound ATU Limit 3 */
+#define	ATU_IATVR3	0x9c	/* Inbound ATU Xlate Value 3 */
+#define	ATU_OCCAR	0xa4	/* Outbound Configuration Cycle Address */
+#define	ATU_OCCDR	0xac	/* Outbound Configuration Cycle Data */
+#define	ATU_MSI_PORT	0xb4	/* MSI port */
+#define	ATU_PDSCR	0xbc	/* PCI Bus Drive Strength Control */
+#define	ATU_PCI_X_CAP_ID 0xe0	/* (1) */
+#define	ATU_PCI_X_NEXT	0xe1	/* (1) */
+#define	ATU_PCIXCMD	0xe2	/* PCI-X Command Register (2) */
+#define	ATU_PCIXSR	0xe4	/* PCI-X Status Register */
+
+#define	ATUCR_DRC_ALIAS		(1U << 19)
+#define	ATUCR_DAU2GXEN		(1U << 18)
+#define	ATUCR_P_SERR_MA		(1U << 16)
+#define	ATUCR_DTS		(1U << 15)
+#define	ATUCR_P_SERR_DIE	(1U << 9)
+#define	ATUCR_DAE		(1U << 8)
+#define	ATUCR_BIST_IE		(1U << 3)
+#define	ATUCR_OUT_EN		(1U << 1)
+
+#define	PCSR_DAAAPE		(1U << 18)
+#define	PCSR_PCI_X_CAP		(3U << 16)
+#define	PCSR_PCI_X_CAP_BORING	(0 << 16)
+#define	PCSR_PCI_X_CAP_66	(1U << 16)
+#define	PCSR_PCI_X_CAP_100	(2U << 16)
+#define	PCSR_PCI_X_CAP_133	(3U << 16)
+#define	PCSR_OTQB		(1U << 15)
+#define	PCSR_IRTQB		(1U << 14)
+#define	PCSR_DTV		(1U << 12)
+#define	PCSR_BUS66		(1U << 10)
+#define	PCSR_BUS64		(1U << 8)
+#define	PCSR_RIB		(1U << 5)
+#define	PCSR_RPB		(1U << 4)
+#define	PCSR_CCR		(1U << 2)
+#define	PCSR_CPR		(1U << 1)
+
+#define	ATUISR_IMW1BU		(1U << 14)
+#define	ATUISR_ISCEM		(1U << 13)
+#define	ATUISR_RSCEM		(1U << 12)
+#define	ATUISR_PST		(1U << 11)
+#define	ATUISR_P_SERR_ASRT	(1U << 10)
+#define	ATUISR_DPE		(1U << 9)
+#define	ATUISR_BIST		(1U << 8)
+#define	ATUISR_IBMA		(1U << 7)
+#define	ATUISR_P_SERR_DET	(1U << 4)
+#define	ATUISR_PMA		(1U << 3)
+#define	ATUISR_PTAM		(1U << 2)
+#define	ATUISR_PTAT		(1U << 1)
+#define	ATUISR_PMPE		(1U << 0)
+
+#define	ATUIMR_IMW1BU		(1U << 11)
+#define	ATUIMR_ISCEM		(1U << 10)
+#define	ATUIMR_RSCEM		(1U << 9)
+#define	ATUIMR_PST		(1U << 8)
+#define	ATUIMR_DPE		(1U << 7)
+#define	ATUIMR_P_SERR_ASRT	(1U << 6)
+#define	ATUIMR_PMA		(1U << 5)
+#define	ATUIMR_PTAM		(1U << 4)
+#define	ATUIMR_PTAT		(1U << 3)
+#define	ATUIMR_PMPE		(1U << 2)
+#define	ATUIMR_IE_SERR_EN	(1U << 1)
+#define	ATUIMR_ECC_TAE		(1U << 0)
+
+#define	PCIXCMD_MOST_1		(0 << 4)
+#define	PCIXCMD_MOST_2		(1 << 4)
+#define	PCIXCMD_MOST_3		(2 << 4)
+#define	PCIXCMD_MOST_4		(3 << 4)
+#define	PCIXCMD_MOST_8		(4 << 4)
+#define	PCIXCMD_MOST_12		(5 << 4)
+#define	PCIXCMD_MOST_16		(6 << 4)
+#define	PCIXCMD_MOST_32		(7 << 4)
+#define	PCIXCMD_MOST_MASK	(7 << 4)
+#define	PCIXCMD_MMRBC_512	(0 << 2)
+#define	PCIXCMD_MMRBC_1024	(1 << 2)
+#define	PCIXCMD_MMRBC_2048	(2 << 2)
+#define	PCIXCMD_MMRBC_4096	(3 << 2)
+#define	PCIXCMD_MMRBC_MASK	(3 << 2)
+#define	PCIXCMD_ERO		(1U << 1)
+#define	PCIXCMD_DPERE		(1U << 0)
+
+#define	PCIXSR_RSCEM		(1U << 29)
+#define	PCIXSR_DMCRS_MASK	(7 << 26)
+#define	PCIXSR_DMOST_MASK	(7 << 23)
+#define	PCIXSR_COMPLEX		(1U << 20)
+#define	PCIXSR_USC		(1U << 19)
+#define	PCIXSR_SCD		(1U << 18)
+#define	PCIXSR_133_CAP		(1U << 17)
+#define	PCIXSR_32PCI		(1U << 16)	/* 0 = 32, 1 = 64 */
+#define	PCIXSR_BUSNO(x)		(((x) & 0xff00) >> 8)
+#define	PCIXSR_DEVNO(x)		(((x) & 0xf8) >> 3)
+#define	PCIXSR_FUNCNO(x)	((x) & 0x7)
+
+/*
+ * Memory Controller Unit
+ */
+#define	MCU_SDIR		0x00	/* DDR SDRAM Init. Register */
+#define	MCU_SDCR		0x04	/* DDR SDRAM Control Register */
+#define	MCU_SDBR		0x08	/* SDRAM Base Register */
+#define	MCU_SBR0		0x0c	/* SDRAM Boundary 0 */
+#define	MCU_SBR1		0x10	/* SDRAM Boundary 1 */
+#define	MCU_ECCR		0x34	/* ECC Control Register */
+#define	MCU_ELOG0		0x38	/* ECC Log 0 */
+#define	MCU_ELOG1		0x3c	/* ECC Log 1 */
+#define	MCU_ECAR0		0x40	/* ECC address 0 */
+#define	MCU_ECAR1		0x44	/* ECC address 1 */
+#define	MCU_ECTST		0x48	/* ECC test register */
+#define	MCU_MCISR		0x4c	/* MCU Interrupt Status Register */
+#define	MCU_RFR			0x50	/* Refresh Frequency Register */
+#define	MCU_DBUDSR		0x54	/* Data Bus Pull-up Drive Strength */
+#define	MCU_DBDDSR		0x58	/* Data Bus Pull-down Drive Strength */
+#define	MCU_CUDSR		0x5c	/* Clock Pull-up Drive Strength */
+#define	MCU_CDDSR		0x60	/* Clock Pull-down Drive Strength */
+#define	MCU_CEUDSR		0x64	/* Clock En Pull-up Drive Strength */
+#define	MCU_CEDDSR		0x68	/* Clock En Pull-down Drive Strength */
+#define	MCU_CSUDSR		0x6c	/* Chip Sel Pull-up Drive Strength */
+#define	MCU_CSDDSR		0x70	/* Chip Sel Pull-down Drive Strength */
+#define	MCU_REUDSR		0x74	/* Rx En Pull-up Drive Strength */
+#define	MCU_REDDSR		0x78	/* Rx En Pull-down Drive Strength */
+#define	MCU_ABUDSR		0x7c	/* Addr Bus Pull-up Drive Strength */
+#define	MCU_ABDDSR		0x80	/* Addr Bus Pull-down Drive Strength */
+#define	MCU_DSDR		0x84	/* Data Strobe Delay Register */
+#define	MCU_REDR		0x88	/* Rx Enable Delay Register */
+
+#define	SDCR_DIMMTYPE		(1U << 1)	/* 0 = unbuf, 1 = reg */
+#define	SDCR_BUSWIDTH		(1U << 2)	/* 0 = 64, 1 = 32 */
+
+#define	SBRx_TECH		(1U << 31)
+#define	SBRx_BOUND		0x0000003f
+
+#define	ECCR_SBERE		(1U << 0)
+#define	ECCR_MBERE		(1U << 1)
+#define	ECCR_SBECE		(1U << 2)
+#define	ECCR_ECCEN		(1U << 3)
+
+#define	ELOGx_SYNDROME		0x000000ff
+#define	ELOGx_ERRTYPE		(1U << 8)	/* 1 = multi-bit */
+#define	ELOGx_RW		(1U << 12)	/* 1 = write error */
+	/*
+	 * Dev ID	Func		Requester
+	 * 2		0		XScale core
+	 * 2		1		ATU
+	 * 13		0		DMA channel 0
+	 * 13		1		DMA channel 1
+	 * 26		0		ATU
+	 */
+#define	ELOGx_REQ_DEV(x)	(((x) >> 19) & 0x1f)
+#define	ELOGx_REQ_FUNC(x)	(((x) >> 16) & 0x3)
+
+#define	MCISR_ECC_ERR0		(1U << 0)
+#define	MCISR_ECC_ERR1		(1U << 1)
+#define	MCISR_ECC_ERRN		(1U << 2)
+
+/*
+ * Timers
+ *
+ * The i80321 timer registers are available in both memory-mapped
+ * and coprocessor spaces.  Most of the registers are read-only
+ * if memory-mapped, so we access them via coprocessor space.
+ *
+ *	TMR0	cp6 c0,1	0xffffe7e0
+ *	TMR1	cp6 c1,1	0xffffe7e4
+ *	TCR0	cp6 c2,1	0xffffe7e8
+ *	TCR1	cp6 c3,1	0xffffe7ec
+ *	TRR0	cp6 c4,1	0xffffe7f0
+ *	TRR1	cp6 c5,1	0xffffe7f4
+ *	TISR	cp6 c6,1	0xffffe7f8
+ *	WDTCR	cp6 c7,1	0xffffe7fc
+ */
+
+#define	TMRx_TC			(1U << 0)
+#define	TMRx_ENABLE		(1U << 1)
+#define	TMRx_RELOAD		(1U << 2)
+#define	TMRx_CSEL_CORE		(0 << 4)
+#define	TMRx_CSEL_CORE_div4	(1 << 4)
+#define	TMRx_CSEL_CORE_div8	(2 << 4)
+#define	TMRx_CSEL_CORE_div16	(3 << 4)
+
+#define	TISR_TMR0		(1U << 0)
+#define	TISR_TMR1		(1U << 1)
+
+#define	WDTCR_ENABLE1		0x1e1e1e1e
+#define	WDTCR_ENABLE2		0xe1e1e1e1
+
+/*
+ * Interrupt Controller Unit.
+ *
+ *	INTCTL	cp6 c0,0	0xffffe7d0
+ *	INTSTR	cp6 c4,0	0xffffe7d4
+ *	IINTSRC	cp6 c8,0	0xffffe7d8
+ *	FINTSRC	cp6 c9,0	0xffffe7dc
+ *	PIRSR			0xffffe1ec
+ */
+
+#define	ICU_PIRSR		0x01ec
+#define	ICU_GPOE		0x07c4
+#define	ICU_GPID		0x07c8
+#define	ICU_GPOD		0x07cc
+
+/*
+ * NOTE: WE USE THE `bitXX' BITS TO INDICATE PENDING SOFTWARE
+ * INTERRUPTS.  See i80321_icu.c
+ */
+#define	ICU_INT_HPI		31	/* high priority interrupt */
+#define	ICU_INT_XINT0		27	/* external interrupts */
+#define	ICU_INT_XINT(x)		((x) + ICU_INT_XINT0)
+#define	ICU_INT_bit26		26
+
+#if defined (CPU_XSCALE_80219)
+#define	ICU_INT_bit25		25	/* reserved */
+#else
+/* CPU_XSCALE_80321 */
+#define	ICU_INT_SSP		25	/* SSP serial port */
+#endif
+
+#define	ICU_INT_MUE		24	/* msg unit error */
+
+#if defined (CPU_XSCALE_80219)
+#define	ICU_INT_bit23		23	/* reserved */
+#else
+/* CPU_XSCALE_80321 */
+#define	ICU_INT_AAUE		23	/* AAU error */
+#endif
+
+#define	ICU_INT_bit22		22
+#define	ICU_INT_DMA1E		21	/* DMA Ch 1 error */
+#define	ICU_INT_DMA0E		20	/* DMA Ch 0 error */
+#define	ICU_INT_MCUE		19	/* memory controller error */
+#define	ICU_INT_ATUE		18	/* ATU error */
+#define	ICU_INT_BIUE		17	/* bus interface unit error */
+#define	ICU_INT_PMU		16	/* XScale PMU */
+#define	ICU_INT_PPM		15	/* peripheral PMU */
+#define	ICU_INT_BIST		14	/* ATU Start BIST */
+#define	ICU_INT_MU		13	/* messaging unit */
+#define	ICU_INT_I2C1		12	/* i2c unit 1 */
+#define	ICU_INT_I2C0		11	/* i2c unit 0 */
+#define	ICU_INT_TMR1		10	/* timer 1 */
+#define	ICU_INT_TMR0		9	/* timer 0 */
+#define	ICU_INT_CPPM		8	/* core processor PMU */
+
+#if defined(CPU_XSCALE_80219)
+#define	ICU_INT_bit7		7 /* reserved */
+#define	ICU_INT_bit6		6 /* reserved */
+#else
+/* CPU_XSCALE_80321 */
+#define	ICU_INT_AAU_EOC		7	/* AAU end-of-chain */
+#define	ICU_INT_AAU_EOT		6	/* AAU end-of-transfer */
+#endif
+
+#define	ICU_INT_bit5		5
+#define	ICU_INT_bit4		4
+#define	ICU_INT_DMA1_EOC	3	/* DMA1 end-of-chain */
+#define	ICU_INT_DMA1_EOT	2	/* DMA1 end-of-transfer */
+#define	ICU_INT_DMA0_EOC	1	/* DMA0 end-of-chain */
+#define	ICU_INT_DMA0_EOT	0	/* DMA0 end-of-transfer */
+
+#if defined (CPU_XSCALE_80219)
+#define	ICU_INT_HWMASK		(0xffffffff &	 \
+							 ~((1 << ICU_INT_bit26) |	\
+							   (1 << ICU_INT_bit25) |	\
+							   (1 << ICU_INT_bit23) |	\
+							   (1 << ICU_INT_bit22) |	\
+							   (1 << ICU_INT_bit7)  |	\
+							   (1 << ICU_INT_bit6)  |	\
+							   (1 << ICU_INT_bit5)  |	\
+							   (1 << ICU_INT_bit4)))
+
+#else
+/* CPU_XSCALE_80321 */
+#define	ICU_INT_HWMASK		(0xffffffff & \
+					~((1 << ICU_INT_bit26) | \
+					  (1 << ICU_INT_bit22) | \
+					  (1 << ICU_INT_bit5)  | \
+					  (1 << ICU_INT_bit4)))
+#endif
+
+/*
+ * SSP Serial Port
+ */
+#if defined (CPU_XSCALE_80321)
+
+#define	SSP_SSCR0	0x00		/* SSC control 0 */
+#define	SSP_SSCR1	0x04		/* SSC control 1 */
+#define	SSP_SSSR	0x08		/* SSP status */
+#define	SSP_SSITR	0x0c		/* SSP interrupt test */
+#define	SSP_SSDR	0x10		/* SSP data */
+
+#define	SSP_SSCR0_DSIZE(x)	((x) - 1)/* data size: 4..16 */
+#define	SSP_SSCR0_FRF_SPI	(0 << 4) /* Motorola Serial Periph Iface */
+#define	SSP_SSCR0_FRF_SSP	(1U << 4)/* TI Sync. Serial Protocol */
+#define	SSP_SSCR0_FRF_UWIRE	(2U << 4)/* NatSemi Microwire */
+#define	SSP_SSCR0_FRF_rsvd	(3U << 4)/* reserved */
+#define	SSP_SSCR0_ECS		(1U << 6)/* external clock select */
+#define	SSP_SSCR0_SSE		(1U << 7)/* sync. serial port enable */
+#define	SSP_SSCR0_SCR(x)	((x) << 8)/* serial clock rate */
+					  /* bit rate = 3.6864 * 10e6 /
+					        (2 * (SCR + 1)) */
+
+#define	SSP_SSCR1_RIE		(1U << 0)/* Rx FIFO interrupt enable */
+#define	SSP_SSCR1_TIE		(1U << 1)/* Tx FIFO interrupt enable */
+#define	SSP_SSCR1_LBM		(1U << 2)/* loopback mode enable */
+#define	SSP_SSCR1_SPO		(1U << 3)/* Moto SPI SSCLK pol. (1 = high) */
+#define	SSP_SSCR1_SPH		(1U << 4)/* Moto SPI SSCLK phase:
+					    0 = inactive full at start,
+						1/2 at end of frame
+					    1 = inactive 1/2 at start,
+						full at end of frame */
+#define	SSP_SSCR1_MWDS		(1U << 5)/* Microwire data size:
+					    0 = 8 bit
+					    1 = 16 bit */
+#define	SSP_SSCR1_TFT		(((x) - 1) << 6) /* Tx FIFO threshold */
+#define	SSP_SSCR1_RFT		(((x) - 1) << 10)/* Rx FIFO threshold */
+#define	SSP_SSCR1_EFWR		(1U << 14)/* enab. FIFO write/read */
+#define	SSP_SSCR1_STRF		(1U << 15)/* FIFO write/read FIFO select:
+					     0 = Tx FIFO
+					     1 = Rx FIFO */
+
+#define	SSP_SSSR_TNF		(1U << 2)/* Tx FIFO not full */
+#define	SSP_SSSR_RNE		(1U << 3)/* Rx FIFO not empty */
+#define	SSP_SSSR_BSY		(1U << 4)/* SSP is busy */
+#define	SSP_SSSR_TFS		(1U << 5)/* Tx FIFO service request */
+#define	SSP_SSSR_RFS		(1U << 6)/* Rx FIFO service request */
+#define	SSP_SSSR_ROR		(1U << 7)/* Rx FIFO overrun */
+#define	SSP_SSSR_TFL(x)		(((x) >> 8) & 0xf) /* Tx FIFO level */
+#define	SSP_SSSR_RFL(x)		(((x) >> 12) & 0xf)/* Rx FIFO level */
+
+#define	SSP_SSITR_TTFS		(1U << 5)/* Test Tx FIFO service */
+#define	SSP_SSITR_TRFS		(1U << 6)/* Test Rx FIFO service */
+#define	SSP_SSITR_TROR		(1U << 7)/* Test Rx overrun */
+
+#endif /* CPU_XSCALE_80321 */
+
+/*
+ * Peripheral Bus Interface Unit
+ */
+
+#define PBIU_PBCR		0x00	/* PBIU Control Register */
+#define PBIU_PBBAR0		0x08	/* PBIU Base Address Register 0 */
+#define PBIU_PBLR0		0x0c	/* PBIU Limit Register 0 */
+#define PBIU_PBBAR1		0x10	/* PBIU Base Address Register 1 */
+#define PBIU_PBLR1		0x14	/* PBIU Limit Register 1 */
+#define PBIU_PBBAR2		0x18	/* PBIU Base Address Register 2 */
+#define PBIU_PBLR2		0x1c	/* PBIU Limit Register 2 */
+#define PBIU_PBBAR3		0x20	/* PBIU Base Address Register 3 */
+#define PBIU_PBLR3		0x24	/* PBIU Limit Register 3 */
+#define PBIU_PBBAR4		0x28	/* PBIU Base Address Register 4 */
+#define PBIU_PBLR4		0x2c	/* PBIU Limit Register 4 */
+#define PBIU_PBBAR5		0x30	/* PBIU Base Address Register 5 */
+#define PBIU_PBLR5		0x34	/* PBIU Limit Register 5 */
+#define PBIU_DSCR		0x38	/* PBIU Drive Strength Control Reg. */
+#define PBIU_MBR0		0x40	/* PBIU Memory-less Boot Reg. 0 */
+#define PBIU_MBR1		0x60	/* PBIU Memory-less Boot Reg. 1 */
+#define PBIU_MBR2		0x64	/* PBIU Memory-less Boot Reg. 2 */
+
+#define	PBIU_PBCR_PBIEN		(1 << 0)
+#define	PBIU_PBCR_PBI100	(1 << 1)
+#define	PBIU_PBCR_PBI66		(2 << 1)
+#define	PBIU_PBCR_PBI33		(3 << 1)
+#define	PBIU_PBCR_PBBEN		(1 << 3)
+
+#define	PBIU_PBARx_WIDTH8	(0 << 0)
+#define	PBIU_PBARx_WIDTH16	(1 << 0)
+#define	PBIU_PBARx_WIDTH32	(2 << 0)
+#define	PBIU_PBARx_ADWAIT4	(0 << 2)
+#define	PBIU_PBARx_ADWAIT8	(1 << 2)
+#define	PBIU_PBARx_ADWAIT12	(2 << 2)
+#define	PBIU_PBARx_ADWAIT16	(3 << 2)
+#define	PBIU_PBARx_ADWAIT20	(4 << 2)
+#define	PBIU_PBARx_RCWAIT1	(0 << 6)
+#define	PBIU_PBARx_RCWAIT4	(1 << 6)
+#define	PBIU_PBARx_RCWAIT8	(2 << 6)
+#define	PBIU_PBARx_RCWAIT12	(3 << 6)
+#define	PBIU_PBARx_RCWAIT16	(4 << 6)
+#define	PBIU_PBARx_RCWAIT20	(5 << 6)
+#define	PBIU_PBARx_FWE		(1 << 9)
+#define	PBIU_BASE_MASK		0xfffff000U
+
+#define	PBIU_PBLRx_SIZE(x)	(~((x) - 1))
+
+/*
+ * Messaging Unit
+ */
+#define MU_IMR0			0x0010	/* MU Inbound Message Register 0 */
+#define MU_IMR1			0x0014	/* MU Inbound Message Register 1 */
+#define MU_OMR0			0x0018	/* MU Outbound Message Register 0 */
+#define MU_OMR1			0x001c	/* MU Outbound Message Register 1 */
+#define MU_IDR			0x0020	/* MU Inbound Doorbell Register */
+#define MU_IISR			0x0024	/* MU Inbound Interrupt Status Reg */
+#define MU_IIMR			0x0028	/* MU Inbound Interrupt Mask Reg */
+#define MU_ODR			0x002c	/* MU Outbound Doorbell Register */
+#define MU_OISR			0x0030	/* MU Outbound Interrupt Status Reg */
+#define MU_OIMR			0x0034	/* MU Outbound Interrupt Mask Reg */
+#define MU_MUCR			0x0050	/* MU Configuration Register */
+#define MU_QBAR			0x0054	/* MU Queue Base Address Register */
+#define MU_IFHPR		0x0060	/* MU Inbound Free Head Pointer Reg */
+#define MU_IFTPR		0x0064	/* MU Inbound Free Tail Pointer Reg */
+#define MU_IPHPR		0x0068	/* MU Inbound Post Head Pointer Reg */
+#define MU_IPTPR		0x006c	/* MU Inbound Post Tail Pointer Reg */
+#define MU_OFHPR		0x0070	/* MU Outbound Free Head Pointer Reg */
+#define MU_OFTPR		0x0074	/* MU Outbound Free Tail Pointer Reg */
+#define MU_OPHPR		0x0078	/* MU Outbound Post Head Pointer Reg */
+#define MU_OPTPR		0x007c	/* MU Outbound Post Tail Pointer Reg */
+#define MU_IAR			0x0080	/* MU Index Address Register */
+
+#define MU_IIMR_IRI	(1 << 6)	/* Index Register Interrupt */
+#define MU_IIMR_OFQFI	(1 << 5)	/* Outbound Free Queue Full Int. */
+#define MU_IIMR_IPQI	(1 << 4)	/* Inbound Post Queue Interrupt */
+#define MU_IIMR_EDI	(1 << 3)	/* Error Doorbell Interrupt */
+#define MU_IIMR_IDI	(1 << 2)	/* Inbound Doorbell Interrupt */
+#define MU_IIMR_IM1I	(1 << 1)	/* Inbound Message 1 Interrupt */
+#define MU_IIMR_IM0I	(1 << 0)	/* Inbound Message 0 Interrupt */
+
+#endif /* _ARM_XSCALE_I80321REG_H_ */


Property changes on: trunk/sys/arm/xscale/i80321/i80321reg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/i80321/i80321var.h
===================================================================
--- trunk/sys/arm/xscale/i80321/i80321var.h	                        (rev 0)
+++ trunk/sys/arm/xscale/i80321/i80321var.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,138 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: i80321var.h,v 1.8 2003/10/06 16:06:06 thorpej Exp $	*/
+
+/*-
+ * Copyright (c) 2002, 2003 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Jason R. Thorpe for Wasabi Systems, Inc.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed for the NetBSD Project by
+ *	Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
+ * 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: stable/10/sys/arm/xscale/i80321/i80321var.h 171628 2007-07-27 14:53:06Z cognet $
+ *
+ */
+
+#ifndef _ARM_XSCALE_I80321VAR_H_
+#define	_ARM_XSCALE_I80321VAR_H_
+
+#include <sys/queue.h>
+#include <dev/pci/pcivar.h>
+#include <sys/rman.h>
+
+extern struct bus_space i80321_bs_tag;
+
+struct i80321_softc {
+	device_t 		dev;
+	bus_space_tag_t 	sc_st;
+	bus_space_handle_t	sc_sh;
+	/* Handles for the various subregions. */
+	bus_space_handle_t 	sc_atu_sh;
+	bus_space_handle_t 	sc_mcu_sh;
+	int			sc_is_host;
+
+	/*
+	 * We expect the board-specific front-end to have already mapped
+	 * the PCI I/O space .. it is only 64K, and I/O mappings tend to
+	 * be smaller than a page size, so it's generally more efficient
+	 * to map them all into virtual space in one fell swoop.
+	 */
+	vm_offset_t		sc_iow_vaddr;		/* I/O window vaddr */
+
+	/*
+	 * Variables that define the Inbound windows.  The base address of
+	 * 0-2 are configured by a host via BARs.  The xlate variable
+	 * defines the start of the local address space that it maps to.
+	 * The size variable defines the byte size.
+	 *
+	 * The first 3 windows are for incoming PCI memory read/write
+	 * cycles from a host.  The 4th window, not configured by the
+	 * host (as it outside the normal BAR range) is the inbound
+	 * window for PCI devices controlled by the i80321.
+	 */
+	struct {
+		uint32_t iwin_base_hi;
+		uint32_t iwin_base_lo;
+		uint32_t iwin_xlate;
+		uint32_t iwin_size;
+	} sc_iwin[4];
+
+	/*
+	 * Variables that define the Outbound windows.
+	 */
+	struct {
+		uint32_t owin_xlate_lo;
+		uint32_t owin_xlate_hi;
+	} sc_owin[2];
+
+	/*
+	 * This is the PCI address that the Outbound I/O
+	 * window maps to.
+	 */
+	uint32_t		sc_ioout_xlate;
+
+	/* Bus space, DMA, and PCI tags for the PCI bus (private devices). */
+	struct bus_space 	sc_pci_iot;
+	struct bus_space 	sc_pci_memt;
+
+	/* GPIO state */
+	uint8_t sc_gpio_dir;    /* GPIO pin direction (1 == output) */
+	uint8_t sc_gpio_val;    /* GPIO output pin value */
+	struct rman sc_irq_rman;
+			
+};
+
+
+struct i80321_pci_softc {
+	device_t 		sc_dev;
+	bus_space_tag_t 	sc_st;
+	bus_space_handle_t 	sc_atu_sh;
+	bus_space_tag_t		sc_pciio;
+	bus_space_tag_t		sc_pcimem;
+	int			sc_busno;
+	struct rman		sc_mem_rman;
+	struct rman		sc_io_rman;
+	struct rman		sc_irq_rman;
+	uint32_t		sc_mem;
+	uint32_t		sc_io;
+};
+
+void	i80321_sdram_bounds(bus_space_tag_t, bus_space_handle_t,
+	    vm_paddr_t *, vm_size_t *);
+
+void	i80321_attach(struct i80321_softc *);
+void	i80321_calibrate_delay(void);
+
+void	i80321_bs_init(bus_space_tag_t, void *);
+void	i80321_io_bs_init(bus_space_tag_t, void *);
+void	i80321_mem_bs_init(bus_space_tag_t, void *);
+extern int machdep_pci_route_interrupt(device_t pcib, device_t dev, int pin);
+
+
+#endif /* _ARM_XSCALE_I80321VAR_H_ */


Property changes on: trunk/sys/arm/xscale/i80321/i80321var.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/i80321/iq31244_7seg.c
===================================================================
--- trunk/sys/arm/xscale/i80321/iq31244_7seg.c	                        (rev 0)
+++ trunk/sys/arm/xscale/i80321/iq31244_7seg.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,391 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: iq31244_7seg.c,v 1.2 2003/07/15 00:25:01 lukem Exp $	*/
+
+/*-
+ * Copyright (c) 2001, 2002, 2003 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Jason R. Thorpe for Wasabi Systems, Inc.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed for the NetBSD Project by
+ *	Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
+ * 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.
+ */
+
+/*
+ * Support for the 7-segment display on the Intel IQ31244.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/xscale/i80321/iq31244_7seg.c 236987 2012-06-13 04:38:09Z imp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/sysctl.h>
+
+#include <machine/bus.h>
+
+#include <arm/xscale/i80321/iq80321reg.h>
+#include <arm/xscale/i80321/iq80321var.h>
+
+#define	WRITE(x, v)	*((__volatile uint8_t *) (x)) = (v)
+
+static int snakestate;
+
+/*
+ * The 7-segment display looks like so:
+ *
+ *         A
+ *	+-----+
+ *	|     |
+ *    F	|     | B
+ *	|  G  |
+ *	+-----+
+ *	|     |
+ *    E	|     | C
+ *	|  D  |
+ *	+-----+ o  DP
+ *
+ * Setting a bit clears the corresponding segment on the
+ * display.
+ */
+#define	SEG_A			(1 << 0)
+#define	SEG_B			(1 << 1)
+#define	SEG_C			(1 << 2)
+#define	SEG_D			(1 << 3)
+#define	SEG_E			(1 << 4)
+#define	SEG_F			(1 << 5)
+#define	SEG_G			(1 << 6)
+#define	SEG_DP			(1 << 7)
+
+static const uint8_t digitmap[] = {
+/*	+#####+
+ *	#     #
+ *	#     #
+ *	#     #
+ *	+-----+
+ *	#     #
+ *	#     #
+ *	#     #
+ *	+#####+
+ */
+	SEG_G,
+
+/*	+-----+
+ *	|     #
+ *	|     #
+ *	|     #
+ *	+-----+
+ *	|     #
+ *	|     #
+ *	|     #
+ *	+-----+
+ */
+	SEG_A|SEG_D|SEG_E|SEG_F|SEG_G,
+
+/*	+#####+
+ *	|     #
+ *	|     #
+ *	|     #
+ *	+#####+
+ *	#     |
+ *	#     |
+ *	#     |
+ *	+#####+
+ */
+	SEG_C|SEG_F,
+
+/*	+#####+
+ *	|     #
+ *	|     #
+ *	|     #
+ *	+#####+
+ *	|     #
+ *	|     #
+ *	|     #
+ *	+#####+
+ */
+	SEG_E|SEG_F,
+
+/*	+-----+
+ *	#     #
+ *	#     #
+ *	#     #
+ *	+#####+
+ *	|     #
+ *	|     #
+ *	|     #
+ *	+-----+
+ */
+	SEG_A|SEG_D|SEG_E,
+
+/*	+#####+
+ *	#     |
+ *	#     |
+ *	#     |
+ *	+#####+
+ *	|     #
+ *	|     #
+ *	|     #
+ *	+#####+
+ */
+	SEG_B|SEG_E,
+
+/*	+#####+
+ *	#     |
+ *	#     |
+ *	#     |
+ *	+#####+
+ *	#     #
+ *	#     #
+ *	#     #
+ *	+#####+
+ */
+	SEG_B,
+
+/*	+#####+
+ *	|     #
+ *	|     #
+ *	|     #
+ *	+-----+
+ *	|     #
+ *	|     #
+ *	|     #
+ *	+-----+
+ */
+	SEG_D|SEG_E|SEG_F,
+
+/*	+#####+
+ *	#     #
+ *	#     #
+ *	#     #
+ *	+#####+
+ *	#     #
+ *	#     #
+ *	#     #
+ *	+#####+
+ */
+	0,
+
+/*	+#####+
+ *	#     #
+ *	#     #
+ *	#     #
+ *	+#####+
+ *	|     #
+ *	|     #
+ *	|     #
+ *	+-----+
+ */
+	SEG_D|SEG_E,
+};
+
+static uint8_t
+iq80321_7seg_xlate(char c)
+{
+	uint8_t rv;
+
+	if (c >= '0' && c <= '9')
+		rv = digitmap[c - '0'];
+	else if (c == '.')
+		rv = (uint8_t) ~SEG_DP;
+	else
+		rv = 0xff;
+
+	return (rv);
+}
+
+void
+iq80321_7seg(char a, char b)
+{
+	uint8_t msb, lsb;
+
+	msb = iq80321_7seg_xlate(a);
+	lsb = iq80321_7seg_xlate(b);
+
+	snakestate = 0;
+
+	WRITE(IQ80321_7SEG_MSB, msb);
+	WRITE(IQ80321_7SEG_LSB, lsb);
+}
+
+static const uint8_t snakemap[][2] = {
+
+/*	+#####+		+#####+
+ *	|     |		|     |
+ *	|     |		|     |
+ *	|     |		|     |
+ *	+-----+		+-----+
+ *	|     |		|     |
+ *	|     |		|     |
+ *	|     |		|     |
+ *	+-----+		+-----+
+ */
+	{ ~SEG_A,	~SEG_A },
+
+/*	+-----+		+-----+
+ *	#     |		|     #
+ *	#     |		|     #
+ *	#     |		|     #
+ *	+-----+		+-----+
+ *	|     |		|     |
+ *	|     |		|     |
+ *	|     |		|     |
+ *	+-----+		+-----+
+ */
+	{ ~SEG_F,	~SEG_B },
+
+/*	+-----+		+-----+
+ *	|     |		|     |
+ *	|     |		|     |
+ *	|     |		|     |
+ *	+#####+		+#####+
+ *	|     |		|     |
+ *	|     |		|     |
+ *	|     |		|     |
+ *	+-----+		+-----+
+ */
+	{ ~SEG_G,	~SEG_G },
+
+/*	+-----+		+-----+
+ *	|     |		|     |
+ *	|     |		|     |
+ *	|     |		|     |
+ *	+-----+		+-----+
+ *	|     #		#     |
+ *	|     #		#     |
+ *	|     #		#     |
+ *	+-----+		+-----+
+ */
+	{ ~SEG_C,	~SEG_E },
+
+/*	+-----+		+-----+
+ *	|     |		|     |
+ *	|     |		|     |
+ *	|     |		|     |
+ *	+-----+		+-----+
+ *	|     |		|     |
+ *	|     |		|     |
+ *	|     |		|     |
+ *	+#####+		+#####+
+ */
+	{ ~SEG_D,	~SEG_D },
+
+/*	+-----+		+-----+
+ *	|     |		|     |
+ *	|     |		|     |
+ *	|     |		|     |
+ *	+-----+		+-----+
+ *	#     |		|     #
+ *	#     |		|     #
+ *	#     |		|     #
+ *	+-----+		+-----+
+ */
+	{ ~SEG_E,	~SEG_C },
+
+/*	+-----+		+-----+
+ *	|     |		|     |
+ *	|     |		|     |
+ *	|     |		|     |
+ *	+#####+		+#####+
+ *	|     |		|     |
+ *	|     |		|     |
+ *	|     |		|     |
+ *	+-----+		+-----+
+ */
+	{ ~SEG_G,	~SEG_G },
+
+/*	+-----+		+-----+
+ *	|     #		#     |
+ *	|     #		#     |
+ *	|     #		#     |
+ *	+-----+		+-----+
+ *	|     |		|     |
+ *	|     |		|     |
+ *	|     |		|     |
+ *	+-----+		+-----+
+ */
+	{ ~SEG_B,	~SEG_F },
+};
+
+static SYSCTL_NODE(_hw, OID_AUTO, sevenseg, CTLFLAG_RD, 0, "7 seg");
+static int freq = 20;
+SYSCTL_INT(_hw_sevenseg, OID_AUTO, freq, CTLFLAG_RW, &freq, 0,
+    "7 Seg update frequency");
+static void
+iq31244_7seg_snake(void)
+{
+	static int snakefreq;
+	int cur = snakestate;
+
+	snakefreq++;
+	if ((snakefreq % freq))
+		return;
+	WRITE(IQ80321_7SEG_MSB, snakemap[cur][0]);
+	WRITE(IQ80321_7SEG_LSB, snakemap[cur][1]);
+
+	snakestate = (cur + 1) & 7;
+}
+
+struct iq31244_7seg_softc {
+	device_t	dev;
+};
+
+static int
+iq31244_7seg_probe(device_t dev)
+{
+
+	device_set_desc(dev, "IQ31244 7seg");
+	return (0);
+}
+
+extern void (*i80321_hardclock_hook)(void);
+static int
+iq31244_7seg_attach(device_t dev)
+{
+
+	i80321_hardclock_hook = iq31244_7seg_snake;
+	return (0);
+}
+
+static device_method_t iq31244_7seg_methods[] = {
+	DEVMETHOD(device_probe, iq31244_7seg_probe),
+	DEVMETHOD(device_attach, iq31244_7seg_attach),
+	{0, 0},
+};
+
+static driver_t iq31244_7seg_driver = {
+	"iqseg",
+	iq31244_7seg_methods,
+	sizeof(struct iq31244_7seg_softc),
+};
+static devclass_t iq31244_7seg_devclass;
+
+DRIVER_MODULE(iqseg, iq, iq31244_7seg_driver, iq31244_7seg_devclass, 0, 0);


Property changes on: trunk/sys/arm/xscale/i80321/iq31244_7seg.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/i80321/iq31244_machdep.c
===================================================================
--- trunk/sys/arm/xscale/i80321/iq31244_machdep.c	                        (rev 0)
+++ trunk/sys/arm/xscale/i80321/iq31244_machdep.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,411 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: hpc_machdep.c,v 1.70 2003/09/16 08:18:22 agc Exp $	*/
+
+/*-
+ * Copyright (c) 1994-1998 Mark Brinicombe.
+ * Copyright (c) 1994 Brini.
+ * All rights reserved.
+ *
+ * This code is derived from software written for Brini by Mark Brinicombe
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by Brini.
+ * 4. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BRINI ``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 BRINI 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.
+ *
+ * RiscBSD kernel project
+ *
+ * machdep.c
+ *
+ * Machine dependant functions for kernel setup
+ *
+ * This file needs a lot of work.
+ *
+ * Created      : 17/09/94
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/xscale/i80321/iq31244_machdep.c 278727 2015-02-13 22:32:02Z ian $");
+
+#define _ARM32_BUS_DMA_PRIVATE
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/sysproto.h>
+#include <sys/signalvar.h>
+#include <sys/imgact.h>
+#include <sys/kernel.h>
+#include <sys/ktr.h>
+#include <sys/linker.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/mutex.h>
+#include <sys/pcpu.h>
+#include <sys/proc.h>
+#include <sys/ptrace.h>
+#include <sys/cons.h>
+#include <sys/bio.h>
+#include <sys/bus.h>
+#include <sys/buf.h>
+#include <sys/exec.h>
+#include <sys/kdb.h>
+#include <sys/msgbuf.h>
+#include <machine/reg.h>
+#include <machine/cpu.h>
+#include <machine/physmem.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/vm_object.h>
+#include <vm/vm_page.h>
+#include <vm/vm_map.h>
+#include <machine/devmap.h>
+#include <machine/vmparam.h>
+#include <machine/pcb.h>
+#include <machine/undefined.h>
+#include <machine/machdep.h>
+#include <machine/metadata.h>
+#include <machine/armreg.h>
+#include <machine/bus.h>
+#include <sys/reboot.h>
+
+#include <arm/xscale/i80321/i80321reg.h>
+#include <arm/xscale/i80321/i80321var.h>
+#include <arm/xscale/i80321/iq80321reg.h>
+#include <arm/xscale/i80321/obiovar.h>
+
+#define	KERNEL_PT_SYS		0	/* Page table for mapping proc0 zero page */
+#define	KERNEL_PT_IOPXS		1
+#define	KERNEL_PT_BEFOREKERN	2
+#define	KERNEL_PT_AFKERNEL	3	/* L2 table for mapping after kernel */
+#define	KERNEL_PT_AFKERNEL_NUM	9
+
+/* this should be evenly divisable by PAGE_SIZE / L2_TABLE_SIZE_REAL (or 4) */
+#define NUM_KERNEL_PTS		(KERNEL_PT_AFKERNEL + KERNEL_PT_AFKERNEL_NUM)
+
+struct pv_addr kernel_pt_table[NUM_KERNEL_PTS];
+
+/* Physical and virtual addresses for some global pages */
+
+struct pv_addr systempage;
+struct pv_addr msgbufpv;
+struct pv_addr irqstack;
+struct pv_addr undstack;
+struct pv_addr abtstack;
+struct pv_addr kernelstack;
+struct pv_addr minidataclean;
+
+#define IQ80321_OBIO_BASE 0xfe800000UL
+#define IQ80321_OBIO_SIZE 0x00100000UL
+/* Static device mappings. */
+static const struct arm_devmap_entry iq80321_devmap[] = {
+	/*
+	 * Map the on-board devices VA == PA so that we can access them
+	 * with the MMU on or off.
+	 */
+	    {
+		    IQ80321_OBIO_BASE,
+		    IQ80321_OBIO_BASE,
+		    IQ80321_OBIO_SIZE,
+		    VM_PROT_READ|VM_PROT_WRITE,
+		    PTE_DEVICE,
+	    },
+	    {
+	    	    IQ80321_IOW_VBASE,
+		    VERDE_OUT_XLATE_IO_WIN0_BASE,
+		    VERDE_OUT_XLATE_IO_WIN_SIZE,
+		    VM_PROT_READ|VM_PROT_WRITE,
+		    PTE_DEVICE,
+	    },
+	
+	    {
+		    IQ80321_80321_VBASE,
+		    VERDE_PMMR_BASE,
+		    VERDE_PMMR_SIZE,
+		    VM_PROT_READ|VM_PROT_WRITE,
+		    PTE_DEVICE,
+	    },
+	    {
+		    0,
+		    0,
+		    0,
+		    0,
+		    0,
+	    }
+};
+
+#define SDRAM_START 0xa0000000
+
+extern vm_offset_t xscale_cache_clean_addr;
+
+void *
+initarm(struct arm_boot_params *abp)
+{
+	struct pv_addr  kernel_l1pt;
+	struct pv_addr  dpcpu;
+	int loop, i;
+	u_int l1pagetable;
+	vm_offset_t freemempos;
+	vm_offset_t freemem_pt;
+	vm_offset_t afterkern;
+	vm_offset_t freemem_after;
+	vm_offset_t lastaddr;
+	uint32_t memsize, memstart;
+
+	lastaddr = parse_boot_param(abp);
+	arm_physmem_kernaddr = abp->abp_physaddr;
+	set_cpufuncs();
+	pcpu_init(pcpup, 0, sizeof(struct pcpu));
+	PCPU_SET(curthread, &thread0);
+
+	/* Do basic tuning, hz etc */
+	init_param1();
+
+	freemempos = 0xa0200000;
+	/* Define a macro to simplify memory allocation */
+#define	valloc_pages(var, np)			\
+	alloc_pages((var).pv_pa, (np));		\
+	(var).pv_va = (var).pv_pa + 0x20000000;
+
+#define alloc_pages(var, np)			\
+	freemempos -= (np * PAGE_SIZE);		\
+	(var) = freemempos;		\
+	memset((char *)(var), 0, ((np) * PAGE_SIZE));
+
+	while (((freemempos - L1_TABLE_SIZE) & (L1_TABLE_SIZE - 1)) != 0)
+		freemempos -= PAGE_SIZE;
+	valloc_pages(kernel_l1pt, L1_TABLE_SIZE / PAGE_SIZE);
+	for (loop = 0; loop < NUM_KERNEL_PTS; ++loop) {
+		if (!(loop % (PAGE_SIZE / L2_TABLE_SIZE_REAL))) {
+			valloc_pages(kernel_pt_table[loop],
+			    L2_TABLE_SIZE / PAGE_SIZE);
+		} else {
+			kernel_pt_table[loop].pv_pa = freemempos +
+			    (loop % (PAGE_SIZE / L2_TABLE_SIZE_REAL)) *
+			    L2_TABLE_SIZE_REAL;
+			kernel_pt_table[loop].pv_va =
+			    kernel_pt_table[loop].pv_pa + 0x20000000;
+		}
+	}
+	freemem_pt = freemempos;
+	freemempos = 0xa0100000;
+	/*
+	 * Allocate a page for the system page mapped to V0x00000000
+	 * This page will just contain the system vectors and can be
+	 * shared by all processes.
+	 */
+	valloc_pages(systempage, 1);
+
+	/* Allocate dynamic per-cpu area. */
+	valloc_pages(dpcpu, DPCPU_SIZE / PAGE_SIZE);
+	dpcpu_init((void *)dpcpu.pv_va, 0);
+
+	/* Allocate stacks for all modes */
+	valloc_pages(irqstack, IRQ_STACK_SIZE);
+	valloc_pages(abtstack, ABT_STACK_SIZE);
+	valloc_pages(undstack, UND_STACK_SIZE);
+	valloc_pages(kernelstack, KSTACK_PAGES);
+	alloc_pages(minidataclean.pv_pa, 1);
+	valloc_pages(msgbufpv, round_page(msgbufsize) / PAGE_SIZE);
+	/*
+	 * Allocate memory for the l1 and l2 page tables. The scheme to avoid
+	 * wasting memory by allocating the l1pt on the first 16k memory was
+	 * taken from NetBSD rpc_machdep.c. NKPT should be greater than 12 for
+	 * this to work (which is supposed to be the case).
+	 */
+
+	/*
+	 * Now we start construction of the L1 page table
+	 * We start by mapping the L2 page tables into the L1.
+	 * This means that we can replace L1 mappings later on if necessary
+	 */
+	l1pagetable = kernel_l1pt.pv_va;
+
+	/* Map the L2 pages tables in the L1 page table */
+	pmap_link_l2pt(l1pagetable, ARM_VECTORS_HIGH & ~(0x00100000 - 1),
+	    &kernel_pt_table[KERNEL_PT_SYS]);
+	pmap_link_l2pt(l1pagetable, IQ80321_IOPXS_VBASE,
+	    &kernel_pt_table[KERNEL_PT_IOPXS]);
+	pmap_link_l2pt(l1pagetable, KERNBASE,
+	    &kernel_pt_table[KERNEL_PT_BEFOREKERN]);
+	pmap_map_chunk(l1pagetable, KERNBASE, SDRAM_START, 0x100000,
+	    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+	pmap_map_chunk(l1pagetable, KERNBASE + 0x100000, SDRAM_START + 0x100000,
+	    0x100000, VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE);
+	pmap_map_chunk(l1pagetable, KERNBASE + 0x200000, SDRAM_START + 0x200000,
+	    (((uint32_t)(lastaddr) - KERNBASE - 0x200000) + L1_S_SIZE) & ~(L1_S_SIZE - 1),
+	    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+	freemem_after = ((int)lastaddr + PAGE_SIZE) & ~(PAGE_SIZE - 1);
+	afterkern = round_page(((vm_offset_t)lastaddr + L1_S_SIZE) & ~(L1_S_SIZE
+	    - 1));
+	for (i = 0; i < KERNEL_PT_AFKERNEL_NUM; i++) {
+		pmap_link_l2pt(l1pagetable, afterkern + i * 0x00100000,
+		    &kernel_pt_table[KERNEL_PT_AFKERNEL + i]);
+	}
+	pmap_map_entry(l1pagetable, afterkern, minidataclean.pv_pa,
+	    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+	
+
+	/* Map the Mini-Data cache clean area. */
+	xscale_setup_minidata(l1pagetable, afterkern,
+	    minidataclean.pv_pa);
+
+	/* Map the vector page. */
+	pmap_map_entry(l1pagetable, ARM_VECTORS_HIGH, systempage.pv_pa,
+	    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+	arm_devmap_bootstrap(l1pagetable, iq80321_devmap);
+	/*
+	 * Give the XScale global cache clean code an appropriately
+	 * sized chunk of unmapped VA space starting at 0xff000000
+	 * (our device mappings end before this address).
+	 */
+	xscale_cache_clean_addr = 0xff000000U;
+
+	cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT);
+	setttb(kernel_l1pt.pv_pa);
+	cpu_tlb_flushID();
+	cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2));
+	/*
+	 * Pages were allocated during the secondary bootstrap for the
+	 * stacks for different CPU modes.
+	 * We must now set the r13 registers in the different CPU modes to
+	 * point to these stacks.
+	 * Since the ARM stacks use STMFD etc. we must set r13 to the top end
+	 * of the stack memory.
+	 */
+	set_stackptrs(0);
+
+	/*
+	 * We must now clean the cache again....
+	 * Cleaning may be done by reading new data to displace any
+	 * dirty data in the cache. This will have happened in setttb()
+	 * but since we are boot strapping the addresses used for the read
+	 * may have just been remapped and thus the cache could be out
+	 * of sync. A re-clean after the switch will cure this.
+	 * After booting there are no gross relocations of the kernel thus
+	 * this problem will not occur after initarm().
+	 */
+	cpu_idcache_wbinv_all();
+	cpu_setup("");
+
+	/*
+	 * Fetch the SDRAM start/size from the i80321 SDRAM configration
+	 * registers.
+	 */
+	i80321_calibrate_delay();
+	i80321_sdram_bounds(obio_bs_tag, IQ80321_80321_VBASE + VERDE_MCU_BASE,
+	    &memstart, &memsize);
+	physmem = memsize / PAGE_SIZE;
+	cninit();
+
+	undefined_init();
+				
+	init_proc0(kernelstack.pv_va);
+	
+	/* Enable MMU, I-cache, D-cache, write buffer. */
+
+	arm_vector_init(ARM_VECTORS_HIGH, ARM_VEC_ALL);
+	pmap_curmaxkvaddr = afterkern + PAGE_SIZE;
+	vm_max_kernel_address = 0xd0000000;
+	pmap_bootstrap(pmap_curmaxkvaddr, &kernel_l1pt);
+	msgbufp = (void*)msgbufpv.pv_va;
+	msgbufinit(msgbufp, msgbufsize);
+	mutex_init();
+	
+	/*
+	 * Add the physical ram we have available.
+	 *
+	 * Exclude the kernel (and all the things we allocated which immediately
+	 * follow the kernel) from the VM allocation pool but not from crash
+	 * dumps.  virtual_avail is a global variable which tracks the kva we've
+	 * "allocated" while setting up pmaps.
+	 *
+	 * Prepare the list of physical memory available to the vm subsystem.
+	 */
+	arm_physmem_hardware_region(SDRAM_START, memsize);
+	arm_physmem_exclude_region(abp->abp_physaddr, 
+	    virtual_avail - KERNVIRTADDR, EXFLAG_NOALLOC);
+	arm_physmem_init_kernel_globals();
+
+	init_param2(physmem);
+	kdb_init();
+	return ((void *)(kernelstack.pv_va + USPACE_SVC_STACK_TOP -
+	    sizeof(struct pcb)));
+}
+
+extern int
+machdep_pci_route_interrupt(device_t pcib, device_t dev, int pin)
+{
+	int bus;
+	int device;
+	int func;
+	uint32_t busno;
+	struct i80321_pci_softc *sc = device_get_softc(pcib);
+	bus = pci_get_bus(dev);
+	device = pci_get_slot(dev);
+	func = pci_get_function(dev);
+	busno = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_PCIXSR);
+	busno = PCIXSR_BUSNO(busno);
+	if (busno == 0xff)
+		busno = 0;
+	if (bus != busno)
+		goto no_mapping;
+	switch (device) {
+		/* IQ31244 PCI */
+	case 1: /* PCIX-PCIX bridge */
+		/*
+		 * The S-ATA chips are behind the bridge, and all of
+		 * the S-ATA interrupts are wired together.
+		 */
+		return (ICU_INT_XINT(2));
+	case 2: /* PCI slot */
+		/* All pins are wired together. */
+		return (ICU_INT_XINT(3));
+	case 3: /* i82546 dual Gig-E */
+		if (pin == 1 || pin == 2)
+			return (ICU_INT_XINT(0));
+		goto no_mapping;
+		/* IQ80321 PCI */
+	case 4: /* i82544 Gig-E */
+	case 8: /*
+		 * Apparently you can set the device for the ethernet adapter
+		 * to 8 with a jumper, so handle that as well
+		 */
+		if (pin == 1)
+			return (ICU_INT_XINT(0));
+		goto no_mapping;
+	case 6: /* S-PCI-X slot */
+		if (pin == 1)
+			return (ICU_INT_XINT(2));
+		if (pin == 2)
+			return (ICU_INT_XINT(3));
+		goto no_mapping;
+	default:
+no_mapping:
+		printf("No mapping for %d/%d/%d/%c\n", bus, device, func, pin);
+		
+	}
+	return (0);
+
+}


Property changes on: trunk/sys/arm/xscale/i80321/iq31244_machdep.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/i80321/iq80321.c
===================================================================
--- trunk/sys/arm/xscale/i80321/iq80321.c	                        (rev 0)
+++ trunk/sys/arm/xscale/i80321/iq80321.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,395 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: i80321_mainbus.c,v 1.13 2003/12/17 22:03:24 abs Exp $	*/
+
+/*-
+ * Copyright (c) 2001, 2002 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Jason R. Thorpe for Wasabi Systems, Inc.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed for the NetBSD Project by
+ *	Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
+ * 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.
+ */
+
+/*
+ * IQ80321 front-end for the i80321 I/O Processor.  We take care
+ * of setting up the i80321 memory map, PCI interrupt routing, etc.,
+ * which are all specific to the board the i80321 is wired up to.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/xscale/i80321/iq80321.c 278613 2015-02-12 03:50:33Z ian $");
+
+#define _ARM32_BUS_DMA_PRIVATE
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <machine/armreg.h>
+#include <machine/bus.h>
+#include <machine/intr.h>
+
+#include <arm/xscale/i80321/i80321reg.h>
+#include <arm/xscale/i80321/i80321var.h>
+#include <arm/xscale/i80321/iq80321reg.h>
+#include <arm/xscale/i80321/iq80321var.h>
+#include <arm/xscale/i80321/i80321_intr.h>
+
+#include <dev/pci/pcireg.h>
+
+
+int	iq80321_probe(device_t);
+void	iq80321_identify(driver_t *, device_t);
+int	iq80321_attach(device_t);
+
+int
+iq80321_probe(device_t dev)
+{
+	device_set_desc(dev, "Intel 80321");
+	return (BUS_PROBE_NOWILDCARD);
+}
+
+void
+iq80321_identify(driver_t *driver, device_t parent)
+{
+	
+	BUS_ADD_CHILD(parent, 0, "iq", 0);
+}
+
+static struct arm32_dma_range i80321_dr;
+static int dma_range_init = 0;
+
+struct arm32_dma_range *
+bus_dma_get_range(void)
+{
+	if (dma_range_init == 0)
+		return (NULL);
+	return (&i80321_dr);
+}
+
+int
+bus_dma_get_range_nb(void)
+{
+	if (dma_range_init == 0)
+		return (0);
+	return (1);
+}
+
+#define PCI_MAPREG_MEM_PREFETCHABLE_MASK	0x00000008
+#define PCI_MAPREG_MEM_TYPE_64BIT		0x00000004
+
+int
+iq80321_attach(device_t dev)
+{
+	struct i80321_softc *sc = device_get_softc(dev);
+	int b0u, b0l, b1u, b1l;
+	vm_paddr_t memstart = 0;
+	vm_size_t memsize = 0;
+	int busno;
+
+	/*
+	 * Fill in the space tag for the i80321's own devices,
+	 * and hand-craft the space handle for it (the device
+	 * was mapped during early bootstrap).
+	 */
+	i80321_bs_init(&i80321_bs_tag, sc);
+	sc->sc_st = &i80321_bs_tag;
+	sc->sc_sh = IQ80321_80321_VBASE;
+	sc->dev = dev;
+	sc->sc_is_host = 1;
+
+	/*
+	 * Slice off a subregion for the Memory Controller -- we need it
+	 * here in order read the memory size.
+	 */
+	if (bus_space_subregion(sc->sc_st, sc->sc_sh, VERDE_MCU_BASE,
+	    VERDE_MCU_SIZE, &sc->sc_mcu_sh))
+		panic("%s: unable to subregion MCU registers",
+		    device_get_name(dev));
+
+	if (bus_space_subregion(sc->sc_st, sc->sc_sh, VERDE_ATU_BASE,
+	    VERDE_ATU_SIZE, &sc->sc_atu_sh))
+		panic("%s: unable to subregion ATU registers",
+		    device_get_name(dev));
+
+	/*
+	 * We have mapped the PCI I/O windows in the early
+	 * bootstrap phase.
+	 */
+	sc->sc_iow_vaddr = IQ80321_IOW_VBASE;
+
+	/*
+	 * Check the configuration of the ATU to see if another BIOS
+	 * has configured us.  If a PC BIOS didn't configure us, then:
+	 * 	IQ80321: BAR0 00000000.0000000c BAR1 is 00000000.8000000c.
+	 * 	IQ31244: BAR0 00000000.00000004 BAR1 is 00000000.0000000c.
+	 * If a BIOS has configured us, at least one of those should be
+	 * different.  This is pretty fragile, but it's not clear what
+	 * would work better.
+	 */
+	b0l = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, PCIR_BARS+0x0);
+	b0u = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, PCIR_BARS+0x4);
+	b1l = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, PCIR_BARS+0x8);
+	b1u = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, PCIR_BARS+0xc);
+
+#ifdef VERBOSE_INIT_ARM	
+	printf("i80321: BAR0 = %08x.%08x BAR1 = %08x.%08x\n",
+		   b0l,b0u, b1l, b1u );
+#endif
+
+#define PCI_MAPREG_MEM_ADDR_MASK	0xfffffff0
+	b0l &= PCI_MAPREG_MEM_ADDR_MASK;
+	b0u &= PCI_MAPREG_MEM_ADDR_MASK;
+	b1l &= PCI_MAPREG_MEM_ADDR_MASK;
+	b1u &= PCI_MAPREG_MEM_ADDR_MASK;
+
+#ifdef VERBOSE_INIT_ARM	
+	printf("i80219: BAR0 = %08x.%08x BAR1 = %08x.%08x\n",
+		   b0l,b0u, b1l, b1u );
+#endif
+
+	if ((b0u != b1u) || (b0l != 0) || ((b1l & ~0x80000000U) != 0))
+		sc->sc_is_host = 0;
+	else
+		sc->sc_is_host = 1;
+
+	/* FIXME: i force it's */	
+
+#ifdef CPU_XSCALE_80219
+	sc->sc_is_host = 1;
+#endif
+	
+	i80321_sdram_bounds(sc->sc_st, sc->sc_mcu_sh, &memstart, &memsize);
+	/*
+	 * We set up the Inbound Windows as follows:
+	 *
+	 *	0	Access to i80321 PMMRs
+	 *
+	 *	1	Reserve space for private devices
+	 *
+	 *	2	RAM access
+	 *
+	 *	3	Unused.
+	 *
+	 * This chunk needs to be customized for each IOP321 application.
+	 */
+#if 0
+	sc->sc_iwin[0].iwin_base_lo = VERDE_PMMR_BASE;
+	sc->sc_iwin[0].iwin_base_hi = 0;
+	sc->sc_iwin[0].iwin_xlate = VERDE_PMMR_BASE;
+	sc->sc_iwin[0].iwin_size = VERDE_PMMR_SIZE;
+#endif
+	if (sc->sc_is_host) {
+		
+		/* Map PCI:Local 1:1. */
+		sc->sc_iwin[1].iwin_base_lo = VERDE_OUT_XLATE_MEM_WIN0_BASE |
+		    PCI_MAPREG_MEM_PREFETCHABLE_MASK |
+		    PCI_MAPREG_MEM_TYPE_64BIT;
+		sc->sc_iwin[1].iwin_base_hi = 0;
+	} else {
+		
+		sc->sc_iwin[1].iwin_base_lo = 0;
+		sc->sc_iwin[1].iwin_base_hi = 0;
+	}
+	sc->sc_iwin[1].iwin_xlate = VERDE_OUT_XLATE_MEM_WIN0_BASE;
+	sc->sc_iwin[1].iwin_size = VERDE_OUT_XLATE_MEM_WIN_SIZE;
+	
+	if (sc->sc_is_host) {
+		sc->sc_iwin[2].iwin_base_lo = memstart |
+		    PCI_MAPREG_MEM_PREFETCHABLE_MASK |
+		    PCI_MAPREG_MEM_TYPE_64BIT;
+		sc->sc_iwin[2].iwin_base_hi = 0;
+	} else {
+		sc->sc_iwin[2].iwin_base_lo = 0;
+		sc->sc_iwin[2].iwin_base_hi = 0;
+	}
+	sc->sc_iwin[2].iwin_xlate = memstart;
+	sc->sc_iwin[2].iwin_size = memsize;
+
+	if (sc->sc_is_host) {
+		sc->sc_iwin[3].iwin_base_lo = 0 |
+		    PCI_MAPREG_MEM_PREFETCHABLE_MASK |
+		    PCI_MAPREG_MEM_TYPE_64BIT;
+	} else {
+		sc->sc_iwin[3].iwin_base_lo = 0;
+	}
+	sc->sc_iwin[3].iwin_base_hi = 0;
+	sc->sc_iwin[3].iwin_xlate = 0;
+	sc->sc_iwin[3].iwin_size = 0;
+	
+#ifdef 	VERBOSE_INIT_ARM
+	printf("i80321: Reserve space for private devices (Inbound Window 1) \n hi:0x%08x lo:0x%08x xlate:0x%08x size:0x%08x\n",
+		   sc->sc_iwin[1].iwin_base_hi,
+		   sc->sc_iwin[1].iwin_base_lo,
+		   sc->sc_iwin[1].iwin_xlate,
+		   sc->sc_iwin[1].iwin_size
+		);
+	printf("i80321: RAM access (Inbound Window 2) \n hi:0x%08x lo:0x%08x xlate:0x%08x size:0x%08x\n",
+		   sc->sc_iwin[2].iwin_base_hi,
+		   sc->sc_iwin[2].iwin_base_lo,
+		   sc->sc_iwin[2].iwin_xlate,
+		   sc->sc_iwin[2].iwin_size
+		);
+#endif
+
+	/*
+	 * We set up the Outbound Windows as follows:
+	 *
+	 *	0	Access to private PCI space.
+	 *
+	 *	1	Unused.
+	 */
+#define PCI_MAPREG_MEM_ADDR(x) ((x) & 0xfffffff0)
+	sc->sc_owin[0].owin_xlate_lo =
+    	    PCI_MAPREG_MEM_ADDR(sc->sc_iwin[1].iwin_base_lo);
+	sc->sc_owin[0].owin_xlate_hi = sc->sc_iwin[1].iwin_base_hi;
+	/*
+	 * Set the Secondary Outbound I/O window to map
+	 * to PCI address 0 for all 64K of the I/O space.
+	 */
+	sc->sc_ioout_xlate = 0;
+	i80321_attach(sc);
+	i80321_dr.dr_sysbase = sc->sc_iwin[2].iwin_xlate;
+	i80321_dr.dr_busbase = PCI_MAPREG_MEM_ADDR(sc->sc_iwin[2].iwin_base_lo);
+	i80321_dr.dr_len = sc->sc_iwin[2].iwin_size;
+	dma_range_init = 1;
+	busno = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_PCIXSR);
+	busno = PCIXSR_BUSNO(busno);
+	if (busno == 0xff)
+		busno = 0;
+	sc->sc_irq_rman.rm_type = RMAN_ARRAY;
+	sc->sc_irq_rman.rm_descr = "i80321 IRQs";
+	if (rman_init(&sc->sc_irq_rman) != 0 ||
+	    rman_manage_region(&sc->sc_irq_rman, 0, 25) != 0)
+		panic("i80321_attach: failed to set up IRQ rman");
+
+	device_add_child(dev, "obio", 0);
+	device_add_child(dev, "itimer", 0);
+	device_add_child(dev, "iopwdog", 0);
+#ifndef 	CPU_XSCALE_80219
+	device_add_child(dev, "iqseg", 0);
+#endif	
+	device_add_child(dev, "pcib", busno);
+	device_add_child(dev, "i80321_dma", 0);
+	device_add_child(dev, "i80321_dma", 1);
+#ifndef CPU_XSCALE_80219	
+	device_add_child(dev, "i80321_aau", 0);
+#endif
+	bus_generic_probe(dev);
+	bus_generic_attach(dev);
+
+	return (0);
+}
+
+void
+arm_mask_irq(uintptr_t nb)
+{
+	intr_enabled &= ~(1 << nb);
+	i80321_set_intrmask();
+}
+
+void
+arm_unmask_irq(uintptr_t nb)
+{
+	intr_enabled |= (1 << nb);
+	i80321_set_intrmask();
+}
+
+
+void
+cpu_reset()
+{
+	(void) disable_interrupts(PSR_I|PSR_F);
+	*(__volatile uint32_t *)(IQ80321_80321_VBASE + VERDE_ATU_BASE +
+	    ATU_PCSR) = PCSR_RIB | PCSR_RPB;
+	printf("Reset failed!\n");
+	for(;;);
+}
+
+static struct resource *
+iq80321_alloc_resource(device_t dev, device_t child, int type, int *rid,
+    u_long start, u_long end, u_long count, u_int flags)
+{
+	struct i80321_softc *sc = device_get_softc(dev);
+	struct resource *rv;
+
+	if (type == SYS_RES_IRQ) {
+		rv = rman_reserve_resource(&sc->sc_irq_rman,
+		    start, end, count, flags, child);
+		if (rv != NULL)
+			rman_set_rid(rv, *rid);
+		return (rv);
+	}
+	return (NULL);
+}
+
+static int
+iq80321_setup_intr(device_t dev, device_t child,
+    struct resource *ires, int flags, driver_filter_t *filt,
+    driver_intr_t *intr, void *arg, void **cookiep)
+{
+	int error;
+
+	error = BUS_SETUP_INTR(device_get_parent(dev), child, ires, flags,
+	    filt, intr, arg, cookiep);
+	if (error)
+		return (error);
+	intr_enabled |= 1 << rman_get_start(ires);
+	i80321_set_intrmask();
+	
+	return (0);
+}
+
+static int
+iq80321_teardown_intr(device_t dev, device_t child, struct resource *res,
+    void *cookie)
+{
+	return (BUS_TEARDOWN_INTR(device_get_parent(dev), child, res, cookie));
+}
+
+static device_method_t iq80321_methods[] = {
+	DEVMETHOD(device_probe, iq80321_probe),
+	DEVMETHOD(device_attach, iq80321_attach),
+	DEVMETHOD(device_identify, iq80321_identify),
+	DEVMETHOD(bus_alloc_resource, iq80321_alloc_resource),
+	DEVMETHOD(bus_setup_intr, iq80321_setup_intr),
+	DEVMETHOD(bus_teardown_intr, iq80321_teardown_intr),
+	{0, 0},
+};
+
+static driver_t iq80321_driver = {
+	"iq",
+	iq80321_methods,
+	sizeof(struct i80321_softc),
+};
+static devclass_t iq80321_devclass;
+
+DRIVER_MODULE(iq, nexus, iq80321_driver, iq80321_devclass, 0, 0);


Property changes on: trunk/sys/arm/xscale/i80321/iq80321.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/i80321/iq80321reg.h
===================================================================
--- trunk/sys/arm/xscale/i80321/iq80321reg.h	                        (rev 0)
+++ trunk/sys/arm/xscale/i80321/iq80321reg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,112 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: iq80321reg.h,v 1.4 2003/05/14 19:46:39 thorpej Exp $	*/
+
+/*-
+ * Copyright (c) 2002 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Jason R. Thorpe for Wasabi Systems, Inc.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed for the NetBSD Project by
+ *	Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
+ * 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: stable/10/sys/arm/xscale/i80321/iq80321reg.h 161592 2006-08-24 23:51:28Z cognet $
+ *
+ */
+
+#ifndef _IQ80321REG_H_
+#define	_IQ80321REG_H_
+
+/*
+ * Memory map and register definitions for the Intel IQ80321
+ * Evaluation Board.
+ */
+
+/*
+ * The memory map of the IQ80321 looks like so:
+ *
+ *           ------------------------------
+ *		Intel 80321 IOP Reserved
+ * FFFF E900 ------------------------------
+ *		Peripheral Memory Mapped
+ *		    Registers
+ * FFFF E000 ------------------------------
+ *		On-board devices
+ * FE80 0000 ------------------------------
+ *		SDRAM
+ * A000 0000 ------------------------------
+ *		Reserved
+ * 9100 0000 ------------------------------
+ * 		Flash
+ * 9080 0000 ------------------------------
+ *		Reserved
+ * 9002 0000 ------------------------------
+ *		ATU Outbound Transaction
+ *		    Windows
+ * 8000 0000 ------------------------------
+ *		ATU Outbound Direct
+ *		    Addressing Windows
+ * 0000 1000 ------------------------------
+ *		Initialization Boot Code
+ *		    from Flash
+ * 0000 0000 ------------------------------
+ */
+
+/*
+ * We allocate a page table for VA 0xfe400000 (4MB) and map the
+ * PCI I/O space (64K) and i80321 memory-mapped registers (4K) there.
+ */
+#define	IQ80321_IOPXS_VBASE	0xfe400000UL
+#define	IQ80321_IOW_VBASE	IQ80321_IOPXS_VBASE
+#define	IQ80321_80321_VBASE	(IQ80321_IOW_VBASE +			\
+				 VERDE_OUT_XLATE_IO_WIN_SIZE)
+
+#define	IQ80321_SDRAM_START	0xa0000000
+/*
+ * The IQ80321 on-board devices are mapped VA==PA during bootstrap.
+ * Conveniently, the size of the on-board register space is 1 section
+ * mapping.
+ */
+#define	IQ80321_OBIO_BASE	0xfe800000UL
+#define	IQ80321_OBIO_SIZE	0x00100000UL	/* 1MB */
+
+#define	IQ80321_UART1		0xfe800000UL	/* TI 16550 */
+
+#if defined( CPU_XSCALE_80321 )
+#define	IQ80321_7SEG_MSB	0xfe840000UL
+#define	IQ80321_7SEG_LSB	0xfe850000UL
+
+#define	IQ80321_ROT_SWITCH	0xfe8d0000UL
+
+#define	IQ80321_BATTERY_STAT	0xfe8f0000UL
+#define	BATTERY_STAT_PRES	(1U << 0)
+#define	BATTERY_STAT_CHRG	(1U << 1)
+#define	BATTERY_STAT_DISCHRG	(1U << 2)
+#endif /* CPU_XSCALE_80321 */
+
+#endif /* _IQ80321REG_H_ */


Property changes on: trunk/sys/arm/xscale/i80321/iq80321reg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/i80321/iq80321var.h
===================================================================
--- trunk/sys/arm/xscale/i80321/iq80321var.h	                        (rev 0)
+++ trunk/sys/arm/xscale/i80321/iq80321var.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,54 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: iq80321var.h,v 1.1 2002/03/27 21:51:30 thorpej Exp $	*/
+
+/*-
+ * Copyright (c) 2002 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Jason R. Thorpe for Wasabi Systems, Inc.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed for the NetBSD Project by
+ *	Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
+ * 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: stable/10/sys/arm/xscale/i80321/iq80321var.h 139735 2005-01-05 21:58:49Z imp $
+ *
+ */
+
+#ifndef _IQ80321_IQ80321VAR_H_
+#define	_IQ80321_IQ80321VAR_H_
+
+#include <dev/pci/pcivar.h>
+
+void	iq80321_7seg(char, char);
+void	iq80321_7seg_snake(void);
+
+#if 0
+void	iq80321_pci_init(pci_chipset_tag_t, void *);
+#endif
+
+#endif /* _IQ80321_IQ80321VAR_H_ */


Property changes on: trunk/sys/arm/xscale/i80321/iq80321var.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/i80321/obio.c
===================================================================
--- trunk/sys/arm/xscale/i80321/obio.c	                        (rev 0)
+++ trunk/sys/arm/xscale/i80321/obio.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,164 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: obio.c,v 1.11 2003/07/15 00:25:05 lukem Exp $	*/
+
+/*-
+ * Copyright (c) 2001, 2002, 2003 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Jason R. Thorpe for Wasabi Systems, Inc.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed for the NetBSD Project by
+ *	Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
+ * 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.
+ */
+
+/*
+ * On-board device autoconfiguration support for Intel IQ80321
+ * evaluation boards.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/xscale/i80321/obio.c 278727 2015-02-13 22:32:02Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/rman.h>
+#include <sys/malloc.h>
+
+#include <machine/bus.h>
+
+#include <arm/xscale/i80321/i80321reg.h>
+
+#include <arm/xscale/i80321/iq80321reg.h>
+#include <arm/xscale/i80321/obiovar.h>
+
+bus_space_tag_t obio_bs_tag;
+
+int	obio_probe(device_t);
+int	obio_attach(device_t);
+
+int
+obio_probe(device_t dev)
+{
+	return (0);
+}
+
+int
+obio_attach(device_t dev)
+{
+	struct obio_softc *sc = device_get_softc(dev);
+
+	obio_bs_tag = arm_base_bs_tag;
+        sc->oba_st = obio_bs_tag;
+	sc->oba_addr = IQ80321_OBIO_BASE;
+	sc->oba_size = IQ80321_OBIO_SIZE;
+	sc->oba_rman.rm_type = RMAN_ARRAY;
+	sc->oba_rman.rm_descr = "OBIO I/O";
+	if (rman_init(&sc->oba_rman) != 0 ||
+	    rman_manage_region(&sc->oba_rman,
+	    sc->oba_addr, sc->oba_addr + sc->oba_size) != 0)
+		panic("obio_attach: failed to set up I/O rman");
+	sc->oba_irq_rman.rm_type = RMAN_ARRAY;
+	sc->oba_irq_rman.rm_descr = "OBIO IRQ";
+	if (rman_init(&sc->oba_irq_rman) != 0 ||
+	    rman_manage_region(&sc->oba_irq_rman, 28, 28) != 0)
+		panic("obio_attach: failed to set up IRQ rman");
+	device_add_child(dev, "uart", 0);
+	bus_generic_probe(dev);
+	bus_generic_attach(dev);
+	return (0);
+}
+
+static struct resource *
+obio_alloc_resource(device_t bus, device_t child, int type, int *rid,
+    u_long start, u_long end, u_long count, u_int flags)
+{
+	struct resource *rv;
+	struct rman *rm;
+	bus_space_tag_t bt = NULL;
+	bus_space_handle_t bh = 0;
+	struct obio_softc *sc = device_get_softc(bus);
+
+	switch (type) {
+	case SYS_RES_IRQ:
+		rm = &sc->oba_irq_rman;
+		break;
+	case SYS_RES_MEMORY:
+		return (NULL);
+	case SYS_RES_IOPORT:
+		rm = &sc->oba_rman;
+		bt = sc->oba_st;
+		bh = sc->oba_addr;
+		start = bh;
+		break;
+	default:
+		return (NULL);
+	}
+
+
+	rv = rman_reserve_resource(rm, start, end, count, flags, child);
+	if (rv == NULL)
+		return (NULL);
+	if (type == SYS_RES_IRQ)
+		return (rv);
+	rman_set_rid(rv, *rid);
+	rman_set_bustag(rv, bt);
+	rman_set_bushandle(rv, bh);
+	
+	return (rv);
+
+}
+
+static int
+obio_activate_resource(device_t bus, device_t child, int type, int rid,
+    struct resource *r)
+{
+	return (0);
+}
+static device_method_t obio_methods[] = {
+	DEVMETHOD(device_probe, obio_probe),
+	DEVMETHOD(device_attach, obio_attach),
+
+	DEVMETHOD(bus_alloc_resource, obio_alloc_resource),
+	DEVMETHOD(bus_activate_resource, obio_activate_resource),
+	DEVMETHOD(bus_setup_intr,	bus_generic_setup_intr),
+	DEVMETHOD(bus_teardown_intr,	bus_generic_teardown_intr),
+
+	{0, 0},
+};
+
+static driver_t obio_driver = {
+	"obio",
+	obio_methods,
+	sizeof(struct obio_softc),
+};
+static devclass_t obio_devclass;
+
+DRIVER_MODULE(obio, iq, obio_driver, obio_devclass, 0, 0);


Property changes on: trunk/sys/arm/xscale/i80321/obio.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/i80321/obiovar.h
===================================================================
--- trunk/sys/arm/xscale/i80321/obiovar.h	                        (rev 0)
+++ trunk/sys/arm/xscale/i80321/obiovar.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,59 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: obiovar.h,v 1.4 2003/06/16 17:40:53 thorpej Exp $	*/
+
+/*-
+ * Copyright (c) 2002, 2003 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Jason R. Thorpe for Wasabi Systems, Inc.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed for the NetBSD Project by
+ *	Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
+ * 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: stable/10/sys/arm/xscale/i80321/obiovar.h 278727 2015-02-13 22:32:02Z ian $
+ *
+ */
+
+#ifndef _IQ80321_OBIOVAR_H_
+#define	_IQ80321_OBIOVAR_H_
+
+#include <sys/rman.h>
+
+struct obio_softc {
+	bus_space_tag_t oba_st;		/* bus space tag */
+	bus_addr_t oba_addr;		/* address of device */
+	bus_size_t oba_size;		/* size of device */
+	int oba_width;			/* bus width */
+	int oba_irq;			/* XINT interrupt bit # */
+	struct rman oba_rman;
+	struct rman oba_irq_rman;
+	
+};
+extern bus_space_tag_t obio_bs_tag;
+
+#endif /* _IQ80321_OBIOVAR_H_ */


Property changes on: trunk/sys/arm/xscale/i80321/obiovar.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/i80321/std.ep80219
===================================================================
--- trunk/sys/arm/xscale/i80321/std.ep80219	                        (rev 0)
+++ trunk/sys/arm/xscale/i80321/std.ep80219	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,7 @@
+#EP80219 board configuration
+#$FreeBSD: stable/10/sys/arm/xscale/i80321/std.ep80219 161592 2006-08-24 23:51:28Z cognet $
+include	"../xscale/i80321/std.i80219"
+files		"../xscale/i80321/files.ep80219"
+makeoptions	KERNPHYSADDR=0xa0200000
+makeoptions	KERNVIRTADDR=0xc0200000
+options	COUNTS_PER_SEC=198000000


Property changes on: trunk/sys/arm/xscale/i80321/std.ep80219
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/xscale/i80321/std.i80219
===================================================================
--- trunk/sys/arm/xscale/i80321/std.i80219	                        (rev 0)
+++ trunk/sys/arm/xscale/i80321/std.i80219	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,5 @@
+#XScale i80219 generic configuration
+#$FreeBSD: stable/10/sys/arm/xscale/i80321/std.i80219 239362 2012-08-18 05:48:19Z andrew $
+files		"../xscale/i80321/files.i80219"
+include		"../xscale/std.xscale-be"
+cpu 		CPU_XSCALE_80219


Property changes on: trunk/sys/arm/xscale/i80321/std.i80219
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/xscale/i80321/std.i80321
===================================================================
--- trunk/sys/arm/xscale/i80321/std.i80321	                        (rev 0)
+++ trunk/sys/arm/xscale/i80321/std.i80321	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,5 @@
+#XScale i80321 generic configuration
+#$FreeBSD: stable/10/sys/arm/xscale/i80321/std.i80321 239362 2012-08-18 05:48:19Z andrew $
+files		"../xscale/i80321/files.i80321"
+include		"../xscale/std.xscale-be"
+cpu 		CPU_XSCALE_80321


Property changes on: trunk/sys/arm/xscale/i80321/std.i80321
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/xscale/i80321/std.iq31244
===================================================================
--- trunk/sys/arm/xscale/i80321/std.iq31244	                        (rev 0)
+++ trunk/sys/arm/xscale/i80321/std.iq31244	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,7 @@
+#IQ31244 board configuration
+#$FreeBSD: stable/10/sys/arm/xscale/i80321/std.iq31244 153277 2005-12-09 23:52:51Z cognet $
+include		"../xscale/i80321/std.i80321"
+files		"../xscale/i80321/files.iq31244"
+makeoptions	KERNPHYSADDR=0xa0200000
+makeoptions	KERNVIRTADDR=0xc0200000
+options		COUNTS_PER_SEC=198000000


Property changes on: trunk/sys/arm/xscale/i80321/std.iq31244
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/xscale/i80321/uart_bus_i80321.c
===================================================================
--- trunk/sys/arm/xscale/i80321/uart_bus_i80321.c	                        (rev 0)
+++ trunk/sys/arm/xscale/i80321/uart_bus_i80321.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,77 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2004 Olivier Houchard.  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 ``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 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: stable/10/sys/arm/xscale/i80321/uart_bus_i80321.c 139735 2005-01-05 21:58:49Z imp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
+#include <machine/resource.h>
+
+#include <dev/pci/pcivar.h>
+
+#include <dev/uart/uart.h>
+#include <dev/uart/uart_bus.h>
+#include <dev/uart/uart_cpu.h>
+
+#include "uart_if.h"
+
+static int uart_i80321_probe(device_t dev);
+
+static device_method_t uart_i80321_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		uart_i80321_probe),
+	DEVMETHOD(device_attach,	uart_bus_attach),
+	DEVMETHOD(device_detach,	uart_bus_detach),
+	{ 0, 0 }
+};
+
+static driver_t uart_i80321_driver = {
+	uart_driver_name,
+	uart_i80321_methods,
+	sizeof(struct uart_softc),
+};
+
+extern SLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs;
+static int
+uart_i80321_probe(device_t dev)
+{
+	struct uart_softc *sc;
+
+	sc = device_get_softc(dev);
+	sc->sc_sysdev = SLIST_FIRST(&uart_sysdevs);
+	sc->sc_class = &uart_ns8250_class;
+	bcopy(&sc->sc_sysdev->bas, &sc->sc_bas, sizeof(sc->sc_bas));
+	return(uart_bus_probe(dev, 0, 0, 0, 0));
+}
+
+
+DRIVER_MODULE(uart, obio, uart_i80321_driver, uart_devclass, 0, 0);


Property changes on: trunk/sys/arm/xscale/i80321/uart_bus_i80321.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/i80321/uart_cpu_i80321.c
===================================================================
--- trunk/sys/arm/xscale/i80321/uart_cpu_i80321.c	                        (rev 0)
+++ trunk/sys/arm/xscale/i80321/uart_cpu_i80321.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,68 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2003 Marcel Moolenaar
+ * 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 ``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 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: stable/10/sys/arm/xscale/i80321/uart_cpu_i80321.c 278727 2015-02-13 22:32:02Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/cons.h>
+#include <machine/bus.h>
+
+#include <dev/uart/uart.h>
+#include <dev/uart/uart_cpu.h>
+
+#include <arm/xscale/i80321/i80321var.h>
+#include <arm/xscale/i80321/obiovar.h>
+
+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)
+{
+	di->ops = uart_getops(&uart_ns8250_class);
+	di->bas.chan = 0;
+	di->bas.bst = obio_bs_tag;
+	di->bas.regshft = 0;
+	di->bas.rclk = 0;
+	di->baudrate = 115200;
+	di->databits = 8;
+	di->stopbits = 1;
+	di->parity = UART_PARITY_NONE;
+	uart_bus_space_io = obio_bs_tag;
+	uart_bus_space_mem = NULL;
+	di->bas.bsh = 0xfe800000;
+	return (0);
+}


Property changes on: trunk/sys/arm/xscale/i80321/uart_cpu_i80321.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/i8134x/crb_machdep.c
===================================================================
--- trunk/sys/arm/xscale/i8134x/crb_machdep.c	                        (rev 0)
+++ trunk/sys/arm/xscale/i8134x/crb_machdep.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,335 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: hpc_machdep.c,v 1.70 2003/09/16 08:18:22 agc Exp $	*/
+
+/*-
+ * Copyright (c) 1994-1998 Mark Brinicombe.
+ * Copyright (c) 1994 Brini.
+ * All rights reserved.
+ *
+ * This code is derived from software written for Brini by Mark Brinicombe
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by Brini.
+ * 4. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BRINI ``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 BRINI 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.
+ *
+ * RiscBSD kernel project
+ *
+ * machdep.c
+ *
+ * Machine dependant functions for kernel setup
+ *
+ * This file needs a lot of work.
+ *
+ * Created      : 17/09/94
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/xscale/i8134x/crb_machdep.c 278727 2015-02-13 22:32:02Z ian $");
+
+#define _ARM32_BUS_DMA_PRIVATE
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/sysproto.h>
+#include <sys/signalvar.h>
+#include <sys/imgact.h>
+#include <sys/kernel.h>
+#include <sys/ktr.h>
+#include <sys/linker.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/mutex.h>
+#include <sys/pcpu.h>
+#include <sys/proc.h>
+#include <sys/ptrace.h>
+#include <sys/cons.h>
+#include <sys/bio.h>
+#include <sys/bus.h>
+#include <sys/buf.h>
+#include <sys/exec.h>
+#include <sys/kdb.h>
+#include <sys/msgbuf.h>
+#include <machine/reg.h>
+#include <machine/cpu.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/vm_object.h>
+#include <vm/vm_page.h>
+#include <vm/vm_map.h>
+#include <machine/devmap.h>
+#include <machine/vmparam.h>
+#include <machine/pcb.h>
+#include <machine/undefined.h>
+#include <machine/machdep.h>
+#include <machine/metadata.h>
+#include <machine/armreg.h>
+#include <machine/bus.h>
+#include <machine/physmem.h>
+#include <sys/reboot.h>
+
+
+#include <arm/xscale/i80321/i80321var.h> /* For i80321_calibrate_delay() */
+
+#include <arm/xscale/i8134x/i81342reg.h>
+#include <arm/xscale/i8134x/i81342var.h>
+#include <arm/xscale/i8134x/obiovar.h>
+
+
+#define KERNEL_PT_SYS		0	/* Page table for mapping proc0 zero page */
+#define	KERNEL_PT_IOPXS		1
+#define KERNEL_PT_BEFOREKERN	2
+#define KERNEL_PT_AFKERNEL	3	/* L2 table for mapping after kernel */
+#define	KERNEL_PT_AFKERNEL_NUM	9
+
+/* this should be evenly divisable by PAGE_SIZE / L2_TABLE_SIZE_REAL (or 4) */
+#define NUM_KERNEL_PTS		(KERNEL_PT_AFKERNEL + KERNEL_PT_AFKERNEL_NUM)
+
+struct pv_addr kernel_pt_table[NUM_KERNEL_PTS];
+
+/* Physical and virtual addresses for some global pages */
+
+struct pv_addr systempage;
+struct pv_addr msgbufpv;
+struct pv_addr irqstack;
+struct pv_addr undstack;
+struct pv_addr abtstack;
+struct pv_addr kernelstack;
+
+/* Static device mappings. */
+static const struct arm_devmap_entry iq81342_devmap[] = {
+	    {
+		    IOP34X_VADDR,
+		    IOP34X_HWADDR,
+		    IOP34X_SIZE,
+		    VM_PROT_READ|VM_PROT_WRITE,
+		    PTE_DEVICE,
+	    },
+	    {
+		    /*
+		     * Cheat and map a whole section, this will bring
+		     * both PCI-X and PCI-E outbound I/O
+		     */
+		    IOP34X_PCIX_OIOBAR_VADDR &~ (0x100000 - 1),
+		    IOP34X_PCIX_OIOBAR &~ (0x100000 - 1),
+		    0x100000,
+		    VM_PROT_READ|VM_PROT_WRITE,
+		    PTE_DEVICE,
+	    },
+	    {
+		    IOP34X_PCE1_VADDR,
+		    IOP34X_PCE1,
+		    IOP34X_PCE1_SIZE,
+		    VM_PROT_READ|VM_PROT_WRITE,
+		    PTE_DEVICE,
+	    },
+	    {	
+		    0,
+		    0,
+		    0,
+		    0,
+		    0,
+	    }
+};
+
+#define SDRAM_START 0x00000000
+
+extern vm_offset_t xscale_cache_clean_addr;
+
+void *
+initarm(struct arm_boot_params *abp)
+{
+	struct pv_addr  kernel_l1pt;
+	struct pv_addr  dpcpu;
+	int loop, i;
+	u_int l1pagetable;
+	vm_offset_t freemempos;
+	vm_offset_t freemem_pt;
+	vm_offset_t afterkern;
+	vm_offset_t freemem_after;
+	vm_offset_t lastaddr;
+	uint32_t memsize, memstart;
+
+	lastaddr = parse_boot_param(abp);
+	arm_physmem_kernaddr = abp->abp_physaddr;
+	set_cpufuncs();
+	pcpu_init(pcpup, 0, sizeof(struct pcpu));
+	PCPU_SET(curthread, &thread0);
+
+	/* Do basic tuning, hz etc */
+	init_param1();
+
+	freemempos = 0x00200000;
+	/* Define a macro to simplify memory allocation */
+#define	valloc_pages(var, np)			\
+	alloc_pages((var).pv_pa, (np));		\
+	(var).pv_va = (var).pv_pa + 0xc0000000;
+
+#define alloc_pages(var, np)			\
+	freemempos -= (np * PAGE_SIZE);		\
+	(var) = freemempos;		\
+	memset((char *)(var), 0, ((np) * PAGE_SIZE));
+
+	while (((freemempos - L1_TABLE_SIZE) & (L1_TABLE_SIZE - 1)) != 0)
+		freemempos -= PAGE_SIZE;
+	valloc_pages(kernel_l1pt, L1_TABLE_SIZE / PAGE_SIZE);
+	for (loop = 0; loop < NUM_KERNEL_PTS; ++loop) {
+		if (!(loop % (PAGE_SIZE / L2_TABLE_SIZE_REAL))) {
+			valloc_pages(kernel_pt_table[loop],
+			    L2_TABLE_SIZE / PAGE_SIZE);
+		} else {
+			kernel_pt_table[loop].pv_pa = freemempos +
+			    (loop % (PAGE_SIZE / L2_TABLE_SIZE_REAL)) *
+			    L2_TABLE_SIZE_REAL;
+			kernel_pt_table[loop].pv_va =
+			    kernel_pt_table[loop].pv_pa + 0xc0000000;
+		}
+	}
+	freemem_pt = freemempos;
+	freemempos = 0x00100000;
+	/*
+	 * Allocate a page for the system page mapped to V0x00000000
+	 * This page will just contain the system vectors and can be
+	 * shared by all processes.
+	 */
+	valloc_pages(systempage, 1);
+
+	/* Allocate dynamic per-cpu area. */
+	valloc_pages(dpcpu, DPCPU_SIZE / PAGE_SIZE);
+	dpcpu_init((void *)dpcpu.pv_va, 0);
+
+	/* Allocate stacks for all modes */
+	valloc_pages(irqstack, IRQ_STACK_SIZE);
+	valloc_pages(abtstack, ABT_STACK_SIZE);
+	valloc_pages(undstack, UND_STACK_SIZE);
+	valloc_pages(kernelstack, KSTACK_PAGES);
+	valloc_pages(msgbufpv, round_page(msgbufsize) / PAGE_SIZE);
+	/*
+	 * Now we start construction of the L1 page table
+	 * We start by mapping the L2 page tables into the L1.
+	 * This means that we can replace L1 mappings later on if necessary
+	 */
+	l1pagetable = kernel_l1pt.pv_va;
+
+	/* Map the L2 pages tables in the L1 page table */
+	pmap_link_l2pt(l1pagetable, ARM_VECTORS_HIGH & ~(0x00100000 - 1),
+	    &kernel_pt_table[KERNEL_PT_SYS]);
+	pmap_map_chunk(l1pagetable, KERNBASE, SDRAM_START, 0x100000,
+	    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+
+	pmap_map_chunk(l1pagetable, KERNBASE + 0x100000, SDRAM_START + 0x100000,
+	    0x100000, VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE);
+
+	pmap_map_chunk(l1pagetable, KERNBASE + 0x200000, SDRAM_START + 0x200000,
+	   (((uint32_t)(lastaddr) - KERNBASE - 0x200000) + L1_S_SIZE) & ~(L1_S_SIZE - 1),
+	    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+	freemem_after = ((int)lastaddr + PAGE_SIZE) & ~(PAGE_SIZE - 1);
+	afterkern = round_page(((vm_offset_t)lastaddr + L1_S_SIZE) & ~(L1_S_SIZE
+	    - 1));
+	for (i = 0; i < KERNEL_PT_AFKERNEL_NUM; i++) {
+		pmap_link_l2pt(l1pagetable, afterkern + i * 0x00100000,
+		    &kernel_pt_table[KERNEL_PT_AFKERNEL + i]);
+	}
+	
+
+	/* Map the vector page. */
+	pmap_map_entry(l1pagetable, ARM_VECTORS_HIGH, systempage.pv_pa,
+	    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+	arm_devmap_bootstrap(l1pagetable, iq81342_devmap);
+	/*
+	 * Give the XScale global cache clean code an appropriately
+	 * sized chunk of unmapped VA space starting at 0xff000000
+	 * (our device mappings end before this address).
+	 */
+	xscale_cache_clean_addr = 0xff000000U;
+
+	cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT);
+	setttb(kernel_l1pt.pv_pa);
+	cpu_tlb_flushID();
+	cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2));
+	/*
+	 * Pages were allocated during the secondary bootstrap for the
+	 * stacks for different CPU modes.
+	 * We must now set the r13 registers in the different CPU modes to
+	 * point to these stacks.
+	 * Since the ARM stacks use STMFD etc. we must set r13 to the top end
+	 * of the stack memory.
+	 */
+
+	set_stackptrs(0);
+
+	/*
+	 * We must now clean the cache again....
+	 * Cleaning may be done by reading new data to displace any
+	 * dirty data in the cache. This will have happened in setttb()
+	 * but since we are boot strapping the addresses used for the read
+	 * may have just been remapped and thus the cache could be out
+	 * of sync. A re-clean after the switch will cure this.
+	 * After booting there are no gross relocations of the kernel thus
+	 * this problem will not occur after initarm().
+	 */
+	cpu_idcache_wbinv_all();
+	cpu_setup("");
+
+	i80321_calibrate_delay();
+	i81342_sdram_bounds(obio_bs_tag, IOP34X_VADDR, &memstart, &memsize);
+	physmem = memsize / PAGE_SIZE;
+	cninit();
+	/* Set stack for exception handlers */
+	
+	undefined_init();
+				
+	init_proc0(kernelstack.pv_va);
+	
+	arm_vector_init(ARM_VECTORS_HIGH, ARM_VEC_ALL);
+
+	pmap_curmaxkvaddr = afterkern + PAGE_SIZE;
+
+	vm_max_kernel_address = 0xd0000000;
+	pmap_bootstrap(pmap_curmaxkvaddr, &kernel_l1pt);
+	msgbufp = (void*)msgbufpv.pv_va;
+	msgbufinit(msgbufp, msgbufsize);
+	mutex_init();
+
+	/*
+	 * Add the physical ram we have available.
+	 *
+	 * Exclude the kernel (and all the things we allocated which immediately
+	 * follow the kernel) from the VM allocation pool but not from crash
+	 * dumps.  virtual_avail is a global variable which tracks the kva we've
+	 * "allocated" while setting up pmaps.
+	 *
+	 * Prepare the list of physical memory available to the vm subsystem.
+	 */
+	arm_physmem_hardware_region(SDRAM_START, memsize);
+	arm_physmem_exclude_region(abp->abp_physaddr, 
+	    virtual_avail - KERNVIRTADDR, EXFLAG_NOALLOC);
+	arm_physmem_init_kernel_globals();
+
+	init_param2(physmem);
+	kdb_init();
+	return ((void *)(kernelstack.pv_va + USPACE_SVC_STACK_TOP -
+	    sizeof(struct pcb)));
+}


Property changes on: trunk/sys/arm/xscale/i8134x/crb_machdep.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/i8134x/files.crb
===================================================================
--- trunk/sys/arm/xscale/i8134x/files.crb	                        (rev 0)
+++ trunk/sys/arm/xscale/i8134x/files.crb	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,3 @@
+# $FreeBSD: stable/10/sys/arm/xscale/i8134x/files.crb 172297 2007-09-22 16:25:43Z cognet $
+arm/xscale/i8134x/crb_machdep.c		standard
+arm/xscale/i8134x/iq81342_7seg.c	optional	7seg


Property changes on: trunk/sys/arm/xscale/i8134x/files.crb
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/xscale/i8134x/files.i81342
===================================================================
--- trunk/sys/arm/xscale/i8134x/files.i81342	                        (rev 0)
+++ trunk/sys/arm/xscale/i8134x/files.i81342	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,15 @@
+# $FreeBSD: stable/10/sys/arm/xscale/i8134x/files.i81342 278727 2015-02-13 22:32:02Z ian $
+arm/arm/bus_space_base.c		standard
+arm/arm/bus_space_generic.c		standard
+arm/arm/cpufunc_asm_xscale.S		standard
+arm/arm/cpufunc_asm_xscale_c3.S		standard
+arm/xscale/i80321/i80321_timer.c	standard
+arm/xscale/i80321/i80321_wdog.c		optional	iopwdog
+arm/xscale/i8134x/i81342.c		standard
+arm/xscale/i8134x/i81342_mcu.c		standard
+arm/xscale/i8134x/i81342_pci.c		optional	pci
+arm/xscale/i8134x/i81342_space.c	standard
+arm/xscale/i8134x/obio.c		standard
+arm/xscale/i8134x/uart_bus_i81342.c	optional	uart
+arm/xscale/i8134x/uart_cpu_i81342.c	optional	uart
+dev/uart/uart_dev_ns8250.c		optional	uart


Property changes on: trunk/sys/arm/xscale/i8134x/files.i81342
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/xscale/i8134x/i81342.c
===================================================================
--- trunk/sys/arm/xscale/i8134x/i81342.c	                        (rev 0)
+++ trunk/sys/arm/xscale/i8134x/i81342.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,467 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2006 Olivier Houchard
+ * 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 ``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
+ * 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: stable/10/sys/arm/xscale/i8134x/i81342.c 278613 2015-02-12 03:50:33Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+
+#define	_ARM32_BUS_DMA_PRIVATE
+#include <machine/armreg.h>
+#include <machine/bus.h>
+#include <machine/intr.h>
+
+#include <arm/xscale/i8134x/i81342reg.h>
+#include <arm/xscale/i8134x/i81342var.h>
+
+#define	WDTCR_ENABLE1		0x1e1e1e1e
+#define	WDTCR_ENABLE2		0xe1e1e1e1
+
+static volatile int intr_enabled0;
+static volatile int intr_enabled1;
+static volatile int intr_enabled2;
+static volatile int intr_enabled3;
+
+struct bus_space i81342_bs_tag;
+
+/* Read the interrupt pending register */
+
+static __inline
+uint32_t intpnd0_read(void)
+{
+	uint32_t ret;
+
+	__asm __volatile("mrc p6, 0, %0, c0, c3, 0"
+	    : "=r" (ret));
+	return (ret);
+}
+
+static __inline
+uint32_t intpnd1_read(void)
+{
+	uint32_t ret;
+
+	__asm __volatile("mrc p6, 0, %0, c1, c3, 0"
+	    : "=r" (ret));
+	return (ret);
+}
+
+static __inline
+uint32_t intpnd2_read(void)
+{
+	uint32_t ret;
+
+	__asm __volatile("mrc p6, 0, %0, c2, c3, 0"
+	    : "=r" (ret));
+	return (ret);
+}
+
+static __inline
+uint32_t intpnd3_read(void)
+{
+	uint32_t ret;
+
+	__asm __volatile("mrc p6, 0, %0, c3, c3, 0"
+	    : "=r" (ret));
+	return (ret);
+}
+
+/* Read the interrupt control register */
+/* 0 masked, 1 unmasked */
+static __inline
+uint32_t intctl0_read(void)
+{
+	uint32_t ret;
+
+	__asm __volatile("mrc p6, 0, %0, c0, c4, 0"
+	    : "=r" (ret));
+	return (ret);
+}
+
+static __inline
+uint32_t intctl1_read(void)
+{
+	uint32_t ret;
+
+	__asm __volatile("mrc p6, 0, %0, c1, c4, 0"
+	    : "=r" (ret));
+	return (ret);
+}
+
+static __inline
+uint32_t intctl2_read(void)
+{
+	uint32_t ret;
+
+	__asm __volatile("mrc p6, 0, %0, c2, c4, 0"
+	    : "=r" (ret));
+	return (ret);
+}
+
+static __inline
+uint32_t intctl3_read(void)
+{
+	uint32_t ret;
+
+	__asm __volatile("mrc p6, 0, %0, c3, c4, 0"
+	    : "=r" (ret));
+	return (ret);
+}
+
+/* Write the interrupt control register */
+
+static __inline
+void intctl0_write(uint32_t val)
+{
+
+	__asm __volatile("mcr p6, 0, %0, c0, c4, 0"
+	    : : "r" (val));
+}
+
+static __inline
+void intctl1_write(uint32_t val)
+{
+
+	__asm __volatile("mcr p6, 0, %0, c1, c4, 0"
+	    : : "r" (val));
+}
+
+static __inline
+void intctl2_write(uint32_t val)
+{
+
+	__asm __volatile("mcr p6, 0, %0, c2, c4, 0"
+	    : : "r" (val));
+}
+
+static __inline
+void intctl3_write(uint32_t val)
+{
+
+	__asm __volatile("mcr p6, 0, %0, c3, c4, 0"
+	    : : "r" (val));
+}
+
+/* Read the interrupt steering register */
+/* 0 IRQ 1 FIQ */
+static __inline
+uint32_t intstr0_read(void)
+{
+	uint32_t ret;
+
+	__asm __volatile("mrc p6, 0, %0, c0, c5, 0"
+	    : "=r" (ret));
+	return (ret);
+}
+
+static __inline
+uint32_t intstr1_read(void)
+{
+	uint32_t ret;
+
+	__asm __volatile("mrc p6, 0, %0, c1, c5, 0"
+	    : "=r" (ret));
+	return (ret);
+}
+
+static __inline
+uint32_t intstr2_read(void)
+{
+	uint32_t ret;
+
+	__asm __volatile("mrc p6, 0, %0, c2, c5, 0"
+	    : "=r" (ret));
+	return (ret);
+}
+
+static __inline
+uint32_t intstr3_read(void)
+{
+	uint32_t ret;
+
+	__asm __volatile("mrc p6, 0, %0, c3, c5, 0"
+	    : "=r" (ret));
+	return (ret);
+}
+
+/* Write the interrupt steering register */
+
+static __inline
+void intstr0_write(uint32_t val)
+{
+
+	__asm __volatile("mcr p6, 0, %0, c0, c5, 0"
+	    : : "r" (val));
+}
+
+static __inline
+void intstr1_write(uint32_t val)
+{
+
+	__asm __volatile("mcr p6, 0, %0, c1, c5, 0"
+	    : : "r" (val));
+}
+
+static __inline
+void intstr2_write(uint32_t val)
+{
+
+	__asm __volatile("mcr p6, 0, %0, c2, c5, 0"
+	    : : "r" (val));
+}
+
+static __inline
+void intstr3_write(uint32_t val)
+{
+
+	__asm __volatile("mcr p6, 0, %0, c3, c5, 0"
+	    : : "r" (val));
+}
+
+void
+cpu_reset(void)
+{
+
+	disable_interrupts(PSR_I);
+	/* XXX: Use the watchdog to reset for now */
+	__asm __volatile("mcr p6, 0, %0, c8, c9, 0\n"
+	    		 "mcr p6, 0, %1, c7, c9, 0\n"
+			 "mcr p6, 0, %2, c7, c9, 0\n"
+	    : : "r" (1), "r" (WDTCR_ENABLE1), "r" (WDTCR_ENABLE2));
+	while (1);
+}
+
+void
+arm_mask_irq(uintptr_t nb)
+{
+
+	if (nb < 32) {
+		intr_enabled0 &= ~(1 << nb);
+		intctl0_write(intr_enabled0);
+	} else if (nb < 64) {
+		intr_enabled1 &= ~(1 << (nb - 32));
+		intctl1_write(intr_enabled1);
+	} else if (nb < 96) {
+		intr_enabled2 &= ~(1 << (nb - 64));
+		intctl2_write(intr_enabled2);
+	} else {
+		intr_enabled3 &= ~(1 << (nb - 96));
+		intctl3_write(intr_enabled3);
+	}
+}
+
+void
+arm_unmask_irq(uintptr_t nb)
+{
+	if (nb < 32) {
+		intr_enabled0 |= (1 << nb);
+		intctl0_write(intr_enabled0);
+	} else if (nb < 64) {
+		intr_enabled1 |= (1 << (nb - 32));
+		intctl1_write(intr_enabled1);
+	} else if (nb < 96) {
+		intr_enabled2 |= (1 << (nb - 64));
+		intctl2_write(intr_enabled2);
+	} else {
+		intr_enabled3 |= (1 << (nb - 96));
+		intctl3_write(intr_enabled3);
+	}
+}
+
+int
+arm_get_next_irq(int last __unused)
+{
+	uint32_t val;
+	val = intpnd0_read() & intr_enabled0;
+	if (val)
+		return (ffs(val) - 1);
+	val = intpnd1_read() & intr_enabled1;
+	if (val)
+		return (32 + ffs(val) - 1);
+	val = intpnd2_read() & intr_enabled2;
+	if (val)
+		return (64 + ffs(val) - 1);
+	val = intpnd3_read() & intr_enabled3;
+	if (val)
+		return (96 + ffs(val) - 1);
+	return (-1);
+}
+
+int
+bus_dma_get_range_nb(void)
+{
+	return (0);
+}
+
+struct arm32_dma_range *
+bus_dma_get_range(void)
+{
+	return (NULL);
+}
+
+static int
+i81342_probe(device_t dev)
+{
+	unsigned int freq;
+
+	freq = *(volatile unsigned int *)(IOP34X_VADDR + IOP34X_PFR);
+
+	switch (freq & IOP34X_FREQ_MASK) {
+	case IOP34X_FREQ_600:
+		device_set_desc(dev, "Intel 81342 600MHz");
+		break;
+	case IOP34X_FREQ_667:
+		device_set_desc(dev, "Intel 81342 667MHz");
+		break;
+	case IOP34X_FREQ_800:
+		device_set_desc(dev, "Intel 81342 800MHz");
+		break;
+	case IOP34X_FREQ_833:
+		device_set_desc(dev, "Intel 81342 833MHz");
+		break;
+	case IOP34X_FREQ_1000:
+		device_set_desc(dev, "Intel 81342 1000MHz");
+		break;
+	case IOP34X_FREQ_1200:
+		device_set_desc(dev, "Intel 81342 1200MHz");
+		break;
+	default:
+		device_set_desc(dev, "Intel 81342 unknown frequency");
+		break;
+	}
+	return (0);
+}
+
+static void
+i81342_identify(driver_t *driver, device_t parent)
+{
+	
+	BUS_ADD_CHILD(parent, 0, "iq", 0);
+}
+
+static int
+i81342_attach(device_t dev)
+{
+	struct i81342_softc *sc = device_get_softc(dev);
+	uint32_t esstrsr;
+
+	i81342_bs_init(&i81342_bs_tag, sc);
+	sc->sc_st = &i81342_bs_tag;
+	sc->sc_sh = IOP34X_VADDR;
+	esstrsr = bus_space_read_4(sc->sc_st, sc->sc_sh, IOP34X_ESSTSR0);
+	sc->sc_atux_sh = IOP34X_ATUX_ADDR(esstrsr) - IOP34X_HWADDR +
+	    IOP34X_VADDR;
+	sc->sc_atue_sh = IOP34X_ATUE_ADDR(esstrsr) - IOP34X_HWADDR +
+	    IOP34X_VADDR;
+	/* Disable all interrupts. */
+	intctl0_write(0);
+	intctl1_write(0);
+	intctl2_write(0);
+	intctl3_write(0);
+	/* Defaults to IRQ */
+	intstr0_write(0);
+	intstr1_write(0);
+	intstr2_write(0);
+	intstr3_write(0);
+	sc->sc_irq_rman.rm_type = RMAN_ARRAY;
+	sc->sc_irq_rman.rm_descr = "i81342 IRQs";
+	if (rman_init(&sc->sc_irq_rman) != 0 ||
+	    rman_manage_region(&sc->sc_irq_rman, 0, 127) != 0)
+		panic("i81342_attach: failed to set up IRQ rman");
+
+	device_add_child(dev, "obio", 0);
+	device_add_child(dev, "itimer", 0);
+	device_add_child(dev, "iopwdog", 0);
+	device_add_child(dev, "pcib", 0);
+	device_add_child(dev, "pcib", 1);
+	device_add_child(dev, "iqseg", 0);
+	bus_generic_probe(dev);
+	bus_generic_attach(dev);
+	return (0);
+}
+
+static struct resource *
+i81342_alloc_resource(device_t dev, device_t child, int type, int *rid,
+    u_long start, u_long end, u_long count, u_int flags)
+{
+	struct i81342_softc *sc = device_get_softc(dev);
+	struct resource *rv;
+
+	if (type == SYS_RES_IRQ) {
+		rv = rman_reserve_resource(&sc->sc_irq_rman,
+		    start, end, count, flags, child);
+		if (rv != NULL)
+			rman_set_rid(rv, *rid);
+		return (rv);
+	}
+	
+	return (NULL);
+}
+
+static int
+i81342_setup_intr(device_t dev, device_t child, struct resource *ires,
+    int flags, driver_filter_t *filt, driver_intr_t *intr, void *arg,
+    void **cookiep)
+{
+	int error;
+
+	error = BUS_SETUP_INTR(device_get_parent(dev), child, ires, flags,
+	    filt, intr, arg, cookiep);
+	if (error)
+		return (error);
+	return (0);
+}
+
+static int
+i81342_teardown_intr(device_t dev, device_t child, struct resource *res,
+    void *cookie)
+{
+	return (BUS_TEARDOWN_INTR(device_get_parent(dev), child, res, cookie));
+}
+
+static device_method_t i81342_methods[] = {
+	DEVMETHOD(device_probe, i81342_probe),
+	DEVMETHOD(device_attach, i81342_attach),
+	DEVMETHOD(device_identify, i81342_identify),
+	DEVMETHOD(bus_alloc_resource, i81342_alloc_resource),
+	DEVMETHOD(bus_setup_intr, i81342_setup_intr),
+	DEVMETHOD(bus_teardown_intr, i81342_teardown_intr),
+	{0, 0},
+};
+
+static driver_t i81342_driver = {
+	"iq",
+	i81342_methods,
+	sizeof(struct i81342_softc),
+};
+static devclass_t i81342_devclass;
+
+DRIVER_MODULE(iq, nexus, i81342_driver, i81342_devclass, 0, 0);


Property changes on: trunk/sys/arm/xscale/i8134x/i81342.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/i8134x/i81342_mcu.c
===================================================================
--- trunk/sys/arm/xscale/i8134x/i81342_mcu.c	                        (rev 0)
+++ trunk/sys/arm/xscale/i8134x/i81342_mcu.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,57 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2006 Olivier Houchard
+ * 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 ``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
+ * 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: stable/10/sys/arm/xscale/i8134x/i81342_mcu.c 236987 2012-06-13 04:38:09Z imp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+
+#include <machine/bus.h>
+#include <arm/xscale/i8134x/i81342reg.h>
+#include <arm/xscale/i8134x/i81342var.h>
+
+void
+i81342_sdram_bounds(bus_space_tag_t bt, bus_space_handle_t bh,
+    vm_paddr_t *start, vm_size_t *size)
+{
+	uint32_t reg;
+	int bank_nb;
+
+	reg = bus_space_read_4(bt, bh, SMC_SDBR);
+	*start = (reg & SMC_SDBR_BASEADDR_MASK);
+	reg = bus_space_read_4(bt, bh, SMC_SBSR);
+	if (reg & SMC_SBSR_BANK_NB)
+		bank_nb = 1;
+	else
+		bank_nb = 2;
+	
+	*size = (reg & SMC_SBSR_BANK_SZ_MASK) * bank_nb;
+}


Property changes on: trunk/sys/arm/xscale/i8134x/i81342_mcu.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/i8134x/i81342_pci.c
===================================================================
--- trunk/sys/arm/xscale/i8134x/i81342_pci.c	                        (rev 0)
+++ trunk/sys/arm/xscale/i8134x/i81342_pci.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,545 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2006 Olivier Houchard
+ * 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 ``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
+ * 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: stable/10/sys/arm/xscale/i8134x/i81342_pci.c 259329 2013-12-13 20:43:11Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/types.h>
+#include <sys/rman.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/pcb.h>
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/vm_extern.h>
+
+#include <arm/xscale/i8134x/i81342reg.h>
+#include <arm/xscale/i8134x/i81342var.h>
+
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcib_private.h>
+#include "pcib_if.h"
+
+#include <dev/pci/pcireg.h>
+
+static pcib_read_config_t i81342_pci_read_config;
+static pcib_write_config_t i81342_pci_write_config;
+
+static int
+i81342_pci_probe(device_t dev)
+{
+	struct i81342_pci_softc *sc;
+	
+	sc = device_get_softc(dev);
+	if (device_get_unit(dev) == 0) {
+		device_set_desc(dev, "i81342 PCI-X bus");
+		sc->sc_is_atux = 1;
+	} else {
+		device_set_desc(dev, "i81342 PCIe bus");
+		sc->sc_is_atux = 0;
+	}
+	return (0);
+}
+
+#define PCI_MAPREG_MEM_PREFETCHABLE_MASK	0x00000008
+#define PCI_MAPREG_MEM_TYPE_64BIT		0x00000004
+
+static int
+i81342_pci_attach(device_t dev)
+{
+	struct i81342_softc *parent_sc;
+	struct i81342_pci_softc *sc;
+	uint32_t memsize, memstart;
+	uint32_t reg;
+	int func;
+	uint32_t busno;
+
+	sc = device_get_softc(dev);
+	parent_sc = device_get_softc(device_get_parent(dev));
+	sc->sc_atu_sh = sc->sc_is_atux ? parent_sc->sc_atux_sh :
+	    parent_sc->sc_atue_sh;
+	sc->sc_st = parent_sc->sc_st;
+	if (bus_space_read_4(sc->sc_st, parent_sc->sc_sh, IOP34X_ESSTSR0)
+	    & IOP34X_INT_SEL_PCIX) {
+		if (sc->sc_is_atux)
+			func = 5;
+		else
+			func = 0;
+	} else {
+		if (sc->sc_is_atux)
+			func = 0;
+		else
+			func = 5;
+	}
+	i81342_io_bs_init(&sc->sc_pciio, sc);
+	i81342_mem_bs_init(&sc->sc_pcimem, sc);
+	i81342_sdram_bounds(sc->sc_st, IOP34X_VADDR, &memstart, &memsize);
+	if (sc->sc_is_atux) {
+		reg = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_PCSR);
+		if (reg & ATUX_P_RSTOUT) {
+			bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_PCSR,
+			    reg &~ ATUX_P_RSTOUT);
+			DELAY(200);
+		}
+	}
+	/* Setup the Inbound windows. */
+	bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IABAR0, 0);
+	bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IAUBAR0, 0);
+	bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IALR0, 0);
+
+	/* Set the mapping Physical address <=> PCI address */
+	bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IABAR1,
+	    memstart | PCI_MAPREG_MEM_PREFETCHABLE_MASK |
+	    PCI_MAPREG_MEM_TYPE_64BIT);
+	bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IAUBAR1, 0);
+	bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IALR1, ~(memsize - 1)
+	     &~(0xfff));
+	bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IATVR1, memstart);
+	bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IAUTVR1, 0);
+
+	bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IABAR2, 0);
+	bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IAUBAR2, 0);
+	bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IALR2, 0);
+
+	/* Setup the Outbound IO Bar */
+	if (sc->sc_is_atux)
+		bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OIOBAR,
+		    (IOP34X_PCIX_OIOBAR >> 4) | func);
+	else
+		bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OIOBAR,
+		    (IOP34X_PCIE_OIOBAR >> 4) | func);
+
+	/* Setup the Outbound windows */
+	bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OUMBAR0, 0);
+	if (sc->sc_is_atux)
+		bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OUMBAR1,
+		    (IOP34X_PCIX_OMBAR >> 32) | (func << ATU_OUMBAR_FUNC) |
+		    ATU_OUMBAR_EN);
+	else
+		bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OUMBAR1,
+		    (IOP34X_PCIE_OMBAR >> 32) | (func << ATU_OUMBAR_FUNC) |
+		    ATU_OUMBAR_EN);
+	bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OUMWTVR1, 0);
+	bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OUMBAR2, 0);
+	bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OUMBAR3, 0);
+
+	/* Enable the outbound windows. */
+	reg = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_CR);
+	bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_CR,
+	    reg | ATU_CR_OUT_EN);
+	
+	bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_ISR,
+	    bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_ISR) & ATUX_ISR_ERRMSK);
+	/*
+	 * Enable bus mastering, memory access, SERR, and parity
+	 * checking on the ATU.
+	 */
+	if (sc->sc_is_atux) {
+		busno = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_PCIXSR);
+		busno = PCIXSR_BUSNO(busno);
+	} else {
+		busno = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_PCSR);
+		busno = PCIE_BUSNO(busno);
+	}
+	reg = bus_space_read_2(sc->sc_st, sc->sc_atu_sh, ATU_CMD);
+	reg |= PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN | PCIM_CMD_PERRESPEN |
+	    PCIM_CMD_SERRESPEN;
+	bus_space_write_2(sc->sc_st, sc->sc_atu_sh, ATU_CMD, reg);
+	sc->sc_busno = busno;
+	/* Initialize memory and i/o rmans. */
+	sc->sc_io_rman.rm_type = RMAN_ARRAY;
+	sc->sc_io_rman.rm_descr = "I81342 PCI I/O Ports";
+	if (rman_init(&sc->sc_io_rman) != 0 ||
+		rman_manage_region(&sc->sc_io_rman,
+		sc->sc_is_atux ? IOP34X_PCIX_OIOBAR_VADDR :
+		IOP34X_PCIE_OIOBAR_VADDR,
+		(sc->sc_is_atux ? IOP34X_PCIX_OIOBAR_VADDR :
+		IOP34X_PCIE_OIOBAR_VADDR) + IOP34X_OIOBAR_SIZE) != 0) {
+		panic("i81342_pci_probe: failed to set up I/O rman");
+	}
+	sc->sc_mem_rman.rm_type = RMAN_ARRAY;
+	sc->sc_mem_rman.rm_descr = "I81342 PCI Memory";
+	if (rman_init(&sc->sc_mem_rman) != 0 ||
+	    rman_manage_region(&sc->sc_mem_rman,
+	    0, 0xffffffff) != 0) {
+		panic("i81342_pci_attach: failed to set up memory rman");
+	}
+	sc->sc_irq_rman.rm_type = RMAN_ARRAY;
+	sc->sc_irq_rman.rm_descr = "i81342 PCI IRQs";
+	if (sc->sc_is_atux) {
+		if (rman_init(&sc->sc_irq_rman) != 0 ||
+		    rman_manage_region(&sc->sc_irq_rman, ICU_INT_XINT0,
+		    ICU_INT_XINT3) != 0)
+			panic("i83142_pci_attach: failed to set up IRQ rman");
+	} else {
+		if (rman_init(&sc->sc_irq_rman) != 0 ||
+		    rman_manage_region(&sc->sc_irq_rman, ICU_INT_ATUE_MA,
+		    ICU_INT_ATUE_MD) != 0)
+			panic("i81342_pci_attach: failed to set up IRQ rman");
+
+	}
+	bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_ISR,
+	    bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_ISR) & ATUX_ISR_ERRMSK);
+	device_add_child(dev, "pci", busno);
+	return (bus_generic_attach(dev));
+}
+
+static int
+i81342_pci_maxslots(device_t dev)
+{
+
+	return (PCI_SLOTMAX);
+}
+
+static void
+i81342_pci_conf_setup(struct i81342_pci_softc *sc, int bus, int slot, int func,
+    int reg, uint32_t *addr)
+{
+	uint32_t busno;
+
+	if (sc->sc_is_atux) {
+		busno = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_PCIXSR);
+		busno = PCIXSR_BUSNO(busno);
+	} else {
+		busno = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_PCSR);
+		busno = PCIE_BUSNO(busno);
+	}
+	bus &= 0xff;
+	slot &= 0x1f;
+	func &= 0x7;
+	if (sc->sc_is_atux) {
+		if (busno == bus)
+			*addr = (1 << (slot + 16)) | (slot << 11) |
+			    (func << 8) | reg;
+		else
+			*addr = (bus << 16) | (slot << 11) | (func << 11) |
+			    reg | 1;
+	} else {
+		*addr = (bus << 24) | (slot << 19) | (func << 16) | reg;
+		if (bus != busno)
+			*addr |= 1;
+	}
+}
+
+static u_int32_t
+i81342_pci_read_config(device_t dev, u_int bus, u_int slot, u_int func,
+    u_int reg, int bytes)
+{
+	struct i81342_pci_softc *sc = device_get_softc(dev);
+	uint32_t addr;
+	uint32_t ret = 0;
+	uint32_t isr;
+	int err = 0;
+	vm_offset_t va;
+
+	i81342_pci_conf_setup(sc, bus, slot, func, reg & ~3, &addr);
+	bus_space_write_4(sc->sc_st, sc->sc_atu_sh, sc->sc_is_atux ?
+	    ATUX_OCCAR : ATUE_OCCAR, addr);
+	if (sc->sc_is_atux)
+		va = sc->sc_atu_sh + ATUX_OCCDR;
+	else
+		va = sc->sc_atu_sh + ATUE_OCCDR;
+	switch (bytes) {
+	case 1:
+		err = badaddr_read((void*)(va + (reg & 3)), 1, &ret);
+		break;
+	case 2:
+		err = badaddr_read((void*)(va + (reg & 3)), 2, &ret);
+		break;
+	case 4:
+		err = badaddr_read((void *)(va) , 4, &ret);
+		break;
+	default:
+		printf("i81342_read_config: invalid size %d\n", bytes);
+		ret = -1;
+	}
+	if (err) {
+		isr = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_ISR);
+		if (sc->sc_is_atux)
+			isr &= ATUX_ISR_ERRMSK;
+		else
+			isr &= ATUE_ISR_ERRMSK;
+		bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_ISR, isr);
+		ret = -1;
+	}
+
+	return (ret);
+}
+
+static void
+i81342_pci_write_config(device_t dev, u_int bus, u_int slot, u_int func,
+    u_int reg, u_int32_t data, int bytes)
+{
+	struct i81342_pci_softc *sc = device_get_softc(dev);
+	uint32_t addr;
+	vm_offset_t va;
+
+	i81342_pci_conf_setup(sc, bus, slot, func, reg & ~3, &addr);
+	bus_space_write_4(sc->sc_st, sc->sc_atu_sh, sc->sc_is_atux ?
+	    ATUX_OCCAR : ATUE_OCCAR, addr);
+	va = sc->sc_is_atux ? ATUX_OCCDR : ATUE_OCCDR;
+		switch (bytes) {
+	case 1:
+		bus_space_write_1(sc->sc_st, sc->sc_atu_sh, va + (reg & 3)
+		    , data);
+		break;
+	case 2:
+		bus_space_write_2(sc->sc_st, sc->sc_atu_sh, va + (reg & 3)
+		    , data);
+		break;
+	case 4:
+		bus_space_write_4(sc->sc_st, sc->sc_atu_sh, va, data);
+		break;
+	default:
+		printf("i81342_pci_write_config: Invalid size : %d\n", bytes);
+	}
+
+
+}
+
+static struct resource *
+i81342_pci_alloc_resource(device_t bus, device_t child, int type, int *rid,
+   u_long start, u_long end, u_long count, u_int flags)
+{
+	struct i81342_pci_softc *sc = device_get_softc(bus);	
+	struct resource *rv;
+	struct rman *rm;
+	bus_space_tag_t bt = NULL;
+	bus_space_handle_t bh = 0;
+
+	switch (type) {
+	case SYS_RES_IRQ:
+		rm = &sc->sc_irq_rman;
+		break;
+	case SYS_RES_MEMORY:
+		rm = &sc->sc_mem_rman;
+		bt = &sc->sc_pcimem;
+		bh = 0;
+		break;
+	case SYS_RES_IOPORT:
+		rm = &sc->sc_io_rman;
+		bt = &sc->sc_pciio;
+		bh = sc->sc_is_atux ? IOP34X_PCIX_OIOBAR_VADDR :
+		    IOP34X_PCIE_OIOBAR_VADDR;
+		start += bh;
+		end += bh;
+		break;
+	default:
+		return (NULL);
+	}
+
+	rv = rman_reserve_resource(rm, start, end, count, flags, child);
+	if (rv == NULL)
+		return (NULL);
+	rman_set_rid(rv, *rid);
+	if (type != SYS_RES_IRQ) {
+		if (type == SYS_RES_MEMORY)
+			bh += (rman_get_start(rv));
+		rman_set_bustag(rv, bt);
+		rman_set_bushandle(rv, bh);
+		if (flags & RF_ACTIVE) {
+			if (bus_activate_resource(child, type, *rid, rv)) {
+				rman_release_resource(rv);
+				return (NULL);
+			}
+		}
+	}
+	return (rv);
+
+
+	return (NULL);
+}
+
+static int
+i81342_pci_activate_resource(device_t bus, device_t child, int type, int rid,
+    struct resource *r)
+{
+	u_long p;
+	int error;
+	
+	if (type == SYS_RES_MEMORY) {
+		error = bus_space_map(rman_get_bustag(r),
+		    rman_get_bushandle(r), rman_get_size(r), 0, &p);
+		if (error)
+			return (error);
+		rman_set_bushandle(r, p);
+	
+	}
+	return (rman_activate_resource(r));
+}
+
+static int
+i81342_pci_setup_intr(device_t dev, device_t child, struct resource *ires,
+    int flags, driver_filter_t *filt, driver_intr_t *intr, void *arg,
+    void **cookiep)
+{
+
+	return (BUS_SETUP_INTR(device_get_parent(dev), child, ires, flags,
+	    filt, intr, arg, cookiep));
+}
+
+
+
+static int
+i81342_pci_teardown_intr(device_t dev, device_t child, struct resource *res,
+    void *cookie)
+{
+	return (BUS_TEARDOWN_INTR(device_get_parent(dev), child, res, cookie));
+}
+
+static int
+i81342_pci_route_interrupt(device_t pcib, device_t dev, int pin)
+{
+	struct i81342_pci_softc *sc;
+	int device;
+	
+	device = pci_get_slot(dev);
+	sc = device_get_softc(pcib);
+	/* XXX: Is board specific */
+	if (sc->sc_is_atux) {
+		/* PCI-X */
+		switch(device) {
+		case 1:
+			switch (pin) {
+			case 1:
+				return (ICU_INT_XINT1);
+			case 2:
+				return (ICU_INT_XINT2);
+			case 3:
+				return (ICU_INT_XINT3);
+			case 4:
+				return (ICU_INT_XINT0);
+			default:
+				break;
+			}
+		case 2:
+			switch (pin) {
+			case 1:
+				return (ICU_INT_XINT2);
+			case 2:
+				return (ICU_INT_XINT3);
+			case 3:
+				return (ICU_INT_XINT2);
+			case 4:
+				return (ICU_INT_XINT3);
+			default:
+				break;
+			}
+		}
+		
+	} else {
+		switch (pin) {
+		case 1:
+			return (ICU_INT_ATUE_MA);
+		case 2:
+			return (ICU_INT_ATUE_MB);
+		case 3:
+			return (ICU_INT_ATUE_MC);
+		case 4:
+			return (ICU_INT_ATUE_MD);
+		default:
+			break;
+		}
+	}
+	printf("Warning: couldn't map %s IRQ for device %d pin %d\n",
+	    sc->sc_is_atux ? "PCI-X" : "PCIe", device, pin);
+	return (-1);
+}
+
+static int
+i81342_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
+{
+	struct i81342_pci_softc *sc = device_get_softc(dev);
+	switch (which) {
+	case PCIB_IVAR_DOMAIN:
+		*result = 0;
+		return (0);
+	case PCIB_IVAR_BUS:
+		*result = sc->sc_busno;
+		return (0);
+		
+	}
+	return (ENOENT);
+}
+
+static int
+i81342_write_ivar(device_t dev, device_t child, int which, uintptr_t result)
+{
+	struct i81342_pci_softc * sc = device_get_softc(dev);
+
+	switch (which) {
+	case PCIB_IVAR_DOMAIN:
+		return (EINVAL);
+	case PCIB_IVAR_BUS:
+		sc->sc_busno = result;
+		return (0);
+	}
+	return (ENOENT);
+}
+
+static device_method_t i81342_pci_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		i81342_pci_probe),
+	DEVMETHOD(device_attach,	i81342_pci_attach),
+	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
+	DEVMETHOD(device_suspend,	bus_generic_suspend),
+	DEVMETHOD(device_resume,	bus_generic_resume),
+
+	/* Bus interface */
+	DEVMETHOD(bus_read_ivar,	i81342_read_ivar),
+	DEVMETHOD(bus_write_ivar,	i81342_write_ivar),
+	DEVMETHOD(bus_alloc_resource,	i81342_pci_alloc_resource),
+	DEVMETHOD(bus_release_resource,	bus_generic_release_resource),
+	DEVMETHOD(bus_activate_resource, i81342_pci_activate_resource),
+	DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+	DEVMETHOD(bus_setup_intr,	i81342_pci_setup_intr),
+	DEVMETHOD(bus_teardown_intr,	i81342_pci_teardown_intr),
+
+	/* pcib interface */
+	DEVMETHOD(pcib_maxslots,	i81342_pci_maxslots),
+	DEVMETHOD(pcib_read_config,	i81342_pci_read_config),
+	DEVMETHOD(pcib_write_config,	i81342_pci_write_config),
+	DEVMETHOD(pcib_route_interrupt,	i81342_pci_route_interrupt),
+
+	DEVMETHOD_END
+};
+
+static driver_t i81342_pci_driver = {
+	"pcib",
+	i81342_pci_methods,
+	sizeof(struct i81342_pci_softc),
+};
+
+static devclass_t i81342_pci_devclass;
+
+DRIVER_MODULE(ipci, iq, i81342_pci_driver, i81342_pci_devclass, 0, 0);


Property changes on: trunk/sys/arm/xscale/i8134x/i81342_pci.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/i8134x/i81342_space.c
===================================================================
--- trunk/sys/arm/xscale/i8134x/i81342_space.c	                        (rev 0)
+++ trunk/sys/arm/xscale/i8134x/i81342_space.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,233 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: i80321_space.c,v 1.6 2003/10/06 15:43:35 thorpej Exp $	*/
+
+/*-
+ * Copyright (c) 2001, 2002 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Jason R. Thorpe for Wasabi Systems, Inc.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed for the NetBSD Project by
+ *	Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
+ * 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.
+ */
+
+/*
+ * bus_space functions for i81342 I/O Processor.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/xscale/i8134x/i81342_space.c 278727 2015-02-13 22:32:02Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/malloc.h>
+
+#include <machine/pcb.h>
+
+#include <vm/vm.h>
+#include <vm/vm_kern.h>
+#include <vm/pmap.h>
+#include <vm/vm_page.h>
+#include <vm/vm_extern.h>
+
+#include <machine/bus.h>
+
+#include <arm/xscale/i8134x/i81342reg.h>
+#include <arm/xscale/i8134x/i81342var.h>
+
+/* Prototypes for all the bus_space structure functions */
+bs_protos(i81342);
+bs_protos(i81342_io);
+bs_protos(i81342_mem);
+
+void
+i81342_bs_init(bus_space_tag_t bs, void *cookie)
+{
+
+	*bs = *arm_base_bs_tag;
+	bs->bs_privdata = cookie;
+}
+
+void
+i81342_io_bs_init(bus_space_tag_t bs, void *cookie)
+{
+
+	*bs = *arm_base_bs_tag;
+	bs->bs_privdata = cookie;
+
+	bs->bs_map = i81342_io_bs_map;
+	bs->bs_unmap = i81342_io_bs_unmap;
+	bs->bs_alloc = i81342_io_bs_alloc;
+	bs->bs_free = i81342_io_bs_free;
+
+}
+
+void
+i81342_mem_bs_init(bus_space_tag_t bs, void *cookie)
+{
+
+	*bs = *arm_base_bs_tag;
+	bs->bs_privdata = cookie;
+
+	bs->bs_map = i81342_mem_bs_map;
+	bs->bs_unmap = i81342_mem_bs_unmap;
+	bs->bs_alloc = i81342_mem_bs_alloc;
+	bs->bs_free = i81342_mem_bs_free;
+
+}
+
+/* *** Routines shared by i81342, PCI IO, and PCI MEM. *** */
+
+int
+i81342_bs_subregion(bus_space_tag_t tag, bus_space_handle_t bsh, bus_size_t offset,
+    bus_size_t size, bus_space_handle_t *nbshp)
+{
+
+	*nbshp = bsh + offset;
+	return (0);
+}
+
+void
+i81342_bs_barrier(bus_space_tag_t tag, bus_space_handle_t bsh, bus_size_t offset,
+    bus_size_t len, int flags)
+{
+
+	/* Nothing to do. */
+}
+
+/* *** Routines for PCI IO. *** */
+
+int
+i81342_io_bs_map(bus_space_tag_t tag, bus_addr_t bpa, bus_size_t size, int flags,
+    bus_space_handle_t *bshp)
+{
+
+	*bshp = bpa;
+	return (0);
+}
+
+void
+i81342_io_bs_unmap(bus_space_tag_t tag, bus_space_handle_t h, bus_size_t size)
+{
+
+	/* Nothing to do. */
+}
+
+int
+i81342_io_bs_alloc(bus_space_tag_t tag, bus_addr_t rstart, bus_addr_t rend,
+    bus_size_t size, bus_size_t alignment, bus_size_t boundary, int flags,
+    bus_addr_t *bpap, bus_space_handle_t *bshp)
+{
+
+	panic("i81342_io_bs_alloc(): not implemented");
+}
+
+void
+i81342_io_bs_free(bus_space_tag_t tag, bus_space_handle_t bsh, bus_size_t size)
+{
+
+	panic("i81342_io_bs_free(): not implemented");
+}
+
+
+/* *** Routines for PCI MEM. *** */
+extern int badaddr_read(void *, int, void *);
+static vm_offset_t allocable = 0xe1000000;
+int
+i81342_mem_bs_map(bus_space_tag_t tag, bus_addr_t bpa, bus_size_t size, int flags,
+    bus_space_handle_t *bshp)
+{
+	struct i81342_pci_softc *sc = (struct i81342_pci_softc *)tag->bs_privdata;
+	struct i81342_pci_map *tmp;
+	vm_offset_t addr, endaddr;
+	vm_paddr_t paddr;
+
+	/* Lookup to see if we already have a mapping at this address. */
+	tmp = sc->sc_pci_mappings;
+	while (tmp) {
+		if (tmp->paddr <= bpa && tmp->paddr + tmp->size >
+		    bpa + size) {
+			*bshp = bpa - tmp->paddr + tmp->vaddr;
+			return (0);
+		}
+		tmp = tmp->next;
+	}
+	addr = allocable;
+	endaddr = ((addr + size) &~ (0x1000000 - 1)) + 0x1000000;
+	if (endaddr >= IOP34X_VADDR)
+		panic("PCI virtual memory exhausted");
+	allocable = endaddr;
+	tmp = malloc(sizeof(*tmp), M_DEVBUF, M_WAITOK);
+	tmp->next = NULL;
+	paddr = bpa &~ (0x100000 - 1);
+	tmp->paddr = paddr;
+	tmp->vaddr = addr;
+	tmp->size = 0;
+	while (addr < endaddr) {
+		pmap_kenter_supersection(addr, paddr + (sc->sc_is_atux ?
+		    IOP34X_PCIX_OMBAR : IOP34X_PCIE_OMBAR), 0);
+		addr += 0x1000000;
+		paddr += 0x1000000;
+		tmp->size += 0x1000000;
+	}
+	tmp->next = sc->sc_pci_mappings;
+	sc->sc_pci_mappings = tmp;
+	*bshp = bpa - tmp->paddr + tmp->vaddr;
+	return (0);
+}
+
+void
+i81342_mem_bs_unmap(bus_space_tag_t tag, bus_space_handle_t h, bus_size_t size)
+{
+#if 0
+	vm_offset_t va, endva;
+
+	va = trunc_page((vm_offset_t)h);
+	endva = va + round_page(size);
+
+	/* Free the kernel virtual mapping. */
+	kva_free(va, endva - va);
+#endif
+}
+
+int
+i81342_mem_bs_alloc(bus_space_tag_t tag, bus_addr_t rstart, bus_addr_t rend,
+    bus_size_t size, bus_size_t alignment, bus_size_t boundary, int flags,
+    bus_addr_t *bpap, bus_space_handle_t *bshp)
+{
+
+	panic("i81342_mem_bs_alloc(): not implemented");
+}
+
+void
+i81342_mem_bs_free(bus_space_tag_t tag, bus_space_handle_t bsh, bus_size_t size)
+{
+
+	panic("i81342_mem_bs_free(): not implemented");
+}


Property changes on: trunk/sys/arm/xscale/i8134x/i81342_space.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/i8134x/i81342reg.h
===================================================================
--- trunk/sys/arm/xscale/i8134x/i81342reg.h	                        (rev 0)
+++ trunk/sys/arm/xscale/i8134x/i81342reg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,349 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2006 Olivier Houchard
+ * 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 ``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
+ * 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: stable/10/sys/arm/xscale/i8134x/i81342reg.h 261455 2014-02-04 03:36:42Z eadler $ */
+
+#ifndef I83142_REG_H_
+#define I83142_REG_H_
+/* Physical Memory Map */
+/*
+ * 0x000000000 - 0x07FFFFFFF SDRAM
+ * 0x090100000 - 0x0901FFFFF ATUe Outbound IO Window
+ * 0x0F0000000 - 0x0F1FFFFFF Flash
+ * 0x0F2000000 - 0x0F20FFFFF PCE1
+ * 0x0F3000000 - 0x0FFCFFFFF Compact Flash
+ * 0x0FFD00000 - 0x0FFDFFFFF MMR
+ * 0x0FFFB0000 - 0x0FFFBFFFF ATU-X Outbound I/O Window
+ * 0x0FFFD0000 - 0x0FFFDFFFF ATUe Outbound I/O Window
+ * 0x100000000 - 0x1FFFFFFFF ATU-X outbound Memory Translation Window
+ * 0x2FF000000 - 0x2FFFFFFFF ATUe Outbound Memory Translation Window
+ */
+
+#define IOP34X_VADDR		0xf0000000
+#define IOP34X_HWADDR		0xffd00000
+#define IOP34X_SIZE		0x100000
+
+#define IOP34X_ADMA0_OFFSET	0x00080000
+#define IOP34X_ADMA1_OFFSET	0x00080200
+#define IOP34X_ADMA2_OFFSET	0x00080400
+#define IOP34X_ADMA_SIZE	0x200
+
+
+/* ADMA Registers */
+#define IOP34X_ADMA_CCR		0x0000 /* Channel Control Register */
+#define IOP34X_ADMA_CSR		0x0004 /* Channel Status Register */
+#define IOP34X_ADMA_DAR		0x0008 /* Descriptor Address Register */
+#define IOP34X_ADMA_IPCR	0x0018 /* Internal Interface Parity Ctrl Reg */
+#define IOP34X_ADMA_NDAR	0x0024 /* Next Descriptor Register */
+#define IOP34X_ADMA_DCR		0x0028 /* Descriptor Control Register */
+
+#define	IOP34X_ADMA_IE		(1 << 0) /* Interrupt enable */
+#define IOP34X_ADMA_TR		(1 << 1) /* Transfert Direction */
+/*
+ *               Source                   Destination
+ *  00         Host I/O Interface	Local Memory
+ *  01         Local Memory             Host I/O Interface
+ *  10         Internal Bus             Local Memory
+ *  11         Local Memory             Internal Bus
+ */
+#define IOP34X_ADMA_SS		(1 << 3) /* Source selection */
+/* 0000: Data Transfer / CRC / Memory Block Fill */
+#define IOP34X_ADMA_ZRBCE	(1 << 7) /* Zero Result Buffer Check Enable */
+#define IOP34X_ADMA_MBFE	(1 << 8) /* Memory Block Fill Enable */
+#define IOP34X_ADMA_CGE		(1 << 9) /* CRC Generation enable */
+#define IOP34X_ADMA_CTD		(1 << 10) /* CRC Transfer disable */
+#define IOP34X_ADMA_CSFD	(1 << 11) /* CRC Seed fetch disable */
+#define IOP34X_ADMA_SWBE	(1 << 12) /* Status write back enable */
+#define IOP34X_ADMA_ESE		(1 << 13) /* Endian swap enable */
+#define IOP34X_ADMA_PQUTE	(1 << 16) /* P+Q Update Transfer Enable */
+#define IOP34X_ADMA_DXE		(1 << 17) /* Dual XOR Enable */
+#define IOP34X_ADMA_PQTE	(1 << 18) /* P+Q Transfer Enable */
+#define IOP34X_ADMA_PTD		(1 << 19) /* P Transfer Disable */
+#define IOP34X_ADMA_ROE		(1 << 30) /* Relaxed Ordering Enable */
+#define IOP34X_ADMA_NSE		(1U << 31) /* No Snoop Enable */
+
+#define IOP34X_PBBAR0		0x81588 /* PBI Base Address Register 0 */
+#define IOP34X_PBBAR0_ADDRMASK	0xfffff000
+#define IOP34X_PBBAR1		0x81590
+#define IOP34X_PCE1		0xF2000000
+#define IOP34X_PCE1_SIZE	0x00100000
+#define IOP34X_PCE1_VADDR	0xF1000000
+#define IOP34X_ESSTSR0		0x82188
+#define IOP34X_CONTROLLER_ONLY	(1 << 14)
+#define IOP34X_INT_SEL_PCIX	(1 << 15)
+#define IOP34X_PFR		0x82180 /* Processor Frequency Register */
+#define IOP34X_FREQ_MASK	((1 << 16) | (1 << 17) | (1 << 18))
+#define IOP34X_FREQ_600		(0)
+#define IOP34X_FREQ_667		(1 << 16)
+#define IOP34X_FREQ_800		(1 << 17)
+#define IOP34X_FREQ_833		((1 << 17) | (1 << 16))
+#define IOP34X_FREQ_1000	(1 << 18)
+#define IOP34X_FREQ_1200	((1 << 16) | (1 << 18))
+
+#define IOP34X_UART0_VADDR	IOP34X_VADDR + 0x82300
+#define IOP34X_UART0_HWADDR	IOP34X_HWADDR + 0x82300
+#define IOP34X_UART1_VADDR	IOP34X_VADDR + 0x82340
+#define IOP34X_UART1_HWADDR	IOP34X_HWADDR + 0x82340
+#define IOP34X_PBI_HWADDR	0xffd81580
+
+/* SDRAM Memory Controller */
+#define SMC_SDBR		0x8180c /* Base Register */
+#define SMC_SDBR_BASEADDR	(1 << 27)
+#define SMC_SDBR_BASEADDR_MASK	((1 << 27) | (1 << 28) | (1 << 29) | (1 << 30) \
+    				| (1U << 31))
+#define SMC_SDUBR		0x81810 /* Upper Base Register */
+#define SMC_SBSR		0x81814 /* SDRAM Bank Size Register */
+#define SMC_SBSR_BANK_NB	(1 << 2) /* Number of DDR Banks
+					   0 => 2 Banks
+					   1 => 1 Bank
+					   */
+#define SMC_SBSR_BANK_SZ	(1 << 27) /* SDRAM Bank Size :
+					   0x00000 Empty
+					   0x00001 128MB
+					   0x00010 256MB
+					   0x00100 512MB
+					   0x01000 1GB
+					   */
+#define SMC_SBSR_BANK_SZ_MASK	((1 << 27) | (1 << 28) | (1 << 29) | (1 << 30) \
+    				| (1U << 31))
+
+
+/* Two possible addresses for ATUe depending on configuration. */
+#define IOP34X_ATUE_ADDR(esstrsr) ((((esstrsr) & (IOP34X_CONTROLLER_ONLY | \
+    IOP34X_INT_SEL_PCIX)) == (IOP34X_CONTROLLER_ONLY | IOP34X_INT_SEL_PCIX)) ? \
+    0xffdc8000 : 0xffdcd000)
+
+/* Three possible addresses for ATU-X depending on configuration. */
+#define IOP34X_ATUX_ADDR(esstrsr) (!((esstrsr) & IOP34X_CONTROLLER_ONLY) ? \
+    0xffdcc000 : !((esstrsr) & IOP34X_INT_SEL_PCIX) ? 0xffdc8000 : 0xffdcd000)
+
+#define IOP34X_OIOBAR_SIZE		0x10000
+#define IOP34X_PCIX_OIOBAR		0xfffb0000
+#define IOP34X_PCIX_OIOBAR_VADDR	0xf01b0000
+#define IOP34X_PCIX_OMBAR		0x100000000
+#define IOP34X_PCIE_OIOBAR		0xfffd0000
+#define IOP34X_PCIE_OIOBAR_VADDR	0xf01d0000
+#define IOP34X_PCIE_OMBAR		0x200000000
+
+/* ATU Registers */
+/* Common for ATU-X and ATUe */
+#define ATU_VID		0x0000 /* ATU Vendor ID */
+#define ATU_DID		0x0002 /* ATU Device ID */
+#define ATU_CMD		0x0004 /* ATU Command Register */
+#define ATU_SR		0x0006 /* ATU Status Register */
+#define ATU_RID		0x0008 /* ATU Revision ID */
+#define ATU_CCR		0x0009 /* ATU Class Code */
+#define ATU_CLSR	0x000c /* ATU Cacheline Size */
+#define ATU_LT		0x000d /* ATU Latency Timer */
+#define ATU_HTR		0x000e /* ATU Header Type */
+#define ATU_BISTR	0x000f /* ATU BIST Register */
+#define ATU_IABAR0	0x0010 /* Inbound ATU Base Address register 0 */
+#define ATU_IAUBAR0	0x0014 /* Inbound ATU Upper Base Address Register 0 */
+#define ATU_IABAR1	0x0018 /* Inbound ATU Base Address Register 1 */
+#define ATU_IAUBAR1	0x001c /* Inbound ATU Upper Base Address Register 1 */
+#define ATU_IABAR2	0x0020 /* Inbound ATU Base Address Register 2 */
+#define ATU_IAUBAR2	0x0024 /* Inbound ATU Upper Base Address Register 2 */
+#define ATU_VSIR	0x002c /* ATU Subsystem Vendor ID Register */
+#define ATU_SIR		0x002e /* ATU Subsystem ID Register */
+#define ATU_ERBAR	0x0030 /* Expansion ROM Base Address Register */
+#define ATU_CAPPTR	0x0034 /* ATU Capabilities Pointer Register */
+#define ATU_ILR		0x003c /* ATU Interrupt Line Register */
+#define ATU_IPR		0x003d /* ATU Interrupt Pin Register */
+#define ATU_MGNT	0x003e /* ATU Minimum Grand Register */
+#define ATU_MLAT	0x003f /* ATU Maximum Latency Register */
+#define ATU_IALR0	0x0040 /* Inbound ATU Limit Register 0 */
+#define ATU_IATVR0	0x0044 /* Inbound ATU Translate Value Register 0 */
+#define ATU_IAUTVR0	0x0048 /* Inbound ATU Upper Translate Value Register 0*/
+#define ATU_IALR1	0x004c /* Inbound ATU Limit Register 1 */
+#define ATU_IATVR1	0x0050 /* Inbound ATU Translate Value Register 1 */
+#define ATU_IAUTVR1	0x0054 /* Inbound ATU Upper Translate Value Register 1*/
+#define ATU_IALR2	0x0058 /* Inbound ATU Limit Register 2 */
+#define ATU_IATVR2	0x005c /* Inbound ATU Translate Value Register 2 */
+#define ATU_IAUTVR2	0x0060 /* Inbound ATU Upper Translate Value Register 2*/
+#define ATU_ERLR	0x0064 /* Expansion ROM Limit Register */
+#define ATU_ERTVR	0x0068 /* Expansion ROM Translater Value Register */
+#define ATU_ERUTVR	0x006c /* Expansion ROM Upper Translate Value Register*/
+#define ATU_CR		0x0070 /* ATU Configuration Register */
+#define ATU_CR_OUT_EN	(1 << 1)
+#define ATU_PCSR	0x0074 /* PCI Configuration and Status Register */
+#define PCIE_BUSNO(x)	((x & 0xff000000) >> 24)
+#define ATUX_CORE_RST	((1 << 30) | (1U << 31)) /* Core Processor Reset */
+#define ATUX_P_RSTOUT	(1 << 21) /* Central Resource PCI Bus Reset */
+#define ATUE_CORE_RST	((1 << 9) | (1 << 8)) /* Core Processor Reset */
+#define ATU_ISR		0x0078 /* ATU Interrupt Status Register */
+#define ATUX_ISR_PIE	(1 << 18) /* PCI Interface error */
+#define ATUX_ISR_IBPR	(1 << 16) /* Internal Bus Parity Error */
+#define ATUX_ISR_DCE	(1 << 14) /* Detected Correctable error */
+#define ATUX_ISR_ISCE	(1 << 13) /* Initiated Split Completion Error Msg */
+#define ATUX_ISR_RSCE	(1 << 12) /* Received Split Completion Error Msg */
+#define ATUX_ISR_DPE	(1 << 9)  /* Detected Parity Error */
+#define ATUX_ISR_IBMA	(1 << 7)  /* Internal Bus Master Abort */
+#define ATUX_ISR_PMA	(1 << 3)  /* PCI Master Abort */
+#define ATUX_ISR_PTAM	(1 << 2)  /* PCI Target Abort (Master) */
+#define ATUX_ISR_PTAT	(1 << 1)  /* PCI Target Abort (Target) */
+#define ATUX_ISR_PMPE	(1 << 0)  /* PCI Master Parity Error */
+#define ATUX_ISR_ERRMSK	(ATUX_ISR_PIE | ATUX_ISR_IBPR | ATUX_ISR_DCE | \
+    ATUX_ISR_ISCE | ATUX_ISR_RSCE | ATUX_ISR_DPE | ATUX_ISR_IBMA | ATUX_ISR_PMA\
+    | ATUX_ISR_PTAM | ATUX_ISR_PTAT | ATUX_ISR_PMPE)
+#define ATUE_ISR_HON	(1 << 13) /* Halt on Error Interrupt */
+#define ATUE_ISR_RSE	(1 << 12) /* Root System Error Message */
+#define ATUE_ISR_REM	(1 << 11) /* Root Error Message */
+#define ATUE_ISR_PIE	(1 << 10) /* PCI Interface error */
+#define ATUE_ISR_CEM	(1 << 9)  /* Correctable Error Message */
+#define ATUE_ISR_UEM	(1 << 8)  /* Uncorrectable error message */
+#define ATUE_ISR_CRS	(1 << 7)  /* Received Configuration Retry Status */
+#define ATUE_ISR_IBMA	(1 << 5)  /* Internal Bus Master Abort */
+#define ATUE_ISR_DPE	(1 << 4)  /* Detected Parity Error Interrupt */
+#define ATUE_ISR_MAI	(1 << 3)  /* Received Master Abort Interrupt */
+#define ATUE_ISR_STAI	(1 << 2)  /* Signaled Target Abort Interrupt */
+#define ATUE_ISR_TAI	(1 << 1)  /* Received Target Abort Interrupt */
+#define ATUE_ISR_MDPE	(1 << 0)  /* Master Data Parity Error Interrupt */
+#define ATUE_ISR_ERRMSK	(ATUE_ISR_HON | ATUE_ISR_RSE | ATUE_ISR_REM | \
+    ATUE_ISR_PIE | ATUE_ISR_CEM | ATUE_ISR_UEM | ATUE_ISR_CRS | ATUE_ISR_IBMA |\
+    ATUE_ISR_DPE | ATUE_ISR_MAI | ATUE_ISR_STAI | ATUE_ISR_TAI | ATUE_ISR_MDPE)
+#define ATU_IMR		0x007c /* ATU Interrupt Mask Register */
+/* 0x0080 - 0x008f reserved */
+#define ATU_VPDCID	0x0090 /* VPD Capability Identifier Register */
+#define ATU_VPDNIP	0x0091 /* VPD Next Item Pointer Register */
+#define ATU_VPDAR	0x0092 /* VPD Address Register */
+#define ATU_VPDDR	0x0094 /* VPD Data Register */
+#define ATU_PMCID	0x0098 /* PM Capability Identifier Register */
+#define ATU_PMNIPR	0x0099 /* PM Next Item Pointer Register */
+#define ATU_PMCR	0x009a /* ATU Power Management Capabilities Register */
+#define ATU_PMCSR	0x009c /* ATU Power Management Control/Status Register*/
+#define ATU_MSICIR	0x00a0 /* MSI Capability Identifier Register */
+#define ATU_MSINIPR	0x00a1 /* MSI Next Item Pointer Register */
+#define ATU_MCR		0x00a2 /* Message Control Register */
+#define ATU_MAR		0x00a4 /* Message Address Register */
+#define ATU_MUAR	0x00a8 /* Message Upper Address Register */
+#define ATU_MDR		0x00ac /* Message Data Register */
+#define ATU_PCIXSR	0x00d4 /* PCI-X Status Register */
+#define PCIXSR_BUSNO(x)         (((x) & 0xff00) >> 8)
+#define ATU_IABAR3	0x0200 /* Inbound ATU Base Address Register 3 */
+#define ATU_IAUBAR3	0x0204 /* Inbound ATU Upper Base Address Register 3 */
+#define ATU_IALR3	0x0208 /* Inbound ATU Limit Register 3 */
+#define ATU_ITVR3	0x020c /* Inbound ATU Upper Translate Value Reg 3 */
+#define ATU_OIOBAR	0x0300 /* Outbound I/O Base Address Register */
+#define ATU_OIOWTVR	0x0304 /* Outbound I/O Window Translate Value Reg */
+#define ATU_OUMBAR0	0x0308 /* Outbound Upper Memory Window base addr reg 0*/
+#define ATU_OUMBAR_FUNC	(28)
+#define ATU_OUMBAR_EN	(1U << 31)
+#define ATU_OUMWTVR0	0x030c /* Outbound Upper 32bit Memory Window Translate Value Register 0 */
+#define ATU_OUMBAR1	0x0310 /* Outbound Upper Memory Window base addr reg1*/
+#define ATU_OUMWTVR1	0x0314 /* Outbound Upper 32bit Memory Window Translate Value Register 1 */
+#define ATU_OUMBAR2	0x0318 /* Outbound Upper Memory Window base addr reg2*/
+#define ATU_OUMWTVR2	0x031c /* Outbount Upper 32bit Memory Window Translate Value Register 2 */
+#define ATU_OUMBAR3	0x0320 /* Outbound Upper Memory Window base addr reg3*/
+#define ATU_OUMWTVR3	0x0324 /* Outbound Upper 32bit Memory Window Translate Value Register 3 */
+
+/* ATU-X specific */
+#define ATUX_OCCAR	0x0330 /* Outbound Configuration Cycle Address Reg */
+#define ATUX_OCCDR	0x0334 /* Outbound Configuration Cycle Data Reg */
+#define ATUX_OCCFN	0x0338 /* Outbound Configuration Cycle Function Number*/
+/* ATUe specific */
+#define ATUE_OCCAR	0x032c /* Outbound Configuration Cycle Address Reg */
+#define ATUE_OCCDR	0x0330 /* Outbound Configuration Cycle Data Reg */
+#define ATUE_OCCFN	0x0334 /* Outbound Configuration Cycle Function Number*/
+/* Interrupts */
+
+/* IINTRSRC0 */
+#define ICU_INT_ADMA0_EOT	(0) /* ADMA 0 End of transfer */
+#define ICU_INT_ADMA0_EOC	(1) /* ADMA 0 End of Chain */
+#define ICU_INT_ADMA1_EOT	(2) /* ADMA 1 End of transfer */
+#define ICU_INT_ADMA1_EOC	(3) /* ADMA 1 End of chain */
+#define ICU_INT_ADMA2_EOT	(4) /* ADMA 2 End of transfer */
+#define ICU_INT_ADMA2_EOC	(5) /* ADMA 2 end of chain */
+#define ICU_INT_WDOG		(6) /* Watchdog timer */
+/* 7 Reserved */
+#define ICU_INT_TIMER0		(8) /* Timer 0 */
+#define ICU_INT_TIMER1		(9) /* Timer 1 */
+#define ICU_INT_I2C0		(10) /* I2C bus interface 0 */
+#define ICU_INT_I2C1		(11) /* I2C bus interface 1 */
+#define ICU_INT_MU		(12) /* Message Unit */
+#define ICU_INT_MU_IPQ		(13) /* Message unit inbound post queue */
+#define ICU_INT_ATUE_IM		(14) /* ATU-E inbound message */
+#define ICU_INT_ATU_BIST	(15) /* ATU/Start BIST */
+#define ICU_INT_PMC		(16) /* PMC */
+#define ICU_INT_PMU		(17) /* PMU */
+#define ICU_INT_PC		(18) /* Processor cache */
+/* 19-23 Reserved */
+#define ICU_INT_XINT0		(24)
+#define ICU_INT_XINT1		(25)
+#define ICU_INT_XINT2		(26)
+#define ICU_INT_XINT3		(27)
+#define ICU_INT_XINT4		(28)
+#define ICU_INT_XINT5		(29)
+#define ICU_INT_XINT6		(30)
+#define ICU_INT_XINT7		(31)
+/* IINTSRC1 */
+#define ICU_INT_XINT8		(32)
+#define ICU_INT_XINT9		(33)
+#define ICU_INT_XINT10		(34)
+#define ICU_INT_XINT11		(35)
+#define ICU_INT_XINT12		(36)
+#define ICU_INT_XINT13		(37)
+#define ICU_INT_XINT14		(38)
+#define ICU_INT_XINT15		(39)
+/* 40-50 reserved */
+#define ICU_INT_UART0		(51) /* UART 0 */
+#define ICU_INT_UART1		(52) /* UART 1 */
+#define ICU_INT_PBIUE		(53) /* Peripheral bus interface unit error */
+#define ICU_INT_ATUCRW		(54) /* ATU Configuration register write */
+#define ICU_INT_ATUE		(55) /* ATU error */
+#define ICU_INT_MCUE		(56) /* Memory controller unit error */
+#define ICU_INT_ADMA0E		(57) /* ADMA Channel 0 error */
+#define ICU_INT_ADMA1E		(58) /* ADMA Channel 1 error */
+#define ICU_INT_ADMA2E		(59) /* ADMA Channel 2 error */
+/* 60-61 reserved */
+#define ICU_INT_MUE		(62) /* Messaging Unit Error */
+/* 63 reserved */
+
+/* IINTSRC2 */
+#define ICU_INT_IP		(64) /* Inter-processor */
+/* 65-93 reserved */
+#define ICU_INT_SIBBE		(94) /* South internal bus bridge error */
+/* 95 reserved */
+
+/* IINTSRC3 */
+#define ICU_INT_I2C2		(96) /* I2C bus interface 2 */
+#define ICU_INT_ATUE_BIST	(97) /* ATU-E/Start BIST */
+#define ICU_INT_ATUE_CRW	(98) /* ATU-E Configuration register write */
+#define ICU_INT_ATUEE		(99) /* ATU-E Error */
+#define ICU_INT_IMU		(100) /* IMU */
+/* 101-106 reserved */
+#define ICU_INT_ATUE_MA		(107) /* ATUE Interrupt message A */
+#define ICU_INT_ATUE_MB		(108) /* ATUE Interrupt message B */
+#define ICU_INT_ATUE_MC		(109) /* ATUE Interrupt message C */
+#define ICU_INT_ATUE_MD		(110) /* ATUE Interrupt message D */
+#define ICU_INT_MU_MSIX_TW	(111) /* MU MSI-X Table write */
+/* 112 reserved */
+#define ICU_INT_IMSI		(113) /* Inbound MSI */
+/* 114-126 reserved */
+#define ICU_INT_HPI		(127) /* HPI */
+
+
+#endif /* I81342_REG_H_ */


Property changes on: trunk/sys/arm/xscale/i8134x/i81342reg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/i8134x/i81342var.h
===================================================================
--- trunk/sys/arm/xscale/i8134x/i81342var.h	                        (rev 0)
+++ trunk/sys/arm/xscale/i8134x/i81342var.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,71 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2006 Olivier Houchard
+ * 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 ``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
+ * 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: stable/10/sys/arm/xscale/i8134x/i81342var.h 171626 2007-07-27 14:50:57Z cognet $ */
+#ifndef I81342VAR_H_
+#define I81342VAR_H_
+
+#include <sys/rman.h>
+
+struct i81342_softc {
+	device_t dev;
+	bus_space_tag_t 	sc_st;
+	bus_space_handle_t 	sc_sh;
+	bus_space_handle_t	sc_atux_sh;
+	bus_space_handle_t	sc_atue_sh;
+	bus_space_tag_t		sc_pciio;
+	bus_space_tag_t		sc_pcimem;
+	struct rman 		sc_irq_rman;
+};
+
+struct i81342_pci_map {
+	vm_offset_t vaddr;
+	vm_paddr_t paddr;
+	vm_size_t size;
+	struct i81342_pci_map *next;
+};
+
+struct i81342_pci_softc {
+	device_t		sc_dev;
+	bus_space_tag_t		sc_st;
+	bus_space_handle_t	sc_atu_sh;
+	struct bus_space	sc_pciio;
+	struct bus_space	sc_pcimem;
+	struct rman		sc_mem_rman;
+	struct rman		sc_io_rman;
+	struct rman		sc_irq_rman;
+	char			sc_is_atux;
+	int			sc_busno;
+	struct i81342_pci_map	*sc_pci_mappings;
+};
+
+void i81342_bs_init(bus_space_tag_t, void *);
+void i81342_io_bs_init(bus_space_tag_t, void *);
+void i81342_mem_bs_init(bus_space_tag_t, void *);
+void i81342_sdram_bounds(bus_space_tag_t, bus_space_handle_t, vm_paddr_t *,
+    vm_size_t *);
+#endif /*I81342VAR_H_ */


Property changes on: trunk/sys/arm/xscale/i8134x/i81342var.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/i8134x/iq81342_7seg.c
===================================================================
--- trunk/sys/arm/xscale/i8134x/iq81342_7seg.c	                        (rev 0)
+++ trunk/sys/arm/xscale/i8134x/iq81342_7seg.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,392 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: iq31244_7seg.c,v 1.2 2003/07/15 00:25:01 lukem Exp $	*/
+
+/*-
+ * Copyright (c) 2001, 2002, 2003 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Jason R. Thorpe for Wasabi Systems, Inc.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed for the NetBSD Project by
+ *	Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
+ * 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.
+ */
+
+/*
+ * Support for the 7-segment display on the Intel IQ81342.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/xscale/i8134x/iq81342_7seg.c 236987 2012-06-13 04:38:09Z imp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/sysctl.h>
+
+#include <machine/bus.h>
+
+#include <arm/xscale/i8134x/i81342reg.h>
+#include <arm/xscale/i8134x/iq81342reg.h>
+#include <arm/xscale/i8134x/iq81342var.h>
+
+#define	WRITE(x, v)	*((__volatile uint8_t *) (x)) = (v)
+
+static int snakestate;
+
+/*
+ * The 7-segment display looks like so:
+ *
+ *         A
+ *	+-----+
+ *	|     |
+ *    F	|     | B
+ *	|  G  |
+ *	+-----+
+ *	|     |
+ *    E	|     | C
+ *	|  D  |
+ *	+-----+ o  DP
+ *
+ * Setting a bit clears the corresponding segment on the
+ * display.
+ */
+#define	SEG_A			(1 << 1)
+#define	SEG_B			(1 << 2)
+#define	SEG_C			(1 << 3)
+#define	SEG_D			(1 << 4)
+#define	SEG_E			(1 << 5)
+#define	SEG_F			(1 << 6)
+#define	SEG_G			(1 << 7)
+#define	SEG_DP			(1 << 0)
+
+static const uint8_t digitmap[] = {
+/*	+#####+
+ *	#     #
+ *	#     #
+ *	#     #
+ *	+-----+
+ *	#     #
+ *	#     #
+ *	#     #
+ *	+#####+
+ */
+	(unsigned char)~SEG_G,
+
+/*	+-----+
+ *	|     #
+ *	|     #
+ *	|     #
+ *	+-----+
+ *	|     #
+ *	|     #
+ *	|     #
+ *	+-----+
+ */
+	SEG_B|SEG_C,
+
+/*	+#####+
+ *	|     #
+ *	|     #
+ *	|     #
+ *	+#####+
+ *	#     |
+ *	#     |
+ *	#     |
+ *	+#####+
+ */
+	~(SEG_C|SEG_F),
+
+/*	+#####+
+ *	|     #
+ *	|     #
+ *	|     #
+ *	+#####+
+ *	|     #
+ *	|     #
+ *	|     #
+ *	+#####+
+ */
+	~(SEG_E|SEG_F),
+
+/*	+-----+
+ *	#     #
+ *	#     #
+ *	#     #
+ *	+#####+
+ *	|     #
+ *	|     #
+ *	|     #
+ *	+-----+
+ */
+	~(SEG_A|SEG_D|SEG_E),
+
+/*	+#####+
+ *	#     |
+ *	#     |
+ *	#     |
+ *	+#####+
+ *	|     #
+ *	|     #
+ *	|     #
+ *	+#####+
+ */
+	~(SEG_B|SEG_E),
+
+/*	+#####+
+ *	#     |
+ *	#     |
+ *	#     |
+ *	+#####+
+ *	#     #
+ *	#     #
+ *	#     #
+ *	+#####+
+ */
+	~(SEG_B),
+
+/*	+#####+
+ *	|     #
+ *	|     #
+ *	|     #
+ *	+-----+
+ *	|     #
+ *	|     #
+ *	|     #
+ *	+-----+
+ */
+	~(SEG_D|SEG_E|SEG_F),
+
+/*	+#####+
+ *	#     #
+ *	#     #
+ *	#     #
+ *	+#####+
+ *	#     #
+ *	#     #
+ *	#     #
+ *	+#####+
+ */
+	~0,
+
+/*	+#####+
+ *	#     #
+ *	#     #
+ *	#     #
+ *	+#####+
+ *	|     #
+ *	|     #
+ *	|     #
+ *	+-----+
+ */
+	~(SEG_D|SEG_E),
+};
+
+static uint8_t
+iq81342_7seg_xlate(char c)
+{
+	uint8_t rv;
+
+	if (c >= '0' && c <= '9')
+		rv = digitmap[c - '0'];
+	else if (c == '.')
+		rv = (uint8_t) ~SEG_DP;
+	else
+		rv = 0xff;
+
+	return (rv);
+}
+
+void
+iq81342_7seg(char a, char b)
+{
+	uint8_t msb, lsb;
+
+	msb = iq81342_7seg_xlate(a);
+	lsb = iq81342_7seg_xlate(b);
+
+	snakestate = 0;
+
+	WRITE(IQ8134X_7SEG_MSB, msb);
+	WRITE(IQ8134X_7SEG_LSB, lsb);
+}
+
+static const uint8_t snakemap[][2] = {
+
+/*	+#####+		+#####+
+ *	|     |		|     |
+ *	|     |		|     |
+ *	|     |		|     |
+ *	+-----+		+-----+
+ *	|     |		|     |
+ *	|     |		|     |
+ *	|     |		|     |
+ *	+-----+		+-----+
+ */
+	{ SEG_A,	SEG_A },
+
+/*	+-----+		+-----+
+ *	#     |		|     #
+ *	#     |		|     #
+ *	#     |		|     #
+ *	+-----+		+-----+
+ *	|     |		|     |
+ *	|     |		|     |
+ *	|     |		|     |
+ *	+-----+		+-----+
+ */
+	{ SEG_F,	SEG_B },
+
+/*	+-----+		+-----+
+ *	|     |		|     |
+ *	|     |		|     |
+ *	|     |		|     |
+ *	+#####+		+#####+
+ *	|     |		|     |
+ *	|     |		|     |
+ *	|     |		|     |
+ *	+-----+		+-----+
+ */
+	{ SEG_G,	SEG_G },
+
+/*	+-----+		+-----+
+ *	|     |		|     |
+ *	|     |		|     |
+ *	|     |		|     |
+ *	+-----+		+-----+
+ *	|     #		#     |
+ *	|     #		#     |
+ *	|     #		#     |
+ *	+-----+		+-----+
+ */
+	{ SEG_C,	SEG_E },
+
+/*	+-----+		+-----+
+ *	|     |		|     |
+ *	|     |		|     |
+ *	|     |		|     |
+ *	+-----+		+-----+
+ *	|     |		|     |
+ *	|     |		|     |
+ *	|     |		|     |
+ *	+#####+		+#####+
+ */
+	{ SEG_D,	SEG_D },
+
+/*	+-----+		+-----+
+ *	|     |		|     |
+ *	|     |		|     |
+ *	|     |		|     |
+ *	+-----+		+-----+
+ *	#     |		|     #
+ *	#     |		|     #
+ *	#     |		|     #
+ *	+-----+		+-----+
+ */
+	{ SEG_E,	SEG_C },
+
+/*	+-----+		+-----+
+ *	|     |		|     |
+ *	|     |		|     |
+ *	|     |		|     |
+ *	+#####+		+#####+
+ *	|     |		|     |
+ *	|     |		|     |
+ *	|     |		|     |
+ *	+-----+		+-----+
+ */
+	{ SEG_G,	SEG_G },
+
+/*	+-----+		+-----+
+ *	|     #		#     |
+ *	|     #		#     |
+ *	|     #		#     |
+ *	+-----+		+-----+
+ *	|     |		|     |
+ *	|     |		|     |
+ *	|     |		|     |
+ *	+-----+		+-----+
+ */
+	{ SEG_B,	SEG_F },
+};
+
+static SYSCTL_NODE(_hw, OID_AUTO, sevenseg, CTLFLAG_RD, 0, "7 seg");
+static int freq = 20;
+SYSCTL_INT(_hw_sevenseg, OID_AUTO, freq, CTLFLAG_RW, &freq, 0,
+    "7 Seg update frequency");
+static void
+iq81342_7seg_snake(void)
+{
+	static int snakefreq;
+	int cur = snakestate;
+
+	snakefreq++;
+	if ((snakefreq % freq))
+		return;
+	WRITE(IQ8134X_7SEG_MSB, snakemap[cur][0]);
+	WRITE(IQ8134X_7SEG_LSB, snakemap[cur][1]);
+
+	snakestate = (cur + 1) & 7;
+}
+
+struct iq81342_7seg_softc {
+	device_t	dev;
+};
+
+static int
+iq81342_7seg_probe(device_t dev)
+{
+
+	device_set_desc(dev, "IQ81342 7seg");
+	return (0);
+}
+
+extern void (*i80321_hardclock_hook)(void);
+static int
+iq81342_7seg_attach(device_t dev)
+{
+
+	i80321_hardclock_hook = iq81342_7seg_snake;
+	return (0);
+}
+
+static device_method_t iq81342_7seg_methods[] = {
+	DEVMETHOD(device_probe, iq81342_7seg_probe),
+	DEVMETHOD(device_attach, iq81342_7seg_attach),
+	{0, 0},
+};
+
+static driver_t iq81342_7seg_driver = {
+	"iqseg",
+	iq81342_7seg_methods,
+	sizeof(struct iq81342_7seg_softc),
+};
+static devclass_t iq81342_7seg_devclass;
+
+DRIVER_MODULE(iqseg, iq, iq81342_7seg_driver, iq81342_7seg_devclass, 0, 0);


Property changes on: trunk/sys/arm/xscale/i8134x/iq81342_7seg.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/i8134x/iq81342reg.h
===================================================================
--- trunk/sys/arm/xscale/i8134x/iq81342reg.h	                        (rev 0)
+++ trunk/sys/arm/xscale/i8134x/iq81342reg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,34 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2006 Olivier Houchard
+ * 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 ``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
+ * 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: stable/10/sys/arm/xscale/i8134x/iq81342reg.h 172297 2007-09-22 16:25:43Z cognet $ */
+
+#ifndef _IQ81342REG_H_
+#define _IQ81342REG_H_
+#define IQ8134X_7SEG_MSB	IOP34X_PCE1_VADDR + 0x40000
+#define IQ8134X_7SEG_LSB	IOP34X_PCE1_VADDR + 0x50000
+#endif /* _IQ81342REG_H_ */


Property changes on: trunk/sys/arm/xscale/i8134x/iq81342reg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/i8134x/iq81342var.h
===================================================================
--- trunk/sys/arm/xscale/i8134x/iq81342var.h	                        (rev 0)
+++ trunk/sys/arm/xscale/i8134x/iq81342var.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,33 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2006 Olivier Houchard
+ * 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 ``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
+ * 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: stable/10/sys/arm/xscale/i8134x/iq81342var.h 172297 2007-09-22 16:25:43Z cognet $ */
+
+#ifndef _IQ81342VAR_H_
+#define _IQ81342VAR_H_
+void iq81342_7seg(char, char);
+#endif /* _I8Q1342VAR_H_ */


Property changes on: trunk/sys/arm/xscale/i8134x/iq81342var.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/i8134x/obio.c
===================================================================
--- trunk/sys/arm/xscale/i8134x/obio.c	                        (rev 0)
+++ trunk/sys/arm/xscale/i8134x/obio.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,170 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: obio.c,v 1.11 2003/07/15 00:25:05 lukem Exp $	*/
+
+/*-
+ * Copyright (c) 2001, 2002, 2003 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Jason R. Thorpe for Wasabi Systems, Inc.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed for the NetBSD Project by
+ *	Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
+ * 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.
+ */
+
+/*
+ * On-board device autoconfiguration support for Intel IQ80321
+ * evaluation boards.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/xscale/i8134x/obio.c 278727 2015-02-13 22:32:02Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/rman.h>
+#include <sys/malloc.h>
+
+#include <machine/bus.h>
+
+#include <arm/xscale/i8134x/i81342reg.h>
+#include <arm/xscale/i8134x/obiovar.h>
+
+bus_space_tag_t obio_bs_tag;
+
+static int
+obio_probe(device_t dev)
+{
+	return (0);
+}
+
+static int
+obio_attach(device_t dev)
+{
+	struct obio_softc *sc = device_get_softc(dev);
+
+	obio_bs_tag = arm_base_bs_tag;
+	sc->oba_st = obio_bs_tag;
+	sc->oba_rman.rm_type = RMAN_ARRAY;
+	sc->oba_rman.rm_descr = "OBIO I/O";
+	if (rman_init(&sc->oba_rman) != 0 ||
+	    rman_manage_region(&sc->oba_rman,
+	    IOP34X_UART0_VADDR, IOP34X_UART1_VADDR + 0x40) != 0)
+		panic("obio_attach: failed to set up I/O rman");
+	sc->oba_irq_rman.rm_type = RMAN_ARRAY;
+	sc->oba_irq_rman.rm_descr = "OBIO IRQ";
+	if (rman_init(&sc->oba_irq_rman) != 0 ||
+	    rman_manage_region(&sc->oba_irq_rman, ICU_INT_UART0, ICU_INT_UART1) != 0)
+		panic("obio_attach: failed to set up IRQ rman");
+	device_add_child(dev, "uart", 0);
+	device_add_child(dev, "uart", 1);
+	bus_generic_probe(dev);
+	bus_generic_attach(dev);
+	return (0);
+}
+
+static struct resource *
+obio_alloc_resource(device_t bus, device_t child, int type, int *rid,
+    u_long start, u_long end, u_long count, u_int flags)
+{
+	struct resource *rv;
+	struct rman *rm;
+	bus_space_tag_t bt = NULL;
+	bus_space_handle_t bh = 0;
+	struct obio_softc *sc = device_get_softc(bus);
+	int unit = device_get_unit(child);
+
+	switch (type) {
+	case SYS_RES_IRQ:
+		rm = &sc->oba_irq_rman;
+		if (unit == 0)
+			start = end = ICU_INT_UART0;
+		else
+			start = end = ICU_INT_UART1;
+		break;
+	case SYS_RES_MEMORY:
+		return (NULL);
+	case SYS_RES_IOPORT:
+		rm = &sc->oba_rman;
+		bt = sc->oba_st;
+		if (unit == 0) {
+			bh = IOP34X_UART0_VADDR;
+			start = bh;
+			end = IOP34X_UART1_VADDR;
+		} else {
+			bh = IOP34X_UART1_VADDR;
+			start = bh;
+			end = start + 0x40;
+		}
+		break;
+	default:
+		return (NULL);
+	}
+
+
+	rv = rman_reserve_resource(rm, start, end, count, flags, child);
+	if (rv == NULL)
+		return (NULL);
+	if (type == SYS_RES_IRQ)
+		return (rv);
+	rman_set_rid(rv, *rid);
+	rman_set_bustag(rv, bt);
+	rman_set_bushandle(rv, bh);
+	
+	return (rv);
+
+}
+
+static int
+obio_activate_resource(device_t bus, device_t child, int type, int rid,
+    struct resource *r)
+{
+	return (0);
+}
+static device_method_t obio_methods[] = {
+	DEVMETHOD(device_probe, obio_probe),
+	DEVMETHOD(device_attach, obio_attach),
+
+	DEVMETHOD(bus_alloc_resource, obio_alloc_resource),
+	DEVMETHOD(bus_activate_resource, obio_activate_resource),
+	DEVMETHOD(bus_setup_intr,	bus_generic_setup_intr),
+	DEVMETHOD(bus_teardown_intr,	bus_generic_teardown_intr),
+
+	{0, 0},
+};
+
+static driver_t obio_driver = {
+	"obio",
+	obio_methods,
+	sizeof(struct obio_softc),
+};
+static devclass_t obio_devclass;
+
+DRIVER_MODULE(obio, iq, obio_driver, obio_devclass, 0, 0);


Property changes on: trunk/sys/arm/xscale/i8134x/obio.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/i8134x/obiovar.h
===================================================================
--- trunk/sys/arm/xscale/i8134x/obiovar.h	                        (rev 0)
+++ trunk/sys/arm/xscale/i8134x/obiovar.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,56 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: obiovar.h,v 1.4 2003/06/16 17:40:53 thorpej Exp $	*/
+
+/*-
+ * Copyright (c) 2002, 2003 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Jason R. Thorpe for Wasabi Systems, Inc.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed for the NetBSD Project by
+ *	Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
+ * 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: stable/10/sys/arm/xscale/i8134x/obiovar.h 278727 2015-02-13 22:32:02Z ian $
+ *
+ */
+
+#ifndef _IQ81342_OBIOVAR_H_
+#define	_IQ81342_OBIOVAR_H_
+
+#include <sys/rman.h>
+
+struct obio_softc {
+	bus_space_tag_t oba_st;		/* bus space tag */
+	int oba_irq;			/* XINT interrupt bit # */
+	struct rman oba_rman;
+	struct rman oba_irq_rman;
+	
+};
+extern bus_space_tag_t obio_bs_tag;
+
+#endif /* _IQ80321_OBIOVAR_H_ */


Property changes on: trunk/sys/arm/xscale/i8134x/obiovar.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/i8134x/std.crb
===================================================================
--- trunk/sys/arm/xscale/i8134x/std.crb	                        (rev 0)
+++ trunk/sys/arm/xscale/i8134x/std.crb	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,6 @@
+#CRB board configuration
+#$FreeBSD: stable/10/sys/arm/xscale/i8134x/std.crb 171626 2007-07-27 14:50:57Z cognet $
+include		"../xscale/i8134x/std.i81342"
+files		"../xscale/i8134x/files.crb"
+makeoptions	KERNPHYSADDR=0x00200000
+makeoptions	KERNVIRTADDR=0xc0200000


Property changes on: trunk/sys/arm/xscale/i8134x/std.crb
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/xscale/i8134x/std.i81342
===================================================================
--- trunk/sys/arm/xscale/i8134x/std.i81342	                        (rev 0)
+++ trunk/sys/arm/xscale/i8134x/std.i81342	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,5 @@
+#XScale i81342 generic configuration
+#$FreeBSD: stable/10/sys/arm/xscale/i8134x/std.i81342 239362 2012-08-18 05:48:19Z andrew $
+files		"../xscale/i8134x/files.i81342"
+include		"../xscale/std.xscale-be"
+cpu 		CPU_XSCALE_81342


Property changes on: trunk/sys/arm/xscale/i8134x/std.i81342
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/xscale/i8134x/uart_bus_i81342.c
===================================================================
--- trunk/sys/arm/xscale/i8134x/uart_bus_i81342.c	                        (rev 0)
+++ trunk/sys/arm/xscale/i8134x/uart_bus_i81342.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,93 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2004 Olivier Houchard.  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 ``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 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: stable/10/sys/arm/xscale/i8134x/uart_bus_i81342.c 171626 2007-07-27 14:50:57Z cognet $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
+#include <machine/resource.h>
+
+#include <dev/pci/pcivar.h>
+
+#include <dev/uart/uart.h>
+#include <dev/uart/uart_bus.h>
+#include <dev/uart/uart_cpu.h>
+
+#include <dev/ic/ns16550.h>
+
+#include "uart_if.h"
+
+static int uart_i81342_probe(device_t dev);
+
+static device_method_t uart_i81342_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		uart_i81342_probe),
+	DEVMETHOD(device_attach,	uart_bus_attach),
+	DEVMETHOD(device_detach,	uart_bus_detach),
+	{ 0, 0 }
+};
+
+static driver_t uart_i81342_driver = {
+	uart_driver_name,
+	uart_i81342_methods,
+	sizeof(struct uart_softc),
+};
+
+extern SLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs;
+static int
+uart_i81342_probe(device_t dev)
+{
+	struct uart_softc *sc;
+	int err;
+
+	sc = device_get_softc(dev);
+	sc->sc_class = &uart_ns8250_class;
+	if (device_get_unit(dev) == 0) {
+		sc->sc_sysdev = SLIST_FIRST(&uart_sysdevs);
+		bcopy(&sc->sc_sysdev->bas, &sc->sc_bas, sizeof(sc->sc_bas));
+	}
+	sc->sc_rres = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->sc_rrid,
+            0, ~0, uart_getrange(sc->sc_class), RF_ACTIVE);
+	
+	sc->sc_bas.bsh = rman_get_bushandle(sc->sc_rres);
+	sc->sc_bas.bst = rman_get_bustag(sc->sc_rres);
+	bus_space_write_4(sc->sc_bas.bst, sc->sc_bas.bsh, REG_IER << 2,
+	    0x40 | 0x10);
+        bus_release_resource(dev, sc->sc_rtype, sc->sc_rrid, sc->sc_rres);
+
+	err = uart_bus_probe(dev, 2, 33334000, 0, device_get_unit(dev));
+	sc->sc_rxfifosz = sc->sc_txfifosz = 1;
+	return (err);
+}
+
+
+DRIVER_MODULE(uart, obio, uart_i81342_driver, uart_devclass, 0, 0);


Property changes on: trunk/sys/arm/xscale/i8134x/uart_bus_i81342.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/i8134x/uart_cpu_i81342.c
===================================================================
--- trunk/sys/arm/xscale/i8134x/uart_cpu_i81342.c	                        (rev 0)
+++ trunk/sys/arm/xscale/i8134x/uart_cpu_i81342.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,69 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2003 Marcel Moolenaar
+ * 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 ``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 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: stable/10/sys/arm/xscale/i8134x/uart_cpu_i81342.c 278727 2015-02-13 22:32:02Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/cons.h>
+#include <machine/bus.h>
+
+#include <dev/uart/uart.h>
+#include <dev/uart/uart_cpu.h>
+
+#include <arm/xscale/i8134x/i81342reg.h>
+#include <arm/xscale/i8134x/obiovar.h>
+
+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)
+{
+
+	di->ops = uart_getops(&uart_ns8250_class);
+	di->bas.chan = 0;
+	di->bas.bst = obio_bs_tag;
+	di->bas.regshft = 2;
+	di->bas.rclk = 33334000;
+	di->baudrate = 115200;
+	di->databits = 8;
+	di->stopbits = 1;
+	di->parity = UART_PARITY_NONE;
+	uart_bus_space_io = obio_bs_tag;
+	uart_bus_space_mem = NULL;
+	di->bas.bsh = IOP34X_UART0_VADDR;
+	return (0);
+}


Property changes on: trunk/sys/arm/xscale/i8134x/uart_cpu_i81342.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/ixp425/avila_ata.c
===================================================================
--- trunk/sys/arm/xscale/ixp425/avila_ata.c	                        (rev 0)
+++ trunk/sys/arm/xscale/ixp425/avila_ata.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,554 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2006 Sam Leffler, Errno Consulting
+ * 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,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ *    redistribution must be conditioned upon including a substantially
+ *    similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/xscale/ixp425/avila_ata.c 305615 2016-09-08 15:06:28Z pfg $");
+
+/*
+ * Compact Flash Support for the Avila Gateworks XScale boards.
+ * The CF slot is operated in "True IDE" mode. Registers are on
+ * the Expansion Bus connected to CS1 and CS2. Interrupts are
+ * tied to GPIO pin 12.  No DMA, just PIO.
+ *
+ * The ADI Pronghorn Metro is very similar. It use CS3 and CS4 and
+ * GPIO pin 0 for interrupts.
+ *
+ * See also http://www.intel.com/design/network/applnots/302456.htm.
+ */
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/time.h>
+#include <sys/bus.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+#include <sys/sysctl.h>
+#include <sys/endian.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+#include <machine/resource.h>
+#include <machine/intr.h>
+#include <arm/xscale/ixp425/ixp425reg.h>
+#include <arm/xscale/ixp425/ixp425var.h>
+
+#include <sys/ata.h>
+#include <sys/sema.h>
+#include <sys/taskqueue.h>
+#include <vm/uma.h>
+#include <dev/ata/ata-all.h>
+#include <ata_if.h>
+
+#define	AVILA_IDE_CTRL	0x06
+
+struct ata_config {
+	const char	*desc;		/* description for probe */
+	uint8_t		gpin;		/* GPIO pin */
+	uint8_t		irq;		/* IRQ */
+	uint32_t	base16;		/* CS base addr for 16-bit */
+	uint32_t	size16;		/* CS size for 16-bit */
+	uint32_t	off16;		/* CS offset for 16-bit */
+	uint32_t	basealt;	/* CS base addr for alt */
+	uint32_t	sizealt;	/* CS size for alt */
+	uint32_t	offalt;		/* CS offset for alt */
+};
+
+static const struct ata_config *
+ata_getconfig(struct ixp425_softc *sa)
+{
+	static const struct ata_config configs[] = {
+		{ .desc		= "Gateworks Avila IDE/CF Controller",
+		  .gpin		= 12,
+		  .irq		= IXP425_INT_GPIO_12,
+		  .base16	= IXP425_EXP_BUS_CS1_HWBASE,
+		  .size16	= IXP425_EXP_BUS_CS1_SIZE,
+		  .off16	= EXP_TIMING_CS1_OFFSET,
+		  .basealt	= IXP425_EXP_BUS_CS2_HWBASE,
+		  .sizealt	= IXP425_EXP_BUS_CS2_SIZE,
+		  .offalt	= EXP_TIMING_CS2_OFFSET,
+		},
+		{ .desc		= "Gateworks Cambria IDE/CF Controller",
+		  .gpin		= 12,
+		  .irq		= IXP425_INT_GPIO_12,
+		  .base16	= CAMBRIA_CFSEL0_HWBASE,
+		  .size16	= CAMBRIA_CFSEL0_SIZE,
+		  .off16	= EXP_TIMING_CS3_OFFSET,
+		  .basealt	= CAMBRIA_CFSEL1_HWBASE,
+		  .sizealt	= CAMBRIA_CFSEL1_SIZE,
+		  .offalt	= EXP_TIMING_CS4_OFFSET,
+		},
+		{ .desc		= "ADI Pronghorn Metro IDE/CF Controller",
+		  .gpin		= 0,
+		  .irq		= IXP425_INT_GPIO_0,
+		  .base16	= IXP425_EXP_BUS_CS3_HWBASE,
+		  .size16	= IXP425_EXP_BUS_CS3_SIZE,
+		  .off16	= EXP_TIMING_CS3_OFFSET,
+		  .basealt	= IXP425_EXP_BUS_CS4_HWBASE,
+		  .sizealt	= IXP425_EXP_BUS_CS4_SIZE,
+		  .offalt	= EXP_TIMING_CS4_OFFSET,
+		},
+	};
+
+	/* XXX honor hint? (but then no multi-board support) */
+	/* XXX total hack */
+	if (cpu_is_ixp43x())
+		return &configs[1];		/* Cambria */
+	if (EXP_BUS_READ_4(sa, EXP_TIMING_CS2_OFFSET) != 0)
+		return &configs[0];		/* Avila */
+	return &configs[2];			/* Pronghorn */
+}
+
+struct ata_avila_softc {
+	device_t		sc_dev;
+	bus_space_tag_t		sc_iot;
+	bus_space_handle_t	sc_exp_ioh;	/* Exp Bus config registers */
+	bus_space_handle_t	sc_ioh;		/* CS1/3 data registers */
+	bus_space_handle_t	sc_alt_ioh;	/* CS2/4 data registers */
+	struct bus_space	sc_expbus_tag;
+	struct resource		sc_ata;		/* hand-crafted for ATA */
+	struct resource		sc_alt_ata;	/* hand-crafted for ATA */
+	u_int32_t		sc_16bit_off;	/* EXP_TIMING_CSx_OFFSET */
+	int			sc_rid;		/* rid for IRQ */
+	struct resource		*sc_irq;	/* IRQ resource */
+	void			*sc_ih;		/* interrupt handler */
+	struct {
+		void	(*cb)(void *);
+		void	*arg;
+	} sc_intr[1];			/* NB: 1/channel */
+};
+
+static void ata_avila_intr(void *);
+bs_protos(ata);
+static	void ata_bs_rm_2_s(bus_space_tag_t tag, bus_space_handle_t, bus_size_t,
+		u_int16_t *, bus_size_t);
+static	void ata_bs_wm_2_s(bus_space_tag_t tag, bus_space_handle_t, bus_size_t,
+		const u_int16_t *, bus_size_t);
+
+static int
+ata_avila_probe(device_t dev)
+{
+	struct ixp425_softc *sa = device_get_softc(device_get_parent(dev));
+	const struct ata_config *config;
+
+	config = ata_getconfig(sa);
+	if (config != NULL) {
+		device_set_desc_copy(dev, config->desc);
+		return 0;
+	}
+	return ENXIO;
+}
+
+static int
+ata_avila_attach(device_t dev)
+{
+	struct ata_avila_softc *sc = device_get_softc(dev);
+	struct ixp425_softc *sa = device_get_softc(device_get_parent(dev));
+	const struct ata_config	*config;
+
+	config = ata_getconfig(sa);
+	KASSERT(config != NULL, ("no board config"));
+
+	sc->sc_dev = dev;
+	/* NB: borrow from parent */
+	sc->sc_iot = sa->sc_iot;
+	sc->sc_exp_ioh = sa->sc_exp_ioh;
+
+	if (bus_space_map(sc->sc_iot, config->base16, config->size16,
+	    0, &sc->sc_ioh))
+		panic("%s: cannot map 16-bit window (0x%x/0x%x)",
+		    __func__, config->base16, config->size16);
+	if (bus_space_map(sc->sc_iot, config->basealt, config->sizealt,
+	    0, &sc->sc_alt_ioh))
+		panic("%s: cannot map alt window (0x%x/0x%x)",
+		    __func__, config->basealt, config->sizealt);
+	sc->sc_16bit_off = config->off16;
+
+	if (config->base16 != CAMBRIA_CFSEL0_HWBASE) {
+		/*
+		 * Craft special resource for ATA bus space ops
+		 * that go through the expansion bus and require
+		 * special hackery to ena/dis 16-bit operations.
+		 *
+		 * XXX probably should just make this generic for
+		 * accessing the expansion bus.
+		 */
+		sc->sc_expbus_tag.bs_privdata = sc;	/* NB: backpointer */
+		/* read single */
+		sc->sc_expbus_tag.bs_r_1	= ata_bs_r_1;
+		sc->sc_expbus_tag.bs_r_2	= ata_bs_r_2;
+		/* read multiple */
+		sc->sc_expbus_tag.bs_rm_2	= ata_bs_rm_2;
+		sc->sc_expbus_tag.bs_rm_2_s	= ata_bs_rm_2_s;
+		/* write (single) */
+		sc->sc_expbus_tag.bs_w_1	= ata_bs_w_1;
+		sc->sc_expbus_tag.bs_w_2	= ata_bs_w_2;
+		/* write multiple */
+		sc->sc_expbus_tag.bs_wm_2	= ata_bs_wm_2;
+		sc->sc_expbus_tag.bs_wm_2_s	= ata_bs_wm_2_s;
+
+		rman_set_bustag(&sc->sc_ata, &sc->sc_expbus_tag);
+		rman_set_bustag(&sc->sc_alt_ata, &sc->sc_expbus_tag);
+	} else {
+		/*
+		 * On Cambria use the shared CS3 expansion bus tag
+		 * that handles interlock for sharing access with the
+		 * optional UART's.
+		 */
+		rman_set_bustag(&sc->sc_ata, &cambria_exp_bs_tag);
+		rman_set_bustag(&sc->sc_alt_ata, &cambria_exp_bs_tag);
+	}
+	rman_set_bushandle(&sc->sc_ata, sc->sc_ioh);
+	rman_set_bushandle(&sc->sc_alt_ata, sc->sc_alt_ioh);
+
+	ixp425_set_gpio(sa, config->gpin, GPIO_TYPE_EDG_RISING);
+
+	/* configure CS1/3 window, leaving timing unchanged */
+	EXP_BUS_WRITE_4(sc, sc->sc_16bit_off,
+	    EXP_BUS_READ_4(sc, sc->sc_16bit_off) |
+	        EXP_BYTE_EN | EXP_WR_EN | EXP_BYTE_RD16 | EXP_CS_EN);
+	/* configure CS2/4 window, leaving timing unchanged */
+	EXP_BUS_WRITE_4(sc, config->offalt,
+	    EXP_BUS_READ_4(sc, config->offalt) |
+	        EXP_BYTE_EN | EXP_WR_EN | EXP_BYTE_RD16 | EXP_CS_EN);
+
+	/* setup interrupt */
+	sc->sc_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->sc_rid,
+	    config->irq, config->irq, 1, RF_ACTIVE);
+	if (!sc->sc_irq)
+		panic("Unable to allocate irq %u.\n", config->irq);
+	bus_setup_intr(dev, sc->sc_irq,
+	    INTR_TYPE_BIO | INTR_MPSAFE | INTR_ENTROPY,
+	    NULL, ata_avila_intr, sc, &sc->sc_ih);
+
+	/* attach channel on this controller */
+	device_add_child(dev, "ata", -1);
+	bus_generic_attach(dev);
+
+	return 0;
+}
+
+static int
+ata_avila_detach(device_t dev)
+{
+	struct ata_avila_softc *sc = device_get_softc(dev);
+
+	/* XXX quiesce gpio? */
+
+	/* detach & delete all children */
+	device_delete_children(dev);
+
+	bus_teardown_intr(dev, sc->sc_irq, sc->sc_ih);
+	bus_release_resource(dev, SYS_RES_IRQ, sc->sc_rid, sc->sc_irq);
+
+	return 0;
+}
+
+static void
+ata_avila_intr(void *xsc)
+{
+	struct ata_avila_softc *sc = xsc;
+
+	if (sc->sc_intr[0].cb != NULL)
+		sc->sc_intr[0].cb(sc->sc_intr[0].arg);
+}
+
+static struct resource *
+ata_avila_alloc_resource(device_t dev, device_t child, int type, int *rid,
+		       u_long start, u_long end, u_long count, u_int flags)
+{
+	struct ata_avila_softc *sc = device_get_softc(dev);
+
+	KASSERT(type == SYS_RES_IRQ && *rid == ATA_IRQ_RID,
+	    ("type %u rid %u start %lu end %lu count %lu flags %u",
+	     type, *rid, start, end, count, flags));
+
+	/* doesn't matter what we return so reuse the real thing */
+	return sc->sc_irq;
+}
+
+static int
+ata_avila_release_resource(device_t dev, device_t child, int type, int rid,
+			 struct resource *r)
+{
+	KASSERT(type == SYS_RES_IRQ && rid == ATA_IRQ_RID,
+	    ("type %u rid %u", type, rid));
+	return 0;
+}
+
+static int
+ata_avila_setup_intr(device_t dev, device_t child, struct resource *irq,
+		   int flags, driver_filter_t *filt,
+		   driver_intr_t *function, void *argument, void **cookiep)
+{
+	struct ata_avila_softc *sc = device_get_softc(dev);
+	int unit = ((struct ata_channel *)device_get_softc(child))->unit;
+
+	KASSERT(unit == 0, ("unit %d", unit));
+	sc->sc_intr[unit].cb = function;
+	sc->sc_intr[unit].arg = argument;
+	*cookiep = sc;
+	return 0;
+}
+
+static int
+ata_avila_teardown_intr(device_t dev, device_t child, struct resource *irq,
+		      void *cookie)
+{
+	struct ata_avila_softc *sc = device_get_softc(dev);
+	int unit = ((struct ata_channel *)device_get_softc(child))->unit;
+
+	KASSERT(unit == 0, ("unit %d", unit));
+	sc->sc_intr[unit].cb = NULL;
+	sc->sc_intr[unit].arg = NULL;
+	return 0;
+}
+
+/*
+ * Bus space accessors for CF-IDE PIO operations.
+ */
+
+/*
+ * Enable/disable 16-bit ops on the expansion bus.
+ */
+static __inline void
+enable_16(struct ata_avila_softc *sc)
+{
+	EXP_BUS_WRITE_4(sc, sc->sc_16bit_off,
+	    EXP_BUS_READ_4(sc, sc->sc_16bit_off) &~ EXP_BYTE_EN);
+	DELAY(100);		/* XXX? */
+}
+
+static __inline void
+disable_16(struct ata_avila_softc *sc)
+{
+	DELAY(100);		/* XXX? */
+	EXP_BUS_WRITE_4(sc, sc->sc_16bit_off,
+	    EXP_BUS_READ_4(sc, sc->sc_16bit_off) | EXP_BYTE_EN);
+}
+
+uint8_t
+ata_bs_r_1(bus_space_tag_t tag, bus_space_handle_t h, bus_size_t o)
+{
+	struct ata_avila_softc *sc = tag->bs_privdata;
+
+	return bus_space_read_1(sc->sc_iot, h, o);
+}
+
+void
+ata_bs_w_1(bus_space_tag_t tag, bus_space_handle_t h, bus_size_t o, u_int8_t v)
+{
+	struct ata_avila_softc *sc = tag->bs_privdata;
+
+	bus_space_write_1(sc->sc_iot, h, o, v);
+}
+
+uint16_t
+ata_bs_r_2(bus_space_tag_t tag, bus_space_handle_t h, bus_size_t o)
+{
+	struct ata_avila_softc *sc = tag->bs_privdata;
+	uint16_t v;
+
+	enable_16(sc);
+	v = bus_space_read_2(sc->sc_iot, h, o);
+	disable_16(sc);
+	return v;
+}
+
+void
+ata_bs_w_2(bus_space_tag_t tag, bus_space_handle_t h, bus_size_t o, uint16_t v)
+{
+	struct ata_avila_softc *sc = tag->bs_privdata;
+
+	enable_16(sc);
+	bus_space_write_2(sc->sc_iot, h, o, v);
+	disable_16(sc);
+}
+
+void
+ata_bs_rm_2(bus_space_tag_t tag, bus_space_handle_t h, bus_size_t o,
+	u_int16_t *d, bus_size_t c)
+{
+	struct ata_avila_softc *sc = tag->bs_privdata;
+
+	enable_16(sc);
+	bus_space_read_multi_2(sc->sc_iot, h, o, d, c);
+	disable_16(sc);
+}
+
+void
+ata_bs_wm_2(bus_space_tag_t tag, bus_space_handle_t h, bus_size_t o,
+	const u_int16_t *d, bus_size_t c)
+{
+	struct ata_avila_softc *sc = tag->bs_privdata;
+
+	enable_16(sc);
+	bus_space_write_multi_2(sc->sc_iot, h, o, d, c);
+	disable_16(sc);
+}
+
+/* XXX workaround ata driver by (incorrectly) byte swapping stream cases */
+
+void
+ata_bs_rm_2_s(bus_space_tag_t tag, bus_space_handle_t h, bus_size_t o,
+	u_int16_t *d, bus_size_t c)
+{
+	struct ata_avila_softc *sc = tag->bs_privdata;
+	uint16_t v;
+	bus_size_t i;
+
+	enable_16(sc);
+#if 1
+	for (i = 0; i < c; i++) {
+		v = bus_space_read_2(sc->sc_iot, h, o);
+		d[i] = bswap16(v);
+	}
+#else
+	bus_space_read_multi_stream_2(sc->sc_iot, h, o, d, c);
+#endif
+	disable_16(sc);
+}
+
+void
+ata_bs_wm_2_s(bus_space_tag_t tag, bus_space_handle_t h, bus_size_t o,
+	const u_int16_t *d, bus_size_t c)
+{
+	struct ata_avila_softc *sc = tag->bs_privdata;
+	bus_size_t i;
+
+	enable_16(sc);
+#if 1
+	for (i = 0; i < c; i++)
+		bus_space_write_2(sc->sc_iot, h, o, bswap16(d[i]));
+#else
+	bus_space_write_multi_stream_2(sc->sc_iot, h, o, d, c);
+#endif
+	disable_16(sc);
+}
+
+static device_method_t ata_avila_methods[] = {
+	/* device interface */
+	DEVMETHOD(device_probe,             ata_avila_probe),
+	DEVMETHOD(device_attach,            ata_avila_attach),
+	DEVMETHOD(device_detach,            ata_avila_detach),
+	DEVMETHOD(device_shutdown,          bus_generic_shutdown),
+	DEVMETHOD(device_suspend,           bus_generic_suspend),
+	DEVMETHOD(device_resume,            bus_generic_resume),
+
+	/* bus methods */
+	DEVMETHOD(bus_alloc_resource,       ata_avila_alloc_resource),
+	DEVMETHOD(bus_release_resource,     ata_avila_release_resource),
+	DEVMETHOD(bus_activate_resource,    bus_generic_activate_resource),
+	DEVMETHOD(bus_deactivate_resource,  bus_generic_deactivate_resource),
+	DEVMETHOD(bus_setup_intr,           ata_avila_setup_intr),
+	DEVMETHOD(bus_teardown_intr,        ata_avila_teardown_intr),
+
+	{ 0, 0 }
+};
+
+devclass_t ata_avila_devclass;
+
+static driver_t ata_avila_driver = {
+	"ata_avila",
+	ata_avila_methods,
+	sizeof(struct ata_avila_softc),
+};
+
+DRIVER_MODULE(ata_avila, ixp, ata_avila_driver, ata_avila_devclass, 0, 0);
+MODULE_VERSION(ata_avila, 1);
+MODULE_DEPEND(ata_avila, ata, 1, 1, 1);
+
+static int
+avila_channel_probe(device_t dev)
+{
+	struct ata_channel *ch = device_get_softc(dev);
+
+	ch->unit = 0;
+	ch->flags |= ATA_USE_16BIT | ATA_NO_SLAVE;
+	device_set_desc_copy(dev, "ATA channel 0");
+
+	return ata_probe(dev);
+}
+
+static int
+avila_channel_attach(device_t dev)
+{
+	struct ata_avila_softc *sc = device_get_softc(device_get_parent(dev));
+	struct ata_channel *ch = device_get_softc(dev);
+	int i;
+
+	for (i = 0; i < ATA_MAX_RES; i++)
+		ch->r_io[i].res = &sc->sc_ata;
+
+	ch->r_io[ATA_DATA].offset = ATA_DATA;
+	ch->r_io[ATA_FEATURE].offset = ATA_FEATURE;
+	ch->r_io[ATA_COUNT].offset = ATA_COUNT;
+	ch->r_io[ATA_SECTOR].offset = ATA_SECTOR;
+	ch->r_io[ATA_CYL_LSB].offset = ATA_CYL_LSB;
+	ch->r_io[ATA_CYL_MSB].offset = ATA_CYL_MSB;
+	ch->r_io[ATA_DRIVE].offset = ATA_DRIVE;
+	ch->r_io[ATA_COMMAND].offset = ATA_COMMAND;
+	ch->r_io[ATA_ERROR].offset = ATA_FEATURE;
+	/* NB: should be used only for ATAPI devices */
+	ch->r_io[ATA_IREASON].offset = ATA_COUNT;
+	ch->r_io[ATA_STATUS].offset = ATA_COMMAND;
+
+	/* NB: the control and alt status registers are special */
+	ch->r_io[ATA_ALTSTAT].res = &sc->sc_alt_ata;
+	ch->r_io[ATA_ALTSTAT].offset = AVILA_IDE_CTRL;
+	ch->r_io[ATA_CONTROL].res = &sc->sc_alt_ata;
+	ch->r_io[ATA_CONTROL].offset = AVILA_IDE_CTRL;
+
+	/* NB: by convention this points at the base of registers */
+	ch->r_io[ATA_IDX_ADDR].offset = 0;
+
+	ata_generic_hw(dev);
+	return ata_attach(dev);
+}
+
+static device_method_t avila_channel_methods[] = {
+	/* device interface */
+	DEVMETHOD(device_probe,     avila_channel_probe),
+	DEVMETHOD(device_attach,    avila_channel_attach),
+	DEVMETHOD(device_detach,    ata_detach),
+	DEVMETHOD(device_shutdown,  bus_generic_shutdown),
+	DEVMETHOD(device_suspend,   ata_suspend),
+	DEVMETHOD(device_resume,    ata_resume),
+
+	{ 0, 0 }
+};
+
+driver_t avila_channel_driver = {
+	"ata",
+	avila_channel_methods,
+	sizeof(struct ata_channel),
+};
+DRIVER_MODULE(ata, ata_avila, avila_channel_driver, ata_devclass, 0, 0);


Property changes on: trunk/sys/arm/xscale/ixp425/avila_ata.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/ixp425/avila_gpio.c
===================================================================
--- trunk/sys/arm/xscale/ixp425/avila_gpio.c	                        (rev 0)
+++ trunk/sys/arm/xscale/ixp425/avila_gpio.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,359 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2009, Oleksandr Tymoshenko <gonzo at FreeBSD.org>
+ * Copyright (c) 2009, Luiz Otavio O Souza.
+ * Copyright (c) 2010, Andrew Thompson <thompsa at FreeBSD.org>
+ * 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 unmodified, 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.
+ */
+
+/*
+ * GPIO driver for Gateworks Avilia
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/xscale/ixp425/avila_gpio.c 278786 2015-02-14 21:16:19Z loos $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/rman.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/gpio.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+#include <arm/xscale/ixp425/ixp425reg.h>
+#include <arm/xscale/ixp425/ixp425var.h>
+
+#include "gpio_if.h"
+
+#define GPIO_SET_BITS(sc, reg, bits)	\
+	GPIO_CONF_WRITE_4(sc, reg, GPIO_CONF_READ_4(sc, (reg)) | (bits))
+
+#define GPIO_CLEAR_BITS(sc, reg, bits)	\
+	GPIO_CONF_WRITE_4(sc, reg, GPIO_CONF_READ_4(sc, (reg)) & ~(bits))
+
+struct avila_gpio_softc {
+	device_t		sc_dev;
+	bus_space_tag_t		sc_iot;
+	bus_space_handle_t	sc_gpio_ioh;
+	uint32_t		sc_valid;
+	struct gpio_pin		sc_pins[IXP4XX_GPIO_PINS];
+};
+
+struct avila_gpio_pin {
+	const char *name;
+	int pin;
+	int caps;
+};
+
+#define	GPIO_PIN_IO	(GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)
+static struct avila_gpio_pin avila_gpio_pins[] = {
+	{ "GPIO0", 0, GPIO_PIN_IO },
+	{ "GPIO1", 1, GPIO_PIN_IO },
+	{ "GPIO2", 2, GPIO_PIN_IO },
+	{ "GPIO3", 3, GPIO_PIN_IO },
+	{ "GPIO4", 4, GPIO_PIN_IO },
+	/*
+	 * The following pins are connected to system devices and should not
+	 * really be frobbed.
+	 */
+#if 0
+	{ "SER_ENA", 5, GPIO_PIN_IO },
+	{ "I2C_SCL", 6, GPIO_PIN_IO },
+	{ "I2C_SDA", 7, GPIO_PIN_IO },
+	{ "PCI_INTD", 8, GPIO_PIN_IO },
+	{ "PCI_INTC", 9, GPIO_PIN_IO },
+	{ "PCI_INTB", 10, GPIO_PIN_IO },
+	{ "PCI_INTA", 11, GPIO_PIN_IO },
+	{ "ATA_INT", 12, GPIO_PIN_IO },
+	{ "PCI_RST", 13, GPIO_PIN_IO },
+	{ "PCI_CLK", 14, GPIO_PIN_OUTPUT },
+	{ "EX_CLK", 15, GPIO_PIN_OUTPUT },
+#endif
+};
+#undef GPIO_PIN_IO
+
+/*
+ * Helpers
+ */
+static void avila_gpio_pin_configure(struct avila_gpio_softc *sc,
+    struct gpio_pin *pin, uint32_t flags);
+static int  avila_gpio_pin_flags(struct avila_gpio_softc *sc, uint32_t pin);
+
+/*
+ * Driver stuff
+ */
+static int avila_gpio_probe(device_t dev);
+static int avila_gpio_attach(device_t dev);
+static int avila_gpio_detach(device_t dev);
+
+/*
+ * GPIO interface
+ */
+static int avila_gpio_pin_max(device_t dev, int *maxpin);
+static int avila_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps);
+static int avila_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t
+    *flags);
+static int avila_gpio_pin_getname(device_t dev, uint32_t pin, char *name);
+static int avila_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags);
+static int avila_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value);
+static int avila_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val);
+static int avila_gpio_pin_toggle(device_t dev, uint32_t pin);
+
+static int
+avila_gpio_pin_flags(struct avila_gpio_softc *sc, uint32_t pin)
+{
+	uint32_t v;
+
+	v = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPINR) & (1 << pin);
+
+	return (v ? GPIO_PIN_INPUT : GPIO_PIN_OUTPUT);
+}
+
+static void
+avila_gpio_pin_configure(struct avila_gpio_softc *sc, struct gpio_pin *pin,
+    unsigned int flags)
+{
+	uint32_t mask;
+
+	mask = 1 << pin->gp_pin;
+
+	/*
+	 * Manage input/output
+	 */
+	if (flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) {
+		IXP4XX_GPIO_LOCK();
+		pin->gp_flags &= ~(GPIO_PIN_INPUT|GPIO_PIN_OUTPUT);
+		if (flags & GPIO_PIN_OUTPUT) {
+			pin->gp_flags |= GPIO_PIN_OUTPUT;
+			GPIO_CLEAR_BITS(sc, IXP425_GPIO_GPOER, mask);
+		}
+		else {
+			pin->gp_flags |= GPIO_PIN_INPUT;
+			GPIO_SET_BITS(sc, IXP425_GPIO_GPOER, mask);
+		}
+		IXP4XX_GPIO_UNLOCK();
+	}
+}
+
+static int
+avila_gpio_pin_max(device_t dev, int *maxpin)
+{
+
+	*maxpin = IXP4XX_GPIO_PINS - 1;
+	return (0);
+}
+
+static int
+avila_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
+{
+	struct avila_gpio_softc *sc = device_get_softc(dev);
+
+	if (pin >= IXP4XX_GPIO_PINS || !(sc->sc_valid & (1 << pin)))
+		return (EINVAL);
+
+	*caps = sc->sc_pins[pin].gp_caps;
+	return (0);
+}
+
+static int
+avila_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
+{
+	struct avila_gpio_softc *sc = device_get_softc(dev);
+
+	if (pin >= IXP4XX_GPIO_PINS || !(sc->sc_valid & (1 << pin)))
+		return (EINVAL);
+
+	IXP4XX_GPIO_LOCK();
+	/* refresh since we do not own all the pins */
+	sc->sc_pins[pin].gp_flags = avila_gpio_pin_flags(sc, pin);
+	*flags = sc->sc_pins[pin].gp_flags;
+	IXP4XX_GPIO_UNLOCK();
+
+	return (0);
+}
+
+static int
+avila_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
+{
+	struct avila_gpio_softc *sc = device_get_softc(dev);
+
+	if (pin >= IXP4XX_GPIO_PINS || !(sc->sc_valid & (1 << pin)))
+		return (EINVAL);
+
+	memcpy(name, sc->sc_pins[pin].gp_name, GPIOMAXNAME);
+	return (0);
+}
+
+static int
+avila_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
+{
+	struct avila_gpio_softc *sc = device_get_softc(dev);
+	uint32_t mask = 1 << pin;
+
+	if (pin >= IXP4XX_GPIO_PINS || !(sc->sc_valid & mask))
+		return (EINVAL);
+
+	avila_gpio_pin_configure(sc, &sc->sc_pins[pin], flags);
+
+	return (0);
+}
+
+static int
+avila_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value)
+{
+	struct avila_gpio_softc *sc = device_get_softc(dev);
+	uint32_t mask = 1 << pin;
+
+	if (pin >= IXP4XX_GPIO_PINS || !(sc->sc_valid & mask))
+		return (EINVAL);
+
+	IXP4XX_GPIO_LOCK();
+	if (value)
+		GPIO_SET_BITS(sc, IXP425_GPIO_GPOUTR, mask);
+	else
+		GPIO_CLEAR_BITS(sc, IXP425_GPIO_GPOUTR, mask);
+	IXP4XX_GPIO_UNLOCK();
+
+	return (0);
+}
+
+static int
+avila_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val)
+{
+	struct avila_gpio_softc *sc = device_get_softc(dev);
+
+	if (pin >= IXP4XX_GPIO_PINS || !(sc->sc_valid & (1 << pin)))
+		return (EINVAL);
+
+	IXP4XX_GPIO_LOCK();
+	*val = (GPIO_CONF_READ_4(sc, IXP425_GPIO_GPINR) & (1 << pin)) ? 1 : 0;
+	IXP4XX_GPIO_UNLOCK();
+
+	return (0);
+}
+
+static int
+avila_gpio_pin_toggle(device_t dev, uint32_t pin)
+{
+	struct avila_gpio_softc *sc = device_get_softc(dev);
+	uint32_t mask = 1 << pin;
+	int res;
+
+	if (pin >= IXP4XX_GPIO_PINS || !(sc->sc_valid & mask))
+		return (EINVAL);
+
+	IXP4XX_GPIO_LOCK();
+	res = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPINR) & mask;
+	if (res)
+		GPIO_CLEAR_BITS(sc, IXP425_GPIO_GPOUTR, mask);
+	else
+		GPIO_SET_BITS(sc, IXP425_GPIO_GPOUTR, mask);
+	IXP4XX_GPIO_UNLOCK();
+
+	return (0);
+}
+
+static int
+avila_gpio_probe(device_t dev)
+{
+
+	device_set_desc(dev, "Gateworks Avila GPIO driver");
+	return (0);
+}
+
+static int
+avila_gpio_attach(device_t dev)
+{
+#define	N(a)	(sizeof(a) / sizeof(a[0]))
+	struct avila_gpio_softc *sc = device_get_softc(dev);
+	struct ixp425_softc *sa = device_get_softc(device_get_parent(dev));
+	int i;
+
+	sc->sc_dev = dev;
+	sc->sc_iot = sa->sc_iot;
+	sc->sc_gpio_ioh = sa->sc_gpio_ioh;
+
+	for (i = 0; i < N(avila_gpio_pins); i++) {
+		struct avila_gpio_pin *p = &avila_gpio_pins[i];
+
+		strncpy(sc->sc_pins[p->pin].gp_name, p->name, GPIOMAXNAME);
+		sc->sc_pins[p->pin].gp_pin = p->pin;
+		sc->sc_pins[p->pin].gp_caps = p->caps;
+		sc->sc_pins[p->pin].gp_flags = avila_gpio_pin_flags(sc, p->pin);
+		sc->sc_valid |= 1 << p->pin;
+	}
+
+	device_add_child(dev, "gpioc", -1);
+	device_add_child(dev, "gpiobus", -1);
+
+	return (bus_generic_attach(dev));
+#undef N
+}
+
+static int
+avila_gpio_detach(device_t dev)
+{
+
+	bus_generic_detach(dev);
+
+	return(0);
+}
+
+static device_method_t gpio_avila_methods[] = {
+	DEVMETHOD(device_probe, avila_gpio_probe),
+	DEVMETHOD(device_attach, avila_gpio_attach),
+	DEVMETHOD(device_detach, avila_gpio_detach),
+
+	/* GPIO protocol */
+	DEVMETHOD(gpio_pin_max, avila_gpio_pin_max),
+	DEVMETHOD(gpio_pin_getname, avila_gpio_pin_getname),
+	DEVMETHOD(gpio_pin_getflags, avila_gpio_pin_getflags),
+	DEVMETHOD(gpio_pin_getcaps, avila_gpio_pin_getcaps),
+	DEVMETHOD(gpio_pin_setflags, avila_gpio_pin_setflags),
+	DEVMETHOD(gpio_pin_get, avila_gpio_pin_get),
+	DEVMETHOD(gpio_pin_set, avila_gpio_pin_set),
+	DEVMETHOD(gpio_pin_toggle, avila_gpio_pin_toggle),
+	{0, 0},
+};
+
+static driver_t gpio_avila_driver = {
+	"gpio_avila",
+	gpio_avila_methods,
+	sizeof(struct avila_gpio_softc),
+};
+static devclass_t gpio_avila_devclass;
+extern devclass_t gpiobus_devclass, gpioc_devclass;
+extern driver_t gpiobus_driver, gpioc_driver;
+
+DRIVER_MODULE(gpio_avila, ixp, gpio_avila_driver, gpio_avila_devclass, 0, 0);
+DRIVER_MODULE(gpiobus, gpio_avila, gpiobus_driver, gpiobus_devclass, 0, 0);
+DRIVER_MODULE(gpioc, gpio_avila, gpioc_driver, gpioc_devclass, 0, 0);
+MODULE_VERSION(gpio_avila, 1);


Property changes on: trunk/sys/arm/xscale/ixp425/avila_gpio.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/ixp425/avila_led.c
===================================================================
--- trunk/sys/arm/xscale/ixp425/avila_led.c	                        (rev 0)
+++ trunk/sys/arm/xscale/ixp425/avila_led.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,119 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2006 Kevin Lo.  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 ``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 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: stable/10/sys/arm/xscale/ixp425/avila_led.c 215319 2010-11-14 20:41:22Z thompsa $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+
+#include <arm/xscale/ixp425/ixp425reg.h>
+#include <arm/xscale/ixp425/ixp425var.h>
+
+#include <dev/led/led.h>
+
+#define	GPIO_LED_STATUS	3
+#define	GPIO_LED_STATUS_BIT	(1U << GPIO_LED_STATUS)
+
+struct led_avila_softc {
+	device_t		sc_dev;
+	bus_space_tag_t		sc_iot;
+	bus_space_handle_t	sc_gpio_ioh;
+	struct cdev		*sc_led;
+};
+
+static void
+led_func(void *arg, int onoff)
+{
+	struct led_avila_softc *sc = arg;
+	uint32_t reg;
+
+	IXP4XX_GPIO_LOCK();
+	reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPOUTR);
+	if (onoff)
+		reg &= ~GPIO_LED_STATUS_BIT;
+	else
+		reg |= GPIO_LED_STATUS_BIT;
+	GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPOUTR, reg);
+	IXP4XX_GPIO_UNLOCK();
+}
+
+static int
+led_avila_probe(device_t dev)
+{
+	device_set_desc(dev, "Gateworks Avila Front Panel LED");
+	return (0);
+}
+
+static int
+led_avila_attach(device_t dev)
+{
+	struct led_avila_softc *sc = device_get_softc(dev);
+	struct ixp425_softc *sa = device_get_softc(device_get_parent(dev));
+
+	sc->sc_dev = dev;
+	sc->sc_iot = sa->sc_iot;
+	sc->sc_gpio_ioh = sa->sc_gpio_ioh;
+
+	/* Configure LED GPIO pin as output */
+	GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPOER,
+	    GPIO_CONF_READ_4(sc, IXP425_GPIO_GPOER) &~ GPIO_LED_STATUS_BIT);
+
+	sc->sc_led = led_create(led_func, sc, "gpioled");
+
+	led_func(sc, 1);		/* Turn on LED */
+
+	return (0);
+}
+
+static int
+led_avila_detach(device_t dev)
+{
+	struct led_avila_softc *sc = device_get_softc(dev);
+
+	if (sc->sc_led != NULL)
+		led_destroy(sc->sc_led);
+	return (0);
+}
+
+static device_method_t led_avila_methods[] = {
+	DEVMETHOD(device_probe,		led_avila_probe),
+	DEVMETHOD(device_attach,	led_avila_attach),
+	DEVMETHOD(device_detach,	led_avila_detach),
+
+	{0, 0},
+};
+
+static driver_t led_avila_driver = {
+	"led_avila",
+	led_avila_methods,
+	sizeof(struct led_avila_softc),
+};
+static devclass_t led_avila_devclass;
+
+DRIVER_MODULE(led_avila, ixp, led_avila_driver, led_avila_devclass, 0, 0);


Property changes on: trunk/sys/arm/xscale/ixp425/avila_led.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/ixp425/avila_machdep.c
===================================================================
--- trunk/sys/arm/xscale/ixp425/avila_machdep.c	                        (rev 0)
+++ trunk/sys/arm/xscale/ixp425/avila_machdep.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,428 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: hpc_machdep.c,v 1.70 2003/09/16 08:18:22 agc Exp $	*/
+
+/*-
+ * Copyright (c) 1994-1998 Mark Brinicombe.
+ * Copyright (c) 1994 Brini.
+ * All rights reserved.
+ *
+ * This code is derived from software written for Brini by Mark Brinicombe
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by Brini.
+ * 4. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BRINI ``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 BRINI 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.
+ *
+ * RiscBSD kernel project
+ *
+ * machdep.c
+ *
+ * Machine dependant functions for kernel setup
+ *
+ * This file needs a lot of work.
+ *
+ * Created      : 17/09/94
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/xscale/ixp425/avila_machdep.c 294683 2016-01-24 21:04:06Z ian $");
+
+#define _ARM32_BUS_DMA_PRIVATE
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/sysproto.h>
+#include <sys/signalvar.h>
+#include <sys/imgact.h>
+#include <sys/kernel.h>
+#include <sys/ktr.h>
+#include <sys/linker.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/mutex.h>
+#include <sys/pcpu.h>
+#include <sys/proc.h>
+#include <sys/ptrace.h>
+#include <sys/cons.h>
+#include <sys/bio.h>
+#include <sys/bus.h>
+#include <sys/buf.h>
+#include <sys/exec.h>
+#include <sys/kdb.h>
+#include <sys/msgbuf.h>
+#include <machine/physmem.h>
+#include <machine/reg.h>
+#include <machine/cpu.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/vm_object.h>
+#include <vm/vm_page.h>
+#include <vm/vm_map.h>
+#include <machine/devmap.h>
+#include <machine/vmparam.h>
+#include <machine/pcb.h>
+#include <machine/undefined.h>
+#include <machine/machdep.h>
+#include <machine/metadata.h>
+#include <machine/armreg.h>
+#include <machine/bus.h>
+#include <sys/reboot.h>
+
+#include <arm/xscale/ixp425/ixp425reg.h>
+#include <arm/xscale/ixp425/ixp425var.h>
+
+#define KERNEL_PT_SYS		0	/* Page table for mapping proc0 zero page */
+#define	KERNEL_PT_IO		1
+#define KERNEL_PT_IO_NUM	3
+#define KERNEL_PT_BEFOREKERN	KERNEL_PT_IO + KERNEL_PT_IO_NUM
+#define KERNEL_PT_AFKERNEL	KERNEL_PT_BEFOREKERN + 1	/* L2 table for mapping after kernel */
+#define	KERNEL_PT_AFKERNEL_NUM	9
+
+/* this should be evenly divisable by PAGE_SIZE / L2_TABLE_SIZE_REAL (or 4) */
+#define NUM_KERNEL_PTS		(KERNEL_PT_AFKERNEL + KERNEL_PT_AFKERNEL_NUM)
+
+struct pv_addr kernel_pt_table[NUM_KERNEL_PTS];
+
+/* Physical and virtual addresses for some global pages */
+
+struct pv_addr systempage;
+struct pv_addr msgbufpv;
+struct pv_addr irqstack;
+struct pv_addr undstack;
+struct pv_addr abtstack;
+struct pv_addr kernelstack;
+struct pv_addr minidataclean;
+
+/* Static device mappings. */
+static const struct arm_devmap_entry ixp425_devmap[] = {
+	/* Physical/Virtual address for I/O space */
+    { IXP425_IO_VBASE, IXP425_IO_HWBASE, IXP425_IO_SIZE,
+      VM_PROT_READ|VM_PROT_WRITE, PTE_DEVICE, },
+
+	/* Expansion Bus */
+    { IXP425_EXP_VBASE, IXP425_EXP_HWBASE, IXP425_EXP_SIZE,
+      VM_PROT_READ|VM_PROT_WRITE, PTE_DEVICE, },
+
+	/* CFI Flash on the Expansion Bus */
+    { IXP425_EXP_BUS_CS0_VBASE, IXP425_EXP_BUS_CS0_HWBASE,
+      IXP425_EXP_BUS_CS0_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_DEVICE, },
+
+	/* IXP425 PCI Configuration */
+    { IXP425_PCI_VBASE, IXP425_PCI_HWBASE, IXP425_PCI_SIZE,
+      VM_PROT_READ|VM_PROT_WRITE, PTE_DEVICE, },
+
+	/* SDRAM Controller */
+    { IXP425_MCU_VBASE, IXP425_MCU_HWBASE, IXP425_MCU_SIZE,
+      VM_PROT_READ|VM_PROT_WRITE, PTE_DEVICE, },
+
+	/* PCI Memory Space */
+    { IXP425_PCI_MEM_VBASE, IXP425_PCI_MEM_HWBASE, IXP425_PCI_MEM_SIZE,
+      VM_PROT_READ|VM_PROT_WRITE, PTE_DEVICE, },
+
+	/* Q-Mgr Memory Space */
+    { IXP425_QMGR_VBASE, IXP425_QMGR_HWBASE, IXP425_QMGR_SIZE,
+      VM_PROT_READ|VM_PROT_WRITE, PTE_DEVICE, },
+
+    { 0 },
+};
+
+/* Static device mappings. */
+static const struct arm_devmap_entry ixp435_devmap[] = {
+	/* Physical/Virtual address for I/O space */
+    { IXP425_IO_VBASE, IXP425_IO_HWBASE, IXP425_IO_SIZE,
+      VM_PROT_READ|VM_PROT_WRITE, PTE_DEVICE, },
+
+    { IXP425_EXP_VBASE, IXP425_EXP_HWBASE, IXP425_EXP_SIZE,
+      VM_PROT_READ|VM_PROT_WRITE, PTE_DEVICE, },
+
+	/* IXP425 PCI Configuration */
+    { IXP425_PCI_VBASE, IXP425_PCI_HWBASE, IXP425_PCI_SIZE,
+      VM_PROT_READ|VM_PROT_WRITE, PTE_DEVICE, },
+
+	/* DDRII Controller NB: mapped same place as IXP425 */
+    { IXP425_MCU_VBASE, IXP435_MCU_HWBASE, IXP425_MCU_SIZE,
+      VM_PROT_READ|VM_PROT_WRITE, PTE_DEVICE, },
+
+	/* PCI Memory Space */
+    { IXP425_PCI_MEM_VBASE, IXP425_PCI_MEM_HWBASE, IXP425_PCI_MEM_SIZE,
+      VM_PROT_READ|VM_PROT_WRITE, PTE_DEVICE, },
+
+	/* Q-Mgr Memory Space */
+    { IXP425_QMGR_VBASE, IXP425_QMGR_HWBASE, IXP425_QMGR_SIZE,
+      VM_PROT_READ|VM_PROT_WRITE, PTE_DEVICE, },
+
+	/* CFI Flash on the Expansion Bus */
+    { IXP425_EXP_BUS_CS0_VBASE, IXP425_EXP_BUS_CS0_HWBASE,
+      IXP425_EXP_BUS_CS0_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_DEVICE, },
+
+	/* USB1 Memory Space */
+    { IXP435_USB1_VBASE, IXP435_USB1_HWBASE, IXP435_USB1_SIZE,
+      VM_PROT_READ|VM_PROT_WRITE, PTE_DEVICE, },
+	/* USB2 Memory Space */
+    { IXP435_USB2_VBASE, IXP435_USB2_HWBASE, IXP435_USB2_SIZE,
+      VM_PROT_READ|VM_PROT_WRITE, PTE_DEVICE, },
+
+	/* GPS Memory Space */
+    { CAMBRIA_GPS_VBASE, CAMBRIA_GPS_HWBASE, CAMBRIA_GPS_SIZE,
+      VM_PROT_READ|VM_PROT_WRITE, PTE_DEVICE, },
+
+	/* RS485 Memory Space */
+    { CAMBRIA_RS485_VBASE, CAMBRIA_RS485_HWBASE, CAMBRIA_RS485_SIZE,
+      VM_PROT_READ|VM_PROT_WRITE, PTE_DEVICE, },
+
+    { 0 }
+};
+
+extern vm_offset_t xscale_cache_clean_addr;
+
+void *
+initarm(struct arm_boot_params *abp)
+{
+#define	next_chunk2(a,b)	(((a) + (b)) &~ ((b)-1))
+#define	next_page(a)		next_chunk2(a,PAGE_SIZE)
+	struct pv_addr  kernel_l1pt;
+	struct pv_addr  dpcpu;
+	int loop, i;
+	u_int l1pagetable;
+	vm_offset_t freemempos;
+	vm_offset_t freemem_pt;
+	vm_offset_t afterkern;
+	vm_offset_t freemem_after;
+	vm_offset_t lastaddr;
+	uint32_t memsize;
+
+	/* kernel text starts where we were loaded at boot */
+#define	KERNEL_TEXT_OFF		(abp->abp_physaddr  - PHYSADDR)
+#define	KERNEL_TEXT_BASE	(KERNBASE + KERNEL_TEXT_OFF)
+#define	KERNEL_TEXT_PHYS	(PHYSADDR + KERNEL_TEXT_OFF)
+
+	lastaddr = parse_boot_param(abp);
+	arm_physmem_kernaddr = abp->abp_physaddr;
+	set_cpufuncs();		/* NB: sets cputype */
+	pcpu_init(pcpup, 0, sizeof(struct pcpu));
+	PCPU_SET(curthread, &thread0);
+
+	init_static_kenv(NULL, 0);
+
+	/* Do basic tuning, hz etc */
+      	init_param1();
+		
+	/*
+	 * We allocate memory downwards from where we were loaded
+	 * by RedBoot; first the L1 page table, then NUM_KERNEL_PTS
+	 * entries in the L2 page table.  Past that we re-align the
+	 * allocation boundary so later data structures (stacks, etc)
+	 * can be mapped with different attributes (write-back vs
+	 * write-through).  Note this leaves a gap for expansion
+	 * (or might be repurposed).
+	 */
+	freemempos = abp->abp_physaddr;
+
+	/* macros to simplify initial memory allocation */
+#define alloc_pages(var, np) do {					\
+	freemempos -= (np * PAGE_SIZE);					\
+	(var) = freemempos;						\
+	/* NB: this works because locore maps PA=VA */			\
+	memset((char *)(var), 0, ((np) * PAGE_SIZE));			\
+} while (0)
+#define	valloc_pages(var, np) do {					\
+	alloc_pages((var).pv_pa, (np));					\
+	(var).pv_va = (var).pv_pa + (KERNVIRTADDR - abp->abp_physaddr);	\
+} while (0)
+
+	/* force L1 page table alignment */
+	while (((freemempos - L1_TABLE_SIZE) & (L1_TABLE_SIZE - 1)) != 0)
+		freemempos -= PAGE_SIZE;
+	/* allocate contiguous L1 page table */
+	valloc_pages(kernel_l1pt, L1_TABLE_SIZE / PAGE_SIZE);
+	/* now allocate L2 page tables; they are linked to L1 below */
+	for (loop = 0; loop < NUM_KERNEL_PTS; ++loop) {
+		if (!(loop % (PAGE_SIZE / L2_TABLE_SIZE_REAL))) {
+			valloc_pages(kernel_pt_table[loop],
+			    L2_TABLE_SIZE / PAGE_SIZE);
+		} else {
+			kernel_pt_table[loop].pv_pa = freemempos +
+			    (loop % (PAGE_SIZE / L2_TABLE_SIZE_REAL)) *
+			    L2_TABLE_SIZE_REAL;
+			kernel_pt_table[loop].pv_va =
+			    kernel_pt_table[loop].pv_pa +
+				(KERNVIRTADDR - abp->abp_physaddr);
+		}
+	}
+	freemem_pt = freemempos;		/* base of allocated pt's */
+
+	/*
+	 * Re-align allocation boundary so we can map the area
+	 * write-back instead of write-through for the stacks and
+	 * related structures allocated below.
+	 */
+	freemempos = PHYSADDR + 0x100000;
+	/*
+	 * Allocate a page for the system page mapped to V0x00000000
+	 * This page will just contain the system vectors and can be
+	 * shared by all processes.
+	 */
+	valloc_pages(systempage, 1);
+
+	/* Allocate dynamic per-cpu area. */
+	valloc_pages(dpcpu, DPCPU_SIZE / PAGE_SIZE);
+	dpcpu_init((void *)dpcpu.pv_va, 0);
+
+	/* Allocate stacks for all modes */
+	valloc_pages(irqstack, IRQ_STACK_SIZE);
+	valloc_pages(abtstack, ABT_STACK_SIZE);
+	valloc_pages(undstack, UND_STACK_SIZE);
+	valloc_pages(kernelstack, KSTACK_PAGES);
+	alloc_pages(minidataclean.pv_pa, 1);
+	valloc_pages(msgbufpv, round_page(msgbufsize) / PAGE_SIZE);
+
+	/*
+	 * Now construct the L1 page table.  First map the L2
+	 * page tables into the L1 so we can replace L1 mappings
+	 * later on if necessary
+	 */
+	l1pagetable = kernel_l1pt.pv_va;
+
+	/* Map the L2 pages tables in the L1 page table */
+	pmap_link_l2pt(l1pagetable, ARM_VECTORS_HIGH & ~(0x00100000 - 1),
+	    &kernel_pt_table[KERNEL_PT_SYS]);
+	pmap_link_l2pt(l1pagetable, IXP425_IO_VBASE,
+	    &kernel_pt_table[KERNEL_PT_IO]);
+	pmap_link_l2pt(l1pagetable, IXP425_MCU_VBASE,
+	    &kernel_pt_table[KERNEL_PT_IO + 1]);
+	pmap_link_l2pt(l1pagetable, IXP425_PCI_MEM_VBASE,
+	    &kernel_pt_table[KERNEL_PT_IO + 2]);
+	pmap_link_l2pt(l1pagetable, KERNBASE,
+	    &kernel_pt_table[KERNEL_PT_BEFOREKERN]);
+	pmap_map_chunk(l1pagetable, KERNBASE, PHYSADDR, 0x100000,
+	    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+	pmap_map_chunk(l1pagetable, KERNBASE + 0x100000, PHYSADDR + 0x100000,
+	    0x100000, VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE);
+	pmap_map_chunk(l1pagetable, KERNEL_TEXT_BASE, KERNEL_TEXT_PHYS,
+	    next_chunk2(((uint32_t)lastaddr) - KERNEL_TEXT_BASE, L1_S_SIZE),
+	    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+	freemem_after = next_page((int)lastaddr);
+	afterkern = round_page(next_chunk2((vm_offset_t)lastaddr, L1_S_SIZE));
+	for (i = 0; i < KERNEL_PT_AFKERNEL_NUM; i++) {
+		pmap_link_l2pt(l1pagetable, afterkern + i * 0x00100000,
+		    &kernel_pt_table[KERNEL_PT_AFKERNEL + i]);
+	}
+	pmap_map_entry(l1pagetable, afterkern, minidataclean.pv_pa,
+	    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+
+
+	/* Map the Mini-Data cache clean area. */
+	xscale_setup_minidata(l1pagetable, afterkern,
+	    minidataclean.pv_pa);
+
+	/* Map the vector page. */
+	pmap_map_entry(l1pagetable, ARM_VECTORS_HIGH, systempage.pv_pa,
+	    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+	if (cpu_is_ixp43x())
+		arm_devmap_bootstrap(l1pagetable, ixp435_devmap);
+	else
+		arm_devmap_bootstrap(l1pagetable, ixp425_devmap);
+	/*
+	 * Give the XScale global cache clean code an appropriately
+	 * sized chunk of unmapped VA space starting at 0xff000000
+	 * (our device mappings end before this address).
+	 */
+	xscale_cache_clean_addr = 0xff000000U;
+
+	cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT);
+	setttb(kernel_l1pt.pv_pa);
+	cpu_tlb_flushID();
+	cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2));
+
+	/*
+	 * Pages were allocated during the secondary bootstrap for the
+	 * stacks for different CPU modes.
+	 * We must now set the r13 registers in the different CPU modes to
+	 * point to these stacks.
+	 * Since the ARM stacks use STMFD etc. we must set r13 to the top end
+	 * of the stack memory.
+	 */
+	set_stackptrs(0);
+
+	/*
+	 * We must now clean the cache again....
+	 * Cleaning may be done by reading new data to displace any
+	 * dirty data in the cache. This will have happened in setttb()
+	 * but since we are boot strapping the addresses used for the read
+	 * may have just been remapped and thus the cache could be out
+	 * of sync. A re-clean after the switch will cure this.
+	 * After booting there are no gross relocations of the kernel thus
+	 * this problem will not occur after initarm().
+	 */
+	cpu_idcache_wbinv_all();
+	cpu_setup("");
+
+	/* ready to setup the console (XXX move earlier if possible) */
+	cninit();
+	/*
+	 * Fetch the RAM size from the MCU registers.  The
+	 * expansion bus was mapped above so we can now read 'em.
+	 */
+	if (cpu_is_ixp43x())
+		memsize = ixp435_ddram_size();
+	else
+		memsize = ixp425_sdram_size();
+
+	undefined_init();
+
+	init_proc0(kernelstack.pv_va);
+
+	arm_vector_init(ARM_VECTORS_HIGH, ARM_VEC_ALL);
+
+	pmap_curmaxkvaddr = afterkern + PAGE_SIZE;
+	vm_max_kernel_address = 0xd0000000;
+	pmap_bootstrap(pmap_curmaxkvaddr, &kernel_l1pt);
+	msgbufp = (void*)msgbufpv.pv_va;
+	msgbufinit(msgbufp, msgbufsize);
+	mutex_init();
+
+	/*
+	 * Add the physical ram we have available.
+	 *
+	 * Exclude the kernel, and all the things we allocated which immediately
+	 * follow the kernel, from the VM allocation pool but not from crash
+	 * dumps.  virtual_avail is a global variable which tracks the kva we've
+	 * "allocated" while setting up pmaps.
+	 *
+	 * Prepare the list of physical memory available to the vm subsystem.
+	 */
+	arm_physmem_hardware_region(PHYSADDR, memsize);
+	arm_physmem_exclude_region(abp->abp_physaddr, 
+	    virtual_avail - KERNVIRTADDR, EXFLAG_NOALLOC);
+	arm_physmem_init_kernel_globals();
+
+	init_param2(physmem);
+	kdb_init();
+
+	return ((void *)(kernelstack.pv_va + USPACE_SVC_STACK_TOP -
+	    sizeof(struct pcb)));
+#undef next_page
+#undef next_chunk2
+}


Property changes on: trunk/sys/arm/xscale/ixp425/avila_machdep.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/ixp425/cambria_exp_space.c
===================================================================
--- trunk/sys/arm/xscale/ixp425/cambria_exp_space.c	                        (rev 0)
+++ trunk/sys/arm/xscale/ixp425/cambria_exp_space.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,259 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2009 Sam Leffler.  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 ``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 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.
+ */
+
+/*
+ * Bus space tag for devices on the Cambria expansion bus.
+ * This interlocks accesses to allow the optional GPS+RS485 UART's
+ * to share access with the CF-IDE adapter.  Note this does not
+ * slow the timing UART r/w ops because the lock operation does
+ * this implicitly for us.  Also note we do not DELAY after byte/word
+ * chip select changes; this doesn't seem necessary (as required
+ * for IXP425/Avila boards).
+ *
+ * XXX should make this generic so all expansion bus devices can
+ * use it but probably not until we eliminate the ATA hacks
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/xscale/ixp425/cambria_exp_space.c 278727 2015-02-13 22:32:02Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/bus.h>
+#include <sys/endian.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+
+#include <arm/xscale/ixp425/ixp425reg.h>
+#include <arm/xscale/ixp425/ixp425var.h>
+
+/* Prototypes for all the bus_space structure functions */
+bs_protos(exp);
+bs_protos(generic);
+
+struct expbus_softc {
+	struct ixp425_softc *sc;	/* bus space tag */
+	struct mtx	lock;		/* i/o interlock */
+	bus_size_t	csoff;		/* CS offset for 8/16 enable */
+};
+#define	EXP_LOCK_INIT(exp) \
+	mtx_init(&(exp)->lock, "ExpBus", NULL, MTX_SPIN)
+#define	EXP_LOCK_DESTROY(exp) \
+	mtx_destroy(&(exp)->lock)
+#define	EXP_LOCK(exp)	mtx_lock_spin(&(exp)->lock)
+#define	EXP_UNLOCK(exp)	mtx_unlock_spin(&(exp)->lock)
+
+/*
+ * Enable/disable 16-bit ops on the expansion bus.
+ */
+static __inline void
+enable_16(struct ixp425_softc *sc, bus_size_t cs)
+{
+	EXP_BUS_WRITE_4(sc, cs, EXP_BUS_READ_4(sc, cs) &~ EXP_BYTE_EN);
+}
+
+static __inline void
+disable_16(struct ixp425_softc *sc, bus_size_t cs)
+{
+	EXP_BUS_WRITE_4(sc, cs, EXP_BUS_READ_4(sc, cs) | EXP_BYTE_EN);
+}
+
+static uint8_t
+cambria_bs_r_1(bus_space_tag_t tag, bus_space_handle_t h, bus_size_t o)
+{
+	struct expbus_softc *exp = tag->bs_privdata;
+	struct ixp425_softc *sc = exp->sc;
+	uint8_t v;
+
+	EXP_LOCK(exp);
+	v = bus_space_read_1(sc->sc_iot, h, o);
+	EXP_UNLOCK(exp);
+	return v;
+}
+
+static void
+cambria_bs_w_1(bus_space_tag_t tag, bus_space_handle_t h, bus_size_t o, u_int8_t v)
+{
+	struct expbus_softc *exp = tag->bs_privdata;
+	struct ixp425_softc *sc = exp->sc;
+
+	EXP_LOCK(exp);
+	bus_space_write_1(sc->sc_iot, h, o, v);
+	EXP_UNLOCK(exp);
+}
+
+static uint16_t
+cambria_bs_r_2(bus_space_tag_t tag, bus_space_handle_t h, bus_size_t o)
+{
+	struct expbus_softc *exp = tag->bs_privdata;
+	struct ixp425_softc *sc = exp->sc;
+	uint16_t v;
+
+	EXP_LOCK(exp);
+	enable_16(sc, exp->csoff);
+	v = bus_space_read_2(sc->sc_iot, h, o);
+	disable_16(sc, exp->csoff);
+	EXP_UNLOCK(exp);
+	return v;
+}
+
+static void
+cambria_bs_w_2(bus_space_tag_t tag, bus_space_handle_t h, bus_size_t o, uint16_t v)
+{
+	struct expbus_softc *exp = tag->bs_privdata;
+	struct ixp425_softc *sc = exp->sc;
+
+	EXP_LOCK(exp);
+	enable_16(sc, exp->csoff);
+	bus_space_write_2(sc->sc_iot, h, o, v);
+	disable_16(sc, exp->csoff);
+	EXP_UNLOCK(exp);
+}
+
+static void
+cambria_bs_rm_2(bus_space_tag_t tag, bus_space_handle_t h, bus_size_t o,
+	u_int16_t *d, bus_size_t c)
+{
+	struct expbus_softc *exp = tag->bs_privdata;
+	struct ixp425_softc *sc = exp->sc;
+
+	EXP_LOCK(exp);
+	enable_16(sc, exp->csoff);
+	bus_space_read_multi_2(sc->sc_iot, h, o, d, c);
+	disable_16(sc, exp->csoff);
+	EXP_UNLOCK(exp);
+}
+
+static void
+cambria_bs_wm_2(bus_space_tag_t tag, bus_space_handle_t h, bus_size_t o,
+	const u_int16_t *d, bus_size_t c)
+{
+	struct expbus_softc *exp = tag->bs_privdata;
+	struct ixp425_softc *sc = exp->sc;
+
+	EXP_LOCK(exp);
+	enable_16(sc, exp->csoff);
+	bus_space_write_multi_2(sc->sc_iot, h, o, d, c);
+	disable_16(sc, exp->csoff);
+	EXP_UNLOCK(exp);
+}
+
+/* XXX workaround ata driver by (incorrectly) byte swapping stream cases */
+
+static void
+cambria_bs_rm_2_s(bus_space_tag_t tag, bus_space_handle_t h, bus_size_t o,
+	u_int16_t *d, bus_size_t c)
+{
+	struct expbus_softc *exp = tag->bs_privdata;
+	struct ixp425_softc *sc = exp->sc;
+	uint16_t v;
+	bus_size_t i;
+
+	EXP_LOCK(exp);
+	enable_16(sc, exp->csoff);
+#if 1
+	for (i = 0; i < c; i++) {
+		v = bus_space_read_2(sc->sc_iot, h, o);
+		d[i] = bswap16(v);
+	}
+#else
+	bus_space_read_multi_stream_2(sc->sc_iot, h, o, d, c);
+#endif
+	disable_16(sc, exp->csoff);
+	EXP_UNLOCK(exp);
+}
+
+static void
+cambria_bs_wm_2_s(bus_space_tag_t tag, bus_space_handle_t h, bus_size_t o,
+	const u_int16_t *d, bus_size_t c)
+{
+	struct expbus_softc *exp = tag->bs_privdata;
+	struct ixp425_softc *sc = exp->sc;
+	bus_size_t i;
+
+	EXP_LOCK(exp);
+	enable_16(sc, exp->csoff);
+#if 1
+	for (i = 0; i < c; i++)
+		bus_space_write_2(sc->sc_iot, h, o, bswap16(d[i]));
+#else
+	bus_space_write_multi_stream_2(sc->sc_iot, h, o, d, c);
+#endif
+	disable_16(sc, exp->csoff);
+	EXP_UNLOCK(exp);
+}
+
+/* NB: we only define what's needed by ata+uart */
+struct bus_space cambria_exp_bs_tag = {
+	/* mapping/unmapping */
+	.bs_map		= generic_bs_map,
+	.bs_unmap	= generic_bs_unmap,
+
+	/* barrier */
+	.bs_barrier	= generic_bs_barrier,
+
+	/* read (single) */
+	.bs_r_1		= cambria_bs_r_1,
+	.bs_r_2		= cambria_bs_r_2,
+
+	/* write (single) */
+	.bs_w_1		= cambria_bs_w_1,
+	.bs_w_2		= cambria_bs_w_2,
+
+	/* read multiple */
+	.bs_rm_2	= cambria_bs_rm_2,
+	.bs_rm_2_s	= cambria_bs_rm_2_s,
+
+	/* write multiple */
+	.bs_wm_2	= cambria_bs_wm_2,
+	.bs_wm_2_s	= cambria_bs_wm_2_s,
+};
+
+void
+cambria_exp_bus_init(struct ixp425_softc *sc)
+{
+	static struct expbus_softc c3;		/* NB: no need to malloc */
+	uint32_t cs3;
+
+	KASSERT(cpu_is_ixp43x(), ("wrong cpu type"));
+
+	c3.sc = sc;
+	c3.csoff = EXP_TIMING_CS3_OFFSET;
+	EXP_LOCK_INIT(&c3);
+	cambria_exp_bs_tag.bs_privdata = &c3;
+
+	cs3 = EXP_BUS_READ_4(sc, EXP_TIMING_CS3_OFFSET);
+	/* XXX force slowest possible timings and byte mode */
+	EXP_BUS_WRITE_4(sc, EXP_TIMING_CS3_OFFSET,
+	    cs3 | (EXP_T1|EXP_T2|EXP_T3|EXP_T4|EXP_T5) |
+	        EXP_BYTE_EN | EXP_WR_EN | EXP_BYTE_RD16 | EXP_CS_EN);
+
+	/* XXX force GPIO 3+4 for GPS+RS485 uarts */
+	ixp425_set_gpio(sc, 3, GPIO_TYPE_EDG_RISING);
+	ixp425_set_gpio(sc, 4, GPIO_TYPE_EDG_RISING);
+}


Property changes on: trunk/sys/arm/xscale/ixp425/cambria_exp_space.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/ixp425/cambria_fled.c
===================================================================
--- trunk/sys/arm/xscale/ixp425/cambria_fled.c	                        (rev 0)
+++ trunk/sys/arm/xscale/ixp425/cambria_fled.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,111 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2008 Sam Leffler.  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 ``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 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: stable/10/sys/arm/xscale/ixp425/cambria_fled.c 205705 2010-03-26 18:49:43Z rpaulo $");
+/*
+ * Cambria Front Panel LED sitting on the I2C bus.
+ */
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+
+#include <machine/bus.h>
+
+#include <dev/iicbus/iiconf.h>
+#include <dev/led/led.h>
+
+#include "iicbus_if.h"
+
+#define	IIC_M_WR	0	/* write operation */
+#define	LED_ADDR	0xae	/* slave address */
+
+struct fled_softc {
+	struct cdev	*sc_led;
+};
+
+static int
+fled_probe(device_t dev)
+{
+	device_set_desc(dev, "Gateworks Cambria Front Panel LED");
+	return 0;
+}
+
+static void
+fled_cb(void *arg, int onoff)
+{
+	uint8_t data[1];
+	struct iic_msg msgs[1] = {
+	     { LED_ADDR, IIC_M_WR, 1, data },
+	};
+	device_t dev = arg;
+
+	data[0] = (onoff == 0);		/* NB: low true */
+	(void) iicbus_transfer(dev, msgs, 1);
+}
+
+static int
+fled_attach(device_t dev)
+{
+	struct fled_softc *sc = device_get_softc(dev);
+
+	sc->sc_led = led_create(fled_cb, dev, "front");
+
+	fled_cb(dev, 1);		/* Turn on LED */
+
+	return 0;
+}
+
+static int
+fled_detach(device_t dev)
+{
+	struct fled_softc *sc = device_get_softc(dev);
+
+	if (sc->sc_led != NULL)
+		led_destroy(sc->sc_led);
+
+	return 0;
+}
+
+static device_method_t fled_methods[] = {
+	DEVMETHOD(device_probe,		fled_probe),
+	DEVMETHOD(device_attach,	fled_attach),
+	DEVMETHOD(device_detach,	fled_detach),
+
+	{0, 0},
+};
+
+static driver_t fled_driver = {
+	"fled",
+	fled_methods,
+	sizeof(struct fled_softc),
+};
+static devclass_t fled_devclass;
+
+DRIVER_MODULE(fled, iicbus, fled_driver, fled_devclass, 0, 0);
+MODULE_VERSION(fled, 1);
+MODULE_DEPEND(fled, iicbus, 1, 1, 1);


Property changes on: trunk/sys/arm/xscale/ixp425/cambria_fled.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/ixp425/cambria_gpio.c
===================================================================
--- trunk/sys/arm/xscale/ixp425/cambria_gpio.c	                        (rev 0)
+++ trunk/sys/arm/xscale/ixp425/cambria_gpio.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,492 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2010, Andrew Thompson <thompsa at FreeBSD.org>
+ * 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 unmodified, 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.
+ */
+
+/*
+ * GPIO driver for Gateworks Cambria
+ *
+ * Note:
+ * The Cambria PLD does not set the i2c ack bit after each write, if we used the
+ * regular iicbus interface it would abort the xfer after the address byte
+ * times out and not write our latch. To get around this we grab the iicbus and
+ * then do our own bit banging. This is a comprimise to changing all the iicbb
+ * device methods to allow a flag to be passed down and is similir to how Linux
+ * does it.
+ *
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/xscale/ixp425/cambria_gpio.c 278786 2015-02-14 21:16:19Z loos $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/rman.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/gpio.h>
+
+#include <arm/xscale/ixp425/ixp425reg.h>
+#include <arm/xscale/ixp425/ixp425var.h>
+#include <arm/xscale/ixp425/ixdp425reg.h>
+
+#include <dev/iicbus/iiconf.h>
+#include <dev/iicbus/iicbus.h>
+
+#include "iicbb_if.h"
+#include "gpio_if.h"
+
+#define	IIC_M_WR	0	/* write operation */
+#define	PLD_ADDR	0xac	/* slave address */
+
+#define	I2C_DELAY	10
+
+#define	GPIO_CONF_CLR(sc, reg, mask)	\
+	GPIO_CONF_WRITE_4(sc, reg, GPIO_CONF_READ_4(sc, reg) &~ (mask))
+#define	GPIO_CONF_SET(sc, reg, mask)	\
+	GPIO_CONF_WRITE_4(sc, reg, GPIO_CONF_READ_4(sc, reg) | (mask))
+
+#define	GPIO_LOCK(_sc)		mtx_lock(&(_sc)->sc_mtx)
+#define	GPIO_UNLOCK(_sc)	mtx_unlock(&(_sc)->sc_mtx)
+#define	GPIO_LOCK_ASSERT(_sc)	mtx_assert(&(_sc)->sc_mtx, MA_OWNED)
+
+#define	GPIO_PINS		5
+struct cambria_gpio_softc {
+	device_t		sc_dev;
+	bus_space_tag_t		sc_iot;
+	bus_space_handle_t	sc_gpio_ioh;
+        struct mtx		sc_mtx;
+	struct gpio_pin		sc_pins[GPIO_PINS];
+	uint8_t			sc_latch;
+	uint8_t			sc_val;
+};
+
+struct cambria_gpio_pin {
+	const char *name;
+	int pin;
+	int flags;
+};
+
+extern struct ixp425_softc *ixp425_softc;
+
+static struct cambria_gpio_pin cambria_gpio_pins[GPIO_PINS] = {
+	{ "PLD0", 0, GPIO_PIN_OUTPUT },
+	{ "PLD1", 1, GPIO_PIN_OUTPUT },
+	{ "PLD2", 2, GPIO_PIN_OUTPUT },
+	{ "PLD3", 3, GPIO_PIN_OUTPUT },
+	{ "PLD4", 4, GPIO_PIN_OUTPUT },
+};
+
+/*
+ * Helpers
+ */
+static int cambria_gpio_read(struct cambria_gpio_softc *, uint32_t, unsigned int *);
+static int cambria_gpio_write(struct cambria_gpio_softc *);
+
+/*
+ * Driver stuff
+ */
+static int cambria_gpio_probe(device_t dev);
+static int cambria_gpio_attach(device_t dev);
+static int cambria_gpio_detach(device_t dev);
+
+/*
+ * GPIO interface
+ */
+static int cambria_gpio_pin_max(device_t dev, int *maxpin);
+static int cambria_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps);
+static int cambria_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t
+    *flags);
+static int cambria_gpio_pin_getname(device_t dev, uint32_t pin, char *name);
+static int cambria_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags);
+static int cambria_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value);
+static int cambria_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val);
+static int cambria_gpio_pin_toggle(device_t dev, uint32_t pin);
+
+static int
+i2c_getsda(struct cambria_gpio_softc *sc)
+{
+	uint32_t reg;
+
+	IXP4XX_GPIO_LOCK();
+	GPIO_CONF_SET(sc, IXP425_GPIO_GPOER, GPIO_I2C_SDA_BIT);
+
+	reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPINR);
+	IXP4XX_GPIO_UNLOCK();
+	return (reg & GPIO_I2C_SDA_BIT);
+}
+
+static void
+i2c_setsda(struct cambria_gpio_softc *sc, int val)
+{
+
+	IXP4XX_GPIO_LOCK();
+	GPIO_CONF_CLR(sc, IXP425_GPIO_GPOUTR, GPIO_I2C_SDA_BIT);
+	if (val)
+		GPIO_CONF_SET(sc, IXP425_GPIO_GPOER, GPIO_I2C_SDA_BIT);
+	else
+		GPIO_CONF_CLR(sc, IXP425_GPIO_GPOER, GPIO_I2C_SDA_BIT);
+	IXP4XX_GPIO_UNLOCK();
+	DELAY(I2C_DELAY);
+}
+
+static void
+i2c_setscl(struct cambria_gpio_softc *sc, int val)
+{
+
+	IXP4XX_GPIO_LOCK();
+	GPIO_CONF_CLR(sc, IXP425_GPIO_GPOUTR, GPIO_I2C_SCL_BIT);
+	if (val)
+		GPIO_CONF_SET(sc, IXP425_GPIO_GPOER, GPIO_I2C_SCL_BIT);
+	else
+		GPIO_CONF_CLR(sc, IXP425_GPIO_GPOER, GPIO_I2C_SCL_BIT);
+	IXP4XX_GPIO_UNLOCK();
+	DELAY(I2C_DELAY);
+}
+
+static void
+i2c_sendstart(struct cambria_gpio_softc *sc)
+{
+	i2c_setsda(sc, 1);
+	i2c_setscl(sc, 1);
+	i2c_setsda(sc, 0);
+	i2c_setscl(sc, 0);
+}
+
+static void
+i2c_sendstop(struct cambria_gpio_softc *sc)
+{
+	i2c_setscl(sc, 1);
+	i2c_setsda(sc, 1);
+	i2c_setscl(sc, 0);
+	i2c_setsda(sc, 0);
+}
+
+static void
+i2c_sendbyte(struct cambria_gpio_softc *sc, u_char data)
+{
+	int i;
+
+	for (i=7; i>=0; i--) {
+		i2c_setsda(sc, data & (1<<i));
+		i2c_setscl(sc, 1);
+		i2c_setscl(sc, 0);
+	}
+	i2c_setscl(sc, 1);
+	i2c_getsda(sc);
+	i2c_setscl(sc, 0);
+}
+
+static u_char
+i2c_readbyte(struct cambria_gpio_softc *sc)
+{
+	int i;
+	unsigned char data=0;
+
+	for (i=7; i>=0; i--)
+	{
+		i2c_setscl(sc, 1);
+		if (i2c_getsda(sc))
+			data |= (1<<i);
+		i2c_setscl(sc, 0);
+	}
+	return data;
+}
+
+static int
+cambria_gpio_read(struct cambria_gpio_softc *sc, uint32_t pin, unsigned int *val)
+{
+	device_t dev = sc->sc_dev;
+	int error;
+
+	error = iicbus_request_bus(device_get_parent(dev), dev,
+	    IIC_DONTWAIT);
+	if (error)
+		return (error);
+
+	i2c_sendstart(sc);
+	i2c_sendbyte(sc, PLD_ADDR | LSB);
+	*val = (i2c_readbyte(sc) & (1 << pin)) != 0;
+	i2c_sendstop(sc);
+
+	iicbus_release_bus(device_get_parent(dev), dev);
+
+	return (0);
+}
+
+static int
+cambria_gpio_write(struct cambria_gpio_softc *sc)
+{
+	device_t dev = sc->sc_dev;
+	int error;
+
+	error = iicbus_request_bus(device_get_parent(dev), dev,
+	    IIC_DONTWAIT);
+	if (error)
+		return (error);
+
+	i2c_sendstart(sc);
+	i2c_sendbyte(sc, PLD_ADDR & ~LSB);
+	i2c_sendbyte(sc, sc->sc_latch);
+	i2c_sendstop(sc);
+
+	iicbus_release_bus(device_get_parent(dev), dev);
+
+	return (0);
+}
+
+static int
+cambria_gpio_pin_max(device_t dev, int *maxpin)
+{
+
+	*maxpin = GPIO_PINS - 1;
+	return (0);
+}
+
+static int
+cambria_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
+{
+	struct cambria_gpio_softc *sc = device_get_softc(dev);
+
+	if (pin >= GPIO_PINS)
+		return (EINVAL);
+
+	*caps = sc->sc_pins[pin].gp_caps;
+	return (0);
+}
+
+static int
+cambria_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
+{
+	struct cambria_gpio_softc *sc = device_get_softc(dev);
+
+	if (pin >= GPIO_PINS)
+		return (EINVAL);
+
+	*flags = sc->sc_pins[pin].gp_flags;
+	return (0);
+}
+
+static int
+cambria_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
+{
+	struct cambria_gpio_softc *sc = device_get_softc(dev);
+
+	if (pin >= GPIO_PINS)
+		return (EINVAL);
+
+	memcpy(name, sc->sc_pins[pin].gp_name, GPIOMAXNAME);
+	return (0);
+}
+
+static int
+cambria_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
+{
+	struct cambria_gpio_softc *sc = device_get_softc(dev);
+	int error;
+	uint8_t mask;
+
+	mask = 1 << pin;
+
+	if (pin >= GPIO_PINS)
+		return (EINVAL);
+
+	GPIO_LOCK(sc);
+	sc->sc_pins[pin].gp_flags = flags;
+
+	/*
+	 * Writing a logical one sets the signal high and writing a logical
+	 * zero sets the signal low. To configure a digital I/O signal as an
+	 * input, a logical one must first be written to the data bit to
+	 * three-state the associated output.
+	 */
+	if (flags & GPIO_PIN_INPUT || sc->sc_val & mask)
+		sc->sc_latch |= mask; /* input or output & high */
+	else
+		sc->sc_latch &= ~mask;
+	error = cambria_gpio_write(sc);
+	GPIO_UNLOCK(sc);
+
+	return (error);
+}
+
+static int
+cambria_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value)
+{
+	struct cambria_gpio_softc *sc = device_get_softc(dev);
+	int error;
+	uint8_t mask;
+
+	mask = 1 << pin;
+
+	if (pin >= GPIO_PINS)
+		return (EINVAL);
+	GPIO_LOCK(sc);
+	if (value)
+		sc->sc_val |= mask;
+	else
+		sc->sc_val &= ~mask;
+
+	if (sc->sc_pins[pin].gp_flags != GPIO_PIN_OUTPUT) {
+		/* just save, altering the latch will disable input */
+		GPIO_UNLOCK(sc);
+		return (0);
+	}
+
+	if (value)
+		sc->sc_latch |= mask;
+	else
+		sc->sc_latch &= ~mask;
+	error = cambria_gpio_write(sc);
+	GPIO_UNLOCK(sc);
+
+	return (error);
+}
+
+static int
+cambria_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val)
+{
+	struct cambria_gpio_softc *sc = device_get_softc(dev);
+	int error = 0;
+
+	if (pin >= GPIO_PINS)
+		return (EINVAL);
+
+	GPIO_LOCK(sc);
+	if (sc->sc_pins[pin].gp_flags == GPIO_PIN_OUTPUT)
+		*val = (sc->sc_latch & (1 << pin)) ? 1 : 0;
+	else
+		error = cambria_gpio_read(sc, pin, val);
+	GPIO_UNLOCK(sc);
+
+	return (error);
+}
+
+static int
+cambria_gpio_pin_toggle(device_t dev, uint32_t pin)
+{
+	struct cambria_gpio_softc *sc = device_get_softc(dev);
+	int error = 0;
+
+	if (pin >= GPIO_PINS)
+		return (EINVAL);
+
+	GPIO_LOCK(sc);
+	sc->sc_val ^= (1 << pin);
+	if (sc->sc_pins[pin].gp_flags == GPIO_PIN_OUTPUT) {
+		sc->sc_latch ^= (1 << pin);
+		error = cambria_gpio_write(sc);
+	}
+	GPIO_UNLOCK(sc);
+
+	return (error);
+}
+
+static int
+cambria_gpio_probe(device_t dev)
+{
+
+	device_set_desc(dev, "Gateworks Cambria GPIO driver");
+	return (0);
+}
+
+static int
+cambria_gpio_attach(device_t dev)
+{
+	struct cambria_gpio_softc *sc = device_get_softc(dev);
+	int pin;
+
+	sc->sc_dev = dev;
+	sc->sc_iot = ixp425_softc->sc_iot;
+	sc->sc_gpio_ioh = ixp425_softc->sc_gpio_ioh;
+
+	mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL, MTX_DEF);
+
+	for (pin = 0; pin < GPIO_PINS; pin++) {
+		struct cambria_gpio_pin *p = &cambria_gpio_pins[pin];
+
+		strncpy(sc->sc_pins[pin].gp_name, p->name, GPIOMAXNAME);
+		sc->sc_pins[pin].gp_pin = pin;
+		sc->sc_pins[pin].gp_caps = GPIO_PIN_INPUT|GPIO_PIN_OUTPUT;
+		sc->sc_pins[pin].gp_flags = 0;
+		cambria_gpio_pin_setflags(dev, pin, p->flags);
+	}
+
+	device_add_child(dev, "gpioc", -1);
+	device_add_child(dev, "gpiobus", -1);
+
+	return (bus_generic_attach(dev));
+}
+
+static int
+cambria_gpio_detach(device_t dev)
+{
+	struct cambria_gpio_softc *sc = device_get_softc(dev);
+
+	KASSERT(mtx_initialized(&sc->sc_mtx), ("gpio mutex not initialized"));
+
+	bus_generic_detach(dev);
+
+	mtx_destroy(&sc->sc_mtx);
+
+	return(0);
+}
+
+static device_method_t cambria_gpio_methods[] = {
+	DEVMETHOD(device_probe, cambria_gpio_probe),
+	DEVMETHOD(device_attach, cambria_gpio_attach),
+	DEVMETHOD(device_detach, cambria_gpio_detach),
+
+	/* GPIO protocol */
+	DEVMETHOD(gpio_pin_max, cambria_gpio_pin_max),
+	DEVMETHOD(gpio_pin_getname, cambria_gpio_pin_getname),
+	DEVMETHOD(gpio_pin_getflags, cambria_gpio_pin_getflags),
+	DEVMETHOD(gpio_pin_getcaps, cambria_gpio_pin_getcaps),
+	DEVMETHOD(gpio_pin_setflags, cambria_gpio_pin_setflags),
+	DEVMETHOD(gpio_pin_get, cambria_gpio_pin_get),
+	DEVMETHOD(gpio_pin_set, cambria_gpio_pin_set),
+	DEVMETHOD(gpio_pin_toggle, cambria_gpio_pin_toggle),
+	{0, 0},
+};
+
+static driver_t cambria_gpio_driver = {
+	"gpio_cambria",
+	cambria_gpio_methods,
+	sizeof(struct cambria_gpio_softc),
+};
+static devclass_t cambria_gpio_devclass;
+extern devclass_t gpiobus_devclass, gpioc_devclass;
+extern driver_t gpiobus_driver, gpioc_driver;
+
+DRIVER_MODULE(gpio_cambria, iicbus, cambria_gpio_driver, cambria_gpio_devclass, 0, 0);
+DRIVER_MODULE(gpiobus, gpio_cambria, gpiobus_driver, gpiobus_devclass, 0, 0);
+DRIVER_MODULE(gpioc, gpio_cambria, gpioc_driver, gpioc_devclass, 0, 0);
+MODULE_VERSION(gpio_cambria, 1);
+MODULE_DEPEND(gpio_cambria, iicbus, 1, 1, 1);


Property changes on: trunk/sys/arm/xscale/ixp425/cambria_gpio.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/ixp425/cambria_led.c
===================================================================
--- trunk/sys/arm/xscale/ixp425/cambria_led.c	                        (rev 0)
+++ trunk/sys/arm/xscale/ixp425/cambria_led.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,134 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2008 Sam Leffler.  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 ``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 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: stable/10/sys/arm/xscale/ixp425/cambria_led.c 194015 2009-06-11 17:05:13Z avg $");
+
+/*
+ * Gateworks Cambria Octal LED Latch driver.
+ */
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+
+#include <machine/armreg.h>
+
+#include <arm/xscale/ixp425/ixp425reg.h>
+#include <arm/xscale/ixp425/ixp425var.h>
+
+#include <dev/led/led.h>
+
+struct led_softc {
+	device_t		sc_dev;
+	bus_space_tag_t		sc_iot;
+	bus_space_handle_t	sc_ioh;
+	struct cdev		*sc_leds[8];
+	uint8_t			sc_latch;
+};
+
+static void
+update_latch(struct led_softc *sc, int bit, int onoff)
+{
+	if (onoff)
+		sc->sc_latch &= ~bit;
+	else
+		sc->sc_latch |= bit;
+	bus_space_write_1(sc->sc_iot, sc->sc_ioh, 0, sc->sc_latch);
+}
+static void led_A(void *arg, int onoff) { update_latch(arg, 1<<0, onoff); }
+static void led_B(void *arg, int onoff) { update_latch(arg, 1<<1, onoff); }
+static void led_C(void *arg, int onoff) { update_latch(arg, 1<<2, onoff); }
+static void led_D(void *arg, int onoff) { update_latch(arg, 1<<3, onoff); }
+static void led_E(void *arg, int onoff) { update_latch(arg, 1<<4, onoff); }
+static void led_F(void *arg, int onoff) { update_latch(arg, 1<<5, onoff); }
+static void led_G(void *arg, int onoff) { update_latch(arg, 1<<6, onoff); }
+static void led_H(void *arg, int onoff) { update_latch(arg, 1<<7, onoff); }
+
+static int
+led_probe(device_t dev)
+{
+	device_set_desc(dev, "Gateworks Octal LED Latch");
+	return (0);
+}
+
+static int
+led_attach(device_t dev)
+{
+	struct led_softc *sc = device_get_softc(dev);
+	struct ixp425_softc *sa = device_get_softc(device_get_parent(dev));
+
+	sc->sc_dev = dev;
+	sc->sc_iot = sa->sc_iot;
+	/* NB: write anywhere works, use first location */
+	if (bus_space_map(sc->sc_iot, CAMBRIA_OCTAL_LED_HWBASE, sizeof(uint8_t),
+	    0, &sc->sc_ioh)) {
+		device_printf(dev, "cannot map LED latch (0x%lx)",
+		    CAMBRIA_OCTAL_LED_HWBASE);
+		return ENXIO;
+	}
+
+	sc->sc_leds[0] = led_create(led_A, sc, "A");
+	sc->sc_leds[1] = led_create(led_B, sc, "B");
+	sc->sc_leds[2] = led_create(led_C, sc, "C");
+	sc->sc_leds[3] = led_create(led_D, sc, "D");
+	sc->sc_leds[4] = led_create(led_E, sc, "E");
+	sc->sc_leds[5] = led_create(led_F, sc, "F");
+	sc->sc_leds[6] = led_create(led_G, sc, "G");
+	sc->sc_leds[7] = led_create(led_H, sc, "H");
+
+	return 0;
+}
+
+static int
+led_detach(device_t dev)
+{
+	struct led_softc *sc = device_get_softc(dev);
+	int i;
+
+	for (i = 0; i < 8; i++) {
+		struct cdev *led = sc->sc_leds[i];
+		if (led != NULL)
+			led_destroy(led);
+	}
+	return (0);
+}
+
+static device_method_t led_methods[] = {
+	DEVMETHOD(device_probe,		led_probe),
+	DEVMETHOD(device_attach,	led_attach),
+	DEVMETHOD(device_detach,	led_detach),
+
+	{0, 0},
+};
+
+static driver_t led_driver = {
+	"led_cambria",
+	led_methods,
+	sizeof(struct led_softc),
+};
+static devclass_t led_devclass;
+DRIVER_MODULE(led_cambria, ixp, led_driver, led_devclass, 0, 0);


Property changes on: trunk/sys/arm/xscale/ixp425/cambria_led.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/ixp425/files.avila
===================================================================
--- trunk/sys/arm/xscale/ixp425/files.avila	                        (rev 0)
+++ trunk/sys/arm/xscale/ixp425/files.avila	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,10 @@
+#$FreeBSD: stable/10/sys/arm/xscale/ixp425/files.avila 215142 2010-11-11 20:18:33Z thompsa $
+arm/xscale/ixp425/avila_machdep.c	standard
+arm/xscale/ixp425/avila_ata.c		optional avila_ata
+arm/xscale/ixp425/avila_led.c		optional avila_led
+arm/xscale/ixp425/avila_gpio.c		optional avila_gpio
+arm/xscale/ixp425/cambria_exp_space.c	standard
+arm/xscale/ixp425/cambria_fled.c	optional cambria_fled
+arm/xscale/ixp425/cambria_led.c		optional cambria_led
+arm/xscale/ixp425/cambria_gpio.c	optional cambria_gpio
+arm/xscale/ixp425/ixdp425_pci.c		optional pci


Property changes on: trunk/sys/arm/xscale/ixp425/files.avila
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/xscale/ixp425/files.ixp425
===================================================================
--- trunk/sys/arm/xscale/ixp425/files.ixp425	                        (rev 0)
+++ trunk/sys/arm/xscale/ixp425/files.ixp425	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,49 @@
+#$FreeBSD: stable/10/sys/arm/xscale/ixp425/files.ixp425 266311 2014-05-17 13:53:38Z ian $
+arm/arm/bus_space_generic.c		standard
+arm/arm/cpufunc_asm_xscale.S		standard
+arm/xscale/ixp425/ixp425.c		standard
+arm/xscale/ixp425/ixp425_mem.c		standard
+arm/xscale/ixp425/ixp425_space.c	standard
+arm/xscale/ixp425/ixp425_timer.c	standard
+arm/xscale/ixp425/ixp425_wdog.c		optional	ixpwdog
+arm/xscale/ixp425/ixp425_iic.c		optional	ixpiic
+arm/xscale/ixp425/ixp425_pci.c		optional	pci
+arm/xscale/ixp425/ixp425_pci_asm.S	optional	pci
+arm/xscale/ixp425/ixp425_pci_space.c	optional	pci
+arm/xscale/ixp425/uart_cpu_ixp425.c	optional	uart
+arm/xscale/ixp425/uart_bus_ixp425.c	optional	uart
+arm/xscale/ixp425/ixp425_a4x_space.c	optional	uart
+arm/xscale/ixp425/ixp425_a4x_io.S	optional	uart
+dev/cfi/cfi_bus_ixp4xx.c		optional	cfi
+dev/hwpmc/hwpmc_xscale.c		optional	hwpmc
+dev/uart/uart_dev_ns8250.c		optional	uart
+#
+# NPE-based Ethernet support (requires qmgr also).
+#
+arm/xscale/ixp425/if_npe.c		optional npe
+arm/xscale/ixp425/ixp425_npe.c		optional npe
+ixp425_npe_fw.c				optional npe_fw			\
+	compile-with	"${AWK} -f $S/tools/fw_stub.awk IxNpeMicrocode.dat:npe_fw -mnpe -c${.TARGET}" \
+	no-implicit-rule before-depend local				\
+	clean		"ixp425_npe_fw.c"
+#
+# NB: ld encodes the path in the binary symbols generated for the
+#     firmware image so link the file to the object directory to
+#     get known values for reference in the _fw.c file.
+#
+IxNpeMicrocode.fwo			optional npe_fw			\
+	dependency	"IxNpeMicrocode.dat"				\
+	compile-with	"${LD} -b binary -d -warn-common -r -d -o ${.TARGET} IxNpeMicrocode.dat" \
+	no-implicit-rule						\
+	clean		"IxNpeMicrocode.fwo"
+IxNpeMicrocode.dat			optional npe_fw			\
+	dependency	"$S/contrib/dev/npe/IxNpeMicrocode.dat.uu"	\
+	compile-with	"uudecode < $S/contrib/dev/npe/IxNpeMicrocode.dat.uu" \
+	no-obj no-implicit-rule						\
+	clean		"IxNpeMicrocode.dat"
+#
+# Q-Manager support
+#
+arm/xscale/ixp425/ixp425_qmgr.c		optional qmgr
+#
+dev/usb/controller/ehci_ixp4xx.c	optional ehci usb


Property changes on: trunk/sys/arm/xscale/ixp425/files.ixp425
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/xscale/ixp425/if_npe.c
===================================================================
--- trunk/sys/arm/xscale/ixp425/if_npe.c	                        (rev 0)
+++ trunk/sys/arm/xscale/ixp425/if_npe.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,1784 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2006-2008 Sam Leffler.  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 ``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 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: stable/10/sys/arm/xscale/ixp425/if_npe.c 266406 2014-05-18 16:07:35Z ian $");
+
+/*
+ * Intel XScale NPE Ethernet driver.
+ *
+ * This driver handles the two ports present on the IXP425.
+ * Packet processing is done by the Network Processing Engines
+ * (NPE's) that work together with a MAC and PHY. The MAC
+ * is also mapped to the XScale cpu; the PHY is accessed via
+ * the MAC. NPE-XScale communication happens through h/w
+ * queues managed by the Q Manager block.
+ *
+ * The code here replaces the ethAcc, ethMii, and ethDB classes
+ * in the Intel Access Library (IAL) and the OS-specific driver.
+ *
+ * XXX add vlan support
+ */
+#ifdef HAVE_KERNEL_OPTION_HEADERS
+#include "opt_device_polling.h"
+#endif
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/mbuf.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/rman.h>
+#include <sys/socket.h>
+#include <sys/sockio.h>
+#include <sys/sysctl.h>
+#include <sys/endian.h>
+#include <machine/bus.h>
+
+#include <net/ethernet.h>
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <net/if_dl.h>
+#include <net/if_media.h>
+#include <net/if_mib.h>
+#include <net/if_types.h>
+#include <net/if_var.h>
+
+#ifdef INET
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#endif
+
+#include <net/bpf.h>
+#include <net/bpfdesc.h>
+
+#include <arm/xscale/ixp425/ixp425reg.h>
+#include <arm/xscale/ixp425/ixp425var.h>
+#include <arm/xscale/ixp425/ixp425_qmgr.h>
+#include <arm/xscale/ixp425/ixp425_npevar.h>
+
+#include <dev/mii/mii.h>
+#include <dev/mii/miivar.h>
+#include <arm/xscale/ixp425/if_npereg.h>
+
+#include <machine/armreg.h>
+
+#include "miibus_if.h"
+
+/*
+ * XXX: For the main bus dma tag. Can go away if the new method to get the
+ * dma tag from the parent got MFC'd into RELENG_6.
+ */
+extern struct ixp425_softc *ixp425_softc;
+
+struct npebuf {
+	struct npebuf	*ix_next;	/* chain to next buffer */
+	void		*ix_m;		/* backpointer to mbuf */
+	bus_dmamap_t	ix_map;		/* bus dma map for associated data */
+	struct npehwbuf	*ix_hw;		/* associated h/w block */
+	uint32_t	ix_neaddr;	/* phys address of ix_hw */
+};
+
+struct npedma {
+	const char*	name;
+	int		nbuf;		/* # npebuf's allocated */
+	bus_dma_tag_t	mtag;		/* bus dma tag for mbuf data */
+	struct npehwbuf	*hwbuf;		/* NPE h/w buffers */
+	bus_dma_tag_t	buf_tag;	/* tag+map for NPE buffers */
+	bus_dmamap_t	buf_map;
+	bus_addr_t	buf_phys;	/* phys addr of buffers */
+	struct npebuf	*buf;		/* s/w buffers (1-1 w/ h/w) */
+};
+
+struct npe_softc {
+	/* XXX mii requires this be first; do not move! */
+	struct ifnet	*sc_ifp;	/* ifnet pointer */
+	struct mtx	sc_mtx;		/* basically a perimeter lock */
+	device_t	sc_dev;
+	bus_space_tag_t	sc_iot;		
+	bus_space_handle_t sc_ioh;	/* MAC register window */
+	device_t	sc_mii;		/* child miibus */
+	bus_space_handle_t sc_miih;	/* MII register window */
+	int		sc_npeid;
+	struct ixpnpe_softc *sc_npe;	/* NPE support */
+	int		sc_debug;	/* DPRINTF* control */
+	int		sc_tickinterval;
+	struct callout	tick_ch;	/* Tick callout */
+	int		npe_watchdog_timer;
+	struct npedma	txdma;
+	struct npebuf	*tx_free;	/* list of free tx buffers */
+	struct npedma	rxdma;
+	bus_addr_t	buf_phys;	/* XXX for returning a value */
+	int		rx_qid;		/* rx qid */
+	int		rx_freeqid;	/* rx free buffers qid */
+	int		tx_qid;		/* tx qid */
+	int		tx_doneqid;	/* tx completed qid */
+	struct ifmib_iso_8802_3 mibdata;
+	bus_dma_tag_t	sc_stats_tag;	/* bus dma tag for stats block */
+	struct npestats	*sc_stats;
+	bus_dmamap_t	sc_stats_map;
+	bus_addr_t	sc_stats_phys;	/* phys addr of sc_stats */
+	struct npestats	sc_totals;	/* accumulated sc_stats */
+};
+
+/*
+ * Static configuration for IXP425.  The tx and
+ * rx free Q id's are fixed by the NPE microcode.  The
+ * rx Q id's are programmed to be separate to simplify
+ * multi-port processing.  It may be better to handle
+ * all traffic through one Q (as done by the Intel drivers).
+ *
+ * Note that the PHY's are accessible only from MAC B on the
+ * IXP425 and from MAC C on other devices.  This and other
+ * platform-specific assumptions are handled with hints.
+ */
+static const struct {
+	uint32_t	macbase;
+	uint32_t	miibase;
+	int		phy;		/* phy id */
+	uint8_t		rx_qid;
+	uint8_t		rx_freeqid;
+	uint8_t		tx_qid;
+	uint8_t		tx_doneqid;
+} npeconfig[NPE_MAX] = {
+	[NPE_A] = {
+	  .macbase	= IXP435_MAC_A_HWBASE,
+	  .miibase	= IXP425_MAC_C_HWBASE,
+	  .phy		= 2,
+	  .rx_qid	= 4,
+	  .rx_freeqid	= 26,
+	  .tx_qid	= 23,
+	  .tx_doneqid	= 31
+	},
+	[NPE_B] = {
+	  .macbase	= IXP425_MAC_B_HWBASE,
+	  .miibase	= IXP425_MAC_B_HWBASE,
+	  .phy		= 0,
+	  .rx_qid	= 4,
+	  .rx_freeqid	= 27,
+	  .tx_qid	= 24,
+	  .tx_doneqid	= 31
+	},
+	[NPE_C] = {
+	  .macbase	= IXP425_MAC_C_HWBASE,
+	  .miibase	= IXP425_MAC_B_HWBASE,
+	  .phy		= 1,
+	  .rx_qid	= 12,
+	  .rx_freeqid	= 28,
+	  .tx_qid	= 25,
+	  .tx_doneqid	= 31
+	},
+};
+static struct npe_softc *npes[NPE_MAX];	/* NB: indexed by npeid */
+
+static __inline uint32_t
+RD4(struct npe_softc *sc, bus_size_t off)
+{
+	return bus_space_read_4(sc->sc_iot, sc->sc_ioh, off);
+}
+
+static __inline void
+WR4(struct npe_softc *sc, bus_size_t off, uint32_t val)
+{
+	bus_space_write_4(sc->sc_iot, sc->sc_ioh, off, val);
+}
+
+#define NPE_LOCK(_sc)		mtx_lock(&(_sc)->sc_mtx)
+#define	NPE_UNLOCK(_sc)		mtx_unlock(&(_sc)->sc_mtx)
+#define NPE_LOCK_INIT(_sc) \
+	mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->sc_dev), \
+	    MTX_NETWORK_LOCK, MTX_DEF)
+#define NPE_LOCK_DESTROY(_sc)	mtx_destroy(&_sc->sc_mtx);
+#define NPE_ASSERT_LOCKED(_sc)	mtx_assert(&_sc->sc_mtx, MA_OWNED);
+#define NPE_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED);
+
+static devclass_t npe_devclass;
+
+static int	override_npeid(device_t, const char *resname, int *val);
+static int	npe_activate(device_t dev);
+static void	npe_deactivate(device_t dev);
+static int	npe_ifmedia_update(struct ifnet *ifp);
+static void	npe_ifmedia_status(struct ifnet *ifp, struct ifmediareq *ifmr);
+static void	npe_setmac(struct npe_softc *sc, u_char *eaddr);
+static void	npe_getmac(struct npe_softc *sc, u_char *eaddr);
+static void	npe_txdone(int qid, void *arg);
+static int	npe_rxbuf_init(struct npe_softc *, struct npebuf *,
+			struct mbuf *);
+static int	npe_rxdone(int qid, void *arg);
+static void	npeinit(void *);
+static void	npestart_locked(struct ifnet *);
+static void	npestart(struct ifnet *);
+static void	npestop(struct npe_softc *);
+static void	npewatchdog(struct npe_softc *);
+static int	npeioctl(struct ifnet * ifp, u_long, caddr_t);
+
+static int	npe_setrxqosentry(struct npe_softc *, int classix,
+			int trafclass, int qid);
+static int	npe_setportaddress(struct npe_softc *, const uint8_t mac[]);
+static int	npe_setfirewallmode(struct npe_softc *, int onoff);
+static int	npe_updatestats(struct npe_softc *);
+#if 0
+static int	npe_getstats(struct npe_softc *);
+static uint32_t	npe_getimageid(struct npe_softc *);
+static int	npe_setloopback(struct npe_softc *, int ena);
+#endif
+
+/* NB: all tx done processing goes through one queue */
+static int tx_doneqid = -1;
+
+static SYSCTL_NODE(_hw, OID_AUTO, npe, CTLFLAG_RD, 0,
+    "IXP4XX NPE driver parameters");
+
+static int npe_debug = 0;
+SYSCTL_INT(_hw_npe, OID_AUTO, debug, CTLFLAG_RW, &npe_debug,
+	   0, "IXP4XX NPE network interface debug msgs");
+TUNABLE_INT("hw.npe.debug", &npe_debug);
+#define	DPRINTF(sc, fmt, ...) do {					\
+	if (sc->sc_debug) device_printf(sc->sc_dev, fmt, __VA_ARGS__);	\
+} while (0)
+#define	DPRINTFn(n, sc, fmt, ...) do {					\
+	if (sc->sc_debug >= n) device_printf(sc->sc_dev, fmt, __VA_ARGS__);\
+} while (0)
+static int npe_tickinterval = 3;		/* npe_tick frequency (secs) */
+SYSCTL_INT(_hw_npe, OID_AUTO, tickinterval, CTLFLAG_RD, &npe_tickinterval,
+	    0, "periodic work interval (secs)");
+TUNABLE_INT("hw.npe.tickinterval", &npe_tickinterval);
+
+static	int npe_rxbuf = 64;		/* # rx buffers to allocate */
+SYSCTL_INT(_hw_npe, OID_AUTO, rxbuf, CTLFLAG_RD, &npe_rxbuf,
+	    0, "rx buffers allocated");
+TUNABLE_INT("hw.npe.rxbuf", &npe_rxbuf);
+static	int npe_txbuf = 128;		/* # tx buffers to allocate */
+SYSCTL_INT(_hw_npe, OID_AUTO, txbuf, CTLFLAG_RD, &npe_txbuf,
+	    0, "tx buffers allocated");
+TUNABLE_INT("hw.npe.txbuf", &npe_txbuf);
+
+static int
+unit2npeid(int unit)
+{
+	static const int npeidmap[2][3] = {
+		/* on 425 A is for HSS, B & C are for Ethernet */
+		{ NPE_B, NPE_C, -1 },	/* IXP425 */
+		/* 435 only has A & C, order C then A */
+		{ NPE_C, NPE_A, -1 },	/* IXP435 */
+	};
+	/* XXX check feature register instead */
+	return (unit < 3 ? npeidmap[
+	    (cpu_id() & CPU_ID_CPU_MASK) == CPU_ID_IXP435][unit] : -1);
+}
+
+static int
+npe_probe(device_t dev)
+{
+	static const char *desc[NPE_MAX] = {
+		[NPE_A] = "IXP NPE-A",
+		[NPE_B] = "IXP NPE-B",
+		[NPE_C] = "IXP NPE-C"
+	};
+	int unit = device_get_unit(dev);
+	int npeid;
+
+	if (unit > 2 ||
+	    (ixp4xx_read_feature_bits() &
+	     (unit == 0 ? EXP_FCTRL_ETH0 : EXP_FCTRL_ETH1)) == 0)
+		return EINVAL;
+
+	npeid = -1;
+	if (!override_npeid(dev, "npeid", &npeid))
+		npeid = unit2npeid(unit);
+	if (npeid == -1) {
+		device_printf(dev, "unit %d not supported\n", unit);
+		return EINVAL;
+	}
+	device_set_desc(dev, desc[npeid]);
+	return 0;
+}
+
+static int
+npe_attach(device_t dev)
+{
+	struct npe_softc *sc = device_get_softc(dev);
+	struct ixp425_softc *sa = device_get_softc(device_get_parent(dev));
+	struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(dev);
+	struct sysctl_oid *tree = device_get_sysctl_tree(dev);
+	struct ifnet *ifp;
+	int error;
+	u_char eaddr[6];
+
+	sc->sc_dev = dev;
+	sc->sc_iot = sa->sc_iot;
+	NPE_LOCK_INIT(sc);
+	callout_init_mtx(&sc->tick_ch, &sc->sc_mtx, 0);
+	sc->sc_debug = npe_debug;
+	sc->sc_tickinterval = npe_tickinterval;
+
+	ifp = if_alloc(IFT_ETHER);
+	if (ifp == NULL) {
+		device_printf(dev, "cannot allocate ifnet\n");
+		error = EIO;		/* XXX */
+		goto out;
+	}
+	/* NB: must be setup prior to invoking mii code */
+	sc->sc_ifp = ifp;
+
+	error = npe_activate(dev);
+	if (error) {
+		device_printf(dev, "cannot activate npe\n");
+		goto out;
+	}
+
+	npe_getmac(sc, eaddr);
+
+	ifp->if_softc = sc;
+	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
+	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+	ifp->if_start = npestart;
+	ifp->if_ioctl = npeioctl;
+	ifp->if_init = npeinit;
+	IFQ_SET_MAXLEN(&ifp->if_snd, sc->txdma.nbuf - 1);
+	ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
+	IFQ_SET_READY(&ifp->if_snd);
+	ifp->if_linkmib = &sc->mibdata;
+	ifp->if_linkmiblen = sizeof(sc->mibdata);
+	sc->mibdata.dot3Compliance = DOT3COMPLIANCE_STATS;
+	/* device supports oversided vlan frames */
+	ifp->if_capabilities |= IFCAP_VLAN_MTU;
+	ifp->if_capenable = ifp->if_capabilities;
+#ifdef DEVICE_POLLING
+	ifp->if_capabilities |= IFCAP_POLLING;
+#endif
+
+	SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "debug",
+	    CTLFLAG_RW, &sc->sc_debug, 0, "control debugging printfs");
+	SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "tickinterval",
+	    CTLFLAG_RW, &sc->sc_tickinterval, 0, "periodic work frequency");
+	SYSCTL_ADD_STRUCT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "stats",
+	    CTLFLAG_RD, &sc->sc_totals, npestats, "onboard stats");
+
+	ether_ifattach(ifp, eaddr);
+	return 0;
+out:
+	if (ifp != NULL)
+		if_free(ifp);
+	NPE_LOCK_DESTROY(sc);
+	npe_deactivate(dev);
+	return error;
+}
+
+static int
+npe_detach(device_t dev)
+{
+	struct npe_softc *sc = device_get_softc(dev);
+	struct ifnet *ifp = sc->sc_ifp;
+
+#ifdef DEVICE_POLLING
+	if (ifp->if_capenable & IFCAP_POLLING)
+		ether_poll_deregister(ifp);
+#endif
+	npestop(sc);
+	if (ifp != NULL) {
+		ether_ifdetach(ifp);
+		if_free(ifp);
+	}
+	NPE_LOCK_DESTROY(sc);
+	npe_deactivate(dev);
+	return 0;
+}
+
+/*
+ * Compute and install the multicast filter.
+ */
+static void
+npe_setmcast(struct npe_softc *sc)
+{
+	struct ifnet *ifp = sc->sc_ifp;
+	uint8_t mask[ETHER_ADDR_LEN], addr[ETHER_ADDR_LEN];
+	int i;
+
+	if (ifp->if_flags & IFF_PROMISC) {
+		memset(mask, 0, ETHER_ADDR_LEN);
+		memset(addr, 0, ETHER_ADDR_LEN);
+	} else if (ifp->if_flags & IFF_ALLMULTI) {
+		static const uint8_t allmulti[ETHER_ADDR_LEN] =
+		    { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 };
+		memcpy(mask, allmulti, ETHER_ADDR_LEN);
+		memcpy(addr, allmulti, ETHER_ADDR_LEN);
+	} else {
+		uint8_t clr[ETHER_ADDR_LEN], set[ETHER_ADDR_LEN];
+		struct ifmultiaddr *ifma;
+		const uint8_t *mac;
+
+		memset(clr, 0, ETHER_ADDR_LEN);
+		memset(set, 0xff, ETHER_ADDR_LEN);
+
+		if_maddr_rlock(ifp);
+		TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
+			if (ifma->ifma_addr->sa_family != AF_LINK)
+				continue;
+			mac = LLADDR((struct sockaddr_dl *) ifma->ifma_addr);
+			for (i = 0; i < ETHER_ADDR_LEN; i++) {
+				clr[i] |= mac[i];
+				set[i] &= mac[i];
+			}
+		}
+		if_maddr_runlock(ifp);
+
+		for (i = 0; i < ETHER_ADDR_LEN; i++) {
+			mask[i] = set[i] | ~clr[i];
+			addr[i] = set[i];
+		}
+	}
+
+	/*
+	 * Write the mask and address registers.
+	 */
+	for (i = 0; i < ETHER_ADDR_LEN; i++) {
+		WR4(sc, NPE_MAC_ADDR_MASK(i), mask[i]);
+		WR4(sc, NPE_MAC_ADDR(i), addr[i]);
+	}
+}
+
+static void
+npe_getaddr(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
+{
+	struct npe_softc *sc;
+
+	if (error != 0)
+		return;
+	sc = (struct npe_softc *)arg;
+	sc->buf_phys = segs[0].ds_addr;
+}
+
+static int
+npe_dma_setup(struct npe_softc *sc, struct npedma *dma,
+	const char *name, int nbuf, int maxseg)
+{
+	int error, i;
+
+	memset(dma, 0, sizeof(*dma));
+
+	dma->name = name;
+	dma->nbuf = nbuf;
+
+	/* DMA tag for mapped mbufs  */
+	error = bus_dma_tag_create(ixp425_softc->sc_dmat, 1, 0,
+	    BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
+	    MCLBYTES, maxseg, MCLBYTES, 0,
+	    busdma_lock_mutex, &sc->sc_mtx, &dma->mtag);
+	if (error != 0) {
+		device_printf(sc->sc_dev, "unable to create %s mbuf dma tag, "
+		     "error %u\n", dma->name, error);
+		return error;
+	}
+
+	/* DMA tag and map for the NPE buffers */
+	error = bus_dma_tag_create(ixp425_softc->sc_dmat, sizeof(uint32_t), 0,
+	    BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
+	    nbuf * sizeof(struct npehwbuf), 1,
+	    nbuf * sizeof(struct npehwbuf), 0,
+	    busdma_lock_mutex, &sc->sc_mtx, &dma->buf_tag);
+	if (error != 0) {
+		device_printf(sc->sc_dev,
+		    "unable to create %s npebuf dma tag, error %u\n",
+		    dma->name, error);
+		return error;
+	}
+	if (bus_dmamem_alloc(dma->buf_tag, (void **)&dma->hwbuf,
+	    BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT,
+	    &dma->buf_map) != 0) {
+		device_printf(sc->sc_dev,
+		     "unable to allocate memory for %s h/w buffers, error %u\n",
+		     dma->name, error);
+		return error;
+	}
+	/* XXX M_TEMP */
+	dma->buf = malloc(nbuf * sizeof(struct npebuf), M_TEMP, M_NOWAIT | M_ZERO);
+	if (dma->buf == NULL) {
+		device_printf(sc->sc_dev,
+		     "unable to allocate memory for %s s/w buffers\n",
+		     dma->name);
+		return error;
+	}
+	if (bus_dmamap_load(dma->buf_tag, dma->buf_map,
+	    dma->hwbuf, nbuf*sizeof(struct npehwbuf), npe_getaddr, sc, 0) != 0) {
+		device_printf(sc->sc_dev,
+		     "unable to map memory for %s h/w buffers, error %u\n",
+		     dma->name, error);
+		return error;
+	}
+	dma->buf_phys = sc->buf_phys;
+	for (i = 0; i < dma->nbuf; i++) {
+		struct npebuf *npe = &dma->buf[i];
+		struct npehwbuf *hw = &dma->hwbuf[i];
+
+		/* calculate offset to shared area */
+		npe->ix_neaddr = dma->buf_phys +
+			((uintptr_t)hw - (uintptr_t)dma->hwbuf);
+		KASSERT((npe->ix_neaddr & 0x1f) == 0,
+		    ("ixpbuf misaligned, PA 0x%x", npe->ix_neaddr));
+		error = bus_dmamap_create(dma->mtag, BUS_DMA_NOWAIT,
+				&npe->ix_map);
+		if (error != 0) {
+			device_printf(sc->sc_dev,
+			     "unable to create dmamap for %s buffer %u, "
+			     "error %u\n", dma->name, i, error);
+			return error;
+		}
+		npe->ix_hw = hw;
+	}
+	bus_dmamap_sync(dma->buf_tag, dma->buf_map, BUS_DMASYNC_PREWRITE);
+	return 0;
+}
+
+static void
+npe_dma_destroy(struct npe_softc *sc, struct npedma *dma)
+{
+	int i;
+
+	if (dma->hwbuf != NULL) {
+		for (i = 0; i < dma->nbuf; i++) {
+			struct npebuf *npe = &dma->buf[i];
+			bus_dmamap_destroy(dma->mtag, npe->ix_map);
+		}
+		bus_dmamap_unload(dma->buf_tag, dma->buf_map);
+		bus_dmamem_free(dma->buf_tag, dma->hwbuf, dma->buf_map);
+	}
+	if (dma->buf != NULL)
+		free(dma->buf, M_TEMP);
+	if (dma->buf_tag)
+		bus_dma_tag_destroy(dma->buf_tag);
+	if (dma->mtag)
+		bus_dma_tag_destroy(dma->mtag);
+	memset(dma, 0, sizeof(*dma));
+}
+
+static int
+override_addr(device_t dev, const char *resname, int *base)
+{
+	int unit = device_get_unit(dev);
+	const char *resval;
+
+	/* XXX warn for wrong hint type */
+	if (resource_string_value("npe", unit, resname, &resval) != 0)
+		return 0;
+	switch (resval[0]) {
+	case 'A':
+		*base = IXP435_MAC_A_HWBASE;
+		break;
+	case 'B':
+		*base = IXP425_MAC_B_HWBASE;
+		break;
+	case 'C':
+		*base = IXP425_MAC_C_HWBASE;
+		break;
+	default:
+		device_printf(dev, "Warning, bad value %s for "
+		    "npe.%d.%s ignored\n", resval, unit, resname);
+		return 0;
+	}
+	if (bootverbose)
+		device_printf(dev, "using npe.%d.%s=%s override\n",
+		    unit, resname, resval);
+	return 1;
+}
+
+static int
+override_npeid(device_t dev, const char *resname, int *npeid)
+{
+	int unit = device_get_unit(dev);
+	const char *resval;
+
+	/* XXX warn for wrong hint type */
+	if (resource_string_value("npe", unit, resname, &resval) != 0)
+		return 0;
+	switch (resval[0]) {
+	case 'A': *npeid = NPE_A; break;
+	case 'B': *npeid = NPE_B; break;
+	case 'C': *npeid = NPE_C; break;
+	default:
+		device_printf(dev, "Warning, bad value %s for "
+		    "npe.%d.%s ignored\n", resval, unit, resname);
+		return 0;
+	}
+	if (bootverbose)
+		device_printf(dev, "using npe.%d.%s=%s override\n",
+		    unit, resname, resval);
+	return 1;
+}
+
+static int
+override_unit(device_t dev, const char *resname, int *val, int min, int max)
+{
+	int unit = device_get_unit(dev);
+	int resval;
+
+	if (resource_int_value("npe", unit, resname, &resval) != 0)
+		return 0;
+	if (!(min <= resval && resval <= max)) {
+		device_printf(dev, "Warning, bad value %d for npe.%d.%s "
+		    "ignored (value must be [%d-%d])\n", resval, unit,
+		    resname, min, max);
+		return 0;
+	}
+	if (bootverbose)
+		device_printf(dev, "using npe.%d.%s=%d override\n",
+		    unit, resname, resval);
+	*val = resval;
+	return 1;
+}
+
+static void
+npe_mac_reset(struct npe_softc *sc)
+{
+	/*
+	 * Reset MAC core.
+	 */
+	WR4(sc, NPE_MAC_CORE_CNTRL, NPE_CORE_RESET);
+	DELAY(NPE_MAC_RESET_DELAY);
+	/* configure MAC to generate MDC clock */
+	WR4(sc, NPE_MAC_CORE_CNTRL, NPE_CORE_MDC_EN);
+}
+
+static int
+npe_activate(device_t dev)
+{
+	struct npe_softc *sc = device_get_softc(dev);
+	int error, i, macbase, miibase, phy;
+
+	/*
+	 * Setup NEP ID, MAC, and MII bindings.  We allow override
+	 * via hints to handle unexpected board configs.
+	 */
+	if (!override_npeid(dev, "npeid", &sc->sc_npeid))
+		sc->sc_npeid = unit2npeid(device_get_unit(dev));
+	sc->sc_npe = ixpnpe_attach(dev, sc->sc_npeid);
+	if (sc->sc_npe == NULL) {
+		device_printf(dev, "cannot attach ixpnpe\n");
+		return EIO;		/* XXX */
+	}
+
+	/* MAC */
+	if (!override_addr(dev, "mac", &macbase))
+		macbase = npeconfig[sc->sc_npeid].macbase;
+	device_printf(sc->sc_dev, "MAC at 0x%x\n", macbase);
+	if (bus_space_map(sc->sc_iot, macbase, IXP425_REG_SIZE, 0, &sc->sc_ioh)) {
+		device_printf(dev, "cannot map mac registers 0x%x:0x%x\n",
+		    macbase, IXP425_REG_SIZE);
+		return ENOMEM;
+	}
+
+	/* PHY */
+	if (!override_unit(dev, "phy", &phy, 0, MII_NPHY - 1))
+		phy = npeconfig[sc->sc_npeid].phy;
+	if (!override_addr(dev, "mii", &miibase))
+		miibase = npeconfig[sc->sc_npeid].miibase;
+	device_printf(sc->sc_dev, "MII at 0x%x\n", miibase);
+	if (miibase != macbase) {
+		/*
+		 * PHY is mapped through a different MAC, setup an
+		 * additional mapping for frobbing the PHY registers.
+		 */
+		if (bus_space_map(sc->sc_iot, miibase, IXP425_REG_SIZE, 0, &sc->sc_miih)) {
+			device_printf(dev,
+			    "cannot map MII registers 0x%x:0x%x\n",
+			    miibase, IXP425_REG_SIZE);
+			return ENOMEM;
+		}
+	} else
+		sc->sc_miih = sc->sc_ioh;
+
+	/*
+	 * Load NPE firmware and start it running.
+	 */
+	error = ixpnpe_init(sc->sc_npe);
+	if (error != 0) {
+		device_printf(dev, "cannot init NPE (error %d)\n", error);
+		return error;
+	}
+
+	/* attach PHY */
+	error = mii_attach(dev, &sc->sc_mii, sc->sc_ifp, npe_ifmedia_update,
+	    npe_ifmedia_status, BMSR_DEFCAPMASK, phy, MII_OFFSET_ANY, 0);
+	if (error != 0) {
+		device_printf(dev, "attaching PHYs failed\n");
+		return error;
+	}
+
+	error = npe_dma_setup(sc, &sc->txdma, "tx", npe_txbuf, NPE_MAXSEG);
+	if (error != 0)
+		return error;
+	error = npe_dma_setup(sc, &sc->rxdma, "rx", npe_rxbuf, 1);
+	if (error != 0)
+		return error;
+
+	/* setup statistics block */
+	error = bus_dma_tag_create(ixp425_softc->sc_dmat, sizeof(uint32_t), 0,
+	    BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
+	    sizeof(struct npestats), 1, sizeof(struct npestats), 0,
+	    busdma_lock_mutex, &sc->sc_mtx, &sc->sc_stats_tag);
+	if (error != 0) {
+		device_printf(sc->sc_dev, "unable to create stats tag, "
+		     "error %u\n", error);
+		return error;
+	}
+	if (bus_dmamem_alloc(sc->sc_stats_tag, (void **)&sc->sc_stats,
+	    BUS_DMA_NOWAIT, &sc->sc_stats_map) != 0) {
+		device_printf(sc->sc_dev,
+		     "unable to allocate memory for stats block, error %u\n",
+		     error);
+		return error;
+	}
+	if (bus_dmamap_load(sc->sc_stats_tag, sc->sc_stats_map,
+	    sc->sc_stats, sizeof(struct npestats), npe_getaddr, sc, 0) != 0) {
+		device_printf(sc->sc_dev,
+		     "unable to load memory for stats block, error %u\n",
+		     error);
+		return error;
+	}
+	sc->sc_stats_phys = sc->buf_phys;
+
+	/*
+	 * Setup h/w rx/tx queues.  There are four q's:
+	 *   rx		inbound q of rx'd frames
+	 *   rx_free	pool of ixpbuf's for receiving frames
+	 *   tx		outbound q of frames to send
+	 *   tx_done	q of tx frames that have been processed
+	 *
+	 * The NPE handles the actual tx/rx process and the q manager
+	 * handles the queues.  The driver just writes entries to the
+	 * q manager mailbox's and gets callbacks when there are rx'd
+	 * frames to process or tx'd frames to reap.  These callbacks
+	 * are controlled by the q configurations; e.g. we get a
+	 * callback when tx_done has 2 or more frames to process and
+	 * when the rx q has at least one frame.  These setings can
+	 * changed at the time the q is configured.
+	 */
+	sc->rx_qid = npeconfig[sc->sc_npeid].rx_qid;
+	ixpqmgr_qconfig(sc->rx_qid, npe_rxbuf, 0,  1,
+		IX_QMGR_Q_SOURCE_ID_NOT_E, (qconfig_hand_t *)npe_rxdone, sc);
+	sc->rx_freeqid = npeconfig[sc->sc_npeid].rx_freeqid;
+	ixpqmgr_qconfig(sc->rx_freeqid,	npe_rxbuf, 0, npe_rxbuf/2, 0, NULL, sc);
+	/*
+	 * Setup the NPE to direct all traffic to rx_qid.
+	 * When QoS is enabled in the firmware there are
+	 * 8 traffic classes; otherwise just 4.
+	 */
+	for (i = 0; i < 8; i++)
+		npe_setrxqosentry(sc, i, 0, sc->rx_qid);
+
+	/* disable firewall mode just in case (should be off) */
+	npe_setfirewallmode(sc, 0);
+
+	sc->tx_qid = npeconfig[sc->sc_npeid].tx_qid;
+	sc->tx_doneqid = npeconfig[sc->sc_npeid].tx_doneqid;
+	ixpqmgr_qconfig(sc->tx_qid, npe_txbuf, 0, npe_txbuf, 0, NULL, sc);
+	if (tx_doneqid == -1) {
+		ixpqmgr_qconfig(sc->tx_doneqid,	npe_txbuf, 0,  2,
+			IX_QMGR_Q_SOURCE_ID_NOT_E, npe_txdone, sc);
+		tx_doneqid = sc->tx_doneqid;
+	}
+
+	KASSERT(npes[sc->sc_npeid] == NULL,
+	    ("npe %u already setup", sc->sc_npeid));
+	npes[sc->sc_npeid] = sc;
+
+	return 0;
+}
+
+static void
+npe_deactivate(device_t dev)
+{
+	struct npe_softc *sc = device_get_softc(dev);
+
+	npes[sc->sc_npeid] = NULL;
+
+	/* XXX disable q's */
+	if (sc->sc_npe != NULL) {
+		ixpnpe_stop(sc->sc_npe);
+		ixpnpe_detach(sc->sc_npe);
+	}
+	if (sc->sc_stats != NULL) {
+		bus_dmamap_unload(sc->sc_stats_tag, sc->sc_stats_map);
+		bus_dmamem_free(sc->sc_stats_tag, sc->sc_stats,
+			sc->sc_stats_map);
+	}
+	if (sc->sc_stats_tag != NULL)
+		bus_dma_tag_destroy(sc->sc_stats_tag);
+	npe_dma_destroy(sc, &sc->txdma);
+	npe_dma_destroy(sc, &sc->rxdma);
+	bus_generic_detach(sc->sc_dev);
+	if (sc->sc_mii != NULL)
+		device_delete_child(sc->sc_dev, sc->sc_mii);
+}
+
+/*
+ * Change media according to request.
+ */
+static int
+npe_ifmedia_update(struct ifnet *ifp)
+{
+	struct npe_softc *sc = ifp->if_softc;
+	struct mii_data *mii;
+
+	mii = device_get_softc(sc->sc_mii);
+	NPE_LOCK(sc);
+	mii_mediachg(mii);
+	/* XXX push state ourself? */
+	NPE_UNLOCK(sc);
+	return (0);
+}
+
+/*
+ * Notify the world which media we're using.
+ */
+static void
+npe_ifmedia_status(struct ifnet *ifp, struct ifmediareq *ifmr)
+{
+	struct npe_softc *sc = ifp->if_softc;
+	struct mii_data *mii;
+
+	mii = device_get_softc(sc->sc_mii);
+	NPE_LOCK(sc);
+	mii_pollstat(mii);
+	ifmr->ifm_active = mii->mii_media_active;
+	ifmr->ifm_status = mii->mii_media_status;
+	NPE_UNLOCK(sc);
+}
+
+static void
+npe_addstats(struct npe_softc *sc)
+{
+#define	NPEADD(x)	sc->sc_totals.x += be32toh(ns->x)
+#define	MIBADD(x) do { sc->mibdata.x += be32toh(ns->x); NPEADD(x); } while (0)
+	struct ifnet *ifp = sc->sc_ifp;
+	struct npestats *ns = sc->sc_stats;
+
+	MIBADD(dot3StatsAlignmentErrors);
+	MIBADD(dot3StatsFCSErrors);
+	MIBADD(dot3StatsInternalMacReceiveErrors);
+	NPEADD(RxOverrunDiscards);
+	NPEADD(RxLearnedEntryDiscards);
+	NPEADD(RxLargeFramesDiscards);
+	NPEADD(RxSTPBlockedDiscards);
+	NPEADD(RxVLANTypeFilterDiscards);
+	NPEADD(RxVLANIdFilterDiscards);
+	NPEADD(RxInvalidSourceDiscards);
+	NPEADD(RxBlackListDiscards);
+	NPEADD(RxWhiteListDiscards);
+	NPEADD(RxUnderflowEntryDiscards);
+	MIBADD(dot3StatsSingleCollisionFrames);
+	MIBADD(dot3StatsMultipleCollisionFrames);
+	MIBADD(dot3StatsDeferredTransmissions);
+	MIBADD(dot3StatsLateCollisions);
+	MIBADD(dot3StatsExcessiveCollisions);
+	MIBADD(dot3StatsInternalMacTransmitErrors);
+	MIBADD(dot3StatsCarrierSenseErrors);
+	NPEADD(TxLargeFrameDiscards);
+	NPEADD(TxVLANIdFilterDiscards);
+
+	sc->mibdata.dot3StatsFrameTooLongs +=
+	      be32toh(ns->RxLargeFramesDiscards)
+	    + be32toh(ns->TxLargeFrameDiscards);
+	sc->mibdata.dot3StatsMissedFrames +=
+	      be32toh(ns->RxOverrunDiscards)
+	    + be32toh(ns->RxUnderflowEntryDiscards);
+
+	ifp->if_oerrors +=
+		  be32toh(ns->dot3StatsInternalMacTransmitErrors)
+		+ be32toh(ns->dot3StatsCarrierSenseErrors)
+		+ be32toh(ns->TxVLANIdFilterDiscards)
+		;
+	ifp->if_ierrors += be32toh(ns->dot3StatsFCSErrors)
+		+ be32toh(ns->dot3StatsInternalMacReceiveErrors)
+		+ be32toh(ns->RxOverrunDiscards)
+		+ be32toh(ns->RxUnderflowEntryDiscards)
+		;
+	ifp->if_collisions +=
+		  be32toh(ns->dot3StatsSingleCollisionFrames)
+		+ be32toh(ns->dot3StatsMultipleCollisionFrames)
+		;
+#undef NPEADD
+#undef MIBADD
+}
+
+static void
+npe_tick(void *xsc)
+{
+#define	ACK	(NPE_RESETSTATS << NPE_MAC_MSGID_SHL)
+	struct npe_softc *sc = xsc;
+	struct mii_data *mii = device_get_softc(sc->sc_mii);
+	uint32_t msg[2];
+
+	NPE_ASSERT_LOCKED(sc);
+
+	/*
+	 * NB: to avoid sleeping with the softc lock held we
+	 * split the NPE msg processing into two parts.  The
+	 * request for statistics is sent w/o waiting for a
+	 * reply and then on the next tick we retrieve the
+	 * results.  This works because npe_tick is the only
+	 * code that talks via the mailbox's (except at setup).
+	 * This likely can be handled better.
+	 */
+	if (ixpnpe_recvmsg_async(sc->sc_npe, msg) == 0 && msg[0] == ACK) {
+		bus_dmamap_sync(sc->sc_stats_tag, sc->sc_stats_map,
+		    BUS_DMASYNC_POSTREAD);
+		npe_addstats(sc);
+	}
+	npe_updatestats(sc);
+	mii_tick(mii);
+
+	npewatchdog(sc);
+
+	/* schedule next poll */
+	callout_reset(&sc->tick_ch, sc->sc_tickinterval * hz, npe_tick, sc);
+#undef ACK
+}
+
+static void
+npe_setmac(struct npe_softc *sc, u_char *eaddr)
+{
+	WR4(sc, NPE_MAC_UNI_ADDR_1, eaddr[0]);
+	WR4(sc, NPE_MAC_UNI_ADDR_2, eaddr[1]);
+	WR4(sc, NPE_MAC_UNI_ADDR_3, eaddr[2]);
+	WR4(sc, NPE_MAC_UNI_ADDR_4, eaddr[3]);
+	WR4(sc, NPE_MAC_UNI_ADDR_5, eaddr[4]);
+	WR4(sc, NPE_MAC_UNI_ADDR_6, eaddr[5]);
+}
+
+static void
+npe_getmac(struct npe_softc *sc, u_char *eaddr)
+{
+	/* NB: the unicast address appears to be loaded from EEPROM on reset */
+	eaddr[0] = RD4(sc, NPE_MAC_UNI_ADDR_1) & 0xff;
+	eaddr[1] = RD4(sc, NPE_MAC_UNI_ADDR_2) & 0xff;
+	eaddr[2] = RD4(sc, NPE_MAC_UNI_ADDR_3) & 0xff;
+	eaddr[3] = RD4(sc, NPE_MAC_UNI_ADDR_4) & 0xff;
+	eaddr[4] = RD4(sc, NPE_MAC_UNI_ADDR_5) & 0xff;
+	eaddr[5] = RD4(sc, NPE_MAC_UNI_ADDR_6) & 0xff;
+}
+
+struct txdone {
+	struct npebuf *head;
+	struct npebuf **tail;
+	int count;
+};
+
+static __inline void
+npe_txdone_finish(struct npe_softc *sc, const struct txdone *td)
+{
+	struct ifnet *ifp = sc->sc_ifp;
+
+	NPE_LOCK(sc);
+	*td->tail = sc->tx_free;
+	sc->tx_free = td->head;
+	/*
+	 * We're no longer busy, so clear the busy flag and call the
+	 * start routine to xmit more packets.
+	 */
+	ifp->if_opackets += td->count;
+	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+	sc->npe_watchdog_timer = 0;
+	npestart_locked(ifp);
+	NPE_UNLOCK(sc);
+}
+
+/*
+ * Q manager callback on tx done queue.  Reap mbufs
+ * and return tx buffers to the free list.  Finally
+ * restart output.  Note the microcode has only one
+ * txdone q wired into it so we must use the NPE ID
+ * returned with each npehwbuf to decide where to
+ * send buffers.
+ */
+static void
+npe_txdone(int qid, void *arg)
+{
+#define	P2V(a, dma) \
+	&(dma)->buf[((a) - (dma)->buf_phys) / sizeof(struct npehwbuf)]
+	struct npe_softc *sc0 = arg;
+	struct npe_softc *sc;
+	struct npebuf *npe;
+	struct txdone *td, q[NPE_MAX];
+	uint32_t entry;
+
+	q[NPE_A].tail = &q[NPE_A].head; q[NPE_A].count = 0;
+	q[NPE_B].tail = &q[NPE_B].head; q[NPE_B].count = 0;
+	q[NPE_C].tail = &q[NPE_C].head; q[NPE_C].count = 0;
+	/* XXX max # at a time? */
+	while (ixpqmgr_qread(qid, &entry) == 0) {
+		DPRINTF(sc0, "%s: entry 0x%x NPE %u port %u\n",
+		    __func__, entry, NPE_QM_Q_NPE(entry), NPE_QM_Q_PORT(entry));
+
+		sc = npes[NPE_QM_Q_NPE(entry)];
+		npe = P2V(NPE_QM_Q_ADDR(entry), &sc->txdma);
+		m_freem(npe->ix_m);
+		npe->ix_m = NULL;
+
+		td = &q[NPE_QM_Q_NPE(entry)];
+		*td->tail = npe;
+		td->tail = &npe->ix_next;
+		td->count++;
+	}
+
+	if (q[NPE_A].count)
+		npe_txdone_finish(npes[NPE_A], &q[NPE_A]);
+	if (q[NPE_B].count)
+		npe_txdone_finish(npes[NPE_B], &q[NPE_B]);
+	if (q[NPE_C].count)
+		npe_txdone_finish(npes[NPE_C], &q[NPE_C]);
+#undef P2V
+}
+
+static int
+npe_rxbuf_init(struct npe_softc *sc, struct npebuf *npe, struct mbuf *m)
+{
+	bus_dma_segment_t segs[1];
+	struct npedma *dma = &sc->rxdma;
+	struct npehwbuf *hw;
+	int error, nseg;
+
+	if (m == NULL) {
+		m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
+		if (m == NULL)
+			return ENOBUFS;
+	}
+	KASSERT(m->m_ext.ext_size >= 1536 + ETHER_ALIGN,
+		("ext_size %d", m->m_ext.ext_size));
+	m->m_pkthdr.len = m->m_len = 1536;
+	/* backload payload and align ip hdr */
+	m->m_data = m->m_ext.ext_buf + (m->m_ext.ext_size - (1536+ETHER_ALIGN));
+	bus_dmamap_unload(dma->mtag, npe->ix_map);
+	error = bus_dmamap_load_mbuf_sg(dma->mtag, npe->ix_map, m,
+			segs, &nseg, 0);
+	if (error != 0) {
+		m_freem(m);
+		return error;
+	}
+	hw = npe->ix_hw;
+	hw->ix_ne[0].data = htobe32(segs[0].ds_addr);
+	/* NB: NPE requires length be a multiple of 64 */
+	/* NB: buffer length is shifted in word */
+	hw->ix_ne[0].len = htobe32(segs[0].ds_len << 16);
+	hw->ix_ne[0].next = 0;
+	bus_dmamap_sync(dma->buf_tag, dma->buf_map, 
+	    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
+	npe->ix_m = m;
+	/* Flush the memory in the mbuf */
+	bus_dmamap_sync(dma->mtag, npe->ix_map, BUS_DMASYNC_PREREAD);
+	return 0;
+}
+
+/*
+ * RX q processing for a specific NPE.  Claim entries
+ * from the hardware queue and pass the frames up the
+ * stack. Pass the rx buffers to the free list.
+ */
+static int
+npe_rxdone(int qid, void *arg)
+{
+#define	P2V(a, dma) \
+	&(dma)->buf[((a) - (dma)->buf_phys) / sizeof(struct npehwbuf)]
+	struct npe_softc *sc = arg;
+	struct npedma *dma = &sc->rxdma;
+	uint32_t entry;
+	int rx_npkts = 0;
+
+	while (ixpqmgr_qread(qid, &entry) == 0) {
+		struct npebuf *npe = P2V(NPE_QM_Q_ADDR(entry), dma);
+		struct mbuf *m;
+
+		bus_dmamap_sync(dma->buf_tag, dma->buf_map,
+		    BUS_DMASYNC_POSTREAD);
+		DPRINTF(sc, "%s: entry 0x%x neaddr 0x%x ne_len 0x%x\n",
+		    __func__, entry, npe->ix_neaddr, npe->ix_hw->ix_ne[0].len);
+		/*
+		 * Allocate a new mbuf to replenish the rx buffer.
+		 * If doing so fails we drop the rx'd frame so we
+		 * can reuse the previous mbuf.  When we're able to
+		 * allocate a new mbuf dispatch the mbuf w/ rx'd
+		 * data up the stack and replace it with the newly
+		 * allocated one.
+		 */
+		m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
+		if (m != NULL) {
+			struct mbuf *mrx = npe->ix_m;
+			struct npehwbuf *hw = npe->ix_hw;
+			struct ifnet *ifp = sc->sc_ifp;
+
+			/* Flush mbuf memory for rx'd data */
+			bus_dmamap_sync(dma->mtag, npe->ix_map,
+			    BUS_DMASYNC_POSTREAD);
+
+			/* set m_len etc. per rx frame size */
+			mrx->m_len = be32toh(hw->ix_ne[0].len) & 0xffff;
+			mrx->m_pkthdr.len = mrx->m_len;
+			mrx->m_pkthdr.rcvif = ifp;
+
+			ifp->if_ipackets++;
+			ifp->if_input(ifp, mrx);
+			rx_npkts++;
+		} else {
+			/* discard frame and re-use mbuf */
+			m = npe->ix_m;
+		}
+		if (npe_rxbuf_init(sc, npe, m) == 0) {
+			/* return npe buf to rx free list */
+			ixpqmgr_qwrite(sc->rx_freeqid, npe->ix_neaddr);
+		} else {
+			/* XXX should not happen */
+		}
+	}
+	return rx_npkts;
+#undef P2V
+}
+
+#ifdef DEVICE_POLLING
+static int
+npe_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
+{
+	struct npe_softc *sc = ifp->if_softc;
+	int rx_npkts = 0;
+
+	if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
+		rx_npkts = npe_rxdone(sc->rx_qid, sc);
+		npe_txdone(sc->tx_doneqid, sc);	/* XXX polls both NPE's */
+	}
+	return rx_npkts;
+}
+#endif /* DEVICE_POLLING */
+
+static void
+npe_startxmit(struct npe_softc *sc)
+{
+	struct npedma *dma = &sc->txdma;
+	int i;
+
+	NPE_ASSERT_LOCKED(sc);
+	sc->tx_free = NULL;
+	for (i = 0; i < dma->nbuf; i++) {
+		struct npebuf *npe = &dma->buf[i];
+		if (npe->ix_m != NULL) {
+			/* NB: should not happen */
+			device_printf(sc->sc_dev,
+			    "%s: free mbuf at entry %u\n", __func__, i);
+			m_freem(npe->ix_m);
+		}
+		npe->ix_m = NULL;
+		npe->ix_next = sc->tx_free;
+		sc->tx_free = npe;
+	}
+}
+
+static void
+npe_startrecv(struct npe_softc *sc)
+{
+	struct npedma *dma = &sc->rxdma;
+	struct npebuf *npe;
+	int i;
+
+	NPE_ASSERT_LOCKED(sc);
+	for (i = 0; i < dma->nbuf; i++) {
+		npe = &dma->buf[i];
+		npe_rxbuf_init(sc, npe, npe->ix_m);
+		/* set npe buf on rx free list */
+		ixpqmgr_qwrite(sc->rx_freeqid, npe->ix_neaddr);
+	}
+}
+
+/*
+ * Reset and initialize the chip
+ */
+static void
+npeinit_locked(void *xsc)
+{
+	struct npe_softc *sc = xsc;
+	struct ifnet *ifp = sc->sc_ifp;
+
+	NPE_ASSERT_LOCKED(sc);
+if (ifp->if_drv_flags & IFF_DRV_RUNNING) return;/*XXX*/
+
+	/*
+	 * Reset MAC core.
+	 */
+	npe_mac_reset(sc);
+
+	/* disable transmitter and reciver in the MAC */
+ 	WR4(sc, NPE_MAC_RX_CNTRL1,
+	    RD4(sc, NPE_MAC_RX_CNTRL1) &~ NPE_RX_CNTRL1_RX_EN);
+ 	WR4(sc, NPE_MAC_TX_CNTRL1,
+	    RD4(sc, NPE_MAC_TX_CNTRL1) &~ NPE_TX_CNTRL1_TX_EN);
+
+	/*
+	 * Set the MAC core registers.
+	 */
+	WR4(sc, NPE_MAC_INT_CLK_THRESH, 0x1);	/* clock ratio: for ipx4xx */
+	WR4(sc, NPE_MAC_TX_CNTRL2,	0xf);	/* max retries */
+	WR4(sc, NPE_MAC_RANDOM_SEED,	0x8);	/* LFSR back-off seed */
+	/* thresholds determined by NPE firmware FS */
+	WR4(sc, NPE_MAC_THRESH_P_EMPTY,	0x12);
+	WR4(sc, NPE_MAC_THRESH_P_FULL,	0x30);
+	WR4(sc, NPE_MAC_BUF_SIZE_TX,	0x8);	/* tx fifo threshold (bytes) */
+	WR4(sc, NPE_MAC_TX_DEFER,	0x15);	/* for single deferral */
+	WR4(sc, NPE_MAC_RX_DEFER,	0x16);	/* deferral on inter-frame gap*/
+	WR4(sc, NPE_MAC_TX_TWO_DEFER_1,	0x8);	/* for 2-part deferral */
+	WR4(sc, NPE_MAC_TX_TWO_DEFER_2,	0x7);	/* for 2-part deferral */
+	WR4(sc, NPE_MAC_SLOT_TIME,	0x80);	/* assumes MII mode */
+
+	WR4(sc, NPE_MAC_TX_CNTRL1,
+		  NPE_TX_CNTRL1_RETRY		/* retry failed xmits */
+		| NPE_TX_CNTRL1_FCS_EN		/* append FCS */
+		| NPE_TX_CNTRL1_2DEFER		/* 2-part deferal */
+		| NPE_TX_CNTRL1_PAD_EN);	/* pad runt frames */
+	/* XXX pad strip? */
+	/* ena pause frame handling */
+	WR4(sc, NPE_MAC_RX_CNTRL1, NPE_RX_CNTRL1_PAUSE_EN);
+	WR4(sc, NPE_MAC_RX_CNTRL2, 0);
+
+	npe_setmac(sc, IF_LLADDR(ifp));
+	npe_setportaddress(sc, IF_LLADDR(ifp));
+	npe_setmcast(sc);
+
+	npe_startxmit(sc);
+	npe_startrecv(sc);
+
+	ifp->if_drv_flags |= IFF_DRV_RUNNING;
+	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+	sc->npe_watchdog_timer = 0;		/* just in case */
+
+	/* enable transmitter and reciver in the MAC */
+ 	WR4(sc, NPE_MAC_RX_CNTRL1,
+	    RD4(sc, NPE_MAC_RX_CNTRL1) | NPE_RX_CNTRL1_RX_EN);
+ 	WR4(sc, NPE_MAC_TX_CNTRL1,
+	    RD4(sc, NPE_MAC_TX_CNTRL1) | NPE_TX_CNTRL1_TX_EN);
+
+	callout_reset(&sc->tick_ch, sc->sc_tickinterval * hz, npe_tick, sc);
+}
+
+static void
+npeinit(void *xsc)
+{
+	struct npe_softc *sc = xsc;
+	NPE_LOCK(sc);
+	npeinit_locked(sc);
+	NPE_UNLOCK(sc);
+}
+
+/*
+ * Dequeue packets and place on the h/w transmit queue.
+ */
+static void
+npestart_locked(struct ifnet *ifp)
+{
+	struct npe_softc *sc = ifp->if_softc;
+	struct npebuf *npe;
+	struct npehwbuf *hw;
+	struct mbuf *m, *n;
+	struct npedma *dma = &sc->txdma;
+	bus_dma_segment_t segs[NPE_MAXSEG];
+	int nseg, len, error, i;
+	uint32_t next;
+
+	NPE_ASSERT_LOCKED(sc);
+	/* XXX can this happen? */
+	if (ifp->if_drv_flags & IFF_DRV_OACTIVE)
+		return;
+
+	while (sc->tx_free != NULL) {
+		IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
+		if (m == NULL) {
+			/* XXX? */
+			ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+			return;
+		}
+		npe = sc->tx_free;
+		bus_dmamap_unload(dma->mtag, npe->ix_map);
+		error = bus_dmamap_load_mbuf_sg(dma->mtag, npe->ix_map,
+		    m, segs, &nseg, 0);
+		if (error == EFBIG) {
+			n = m_collapse(m, M_NOWAIT, NPE_MAXSEG);
+			if (n == NULL) {
+				if_printf(ifp, "%s: too many fragments %u\n",
+				    __func__, nseg);
+				m_freem(m);
+				return;	/* XXX? */
+			}
+			m = n;
+			error = bus_dmamap_load_mbuf_sg(dma->mtag, npe->ix_map,
+			    m, segs, &nseg, 0);
+		}
+		if (error != 0 || nseg == 0) {
+			if_printf(ifp, "%s: error %u nseg %u\n",
+			    __func__, error, nseg);
+			m_freem(m);
+			return;	/* XXX? */
+		}
+		sc->tx_free = npe->ix_next;
+
+		bus_dmamap_sync(dma->mtag, npe->ix_map, BUS_DMASYNC_PREWRITE);
+	
+		/*
+		 * Tap off here if there is a bpf listener.
+		 */
+		BPF_MTAP(ifp, m);
+
+		npe->ix_m = m;
+		hw = npe->ix_hw;
+		len = m->m_pkthdr.len;
+		next = npe->ix_neaddr + sizeof(hw->ix_ne[0]);
+		for (i = 0; i < nseg; i++) {
+			hw->ix_ne[i].data = htobe32(segs[i].ds_addr);
+			hw->ix_ne[i].len = htobe32((segs[i].ds_len<<16) | len);
+			hw->ix_ne[i].next = htobe32(next);
+
+			len = 0;		/* zero for segments > 1 */
+			next += sizeof(hw->ix_ne[0]);
+		}
+		hw->ix_ne[i-1].next = 0;	/* zero last in chain */
+		bus_dmamap_sync(dma->buf_tag, dma->buf_map,
+		    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
+
+		DPRINTF(sc, "%s: qwrite(%u, 0x%x) ne_data %x ne_len 0x%x\n",
+		    __func__, sc->tx_qid, npe->ix_neaddr,
+		    hw->ix_ne[0].data, hw->ix_ne[0].len);
+		/* stick it on the tx q */
+		/* XXX add vlan priority */
+		ixpqmgr_qwrite(sc->tx_qid, npe->ix_neaddr);
+
+		sc->npe_watchdog_timer = 5;
+	}
+	if (sc->tx_free == NULL)
+		ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+}
+
+void
+npestart(struct ifnet *ifp)
+{
+	struct npe_softc *sc = ifp->if_softc;
+	NPE_LOCK(sc);
+	npestart_locked(ifp);
+	NPE_UNLOCK(sc);
+}
+
+static void
+npe_stopxmit(struct npe_softc *sc)
+{
+	struct npedma *dma = &sc->txdma;
+	int i;
+
+	NPE_ASSERT_LOCKED(sc);
+
+	/* XXX qmgr */
+	for (i = 0; i < dma->nbuf; i++) {
+		struct npebuf *npe = &dma->buf[i];
+
+		if (npe->ix_m != NULL) {
+			bus_dmamap_unload(dma->mtag, npe->ix_map);
+			m_freem(npe->ix_m);
+			npe->ix_m = NULL;
+		}
+	}
+}
+
+static void
+npe_stoprecv(struct npe_softc *sc)
+{
+	struct npedma *dma = &sc->rxdma;
+	int i;
+
+	NPE_ASSERT_LOCKED(sc);
+
+	/* XXX qmgr */
+	for (i = 0; i < dma->nbuf; i++) {
+		struct npebuf *npe = &dma->buf[i];
+
+		if (npe->ix_m != NULL) {
+			bus_dmamap_unload(dma->mtag, npe->ix_map);
+			m_freem(npe->ix_m);
+			npe->ix_m = NULL;
+		}
+	}
+}
+
+/*
+ * Turn off interrupts, and stop the nic.
+ */
+void
+npestop(struct npe_softc *sc)
+{
+	struct ifnet *ifp = sc->sc_ifp;
+
+	/*  disable transmitter and reciver in the MAC  */
+ 	WR4(sc, NPE_MAC_RX_CNTRL1,
+	    RD4(sc, NPE_MAC_RX_CNTRL1) &~ NPE_RX_CNTRL1_RX_EN);
+ 	WR4(sc, NPE_MAC_TX_CNTRL1,
+	    RD4(sc, NPE_MAC_TX_CNTRL1) &~ NPE_TX_CNTRL1_TX_EN);
+
+	sc->npe_watchdog_timer = 0;
+	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+
+	callout_stop(&sc->tick_ch);
+
+	npe_stopxmit(sc);
+	npe_stoprecv(sc);
+	/* XXX go into loopback & drain q's? */
+	/* XXX but beware of disabling tx above */
+
+	/*
+	 * The MAC core rx/tx disable may leave the MAC hardware in an
+	 * unpredictable state. A hw reset is executed before resetting
+	 * all the MAC parameters to a known value.
+	 */
+	WR4(sc, NPE_MAC_CORE_CNTRL, NPE_CORE_RESET);
+	DELAY(NPE_MAC_RESET_DELAY);
+	WR4(sc, NPE_MAC_INT_CLK_THRESH, NPE_MAC_INT_CLK_THRESH_DEFAULT);
+	WR4(sc, NPE_MAC_CORE_CNTRL, NPE_CORE_MDC_EN);
+}
+
+void
+npewatchdog(struct npe_softc *sc)
+{
+	NPE_ASSERT_LOCKED(sc);
+
+	if (sc->npe_watchdog_timer == 0 || --sc->npe_watchdog_timer != 0)
+		return;
+
+	device_printf(sc->sc_dev, "watchdog timeout\n");
+	sc->sc_ifp->if_oerrors++;
+
+	npeinit_locked(sc);
+}
+
+static int
+npeioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
+{
+	struct npe_softc *sc = ifp->if_softc;
+ 	struct mii_data *mii;
+ 	struct ifreq *ifr = (struct ifreq *)data;	
+	int error = 0;
+#ifdef DEVICE_POLLING
+	int mask;
+#endif
+
+	switch (cmd) {
+	case SIOCSIFFLAGS:
+		NPE_LOCK(sc);
+		if ((ifp->if_flags & IFF_UP) == 0 &&
+		    ifp->if_drv_flags & IFF_DRV_RUNNING) {
+			ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
+			npestop(sc);
+		} else {
+			/* reinitialize card on any parameter change */
+			npeinit_locked(sc);
+		}
+		NPE_UNLOCK(sc);
+		break;
+
+	case SIOCADDMULTI:
+	case SIOCDELMULTI:
+		/* update multicast filter list. */
+		NPE_LOCK(sc);
+		npe_setmcast(sc);
+		NPE_UNLOCK(sc);
+		error = 0;
+		break;
+
+  	case SIOCSIFMEDIA:
+  	case SIOCGIFMEDIA:
+ 		mii = device_get_softc(sc->sc_mii);
+ 		error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, cmd);
+  		break;
+
+#ifdef DEVICE_POLLING
+	case SIOCSIFCAP:
+		mask = ifp->if_capenable ^ ifr->ifr_reqcap;
+		if (mask & IFCAP_POLLING) {
+			if (ifr->ifr_reqcap & IFCAP_POLLING) {
+				error = ether_poll_register(npe_poll, ifp);
+				if (error)
+					return error;
+				NPE_LOCK(sc);
+				/* disable callbacks XXX txdone is shared */
+				ixpqmgr_notify_disable(sc->rx_qid);
+				ixpqmgr_notify_disable(sc->tx_doneqid);
+				ifp->if_capenable |= IFCAP_POLLING;
+				NPE_UNLOCK(sc);
+			} else {
+				error = ether_poll_deregister(ifp);
+				/* NB: always enable qmgr callbacks */
+				NPE_LOCK(sc);
+				/* enable qmgr callbacks */
+				ixpqmgr_notify_enable(sc->rx_qid,
+				    IX_QMGR_Q_SOURCE_ID_NOT_E);
+				ixpqmgr_notify_enable(sc->tx_doneqid,
+				    IX_QMGR_Q_SOURCE_ID_NOT_E);
+				ifp->if_capenable &= ~IFCAP_POLLING;
+				NPE_UNLOCK(sc);
+			}
+		}
+		break;
+#endif
+	default:
+		error = ether_ioctl(ifp, cmd, data);
+		break;
+	}
+	return error;
+}
+
+/*
+ * Setup a traffic class -> rx queue mapping.
+ */
+static int
+npe_setrxqosentry(struct npe_softc *sc, int classix, int trafclass, int qid)
+{
+	uint32_t msg[2];
+
+	msg[0] = (NPE_SETRXQOSENTRY << 24) | (sc->sc_npeid << 20) | classix;
+	msg[1] = (trafclass << 24) | (1 << 23) | (qid << 16) | (qid << 4);
+	return ixpnpe_sendandrecvmsg_sync(sc->sc_npe, msg, msg);
+}
+
+static int
+npe_setportaddress(struct npe_softc *sc, const uint8_t mac[ETHER_ADDR_LEN])
+{
+	uint32_t msg[2];
+
+	msg[0] = (NPE_SETPORTADDRESS << 24)
+	       | (sc->sc_npeid << 20)
+	       | (mac[0] << 8)
+	       | (mac[1] << 0);
+	msg[1] = (mac[2] << 24)
+	       | (mac[3] << 16)
+	       | (mac[4] << 8)
+	       | (mac[5] << 0);
+	return ixpnpe_sendandrecvmsg_sync(sc->sc_npe, msg, msg);
+}
+
+static int
+npe_setfirewallmode(struct npe_softc *sc, int onoff)
+{
+	uint32_t msg[2];
+
+	/* XXX honor onoff */
+	msg[0] = (NPE_SETFIREWALLMODE << 24) | (sc->sc_npeid << 20);
+	msg[1] = 0;
+	return ixpnpe_sendandrecvmsg_sync(sc->sc_npe, msg, msg);
+}
+
+/*
+ * Update and reset the statistics in the NPE.
+ */
+static int
+npe_updatestats(struct npe_softc *sc)
+{
+	uint32_t msg[2];
+
+	msg[0] = NPE_RESETSTATS << NPE_MAC_MSGID_SHL;
+	msg[1] = sc->sc_stats_phys;	/* physical address of stat block */
+	return ixpnpe_sendmsg_async(sc->sc_npe, msg);
+}
+
+#if 0
+/*
+ * Get the current statistics block.
+ */
+static int
+npe_getstats(struct npe_softc *sc)
+{
+	uint32_t msg[2];
+
+	msg[0] = NPE_GETSTATS << NPE_MAC_MSGID_SHL;
+	msg[1] = sc->sc_stats_phys;	/* physical address of stat block */
+	return ixpnpe_sendandrecvmsg(sc->sc_npe, msg, msg);
+}
+
+/*
+ * Query the image id of the loaded firmware.
+ */
+static uint32_t
+npe_getimageid(struct npe_softc *sc)
+{
+	uint32_t msg[2];
+
+	msg[0] = NPE_GETSTATUS << NPE_MAC_MSGID_SHL;
+	msg[1] = 0;
+	return ixpnpe_sendandrecvmsg_sync(sc->sc_npe, msg, msg) == 0 ? msg[1] : 0;
+}
+
+/*
+ * Enable/disable loopback.
+ */
+static int
+npe_setloopback(struct npe_softc *sc, int ena)
+{
+	uint32_t msg[2];
+
+	msg[0] = (NPE_SETLOOPBACK << NPE_MAC_MSGID_SHL) | (ena != 0);
+	msg[1] = 0;
+	return ixpnpe_sendandrecvmsg_sync(sc->sc_npe, msg, msg);
+}
+#endif
+
+static void
+npe_child_detached(device_t dev, device_t child)
+{
+	struct npe_softc *sc;
+
+	sc = device_get_softc(dev);
+	if (child == sc->sc_mii)
+		sc->sc_mii = NULL;
+}
+
+/*
+ * MII bus support routines.
+ */
+#define	MII_RD4(sc, reg)	bus_space_read_4(sc->sc_iot, sc->sc_miih, reg)
+#define	MII_WR4(sc, reg, v) \
+	bus_space_write_4(sc->sc_iot, sc->sc_miih, reg, v)
+
+static uint32_t
+npe_mii_mdio_read(struct npe_softc *sc, int reg)
+{
+	uint32_t v;
+
+	/* NB: registers are known to be sequential */
+	v =  (MII_RD4(sc, reg+0) & 0xff) << 0;
+	v |= (MII_RD4(sc, reg+4) & 0xff) << 8;
+	v |= (MII_RD4(sc, reg+8) & 0xff) << 16;
+	v |= (MII_RD4(sc, reg+12) & 0xff) << 24;
+	return v;
+}
+
+static void
+npe_mii_mdio_write(struct npe_softc *sc, int reg, uint32_t cmd)
+{
+	/* NB: registers are known to be sequential */
+	MII_WR4(sc, reg+0, cmd & 0xff);
+	MII_WR4(sc, reg+4, (cmd >> 8) & 0xff);
+	MII_WR4(sc, reg+8, (cmd >> 16) & 0xff);
+	MII_WR4(sc, reg+12, (cmd >> 24) & 0xff);
+}
+
+static int
+npe_mii_mdio_wait(struct npe_softc *sc)
+{
+	uint32_t v;
+	int i;
+
+	/* NB: typically this takes 25-30 trips */
+	for (i = 0; i < 1000; i++) {
+		v = npe_mii_mdio_read(sc, NPE_MAC_MDIO_CMD);
+		if ((v & NPE_MII_GO) == 0)
+			return 1;
+		DELAY(1);
+	}
+	device_printf(sc->sc_dev, "%s: timeout after ~1ms, cmd 0x%x\n",
+	    __func__, v);
+	return 0;		/* NB: timeout */
+}
+
+static int
+npe_miibus_readreg(device_t dev, int phy, int reg)
+{
+	struct npe_softc *sc = device_get_softc(dev);
+	uint32_t v;
+
+	v = (phy << NPE_MII_ADDR_SHL) | (reg << NPE_MII_REG_SHL) | NPE_MII_GO;
+	npe_mii_mdio_write(sc, NPE_MAC_MDIO_CMD, v);
+	if (npe_mii_mdio_wait(sc))
+		v = npe_mii_mdio_read(sc, NPE_MAC_MDIO_STS);
+	else
+		v = 0xffff | NPE_MII_READ_FAIL;
+	return (v & NPE_MII_READ_FAIL) ? 0xffff : (v & 0xffff);
+}
+
+static int
+npe_miibus_writereg(device_t dev, int phy, int reg, int data)
+{
+	struct npe_softc *sc = device_get_softc(dev);
+	uint32_t v;
+
+	v = (phy << NPE_MII_ADDR_SHL) | (reg << NPE_MII_REG_SHL)
+	  | data | NPE_MII_WRITE
+	  | NPE_MII_GO;
+	npe_mii_mdio_write(sc, NPE_MAC_MDIO_CMD, v);
+	/* XXX complain about timeout */
+	(void) npe_mii_mdio_wait(sc);
+	return (0);
+}
+
+static void
+npe_miibus_statchg(device_t dev)
+{
+	struct npe_softc *sc = device_get_softc(dev);
+	struct mii_data *mii = device_get_softc(sc->sc_mii);
+	uint32_t tx1, rx1;
+
+	/* sync MAC duplex state */
+	tx1 = RD4(sc, NPE_MAC_TX_CNTRL1);
+	rx1 = RD4(sc, NPE_MAC_RX_CNTRL1);
+	if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX) {
+		tx1 &= ~NPE_TX_CNTRL1_DUPLEX;
+		rx1 |= NPE_RX_CNTRL1_PAUSE_EN;
+	} else {
+		tx1 |= NPE_TX_CNTRL1_DUPLEX;
+		rx1 &= ~NPE_RX_CNTRL1_PAUSE_EN;
+	}
+	WR4(sc, NPE_MAC_RX_CNTRL1, rx1);
+	WR4(sc, NPE_MAC_TX_CNTRL1, tx1);
+}
+
+static device_method_t npe_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		npe_probe),
+	DEVMETHOD(device_attach,	npe_attach),
+	DEVMETHOD(device_detach,	npe_detach),
+
+	/* Bus interface */
+	DEVMETHOD(bus_child_detached,	npe_child_detached),
+
+	/* MII interface */
+	DEVMETHOD(miibus_readreg,	npe_miibus_readreg),
+	DEVMETHOD(miibus_writereg,	npe_miibus_writereg),
+	DEVMETHOD(miibus_statchg,	npe_miibus_statchg),
+
+	{ 0, 0 }
+};
+
+static driver_t npe_driver = {
+	"npe",
+	npe_methods,
+	sizeof(struct npe_softc),
+};
+
+DRIVER_MODULE(npe, ixp, npe_driver, npe_devclass, 0, 0);
+DRIVER_MODULE(miibus, npe, miibus_driver, miibus_devclass, 0, 0);
+MODULE_DEPEND(npe, ixpqmgr, 1, 1, 1);
+MODULE_DEPEND(npe, miibus, 1, 1, 1);
+MODULE_DEPEND(npe, ether, 1, 1, 1);


Property changes on: trunk/sys/arm/xscale/ixp425/if_npe.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/ixp425/if_npereg.h
===================================================================
--- trunk/sys/arm/xscale/ixp425/if_npereg.h	                        (rev 0)
+++ trunk/sys/arm/xscale/ixp425/if_npereg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,282 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2006 Sam Leffler, Errno Consulting
+ * 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,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ *    redistribution must be conditioned upon including a substantially
+ *    similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
+ *
+ * $FreeBSD: stable/10/sys/arm/xscale/ixp425/if_npereg.h 236987 2012-06-13 04:38:09Z imp $
+ */
+
+/*
+ * Copyright (c) 2001-2005, Intel Corporation.
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ */
+
+#ifndef ARM_XSCALE_IF_NPEREG_H
+#define	ARM_XSCALE_IF_NPEREG_H
+
+/*
+ * NPE/NPE tx/rx descriptor format.  This is just the area
+ * shared with ucode running in the NPE; the driver-specific
+ * state is defined in the driver.  The shared area must be
+ * cacheline-aligned.  We allocate NPE_MAXSEG "descriptors"
+ * per buffer; this allows us to do minimal s/g.  The number
+ * of descriptors can be expanded but doing so uses memory
+ * so should be done with care.
+ *
+ * The driver sets up buffers in uncached memory.
+ */
+#define	NPE_MAXSEG	3		/* empirically selected */
+
+struct npehwbuf {
+	struct {			/* NPE shared area, cacheline aligned */
+		uint32_t next;		/* phys addr of next segment */
+		uint32_t len;		/* buffer/segment length (bytes) */
+		uint32_t data;		/* phys addr of data segment */
+		uint32_t pad[5];	/* pad to cacheline */
+	} ix_ne[NPE_MAXSEG];
+};
+
+#define NPE_FRAME_SIZE_DEFAULT	1536
+#define NPE_FRAME_SIZE_MAX	(65536-64)
+#define NPE_FRAME_SIZE_MIN	64
+
+/*
+ * Queue Manager-related definitions.
+ *
+ * These define the layout of 32-bit Q entries passed
+ * between the host cpu and the NPE's.
+ */
+#define	NPE_QM_Q_NPE(e)		(((e)>>0)&0x3)		/* NPE ID */
+#define	NPE_QM_Q_PORT(e)	(((e)>>3)&0x1)		/* Port ID */
+#define	NPE_QM_Q_PRIO(e)	(((e)>>0)&0x3)		/* 802.1d priority */
+#define	NPE_QM_Q_ADDR(e)	((e)&0xfffffffe0)	/* phys address */
+
+/*
+ * Host->NPE requests written to the shared mailbox.
+ * The NPE writes the same value back as an ACK.
+ */
+#define	NPE_GETSTATUS		0x00	/* get firmware revision */
+#define	NPE_SETPORTADDRESS	0x01	/* set port id and mac address */
+#define	NPE_GETMACADDRDB	0x02	/* upload filter database */
+#define	NPE_SETMACADDRDB	0x03	/* download filter database */
+#define	NPE_GETSTATS		0x04	/* get statistics */
+#define	NPE_RESETSTATS		0x05	/* reset stats + return result */
+#define	NPE_SETMAXFRAME		0x06	/* configure max tx/rx frame lengths */
+#define	NPE_SETRXTAGMODE	0x07	/* configure VLAN rx operating mode */
+#define	NPE_SETDEFRXVID		0x08	/* set def VLAN tag + traffic class */
+#define	NPE_SETRXQOSENTRY	0x0b	/* map user pri -> QoS class+rx qid */
+#define	NPE_SETFIREWALLMODE	0x0e	/* config firewall services */
+#define	NPE_SETLOOPBACK		0x12	/* enable/disable loopback */
+/* ... XXX more */
+
+#define	NPE_MAC_MSGID_SHL	24
+#define	NPE_MAC_PORTID_SHL	16
+
+/*
+ * MAC register definitions; see section
+ * 15.2 of the Intel Developers Manual.
+ */
+#define	NPE_MAC_TX_CNTRL1	0x000
+#define	NPE_MAC_TX_CNTRL2	0x004
+#define	NPE_MAC_RX_CNTRL1	0x010
+#define	NPE_MAC_RX_CNTRL2	0x014
+#define	NPE_MAC_RANDOM_SEED	0x020
+#define	NPE_MAC_THRESH_P_EMPTY	0x030
+#define	NPE_MAC_THRESH_P_FULL	0x038
+#define	NPE_MAC_BUF_SIZE_TX	0x040
+#define	NPE_MAC_TX_DEFER	0x050
+#define	NPE_MAC_RX_DEFER	0x054
+#define	NPE_MAC_TX_TWO_DEFER_1	0x060
+#define	NPE_MAC_TX_TWO_DEFER_2	0x064
+#define	NPE_MAC_SLOT_TIME	0x070
+#define	NPE_MAC_MDIO_CMD_1	0x080
+#define	NPE_MAC_MDIO_CMD_2	0x084
+#define	NPE_MAC_MDIO_CMD_3	0x088
+#define	NPE_MAC_MDIO_CMD_4	0x08c
+#define	NPE_MAC_MDIO_STS_1	0x090
+#define	NPE_MAC_MDIO_STS_2	0x094
+#define	NPE_MAC_MDIO_STS_3	0x098
+#define	NPE_MAC_MDIO_STS_4	0x09c
+#define	NPE_MAC_ADDR_MASK_1	0x0A0
+#define	NPE_MAC_ADDR_MASK_2	0x0A4
+#define	NPE_MAC_ADDR_MASK_3	0x0A8
+#define	NPE_MAC_ADDR_MASK_4	0x0AC
+#define	NPE_MAC_ADDR_MASK_5	0x0B0
+#define	NPE_MAC_ADDR_MASK_6	0x0B4
+#define	NPE_MAC_ADDR_1		0x0C0
+#define	NPE_MAC_ADDR_2		0x0C4
+#define	NPE_MAC_ADDR_3		0x0C8
+#define	NPE_MAC_ADDR_4		0x0CC
+#define	NPE_MAC_ADDR_5		0x0D0
+#define	NPE_MAC_ADDR_6		0x0D4
+#define	NPE_MAC_INT_CLK_THRESH	0x0E0
+#define	NPE_MAC_UNI_ADDR_1	0x0F0
+#define	NPE_MAC_UNI_ADDR_2	0x0F4
+#define	NPE_MAC_UNI_ADDR_3	0x0F8
+#define	NPE_MAC_UNI_ADDR_4	0x0FC
+#define	NPE_MAC_UNI_ADDR_5	0x100
+#define	NPE_MAC_UNI_ADDR_6	0x104
+#define	NPE_MAC_CORE_CNTRL	0x1FC
+
+#define	NPE_MAC_ADDR_MASK(i)    (NPE_MAC_ADDR_MASK_1 + ((i)<<2))
+#define	NPE_MAC_ADDR(i)     	(NPE_MAC_ADDR_1 + ((i)<<2))
+#define	NPE_MAC_UNI_ADDR(i)    	(NPE_MAC_UNI_ADDR_1 + ((i)<<2))
+
+/*
+ * Bit definitions
+ */
+
+/* TX Control Register 1*/
+#define	NPE_TX_CNTRL1_TX_EN		0x01	/* enable TX engine */
+#define	NPE_TX_CNTRL1_DUPLEX		0x02	/* select half duplex */
+#define	NPE_TX_CNTRL1_RETRY		0x04	/* auto-retry on collision */
+#define	NPE_TX_CNTRL1_PAD_EN		0x08	/* pad frames <64 bytes */
+#define	NPE_TX_CNTRL1_FCS_EN		0x10	/* append FCS */
+#define	NPE_TX_CNTRL1_2DEFER		0x20	/* select 2-part deferral */
+#define	NPE_TX_CNTRL1_RMII		0x40
+
+/* TX Control Register 2 */
+#define	NPE_TX_CNTRL2_RETRIES_MASK	0xf	/* max retry count */
+
+/* RX Control Register 1 */
+#define	NPE_RX_CNTRL1_RX_EN		0x01	/* enable RX engine */
+#define	NPE_RX_CNTRL1_PADSTRIP_EN	0x02	/* strip frame padding */
+#define	NPE_RX_CNTRL1_CRC_EN		0x04	/* include CRC in RX frame */
+#define	NPE_RX_CNTRL1_PAUSE_EN		0x08	/* detect Pause frames */
+#define	NPE_RX_CNTRL1_LOOP_EN		0x10	/* loopback tx/rx */
+#define	NPE_RX_CNTRL1_ADDR_FLTR_EN	0x20	/* enable address filtering */
+#define	NPE_RX_CNTRL1_RX_RUNT_EN	0x40	/* enable RX of runt frames */
+#define	NPE_RX_CNTRL1_BCAST_DIS		0x80	/* discard broadcast frames */
+
+/* RX Control Register 2 */
+#define	NPE_RX_CNTRL2_DEFER_EN	0x01
+
+/* Core Control Register */
+#define	NPE_CORE_RESET			0x01	/* MAC reset state */
+#define	NPE_CORE_RX_FIFO_FLUSH		0x02	/* flush RX FIFO */
+#define	NPE_CORE_TX_FIFO_FLUSH		0x04	/* flush TX FIFO */
+#define	NPE_CORE_SEND_JAM		0x08	/* send JAM on packet RX */
+#define	NPE_CORE_MDC_EN			0x10	/* IXP42X drives MDC clock */
+
+/*
+ * Stat block returned by NPE with NPE_GETSTATS msg.
+ */
+struct npestats {
+	uint32_t dot3StatsAlignmentErrors;
+	uint32_t dot3StatsFCSErrors;
+	uint32_t dot3StatsInternalMacReceiveErrors;
+	uint32_t RxOverrunDiscards;
+	uint32_t RxLearnedEntryDiscards;
+	uint32_t RxLargeFramesDiscards;
+	uint32_t RxSTPBlockedDiscards;
+	uint32_t RxVLANTypeFilterDiscards;
+	uint32_t RxVLANIdFilterDiscards;
+	uint32_t RxInvalidSourceDiscards;
+	uint32_t RxBlackListDiscards;
+	uint32_t RxWhiteListDiscards;
+	uint32_t RxUnderflowEntryDiscards;
+	uint32_t dot3StatsSingleCollisionFrames;
+	uint32_t dot3StatsMultipleCollisionFrames;
+	uint32_t dot3StatsDeferredTransmissions;
+	uint32_t dot3StatsLateCollisions;
+	uint32_t dot3StatsExcessiveCollisions;
+	uint32_t dot3StatsInternalMacTransmitErrors;
+	uint32_t dot3StatsCarrierSenseErrors;
+	uint32_t TxLargeFrameDiscards;
+	uint32_t TxVLANIdFilterDiscards;
+};
+
+/*
+ * Default values
+ */
+#define NPE_MAC_INT_CLK_THRESH_DEFAULT  0x1
+
+#define NPE_MAC_RESET_DELAY    1
+
+/* This value applies to RMII */
+#define NPE_MAC_SLOT_TIME_RMII_DEFAULT  0xFF
+
+/*
+ * MII definitions - these have been verified against the LXT971 and LXT972 PHYs
+ */
+#define	NPE_MII_REG_SHL		16
+#define	NPE_MII_ADDR_SHL	21
+
+/* NB: shorthands for mii bus mdio routines */
+#define	NPE_MAC_MDIO_CMD	NPE_MAC_MDIO_CMD_1
+#define	NPE_MAC_MDIO_STS	NPE_MAC_MDIO_STS_1
+
+#define NPE_MII_GO                  (1<<31)
+#define NPE_MII_WRITE               (1<<26)
+#define NPE_MII_TIMEOUT_10TH_SECS        5
+#define NPE_MII_10TH_SEC_IN_MILLIS     100
+#define NPE_MII_READ_FAIL           (1<<31)
+
+#define NPE_MII_PHY_DEF_DELAY	300	/* max delay before link up, etc. */
+#define NPE_MII_PHY_NO_DELAY	0x0	/* do not delay */
+#define NPE_MII_PHY_NULL	0xff	/* PHY is not present */
+#define NPE_MII_PHY_DEF_ADDR	0x0	/* default PHY's logical address */
+
+/* Register definition */
+#define NPE_MII_CTRL_REG	0x0	/* Control Register */
+#define NPE_MII_STAT_REG	0x1	/* Status Register */
+#define NPE_MII_PHY_ID1_REG	0x2	/* PHY identifier 1 Register */
+#define NPE_MII_PHY_ID2_REG	0x3	/* PHY identifier 2 Register */
+#define NPE_MII_AN_ADS_REG	0x4	/* Auto-Negotiation 	  */
+					/* Advertisement Register */
+#define NPE_MII_AN_PRTN_REG	0x5	/* Auto-Negotiation 	    */
+					/* partner ability Register */
+#define NPE_MII_AN_EXP_REG	0x6	/* Auto-Negotiation   */
+					/* Expansion Register */
+#define NPE_MII_AN_NEXT_REG	0x7	/* Auto-Negotiation 	       */
+					/* next-page transmit Register */
+#endif /* ARM_XSCALE_IF_NPEREG_H */


Property changes on: trunk/sys/arm/xscale/ixp425/if_npereg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/ixp425/ixdp425_pci.c
===================================================================
--- trunk/sys/arm/xscale/ixp425/ixdp425_pci.c	                        (rev 0)
+++ trunk/sys/arm/xscale/ixp425/ixdp425_pci.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,174 @@
+/* $MidnightBSD$ */
+/*      $NetBSD: ixdp425_pci.c,v 1.5 2005/12/11 12:17:09 christos Exp $ */
+/*
+ * Copyright (c) 2003
+ *	Ichiro FUKUHARA <ichiro at ichiro.org>.
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Ichiro FUKUHARA.
+ * 4. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ICHIRO FUKUHARA ``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 ICHIRO FUKUHARA OR THE VOICES IN HIS HEAD 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: stable/10/sys/arm/xscale/ixp425/ixdp425_pci.c 229125 2011-12-31 15:53:34Z marius $");
+
+#define _ARM32_BUS_DMA_PRIVATE
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+
+#include <dev/pci/pcivar.h>
+
+#include <machine/bus.h>
+#include <machine/intr.h>
+
+#include <arm/xscale/ixp425/ixp425reg.h>
+#include <arm/xscale/ixp425/ixp425var.h>
+#include <arm/xscale/ixp425/ixp425_intr.h>
+#include <arm/xscale/ixp425/ixdp425reg.h>
+
+void
+ixp425_md_attach(device_t dev)
+{
+	struct ixp425_softc *sc = device_get_softc(device_get_parent(dev));
+	struct ixppcib_softc *pci_sc = device_get_softc(dev);
+	uint32_t reg;
+
+	
+	/* PCI Reset Assert */
+	reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPOUTR);
+	reg &= ~(1U << GPIO_PCI_RESET);
+	GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPOUTR, reg);
+
+	/* PCI Clock Disable */
+	reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPCLKR);
+	reg &= ~GPCLKR_MUX14;
+	GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPCLKR, reg);
+
+	/*
+	 * set GPIO Direction
+	 *	Output: PCI_CLK, PCI_RESET
+	 *	Input:  PCI_INTA, PCI_INTB, PCI_INTC, PCI_INTD
+	 */
+	reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPOER);
+	reg &= ~(1U << GPIO_PCI_CLK);
+	reg &= ~(1U << GPIO_PCI_RESET);
+	reg |= ((1U << GPIO_PCI_INTA) | (1U << GPIO_PCI_INTB) |
+		(1U << GPIO_PCI_INTC) | (1U << GPIO_PCI_INTD));
+	GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPOER, reg);
+
+	/*
+	 * Set GPIO interrupt type
+	 * 	PCI_INT_A, PCI_INTB, PCI_INT_C, PCI_INT_D: Active Low
+	 */
+	reg = GPIO_CONF_READ_4(sc, GPIO_TYPE_REG(GPIO_PCI_INTA));
+	reg &= ~GPIO_TYPE(GPIO_PCI_INTA, GPIO_TYPE_MASK);
+	reg |= GPIO_TYPE(GPIO_PCI_INTA, GPIO_TYPE_ACT_LOW);
+	GPIO_CONF_WRITE_4(sc, GPIO_TYPE_REG(GPIO_PCI_INTA), reg);
+
+	reg = GPIO_CONF_READ_4(sc, GPIO_TYPE_REG(GPIO_PCI_INTB));
+	reg &= ~GPIO_TYPE(GPIO_PCI_INTB, GPIO_TYPE_MASK);
+	reg |= GPIO_TYPE(GPIO_PCI_INTB, GPIO_TYPE_ACT_LOW);
+	GPIO_CONF_WRITE_4(sc, GPIO_TYPE_REG(GPIO_PCI_INTB), reg);
+
+	reg = GPIO_CONF_READ_4(sc, GPIO_TYPE_REG(GPIO_PCI_INTC));
+	reg &= ~GPIO_TYPE(GPIO_PCI_INTC, GPIO_TYPE_MASK);
+	reg |= GPIO_TYPE(GPIO_PCI_INTC, GPIO_TYPE_ACT_LOW);
+	GPIO_CONF_WRITE_4(sc, GPIO_TYPE_REG(GPIO_PCI_INTC), reg);
+
+	reg = GPIO_CONF_READ_4(sc, GPIO_TYPE_REG(GPIO_PCI_INTD));
+	reg &= ~GPIO_TYPE(GPIO_PCI_INTD, GPIO_TYPE_MASK);
+	reg |= GPIO_TYPE(GPIO_PCI_INTD, GPIO_TYPE_ACT_LOW);
+	GPIO_CONF_WRITE_4(sc, GPIO_TYPE_REG(GPIO_PCI_INTD), reg);
+
+	/* clear ISR */
+	GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPISR,
+			  (1U << GPIO_PCI_INTA) | (1U << GPIO_PCI_INTB) |
+			  (1U << GPIO_PCI_INTC) | (1U << GPIO_PCI_INTD));
+
+	/* wait 1ms to satisfy "minimum reset assertion time" of the PCI spec */
+	DELAY(1000);
+	reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPCLKR);
+	GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPCLKR, reg |
+		(0xf << GPCLKR_CLK0DC_SHIFT) | (0xf << GPCLKR_CLK0TC_SHIFT));
+
+	/* PCI Clock Enable */
+	reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPCLKR);
+	reg |= GPCLKR_MUX14;
+	GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPCLKR, reg | GPCLKR_MUX14);
+
+	/*
+	 * wait 100us to satisfy "minimum reset assertion time from clock stable
+	 * requirement of the PCI spec
+	 */
+	DELAY(100);
+        /* PCI Reset deassert */
+	reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPOUTR);
+	reg |= 1U << GPIO_PCI_RESET;
+	GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPOUTR, reg | (1U << GPIO_PCI_RESET));
+	pci_sc->sc_irq_rman.rm_type = RMAN_ARRAY;
+	pci_sc->sc_irq_rman.rm_descr = "IXP425 PCI IRQs";
+	CTASSERT(PCI_INT_D < PCI_INT_A);
+	/* XXX this overlaps the irq's setup in ixp425_attach */
+	if (rman_init(&pci_sc->sc_irq_rman) != 0 ||
+	    rman_manage_region(&pci_sc->sc_irq_rman, PCI_INT_D, PCI_INT_A) != 0)
+		panic("ixp425_md_attach: failed to set up IRQ rman");
+}
+
+#define	IXP425_MAX_DEV	5
+#define	IXP425_MAX_LINE	4
+
+int
+ixp425_md_route_interrupt(device_t bridge, device_t device, int pin)
+{
+	static int ixp425_pci_table[IXP425_MAX_DEV][IXP425_MAX_LINE] = {
+		{PCI_INT_A, PCI_INT_B, PCI_INT_C, PCI_INT_D},
+		{PCI_INT_B, PCI_INT_C, PCI_INT_D, PCI_INT_A},
+		{PCI_INT_C, PCI_INT_D, PCI_INT_A, PCI_INT_B},
+		{PCI_INT_D, PCI_INT_A, PCI_INT_B, PCI_INT_C},
+		/* NB: for optional USB controller on Gateworks Avila */
+		{PCI_INT_A, PCI_INT_B, PCI_INT_C, PCI_INT_D},
+	};
+	int dev;
+	
+	dev = pci_get_slot(device);
+	if (bootverbose)
+		device_printf(bridge, "routing pin %d for %s\n", pin,
+		    device_get_nameunit(device));
+	if (pin >= 1 && pin <= IXP425_MAX_LINE &&
+	    dev >= 1 && dev <= IXP425_MAX_DEV) {
+		return (ixp425_pci_table[dev - 1][pin - 1]);
+	} else
+		printf("ixppcib: no mapping for %d/%d/%d\n",
+			pci_get_bus(device), dev, pci_get_function(device));
+
+	return (-1);
+}


Property changes on: trunk/sys/arm/xscale/ixp425/ixdp425_pci.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/ixp425/ixdp425reg.h
===================================================================
--- trunk/sys/arm/xscale/ixp425/ixdp425reg.h	                        (rev 0)
+++ trunk/sys/arm/xscale/ixp425/ixdp425reg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,55 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: ixdp425reg.h,v 1.6 2005/12/11 12:17:09 christos Exp $ */
+/*
+ * Copyright (c) 2003
+ *	Ichiro FUKUHARA <ichiro at ichiro.org>.
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Ichiro FUKUHARA.
+ * 4. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ICHIRO FUKUHARA ``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 ICHIRO FUKUHARA OR THE VOICES IN HIS HEAD 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: stable/10/sys/arm/xscale/ixp425/ixdp425reg.h 164763 2006-11-30 06:30:01Z kevlo $ */
+#ifndef	_IXDP425REG_H_
+#define	_IXDP425REG_H_
+/* GPIOs */
+#define	GPIO_PCI_CLK	14
+#define	GPIO_PCI_RESET	13
+#define	GPIO_PCI_INTA	11
+#define	GPIO_PCI_INTB	10
+#define	GPIO_PCI_INTC	9
+#define	GPIO_PCI_INTD	8
+#define	GPIO_I2C_SDA	7
+#define  GPIO_I2C_SDA_BIT	(1U << GPIO_I2C_SDA)
+#define	GPIO_I2C_SCL	6
+#define	  GPIO_I2C_SCL_BIT	(1U << GPIO_I2C_SCL)
+/* Interrupt */
+#define	PCI_INT_A	IXP425_INT_GPIO_11
+#define	PCI_INT_B	IXP425_INT_GPIO_10
+#define	PCI_INT_C	IXP425_INT_GPIO_9
+#define	PCI_INT_D	IXP425_INT_GPIO_8
+#endif /* _IXDP425REG_H_ */


Property changes on: trunk/sys/arm/xscale/ixp425/ixdp425reg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/ixp425/ixp425.c
===================================================================
--- trunk/sys/arm/xscale/ixp425/ixp425.c	                        (rev 0)
+++ trunk/sys/arm/xscale/ixp425/ixp425.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,697 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: ixp425.c,v 1.10 2005/12/11 12:16:51 christos Exp $ */
+
+/*
+ * Copyright (c) 2003
+ *	Ichiro FUKUHARA <ichiro at ichiro.org>.
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Ichiro FUKUHARA.
+ * 4. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ICHIRO FUKUHARA ``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 ICHIRO FUKUHARA OR THE VOICES IN HIS HEAD 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: stable/10/sys/arm/xscale/ixp425/ixp425.c 278613 2015-02-12 03:50:33Z ian $");
+
+#include "opt_ddb.h"
+
+#define _ARM32_BUS_DMA_PRIVATE
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <machine/armreg.h>
+#include <machine/bus.h>
+#include <machine/intr.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <arm/xscale/ixp425/ixp425reg.h>
+#include <arm/xscale/ixp425/ixp425var.h>
+#include <arm/xscale/ixp425/ixp425_intr.h>
+
+#include <dev/pci/pcireg.h>
+
+volatile uint32_t intr_enabled;
+uint32_t intr_steer = 0;
+
+/* ixp43x et. al have +32 IRQ's */
+volatile uint32_t intr_enabled2;
+uint32_t intr_steer2 = 0;
+
+struct	ixp425_softc *ixp425_softc = NULL;
+
+struct mtx ixp425_gpio_mtx;
+
+static int	ixp425_probe(device_t);
+static void	ixp425_identify(driver_t *, device_t);
+static int	ixp425_attach(device_t);
+
+/*
+ * Return a mask of the "fuse" bits that identify
+ * which h/w features are present.
+ * NB: assumes the expansion bus is mapped.
+ */
+uint32_t
+ixp4xx_read_feature_bits(void)
+{
+	uint32_t bits = ~IXPREG(IXP425_EXP_VBASE + EXP_FCTRL_OFFSET);
+	bits &= ~EXP_FCTRL_RESVD;
+	if (!cpu_is_ixp46x())
+		bits &= ~EXP_FCTRL_IXP46X_ONLY;
+	return bits;
+}
+
+void
+ixp4xx_write_feature_bits(uint32_t v)
+{
+	IXPREG(IXP425_EXP_VBASE + EXP_FCTRL_OFFSET) = ~v;
+}
+
+struct arm32_dma_range *
+bus_dma_get_range(void)
+{
+	return (NULL);
+}
+
+int
+bus_dma_get_range_nb(void)
+{
+	return (0);
+}
+
+static const uint8_t int2gpio[32] __attribute__ ((aligned(32))) = {
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff,	/* INT#0 -> INT#5 */
+	0x00, 0x01,				/* GPIO#0 -> GPIO#1 */
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff,	/* INT#8 -> INT#13 */
+	0xff, 0xff, 0xff, 0xff, 0xff,		/* INT#14 -> INT#18 */
+	0x02, 0x03, 0x04, 0x05, 0x06, 0x07,	/* GPIO#2 -> GPIO#7 */
+	0x08, 0x09, 0x0a, 0x0b, 0x0c,		/* GPIO#8 -> GPIO#12 */
+	0xff, 0xff				/* INT#30 -> INT#31 */
+};
+
+static __inline uint32_t
+ixp425_irq2gpio_bit(int irq)
+{
+	return (1U << int2gpio[irq]);
+}
+
+#ifdef DDB
+#include <ddb/ddb.h>
+
+DB_SHOW_COMMAND(gpio, db_show_gpio)
+{
+	static const char *itype[8] = {
+		[GPIO_TYPE_ACT_HIGH]	= "act-high",
+		[GPIO_TYPE_ACT_LOW]	= "act-low",
+		[GPIO_TYPE_EDG_RISING]	= "edge-rising",
+		[GPIO_TYPE_EDG_FALLING]	= "edge-falling",
+		[GPIO_TYPE_TRANSITIONAL]= "transitional",
+		[5] = "type-5", [6] = "type-6", [7] = "type-7"
+	};
+	uint32_t gpoutr = GPIO_CONF_READ_4(ixp425_softc, IXP425_GPIO_GPOUTR);
+	uint32_t gpoer = GPIO_CONF_READ_4(ixp425_softc, IXP425_GPIO_GPOER);
+	uint32_t gpinr = GPIO_CONF_READ_4(ixp425_softc, IXP425_GPIO_GPINR);
+	uint32_t gpit1r = GPIO_CONF_READ_4(ixp425_softc, IXP425_GPIO_GPIT1R);
+	uint32_t gpit2r = GPIO_CONF_READ_4(ixp425_softc, IXP425_GPIO_GPIT2R);
+	int i, j;
+
+	db_printf("GPOUTR %08x GPINR  %08x GPOER  %08x GPISR %08x\n",
+	   gpoutr, gpinr, gpoer,
+	   GPIO_CONF_READ_4(ixp425_softc, IXP425_GPIO_GPISR));
+	db_printf("GPIT1R %08x GPIT2R %08x GPCLKR %08x\n",
+	   gpit1r, gpit2r, GPIO_CONF_READ_4(ixp425_softc, IXP425_GPIO_GPCLKR));
+	for (i = 0; i < 16; i++) {
+		db_printf("[%2d] out %u in %u %-3s", i,
+		    (gpoutr>>i)&1, (gpinr>>i)&1, (gpoer>>i)&1 ? "in" : "out");
+		for (j = 0; j < 32; j++)
+			if (int2gpio[j] == i) {
+				db_printf(" irq %2u %s", j, itype[
+				    (((i & 8) ? gpit2r : gpit1r) >> (3*(i&7)))
+					& 7]);
+				break;
+			}
+		db_printf("\n");
+	}
+}
+#endif
+
+void
+ixp425_set_gpio(struct ixp425_softc *sc, int pin, int type)
+{
+	uint32_t gpiotr = GPIO_CONF_READ_4(sc, GPIO_TYPE_REG(pin));
+
+	IXP4XX_GPIO_LOCK();
+	/* clear interrupt type */
+	GPIO_CONF_WRITE_4(sc, GPIO_TYPE_REG(pin),
+	    gpiotr &~ GPIO_TYPE(pin, GPIO_TYPE_MASK));
+	/* clear any pending interrupt */
+	GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPISR, (1<<pin));
+	/* set new interrupt type */
+	GPIO_CONF_WRITE_4(sc, GPIO_TYPE_REG(pin),
+	    gpiotr | GPIO_TYPE(pin, type));
+
+	/* configure gpio line as an input */
+	GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPOER,
+	    GPIO_CONF_READ_4(sc, IXP425_GPIO_GPOER) | (1<<pin));
+	IXP4XX_GPIO_UNLOCK();
+}
+
+static __inline void
+ixp425_gpio_ack(int irq)
+{
+	if (irq < 32 && ((1 << irq) & IXP425_INT_GPIOMASK))
+		IXPREG(IXP425_GPIO_VBASE + IXP425_GPIO_GPISR) =
+		    ixp425_irq2gpio_bit(irq);
+}
+
+static void
+ixp425_post_filter(void *arg)
+{
+	uintptr_t irq = (uintptr_t) arg;
+	ixp425_gpio_ack(irq);
+}
+
+void
+arm_mask_irq(uintptr_t nb)
+{
+	int i;
+
+	i = disable_interrupts(PSR_I);
+	if (nb < 32) {
+		intr_enabled &= ~(1 << nb);
+		ixp425_set_intrmask();
+	} else {
+		intr_enabled2 &= ~(1 << (nb - 32));
+		ixp435_set_intrmask();
+	}
+	restore_interrupts(i);
+	/*XXX; If it's a GPIO interrupt, ACK it know. Can it be a problem ?*/
+	ixp425_gpio_ack(nb);
+}
+
+void
+arm_unmask_irq(uintptr_t nb)
+{
+	int i;
+
+	i = disable_interrupts(PSR_I);
+	if (nb < 32) {
+		intr_enabled |= (1 << nb);
+		ixp425_set_intrmask();
+	} else {
+		intr_enabled2 |= (1 << (nb - 32));
+		ixp435_set_intrmask();
+	}
+	restore_interrupts(i);
+}
+
+static __inline uint32_t
+ixp425_irq_read(void)
+{
+	return IXPREG(IXP425_INT_STATUS) & intr_enabled;
+}
+
+static __inline uint32_t
+ixp435_irq_read(void)
+{
+	return IXPREG(IXP435_INT_STATUS2) & intr_enabled2;
+}
+
+int
+arm_get_next_irq(int last)
+{
+	uint32_t mask;
+
+	last += 1;		/* always advance fwd, NB: handles -1 */
+	if (last < 32) {
+		mask = ixp425_irq_read() >> last;
+		for (; mask != 0; mask >>= 1, last++) {
+			if (mask & 1)
+				return last;
+		}
+		last = 32;
+	}
+	if (cpu_is_ixp43x()) {
+		mask = ixp435_irq_read() >> (32-last);
+		for (; mask != 0; mask >>= 1, last++) {
+			if (mask & 1)
+				return last;
+		}
+	}
+	return -1;
+}
+
+void
+cpu_reset(void)
+{
+
+	bus_space_write_4(&ixp425_bs_tag, IXP425_TIMER_VBASE,
+	    IXP425_OST_WDOG_KEY, OST_WDOG_KEY_MAJICK);
+	bus_space_write_4(&ixp425_bs_tag, IXP425_TIMER_VBASE,
+	    IXP425_OST_WDOG, 0);
+	bus_space_write_4(&ixp425_bs_tag, IXP425_TIMER_VBASE,
+	    IXP425_OST_WDOG_ENAB, OST_WDOG_ENAB_RST_ENA |
+	    OST_WDOG_ENAB_CNT_ENA);
+	printf("Reset failed!\n");
+	for(;;);
+}
+
+static void
+ixp425_identify(driver_t *driver, device_t parent)
+{
+	BUS_ADD_CHILD(parent, 0, "ixp", 0);
+}
+
+static int
+ixp425_probe(device_t dev)
+{
+	device_set_desc(dev, "Intel IXP4XX");
+	return (0);
+}
+
+static int
+ixp425_attach(device_t dev)
+{
+	struct ixp425_softc *sc;
+
+	device_printf(dev, "%b\n", ixp4xx_read_feature_bits(), EXP_FCTRL_BITS);
+
+	sc = device_get_softc(dev);
+	sc->sc_iot = &ixp425_bs_tag;
+	KASSERT(ixp425_softc == NULL, ("%s called twice?", __func__));
+	ixp425_softc = sc;
+
+	intr_enabled = 0;
+	ixp425_set_intrmask();
+	ixp425_set_intrsteer();
+	if (cpu_is_ixp43x()) {
+		intr_enabled2 = 0;
+		ixp435_set_intrmask();
+		ixp435_set_intrsteer();
+	}
+	arm_post_filter = ixp425_post_filter;
+
+	mtx_init(&ixp425_gpio_mtx, "gpio", NULL, MTX_DEF);
+	if (bus_space_map(sc->sc_iot, IXP425_GPIO_HWBASE, IXP425_GPIO_SIZE,
+	    0, &sc->sc_gpio_ioh))
+		panic("%s: unable to map GPIO registers", __func__);
+	if (bus_space_map(sc->sc_iot, IXP425_EXP_HWBASE, IXP425_EXP_SIZE,
+	    0, &sc->sc_exp_ioh))
+		panic("%s: unable to map Expansion Bus registers", __func__);
+
+	/* XXX belongs in platform init */
+	if (cpu_is_ixp43x())
+		cambria_exp_bus_init(sc);
+
+	if (bus_dma_tag_create(NULL, 1, 0, BUS_SPACE_MAXADDR_32BIT,
+	    BUS_SPACE_MAXADDR, NULL, NULL,  0xffffffff, 0xff, 0xffffffff, 0,
+	    NULL, NULL, &sc->sc_dmat))
+		panic("%s: failed to create dma tag", __func__);
+
+	sc->sc_irq_rman.rm_type = RMAN_ARRAY;
+	sc->sc_irq_rman.rm_descr = "IXP4XX IRQs";
+	if (rman_init(&sc->sc_irq_rman) != 0 ||
+	    rman_manage_region(&sc->sc_irq_rman, 0, cpu_is_ixp43x() ? 63 : 31) != 0)
+		panic("%s: failed to set up IRQ rman", __func__);
+
+	sc->sc_mem_rman.rm_type = RMAN_ARRAY;
+	sc->sc_mem_rman.rm_descr = "IXP4XX Memory";
+	if (rman_init(&sc->sc_mem_rman) != 0 ||
+	    rman_manage_region(&sc->sc_mem_rman, 0, ~0) != 0)
+		panic("%s: failed to set up memory rman", __func__);
+
+	BUS_ADD_CHILD(dev, 0, "pcib", 0);
+	BUS_ADD_CHILD(dev, 0, "ixpclk", 0);
+	BUS_ADD_CHILD(dev, 0, "ixpiic", 0);
+	/* XXX move to hints? */
+	BUS_ADD_CHILD(dev, 0, "ixpwdog", 0);
+
+	/* attach wired devices via hints */
+	bus_enumerate_hinted_children(dev);
+
+	bus_generic_probe(dev);
+	bus_generic_attach(dev);
+
+	return (0);
+}
+
+static void
+ixp425_hinted_child(device_t bus, const char *dname, int dunit)
+{
+	device_t child;
+	struct ixp425_ivar *ivar;
+
+	child = BUS_ADD_CHILD(bus, 0, dname, dunit);
+	ivar = IXP425_IVAR(child);
+	resource_int_value(dname, dunit, "addr", &ivar->addr);
+	resource_int_value(dname, dunit, "irq", &ivar->irq);
+}
+
+static device_t
+ixp425_add_child(device_t dev, u_int order, const char *name, int unit)
+{
+	device_t child;
+	struct ixp425_ivar *ivar;
+
+	child = device_add_child_ordered(dev, order, name, unit);
+	if (child == NULL)
+		return NULL;
+	ivar = malloc(sizeof(struct ixp425_ivar), M_DEVBUF, M_NOWAIT);
+	if (ivar == NULL) {
+		device_delete_child(dev, child);
+		return NULL;
+	}
+	ivar->addr = 0;
+	ivar->irq = -1;
+	device_set_ivars(child, ivar);
+	return child;
+}
+
+static int
+ixp425_read_ivar(device_t bus, device_t child, int which, uintptr_t *result)
+{
+	struct ixp425_ivar *ivar = IXP425_IVAR(child);
+
+	switch (which) {
+	case IXP425_IVAR_ADDR:
+		if (ivar->addr != 0) {
+			*(uint32_t *)result = ivar->addr;
+			return 0;
+		}
+		break;
+	case IXP425_IVAR_IRQ:
+		if (ivar->irq != -1) {
+			*(int *)result = ivar->irq;
+			return 0;
+		}
+		break;
+	}
+	return EINVAL;
+}
+
+/*
+ * NB: This table handles P->V translations for regions setup with
+ * static mappings in initarm.  This is used solely for calls to
+ * bus_alloc_resource_any; anything done with bus_space_map is
+ * handled elsewhere and does not require an entry here.
+ *
+ * XXX this table is also used by uart_cpu_getdev via getvbase
+ *    (hence the public api)
+ */
+struct hwvtrans {
+	uint32_t	hwbase;
+	uint32_t	size;
+	uint32_t	vbase;
+	int		isa4x;	/* XXX needs special bus space tag */
+	int		isslow;	/* XXX needs special bus space tag */
+};
+
+static const struct hwvtrans *
+gethwvtrans(uint32_t hwbase, uint32_t size)
+{
+	static const struct hwvtrans hwvtrans[] = {
+	    /* NB: needed only for uart_cpu_getdev */
+	    { .hwbase	= IXP425_UART0_HWBASE,
+	      .size 	= IXP425_REG_SIZE,
+	      .vbase	= IXP425_UART0_VBASE,
+	      .isa4x	= 1 },
+	    { .hwbase	= IXP425_UART1_HWBASE,
+	      .size 	= IXP425_REG_SIZE,
+	      .vbase	= IXP425_UART1_VBASE,
+	      .isa4x	= 1 },
+	    { .hwbase	= IXP425_PCI_HWBASE,
+	      .size 	= IXP425_PCI_SIZE,
+	      .vbase	= IXP425_PCI_VBASE },
+	    { .hwbase	= IXP425_PCI_MEM_HWBASE,
+	      .size 	= IXP425_PCI_MEM_SIZE,
+	      .vbase	= IXP425_PCI_MEM_VBASE },
+	    { .hwbase	= IXP425_EXP_BUS_CS0_HWBASE,
+	      .size 	= IXP425_EXP_BUS_CS0_SIZE,
+	      .vbase	= IXP425_EXP_BUS_CS0_VBASE },
+	    /* NB: needed for ixp435 ehci controllers */
+	    { .hwbase	= IXP435_USB1_HWBASE,
+	      .size 	= IXP435_USB1_SIZE,
+	      .vbase	= IXP435_USB1_VBASE },
+	    { .hwbase	= IXP435_USB2_HWBASE,
+	      .size 	= IXP435_USB2_SIZE,
+	      .vbase	= IXP435_USB2_VBASE },
+	    { .hwbase	= CAMBRIA_GPS_HWBASE,
+	      .size 	= CAMBRIA_GPS_SIZE,
+	      .vbase	= CAMBRIA_GPS_VBASE,
+	      .isslow	= 1 },
+	    { .hwbase	= CAMBRIA_RS485_HWBASE,
+	      .size 	= CAMBRIA_RS485_SIZE,
+	      .vbase	= CAMBRIA_RS485_VBASE,
+	      .isslow	= 1 },
+	};
+	int i;
+
+	for (i = 0; i < sizeof hwvtrans / sizeof *hwvtrans; i++) {
+		if (hwbase >= hwvtrans[i].hwbase &&
+		    hwbase + size <= hwvtrans[i].hwbase + hwvtrans[i].size)
+			return &hwvtrans[i];
+	}
+	return NULL;
+}
+
+/* XXX for uart_cpu_getdev */
+int
+getvbase(uint32_t hwbase, uint32_t size, uint32_t *vbase)
+{
+	const struct hwvtrans *hw;
+
+	hw = gethwvtrans(hwbase, size);
+	if (hw == NULL)
+		return (ENOENT);
+	*vbase = hwbase - hw->hwbase + hw->vbase;
+	return (0);
+}
+
+static struct resource *
+ixp425_alloc_resource(device_t dev, device_t child, int type, int *rid,
+    u_long start, u_long end, u_long count, u_int flags)
+{
+	struct ixp425_softc *sc = device_get_softc(dev);
+	const struct hwvtrans *vtrans;
+	struct resource *rv;
+	uint32_t addr;
+	int needactivate = flags & RF_ACTIVE;
+	int irq;
+
+	flags &= ~RF_ACTIVE;
+	switch (type) {
+	case SYS_RES_IRQ:
+		/* override per hints */
+		if (BUS_READ_IVAR(dev, child, IXP425_IVAR_IRQ, &irq) == 0)
+			start = end = irq;
+		rv = rman_reserve_resource(&sc->sc_irq_rman, start, end, count,
+		    flags, child);
+		if (rv != NULL)
+			rman_set_rid(rv, *rid);
+		break;
+
+	case SYS_RES_MEMORY:
+		/* override per hints */
+		if (BUS_READ_IVAR(dev, child, IXP425_IVAR_ADDR, &addr) == 0) {
+			start = addr;
+			/* XXX use nominal window to check for mapping */
+			vtrans = gethwvtrans(start, 0x1000);
+			if (vtrans != NULL) {
+				/*
+				 * Assign the entire mapped region; this may
+				 * not be correct but without more info from
+				 * the caller we cannot tell.
+				 */
+				end = start + vtrans->size -
+				    (start - vtrans->hwbase);
+				if (bootverbose)
+					device_printf(child,
+					    "%s: assign 0x%lx:0x%lx%s\n",
+					    __func__, start, end - start,
+					    vtrans->isa4x ? " A4X" :
+					    vtrans->isslow ? " SLOW" : "");
+			}
+		} else
+			vtrans = gethwvtrans(start, end - start);
+		if (vtrans == NULL) {
+			/* likely means above table needs to be updated */
+			device_printf(child, "%s: no mapping for 0x%lx:0x%lx\n",
+			    __func__, start, end - start);
+			return NULL;
+		}
+		rv = rman_reserve_resource(&sc->sc_mem_rman, start, end,
+		    end - start, flags, child);
+		if (rv == NULL) {
+			device_printf(child, "%s: cannot reserve 0x%lx:0x%lx\n",
+			    __func__, start, end - start);
+			return NULL;
+		}
+		rman_set_rid(rv, *rid);
+		break;
+	default:
+		rv = NULL;
+		break;
+	}
+	if (rv != NULL && needactivate) {
+		if (bus_activate_resource(child, type, *rid, rv)) {
+			rman_release_resource(rv);
+			return (NULL);
+		}
+	}
+	return (rv);
+}
+
+static int
+ixp425_release_resource(device_t bus, device_t child, int type, int rid,
+    struct resource *r)
+{
+	/* NB: no private resources, just release */
+	return rman_release_resource(r);
+}
+
+static int
+ixp425_activate_resource(device_t dev, device_t child, int type, int rid,
+    struct resource *r)
+{
+	struct ixp425_softc *sc = device_get_softc(dev);
+	const struct hwvtrans *vtrans;
+
+	if (type == SYS_RES_MEMORY) {
+		vtrans = gethwvtrans(rman_get_start(r), rman_get_size(r));
+		if (vtrans == NULL) {		/* NB: should not happen */
+			device_printf(child, "%s: no mapping for 0x%lx:0x%lx\n",
+			    __func__, rman_get_start(r), rman_get_size(r));
+			return (ENOENT);
+		}
+		if (vtrans->isa4x)
+			rman_set_bustag(r, &ixp425_a4x_bs_tag);
+		else if (vtrans->isslow)
+			rman_set_bustag(r, &cambria_exp_bs_tag);
+		else
+			rman_set_bustag(r, sc->sc_iot);
+		rman_set_bushandle(r, vtrans->vbase);
+	}
+	return (rman_activate_resource(r));
+}
+
+static int
+ixp425_deactivate_resource(device_t bus, device_t child, int type, int rid,
+    struct resource *r)
+{
+	/* NB: no private resources, just deactive */
+	return (rman_deactivate_resource(r));
+}
+
+static __inline void
+get_masks(struct resource *res, uint32_t *mask, uint32_t *mask2)
+{
+	int i;
+
+	*mask = 0;
+	for (i = rman_get_start(res); i < 32 && i <= rman_get_end(res); i++)
+		*mask |= 1 << i;
+	*mask2 = 0;
+	for (; i <= rman_get_end(res); i++)
+		*mask2 |= 1 << (i - 32);
+}
+
+static __inline void
+update_masks(uint32_t mask, uint32_t mask2)
+{
+
+	intr_enabled = mask;
+	ixp425_set_intrmask();
+	if (cpu_is_ixp43x()) {
+		intr_enabled2 = mask2;
+		ixp435_set_intrmask();
+	}
+}
+
+static int
+ixp425_setup_intr(device_t dev, device_t child,
+    struct resource *res, int flags, driver_filter_t *filt,
+    driver_intr_t *intr, void *arg, void **cookiep)
+{
+	uint32_t mask, mask2;
+	int error;
+
+	error = BUS_SETUP_INTR(device_get_parent(dev), child, res, flags,
+	    filt, intr, arg, cookiep);
+	if (error)
+		return (error);
+
+	get_masks(res, &mask, &mask2);
+	update_masks(intr_enabled | mask, intr_enabled2 | mask2);
+
+	return (0);
+}
+
+static int
+ixp425_teardown_intr(device_t dev, device_t child, struct resource *res,
+    void *cookie)
+{
+	uint32_t mask, mask2;
+
+	get_masks(res, &mask, &mask2);
+	update_masks(intr_enabled &~ mask, intr_enabled2 &~ mask2);
+
+	return (BUS_TEARDOWN_INTR(device_get_parent(dev), child, res, cookie));
+}
+
+static device_method_t ixp425_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,			ixp425_probe),
+	DEVMETHOD(device_attach,		ixp425_attach),
+	DEVMETHOD(device_identify,		ixp425_identify),
+
+	/* Bus interface */
+	DEVMETHOD(bus_add_child,		ixp425_add_child),
+	DEVMETHOD(bus_hinted_child,		ixp425_hinted_child),
+	DEVMETHOD(bus_read_ivar,		ixp425_read_ivar),
+
+	DEVMETHOD(bus_alloc_resource,		ixp425_alloc_resource),
+	DEVMETHOD(bus_release_resource,		ixp425_release_resource),
+	DEVMETHOD(bus_activate_resource,	ixp425_activate_resource),
+	DEVMETHOD(bus_deactivate_resource,	ixp425_deactivate_resource),
+	DEVMETHOD(bus_setup_intr,		ixp425_setup_intr),
+	DEVMETHOD(bus_teardown_intr,		ixp425_teardown_intr),
+
+	{0, 0},
+};
+
+static driver_t ixp425_driver = {
+	"ixp",
+	ixp425_methods,
+	sizeof(struct ixp425_softc),
+};
+static devclass_t ixp425_devclass;
+
+DRIVER_MODULE(ixp, nexus, ixp425_driver, ixp425_devclass, 0, 0);


Property changes on: trunk/sys/arm/xscale/ixp425/ixp425.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/ixp425/ixp425_a4x_io.S
===================================================================
--- trunk/sys/arm/xscale/ixp425/ixp425_a4x_io.S	                        (rev 0)
+++ trunk/sys/arm/xscale/ixp425/ixp425_a4x_io.S	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,153 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: ixp425_a4x_io.S,v 1.2 2005/12/11 12:16:51 christos Exp $	*/
+
+/*
+ * Copyright 2003 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Steve C. Woodford for Wasabi Systems, Inc.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed for the NetBSD Project by
+ *      Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
+ * 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.
+ */
+
+/*	
+ * There are simple bus space functions for IO registers mapped at
+ * 32-bit aligned positions.  offset is multiplied by 4.  
+ *
+ * Based loosely on pxa2x0_a2x_io.S
+ */
+
+#include <machine/asm.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/xscale/ixp425/ixp425_a4x_io.S 275767 2014-12-14 16:28:53Z andrew $");
+
+/*
+ * bus_space I/O functions with offset*4
+ */
+
+/*
+ * Read single
+ */
+ENTRY(a4x_bs_r_1)
+	ldr	r0, [r1, r2, LSL #2]
+	and	r0, r0, #0xff
+	mov	pc, lr
+END(a4x_bs_r_1)
+
+ENTRY(a4x_bs_r_2)
+	ldr	r0, [r1, r2, LSL #2]
+	mov	r1, #0xff
+	orr	r1, r1, r1, lsl #8
+	and	r0, r0, r1
+	mov	pc, lr
+END(a4x_bs_r_2)
+
+ENTRY(a4x_bs_r_4)
+	ldr	r0, [r1, r2, LSL #2]
+	mov	pc, lr
+END(a4x_bs_r_4)
+
+/*
+ * Write single
+ */
+ENTRY(a4x_bs_w_1)
+	and	r3, r3, #0xff
+	str	r3, [r1, r2, LSL #2]
+	mov	pc, lr
+END(a4x_bs_w_1)
+
+ENTRY(a4x_bs_w_2)
+	mov	r0, #0xff
+	orr	r0, r0, r0, lsl #8
+	and	r3, r3, r0
+	str	r3, [r1, r2, LSL #2]
+	mov	pc, lr
+END(a4x_bs_w_2)
+
+ENTRY(a4x_bs_w_4)
+	str	r3, [r1, r2, LSL #2]
+	mov	pc, lr
+END(a4x_bs_w_4)
+
+/*
+ * Read multiple
+ */
+ENTRY(a4x_bs_rm_1)
+	add	r0, r1, r2, lsl #2
+	ldr	r2, [sp, #0]
+	mov	r1, r3
+	teq	r2, #0
+	moveq	pc, lr
+1:	ldr	r3, [r0]
+	subs	r2, r2, #1
+	strb	r3, [r1], #1
+	bne	1b
+	mov	pc, lr
+END(a4x_bs_rm_1)
+
+ENTRY(a4x_bs_rm_2)
+	add	r0, r1, r2, lsl #2
+	ldr	r2, [sp, #0]
+	mov	r1, r3
+	teq	r2, #0
+	moveq	pc, lr
+1:	ldr	r3, [r0]
+	subs	r2, r2, #1
+	strh	r3, [r1], #2
+	bne	1b
+	mov	pc, lr
+END(a4x_bs_rm_2)
+
+/*
+ * Write multiple
+ */
+ENTRY(a4x_bs_wm_1)
+	add	r0, r1, r2, lsl #2
+	ldr	r2, [sp, #0]
+	mov	r1, r3
+	teq	r2, #0
+	moveq	pc, lr
+1:	ldrb	r3, [r1], #1
+	subs	r2, r2, #1
+	str	r3, [r0]
+	bne	1b
+	mov	pc, lr
+END(a4x_bs_wm_1)
+
+ENTRY(a4x_bs_wm_2)
+	add	r0, r1, r2, lsl #2
+	ldr	r2, [sp, #0]
+	mov	r1, r3
+	teq	r2, #0
+	moveq	pc, lr
+1:	ldrh	r3, [r1], #2
+	subs	r2, r2, #1
+	str	r3, [r0]
+	bne	1b
+	mov	pc, lr
+END(a4x_bs_wm_2)


Property changes on: trunk/sys/arm/xscale/ixp425/ixp425_a4x_io.S
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/ixp425/ixp425_a4x_space.c
===================================================================
--- trunk/sys/arm/xscale/ixp425/ixp425_a4x_space.c	                        (rev 0)
+++ trunk/sys/arm/xscale/ixp425/ixp425_a4x_space.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,115 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: ixp425_a4x_space.c,v 1.2 2005/12/11 12:16:51 christos Exp $	*/
+
+/*
+ * Copyright 2003 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Steve C. Woodford for Wasabi Systems, Inc.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed for the NetBSD Project by
+ *      Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
+ * 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.
+ */
+
+/*
+ * Bus space tag for 8/16-bit devices on 32-bit bus.
+ * all registers are located at the address of multiple of 4.
+ *
+ * Based on pxa2x0_a4x_space.c
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/xscale/ixp425/ixp425_a4x_space.c 278727 2015-02-13 22:32:02Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+
+#include <machine/pcb.h>
+
+#include <vm/vm.h>
+#include <vm/vm_kern.h>
+#include <vm/pmap.h>
+#include <vm/vm_page.h>
+#include <vm/vm_extern.h>
+
+#include <machine/bus.h>
+
+/* Prototypes for all the bus_space structure functions */
+bs_protos(a4x);
+bs_protos(generic);
+
+struct bus_space ixp425_a4x_bs_tag = {
+	/* cookie */
+	.bs_privdata	= (void *) 0,
+
+	/* mapping/unmapping */
+	.bs_map		= generic_bs_map,
+	.bs_unmap	= generic_bs_unmap,
+	.bs_subregion	= generic_bs_subregion,
+
+	/* allocation/deallocation */
+	.bs_alloc	= generic_bs_alloc,	/* XXX not implemented */
+	.bs_free	= generic_bs_free,	/* XXX not implemented */
+
+	/* barrier */
+	.bs_barrier	= generic_bs_barrier,
+
+	/* read (single) */
+	.bs_r_1		= a4x_bs_r_1,
+	.bs_r_2		= a4x_bs_r_2,
+	.bs_r_4		= a4x_bs_r_4,
+
+	/* read multiple */
+	.bs_rm_1	= a4x_bs_rm_1,
+	.bs_rm_2	= a4x_bs_rm_2,
+
+	/* read region */
+	/* XXX not implemented */
+
+	/* write (single) */
+	.bs_w_1		= a4x_bs_w_1,
+	.bs_w_2		= a4x_bs_w_2,
+	.bs_w_4		= a4x_bs_w_4,
+
+	/* write multiple */
+	.bs_wm_1	= a4x_bs_wm_1,
+	.bs_wm_2	= a4x_bs_wm_2,
+
+	/* write region */
+	/* XXX not implemented */
+
+	/* set multiple */
+	/* XXX not implemented */
+
+	/* set region */
+	/* XXX not implemented */
+
+	/* copy */
+	/* XXX not implemented */
+};


Property changes on: trunk/sys/arm/xscale/ixp425/ixp425_a4x_space.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/ixp425/ixp425_iic.c
===================================================================
--- trunk/sys/arm/xscale/ixp425/ixp425_iic.c	                        (rev 0)
+++ trunk/sys/arm/xscale/ixp425/ixp425_iic.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,196 @@
+/* $MidnightBSD$ */
+/*
+ * Copyright (c) 2006 Kevin Lo. 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 WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
+ * 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: stable/10/sys/arm/xscale/ixp425/ixp425_iic.c 236987 2012-06-13 04:38:09Z imp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/uio.h>
+
+#include <arm/xscale/ixp425/ixp425reg.h>
+#include <arm/xscale/ixp425/ixp425var.h>
+#include <arm/xscale/ixp425/ixdp425reg.h>
+
+#include <dev/iicbus/iiconf.h>
+#include <dev/iicbus/iicbus.h>
+
+#include "iicbb_if.h"
+
+#define I2C_DELAY	10
+
+/* bit clr/set shorthands */
+#define	GPIO_CONF_CLR(sc, reg, mask)	\
+	GPIO_CONF_WRITE_4(sc, reg, GPIO_CONF_READ_4(sc, reg) &~ (mask))
+#define	GPIO_CONF_SET(sc, reg, mask)	\
+	GPIO_CONF_WRITE_4(sc, reg, GPIO_CONF_READ_4(sc, reg) | (mask))
+
+struct ixpiic_softc {
+	device_t		sc_dev;
+	bus_space_tag_t		sc_iot;
+	bus_space_handle_t	sc_gpio_ioh;
+
+	device_t		iicbb;
+};
+
+static struct ixpiic_softc *ixpiic_sc = NULL;
+
+static int
+ixpiic_probe(device_t dev)
+{
+	device_set_desc(dev, "IXP4XX GPIO-Based I2C Interface");
+	return (0);
+}
+
+static int
+ixpiic_attach(device_t dev)
+{
+	struct ixpiic_softc *sc = device_get_softc(dev);
+	struct ixp425_softc *sa = device_get_softc(device_get_parent(dev));
+
+	ixpiic_sc = sc;
+
+	sc->sc_dev = dev;
+	sc->sc_iot = sa->sc_iot;
+	sc->sc_gpio_ioh = sa->sc_gpio_ioh;
+
+	GPIO_CONF_SET(sc, IXP425_GPIO_GPOER,
+		GPIO_I2C_SCL_BIT | GPIO_I2C_SDA_BIT);
+	GPIO_CONF_CLR(sc, IXP425_GPIO_GPOUTR,
+		GPIO_I2C_SCL_BIT | GPIO_I2C_SDA_BIT);
+
+	/* add generic bit-banging code */	
+	if ((sc->iicbb = device_add_child(dev, "iicbb", -1)) == NULL)
+		device_printf(dev, "could not add iicbb\n");
+
+	/* probe and attach the bit-banging code */
+	device_probe_and_attach(sc->iicbb);
+
+	return (0);
+}
+
+static int
+ixpiic_callback(device_t dev, int index, caddr_t data)
+{
+	return (0);
+}
+
+static int
+ixpiic_getscl(device_t dev)
+{
+	struct ixpiic_softc *sc = ixpiic_sc;
+	uint32_t reg;
+
+	IXP4XX_GPIO_LOCK();
+	GPIO_CONF_SET(sc, IXP425_GPIO_GPOER, GPIO_I2C_SCL_BIT);
+
+	reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPINR);
+	IXP4XX_GPIO_UNLOCK();
+	return (reg & GPIO_I2C_SCL_BIT);
+}
+
+static int
+ixpiic_getsda(device_t dev)
+{
+	struct ixpiic_softc *sc = ixpiic_sc;
+	uint32_t reg;
+
+	IXP4XX_GPIO_LOCK();
+	GPIO_CONF_SET(sc, IXP425_GPIO_GPOER, GPIO_I2C_SDA_BIT);
+
+	reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPINR);
+	IXP4XX_GPIO_UNLOCK();
+	return (reg & GPIO_I2C_SDA_BIT);
+}
+
+static void
+ixpiic_setsda(device_t dev, int val)
+{
+	struct ixpiic_softc *sc = ixpiic_sc;
+
+	IXP4XX_GPIO_LOCK();
+	GPIO_CONF_CLR(sc, IXP425_GPIO_GPOUTR, GPIO_I2C_SDA_BIT);
+	if (val)
+		GPIO_CONF_SET(sc, IXP425_GPIO_GPOER, GPIO_I2C_SDA_BIT);
+	else
+		GPIO_CONF_CLR(sc, IXP425_GPIO_GPOER, GPIO_I2C_SDA_BIT);
+	IXP4XX_GPIO_UNLOCK();
+	DELAY(I2C_DELAY);
+}
+
+static void
+ixpiic_setscl(device_t dev, int val)
+{
+	struct ixpiic_softc *sc = ixpiic_sc;
+
+	IXP4XX_GPIO_LOCK();
+	GPIO_CONF_CLR(sc, IXP425_GPIO_GPOUTR, GPIO_I2C_SCL_BIT);
+	if (val)
+		GPIO_CONF_SET(sc, IXP425_GPIO_GPOER, GPIO_I2C_SCL_BIT);
+	else
+		GPIO_CONF_CLR(sc, IXP425_GPIO_GPOER, GPIO_I2C_SCL_BIT);
+	IXP4XX_GPIO_UNLOCK();
+	DELAY(I2C_DELAY);
+}
+
+static int
+ixpiic_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
+{
+	/* reset bus */
+	ixpiic_setsda(dev, 1);
+	ixpiic_setscl(dev, 1);
+
+	return (IIC_ENOADDR);
+}
+
+static device_method_t ixpiic_methods[] = {
+	/* device interface */
+	DEVMETHOD(device_probe,		ixpiic_probe),
+	DEVMETHOD(device_attach,	ixpiic_attach),
+
+	/* iicbb interface */
+	DEVMETHOD(iicbb_callback,	ixpiic_callback),
+	DEVMETHOD(iicbb_setsda,		ixpiic_setsda),
+	DEVMETHOD(iicbb_setscl,		ixpiic_setscl),
+	DEVMETHOD(iicbb_getsda,		ixpiic_getsda),
+	DEVMETHOD(iicbb_getscl,		ixpiic_getscl),
+	DEVMETHOD(iicbb_reset,		ixpiic_reset),
+
+	{ 0, 0 }
+};
+
+static driver_t ixpiic_driver = {
+	"ixpiic",
+	ixpiic_methods,
+	sizeof(struct ixpiic_softc),
+};
+static devclass_t ixpiic_devclass;
+
+DRIVER_MODULE(ixpiic, ixp, ixpiic_driver, ixpiic_devclass, 0, 0);
+DRIVER_MODULE(iicbb, ixpiic, iicbb_driver, iicbb_devclass, 0, 0);


Property changes on: trunk/sys/arm/xscale/ixp425/ixp425_iic.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/ixp425/ixp425_intr.h
===================================================================
--- trunk/sys/arm/xscale/ixp425/ixp425_intr.h	                        (rev 0)
+++ trunk/sys/arm/xscale/ixp425/ixp425_intr.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,90 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: ixp425_intr.h,v 1.6 2005/12/24 20:06:52 perry Exp $	*/
+
+/*
+ * Copyright (c) 2001, 2002 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Jason R. Thorpe for Wasabi Systems, Inc.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed for the NetBSD Project by
+ *	Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
+ * 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: stable/10/sys/arm/xscale/ixp425/ixp425_intr.h 186352 2008-12-20 03:26:09Z sam $
+ *
+ */
+
+#ifndef _IXP425_INTR_H_
+#define _IXP425_INTR_H_
+
+#define	ARM_IRQ_HANDLER	_C_LABEL(ixp425_intr_dispatch)
+
+#ifndef _LOCORE
+
+#include <machine/armreg.h>
+#include <machine/cpufunc.h>
+
+#include <arm/xscale/ixp425/ixp425reg.h>
+
+#define IXPREG(reg)     *((__volatile u_int32_t*) (reg))
+
+void ixp425_do_pending(void);
+
+extern __volatile uint32_t intr_enabled;
+extern uint32_t intr_steer;
+
+static __inline void __attribute__((__unused__))
+ixp425_set_intrmask(void)
+{
+	IXPREG(IXP425_INT_ENABLE) = intr_enabled & IXP425_INT_HWMASK;
+}
+
+static __inline void
+ixp425_set_intrsteer(void)
+{
+	IXPREG(IXP425_INT_SELECT) = intr_steer & IXP425_INT_HWMASK;
+}
+
+extern __volatile uint32_t intr_enabled2;
+extern uint32_t intr_steer2;
+
+static __inline void __attribute__((__unused__))
+ixp435_set_intrmask(void)
+{
+	IXPREG(IXP435_INT_ENABLE2) = intr_enabled2 & IXP435_INT_HWMASK;
+}
+
+static __inline void
+ixp435_set_intrsteer(void)
+{
+	IXPREG(IXP435_INT_SELECT2) = intr_steer2 & IXP435_INT_HWMASK;
+}
+
+#endif /* _LOCORE */
+
+#endif /* _IXP425_INTR_H_ */


Property changes on: trunk/sys/arm/xscale/ixp425/ixp425_intr.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/ixp425/ixp425_mem.c
===================================================================
--- trunk/sys/arm/xscale/ixp425/ixp425_mem.c	                        (rev 0)
+++ trunk/sys/arm/xscale/ixp425/ixp425_mem.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,103 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: ixp425_mem.c,v 1.2 2005/12/11 12:16:51 christos Exp $	*/
+
+/*
+ * Copyright (c) 2003 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Steve C. Woodford for Wasabi Systems, Inc.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed for the NetBSD Project by
+ *      Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
+ * 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: stable/10/sys/arm/xscale/ixp425/ixp425_mem.c 266406 2014-05-18 16:07:35Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+
+#include <arm/xscale/ixp425/ixp425reg.h>
+#include <arm/xscale/ixp425/ixp425var.h>
+
+static uint32_t sdram_64bit[] = {
+	0x00800000,	/* 8M:  One 2M x 32 chip */
+	0x01000000,	/* 16M: Two 2M x 32 chips */
+	0x01000000,	/* 16M: Two 4M x 16 chips */
+	0x02000000,	/* 32M: Four 4M x 32 chips */
+	0, 0, 0, 0
+};
+
+static uint32_t sdram_other[] = {
+	0x02000000,	/*  32M: Two   8M x 16 chips */
+	0x04000000,	/*  64M: Four  8M x 16 chips */
+	0x04000000,	/*  64M: Two  16M x 16 chips */
+	0x08000000,	/* 128M: Four 16M x 16 chips */
+	0x08000000,	/* 128M: Two  32M x 16 chips */
+	0x10000000,	/* 256M: Four 32M x 16 chips */
+	0, 0
+};
+
+uint32_t
+ixp425_sdram_size(void)
+{
+#define MCU_REG_READ(x)	(*(volatile uint32_t *)(IXP425_MCU_VBASE + (x)))
+	uint32_t size, sdr_config;
+
+	sdr_config = MCU_REG_READ(MCU_SDR_CONFIG);
+
+	if (sdr_config & MCU_SDR_CONFIG_64MBIT)
+		size = sdram_64bit[MCU_SDR_CONFIG_MCONF(sdr_config)];
+	else
+		size = sdram_other[MCU_SDR_CONFIG_MCONF(sdr_config)];
+
+	if (size == 0) {
+		printf("** SDR_CONFIG returns unknown value, using 32M\n");
+		size = 32 * 1024 * 1024;
+	}
+
+	return (size);
+#undef MCU_REG_READ
+}
+
+uint32_t
+ixp435_ddram_size(void)
+{
+#define MCU_REG_READ(x)	(*(volatile uint32_t *)(IXP425_MCU_VBASE + (x)))
+	uint32_t sbr0;
+
+	/*
+	 * Table 198, page 516 shows DDR-I/II SDRAM bank sizes
+	 * for SBR0 and SBR1.  The manual states both banks must
+	 * be programmed to be the same size.  We just assume
+	 * it's done right and calculate 2x for the memory size.
+	 */
+	sbr0 = MCU_REG_READ(MCU_DDR_SBR0);
+	return 2 * 16*(sbr0 & 0x7f) * 1024 * 1024;
+#undef MCU_REG_READ
+}


Property changes on: trunk/sys/arm/xscale/ixp425/ixp425_mem.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/ixp425/ixp425_npe.c
===================================================================
--- trunk/sys/arm/xscale/ixp425/ixp425_npe.c	                        (rev 0)
+++ trunk/sys/arm/xscale/ixp425/ixp425_npe.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,1576 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2006-2008 Sam Leffler, Errno Consulting
+ * 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,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ *    redistribution must be conditioned upon including a substantially
+ *    similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
+ */
+
+/*-
+ * Copyright (c) 2001-2005, Intel Corporation.
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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: stable/10/sys/arm/xscale/ixp425/ixp425_npe.c 249582 2013-04-17 11:40:10Z gabor $");
+
+/*
+ * Intel XScale Network Processing Engine (NPE) support.
+ *
+ * Each NPE has an ixpnpeX device associated with it that is
+ * attached at boot.  Depending on the microcode loaded into
+ * an NPE there may be an Ethernet interface (npeX) or some
+ * other network interface (e.g. for ATM).  This file has support
+ * for loading microcode images and the associated NPE CPU
+ * manipulations (start, stop, reset).
+ *
+ * The code here basically replaces the npeDl and npeMh classes
+ * in the Intel Access Library (IAL).
+ *
+ * NB: Microcode images are loaded with firmware(9).  To
+ *     include microcode in a static kernel include the
+ *     ixpnpe_fw device.  Otherwise the firmware will be
+ *     automatically loaded from the filesystem.
+ */
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/time.h>
+#include <sys/bus.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+#include <sys/sysctl.h>
+
+#include <sys/linker.h>
+#include <sys/firmware.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+#include <machine/resource.h>
+#include <machine/intr.h>
+#include <arm/xscale/ixp425/ixp425reg.h>
+#include <arm/xscale/ixp425/ixp425var.h>
+
+#include <arm/xscale/ixp425/ixp425_npereg.h>
+#include <arm/xscale/ixp425/ixp425_npevar.h>
+
+struct ixpnpe_softc {
+	device_t	sc_dev;
+	bus_space_tag_t	sc_iot;
+	bus_space_handle_t sc_ioh;
+	bus_size_t	sc_size;	/* size of mapped register window */
+	struct resource	*sc_irq;	/* IRQ resource */
+	void		*sc_ih;		/* interrupt handler */
+	struct mtx	sc_mtx;		/* mailbox lock */
+	uint32_t	sc_msg[2];	/* reply msg collected in ixpnpe_intr */
+	int		sc_msgwaiting;	/* sc_msg holds valid data */
+	int		sc_npeid;
+	int		sc_nrefs;	/* # of references */
+
+	int		validImage;	/* valid ucode image loaded */
+	int		started;	/* NPE is started */
+	uint8_t		functionalityId;/* ucode functionality ID */
+	int		insMemSize;	/* size of instruction memory */
+	int		dataMemSize;	/* size of data memory */
+	uint32_t	savedExecCount;
+	uint32_t	savedEcsDbgCtxtReg2;
+};
+static struct ixpnpe_softc *npes[NPE_MAX];
+
+#define	IX_NPEDL_NPEIMAGE_FIELD_MASK	0xff
+
+/* used to read download map from version in microcode image */
+#define IX_NPEDL_BLOCK_TYPE_INSTRUCTION	0x00000000
+#define IX_NPEDL_BLOCK_TYPE_DATA	0x00000001
+#define IX_NPEDL_BLOCK_TYPE_STATE	0x00000002
+#define IX_NPEDL_END_OF_DOWNLOAD_MAP	0x0000000F
+
+/*
+ * masks used to extract address info from State information context
+ * register addresses as read from microcode image
+ */
+#define IX_NPEDL_MASK_STATE_ADDR_CTXT_REG         0x0000000F
+#define IX_NPEDL_MASK_STATE_ADDR_CTXT_NUM         0x000000F0
+
+/* LSB offset of Context Number field in State-Info Context Address */
+#define IX_NPEDL_OFFSET_STATE_ADDR_CTXT_NUM       4
+
+/* size (in words) of single State Information entry (ctxt reg address|data) */
+#define IX_NPEDL_STATE_INFO_ENTRY_SIZE	2
+
+typedef struct {
+	uint32_t type;
+	uint32_t offset;
+} IxNpeDlNpeMgrDownloadMapBlockEntry;
+
+typedef union {
+	IxNpeDlNpeMgrDownloadMapBlockEntry block;
+	uint32_t eodmMarker;
+} IxNpeDlNpeMgrDownloadMapEntry;
+
+typedef struct {
+	/* 1st entry in the download map (there may be more than one) */
+	IxNpeDlNpeMgrDownloadMapEntry entry[1];
+} IxNpeDlNpeMgrDownloadMap;
+
+/* used to access an instruction or data block in a microcode image */
+typedef struct {
+	uint32_t npeMemAddress;
+	uint32_t size;
+	uint32_t data[1];
+} IxNpeDlNpeMgrCodeBlock;
+
+/* used to access each Context Reg entry state-information block */
+typedef struct {
+	uint32_t addressInfo;
+	uint32_t value;
+} IxNpeDlNpeMgrStateInfoCtxtRegEntry;
+
+/* used to access a state-information block in a microcode image */
+typedef struct {
+	uint32_t size;
+	IxNpeDlNpeMgrStateInfoCtxtRegEntry ctxtRegEntry[1];
+} IxNpeDlNpeMgrStateInfoBlock;
+
+static int npe_debug = 0;
+SYSCTL_INT(_debug, OID_AUTO, ixp425npe, CTLFLAG_RW, &npe_debug,
+	   0, "IXP4XX NPE debug msgs");
+TUNABLE_INT("debug.ixp425npe", &npe_debug);
+#define	DPRINTF(dev, fmt, ...) do {					\
+	if (npe_debug) device_printf(dev, fmt, __VA_ARGS__);		\
+} while (0)
+#define	DPRINTFn(n, dev, fmt, ...) do {					\
+	if (npe_debug >= n) printf(fmt, __VA_ARGS__);			\
+} while (0)
+
+static int npe_checkbits(struct ixpnpe_softc *, uint32_t reg, uint32_t);
+static int npe_isstopped(struct ixpnpe_softc *);
+static int npe_load_ins(struct ixpnpe_softc *,
+		const IxNpeDlNpeMgrCodeBlock *bp, int verify);
+static int npe_load_data(struct ixpnpe_softc *,
+		const IxNpeDlNpeMgrCodeBlock *bp, int verify);
+static int npe_load_stateinfo(struct ixpnpe_softc *,
+		const IxNpeDlNpeMgrStateInfoBlock *bp, int verify);
+static int npe_load_image(struct ixpnpe_softc *,
+		const uint32_t *imageCodePtr, int verify);
+static int npe_cpu_reset(struct ixpnpe_softc *);
+static int npe_cpu_start(struct ixpnpe_softc *);
+static int npe_cpu_stop(struct ixpnpe_softc *);
+static void npe_cmd_issue_write(struct ixpnpe_softc *,
+		uint32_t cmd, uint32_t addr, uint32_t data);
+static uint32_t npe_cmd_issue_read(struct ixpnpe_softc *,
+		uint32_t cmd, uint32_t addr);
+static int npe_ins_write(struct ixpnpe_softc *,
+		uint32_t addr, uint32_t data, int verify);
+static int npe_data_write(struct ixpnpe_softc *,
+		uint32_t addr, uint32_t data, int verify);
+static void npe_ecs_reg_write(struct ixpnpe_softc *,
+		uint32_t reg, uint32_t data);
+static uint32_t npe_ecs_reg_read(struct ixpnpe_softc *, uint32_t reg);
+static void npe_issue_cmd(struct ixpnpe_softc *, uint32_t command);
+static void npe_cpu_step_save(struct ixpnpe_softc *);
+static int npe_cpu_step(struct ixpnpe_softc *, uint32_t npeInstruction,
+		uint32_t ctxtNum, uint32_t ldur);
+static void npe_cpu_step_restore(struct ixpnpe_softc *);
+static int npe_logical_reg_read(struct ixpnpe_softc *,
+		uint32_t regAddr, uint32_t regSize,
+		uint32_t ctxtNum, uint32_t *regVal);
+static int npe_logical_reg_write(struct ixpnpe_softc *,
+		uint32_t regAddr, uint32_t regVal,
+		uint32_t regSize, uint32_t ctxtNum, int verify);
+static int npe_physical_reg_write(struct ixpnpe_softc *,
+		uint32_t regAddr, uint32_t regValue, int verify);
+static int npe_ctx_reg_write(struct ixpnpe_softc *, uint32_t ctxtNum,
+		uint32_t ctxtReg, uint32_t ctxtRegVal, int verify);
+
+static void ixpnpe_intr(void *arg);
+
+static uint32_t
+npe_reg_read(struct ixpnpe_softc *sc, bus_size_t off)
+{
+	uint32_t v = bus_space_read_4(sc->sc_iot, sc->sc_ioh, off);
+	DPRINTFn(9, sc->sc_dev, "%s(0x%lx) => 0x%x\n", __func__, off, v);
+	return v;
+}
+
+static void
+npe_reg_write(struct ixpnpe_softc *sc, bus_size_t off, uint32_t val)
+{
+	DPRINTFn(9, sc->sc_dev, "%s(0x%lx, 0x%x)\n", __func__, off, val);
+	bus_space_write_4(sc->sc_iot, sc->sc_ioh, off, val);
+}
+
+struct ixpnpe_softc *
+ixpnpe_attach(device_t dev, int npeid)
+{
+	struct npeconfig {
+		uint32_t	base;
+		uint32_t	size;
+		int		irq;
+		uint32_t	ins_memsize;
+		uint32_t	data_memsize;
+	};
+	static const struct npeconfig npeconfigs[NPE_MAX] = {
+		[NPE_A] = {
+		    .base = IXP425_NPE_A_HWBASE,
+		    .size = IXP425_NPE_A_SIZE,
+		    .irq = IXP425_INT_NPE_A,
+		    .ins_memsize = IX_NPEDL_INS_MEMSIZE_WORDS_NPEA,
+		    .data_memsize = IX_NPEDL_DATA_MEMSIZE_WORDS_NPEA
+		},
+		[NPE_B] = {
+		    .base = IXP425_NPE_B_HWBASE,
+		    .size = IXP425_NPE_B_SIZE,
+		    .irq = IXP425_INT_NPE_B,
+		    .ins_memsize = IX_NPEDL_INS_MEMSIZE_WORDS_NPEB,
+		    .data_memsize = IX_NPEDL_DATA_MEMSIZE_WORDS_NPEB
+		},
+		[NPE_C] = {
+		    .base = IXP425_NPE_C_HWBASE,
+		    .size = IXP425_NPE_C_SIZE,
+		    .irq = IXP425_INT_NPE_C,
+		    .ins_memsize = IX_NPEDL_INS_MEMSIZE_WORDS_NPEC,
+		    .data_memsize = IX_NPEDL_DATA_MEMSIZE_WORDS_NPEC
+		},
+	};
+	struct ixp425_softc *sa = device_get_softc(device_get_parent(dev));
+	struct ixpnpe_softc *sc;
+	const struct npeconfig *config;
+	int rid;
+
+	if (npeid >= NPE_MAX) {
+		device_printf(dev, "%s: bad npeid %d\n", __func__, npeid);
+		return NULL;
+	}
+	sc = npes[npeid];
+	if (sc != NULL) {
+		sc->sc_nrefs++;
+		return sc;
+	}
+	config = &npeconfigs[npeid];
+
+	/* XXX M_BUS */
+	sc = malloc(sizeof(struct ixpnpe_softc), M_TEMP, M_WAITOK | M_ZERO);
+	sc->sc_dev = dev;
+	sc->sc_iot = sa->sc_iot;
+	mtx_init(&sc->sc_mtx, device_get_nameunit(dev), "npe driver", MTX_DEF);
+	sc->sc_npeid = npeid;
+	sc->sc_nrefs = 1;
+
+	sc->sc_size = config->size;
+	if (cpu_is_ixp42x()) {
+		/* NB: instruction/data memory sizes are NPE-dependent */
+		sc->insMemSize = config->ins_memsize;
+		sc->dataMemSize = config->data_memsize;
+	} else {
+		sc->insMemSize = IXP46X_NPEDL_INS_MEMSIZE_WORDS;
+		sc->dataMemSize = IXP46X_NPEDL_DATA_MEMSIZE_WORDS;
+	}
+
+	if (bus_space_map(sc->sc_iot, config->base, sc->sc_size, 0, &sc->sc_ioh))
+		panic("%s: Cannot map registers", device_get_name(dev));
+
+	/*
+	 * Setup IRQ and handler for NPE message support.
+	 */
+	rid = 0;
+	sc->sc_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid,
+	    config->irq, config->irq, 1, RF_ACTIVE);
+	if (sc->sc_irq == NULL)
+		panic("%s: Unable to allocate irq %u", device_get_name(dev),
+		    config->irq);
+	/* XXX could be a source of entropy */
+	bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_NET | INTR_MPSAFE,
+	    NULL, ixpnpe_intr, sc, &sc->sc_ih);
+	/*
+	 * Enable output fifo interrupts (NB: must also set OFIFO Write Enable)
+	 */
+	npe_reg_write(sc, IX_NPECTL,
+	    npe_reg_read(sc, IX_NPECTL) | (IX_NPECTL_OFE | IX_NPECTL_OFWE));
+
+	npes[npeid] = sc;
+
+	return sc;
+}
+
+void
+ixpnpe_detach(struct ixpnpe_softc *sc)
+{
+	if (--sc->sc_nrefs == 0) {
+		npes[sc->sc_npeid] = NULL;
+
+		/* disable output fifo interrupts */
+		npe_reg_write(sc, IX_NPECTL,
+		    npe_reg_read(sc, IX_NPECTL) &~ (IX_NPECTL_OFE | IX_NPECTL_OFWE));
+
+		bus_teardown_intr(sc->sc_dev, sc->sc_irq, sc->sc_ih);
+		bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_size);
+		mtx_destroy(&sc->sc_mtx);
+		free(sc, M_TEMP);
+	}
+}
+
+int
+ixpnpe_stopandreset(struct ixpnpe_softc *sc)
+{
+	int error;
+
+	mtx_lock(&sc->sc_mtx);
+	error = npe_cpu_stop(sc);		/* stop NPE */
+	if (error == 0)
+		error = npe_cpu_reset(sc);	/* reset it */
+	if (error == 0)
+		sc->started = 0;		/* mark stopped */
+	mtx_unlock(&sc->sc_mtx);
+
+	DPRINTF(sc->sc_dev, "%s: error %d\n", __func__, error);
+	return error;
+}
+
+static int
+ixpnpe_start_locked(struct ixpnpe_softc *sc)
+{
+	int error;
+
+	if (!sc->started) {
+		error = npe_cpu_start(sc);
+		if (error == 0)
+			sc->started = 1;
+	} else
+		error = 0;
+
+	DPRINTF(sc->sc_dev, "%s: error %d\n", __func__, error);
+	return error;
+}
+
+int
+ixpnpe_start(struct ixpnpe_softc *sc)
+{
+	int ret;
+
+	mtx_lock(&sc->sc_mtx);
+	ret = ixpnpe_start_locked(sc);
+	mtx_unlock(&sc->sc_mtx);
+	return (ret);
+}
+
+int
+ixpnpe_stop(struct ixpnpe_softc *sc)
+{
+	int error;
+
+	mtx_lock(&sc->sc_mtx);
+	error = npe_cpu_stop(sc);
+	if (error == 0)
+		sc->started = 0;
+	mtx_unlock(&sc->sc_mtx);
+
+	DPRINTF(sc->sc_dev, "%s: error %d\n", __func__, error);
+	return error;
+}
+
+/*
+ * Indicates the start of an NPE Image, in new NPE Image Library format.
+ * 2 consecutive occurrences indicates the end of the NPE Image Library
+ */
+#define NPE_IMAGE_MARKER 0xfeedf00d
+
+/*
+ * NPE Image Header definition, used in new NPE Image Library format
+ */
+typedef struct {
+	uint32_t marker;
+	uint32_t id;
+	uint32_t size;
+} IxNpeDlImageMgrImageHeader;
+
+static int
+npe_findimage(struct ixpnpe_softc *sc,
+    const uint32_t *imageLibrary, uint32_t imageId,
+    const uint32_t **imagePtr, uint32_t *imageSize)
+{
+	const IxNpeDlImageMgrImageHeader *image;
+	uint32_t offset = 0;
+
+	while (imageLibrary[offset] == NPE_IMAGE_MARKER) {
+		image = (const IxNpeDlImageMgrImageHeader *)
+		    &imageLibrary[offset];
+		offset += sizeof(IxNpeDlImageMgrImageHeader)/sizeof(uint32_t);
+		
+		DPRINTF(sc->sc_dev, "%s: off %u mark 0x%x id 0x%x size %u\n",
+		    __func__, offset, image->marker, image->id, image->size);
+		if (image->id == imageId) {
+			*imagePtr = imageLibrary + offset;
+			*imageSize = image->size;
+			return 0;
+		}
+		/* 2 consecutive NPE_IMAGE_MARKER's indicates end of library */
+		if (image->id == NPE_IMAGE_MARKER) {
+			DPRINTF(sc->sc_dev, "imageId 0x%08x not found in "
+			    "image library header\n", imageId);
+			/* reached end of library, image not found */
+			return ESRCH;
+		}
+		offset += image->size;
+	}
+	return ESRCH;
+}
+
+static int
+ixpnpe_load_firmware(struct ixpnpe_softc *sc, const char *imageName,
+    uint32_t imageId)
+{
+	static const char *devname[4] =
+	     { "IXP425", "IXP435/IXP465", "DeviceID#2", "DeviceID#3" };
+	uint32_t imageSize;
+	const uint32_t *imageCodePtr;
+	const struct firmware *fw;
+	int error;
+
+	DPRINTF(sc->sc_dev, "load %s, imageId 0x%08x\n", imageName, imageId);
+
+#if 0
+	IxFeatureCtrlDeviceId devid = IX_NPEDL_DEVICEID_FROM_IMAGEID_GET(imageId);
+	/*
+	 * Checking if image being loaded is meant for device that is running.
+	 * Image is forward compatible. i.e Image built for IXP42X should run
+	 * on IXP46X but not vice versa.
+	 */
+	if (devid > (ixFeatureCtrlDeviceRead() & IX_FEATURE_CTRL_DEVICE_TYPE_MASK))
+	    return EINVAL;
+#endif
+	error = ixpnpe_stopandreset(sc);		/* stop and reset the NPE */
+	if (error != 0)
+		return error;
+
+	fw = firmware_get(imageName);
+	if (fw == NULL)
+		return ENOENT;
+
+	/* Locate desired image in files w/ combined images */
+	error = npe_findimage(sc, fw->data, imageId, &imageCodePtr, &imageSize);
+	if (error != 0)
+		goto done;
+
+	device_printf(sc->sc_dev,
+	    "load fw image %s.NPE-%c Func 0x%x Rev %u.%u\n",
+	    devname[NPEIMAGE_DEVID(imageId)], 'A' + NPEIMAGE_NPEID(imageId),
+	    NPEIMAGE_FUNCID(imageId), NPEIMAGE_MAJOR(imageId),
+	    NPEIMAGE_MINOR(imageId));
+
+	/*
+	 * If download was successful, store image Id in list of
+	 * currently loaded images. If a critical error occured
+	 * during download, record that the NPE has an invalid image
+	 */
+	mtx_lock(&sc->sc_mtx);
+	error = npe_load_image(sc, imageCodePtr, 1 /*VERIFY*/);
+	if (error == 0) {
+		sc->validImage = 1;
+		error = ixpnpe_start_locked(sc);
+	} else {
+		sc->validImage = 0;
+	}
+	sc->functionalityId = IX_NPEDL_FUNCTIONID_FROM_IMAGEID_GET(imageId);
+	mtx_unlock(&sc->sc_mtx);
+done:
+	firmware_put(fw, FIRMWARE_UNLOAD);
+	DPRINTF(sc->sc_dev, "%s: error %d\n", __func__, error);
+	return error;
+}
+
+static int
+override_imageid(device_t dev, const char *resname, uint32_t *val)
+{
+	int unit = device_get_unit(dev);
+	int resval;
+
+	if (resource_int_value("npe", unit, resname, &resval) != 0)
+		return 0;
+	/* XXX validate */
+	if (bootverbose)
+		device_printf(dev, "using npe.%d.%s=0x%x override\n",
+		    unit, resname, resval);
+	*val = resval;
+	return 1;
+}
+
+int
+ixpnpe_init(struct ixpnpe_softc *sc)
+{
+	static const uint32_t npeconfig[NPE_MAX] = {
+		[NPE_A] = IXP425_NPE_A_IMAGEID,
+		[NPE_B] = IXP425_NPE_B_IMAGEID,
+		[NPE_C] = IXP425_NPE_C_IMAGEID,
+	};
+	uint32_t imageid, msg[2];
+	int error;
+
+	if (sc->started)
+		return 0;
+	/*
+	 * Load NPE firmware and start it running.  We assume
+	 * that minor version bumps remain compatible so probe
+	 * the firmware image starting with the expected version
+	 * and then bump the minor version up to the max.
+	 */
+	if (!override_imageid(sc->sc_dev, "imageid", &imageid))
+		imageid = npeconfig[sc->sc_npeid];
+	for (;;) {
+		error = ixpnpe_load_firmware(sc, "npe_fw", imageid);
+		if (error == 0)
+			break;
+		/*
+		 * ESRCH is returned when the requested image
+		 * is not present
+		 */
+		if (error != ESRCH) {
+			device_printf(sc->sc_dev,
+			    "cannot init NPE (error %d)\n", error);
+			return error;
+		}
+		/* bump the minor version up to the max possible */
+		if (NPEIMAGE_MINOR(imageid) == 0xff) {
+			device_printf(sc->sc_dev, "cannot locate firmware "
+			    "(imageid 0x%08x)\n", imageid);
+			return error;
+		}
+		imageid++;
+	}
+	/* NB: firmware should respond with a status msg */
+	if (ixpnpe_recvmsg_sync(sc, msg) != 0) {
+		device_printf(sc->sc_dev,
+		    "firmware did not respond as expected\n");
+		return EIO;
+	}
+	return 0;
+}
+
+int
+ixpnpe_getfunctionality(struct ixpnpe_softc *sc)
+{
+	return (sc->validImage ? sc->functionalityId : 0);
+}
+
+static int
+npe_checkbits(struct ixpnpe_softc *sc, uint32_t reg, uint32_t expectedBitsSet)
+{
+	uint32_t val;
+
+	val = npe_reg_read(sc, reg);
+	DPRINTFn(5, sc->sc_dev, "%s(0x%x, 0x%x) => 0x%x (%u)\n",
+	    __func__, reg, expectedBitsSet, val,
+	    (val & expectedBitsSet) == expectedBitsSet);
+	return ((val & expectedBitsSet) == expectedBitsSet);
+}
+
+static int
+npe_isstopped(struct ixpnpe_softc *sc)
+{
+	return npe_checkbits(sc,
+	    IX_NPEDL_REG_OFFSET_EXCTL, IX_NPEDL_EXCTL_STATUS_STOP);
+}
+
+static int
+npe_load_ins(struct ixpnpe_softc *sc,
+    const IxNpeDlNpeMgrCodeBlock *bp, int verify)
+{
+	uint32_t npeMemAddress;
+	int i, blockSize;
+
+	npeMemAddress = bp->npeMemAddress;
+	blockSize = bp->size;		/* NB: instruction/data count */
+	if (npeMemAddress + blockSize > sc->insMemSize) {
+		device_printf(sc->sc_dev,
+		    "Block size %u too big for NPE memory\n", blockSize);
+		return EINVAL;	/* XXX */
+	}
+	for (i = 0; i < blockSize; i++, npeMemAddress++) {
+		if (npe_ins_write(sc, npeMemAddress, bp->data[i], verify) != 0) {
+			device_printf(sc->sc_dev,
+			    "NPE instruction write failed");
+			return EIO;
+		}
+	}
+	return 0;
+}
+
+static int
+npe_load_data(struct ixpnpe_softc *sc,
+    const IxNpeDlNpeMgrCodeBlock *bp, int verify)
+{
+	uint32_t npeMemAddress;
+	int i, blockSize;
+
+	npeMemAddress = bp->npeMemAddress;
+	blockSize = bp->size;		/* NB: instruction/data count */
+	if (npeMemAddress + blockSize > sc->dataMemSize) {
+		device_printf(sc->sc_dev,
+		    "Block size %u too big for NPE memory\n", blockSize);
+		return EINVAL;
+	}
+	for (i = 0; i < blockSize; i++, npeMemAddress++) {
+		if (npe_data_write(sc, npeMemAddress, bp->data[i], verify) != 0) {
+			device_printf(sc->sc_dev, "NPE data write failed\n");
+			return EIO;
+		}
+	}
+	return 0;
+}
+
+static int
+npe_load_stateinfo(struct ixpnpe_softc *sc,
+    const IxNpeDlNpeMgrStateInfoBlock *bp, int verify)
+{
+	int i, nentries, error;
+
+	npe_cpu_step_save(sc);
+
+	/* for each state-info context register entry in block */
+	nentries = bp->size / IX_NPEDL_STATE_INFO_ENTRY_SIZE;
+	error = 0;
+	for (i = 0; i < nentries; i++) {
+		/* each state-info entry is 2 words (address, value) */
+		uint32_t regVal = bp->ctxtRegEntry[i].value;
+		uint32_t addrInfo = bp->ctxtRegEntry[i].addressInfo;
+
+		uint32_t reg = (addrInfo & IX_NPEDL_MASK_STATE_ADDR_CTXT_REG);
+		uint32_t cNum = (addrInfo & IX_NPEDL_MASK_STATE_ADDR_CTXT_NUM) >>
+		    IX_NPEDL_OFFSET_STATE_ADDR_CTXT_NUM;
+		
+		/* error-check Context Register No. and Context Number values */
+		if (!(0 <= reg && reg < IX_NPEDL_CTXT_REG_MAX)) {
+			device_printf(sc->sc_dev,
+			    "invalid Context Register %u\n", reg);
+			error = EINVAL;
+			break;
+		}
+		if (!(0 <= cNum && cNum < IX_NPEDL_CTXT_NUM_MAX)) {
+			device_printf(sc->sc_dev,
+			    "invalid Context Number %u\n", cNum);
+			error = EINVAL;
+			break;
+		}
+		/* NOTE that there is no STEVT register for Context 0 */
+		if (cNum == 0 && reg == IX_NPEDL_CTXT_REG_STEVT) {
+			device_printf(sc->sc_dev,
+			    "no STEVT for Context 0\n");
+			error = EINVAL;
+			break;
+		}
+
+		if (npe_ctx_reg_write(sc, cNum, reg, regVal, verify) != 0) {
+			device_printf(sc->sc_dev,
+			    "write of state-info to NPE failed\n");
+			error = EIO;
+			break;
+		}
+	}
+
+	npe_cpu_step_restore(sc);
+	return error;
+}
+
+static int
+npe_load_image(struct ixpnpe_softc *sc,
+    const uint32_t *imageCodePtr, int verify)
+{
+#define	EOM(marker)	((marker) == IX_NPEDL_END_OF_DOWNLOAD_MAP)
+	const IxNpeDlNpeMgrDownloadMap *downloadMap;
+	int i, error;
+
+	if (!npe_isstopped(sc)) {		/* verify NPE is stopped */
+		device_printf(sc->sc_dev,
+		    "cannot load image, NPE not stopped\n");
+		return EIO;
+	}
+
+	/*
+	 * Read Download Map, checking each block type and calling
+	 * appropriate function to perform download
+	 */
+	error = 0;
+	downloadMap = (const IxNpeDlNpeMgrDownloadMap *) imageCodePtr;
+	for (i = 0; !EOM(downloadMap->entry[i].eodmMarker); i++) {
+		/* calculate pointer to block to be downloaded */
+		const uint32_t *bp = imageCodePtr +
+		    downloadMap->entry[i].block.offset;
+		switch (downloadMap->entry[i].block.type) {
+		case IX_NPEDL_BLOCK_TYPE_INSTRUCTION:
+			error = npe_load_ins(sc,
+			    (const IxNpeDlNpeMgrCodeBlock *) bp, verify);
+			DPRINTF(sc->sc_dev, "%s: inst, error %d\n",
+			    __func__, error);
+			break;
+		case IX_NPEDL_BLOCK_TYPE_DATA:
+			error = npe_load_data(sc,
+			    (const IxNpeDlNpeMgrCodeBlock *) bp, verify);
+			DPRINTF(sc->sc_dev, "%s: data, error %d\n",
+			    __func__, error);
+			break;
+		case IX_NPEDL_BLOCK_TYPE_STATE:
+		    error = npe_load_stateinfo(sc,
+			(const IxNpeDlNpeMgrStateInfoBlock *) bp, verify);
+			DPRINTF(sc->sc_dev, "%s: state, error %d\n",
+			    __func__, error);
+			break;
+		default:
+			device_printf(sc->sc_dev,
+			    "unknown block type 0x%x in download map\n",
+			    downloadMap->entry[i].block.type);
+			error = EIO;		/* XXX */
+			break;
+		}
+		if (error != 0)
+			break;
+	}
+	return error;
+#undef EOM
+}
+
+/* contains Reset values for Context Store Registers  */
+static const struct {
+	uint32_t regAddr;
+	uint32_t regResetVal;
+} ixNpeDlEcsRegResetValues[] = {
+	{ IX_NPEDL_ECS_BG_CTXT_REG_0,    IX_NPEDL_ECS_BG_CTXT_REG_0_RESET },
+	{ IX_NPEDL_ECS_BG_CTXT_REG_1,    IX_NPEDL_ECS_BG_CTXT_REG_1_RESET },
+	{ IX_NPEDL_ECS_BG_CTXT_REG_2,    IX_NPEDL_ECS_BG_CTXT_REG_2_RESET },
+	{ IX_NPEDL_ECS_PRI_1_CTXT_REG_0, IX_NPEDL_ECS_PRI_1_CTXT_REG_0_RESET },
+	{ IX_NPEDL_ECS_PRI_1_CTXT_REG_1, IX_NPEDL_ECS_PRI_1_CTXT_REG_1_RESET },
+	{ IX_NPEDL_ECS_PRI_1_CTXT_REG_2, IX_NPEDL_ECS_PRI_1_CTXT_REG_2_RESET },
+	{ IX_NPEDL_ECS_PRI_2_CTXT_REG_0, IX_NPEDL_ECS_PRI_2_CTXT_REG_0_RESET },
+	{ IX_NPEDL_ECS_PRI_2_CTXT_REG_1, IX_NPEDL_ECS_PRI_2_CTXT_REG_1_RESET },
+	{ IX_NPEDL_ECS_PRI_2_CTXT_REG_2, IX_NPEDL_ECS_PRI_2_CTXT_REG_2_RESET },
+	{ IX_NPEDL_ECS_DBG_CTXT_REG_0,   IX_NPEDL_ECS_DBG_CTXT_REG_0_RESET },
+	{ IX_NPEDL_ECS_DBG_CTXT_REG_1,   IX_NPEDL_ECS_DBG_CTXT_REG_1_RESET },
+	{ IX_NPEDL_ECS_DBG_CTXT_REG_2,   IX_NPEDL_ECS_DBG_CTXT_REG_2_RESET },
+	{ IX_NPEDL_ECS_INSTRUCT_REG,     IX_NPEDL_ECS_INSTRUCT_REG_RESET }
+};
+
+/* contains Reset values for Context Store Registers  */
+static const uint32_t ixNpeDlCtxtRegResetValues[] = {
+	IX_NPEDL_CTXT_REG_RESET_STEVT,
+	IX_NPEDL_CTXT_REG_RESET_STARTPC,
+	IX_NPEDL_CTXT_REG_RESET_REGMAP,
+	IX_NPEDL_CTXT_REG_RESET_CINDEX,
+};
+
+#define	IX_NPEDL_PARITY_BIT_MASK	0x3F00FFFF
+#define	IX_NPEDL_CONFIG_CTRL_REG_MASK	0x3F3FFFFF
+
+#if 0
+/*
+ * Reset the NPE and its coprocessor using the
+ * fuse bits in the feature control register.
+ */
+static void
+npe_reset(int npeid)
+{
+	uint32_t mask = EXP_FCTRL_NPEA << npeid;
+	uint32_t v;
+
+	v = ixp4xx_read_feature_bits();
+	ixp4xx_write_feature_bits(v &~ mask);
+	/* un-fuse and un-reset the NPE & coprocessor */
+	ixp4xx_write_feature_bits(v | mask);
+}
+#endif
+
+static int
+npe_cpu_reset(struct ixpnpe_softc *sc)
+{
+#define	N(a)	(sizeof(a) / sizeof(a[0]))
+	uint32_t ctxtReg; /* identifies Context Store reg (0-3) */
+	uint32_t regAddr;
+	uint32_t regVal;
+	uint32_t ixNpeConfigCtrlRegVal;
+	int i, error = 0;
+	
+	/* pre-store the NPE Config Control Register Value */
+	ixNpeConfigCtrlRegVal = npe_reg_read(sc, IX_NPEDL_REG_OFFSET_CTL);
+	ixNpeConfigCtrlRegVal |= 0x3F000000;
+
+	/* disable the parity interrupt */
+	npe_reg_write(sc, IX_NPEDL_REG_OFFSET_CTL,
+	    (ixNpeConfigCtrlRegVal & IX_NPEDL_PARITY_BIT_MASK));
+	DPRINTFn(2, sc->sc_dev, "%s: dis parity int, CTL => 0x%x\n",
+	    __func__, ixNpeConfigCtrlRegVal & IX_NPEDL_PARITY_BIT_MASK);
+
+	npe_cpu_step_save(sc);
+
+	/*
+	 * Clear the FIFOs.
+	 */
+	while (npe_checkbits(sc,
+	      IX_NPEDL_REG_OFFSET_WFIFO, IX_NPEDL_MASK_WFIFO_VALID)) {
+		/* read from the Watch-point FIFO until empty */
+		(void) npe_reg_read(sc, IX_NPEDL_REG_OFFSET_WFIFO);
+	}
+
+	while (npe_checkbits(sc,
+	      IX_NPEDL_REG_OFFSET_STAT, IX_NPEDL_MASK_STAT_OFNE)) {
+		/* read from the outFIFO until empty */
+		(void) npe_reg_read(sc, IX_NPEDL_REG_OFFSET_FIFO);
+	}
+	
+	while (npe_checkbits(sc,
+	      IX_NPEDL_REG_OFFSET_STAT, IX_NPEDL_MASK_STAT_IFNE)) {
+		/*
+		 * Step execution of the NPE intruction to read inFIFO using
+		 * the Debug Executing Context stack.
+		 */
+		error = npe_cpu_step(sc, IX_NPEDL_INSTR_RD_FIFO, 0, 0);
+		if (error != 0) {
+			DPRINTF(sc->sc_dev, "%s: cannot step (1), error %u\n",
+			    __func__, error);
+			npe_cpu_step_restore(sc);
+			return error;
+		}
+	}
+	
+	/*
+	 * Reset the mailbox reg
+	 */
+	/* ...from XScale side */
+	npe_reg_write(sc, IX_NPEDL_REG_OFFSET_MBST, IX_NPEDL_REG_RESET_MBST);
+	/* ...from NPE side */
+	error = npe_cpu_step(sc, IX_NPEDL_INSTR_RESET_MBOX, 0, 0);
+	if (error != 0) {
+		DPRINTF(sc->sc_dev, "%s: cannot step (2), error %u\n",
+		    __func__, error);
+		npe_cpu_step_restore(sc);
+		return error;
+	}
+
+	/*
+	 * Reset the physical registers in the NPE register file:
+	 * Note: no need to save/restore REGMAP for Context 0 here
+	 * since all Context Store regs are reset in subsequent code.
+	 */
+	for (regAddr = 0;
+	     regAddr < IX_NPEDL_TOTAL_NUM_PHYS_REG && error == 0;
+	     regAddr++) {
+		/* for each physical register in the NPE reg file, write 0 : */
+		error = npe_physical_reg_write(sc, regAddr, 0, TRUE);
+		if (error != 0) {
+			DPRINTF(sc->sc_dev, "%s: cannot write phy reg,"
+			    "error %u\n", __func__, error);
+			npe_cpu_step_restore(sc);
+			return error;		/* abort reset */
+		}
+	}
+
+	/*
+	 * Reset the context store:
+	 */
+	for (i = IX_NPEDL_CTXT_NUM_MIN; i <= IX_NPEDL_CTXT_NUM_MAX; i++) {	
+		/* set each context's Context Store registers to reset values */
+		for (ctxtReg = 0; ctxtReg < IX_NPEDL_CTXT_REG_MAX; ctxtReg++) {
+			/* NOTE that there is no STEVT register for Context 0 */
+			if (i == 0 && ctxtReg == IX_NPEDL_CTXT_REG_STEVT)
+				continue;
+			regVal = ixNpeDlCtxtRegResetValues[ctxtReg];
+			error = npe_ctx_reg_write(sc, i, ctxtReg,
+			    regVal, TRUE);
+			if (error != 0) {
+				DPRINTF(sc->sc_dev, "%s: cannot write ctx reg,"
+				    "error %u\n", __func__, error);
+				npe_cpu_step_restore(sc);
+				return error;	 /* abort reset */
+			}
+		}
+	}
+
+	npe_cpu_step_restore(sc);
+
+	/* write Reset values to Execution Context Stack registers */
+	for (i = 0; i < N(ixNpeDlEcsRegResetValues); i++)
+		npe_ecs_reg_write(sc,
+		    ixNpeDlEcsRegResetValues[i].regAddr,
+		    ixNpeDlEcsRegResetValues[i].regResetVal);
+
+	/* clear the profile counter */
+	npe_issue_cmd(sc, IX_NPEDL_EXCTL_CMD_CLR_PROFILE_CNT);
+	
+	/* clear registers EXCT, AP0, AP1, AP2 and AP3 */
+	for (regAddr = IX_NPEDL_REG_OFFSET_EXCT;
+	     regAddr <= IX_NPEDL_REG_OFFSET_AP3;
+	     regAddr += sizeof(uint32_t))
+		npe_reg_write(sc, regAddr, 0);
+
+	/* Reset the Watch-count register */
+	npe_reg_write(sc, IX_NPEDL_REG_OFFSET_WC, 0);
+#if 0
+	/*
+	 * WR IXA00055043 - Remove IMEM Parity Introduced by NPE Reset Operation
+	 * XXX Removed because it breaks IXP435 operation; e.g. on Gateworks
+	 * XXX 2358 boards reseting NPE-A after NPE-C is running causes both
+	 * XXX npe's to stop working
+	 */
+	npe_reset(sc->sc_npeid);
+#endif
+	/*
+	 * Call NpeMgr function to stop the NPE again after the Feature Control
+	 * has unfused and Un-Reset the NPE and its associated Coprocessors.
+	 */
+	error = npe_cpu_stop(sc);
+
+	/* restore NPE configuration bus Control Register - Parity Settings  */
+	npe_reg_write(sc, IX_NPEDL_REG_OFFSET_CTL,
+	    (ixNpeConfigCtrlRegVal & IX_NPEDL_CONFIG_CTRL_REG_MASK));
+	DPRINTFn(2, sc->sc_dev, "%s: restore CTL => 0x%x\n",
+	    __func__, npe_reg_read(sc, IX_NPEDL_REG_OFFSET_CTL));
+
+	return error;
+#undef N
+}
+
+static int
+npe_cpu_start(struct ixpnpe_softc *sc)
+{
+	uint32_t ecsRegVal;
+
+	/*
+	 * Ensure only Background Context Stack Level is Active by turning off
+	 * the Active bit in each of the other Executing Context Stack levels.
+	 */
+	ecsRegVal = npe_ecs_reg_read(sc, IX_NPEDL_ECS_PRI_1_CTXT_REG_0);
+	ecsRegVal &= ~IX_NPEDL_MASK_ECS_REG_0_ACTIVE;
+	npe_ecs_reg_write(sc, IX_NPEDL_ECS_PRI_1_CTXT_REG_0, ecsRegVal);
+
+	ecsRegVal = npe_ecs_reg_read(sc, IX_NPEDL_ECS_PRI_2_CTXT_REG_0);
+	ecsRegVal &= ~IX_NPEDL_MASK_ECS_REG_0_ACTIVE;
+	npe_ecs_reg_write(sc, IX_NPEDL_ECS_PRI_2_CTXT_REG_0, ecsRegVal);
+
+	ecsRegVal = npe_ecs_reg_read(sc, IX_NPEDL_ECS_DBG_CTXT_REG_0);
+	ecsRegVal &= ~IX_NPEDL_MASK_ECS_REG_0_ACTIVE;
+	npe_ecs_reg_write(sc, IX_NPEDL_ECS_DBG_CTXT_REG_0, ecsRegVal);
+	
+	/* clear the pipeline */
+	npe_issue_cmd(sc, IX_NPEDL_EXCTL_CMD_NPE_CLR_PIPE);
+	
+	/* start NPE execution by issuing cmd through EXCTL register on NPE */
+	npe_issue_cmd(sc, IX_NPEDL_EXCTL_CMD_NPE_START);
+
+	/*
+	 * Check execution status of NPE to verify operation was successful.
+	 */
+	return npe_checkbits(sc,
+	    IX_NPEDL_REG_OFFSET_EXCTL, IX_NPEDL_EXCTL_STATUS_RUN) ? 0 : EIO;
+}
+
+static int
+npe_cpu_stop(struct ixpnpe_softc *sc)
+{
+	/* stop NPE execution by issuing cmd through EXCTL register on NPE */
+	npe_issue_cmd(sc, IX_NPEDL_EXCTL_CMD_NPE_STOP);
+
+	/* verify that NPE Stop was successful */
+	return npe_checkbits(sc,
+	    IX_NPEDL_REG_OFFSET_EXCTL, IX_NPEDL_EXCTL_STATUS_STOP) ? 0 : EIO;
+}
+
+#define IX_NPEDL_REG_SIZE_BYTE            8
+#define IX_NPEDL_REG_SIZE_SHORT           16
+#define IX_NPEDL_REG_SIZE_WORD            32
+
+/*
+ * Introduce extra read cycles after issuing read command to NPE
+ * so that we read the register after the NPE has updated it
+ * This is to overcome race condition between XScale and NPE
+ */
+#define IX_NPEDL_DELAY_READ_CYCLES        2
+/*
+ * To mask top three MSBs of 32bit word to download into NPE IMEM
+ */
+#define IX_NPEDL_MASK_UNUSED_IMEM_BITS    0x1FFFFFFF;
+
+static void
+npe_cmd_issue_write(struct ixpnpe_softc *sc,
+    uint32_t cmd, uint32_t addr, uint32_t data)
+{
+	npe_reg_write(sc, IX_NPEDL_REG_OFFSET_EXDATA, data);
+	npe_reg_write(sc, IX_NPEDL_REG_OFFSET_EXAD, addr);
+	npe_reg_write(sc, IX_NPEDL_REG_OFFSET_EXCTL, cmd);
+}
+
+static uint32_t
+npe_cmd_issue_read(struct ixpnpe_softc *sc, uint32_t cmd, uint32_t addr)
+{
+	uint32_t data;
+	int i;
+
+	npe_reg_write(sc, IX_NPEDL_REG_OFFSET_EXAD, addr);
+	npe_reg_write(sc, IX_NPEDL_REG_OFFSET_EXCTL, cmd);
+	for (i = 0; i <= IX_NPEDL_DELAY_READ_CYCLES; i++)
+		data = npe_reg_read(sc, IX_NPEDL_REG_OFFSET_EXDATA);
+	return data;
+}
+
+static int
+npe_ins_write(struct ixpnpe_softc *sc, uint32_t addr, uint32_t data, int verify)
+{
+	DPRINTFn(4, sc->sc_dev, "%s(0x%x, 0x%x)\n", __func__, addr, data);
+	npe_cmd_issue_write(sc, IX_NPEDL_EXCTL_CMD_WR_INS_MEM, addr, data);
+	if (verify) {
+		uint32_t rdata;
+
+		/*
+		 * Write invalid data to this reg, so we can see if we're
+		 * reading the EXDATA register too early.
+		 */
+		npe_reg_write(sc, IX_NPEDL_REG_OFFSET_EXDATA, ~data);
+
+		/*
+		 * Disabled since top 3 MSB are not used for Azusa
+		 * hardware Refer WR:IXA00053900
+		 */
+		data &= IX_NPEDL_MASK_UNUSED_IMEM_BITS;
+
+		rdata = npe_cmd_issue_read(sc, IX_NPEDL_EXCTL_CMD_RD_INS_MEM,
+		    addr);
+		rdata &= IX_NPEDL_MASK_UNUSED_IMEM_BITS;
+
+		if (data != rdata)
+			return EIO;
+	}
+	return 0;
+}
+
+static int
+npe_data_write(struct ixpnpe_softc *sc, uint32_t addr, uint32_t data, int verify)
+{
+	DPRINTFn(4, sc->sc_dev, "%s(0x%x, 0x%x)\n", __func__, addr, data);
+	npe_cmd_issue_write(sc, IX_NPEDL_EXCTL_CMD_WR_DATA_MEM, addr, data);
+	if (verify) {
+		/*
+		 * Write invalid data to this reg, so we can see if we're
+		 * reading the EXDATA register too early.
+		 */
+		npe_reg_write(sc, IX_NPEDL_REG_OFFSET_EXDATA, ~data);
+		if (data != npe_cmd_issue_read(sc, IX_NPEDL_EXCTL_CMD_RD_DATA_MEM, addr))
+			return EIO;
+	}
+	return 0;
+}
+
+static void
+npe_ecs_reg_write(struct ixpnpe_softc *sc, uint32_t reg, uint32_t data)
+{
+	npe_cmd_issue_write(sc, IX_NPEDL_EXCTL_CMD_WR_ECS_REG, reg, data);
+}
+
+static uint32_t
+npe_ecs_reg_read(struct ixpnpe_softc *sc, uint32_t reg)
+{
+	return npe_cmd_issue_read(sc, IX_NPEDL_EXCTL_CMD_RD_ECS_REG, reg);
+}
+
+static void
+npe_issue_cmd(struct ixpnpe_softc *sc, uint32_t command)
+{
+	npe_reg_write(sc, IX_NPEDL_REG_OFFSET_EXCTL, command);
+}
+
+static void
+npe_cpu_step_save(struct ixpnpe_softc *sc)
+{
+	/* turn off the halt bit by clearing Execution Count register. */
+	/* save reg contents 1st and restore later */
+	sc->savedExecCount = npe_reg_read(sc, IX_NPEDL_REG_OFFSET_EXCT);
+	npe_reg_write(sc, IX_NPEDL_REG_OFFSET_EXCT, 0);
+
+	/* ensure that IF and IE are on (temporarily), so that we don't end up
+	 * stepping forever */
+	sc->savedEcsDbgCtxtReg2 = npe_ecs_reg_read(sc,
+	    IX_NPEDL_ECS_DBG_CTXT_REG_2);
+
+	npe_ecs_reg_write(sc, IX_NPEDL_ECS_DBG_CTXT_REG_2,
+	    (sc->savedEcsDbgCtxtReg2 | IX_NPEDL_MASK_ECS_DBG_REG_2_IF |
+	     IX_NPEDL_MASK_ECS_DBG_REG_2_IE));
+}
+
+static int
+npe_cpu_step(struct ixpnpe_softc *sc, uint32_t npeInstruction,
+    uint32_t ctxtNum, uint32_t ldur)
+{
+#define	IX_NPE_DL_MAX_NUM_OF_RETRIES	1000000
+	uint32_t ecsDbgRegVal;
+	uint32_t oldWatchcount, newWatchcount;
+	int tries;
+
+	/* set the Active bit, and the LDUR, in the debug level */
+	ecsDbgRegVal = IX_NPEDL_MASK_ECS_REG_0_ACTIVE |
+	    (ldur << IX_NPEDL_OFFSET_ECS_REG_0_LDUR);
+
+	npe_ecs_reg_write(sc, IX_NPEDL_ECS_DBG_CTXT_REG_0, ecsDbgRegVal);
+
+	/*
+	 * Set CCTXT at ECS DEBUG L3 to specify in which context to execute the
+	 * instruction, and set SELCTXT at ECS DEBUG Level to specify which
+	 * context store to access.
+	 * Debug ECS Level Reg 1 has form  0x000n000n, where n = context number
+	 */
+	ecsDbgRegVal = (ctxtNum << IX_NPEDL_OFFSET_ECS_REG_1_CCTXT) |
+	    (ctxtNum << IX_NPEDL_OFFSET_ECS_REG_1_SELCTXT);
+
+	npe_ecs_reg_write(sc, IX_NPEDL_ECS_DBG_CTXT_REG_1, ecsDbgRegVal);
+
+	/* clear the pipeline */
+	npe_issue_cmd(sc, IX_NPEDL_EXCTL_CMD_NPE_CLR_PIPE);
+
+	/* load NPE instruction into the instruction register */
+	npe_ecs_reg_write(sc, IX_NPEDL_ECS_INSTRUCT_REG, npeInstruction);
+
+	/* need this value later to wait for completion of NPE execution step */
+	oldWatchcount = npe_reg_read(sc, IX_NPEDL_REG_OFFSET_WC);
+
+	/* issue a Step One command via the Execution Control register */
+	npe_issue_cmd(sc, IX_NPEDL_EXCTL_CMD_NPE_STEP);
+
+	/*
+	 * Force the XScale to wait until the NPE has finished execution step
+	 * NOTE that this delay will be very small, just long enough to allow a
+	 * single NPE instruction to complete execution; if instruction
+	 * execution is not completed before timeout retries, exit the while
+	 * loop.
+	 */
+	newWatchcount = npe_reg_read(sc, IX_NPEDL_REG_OFFSET_WC);
+	for (tries = 0; tries < IX_NPE_DL_MAX_NUM_OF_RETRIES &&
+	    newWatchcount == oldWatchcount; tries++) {
+		/* Watch Count register incr's when NPE completes an inst */
+		newWatchcount = npe_reg_read(sc, IX_NPEDL_REG_OFFSET_WC);
+	}
+	return (tries < IX_NPE_DL_MAX_NUM_OF_RETRIES) ? 0 : EIO;
+#undef IX_NPE_DL_MAX_NUM_OF_RETRIES
+}
+
+static void
+npe_cpu_step_restore(struct ixpnpe_softc *sc)
+{
+	/* clear active bit in debug level */
+	npe_ecs_reg_write(sc, IX_NPEDL_ECS_DBG_CTXT_REG_0, 0);
+
+	/* clear the pipeline */
+	npe_issue_cmd(sc, IX_NPEDL_EXCTL_CMD_NPE_CLR_PIPE);
+
+	/* restore Execution Count register contents. */
+	npe_reg_write(sc, IX_NPEDL_REG_OFFSET_EXCT, sc->savedExecCount);
+
+	/* restore IF and IE bits to original values */
+	npe_ecs_reg_write(sc, IX_NPEDL_ECS_DBG_CTXT_REG_2, sc->savedEcsDbgCtxtReg2);
+}
+
+static int
+npe_logical_reg_read(struct ixpnpe_softc *sc,
+    uint32_t regAddr, uint32_t regSize,
+    uint32_t ctxtNum, uint32_t *regVal)
+{
+	uint32_t npeInstruction, mask;
+	int error;
+
+	switch (regSize) {
+	case IX_NPEDL_REG_SIZE_BYTE:
+		npeInstruction = IX_NPEDL_INSTR_RD_REG_BYTE;
+		mask = 0xff;
+		break;
+	case IX_NPEDL_REG_SIZE_SHORT:
+		npeInstruction = IX_NPEDL_INSTR_RD_REG_SHORT;
+		mask = 0xffff;
+		break;
+	case IX_NPEDL_REG_SIZE_WORD:
+		npeInstruction = IX_NPEDL_INSTR_RD_REG_WORD;
+		mask = 0xffffffff;
+		break;
+	default:
+		return EINVAL;
+	}
+
+	/* make regAddr be the SRC and DEST operands (e.g. movX d0, d0) */
+	npeInstruction |= (regAddr << IX_NPEDL_OFFSET_INSTR_SRC) |
+	    (regAddr << IX_NPEDL_OFFSET_INSTR_DEST);
+
+	/* step execution of NPE inst using Debug Executing Context stack */
+	error = npe_cpu_step(sc, npeInstruction, ctxtNum,
+	    IX_NPEDL_RD_INSTR_LDUR);
+	if (error != 0) {
+		DPRINTF(sc->sc_dev, "%s(0x%x, %u, %u), cannot step, error %d\n",
+		    __func__, regAddr, regSize, ctxtNum, error);
+		return error;
+	}
+	/* read value of register from Execution Data register */
+	*regVal = npe_reg_read(sc, IX_NPEDL_REG_OFFSET_EXDATA);
+
+	/* align value from left to right */
+	*regVal = (*regVal >> (IX_NPEDL_REG_SIZE_WORD - regSize)) & mask;
+
+	return 0;
+}
+
+static int
+npe_logical_reg_write(struct ixpnpe_softc *sc, uint32_t regAddr, uint32_t regVal,
+    uint32_t regSize, uint32_t ctxtNum, int verify)
+{
+	int error;
+
+	DPRINTFn(4, sc->sc_dev, "%s(0x%x, 0x%x, %u, %u)\n",
+	    __func__, regAddr, regVal, regSize, ctxtNum);
+	if (regSize == IX_NPEDL_REG_SIZE_WORD) {
+		/*
+		 * NPE register addressing is left-to-right: e.g. |d0|d1|d2|d3|
+		 * Write upper half-word (short) to |d0|d1|
+		 */
+		error = npe_logical_reg_write(sc, regAddr,
+			     regVal >> IX_NPEDL_REG_SIZE_SHORT,
+			     IX_NPEDL_REG_SIZE_SHORT, ctxtNum, verify);
+		if (error != 0)
+		    return error;
+
+		/* Write lower half-word (short) to |d2|d3| */
+		error = npe_logical_reg_write(sc,
+			     regAddr + sizeof(uint16_t),
+			     regVal & 0xffff,
+			     IX_NPEDL_REG_SIZE_SHORT, ctxtNum, verify);
+	} else {
+		uint32_t npeInstruction;
+
+		switch (regSize) {
+		case IX_NPEDL_REG_SIZE_BYTE:
+			npeInstruction = IX_NPEDL_INSTR_WR_REG_BYTE;
+			regVal &= 0xff;
+			break;
+		case IX_NPEDL_REG_SIZE_SHORT:
+			npeInstruction = IX_NPEDL_INSTR_WR_REG_SHORT;
+			regVal &= 0xffff;
+			break;
+		default:
+			return EINVAL;
+		}
+		/* fill dest operand field of inst with dest reg addr */
+		npeInstruction |= (regAddr << IX_NPEDL_OFFSET_INSTR_DEST);
+
+		/* fill src operand field of inst with least-sig 5 bits of val*/
+		npeInstruction |=
+		    ((regVal & IX_NPEDL_MASK_IMMED_INSTR_SRC_DATA) <<
+		     IX_NPEDL_OFFSET_INSTR_SRC);
+
+		/* fill coprocessor field of inst with most-sig 11 bits of val*/
+		npeInstruction |=
+		    ((regVal & IX_NPEDL_MASK_IMMED_INSTR_COPROC_DATA) <<
+		     IX_NPEDL_DISPLACE_IMMED_INSTR_COPROC_DATA);
+
+		/* step execution of NPE intruction using Debug ECS */
+		error = npe_cpu_step(sc, npeInstruction,
+		    ctxtNum, IX_NPEDL_WR_INSTR_LDUR);
+	}
+	if (error != 0) {
+		DPRINTF(sc->sc_dev, "%s(0x%x, 0x%x, %u, %u), error %u "
+		    "writing reg\n", __func__, regAddr, regVal, regSize,
+		    ctxtNum, error);
+		return error;
+	}
+	if (verify) {
+		uint32_t retRegVal;
+
+		error = npe_logical_reg_read(sc, regAddr, regSize, ctxtNum,
+		    &retRegVal);
+		if (error == 0 && regVal != retRegVal)
+			error = EIO;	/* XXX ambiguous */
+	}
+	return error;
+}
+
+/*
+ * There are 32 physical registers used in an NPE.  These are
+ * treated as 16 pairs of 32-bit registers.  To write one of the pair,
+ * write the pair number (0-16) to the REGMAP for Context 0.  Then write
+ * the value to register  0 or 4 in the regfile, depending on which
+ * register of the pair is to be written
+ */
+static int
+npe_physical_reg_write(struct ixpnpe_softc *sc,
+    uint32_t regAddr, uint32_t regValue, int verify)
+{
+	int error;
+
+	/*
+	 * Set REGMAP for context 0 to (regAddr >> 1) to choose which pair
+	 * (0-16) of physical registers to write .
+	 */
+	error = npe_logical_reg_write(sc, IX_NPEDL_CTXT_REG_ADDR_REGMAP,
+		   (regAddr >> IX_NPEDL_OFFSET_PHYS_REG_ADDR_REGMAP),
+		   IX_NPEDL_REG_SIZE_SHORT, 0, verify);
+	if (error == 0) {
+	    /* regAddr = 0 or 4  */
+	    regAddr = (regAddr & IX_NPEDL_MASK_PHYS_REG_ADDR_LOGICAL_ADDR) *
+		sizeof(uint32_t);
+	    error = npe_logical_reg_write(sc, regAddr, regValue,
+		IX_NPEDL_REG_SIZE_WORD, 0, verify);
+	}
+	return error;
+}
+
+static int
+npe_ctx_reg_write(struct ixpnpe_softc *sc, uint32_t ctxtNum,
+    uint32_t ctxtReg, uint32_t ctxtRegVal, int verify)
+{
+	DPRINTFn(4, sc->sc_dev, "%s(%u, %u, %u)\n",
+	    __func__, ctxtNum, ctxtReg, ctxtRegVal);
+	/*
+	 * Context 0 has no STARTPC. Instead, this value is used to set
+	 * NextPC for Background ECS, to set where NPE starts executing code
+	 */
+	if (ctxtNum == 0 && ctxtReg == IX_NPEDL_CTXT_REG_STARTPC) {
+		/* read BG_CTXT_REG_0, update NEXTPC bits, & write back to reg*/
+		uint32_t v = npe_ecs_reg_read(sc, IX_NPEDL_ECS_BG_CTXT_REG_0);
+		v &= ~IX_NPEDL_MASK_ECS_REG_0_NEXTPC;
+		v |= (ctxtRegVal << IX_NPEDL_OFFSET_ECS_REG_0_NEXTPC) &
+		    IX_NPEDL_MASK_ECS_REG_0_NEXTPC;
+
+		npe_ecs_reg_write(sc, IX_NPEDL_ECS_BG_CTXT_REG_0, v);
+		return 0;
+	} else {
+		static const struct {
+			uint32_t regAddress;
+			uint32_t regSize;
+		} regAccInfo[IX_NPEDL_CTXT_REG_MAX] = {
+			{ IX_NPEDL_CTXT_REG_ADDR_STEVT,
+			  IX_NPEDL_REG_SIZE_BYTE },
+			{ IX_NPEDL_CTXT_REG_ADDR_STARTPC,
+			  IX_NPEDL_REG_SIZE_SHORT },
+			{ IX_NPEDL_CTXT_REG_ADDR_REGMAP,
+			  IX_NPEDL_REG_SIZE_SHORT },
+			{ IX_NPEDL_CTXT_REG_ADDR_CINDEX,
+			  IX_NPEDL_REG_SIZE_BYTE }
+		};
+		return npe_logical_reg_write(sc, regAccInfo[ctxtReg].regAddress,
+			ctxtRegVal, regAccInfo[ctxtReg].regSize, ctxtNum, verify);
+	}
+}
+
+/*
+ * NPE Mailbox support.
+ */
+#define	IX_NPEMH_MAXTRIES	100000
+
+static int
+ofifo_wait(struct ixpnpe_softc *sc)
+{
+	int i;
+
+	for (i = 0; i < IX_NPEMH_MAXTRIES; i++) {
+		if (npe_reg_read(sc, IX_NPESTAT) & IX_NPESTAT_OFNE)
+			return 1;
+		DELAY(10);
+	}
+	device_printf(sc->sc_dev, "%s: timeout, last status 0x%x\n",
+	    __func__, npe_reg_read(sc, IX_NPESTAT));
+	return 0;
+}
+
+static int
+getmsg(struct ixpnpe_softc *sc, uint32_t msg[2])
+{
+	mtx_assert(&sc->sc_mtx, MA_OWNED);
+
+	if (!ofifo_wait(sc))
+		return EAGAIN;
+	msg[0] = npe_reg_read(sc, IX_NPEFIFO);
+	DPRINTF(sc->sc_dev, "%s: msg0 0x%x\n", __func__, msg[0]);
+	if (!ofifo_wait(sc))
+		return EAGAIN;
+	msg[1] = npe_reg_read(sc, IX_NPEFIFO);
+	DPRINTF(sc->sc_dev, "%s: msg1 0x%x\n", __func__, msg[1]);
+	return 0;
+}
+
+static void
+ixpnpe_intr(void *arg)
+{
+	struct ixpnpe_softc *sc = arg;
+	uint32_t status;
+
+	mtx_lock(&sc->sc_mtx);
+	status = npe_reg_read(sc, IX_NPESTAT);
+	DPRINTF(sc->sc_dev, "%s: status 0x%x\n", __func__, status);
+	if ((status & IX_NPESTAT_OFINT) == 0) {
+		/* NB: should not happen */
+		device_printf(sc->sc_dev, "%s: status 0x%x\n",
+		    __func__, status);
+		/* XXX must silence interrupt? */
+		mtx_unlock(&sc->sc_mtx);
+		return;
+	}
+	/*
+	 * A message is waiting in the output FIFO, copy it so
+	 * the interrupt will be silenced.
+	 */
+	if (getmsg(sc, sc->sc_msg) == 0)
+		sc->sc_msgwaiting = 1;
+	mtx_unlock(&sc->sc_mtx);
+}
+
+static int
+ififo_wait(struct ixpnpe_softc *sc)
+{
+	int i;
+
+	for (i = 0; i < IX_NPEMH_MAXTRIES; i++) {
+		if (npe_reg_read(sc, IX_NPESTAT) & IX_NPESTAT_IFNF)
+			return 1;
+		DELAY(10);
+	}
+	device_printf(sc->sc_dev, "%s: timeout, last status 0x%x\n",
+	    __func__, npe_reg_read(sc, IX_NPESTAT));
+	return 0;
+}
+
+static int
+putmsg(struct ixpnpe_softc *sc, const uint32_t msg[2])
+{
+	mtx_assert(&sc->sc_mtx, MA_OWNED);
+
+	DPRINTF(sc->sc_dev, "%s: msg 0x%x:0x%x\n", __func__, msg[0], msg[1]);
+	if (!ififo_wait(sc))
+		return EIO;
+	npe_reg_write(sc, IX_NPEFIFO, msg[0]);
+	if (!ififo_wait(sc))
+		return EIO;
+	npe_reg_write(sc, IX_NPEFIFO, msg[1]);
+
+	return 0;
+}
+
+/*
+ * Send a msg to the NPE and wait for a reply.  We spin as
+ * we may be called early with interrupts not properly setup.
+ */
+int
+ixpnpe_sendandrecvmsg_sync(struct ixpnpe_softc *sc,
+	const uint32_t send[2], uint32_t recv[2])
+{
+	int error;
+
+	mtx_lock(&sc->sc_mtx);
+	error = putmsg(sc, send);
+	if (error == 0)
+		error = getmsg(sc, recv);
+	mtx_unlock(&sc->sc_mtx);
+
+	return error;
+}
+
+/*
+ * Send a msg to the NPE w/o waiting for a reply.
+ */
+int
+ixpnpe_sendmsg_async(struct ixpnpe_softc *sc, const uint32_t msg[2])
+{
+	int error;
+
+	mtx_lock(&sc->sc_mtx);
+	error = putmsg(sc, msg);
+	mtx_unlock(&sc->sc_mtx);
+
+	return error;
+}
+
+static int
+recvmsg_locked(struct ixpnpe_softc *sc, uint32_t msg[2])
+{
+	mtx_assert(&sc->sc_mtx, MA_OWNED);
+
+	DPRINTF(sc->sc_dev, "%s: msgwaiting %d\n", __func__, sc->sc_msgwaiting);
+	if (sc->sc_msgwaiting) {
+		msg[0] = sc->sc_msg[0];
+		msg[1] = sc->sc_msg[1];
+		sc->sc_msgwaiting = 0;
+		return 0;
+	}
+	return EAGAIN;
+}
+
+/*
+ * Receive any msg previously received from the NPE. If nothing
+ * is available we return EAGAIN and the caller is required to
+ * do a synchronous receive or try again later.
+ */
+int
+ixpnpe_recvmsg_async(struct ixpnpe_softc *sc, uint32_t msg[2])
+{
+	int error;
+
+	mtx_lock(&sc->sc_mtx);
+	error = recvmsg_locked(sc, msg);
+	mtx_unlock(&sc->sc_mtx);
+
+	return error;
+}
+
+/*
+ * Receive a msg from the NPE.  If one was received asynchronously
+ * then it's returned; otherwise we poll synchronously.
+ */
+int
+ixpnpe_recvmsg_sync(struct ixpnpe_softc *sc, uint32_t msg[2])
+{
+	int error;
+
+	mtx_lock(&sc->sc_mtx);
+	error = recvmsg_locked(sc, msg);
+	if (error == EAGAIN)
+		error = getmsg(sc, msg);
+	mtx_unlock(&sc->sc_mtx);
+
+	return error;
+}


Property changes on: trunk/sys/arm/xscale/ixp425/ixp425_npe.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/ixp425/ixp425_npereg.h
===================================================================
--- trunk/sys/arm/xscale/ixp425/ixp425_npereg.h	                        (rev 0)
+++ trunk/sys/arm/xscale/ixp425/ixp425_npereg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,428 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2006 Sam Leffler, Errno Consulting
+ * 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,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ *    redistribution must be conditioned upon including a substantially
+ *    similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
+ *
+ * $FreeBSD: stable/10/sys/arm/xscale/ixp425/ixp425_npereg.h 236987 2012-06-13 04:38:09Z imp $
+ */
+
+/*-
+ * Copyright (c) 2001-2005, Intel Corporation.
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+*/
+
+#ifndef _IXP425_NPEREG_H_
+#define _IXP425_NPEREG_H_
+
+/* signature found as 1st word in a microcode image library */
+#define IX_NPEDL_IMAGEMGR_SIGNATURE      0xDEADBEEF
+/* marks end of header in a microcode image library */
+#define IX_NPEDL_IMAGEMGR_END_OF_HEADER  0xFFFFFFFF
+
+/*
+ * Intel (R) IXP400 Software NPE Image ID Definition
+ *
+ * Definition of NPE Image ID to be passed to ixNpeDlNpeInitAndStart()
+ * as input of type uint32_t which has the following fields format:
+ *
+ * Field		[Bit Location]
+ * -----------------------------------
+ * Device ID		[31 - 28]
+ * NPE ID		[27 - 24]
+ * NPE Functionality ID	[23 - 16]
+ * Major Release Number	[15 -  8]
+ * Minor Release Number	[7 - 0]
+ */
+#define IX_NPEDL_NPEID_FROM_IMAGEID_GET(imageId) \
+    (((imageId) >> 24) & 0xf)
+#define IX_NPEDL_DEVICEID_FROM_IMAGEID_GET(imageId) \
+    (((imageId) >> 28) & 0xf)
+#define IX_NPEDL_FUNCTIONID_FROM_IMAGEID_GET(imageId) \
+    (((imageId) >> 16) & 0xff)
+#define IX_NPEDL_MAJOR_FROM_IMAGEID_GET(imageId) \
+    (((imageId) >> 8) & 0xff)
+#define IX_NPEDL_MINOR_FROM_IMAGEID_GET(imageId) \
+    (((imageId) >> 0) & 0xff)
+
+/*
+ * Instruction and Data Memory Size (in words) for each NPE
+ */
+#define IX_NPEDL_INS_MEMSIZE_WORDS_NPEA     4096
+#define IX_NPEDL_INS_MEMSIZE_WORDS_NPEB     2048
+#define IX_NPEDL_INS_MEMSIZE_WORDS_NPEC     2048
+
+#define IX_NPEDL_DATA_MEMSIZE_WORDS_NPEA    2048
+#define IX_NPEDL_DATA_MEMSIZE_WORDS_NPEB    2048
+#define IX_NPEDL_DATA_MEMSIZE_WORDS_NPEC    2048
+
+#define IXP46X_NPEDL_INS_MEMSIZE_WORDS      4096
+#define IXP46X_NPEDL_DATA_MEMSIZE_WORDS     4096
+
+/* BAR offsets */
+#define IX_NPEDL_REG_OFFSET_EXAD             0x00000000	/* Execution Address */
+#define IX_NPEDL_REG_OFFSET_EXDATA           0x00000004	/* Execution Data */
+#define IX_NPEDL_REG_OFFSET_EXCTL            0x00000008	/* Execution Control */
+#define IX_NPEDL_REG_OFFSET_EXCT 	     0x0000000C	/* Execution Count */
+#define IX_NPEDL_REG_OFFSET_AP0	             0x00000010	/* Action Point 0 */
+#define IX_NPEDL_REG_OFFSET_AP1	             0x00000014	/* Action Point 1 */
+#define IX_NPEDL_REG_OFFSET_AP2	             0x00000018	/* Action Point 2 */
+#define IX_NPEDL_REG_OFFSET_AP3	             0x0000001C	/* Action Point 3 */
+#define IX_NPEDL_REG_OFFSET_WFIFO            0x00000020	/* Watchpoint FIFO */
+#define IX_NPEDL_REG_OFFSET_WC	             0x00000024	/* Watch Count */
+#define IX_NPEDL_REG_OFFSET_PROFCT           0x00000028	/* Profile Count */
+#define IX_NPEDL_REG_OFFSET_STAT	     0x0000002C	/* Messaging Status */
+#define IX_NPEDL_REG_OFFSET_CTL	             0x00000030	/* Messaging Control */
+#define IX_NPEDL_REG_OFFSET_MBST	     0x00000034	/* Mailbox Status */
+#define IX_NPEDL_REG_OFFSET_FIFO	     0x00000038	/* Message FIFO */
+
+/*
+ * Reset value for Mailbox (MBST) register
+ * NOTE that if used, it should be complemented with an NPE intruction
+ * to clear the Mailbox at the NPE side as well
+ */
+#define IX_NPEDL_REG_RESET_MBST              0x0000F0F0
+
+#define IX_NPEDL_MASK_WFIFO_VALID            0x80000000	/* VALID bit */
+#define IX_NPEDL_MASK_STAT_OFNE              0x00010000	/* OFNE bit */
+#define IX_NPEDL_MASK_STAT_IFNE              0x00080000	/* IFNE bit */
+
+/*
+ * EXCTL (Execution Control) Register commands
+*/
+#define IX_NPEDL_EXCTL_CMD_NPE_STEP          0x01	/* Step 1 instruction */
+#define IX_NPEDL_EXCTL_CMD_NPE_START         0x02	/* Start execution */
+#define IX_NPEDL_EXCTL_CMD_NPE_STOP          0x03	/* Stop execution */
+#define IX_NPEDL_EXCTL_CMD_NPE_CLR_PIPE      0x04	/* Clear ins pipeline */
+
+/*
+ * Read/write operations use address in EXAD and data in EXDATA.
+ */
+#define IX_NPEDL_EXCTL_CMD_RD_INS_MEM        0x10	/* Read ins memory */
+#define IX_NPEDL_EXCTL_CMD_WR_INS_MEM        0x11	/* Write ins memory */
+#define IX_NPEDL_EXCTL_CMD_RD_DATA_MEM       0x12	/* Read data memory */
+#define IX_NPEDL_EXCTL_CMD_WR_DATA_MEM       0x13	/* Write data memory */
+#define IX_NPEDL_EXCTL_CMD_RD_ECS_REG        0x14	/* Read ECS register */
+#define IX_NPEDL_EXCTL_CMD_WR_ECS_REG        0x15	/* Write ECS register */
+
+#define IX_NPEDL_EXCTL_CMD_CLR_PROFILE_CNT   0x0C	/* Clear Profile Count register */
+
+
+/*
+ * EXCTL (Execution Control) Register status bit masks
+ */
+#define IX_NPEDL_EXCTL_STATUS_RUN            0x80000000
+#define IX_NPEDL_EXCTL_STATUS_STOP           0x40000000
+#define IX_NPEDL_EXCTL_STATUS_CLEAR          0x20000000
+#define IX_NPEDL_EXCTL_STATUS_ECS_K          0x00800000	/* pipeline Klean */
+
+/*
+ * Executing Context Stack (ECS) level registers
+ */
+#define IX_NPEDL_ECS_BG_CTXT_REG_0           0x00	/* reg 0 @ bg ctx */
+#define IX_NPEDL_ECS_BG_CTXT_REG_1           0x01	/* reg 1 @ bg ctx */
+#define IX_NPEDL_ECS_BG_CTXT_REG_2           0x02	/* reg 2 @ bg ctx */
+
+#define IX_NPEDL_ECS_PRI_1_CTXT_REG_0        0x04	/* reg 0 @ pri 1 ctx */
+#define IX_NPEDL_ECS_PRI_1_CTXT_REG_1        0x05	/* reg 1 @ pri 1 ctx */
+#define IX_NPEDL_ECS_PRI_1_CTXT_REG_2        0x06	/* reg 2 @ pri 1 ctx */
+
+#define IX_NPEDL_ECS_PRI_2_CTXT_REG_0        0x08	/* reg 0 @ pri 2 ctx */
+#define IX_NPEDL_ECS_PRI_2_CTXT_REG_1        0x09	/* reg 1 @ pri 2 ctx */
+#define IX_NPEDL_ECS_PRI_2_CTXT_REG_2        0x0A	/* reg 2 @ pri 2 ctx */
+
+#define IX_NPEDL_ECS_DBG_CTXT_REG_0          0x0C	/* reg 0 @ debug ctx */
+#define IX_NPEDL_ECS_DBG_CTXT_REG_1          0x0D	/* reg 1 @ debug ctx */
+#define IX_NPEDL_ECS_DBG_CTXT_REG_2          0x0E	/* reg 2 @ debug ctx */
+
+#define IX_NPEDL_ECS_INSTRUCT_REG            0x11	/* Instruction reg */
+
+/*
+ * Execution Access register reset values
+ */
+#define IX_NPEDL_ECS_BG_CTXT_REG_0_RESET     0xA0000000
+#define IX_NPEDL_ECS_BG_CTXT_REG_1_RESET     0x01000000
+#define IX_NPEDL_ECS_BG_CTXT_REG_2_RESET     0x00008000
+#define IX_NPEDL_ECS_PRI_1_CTXT_REG_0_RESET  0x20000080
+#define IX_NPEDL_ECS_PRI_1_CTXT_REG_1_RESET  0x01000000
+#define IX_NPEDL_ECS_PRI_1_CTXT_REG_2_RESET  0x00008000
+#define IX_NPEDL_ECS_PRI_2_CTXT_REG_0_RESET  0x20000080
+#define IX_NPEDL_ECS_PRI_2_CTXT_REG_1_RESET  0x01000000
+#define IX_NPEDL_ECS_PRI_2_CTXT_REG_2_RESET  0x00008000
+#define IX_NPEDL_ECS_DBG_CTXT_REG_0_RESET    0x20000000
+#define IX_NPEDL_ECS_DBG_CTXT_REG_1_RESET    0x00000000
+#define IX_NPEDL_ECS_DBG_CTXT_REG_2_RESET    0x001E0000
+#define IX_NPEDL_ECS_INSTRUCT_REG_RESET      0x1003C00F
+
+/*
+ * Masks used to read/write particular bits in Execution Access registers
+ */
+
+#define IX_NPEDL_MASK_ECS_REG_0_ACTIVE       0x80000000	/* Active bit */
+#define IX_NPEDL_MASK_ECS_REG_0_NEXTPC       0x1FFF0000	/* NextPC bits */
+#define IX_NPEDL_MASK_ECS_REG_0_LDUR         0x00000700	/* LDUR bits */
+
+#define IX_NPEDL_MASK_ECS_REG_1_CCTXT        0x000F0000	/* NextPC bits */
+#define IX_NPEDL_MASK_ECS_REG_1_SELCTXT      0x0000000F
+
+#define IX_NPEDL_MASK_ECS_DBG_REG_2_IF       0x00100000	/* IF bit */
+#define IX_NPEDL_MASK_ECS_DBG_REG_2_IE       0x00080000	/* IE bit */
+
+
+/*
+ * Bit-Offsets from LSB of particular bit-fields in Execution Access registers.
+ */
+
+#define IX_NPEDL_OFFSET_ECS_REG_0_NEXTPC     16
+#define IX_NPEDL_OFFSET_ECS_REG_0_LDUR        8
+
+#define IX_NPEDL_OFFSET_ECS_REG_1_CCTXT      16
+#define IX_NPEDL_OFFSET_ECS_REG_1_SELCTXT     0
+
+/*
+ * NPE core & co-processor instruction templates to load into NPE Instruction
+ * Register, for read/write of NPE register file registers.
+ */
+
+/*
+ * Read an 8-bit NPE internal logical register
+ * and return the value in the EXDATA register (aligned to MSB).
+ * NPE Assembler instruction:  "mov8 d0, d0  &&& DBG_WrExec"
+ */
+#define IX_NPEDL_INSTR_RD_REG_BYTE    0x0FC00000
+
+/*
+ * Read a 16-bit NPE internal logical register
+ * and return the value in the EXDATA register (aligned to MSB).
+ * NPE Assembler instruction:  "mov16 d0, d0  &&& DBG_WrExec"
+ */
+#define IX_NPEDL_INSTR_RD_REG_SHORT   0x0FC08010
+
+/*
+ * Read a 16-bit NPE internal logical register
+ * and return the value in the EXDATA register.
+ * NPE Assembler instruction:  "mov32 d0, d0  &&& DBG_WrExec"
+ */
+#define IX_NPEDL_INSTR_RD_REG_WORD    0x0FC08210
+
+/*
+ * Write an 8-bit NPE internal logical register.
+ * NPE Assembler instruction:  "mov8 d0, #0"
+ */
+#define IX_NPEDL_INSTR_WR_REG_BYTE    0x00004000
+
+/*
+ * Write a 16-bit NPE internal logical register.
+ * NPE Assembler instruction:  "mov16 d0, #0"
+ */
+#define IX_NPEDL_INSTR_WR_REG_SHORT   0x0000C000
+
+/*
+ * Write a 16-bit NPE internal logical register.
+ * NPE Assembler instruction:  "cprd32 d0    &&& DBG_RdInFIFO"
+ */
+#define IX_NPEDL_INSTR_RD_FIFO        0x0F888220
+
+/*
+ * Reset Mailbox (MBST) register
+ * NPE Assembler instruction:  "mov32 d0, d0  &&& DBG_ClearM"
+ */
+#define IX_NPEDL_INSTR_RESET_MBOX     0x0FAC8210
+
+
+/*
+ * Bit-offsets from LSB, of particular bit-fields in an NPE instruction
+ */
+#define IX_NPEDL_OFFSET_INSTR_SRC              4	/* src operand */
+#define IX_NPEDL_OFFSET_INSTR_DEST             9	/* dest operand */
+#define IX_NPEDL_OFFSET_INSTR_COPROC          18	/* coprocessor ins */
+
+/*
+ * Masks used to read/write particular bits of an NPE Instruction
+ */
+
+/**
+ * Mask the bits of 16-bit data value (least-sig 5 bits) to be used in
+ * SRC field of immediate-mode NPE instruction
+ */
+#define IX_NPEDL_MASK_IMMED_INSTR_SRC_DATA         0x1F
+
+/**
+ * Mask the bits of 16-bit data value (most-sig 11 bits) to be used in
+ * COPROC field of immediate-mode NPE instruction
+ */
+#define IX_NPEDL_MASK_IMMED_INSTR_COPROC_DATA      0xFFE0
+
+/**
+ * LSB offset of the bit-field of 16-bit data value (most-sig 11 bits)
+ * to be used in COPROC field of immediate-mode NPE instruction
+ */
+#define IX_NPEDL_OFFSET_IMMED_INSTR_COPROC_DATA    5
+
+/**
+ * Number of left-shifts required to align most-sig 11 bits of 16-bit
+ * data value into COPROC field of immediate-mode NPE instruction
+ */
+#define IX_NPEDL_DISPLACE_IMMED_INSTR_COPROC_DATA \
+     (IX_NPEDL_OFFSET_INSTR_COPROC - IX_NPEDL_OFFSET_IMMED_INSTR_COPROC_DATA)
+
+/**
+ * LDUR value used with immediate-mode NPE Instructions by the NpeDl
+ * for writing to NPE internal logical registers
+ */
+#define IX_NPEDL_WR_INSTR_LDUR                     1
+
+/**
+ * LDUR value used with NON-immediate-mode NPE Instructions by the NpeDl
+ * for reading from NPE internal logical registers
+ */
+#define IX_NPEDL_RD_INSTR_LDUR                     0
+
+
+/**
+ * NPE internal Context Store registers.
+ */
+typedef enum
+{
+    IX_NPEDL_CTXT_REG_STEVT = 0,  /**< identifies STEVT   */
+    IX_NPEDL_CTXT_REG_STARTPC,    /**< identifies STARTPC */
+    IX_NPEDL_CTXT_REG_REGMAP,     /**< identifies REGMAP  */
+    IX_NPEDL_CTXT_REG_CINDEX,     /**< identifies CINDEX  */
+    IX_NPEDL_CTXT_REG_MAX         /**< Total number of Context Store registers */
+} IxNpeDlCtxtRegNum;
+
+
+/*
+ * NPE Context Store register logical addresses
+ */
+#define IX_NPEDL_CTXT_REG_ADDR_STEVT      0x0000001B
+#define IX_NPEDL_CTXT_REG_ADDR_STARTPC    0x0000001C
+#define IX_NPEDL_CTXT_REG_ADDR_REGMAP     0x0000001E
+#define IX_NPEDL_CTXT_REG_ADDR_CINDEX     0x0000001F
+
+/*
+ * NPE Context Store register reset values
+ */
+
+/**
+ * Reset value of STEVT NPE internal Context Store register
+ *        (STEVT = off, 0x80)
+ */
+#define IX_NPEDL_CTXT_REG_RESET_STEVT     0x80
+
+/**
+ * Reset value of STARTPC NPE internal Context Store register
+ *        (STARTPC = 0x0000)
+ */
+#define IX_NPEDL_CTXT_REG_RESET_STARTPC   0x0000
+
+/**
+ * Reset value of REGMAP NPE internal Context Store register
+ *        (REGMAP = d0->p0, d8->p2, d16->p4)
+ */
+#define IX_NPEDL_CTXT_REG_RESET_REGMAP    0x0820
+
+/**
+ * Reset value of CINDEX NPE internal Context Store register
+ *        (CINDEX = 0)
+ */
+#define IX_NPEDL_CTXT_REG_RESET_CINDEX    0x00
+
+
+/*
+ * Numeric range of context levels available on an NPE
+ */
+#define IX_NPEDL_CTXT_NUM_MIN             0
+#define IX_NPEDL_CTXT_NUM_MAX             15
+
+
+/**
+ * Number of Physical registers currently supported
+ *        Initial NPE implementations will have a 32-word register file.
+ *        Later implementations may have a 64-word register file.
+ */
+#define IX_NPEDL_TOTAL_NUM_PHYS_REG               32
+
+/**
+ * LSB-offset of Regmap number in Physical NPE register address, used
+ *        for Physical To Logical register address mapping in the NPE
+ */
+#define IX_NPEDL_OFFSET_PHYS_REG_ADDR_REGMAP      1
+
+/**
+ * Mask to extract a logical NPE register address from a physical
+ *        register address, used for Physical To Logical address mapping
+ */
+#define IX_NPEDL_MASK_PHYS_REG_ADDR_LOGICAL_ADDR   0x1
+
+/*
+ * NPE Message/Mailbox interface.
+ */
+#define	IX_NPESTAT	IX_NPEDL_REG_OFFSET_STAT	/* status register */
+#define	IX_NPECTL	IX_NPEDL_REG_OFFSET_CTL		/* control register */
+#define	IX_NPEFIFO	IX_NPEDL_REG_OFFSET_FIFO	/* FIFO register */
+
+/* control register */
+#define	IX_NPECTL_OFE		0x00010000	/* output fifo enable */
+#define	IX_NPECTL_IFE		0x00020000	/* input fifo enable */
+#define	IX_NPECTL_OFWE		0x01000000	/* output fifo write enable */
+#define	IX_NPECTL_IFWE		0x02000000	/* input fifo write enable */
+
+/* status register */
+#define	IX_NPESTAT_OFNE		0x00010000	/* output fifo not empty */
+#define	IX_NPESTAT_IFNF		0x00020000	/* input fifo not full */
+#define	IX_NPESTAT_OFNF		0x00040000	/* output fifo not full */
+#define	IX_NPESTAT_IFNE		0x00080000	/* input fifo not empty */
+#define	IX_NPESTAT_MBINT	0x00100000	/* Mailbox interrupt */
+#define	IX_NPESTAT_IFINT	0x00200000	/* input fifo interrupt */
+#define	IX_NPESTAT_OFINT	0x00400000	/* output fifo interrupt */
+#define	IX_NPESTAT_WFINT	0x00800000	/* watch fifo interrupt */
+#endif /* _IXP425_NPEREG_H_ */


Property changes on: trunk/sys/arm/xscale/ixp425/ixp425_npereg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/ixp425/ixp425_npevar.h
===================================================================
--- trunk/sys/arm/xscale/ixp425/ixp425_npevar.h	                        (rev 0)
+++ trunk/sys/arm/xscale/ixp425/ixp425_npevar.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,123 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2006 Sam Leffler.  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 ``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 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: stable/10/sys/arm/xscale/ixp425/ixp425_npevar.h 186420 2008-12-23 04:51:46Z sam $
+ */
+
+#ifndef _IXP425_NPEVAR_H_
+#define _IXP425_NPEVAR_H_
+
+/*
+ * Intel (R) IXP400 Software NPE Image ID Definition
+ *
+ * Firmware Id's for current firmware image.  These are typed by
+ * NPE ID and the feature set.  Not all features are available
+ * on all NPE's.  The Image ID has the following structure:
+ *
+ * Field		[Bit Location]
+ * -----------------------------------
+ * Device ID		[28..31]
+ * NPE ID		[24..27]
+ * NPE Functionality ID	[16..23]
+ * Major Release Number	[8..15]
+ * Minor Release Number	[0..7]
+ *
+ * The following "feature sets" are known to exist:
+ *
+ * HSS-0: supports 32 channelized and 4 packetized.
+ * HSS-0 + ATM + SPHY:
+ *    For HSS, 16/32 channelized and 4/0 packetized.
+ *    For ATM, AAL5, AAL0 and OAM for UTOPIA SPHY, 1 logical port, 32 VCs.
+ *    Fast Path support.
+ * HSS-0 + ATM + MPHY:
+ *    For HSS, 16/32 channelized and 4/0 packetized.
+ *    For ATM, AAL5, AAL0 and OAM for UTOPIA MPHY, 1 logical port, 32 VCs.
+ *    Fast Path support.
+ * ATM-Only:
+ *    AAL5, AAL0 and OAM for UTOPIA MPHY, 12 logical ports, 32 VCs.
+ *    Fast Path support.
+ * HSS-2:
+ *    HSS-0 and HSS-1.
+ *    Each HSS port supports 32 channelized and 4 packetized.
+ * ETH: Ethernet Rx/Tx which includes:
+ *    MAC_FILTERING, MAC_LEARNING, SPANNING_TREE, FIREWALL
+ * ETH+VLAN Ethernet Rx/Tx which includes:
+ *    MAC_FILTERING, MAC_LEARNING, SPANNING_TREE, FIREWALL, VLAN_QOS
+ * ETH+VLAN+HDR: Ethernet Rx/Tx which includes:
+ *    SPANNING_TREE, FIREWALL, VLAN_QOS, HEADER_CONVERSION
+ */
+#define NPEIMAGE_DEVID(id)	(((id) >> 28) & 0xf)
+#define NPEIMAGE_NPEID(id)	(((id) >> 24) & 0xf)
+#define NPEIMAGE_FUNCID(id) 	(((id) >> 16) & 0xff)
+#define NPEIMAGE_MAJOR(id)	(((id) >> 8)  & 0xff)
+#define NPEIMAGE_MINOR(id)	(((id) >> 0)  & 0xff)
+#define	NPEIMAGE_MAKEID(dev, npe, func, maj, min) \
+	((((dev) & 0xf) << 28) | (((npe) & 0xf) << 24) | \
+	(((func) & 0xff) << 16) (((maj) & 0xff) << 8) | (((min) & 0xff) << 0))
+
+/* XXX not right, revise */
+/* NPE A Firmware Image Id's */
+#define	NPEFW_A_HSS0		0x00010000 /* HSS-0: 32 chan+4 packet */
+#define NPEFW_A_HSS0_ATM_S_1	0x00020000 /* HSS-0+ATM UTOPIA SPHY (1 port) */
+#define NPEFW_A_HSS0_ATM_M_1	0x00020000 /* HSS-0+ATM UTOPIA MPHY (1 port) */
+#define NPEFW_A_ATM_M_12	0x00040000 /* ATM UTOPIA MPHY (12 ports) */
+#define NPEFW_A_DMA		0x00150100 /* DMA only */
+#define	NPEFW_A_HSS2		0x00090000 /* HSS-0 + HSS-1 */
+#define	NPEFW_A_ETH		0x10800200 /* Basic Ethernet */
+#define	NPEFW_A_ETH_VLAN	0x10810200 /* NPEFW_A_ETH + VLAN QoS */
+#define	NPEFW_A_ETH_VLAN_HDR	0x10820200 /* NPEFW_A_ETH_VLAN + Hdr conv */
+/* XXX ... more not included */
+
+/* NPE B Firmware Image Id's */
+#define NPEFW_B_ETH		0x01000200 /* Basic Ethernet */
+#define NPEFW_B_ETH_VLAN	0x01010200 /* NPEFW_B_ETH + VLAN QoS */
+#define NPEFW_B_ETH_VLAN_HDR	0x01020201 /* NPEFW_B_ETH_VLAN + Hdr conv */
+#define NPEFW_B_DMA		0x01020100 /* DMA only */
+/* XXX ... more not include */
+
+/* NPE ID's */
+#define	NPE_A		0
+#define	NPE_B		1
+#define	NPE_C		2
+#define	NPE_MAX		(NPE_C+1)
+
+#define	IXP425_NPE_A_IMAGEID	0x10820200
+#define	IXP425_NPE_B_IMAGEID	0x01020201
+#define	IXP425_NPE_C_IMAGEID	0x02050201
+
+struct ixpnpe_softc;
+struct ixpnpe_softc *ixpnpe_attach(device_t, int npeid);
+void	ixpnpe_detach(struct ixpnpe_softc *);
+int	ixpnpe_stopandreset(struct ixpnpe_softc *);
+int	ixpnpe_start(struct ixpnpe_softc *);
+int	ixpnpe_stop(struct ixpnpe_softc *);
+int	ixpnpe_init(struct ixpnpe_softc *);
+int	ixpnpe_getfunctionality(struct ixpnpe_softc *sc);
+
+int	ixpnpe_sendmsg_async(struct ixpnpe_softc *, const uint32_t msg[2]);
+int	ixpnpe_recvmsg_async(struct ixpnpe_softc *, uint32_t msg[2]);
+int	ixpnpe_sendandrecvmsg_sync(struct ixpnpe_softc *,
+	     const uint32_t send[2], uint32_t recv[2]);
+int	ixpnpe_recvmsg_sync(struct ixpnpe_softc *, uint32_t msg[2]);
+#endif /* _IXP425_NPEVAR_H_ */


Property changes on: trunk/sys/arm/xscale/ixp425/ixp425_npevar.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/ixp425/ixp425_pci.c
===================================================================
--- trunk/sys/arm/xscale/ixp425/ixp425_pci.c	                        (rev 0)
+++ trunk/sys/arm/xscale/ixp425/ixp425_pci.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,478 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: ixp425_pci.c,v 1.5 2006/04/10 03:36:03 simonb Exp $ */
+
+/*
+ * Copyright (c) 2003
+ *	Ichiro FUKUHARA <ichiro at ichiro.org>.
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Ichiro FUKUHARA.
+ * 4. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ICHIRO FUKUHARA ``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 ICHIRO FUKUHARA OR THE VOICES IN HIS HEAD 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: stable/10/sys/arm/xscale/ixp425/ixp425_pci.c 278613 2015-02-12 03:50:33Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#define _ARM32_BUS_DMA_PRIVATE
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/rman.h>
+
+#include <dev/pci/pcivar.h>
+
+#include <machine/armreg.h>
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/pcb.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/vm_extern.h>
+
+#include <arm/xscale/ixp425/ixp425reg.h>
+#include <arm/xscale/ixp425/ixp425var.h>
+
+#include <dev/pci/pcib_private.h>
+#include "pcib_if.h"
+
+#include <dev/pci/pcireg.h>
+extern struct ixp425_softc *ixp425_softc;
+
+#define	PCI_CSR_WRITE_4(sc, reg, data)	\
+	bus_write_4(sc->sc_csr, reg, data)
+
+#define	PCI_CSR_READ_4(sc, reg)	\
+	bus_read_4(sc->sc_csr, reg)
+
+#define PCI_CONF_LOCK(s)	(s) = disable_interrupts(PSR_I)
+#define PCI_CONF_UNLOCK(s)	restore_interrupts((s))
+
+static device_probe_t ixppcib_probe;
+static device_attach_t ixppcib_attach;
+static bus_read_ivar_t ixppcib_read_ivar;
+static bus_write_ivar_t ixppcib_write_ivar;
+static bus_setup_intr_t ixppcib_setup_intr;
+static bus_teardown_intr_t ixppcib_teardown_intr;
+static bus_alloc_resource_t ixppcib_alloc_resource;
+static bus_activate_resource_t ixppcib_activate_resource;
+static bus_deactivate_resource_t ixppcib_deactivate_resource;
+static bus_release_resource_t ixppcib_release_resource;
+static pcib_maxslots_t ixppcib_maxslots;
+static pcib_read_config_t ixppcib_read_config;
+static pcib_write_config_t ixppcib_write_config;
+static pcib_route_interrupt_t ixppcib_route_interrupt;
+
+static int
+ixppcib_probe(device_t dev)
+{
+	device_set_desc(dev, "IXP4XX PCI Bus");
+        return (0);
+}
+
+static void
+ixp425_pci_conf_reg_write(struct ixppcib_softc *sc, uint32_t reg,
+    uint32_t data)
+{
+	PCI_CSR_WRITE_4(sc, PCI_CRP_AD_CBE, ((reg & ~3) | COMMAND_CRP_WRITE));
+	PCI_CSR_WRITE_4(sc, PCI_CRP_AD_WDATA, data);
+}
+
+static int
+ixppcib_attach(device_t dev)
+{
+	int rid;
+	struct ixppcib_softc *sc;
+
+	sc = device_get_softc(dev);
+
+	rid = 0;
+	sc->sc_csr = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid,
+	    IXP425_PCI_HWBASE, IXP425_PCI_HWBASE + IXP425_PCI_SIZE,
+	    IXP425_PCI_SIZE, RF_ACTIVE);
+	if (sc->sc_csr == NULL)
+		panic("cannot allocate PCI CSR registers");
+
+	ixp425_md_attach(dev);
+	/* always setup the base, incase another OS messes w/ it */
+	PCI_CSR_WRITE_4(sc, PCI_PCIMEMBASE, 0x48494a4b);
+
+	rid = 0;
+	sc->sc_mem = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid,
+	    IXP425_PCI_MEM_HWBASE, IXP425_PCI_MEM_HWBASE + IXP425_PCI_MEM_SIZE,
+	    IXP425_PCI_MEM_SIZE, RF_ACTIVE);
+	if (sc->sc_mem == NULL)
+		panic("cannot allocate PCI MEM space");
+
+	/* NB: PCI dma window is 64M so anything above must be bounced */
+	if (bus_dma_tag_create(NULL, 1, 0, IXP425_AHB_OFFSET + 64 * 1024 * 1024,
+	    BUS_SPACE_MAXADDR, NULL, NULL,  0xffffffff, 0xff, 0xffffffff, 0,
+	    NULL, NULL, &sc->sc_dmat))
+		panic("couldn't create the PCI dma tag !");
+	/*
+	 * The PCI bus can only address 64MB. However, due to the way our
+	 * implementation of busdma works, busdma can't tell if a device
+	 * is a PCI device or not. So defaults to the PCI dma tag, which
+	 * restrict the DMA'able memory to the first 64MB, and explicitely
+	 * create less restrictive tags for non-PCI devices.
+	 */
+	arm_root_dma_tag = sc->sc_dmat;
+	/*
+	 * Initialize the bus space tags.
+	 */
+	ixp425_io_bs_init(&sc->sc_pci_iot, sc);
+	ixp425_mem_bs_init(&sc->sc_pci_memt, sc);
+
+	sc->sc_dev = dev;
+
+	/* Initialize memory and i/o rmans. */
+	sc->sc_io_rman.rm_type = RMAN_ARRAY;
+	sc->sc_io_rman.rm_descr = "IXP4XX PCI I/O Ports";
+	if (rman_init(&sc->sc_io_rman) != 0 ||
+		rman_manage_region(&sc->sc_io_rman, 0,
+	    	    IXP425_PCI_IO_SIZE) != 0) {
+		panic("ixppcib_probe: failed to set up I/O rman");
+	}
+
+	sc->sc_mem_rman.rm_type = RMAN_ARRAY;
+	sc->sc_mem_rman.rm_descr = "IXP4XX PCI Memory";
+	if (rman_init(&sc->sc_mem_rman) != 0 ||
+		rman_manage_region(&sc->sc_mem_rman, IXP425_PCI_MEM_HWBASE,
+		    IXP425_PCI_MEM_HWBASE + IXP425_PCI_MEM_SIZE) != 0) {
+		panic("ixppcib_probe: failed to set up memory rman");
+	}
+
+	/*
+	 * PCI->AHB address translation
+	 * 	begin at the physical memory start + OFFSET
+	 */
+	PCI_CSR_WRITE_4(sc, PCI_AHBMEMBASE,
+	    (IXP425_AHB_OFFSET & 0xFF000000) +
+	    ((IXP425_AHB_OFFSET & 0xFF000000) >> 8) +
+	    ((IXP425_AHB_OFFSET & 0xFF000000) >> 16) +
+	    ((IXP425_AHB_OFFSET & 0xFF000000) >> 24) +
+	    0x00010203);
+	
+#define IXPPCIB_WRITE_CONF(sc, reg, val) \
+	ixp425_pci_conf_reg_write(sc, reg, val)
+	/* Write Mapping registers PCI Configuration Registers */
+	/* Base Address 0 - 3 */
+	IXPPCIB_WRITE_CONF(sc, PCI_MAPREG_BAR0, IXP425_AHB_OFFSET + 0x00000000);
+	IXPPCIB_WRITE_CONF(sc, PCI_MAPREG_BAR1, IXP425_AHB_OFFSET + 0x01000000);
+	IXPPCIB_WRITE_CONF(sc, PCI_MAPREG_BAR2, IXP425_AHB_OFFSET + 0x02000000);
+	IXPPCIB_WRITE_CONF(sc, PCI_MAPREG_BAR3, IXP425_AHB_OFFSET + 0x03000000);
+	
+	/* Base Address 4 */
+	IXPPCIB_WRITE_CONF(sc, PCI_MAPREG_BAR4, 0xffffffff);
+	
+	/* Base Address 5 */
+	IXPPCIB_WRITE_CONF(sc, PCI_MAPREG_BAR5, 0x00000000);
+	
+	/* Assert some PCI errors */
+	PCI_CSR_WRITE_4(sc, PCI_ISR, ISR_AHBE | ISR_PPE | ISR_PFE | ISR_PSE);
+	
+#ifdef __ARMEB__
+	/*
+	 * Set up byte lane swapping between little-endian PCI
+	 * and the big-endian AHB bus
+	 */
+	PCI_CSR_WRITE_4(sc, PCI_CSR, CSR_IC | CSR_ABE | CSR_PDS);
+#else
+	PCI_CSR_WRITE_4(sc, PCI_CSR, CSR_IC | CSR_ABE);
+#endif
+	
+	/*
+	 * Enable bus mastering and I/O,memory access
+	 */
+	IXPPCIB_WRITE_CONF(sc, PCIR_COMMAND,
+	    PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN);
+	
+	/*
+	 * Wait some more to ensure PCI devices have stabilised.
+	 */
+	DELAY(50000);
+
+	device_add_child(dev, "pci", -1);
+	return (bus_generic_attach(dev));
+}
+
+static int
+ixppcib_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
+{
+	struct ixppcib_softc *sc;
+
+	sc = device_get_softc(dev);
+	switch (which) {
+	case PCIB_IVAR_DOMAIN:
+		*result = 0;
+		return (0);
+	case PCIB_IVAR_BUS:
+		*result = sc->sc_bus;
+		return (0);
+	}
+
+	return (ENOENT);
+}
+
+static int
+ixppcib_write_ivar(device_t dev, device_t child, int which, uintptr_t value)
+{
+	struct ixppcib_softc *sc;
+
+	sc = device_get_softc(dev);
+	switch (which) {
+	case PCIB_IVAR_DOMAIN:
+		return (EINVAL);
+	case PCIB_IVAR_BUS:
+		sc->sc_bus = value;
+		return (0);
+	}
+
+	return (ENOENT);
+}
+
+static int
+ixppcib_setup_intr(device_t dev, device_t child, struct resource *ires,
+    int flags, driver_filter_t *filt, driver_intr_t *intr, void *arg,
+    void **cookiep)
+{
+
+	return (BUS_SETUP_INTR(device_get_parent(dev), child, ires, flags,
+	    filt, intr, arg, cookiep));
+}
+
+static int
+ixppcib_teardown_intr(device_t dev, device_t child, struct resource *vec,
+     void *cookie)
+{
+
+	return (BUS_TEARDOWN_INTR(device_get_parent(dev), child, vec, cookie));
+}
+
+static struct resource *
+ixppcib_alloc_resource(device_t bus, device_t child, int type, int *rid,
+    u_long start, u_long end, u_long count, u_int flags)
+{
+	struct ixppcib_softc *sc = device_get_softc(bus);
+	struct rman *rmanp;
+	struct resource *rv;
+
+	rv = NULL;
+	switch (type) {
+	case SYS_RES_IRQ:
+		rmanp = &sc->sc_irq_rman;
+		break;
+
+	case SYS_RES_IOPORT:
+		rmanp = &sc->sc_io_rman;
+		break;
+
+	case SYS_RES_MEMORY:
+		rmanp = &sc->sc_mem_rman;
+		break;
+
+	default:
+		return (rv);
+	}
+
+	rv = rman_reserve_resource(rmanp, start, end, count, flags & ~RF_ACTIVE,
+	    child);
+	if (rv == NULL)
+		return (NULL);
+	rman_set_rid(rv, *rid);
+	if (flags & RF_ACTIVE) {
+		if (bus_activate_resource(child, type, *rid, rv)) {
+			rman_release_resource(rv);
+			return (NULL);
+		}
+	}
+
+	return (rv);
+}
+
+static int
+ixppcib_activate_resource(device_t bus, device_t child, int type, int rid,
+    struct resource *r)
+{
+
+	struct ixppcib_softc *sc = device_get_softc(bus);
+
+	switch (type) {
+	case SYS_RES_IOPORT:
+		rman_set_bustag(r, &sc->sc_pci_iot);
+		rman_set_bushandle(r, rman_get_start(r));
+		break;
+	case SYS_RES_MEMORY:
+		rman_set_bustag(r, &sc->sc_pci_memt);
+		rman_set_bushandle(r, rman_get_bushandle(sc->sc_mem) +
+		    (rman_get_start(r) - IXP425_PCI_MEM_HWBASE));
+		break;
+	}
+		
+	return (rman_activate_resource(r));
+}
+
+static int
+ixppcib_deactivate_resource(device_t bus, device_t child, int type, int rid,
+    struct resource *r)
+{
+
+	device_printf(bus, "%s called deactivate_resource (unexpected)\n",
+	    device_get_nameunit(child));
+	return (ENXIO);
+}
+
+static int
+ixppcib_release_resource(device_t bus, device_t child, int type, int rid,
+    struct resource *r)
+{
+
+	device_printf(bus, "%s called release_resource (unexpected)\n",
+	    device_get_nameunit(child));
+	return (ENXIO);
+}
+
+static void
+ixppcib_conf_setup(struct ixppcib_softc *sc, int bus, int slot, int func,
+    int reg)
+{
+	if (bus == 0) {
+		/* configuration type 0 */
+		PCI_CSR_WRITE_4(sc, PCI_NP_AD,
+		    (1U << (32 - (slot & 0x1f))) |
+		    ((func & 0x7) << 8) | (reg & ~3));
+	} else {
+		/* configuration type 1 */
+		PCI_CSR_WRITE_4(sc, PCI_NP_AD,
+		    (bus << 16) | (slot << 11) |
+		    (func << 8) | (reg & ~3) | 1);
+	}
+
+}
+
+static int
+ixppcib_maxslots(device_t dev)
+{
+
+	return (PCI_SLOTMAX);
+}
+
+static u_int32_t
+ixppcib_read_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg,
+    int bytes)
+{
+	struct ixppcib_softc *sc = device_get_softc(dev);
+	u_int32_t data, ret;
+
+	ixppcib_conf_setup(sc, bus, slot, func, reg & ~3);
+
+	PCI_CSR_WRITE_4(sc, PCI_NP_CBE, COMMAND_NP_CONF_READ);
+	ret = PCI_CSR_READ_4(sc, PCI_NP_RDATA);
+	ret >>= (reg & 3) * 8;
+	ret &= 0xffffffff >> ((4 - bytes) * 8);
+#if 0
+	device_printf(dev, "%s: %u:%u:%u %#x(%d) = %#x\n",
+	    __func__, bus, slot, func, reg, bytes, ret);
+#endif
+	/* check & clear PCI abort */
+	data = PCI_CSR_READ_4(sc, PCI_ISR);
+	if (data & ISR_PFE) {
+		PCI_CSR_WRITE_4(sc, PCI_ISR, ISR_PFE);
+		return (-1);
+	}
+	return (ret);
+}
+
+static const int byteenables[] = { 0, 0x10, 0x30, 0x70, 0xf0 };
+
+static void
+ixppcib_write_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg,
+    u_int32_t val, int bytes)
+{
+	struct ixppcib_softc *sc = device_get_softc(dev);
+	u_int32_t data;
+
+#if 0
+	device_printf(dev, "%s: %u:%u:%u %#x(%d) = %#x\n",
+	    __func__, bus, slot, func, reg, bytes, val);
+#endif
+	ixppcib_conf_setup(sc, bus, slot, func, reg & ~3);
+
+	/* Byte enables are active low, so not them first */
+	PCI_CSR_WRITE_4(sc, PCI_NP_CBE, COMMAND_NP_CONF_WRITE |
+	    (~(byteenables[bytes] << (reg & 3)) & 0xf0));
+	PCI_CSR_WRITE_4(sc, PCI_NP_WDATA, val << ((reg & 3) * 8));
+
+	/* check & clear PCI abort */
+	data = PCI_CSR_READ_4(sc, PCI_ISR);
+	if (data & ISR_PFE)
+		PCI_CSR_WRITE_4(sc, PCI_ISR, ISR_PFE);
+}
+
+static int
+ixppcib_route_interrupt(device_t bridge, device_t device, int pin)
+{
+
+	return (ixp425_md_route_interrupt(bridge, device, pin));
+}
+
+static device_method_t ixppcib_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,			ixppcib_probe),
+	DEVMETHOD(device_attach,		ixppcib_attach),
+
+	/* Bus interface */
+	DEVMETHOD(bus_read_ivar,		ixppcib_read_ivar),
+	DEVMETHOD(bus_write_ivar,		ixppcib_write_ivar),
+	DEVMETHOD(bus_setup_intr,		ixppcib_setup_intr),
+	DEVMETHOD(bus_teardown_intr,		ixppcib_teardown_intr),
+	DEVMETHOD(bus_alloc_resource,		ixppcib_alloc_resource),
+	DEVMETHOD(bus_activate_resource,	ixppcib_activate_resource),
+	DEVMETHOD(bus_deactivate_resource,	ixppcib_deactivate_resource),
+	DEVMETHOD(bus_release_resource,		ixppcib_release_resource),
+	/* DEVMETHOD(bus_get_dma_tag,		ixppcib_get_dma_tag), */
+
+	/* pcib interface */
+	DEVMETHOD(pcib_maxslots,		ixppcib_maxslots),
+	DEVMETHOD(pcib_read_config,		ixppcib_read_config),
+	DEVMETHOD(pcib_write_config,		ixppcib_write_config),
+	DEVMETHOD(pcib_route_interrupt,		ixppcib_route_interrupt),
+
+	DEVMETHOD_END
+};
+
+static driver_t ixppcib_driver = {
+	"pcib",
+	ixppcib_methods,
+	sizeof(struct ixppcib_softc),
+};
+static devclass_t ixppcib_devclass;
+
+DRIVER_MODULE(ixppcib, ixp, ixppcib_driver, ixppcib_devclass, 0, 0);


Property changes on: trunk/sys/arm/xscale/ixp425/ixp425_pci.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/ixp425/ixp425_pci_asm.S
===================================================================
--- trunk/sys/arm/xscale/ixp425/ixp425_pci_asm.S	                        (rev 0)
+++ trunk/sys/arm/xscale/ixp425/ixp425_pci_asm.S	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,109 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: ixp425_pci_asm.S,v 1.2 2005/12/11 12:16:51 christos Exp $	*/
+
+/*
+ * Copyright (c) 2003 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Jason R. Thorpe for Wasabi Systems, Inc.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed for the NetBSD Project by
+ *	Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
+ * 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: stable/10/sys/arm/xscale/ixp425/ixp425_pci_asm.S 275767 2014-12-14 16:28:53Z andrew $
+ *
+ */
+
+#include <machine/asm.h>
+
+/*
+ * Bus space functions for IXP425 PCI space access.  We have to swizzle
+ * the address for 1 and 2 byte accesses when in big-endian mode.
+ */
+
+/*
+ * read single
+ */
+
+ENTRY(ixp425_pci_mem_bs_r_1)
+#ifdef __ARMEB__
+	add	r1, r1, r2
+	eor	r1, r1, #0x3
+	ldrb	r0, [r1]
+#else
+	ldrb	r0, [r1, r2]
+#endif /* __ARMEB__ */
+	mov	pc, lr
+END(ixp425_pci_mem_bs_r_1)
+
+ENTRY(ixp425_pci_mem_bs_r_2)
+#ifdef __ARMEB__
+	add	r1, r1, r2
+	eor	r1, r1, #0x2
+	ldrh	r0, [r1]
+#else
+	ldrh	r0, [r1, r2]
+#endif /* __ARMEB__ */
+	mov	pc, lr
+END(ixp425_pci_mem_bs_r_2)
+
+ENTRY(ixp425_pci_mem_bs_r_4)
+	ldr	r0, [r1, r2]
+	mov	pc, lr
+END(ixp425_pci_mem_bs_r_4)
+
+/*
+ * write single
+ */
+
+ENTRY(ixp425_pci_mem_bs_w_1)
+#ifdef __ARMEB__
+	add	r1, r1, r2
+	eor	r1, r1, #0x3
+	strb	r3, [r1]
+#else
+	strb	r3, [r1, r2]
+#endif /* __ARMEB__ */
+	mov	pc, lr
+END(ixp425_pci_mem_bs_w_1)
+
+ENTRY(ixp425_pci_mem_bs_w_2)
+#ifdef __ARMEB__
+	add	r1, r1, r2
+	eor	r1, r1, #0x2
+	strh	r3, [r1]
+#else
+	strh	r3, [r1, r2]
+#endif /* __ARMEB__ */
+	mov	pc, lr
+END(ixp425_pci_mem_bs_w_2)
+
+ENTRY(ixp425_pci_mem_bs_w_4)
+	str	r3, [r1, r2]
+	mov	pc, lr
+END(ixp425_pci_mem_bs_w_4)


Property changes on: trunk/sys/arm/xscale/ixp425/ixp425_pci_asm.S
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/ixp425/ixp425_pci_space.c
===================================================================
--- trunk/sys/arm/xscale/ixp425/ixp425_pci_space.c	                        (rev 0)
+++ trunk/sys/arm/xscale/ixp425/ixp425_pci_space.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,486 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: ixp425_pci_space.c,v 1.6 2006/04/10 03:36:03 simonb Exp $ */
+
+/*
+ * Copyright (c) 2003
+ *	Ichiro FUKUHARA <ichiro at ichiro.org>.
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Ichiro FUKUHARA.
+ * 4. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ICHIRO FUKUHARA ``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 ICHIRO FUKUHARA OR THE VOICES IN HIS HEAD 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: stable/10/sys/arm/xscale/ixp425/ixp425_pci_space.c 278727 2015-02-13 22:32:02Z ian $");
+
+/*
+ * bus_space PCI functions for ixp425
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/endian.h>
+
+#include <machine/pcb.h>
+
+#include <vm/vm.h>
+#include <vm/vm_kern.h>
+#include <vm/pmap.h>
+#include <vm/vm_page.h>
+#include <vm/vm_extern.h>
+
+#include <machine/bus.h>
+
+#include <arm/xscale/ixp425/ixp425reg.h>
+#include <arm/xscale/ixp425/ixp425var.h>
+
+/*
+ * Macros to read/write registers
+*/
+#define CSR_READ_4(x)		*(volatile uint32_t *) \
+	(IXP425_PCI_CSR_BASE + (x))
+#define CSR_WRITE_4(x, v)	*(volatile uint32_t *) \
+	(IXP425_PCI_CSR_BASE + (x)) = (v)
+
+/* Proto types for all the bus_space structure functions */
+bs_protos(ixp425_pci);
+bs_protos(ixp425_pci_io);
+bs_protos(ixp425_pci_mem);
+
+/* special I/O functions */
+static u_int8_t  _pci_io_bs_r_1(bus_space_tag_t tag, bus_space_handle_t, bus_size_t);
+static u_int16_t _pci_io_bs_r_2(bus_space_tag_t tag, bus_space_handle_t, bus_size_t);
+static u_int32_t _pci_io_bs_r_4(bus_space_tag_t tag, bus_space_handle_t, bus_size_t);
+
+static void _pci_io_bs_w_1(bus_space_tag_t tag, bus_space_handle_t, bus_size_t, u_int8_t);
+static void _pci_io_bs_w_2(bus_space_tag_t tag, bus_space_handle_t, bus_size_t, u_int16_t);
+static void _pci_io_bs_w_4(bus_space_tag_t tag, bus_space_handle_t, bus_size_t, u_int32_t);
+
+#ifdef __ARMEB__
+static u_int8_t  _pci_io_bs_r_1_s(bus_space_tag_t tag, bus_space_handle_t, bus_size_t);
+static u_int16_t _pci_io_bs_r_2_s(bus_space_tag_t tag, bus_space_handle_t, bus_size_t);
+static u_int32_t _pci_io_bs_r_4_s(bus_space_tag_t tag, bus_space_handle_t, bus_size_t);
+
+static void _pci_io_bs_w_1_s(bus_space_tag_t tag, bus_space_handle_t, bus_size_t, u_int8_t);
+static void _pci_io_bs_w_2_s(bus_space_tag_t tag, bus_space_handle_t, bus_size_t, u_int16_t);
+static void _pci_io_bs_w_4_s(bus_space_tag_t tag, bus_space_handle_t, bus_size_t, u_int32_t);
+
+static u_int8_t  _pci_mem_bs_r_1(bus_space_tag_t tag, bus_space_handle_t, bus_size_t);
+static u_int16_t _pci_mem_bs_r_2(bus_space_tag_t tag, bus_space_handle_t, bus_size_t);
+static u_int32_t _pci_mem_bs_r_4(bus_space_tag_t tag, bus_space_handle_t, bus_size_t);
+
+static void _pci_mem_bs_w_1(bus_space_tag_t tag, bus_space_handle_t, bus_size_t, u_int8_t);
+static void _pci_mem_bs_w_2(bus_space_tag_t tag, bus_space_handle_t, bus_size_t, u_int16_t);
+static void _pci_mem_bs_w_4(bus_space_tag_t tag, bus_space_handle_t, bus_size_t, u_int32_t);
+#endif
+
+struct bus_space ixp425_pci_io_bs_tag_template = {
+	/* mapping/unmapping */
+	.bs_map		= ixp425_pci_io_bs_map,
+	.bs_unmap	= ixp425_pci_io_bs_unmap,
+	.bs_subregion	= ixp425_pci_bs_subregion,
+
+	.bs_alloc	= ixp425_pci_io_bs_alloc,
+	.bs_free	= ixp425_pci_io_bs_free,
+
+	/* barrier */
+	.bs_barrier	= ixp425_pci_bs_barrier,
+
+	/*
+	 * IXP425 processor does not have PCI I/O windows
+	 */
+	/* read (single) */
+	.bs_r_1		= _pci_io_bs_r_1,
+	.bs_r_2		= _pci_io_bs_r_2,
+	.bs_r_4		= _pci_io_bs_r_4,
+
+	/* write (single) */
+	.bs_w_1		= _pci_io_bs_w_1,
+	.bs_w_2		= _pci_io_bs_w_2,
+	.bs_w_4		= _pci_io_bs_w_4,
+
+#ifdef __ARMEB__
+	.bs_r_1_s	= _pci_io_bs_r_1_s,
+	.bs_r_2_s	= _pci_io_bs_r_2_s,
+	.bs_r_4_s	= _pci_io_bs_r_4_s,
+
+	.bs_w_1_s	= _pci_io_bs_w_1_s,
+	.bs_w_2_s	= _pci_io_bs_w_2_s,
+	.bs_w_4_s	= _pci_io_bs_w_4_s,
+#else
+	.bs_r_1_s	= _pci_io_bs_r_1,
+	.bs_r_2_s	= _pci_io_bs_r_2,
+	.bs_r_4_s	= _pci_io_bs_r_4,
+
+	.bs_w_1_s	= _pci_io_bs_w_1,
+	.bs_w_2_s	= _pci_io_bs_w_2,
+	.bs_w_4_s	= _pci_io_bs_w_4,
+#endif
+};
+
+void
+ixp425_io_bs_init(bus_space_tag_t bs, void *cookie)
+{
+	*bs = ixp425_pci_io_bs_tag_template;
+	bs->bs_privdata = cookie;
+}
+
+struct bus_space ixp425_pci_mem_bs_tag_template = {
+	/* mapping/unmapping */
+	.bs_map		= ixp425_pci_mem_bs_map,
+	.bs_unmap	= ixp425_pci_mem_bs_unmap,
+	.bs_subregion	= ixp425_pci_bs_subregion,
+
+	.bs_alloc	= ixp425_pci_mem_bs_alloc,
+	.bs_free	= ixp425_pci_mem_bs_free,
+
+	/* barrier */
+	.bs_barrier	= ixp425_pci_bs_barrier,
+
+#ifdef __ARMEB__
+	/* read (single) */
+	.bs_r_1_s	= _pci_mem_bs_r_1,
+	.bs_r_2_s	= _pci_mem_bs_r_2,
+	.bs_r_4_s	= _pci_mem_bs_r_4,
+
+	.bs_r_1	= 	ixp425_pci_mem_bs_r_1,
+	.bs_r_2	= 	ixp425_pci_mem_bs_r_2,
+	.bs_r_4	= 	ixp425_pci_mem_bs_r_4,
+
+	/* write (single) */
+	.bs_w_1_s	= _pci_mem_bs_w_1,
+	.bs_w_2_s	= _pci_mem_bs_w_2,
+	.bs_w_4_s	= _pci_mem_bs_w_4,
+
+	.bs_w_1	=	 ixp425_pci_mem_bs_w_1,
+	.bs_w_2	= 	ixp425_pci_mem_bs_w_2,
+	.bs_w_4	= 	ixp425_pci_mem_bs_w_4,
+#else
+	/* read (single) */
+	.bs_r_1		= ixp425_pci_mem_bs_r_1,
+	.bs_r_2		= ixp425_pci_mem_bs_r_2,
+	.bs_r_4		= ixp425_pci_mem_bs_r_4,
+	.bs_r_1_s	= ixp425_pci_mem_bs_r_1,
+	.bs_r_2_s	= ixp425_pci_mem_bs_r_2,
+	.bs_r_4_s	= ixp425_pci_mem_bs_r_4,
+
+	/* write (single) */
+	.bs_w_1		= ixp425_pci_mem_bs_w_1,
+	.bs_w_2		= ixp425_pci_mem_bs_w_2,
+	.bs_w_4		= ixp425_pci_mem_bs_w_4,
+	.bs_w_1_s	= ixp425_pci_mem_bs_w_1,
+	.bs_w_2_s	= ixp425_pci_mem_bs_w_2,
+	.bs_w_4_s	= ixp425_pci_mem_bs_w_4,
+#endif
+};
+
+void
+ixp425_mem_bs_init(bus_space_tag_t bs, void *cookie)
+{
+	*bs = ixp425_pci_mem_bs_tag_template;
+	bs->bs_privdata = cookie;
+}
+
+/* common routine */
+int
+ixp425_pci_bs_subregion(bus_space_tag_t tag, bus_space_handle_t bsh, bus_size_t offset,
+	bus_size_t size, bus_space_handle_t *nbshp)
+{
+	*nbshp = bsh + offset;
+	return (0);
+}
+
+void
+ixp425_pci_bs_barrier(bus_space_tag_t tag, bus_space_handle_t bsh, bus_size_t offset,
+    bus_size_t len, int flags)
+{
+	/* NULL */
+}	
+
+/* io bs */
+int
+ixp425_pci_io_bs_map(bus_space_tag_t tag, bus_addr_t bpa, bus_size_t size,
+	int cacheable, bus_space_handle_t *bshp)
+{
+	*bshp = bpa;
+	return (0);
+}
+
+void
+ixp425_pci_io_bs_unmap(bus_space_tag_t tag, bus_space_handle_t h, bus_size_t size)
+{
+	/* Nothing to do. */
+}
+
+int
+ixp425_pci_io_bs_alloc(bus_space_tag_t tag, bus_addr_t rstart, bus_addr_t rend,
+	bus_size_t size, bus_size_t alignment, bus_size_t boundary, int cacheable,
+	bus_addr_t *bpap, bus_space_handle_t *bshp)
+{
+	panic("ixp425_pci_io_bs_alloc(): not implemented\n");
+}
+
+void
+ixp425_pci_io_bs_free(bus_space_tag_t tag, bus_space_handle_t bsh, bus_size_t size)
+{
+	panic("ixp425_pci_io_bs_free(): not implemented\n");
+}
+
+/* special I/O functions */
+static __inline u_int32_t
+_bs_r(bus_space_tag_t tag, bus_space_handle_t ioh, bus_size_t off, u_int32_t be)
+{
+	u_int32_t data;
+
+	CSR_WRITE_4(PCI_NP_AD, (ioh + off) & ~3);
+	CSR_WRITE_4(PCI_NP_CBE, be | COMMAND_NP_IO_READ);
+	data = CSR_READ_4(PCI_NP_RDATA);
+	if (CSR_READ_4(PCI_ISR) & ISR_PFE)
+		CSR_WRITE_4(PCI_ISR, ISR_PFE);
+
+	return data;
+}
+
+static u_int8_t
+_pci_io_bs_r_1(bus_space_tag_t tag, bus_space_handle_t ioh, bus_size_t off)
+{
+	u_int32_t data, n, be;
+
+	n = (ioh + off) % 4;
+	be = (0xf & ~(1U << n)) << NP_CBE_SHIFT;
+	data = _bs_r(tag, ioh, off, be);
+
+	return data >> (8 * n);
+}
+
+static u_int16_t
+_pci_io_bs_r_2(bus_space_tag_t tag, bus_space_handle_t ioh, bus_size_t off)
+{
+	u_int32_t data, n, be;
+
+	n = (ioh + off) % 4;
+	be = (0xf & ~((1U << n) | (1U << (n + 1)))) << NP_CBE_SHIFT;
+	data = _bs_r(tag, ioh, off, be);
+
+	return data >> (8 * n);
+}
+
+static u_int32_t
+_pci_io_bs_r_4(bus_space_tag_t tag, bus_space_handle_t ioh, bus_size_t off)
+{
+	u_int32_t data;
+
+	data = _bs_r(tag, ioh, off, 0);
+	return data;
+}
+
+#ifdef __ARMEB__
+static u_int8_t
+_pci_io_bs_r_1_s(bus_space_tag_t tag, bus_space_handle_t ioh, bus_size_t off)
+{
+	u_int32_t data, n, be;
+
+	n = (ioh + off) % 4;
+	be = (0xf & ~(1U << n)) << NP_CBE_SHIFT;
+	data = _bs_r(tag, ioh, off, be);
+
+	return data >> (8 * n);
+}
+
+static u_int16_t
+_pci_io_bs_r_2_s(bus_space_tag_t tag, bus_space_handle_t ioh, bus_size_t off)
+{
+	u_int32_t data, n, be;
+
+	n = (ioh + off) % 4;
+	be = (0xf & ~((1U << n) | (1U << (n + 1)))) << NP_CBE_SHIFT;
+	data = _bs_r(tag, ioh, off, be);
+
+	return data >> (8 * n);
+}
+
+static u_int32_t
+_pci_io_bs_r_4_s(bus_space_tag_t tag, bus_space_handle_t ioh, bus_size_t off)
+{
+	u_int32_t data;
+
+	data = _bs_r(tag, ioh, off, 0);
+	return le32toh(data);
+}
+#endif /* __ARMEB__ */
+
+static __inline void
+_bs_w(bus_space_tag_t tag, bus_space_handle_t ioh, bus_size_t off,
+	u_int32_t be, u_int32_t data)
+{
+	CSR_WRITE_4(PCI_NP_AD, (ioh + off) & ~3);
+	CSR_WRITE_4(PCI_NP_CBE, be | COMMAND_NP_IO_WRITE);
+	CSR_WRITE_4(PCI_NP_WDATA, data);
+	if (CSR_READ_4(PCI_ISR) & ISR_PFE)
+		CSR_WRITE_4(PCI_ISR, ISR_PFE);
+}
+
+static void
+_pci_io_bs_w_1(bus_space_tag_t tag, bus_space_handle_t ioh, bus_size_t off,
+	u_int8_t val)
+{
+	u_int32_t data, n, be;
+
+	n = (ioh + off) % 4;
+	be = (0xf & ~(1U << n)) << NP_CBE_SHIFT;
+	data = val << (8 * n);
+	_bs_w(tag, ioh, off, be, data);
+}
+
+static void
+_pci_io_bs_w_2(bus_space_tag_t tag, bus_space_handle_t ioh, bus_size_t off,
+	u_int16_t val)
+{
+	u_int32_t data, n, be;
+
+	n = (ioh + off) % 4;
+	be = (0xf & ~((1U << n) | (1U << (n + 1)))) << NP_CBE_SHIFT;
+	data = val << (8 * n);
+	_bs_w(tag, ioh, off, be, data);
+}
+
+static void
+_pci_io_bs_w_4(bus_space_tag_t tag, bus_space_handle_t ioh, bus_size_t off,
+	u_int32_t val)
+{
+	_bs_w(tag, ioh, off, 0, val);
+}
+
+#ifdef __ARMEB__
+static void
+_pci_io_bs_w_1_s(bus_space_tag_t tag, bus_space_handle_t ioh, bus_size_t off,
+	u_int8_t val)
+{
+	u_int32_t data, n, be;
+
+	n = (ioh + off) % 4;
+	be = (0xf & ~(1U << n)) << NP_CBE_SHIFT;
+	data = val << (8 * n);
+	_bs_w(tag, ioh, off, be, data);
+}
+
+static void
+_pci_io_bs_w_2_s(bus_space_tag_t tag, bus_space_handle_t ioh, bus_size_t off,
+	u_int16_t val)
+{
+	u_int32_t data, n, be;
+
+	n = (ioh + off) % 4;
+	be = (0xf & ~((1U << n) | (1U << (n + 1)))) << NP_CBE_SHIFT;
+	data = val << (8 * n);
+	_bs_w(tag, ioh, off, be, data);
+}
+
+static void
+_pci_io_bs_w_4_s(bus_space_tag_t tag, bus_space_handle_t ioh, bus_size_t off,
+	u_int32_t val)
+{
+	_bs_w(tag, ioh, off, 0, htole32(val));
+}
+#endif /* __ARMEB__ */
+
+/* mem bs */
+int
+ixp425_pci_mem_bs_map(bus_space_tag_t tag, bus_addr_t bpa, bus_size_t size,
+	      int cacheable, bus_space_handle_t *bshp)
+{
+	*bshp = (vm_offset_t)pmap_mapdev(bpa, size);
+	return (0);
+}
+
+void
+ixp425_pci_mem_bs_unmap(bus_space_tag_t tag, bus_space_handle_t h, bus_size_t size)
+{
+
+	pmap_unmapdev((vm_offset_t)h, size);
+}
+
+int
+ixp425_pci_mem_bs_alloc(bus_space_tag_t tag, bus_addr_t rstart, bus_addr_t rend,
+	bus_size_t size, bus_size_t alignment, bus_size_t boundary, int cacheable,
+	bus_addr_t *bpap, bus_space_handle_t *bshp)
+{
+	panic("ixp425_mem_bs_alloc(): not implemented\n");
+}
+
+void
+ixp425_pci_mem_bs_free(bus_space_tag_t tag, bus_space_handle_t bsh, bus_size_t size)
+{
+	panic("ixp425_mem_bs_free(): not implemented\n");
+}
+
+#ifdef __ARMEB__
+static u_int8_t
+_pci_mem_bs_r_1(bus_space_tag_t tag, bus_space_handle_t ioh, bus_size_t off)
+{
+	return ixp425_pci_mem_bs_r_1(tag, ioh, off);
+}
+
+static u_int16_t
+_pci_mem_bs_r_2(bus_space_tag_t tag, bus_space_handle_t ioh, bus_size_t off)
+{
+	return (ixp425_pci_mem_bs_r_2(tag, ioh, off));
+}
+
+static u_int32_t
+_pci_mem_bs_r_4(bus_space_tag_t tag, bus_space_handle_t ioh, bus_size_t off)
+{
+	u_int32_t data;
+
+	data = ixp425_pci_mem_bs_r_4(tag, ioh, off);
+	return (le32toh(data));
+}
+
+static void
+_pci_mem_bs_w_1(bus_space_tag_t tag, bus_space_handle_t ioh, bus_size_t off,
+	u_int8_t val)
+{
+	ixp425_pci_mem_bs_w_1(tag, ioh, off, val);
+}
+
+static void
+_pci_mem_bs_w_2(bus_space_tag_t tag, bus_space_handle_t ioh, bus_size_t off,
+	u_int16_t val)
+{
+	ixp425_pci_mem_bs_w_2(tag, ioh, off, val);
+}
+
+static void
+_pci_mem_bs_w_4(bus_space_tag_t tag, bus_space_handle_t ioh, bus_size_t off,
+	u_int32_t val)
+{
+	ixp425_pci_mem_bs_w_4(tag, ioh, off, htole32(val));
+}
+#endif /* __ARMEB__ */
+
+/* End of ixp425_pci_space.c */


Property changes on: trunk/sys/arm/xscale/ixp425/ixp425_pci_space.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/ixp425/ixp425_qmgr.c
===================================================================
--- trunk/sys/arm/xscale/ixp425/ixp425_qmgr.c	                        (rev 0)
+++ trunk/sys/arm/xscale/ixp425/ixp425_qmgr.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,1106 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2006 Sam Leffler, Errno Consulting
+ * 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,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ *    redistribution must be conditioned upon including a substantially
+ *    similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
+ */
+
+/*-
+ * Copyright (c) 2001-2005, Intel Corporation.
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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: stable/10/sys/arm/xscale/ixp425/ixp425_qmgr.c 236987 2012-06-13 04:38:09Z imp $");
+
+/*
+ * Intel XScale Queue Manager support.
+ *
+ * Each IXP4XXX device has a hardware block that implements a priority
+ * queue manager that is shared between the XScale cpu and the backend
+ * devices (such as the NPE).  Queues are accessed by reading/writing
+ * special memory locations.  The queue contents are mapped into a shared
+ * SRAM region with entries managed in a circular buffer.  The XScale
+ * processor can receive interrupts based on queue contents (a condition
+ * code determines when interrupts should be delivered).
+ *
+ * The code here basically replaces the qmgr class in the Intel Access
+ * Library (IAL).
+ */
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/time.h>
+#include <sys/bus.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+#include <sys/sysctl.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+#include <machine/resource.h>
+#include <machine/intr.h>
+#include <arm/xscale/ixp425/ixp425reg.h>
+#include <arm/xscale/ixp425/ixp425var.h>
+
+#include <arm/xscale/ixp425/ixp425_qmgr.h>
+
+/*
+ * State per AQM hw queue.
+ * This structure holds q configuration and dispatch state.
+ */
+struct qmgrInfo {
+	int		qSizeInWords;		/* queue size in words */
+
+	uint32_t	qOflowStatBitMask;	/* overflow status mask */
+	int		qWriteCount;		/* queue write count */
+
+	bus_size_t	qAccRegAddr;		/* access register */
+	bus_size_t	qUOStatRegAddr;		/* status register */
+	bus_size_t	qConfigRegAddr;		/* config register */
+	int		qSizeInEntries;		/* queue size in entries */
+
+	uint32_t	qUflowStatBitMask;	/* underflow status mask */
+	int		qReadCount;		/* queue read count */
+
+	/* XXX union */
+	uint32_t	qStatRegAddr;
+	uint32_t	qStatBitsOffset;
+	uint32_t	qStat0BitMask;
+	uint32_t	qStat1BitMask;
+
+	uint32_t	intRegCheckMask;	/* interrupt reg check mask */
+	void		(*cb)(int, void *);	/* callback function */
+	void		*cbarg;			/* callback argument */
+	int 		priority;		/* dispatch priority */
+#if 0
+	/* NB: needed only for A0 parts */
+	u_int		statusWordOffset;	/* status word offset */
+	uint32_t	statusMask;             /* status mask */
+	uint32_t	statusCheckValue;	/* status check value */
+#endif
+};
+
+struct ixpqmgr_softc {
+	device_t		sc_dev;
+	bus_space_tag_t		sc_iot;
+	bus_space_handle_t	sc_ioh;
+
+	struct resource		*sc_irq1;	/* IRQ resource */
+	void			*sc_ih1;	/* interrupt handler */
+	int			sc_rid1;	/* resource id for irq */
+
+	struct resource		*sc_irq2;
+	void			*sc_ih2;
+	int			sc_rid2;
+
+	struct qmgrInfo		qinfo[IX_QMGR_MAX_NUM_QUEUES];
+	/*
+	 * This array contains a list of queue identifiers ordered by
+	 * priority. The table is split logically between queue
+	 * identifiers 0-31 and 32-63.  To optimize lookups bit masks
+	 * are kept for the first-32 and last-32 q's.  When the
+	 * table needs to be rebuilt mark rebuildTable and it'll
+	 * happen after the next interrupt.
+	 */
+	int			priorityTable[IX_QMGR_MAX_NUM_QUEUES];
+	uint32_t		lowPriorityTableFirstHalfMask;
+	uint32_t		uppPriorityTableFirstHalfMask;
+	int			rebuildTable;	/* rebuild priorityTable */
+
+	uint32_t		aqmFreeSramAddress;	/* SRAM free space */
+};
+
+static int qmgr_debug = 0;
+SYSCTL_INT(_debug, OID_AUTO, qmgr, CTLFLAG_RW, &qmgr_debug,
+	   0, "IXP4XX Q-Manager debug msgs");
+TUNABLE_INT("debug.qmgr", &qmgr_debug);
+#define	DPRINTF(dev, fmt, ...) do {					\
+	if (qmgr_debug) printf(fmt, __VA_ARGS__);			\
+} while (0)
+#define	DPRINTFn(n, dev, fmt, ...) do {					\
+	if (qmgr_debug >= n) printf(fmt, __VA_ARGS__);			\
+} while (0)
+
+static struct ixpqmgr_softc *ixpqmgr_sc = NULL;
+
+static void ixpqmgr_rebuild(struct ixpqmgr_softc *);
+static void ixpqmgr_intr(void *);
+
+static void aqm_int_enable(struct ixpqmgr_softc *sc, int qId);
+static void aqm_int_disable(struct ixpqmgr_softc *sc, int qId);
+static void aqm_qcfg(struct ixpqmgr_softc *sc, int qId, u_int ne, u_int nf);
+static void aqm_srcsel_write(struct ixpqmgr_softc *sc, int qId, int sourceId);
+static void aqm_reset(struct ixpqmgr_softc *sc);
+
+static void
+dummyCallback(int qId, void *arg)
+{
+	/* XXX complain */
+}
+
+static uint32_t
+aqm_reg_read(struct ixpqmgr_softc *sc, bus_size_t off)
+{
+	DPRINTFn(9, sc->sc_dev, "%s(0x%x)\n", __func__, (int)off);
+	return bus_space_read_4(sc->sc_iot, sc->sc_ioh, off);
+}
+
+static void
+aqm_reg_write(struct ixpqmgr_softc *sc, bus_size_t off, uint32_t val)
+{
+	DPRINTFn(9, sc->sc_dev, "%s(0x%x, 0x%x)\n", __func__, (int)off, val);
+	bus_space_write_4(sc->sc_iot, sc->sc_ioh, off, val);
+}
+
+static int
+ixpqmgr_probe(device_t dev)
+{
+	device_set_desc(dev, "IXP4XX Q-Manager");
+	return 0;
+}
+
+static int
+ixpqmgr_attach(device_t dev)
+{
+	struct ixpqmgr_softc *sc = device_get_softc(dev);
+	struct ixp425_softc *sa = device_get_softc(device_get_parent(dev));
+	int i, err;
+
+	ixpqmgr_sc = sc;
+
+	sc->sc_dev = dev;
+	sc->sc_iot = sa->sc_iot;
+	if (bus_space_map(sc->sc_iot, IXP425_QMGR_HWBASE, IXP425_QMGR_SIZE,
+	    0, &sc->sc_ioh))
+		panic("%s: Cannot map registers", device_get_name(dev));
+
+	/* NB: we only use the lower 32 q's */
+
+	/* Set up QMGR interrupts */
+	sc->sc_rid1 = 0;
+	sc->sc_irq1 = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->sc_rid1,
+	    IXP425_INT_QUE1_32, IXP425_INT_QUE1_32, 1, RF_ACTIVE);
+	sc->sc_rid2 = 1;
+	sc->sc_irq2 = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->sc_rid2,
+	    IXP425_INT_QUE33_64, IXP425_INT_QUE33_64, 1, RF_ACTIVE);
+
+	if (sc->sc_irq1 == NULL || sc->sc_irq2 == NULL)
+		panic("Unable to allocate the qmgr irqs.\n");
+
+	err = bus_setup_intr(dev, sc->sc_irq1, INTR_TYPE_NET | INTR_MPSAFE,
+	    NULL, ixpqmgr_intr, NULL, &sc->sc_ih1);
+	if (err) {
+		device_printf(dev, "failed to set up qmgr irq=%d\n",
+		   IXP425_INT_QUE1_32);
+		return (ENXIO);
+	}
+	err = bus_setup_intr(dev, sc->sc_irq2, INTR_TYPE_NET | INTR_MPSAFE,
+	    NULL, ixpqmgr_intr, NULL, &sc->sc_ih2);
+	if (err) {
+		device_printf(dev, "failed to set up qmgr irq=%d\n",
+		   IXP425_INT_QUE33_64);
+		return (ENXIO);
+	}
+
+	/* NB: softc is pre-zero'd */
+	for (i = 0; i < IX_QMGR_MAX_NUM_QUEUES; i++) {
+	    struct qmgrInfo *qi = &sc->qinfo[i];
+
+	    qi->cb = dummyCallback;
+	    qi->priority = IX_QMGR_Q_PRIORITY_0;	/* default priority */
+	    /*
+	     * There are two interrupt registers, 32 bits each. One
+	     * for the lower queues(0-31) and one for the upper
+	     * queues(32-63). Therefore need to mod by 32 i.e the
+	     * min upper queue identifier.
+	     */
+	    qi->intRegCheckMask = (1<<(i%(IX_QMGR_MIN_QUEUPP_QID)));
+
+	    /*
+	     * Register addresses and bit masks are calculated and
+	     * stored here to optimize QRead, QWrite and QStatusGet
+	     * functions.
+	     */
+
+	    /* AQM Queue access reg addresses, per queue */
+	    qi->qAccRegAddr = IX_QMGR_Q_ACCESS_ADDR_GET(i);
+	    qi->qAccRegAddr = IX_QMGR_Q_ACCESS_ADDR_GET(i);
+	    qi->qConfigRegAddr = IX_QMGR_Q_CONFIG_ADDR_GET(i);
+
+	    /* AQM Queue lower-group (0-31), only */
+	    if (i < IX_QMGR_MIN_QUEUPP_QID) {
+		/* AQM Q underflow/overflow status reg address, per queue */
+		qi->qUOStatRegAddr = IX_QMGR_QUEUOSTAT0_OFFSET +
+		    ((i / IX_QMGR_QUEUOSTAT_NUM_QUE_PER_WORD) *
+		     sizeof(uint32_t));
+
+		/* AQM Q underflow status bit masks for status reg per queue */
+		qi->qUflowStatBitMask =
+		    (IX_QMGR_UNDERFLOW_BIT_OFFSET + 1) <<
+		    ((i & (IX_QMGR_QUEUOSTAT_NUM_QUE_PER_WORD - 1)) *
+		     (32 / IX_QMGR_QUEUOSTAT_NUM_QUE_PER_WORD));
+
+		/* AQM Q overflow status bit masks for status reg, per queue */
+		qi->qOflowStatBitMask =
+		    (IX_QMGR_OVERFLOW_BIT_OFFSET + 1) <<
+		    ((i & (IX_QMGR_QUEUOSTAT_NUM_QUE_PER_WORD - 1)) *
+		     (32 / IX_QMGR_QUEUOSTAT_NUM_QUE_PER_WORD));
+
+		/* AQM Q lower-group (0-31) status reg addresses, per queue */
+		qi->qStatRegAddr = IX_QMGR_QUELOWSTAT0_OFFSET +
+		    ((i / IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD) *
+		     sizeof(uint32_t));
+
+		/* AQM Q lower-group (0-31) status register bit offset */
+		qi->qStatBitsOffset =
+		    (i & (IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD - 1)) *
+		    (32 / IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD);
+	    } else { /* AQM Q upper-group (32-63), only */
+		qi->qUOStatRegAddr = 0;		/* XXX */
+
+		/* AQM Q upper-group (32-63) Nearly Empty status reg bitmasks */
+		qi->qStat0BitMask = (1 << (i - IX_QMGR_MIN_QUEUPP_QID));
+
+		/* AQM Q upper-group (32-63) Full status register bitmasks */
+		qi->qStat1BitMask = (1 << (i - IX_QMGR_MIN_QUEUPP_QID));
+	    }
+	}
+	
+	sc->aqmFreeSramAddress = 0x100;	/* Q buffer space starts at 0x2100 */
+
+	ixpqmgr_rebuild(sc);		/* build initial priority table */
+	aqm_reset(sc);			/* reset h/w */
+	return (0);
+}
+
+static int
+ixpqmgr_detach(device_t dev)
+{
+	struct ixpqmgr_softc *sc = device_get_softc(dev);
+
+	aqm_reset(sc);		/* disable interrupts */
+	bus_teardown_intr(dev, sc->sc_irq1, sc->sc_ih1);
+	bus_teardown_intr(dev, sc->sc_irq2, sc->sc_ih2);
+	bus_release_resource(dev, SYS_RES_IRQ, sc->sc_rid1, sc->sc_irq1);
+	bus_release_resource(dev, SYS_RES_IRQ, sc->sc_rid2, sc->sc_irq2);
+	bus_space_unmap(sc->sc_iot, sc->sc_ioh, IXP425_QMGR_SIZE);
+	return (0);
+}
+
+int
+ixpqmgr_qconfig(int qId, int qEntries, int ne, int nf, int srcSel,
+    qconfig_hand_t *cb, void *cbarg)
+{
+	struct ixpqmgr_softc *sc = ixpqmgr_sc;
+	struct qmgrInfo *qi = &sc->qinfo[qId];
+
+	DPRINTF(sc->sc_dev, "%s(%u, %u, %u, %u, %u, %p, %p)\n",
+	    __func__, qId, qEntries, ne, nf, srcSel, cb, cbarg);
+
+	/* NB: entry size is always 1 */
+	qi->qSizeInWords = qEntries;
+
+	qi->qReadCount = 0;
+	qi->qWriteCount = 0;
+	qi->qSizeInEntries = qEntries;	/* XXX kept for code clarity */
+
+	if (cb == NULL) {
+	    /* Reset to dummy callback */
+	    qi->cb = dummyCallback;
+	    qi->cbarg = 0;
+	} else {
+	    qi->cb = cb;
+	    qi->cbarg = cbarg;
+	}
+
+	/* Write the config register; NB must be AFTER qinfo setup */
+	aqm_qcfg(sc, qId, ne, nf);
+	/*
+	 * Account for space just allocated to queue.
+	 */
+	sc->aqmFreeSramAddress += (qi->qSizeInWords * sizeof(uint32_t));
+
+	/* Set the interrupt source if this queue is in the range 0-31 */
+	if (qId < IX_QMGR_MIN_QUEUPP_QID)
+	    aqm_srcsel_write(sc, qId, srcSel);
+
+	if (cb != NULL)				/* Enable the interrupt */
+	    aqm_int_enable(sc, qId);
+
+	sc->rebuildTable = TRUE;
+
+	return 0;		/* XXX */
+}
+
+int
+ixpqmgr_qwrite(int qId, uint32_t entry)
+{
+	struct ixpqmgr_softc *sc = ixpqmgr_sc;
+	struct qmgrInfo *qi = &sc->qinfo[qId];
+
+	DPRINTFn(3, sc->sc_dev, "%s(%u, 0x%x) writeCount %u size %u\n",
+	    __func__, qId, entry, qi->qWriteCount, qi->qSizeInEntries);
+
+	/* write the entry */
+	aqm_reg_write(sc, qi->qAccRegAddr, entry);
+
+	/* NB: overflow is available for lower queues only */
+	if (qId < IX_QMGR_MIN_QUEUPP_QID) {
+	    int qSize = qi->qSizeInEntries;
+	    /*
+	     * Increment the current number of entries in the queue
+	     * and check for overflow .
+	     */
+	    if (qi->qWriteCount++ == qSize) {	/* check for overflow */
+		uint32_t status = aqm_reg_read(sc, qi->qUOStatRegAddr);
+		int qPtrs;
+
+		/*
+		 * Read the status twice because the status may
+		 * not be immediately ready after the write operation
+		 */
+		if ((status & qi->qOflowStatBitMask) ||
+		    ((status = aqm_reg_read(sc, qi->qUOStatRegAddr)) & qi->qOflowStatBitMask)) {
+		    /*
+		     * The queue is full, clear the overflow status bit if set.
+		     */
+		    aqm_reg_write(sc, qi->qUOStatRegAddr,
+			status & ~qi->qOflowStatBitMask);
+		    qi->qWriteCount = qSize;
+		    DPRINTFn(5, sc->sc_dev,
+			"%s(%u, 0x%x) Q full, overflow status cleared\n",
+			__func__, qId, entry);
+		    return ENOSPC;
+		}
+		/*
+		 * No overflow occured : someone is draining the queue
+		 * and the current counter needs to be
+		 * updated from the current number of entries in the queue
+		 */
+
+		/* calculate number of words in q */
+		qPtrs = aqm_reg_read(sc, qi->qConfigRegAddr);
+		DPRINTFn(2, sc->sc_dev,
+		    "%s(%u, 0x%x) Q full, no overflow status, qConfig 0x%x\n",
+		    __func__, qId, entry, qPtrs);
+		qPtrs = (qPtrs - (qPtrs >> 7)) & 0x7f;
+
+		if (qPtrs == 0) {
+		    /*
+		     * The queue may be full at the time of the
+		     * snapshot. Next access will check
+		     * the overflow status again.
+		     */
+		    qi->qWriteCount = qSize;
+		} else {
+		    /* convert the number of words to a number of entries */
+		    qi->qWriteCount = qPtrs & (qSize - 1);
+		}
+	    }
+	}
+	return 0;
+}
+
+int
+ixpqmgr_qread(int qId, uint32_t *entry)
+{
+	struct ixpqmgr_softc *sc = ixpqmgr_sc;
+	struct qmgrInfo *qi = &sc->qinfo[qId];
+	bus_size_t off = qi->qAccRegAddr;
+
+	*entry = aqm_reg_read(sc, off);
+
+	/*
+	 * Reset the current read count : next access to the read function
+	 * will force a underflow status check.
+	 */
+	qi->qReadCount = 0;
+
+	/* Check if underflow occurred on the read */
+	if (*entry == 0 && qId < IX_QMGR_MIN_QUEUPP_QID) {
+	    /* get the queue status */
+	    uint32_t status = aqm_reg_read(sc, qi->qUOStatRegAddr);
+
+	    if (status & qi->qUflowStatBitMask) { /* clear underflow status */
+		aqm_reg_write(sc, qi->qUOStatRegAddr,
+		    status &~ qi->qUflowStatBitMask);
+		return ENOSPC;
+	    }
+	}
+	return 0;
+}
+
+int
+ixpqmgr_qreadm(int qId, uint32_t n, uint32_t *p)
+{
+	struct ixpqmgr_softc *sc = ixpqmgr_sc;
+	struct qmgrInfo *qi = &sc->qinfo[qId];
+	uint32_t entry;
+	bus_size_t off = qi->qAccRegAddr;
+
+	entry = aqm_reg_read(sc, off);
+	while (--n) {
+	    if (entry == 0) {
+		/* if we read a NULL entry, stop. We have underflowed */
+		break;
+	    }
+	    *p++ = entry;	/* store */
+	    entry = aqm_reg_read(sc, off);
+	}
+	*p = entry;
+
+	/*
+	 * Reset the current read count : next access to the read function
+	 * will force a underflow status check.
+	 */
+	qi->qReadCount = 0;
+
+	/* Check if underflow occurred on the read */
+	if (entry == 0 && qId < IX_QMGR_MIN_QUEUPP_QID) {
+	    /* get the queue status */
+	    uint32_t status = aqm_reg_read(sc, qi->qUOStatRegAddr);
+
+	    if (status & qi->qUflowStatBitMask) { /* clear underflow status */
+		aqm_reg_write(sc, qi->qUOStatRegAddr,
+		    status &~ qi->qUflowStatBitMask);
+		return ENOSPC;
+	    }
+	}
+	return 0;
+}
+
+uint32_t
+ixpqmgr_getqstatus(int qId)
+{
+#define	QLOWSTATMASK \
+    ((1 << (32 / IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD)) - 1)
+	struct ixpqmgr_softc *sc = ixpqmgr_sc;
+	const struct qmgrInfo *qi = &sc->qinfo[qId];
+	uint32_t status;
+
+	if (qId < IX_QMGR_MIN_QUEUPP_QID) {
+	    /* read the status of a queue in the range 0-31 */
+	    status = aqm_reg_read(sc, qi->qStatRegAddr);
+
+	    /* mask out the status bits relevant only to this queue */
+	    status = (status >> qi->qStatBitsOffset) & QLOWSTATMASK;
+	} else { /* read status of a queue in the range 32-63 */
+	    status = 0;
+	    if (aqm_reg_read(sc, IX_QMGR_QUEUPPSTAT0_OFFSET)&qi->qStat0BitMask)
+		status |= IX_QMGR_Q_STATUS_NE_BIT_MASK;	/* nearly empty */
+	    if (aqm_reg_read(sc, IX_QMGR_QUEUPPSTAT1_OFFSET)&qi->qStat1BitMask)
+		status |= IX_QMGR_Q_STATUS_F_BIT_MASK;	/* full */
+	}
+	return status;
+#undef QLOWSTATMASK
+}
+
+uint32_t
+ixpqmgr_getqconfig(int qId)
+{
+	struct ixpqmgr_softc *sc = ixpqmgr_sc;
+
+	return aqm_reg_read(sc, IX_QMGR_Q_CONFIG_ADDR_GET(qId));
+}
+
+void
+ixpqmgr_dump(void)
+{
+	struct ixpqmgr_softc *sc = ixpqmgr_sc;
+	int i, a;
+
+	/* status registers */
+	printf("0x%04x: %08x %08x %08x %08x\n"
+		, 0x400
+		, aqm_reg_read(sc, 0x400)
+		, aqm_reg_read(sc, 0x400+4)
+		, aqm_reg_read(sc, 0x400+8)
+		, aqm_reg_read(sc, 0x400+12)
+	);
+	printf("0x%04x: %08x %08x %08x %08x\n"
+		, 0x410
+		, aqm_reg_read(sc, 0x410)
+		, aqm_reg_read(sc, 0x410+4)
+		, aqm_reg_read(sc, 0x410+8)
+		, aqm_reg_read(sc, 0x410+12)
+	);
+	printf("0x%04x: %08x %08x %08x %08x\n"
+		, 0x420
+		, aqm_reg_read(sc, 0x420)
+		, aqm_reg_read(sc, 0x420+4)
+		, aqm_reg_read(sc, 0x420+8)
+		, aqm_reg_read(sc, 0x420+12)
+	);
+	printf("0x%04x: %08x %08x %08x %08x\n"
+		, 0x430
+		, aqm_reg_read(sc, 0x430)
+		, aqm_reg_read(sc, 0x430+4)
+		, aqm_reg_read(sc, 0x430+8)
+		, aqm_reg_read(sc, 0x430+12)
+	);
+	/* q configuration registers */
+	for (a = 0x2000; a < 0x20ff; a += 32)
+		printf("0x%04x: %08x %08x %08x %08x %08x %08x %08x %08x\n"
+			, a
+			, aqm_reg_read(sc, a)
+			, aqm_reg_read(sc, a+4)
+			, aqm_reg_read(sc, a+8)
+			, aqm_reg_read(sc, a+12)
+			, aqm_reg_read(sc, a+16)
+			, aqm_reg_read(sc, a+20)
+			, aqm_reg_read(sc, a+24)
+			, aqm_reg_read(sc, a+28)
+		);
+	/* allocated SRAM */
+	for (i = 0x100; i < sc->aqmFreeSramAddress; i += 32) {
+		a = 0x2000 + i;
+		printf("0x%04x: %08x %08x %08x %08x %08x %08x %08x %08x\n"
+			, a
+			, aqm_reg_read(sc, a)
+			, aqm_reg_read(sc, a+4)
+			, aqm_reg_read(sc, a+8)
+			, aqm_reg_read(sc, a+12)
+			, aqm_reg_read(sc, a+16)
+			, aqm_reg_read(sc, a+20)
+			, aqm_reg_read(sc, a+24)
+			, aqm_reg_read(sc, a+28)
+		);
+	}
+	for (i = 0; i < 16; i++) {
+		printf("Q[%2d] config 0x%08x status 0x%02x  "
+		       "Q[%2d] config 0x%08x status 0x%02x\n"
+		    , i, ixpqmgr_getqconfig(i), ixpqmgr_getqstatus(i)
+		    , i+16, ixpqmgr_getqconfig(i+16), ixpqmgr_getqstatus(i+16)
+		);
+	}
+}
+
+void
+ixpqmgr_notify_enable(int qId, int srcSel)
+{
+	struct ixpqmgr_softc *sc = ixpqmgr_sc;
+#if 0
+	/* Calculate the checkMask and checkValue for this q */
+	aqm_calc_statuscheck(sc, qId, srcSel);
+#endif
+	/* Set the interrupt source if this queue is in the range 0-31 */
+	if (qId < IX_QMGR_MIN_QUEUPP_QID)
+	    aqm_srcsel_write(sc, qId, srcSel);
+
+	/* Enable the interrupt */
+	aqm_int_enable(sc, qId);
+}
+
+void
+ixpqmgr_notify_disable(int qId)
+{
+	struct ixpqmgr_softc *sc = ixpqmgr_sc;
+
+	aqm_int_disable(sc, qId);
+}
+
+/*
+ * Rebuild the priority table used by the dispatcher.
+ */
+static void
+ixpqmgr_rebuild(struct ixpqmgr_softc *sc)
+{
+	int q, pri;
+	int lowQuePriorityTableIndex, uppQuePriorityTableIndex;
+	struct qmgrInfo *qi;
+
+	sc->lowPriorityTableFirstHalfMask = 0;
+	sc->uppPriorityTableFirstHalfMask = 0;
+	
+	lowQuePriorityTableIndex = 0;
+	uppQuePriorityTableIndex = 32;
+	for (pri = 0; pri < IX_QMGR_NUM_PRIORITY_LEVELS; pri++) {
+	    /* low priority q's */
+	    for (q = 0; q < IX_QMGR_MIN_QUEUPP_QID; q++) {
+		qi = &sc->qinfo[q];
+		if (qi->priority == pri) {
+		    /*
+		     * Build the priority table bitmask which match the
+		     * queues of the first half of the priority table.
+		     */
+		    if (lowQuePriorityTableIndex < 16) {
+			sc->lowPriorityTableFirstHalfMask |=
+			    qi->intRegCheckMask;
+		    }
+		    sc->priorityTable[lowQuePriorityTableIndex++] = q;
+		}
+	    }
+	    /* high priority q's */
+	    for (; q < IX_QMGR_MAX_NUM_QUEUES; q++) {
+		qi = &sc->qinfo[q];
+		if (qi->priority == pri) {
+		    /*
+		     * Build the priority table bitmask which match the
+		     * queues of the first half of the priority table .
+		     */
+		    if (uppQuePriorityTableIndex < 48) {
+			sc->uppPriorityTableFirstHalfMask |=
+			    qi->intRegCheckMask;
+		    }
+		    sc->priorityTable[uppQuePriorityTableIndex++] = q;
+		}
+	    }
+	}
+	sc->rebuildTable = FALSE;
+}
+
+/*
+ * Count the number of leading zero bits in a word,
+ * and return the same value than the CLZ instruction.
+ * Note this is similar to the standard ffs function but
+ * it counts zero's from the MSB instead of the LSB.
+ *
+ * word (in)    return value (out)
+ * 0x80000000   0
+ * 0x40000000   1
+ * ,,,          ,,,
+ * 0x00000002   30
+ * 0x00000001   31
+ * 0x00000000   32
+ *
+ * The C version of this function is used as a replacement
+ * for system not providing the equivalent of the CLZ
+ * assembly language instruction.
+ *
+ * Note that this version is big-endian
+ */
+static unsigned int
+_lzcount(uint32_t word)
+{
+	unsigned int lzcount = 0;
+
+	if (word == 0)
+	    return 32;
+	while ((word & 0x80000000) == 0) {
+	    word <<= 1;
+	    lzcount++;
+	}
+	return lzcount;
+}
+
+static void
+ixpqmgr_intr(void *arg)
+{
+	struct ixpqmgr_softc *sc = ixpqmgr_sc;
+	uint32_t intRegVal;                /* Interrupt reg val */
+	struct qmgrInfo *qi;
+	int priorityTableIndex;		/* Priority table index */
+	int qIndex;			/* Current queue being processed */
+
+	/* Read the interrupt register */
+	intRegVal = aqm_reg_read(sc, IX_QMGR_QINTREG0_OFFSET);
+	/* Write back to clear interrupt */
+	aqm_reg_write(sc, IX_QMGR_QINTREG0_OFFSET, intRegVal);
+
+	DPRINTFn(5, sc->sc_dev, "%s: ISR0 0x%x ISR1 0x%x\n",
+	    __func__, intRegVal, aqm_reg_read(sc, IX_QMGR_QINTREG1_OFFSET));
+
+	/* No queue has interrupt register set */
+	if (intRegVal != 0) {
+		/* get the first queue Id from the interrupt register value */
+		qIndex = (32 - 1) - _lzcount(intRegVal);
+
+		DPRINTFn(2, sc->sc_dev, "%s: ISR0 0x%x qIndex %u\n",
+		    __func__, intRegVal, qIndex);
+
+		/*
+		 * Optimize for single callback case.
+		 */
+		 qi = &sc->qinfo[qIndex];
+		 if (intRegVal == qi->intRegCheckMask) {
+		    /*
+		     * Only 1 queue event triggered a notification.
+		     * Call the callback function for this queue
+		     */
+		    qi->cb(qIndex, qi->cbarg);
+		 } else {
+		     /*
+		      * The event is triggered by more than 1 queue,
+		      * the queue search will start from the beginning
+		      * or the middle of the priority table.
+		      *
+		      * The search will end when all the bits of the interrupt
+		      * register are cleared. There is no need to maintain
+		      * a separate value and test it at each iteration.
+		      */
+		     if (intRegVal & sc->lowPriorityTableFirstHalfMask) {
+			 priorityTableIndex = 0;
+		     } else {
+			 priorityTableIndex = 16;
+		     }
+		     /*
+		      * Iterate over the priority table until all the bits
+		      * of the interrupt register are cleared.
+		      */
+		     do {
+			 qIndex = sc->priorityTable[priorityTableIndex++];
+			 qi = &sc->qinfo[qIndex];
+
+			 /* If this queue caused this interrupt to be raised */
+			 if (intRegVal & qi->intRegCheckMask) {
+			     /* Call the callback function for this queue */
+			     qi->cb(qIndex, qi->cbarg);
+			     /* Clear the interrupt register bit */
+			     intRegVal &= ~qi->intRegCheckMask;
+			 }
+		      } while (intRegVal);
+		 }
+	 }
+
+	/* Rebuild the priority table if needed */
+	if (sc->rebuildTable)
+	    ixpqmgr_rebuild(sc);
+}
+
+#if 0
+/*
+ * Generate the parameters used to check if a Q's status matches
+ * the specified source select.  We calculate which status word
+ * to check (statusWordOffset), the value to check the status
+ * against (statusCheckValue) and the mask (statusMask) to mask
+ * out all but the bits to check in the status word.
+ */
+static void
+aqm_calc_statuscheck(int qId, IxQMgrSourceId srcSel)
+{
+	struct qmgrInfo *qi = &qinfo[qId];
+	uint32_t shiftVal;
+
+	if (qId < IX_QMGR_MIN_QUEUPP_QID) {
+	    switch (srcSel) {
+	    case IX_QMGR_Q_SOURCE_ID_E:
+		qi->statusCheckValue = IX_QMGR_Q_STATUS_E_BIT_MASK;
+		qi->statusMask = IX_QMGR_Q_STATUS_E_BIT_MASK;
+		break;
+	    case IX_QMGR_Q_SOURCE_ID_NE:
+		qi->statusCheckValue = IX_QMGR_Q_STATUS_NE_BIT_MASK;
+		qi->statusMask = IX_QMGR_Q_STATUS_NE_BIT_MASK;
+		break;
+	    case IX_QMGR_Q_SOURCE_ID_NF:
+		qi->statusCheckValue = IX_QMGR_Q_STATUS_NF_BIT_MASK;
+		qi->statusMask = IX_QMGR_Q_STATUS_NF_BIT_MASK;
+		break;
+	    case IX_QMGR_Q_SOURCE_ID_F:
+		qi->statusCheckValue = IX_QMGR_Q_STATUS_F_BIT_MASK;
+		qi->statusMask = IX_QMGR_Q_STATUS_F_BIT_MASK;
+		break;
+	    case IX_QMGR_Q_SOURCE_ID_NOT_E:
+		qi->statusCheckValue = 0;
+		qi->statusMask = IX_QMGR_Q_STATUS_E_BIT_MASK;
+		break;
+	    case IX_QMGR_Q_SOURCE_ID_NOT_NE:
+		qi->statusCheckValue = 0;
+		qi->statusMask = IX_QMGR_Q_STATUS_NE_BIT_MASK;
+		break;
+	    case IX_QMGR_Q_SOURCE_ID_NOT_NF:
+		qi->statusCheckValue = 0;
+		qi->statusMask = IX_QMGR_Q_STATUS_NF_BIT_MASK;
+		break;
+	    case IX_QMGR_Q_SOURCE_ID_NOT_F:
+		qi->statusCheckValue = 0;
+		qi->statusMask = IX_QMGR_Q_STATUS_F_BIT_MASK;
+		break;
+	    default:
+		/* Should never hit */
+		IX_OSAL_ASSERT(0);
+		break;
+	    }
+
+	    /* One nibble of status per queue so need to shift the
+	     * check value and mask out to the correct position.
+	     */
+	    shiftVal = (qId % IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD) *
+		IX_QMGR_QUELOWSTAT_BITS_PER_Q;
+
+	    /* Calculate the which status word to check from the qId,
+	     * 8 Qs status per word
+	     */
+	    qi->statusWordOffset = qId / IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD;
+
+	    qi->statusCheckValue <<= shiftVal;
+	    qi->statusMask <<= shiftVal;
+	} else {
+	    /* One status word */
+	    qi->statusWordOffset = 0;
+	    /* Single bits per queue and int source bit hardwired  NE,
+	     * Qs start at 32.
+	     */
+	    qi->statusMask = 1 << (qId - IX_QMGR_MIN_QUEUPP_QID);
+	    qi->statusCheckValue = qi->statusMask;
+	}
+}
+#endif
+
+static void
+aqm_int_enable(struct ixpqmgr_softc *sc, int qId)
+{
+	bus_size_t reg;
+	uint32_t v;
+	
+	if (qId < IX_QMGR_MIN_QUEUPP_QID)
+	    reg = IX_QMGR_QUEIEREG0_OFFSET;
+	else
+	    reg = IX_QMGR_QUEIEREG1_OFFSET;
+	v = aqm_reg_read(sc, reg);
+	aqm_reg_write(sc, reg, v | (1 << (qId % IX_QMGR_MIN_QUEUPP_QID)));
+
+	DPRINTF(sc->sc_dev, "%s(%u) 0x%lx: 0x%x => 0x%x\n",
+	    __func__, qId, reg, v, aqm_reg_read(sc, reg));
+}
+
+static void
+aqm_int_disable(struct ixpqmgr_softc *sc, int qId)
+{
+	bus_size_t reg;
+	uint32_t v;
+
+	if (qId < IX_QMGR_MIN_QUEUPP_QID)
+	    reg = IX_QMGR_QUEIEREG0_OFFSET;
+	else
+	    reg = IX_QMGR_QUEIEREG1_OFFSET;
+	v = aqm_reg_read(sc, reg);
+	aqm_reg_write(sc, reg, v &~ (1 << (qId % IX_QMGR_MIN_QUEUPP_QID)));
+
+	DPRINTF(sc->sc_dev, "%s(%u) 0x%lx: 0x%x => 0x%x\n",
+	    __func__, qId, reg, v, aqm_reg_read(sc, reg));
+}
+
+static unsigned
+log2(unsigned n)
+{
+	unsigned count;
+	/*
+	 * N.B. this function will return 0 if supplied 0.
+	 */
+	for (count = 0; n/2; count++)
+	    n /= 2;
+	return count;
+}
+
+static __inline unsigned
+toAqmEntrySize(int entrySize)
+{
+	/* entrySize  1("00"),2("01"),4("10") */
+	return log2(entrySize);
+}
+
+static __inline unsigned
+toAqmBufferSize(unsigned bufferSizeInWords)
+{
+	/* bufferSize 16("00"),32("01),64("10"),128("11") */
+	return log2(bufferSizeInWords / IX_QMGR_MIN_BUFFER_SIZE);
+}
+
+static __inline unsigned
+toAqmWatermark(int watermark)
+{
+	/*
+	 * Watermarks 0("000"),1("001"),2("010"),4("011"),
+	 * 8("100"),16("101"),32("110"),64("111")
+	 */
+	return log2(2 * watermark);
+}
+
+static void
+aqm_qcfg(struct ixpqmgr_softc *sc, int qId, u_int ne, u_int nf)
+{
+	const struct qmgrInfo *qi = &sc->qinfo[qId];
+	uint32_t qCfg;
+	uint32_t baseAddress;
+
+	/* Build config register */
+	qCfg = ((toAqmEntrySize(1) & IX_QMGR_ENTRY_SIZE_MASK) <<
+		    IX_QMGR_Q_CONFIG_ESIZE_OFFSET)
+	     | ((toAqmBufferSize(qi->qSizeInWords) & IX_QMGR_SIZE_MASK) <<
+		    IX_QMGR_Q_CONFIG_BSIZE_OFFSET);
+
+	/* baseAddress, calculated relative to start address */
+	baseAddress = sc->aqmFreeSramAddress;
+		
+	/* base address must be word-aligned */
+	KASSERT((baseAddress % IX_QMGR_BASE_ADDR_16_WORD_ALIGN) == 0,
+	    ("address not word-aligned"));
+
+	/* Now convert to a 16 word pointer as required by QUECONFIG register */
+	baseAddress >>= IX_QMGR_BASE_ADDR_16_WORD_SHIFT;
+	qCfg |= baseAddress << IX_QMGR_Q_CONFIG_BADDR_OFFSET;
+
+	/* set watermarks */
+	qCfg |= (toAqmWatermark(ne) << IX_QMGR_Q_CONFIG_NE_OFFSET)
+	     |  (toAqmWatermark(nf) << IX_QMGR_Q_CONFIG_NF_OFFSET);
+
+	DPRINTF(sc->sc_dev, "%s(%u, %u, %u) 0x%x => 0x%x @ 0x%x\n",
+	    __func__, qId, ne, nf,
+	    aqm_reg_read(sc, IX_QMGR_Q_CONFIG_ADDR_GET(qId)),
+	    qCfg, IX_QMGR_Q_CONFIG_ADDR_GET(qId));
+
+	aqm_reg_write(sc, IX_QMGR_Q_CONFIG_ADDR_GET(qId), qCfg);
+}
+
+static void
+aqm_srcsel_write(struct ixpqmgr_softc *sc, int qId, int sourceId)
+{
+	bus_size_t off;
+	uint32_t v;
+
+	/*
+	 * Calculate the register offset; multiple queues split across registers
+	 */
+	off = IX_QMGR_INT0SRCSELREG0_OFFSET +
+	    ((qId / IX_QMGR_INTSRC_NUM_QUE_PER_WORD) * sizeof(uint32_t));
+
+	v = aqm_reg_read(sc, off);
+	if (off == IX_QMGR_INT0SRCSELREG0_OFFSET && qId == 0) {
+	    /* Queue 0 at INT0SRCSELREG should not corrupt the value bit-3  */
+	    v |= 0x7;
+	} else {
+	  const uint32_t bpq = 32 / IX_QMGR_INTSRC_NUM_QUE_PER_WORD;
+	  uint32_t mask;
+	  int qshift;
+
+	  qshift = (qId & (IX_QMGR_INTSRC_NUM_QUE_PER_WORD-1)) * bpq;
+	  mask = ((1 << bpq) - 1) << qshift;	/* q's status mask */
+
+	  /* merge sourceId */
+	  v = (v &~ mask) | ((sourceId << qshift) & mask);
+	}
+
+	DPRINTF(sc->sc_dev, "%s(%u, %u) 0x%x => 0x%x @ 0x%lx\n",
+	    __func__, qId, sourceId, aqm_reg_read(sc, off), v, off);
+	aqm_reg_write(sc, off, v);
+}
+
+/*
+ * Reset AQM registers to default values.
+ */
+static void
+aqm_reset(struct ixpqmgr_softc *sc)
+{
+	int i;
+
+	/* Reset queues 0..31 status registers 0..3 */
+	aqm_reg_write(sc, IX_QMGR_QUELOWSTAT0_OFFSET,
+		IX_QMGR_QUELOWSTAT_RESET_VALUE);
+	aqm_reg_write(sc, IX_QMGR_QUELOWSTAT1_OFFSET,
+		IX_QMGR_QUELOWSTAT_RESET_VALUE);
+	aqm_reg_write(sc, IX_QMGR_QUELOWSTAT2_OFFSET,
+		IX_QMGR_QUELOWSTAT_RESET_VALUE);
+	aqm_reg_write(sc, IX_QMGR_QUELOWSTAT3_OFFSET,
+		IX_QMGR_QUELOWSTAT_RESET_VALUE);
+
+	/* Reset underflow/overflow status registers 0..1 */
+	aqm_reg_write(sc, IX_QMGR_QUEUOSTAT0_OFFSET,
+		IX_QMGR_QUEUOSTAT_RESET_VALUE);
+	aqm_reg_write(sc, IX_QMGR_QUEUOSTAT1_OFFSET,
+		IX_QMGR_QUEUOSTAT_RESET_VALUE);
+	
+	/* Reset queues 32..63 nearly empty status registers */
+	aqm_reg_write(sc, IX_QMGR_QUEUPPSTAT0_OFFSET,
+		IX_QMGR_QUEUPPSTAT0_RESET_VALUE);
+
+	/* Reset queues 32..63 full status registers */
+	aqm_reg_write(sc, IX_QMGR_QUEUPPSTAT1_OFFSET,
+		IX_QMGR_QUEUPPSTAT1_RESET_VALUE);
+
+	/* Reset int0 status flag source select registers 0..3 */
+	aqm_reg_write(sc, IX_QMGR_INT0SRCSELREG0_OFFSET,
+			     IX_QMGR_INT0SRCSELREG_RESET_VALUE);
+	aqm_reg_write(sc, IX_QMGR_INT0SRCSELREG1_OFFSET,
+			     IX_QMGR_INT0SRCSELREG_RESET_VALUE);
+	aqm_reg_write(sc, IX_QMGR_INT0SRCSELREG2_OFFSET,
+			     IX_QMGR_INT0SRCSELREG_RESET_VALUE);
+	aqm_reg_write(sc, IX_QMGR_INT0SRCSELREG3_OFFSET,
+			     IX_QMGR_INT0SRCSELREG_RESET_VALUE);
+	
+	/* Reset queue interrupt enable register 0..1 */
+	aqm_reg_write(sc, IX_QMGR_QUEIEREG0_OFFSET,
+		IX_QMGR_QUEIEREG_RESET_VALUE);
+	aqm_reg_write(sc, IX_QMGR_QUEIEREG1_OFFSET,
+		IX_QMGR_QUEIEREG_RESET_VALUE);
+
+	/* Reset queue interrupt register 0..1 */
+	aqm_reg_write(sc, IX_QMGR_QINTREG0_OFFSET, IX_QMGR_QINTREG_RESET_VALUE);
+	aqm_reg_write(sc, IX_QMGR_QINTREG1_OFFSET, IX_QMGR_QINTREG_RESET_VALUE);
+
+	/* Reset queue configuration words 0..63 */
+	for (i = 0; i < IX_QMGR_MAX_NUM_QUEUES; i++)
+	    aqm_reg_write(sc, sc->qinfo[i].qConfigRegAddr,
+		IX_QMGR_QUECONFIG_RESET_VALUE);
+
+	/* XXX zero SRAM to simplify debugging */
+	for (i = IX_QMGR_QUEBUFFER_SPACE_OFFSET;
+	     i < IX_QMGR_AQM_SRAM_SIZE_IN_BYTES; i += sizeof(uint32_t))
+	    aqm_reg_write(sc, i, 0);
+}
+
+static device_method_t ixpqmgr_methods[] = {
+	DEVMETHOD(device_probe,		ixpqmgr_probe),
+	DEVMETHOD(device_attach,	ixpqmgr_attach),
+	DEVMETHOD(device_detach,	ixpqmgr_detach),
+
+	{ 0, 0 }
+};
+
+static driver_t ixpqmgr_driver = {
+	"ixpqmgr",
+	ixpqmgr_methods,
+	sizeof(struct ixpqmgr_softc),
+};
+static devclass_t ixpqmgr_devclass;
+
+DRIVER_MODULE(ixpqmgr, ixp, ixpqmgr_driver, ixpqmgr_devclass, 0, 0);


Property changes on: trunk/sys/arm/xscale/ixp425/ixp425_qmgr.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/ixp425/ixp425_qmgr.h
===================================================================
--- trunk/sys/arm/xscale/ixp425/ixp425_qmgr.h	                        (rev 0)
+++ trunk/sys/arm/xscale/ixp425/ixp425_qmgr.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,246 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2006 Sam Leffler, Errno Consulting
+ * 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,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ *    redistribution must be conditioned upon including a substantially
+ *    similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
+ *
+ * $FreeBSD: stable/10/sys/arm/xscale/ixp425/ixp425_qmgr.h 236987 2012-06-13 04:38:09Z imp $
+ */
+
+/*-
+ * Copyright (c) 2001-2005, Intel Corporation.
+ * 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.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+*/
+
+#ifndef ARM_XSCALE_IXP425_QMGR_H
+#define	ARM_XSCALE_IXP425_QMGR_H
+
+#define	IX_QMGR_MAX_NUM_QUEUES		64
+#define	IX_QMGR_MIN_QUEUPP_QID		32
+
+#define IX_QMGR_MIN_ENTRY_SIZE_IN_WORDS 16
+
+/* Total size of SRAM */
+#define IX_QMGR_AQM_SRAM_SIZE_IN_BYTES 0x4000
+
+#define	IX_QMGR_Q_PRIORITY_0		0
+#define	IX_QMGR_Q_PRIORITY_1		1
+#define	IX_QMGR_Q_PRIORITY_2		2
+#define IX_QMGR_NUM_PRIORITY_LEVELS	3	/* number of priority levels */
+
+#define	IX_QMGR_Q_STATUS_E_BIT_MASK	0x1	/* Empty */
+#define	IX_QMGR_Q_STATUS_NE_BIT_MASK	0x2	/* Nearly Empty */
+#define	IX_QMGR_Q_STATUS_NF_BIT_MASK	0x4	/* Nearly Full */
+#define	IX_QMGR_Q_STATUS_F_BIT_MASK	0x8	/* Full */
+#define	IX_QMGR_Q_STATUS_UF_BIT_MASK	0x10	/* Underflow */
+#define	IX_QMGR_Q_STATUS_OF_BIT_MASK	0x20	/* Overflow */
+
+#define	IX_QMGR_Q_SOURCE_ID_E		0 /* Q Empty after last read */
+#define	IX_QMGR_Q_SOURCE_ID_NE		1 /* Q Nearly Empty after last read */
+#define	IX_QMGR_Q_SOURCE_ID_NF		2 /* Q Nearly Full after last write */
+#define	IX_QMGR_Q_SOURCE_ID_F		3 /* Q Full after last write */
+#define	IX_QMGR_Q_SOURCE_ID_NOT_E	4 /* Q !Empty after last write */
+#define	IX_QMGR_Q_SOURCE_ID_NOT_NE	5 /* Q !Nearly Empty after last write */
+#define	IX_QMGR_Q_SOURCE_ID_NOT_NF	6 /* Q !Nearly Full after last read */
+#define	IX_QMGR_Q_SOURCE_ID_NOT_F	7 /* Q !Full after last read */
+
+#define IX_QMGR_UNDERFLOW_BIT_OFFSET	0x0	/* underflow bit mask */
+#define IX_QMGR_OVERFLOW_BIT_OFFSET     0x1	/* overflow bit mask */
+
+#define IX_QMGR_QUEACC0_OFFSET		0x0000	/* q 0 access register */
+#define IX_QMGR_QUEACC_SIZE		0x4/*words*/
+
+#define IX_QMGR_QUELOWSTAT0_OFFSET	0x400	/* Q status, q's 0-7 */
+#define IX_QMGR_QUELOWSTAT1_OFFSET	0x404	/* Q status, q's 8-15 */
+#define IX_QMGR_QUELOWSTAT2_OFFSET	0x408	/* Q status, q's 16-23 */
+#define IX_QMGR_QUELOWSTAT3_OFFSET	0x40c	/* Q status, q's 24-31 */
+
+/* Queue status register Q status bits mask */
+#define IX_QMGR_QUELOWSTAT_QUE_STS_BITS_MASK 0xF
+/* Size of queue 0-31 status register */
+#define IX_QMGR_QUELOWSTAT_SIZE     0x4 /*words*/
+#define IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD 8	/* # status/word */
+
+#define IX_QMGR_QUEUOSTAT0_OFFSET	0x410	/* Q UF/OF status, q's 0-15 */
+#define IX_QMGR_QUEUOSTAT1_OFFSET	0x414	/* Q UF/OF status, q's 16-31 */
+
+#define IX_QMGR_QUEUOSTAT_NUM_QUE_PER_WORD 16	/* # UF/OF status/word */
+
+#define IX_QMGR_QUEUPPSTAT0_OFFSET	0x418	/* NE status, q's 32-63 */
+#define IX_QMGR_QUEUPPSTAT1_OFFSET	0x41c	/* F status, q's 32-63 */
+
+#define IX_QMGR_INT0SRCSELREG0_OFFSET	0x420	/* INT src select, q's 0-7 */
+#define IX_QMGR_INT0SRCSELREG1_OFFSET	0x424	/* INT src select, q's 8-15 */
+#define IX_QMGR_INT0SRCSELREG2_OFFSET	0x428	/* INT src select, q's 16-23 */
+#define IX_QMGR_INT0SRCSELREG3_OFFSET	0x42c	/* INT src select, q's 24-31 */
+
+#define IX_QMGR_INTSRC_NUM_QUE_PER_WORD 8	/* # INT src select/word */
+
+#define IX_QMGR_QUEIEREG0_OFFSET	0x430	/* INT enable, q's 0-31 */
+#define IX_QMGR_QUEIEREG1_OFFSET	0x434	/* INT enable, q's 32-63 */
+#define IX_QMGR_QINTREG0_OFFSET		0x438	/* INT status, q's 0-31 */
+#define IX_QMGR_QINTREG1_OFFSET		0x43c	/* INT status, q's 32-63 */
+
+#define IX_QMGR_QUECONFIG_BASE_OFFSET	0x2000	/* Q config register, q 0 */
+
+#define IX_QMGR_QUECONFIG_SIZE		0x100	/* total size of Q config regs*/
+
+#define IX_QMGR_QUEBUFFER_SPACE_OFFSET	0x2100	/* start of SRAM */
+
+/* Total bits in a word */
+#define BITS_PER_WORD 32
+
+/* Size of queue buffer space */
+#define IX_QMGR_QUE_BUFFER_SPACE_SIZE 0x1F00
+
+/*
+ * This macro will return the address of the access register for the
+ * queue  specified by qId
+ */
+#define IX_QMGR_Q_ACCESS_ADDR_GET(qId)\
+        (((qId) * (IX_QMGR_QUEACC_SIZE * sizeof(uint32_t)))\
+	 + IX_QMGR_QUEACC0_OFFSET)
+
+/*
+ * Bit location of bit-3 of INT0SRCSELREG0 register to enabled
+ * sticky interrupt register.
+ */
+#define IX_QMGR_INT0SRCSELREG0_BIT3 3
+
+/*
+ * These defines are the bit offsets of the various fields of
+ * the queue configuration register.
+ */
+#if 0
+#define IX_QMGR_Q_CONFIG_WRPTR_OFFSET       0x00
+#define IX_QMGR_Q_CONFIG_RDPTR_OFFSET       0x07
+#define IX_QMGR_Q_CONFIG_BADDR_OFFSET       0x0E
+#define IX_QMGR_Q_CONFIG_ESIZE_OFFSET       0x16
+#define IX_QMGR_Q_CONFIG_BSIZE_OFFSET       0x18
+#define IX_QMGR_Q_CONFIG_NE_OFFSET          0x1A
+#define IX_QMGR_Q_CONFIG_NF_OFFSET          0x1D
+
+#define IX_QMGR_NE_NF_CLEAR_MASK            0x03FFFFFF
+#define IX_QMGR_NE_MASK                     0x7
+#define IX_QMGR_NF_MASK                     0x7
+#define IX_QMGR_SIZE_MASK                   0x3
+#define IX_QMGR_ENTRY_SIZE_MASK             0x3
+#define IX_QMGR_BADDR_MASK                  0x003FC000
+#define IX_QMGR_RDPTR_MASK                  0x7F
+#define IX_QMGR_WRPTR_MASK                  0x7F
+#define IX_QMGR_RDWRPTR_MASK                0x00003FFF
+#else
+#define IX_QMGR_Q_CONFIG_WRPTR_OFFSET       0
+#define IX_QMGR_WRPTR_MASK                  0x7F
+#define IX_QMGR_Q_CONFIG_RDPTR_OFFSET       7
+#define IX_QMGR_RDPTR_MASK                  0x7F
+#define IX_QMGR_Q_CONFIG_BADDR_OFFSET       14
+#define IX_QMGR_BADDR_MASK                  0x3FC000	/* XXX not used */
+#define IX_QMGR_Q_CONFIG_ESIZE_OFFSET       22
+#define IX_QMGR_ENTRY_SIZE_MASK             0x3
+#define IX_QMGR_Q_CONFIG_BSIZE_OFFSET       24
+#define IX_QMGR_SIZE_MASK                   0x3
+#define IX_QMGR_Q_CONFIG_NE_OFFSET          26
+#define IX_QMGR_NE_MASK                     0x7
+#define IX_QMGR_Q_CONFIG_NF_OFFSET          29
+#define IX_QMGR_NF_MASK                     0x7
+
+#define IX_QMGR_RDWRPTR_MASK                0x00003FFF
+#define IX_QMGR_NE_NF_CLEAR_MASK            0x03FFFFFF
+#endif
+
+#define IX_QMGR_BASE_ADDR_16_WORD_ALIGN     64
+#define IX_QMGR_BASE_ADDR_16_WORD_SHIFT     6
+
+#define IX_QMGR_AQM_ADDRESS_SPACE_SIZE_IN_WORDS 0x1000
+
+/* Base address of AQM SRAM */
+#define IX_QMGR_AQM_SRAM_BASE_ADDRESS_OFFSET \
+((IX_QMGR_QUECONFIG_BASE_OFFSET) + (IX_QMGR_QUECONFIG_SIZE))
+
+/* Min buffer size used for generating buffer size in QUECONFIG */
+#define IX_QMGR_MIN_BUFFER_SIZE 16
+
+/* Reset values of QMgr hardware registers */
+#define IX_QMGR_QUELOWSTAT_RESET_VALUE    0x33333333
+#define IX_QMGR_QUEUOSTAT_RESET_VALUE     0x00000000
+#define IX_QMGR_QUEUPPSTAT0_RESET_VALUE   0xFFFFFFFF
+#define IX_QMGR_QUEUPPSTAT1_RESET_VALUE   0x00000000
+#define IX_QMGR_INT0SRCSELREG_RESET_VALUE 0x00000000
+#define IX_QMGR_QUEIEREG_RESET_VALUE      0x00000000
+#define IX_QMGR_QINTREG_RESET_VALUE       0xFFFFFFFF
+#define IX_QMGR_QUECONFIG_RESET_VALUE     0x00000000
+
+#define IX_QMGR_QUELOWSTAT_BITS_PER_Q \
+	(BITS_PER_WORD/IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD)
+
+#define IX_QMGR_QUELOWSTAT_QID_MASK 0x7
+#define IX_QMGR_Q_CONFIG_ADDR_GET(qId)\
+        (((qId) * sizeof(uint32_t)) + IX_QMGR_QUECONFIG_BASE_OFFSET)
+
+#define IX_QMGR_ENTRY1_OFFSET 0
+#define IX_QMGR_ENTRY2_OFFSET 1
+#define IX_QMGR_ENTRY4_OFFSET 3
+
+typedef void qconfig_hand_t(int, void *);
+
+int	ixpqmgr_qconfig(int qId, int qSizeInWords, int ne, int nf, int srcSel,
+	    qconfig_hand_t *cb, void *cbarg);
+int	ixpqmgr_qwrite(int qId, uint32_t entry);
+int	ixpqmgr_qread(int qId, uint32_t *entry);
+int	ixpqmgr_qreadm(int qId, uint32_t n, uint32_t *p);
+uint32_t ixpqmgr_getqstatus(int qId);
+uint32_t ixpqmgr_getqconfig(int qId);
+void	ixpqmgr_notify_enable(int qId, int srcSel);
+void	ixpqmgr_notify_disable(int qId);
+void	ixpqmgr_dump(void);
+
+#endif /* ARM_XSCALE_IXP425_QMGR_H */


Property changes on: trunk/sys/arm/xscale/ixp425/ixp425_qmgr.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/ixp425/ixp425_space.c
===================================================================
--- trunk/sys/arm/xscale/ixp425/ixp425_space.c	                        (rev 0)
+++ trunk/sys/arm/xscale/ixp425/ixp425_space.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,130 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: ixp425_space.c,v 1.6 2006/04/10 03:36:03 simonb Exp $ */
+
+/*
+ * Copyright (c) 2003
+ *	Ichiro FUKUHARA <ichiro at ichiro.org>.
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Ichiro FUKUHARA.
+ * 4. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ICHIRO FUKUHARA ``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 ICHIRO FUKUHARA OR THE VOICES IN HIS HEAD 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: stable/10/sys/arm/xscale/ixp425/ixp425_space.c 278727 2015-02-13 22:32:02Z ian $");
+
+/*
+ * bus_space I/O functions for ixp425
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+
+#include <machine/pcb.h>
+
+#include <vm/vm.h>
+#include <vm/vm_kern.h>
+#include <vm/pmap.h>
+#include <vm/vm_page.h>
+#include <vm/vm_extern.h>
+
+#include <machine/bus.h>
+
+#include <arm/xscale/ixp425/ixp425reg.h>
+#include <arm/xscale/ixp425/ixp425var.h>
+
+/* Proto types for all the bus_space structure functions */
+bs_protos(generic);
+
+struct bus_space ixp425_bs_tag = {
+	/* cookie */
+	.bs_privdata	= (void *) 0,
+
+	/* mapping/unmapping */
+	.bs_map		= generic_bs_map,
+	.bs_unmap	= generic_bs_unmap,
+	.bs_subregion	= generic_bs_subregion,
+
+	/* allocation/deallocation */
+	.bs_alloc	= generic_bs_alloc,
+	.bs_free	= generic_bs_free,
+
+	/* barrier */
+	.bs_barrier	= generic_bs_barrier,
+
+	/* read (single) */
+	.bs_r_1		= generic_bs_r_1,
+	.bs_r_2		= generic_bs_r_2,
+	.bs_r_4		= generic_bs_r_4,
+	.bs_r_8		= NULL,
+
+	/* read multiple */
+	.bs_rm_1	= generic_bs_rm_1,
+	.bs_rm_2	= generic_bs_rm_2,
+	.bs_rm_4	= generic_bs_rm_4,
+	.bs_rm_8	= NULL,
+
+	/* read region */
+	.bs_rr_1	= generic_bs_rr_1,
+	.bs_rr_2	= generic_bs_rr_2,
+	.bs_rr_4	= generic_bs_rr_4,
+	.bs_rr_8	= NULL,
+
+	/* write (single) */
+	.bs_w_1		= generic_bs_w_1,
+	.bs_w_2		= generic_bs_w_2,
+	.bs_w_4		= generic_bs_w_4,
+	.bs_w_8		= NULL,
+
+	/* write multiple */
+	.bs_wm_1	= generic_bs_wm_1,
+	.bs_wm_2	= generic_bs_wm_2,
+	.bs_wm_4	= generic_bs_wm_4,
+	.bs_wm_8	= NULL,
+
+	/* write region */
+	.bs_wr_1	= generic_bs_wr_1,
+	.bs_wr_2	= generic_bs_wr_2,
+	.bs_wr_4	= generic_bs_wr_4,
+	.bs_wr_8	= NULL,
+
+	/* set multiple */
+	/* XXX not implemented */
+
+	/* set region */
+	.bs_sr_1	= NULL,
+	.bs_sr_2	= generic_bs_sr_2,
+	.bs_sr_4	= generic_bs_sr_4,
+	.bs_sr_8	= NULL,
+
+	/* copy */
+	.bs_c_1		= NULL,
+	.bs_c_2		= generic_bs_c_2,
+	.bs_c_4		= NULL,
+	.bs_c_8		= NULL,
+};


Property changes on: trunk/sys/arm/xscale/ixp425/ixp425_space.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/ixp425/ixp425_timer.c
===================================================================
--- trunk/sys/arm/xscale/ixp425/ixp425_timer.c	                        (rev 0)
+++ trunk/sys/arm/xscale/ixp425/ixp425_timer.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,270 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: ixp425_timer.c,v 1.11 2006/04/10 03:36:03 simonb Exp $ */
+
+/*
+ * Copyright (c) 2003
+ *	Ichiro FUKUHARA <ichiro at ichiro.org>.
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Ichiro FUKUHARA.
+ * 4. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ICHIRO FUKUHARA ``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 ICHIRO FUKUHARA OR THE VOICES IN HIS HEAD 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: stable/10/sys/arm/xscale/ixp425/ixp425_timer.c 278613 2015-02-12 03:50:33Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/time.h>
+#include <sys/bus.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+#include <sys/timetc.h>
+
+#include <machine/armreg.h>
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+#include <machine/frame.h>
+#include <machine/resource.h>
+#include <machine/intr.h>
+#include <arm/xscale/ixp425/ixp425reg.h>
+#include <arm/xscale/ixp425/ixp425var.h>
+
+static uint32_t counts_per_hz;
+
+/* callback functions for intr_functions */
+int	ixpclk_intr(void *);
+
+struct ixpclk_softc {
+	device_t		sc_dev;
+	bus_addr_t		sc_baseaddr;
+	bus_space_tag_t		sc_iot;
+	bus_space_handle_t      sc_ioh;
+};
+
+static unsigned ixp425_timer_get_timecount(struct timecounter *tc);
+
+#ifndef IXP425_CLOCK_FREQ
+#define	COUNTS_PER_SEC		66666600	/* 66MHz */
+#else
+#define	COUNTS_PER_SEC		IXP425_CLOCK_FREQ
+#endif
+#define	COUNTS_PER_USEC		((COUNTS_PER_SEC / 1000000) + 1)
+
+static struct ixpclk_softc *ixpclk_sc = NULL;
+
+#define GET_TS_VALUE(sc)	(*(volatile u_int32_t *) \
+				  (IXP425_TIMER_VBASE + IXP425_OST_TS))
+
+static struct timecounter ixp425_timer_timecounter = {
+	ixp425_timer_get_timecount,	/* get_timecount */
+	NULL, 				/* no poll_pps */
+	~0u, 				/* counter_mask */
+	COUNTS_PER_SEC,			/* frequency */
+	"IXP4XX Timer", 		/* name */
+	1000,				/* quality */
+};
+
+static int
+ixpclk_probe(device_t dev)
+{
+	device_set_desc(dev, "IXP4XX Timer");
+	return (0);
+}
+
+static int
+ixpclk_attach(device_t dev)
+{
+	struct ixpclk_softc *sc = device_get_softc(dev);
+	struct ixp425_softc *sa = device_get_softc(device_get_parent(dev));
+
+	ixpclk_sc = sc;
+
+	sc->sc_dev = dev;
+	sc->sc_iot = sa->sc_iot;
+	sc->sc_baseaddr = IXP425_TIMER_HWBASE;
+
+	if (bus_space_map(sc->sc_iot, sc->sc_baseaddr, 8, 0,
+			  &sc->sc_ioh))
+		panic("%s: Cannot map registers", device_get_name(dev));
+
+	return (0);
+}
+
+static device_method_t ixpclk_methods[] = {
+	DEVMETHOD(device_probe, ixpclk_probe),
+	DEVMETHOD(device_attach, ixpclk_attach),
+	{0, 0},
+};
+
+static driver_t ixpclk_driver = {
+	"ixpclk",
+	ixpclk_methods,
+	sizeof(struct ixpclk_softc),
+};
+static devclass_t ixpclk_devclass;
+
+DRIVER_MODULE(ixpclk, ixp, ixpclk_driver, ixpclk_devclass, 0, 0);
+static unsigned
+ixp425_timer_get_timecount(struct timecounter *tc)
+{
+	uint32_t ret;
+
+	ret = GET_TS_VALUE(sc);
+	return (ret);
+}
+
+/*
+ * cpu_initclocks:
+ *
+ *	Initialize the clock and get them going.
+ */
+void
+cpu_initclocks(void)
+{
+	struct ixpclk_softc* sc = ixpclk_sc;
+	struct resource *irq;
+	device_t dev = sc->sc_dev;
+	u_int oldirqstate;
+	int rid = 0;
+	void *ihl;
+
+	if (hz < 50 || COUNTS_PER_SEC % hz) {
+		printf("Cannot get %d Hz clock; using 100 Hz\n", hz);
+		hz = 100;
+	}
+	tick = 1000000 / hz;	/* number of microseconds between interrupts */
+
+	/*
+	 * We only have one timer available; stathz and profhz are
+	 * always left as 0 (the upper-layer clock code deals with
+	 * this situation).
+	 */
+	if (stathz != 0)
+		printf("Cannot get %d Hz statclock\n", stathz);
+	stathz = 0;
+
+	if (profhz != 0)
+		printf("Cannot get %d Hz profclock\n", profhz);
+	profhz = 0;
+
+	/* Report the clock frequency. */
+
+	oldirqstate = disable_interrupts(PSR_I);
+
+	irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, IXP425_INT_TMR0,
+	    IXP425_INT_TMR0, 1, RF_ACTIVE);
+	if (!irq)
+		panic("Unable to setup the clock irq handler.\n");
+	else
+		bus_setup_intr(dev, irq, INTR_TYPE_CLK, ixpclk_intr, NULL,
+		    NULL, &ihl);
+
+	/* Set up the new clock parameters. */
+
+	/* clear interrupt */
+	bus_space_write_4(sc->sc_iot, sc->sc_ioh, IXP425_OST_STATUS,
+			  OST_WARM_RESET | OST_WDOG_INT | OST_TS_INT |
+			  OST_TIM1_INT | OST_TIM0_INT);
+
+	counts_per_hz = COUNTS_PER_SEC / hz;
+
+	/* reload value & Timer enable */
+	bus_space_write_4(sc->sc_iot, sc->sc_ioh, IXP425_OST_TIM0_RELOAD,
+			  (counts_per_hz & TIMERRELOAD_MASK) | OST_TIMER_EN);
+
+	tc_init(&ixp425_timer_timecounter);
+	restore_interrupts(oldirqstate);
+	rid = 0;
+}
+
+
+/*
+ * DELAY:
+ *
+ *	Delay for at least N microseconds.
+ */
+void
+DELAY(int n)
+{
+	u_int32_t first, last;
+	int usecs;
+
+	if (n == 0)
+		return;
+
+	/*
+	 * Clamp the timeout at a maximum value (about 32 seconds with
+	 * a 66MHz clock). *Nobody* should be delay()ing for anywhere
+	 * near that length of time and if they are, they should be hung
+	 * out to dry.
+	 */
+	if (n >= (0x80000000U / COUNTS_PER_USEC))
+		usecs = (0x80000000U / COUNTS_PER_USEC) - 1;
+	else
+		usecs = n * COUNTS_PER_USEC;
+
+	/* Note: Timestamp timer counts *up*, unlike the other timers */
+	first = GET_TS_VALUE();
+
+	while (usecs > 0) {
+		last = GET_TS_VALUE();
+		usecs -= (int)(last - first);
+		first = last;
+	}
+}
+
+/*
+ * ixpclk_intr:
+ *
+ *	Handle the hardclock interrupt.
+ */
+int
+ixpclk_intr(void *arg)
+{
+	struct ixpclk_softc* sc = ixpclk_sc;
+	struct trapframe *frame = arg;
+
+	bus_space_write_4(sc->sc_iot, sc->sc_ioh, IXP425_OST_STATUS,
+			  OST_TIM0_INT);
+
+	hardclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
+	return (FILTER_HANDLED);
+}
+
+void
+cpu_startprofclock(void)
+{
+}
+
+void
+cpu_stopprofclock(void)
+{
+}


Property changes on: trunk/sys/arm/xscale/ixp425/ixp425_timer.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/ixp425/ixp425_wdog.c
===================================================================
--- trunk/sys/arm/xscale/ixp425/ixp425_wdog.c	                        (rev 0)
+++ trunk/sys/arm/xscale/ixp425/ixp425_wdog.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,118 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2006 Sam Leffler.  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 ``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 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: stable/10/sys/arm/xscale/ixp425/ixp425_wdog.c 259329 2013-12-13 20:43:11Z ian $");
+
+/*
+ * IXP4XX Watchdog Timer Support.
+ */
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/time.h>
+#include <sys/bus.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+#include <sys/watchdog.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+#include <machine/resource.h>
+#include <machine/intr.h>
+
+#include <arm/xscale/ixp425/ixp425reg.h>
+#include <arm/xscale/ixp425/ixp425var.h>
+
+struct ixpwdog_softc {
+	device_t		sc_dev;
+};
+
+static __inline uint32_t
+RD4(struct ixpwdog_softc *sc, bus_size_t off)
+{
+	return bus_space_read_4(&ixp425_bs_tag, IXP425_TIMER_VBASE, off);
+}
+
+static __inline void
+WR4(struct ixpwdog_softc *sc, bus_size_t off, uint32_t val)
+{
+	bus_space_write_4(&ixp425_bs_tag, IXP425_TIMER_VBASE, off, val);
+}
+
+static void
+ixp425_watchdog(void *arg, u_int cmd, int *error)
+{
+	struct ixpwdog_softc *sc = arg;
+	u_int u = cmd & WD_INTERVAL;
+
+	WR4(sc, IXP425_OST_WDOG_KEY, OST_WDOG_KEY_MAJICK);
+	if (4 <= u && u <= 35) {
+		WR4(sc, IXP425_OST_WDOG_ENAB, 0);
+		/* approximate 66.66MHz cycles */
+		WR4(sc, IXP425_OST_WDOG, 2<<(u - 4));
+		/* NB: reset on timer expiration */
+		WR4(sc, IXP425_OST_WDOG_ENAB,
+		    OST_WDOG_ENAB_CNT_ENA | OST_WDOG_ENAB_RST_ENA);
+		*error = 0;
+	} else {
+		/* disable watchdog */
+		WR4(sc, IXP425_OST_WDOG_ENAB, 0);
+	}
+	WR4(sc, IXP425_OST_WDOG_KEY, 0);
+}
+
+static int
+ixpwdog_probe(device_t dev)
+{
+	device_set_desc(dev, "IXP4XX Watchdog Timer");
+	return (0);
+}
+
+static int
+ixpwdog_attach(device_t dev)
+{
+	struct ixpwdog_softc *sc = device_get_softc(dev);
+
+	sc->sc_dev = dev;
+
+	EVENTHANDLER_REGISTER(watchdog_list, ixp425_watchdog, sc, 0);
+	return (0);
+}
+
+static device_method_t ixpwdog_methods[] = {
+	DEVMETHOD(device_probe,		ixpwdog_probe),
+	DEVMETHOD(device_attach,	ixpwdog_attach),
+	{0, 0},
+};
+
+static driver_t ixpwdog_driver = {
+	"ixpwdog",
+	ixpwdog_methods,
+	sizeof(struct ixpwdog_softc),
+};
+static devclass_t ixpwdog_devclass;
+DRIVER_MODULE(ixpwdog, ixp, ixpwdog_driver, ixpwdog_devclass, 0, 0);


Property changes on: trunk/sys/arm/xscale/ixp425/ixp425_wdog.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/ixp425/ixp425reg.h
===================================================================
--- trunk/sys/arm/xscale/ixp425/ixp425reg.h	                        (rev 0)
+++ trunk/sys/arm/xscale/ixp425/ixp425reg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,715 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: ixp425reg.h,v 1.19 2005/12/11 12:16:51 christos Exp $ */
+/*
+ * Copyright (c) 2003
+ *	Ichiro FUKUHARA <ichiro at ichiro.org>.
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Ichiro FUKUHARA.
+ * 4. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ICHIRO FUKUHARA ``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 ICHIRO FUKUHARA OR THE VOICES IN HIS HEAD 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: stable/10/sys/arm/xscale/ixp425/ixp425reg.h 261455 2014-02-04 03:36:42Z eadler $
+ *
+ */
+
+#ifndef _IXP425REG_H_
+#define _IXP425REG_H_
+
+/*
+ * Physical memory map for the Intel IXP425
+ */
+/*
+ * CC00 00FF ---------------------------
+ *           SDRAM Configuration Registers
+ * CC00 0000 ---------------------------
+ *
+ * C800 BFFF ---------------------------
+ *           System and Peripheral Registers
+ * C800 0000 ---------------------------
+ *           Expansion Bus Configuration Registers
+ * C400 0000 ---------------------------
+ *           PCI Configuration and Status Registers
+ * C000 0000 ---------------------------
+ *
+ * 6400 0000 ---------------------------
+ *           Queue manager
+ * 6000 0000 ---------------------------
+ *           Expansion Bus Data
+ * 5000 0000 ---------------------------
+ *           PCI Data
+ * 4800 0000 ---------------------------
+ *
+ * 4000 0000 ---------------------------
+ *           SDRAM
+ * 0000 0000 ---------------------------
+ */
+
+/*
+ * Virtual memory map for the Intel IXP425/IXP435 integrated devices
+ */
+/*
+ * FFFF FFFF ---------------------------
+ *
+ *           Global cache clean area
+ * FF00 0000 ---------------------------
+ *
+ * FE00 0000 ---------------------------
+ *           16M CFI Flash (on ext bus)
+ * FD00 0000 ---------------------------
+ *
+ * FC00 0000 ---------------------------
+ *           PCI Data (memory space)
+ * F800 0000 --------------------------- IXP425_PCI_MEM_VBASE
+ *
+ * F020 1000 ---------------------------
+ *           SDRAM/DDR Memory Controller
+ * F020 0000 --------------------------- IXP425_MCU_VBASE
+ *
+ * F001 F000 RS485 (Cambria)		 CAMBRIA_RS485_VBASE
+ * F001 E000 GPS (Cambria)		 CAMBRIA_GPS_VBASE
+ * F001 D000 EHCI USB 2 (IXP435)	 IXP435_USB2_VBASE
+ * F001 C000 EHCI USB 1 (IXP435)	 IXP435_USB1_VBASE
+ *           Queue manager
+ * F001 8000 --------------------------- IXP425_QMGR_VBASE
+ *           PCI Configuration and Status
+ * F001 7000 --------------------------- IXP425_PCI_VBASE
+ *
+ *	     (NB: gap for future addition of EXP CS5-7)
+ * F001 4000 Expansion Bus Chip Select 4
+ * F001 3000 Expansion Bus Chip Select 3
+ * F001 2000 Expansion Bus Chip Select 2
+ * F001 1000 Expansion Bus Chip Select 1
+ *           Expansion Bus Configuration
+ * F001 0000 --------------------------- IXP425_EXP_VBASE
+ *
+ * F000 C000 MAC-A (IXP435)
+ * F000 B000 USB (option on IXP425)
+ * F000 A000 MAC-B (IXP425) | MAC-C (IXP435)
+ * F000 9000 MAC-A (IXP425)
+ * F000 8000 NPE-C
+ * F000 7000 NPE-B (IXP425)
+ * F000 6000 NPE-A
+ * F000 5000 Timers
+ * F000 4000 GPIO Controller
+ * F000 3000 Interrupt Controller
+ * F000 2000 Performance Monitor Controller (PMC)
+ * F000 1000 UART 1 (IXP425)
+ * F000 0000 UART 0
+ * F000 0000 --------------------------- IXP425_IO_VBASE
+ *
+ * 0000 0000 ---------------------------
+ *
+ */
+
+/* Physical/Virtual address for I/O space */
+
+#define	IXP425_IO_VBASE		0xf0000000UL
+#define	IXP425_IO_HWBASE	0xc8000000UL
+#define	IXP425_IO_SIZE		0x00010000UL
+
+/* Physical/Virtual addresss offsets */
+#define	IXP425_UART0_OFFSET	0x00000000UL
+#define	IXP425_UART1_OFFSET	0x00001000UL
+#define	IXP425_PMC_OFFSET	0x00002000UL
+#define	IXP425_INTR_OFFSET	0x00003000UL
+#define	IXP425_GPIO_OFFSET	0x00004000UL
+#define	IXP425_TIMER_OFFSET	0x00005000UL
+#define	IXP425_NPE_A_OFFSET	0x00006000UL	/* Not User Programmable */
+#define	IXP425_NPE_B_OFFSET	0x00007000UL	/* Not User Programmable */
+#define	IXP425_NPE_C_OFFSET	0x00008000UL	/* Not User Programmable */
+#define	IXP425_MAC_B_OFFSET	0x00009000UL	/* Ethernet MAC on NPE-B */
+#define	IXP425_MAC_C_OFFSET	0x0000a000UL	/* Ethernet MAC on NPE-C */
+#define	IXP425_USB_OFFSET	0x0000b000UL
+
+#define	IXP435_MAC_A_OFFSET	0x0000c000UL	/* Ethernet MAC on NPE-A */
+
+#define	IXP425_REG_SIZE		0x1000
+
+/*
+ * UART
+ * 	UART0 0xc8000000
+ * 	UART1 0xc8001000
+ *
+ */
+/* I/O space */
+#define	IXP425_UART0_HWBASE	(IXP425_IO_HWBASE + IXP425_UART0_OFFSET)
+#define	IXP425_UART1_HWBASE	(IXP425_IO_HWBASE + IXP425_UART1_OFFSET)
+
+#define	IXP425_UART0_VBASE	(IXP425_IO_VBASE + IXP425_UART0_OFFSET)
+						/* 0xf0000000 */
+#define	IXP425_UART1_VBASE	(IXP425_IO_VBASE + IXP425_UART1_OFFSET)
+						/* 0xf0001000 */
+
+#define	IXP425_UART_FREQ	14745600
+
+#define	IXP425_UART_IER		0x01	/* interrupt enable register */
+#define	IXP425_UART_IER_RTOIE	0x10	/* receiver timeout interrupt enable */
+#define	IXP425_UART_IER_UUE	0x40	/* UART Unit enable */
+
+/*#define	IXP4XX_COM_NPORTS	8*/
+
+/*
+ * Timers
+ */
+#define	IXP425_TIMER_HWBASE	(IXP425_IO_HWBASE + IXP425_TIMER_OFFSET)
+#define	IXP425_TIMER_VBASE	(IXP425_IO_VBASE + IXP425_TIMER_OFFSET)
+
+#define	IXP425_OST_TS		0x0000
+#define	IXP425_OST_TIM0		0x0004
+#define	IXP425_OST_TIM1		0x000C
+
+#define	IXP425_OST_TIM0_RELOAD	0x0008
+#define	IXP425_OST_TIM1_RELOAD	0x0010
+#define	TIMERRELOAD_MASK	0xFFFFFFFC
+#define	OST_ONESHOT_EN		(1U << 1)
+#define	OST_TIMER_EN		(1U << 0)
+
+#define	IXP425_OST_STATUS	0x0020
+#define	OST_WARM_RESET		(1U << 4)
+#define	OST_WDOG_INT		(1U << 3)
+#define	OST_TS_INT		(1U << 2)
+#define	OST_TIM1_INT		(1U << 1)
+#define	OST_TIM0_INT		(1U << 0)
+
+#define	IXP425_OST_WDOG		0x0014
+#define	IXP425_OST_WDOG_ENAB	0x0018
+#define	IXP425_OST_WDOG_KEY	0x001c
+#define	OST_WDOG_KEY_MAJICK	0x482e
+#define	OST_WDOG_ENAB_RST_ENA	(1u << 0)
+#define	OST_WDOG_ENAB_INT_ENA	(1u << 1)
+#define	OST_WDOG_ENAB_CNT_ENA	(1u << 2)
+
+/*
+ * Interrupt Controller Unit.
+ *  PA 0xc8003000
+ */
+
+#define	IXP425_IRQ_HWBASE	IXP425_IO_HWBASE + IXP425_INTR_OFFSET
+#define	IXP425_IRQ_VBASE	IXP425_IO_VBASE  + IXP425_INTR_OFFSET
+						/* 0xf0003000 */
+#define	IXP425_IRQ_SIZE		0x00000020UL
+
+#define	IXP425_INT_STATUS	(IXP425_IRQ_VBASE + 0x00)
+#define	IXP425_INT_ENABLE	(IXP425_IRQ_VBASE + 0x04)
+#define	IXP425_INT_SELECT	(IXP425_IRQ_VBASE + 0x08)
+#define	IXP425_IRQ_STATUS	(IXP425_IRQ_VBASE + 0x0C)
+#define	IXP425_FIQ_STATUS	(IXP425_IRQ_VBASE + 0x10)
+#define	IXP425_INT_PRTY		(IXP425_IRQ_VBASE + 0x14)
+#define	IXP425_IRQ_ENC		(IXP425_IRQ_VBASE + 0x18)
+#define	IXP425_FIQ_ENC		(IXP425_IRQ_VBASE + 0x1C)
+
+#define	IXP425_INT_SW1		31	/* SW Interrupt 1 */
+#define	IXP425_INT_SW0		30	/* SW Interrupt 0 */
+#define	IXP425_INT_GPIO_12	29	/* GPIO 12 */
+#define	IXP425_INT_GPIO_11	28	/* GPIO 11 */
+#define	IXP425_INT_GPIO_10	27	/* GPIO 11 */
+#define	IXP425_INT_GPIO_9	26	/* GPIO 9 */
+#define	IXP425_INT_GPIO_8	25	/* GPIO 8 */
+#define	IXP425_INT_GPIO_7	24	/* GPIO 7 */
+#define	IXP425_INT_GPIO_6	23	/* GPIO 6 */
+#define	IXP425_INT_GPIO_5	22	/* GPIO 5 */
+#define	IXP425_INT_GPIO_4	21	/* GPIO 4 */
+#define	IXP425_INT_GPIO_3	20	/* GPIO 3 */
+#define	IXP425_INT_GPIO_2	19	/* GPIO 2 */
+#define	IXP425_INT_XSCALE_PMU	18	/* XScale PMU */
+#define	IXP425_INT_AHB_PMU	17	/* AHB PMU */
+#define	IXP425_INT_WDOG		16	/* Watchdog Timer */
+#define	IXP425_INT_UART0	15	/* HighSpeed UART */
+#define	IXP425_INT_STAMP	14	/* Timestamp Timer */
+#define	IXP425_INT_UART1	13	/* Console UART */
+#define	IXP425_INT_USB		12	/* USB */
+#define	IXP425_INT_TMR1		11	/* General-Purpose Timer1 */
+#define	IXP425_INT_PCIDMA2	10	/* PCI DMA Channel 2 */
+#define	IXP425_INT_PCIDMA1	 9	/* PCI DMA Channel 1 */
+#define	IXP425_INT_PCIINT	 8	/* PCI Interrupt */
+#define	IXP425_INT_GPIO_1	 7	/* GPIO 1 */
+#define	IXP425_INT_GPIO_0	 6	/* GPIO 0 */
+#define	IXP425_INT_TMR0		 5	/* General-Purpose Timer0 */
+#define	IXP425_INT_QUE33_64	 4	/* Queue Manager 33-64 */
+#define	IXP425_INT_QUE1_32	 3	/* Queue Manager  1-32 */
+#define	IXP425_INT_NPE_C	 2	/* NPE C */
+#define	IXP425_INT_NPE_B	 1	/* NPE B */
+#define	IXP425_INT_NPE_A	 0	/* NPE A */
+
+/* NB: IXP435 has an additional 32 IRQ's */
+#define	IXP435_INT_STATUS2	(IXP425_IRQ_VBASE + 0x20)
+#define	IXP435_INT_ENABLE2	(IXP425_IRQ_VBASE + 0x24)
+#define	IXP435_INT_SELECT2	(IXP425_IRQ_VBASE + 0x28)
+#define	IXP435_IRQ_STATUS2	(IXP425_IRQ_VBASE + 0x2C)
+#define	IXP435_FIQ_STATUS2	(IXP425_IRQ_VBASE + 0x30)
+
+#define	IXP435_INT_USB0		32	/* USB Host 2.0 Host 0 */
+#define	IXP435_INT_USB1		33	/* USB Host 2.0 Host 1 */
+#define	IXP435_INT_QMGR_PER	60	/* Queue manager parity error */
+#define	IXP435_INT_ECC		61	/* Single or multi-bit ECC error */
+
+/*
+ * software interrupt
+ */
+#define	IXP425_INT_bit31	31
+#define	IXP425_INT_bit30	30
+#define	IXP425_INT_bit14	14
+#define	IXP425_INT_bit11	11
+
+#define	IXP425_INT_HWMASK	(0xffffffff & \
+					~((1 << IXP425_INT_bit31) | \
+					  (1 << IXP425_INT_bit30) | \
+					  (1 << IXP425_INT_bit14) | \
+					  (1 << IXP425_INT_bit11)))
+#define	IXP425_INT_GPIOMASK	(0x3ff800c0u)
+
+#define	IXP435_INT_HWMASK	((1 << (IXP435_INT_USB0 - 32)) | \
+				 (1 << (IXP435_INT_USB1 - 32)) | \
+				 (1 << (IXP435_INT_QMGR_PER - 32)) | \
+				 (1 << (IXP435_INT_ECC - 32)))
+
+/*
+ * GPIO
+ */
+#define	IXP425_GPIO_HWBASE	IXP425_IO_HWBASE + IXP425_GPIO_OFFSET
+#define IXP425_GPIO_VBASE	IXP425_IO_VBASE  + IXP425_GPIO_OFFSET
+					/* 0xf0004000 */
+#define IXP425_GPIO_SIZE	0x00000020UL
+
+#define	IXP425_GPIO_GPOUTR	0x00
+#define	IXP425_GPIO_GPOER	0x04
+#define	IXP425_GPIO_GPINR	0x08
+#define	IXP425_GPIO_GPISR	0x0c
+#define	IXP425_GPIO_GPIT1R	0x10
+#define	IXP425_GPIO_GPIT2R	0x14
+#define	IXP425_GPIO_GPCLKR	0x18
+# define GPCLKR_MUX14	(1U << 8)
+# define GPCLKR_CLK0TC_SHIFT	4
+# define GPCLKR_CLK0DC_SHIFT	0
+
+/* GPIO Output */
+#define	GPOUT_ON		0x1
+#define	GPOUT_OFF		0x0
+
+/* GPIO direction */
+#define	GPOER_INPUT		0x1
+#define	GPOER_OUTPUT		0x0
+
+/* GPIO Type bits */
+#define	GPIO_TYPE_ACT_HIGH	0x0
+#define	GPIO_TYPE_ACT_LOW	0x1
+#define	GPIO_TYPE_EDG_RISING	0x2
+#define	GPIO_TYPE_EDG_FALLING	0x3
+#define	GPIO_TYPE_TRANSITIONAL	0x4
+#define	GPIO_TYPE_MASK		0x7
+#define	GPIO_TYPE(b,v)		((v) << (((b) & 0x7) * 3))
+#define	GPIO_TYPE_REG(b)	(((b)&8)?IXP425_GPIO_GPIT2R:IXP425_GPIO_GPIT1R)
+
+#define	IXP4XX_GPIO_PINS	16
+
+/*
+ * Expansion Bus Configuration Space.
+ */
+#define	IXP425_EXP_HWBASE	0xc4000000UL
+#define	IXP425_EXP_VBASE	0xf0010000UL
+#define	IXP425_EXP_SIZE		0x1000
+
+/* offset */
+#define	EXP_TIMING_CS0_OFFSET		0x0000
+#define	EXP_TIMING_CS1_OFFSET		0x0004
+#define	EXP_TIMING_CS2_OFFSET		0x0008
+#define	EXP_TIMING_CS3_OFFSET		0x000c
+#define	EXP_TIMING_CS4_OFFSET		0x0010
+#define	EXP_TIMING_CS5_OFFSET		0x0014
+#define	EXP_TIMING_CS6_OFFSET		0x0018
+#define	EXP_TIMING_CS7_OFFSET		0x001c
+#define EXP_CNFG0_OFFSET		0x0020
+#define EXP_CNFG1_OFFSET		0x0024
+#define	EXP_FCTRL_OFFSET		0x0028
+
+#define IXP425_EXP_RECOVERY_SHIFT	16
+#define IXP425_EXP_HOLD_SHIFT		20
+#define IXP425_EXP_STROBE_SHIFT		22
+#define IXP425_EXP_SETUP_SHIFT		26
+#define IXP425_EXP_ADDR_SHIFT		28
+#define IXP425_EXP_CS_EN		(1U << 31)
+
+#define IXP425_EXP_RECOVERY_T(x)	(((x) & 15) << IXP425_EXP_RECOVERY_SHIFT)
+#define IXP425_EXP_HOLD_T(x)		(((x) & 3)  << IXP425_EXP_HOLD_SHIFT)
+#define IXP425_EXP_STROBE_T(x)		(((x) & 15) << IXP425_EXP_STROBE_SHIFT)
+#define IXP425_EXP_SETUP_T(x)		(((x) & 3)  << IXP425_EXP_SETUP_SHIFT)
+#define IXP425_EXP_ADDR_T(x)		(((x) & 3)  << IXP425_EXP_ADDR_SHIFT)
+
+/* EXP_CSn bits */
+#define EXP_BYTE_EN		0x00000001	/* bus uses only 8-bit data */
+#define EXP_WR_EN		0x00000002	/* ena writes to CS region */
+/* bit 2 is reserved */
+#define EXP_SPLT_EN		0x00000008	/* ena AHB split transfers */
+#define EXP_MUX_EN		0x00000010	/* multiplexed address/data */
+#define EXP_HRDY_POL		0x00000020	/* HPI|HRDY polarity */
+#define EXP_BYTE_RD16		0x00000040	/* byte rd access to word dev */
+#define	EXP_CNFG		0x00003c00	/* device config size */
+#define EXP_SZ_512		(0 << 10)
+#define EXP_SZ_1K		(1 << 10)
+#define EXP_SZ_2K		(2 << 10)
+#define EXP_SZ_4K		(3 << 10)
+#define EXP_SZ_8K		(4 << 10)
+#define EXP_SZ_16K		(5 << 10)
+#define EXP_SZ_32K		(6 << 10)
+#define EXP_SZ_64K		(7 << 10)
+#define EXP_SZ_128K		(8 << 10)
+#define EXP_SZ_256K		(9 << 10)
+#define EXP_SZ_512K		(10 << 10)
+#define EXP_SZ_1M		(11 << 10)
+#define EXP_SZ_2M		(12 << 10)
+#define EXP_SZ_4M		(13 << 10)
+#define EXP_SZ_8M		(14 << 10)
+#define EXP_SZ_16M		(15 << 10)
+#define	EXP_CYC_TYPE		0x0000c000	/* bus cycle "type" */
+#define EXP_CYC_INTEL		(0 << 14)
+#define EXP_CYC_MOTO		(1 << 14)
+#define EXP_CYC_HPI		(2 << 14)
+#define	EXP_T5			0x000f0000	/* recovery timing */
+#define	EXP_T4			0x00300000	/* hold timing */
+#define	EXP_T3			0x03c00000	/* strobe timing */
+#define	EXP_T2			0x0c000000	/* setup/chip select timing */
+#define	EXP_T1			0x30000000	/* address timing */
+/* bit 30 is reserved */
+#define	EXP_CS_EN		0x80000000	/* chip select enabled */
+
+/* EXP_CNFG0 bits */
+#define EXP_CNFG0_8BIT             (1 << 0)
+#define EXP_CNFG0_PCI_HOST         (1 << 1)
+#define EXP_CNFG0_PCI_ARB          (1 << 2)
+#define EXP_CNFG0_PCI_66MHZ        (1 << 4)
+#define EXP_CNFG0_MEM_MAP          (1U << 31)
+
+/* EXP_CNFG1 bits */
+#define EXP_CNFG1_SW_INT0          (1 << 0)
+#define EXP_CNFG1_SW_INT1          (1 << 1)
+
+#define	EXP_FCTRL_RCOMP		(1<<0)
+#define	EXP_FCTRL_USB_DEVICE	(1<<1)
+#define	EXP_FCTRL_HASH		(1<<2)
+#define	EXP_FCTRL_AES		(1<<3)
+#define	EXP_FCTRL_DES		(1<<4)
+#define	EXP_FCTRL_HDLC		(1<<5)
+#define	EXP_FCTRL_AAL		(1<<6)
+#define	EXP_FCTRL_HSS		(1<<7)
+#define	EXP_FCTRL_UTOPIA	(1<<8)
+#define	EXP_FCTRL_ETH0		(1<<9)
+#define	EXP_FCTRL_ETH1		(1<<10)
+#define	EXP_FCTRL_NPEA		(1<<11)		/* reset */
+#define	EXP_FCTRL_NPEB		(1<<12)		/* reset */
+#define	EXP_FCTRL_NPEC		(1<<13)		/* reset */
+#define	EXP_FCTRL_PCI		(1<<14)
+#define	EXP_FCTRL_ECC_TIMESYNC	(1<<15)
+#define	EXP_FCTRL_UTOPIA_PHY	(3<<16)		/* PHY limit */
+#define	EXP_FCTRL_USB_HOST	(1<<18)
+#define	EXP_FCTRL_NPEA_ETH	(1<<19)
+#define	EXP_FCTRL_NPEB_ETH	(1<<20)
+#define	EXP_FCTRL_RSA		(1<<21)
+#define	EXP_FCTRL_MAXFREQ	(3<<22)		/* XScale frequency */
+#define	EXP_FCTRL_RESVD		(0xff<<24)
+
+#define EXP_FCTRL_IXP46X_ONLY \
+	(EXP_FCTRL_ECC_TIMESYNC | EXP_FCTRL_USB_HOST | EXP_FCTRL_NPEA_ETH | \
+	 EXP_FCTRL_NPEB_ETH | EXP_FCTRL_RSA | EXP_FCTRL_MAXFREQ)
+
+#define	EXP_FCTRL_BITS \
+	"\20\1RCOMP\2USB\3HASH\4AES\5DES\6HDLC\7AAL\10HSS\11UTOPIA\12ETH0" \
+	"\13ETH1\17PCI\20ECC\23USB_HOST\24NPEA_ETH\25NPEB_ETH\26RSA"
+
+/*
+ * PCI
+ */
+#define IXP425_PCI_HWBASE	0xc0000000
+#define	IXP425_PCI_VBASE	0xf0017000UL
+#define	IXP425_PCI_SIZE		0x1000
+
+#define	IXP425_AHB_OFFSET	0x00000000UL	/* AHB bus */
+
+/*
+ * Mapping registers of IXP425 PCI Configuration
+ */
+/* PCI_ID_REG			0x00 */
+/* PCI_COMMAND_STATUS_REG	0x04 */
+/* PCI_CLASS_REG		0x08 */
+/* PCI_BHLC_REG			0x0c */
+#define	PCI_MAPREG_BAR0		0x10	/* Base Address 0 */
+#define	PCI_MAPREG_BAR1		0x14	/* Base Address 1 */
+#define	PCI_MAPREG_BAR2		0x18	/* Base Address 2 */
+#define	PCI_MAPREG_BAR3		0x1c	/* Base Address 3 */
+#define	PCI_MAPREG_BAR4		0x20	/* Base Address 4 */
+#define	PCI_MAPREG_BAR5		0x24	/* Base Address 5 */
+/* PCI_SUBSYS_ID_REG		0x2c */
+/* PCI_INTERRUPT_REG		0x3c */
+#define	PCI_RTOTTO		0x40
+
+/* PCI Controller CSR Base Address */
+#define	IXP425_PCI_CSR_BASE	IXP425_PCI_VBASE
+
+/* PCI Memory Space */
+#define	IXP425_PCI_MEM_HWBASE	0x48000000UL
+#define	IXP425_PCI_MEM_VBASE	0xf8000000UL
+#define	IXP425_PCI_MEM_SIZE	0x04000000UL	/* 64MB */
+
+/* PCI I/O Space */
+#define	IXP425_PCI_IO_HWBASE	0x00000000UL
+#define	IXP425_PCI_IO_SIZE	0x00100000UL    /* 1Mbyte */
+
+/* PCI Controller Configuration Offset */
+#define	PCI_NP_AD		0x00
+#define	PCI_NP_CBE		0x04
+# define NP_CBE_SHIFT		4
+#define	PCI_NP_WDATA		0x08
+#define	PCI_NP_RDATA		0x0c
+#define	PCI_CRP_AD_CBE		0x10
+#define	PCI_CRP_AD_WDATA	0x14
+#define	PCI_CRP_AD_RDATA	0x18
+#define	PCI_CSR			0x1c
+# define CSR_PRST		(1U << 16)
+# define CSR_IC			(1U << 15)
+# define CSR_ABE		(1U << 4)
+# define CSR_PDS		(1U << 3)
+# define CSR_ADS		(1U << 2)
+# define CSR_HOST		(1U << 0)
+#define	PCI_ISR			0x20
+# define ISR_AHBE		(1U << 3)
+# define ISR_PPE		(1U << 2)
+# define ISR_PFE		(1U << 1)
+# define ISR_PSE		(1U << 0)
+#define	PCI_INTEN		0x24
+#define	PCI_DMACTRL		0x28
+#define	PCI_AHBMEMBASE		0x2c
+#define	PCI_AHBIOBASE		0x30
+#define	PCI_PCIMEMBASE		0x34
+#define	PCI_AHBDOORBELL		0x38
+#define	PCI_PCIDOORBELL		0x3c
+#define	PCI_ATPDMA0_AHBADDR	0x40
+#define	PCI_ATPDMA0_PCIADDR	0x44
+#define	PCI_ATPDMA0_LENGTH	0x48
+#define	PCI_ATPDMA1_AHBADDR	0x4c
+#define	PCI_ATPDMA1_PCIADDR	0x50
+#define	PCI_ATPDMA1_LENGTH	0x54
+#define	PCI_PTADMA0_AHBADDR	0x58
+#define	PCI_PTADMA0_PCIADDR	0x5c
+#define	PCI_PTADMA0_LENGTH	0x60
+#define	PCI_PTADMA1_AHBADDR	0x64
+#define	PCI_PTADMA1_PCIADDR	0x68
+#define	PCI_PTADMA1_LENGTH	0x6c
+
+/* PCI target(T)/initiator(I) Interface Commands for PCI_NP_CBE register */
+#define	COMMAND_NP_IA		0x0	/* Interrupt Acknowledge   (I)*/
+#define	COMMAND_NP_SC		0x1	/* Special Cycle	   (I)*/
+#define	COMMAND_NP_IO_READ	0x2	/* I/O Read		(T)(I) */
+#define	COMMAND_NP_IO_WRITE	0x3	/* I/O Write		(T)(I) */
+#define	COMMAND_NP_MEM_READ	0x6	/* Memory Read		(T)(I) */
+#define	COMMAND_NP_MEM_WRITE	0x7	/* Memory Write		(T)(I) */
+#define	COMMAND_NP_CONF_READ	0xa	/* Configuration Read	(T)(I) */
+#define	COMMAND_NP_CONF_WRITE	0xb	/* Configuration Write	(T)(I) */
+
+/* PCI byte enables */
+#define	BE_8BIT(a)		((0x10u << ((a) & 0x03)) ^ 0xf0)
+#define	BE_16BIT(a)		((0x30u << ((a) & 0x02)) ^ 0xf0)
+#define	BE_32BIT(a)		0x00
+
+/* PCI byte selects */
+#define	READ_8BIT(v,a)		((u_int8_t)((v) >> (((a) & 3) * 8)))
+#define	READ_16BIT(v,a)		((u_int16_t)((v) >> (((a) & 2) * 8)))
+#define	WRITE_8BIT(v,a)		(((u_int32_t)(v)) << (((a) & 3) * 8))
+#define	WRITE_16BIT(v,a)	(((u_int32_t)(v)) << (((a) & 2) * 8))
+
+/* PCI Controller Configuration Commands for PCI_CRP_AD_CBE */
+#define COMMAND_CRP_READ	0x00
+#define COMMAND_CRP_WRITE	(1U << 16)
+
+/*
+ * SDRAM Configuration Register
+ */
+#define	IXP425_MCU_HWBASE	0xcc000000UL
+#define IXP425_MCU_VBASE	0xf0200000UL
+#define	IXP425_MCU_SIZE		0x1000		/* Actually only 256 bytes */
+#define	MCU_SDR_CONFIG		0x00
+#define  MCU_SDR_CONFIG_MCONF(x) ((x) & 0x7)
+#define  MCU_SDR_CONFIG_64MBIT	(1u << 5)
+#define	MCU_SDR_REFRESH		0x04
+#define	MCU_SDR_IR		0x08
+
+/*
+ * IXP435 DDR MCU Registers
+ */
+#define	IXP435_MCU_HWBASE	0xcc00e500UL
+#define	MCU_DDR_SDIR		0x00		/* DDR SDAM Initialization Reg*/
+#define	MCU_DDR_SDCR0		0x04		/* DDR SDRAM Control Reg 0 */
+#define	MCU_DDR_SDCR1		0x08		/* DDR SDRAM Control Reg 1 */
+#define	MCU_DDR_SDBR		0x0c		/* SDRAM Base Register */
+#define	MCU_DDR_SBR0		0x10		/* SDRAM Boundary Register 0 */
+#define	MCU_DDR_SBR1		0x14		/* SDRAM Boundary Register 1 */
+#define	MCU_DDR_ECCR		0x1c		/* ECC Control Register */
+#define	MCU_DDR_ELOG0		0x20		/* ECC Log Register 0 */
+#define	MCU_DDR_ELOG1		0x24		/* ECC Log Register 1 */
+#define	MCU_DDR_ECAR0		0x28		/* ECC Address Register 0 */
+#define	MCU_DDR_ECAR1		0x2c		/* ECC Address Register 1 */
+#define	MCU_DDR_ECTST		0x30		/* ECC Test Register */
+#define	MCU_DDR_MCISR		0x34		/* MC Interrupt Status Reg */
+#define	MCU_DDR_MPTCR		0x3c		/* MC Port Transaction Cnt Reg*/
+#define	MCU_DDR_RFR		0x48		/* Refresh Frequency Register */
+#define	MCU_DDR_SDPR(n)		(0x50+(n)*4)	/* SDRAM Page Register 0-7 */
+/* NB: RCVDLY at 0x1050 and LEGOVERIDE at 0x1074 */
+
+/*
+ * Performance Monitoring Unit          (CP14)
+ *
+ *      CP14.0.1	Performance Monitor Control Register(PMNC)
+ *      CP14.1.1	Clock Counter(CCNT)
+ *      CP14.4.1	Interrupt Enable Register(INTEN)
+ *      CP14.5.1	Overflow Flag Register(FLAG)
+ *      CP14.8.1	Event Selection Register(EVTSEL)
+ *      CP14.0.2	Performance Counter Register 0(PMN0)
+ *      CP14.1.2	Performance Counter Register 0(PMN1)
+ *      CP14.2.2	Performance Counter Register 0(PMN2)
+ *      CP14.3.2	Performance Counter Register 0(PMN3)
+ */
+
+#define	PMNC_E		0x00000001	/* enable all counters */
+#define	PMNC_P		0x00000002	/* reset all PMNs to 0 */
+#define	PMNC_C		0x00000004	/* clock counter reset */
+#define	PMNC_D		0x00000008	/* clock counter / 64 */
+
+#define INTEN_CC_IE	0x00000001	/* enable clock counter interrupt */
+#define	INTEN_PMN0_IE	0x00000002	/* enable PMN0 interrupt */
+#define	INTEN_PMN1_IE	0x00000004	/* enable PMN1 interrupt */
+#define	INTEN_PMN2_IE	0x00000008	/* enable PMN2 interrupt */
+#define	INTEN_PMN3_IE	0x00000010	/* enable PMN3 interrupt */
+
+#define	FLAG_CC_IF	0x00000001	/* clock counter overflow */
+#define	FLAG_PMN0_IF	0x00000002	/* PMN0 overflow */
+#define	FLAG_PMN1_IF	0x00000004	/* PMN1 overflow */
+#define	FLAG_PMN2_IF	0x00000008	/* PMN2 overflow */
+#define	FLAG_PMN3_IF	0x00000010	/* PMN3 overflow */
+
+#define EVTSEL_EVCNT_MASK 0x0000000ff	/* event to count for PMNs */
+#define PMNC_EVCNT0_SHIFT 0
+#define PMNC_EVCNT1_SHIFT 8
+#define PMNC_EVCNT2_SHIFT 16
+#define PMNC_EVCNT3_SHIFT 24
+
+/*
+ * Queue Manager
+ */
+#define	IXP425_QMGR_HWBASE	0x60000000UL
+#define IXP425_QMGR_VBASE	0xf0018000UL
+#define IXP425_QMGR_SIZE	0x4000
+
+/*
+ * Network Processing Engines (NPE's) and associated Ethernet MAC's.
+ */
+#define IXP425_NPE_A_HWBASE	(IXP425_IO_HWBASE + IXP425_NPE_A_OFFSET)
+#define IXP425_NPE_A_VBASE	(IXP425_IO_VBASE + IXP425_NPE_A_OFFSET)
+#define IXP425_NPE_A_SIZE	0x1000		/* Actually only 256 bytes */
+
+#define IXP425_NPE_B_HWBASE	(IXP425_IO_HWBASE + IXP425_NPE_B_OFFSET)
+#define IXP425_NPE_B_VBASE	(IXP425_IO_VBASE + IXP425_NPE_B_OFFSET)
+#define IXP425_NPE_B_SIZE	0x1000		/* Actually only 256 bytes */
+
+#define IXP425_NPE_C_HWBASE	(IXP425_IO_HWBASE + IXP425_NPE_C_OFFSET)
+#define IXP425_NPE_C_VBASE	(IXP425_IO_VBASE + IXP425_NPE_C_OFFSET)
+#define IXP425_NPE_C_SIZE	0x1000		/* Actually only 256 bytes */
+
+#define IXP425_MAC_B_HWBASE	(IXP425_IO_HWBASE + IXP425_MAC_B_OFFSET)
+#define IXP425_MAC_B_VBASE	(IXP425_IO_VBASE + IXP425_MAC_B_OFFSET)
+#define IXP425_MAC_B_SIZE	0x1000 		/* Actually only 256 bytes */
+
+#define IXP425_MAC_C_HWBASE	(IXP425_IO_HWBASE + IXP425_MAC_C_OFFSET)
+#define IXP425_MAC_C_VBASE	(IXP425_IO_VBASE + IXP425_MAC_C_OFFSET)
+#define IXP425_MAC_C_SIZE	0x1000		/* Actually only 256 bytes */
+
+#define IXP435_MAC_A_HWBASE	(IXP425_IO_HWBASE + IXP435_MAC_A_OFFSET)
+#define IXP435_MAC_A_VBASE	(IXP425_IO_VBASE + IXP435_MAC_A_OFFSET)
+#define IXP435_MAC_A_SIZE	0x1000 		/* Actually only 256 bytes */
+
+/*
+ * Expansion Bus Data Space.
+ */
+#define	IXP425_EXP_BUS_HWBASE	0x50000000UL
+#define	IXP425_EXP_BUS_SIZE	0x01000000	/* max, typically smaller */
+
+#define	IXP425_EXP_BUS_CSx_HWBASE(i) \
+	(IXP425_EXP_BUS_HWBASE + (i)*IXP425_EXP_BUS_SIZE)
+#define	IXP425_EXP_BUS_CSx_SIZE		0x1000
+#define	IXP425_EXP_BUS_CSx_VBASE(i) \
+	(0xF0011000UL + (((i)-1)*IXP425_EXP_BUS_CSx_SIZE))
+
+/* NB: CS0 is special; it maps flash */
+#define	IXP425_EXP_BUS_CS0_HWBASE	IXP425_EXP_BUS_CSx_HWBASE(0)
+#define IXP425_EXP_BUS_CS0_VBASE	0xFD000000UL
+#ifndef IXP4XX_FLASH_SIZE
+#define IXP425_EXP_BUS_CS0_SIZE		0x01000000	/* NB: 16M */
+#else
+#define IXP425_EXP_BUS_CS0_SIZE		IXP4XX_FLASH_SIZE
+#endif
+#define	IXP425_EXP_BUS_CS1_HWBASE	IXP425_EXP_BUS_CSx_HWBASE(1)
+#define IXP425_EXP_BUS_CS1_VBASE	IXP425_EXP_BUS_CSx_VBASE(1)
+#define IXP425_EXP_BUS_CS1_SIZE		IXP425_EXP_BUS_CSx_SIZE
+#define	IXP425_EXP_BUS_CS2_HWBASE	IXP425_EXP_BUS_CSx_HWBASE(2)
+#define IXP425_EXP_BUS_CS2_VBASE	IXP425_EXP_BUS_CSx_VBASE(2)
+#define IXP425_EXP_BUS_CS2_SIZE		IXP425_EXP_BUS_CSx_SIZE
+#define	IXP425_EXP_BUS_CS3_HWBASE	IXP425_EXP_BUS_CSx_HWBASE(3)
+#define IXP425_EXP_BUS_CS3_VBASE	IXP425_EXP_BUS_CSx_VBASE(3)
+#define IXP425_EXP_BUS_CS3_SIZE		IXP425_EXP_BUS_CSx_SIZE
+#define	IXP425_EXP_BUS_CS4_HWBASE	IXP425_EXP_BUS_CSx_HWBASE(4)
+#define IXP425_EXP_BUS_CS4_VBASE	IXP425_EXP_BUS_CSx_VBASE(4)
+#define IXP425_EXP_BUS_CS4_SIZE		IXP425_EXP_BUS_CSx_SIZE
+
+/* NB: not mapped (yet) */
+#define	IXP425_EXP_BUS_CS5_HWBASE	IXP425_EXP_BUS_CSx_HWBASE(5)
+#define	IXP425_EXP_BUS_CS6_HWBASE	IXP425_EXP_BUS_CSx_HWBASE(6)
+#define	IXP425_EXP_BUS_CS7_HWBASE	IXP425_EXP_BUS_CSx_HWBASE(7)
+
+/*
+ * IXP435/Gateworks Cambria
+ */
+#define IXP435_USB1_HWBASE	0xCD000000UL	/* USB host controller 1 */
+#define IXP435_USB1_VBASE	0xF001C000UL
+#define IXP435_USB1_SIZE	0x1000		/* NB: only uses 0x300 */
+
+#define IXP435_USB2_HWBASE	0xCE000000UL	/* USB host controller 2 */
+#define IXP435_USB2_VBASE	0xF001D000UL
+#define IXP435_USB2_SIZE	0x1000		/* NB: only uses 0x300 */
+
+#define	CAMBRIA_GPS_HWBASE	0x53FC0000UL	/* optional GPS Serial Port */
+#define	CAMBRIA_GPS_VBASE	0xF001E000UL
+#define	CAMBRIA_GPS_SIZE	0x1000
+#define	CAMBRIA_RS485_HWBASE	0x53F80000UL	/* optional RS485 Serial Port */
+#define	CAMBRIA_RS485_VBASE	0xF001F000UL
+#define	CAMBRIA_RS485_SIZE	0x1000
+
+/* NB: these are mapped on the fly, so no fixed virtual addresses */
+#define	CAMBRIA_OCTAL_LED_HWBASE 0x53F40000UL	/* Octal Status LED Latch */
+#define	CAMBRIA_OCTAL_LED_SIZE	0x1000
+#define	CAMBRIA_CFSEL1_HWBASE	0x53E40000UL	/* Compact Flash Socket Sel 0 */
+#define	CAMBRIA_CFSEL1_SIZE	0x40000
+#define	CAMBRIA_CFSEL0_HWBASE	0x53E00000UL	/* Compact Flash Socket Sel 1 */
+#define	CAMBRIA_CFSEL0_SIZE	0x40000
+
+#endif /* _IXP425REG_H_ */


Property changes on: trunk/sys/arm/xscale/ixp425/ixp425reg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/ixp425/ixp425var.h
===================================================================
--- trunk/sys/arm/xscale/ixp425/ixp425var.h	                        (rev 0)
+++ trunk/sys/arm/xscale/ixp425/ixp425var.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,129 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: ixp425var.h,v 1.10 2006/04/10 03:36:03 simonb Exp $ */
+
+/*
+ * Copyright (c) 2003
+ *	Ichiro FUKUHARA <ichiro at ichiro.org>.
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Ichiro FUKUHARA.
+ * 4. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ICHIRO FUKUHARA ``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 ICHIRO FUKUHARA OR THE VOICES IN HIS HEAD 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: stable/10/sys/arm/xscale/ixp425/ixp425var.h 229125 2011-12-31 15:53:34Z marius $
+ *
+ */
+
+#ifndef _IXP425VAR_H_
+#define _IXP425VAR_H_
+
+#include <sys/conf.h>
+#include <sys/queue.h>
+
+#include <machine/bus.h>
+
+#include <sys/rman.h>
+
+/* NB: cputype is setup by set_cpufuncs */
+#define	cpu_is_ixp42x()	(cputype == CPU_ID_IXP425)
+#define	cpu_is_ixp43x()	(cputype == CPU_ID_IXP435)
+#define	cpu_is_ixp46x()	(cputype == CPU_ID_IXP465)
+
+struct ixp425_softc {
+	device_t sc_dev;
+	bus_space_tag_t sc_iot;
+	bus_space_handle_t sc_gpio_ioh;
+	bus_space_handle_t sc_exp_ioh;
+
+	u_int32_t sc_intrmask;
+
+	struct rman sc_irq_rman;
+	struct rman sc_mem_rman;
+	bus_dma_tag_t sc_dmat;
+};
+
+void	ixp425_set_gpio(struct ixp425_softc *sc, int pin, int type);
+
+struct ixppcib_softc {
+	device_t                sc_dev;
+	
+	u_int                   sc_bus;
+	
+	struct resource         *sc_csr;
+	struct resource         *sc_mem;
+	
+	struct rman             sc_io_rman;
+	struct rman             sc_mem_rman;
+	struct rman             sc_irq_rman;
+	
+	struct bus_space        sc_pci_memt;
+	struct bus_space        sc_pci_iot;
+	bus_dma_tag_t 		sc_dmat;
+};
+
+#define EXP_BUS_WRITE_4(sc, reg, data) \
+	bus_space_write_4(sc->sc_iot, sc->sc_exp_ioh, reg, data)
+#define EXP_BUS_READ_4(sc, reg) \
+	bus_space_read_4(sc->sc_iot, sc->sc_exp_ioh, reg)
+
+#define	GPIO_CONF_WRITE_4(sc, reg, data)	\
+	bus_space_write_4(sc->sc_iot, sc->sc_gpio_ioh, reg, data)
+#define	GPIO_CONF_READ_4(sc, reg) \
+	bus_space_read_4(sc->sc_iot, sc->sc_gpio_ioh, reg)
+#define	IXP4XX_GPIO_LOCK()	mtx_lock(&ixp425_gpio_mtx)
+#define	IXP4XX_GPIO_UNLOCK()	mtx_unlock(&ixp425_gpio_mtx)
+extern struct mtx ixp425_gpio_mtx;
+
+extern struct bus_space ixp425_bs_tag;
+extern struct bus_space ixp425_a4x_bs_tag;
+
+extern struct bus_space cambria_exp_bs_tag;
+void	cambria_exp_bus_init(struct ixp425_softc *);
+
+void	ixp425_io_bs_init(bus_space_tag_t, void *);
+void	ixp425_mem_bs_init(bus_space_tag_t, void *);
+
+uint32_t ixp425_sdram_size(void);
+uint32_t ixp435_ddram_size(void);
+uint32_t ixp4xx_read_feature_bits(void);
+void	ixp4xx_write_feature_bits(uint32_t);
+
+int	ixp425_md_route_interrupt(device_t, device_t, int);
+void	ixp425_md_attach(device_t);
+
+int	getvbase(uint32_t, uint32_t, uint32_t *);
+
+struct ixp425_ivar {
+	uint32_t	addr;
+	int		irq;
+};
+#define	IXP425_IVAR(d)	((struct ixp425_ivar *) device_get_ivars(d))
+
+enum {
+	IXP425_IVAR_ADDR,		/* base physical address */
+	IXP425_IVAR_IRQ			/* irq/gpio pin assignment */
+};
+#endif /* _IXP425VAR_H_ */


Property changes on: trunk/sys/arm/xscale/ixp425/ixp425var.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/ixp425/std.avila
===================================================================
--- trunk/sys/arm/xscale/ixp425/std.avila	                        (rev 0)
+++ trunk/sys/arm/xscale/ixp425/std.avila	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,21 @@
+#$FreeBSD: stable/10/sys/arm/xscale/ixp425/std.avila 266110 2014-05-15 02:41:23Z ian $
+
+#
+# Gateworks GW23XX board configuration
+#
+files		"../xscale/ixp425/files.avila"
+#
+# Physical memory starts at 0.  We assume images are loaded at
+# 0x200000, e.g. from redboot with load -b 0x200000 kernel.
+#
+# Redboot is expected to handle unmapping the flash memory that
+# appears at 0 on boot.  Likewise we expect the expansion bus to
+# be remapped away from 0.
+#
+options		PHYSADDR=0x00000000
+options		KERNPHYSADDR=0x00200000
+makeoptions	KERNPHYSADDR=0x00200000
+options		KERNVIRTADDR=0xc0200000		# Used in ldscript.arm
+makeoptions	KERNVIRTADDR=0xc0200000
+options		FLASHADDR=0x50000000
+options		LOADERRAMADDR=0x00000000


Property changes on: trunk/sys/arm/xscale/ixp425/std.avila
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/xscale/ixp425/std.ixp425
===================================================================
--- trunk/sys/arm/xscale/ixp425/std.ixp425	                        (rev 0)
+++ trunk/sys/arm/xscale/ixp425/std.ixp425	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,5 @@
+#XScale IXP425 generic configuration
+#$FreeBSD: stable/10/sys/arm/xscale/ixp425/std.ixp425 239362 2012-08-18 05:48:19Z andrew $
+files		"../xscale/ixp425/files.ixp425"
+include		"../xscale/std.xscale-be"
+cpu 		CPU_XSCALE_IXP425


Property changes on: trunk/sys/arm/xscale/ixp425/std.ixp425
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/xscale/ixp425/std.ixp435
===================================================================
--- trunk/sys/arm/xscale/ixp425/std.ixp435	                        (rev 0)
+++ trunk/sys/arm/xscale/ixp425/std.ixp435	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,7 @@
+#XScale IXP435 generic configuration
+#$FreeBSD: stable/10/sys/arm/xscale/ixp425/std.ixp435 239362 2012-08-18 05:48:19Z andrew $
+
+files		"../xscale/ixp425/files.ixp425"
+include		"../xscale/std.xscale-be"
+cpu 		CPU_XSCALE_IXP435
+cpu 		CPU_XSCALE_IXP425


Property changes on: trunk/sys/arm/xscale/ixp425/std.ixp435
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/xscale/ixp425/uart_bus_ixp425.c
===================================================================
--- trunk/sys/arm/xscale/ixp425/uart_bus_ixp425.c	                        (rev 0)
+++ trunk/sys/arm/xscale/ixp425/uart_bus_ixp425.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,83 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2006 Kevin Lo.  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 ``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 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: stable/10/sys/arm/xscale/ixp425/uart_bus_ixp425.c 194668 2009-06-22 22:46:37Z sam $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
+#include <machine/resource.h>
+
+#include <dev/pci/pcivar.h>
+#include <dev/ic/ns16550.h>
+
+#include <dev/uart/uart.h>
+#include <dev/uart/uart_bus.h>
+#include <dev/uart/uart_cpu.h>
+
+#include <arm/xscale/ixp425/ixp425reg.h>
+#include <arm/xscale/ixp425/ixp425var.h>
+
+#include "uart_if.h"
+
+static int uart_ixp425_probe(device_t dev);
+
+static device_method_t uart_ixp425_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		uart_ixp425_probe),
+	DEVMETHOD(device_attach,	uart_bus_attach),
+	DEVMETHOD(device_detach,	uart_bus_detach),
+	{ 0, 0 }
+};
+
+static driver_t uart_ixp425_driver = {
+	uart_driver_name,
+	uart_ixp425_methods,
+	sizeof(struct uart_softc),
+};
+DRIVER_MODULE(uart, ixp, uart_ixp425_driver, uart_devclass, 0, 0);
+
+static int
+uart_ixp425_probe(device_t dev)
+{
+	struct uart_softc *sc;
+	int unit = device_get_unit(dev);
+	u_int rclk;
+
+	sc = device_get_softc(dev);
+	sc->sc_class = &uart_ns8250_class;
+	if (resource_int_value("uart", unit, "rclk", &rclk))
+		rclk = IXP425_UART_FREQ;
+	if (bootverbose)
+		device_printf(dev, "rclk %u\n", rclk);
+
+	return uart_bus_probe(dev, 0, rclk, 0, 0);
+}


Property changes on: trunk/sys/arm/xscale/ixp425/uart_bus_ixp425.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/ixp425/uart_cpu_ixp425.c
===================================================================
--- trunk/sys/arm/xscale/ixp425/uart_cpu_ixp425.c	                        (rev 0)
+++ trunk/sys/arm/xscale/ixp425/uart_cpu_ixp425.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,97 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2003 Marcel Moolenaar
+ * 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 ``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 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: stable/10/sys/arm/xscale/ixp425/uart_cpu_ixp425.c 170109 2007-05-29 18:10:42Z jhay $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/cons.h>
+#include <machine/bus.h>
+
+#include <dev/uart/uart.h>
+#include <dev/uart/uart_cpu.h>
+
+#include <arm/xscale/ixp425/ixp425reg.h>
+#include <arm/xscale/ixp425/ixp425var.h>
+
+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)
+{
+	uint32_t i, ivar, vaddr;
+
+	/*
+	 * Scan the hints. The IXP425 only have 2 serial ports, so only
+	 * scan them.
+	 */
+	for (i = 0; i < 2; i++) {
+		if (resource_int_value("uart", i, "flags", &ivar))
+			continue;
+		if (devtype == UART_DEV_CONSOLE && !UART_FLAGS_CONSOLE(ivar))
+			continue;
+		if (devtype == UART_DEV_DBGPORT && !UART_FLAGS_DBGPORT(ivar))
+			continue;
+		/*
+		 * We have a possible device. Make sure it's enabled and
+		 * that we have an I/O port.
+		 */
+		if (resource_int_value("uart", i, "disabled", &ivar) == 0 &&
+		    ivar != 0)
+			continue;
+		if (resource_int_value("uart", i, "addr", &ivar) != 0 ||
+		    ivar == 0)
+			continue;
+		/* Got it. Fill in the instance and return it. */
+		di->ops = uart_getops(&uart_ns8250_class);
+		di->bas.chan = 0;
+		di->bas.bst = &ixp425_a4x_bs_tag;
+		di->bas.regshft = 0;
+		di->bas.rclk = IXP425_UART_FREQ;
+		di->baudrate = 115200;
+		di->databits = 8;
+		di->stopbits = 1;
+		di->parity = UART_PARITY_NONE;
+		uart_bus_space_io = NULL;
+		uart_bus_space_mem = &ixp425_a4x_bs_tag;
+
+		getvbase(ivar, IXP425_REG_SIZE, &vaddr);
+		di->bas.bsh = vaddr;
+		return (0);
+	}
+
+	return (ENXIO);
+}


Property changes on: trunk/sys/arm/xscale/ixp425/uart_cpu_ixp425.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/pxa/files.pxa
===================================================================
--- trunk/sys/arm/xscale/pxa/files.pxa	                        (rev 0)
+++ trunk/sys/arm/xscale/pxa/files.pxa	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,17 @@
+# $FreeBSD: stable/10/sys/arm/xscale/pxa/files.pxa 266311 2014-05-17 13:53:38Z ian $
+
+arm/arm/bus_space_generic.c		standard
+arm/arm/cpufunc_asm_xscale.S		standard
+
+arm/xscale/pxa/pxa_gpio.c		standard
+arm/xscale/pxa/pxa_icu.c		standard
+arm/xscale/pxa/pxa_machdep.c		standard
+arm/xscale/pxa/pxa_obio.c		standard
+arm/xscale/pxa/pxa_smi.c		standard
+arm/xscale/pxa/pxa_space.c		standard
+arm/xscale/pxa/pxa_timer.c		standard
+
+arm/xscale/pxa/uart_bus_pxa.c		optional uart
+arm/xscale/pxa/uart_cpu_pxa.c		optional uart
+
+arm/xscale/pxa/if_smc_smi.c		optional smc


Property changes on: trunk/sys/arm/xscale/pxa/files.pxa
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/xscale/pxa/if_smc_smi.c
===================================================================
--- trunk/sys/arm/xscale/pxa/if_smc_smi.c	                        (rev 0)
+++ trunk/sys/arm/xscale/pxa/if_smc_smi.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,126 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2008 Benno Rice
+ * 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 ``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 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: stable/10/sys/arm/xscale/pxa/if_smc_smi.c 259342 2013-12-13 22:08:31Z ian $");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/socket.h>
+#include <sys/systm.h>
+#include <sys/taskqueue.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+
+#include <net/ethernet.h>
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <net/if_media.h>
+
+#include <dev/smc/if_smcvar.h>
+
+#include <dev/mii/mii.h>
+#include <dev/mii/miivar.h>
+
+#include "miibus_if.h"
+
+#include <arm/xscale/pxa/pxareg.h>
+#include <arm/xscale/pxa/pxavar.h>
+
+static int		smc_smi_probe(device_t);
+static int		smc_smi_attach(device_t);
+static int		smc_smi_detach(device_t);
+
+static int
+smc_smi_probe(device_t dev)
+{
+	struct	smc_softc *sc;
+
+	sc = device_get_softc(dev);
+	sc->smc_usemem = 1;
+
+	if (smc_probe(dev) != 0) {
+		return (ENXIO);
+	}
+	return (0);
+}
+
+static int
+smc_smi_attach(device_t dev)
+{
+	int	err;
+ 	struct	smc_softc *sc;
+
+	sc = device_get_softc(dev);
+
+	err = smc_attach(dev);
+	if (err) {
+		return (err);
+	}
+
+	return (0);
+}
+
+static int
+smc_smi_detach(device_t dev)
+{
+
+	smc_detach(dev);
+
+	return (0);
+}
+
+static device_method_t smc_smi_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		smc_smi_probe),
+	DEVMETHOD(device_attach,	smc_smi_attach),
+	DEVMETHOD(device_detach,	smc_smi_detach),
+
+	/* MII interface */
+	DEVMETHOD(miibus_readreg,	smc_miibus_readreg),
+	DEVMETHOD(miibus_writereg,	smc_miibus_writereg),
+	DEVMETHOD(miibus_statchg,	smc_miibus_statchg),
+
+	{ 0, 0 }
+};
+
+static driver_t smc_smi_driver = {
+	"smc",
+	smc_smi_methods,
+	sizeof(struct smc_softc),
+};
+
+extern devclass_t smc_devclass;
+
+DRIVER_MODULE(smc, smi, smc_smi_driver, smc_devclass, 0, 0);
+DRIVER_MODULE(miibus, smc, miibus_driver, miibus_devclass, 0, 0);
+MODULE_DEPEND(smc, smi, 1, 1, 1);
+MODULE_DEPEND(smc, ether, 1, 1, 1);
+MODULE_DEPEND(smc, miibus, 1, 1, 1);


Property changes on: trunk/sys/arm/xscale/pxa/if_smc_smi.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/pxa/pxa_gpio.c
===================================================================
--- trunk/sys/arm/xscale/pxa/pxa_gpio.c	                        (rev 0)
+++ trunk/sys/arm/xscale/pxa/pxa_gpio.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,359 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2006 Benno Rice.  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 ``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 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: stable/10/sys/arm/xscale/pxa/pxa_gpio.c 179595 2008-06-06 05:08:09Z benno $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/interrupt.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/mutex.h>
+#include <sys/rman.h>
+#include <sys/queue.h>
+#include <sys/taskqueue.h>
+#include <sys/timetc.h>
+#include <machine/bus.h>
+#include <machine/intr.h>
+
+#include <arm/xscale/pxa/pxavar.h>
+#include <arm/xscale/pxa/pxareg.h>
+
+struct pxa_gpio_softc {
+	struct resource *	pg_res[4];
+	bus_space_tag_t		pg_bst;
+	bus_space_handle_t	pg_bsh;
+	struct mtx		pg_mtx;
+
+	uint32_t		pg_intr[3];
+};
+
+static struct resource_spec pxa_gpio_spec[] = {
+	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		0,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		1,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		2,	RF_ACTIVE },
+	{ -1, 0 }
+};
+
+static struct pxa_gpio_softc *pxa_gpio_softc = NULL;
+
+static int	pxa_gpio_probe(device_t);
+static int	pxa_gpio_attach(device_t);
+
+static driver_filter_t	pxa_gpio_intr0;
+static driver_filter_t	pxa_gpio_intr1;
+static driver_filter_t	pxa_gpio_intrN;
+
+static int
+pxa_gpio_probe(device_t dev)
+{
+	
+	device_set_desc(dev, "GPIO Controller");
+	return (0);
+}
+
+static int
+pxa_gpio_attach(device_t dev)
+{
+	int	error;
+	void	*ihl;
+	struct	pxa_gpio_softc *sc;
+	
+	sc = (struct pxa_gpio_softc *)device_get_softc(dev);
+	
+	if (pxa_gpio_softc != NULL)
+		return (ENXIO);
+	pxa_gpio_softc = sc;
+	
+	error = bus_alloc_resources(dev, pxa_gpio_spec, sc->pg_res);
+	if (error) {
+		device_printf(dev, "could not allocate resources\n");
+		return (ENXIO);
+	}
+	
+	sc->pg_bst = rman_get_bustag(sc->pg_res[0]);
+	sc->pg_bsh = rman_get_bushandle(sc->pg_res[0]);
+	
+	/* Disable and clear all interrupts. */
+	bus_space_write_4(sc->pg_bst, sc->pg_bsh, GPIO_GRER0, 0);
+	bus_space_write_4(sc->pg_bst, sc->pg_bsh, GPIO_GRER1, 0);
+	bus_space_write_4(sc->pg_bst, sc->pg_bsh, GPIO_GRER2, 0);
+	bus_space_write_4(sc->pg_bst, sc->pg_bsh, GPIO_GFER0, 0);
+	bus_space_write_4(sc->pg_bst, sc->pg_bsh, GPIO_GFER1, 0);
+	bus_space_write_4(sc->pg_bst, sc->pg_bsh, GPIO_GFER2, 0);
+	bus_space_write_4(sc->pg_bst, sc->pg_bsh, GPIO_GEDR0, ~0);
+	bus_space_write_4(sc->pg_bst, sc->pg_bsh, GPIO_GEDR1, ~0);
+	bus_space_write_4(sc->pg_bst, sc->pg_bsh, GPIO_GEDR2, ~0);
+	
+	mtx_init(&sc->pg_mtx, "GPIO mutex", NULL, MTX_SPIN);
+	
+	if (bus_setup_intr(dev, sc->pg_res[1], INTR_TYPE_MISC|INTR_MPSAFE,
+	    pxa_gpio_intr0, NULL, sc, &ihl) != 0) {
+		bus_release_resources(dev, pxa_gpio_spec, sc->pg_res);
+		device_printf(dev, "could not set up intr0\n");
+		return (ENXIO);
+	}
+	
+	if (bus_setup_intr(dev, sc->pg_res[2], INTR_TYPE_MISC|INTR_MPSAFE,
+	    pxa_gpio_intr1, NULL, sc, &ihl) != 0) {
+		bus_release_resources(dev, pxa_gpio_spec, sc->pg_res);
+		device_printf(dev, "could not set up intr1\n");
+		return (ENXIO);
+	}
+	
+	if (bus_setup_intr(dev, sc->pg_res[3], INTR_TYPE_MISC|INTR_MPSAFE,
+	    pxa_gpio_intrN, NULL, sc, &ihl) != 0) {
+		bus_release_resources(dev, pxa_gpio_spec, sc->pg_res);
+		device_printf(dev, "could not set up intrN\n");
+		return (ENXIO);
+	}
+	
+	return (0);
+}
+
+static int
+pxa_gpio_intr0(void *arg)
+{
+	struct	pxa_gpio_softc *sc;
+	
+	sc = (struct pxa_gpio_softc *)arg;
+	
+	bus_space_write_4(sc->pg_bst, sc->pg_bsh, GPIO_GEDR0, 0x1);
+	sc->pg_intr[0] |= 1;
+	
+	return (FILTER_HANDLED);
+}
+
+static int
+pxa_gpio_intr1(void *arg)
+{
+	struct	pxa_gpio_softc *sc;
+	
+	sc = (struct pxa_gpio_softc *)arg;
+	
+	bus_space_write_4(sc->pg_bst, sc->pg_bsh, GPIO_GEDR0, 0x2);
+	sc->pg_intr[1] |= 2;
+	
+	return (FILTER_HANDLED);
+}
+
+static int
+pxa_gpio_intrN(void *arg)
+{
+	uint32_t	gedr0, gedr1, gedr2;
+	struct		pxa_gpio_softc *sc;
+	
+	sc = (struct pxa_gpio_softc *)arg;
+	
+	gedr0 = bus_space_read_4(sc->pg_bst, sc->pg_bsh, GPIO_GEDR0);
+	gedr0 &= 0xfffffffc;
+	bus_space_write_4(sc->pg_bst, sc->pg_bsh, GPIO_GEDR0, gedr0);
+	
+	gedr1 = bus_space_read_4(sc->pg_bst, sc->pg_bsh, GPIO_GEDR1);
+	bus_space_write_4(sc->pg_bst, sc->pg_bsh, GPIO_GEDR1, gedr1);
+	
+	gedr2 = bus_space_read_4(sc->pg_bst, sc->pg_bsh, GPIO_GEDR2);
+	gedr2 &= 0x001fffff;
+	bus_space_write_4(sc->pg_bst, sc->pg_bsh, GPIO_GEDR2, gedr2);
+	
+	sc->pg_intr[0] |= gedr0;
+	sc->pg_intr[1] |= gedr1;
+	sc->pg_intr[2] |= gedr2;
+	
+	return (FILTER_HANDLED);
+}
+
+static device_method_t pxa_gpio_methods[] = {
+	DEVMETHOD(device_probe, pxa_gpio_probe),
+	DEVMETHOD(device_attach, pxa_gpio_attach),
+	
+	{0, 0}
+};
+
+static driver_t pxa_gpio_driver = {
+	"gpio",
+	pxa_gpio_methods,
+	sizeof(struct pxa_gpio_softc),
+};
+
+static devclass_t pxa_gpio_devclass;
+
+DRIVER_MODULE(pxagpio, pxa, pxa_gpio_driver, pxa_gpio_devclass, 0, 0);
+
+#define	pxagpio_reg_read(softc, reg)		\
+	bus_space_read_4(sc->pg_bst, sc->pg_bsh, reg)
+#define	pxagpio_reg_write(softc, reg, val)	\
+	bus_space_write_4(sc->pg_bst, sc->pg_bsh, reg, val)
+
+uint32_t
+pxa_gpio_get_function(int gpio)
+{
+	struct		pxa_gpio_softc *sc;
+	uint32_t	rv, io;
+	
+	sc = pxa_gpio_softc;
+	
+	rv = pxagpio_reg_read(sc, GPIO_FN_REG(gpio)) >> GPIO_FN_SHIFT(gpio);
+	rv = GPIO_FN(rv);
+	
+	io = pxagpio_reg_read(sc, PXA250_GPIO_REG(GPIO_GPDR0, gpio));
+	if (io & GPIO_BIT(gpio))
+		rv |= GPIO_OUT;
+	
+	io = pxagpio_reg_read(sc, PXA250_GPIO_REG(GPIO_GPLR0, gpio));
+	if (io & GPIO_BIT(gpio))
+		rv |= GPIO_SET;
+	
+	return (rv);
+}
+
+uint32_t
+pxa_gpio_set_function(int gpio, uint32_t fn)
+{
+	struct		pxa_gpio_softc *sc;
+	uint32_t	rv, bit, oldfn;
+	
+	sc = pxa_gpio_softc;
+	
+	oldfn = pxa_gpio_get_function(gpio);
+	
+	if (GPIO_FN(fn) == GPIO_FN(oldfn) &&
+	    GPIO_FN_IS_OUT(fn) == GPIO_FN_IS_OUT(oldfn)) {
+		/*
+		 * The pin's function is not changing.
+		 * For Alternate Functions and GPIO input, we can just
+		 * return now.
+		 * For GPIO output pins, check the initial state is
+		 * the same.
+		 *
+		 * Return 'fn' instead of 'oldfn' so the caller can
+		 * reliably detect that we didn't change anything.
+		 * (The initial state might be different for non-
+		 * GPIO output pins).
+		 */
+		if (!GPIO_IS_GPIO_OUT(fn) ||
+		    GPIO_FN_IS_SET(fn) == GPIO_FN_IS_SET(oldfn))
+			return (fn);
+	}
+	
+	/*
+	 * See section 4.1.3.7 of the PXA2x0 Developer's Manual for
+	 * the correct procedure for changing GPIO pin functions.
+	 */
+	
+	bit = GPIO_BIT(gpio);
+	
+	/*
+	 * 1. Configure the correct set/clear state of the pin
+	 */
+	if (GPIO_FN_IS_SET(fn))
+		pxagpio_reg_write(sc, PXA250_GPIO_REG(GPIO_GPSR0, gpio), bit);
+	else
+		pxagpio_reg_write(sc, PXA250_GPIO_REG(GPIO_GPCR0, gpio), bit);
+	
+	/*
+	 * 2. Configure the pin as an input or output as appropriate
+	 */
+	rv = pxagpio_reg_read(sc, PXA250_GPIO_REG(GPIO_GPDR0, gpio)) & ~bit;
+	if (GPIO_FN_IS_OUT(fn))
+		rv |= bit;
+	pxagpio_reg_write(sc, PXA250_GPIO_REG(GPIO_GPDR0, gpio), rv);
+	
+	/*
+	 * 3. Configure the pin's function
+	 */
+	bit = GPIO_FN_MASK << GPIO_FN_SHIFT(gpio);
+	fn = GPIO_FN(fn) << GPIO_FN_SHIFT(gpio);
+	rv = pxagpio_reg_read(sc, GPIO_FN_REG(gpio)) & ~bit;
+	pxagpio_reg_write(sc, GPIO_FN_REG(gpio), rv | fn);
+	
+	return (oldfn);
+}
+
+/*
+ * GPIO "interrupt" handling.
+ */
+
+void
+pxa_gpio_mask_irq(int irq)
+{
+	uint32_t	val;
+	struct		pxa_gpio_softc *sc;
+	int		gpio;
+	
+	sc = pxa_gpio_softc;
+	gpio = IRQ_TO_GPIO(irq);
+	
+	val = pxagpio_reg_read(sc, PXA250_GPIO_REG(GPIO_GRER0, gpio));
+	val &= ~GPIO_BIT(gpio);
+	pxagpio_reg_write(sc, PXA250_GPIO_REG(GPIO_GRER0, gpio), val);
+}
+
+void
+pxa_gpio_unmask_irq(int irq)
+{
+	uint32_t	val;
+	struct		pxa_gpio_softc *sc;
+	int		gpio;
+	
+	sc = pxa_gpio_softc;
+	gpio = IRQ_TO_GPIO(irq);
+	
+	val = pxagpio_reg_read(sc, PXA250_GPIO_REG(GPIO_GRER0, gpio));
+	val |= GPIO_BIT(gpio);
+	pxagpio_reg_write(sc, PXA250_GPIO_REG(GPIO_GRER0, gpio), val);
+}
+
+int
+pxa_gpio_get_next_irq()
+{
+	struct  pxa_gpio_softc *sc;
+	int     gpio;
+	
+	sc = pxa_gpio_softc;
+	
+	if (sc->pg_intr[0] != 0) {
+		gpio = ffs(sc->pg_intr[0]) - 1;
+		sc->pg_intr[0] &= ~(1 << gpio);
+		return (GPIO_TO_IRQ(gpio));
+	}
+	if (sc->pg_intr[1] != 0) {
+		gpio = ffs(sc->pg_intr[1]) - 1;
+		sc->pg_intr[1] &= ~(1 << gpio);
+		return (GPIO_TO_IRQ(gpio + 32));
+	}
+	if (sc->pg_intr[2] != 0) {
+		gpio = ffs(sc->pg_intr[2]) - 1;
+		sc->pg_intr[2] &= ~(1 << gpio);
+		return (GPIO_TO_IRQ(gpio + 64));
+	}
+
+	return (-1);
+}


Property changes on: trunk/sys/arm/xscale/pxa/pxa_gpio.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/pxa/pxa_icu.c
===================================================================
--- trunk/sys/arm/xscale/pxa/pxa_icu.c	                        (rev 0)
+++ trunk/sys/arm/xscale/pxa/pxa_icu.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,260 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2006 Benno Rice.  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 ``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 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: stable/10/sys/arm/xscale/pxa/pxa_icu.c 278613 2015-02-12 03:50:33Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/timetc.h>
+#include <machine/armreg.h>
+#include <machine/bus.h>
+#include <machine/intr.h>
+
+#include <arm/xscale/pxa/pxavar.h>
+#include <arm/xscale/pxa/pxareg.h>
+
+struct pxa_icu_softc {
+	struct resource	*	pi_res[1];
+	bus_space_tag_t		pi_bst;
+	bus_space_handle_t	pi_bsh;
+};
+
+static struct resource_spec pxa_icu_spec[] = {
+	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
+	{ -1, 0 }
+};
+
+static struct pxa_icu_softc *pxa_icu_softc = NULL;
+
+static int	pxa_icu_probe(device_t);
+static int	pxa_icu_attach(device_t);
+
+uint32_t	pxa_icu_get_icip(void);
+void		pxa_icu_clear_icip(int);
+uint32_t	pxa_icu_get_icfp(void);
+void		pxa_icu_clear_icfp(int);
+uint32_t	pxa_icu_get_icmr(void);
+void		pxa_icu_set_icmr(uint32_t);
+uint32_t	pxa_icu_get_iclr(void);
+void		pxa_icu_set_iclr(uint32_t);
+uint32_t	pxa_icu_get_icpr(void);
+void		pxa_icu_idle_enable(void);
+void		pxa_icu_idle_disable(void);
+
+extern uint32_t	pxa_gpio_intr_flags[];
+
+static int
+pxa_icu_probe(device_t dev)
+{
+
+	device_set_desc(dev, "Interrupt Controller");
+	return (0);
+}
+
+static int
+pxa_icu_attach(device_t dev)
+{
+	int	error;
+	struct	pxa_icu_softc *sc;
+
+	sc = (struct pxa_icu_softc *)device_get_softc(dev);
+
+	if (pxa_icu_softc != NULL)
+		return (ENXIO);
+	pxa_icu_softc = sc;
+
+	error = bus_alloc_resources(dev, pxa_icu_spec, sc->pi_res);
+	if (error) {
+		device_printf(dev, "could not allocate resources\n");
+		return (ENXIO);
+	}
+
+	sc->pi_bst = rman_get_bustag(sc->pi_res[0]);
+	sc->pi_bsh = rman_get_bushandle(sc->pi_res[0]);
+
+	/* Disable all interrupts. */
+	pxa_icu_set_icmr(0);
+
+	/* Route all interrupts to IRQ rather than FIQ. */
+	pxa_icu_set_iclr(0);
+
+	/* XXX: This should move to configure_final or something. */
+	enable_interrupts(PSR_I|PSR_F);
+
+	return (0);
+}
+
+static device_method_t pxa_icu_methods[] = {
+	DEVMETHOD(device_probe, pxa_icu_probe),
+	DEVMETHOD(device_attach, pxa_icu_attach),
+
+	{0, 0}
+};
+
+static driver_t pxa_icu_driver = {
+	"icu",
+	pxa_icu_methods,
+	sizeof(struct pxa_icu_softc),
+};
+
+static devclass_t pxa_icu_devclass;
+
+DRIVER_MODULE(pxaicu, pxa, pxa_icu_driver, pxa_icu_devclass, 0, 0);
+
+int
+arm_get_next_irq(int last __unused)
+{
+	int	irq;
+
+	if ((irq = pxa_icu_get_icip()) != 0) {
+		return (ffs(irq) - 1);
+	}
+
+	return (pxa_gpio_get_next_irq());
+}
+
+void
+arm_mask_irq(uintptr_t nb)
+{
+	uint32_t	mr;
+
+	if (nb >= IRQ_GPIO0) {
+		pxa_gpio_mask_irq(nb);
+		return;
+	}
+
+	mr = pxa_icu_get_icmr();
+	mr &= ~(1 << nb);
+	pxa_icu_set_icmr(mr);
+}
+
+void
+arm_unmask_irq(uintptr_t nb)
+{
+	uint32_t	mr;
+
+	if (nb >= IRQ_GPIO0) {
+		pxa_gpio_unmask_irq(nb);
+		return;
+	}
+
+	mr = pxa_icu_get_icmr();
+	mr |= (1 << nb);
+	pxa_icu_set_icmr(mr);
+}
+
+uint32_t
+pxa_icu_get_icip()
+{
+
+	return (bus_space_read_4(pxa_icu_softc->pi_bst,
+	    pxa_icu_softc->pi_bsh, ICU_IP));
+}
+
+void
+pxa_icu_clear_icip(int irq)
+{
+
+	bus_space_write_4(pxa_icu_softc->pi_bst,
+	    pxa_icu_softc->pi_bsh, ICU_IP, (1 << irq));
+}
+
+uint32_t
+pxa_icu_get_icfp()
+{
+
+	return (bus_space_read_4(pxa_icu_softc->pi_bst,
+	    pxa_icu_softc->pi_bsh, ICU_FP));
+}
+
+void
+pxa_icu_clear_icfp(int irq)
+{
+
+	bus_space_write_4(pxa_icu_softc->pi_bst,
+	    pxa_icu_softc->pi_bsh, ICU_FP, (1 << irq));
+}
+
+uint32_t
+pxa_icu_get_icmr()
+{
+
+	return (bus_space_read_4(pxa_icu_softc->pi_bst,
+	    pxa_icu_softc->pi_bsh, ICU_MR));
+}
+
+void
+pxa_icu_set_icmr(uint32_t val)
+{
+
+	bus_space_write_4(pxa_icu_softc->pi_bst,
+	    pxa_icu_softc->pi_bsh, ICU_MR, val);
+}
+
+uint32_t
+pxa_icu_get_iclr()
+{
+
+	return (bus_space_read_4(pxa_icu_softc->pi_bst,
+	    pxa_icu_softc->pi_bsh, ICU_LR));
+}
+
+void
+pxa_icu_set_iclr(uint32_t val)
+{
+
+	bus_space_write_4(pxa_icu_softc->pi_bst,
+	    pxa_icu_softc->pi_bsh, ICU_LR, val);
+}
+
+uint32_t
+pxa_icu_get_icpr()
+{
+
+	return (bus_space_read_4(pxa_icu_softc->pi_bst,
+	    pxa_icu_softc->pi_bsh, ICU_PR));
+}
+
+void
+pxa_icu_idle_enable()
+{
+
+	bus_space_write_4(pxa_icu_softc->pi_bst,
+	    pxa_icu_softc->pi_bsh, ICU_CR, 0x0);
+}
+
+void
+pxa_icu_idle_disable()
+{
+
+	bus_space_write_4(pxa_icu_softc->pi_bst,
+	    pxa_icu_softc->pi_bsh, ICU_CR, 0x1);
+}


Property changes on: trunk/sys/arm/xscale/pxa/pxa_icu.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/pxa/pxa_machdep.c
===================================================================
--- trunk/sys/arm/xscale/pxa/pxa_machdep.c	                        (rev 0)
+++ trunk/sys/arm/xscale/pxa/pxa_machdep.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,436 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: hpc_machdep.c,v 1.70 2003/09/16 08:18:22 agc Exp $	*/
+
+/*-
+ * Copyright (c) 1994-1998 Mark Brinicombe.
+ * Copyright (c) 1994 Brini.
+ * All rights reserved.
+ *
+ * This code is derived from software written for Brini by Mark Brinicombe
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by Brini.
+ * 4. The name of the company nor the name of the author may be used to
+ *    endorse or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BRINI ``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 BRINI 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.
+ *
+ * RiscBSD kernel project
+ *
+ * machdep.c
+ *
+ * Machine dependant functions for kernel setup
+ *
+ * This file needs a lot of work.
+ *
+ * Created      : 17/09/94
+ */
+
+#include "opt_ddb.h"
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/xscale/pxa/pxa_machdep.c 266386 2014-05-18 00:32:35Z ian $");
+
+#define _ARM32_BUS_DMA_PRIVATE
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/sysproto.h>
+#include <sys/signalvar.h>
+#include <sys/imgact.h>
+#include <sys/kernel.h>
+#include <sys/ktr.h>
+#include <sys/linker.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/mutex.h>
+#include <sys/pcpu.h>
+#include <sys/proc.h>
+#include <sys/ptrace.h>
+#include <sys/cons.h>
+#include <sys/bio.h>
+#include <sys/bus.h>
+#include <sys/buf.h>
+#include <sys/exec.h>
+#include <sys/kdb.h>
+#include <sys/msgbuf.h>
+#include <machine/reg.h>
+#include <machine/cpu.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/vm_object.h>
+#include <vm/vm_page.h>
+#include <vm/vm_map.h>
+#include <machine/devmap.h>
+#include <machine/vmparam.h>
+#include <machine/pcb.h>
+#include <machine/undefined.h>
+#include <machine/machdep.h>
+#include <machine/metadata.h>
+#include <machine/armreg.h>
+#include <machine/bus.h>
+#include <machine/physmem.h>
+#include <sys/reboot.h>
+
+#include <arm/xscale/pxa/pxareg.h>
+#include <arm/xscale/pxa/pxavar.h>
+
+#define KERNEL_PT_SYS		0	/* Page table for mapping proc0 zero page */
+#define	KERNEL_PT_IOPXS		1
+#define KERNEL_PT_BEFOREKERN	2
+#define KERNEL_PT_AFKERNEL	3	/* L2 table for mapping after kernel */
+#define	KERNEL_PT_AFKERNEL_NUM	9
+
+/* this should be evenly divisable by PAGE_SIZE / L2_TABLE_SIZE_REAL (or 4) */
+#define NUM_KERNEL_PTS		(KERNEL_PT_AFKERNEL + KERNEL_PT_AFKERNEL_NUM)
+
+struct pv_addr kernel_pt_table[NUM_KERNEL_PTS];
+
+/* Physical and virtual addresses for some global pages */
+
+struct pv_addr systempage;
+struct pv_addr msgbufpv;
+struct pv_addr irqstack;
+struct pv_addr undstack;
+struct pv_addr abtstack;
+struct pv_addr kernelstack;
+struct pv_addr minidataclean;
+
+static void	pxa_probe_sdram(bus_space_tag_t, bus_space_handle_t,
+		    uint32_t *, uint32_t *);
+
+/* Static device mappings. */
+static const struct arm_devmap_entry pxa_devmap[] = {
+	/*
+	 * Map the on-board devices up into the KVA region so we don't muck
+	 * up user-space.
+	 */
+	{
+		PXA2X0_PERIPH_START + PXA2X0_PERIPH_OFFSET,
+		PXA2X0_PERIPH_START,
+		PXA250_PERIPH_END - PXA2X0_PERIPH_START,
+		VM_PROT_READ|VM_PROT_WRITE,
+		PTE_DEVICE,
+	},
+	{ 0, 0, 0, 0, 0, }
+};
+
+#define SDRAM_START 0xa0000000
+
+extern vm_offset_t xscale_cache_clean_addr;
+
+void *
+initarm(struct arm_boot_params *abp)
+{
+	struct pv_addr  kernel_l1pt;
+	struct pv_addr  dpcpu;
+	int loop;
+	u_int l1pagetable;
+	vm_offset_t freemempos;
+	vm_offset_t freemem_pt;
+	vm_offset_t afterkern;
+	vm_offset_t freemem_after;
+	vm_offset_t lastaddr;
+	int i, j;
+	uint32_t memsize[PXA2X0_SDRAM_BANKS], memstart[PXA2X0_SDRAM_BANKS];
+
+	lastaddr = parse_boot_param(abp);
+	arm_physmem_kernaddr = abp->abp_physaddr;
+	set_cpufuncs();
+	pcpu_init(pcpup, 0, sizeof(struct pcpu));
+	PCPU_SET(curthread, &thread0);
+
+	/* Do basic tuning, hz etc */
+	init_param1();
+
+	freemempos = 0xa0200000;
+	/* Define a macro to simplify memory allocation */
+#define	valloc_pages(var, np)			\
+	alloc_pages((var).pv_pa, (np));		\
+	(var).pv_va = (var).pv_pa + 0x20000000;
+
+#define alloc_pages(var, np)			\
+	freemempos -= (np * PAGE_SIZE);		\
+	(var) = freemempos;		\
+	memset((char *)(var), 0, ((np) * PAGE_SIZE));
+
+	while (((freemempos - L1_TABLE_SIZE) & (L1_TABLE_SIZE - 1)) != 0)
+		freemempos -= PAGE_SIZE;
+	valloc_pages(kernel_l1pt, L1_TABLE_SIZE / PAGE_SIZE);
+	for (loop = 0; loop < NUM_KERNEL_PTS; ++loop) {
+		if (!(loop % (PAGE_SIZE / L2_TABLE_SIZE_REAL))) {
+			valloc_pages(kernel_pt_table[loop],
+			    L2_TABLE_SIZE / PAGE_SIZE);
+		} else {
+			kernel_pt_table[loop].pv_pa = freemempos +
+			    (loop % (PAGE_SIZE / L2_TABLE_SIZE_REAL)) *
+			    L2_TABLE_SIZE_REAL;
+			kernel_pt_table[loop].pv_va =
+			    kernel_pt_table[loop].pv_pa + 0x20000000;
+		}
+	}
+	freemem_pt = freemempos;
+	freemempos = 0xa0100000;
+	/*
+	 * Allocate a page for the system page mapped to V0x00000000
+	 * This page will just contain the system vectors and can be
+	 * shared by all processes.
+	 */
+	valloc_pages(systempage, 1);
+
+	/* Allocate dynamic per-cpu area. */
+	valloc_pages(dpcpu, DPCPU_SIZE / PAGE_SIZE);
+	dpcpu_init((void *)dpcpu.pv_va, 0);
+
+	/* Allocate stacks for all modes */
+	valloc_pages(irqstack, IRQ_STACK_SIZE);
+	valloc_pages(abtstack, ABT_STACK_SIZE);
+	valloc_pages(undstack, UND_STACK_SIZE);
+	valloc_pages(kernelstack, KSTACK_PAGES);
+	alloc_pages(minidataclean.pv_pa, 1);
+	valloc_pages(msgbufpv, round_page(msgbufsize) / PAGE_SIZE);
+	/*
+	 * Allocate memory for the l1 and l2 page tables. The scheme to avoid
+	 * wasting memory by allocating the l1pt on the first 16k memory was
+	 * taken from NetBSD rpc_machdep.c. NKPT should be greater than 12 for
+	 * this to work (which is supposed to be the case).
+	 */
+
+	/*
+	 * Now we start construction of the L1 page table
+	 * We start by mapping the L2 page tables into the L1.
+	 * This means that we can replace L1 mappings later on if necessary
+	 */
+	l1pagetable = kernel_l1pt.pv_va;
+
+	/* Map the L2 pages tables in the L1 page table */
+	pmap_link_l2pt(l1pagetable, ARM_VECTORS_HIGH & ~(0x00100000 - 1),
+	    &kernel_pt_table[KERNEL_PT_SYS]);
+#if 0 /* XXXBJR: What is this?  Don't know if there's an analogue. */
+	pmap_link_l2pt(l1pagetable, IQ80321_IOPXS_VBASE,
+	                &kernel_pt_table[KERNEL_PT_IOPXS]);
+#endif
+	pmap_link_l2pt(l1pagetable, KERNBASE,
+	    &kernel_pt_table[KERNEL_PT_BEFOREKERN]);
+	pmap_map_chunk(l1pagetable, KERNBASE, SDRAM_START, 0x100000,
+	    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+	pmap_map_chunk(l1pagetable, KERNBASE + 0x100000, SDRAM_START + 0x100000,
+	    0x100000, VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE);
+	pmap_map_chunk(l1pagetable, KERNBASE + 0x200000, SDRAM_START + 0x200000,
+	   (((uint32_t)(lastaddr) - KERNBASE - 0x200000) + L1_S_SIZE) & ~(L1_S_SIZE - 1),
+	    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+	freemem_after = ((int)lastaddr + PAGE_SIZE) & ~(PAGE_SIZE - 1);
+	afterkern = round_page(((vm_offset_t)lastaddr + L1_S_SIZE) &
+	    ~(L1_S_SIZE - 1));
+	for (i = 0; i < KERNEL_PT_AFKERNEL_NUM; i++) {
+		pmap_link_l2pt(l1pagetable, afterkern + i * 0x00100000,
+		    &kernel_pt_table[KERNEL_PT_AFKERNEL + i]);
+	}
+	pmap_map_entry(l1pagetable, afterkern, minidataclean.pv_pa,
+	    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+
+
+	/* Map the Mini-Data cache clean area. */
+	xscale_setup_minidata(l1pagetable, afterkern,
+	    minidataclean.pv_pa);
+
+	/* Map the vector page. */
+	pmap_map_entry(l1pagetable, ARM_VECTORS_HIGH, systempage.pv_pa,
+	    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+	arm_devmap_bootstrap(l1pagetable, pxa_devmap);
+
+	/*
+	 * Give the XScale global cache clean code an appropriately
+	 * sized chunk of unmapped VA space starting at 0xff000000
+	 * (our device mappings end before this address).
+	 */
+	xscale_cache_clean_addr = 0xff000000U;
+
+	cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT);
+	setttb(kernel_l1pt.pv_pa);
+	cpu_tlb_flushID();
+	cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2));
+
+	/*
+	 * Pages were allocated during the secondary bootstrap for the
+	 * stacks for different CPU modes.
+	 * We must now set the r13 registers in the different CPU modes to
+	 * point to these stacks.
+	 * Since the ARM stacks use STMFD etc. we must set r13 to the top end
+	 * of the stack memory.
+	 */
+	set_stackptrs(0);
+
+	/*
+	 * We must now clean the cache again....
+	 * Cleaning may be done by reading new data to displace any
+	 * dirty data in the cache. This will have happened in setttb()
+	 * but since we are boot strapping the addresses used for the read
+	 * may have just been remapped and thus the cache could be out
+	 * of sync. A re-clean after the switch will cure this.
+	 * After booting there are no gross relocations of the kernel thus
+	 * this problem will not occur after initarm().
+	 */
+	cpu_idcache_wbinv_all();
+	cpu_setup("");
+
+	/*
+	 * Sort out bus_space for on-board devices.
+	 */
+	pxa_obio_tag_init();
+
+	/*
+	 * Fetch the SDRAM start/size from the PXA2X0 SDRAM configration
+	 * registers.
+	 */
+	pxa_probe_sdram(obio_tag, PXA2X0_MEMCTL_BASE, memstart, memsize);
+
+	/* Fire up consoles. */
+	cninit();
+
+	undefined_init();
+
+	init_proc0(kernelstack.pv_va);
+
+	/* Enable MMU, I-cache, D-cache, write buffer. */
+	arm_vector_init(ARM_VECTORS_HIGH, ARM_VEC_ALL);
+
+	pmap_curmaxkvaddr = afterkern + PAGE_SIZE;
+	vm_max_kernel_address = 0xd0000000;
+	pmap_bootstrap(pmap_curmaxkvaddr, &kernel_l1pt);
+	msgbufp = (void*)msgbufpv.pv_va;
+	msgbufinit(msgbufp, msgbufsize);
+	mutex_init();
+
+	/*
+	 * Add the physical ram we have available.
+	 *
+	 * Exclude the kernel (and all the things we allocated which immediately
+	 * follow the kernel) from the VM allocation pool but not from crash
+	 * dumps.  virtual_avail is a global variable which tracks the kva we've
+	 * "allocated" while setting up pmaps.
+	 *
+	 * Prepare the list of physical memory available to the vm subsystem.
+	 */
+	for (j = 0; j < PXA2X0_SDRAM_BANKS; j++) {
+		if (memsize[j] > 0)
+			arm_physmem_hardware_region(memstart[j], memsize[j]);
+	}
+	arm_physmem_exclude_region(abp->abp_physaddr, 
+	    virtual_avail - KERNVIRTADDR, EXFLAG_NOALLOC);
+	arm_physmem_init_kernel_globals();
+
+	init_param2(physmem);
+	kdb_init();
+	return ((void *)(kernelstack.pv_va + USPACE_SVC_STACK_TOP -
+	    sizeof(struct pcb)));
+}
+
+static void
+pxa_probe_sdram(bus_space_tag_t bst, bus_space_handle_t bsh,
+    uint32_t *memstart, uint32_t *memsize)
+{
+	uint32_t	mdcnfg, dwid, dcac, drac, dnb;
+	int		i;
+
+	mdcnfg = bus_space_read_4(bst, bsh, MEMCTL_MDCNFG);
+
+	/*
+	 * Scan all 4 SDRAM banks
+	 */
+	for (i = 0; i < PXA2X0_SDRAM_BANKS; i++) {
+		memstart[i] = 0;
+		memsize[i] = 0;
+
+		switch (i) {
+		case 0:
+		case 1:
+			if ((i == 0 && (mdcnfg & MDCNFG_DE0) == 0) ||
+			    (i == 1 && (mdcnfg & MDCNFG_DE1) == 0))
+				continue;
+			dwid = mdcnfg >> MDCNFD_DWID01_SHIFT;
+			dcac = mdcnfg >> MDCNFD_DCAC01_SHIFT;
+			drac = mdcnfg >> MDCNFD_DRAC01_SHIFT;
+			dnb = mdcnfg >> MDCNFD_DNB01_SHIFT;
+			break;
+
+		case 2:
+		case 3:
+			if ((i == 2 && (mdcnfg & MDCNFG_DE2) == 0) ||
+			    (i == 3 && (mdcnfg & MDCNFG_DE3) == 0))
+				continue;
+			dwid = mdcnfg >> MDCNFD_DWID23_SHIFT;
+			dcac = mdcnfg >> MDCNFD_DCAC23_SHIFT;
+			drac = mdcnfg >> MDCNFD_DRAC23_SHIFT;
+			dnb = mdcnfg >> MDCNFD_DNB23_SHIFT;
+			break;
+		default:
+			panic("pxa_probe_sdram: impossible");
+		}
+
+		dwid = 2 << (1 - (dwid & MDCNFD_DWID_MASK));  /* 16/32 width */
+		dcac = 1 << ((dcac & MDCNFD_DCAC_MASK) + 8);  /* 8-11 columns */
+		drac = 1 << ((drac & MDCNFD_DRAC_MASK) + 11); /* 11-13 rows */
+		dnb = 2 << (dnb & MDCNFD_DNB_MASK);	      /* # of banks */
+
+		memsize[i] = dwid * dcac * drac * dnb;
+		memstart[i] = PXA2X0_SDRAM0_START +
+		    (i * PXA2X0_SDRAM_BANK_SIZE);
+	}
+}
+
+#define	TIMER_FREQUENCY	3686400
+#define	UNIMPLEMENTED	panic("%s: unimplemented", __func__)
+
+/* XXXBJR: Belongs with DELAY in a timer.c of some sort. */
+void
+cpu_startprofclock(void)
+{
+	UNIMPLEMENTED;
+}
+
+void
+cpu_stopprofclock(void)
+{
+	UNIMPLEMENTED;
+}
+
+static struct arm32_dma_range pxa_range = {
+	.dr_sysbase = 0,
+	.dr_busbase = 0,
+	.dr_len = ~0u,
+};
+
+struct arm32_dma_range *
+bus_dma_get_range(void)
+{
+
+	return (&pxa_range);
+}
+
+int
+bus_dma_get_range_nb(void)
+{
+
+	return (1);
+}


Property changes on: trunk/sys/arm/xscale/pxa/pxa_machdep.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/pxa/pxa_obio.c
===================================================================
--- trunk/sys/arm/xscale/pxa/pxa_obio.c	                        (rev 0)
+++ trunk/sys/arm/xscale/pxa/pxa_obio.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,398 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2006 Benno Rice.  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 ``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 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: stable/10/sys/arm/xscale/pxa/pxa_obio.c 265999 2014-05-14 01:35:43Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <machine/bus.h>
+#include <machine/intr.h>
+
+#include <arm/xscale/pxa/pxavar.h>
+#include <arm/xscale/pxa/pxareg.h>
+
+static void	pxa_identify(driver_t *, device_t);
+static int	pxa_probe(device_t);
+static int	pxa_attach(device_t);
+
+static int	pxa_print_child(device_t, device_t);
+
+static int	pxa_setup_intr(device_t, device_t, struct resource *, int,
+		    driver_filter_t *, driver_intr_t *, void *, void **);
+static int	pxa_read_ivar(device_t, device_t, int, uintptr_t *);
+
+static struct resource_list *	pxa_get_resource_list(device_t, device_t);
+static struct resource *	pxa_alloc_resource(device_t, device_t, int,
+				    int *, u_long, u_long, u_long, u_int);
+static int			pxa_release_resource(device_t, device_t, int,
+				    int, struct resource *);
+static int			pxa_activate_resource(device_t, device_t,
+				    int, int, struct resource *);
+
+static struct resource *	pxa_alloc_gpio_irq(device_t, device_t, int,
+				    int *, u_long, u_long, u_long, u_int);
+
+struct obio_device {
+	const char	*od_name;
+	u_long		od_base;
+	u_long		od_size;
+	u_int		od_irqs[5];
+	struct resource_list od_resources;
+};
+
+static struct obio_device obio_devices[] = {
+	{ "icu", PXA2X0_INTCTL_BASE, PXA2X0_INTCTL_SIZE, { 0 } },
+	{ "timer", PXA2X0_OST_BASE, PXA2X0_OST_SIZE, { PXA2X0_INT_OST0, PXA2X0_INT_OST1, PXA2X0_INT_OST2, PXA2X0_INT_OST3, 0 } },
+	{ "dmac", PXA2X0_DMAC_BASE, PXA2X0_DMAC_SIZE, { PXA2X0_INT_DMA, 0 } },
+	{ "gpio", PXA2X0_GPIO_BASE, PXA250_GPIO_SIZE, { PXA2X0_INT_GPIO0, PXA2X0_INT_GPIO1, PXA2X0_INT_GPION, 0 } },
+	{ "uart", PXA2X0_FFUART_BASE, PXA2X0_FFUART_SIZE, { PXA2X0_INT_FFUART, 0 } },
+	{ "uart", PXA2X0_BTUART_BASE, PXA2X0_BTUART_SIZE, { PXA2X0_INT_BTUART, 0 } },
+	{ "uart", PXA2X0_STUART_BASE, PXA2X0_STUART_SIZE, { PXA2X0_INT_STUART, 0 } },
+	{ "uart", PXA2X0_HWUART_BASE, PXA2X0_HWUART_SIZE, { PXA2X0_INT_HWUART, 0 } },
+	{ "smi", PXA2X0_CS0_START, PXA2X0_CS_SIZE * 6, { 0 } },
+	{ NULL, 0, 0, { 0 } }
+};
+
+void
+pxa_identify(driver_t *driver, device_t parent)
+{
+
+	BUS_ADD_CHILD(parent, 0, "pxa", 0);
+}
+
+int
+pxa_probe(device_t dev)
+{
+
+	device_set_desc(dev, "XScale PXA On-board IO");
+	return (BUS_PROBE_NOWILDCARD);
+}
+
+int
+pxa_attach(device_t dev)
+{
+	struct		obio_softc *sc;
+	struct		obio_device *od;
+	int		i;
+	device_t	child;
+
+	sc = device_get_softc(dev);
+
+	sc->obio_bst = obio_tag;
+
+	sc->obio_mem.rm_type = RMAN_ARRAY;
+	sc->obio_mem.rm_descr = "PXA2X0 OBIO Memory";
+	if (rman_init(&sc->obio_mem) != 0)
+		panic("pxa_attach: failed to init obio mem rman");
+	if (rman_manage_region(&sc->obio_mem, 0, PXA250_PERIPH_END) != 0)
+		panic("pxa_attach: failed to set up obio mem rman");
+
+	sc->obio_irq.rm_type = RMAN_ARRAY;
+	sc->obio_irq.rm_descr = "PXA2X0 OBIO IRQ";
+	if (rman_init(&sc->obio_irq) != 0)
+		panic("pxa_attach: failed to init obio irq rman");
+	if (rman_manage_region(&sc->obio_irq, 0, 31) != 0)
+		panic("pxa_attach: failed to set up obio irq rman (main irqs)");
+	if (rman_manage_region(&sc->obio_irq, IRQ_GPIO0, IRQ_GPIO_MAX) != 0)
+		panic("pxa_attach: failed to set up obio irq rman (gpio irqs)");
+
+	for (od = obio_devices; od->od_name != NULL; od++) {
+		resource_list_init(&od->od_resources);
+
+		resource_list_add(&od->od_resources, SYS_RES_MEMORY, 0,
+		    od->od_base, od->od_base + od->od_size, od->od_size);
+
+		for (i = 0; od->od_irqs[i] != 0; i++) {
+			resource_list_add(&od->od_resources, SYS_RES_IRQ, i,
+			    od->od_irqs[i], od->od_irqs[i], 1);
+		}
+
+		child = device_add_child(dev, od->od_name, -1);
+		device_set_ivars(child, od);
+	}
+
+	bus_generic_probe(dev);
+	bus_generic_attach(dev);
+
+	return (0);
+}
+
+static int
+pxa_print_child(device_t dev, device_t child)
+{
+	struct	obio_device *od;
+	int	retval;
+
+	od = (struct obio_device *)device_get_ivars(child);
+	if (od == NULL)
+		panic("Unknown device on pxa0");
+
+	retval = 0;
+
+	retval += bus_print_child_header(dev, child);
+
+	retval += resource_list_print_type(&od->od_resources, "at mem",
+	    SYS_RES_MEMORY, "0x%08lx");
+	retval += resource_list_print_type(&od->od_resources, "irq",
+	    SYS_RES_IRQ, "%ld");
+
+	retval += bus_print_child_footer(dev, child);
+
+	return (retval);
+}
+
+static int
+pxa_setup_intr(device_t dev, device_t child, struct resource *irq, int flags,
+    driver_filter_t *filter, driver_intr_t *ithread, void *arg, void **cookiep)
+{
+	struct	obio_softc *sc;
+	int error;
+
+	sc = (struct obio_softc *)device_get_softc(dev);
+
+	error = BUS_SETUP_INTR(device_get_parent(dev), child, irq, flags,
+	    filter, ithread, arg, cookiep);
+	if (error)
+		return (error);
+	return (0);
+}
+
+static int
+pxa_teardown_intr(device_t dev, device_t child, struct resource *ires,
+    void *cookie)
+{
+	return (BUS_TEARDOWN_INTR(device_get_parent(dev), child, ires, cookie));}
+
+static int
+pxa_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
+{
+	struct	obio_device *od;
+
+	od = (struct obio_device *)device_get_ivars(child);
+
+	switch (which) {
+	case PXA_IVAR_BASE:
+		*((u_long *)result) = od->od_base;
+		break;
+
+	default:
+		return (ENOENT);
+	}
+
+	return (0);
+}
+
+static struct resource_list *
+pxa_get_resource_list(device_t dev, device_t child)
+{
+	struct	obio_device *od;
+
+	od = (struct obio_device *)device_get_ivars(child);
+
+	if (od == NULL)
+		return (NULL);
+
+	return (&od->od_resources);
+}
+
+static struct resource *
+pxa_alloc_resource(device_t dev, device_t child, int type, int *rid,
+    u_long start, u_long end, u_long count, u_int flags)
+{
+	struct	obio_softc *sc;
+	struct	obio_device *od;
+	struct	resource *rv;
+	struct	resource_list *rl;
+	struct	resource_list_entry *rle;
+	struct	rman *rm;
+	int	needactivate;
+
+	sc = (struct obio_softc *)device_get_softc(dev);
+	od = (struct obio_device *)device_get_ivars(child);
+	rl = &od->od_resources;
+
+	rle = resource_list_find(rl, type, *rid);
+	if (rle == NULL) {
+		/* We can allocate GPIO-based IRQs lazily. */
+		if (type == SYS_RES_IRQ)
+			return (pxa_alloc_gpio_irq(dev, child, type, rid,
+			    start, end, count, flags));
+		return (NULL);
+	}
+	if (rle->res != NULL)
+		panic("pxa_alloc_resource: resource is busy");
+
+	switch (type) {
+	case SYS_RES_IRQ:
+		rm = &sc->obio_irq;
+		break;
+
+	case SYS_RES_MEMORY:
+		rm = &sc->obio_mem;
+		break;
+
+	default:
+		return (NULL);
+	}
+
+	needactivate = flags & RF_ACTIVE;
+	flags &= ~RF_ACTIVE;
+	rv = rman_reserve_resource(rm, rle->start, rle->end, rle->count, flags,
+	    child);
+	if (rv == NULL)
+		return (NULL);
+	rle->res = rv;
+	rman_set_rid(rv, *rid);
+	if (type == SYS_RES_MEMORY) {
+		rman_set_bustag(rv, sc->obio_bst);
+		rman_set_bushandle(rv, rle->start);
+	}
+
+	if (needactivate) {
+		if (bus_activate_resource(child, type, *rid, rv)) {
+			rman_release_resource(rv);
+			return (NULL);
+		}
+	}
+
+	return (rv);
+}
+
+static int
+pxa_release_resource(device_t dev, device_t child, int type, int rid,
+    struct resource *r)
+{
+	struct	obio_device *od;
+	struct	resource_list *rl;
+	struct	resource_list_entry *rle;
+
+	od = (struct obio_device *)device_get_ivars(child);
+	rl = &od->od_resources;
+
+	if (type == SYS_RES_IOPORT)
+		type = SYS_RES_MEMORY;
+
+	rle = resource_list_find(rl, type, rid);
+
+	if (!rle)
+		panic("pxa_release_resource: can't find resource");
+	if (!rle->res)
+		panic("pxa_release_resource: resource entry is not busy");
+
+	rman_release_resource(rle->res);
+	rle->res = NULL;
+
+	return (0);
+}
+
+static int
+pxa_activate_resource(device_t dev, device_t child, int type, int rid,
+    struct resource *r)
+{
+
+	return (rman_activate_resource(r));
+}
+
+static device_method_t pxa_methods[] = {
+	DEVMETHOD(device_identify,	pxa_identify),
+	DEVMETHOD(device_probe,		pxa_probe),
+	DEVMETHOD(device_attach,	pxa_attach),
+
+	DEVMETHOD(bus_print_child,	pxa_print_child),
+
+	DEVMETHOD(bus_read_ivar,	pxa_read_ivar),
+	DEVMETHOD(bus_setup_intr,	pxa_setup_intr),
+	DEVMETHOD(bus_teardown_intr,	pxa_teardown_intr),
+
+	DEVMETHOD(bus_get_resource_list,	pxa_get_resource_list),
+	DEVMETHOD(bus_alloc_resource,		pxa_alloc_resource),
+	DEVMETHOD(bus_release_resource,		pxa_release_resource),
+	DEVMETHOD(bus_activate_resource,	pxa_activate_resource),
+
+	{0, 0}
+};
+
+static driver_t pxa_driver = {
+	"pxa",
+	pxa_methods,
+	sizeof(struct obio_softc),
+};
+
+static devclass_t pxa_devclass;
+
+DRIVER_MODULE(pxa, nexus, pxa_driver, pxa_devclass, 0, 0);
+
+static struct resource *
+pxa_alloc_gpio_irq(device_t dev, device_t child, int type, int *rid,
+    u_long start, u_long end, u_long count, u_int flags)
+{
+	struct	obio_softc *sc;
+	struct	obio_device *od;
+	struct	resource_list *rl;
+	struct	resource_list_entry *rle;
+	struct	resource *rv;
+	struct	rman *rm;
+	int	needactivate;
+
+	sc = device_get_softc(dev);
+	od = device_get_ivars(child);
+	rl = &od->od_resources;
+	rm = &sc->obio_irq;
+
+	needactivate = flags & RF_ACTIVE;
+	flags &= ~RF_ACTIVE;
+	rv = rman_reserve_resource(rm, start, end, count, flags, child);
+	if (rv == NULL)
+		return (NULL);
+
+	resource_list_add(rl, type, *rid, start, end, count);
+	rle = resource_list_find(rl, type, *rid);
+	if (rle == NULL)
+		panic("pxa_alloc_gpio_irq: unexpectedly can't find resource");
+
+	rle->res = rv;
+	rle->start = rman_get_start(rv);
+	rle->end = rman_get_end(rv);
+	rle->count = count;
+
+	if (needactivate) {
+		if (bus_activate_resource(child, type, *rid, rv)) {
+			rman_release_resource(rv);
+			return (NULL);
+		}
+	}
+
+	if (bootverbose)
+		device_printf(dev, "lazy allocation of irq %ld for %s\n",
+		    start, device_get_nameunit(child));
+
+	return (rv);
+}


Property changes on: trunk/sys/arm/xscale/pxa/pxa_obio.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/pxa/pxa_smi.c
===================================================================
--- trunk/sys/arm/xscale/pxa/pxa_smi.c	                        (rev 0)
+++ trunk/sys/arm/xscale/pxa/pxa_smi.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,357 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2006 Benno Rice.  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 ``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 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: stable/10/sys/arm/xscale/pxa/pxa_smi.c 241885 2012-10-22 13:06:09Z eadler $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/timetc.h>
+#include <machine/bus.h>
+#include <machine/intr.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <arm/xscale/pxa/pxavar.h>
+#include <arm/xscale/pxa/pxareg.h>
+
+static MALLOC_DEFINE(M_PXASMI, "PXA SMI",
+    "Data for static memory interface devices.");
+
+struct pxa_smi_softc {
+	struct resource	*ps_res[1];
+	struct rman	ps_mem;
+	bus_space_tag_t	ps_bst;
+	bus_addr_t	ps_base;
+};
+
+struct smi_ivars {
+	struct resource_list	smid_resources;
+	bus_addr_t		smid_mem;
+};
+
+static struct resource_spec pxa_smi_spec[] = {
+	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
+	{ -1, 0 }
+};
+
+static int	pxa_smi_probe(device_t);
+static int	pxa_smi_attach(device_t);
+
+static int	pxa_smi_print_child(device_t, device_t);
+
+static int	pxa_smi_read_ivar(device_t, device_t, int, uintptr_t *);
+
+static struct resource *	pxa_smi_alloc_resource(device_t, device_t,
+				    int, int *, u_long, u_long, u_long, u_int);
+static int			pxa_smi_release_resource(device_t, device_t,
+				    int, int, struct resource *);
+static int			pxa_smi_activate_resource(device_t, device_t,
+				    int, int, struct resource *);
+
+static void	pxa_smi_add_device(device_t, const char *, int);
+
+static int
+pxa_smi_probe(device_t dev)
+{
+
+	if (resource_disabled("smi", device_get_unit(dev)))
+		return (ENXIO);
+
+	device_set_desc(dev, "Static Memory Interface");
+	return (0);
+}
+
+static int
+pxa_smi_attach(device_t dev)
+{
+	int		error, i, dunit;
+	const char	*dname;
+	struct		pxa_smi_softc *sc;
+
+	sc = (struct pxa_smi_softc *)device_get_softc(dev);
+
+	error = bus_alloc_resources(dev, pxa_smi_spec, sc->ps_res);
+	if (error) {
+		device_printf(dev, "could not allocate resources\n");
+		return (ENXIO);
+	}
+
+	sc->ps_mem.rm_type = RMAN_ARRAY;
+	sc->ps_mem.rm_descr = device_get_nameunit(dev);
+	if (rman_init(&sc->ps_mem) != 0)
+		panic("pxa_smi_attach: failed to init mem rman");
+	if (rman_manage_region(&sc->ps_mem, 0, PXA2X0_CS_SIZE * 6) != 0)
+		panic("pxa_smi_attach: failed ot set up mem rman");
+
+	sc->ps_bst = base_tag;
+	sc->ps_base = rman_get_start(sc->ps_res[0]);
+
+	i = 0;
+	while (resource_find_match(&i, &dname, &dunit, "at",
+	    device_get_nameunit(dev)) == 0) {
+		pxa_smi_add_device(dev, dname, dunit);
+	}
+
+	bus_generic_probe(dev);
+	bus_generic_attach(dev);
+
+	return (0);
+}
+
+static int
+pxa_smi_print_child(device_t dev, device_t child)
+{
+	struct	smi_ivars *smid;
+	int	retval;
+
+	smid = (struct smi_ivars *)device_get_ivars(child);
+	if (smid == NULL) {
+		device_printf(dev, "unknown device: %s\n",
+		    device_get_nameunit(child));
+		return (0);
+	}
+
+	retval = 0;
+
+	retval += bus_print_child_header(dev, child);
+
+	retval += resource_list_print_type(&smid->smid_resources, "at mem",
+	    SYS_RES_MEMORY, "%#lx");
+	retval += resource_list_print_type(&smid->smid_resources, "irq",
+	    SYS_RES_IRQ, "%ld");
+
+	retval += bus_print_child_footer(dev, child);
+
+	return (retval);
+}
+
+static int
+pxa_smi_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
+{
+	struct	pxa_smi_softc *sc;
+	struct	smi_ivars *smid;
+
+	sc = device_get_softc(dev);
+	smid = device_get_ivars(child);
+
+	switch (which) {
+	case SMI_IVAR_PHYSBASE:
+		*((bus_addr_t *)result) = smid->smid_mem;
+		break;
+
+	default:
+		return (ENOENT);
+	}
+
+	return (0);
+}
+
+static struct resource *
+pxa_smi_alloc_resource(device_t dev, device_t child, int type, int *rid,
+    u_long start, u_long end, u_long count, u_int flags)
+{
+	struct	pxa_smi_softc *sc;
+	struct	smi_ivars *smid;
+	struct	resource *rv;
+	struct	resource_list *rl;
+	struct	resource_list_entry *rle;
+	int	needactivate;
+
+	sc = (struct pxa_smi_softc *)device_get_softc(dev);
+	smid = (struct smi_ivars *)device_get_ivars(child);
+	rl = &smid->smid_resources;
+
+	if (type == SYS_RES_IOPORT)
+		type = SYS_RES_MEMORY;
+
+	rle = resource_list_find(rl, type, *rid);
+	if (rle == NULL)
+		return (NULL);
+	if (rle->res != NULL)
+		panic("pxa_smi_alloc_resource: resource is busy");
+
+	needactivate = flags & RF_ACTIVE;
+	flags &= ~RF_ACTIVE;
+
+	switch (type) {
+	case SYS_RES_MEMORY:
+		rv = rman_reserve_resource(&sc->ps_mem, rle->start, rle->end,
+		    rle->count, flags, child);
+		if (rv == NULL)
+			return (NULL);
+		rle->res = rv;
+		rman_set_rid(rv, *rid);
+		rman_set_bustag(rv, sc->ps_bst);
+		rman_set_bushandle(rv, rle->start);
+		if (needactivate) {
+			if (bus_activate_resource(child, type, *rid, rv) != 0) {
+				rman_release_resource(rv);
+				return (NULL);
+			}
+		}
+
+		break;
+
+	case SYS_RES_IRQ:
+		rv = bus_alloc_resource(dev, type, rid, rle->start, rle->end,
+		    rle->count, flags);
+		if (rv == NULL)
+			return (NULL);
+		if (needactivate) {
+			if (bus_activate_resource(child, type, *rid, rv) != 0) {
+				bus_release_resource(dev, type, *rid, rv);
+				return (NULL);
+			}
+		}
+
+		break;
+
+	default:
+		return (NULL);
+	}
+
+	return (rv);
+}
+
+static int
+pxa_smi_release_resource(device_t dev, device_t child, int type, int rid,
+    struct resource *r)
+{
+	struct	smi_ivars *smid;
+	struct	resource_list *rl;
+	struct	resource_list_entry *rle;
+
+	if (type == SYS_RES_IRQ)
+		return (bus_release_resource(dev, SYS_RES_IRQ, rid, r));
+
+	smid = (struct smi_ivars *)device_get_ivars(child);
+	rl = &smid->smid_resources;
+
+	if (type == SYS_RES_IOPORT)
+		type = SYS_RES_MEMORY;
+
+	rle = resource_list_find(rl, type, rid);
+	if (rle == NULL)
+		panic("pxa_smi_release_resource: can't find resource");
+	if (rle->res == NULL)
+		panic("pxa_smi_release_resource: resource entry not busy");
+
+	rman_release_resource(rle->res);
+	rle->res = NULL;
+
+	return (0);
+}
+
+static int
+pxa_smi_activate_resource(device_t dev, device_t child, int type, int rid,
+    struct resource *r)
+{
+	struct	pxa_smi_softc *sc;
+
+	sc = (struct pxa_smi_softc *)device_get_softc(dev);
+
+	if (type == SYS_RES_IRQ)
+		return (bus_activate_resource(dev, SYS_RES_IRQ, rid, r));
+
+	rman_set_bushandle(r, (bus_space_handle_t)pmap_mapdev(rman_get_start(r),
+	    rman_get_size(r)));
+	return (rman_activate_resource(r));
+}
+
+static device_method_t pxa_smi_methods[] = {
+	DEVMETHOD(device_probe, pxa_smi_probe),
+	DEVMETHOD(device_attach, pxa_smi_attach),
+
+	DEVMETHOD(bus_print_child, pxa_smi_print_child),
+
+	DEVMETHOD(bus_read_ivar, pxa_smi_read_ivar),
+
+	DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
+
+	DEVMETHOD(bus_alloc_resource, pxa_smi_alloc_resource),
+	DEVMETHOD(bus_release_resource, pxa_smi_release_resource),
+	DEVMETHOD(bus_activate_resource, pxa_smi_activate_resource),
+
+	{0, 0}
+};
+
+static driver_t pxa_smi_driver = {
+	"smi",
+	pxa_smi_methods,
+	sizeof(struct pxa_smi_softc),
+};
+
+static devclass_t pxa_smi_devclass;
+
+DRIVER_MODULE(smi, pxa, pxa_smi_driver, pxa_smi_devclass, 0, 0);
+
+static void
+pxa_smi_add_device(device_t dev, const char *name, int unit)
+{
+	device_t	child;
+	int		start, count;
+	struct		smi_ivars *ivars;
+
+	ivars = (struct smi_ivars *)malloc(
+	    sizeof(struct smi_ivars), M_PXASMI, M_WAITOK);
+	if (ivars == NULL)
+		return;
+
+	child = device_add_child(dev, name, unit);
+	if (child == NULL) {
+		free(ivars, M_PXASMI);
+		return;
+	}
+
+	device_set_ivars(child, ivars);
+	resource_list_init(&ivars->smid_resources);
+
+	start = 0;
+	count = 0;
+	resource_int_value(name, unit, "mem", &start);
+	resource_int_value(name, unit, "size", &count);
+	if (start > 0 || count > 0) {
+		resource_list_add(&ivars->smid_resources, SYS_RES_MEMORY, 0,
+		    start, start + count, count);
+		ivars->smid_mem = (bus_addr_t)start;
+	}
+
+	start = -1;
+	count = 0;
+	resource_int_value(name, unit, "irq", &start);
+	if (start > -1)
+		resource_list_add(&ivars->smid_resources, SYS_RES_IRQ, 0, start,
+		     start, 1);
+
+	if (resource_disabled(name, unit))
+		device_disable(child);
+}


Property changes on: trunk/sys/arm/xscale/pxa/pxa_smi.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/pxa/pxa_space.c
===================================================================
--- trunk/sys/arm/xscale/pxa/pxa_space.c	                        (rev 0)
+++ trunk/sys/arm/xscale/pxa/pxa_space.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,269 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: obio_space.c,v 1.6 2003/07/15 00:25:05 lukem Exp $	*/
+
+/*-
+ * Copyright (c) 2001, 2002, 2003 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Jason R. Thorpe for Wasabi Systems, Inc.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed for the NetBSD Project by
+ *	Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
+ * 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.
+ */
+
+/*
+ * bus_space functions for PXA devices
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/arm/xscale/pxa/pxa_space.c 278727 2015-02-13 22:32:02Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+
+#include <machine/bus.h>
+
+#include <arm/xscale/pxa/pxareg.h>
+#include <arm/xscale/pxa/pxavar.h>
+
+static MALLOC_DEFINE(M_PXATAG, "PXA bus_space tags", "Bus_space tags for PXA");
+
+/* Prototypes for all the bus_space structure functions */
+bs_protos(generic);
+bs_protos(pxa);
+
+/*
+ * The obio bus space tag.  This is constant for all instances, so
+ * we never have to explicitly "create" it.
+ */
+struct bus_space _base_tag = {
+	/* cookie */
+	.bs_privdata	= NULL,
+
+	/* mapping/unmapping */
+	.bs_map		= generic_bs_map,
+	.bs_unmap	= generic_bs_unmap,
+	.bs_subregion	= generic_bs_subregion,
+
+	/* allocation/deallocation */
+	.bs_alloc	= generic_bs_alloc,
+	.bs_free	= generic_bs_free,
+
+	/* barrier */
+	.bs_barrier	= generic_bs_barrier,
+
+	/* read (single) */
+	.bs_r_1		= pxa_bs_r_1,
+	.bs_r_2		= pxa_bs_r_2,
+	.bs_r_4		= pxa_bs_r_4,
+	.bs_r_8		= BS_UNIMPLEMENTED,
+
+	/* read multiple */
+	.bs_rm_1	= pxa_bs_rm_1,
+	.bs_rm_2	= pxa_bs_rm_2,
+	.bs_rm_4	= BS_UNIMPLEMENTED,
+	.bs_rm_8	= BS_UNIMPLEMENTED,
+
+	/* read region */
+	.bs_rr_1	= pxa_bs_rr_1,
+	.bs_rr_2	= BS_UNIMPLEMENTED,
+	.bs_rr_4	= BS_UNIMPLEMENTED,
+	.bs_rr_8	= BS_UNIMPLEMENTED,
+
+	/* write (single) */
+	.bs_w_1		= pxa_bs_w_1,
+	.bs_w_2		= pxa_bs_w_2,
+	.bs_w_4		= pxa_bs_w_4,
+	.bs_w_8		= BS_UNIMPLEMENTED,
+
+	/* write multiple */
+	.bs_wm_1	= pxa_bs_wm_1,
+	.bs_wm_2	= pxa_bs_wm_2,
+	.bs_wm_4	= BS_UNIMPLEMENTED,
+	.bs_wm_8	= BS_UNIMPLEMENTED,
+
+	/* write region */
+	.bs_wr_1	= BS_UNIMPLEMENTED,
+	.bs_wr_2	= BS_UNIMPLEMENTED,
+	.bs_wr_4	= BS_UNIMPLEMENTED,
+	.bs_wr_8	= BS_UNIMPLEMENTED,
+
+	/* set multiple */
+	.bs_sm_1	= BS_UNIMPLEMENTED,
+	.bs_sm_2	= BS_UNIMPLEMENTED,
+	.bs_sm_4	= BS_UNIMPLEMENTED,
+	.bs_sm_8	= BS_UNIMPLEMENTED,
+
+	/* set region */
+	.bs_sr_1	= BS_UNIMPLEMENTED,
+	.bs_sr_2	= BS_UNIMPLEMENTED,
+	.bs_sr_4	= BS_UNIMPLEMENTED,
+	.bs_sr_8	= BS_UNIMPLEMENTED,
+
+	/* copy */
+	.bs_c_1		= BS_UNIMPLEMENTED,
+	.bs_c_2		= BS_UNIMPLEMENTED,
+	.bs_c_4		= BS_UNIMPLEMENTED,
+	.bs_c_8		= BS_UNIMPLEMENTED,
+
+	/* read stream (single) */
+	.bs_r_1_s	= BS_UNIMPLEMENTED,
+	.bs_r_2_s	= BS_UNIMPLEMENTED,
+	.bs_r_4_s	= BS_UNIMPLEMENTED,
+	.bs_r_8_s	= BS_UNIMPLEMENTED,
+
+	/* read multiple stream */
+	.bs_rm_1_s	= BS_UNIMPLEMENTED,
+	.bs_rm_2_s	= BS_UNIMPLEMENTED,
+	.bs_rm_4_s	= BS_UNIMPLEMENTED,
+	.bs_rm_8_s	= BS_UNIMPLEMENTED,
+
+	/* read region stream */
+	.bs_rr_1_s	= BS_UNIMPLEMENTED,
+	.bs_rr_2_s	= BS_UNIMPLEMENTED,
+	.bs_rr_4_s	= BS_UNIMPLEMENTED,
+	.bs_rr_8_s	= BS_UNIMPLEMENTED,
+
+	/* write stream (single) */
+	.bs_w_1_s	= BS_UNIMPLEMENTED, 
+	.bs_w_2_s	= BS_UNIMPLEMENTED, 
+	.bs_w_4_s	= BS_UNIMPLEMENTED, 
+	.bs_w_8_s	= BS_UNIMPLEMENTED, 
+
+	/* write multiple stream */
+	.bs_wm_1_s	= BS_UNIMPLEMENTED,
+	.bs_wm_2_s	= BS_UNIMPLEMENTED,
+	.bs_wm_4_s	= BS_UNIMPLEMENTED,
+	.bs_wm_8_s	= BS_UNIMPLEMENTED,
+
+	/* write region stream */
+	.bs_wr_1_s	= BS_UNIMPLEMENTED,
+	.bs_wr_2_s	= BS_UNIMPLEMENTED,
+	.bs_wr_4_s	= BS_UNIMPLEMENTED,
+	.bs_wr_8_s	= BS_UNIMPLEMENTED,
+};
+
+static struct bus_space	_obio_tag;
+
+bus_space_tag_t		base_tag = &_base_tag;
+bus_space_tag_t		obio_tag = NULL;
+
+void
+pxa_obio_tag_init()
+{
+
+	bcopy(&_base_tag, &_obio_tag, sizeof(struct bus_space));
+	_obio_tag.bs_privdata = (void *)PXA2X0_PERIPH_OFFSET;
+	obio_tag = &_obio_tag;
+}
+
+bus_space_tag_t
+pxa_bus_tag_alloc(bus_addr_t offset)
+{
+	struct	bus_space *tag;
+
+	tag = (struct bus_space *)malloc(sizeof(struct bus_space), M_PXATAG,
+	    M_WAITOK);
+	if (tag == NULL) {
+		return (NULL);
+	}
+
+	bcopy(&_base_tag, tag, sizeof(struct bus_space));
+	tag->bs_privdata = (void *)offset;
+
+	return ((bus_space_tag_t)tag);
+}
+
+
+#define	READ_SINGLE(type, proto, base)					\
+	type								\
+	proto(bus_space_tag_t tag, bus_space_handle_t bsh, bus_size_t offset)	\
+	{								\
+		bus_addr_t	tag_offset;				\
+		type		value;					\
+		tag_offset = (bus_addr_t)tag->bs_privdata;		\
+		value = base(NULL, bsh + tag_offset, offset);		\
+		return (value);						\
+	}
+
+READ_SINGLE(u_int8_t,  pxa_bs_r_1, generic_bs_r_1)
+READ_SINGLE(u_int16_t, pxa_bs_r_2, generic_bs_r_2)
+READ_SINGLE(u_int32_t, pxa_bs_r_4, generic_bs_r_4)
+
+#undef READ_SINGLE
+
+#define	WRITE_SINGLE(type, proto, base)					\
+	void								\
+	proto(bus_space_tag_t tag, bus_space_handle_t bsh, bus_size_t offset,	\
+	    type value)							\
+	{								\
+		bus_addr_t	tag_offset;				\
+		tag_offset = (bus_addr_t)tag->bs_privdata;		\
+		base(NULL, bsh + tag_offset, offset, value);		\
+	}
+
+WRITE_SINGLE(u_int8_t,  pxa_bs_w_1, generic_bs_w_1)
+WRITE_SINGLE(u_int16_t, pxa_bs_w_2, generic_bs_w_2)
+WRITE_SINGLE(u_int32_t, pxa_bs_w_4, generic_bs_w_4)
+
+#undef WRITE_SINGLE
+
+#define	READ_MULTI(type, proto, base)					\
+	void								\
+	proto(bus_space_tag_t tag, bus_space_handle_t bsh, bus_size_t offset,	\
+	    type *dest, bus_size_t count)				\
+	{								\
+		bus_addr_t	tag_offset;				\
+		tag_offset = (bus_addr_t)tag->bs_privdata;		\
+		base(NULL, bsh + tag_offset, offset, dest, count);	\
+	}
+
+READ_MULTI(u_int8_t,  pxa_bs_rm_1, generic_bs_rm_1)
+READ_MULTI(u_int16_t, pxa_bs_rm_2, generic_bs_rm_2)
+
+READ_MULTI(u_int8_t,  pxa_bs_rr_1, generic_bs_rr_1)
+
+#undef READ_MULTI
+
+#define	WRITE_MULTI(type, proto, base)					\
+	void								\
+	proto(bus_space_tag_t tag, bus_space_handle_t bsh, bus_size_t offset,	\
+	    const type *src, bus_size_t count)				\
+	{								\
+		bus_addr_t	tag_offset;				\
+		tag_offset = (bus_addr_t)tag->bs_privdata;		\
+		base(NULL, bsh + tag_offset, offset, src, count);	\
+	}
+
+WRITE_MULTI(u_int8_t,  pxa_bs_wm_1, generic_bs_wm_1)
+WRITE_MULTI(u_int16_t, pxa_bs_wm_2, generic_bs_wm_2)
+
+#undef WRITE_MULTI


Property changes on: trunk/sys/arm/xscale/pxa/pxa_space.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/pxa/pxa_timer.c
===================================================================
--- trunk/sys/arm/xscale/pxa/pxa_timer.c	                        (rev 0)
+++ trunk/sys/arm/xscale/pxa/pxa_timer.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,319 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2006 Benno Rice.  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 ``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 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: stable/10/sys/arm/xscale/pxa/pxa_timer.c 278613 2015-02-12 03:50:33Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/timetc.h>
+#include <machine/armreg.h>
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/frame.h>
+#include <machine/intr.h>
+
+#include <arm/xscale/pxa/pxavar.h>
+#include <arm/xscale/pxa/pxareg.h>
+
+#define	PXA_TIMER_FREQUENCY	3686400
+#define	PXA_TIMER_TICK		(PXA_TIMER_FREQUENCY / hz)
+
+struct pxa_timer_softc {
+	struct resource	*	pt_res[5];
+	bus_space_tag_t		pt_bst;
+	bus_space_handle_t	pt_bsh;
+};
+
+static struct resource_spec pxa_timer_spec[] = {
+	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		0,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		1,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		2,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		3,	RF_ACTIVE },
+	{ -1, 0 }
+};
+
+static struct pxa_timer_softc *timer_softc = NULL;
+
+static int	pxa_timer_probe(device_t);
+static int	pxa_timer_attach(device_t);
+
+static driver_filter_t	pxa_hardclock;
+
+static unsigned	pxa_timer_get_timecount(struct timecounter *);
+
+uint32_t	pxa_timer_get_osmr(int);
+void		pxa_timer_set_osmr(int, uint32_t);
+uint32_t	pxa_timer_get_oscr(void);
+void		pxa_timer_set_oscr(uint32_t);
+uint32_t	pxa_timer_get_ossr(void);
+void		pxa_timer_clear_ossr(uint32_t);
+void		pxa_timer_watchdog_enable(void);
+void		pxa_timer_watchdog_disable(void);
+void		pxa_timer_interrupt_enable(int);
+void		pxa_timer_interrupt_disable(int);
+
+static struct timecounter pxa_timer_timecounter = {
+	.tc_get_timecount = pxa_timer_get_timecount,
+	.tc_name = "OS Timer",
+	.tc_frequency = PXA_TIMER_FREQUENCY,
+	.tc_counter_mask = ~0u,
+	.tc_quality = 1000,
+};
+
+static int
+pxa_timer_probe(device_t dev)
+{
+
+	device_set_desc(dev, "OS Timer");
+	return (0);
+}
+
+static int
+pxa_timer_attach(device_t dev)
+{
+	int	error;
+	void	*ihl;
+	struct	pxa_timer_softc *sc;
+
+	sc = (struct pxa_timer_softc *)device_get_softc(dev);
+
+	if (timer_softc != NULL)
+		return (ENXIO);
+
+	error = bus_alloc_resources(dev, pxa_timer_spec, sc->pt_res);
+	if (error) {
+		device_printf(dev, "could not allocate resources\n");
+		return (ENXIO);
+	}
+
+	sc->pt_bst = rman_get_bustag(sc->pt_res[0]);
+	sc->pt_bsh = rman_get_bushandle(sc->pt_res[0]);
+
+	timer_softc = sc;
+
+	pxa_timer_interrupt_disable(-1);
+	pxa_timer_watchdog_disable();
+
+	if (bus_setup_intr(dev, sc->pt_res[1], INTR_TYPE_CLK,
+	    pxa_hardclock, NULL, NULL, &ihl) != 0) {
+		bus_release_resources(dev, pxa_timer_spec, sc->pt_res);
+		device_printf(dev, "could not setup hardclock interrupt\n");
+		return (ENXIO);
+	}
+
+	return (0);
+}
+
+static int
+pxa_hardclock(void *arg)
+{
+	struct		trapframe *frame;
+
+	frame = (struct trapframe *)arg;
+
+	/* Clear the interrupt */
+	pxa_timer_clear_ossr(OST_SR_CH0);
+
+	/* Schedule next tick */
+	pxa_timer_set_osmr(0, pxa_timer_get_oscr() + PXA_TIMER_TICK);
+
+	/* Do what we came here for */
+	hardclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
+	
+	return (FILTER_HANDLED);
+}
+
+static device_method_t pxa_timer_methods[] = {
+	DEVMETHOD(device_probe, pxa_timer_probe),
+	DEVMETHOD(device_attach, pxa_timer_attach),
+
+	{0, 0}
+};
+
+static driver_t pxa_timer_driver = {
+	"timer",
+	pxa_timer_methods,
+	sizeof(struct pxa_timer_softc),
+};
+
+static devclass_t pxa_timer_devclass;
+
+DRIVER_MODULE(pxatimer, pxa, pxa_timer_driver, pxa_timer_devclass, 0, 0);
+
+static unsigned
+pxa_timer_get_timecount(struct timecounter *tc)
+{
+
+	return (pxa_timer_get_oscr());
+}
+
+void
+cpu_initclocks(void)
+{
+
+	pxa_timer_set_oscr(0);
+	pxa_timer_set_osmr(0, PXA_TIMER_TICK);
+	pxa_timer_interrupt_enable(0);
+
+	tc_init(&pxa_timer_timecounter);
+}
+
+void
+cpu_reset(void)
+{
+	uint32_t	val;
+
+	(void)disable_interrupts(PSR_I|PSR_F);
+
+	val = pxa_timer_get_oscr();
+	val += PXA_TIMER_FREQUENCY;
+	pxa_timer_set_osmr(3, val);
+	pxa_timer_watchdog_enable();
+
+	for(;;);
+}
+
+void
+DELAY(int usec)
+{
+	uint32_t	val;
+
+	if (timer_softc == NULL) {
+		for (; usec > 0; usec--)
+			for (val = 100; val > 0; val--)
+				;
+		return;
+	}
+
+	val = pxa_timer_get_oscr();
+	val += (PXA_TIMER_FREQUENCY * usec) / 1000000;
+	while (pxa_timer_get_oscr() <= val);
+}
+
+uint32_t
+pxa_timer_get_osmr(int which)
+{
+
+	return (bus_space_read_4(timer_softc->pt_bst,
+	    timer_softc->pt_bsh, which * 0x4));
+}
+
+void
+pxa_timer_set_osmr(int which, uint32_t val)
+{
+
+	bus_space_write_4(timer_softc->pt_bst,
+	    timer_softc->pt_bsh, which * 0x4, val);
+}
+
+uint32_t
+pxa_timer_get_oscr()
+{
+
+	return (bus_space_read_4(timer_softc->pt_bst,
+	    timer_softc->pt_bsh, OST_CR));
+}
+
+void
+pxa_timer_set_oscr(uint32_t val)
+{
+
+	bus_space_write_4(timer_softc->pt_bst,
+	    timer_softc->pt_bsh, OST_CR, val);
+}
+
+uint32_t
+pxa_timer_get_ossr()
+{
+
+	return (bus_space_read_4(timer_softc->pt_bst,
+	    timer_softc->pt_bsh, OST_SR));
+}
+
+void
+pxa_timer_clear_ossr(uint32_t val)
+{
+
+	bus_space_write_4(timer_softc->pt_bst,
+	    timer_softc->pt_bsh, OST_SR, val);
+}
+
+void
+pxa_timer_watchdog_enable()
+{
+
+	bus_space_write_4(timer_softc->pt_bst,
+	    timer_softc->pt_bsh, OST_WR, 0x1);
+}
+
+void
+pxa_timer_watchdog_disable()	
+{
+
+	bus_space_write_4(timer_softc->pt_bst,
+	    timer_softc->pt_bsh, OST_WR, 0x0);
+}
+
+void
+pxa_timer_interrupt_enable(int which)
+{
+	uint32_t	oier;
+
+	if (which == -1) {
+		bus_space_write_4(timer_softc->pt_bst,
+		    timer_softc->pt_bsh, OST_IR, 0xf);
+		return;
+	}
+
+	oier = bus_space_read_4(timer_softc->pt_bst,
+	    timer_softc->pt_bsh, OST_IR);
+	oier |= 1 << which;
+	bus_space_write_4(timer_softc->pt_bst,
+	    timer_softc->pt_bsh, OST_IR, oier);
+}
+
+void
+pxa_timer_interrupt_disable(int which)
+{
+	uint32_t	oier;
+
+	if (which == -1) {
+		bus_space_write_4(timer_softc->pt_bst,
+		    timer_softc->pt_bsh, OST_IR, 0);
+	}
+
+	oier = bus_space_read_4(timer_softc->pt_bst,
+	    timer_softc->pt_bsh, OST_IR);
+	oier &= ~(1 << which);
+	bus_space_write_4(timer_softc->pt_bst,
+	    timer_softc->pt_bsh, OST_IR, oier);
+}


Property changes on: trunk/sys/arm/xscale/pxa/pxa_timer.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/pxa/pxareg.h
===================================================================
--- trunk/sys/arm/xscale/pxa/pxareg.h	                        (rev 0)
+++ trunk/sys/arm/xscale/pxa/pxareg.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,757 @@
+/* $MidnightBSD$ */
+/* $NetBSD: pxa2x0reg.h,v 1.9 2006/04/10 04:13:58 simonb Exp $ */
+
+/*
+ * Copyright (c) 2002  Genetec Corporation.  All rights reserved.
+ * Written by Hiroyuki Bessho for Genetec Corporation.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed for the NetBSD Project by
+ *	Genetec Corporation.
+ * 4. The name of Genetec Corporation may not be used to endorse or
+ *    promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``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 GENETEC CORPORATION
+ * 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: stable/10/sys/arm/xscale/pxa/pxareg.h 266311 2014-05-17 13:53:38Z ian $
+ */
+
+
+/*
+ * Intel PXA2[15]0 processor is XScale based integrated CPU
+ *
+ * Reference:
+ *  Intel(r) PXA250 and PXA210 Application Processors
+ *   Developer's Manual
+ *  (278522-001.pdf)
+ */
+#ifndef _ARM_XSCALE_PXAREG_H_
+#define _ARM_XSCALE_PXAREG_H_
+
+#ifndef _LOCORE
+#include <sys/types.h>		/* for uint32_t */
+#endif
+
+/*
+ * Chip select domains
+ */
+#define PXA2X0_CS0_START 0x00000000
+#define PXA2X0_CS1_START 0x04000000
+#define PXA2X0_CS2_START 0x08000000
+#define PXA2X0_CS3_START 0x0c000000
+#define PXA2X0_CS4_START 0x10000000
+#define PXA2X0_CS5_START 0x14000000
+#define	PXA2X0_CS_SIZE   0x04000000
+
+#define PXA2X0_PCMCIA_SLOT0  0x20000000
+#define PXA2X0_PCMCIA_SLOT1  0x30000000
+
+#define PXA2X0_PERIPH_START 0x40000000
+/* #define PXA2X0_MEMCTL_START 0x48000000 */
+#define PXA270_PERIPH_END   0x530fffff
+#define PXA250_PERIPH_END   0x480fffff
+#define	PXA2X0_PERIPH_OFFSET 0xa8000000
+
+#define PXA2X0_SDRAM0_START 0xa0000000
+#define PXA2X0_SDRAM1_START 0xa4000000
+#define PXA2X0_SDRAM2_START 0xa8000000
+#define PXA2X0_SDRAM3_START 0xac000000
+#define	PXA2X0_SDRAM_BANKS      4
+#define	PXA2X0_SDRAM_BANK_SIZE  0x04000000
+
+/*
+ * Physical address of integrated peripherals
+ */
+
+#define PXA2X0_DMAC_BASE	0x40000000
+#define PXA2X0_DMAC_SIZE	0x300
+#define PXA2X0_FFUART_BASE	0x40100000 /* Full Function UART */
+#define	PXA2X0_FFUART_SIZE	0x20
+#define PXA2X0_BTUART_BASE	0x40200000 /* Bluetooth UART */
+#define	PXA2X0_BTUART_SIZE	0x24
+#define PXA2X0_I2C_BASE		0x40300000
+#define PXA2X0_I2C_SIZE		0x000016a4
+#define PXA2X0_I2S_BASE 	0x40400000
+#define PXA2X0_AC97_BASE	0x40500000
+#define PXA2X0_AC97_SIZE	0x600
+#define PXA2X0_USBDC_BASE 	0x40600000 /* USB Client */
+#define PXA2X0_USBDC_SIZE 	0x0e04
+#define PXA2X0_STUART_BASE	0x40700000 /* Standard UART */
+#define	PXA2X0_STUART_SIZE	0x24
+#define PXA2X0_ICP_BASE 	0x40800000
+#define PXA2X0_RTC_BASE 	0x40900000
+#define PXA2X0_RTC_SIZE 	0x10
+#define PXA2X0_OST_BASE 	0x40a00000 /* OS Timer */
+#define	PXA2X0_OST_SIZE		0x20
+#define PXA2X0_PWM0_BASE	0x40b00000
+#define PXA2X0_PWM1_BASE	0x40c00000
+#define PXA2X0_INTCTL_BASE	0x40d00000 /* Interrupt controller */
+#define	PXA2X0_INTCTL_SIZE	0x20
+#define PXA2X0_GPIO_BASE	0x40e00000
+
+#define PXA270_GPIO_SIZE  	0x150
+#define PXA250_GPIO_SIZE  	0x70
+#define PXA2X0_POWMAN_BASE  	0x40f00000 /* Power management */
+#define PXA2X0_SSP_BASE 	0x41000000
+#define PXA2X0_MMC_BASE 	0x41100000 /* MultiMediaCard */
+#define PXA2X0_MMC_SIZE		0x48
+#define PXA2X0_CLKMAN_BASE  	0x41300000 /* Clock Manager */
+#define PXA2X0_CLKMAN_SIZE	12
+#define	PXA2X0_HWUART_BASE	0x41600000 /* Hardware UART */
+#define	PXA2X0_HWUART_SIZE	0x30
+#define PXA2X0_LCDC_BASE	0x44000000 /* LCD Controller */
+#define PXA2X0_LCDC_SIZE	0x220
+#define PXA2X0_MEMCTL_BASE	0x48000000 /* Memory Controller */
+#define PXA2X0_MEMCTL_SIZE	0x48
+#define PXA2X0_USBH_BASE	0x4c000000 /* USB Host controller */
+#define PXA2X0_USBH_SIZE	0x70
+
+/* Internal SRAM storage. PXA27x only */
+#define PXA270_SRAM0_START 0x5c000000
+#define PXA270_SRAM1_START 0x5c010000
+#define PXA270_SRAM2_START 0x5c020000
+#define PXA270_SRAM3_START 0x5c030000
+#define	PXA270_SRAM_BANKS      4
+#define	PXA270_SRAM_BANK_SIZE  0x00010000
+
+/* width of interrupt controller */
+#define ICU_LEN			32   /* but [0..7,15,16] is not used */
+#define ICU_INT_HWMASK		0xffffff00
+#define PXA250_IRQ_MIN 8	/* 0..7 are not used by integrated
+				   peripherals */
+#define PXA270_IRQ_MIN 0
+
+#define PXA2X0_INT_USBH1	3	/* USB host (OHCI) */
+
+#define	PXA2X0_INT_HWUART	7
+#define PXA2X0_INT_GPIO0	8
+#define PXA2X0_INT_GPIO1	9
+#define PXA2X0_INT_GPION	10	/* irq from GPIO[2..80] */
+#define PXA2X0_INT_USB  	11
+#define PXA2X0_INT_PMU  	12
+#define PXA2X0_INT_I2S  	13
+#define PXA2X0_INT_AC97  	14
+#define PXA2X0_INT_LCD  	17
+#define PXA2X0_INT_I2C  	18
+#define PXA2X0_INT_ICP  	19
+#define PXA2X0_INT_STUART  	20
+#define PXA2X0_INT_BTUART  	21
+#define PXA2X0_INT_FFUART  	22
+#define PXA2X0_INT_MMC  	23
+#define PXA2X0_INT_SSP  	24
+#define PXA2X0_INT_DMA  	25
+#define PXA2X0_INT_OST0  	26
+#define PXA2X0_INT_OST1  	27
+#define PXA2X0_INT_OST2  	28
+#define PXA2X0_INT_OST3  	29
+#define PXA2X0_INT_RTCHZ  	30
+#define PXA2X0_INT_ALARM  	31	/* RTC Alarm interrupt */
+
+/* DMAC */
+#define DMAC_N_CHANNELS	16
+#define	DMAC_N_PRIORITIES 3
+
+#define DMAC_DCSR(n)	((n)*4)
+#define  DCSR_BUSERRINTR    (1<<0)	/* bus error interrupt */
+#define  DCSR_STARTINTR     (1<<1)	/* start interrupt */
+#define  DCSR_ENDINTR       (1<<2)	/* end interrupt */
+#define  DCSR_STOPSTATE     (1<<3)	/* channel is not running */
+#define  DCSR_REQPEND       (1<<8)	/* request pending */
+#define  DCSR_STOPIRQEN     (1<<29)     /* stop interrupt enable */
+#define  DCSR_NODESCFETCH   (1<<30)	/* no-descriptor fetch mode */
+#define  DCSR_RUN  	    (1<<31)
+#define DMAC_DINT 	0x00f0		/* DAM interrupt */
+#define  DMAC_DINT_MASK	0xffffu
+#define DMAC_DRCMR(n)	(0x100+(n)*4)	/* Channel map register */
+#define  DRCMR_CHLNUM	0x0f		/* channel number */
+#define  DRCMR_MAPVLD	(1<<7)		/* map valid */
+#define DMAC_DDADR(n)	(0x0200+(n)*16)
+#define  DDADR_STOP	(1<<0)
+#define DMAC_DSADR(n)	(0x0204+(n)*16)
+#define DMAC_DTADR(n)	(0x0208+(n)*16)
+#define DMAC_DCMD(n)	(0x020c+(n)*16)
+#define  DCMD_LENGTH_MASK	0x1fff
+#define  DCMD_WIDTH_SHIFT  14
+#define  DCMD_WIDTH_0	(0<<DCMD_WIDTH_SHIFT)	/* for mem-to-mem transfer*/
+#define  DCMD_WIDTH_1	(1<<DCMD_WIDTH_SHIFT)
+#define  DCMD_WIDTH_2	(2<<DCMD_WIDTH_SHIFT)
+#define  DCMD_WIDTH_4	(3<<DCMD_WIDTH_SHIFT)
+#define  DCMD_SIZE_SHIFT  16
+#define  DCMD_SIZE_8	(1<<DCMD_SIZE_SHIFT)
+#define  DCMD_SIZE_16	(2<<DCMD_SIZE_SHIFT)
+#define  DCMD_SIZE_32	(3<<DCMD_SIZE_SHIFT)
+#define  DCMD_LITTLE_ENDIEN	(0<<18)
+#define	 DCMD_ENDIRQEN	  (1<<21)
+#define  DCMD_STARTIRQEN  (1<<22)
+#define  DCMD_FLOWTRG     (1<<28)	/* flow control by target */
+#define  DCMD_FLOWSRC     (1<<29)	/* flow control by source */
+#define  DCMD_INCTRGADDR  (1<<30)	/* increment target address */
+#define  DCMD_INCSRCADDR  (1<<31)	/* increment source address */
+
+#ifndef __ASSEMBLER__
+/* DMA descriptor */
+struct pxa_dma_desc {
+	volatile uint32_t	dd_ddadr;
+#define	DMAC_DESC_LAST	0x1
+	volatile uint32_t	dd_dsadr;
+	volatile uint32_t	dd_dtadr;
+	volatile uint32_t	dd_dcmd;		/* command and length */
+};
+#endif
+
+/* UART */
+#define PXA2X0_COM_FREQ   14745600L
+
+/* I2C */
+#define I2C_IBMR	0x1680		/* Bus monitor register */
+#define I2C_IDBR	0x1688		/* Data buffer */
+#define I2C_ICR  	0x1690		/* Control register */
+#define  ICR_START	(1<<0)
+#define  ICR_STOP	(1<<1)
+#define  ICR_ACKNAK	(1<<2)
+#define  ICR_TB  	(1<<3)
+#define  ICR_MA  	(1<<4)
+#define I2C_ISR  	0x1698		/* Status register */
+#define I2C_ISAR	0x16a0		/* Slave address */
+
+/* Clock Manager */
+#define CLKMAN_CCCR	0x00	/* Core Clock Configuration */
+#define  CCCR_TURBO_X1	 (2<<7)
+#define  CCCR_TURBO_X15	 (3<<7)	/* x 1.5 */
+#define  CCCR_TURBO_X2	 (4<<7)
+#define  CCCR_TURBO_X25	 (5<<7)	/* x 2.5 */
+#define  CCCR_TURBO_X3	 (6<<7)	/* x 3.0 */
+#define  CCCR_RUN_X1	 (1<<5)
+#define  CCCR_RUN_X2	 (2<<5)
+#define  CCCR_RUN_X4	 (3<<5)
+#define  CCCR_MEM_X27	 (1<<0)	/* x27, 99.53MHz */
+#define  CCCR_MEM_X32	 (2<<0)	/* x32, 117,96MHz */
+#define  CCCR_MEM_X36	 (3<<0)	/* x26, 132.71MHz */
+#define  CCCR_MEM_X40	 (4<<0)	/* x27, 99.53MHz */
+#define  CCCR_MEM_X45	 (5<<0)	/* x27, 99.53MHz */
+#define  CCCR_MEM_X9	 (0x1f<<0)	/* x9, 33.2MHz */
+
+#define CLKMAN_CKEN	0x04	/* Clock Enable Register */
+#define CLKMAN_OSCC	0x08	/* Osillcator Configuration Register */
+
+#define CCCR_N_SHIFT	7
+#define CCCR_N_MASK	(0x07<<CCCR_N_SHIFT)
+#define CCCR_M_SHIFT	5
+#define CCCR_M_MASK	(0x03<<CCCR_M_SHIFT)
+#define CCCR_L_MASK	0x1f
+
+#define CKEN_PWM0	(1<<0)
+#define CKEN_PWM1	(1<<1)
+#define CKEN_AC97	(1<<2)
+#define CKEN_SSP	(1<<3)
+#define CKEN_STUART	(1<<5)
+#define CKEN_FFUART	(1<<6)
+#define CKEN_BTUART	(1<<7)
+#define CKEN_I2S	(1<<8)
+#define CKEN_USBH	(1<<10)
+#define CKEN_USB	(1<<11)
+#define CKEN_MMC	(1<<12)
+#define CKEN_FICP	(1<<13)
+#define CKEN_I2C	(1<<14)
+#define CKEN_LCD	(1<<16)
+
+#define OSCC_OOK	(1<<0)	/* 32.768 kHz oscillator status */
+#define OSCC_OON	(1<<1)	/* 32.768 kHz oscillator */
+
+/*
+ * RTC
+ */
+#define RTC_RCNR	0x0000	/* count register */
+#define RTC_RTAR	0x0004	/* alarm register */
+#define RTC_RTSR	0x0008	/* status register */
+#define RTC_RTTR	0x000c	/* trim register */
+/*
+ * GPIO
+ */
+#define GPIO_GPLR0  0x00	/* Level reg [31:0] */
+#define GPIO_GPLR1  0x04	/* Level reg [63:32] */
+#define GPIO_GPLR2  0x08	/* Level reg [80:64] */
+
+#define GPIO_GPDR0  0x0c	/* dir reg [31:0] */
+#define GPIO_GPDR1  0x10	/* dir reg [63:32] */
+#define GPIO_GPDR2  0x14	/* dir reg [80:64] */
+
+#define GPIO_GPSR0  0x18	/* set reg [31:0] */
+#define GPIO_GPSR1  0x1c	/* set reg [63:32] */
+#define GPIO_GPSR2  0x20	/* set reg [80:64] */
+
+#define GPIO_GPCR0  0x24	/* clear reg [31:0] */
+#define GPIO_GPCR1  0x28	/* clear reg [63:32] */
+#define GPIO_GPCR2  0x2c	/* clear reg [80:64] */
+
+#define GPIO_GPER0  0x30	/* rising edge [31:0] */
+#define GPIO_GPER1  0x34	/* rising edge [63:32] */
+#define GPIO_GPER2  0x38	/* rising edge [80:64] */
+
+#define GPIO_GRER0  0x30	/* rising edge [31:0] */
+#define GPIO_GRER1  0x34	/* rising edge [63:32] */
+#define GPIO_GRER2  0x38	/* rising edge [80:64] */
+
+#define GPIO_GFER0  0x3c	/* falling edge [31:0] */
+#define GPIO_GFER1  0x40	/* falling edge [63:32] */
+#define GPIO_GFER2  0x44	/* falling edge [80:64] */
+
+#define GPIO_GEDR0  0x48	/* edge detect [31:0] */
+#define GPIO_GEDR1  0x4c	/* edge detect [63:32] */
+#define GPIO_GEDR2  0x50	/* edge detect [80:64] */
+
+#define GPIO_GAFR0_L  0x54	/* alternate function [15:0] */
+#define GPIO_GAFR0_U  0x58	/* alternate function [31:16] */
+#define GPIO_GAFR1_L  0x5c	/* alternate function [47:32] */
+#define GPIO_GAFR1_U  0x60	/* alternate function [63:48] */
+#define GPIO_GAFR2_L  0x64	/* alternate function [79:64] */
+#define GPIO_GAFR2_U  0x68	/* alternate function [80] */
+
+/* Only for PXA270 */
+#define GPIO_GAFR3_L  0x6c	/* alternate function [111:96] */
+#define GPIO_GAFR3_U  0x70	/* alternate function [120:112] */
+
+#define GPIO_GPLR3  0x100	/* Level reg [120:96] */
+#define GPIO_GPDR3  0x10c	/* dir reg [120:96] */
+#define GPIO_GPSR3  0x118	/* set reg [120:96] */
+#define GPIO_GPCR3  0x124	/* clear reg [120:96] */
+#define GPIO_GRER3  0x130	/* rising edge [120:96] */
+#define GPIO_GFER3  0x13c	/* falling edge [120:96] */
+#define GPIO_GEDR3  0x148	/* edge detect [120:96] */
+
+/* a bit simpler if we don't support PXA270 */
+#define	PXA250_GPIO_REG(r, pin)	((r) + (((pin) / 32) * 4))
+#define	PXA250_GPIO_NPINS    85
+
+#define	PXA270_GPIO_REG(r, pin) \
+(pin < 96 ? PXA250_GPIO_REG(r,pin) : ((r) + 0x100 + ((((pin)-96) / 32) * 4)))
+#define PXA270_GPIO_NPINS    121
+
+
+#define	GPIO_BANK(pin)		((pin) / 32)
+#define	GPIO_BIT(pin)		(1u << ((pin) & 0x1f))
+#define	GPIO_FN_REG(pin)	(GPIO_GAFR0_L + (((pin) / 16) * 4))
+#define	GPIO_FN_SHIFT(pin)	((pin & 0xf) * 2)
+
+#define	GPIO_IN		  	0x00	/* Regular GPIO input pin */
+#define	GPIO_OUT	  	0x10	/* Regular GPIO output pin */
+#define	GPIO_ALT_FN_1_IN	0x01	/* Alternate function 1 input */
+#define	GPIO_ALT_FN_1_OUT	0x11	/* Alternate function 1 output */
+#define	GPIO_ALT_FN_2_IN	0x02	/* Alternate function 2 input */
+#define	GPIO_ALT_FN_2_OUT	0x12	/* Alternate function 2 output */
+#define	GPIO_ALT_FN_3_IN	0x03	/* Alternate function 3 input */
+#define	GPIO_ALT_FN_3_OUT	0x13	/* Alternate function 3 output */
+#define	GPIO_SET		0x20	/* Initial state is Set */
+#define	GPIO_CLR		0x00	/* Initial state is Clear */
+
+#define	GPIO_FN_MASK		0x03
+#define	GPIO_FN_IS_OUT(n)	((n) & GPIO_OUT)
+#define	GPIO_FN_IS_SET(n)	((n) & GPIO_SET)
+#define	GPIO_FN(n)		((n) & GPIO_FN_MASK)
+#define	GPIO_IS_GPIO(n)		(GPIO_FN(n) == 0)
+#define	GPIO_IS_GPIO_IN(n)	(((n) & (GPIO_FN_MASK|GPIO_OUT)) == GPIO_IN)
+#define	GPIO_IS_GPIO_OUT(n)	(((n) & (GPIO_FN_MASK|GPIO_OUT)) == GPIO_OUT)
+
+#define	IRQ_GPIO0		64
+#define	IRQ_NGPIO		128
+#define	IRQ_GPIO_MAX		IRQ_GPIO0 + IRQ_NGPIO
+#define	IRQ_TO_GPIO(x)		(x - IRQ_GPIO0)
+#define	GPIO_TO_IRQ(x)		(x + IRQ_GPIO0)
+
+/*
+ * memory controller
+ */
+
+#define MEMCTL_MDCNFG	0x0000
+#define  MDCNFG_DE0		(1<<0)
+#define  MDCNFG_DE1		(1<<1)
+#define  MDCNFD_DWID01_SHIFT	2
+#define  MDCNFD_DCAC01_SHIFT	3
+#define  MDCNFD_DRAC01_SHIFT	5
+#define  MDCNFD_DNB01_SHIFT	7
+#define  MDCNFG_DE2		(1<<16)
+#define  MDCNFG_DE3		(1<<17)
+#define  MDCNFD_DWID23_SHIFT	18
+#define  MDCNFD_DCAC23_SHIFT	19
+#define  MDCNFD_DRAC23_SHIFT	21
+#define  MDCNFD_DNB23_SHIFT	23
+
+#define  MDCNFD_DWID_MASK	0x1
+#define  MDCNFD_DCAC_MASK	0x3
+#define  MDCNFD_DRAC_MASK	0x3
+#define  MDCNFD_DNB_MASK	0x1
+	
+#define MEMCTL_MDREFR   0x04	/* refresh control register */
+#define  MDREFR_DRI	0xfff
+#define  MDREFR_E0PIN	(1<<12)
+#define  MDREFR_K0RUN   (1<<13)	/* SDCLK0 enable */
+#define  MDREFR_K0DB2   (1<<14)	/* SDCLK0 1/2 freq */
+#define  MDREFR_E1PIN	(1<<15)
+#define  MDREFR_K1RUN   (1<<16)	/* SDCLK1 enable */
+#define  MDREFR_K1DB2   (1<<17)	/* SDCLK1 1/2 freq */
+#define  MDREFR_K2RUN   (1<<18)	/* SDCLK2 enable */
+#define  MDREFR_K2DB2	(1<<19)	/* SDCLK2 1/2 freq */
+#define	 MDREFR_APD	(1<<20)	/* Auto Power Down */
+#define  MDREFR_SLFRSH	(1<<22)	/* Self Refresh */
+#define  MDREFR_K0FREE	(1<<23)	/* SDCLK0 free run */
+#define  MDREFR_K1FREE	(1<<24)	/* SDCLK1 free run */
+#define  MDREFR_K2FREE	(1<<25)	/* SDCLK2 free run */
+
+#define MEMCTL_MSC0	0x08	/* Asychronous Statis memory Control CS[01] */
+#define MEMCTL_MSC1	0x0c	/* Asychronous Statis memory Control CS[23] */
+#define MEMCTL_MSC2	0x10	/* Asychronous Statis memory Control CS[45] */
+#define  MSC_RBUFF_SHIFT 15	/* return data buffer */
+#define  MSC_RBUFF	(1<<MSC_RBUFF_SHIFT)
+#define  MSC_RRR_SHIFT   12  	/* recovery time */
+#define	 MSC_RRR	(7<<MSC_RRR_SHIFT)
+#define  MSC_RDN_SHIFT    8	/* ROM delay next access */
+#define  MSC_RDN	(0x0f<<MSC_RDN_SHIFT)
+#define  MSC_RDF_SHIFT    4	/*  ROM delay first access*/
+#define  MSC_RDF  	(0x0f<<MSC_RDF_SHIFT)
+#define  MSC_RBW_SHIFT    3	/* 32/16 bit bus */
+#define  MSC_RBW 	(1<<MSC_RBW_SHIFT)
+#define  MSC_RT_SHIFT	   0	/* type */
+#define  MSC_RT 	(7<<MSC_RT_SHIFT)
+#define  MSC_RT_NONBURST	0
+#define  MSC_RT_SRAM    	1
+#define  MSC_RT_BURST4  	2
+#define  MSC_RT_BURST8  	3
+#define  MSC_RT_VLIO   	 	4
+
+/* expansion memory timing configuration */
+#define MEMCTL_MCMEM(n)	(0x28+4*(n))
+#define MEMCTL_MCATT(n)	(0x30+4*(n))
+#define MEMCTL_MCIO(n)	(0x38+4*(n))
+
+#define  MC_HOLD_SHIFT	14
+#define  MC_ASST_SHIFT	7
+#define  MC_SET_SHIFT	0
+#define  MC_TIMING_VAL(hold,asst,set)	(((hold)<<MC_HOLD_SHIFT)| \
+		((asst)<<MC_ASST_SHIFT)|((set)<<MC_SET_SHIFT))
+
+#define MEMCTL_MECR	0x14	/* Expansion memory configuration */
+#define MECR_NOS	(1<<0)	/* Number of sockets */
+#define MECR_CIT	(1<<1)	/* Card-is-there */
+
+#define MEMCTL_MDMRS	0x0040
+
+/*
+ * LCD Controller
+ */
+#define LCDC_LCCR0	0x000	/* Controller Control Register 0 */
+#define  LCCR0_ENB	(1U<<0)	/* LCD Controller Enable */
+#define  LCCR0_CMS	(1U<<1)	/* Color/Mono select */
+#define  LCCR0_SDS	(1U<<2)	/* Single/Dual -panel */
+#define  LCCR0_LDM	(1U<<3)	/* LCD Disable Done Mask */
+#define  LCCR0_SFM	(1U<<4)	/* Start of Frame Mask */
+#define  LCCR0_IUM	(1U<<5)	/* Input FIFO Underrun Mask */
+#define  LCCR0_EFM	(1U<<6)	/* End of Frame Mask */
+#define  LCCR0_PAS	(1U<<7)	/* Passive/Active Display select */
+#define  LCCR0_DPD	(1U<<9)	/* Double-Pixel Data pin mode */
+#define  LCCR0_DIS	(1U<<10) /* LCD Disable */
+#define  LCCR0_QDM	(1U<<11) /* LCD Quick Disable Mask */
+#define  LCCR0_BM	(1U<<20) /* Branch Mask */
+#define  LCCR0_OUM	(1U<<21) /* Output FIFO Underrun Mask */
+
+#define  LCCR0_IMASK	(LCCR0_LDM|LCCR0_SFM|LCCR0_IUM|LCCR0_EFM|LCCR0_QDM|LCCR0_BM|LCCR0_OUM)
+
+
+#define LCDC_LCCR1	0x004	/* Controller Control Register 1 */
+#define LCDC_LCCR2	0x008	/* Controller Control Register 2 */
+#define LCDC_LCCR3	0x00c	/* Controller Control Register 2 */
+#define  LCCR3_BPP_SHIFT 24		/* Bits per pixel */
+#define  LCCR3_BPP	(0x07<<LCCR3_BPP_SHIFT)
+#define LCDC_LCCR4	0x010	/* Controller Control Register 4 */
+#define LCDC_LCCR5	0x014	/* Controller Control Register 5 */
+#define LCDC_FBR0	0x020	/* DMA ch0 frame branch register */
+#define LCDC_FBR1	0x024	/* DMA ch1 frame branch register */
+#define LCDC_FBR2	0x028	/* DMA ch2 frame branch register */
+#define LCDC_FBR3	0x02c	/* DMA ch3 frame branch register */
+#define LCDC_FBR4	0x030	/* DMA ch4 frame branch register */
+#define LCDC_LCSR1	0x034	/* controller status register 1 PXA27x only */
+#define LCDC_LCSR	0x038	/* controller status register */
+#define  LCSR_LDD	(1U<<0) /* LCD disable done */
+#define  LCSR_SOF	(1U<<1) /* Start of frame */
+#define LCDC_LIIDR	0x03c	/* controller interrupt ID Register */
+#define LCDC_TRGBR	0x040	/* TMED RGB Speed Register */
+#define LCDC_TCR	0x044	/* TMED Control Register */
+#define LCDC_OVL1C1	0x050	/* Overlay 1 control register 1 */
+#define LCDC_OVL1C2	0x060	/* Overlay 1 control register 2 */
+#define LCDC_OVL2C1	0x070	/* Overlay 1 control register 1 */
+#define LCDC_OVL2C2	0x080	/* Overlay 1 control register 2 */
+#define LCDC_CCR	0x090	/* Cursor control register */
+#define LCDC_CMDCR	0x100	/* Command control register */
+#define LCDC_PRSR	0x104	/* Panel read status register */
+#define LCDC_FBR5	0x110	/* DMA ch5 frame branch register */
+#define LCDC_FBR6	0x114	/* DMA ch6 frame branch register */
+#define LCDC_FDADR0	0x200	/* DMA ch0 frame descriptor address */
+#define LCDC_FSADR0	0x204	/* DMA ch0 frame source address */
+#define LCDC_FIDR0	0x208	/* DMA ch0 frame ID register */
+#define LCDC_LDCMD0	0x20c	/* DMA ch0 command register */
+#define LCDC_FDADR1	0x210	/* DMA ch1 frame descriptor address */
+#define LCDC_FSADR1	0x214	/* DMA ch1 frame source address */
+#define LCDC_FIDR1	0x218	/* DMA ch1 frame ID register */
+#define LCDC_LDCMD1	0x21c	/* DMA ch1 command register */
+#define LCDC_FDADR2	0x220	/* DMA ch2 frame descriptor address */
+#define LCDC_FSADR2	0x224	/* DMA ch2 frame source address */
+#define LCDC_FIDR2	0x228	/* DMA ch2 frame ID register */
+#define LCDC_LDCMD2	0x22c	/* DMA ch2 command register */
+#define LCDC_FDADR3	0x230	/* DMA ch3 frame descriptor address */
+#define LCDC_FSADR3	0x234	/* DMA ch3 frame source address */
+#define LCDC_FIDR3	0x238	/* DMA ch3 frame ID register */
+#define LCDC_LDCMD3	0x23c	/* DMA ch3 command register */
+#define LCDC_FDADR4	0x240	/* DMA ch4 frame descriptor address */
+#define LCDC_FSADR4	0x244	/* DMA ch4 frame source address */
+#define LCDC_FIDR4	0x248	/* DMA ch4 frame ID register */
+#define LCDC_LDCMD4	0x24c	/* DMA ch4 command register */
+#define LCDC_FDADR5	0x250	/* DMA ch5 frame descriptor address */
+#define LCDC_FSADR5	0x254	/* DMA ch5 frame source address */
+#define LCDC_FIDR5	0x258	/* DMA ch5 frame ID register */
+#define LCDC_LDCMD5	0x25c	/* DMA ch5 command register */
+#define LCDC_FDADR6	0x260	/* DMA ch6 frame descriptor address */
+#define LCDC_FSADR6	0x264	/* DMA ch6 frame source address */
+#define LCDC_FIDR6	0x268	/* DMA ch6 frame ID register */
+#define LCDC_LDCMD6	0x26c	/* DMA ch6 command register */
+#define LCDC_LCDBSCNTR	0x054	/* LCD buffer strength control register */
+
+/*
+ * MMC/SD controller
+ */
+#define MMC_STRPCL	0x00	/* start/stop MMC clock */
+#define  STRPCL_NOOP	0
+#define  STRPCL_STOP	1	/* stop MMC clock */
+#define  STRPCL_START	2	/* start MMC clock */
+#define MMC_STAT	0x04	/* status register */
+#define  STAT_READ_TIME_OUT   		(1<<0)
+#define  STAT_TIMEOUT_RESPONSE		(1<<1)
+#define  STAT_CRC_WRITE_ERROR		(1<<2)
+#define  STAT_CRC_READ_ERROR		(1<<3)
+#define  STAT_SPI_READ_ERROR_TOKEN	(1<<4)
+#define  STAT_RES_CRC_ERR		(1<<5)
+#define  STAT_XMIT_FIFO_EMPTY		(1<<6)
+#define  STAT_RECV_FIFO_FULL		(1<<7)
+#define  STAT_CLK_EN			(1<<8)
+#define  STAT_DATA_TRAN_DONE		(1<<11)
+#define  STAT_PRG_DONE			(1<<12)
+#define  STAT_END_CMD_RES		(1<<13)
+#define MMC_CLKRT	0x08	/* MMC clock rate */
+#define  CLKRT_20M	0
+#define  CLKRT_10M	1
+#define  CLKRT_5M	2
+#define  CLKRT_2_5M	3
+#define  CLKRT_1_25M	4
+#define  CLKRT_625K	5
+#define  CLKRT_312K	6
+#define MMC_SPI  	0x0c	/* SPI mode control */
+#define  SPI_EN  	(1<<0)	/* enable SPI mode */
+#define  SPI_CRC_ON	(1<<1)	/* enable CRC generation */
+#define  SPI_CS_EN	(1<<2)	/* Enable CS[01] */
+#define  SPI_CS_ADDRESS	(1<<3)	/* CS0/CS1 */
+#define MMC_CMDAT	0x10	/* command/response/data */
+#define  CMDAT_RESPONSE_FORMAT	0x03
+#define  CMDAT_RESPONSE_FORMAT_NO 0 /* no response */
+#define  CMDAT_RESPONSE_FORMAT_R1 1 /* R1, R1b, R4, R5 */
+#define  CMDAT_RESPONSE_FORMAT_R2 2
+#define  CMDAT_RESPONSE_FORMAT_R3 3
+#define  CMDAT_DATA_EN		(1<<2)
+#define  CMDAT_WRITE		(1<<3) /* 1=write 0=read operation */
+#define  CMDAT_STREAM_BLOCK	(1<<4) /* stream mode */
+#define  CMDAT_BUSY		(1<<5) /* busy signal is expected */
+#define  CMDAT_INIT		(1<<6) /* preceede command with 80 clocks */
+#define  CMDAT_MMC_DMA_EN	(1<<7) /* DMA enable */
+#define MMC_RESTO	0x14	/* expected response time out */
+#define MMC_RDTO 	0x18	/* expected data read time out */
+#define MMC_BLKLEN	0x1c	/* block length of data transaction */
+#define MMC_NOB  	0x20	/* number of blocks (block mode) */
+#define MMC_PRTBUF	0x24	/* partial MMC_TXFIFO written */
+#define  PRTBUF_BUF_PART_FULL (1<<0) /* buffer partially full */
+#define MMC_I_MASK	0x28	/* interrupt mask */
+#define MMC_I_REG	0x2c	/* interrupt register */
+#define  MMC_I_DATA_TRAN_DONE	(1<<0)
+#define  MMC_I_PRG_DONE		(1<<1)
+#define  MMC_I_END_CMD_RES	(1<<2)
+#define  MMC_I_STOP_CMD		(1<<3)
+#define  MMC_I_CLK_IS_OFF	(1<<4)
+#define  MMC_I_RXFIFO_RD_REQ	(1<<5)
+#define  MMC_I_TXFIFO_WR_REQ	(1<<6)
+#define MMC_CMD  	0x30	/* index of current command */
+#define MMC_ARGH 	0x34	/* MSW part of the current command arg */
+#define MMC_ARGL 	0x38	/* LSW part of the current command arg */
+#define MMC_RES  	0x3c	/* response FIFO */
+#define MMC_RXFIFO	0x40	/* receive FIFO */
+#define MMC_TXFIFO	0x44 	/* transmit FIFO */
+
+/*
+ * AC97
+ */
+#define	AC97_N_CODECS	2
+#define AC97_GCR 	0x000c	/* Global control register */
+#define  GCR_GIE       	(1<<0)	/* interrupt enable */
+#define  GCR_COLD_RST	(1<<1)
+#define  GCR_WARM_RST	(1<<2)
+#define  GCR_ACLINK_OFF	(1<<3)
+#define  GCR_PRIRES_IEN	(1<<4)	/* Primary resume interrupt enable */
+#define  GCR_SECRES_IEN	(1<<5)	/* Secondary resume interrupt enable */
+#define  GCR_PRIRDY_IEN	(1<<8)	/* Primary ready interrupt enable */
+#define  GCR_SECRDY_IEN	(1<<9)	/* Primary ready interrupt enable */
+#define  GCR_SDONE_IE 	(1<<18)	/* Status done interrupt enable */
+#define  GCR_CDONE_IE	(1<<19)	/* Command done interrupt enable */
+
+#define AC97_GSR 	0x001c	/* Global status register */
+#define  GSR_GSCI	(1<<0)	/* codec GPI status change interrupt */
+#define  GSR_MIINT	(1<<1)	/* modem in interrupt */
+#define  GSR_MOINT	(1<<2)	/* modem out interrupt */
+#define  GSR_PIINT	(1<<5)	/* PCM in interrupt */
+#define  GSR_POINT	(1<<6)	/* PCM out interrupt */
+#define  GSR_MINT	(1<<7)	/* Mic in interrupt */
+#define  GSR_PCR	(1<<8)	/* primary code ready */
+#define  GSR_SCR	(1<<9)	/* secondary code ready */
+#define  GSR_PRIRES	(1<<10)	/* primary resume interrupt */
+#define  GSR_SECRES	(1<<11)	/* secondary resume interrupt */
+#define  GSR_BIT1SLT12	(1<<12)	/* Bit 1 of slot 12 */
+#define  GSR_BIT2SLT12	(1<<13)	/* Bit 2 of slot 12 */
+#define  GSR_BIT3SLT12	(1<<14)	/* Bit 3 of slot 12 */
+#define  GSR_RDCS 	(1<<15)	/* Read completion status */
+#define  GSR_SDONE 	(1<<18)	/* status done */
+#define  GSR_CDONE 	(1<<19)	/* command done */
+
+#define AC97_POCR 	0x0000	/* PCM-out control */
+#define AC97_PICR 	0x0004	/* PCM-in control */
+#define AC97_POSR 	0x0010	/* PCM-out status */
+#define AC97_PISR 	0x0014	/* PCM-out status */
+#define AC97_MCCR	0x0008	/* MIC-in control register */
+#define AC97_MCSR	0x0018	/* MIC-in status register */
+#define AC97_MICR	0x0100	/* Modem-in control register */
+#define AC97_MISR	0x0108	/* Modem-in status register */
+#define AC97_MOCR	0x0110	/* Modem-out control register */
+#define AC97_MOSR	0x0118	/* Modem-out status register */
+#define  AC97_FEFIE	(1<<3)	/* fifo error interrupt enable */
+#define  AC97_FIFOE	(1<<4)	/* fifo error */
+
+#define AC97_CAR  	0x0020	/* Codec access register */
+#define  CAR_CAIP  	(1<<0)	/* Codec access in progress */
+
+#define AC97_PCDR	0x0040	/* PCM data register */
+#define AC97_MCDR 	0x0060	/* MIC-in data register */
+#define AC97_MODR 	0x0140	/* Modem data register */
+
+/* address to access codec registers */
+#define AC97_PRIAUDIO	0x0200	/* Primary audio codec */
+#define AC97_SECAUDIO	0x0300	/* Secondary autio codec */
+#define AC97_PRIMODEM	0x0400	/* Primary modem codec */
+#define AC97_SECMODEM	0x0500	/* Secondary modem codec */
+#define	AC97_CODEC_BASE(c)	(AC97_PRIAUDIO + ((c) * 0x100))
+
+/*
+ * USB device controller
+ */
+#define USBDC_UDCCR	0x0000  /* UDC control register    */
+#define USBDC_UDCCS(n)	(0x0010+4*(n))  /* Endpoint Control/Status Registers */
+#define USBDC_UICR0	0x0050  /* UDC Interrupt Control Register 0  */
+#define USBDC_UICR1	0x0054  /* UDC Interrupt Control Register 1  */
+#define USBDC_USIR0	0x0058  /* UDC Status Interrupt Register 0  */
+#define USBDC_USIR1	0x005C  /* UDC Status Interrupt Register 1  */
+#define USBDC_UFNHR	0x0060  /* UDC Frame Number Register High  */
+#define USBDC_UFNLR	0x0064  /* UDC Frame Number Register Low  */
+#define USBDC_UBCR2	0x0068  /* UDC Byte Count Register 2  */
+#define USBDC_UBCR4	0x006C  /* UDC Byte Count Register 4  */
+#define USBDC_UBCR7	0x0070  /* UDC Byte Count Register 7  */
+#define USBDC_UBCR9	0x0074  /* UDC Byte Count Register 9  */
+#define USBDC_UBCR12	0x0078  /* UDC Byte Count Register 12  */
+#define USBDC_UBCR14	0x007C  /* UDC Byte Count Register 14  */
+#define USBDC_UDDR0	0x0080  /* UDC Endpoint 0 Data Register  */
+#define USBDC_UDDR1	0x0100  /* UDC Endpoint 1 Data Register  */
+#define USBDC_UDDR2	0x0180  /* UDC Endpoint 2 Data Register  */
+#define USBDC_UDDR3	0x0200  /* UDC Endpoint 3 Data Register  */
+#define USBDC_UDDR4	0x0400  /* UDC Endpoint 4 Data Register  */
+#define USBDC_UDDR5	0x00A0  /* UDC Endpoint 5 Data Register  */
+#define USBDC_UDDR6	0x0600  /* UDC Endpoint 6 Data Register  */
+#define USBDC_UDDR7	0x0680  /* UDC Endpoint 7 Data Register  */
+#define USBDC_UDDR8	0x0700  /* UDC Endpoint 8 Data Register  */
+#define USBDC_UDDR9	0x0900  /* UDC Endpoint 9 Data Register  */
+#define USBDC_UDDR10	0x00C0  /* UDC Endpoint 10 Data Register  */
+#define USBDC_UDDR11	0x0B00  /* UDC Endpoint 11 Data Register  */
+#define USBDC_UDDR12	0x0B80  /* UDC Endpoint 12 Data Register  */
+#define USBDC_UDDR13	0x0C00  /* UDC Endpoint 13 Data Register  */
+#define USBDC_UDDR14	0x0E00  /* UDC Endpoint 14 Data Register  */
+#define USBDC_UDDR15	0x00E0  /* UDC Endpoint 15 Data Register  */
+
+#define USBHC_UHCRHDA	0x0048	/* UHC Root Hub Descriptor A */
+#define  UHCRHDA_POTPGT_SHIFT	24	/* Power on to power good time */
+#define  UHCRHDA_NOCP	(1<<12)	/* No over current protection */
+#define  UHCRHDA_OCPM	(1<<11)	/* Over current protection mode */
+#define  UHCRHDA_DT	(1<<10)	/* Device type */
+#define  UHCRHDA_NPS	(1<<9)	/* No power switching */
+#define  UHCRHDA_PSM	(1<<8)	/* Power switching mode */
+#define  UHCRHDA_NDP_MASK	0xff	/* Number downstream ports */
+#define USBHC_UHCRHDB	0x004c	/* UHC Root Hub Descriptor B */
+#define USBHC_UHCRHS	0x0050	/* UHC Root Hub Stauts */
+#define USBHC_UHCHR	0x0064	/* UHC Reset Register */
+#define  UHCHR_SSEP3	(1<<11)	/* Sleep standby enable for port3 */
+#define  UHCHR_SSEP2	(1<<10)	/* Sleep standby enable for port2 */
+#define  UHCHR_SSEP1	(1<<9)	/* Sleep standby enable for port1 */
+#define  UHCHR_PCPL	(1<<7)	/* Power control polarity low */
+#define  UHCHR_PSPL	(1<<6)	/* Power sense polarity low */
+#define  UHCHR_SSE	(1<<5)	/* Sleep standby enable */
+#define  UHCHR_UIT	(1<<4)	/* USB interrupt test */
+#define  UHCHR_SSDC	(1<<3)	/* Simulation scale down clock */
+#define  UHCHR_CGR	(1<<2)	/* Clock generation reset */
+#define  UHCHR_FHR	(1<<1)	/* Force host controller reset */
+#define  UHCHR_FSBIR	(1<<0)	/* Force system bus interface reset */
+#define  UHCHR_MASK	0xeff
+
+/*
+ * PWM controller
+ */
+#define PWM_PWMCR	0x0000	/* Control register */
+#define PWM_PWMDCR	0x0004	/* Duty cycle register */
+#define  PWM_FD		(1<<10)	/* Full duty */
+#define PWM_PWMPCR	0x0008	/* Period register */
+
+/*
+ * OS timer
+ */
+#define	OST_MR0		0x00	/* Match register 0 */
+#define	OST_MR1		0x04	/* Match register 1 */
+#define	OST_MR2		0x08	/* Match register 2 */
+#define	OST_MR3		0x0c	/* Match register 3 */
+#define	OST_CR		0x10	/* Count register */
+#define	OST_SR		0x14	/* Status register */
+#define	 OST_SR_CH0	(1<<0)
+#define	 OST_SR_CH1	(1<<1)
+#define	 OST_SR_CH2	(1<<2)
+#define	 OST_SR_CH3	(1<<3)
+#define	OST_WR		0x18	/* Watchdog enable register */
+#define	OST_IR		0x1c	/* Interrupt enable register */
+
+/*
+ * Interrupt controller
+ */
+#define	ICU_IP		0x00	/* IRQ pending register */
+#define	ICU_MR		0x04	/* Mask register */
+#define	ICU_LR		0x08	/* Level register */
+#define	ICU_FP		0x0c	/* FIQ pending register */
+#define	ICU_PR		0x10	/* Pending register */
+#define	ICU_CR		0x14	/* Control register */
+
+#endif /* _ARM_XSCALE_PXAREG_H_ */


Property changes on: trunk/sys/arm/xscale/pxa/pxareg.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/pxa/pxavar.h
===================================================================
--- trunk/sys/arm/xscale/pxa/pxavar.h	                        (rev 0)
+++ trunk/sys/arm/xscale/pxa/pxavar.h	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,113 @@
+/* $MidnightBSD$ */
+/*	$NetBSD: obiovar.h,v 1.4 2003/06/16 17:40:53 thorpej Exp $	*/
+
+/*-
+ * Copyright (c) 2002, 2003 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Jason R. Thorpe for Wasabi Systems, Inc.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed for the NetBSD Project by
+ *	Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
+ * 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: stable/10/sys/arm/xscale/pxa/pxavar.h 179595 2008-06-06 05:08:09Z benno $
+ *
+ */
+
+#ifndef _PXAVAR_H_
+#define	_PXAVAR_H_
+
+#include <sys/rman.h>
+
+struct obio_softc {
+	bus_space_tag_t obio_bst;	/* bus space tag */
+	struct rman	obio_mem;
+	struct rman	obio_irq;
+};
+
+extern bus_space_tag_t	base_tag;
+extern bus_space_tag_t	obio_tag;
+void		pxa_obio_tag_init(void);
+bus_space_tag_t	pxa_bus_tag_alloc(bus_addr_t);
+
+uint32_t	pxa_gpio_get_function(int);
+uint32_t	pxa_gpio_set_function(int, uint32_t);
+int		pxa_gpio_setup_intrhandler(const char *, driver_filter_t *,
+		    driver_intr_t *, void *, int, int, void **);
+void		pxa_gpio_mask_irq(int);
+void		pxa_gpio_unmask_irq(int);
+int		pxa_gpio_get_next_irq(void);
+
+struct dmac_channel;
+
+struct dmac_descriptor {
+	uint32_t	ddadr;
+	uint32_t	dsadr;
+	uint32_t	dtadr;
+	uint32_t	dcmd;
+};
+#define	DMACD_SET_DESCRIPTOR(d, dadr)	do { d->ddadr = dadr; } while (0)
+#define	DMACD_SET_SOURCE(d, sadr)	do { d->dsadr = sadr; } while (0)
+#define	DMACD_SET_TARGET(d, tadr)	do { d->dtadr = tadr; } while (0)
+#define	DMACD_SET_COMMAND(d, cmd)	do { d->dcmd = cmd; } while (0)
+
+#define	DMAC_PRIORITY_HIGHEST	1
+#define	DMAC_PRIORITY_HIGH	2
+#define	DMAC_PRIORITY_LOW	3
+
+int	pxa_dmac_alloc(int, struct dmac_channel **, int);
+void	pxa_dmac_release(struct dmac_channel *);
+int	pxa_dmac_transfer(struct dmac_channel *, bus_addr_t);
+int	pxa_dmac_transfer_single(struct dmac_channel *,
+		    bus_addr_t, bus_addr_t, uint32_t);
+int	pxa_dmac_transfer_done(struct dmac_channel *);
+int	pxa_dmac_transfer_failed(struct dmac_channel *);
+
+enum pxa_device_ivars {
+	PXA_IVAR_BASE,
+};
+
+enum smi_device_ivars {
+	SMI_IVAR_PHYSBASE,
+};
+
+#define	PXA_ACCESSOR(var, ivar, type)	\
+	__BUS_ACCESSOR(pxa, var, PXA, ivar, type)
+
+PXA_ACCESSOR(base,	BASE,	u_long)
+
+#undef	PXA_ACCESSOR
+
+#define	SMI_ACCESSOR(var, ivar, type)	\
+	__BUS_ACCESSOR(smi, var, SMI, ivar, type)
+
+SMI_ACCESSOR(physbase,	PHYSBASE,	bus_addr_t)
+
+#undef CSR_ACCESSOR
+
+#endif /* _PXAVAR_H_ */


Property changes on: trunk/sys/arm/xscale/pxa/pxavar.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/pxa/std.pxa
===================================================================
--- trunk/sys/arm/xscale/pxa/std.pxa	                        (rev 0)
+++ trunk/sys/arm/xscale/pxa/std.pxa	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,9 @@
+# XScale PXA generic configuration
+# $FreeBSD: stable/10/sys/arm/xscale/pxa/std.pxa 266175 2014-05-15 19:09:31Z ian $
+files		"../xscale/pxa/files.pxa"
+include		"../xscale/std.xscale"
+makeoptions	KERNPHYSADDR=0xa0200000
+makeoptions	KERNVIRTADDR=0xc0200000
+makeoptions	CONF_CFLAGS=-mcpu=xscale
+options		XSCALE_CACHE_READ_WRITE_ALLOCATE
+machine 	arm


Property changes on: trunk/sys/arm/xscale/pxa/std.pxa
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/xscale/pxa/uart_bus_pxa.c
===================================================================
--- trunk/sys/arm/xscale/pxa/uart_bus_pxa.c	                        (rev 0)
+++ trunk/sys/arm/xscale/pxa/uart_bus_pxa.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,104 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2006 Benno Rice.  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 ``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 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: stable/10/sys/arm/xscale/pxa/uart_bus_pxa.c 234004 2012-04-07 23:47:08Z stas $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
+#include <machine/resource.h>
+
+#include <dev/pci/pcivar.h>
+
+#include <dev/uart/uart.h>
+#include <dev/uart/uart_bus.h>
+#include <dev/uart/uart_cpu.h>
+
+#include <dev/ic/ns16550.h>
+
+#include <arm/xscale/pxa/pxavar.h>
+#include <arm/xscale/pxa/pxareg.h>
+
+#include "uart_if.h"
+
+#define	PXA_UART_UUE	0x40	/* UART Unit Enable */
+
+static int uart_pxa_probe(device_t dev);
+
+static device_method_t uart_pxa_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		uart_pxa_probe),
+	DEVMETHOD(device_attach,	uart_bus_attach),
+	DEVMETHOD(device_detach,	uart_bus_detach),
+	{ 0, 0 }
+};
+
+static driver_t uart_pxa_driver = {
+	uart_driver_name,
+	uart_pxa_methods,
+	sizeof(struct uart_softc),
+};
+
+static int
+uart_pxa_probe(device_t dev)
+{
+	bus_space_handle_t	base;
+	struct			uart_softc *sc;
+
+	base = (bus_space_handle_t)pxa_get_base(dev);
+#ifdef QEMU_WORKAROUNDS
+	/*
+	 * QEMU really exposes only the first uart unless
+	 * you specify several of them in the configuration.
+	 * Otherwise all the rest of UARTs stay unconnected,
+	 * which causes problems in the ns16550 attach routine.
+	 * Unfortunately, even if you provide qemu with 4 uarts
+	 * on the command line, it has a bug where it segfaults
+	 * trying to enable bluetooth on the HWUART.  So we just
+	 * allow the FFUART to be attached.
+	 * Also, don't check the UUE (UART Unit Enable) bit, as
+	 * the gumstix bootloader doesn't set it.
+	 */
+	if (base != PXA2X0_FFUART_BASE)
+		return (ENXIO);
+#else
+	/* Check to see if the enable bit's on. */
+	if ((bus_space_read_4(obio_tag, base,
+	    (REG_IER << 2)) & PXA_UART_UUE) == 0)
+		return (ENXIO);
+#endif
+	sc = device_get_softc(dev);
+	sc->sc_class = &uart_ns8250_class;
+
+	return(uart_bus_probe(dev, 2, PXA2X0_COM_FREQ, 0, 0));
+}
+
+DRIVER_MODULE(uart, pxa, uart_pxa_driver, uart_devclass, 0, 0);


Property changes on: trunk/sys/arm/xscale/pxa/uart_bus_pxa.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/pxa/uart_cpu_pxa.c
===================================================================
--- trunk/sys/arm/xscale/pxa/uart_cpu_pxa.c	                        (rev 0)
+++ trunk/sys/arm/xscale/pxa/uart_cpu_pxa.c	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,70 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2003 Marcel Moolenaar
+ * 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 ``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 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: stable/10/sys/arm/xscale/pxa/uart_cpu_pxa.c 179595 2008-06-06 05:08:09Z benno $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/cons.h>
+#include <machine/bus.h>
+
+#include <dev/uart/uart.h>
+#include <dev/uart/uart_cpu.h>
+
+#include <arm/xscale/pxa/pxavar.h>
+#include <arm/xscale/pxa/pxareg.h>
+
+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 ? 1 : 0);
+}
+
+int
+uart_cpu_getdev(int devtype, struct uart_devinfo *di)
+{
+
+	di->ops = uart_getops(&uart_ns8250_class);
+	di->bas.chan = 0;
+	di->bas.bst = obio_tag;
+	di->bas.regshft = 2;
+	di->bas.rclk = PXA2X0_COM_FREQ;
+	di->baudrate = 115200;
+	di->databits = 8;
+	di->stopbits = 1;
+	di->parity = UART_PARITY_NONE;
+	uart_bus_space_mem = obio_tag;
+	uart_bus_space_io = NULL;
+	di->bas.bsh = PXA2X0_FFUART_BASE;
+	return (0);
+}


Property changes on: trunk/sys/arm/xscale/pxa/uart_cpu_pxa.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/arm/xscale/std.xscale
===================================================================
--- trunk/sys/arm/xscale/std.xscale	                        (rev 0)
+++ trunk/sys/arm/xscale/std.xscale	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,3 @@
+# $FreeBSD: stable/10/sys/arm/xscale/std.xscale 239362 2012-08-18 05:48:19Z andrew $
+options		ARM_CACHE_LOCK_ENABLE
+options		NO_EVENTTIMERS


Property changes on: trunk/sys/arm/xscale/std.xscale
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/sys/arm/xscale/std.xscale-be
===================================================================
--- trunk/sys/arm/xscale/std.xscale-be	                        (rev 0)
+++ trunk/sys/arm/xscale/std.xscale-be	2018-06-02 15:44:28 UTC (rev 10219)
@@ -0,0 +1,5 @@
+#Big-Endian XScale generic configuration
+#$FreeBSD: stable/10/sys/arm/xscale/std.xscale-be 239362 2012-08-18 05:48:19Z andrew $
+
+include		"../xscale/std.xscale"
+machine 	arm	armeb


Property changes on: trunk/sys/arm/xscale/std.xscale-be
___________________________________________________________________
Added: mnbsd:nokeywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property


More information about the Midnightbsd-cvs mailing list