? sys/cscope.out ? sys/arch/arm/trustzone Index: sys/arch/arm/allwinner/awin_board.c =================================================================== RCS file: /cvsroot/src/sys/arch/arm/allwinner/awin_board.c,v retrieving revision 1.13 diff -u -p -u -r1.13 awin_board.c --- sys/arch/arm/allwinner/awin_board.c 11 Apr 2014 03:10:13 -0000 1.13 +++ sys/arch/arm/allwinner/awin_board.c 11 Apr 2014 15:32:41 -0000 @@ -224,7 +224,7 @@ awin_cpu_hatch(struct cpu_info *ci) } #endif -psize_t +psize_t awin_memprobe(void) { const uint32_t dcr = bus_space_read_4(&awin_bs_tag, awin_core_bsh, Index: sys/arch/arm/arm32/locore.S =================================================================== RCS file: /cvsroot/src/sys/arch/arm/arm32/locore.S,v retrieving revision 1.35 diff -u -p -u -r1.35 locore.S --- sys/arch/arm/arm32/locore.S 17 Dec 2013 01:27:21 -0000 1.35 +++ sys/arch/arm/arm32/locore.S 11 Apr 2014 15:32:41 -0000 @@ -123,8 +123,8 @@ svcstk: #ifndef OFW /* OFW based systems will used OF_boot() */ - -.Lcpufuncs: + +.Lcpufuncs: .word _C_LABEL(cpufuncs) ENTRY_NP(cpu_reset) Index: sys/arch/arm/cortex/a9_mpsubr.S =================================================================== RCS file: /cvsroot/src/sys/arch/arm/cortex/a9_mpsubr.S,v retrieving revision 1.16 diff -u -p -u -r1.16 a9_mpsubr.S --- sys/arch/arm/cortex/a9_mpsubr.S 11 Apr 2014 02:37:45 -0000 1.16 +++ sys/arch/arm/cortex/a9_mpsubr.S 11 Apr 2014 15:32:41 -0000 @@ -103,7 +103,7 @@ arm_boot_l1pt_init: // Do we need add sharing for this? tst pa, #(L1_S_C|L1_S_B) // is this entry cacheable? orrne pa, pa, attr // add sharing - + 4: cmp n_sec, #0 bne 2b bx lr // return @@ -135,7 +135,7 @@ arm_boot_l1pt_init: #define CPU_CONTROL_AFLT_ENABLE_SET CPU_CONTROL_AFLT_ENABLE #endif -// bits to set in the Control Register +// bits to set in the Control Register // #define CPU_CONTROL_SET \ (CPU_CONTROL_MMU_ENABLE | \ @@ -147,7 +147,7 @@ arm_boot_l1pt_init: CPU_CONTROL_EX_BEND_SET | \ CPU_CONTROL_UNAL_ENABLE) -// bits to clear in the Control Register +// bits to clear in the Control Register // #define CPU_CONTROL_CLR \ (CPU_CONTROL_AFLT_ENABLE_CLR) @@ -156,7 +156,7 @@ arm_cpuinit: // Because the MMU may already be on do a typical sequence to set // the Translation Table Base(s). mov ip, lr - mov r10, r0 // save TTBR + mov r10, r0 // save TTBR mov r1, #0 mcr p15, 0, r1, c7, c5, 0 // invalidate I cache @@ -199,7 +199,7 @@ arm_cpuinit: XPUTC(#72) #if defined(ARM_MMU_EXTENDED) - XPUTC(#49) + XPUTC(#49) mov r1, #TTBCR_S_N_1 // make sure TTBCR_S_N is 1 #else XPUTC(#48) @@ -301,7 +301,7 @@ xputc: #endif mov r2, #TIMO -3: +3: #if COM_MULT == 1 ldrb r1, [r3, #(COM_LSR*COM_MULT)] #else Index: sys/arch/arm/samsung/exynos4_loc.c =================================================================== RCS file: sys/arch/arm/samsung/exynos4_loc.c diff -N sys/arch/arm/samsung/exynos4_loc.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arch/arm/samsung/exynos4_loc.c 11 Apr 2014 15:32:42 -0000 @@ -0,0 +1,273 @@ +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Nick Hudson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this 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 +#include + +#include + +#define IRQ_G3D_IRQGP IRQ_SPI(127) +#define IRQ_G3D_IRQPP3 IRQ_SPI(126) +#define IRQ_G3D_IRQPP2 IRQ_SPI(125) +#define IRQ_G3D_IRQPP1 IRQ_SPI(124) +#define IRQ_G3D_IRQPP0 IRQ_SPI(123) +#define IRQ_G3D_IRQGPMMU IRQ_SPI(122) +#define IRQ_G3D_IRQPPMMU3 IRQ_SPI(121) +#define IRQ_G3D_IRQPPMMU2 IRQ_SPI(120) +#define IRQ_G3D_IRQPPMMU1 IRQ_SPI(119) +#define IRQ_G3D_IRQPPMMU0 IRQ_SPI(118) +#define IRQ_G3D_IRQPMU IRQ_SPI(117) +#define IRQ_C2C_SSCM_1 IRQ_SPI(116) +#define IRQ_TSI IRQ_SPI(115) +#define IRQ_CEC IRQ_SPI(114) +#define IRQ_SLIMBUS IRQ_SPI(113) +#define IRQ_SSS IRQ_SPI(112) +#define IRQ_GPS IRQ_SPI(111) +#define IRQ_PMU IRQ_SPI(110) +#define IRQ_KEYPAD IRQ_SPI(109) + +#define IRQ_FIMC_LITE1 IRQ_SPI(106) +#define IRQ_FIMC_LITE0 IRQ_SPI(105) +#define IRQ_SPDIF IRQ_SPI(104) +#define IRQ_PCM2 IRQ_SPI(103) +#define IRQ_PCM1 IRQ_SPI(102) +#define IRQ_PCM0 IRQ_SPI(101) +#define IRQ_AC97 IRQ_SPI(100) +#define IRQ_I2S2 IRQ_SPI(99) +#define IRQ_I2S1 IRQ_SPI(98) +#define IRQ_I2S0 IRQ_SPI(97) +#define IRQ_AUDIO_SS IRQ_SPI(96) +#define IRQ_ISP_1 IRQ_SPI(95) +#define IRQ_MFC IRQ_SPI(94) +#define IRQ_HDMI_I2C IRQ_SPI(93) +#define IRQ_HDMI IRQ_SPI(92) +#define IRQ_MIXER IRQ_SPI(91) +#define IRQ_ISP_0 IRQ_SPI(90) +#define IRQ_G2D IRQ_SPI(89) +#define IRQ_JPEG IRQ_SPI(88) +#define IRQ_FIMC3 IRQ_SPI(87) +#define IRQ_FIMC2 IRQ_SPI(86) +#define IRQ_FIMC1 IRQ_SPI(85) +#define IRQ_FIMC0 IRQ_SPI(84) +#define IRQ_ROTATOR IRQ_SPI(83) +#define IRQ_MIPI_CSI_2LANE IRQ_SPI(80) +#define IRQ_MIPI_DSI_4LANE IRQ_SPI(79) +#define IRQ_MIPI_CSI_4LANE IRQ_SPI(78) +#define IRQ_SDMMC IRQ_SPI(77) +#define IRQ_HSMMC3 IRQ_SPI(76) +#define IRQ_HSMMC2 IRQ_SPI(75) +#define IRQ_HSMMC1 IRQ_SPI(74) +#define IRQ_HSMMC0 IRQ_SPI(73) +#define IRQ_GPIO_C2C IRQ_SPI(72) +#define IRQ_HSOTG IRQ_SPI(71) +#define IRQ_UHOST IRQ_SPI(70) +#define IRQ_G1_IRQ IRQ_SPI(69) +#define IRQ_SPI2 IRQ_SPI(68) +#define IRQ_SPI1 IRQ_SPI(67) +#define IRQ_SPI0 IRQ_SPI(66) +#define IRQ_I2C7 IRQ_SPI(65) +#define IRQ_I2C6 IRQ_SPI(64) +#define IRQ_I2C5 IRQ_SPI(63) +#define IRQ_I2C4 IRQ_SPI(62) +#define IRQ_I2C3 IRQ_SPI(61) +#define IRQ_I2C2 IRQ_SPI(60) +#define IRQ_I2C1 IRQ_SPI(59) +#define IRQ_I2C0 IRQ_SPI(58) +#define IRQ_G0_IRQ IRQ_SPI(57) +#define IRQ_UART3 IRQ_SPI(55) +#define IRQ_UART2 IRQ_SPI(54) +#define IRQ_UART1 IRQ_SPI(53) +#define IRQ_UART0 IRQ_SPI(52) +#define IRQ_NFC IRQ_SPI(51) +#define IRQ_IEM_IEC IRQ_SPI(50) +#define IRQ_IEM_APC IRQ_SPI(49) +#define IRQ_GPIO_LB IRQ_SPI(47) +#define IRQ_GPIO_RT IRQ_SPI(46) +#define IRQ_RTC_TIC IRQ_SPI(45) +#define IRQ_RTC_ALARM IRQ_SPI(44) +#define IRQ_WDT IRQ_SPI(43) +#define IRQ_TIMER4 IRQ_SPI(41) +#define IRQ_TIMER3 IRQ_SPI(40) +#define IRQ_TIMER2 IRQ_SPI(39) +#define IRQ_TIMER1 IRQ_SPI(38) +#define IRQ_TIMER0 IRQ_SPI(37) +#define IRQ_PDMA1 IRQ_SPI(36) +#define IRQ_PDMA0 IRQ_SPI(35) +#define IRQ_MDMA IRQ_SPI(34) +#define IRQ_C2C_SSCM_0 IRQ_SPI(33) +#define IRQ_EINT16_31 IRQ_SPI(32) +#define IRQ_EINT_15 IRQ_SPI(31) +#define IRQ_EINT_14 IRQ_SPI(30) +#define IRQ_EINT_13 IRQ_SPI(29) +#define IRQ_EINT_12 IRQ_SPI(28) +#define IRQ_EINT_11 IRQ_SPI(27) +#define IRQ_EINT_10 IRQ_SPI(26) +#define IRQ_EINT_9 IRQ_SPI(25) +#define IRQ_EINT_8 IRQ_SPI(24) +#define IRQ_EINT_7 IRQ_SPI(23) +#define IRQ_EINT_6 IRQ_SPI(22) +#define IRQ_EINT_5 IRQ_SPI(21) +#define IRQ_EINT_4 IRQ_SPI(20) +#define IRQ_EINT_3 IRQ_SPI(19) +#define IRQ_EINT_2 IRQ_SPI(18) +#define IRQ_EINT_1 IRQ_SPI(17) +#define IRQ_EINT_0 IRQ_SPI(16) + +#define IRQ_CPU_NIRQOUT_3 EXYNOS_COMBINERIRQ(19, 6) +#define IRQ_PARITYFAILSCU_3 EXYNOS_COMBINERIRQ(19, 5) +#define IRQ_PARITYFAIL3 EXYNOS_COMBINERIRQ(19, 4) +#define IRQ_NCTIIRQ_3 EXYNOS_COMBINERIRQ(19, 3) +#define IRQ_PMUIRQ_3 EXYNOS_COMBINERIRQ(19, 2) +#define IRQ_MCT_L0_IRQ EXYNOS_COMBINERIRQ(19, 0) +#define IRQ_CPU_NIRQOUT_2 EXYNOS_COMBINERIRQ(18, 6) +#define IRQ_PARITYFAILSCU_2 EXYNOS_COMBINERIRQ(18, 5) +#define IRQ_PARITYFAIL2 EXYNOS_COMBINERIRQ(18, 4) +#define IRQ_NCTIIRQ_2 EXYNOS_COMBINERIRQ(18, 3) +#define IRQ_PMUIRQ_2 EXYNOS_COMBINERIRQ(18, 2) +#define IRQ_MCT_L1_IRQ EXYNOS_COMBINERIRQ(18, 0) +#define IRQ_MCT_L2_IRQ EXYNOS_COMBINERIRQ(17, 7) +#define IRQ_SYSMMU_ISP_CX_1 EXYNOS_COMBINERIRQ(17, 5) +#define IRQ_SYSMMU_FIMC_FD_1 EXYNOS_COMBINERIRQ(17, 4) +#define IRQ_SYSMMU_FIMC_DRC_1 EXYNOS_COMBINERIRQ(17, 3) +#define IRQ_SYSMMU_FIMC_ISP_1 EXYNOS_COMBINERIRQ(17, 2) +#define IRQ_SYSMMU_FIMC_LITE1_1 EXYNOS_COMBINERIRQ(17, 1) +#define IRQ_SYSMMU_FIMC_LITE0_1 EXYNOS_COMBINERIRQ(17, 0) +#define IRQ_MCT_L3_IRQ EXYNOS_COMBINERIRQ(16, 7) +#define IRQ_SYSMMU_ISP_CX_0 EXYNOS_COMBINERIRQ(16, 5) +#define IRQ_SYSMMU_FIMC_FD_0 EXYNOS_COMBINERIRQ(16, 4) +#define IRQ_SYSMMU_FIMC_DRC_0 EXYNOS_COMBINERIRQ(16, 3) +#define IRQ_SYSMMU_FIMC_ISP_0 EXYNOS_COMBINERIRQ(16, 2) +#define IRQ_SYSMMU_FIMC_LITE1_0 EXYNOS_COMBINERIRQ(16, 1) +#define IRQ_SYSMMU_FIMC_LITE0_0 EXYNOS_COMBINERIRQ(16, 0) +#define IRQ_DECERRINTR EXYNOS_COMBINERIRQ(15, 7) +#define IRQ_SLVERRINTR EXYNOS_COMBINERIRQ(15, 6) +#define IRQ_ERRRDINTR EXYNOS_COMBINERIRQ(15, 5) +#define IRQ_ERRRTINTR EXYNOS_COMBINERIRQ(15, 4) +#define IRQ_ERRWDINTR EXYNOS_COMBINERIRQ(15, 3) +#define IRQ_ERRWTINTR EXYNOS_COMBINERIRQ(15, 2) +#define IRQ_ECNTRINTR EXYNOS_COMBINERIRQ(15, 1) +#define IRQ_SCUEVABORT EXYNOS_COMBINERIRQ(15, 0) +#define IRQ_CPU_NIRQOUT_1 EXYNOS_COMBINERIRQ(14, 6) +#define IRQ_CPU_NIRQOUT_0 EXYNOS_COMBINERIRQ(13, 5) +#define IRQ_MCT_G3 EXYNOS_COMBINERIRQ(12, 7) +#define IRQ_MCT_G2 EXYNOS_COMBINERIRQ(12, 6) +#define IRQ_MCT_G1 EXYNOS_COMBINERIRQ(12, 5) +#define IRQ_MCT_G0 EXYNOS_COMBINERIRQ(12, 4) +#define IRQ_MIPI_HSI EXYNOS_COMBINERIRQ(12, 1) +#define IRQ_UART4 EXYNOS_COMBINERIRQ(12, 0) +#define IRQ_LCD0_3 EXYNOS_COMBINERIRQ(11, 3) +#define IRQ_LCD0_2 EXYNOS_COMBINERIRQ(11, 2) +#define IRQ_LCD0_1 EXYNOS_COMBINERIRQ(11, 1) +#define IRQ_LCD0_0 EXYNOS_COMBINERIRQ(11, 0) +#define IRQ_DMC1_PPC_PEREV_M EXYNOS_COMBINERIRQ(10, 7) +#define IRQ_DMC1_PPC_PEREV_A EXYNOS_COMBINERIRQ(10, 6) +#define IRQ_DMC0_PPC_PEREV_M EXYNOS_COMBINERIRQ(10, 5) +#define IRQ_DMC0_PPC_PEREV_A EXYNOS_COMBINERIRQ(10, 4) +#define IRQ_ADC EXYNOS_COMBINERIRQ(10, 3) +#define IRQ_L2CACHE EXYNOS_COMBINERIRQ(10, 2) +#define IRQ_RP_TIMER EXYNOS_COMBINERIRQ(10, 1) +#define IRQ_GPIO_AUDIO EXYNOS_COMBINERIRQ(10, 0) +#define IRQ_PPMU_ISP_X EXYNOS_COMBINERIRQ(9, 7) +#define IRQ_PPMU_MFC_M1 EXYNOS_COMBINERIRQ(9, 6) +#define IRQ_PPMU_MFC_M0 EXYNOS_COMBINERIRQ(9, 5) +#define IRQ_PPMU_3D EXYNOS_COMBINERIRQ(9, 4) +#define IRQ_PPMU_TV_M0 EXYNOS_COMBINERIRQ(9, 3) +#define IRQ_PPMU_FILE_D_M0 EXYNOS_COMBINERIRQ(9, 2) +#define IRQ_PPMU_ISP_MX EXYNOS_COMBINERIRQ(9, 1) +#define IRQ_PPMU_LCD0 EXYNOS_COMBINERIRQ(9, 0) +#define IRQ_PPMU_IMAGE_M0 EXYNOS_COMBINERIRQ(8, 7) +#define IRQ_PPMU_CAMIF_M0 EXYNOS_COMBINERIRQ(8, 6) +#define IRQ_PPMU_D_RIGHT_M0 EXYNOS_COMBINERIRQ(8, 5) +#define IRQ_PPMU_D_LEFT_M0 EXYNOS_COMBINERIRQ(8, 4) +#define IRQ_PPMU_ACP0_M0 EXYNOS_COMBINERIRQ(8, 3) +#define IRQ_PPMU_XIU_R_S1 EXYNOS_COMBINERIRQ(8, 2) +#define IRQ_PPMU_XIU_R EXYNOS_COMBINERIRQ(8, 1) +#define IRQ_PPMU_XIU_L EXYNOS_COMBINERIRQ(8, 0) +#define IRQ_SYSMMU_MFC_M1_1 EXYNOS_COMBINERIRQ(7, 6) +#define IRQ_SYSMMU_MFC_M0_1 EXYNOS_COMBINERIRQ(7, 5) +#define IRQ_SYSMMU_TV_M0_1 EXYNOS_COMBINERIRQ(7, 4) +#define IRQ_SYSMMU_LCD0_M0_1 EXYNOS_COMBINERIRQ(7, 2) +#define IRQ_SYSMMU_GPS_1 EXYNOS_COMBINERIRQ(7, 1) +#define IRQ_SYSMMU_ROTATOR_1 EXYNOS_COMBINERIRQ(7, 0) +#define IRQ_SYSMMU_2D_1 EXYNOS_COMBINERIRQ(6, 7) +#define IRQ_SYSMMU_JPEG_1 EXYNOS_COMBINERIRQ(6, 6) +#define IRQ_SYSMMU_FIMC3_1 EXYNOS_COMBINERIRQ(6, 5) +#define IRQ_SYSMMU_FIMC2_1 EXYNOS_COMBINERIRQ(6, 4) +#define IRQ_SYSMMU_FIMC1_1 EXYNOS_COMBINERIRQ(6, 3) +#define IRQ_SYSMMU_FIMC0_1 EXYNOS_COMBINERIRQ(6, 2) +#define IRQ_SYSMMU_SSS_1 EXYNOS_COMBINERIRQ(6, 1) +#define IRQ_SYSMMU_MDMA_1 EXYNOS_COMBINERIRQ(6, 0) +#define IRQ_SYSMMU_MFC_M1_0 EXYNOS_COMBINERIRQ(5, 6) +#define IRQ_SYSMMU_MFC_M0_0 EXYNOS_COMBINERIRQ(5, 5) +#define IRQ_SYSMMU_TV_M0_0 EXYNOS_COMBINERIRQ(5, 4) +#define IRQ_SYSMMU_LCD0_M0_0 EXYNOS_COMBINERIRQ(5, 2) +#define IRQ_SYSMMU_GPS_0 EXYNOS_COMBINERIRQ(5, 1) +#define IRQ_SYSMMU_ROTATOR_0 EXYNOS_COMBINERIRQ(5, 0) +#define IRQ_SYSMMU_2D_0 EXYNOS_COMBINERIRQ(4, 7) +#define IRQ_SYSMMU_JPEG_0 EXYNOS_COMBINERIRQ(4, 6) +#define IRQ_SYSMMU_FIMC3_0 EXYNOS_COMBINERIRQ(4, 5) +#define IRQ_SYSMMU_FIMC2_0 EXYNOS_COMBINERIRQ(4, 4) +#define IRQ_SYSMMU_FIMC1_0 EXYNOS_COMBINERIRQ(4, 3) +#define IRQ_SYSMMU_FIMC0_0 EXYNOS_COMBINERIRQ(4, 2) +#define IRQ_SYSMMU_SSS_0 EXYNOS_COMBINERIRQ(4, 1) +#define IRQ_SYSMMU_MDMA_0 EXYNOS_COMBINERIRQ(4, 0) +#define IRQ_NCTIIRQ_ISP EXYNOS_COMBINERIRQ(3, 6) +#define IRQ_PMUIRQ_ISP EXYNOS_COMBINERIRQ(3, 5) +#define IRQ_TMU_1 EXYNOS_COMBINERIRQ(3, 4) +#define IRQ_NCTIIRQ_1 EXYNOS_COMBINERIRQ(3, 3) +#define IRQ_PMUIRQ_1 EXYNOS_COMBINERIRQ(3, 2) +#define IRQ_PARITYFAILSCU_1 EXYNOS_COMBINERIRQ(3, 1) +#define IRQ_PARITYFAIL1 EXYNOS_COMBINERIRQ(3, 0) +#define IRQ_PARRINTR EXYNOS_COMBINERIRQ(2, 6) +#define IRQ_PARRDINTR EXYNOS_COMBINERIRQ(2, 5) +#define IRQ_TMU_0 EXYNOS_COMBINERIRQ(2, 4) +#define IRQ_NCTIIRQ_0 EXYNOS_COMBINERIRQ(2, 3) +#define IRQ_PMUIRQ_0 EXYNOS_COMBINERIRQ(2, 2) +#define IRQ_PARITYFAILSCU_0 EXYNOS_COMBINERIRQ(2, 1) +#define IRQ_PARITYFAIL0 EXYNOS_COMBINERIRQ(2, 0) +#define IRQ_TZASC1_1 EXYNOS_COMBINERIRQ(1, 3) +#define IRQ_TZASC1_0 EXYNOS_COMBINERIRQ(1, 2) +#define IRQ_TZASC0_1 EXYNOS_COMBINERIRQ(1, 1) +#define IRQ_TZASC0_0 EXYNOS_COMBINERIRQ(1, 0) +#define IRQ_MDNIE_LCD0_3 EXYNOS_COMBINERIRQ(0, 3) +#define IRQ_MDNIE_LCD0_2 EXYNOS_COMBINERIRQ(0, 2) +#define IRQ_MDNIE_LCD0_1 EXYNOS_COMBINERIRQ(0, 1) +#define IRQ_MDNIE_LCD0_0 EXYNOS_COMBINERIRQ(0, 0) + +#define OFFANDSIZE(p,n) EXYNOS4##p##_##n##_OFFSET, 0x10000 + + +static const struct exyo_locators exynos4_locators[] = { + { "mct", OFFANDSIZE(,MCT), NOPORT, IRQ_MCT_LTIMER, 0 }, +}; + +struct exyo_locinfo exynos4_locinfo = { + .locators = exynos4_locators, + .nlocators = __arraycount(exynos4_locators) +}; Index: sys/arch/arm/samsung/exynos4_reg.h =================================================================== RCS file: sys/arch/arm/samsung/exynos4_reg.h diff -N sys/arch/arm/samsung/exynos4_reg.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arch/arm/samsung/exynos4_reg.h 11 Apr 2014 15:32:42 -0000 @@ -0,0 +1,265 @@ +/* $NetBSD */ +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Reinoud Zandijk. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this 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. + */ + +#ifndef _ARM_SAMSUNG_EXYNOS4_REG_H_ +#define _ARM_SAMSUNG_EXYNOS4_REG_H_ + +/* + * Physical memory layout of Exynos SoCs as per documentation + * + * Base Address Limit Address Size Description + * 0x00000000 0x00010000 64 KB iROM + * 0x02000000 0x02010000 64 KB iROM (mirror of 0x0 to 0x10000) + * 0x02020000 0x02060000 256 KB iRAM + * 0x03000000 0x03020000 128 KB Data memory or general purpose of Samsung + * Reconfigurable Processor SRP. + * 0x03020000 0x03030000 64 KB I-cache or general purpose of SRP. + * 0x03030000 0x03039000 36 KB Configuration memory (write only) of SRP + * 0x03810000 0x03830000 ­ AudioSS's SFR region + * 0x04000000 0x05000000 16 MB Bank0 of Static ROM Controller (SMC) + * (16-bit only) + * 0x05000000 0x06000000 16 MB Bank1 of SMC + * 0x06000000 0x07000000 16 MB Bank2 of SMC + * 0x07000000 0x08000000 16 MB Bank3 of SMC + * 0x08000000 0x0C000000 64 MB Reserved + * 0x0C000000 0x0CD00000 ­ Reserved + * 0x0CE00000 0x0D000000 ­ SFR region of Nand Flash Contr. (NFCON) + * 0x10000000 0x14000000 ­ SFR region + * 0x40000000 0xA0000000 1.5 GB Memory of Dynamic Memory Contr. (DMC)-0 + * 0xA0000000 0x00000000 1.5 GB Memory of DMC-1 +*/ + +/* + * + * The exynos can boot from its iROM or from an external Nand memory. Since + * these are normally hardly used they are excluded from the normal register + * space here. + * + * XXX What about the audio subsystem region. Where are the docs? + * + * EXYNOS_CORE_PBASE points to the main SFR region. + * + * Notes: + * + * SFR Special Function Register + * ISP In-System Programming, like a JTAG + * ACP Accelerator Coherency Port + * SSS Security Sub System + * GIC Generic Interurrupt Controller + * PMU Power Management Unit + * DMC 2D Graphics engine + * LEFTBUS Data bus / Peripheral bus + * RIGHTBUS ,, + * G3D 3D Graphics engine + * MFC Multi-Format Codec + * LCD0 LCD display + * MCT Multi Core Timer + * CMU Clock Management Unit + * TMU Thermal Management Unit + * PPMU Pin Parametric Measurement Unit (?) + * MMU Memory Management Unit + * MCTimer ? + * WDT Watch Dog Timer + * RTC Real Time Clock + * KEYIF Keypad interface + * SECKEY ? + * TZPC TrustZone Protection Controller + * UART Universal asynchronous receiver/transmitter + * I2C Inter IC Connect + * SPI Serial Peripheral Interface Bus + * I2S Inter-IC Sound, Integrated Interchip Sound, or IIS + * PCM Pulse-code modulation, audio stream at set fixed rate + * SPDIF Sony/Philips Digital Interface Format + * Slimbus Serial Low-power Inter-chip Media Bus + * SMMU System mmu. No idea as how its programmed (or not) + * PERI-L UART, I2C, SPI, I2S, PCM, SPDIF, PWM, I2CHDMI, Slimbus + * PERI-R CHIPID, SYSREG, PMU/CMU/TMU Bus I/F, MCTimer, WDT, RTC, KEYIF, + * SECKEY, TZPC + */ + +/* + * Note that this table is not 80-char friendly, this is done to allow more + * elaborate comments to clarify the register offsets use + */ + +#define EXYNOS4_CORE_SIZE 0x04000000 +#define EXYNOS4_SDRAM_PBASE 0x40000000 + +#define EXYNOS4_SYSREG_OFFSET 0x00010000 +#define EXYNOS4_PMU_OFFSET 0x00020000 /* Power Management Unit */ +#define EXYNOS4_CMU_TOP_PART_OFFSET 0x00030000 /* XXX unknown XXX */ +#define EXYNOS4_CMU_CORE_ISP_PART_OFFSET 0x00040000 /* XXX unknown XXX */ +#define EXYNOS4_MCT_OFFSET 0x00050000 /* Multi Core Timer */ +#define EXYNOS4_WDT_OFFSET 0x00060000 /* Watch Dog Timer */ +#define EXYNOS4_RTC_OFFSET 0x00070000 /* Real Time Clock */ +#define EXYNOS4_KEYIF_OFFSET 0x000A0000 /* Keypad interface */ +#define EXYNOS4_HDMI_CEC_OFFSET 0x000B0000 /* HDMI Consumer Electronic Control */ +#define EXYNOS4_TMU_OFFSET 0x000C0000 /* Thermal Managment */ +#define EXYNOS4_SECKEY_OFFSET 0x00100000 /* XXX unknown XXX */ +#define EXYNOS4_TZPC0_OFFSET 0x00110000 /* ARM Trusted Zone Protection Controller */ +#define EXYNOS4_TZPC1_OFFSET 0x00120000 +#define EXYNOS4_TZPC2_OFFSET 0x00130000 +#define EXYNOS4_TZPC3_OFFSET 0x00140000 +#define EXYNOS4_TZPC4_OFFSET 0x00150000 +#define EXYNOS4_TZPC5_OFFSET 0x00160000 +#define EXYNOS4_INTCOMBINER_OFFSET 0x00440000 /* combines first 32 interrupt sources */ +#define EXYNOS4_GIC_CNTR_OFFSET 0x00480000 /* generic interrupt controller offset */ +#define EXYNOS4_GIC_DISTRIBUTOR_OFFSET 0x00490000 +#define EXYNOS4_AP_C2C_OFFSET 0x00540000 /* Chip 2 Chip XXX doc? XXX */ +#define EXYNOS4_CP_C2C_MODEM_OFFSET 0x00580000 +#define EXYNOS4_DMC0_OFFSET 0x00600000 /* Dynamic Memory Controller */ +#define EXYNOS4_DMC1_OFFSET 0x00610000 +#define EXYNOS4_PPMU_DMC_L_OFFSET 0x006A0000 /* event counters XXX ? */ +#define EXYNOS4_PPMU_DMC_R_OFFSET 0x006B0000 +#define EXYNOS4_PPMU_CPU_OFFSET 0x006C0000 +#define EXYNOS4_GPIO_C2C_OFFSET 0x006E0000 +#define EXYNOS4_TZASC_LR_OFFSET 0x00700000 /* trust zone access control */ +#define EXYNOS4_TZASC_LW_OFFSET 0x00710000 +#define EXYNOS4_TZASC_RR_OFFSET 0x00720000 +#define EXYNOS4_TZASC_RW_OFFSET 0x00730000 +#define EXYNOS4_G2D_ACP_OFFSET 0x00800000 /* 2D graphics engine */ +#define EXYNOS4_SSS_OFFSET 0x00830000 /* Security Sub System */ +#define EXYNOS4_CORESIGHT_1_OFFSET 0x00880000 /* 1st region */ +#define EXYNOS4_CORESIGHT_2_OFFSET 0x00890000 /* 2nd region */ +#define EXYNOS4_CORESIGHT_3_OFFSET 0x008B0000 /* 3rd region */ +#define EXYNOS4_SMMUG2D_ACP_OFFSET 0x00A40000 /* system mmu for 2D graphics engine */ +#define EXYNOS4_SMMUSSS_OFFSET 0x00A50000 /* system mmu for SSS */ +#define EXYNOS4_GPIO_RIGHT_OFFSET 0x01000000 +#define EXYNOS4_GPIO_LEFT_OFFSET 0x01400000 +#define EXYNOS4_FIMC0_OFFSET 0x01800000 /* image for display */ +#define EXYNOS4_FIMC1_OFFSET 0x01810000 +#define EXYNOS4_FIMC2_OFFSET 0x01820000 +#define EXYNOS4_FIMC3_OFFSET 0x01830000 +#define EXYNOS4_JPEG_OFFSET 0x01840000 /* JPEG Codec */ +#define EXYNOS4_MIPI_CSI0_OFFSET 0x01880000 /* MIPI-Slim bus Interface */ +#define EXYNOS4_MIPI_CSI1_OFFSET 0x01890000 +#define EXYNOS4_SMMUFIMC0_OFFSET 0x01A20000 /* system mmus */ +#define EXYNOS4_SMMUFIMC1_OFFSET 0x01A30000 +#define EXYNOS4_SMMUFIMC2_OFFSET 0x01A40000 +#define EXYNOS4_SMMUFIMC3_OFFSET 0x01A50000 +#define EXYNOS4_SMMUJPEG_OFFSET 0x01A60000 +#define EXYNOS4_FIMD0_OFFSET 0x01C00000 /* LCD0 */ +#define EXYNOS4_MIPI_DSI0_OFFSET 0x01C80000 /* LCD0 */ +#define EXYNOS4_SMMUFIMD0_OFFSET 0x01E20000 /* system mmus */ +#define EXYNOS4_FIMC_ISP_OFFSET 0x02000000 /* (digital) camera video input */ +#define EXYNOS4_FIMC_DRC_TOP_OFFSET 0x02010000 +#define EXYNOS4_FIMC_FD_TOP_OFFSET 0x02040000 +#define EXYNOS4_MPWM_ISP_OFFSET 0x02110000 /* (specialised?) PWM */ +#define EXYNOS4_I2C0_ISP_OFFSET 0x02130000 /* I2C bus */ +#define EXYNOS4_I2C1_ISP_OFFSET 0x02140000 +#define EXYNOS4_MTCADC_ISP_OFFSET 0x02150000 /* (specialised?) AD Converter */ +#define EXYNOS4_PWM_ISP_OFFSET 0x02160000 /* PWM */ +#define EXYNOS4_WDT_ISP_OFFSET 0x02170000 /* Watch Dog Timer */ +#define EXYNOS4_MCUCTL_ISP_OFFSET 0x02180000 /* XXX micro controller control unit? */ +#define EXYNOS4_UART_ISP_OFFSET 0x02190000 /* uart base clock */ +#define EXYNOS4_SPI0_ISP_OFFSET 0x021A0000 +#define EXYNOS4_SPI1_ISP_OFFSET 0x021B0000 +#define EXYNOS4_GIC_C_ISP_OFFSET 0x021E0000 +#define EXYNOS4_GIC_D_ISP_OFFSET 0x021F0000 +#define EXYNOS4_SYSMMU_FIMC_ISP_OFFSET 0x02260000 +#define EXYNOS4_SYSMMU_FIMC_DRC_OFFSET 0x02270000 +#define EXYNOS4_SYSMMU_FIMC_FD_OFFSET 0x022A0000 +#define EXYNOS4_SYSMMU_ISPCPU_OFFSET 0x022B0000 +#define EXYNOS4_FIMC_LITE0_OFFSET 0x02390000 /* external image input? */ +#define EXYNOS4_FIMC_LITE1_OFFSET 0x023A0000 +#define EXYNOS4_SYSMMU_FIMC_LITE0_OFFSET 0x023B0000 +#define EXYNOS4_SYSMMU_FIMC_LITE1_OFFSET 0x023C0000 +#define EXYNOS4_USBDEV0_OFFSET 0x02480000 /* XXX unknown XXX */ +#define EXYNOS4_USBDEV0_1_OFFSET 0x02480000 +#define EXYNOS4_USBDEV0_2_OFFSET 0x02490000 +#define EXYNOS4_USBDEV0_3_OFFSET 0x024A0000 +#define EXYNOS4_USBDEV0_4_OFFSET 0x024B0000 +#define EXYNOS4_TSI_OFFSET 0x02500000 /* Transport Stream Interface */ +#define EXYNOS4_SDMMC0_OFFSET 0x02510000 /* SD card interface */ +#define EXYNOS4_SDMMC1_OFFSET 0x02520000 +#define EXYNOS4_SDMMC2_OFFSET 0x02530000 +#define EXYNOS4_SDMMC3_OFFSET 0x02540000 +#define EXYNOS4_SDMMC4_OFFSET 0x02550000 +#define EXYNOS4_MIPI_HSI_OFFSET 0x02560000 /* LCD0 */ +#define EXYNOS4_SROMC_OFFSET 0x02570000 +#define EXYNOS4_USBHOST0_OFFSET 0x02580000 /* USB interface 0 */ +#define EXYNOS4_USBHOST1_OFFSET 0x02590000 /* USB interface 1 */ +#define EXYNOS4_USBOTG1_OFFSET 0x025B0000 /* USB On The Go interface */ +#define EXYNOS4_PDMA0_OFFSET 0x02680000 /* Peripheral DMA */ +#define EXYNOS4_PDMA1_OFFSET 0x02690000 +#define EXYNOS4_GADC_OFFSET 0x026C0000 /* General AD Converter */ +#define EXYNOS4_ROTATOR_OFFSET 0x02810000 /* Image rotator for video output */ +#define EXYNOS4_SMDMA_OFFSET 0x02840000 /* (s) Memory DMA */ +#define EXYNOS4_NSMDMA_OFFSET 0x02850000 /* (ns) Memory DMA */ +#define EXYNOS4_SMMUROTATOR_OFFSET 0x02A30000 /* system mmu for rotator */ +#define EXYNOS4_SMMUMDMA_OFFSET 0x02A40000 +#define EXYNOS4_VP_OFFSET 0x02C00000 /* Video Processor */ +#define EXYNOS4_MIXER_OFFSET 0x02C10000 /* Video mixer */ +#define EXYNOS4_HDMI0_OFFSET 0x02D00000 +#define EXYNOS4_HDMI1_OFFSET 0x02D10000 +#define EXYNOS4_HDMI2_OFFSET 0x02D20000 +#define EXYNOS4_HDMI3_OFFSET 0x02D30000 +#define EXYNOS4_HDMI4_OFFSET 0x02D40000 +#define EXYNOS4_HDMI5_OFFSET 0x02D50000 +#define EXYNOS4_HDMI6_OFFSET 0x02D60000 +#define EXYNOS4_SMMUTV_OFFSET 0x02E20000 +#define EXYNOS4_G3D_OFFSET 0x03000000 /* 3D Graphics Accelerator */ +#define EXYNOS4_PPMU_3D_OFFSET 0x03220000 +#define EXYNOS4_MFC_OFFSET 0x03400000 /* Multi Format Codec */ +#define EXYNOS4_SMMUMFC_L_OFFSET 0x03620000 +#define EXYNOS4_SMMUMFC_R_OFFSET 0x03630000 +#define EXYNOS4_PMMU_MFC_L_OFFSET 0x03660000 /* ? */ +#define EXYNOS4_PMMU_MFC_R_OFFSET 0x03670000 /* ? */ +#define EXYNOS4_UART0_OFFSET 0x03800000 /* serial port 0 */ +#define EXYNOS4_UART1_OFFSET 0x03810000 /* serial port 1 */ +#define EXYNOS4_UART2_OFFSET 0x03820000 /* serial port 2 */ +#define EXYNOS4_UART3_OFFSET 0x03830000 /* serial port 3 */ +#define EXYNOS4_UART4_OFFSET 0x03840000 /* serial port 4 */ +#define EXYNOS4_I2C0_OFFSET 0x03860000 /* Inter Integrated Circuit (I2C) */ +#define EXYNOS4_I2C1_OFFSET 0x03870000 /* Inter Integrated Circuit (I2C) */ +#define EXYNOS4_I2C2_OFFSET 0x03880000 /* Inter Integrated Circuit (I2C) */ +#define EXYNOS4_I2C3_OFFSET 0x03890000 /* Inter Integrated Circuit (I2C) */ +#define EXYNOS4_I2C4_OFFSET 0x038A0000 /* Inter Integrated Circuit (I2C) */ +#define EXYNOS4_I2C5_OFFSET 0x038B0000 /* Inter Integrated Circuit (I2C) */ +#define EXYNOS4_I2C6_OFFSET 0x038C0000 /* Inter Integrated Circuit (I2C) */ +#define EXYNOS4_I2C7_OFFSET 0x038D0000 /* Inter Integrated Circuit (I2C) */ +#define EXYNOS4_I2CHDMI_OFFSET 0x038E0000 /* I2C for HDMI */ +#define EXYNOS4_SPI0_OFFSET 0x03920000 /* Serial Peripheral Interface0 */ +#define EXYNOS4_SPI1_OFFSET 0x03930000 /* Serial Peripheral Interface0 */ +#define EXYNOS4_SPI2_OFFSET 0x03940000 /* Serial Peripheral Interface0 */ +#define EXYNOS4_I2S1_OFFSET 0x03960000 /* sound */ +#define EXYNOS4_I2S2_OFFSET 0x03970000 /* sound */ +#define EXYNOS4_PCM1_OFFSET 0x03980000 /* sound */ +#define EXYNOS4_PCM2_OFFSET 0x03990000 /* sound */ +#define EXYNOS4_AC97_OFFSET 0x039A0000 /* AC97 audio codec sound */ +#define EXYNOS4_SPDIF_OFFSET 0x039B0000 /* SPDIF sound */ +#define EXYNOS4_PWMTIMER_OFFSET 0x039D0000 + +/* standard frequency settings */ +#define EXYNOS4_ACLK_REF_FREQ (200*1000*1000) /* 200 Mhz */ +#define EXYNOS4_UART_FREQ (109*1000*1000) /* should be EXYNOS_ACLK_REF_FREQ! */ + +#endif /* _ARM_SAMSUNG_EXYNOS5_REG_H_ */ + Index: sys/arch/arm/samsung/exynos5_loc.c =================================================================== RCS file: sys/arch/arm/samsung/exynos5_loc.c diff -N sys/arch/arm/samsung/exynos5_loc.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arch/arm/samsung/exynos5_loc.c 11 Apr 2014 15:32:42 -0000 @@ -0,0 +1,221 @@ +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Nick Hudson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this 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 +#include + +#include + +#define IRQ_RP_TIMER IRQ_SPI(127) +#define IRQ_CAM_B IRQ_SPI(126) +#define IRQ_CAM_A IRQ_SPI(125) +#define IRQ_MDMA1 IRQ_SPI(124) +#define IRQ_MCT_L1 IRQ_SPI(121) +#define IRQ_MCT_L0 IRQ_SPI(120) +#define IRQ_G3D_IRQMMU IRQ_SPI(119) +#define IRQ_G3D_IRQJOB IRQ_SPI(118) +#define IRQ_G3D_IRQGPU IRQ_SPI(117) +#define IRQ_SATA IRQ_SPI(115) +#define IRQ_CEC IRQ_SPI(114) +#define IRQ_DP1_1 IRQ_SPI(113) +#define IRQ_INTFEEDCTRL_SSS IRQ_SPI(112) +#define IRQ_PMU IRQ_SPI(111) +#define IRQ_CAM_C IRQ_SPI(110) +#define IRQ_SATAPMEREQ IRQ_SPI(109) +#define IRQ_SATAPHY IRQ_SPI(108) +#define IRQ_ADC0 IRQ_SPI(106) +#define IRQ_SPDIF IRQ_SPI(105) +#define IRQ_PCM2 IRQ_SPI(104) +#define IRQ_PCM1 IRQ_SPI(103) +#define IRQ_PCM0 IRQ_SPI(102) +#define IRQ_AC97 IRQ_SPI(101) +#define IRQ_I2S2 IRQ_SPI(100) +#define IRQ_I2S1 IRQ_SPI(99) +#define IRQ_I2S0 IRQ_SPI(98) +#define IRQ_AUDIO_SS IRQ_SPI(97) +#define IRQ_MFC IRQ_SPI(96) +#define IRQ_HDMI IRQ_SPI(95) +#define IRQ_MIXER IRQ_SPI(94) +#define IRQ_EFNFCON_1 IRQ_SPI(93) +#define IRQ_EFNFCON_0 IRQ_SPI(92) +#define IRQ_G2D IRQ_SPI(91) +#define IRQ_EFNFCON_DMA IRQ_SPI(90) +#define IRQ_JPEG IRQ_SPI(89) +#define IRQ_GSCL3 IRQ_SPI(88) +#define IRQ_GSCL2 IRQ_SPI(87) +#define IRQ_GSCL1 IRQ_SPI(86) +#define IRQ_GSCL0 IRQ_SPI(85) +#define IRQ_ROTATOR IRQ_SPI(84) +#define IRQ_WDT_IOP IRQ_SPI(83) +#define IRQ_MIPI_DSI_4LANE IRQ_SPI(82) +#define IRQ_EFNFCON_DMA_ABORT IRQ_SPI(81) +#define IRQ_MIPI_CSI_B IRQ_SPI(80) +#define IRQ_MIPI_CSI_A IRQ_SPI(79) +#define IRQ_SDMMC3 IRQ_SPI(78) +#define IRQ_SDMMC2 IRQ_SPI(77) +#define IRQ_SDMMC1 IRQ_SPI(76) +#define IRQ_SDMMC0 IRQ_SPI(75) +#define IRQ_USBOTG IRQ_SPI(74) +#define IRQ_MIPI_HSI IRQ_SPI(73) +#define IRQ_USB_DRD30 IRQ_SPI(72) +#define IRQ_USB_HOST20 IRQ_SPI(71) +#define IRQ_SPI2 IRQ_SPI(70) +#define IRQ_SPI1 IRQ_SPI(69) +#define IRQ_SPI0 IRQ_SPI(68) +#define IRQ_CPU_NFIQ_1 IRQ_SPI(67) +#define IRQ_CPU_NFIQ_0 IRQ_SPI(66) +#define IRQ_TMU IRQ_SPI(65) +#define IRQ_I2C IRQ_SPI(64) +#define IRQ_I2C7 IRQ_SPI(63) +#define IRQ_I2C6 IRQ_SPI(62) +#define IRQ_I2C5 IRQ_SPI(61) +#define IRQ_I2C4 IRQ_SPI(60) +#define IRQ_I2C3_USI3 IRQ_SPI(59) +#define IRQ_I2C2_USI2 IRQ_SPI(58) +#define IRQ_I2C1_USI1 IRQ_SPI(57) +#define IRQ_I2C0_USI0 IRQ_SPI(56) +#define IRQ_MONOCNT IRQ_SPI(55) +#define IRQ_UART3 IRQ_SPI(54) +#define IRQ_UART2 IRQ_SPI(53) +#define IRQ_UART1 IRQ_SPI(52) +#define IRQ_UART0 IRQ_SPI(51) +#define IRQ_GPIO_C2C IRQ_SPI(50) +#define IRQ_GPIO IRQ_SPI(47) +#define IRQ_GPIO_LB IRQ_SPI(46) +#define IRQ_GPIO_RT IRQ_SPI(45) +#define IRQ_RTC_TIC IRQ_SPI(44) +#define IRQ_RTC_ALARM IRQ_SPI(43) +#define IRQ_WDT IRQ_SPI(42) +#define IRQ_RTIC IRQ_SPI(41) +#define IRQ_TIMER4 IRQ_SPI(40) +#define IRQ_TIMER3 IRQ_SPI(39) +#define IRQ_TIMER2 IRQ_SPI(38) +#define IRQ_TIMER1 IRQ_SPI(37) +#define IRQ_TIMER0 IRQ_SPI(36) +#define IRQ_PDMA1 IRQ_SPI(35) +#define IRQ_PDMA0 IRQ_SPI(34) +#define IRQ_MDMA0_CORE IRQ_SPI(33) + +#define IRQ_SYSMMU_DRCISP_1 EXYNOS_COMBINERIRQ(11, 7) +#define IRQ_SYSMMU_ODC_1 EXYNOS_COMBINERIRQ(11, 1) +#define IRQ_SYSMMU_ODC_0 EXYNOS_COMBINERIRQ(11, 0) + +#define IRQ_SYSMMU_ISP_1 EXYNOS_COMBINERIRQ(10, 7) +#define IRQ_SYSMMU_ISP_0 EXYNOS_COMBINERIRQ(10, 6) +#define IRQ_SYSMMU_DIS0_1 EXYNOS_COMBINERIRQ(10, 5) +#define IRQ_SYSMMU_DIS0_0 EXYNOS_COMBINERIRQ(10, 4) +#define IRQ_DP1 EXYNOS_COMBINERIRQ(10, 3) + +#define IRQ_SYSMMU_DIS1_1 EXYNOS_COMBINERIRQ(9, 5) +#define IRQ_SYSMMU_DIS1_0 EXYNOS_COMBINERIRQ(9, 4) + +#define IRQ_SYSMMU_MFCL_1 EXYNOS_COMBINERIRQ(8, 6) +#define IRQ_SYSMMU_MFCL_0 EXYNOS_COMBINERIRQ(8, 5) + +#define IRQ_SYSMMU_TV_M0_1 EXYNOS_COMBINERIRQ(7, 5) +#define IRQ_SYSMMU_TV_M0_0 EXYNOS_COMBINERIRQ(7, 4) +#define IRQ_SYSMMU_MDMA1_1 EXYNOS_COMBINERIRQ(7, 3) +#define IRQ_SYSMMU_MDMA1_0 EXYNOS_COMBINERIRQ(7, 2) +#define IRQ_SYSMMU_MDMA0_1 EXYNOS_COMBINERIRQ(7, 1) +#define IRQ_SYSMMU_MDMA0_0 EXYNOS_COMBINERIRQ(7, 0) + +#define IRQ_SYSMMU_SSS_1 EXYNOS_COMBINERIRQ(6, 7) +#define IRQ_SYSMMU_SSS_0 EXYNOS_COMBINERIRQ(6, 6) +#define IRQ_SYSMMU_RTIC_1 EXYNOS_COMBINERIRQ(6, 5) +#define IRQ_SYSMMU_RTIC_0 EXYNOS_COMBINERIRQ(6, 4) +#define IRQ_SYSMMU_MFCR_1 EXYNOS_COMBINERIRQ(6, 3) +#define IRQ_SYSMMU_MFCR_0 EXYNOS_COMBINERIRQ(6, 2) +#define IRQ_SYSMMU_ARM_1 EXYNOS_COMBINERIRQ(6, 1) + +#define IRQ_SYSMMU_ARM_0 EXYNOS_COMBINERIRQ(5, 0) +#define IRQ_SYSMMU_3DNR_1 EXYNOS_COMBINERIRQ(5, 7) +#define IRQ_SYSMMU_3DNR_0 EXYNOS_COMBINERIRQ(5, 6) +#define IRQ_SYSMMU_MCUISP_1 EXYNOS_COMBINERIRQ(5, 5) +#define IRQ_SYSMMU_MCUISP_0 EXYNOS_COMBINERIRQ(5, 4) +#define IRQ_SYSMMU_SCALERCISP_1 EXYNOS_COMBINERIRQ(5, 3) +#define IRQ_SYSMMU_SCALERCISP_0 EXYNOS_COMBINERIRQ(5, 2) +#define IRQ_SYSMMU_FDISP_1 EXYNOS_COMBINERIRQ(5, 1) +#define IRQ_SYSMMU_FDISP_0 EXYNOS_COMBINERIRQ(5, 0) + +#define IRQ_MCUIOP_CTIIRQ EXYNOS_COMBINERIRQ(4, 7) +#define IRQ_MCUIOP_PMUIRQ EXYNOS_COMBINERIRQ(4, 6) +#define IRQ_MCUISP_CTIIRQ EXYNOS_COMBINERIRQ(4, 5) +#define IRQ_MCUISP_PMUIRQ EXYNOS_COMBINERIRQ(4, 4) +#define IRQ_SYSMMU_JPEGX_1 EXYNOS_COMBINERIRQ(4, 3) +#define IRQ_SYSMMU_JPEGX_0 EXYNOS_COMBINERIRQ(4, 2) +#define IRQ_SYSMMU_ROTATOR_1 EXYNOS_COMBINERIRQ(4, 1) +#define IRQ_SYSMMU_ROTATOR_0 EXYNOS_COMBINERIRQ(4, 0) + +#define IRQ_SYSMMU_SCALERPISP_1 EXYNOS_COMBINERIRQ(3, 7) +#define IRQ_SYSMMU_SCALERPISP_0 EXYNOS_COMBINERIRQ(3, 6) +#define IRQ_SYSMMU_FIMC_LITE0_1 EXYNOS_COMBINERIRQ(3, 5) +#define IRQ_SYSMMU_FIMC_LITE0_0 EXYNOS_COMBINERIRQ(3, 4) +#define IRQ_SYSMMU_DISP1_M0_1 EXYNOS_COMBINERIRQ(3, 3) +#define IRQ_SYSMMU_DISP1_M0_0 EXYNOS_COMBINERIRQ(3, 2) +#define IRQ_SYSMMU_FIMC_LITE2_1 EXYNOS_COMBINERIRQ(3, 1) +#define IRQ_SYSMMU_FIMC_LITE2_0 EXYNOS_COMBINERIRQ(3, 0) + +#define IRQ_SYSMMU_GSCL3_1 EXYNOS_COMBINERIRQ(2, 7) +#define IRQ_SYSMMU_GSCL3_0 EXYNOS_COMBINERIRQ(2, 6) +#define IRQ_SYSMMU_GSCL2_1 EXYNOS_COMBINERIRQ(2, 5) +#define IRQ_SYSMMU_GSCL2_0 EXYNOS_COMBINERIRQ(2, 4) +#define IRQ_SYSMMU_GSCL1_1 EXYNOS_COMBINERIRQ(2, 3) +#define IRQ_SYSMMU_GSCL1_0 EXYNOS_COMBINERIRQ(2, 2) +#define IRQ_SYSMMU_GSCL0_1 EXYNOS_COMBINERIRQ(2, 1) +#define IRQ_SYSMMU_GSCL0_0 EXYNOS_COMBINERIRQ(2, 0) + +#define IRQ_CPU_NCNTVIRQ_0 EXYNOS_COMBINERIRQ(1, 7) +#define IRQ_CPU_NCNTPSIRQ_0 EXYNOS_COMBINERIRQ(1, 6) +#define IRQ_CPU_NCNTPSNIRQ_0 EXYNOS_COMBINERIRQ(1, 5) +#define IRQ_CPU_NCNTHPIRQ_0 EXYNOS_COMBINERIRQ(1, 4) +#define IRQ_CPU_NCTIIRQ_0 EXYNOS_COMBINERIRQ(1, 3) +#define IRQ_CPU_NPMUIRQ_0 EXYNOS_COMBINERIRQ(1, 2) +#define IRQ_CPU_PARITYFAILSCU_0 EXYNOS_COMBINERIRQ(1, 1) +#define IRQ_CPU_PARITYFAIL0 EXYNOS_COMBINERIRQ(1, 0) + +#define IRQ_TZASC_XR1BXW EXYNOS_COMBINERIRQ(0, 7) +#define IRQ_TZASC_XR1BXR EXYNOS_COMBINERIRQ(0, 6) +#define IRQ_TZASC_XLBXW EXYNOS_COMBINERIRQ(0, 5) +#define IRQ_TZASC_XLBXR EXYNOS_COMBINERIRQ(0, 4) +#define IRQ_TZASC_DRBXW EXYNOS_COMBINERIRQ(0, 3) +#define IRQ_TZASC_DRBXR EXYNOS_COMBINERIRQ(0, 2) +#define IRQ_TZASC_CBXW EXYNOS_COMBINERIRQ(0, 1) +#define IRQ_TZASC_CBXR EXYNOS_COMBINERIRQ(0, 0) + + +#define OFFANDSIZE(p,n) EXYNOS5##p##_##n##_OFFSET, 0x10000 + +static const struct exyo_locators exynos5_locators[] = { + { "mct", OFFANDSIZE(,MCT), NOPORT, IRQ_MCT_LTIMER, 0 }, +}; + +struct exyo_locinfo exynos5_locinfo = { + .locators = exynos5_locators, + .nlocators = __arraycount(exynos5_locators) +}; Index: sys/arch/arm/samsung/exynos5_reg.h =================================================================== RCS file: sys/arch/arm/samsung/exynos5_reg.h diff -N sys/arch/arm/samsung/exynos5_reg.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arch/arm/samsung/exynos5_reg.h 11 Apr 2014 15:32:42 -0000 @@ -0,0 +1,357 @@ +/* $NetBSD */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Nick Hudson. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this 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. + */ + +#ifndef _ARM_SAMSUNG_EXYNOS5_REG_H_ +#define _ARM_SAMSUNG_EXYNOS5_REG_H_ + +/* + * Physical memory layout of Exynos5 SoCs as per documentation + * + * Base Address Limit Address Size Description + * 0x00000000 0x0000FFFF 64 KB iROM/iRAM/SROM + * 0x02000000 0x0200FFFF 64 KB iROM (mirror of 0x0 to 0xFFFF) + * 0x02020000 0x02077FFF 352 KB iRAM + * 0x03000000 0x03027FFF 160 KB Data memory of SRP + * 0x03028000 0x0303FFFF 96 KB I-cache of SRP + * 0x03040000 0x03048FFF 36 KB Configuration memory of SRP (write-only) + * 0x03800000 0x0386FFFF SFR region of AudioSS + * 0x04000000 0x04020000 128 KB SROMC's Bank 0 + * 0x05000000 0x05020000 128 KB SROMC's Bank 1 + * 0x06000000 0x06020000 128 KB SROMC's Bank 2 + * 0x07000000 0x07020000 128 KB SROMC's Bank 3 + * 0x10000000 0x1FFFFFFF SFR region + * 0x20000000 0xFFFFFFFF DRAM +*/ + +#define EXYNOS5_CORE_PBASE 0x10000000 /* SFR */ + +#define EXYNOS5_CORE_SIZE 0x10000000 +#define EXYNOS5_SDRAM_PBASE 0x20000000 + +#define EXYNOS5_CMU_COREPART 0x00010000 +#define EXYNOS5_CMU_TOPPART_OFFSET 0x00020000 +#define EXYNOS5_CMU_MEMPART_OFFSET 0x00030000 +#define EXYNOS5_ALIVE_OFFSET 0x00040000 +#define EXYNOS5_SYSREG_OFFSET 0x00050000 +#define EXYNOS5_TMU_OFFSET 0x00060000 +#define EXYNOS5_MONOTONIC_CNT_OFFSET 0x000C0000 + +#define EXYNOS5_HDMI_CEC_OFFSET 0x001B0000 +#define EXYNOS5_MCT_OFFSET 0x001C0000 +#define EXYNOS5_WDT_OFFSET 0x001D0000 +#define EXYNOS5_RTC_OFFSET 0x001E0000 + +#define EXYNOS5_INT_COMB_CPU_OFFSET 0x00440000 +#define EXYNOS5_INT_COMB_IOP_OFFSET 0x00450000 +#define EXYNOS5_GIC_CPU_OFFSET 0x00480000 +#define EXYNOS5_GIC_IOP_CONTROLLER_OFFSET 0x004A0000 +#define EXYNOS5_GIC_IOP_DISTRIBUTOR_OFFSET 0x004B0000 +#define EXYNOS5_MPCORE PRIVATE REGION_OFFSET 0x00500000 +#define EXYNOS5_NS MDMA0 0x00800000 +#define EXYNOS5_SSS_OFFSET 0x00830000 +#define EXYNOS5_SSS_KEY_OFFSET 0x00840000 +#define EXYNOS5_2D_OFFSET 0x00850000 +#define EXYNOS5_CSSYS_OFFSET 0x00880000 +#if 0 +#define EXYNOS5_A15 (EAGLE) 0x00890000 +#define EXYNOS5_A5 (IOP) 0x008A0000 +#define EXYNOS5_A5 (ISP) 0x008B0000 +#endif +#define EXYNOS5_SYSMMU_MDMA_OFFSET 0x00A40000 +#define EXYNOS5_SYSMMU_SSS_OFFSET 0x00A50000 +#define EXYNOS5_SYSMMU_2D_OFFSET 0x00A60000 +#define EXYNOS5_DREXII_PHY0_OFFSET 0x00C00000 +#define EXYNOS5_DREXII_PHY1_OFFSET 0x00C10000 +#define EXYNOS5_AS_A_3D_OFFSET 0x00CC0000 +#define EXYNOS5_AS_A_C2C_OFFSET 0x00CD0000 +#define EXYNOS5_AS_A_LEFT_BUS_OFFSET 0x00CE0000 +#define EXYNOS5_AS_A_RIGHT0_BUS_OFFSET 0x00CF0000 +#define EXYNOS5_AS_A_DISP1_BUS_OFFSET 0x00D00000 +#define EXYNOS5_C2C_GPIO_OFFSET 0x00D10000 +#define EXYNOS5_DREXII_OFFSET 0x00DD0000 +#define EXYNOS5_AS_A_EFCON_OFFSET 0x00DE0000 +#define EXYNOS5_AP_C2C_OFFSET 0x00E00000 +#define EXYNOS5_CP_C2C_OFFSET 0x00E40000 +#define EXYNOS5_AS_A_ACP_BLK_OFFSET 0x00E80000 +#define EXYNOS5_AS_A_CPU_P_BLK_OFFSET 0x00E90000 +#define EXYNOS5_AS_A_LBX_BUS_OFFSET 0x00F00000 +#define EXYNOS5_AS_A_R1BX_BUS_OFFSET 0x00F10000 +#define EXYNOS5_AS_A_R0BX_BUS_OFFSET 0x00F20000 +#define EXYNOS5_AS_A_CPU_OFFSET 0x00F30000 +#define EXYNOS5_MFC_OFFSET 0x01000000 +#define EXYNOS5_SYSMMU_MFC0_R 0x01200000 +#define EXYNOS5_SYSMMU_MFC1_L 0x01210000 +#define EXYNOS5_GPIO_LEFT_OFFSET 0x01400000 +#define EXYNOS5_AS_A_MFC_OFFSET 0x01680000 +#define EXYNOS5_AS_A_GENX_OFFSET 0x016A0000 +#define EXYNOS5_3D ENGINE_OFFSET 0x01800000 +#define EXYNOS5_ROTATOR_OFFSET 0x01C00000 +#define EXYNOS5_NS_MDMA1 0x01C10000 +#define EXYNOS5_SYSMMU_ROTATOR_OFFSET 0x01D40000 +#define EXYNOS5_SYSMMU_MDMA1 0x01D50000 +#define EXYNOS5_AS_A_FILE_OFFSET 0x01DA0000 +#define EXYNOS5_AS_A_GPS_OFFSET 0x01DB0000 +#define EXYNOS5_AS_A_JPEG_OFFSET 0x01DC0000 +#define EXYNOS5_JPEG_OFFSET 0x01E00000 +#define EXYNOS5_SYSMMU_JPEG_OFFSET 0x01F20000 +#if 0 +#define EXYNOS5_USB3_DEVICE_LINK_OFFSET 0x02000000 +#define EXYNOS5_USB3_DEVICE_LINK_OFFSET 0x02010000 +#define EXYNOS5_USB3_DEVICE_LINK_OFFSET 0x02020000 +#define EXYNOS5_USB3_DEVICE_LINK_OFFSET 0x02030000 +#define EXYNOS5_USB3_DEVICE_LINK_OFFSET 0x02040000 +#define EXYNOS5_USB3_DEVICE_LINK_OFFSET 0x02050000 +#define EXYNOS5_USB3_DEVICE_LINK_OFFSET 0x02060000 +#define EXYNOS5_USB3_DEVICE_LINK_OFFSET 0x02070000 +#define EXYNOS5_USB3_DEVICE_LINK_OFFSET 0x02080000 +#define EXYNOS5_USB3_DEVICE_LINK_OFFSET 0x02090000 +#define EXYNOS5_USB3_DEVICE_LINK_OFFSET 0x020A0000 +#define EXYNOS5_USB3_DEVICE_LINK_OFFSET 0x020B0000 +#define EXYNOS5_USB3_DEVICE_LINK_OFFSET 0x020C0000 +#define EXYNOS5_USB3_DEVICE_LINK_OFFSET 0x020D0000 +#define EXYNOS5_USB3_DEVICE_LINK_OFFSET 0x020E0000 +#define EXYNOS5_USB3_DEVICE_LINK_OFFSET 0x020F0000 +#endif +#define EXYNOS5_USB3_DEVICE_CTRL_OFFSET 0x02100000 +#define EXYNOS5_USB2_HOST_EHCI_OFFSET 0x02110000 +#define EXYNOS5_USB2_HOST_OHCI_OFFSET 0x02120000 +#define EXYNOS5_USB2_HOST_CTRL_OFFSET 0x02130000 +#define EXYNOS5_USB2_DEVICE_LINK_OFFSET 0x02140000 +#define EXYNOS5_MIPI_HSI_OFFSET 0x02160000 +#define EXYNOS5_SATA PHY CONTROL_OFFSET 0x02170000 +#define EXYNOS5_MCUCTL_IOP_OFFSET 0x02180000 +#define EXYNOS5_WDT_IOP_OFFSET 0x02190000 +#define EXYNOS5_PDMA0 0x021A0000 +#define EXYNOS5_PDMA1 0x021B0000 +#define EXYNOS5_RTIC_OFFSET 0x021C0000 +#define EXYNOS5_SATA_I2C_PHY_CONTROL_OFFSET 0x021D0000 +#define EXYNOS5_MSH0 0x02200000 +#define EXYNOS5_MSH1 0x02210000 +#define EXYNOS5_MSH2 0x02220000 +#define EXYNOS5_MSH3 0x02230000 +#define EXYNOS5_SROMC_OFFSET 0x02250000 +#define EXYNOS5_SATA_OFFSET 0x022F0000 +#if 0 +#define EXYNOS5_AXI_FILE_D64 (GPV) 0x02300000 +#define EXYNOS5_AXI_FILE_D64 (GPV) 0x02310000 +#endif +#define EXYNOS5_AXI_USB_SATA_D64 0x02320000 +#if 0 +#define EXYNOS5_AXI_USB_SATA_D64 0x02330000 +#endif +#define EXYNOS5_SYSMMU_IOPROCESSOR_OFFSET 0x02360000 +#define EXYNOS5_SYSMMU_RTIC_OFFSET 0x02370000 +#define EXYNOS5_AS_A_IOP_FD64X_OFFSET 0x02380000 +#define EXYNOS5_AS_A_AUDIO_OFFSET 0x02390000 +#if 0 +#define EXYNOS5_AXI_GPS (GPV) 0x02600000 +#define EXYNOS5_AXI_GPS (GPV) 0x02610000 +#endif +#define EXYNOS5_AS_A_GPSCPU_OFFSET 0x02620000 +#define EXYNOS5_SYSMMU_GPS_OFFSET 0x02630000 +#define EXYNOS5_UART0_OFFSET 0x02C00000 +#define EXYNOS5_UART1_OFFSET 0x02C10000 +#define EXYNOS5_UART2_OFFSET 0x02C20000 +#define EXYNOS5_UART3_OFFSET 0x02C30000 +#define EXYNOS5_USI0_OFFSET 0x02C50000 +#define EXYNOS5_I2C0_OFFSET 0x02C60000 +#define EXYNOS5_I2C1_OFFSET 0x02C70000 +#define EXYNOS5_I2C2_OFFSET 0x02C80000 +#define EXYNOS5_I2C3_OFFSET 0x02C90000 +#define EXYNOS5_I2C4_OFFSET 0x02CA0000 +#define EXYNOS5_I2C5_OFFSET 0x02CB0000 +#define EXYNOS5_I2C6_OFFSET 0x02CC0000 +#define EXYNOS5_I2C7_OFFSET 0x02CD0000 +#define EXYNOS5_I2C_HDMI_OFFSET 0x02CE0000 +#define EXYNOS5_USI_OFFSET 0x02D00000 +#define EXYNOS5_TSADC_OFFSET 0x02D10000 +#define EXYNOS5_SPI0_OFFSET 0x02D20000 +#define EXYNOS5_SPI1_OFFSET 0x12D30000 +#define EXYNOS5_SPI2_OFFSET 0x12D40000 +#define EXYNOS5_USI2_OFFSET 0x12D50000 +#define EXYNOS5_I2S1_OFFSET 0x12D60000 +#define EXYNOS5_I2S2_OFFSET 0x12D70000 +#define EXYNOS5_PCM1_OFFSET 0x12D80000 +#define EXYNOS5_PCM2_OFFSET 0x12D90000 +#define EXYNOS5_AC97_OFFSET 0x12DA0000 +#define EXYNOS5_SPDIF_OFFSET 0x12DB0000 +#define EXYNOS5_PWM_OFFSET 0x12DD0000 +#define EXYNOS5_USI3_OFFSET 0x12DE0000 +#define EXYNOS5_FIMC_ISP_OFFSET 0x13000000 +#define EXYNOS5_FIMC_DRC_TOP_OFFSET 0x13010000 +#define EXYNOS5_FIMC_SCALERC_OFFSET 0x13020000 +#define EXYNOS5_FIMC_SCALERP_OFFSET 0x13030000 +#define EXYNOS5_FIMC_FD_TOP_OFFSET 0x13040000 +#define EXYNOS5_FIMC_ODC_OFFSET 0x03050000 +#define EXYNOS5_FIMC_DIS_OFFSET 0x03060000 +#define EXYNOS5_FIMC_3DNR_OFFSET 0x03070000 +#define EXYNOS5_ASYNC_AXI_M_OFFSET 0x030F0000 +#define EXYNOS5_MPWM_ISP_OFFSET 0x03110000 +#define EXYNOS5_I2C2_ISP_OFFSET 0x03120000 +#define EXYNOS5_I2C0_ISP_OFFSET 0x03130000 +#define EXYNOS5_I2C1_ISP_OFFSET 0x03140000 +#define EXYNOS5_MTCADC_ISP_OFFSET 0x03150000 +#define EXYNOS5_PWM_ISP_OFFSET 0x03160000 +#define EXYNOS5_WDT_ISP_OFFSET 0x03170000 +#define EXYNOS5_MCUCTL_ISP_OFFSET 0x03180000 +#define EXYNOS5_UART_ISP_OFFSET 0x03190000 +#define EXYNOS5_SPI0_ISP_OFFSET 0x031A0000 +#define EXYNOS5_SPI1_ISP_OFFSET 0x031B0000 +#define EXYNOS5_GIC_C_ISP_OFFSET 0x031E0000 +#define EXYNOS5_GIC_D_ISP_OFFSET 0x031F0000 +#define EXYNOS5_SYSMMU_FIMC_ISP_OFFSET 0x03260000 +#define EXYNOS5_SYSMMU_FIMC_DRC_OFFSET 0x03270000 +#define EXYNOS5_SYSMMU_FIMC_SCALERC_OFFSET 0x03280000 +#define EXYNOS5_SYSMMU_FIMC_SCALERP_OFFSET 0x03290000 +#define EXYNOS5_SYSMMU_FIMC_FD_OFFSET 0x032A0000 +#define EXYNOS5_SYSMMU_ISPCPU_OFFSET 0x032B0000 +#define EXYNOS5_SYSMMU_FIMC_ODC_OFFSET 0x032C0000 +#define EXYNOS5_SYSMMU_FIMC_DIS0 0x032D0000 +#define EXYNOS5_SYSMMU_FIMC_DIS1 0x032E0000 +#define EXYNOS5_SYSMMU_FIMC_3DNR_OFFSET 0x032F0000 +#define EXYNOS5_GPIO_RIGHT_OFFSET 0x03400000 +#define EXYNOS5_AS_A_MFC0_OFFSET 0x03620000 +#define EXYNOS5_AS_A_ISP0_OFFSET 0x03640000 +#define EXYNOS5_AS_A_ISP1_OFFSET 0x03650000 +#define EXYNOS5_AS_A_RIGHT1_OFFSET 0x03670000 +#define EXYNOS5_FIMC_LITE0_OFFSET 0x03C00000 +#define EXYNOS5_FIMC_LITE1_OFFSET 0x03C10000 +#define EXYNOS5_MIPI_CSI0_OFFSET 0x03C20000 +#define EXYNOS5_MIPI_CSI1_OFFSET 0x03C30000 +#define EXYNOS5_SYSMMU_FIMC_LITE0_OFFSET 0x03C40000 +#define EXYNOS5_SYSMMU_FIMC_LITE1_OFFSET 0x03C50000 +#define EXYNOS5_FIMC_LITE2_OFFSET 0x03C90000 +#define EXYNOS5_SYSMMU_FIMC_LITE2_OFFSET 0x03CA0000 +#define EXYNOS5_GSCALER0_OFFSET 0x03E00000 +#define EXYNOS5_GSCALER1_OFFSET 0x03E10000 +#define EXYNOS5_GSCALER2_OFFSET 0x03E20000 +#define EXYNOS5_GSCALER3_OFFSET 0x03E30000 +#define EXYNOS5_AS_A_GS0_OFFSET 0x03E40000 +#define EXYNOS5_AS_A_GS1_OFFSET 0x03E50000 +#define EXYNOS5_AS_A_GS2_OFFSET 0x03E60000 +#define EXYNOS5_AS_A_GS3_OFFSET 0x03E70000 +#define EXYNOS5_SYSMMU_GSCALER0_OFFSET 0x03E80000 +#define EXYNOS5_SYSMMU_GSCALER1_OFFSET 0x03E90000 +#define EXYNOS5_SYSMMU_GSCALER2_OFFSET 0x03EA0000 +#define EXYNOS5_SYSMMU_GSCALER3_OFFSET 0x03EB0000 +#define EXYNOS5_AS_A_GSCALER_OFFSET 0x04220000 +#define EXYNOS5_DISP1_MIX_OFFSET 0x04400000 +#define EXYNOS5_DISP1_ENH_OFFSET 0x04410000 +#define EXYNOS5_DISP1_CTRL_OFFSET 0x04420000 +#define EXYNOS5_MIE_OFFSET 0x04430000 +#define EXYNOS5_TV_MIXER_OFFSET 0x04450000 +#define EXYNOS5_MIPI_DSI1_OFFSET 0x04500000 +#define EXYNOS5_DP1_OFFSET 0x04510000 +#define EXYNOS5_HDMI_0_OFFSET 0x04530000 +#define EXYNOS5_HDMI_1_OFFSET 0x04540000 +#define EXYNOS5_HDMI_2_OFFSET 0x04550000 +#define EXYNOS5_HDMI_3_OFFSET 0x04560000 +#define EXYNOS5_HDMI_4_OFFSET 0x04570000 +#define EXYNOS5_HDMI_5_OFFSET 0x04580000 +#define EXYNOS5_HDMI_6_OFFSET 0x04590000 +#define EXYNOS5_DP1_1_OFFSET 0x045B0000 +#define EXYNOS5_SYSMMU_DISP1_OFFSET 0x04640000 +#define EXYNOS5_SYSMMU_TV_OFFSET 0x04650000 +#define EXYNOS5_AS_A_TV_OFFSET 0x046D0000 +#if 0 +#define EXYNOS5_AES0&EF0 (NEW) 0x08000000 +#define EXYNOS5_AES0&EF0 (NEW) 0x08010000 +#define EXYNOS5_AES0&EF0 (NEW) 0x08020000 +#define EXYNOS5_AES0&EF0 (NEW) 0x08030000 +#define EXYNOS5_AES0&EF0 (NEW) 0x08040000 +#define EXYNOS5_AES0&EF0 (NEW) 0x08050000 +#define EXYNOS5_AES0&EF0 (NEW) 0x08060000 +#define EXYNOS5_AES0&EF0 (NEW) 0x08070000 +#define EXYNOS5_AES0&EF0 (NER) 0x08080000 +#define EXYNOS5_AES0&EF0 (NER) 0x08090000 +#define EXYNOS5_AES0&EF0 (NER) 0x080A0000 +#define EXYNOS5_AES0&EF0 (NER) 0x080B0000 +#define EXYNOS5_AES0&EF0 (NER) 0x080C0000 +#define EXYNOS5_AES0&EF0 (NER) 0x080D0000 +#define EXYNOS5_AES0&EF0 (NER) 0x080E0000 +#define EXYNOS5_AES0&EF0 (NER) 0x080F0000 +#define EXYNOS5_AES0&EF0 (EW) 0x08100000 +#define EXYNOS5_AES0&EF0 (EW) 0x08110000 +#define EXYNOS5_AES0&EF0 (EW) 0x08120000 +#define EXYNOS5_AES0&EF0 (EW) 0x08130000 +#define EXYNOS5_AES0&EF0 (EW) 0x08140000 +#define EXYNOS5_AES0&EF0 (EW) 0x08150000 +#define EXYNOS5_AES0&EF0 (EW) 0x08160000 +#define EXYNOS5_AES0&EF0 (EW) 0x08170000 +#define EXYNOS5_AES0&EF0 (ER) 0x08180000 +#define EXYNOS5_AES0&EF0 (ER) 0x08190000 +#define EXYNOS5_AES0&EF0 (ER) 0x081A0000 +#define EXYNOS5_AES0&EF0 (ER) 0x081B0000 +#define EXYNOS5_AES0&EF0 (ER) 0x081C0000 +#define EXYNOS5_AES0&EF0 (ER) 0x081D0000 +#define EXYNOS5_AES0&EF0 (ER) 0x081E0000 +#define EXYNOS5_AES0&EF0 (ER) 0x081F0000 +#define EXYNOS5_EFCON0_SFR_OFFSET 0x08200000 +#define EXYNOS5_AES0 SFR_OFFSET 0x08300000 +#define EXYNOS5_AES1&EF1 (NEW) 0x08400000 +#define EXYNOS5_AES1&EF1 (NEW) 0x08410000 +#define EXYNOS5_AES1&EF1 (NEW) 0x08420000 +#define EXYNOS5_AES1&EF1 (NEW) 0x08430000 +#define EXYNOS5_AES1&EF1 (NEW) 0x08440000 +#define EXYNOS5_AES1&EF1 (NEW) 0x08450000 +#define EXYNOS5_AES1&EF1 (NEW) 0x08460000 +#define EXYNOS5_AES1&EF1 (NEW) 0x08470000 +#define EXYNOS5_AES1&EF1 (NER) 0x08480000 +#define EXYNOS5_AES1&EF1 (NER) 0x08490000 +#define EXYNOS5_AES1&EF1 (NER) 0x084A0000 +#define EXYNOS5_AES1&EF1 (NER) 0x084B0000 +#define EXYNOS5_AES1&EF1 (NER) 0x084C0000 +#define EXYNOS5_AES1&EF1 (NER) 0x084D0000 +#define EXYNOS5_AES1&EF1 (NER) 0x084E0000 +#define EXYNOS5_AES1&EF1 (NER) 0x084F0000 +#define EXYNOS5_AES1&EF1 (EW) 0x08500000 +#define EXYNOS5_AES1&EF1 (EW) 0x08510000 +#define EXYNOS5_AES1&EF1 (EW) 0x08520000 +#define EXYNOS5_AES1&EF1 (EW) 0x08530000 +#define EXYNOS5_AES1&EF1 (EW) 0x08540000 +#define EXYNOS5_AES1&EF1 (EW) 0x08550000 +#define EXYNOS5_AES1&EF1 (EW) 0x08560000 +#define EXYNOS5_AES1&EF1 (EW) 0x08570000 +#define EXYNOS5_AES1&EF1 (ER) 0x08580000 +#define EXYNOS5_AES1&EF1 (ER) 0x08590000 +#define EXYNOS5_AES1&EF1 (ER) 0x085A0000 +#define EXYNOS5_AES1&EF1 (ER) 0x085B0000 +#define EXYNOS5_AES1&EF1 (ER) 0x085C0000 +#define EXYNOS5_AES1&EF1 (ER) 0x085D0000 +#define EXYNOS5_AES1&EF1 (ER) 0x085E0000 +#define EXYNOS5_AES1&EF1 (ER) 0x085F0000 +#endif +#define EXYNOS5_EFCON1_SFR_OFFSET 0x08600000 +#define EXYNOS5_NS_NDMA_OFFSET 0x08680000 +#define EXYNOS5_S_NDMA_OFFSET 0x08690000 +#define EXYNOS5_AES1 SFR_OFFSET 0x08700000 + +#endif /* _ARM_SAMSUNG_EXYNOS5_REG_H_ */ Index: sys/arch/arm/samsung/exynos_intr.h =================================================================== RCS file: sys/arch/arm/samsung/exynos_intr.h diff -N sys/arch/arm/samsung/exynos_intr.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arch/arm/samsung/exynos_intr.h 11 Apr 2014 15:32:42 -0000 @@ -0,0 +1,63 @@ +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Nick Hudson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this 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. + */ + +#ifndef _ARM_SAMSUNG_EXYNOS_INTR_H_ +#define _ARM_SAMSUNG_EXYNOS_INTR_H_ + +#define PIC_MAXSOURCES 160 +#define PIC_MAXMAXSOURCES 192 /* XXX */ + +/* + * The Exynos uses a generic interrupt controller + */ +#include + +#ifdef _KERNEL_OPT +#include "opt_exynos.h" +#endif + +/* + * The GIC supports + * - 16 Software Generated Interrupts (SGIs) + * - 16 Private Peripheral Interrupts (PPIs) + * - 127 Shared Peripheral Interrupts (SPIs) + */ + +#define EXYNOS_NSPI 128 +#define EXYNOS_COMBINERBASE EXYNOS_SPIBASE + EXYNOS_NSPI + +#define EXYNOS_BITSPERGROUP 8 + +#define EXYNOS_COMBINERIRQ(g, b) \ + (EXYNOS_COMBINERBASE + ((g) * EXYNOS_BITSPERGROUP + (b))) + +#define IRQ_MCT_LTIMER IRQ_PPI(12) + +#endif /* _ARM_SAMSUNG_EXYNOS_INTR_H_ */ + Index: sys/arch/arm/samsung/exynos_io.c =================================================================== RCS file: sys/arch/arm/samsung/exynos_io.c diff -N sys/arch/arm/samsung/exynos_io.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arch/arm/samsung/exynos_io.c 11 Apr 2014 15:32:42 -0000 @@ -0,0 +1,192 @@ +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Matt Thomas of 3am Software Foundry. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Reinoud Zandijk + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this 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 "locators.h" +#include "opt_exynos.h" + +#include +__KERNEL_RCSID(1, "$NetBSD$"); + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#if 0 +#include +#endif +#include + + +static int exyo_match(device_t, cfdata_t, void *); +static void exyo_attach(device_t, device_t, void *); + +static struct exyo_softc { + device_t sc_dev; + bus_space_tag_t sc_bst; + bus_space_tag_t sc_a4x_bst; + bus_space_handle_t sc_bsh; + bus_space_handle_t sc_ccm_bsh; + bus_dma_tag_t sc_dmat; + bus_dma_tag_t sc_coherent_dmat; +} exyo_sc; + +CFATTACH_DECL_NEW(exyo_io, 0, exyo_match, exyo_attach, NULL, NULL); + +/* there can only be one */ +static int +exyo_match(device_t parent, cfdata_t cf, void *aux) +{ + if (exyo_sc.sc_dev != NULL) + return 0; + + return 1; +} + +static int +exyo_print(void *aux, const char *pnp) +{ + const struct exyo_attach_args * const aio = aux; + + if (aio->aio_loc.loc_port != EXYOCF_PORT_DEFAULT) + aprint_normal(" port %d", aio->aio_loc.loc_port); + + return QUIET; +} + +void +exyo_device_register(device_t self, void *aux) +{ + prop_dictionary_t dict = device_properties(self); + + if (device_is_a(self, "mct")) { + /* + * This clock always runs at (arm_clk div 2) and only goes + * to timers that are part of the A9 MP core subsystem. + */ + prop_dictionary_set_uint32(dict, "frequency", + curcpu()->ci_data.cpu_cc_freq / 2); + return; + } +} + +static int +exyo_find(device_t parent, cfdata_t cf, const int *ldesc, void *aux) +{ + const struct exyo_attach_args * const aio = aux; + const struct exyo_locators * const loc = &aio->aio_loc; + const int port = cf->cf_loc[EXYOCF_PORT]; + + if (strcmp(cf->cf_name, loc->loc_name) + || (port != EXYOCF_PORT_DEFAULT && port != loc->loc_port)) + return 0; + + return config_match(parent, cf, aux); +} + +static void +exyo_attach(device_t parent, device_t self, void *aux) +{ + struct exyo_softc * const sc = &exyo_sc; + prop_dictionary_t dict = device_properties(self); + + sc->sc_dev = self; + + sc->sc_bst = &exynos_bs_tag; + sc->sc_a4x_bst = &exynos_a4x_bs_tag; + sc->sc_bsh = exynos_core_bsh; +// sc->sc_dmat = &exynos_dma_tag; +// sc->sc_coherent_dmat = &exynos_coherent_dma_tag; + + aprint_naive("\n"); + aprint_normal("\n"); + + const struct exyo_locators *l = NULL; + size_t nl = 0; + +#if defined(EXYNOS4) + if (IS_EXYNOS4) { + l = exynos4_locinfo.locators; + nl = exynos4_locinfo.nlocators; + } +#elif defined(EXYNOS5) + if (IS_EXYNOS5) { + l = exynos5_locinfo.locators; + nl = exynos5_locainfo.nlocators; + } +#else +#error Must define a SoC +#endif + + for (const struct exyo_locators *loc = l; loc < l + nl; loc++) { + char prop_name[31]; + bool skip; + + if (loc->loc_port == EXYOCF_PORT_DEFAULT) { + snprintf(prop_name, sizeof(prop_name), + "no-%s", loc->loc_name); + } else { + snprintf(prop_name, sizeof(prop_name), + "no-%s-%d", loc->loc_name, loc->loc_port); + } + if (prop_dictionary_get_bool(dict, prop_name, &skip) && skip) + continue; + + struct exyo_attach_args aio = { + .aio_loc = *loc, + .aio_core_bst = sc->sc_bst, + .aio_core_a4x_bst = sc->sc_a4x_bst, + .aio_core_bsh = sc->sc_bsh, + .aio_ccm_bsh = sc->sc_ccm_bsh, + .aio_dmat = sc->sc_dmat, + .aio_coherent_dmat = sc->sc_coherent_dmat, + }; + cfdata_t cf = config_search_ia(exyo_find, + sc->sc_dev, "exyo", &aio); +#if 0 + if (cf == NULL) { + if (loc->loc_flags & EXYO_REQUIRED) + panic("%s: failed to find %s!", __func__, + loc->loc_name); + continue; + } +#endif + config_attach(sc->sc_dev, cf, &aio, exyo_print); + } +} Index: sys/arch/arm/samsung/exynos_io.h =================================================================== RCS file: sys/arch/arm/samsung/exynos_io.h diff -N sys/arch/arm/samsung/exynos_io.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arch/arm/samsung/exynos_io.h 11 Apr 2014 15:32:42 -0000 @@ -0,0 +1,55 @@ +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Nick Hudson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this 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. + */ + +#ifndef _ARM_SAMSUMG_EXYNOS_IO_H_ +#define _ARM_SAMSUNG_EXYNOS_IO_H_ + +#include "locators.h" + +#include + +struct exyo_locinfo { + const struct exyo_locators *locators; + size_t nlocators; +}; + +#if defined(EXYNOS4) +extern struct exyo_locinfo exynos4_locinfo; +#endif +#if defined(EXYNOS5) +extern struct exyo_locinfo exynos5_locinfo; +#endif + +/* XXXNH needed? */ +#define NOPORT EXYOCF_PORT_DEFAULT +#define NOINTR EXYO_INTR_DEFAULT +#define EANY EXYO_ALL +#define REQ EXYO_REQUIRED + +#endif /* _ARM_SAMSUNG_EXYNOS_IO_H_ */ Index: sys/arch/arm/samsung/exynos_reg.h =================================================================== RCS file: sys/arch/arm/samsung/exynos_reg.h diff -N sys/arch/arm/samsung/exynos_reg.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arch/arm/samsung/exynos_reg.h 11 Apr 2014 15:32:42 -0000 @@ -0,0 +1,111 @@ +/* $NetBSD */ +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Reinoud Zandijk. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this 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. + */ + +#ifndef _ARM_SAMSUNG_EXYNOS_REG_H_ +#define _ARM_SAMSUNG_EXYNOS_REG_H_ + +/* + * + * The exynos can boot from its iROM or from an external Nand memory. Since + * these are normally hardly used they are excluded from the normal register + * space here. + * + * XXX What about the audio subsystem region. Where are the docs? + * + * EXYNOS_CORE_PBASE points to the main SFR region. + * + * Notes: + * + * SFR Special Function Register + * ISP In-System Programming, like a JTAG + * ACP Accelerator Coherency Port + * SSS Security Sub System + * GIC Generic Interurrupt Controller + * PMU Power Management Unit + * DMC 2D Graphics engine + * LEFTBUS Data bus / Peripheral bus + * RIGHTBUS ,, + * G3D 3D Graphics engine + * MFC Multi-Format Codec + * LCD0 LCD display + * MCT Multi Core Timer + * CMU Clock Management Unit + * TMU Thermal Management Unit + * PPMU Pin Parametric Measurement Unit (?) + * MMU Memory Management Unit + * MCTimer ? + * WDT Watch Dog Timer + * RTC Real Time Clock + * KEYIF Keypad interface + * SECKEY ? + * TZPC TrustZone Protection Controller + * UART Universal asynchronous receiver/transmitter + * I2C Inter IC Connect + * SPI Serial Peripheral Interface Bus + * I2S Inter-IC Sound, Integrated Interchip Sound, or IIS + * PCM Pulse-code modulation, audio stream at set fixed rate + * SPDIF Sony/Philips Digital Interface Format + * Slimbus Serial Low-power Inter-chip Media Bus + * SMMU System mmu. No idea as how its programmed (or not) + * PERI-L UART, I2C, SPI, I2S, PCM, SPDIF, PWM, I2CHDMI, Slimbus + * PERI-R CHIPID, SYSREG, PMU/CMU/TMU Bus I/F, MCTimer, WDT, RTC, KEYIF, + * SECKEY, TZPC + */ + +/* + * Common to Exynos4 and Exynos 5 + * */ +#define EXYNOS_CORE_PBASE 0x10000000 /* SFR */ +#define EXYNOS_CORE_SIZE 0x10000000 + + +#define EXYNOS_CHIPID_OFFSET 0x00000000 +#define EXYNOS_PROD_ID_OFFSET (EXYNOS_CHIPID_OFFSET + 0) +#define EXYNOS_PACKAGE_ID_OFFSET (EXYNOS_CHIPID_OFFSET + 4) + +#define EXYNOS_PACKAGE_ID_2_GIG 0x06030058 + +/* standard block size for offsets defined below */ +#define EXYNOS_BLOCK_SIZE 0x00010000 + + +/* standard frequency settings */ +#define EXYNOS_ACLK_REF_FREQ (200*1000*1000) /* 200 Mhz */ +#define EXYNOS_UART_FREQ (109*1000*1000) /* should be EXYNOS_ACLK_REF_FREQ! */ + +#if defined(EXYNOS5) +#include +#endif +#if defined(EXYNOS4) +#include +#endif + +#endif /* _ARM_SAMSUNG_EXYNOS_REG_H_ */ + Index: sys/arch/arm/samsung/exynos_smc.S =================================================================== RCS file: sys/arch/arm/samsung/exynos_smc.S diff -N sys/arch/arm/samsung/exynos_smc.S --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arch/arm/samsung/exynos_smc.S 11 Apr 2014 15:32:42 -0000 @@ -0,0 +1,49 @@ +/* $NetBSD: exynos_soc.c,v 1.12 2014/03/13 23:45:02 matt Exp $ */ +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Reinoud Zandijk. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this 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 +#include + +RCSID("$NetBSD: exynos_soc.c,v 1.12 2014/03/13 23:45:02 matt Exp $") + +/* + * void + * exynos_smc(uint32_t cmd, uint32_t arg1, uint32_t arg2, uint32_t arg3) + */ + + .global _C_LABEL(exynos_smc) +_C_LABEL(exynos_smc): + stmfd sp!, {r4-r11, lr} + dsb /* Data Synchronisation Barrier */ + smc #0 /* Call firmware for all permissions */ + ldmfd sp!, {r4-r11, pc} +END(_C_LABEL(exynos_smc)) + Index: sys/arch/arm/samsung/exynos_soc.c =================================================================== RCS file: sys/arch/arm/samsung/exynos_soc.c diff -N sys/arch/arm/samsung/exynos_soc.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arch/arm/samsung/exynos_soc.c 11 Apr 2014 15:32:42 -0000 @@ -0,0 +1,287 @@ +/* $NetBSD: exynos_soc.c,v 1.12 2014/03/13 23:45:02 matt Exp $ */ +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Reinoud Zandijk. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this 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 "opt_exynos.h" + +#define _ARM32_BUS_DMA_PRIVATE + +#include +__KERNEL_RCSID(1, "$NetBSD: exynos_soc.c,v 1.12 2014/03/13 23:45:02 matt Exp $"); + +#include +#include +#include +#include + +#include + +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include + +/* XXXNH */ +#include + +bus_space_handle_t exynos_core_bsh; + +/* these variables are retrieved in start.S and stored in .data */ +uint32_t exynos_soc_id = 0; +uint32_t exynos_pop_id = 0; + + +/* + * the early serial console + */ +#ifdef EXYNOS_CONSOLE_EARLY + +#include "opt_sscom.h" +#include +#include +#include + +static volatile uint8_t *uart_base; + +#define CON_REG(a) (*((volatile uint32_t *)(uart_base + (a)))) + +static int +exynos_cngetc(dev_t dv) +{ + if ((CON_REG(SSCOM_UTRSTAT) & UTRSTAT_RXREADY) == 0) + return -1; + + return CON_REG(SSCOM_URXH); +} + +static void +exynos_cnputc(dev_t dv, int c) +{ + int timo = 150000; + + while ((CON_REG(SSCOM_UFSTAT) & UFSTAT_TXFULL) && --timo > 0); + + CON_REG(SSCOM_UTXH) = c & 0xff; +} + +static struct consdev exynos_earlycons = { + .cn_putc = exynos_cnputc, + .cn_getc = exynos_cngetc, + .cn_pollc = nullcnpollc, +}; +#endif /* EXYNOS_CONSOLE_EARLY */ + + +static int +exynos_do_idle(void) +{ + exynos_smc(SMC_CMD_SLEEP, 0, 0, 0); + + return 0; +} + + +static int +exynos_set_cpu_boot_addr(int cpu, vaddr_t boot_addr) +{ +#if 0 + void __iomem *boot_reg = S5P_VA_SYSRAM_NS + 0x1c; + + if (!soc_is_exynos5420()) + boot_reg += 4 * cpu; + + writel_relaxed(boot_addr, boot_reg); + return 0; +#endif + return 0; +} + + +static int +exynos_cpu_boot(int cpu) +{ + exynos_smc(SMC_CMD_CPU1BOOT, cpu, 0, 0); + + return 0; +} + + +/* + * The latency values used below are `magic' and probably chosen empiricaly. + * For the 4210 variant the data latency is lower, a 0x110. This is currently + * not enforced. + * + * The prefetch values are also different for the revision 0 of the + * Exynos4412, but why? + */ + +static int +exynos_l2cc_init(void) +{ + const uint32_t tag_latency = 0x110; + const uint32_t data_latency = IS_EXYNOS4410 ? 0x110 : 0x120; + const uint32_t prefetch4412 = /* 0111 0001 0000 0000 0000 0000 0000 0111 */ + PREFETCHCTL_DBLLINEF_EN | + PREFETCHCTL_INSTRPREF_EN | + PREFETCHCTL_DATAPREF_EN | + PREFETCHCTL_PREF_DROP_EN | + PREFETCHCTL_PREFETCH_OFFSET_7; + const uint32_t prefetch4412_r0 = /* 0011 0000 0000 0000 0000 0000 0000 0111 */ + PREFETCHCTL_INSTRPREF_EN | + PREFETCHCTL_DATAPREF_EN | + PREFETCHCTL_PREFETCH_OFFSET_7; + const uint32_t aux_val = /* 0111 1100 0100 0111 0000 0000 0000 0001 */ + AUXCTL_EARLY_BRESP_EN | + AUXCTL_I_PREFETCH | + AUXCTL_D_PREFETCH | + AUXCTL_NS_INT_ACC_CTL | + AUXCTL_NS_INT_LOCK_EN | + AUXCTL_SHARED_ATT_OVR | + AUXCTL_WAY_SIZE_RSVD7 << 16 | /* why rsvd7 ??? */ + AUXCTL_FULL_LINE_WR0; + const uint32_t aux_keepmask = /* 1100 0010 0000 0000 1111 1111 1111 1111 */ + AUXCTL_RSVD31 | + AUXCTL_EARLY_BRESP_EN | + AUXCTL_CACHE_REPL_RR | + + AUXCTL_SH_ATTR_INV_ENA| + AUXCTL_EXCL_CACHE_CFG | + AUXCTL_ST_BUF_DEV_LIM_EN | + AUXCTL_HIPRO_SO_DEV_EN | + AUXCTL_FULL_LINE_WR0 | + 0xffff; + uint32_t prefetch; + + /* check the bitmaps are the same as the linux implementation uses */ + KASSERT(prefetch4412 == 0x71000007); + KASSERT(prefetch4412_r0 == 0x30000007); + KASSERT(aux_val == 0x7C470001); + KASSERT(aux_keepmask == 0xC200FFFF); + + if (IS_EXYNOS4412_R0) + prefetch = prefetch4412_r0; + else + prefetch = prefetch4412; /* newer than >= r1_0 */ + ; + + exynos_smc(SMC_CMD_L2X0SETUP1, tag_latency, data_latency, prefetch); + exynos_smc(SMC_CMD_L2X0SETUP2, + POWERCTL_DYNCLKGATE | POWERCTL_STANDBY, + aux_val, aux_keepmask); + exynos_smc(SMC_CMD_L2X0INVALL, 0, 0, 0); + exynos_smc(SMC_CMD_L2X0CTRL, 1, 0, 0); + + return 0; +} + + +static struct trustzone_firmware_handlers exynos_firmware_handlers = { + .do_idle = exynos_do_idle, + .set_cpu_boot_addr = exynos_set_cpu_boot_addr, + .cpu_boot = exynos_cpu_boot, + .l2cc_init = exynos_l2cc_init +}; + + +void +exynos_bootstrap(vaddr_t iobase, vaddr_t uartbase) +{ +// int error; + + /* set up early console so we can use printf() and friends */ +#ifdef EXYNOS_CONSOLE_EARLY + uart_base = (volatile uint8_t *) uartbase; + cn_tab = &exynos_earlycons; + printf("Exynos early console operational\n\n"); +#endif +#if 0 + /* map in the exynos io registers */ + error = bus_space_map(&exynos_bs_tag, EXYNOS_CORE_PBASE, + 0x04000000 /*EXYNOS_CORE_SIZE*/, 0, &exynos_core_bsh); + if (error) + panic("%s: failed to map in Exynos io registers: %d", + __func__, error); + KASSERT(exynos_core_bsh == iobase); +#endif + /* setup trustzone handlers */ + trustzone_firmware_handlers = &exynos_firmware_handlers; +} + + +void +exynos_device_register(device_t self, void *aux) +{ + if (device_is_a(self, "armperiph") + && device_is_a(device_parent(self), "mainbus")) { + /* + * XXX KLUDGE ALERT XXX + * The iot mainbus supplies is completely wrong since it scales + * addresses by 2. The simpliest remedy is to replace with our + * bus space used for the armcore regisers (which armperiph uses). + */ + struct mainbus_attach_args * const mb = aux; + mb->mb_iot = &exynos_bs_tag; + return; + } + if (device_is_a(self, "armgic") + && device_is_a(device_parent(self), "armperiph")) { + /* + * The Exynos4420 armgic is located at a different location! + */ + struct mpcore_attach_args * const mpcaa = aux; + mpcaa->mpcaa_memh = EXYNOS_CORE_VBASE; + + extern uint32_t exynos_soc_id; + switch (EXYNOS_PRODUCT_ID(exynos_soc_id)) { + case 0xe5410: + mpcaa->mpcaa_off1 = EXYNOS5_GIC_IOP_DISTRIBUTOR_OFFSET; + mpcaa->mpcaa_off2 = EXYNOS5_GIC_IOP_CONTROLLER_OFFSET; + break; + case 0xe4410: + case 0xe4412: + mpcaa->mpcaa_off1 = EXYNOS4_GIC_DISTRIBUTOR_OFFSET; + mpcaa->mpcaa_off2 = EXYNOS4_GIC_CNTR_OFFSET; + break; + } + } + + exyo_device_register(self, aux); +} + Index: sys/arch/arm/samsung/exynos_space.c =================================================================== RCS file: sys/arch/arm/samsung/exynos_space.c diff -N sys/arch/arm/samsung/exynos_space.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arch/arm/samsung/exynos_space.c 11 Apr 2014 15:32:42 -0000 @@ -0,0 +1,426 @@ +/* $NetBSD: exynos_space.c,v 1.3 2014/02/20 21:45:49 matt Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Nick Hudson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this 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 +__KERNEL_RCSID(0, "$NetBSD: exynos_space.c,v 1.3 2014/02/20 21:45:49 matt Exp $"); + +#include +#include + +#include + +#include + +/* Prototypes for all the bus_space structure functions */ +bs_protos(exynos); +bs_protos(exynos_a4x); +bs_protos(a4x); +bs_protos(bs_notimpl); +bs_protos(generic); +bs_protos(generic_armv4); + +#if __ARMEB__ +#define NSWAP(n) n ## _swap +#else +#define NSWAP(n) n +#endif + +struct bus_space exynos_bs_tag = { + /* cookie */ + (void *) 0, + + /* mapping/unmapping */ + exynos_bs_map, + exynos_bs_unmap, + exynos_bs_subregion, + + /* allocation/deallocation */ + exynos_bs_alloc, /* not implemented */ + exynos_bs_free, /* not implemented */ + + /* get kernel virtual address */ + exynos_bs_vaddr, + + /* mmap */ + exynos_bs_mmap, + + /* barrier */ + exynos_bs_barrier, + + /* read (single) */ + generic_bs_r_1, + NSWAP(generic_armv4_bs_r_2), + NSWAP(generic_bs_r_4), + bs_notimpl_bs_r_8, + + /* read multiple */ + generic_bs_rm_1, + NSWAP(generic_armv4_bs_rm_2), + NSWAP(generic_bs_rm_4), + bs_notimpl_bs_rm_8, + + /* read region */ + generic_bs_rr_1, + NSWAP(generic_armv4_bs_rr_2), + NSWAP(generic_bs_rr_4), + bs_notimpl_bs_rr_8, + + /* write (single) */ + generic_bs_w_1, + NSWAP(generic_armv4_bs_w_2), + NSWAP(generic_bs_w_4), + bs_notimpl_bs_w_8, + + /* write multiple */ + generic_bs_wm_1, + NSWAP(generic_armv4_bs_wm_2), + NSWAP(generic_bs_wm_4), + bs_notimpl_bs_wm_8, + + /* write region */ + generic_bs_wr_1, + NSWAP(generic_armv4_bs_wr_2), + NSWAP(generic_bs_wr_4), + bs_notimpl_bs_wr_8, + + /* set multiple */ + bs_notimpl_bs_sm_1, + bs_notimpl_bs_sm_2, + bs_notimpl_bs_sm_4, + bs_notimpl_bs_sm_8, + + /* set region */ + generic_bs_sr_1, + NSWAP(generic_armv4_bs_sr_2), + bs_notimpl_bs_sr_4, + bs_notimpl_bs_sr_8, + + /* copy */ + bs_notimpl_bs_c_1, + generic_armv4_bs_c_2, + bs_notimpl_bs_c_4, + bs_notimpl_bs_c_8, + +#ifdef __BUS_SPACE_HAS_STREAM_METHODS + /* read (single) */ + generic_bs_r_1, + NSWAP(generic_armv4_bs_r_2), + NSWAP(generic_bs_r_4), + bs_notimpl_bs_r_8, + + /* read multiple */ + generic_bs_rm_1, + NSWAP(generic_armv4_bs_rm_2), + NSWAP(generic_bs_rm_4), + bs_notimpl_bs_rm_8, + + /* read region */ + generic_bs_rr_1, + NSWAP(generic_armv4_bs_rr_2), + NSWAP(generic_bs_rr_4), + bs_notimpl_bs_rr_8, + + /* write (single) */ + generic_bs_w_1, + NSWAP(generic_armv4_bs_w_2), + NSWAP(generic_bs_w_4), + bs_notimpl_bs_w_8, + + /* write multiple */ + generic_bs_wm_1, + NSWAP(generic_armv4_bs_wm_2), + NSWAP(generic_bs_wm_4), + bs_notimpl_bs_wm_8, + + /* write region */ + generic_bs_wr_1, + NSWAP(generic_armv4_bs_wr_2), + NSWAP(generic_bs_wr_4), + bs_notimpl_bs_wr_8, +#endif +}; + +struct bus_space exynos_a4x_bs_tag = { + /* cookie */ + (void *) 0, + + /* mapping/unmapping */ + exynos_bs_map, + exynos_bs_unmap, + exynos_a4x_bs_subregion, + + /* allocation/deallocation */ + exynos_bs_alloc, /* not implemented */ + exynos_bs_free, /* not implemented */ + + /* get kernel virtual address */ + exynos_bs_vaddr, + + /* mmap */ + exynos_a4x_bs_mmap, + + /* barrier */ + exynos_bs_barrier, + + /* read (single) */ + a4x_bs_r_1, + NSWAP(a4x_bs_r_2), + NSWAP(a4x_bs_r_4), + bs_notimpl_bs_r_8, + + /* read multiple */ + a4x_bs_rm_1, + NSWAP(a4x_bs_rm_2), + NSWAP(a4x_bs_rm_4), + bs_notimpl_bs_rm_8, + + /* read region */ + bs_notimpl_bs_rr_1, + bs_notimpl_bs_rr_2, + bs_notimpl_bs_rr_4, + bs_notimpl_bs_rr_8, + + /* write (single) */ + a4x_bs_w_1, + NSWAP(a4x_bs_w_2), + NSWAP(a4x_bs_w_4), + bs_notimpl_bs_w_8, + + /* write multiple */ + a4x_bs_wm_1, + NSWAP(a4x_bs_wm_2), + NSWAP(a4x_bs_wm_4), + bs_notimpl_bs_wm_8, + + /* write region */ + bs_notimpl_bs_wr_1, + bs_notimpl_bs_wr_2, + bs_notimpl_bs_wr_4, + bs_notimpl_bs_wr_8, + + /* set multiple */ + bs_notimpl_bs_sm_1, + bs_notimpl_bs_sm_2, + bs_notimpl_bs_sm_4, + bs_notimpl_bs_sm_8, + + /* set region */ + bs_notimpl_bs_sr_1, + bs_notimpl_bs_sr_2, + bs_notimpl_bs_sr_4, + bs_notimpl_bs_sr_8, + + /* copy */ + bs_notimpl_bs_c_1, + bs_notimpl_bs_c_2, + bs_notimpl_bs_c_4, + bs_notimpl_bs_c_8, + +#ifdef __BUS_SPACE_HAS_STREAM_METHODS + /* read (single) */ + a4x_bs_r_1, + NSWAP(a4x_bs_r_2), + NSWAP(a4x_bs_r_4), + bs_notimpl_bs_r_8, + + /* read multiple */ + a4x_bs_rm_1, + NSWAP(a4x_bs_rm_2), + NSWAP(a4x_bs_rm_4), + bs_notimpl_bs_rm_8, + + /* read region */ + a4x_bs_rr_1, + NSWAP(a4x_bs_rr_2), + NSWAP(a4x_bs_rr_4), + bs_notimpl_bs_rr_8, + + /* write (single) */ + a4x_bs_w_1, + NSWAP(a4x_bs_w_2), + NSWAP(a4x_bs_w_4), + bs_notimpl_bs_w_8, + + /* write multiple */ + a4x_bs_wm_1, + NSWAP(a4x_bs_wm_2), + NSWAP(a4x_bs_wm_4), + bs_notimpl_bs_wm_8, + + /* write region */ + a4x_bs_wr_1, + NSWAP(a4x_bs_wr_2), + NSWAP(a4x_bs_wr_4), + bs_notimpl_bs_wr_8, +#endif +}; + +int +exynos_bs_map(void *t, bus_addr_t bpa, bus_size_t size, int flag, + bus_space_handle_t *bshp) +{ + u_long startpa, endpa, pa; + const struct pmap_devmap *pd; + vaddr_t va; + + if ((pd = pmap_devmap_find_pa(bpa, size)) != NULL) { + /* Device was statically mapped. */ + *bshp = pd->pd_va + (bpa - pd->pd_pa); + return 0; + } + + startpa = trunc_page(bpa); + endpa = round_page(bpa + size); + + /* XXX use extent manager to check duplicate mapping */ + + va = uvm_km_alloc(kernel_map, endpa - startpa, 0, + UVM_KMF_VAONLY | UVM_KMF_NOWAIT | UVM_KMF_COLORMATCH); + if (!va) + return ENOMEM; + + *bshp = (bus_space_handle_t)(va + (bpa - startpa)); + + const int pmapflags = + (flag & (BUS_SPACE_MAP_CACHEABLE|BUS_SPACE_MAP_PREFETCHABLE)) + ? 0 + : PMAP_NOCACHE; + for (pa = startpa; pa < endpa; pa += PAGE_SIZE, va += PAGE_SIZE) { + pmap_kenter_pa(va, pa, VM_PROT_READ | VM_PROT_WRITE, pmapflags); + } + pmap_update(pmap_kernel()); + + return 0; +} + +void +exynos_bs_unmap(void *t, bus_space_handle_t bsh, bus_size_t size) +{ + vaddr_t va; + vsize_t sz; + + if (pmap_devmap_find_va(bsh, size) != NULL) { + /* Device was statically mapped; nothing to do. */ + return; + } + + va = trunc_page(bsh); + sz = round_page(bsh + size) - va; + + pmap_kremove(va, sz); + pmap_update(pmap_kernel()); + uvm_km_free(kernel_map, va, sz, UVM_KMF_VAONLY); +} + + +int +exynos_bs_subregion(void *t, bus_space_handle_t bsh, bus_size_t offset, + bus_size_t size, bus_space_handle_t *nbshp) +{ + + *nbshp = bsh + offset; + return (0); +} + +int +exynos_a4x_bs_subregion(void *t, bus_space_handle_t bsh, bus_size_t offset, + bus_size_t size, bus_space_handle_t *nbshp) +{ + + *nbshp = bsh + 4 * offset; + return (0); +} + +void +exynos_bs_barrier(void *t, bus_space_handle_t bsh, bus_size_t offset, + bus_size_t len, int flags) +{ + flags &= BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE; + + if (flags) { + /* Issue an ARM11 Data Syncronisation Barrier (DSB) */ +#ifdef _ARM_ARCH_7 + __asm __volatile("dsb"); +#else + __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" : : "r" (0) + : "memory"); +#endif + return; + } + +} + +void * +exynos_bs_vaddr(void *t, bus_space_handle_t bsh) +{ + + return (void *)bsh; +} + +paddr_t +exynos_bs_mmap(void *t, bus_addr_t bpa, off_t offset, int prot, int flags) +{ + paddr_t bus_flags = 0; + + if (flags & BUS_SPACE_MAP_PREFETCHABLE) + bus_flags |= ARM32_MMAP_WRITECOMBINE; + + return (arm_btop(bpa + offset) | bus_flags); +} + +paddr_t +exynos_a4x_bs_mmap(void *t, bus_addr_t bpa, off_t offset, int prot, int flags) +{ + paddr_t bus_flags = 0; + + if (flags & BUS_SPACE_MAP_PREFETCHABLE) + bus_flags |= ARM32_MMAP_WRITECOMBINE; + + return (arm_btop(bpa + 4 * offset) | bus_flags); +} + +int +exynos_bs_alloc(void *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("%s(): not implemented\n", __func__); +} + +void +exynos_bs_free(void *t, bus_space_handle_t bsh, bus_size_t size) +{ + + panic("%s(): not implemented\n", __func__); +} + Index: sys/arch/arm/samsung/exynos_sscom.c =================================================================== RCS file: sys/arch/arm/samsung/exynos_sscom.c diff -N sys/arch/arm/samsung/exynos_sscom.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arch/arm/samsung/exynos_sscom.c 11 Apr 2014 15:32:42 -0000 @@ -0,0 +1,165 @@ +/* $NetBSD: sscom_exynos.c,v 1.10 2014/03/14 21:40:48 matt Exp $ */ + +/* + * Copyright (c) 2014 Reinoud Zandijk + * 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. + */ + +#include +__KERNEL_RCSID(0, "$NetBSD: sscom_exynos.c,v 1.10 2014/03/14 21:40:48 matt Exp $"); + +#include "opt_sscom.h" +#include "opt_ddb.h" +#include "opt_kgdb.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +static int sscom_match(device_t, cfdata_t, void *); +static void sscom_attach(device_t, device_t, void *); + +/* XXX cludge for not-existing interrupt code XXX */ +#define exynos_unmask_interrupts(intbits) +#define exynos_mask_interrupts(intbits) + + +CFATTACH_DECL_NEW(exynos_sscom, sizeof(struct sscom_softc), sscom_match, + sscom_attach, NULL, NULL); + +static int +sscom_match(device_t parent, cfdata_t cf, void *aux) +{ + struct exyo_attach_args *sa = aux; + int unit = sa->aio_loc.loc_port; + + return (unit >= 0) && (unit <= 4); +} + +static void +exynos_change_txrx_interrupts(struct sscom_softc *sc, bool unmask_p, + u_int flags) +{ + int intbits = 0; + if (flags & SSCOM_HW_RXINT) + intbits |= 1 << sc->sc_rx_irqno; + if (flags & SSCOM_HW_TXINT) + intbits |= 1 << sc->sc_tx_irqno; + if (unmask_p) { + exynos_unmask_interrupts(intbits); + } else { + exynos_mask_interrupts(intbits); + } +} + +static void +sscom_attach(device_t parent, device_t self, void *aux) +{ + struct sscom_softc *sc = device_private(self); + struct exyo_attach_args *sa = aux; + int unit = sa->aio_loc.loc_port; + bus_addr_t iobase = sa->aio_loc.loc_offset; + + aprint_normal( ": UART%d addr=%lx", unit, iobase ); + + sc->sc_dev = self; + sc->sc_iot = sa->aio_core_bst; + sc->sc_unit = unit; + sc->sc_frequency = EXYNOS_UART_FREQ; + + sc->sc_change_txrx_interrupts = exynos_change_txrx_interrupts; + + sc->sc_rx_irqno = 0; // S3C2800_INT_RXD0 + sa->sa_index; + sc->sc_tx_irqno = 0; // S3C2800_INT_TXD0 + sa->sa_index; + + if (bus_space_map(sc->sc_iot, iobase, SSCOM_SIZE, 0, &sc->sc_ioh)) { + printf( ": failed to map registers\n" ); + return; + } + + printf("\n"); + +#if 0 + exynos_intr_establish(exynos_uart_config[unit].tx_int, + IPL_SERIAL, IST_LEVEL, sscomtxintr, sc); + exynos_intr_establish(exynos_uart_config[unit].rx_int, + IPL_SERIAL, IST_LEVEL, sscomrxintr, sc); + exynos_intr_establish(exynos_uart_config[unit].err_int, + IPL_SERIAL, IST_LEVEL, sscomrxintr, sc); +#endif + sscom_disable_txrxint(sc); + + sscom_attach_subr(sc); +} + + +#if 0 +int +exynos_sscom_cnattach(bus_space_tag_t iot, int unit, int rate, + int frequency, tcflag_t cflag) +{ + return sscom_cnattach(iot, exynos_uart_config + unit, + rate, frequency, cflag); +} + +#ifdef KGDB +int +exynos_sscom_kgdb_attach(bus_space_tag_t iot, int unit, int rate, + int frequency, tcflag_t cflag) +{ + return sscom_kgdb_attach(iot, exynos_uart_config + unit, + rate, frequency, cflag); +} +#endif /* KGDB */ +#endif + Index: sys/arch/arm/samsung/exynos_var.h =================================================================== RCS file: sys/arch/arm/samsung/exynos_var.h diff -N sys/arch/arm/samsung/exynos_var.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arch/arm/samsung/exynos_var.h 11 Apr 2014 15:32:42 -0000 @@ -0,0 +1,108 @@ +/* $NetBSD: awin_var.h,v 1.9 2014/02/26 00:19:01 matt Exp $ */ +/*- + * Copyright (c) 2013, 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Matt Thomas of 3am Software Foundry. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Reinoud Zandijk. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this 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. + */ + +#ifndef _ARM_SAMSUNG_EXYNOS_VAR_H_ +#define _ARM_SAMSUNG_EXYNOS_VAR_H_ + +#include +#include +#include +#include + +//#include + +extern uint32_t exynos_soc_id; +extern uint32_t exynos_pop_id; + +#define EXYNOS_PRODUCT_FAMILY(soc) __SHIFTOUT((soc), __BITS(24,31)) +#define EXYNOS4_PRODUCT_FAMILY 0xe4 +#define EXYNOS5_PRODUCT_FAMILY 0xe5 +#define EXYNOS_PRODUCT_ID(soc) __SHIFTOUT((soc), __BITS(12,31)) +#define EXYNOS_PRODUCT_PACKAGE(soc) __SHIFTOUT((soc), __BITS(8,11)) +#define EXYNOS_PRODUCT_REV(soc) __SHIFTOUT((soc), __BITS(4,7)) +#define EXYNOS_PRODUCT_SUBREV(soc) __SHIFTOUT((soc), __BITS(0,3)) + + +#define IS_EXYNOS4410 (EXYNOS_PRODUCT_ID(exynos_soc_id) == 0xe4410) +#define IS_EXYNOS4412 (EXYNOS_PRODUCT_ID(exynos_soc_id) == 0xe4412) +#define IS_EXYNOS4412_R0 \ + ((EXYNOS_PRODUCT_ID(exynos_soc_id) == 0xe4412) && \ + (EXYNOS_PRODUCT_REV(exynos_soc_id) == 0)) +#define IS_EXYNOS5440 (EXYNOS_PRODUCT_ID(exynos_soc_id) == 0xe5440) + +#define IS_EXYNOS4 (IS_EXYNOS4410 || IS_EXYNOS4412) +#define IS_EXYNOS5 (IS_EXYNOS5440) + +struct exyo_locators { + const char *loc_name; + bus_size_t loc_offset; + bus_size_t loc_size; + int loc_port; + int loc_intr; + int loc_flags; +}; + +#define EXYO_INTR_DEFAULT 0 + +#if 0 +#define EXYO_E4410 __BIT(0) +#define EXYO_E4412 __BIT(1) +#define EXYO_E5440 __BIT(2) +#define EXYO_E5XXX __BIT(3) + +#define EXYO_ONLY __BITS(7,0) +#define EXYO_ALL __BITS(7,0) +#define EXYO_REQUIRED __BIT(8) +#endif + +struct exyo_attach_args { + struct exyo_locators aio_loc; + bus_space_tag_t aio_core_bst; + bus_space_tag_t aio_core_a4x_bst; + bus_space_handle_t aio_core_bsh; + bus_space_handle_t aio_ccm_bsh; + bus_dma_tag_t aio_dmat; + bus_dma_tag_t aio_coherent_dmat; +}; + + +extern struct bus_space exynos_bs_tag; +extern struct bus_space exynos_a4x_bs_tag; +extern bus_space_handle_t exynos_core_bsh; + +void exynos_bootstrap(vaddr_t, vaddr_t); +void exynos_device_register(device_t self, void *aux); +void exyo_device_register(device_t self, void *aux); + +#endif /* _ARM_SAMSUNG_EXYNOS_VAR_H_ */ + Index: sys/arch/arm/samsung/files.exynos =================================================================== RCS file: sys/arch/arm/samsung/files.exynos diff -N sys/arch/arm/samsung/files.exynos --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arch/arm/samsung/files.exynos 11 Apr 2014 15:32:42 -0000 @@ -0,0 +1,67 @@ +# $NetBSD$ +# +# Configuration info for Samsung Exynos SoC ARM Peripherals +# + +include "arch/arm/pic/files.pic" +include "arch/arm/cortex/files.cortex" + +file arch/arm/arm32/arm32_boot.c +file arch/arm/arm32/arm32_kvminit.c +file arch/arm/arm32/arm32_reboot.c +file arch/arm/arm32/irq_dispatch.S + +file arch/arm/samsung/exynos_soc.c +file arch/arm/samsung/exynos_space.c +#file arch/arm/samsung/primecell.c +file arch/arm/samsung/exynos_smc.S arm_trustzone_firmware +file arch/arm/trustzone/firmware.c arm_trustzone_firmware + +file arch/arm/arm/bus_space_a4x.S exyo + +# Console parameters +defparam opt_exynos.h CONADDR +defparam opt_exynos.h CONSPEED +defparam opt_exynos.h CONMODE + +# Memory size in megabytes +defparam opt_exynos.h MEMSIZE +defparam opt_exynos.h EXYNOS_WDT_DEFAULT_PERIOD +defflag opt_exynos.h EXYNOS_CONSOLE_EARLY + +# +defflag opt_exynos.h EXYNOS4 +defflag opt_exynos.h EXYNOS4120: EXYNOS4 +defflag opt_exynos.h EXYNOS4212: EXYNOS4 +defflag opt_exynos.h EXYNOS4412: EXYNOS4 +defflag opt_exynos.h EXYNOS4412P: EXYNOS4 +defflag opt_exynos.h EXYNOS5 +defflag opt_exynos.h EXYNOS5250: EXYNOS5 +defflag opt_exynos.h EXYNOS5260: EXYNOS5 +defflag opt_exynos.h EXYNOS5410: EXYNOS5 +defflag opt_exynos.h EXYNOS5420: EXYNOS5 +defflag opt_exynos.h EXYNOS5440: EXYNOS5 +defflag opt_exynos.h EXYNOS5422: EXYNOS5 + +# SoC I/O attach point +device exyo { [port=-1] } : bus_space_generic +attach exyo at mainbus with exyo_io +file arch/arm/samsung/exynos_io.c exyo_io +file arch/arm/samsung/exynos4_loc.c exyo_io | exynos4 +file arch/arm/samsung/exynos5_loc.c exyo_io | exynos5 + +# Multi Core timer +device mct { } : bus_space_generic +attach mct at exyo with exyo_mct +file arch/arm/samsung/mct.c exyo_mct + +# UARTs +# +# built-in UART +# +device sscom +attach sscom at exyo with exynos_sscom +file arch/arm/samsung/sscom.c sscom needs-flag +file arch/arm/samsung/exynos_sscom.c exynos_sscom +defflag opt_sscom.h SSCOM0CONSOLE SSCOM1CONSOLE +defparam opt_sscom.h SSCOM_FREQ Index: sys/arch/arm/samsung/mct.c =================================================================== RCS file: sys/arch/arm/samsung/mct.c diff -N sys/arch/arm/samsung/mct.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arch/arm/samsung/mct.c 11 Apr 2014 15:32:42 -0000 @@ -0,0 +1,305 @@ +/* $NetBSD$ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Reinoud Zandijk. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this 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 + +__KERNEL_RCSID(1, "$NetBSD: exynos_io.c,v 1.8 2014/02/26 00:19:01 matt Exp $"); + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + + +static int mct_match(device_t, cfdata_t, void *); +static void mct_attach(device_t, device_t, void *); + +static int clockhandler(void *); +static u_int mct_get_timecount(struct timecounter *); + + +CFATTACH_DECL_NEW(exyo_mct, 0, mct_match, mct_attach, NULL, NULL); + + +static struct timecounter mct_timecounter = { + .tc_get_timecount = mct_get_timecount, + .tc_poll_pps = 0, + .tc_counter_mask = ~0u, + .tc_frequency = 0, /* set by cpu_initclocks() */ + .tc_name = NULL, /* set by cpu_initclocks() */ + .tc_quality = 500, /* why 500? */ + .tc_priv = &mct_sc, + .tc_next = NULL, +}; + + +static inline uint32_t +mct_read_global(struct mct_softc *sc, bus_size_t o) +{ + return bus_space_read_4(sc->sc_bst, sc->sc_bsh, o); +} + + +static inline void +mct_write_global(struct mct_softc *sc, bus_size_t o, uint32_t v) +{ + bus_size_t wreg; + uint32_t bit; + int i; + + /* do the write */ + bus_space_write_4(sc->sc_bst, sc->sc_bsh, o, v); +// printf("%s: write %#x at %#x\n", +// __func__, ((uint32_t) sc->sc_bsh + (uint32_t) o), v); + + /* dependent on the write address, do the ack dance */ + if (o == MCT_G_CNT_L || o == MCT_G_CNT_U) { + wreg = MCT_G_CNT_WSTAT; + bit = (o == MCT_G_CNT_L) ? G_CNT_WSTAT_L : G_CNT_WSTAT_U; + } else { + wreg = MCT_G_WSTAT; + switch (o) { + case MCT_G_COMP0_L: + bit = G_WSTAT_COMP0_L; + break; + case MCT_G_COMP0_U: + bit = G_WSTAT_COMP0_U; + break; + case MCT_G_COMP0_ADD_INCR: + bit = G_WSTAT_ADD_INCR; + break; + case MCT_G_TCON: + bit = G_WSTAT_TCON; + break; + default: + /* all other registers */ + return; + } + } + + /* wait for ack */ + for (i = 0; i < 10000000; i++) { + /* value accepted by the hardware/hal ? */ + if (mct_read_global(sc, wreg) & bit) { + /* ack */ + bus_space_write_4(sc->sc_bst, sc->sc_bsh, wreg, bit); + return; + } + } + panic("MCT hangs after writing %#x at %#x", v, (uint32_t) o); +} + + +static int +mct_match(device_t parent, cfdata_t cf, void *aux) +{ + /* sanity check, something is mixed up! */ + if (!device_is_a(parent, "exyo")) + return 1; + + /* there can only be one */ + if (mct_sc.sc_dev != NULL) + return 0; + + return 1; +} + + +static void +mct_attach(device_t parent, device_t self, void *aux) +{ + struct exyo_attach_args *aio = (struct exyo_attach_args *) aux; + struct mct_softc * const sc = &mct_sc; + prop_dictionary_t dict = device_properties(self); + char freqbuf[sizeof("XXX SHz")]; + + self->dv_private = sc; + sc->sc_dev = self; + sc->sc_bst = aio->aio_core_bst; + sc->sc_irq = aio->aio_loc.loc_intr; + + bus_space_subregion(sc->sc_bst, aio->aio_core_bsh, + aio->aio_loc.loc_offset, aio->aio_loc.loc_size, &sc->sc_bsh); + + KASSERTMSG(sc->sc_bsh, + "%s: can't map in registers for %#x + %#x for device %s\n", + __func__, + (uint32_t) aio->aio_loc.loc_offset, + (uint32_t) aio->aio_loc.loc_size, + device_xname(sc->sc_dev)); + + prop_dictionary_get_uint32(dict, "frequency", &sc->sc_freq); + + humanize_number(freqbuf, sizeof(freqbuf), sc->sc_freq, "Hz", 1000); + + aprint_naive("\n"); + aprint_normal(": Exynos SoC multi core timer (64 bits) (%s)\n", freqbuf); + + evcnt_attach_dynamic(&sc->sc_ev_missing_ticks, EVCNT_TYPE_MISC, NULL, + device_xname(self), "missing interrupts"); + + sc->sc_global_ih = intr_establish(sc->sc_irq, IPL_CLOCK, IST_EDGE, + clockhandler, NULL); + if (sc->sc_global_ih == NULL) + panic("%s: unable to register timer interrupt", __func__); + aprint_normal_dev(sc->sc_dev, "interrupting on irq %d\n", sc->sc_irq); +} + + +static inline uint64_t +mct_gettime(struct mct_softc *sc) +{ + uint32_t lo, hi; + do { + hi = mct_read_global(sc, MCT_G_CNT_U); + lo = mct_read_global(sc, MCT_G_CNT_L); + } while (hi != mct_read_global(sc, MCT_G_CNT_U)); + return ((uint64_t) hi << 32) | lo; +} + + +static u_int +mct_get_timecount(struct timecounter *tc) +{ + struct mct_softc * const sc = tc->tc_priv; + return (u_int) (mct_gettime(sc)); +} + + +/* interrupt handler */ +static int +clockhandler(void *arg) +{ + struct clockframe * const cf = arg; + struct mct_softc * const sc = &mct_sc; + const uint64_t now = mct_gettime(sc); + uint64_t delta = now - sc->sc_lastintr; + + /* ack the interrupt */ + mct_write_global(sc, MCT_G_INT_CSTAT, G_INT_CSTAT_CLEAR); + + /* check if we missed clock interrupts */ + if (delta > sc->sc_autoinc) + sc->sc_ev_missing_ticks.ev_count += delta / sc->sc_autoinc; + + sc->sc_lastintr = now; + hardclock(cf); + + /* handled */ + return 1; +} + + +void +mct_init_cpu_clock(struct cpu_info *ci) +{ + struct mct_softc * const sc = &mct_sc; + uint64_t now = mct_gettime(sc); + uint64_t then; + uint32_t tcon; + + KASSERT(ci == curcpu()); + + sc->sc_lastintr = now; + + /* get current config */ + tcon = mct_read_global(sc, MCT_G_TCON); + + /* setup auto increment */ + mct_write_global(sc, MCT_G_COMP0_ADD_INCR, sc->sc_autoinc); + + /* (re)setup comparator */ + then = now + sc->sc_autoinc; + mct_write_global(sc, MCT_G_COMP0_L, (uint32_t) then); + mct_write_global(sc, MCT_G_COMP0_U, (uint32_t) (then >> 32)); + tcon |= G_TCON_COMP0_AUTOINC; + tcon |= G_TCON_COMP0_ENABLE; + + /* start timer */ + tcon |= G_TCON_START; + + /* enable interrupt */ + mct_write_global(sc, MCT_G_INT_ENB, G_INT_ENB_ENABLE); + + /* update config, starting the thing */ + mct_write_global(sc, MCT_G_TCON, tcon); +} + + +void +cpu_initclocks(void) +{ + struct mct_softc * const sc = &mct_sc; + + sc->sc_autoinc = sc->sc_freq / hz; + mct_init_cpu_clock(curcpu()); + + mct_timecounter.tc_name = device_xname(sc->sc_dev); + mct_timecounter.tc_frequency = sc->sc_freq; + + tc_init(&mct_timecounter); + +#if 0 + { + uint64_t then, now; + + printf("testing timer\n"); + for (int i = 0; i < 200; i++) { + printf("cstat %d\n", mct_read_global(sc, MCT_G_INT_CSTAT)); + then = mct_get_timecount(&mct_timecounter); + do { + now = mct_get_timecount(&mct_timecounter); + } while (now == then); + printf("\tgot %"PRIu64"\n", now); + for (int j = 0; j < 90000; j++); + } + printf("passed\n"); + } +#endif +} + + +void +setstatclockrate(int newhz) +{ +} + Index: sys/arch/arm/samsung/mct_reg.h =================================================================== RCS file: sys/arch/arm/samsung/mct_reg.h diff -N sys/arch/arm/samsung/mct_reg.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arch/arm/samsung/mct_reg.h 11 Apr 2014 15:32:42 -0000 @@ -0,0 +1,79 @@ +/* $NetBSD */ +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Reinoud Zandijk. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this 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. + */ + +#ifndef _ARM_SAMSUNG_MCT_REG_H_ +#define _ARM_SAMSUNG_MCT_REG_H_ + +/* global timer register offsets */ +#define MCT_G_CNT_L 0x100 /* lower bits */ +#define MCT_G_CNT_U 0x104 /* higher bits */ +#define MCT_G_CNT_WSTAT 0x110 /* wait for write OK cntr */ +#define G_CNT_WSTAT_L __BIT(0) +#define G_CNT_WSTAT_U __BIT(1) + +#define MCT_G_COMP0_L 0x200 /* compare0 lower bits */ +#define MCT_G_COMP0_U 0x204 /* compare0 higher bits */ +#define MCT_G_COMP0_ADD_INCR 0x208 /* compare0 auto add value */ +#define MCT_G_TCON 0x240 /* configuration register */ +#define G_TCON_COMP0_ENABLE __BIT(0) +#define G_TCON_COMP0_AUTOINC __BIT(1) +#define G_TCON_START __BIT(8) +#define MCT_G_INT_CSTAT 0x244 /* clear interrupt */ +#define G_INT_CSTAT_CLEAR __BIT(0) +#define MCT_G_INT_ENB 0x248 /* enable interrupts */ +#define G_INT_ENB_ENABLE __BIT(0) +#define MCT_G_WSTAT 0x24C /* wait for write OK */ +#define G_WSTAT_COMP0_L __BIT(0) +#define G_WSTAT_COMP0_U __BIT(1) +#define G_WSTAT_ADD_INCR __BIT(2) +#define G_WSTAT_TCON __BIT(16) + +/* local cpu-bound timers */ +#define MCT_L_OFFSET(x) (0x300 + (0x100 * x)) +#define MCT_L_MASK 0xffffff00 + +#define MCT_L_TCNTB 0x00 /* TODO: what */ +#define MCT_L_ICNTB 0x08 /* interrupt count buffer */ +#define L_INCTB_UPDATE(x) (__BIT(31) | (x)) +#define MCT_L_TCON 0x20 /* configuration register */ +#define L_TCON_TIMER_START __BIT(0) +#define L_TCON_INT_START __BIT(1) +#define L_TCON_INTERVAL_MODE __BIT(2) +#define MCT_L_INC_CSTAT 0x30 +#define L_INC_CSTAT_CLEAR __BIT(0) +#define MCT_L_INT_ENB 0x34 +#define L_INT_ENB_ENABLE __BIT(0) +#define MCT_L_WSTAT 0x40 +#define L_WSTAT_L_TCNTB __BIT(0) +#define L_WSTAT_L_ICNTB __BIT(1) +#define L_WSTAT_L_TCON __BIT(3) + +#endif /* _ARM_SAMSUNG_MCT_REG_H_ */ + Index: sys/arch/arm/samsung/mct_var.h =================================================================== RCS file: sys/arch/arm/samsung/mct_var.h diff -N sys/arch/arm/samsung/mct_var.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arch/arm/samsung/mct_var.h 11 Apr 2014 15:32:42 -0000 @@ -0,0 +1,55 @@ +/* $NetBSD */ +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Reinoud Zandijk. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this 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. + */ + +#ifndef _ARM_SAMSUNG_MCT_VAR_H_ +#define _ARM_SAMSUNG_MCT_VAR_H_ + +#include +#include +#include + +static struct mct_softc { + device_t sc_dev; + bus_space_tag_t sc_bst; + bus_space_handle_t sc_bsh; + uint32_t sc_irq; + + uint32_t sc_freq; + void *sc_global_ih; + + uint64_t sc_lastintr; + uint32_t sc_autoinc; + struct evcnt sc_ev_missing_ticks; +} mct_sc; + +void mct_init_cpu_clock(struct cpu_info *ci); + +#endif /* _ARM_SAMSUNG_MCT_VAR_H_ */ + Index: sys/arch/arm/samsung/smc.h =================================================================== RCS file: sys/arch/arm/samsung/smc.h diff -N sys/arch/arm/samsung/smc.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arch/arm/samsung/smc.h 11 Apr 2014 15:32:42 -0000 @@ -0,0 +1,72 @@ +/* $NetBSD: exynos_soc.c,v 1.12 2014/03/13 23:45:02 matt Exp $ */ +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Reinoud Zandijk. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this 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. + */ + + +#ifndef _ARM_SAMSUNG_SMC_H_ +#define _ARM_SAMSUNG_SMC_H_ + +/* provided by Samsung for the Exynos SMC calls */ + +#define SMC_CMD_INIT (-1) +#define SMC_CMD_INFO (-2) +/* For Power Management */ +#define SMC_CMD_SLEEP (-3) +#define SMC_CMD_CPU1BOOT (-4) +#define SMC_CMD_CPU0AFTR (-5) +/* For CP15 Access */ +#define SMC_CMD_C15RESUME (-11) +/* For L2 Cache Access */ +#define SMC_CMD_L2X0CTRL (-21) +#define SMC_CMD_L2X0SETUP1 (-22) +#define SMC_CMD_L2X0SETUP2 (-23) +#define SMC_CMD_L2X0INVALL (-24) +#define SMC_CMD_L2X0DEBUG (-25) + + +/* XXX status of the following SMC is not known */ +/* For Accessing CP15/SFR (General) */ +#define SMC_CMD_REG (-101) + +/* MACRO for SMC_CMD_REG */ +#define SMC_REG_CLASS_CP15 (0x0 << 30) +#define SMC_REG_CLASS_SFR_W (0x1 << 30) +#define SMC_REG_CLASS_SFR_R (0x3 << 30) +#define SMC_REG_CLASS_MASK (0x3 << 30) +#define SMC_REG_ID_CP15(CRn, Op1, CRm, Op2) \ + (SMC_REG_CLASS_CP15 | \ + ((CRn) << 10) | ((Op1) << 7) | ((CRm) << 3) | (Op2)) +#define SMC_REG_ID_SFR_W(ADDR) (SMC_REG_CLASS_SFR_W | ((ADDR) >> 2)) +#define SMC_REG_ID_SFR_R(ADDR) (SMC_REG_CLASS_SFR_R | ((ADDR) >> 2)) + + +extern void exynos_smc(uint32_t cmd, uint32_t arg1, uint32_t arg2, uint32_t arg3); + +#endif /* _ARM_SAMSUNG_SMC_H_ */ + Index: sys/arch/arm/samsung/sscom.c =================================================================== RCS file: sys/arch/arm/samsung/sscom.c diff -N sys/arch/arm/samsung/sscom.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arch/arm/samsung/sscom.c 11 Apr 2014 15:32:43 -0000 @@ -0,0 +1,2092 @@ +/* $NetBSD: sscom.c,v 1.44 2014/03/16 12:26:58 reinoud 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. + */ + +/*- + * Copyright (c) 1998, 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) 1991 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. + * + * @(#)com.c 7.5 (Berkeley) 5/16/91 + */ + +/* + * Support integrated UARTs of Samsung S3C2800/2400X/2410X + * Derived from sys/dev/ic/com.c + */ + +#include +__KERNEL_RCSID(0, "$NetBSD: sscom.c,v 1.44 2014/03/16 12:26:58 reinoud Exp $"); + +#include "opt_sscom.h" +#include "opt_ddb.h" +#include "opt_kgdb.h" +#include "opt_multiprocessor.h" +#include "opt_lockdebug.h" + +#include "rnd.h" +#ifdef RND_COM +#include +#endif + +/* + * Override cnmagic(9) macro before including . + * We need to know if cn_check_magic triggered debugger, so set a flag. + * Callers of cn_check_magic must declare int cn_trapped = 0; + * XXX: this is *ugly*! + */ +#define cn_trap() \ + do { \ + console_debugger(); \ + cn_trapped = 1; \ + } while (/* CONSTCOND */ 0) + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +dev_type_open(sscomopen); +dev_type_close(sscomclose); +dev_type_read(sscomread); +dev_type_write(sscomwrite); +dev_type_ioctl(sscomioctl); +dev_type_stop(sscomstop); +dev_type_tty(sscomtty); +dev_type_poll(sscompoll); + +int sscomcngetc (dev_t); +void sscomcnputc (dev_t, int); +void sscomcnpollc (dev_t, int); + +#define integrate static inline +void sscomsoft (void *); + +integrate void sscom_rxsoft (struct sscom_softc *, struct tty *); +integrate void sscom_txsoft (struct sscom_softc *, struct tty *); +integrate void sscom_stsoft (struct sscom_softc *, struct tty *); +integrate void sscom_schedrx (struct sscom_softc *); +static void sscom_modem(struct sscom_softc *, int); +static void sscom_break(struct sscom_softc *, int); +static void sscom_iflush(struct sscom_softc *); +static void sscom_hwiflow(struct sscom_softc *); +static void sscom_loadchannelregs(struct sscom_softc *); +static void tiocm_to_sscom(struct sscom_softc *, u_long, int); +static int sscom_to_tiocm(struct sscom_softc *); +static void tiocm_to_sscom(struct sscom_softc *, u_long, int); +static int sscom_to_tiocm(struct sscom_softc *); +static void sscom_iflush(struct sscom_softc *); + +static int sscomhwiflow(struct tty *tp, int block); +#if defined(KGDB) || defined(SSCOM0CONSOLE) || defined(SSCOM1CONSOLE) +static int sscom_init(bus_space_tag_t, const struct sscom_uart_info *, + int, int, tcflag_t, bus_space_handle_t *); +#endif + +extern struct cfdriver sscom_cd; + +const struct cdevsw sscom_cdevsw = { + .d_open = sscomopen, + .d_close = sscomclose, + .d_read = sscomread, + .d_write = sscomwrite, + .d_ioctl = sscomioctl, + .d_stop = sscomstop, + .d_tty = sscomtty, + .d_poll = sscompoll, + .d_mmap = nommap, + .d_kqfilter = ttykqfilter, + .d_flag = D_TTY +}; + +/* + * Make this an option variable one can patch. + * But be warned: this must be a power of 2! + */ +u_int sscom_rbuf_size = SSCOM_RING_SIZE; + +/* Stop input when 3/4 of the ring is full; restart when only 1/4 is full. */ +u_int sscom_rbuf_hiwat = (SSCOM_RING_SIZE * 1) / 4; +u_int sscom_rbuf_lowat = (SSCOM_RING_SIZE * 3) / 4; + +static int sscomconsunit = -1; +static bus_space_tag_t sscomconstag; +static bus_space_handle_t sscomconsioh; +static int sscomconsattached; +static int sscomconsrate; +static tcflag_t sscomconscflag; +static struct cnm_state sscom_cnm_state; + +#ifdef KGDB +#include + +static int sscom_kgdb_unit = -1; +static bus_space_tag_t sscom_kgdb_iot; +static bus_space_handle_t sscom_kgdb_ioh; +static int sscom_kgdb_attached; + +int sscom_kgdb_getc (void *); +void sscom_kgdb_putc (void *, int); +#endif /* KGDB */ + +#define SSCOMUNIT_MASK 0x7f +#define SSCOMDIALOUT_MASK 0x80 + +#define SSCOMUNIT(x) (minor(x) & SSCOMUNIT_MASK) +#define SSCOMDIALOUT(x) (minor(x) & SSCOMDIALOUT_MASK) + +#if 0 +#define SSCOM_ISALIVE(sc) ((sc)->enabled != 0 && \ + device_is_active(&(sc)->sc_dev)) +#else +#define SSCOM_ISALIVE(sc) device_is_active((sc)->sc_dev) +#endif + +#define BR BUS_SPACE_BARRIER_READ +#define BW BUS_SPACE_BARRIER_WRITE +#define SSCOM_BARRIER(t, h, f) /* no-op */ + +#if (defined(MULTIPROCESSOR) || defined(LOCKDEBUG)) && defined(SSCOM_MPLOCK) + +#define SSCOM_LOCK(sc) mutex_enter((sc)->sc_lock) +#define SSCOM_UNLOCK(sc) mutex_exit((sc)->sc_lock) + +#else + +#define SSCOM_LOCK(sc) +#define SSCOM_UNLOCK(sc) + +#endif + +#ifndef SSCOM_TOLERANCE +#define SSCOM_TOLERANCE 30 /* XXX: baud rate tolerance, in 0.1% units */ +#endif + +/* value for UCON */ +#define UCON_RXINT_MASK \ + (UCON_RXMODE_MASK|UCON_ERRINT|UCON_TOINT|UCON_RXINT_TYPE) +#define UCON_RXINT_ENABLE \ + (UCON_RXMODE_INT|UCON_ERRINT|UCON_TOINT|UCON_RXINT_TYPE_LEVEL) +#define UCON_TXINT_MASK (UCON_TXMODE_MASK|UCON_TXINT_TYPE) +#define UCON_TXINT_ENABLE (UCON_TXMODE_INT|UCON_TXINT_TYPE_LEVEL) + +/* we don't want tx interrupt on debug port, but it is needed to + have transmitter active */ +#define UCON_DEBUGPORT (UCON_RXINT_ENABLE|UCON_TXINT_ENABLE) + + +static inline void +__sscom_output_chunk(struct sscom_softc *sc, int ufstat) +{ + int n, space; + bus_space_tag_t iot = sc->sc_iot; + bus_space_handle_t ioh = sc->sc_ioh; + + n = sc->sc_tbc; + space = 16 - ((ufstat & UFSTAT_TXCOUNT) >> UFSTAT_TXCOUNT_SHIFT); + + if (n > space) + n = space; + + if (n > 0) { + bus_space_write_multi_1(iot, ioh, SSCOM_UTXH, sc->sc_tba, n); + sc->sc_tbc -= n; + sc->sc_tba += n; + } +} + +static void +sscom_output_chunk(struct sscom_softc *sc) +{ + uint32_t ufstat = bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSCOM_UFSTAT); + + if (!(ufstat & UFSTAT_TXFULL)) + __sscom_output_chunk(sc, ufstat); +} + +int +sscomspeed(long speed, long frequency) +{ +#define divrnd(n, q) (((n)*2/(q)+1)/2) /* divide and round off */ + + int x, err; + + if (speed <= 0) + return -1; + x = divrnd(frequency / 16, speed); + if (x <= 0) + return -1; + err = divrnd(((quad_t)frequency) * 1000 / 16, speed * x) - 1000; + if (err < 0) + err = -err; + if (err > SSCOM_TOLERANCE) + return -1; + return x-1; + +#undef divrnd +} + +void sscomstatus (struct sscom_softc *, const char *); + +#ifdef SSCOM_DEBUG +int sscom_debug = 0; + +/* XXX not all is printed in this version XXX */ +void +sscomstatus(struct sscom_softc *sc, const char *str) +{ + struct tty *tp = sc->sc_tty; + int umstat = bus_space_read_1(sc->sc_iot, sc->sc_iot, SSCOM_UMSTAT); + int umcon = bus_space_read_4(sc->sc_iot, sc->sc_iot, SSCOM_UMCON); + + printf("%s: %s %sclocal %sdcd %sts_carr_on %sdtr %stx_stopped\n", + device_xname(sc->sc_dev), str, + ISSET(tp->t_cflag, CLOCAL) ? "+" : "-", + "+", /* DCD */ + ISSET(tp->t_state, TS_CARR_ON) ? "+" : "-", + "+", /* DTR */ + sc->sc_tx_stopped ? "+" : "-"); + + printf("%s: %s %scrtscts %scts %sts_ttstop %srts %xrx_flags\n", + device_xname(sc->sc_dev), str, + ISSET(tp->t_cflag, CRTSCTS) ? "+" : "-", + ISSET(umstat, UMSTAT_CTS) ? "+" : "-", + ISSET(tp->t_state, TS_TTSTOP) ? "+" : "-", + ISSET(umcon, UMCON_RTS) ? "+" : "-", + sc->sc_rx_flags); +} +#else +#define sscom_debug 0 +#endif + +static void +sscom_enable_debugport(struct sscom_softc *sc) +{ + int s; + + /* Turn on line break interrupt, set carrier. */ + s = splserial(); + SSCOM_LOCK(sc); + sc->sc_ucon = UCON_DEBUGPORT; + bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSCOM_UCON, sc->sc_ucon); + sc->sc_umcon = UMCON_RTS|UMCON_DTR; + sc->sc_set_modem_control(sc); + sscom_enable_rxint(sc); + sscom_disable_txint(sc); + SSCOM_UNLOCK(sc); + splx(s); +} + +static void +sscom_set_modem_control(struct sscom_softc *sc) +{ + /* flob RTS */ + bus_space_write_4(sc->sc_iot, sc->sc_ioh, + SSCOM_UMCON, sc->sc_umcon & UMCON_HW_MASK); + /* ignore DTR */ +} + +static int +sscom_read_modem_status(struct sscom_softc *sc) +{ + int msts; + + msts = bus_space_read_1(sc->sc_iot, sc->sc_ioh, SSCOM_UMSTAT); + + /* DCD and DSR are always on */ + return (msts & UMSTAT_CTS) | MSTS_DCD | MSTS_DSR; +} + +void +sscom_attach_subr(struct sscom_softc *sc) +{ + int unit = sc->sc_unit; + bus_space_tag_t iot = sc->sc_iot; + bus_space_handle_t ioh = sc->sc_ioh; + struct tty *tp; + + callout_init(&sc->sc_diag_callout, 0); +#if (defined(MULTIPROCESSOR) || defined(LOCKDEBUG)) && defined(SSCOM_MPLOCK) + sc->sc_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_SERIAL); +#endif + + sc->sc_ucon = UCON_RXINT_ENABLE|UCON_TXINT_ENABLE; + + /* + * set default for modem control hook + */ + if (sc->sc_set_modem_control == NULL) + sc->sc_set_modem_control = sscom_set_modem_control; + if (sc->sc_read_modem_status == NULL) + sc->sc_read_modem_status = sscom_read_modem_status; + + /* Disable interrupts before configuring the device. */ + KASSERT(sc->sc_change_txrx_interrupts != NULL); + sscom_disable_txrxint(sc); + +#ifdef KGDB + /* + * Allow kgdb to "take over" this port. If this is + * the kgdb device, it has exclusive use. + */ + if (unit == sscom_kgdb_unit) { + SET(sc->sc_hwflags, SSCOM_HW_KGDB); + sc->sc_ucon = UCON_DEBUGPORT; + } +#endif + + if (unit == sscomconsunit) { + uint32_t stat; + int timo; + + sscomconsattached = 1; + sscomconstag = iot; + sscomconsioh = ioh; + + /* wait for this transmission to complete */ + timo = 1500000; + do { + stat = bus_space_read_4(iot, ioh, SSCOM_UTRSTAT); + } while ((stat & UTRSTAT_TXEMPTY) == 0 && --timo > 0); + + /* Make sure the console is always "hardwired". */ + SET(sc->sc_hwflags, SSCOM_HW_CONSOLE); + SET(sc->sc_swflags, TIOCFLAG_SOFTCAR); + + sc->sc_ucon = UCON_DEBUGPORT; + } + + /* set RX/TX trigger to half values */ + bus_space_write_4(iot, ioh, SSCOM_UFCON, + (4<sc_ucon); + +#ifdef KGDB + if (ISSET(sc->sc_hwflags, SSCOM_HW_KGDB)) { + sscom_kgdb_attached = 1; + printf("%s: kgdb\n", device_xname(sc->sc_dev)); + sscom_enable_debugport(sc); + return; + } +#endif + + tp = tty_alloc(); + tp->t_oproc = sscomstart; + tp->t_param = sscomparam; + tp->t_hwiflow = sscomhwiflow; + + sc->sc_tty = tp; + sc->sc_rbuf = malloc(sscom_rbuf_size << 1, M_DEVBUF, M_NOWAIT); + sc->sc_rbput = sc->sc_rbget = sc->sc_rbuf; + sc->sc_rbavail = sscom_rbuf_size; + if (sc->sc_rbuf == NULL) { + printf("%s: unable to allocate ring buffer\n", + device_xname(sc->sc_dev)); + return; + } + sc->sc_ebuf = sc->sc_rbuf + (sscom_rbuf_size << 1); + + tty_attach(tp); + + if (ISSET(sc->sc_hwflags, SSCOM_HW_CONSOLE)) { + int maj; + + /* locate the major number */ + maj = cdevsw_lookup_major(&sscom_cdevsw); + + cn_tab->cn_dev = makedev(maj, device_unit(sc->sc_dev)); + + printf("%s: console (major=%d)\n", device_xname(sc->sc_dev), maj); + } + + + sc->sc_si = softint_establish(SOFTINT_SERIAL, sscomsoft, sc); + +#ifdef RND_COM + rnd_attach_source(&sc->rnd_source, device_xname(sc->sc_dev), + RND_TYPE_TTY, 0); +#endif + + /* if there are no enable/disable functions, assume the device + is always enabled */ + + if (ISSET(sc->sc_hwflags, SSCOM_HW_CONSOLE)) + sscom_enable_debugport(sc); + else + sscom_disable_txrxint(sc); + + SET(sc->sc_hwflags, SSCOM_HW_DEV_OK); +} + +int +sscom_detach(device_t self, int flags) +{ + struct sscom_softc *sc = device_private(self); + + if (sc->sc_hwflags & (SSCOM_HW_CONSOLE|SSCOM_HW_KGDB)) + return EBUSY; + + return 0; +} + +int +sscom_activate(device_t self, enum devact act) +{ +#ifdef notyet + struct sscom_softc *sc = device_private(self); +#endif + + switch (act) { + case DVACT_DEACTIVATE: +#ifdef notyet + sc->enabled = 0; +#endif + return 0; + default: + return EOPNOTSUPP; + } +} + +void +sscom_shutdown(struct sscom_softc *sc) +{ +#ifdef notyet + struct tty *tp = sc->sc_tty; + int s; + + s = splserial(); + SSCOM_LOCK(sc); + + /* If we were asserting flow control, then deassert it. */ + SET(sc->sc_rx_flags, RX_IBUF_BLOCKED); + sscom_hwiflow(sc); + + /* Clear any break condition set with TIOCSBRK. */ + sscom_break(sc, 0); + + /* + * Hang up if necessary. Wait a bit, so the other side has time to + * notice even if we immediately open the port again. + * Avoid tsleeping above splhigh(). + */ + if (ISSET(tp->t_cflag, HUPCL)) { + sscom_modem(sc, 0); + SSCOM_UNLOCK(sc); + splx(s); + /* XXX tsleep will only timeout */ + (void) tsleep(sc, TTIPRI, ttclos, hz); + s = splserial(); + SSCOM_LOCK(sc); + } + + if (ISSET(sc->sc_hwflags, SSCOM_HW_CONSOLE)) + /* interrupt on break */ + sc->sc_ucon = UCON_DEBUGPORT; + else + sc->sc_ucon = 0; + bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSCOM_UCON, sc->sc_ucon); + +#ifdef DIAGNOSTIC + if (!sc->enabled) + panic("sscom_shutdown: not enabled?"); +#endif + sc->enabled = 0; + SSCOM_UNLOCK(sc); + splx(s); +#endif +} + +int +sscomopen(dev_t dev, int flag, int mode, struct lwp *l) +{ + struct sscom_softc *sc; + struct tty *tp; + int s, s2; + int error; + + sc = device_lookup_private(&sscom_cd, SSCOMUNIT(dev)); + if (sc == NULL || !ISSET(sc->sc_hwflags, SSCOM_HW_DEV_OK) || + sc->sc_rbuf == NULL) + return ENXIO; + + if (!device_is_active(sc->sc_dev)) + return ENXIO; + +#ifdef KGDB + /* + * If this is the kgdb port, no other use is permitted. + */ + if (ISSET(sc->sc_hwflags, SSCOM_HW_KGDB)) + return EBUSY; +#endif + + tp = sc->sc_tty; + + if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp)) + return (EBUSY); + + s = spltty(); + + /* + * Do the following iff this is a first open. + */ + if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { + struct termios t; + + tp->t_dev = dev; + + s2 = splserial(); + SSCOM_LOCK(sc); + + /* Turn on interrupts. */ + sscom_enable_txrxint(sc); + + /* Fetch the current modem control status, needed later. */ + sc->sc_msts = sc->sc_read_modem_status(sc); + +#if 0 + /* Clear PPS capture state on first open. */ + sc->sc_ppsmask = 0; + sc->ppsparam.mode = 0; +#endif + + SSCOM_UNLOCK(sc); + splx(s2); + + /* + * Initialize the termios status to the defaults. Add in the + * sticky bits from TIOCSFLAGS. + */ + t.c_ispeed = 0; + if (ISSET(sc->sc_hwflags, SSCOM_HW_CONSOLE)) { + t.c_ospeed = sscomconsrate; + t.c_cflag = sscomconscflag; + } else { + t.c_ospeed = TTYDEF_SPEED; + t.c_cflag = TTYDEF_CFLAG; + } + if (ISSET(sc->sc_swflags, TIOCFLAG_CLOCAL)) + SET(t.c_cflag, CLOCAL); + if (ISSET(sc->sc_swflags, TIOCFLAG_CRTSCTS)) + SET(t.c_cflag, CRTSCTS); + if (ISSET(sc->sc_swflags, TIOCFLAG_MDMBUF)) + SET(t.c_cflag, MDMBUF); + /* Make sure sscomparam() will do something. */ + tp->t_ospeed = 0; + (void) sscomparam(tp, &t); + tp->t_iflag = TTYDEF_IFLAG; + tp->t_oflag = TTYDEF_OFLAG; + tp->t_lflag = TTYDEF_LFLAG; + ttychars(tp); + ttsetwater(tp); + + s2 = splserial(); + SSCOM_LOCK(sc); + + /* + * Turn on DTR. We must always do this, even if carrier is not + * present, because otherwise we'd have to use TIOCSDTR + * immediately after setting CLOCAL, which applications do not + * expect. We always assert DTR while the device is open + * unless explicitly requested to deassert it. + */ + sscom_modem(sc, 1); + + /* Clear the input ring, and unblock. */ + sc->sc_rbput = sc->sc_rbget = sc->sc_rbuf; + sc->sc_rbavail = sscom_rbuf_size; + sscom_iflush(sc); + CLR(sc->sc_rx_flags, RX_ANY_BLOCK); + sscom_hwiflow(sc); + + if (sscom_debug) + sscomstatus(sc, "sscomopen "); + + SSCOM_UNLOCK(sc); + splx(s2); + } + + splx(s); + + error = ttyopen(tp, SSCOMDIALOUT(dev), ISSET(flag, O_NONBLOCK)); + if (error) + goto bad; + + error = (*tp->t_linesw->l_open)(dev, tp); + if (error) + goto bad; + + return 0; + +bad: + if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { + /* + * We failed to open the device, and nobody else had it opened. + * Clean up the state as appropriate. + */ + sscom_shutdown(sc); + } + + return error; +} + +int +sscomclose(dev_t dev, int flag, int mode, struct lwp *l) +{ + struct sscom_softc *sc = device_lookup_private(&sscom_cd, SSCOMUNIT(dev)); + struct tty *tp = sc->sc_tty; + + /* XXX This is for cons.c. */ + if (!ISSET(tp->t_state, TS_ISOPEN)) + return 0; + + (*tp->t_linesw->l_close)(tp, flag); + ttyclose(tp); + + if (SSCOM_ISALIVE(sc) == 0) + return 0; + + if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { + /* + * Although we got a last close, the device may still be in + * use; e.g. if this was the dialout node, and there are still + * processes waiting for carrier on the non-dialout node. + */ + sscom_shutdown(sc); + } + + return 0; +} + +int +sscomread(dev_t dev, struct uio *uio, int flag) +{ + struct sscom_softc *sc = device_lookup_private(&sscom_cd, SSCOMUNIT(dev)); + struct tty *tp = sc->sc_tty; + + if (SSCOM_ISALIVE(sc) == 0) + return EIO; + + return (*tp->t_linesw->l_read)(tp, uio, flag); +} + +int +sscomwrite(dev_t dev, struct uio *uio, int flag) +{ + struct sscom_softc *sc = device_lookup_private(&sscom_cd, SSCOMUNIT(dev)); + struct tty *tp = sc->sc_tty; + + if (SSCOM_ISALIVE(sc) == 0) + return EIO; + + return (*tp->t_linesw->l_write)(tp, uio, flag); +} + +int +sscompoll(dev_t dev, int events, struct lwp *l) +{ + struct sscom_softc *sc = device_lookup_private(&sscom_cd, SSCOMUNIT(dev)); + struct tty *tp = sc->sc_tty; + + if (SSCOM_ISALIVE(sc) == 0) + return EIO; + + return (*tp->t_linesw->l_poll)(tp, events, l); +} + +struct tty * +sscomtty(dev_t dev) +{ + struct sscom_softc *sc = device_lookup_private(&sscom_cd, SSCOMUNIT(dev)); + struct tty *tp = sc->sc_tty; + + return tp; +} + +int +sscomioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) +{ + struct sscom_softc *sc = device_lookup_private(&sscom_cd, SSCOMUNIT(dev)); + struct tty *tp = sc->sc_tty; + int error; + int s; + + if (SSCOM_ISALIVE(sc) == 0) + return EIO; + + error = (*tp->t_linesw->l_ioctl)(tp, cmd, data, flag, l); + if (error != EPASSTHROUGH) + return error; + + error = ttioctl(tp, cmd, data, flag, l); + if (error != EPASSTHROUGH) + return error; + + error = 0; + + s = splserial(); + SSCOM_LOCK(sc); + + switch (cmd) { + case TIOCSBRK: + sscom_break(sc, 1); + break; + + case TIOCCBRK: + sscom_break(sc, 0); + break; + + case TIOCSDTR: + sscom_modem(sc, 1); + break; + + case TIOCCDTR: + sscom_modem(sc, 0); + break; + + case TIOCGFLAGS: + *(int *)data = sc->sc_swflags; + break; + + case TIOCSFLAGS: + error = kauth_authorize_device_tty(l->l_cred, + KAUTH_DEVICE_TTY_PRIVSET, tp); + if (error) + break; + sc->sc_swflags = *(int *)data; + break; + + case TIOCMSET: + case TIOCMBIS: + case TIOCMBIC: + tiocm_to_sscom(sc, cmd, *(int *)data); + break; + + case TIOCMGET: + *(int *)data = sscom_to_tiocm(sc); + break; + + default: + error = EPASSTHROUGH; + break; + } + + SSCOM_UNLOCK(sc); + splx(s); + + if (sscom_debug) + sscomstatus(sc, "sscomioctl "); + + return error; +} + +integrate void +sscom_schedrx(struct sscom_softc *sc) +{ + + sc->sc_rx_ready = 1; + + /* Wake up the poller. */ + softint_schedule(sc->sc_si); +} + +static void +sscom_break(struct sscom_softc *sc, int onoff) +{ + + if (onoff) + SET(sc->sc_ucon, UCON_SBREAK); + else + CLR(sc->sc_ucon, UCON_SBREAK); + + if (!sc->sc_heldchange) { + if (sc->sc_tx_busy) { + sc->sc_heldtbc = sc->sc_tbc; + sc->sc_tbc = 0; + sc->sc_heldchange = 1; + } else + sscom_loadchannelregs(sc); + } +} + +static void +sscom_modem(struct sscom_softc *sc, int onoff) +{ + if (onoff) + SET(sc->sc_umcon, UMCON_DTR); + else + CLR(sc->sc_umcon, UMCON_DTR); + + if (!sc->sc_heldchange) { + if (sc->sc_tx_busy) { + sc->sc_heldtbc = sc->sc_tbc; + sc->sc_tbc = 0; + sc->sc_heldchange = 1; + } else + sscom_loadchannelregs(sc); + } +} + +static void +tiocm_to_sscom(struct sscom_softc *sc, u_long how, int ttybits) +{ + u_char sscombits; + + sscombits = 0; + if (ISSET(ttybits, TIOCM_DTR)) + sscombits = UMCON_DTR; + if (ISSET(ttybits, TIOCM_RTS)) + SET(sscombits, UMCON_RTS); + + switch (how) { + case TIOCMBIC: + CLR(sc->sc_umcon, sscombits); + break; + + case TIOCMBIS: + SET(sc->sc_umcon, sscombits); + break; + + case TIOCMSET: + CLR(sc->sc_umcon, UMCON_DTR); + SET(sc->sc_umcon, sscombits); + break; + } + + if (!sc->sc_heldchange) { + if (sc->sc_tx_busy) { + sc->sc_heldtbc = sc->sc_tbc; + sc->sc_tbc = 0; + sc->sc_heldchange = 1; + } else + sscom_loadchannelregs(sc); + } +} + +static int +sscom_to_tiocm(struct sscom_softc *sc) +{ + u_char sscombits; + int ttybits = 0; + + sscombits = sc->sc_umcon; +#if 0 + if (ISSET(sscombits, MCR_DTR)) + SET(ttybits, TIOCM_DTR); +#endif + if (ISSET(sscombits, UMCON_RTS)) + SET(ttybits, TIOCM_RTS); + + sscombits = sc->sc_msts; + if (ISSET(sscombits, MSTS_DCD)) + SET(ttybits, TIOCM_CD); + if (ISSET(sscombits, MSTS_DSR)) + SET(ttybits, TIOCM_DSR); + if (ISSET(sscombits, MSTS_CTS)) + SET(ttybits, TIOCM_CTS); + + if (sc->sc_ucon != 0) + SET(ttybits, TIOCM_LE); + + return ttybits; +} + +static int +cflag2lcr(tcflag_t cflag) +{ + u_char lcr = ULCON_PARITY_NONE; + + switch (cflag & (PARENB|PARODD)) { + case PARENB|PARODD: lcr = ULCON_PARITY_ODD; break; + case PARENB: lcr = ULCON_PARITY_EVEN; + } + + switch (ISSET(cflag, CSIZE)) { + case CS5: + SET(lcr, ULCON_LENGTH_5); + break; + case CS6: + SET(lcr, ULCON_LENGTH_6); + break; + case CS7: + SET(lcr, ULCON_LENGTH_7); + break; + case CS8: + SET(lcr, ULCON_LENGTH_8); + break; + } + if (ISSET(cflag, CSTOPB)) + SET(lcr, ULCON_STOP); + + return lcr; +} + +int +sscomparam(struct tty *tp, struct termios *t) +{ + struct sscom_softc *sc = device_lookup_private(&sscom_cd, SSCOMUNIT(tp->t_dev)); + int ospeed; + u_char lcr; + int s; + + if (SSCOM_ISALIVE(sc) == 0) + return EIO; + + ospeed = sscomspeed(t->c_ospeed, sc->sc_frequency); + + /* Check requested parameters. */ + if (ospeed < 0) + return EINVAL; + if (t->c_ispeed && t->c_ispeed != t->c_ospeed) + return EINVAL; + + /* + * For the console, always force CLOCAL and !HUPCL, so that the port + * is always active. + */ + if (ISSET(sc->sc_swflags, TIOCFLAG_SOFTCAR) || + ISSET(sc->sc_hwflags, SSCOM_HW_CONSOLE)) { + SET(t->c_cflag, CLOCAL); + CLR(t->c_cflag, HUPCL); + } + + /* + * If there were no changes, don't do anything. This avoids dropping + * input and improves performance when all we did was frob things like + * VMIN and VTIME. + */ + if (tp->t_ospeed == t->c_ospeed && + tp->t_cflag == t->c_cflag) + return 0; + + lcr = cflag2lcr(t->c_cflag); + + s = splserial(); + SSCOM_LOCK(sc); + + sc->sc_ulcon = lcr; + + /* + * If we're not in a mode that assumes a connection is present, then + * ignore carrier changes. + */ + if (ISSET(t->c_cflag, CLOCAL | MDMBUF)) + sc->sc_msr_dcd = 0; + else + sc->sc_msr_dcd = MSTS_DCD; + + /* + * Set the flow control pins depending on the current flow control + * mode. + */ + if (ISSET(t->c_cflag, CRTSCTS)) { + sc->sc_mcr_dtr = UMCON_DTR; + sc->sc_mcr_rts = UMCON_RTS; + sc->sc_msr_cts = MSTS_CTS; + } + else if (ISSET(t->c_cflag, MDMBUF)) { + /* + * For DTR/DCD flow control, make sure we don't toggle DTR for + * carrier detection. + */ + sc->sc_mcr_dtr = 0; + sc->sc_mcr_rts = UMCON_DTR; + sc->sc_msr_cts = MSTS_DCD; + } + else { + /* + * If no flow control, then always set RTS. This will make + * the other side happy if it mistakenly thinks we're doing + * RTS/CTS flow control. + */ + sc->sc_mcr_dtr = UMCON_DTR | UMCON_RTS; + sc->sc_mcr_rts = 0; + sc->sc_msr_cts = 0; + if (ISSET(sc->sc_umcon, UMCON_DTR)) + SET(sc->sc_umcon, UMCON_RTS); + else + CLR(sc->sc_umcon, UMCON_RTS); + } + sc->sc_msr_mask = sc->sc_msr_cts | sc->sc_msr_dcd; + + if (ospeed == 0) + CLR(sc->sc_umcon, sc->sc_mcr_dtr); + else + SET(sc->sc_umcon, sc->sc_mcr_dtr); + + sc->sc_ubrdiv = ospeed; + + /* And copy to tty. */ + tp->t_ispeed = 0; + tp->t_ospeed = t->c_ospeed; + tp->t_cflag = t->c_cflag; + + if (!sc->sc_heldchange) { + if (sc->sc_tx_busy) { + sc->sc_heldtbc = sc->sc_tbc; + sc->sc_tbc = 0; + sc->sc_heldchange = 1; + } else + sscom_loadchannelregs(sc); + } + + if (!ISSET(t->c_cflag, CHWFLOW)) { + /* Disable the high water mark. */ + sc->sc_r_hiwat = 0; + sc->sc_r_lowat = 0; + if (ISSET(sc->sc_rx_flags, RX_TTY_OVERFLOWED)) { + CLR(sc->sc_rx_flags, RX_TTY_OVERFLOWED); + sscom_schedrx(sc); + } + if (ISSET(sc->sc_rx_flags, RX_TTY_BLOCKED|RX_IBUF_BLOCKED)) { + CLR(sc->sc_rx_flags, RX_TTY_BLOCKED|RX_IBUF_BLOCKED); + sscom_hwiflow(sc); + } + } else { + sc->sc_r_hiwat = sscom_rbuf_hiwat; + sc->sc_r_lowat = sscom_rbuf_lowat; + } + + SSCOM_UNLOCK(sc); + splx(s); + + /* + * Update the tty layer's idea of the carrier bit, in case we changed + * CLOCAL or MDMBUF. We don't hang up here; we only do that by + * explicit request. + */ + (void) (*tp->t_linesw->l_modem)(tp, ISSET(sc->sc_msts, MSTS_DCD)); + + if (sscom_debug) + sscomstatus(sc, "sscomparam "); + + if (!ISSET(t->c_cflag, CHWFLOW)) { + if (sc->sc_tx_stopped) { + sc->sc_tx_stopped = 0; + sscomstart(tp); + } + } + + return 0; +} + +static void +sscom_iflush(struct sscom_softc *sc) +{ + bus_space_tag_t iot = sc->sc_iot; + bus_space_handle_t ioh = sc->sc_ioh; + int timo; + + + timo = 50000; + /* flush any pending I/O */ + while ( sscom_rxrdy(iot, ioh) && --timo) + (void)sscom_getc(iot,ioh); +#ifdef DIAGNOSTIC + if (!timo) + printf("%s: sscom_iflush timeout\n", device_xname(sc->sc_dev)); +#endif +} + +static void +sscom_loadchannelregs(struct sscom_softc *sc) +{ + bus_space_tag_t iot = sc->sc_iot; + bus_space_handle_t ioh = sc->sc_ioh; + + /* XXXXX necessary? */ + sscom_iflush(sc); + + bus_space_write_4(iot, ioh, SSCOM_UCON, 0); + +#if 0 + if (ISSET(sc->sc_hwflags, COM_HW_FLOW)) { + bus_space_write_1(iot, ioh, com_lcr, LCR_EERS); + bus_space_write_1(iot, ioh, com_efr, sc->sc_efr); + } +#endif + + bus_space_write_2(iot, ioh, SSCOM_UBRDIV, sc->sc_ubrdiv); + bus_space_write_1(iot, ioh, SSCOM_ULCON, sc->sc_ulcon); + sc->sc_set_modem_control(sc); + bus_space_write_4(iot, ioh, SSCOM_UCON, sc->sc_ucon); +} + +static int +sscomhwiflow(struct tty *tp, int block) +{ + struct sscom_softc *sc = device_lookup_private(&sscom_cd, SSCOMUNIT(tp->t_dev)); + int s; + + if (SSCOM_ISALIVE(sc) == 0) + return 0; + + if (sc->sc_mcr_rts == 0) + return 0; + + s = splserial(); + SSCOM_LOCK(sc); + + if (block) { + if (!ISSET(sc->sc_rx_flags, RX_TTY_BLOCKED)) { + SET(sc->sc_rx_flags, RX_TTY_BLOCKED); + sscom_hwiflow(sc); + } + } else { + if (ISSET(sc->sc_rx_flags, RX_TTY_OVERFLOWED)) { + CLR(sc->sc_rx_flags, RX_TTY_OVERFLOWED); + sscom_schedrx(sc); + } + if (ISSET(sc->sc_rx_flags, RX_TTY_BLOCKED)) { + CLR(sc->sc_rx_flags, RX_TTY_BLOCKED); + sscom_hwiflow(sc); + } + } + + SSCOM_UNLOCK(sc); + splx(s); + return 1; +} + +/* + * (un)block input via hw flowcontrol + */ +static void +sscom_hwiflow(struct sscom_softc *sc) +{ + if (sc->sc_mcr_rts == 0) + return; + + if (ISSET(sc->sc_rx_flags, RX_ANY_BLOCK)) { + CLR(sc->sc_umcon, sc->sc_mcr_rts); + CLR(sc->sc_mcr_active, sc->sc_mcr_rts); + } else { + SET(sc->sc_umcon, sc->sc_mcr_rts); + SET(sc->sc_mcr_active, sc->sc_mcr_rts); + } + sc->sc_set_modem_control(sc); +} + + +void +sscomstart(struct tty *tp) +{ + struct sscom_softc *sc = device_lookup_private(&sscom_cd, SSCOMUNIT(tp->t_dev)); + int s; + + if (SSCOM_ISALIVE(sc) == 0) + return; + + s = spltty(); + if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP)) + goto out; + if (sc->sc_tx_stopped) + goto out; + if (!ttypull(tp)) + goto out; + + /* Grab the first contiguous region of buffer space. */ + { + u_char *tba; + int tbc; + + tba = tp->t_outq.c_cf; + tbc = ndqb(&tp->t_outq, 0); + + (void)splserial(); + SSCOM_LOCK(sc); + + sc->sc_tba = tba; + sc->sc_tbc = tbc; + } + + SET(tp->t_state, TS_BUSY); + sc->sc_tx_busy = 1; + + /* Output the first chunk of the contiguous buffer. */ + sscom_output_chunk(sc); + + /* Enable transmit completion interrupts if necessary. */ + if ((sc->sc_hwflags & SSCOM_HW_TXINT) == 0) + sscom_enable_txint(sc); + + SSCOM_UNLOCK(sc); +out: + splx(s); + return; +} + +/* + * Stop output on a line. + */ +void +sscomstop(struct tty *tp, int flag) +{ + struct sscom_softc *sc = device_lookup_private(&sscom_cd, SSCOMUNIT(tp->t_dev)); + int s; + + s = splserial(); + SSCOM_LOCK(sc); + if (ISSET(tp->t_state, TS_BUSY)) { + /* Stop transmitting at the next chunk. */ + sc->sc_tbc = 0; + sc->sc_heldtbc = 0; + if (!ISSET(tp->t_state, TS_TTSTOP)) + SET(tp->t_state, TS_FLUSH); + } + SSCOM_UNLOCK(sc); + splx(s); +} + +void +sscomdiag(void *arg) +{ + struct sscom_softc *sc = arg; + int overflows, floods; + int s; + + s = splserial(); + SSCOM_LOCK(sc); + overflows = sc->sc_overflows; + sc->sc_overflows = 0; + floods = sc->sc_floods; + sc->sc_floods = 0; + sc->sc_errors = 0; + SSCOM_UNLOCK(sc); + splx(s); + + log(LOG_WARNING, "%s: %d silo overflow%s, %d ibuf flood%s\n", + device_xname(sc->sc_dev), + overflows, overflows == 1 ? "" : "s", + floods, floods == 1 ? "" : "s"); +} + +integrate void +sscom_rxsoft(struct sscom_softc *sc, struct tty *tp) +{ + int (*rint) (int, struct tty *) = tp->t_linesw->l_rint; + u_char *get, *end; + u_int cc, scc; + u_char rsr; + int code; + int s; + + end = sc->sc_ebuf; + get = sc->sc_rbget; + scc = cc = sscom_rbuf_size - sc->sc_rbavail; + + if (cc == sscom_rbuf_size) { + sc->sc_floods++; + if (sc->sc_errors++ == 0) + callout_reset(&sc->sc_diag_callout, 60 * hz, + sscomdiag, sc); + } + + while (cc) { + code = get[0]; + rsr = get[1]; + if (rsr) { + if (ISSET(rsr, UERSTAT_OVERRUN)) { + sc->sc_overflows++; + if (sc->sc_errors++ == 0) + callout_reset(&sc->sc_diag_callout, + 60 * hz, sscomdiag, sc); + } + if (ISSET(rsr, UERSTAT_BREAK | UERSTAT_FRAME)) + SET(code, TTY_FE); + if (ISSET(rsr, UERSTAT_PARITY)) + SET(code, TTY_PE); + } + if ((*rint)(code, tp) == -1) { + /* + * The line discipline's buffer is out of space. + */ + if (!ISSET(sc->sc_rx_flags, RX_TTY_BLOCKED)) { + /* + * We're either not using flow control, or the + * line discipline didn't tell us to block for + * some reason. Either way, we have no way to + * know when there's more space available, so + * just drop the rest of the data. + */ + get += cc << 1; + if (get >= end) + get -= sscom_rbuf_size << 1; + cc = 0; + } else { + /* + * Don't schedule any more receive processing + * until the line discipline tells us there's + * space available (through sscomhwiflow()). + * Leave the rest of the data in the input + * buffer. + */ + SET(sc->sc_rx_flags, RX_TTY_OVERFLOWED); + } + break; + } + get += 2; + if (get >= end) + get = sc->sc_rbuf; + cc--; + } + + if (cc != scc) { + sc->sc_rbget = get; + s = splserial(); + SSCOM_LOCK(sc); + + cc = sc->sc_rbavail += scc - cc; + /* Buffers should be ok again, release possible block. */ + if (cc >= sc->sc_r_lowat) { + if (ISSET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED)) { + CLR(sc->sc_rx_flags, RX_IBUF_OVERFLOWED); + sscom_enable_rxint(sc); + sc->sc_ucon |= UCON_ERRINT; + bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSCOM_UCON, + sc->sc_ucon); + + } + if (ISSET(sc->sc_rx_flags, RX_IBUF_BLOCKED)) { + CLR(sc->sc_rx_flags, RX_IBUF_BLOCKED); + sscom_hwiflow(sc); + } + } + SSCOM_UNLOCK(sc); + splx(s); + } +} + +integrate void +sscom_txsoft(struct sscom_softc *sc, struct tty *tp) +{ + + CLR(tp->t_state, TS_BUSY); + if (ISSET(tp->t_state, TS_FLUSH)) + CLR(tp->t_state, TS_FLUSH); + else + ndflush(&tp->t_outq, (int)(sc->sc_tba - tp->t_outq.c_cf)); + (*tp->t_linesw->l_start)(tp); +} + +integrate void +sscom_stsoft(struct sscom_softc *sc, struct tty *tp) +{ + u_char msr, delta; + int s; + + s = splserial(); + SSCOM_LOCK(sc); + msr = sc->sc_msts; + delta = sc->sc_msr_delta; + sc->sc_msr_delta = 0; + SSCOM_UNLOCK(sc); + splx(s); + + if (ISSET(delta, sc->sc_msr_dcd)) { + /* + * Inform the tty layer that carrier detect changed. + */ + (void) (*tp->t_linesw->l_modem)(tp, ISSET(msr, MSTS_DCD)); + } + + if (ISSET(delta, sc->sc_msr_cts)) { + /* Block or unblock output according to flow control. */ + if (ISSET(msr, sc->sc_msr_cts)) { + sc->sc_tx_stopped = 0; + (*tp->t_linesw->l_start)(tp); + } else { + sc->sc_tx_stopped = 1; + } + } + + if (sscom_debug) + sscomstatus(sc, "sscom_stsoft"); +} + +void +sscomsoft(void *arg) +{ + struct sscom_softc *sc = arg; + struct tty *tp; + + if (SSCOM_ISALIVE(sc) == 0) + return; + + { + tp = sc->sc_tty; + + if (sc->sc_rx_ready) { + sc->sc_rx_ready = 0; + sscom_rxsoft(sc, tp); + } + + if (sc->sc_st_check) { + sc->sc_st_check = 0; + sscom_stsoft(sc, tp); + } + + if (sc->sc_tx_done) { + sc->sc_tx_done = 0; + sscom_txsoft(sc, tp); + } + } +} + + +int +sscomrxintr(void *arg) +{ + struct sscom_softc *sc = arg; + bus_space_tag_t iot = sc->sc_iot; + bus_space_handle_t ioh = sc->sc_ioh; + u_char *put, *end; + u_int cc; + + if (SSCOM_ISALIVE(sc) == 0) + return 0; + + SSCOM_LOCK(sc); + + end = sc->sc_ebuf; + put = sc->sc_rbput; + cc = sc->sc_rbavail; + + do { + u_char msts, delta; + u_char uerstat; + uint32_t ufstat; + + ufstat = bus_space_read_4(iot, ioh, SSCOM_UFSTAT); + + /* XXX: break interrupt with no character? */ + + if ( (ufstat & (UFSTAT_RXCOUNT|UFSTAT_RXFULL)) && + !ISSET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED)) { + + while (cc > 0) { + int cn_trapped = 0; + + /* get status and received character. + read status register first */ + uerstat = sscom_geterr(iot, ioh); + put[0] = sscom_getc(iot, ioh); + + if (ISSET(uerstat, UERSTAT_BREAK)) { + int con_trapped = 0; + cn_check_magic(sc->sc_tty->t_dev, + CNC_BREAK, sscom_cnm_state); + if (con_trapped) + continue; +#if defined(KGDB) + if (ISSET(sc->sc_hwflags, + SSCOM_HW_KGDB)) { + kgdb_connect(1); + continue; + } +#endif + } + + put[1] = uerstat; + cn_check_magic(sc->sc_tty->t_dev, + put[0], sscom_cnm_state); + if (!cn_trapped) { + put += 2; + if (put >= end) + put = sc->sc_rbuf; + cc--; + } + + ufstat = bus_space_read_4(iot, ioh, SSCOM_UFSTAT); + if ( (ufstat & (UFSTAT_RXFULL|UFSTAT_RXCOUNT)) == 0 ) + break; + } + + /* + * Current string of incoming characters ended because + * no more data was available or we ran out of space. + * Schedule a receive event if any data was received. + * If we're out of space, turn off receive interrupts. + */ + sc->sc_rbput = put; + sc->sc_rbavail = cc; + if (!ISSET(sc->sc_rx_flags, RX_TTY_OVERFLOWED)) + sc->sc_rx_ready = 1; + + /* + * See if we are in danger of overflowing a buffer. If + * so, use hardware flow control to ease the pressure. + */ + if (!ISSET(sc->sc_rx_flags, RX_IBUF_BLOCKED) && + cc < sc->sc_r_hiwat) { + SET(sc->sc_rx_flags, RX_IBUF_BLOCKED); + sscom_hwiflow(sc); + } + + /* + * If we're out of space, disable receive interrupts + * until the queue has drained a bit. + */ + if (!cc) { + SET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED); + sscom_disable_rxint(sc); + sc->sc_ucon &= ~UCON_ERRINT; + bus_space_write_4(iot, ioh, SSCOM_UCON, sc->sc_ucon); + } + } + + + msts = sc->sc_read_modem_status(sc); + delta = msts ^ sc->sc_msts; + sc->sc_msts = msts; + +#ifdef notyet + /* + * Pulse-per-second (PSS) signals on edge of DCD? + * Process these even if line discipline is ignoring DCD. + */ + if (delta & sc->sc_ppsmask) { + struct timeval tv; + if ((msr & sc->sc_ppsmask) == sc->sc_ppsassert) { + /* XXX nanotime() */ + microtime(&tv); + TIMEVAL_TO_TIMESPEC(&tv, + &sc->ppsinfo.assert_timestamp); + if (sc->ppsparam.mode & PPS_OFFSETASSERT) { + timespecadd(&sc->ppsinfo.assert_timestamp, + &sc->ppsparam.assert_offset, + &sc->ppsinfo.assert_timestamp); + } + +#ifdef PPS_SYNC + if (sc->ppsparam.mode & PPS_HARDPPSONASSERT) + hardpps(&tv, tv.tv_usec); +#endif + sc->ppsinfo.assert_sequence++; + sc->ppsinfo.current_mode = sc->ppsparam.mode; + + } else if ((msr & sc->sc_ppsmask) == sc->sc_ppsclear) { + /* XXX nanotime() */ + microtime(&tv); + TIMEVAL_TO_TIMESPEC(&tv, + &sc->ppsinfo.clear_timestamp); + if (sc->ppsparam.mode & PPS_OFFSETCLEAR) { + timespecadd(&sc->ppsinfo.clear_timestamp, + &sc->ppsparam.clear_offset, + &sc->ppsinfo.clear_timestamp); + } + +#ifdef PPS_SYNC + if (sc->ppsparam.mode & PPS_HARDPPSONCLEAR) + hardpps(&tv, tv.tv_usec); +#endif + sc->ppsinfo.clear_sequence++; + sc->ppsinfo.current_mode = sc->ppsparam.mode; + } + } +#endif + + /* + * Process normal status changes + */ + if (ISSET(delta, sc->sc_msr_mask)) { + SET(sc->sc_msr_delta, delta); + + /* + * Stop output immediately if we lose the output + * flow control signal or carrier detect. + */ + if (ISSET(~msts, sc->sc_msr_mask)) { + sc->sc_tbc = 0; + sc->sc_heldtbc = 0; +#ifdef SSCOM_DEBUG + if (sscom_debug) + sscomstatus(sc, "sscomintr "); +#endif + } + + sc->sc_st_check = 1; + } + + /* + * Done handling any receive interrupts. + */ + + /* + * If we've delayed a parameter change, do it + * now, and restart * output. + */ + if ((ufstat & UFSTAT_TXCOUNT) == 0) { + /* XXX: we should check transmitter empty also */ + + if (sc->sc_heldchange) { + sscom_loadchannelregs(sc); + sc->sc_heldchange = 0; + sc->sc_tbc = sc->sc_heldtbc; + sc->sc_heldtbc = 0; + } + } + + + } while (0); + + SSCOM_UNLOCK(sc); + + /* Wake up the poller. */ + softint_schedule(sc->sc_si); + +#ifdef RND_COM + rnd_add_uint32(&sc->rnd_source, iir | rsr); +#endif + + return 1; +} + +int +sscomtxintr(void *arg) +{ + struct sscom_softc *sc = arg; + bus_space_tag_t iot = sc->sc_iot; + bus_space_handle_t ioh = sc->sc_ioh; + uint32_t ufstat; + + if (SSCOM_ISALIVE(sc) == 0) + return 0; + + SSCOM_LOCK(sc); + + ufstat = bus_space_read_4(iot, ioh, SSCOM_UFSTAT); + + /* + * If we've delayed a parameter change, do it + * now, and restart * output. + */ + if (sc->sc_heldchange && (ufstat & UFSTAT_TXCOUNT) == 0) { + /* XXX: we should check transmitter empty also */ + sscom_loadchannelregs(sc); + sc->sc_heldchange = 0; + sc->sc_tbc = sc->sc_heldtbc; + sc->sc_heldtbc = 0; + } + + /* + * See if data can be transmitted as well. Schedule tx + * done event if no data left and tty was marked busy. + */ + if (!ISSET(ufstat,UFSTAT_TXFULL)) { + /* + * Output the next chunk of the contiguous + * buffer, if any. + */ + if (sc->sc_tbc > 0) { + __sscom_output_chunk(sc, ufstat); + } + else { + /* + * Disable transmit sscompletion + * interrupts if necessary. + */ + if (sc->sc_hwflags & SSCOM_HW_TXINT) + sscom_disable_txint(sc); + if (sc->sc_tx_busy) { + sc->sc_tx_busy = 0; + sc->sc_tx_done = 1; + } + } + } + + SSCOM_UNLOCK(sc); + + /* Wake up the poller. */ + softint_schedule(sc->sc_si); + +#ifdef RND_COM + rnd_add_uint32(&sc->rnd_source, iir | rsr); +#endif + + return 1; +} + + +#if defined(KGDB) || defined(SSCOM0CONSOLE) || defined(SSCOM1CONSOLE) +/* + * Initialize UART for use as console or KGDB line. + */ +static int +sscom_init(bus_space_tag_t iot, const struct sscom_uart_info *config, + int rate, int frequency, tcflag_t cflag, bus_space_handle_t *iohp) +{ + bus_space_handle_t ioh; + bus_addr_t iobase = config->iobase; + int timo = 150000; + + if (bus_space_map(iot, iobase, SSCOM_SIZE, 0, &ioh)) + return ENOMEM; /* ??? */ + + /* wait until all is transmitted until we enable this device */ + while (!(bus_space_read_4(iot, ioh, SSCOM_UTRSTAT) & + UTRSTAT_TXSHIFTER_EMPTY) && --timo); + + /* reset UART control */ + bus_space_write_4(iot, ioh, SSCOM_UCON, 0); + + /* set RX/TX trigger to half values */ + bus_space_write_4(iot, ioh, SSCOM_UFCON, + (4<unit; + sscomconsrate = rate; + sscomconscflag = cflag; + + return 0; +} + +void +sscom_cndetach(void) +{ + bus_space_unmap(sscomconstag, sscomconsioh, SSCOM_SIZE); + sscomconstag = NULL; + + cn_tab = NULL; +} + +/* + * The read-ahead code is so that you can detect pending in-band + * cn_magic in polled mode while doing output rather than having to + * wait until the kernel decides it needs input. + */ + +#define MAX_READAHEAD 20 +static int sscom_readahead[MAX_READAHEAD]; +static int sscom_readaheadcount = 0; + +int +sscomcngetc(dev_t dev) +{ + int s = splserial(); + u_char __attribute__((__unused__)) stat; + u_char c; + + /* got a character from reading things earlier */ + if (sscom_readaheadcount > 0) { + int i; + + c = sscom_readahead[0]; + for (i = 1; i < sscom_readaheadcount; i++) { + sscom_readahead[i-1] = sscom_readahead[i]; + } + sscom_readaheadcount--; + splx(s); + return c; + } + + /* block until a character becomes available */ + while (!sscom_rxrdy(sscomconstag, sscomconsioh)) + ; + + c = sscom_getc(sscomconstag, sscomconsioh); + stat = sscom_geterr(sscomconstag, sscomconsioh); + { + int __attribute__((__unused__))cn_trapped = 0; +#ifdef DDB + extern int db_active; + if (!db_active) +#endif + cn_check_magic(dev, c, sscom_cnm_state); + } + splx(s); + return c; +} + +/* + * Console kernel output character routine. + */ +void +sscomcnputc(dev_t dev, int c) +{ + int s = splserial(); + int timo; + + int cin; + int __attribute__((__unused__)) stat; + if (sscom_readaheadcount < MAX_READAHEAD && + sscom_rxrdy(sscomconstag, sscomconsioh)) { + + int __attribute__((__unused__))cn_trapped = 0; + cin = sscom_getc(sscomconstag, sscomconsioh); + stat = sscom_geterr(sscomconstag, sscomconsioh); + cn_check_magic(dev, cin, sscom_cnm_state); + sscom_readahead[sscom_readaheadcount++] = cin; + } + + /* wait for any pending transmission to finish */ + timo = 150000; + while (ISSET(bus_space_read_4(sscomconstag, sscomconsioh, SSCOM_UFSTAT), + UFSTAT_TXFULL) && --timo) + continue; + + bus_space_write_1(sscomconstag, sscomconsioh, SSCOM_UTXH, c); + SSCOM_BARRIER(sscomconstag, sscomconsioh, BR | BW); + +#if 0 + /* wait for this transmission to complete */ + timo = 1500000; + while (!ISSET(bus_space_read_4(sscomconstag, sscomconsioh, SSCOM_UTRSTAT), + UTRSTAT_TXEMPTY) && --timo) + continue; +#endif + splx(s); +} + +void +sscomcnpollc(dev_t dev, int on) +{ + + sscom_readaheadcount = 0; +} + +#endif /* SSCOM0CONSOLE||SSCOM1CONSOLE */ + +#ifdef KGDB +int +sscom_kgdb_attach(bus_space_tag_t iot, const struct sscom_uart_info *config, + int rate, int frequency, tcflag_t cflag) +{ + int res; + + if (iot == sscomconstag && config->unit == sscomconsunit) { + printf( "console==kgdb_port (%d): kgdb disabled\n", sscomconsunit); + return EBUSY; /* cannot share with console */ + } + + res = sscom_init(iot, config, rate, frequency, cflag, &sscom_kgdb_ioh); + if (res) + return res; + + kgdb_attach(sscom_kgdb_getc, sscom_kgdb_putc, NULL); + kgdb_dev = 123; /* unneeded, only to satisfy some tests */ + + sscom_kgdb_iot = iot; + sscom_kgdb_unit = config->unit; + + return 0; +} + +/* ARGSUSED */ +int +sscom_kgdb_getc(void *arg) +{ + int c, stat; + + /* block until a character becomes available */ + while (!sscom_rxrdy(sscom_kgdb_iot, sscom_kgdb_ioh)) + ; + + c = sscom_getc(sscom_kgdb_iot, sscom_kgdb_ioh); + stat = sscom_geterr(sscom_kgdb_iot, sscom_kgdb_ioh); + + return c; +} + +/* ARGSUSED */ +void +sscom_kgdb_putc(void *arg, int c) +{ + int timo; + + /* wait for any pending transmission to finish */ + timo = 150000; + while (ISSET(bus_space_read_4(sscom_kgdb_iot, sscom_kgdb_ioh, + SSCOM_UFSTAT), UFSTAT_TXFULL) && --timo) + continue; + + bus_space_write_1(sscom_kgdb_iot, sscom_kgdb_ioh, SSCOM_UTXH, c); + SSCOM_BARRIER(sscom_kgdb_iot, sscom_kgdb_ioh, BR | BW); + +#if 0 + /* wait for this transmission to complete */ + timo = 1500000; + while (!ISSET(bus_space_read_4(sscom_kgdb_iot, sscom_kgdb_ioh, + SSCOM_UTRSTAT), UTRSTAT_TXEMPTY) && --timo) + continue; +#endif +} +#endif /* KGDB */ + +/* helper function to identify the sscom ports used by + console or KGDB (and not yet autoconf attached) */ +int +sscom_is_console(bus_space_tag_t iot, int unit, + bus_space_handle_t *ioh) +{ + bus_space_handle_t help; + + if (!sscomconsattached && + iot == sscomconstag && unit == sscomconsunit) + help = sscomconsioh; +#ifdef KGDB + else if (!sscom_kgdb_attached && + iot == sscom_kgdb_iot && unit == sscom_kgdb_unit) + help = sscom_kgdb_ioh; +#endif + else + return 0; + + if (ioh) + *ioh = help; + return 1; +} + Index: sys/arch/arm/samsung/sscom_reg.h =================================================================== RCS file: sys/arch/arm/samsung/sscom_reg.h diff -N sys/arch/arm/samsung/sscom_reg.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arch/arm/samsung/sscom_reg.h 11 Apr 2014 15:32:43 -0000 @@ -0,0 +1,156 @@ +/* $NetBSD: s3c2xx0reg.h,v 1.6 2010/02/21 06:08:53 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. + */ + + +/* + * Register definitions for the Exynos[45] chipsets UARTs + */ +#ifndef _ARM_SAMSUNG_SSCOM_REG_H_ +#define _ARM_SAMSUNG_SSCOM_REG_H_ + + +#define SSCOM_ULCON 0x00 /* UART line control */ +#define ULCON_IR (1<<6) +#define ULCON_PARITY_SHIFT 3 +#define ULCON_PARITY_NONE (0< +#include +#include +#include +#include +#include + +#include + +/* 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 + +struct sscom_softc { + device_t sc_dev; + void *sc_si; + struct tty *sc_tty; + + struct callout sc_diag_callout; + + int sc_unit; /* UART0/UART1 */ + int sc_frequency; + + bus_space_tag_t sc_iot; + bus_space_handle_t sc_ioh; + + u_int sc_overflows, + sc_floods, + sc_errors; + + int sc_hwflags, + sc_swflags; + + u_int sc_r_hiwat, + sc_r_lowat; + u_char *volatile sc_rbget, + *volatile sc_rbput; + volatile u_int sc_rbavail; + u_char *sc_rbuf, + *sc_ebuf; + + u_char *sc_tba; + u_int sc_tbc, + sc_heldtbc; + + volatile u_char sc_rx_flags, +#define RX_TTY_BLOCKED 0x01 +#define RX_TTY_OVERFLOWED 0x02 +#define RX_IBUF_BLOCKED 0x04 +#define RX_IBUF_OVERFLOWED 0x08 +#define RX_ANY_BLOCK 0x0f + sc_tx_busy, + sc_tx_done, + sc_tx_stopped, + sc_st_check, + sc_rx_ready; + + /* data to stored in UART registers. + actual write to UART register is pended while sc_tx_busy */ + uint32_t sc_ucon; /* control register */ + uint16_t sc_ubrdiv; /* baudrate register */ + uint32_t sc_heldchange; /* register changes are pended */ + uint32_t sc_ulcon; /* line control */ + uint32_t sc_umcon; /* modem control */ +#define UMCON_HW_MASK (UMCON_RTS) +#define UMCON_DTR (1<<4) /* provided by other means such as GPIO */ + uint8_t sc_msts; /* modem status */ +#define MSTS_CTS UMSTAT_CTS /* bit0 */ +#define MSTS_DCD (1<<1) +#define MSTS_DSR (1<<2) + + uint8_t sc_msr_dcd; /* DCD or 0 */ + uint8_t sc_mcr_dtr; /* DTR or 0 or DTR|RTS*/ + uint8_t sc_mcr_rts; /* RTS or DTR in sc_umcon */ + uint8_t sc_msr_cts; /* CTS or DCD in sc_msts */ + + uint8_t sc_msr_mask; /* sc_msr_cts|sc_msr_dcd */ + uint8_t sc_mcr_active; + uint8_t sc_msr_delta; + + uint8_t sc_rx_irqno, sc_tx_irqno; + +#if 0 + /* PPS signal on DCD, with or without inkernel clock disciplining */ + u_char sc_ppsmask; /* pps signal mask */ + u_char sc_ppsassert; /* pps leading edge */ + u_char sc_ppsclear; /* pps trailing edge */ + pps_info_t ppsinfo; + pps_params_t ppsparam; +#endif + +#ifdef RND_COM + krndsource_t sc_rnd_source; +#endif +#if (defined(MULTIPROCESSOR) || defined(LOCKDEBUG)) && defined(SSCOM_MPLOCK) + kmutex_t sc_lock; +#endif + + /* + * S3C2XX0's UART doesn't have modem control/status pins. + * On platforms with S3C2XX0, those pins are simply unavailable + * or provided by other means such as GPIO. Platform specific attach routine + * have to provide functions to read/write modem control/status pins. + */ + int (*sc_read_modem_status)( struct sscom_softc * ); + void (*sc_set_modem_control)( struct sscom_softc * ); + void (*sc_change_txrx_interrupts)(struct sscom_softc *, bool, u_int); +}; + +/* UART register address, etc. */ +struct sscom_uart_info { + int unit; + char tx_int, rx_int, err_int; + bus_addr_t iobase; +}; + +#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) + +#define sscom_mask_rxint(sc) \ + (*(sc)->sc_change_txrx_interrupts)((sc), false, SSCOM_HW_RXINT) +#define sscom_unmask_rxint(sc) \ + (*(sc)->sc_change_txrx_interrupts)((sc), true, SSCOM_HW_RXINT) +#define sscom_mask_txint(sc) \ + (*(sc)->sc_change_txrx_interrupts)((sc), false, SSCOM_HW_TXINT) +#define sscom_unmask_txint(sc) \ + (*(sc)->sc_change_txrx_interrupts)((sc), true, SSCOM_HW_TXINT) +#define sscom_mask_txrxint(sc) \ + (*(sc)->sc_change_txrx_interrupts)((sc), false, \ + SSCOM_HW_RXINT | SSCOM_HW_TXINT) +#define sscom_unmask_txrxint(sc) \ + (*(sc)->sc_change_txrx_interrupts)((sc), true, \ + SSCOM_HW_RXINT | SSCOM_HW_TXINT) + +#define sscom_enable_rxint(sc) \ + (sscom_unmask_rxint(sc), ((sc)->sc_hwflags |= SSCOM_HW_RXINT)) +#define sscom_disable_rxint(sc) \ + (sscom_mask_rxint(sc), ((sc)->sc_hwflags &= ~SSCOM_HW_RXINT)) +#define sscom_enable_txint(sc) \ + (sscom_unmask_txint(sc), ((sc)->sc_hwflags |= SSCOM_HW_TXINT)) +#define sscom_disable_txint(sc) \ + (sscom_mask_txint(sc),((sc)->sc_hwflags &= ~SSCOM_HW_TXINT)) +#define sscom_enable_txrxint(sc) \ + (sscom_unmask_txrxint(sc),((sc)->sc_hwflags |= (SSCOM_HW_TXINT|SSCOM_HW_RXINT))) +#define sscom_disable_txrxint(sc) \ + (sscom_mask_txrxint(sc),((sc)->sc_hwflags &= ~(SSCOM_HW_TXINT|SSCOM_HW_RXINT))) + + +int sscomspeed(long, long); +void sscom_attach_subr(struct sscom_softc *); + +int sscom_detach(device_t, int); +int sscom_activate(device_t, enum devact); +void sscom_shutdown(struct sscom_softc *); +void sscomdiag(void *); +void sscomstart(struct tty *); +int sscomparam(struct tty *, struct termios *); +int sscomread(dev_t, struct uio *, int); +void sscom_config(struct sscom_softc *); + +int sscomtxintr(void *); +int sscomrxintr(void *); + +int sscom_cnattach(bus_space_tag_t, const struct sscom_uart_info *, + int, int, tcflag_t); +void sscom_cndetach(void); +int sscom_is_console(bus_space_tag_t, int, bus_space_handle_t *); + +#ifdef KGDB +int sscom_kgdb_attach(bus_space_tag_t, const struct sscom_uart_info *, + int, int, tcflag_t); +#endif + +#endif /* _ARM_SAMSUNG_SSCOM_VAR_H */ + Index: sys/arch/evbarm/conf/ODROID =================================================================== RCS file: sys/arch/evbarm/conf/ODROID diff -N sys/arch/evbarm/conf/ODROID --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arch/evbarm/conf/ODROID 11 Apr 2014 15:32:44 -0000 @@ -0,0 +1,237 @@ +# +# $NetBSD$ +# +# ODROID -- ODROID series Exynos Kernel +# + +include "arch/evbarm/conf/std.odroid" + +# estimated number of users + +maxusers 32 + +# Standard system options + +options RTC_OFFSET=0 # hardware clock is this many mins. west of GMT +#options NTP # NTP phase/frequency locked loop + +# CPU options +options CPU_CORTEX +options CPU_CORTEXA9 +options EXYNOS4120 +options EXYNOS4212 +options EXYNOS4412 +options EXYNOS4412P +options EXYNOS5260 +options EXYNOS5410 +options EXYNOS5420 +options EXYNOS5440 +options EXYNOS5422 +#options MULTIPROCESSOR +options PMAPCOUNTERS +options BUSDMA_COUNTERS +options EXYNOS_CONSOLE_EARLY + +# Specify the memory size in megabytes (optional). +#options MEMSIZE=2048 + +# File systems +file-system FFS # UFS +#file-system LFS # log-structured file system +file-system MFS # memory file system +file-system NFS # Network file system +#file-system ADOSFS # AmigaDOS-compatible file system +#file-system EXT2FS # second extended file system (linux) +#file-system CD9660 # ISO 9660 + Rock Ridge file system +file-system MSDOSFS # MS-DOS file system +#file-system FDESC # /dev/fd +file-system KERNFS # /kern +#file-system NULLFS # loopback file system +file-system PROCFS # /proc +#file-system PUFFS # Userspace file systems (e.g. ntfs-3g & sshfs) +#file-system UMAPFS # NULLFS + uid and gid remapping +#file-system UNION # union file system +file-system TMPFS # memory file system +file-system PTYFS # /dev/pts/N support + +# File system options +#options QUOTA # legacy UFS quotas +#options QUOTA2 # new, in-filesystem UFS quotas +#options FFS_EI # FFS Endian Independent support +#options NFSSERVER +options WAPBL # File system journaling support +#options FFS_NO_SNAPSHOT # No FFS snapshot support + +# Networking options + +#options GATEWAY # packet forwarding +options INET # IP + ICMP + TCP + UDP +options INET6 # IPV6 +#options IPSEC # IP security +#options IPSEC_DEBUG # debug for IP security +#options MROUTING # IP multicast routing +#options PIM # Protocol Independent Multicast +#options NETATALK # AppleTalk networking +#options PPP_BSDCOMP # BSD-Compress compression support for PPP +#options PPP_DEFLATE # Deflate compression support for PPP +#options PPP_FILTER # Active filter support for PPP (requires bpf) +#options TCP_DEBUG # Record last TCP_NDEBUG packets with SO_DEBUG + +options NFS_BOOT_BOOTP +options NFS_BOOT_DHCP +#options NFS_BOOT_BOOTSTATIC +#options NFS_BOOTSTATIC_MYIP="\"192.168.1.4\"" +#options NFS_BOOTSTATIC_GWIP="\"192.168.1.1\"" +#options NFS_BOOTSTATIC_MASK="\"255.255.255.0\"" +#options NFS_BOOTSTATIC_SERVADDR="\"192.168.1.1\"" +#options NFS_BOOTSTATIC_SERVER="\"192.168.1.1:/nfs/sdp2430\"" + +options NFS_BOOT_RWSIZE=1024 + +# Compatibility options + +#options COMPAT_43 # 4.3BSD compatibility. +options COMPAT_60 # NetBSD 6.0 compatibility. +options COMPAT_50 # NetBSD 5.0 compatibility. +options COMPAT_40 # NetBSD 4.0 compatibility. +options COMPAT_30 # NetBSD 3.0 compatibility. +#options COMPAT_20 # NetBSD 2.0 compatibility. +#options COMPAT_16 # NetBSD 1.6 compatibility. +#options COMPAT_15 # NetBSD 1.5 compatibility. +#options COMPAT_14 # NetBSD 1.4 compatibility. +#options COMPAT_13 # NetBSD 1.3 compatibility. +#options COMPAT_12 # NetBSD 1.2 compatibility. +#options COMPAT_11 # NetBSD 1.1 compatibility. +#options COMPAT_10 # NetBSD 1.0 compatibility. +#options COMPAT_09 # NetBSD 0.9 compatibility. +#options TCP_COMPAT_42 # 4.2BSD TCP/IP bug compat. Not recommended. +#options COMPAT_BSDPTY # /dev/[pt]ty?? ptys. + +# Shared memory options + +options SYSVMSG # System V-like message queues +options SYSVSEM # System V-like semaphores +options SYSVSHM # System V-like memory sharing + +# Device options + +#options MEMORY_DISK_HOOKS # boottime setup of ramdisk +#options MEMORY_DISK_ROOT_SIZE=8192 # Size in blocks +#options MEMORY_DISK_DYNAMIC +#options MINIROOTSIZE=1000 # Size in blocks +#options MEMORY_DISK_IS_ROOT # use memory disk as root + +options DKWEDGE_AUTODISCOVER +options DKWEDGE_METHOD_GPT + +# Miscellaneous kernel options +options KTRACE # system call tracing, a la ktrace(1) +#options KMEMSTATS # kernel memory statistics +#options SCSIVERBOSE # Verbose SCSI errors +#options MIIVERBOSE # Verbose MII autoconfuration messages +#options DDB_KEYCODE=0x40 +#options USERCONF # userconf(4) support +#options PIPE_SOCKETPAIR # smaller, but slower pipe(2) + +# Development and Debugging options + +#options PERFCTRS # performance counters +options DIAGNOSTIC # internally consistency checks +options DEBUG +#options PMAP_DEBUG # Enable pmap_debug_level code +#options IPKDB # remote kernel debugging +options VERBOSE_INIT_ARM # verbose bootstraping messages +options DDB # in-kernel debugger +options DDB_ONPANIC=1 +options DDB_HISTORY_SIZE=100 # Enable history editing in DDB +#options KGDB +makeoptions DEBUG="-g" # compile full symbol table +options SYMTAB_SPACE=800000 + +## USB Debugging options +options USB_DEBUG +options EHCI_DEBUG +options OHCI_DEBUG +options UHUB_DEBUG + + +# Valid options for BOOT_ARGS: +# single Boot to single user only +# kdb Give control to kernel debugger +# ask Ask for file name to reboot from +# memorydisk= Set memorydisk size to KB +# quiet Show aprint_naive output +# verbose Show aprint_normal and aprint_verbose output +#options BOOT_ARGS="\"\"" + +config netbsd root on ? type ? + +# The main bus device +mainbus0 at root + +# The boot cpu and secondary CPUs +cpu0 at mainbus? +#cpu? at mainbus? # Multiprocessor + +# A9 core devices +armperiph0 at mainbus? +arml2cc0 at armperiph? # L2 Cache Controller +armgic0 at armperiph? # Interrupt Controller + +# Exynos SoC +exyo0 at mainbus? + +# Integrated Samsung devices +mct0 at exyo0 + +# Integrated Samsung UARTs +sscom0 at exyo0 port 0 # UART0 +sscom1 at exyo0 port 1 # UART1 +sscom2 at exyo0 port 2 # UART2 +sscom3 at exyo0 port 3 # UART3 +sscom4 at exyo0 port 4 # UART4 (GPS) + + +# Odroid-U connectivity + +# UARTS +# sscom0 attached to expansion port +# sscom1 is default serial UART console, enable for low-level console: +options SSCOM0CONSOLE, CONSPEED=115200 +# On-board USB +#exyousb0 at exyo0 port 0 +#exyousb1 at exyo0 port 1 +#ohci* at exyousb? +#ehci* at exyousb? +#usb* at ohci? +#usb* at ehci? + +# SATA +#ahcisata* at exyno0 +#atabus* at ata? +#wd* at atabus? drive ? + +#include "dev/usb/usbdevices.config" + + +# Pseudo-Devices + +# disk/mass storage pseudo-devices +#pseudo-device md # memory disk device (ramdisk) +#pseudo-device vnd # disk-like interface to files +#pseudo-device fss # file system snapshot device +#pseudo-device putter # for puffs and pud +pseudo-device drvctl # driver control + +# network pseudo-devices +pseudo-device bpfilter # Berkeley packet filter +pseudo-device loop # network loopback +#pseudo-device kttcp # network loopback + +# miscellaneous pseudo-devices +pseudo-device pty # pseudo-terminals +#options RND_COM +#pseudo-device clockctl # user control of clock subsystem +pseudo-device ksyms # /dev/ksyms +#pseudo-device lockstat # lock profiling + Index: sys/arch/evbarm/conf/files.odroid =================================================================== RCS file: sys/arch/evbarm/conf/files.odroid diff -N sys/arch/evbarm/conf/files.odroid --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arch/evbarm/conf/files.odroid 11 Apr 2014 15:32:44 -0000 @@ -0,0 +1,12 @@ +# $NetBSD$ +# +# ODROID evaluation board configuration info +# + +file arch/evbarm/odroid/odroid_machdep.c + +# Kernel boot arguments +defparam opt_machdep.h BOOT_ARGS + +# Pull in Exynos SoC default +include "arch/arm/samsung/files.exynos" Index: sys/arch/evbarm/conf/mk.odroid =================================================================== RCS file: sys/arch/evbarm/conf/mk.odroid diff -N sys/arch/evbarm/conf/mk.odroid --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arch/evbarm/conf/mk.odroid 11 Apr 2014 15:32:44 -0000 @@ -0,0 +1,37 @@ +# $NetBSD: mk.cubie,v 1.3 2014/01/30 00:07:35 matt Exp $ + +.if !empty(MACHINE_ARCH:M*eb) +EXTRA_LINKFLAGS+= --be8 +.endif + +SYSTEM_FIRST_OBJ= odroid_start.o +SYSTEM_FIRST_SFILE= ${THISARM}/odroid/odroid_start.S + +GENASSYM_EXTRAS+= ${THISARM}/odroid/genassym.cf + +_OSRELEASE!= ${HOST_SH} $S/conf/osrelease.sh + +KERNEL_BASE_PHYS?=$(LOADADDRESS) +KERNEL_BASE_VIRT?=$(LOADADDRESS) + +MKUBOOTIMAGEARGS= -A arm -T kernel +MKUBOOTIMAGEARGS+= -a $(KERNEL_BASE_PHYS) -e $(KERNEL_BASE_PHYS) +MKUBOOTIMAGEARGS+= -n "NetBSD/$(BOARDTYPE) ${_OSRELEASE}" +MKUBOOTIMAGEARGS_NONE= ${MKUBOOTIMAGEARGS} -C none +MKUBOOTIMAGEARGS_GZ= ${MKUBOOTIMAGEARGS} -C gz + +SYSTEM_LD_TAIL_EXTRA+=; \ + echo ${OBJCOPY} -S -O binary $@ $@.bin; \ + ${OBJCOPY} -S -O binary $@ $@.bin; \ + echo ${TOOL_GZIP} -9c $@.bin > $@.bin.gz; \ + ${TOOL_GZIP} -9c $@.bin > $@.bin.gz; \ + echo ${TOOL_MKUBOOTIMAGE} ${MKUBOOTIMAGEARGS_GZ} $@.bin.gz $@.gz.ub; \ + ${TOOL_MKUBOOTIMAGE} ${MKUBOOTIMAGEARGS_GZ} $@.bin.gz $@.gz.ub; \ + echo ${TOOL_MKUBOOTIMAGE} ${MKUBOOTIMAGEARGS_NONE} $@.bin $@.ub; \ + ${TOOL_MKUBOOTIMAGE} ${MKUBOOTIMAGEARGS_NONE} $@.bin $@.ub; \ + echo + +EXTRA_KERNELS+= ${KERNELS:@.KERNEL.@${.KERNEL.}.bin@} +EXTRA_KERNELS+= ${KERNELS:@.KERNEL.@${.KERNEL.}.ub@} +EXTRA_KERNELS+= ${KERNELS:@.KERNEL.@${.KERNEL.}.bin.gz@} +EXTRA_KERNELS+= ${KERNELS:@.KERNEL.@${.KERNEL.}.gz.ub@} Index: sys/arch/evbarm/conf/std.odroid =================================================================== RCS file: sys/arch/evbarm/conf/std.odroid diff -N sys/arch/evbarm/conf/std.odroid --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arch/evbarm/conf/std.odroid 11 Apr 2014 15:32:44 -0000 @@ -0,0 +1,31 @@ +# $NetBSD$ +# +# standard NetBSD/evbarm for ODROID options + +machine evbarm arm +include "arch/evbarm/conf/std.evbarm" + +# Pull in ODROID config definitions +include "arch/evbarm/conf/files.odroid" + +#makeoptions CPUFLAGS="-mcpu=cortex-a9 -mfpu=neon" + +# To support easy transit to ../arch/arm/arm32 +options MODULAR +options ARM_HAS_VBAR +options CORTEX_PMC +options __HAVE_CPU_COUNTER +options __HAVE_FAST_SOFTINTS # should be in types.h +#options __HAVE_MM_MD_DIRECT_MAPPED_PHYS +options TPIDRPRW_IS_CURCPU +options KERNEL_BASE_EXT=0x80000000 +options FPU_VFP +options ARM_TRUSTZONE_FIRMWARE + +makeoptions KERNEL_BASE_PHYS="0x80000000" +makeoptions KERNEL_BASE_VIRT="0x80000000" +makeoptions BOARDTYPE="odroid" +makeoptions BOARDMKFRAG="${THISARM}/conf/mk.odroid" + +options ARM_INTR_IMPL="" +options ARM_GENERIC_TODR Index: sys/arch/evbarm/odroid/genassym.cf =================================================================== RCS file: sys/arch/evbarm/odroid/genassym.cf diff -N sys/arch/evbarm/odroid/genassym.cf --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arch/evbarm/odroid/genassym.cf 11 Apr 2014 15:32:45 -0000 @@ -0,0 +1,38 @@ +# $NetBSD: genassym.cf,v 1.1 2013/09/03 18:01:33 matt Exp $ + +#- +# Copyright (c) 2013 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Matt Thomas of 3am Software Foundry. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this 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 + +define LSR_TXRDY UTRSTAT_TXEMPTY +define LSR_TSRE UTRSTAT_TXSHIFTER_EMPTY +define COM_DATA SSCOM_UTXH +define COM_LSR SSCOM_UERSTAT + Index: sys/arch/evbarm/odroid/odroid_machdep.c =================================================================== RCS file: sys/arch/evbarm/odroid/odroid_machdep.c diff -N sys/arch/evbarm/odroid/odroid_machdep.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arch/evbarm/odroid/odroid_machdep.c 11 Apr 2014 15:32:45 -0000 @@ -0,0 +1,446 @@ +/* $NetBSD$ */ + +/* + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Reinoud Zandijk. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this 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 +__KERNEL_RCSID(0, "$NetBSD$"); + +#include "opt_evbarm_boardtype.h" +#include "opt_exynos.h" +#include "opt_machdep.h" +#include "opt_ddb.h" +#include "opt_kgdb.h" +#include "opt_ipkdb.h" +#include "opt_md.h" +#include "opt_sscom.h" +#include "opt_arm_debug.h" + +#include "ukbd.h" +#include "arml2cc.h" // RPZ why is it not called opt_l2cc.h? + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include +#ifdef KGDB +#include +#endif + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include + +#include + +/* serial console stuff */ +#include "sscom.h" +#include "opt_sscom.h" + +#if defined(KGDB) || \ + defined(SSCOM0CONSOLE) || defined(SSCOM1CONSOLE) || \ + defined(SSCOM2CONSOLE) || defined(SSCOM3CONSOLE) +#if NSSCOM == 0 +#error must define sscom for use with serial console or KGD +#endif + +#include +#include + +#if 0 +static struct sscom_uart_info exyuarts = { + { + .unit = 0, + .tx_int = 0, /* XXX */ + .rx_int = 0, /* XXX */ + .err_int = 0, /* XXX */ + .iobase = EXYNOS5_CORE_PBASE + EXYNOS5_UART2_OFFSET + }, + { + .unit = 1, + .tx_int = 0, /* XXX */ + .rx_int = 0, /* XXX */ + .err_int = 0, /* XXX */ + .iobase = EXYNOS_CORE_PBASE + EXYNOS_UART1_OFFSET + }, + { + .unit = 1, + .tx_int = 0, /* XXX */ + .rx_int = 0, /* XXX */ + .err_int = 0, /* XXX */ + .iobase = EXYNOS_CORE_PBASE + EXYNOS_UART2_OFFSET + }, + { + .unit = 1, + .tx_int = 0, /* XXX */ + .rx_int = 0, /* XXX */ + .err_int = 0, /* XXX */ + .iobase = EXYNOS_CORE_PBASE + EXYNOS_UART3_OFFSET + }, +}; +#endif + + +/* sanity checks for serial console */ +#ifndef CONSPEED +#define CONSPEED 115200 +#endif /* CONSPEED */ +#ifndef CONMODE +#define CONMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB | HUPCL)) | CS8) /* 8N1 */ +#endif /* CONMODE */ + +// __CTASSERT(EXYNOS_CORE_PBASE + EXYNOS_UART0_OFFSET <= CONADDR); +// __CTASSERT(CONADDR <= EXYNOS_CORE_PBASE + EXYNOS_UART4_OFFSET); +// __CTASSERT(CONADDR % EXYNOS_BLOCK_SIZE == 0); +static const bus_addr_t conaddr = CONADDR; +static const int conspeed = CONSPEED; +static const int conmode = CONMODE; +#endif /*defined(KGDB) || defined(SSCOM0CONSOLE) || defined(SSCOM1CONSOLE) */ + + +/* + * Macros to translate between physical and virtual for a subset of the + * kernel address space. *Not* for general use. + */ +extern char KERNEL_BASE_phys[]; /* physical start of kernel */ +extern char KERNEL_BASE_virt[]; /* virtual start of kernel */ + +#define KERNEL_BASE_PHYS ((paddr_t)KERNEL_BASE_phys) + +#define KERN_VTOPDIFF ((vaddr_t)KERNEL_BASE_phys - (vaddr_t)KERNEL_BASE_virt) +#define KERN_VTOPHYS(va) ((paddr_t)((vaddr_t)va + KERN_VTOPDIFF)) +#define KERN_PHYSTOV(pa) ((vaddr_t)((paddr_t)pa - KERN_VTOPDIFF)) + +#define KERN_PHYSTOV(pa) ((vaddr_t)((paddr_t)pa - KERN_VTOPDIFF)) +#define EXYNOS_IOPHYSTOVIRT(a) \ + ((vaddr_t)(((a) - EXYNOS_CORE_PBASE) + EXYNOS_CORE_VBASE)) + +/* + * odroid_start determines the uart_physical address based on SoC type + */ +extern paddr_t uart_address; + +/* + * uboot passes 4 arguments to us. + * + * arg0 arg1 arg2 arg3 : the `bootargs' environment variable from the uboot + * context (in PA!) + * + * Note that the storage has to be in .data and not in .bss. On kernel start + * the .bss is cleared and this information would get lost. + */ +uintptr_t uboot_args[4] = { 0 }; + + +/* + * argument and boot configure storage + */ +BootConfig bootconfig; /* for pmap's sake */ +//static char bootargs[MAX_BOOT_STRING]; /* copied string from uboot */ +char *boot_args = NULL; /* MI bootargs */ +char *boot_file = NULL; /* MI bootfile */ + + +/* + * kernel start and end from the linker + */ +extern char KERNEL_BASE_phys[]; /* physical start of kernel */ +extern char _end[]; /* physical end of kernel */ + + +/* XXX we have no framebuffer implementation yet so com is console XXX */ +int use_fb_console = false; + + +/* prototypes */ +void consinit(void); +#ifdef KGDB +static void kgdb_port_init(void); +#endif +void odroid_device_register(device_t self, void *aux); + + +/* + * Our static device mappings at fixed virtual addresses so we can use them + * while booting the kernel. + * + * Map the extents segment-aligned and segment-rounded in size to avoid L2 + * page tables + */ + +#define _A(a) ((a) & ~L1_S_OFFSET) +#define _S(s) (((s) + L1_S_SIZE - 1) & (~(L1_S_SIZE-1))) + +static const struct pmap_devmap e4_devmap[] = { + { + /* map in core IO space */ + .pd_va = _A(EXYNOS_CORE_VBASE), + .pd_pa = _A(EXYNOS_CORE_PBASE), + .pd_size = _S(EXYNOS4_CORE_SIZE), + .pd_prot = VM_PROT_READ | VM_PROT_WRITE, + .pd_cache = PTE_NOCACHE + }, + {0} +}; + +static const struct pmap_devmap e5_devmap[] = { + { + /* map in core IO space */ + .pd_va = _A(EXYNOS_CORE_VBASE), + .pd_pa = _A(EXYNOS_CORE_PBASE), + .pd_size = _S(EXYNOS5_CORE_SIZE), + .pd_prot = VM_PROT_READ | VM_PROT_WRITE, + .pd_cache = PTE_NOCACHE + }, + {0} +}; +#undef _A +#undef _S + +/* + * u_int initarm(...) + * + * Our entry point from the assembly before main() is called. + * - take a copy of the config we got from uboot + * - init the physical console + * - setting up page tables for the kernel + */ + +u_int +initarm(void *arg) +{ + const struct pmap_devmap const *devmap; + bus_addr_t rambase; + + /* allocate/map our basic memory mapping */ + switch (EXYNOS_PRODUCT_FAMILY(exynos_soc_id)) { + case EXYNOS4_PRODUCT_FAMILY: + devmap = e4_devmap; + rambase = EXYNOS4_SDRAM_PBASE; + break; + case EXYNOS5_PRODUCT_FAMILY: + devmap = e5_devmap; + rambase = EXYNOS5_SDRAM_PBASE; + break; + default: + /* Won't work, but... */ + panic("Unknown product family %llx", + EXYNOS_PRODUCT_FAMILY(exynos_soc_id)); + } + pmap_devmap_register(devmap); + + /* bootstrap soc. uart_address is determined in odroid_start */ + exynos_bootstrap(EXYNOS_CORE_VBASE, EXYNOS_IOPHYSTOVIRT(uart_address)); + + /* set up CPU / MMU / TLB functions */ + if (set_cpufuncs()) + panic("cpu not recognized!"); + + /* get normal console working */ +// consinit(); + +#ifdef KGDB + kgdb_port_init(); +#endif + +#ifdef VERBOSE_INIT_ARM + printf("\nuboot arg = %#"PRIxPTR", %#"PRIxPTR", %#"PRIxPTR", %#"PRIxPTR"\n", + uboot_args[0], uboot_args[1], uboot_args[2], uboot_args[3]); + printf("Exynos SoC ID %08x\n", exynos_soc_id); + + printf("initarm: cbar=%#x\n", armreg_cbar_read()); +#endif + + /* init clocks */ + /* determine cpu clock source */ +curcpu()->ci_data.cpu_cc_freq = 1*1000*1000*1000; /* XXX hack XXX */ + +#if NARML2CC > 0 + /* probe and enable the PL310 L2CC */ + const bus_space_handle_t pl310_bh = + armreg_cbar_read() - EXYNOS_CORE_PBASE + EXYNOS_CORE_VBASE; + + trustzone_firmware_handlers->l2cc_init(); + arml2cc_init(&exynos_bs_tag, pl310_bh, 0x2000); +#endif + +/* XXX watchdog not implemented yet */ +// cpu_reset_address = exynos_wdog_reset; + +#ifdef VERBOSE_INIT_ARM + printf("\nNetBSD/evbarm (odroid) booting ...\n"); +#endif + +#ifdef BOOT_ARGS + char mi_bootargs[] = BOOT_ARGS; + parse_mi_bootargs(mi_bootargs); +#endif + + /* Fake bootconfig structure for the benefit of pmap.c. */ + bootconfig.dramblocks = 1; + bootconfig.dram[0].address = rambase; + + /* + * Determine physical memory by looking at the PoP package + */ + + psize_t ram_size = (psize_t) 0x90000000 - 0x20000000; +#if 0 + switch (exynos_pop_id) { + case EXYNOS_PACKAGE_ID_2_GIG: + ram_size = (psize_t) 2*1024*1024*1024; + break; + default: + printf("Unknown PoP package id 0x%08x\n", exynos_pop_id); + ram_size = (psize_t) 0x10000000; + } +#endif + /* + * Configure DMA tags + */ + /* XXX dma not implemented yet */ + // exynos_dma_bootstrap(ram_size); + + bootconfig.dram[0].pages = ram_size / PAGE_SIZE; + +#ifdef __HAVE_MM_MD_DIRECT_MAPPED_PHYS +#error __HAVE_MM_MD_DIRECT_MAPPED_PHYS cannot handle 2G RAM yet + const bool mapallmem_p = true; + if (ram_size > KERNEL_VM_BASE - KERNEL_BASE) { + printf("%s: dropping RAM size from %luMB to %uMB\n", + __func__, (unsigned long) (ram_size >> 20), + (KERNEL_VM_BASE - KERNEL_BASE) >> 20); + ram_size = KERNEL_VM_BASE - KERNEL_BASE; + } +#else + const bool mapallmem_p = false; +#endif + KASSERT((armreg_pfr1_read() & ARM_PFR1_SEC_MASK) != 0); + + arm32_bootmem_init(bootconfig.dram[0].address, ram_size, + KERNEL_BASE_PHYS); + arm32_kernel_vm_init(KERNEL_VM_BASE, ARM_VECTORS_LOW, 0, devmap, + mapallmem_p); + +printf("did we?\n"); + + /* forget about passed bootargs for now */ + /* TODO translate `uboot_args' phys->virt to bootargs */ +char tmp[1000]; +strcpy(tmp, "-v"); + boot_args = tmp; // bootargs; + parse_mi_bootargs(boot_args); + + /* we've a specific device_register routine */ + evbarm_device_register = odroid_device_register; + + return initarm_common(KERNEL_VM_BASE, KERNEL_VM_SIZE, NULL, 0); +} + + +void +consinit(void) +{ + static int consinit_called = 0; +#if 0 +#if NSSCOM > 0 + bus_space_tag_t iot = &exynos_bs_tag; +#endif +#endif + if (consinit_called) + return; + consinit_called = 1; + +#if 0 +#if NSSCOM > 0 + /* attach console */ + if (sscom_cnattach(iot, &uarts[SSCON_CHANNEL], + conspeed, EXYNOS_UART_FREQ, conmode)) + panic("Serial console can not be initialized"); +#else +#error only serial console is supported +#endif + +#if NUKBD > 0 + /* allow USB keyboards to become console */ + ukbd_cnattach(); +#endif /* NUKBD */ + +#endif +} + + +void +odroid_device_register(device_t self, void *aux) +{ + prop_dictionary_t dict = device_properties(self); + + exynos_device_register(self, aux); + + if (device_is_a(self, "sscom")) { + if (use_fb_console) + prop_dictionary_set_bool(dict, "is_console", false); + } +} + Index: sys/arch/evbarm/odroid/odroid_start.S =================================================================== RCS file: sys/arch/evbarm/odroid/odroid_start.S diff -N sys/arch/evbarm/odroid/odroid_start.S --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arch/evbarm/odroid/odroid_start.S 11 Apr 2014 15:32:45 -0000 @@ -0,0 +1,293 @@ +/* $NetBSD$ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Matt Thomas of 3am Software Foundry. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this 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 "opt_exynos.h" +#include "opt_sscom.h" +#include "opt_cpuoptions.h" +#include "opt_cputypes.h" +#include "opt_multiprocessor.h" +#include "opt_arm_debug.h" + +#include +#include +#include "assym.h" + +#include +#include +#include + +#include + +RCSID("$NetBSD$") + + +#if defined(VERBOSE_INIT_ARM) + +#define XPUTC(n) mov r0, n; bl xputc +#ifdef __ARMEB__ +#define COM_BSWAP +#endif +#else +#define XPUTC(n) +#endif + +#define INIT_MEMSIZE 128 + +#if 1 +#define TEMP_L1_TABLE (0x80000000 + INIT_MEMSIZE * 0x100000 - L1_TABLE_SIZE) +#else +#define TEMP_L1_TABLE +#endif + +#define MD_CPU_HATCH _C_LABEL(exynos_cpu_hatch) + +/* + * Kernel start routine for ODROID boards running on uboot firmware + * At this point, this code has been loaded into SDRAM + * and the MMU is off + */ + #ifdef KERNEL_BASES_EQUAL + .text +#else + .section .start,"ax",%progbits +#endif + + .global _C_LABEL(odroid_start) +_C_LABEL(odroid_start): +#ifdef __ARMEB__ + setend be /* force big endian */ +#endif + + /* Move into supervisor mode and disable IRQs/FIQs. */ + cpsid if, #PSR_SVC32_MODE + + /* + * Save any arguments passed to us. But since .start is at 0x40000000 + * and .text is at 0x8000000, we can't directly use the address that + * the linker gave us directly. We have to replace the upper 4 bits + * of the address the linker gave us and replace it with the upper 4 + * bits of our pc. Or replace the lower 28 bits of our PC with the + * lower 28 bits of what the linker gave us. + */ + adr r4, _C_LABEL(odroid_start) + movw r5, #:lower16:uboot_args + movt r5, #:upper16:uboot_args + bfi r4, r5, #0, #28 + + stmia r4, {r0-r3} // Save the arguments + + /* + * For easy and early SoC / PoP dependency, retrieve the IDs + */ + movw r6, #:lower16:EXYNOS_CORE_PBASE + movt r6, #:upper16:EXYNOS_CORE_PBASE + + ldr r0, [r6, #EXYNOS_PROD_ID_OFFSET] // load soc_id + + movw r5, #:lower16:exynos_soc_id + movt r5, #:upper16:exynos_soc_id + bfi r4, r5, #0, #28 + str r0, [r4] // save soc_id + + /* Pick uart address and initial MMU table for the SoC */ + mov r1, r0, lsr #24 + cmp r1, #0xe5 + ldreq r2, .Lexynos5_uart + adreq r3, .Lmmu_init_table5 + cmp r1, #0xe4 + ldreq r2, .Lexynos4_uart + adreq r3, .Lmmu_init_table4 + str r2, uart_address + str r3, .Lmmu_init_table + + /* + * Turn on the SMP bit + */ + bl cortex_init + + XPUTC(#67) + +/* XXX RPZ CHECK ME, where are these bits? XXX */ +#if defined(MULTIPROCESSOR) && 0 + movw r0, #:lower16:(EXYNOS_CORE_PBASE+EXYNOS_CPUCFG_OFFSET) + movt r0, #:upper16:(EXYNOS_CORE_PBASE+EXYNOS_CPUCFG_OFFSET) + + /* Set where the other CPU(s) are going to execute */ + adr r1, cortex_mpstart + str r1, [r0, #EXYNOS_CPUCFG_PRIVATE_REG] + + /* Bring CPU1 out of reset */ + ldr r1, [r0, #EXYNOS_CPUCFG_CPU1_RST_CTRL_REG] + orr r1, r1, #(EXYNOS_CPUCFG_CPU_RST_CTRL_CORE_RESET|EXYNOS_CPUCFG_CPU_RST_CTRL_RESET) + str r1, [r0, #EXYNOS_CPUCFG_CPU1_RST_CTRL_REG] +#endif /* MULTIPROCESSOR */ + + /* + * Set up a preliminary mapping in the MMU to allow us to run + * at KERNEL_BASE with caches on. + */ + movw r0, #:lower16:TEMP_L1_TABLE + movt r0, #:upper16:TEMP_L1_TABLE + ldr r1, .Lmmu_init_table + bl arm_boot_l1pt_init + + XPUTC(#68) + + /* + * Turn on the MMU, Caches, etc. + */ + movw r0, #:lower16:TEMP_L1_TABLE + movt r0, #:upper16:TEMP_L1_TABLE + bl arm_cpuinit + + XPUTC(#90) + XPUTC(#13) + XPUTC(#10) + + /* + * Jump to start in locore.S, which in turn will call initarm and main. + */ + movw ip, #:lower16:start + movt ip, #:upper16:start + bx ip /* Jump to start (flushes pipeline). */ + nop + nop + nop + nop + + /* NOTREACHED */ +ASEND(_C_LABEL(odroid_start)) + + .global xputc + + .global uart_address +uart_address: + .word 0 + +.Lexynos4_uart: + .word EXYNOS_CORE_PBASE + EXYNOS4_UART1_OFFSET + +.Lexynos5_uart: + .word EXYNOS_CORE_PBASE + EXYNOS5_UART2_OFFSET + +.Lmmu_init_table: + .word 0 + + .p2align 2 + +#if defined(VERBOSE_INIT_ARM) +#define TIMO 0x25000 +xputc: + mov r2, #TIMO + ldr r3, uart_address /* get uart physical address */ +1: + ldrb r1, [r3, #COM_LSR] + tst r1, #LSR_TXRDY + bne 2f + subs r2, r2, #1 + bne 1b +2: + strb r0, [r3, #COM_DATA] + + mov r2, #TIMO +3: + ldrb r1, [r3, #COM_LSR] + tst r1, #LSR_TSRE + bne 4f + subs r2, r2, #1 + bne 3b +4: + bx lr + +#endif + +#include + +.Lmmu_init_table4: +#ifdef KERNEL_BASES_EQUAL + /* Map memory 1:1 VA to PA, write-back cacheable, shareable */ + MMU_INIT(KERNEL_BASE, KERNEL_BASE, + (INIT_MEMSIZE * L1_S_SIZE + L1_S_SIZE - 1) / L1_S_SIZE, + L1_S_PROTO_armv7 | L1_S_APv7_KRW | L1_S_CACHEABLE) +#else + /* Map KERNEL_BASE VA to SDRAM PA, write-back cacheable, shareable */ + MMU_INIT(KERNEL_BASE, EXYNOS4_SDRAM_PBASE, + (INIT_MEMSIZE * L1_S_SIZE + L1_S_SIZE - 1) / L1_S_SIZE, + L1_S_PROTO_armv7 | L1_S_APv7_KRW | L1_S_CACHEABLE) + + /* Map memory 1:1 VA to PA, write-back cacheable, shareable */ + MMU_INIT(EXYNOS4_SDRAM_PBASE, EXYNOS4_SDRAM_PBASE, + (INIT_MEMSIZE * L1_S_SIZE + L1_S_SIZE - 1) / L1_S_SIZE, + L1_S_PROTO_armv7 | L1_S_APv7_KRW | L1_S_CACHEABLE) +#endif + /* Map EXYNOS CORE (so console will work) */ + MMU_INIT(EXYNOS_CORE_VBASE, EXYNOS_CORE_PBASE, + (EXYNOS4_CORE_SIZE + L1_S_SIZE - 1) / L1_S_SIZE, + L1_S_PROTO_armv7 | L1_S_APv7_KRW | L1_S_V6_XN) + + /* Map EXYNOS CORE (so console will work) */ + MMU_INIT(EXYNOS_CORE_PBASE, EXYNOS_CORE_PBASE, + (EXYNOS4_CORE_SIZE + L1_S_SIZE - 1) / L1_S_SIZE, + L1_S_PROTO_armv7 | L1_S_APv7_KRW | L1_S_V6_XN) + + /* end of table */ + MMU_INIT(0, 0, 0, 0) + +.Lmmu_init_table5: +#ifdef KERNEL_BASES_EQUAL + /* Map memory 1:1 VA to PA, write-back cacheable, shareable */ + MMU_INIT(KERNEL_BASE, KERNEL_BASE, + (INIT_MEMSIZE * L1_S_SIZE + L1_S_SIZE - 1) / L1_S_SIZE, + L1_S_PROTO_armv7 | L1_S_APv7_KRW | L1_S_CACHEABLE) +#else + /* Map KERNEL_BASE VA to SDRAM PA, write-back cacheable, shareable */ + MMU_INIT(KERNEL_BASE, KERNEL_BASE - KERNEL_BASE_VOFFSET, + (INIT_MEMSIZE * L1_S_SIZE + L1_S_SIZE - 1) / L1_S_SIZE, + L1_S_PROTO_armv7 | L1_S_APv7_KRW | L1_S_CACHEABLE) + + /* Map memory 1:1 VA to PA, write-back cacheable, shareable */ + MMU_INIT(EXYNOS5_SDRAM_PBASE, EXYNOS5_SDRAM_PBASE, + (INIT_MEMSIZE * L1_S_SIZE + L1_S_SIZE - 1) / L1_S_SIZE, + L1_S_PROTO_armv7 | L1_S_APv7_KRW | L1_S_CACHEABLE) +#endif + /* Map EXYNOS CORE (so console will work) */ + MMU_INIT(EXYNOS_CORE_VBASE, EXYNOS_CORE_PBASE, + (EXYNOS5_CORE_SIZE + L1_S_SIZE - 1) / L1_S_SIZE, + L1_S_PROTO_armv7 | L1_S_APv7_KRW | L1_S_V6_XN) + + /* Map EXYNOS CORE (so console will work) */ + MMU_INIT(EXYNOS_CORE_PBASE, EXYNOS_CORE_PBASE, + (EXYNOS5_CORE_SIZE + L1_S_SIZE - 1) / L1_S_SIZE, + L1_S_PROTO_armv7 | L1_S_APv7_KRW | L1_S_V6_XN) + + /* end of table */ + MMU_INIT(0, 0, 0, 0) + Index: sys/arch/evbarm/odroid/platform.h =================================================================== RCS file: sys/arch/evbarm/odroid/platform.h diff -N sys/arch/evbarm/odroid/platform.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arch/evbarm/odroid/platform.h 11 Apr 2014 15:32:45 -0000 @@ -0,0 +1,66 @@ +/* $NetBSD$ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Nick Hudson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this 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. + */ + +#ifndef _ARM_ODROID_PLATFORM_H +#define _ARM_ODROID_PLATFORM_H + +#include "opt_exynos.h" + +/* + * Kernel VM space 16Mb behind KERNEL_BASE upto 0xf0000000 + */ +#define KERNEL_VM_BASE 0xc0000000 +#define KERNEL_VM_SIZE (EXYNOS_CORE_VBASE - KERNEL_VM_BASE) + +/* + * IO space + */ + +#define EXYNOS_CORE_VBASE 0xf0000000 + +/* + * Serial consoles + */ +#define CONADDR_VA ((CONADDR - EXYNOS_CORE_PBASE) + EXYNOS_CORE_VBASE) + +#ifdef SSCOM0CONSOLE +#define SSCON_CHANNEL 0 +#define CONADDR (EXYNOS_CORE_PBASE + EXYNOS5_UART2_OFFSET) +#endif +#if 0 +#ifdef SSCOM1CONSOLE +#define SSCON_CHANNEL 1 +#define CONADDR (EXYNOS_CORE_PBASE + EXYNOS_UART1_OFFSET) +#endif +#endif + +#endif /* _ARM_ODROID_PLATFORM_H */ +