commit a82fcbc63c8f107d20954b8cbec64c26777c0880 Author: thead_admin Date: Tue Sep 13 10:33:44 2022 +0800 Linux_SDK_V0.9.5 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4e9c07c --- /dev/null +++ b/.gitignore @@ -0,0 +1,13 @@ +*.o +*.a +*.o.d +*.o.cmd +*.a.cmd +*.ko.cmd +*.ko +*.mod +*.mod.c +*.mod.cmd +Module.symvers +*.so +*.Module.* diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..ff29d3e --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "CSI_DSP_FW"] + path = CSI_DSP_FW + url = git@gitlab.alibaba-inc.com:thead-linux-private/csi_dsp_firmware.git diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..385cb19 --- /dev/null +++ b/Makefile @@ -0,0 +1,137 @@ +## + # Copyright (C) 2021 Alibaba Group Holding Limited + # + # This program is free software; you can redistribute it and/or modify + # it under the terms of the GNU General Public License version 2 as + # published by the Free Software Foundation. +## + +test = $(shell if [ -f "../.param" ]; then echo "exist"; else echo "noexist"; fi) +ifeq ("$(test)", "exist") + include ../.param +endif + +CONFIG_DRIVER_BUILD_PARAMS=KERNEL=$(LINUX_DIR) CROSS=$(CROSS_COMPILE) ARCH=$(ARCH) BOARD_NAME=$(BOARD_NAME) +CONFIG_LIB_BUILD_PARAMS=CROSS=$(CROSS_COMPILE) ARCH=$(ARCH) BOARD_NAME=$(BOARD_NAME) +CONFIG_TEST_BUILD_PARAMS=CROSS=$(CROSS_COMPILE) ARCH=$(ARCH) BOARD_NAME=$(BOARD_NAME) + +MODULE_NAME=xtensa_dsp +BUILD_LOG_START="\033[47;30m>>> $(MODULE_NAME) $@ begin\033[0m" +BUILD_LOG_END ="\033[47;30m<<< $(MODULE_NAME) $@ end\033[0m" + +DIR_TARGET_BASE=bsp/xtensa_dsp +DIR_TARGET_LIB =bsp/xtensa_dsp/lib +DIR_TARGET_KO =bsp/xtensa_dsp/ko +DIR_TARGET_TEST=bsp/xtensa_dsp/test + + + +# +# Do a parallel build with multiple jobs, based on the number of CPUs online +# in this system: 'make -j8' on a 8-CPU system, etc. +# +# (To override it, run 'make JOBS=1' and similar.) +# +ifeq ($(JOBS),) + JOBS := $(shell grep -c ^processor /proc/cpuinfo 2>/dev/null) + ifeq ($(JOBS),) + JOBS := 1 + endif +endif + +all: info lib driver test install_local_output install_rootfs +.PHONY: info driver lib test install_local_output install_rootfs \ + clean_driver clean_lib clean_test clean_tools clean_output clean + +info: + @echo $(BUILD_LOG_START) + @echo " ====== Build Info from repo project ======" + @echo " BUILDROOT_DIR="$(BUILDROOT_DIR) + @echo " CROSS_COMPILE="$(CROSS_COMPILE) + @echo " LINUX_DIR="$(LINUX_DIR) + @echo " ARCH="$(ARCH) + @echo " BOARD_NAME="$(BOARD_NAME) + @echo " KERNEL_ID="$(KERNELVERSION) + @echo " KERNEL_DIR="$(LINUX_DIR) + @echo " INSTALL_DIR_ROOTFS="$(INSTALL_DIR_ROOTFS) + @echo " INSTALL_DIR_SDK="$(INSTALL_DIR_SDK) + @echo " CONFIG_DRIVER_BUILD_PARAMS="$(CONFIG_DRIVER_BUILD_PARAMS) + @echo " CONFIG_LIB_BUILD_PARAMS="$(CONFIG_LIB_BUILD_PARAMS) + @echo " CONFIG_TEST_BUILD_PARAMS="$(CONFIG_TEST_BUILD_PARAMS) + @echo $(BUILD_LOG_END) + +driver: + @echo $(BUILD_LOG_START) + make -C driver/xrp-kernel $(CONFIG_DRIVER_BUILD_PARAMS) BUILD_TYPE=DEBUG + @echo $(BUILD_LOG_END) + +clean_driver: + @echo $(BUILD_LOG_START) + make -C driver/xrp-kernel $(CONFIG_DRIVER_BUILD_PARAMS) clean + @echo $(BUILD_LOG_END) + +lib: + @echo $(BUILD_LOG_START) + # make -C driver/xrp-user/xrp-host $(CONFIG_LIB_BUILD_PARAMS) + # make -C driver/xrp-user/xrp-common $(CONFIG_LIB_BUILD_PARAMS) + make -C driver/xrp-user/ $(CONFIG_LIB_BUILD_PARAMS) + @echo $(BUILD_LOG_END) + +clean_lib: + @echo $(BUILD_LOG_START) + make -C driver/xrp-user/xrp-host clean + make -C driver/xrp-user/xrp-common clean + make -C driver/xrp-user/ clean + @echo $(BUILD_LOG_END) + +test: lib driver + @echo $(BUILD_LOG_START) + make -C test/vi_test $(CONFIG_TEST_BUILD_PARAMS) + make -C test/npu_test $(CONFIG_TEST_BUILD_PARAMS) + make -C test/ip_test $(CONFIG_TEST_BUILD_PARAMS) + make -C test/drv_test $(CONFIG_TEST_BUILD_PARAMS) + @echo $(BUILD_LOG_END) + +clean_test: + @echo $(BUILD_LOG_START) + make -C test/vi_test clean + make -C test/npu_test clean + make -C test/ip_test clean + make -C test/drv_test clean + @echo $(BUILD_LOG_END) + + +install_local_output: driver lib test + @echo $(BUILD_LOG_START) + # driver files + mkdir -p ./output/rootfs/$(DIR_TARGET_KO) + cp -f ./driver/xrp-kernel/*.ko ./output/rootfs/$(DIR_TARGET_KO) + + # lib files + mkdir -p ./output/rootfs/$(DIR_TARGET_LIB) + cp -f ./driver/xrp-user/*.so ./output/rootfs/$(DIR_TARGET_LIB) + # test files + mkdir -p ./output/rootfs/$(DIR_TARGET_TEST) + cp -rf ./test/vi_test/output/* ./output/rootfs/$(DIR_TARGET_TEST) + cp -rf ./test/npu_test/output/* ./output/rootfs/$(DIR_TARGET_TEST) + cp -rf ./test/ip_test/output/* ./output/rootfs/$(DIR_TARGET_TEST) + cp -rf ./test/drv_test/output/* ./output/rootfs/$(DIR_TARGET_TEST) + @if [ `command -v tree` != "" ]; then \ + tree ./output/rootfs -I 'sdk' | grep -v "\.json"; \ + echo "INFO: The files above, has filter out the sdk folder and .json files"; \ + fi + @echo $(BUILD_LOG_END) + +install_rootfs: install_local_output + @echo $(BUILD_LOG_START) +# cp -rf output/rootfs/* $(INSTALL_DIR_ROOTFS) + @echo $(BUILD_LOG_END) + +clean_output: + @echo $(BUILD_LOG_START) + rm -rf ./output + rm -rf $(INSTALL_DIR_ROOTFS)/$(DIR_TARGET_BASE) + @echo $(BUILD_LOG_END) + +clean: clean_output clean_driver clean_lib clean_test + diff --git a/README.md b/README.md new file mode 100644 index 0000000..56e2aa0 --- /dev/null +++ b/README.md @@ -0,0 +1,14 @@ +# How to get the code +- git clone git@gitlab.alibaba-inc.com:thead-linux-private/xtensa_dsp.git + +# How to build +## Build within repo project +- XX +## Build out of repo project +- YY + +# Description of each directories +- driver/: Linux kernel module Driver. +- lib/: User mode libs and header files. +- test/: Test cases and demo app. + diff --git a/driver/board/dts_FM_95P_VI_V2_SP1.txt b/driver/board/dts_FM_95P_VI_V2_SP1.txt new file mode 100644 index 0000000..7d50ecb --- /dev/null +++ b/driver/board/dts_FM_95P_VI_V2_SP1.txt @@ -0,0 +1,1005 @@ +/dts-v1/; +/ { + model = "T-HEAD Light FM c910 soc"; + compatible = "thead,light_fm_c910_soc"; + #address-cells = <2>; + #size-cells = <2>; + + memory@0 { + device_type = "memory"; + /* + * Total memory size: 8GB in HAPS system: + * 0x0 00000000 - 0x1 80000000: 6GB reserved for Linux system + * 0x1 80000000 - 0x0 80000000: 2GB reserved for Media system + */ + reg = <0x0 0x00000000 0x0 0x60000000>; + }; + + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + media-buffer@c0000000 { + compatible = "shared-dma-pool"; + reg = <0x0 0xc0000000 0x0 0x40000000>; + reusable; + status = "okay"; + }; + + isp_reserved: isp@40000000 { + no-map; + reg = <0 0x40000000 0 0x10000000>; + status = "okay"; + }; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + timebase-frequency = <3000000>; + cpu@0 { + device_type = "cpu"; + reg = <0>; + status = "okay"; + compatible = "riscv"; + riscv,isa = "rv64imafdcvsu"; + mmu-type = "riscv,sv39"; + cpu0_intc: interrupt-controller { + #interrupt-cells = <1>; + compatible = "riscv,cpu-intc"; + interrupt-controller; + }; + }; + cpu@1 { + device_type = "cpu"; + reg = <1>; + status = "disabled"; + compatible = "riscv"; + riscv,isa = "rv64imafdcvsu"; + mmu-type = "riscv,sv39"; + cpu1_intc: interrupt-controller { + #interrupt-cells = <1>; + compatible = "riscv,cpu-intc"; + interrupt-controller; + }; + }; + cpu@2 { + device_type = "cpu"; + reg = <2>; + status = "disabled"; + compatible = "riscv"; + riscv,isa = "rv64imafdcvsu"; + mmu-type = "riscv,sv39"; + cpu2_intc: interrupt-controller { + #interrupt-cells = <1>; + compatible = "riscv,cpu-intc"; + interrupt-controller; + }; + }; + cpu@3 { + device_type = "cpu"; + reg = <3>; + status = "disabled"; + compatible = "riscv"; + riscv,isa = "rv64imafdcvsu"; + mmu-type = "riscv,sv39"; + cpu3_intc: interrupt-controller { + #interrupt-cells = <1>; + compatible = "riscv,cpu-intc"; + interrupt-controller; + }; + }; + }; + + soc { + compatible = "simple-bus"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + + intc: interrupt-controller@ffd8000000 { + #interrupt-cells = <1>; + compatible = "riscv,plic0"; + interrupt-controller; + interrupts-extended = < + &cpu0_intc 0xffffffff &cpu0_intc 9 + &cpu1_intc 0xffffffff &cpu1_intc 9 + &cpu2_intc 0xffffffff &cpu2_intc 9 + &cpu3_intc 0xffffffff &cpu3_intc 9 + >; + reg = <0xff 0xd8000000 0x0 0x04000000>; + reg-names = "control"; + riscv,max-priority = <7>; + riscv,ndev = <240>; + }; + + clocks { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <0>; + + dummy_clock_apb: apb-clock@0 { + compatible = "fixed-clock"; + reg = <0>; /* Not address, just for index */ + clock-frequency = <50000000>; + clock-output-names = "dummy_clock_apb"; + #clock-cells = <0>; + }; + + dummy_clock_ref: ref-clock@1 { + compatible = "fixed-clock"; + reg = <1>; /* Not address, just for index */ + clock-frequency = <50000000>; + clock-output-names = "dummy_clock_ref"; + #clock-cells = <0>; + }; + + dummy_clock_suspend: suspend-clock@2 { + compatible = "fixed-clock"; + reg = <2>; /* Not address, just for index */ + clock-frequency = <50000000>; + clock-output-names = "dummy_clock_suspend"; + #clock-cells = <0>; + }; + + dummy_clock_rtc: rtc-clock@3 { + compatible = "fixed-clock"; + reg = <3>; /* Not address, just for index */ + clock-frequency = <32768>; + clock-output-names = "dummy_clock_rtc"; + #clock-cells = <0>; + }; + + dummy_clock_ahb: ahb-clock@4 { + compatible = "fixed-clock"; + reg = <4>; /* Not address, just for index */ + clock-frequency = <50000000>; + clock-output-names = "dummy_clock_ahb"; + #clock-cells = <0>; + }; + + dummy_clock_npu: npu-clock@5 { + compatible = "fixed-clock"; + reg = <5>; /* Not address, just for index */ + clock-frequency = <24000000>; + clock-output-names = "dummy_clock_npu"; + #clock-cells = <0>; + }; + }; + + gpio0: gpio@ffec005000 { + compatible = "snps,dw-apb-gpio"; + reg = <0xff 0xec005000 0x0 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + + gpio0_porta: gpio0-controller@0 { + compatible = "snps,dw-apb-gpio-port"; + gpio-controller; + #gpio-cells = <2>; + snps,nr-gpios = <32>; + reg = <0>; + + interrupt-controller; + #interrupt-cells = <2>; + interrupt-parent = <&intc>; + interrupts = <56>; + }; + }; + + gpio1: gpio@ffec006000 { + compatible = "snps,dw-apb-gpio"; + reg = <0xff 0xec006000 0x0 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + + gpio1_porta: gpio1-controller@0 { + compatible = "snps,dw-apb-gpio-port"; + gpio-controller; + #gpio-cells = <2>; + snps,nr-gpios = <32>; + reg = <0>; + + interrupt-controller; + #interrupt-cells = <2>; + interrupt-parent = <&intc>; + interrupts = <57>; + }; + }; + + gpio2: gpio@ffe7f34000 { + compatible = "snps,dw-apb-gpio"; + reg = <0xff 0xe7f34000 0x0 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + + gpio2_porta: gpio2-controller@0 { + compatible = "snps,dw-apb-gpio-port"; + gpio-controller; + #gpio-cells = <2>; + snps,nr-gpios = <32>; + reg = <0>; + + interrupt-controller; + #interrupt-cells = <2>; + interrupt-parent = <&intc>; + interrupts = <58>; + }; + }; + + gpio3: gpio@ffe7f38000 { + compatible = "snps,dw-apb-gpio"; + reg = <0xff 0xe7f38000 0x0 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + + gpio3_porta: gpio3-controller@0 { + compatible = "snps,dw-apb-gpio-port"; + gpio-controller; + #gpio-cells = <2>; + snps,nr-gpios = <32>; + reg = <0>; + + interrupt-controller; + #interrupt-cells = <2>; + interrupt-parent = <&intc>; + interrupts = <59>; + }; + }; + + timer0: timer@ffefc32000 { + compatible = "snps,dw-apb-timer"; + reg = <0xff 0xefc32000 0x0 0x14>; + clocks = <&dummy_clock_apb>; + clock-names = "timer"; + clock-frequency = <50000000>; + interrupts = <16>; + interrupt-parent = <&intc>; + status = "okay"; + }; + + timer1: timer@ffefc32014 { + compatible = "snps,dw-apb-timer"; + reg = <0xff 0xefc32014 0x0 0x14>; + clocks = <&dummy_clock_apb>; + clock-names = "timer"; + clock-frequency = <50000000>; + interrupts = <17>; + interrupt-parent = <&intc>; + status = "okay"; + }; + + timer2: timer@ffefc32028 { + compatible = "snps,dw-apb-timer"; + reg = <0xff 0xefc32028 0x0 0x14>; + clocks = <&dummy_clock_apb>; + clock-names = "timer"; + clock-frequency = <50000000>; + interrupts = <18>; + interrupt-parent = <&intc>; + status = "disabled"; + }; + + timer3: timer@ffefc3203c { + compatible = "snps,dw-apb-timer"; + reg = <0xff 0xefc3203c 0x0 0x14>; + clocks = <&dummy_clock_apb>; + clock-names = "timer"; + clock-frequency = <50000000>; + interrupts = <19>; + interrupt-parent = <&intc>; + status = "disabled"; + }; + + timer4: timer@ffffc33000 { + compatible = "snps,dw-apb-timer"; + reg = <0xff 0xffc33000 0x0 0x14>; + clocks = <&dummy_clock_apb>; + clock-names = "timer"; + clock-frequency = <50000000>; + interrupts = <20>; + interrupt-parent = <&intc>; + status = "disabled"; + }; + + timer5: timer@ffffc33014 { + compatible = "snps,dw-apb-timer"; + reg = <0xff 0xffc33014 0x0 0x14>; + clocks = <&dummy_clock_apb>; + clock-names = "timer"; + clock-frequency = <50000000>; + interrupts = <21>; + interrupt-parent = <&intc>; + status = "disabled"; + }; + + timer6: timer@ffffc33028 { + compatible = "snps,dw-apb-timer"; + reg = <0xff 0xffc33028 0x0 0x14>; + clocks = <&dummy_clock_apb>; + clock-names = "timer"; + clock-frequency = <50000000>; + interrupts = <22>; + interrupt-parent = <&intc>; + status = "disabled"; + }; + + timer7: timer@ffffc3303c { + compatible = "snps,dw-apb-timer"; + reg = <0xff 0xffc3303c 0x0 0x14>; + clocks = <&dummy_clock_apb>; + clock-names = "timer"; + clock-frequency = <50000000>; + interrupts = <23>; + interrupt-parent = <&intc>; + status = "disabled"; + }; + +// keys: gpio-keys@100 { +// compatible = "gpio-keys"; +// reg = <0x0 0x100 0x0 0x0>; +// +// key0 { +// label = "key0"; +// gpios = <&gpio1_porta 7 1>; /* GPIO_ACTIVE_LOW: 1 */ +// linux,code = <59>; /* KEY_F1: 59 */ +// status = "okay"; +// }; +// }; +// +// leds: gpio-leds@200 { +// compatible = "gpio-leds"; +// reg = <0x0 0x200 0x0 0x0>; +// +// led0 { +// label = "led0"; +// gpios = <&gpio1_porta 8 0>; /* GPIO_ACTIVE_HIGH: 0 */ +// default-state = "off"; +// }; +// }; + + uart0: serial@ffe7014000 { /* Normal serial, for C910 log */ + compatible = "snps,dw-apb-uart"; + reg = <0xff 0xe7014000 0x0 0x4000>; + interrupt-parent = <&intc>; + interrupts = <36>; + clocks = <&dummy_clock_apb>; + clock-names = "baudclk"; + reg-shift = <2>; + reg-io-width = <4>; + hw-flow-control = "unsupport"; + status = "okay"; + }; + uart1: serial@ffe7f00000 { /* Normal serial, for C902 log */ + compatible = "snps,dw-apb-uart"; + reg = <0xff 0xe7f00000 0x0 0x4000>; + interrupt-parent = <&intc>; + interrupts = <37>; + clocks = <&dummy_clock_apb>; + clock-names = "baudclk"; + reg-shift = <2>; + reg-io-width = <4>; + hw-flow-control = "unsupport"; + status = "okay"; + }; + uart2: serial@ffec010000 { /* IRDA supported serial, not in 85P bit */ + compatible = "snps,dw-apb-uart"; + reg = <0xff 0xec010000 0x0 0x4000>; + interrupt-parent = <&intc>; + interrupts = <38>; + clocks = <&dummy_clock_apb>; + clock-names = "baudclk"; + reg-shift = <2>; + reg-io-width = <4>; + hw-flow-control = "unsupport"; + status = "disabled"; + }; + uart3: serial@ffe7f04000 { /* IRDA supported serial, not in 85P bit */ + compatible = "snps,dw-apb-uart"; + reg = <0xff 0xe7f04000 0x0 0x4000>; + interrupt-parent = <&intc>; + interrupts = <39>; + clocks = <&dummy_clock_apb>; + clock-names = "baudclk"; + reg-shift = <2>; + reg-io-width = <4>; + hw-flow-control = "unsupport"; + status = "disabled"; + }; + uart4: serial@fff7f08000 { /* High Speed with Flow Ctrol serial */ + compatible = "snps,dw-apb-uart"; + reg = <0xff 0xf7f08000 0x0 0x4000>; + interrupt-parent = <&intc>; + interrupts = <40>; + clocks = <&dummy_clock_apb>; + clock-names = "baudclk"; + reg-shift = <2>; + reg-io-width = <4>; + hw-flow-control = "support"; + status = "okay"; + }; + uart5: serial@fff7f0c000 { /* Normal serial, for external SE, not in 85P bit */ + compatible = "snps,dw-apb-uart"; + reg = <0xff 0xf7f0c000 0x0 0x4000>; + interrupt-parent = <&intc>; + interrupts = <41>; + clocks = <&dummy_clock_apb>; + clock-names = "baudclk"; + reg-shift = <2>; + reg-io-width = <4>; + hw-flow-control = "unsupport"; + status = "disabled"; + }; + + i2c0: i2c@ffe7f20000 { + compatible = "snps,designware-i2c"; + reg = <0xff 0xe7f20000 0x0 0x4000>; + interrupt-parent = <&intc>; + interrupts = <44>; + clocks = <&dummy_clock_apb>; + clock-frequency = <100000>; + + #address-cells = <1>; + #size-cells = <0>; + eeprom@50 { + compatible = "atmel,24c32"; + reg = <0x50>; + pagesize = <32>; + }; + }; + + i2c2: i2c@ffec00c000{ + compatible = "snps,designware-i2c"; + reg = <0xff 0xec00c000 0x0 0x4000>; + interrupt-parent = <&intc>; + interrupts = <46>; + clocks = <&dummy_clock_apb>; + clock-frequency = <100000>; + + #address-cells = <1>; + #size-cells = <0>; + //status = "disabled"; + }; + + i2c3: i2c@123321{ + compatible = "snps,designware-i2c"; + reg = <0xff 0xec014000 0x0 0x4000>; + //reg = <0xff 0xec00c000 0x0 0x4000>; + interrupt-parent = <&intc>; + //interrupts = <46>; + clocks = <&dummy_clock_apb>; + clock-frequency = <100000>; + + #address-cells = <1>; + #size-cells = <0>; + ov2775_0: ov2775_mipi@20 { + compatible = "ovti,ov2775"; + //reg = <0x20>; + reg = <0x10>; + pinctrl-names = "default"; + clocks = <&dummy_clock_apb>; + clock-names = "csi_mclk"; + //assigned-clocks = <&clk IMX8MP_CLK_IPP_DO_CLKO2>; + //assigned-clock-parents = <&clk IMX8MP_CLK_24M>; + assigned-clock-rates = <24000000>; + csi_id = <0>; + //pwn-gpios = <&gpio2 11 GPIO_ACTIVE_HIGH>; + //rst-gpios = <&gpio1 6 GPIO_ACTIVE_LOW>; + mclk = <24000000>; + mclk_source = <0>; + status = "okay"; + + port { + ov2775_mipi_0_ep: endpoint { + data-lanes = <1 2 3 4>; + clock-lanes = <0>; + max-pixel-frequency = /bits/ 64 <266000000>; + //remote-endpoint = <&mipi_csi0_ep>; + }; + }; + + }; + }; + + spi0: spi@ffe700c000 { + compatible = "snps,dw-apb-ssi"; + reg = <0xff 0xe700c000 0x0 0x1000>; + interrupt-parent = <&intc>; + interrupts = <54>; + clocks = <&dummy_clock_apb>; + num-cs = <2>; + cs-gpios = <&gpio2_porta 15 0>, // GPIO_ACTIVE_HIGH: 0 + <&gpio2_porta 23 0>; // GPIO_ACTIVE_LOW: 1 + + #address-cells = <1>; + #size-cells = <0>; + spi_norflash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "winbond,w25q64", "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <8000000>; + w25q,fast-read; + }; + spidev@1 { + compatible = "spidev"; + #address-cells = <1>; + #size-cells = <1>; + reg = <1>; + spi-max-frequency = <12500000>; + }; + }; + + qspi0: spi@ffea000000 { + compatible = "snps,dw-apb-ssi-quad"; + reg = <0xff 0xea000000 0x0 0x1000>; + interrupt-parent = <&intc>; + interrupts = <52>; + clocks = <&dummy_clock_apb>; + num-cs = <2>; + cs-gpios = <&gpio2_porta 3 0>, // GPIO_ACTIVE_HIGH: 0 + <&gpio2_porta 26 0>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + spi-flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "spi-nand"; + spi-max-frequency = <10000000>; + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; + reg = <0>; + + partition@0 { + label = "ubi1"; + reg = <0x00000000 0x08000000>; + }; + }; + spidev@1 { + compatible = "spidev"; + #address-cells = <1>; + #size-cells = <1>; + reg = <1>; + spi-max-frequency = <6250000>; + }; + }; + + watchdog0: watchdog@ffefc30000 { + compatible = "snps,dw-wdt"; + reg = <0xff 0xefc30000 0x0 0x1000>; + interrupt-parent = <&intc>; + interrupts = <24>; + clocks = <&dummy_clock_apb>; + clock-names = "baudclk"; + status = "okay"; + }; + + watchdog1: watchdog@ffefc31000 { + compatible = "snps,dw-wdt"; + reg = <0xff 0xefc31000 0x0 0x1000>; + interrupt-parent = <&intc>; + interrupts = <25>; + clocks = <&dummy_clock_apb>; + clock-names = "baudclk"; + status = "okay"; + }; + + rtc: rtc@fffff40000 { + compatible = "apm,xgene-rtc"; + reg = <0xff 0xfff40000 0x0 0x1000>; + interrupt-parent = <&intc>; + interrupts = <74>; + clocks = <&dummy_clock_rtc>; + clock-names = "rtc"; + status = "okay"; + }; + + usb: dwc3@ffe7040000 { + compatible = "snps,dwc3"; + reg = <0xff 0xe7040000 0x0 0x10000>; + interrupt-parent = <&intc>; + interrupts = <68>; + clocks = <&dummy_clock_ref>, <&dummy_clock_apb>, <&dummy_clock_suspend>; + clock-names = "ref", "bus_early", "suspend"; + reg-shift = <2>; + reg-io-width = <4>; + maximum-speed = "super-speed"; + dr_mode = "peripheral"; + snps,usb3_lpm_capable; + snps,dis_u3_susphy_quirk; + status = "disabled"; + }; + + pmu: pmu@0 { + compatible = "riscv,c910_pmu"; + reg = <0 0 0 0>; /* Not address, just for index */ + }; + + dmac0: dmac@ffefc00000 { + compatible = "snps,axi-dma-1.01a"; + reg = <0xff 0xefc00000 0x0 0x1000>; + interrupt-parent = <&intc>; + interrupts = <27>; + clocks = <&dummy_clock_apb>, <&dummy_clock_apb>; + clock-names = "core-clk", "cfgr-clk"; + + dma-channels = <4>; + snps,block-size = <65536 65536 65536 65536>; + snps,priority = <0 1 2 3>; + snps,dma-masters = <1>; + snps,data-width = <4>; + snps,axi-max-burst-len = <16>; + status = "disabled"; + }; + + dmac1: tee_dmac@ffff340000 { + compatible = "snps,axi-dma-1.01a"; + reg = <0xff 0xff340000 0x0 0x1000>; + interrupt-parent = <&intc>; + interrupts = <150>; + clocks = <&dummy_clock_apb>, <&dummy_clock_apb>; + clock-names = "core-clk", "cfgr-clk"; + + dma-channels = <4>; + snps,block-size = <65536 65536 65536 65536>; + snps,priority = <0 1 2 3>; + snps,dma-masters = <1>; + snps,data-width = <4>; + snps,axi-max-burst-len = <16>; + status = "disabled"; + }; + + gmac: ethernet@ffe7070000 { + compatible = "snps,dwmac"; + reg = <0xff 0xe7070000 0x0 0x2000>; + interrupt-parent = <&intc>; + interrupts = <66>; + interrupt-names = "macirq"; + clocks = <&dummy_clock_apb>; + clock-names = "stmmaceth"; + snps,pbl = <32>; + snps,fixed-burst; + + max-speed = <100>; + phy-mode = "mii"; + phy-handle = <&phy_88E1111>; + mdio0 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "snps,dwmac-mdio"; + + phy_88E1111: ethernet-phy@0 { + reg = <0x0 0x0>; + }; + }; + }; + + emmc: sdhci@ffe7080000 { + compatible = "snps,dwcmshc-sdhci"; + reg = <0xff 0xe7080000 0x0 0x10000>; + interrupt-parent = <&intc>; + interrupts = <62>; + interrupt-names = "sdhciirq"; + clocks = <&dummy_clock_ahb>; + clock-names = "core"; + max-frequency = <50000000>; + non-removable; + no-sdio; + no-sd; + bus-width = <8>; + status = "disabled"; + }; + + sdhci0: sd@ffe7090000 { + compatible = "snps,dwcmshc-sdhci"; + reg = <0xff 0xe7090000 0x0 0x10000>; + interrupt-parent = <&intc>; + interrupts = <64>; + interrupt-names = "sdhci0irq"; + clocks = <&dummy_clock_ahb>; + clock-names = "core"; + max-frequency = <50000000>; + no-1-8-v; + bus-width = <4>; + status = "disabled"; + }; + + hwspinlock: hwspinlock@ffefc10000 { + compatible = "light,hwspinlock"; + reg = <0xff 0xefc10000 0x0 0x10000>; + }; + + npu: vha@fffc800000 { + compatible = "img,ax3386-nna"; + reg = <0xff 0xfc800000 0x0 0x100000>; + interrupt-parent = <&intc>; + interrupts = <113>; + interrupt-names = "npuirq"; + clocks = <&dummy_clock_npu>; + clock-names = "dummy_clock_npu"; + vha_clk_rate = <24000000>; + ldo_vha-supply = <&npu>; + dma-mask = <0xf 0xffffffff>; + status = "disabled"; + }; + + vdec: vdec@ffecc00000 { + compatible = "platform-vc8000d"; + reg = <0xff 0xecc00000 0x0 0x1000>; + interrupt-parent = <&intc>; + interrupts = <131>; + status = "disabled"; + }; + + venc: venc@ffecc10000 { + compatible = "platform-vc8000e"; + reg = <0xff 0xecc10000 0x0 0x1000>; + interrupt-parent = <&intc>; + interrupts = <133>; + status = "disabled"; + }; + + // from https://github.com/iwave-git-imx8mm-8mn/kernel_iwg34m/blob/62c0186302d2c4754e06722b3c38f6c4557b91f4/arch/arm64/boot/dts/freescale/imx8mp.dtsi + aliases { + csi0 = &v4l2_mipi_csi_0; + }; + + v4l2_mipi_csi_0: mipi_csi@ff000000 { + compatible = "thead,light-mipi-csi"; + //reg = < 0xff 0xe4000000 0x0 0x10000>; + reg = < 0x00 0xff000000 0x0 0x10000>; + interrupt-parent = <&intc>; + interrupts = <199>; + clock-frequency = <24000000>; + bus-width = <4>; + no-reset-control; + status = "okay"; + + port@0 { + endpoint { + remote-endpoint = <&ov2775_mipi_0_ep>; + data-lanes = <4>; + csis-hs-settle = <16>; + }; + }; + }; + + v4l2_isp_0: v4l2_isp@ffe4100000 { + compatible = "fsl,imx8mp-isp"; + reg = <0xff 0xe4100000 0x0 0x10000>; + interrupt-parent = <&intc>; + interrupts = <117>; + memory-region = <&isp_reserved>; + clock-names = "core", "axi", "ahb"; + //clocks = <&clk IMX8MP_CLK_MEDIA_ISP_SRC>; + //clock-names = "isp_root"; + //assigned-clocks = <&clk IMX8MP_CLK_MEDIA_ISP_SRC>; + //assigned-clock-parents = <&clk IMX8MP_SYS_PLL2_500M>; + //assigned-clock-rates = <500000000>; + //power-domains = <&ispdwp_pd>; + id = <0>; + status = "okay"; + }; + + v4l2_dewarp: dwe@ffe4130000 { + compatible = "fsl,imx8mp-dwe"; + reg = <0xff 0xe4130000 0x0 0x10000>; + interrupt-parent = <&intc>; + interrupts = <98>; + //clocks = <&clk IMX8MP_CLK_MEDIA_AXI>, + // <&clk IMX8MP_CLK_MEDIA_AXI>, + // <&clk IMX8MP_CLK_MEDIA_APB>; + clock-names = "core", "axi", "ahb"; + //assigned-clocks = <&clk IMX8MP_CLK_MEDIA_AXI_ROOT>, + // <&clk IMX8MP_CLK_MEDIA_APB_ROOT>; + //assigned-clock-rates = <500000000>, <200000000>; + //power-domains = <&ispdwp_pd>; + id = <0>; + status = "okay"; + }; + + isp0: isp@ffe4100000 { + compatible = "thead,light-isp"; + reg = <0xff 0xe4100000 0x0 0x10000>; + interrupt-parent = <&intc>; + interrupts = <117>,<118>; + status = "okay"; + }; + + isp1: isp@ffe4110000 { + compatible = "thead,light-isp"; + reg = <0xff 0xe4110000 0x0 0x10000>; + interrupt-parent = <&intc>; + interrupts = <120>,<121>; + status = "okay"; + }; + + isp_ry0: isp_ry@ffe4120000 { + compatible = "thead,light-isp_ry"; + reg = <0xff 0xe4120000 0x0 0x10000>; + interrupt-parent = <&intc>; + interrupts = <123>,<124>; + status = "okay"; + }; + + dewarp: dewarp@ffe4130000 { + compatible = "thead,light-dewarp"; + reg = <0xff 0xe4130000 0x0 0x10000>; + interrupt-parent = <&intc>; + interrupts = <98>,<99>; + status = "okay"; + }; + + dec400_isp0: dec400@ffe4060000 { + compatible = "thead,dec400"; + reg = <0xff 0xe4060000 0x0 0x8000>; + status = "okay"; + }; + + dec400_isp1: dec400@ffe4068000 { + compatible = "thead,dec400"; + reg = <0xff 0xe4068000 0x0 0x8000>; + status = "okay"; + }; + + //isp-ry + dec400_isp2: dec400@ffe4070000 { + compatible = "thead,dec400"; + reg = <0xff 0xe4070000 0x0 0x8000>; + status = "okay"; + }; + + bm_visys: bm_visys@ffe4040000 { + compatible = "thead,light-bm-visys"; + reg = <0xff 0xe4040000 0x0 0x10000>; + status = "okay"; + }; + + bm_csi0: csi@ffe4000000{ + compatible = "thead,light-bm-csi"; + reg = < 0xff 0xe4000000 0x0 0x10000>; + interrupt-parent = <&intc>; + interrupts = <128>; + dphyglueiftester = <0x180>; + status = "okay"; + //status = "disabled"; + }; + + bm_csi1: csi@ffe4020000{ + compatible = "thead,light-bm-csi"; + reg = < 0xff 0xe4020000 0x0 0x10000>; + interrupt-parent = <&intc>; + interrupts = <127>; + dphyglueiftester = <0x184>; + status = "okay"; + //status = "disabled"; + }; + + bm_isp0: bm_isp@ffe4100000 { + compatible = "thead,light-bm-isp"; + reg = <0xff 0xe4100000 0x0 0x10000>; + status = "okay"; + }; + + bm_isp1: bm_isp@ffe4110000 { + compatible = "thead,light-bm-isp"; + reg = <0xff 0xe4110000 0x0 0x10000>; + //status = "okay"; + status = "disabled"; + }; + + //isp-ry + bm_isp2: bm_isp@ffe4120000 { + compatible = "thead,light-bm-isp"; + reg = <0xff 0xe4120000 0x0 0x10000>; + //status = "okay"; + status = "disabled"; + }; + + vi_pre: vi_pre@ffe4030000 { + compatible = "thead,vi_pre"; + reg = <0xff 0xe4030000 0x0 0x1000>; + status = "okay"; + }; + + xtensa_dsp: dsp@01{ + compatible = "thead,dsp-hw-common"; + reg = <0xff 0xef040000 0x0 0x001000 >; /*DSP_SYSREG(0x0000-0xFFF) */ + }; + + xtensa_dsp0: dsp@0 { + compatible = "cdns,xrp-hw-simple"; + reg = <0xff 0xe4040190 0x0 0x000010 /* host irq DSP->CPU INT Register */ + 0xff 0xe40401e0 0x0 0x000010 /* device irq CPU->DSP INT Register */ + 0xff 0xef048000 0x0 0x008000 /*DSP_APB(0x0000-0xFFF) */ + 0x00 0x90000000 0x0 0x00001000 /* DSP communication area */ + 0x0 0x90001000 0x0 0x00fff000>; /* DSP shared memory */ + dsp = <0>; + dspsys-rst-bit = <8>; /*bit# in DSP_SYSREG*/ + dspsys-bus-offset = <0x90>; /*in DSP_SYSREG*/ + device-irq = <0x4 1 24>; /*0xff 0xe40401e4 offset to clear DSP I]RQ, bit#, IRQ# */ + device-irq-host-offset = <0x8>; /*0xff 0xe40401e8 offset to trigger DSP IRQ*/ + device-irq-mode = <1>; /*level trigger*/ + host-irq = <0x4 1>; /*0xff 0xe4040194 offset to clear, bit# */ + host-irq-mode = <1>; /*level trigger */ + host-irq-offset = <0x8>; /* 0xff 0xe4040198 offset to trigger ,device side*/ + interrupt-parent = <&intc>; + interrupts = <156>; + firmware-name = "xrp0.elf"; + ranges = <0x00 0x70000000 0x00 0x70000000 0x00 0x40000000 + 0x00 0xfa000000 0xff 0xe0000000 0x00 0x00180000 + 0x00 0xe0180000 0xff 0xe0180000 0x00 0x00040000 + 0x00 0xffc00000 0xff 0xe4000000 0x00 0x00200000 >; /* VISYS_R */ + dsp@0 { + ranges = <0x00 0x70000000 0x00 0x70000000 0x00 0x40000000 + 0x00 0xfa000000 0xff 0xe0000000 0x00 0x00180000 + 0x00 0xe0180000 0xff 0xe0180000 0x00 0x00040000 + 0x00 0xffc00000 0xff 0xe4000000 0x00 0x00200000 >; /* VISYS_R */ + + }; + }; + + + xtensa_dsp1: dsp@1 { + compatible = "cdns,xrp-hw-simple"; + reg = <0xff 0xe40401a0 0x0 0x000010 /* host irq DSP->CPU INT Register */ + 0xff 0xe40401d0 0x0 0x000010 /* device irq CPU->DSP INT Register */ + 0xff 0xef050000 0x0 0x008000 /*DSP_APB(0x0000-0xFFF) */ + 0x00 0xa0000000 0x0 0x00001000 /* DSP communication area */ + 0x0 0xa0001000 0x0 0x00fff000>; /* DSP shared memory */ + dsp = <1>; + dspsys-rst-bit = <8>; /*bit# in DSP_SYSREG*/ + dspsys-bus-offset = <0x90>; /*in DSP_SYSREG*/ + device-irq = <0x4 1 24>; /*0xff 0xe40401e4 offset to clear DSP I]RQ, bit#, IRQ# */ + device-irq-host-offset = <0x8>; /*0xff 0xe40401e8 offset to trigger DSP IRQ*/ + device-irq-mode = <1>; /*level trigger*/ + host-irq = <0x4 1>; /*0xff 0xe4040194 offset to clear, bit# */ + host-irq-mode = <1>; /*level trigger */ + host-irq-offset = <0x8>; /* 0xff 0xe4040198 offset to trigger ,device side*/ + interrupt-parent = <&intc>; + interrupts = <157>; + firmware-name = "xrp1.elf"; + status = "disabled"; + ranges = <0x00 0x70000000 0x00 0x70000000 0x00 0x40000000 + 0x00 0xfa000000 0xff 0xe0000000 0x00 0x00180000 + 0x00 0xe0180000 0xff 0xe01C0000 0x00 0x00040000 + 0x00 0xffc00000 0xff 0xe4000000 0x00 0x00200000 >; /* VISYS_R */ + dsp@0 { + ranges = <0x00 0x70000000 0x00 0x70000000 0x00 0x40000000 + 0x00 0xfa000000 0xff 0xe0000000 0x00 0x00180000 + 0x00 0xe0180000 0xff 0xe01C0000 0x00 0x00040000 + 0x00 0xffc00000 0xff 0xe4000000 0x00 0x00200000 >; /* VISYS_R */ + + }; + }; + + + + pmp: pmp@ffdc020000 { + compatible = "pmp"; + reg = <0xff 0xdc020000 0x0 0x1000>; + }; + + mrvbr: mrvbr@ffff019050{ + compatible = "mrvbr"; + reg = <0xff 0xff019050 0x0 0x1000>; + }; + + mrmr: mrmr@ffff015004 { + compatible = "mrmr"; + reg = <0xff 0xff015004 0x0 0x1000>; + }; + }; + + chosen { + bootargs = "console=ttyS0,115200 crashkernel=256M-:128M sram=0xffe0000000,0x180000"; + linux,initrd-start = <0x0 0x2000000>; + linux,initrd-end = <0x0 0x0>; + //bootargs = "console=ttyS0,115200 crashkernel=256M-:128M sram=0xffe0000000,0x180000 rdinit=/sbin/init root=/dev/nfs rw nfsroot=172.16.150.200:/home/share.dir/nfs/lucz/nfs_root,v3,tcp,nolock ip=172.16.150.233::172.16.150.254:255.255.255.0 rootwait"; + //bootargs = "console=ttyS0,115200 crashkernel=256M-:128M sram=0xffe0000000,0x180000 rdinit=/sbin/init root=/dev/nfs rw nfsroot=172.16.150.200:/home/share.dir/nfs/lucz/nfs_root,v3,tcp,nolock ip=172.18.80.233::172.18.80.254:255.255.255.0 rootwait"; + stdout-path = "/soc/serial@fff7014000:115200"; + }; +}; + diff --git a/driver/xrp-kernel/.deps/.dirstamp b/driver/xrp-kernel/.deps/.dirstamp new file mode 100644 index 0000000..e69de29 diff --git a/driver/xrp-kernel/.deps/libxrp_host_standalone_a-xrp_alloc.Po b/driver/xrp-kernel/.deps/libxrp_host_standalone_a-xrp_alloc.Po new file mode 100644 index 0000000..511d2a3 --- /dev/null +++ b/driver/xrp-kernel/.deps/libxrp_host_standalone_a-xrp_alloc.Po @@ -0,0 +1,192 @@ +../xrp-kernel/libxrp_host_standalone_a-xrp_alloc.o: \ + ../xrp-kernel/xrp_alloc.c \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/errno.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/yvals.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/yvals.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/config/core-isa.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/lib/xcc/include/stdarg.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/sys/reent.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stdio.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/stdio.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/mbstatet.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_scmpr.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/wchar.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/xwcstod.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/xwstr.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/fenv.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/ymath.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/ymath.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stdbool.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stddef.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/stddef.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stdlib.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/stdlib.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/alloca.h \ + ../xrp-common/xrp_debug.h ../xrp-kernel/xrp_private_alloc.h \ + ../xrp-kernel/xrp_alloc.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stdint.h \ + xrp_atomic.h thread-xos/xrp_thread_impl.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_types.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/hal.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/config/core.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xtensa-versions.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xtensa-types.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/config/core-matmap.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/config/tie.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/hal-certified.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/hal-compat.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/core-macros.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/corebits.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_core.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_interrupt.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_timer.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_externalregisters.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_coprocessors.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/intctrl.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/core-macros-compat.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_common.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/config/system.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_params.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_errors.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_regaccess.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_log.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_thread.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_cond.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_event.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_mutex.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_msgq.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_semaphore.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_blockmem.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_barrier.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_timer.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_stopwatch.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_syslog.h + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/errno.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/yvals.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/yvals.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/config/core-isa.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/lib/xcc/include/stdarg.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/sys/reent.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stdio.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/stdio.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/mbstatet.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_scmpr.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/wchar.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/xwcstod.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/xwstr.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/fenv.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/ymath.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/ymath.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stdbool.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stddef.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/stddef.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stdlib.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/stdlib.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/alloca.h: + +../xrp-common/xrp_debug.h: + +../xrp-kernel/xrp_private_alloc.h: + +../xrp-kernel/xrp_alloc.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stdint.h: + +xrp_atomic.h: + +thread-xos/xrp_thread_impl.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_types.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/hal.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/config/core.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xtensa-versions.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xtensa-types.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/config/core-matmap.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/config/tie.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/hal-certified.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/hal-compat.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/core-macros.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/corebits.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_core.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_interrupt.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_timer.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_externalregisters.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_coprocessors.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/intctrl.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/core-macros-compat.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_common.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/config/system.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_params.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_errors.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_regaccess.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_log.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_thread.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_cond.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_event.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_mutex.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_msgq.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_semaphore.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_blockmem.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_barrier.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_timer.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_stopwatch.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_syslog.h: diff --git a/driver/xrp-kernel/.dirstamp b/driver/xrp-kernel/.dirstamp new file mode 100644 index 0000000..e69de29 diff --git a/driver/xrp-kernel/Kconfig b/driver/xrp-kernel/Kconfig new file mode 100644 index 0000000..8b5dd9f --- /dev/null +++ b/driver/xrp-kernel/Kconfig @@ -0,0 +1,49 @@ +# +# Xtensa Remote Processing kernel driver +# + +config XRP + tristate "XRP driver" + help + This is the core of Cadence Xtensa Remote Processing driver. + It should be enabled to support applications communicating with + Xtensa DSPs through the XRP API. + + If unsure, say N. + + To compile this driver as a module, choose M here: the + module will be called xrp. + +config XRP_DEBUG + bool "Debug XRP" + depends on XRP + help + This enables verbose debug output of the XRP driver. + + If unsure, say N. + +config XRP_HW_SIMPLE + tristate "XRP for simple hardware" + depends on XRP + help + This is hardware-specific XRP kernel driver for the simple + hardware. It should be enabled to support XRP on simple hardware + platforms. + + If unsure, say N. + + To compile this driver as a module, choose M here: the + module will be called xrp_hw_simple. + +config XRP_HW_HIKEY960 + tristate "XRP for HiKey960" + depends on XRP + help + This is hardware-specific XRP kernel driver for the HiKey960 + hardware. It should be enabled to support XRP on HiKey960 + platform. + + If unsure, say N. + + To compile this driver as a module, choose M here: the + module will be called xrp_hw_hikey960. diff --git a/driver/xrp-kernel/Makefile b/driver/xrp-kernel/Makefile new file mode 100644 index 0000000..4024d40 --- /dev/null +++ b/driver/xrp-kernel/Makefile @@ -0,0 +1,63 @@ +# +# Copyright (c) 2017 Cadence Design Systems Inc. +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Alternatively you can use and distribute this file under the terms of +# the GNU General Public License version 2 or later. +# +ifdef VISYS_SYM_PATH +KBUILD_EXTRA_SYMBOLS += $(VISYS_SYM_PATH)/bm_visys/Module.symvers +else +KBUILD_EXTRA_SYMBOLS += $(shell pwd)/../../../baremetal-drivers/driver/visys/Module.symvers +endif +# export KBUILD_EXTRA_SYMBOLS +EXTRA_CFLAGS += -DWITH_VISYS_KO + + +xrp-y += xvp_main.o xrp_address_map.o xrp_alloc.o xrp_debug.o +xrp-$(CONFIG_OF) += xrp_firmware.o +xrp-$(CONFIG_CMA) += xrp_cma_alloc.o + +obj-$(CONFIG_XRP) += xrp.o +obj-$(CONFIG_XRP_HW_SIMPLE) += xrp_hw_simple.o +obj-m += xrp_hw_comm.o +obj-$(CONFIG_XRP_HW_HIKEY960) += xrp_hw_hikey960.o + +ifeq ($(BUILD_TYPE),DEBUG) + EXTRA_CFLAGS += -DDEBUG +endif +KBUILD_CFLAGS += -O2 +ccflags-$(CONFIG_XRP_DEBUG) += -DDEBUG +ccflags-$(CONFIG_XRP_HW_HIKEY960) += -I$(srctree)/drivers/hisi/hifi_mailbox + +# Remove this comment and all lines below it when integrating this Makefile +# into the linux kernel make system. +# +# sed -i % '/Remove this comment and all lines below it/,$d' +# make -C $(KERNEL) M=$(PWD) modules + +# KSRC ?= /lib/modules/$(shell uname -r)/build + +modules: + $(MAKE) -C $(KERNEL) M=`pwd` CONFIG_XRP=m CONFIG_XRP_HW_SIMPLE=m CONFIG_XRP_DEBUG=y modules + +%: + $(MAKE) -C $(KERNEL) M=`pwd` CONFIG_XRP=m $@ diff --git a/driver/xrp-kernel/README b/driver/xrp-kernel/README new file mode 100644 index 0000000..ca1896f --- /dev/null +++ b/driver/xrp-kernel/README @@ -0,0 +1,25 @@ +Driver parameters: + +- firmware_command_timeout, int: a number of seconds that the host waits for + the DSP to respond to a synchronization request or a command. Can be changed + at runtime through the following sysfs entry: + /sys/module/xrp/parameters/firmware_command_timeout + +- firmware_reboot, 0/1: controls whether the driver reboots firmware on + command timeout. Enabled by default and can be changed at runtime through + the following sysfs entry: /sys/module/xrp/parameters/firmware_reboot + +- loopback, 0/1/2/3: controls level of interaction between the driver and + the firmware. + 0: normal operation. The driver loads firmware, controls DSP and interacts + with the firmware through shared memory; + 1: no-communication loopback. The driver loads the firmware and controls + DSP, but does not communicate with firmware. Initial synchronization + is not performed and command submission is completed immediately after + all normal preparation steps related to buffer mapping. Communication + area is not touched by the driver. + 2: no-control loopback. The driver loads the firmware, but does not control + DSP nor does it communicate with the firmware. Neither communication + area nor DSP MMIO area are touched by the driver. + 3: no-firmware loopback. The driver doesn't load firmware, doesn't control + DSP and doesn't communicate with DSP. diff --git a/driver/xrp-kernel/cdns,xrp,cma.txt b/driver/xrp-kernel/cdns,xrp,cma.txt new file mode 100644 index 0000000..ea437e9 --- /dev/null +++ b/driver/xrp-kernel/cdns,xrp,cma.txt @@ -0,0 +1,59 @@ +Bindings for the Cadence Xtensa Remote Processing driver, CMA mode. +In CMA mode DSP communication area and shared memory are allocated from the +CMA-managed reserved memory region assigned to the XRP device. + +Required properties: +- compatible: shall be "cdns,xrp,cma". +- memory-region: phandle, refers to a child node inside reserved-memory node. + +Optional properties: +- queue-priority: cells indicating priorities of DSP hardware queues. If + missing then single default queue is configured. +- firmware-name: string identifying firmware name. If missing the driver + doesn't load the firmware. + +- #address-cells: number of cells DSP physical address takes in the ranges. +- #size-cells: number of cells each size takes in the ranges. +- ranges: standard ranges property. Provides mapping of DSP physical addresses + to host physical addresses. Arbitrary number of groups with the following + structure: + - cells with DSP physical address of the region; + - cells with the corresponding host physical address of the + region; + - cells with the size of the region. + Ranges must cover addresses of the reserved memory pointed to by the + memory-region property. + +XRP node may have an optional subnode when there's non-identity mapping set +up in the ranges property. Both subnode and ranges property are required in +order for the address translation to work. + +Example: + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + xrp_reserved: xrp@08000000 { + compatible = "shared-dma-pool"; + reg = <0x08000000 0x08000000>; + reusable; + }; + }; + + xrp@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "cdns,xrp,cma"; + memory-region = <&xrp_reserved>; + queue-priority = <0 1 2>; + firmware-name = "xrp0.elf"; + ranges = <0x00000000 0x00000000 0x10000000 + 0x3ffc0000 0xc0000000 0x00020000 + 0x3ffe0000 0xc0020000 0x00020000 + 0x50000000 0x50000000 0x01000000 + 0x60000000 0x60000000 0x20000000 + 0xf0000000 0xf0000000 0x0d000000>; + dsp@0 { + }; + }; diff --git a/driver/xrp-kernel/cdns,xrp,v1.txt b/driver/xrp-kernel/cdns,xrp,v1.txt new file mode 100644 index 0000000..0cba5f4 --- /dev/null +++ b/driver/xrp-kernel/cdns,xrp,v1.txt @@ -0,0 +1,43 @@ +Bindings for the Cadence Xtensa Remote Processing driver, v.1. + +Required properties: +- compatible: shall be "cdns,xrp,v1". +- reg: location of DSP shared memory area. + +Optional properties: +- queue-priority: cells indicating priorities of DSP hardware queues. If + missing then single default queue is configured. +- firmware-name: string identifying firmware name. If missing the driver + doesn't load the firmware. + +- #address-cells: number of cells DSP physical address takes in the ranges. +- #size-cells: number of cells each size takes in the ranges. +- ranges: standard ranges property. Provides mapping of DSP physical addresses + to host physical addresses. Arbitrary number of groups with the following + structure: + - cells with DSP physical address of the region; + - cells with the corresponding host physical address of the + region; + - cells with the size of the region. + +XRP node may have an optional subnode when there's non-identity mapping set +up in the ranges property. Both subnode and ranges property are required in +order for the address translation to work. + +Example: + + xrp@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "cdns,xrp,v1"; + reg = <0xf0000000 0x01000000>; + firmware-name = "xrp0.elf"; + ranges = <0x00000000 0x00000000 0x10000000 + 0x3ffc0000 0xc0000000 0x00020000 + 0x3ffe0000 0xc0020000 0x00020000 + 0x50000000 0x50000000 0x01000000 + 0x60000000 0x60000000 0x20000000 + 0xf0000000 0xf0000000 0x0d000000>; + dsp@0 { + }; + }; diff --git a/driver/xrp-kernel/cdns,xrp-hw-hikey960,cma.txt b/driver/xrp-kernel/cdns,xrp-hw-hikey960,cma.txt new file mode 100644 index 0000000..ce93b8d --- /dev/null +++ b/driver/xrp-kernel/cdns,xrp-hw-hikey960,cma.txt @@ -0,0 +1,52 @@ +Bindings for the Cadence Xtensa Remote Processing HW-specific driver for +HiKey960. + +This binding is an extension of the cdns,xrp,cma binding. All properties of +that binding are in effect. + +Required properties: +- compatible: shall be "cdns,xrp-hw-hikey960,cma". + +Optional properties: +- reg: panic/log buffer location. +- device-irq: 1 32-bit cell: DSP IRQ number (normal core IRQ number, not + external IRQ number) assigned to the egress mailbox. +- host-irq: 1 32-bit cell, when present enables IRQ usage in DSP->host + direction. + +Example: + + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + xrp_reserved: xrp@60000000 { + compatible = "shared-dma-pool"; + reg = <0x0 0x60000000 0x0 0x10000000>; + reusable; + }; + }; + + xrp@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "cdns,xrp-hw-simple,cma"; + memory-region = <&xrp_reserved>; + reg = < + 0x0 0x8b300000 0x0 0x00001000 /* Panic/log page */ + >; + device-irq = <3>; + host-irq = <0>; + firmware-name = "xrp0.elf"; + ranges = < + 0x00000000 0x0 0x00000000 0x89200000 + 0x89cc0000 0x0 0x89cc0000 0x06340000 + 0x90000000 0x0 0x90000000 0x30000000 + 0xc0000000 0x0 0x89200000 0x00600000 + 0xe8000000 0x0 0x89800000 0x00030000 + 0xe8058000 0x0 0x89830000 0x00031000 + >; + dsp@0 { + }; + }; diff --git a/driver/xrp-kernel/cdns,xrp-hw-hikey960,v1.txt b/driver/xrp-kernel/cdns,xrp-hw-hikey960,v1.txt new file mode 100644 index 0000000..35ecfe5 --- /dev/null +++ b/driver/xrp-kernel/cdns,xrp-hw-hikey960,v1.txt @@ -0,0 +1,41 @@ +Bindings for the Cadence Xtensa Remote Processing HW-specific driver for +HiKey960. + +This binding is an extension of the cdns,xrp,v1 binding. All properties of +that binding are in effect. + +Required properties: +- compatible: shall be "cdns,xrp-hw-hikey960,v1". +- reg: register locations of the DSP shared memory (first entry, same as in + cdns,xrp,v1) panic/log buffer location (second entry, optional). + +Optional properties: +- device-irq: 1 32-bit cell: DSP IRQ number (normal core IRQ number, not + external IRQ number) assigned to the egress mailbox. +- host-irq: 1 32-bit cell, when present enables IRQ usage in DSP->host + direction. + +Example: + + xrp@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "cdns,xrp-hw-simple,v1"; + reg = < + 0x0 0x8b301000 0x0 0x0037f000 /* Shared memory */ + 0x0 0x8b300000 0x0 0x00001000 /* Panic/log page */ + >; + device-irq = <3>; + host-irq = <0>; + firmware-name = "xrp0.elf"; + ranges = < + 0x00000000 0x0 0x00000000 0x89200000 + 0x89cc0000 0x0 0x89cc0000 0x06340000 + 0x90000000 0x0 0x90000000 0x30000000 + 0xc0000000 0x0 0x89200000 0x00600000 + 0xe8000000 0x0 0x89800000 0x00030000 + 0xe8058000 0x0 0x89830000 0x00031000 + >; + dsp@0 { + }; + }; diff --git a/driver/xrp-kernel/cdns,xrp-hw-simple,cma.txt b/driver/xrp-kernel/cdns,xrp-hw-simple,cma.txt new file mode 100644 index 0000000..ea8dbdd --- /dev/null +++ b/driver/xrp-kernel/cdns,xrp-hw-simple,cma.txt @@ -0,0 +1,65 @@ +Bindings for the Cadence Xtensa Remote Processing Simple HW-specific driver. + +This binding is an extension of the cdns,xrp,cma binding. All properties of +that binding are in effect. + +Required properties: +- compatible: shall be "cdns,xrp-hw-simple,cma". +- reg: register location of the DSP MMIO block. + +Optional properties: +- device-irq: 3 32-bit cells: + - first: offset of the 32-bit device IRQ MMIO register from the DSP MMIO + block start as seen by the device; + - second: register bit index that controls IRQ; + - third: DSP IRQ number (normal core IRQ number, not external IRQ number) + controlled by this register/bit. +- device-irq-host-offset: offset of the 32-bit device IRQ MMIO register from + the DSP MMIO block start as seen by the host. If omitted device-irq cell 0 + is used; +- device-irq-mode: 0 for none (polling), 1 for level, 2 for edge, 3 for + software-assisted (by LUA script in the XTSC) edge. + +- host-irq: 2 32-bit cells: + - first: offset of the 32-bit device IRQ MMIO register from the DSP MMIO + block start; + - second: register bit index that controls IRQ. +- host-irq-mode: 0 for none (polling), 1 for level, 2 for edge. +- interrupts: host IRQ number controlled by this register/bit. + +Example: + + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + xrp_reserved: xrp@08000000 { + compatible = "shared-dma-pool"; + reg = <0x08000000 0x08000000>; + reusable; + }; + }; + + xrp@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "cdns,xrp-hw-simple,cma"; + memory-region = <&xrp_reserved>; + reg = <0xfd001000 0x00000200>; /* DSP MMIO */ + device-irq = <0 1 5>; /* offset, bit#, IRQ# */ + device-irq-host-offset = <0>; + device-irq-mode = <1>; + host-irq = <0xfffff000 0>; /* offset, bit# */ + host-irq-mode = <2>; + interrupts = <15 0>; + firmware-name = "xrp0.elf"; + ranges = <0x00000000 0x00000000 0x10000000 + 0x3ffc0000 0xc0000000 0x00020000 + 0x3ffe0000 0xc0020000 0x00020000 + 0x50000000 0x50000000 0x01000000 + 0x60000000 0x60000000 0x20000000 + 0xf0000000 0xf0000000 0x0d000000>; + dsp@0 { + }; + }; diff --git a/driver/xrp-kernel/cdns,xrp-hw-simple,v1.txt b/driver/xrp-kernel/cdns,xrp-hw-simple,v1.txt new file mode 100644 index 0000000..8f56250 --- /dev/null +++ b/driver/xrp-kernel/cdns,xrp-hw-simple,v1.txt @@ -0,0 +1,54 @@ +Bindings for the Cadence Xtensa Remote Processing Simple HW-specific driver. + +This binding is an extension of the cdns,xrp,v1 binding. All properties of +that binding are in effect. + +Required properties: +- compatible: shall be "cdns,xrp-hw-simple,v1". +- reg: register locations of the DSP shared memory (first entry, same as in + cdns,xrp,v1) and DSP MMIO block (second entry). + +Optional properties: +- device-irq: 3 32-bit cells: + - first: offset of the 32-bit device IRQ MMIO register from the DSP MMIO + block start as seen by the device; + - second: register bit index that controls IRQ; + - third: DSP IRQ number (normal core IRQ number, not external IRQ number) + controlled by this register/bit. +- device-irq-host-offset: offset of the 32-bit device IRQ MMIO register from + the DSP MMIO block start as seen by the host. If omitted device-irq cell 0 + is used; +- device-irq-mode: 0 for none (polling), 1 for level, 2 for edge, 3 for + software-assisted (by LUA script in the XTSC) edge. + +- host-irq: 2 32-bit cells: + - first: offset of the 32-bit device IRQ MMIO register from the DSP MMIO + block start; + - second: register bit index that controls IRQ. +- host-irq-mode: 0 for none (polling), 1 for level, 2 for edge. +- interrupts: host IRQ number controlled by this register/bit. + +Example: + + xrp@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "cdns,xrp-hw-simple,v1"; + reg = <0xf0000000 0x01000000 /* DSP shared memory */ + 0xfd001000 0x00000200>; /* DSP MMIO */ + device-irq = <0 1 5>; /* offset, bit#, IRQ# */ + device-irq-host-offset = <0>; + device-irq-mode = <1>; + host-irq = <0xfffff000 0>; /* offset, bit# */ + host-irq-mode = <2>; + interrupts = <15 0>; + firmware-name = "xrp0.elf"; + ranges = <0x00000000 0x00000000 0x10000000 + 0x3ffc0000 0xc0000000 0x00020000 + 0x3ffe0000 0xc0020000 0x00020000 + 0x50000000 0x50000000 0x01000000 + 0x60000000 0x60000000 0x20000000 + 0xf0000000 0xf0000000 0x0d000000>; + dsp@0 { + }; + }; diff --git a/driver/xrp-kernel/cdns,xrp-hw-simple.txt b/driver/xrp-kernel/cdns,xrp-hw-simple.txt new file mode 100644 index 0000000..38cfe1a --- /dev/null +++ b/driver/xrp-kernel/cdns,xrp-hw-simple.txt @@ -0,0 +1,55 @@ +Bindings for the Cadence Xtensa Remote Processing Simple HW-specific driver. + +This binding is an extension of the cdns,xrp binding. All properties of +that binding are in effect. + +Required properties: +- compatible: shall be "cdns,xrp-hw-simple". +- reg: register locations of the DSP MMIO block, DSP communication area and + DSP shared memory area. + +Optional properties: +- device-irq: 3 32-bit cells: + - first: offset of the 32-bit device IRQ MMIO register from the DSP MMIO + block start as seen by the device; + - second: register bit index that controls IRQ; + - third: DSP IRQ number (normal core IRQ number, not external IRQ number) + controlled by this register/bit. +- device-irq-host-offset: offset of the 32-bit device IRQ MMIO register from + the DSP MMIO block start as seen by the host. If omitted device-irq cell 0 + is used; +- device-irq-mode: 0 for none (polling), 1 for level, 2 for edge, 3 for + software-assisted (by LUA script in the XTSC) edge. + +- host-irq: 2 32-bit cells: + - first: offset of the 32-bit device IRQ MMIO register from the DSP MMIO + block start; + - second: register bit index that controls IRQ. +- host-irq-mode: 0 for none (polling), 1 for level, 2 for edge. +- interrupts: host IRQ number controlled by this register/bit. + +Example: + + xrp@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "cdns,xrp-hw-simple"; + reg = <0xfd001000 0x00000200 /* DSP MMIO */ + 0xf0000000 0x00001000 /* DSP communication area */ + 0xf0001000 0x00fff000>; /* DSP shared memory */ + device-irq = <0 1 5>; /* offset, bit#, IRQ# */ + device-irq-host-offset = <0>; + device-irq-mode = <1>; + host-irq = <0xfffff000 0>; /* offset, bit# */ + host-irq-mode = <2>; + interrupts = <15 0>; + firmware-name = "xrp0.elf"; + ranges = <0x00000000 0x00000000 0x10000000 + 0x3ffc0000 0xc0000000 0x00020000 + 0x3ffe0000 0xc0020000 0x00020000 + 0x50000000 0x50000000 0x01000000 + 0x60000000 0x60000000 0x20000000 + 0xf0000000 0xf0000000 0x0d000000>; + dsp@0 { + }; + }; diff --git a/driver/xrp-kernel/cdns,xrp.txt b/driver/xrp-kernel/cdns,xrp.txt new file mode 100644 index 0000000..f41d9ef --- /dev/null +++ b/driver/xrp-kernel/cdns,xrp.txt @@ -0,0 +1,46 @@ +Bindings for the Cadence Xtensa Remote Processing driver. + +Required properties: +- compatible: shall be "cdns,xrp". +- reg: register locations of the DSP MMIO block, DSP communication area and + DSP shared memory area. + +Optional properties: +- queue-priority: cells indicating priorities of DSP hardware queues. If + missing then single default queue is configured. +- firmware-name: string identifying firmware name. If missing the driver + doesn't load the firmware. + +- #address-cells: number of cells DSP physical address takes in the ranges. +- #size-cells: number of cells each size takes in the ranges. +- ranges: standard ranges property. Provides mapping of DSP physical addresses + to host physical addresses. Arbitrary number of groups with the following + structure: + - cells with DSP physical address of the region; + - cells with the corresponding host physical address of the + region; + - cells with the size of the region. + +XRP node may have an optional subnode when there's non-identity mapping set +up in the ranges property. Both subnode and ranges property are required in +order for the address translation to work. + +Example: + + xrp@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "cdns,xrp"; + reg = <0xfd001000 0x00000200 /* DSP MMIO */ + 0xf0000000 0x00001000 /* DSP communication area */ + 0xf0001000 0x00fff000>; /* DSP shared memory */ + firmware-name = "xrp0.elf"; + ranges = <0x00000000 0x00000000 0x10000000 + 0x3ffc0000 0xc0000000 0x00020000 + 0x3ffe0000 0xc0020000 0x00020000 + 0x50000000 0x50000000 0x01000000 + 0x60000000 0x60000000 0x20000000 + 0xf0000000 0xf0000000 0x0d000000>; + dsp@0 { + }; + }; diff --git a/driver/xrp-kernel/insmod.sh b/driver/xrp-kernel/insmod.sh new file mode 100644 index 0000000..bba4e20 --- /dev/null +++ b/driver/xrp-kernel/insmod.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +# mkdir /tmp/debugfs +# mount -t debugfs none /tmp/debugfs +# echo -n 'file xvp_main.c +p' > /tmp/debugfs/dynamic_debug/control +# echo -n 'file xrp_hw_simple.c +p' > /tmp/debugfs/dynamic_debug/control +# echo -n 'file xrp_firmware.c +p' > /tmp/debugfs/dynamic_debug/control +# echo 8 > /proc/sys/kernel/printk +modprobe xrp_hw_comm +modprobe xrp +# echo 1 > /sys/module/xrp/parameters/loopback +modprobe xrp_hw_simple \ No newline at end of file diff --git a/driver/xrp-kernel/insmod_load_fw_man.sh b/driver/xrp-kernel/insmod_load_fw_man.sh new file mode 100644 index 0000000..2e5e952 --- /dev/null +++ b/driver/xrp-kernel/insmod_load_fw_man.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +mkdir /tmp/debugfs +mount -t debugfs none /tmp/debugfs +echo -n 'file xvp_main.c +p' > /tmp/debugfs/dynamic_debug/control +echo -n 'file xrp_hw_simple.c +p' > /tmp/debugfs/dynamic_debug/control +echo -n 'file xrp_firmware.c +p' > /tmp/debugfs/dynamic_debug/control +echo 8 > /proc/sys/kernel/printk +modprobe xrp_hw_comm +modprobe xrp +# echo 1 > /sys/module/xrp/parameters/loopback +#increase the timeout time 2 min +echo 120 > /sys/module/xrp/parameters/firmware_command_timeout +echo 1 > /sys/module/xrp/parameters/load_mode + +memtool mw 0xffe7f3c408 0x11000000 +memtool mw 0xffe7f3c40c 0x111 +memtool mw 0xffe7f3c410 0x11111 + +modprobe xrp_hw_simple \ No newline at end of file diff --git a/driver/xrp-kernel/rmmod.sh b/driver/xrp-kernel/rmmod.sh new file mode 100755 index 0000000..3ee66d5 --- /dev/null +++ b/driver/xrp-kernel/rmmod.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +# echo 1 > /sys/module/xrp/parameters/loopback +rmmod xrp_hw_simple.ko +rmmod xrp.ko +rmmod xrp_hw_comm.ko \ No newline at end of file diff --git a/driver/xrp-kernel/xrp_address_map.c b/driver/xrp-kernel/xrp_address_map.c new file mode 100644 index 0000000..14c9387 --- /dev/null +++ b/driver/xrp-kernel/xrp_address_map.c @@ -0,0 +1,173 @@ +/* + * xrp_address_map: CPU->DSP physical address translator + * + * Copyright (c) 2017 Cadence Design Systems, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Alternatively you can use and distribute this file under the terms of + * the GNU General Public License version 2 or later. + */ + +#include +#include +#include +#include +#include +#include +#include "xrp_address_map.h" + +#if IS_ENABLED(CONFIG_OF) +static int xrp_compare_address_sort(const void *a, const void *b) +{ + const struct xrp_address_map_entry *pa = a; + const struct xrp_address_map_entry *pb = b; + + if (pa->src_addr < pb->src_addr && + pb->src_addr - pa->src_addr >= pa->size) + return -1; + if (pa->src_addr > pb->src_addr && + pa->src_addr - pb->src_addr >= pb->size) + return 1; + return 0; +} +#endif + +int xrp_init_address_map(struct device *dev, + struct xrp_address_map *map) +{ + int ret = 0; +#if IS_ENABLED(CONFIG_OF) + struct device_node *pnode = dev->of_node; + struct device_node *node; + int rlen, off; + const __be32 *ranges = of_get_property(pnode, "ranges", &rlen); + int na, pna, ns; + int i; + + if (!ranges) { + dev_dbg(dev, "%s: no 'ranges' property in the device tree, no translation at that level\n", + __func__); + goto empty; + } + + node = of_get_next_child(pnode, NULL); + if (!node) { + dev_warn(dev, "%s: no child node found in the device tree, no translation at that level\n", + __func__); + goto empty; + } + + na = of_n_addr_cells(node); + ns = of_n_size_cells(node); + pna = of_n_addr_cells(pnode); + + rlen /= 4; + map->n = rlen / (na + pna + ns); + map->entry = kmalloc_array(map->n, sizeof(*map->entry), GFP_KERNEL); + if (!map->entry) { + ret = -ENOMEM; + goto err; + } + dev_dbg(dev, + "%s: na = %d, pna = %d, ns = %d, rlen = %d cells, n = %d\n", + __func__, na, pna, ns, rlen, map->n); + + for (off = 0, i = 0; off < rlen; off += na + pna + ns, ++i) { + map->entry[i].src_addr = of_translate_address(node, + ranges + off); + map->entry[i].dst_addr = of_read_number(ranges + off, na); + map->entry[i].size = of_read_number(ranges + off + na + pna, + ns); + dev_dbg(dev, + " src_addr = 0x%llx, dst_addr = 0x%lx, size = 0x%lx\n", + (unsigned long long)map->entry[i].src_addr, + (unsigned long)map->entry[i].dst_addr, + (unsigned long)map->entry[i].size); + } + sort(map->entry, map->n, sizeof(*map->entry), + xrp_compare_address_sort, NULL); +err: + of_node_put(node); + return ret; + +empty: +#endif + map->n = 1; + map->entry = kmalloc(sizeof(*map->entry), GFP_KERNEL); + map->entry->src_addr = 0; + map->entry->dst_addr = 0; + map->entry->size = ~0ul; + return ret; +} + +void xrp_free_address_map(struct xrp_address_map *map) +{ + if(!map->entry) + kfree(map->entry); +} + +static int xrp_compare_address_search(const void *a, const void *b) +{ + const phys_addr_t *pa = a; + return xrp_compare_address(*pa, b); +} + +struct xrp_address_map_entry * +xrp_get_address_mapping(const struct xrp_address_map *map, phys_addr_t addr) +{ + struct xrp_address_map_entry *entry = + bsearch(&addr, map->entry, map->n, sizeof(*map->entry), + xrp_compare_address_search); + return entry; +} + +u32 xrp_translate_to_dsp(const struct xrp_address_map *map, phys_addr_t addr) +{ + struct xrp_address_map_entry *entry = xrp_get_address_mapping(map, addr); + + if (!entry) + return XRP_NO_TRANSLATION; + return entry->dst_addr + addr - entry->src_addr; +} + +phys_addr_t xrp_translate_dsp_to_host(const struct xrp_address_map *map,u32 addr) +{ + int loop; + struct xrp_address_map_entry *entry=NULL; + for(loop=0;loopn;loop++) + { + + if((map->entry[loop].dst_addr<=addr) && + ((map->entry[loop].dst_addr+map->entry[loop].size)>addr)) + { + // pr_debug("%s\n",__func__); + entry= &map->entry[loop]; + break; + } + } + if(entry == NULL) + { + return (phys_addr_t)OF_BAD_ADDR; + } + pr_debug("%s,entry(%d),device:(0x%08x,0x%08x),target:0x%08x\n", + __func__,loop,entry->dst_addr,entry->dst_addr+entry->size,addr); + return entry->src_addr+addr-entry->dst_addr; +} \ No newline at end of file diff --git a/driver/xrp-kernel/xrp_address_map.h b/driver/xrp-kernel/xrp_address_map.h new file mode 100644 index 0000000..61f32bc --- /dev/null +++ b/driver/xrp-kernel/xrp_address_map.h @@ -0,0 +1,78 @@ +/* + * xrp_address_map: CPU->DSP physical address translator + * + * Copyright (c) 2017 Cadence Design Systems, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Alternatively you can use and distribute this file under the terms of + * the GNU General Public License version 2 or later. + */ + +#ifndef XRP_ADDRESS_MAP_H +#define XRP_ADDRESS_MAP_H + +#include + +#define XRP_NO_TRANSLATION ((u32)~0ul) + +struct xrp_address_map_entry { + phys_addr_t src_addr; + u32 dst_addr; + u32 size; +}; + +struct xrp_address_map { + unsigned n; + struct xrp_address_map_entry *entry; +}; + +int xrp_init_address_map(struct device *dev, + struct xrp_address_map *map); + +void xrp_free_address_map(struct xrp_address_map *map); + +struct xrp_address_map_entry * +xrp_get_address_mapping(const struct xrp_address_map *map, phys_addr_t addr); + +u32 xrp_translate_to_dsp(const struct xrp_address_map *map, phys_addr_t addr); + +phys_addr_t xrp_translate_dsp_to_host(const struct xrp_address_map *map,u32 addr); +static inline int xrp_compare_address(phys_addr_t addr, + const struct xrp_address_map_entry *entry) +{ + if (addr < entry->src_addr) + return -1; + if (addr - entry->src_addr < entry->size) + return 0; + return 1; +} + +static inline int xrp_compare_dev_address(phys_addr_t addr, + const struct xrp_address_map_entry *entry) +{ + if (addr < entry->dst_addr) + return -1; + if (addr - entry->dst_addr < entry->size) + return 0; + return 1; +} + +#endif diff --git a/driver/xrp-kernel/xrp_alloc.c b/driver/xrp-kernel/xrp_alloc.c new file mode 100644 index 0000000..2fd0b3e --- /dev/null +++ b/driver/xrp-kernel/xrp_alloc.c @@ -0,0 +1,443 @@ +/* + * Copyright (c) 2016 - 2017 Cadence Design Systems Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Alternatively you can use and distribute this file under the terms of + * the GNU General Public License version 2 or later. + */ + +#ifdef __KERNEL__ + +#include +#include +#include +#include +#include +#include +#else + +#include +#include +#include +#include +#include +#include "xrp_debug.h" + +#define PAGE_SIZE 4096 +#define GFP_KERNEL 0 +#define ALIGN(v, a) (((v) + (a) - 1) & -(a)) + +#define GET_PAGE_NUM(size, offset) ((((size) + ((offset) & ~PAGE_MASK)) + PAGE_SIZE - 1) >> PAGE_SHIFT) +static void *kmalloc(size_t sz, int flags) +{ + (void)flags; + return malloc(sz); +} + +static void *kzalloc(size_t sz, int flags) +{ + (void)flags; + return calloc(1, sz); +} + +static void kfree(void *p) +{ + free(p); +} + +#endif + +#include "xrp_private_alloc.h" + +#ifndef __KERNEL__ + +static void mutex_init(struct mutex *mutex) +{ + xrp_mutex_init(&mutex->o); +} + +static void mutex_lock(struct mutex *mutex) +{ + xrp_mutex_lock(&mutex->o); +} + +static void mutex_unlock(struct mutex *mutex) +{ + xrp_mutex_unlock(&mutex->o); +} + +static void atomic_set(atomic_t *p, uint32_t v) +{ + *((volatile atomic_t *)p) = v; +} + +#define container_of(ptr, type, member) ({ \ + void *__mptr = (void *)(ptr); \ + ((type *)(__mptr - offsetof(type, member))); }) + +#endif + +struct xrp_private_pool { + struct xrp_allocation_pool pool; + struct mutex free_list_lock; + phys_addr_t start; + u32 size; + struct xrp_allocation *free_list; +}; + +static inline void xrp_pool_lock(struct xrp_private_pool *pool) +{ + mutex_lock(&pool->free_list_lock); +} + +static inline void xrp_pool_unlock(struct xrp_private_pool *pool) +{ + mutex_unlock(&pool->free_list_lock); +} + +static void xrp_private_free(struct xrp_allocation *xrp_allocation) +{ + struct xrp_private_pool *pool = container_of(xrp_allocation->pool, + struct xrp_private_pool, + pool); + struct xrp_allocation **pcur; + + pr_debug("%s: %pap x %d\n", __func__, + &xrp_allocation->start, xrp_allocation->size); + + xrp_pool_lock(pool); + + for (pcur = &pool->free_list; ; pcur = &(*pcur)->next) { + struct xrp_allocation *cur = *pcur; + + if (cur && cur->start + cur->size == xrp_allocation->start) { + struct xrp_allocation *next = cur->next; + + pr_debug("merging block tail: %pap x 0x%x ->\n", + &cur->start, cur->size); + cur->size += xrp_allocation->size; + pr_debug("... -> %pap x 0x%x\n", + &cur->start, cur->size); + kfree(xrp_allocation); + + if (next && cur->start + cur->size == next->start) { + pr_debug("merging with next block: %pap x 0x%x ->\n", + &cur->start, cur->size); + cur->size += next->size; + cur->next = next->next; + pr_debug("... -> %pap x 0x%x\n", + &cur->start, cur->size); + kfree(next); + } + break; + } + + if (!cur || xrp_allocation->start < cur->start) { + if (cur && xrp_allocation->start + xrp_allocation->size == + cur->start) { + pr_debug("merging block head: %pap x 0x%x ->\n", + &cur->start, cur->size); + cur->size += xrp_allocation->size; + cur->start = xrp_allocation->start; + pr_debug("... -> %pap x 0x%x\n", + &cur->start, cur->size); + kfree(xrp_allocation); + } else { + pr_debug("inserting new free block\n"); + xrp_allocation->next = cur; + *pcur = xrp_allocation; + } + break; + } + } + + xrp_pool_unlock(pool); +} + +static long xrp_alloc_gfp(u32 size, u32 align,struct xrp_allocation **alloc); +static long xrp_private_alloc(struct xrp_allocation_pool *pool, + u32 size, u32 align, + struct xrp_allocation **alloc) +{ + struct xrp_private_pool *ppool = container_of(pool, + struct xrp_private_pool, + pool); + struct xrp_allocation **pcur; + struct xrp_allocation *cur = NULL; + struct xrp_allocation *new; + phys_addr_t aligned_start = 0; + bool found = false; + + if (!size || (align & (align - 1))) + return -EINVAL; + if (!align) + align = 1; + + new = kzalloc(sizeof(struct xrp_allocation), GFP_KERNEL); + if (!new) + return -ENOMEM; + + align = ALIGN(align, PAGE_SIZE); + size = ALIGN(size, PAGE_SIZE); + + xrp_pool_lock(ppool); + + /* on exit free list is fixed */ + for (pcur = &ppool->free_list; *pcur; pcur = &(*pcur)->next) { + cur = *pcur; + aligned_start = ALIGN(cur->start, align); + + if (aligned_start >= cur->start && + aligned_start - cur->start + size <= cur->size) { + if (aligned_start == cur->start) { + if (aligned_start + size == cur->start + cur->size) { + pr_debug("reusing complete block: %pap x %x\n", + &cur->start, cur->size); + *pcur = cur->next; + } else { + pr_debug("cutting block head: %pap x %x ->\n", + &cur->start, cur->size); + cur->size -= aligned_start + size - cur->start; + cur->start = aligned_start + size; + pr_debug("... -> %pap x %x\n", + &cur->start, cur->size); + cur = NULL; + } + } else { + if (aligned_start + size == cur->start + cur->size) { + pr_debug("cutting block tail: %pap x %x ->\n", + &cur->start, cur->size); + cur->size = aligned_start - cur->start; + pr_debug("... -> %pap x %x\n", + &cur->start, cur->size); + cur = NULL; + } else { + pr_debug("splitting block into two: %pap x %x ->\n", + &cur->start, cur->size); + new->start = aligned_start + size; + new->size = cur->start + + cur->size - new->start; + + cur->size = aligned_start - cur->start; + + new->next = cur->next; + cur->next = new; + pr_debug("... -> %pap x %x + %pap x %x\n", + &cur->start, cur->size, + &new->start, new->size); + + cur = NULL; + new = NULL; + } + } + found = true; + break; + } else { + cur = NULL; + } + } + + xrp_pool_unlock(ppool); + + if (!found) { + kfree(cur); + kfree(new); + if(!xrp_alloc_gfp(size,align,alloc)) + { + return 0; + } + return -ENOMEM; + } + + if (!cur) { + cur = new; + new = NULL; + } + if (!cur) { + cur = kzalloc(sizeof(struct xrp_allocation), GFP_KERNEL); + if (!cur) + return -ENOMEM; + } + if (new) + kfree(new); + + pr_debug("returning: %pap x %x\n", &aligned_start, size); + cur->start = aligned_start; + cur->size = size; + cur->pool = pool; + atomic_set(&cur->ref, 0); + xrp_allocation_get(cur); + *alloc = cur; + + return 0; +} + +static void xrp_private_free_pool(struct xrp_allocation_pool *pool) +{ + struct xrp_private_pool *ppool = container_of(pool, + struct xrp_private_pool, + pool); + kfree(ppool->free_list); + kfree(ppool); +} + +static phys_addr_t xrp_private_offset(const struct xrp_allocation *allocation) +{ + struct xrp_private_pool *ppool = container_of(allocation->pool, + struct xrp_private_pool, + pool); + return allocation->start ;//- ppool->start; +} + +static const struct xrp_allocation_ops xrp_private_pool_ops = { + .alloc = xrp_private_alloc, + .free = xrp_private_free, + .free_pool = xrp_private_free_pool, + .offset = xrp_private_offset, +}; + +long xrp_init_private_pool(struct xrp_allocation_pool **ppool, + phys_addr_t start, u32 size) +{ + struct xrp_private_pool *pool = kmalloc(sizeof(*pool), GFP_KERNEL); + struct xrp_allocation *allocation = kmalloc(sizeof(*allocation), + GFP_KERNEL); + + if (!pool || !allocation) { + kfree(pool); + kfree(allocation); + return -ENOMEM; + } + + *allocation = (struct xrp_allocation){ + .pool = &pool->pool, + .start = start, + .size = size, + }; + *pool = (struct xrp_private_pool){ + .pool = { + .ops = &xrp_private_pool_ops, + }, + .start = start, + .size = size, + .free_list = allocation, + }; + mutex_init(&pool->free_list_lock); + *ppool = &pool->pool; + return 0; +} + +static void xrp_free_gfp(struct xrp_allocation *alloc) +{ + size_t numPages; + int i; + struct page *page; + phys_addr_t phys; + if(!alloc) + return; + if(alloc->size & (PAGE_SIZE-1) || + alloc->start &(PAGE_SIZE-1)) + { + pr_debug("alloc is not aligment addr: %llx,size: %d",alloc->start,alloc->size); + return ; + } + + phys = alloc->start; + numPages = alloc->size>>PAGE_SHIFT; + for (i = 0; i < numPages; i++) + { + page = pfn_to_page(__phys_to_pfn(phys)); + ClearPageReserved(page); + phys +=PAGE_SIZE; + + } + __free_pages(pfn_to_page(__phys_to_pfn(alloc->start)), get_order(alloc->size)); + kfree(alloc->pool); + kfree(alloc); + pr_debug("free gfp alloc on phy addr: %llx,size: %d",alloc->start,alloc->size); + return; +} +static const struct xrp_allocation_ops xrp_gfp_pool_ops = { + .free = xrp_free_gfp, + .offset = xrp_private_offset, +}; + + +static long xrp_alloc_gfp(u32 size, u32 align, + struct xrp_allocation **alloc) +{ + struct xrp_allocation *new; + size_t numPages; + struct page *contiguousPages; + struct xrp_allocation_pool *pool; + int i; + unsigned int gfp = GFP_KERNEL | GFP_DMA | __GFP_NOWARN; + if (!size || (align & (align - 1))) + return -EINVAL; + if (!align) + align = 1; + + new = kzalloc(sizeof(struct xrp_allocation), GFP_KERNEL); + + if(!new) + return -ENOMEM; + new->pool = kzalloc(sizeof(struct xrp_allocation_pool),GFP_KERNEL); + if(!new->pool) + goto OnError; + new->pool->ops = &xrp_gfp_pool_ops; + align = ALIGN(align, PAGE_SIZE); + size = ALIGN(size, PAGE_SIZE); + numPages = size >> PAGE_SHIFT; + + int order = get_order(size); + + if (order >= MAX_ORDER) + { + pr_debug("Too big buffer size requested. (order %d >= max %d)\n", + order, MAX_ORDER); + goto TwoError; + } + + contiguousPages = alloc_pages(gfp, order); + + for (i = 0; i < numPages; i++) + { + struct page *page; + + page = nth_page(contiguousPages, i); + + SetPageReserved(page); + } + + new->start = page_to_phys(nth_page(contiguousPages, 0)); + new->size = size; + atomic_set(&new->ref, 0); + xrp_allocation_get(new); + + *alloc = new; + pr_debug("alloc by gfp with phy addr: %llx,size: %d",new->start,new->size); + return 0; +TwoError: + kfree(new->pool); +OnError: + kfree(new); + return -ENOMEM; +} diff --git a/driver/xrp-kernel/xrp_alloc.h b/driver/xrp-kernel/xrp_alloc.h new file mode 100644 index 0000000..b182ab4 --- /dev/null +++ b/driver/xrp-kernel/xrp_alloc.h @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2016 - 2017 Cadence Design Systems Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Alternatively you can use and distribute this file under the terms of + * the GNU General Public License version 2 or later. + */ + +#ifndef XRP_ALLOC_H +#define XRP_ALLOC_H + +#ifndef __KERNEL__ + +#include +#include +#include + +typedef uint32_t u32; +typedef uint32_t phys_addr_t; +typedef _Atomic uint32_t atomic_t; + +struct mutex { + xrp_mutex o; +}; + +static inline void atomic_inc(atomic_t *v) +{ + ++*(volatile atomic_t *)v; +} + +static inline int atomic_dec_and_test(atomic_t *v) +{ + return --*(volatile atomic_t *)v == 0; +} + +#endif + +struct xrp_allocation_pool; +struct xrp_allocation; + +struct xrp_allocation_ops { + long (*alloc)(struct xrp_allocation_pool *allocation_pool, + u32 size, u32 align, struct xrp_allocation **alloc); + void (*free)(struct xrp_allocation *allocation); + void (*free_pool)(struct xrp_allocation_pool *allocation_pool); + phys_addr_t (*offset)(const struct xrp_allocation *allocation); +}; + +struct xrp_allocation_pool { + const struct xrp_allocation_ops *ops; +}; + +struct xrp_allocation { + struct xrp_allocation_pool *pool; + struct xrp_allocation *next; + phys_addr_t start; + u32 size; + atomic_t ref; +}; + +static inline void xrp_free_pool(struct xrp_allocation_pool *allocation_pool) +{ + allocation_pool->ops->free_pool(allocation_pool); +} + +static inline void xrp_free(struct xrp_allocation *allocation) +{ + return allocation->pool->ops->free(allocation); +} + +static inline long xrp_allocate(struct xrp_allocation_pool *allocation_pool, + u32 size, u32 align, + struct xrp_allocation **alloc) +{ + return allocation_pool->ops->alloc(allocation_pool, + size, align, alloc); +} + +static inline void xrp_allocation_get(struct xrp_allocation *xrp_allocation) +{ + atomic_inc(&xrp_allocation->ref); +} + +static inline void xrp_allocation_put(struct xrp_allocation *xrp_allocation) +{ + if (atomic_dec_and_test(&xrp_allocation->ref)) + xrp_allocation->pool->ops->free(xrp_allocation); +} + +static inline phys_addr_t xrp_allocation_offset(const struct xrp_allocation *allocation) +{ + return allocation->pool->ops->offset(allocation); +} + +#endif diff --git a/driver/xrp-kernel/xrp_cma_alloc.c b/driver/xrp-kernel/xrp_cma_alloc.c new file mode 100644 index 0000000..066ddb2 --- /dev/null +++ b/driver/xrp-kernel/xrp_cma_alloc.c @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2017 Cadence Design Systems Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Alternatively you can use and distribute this file under the terms of + * the GNU General Public License version 2 or later. + */ + +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 16, 0) +#include +#else +#include +#endif +#include +#include +#include "xrp_cma_alloc.h" + +struct xrp_cma_allocation { + struct xrp_allocation allocation; + void *kvaddr; +}; + +struct xrp_cma_pool { + struct xrp_allocation_pool pool; + struct device *dev; +}; + +static long xrp_cma_alloc(struct xrp_allocation_pool *allocation_pool, + u32 size, u32 align, struct xrp_allocation **alloc) +{ + struct xrp_cma_pool *pool = container_of(allocation_pool, + struct xrp_cma_pool, pool); + struct xrp_cma_allocation *new_cma; + struct xrp_allocation *new; + dma_addr_t dma_addr; + void *kvaddr; + + size = ALIGN(size, PAGE_SIZE); + + new_cma = kzalloc(sizeof(struct xrp_cma_allocation), GFP_KERNEL); + if (!new_cma) + return -ENOMEM; + + new = &new_cma->allocation; +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,8,0) + { + DEFINE_DMA_ATTRS(attrs); + + dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &attrs); + kvaddr = dma_alloc_attrs(pool->dev, size, &dma_addr, + GFP_KERNEL, &attrs); + } +#else + kvaddr = dma_alloc_attrs(pool->dev, size, &dma_addr, GFP_KERNEL, + DMA_ATTR_NO_KERNEL_MAPPING); +#endif + if (!kvaddr) { + kfree(new_cma); + return -ENOMEM; + } + new->pool = allocation_pool; + new->start = dma_to_phys(pool->dev, dma_addr); + new->size = size; + atomic_set(&new->ref, 0); + xrp_allocation_get(new); + new_cma->kvaddr = kvaddr; + *alloc = new; + + return 0; +} + +static void xrp_cma_free(struct xrp_allocation *xrp_allocation) +{ + struct xrp_cma_pool *pool = container_of(xrp_allocation->pool, + struct xrp_cma_pool, pool); + struct xrp_cma_allocation *a = container_of(xrp_allocation, + struct xrp_cma_allocation, + allocation); + +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,8,0) + DEFINE_DMA_ATTRS(attrs); + + dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &attrs); + dma_free_attrs(pool->dev, xrp_allocation->size, + a->kvaddr, + phys_to_dma(pool->dev, xrp_allocation->start), + &attrs); +#else + dma_free_attrs(pool->dev, xrp_allocation->size, + a->kvaddr, + phys_to_dma(pool->dev, xrp_allocation->start), + DMA_ATTR_NO_KERNEL_MAPPING); +#endif + kfree(a); +} + +static void xrp_cma_free_pool(struct xrp_allocation_pool *allocation_pool) +{ + struct xrp_cma_pool *pool = container_of(allocation_pool, + struct xrp_cma_pool, pool); + + kfree(pool); +} + +static phys_addr_t xrp_cma_offset(const struct xrp_allocation *allocation) +{ + return allocation->start; +} + +static const struct xrp_allocation_ops xrp_cma_pool_ops = { + .alloc = xrp_cma_alloc, + .free = xrp_cma_free, + .free_pool = xrp_cma_free_pool, + .offset = xrp_cma_offset, +}; + +long xrp_init_cma_pool(struct xrp_allocation_pool **ppool, struct device *dev) +{ + struct xrp_cma_pool *pool = kmalloc(sizeof(*pool), GFP_KERNEL); + + if (!pool) + return -ENOMEM; + + pool->pool.ops = &xrp_cma_pool_ops; + pool->dev = dev; + *ppool = &pool->pool; + return 0; +} diff --git a/driver/xrp-kernel/xrp_cma_alloc.h b/driver/xrp-kernel/xrp_cma_alloc.h new file mode 100644 index 0000000..88002ff --- /dev/null +++ b/driver/xrp-kernel/xrp_cma_alloc.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2017 Cadence Design Systems Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Alternatively you can use and distribute this file under the terms of + * the GNU General Public License version 2 or later. + */ + +#ifndef XRP_CMA_ALLOC_H +#define XRP_CMA_ALLOC_H + +#include "xrp_alloc.h" + +struct device; + +#ifdef CONFIG_CMA +long xrp_init_cma_pool(struct xrp_allocation_pool **pool, struct device *dev); +#else +static inline long xrp_init_cma_pool(struct xrp_allocation_pool **pool, + struct device *dev) +{ + return -ENXIO; +} +#endif + +#endif diff --git a/driver/xrp-kernel/xrp_debug.c b/driver/xrp-kernel/xrp_debug.c new file mode 100644 index 0000000..526d852 --- /dev/null +++ b/driver/xrp-kernel/xrp_debug.c @@ -0,0 +1,275 @@ +/* + * xrp_debug: + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Alternatively you can use and distribute this file under the terms of + * the GNU General Public License version 2 or later. + */ + +#include +// #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "xrp_kernel_defs.h" +#include "xrp_hw.h" +#include "xrp_hw_simple_dsp_interface.h" + +#define GET_PAGE_NUM(size, offset) ((((size) + ((offset) & ~PAGE_MASK)) + PAGE_SIZE - 1) >> PAGE_SHIFT) +struct xrp_panic_log{ + + struct xrp_hw_panic __iomem *panic; + phys_addr_t panic_phys; + u32 last_read; + struct proc_dir_entry *log_proc_file; +}; +static void memset_hw(void __iomem *dst, int c, size_t sz) +{ + int i; + volatile u32 * d_ptr=dst; + for(i=0;ipanic) + return; + + pr_debug("%s: panic = 0x%08x, ccount = 0x%08x\n", + fn, + __raw_readl(&panic_log->panic->panic), + __raw_readl(&panic_log->panic->ccount)); + pr_debug("%s: read = 0x%08x, write = 0x%08x, size = 0x%08x\n", + fn, + __raw_readl(&panic_log->panic->rb.read), + __raw_readl(&panic_log->panic->rb.write), + __raw_readl(&panic_log->panic->rb.size)); +} + +static void dump_log_page(struct xrp_panic_log *hw) +{ + char *buf; + size_t i; + + if (!hw->panic) + return; + + dump_regs(__func__, hw); + buf = kmalloc(PAGE_SIZE, GFP_KERNEL); + if (buf) { + memcpy_fromio(buf, hw->panic, hw->panic->rb.size); + buf+=sizeof(struct xrp_hw_panic); + for (i = 0; i < hw->panic->rb.size; i += 64) + pr_debug(" %*pEhp\n", 64, buf + i); + kfree(buf); + } else { + pr_debug("(couldn't allocate copy buffer)\n"); + } +} + +static int log_proc_show(struct seq_file *file, void *v) +{ + struct xrp_panic_log *hw = file->private; + char *buf; + size_t i; + int page_num = GET_PAGE_NUM(hw->panic->rb.size,0); + dump_regs(__func__, hw); + buf = kmalloc(PAGE_SIZE*page_num, GFP_KERNEL); + if (buf) { + memcpy_fromio(buf, hw->panic->rb.data, hw->panic->rb.size); + seq_printf(file,"****************** device log >>>>>>>>>>>>>>>>>\n"); + for (i = 0; i < hw->panic->rb.size; i += 64) + seq_printf(file," %*pEp", 64,buf+i); + // pr_debug(" %*pEhp\n", 64, buf + i); + // seq_printf(file," %*pEp\n",buf); + kfree(buf); + + uint32_t write = __raw_readl(&hw->panic->rb.write); + __raw_writel(write, &hw->panic->rb.read); + + return 0; + } + else + { + pr_debug("Fail to alloc buf\n"); + return -1; + } + return 0; +} + +static int log_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, log_proc_show, NULL); +} + +static const struct file_operations log_proc_fops = { + .open = log_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + + +static bool xrp_panic_init(struct xrp_hw_panic* panic,size_t size) +{ + if(size < sizeof(struct xrp_hw_panic)) + { + return false; + } + memset_hw(panic,0x0,size); + panic->panic = 0; + panic->ccount = 0; + panic->rb.read = 0; + panic->rb.write = 0; + panic->rb.size = size - sizeof(struct xrp_hw_panic); + sprintf(panic->rb.data,"Inition dsp log\n"); + return true; +} + +void* xrp_create_panic_log_proc(void* dir,void * panic_addr,size_t size) +{ + struct xrp_panic_log *panic_log = kmalloc(sizeof(struct xrp_panic_log),GFP_KERNEL); + + if(panic_log == NULL) + return NULL; + + panic_log->last_read = 0; + panic_log->panic = panic_addr; + xrp_panic_init(panic_log->panic,size); + + panic_log->log_proc_file=proc_create_single_data("dsp_log",0644,dir,&log_proc_show,panic_log); + if(panic_log->log_proc_file == NULL) { + pr_debug("Error: Could not initialize %s\n","dsp_log"); + kfree(panic_log); + panic_log =NULL; + } else { + + pr_debug("%s create Success!\n","dsp_log"); + } + return panic_log; +} + +void xrp_remove_panic_log_proc(void *arg) +{ + // char file_name[32]; + struct xrp_panic_log *panic_log = arg; + // remove_proc_entry(panic_log->log_proc_file,NULL); + + proc_remove(panic_log->log_proc_file); + kfree(arg); + pr_debug("dsp proc removed\n"); +} + +bool panic_check(void *arg) +{ + struct xrp_panic_log *panic_log = arg; + uint32_t panic; + uint32_t ccount; + uint32_t read; + uint32_t write; + uint32_t size; + + if (!panic_log || !panic_log->panic) + return true; + + panic = __raw_readl(&panic_log->panic->panic); + ccount = __raw_readl(&panic_log->panic->ccount); + read = __raw_readl(&panic_log->panic->rb.read); + write = __raw_readl(&panic_log->panic->rb.write); + size = __raw_readl(&panic_log->panic->rb.size); + + if (read == 0 && read != panic_log->last_read) { + pr_debug( "****************** device restarted >>>>>>>>>>>>>>>>>\n"); + dump_log_page(panic_log); + pr_debug ("<<<<<<<<<<<<<<<<<< device restarted *****************\n"); + } + if (write < size && read < size && size < PAGE_SIZE) { + uint32_t tail; + uint32_t total; + char *buf = NULL; + + panic_log->last_read = read; + if (read < write) { + tail = write - read; + total = tail; + } else if (read == write) { + tail = 0; + total = 0; + } else { + tail = size - read; + total = write + tail; + } + + if (total) + buf = kmalloc(total, GFP_KERNEL); + + if (buf) { + uint32_t off = 0; + + pr_debug("panic = 0x%08x, ccount = 0x%08x read = %d, write = %d, size = %d, total = %d", + panic, ccount, read, write, size, total); + + while (off != total) { + memcpy_fromio(buf + off, + panic_log->panic->rb.data + read, + tail); + read = 0; + off += tail; + tail = total - tail; + } + __raw_writel(write, &panic_log->panic->rb.read); + panic_log->last_read = write; + pr_debug("<<<\n%.*s\n>>>\n", + total, buf); + kfree(buf); + } else if (total) { + pr_debug( + "%s: couldn't allocate memory (%d) to read the dump\n", + __func__, total); + } + } else { + if (read != panic_log->last_read) { + pr_debug( + "nonsense in the log buffer: read = %d, write = %d, size = %d\n", + read, write, size); + panic_log->last_read = read; + } + } + if (panic == 0xdeadbabe) { + pr_debug("%s: panic detected, log dump:\n", __func__); + dump_log_page(panic_log); + } + + return panic == 0xdeadbabe; +} + diff --git a/driver/xrp-kernel/xrp_debug.h b/driver/xrp-kernel/xrp_debug.h new file mode 100644 index 0000000..703a4f3 --- /dev/null +++ b/driver/xrp-kernel/xrp_debug.h @@ -0,0 +1,34 @@ +/* + * xrp_debug: + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Alternatively you can use and distribute this file under the terms of + * the GNU General Public License version 2 or later. + */ + +#ifndef XRP_DEBUG_H +#define XRP_DEBUG_H +void* xrp_create_panic_log_proc(void* dir,void * panic_addr,size_t size); + +void xrp_remove_panic_log_proc(void *arg); + +bool panic_check(void *arg); +#endif diff --git a/driver/xrp-kernel/xrp_firmware.c b/driver/xrp-kernel/xrp_firmware.c new file mode 100644 index 0000000..90c51a6 --- /dev/null +++ b/driver/xrp-kernel/xrp_firmware.c @@ -0,0 +1,406 @@ +/* + * xrp_firmware: firmware manipulation for the XRP + * + * Copyright (c) 2015 - 2017 Cadence Design Systems, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Alternatively you can use and distribute this file under the terms of + * the GNU General Public License version 2 or later. + */ + +#include "xrp_firmware.h" +#include "xrp_address_map.h" +#include "xrp_hw.h" +#include "xrp_internal.h" +#include "xrp_kernel_dsp_interface.h" +#include +#include +#include +#include +#include +#include +#include + + +static phys_addr_t xrp_translate_to_cpu(struct xvp *xvp, Elf32_Phdr *phdr) { + phys_addr_t res; + __be32 addr = cpu_to_be32((u32)phdr->p_paddr); + struct device_node *node = of_get_next_child(xvp->dev->of_node, NULL); + + if (!node) + node = xvp->dev->of_node; + + res = of_translate_address(node, &addr); + + if (node != xvp->dev->of_node) + of_node_put(node); + return res; +} + +static int xrp_load_segment_to_sysmem(struct xvp *xvp, Elf32_Phdr *phdr) { + // phys_addr_t pa = xrp_translate_to_cpu(xvp, phdr); + phys_addr_t pa = xrp_translate_dsp_to_host(&xvp->address_map,phdr->p_paddr); + struct page *page = pfn_to_page(__phys_to_pfn(pa)); + size_t page_offs = pa & ~PAGE_MASK; + size_t offs; + + for (offs = 0; offs < phdr->p_memsz; ++page) { + void *p = kmap(page); + size_t sz; + + if (!p) + return -ENOMEM; + + page_offs &= ~PAGE_MASK; + sz = PAGE_SIZE - page_offs; + + dev_dbg(xvp->dev, "loading segment to host addr 0x%d by host visiul %p,size:%d\n", + page_offs,p,sz); + if (offs < phdr->p_filesz) { + size_t copy_sz = sz; + + if (phdr->p_filesz - offs < copy_sz) + copy_sz = phdr->p_filesz - offs; + + copy_sz = ALIGN(copy_sz, 4); + memcpy(p + page_offs, (void *)xvp->firmware->data + phdr->p_offset + offs, + copy_sz); + page_offs += copy_sz; + offs += copy_sz; + sz -= copy_sz; + } + dev_dbg(xvp->dev, "loading segment to host addr 0x%d by host visiul %p,size:%d\n", + page_offs,p, sz); + if (offs < phdr->p_memsz && sz) { + if (phdr->p_memsz - offs < sz) + sz = phdr->p_memsz - offs; + + sz = ALIGN(sz, 4); + memset(p + page_offs, 0, sz); + page_offs += sz; + offs += sz; + } + kunmap(page); + } + dma_sync_single_for_device(xvp->dev, pa, phdr->p_memsz, DMA_TO_DEVICE); + dev_dbg(xvp->dev, "xrp_load_segment_to_sysmem"); + return 0; +} +static int xrp_load_segment_to_iomem(struct xvp *xvp, Elf32_Phdr *phdr) { + // phys_addr_t pa = xrp_translate_to_cpu(xvp, phdr); + phys_addr_t pa = xrp_translate_dsp_to_host(&xvp->address_map,phdr->p_paddr); + if(pa==OF_BAD_ADDR) + { + dev_err(xvp->dev, "couldn't translate DSP addr 0x%x\n", phdr->p_paddr); + return -EINVAL; + } + void __iomem *p = ioremap(pa, phdr->p_memsz); + + if (!p) { + dev_err(xvp->dev, "couldn't ioremap %pap x 0x%08x\n", &pa, + (u32)phdr->p_memsz); + return -EINVAL; + } + dev_dbg(xvp->dev, "loading segment to host addr 0x%pap by host virtual 0x%llx,size:%d,total size:%d,fw dataptr:0x%llx,offset:0x%x\n", + &pa,p, phdr->p_filesz,(u32)phdr->p_memsz,xvp->firmware->data,phdr->p_offset); + + if(phdr->p_filesz) + { + if (xvp->hw_ops->memcpy_tohw) + xvp->hw_ops->memcpy_tohw(p, (void *)xvp->firmware->data + phdr->p_offset, + ALIGN(phdr->p_filesz, 4)); + else + memcpy_toio(p, (void *)xvp->firmware->data + phdr->p_offset, + ALIGN(phdr->p_filesz, 4)); + + dev_dbg(xvp->dev, "copy size:%d\n",ALIGN(phdr->p_filesz, 4)); + } + if(phdr->p_memsz - phdr->p_filesz) + { + if (xvp->hw_ops->memset_hw) + xvp->hw_ops->memset_hw(p + phdr->p_filesz, 0, + phdr->p_memsz - phdr->p_filesz); + else + memset_io(p + ALIGN(phdr->p_filesz, 4), 0, + ALIGN(phdr->p_memsz - ALIGN(phdr->p_filesz, 4), 4)); + dev_dbg(xvp->dev, "set size:%d\n",ALIGN(phdr->p_memsz - ALIGN(phdr->p_filesz, 4),4)); + } + + iounmap(p); + dev_dbg(xvp->dev, "xrp_load_segment_to_iomem done\n"); + return 0; +} + +static inline bool xrp_section_bad(struct xvp *xvp, const Elf32_Shdr *shdr) { + return shdr->sh_offset > xvp->firmware->size || + shdr->sh_size > xvp->firmware->size - shdr->sh_offset; +} + +static int xrp_firmware_find_symbol(struct xvp *xvp, const char *name, + void **paddr, size_t *psize) { + const Elf32_Ehdr *ehdr = (Elf32_Ehdr *)xvp->firmware->data; + const void *shdr_data = xvp->firmware->data + ehdr->e_shoff; + const Elf32_Shdr *sh_symtab = NULL; + const Elf32_Shdr *sh_strtab = NULL; + const void *sym_data; + const void *str_data; + const Elf32_Sym *esym; + void *addr = NULL; + unsigned i; + + if (ehdr->e_shoff == 0) { + dev_dbg(xvp->dev, "%s: no section header in the firmware image", __func__); + return -ENOENT; + } + if (ehdr->e_shoff > xvp->firmware->size || + ehdr->e_shnum * ehdr->e_shentsize > xvp->firmware->size - ehdr->e_shoff) { + dev_err(xvp->dev, "%s: bad firmware SHDR information", __func__); + return -EINVAL; + } + + /* find symbols and string sections */ + + for (i = 0; i < ehdr->e_shnum; ++i) { + const Elf32_Shdr *shdr = shdr_data + i * ehdr->e_shentsize; + + switch (shdr->sh_type) { + case SHT_SYMTAB: + sh_symtab = shdr; + break; + case SHT_STRTAB: + sh_strtab = shdr; + break; + default: + break; + } + } + + if (!sh_symtab || !sh_strtab) { + dev_dbg(xvp->dev, "%s: no symtab or strtab in the firmware image", + __func__); + return -ENOENT; + } + + if (xrp_section_bad(xvp, sh_symtab)) { + dev_err(xvp->dev, "%s: bad firmware SYMTAB section information", __func__); + return -EINVAL; + } + + if (xrp_section_bad(xvp, sh_strtab)) { + dev_err(xvp->dev, "%s: bad firmware STRTAB section information", __func__); + return -EINVAL; + } + + /* iterate through all symbols, searching for the name */ + + sym_data = xvp->firmware->data + sh_symtab->sh_offset; + str_data = xvp->firmware->data + sh_strtab->sh_offset; + + for (i = 0; i < sh_symtab->sh_size; i += sh_symtab->sh_entsize) { + esym = sym_data + i; + + if (!(ELF_ST_TYPE(esym->st_info) == STT_OBJECT && + esym->st_name < sh_strtab->sh_size && + strncmp(str_data + esym->st_name, name, + sh_strtab->sh_size - esym->st_name) == 0)) + continue; + + if (esym->st_shndx > 0 && esym->st_shndx < ehdr->e_shnum) { + const Elf32_Shdr *shdr = shdr_data + esym->st_shndx * ehdr->e_shentsize; + Elf32_Off in_section_off = esym->st_value - shdr->sh_addr; + + if (xrp_section_bad(xvp, shdr)) { + dev_err(xvp->dev, "%s: bad firmware section #%d information", __func__, + esym->st_shndx); + return -EINVAL; + } + + if (esym->st_value < shdr->sh_addr || in_section_off > shdr->sh_size || + esym->st_size > shdr->sh_size - in_section_off) { + dev_err(xvp->dev, "%s: bad symbol information", __func__); + return -EINVAL; + } + addr = (void *)xvp->firmware->data + shdr->sh_offset + in_section_off; + + dev_dbg(xvp->dev, + "%s: found symbol, st_shndx = %d, " + "sh_offset = 0x%08x, sh_addr = 0x%08x, " + "st_value = 0x%08x, address = %p", + __func__, esym->st_shndx, shdr->sh_offset, shdr->sh_addr, + esym->st_value, addr); + } else { + dev_dbg(xvp->dev, "%s: unsupported section index in found symbol: 0x%x", + __func__, esym->st_shndx); + return -EINVAL; + } + break; + } + + if (!addr) + return -ENOENT; + + *paddr = addr; + *psize = esym->st_size; + + return 0; +} + +static int xrp_firmware_fixup_symbol(struct xvp *xvp, const char *name, + phys_addr_t v) { + u32 v32 = XRP_DSP_COMM_BASE_MAGIC; + void *addr; + size_t sz; + int rc; + if(v == XRP_NO_TRANSLATION) + { + dev_err(xvp->dev, "%s: invalid dsp address %llx", __func__, name); + return -EINVAL; + } + rc = xrp_firmware_find_symbol(xvp, name, &addr, &sz); + if (rc < 0) { + dev_err(xvp->dev, "%s: symbol \"%s\" is not found", __func__, name); + return rc; + } + + if (sz != sizeof(u32)) { + dev_err(xvp->dev, "%s: symbol \"%s\" has wrong size: %zu", __func__, name, + sz); + return -EINVAL; + } + + /* update data associated with symbol */ + + if (memcmp(addr, &v32, sz) != 0) { + dev_dbg(xvp->dev, "%s: value pointed to by symbol is incorrect: %*ph", + __func__, (int)sz, addr); + } + + v32 = v; + memcpy(addr, &v32, sz); + + return 0; +} + +static int xrp_load_firmware(struct xvp *xvp) { + Elf32_Ehdr *ehdr = (Elf32_Ehdr *)xvp->firmware->data; + int i; + if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG)) { + + dev_err(xvp->dev, "bad firmware ELF magic\n"); + return -EINVAL; + } + + if (ehdr->e_type != ET_EXEC) { + dev_err(xvp->dev, "bad firmware ELF type\n"); + return -EINVAL; + } + + if (ehdr->e_machine != 94 /*EM_XTENSA*/) { + dev_err(xvp->dev, "bad firmware ELF machine\n"); + return -EINVAL; + } + + if (ehdr->e_phoff >= xvp->firmware->size || + ehdr->e_phoff + ehdr->e_phentsize * ehdr->e_phnum > xvp->firmware->size) { + dev_err(xvp->dev, "bad firmware ELF PHDR information\n"); + return -EINVAL; + } + + xrp_firmware_fixup_symbol( + xvp, "xrp_dsp_comm_base", + xrp_translate_to_dsp(&xvp->address_map, xvp->comm_phys)); + + for (i = 0; i < ehdr->e_phnum; ++i) { + Elf32_Phdr *phdr = + (void *)xvp->firmware->data + ehdr->e_phoff + i * ehdr->e_phentsize; + phys_addr_t pa; + int rc; + + /* Only load non-empty loadable segments, R/W/X */ + if (!(phdr->p_type == PT_LOAD && (phdr->p_flags & (PF_X | PF_R | PF_W)) && + phdr->p_memsz > 0)) + continue; + + if (phdr->p_offset >= xvp->firmware->size || + phdr->p_offset + phdr->p_filesz > xvp->firmware->size) { + dev_err(xvp->dev, "bad firmware ELF program header entry %d\n", i); + return -EINVAL; + } + + // pa = xrp_translate_to_cpu(xvp, phdr); + pa=phdr->p_paddr; + if (pa == (phys_addr_t)OF_BAD_ADDR) { + dev_err( + xvp->dev, + "device address 0x%08x could not be mapped to host physical address", + (u32)phdr->p_paddr); + return -EINVAL; + } + dev_dbg(xvp->dev, "loading segment %d (device 0x%08x) to physical %pap\n", + i, (u32)phdr->p_paddr, &pa); + + // if (pfn_valid(__phys_to_pfn(pa))) + // rc = xrp_load_segment_to_sysmem(xvp, phdr); + // else + rc = xrp_load_segment_to_iomem(xvp, phdr); + + if (rc < 0) + return rc; + } + dev_dbg(xvp->dev, "loading firmware sucessful\n"); + return 0; +} + +int xrp_request_firmware(struct xvp *xvp,Elf32_Addr *boot_addr) { + int ret = request_firmware(&xvp->firmware, xvp->firmware_name, xvp->dev); + + if (ret < 0 || boot_addr == NULL) + return ret; + + ret = xrp_load_firmware(xvp); + *boot_addr = xrp_get_firmware_entry_addr(xvp); + release_firmware(xvp->firmware); + + return ret; +} + +Elf32_Addr xrp_get_firmware_entry_addr(struct xvp *xvp) +{ + Elf32_Ehdr *ehdr = (Elf32_Ehdr *)xvp->firmware->data; + int i; + if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG)) { + + dev_err(xvp->dev, "bad firmware ELF magic\n"); + return 0; + } + + if (ehdr->e_type != ET_EXEC) { + dev_err(xvp->dev, "bad firmware ELF type\n"); + return 0; + } + + if (ehdr->e_machine != 94 /*EM_XTENSA*/) { + dev_err(xvp->dev, "bad firmware ELF machine\n"); + return 0; + } + return ehdr->e_entry; + +} \ No newline at end of file diff --git a/driver/xrp-kernel/xrp_firmware.h b/driver/xrp-kernel/xrp_firmware.h new file mode 100644 index 0000000..18e3338 --- /dev/null +++ b/driver/xrp-kernel/xrp_firmware.h @@ -0,0 +1,50 @@ +/* + * xrp_firmware: firmware manipulation for the XRP + * + * Copyright (c) 2015 - 2017 Cadence Design Systems, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Alternatively you can use and distribute this file under the terms of + * the GNU General Public License version 2 or later. + */ + +#ifndef XRP_FIRMWARE_H +#define XRP_FIRMWARE_H +#include +struct xvp; + +#if IS_ENABLED(CONFIG_OF) +int xrp_request_firmware(struct xvp *xvp,Elf32_Addr *boot_addr); +Elf32_Addr xrp_get_firmware_entry_addr(struct xvp *xvp); +#else +int xrp_request_firmware(struct xvp *xvp,Elf32_Addr *boot_addr) +{ + (void)xvp; + return -EINVAL; +} +Elf32_Addr xrp_get_firmware_entry_addr(struct xvp *xvp) +{ + (void)xvp; + return 0; +} +#endif + +#endif diff --git a/driver/xrp-kernel/xrp_hw.h b/driver/xrp-kernel/xrp_hw.h new file mode 100644 index 0000000..dbb7cb8 --- /dev/null +++ b/driver/xrp-kernel/xrp_hw.h @@ -0,0 +1,251 @@ +/* + * Copyright (c) 2017 Cadence Design Systems, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Alternatively you can use and distribute this file under the terms of + * the GNU General Public License version 2 or later. + */ + +/*! + * \file xrp_hw.h + * \brief Interface between generic and HW-specific kernel drivers. + */ + +#ifndef _XRP_HW +#define _XRP_HW + +#include +#include +#include + +struct xvp; + +/*! + * Hardware-specific operation entry points. + * Hardware-specific driver passes a pointer to this structure to xrp_init + * at initialization time. + */ +struct xrp_hw_ops { + /*! + * Enable power/clock, but keep the core stalled. + * \param hw_arg: opaque parameter passed to xrp_init at initialization + * time + */ + int (*enable)(void *hw_arg); + /*! + * Diable power/clock. + * + * \param hw_arg: opaque parameter passed to xrp_init at initialization + * time + */ + void (*disable)(void *hw_arg); + /*! + * Reset the core. + * + * \param hw_arg: opaque parameter passed to xrp_init at initialization + * time + */ + void (*reset)(void *hw_arg); + /*! + * Unstall the core. + * + * \param hw_arg: opaque parameter passed to xrp_init at initialization + * time + */ + void (*release)(void *hw_arg); + /*! + * Stall the core. + * + * \param hw_arg: opaque parameter passed to xrp_init at initialization + * time + */ + void (*halt)(void *hw_arg); + + /*! Get HW-specific data to pass to the DSP on synchronization + * + * \param hw_arg: opaque parameter passed to xrp_init at initialization + * time + * \param sz: return size of sync data here + * \return a buffer allocated with kmalloc that the caller will free + */ + void *(*get_hw_sync_data)(void *hw_arg, size_t *sz); + + /*! + * Send IRQ to the core. + * + * \param hw_arg: opaque parameter passed to xrp_init at initialization + * time + */ + void (*send_irq)(void *hw_arg); + + /*! + * Check whether region of physical memory may be handled by + * dma_sync_* operations + * + * \param hw_arg: opaque parameter passed to xrp_init at initialization + * time + */ + bool (*cacheable)(void *hw_arg, unsigned long pfn, unsigned long n_pages); + /*! + * Synchronize region of memory for DSP access. + * + * \param hw_arg: opaque parameter passed to xrp_init at initialization + * time + * \param flags: XRP_FLAG_{READ,WRITE,READWRITE} + */ + void (*dma_sync_for_device)(void *hw_arg, + void *vaddr, phys_addr_t paddr, + unsigned long sz, unsigned flags); + /*! + * Synchronize region of memory for host access. + * + * \param hw_arg: opaque parameter passed to xrp_init at initialization + * time + * \param flags: XRP_FLAG_{READ,WRITE,READWRITE} + */ + void (*dma_sync_for_cpu)(void *hw_arg, + void *vaddr, phys_addr_t paddr, + unsigned long sz, unsigned flags); + + /*! + * memcpy data/code to device-specific memory. + */ + void (*memcpy_tohw)(volatile void __iomem *dst, const void *src, size_t sz); + /*! + * memset device-specific memory. + */ + void (*memset_hw)(volatile void __iomem *dst, int c, size_t sz); + + /*! + * Check DSP status. + * + * \param hw_arg: opaque parameter passed to xrp_init at initialization + * time + * \return whether the core has crashed and needs to be restarted + */ + bool (*panic_check)(void *hw_arg); + + phys_addr_t (*get_base_mimo)(void *hw_arg); + + void (*update_device_base)(void *hw_arg,phys_addr_t addr); + + void (*set_reset_vector)(void *hw_arg,u32 addr); + + void (*clear_hw)(void *hw_arg); + +}; + +enum xrp_init_flags { + /*! Use interrupts in DSP->host communication */ + XRP_INIT_USE_HOST_IRQ = 0x1, +}; + +/*! + * Initialize generic XRP kernel driver from cdns,xrp-compatible device + * tree node. + * + * \param pdev: pointer to platform device associated with the XRP device + * instance + * \param flags: initialization flags + * \param hw: pointer to xrp_hw_ops structeure for this device + * \param hw_arg: opaque pointer passed back to hw-specific functions + * \return error code or pointer to struct xvp, use IS_ERR_VALUE and ERR_PTR + */ +long xrp_init(struct platform_device *pdev, enum xrp_init_flags flags, + const struct xrp_hw_ops *hw, void *hw_arg,int mem_idx); + +/*! + * Initialize generic XRP kernel driver from cdns,xrp,v1-compatible device + * tree node. + * + * \param pdev: pointer to platform device associated with the XRP device + * instance + * \param flags: initialization flags + * \param hw: pointer to xrp_hw_ops structeure for this device + * \param hw_arg: opaque pointer passed back to hw-specific functions + * \return error code or pointer to struct xvp, use IS_ERR_VALUE and ERR_PTR + */ +long xrp_init_v1(struct platform_device *pdev, enum xrp_init_flags flags, + const struct xrp_hw_ops *hw, void *hw_arg,int mem_idx); + +/*! + * Initialize generic XRP kernel driver from cdns,xrp,cma-compatible device + * tree node. + * + * \param pdev: pointer to platform device associated with the XRP device + * instance + * \param flags: initialization flags + * \param hw: pointer to xrp_hw_ops structeure for this device + * \param hw_arg: opaque pointer passed back to hw-specific functions + * \return error code or pointer to struct xvp, use IS_ERR_VALUE and ERR_PTR + */ +long xrp_init_cma(struct platform_device *pdev, enum xrp_init_flags flags, + const struct xrp_hw_ops *hw, void *hw_arg,int mem_idx); + +/*! + * Deinitialize generic XRP kernel driver. + * + * \param pdev: pointer to platform device associated with the XRP device + * instance + * \return 0 on success, negative error code otherwise + */ +int xrp_deinit(struct platform_device *pdev); + +/*! + * Deinitialize generic XRP kernel driver. + * + * \param pdev: pointer to platform device associated with the XRP device + * instance + * \param hw_arg: optional pointer to opaque pointer where generic XRP driver + * returns hw_arg that was associated with the pdev at xrp_init + * time + * \return 0 on success, negative error code otherwise + */ +int xrp_deinit_hw(struct platform_device *pdev, void **hw_arg); + +/*! + * Notify generic XRP driver of possible IRQ from the DSP. + * + * \param irq: IRQ number + * \param xvp: pointer to struct xvp returned from xrp_init* call + * \return whether IRQ was recognized and handled + */ +irqreturn_t xrp_irq_handler(int irq, struct xvp *xvp); + +/*! + * Resume generic XRP operation of the device dev. + * + * \param dev: device which operation shall be resumed + * \return 0 on success, negative error code otherwise + */ +int xrp_runtime_resume(struct device *dev); + +/*! + * Suspend generic XRP operation of the device dev. + * + * \param dev: device which operation shall be suspended + * \return 0 on success, negative error code otherwise + */ +int xrp_runtime_suspend(struct device *dev); + +int xrp_set_reset_reg(int dsp_id); + +#endif diff --git a/driver/xrp-kernel/xrp_hw_comm.c b/driver/xrp-kernel/xrp_hw_comm.c new file mode 100644 index 0000000..7c79112 --- /dev/null +++ b/driver/xrp-kernel/xrp_hw_comm.c @@ -0,0 +1,157 @@ +/* + * XRP: Linux device driver for Xtensa Remote Processing + * + * Copyright (c) 2015 - 2017 Cadence Design Systems, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Alternatively you can use and distribute this file under the terms of + * the GNU General Public License version 2 or later. + */ + +#include +#include +#include +#include +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 16, 0) +#include +#else +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "xrp_cma_alloc.h" +#include "xrp_firmware.h" +#include "xrp_hw.h" +#include "xrp_internal.h" +#include "xrp_kernel_defs.h" +#include "xrp_kernel_dsp_interface.h" +#include "xrp_private_alloc.h" + +#define DRIVER_NAME "xrp_hw_com" + +struct xrp_hw_common_drvdata { + + phys_addr_t sys_reg_phys; + void __iomem *sys_regs; + size_t sys_reg_size; + struct mutex lock; + +}; +static struct xrp_hw_common_drvdata *hw_drvdata = NULL; +#define XRP_REG_RESET (0x28) +#define DSP0_RESET_BIT_MASK (0x1<<8) + +#define DSP1_RESET_BIT_MASK (0x1<<12) +int xrp_set_reset_reg(int dsp_id) +{ + uint32_t bit_mask = dsp_id==0?DSP0_RESET_BIT_MASK + :DSP1_RESET_BIT_MASK; + + pr_debug("%s,reset\n", __func__); + if(!hw_drvdata) + { + pr_debug("%s hw_drvdata is NULL \n",__func__); + return -1; + } + mutex_lock(&hw_drvdata->lock); + + uint32_t old_value = __raw_readl(hw_drvdata->sys_regs+XRP_REG_RESET); + pr_debug("%s,reset reg:%x\n",__func__,old_value); + __raw_writel(old_value^bit_mask,hw_drvdata->sys_regs+XRP_REG_RESET); + udelay(10000); + __raw_writel(old_value,hw_drvdata->sys_regs+XRP_REG_RESET); + mutex_unlock(&hw_drvdata->lock); + + return 0; +} +EXPORT_SYMBOL(xrp_set_reset_reg); +static const struct of_device_id xrp_hw_common_of_match[] = { + { + .compatible = "thead,dsp-hw-common", + }, {}, +}; +// MODULE_DEVICE_TABLE(of, xrp_hw_common_of_match); +static int xrp_hw_common_probe(struct platform_device *pdev) +{ + long ret = -EINVAL; + + struct resource *mem; + + hw_drvdata = + devm_kzalloc(&pdev->dev, sizeof(*hw_drvdata), GFP_KERNEL); + if (!hw_drvdata) + return -ENOMEM; + + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!mem) { + return -ENODEV; + } + hw_drvdata->sys_reg_phys = mem->start; + hw_drvdata->sys_reg_size =mem->end-mem->start; + hw_drvdata->sys_regs = devm_ioremap_resource(&pdev->dev, mem); + pr_debug("%s,sys_reg_phys:%lx,sys_regs:%lx,size:%x\n", __func__, + hw_drvdata->sys_reg_phys,hw_drvdata->sys_regs,hw_drvdata->sys_reg_size); + mutex_init(&hw_drvdata->lock); + + return 0; +} + +static int xrp_hw_common_remove(struct platform_device *pdev) +{ + return 0; +} + + +static struct platform_driver xrp_hw_common_driver = { + .probe = xrp_hw_common_probe, + .remove = xrp_hw_common_remove, + .driver = { + .name = DRIVER_NAME, + .of_match_table = of_match_ptr( xrp_hw_common_of_match), + }, +}; + +module_platform_driver(xrp_hw_common_driver); + +MODULE_AUTHOR("T-HEAD"); +MODULE_DESCRIPTION("XRP: Linux device driver for Xtensa Remote Processing"); +MODULE_LICENSE("Dual MIT/GPL"); diff --git a/driver/xrp-kernel/xrp_hw_hikey960.c b/driver/xrp-kernel/xrp_hw_hikey960.c new file mode 100644 index 0000000..638b812 --- /dev/null +++ b/driver/xrp-kernel/xrp_hw_hikey960.c @@ -0,0 +1,480 @@ +/* + * xrp_hw_hikey: Simple xtensa/arm low-level XRP driver + * + * Copyright (c) 2018 Cadence Design Systems, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Alternatively you can use and distribute this file under the terms of + * the GNU General Public License version 2 or later. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "xrp_hw.h" +#include "xrp_hw_hikey960_dsp_interface.h" +#include "xrp_ring_buffer.h" + +#include +#include +#include + +#define DRIVER_NAME "xrp-hw-hikey960" + +enum xrp_irq_mode { + XRP_IRQ_NONE, + XRP_IRQ_LEVEL, + XRP_IRQ_EDGE, + XRP_IRQ_MAX, +}; + +struct xrp_hw_hikey { + struct xvp *xrp; + struct device *dev; + + struct xrp_hw_hikey960_panic __iomem *panic; + uint32_t last_read; + + /* how IRQ is used to notify the device of incoming data */ + enum xrp_irq_mode device_irq_mode; + /* device IRQ# */ + u32 device_irq; + /* how IRQ is used to notify the host of incoming data */ + enum xrp_irq_mode host_irq_mode; + /* dummy host IRQ */ + u32 host_irq; +}; + +static void *get_hw_sync_data(void *hw_arg, size_t *sz) +{ + struct xrp_hw_hikey *hw = hw_arg; + struct xrp_hw_hikey960_sync_data *hw_sync_data = + kmalloc(sizeof(*hw_sync_data), GFP_KERNEL); + + if (!hw_sync_data) + return NULL; + + *hw_sync_data = (struct xrp_hw_hikey960_sync_data){ + .host_irq_mode = hw->host_irq_mode, + .device_irq_mode = hw->device_irq_mode, + .device_irq = hw->device_irq, + }; + *sz = sizeof(*hw_sync_data); + return hw_sync_data; +} + +static int send_cmd_async(struct xrp_hw_hikey *hw, uint32_t mbx, uint32_t cmd) +{ + int ret = RPROC_ASYNC_SEND(mbx, &cmd, 1); + if (ret != 0) { + dev_err(hw->dev, "%s: RPROC_ASYNC_SEND ret = %d\n", + __func__, ret); + } + return ret; +} + +static int send_cmd_sync(struct xrp_hw_hikey *hw, uint32_t mbx, uint32_t cmd) +{ + int ret = hisi_rproc_xfer_sync_auto(mbx, &cmd, 1, NULL, 0); + if (ret != 0) { + dev_err(hw->dev, "%s: RPROC_SYNC_SEND ret = %d\n", + __func__, ret); + } + return ret; +} + +static int enable(void *hw_arg) +{ + return 0; +} + +static void disable(void *hw_arg) +{ +} + +static void reset(void *hw_arg) +{ +} + +static void dump_regs(const char *fn, void *hw_arg) +{ + struct xrp_hw_hikey *hw = hw_arg; + + if (!hw->panic) + return; + + dev_info(hw->dev, "%s: panic = 0x%08x, ccount = 0x%08x\n", + fn, + __raw_readl(&hw->panic->panic), + __raw_readl(&hw->panic->ccount)); + dev_info(hw->dev, "%s: read = 0x%08x, write = 0x%08x, size = 0x%08x\n", + fn, + __raw_readl(&hw->panic->rb.read), + __raw_readl(&hw->panic->rb.write), + __raw_readl(&hw->panic->rb.size)); +} + +static void dump_log_page(struct xrp_hw_hikey *hw) +{ + char *buf; + size_t i; + + if (!hw->panic) + return; + + dump_regs(__func__, hw); + buf = kmalloc(PAGE_SIZE, GFP_KERNEL); + if (buf) { + memcpy_fromio(buf, hw->panic, PAGE_SIZE); + for (i = 0; i < PAGE_SIZE; i += 64) + dev_info(hw->dev, " %*pEhp\n", 64, buf + i); + kfree(buf); + } else { + dev_err(hw->dev, " (couldn't allocate copy buffer)\n"); + } +} + +static void halt(void *hw_arg) +{ + struct xrp_hw_hikey *hw = hw_arg; + int i; + + dev_dbg(hw->dev, "%s\n", __func__); + dump_regs(__func__, hw); + dump_log_page(hw); + + send_cmd_sync(hw_arg, HISI_RPROC_LPM3_MBX17, + (16 << 16) | (3 << 8) | (1 << 0)); + for (i = 0; i < 10; ++i) { + schedule(); + mdelay(1); + dump_regs(__func__, hw); + } + dev_dbg(hw->dev, "%s done\n", __func__); +} + +static void release(void *hw_arg) +{ + struct xrp_hw_hikey *hw = hw_arg; + int i; + + dev_dbg(hw->dev, "%s\n", __func__); + dump_regs(__func__, hw); + + send_cmd_async(hw_arg, HISI_RPROC_HIFI_MBX18, 0xb007); + for (i = 0; i < 10; ++i) { + schedule(); + mdelay(1); + dump_regs(__func__, hw); + } + dev_dbg(hw->dev, "%s done\n", __func__); +} + +static void send_irq(void *hw_arg) +{ + struct xrp_hw_hikey *hw = hw_arg; + + switch (hw->device_irq_mode) { + case XRP_IRQ_EDGE: + case XRP_IRQ_LEVEL: + send_cmd_async(hw_arg, HISI_RPROC_HIFI_MBX18, 0); + break; + default: + break; + } +} + +static void irq_handler(void *dev_id) +{ + struct xrp_hw_hikey *hw = dev_id; + + dev_dbg(hw->dev, "%s\n", __func__); + xrp_irq_handler(0, hw->xrp); + DRV_k3IpcIntHandler_Autoack(); +} + +static void *irq_handler_context; +static void irq1_handler(unsigned int dummy) +{ + irq_handler(irq_handler_context); +} + +static bool panic_check(void *hw_arg) +{ + struct xrp_hw_hikey *hw = hw_arg; + uint32_t panic; + uint32_t ccount; + uint32_t read; + uint32_t write; + uint32_t size; + + if (!hw->panic) + return false; + + panic = __raw_readl(&hw->panic->panic); + ccount = __raw_readl(&hw->panic->ccount); + read = __raw_readl(&hw->panic->rb.read); + write = __raw_readl(&hw->panic->rb.write); + size = __raw_readl(&hw->panic->rb.size); + + if (read == 0 && read != hw->last_read) { + dev_warn(hw->dev, "****************** device restarted >>>>>>>>>>>>>>>>>\n"); + dump_log_page(hw); + dev_warn(hw->dev, "<<<<<<<<<<<<<<<<<< device restarted *****************\n"); + } + if (write < size && read < size && size < PAGE_SIZE) { + uint32_t tail; + uint32_t total; + char *buf = NULL; + + hw->last_read = read; + if (read < write) { + tail = write - read; + total = tail; + } else if (read == write) { + tail = 0; + total = 0; + } else { + tail = size - read; + total = write + tail; + } + + if (total) + buf = kmalloc(total, GFP_KERNEL); + + if (buf) { + uint32_t off = 0; + + dev_dbg(hw->dev, "panic = 0x%08x, ccount = 0x%08x read = %d, write = %d, size = %d, total = %d", + panic, ccount, read, write, size, total); + + while (off != total) { + memcpy_fromio(buf + off, + hw->panic->rb.data + read, + tail); + read = 0; + off += tail; + tail = total - tail; + } + __raw_writel(write, &hw->panic->rb.read); + hw->last_read = write; + dev_info(hw->dev, "<<<\n%.*s\n>>>\n", + total, buf); + kfree(buf); + } else if (total) { + dev_err(hw->dev, + "%s: couldn't allocate memory (%d) to read the dump\n", + __func__, total); + } + } else { + if (read != hw->last_read) { + dev_warn(hw->dev, + "nonsense in the log buffer: read = %d, write = %d, size = %d\n", + read, write, size); + hw->last_read = read; + } + } + if (panic == 0xdeadbabe) { + dev_info(hw->dev, "%s: panic detected, log dump:\n", __func__); + dump_log_page(hw); + } + + return panic == 0xdeadbabe; +} + +static const struct xrp_hw_ops hw_ops = { + .enable = enable, + .disable = disable, + .halt = halt, + .release = release, + .reset = reset, + + .get_hw_sync_data = get_hw_sync_data, + + .send_irq = send_irq, + + .panic_check = panic_check, +}; + +static long init_hw(struct platform_device *pdev, struct xrp_hw_hikey *hw, + int mem_idx, enum xrp_init_flags *init_flags) +{ + struct resource *mem; + long ret; + + mem = platform_get_resource(pdev, IORESOURCE_MEM, mem_idx); + if (mem) { + hw->panic = devm_ioremap_resource(&pdev->dev, mem); + if (IS_ERR(hw->panic)) { + dev_dbg(&pdev->dev, + "%s: couldn't ioremap abort/log region: %ld\n", + __func__, PTR_ERR(hw->panic)); + hw->panic = NULL; + } else { + dev_dbg(&pdev->dev, + "%s: log ring buffer = %pap, mapped at %p\n", + __func__, &mem->start, hw->panic); + } + } + + ret = of_property_read_u32(pdev->dev.of_node, + "device-irq", + &hw->device_irq); + if (ret == 0) { + hw->device_irq_mode = XRP_IRQ_LEVEL; + dev_dbg(&pdev->dev, + "%s: device IRQ = %d\n", + __func__, hw->device_irq); + } else { + dev_info(&pdev->dev, + "using polling mode on the device side\n"); + } + + ret = of_property_read_u32(pdev->dev.of_node, + "host-irq", + &hw->host_irq); + if (ret == 0) { + hw->host_irq_mode = XRP_IRQ_LEVEL; + dev_dbg(&pdev->dev, "%s: using host IRQ\n", __func__); + irq_handler_context = hw; + DRV_IPCIntInit(); + IPC_IntConnect(IPC_ACPU_INT_SRC_HIFI_MSG, + irq1_handler, 0); + IPC_IntEnable(IPC_ACPU_INT_SRC_HIFI_MSG); + *init_flags |= XRP_INIT_USE_HOST_IRQ; + } else { + dev_info(&pdev->dev, "using polling mode on the host side\n"); + } + return 0; +} + +typedef long init_function(struct platform_device *pdev, + struct xrp_hw_hikey *hw); + +static init_function init_v1; +static long init_v1(struct platform_device *pdev, struct xrp_hw_hikey *hw) +{ + long ret; + enum xrp_init_flags init_flags = 0; + + ret = init_hw(pdev, hw, 1, &init_flags); + if (ret < 0) + return ret; + + return xrp_init_v1(pdev, init_flags, &hw_ops, hw); +} + +static init_function init_cma; +static long init_cma(struct platform_device *pdev, struct xrp_hw_hikey *hw) +{ + long ret; + enum xrp_init_flags init_flags = 0; + + ret = init_hw(pdev, hw, 0, &init_flags); + if (ret < 0) + return ret; + + return xrp_init_cma(pdev, init_flags, &hw_ops, hw); +} + +#ifdef CONFIG_OF +static const struct of_device_id xrp_hw_hikey_match[] = { + { + .compatible = "cdns,xrp-hw-hikey960,v1", + .data = init_v1, + }, { + .compatible = "cdns,xrp-hw-hikey960,cma", + .data = init_cma, + }, {}, +}; +MODULE_DEVICE_TABLE(of, xrp_hw_hikey_match); +#endif + +static int xrp_hw_hikey_probe(struct platform_device *pdev) +{ + struct xrp_hw_hikey *hw = + devm_kzalloc(&pdev->dev, sizeof(*hw), GFP_KERNEL); + const struct of_device_id *match; + init_function *init; + long ret; + + if (!hw) + return -ENOMEM; + + match = of_match_device(of_match_ptr(xrp_hw_hikey_match), + &pdev->dev); + if (!match) + return -ENODEV; + + hw->dev = &pdev->dev; + init = match->data; + ret = init(pdev, hw); + if (IS_ERR_VALUE(ret)) { + xrp_deinit(pdev); + return ret; + } else { + hw->xrp = ERR_PTR(ret); + return 0; + } + +} + +static int xrp_hw_hikey_remove(struct platform_device *pdev) +{ + /* + * There's no way to disconnect from IPC or disable IPC IRQ. + * Do it here when it's available. + */ + return xrp_deinit(pdev); +} + +static int xrp_hw_hikey_idle(struct device *dev) +{ + /* Power management is flaky, don't do it now. */ + return 1; +} + +static const struct dev_pm_ops xrp_hw_hikey_pm_ops = { + SET_RUNTIME_PM_OPS(xrp_runtime_suspend, + xrp_runtime_resume, + xrp_hw_hikey_idle) +}; + +static struct platform_driver xrp_hw_hikey_driver = { + .probe = xrp_hw_hikey_probe, + .remove = xrp_hw_hikey_remove, + .driver = { + .name = DRIVER_NAME, + .of_match_table = of_match_ptr(xrp_hw_hikey_match), + .pm = &xrp_hw_hikey_pm_ops, + }, +}; + +module_platform_driver(xrp_hw_hikey_driver); + +MODULE_AUTHOR("Max Filippov"); +MODULE_DESCRIPTION("XRP HiKey960: low level device driver for Xtensa Remote Processing"); +MODULE_LICENSE("Dual MIT/GPL"); diff --git a/driver/xrp-kernel/xrp_hw_hikey960_dsp_interface.h b/driver/xrp-kernel/xrp_hw_hikey960_dsp_interface.h new file mode 100644 index 0000000..be39317 --- /dev/null +++ b/driver/xrp-kernel/xrp_hw_hikey960_dsp_interface.h @@ -0,0 +1,53 @@ +/* + * XRP interface between hardware-specific linux and DSP parts of HiKey960 + * + * Copyright (c) 2018 Cadence Design Systems, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Alternatively you can use and distribute this file under the terms of + * the GNU General Public License version 2 or later. + */ + +#ifndef _XRP_KERNEL_HIKEY960_DSP_INTERFACE +#define _XRP_KERNEL_HIKEY960_DSP_INTERFACE + +#include "xrp_ring_buffer.h" + +enum { + XRP_DSP_SYNC_IRQ_MODE_NONE = 0x0, + XRP_DSP_SYNC_IRQ_MODE_LEVEL = 0x1, + XRP_DSP_SYNC_IRQ_MODE_EDGE = 0x2, +}; + +struct xrp_hw_hikey960_sync_data { + __u32 host_irq_mode; + __u32 device_irq_mode; + __u32 device_irq; +}; + +struct xrp_hw_hikey960_panic { + __u32 panic; + __u32 ccount; + __u32 reserved[2]; + struct xrp_ring_buffer rb; +}; + +#endif diff --git a/driver/xrp-kernel/xrp_hw_simple.c b/driver/xrp-kernel/xrp_hw_simple.c new file mode 100644 index 0000000..c098e2e --- /dev/null +++ b/driver/xrp-kernel/xrp_hw_simple.c @@ -0,0 +1,1158 @@ +/* + * xrp_hw_simple: Simple xtensa/arm low-level XRP driver + * + * Copyright (c) 2017 Cadence Design Systems, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Alternatively you can use and distribute this file under the terms of + * the GNU General Public License version 2 or later. + */ + +#include +// #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "xrp_kernel_defs.h" +#include "xrp_hw.h" +#include "xrp_hw_simple_dsp_interface.h" + +#define DRIVER_NAME "xrp-hw-simple" + +#define XRP_REG_RESET (0x28) +#define RESET_BIT_MASK (0x1<<8) + +#define CDNS_DSP_RRG_OFFSET (0x4000) +#define XRP_REG_RUNSTALL (CDNS_DSP_RRG_OFFSET+0x20) +#define START_VECTOR_SEL (CDNS_DSP_RRG_OFFSET+0x1C) +#define ALT_RESET_VEC (CDNS_DSP_RRG_OFFSET+0x18) +// #define DSP_INT_MASK (0x1<<1) +// #define INT_DSP_MASK (0x1<<1) +#define VI_SYS_OFFSET_MASK (0x00000FFF) + +#ifdef WITH_VISYS_KO +extern int k_bm_visys_write_reg(uint32_t offset, uint32_t value); +extern int k_bm_visys_read_reg(uint32_t offset, uint32_t *value); +#endif +enum xrp_irq_mode { + XRP_IRQ_NONE, + XRP_IRQ_LEVEL, + XRP_IRQ_EDGE, + XRP_IRQ_EDGE_SW, + XRP_IRQ_MAX, +}; + +struct xrp_hw_simple { + struct xvp *xrp; + phys_addr_t dev_regs_phys; + void __iomem *dev_regs; + /* IRQ register base phy address on device side */ + phys_addr_t irq_regs_dev_phys; + /* Device IRQ register phy base addr on host side */ + phys_addr_t device_irq_regs_phys; + /* Device IRQ register virtual base addr on host side */ + void __iomem *device_irq_regs; + /* host IRQ register phy base addr on host side */ + phys_addr_t host_irq_regs_phys; + /* host IRQ register virtual base addr on host side */ + void __iomem *host_irq_regs; + /* how IRQ is used to notify the device of incoming data */ + enum xrp_irq_mode device_irq_mode; + /* + * offset of device IRQ register in MMIO region (device side) + * bit number + * device IRQ# + */ + u32 device_irq[3]; + /* offset of devuce IRQ register in MMIO region (host side) */ + u32 device_irq_host_offset; + /* how IRQ is used to notify the host of incoming data */ + enum xrp_irq_mode host_irq_mode; + /* + * offset of IRQ register (host side) + * bit number + */ + u32 host_irq[2]; + /* + offset of IRQ register (device side to trigger) + */ + u32 host_irq_offset; + u32 device_id; + + struct xrp_hw_panic __iomem *panic; + phys_addr_t panic_phys; + u32 last_read; + + struct proc_dir_entry *log_proc_file; + struct clk *cclk; + // struct clk *aclk; + struct clk *pclk; +}; + +// static inline void irq_reg_write32(struct xrp_hw_simple *hw, unsigned addr, u32 v) +// { +// if (hw->irq_regs) +// // pr_debug("%s,irq Addr %llx\n",__func__,(unsigned long long)(hw->regs + addr)); +// __raw_writel(v, hw->irq_regs + addr); +// } + +static inline void host_irq_reg_write32(struct xrp_hw_simple *hw, unsigned int addr, u32 v) +{ + if( IOMEM_ERR_PTR(-EBUSY) ==hw->host_irq_regs ) + { + #ifdef WITH_VISYS_KO + uint32_t offset = ((uint32_t)(hw->host_irq_regs_phys&VI_SYS_OFFSET_MASK)+addr); + // pr_debug("%s,vi sys write (%x,%d)\n",__func__,offset,v); + k_bm_visys_write_reg(offset, v); + #else + pr_debug("%s,vi sys Error,need enable VISYS KO\n",__func__); + #endif + return; + } + if (hw->host_irq_regs) + pr_debug("%s,irq Addr %llx\n",__func__,(unsigned long long)(hw->host_irq_regs + addr)); + __raw_writel(v, hw->host_irq_regs + addr); +} + +static inline void device_irq_reg_write32(struct xrp_hw_simple *hw, unsigned int addr, u32 v) +{ + if( IOMEM_ERR_PTR(-EBUSY) ==hw->device_irq_regs ) + { + #ifdef WITH_VISYS_KO + uint32_t offset = ((uint32_t)(hw->device_irq_regs_phys&VI_SYS_OFFSET_MASK)+addr); + pr_debug("%s,vi sys write (%lx,%x,0x%x,%d)\n",__func__,hw->device_irq_regs_phys,addr,offset,v); + k_bm_visys_write_reg(offset, v); + #else + pr_debug("%s,vi sys Error,need enable VISYS KO\n",__func__); + #endif + return; + } + if (hw->device_irq_regs) + pr_debug("%s,irq Addr %llx\n",__func__,(unsigned long long)(hw->device_irq_regs + addr)); + __raw_writel(v, hw->device_irq_regs + addr); +} + +// static inline u32 irq_reg_read32(struct xrp_hw_simple *hw, unsigned addr) +// { +// if (hw->irq_regs) +// return __raw_readl(hw->irq_regs + addr); +// else +// return 0; +// } + +static inline u32 host_irq_reg_read32(struct xrp_hw_simple *hw, unsigned addr) +{ + if( IOMEM_ERR_PTR(-EBUSY) ==hw->host_irq_regs ) + { + + uint32_t offset = ((uint32_t)(hw->host_irq_regs_phys&VI_SYS_OFFSET_MASK)+(uint32_t)addr); + uint32_t v=0; + #ifdef WITH_VISYS_KO + k_bm_visys_read_reg(offset,&v); + // pr_debug("%s,vi sys read (%x,%d)\n",__func__,offset,v); + #else + pr_err("%s,vi sys Error,need enable VISYS KO\n",__func__); + #endif + return v; + + } + + if (hw->host_irq_regs) + return __raw_readl(hw->host_irq_regs + addr); + else + return 0; +} + +static inline u32 device_irq_reg_read32(struct xrp_hw_simple *hw, unsigned addr) +{ + if( IOMEM_ERR_PTR(-EBUSY) ==hw->device_irq_regs ) + { + + uint32_t offset = ((uint32_t)(hw->device_irq_regs_phys&VI_SYS_OFFSET_MASK)+(uint32_t)addr); + uint32_t v = 0; + #ifdef WITH_VISYS_KO + k_bm_visys_read_reg(offset,&v); + // pr_debug("%s,vi sys write (%x,%d)\n",__func__,offset,v); + #else + pr_error("%s,vi sys Error,need enable VISYS KO\n",__func__); + #endif + return v; + + } + + if (hw->device_irq_regs) + return __raw_readl(hw->device_irq_regs + addr); + else + return 0; +} + +static inline void dev_reg_write32(struct xrp_hw_simple *hw, unsigned addr, u32 v) +{ + if (hw->dev_regs) + + //pr_debug("%s,write to dev Addr %p,value:%x\n",__func__,(hw->dev_regs + addr),v); + __raw_writel(v, hw->dev_regs + addr); +} + +static inline u32 dev_reg_read32(struct xrp_hw_simple *hw, unsigned addr) +{ + if (hw->dev_regs) + return __raw_readl(hw->dev_regs + addr); + else + return 0; +} + +static void dump_regs(const char *fn, void *hw_arg) +{ + struct xrp_hw_simple *hw = hw_arg; + + if (!hw->panic) + return; + + pr_debug("%s: panic = 0x%08x, ccount = 0x%08x\n", + fn, + __raw_readl(&hw->panic->panic), + __raw_readl(&hw->panic->ccount)); + pr_debug("%s: read = 0x%08x, write = 0x%08x, size = 0x%08x\n", + fn, + __raw_readl(&hw->panic->rb.read), + __raw_readl(&hw->panic->rb.write), + __raw_readl(&hw->panic->rb.size)); +} + +static void dump_log_page(struct xrp_hw_simple *hw) +{ + char *buf; + size_t i; + + if (!hw->panic) + return; + + dump_regs(__func__, hw); + buf = kmalloc(PAGE_SIZE, GFP_KERNEL); + if (buf) { + memcpy_fromio(buf, hw->panic, hw->panic->rb.size); + buf+=sizeof(struct xrp_hw_panic); + for (i = 0; i < hw->panic->rb.size; i += 64) + pr_debug(" %*pEhp\n", 64, buf + i); + kfree(buf); + } else { + pr_debug("(couldn't allocate copy buffer)\n"); + } +} + +static int log_proc_show(struct seq_file *file, void *v) +{ + struct xrp_hw_simple *hw = file->private; + char *buf; + size_t i; + dump_regs(__func__, hw); + buf = kmalloc(PAGE_SIZE, GFP_KERNEL); + if (buf) { + memcpy_fromio(buf, hw->panic->rb.data, hw->panic->rb.size); + seq_printf(file,"****************** device log >>>>>>>>>>>>>>>>>\n"); + for (i = 0; i < hw->panic->rb.size; i += 64) + seq_printf(file," %*pEp", 64,buf+i); + // pr_debug(" %*pEhp\n", 64, buf + i); + // seq_printf(file," %*pEp\n",buf); + kfree(buf); + + uint32_t write = __raw_readl(&hw->panic->rb.write); + __raw_writel(write, &hw->panic->rb.read); + + return 0; + } + else + { + pr_debug("Fail to alloc buf\n"); + return -1; + } + return 0; +} + +static int log_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, log_proc_show, NULL); +} + +static const struct file_operations log_proc_fops = { + .open = log_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +int xrp_hw_create_log_proc(struct xrp_hw_simple *hw) +{ + int rv = 0; + char file_name[32]; + sprintf(file_name,"dsp%d_proc",hw->device_id); + // hw->log_proc_file = create_proc_entry(file_name,0644,NULL); + hw->log_proc_file = proc_mkdir(file_name, NULL); + if (NULL == hw->log_proc_file ) + { + pr_debug("Error: Could not create dir\n"); + return -ENODEV; + } + + // hw->log_proc_file = proc_create_data(file_name,0644,S_IFREG | S_IRUGO,&log_proc_fops,hw); + hw->log_proc_file=proc_create_single_data("dsp_log",0644,hw->log_proc_file,&log_proc_show,hw); + + if(hw->log_proc_file == NULL) { + rv = -ENOMEM; + pr_debug("Error: Could not initialize %s\n","dsp_log"); + } else { + + pr_debug("%s create Success!\n","dsp_log"); + } + return rv; +} + +void xrp_hw_remove_log_proc(void *hw_arg) +{ + char file_name[32]; + struct xrp_hw_simple *hw = hw_arg; + sprintf(file_name,"dsp%d_proc",hw->device_id); + remove_proc_entry(file_name,NULL); + // proc_remove(hw->log_proc_file); + pr_debug("%s,proc removed\n",file_name); +} + +// int xrp_hw_log_read(char *buffer,char** buffer_location,off_t offset, +// int buffer_length,int *eof,void *data) +// { +// int len = 0; +// struct xrp_hw_simple *hw = data; + +// if(offset > 0) { +// printk(KERN_INFO "offset %d: /proc/test1: profile_read,\ +// wrote %d Bytes\n",(int)(offset),len); +// *eof = 1; +// return len; +// } +// //填充buffer并获取其长度 +// len = sprintf(buffer, +// "For the %d %s time,go away!\n",count, +// (count % 100 > 10 && count % 100 < 14)?"th": +// (count % 10 == 1)?"st": +// (count % 10 == 2)?"nd": +// (count % 10 == 3)?"rd":"th"); +// count++; +// printk(KERN_INFO "leasving /proc/test1: profile_read,wrote %d Bytes\n",len); +// return len; +// } + +static void *get_hw_sync_data(void *hw_arg, size_t *sz) +{ + static const u32 irq_mode[] = { + [XRP_IRQ_NONE] = XRP_DSP_SYNC_IRQ_MODE_NONE, + [XRP_IRQ_LEVEL] = XRP_DSP_SYNC_IRQ_MODE_LEVEL, + [XRP_IRQ_EDGE] = XRP_DSP_SYNC_IRQ_MODE_EDGE, + [XRP_IRQ_EDGE_SW] = XRP_DSP_SYNC_IRQ_MODE_EDGE, + }; + struct xrp_hw_simple *hw = hw_arg; + struct xrp_hw_simple_sync_data *hw_sync_data = + kmalloc(sizeof(*hw_sync_data), GFP_KERNEL); + + if (!hw_sync_data) + return NULL; + u32 device_host_offset=0; + u32 host_device_offset=0; + if(hw->device_irq_regs_phys > hw->host_irq_regs_phys) + { + device_host_offset = hw->device_irq_regs_phys-hw->host_irq_regs_phys; + } + else + { + host_device_offset = hw->host_irq_regs_phys-hw->device_irq_regs_phys; + } + *hw_sync_data = (struct xrp_hw_simple_sync_data){ + .device_mmio_base = hw->irq_regs_dev_phys, + .host_irq_mode = hw->host_irq_mode, + .host_irq_offset = hw->host_irq_offset+host_device_offset, + .host_irq_bit = hw->host_irq[1], + .device_irq_mode = irq_mode[hw->device_irq_mode], + .device_irq_offset = hw->device_irq[0]+device_host_offset, + .device_irq_bit = hw->device_irq[1], + .device_irq = hw->device_irq[2], + // .panic_base = hw->panic_phys, + }; + *sz = sizeof(*hw_sync_data); + return hw_sync_data; +} + +static void reset(void *hw_arg) +{ + // dev_reg_write32(hw_arg, XRP_REG_RESET, (dev_reg_read32(hw_arg, XRP_REG_RESET))^RESET_BIT_MASK); + // udelay(10000); + // dev_reg_write32(hw_arg, XRP_REG_RESET, (dev_reg_read32(hw_arg, XRP_REG_RESET))^RESET_BIT_MASK); + struct xrp_hw_simple *hw = hw_arg; + xrp_set_reset_reg(hw->device_id); +} + +static void halt(void *hw_arg) +{ + dev_reg_write32(hw_arg, XRP_REG_RUNSTALL, 1); + + pr_debug("%s: halt value:%x\n",__func__,dev_reg_read32(hw_arg, XRP_REG_RUNSTALL)); + // dump_log_page(hw_arg); +} + +static void set_reset_vector(void *hw_arg,u32 addr) +{ + struct xrp_hw_simple *hw = hw_arg; + // if(hw->device_id ==0) + // { + // addr = 0x80000000; + // } + // else{ + // addr = 0x70000000; + // } + addr = addr&0xffffff00; + dev_reg_write32(hw_arg, ALT_RESET_VEC, addr); + pr_debug("%s: reset_vector:%x\n",__func__,dev_reg_read32(hw_arg, ALT_RESET_VEC)); +} +static void release(void *hw_arg) +{ + dev_reg_write32(hw_arg, XRP_REG_RUNSTALL, 0); +} + +static void send_irq(void *hw_arg) +{ + struct xrp_hw_simple *hw = hw_arg; + pr_debug("%s: Enter\n",__func__); + switch (hw->device_irq_mode) { + case XRP_IRQ_EDGE_SW: + device_irq_reg_write32(hw, hw->device_irq_host_offset, + BIT(hw->device_irq[1])); + while ((device_irq_reg_read32(hw, hw->device_irq_host_offset) & + BIT(hw->device_irq[1]))) + mb(); + break; + case XRP_IRQ_EDGE: + device_irq_reg_write32(hw, hw->device_irq_host_offset, 0); + /* fallthrough */ + case XRP_IRQ_LEVEL: + wmb(); + device_irq_reg_write32(hw, hw->device_irq_host_offset, + BIT(hw->device_irq[1])); + + break; + default: + break; + } +} +static int enable(void *hw_arg) +{ + struct xrp_hw_simple *hw = hw_arg; + int ret; + ret = clk_prepare_enable(hw->cclk); + if (ret < 0) { + pr_err("could not prepare or enable core clock\n"); + return ret; + } + + // ret = clk_prepare_enable(hw->aclk); + // if (ret < 0) { + // pr_err("could not prepare or enable axi clock\n"); + // clk_disable_unprepare(hw->cclk); + // return ret; + // } + + ret = clk_prepare_enable(hw->pclk); + if (ret < 0) { + pr_err("could not prepare or enable apb clock\n"); + clk_disable_unprepare(hw->cclk); + // clk_disable_unprepare(hw->aclk); + return ret; + } + pr_debug("%s: enable dsp\n",__func__); + return ret; +} + +static void disable(void *hw_arg) +{ + struct xrp_hw_simple *hw = hw_arg; + clk_disable_unprepare(hw->pclk); + // clk_disable_unprepare(hw->aclk); + clk_disable_unprepare(hw->cclk); + pr_debug("%s: disable dsp\n",__func__); + return; +} +static inline void ack_irq(void *hw_arg) +{ + struct xrp_hw_simple *hw = hw_arg; + + if (hw->host_irq_mode == XRP_IRQ_LEVEL) + host_irq_reg_write32(hw, hw->host_irq[0], BIT(hw->host_irq[1])); + //__raw_writel(DSP_INT_MASK,0xFFE4040190); //DSP0 +} +static inline bool is_expect_irq(struct xrp_hw_simple *hw) +{ + return host_irq_reg_read32(hw,hw->host_irq_offset)&BIT(hw->host_irq[1]); +} +static irqreturn_t irq_handler(int irq, void *dev_id) +{ + irqreturn_t ret=IRQ_NONE; + struct xrp_hw_simple *hw = dev_id; + + if(is_expect_irq(hw)) + { + ret = xrp_irq_handler(irq, hw->xrp); + + if (ret == IRQ_HANDLED) + ack_irq(hw); + + } + else{ + pr_err("%s: unexpect irq,%x\n",__func__,host_irq_reg_read32(hw,hw->host_irq_offset)); + } + + + return ret; +} + +phys_addr_t get_irq_base_mimo(void *hw_arg) +{ + struct xrp_hw_simple *hw = hw_arg; + pr_debug("%s: dev_regs\n",__func__); + return hw->device_irq_regs_phys < hw->host_irq_regs_phys?hw->device_irq_regs_phys:hw->host_irq_regs_phys; +} + +void update_device_base(void *hw_arg,phys_addr_t addr) +{ + struct xrp_hw_simple *hw = hw_arg; + hw->irq_regs_dev_phys = addr; + pr_debug("%s:dev_regs,%p\n",__func__,hw->irq_regs_dev_phys); +} +void memcpy_tohw(volatile void __iomem *dst, const void *src, size_t sz) +{ + + int i; + u32 *s_ptr = src; + volatile u32 * d_ptr=dst; + pr_debug("%s,dst:0x%llx,src:0x%llx,size:%d",__FUNCTION__,dst,src,sz); + udelay(10000); + for(i=0;i= 8) { + __raw_writeq(*(u64 *)from, to); + from += 8; + to += 8; + count -= 8; + } + + while (count) { + __raw_writeb(*(u8 *)from, to); + from++; + to++; + count--; + } +} + +void memset_hw_local(volatile void __iomem *dst, int c, size_t count) +{ + u64 qc = (u8)c; + + qc |= qc << 8; + qc |= qc << 16; + qc |= qc << 32; + while (count && !IS_ALIGNED((unsigned long)dst, 8)) { + __raw_writeb(c, dst); + dst++; + count--; + } + + while (count >= 8) { + __raw_writeq(qc, dst); + dst += 8; + count -= 8; + } + + while (count) { + __raw_writeb(c, dst); + dst++; + count--; + } +} +void memset_hw(void __iomem *dst, int c, size_t sz) +{ + int i; + volatile u32 * d_ptr=dst; + for(i=0;ixrp->dev, paddr, sz,DMA_TO_DEVICE); +// break; +// } +// } + +// static void dma_sync_for_cpu(void *hw_arg, +// void *vaddr, phys_addr_t paddr, +// unsigned long sz, unsigned flags) +// { +// struct xrp_hw_simple *hw = hw_arg; +// switch (flags) { +// case XRP_FLAG_WRITE: +// case XRP_FLAG_READ_WRITE: +// arch_sync_dma_for_cpu(hw->xrp->dev, paddr, sz,DMA_FROM_DEVICE); +// break; +// } +// } +#endif + +static bool panic_check(void *hw_arg) +{ + struct xrp_hw_simple *hw = hw_arg; + uint32_t panic; + uint32_t ccount; + uint32_t read; + uint32_t write; + uint32_t size; + + if (!hw->panic) + return false; + + panic = __raw_readl(&hw->panic->panic); + ccount = __raw_readl(&hw->panic->ccount); + read = __raw_readl(&hw->panic->rb.read); + write = __raw_readl(&hw->panic->rb.write); + size = __raw_readl(&hw->panic->rb.size); + + if (read == 0 && read != hw->last_read) { + pr_debug( "****************** device restarted >>>>>>>>>>>>>>>>>\n"); + dump_log_page(hw); + pr_debug ("<<<<<<<<<<<<<<<<<< device restarted *****************\n"); + } + if (write < size && read < size && size < PAGE_SIZE) { + uint32_t tail; + uint32_t total; + char *buf = NULL; + + hw->last_read = read; + if (read < write) { + tail = write - read; + total = tail; + } else if (read == write) { + tail = 0; + total = 0; + } else { + tail = size - read; + total = write + tail; + } + + if (total) + buf = kmalloc(total, GFP_KERNEL); + + if (buf) { + uint32_t off = 0; + + pr_debug("panic = 0x%08x, ccount = 0x%08x read = %d, write = %d, size = %d, total = %d", + panic, ccount, read, write, size, total); + + while (off != total) { + memcpy_fromio(buf + off, + hw->panic->rb.data + read, + tail); + read = 0; + off += tail; + tail = total - tail; + } + __raw_writel(write, &hw->panic->rb.read); + hw->last_read = write; + pr_debug("<<<\n%.*s\n>>>\n", + total, buf); + kfree(buf); + } else if (total) { + pr_debug( + "%s: couldn't allocate memory (%d) to read the dump\n", + __func__, total); + } + } else { + if (read != hw->last_read) { + pr_debug( + "nonsense in the log buffer: read = %d, write = %d, size = %d\n", + read, write, size); + hw->last_read = read; + } + } + if (panic == 0xdeadbabe) { + pr_debug("%s: panic detected, log dump:\n", __func__); + dump_log_page(hw); + } + + return panic == 0xdeadbabe; +} + + +static bool xrp_panic_init(struct xrp_hw_panic* panic,size_t size) +{ + if(size < sizeof(struct xrp_hw_panic)) + { + return false; + } + memset_hw(panic,0x0,size); + panic->panic = 0; + panic->ccount = 0; + panic->rb.read = 0; + panic->rb.write = 0; + panic->rb.size = size - sizeof(struct xrp_hw_panic); + sprintf(panic->rb.data,"Inition dsp log\n"); + return true; +} +static const struct xrp_hw_ops hw_ops = { + .halt = halt, + .release = release, + .reset = reset, + .enable = enable, + .disable = disable, + .get_hw_sync_data = get_hw_sync_data, + + .send_irq = send_irq, + .get_base_mimo = get_irq_base_mimo, + .update_device_base = update_device_base, + .set_reset_vector = set_reset_vector, + .memcpy_tohw= memcpy_toio_local, + .memset_hw = memset_hw_local, + .clear_hw = xrp_hw_remove_log_proc, +#if defined(__XTENSA__) || defined(__arm__) + .cacheable = cacheable, + .dma_sync_for_device = dma_sync_for_device, + .dma_sync_for_cpu = dma_sync_for_cpu, +#endif +}; + +static long init_hw_irq(struct platform_device *pdev, struct xrp_hw_simple *hw, + int mem_idx, enum xrp_init_flags *init_flags) +{ + struct resource *mem; + int irq; + long ret; + + mem = platform_get_resource(pdev, IORESOURCE_MEM, mem_idx++); + if (!mem) { + ret = -ENODEV; + goto err; + } + hw->host_irq_regs_phys = mem->start; + // hw->irq_regs_dev_phys =hw->irq_regs_phys; + hw->host_irq_regs = devm_ioremap_resource(&pdev->dev, mem); + pr_debug("%s:host irq regs = %pap/%p\n", + __func__, &mem->start, hw->host_irq_regs); + + + ret = of_property_read_u32_array(pdev->dev.of_node, "host-irq", + hw->host_irq, + ARRAY_SIZE(hw->host_irq)); + if (ret == 0) { + u32 host_irq_mode; + + ret = of_property_read_u32(pdev->dev.of_node, + "host-irq-mode", + &host_irq_mode); + if (host_irq_mode < XRP_IRQ_MAX) + hw->host_irq_mode =host_irq_mode; + else + ret = -ENOENT; + u32 host_irq_offset; + ret = of_property_read_u32(pdev->dev.of_node, + "host-irq-offset", + &host_irq_offset); + + if(ret == 0) + { + hw->host_irq_offset=host_irq_offset; + } + + dev_dbg(&pdev->dev, + "%s: Host IRQ MMIO: device offset = 0x%08x,host offset = 0x%08x, bit = %d,IRQ mode = %d", + __func__, hw->host_irq_offset, + hw->host_irq[0], hw->host_irq[1], + hw->host_irq_mode); + + } + + mem = platform_get_resource(pdev, IORESOURCE_MEM, mem_idx); + if (!mem) { + ret = -ENODEV; + goto err; + } + hw->device_irq_regs_phys = mem->start; + // hw->irq_regs_dev_phys =hw->irq_regs_phys; + hw->device_irq_regs = devm_ioremap_resource(&pdev->dev, mem); + pr_debug("%s:Device irq regs = %pap/%lx\n", + __func__, &mem->start, hw->device_irq_regs_phys); + + ret = of_property_read_u32_array(pdev->dev.of_node, + "device-irq", + hw->device_irq, + ARRAY_SIZE(hw->device_irq)); + if (ret == 0) { + u32 device_irq_host_offset; + + ret = of_property_read_u32(pdev->dev.of_node, + "device-irq-host-offset", + &device_irq_host_offset); + if (ret == 0) { + hw->device_irq_host_offset = device_irq_host_offset; + } else { + hw->device_irq_host_offset = hw->device_irq[0]; + ret = 0; + } + } + if (ret == 0) { + u32 device_irq_mode; + + ret = of_property_read_u32(pdev->dev.of_node, + "device-irq-mode", + &device_irq_mode); + if (device_irq_mode < XRP_IRQ_MAX) + hw->device_irq_mode = device_irq_mode; + else + ret = -ENOENT; + } + if (ret == 0) { + dev_dbg(&pdev->dev, + "%s: device IRQ MMIO host offset = 0x%08x, offset = 0x%08x, bit = %d, device IRQ = %d, IRQ mode = %d", + __func__, hw->device_irq_host_offset, + hw->device_irq[0], hw->device_irq[1], + hw->device_irq[2], hw->device_irq_mode); + } else { + dev_info(&pdev->dev, + "using polling mode on the device side\n"); + } + + + if (ret == 0 && hw->host_irq_mode != XRP_IRQ_NONE) + irq = platform_get_irq(pdev, 0); + else + irq = -1; + + if (irq >= 0) { + dev_dbg(&pdev->dev, "%s: host IRQ = %d, ", + __func__, irq); + ret = devm_request_irq(&pdev->dev, irq, irq_handler, + IRQF_SHARED, pdev->name, hw); + if (ret < 0) { + dev_err(&pdev->dev, "request_irq %d failed\n", irq); + goto err; + } + *init_flags |= XRP_INIT_USE_HOST_IRQ; + } else { + dev_info(&pdev->dev, "using polling mode on the host side\n"); + } + + ret = 0; +err: + return ret; +} + +static long init_hw_device(struct platform_device *pdev, struct xrp_hw_simple *hw,int mem_idx) +{ + struct resource *mem; + + long ret; + + mem = platform_get_resource(pdev, IORESOURCE_MEM, mem_idx++); + if (!mem) { + ret = -ENODEV; + goto err; + } + hw->dev_regs_phys = mem->start; + hw->dev_regs = devm_ioremap_resource(&pdev->dev, mem); + pr_debug("%s: regs = %pap/%p\n", + __func__, &mem->start, hw->dev_regs); + + + + hw->cclk = devm_clk_get(&pdev->dev, "cclk"); + if (hw->cclk==NULL) { + dev_err(&pdev->dev, "failed to get core clock\n"); + ret = -ENOENT; + goto err; + } + dev_dbg(&pdev->dev, "get core clock\n"); + // hw->aclk = devm_clk_get(&pdev->dev, "aclk"); + // if (hw->aclk==NULL) { + // dev_err(&pdev->dev, "failed to get axi clock\n"); + // ret = -ENOENT; + // goto err; + // } + + hw->pclk = devm_clk_get(&pdev->dev, "pclk"); + if ( hw->pclk ==NULL) { + dev_err(&pdev->dev, "failed to get apb clock\n"); + ret = -ENOENT; + goto err; + } + dev_dbg(&pdev->dev, "get apb clock\n"); + u32 device_id; + + ret = of_property_read_u32(pdev->dev.of_node,"dsp",&device_id); + if(ret ==0 ) + { + hw->device_id = device_id; + pr_debug("%s: device_id = %d\n", + __func__,hw->device_id); + } + else{ + pr_debug("%s: no device_id \n",__func__); + ret = -ENODEV; + } + // xrp_hw_create_log_proc(hw); + +err: + return ret; +} +static long init(struct platform_device *pdev, struct xrp_hw_simple *hw) +{ + long ret; + enum xrp_init_flags init_flags = 0; + + ret = init_hw_irq(pdev, hw, 0, &init_flags); + if (ret < 0) + return ret; + ret =init_hw_device(pdev, hw, 2); + if (ret < 0) + return ret; + return xrp_init(pdev, init_flags, &hw_ops, hw,4); +} + +static long init_v1(struct platform_device *pdev, struct xrp_hw_simple *hw) +{ + long ret; + enum xrp_init_flags init_flags = 0; + + ret = init_hw_irq(pdev, hw, 0, &init_flags); + if (ret < 0) + return ret; + ret =init_hw_device(pdev, hw, 1); + if (ret < 0) + return ret; + return xrp_init_v1(pdev, init_flags, &hw_ops, hw,2); +} + +static long init_cma(struct platform_device *pdev, struct xrp_hw_simple *hw) +{ + long ret; + enum xrp_init_flags init_flags = 0; + + ret = init_hw_irq(pdev, hw, 0, &init_flags); + if (ret < 0) + return ret; + ret =init_hw_device(pdev, hw, 1); + if (ret < 0) + return ret; + return xrp_init_cma(pdev, init_flags, &hw_ops, hw,2); +} + +#ifdef CONFIG_OF +static const struct of_device_id xrp_hw_simple_match[] = { + { + .compatible = "cdns,xrp-hw-simple", + .data = init, + }, { + .compatible = "cdns,xrp-hw-simple,v1", + .data = init_v1, + }, { + .compatible = "cdns,xrp-hw-simple,cma", + .data = init_cma, + }, {}, +}; +// MODULE_DEVICE_TABLE(of, xrp_hw_simple_match); +#endif + +static int xrp_hw_simple_probe(struct platform_device *pdev) +{ + struct xrp_hw_simple *hw = + devm_kzalloc(&pdev->dev, sizeof(*hw), GFP_KERNEL); + const struct of_device_id *match; + long (*init)(struct platform_device *pdev, struct xrp_hw_simple *hw); + long ret; + + if (!hw) + return -ENOMEM; + + match = of_match_device(of_match_ptr(xrp_hw_simple_match), + &pdev->dev); + if (!match) + return -ENODEV; + + init = match->data; + ret = init(pdev, hw); + if (IS_ERR_VALUE(ret)) { + //xrp_deinit(pdev); + pr_debug("init fail\n"); + return ret; + } else { + hw->xrp = ERR_PTR(ret); + return 0; + } + +} + + +static int xrp_hw_simple_remove(struct platform_device *pdev) +{ + // xrp_hw_remove_log_proc(); + return xrp_deinit(pdev); +} + +static const struct dev_pm_ops xrp_hw_simple_pm_ops = { + SET_RUNTIME_PM_OPS(xrp_runtime_suspend, + xrp_runtime_resume, NULL) +}; + +static struct platform_driver xrp_hw_simple_driver = { + .probe = xrp_hw_simple_probe, + .remove = xrp_hw_simple_remove, + .driver = { + .name = DRIVER_NAME, + .of_match_table = of_match_ptr(xrp_hw_simple_match), + .pm = &xrp_hw_simple_pm_ops, + }, +}; + +module_platform_driver(xrp_hw_simple_driver); + +MODULE_AUTHOR("Max Filippov"); +MODULE_DESCRIPTION("XRP: low level device driver for Xtensa Remote Processing"); +MODULE_LICENSE("Dual MIT/GPL"); diff --git a/driver/xrp-kernel/xrp_hw_simple_dsp_interface.h b/driver/xrp-kernel/xrp_hw_simple_dsp_interface.h new file mode 100644 index 0000000..dc902bb --- /dev/null +++ b/driver/xrp-kernel/xrp_hw_simple_dsp_interface.h @@ -0,0 +1,66 @@ +/* + * @Author: your name + * @Date: 2022-03-25 12:36:07 + * @LastEditTime: 2022-03-25 12:36:08 + * @LastEditors: your name + * @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE + * @FilePath: /workspace/thead-build/light-fm/tmp-glibc/work/riscv64-oe-linux/xtensa-dsp/1.0-r0/git/driver/xrp-kernel/xrp_hw_simple_dsp_interface.h + */ +/* + * XRP interface between hardware-specific linux and DSP parts of example + * hardware + * + * Copyright (c) 2017 Cadence Design Systems, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Alternatively you can use and distribute this file under the terms of + * the GNU General Public License version 2 or later. + */ + +#ifndef _XRP_KERNEL_SIMPLE_HW_DSP_INTERFACE +#define _XRP_KERNEL_SIMPLE_HW_DSP_INTERFACE + +#include "xrp_ring_buffer.h" +enum { + XRP_DSP_SYNC_IRQ_MODE_NONE = 0x0, + XRP_DSP_SYNC_IRQ_MODE_LEVEL = 0x1, + XRP_DSP_SYNC_IRQ_MODE_EDGE = 0x2, +}; + +struct xrp_hw_simple_sync_data { + __u32 device_mmio_base; + __u32 host_irq_mode; + __u32 host_irq_offset; + __u32 host_irq_bit; + __u32 device_irq_mode; + __u32 device_irq_offset; + __u32 device_irq_bit; + __u32 device_irq; +}; + + +struct xrp_hw_panic { + __u32 panic; + __u32 ccount; + __u32 reserved[2]; + struct xrp_ring_buffer rb; +}; +#endif diff --git a/driver/xrp-kernel/xrp_internal.h b/driver/xrp-kernel/xrp_internal.h new file mode 100644 index 0000000..26cbd87 --- /dev/null +++ b/driver/xrp-kernel/xrp_internal.h @@ -0,0 +1,92 @@ +/* + * Internal XRP structures definition. + * + * Copyright (c) 2015 - 2017 Cadence Design Systems, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Alternatively you can use and distribute this file under the terms of + * the GNU General Public License version 2 or later. + */ + +#ifndef XRP_INTERNAL_H +#define XRP_INTERNAL_H + +#include +#include +#include +#include +#include +#include "xrp_address_map.h" +#include "xrp_kernel_report.h" +struct device; +struct firmware; +struct xrp_hw_ops; +struct xrp_allocation_pool; +struct xrp_dma_buf_list; +struct xrp_panic_log ; +struct xrp_comm { + struct mutex lock; + void __iomem *comm; + struct completion completion; + u32 priority; +}; + +struct xvp { + struct device *dev; + const char *firmware_name; + const struct firmware *firmware; + struct miscdevice miscdev; + const struct xrp_hw_ops *hw_ops; + void *hw_arg; + unsigned n_queues; + + u32 *queue_priority; + struct xrp_comm *queue; + struct xrp_comm **queue_ordered; + void __iomem *comm; + phys_addr_t pmem; + phys_addr_t comm_phys; + phys_addr_t shared_size; + atomic_t reboot_cycle; + atomic_t reboot_cycle_complete; + + struct xrp_address_map address_map; + + bool host_irq_mode; + + struct xrp_allocation_pool *pool; + bool off; + int nodeid; + + struct xrp_reporter *reporter; + + struct list_head dma_buf_list; + + struct proc_dir_entry *proc_dir; + + void __iomem *panic; + phys_addr_t panic_phy; + phys_addr_t panic_size; + struct xrp_panic_log *panic_log; + // struct xrp_dsp_debug_info debug_info; +}; + +#endif diff --git a/driver/xrp-kernel/xrp_kernel_defs.h b/driver/xrp-kernel/xrp_kernel_defs.h new file mode 100644 index 0000000..1e56b54 --- /dev/null +++ b/driver/xrp-kernel/xrp_kernel_defs.h @@ -0,0 +1,107 @@ +/* + * XRP driver IOCTL codes and data structures + * + * Copyright (c) 2015 - 2017 Cadence Design Systems, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Alternatively you can use and distribute this file under the terms of + * the GNU General Public License version 2 or later. + */ + +#ifndef _XRP_KERNEL_DEFS_H +#define _XRP_KERNEL_DEFS_H + +#define XRP_IOCTL_MAGIC 'r' +#define XRP_IOCTL_ALLOC _IO(XRP_IOCTL_MAGIC, 1) +#define XRP_IOCTL_FREE _IO(XRP_IOCTL_MAGIC, 2) +#define XRP_IOCTL_QUEUE _IO(XRP_IOCTL_MAGIC, 3) +#define XRP_IOCTL_QUEUE_NS _IO(XRP_IOCTL_MAGIC, 4) + +#define XRP_IOCTL_REPORT_CREATE _IO(XRP_IOCTL_MAGIC, 5) + +#define XRP_IOCTL_REPORT_RELEASE _IO(XRP_IOCTL_MAGIC, 6) + +#define XRP_IOCTL_DMABUF_IMPORT _IO(XRP_IOCTL_MAGIC, 7) + +#define XRP_IOCTL_DMABUF_EXPORT _IO(XRP_IOCTL_MAGIC, 8) +#define XRP_IOCTL_DMABUF_RELEASE _IO(XRP_IOCTL_MAGIC, 9) + +#define XRP_IOCTL_DMABUF_SYNC _IO(XRP_IOCTL_MAGIC, 10) +struct xrp_ioctl_alloc { + __u32 size; + __u32 align; + __u64 addr; + __u64 paddr; +}; + +enum { + XRP_FLAG_READ = 0x1, + XRP_FLAG_WRITE = 0x2, + XRP_FLAG_READ_WRITE = 0x3, +}; + +struct xrp_ioctl_buffer { + __u32 flags; + __u32 size; + __u64 addr; +}; + +enum { + XRP_QUEUE_FLAG_NSID = 0x4, + XRP_QUEUE_FLAG_PRIO = 0xff00, + XRP_QUEUE_FLAG_PRIO_SHIFT = 8, + + XRP_QUEUE_VALID_FLAGS = + XRP_QUEUE_FLAG_NSID | + XRP_QUEUE_FLAG_PRIO, +}; + +struct xrp_ioctl_queue { + __u32 flags; + __u32 in_data_size; + __u32 out_data_size; + __u32 buffer_size; + __u64 in_data_addr; + __u64 out_data_addr; + __u64 buffer_addr; + __u64 nsid_addr; +}; + +struct xrp_report_buffer +{ + __u32 report_id; + __u32 data[1]; +}; + + +struct xrp_dma_buf{ + int fd; + __u32 flags; + __u32 size; + __u64 addr; + __u64 paddr; +} ; +// struct xrp_ioctl_report { + +// __u32 size; +// struct xrp_report_buffer *addr; +// }; +#endif diff --git a/driver/xrp-kernel/xrp_kernel_dsp_interface.h b/driver/xrp-kernel/xrp_kernel_dsp_interface.h new file mode 100644 index 0000000..184f07d --- /dev/null +++ b/driver/xrp-kernel/xrp_kernel_dsp_interface.h @@ -0,0 +1,150 @@ +/* + * Data structures and constants for generic XRP interface between + * linux and DSP + * + * Copyright (c) 2015 - 2019 Cadence Design Systems, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Alternatively you can use and distribute this file under the terms of + * the GNU General Public License version 2 or later. + */ + +#ifndef _XRP_KERNEL_DSP_INTERFACE_H +#define _XRP_KERNEL_DSP_INTERFACE_H + +#ifndef XRP_DSP_COMM_BASE_MAGIC +#define XRP_DSP_COMM_BASE_MAGIC 0x20161006 +#endif + +enum { + XRP_DSP_SYNC_IDLE = 0, + XRP_DSP_SYNC_HOST_TO_DSP = 0x1, + XRP_DSP_SYNC_DSP_TO_HOST = 0x3, + XRP_DSP_SYNC_START = 0x101, + XRP_DSP_SYNC_DSP_READY_V1 = 0x203, + XRP_DSP_SYNC_DSP_READY_V2 = 0x303, +}; + +enum { + XRP_DSP_SYNC_TYPE_ACCEPT = 0x80000000, + XRP_DSP_SYNC_TYPE_MASK = 0x00ffffff, + XRP_DSP_SYNC_TYPE_LAST = 0, + XRP_DSP_SYNC_TYPE_HW_SPEC_DATA = 1, + XRP_DSP_SYNC_TYPE_HW_QUEUES = 2, + XRP_DSP_SYNC_TYPE_HW_DEBUG_INFO =3, +}; + +struct xrp_dsp_tlv { + __u32 type; + __u32 length; + __u32 value[0]; +}; + +struct xrp_dsp_sync_v1 { + __u32 sync; + __u32 hw_sync_data[0]; +}; + +struct xrp_dsp_sync_v2 { + __u32 sync; + __u32 reserved[3]; + struct xrp_dsp_tlv hw_sync_data[0]; +}; + +enum log_level{ + FW_DEBUG_LOG_MODE_QUIET, /* disabel FW log printf */ + FW_DEBUG_LOG_MODE_ERR, /* enable FW log printf with error level */ + FW_DEBUG_LOG_MODE_WRN, /* enable FW log printf with warning level */ + FW_DEBUG_LOG_MODE_INF, /* enable FW log printf with info level*/ + FW_DEBUG_LOG_MODE_DBG, /* enable FW log printf with debug level*/ + FW_DEBUG_LOG_MODE_TRACE, /* enable FW log printf with trace level*/ +}; + +struct xrp_dsp_debug_info{ + __u32 panic_addr; + __u32 log_level; + __u32 profile_addr; +}; +enum { + XRP_DSP_BUFFER_FLAG_READ = 0x1, + XRP_DSP_BUFFER_FLAG_WRITE = 0x2, +}; + +struct xrp_dsp_buffer { + /* + * When submitted to DSP: types of access allowed + * When returned to host: actual access performed + */ + __u32 flags; + __u32 size; + __u32 addr; +}; + +enum { + XRP_DSP_CMD_FLAG_REQUEST_VALID = 0x00000001, + XRP_DSP_CMD_FLAG_RESPONSE_VALID = 0x00000002, + XRP_DSP_CMD_FLAG_REQUEST_NSID = 0x00000004, + XRP_DSP_CMD_FLAG_RESPONSE_DELIVERY_FAIL = 0x00000008, +}; + +enum { + XRP_DSP_REPORT_INVALID = 0, + XRP_DSP_REPORT_WORKING = 0x1, + XRP_DSP_REPORT_OVERWIRTE = 0x3, +}; +#define XRP_DSP_REPORT_TO_HOST_FLAG (0x10000000) +#define XRP_DSP_CMD_INLINE_DATA_SIZE 16 +#define XRP_DSP_CMD_INLINE_BUFFER_COUNT 1 +#define XRP_DSP_CMD_NAMESPACE_ID_SIZE 16 +#define XRP_DSP_CMD_STRIDE 128 + +struct xrp_dsp_cmd { + __u32 flags; + __u32 in_data_size; + __u32 out_data_size; + __u32 buffer_size; + union { + __u32 in_data_addr; + __u8 in_data[XRP_DSP_CMD_INLINE_DATA_SIZE]; + }; + union { + __u32 out_data_addr; + __u8 out_data[XRP_DSP_CMD_INLINE_DATA_SIZE]; + }; + union { + __u32 buffer_addr; + struct xrp_dsp_buffer buffer_data[XRP_DSP_CMD_INLINE_BUFFER_COUNT]; + __u8 buffer_alignment[XRP_DSP_CMD_INLINE_DATA_SIZE]; + }; + __u8 nsid[XRP_DSP_CMD_NAMESPACE_ID_SIZE]; +/*************DSP report channel***************************************/ + __u32 report_id; + __u32 report_paylad_size; + __u32 report_buffer_size; + __u32 report_status; + union { + __u32 report_addr; + __u8 report_data[XRP_DSP_CMD_INLINE_DATA_SIZE]; + }; + __u32 cmd_flag; +}; + +#endif diff --git a/driver/xrp-kernel/xrp_kernel_report.h b/driver/xrp-kernel/xrp_kernel_report.h new file mode 100644 index 0000000..675614f --- /dev/null +++ b/driver/xrp-kernel/xrp_kernel_report.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2017 Cadence Design Systems Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Alternatively you can use and distribute this file under the terms of + * the GNU General Public License version 2 or later. + */ + +#ifndef XRP_KERNEL_REPORT_H +#define XRP_KERNEL_REPORT_H + +// #include "xrp_alloc.h" +#include +struct xrp_reporter { + + struct fasync_struct *fasync; + struct tasklet_struct report_task; + __u64 buffer_virt; + + phys_addr_t buffer_phys; + size_t buffer_size; + +}; + +#endif diff --git a/driver/xrp-kernel/xrp_private_alloc.h b/driver/xrp-kernel/xrp_private_alloc.h new file mode 100644 index 0000000..9fbf964 --- /dev/null +++ b/driver/xrp-kernel/xrp_private_alloc.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2017 Cadence Design Systems Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Alternatively you can use and distribute this file under the terms of + * the GNU General Public License version 2 or later. + */ + +#ifndef XRP_PRIVATE_ALLOC_H +#define XRP_PRIVATE_ALLOC_H + +#include "xrp_alloc.h" + +long xrp_init_private_pool(struct xrp_allocation_pool **pool, + phys_addr_t start, u32 size); + +#endif diff --git a/driver/xrp-kernel/xrp_ring_buffer.h b/driver/xrp-kernel/xrp_ring_buffer.h new file mode 100644 index 0000000..00d79b5 --- /dev/null +++ b/driver/xrp-kernel/xrp_ring_buffer.h @@ -0,0 +1,40 @@ +/* + * XRP ring buffer structure + * + * Copyright (c) 2018 Cadence Design Systems, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Alternatively you can use and distribute this file under the terms of + * the GNU General Public License version 2 or later. + */ + +#ifndef XRP_RING_BUFFER_H +#define XRP_RING_BUFFER_H + +struct xrp_ring_buffer { + __u32 read; + __u32 write; + __u32 size; + __u32 reserved[1]; + __u8 data[0]; +}; + +#endif diff --git a/driver/xrp-kernel/xvp_main.c b/driver/xrp-kernel/xvp_main.c new file mode 100644 index 0000000..00b7e77 --- /dev/null +++ b/driver/xrp-kernel/xvp_main.c @@ -0,0 +1,3287 @@ +/* + * XRP: Linux device driver for Xtensa Remote Processing + * + * Copyright (c) 2015 - 2017 Cadence Design Systems, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Alternatively you can use and distribute this file under the terms of + * the GNU General Public License version 2 or later. + */ + +#include +#include +#include +#include +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 16, 0) +#include +#else +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "xrp_cma_alloc.h" +#include "xrp_firmware.h" +#include "xrp_hw.h" +#include "xrp_internal.h" +#include "xrp_kernel_defs.h" +#include "xrp_kernel_dsp_interface.h" +#include "xrp_private_alloc.h" +#include "xrp_debug.h" +#define DRIVER_NAME "xrp" +#define XRP_DEFAULT_TIMEOUT 60 + +#ifndef __io_virt +#define __io_virt(a) ((void __force *)(a)) +#endif + +struct xrp_alien_mapping { + unsigned long vaddr; + unsigned long size; + phys_addr_t paddr; + void *allocation; + enum { + ALIEN_GUP, + ALIEN_PFN_MAP, + ALIEN_COPY, + } type; +}; + +struct xrp_mapping { + enum { + XRP_MAPPING_NONE, + XRP_MAPPING_NATIVE, + XRP_MAPPING_ALIEN, + XRP_MAPPING_KERNEL = 0x4, + } type; + union { + struct { + struct xrp_allocation *xrp_allocation; + unsigned long vaddr; + } native; + struct xrp_alien_mapping alien_mapping; + }; +}; + +struct xvp_file { + struct xvp *xvp; + spinlock_t busy_list_lock; + struct xrp_allocation *busy_list; +}; + +struct xrp_known_file { + void *filp; + struct hlist_node node; +}; + +struct xrp_dma_buf_item{ + + struct list_head link; + struct dma_buf *dmabuf; + struct sg_table *sgt; + struct dma_buf_attachment * attachment; + int ref; +}; +static int firmware_command_timeout = XRP_DEFAULT_TIMEOUT; +module_param(firmware_command_timeout, int, 0644); +MODULE_PARM_DESC(firmware_command_timeout, "Firmware command timeout in seconds."); + +static int firmware_reboot = 1; +module_param(firmware_reboot, int, 0644); +MODULE_PARM_DESC(firmware_reboot, "Reboot firmware on command timeout."); + +enum { + LOOPBACK_NORMAL, /* normal work mode */ + LOOPBACK_NOIO, /* don't communicate with FW, but still load it and control DSP */ + LOOPBACK_NOMMIO, /* don't comminicate with FW or use DSP MMIO, but still load the FW */ + LOOPBACK_NOFIRMWARE, /* communicate with FW or use DSP MMIO, don't load the FW */ + + LOOPBACK_NOFIRMWARE_NOMMIO, /* don't communicate with FW or use DSP MMIO, don't load the FW */ +}; +static int loopback = 0; +module_param(loopback, int, 0644); +MODULE_PARM_DESC(loopback, "Don't use actual DSP, perform everything locally."); + +static int load_mode = 0; +module_param(load_mode, int, 0644); +MODULE_PARM_DESC(load_mode, "firmware load mode. 0: load by driver. 1:load by xplorer to debug."); + +enum { + LOAD_MODE_AUTO, /* load firmware auto by drvier */ + LOAD_MODE_MANUAL, /* load firmware manually for debug*/ +}; + +static int heartbeat_period = 0; +module_param(heartbeat_period, int, 0644); +MODULE_PARM_DESC(heartbeat_period, "Firmware command timeout in seconds."); + +static int dsp_fw_log_mode = 1; +module_param(dsp_fw_log_mode, int, 0644); +MODULE_PARM_DESC(dsp_fw_log_mode, "Firmware LOG MODE.0:disable,1:ERROR(DEFAULT),2:WRNING,3:INFO,4:DEUBG,5:TRACE"); +static DEFINE_HASHTABLE(xrp_known_files, 10); +static DEFINE_SPINLOCK(xrp_known_files_lock); + +static DEFINE_SPINLOCK(xrp_dma_buf_lock); +static DEFINE_IDA(xvp_nodeid); + +static int xrp_boot_firmware(struct xvp *xvp); + +static long xrp_copy_user_from_phys(struct xvp *xvp, + unsigned long vaddr, unsigned long size, + phys_addr_t paddr, unsigned long flags); +static bool xrp_cacheable(struct xvp *xvp, unsigned long pfn, + unsigned long n_pages) +{ + if (xvp->hw_ops->cacheable) { + return xvp->hw_ops->cacheable(xvp->hw_arg, pfn, n_pages); + } else { + unsigned long i; + + for (i = 0; i < n_pages; ++i) + if (!pfn_valid(pfn + i)) + return false; + return true; + } +} + +static int xrp_dma_direction(unsigned flags) +{ + static const enum dma_data_direction xrp_dma_direction[] = { + [0] = DMA_NONE, + [XRP_FLAG_READ] = DMA_TO_DEVICE, + [XRP_FLAG_WRITE] = DMA_FROM_DEVICE, + [XRP_FLAG_READ_WRITE] = DMA_BIDIRECTIONAL, + }; + return xrp_dma_direction[flags & XRP_FLAG_READ_WRITE]; +} + +static void xrp_default_dma_sync_for_device(struct xvp *xvp, + phys_addr_t phys, + unsigned long size, + unsigned long flags) +{ + dma_sync_single_for_device(xvp->dev, phys_to_dma(xvp->dev, phys), size, + xrp_dma_direction(flags)); +} + +static void xrp_dma_sync_for_device(struct xvp *xvp, + unsigned long virt, + phys_addr_t phys, + unsigned long size, + unsigned long flags) +{ + if (xvp->hw_ops->dma_sync_for_device) + xvp->hw_ops->dma_sync_for_device(xvp->hw_arg, + (void *)virt, phys, size, + flags); + else + xrp_default_dma_sync_for_device(xvp, phys, size, flags); +} + +static void xrp_default_dma_sync_for_cpu(struct xvp *xvp, + phys_addr_t phys, + unsigned long size, + unsigned long flags) +{ + dma_sync_single_for_cpu(xvp->dev, phys_to_dma(xvp->dev, phys), size, + xrp_dma_direction(flags)); +} + +static void xrp_dma_sync_for_cpu(struct xvp *xvp, + unsigned long virt, + phys_addr_t phys, + unsigned long size, + unsigned long flags) +{ + if (xvp->hw_ops->dma_sync_for_cpu) + xvp->hw_ops->dma_sync_for_cpu(xvp->hw_arg, + (void *)virt, phys, size, + flags); + else + xrp_default_dma_sync_for_cpu(xvp, phys, size, flags); +} +static inline void xrp_comm_write32(volatile void __iomem *addr, u32 v) +{ + //__raw_writel(v, addr); + writel(v, addr); +} + +static inline u32 xrp_comm_read32(volatile void __iomem *addr) +{ + //return __raw_readl(addr); + return readl(addr); +} + +static inline void __iomem *xrp_comm_put_tlv(void __iomem **addr, + uint32_t type, + uint32_t length) +{ + struct xrp_dsp_tlv __iomem *tlv = *addr; + + xrp_comm_write32(&tlv->type, type); + xrp_comm_write32(&tlv->length, length); + *addr = tlv->value + ((length + 3) / 4); + return tlv->value; +} + +static inline void __iomem *xrp_comm_get_tlv(void __iomem **addr, + uint32_t *type, + uint32_t *length) +{ + struct xrp_dsp_tlv __iomem *tlv = *addr; + + *type = xrp_comm_read32(&tlv->type); + *length = xrp_comm_read32(&tlv->length); + *addr = tlv->value + ((*length + 3) / 4); + return tlv->value; +} + +static inline void xrp_comm_write(volatile void __iomem *addr, const void *p, + size_t sz) +{ + size_t sz32 = sz & ~3; + u32 v; + + while (sz32) { + memcpy(&v, p, sizeof(v)); + __raw_writel(v, addr); + p += 4; + addr += 4; + sz32 -= 4; + } + sz &= 3; + if (sz) { + v = 0; + memcpy(&v, p, sz); + __raw_writel(v, addr); + } +} + +static inline void xrp_comm_read(volatile void __iomem *addr, void *p, + size_t sz) +{ + size_t sz32 = sz & ~3; + u32 v; + + while (sz32) { + v = __raw_readl(addr); + memcpy(p, &v, sizeof(v)); + p += 4; + addr += 4; + sz32 -= 4; + } + sz &= 3; + if (sz) { + v = __raw_readl(addr); + memcpy(p, &v, sz); + } +} + + +static inline void xrp_send_device_irq(struct xvp *xvp) +{ + if (xvp->hw_ops->send_irq) + xvp->hw_ops->send_irq(xvp->hw_arg); +} + +static inline bool xrp_panic_check(struct xvp *xvp) +{ + if (xvp->hw_ops->panic_check) + return xvp->hw_ops->panic_check(xvp->hw_arg); + else + return panic_check(xvp->panic_log); +} + +static void xrp_add_known_file(struct file *filp) +{ + struct xrp_known_file *p = kmalloc(sizeof(*p), GFP_KERNEL); + + if (!p) + return; + + p->filp = filp; + spin_lock(&xrp_known_files_lock); + hash_add(xrp_known_files, &p->node, (unsigned long)filp); + spin_unlock(&xrp_known_files_lock); +} + +static void xrp_remove_known_file(struct file *filp) +{ + struct xrp_known_file *p; + struct xrp_known_file *pf = NULL; + + spin_lock(&xrp_known_files_lock); + hash_for_each_possible(xrp_known_files, p, node, (unsigned long)filp) { + if (p->filp == filp) { + hash_del(&p->node); + pf = p; + break; + } + } + spin_unlock(&xrp_known_files_lock); + if (pf) + kfree(pf); +} + +static bool xrp_is_known_file(struct file *filp) +{ + bool ret = false; + struct xrp_known_file *p; + + spin_lock(&xrp_known_files_lock); + hash_for_each_possible(xrp_known_files, p, node, (unsigned long)filp) { + if (p->filp == filp) { + ret = true; + break; + } + } + spin_unlock(&xrp_known_files_lock); + return ret; +} + +static void xrp_sync_v2(struct xvp *xvp, + void *hw_sync_data, size_t sz) +{ + struct xrp_dsp_sync_v2 __iomem *shared_sync = xvp->comm; + void __iomem *addr = shared_sync->hw_sync_data; + + xrp_comm_write(xrp_comm_put_tlv(&addr, + XRP_DSP_SYNC_TYPE_HW_SPEC_DATA, sz), + hw_sync_data, sz); + if (xvp->n_queues > 1) { + struct xrp_dsp_sync_v2 __iomem *queue_sync; + unsigned i; + + xrp_comm_write(xrp_comm_put_tlv(&addr, + XRP_DSP_SYNC_TYPE_HW_QUEUES, + xvp->n_queues * sizeof(u32)), + xvp->queue_priority, + xvp->n_queues * sizeof(u32)); + for (i = 1; i < xvp->n_queues; ++i) { + queue_sync = xvp->queue[i].comm; + xrp_comm_write32(&queue_sync->sync, + XRP_DSP_SYNC_IDLE); + } + } + struct xrp_dsp_debug_info debug_info ={ + .panic_addr = xvp->panic_phy, + .log_level = dsp_fw_log_mode, + }; + + xrp_comm_write(xrp_comm_put_tlv(&addr, + XRP_DSP_SYNC_TYPE_HW_DEBUG_INFO, sizeof(struct xrp_dsp_debug_info)), + &debug_info, sizeof(struct xrp_dsp_debug_info)); + xrp_comm_put_tlv(&addr, XRP_DSP_SYNC_TYPE_LAST, 0); +} + +static int xrp_sync_complete_v2(struct xvp *xvp, size_t sz) +{ + struct xrp_dsp_sync_v2 __iomem *shared_sync = xvp->comm; + void __iomem *addr = shared_sync->hw_sync_data; + u32 type, len; + + xrp_comm_get_tlv(&addr, &type, &len); + if (len != sz) { + dev_err(xvp->dev, + "HW spec data size modified by the DSP\n"); + return -EINVAL; + } + if (!(type & XRP_DSP_SYNC_TYPE_ACCEPT)) + dev_info(xvp->dev, + "HW spec data not recognized by the DSP\n"); + + if (xvp->n_queues > 1) { + void __iomem *p = xrp_comm_get_tlv(&addr, &type, &len); + + if (len != xvp->n_queues * sizeof(u32)) { + dev_err(xvp->dev, + "Queue priority size modified by the DSP\n"); + return -EINVAL; + } + if (type & XRP_DSP_SYNC_TYPE_ACCEPT) { + xrp_comm_read(p, xvp->queue_priority, + xvp->n_queues * sizeof(u32)); + } else { + dev_info(xvp->dev, + "Queue priority data not recognized by the DSP\n"); + xvp->n_queues = 1; + } + } + return 0; +} + +static int xrp_synchronize(struct xvp *xvp) +{ + size_t sz; + void *hw_sync_data; + unsigned long deadline = jiffies + firmware_command_timeout * HZ; + struct xrp_dsp_sync_v1 __iomem *shared_sync = xvp->comm; + int ret; + u32 v, v1; + + hw_sync_data = xvp->hw_ops->get_hw_sync_data(xvp->hw_arg, &sz); + if (!hw_sync_data) { + ret = -ENOMEM; + goto err; + } + ret = -ENODEV; + dev_dbg(xvp->dev,"%s:comm sync:%p\n",__func__,&shared_sync->sync); + xrp_comm_write32(&shared_sync->sync, XRP_DSP_SYNC_START); + mb(); + do { + v = xrp_comm_read32(&shared_sync->sync); + if (v != XRP_DSP_SYNC_START) + break; + if (xrp_panic_check(xvp)) + goto err; + schedule(); + } while (time_before(jiffies, deadline)); + dev_dbg(xvp->dev,"%s:comm sync data :%x\n",__func__,v); + switch (v) { + case XRP_DSP_SYNC_DSP_READY_V1: + if (xvp->n_queues > 1) { + dev_info(xvp->dev, + "Queue priority data not recognized by the DSP\n"); + xvp->n_queues = 1; + } + xrp_comm_write(&shared_sync->hw_sync_data, hw_sync_data, sz); + break; + case XRP_DSP_SYNC_DSP_READY_V2: + xrp_sync_v2(xvp, hw_sync_data, sz); + break; + case XRP_DSP_SYNC_START: + dev_err(xvp->dev, "DSP is not ready for synchronization\n"); + goto err; + default: + dev_err(xvp->dev, + "DSP response to XRP_DSP_SYNC_START is not recognized\n"); + goto err; + } + + mb(); + xrp_comm_write32(&shared_sync->sync, XRP_DSP_SYNC_HOST_TO_DSP); + + do { + mb(); + v1 = xrp_comm_read32(&shared_sync->sync); + if (v1 == XRP_DSP_SYNC_DSP_TO_HOST) + break; + if (xrp_panic_check(xvp)) + goto err; + schedule(); + } while (time_before(jiffies, deadline)); + + if (v1 != XRP_DSP_SYNC_DSP_TO_HOST) { + dev_err(xvp->dev, + "DSP haven't confirmed initialization data reception\n"); + goto err; + } + + if (v == XRP_DSP_SYNC_DSP_READY_V2) { + ret = xrp_sync_complete_v2(xvp, sz); + if (ret < 0) + goto err; + } + + xrp_send_device_irq(xvp); + + // if (xvp->host_irq_mode) { + // int res = wait_for_completion_timeout(&xvp->queue[0].completion, + // firmware_command_timeout * HZ); + + // ret = -ENODEV; + // if (xrp_panic_check(xvp)) + // goto err; + // if (res == 0) { + // dev_err(xvp->dev, + // "host IRQ mode is requested, but DSP couldn't deliver IRQ during synchronization\n"); + // goto err; + // } + // } + ret = 0; +err: + kfree(hw_sync_data); + xrp_comm_write32(&shared_sync->sync, XRP_DSP_SYNC_IDLE); + return ret; +} + +static bool xrp_cmd_complete(struct xrp_comm *xvp) +{ + struct xrp_dsp_cmd __iomem *cmd = xvp->comm; + u32 flags = xrp_comm_read32(&cmd->flags); + pr_debug(" xrp_cmd_complete %x\n", flags); + rmb(); + return (flags & (XRP_DSP_CMD_FLAG_REQUEST_VALID | + XRP_DSP_CMD_FLAG_RESPONSE_VALID)) == + (XRP_DSP_CMD_FLAG_REQUEST_VALID | + XRP_DSP_CMD_FLAG_RESPONSE_VALID); +} + +static inline int xrp_report_comlete(struct xvp *xvp) +{ + struct xrp_dsp_cmd __iomem *cmd = xvp->comm; + + if(!xvp->reporter) + return -1; + + u32 flags = xrp_comm_read32(&cmd->report_id); + + if(flags& XRP_DSP_REPORT_TO_HOST_FLAG ) + { + // dev_err(xvp->dev, "%s,report_flag %x\n", __func__,flags); + flags &= (~XRP_DSP_REPORT_TO_HOST_FLAG); + + xrp_comm_write32(&cmd->report_id,flags); + tasklet_schedule(&xvp->reporter->report_task); + return 0; + } + return -1; +} + + +static inline int xrp_device_cmd_comlete(struct xvp *xvp) +{ + struct xrp_dsp_cmd __iomem *cmd = xvp->comm; + + u32 flags = xrp_comm_read32(&cmd->cmd_flag); + + if(flags& XRP_DSP_REPORT_TO_HOST_FLAG ) + { + xrp_comm_write32(&cmd->cmd_flag,0); + return 0; + } + return -1; +} + +irqreturn_t xrp_irq_handler(int irq, struct xvp *xvp) +{ + unsigned i, n = 0; + + // dev_dbg(xvp->dev, "%s\n", __func__); + if (!xvp->comm) + return IRQ_NONE; + + if(!xrp_report_comlete(xvp)) + { + dev_dbg(xvp->dev, "completing report\n"); + // return IRQ_HANDLED; + } + if(xrp_device_cmd_comlete(xvp)) + { + dev_dbg(xvp->dev, "no cmd msg report\n"); + return IRQ_HANDLED; + } + for (i = 0; i < xvp->n_queues; ++i) { + if (xrp_cmd_complete(xvp->queue + i)) { + dev_dbg(xvp->dev, "completing queue %d\n", i); + complete(&xvp->queue[i].completion); + ++n; + } + } + + return n ? IRQ_HANDLED : IRQ_NONE; +} +EXPORT_SYMBOL(xrp_irq_handler); + +static inline void xvp_file_lock(struct xvp_file *xvp_file) +{ + spin_lock(&xvp_file->busy_list_lock); +} + +static inline void xvp_file_unlock(struct xvp_file *xvp_file) +{ + spin_unlock(&xvp_file->busy_list_lock); +} + +static void xrp_allocation_queue(struct xvp_file *xvp_file, + struct xrp_allocation *xrp_allocation) +{ + xvp_file_lock(xvp_file); + + xrp_allocation->next = xvp_file->busy_list; + xvp_file->busy_list = xrp_allocation; + + xvp_file_unlock(xvp_file); +} + +static struct xrp_allocation *xrp_allocation_dequeue(struct xvp_file *xvp_file, + phys_addr_t paddr, u32 size) +{ + struct xrp_allocation **pcur; + struct xrp_allocation *cur; + + xvp_file_lock(xvp_file); + + for (pcur = &xvp_file->busy_list; (cur = *pcur); pcur = &((*pcur)->next)) { + pr_debug("%s: %pap / %pap x %d\n", __func__, &paddr, &cur->start, cur->size); + if (paddr >= cur->start && paddr + size - cur->start <= cur->size) { + *pcur = cur->next; + break; + } + } + + xvp_file_unlock(xvp_file); + return cur; +} + +static long xrp_ioctl_alloc(struct file *filp, + struct xrp_ioctl_alloc __user *p) +{ + struct xvp_file *xvp_file = filp->private_data; + struct xrp_allocation *xrp_allocation; + unsigned long vaddr; + struct xrp_ioctl_alloc xrp_ioctl_alloc; + long err; + + // pr_debug("%s: %p\n", __func__, p); + if (copy_from_user(&xrp_ioctl_alloc, p, sizeof(*p))) + return -EFAULT; + + // pr_debug("%s: size = %d, align = %x\n", __func__, + // xrp_ioctl_alloc.size, xrp_ioctl_alloc.align); + + err = xrp_allocate(xvp_file->xvp->pool, + xrp_ioctl_alloc.size, + xrp_ioctl_alloc.align, + &xrp_allocation); + if (err) + return err; + + xrp_allocation_queue(xvp_file, xrp_allocation); + + vaddr = vm_mmap(filp, 0, xrp_allocation->size, + PROT_READ | PROT_WRITE, MAP_SHARED, + xrp_allocation_offset(xrp_allocation)); + + xrp_ioctl_alloc.addr = vaddr; + xrp_ioctl_alloc.paddr = xrp_allocation->start; + pr_debug("%s: vaddr = %llx, paddr = %llx\n", __func__, + xrp_ioctl_alloc.addr, xrp_ioctl_alloc.paddr); + if (copy_to_user(p, &xrp_ioctl_alloc, sizeof(*p))) { + vm_munmap(vaddr, xrp_ioctl_alloc.size); + return -EFAULT; + } + return 0; +} +static void xrp_report_tasklet(unsigned long arg) +{ + struct xvp *xvp=(struct xvp *)arg; + struct xrp_dsp_cmd __iomem *cmd=xvp->comm; + struct xrp_report_buffer *p_buf = xvp->reporter->buffer_virt; + // pr_debug("%s,addr:%lx\n",__func__,arg); + if(!xvp->reporter->fasync) + { + pr_debug("%s:fasync is not register in user space\n",__func__); + return; + } + // pr_debug("%s,%d\n",__func__,xvp->reporter->fasync->magic); + // if(!xvp->reporter->user_buffer_virt && + // !xvp->reporter->buffer_size) + // { + // pr_debug("%s:user_buffer_virt and buffer size is invalid\n",__func__); + // return; + // } + // size_t s= xrp_comm_read32(&cmd->report_paylad_size); + + // unsigned int id = xrp_comm_read32(&cmd->report_id); + // if(copy_to_user(&p_buf_user->report_id,&id,sizeof(p_buf_user->report_id))); + // { + // pr_debug("%s:copy report id to user fail\n",__func__); + // return; + // } + + // if(xvp->reporter->buffer_size>XRP_DSP_CMD_INLINE_DATA_SIZE) + // { + // if(xrp_copy_user_from_phys(xvp,&p_buf_user->data[0],s,xvp->reporter->buffer_phys,XRP_FLAG_READ_WRITE)) + // return; + // } + // else + // { + // char temp_buf[XRP_DSP_CMD_INLINE_DATA_SIZE]; + // xrp_comm_read(&cmd->report_data,temp_buf,s); + // if(copy_to_user(&p_buf_user->data[0],temp_buf,s)) + // { + // pr_debug("%s:copy report data to user fail\n",__func__); + // return; + // } + // } + /*****clear report*********************/ + p_buf->report_id = xrp_comm_read32(&cmd->report_id)&0xffff; + + //xrp_dma_sync_for_cpu(xvp,xvp->reporter->buffer_virt,xvp->reporter->buffer_phys,xvp->reporter->buffer_size,XRP_FLAG_WRITE); + kill_fasync(&(xvp->reporter->fasync), SIGIO, POLL_IN); + xrp_comm_write32(&cmd->report_id,0x0); + // pr_debug("%s,report_id:%d,report_data:%x\n",__func__,p_buf->report_id,p_buf->data[0]); +} +static long xrp_map_phy_to_virt(phys_addr_t paddr,unsigned long size,__u64 *vaddr) +{ + // if (pfn_valid(__phys_to_pfn(paddr))) { + // struct page *page = pfn_to_page(__phys_to_pfn(paddr)); + // size_t page_offs = paddr & ~PAGE_MASK; + // size_t offs; + + // // for (offs = 0; offs < size; ++page) { + // // void *p = kmap(page); + // // size_t sz = PAGE_SIZE - page_offs; + // // size_t copy_sz = sz; + // // unsigned long rc; + // // } + // if(page_offs+size>PAGE_SIZE) + // { + // pr_debug("%s,phys addr map to virt exceed one page",__func__); + // return -EINVAL; + // } + // void *p = kmap(page); + // if(!p) + // { + // pr_debug("%s couldn't kmap %pap x 0x%08x\n",__func__,&paddr, (u32)size); + // return -EINVAL; + // } + // *vaddr =p + page_offs; + // pr_debug("%s map to mem",__func__); + // return 0; + + // } + // else + { + void __iomem *p = ioremap(paddr, size); + unsigned long rc; + + if (!p) { + pr_debug("%s,couldn't ioremap %pap x 0x%08x\n",__func__,&paddr, (u32)size); + return -EINVAL; + } + *vaddr = p; + pr_debug("%s map to io mem",__func__); + return 0; + } + // iounmap(p); + // if (rc) + // return -EFAULT; + + // } +} + +static long xrp_unmap_phy_to_virt(unsigned long *vaddr,phys_addr_t paddr,unsigned long size) +{ + if (pfn_valid(__phys_to_pfn(paddr))) { + struct page *page = pfn_to_page(__phys_to_pfn(paddr)); + kunmap(page); + } + else{ + iounmap(*vaddr); + } + *vaddr=NULL; + return 0; +} +static long xrp_ioctl_alloc_report(struct file *filp, + struct xrp_ioctl_alloc __user *p) +{ + struct xvp_file *xvp_file = filp->private_data; + struct xrp_allocation *xrp_allocation; + struct xvp *xvp = xvp_file->xvp; + struct xrp_ioctl_alloc xrp_ioctl_alloc; + struct xrp_dsp_cmd __iomem *cmd=xvp->comm; + unsigned long vaddr; + long err; + + pr_debug("%s: %p\n", __func__, p); + if (copy_from_user(&xrp_ioctl_alloc, p, sizeof(*p))) + return -EFAULT; + pr_debug("%s: virtAddr = %lx.size = %d, align = %x\n", __func__, + xrp_ioctl_alloc.addr,xrp_ioctl_alloc.size, + xrp_ioctl_alloc.align); + // if(NULL == xrp_ioctl_alloc.addr) + // { + // return -EFAULT; + // } + xvp->reporter= kmalloc(sizeof(*(xvp->reporter)), GFP_KERNEL); + if (!xvp->reporter) + return -EFAULT; + xvp->reporter->fasync=NULL; + err = xrp_allocate(xvp_file->xvp->pool, + xrp_ioctl_alloc.size, + xrp_ioctl_alloc.align, + &xrp_allocation); + + if (err) + return err; + xrp_allocation_queue(xvp_file, xrp_allocation); + + vaddr = vm_mmap(filp, 0, xrp_allocation->size, + PROT_READ | PROT_WRITE, MAP_SHARED, + xrp_allocation_offset(xrp_allocation)); + xrp_ioctl_alloc.addr=vaddr; + xvp->reporter->buffer_phys = xrp_allocation->start; + + if(xrp_map_phy_to_virt(xvp->reporter->buffer_phys,sizeof(__u32),&xvp->reporter->buffer_virt)) + { + pr_debug("%s: map to kernel virt fail\n", __func__); + kfree(xvp->reporter); + return -EFAULT; + } + + xrp_comm_write32(&cmd->report_addr, + xrp_translate_to_dsp(&xvp->address_map,xvp->reporter->buffer_phys+sizeof(__u32))); + unsigned int dsp_addr = xrp_comm_read32(&cmd->report_addr); + pr_debug("%s: alloc_report buffer user virt:%llx,kernel virt:%lx, phys:%llx,dsp_addr:%x,size:%d\n", __func__, + vaddr,xvp->reporter->buffer_virt,xvp->reporter->buffer_phys,dsp_addr,xrp_allocation->size); + /*alloc report memory for DSP , alloc kernel memory for user get*/ + // if(xrp_ioctl_alloc.size>XRP_DSP_CMD_INLINE_DATA_SIZE) + // { + + // err = xrp_allocate(xvp_file->xvp->pool, + // xrp_ioctl_alloc.size, + // xrp_ioctl_alloc.align, + // &xrp_allocation); + // if (err) + // return err; + + // // xrp_allocation_queue(xvp_file, xrp_allocation); + // xvp->reporter->buffer_phys = xrp_allocation->start; + // xrp_comm_write32(&cmd->report_addr, + // xrp_translate_to_dsp(&xvp->address_map,xvp->reporter->buffer_phys)); + // // vaddr = vm_mmap(filp, 0, xrp_allocation->size, + // // PROT_READ | PROT_WRITE, MAP_SHARED, + // // xrp_allocation_offset(xrp_allocation)); + // // xrp_ioctl_alloc.addr=vaddr; + // pr_debug("%s: kernel bufdfer:%lx\n", __func__, xvp->reporter->buffer_phys); + // } + // else{ + // xvp->reporter->buffer_phys = NULL; + // } + /*save the user addr ,which kernel copy the report to */ + // xvp->reporter->user_buffer_virt = xrp_ioctl_alloc.addr; + xvp->reporter->buffer_size = xrp_ioctl_alloc.size; + xrp_comm_write32(&cmd->report_buffer_size,xvp->reporter->buffer_size); + xrp_comm_write32(&cmd->report_status,XRP_DSP_REPORT_WORKING); + xrp_comm_write32(&cmd->report_id,0); + tasklet_init(&xvp->reporter->report_task,xrp_report_tasklet,(unsigned long)xvp); + if (copy_to_user(p, &xrp_ioctl_alloc, sizeof(*p))) { + vm_munmap(vaddr, xrp_ioctl_alloc.size); + kfree(xvp->reporter); + pr_debug("%s: copy to user fail\n", __func__); + return -EFAULT; + } + pr_debug("%s: alloc_report %lx end\n", __func__,xvp); + return 0; +} + +static int xrp_report_fasync(int fd, struct file *filp, int on){ + struct xvp_file *xvp_file = (struct xvp_file *)filp->private_data; + + pr_debug("%s: start,mode: %d\n", __func__,on); + if(xvp_file->xvp->reporter == NULL) + { + pr_debug("%s: reporter is NULL\n", __func__,on); + return 0; + } + if( fasync_helper(fd,filp,on,&(xvp_file->xvp->reporter->fasync)) < 0){ + pr_debug("%s: xrp_report_fasync fail\n", __func__); + return -EIO; + } + pr_debug("%s: end\n", __func__); + return 0; +} + +static int xrp_report_fasync_release(struct file *filp){ + struct xvp_file *xvp_file = (struct xvp_file *)filp->private_data; + if(xvp_file->xvp->reporter) + return xrp_report_fasync(-1,filp,0); + return 0; + +} +static long xrp_ioctl_release_report(struct file *filp, + struct xrp_ioctl_alloc __user *p) +{ + struct xvp_file *xvp_file = filp->private_data; + struct xvp *xvp = xvp_file->xvp; + struct mm_struct *mm = current->mm; + struct xrp_ioctl_alloc xrp_ioctl_alloc; + struct vm_area_struct *vma; + unsigned long start; + struct xrp_dsp_cmd __iomem *cmd=xvp->comm; + + tasklet_kill(&xvp->reporter->report_task); + xrp_comm_write32(&cmd->report_status,XRP_DSP_REPORT_INVALID); + + if (copy_from_user(&xrp_ioctl_alloc, p, sizeof(*p))) + return -EFAULT; + + start = xrp_ioctl_alloc.addr; + pr_debug("%s: virt_addr = 0x%08lx\n", __func__, start); + + #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0) + down_read(&mm->mmap_sem); + #else + down_read(&mm->mmap_lock); + #endif + vma = find_vma(mm, start); + + if (vma && vma->vm_file == filp && + vma->vm_start <= start && start < vma->vm_end) { + size_t size; + + start = vma->vm_start; + size = vma->vm_end - vma->vm_start; + #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0) + up_read(&mm->mmap_sem); + #else + up_read(&mm->mmap_lock); + #endif + pr_debug("%s: 0x%lx x %zu\n", __func__, start, size); + vm_munmap(start, size); + } + else{ + pr_debug("%s: no vma/bad vma for vaddr = 0x%08lx\n", __func__, start); + #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0) + up_read(&mm->mmap_sem); + #else + up_read(&mm->mmap_lock); + #endif + return -EINVAL; + } + + xrp_report_fasync_release(filp); + kfree(xvp->reporter); + xvp->reporter =NULL; + + + return 0; +} +// static struct struct_list timer; + +// static void xrp_device_heartbeat_check(unsigned long arg) +// { +// struct xvp *xvp = struct xvp *(arg); +// if(xvp->reporter != NULL) +// { +// xrp_comm_write32(&cmd->flags, 0); +// } + +// mod_timer(&timer,jiffies + heartbeat_period * HZ); +// } +// static int xrp_device_heartbeat_init(void * arg) +// { +// if(heartbeat_period > 0) +// { +// init_timer(&timer); +// timer.function = xrp_device_heartbeat_check; +// timer.expires = jiffies + heartbeat_period * HZ; +// timer.data = arg; +// add_timer(&timer); +// pr_debug("%s enable heartbeat timer\n", __func__); +// } + +// } +static void xrp_put_pages(phys_addr_t phys, unsigned long n_pages) +{ + struct page *page; + unsigned long i; + + page = pfn_to_page(__phys_to_pfn(phys)); + for (i = 0; i < n_pages; ++i) + put_page(page + i); +} + +static void xrp_alien_mapping_destroy(struct xrp_alien_mapping *alien_mapping) +{ + switch (alien_mapping->type) { + case ALIEN_GUP: + xrp_put_pages(alien_mapping->paddr, + PFN_UP(alien_mapping->vaddr + + alien_mapping->size) - + PFN_DOWN(alien_mapping->vaddr)); + break; + case ALIEN_COPY: + xrp_allocation_put(alien_mapping->allocation); + break; + default: + break; + } +} + +static long xvp_pfn_virt_to_phys(struct xvp_file *xvp_file, + struct vm_area_struct *vma, + unsigned long vaddr, unsigned long size, + phys_addr_t *paddr, + struct xrp_alien_mapping *mapping) +{ + int ret; + unsigned long i; + unsigned long nr_pages = PFN_UP(vaddr + size) - PFN_DOWN(vaddr); + unsigned long pfn; + const struct xrp_address_map_entry *address_map; + + ret = follow_pfn(vma, vaddr, &pfn); + if (ret) + return ret; + + *paddr = __pfn_to_phys(pfn) + (vaddr & ~PAGE_MASK); + address_map = xrp_get_address_mapping(&xvp_file->xvp->address_map, + *paddr); + if (!address_map) { + pr_debug("%s: untranslatable addr: %pap\n", __func__, paddr); + return -EINVAL; + } + + for (i = 1; i < nr_pages; ++i) { + unsigned long next_pfn; + phys_addr_t next_phys; + + ret = follow_pfn(vma, vaddr + (i << PAGE_SHIFT), &next_pfn); + if (ret) + return ret; + if (next_pfn != pfn + 1) { + pr_debug("%s: non-contiguous physical memory\n", + __func__); + return -EINVAL; + } + next_phys = __pfn_to_phys(next_pfn); + if (xrp_compare_address(next_phys, address_map)) { + pr_debug("%s: untranslatable addr: %pap\n", + __func__, &next_phys); + return -EINVAL; + } + pfn = next_pfn; + } + *mapping = (struct xrp_alien_mapping){ + .vaddr = vaddr, + .size = size, + .paddr = *paddr, + .type = ALIEN_PFN_MAP, + }; + pr_debug("%s: success, paddr: %pap\n", __func__, paddr); + return 0; +} + +static long xvp_gup_virt_to_phys(struct xvp_file *xvp_file, + unsigned long vaddr, unsigned long size, + phys_addr_t *paddr, + struct xrp_alien_mapping *mapping) +{ + int ret; + int i; + int nr_pages; + struct page **page; + const struct xrp_address_map_entry *address_map; + + if (PFN_UP(vaddr + size) - PFN_DOWN(vaddr) > INT_MAX) + return -EINVAL; + + nr_pages = PFN_UP(vaddr + size) - PFN_DOWN(vaddr); + page = kmalloc(nr_pages * sizeof(void *), GFP_KERNEL); + if (!page) + return -ENOMEM; + + ret = get_user_pages_fast(vaddr, nr_pages, 1, page); + if (ret < 0) + goto out; + + if (ret < nr_pages) { + pr_debug("%s: asked for %d pages, but got only %d\n", + __func__, nr_pages, ret); + nr_pages = ret; + ret = -EINVAL; + goto out_put; + } + + address_map = xrp_get_address_mapping(&xvp_file->xvp->address_map, + page_to_phys(page[0])); + if (!address_map) { + phys_addr_t addr = page_to_phys(page[0]); + pr_debug("%s: untranslatable addr: %pap\n", + __func__, &addr); + ret = -EINVAL; + goto out_put; + } + + for (i = 1; i < nr_pages; ++i) { + phys_addr_t addr; + + if (page[i] != page[i - 1] + 1) { + pr_debug("%s: non-contiguous physical memory\n", + __func__); + ret = -EINVAL; + goto out_put; + } + addr = page_to_phys(page[i]); + if (xrp_compare_address(addr, address_map)) { + pr_debug("%s: untranslatable addr: %pap\n", + __func__, &addr); + ret = -EINVAL; + goto out_put; + } + } + + *paddr = __pfn_to_phys(page_to_pfn(page[0])) + (vaddr & ~PAGE_MASK); + *mapping = (struct xrp_alien_mapping){ + .vaddr = vaddr, + .size = size, + .paddr = *paddr, + .type = ALIEN_GUP, + }; + ret = 0; + pr_debug("%s: success, paddr: %pap\n", __func__, paddr); + +out_put: + if (ret < 0) + for (i = 0; i < nr_pages; ++i) + put_page(page[i]); +out: + kfree(page); + return ret; +} + +static long _xrp_copy_user_phys(struct xvp *xvp, + unsigned long vaddr, unsigned long size, + phys_addr_t paddr, unsigned long flags, + bool to_phys) +{ + // if (pfn_valid(__phys_to_pfn(paddr))) { + // struct page *page = pfn_to_page(__phys_to_pfn(paddr)); + // size_t page_offs = paddr & ~PAGE_MASK; + // size_t offs; + + // if (!to_phys) + // xrp_default_dma_sync_for_cpu(xvp, paddr, size, flags); + // for (offs = 0; offs < size; ++page) { + // void *p = kmap(page); + // size_t sz = PAGE_SIZE - page_offs; + // size_t copy_sz = sz; + // unsigned long rc; + + // if (!p) + // return -ENOMEM; + + // if (size - offs < copy_sz) + // copy_sz = size - offs; + + // if (to_phys) + // rc = copy_from_user(p + page_offs, + // (void __user *)(vaddr + offs), + // copy_sz); + // else + // rc = copy_to_user((void __user *)(vaddr + offs), + // p + page_offs, copy_sz); + // pr_debug("%s rc:%d,user addr :(%llx,%d) kernel:addr(%llx,%d) size:%d\n", __func__,rc,vaddr,offs,p,page_offs,copy_sz); + // page_offs = 0; + // offs += copy_sz; + + // kunmap(page); + // if (rc) + // return -EFAULT; + // } + // if (to_phys) + // xrp_default_dma_sync_for_device(xvp, paddr, size, flags); + // } else + { + void __iomem *p = ioremap(paddr, size); + unsigned long rc; + pr_debug("%s ioremap:to_phys %d-(%llx,%llx)\n", __func__,to_phys,paddr,p); + if (!p) { + dev_err(xvp->dev, + "couldn't ioremap %pap x 0x%08x\n", + &paddr, (u32)size); + return -EINVAL; + } + if (to_phys) + { + rc = copy_from_user(__io_virt(p), + (void __user *)vaddr, size); + /*fix 5.10 kernel copy from vaddr in kernel to phy*/ + if(rc) + { + xrp_comm_write(p,(void *)vaddr,size); + pr_debug("%s WR replease by copy to phy\n", __func__); + rc =0 ; + } + } + else + rc = copy_to_user((void __user *)vaddr, + __io_virt(p), size); + pr_debug("%s rc:%d,user addr :(%llx) kernel:addr(%llx) size:%d\n", __func__,rc,vaddr,p,size); + iounmap(p); + if (rc) + return -EFAULT; + } + return 0; +} + +static long xrp_copy_user_to_phys(struct xvp *xvp, + unsigned long vaddr, unsigned long size, + phys_addr_t paddr, unsigned long flags) +{ + return _xrp_copy_user_phys(xvp, vaddr, size, paddr, flags, true); +} + +static long xrp_copy_user_from_phys(struct xvp *xvp, + unsigned long vaddr, unsigned long size, + phys_addr_t paddr, unsigned long flags) +{ + return _xrp_copy_user_phys(xvp, vaddr, size, paddr, flags, false); +} + +static long xvp_copy_virt_to_phys(struct xvp_file *xvp_file, + unsigned long flags, + unsigned long vaddr, unsigned long size, + phys_addr_t *paddr, + struct xrp_alien_mapping *mapping) +{ + phys_addr_t phys; + unsigned long align = clamp(vaddr & -vaddr, 16ul, PAGE_SIZE); + unsigned long offset = vaddr & (align - 1); + struct xrp_allocation *allocation; + long rc; + + rc = xrp_allocate(xvp_file->xvp->pool, + size + align, align, &allocation); + if (rc < 0) + return rc; + + phys = (allocation->start & -align) | offset; + if (phys < allocation->start) + phys += align; + + if (flags & XRP_FLAG_READ) { + if (xrp_copy_user_to_phys(xvp_file->xvp, + vaddr, size, phys, flags)) { + xrp_allocation_put(allocation); + return -EFAULT; + } + } + + *paddr = phys; + *mapping = (struct xrp_alien_mapping){ + .vaddr = vaddr, + .size = size, + .paddr = *paddr, + .allocation = allocation, + .type = ALIEN_COPY, + }; + pr_debug("%s: copying to pa: %pap\n", __func__, paddr); + + return 0; +} + +static unsigned xvp_get_region_vma_count(unsigned long virt, + unsigned long size, + struct vm_area_struct *vma) +{ + unsigned i; + struct mm_struct *mm = current->mm; + + if (virt + size < virt) + return 0; + if (vma->vm_start > virt) + return 0; + if (vma->vm_start <= virt && + virt + size <= vma->vm_end) + return 1; + for (i = 2; ; ++i) { + struct vm_area_struct *next_vma = find_vma(mm, vma->vm_end); + + if (!next_vma) + return 0; + if (next_vma->vm_start != vma->vm_end) + return 0; + vma = next_vma; + if (virt + size <= vma->vm_end) + return i; + } + return 0; +} + +static long xrp_share_kernel(struct file *filp, + unsigned long virt, unsigned long size, + unsigned long flags, phys_addr_t *paddr, + struct xrp_mapping *mapping) +{ + struct xvp_file *xvp_file = filp->private_data; + struct xvp *xvp = xvp_file->xvp; + phys_addr_t phys = __pa(virt); + long err = 0; + + pr_debug("%s: sharing kernel-only buffer: %pap\n", __func__, &phys); + if (xrp_translate_to_dsp(&xvp->address_map, phys) == + XRP_NO_TRANSLATION) { + #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0) + mm_segment_t oldfs = get_fs(); + set_fs(KERNEL_DS); + #else + mm_segment_t oldfs =force_uaccess_begin(); + #endif + + pr_debug("%s: untranslatable addr, making shadow copy\n", + __func__); + + err = xvp_copy_virt_to_phys(xvp_file, flags, + virt, size, paddr, + &mapping->alien_mapping); + #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0) + set_fs(oldfs); + #else + force_uaccess_end(oldfs); + #endif + mapping->type = XRP_MAPPING_ALIEN | XRP_MAPPING_KERNEL; + } else { + mapping->type = XRP_MAPPING_KERNEL; + *paddr = phys; + + xrp_default_dma_sync_for_device(xvp, phys, size, flags); + } + pr_debug("%s: mapping = %p, mapping->type = %d\n", + __func__, mapping, mapping->type); + return err; +} + +static bool vma_needs_cache_ops(struct vm_area_struct *vma) +{ + pgprot_t prot = vma->vm_page_prot; + + return pgprot_val(prot) != pgprot_val(pgprot_noncached(prot)) && + pgprot_val(prot) != pgprot_val(pgprot_writecombine(prot)); +} + +/* Share blocks of memory, from host to IVP or back. + * + * When sharing to IVP return physical addresses in paddr. + * Areas allocated from the driver can always be shared in both directions. + * Contiguous 3rd party allocations need to be shared to IVP before they can + * be shared back. + */ + +static long __xrp_share_block(struct file *filp, + unsigned long virt, unsigned long size, + unsigned long flags, phys_addr_t *paddr, + struct xrp_mapping *mapping) +{ + phys_addr_t phys = ~0ul; + struct xvp_file *xvp_file = filp->private_data; + struct xvp *xvp = xvp_file->xvp; + struct mm_struct *mm = current->mm; + struct vm_area_struct *vma = find_vma(mm, virt); + bool do_cache = true; + long rc = -EINVAL; + + if (!vma) { + pr_debug("%s: no vma for vaddr/size = 0x%08lx/0x%08lx\n", + __func__, virt, size); + return -EINVAL; + } + /* + * Region requested for sharing should be within single VMA. + * That's true for the majority of cases, but sometimes (e.g. + * sharing buffer in the beginning of .bss which shares a + * file-mapped page with .data, followed by anonymous page) + * region will cross multiple VMAs. Support it in the simplest + * way possible: start with get_user_pages and use shadow copy + * if that fails. + */ + switch (xvp_get_region_vma_count(virt, size, vma)) { + case 0: + pr_debug("%s: bad vma for vaddr/size = 0x%08lx/0x%08lx\n", + __func__, virt, size); + pr_debug("%s: vma->vm_start = 0x%08lx, vma->vm_end = 0x%08lx\n", + __func__, vma->vm_start, vma->vm_end); + return -EINVAL; + case 1: + break; + default: + pr_debug("%s: multiple vmas cover vaddr/size = 0x%08lx/0x%08lx\n", + __func__, virt, size); + vma = NULL; + break; + } + /* + * And it need to be allocated from the same file descriptor, or + * at least from a file descriptor managed by the XRP. + */ + if (vma && + (vma->vm_file == filp || xrp_is_known_file(vma->vm_file))) { + struct xvp_file *vm_file = vma->vm_file->private_data; + struct xrp_allocation *xrp_allocation = vma->vm_private_data; + + phys = (vma->vm_pgoff << PAGE_SHIFT) + + virt - vma->vm_start; + pr_debug("%s: XRP allocation at 0x%08lx, paddr: %pap\n", + __func__, virt, &phys); + /* + * If it was allocated from a different XRP file it may belong + * to a different device and not be directly accessible. + * Check if it is. + */ + if (vma->vm_file != filp) { + const struct xrp_address_map_entry *address_map = + xrp_get_address_mapping(&xvp->address_map, + phys); + + if (!address_map || + xrp_compare_address(phys + size - 1, address_map)) + pr_debug("%s: untranslatable addr: %pap\n", + __func__, &phys); + else + rc = 0; + + } else { + rc = 0; + } + + if (rc == 0) { + mapping->type = XRP_MAPPING_NATIVE; + mapping->native.xrp_allocation = xrp_allocation; + mapping->native.vaddr = virt; + xrp_allocation_get(xrp_allocation); + do_cache = vma_needs_cache_ops(vma); + } + } + if (rc < 0) { + struct xrp_alien_mapping *alien_mapping = + &mapping->alien_mapping; + unsigned long n_pages = PFN_UP(virt + size) - PFN_DOWN(virt); + + /* Otherwise this is alien allocation. */ + pr_debug("%s: non-XVP allocation at 0x%08lx\n", + __func__, virt); + + /* + * A range can only be mapped directly if it is either + * uncached or HW-specific cache operations can handle it. + */ + if (vma && vma->vm_flags & (VM_IO | VM_PFNMAP)) { + rc = xvp_pfn_virt_to_phys(xvp_file, vma, + virt, size, + &phys, + alien_mapping); + if (rc == 0 && vma_needs_cache_ops(vma) && + !xrp_cacheable(xvp, PFN_DOWN(phys), n_pages)) { + pr_debug("%s: needs unsupported cache mgmt\n", + __func__); + rc = -EINVAL; + } + } else { + #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0) + up_read(&mm->mmap_sem); + #else + up_read(&mm->mmap_lock); + #endif + rc = xvp_gup_virt_to_phys(xvp_file, virt, + size, &phys, + alien_mapping); + if (rc == 0 && + (!vma || vma_needs_cache_ops(vma)) && + !xrp_cacheable(xvp, PFN_DOWN(phys), n_pages)) { + pr_debug("%s: needs unsupported cache mgmt\n", + __func__); + xrp_put_pages(phys, n_pages); + rc = -EINVAL; + } + #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0) + down_read(&mm->mmap_sem); + #else + down_read(&mm->mmap_lock); + #endif + } + if (rc == 0 && vma && !vma_needs_cache_ops(vma)) + do_cache = false; + + /* + * If we couldn't share try to make a shadow copy. + */ + if (rc < 0) { + rc = xvp_copy_virt_to_phys(xvp_file, flags, + virt, size, &phys, + alien_mapping); + do_cache = false; + } + + /* We couldn't share it. Fail the request. */ + if (rc < 0) { + pr_debug("%s: couldn't map virt to phys\n", + __func__); + return -EINVAL; + } + + phys = alien_mapping->paddr + + virt - alien_mapping->vaddr; + + mapping->type = XRP_MAPPING_ALIEN; + } + + *paddr = phys; + pr_debug("%s: mapping = %p, mapping->type = %d,do_cache = %d\n", + __func__, mapping, mapping->type,do_cache); + + if (do_cache) + xrp_dma_sync_for_device(xvp, + virt, phys, size, + flags); + return 0; +} + +static long xrp_writeback_alien_mapping(struct xvp_file *xvp_file, + struct xrp_alien_mapping *alien_mapping, + unsigned long flags) +{ + struct page *page; + size_t nr_pages; + size_t i; + long ret = 0; + + switch (alien_mapping->type) { + case ALIEN_GUP: + xrp_dma_sync_for_cpu(xvp_file->xvp, + alien_mapping->vaddr, + alien_mapping->paddr, + alien_mapping->size, + flags); + pr_debug("%s: dirtying alien GUP @va = %p, pa = %pap\n", + __func__, (void __user *)alien_mapping->vaddr, + &alien_mapping->paddr); + page = pfn_to_page(__phys_to_pfn(alien_mapping->paddr)); + nr_pages = PFN_UP(alien_mapping->vaddr + alien_mapping->size) - + PFN_DOWN(alien_mapping->vaddr); + for (i = 0; i < nr_pages; ++i) + SetPageDirty(page + i); + break; + + case ALIEN_COPY: + pr_debug("%s: synchronizing alien copy @pa = %pap back to %p\n", + __func__, &alien_mapping->paddr, + (void __user *)alien_mapping->vaddr); + if (xrp_copy_user_from_phys(xvp_file->xvp, + alien_mapping->vaddr, + alien_mapping->size, + alien_mapping->paddr, + flags)) + ret = -EINVAL; + break; + + default: + break; + } + return ret; +} + +/* + * + */ +static long __xrp_unshare_block(struct file *filp, struct xrp_mapping *mapping, + unsigned long flags) +{ + long ret = 0; + mm_segment_t oldfs ; + + if (mapping->type & XRP_MAPPING_KERNEL) + #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0) + oldfs = get_fs(); + set_fs(KERNEL_DS); + #else + oldfs =force_uaccess_begin(); + #endif + + switch (mapping->type & ~XRP_MAPPING_KERNEL) { + case XRP_MAPPING_NATIVE: + if (flags & XRP_FLAG_WRITE) { + struct xvp_file *xvp_file = filp->private_data; + + xrp_dma_sync_for_cpu(xvp_file->xvp, + mapping->native.vaddr, + mapping->native.xrp_allocation->start, + mapping->native.xrp_allocation->size, + flags); + + } + xrp_allocation_put(mapping->native.xrp_allocation); + break; + + case XRP_MAPPING_ALIEN: + if (flags & XRP_FLAG_WRITE) + ret = xrp_writeback_alien_mapping(filp->private_data, + &mapping->alien_mapping, + flags); + + xrp_alien_mapping_destroy(&mapping->alien_mapping); + break; + + case XRP_MAPPING_KERNEL: + break; + + default: + break; + } + + if (mapping->type & XRP_MAPPING_KERNEL) + #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0) + set_fs(oldfs); + #else + force_uaccess_end(oldfs); + #endif + + mapping->type = XRP_MAPPING_NONE; + + return ret; +} + +static long xrp_ioctl_free(struct file *filp, + struct xrp_ioctl_alloc __user *p) +{ + struct mm_struct *mm = current->mm; + struct xrp_ioctl_alloc xrp_ioctl_alloc; + struct vm_area_struct *vma; + unsigned long start; + + // pr_debug("%s: %p\n", __func__, p); + if (copy_from_user(&xrp_ioctl_alloc, p, sizeof(*p))) + return -EFAULT; + + start = xrp_ioctl_alloc.addr; + // pr_debug("%s: virt_addr = 0x%08lx\n", __func__, start); + #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0) + down_read(&mm->mmap_sem); + #else + down_read(&mm->mmap_lock); + #endif + vma = find_vma(mm, start); + + if (vma && vma->vm_file == filp && + vma->vm_start <= start && start < vma->vm_end) { + size_t size; + + start = vma->vm_start; + size = vma->vm_end - vma->vm_start; + #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0) + up_read(&mm->mmap_sem); + #else + up_read(&mm->mmap_lock); + #endif + pr_debug("%s: 0x%lx x %zu\n", __func__, start, size); + return vm_munmap(start, size); + } + // pr_debug("%s: no vma/bad vma for vaddr = 0x%08lx\n", __func__, start); + #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0) + up_read(&mm->mmap_sem); + #else + up_read(&mm->mmap_lock); + #endif + + return -EINVAL; +} + +static long xvp_complete_cmd_irq(struct xvp *xvp, struct xrp_comm *comm, + bool (*cmd_complete)(struct xrp_comm *p)) +{ + long timeout = firmware_command_timeout * HZ; + + if (cmd_complete(comm)) + return 0; + if (xrp_panic_check(xvp)) + return -EBUSY; + do { + timeout = wait_for_completion_interruptible_timeout(&comm->completion, + timeout); + if (cmd_complete(comm)) + return 0; + if (xrp_panic_check(xvp)) + return -EBUSY; + } while (timeout > 0); + + if (timeout == 0) + return -EBUSY; + return timeout; +} + +static long xvp_complete_cmd_poll(struct xvp *xvp, struct xrp_comm *comm, + bool (*cmd_complete)(struct xrp_comm *p)) +{ + unsigned long deadline = jiffies + firmware_command_timeout * HZ; + + do { + if (cmd_complete(comm)) + return 0; + if (xrp_panic_check(xvp)) + return -EBUSY; + schedule(); + } while (time_before(jiffies, deadline)); + + return -EBUSY; +} + +struct xrp_request { + struct xrp_ioctl_queue ioctl_queue; + size_t n_buffers; + struct xrp_mapping *buffer_mapping; + struct xrp_dsp_buffer *dsp_buffer; + phys_addr_t in_data_phys; + phys_addr_t out_data_phys; + phys_addr_t dsp_buffer_phys; + union { + struct xrp_mapping in_data_mapping; + u8 in_data[XRP_DSP_CMD_INLINE_DATA_SIZE]; + }; + union { + struct xrp_mapping out_data_mapping; + u8 out_data[XRP_DSP_CMD_INLINE_DATA_SIZE]; + }; + union { + struct xrp_mapping dsp_buffer_mapping; + struct xrp_dsp_buffer buffer_data[XRP_DSP_CMD_INLINE_BUFFER_COUNT]; + }; + u8 nsid[XRP_DSP_CMD_NAMESPACE_ID_SIZE]; +}; + +static void xrp_unmap_request_nowb(struct file *filp, struct xrp_request *rq) +{ + size_t n_buffers = rq->n_buffers; + size_t i; + + if (rq->ioctl_queue.in_data_size > XRP_DSP_CMD_INLINE_DATA_SIZE) + __xrp_unshare_block(filp, &rq->in_data_mapping, 0); + if (rq->ioctl_queue.out_data_size > XRP_DSP_CMD_INLINE_DATA_SIZE) + __xrp_unshare_block(filp, &rq->out_data_mapping, 0); + for (i = 0; i < n_buffers; ++i) + __xrp_unshare_block(filp, rq->buffer_mapping + i, 0); + if (n_buffers > XRP_DSP_CMD_INLINE_BUFFER_COUNT) + __xrp_unshare_block(filp, &rq->dsp_buffer_mapping, 0); + + if (n_buffers) { + kfree(rq->buffer_mapping); + if (n_buffers > XRP_DSP_CMD_INLINE_BUFFER_COUNT) { + kfree(rq->dsp_buffer); + } + } +} + +static long xrp_unmap_request(struct file *filp, struct xrp_request *rq) +{ + size_t n_buffers = rq->n_buffers; + size_t i; + long ret = 0; + long rc; + + if (rq->ioctl_queue.in_data_size > XRP_DSP_CMD_INLINE_DATA_SIZE) + __xrp_unshare_block(filp, &rq->in_data_mapping, XRP_FLAG_READ); + if (rq->ioctl_queue.out_data_size > XRP_DSP_CMD_INLINE_DATA_SIZE) { + rc = __xrp_unshare_block(filp, &rq->out_data_mapping, + XRP_FLAG_WRITE); + + if (rc < 0) { + pr_debug("%s: out_data could not be unshared\n", + __func__); + ret = rc; + } + } else { + pr_debug("%s: out_data <%s> to copied\n", + __func__,rq->out_data); + if (copy_to_user((void __user *)(unsigned long)rq->ioctl_queue.out_data_addr, + rq->out_data, + rq->ioctl_queue.out_data_size)) { + pr_debug("%s: out_data could not be copied\n", + __func__); + ret = -EFAULT; + } + } + + if (n_buffers > XRP_DSP_CMD_INLINE_BUFFER_COUNT) + __xrp_unshare_block(filp, &rq->dsp_buffer_mapping, + XRP_FLAG_READ_WRITE); + + for (i = 0; i < n_buffers; ++i) { + rc = __xrp_unshare_block(filp, rq->buffer_mapping + i, + rq->dsp_buffer[i].flags); + if (rc < 0) { + pr_debug("%s: buffer %zd could not be unshared\n", + __func__, i); + ret = rc; + } + } + + if (n_buffers) { + kfree(rq->buffer_mapping); + if (n_buffers > XRP_DSP_CMD_INLINE_BUFFER_COUNT) { + kfree(rq->dsp_buffer); + } + rq->n_buffers = 0; + } + + return ret; +} + +static long xrp_map_request(struct file *filp, struct xrp_request *rq, + struct mm_struct *mm) +{ + struct xvp_file *xvp_file = filp->private_data; + struct xvp *xvp = xvp_file->xvp; + struct xrp_ioctl_buffer __user *buffer; + size_t n_buffers = rq->ioctl_queue.buffer_size / + sizeof(struct xrp_ioctl_buffer); + + size_t i; + long ret = 0; + + if ((rq->ioctl_queue.flags & XRP_QUEUE_FLAG_NSID) && + copy_from_user(rq->nsid, + (void __user *)(unsigned long)rq->ioctl_queue.nsid_addr, + sizeof(rq->nsid))) { + pr_debug("%s: nsid could not be copied\n ", __func__); + return -EINVAL; + } + rq->n_buffers = n_buffers; + if (n_buffers) { + rq->buffer_mapping = + kzalloc(n_buffers * sizeof(*rq->buffer_mapping), + GFP_KERNEL); + if (n_buffers > XRP_DSP_CMD_INLINE_BUFFER_COUNT) { + rq->dsp_buffer = + kmalloc(n_buffers * sizeof(*rq->dsp_buffer), + GFP_KERNEL); + if (!rq->dsp_buffer) { + kfree(rq->buffer_mapping); + return -ENOMEM; + } + } else { + rq->dsp_buffer = rq->buffer_data; + } + } + #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0) + down_read(&mm->mmap_sem); + #else + down_read(&mm->mmap_lock); + #endif + + if (rq->ioctl_queue.in_data_size > XRP_DSP_CMD_INLINE_DATA_SIZE) { + ret = __xrp_share_block(filp, rq->ioctl_queue.in_data_addr, + rq->ioctl_queue.in_data_size, + XRP_FLAG_READ, &rq->in_data_phys, + &rq->in_data_mapping); + if(ret < 0) { + pr_debug("%s: in_data could not be shared\n", + __func__); + goto share_err; + } + } else { + if (copy_from_user(rq->in_data, + (void __user *)(unsigned long)rq->ioctl_queue.in_data_addr, + rq->ioctl_queue.in_data_size)) { + pr_debug("%s: in_data could not be copied\n", + __func__); + ret = -EFAULT; + goto share_err; + } + } + + if (rq->ioctl_queue.out_data_size > XRP_DSP_CMD_INLINE_DATA_SIZE) { + ret = __xrp_share_block(filp, rq->ioctl_queue.out_data_addr, + rq->ioctl_queue.out_data_size, + XRP_FLAG_WRITE, &rq->out_data_phys, + &rq->out_data_mapping); + if (ret < 0) { + pr_debug("%s: out_data could not be shared\n", + __func__); + goto share_err; + } + } + + buffer = (void __user *)(unsigned long)rq->ioctl_queue.buffer_addr; + + for (i = 0; i < n_buffers; ++i) { + struct xrp_ioctl_buffer ioctl_buffer; + phys_addr_t buffer_phys = ~0ul; + + if (copy_from_user(&ioctl_buffer, buffer + i, + sizeof(ioctl_buffer))) { + ret = -EFAULT; + goto share_err; + } + if (ioctl_buffer.flags & XRP_FLAG_READ_WRITE) { + ret = __xrp_share_block(filp, ioctl_buffer.addr, + ioctl_buffer.size, + ioctl_buffer.flags, + &buffer_phys, + rq->buffer_mapping + i); + if (ret < 0) { + pr_debug("%s: buffer %zd could not be shared\n", + __func__, i); + goto share_err; + } + } + + rq->dsp_buffer[i] = (struct xrp_dsp_buffer){ + .flags = ioctl_buffer.flags, + .size = ioctl_buffer.size, + .addr = xrp_translate_to_dsp(&xvp->address_map, + buffer_phys), + }; + } + + if (n_buffers > XRP_DSP_CMD_INLINE_BUFFER_COUNT) { + ret = xrp_share_kernel(filp, (unsigned long)rq->dsp_buffer, + n_buffers * sizeof(*rq->dsp_buffer), + XRP_FLAG_READ_WRITE, &rq->dsp_buffer_phys, + &rq->dsp_buffer_mapping); + if(ret < 0) { + pr_debug("%s: buffer descriptors could not be shared\n", + __func__); + goto share_err; + } + } +share_err: + #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0) + up_read(&mm->mmap_sem); + #else + up_read(&mm->mmap_lock); + #endif + if (ret < 0) + xrp_unmap_request_nowb(filp, rq); + return ret; +} + +static void xrp_fill_hw_request(struct xrp_dsp_cmd __iomem *cmd, + struct xrp_request *rq, + const struct xrp_address_map *map) +{ + xrp_comm_write32(&cmd->in_data_size, rq->ioctl_queue.in_data_size); + xrp_comm_write32(&cmd->out_data_size, rq->ioctl_queue.out_data_size); + xrp_comm_write32(&cmd->buffer_size, + rq->n_buffers * sizeof(struct xrp_dsp_buffer)); + + if (rq->ioctl_queue.in_data_size > XRP_DSP_CMD_INLINE_DATA_SIZE) + xrp_comm_write32(&cmd->in_data_addr, + xrp_translate_to_dsp(map, rq->in_data_phys)); + else + xrp_comm_write(&cmd->in_data, rq->in_data, + rq->ioctl_queue.in_data_size); + + if (rq->ioctl_queue.out_data_size > XRP_DSP_CMD_INLINE_DATA_SIZE) + xrp_comm_write32(&cmd->out_data_addr, + xrp_translate_to_dsp(map, rq->out_data_phys)); + + if (rq->n_buffers > XRP_DSP_CMD_INLINE_BUFFER_COUNT) + xrp_comm_write32(&cmd->buffer_addr, + xrp_translate_to_dsp(map, rq->dsp_buffer_phys)); + else + xrp_comm_write(&cmd->buffer_data, rq->dsp_buffer, + rq->n_buffers * sizeof(struct xrp_dsp_buffer)); + + if (rq->ioctl_queue.flags & XRP_QUEUE_FLAG_NSID) + xrp_comm_write(&cmd->nsid, rq->nsid, sizeof(rq->nsid)); + +#ifdef DEBUG + { + struct xrp_dsp_cmd dsp_cmd; + xrp_comm_read(cmd, &dsp_cmd, sizeof(dsp_cmd)); + pr_debug("%s: cmd for DSP: %p: %*ph\n", + __func__, cmd, + (int)sizeof(dsp_cmd), &dsp_cmd); + } +#endif + + wmb(); + /* update flags */ + xrp_comm_write32(&cmd->flags, + (rq->ioctl_queue.flags & ~XRP_DSP_CMD_FLAG_RESPONSE_VALID) | + XRP_DSP_CMD_FLAG_REQUEST_VALID); +} + +static long xrp_complete_hw_request(struct xrp_dsp_cmd __iomem *cmd, + struct xrp_request *rq) +{ + u32 flags = xrp_comm_read32(&cmd->flags); + + if (rq->ioctl_queue.out_data_size <= XRP_DSP_CMD_INLINE_DATA_SIZE) + xrp_comm_read(&cmd->out_data, rq->out_data, + rq->ioctl_queue.out_data_size); + if (rq->n_buffers <= XRP_DSP_CMD_INLINE_BUFFER_COUNT) + xrp_comm_read(&cmd->buffer_data, rq->dsp_buffer, + rq->n_buffers * sizeof(struct xrp_dsp_buffer)); + xrp_comm_write32(&cmd->flags, 0); + + return (flags & XRP_DSP_CMD_FLAG_RESPONSE_DELIVERY_FAIL) ? -ENXIO : 0; +} + +static long xrp_ioctl_submit_sync(struct file *filp, + struct xrp_ioctl_queue __user *p) +{ + struct xvp_file *xvp_file = filp->private_data; + struct xvp *xvp = xvp_file->xvp; + struct xrp_comm *queue = xvp->queue; + struct xrp_request xrp_rq, *rq = &xrp_rq; + long ret = 0; + bool went_off = false; + + if (copy_from_user(&rq->ioctl_queue, p, sizeof(*p))) + return -EFAULT; + + if (rq->ioctl_queue.flags & ~XRP_QUEUE_VALID_FLAGS) { + dev_dbg(xvp->dev, "%s: invalid flags 0x%08x\n", + __func__, rq->ioctl_queue.flags); + return -EINVAL; + } + + if (xvp->n_queues > 1) { + unsigned n = (rq->ioctl_queue.flags & XRP_QUEUE_FLAG_PRIO) >> + XRP_QUEUE_FLAG_PRIO_SHIFT; + + if (n >= xvp->n_queues) + n = xvp->n_queues - 1; + queue = xvp->queue_ordered[n]; + dev_dbg(xvp->dev, "%s: priority: %d -> %d\n", + __func__, n, queue->priority); + } + + ret = xrp_map_request(filp, rq, current->mm); + if (ret < 0) + return ret; + + if (loopback < LOOPBACK_NOIO) { + int reboot_cycle; +retry: + mutex_lock(&queue->lock); + reboot_cycle = atomic_read(&xvp->reboot_cycle); + if (reboot_cycle != atomic_read(&xvp->reboot_cycle_complete)) { + mutex_unlock(&queue->lock); + goto retry; + } + + if (xvp->off) { + ret = -ENODEV; + } else { + xrp_fill_hw_request(queue->comm, rq, &xvp->address_map); + + xrp_send_device_irq(xvp); + + if (xvp->host_irq_mode) { + ret = xvp_complete_cmd_irq(xvp, queue, + xrp_cmd_complete); + } else { + ret = xvp_complete_cmd_poll(xvp, queue, + xrp_cmd_complete); + } + + xrp_panic_check(xvp); + + /* copy back inline data */ + if (ret == 0) { + ret = xrp_complete_hw_request(queue->comm, rq); + } else if (ret == -EBUSY && firmware_reboot && + atomic_inc_return(&xvp->reboot_cycle) == + reboot_cycle + 1) { + int rc; + unsigned i; + + dev_dbg(xvp->dev, + "%s: restarting firmware...\n", + __func__); + for (i = 0; i < xvp->n_queues; ++i) + if (xvp->queue + i != queue) + mutex_lock(&xvp->queue[i].lock); + rc = xrp_boot_firmware(xvp); + atomic_set(&xvp->reboot_cycle_complete, + atomic_read(&xvp->reboot_cycle)); + for (i = 0; i < xvp->n_queues; ++i) + if (xvp->queue + i != queue) + mutex_unlock(&xvp->queue[i].lock); + if (rc < 0) { + ret = rc; + went_off = xvp->off; + } + } + } + mutex_unlock(&queue->lock); + } + + if (ret == 0) + ret = xrp_unmap_request(filp, rq); + else if (!went_off) + xrp_unmap_request_nowb(filp, rq); + /* + * Otherwise (if the DSP went off) all mapped buffers are leaked here. + * There seems to be no way to recover them as we don't know what's + * going on with the DSP; the DSP may still be reading and writing + * this memory. + */ + + return ret; +} +// static void xrp_dam_buf_free(struct xrp_allocation *xrp_allocation) +// { +// dev_dbg(xvp->dev,"%s: release dma_buf allocation n", +// __func__); +// kfree(xrp_allocation->pool); +// kfree(xrp_allocation); +// return +// } + +// static void xrp_dam_buf_offset(struct xrp_allocation *xrp_allocation) +// { +// return 0; +// } +// static const struct xrp_allocation_ops xrp_dma_buf_pool_ops = { +// .alloc = NULL, +// .free = xrp_dam_buf_free, +// .free_pool = NULL, +// .offset = xrp_dam_buf_offset, +// }; + +// static inline struct xrp_dma_buf_item * xrp_get_dma_buf_tail(struct xrp_dma_buf_item **list) +// { +// struct xrp_dma_buf_item ** item; + +// if(*list == NULLL) +// return NULL; + +// for(item = list;(*item)->next != NULL;item= &(*item)->next) +// { +// ; +// } +// return *item; +// } + +// static inline void xrp_dam_buf_add_item(struct xrp_dma_buf_item **list,struct xrp_dma_buf_item *entry) +// { +// struct xrp_dma_buf_item * item = xrp_get_dma_buf_tail(list); +// if(item == NULL) +// { +// *list=entry; +// } +// else{ +// item->next = entry; +// } +// } + +// static inline int xrp_get_dma_buf_remove(struct xrp_dma_buf_item **list,struct xrp_dma_buf_item *entry) +// { +// { +// struct xrp_dma_buf_item ** item; + + +// for(item = list;(*item)->next != NULL;item= &(*item)->next) +// { +// struct xrp_dma_buf_item *cur = *item; +// if(); +// } +// } +static void xrp_release_dma_buf_item(struct xrp_dma_buf_item * item) +{ + spin_lock(&xrp_dma_buf_lock); + if(--item->ref==0) + { + list_del(&item->link); + kfree(item); + } + spin_unlock(&xrp_dma_buf_lock); +} +static long xrp_ioctl_dma_buf_import(struct file *filp, + struct xrp_dma_buf __user *p) +{ + long ret; + struct xvp_file *xvp_file = filp->private_data; + struct xvp *xvp = xvp_file->xvp; + struct xrp_dma_buf xrp_dma_buf; + struct dma_buf *dmabuf = NULL; + struct sg_table *sgt = NULL; + struct xrp_dma_buf_item *dma_buf_item=NULL; + struct xrp_dma_buf_item *temp=NULL; + struct dma_buf_attachment *attachment = NULL; + // struct xrp_allocation *xrp_allocation; + // struct xrp_private_pool *pool; + int npages = 0; + int i; + struct scatterlist *s; + unsigned int size = 0; + + dev_dbg(xvp->dev,"%s: entry\n", __func__); + if (copy_from_user(&xrp_dma_buf, p, sizeof(*p))) + { + return -EFAULT; + } + + dmabuf = dma_buf_get(xrp_dma_buf.fd); + + if(!dmabuf) + { + return -EFAULT; + } + + spin_lock(&xrp_dma_buf_lock); + list_for_each_entry(temp,&xvp->dma_buf_list, link) + { + if(temp->dmabuf == dmabuf) + { + dma_buf_item = temp; + dma_buf_item->ref++; + break; + } + } + + spin_unlock(&xrp_dma_buf_lock); + + if(dma_buf_item == NULL) + { + dev_dbg(xvp->dev, + "%s: no exit same dma buf\n", __func__); + attachment = dma_buf_attach(dmabuf, xvp->dev); + if (!attachment) + { + goto One_Err; + } + + sgt = dma_buf_map_attachment(attachment, xrp_dma_direction(xrp_dma_buf.flags)); + if (!sgt) + { + goto One_Err; + } + + dma_buf_item = kzalloc(sizeof(*dma_buf_item),GFP_KERNEL); + if(dma_buf_item == NULL) + { + goto One_Err; + } + + dma_buf_item->attachment = attachment; + dma_buf_item->dmabuf = dmabuf; + dma_buf_item->sgt = sgt; + dma_buf_item->ref = 1; + spin_lock(&xrp_dma_buf_lock); + list_add_tail(&dma_buf_item->link, &xvp->dma_buf_list); + spin_unlock(&xrp_dma_buf_lock); + } + else + { + dev_dbg(xvp->dev, + "%s: exit same dma buf\n", __func__); + attachment = dma_buf_item->attachment; + sgt = dma_buf_item->sgt; + spin_lock(&xrp_dma_buf_lock); + dma_buf_item->ref++; + spin_unlock(&xrp_dma_buf_lock); + } + + if(sgt->nents != 1) + { + dev_dbg(xvp->dev, + "%s: sg table number (%d) is not 1, unspoort.\n", + __func__,sgt->nents); + goto Two_Err; + } + /* Prepare page array. */ + /* Get number of pages. */ + for_each_sg(sgt->sgl, s, sgt->orig_nents, i) + { + npages += (sg_dma_len(s) + PAGE_SIZE - 1) / PAGE_SIZE; + size += sg_dma_len(s); + } + + xrp_dma_buf.size = size; +#ifdef VIDMEM_DMA_MAP + xrp_dma_buf. = sg_dma_address(s) + j * PAGE_SIZE; +#else + // xrp_dma_buf.paddr = page_to_phys(nth_page(sg_page(s), 0)); + xrp_dma_buf.paddr = sg_phys(sgt->sgl); +#endif + // dev_dbg(xvp->dev, + // "%s: import dma-buf phy addr:0x%lx,size:%d\n", + // __func__,xrp_dma_buf.paddr,xrp_dma_buf.size); +// xrp_allocation = kzalloc(sizeof(*xrp_allocation), GFP_KERNEL | __GFP_NORETRY); +// if(!xrp_allocation) +// { +// return -ENOMEM; +// } +// pool = kmalloc(sizeof(*pool), GFP_KERNEL); +// if(!pool) +// { +// kfree(xrp_allocation); +// return -ENOMEM; +// } +// *pool = (struct xrp_private_pool){ +// .pool = { +// .ops = &xrp_dma_buf_pool_ops, +// }, +// .start = xrp_dma_buf.paddr , +// .size = xrp_dma_buf.size, +// .free_list = NULL, +// }; +// xrp_allocation->pool = pool; +// xrp_allocation->start = xrp_dma_buf.paddr; +// xrp_allocation->size = xrp_dma_buf.size; + +// xrp_allocation_queue(xvp_file, xrp_allocation); + +// xrp_dma_buf.addr = vm_mmap(filp, 0, xrp_allocation->size, +// PROT_READ | PROT_WRITE, MAP_SHARED, +// xrp_dam_buf_offset(xrp_allocation)); + + + struct file *export_filp = fget(xrp_dma_buf.fd); + xrp_dma_buf.addr = vm_mmap(export_filp, 0, xrp_dma_buf.size, + PROT_READ | PROT_WRITE, MAP_SHARED,0); + + fput(export_filp); + dev_dbg(xvp->dev, + "%s: import dma-buf phy addr:0x%lx,user addr:0x%lx,size:%d\n", + __func__,xrp_dma_buf.paddr,xrp_dma_buf.addr,xrp_dma_buf.size); + + + if (copy_to_user(p, &xrp_dma_buf, sizeof(*p))) { + dma_buf_put(dmabuf); + vm_munmap(xrp_dma_buf.addr , xrp_dma_buf.size); + goto Two_Err; + } + + return 0; + +Two_Err: + xrp_release_dma_buf_item(dma_buf_item); +One_Err: + dma_buf_put(dmabuf); + return -EINVAL; +} + +static struct xrp_dma_buf_item * xrp_search_dma_buf( struct list_head *list,int fd) +{ + struct xrp_dma_buf_item *loop; + struct xrp_dma_buf_item *dma_buf_item=NULL; + struct dma_buf *dmabuf = NULL; + // pr_debug("%s: fd %d,entry\n", __func__,fd); + dmabuf = dma_buf_get(fd); + spin_lock(&xrp_dma_buf_lock); + list_for_each_entry(loop,list, link) + { + if(loop->dmabuf == dmabuf) + { + dma_buf_item = loop; + break; + } + + } + spin_unlock(&xrp_dma_buf_lock); + dma_buf_put(dmabuf); + pr_debug("%s: %p exit\n", __func__,fd,dma_buf_item); + return dma_buf_item; +} + +static long xrp_ioctl_dma_buf_release(struct file *filp, + int __user *p) +{ + int fd; + struct xvp_file *xvp_file = filp->private_data; + struct xvp *xvp = xvp_file->xvp; + struct dma_buf *dmabuf = NULL; + struct xrp_dma_buf_item *dma_buf_item=NULL; + struct xrp_dma_buf_item *loop,*temp; + + if (copy_from_user(&fd, p, sizeof(*p))) + { + return -EFAULT; + } + + // dmabuf = dma_buf_get(fd); + // spin_lock(&xrp_dma_buf_lock); + // list_for_each_entry_safe(loop, temp, &xvp->dma_buf_list, link) + // { + // if(loop->dmabuf == dmabuf) + // { + // dma_buf_item = loop; + // if((--dma_buf_item->ref)==0) + // list_del(&dma_buf_item); + // break; + // } + + // } + // spin_unlock(&xrp_dma_buf_lock); + // dma_buf_put(dmabuf); + dma_buf_item = xrp_search_dma_buf(&xvp->dma_buf_list,fd); + if(dma_buf_item == NULL) + { + return -EFAULT; + } + + dma_buf_unmap_attachment(dma_buf_item->attachment, dma_buf_item->sgt, DMA_BIDIRECTIONAL); + dma_buf_detach(dma_buf_item->dmabuf, dma_buf_item->attachment); + dma_buf_put(dma_buf_item->dmabuf); + xrp_release_dma_buf_item(dma_buf_item); + return 0; +} + + +static long xrp_ioctl_dma_buf_sync(struct file *filp, + struct xrp_dma_buf __user *p) +{ + struct xvp_file *xvp_file = filp->private_data; + struct xvp *xvp = xvp_file->xvp; + struct xrp_dma_buf xrp_dma_buf; + struct xrp_dma_buf_item *dma_buf_item=NULL; + if (copy_from_user(&xrp_dma_buf, p, sizeof(*p))) + { + return -EFAULT; + } + + dma_buf_item = xrp_search_dma_buf(&xvp->dma_buf_list,xrp_dma_buf.fd); + if(dma_buf_item == NULL) + { + return -EFAULT; + } + switch(xrp_dma_buf.flags) + { + case XRP_FLAG_READ: + dma_sync_single_for_cpu(xvp->dev, phys_to_dma(xvp->dev, xrp_dma_buf.paddr), xrp_dma_buf.size, + xrp_dma_direction(xrp_dma_buf.flags)); + break; + case XRP_FLAG_WRITE: + dma_sync_single_for_device(xvp->dev, phys_to_dma(xvp->dev, xrp_dma_buf.paddr), xrp_dma_buf.size, + xrp_dma_direction(xrp_dma_buf.flags)); + break; + case XRP_FLAG_READ_WRITE: + dma_sync_single_for_cpu(xvp->dev, phys_to_dma(xvp->dev, xrp_dma_buf.paddr), xrp_dma_buf.size, + xrp_dma_direction(xrp_dma_buf.flags)); + dma_sync_single_for_device(xvp->dev, phys_to_dma(xvp->dev, xrp_dma_buf.paddr),xrp_dma_buf.size, + xrp_dma_direction(xrp_dma_buf.flags)); + break; + default: + dev_dbg(xvp->dev,"%s: invalid type%x\n", __func__, xrp_dma_buf.flags); + return -EFAULT; + } + return 0; +} +static long xvp_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + long retval; + + pr_debug("%s: %x\n", __func__, cmd); + + switch(cmd){ + case XRP_IOCTL_ALLOC: + retval = xrp_ioctl_alloc(filp, + (struct xrp_ioctl_alloc __user *)arg); + break; + + case XRP_IOCTL_FREE: + retval = xrp_ioctl_free(filp, + (struct xrp_ioctl_alloc __user *)arg); + break; + + case XRP_IOCTL_QUEUE: + case XRP_IOCTL_QUEUE_NS: + retval = xrp_ioctl_submit_sync(filp, + (struct xrp_ioctl_queue __user *)arg); + break; + case XRP_IOCTL_REPORT_CREATE: + retval = xrp_ioctl_alloc_report(filp, + (struct xrp_ioctl_alloc __user *)arg); + break; + case XRP_IOCTL_REPORT_RELEASE: + retval = xrp_ioctl_release_report(filp, + (struct xrp_ioctl_alloc __user *)arg); + break; + case XRP_IOCTL_DMABUF_IMPORT: + retval = xrp_ioctl_dma_buf_import(filp, + (struct xrp_dma_buf __user *)arg); + break; + case XRP_IOCTL_DMABUF_RELEASE: + retval = xrp_ioctl_dma_buf_release(filp, + (int __user *)arg); + break; + case XRP_IOCTL_DMABUF_SYNC: + retval = xrp_ioctl_dma_buf_sync(filp, + (struct xrp_dma_buf __user *)arg); + break; + default: + retval = -EINVAL; + break; + } + return retval; +} + +static void xvp_vm_open(struct vm_area_struct *vma) +{ + // pr_debug("%s\n", __func__); + xrp_allocation_get(vma->vm_private_data); +} + +static void xvp_vm_close(struct vm_area_struct *vma) +{ + // pr_debug("%s\n", __func__); + xrp_allocation_put(vma->vm_private_data); +} + +static const struct vm_operations_struct xvp_vm_ops = { + .open = xvp_vm_open, + .close = xvp_vm_close, +}; + +static int xvp_mmap(struct file *filp, struct vm_area_struct *vma) +{ + int err; + struct xvp_file *xvp_file = filp->private_data; + unsigned long pfn = vma->vm_pgoff;// + PFN_DOWN(xvp_file->xvp->pmem); + struct xrp_allocation *xrp_allocation; + + xrp_allocation = xrp_allocation_dequeue(filp->private_data, + pfn << PAGE_SHIFT, + vma->vm_end - vma->vm_start); + if (xrp_allocation) { + struct xvp *xvp = xvp_file->xvp; + pgprot_t prot = vma->vm_page_prot; + + if (!xrp_cacheable(xvp, pfn, + PFN_DOWN(vma->vm_end - vma->vm_start))) { + prot = pgprot_writecombine(prot); + // prot = pgprot_noncached(prot); + vma->vm_page_prot = prot; + dev_dbg(xvp->dev,"%s cache atribution set \n", __func__); + } + + err = remap_pfn_range(vma, vma->vm_start, pfn, + vma->vm_end - vma->vm_start, + prot); + + vma->vm_private_data = xrp_allocation; + vma->vm_ops = &xvp_vm_ops; + } else { + pr_err("%s no valid xrp allocate for %lx:\n", __func__,pfn); + err = -EINVAL; + } + + return err; +} + +static int xvp_open(struct inode *inode, struct file *filp) +{ + struct xvp *xvp = container_of(filp->private_data, + struct xvp, miscdev); + struct xvp_file *xvp_file; + int rc; + + dev_dbg(xvp->dev,"%s\n", __func__); + rc = pm_runtime_get_sync(xvp->dev); + if (rc < 0) + { + dev_err(xvp->dev,"%s:pm_runtime_get_sync fail:%d\n", __func__,rc); + return rc; + } + + + xvp_file = devm_kzalloc(xvp->dev, sizeof(*xvp_file), GFP_KERNEL); + if (!xvp_file) { + dev_err(xvp->dev,"%s:malloc fail\n", __func__); + pm_runtime_put_sync(xvp->dev); + return -ENOMEM; + } + + xvp_file->xvp = xvp; + spin_lock_init(&xvp_file->busy_list_lock); + filp->private_data = xvp_file; + xrp_add_known_file(filp); + return 0; +} + +static int xvp_close(struct inode *inode, struct file *filp) +{ + struct xvp_file *xvp_file = filp->private_data; + + pr_debug("%s\n", __func__); + xrp_report_fasync_release(filp); + xrp_remove_known_file(filp); + pm_runtime_put_sync(xvp_file->xvp->dev); + devm_kfree(xvp_file->xvp->dev, xvp_file); + return 0; +} + +static inline int xvp_enable_dsp(struct xvp *xvp) +{ + if (loopback < LOOPBACK_NOMMIO && + xvp->hw_ops->enable) + return xvp->hw_ops->enable(xvp->hw_arg); + else + return 0; +} + +static inline void xvp_disable_dsp(struct xvp *xvp) +{ + if (loopback < LOOPBACK_NOMMIO && + xvp->hw_ops->disable) + xvp->hw_ops->disable(xvp->hw_arg); +} + +static inline void xvp_remove_proc(struct xvp *xvp) +{ + if( xvp->proc_dir) + { + if(xvp->panic_log) + { + xrp_remove_panic_log_proc(xvp->panic_log); + xvp->panic_log =NULL; + } + // remove_proc_entry(xvp->proc_dir,NULL); + proc_remove(xvp->proc_dir); + } +} + +static inline void xrp_set_resetVec(struct xvp *xvp,u32 addr) +{ + if (loopback < LOOPBACK_NOMMIO && + xvp->hw_ops->set_reset_vector) + xvp->hw_ops->set_reset_vector(xvp->hw_arg,addr); +} +static inline void xrp_reset_dsp(struct xvp *xvp) +{ + if (loopback < LOOPBACK_NOMMIO && + xvp->hw_ops->reset) + xvp->hw_ops->reset(xvp->hw_arg); +} + +static inline void xrp_halt_dsp(struct xvp *xvp) +{ + if (loopback < LOOPBACK_NOMMIO && + xvp->hw_ops->halt) + xvp->hw_ops->halt(xvp->hw_arg); +} + +static inline void xrp_release_dsp(struct xvp *xvp) +{ + if (loopback < LOOPBACK_NOMMIO && + xvp->hw_ops->release) + xvp->hw_ops->release(xvp->hw_arg); +} + +static int xrp_boot_firmware(struct xvp *xvp) +{ + int ret; + u32 fm_entry_point=0; + struct xrp_dsp_sync_v1 __iomem *shared_sync = xvp->comm; + // dev_dbg(xvp->dev,"%s",__func__); +//#if 1 //LOAD_MODE_MANUAL load release dsp by xplorer + if(load_mode == LOAD_MODE_AUTO) + { + xrp_halt_dsp(xvp); + //xrp_reset_dsp(xvp); + + if (xvp->firmware_name) { + if (loopback < LOOPBACK_NOFIRMWARE) { + ret = xrp_request_firmware(xvp,&fm_entry_point); + if (ret < 0) + return ret; + } + + if (loopback < LOOPBACK_NOIO) { + xrp_comm_write32(&shared_sync->sync, XRP_DSP_SYNC_IDLE); + mb(); + } + // fm_entry_point = xrp_get_firmware_entry_addr(xvp); + dev_dbg(xvp->dev,"%s,firmware entry point :%x\n",__func__,fm_entry_point); + if(fm_entry_point) + { + xrp_set_resetVec(xvp,fm_entry_point); + } + } + xrp_reset_dsp(xvp); + } + + xrp_release_dsp(xvp); +//#endif + if (loopback < LOOPBACK_NOIO) { + ret = xrp_synchronize(xvp); + if (ret < 0) { + xrp_halt_dsp(xvp); + dev_err(xvp->dev, + "%s: couldn't synchronize with the DSP core\n", + __func__); + dev_err(xvp->dev, + "XRP device will not use the DSP until the driver is rebound to this device\n"); + xvp->off = true; + return ret; + } + } + return 0; +} + +static const struct file_operations xvp_fops = { + .owner = THIS_MODULE, + .llseek = no_llseek, + .unlocked_ioctl = xvp_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = xvp_ioctl, +#endif + .mmap = xvp_mmap, + .open = xvp_open, + .fasync = xrp_report_fasync, + .release = xvp_close, +}; + +int xrp_runtime_suspend(struct device *dev) +{ + struct xvp *xvp = dev_get_drvdata(dev); + + xrp_halt_dsp(xvp); + xrp_reset_dsp(xvp); + xvp_disable_dsp(xvp); + // release_firmware(xvp->firmware); + return 0; +} +EXPORT_SYMBOL(xrp_runtime_suspend); + +int xrp_runtime_resume(struct device *dev) +{ + struct xvp *xvp = dev_get_drvdata(dev); + unsigned i; + int ret = 0; + + for (i = 0; i < xvp->n_queues; ++i) + mutex_lock(&xvp->queue[i].lock); + + if (xvp->off) + goto out; + ret = xvp_enable_dsp(xvp); + if (ret < 0) { + dev_err(xvp->dev, "couldn't enable DSP\n"); + goto out; + } + + ret = xrp_boot_firmware(xvp); + if (ret < 0) + xvp_disable_dsp(xvp); + +out: + for (i = 0; i < xvp->n_queues; ++i) + mutex_unlock(&xvp->queue[i].lock); + + return ret; +} +EXPORT_SYMBOL(xrp_runtime_resume); + +static int xrp_init_regs_v0(struct platform_device *pdev, struct xvp *xvp,int mem_idx) +{ + struct resource res; + struct device_node *np; + int ret = 0; + np = of_parse_phandle(pdev->dev.of_node, "memory-region", 0); + if (!np) { + dev_err(&pdev->dev, "No memory-region specified\n"); + return -EINVAL; + } + ret = of_address_to_resource(np, 0, &res); + dev_dbg(xvp->dev,"%s:dsp runing addr 0x%llx,size:0x%x\n", __func__, + res.start,resource_size(&res)); + + + ret = of_address_to_resource(np, 1, &res); + if (ret) + { + dev_dbg(xvp->dev,"%s:get comm region fail\n", __func__); + return -ENODEV; + } + + xvp->comm_phys = res.start; + xvp->comm = devm_ioremap_resource(&pdev->dev, &res); + dev_dbg(xvp->dev,"%s:xvp->comm =0x%p, phy_addr base=0x%llx\n", __func__, + xvp->comm, xvp->comm_phys); + // mem = platform_get_resource(pdev, IORESOURCE_MEM, mem_idx); + + ret = of_address_to_resource(np, 2, &res); + if(ret) + { + dev_dbg(xvp->dev,"%s:get paic region fail:%d\n", __func__,ret); + }else + { + xvp->panic_phy = res.start; + xvp->panic = devm_ioremap_resource(&pdev->dev, &res); + xvp->panic_size = resource_size(&res); + if(xvp->panic) + { + dev_dbg(xvp->dev,"%s:panic=0x%p, panic phy base=0x%llx,size:%d\n", __func__, + xvp->panic, xvp->panic_phy,xvp->panic_size); + }else + { + dev_warn(xvp->dev,"%s:get paic region fail\n", __func__); + } + } + + ret = of_address_to_resource(np, 3, &res); + if (ret) + { + dev_dbg(xvp->dev,"%s:get memory pool region fail\n", __func__); + return -ENODEV; + } + xvp->pmem = res.start; + xvp->shared_size = resource_size(&res); + dev_dbg(xvp->dev,"%s,memory pool phy_addr base=0x%llx,size:0x%x\n", __func__, + xvp->pmem, xvp->shared_size); + return xrp_init_private_pool(&xvp->pool, xvp->pmem, + xvp->shared_size); +} + +static int xrp_init_regs_v1(struct platform_device *pdev, struct xvp *xvp,int mem_idx) +{ + struct resource *mem; + struct resource r; + + mem = platform_get_resource(pdev, IORESOURCE_MEM, mem_idx); + if (!mem) + return -ENODEV; + + if (resource_size(mem) < 2 * PAGE_SIZE) { + dev_err(xvp->dev, + "%s: shared memory size is too small\n", + __func__); + return -ENOMEM; + } + + xvp->comm_phys = mem->start; + xvp->pmem = mem->start + PAGE_SIZE; + xvp->shared_size = resource_size(mem) - PAGE_SIZE; + + r = *mem; + r.end = r.start + PAGE_SIZE; + xvp->comm = devm_ioremap_resource(&pdev->dev, &r); + return xrp_init_private_pool(&xvp->pool, xvp->pmem, + xvp->shared_size); +} + +static bool xrp_translate_base_mimo_to_dsp(struct xvp *xvp) +{ + + if(!xvp->hw_ops->get_base_mimo || !xvp->hw_ops->get_hw_sync_data ) + { + return true; + } + + + phys_addr_t mimo_addr = xvp->hw_ops->get_base_mimo(xvp->hw_arg); + + u32 device_mimo_addr = xrp_translate_to_dsp(&xvp->address_map, mimo_addr); + if(device_mimo_addr==XRP_NO_TRANSLATION) + { + dev_err(xvp->dev, + "%s: 0x%x translate to dsp address fail\n", + __func__,mimo_addr); + return false; + } + xvp->hw_ops->update_device_base(xvp->hw_arg,device_mimo_addr); + dev_dbg(xvp->dev, + "%s: Base mimo translate to dsp address \n",__func__); + return true; + +} + +static int xrp_init_regs_cma(struct platform_device *pdev, struct xvp *xvp,int mem_idx) +{ + dma_addr_t comm_phys; + + if (of_reserved_mem_device_init(xvp->dev) < 0) + return -ENODEV; + + xvp->comm = dma_alloc_attrs(xvp->dev, PAGE_SIZE, &comm_phys, + GFP_KERNEL, 0); + if (!xvp->comm) + return -ENOMEM; + + xvp->comm_phys = dma_to_phys(xvp->dev, comm_phys); + return xrp_init_cma_pool(&xvp->pool, xvp->dev); +} + +static int compare_queue_priority(const void *a, const void *b) +{ + const void * const *ppa = a; + const void * const *ppb = b; + const struct xrp_comm *pa = *ppa, *pb = *ppb; + + if (pa->priority == pb->priority) + return 0; + else + return pa->priority < pb->priority ? -1 : 1; +} + +static long xrp_init_common(struct platform_device *pdev, + enum xrp_init_flags init_flags, + const struct xrp_hw_ops *hw_ops, void *hw_arg, + int mem_idx, + int (*xrp_init_regs)(struct platform_device *pdev, + struct xvp *xvp,int mem_idx)) +{ + long ret; + char nodename[sizeof("xvp") + 3 * sizeof(int)]; + struct xvp *xvp; + int nodeid; + unsigned i; + u32 value; + char dir_name[32]; + xvp = devm_kzalloc(&pdev->dev, sizeof(*xvp), GFP_KERNEL); + if (!xvp) { + ret = -ENOMEM; + goto err; + } + xvp->reporter = NULL; + xvp->dev = &pdev->dev; + xvp->hw_ops = hw_ops; + xvp->hw_arg = hw_arg; + if (init_flags & XRP_INIT_USE_HOST_IRQ) + xvp->host_irq_mode = true; + platform_set_drvdata(pdev, xvp); + + ret = xrp_init_regs(pdev, xvp,mem_idx); + if (ret < 0) + goto err; + + dev_dbg(xvp->dev,"%s: comm = %pap/%p\n", __func__, &xvp->comm_phys, xvp->comm); + dev_dbg(xvp->dev,"%s: xvp->pmem = %pap\n", __func__, &xvp->pmem); + // writel(0xdeadbeef,xvp->comm+0x4); + // value = readl(xvp->comm+0x4); + // pr_debug("offset=04, value is:0x%08x\n",value); + + ret = xrp_init_address_map(xvp->dev, &xvp->address_map); + if (ret < 0) + goto err_free_pool; + + if(false ==xrp_translate_base_mimo_to_dsp(xvp)) + { + goto err_free_map; + } + ret = device_property_read_u32_array(xvp->dev, "queue-priority", + NULL, 0); + if (ret > 0) { + xvp->n_queues = ret; + xvp->queue_priority = devm_kmalloc(&pdev->dev, + ret * sizeof(u32), + GFP_KERNEL); + if (xvp->queue_priority == NULL) + goto err_free_pool; + ret = device_property_read_u32_array(xvp->dev, + "queue-priority", + xvp->queue_priority, + xvp->n_queues); + if (ret < 0) + goto err_free_pool; + dev_dbg(xvp->dev, + "multiqueue (%d) configuration, queue priorities:\n", + xvp->n_queues); + for (i = 0; i < xvp->n_queues; ++i) + dev_dbg(xvp->dev, " %d\n", xvp->queue_priority[i]); + } else { + xvp->n_queues = 1; + } + xvp->queue = devm_kmalloc(&pdev->dev, + xvp->n_queues * sizeof(*xvp->queue), + GFP_KERNEL); + xvp->queue_ordered = devm_kmalloc(&pdev->dev, + xvp->n_queues * sizeof(*xvp->queue_ordered), + GFP_KERNEL); + if (xvp->queue == NULL || + xvp->queue_ordered == NULL) + goto err_free_pool; + + for (i = 0; i < xvp->n_queues; ++i) { + mutex_init(&xvp->queue[i].lock); + xvp->queue[i].comm = xvp->comm + XRP_DSP_CMD_STRIDE * i; + init_completion(&xvp->queue[i].completion); + if (xvp->queue_priority) + xvp->queue[i].priority = xvp->queue_priority[i]; + xvp->queue_ordered[i] = xvp->queue + i; + } + sort(xvp->queue_ordered, xvp->n_queues, sizeof(*xvp->queue_ordered), + compare_queue_priority, NULL); + if (xvp->n_queues > 1) { + dev_dbg(xvp->dev, "SW -> HW queue priority mapping:\n"); + for (i = 0; i < xvp->n_queues; ++i) { + dev_dbg(xvp->dev, " %d -> %d\n", + i, xvp->queue_ordered[i]->priority); + } + } + + ret = device_property_read_string(xvp->dev, "firmware-name", + &xvp->firmware_name); + if (ret == -EINVAL || ret == -ENODATA) { + dev_dbg(xvp->dev, + "no firmware-name property, not loading firmware\n"); + } else if (ret < 0) { + dev_err(xvp->dev, "invalid firmware name (%ld)\n", ret); + goto err_free_map; + } + + nodeid = ida_simple_get(&xvp_nodeid, 0, 0, GFP_KERNEL); + if (nodeid < 0) { + ret = nodeid; + goto err_free_map; + } + + sprintf(dir_name,"dsp%d_proc",nodeid); + xvp->proc_dir = proc_mkdir(dir_name, NULL); + if (NULL != xvp->proc_dir) + { + xvp->panic_log = xrp_create_panic_log_proc(xvp->proc_dir,xvp->panic,xvp->panic_size); + } + else + { + dev_err(xvp->dev, "create %s fail\n", dir_name); + goto err_free_id; + } + pm_runtime_enable(xvp->dev); + if (!pm_runtime_enabled(xvp->dev)) { + ret = xrp_runtime_resume(xvp->dev); + if (ret) + goto err_pm_disable; + }else + { + ret = xrp_runtime_resume(xvp->dev); + if (ret) + goto err_proc_remove; + // xvp_enable_dsp(xvp); + xrp_runtime_suspend(xvp->dev); + } + + xvp->nodeid = nodeid; + sprintf(nodename, "xvp%u", nodeid); + + xvp->miscdev = (struct miscdevice){ + .minor = MISC_DYNAMIC_MINOR, + .name = devm_kstrdup(&pdev->dev, nodename, GFP_KERNEL), + .nodename = devm_kstrdup(&pdev->dev, nodename, GFP_KERNEL), + .fops = &xvp_fops, + }; + + ret = misc_register(&xvp->miscdev); + if (ret < 0) + goto err_pm_disable; + // xrp_device_heartbeat_init(xvp); + + INIT_LIST_HEAD(&xvp->dma_buf_list); + + + return PTR_ERR(xvp); + + +err_pm_disable: + pm_runtime_disable(xvp->dev); +err_proc_remove: + xvp_remove_proc(xvp); +err_free_id: + ida_simple_remove(&xvp_nodeid, nodeid); +err_free_map: + xrp_free_address_map(&xvp->address_map); +err_free_pool: + xrp_free_pool(xvp->pool); + if (xvp->comm_phys && !xvp->pmem) { + dma_free_attrs(xvp->dev, PAGE_SIZE, xvp->comm, + phys_to_dma(xvp->dev, xvp->comm_phys), 0); + } +err: + dev_err(&pdev->dev, "%s: ret = %ld\n", __func__, ret); + return ret; +} + +typedef long xrp_init_function(struct platform_device *pdev, + enum xrp_init_flags flags, + const struct xrp_hw_ops *hw_ops, void *hw_arg,int mem_idx); + +xrp_init_function xrp_init; +long xrp_init(struct platform_device *pdev, enum xrp_init_flags flags, + const struct xrp_hw_ops *hw_ops, void *hw_arg,int mem_idx) +{ + return xrp_init_common(pdev, flags, hw_ops, hw_arg, mem_idx,xrp_init_regs_v0); +} +EXPORT_SYMBOL(xrp_init); + +xrp_init_function xrp_init_v1; +long xrp_init_v1(struct platform_device *pdev, enum xrp_init_flags flags, + const struct xrp_hw_ops *hw_ops, void *hw_arg,int mem_idx) +{ + return xrp_init_common(pdev, flags, hw_ops, hw_arg, mem_idx,xrp_init_regs_v1); +} +EXPORT_SYMBOL(xrp_init_v1); + +xrp_init_function xrp_init_cma; +long xrp_init_cma(struct platform_device *pdev, enum xrp_init_flags flags, + const struct xrp_hw_ops *hw_ops, void *hw_arg,int mem_idx) +{ + return xrp_init_common(pdev, flags, hw_ops, hw_arg, mem_idx,xrp_init_regs_cma); +} +EXPORT_SYMBOL(xrp_init_cma); + +int xrp_deinit(struct platform_device *pdev) +{ + struct xvp *xvp = platform_get_drvdata(pdev); + + pm_runtime_disable(xvp->dev); + if (!pm_runtime_status_suspended(xvp->dev)) + xrp_runtime_suspend(xvp->dev); + // xvp_clear_dsp(xvp); + xvp_remove_proc(xvp); + dev_dbg(xvp->dev,"%s:phase 1\n",__func__); + misc_deregister(&xvp->miscdev); + dev_dbg(xvp->dev,"%s:phase 2\n",__func__); + // release_firmware(xvp->firmware); + // dev_dbg(xvp->dev,"%s:phase 3\n",__func__); + xrp_free_pool(xvp->pool); + if (xvp->comm_phys && !xvp->pmem) { + dma_free_attrs(xvp->dev, PAGE_SIZE, xvp->comm, + phys_to_dma(xvp->dev, xvp->comm_phys), 0); + } + dev_dbg(xvp->dev,"%s:phase 3\n",__func__); + xrp_free_address_map(&xvp->address_map); + dev_dbg(xvp->dev,"%s:phase 4\n",__func__); + if(!ida_is_empty(&xvp_nodeid)) + { + ida_simple_remove(&xvp_nodeid, xvp->nodeid); + dev_dbg(xvp->dev,"%s:phase 5\n",__func__); + } + + return 0; +} +EXPORT_SYMBOL(xrp_deinit); + +int xrp_deinit_hw(struct platform_device *pdev, void **hw_arg) +{ + if (hw_arg) { + struct xvp *xvp = platform_get_drvdata(pdev); + *hw_arg = xvp->hw_arg; + } + return xrp_deinit(pdev); +} +EXPORT_SYMBOL(xrp_deinit_hw); +static void *get_hw_sync_data(void *hw_arg, size_t *sz) +{ + void *p = kzalloc(64, GFP_KERNEL); + + *sz = 64; + return p; +} + +static const struct xrp_hw_ops hw_ops = { + .get_hw_sync_data = get_hw_sync_data, +}; + +#ifdef CONFIG_OF +static const struct of_device_id xrp_of_match[] = { + { + .compatible = "cdns,xrp", + .data = xrp_init, + }, { + .compatible = "cdns,xrp,v1", + .data = xrp_init_v1, + }, { + .compatible = "cdns,xrp,cma", + .data = xrp_init_cma, + }, {}, +}; +MODULE_DEVICE_TABLE(of, xrp_of_match); +#endif + +#ifdef CONFIG_ACPI +static const struct acpi_device_id xrp_acpi_match[] = { + { "CXRP0001", 0 }, + { }, +}; +MODULE_DEVICE_TABLE(acpi, xrp_acpi_match); +#endif + +static int xrp_probe(struct platform_device *pdev) +{ + long ret = -EINVAL; + +#ifdef CONFIG_OF + const struct of_device_id *match; + + match = of_match_device(xrp_of_match, &pdev->dev); + if (match) { + xrp_init_function *init = match->data; + + ret = init(pdev, 0, &hw_ops, NULL,0); + return IS_ERR_VALUE(ret) ? ret : 0; + } else { + pr_debug("%s: no OF device match found\n", __func__); + } +#endif +#ifdef CONFIG_ACPI + ret = xrp_init_v1(pdev, 0, &hw_ops, NULL,2); + if (!IS_ERR_VALUE(ret)) { + struct xrp_address_map_entry *entry; + struct xvp *xvp = ERR_PTR(ret); + + ret = 0; + /* + * On ACPI system DSP can currently only access + * its own shared memory. + */ + entry = xrp_get_address_mapping(&xvp->address_map, + xvp->comm_phys); + if (entry) { + entry->src_addr = xvp->comm_phys; + entry->dst_addr = (u32)xvp->comm_phys; + entry->size = (u32)xvp->shared_size + PAGE_SIZE; + } else { + dev_err(xvp->dev, + "%s: couldn't find mapping for shared memory\n", + __func__); + ret = -EINVAL; + } + } +#endif + return ret; +} + +static int xrp_remove(struct platform_device *pdev) +{ + return xrp_deinit(pdev); +} + +static const struct dev_pm_ops xrp_pm_ops = { + SET_RUNTIME_PM_OPS(xrp_runtime_suspend, + xrp_runtime_resume, NULL) +}; + +static struct platform_driver xrp_driver = { + .probe = xrp_probe, + .remove = xrp_remove, + .driver = { + .name = DRIVER_NAME, + .of_match_table = of_match_ptr(xrp_of_match), + .acpi_match_table = ACPI_PTR(xrp_acpi_match), + .pm = &xrp_pm_ops, + }, +}; + +module_platform_driver(xrp_driver); + +MODULE_AUTHOR("T-HEAD"); +MODULE_DESCRIPTION("XRP: Linux device driver for Xtensa Remote Processing"); +MODULE_LICENSE("Dual MIT/GPL"); diff --git a/driver/xrp-user/Makefile b/driver/xrp-user/Makefile new file mode 100644 index 0000000..b1589fb --- /dev/null +++ b/driver/xrp-user/Makefile @@ -0,0 +1,68 @@ +## + # Copyright (C) 2021 Alibaba Group Holding Limited + # + # This program is free software; you can redistribute it and/or modify + # it under the terms of the GNU General Public License version 2 as + # published by the Free Software Foundation. +## + + +# INCLUDES = -I../../driver/isp -I../../common + +TARGET = libdsp.so + +CFLAGS = -O2 -Wall -g -lm -lpthread +CFLAGS:=-fPIC +LDFLAGS:=-shared -fpic +LDFLAGS+=--whole-archive +LDFLAGS += -Lxrp-host -lxrp_linux +LDFLAGS += -Lxrp-common -lxrp-common +LDFLAGS+=--no-whole-archive +# LDFLAGS += -Lxrp-host -lxrp_linux +# LDFLAGS += -Lxrp-common -lxrp-common +# LIB_PATH += -Lxrp-host +# LIB_PATH += -Lxrp-common +# LIBS += -lpthread +# LIBS += -lxrp_linux +# LIBS += -lxrp-common +# USE_THREADS = + + +xrp_SRCS += dsp-ps/csi_dsp_core.c +# xrp_SRCS += dsp-ps/dsp_ps_core.c +xrp_SRCS += dsp-ps/csi_dsp_helper.c +xrp_SRCS += dsp-ps/dsp_common.c + +INCLUDES = -I$(CURDIR) -Ihosted -Iinclude -Ithread-pthread -I../xrp-common -I../../xrp-kernel +# object files will be generated from .c sourcefiles +xrp_OBJS = $(notdir $(xrp_SRCS:.c=.o)) + +all: $(TARGET) + +XRP_COMMON := xrp-common +$(XRP_COMMON): DUMMY + make -C $(XRP_COMMON) + +XRP_LINUX:=xrp-host +$(XRP_LINUX): DUMMY + make -C $(XRP_LINUX) + +DUMMY: + + +$(xrp_OBJS): $(xrp_SRCS) + $(CC) -c $(CFLAGS) $(INCLUDES) $(xrp_SRCS) + + +$(TARGET): $(xrp_OBJS) $(XRP_COMMON) $(XRP_LINUX) + $(LD) $(LDFLAGS) -o $(TARGET) $(xrp_OBJS) $(LIB_PATH) $(LIBS) + +clean: + rm -f *.o + rm -f *.so + rm -rf output + +install: + +.PHONY: clean all prepare common + diff --git a/driver/xrp-user/dsp-ps/csi_dsp_core.c b/driver/xrp-user/dsp-ps/csi_dsp_core.c new file mode 100644 index 0000000..e94efb1 --- /dev/null +++ b/driver/xrp-user/dsp-ps/csi_dsp_core.c @@ -0,0 +1,1363 @@ +/* + * Copyright (c) 2021 Alibaba Group. All rights reserved. + * License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include +#include +#include +#include +#include "../include/xrp_api.h" +#include "../include/dsp_ps_ns.h" +#include "../include/csi_dsp_api.h" +#include "csi_dsp_core.h" +#include "dsp_common.h" +// #include "../xrp-host/xrp_host_common.h" + +#define DEV_ID 0 + +#define DSP_INVALID_ITEM 0xdead +int csi_dsp_cmd_send(const struct xrp_queue *queue,int cmd_type,void * cmd_payload, + size_t payload_size,void *resp, size_t resp_size,struct xrp_buffer_group *buffer_group) +{ + enum xrp_status status; + size_t cmd_size= payload_size+4; + s_cmd_t *cmd=(s_cmd_t *)malloc(cmd_size); + DSP_PRINT(DEBUG,"dsp common cmd send %d\n",cmd_type); + if(!cmd) + { + DSP_PRINT(WARNING,"malloc fail\n",__func__); + return -1; + } + cmd->cmd=cmd_type; + if(payload_size>0) + { + memcpy(cmd->data,cmd_payload,payload_size); + } + + xrp_run_command_sync(queue,cmd,cmd_size,resp,resp_size,buffer_group,&status); + if(status!=XRP_STATUS_SUCCESS) + { + DSP_PRINT(WARNING,"cmd fail\n",__func__); + free(cmd); + return -1; + } + free(cmd); + return 0; + +} + + +/*********************************/ +static int dsp_register_report_item_to_dsp(struct csi_dsp_task_handler *task) +{ + int resp =0; + struct report_config_msg config; + if(!task || task->report_id<0 || !task->instance || !task->instance->comm_queue) + { + DSP_PRINT(ERROR,"param check fail\n"); + return -1; + } + config.report_id=task->report_id; + memcpy(config.task,task->task_ns,TASK_NAME_LINE); + if(csi_dsp_cmd_send(task->instance->comm_queue,PS_CMD_REPORT_CONFIG,&config,sizeof(struct report_config_msg),&resp,sizeof(resp),NULL)) + { + DSP_PRINT(ERROR,"register_report_item_to_dsp fail\n"); + return -1; + } + return 0; +} + +// int csi_dsp_register_report_fix_id(struct csi_dsp_task_handler *task, +// int (*cb)(void*context,void*data), +// void* context, +// size_t data_size) +// { +// if(task->report_id<0) +// { +// printf("report id is invalid\n"); +// return -1; +// } +// if(xrp_add_report_item_with_id(task->instance->report_impl, +// cb,task->report_id,context,data_size)<0) +// { +// return -1; +// } +// if(dsp_register_report_item_to_dsp(task)) +// { +// return -1; +// } +// printf("new reprot %d is created and register to DSP\n",task->report_id); +// return 0; + +// } + + +int csi_dsp_delete_instance(void* dsp) +{ + if(!dsp) + return 0; + // printf("%s,entry\n",__FUNCTION__); + struct csi_dsp_instance *instance = (struct csi_dsp_instance *)dsp; + csi_dsp_disable_heartbeat_check(); + xrp_release_queue(instance->comm_queue); + xrp_release_device(instance->device); + free(dsp); + DSP_PRINT(INFO,"exit\n"); + return 0; +} +void* csi_dsp_create_instance(int dsp_id) +{ + enum xrp_status status; + struct xrp_device *device; + struct csi_dsp_instance *instance = NULL; + struct xrp_queue * queue; + unsigned char ns_id[]=XRP_PS_NSID_COMMON_CMD; + + dsp_InitEnv(); + + instance=malloc(sizeof(*instance)); + if(!instance) + { + DSP_PRINT(ERROR,"malloc fail\n"); + return NULL; + } + device = xrp_open_device(dsp_id, &status); + if(status!=XRP_STATUS_SUCCESS) + { + + free(instance); + DSP_PRINT(ERROR,"open device\n"); + return NULL; + } + instance->device=device; + + /* unsigned char XRP_NSID[] = XRP_PS_NSID_INITIALIZER; + create a comon queue to handler the common message + */ + queue = xrp_create_ns_queue(device, ns_id, &status); + if(status!=XRP_STATUS_SUCCESS) + { + xrp_release_device(device); + free(instance); + DSP_PRINT(ERROR,"create ns queue faile\n"); + return NULL; + } + instance->comm_queue=queue; + INIT_LIST_HEAD(&instance->task_list); + //csi_dsp_enable_heartbeat_check(instance,10); + DSP_PRINT(INFO,"dsp instance create successulf\n"); + return instance; +} + + +int csi_dsp_create_reporter(void* dsp) +{ + struct csi_dsp_instance *instance = (struct csi_dsp_instance *)dsp; + struct xrp_report *reporter = xrp_create_reporter(instance->device,MAX_REPORT_SIZE+32); + if(reporter==NULL) + { + DSP_PRINT(ERROR,"create ns queue\n"); + return -1; + } + instance->report_impl=reporter; + DSP_PRINT(INFO,"create reporter\n"); + return 0; +} + +int csi_dsp_destroy_reporter(void *dsp) +{ + struct csi_dsp_instance *instance = (struct csi_dsp_instance *)dsp; + if(0 == xrp_release_reporter(instance->device,instance->report_impl)) + { + instance->report_impl=NULL; + } + else + { + DSP_PRINT(ERROR,"reporter destroy fail\n"); + return -1; + } + DSP_PRINT(INFO,"release reporter\n"); + return 0; +} + + +static void dsp_task_init(struct csi_dsp_task_handler * task) +{ + task->algo.algo_id = DSP_INVALID_ITEM; + task->algo.task_id = DSP_INVALID_ITEM; + task->fe.frontend_type = CSI_DSP_FE_TYPE_INVALID; + task->be.backend_type = CSI_DSP_BE_TYPE_INVALID; + task->report_id =-1; +} +/* queue ns 应该通过DSP侧来分配保证唯一性,区分不同进程的task.*/ +void *csi_dsp_create_task(void* dsp,csi_dsp_task_mode_e task_type) +{ + struct csi_dsp_task_handler * task; + struct csi_dsp_task_create_resp resp; + struct xrp_queue *queue; + struct csi_dsp_task_create_req config_para; + enum xrp_status status; + struct csi_dsp_instance *instance = (struct csi_dsp_instance *)dsp; + dsp_handler_item_t *task_item =NULL; + if(!instance) + { + DSP_PRINT(ERROR,"param check fail\n"); + return NULL; + } + task_item = malloc(sizeof(*task_item)); + if(!task_item) + { + DSP_PRINT(ERROR,"malloc fail\n"); + goto error1; + } + task= malloc(sizeof(*task)); + if(!task) + { + DSP_PRINT(ERROR,"malloc fail\n"); + goto error; + } + task_item->handler = task; + config_para.type=task_type; + if(csi_dsp_cmd_send(instance->comm_queue,PS_CMD_TASK_ALLOC,&config_para,sizeof(struct csi_dsp_task_create_req),&resp,sizeof(resp),NULL)) + { + DSP_PRINT(ERROR,"PS_CMD_TASK_ALLOC fail\n"); + goto error; + } + if(resp.status!=CSI_DSP_OK) + { + DSP_PRINT(ERROR,"task creat fail:%d\n",resp.status); + goto error; + } + task->queue = NULL; + if(task_type == CSI_DSP_TASK_SW_TO_SW || task_type == CSI_DSP_TASK_SW_TO_HW) + { + + queue = xrp_create_ns_queue(instance->device, resp.task_ns, &status); + if(status!=XRP_STATUS_SUCCESS) + { + DSP_PRINT(ERROR,"queue creat fail\n"); + goto error; + } + task->queue=queue; + + csi_dsp_sw_task_manager_t *sw_task_ctx = malloc(sizeof(*sw_task_ctx)); + if(sw_task_ctx ==NULL) + { + DSP_PRINT(ERROR,"malloc fail\n"); + xrp_release_queue(queue); + goto error; + } + INIT_LIST_HEAD(&sw_task_ctx->event_list); + sw_task_ctx->event_num = 0; + pthread_mutex_init(&sw_task_ctx->mutex, NULL); + task->private = sw_task_ctx; + if(status != XRP_STATUS_SUCCESS) + { + DSP_PRINT(ERROR,"xrp_create_buffer_group fail\n"); + free(sw_task_ctx); + xrp_release_queue(queue); + goto error; + } + } + else{ + // HW task create report + } + task->buffers = xrp_create_buffer_group(&status); + memcpy(task->task_ns,resp.task_ns,TASK_NAME_LINE); + task->task_id=resp.task_id; + task->instance=instance; + task->mode=task_type; + list_add_tail(&task_item->head,&instance->task_list); + dsp_task_init(task); + // task->report_id=-1; + DSP_PRINT(INFO,"task(%d) ,ns(%x)create successful!\n",task->task_id,task->task_ns[0]); + return task; + +error: + free(task); +error1: + free(task_item); + return NULL; +} +void csi_dsp_destroy_task(void *task_ctx) +{ + csi_dsp_status_e resp; + struct csi_dsp_task_handler * task = (struct csi_dsp_task_handler *)task_ctx; + if(task_ctx ==NULL) + { + return; + } + if(task->queue) + xrp_release_queue(task->queue); + + if(task->report_id>=0) + { + xrp_remove_report_item(task->instance->report_impl,task->report_id); + } + + if(task->buffers) + { + xrp_release_buffer_group(task->buffers); + } + + + struct csi_dsp_task_free_req config_para; + + config_para.task_id = task->task_id; + memcpy(config_para.task_ns,task->task_ns,sizeof(config_para.task_ns)); + + if(csi_dsp_cmd_send(task->instance->comm_queue,PS_CMD_TASK_FREE,&config_para,sizeof(struct csi_dsp_task_free_req),&resp,sizeof(resp),NULL)) + { + DSP_PRINT(ERROR,"send PS_CMD_TASK_FREE fail\n"); + } + + if(resp!=CSI_DSP_OK) + { + DSP_PRINT(ERROR,"TASK FREE Fail due to %d\n",resp); + } + DSP_PRINT(INFO,"task(%d) ,ns(%x) destroy successful!\n",task->task_id,task->task_ns[0]); + free(task); +} + +int csi_dsp_task_config_frontend(void *task_ctx,struct csi_dsp_task_fe_para* config_para) +{ + struct csi_dsp_task_handler * task = (struct csi_dsp_task_handler *)task_ctx; + csi_dsp_status_e resp =0; + if(!task || !task->instance || !task->instance->comm_queue) + { + DSP_PRINT(ERROR,"param check fail\n"); + return -1; + } + config_para->task_id= task->task_id ; + if(csi_dsp_cmd_send(task->instance->comm_queue,PS_CMD_FE_CONFIG,config_para,sizeof(struct csi_dsp_task_fe_para),&resp,sizeof(resp),NULL)) + { + DSP_PRINT(ERROR,"config_frontend cmd send fail\n"); + return -1; + } + if(resp != CSI_DSP_OK) + { + DSP_PRINT(ERROR,"PS_CMD_FE_CONFIG fail %d\n",resp); + return -1; + } + memcpy(&task->fe,config_para,sizeof(task->fe)); + DSP_PRINT(INFO,"task(%d) set frontend %d!\n",config_para->task_id,config_para->frontend_type); + return 0; +} + +int csi_dsp_task_get_frontend(void *task_ctx,struct csi_dsp_task_fe_para *config_para) +{ + struct csi_dsp_task_handler * task = (struct csi_dsp_task_handler *)task_ctx; + csi_dsp_status_e resp =0; + if(!config_para|!task || !task->instance || !task->instance->comm_queue) + { + DSP_PRINT(ERROR,"param check fail\n"); + return -1; + } + memcpy(config_para,&task->fe,sizeof(task->fe)); + return 0; +} +int csi_dsp_task_config_backend(void *task_ctx,struct csi_dsp_task_be_para* config_para) +{ + csi_dsp_status_e resp =0; + struct csi_dsp_task_handler * task = (struct csi_dsp_task_handler *)task_ctx; + size_t sz; + if(!task || !task->instance || !task->instance->comm_queue) + { + DSP_PRINT(ERROR,"param check fail\n"); + return -1; + } + config_para->task_id= task->task_id ; + if(config_para->backend_type == CSI_DSP_BE_TYPE_HOST) + { + sz= sizeof(struct csi_dsp_task_be_para)+sizeof(struct csi_dsp_buffer)*config_para->sw_param.num_buf; + } + else + { + sz= sizeof(struct csi_dsp_task_be_para); + } + if(csi_dsp_cmd_send(task->instance->comm_queue,PS_CMD_BE_CONFIG, config_para,sz,&resp,sizeof(resp),NULL)) + { + DSP_PRINT(ERROR,"send cmd fail\n"); + return -1; + } + if(resp != CSI_DSP_OK) + { + DSP_PRINT(ERROR,"resp ERROR: %d\n",resp); + return -1; + } + memcpy(&task->be,config_para,sizeof(task->be)); + DSP_PRINT(INFO,"task(%d) set backend %d!\n",task->task_id,config_para->backend_type); + return 0; +} + +int csi_dsp_task_update_backend_buf(void *task_ctx,struct csi_dsp_task_be_para* config_para) +{ + csi_dsp_status_e resp =0; + struct csi_dsp_task_handler * task = (struct csi_dsp_task_handler *)task_ctx; + size_t sz; + if(!task || !task->instance || !task->instance->comm_queue) + { + DSP_PRINT(ERROR,"param check fail\n"); + return -1; + } + if(config_para->backend_type !=CSI_DSP_BE_TYPE_HOST) + { + DSP_PRINT(ERROR,"unsport backend type\n"); + return -1; + } + config_para->task_id= task->task_id ; + if(config_para->backend_type == CSI_DSP_BE_TYPE_HOST) + { + sz= sizeof(struct csi_dsp_task_be_para)+sizeof(struct csi_dsp_buffer)*config_para->sw_param.num_buf; + } + else + { + sz= sizeof(struct csi_dsp_task_be_para); + } + if(csi_dsp_cmd_send(task->instance->comm_queue,PS_CMD_BE_ASSGIN_BUF, config_para,sz,&resp,sizeof(resp),NULL)) + { + DSP_PRINT(ERROR,"send cmd fail\n"); + return -1; + } + if(resp != CSI_DSP_OK) + { + DSP_PRINT(ERROR,"resp ERROR: %d\n",resp); + return -1; + } + DSP_PRINT(INFO,"task(%d) set backend %d!\n",task->task_id,config_para->backend_type); + return 0; +} + +int csi_dsp_task_get_backend(void *task_ctx,struct csi_dsp_task_be_para* config_para) +{ + csi_dsp_status_e resp =0; + struct csi_dsp_task_handler * task = (struct csi_dsp_task_handler *)task_ctx; + if(!task || !task->instance || !task->instance->comm_queue) + { + DSP_PRINT(ERROR,"param check fail\n"); + return -1; + } + memcpy(config_para,&task->be,sizeof(task->be)); + return 0; +} +int csi_dsp_task_config_algo(void *task_ctx,struct csi_dsp_algo_config_par* config_para) +{ + csi_dsp_status_e resp =0; + struct csi_dsp_task_handler * task = (struct csi_dsp_task_handler *)task_ctx; + struct csi_dsp_algo_config_par config; + struct xrp_buffer *buffer = NULL; + struct xrp_buffer *algo_buffer = NULL; + struct xrp_buffer *algo_set_buffer = NULL; + enum xrp_status status; + void* buf_ptr; + struct xrp_buffer_group *buffer_group =NULL; + if(!task || !task->instance || !task->instance->comm_queue) + { + DSP_PRINT(ERROR,"param check fail\n"); + return -1; + } + config.task_id= task->task_id ; + config.algo_id = config_para->algo_id; + config.algo_ptr = 0; + config.sett_length = config_para->sett_length; + config.sett_ptr = 0; + config.bufs_ptr = 0; + config.buf_num = config_para->buf_num; + config.algo_size = config_para->algo_size; + buffer_group = xrp_create_buffer_group(&status); + if(status != XRP_STATUS_SUCCESS) + { + DSP_PRINT(ERROR,"malloc buf group fail\n"); + return -1; + } + if(config_para->sett_ptr && (config_para->sett_length !=0)) + { + + buffer = xrp_create_buffer(task->instance->device,config.sett_length,NULL,&status); + if(status != XRP_STATUS_SUCCESS) + { + DSP_PRINT(ERROR,"malloc buf fail\n"); + goto Err3; + } + xrp_add_buffer_to_group(buffer_group,buffer,XRP_READ,&status); + xrp_buffer_get_info(buffer,XRP_BUFFER_PHY_ADDR,&config.sett_ptr,sizeof(config.sett_ptr),&status); + xrp_buffer_get_info(buffer,XRP_BUFFER_USER_ADDR,&buf_ptr,sizeof(buf_ptr),&status); + memcpy(buf_ptr,(void*)config_para->sett_ptr,config_para->sett_length); + DSP_PRINT(INFO," setting buf phy:%llx\n",config.sett_ptr); + + } + + if(config_para->bufs_ptr && (config_para->buf_num !=0)) + { + + algo_set_buffer = xrp_create_buffer(task->instance->device,config_para->buf_num*sizeof(struct csi_dsp_buffer),NULL,&status); + if(status != XRP_STATUS_SUCCESS) + { + DSP_PRINT(ERROR,"malloc buf fail\n"); + goto Err3; + } + xrp_add_buffer_to_group(buffer_group,algo_set_buffer,XRP_READ,&status); + xrp_buffer_get_info(algo_set_buffer,XRP_BUFFER_PHY_ADDR,&config.bufs_ptr,sizeof(config.sett_ptr),&status); + xrp_buffer_get_info(algo_set_buffer,XRP_BUFFER_USER_ADDR,&buf_ptr,sizeof(buf_ptr),&status); + memcpy(buf_ptr,(void*)config_para->bufs_ptr,config_para->buf_num*sizeof(struct csi_dsp_buffer)); + DSP_PRINT(INFO," algo_set_buffer phy:%llx\n",config.bufs_ptr); + + } + + if(config_para->algo_ptr && (config_para->algo_size !=0)) + { + + algo_buffer = xrp_create_buffer(task->instance->device,config_para->algo_size,NULL,&status); + if(status != XRP_STATUS_SUCCESS) + { + DSP_PRINT(ERROR,"malloc buf fail\n"); + goto Err2; + } + xrp_add_buffer_to_group(buffer_group,algo_buffer,XRP_READ,&status); + xrp_buffer_get_info(algo_buffer,XRP_BUFFER_PHY_ADDR,&config.algo_ptr,sizeof(config.algo_ptr),&status); + xrp_buffer_get_info(algo_buffer,XRP_BUFFER_USER_ADDR,&buf_ptr,sizeof(buf_ptr),&status); + memcpy(buf_ptr,(void*)config_para->algo_ptr,config_para->algo_size); + DSP_PRINT(INFO,"algo buf phy:%llx\n",config_para->algo_ptr); + + } + + if(csi_dsp_cmd_send(task->instance->comm_queue,PS_CMD_ALGO_CONFIG, &config,sizeof(struct csi_dsp_algo_config_par),&resp,sizeof(resp),buffer_group)) + { + DSP_PRINT(ERROR,"send cmd fail\n"); + goto Err1; + } + + if(resp != CSI_DSP_OK) + { + DSP_PRINT(ERROR,"resp fail %d\n",resp); + goto Err1; + } + memcpy(&task->algo,&config,sizeof(config)); + + if(buffer) + { + xrp_release_buffer(buffer); + } + if(algo_set_buffer) + { + xrp_release_buffer(algo_set_buffer); + } + if(algo_buffer) + { + xrp_release_buffer(algo_buffer); + } + xrp_release_buffer_group(buffer_group); + + DSP_PRINT(INFO,"task %d sucessful!\n",task->task_id); + return 0; + +Err1: + if(algo_buffer) xrp_release_buffer(algo_buffer); +Err2: + if(buffer) xrp_release_buffer(buffer); +Err3: + xrp_release_buffer_group(buffer_group); + return -1; +} + +int csi_dsp_task_load_algo(void *task_ctx, csi_dsp_algo_load_req_t* config_para) +{ + csi_dsp_algo_load_resp_t resp; + struct csi_dsp_task_handler * task = (struct csi_dsp_task_handler *)task_ctx; + if(!task || !task->instance || !task->instance->comm_queue) + { + DSP_PRINT(ERROR,"param check fail\n"); + return -1; + } + config_para->task_id= task->task_id; + if(csi_dsp_cmd_send(task->instance->comm_queue,PS_CMD_ALGO_LOAD, config_para,sizeof(csi_dsp_algo_load_req_t),&resp,sizeof(resp),NULL)) + { + DSP_PRINT(ERROR,"send cmd fail\n"); + return -1; + } + if(resp.status != CSI_DSP_OK) + { + DSP_PRINT(ERROR,"resp fail %d\n",resp.status); + return -1; + } + task->algo.algo_id=config_para->algo_id; + task->algo.algo_ptr = config_para->algo_ptr; + // task->algo.buf_num = resp.buf_desc_num; + // task->algo.sett_length = resp. + DSP_PRINT(INFO,"task %d load algo sucessful!\n",task->task_id); + return 0; +} + +int csi_dsp_task_acquire_algo(void *task_ctx,char*name) +{ + FILE * fp; + int size; + int rev = 0; + char file[128]; + struct xrp_buffer *buffer = NULL; + enum xrp_status status; + void* buf_ptr; + uint64_t buf_phy; + struct xrp_buffer_group *buffer_group =NULL; + csi_dsp_algo_load_resp_t resp; + csi_dsp_algo_load_req_t config_para; + if(task_ctx == NULL || name ==NULL || strlen(name)>100 ) + { + DSP_PRINT(ERROR,"param check fail\n"); + return -1; + } + + sprintf(file,"/lib/firmware/%s.lib",name); + DSP_PRINT(DEBUG,"open file:%s\n",file); + fp = fopen(file, "rb"); + + if(fp==NULL) + { + DSP_PRINT(ERROR,"open file fail\n"); + return -1; + } + fseek(fp , 0, SEEK_END); + size = ftell(fp); + rewind(fp); + + if(size ==0) + { + return -1; + } + + struct csi_dsp_task_handler * task = (struct csi_dsp_task_handler *)task_ctx; + buffer_group = xrp_create_buffer_group(&status); + if(status != XRP_STATUS_SUCCESS) + { + DSP_PRINT(ERROR,"malloc buf group fail\n"); + return -1; + } + buffer = xrp_create_buffer(task->instance->device,size,NULL,&status); + if(status != XRP_STATUS_SUCCESS) + { + DSP_PRINT(ERROR,"malloc buf fail\n"); + return -1; + } + xrp_add_buffer_to_group(buffer_group,buffer,XRP_READ,&status); + xrp_buffer_get_info(buffer,XRP_BUFFER_PHY_ADDR,&buf_phy,sizeof(buf_phy),&status); + xrp_buffer_get_info(buffer,XRP_BUFFER_USER_ADDR,&buf_ptr,sizeof(buf_ptr),&status); + DSP_PRINT(DEBUG,"algo buf virtual:0x%p, phy:0x%lx\n", buf_ptr,buf_phy); + + rev = fread(buf_ptr, 1, size, fp); + if(rev != size) + { + DSP_PRINT(ERROR,"Loading file failed\n"); + return -1; + } + fclose(fp); + config_para.task_id= task->task_id; + config_para.algo_id =-1; + config_para.algo_ptr = buf_phy; + if(csi_dsp_cmd_send(task->instance->comm_queue,PS_CMD_ALGO_LOAD, &config_para,sizeof(csi_dsp_algo_load_req_t),&resp,sizeof(resp),buffer_group)) + { + DSP_PRINT(ERROR,"send cmd fail\n"); + return -1; + } + if(resp.status != CSI_DSP_OK) + { + DSP_PRINT(ERROR,"resp fail %d\n",resp.status); + return -1; + } + + if(buffer) + { + // memset(buf_ptr,0xee,config_para->sett_length); + xrp_release_buffer(buffer); + xrp_release_buffer_group(buffer_group); + } + task->algo.algo_id=config_para.algo_id; + task->algo.algo_ptr = config_para.algo_ptr; + DSP_PRINT(INFO,"task %d acquire algo:%s sucessful!\n",task->task_id,name); + return 0; + +} +int csi_dsp_task_start(void *task_ctx) +{ + csi_dsp_status_e resp; + struct csi_dsp_task_start_req req; + struct csi_dsp_task_handler * task = (struct csi_dsp_task_handler *)task_ctx; + req.task_id = task->task_id; + if(task== NULL) + { + DSP_PRINT(ERROR,"ERR Invalid task \n"); + return -1; + } + if(csi_dsp_cmd_send(task->instance->comm_queue,PS_CMD_TASK_START,&req,sizeof(struct csi_dsp_task_start_req),&resp,sizeof(resp),NULL)) + { + DSP_PRINT(ERROR,"csi_dsp_task_start fail \n",resp); + return -1; + } + + if(resp != CSI_DSP_OK ) + { + DSP_PRINT(ERROR,"csi_dsp_task_start resp due to %d\n",resp); + return -1; + } + DSP_PRINT(INFO,"task start sucessful!\n",task->task_id); + return 0; +} + +int csi_dsp_task_stop(void *task_ctx) +{ + csi_dsp_status_e resp; + struct csi_dsp_task_start_req req; + struct csi_dsp_task_handler * task = (struct csi_dsp_task_handler *)task_ctx; + + if(task== NULL) + { + DSP_PRINT(ERROR,"ERR Invalid task \n"); + return -1; + } + req.task_id = task->task_id; + + if(csi_dsp_cmd_send(task->instance->comm_queue,PS_CMD_TASK_STOP,&req,sizeof(req),&resp,sizeof(resp),NULL)) + { + return -1; + } + if(resp != CSI_DSP_OK) + { + printf("csi_dsp_task_start fail due to %d\n",resp); + } + return 0; + +} + +static int csi_dsp_config_report_item_to_dsp(void *task_ctx,enum cmd_type flag) +{ + csi_dsp_status_e resp; + struct report_config_msg config; + struct csi_dsp_task_handler * task = (struct csi_dsp_task_handler *)task_ctx; + if(!task || task->report_id<0 || !task->instance || !task->instance->comm_queue) + { + DSP_PRINT(ERROR,"param check fail\n"); + return -1; + } + config.report_id=task->report_id; + config.flag = flag; + memcpy(config.task,task->task_ns,TASK_NAME_LINE); + config.addr = 0xdeadbeef; + config.size = task->report_size; + if(csi_dsp_cmd_send(task->instance->comm_queue,PS_CMD_REPORT_CONFIG,&config,sizeof(struct report_config_msg),&resp,sizeof(resp),NULL)) + { + DSP_PRINT(ERROR,"send PS_CMD_REPORT_CONFIG fail\n"); + return -1; + } + if(resp != CSI_DSP_OK) + { + DSP_PRINT(ERROR,"PS_CMD_REPORT_CONFIG fail due to %d\n",resp); + return -1; + } + return 0; +} + + +int csi_dsp_task_register_cb(void *task_ctx, + int (*cb)(void*context,void*data), + void* context, + size_t data_size) +{ + struct csi_dsp_task_handler * task = (struct csi_dsp_task_handler *)task_ctx; + task->report_id = task->task_id; + if(task->report_id<0) + { + DSP_PRINT(WARNING,"report id is invalid\n"); + return -1; + } + task->report_size = data_size; + if(xrp_add_report_item_with_id(task->instance->report_impl, + cb,task->report_id,context,data_size)<0) + { + DSP_PRINT(WARNING,"report id is invalid\n"); + return -1; + } + if(csi_dsp_config_report_item_to_dsp(task,CMD_SETUP)) + { + DSP_PRINT(WARNING,"report id is invalid\n"); + return -1; + } + task->cb = cb; + task->context = context; + DSP_PRINT(INFO,"new reprot %d is created and register to DSP\n",task->report_id); + return 0; +} + +int csi_dsp_ps_task_unregister_cb(void *task_ctx) +{ + struct csi_dsp_task_handler * task = (struct csi_dsp_task_handler *)task_ctx; + if(task->report_id<0) + { + DSP_PRINT(WARNING,"report id is invalid\n"); + return -1; + } + if(csi_dsp_config_report_item_to_dsp(task,CMD_RELEASE)) + { + DSP_PRINT(WARNING,"report release fail\n"); + return -1; + } + + xrp_remove_report_item(task->instance->report_impl,task->report_id); + DSP_PRINT(INFO,"new reprot %d is unregister to DSP\n",task->report_id); + task->report_id =-1; + + return 0; + +} + +struct csi_sw_task_req* csi_dsp_task_create_request(void *task_ctx) +{ + struct csi_dsp_task_handler * task = (struct csi_dsp_task_handler *)task_ctx; + struct csi_sw_task_req* req = NULL; + void* req_ptr,*event_ptr; + enum xrp_status status; + if(task->mode != CSI_DSP_TASK_SW_TO_SW) + { + DSP_PRINT(WARNING,"un-support for task type:%d\n",task->mode); + return NULL; + } + if(task->algo.algo_id == DSP_INVALID_ITEM) + { + DSP_PRINT(WARNING,"algo is not loaded:%d\n",task->algo.algo_id); + return NULL; + } + req = malloc(sizeof(*req)); + if(req == NULL) + { + DSP_PRINT(WARNING,"memroy alloc fail\n"); + return NULL; + } + + req->priv = xrp_create_buffer_group(&status); + if(status != XRP_STATUS_SUCCESS) + { + DSP_PRINT(WARNING,"buffer group create fail\n"); + free(req); + return NULL; + } + req->status = CSI_DSP_SW_REQ_IDLE; + req->algo_id = task->algo.algo_id; + req->task = task_ctx; + req->buffer_num =0; + req->request_id = rand(); + req->sett_length =0; + req->sett_ptr = NULL; + DSP_PRINT(DEBUG,"new req %d is created in task %d\n",req->request_id,task->task_id); + return req; + +} + + +int csi_dsp_task_release_request(struct csi_sw_task_req* req) +{ + struct xrp_buffer_group *group; + enum xrp_status status; + int buf_idx,plane_idx;; + struct xrp_buffer *buffer; + int index; + size_t buf_num; + struct csi_dsp_task_handler * task =(struct csi_dsp_task_handler *) req->task; + if(req == NULL) + { + return 0; + } + group = (struct xrp_buffer_group *)req->priv; + if(group == NULL) + { + free(req); + DSP_PRINT(WARNING,"buffer group create fail\n"); + return -1; + } + + for(buf_idx=0;buf_idxbuffer_num;buf_idx++) + { + if(req->buffers[buf_idx].type == CSI_DSP_BUF_TYPE_DMA_BUF_IMPORT || + req->buffers[buf_idx].type == CSI_DSP_BUF_TYPE_DMA_BUF_EXPORT) + { + for(plane_idx =0 ;plane_idxbuffers[buf_idx].plane_count;plane_idx++) + { + xrp_release_dma_buf(task->instance->device,req->buffers[buf_idx].planes[plane_idx].fd,&status); + } + } + else + { + for(plane_idx =0 ;plane_idxbuffers[buf_idx].plane_count;plane_idx++) + { + // printf("release buf %d plane %d\n",buf_idx,plane_idx); + buffer = xrp_get_buffer_from_group(group,req->buffers[buf_idx].planes[plane_idx].fd,&status); + xrp_unmap_buffer(buffer,(void *)req->buffers[buf_idx].planes[plane_idx].buf_vir,&status); + xrp_release_buffer(buffer); + } + } + + } + /*free sett buf */ + xrp_buffer_group_get_info(group,XRP_BUFFER_GROUP_SIZE_SIZE_T, 0,&buf_num,sizeof(buf_num),&status); + if(status!=XRP_STATUS_SUCCESS) + { + DSP_PRINT(WARNING,"Get sett buffer release fail\n"); + return -1; + } + uint64_t buf_phy; + for(index=0; indexsett_ptr) + { + // xrp_unmap_buffer(buffer,(void *)req->buffers[buf_idx].planes[plane_idx].buf_vir,&status); + xrp_release_buffer(buffer); + break; + } + } + + xrp_release_buffer_group(group); + DSP_PRINT(DEBUG,"req %d is release successful!\n",req->request_id); + free(req); + return 0; +} +int csi_dsp_task_create_buffer(void * task_ctx,struct csi_dsp_buffer * buffer) +{ + struct csi_dsp_task_handler * task= (struct csi_dsp_task_handler *)task_ctx; + int i,j; + struct xrp_buffer * buf=NULL; + size_t buf_size; + int fail_release =0; + uint64_t phy_addr; + enum xrp_status status; + if(task == NULL || buffer==NULL) + { + DSP_PRINT(WARNING,"param check fail\n"); + return -1; + } + if(task->buffers==NULL) + { + DSP_PRINT(WARNING,"Buffrs not init\n"); + return -1; + } + switch(buffer->type) + { + case CSI_DSP_BUF_ALLOC_DRV: + for(i=0;iplane_count;i++) + { + buf = xrp_create_buffer(task->instance->device,buffer->planes[i].size,NULL,&status); + if(status != XRP_STATUS_SUCCESS) + { + DSP_PRINT(WARNING,"create xrp buffer fail\n"); + goto err_1; + } + else + { + int flag = buffer->dir == CSI_DSP_BUFFER_IN ?XRP_READ:XRP_WRITE; + buffer->planes[i].buf_vir = xrp_map_buffer(buf,0,buffer->planes[i].size,flag,&status); + if(status != XRP_STATUS_SUCCESS) + { + + xrp_release_buffer(buf); + DSP_PRINT(WARNING,"Error Map Buffrs not fail\n"); + goto err_1; + } + // printf("%s,Debug V:%llx,P:%llx\n",__FUNCTION__,buf->ptr,buf->phy_addr); + xrp_buffer_get_info(buf,XRP_BUFFER_PHY_ADDR,&buffer->planes[i].buf_phy,sizeof(phy_addr),&status); + if(status != XRP_STATUS_SUCCESS) + { + + xrp_unmap_buffer(buf,buffer->planes[i].buf_vir,&status); + xrp_release_buffer(buf); + DSP_PRINT(WARNING,"Error get phy addr fail\n"); + goto err_1; + } + buffer->planes[i].fd = xrp_add_buffer_to_group(task->buffers,buf,flag,&status); + if(status !=XRP_STATUS_SUCCESS) + { + xrp_unmap_buffer(buf,buffer->planes[i].buf_vir,&status); + xrp_release_buffer(buf); + DSP_PRINT(WARNING,"add to buffer group fail\n"); + goto err_1; + } + } + DSP_PRINT(DEBUG,"create buffer:Vaddr(0x%llx),Paddr(0x%llx)\n", buffer->planes[i].buf_vir,buffer->planes[i].buf_phy); + } + return 0; + + err_1: + for(j=0;jbuffers, buffer->planes[j].fd,&status); + xrp_unmap_buffer(buf,buffer->planes[j].buf_vir,&status); + xrp_release_buffer(buf); + } + return -1; + + case CSI_DSP_BUF_ALLOC_APP: + return 0; + case CSI_DSP_BUF_TYPE_DMA_BUF_EXPORT: + DSP_PRINT(INFO,"ERR DMA buffer export not support\n"); + return 0; + case CSI_DSP_BUF_TYPE_DMA_BUF_IMPORT: + + for(i=0;iplane_count;i++) + { + int flag = buffer->dir == CSI_DSP_BUFFER_IN ?XRP_READ:XRP_WRITE; + + + xrp_import_dma_buf(task->instance->device,buffer->planes[i].fd,flag,&buffer->planes[i].buf_phy, + &buffer->planes[i].buf_vir,&buffer->planes[i].size,&status); + if(status !=XRP_STATUS_SUCCESS ) + { + DSP_PRINT(WARNING,"dma buf import fail\n"); + goto err_2; + } + + } + break; + err_2: + for(j=0;jinstance->device,buffer->planes[i].fd,&status); + } + return -1; + default: + DSP_PRINT(WARNING,"buffer type:%d not support\n",buffer->type); + return -1; + } + return 0; + +} + +int csi_dsp_task_free_buffer(void * task_ctx,struct csi_dsp_buffer * buffer) +{ + struct csi_dsp_task_handler * task= (struct csi_dsp_task_handler *)task_ctx; + int i,j; + struct xrp_buffer * buf=NULL; + size_t buf_size; + int fail_release =0; + uint64_t phy_addr; + enum xrp_status status; + + if(task == NULL||task->buffers==NULL||buffer==NULL) + { + DSP_PRINT(WARNING,"param check fail\n") + return -1; + } + + + switch(buffer->type) + { + case CSI_DSP_BUF_ALLOC_DRV: + for(i=0;iplane_count;i++) + { + + buf = xrp_get_buffer_from_group(task->buffers,buffer->planes[i].fd,&status); + xrp_unmap_buffer(buf,buffer->planes[i].buf_vir,&status); + xrp_release_buffer(buf); + } + break; + + case CSI_DSP_BUF_ALLOC_APP: + break; + case CSI_DSP_BUF_TYPE_DMA_BUF_EXPORT: + DSP_PRINT(WARNING,"buffer type not support\n"); + break; + case CSI_DSP_BUF_TYPE_DMA_BUF_IMPORT: + for(i=0;iplane_count;i++) + { + xrp_release_dma_buf(task->instance->device,buffer->planes[i].fd,&status); + if(status != XRP_STATUS_SUCCESS) + { + DSP_PRINT(WARNING,"ERR DMA Buffrs(%d) Release fail\n",buffer->planes[i].fd); + return -1; + } + } + break; + default: + DSP_PRINT(WARNING,"buffer type:%d not support\n",buffer->type); + return -1; + } + return 0; + +} + +int csi_dsp_request_add_buffer(struct csi_sw_task_req* req,struct csi_dsp_buffer * buffer) +{ + struct csi_dsp_task_handler * task=NULL; + struct xrp_buffer * buf=NULL; + enum xrp_status status; + int i,j; + struct xrp_buffer_group *buf_gp ; + if(!req ) + { + return -1; + } + buf_gp = (struct xrp_buffer_group *)req->priv; + task = req->task; + int flag = buffer->dir == CSI_DSP_BUFFER_IN ?XRP_READ:XRP_WRITE; + switch(buffer->type) + { + case CSI_DSP_BUF_ALLOC_DRV: + for(i=0;iplane_count;i++) + { + buf = xrp_create_buffer(task->instance->device,buffer->planes[i].size,NULL,&status); + if(status != XRP_STATUS_SUCCESS) + { + DSP_PRINT(WARNING,"create buffer failed\n"); + goto err_1; + } + else + { + + buffer->planes[i].buf_vir = xrp_map_buffer(buf,0,buffer->planes[i].size,flag,&status); + if(status != XRP_STATUS_SUCCESS) + { + DSP_PRINT(WARNING,"Map Buffrs not init\n"); + xrp_release_buffer(buf); + goto err_1; + } + xrp_buffer_get_info(buf,XRP_BUFFER_PHY_ADDR,&buffer->planes[i].buf_phy,sizeof(uint64_t),&status); + if(status != XRP_STATUS_SUCCESS) + { + DSP_PRINT(WARNING,"xrp_buffer_get_info failed\n"); + xrp_unmap_buffer(buf,buffer->planes[i].buf_vir,&status); + xrp_release_buffer(buf); + goto err_1; + } + buffer->planes[i].fd = xrp_add_buffer_to_group(buf_gp,buf,flag,&status); + if(status !=XRP_STATUS_SUCCESS) + { + DSP_PRINT(WARNING,"xrp_add_buffer_to_group failed\n"); + xrp_unmap_buffer(buf,buffer->planes[i].buf_vir,&status); + xrp_release_buffer(buf); + goto err_1; + } + } + DSP_PRINT(DEBUG,"create buffer:Vaddr(0x%llx),Paddr(0x%llx)\n", buffer->planes[i].buf_vir,buffer->planes[i].buf_phy); + } + memcpy(&req->buffers[req->buffer_num++],buffer,sizeof(*buffer)); + return 0; + + err_1: + for(j=0;jplanes[j].fd,&status); + xrp_unmap_buffer(buf,buffer->planes[j].buf_vir,&status); + xrp_release_buffer(buf); + } + return -1; + case CSI_DSP_BUF_TYPE_DMA_BUF_EXPORT: + DSP_PRINT(INFO,"ERR DMA buffer export not support\n"); + return -1; + case CSI_DSP_BUF_TYPE_DMA_BUF_IMPORT: + + for(i=0;iplane_count;i++) + { + xrp_import_dma_buf(task->instance->device,buffer->planes[i].fd,flag,&buffer->planes[i].buf_phy, + & buffer->planes[i].buf_vir,&buffer->planes[i].size,&status); + if(status !=XRP_STATUS_SUCCESS ) + { + DSP_PRINT(WARNING,"dma buf import fail\n"); + goto err_2; + } + + } + memcpy(&req->buffers[req->buffer_num++],buffer,sizeof(*buffer)); + break; + err_2: + for(j=0;jinstance->device,buffer->planes[i].fd,&status); + } + return -1; + case CSI_DSP_BUF_ALLOC_APP: + return 0; + default: + DSP_PRINT(WARNING,"buffer type not support\n"); + return -1; + } + return 0; +} + +int csi_dsp_request_set_property(struct csi_sw_task_req* req,void* property,size_t sz) +{ + if(!req || !property || sz==0) + { + return -1; + } + csi_dsp_status_e status; + struct csi_dsp_task_handler * task=req->task; + struct xrp_buffer * buf=NULL; + void *sett_virt_addr =NULL; + struct xrp_buffer_group *buf_gp ; + + buf_gp = (struct xrp_buffer_group *)req->priv; + req->sett_length = sz; + buf = xrp_create_buffer(task->instance->device,req->sett_length,NULL,&status); + if(status != XRP_STATUS_SUCCESS) + { + DSP_PRINT(WARNING,"create buffer failed\n"); + return -1; + } + else + { + + xrp_buffer_get_info(buf,XRP_BUFFER_USER_ADDR,&sett_virt_addr,sizeof(uint64_t),&status); + if(status != XRP_STATUS_SUCCESS) + { + DSP_PRINT(WARNING,"ERROR get virtual addr\n"); + xrp_release_buffer(buf); + return -1; + } + xrp_buffer_get_info(buf,XRP_BUFFER_PHY_ADDR,&req->sett_ptr,sizeof(uint64_t),&status); + if(status != XRP_STATUS_SUCCESS) + { + DSP_PRINT(WARNING,"Get PHY_ADDR failed\n"); + xrp_release_buffer(buf); + return -1; + } + xrp_add_buffer_to_group(buf_gp,buf,XRP_READ,&status); + if(status !=XRP_STATUS_SUCCESS) + { + DSP_PRINT(WARNING,"xrp_add_buffer_to_group failed\n"); + xrp_release_buffer(buf); + return -1; + } + } + memcpy(sett_virt_addr,property,req->sett_length); + DSP_PRINT(DEBUG,"setting propert in %p succeful!\n",req->sett_ptr); + return 0; +} + + +int csi_dsp_request_enqueue(struct csi_sw_task_req* req) +{ + struct csi_dsp_task_handler * task=NULL; + struct xrp_buffer * buf=NULL; + task_event_item_t *event_item; + csi_dsp_status_e status; + struct xrp_event *evt; + csi_dsp_sw_task_manager_t * sw_task_ctx; + enum xrp_status s; + int loop; + if(!req ) + { + return -1; + } + task = (struct csi_dsp_task_handler *)req->task; + + sw_task_ctx = (csi_dsp_sw_task_manager_t *)task->private; + event_item = malloc(sizeof(task_event_item_t)); + if(event_item==NULL) + { + DSP_PRINT(WARNING,"malloc fail\n"); + return -1; + } + + for(loop =0;loopbuffer_num;loop++) + { + csi_dsp_buf_flush(task->instance->device,&req->buffers[loop]); + } + + xrp_enqueue_command(task->queue, req, sizeof(struct csi_sw_task_req), + &event_item->req_status, sizeof(event_item->req_status), + req->priv, &evt, &s); + if (s != XRP_STATUS_SUCCESS) { + DSP_PRINT(WARNING,"enqueue task to dsp fail\n"); + return -1; + } + + req->status = CSI_DSP_SW_REQ_RUNNING; + event_item->event = evt; + event_item->req = req; + pthread_mutex_lock(&sw_task_ctx->mutex); + list_add_tail(&event_item->head,&sw_task_ctx->event_list); + sw_task_ctx->event_num++; + pthread_mutex_unlock(&sw_task_ctx->mutex); + DSP_PRINT(DEBUG,"Req %d is enqueue \n",req->request_id); + return 0; +} + +struct csi_sw_task_req* csi_dsp_request_dequeue(void *task_ctx) +{ + struct csi_dsp_task_handler * task=(struct csi_dsp_task_handler *)task_ctx; + csi_dsp_sw_task_manager_t * sw_task_ctx = (csi_dsp_sw_task_manager_t *)task->private; + struct csi_sw_task_req* req=NULL; + int id=0; + task_event_item_t *item; + enum xrp_status status; + int loop; + pthread_mutex_lock(&sw_task_ctx->mutex); + struct xrp_event **evts = malloc(sw_task_ctx->event_num*sizeof(struct xrp_event*)); + list_for_each_entry(item,&sw_task_ctx->event_list,head){ + evts[id++]=item->event; + } + pthread_mutex_unlock(&sw_task_ctx->mutex); + DSP_PRINT(DEBUG,"Wait for Req event \n"); + id= xrp_wait_any(evts,sw_task_ctx->event_num,&status); + if(id>=sw_task_ctx->event_num || status !=XRP_STATUS_SUCCESS) + { + DSP_PRINT(WARNING,"id invalid:%d\n",id); + return NULL; + } + list_for_each_entry(item,&sw_task_ctx->event_list,head){ + if(item->event == evts[id]) + break; + } + pthread_mutex_lock(&sw_task_ctx->mutex); + list_del(&item->head); + sw_task_ctx->event_num--; + pthread_mutex_unlock(&sw_task_ctx->mutex); + req = item->req; + xrp_release_event(item->event); + if(item->req_status !=CSI_DSP_OK) + { + DSP_PRINT(WARNING,"req fail with resp:%d\n",item->req_status); + req->status = CSI_DSP_SW_REQ_FAIL; + } + else{ + req->status = CSI_DSP_SW_REQ_DONE; + } + free(evts); + free(item); + + for(loop =0;loopbuffer_num;loop++) + { + csi_dsp_buf_flush(task->instance->device,&req->buffers[loop]); + } + + DSP_PRINT(DEBUG,"Req %d is deuque \n",req->request_id); + return req; +} + + +int csi_dsp_test_config(void* dsp ,struct csi_dsp_ip_test_par* config_para,void* buf) +{ + struct csi_dsp_instance * instance = (struct csi_dsp_instance *)dsp; + if(!dsp || !buf || !config_para->result_buf_size) + { + DSP_PRINT(WARNING,"param check fail\n"); + return -1; + } + + if(csi_dsp_cmd_send(instance->comm_queue,PS_CMD_DSP_IP_TEST, config_para,sizeof(struct csi_dsp_ip_test_par),buf,config_para->result_buf_size,NULL)) + { + DSP_PRINT(WARNING," send cmd fail\n"); + return -1; + } + + return 0; +} \ No newline at end of file diff --git a/driver/xrp-user/dsp-ps/csi_dsp_core.h b/driver/xrp-user/dsp-ps/csi_dsp_core.h new file mode 100644 index 0000000..be38f29 --- /dev/null +++ b/driver/xrp-user/dsp-ps/csi_dsp_core.h @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2021 Alibaba Group. All rights reserved. + * License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +/*! + * \file + * \brief This section defines CSI DSP API. + * + + */ + +#ifndef _CSI_DSP_CORE_H +#define _CSI_DSP_CORE_H + +#include +#include "xrp_api.h" +#include "csi_dsp_task_defs.h" +#include "csi_dsp_post_process_defs.h" +#include "dsp_ps_ns.h" +#include "list.h" +#include +#ifdef __cplusplus +extern "C" { +#endif + + + +struct csi_dsp_logger{ + + struct xrp_queue *comm_queue; + struct log_ops{ + int (*create)(int mode); + int(*enable)(); + int (*disable)(); + }; +}; + +struct csi_dsp_monitor{ + + struct xrp_queue *comm_queue; + struct mon_ops{ + int(*enable)(); + int (*disable)(); + }; +}; + + + +typedef struct dsp_handler_item{ + struct list_head head; + void* handler; +}dsp_handler_item_t; + +struct csi_dsp_instance{ + int id; + struct xrp_device *device; + struct xrp_queue *comm_queue; + struct csi_dsp_logger *logger_impl; + struct csi_dsp_monitor *monitor_impl; + struct xrp_report *report_impl; + + struct list_head task_list; + +}; + +struct csi_dsp_task_handler{ + int task_id; + char task_ns[TASK_NAME_LINE]; + + csi_dsp_task_mode_e mode; + struct csi_dsp_instance *instance; + struct xrp_queue *queue; + struct csi_dsp_task_fe_para fe; + + struct csi_dsp_task_be_para be; + + struct csi_dsp_algo_config_par algo; + + struct xrp_buffer_group *buffers; //store task level buf info + int priority; + int report_id; + uint32_t report_size; + int (*cb)(void*context,void*data); + void *context; + void *private; + +}; + +typedef struct task_event_item{ + struct list_head head; + struct xrp_event * event; + struct csi_sw_task_req* req; + csi_dsp_status_e req_status; +}task_event_item_t; + +typedef struct csi_dsp_sw_task_manager{ + + struct list_head event_list; + int event_num; + pthread_mutex_t mutex; +}csi_dsp_sw_task_manager_t; + +int csi_dsp_test_config(void* dsp ,struct csi_dsp_ip_test_par* config_para,void* buf); +int csi_dsp_cmd_send(const struct xrp_queue *queue,int cmd_type,void * cmd_payload, + size_t payload_size,void *resp, size_t resp_size,struct xrp_buffer_group *buffer_group); +int csi_dsp_enable_heartbeat_check(struct csi_dsp_instance *dsp ,int secs); + +int csi_dsp_disable_heartbeat_check(); +int csi_dsp_buf_flush( struct xrp_device *device,struct csi_dsp_buffer *buffers); +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/driver/xrp-user/dsp-ps/csi_dsp_helper.c b/driver/xrp-user/dsp-ps/csi_dsp_helper.c new file mode 100644 index 0000000..cf2d403 --- /dev/null +++ b/driver/xrp-user/dsp-ps/csi_dsp_helper.c @@ -0,0 +1,159 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "../include/xrp_api.h" +#include "../include/dsp_ps_ns.h" +#include "../include/csi_dsp_api.h" +#include "csi_dsp_core.h" +#include "csi_dsp_task_defs.h" +#include "dsp_common.h" +// #include "../xrp-host/xrp_host_common.h" +struct csi_dsp_instance *instance = NULL; +void csi_dsp_heartbeak_polling() +{ + dsp_handler_item_t *task_item =NULL; + struct itimerval val,oval; + struct csi_dsp_task_handler *task; + // static counter =0; + + DSP_PRINT(INFO,"heartbeat checking\n"); + if(instance == NULL) + { + DSP_PRINT(WARNING,"dsp instance is NULL\n"); + return; + } + // counter++; + /*close timer*/ + val.it_value.tv_sec = 0; + val.it_value.tv_usec =0; + val.it_interval.tv_sec = 0; + val.it_interval.tv_usec =0; + setitimer(ITIMER_REAL,&val,&oval); + + if(csi_dsp_cmd_send(instance->comm_queue,PS_CMD_HEART_BEAT_REQ,NULL,0,NULL,0,NULL)) + { + DSP_PRINT(WARNING,"PS_CMD_TASK_ALLOC fail\n"); + s_cmd_t cmd = + { + .cmd=CSI_DSP_REPORT_HEARTBEAT_ERR, + }; + list_for_each_entry(task_item,&instance->task_list,head) + { + task = task_item->handler; + if(task->mode & CSI_DSP_TASK_HW) + { + if(task->cb) + task->cb(task->context,&cmd); + } + } + } + /*restore timer*/ + setitimer(ITIMER_REAL,&oval,NULL); + return; +} + + +int csi_dsp_enable_heartbeat_check(struct csi_dsp_instance *dsp ,int secs) +{ + struct itimerval val,oval; + signal(SIGALRM,csi_dsp_heartbeak_polling); + val.it_value.tv_sec = secs; + val.it_value.tv_usec =0; + val.it_interval.tv_sec = secs; + val.it_interval.tv_usec =0; + instance = dsp; + DSP_PRINT(DEBUG,"period:%d sec hearbeat working\n",secs); + return setitimer(ITIMER_REAL,&val,&oval); + +} + +int csi_dsp_disable_heartbeat_check() +{ + struct itimerval val; + val.it_value.tv_sec = 0; + val.it_value.tv_usec =0; + val.it_interval.tv_sec = 0; + val.it_interval.tv_usec =0; + instance = NULL; + DSP_PRINT(INFO,"sec hearbeat disable\n"); + return setitimer(ITIMER_REAL,&val,NULL); + +} +void isp_algo_result_handler(void *context,void *data) +{ + s_cmd_t *msg=(s_cmd_t *)data; + printf("report recived:%x\n",msg->cmd); + switch(msg->cmd) + { + case CSI_DSP_REPORT_ISP_ERR: + printf("ISP error:%d\n",msg->data[0]); + break; + case CSI_DSP_REPORT_RY_ERR: + printf("Post ISP error\n",msg->data[0]); + break; + case CSI_DSP_REPORT_ALGO_ERR: + printf("algo err\n"); + break; + case CSI_DSP_REPORT_VI_PRE_ERR: + break; + case CSI_DSP_REPORT_RESULT: + break; + case CSI_DSP_REPORT_HEARTBEAT_ERR: + printf("heartbeat not detect\n"); + break; + default: + break; + + } + +} + + +int csi_dsp_buf_flush( struct xrp_device *device,struct csi_dsp_buffer *buffers) +{ + int loop; + enum xrp_status status; + int flag = buffers->dir == CSI_DSP_BUFFER_IN ?XRP_READ:XRP_WRITE; + if(buffers->type == CSI_DSP_BUF_TYPE_DMA_BUF_IMPORT || + buffers->type == CSI_DSP_BUF_TYPE_DMA_BUF_IMPORT ) + { + for(loop=0;loopplane_count;loop++) + { + xrp_flush_dma_buf(device, buffers->planes[loop].fd,flag,&status); + } + + } + +} + +// void hw_task_result_handler(void *context,void *data) +// { +// s_cmd_t *msg=(s_cmd_t *)data; +// struct csi_dsp_task_handler * task = (struct csi_dsp_task_handler *)context; +// printf("report recived:%x\n",msg->cmd); +// switch(msg->cmd) +// { +// case VI_SYS_REPORT_ISP_ERR: +// printf("ISP error:%d\n",msg->data[0]); +// break; +// case VI_SYS_REPORT_RY_ERR: +// printf("Post ISP error\n",msg->data[0]); +// break; +// case VI_SYS_REPORT_ALGO_ERR: +// printf("algo err\n"); +// break; +// case VI_SYS_REPORT_RESULT: +// if(task->cb) +// { +// task->cb(task->context,) +// } +// break; +// default: +// break; +// } +// } \ No newline at end of file diff --git a/driver/xrp-user/dsp-ps/dsp_common.c b/driver/xrp-user/dsp-ps/dsp_common.c new file mode 100644 index 0000000..ccf4e6d --- /dev/null +++ b/driver/xrp-user/dsp-ps/dsp_common.c @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2022 Alibaba Group. All rights reserved. + * License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "dsp_common.h" + +int log_level = CSI_DSP_LOG_INFO; +int pid = 0; + + +static int getLogLevel() +{ + pid = getpid(); + char *env = getenv("LIGHT_DSP_LOG_LEVEL"); + + if (env == NULL) + return CSI_DSP_LOG_ERROR; + else + { + int level = atoi(env); + if (level >= CSI_DSP_LOG_MAX || level < CSI_DSP_LOG_QUIET) + return CSI_DSP_LOG_ERROR; + else + return level; + } +} + +void dsp_InitEnv() +{ + log_level = getLogLevel(); + +} diff --git a/driver/xrp-user/dsp-ps/list.h b/driver/xrp-user/dsp-ps/list.h new file mode 100644 index 0000000..efe0696 --- /dev/null +++ b/driver/xrp-user/dsp-ps/list.h @@ -0,0 +1,353 @@ +/* + * Copyright © 2010 Intel Corporation + * Copyright © 2010 Francisco Jerez + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + */ + +/* Modified by Ben Skeggs to match kernel list APIs */ + +#ifndef _XORG_LIST_H_ +#define _XORG_LIST_H_ + +/** + * @file Classic doubly-link circular list implementation. + * For real usage examples of the linked list, see the file test/list.c + * + * Example: + * We need to keep a list of struct foo in the parent struct bar, i.e. what + * we want is something like this. + * + * struct bar { + * ... + * struct foo *list_of_foos; -----> struct foo {}, struct foo {}, struct foo{} + * ... + * } + * + * We need one list head in bar and a list element in all list_of_foos (both are of + * data type 'struct list_head'). + * + * struct bar { + * ... + * struct list_head list_of_foos; + * ... + * } + * + * struct foo { + * ... + * struct list_head entry; + * ... + * } + * + * Now we initialize the list head: + * + * struct bar bar; + * ... + * INIT_LIST_HEAD(&bar.list_of_foos); + * + * Then we create the first element and add it to this list: + * + * struct foo *foo = malloc(...); + * .... + * list_add(&foo->entry, &bar.list_of_foos); + * + * Repeat the above for each element you want to add to the list. Deleting + * works with the element itself. + * list_del(&foo->entry); + * free(foo); + * + * Note: calling list_del(&bar.list_of_foos) will set bar.list_of_foos to an empty + * list again. + * + * Looping through the list requires a 'struct foo' as iterator and the + * name of the field the subnodes use. + * + * struct foo *iterator; + * list_for_each_entry(iterator, &bar.list_of_foos, entry) { + * if (iterator->something == ...) + * ... + * } + * + * Note: You must not call list_del() on the iterator if you continue the + * loop. You need to run the safe for-each loop instead: + * + * struct foo *iterator, *next; + * list_for_each_entry_safe(iterator, next, &bar.list_of_foos, entry) { + * if (...) + * list_del(&iterator->entry); + * } + * + */ + +/** + * The linkage struct for list nodes. This struct must be part of your + * to-be-linked struct. struct list_head is required for both the head of the + * list and for each list node. + * + * Position and name of the struct list_head field is irrelevant. + * There are no requirements that elements of a list are of the same type. + * There are no requirements for a list head, any struct list_head can be a list + * head. + */ +struct list_head { + struct list_head *next, *prev; +}; + +/** + * Initialize the list as an empty list. + * + * Example: + * INIT_LIST_HEAD(&bar->list_of_foos); + * + * @param The list to initialized. + */ +#define LIST_HEAD_INIT(name) { &(name), &(name) } + +#define LIST_HEAD(name) \ + struct list_head name = LIST_HEAD_INIT(name) + +static inline void +INIT_LIST_HEAD(struct list_head *list) +{ + list->next = list->prev = list; +} + +static inline void +__list_add(struct list_head *entry, + struct list_head *prev, struct list_head *next) +{ + next->prev = entry; + entry->next = next; + entry->prev = prev; + prev->next = entry; +} + +/** + * Insert a new element after the given list head. The new element does not + * need to be initialised as empty list. + * The list changes from: + * head → some element → ... + * to + * head → new element → older element → ... + * + * Example: + * struct foo *newfoo = malloc(...); + * list_add(&newfoo->entry, &bar->list_of_foos); + * + * @param entry The new element to prepend to the list. + * @param head The existing list. + */ +static inline void +list_add(struct list_head *entry, struct list_head *head) +{ + __list_add(entry, head, head->next); +} + +/** + * Append a new element to the end of the list given with this list head. + * + * The list changes from: + * head → some element → ... → lastelement + * to + * head → some element → ... → lastelement → new element + * + * Example: + * struct foo *newfoo = malloc(...); + * list_add_tail(&newfoo->entry, &bar->list_of_foos); + * + * @param entry The new element to prepend to the list. + * @param head The existing list. + */ +static inline void +list_add_tail(struct list_head *entry, struct list_head *head) +{ + __list_add(entry, head->prev, head); +} + +static inline void +__list_del(struct list_head *prev, struct list_head *next) +{ + next->prev = prev; + prev->next = next; +} + +/** + * Remove the element from the list it is in. Using this function will reset + * the pointers to/from this element so it is removed from the list. It does + * NOT free the element itself or manipulate it otherwise. + * + * Using list_del on a pure list head (like in the example at the top of + * this file) will NOT remove the first element from + * the list but rather reset the list as empty list. + * + * Example: + * list_del(&foo->entry); + * + * @param entry The element to remove. + */ +static inline void +list_del(struct list_head *entry) +{ + __list_del(entry->prev, entry->next); +} + +static inline void +list_del_init(struct list_head *entry) +{ + __list_del(entry->prev, entry->next); + INIT_LIST_HEAD(entry); +} + +static inline void list_move_tail(struct list_head *list, + struct list_head *head) +{ + __list_del(list->prev, list->next); + list_add_tail(list, head); +} + +/** + * Check if the list is empty. + * + * Example: + * list_empty(&bar->list_of_foos); + * + * @return True if the list contains one or more elements or False otherwise. + */ +static inline int +list_empty(struct list_head *head) +{ + return head->next == head; +} + +/** + * Returns a pointer to the container of this list element. + * + * Example: + * struct foo* f; + * f = container_of(&foo->entry, struct foo, entry); + * assert(f == foo); + * + * @param ptr Pointer to the struct list_head. + * @param type Data type of the list element. + * @param member Member name of the struct list_head field in the list element. + * @return A pointer to the data struct containing the list head. + */ +#ifndef container_of +#define container_of(ptr, type, member) \ + (type *)((char *)(ptr) - (char *) &((type *)0)->member) +#endif + +/** + * Alias of container_of + */ +#define list_entry(ptr, type, member) \ + container_of(ptr, type, member) + +/** + * Retrieve the first list entry for the given list pointer. + * + * Example: + * struct foo *first; + * first = list_first_entry(&bar->list_of_foos, struct foo, list_of_foos); + * + * @param ptr The list head + * @param type Data type of the list element to retrieve + * @param member Member name of the struct list_head field in the list element. + * @return A pointer to the first list element. + */ +#define list_first_entry(ptr, type, member) \ + list_entry((ptr)->next, type, member) + +/** + * Retrieve the last list entry for the given listpointer. + * + * Example: + * struct foo *first; + * first = list_last_entry(&bar->list_of_foos, struct foo, list_of_foos); + * + * @param ptr The list head + * @param type Data type of the list element to retrieve + * @param member Member name of the struct list_head field in the list element. + * @return A pointer to the last list element. + */ +#define list_last_entry(ptr, type, member) \ + list_entry((ptr)->prev, type, member) + +#define __container_of(ptr, sample, member) \ + (void *)container_of((ptr), typeof(*(sample)), member) + +/** + * Loop through the list given by head and set pos to struct in the list. + * + * Example: + * struct foo *iterator; + * list_for_each_entry(iterator, &bar->list_of_foos, entry) { + * [modify iterator] + * } + * + * This macro is not safe for node deletion. Use list_for_each_entry_safe + * instead. + * + * @param pos Iterator variable of the type of the list elements. + * @param head List head + * @param member Member name of the struct list_head in the list elements. + * + */ +#define list_for_each_entry(pos, head, member) \ + for (pos = __container_of((head)->next, pos, member); \ + &pos->member != (head); \ + pos = __container_of(pos->member.next, pos, member)) + +/** + * Loop through the list, keeping a backup pointer to the element. This + * macro allows for the deletion of a list element while looping through the + * list. + * + * See list_for_each_entry for more details. + */ +#define list_for_each_entry_safe(pos, tmp, head, member) \ + for (pos = __container_of((head)->next, pos, member), \ + tmp = __container_of(pos->member.next, pos, member); \ + &pos->member != (head); \ + pos = tmp, tmp = __container_of(pos->member.next, tmp, member)) + + +#define list_for_each_entry_reverse(pos, head, member) \ + for (pos = __container_of((head)->prev, pos, member); \ + &pos->member != (head); \ + pos = __container_of(pos->member.prev, pos, member)) + +#define list_for_each_entry_continue(pos, head, member) \ + for (pos = __container_of(pos->member.next, pos, member); \ + &pos->member != (head); \ + pos = __container_of(pos->member.next, pos, member)) + +#define list_for_each_entry_continue_reverse(pos, head, member) \ + for (pos = __container_of(pos->member.prev, pos, member); \ + &pos->member != (head); \ + pos = __container_of(pos->member.prev, pos, member)) + +#define list_for_each_entry_from(pos, head, member) \ + for (; \ + &pos->member != (head); \ + pos = __container_of(pos->member.next, pos, member)) + +#endif diff --git a/driver/xrp-user/include/csi_dsp_api.h b/driver/xrp-user/include/csi_dsp_api.h new file mode 100644 index 0000000..423d8d1 --- /dev/null +++ b/driver/xrp-user/include/csi_dsp_api.h @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2021 Alibaba Group. All rights reserved. + * License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +/*! + * \file + * \brief This section defines CSI DSP API. + * + * General properties: + * 1. API Handler DSP TASK CREATE + * 2. API Handler DSP ALGO config + * 3. API + */ + +#ifndef _CSI_DSP_API_H +#define _CSI_DSP_API_H + +#include +#include +#include "csi_dsp_task_defs.h" +#ifdef __cplusplus +extern "C" { +#endif + + +/************* CPU interafce*********************************/ + +/** + * @description: * Open DSP device by index. + + * @param {int} dsp_id dsp index to create + * @return {*} pointer to the opened device or NULL in case of error + */ +void *csi_dsp_create_instance(int dsp_id); + +/** + * @description: Close DSP device by index. + * @param {void} *dsp ,dsp index to close + * @return {int} return 0 when delete success, not 0 in case of error + */ +int csi_dsp_delete_instance(void *dsp); + +/** + * @description: create an task on an instance + * Task have a dependece Algo + * for CSI_DSP_TASK_HW (CSI_DSP_TASK_SW_TO_HW|CSI_DSP_TASK_SW_TO_SW) + * both csi_dsp_task_config_frontend and csi_dsp_task_config_backend are needed to call + * for CSI_DSP_TASK_SW_TO_SW use task req to handle seperate process req on this task + * @param {void *} point to an dsp instance + * @param {csi_dsp_task_mode_e} task_type + * @return {*}pointer to the createrf task or NULL in case of error + */ +void *csi_dsp_create_task(void * instance,csi_dsp_task_mode_e task_type); + +/** + * @description: create a report handler on an instance + * @param {void*} point to an dsp instance + * @return {int} return 0 when create success, not 0 in case of error + */ +int csi_dsp_create_reporter(void* dsp); +/** + * @description: destroy a report handler on an instance + * @param {void} point to an dsp instance + * @return {int} return 0 when create success, not 0 in case of error + */ +int csi_dsp_destroy_reporter(void *dsp); +/** + * @description: destroy a task handler + * @param {void} *task, point to an task handler + * @return {int} return 0 when credestroy success, not 0 in case of error + */ +void csi_dsp_destroy_task(void *task); + +/** + * @description: config a task's frontend ,for SW Task + * @param {void} *task + * @param {csi_dsp_task_fe_para} *config_para + * @return {*} + */ +int csi_dsp_task_config_frontend(void *task,struct csi_dsp_task_fe_para *config_para); + +/** + * @description: + * @param {void} *task + * @param {csi_dsp_task_fe_para} *config_para + * @return {*} + */ +int csi_dsp_task_get_frontend(void *task,struct csi_dsp_task_fe_para *config_para); +/** + * @description: + * @param {void} *task + * @param {csi_dsp_task_be_para} *config_para + * @return {*} + */ +int csi_dsp_task_config_backend(void *task,struct csi_dsp_task_be_para *config_para); +/** + * @description: + * @param {void} *task + * @param {csi_dsp_task_be_para} *config_para + * @return {*} + */ +int csi_dsp_task_get_backend(void *task,struct csi_dsp_task_be_para *config_para); +/** + * @description: + * @param {void} *task + * @param {csi_dsp_algo_config_par} *config_para + * @return {*} + */ +int csi_dsp_task_config_algo(void *task,struct csi_dsp_algo_config_par *config_para); +/** + * @description: + * @param {void} *task_ctx + * @param {csi_dsp_algo_load_req_t*} config_para + * @return {*} + */ +int csi_dsp_task_load_algo(void *task_ctx, csi_dsp_algo_load_req_t* config_para); +/** + * @description: + * @param {void} *task_ctx + * @return {*} + */ +int csi_dsp_task_acquire_algo(void *task_ctx,char*name); +/** + * @description: + * @param {void} *task + * @return {*} + */ +int csi_dsp_task_start(void *task); +/** + * @description: + * @param {void} *task + * @return {*} + */ +int csi_dsp_task_stop(void *task); +/** + * @description: + * @param {void} *task + * @param { } int + * @param {void*} context + * @param {size_t} data_size + * @return {*} + */ +int csi_dsp_task_register_cb(void *task, + int (*cb)(void*context,void*data), + void* context, + size_t data_size); +/** + * @description: + * @param {void} *task + * @return {*} + */ +int csi_dsp_ps_task_unregister_cb(void *task); + +/** + * @description: + * @param {void} *task + * @return {*} + */ +struct csi_sw_task_req* csi_dsp_task_create_request(void *task); + +/** + * @description: + * @param {void *} task_ctx + * @param {csi_dsp_buffer *} buffer + * @return {*} + */ +int csi_dsp_task_create_buffer(void * task_ctx,struct csi_dsp_buffer * buffer); +/** + * @description: + * @param {void *} task_ctx + * @param {csi_dsp_buffer *} buffer + * @return {*} + */ +int csi_dsp_task_free_buffer(void * task_ctx,struct csi_dsp_buffer * buffer); +/** + * @description: + * @param {csi_sw_task_req*} req + * @param {csi_dsp_buffer *} buffer + * @return {*} + */ +int csi_dsp_request_add_buffer(struct csi_sw_task_req* req,struct csi_dsp_buffer * buffer); + +/** + * @description: + * @param {csi_sw_task_req*} req + * @param {void*} property + * @param {size_t} sz + * @return {*} + */ +int csi_dsp_request_set_property(struct csi_sw_task_req* req,void* property,size_t sz); + +/** + * @description: + * @param {csi_sw_task_req*} req + * @return {*} + */ +int csi_dsp_request_enqueue(struct csi_sw_task_req* req); +/** + * @description: + * @param {void} *task + * @return {*} + */ +struct csi_sw_task_req* csi_dsp_request_dequeue(void *task); + +/** + * @description: + * @param {csi_sw_task_req*} req + * @return {*} + */ +int csi_dsp_task_release_request(struct csi_sw_task_req* req); + + +int csi_dsp_task_update_backend_buf(void *task_ctx,struct csi_dsp_task_be_para* config_para); +int csi_dsp_test_config(void* dsp ,struct csi_dsp_ip_test_par* config_para,void* buf); +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/driver/xrp-user/include/csi_dsp_post_process_defs.h b/driver/xrp-user/include/csi_dsp_post_process_defs.h new file mode 100644 index 0000000..31481b0 --- /dev/null +++ b/driver/xrp-user/include/csi_dsp_post_process_defs.h @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2021 Alibaba Group. All rights reserved. + * License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +/*! + * \file + * \brief This section defines DSP shared strcut for CPU&DSP&APP. + * + * General properties: + * 1. Post porcess define data and strcut, visiable for APP + * 2. user define data shared bedtween DSP ans host + */ + +#ifndef _CSI_DSP_POST_DEFS_H +#define _CSI_DSP_POST_DEFS_H + +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif +#define CSI_DSP_MAX_BUFFER 8 +typedef uint8_t dsp_id_t; + + + +typedef enum csi_dsp_img_fmt{ + CSI_DSP_IMG_FMT_RAW8 =0, + CSI_DSP_IMG_FMT_RAW10_UNALGIN, + CSI_DSP_IMG_FMT_RAW10_ALGIN, + CSI_DSP_IMG_FMT_RAW12_UNALGIN, + CSI_DSP_IMG_FMT_RAW12_ALGIN, + CSI_DSP_IMG_FMT_RAW16_UNALGIN, + CSI_DSP_IMG_FMT_RAW16_ALGIN, + CSI_DSP_IMG_FMT_NV12, + CSI_DSP_IMG_FMT_NV21, + CSI_DSP_IMG_FMT_I420, /* 420 3P Y/U/V */ + CSI_DSP_IMG_FMT_YV12, /* 420 3P Y/V/U */ + CSI_DSP_IMG_FMT_YUY2, /* 422 1P YUYV */ + CSI_DSP_IMG_FMT_YVYU, /* 422 1P YVYU */ + CSI_DSP_IMG_FMT_YV16, /* 422 3P Y/V/U */ + CSI_DSP_IMG_FMT_Y, /* Y only */ + CSI_DSP_IMG_FMT_420_CHROME, /* u or v only */ + CSI_DSP_IMG_FMT_422_CHROME, /* u or v only */ + CSI_DSP_IMG_FMT_420_UV_IL, /* uv interleave*/ + CSI_DSP_IMG_FMT_422_UV_IL, /* uv interleave*/ + CSI_DSP_IMG_FMT_INVALID, + + +} csi_dsp_img_fmt_e; + +enum buffer_property{ + CSI_DSP_BUFFER_IN, + CSI_DSP_BUFFER_OUT, + CSI_DSP_BUFFER_IN_OUT, + +}; + +struct csi_dsp_plane { + + int fd; + uint32_t stride; /* if buffer type is image */ + uint32_t size; + uint64_t buf_phy; + uint64_t buf_vir; +}; + +typedef enum csi_dsp_buf_type { + CSI_DSP_BUF_TYPE_DMA_BUF_IMPORT, // memory allocated via dma-buf from extern + CSI_DSP_BUF_TYPE_DMA_BUF_EXPORT, // memory allocated via dma-buf from internal + CSI_DSP_BUF_ALLOC_APP, // memory allocated via APP malloc + CSI_DSP_BUF_ALLOC_DRV, // memory allocated via DSP Drvier + CSI_DSP_BUF_ALLOC_FM, // memory will auto acquire by DSP FM +} csi_dsp_buf_type_e; + +struct csi_dsp_buffer { + dsp_id_t buf_id; + enum buffer_property dir; + csi_dsp_buf_type_e type; + uint8_t format; + uint8_t plane_count; + uint32_t width; + uint32_t height; + struct csi_dsp_plane planes[3]; +}; + struct csi_dsp_algo_config_par{ + int16_t algo_id; + int task_id; + uint64_t algo_ptr; + uint64_t sett_ptr; + uint32_t sett_length; + uint64_t bufs_ptr; + uint32_t buf_num; + uint32_t algo_size; + +}; +typedef enum csi_dsp_sw_req_status { + CSI_DSP_SW_REQ_IDLE, + CSI_DSP_SW_REQ_RUNNING, + CSI_DSP_SW_REQ_FAIL, + CSI_DSP_SW_REQ_DONE, +} csi_dsp_sw_req_status_e; + +struct csi_sw_task_req{ + + uint16_t algo_id; + uint16_t request_id; + uint16_t buffer_num; + csi_dsp_sw_req_status_e status; + uint32_t sett_length; + uint64_t sett_ptr; + struct csi_dsp_buffer buffers[CSI_DSP_MAX_BUFFER]; + void *task; + void* priv; +}; + + +typedef enum csi_dsp_algo_lib_id{ + CSI_DSP_ALGO_LIB_COPY, + CSI_DSP_ALGO_LIB_0, + CSI_DSP_ALGO_LIB_1, + +}csi_dsp_algo_lib_id_e; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/driver/xrp-user/include/csi_dsp_task_defs.h b/driver/xrp-user/include/csi_dsp_task_defs.h new file mode 100644 index 0000000..d495a3e --- /dev/null +++ b/driver/xrp-user/include/csi_dsp_task_defs.h @@ -0,0 +1,229 @@ +/* + * Copyright (c) 2021 Alibaba Group. All rights reserved. + * License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +/*! + * \file + * \brief This section defines DSP shared strcut for CPU&DSP&APP. + * + * General properties: + * 1. Post porcess define data and strcut, visiable for APP + * 2. user define data shared bedtween DSP ans host + */ + +#ifndef _CSI_DSP_TASK_DEFS_H +#define _CSI_DSP_TASK_DEFS_H + +#include +#include +#include "csi_dsp_post_process_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define MAX_REPORT_SIZE 256 + +#define CSI_DSP_HW_TASK_EXTRA_BUF_START_INDEX 2 +typedef struct { + uint16_t id; + uint16_t hor; + uint16_t ver; + uint16_t data_fmt; + uint16_t line_in_entry; + uint16_t line_stride; + uint32_t buffer_size; + uint64_t buffer_addr; +}sisp_config_par; + +typedef sisp_config_par spost_isp_config_par; +// typedef sisp_config_par svipre_config_par; +typedef struct vipre_config_par{ + uint8_t id; + uint8_t act_channel; + uint8_t data_fmt; + uint8_t buffer_num; + uint16_t line_num; + uint16_t hor; + uint16_t ver; + uint16_t line_stride; + uint32_t buffer_size; + uint64_t buffer_addr[12]; +}vipre_config_par_t; + +typedef struct { + uint16_t algo_id; + float gamma; // float鍙傛暟 + float coef1; + float coef2; + float coef3; + float coef4; + short beta; // short鍨嬪弬鏁� + short beta1; + short beta2; + short beta3; + short beta4; +}salgo_config_par; + + +typedef enum{ + CSI_DSP_REPORT_NORMAL, + CSI_DSP_REPORT_RESULT, + CSI_DSP_REPORT_RESULT_WITH_EXRA_PARAM, + CSI_DSP_REPORT_ALGO_ERR, + CSI_DSP_REPORT_PS_ERR, + CSI_DSP_REPORT_ISP_ERR, + CSI_DSP_REPORT_RY_ERR, + CSI_DSP_REPORT_VI_PRE_ERR, + CSI_DSP_REPORT_NO_BUF, + CSI_DSP_REPORT_HEARTBEAT_ERR, + CSI_DSP_HW_FRAME_DROP, + CSI_DSP_REPORT_EXRA_PARAM, +}csi_dsp_report_e; + +typedef struct dsp_frame{ + uint64_t p_frame_buff[3]; + uint32_t frame_buff_size[3]; + int32_t frame_width; + int32_t frame_height; + int32_t frame_pitch; + uint8_t pixel_res; + uint8_t num_channels; + int8_t fmt; +}dsp_frame_t; + + + +typedef enum csi_dsp_task_mode{ + CSI_DSP_TASK_SW_TO_SW =0x1<<0, /*SW Queue to handle in / data/exception */ + CSI_DSP_TASK_SW_TO_HW =0x1<<1, /*SW Queue to handle in and exception / Report handlere exception,HW handl out*/ + CSI_DSP_TASK_HW_TO_SW =0x1<<2, /* HW send handle in, Report handler out and exception*/ + CSI_DSP_TASK_HW_TO_HW =0x01<<3, /* Hw handler in&out Report handler exception*/ + CSI_DSP_TASK_SW = (CSI_DSP_TASK_SW_TO_HW|CSI_DSP_TASK_SW_TO_SW), + CSI_DSP_TASK_HW = (CSI_DSP_TASK_HW_TO_SW|CSI_DSP_TASK_HW_TO_HW), +}csi_dsp_task_mode_e; + +//#define CSI_DSP_TASK_SW (CSI_DSP_TASK_SW_TO_HW|CSI_DSP_TASK_SW_TO_SW) +//#define CSI_DSP_TASK_HW (CSI_DSP_TASK_HW_TO_SW|CSI_DSP_TASK_HW_TO_HW) + +typedef enum csi_dsp_status{ + CSI_DSP_ERR_ILLEGAL_PARAM = -100, + CSI_DSP_TASK_NOT_VALID, + CSI_DSP_TASK_ALLOC_FAIL, + CSI_DSP_TASK_ADD_TO_SCHEDULER_FAIL, + CSI_DSP_TASK_ALREADY_RUNNING, + CSI_DSP_TASK_START_FAIL, + CSI_DSP_REPORTER_NOT_INIT, + CSI_DSP_FE_NOT_VALID, + CSI_DSP_FE_CONFIG_FAIL, + CSI_DSP_BE_CONFIG_FAIL, + CSI_DSP_BE_NOT_VALID, + CSI_DSP_ALGO_INVALID, + CSI_DSP_ALGO_ERR, + CSI_DSP_FE_ERR, + CSI_DSP_BE_ERR, + CSI_DSP_BUF_TYPE_ERR, + CSI_DSP_ALGO_LOAD_FAIL, + CSI_DSP_MALLO_FAIL, + CSI_DSP_ALGO_BUF_FAIL, + CSI_DSP_FAIL, + CSI_DSP_OK = 0, +}csi_dsp_status_e; + +struct csi_dsp_task_create_req{ + csi_dsp_task_mode_e type; + int priority; +}; + + + +struct csi_dsp_task_comm_resp{ + csi_dsp_status_e status; +}; +enum csi_dsp_fe_type{ + CSI_DSP_FE_TYPE_CPU, + CSI_DSP_FE_TYPE_ISP, + CSI_DSP_FE_TYPE_VIPRE, + CSI_DSP_FE_TYPE_INVALID, +}; + +enum csi_dsp_be_type{ + CSI_DSP_BE_TYPE_HOST, + CSI_DSP_BE_TYPE_POST_ISP, + CSI_DSP_BE_TYPE_INVALID, +}; + +enum csi_dsp_task_cfg{ + CSI_DSP_TASK_IDLE, + CSI_DSP_TASK_START, + CSI_DSP_TASK_STOP, + +}; + +struct csi_dsp_task_fe_para{ + enum csi_dsp_fe_type frontend_type; + int task_id; + union{ + sisp_config_par isp_param; + vipre_config_par_t vipre_param; + }; +}; +typedef struct _sw_be_config_par{ + int num_buf; + struct csi_dsp_buffer bufs[1]; + +}sw_be_config_par; + +struct csi_dsp_task_be_para{ + enum csi_dsp_be_type backend_type; + int task_id; + union{ + sisp_config_par post_isp_param; + sw_be_config_par sw_param; + }; + +}; + +typedef struct csi_dsp_report_item{ + csi_dsp_report_e type; + union{ + char data[MAX_REPORT_SIZE]; + struct csi_dsp_buffer buf; + }; +}csi_dsp_report_item_t; + +typedef struct csi_dsp_algo_load_req{ + uint16_t algo_id; + int task_id; + uint64_t algo_ptr; +}csi_dsp_algo_load_req_t; + +typedef struct csi_dsp_algo_load_resp{ + csi_dsp_status_e status; + uint16_t algo_id; + uint16_t buf_desc_num; + uint16_t info_prop_des_num; + uint16_t set_prop_des_num; +}csi_dsp_algo_load_resp_t; + + +void isp_algo_result_handler(void *context,void *data); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/driver/xrp-user/include/dsp_common.h b/driver/xrp-user/include/dsp_common.h new file mode 100644 index 0000000..29a3079 --- /dev/null +++ b/driver/xrp-user/include/dsp_common.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2022 Alibaba Group. All rights reserved. + * License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef _DSP_COMMON_H_ +#define _DSP_COMMON_H_ + +#include +#include +#include +#include + + +#define DSP_MIN(a, b) ((a) < (b) ? (a) : (b)) +#define DSP_MAX(a, b) ((a) > (b) ? (a) : (b)) +#define DSP_ALIGN_UP(num, bits) (((num) + (1 << (bits)) - 1) & ~((1 << (bits)) - 1)) + +#define DSP_ZERO_MEMORY(data) \ + { \ + memset(data, 0, sizeof(*(data))); \ + } + +#define DSP_MEMCPY(dst, src, size) \ + { \ + memcpy(dst, src, size); \ + } + +#define DSP_SAFE_FREE(buf) \ + { \ + if (buf != NULL) \ + { \ + free(buf); \ + buf = NULL; \ + } \ + } + +#define DSP_PRINT(level, ...) \ + { \ + if (log_level >= CSI_DSP_LOG_##level) \ + { \ + printf("CSI_DSP[%d] %s,(%s,%d): ", pid, #level,__FUNCTION__,__LINE__); \ + printf(__VA_ARGS__); \ + } \ + } + +#define DSP_PRINT_RETURN(retcode, level, ...) \ + { \ + DSP_PRINT(level, __VA_ARGS__) \ + return retcode; \ + } + +#define DSP_CHECK_CONDITION(cond, retcode, ...) \ + if (cond) \ + { \ + DSP_PRINT(ERROR, __VA_ARGS__) \ + return retcode; \ + } + + + +typedef enum log_level +{ + CSI_DSP_LOG_QUIET = 0, + CSI_DSP_LOG_ERROR, + CSI_DSP_LOG_WARNING, + CSI_DSP_LOG_INFO, + CSI_DSP_LOG_DEBUG, + CSI_DSP_LOG_TRACE, + CSI_DSP_LOG_MAX +} csi_dsp_log_level; + +extern int log_level; +extern int pid; + +void dsp_InitEnv(); + +#endif \ No newline at end of file diff --git a/driver/xrp-user/include/dsp_ps_ns.h b/driver/xrp-user/include/dsp_ps_ns.h new file mode 100644 index 0000000..57d3fc6 --- /dev/null +++ b/driver/xrp-user/include/dsp_ps_ns.h @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2021 Alibaba Group. All rights reserved. + * License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +/*! + * \file + * \brief This section defines DSP and host shared data and strcut. + * + * General properties: + * 1. Define the common shared struct for both DSP and Host + * 2. The shared strcut only visible internal, for those open to APP shou be define in dsp_post_process_defs + */ + +#ifndef _DSP_PS_NS_H +#define _DSP_PS_NS_H + +#include + +#include "xrp_api.h" +#include "csi_dsp_task_defs.h" +#ifdef __cplusplus +extern "C" { +#endif +// enum { +// PS_CMD_IDLE = 0, +// PS_CMD_INLINE_START =PS_CMD_IDLE, +// PS_CMD_LOOPBACK_TEST, +// PS_CMD_ISP_CONFIG, +// PS_CMD_RY_CONFIG, +// PS_CMD_ISP_ALGO_CONFIG, +// PS_CMD_QUERY_DRAM_SIZE, +// PS_CMD_SET_IO_BUFFER, +// PS_CMD_WITH_BUFFER_START, +// }; + +#define TASK_NAME_LINE XRP_NAMESPACE_ID_SIZE +#define XRP_PS_NSID_COMMON_CMD \ + {0xf9, 0x3c, 0x09, 0x61, 0x9d, 0x3f, 0x45, 0x29, \ + 0xbd, 0xe9, 0x7a, 0x4b, 0x18, 0x91, 0xdb, 0x15} + + +#define XRP_PS_NSID_ISP_ALGO \ + {0xf9, 0x3c, 0x09, 0x61, 0x9d, 0x3f, 0x45, 0x29, \ + 0xbd, 0xe9, 0x7a, 0x4b, 0x18, 0x91, 0xdb, 0x14} + +typedef struct { + uint32_t cmd; + uint32_t data[1]; +}s_cmd_t; +typedef enum { + PS_CMD_IDLE = 0, + PS_CMD_INLINE_START =PS_CMD_IDLE, + PS_CMD_TASK_ALLOC, + PS_CMD_TASK_FREE, + PS_CMD_LOOPBACK_TEST, + PS_CMD_REPORT_CONFIG, + PS_CMD_LOG_CONFIG, + PS_CMD_HEART_BEAT_REQ, + PS_CMD_LOAD_MINITOR_REQ, + PS_CMD_FE_CONFIG, + PS_CMD_BE_CONFIG, + + PS_CMD_ALGO_CONFIG, + PS_CMD_TASK_START, + + PS_CMD_TASK_STOP, + + PS_CMD_DATA_MOVE, + + PS_CMD_DSP_IP_TEST, + PS_CMD_BE_ASSGIN_BUF, + PS_CMD_ALGO_LOAD, +}ECOMMON_CMD; + +enum cmd_type{ + CMD_SETUP, + CMD_RELEASE, + CMD_INVALID, +}; + +struct report_config_msg{ + enum cmd_type flag; + int32_t report_id; + char task[TASK_NAME_LINE]; + uint32_t size; + uint64_t addr; +}; + +struct data_move_msg{ + uint64_t src_addr; + uint64_t dst_addr; + uint32_t size; +}; + +struct csi_dsp_task_start_req{ + int task_id; + char task_ns[TASK_NAME_LINE]; +}; + +struct csi_dsp_task_create_resp{ + + csi_dsp_status_e status; + char task_ns[TASK_NAME_LINE]; + int task_id; + +}; + +struct csi_dsp_task_free_req{ + int task_id; + char task_ns[TASK_NAME_LINE]; +}; + +struct csi_dsp_ip_test_par{ + char case_name[32]; + char case_goup[32]; + int result_buf_size; +}; + +// struct csi_dsp_algo_config_par{ +// uint16_t algo_id; +// char* algo; +// union +// { +// float gam_coef[4]; +// short beta_coef[4]; +// }; +// }; +#ifdef __cplusplus +} +#endif +#endif diff --git a/driver/xrp-user/include/xrp_api.h b/driver/xrp-user/include/xrp_api.h new file mode 100644 index 0000000..c7d04e6 --- /dev/null +++ b/driver/xrp-user/include/xrp_api.h @@ -0,0 +1,612 @@ +/* + * Copyright (c) 2016 - 2017 Cadence Design Systems Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/*! + * \file xrp_api.h + * \brief This section defines XRP API. + * + * General API properties: + * - All status pointers can be NULL. + * - Reference counting is not meant to work across host/DSP boundary, i.e. + * DSP may not retain the host buffer. + * - A buffer allocated for one device can be passed as command parameter to + * a different device; implementation should do reasonable thing, e.g. use + * the original data if possible or transparently migrate it to suitable + * memory. + * - A group of API calls may be host side only, DSP side only, or usable on + * both sides. When it's usable on both sides there may be additional + * restrictions on the DSP side. + */ + +#ifndef _XRP_API_H +#define _XRP_API_H + +#include +#include +#ifdef __cplusplus +extern "C" { +#endif + +/* + * User API. + */ + +struct xrp_device; +struct xrp_queue; +struct xrp_buffer; +struct xrp_buffer_group; +struct xrp_event; + +struct xrp_report; +/*! + * Status codes of XRP calls. + */ +enum xrp_status { + /*! Call completed successfully. */ + XRP_STATUS_SUCCESS, + /*! Call failed. */ + XRP_STATUS_FAILURE, + /*! Call has not completed. */ + XRP_STATUS_PENDING, +}; +enum xrp_access_flags { + XRP_READ = 0x1, + XRP_WRITE = 0x2, + XRP_READ_WRITE = 0x3, +}; + +/*! + * Types of information that may be queried for a buffer object. + */ +enum xrp_buffer_info { + /*! Size of the buffer. */ + XRP_BUFFER_SIZE_SIZE_T, + /*! Host pointer of the buffer. */ + XRP_BUFFER_HOST_POINTER_PTR, + + XRP_BUFFER_PHY_ADDR, + + XRP_BUFFER_USER_ADDR, +}; + +/*! + * Types of information that may be queried for a buffer group object. + */ +enum xrp_buffer_group_info { + /*! Access flags associated with a buffer. Requires buffer index. */ + XRP_BUFFER_GROUP_BUFFER_FLAGS_ENUM, + /*! Number of buffers in the buffer group. Buffer index is ignored. */ + XRP_BUFFER_GROUP_SIZE_SIZE_T, +}; + +#define XRP_NAMESPACE_ID_SIZE 16 + +/*! + * \defgroup device_api Device API + * These calls are available on the host side and on the DSP side with the + * following restriction: + * - only device 0 may be opened. + * @{ + */ + +/*! + * Open device by index. + * A device is reference counted and is opened with reference count of 1. + * Devices are numbered sequentially starting at 0, they can be probed with + * simple loop. + * \param idx: device index to open + * \param[out] status: operation status + * \return pointer to the opened device or NULL in case of error + */ +struct xrp_device *xrp_open_device(int idx, enum xrp_status *status); + +/*! + * Increment device reference count. + */ +void xrp_retain_device(struct xrp_device *device); + +/*! + * Decrement device reference count (and free associated resources once the + * counter gets down to zero). + */ +void xrp_release_device(struct xrp_device *device); + +/*! + * @} + */ + +/*! + * \defgroup buffer_api Buffer API + * These calls are available on the host side and on the DSP side with the + * following restriction: + * - buffers may not be created on the DSP side. + * @{ + */ + +/*! + * Create memory buffer and allocate device-specific storage (host_ptr == NULL) + * or use host buffer (host_ptr != NULL, treated as virtual address in the + * current process). + * A buffer is reference counted and is created with reference count of 1. + * \param[out] status: operation status + */ +struct xrp_buffer *xrp_create_buffer(struct xrp_device *device, + size_t size, void *host_ptr, + enum xrp_status *status); + +/*! + * Increment buffer reference count. + */ +void xrp_retain_buffer(struct xrp_buffer *buffer); + +/*! + * Decrement buffer reference count (and free the storage if it was allocated + * once the counter gets down to zero). + */ +void xrp_release_buffer(struct xrp_buffer *buffer); + +/*! + * Map subbuffer of the buffer. Buffer may be mapped multiple times. + * + * \param map_flags: access to the mapping requested by the mapper. Access + * to buffers on DSP side is subject to restrictions set by the host side. + * \param[out] status: operation status + */ +void *xrp_map_buffer(struct xrp_buffer *buffer, size_t offset, size_t size, + enum xrp_access_flags map_flags, enum xrp_status *status); + +/*! + * Unmap previously mapped buffer. + * \param[out] status: operation status + */ +void xrp_unmap_buffer(struct xrp_buffer *buffer, void *p, + enum xrp_status *status); + +/*! + * Get information about the buffer object. + * + * \param info: information type to retrieve. + * \param[out] out: pointer to return information to. + * \param out_sz: size of out buffer. + * \param[out] status: operation status + */ +void xrp_buffer_get_info(struct xrp_buffer *buffer, enum xrp_buffer_info info, + void *out, size_t out_sz, enum xrp_status *status); + +/*! + * @} + */ + +/*! + * \defgroup buffer_group_api Buffer Group API + * These calls are available on the host side and on the DSP side with the + * following restrictions: + * - buffer groups may not be created on the DSP side; + * - existing buffer groups may not be modified on the DSP side. + * @{ + */ + +/*! + * Create a group of shared buffers. Group is reference counted and is + * created with reference count of 1. + * \param[out] status: operation status + */ +struct xrp_buffer_group *xrp_create_buffer_group(enum xrp_status *status); + +/*! + * Increment buffer group reference count. + */ +void xrp_retain_buffer_group(struct xrp_buffer_group *group); + +/*! + * Decrement group reference count (and free it once the counter gets down + * to zero). + */ +void xrp_release_buffer_group(struct xrp_buffer_group *group); + +/*! + * Add buffer to the group and get its index. + * This adds a reference to the buffer. + * + * \param access_flags: granted access. User of the buffer on the DSP side + * will be able to map it only for this type of access. + * \param[out] status: operation status + */ +size_t xrp_add_buffer_to_group(struct xrp_buffer_group *group, + struct xrp_buffer *buffer, + enum xrp_access_flags access_flags, + enum xrp_status *status); + +/*! + * Put new buffer to the existing index in the group. + * When operation succeeds it releases the buffer previously contained at + * that index and adds a reference to the new buffer. + * + * \param access_flags: granted access. User of the buffer on the DSP side + * will be able to map it only for this type of access. + * \param[out] status: operation status + */ +void xrp_set_buffer_in_group(struct xrp_buffer_group *group, + size_t index, + struct xrp_buffer *buffer, + enum xrp_access_flags access_flags, + enum xrp_status *status); + +/*! + * Get buffer from the group by its index. + * Buffer must be freed with release_buffer. + * \param[out] status: operation status + */ +struct xrp_buffer *xrp_get_buffer_from_group(struct xrp_buffer_group *group, + size_t idx, + enum xrp_status *status); + +/*! + * Get information about the buffer group object. + * + * \param info: information type to retrieve. + * \param idx: buffer index (if applicable). + * \param[out] out: pointer to return information to. + * \param out_sz: size of out buffer. + * \param[out] status: operation status + */ +void xrp_buffer_group_get_info(struct xrp_buffer_group *group, + enum xrp_buffer_group_info info, size_t idx, + void *out, size_t out_sz, + enum xrp_status *status); + +/*! + * @} + */ + +/*! + * \defgroup queue_api Queue API + * These calls are available only on the host side. + * @{ + */ + +/*! + * Create queue to the default namespace of the device. + * Queue is an ordered device communication channel. Queue is reference + * counted and is created with reference count of 1. + * \param[out] status: operation status + */ +struct xrp_queue *xrp_create_queue(struct xrp_device *device, + enum xrp_status *status); + +/*! + * Create queue to the specified namespace of the device. + * Queue is an ordered device communication channel. Queue is reference + * counted and is created with reference count of 1. + * \param[out] status: operation status + */ +struct xrp_queue *xrp_create_ns_queue(struct xrp_device *device, + const void *nsid, + enum xrp_status *status); + +/*! + * Create queue to the specified namespace of the device with specific + * priority. + * Queue is an ordered device communication channel. Queue is reference + * counted and is created with reference count of 1. + * \param[out] status: operation status + */ +struct xrp_queue *xrp_create_nsp_queue(struct xrp_device *device, + const void *nsid, + int priority, + enum xrp_status *status); + +/*! + * Increment queue reference count. + */ +void xrp_retain_queue(struct xrp_queue *queue); + +/*! + * Decrement queue reference count (and free it once the counter gets down + * to zero). + */ +void xrp_release_queue(struct xrp_queue *queue); + +/*! + * @} + */ + +/*! + * \defgroup event_api Event API + * These calls are available only on the host side. + * @{ + */ + +/*! + * Increment event reference count. + */ +void xrp_retain_event(struct xrp_event *event); + +/*! + * Decrement event reference count (and free it once the counter gets down + * to zero). + */ +void xrp_release_event(struct xrp_event *event); + + +/*! + * Get status of the event/associated command. + * The function may be called at any time, it sets *status to + * XRP_STATUS_PENDING if the command has not been executed yet, or to the + * command execution status. See status description of xrp_run_command_sync() + * for the description of command execution status. + * \param[out] status: operation status + */ +void xrp_event_status(struct xrp_event *event, enum xrp_status *status); + +/*! + * @} + */ + +/*! + * \defgroup communication_api Communication API + * These calls are available only on the host side. + * @{ + */ + +/* + * Even more internal API related to command passing between cores. + * These are tightly coupled to the host-DSP communication model and + * are likely to be changed/enhanced as the model evolves. + */ + +/*! + * Synchronously send command from host to DSP. + * + * When this is invoked on the host it synchronously runs a command on DSP, + * passing a group of shared buffers and two additional (small) buffers + * with opaque command description (in_data) and results (out_data). + * + * in_data is used at the function call and is not referenced afterwards. + * out_data is updated with the value returned by DSP before the function + * returns. + * + * Optimal processing is guaranteed for in_data and out_data buffers not + * exceeding 16 bytes in size. Larger buffers may require additional data + * copying depending on the implementation. + * + * status is the result of command execution. Command execution is + * successful if the command was delivered to the DSP and the response was + * delivered back. Otherwise the command execution has failed. IOW execution + * success means that the out_data contains command-specific response received + * from the DSP, execution failure means that out_data does not contain useful + * information. + * + * \param[out] status: operation status + */ +void xrp_run_command_sync(struct xrp_queue *queue, + const void *in_data, size_t in_data_size, + void *out_data, size_t out_data_size, + struct xrp_buffer_group *buffer_group, + enum xrp_status *status); + +/*! + * Asynchronously send command from host to DSP. + * + * When this is invoked on the host it queues a command to DSP, + * passing a group of shared buffers and two additional (small) buffers + * with opaque command description (in_data) and results (out_data). + * + * in_data is used at the function call and is not referenced afterwards. + * out_data must stay valid after this function call until command completion, + * at which point it is updated with the value returned by DSP. + * + * Optimal processing is guaranteed for in_data and out_data buffers not + * exceeding 16 bytes in size. Larger buffers may require additional data + * copying depending on the implementation. + * + * If event is non-NULL then a pointer to an event corresponding to the + * queued command is returned. This event can be waited for with xrp_wait, + * it is signaled when the command execution is complete. + * The returned event object is reference counted and is created with + * reference count of 1. + * + * status is the result of command enqueuing. Command enqueuing is + * successful if the command was enqueued on the host side and an associated + * event has been returned (if requested). Otherwise the command enqueuing has + * failed. IOW enqueuing success means that if event is non-NULL then *event + * contains valid event, enqueuing failure means that *event does not contain + * useful information. + * + * \param[out] status: operation status + */ +void xrp_enqueue_command(struct xrp_queue *queue, + const void *in_data, size_t in_data_size, + void *out_data, size_t out_data_size, + struct xrp_buffer_group *buffer_group, + struct xrp_event **event, + enum xrp_status *status); + +/*! + * Wait for the event. + * Waiting for already signaled event completes immediately. + * Successful completion of this function does not alter the event state, + * i.e. the event remains signaled. + * status is the result of waiting, not the result of the command execution. + * Use xrp_event_status() to get the command execution status. + * \param[out] status: operation status + */ +void xrp_wait(struct xrp_event *event, enum xrp_status *status); + +/*! + * Wait for any event in the group. + * Waiting for a group with already signaled event completes immediately. + * Successful completion of this function does not alter the event state, + * i.e. signaled events remain signaled. + * status is the result of waiting, not the result of the command execution. + * Use xrp_event_status() with individual events to get the corresponding + * command execution status. + * + * \param[in] event: an array of pointers to events to wait for + * \param[i] n_events: number of events in the events array + * \param[out] status: operation status + * \return index of a completed event in the event array + */ +size_t xrp_wait_any(struct xrp_event **event, size_t n_events, + enum xrp_status *status); + +int xrp_add_report_item_with_id(struct xrp_report *report, + int (*cb)(void*context,void*data), + int report_id, + void* context, + size_t data_size); + +int xrp_add_report_item(struct xrp_report *report, + int (*cb)(void*context,void*data), + void* context, + size_t data_size); + +void xrp_remove_report_item(struct xrp_report *report,int report_id); + +struct xrp_report *xrp_create_reporter(struct xrp_device *device,size_t size); + +int xrp_release_reporter(struct xrp_device *device,struct xrp_report *report); + +void xrp_import_dma_buf(struct xrp_device *device, int fd,enum xrp_access_flags flag ,uint64_t *phy_addr, + uint64_t *user_addr,size_t* size,enum xrp_status *status); + +void xrp_release_dma_buf(struct xrp_device *device, int fd,enum xrp_status *status); + +void xrp_flush_dma_buf(struct xrp_device *device, int fd,enum xrp_access_flags flag ,enum xrp_status *status); +/*! + * @} + */ + +/*! + * \defgroup dsp_specific_api DSP-specific Interface (Library-Style) + * These calls are available only on the DSP side. + * @{ + */ + +/*! + * Check if there's a command from the host in the hardware queue. + * Returns XRP_STATUS_PENDING if the queue is empty or XRP_STATUS_SUCCESS + * if there is a command ready for processing. + * + * The check is quick and may be issued in any context. + */ +enum xrp_status xrp_device_poll(struct xrp_device *device); + +/*! + * Check if there's a command from the host in the hardware queue and invoke + * command handler if there's one. + * Returns XRP_STATUS_PENDING if the queue is empty, or the status returned by + * the command handler. + */ +enum xrp_status xrp_device_dispatch(struct xrp_device *device); + +/*! + * Function type for command handler. + * + * This callback is called on the DSP side to process queued command. + * in_data, out_data and buffer_group correspond to the same parameters of the + * host side API calls. + * + * On return from this function buffer group and individual buffer reference + * counters shall be restored to their entry values. out_data buffer shall be + * updated with command return value. + * Neither in_data nor out_data may be referenced after this function returns. + * + * Return value shall describe whether xrp_command_handler itself was + * successful or not, not the command it was requested to run. + * I.e. if the command was not recognized or its handler could not be called + * due to insufficient memory, that's XRP_STATUS_FAILURE returned in status. + * The host will also receive XRP_STATUS_FAILURE as a completion status. + * If the command was run that's XRP_STATUS_SUCCESS regardless of the + * command-specific status, which should be returned in out_data. + * + * \param handler_context: context that was passed to the + * xrp_device_register_namespace + */ +typedef enum xrp_status +(xrp_command_handler)(void *handler_context, + const void *in_data, size_t in_data_size, + void *out_data, size_t out_data_size, + struct xrp_buffer_group *buffer_group); + +/*! + * Register namespace handler. + * + * There may be only one handler for a namespace, second attempt to register + * a handler for the same namespace will fail. + * + * \param device: device for which namespace handler is registered + * \param nsid: namespace identifier, XRP_NAMESPACE_ID_SIZE bytes long + * \param handler: pointer to the handler function + * \param handler_context: first argument that will be passed to the handler + * function + * \param[out] status: operation status + */ +void xrp_device_register_namespace(struct xrp_device *device, + const void *nsid, + xrp_command_handler *handler, + void *handler_context, + enum xrp_status *status); + +/*! + * Unregister namespace handler. + * + * Only registered namespace handler may be unregistered. + * + * \param device: device for which namespace handler is registered + * \param nsid: namespace identifier, XRP_NAMESPACE_ID_SIZE bytes long + * \param[out] status: operation status + */ +void xrp_device_unregister_namespace(struct xrp_device *device, + const void *nsid, + enum xrp_status *status); + +/*! + * Enable or disable shared memory cache management. + * Note that this call does not change memory caching attributes, it only + * enables flushing and invalidating used regions of shared memory in the + * XRP code. + * + * \param device: device for which shared memory cache management state is + * changed + * \param enable: whether cache management shall be enabled (non-zero) or + * disabled (0) + */ +void xrp_device_enable_cache(struct xrp_device *device, int enable); + +/*! + * @} + */ + +/*! + * Helper function that terminates fast simulation. + */ +void xrp_exit(void); + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/driver/xrp-user/xrp-common/.deps/.dirstamp b/driver/xrp-user/xrp-common/.deps/.dirstamp new file mode 100644 index 0000000..e69de29 diff --git a/driver/xrp-user/xrp-common/.deps/libxrp_host_single_a-xrp_ns.Po b/driver/xrp-user/xrp-common/.deps/libxrp_host_single_a-xrp_ns.Po new file mode 100644 index 0000000..ff2ba37 --- /dev/null +++ b/driver/xrp-user/xrp-common/.deps/libxrp_host_single_a-xrp_ns.Po @@ -0,0 +1,50 @@ +../xrp-common/libxrp_host_single_a-xrp_ns.o: ../xrp-common/xrp_ns.c \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/inttypes.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stdint.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/yvals.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/yvals.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/config/core-isa.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/lib/xcc/include/stdarg.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stdlib.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/stdlib.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/alloca.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/string.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/string.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_scmpr.h \ + ../xrp-common/xrp_debug.h ../xrp-common/xrp_ns.h ../xrp_api.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stddef.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/stddef.h + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/inttypes.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stdint.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/yvals.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/yvals.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/config/core-isa.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/lib/xcc/include/stdarg.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stdlib.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/stdlib.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/alloca.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/string.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/string.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_scmpr.h: + +../xrp-common/xrp_debug.h: + +../xrp-common/xrp_ns.h: + +../xrp_api.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stddef.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/stddef.h: diff --git a/driver/xrp-user/xrp-common/.deps/xrp_ns.Po b/driver/xrp-user/xrp-common/.deps/xrp_ns.Po new file mode 100644 index 0000000..e824265 --- /dev/null +++ b/driver/xrp-user/xrp-common/.deps/xrp_ns.Po @@ -0,0 +1,50 @@ +xrp_ns.o: xrp_ns.c \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/inttypes.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stdint.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/yvals.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/yvals.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/config/core-isa.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/lib/xcc/include/stdarg.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stdlib.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/stdlib.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/alloca.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/string.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/string.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_scmpr.h \ + xrp_debug.h xrp_ns.h ../xrp_api.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stddef.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/stddef.h + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/inttypes.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stdint.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/yvals.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/yvals.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/config/core-isa.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/lib/xcc/include/stdarg.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stdlib.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/stdlib.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/alloca.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/string.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/string.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_scmpr.h: + +xrp_debug.h: + +xrp_ns.h: + +../xrp_api.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stddef.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/stddef.h: diff --git a/driver/xrp-user/xrp-common/.deps/xrp_rb_file.Po b/driver/xrp-user/xrp-common/.deps/xrp_rb_file.Po new file mode 100644 index 0000000..fac2622 --- /dev/null +++ b/driver/xrp-user/xrp-common/.deps/xrp_rb_file.Po @@ -0,0 +1,37 @@ +xrp_rb_file.o: xrp_rb_file.c \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/string.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/string.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/yvals.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/config/core-isa.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/lib/xcc/include/stdarg.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_scmpr.h \ + xrp_rb_file.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stddef.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/stddef.h \ + xrp_types.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stdint.h \ + ../xrp-kernel/xrp_ring_buffer.h + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/string.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/string.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/yvals.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/config/core-isa.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/lib/xcc/include/stdarg.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_scmpr.h: + +xrp_rb_file.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stddef.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/stddef.h: + +xrp_types.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stdint.h: + +../xrp-kernel/xrp_ring_buffer.h: diff --git a/driver/xrp-user/xrp-common/.dirstamp b/driver/xrp-user/xrp-common/.dirstamp new file mode 100644 index 0000000..e69de29 diff --git a/driver/xrp-user/xrp-common/Makefile b/driver/xrp-user/xrp-common/Makefile new file mode 100644 index 0000000..d8325bb --- /dev/null +++ b/driver/xrp-user/xrp-common/Makefile @@ -0,0 +1,39 @@ +## + # Copyright (C) 2021 Alibaba Group Holding Limited + # + # This program is free software; you can redistribute it and/or modify + # it under the terms of the GNU General Public License version 2 as + # published by the Free Software Foundation. +## + + +TARGET = libxrp-common.a + +CFLAGS = -O0 -Wall -g -lm +CFLAGS += -fPIC + + +xrp_SRCS += xrp_rb_file.c +xrp_SRCS += xrp_ns.c + +INCLUDES = -I$(CURDIR) -I../include -I../../xrp-kernel +# object files will be generated from .c sourcefiles +xrp_OBJS = $(notdir $(xrp_SRCS:.c=.o)) + +all: $(TARGET) + +$(xrp_OBJS): $(xrp_SRCS) + $(CC) -c $(CFLAGS) $(INCLUDES) $(xrp_SRCS) + + +$(TARGET): $(xrp_OBJS) + $(AR) -rc $(TARGET) $(xrp_OBJS) + +clean: + rm -f *.o *.a + rm -rf output + +install: + +.PHONY: clean all prepare common + diff --git a/driver/xrp-user/xrp-common/Makefile.am b/driver/xrp-user/xrp-common/Makefile.am new file mode 100644 index 0000000..aa770c1 --- /dev/null +++ b/driver/xrp-user/xrp-common/Makefile.am @@ -0,0 +1,31 @@ +# +# Copyright (c) 2018 Cadence Design Systems Inc. +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +AM_CPPFLAGS = -I$(srcdir)/.. \ + -I$(srcdir)/../xrp-kernel +AM_CFLAGS = -W -Wall + +lib_LIBRARIES = libxrp-common.a + +libxrp_common_a_SOURCES = xrp_rb_file.c \ + xrp_ns.c diff --git a/driver/xrp-user/xrp-common/Makefile.in b/driver/xrp-user/xrp-common/Makefile.in new file mode 100644 index 0000000..67c1c2d --- /dev/null +++ b/driver/xrp-user/xrp-common/Makefile.in @@ -0,0 +1,657 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# +# Copyright (c) 2018 Cadence Design Systems Inc. +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = xrp-common +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(libdir)" +LIBRARIES = $(lib_LIBRARIES) +ARFLAGS = cru +AM_V_AR = $(am__v_AR_@AM_V@) +am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) +am__v_AR_0 = @echo " AR " $@; +am__v_AR_1 = +libxrp_common_a_AR = $(AR) $(ARFLAGS) +libxrp_common_a_LIBADD = +am_libxrp_common_a_OBJECTS = xrp_rb_file.$(OBJEXT) xrp_ns.$(OBJEXT) +libxrp_common_a_OBJECTS = $(am_libxrp_common_a_OBJECTS) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ +depcomp = $(SHELL) $(top_srcdir)/autoconf/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/xrp_ns.Po ./$(DEPDIR)/xrp_rb_file.Po +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libxrp_common_a_SOURCES) +DIST_SOURCES = $(libxrp_common_a_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/autoconf/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCAS = @CCAS@ +CCASDEPMODE = @CCASDEPMODE@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DSP_CACHEATTR = @DSP_CACHEATTR@ +DSP_COMM_BASE = @DSP_COMM_BASE@ +DSP_LSP = @DSP_LSP@ +DTC = @DTC@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GREP = @GREP@ +HOST_CACHEATTR = @HOST_CACHEATTR@ +HOST_LSP = @HOST_LSP@ +HOST_OS = @HOST_OS@ +HW_PORT = @HW_PORT@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBFDT_CPPFLAGS = @LIBFDT_CPPFLAGS@ +LIBFDT_LDFLAGS = @LIBFDT_LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +THREADS_CFLAGS = @THREADS_CFLAGS@ +THREADS_IMPL = @THREADS_IMPL@ +THREADS_LDFLAGS = @THREADS_LDFLAGS@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AM_CPPFLAGS = -I$(srcdir)/.. \ + -I$(srcdir)/../xrp-kernel + +AM_CFLAGS = -W -Wall +lib_LIBRARIES = libxrp-common.a +libxrp_common_a_SOURCES = xrp_rb_file.c \ + xrp_ns.c + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign xrp-common/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign xrp-common/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-libLIBRARIES: $(lib_LIBRARIES) + @$(NORMAL_INSTALL) + @list='$(lib_LIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ + echo " $(INSTALL_DATA) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(INSTALL_DATA) $$list2 "$(DESTDIR)$(libdir)" || exit $$?; } + @$(POST_INSTALL) + @list='$(lib_LIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + if test -f $$p; then \ + $(am__strip_dir) \ + echo " ( cd '$(DESTDIR)$(libdir)' && $(RANLIB) $$f )"; \ + ( cd "$(DESTDIR)$(libdir)" && $(RANLIB) $$f ) || exit $$?; \ + else :; fi; \ + done + +uninstall-libLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LIBRARIES)'; test -n "$(libdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(libdir)'; $(am__uninstall_files_from_dir) + +clean-libLIBRARIES: + -test -z "$(lib_LIBRARIES)" || rm -f $(lib_LIBRARIES) + +libxrp-common.a: $(libxrp_common_a_OBJECTS) $(libxrp_common_a_DEPENDENCIES) $(EXTRA_libxrp_common_a_DEPENDENCIES) + $(AM_V_at)-rm -f libxrp-common.a + $(AM_V_AR)$(libxrp_common_a_AR) libxrp-common.a $(libxrp_common_a_OBJECTS) $(libxrp_common_a_LIBADD) + $(AM_V_at)$(RANLIB) libxrp-common.a + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xrp_ns.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xrp_rb_file.Po@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(libdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libLIBRARIES mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/xrp_ns.Po + -rm -f ./$(DEPDIR)/xrp_rb_file.Po + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-libLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/xrp_ns.Po + -rm -f ./$(DEPDIR)/xrp_rb_file.Po + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-libLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libLIBRARIES cscopelist-am ctags ctags-am \ + distclean distclean-compile distclean-generic distclean-tags \ + distdir dvi dvi-am html html-am info info-am install \ + install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am \ + install-libLIBRARIES install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-libLIBRARIES + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/driver/xrp-user/xrp-common/xrp_debug.h b/driver/xrp-user/xrp-common/xrp_debug.h new file mode 100644 index 0000000..e7effe2 --- /dev/null +++ b/driver/xrp-user/xrp-common/xrp_debug.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2016 - 2018 Cadence Design Systems Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef _XRP_DEBUG_H +#define _XRP_DEBUG_H + +#ifdef DEBUG +#include +#define pr_debug printf +#else +static inline int pr_debug(const char *p, ...) +{ + (void)p; + return 0; +} +#endif + +#endif diff --git a/driver/xrp-user/xrp-common/xrp_ns.c b/driver/xrp-user/xrp-common/xrp_ns.c new file mode 100644 index 0000000..4d2c048 --- /dev/null +++ b/driver/xrp-user/xrp-common/xrp_ns.c @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2016 - 2018 Cadence Design Systems Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include +#include "xrp_debug.h" +#include "xrp_ns.h" + +static int compare_cmd_ns(const void *nsid, struct xrp_cmd_ns *cmd_ns) +{ + return memcmp(nsid, cmd_ns->id, sizeof(cmd_ns->id)); +} + +int xrp_cmd_ns_match(const void *nsid, struct xrp_cmd_ns *cmd_ns) +{ + return cmd_ns && compare_cmd_ns(nsid, cmd_ns) == 0; +} + +#ifdef DEBUG +static void dump_nsid(const void *p) +{ + const uint8_t *id = p; + + printf("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", + id[0], id[1], id[2], id[3], + id[4], id[5], + id[6], id[7], + id[8], id[9], + id[10], id[11], id[12], id[13], id[14], id[15]); +} + +static void dump_cmd_ns(const struct xrp_cmd_ns *cmd_ns) +{ + if (cmd_ns) { + dump_nsid(cmd_ns->id); + printf(" -> %p(%p)", cmd_ns->handler, cmd_ns->handler_context); + } else { + printf("NULL"); + } +} + +static void dump_cmd_ns_map(const struct xrp_cmd_ns_map *ns_map) +{ + size_t i; + + printf("n_cmd_ns: %zu, size_cmd_ns: %zu\n", + ns_map->n_cmd_ns, ns_map->size_cmd_ns); + for (i = 0; i < ns_map->n_cmd_ns; ++i) { + printf(" "); + dump_cmd_ns(ns_map->cmd_ns + i); + printf("\n"); + } +} +#else +static void dump_nsid(const void *p) +{ + (void)p; +} + +static void dump_cmd_ns(const struct xrp_cmd_ns *cmd_ns) +{ + (void)cmd_ns; +} + +static void dump_cmd_ns_map(const struct xrp_cmd_ns_map *ns_map) +{ + (void)ns_map; +} +#endif + +static int cmd_ns_present(struct xrp_cmd_ns_map *ns_map, + struct xrp_cmd_ns *cmd_ns) +{ + return cmd_ns >= ns_map->cmd_ns && + cmd_ns < ns_map->cmd_ns + ns_map->n_cmd_ns; +} + +struct xrp_cmd_ns *xrp_find_cmd_ns(struct xrp_cmd_ns_map *ns_map, + const void *id) +{ + size_t a = 0; + size_t b = ns_map->n_cmd_ns; + struct xrp_cmd_ns *p; + + pr_debug("%s: ", __func__); + dump_nsid(id); + pr_debug("\n"); + while (b - a > 1) { + size_t c = (a + b) / 2; + + pr_debug("a: %zu, b:%zu, c: %zu\n", a, b, c); + p = ns_map->cmd_ns + c; + if (compare_cmd_ns(id, p) < 0) + b = c; + else + a = c; + pr_debug("...a: %zu, b:%zu\n", a, b); + } + p = ns_map->cmd_ns + a; + if (a < b && compare_cmd_ns(id, p) > 0) + ++p; + if (cmd_ns_present(ns_map, p)) { + pr_debug("%s: found: ", __func__); + dump_cmd_ns(p); + pr_debug("\n"); + } else { + pr_debug("%s: not found\n", __func__); + } + + return p; +} + +static struct xrp_cmd_ns *insert_cmd_ns(struct xrp_cmd_ns_map *ns_map, + struct xrp_cmd_ns *cmd_ns) +{ + size_t i = cmd_ns - ns_map->cmd_ns; + + if (ns_map->n_cmd_ns == ns_map->size_cmd_ns) { + size_t new_size = (ns_map->size_cmd_ns + 1) * 2; + void *new_cmd_ns = realloc(ns_map->cmd_ns, + new_size * sizeof(*ns_map->cmd_ns)); + + if (!new_cmd_ns) + return NULL; + ns_map->cmd_ns = new_cmd_ns; + ns_map->size_cmd_ns = new_size; + cmd_ns = ns_map->cmd_ns + i; + } + memmove(cmd_ns + 1, cmd_ns, + sizeof(*cmd_ns) * (ns_map->n_cmd_ns - i)); + ++ns_map->n_cmd_ns; + return cmd_ns; +} + +static void remove_cmd_ns(struct xrp_cmd_ns_map *ns_map, + struct xrp_cmd_ns *cmd_ns) +{ + size_t i = cmd_ns - ns_map->cmd_ns; + + memmove(cmd_ns, cmd_ns + 1, + sizeof(*cmd_ns) * (ns_map->n_cmd_ns - i - 1)); + --ns_map->n_cmd_ns; +} + +int xrp_register_namespace(struct xrp_cmd_ns_map *ns_map, + const void *nsid, + xrp_command_handler *handler, + void *handler_context) +{ + struct xrp_cmd_ns *cmd_ns = xrp_find_cmd_ns(ns_map, nsid); + + if (cmd_ns_present(ns_map, cmd_ns) && xrp_cmd_ns_match(nsid, cmd_ns)) { + return 0; + } else { + cmd_ns = insert_cmd_ns(ns_map, cmd_ns); + if (cmd_ns) { + memcpy(cmd_ns->id, nsid, sizeof(cmd_ns->id)); + cmd_ns->handler = handler; + cmd_ns->handler_context = handler_context; + dump_cmd_ns_map(ns_map); + return 1; + } else { + return 0; + } + } +} + +int xrp_unregister_namespace(struct xrp_cmd_ns_map *ns_map, + const void *nsid) +{ + struct xrp_cmd_ns *cmd_ns = xrp_find_cmd_ns(ns_map, nsid); + + if (cmd_ns_present(ns_map, cmd_ns) && xrp_cmd_ns_match(nsid, cmd_ns)) { + remove_cmd_ns(ns_map, cmd_ns); + dump_cmd_ns_map(ns_map); + return 1; + } else { + return 0; + } +} diff --git a/driver/xrp-user/xrp-common/xrp_ns.h b/driver/xrp-user/xrp-common/xrp_ns.h new file mode 100644 index 0000000..1aba666 --- /dev/null +++ b/driver/xrp-user/xrp-common/xrp_ns.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2016 - 2018 Cadence Design Systems Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef _XRP_NS_H +#define _XRP_NS_H + +#include + +struct xrp_cmd_ns { + char id[XRP_NAMESPACE_ID_SIZE]; + xrp_command_handler *handler; + void *handler_context; +}; + +struct xrp_cmd_ns_map { + size_t n_cmd_ns; + size_t size_cmd_ns; + struct xrp_cmd_ns *cmd_ns; +}; + +int xrp_register_namespace(struct xrp_cmd_ns_map *ns_map, + const void *nsid, + xrp_command_handler *handler, + void *handler_context); +int xrp_unregister_namespace(struct xrp_cmd_ns_map *ns_map, + const void *nsid); + +int xrp_cmd_ns_match(const void *nsid, struct xrp_cmd_ns *cmd_ns); +struct xrp_cmd_ns *xrp_find_cmd_ns(struct xrp_cmd_ns_map *ns_map, + const void *id); + +#endif diff --git a/driver/xrp-user/xrp-common/xrp_rb_file.c b/driver/xrp-user/xrp-common/xrp_rb_file.c new file mode 100644 index 0000000..1c0ca3d --- /dev/null +++ b/driver/xrp-user/xrp-common/xrp_rb_file.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2018 Cadence Design Systems Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include "xrp_rb_file.h" + +static size_t xrp_rb_write_some(void *cookie, const void *buf, size_t size) +{ + volatile struct xrp_ring_buffer *rb = cookie; + uint32_t read = rb->read; + uint32_t write = rb->write; + size_t tail; + + if (read > write) { + tail = read - 1 - write; + } else if (read) { + tail = rb->size - write; + } else { + tail = rb->size - 1 - write; + } + + if (size < tail) + tail = size; + + memcpy((char *)rb->data + write, buf, tail); + + write += tail; + if (write == rb->size) + write = 0; + rb->write = write; + + return tail; +} + +size_t xrp_rb_write(void *cookie, const void *buf, size_t size) +{ + size_t write_total = 0; + const char *p = buf; + + while (size) { + size_t write = xrp_rb_write_some(cookie, p, size); + + if (write == 0) + break; + + p += write; + size -= write; + write_total += write; + } + return write_total; +} diff --git a/driver/xrp-user/xrp-common/xrp_rb_file.h b/driver/xrp-user/xrp-common/xrp_rb_file.h new file mode 100644 index 0000000..ba286dc --- /dev/null +++ b/driver/xrp-user/xrp-common/xrp_rb_file.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2018 Cadence Design Systems Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef XRP_RB_FILE_H +#define XRP_RB_FILE_H + +#include +#include +#include + +size_t xrp_rb_write(void *cookie, const void *buf, size_t size); + +#endif diff --git a/driver/xrp-user/xrp-common/xrp_types.h b/driver/xrp-user/xrp-common/xrp_types.h new file mode 100644 index 0000000..6259885 --- /dev/null +++ b/driver/xrp-user/xrp-common/xrp_types.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2018 Cadence Design Systems Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef XRP_TYPES_H +#define XRP_TYPES_H + +#include + +#ifndef HAVE___U8 +typedef uint8_t __u8; +#endif +#ifndef HAVE___U32 +typedef uint32_t __u32; +#endif +#ifndef HAVE___U64 +typedef uint64_t __u64; +#endif + +#endif diff --git a/driver/xrp-user/xrp-host/.deps/libxrp_host_hosted_a-xrp_host_common.Po b/driver/xrp-user/xrp-host/.deps/libxrp_host_hosted_a-xrp_host_common.Po new file mode 100644 index 0000000..3dadccc --- /dev/null +++ b/driver/xrp-user/xrp-host/.deps/libxrp_host_hosted_a-xrp_host_common.Po @@ -0,0 +1,228 @@ +libxrp_host_hosted_a-xrp_host_common.o: xrp_host_common.c \ + /usr/include/stdc-predef.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stdint.h /usr/include/stdint.h \ + /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ + /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/bits/long-double.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h \ + /usr/include/x86_64-linux-gnu/bits/wchar.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-intn.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h /usr/include/stdio.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stddef.h \ + /usr/include/x86_64-linux-gnu/bits/types/__FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/FILE.h \ + /usr/include/x86_64-linux-gnu/bits/libio.h \ + /usr/include/x86_64-linux-gnu/bits/_G_config.h \ + /usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stdarg.h \ + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ + /usr/include/x86_64-linux-gnu/bits/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/stdio2.h /usr/include/string.h \ + /usr/include/x86_64-linux-gnu/bits/types/locale_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__locale_t.h \ + /usr/include/strings.h \ + /usr/include/x86_64-linux-gnu/bits/strings_fortified.h \ + /usr/include/x86_64-linux-gnu/bits/string_fortified.h ../xrp_api.h \ + xrp_host_common.h /usr/include/stdlib.h \ + /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h \ + /usr/include/x86_64-linux-gnu/bits/floatn.h \ + /usr/include/x86_64-linux-gnu/bits/floatn-common.h \ + /usr/include/x86_64-linux-gnu/sys/types.h \ + /usr/include/x86_64-linux-gnu/bits/types/clock_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/clockid_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/time_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/timer_t.h /usr/include/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap-16.h \ + /usr/include/x86_64-linux-gnu/bits/uintn-identity.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ + /usr/include/x86_64-linux-gnu/bits/types/sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h \ + /usr/include/x86_64-linux-gnu/bits/select2.h \ + /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ + /usr/include/x86_64-linux-gnu/bits/sysmacros.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h \ + /usr/include/x86_64-linux-gnu/bits/thread-shared-types.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h \ + /usr/include/alloca.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib.h xrp_atomic.h \ + thread-pthread/xrp_thread_impl.h /usr/include/pthread.h \ + /usr/include/sched.h /usr/include/x86_64-linux-gnu/bits/sched.h \ + /usr/include/x86_64-linux-gnu/bits/cpu-set.h /usr/include/time.h \ + /usr/include/x86_64-linux-gnu/bits/time.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_tm.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h \ + /usr/include/x86_64-linux-gnu/bits/setjmp.h hosted/xrp_host_impl.h \ + thread-pthread/xrp_queue_impl.h xrp_threaded_queue.h + +/usr/include/stdc-predef.h: + +/usr/lib/gcc/x86_64-linux-gnu/7/include/stdint.h: + +/usr/include/stdint.h: + +/usr/include/x86_64-linux-gnu/bits/libc-header-start.h: + +/usr/include/features.h: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/usr/include/x86_64-linux-gnu/bits/long-double.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/usr/include/x86_64-linux-gnu/bits/types.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/include/x86_64-linux-gnu/bits/wchar.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-intn.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-uintn.h: + +/usr/include/stdio.h: + +/usr/lib/gcc/x86_64-linux-gnu/7/include/stddef.h: + +/usr/include/x86_64-linux-gnu/bits/types/__FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/FILE.h: + +/usr/include/x86_64-linux-gnu/bits/libio.h: + +/usr/include/x86_64-linux-gnu/bits/_G_config.h: + +/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h: + +/usr/lib/gcc/x86_64-linux-gnu/7/include/stdarg.h: + +/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: + +/usr/include/x86_64-linux-gnu/bits/sys_errlist.h: + +/usr/include/x86_64-linux-gnu/bits/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/stdio2.h: + +/usr/include/string.h: + +/usr/include/x86_64-linux-gnu/bits/types/locale_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__locale_t.h: + +/usr/include/strings.h: + +/usr/include/x86_64-linux-gnu/bits/strings_fortified.h: + +/usr/include/x86_64-linux-gnu/bits/string_fortified.h: + +../xrp_api.h: + +xrp_host_common.h: + +/usr/include/stdlib.h: + +/usr/include/x86_64-linux-gnu/bits/waitflags.h: + +/usr/include/x86_64-linux-gnu/bits/waitstatus.h: + +/usr/include/x86_64-linux-gnu/bits/floatn.h: + +/usr/include/x86_64-linux-gnu/bits/floatn-common.h: + +/usr/include/x86_64-linux-gnu/sys/types.h: + +/usr/include/x86_64-linux-gnu/bits/types/clock_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/clockid_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/time_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/timer_t.h: + +/usr/include/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap-16.h: + +/usr/include/x86_64-linux-gnu/bits/uintn-identity.h: + +/usr/include/x86_64-linux-gnu/sys/select.h: + +/usr/include/x86_64-linux-gnu/bits/select.h: + +/usr/include/x86_64-linux-gnu/bits/types/sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h: + +/usr/include/x86_64-linux-gnu/bits/select2.h: + +/usr/include/x86_64-linux-gnu/sys/sysmacros.h: + +/usr/include/x86_64-linux-gnu/bits/sysmacros.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: + +/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h: + +/usr/include/alloca.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-float.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib.h: + +xrp_atomic.h: + +thread-pthread/xrp_thread_impl.h: + +/usr/include/pthread.h: + +/usr/include/sched.h: + +/usr/include/x86_64-linux-gnu/bits/sched.h: + +/usr/include/x86_64-linux-gnu/bits/cpu-set.h: + +/usr/include/time.h: + +/usr/include/x86_64-linux-gnu/bits/time.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h: + +/usr/include/x86_64-linux-gnu/bits/setjmp.h: + +hosted/xrp_host_impl.h: + +thread-pthread/xrp_queue_impl.h: + +xrp_threaded_queue.h: diff --git a/driver/xrp-user/xrp-host/.deps/libxrp_host_hosted_a-xrp_sync_queue.Po b/driver/xrp-user/xrp-host/.deps/libxrp_host_hosted_a-xrp_sync_queue.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/driver/xrp-user/xrp-host/.deps/libxrp_host_hosted_a-xrp_sync_queue.Po @@ -0,0 +1 @@ +# dummy diff --git a/driver/xrp-user/xrp-host/.deps/libxrp_host_hosted_a-xrp_threaded_queue.Po b/driver/xrp-user/xrp-host/.deps/libxrp_host_hosted_a-xrp_threaded_queue.Po new file mode 100644 index 0000000..1134609 --- /dev/null +++ b/driver/xrp-user/xrp-host/.deps/libxrp_host_hosted_a-xrp_threaded_queue.Po @@ -0,0 +1,211 @@ +libxrp_host_hosted_a-xrp_threaded_queue.o: xrp_threaded_queue.c \ + /usr/include/stdc-predef.h /usr/include/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ + /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/bits/long-double.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stddef.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h \ + /usr/include/x86_64-linux-gnu/bits/types/__FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/FILE.h \ + /usr/include/x86_64-linux-gnu/bits/libio.h \ + /usr/include/x86_64-linux-gnu/bits/_G_config.h \ + /usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stdarg.h \ + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ + /usr/include/x86_64-linux-gnu/bits/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/stdio2.h ../xrp-common/xrp_debug.h \ + xrp_host_common.h /usr/include/stdlib.h \ + /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h \ + /usr/include/x86_64-linux-gnu/bits/floatn.h \ + /usr/include/x86_64-linux-gnu/bits/floatn-common.h \ + /usr/include/x86_64-linux-gnu/sys/types.h \ + /usr/include/x86_64-linux-gnu/bits/types/clock_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/clockid_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/time_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/timer_t.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-intn.h /usr/include/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap-16.h \ + /usr/include/x86_64-linux-gnu/bits/uintn-identity.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ + /usr/include/x86_64-linux-gnu/bits/types/sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h \ + /usr/include/x86_64-linux-gnu/bits/select2.h \ + /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ + /usr/include/x86_64-linux-gnu/bits/sysmacros.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h \ + /usr/include/x86_64-linux-gnu/bits/thread-shared-types.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h \ + /usr/include/alloca.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib.h xrp_atomic.h \ + thread-pthread/xrp_thread_impl.h /usr/include/pthread.h \ + /usr/include/sched.h /usr/include/x86_64-linux-gnu/bits/sched.h \ + /usr/include/x86_64-linux-gnu/bits/cpu-set.h /usr/include/time.h \ + /usr/include/x86_64-linux-gnu/bits/time.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_tm.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h \ + /usr/include/x86_64-linux-gnu/bits/types/locale_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__locale_t.h \ + /usr/include/x86_64-linux-gnu/bits/setjmp.h hosted/xrp_host_impl.h \ + ../xrp_api.h thread-pthread/xrp_queue_impl.h xrp_threaded_queue.h \ + xrp_threaded_queue.h + +/usr/include/stdc-predef.h: + +/usr/include/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/libc-header-start.h: + +/usr/include/features.h: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/usr/include/x86_64-linux-gnu/bits/long-double.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/usr/lib/gcc/x86_64-linux-gnu/7/include/stddef.h: + +/usr/include/x86_64-linux-gnu/bits/types.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/include/x86_64-linux-gnu/bits/types/__FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/FILE.h: + +/usr/include/x86_64-linux-gnu/bits/libio.h: + +/usr/include/x86_64-linux-gnu/bits/_G_config.h: + +/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h: + +/usr/lib/gcc/x86_64-linux-gnu/7/include/stdarg.h: + +/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: + +/usr/include/x86_64-linux-gnu/bits/sys_errlist.h: + +/usr/include/x86_64-linux-gnu/bits/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/stdio2.h: + +../xrp-common/xrp_debug.h: + +xrp_host_common.h: + +/usr/include/stdlib.h: + +/usr/include/x86_64-linux-gnu/bits/waitflags.h: + +/usr/include/x86_64-linux-gnu/bits/waitstatus.h: + +/usr/include/x86_64-linux-gnu/bits/floatn.h: + +/usr/include/x86_64-linux-gnu/bits/floatn-common.h: + +/usr/include/x86_64-linux-gnu/sys/types.h: + +/usr/include/x86_64-linux-gnu/bits/types/clock_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/clockid_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/time_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/timer_t.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-intn.h: + +/usr/include/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap-16.h: + +/usr/include/x86_64-linux-gnu/bits/uintn-identity.h: + +/usr/include/x86_64-linux-gnu/sys/select.h: + +/usr/include/x86_64-linux-gnu/bits/select.h: + +/usr/include/x86_64-linux-gnu/bits/types/sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h: + +/usr/include/x86_64-linux-gnu/bits/select2.h: + +/usr/include/x86_64-linux-gnu/sys/sysmacros.h: + +/usr/include/x86_64-linux-gnu/bits/sysmacros.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: + +/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h: + +/usr/include/alloca.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-float.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib.h: + +xrp_atomic.h: + +thread-pthread/xrp_thread_impl.h: + +/usr/include/pthread.h: + +/usr/include/sched.h: + +/usr/include/x86_64-linux-gnu/bits/sched.h: + +/usr/include/x86_64-linux-gnu/bits/cpu-set.h: + +/usr/include/time.h: + +/usr/include/x86_64-linux-gnu/bits/time.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h: + +/usr/include/x86_64-linux-gnu/bits/types/locale_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__locale_t.h: + +/usr/include/x86_64-linux-gnu/bits/setjmp.h: + +hosted/xrp_host_impl.h: + +../xrp_api.h: + +thread-pthread/xrp_queue_impl.h: + +xrp_threaded_queue.h: + +xrp_threaded_queue.h: diff --git a/driver/xrp-user/xrp-host/.deps/libxrp_host_single_a-xrp_host_common.Po b/driver/xrp-user/xrp-host/.deps/libxrp_host_single_a-xrp_host_common.Po new file mode 100644 index 0000000..c2a1050 --- /dev/null +++ b/driver/xrp-user/xrp-host/.deps/libxrp_host_single_a-xrp_host_common.Po @@ -0,0 +1,204 @@ +libxrp_host_single_a-xrp_host_common.o: xrp_host_common.c \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stdint.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/yvals.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/yvals.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/config/core-isa.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/lib/xcc/include/stdarg.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stdio.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/stdio.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/mbstatet.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_scmpr.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/string.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/string.h \ + ../xrp_api.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stddef.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/stddef.h \ + xrp_host_common.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stdlib.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/stdlib.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/alloca.h \ + xrp_atomic.h thread-xos/xrp_thread_impl.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_types.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/hal.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/config/core.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xtensa-versions.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xtensa-types.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/config/core-matmap.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/config/tie.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/hal-certified.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/hal-compat.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/core-macros.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/corebits.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_core.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_interrupt.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_timer.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_externalregisters.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_coprocessors.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/intctrl.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/core-macros-compat.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_common.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/config/system.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_params.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/sys/reent.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/wchar.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/xwcstod.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/xwstr.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/fenv.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/ymath.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/ymath.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_errors.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_regaccess.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_log.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_thread.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_cond.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_event.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_mutex.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_msgq.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_semaphore.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_blockmem.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_barrier.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_timer.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_stopwatch.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_syslog.h \ + single/xrp_host_impl.h ../xrp_api.h thread-xos/xrp_thread_impl.h \ + thread-xos/xrp_queue_impl.h xrp_threaded_queue.h \ + thread-xos/xrp_thread_impl.h + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stdint.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/yvals.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/yvals.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/config/core-isa.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/lib/xcc/include/stdarg.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stdio.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/stdio.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/mbstatet.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_scmpr.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/string.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/string.h: + +../xrp_api.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stddef.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/stddef.h: + +xrp_host_common.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stdlib.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/stdlib.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/alloca.h: + +xrp_atomic.h: + +thread-xos/xrp_thread_impl.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_types.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/hal.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/config/core.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xtensa-versions.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xtensa-types.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/config/core-matmap.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/config/tie.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/hal-certified.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/hal-compat.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/core-macros.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/corebits.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_core.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_interrupt.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_timer.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_externalregisters.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_coprocessors.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/intctrl.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/core-macros-compat.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_common.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/config/system.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_params.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/sys/reent.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/wchar.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/xwcstod.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/xwstr.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/fenv.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/ymath.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/ymath.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_errors.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_regaccess.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_log.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_thread.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_cond.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_event.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_mutex.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_msgq.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_semaphore.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_blockmem.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_barrier.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_timer.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_stopwatch.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_syslog.h: + +single/xrp_host_impl.h: + +../xrp_api.h: + +thread-xos/xrp_thread_impl.h: + +thread-xos/xrp_queue_impl.h: + +xrp_threaded_queue.h: + +thread-xos/xrp_thread_impl.h: diff --git a/driver/xrp-user/xrp-host/.deps/libxrp_host_single_a-xrp_sync_queue.Po b/driver/xrp-user/xrp-host/.deps/libxrp_host_single_a-xrp_sync_queue.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/driver/xrp-user/xrp-host/.deps/libxrp_host_single_a-xrp_sync_queue.Po @@ -0,0 +1 @@ +# dummy diff --git a/driver/xrp-user/xrp-host/.deps/libxrp_host_single_a-xrp_threaded_queue.Po b/driver/xrp-user/xrp-host/.deps/libxrp_host_single_a-xrp_threaded_queue.Po new file mode 100644 index 0000000..d944ad1 --- /dev/null +++ b/driver/xrp-user/xrp-host/.deps/libxrp_host_single_a-xrp_threaded_queue.Po @@ -0,0 +1,196 @@ +libxrp_host_single_a-xrp_threaded_queue.o: xrp_threaded_queue.c \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stdio.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/stdio.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/yvals.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/config/core-isa.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/lib/xcc/include/stdarg.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/mbstatet.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_scmpr.h \ + ../xrp-common/xrp_debug.h xrp_host_common.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stdlib.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/stdlib.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/alloca.h \ + xrp_atomic.h thread-xos/xrp_thread_impl.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_types.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stdint.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/hal.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/config/core.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xtensa-versions.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xtensa-types.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/config/core-matmap.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/config/tie.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/hal-certified.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stddef.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/stddef.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/hal-compat.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/core-macros.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/corebits.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_core.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_interrupt.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_timer.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_externalregisters.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_coprocessors.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/intctrl.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/core-macros-compat.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_common.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/config/system.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_params.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/sys/reent.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/wchar.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/xwcstod.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/xwstr.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/fenv.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/ymath.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/ymath.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_errors.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_regaccess.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_log.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_thread.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_cond.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_event.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_mutex.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_msgq.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_semaphore.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_blockmem.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_barrier.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_timer.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_stopwatch.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_syslog.h \ + single/xrp_host_impl.h ../xrp_api.h thread-xos/xrp_thread_impl.h \ + thread-xos/xrp_queue_impl.h xrp_threaded_queue.h \ + thread-xos/xrp_thread_impl.h xrp_threaded_queue.h + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stdio.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/stdio.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/yvals.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/config/core-isa.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/lib/xcc/include/stdarg.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/mbstatet.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_scmpr.h: + +../xrp-common/xrp_debug.h: + +xrp_host_common.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stdlib.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/stdlib.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/alloca.h: + +xrp_atomic.h: + +thread-xos/xrp_thread_impl.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_types.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stdint.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/hal.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/config/core.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xtensa-versions.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xtensa-types.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/config/core-matmap.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/config/tie.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/hal-certified.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stddef.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/stddef.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/hal-compat.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/core-macros.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/corebits.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_core.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_interrupt.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_timer.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_externalregisters.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_coprocessors.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/intctrl.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/core-macros-compat.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_common.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/config/system.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_params.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/sys/reent.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/wchar.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/xwcstod.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/xwstr.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/fenv.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/ymath.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/ymath.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_errors.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_regaccess.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_log.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_thread.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_cond.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_event.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_mutex.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_msgq.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_semaphore.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_blockmem.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_barrier.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_timer.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_stopwatch.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_syslog.h: + +single/xrp_host_impl.h: + +../xrp_api.h: + +thread-xos/xrp_thread_impl.h: + +thread-xos/xrp_queue_impl.h: + +xrp_threaded_queue.h: + +thread-xos/xrp_thread_impl.h: + +xrp_threaded_queue.h: diff --git a/driver/xrp-user/xrp-host/.deps/libxrp_host_standalone_a-xrp_host_common.Po b/driver/xrp-user/xrp-host/.deps/libxrp_host_standalone_a-xrp_host_common.Po new file mode 100644 index 0000000..26a5339 --- /dev/null +++ b/driver/xrp-user/xrp-host/.deps/libxrp_host_standalone_a-xrp_host_common.Po @@ -0,0 +1,204 @@ +libxrp_host_standalone_a-xrp_host_common.o: xrp_host_common.c \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stdint.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/yvals.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/yvals.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/config/core-isa.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/lib/xcc/include/stdarg.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stdio.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/stdio.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/mbstatet.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_scmpr.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/string.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/string.h \ + ../xrp_api.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stddef.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/stddef.h \ + xrp_host_common.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stdlib.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/stdlib.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/alloca.h \ + xrp_atomic.h thread-xos/xrp_thread_impl.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_types.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/hal.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/config/core.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xtensa-versions.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xtensa-types.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/config/core-matmap.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/config/tie.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/hal-certified.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/hal-compat.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/core-macros.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/corebits.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_core.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_interrupt.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_timer.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_externalregisters.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_coprocessors.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/intctrl.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/core-macros-compat.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_common.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/config/system.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_params.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/sys/reent.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/wchar.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/xwcstod.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/xwstr.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/fenv.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/ymath.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/ymath.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_errors.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_regaccess.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_log.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_thread.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_cond.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_event.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_mutex.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_msgq.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_semaphore.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_blockmem.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_barrier.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_timer.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_stopwatch.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_syslog.h \ + standalone/xrp_host_impl.h ../xrp_api.h thread-xos/xrp_thread_impl.h \ + thread-xos/xrp_queue_impl.h xrp_threaded_queue.h \ + thread-xos/xrp_thread_impl.h + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stdint.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/yvals.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/yvals.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/config/core-isa.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/lib/xcc/include/stdarg.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stdio.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/stdio.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/mbstatet.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_scmpr.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/string.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/string.h: + +../xrp_api.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stddef.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/stddef.h: + +xrp_host_common.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stdlib.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/stdlib.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/alloca.h: + +xrp_atomic.h: + +thread-xos/xrp_thread_impl.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_types.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/hal.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/config/core.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xtensa-versions.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xtensa-types.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/config/core-matmap.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/config/tie.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/hal-certified.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/hal-compat.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/core-macros.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/corebits.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_core.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_interrupt.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_timer.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_externalregisters.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_coprocessors.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/intctrl.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/core-macros-compat.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_common.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/config/system.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_params.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/sys/reent.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/wchar.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/xwcstod.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/xwstr.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/fenv.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/ymath.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/ymath.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_errors.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_regaccess.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_log.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_thread.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_cond.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_event.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_mutex.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_msgq.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_semaphore.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_blockmem.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_barrier.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_timer.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_stopwatch.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_syslog.h: + +standalone/xrp_host_impl.h: + +../xrp_api.h: + +thread-xos/xrp_thread_impl.h: + +thread-xos/xrp_queue_impl.h: + +xrp_threaded_queue.h: + +thread-xos/xrp_thread_impl.h: diff --git a/driver/xrp-user/xrp-host/.deps/libxrp_host_standalone_a-xrp_sync_queue.Po b/driver/xrp-user/xrp-host/.deps/libxrp_host_standalone_a-xrp_sync_queue.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/driver/xrp-user/xrp-host/.deps/libxrp_host_standalone_a-xrp_sync_queue.Po @@ -0,0 +1 @@ +# dummy diff --git a/driver/xrp-user/xrp-host/.deps/libxrp_host_standalone_a-xrp_threaded_queue.Po b/driver/xrp-user/xrp-host/.deps/libxrp_host_standalone_a-xrp_threaded_queue.Po new file mode 100644 index 0000000..3c1e832 --- /dev/null +++ b/driver/xrp-user/xrp-host/.deps/libxrp_host_standalone_a-xrp_threaded_queue.Po @@ -0,0 +1,196 @@ +libxrp_host_standalone_a-xrp_threaded_queue.o: xrp_threaded_queue.c \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stdio.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/stdio.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/yvals.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/config/core-isa.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/lib/xcc/include/stdarg.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/mbstatet.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_scmpr.h \ + ../xrp-common/xrp_debug.h xrp_host_common.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stdlib.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/stdlib.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/alloca.h \ + xrp_atomic.h thread-xos/xrp_thread_impl.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_types.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stdint.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/hal.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/config/core.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xtensa-versions.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xtensa-types.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/config/core-matmap.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/config/tie.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/hal-certified.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stddef.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/stddef.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/hal-compat.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/core-macros.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/corebits.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_core.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_interrupt.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_timer.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_externalregisters.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_coprocessors.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/intctrl.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/core-macros-compat.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_common.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/config/system.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_params.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/sys/reent.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/wchar.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/xwcstod.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/xwstr.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/fenv.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/ymath.h \ + /home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/ymath.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_errors.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_regaccess.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_log.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_thread.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_cond.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_event.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_mutex.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_msgq.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_semaphore.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_blockmem.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_barrier.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_timer.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_stopwatch.h \ + /home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_syslog.h \ + standalone/xrp_host_impl.h ../xrp_api.h thread-xos/xrp_thread_impl.h \ + thread-xos/xrp_queue_impl.h xrp_threaded_queue.h \ + thread-xos/xrp_thread_impl.h xrp_threaded_queue.h + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stdio.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/stdio.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/yvals.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/config/core-isa.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/lib/xcc/include/stdarg.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/mbstatet.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_scmpr.h: + +../xrp-common/xrp_debug.h: + +xrp_host_common.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stdlib.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/stdlib.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/alloca.h: + +xrp_atomic.h: + +thread-xos/xrp_thread_impl.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_types.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stdint.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/hal.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/config/core.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xtensa-versions.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xtensa-types.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/config/core-matmap.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/config/tie.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/hal-certified.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/stddef.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/stddef.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/hal-compat.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/core-macros.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/corebits.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_core.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_interrupt.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_timer.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_externalregisters.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/tie/xt_coprocessors.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/intctrl.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/core-macros-compat.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_common.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/arch/include/xtensa/config/system.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_params.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/sys/reent.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/wchar.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/xwcstod.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/xwstr.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/fenv.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/ymath.h: + +/home/jianghm/xtensa/XtDevTools/install/builds/RI-2020.4-linux/q7_check/xtensa-elf/include/c99/ymath.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_errors.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_regaccess.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_log.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_thread.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_cond.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_event.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_mutex.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_msgq.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_semaphore.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_blockmem.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_barrier.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_timer.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_stopwatch.h: + +/home/jianghm/xtensa/XtDevTools/install/tools/RI-2020.4-linux/XtensaTools/xtensa-elf/include/xtensa/xos_syslog.h: + +standalone/xrp_host_impl.h: + +../xrp_api.h: + +thread-xos/xrp_thread_impl.h: + +thread-xos/xrp_queue_impl.h: + +xrp_threaded_queue.h: + +thread-xos/xrp_thread_impl.h: + +xrp_threaded_queue.h: diff --git a/driver/xrp-user/xrp-host/Makefile b/driver/xrp-user/xrp-host/Makefile new file mode 100644 index 0000000..e6a5497 --- /dev/null +++ b/driver/xrp-user/xrp-host/Makefile @@ -0,0 +1,52 @@ +## + # Copyright (C) 2021 Alibaba Group Holding Limited + # + # This program is free software; you can redistribute it and/or modify + # it under the terms of the GNU General Public License version 2 as + # published by the Free Software Foundation. +## + + +# INCLUDES = -I../../driver/isp -I../../common + +TARGET = libxrp_linux.a + +CFLAGS = -O0 -Wall -g -lm -lpthread +CFLAGS += -fPIC + +# USE_THREADS = + +# ifdef USE_THREADS +queue_sources = xrp_threaded_queue.c +INCLUDE +=-Ithread-pthread +# else +# queue_sources = xrp_sync_queue.c +# endif + +xrp_SRCS += $(queue_sources) +xrp_SRCS += xrp_host_common.c +xrp_SRCS += hosted/xrp_linux.c +xrp_SRCS += xrp_report.c + +INCLUDES = -I$(CURDIR) -Ihosted -I../include -Ithread-pthread -I../xrp-common -I../../xrp-kernel +# object files will be generated from .c sourcefiles +xrp_OBJS = $(notdir $(xrp_SRCS:.c=.o)) + +all: $(TARGET) + + +$(xrp_OBJS): $(xrp_SRCS) + $(CC) -c $(CFLAGS) $(INCLUDES) $(xrp_SRCS) + + +$(TARGET): $(xrp_OBJS) + $(AR) -rc $(TARGET) $(xrp_OBJS) + +clean: + rm -f *.o *.a + rm -rf output + +install: + +.PHONY: clean all prepare common + diff --git a/driver/xrp-user/xrp-host/Makefile.am b/driver/xrp-user/xrp-host/Makefile.am new file mode 100644 index 0000000..6285945 --- /dev/null +++ b/driver/xrp-user/xrp-host/Makefile.am @@ -0,0 +1,69 @@ +# +# Copyright (c) 2017 - 2018 Cadence Design Systems Inc. +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +AM_CPPFLAGS = -I$(srcdir)/.. -I$(srcdir) -I$(srcdir)/../xrp-common \ + -I$(srcdir)/thread-@THREADS_IMPL@ +AM_CFLAGS = -W -Wall $(THREADS_CFLAGS) + +include_HEADERS = ../xrp_api.h +lib_LIBRARIES = + +if BUILD_STANDALONE +lib_LIBRARIES += libxrp-host-standalone.a +endif +if BUILD_HOSTED +lib_LIBRARIES += libxrp-host-hosted.a +endif +if BUILD_SINGLE +lib_LIBRARIES += libxrp-host-single.a +endif + +if USE_THREADS +queue_sources = xrp_threaded_queue.c +else +queue_sources = xrp_sync_queue.c +endif + +libxrp_host_standalone_a_CPPFLAGS = $(AM_CPPFLAGS) \ + $(LIBFDT_CPPFLAGS) \ + -I$(srcdir)/standalone \ + -I$(srcdir)/../xrp-kernel +libxrp_host_standalone_a_SOURCES = xrp_host_common.c \ + $(queue_sources) \ + standalone/xrp_host.c \ + standalone/xrp_@HOST_OS@.c \ + ../xrp-kernel/xrp_alloc.c + +libxrp_host_hosted_a_CPPFLAGS = $(AM_CPPFLAGS) \ + -I$(srcdir)/hosted \ + -I$(srcdir)/../xrp-kernel +libxrp_host_hosted_a_SOURCES = xrp_host_common.c \ + $(queue_sources) \ + hosted/xrp_@HOST_OS@.c + +libxrp_host_single_a_CPPFLAGS = $(AM_CPPFLAGS) \ + -I$(srcdir)/single +libxrp_host_single_a_SOURCES = xrp_host_common.c \ + $(queue_sources) \ + single/xrp_single.c \ + ../xrp-common/xrp_ns.c diff --git a/driver/xrp-user/xrp-host/hosted/.deps/.dirstamp b/driver/xrp-user/xrp-host/hosted/.deps/.dirstamp new file mode 100644 index 0000000..e69de29 diff --git a/driver/xrp-user/xrp-host/hosted/.deps/libxrp_host_hosted_a-xrp_elf.Po b/driver/xrp-user/xrp-host/hosted/.deps/libxrp_host_hosted_a-xrp_elf.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/driver/xrp-user/xrp-host/hosted/.deps/libxrp_host_hosted_a-xrp_elf.Po @@ -0,0 +1 @@ +# dummy diff --git a/driver/xrp-user/xrp-host/hosted/.deps/libxrp_host_hosted_a-xrp_linux.Po b/driver/xrp-user/xrp-host/hosted/.deps/libxrp_host_hosted_a-xrp_linux.Po new file mode 100644 index 0000000..9fae5cc --- /dev/null +++ b/driver/xrp-user/xrp-host/hosted/.deps/libxrp_host_hosted_a-xrp_linux.Po @@ -0,0 +1,298 @@ +hosted/libxrp_host_hosted_a-xrp_linux.o: hosted/xrp_linux.c \ + /usr/include/stdc-predef.h /usr/include/fcntl.h /usr/include/features.h \ + /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/bits/long-double.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h \ + /usr/include/x86_64-linux-gnu/bits/fcntl.h \ + /usr/include/x86_64-linux-gnu/bits/fcntl-linux.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h \ + /usr/include/x86_64-linux-gnu/bits/stat.h \ + /usr/include/x86_64-linux-gnu/bits/fcntl2.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stdint.h /usr/include/stdint.h \ + /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ + /usr/include/x86_64-linux-gnu/bits/wchar.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-intn.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h /usr/include/stdio.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stddef.h \ + /usr/include/x86_64-linux-gnu/bits/types/__FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/FILE.h \ + /usr/include/x86_64-linux-gnu/bits/libio.h \ + /usr/include/x86_64-linux-gnu/bits/_G_config.h \ + /usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h \ + /usr/lib/gcc/x86_64-linux-gnu/7/include/stdarg.h \ + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ + /usr/include/x86_64-linux-gnu/bits/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/stdio2.h /usr/include/stdlib.h \ + /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h \ + /usr/include/x86_64-linux-gnu/bits/floatn.h \ + /usr/include/x86_64-linux-gnu/bits/floatn-common.h \ + /usr/include/x86_64-linux-gnu/sys/types.h \ + /usr/include/x86_64-linux-gnu/bits/types/clock_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/clockid_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/time_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/timer_t.h /usr/include/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap-16.h \ + /usr/include/x86_64-linux-gnu/bits/uintn-identity.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ + /usr/include/x86_64-linux-gnu/bits/types/sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h \ + /usr/include/x86_64-linux-gnu/bits/select2.h \ + /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ + /usr/include/x86_64-linux-gnu/bits/sysmacros.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h \ + /usr/include/x86_64-linux-gnu/bits/thread-shared-types.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h \ + /usr/include/alloca.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib.h /usr/include/string.h \ + /usr/include/x86_64-linux-gnu/bits/types/locale_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__locale_t.h \ + /usr/include/strings.h \ + /usr/include/x86_64-linux-gnu/bits/strings_fortified.h \ + /usr/include/x86_64-linux-gnu/bits/string_fortified.h \ + /usr/include/x86_64-linux-gnu/sys/ioctl.h \ + /usr/include/x86_64-linux-gnu/bits/ioctls.h \ + /usr/include/x86_64-linux-gnu/asm/ioctls.h \ + /usr/include/asm-generic/ioctls.h /usr/include/linux/ioctl.h \ + /usr/include/x86_64-linux-gnu/asm/ioctl.h \ + /usr/include/asm-generic/ioctl.h \ + /usr/include/x86_64-linux-gnu/bits/ioctl-types.h \ + /usr/include/x86_64-linux-gnu/sys/ttydefaults.h \ + /usr/include/x86_64-linux-gnu/sys/stat.h /usr/include/unistd.h \ + /usr/include/x86_64-linux-gnu/bits/posix_opt.h \ + /usr/include/x86_64-linux-gnu/bits/environments.h \ + /usr/include/x86_64-linux-gnu/bits/confname.h \ + /usr/include/x86_64-linux-gnu/bits/getopt_posix.h \ + /usr/include/x86_64-linux-gnu/bits/getopt_core.h \ + /usr/include/x86_64-linux-gnu/bits/unistd.h ../xrp-common/xrp_types.h \ + xrp_host_common.h xrp_atomic.h thread-pthread/xrp_thread_impl.h \ + /usr/include/pthread.h /usr/include/sched.h \ + /usr/include/x86_64-linux-gnu/bits/sched.h \ + /usr/include/x86_64-linux-gnu/bits/cpu-set.h /usr/include/time.h \ + /usr/include/x86_64-linux-gnu/bits/time.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_tm.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h \ + /usr/include/x86_64-linux-gnu/bits/setjmp.h hosted/xrp_host_impl.h \ + ../xrp_api.h thread-pthread/xrp_queue_impl.h xrp_threaded_queue.h \ + hosted/xrp_host_impl.h ../xrp-kernel/xrp_kernel_defs.h + +/usr/include/stdc-predef.h: + +/usr/include/fcntl.h: + +/usr/include/features.h: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/usr/include/x86_64-linux-gnu/bits/long-double.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/usr/include/x86_64-linux-gnu/bits/types.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/include/x86_64-linux-gnu/bits/fcntl.h: + +/usr/include/x86_64-linux-gnu/bits/fcntl-linux.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h: + +/usr/include/x86_64-linux-gnu/bits/stat.h: + +/usr/include/x86_64-linux-gnu/bits/fcntl2.h: + +/usr/lib/gcc/x86_64-linux-gnu/7/include/stdint.h: + +/usr/include/stdint.h: + +/usr/include/x86_64-linux-gnu/bits/libc-header-start.h: + +/usr/include/x86_64-linux-gnu/bits/wchar.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-intn.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-uintn.h: + +/usr/include/stdio.h: + +/usr/lib/gcc/x86_64-linux-gnu/7/include/stddef.h: + +/usr/include/x86_64-linux-gnu/bits/types/__FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/FILE.h: + +/usr/include/x86_64-linux-gnu/bits/libio.h: + +/usr/include/x86_64-linux-gnu/bits/_G_config.h: + +/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h: + +/usr/lib/gcc/x86_64-linux-gnu/7/include/stdarg.h: + +/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: + +/usr/include/x86_64-linux-gnu/bits/sys_errlist.h: + +/usr/include/x86_64-linux-gnu/bits/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/stdio2.h: + +/usr/include/stdlib.h: + +/usr/include/x86_64-linux-gnu/bits/waitflags.h: + +/usr/include/x86_64-linux-gnu/bits/waitstatus.h: + +/usr/include/x86_64-linux-gnu/bits/floatn.h: + +/usr/include/x86_64-linux-gnu/bits/floatn-common.h: + +/usr/include/x86_64-linux-gnu/sys/types.h: + +/usr/include/x86_64-linux-gnu/bits/types/clock_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/clockid_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/time_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/timer_t.h: + +/usr/include/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap-16.h: + +/usr/include/x86_64-linux-gnu/bits/uintn-identity.h: + +/usr/include/x86_64-linux-gnu/sys/select.h: + +/usr/include/x86_64-linux-gnu/bits/select.h: + +/usr/include/x86_64-linux-gnu/bits/types/sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h: + +/usr/include/x86_64-linux-gnu/bits/select2.h: + +/usr/include/x86_64-linux-gnu/sys/sysmacros.h: + +/usr/include/x86_64-linux-gnu/bits/sysmacros.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: + +/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h: + +/usr/include/alloca.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-float.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib.h: + +/usr/include/string.h: + +/usr/include/x86_64-linux-gnu/bits/types/locale_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__locale_t.h: + +/usr/include/strings.h: + +/usr/include/x86_64-linux-gnu/bits/strings_fortified.h: + +/usr/include/x86_64-linux-gnu/bits/string_fortified.h: + +/usr/include/x86_64-linux-gnu/sys/ioctl.h: + +/usr/include/x86_64-linux-gnu/bits/ioctls.h: + +/usr/include/x86_64-linux-gnu/asm/ioctls.h: + +/usr/include/asm-generic/ioctls.h: + +/usr/include/linux/ioctl.h: + +/usr/include/x86_64-linux-gnu/asm/ioctl.h: + +/usr/include/asm-generic/ioctl.h: + +/usr/include/x86_64-linux-gnu/bits/ioctl-types.h: + +/usr/include/x86_64-linux-gnu/sys/ttydefaults.h: + +/usr/include/x86_64-linux-gnu/sys/stat.h: + +/usr/include/unistd.h: + +/usr/include/x86_64-linux-gnu/bits/posix_opt.h: + +/usr/include/x86_64-linux-gnu/bits/environments.h: + +/usr/include/x86_64-linux-gnu/bits/confname.h: + +/usr/include/x86_64-linux-gnu/bits/getopt_posix.h: + +/usr/include/x86_64-linux-gnu/bits/getopt_core.h: + +/usr/include/x86_64-linux-gnu/bits/unistd.h: + +../xrp-common/xrp_types.h: + +xrp_host_common.h: + +xrp_atomic.h: + +thread-pthread/xrp_thread_impl.h: + +/usr/include/pthread.h: + +/usr/include/sched.h: + +/usr/include/x86_64-linux-gnu/bits/sched.h: + +/usr/include/x86_64-linux-gnu/bits/cpu-set.h: + +/usr/include/time.h: + +/usr/include/x86_64-linux-gnu/bits/time.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h: + +/usr/include/x86_64-linux-gnu/bits/setjmp.h: + +hosted/xrp_host_impl.h: + +../xrp_api.h: + +thread-pthread/xrp_queue_impl.h: + +xrp_threaded_queue.h: + +hosted/xrp_host_impl.h: + +../xrp-kernel/xrp_kernel_defs.h: diff --git a/driver/xrp-user/xrp-host/hosted/.dirstamp b/driver/xrp-user/xrp-host/hosted/.dirstamp new file mode 100644 index 0000000..e69de29 diff --git a/driver/xrp-user/xrp-host/hosted/xrp_host_impl.h b/driver/xrp-user/xrp-host/hosted/xrp_host_impl.h new file mode 100644 index 0000000..3ede50a --- /dev/null +++ b/driver/xrp-user/xrp-host/hosted/xrp_host_impl.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2016 - 2018 Cadence Design Systems Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef _XRP_LINUX_NATIVE_H +#define _XRP_LINUX_NATIVE_H + +#include +#include "xrp_thread_impl.h" +#include "xrp_queue_impl.h" + +struct xrp_device_impl { + int fd; +}; + +struct xrp_buffer_impl { +}; + +struct xrp_queue_impl { + struct xrp_request_queue queue; +}; + +void xrp_impl_release_device(struct xrp_device *device); + +void xrp_impl_create_device_buffer(struct xrp_device *device, + struct xrp_buffer *buffer, + size_t size, + enum xrp_status *status); +void xrp_impl_release_device_buffer(struct xrp_buffer *buffer); + +void xrp_impl_create_queue(struct xrp_queue *queue, + enum xrp_status *status); +void xrp_impl_release_queue(struct xrp_queue *queue); + +void xrp_impl_create_report(struct xrp_device *device, + struct xrp_report *report, + size_t size, + enum xrp_status *status); + +void xrp_impl_release_report(struct xrp_device *device, + struct xrp_report *report,enum xrp_status *status); +int xrp_impl_add_report_item(struct xrp_report *report, + int (*cb)(void*context,void*data), + void* context, + size_t data_size); +int xrp_impl_add_report_item_with_id(struct xrp_report *report, + int (*cb)(void*context,void*data), + int report_id, + void* context, + size_t data_size); + +void xrp_impl_remove_report_item(struct xrp_report *report,int report_id); +void xrp_impl_import_dma_buf(struct xrp_device *device, int fd,enum xrp_access_flags,uint64_t *phy_addr, + uint64_t *user_addr,size_t* size,enum xrp_status *status); + +void xrp_impl_release_dma_buf(struct xrp_device *device, int fd,enum xrp_status *status); +#endif diff --git a/driver/xrp-user/xrp-host/hosted/xrp_linux.c b/driver/xrp-user/xrp-host/hosted/xrp_linux.c new file mode 100644 index 0000000..be78a47 --- /dev/null +++ b/driver/xrp-user/xrp-host/hosted/xrp_linux.c @@ -0,0 +1,478 @@ +/* + * Copyright (c) 2016 - 2018 Cadence Design Systems Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "xrp_types.h" +#include "xrp_host_common.h" +#include "xrp_host_impl.h" +#include "xrp_kernel_defs.h" +#include "xrp_report.h" +#include "dsp_common.h" +struct xrp_request { + struct xrp_queue_item q; + void *in_data; + void *out_data; + size_t in_data_size; + size_t out_data_size; + struct xrp_buffer_group *buffer_group; + struct xrp_event *event; +}; + +/* Device API. */ + +struct xrp_device *xrp_open_device(int idx, enum xrp_status *status) +{ + struct xrp_device *device; + char name[sizeof("/dev/xvp") + sizeof(int) * 4]; + int fd; + + sprintf(name, "/dev/xvp%u", idx); + fd = open(name, O_RDWR); + if (fd == -1) { + set_status(status, XRP_STATUS_FAILURE); + return NULL; + } + device = alloc_refcounted(sizeof(*device)); + if (!device) { + set_status(status, XRP_STATUS_FAILURE); + return NULL; + } + device->impl.fd = fd; + set_status(status, XRP_STATUS_SUCCESS); + return device; +} + +void xrp_impl_release_device(struct xrp_device *device) +{ + close(device->impl.fd); +} + + +/* Buffer API. */ + +void xrp_impl_create_device_buffer(struct xrp_device *device, + struct xrp_buffer *buffer, + size_t size, + enum xrp_status *status) +{ + struct xrp_ioctl_alloc ioctl_alloc = { + .size = size, + }; + int ret; + + xrp_retain_device(device); + buffer->device = device; + ret = ioctl(buffer->device->impl.fd, XRP_IOCTL_ALLOC, &ioctl_alloc); + if (ret < 0) { + xrp_release_device(buffer->device); + set_status(status, XRP_STATUS_FAILURE); + return; + } + buffer->ptr = (void *)(uintptr_t)ioctl_alloc.addr; + buffer->size = size; + buffer->phy_addr = ioctl_alloc.paddr; + set_status(status, XRP_STATUS_SUCCESS); +} + +void xrp_impl_release_device_buffer(struct xrp_buffer *buffer) +{ + struct xrp_ioctl_alloc ioctl_alloc = { + .addr = (uintptr_t)buffer->ptr, + }; + ioctl(buffer->device->impl.fd, + XRP_IOCTL_FREE, &ioctl_alloc); + + xrp_release_device(buffer->device); +} + +/* Queue API. */ + +static void _xrp_run_command(struct xrp_queue *queue, + const void *in_data, size_t in_data_size, + void *out_data, size_t out_data_size, + struct xrp_buffer_group *buffer_group, + enum xrp_status *status) +{ + int ret; + + if (buffer_group) + xrp_mutex_lock(&buffer_group->mutex); + { + size_t n_buffers = buffer_group ? buffer_group->n_buffers : 0; + struct xrp_ioctl_buffer ioctl_buffer[n_buffers];/* TODO */ + struct xrp_ioctl_queue ioctl_queue = { + .flags = (queue->use_nsid ? XRP_QUEUE_FLAG_NSID : 0) | + ((queue->priority << XRP_QUEUE_FLAG_PRIO_SHIFT) & + XRP_QUEUE_FLAG_PRIO), + .in_data_size = in_data_size, + .out_data_size = out_data_size, + .buffer_size = n_buffers * + sizeof(struct xrp_ioctl_buffer), + .in_data_addr = (uintptr_t)in_data, + .out_data_addr = (uintptr_t)out_data, + .buffer_addr = (uintptr_t)ioctl_buffer, + .nsid_addr = (uintptr_t)queue->nsid, + }; + size_t i; + + for (i = 0; i < n_buffers; ++i) { + ioctl_buffer[i] = (struct xrp_ioctl_buffer){ + .flags = buffer_group->buffer[i].access_flags, + .size = buffer_group->buffer[i].buffer->size, + .addr = (uintptr_t)buffer_group->buffer[i].buffer->ptr, + }; + } + if (buffer_group) + xrp_mutex_unlock(&buffer_group->mutex); + + ret = ioctl(queue->device->impl.fd, + XRP_IOCTL_QUEUE, &ioctl_queue); + } + // printf("%s, user out data\n",__func__); + if (ret < 0) + set_status(status, XRP_STATUS_FAILURE); + else + set_status(status, XRP_STATUS_SUCCESS); +} + +static void xrp_request_process(struct xrp_queue_item *q, + void *context) +{ + enum xrp_status status; + struct xrp_request *rq = (struct xrp_request *)q; + + _xrp_run_command(context, + rq->in_data, rq->in_data_size, + rq->out_data, rq->out_data_size, + rq->buffer_group, + &status); + + if (rq->buffer_group) + xrp_release_buffer_group(rq->buffer_group); + + if (rq->event) { + xrp_impl_broadcast_event(rq->event, status); + xrp_release_event(rq->event); + } + // printf("%s,get resp with event %p!\n",__func__,rq->event); + free(rq->in_data); + free(rq); +} + +void xrp_impl_create_queue(struct xrp_queue *queue, + enum xrp_status *status) +{ + xrp_queue_init(&queue->impl.queue, queue->priority, + queue, xrp_request_process); + set_status(status, XRP_STATUS_SUCCESS); +} + +void xrp_impl_release_queue(struct xrp_queue *queue) +{ + xrp_queue_destroy(&queue->impl.queue); +} + +/* Communication API */ + +void xrp_enqueue_command(struct xrp_queue *queue, + const void *in_data, size_t in_data_size, + void *out_data, size_t out_data_size, + struct xrp_buffer_group *buffer_group, + struct xrp_event **evt, + enum xrp_status *status) +{ + struct xrp_request *rq; + void *in_data_copy; + + rq = malloc(sizeof(*rq)); + in_data_copy = malloc(in_data_size); + + if (!rq || (in_data_size && !in_data_copy)) { + free(in_data_copy); + free(rq); + set_status(status, XRP_STATUS_FAILURE); + return; + } + + memcpy(in_data_copy, in_data, in_data_size); + rq->in_data = in_data_copy; + rq->in_data_size = in_data_size; + rq->out_data = out_data; + rq->out_data_size = out_data_size; + + if (evt) { + struct xrp_event *event = xrp_event_create(); + + if (!event) { + free(rq->in_data); + free(rq); + set_status(status, XRP_STATUS_FAILURE); + return; + } + xrp_retain_queue(queue); + event->queue = queue; + *evt = event; + xrp_retain_event(event); + rq->event = event; + } else { + rq->event = NULL; + } + + if (buffer_group) + xrp_retain_buffer_group(buffer_group); + rq->buffer_group = buffer_group; + + set_status(status, XRP_STATUS_SUCCESS); + xrp_queue_push(&queue->impl.queue, &rq->q); +} + +static struct xrp_report *reporter; + +void xrp_reporter_sig_handler() +{ + // printf("%s\n",__func__); + struct xrp_report_buffer *report_buffer; + if(!reporter || !reporter->report_buf) + { + return; + } + report_buffer = (struct xrp_report_buffer *)reporter->report_buf; + // printf("buffer:%lx,id:%d,data:%x,%x,%x,%x\n",report_buffer,report_buffer->report_id,report_buffer->data[0],report_buffer->data[1],report_buffer->data[2],report_buffer->data[3]); + + xrp_process_report(&reporter->list,report_buffer->data,report_buffer->report_id); +} + + +int xrp_add_report_item_with_id(struct xrp_report *report, + int (*cb)(void*context,void*data), + int report_id, + void* context, + size_t data_size) +{ + // int id; + // // set_status(status, XRP_STATUS_SUCCESS); + // id =xrp_alloc_report_id(&report->list); + if(report_id<0 || !report) + { + // set_status(status, XRP_STATUS_FAILURE); + return -1; + } + if(data_size>report->buf_size) + { + //realloc() + DSP_PRINT(WARNING,"report instance size %d is exceed limit %d\n",data_size,report->buf_size); + // set_status(status, XRP_STATUS_FAILURE); + return -1; + } + char *report_buf = malloc(data_size); + if(!report_buf) + { + // set_status(status, XRP_STATUS_FAILURE); + return -1; + } + struct xrp_report_item new_item={ + .report_id = report_id, + .buf = report_buf, + .size = data_size, + .context = context, + .fn = cb, + }; + + DSP_PRINT(DEBUG,"add report id:%d\n", report_id); + if(xrp_add_report(&report->list,&new_item)) + { + free(report_buf); + return -1; + } + DSP_PRINT(INFO,"the report item: %d is added sucessfully\n",report_id); + return report_id; + +} +int xrp_add_report_item(struct xrp_report *report, + int (*cb)(void*context,void*data), + void* context, + size_t data_size) +{ + int id; + id =xrp_alloc_report_id(&report->list); + if(id<0) + { + return -1; + } + return xrp_add_report_item_with_id(report,cb,id,context,data_size); +} + + + + +void xrp_remove_report_item(struct xrp_report *report,int report_id) +{ + int id; + struct xrp_report_item* item=xrp_get_report_entry(&report->list,report_id); + free(item->buf); + xrp_remove_report(&report->list,report_id); +} + +void xrp_impl_create_report(struct xrp_device *device, + struct xrp_report *report, + size_t size, + enum xrp_status *status) +{ + // char *report_buf = malloc(size+4); + // if(!report_buf) + // { + // set_status(status, XRP_STATUS_FAILURE); + // return; + // } + + struct xrp_ioctl_alloc ioctl_alloc = { + .addr = (uintptr_t)NULL, + .size = size, + }; + int ret; + + xrp_retain_device(device); + report->device = device; + ret = ioctl(report->device->impl.fd, XRP_IOCTL_REPORT_CREATE, &ioctl_alloc); + if (ret < 0) { + // free(report_buf); + set_status(status, XRP_STATUS_FAILURE); + return; + } + if(ioctl_alloc.addr ==NULL) + { + DSP_PRINT(INFO,"alloc report buffer fail\n"); + set_status(status, XRP_STATUS_FAILURE); + return ; + } + report->report_buf = (void *)(uintptr_t)ioctl_alloc.addr; + // printf("buf:%lx,report:x\n",ioctl_alloc.addr,report); + report->buf_size = size; + report->list.queue.head=NULL; + reporter=report; + signal(SIGIO, xrp_reporter_sig_handler); /* sigaction() is better */ + fcntl(report->device->impl.fd, F_SETOWN, getpid()); + int oflags = fcntl(report->device->impl.fd, F_GETFL); + fcntl(report->device->impl.fd, F_SETFL, oflags | FASYNC); + set_status(status, XRP_STATUS_SUCCESS); + DSP_PRINT(INFO,"buf:%lx,user space report create\n",ioctl_alloc.addr); +} +void xrp_impl_release_report(struct xrp_device *device, + struct xrp_report *report,enum xrp_status *status) +{ + struct xrp_ioctl_alloc ioctl_alloc = { + .addr = (uintptr_t)report->report_buf, + .size = report->buf_size, + }; + int ret = ioctl(report->device->impl.fd, XRP_IOCTL_REPORT_RELEASE, &ioctl_alloc); + if (ret < 0) { + // free(report_buf); + set_status(status, XRP_STATUS_FAILURE); + return; + } + report->report_buf=NULL; + xrp_release_device(device); + set_status(status, XRP_STATUS_SUCCESS); + return; +} + +void xrp_import_dma_buf(struct xrp_device *device, int fd,enum xrp_access_flags flag,uint64_t *phy_addr, + uint64_t *user_addr,size_t* size,enum xrp_status *status) +{ + struct xrp_dma_buf dma_buf; + + if(fd < 0 || !(flag&XRP_FLAG_READ_WRITE)) + { + set_status(status, XRP_STATUS_FAILURE); + DSP_PRINT(DEBUG,"param check fail\n"); + return; + } + dma_buf.fd = fd; + dma_buf.flags = flag; + int ret = ioctl(device->impl.fd, XRP_IOCTL_DMABUF_IMPORT,&dma_buf); + + if (ret < 0) { + DSP_PRINT(DEBUG,"_DMABUF_IMPORT fail\n"); + set_status(status, XRP_STATUS_FAILURE); + } + else + { + *phy_addr = dma_buf.paddr; + *user_addr = dma_buf.addr; + *size = dma_buf.size; + set_status(status, XRP_STATUS_SUCCESS); + } + return; +} + +void xrp_release_dma_buf(struct xrp_device *device, int fd,enum xrp_status *status) +{ + if(fd < 0) + { + set_status(status, XRP_STATUS_FAILURE); + return; + } + int ret = ioctl(device->impl.fd, XRP_IOCTL_DMABUF_RELEASE,&fd); + + if (ret < 0) { + set_status(status, XRP_STATUS_FAILURE); + } + else + { + set_status(status, XRP_STATUS_SUCCESS); + } + return ; + +} + +void xrp_flush_dma_buf(struct xrp_device *device, int fd,enum xrp_access_flags flag,enum xrp_status *status) +{ + struct xrp_dma_buf dma_buf; + dma_buf.fd = fd; + dma_buf.flags = flag; + if(fd < 0) + { + set_status(status, XRP_STATUS_FAILURE); + return; + } + + int ret = ioctl(device->impl.fd, XRP_IOCTL_DMABUF_SYNC,&dma_buf); + + if (ret < 0) { + set_status(status, XRP_STATUS_FAILURE); + } + else + { + set_status(status, XRP_STATUS_SUCCESS); + } +} \ No newline at end of file diff --git a/driver/xrp-user/xrp-host/thread-pthread/xrp_queue_impl.h b/driver/xrp-user/xrp-host/thread-pthread/xrp_queue_impl.h new file mode 100644 index 0000000..8764272 --- /dev/null +++ b/driver/xrp-user/xrp-host/thread-pthread/xrp_queue_impl.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2018 Cadence Design Systems Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "xrp_threaded_queue.h" diff --git a/driver/xrp-user/xrp-host/thread-pthread/xrp_thread_impl.h b/driver/xrp-user/xrp-host/thread-pthread/xrp_thread_impl.h new file mode 100644 index 0000000..05dfe59 --- /dev/null +++ b/driver/xrp-user/xrp-host/thread-pthread/xrp_thread_impl.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2018 Cadence Design Systems Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef _XRP_THREAD_PTHREAD_IMPL_H +#define _XRP_THREAD_PTHREAD_IMPL_H + +#include + +typedef pthread_t xrp_thread; +typedef pthread_mutex_t xrp_mutex; + +typedef struct xrp_cond { + pthread_mutex_t mutex; + pthread_cond_t cond; +} xrp_cond; + +static inline void xrp_mutex_init(xrp_mutex *p) +{ + pthread_mutex_init(p, NULL); +} + +static inline void xrp_mutex_lock(xrp_mutex *p) +{ + pthread_mutex_lock(p); +} + +static inline void xrp_mutex_unlock(xrp_mutex *p) +{ + pthread_mutex_unlock(p); +} + +static inline void xrp_mutex_destroy(xrp_mutex *p) +{ + pthread_mutex_destroy(p); +} + +static inline void xrp_cond_init(xrp_cond *p) +{ + pthread_mutex_init(&p->mutex, NULL); + pthread_cond_init(&p->cond, NULL); +} + +static inline void xrp_cond_lock(xrp_cond *p) +{ + pthread_mutex_lock(&p->mutex); +} + +static inline void xrp_cond_unlock(xrp_cond *p) +{ + pthread_mutex_unlock(&p->mutex); +} + +static inline void xrp_cond_broadcast(xrp_cond *p) +{ + pthread_cond_broadcast(&p->cond); +} + +static inline void xrp_cond_wait(xrp_cond *p) +{ + pthread_cond_wait(&p->cond, &p->mutex); +} + +static inline void xrp_cond_destroy(xrp_cond *p) +{ + pthread_mutex_destroy(&p->mutex); + pthread_cond_destroy(&p->cond); +} + +static inline int xrp_thread_create(xrp_thread *thread, int priority, + void *(*thread_func)(void *), + void *p) +{ + (void)priority; + return pthread_create(thread, NULL, thread_func, p) == 0; +} + +static inline int xrp_thread_join(xrp_thread *thread) +{ + return pthread_join(*thread, NULL) == 0; +} + +static inline int xrp_thread_detach(xrp_thread *thread) +{ + return pthread_detach(*thread) == 0; +} + +#endif diff --git a/driver/xrp-user/xrp-host/xrp_atomic.h b/driver/xrp-user/xrp-host/xrp_atomic.h new file mode 100644 index 0000000..68c20f5 --- /dev/null +++ b/driver/xrp-user/xrp-host/xrp_atomic.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2018 Cadence Design Systems Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef _XRP_ATOMIC_H +#define _XRP_ATOMIC_H + +#if defined(__STDC_NO_ATOMICS__) +#warning The compiler does not support atomics, reference counting may not be thread safe +#endif + +#endif diff --git a/driver/xrp-user/xrp-host/xrp_host_common.c b/driver/xrp-user/xrp-host/xrp_host_common.c new file mode 100644 index 0000000..904e871 --- /dev/null +++ b/driver/xrp-user/xrp-host/xrp_host_common.c @@ -0,0 +1,482 @@ +/* + * Copyright (c) 2016 - 2018 Cadence Design Systems Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include + +#include "xrp_api.h" +#include "xrp_host_common.h" +#include "dsp_common.h" + +/* Device API. */ + +void xrp_retain_device(struct xrp_device *device) +{ + DSP_PRINT(DEBUG," ref %d\n",device->ref.count); + retain_refcounted(device); +} + +void xrp_release_device(struct xrp_device *device) +{ + DSP_PRINT(DEBUG,"ref %d\n",device->ref.count); + if (last_release_refcounted(device)) { + xrp_impl_release_device(device); + free(device); + } +} + + +/* Buffer API. */ + +struct xrp_buffer *xrp_create_buffer(struct xrp_device *device, + size_t size, void *host_ptr, + enum xrp_status *status) +{ + struct xrp_buffer *buf; + + if (!host_ptr && !device) { + set_status(status, XRP_STATUS_FAILURE); + return NULL; + } + + buf = alloc_refcounted(sizeof(*buf)); + + if (!buf) { + set_status(status, XRP_STATUS_FAILURE); + return NULL; + } + + if (!host_ptr) { + enum xrp_status s; + + buf->type = XRP_BUFFER_TYPE_DEVICE; + xrp_impl_create_device_buffer(device, buf, size, &s); + if (s != XRP_STATUS_SUCCESS) { + free(buf); + buf = NULL; + } + set_status(status, s); + } else { + buf->type = XRP_BUFFER_TYPE_HOST; + buf->ptr = host_ptr; + buf->size = size; + set_status(status, XRP_STATUS_SUCCESS); + } + // printf("%s,Debug V:%llx,P:%llx\n",__FUNCTION__,buf->ptr,buf->phy_addr); + return buf; +} + +void xrp_retain_buffer(struct xrp_buffer *buffer) +{ + retain_refcounted(buffer); +} + +void xrp_release_buffer(struct xrp_buffer *buffer) +{ + DSP_PRINT(DEBUG,"ref:%d\n",buffer->ref.count); + if (last_release_refcounted(buffer)) { + // printf("%s,ref:%d\n",__FUNCTION__,buffer->ref.count); + if (buffer->type == XRP_BUFFER_TYPE_DEVICE) + xrp_impl_release_device_buffer(buffer); + free(buffer); + } +} + +void *xrp_map_buffer(struct xrp_buffer *buffer, size_t offset, size_t size, + enum xrp_access_flags map_flags, enum xrp_status *status) +{ + if (offset <= buffer->size && + size <= buffer->size - offset) { + retain_refcounted(buffer); + (void)++buffer->map_count; + buffer->map_flags |= map_flags; + set_status(status, XRP_STATUS_SUCCESS); + return (char *)buffer->ptr + offset; + } + set_status(status, XRP_STATUS_FAILURE); + return NULL; +} + +void xrp_unmap_buffer(struct xrp_buffer *buffer, void *p, + enum xrp_status *status) +{ + if (p >= buffer->ptr && + (size_t)((char *)p - (char *)buffer->ptr) <= buffer->size) { + (void)--buffer->map_count; + xrp_release_buffer(buffer); + set_status(status, XRP_STATUS_SUCCESS); + } else { + set_status(status, XRP_STATUS_FAILURE); + } +} + +void xrp_buffer_get_info(struct xrp_buffer *buffer, enum xrp_buffer_info info, + void *out, size_t out_sz, enum xrp_status *status) +{ + enum xrp_status s = XRP_STATUS_FAILURE; + size_t sz; + void *ptr; + + switch (info) { + case XRP_BUFFER_SIZE_SIZE_T: + sz = sizeof(buffer->size); + ptr = &buffer->size; + break; + + case XRP_BUFFER_HOST_POINTER_PTR: + if (buffer->type != XRP_BUFFER_TYPE_HOST) { + static void *p = NULL; + ptr = &p; + } else { + ptr = &buffer->ptr; + } + sz = sizeof(void *); + break; + case XRP_BUFFER_PHY_ADDR: + ptr = &buffer->phy_addr; + sz = sizeof(void *); + break; + case XRP_BUFFER_USER_ADDR: + ptr = &buffer->ptr; + sz = sizeof(void *); + break; + default: + goto out; + } + + if (sz == out_sz) { + memcpy(out, ptr, sz); + s = XRP_STATUS_SUCCESS; + } +out: + set_status(status, s); +} + + +/* Buffer group API. */ + +struct xrp_buffer_group *xrp_create_buffer_group(enum xrp_status *status) +{ + struct xrp_buffer_group *group = alloc_refcounted(sizeof(*group)); + + if (group) { + xrp_mutex_init(&group->mutex); + set_status(status, XRP_STATUS_SUCCESS); + } else { + set_status(status, XRP_STATUS_FAILURE); + } + + return group; +} + +void xrp_retain_buffer_group(struct xrp_buffer_group *group) +{ + retain_refcounted(group); +} + +void xrp_release_buffer_group(struct xrp_buffer_group *group) +{ + if (last_release_refcounted(group)) { + size_t i; + + xrp_mutex_lock(&group->mutex); + for (i = 0; i < group->n_buffers; ++i) + xrp_release_buffer(group->buffer[i].buffer); + xrp_mutex_unlock(&group->mutex); + xrp_mutex_destroy(&group->mutex); + free(group->buffer); + free(group); + } +} + +size_t xrp_add_buffer_to_group(struct xrp_buffer_group *group, + struct xrp_buffer *buffer, + enum xrp_access_flags access_flags, + enum xrp_status *status) +{ + size_t n_buffers; + + xrp_mutex_lock(&group->mutex); + if (group->n_buffers == group->capacity) { + struct xrp_buffer_group_record *r = + realloc(group->buffer, + sizeof(struct xrp_buffer_group_record) * + ((group->capacity + 2) * 2)); + + if (r == NULL) { + xrp_mutex_unlock(&group->mutex); + set_status(status, XRP_STATUS_FAILURE); + return -1; + } + group->buffer = r; + group->capacity = (group->capacity + 2) * 2; + } + + xrp_retain_buffer(buffer); + group->buffer[group->n_buffers].buffer = buffer; + group->buffer[group->n_buffers].access_flags = access_flags; + n_buffers = group->n_buffers++; + xrp_mutex_unlock(&group->mutex); + set_status(status, XRP_STATUS_SUCCESS); + return n_buffers; +} + +void xrp_set_buffer_in_group(struct xrp_buffer_group *group, + size_t index, + struct xrp_buffer *buffer, + enum xrp_access_flags access_flags, + enum xrp_status *status) +{ + struct xrp_buffer *old_buffer; + + xrp_retain_buffer(buffer); + + xrp_mutex_lock(&group->mutex); + if (index < group->n_buffers) { + old_buffer = group->buffer[index].buffer; + group->buffer[index].buffer = buffer; + group->buffer[index].access_flags = access_flags; + set_status(status, XRP_STATUS_SUCCESS); + } else { + old_buffer = buffer; + set_status(status, XRP_STATUS_FAILURE); + } + xrp_mutex_unlock(&group->mutex); + xrp_release_buffer(old_buffer); +} + +struct xrp_buffer *xrp_get_buffer_from_group(struct xrp_buffer_group *group, + size_t idx, + enum xrp_status *status) +{ + struct xrp_buffer *buffer = NULL; + + xrp_mutex_lock(&group->mutex); + if (idx < group->n_buffers) { + buffer = group->buffer[idx].buffer; + // xrp_retain_buffer(buffer); temp fix for buffer ref; + set_status(status, XRP_STATUS_SUCCESS); + } else { + set_status(status, XRP_STATUS_FAILURE); + } + xrp_mutex_unlock(&group->mutex); + return buffer; +} + +void xrp_buffer_group_get_info(struct xrp_buffer_group *group, + enum xrp_buffer_group_info info, size_t idx, + void *out, size_t out_sz, + enum xrp_status *status) +{ + enum xrp_status s = XRP_STATUS_FAILURE; + size_t sz; + void *ptr; + + xrp_mutex_lock(&group->mutex); + switch (info) { + case XRP_BUFFER_GROUP_BUFFER_FLAGS_ENUM: + if (idx >= group->n_buffers) + goto out; + sz = sizeof(group->buffer[idx].access_flags); + ptr = &group->buffer[idx].access_flags; + break; + + case XRP_BUFFER_GROUP_SIZE_SIZE_T: + sz = sizeof(group->n_buffers); + ptr = &group->n_buffers; + break; + + default: + goto out; + } + + if (sz == out_sz) { + memcpy(out, ptr, sz); + s = XRP_STATUS_SUCCESS; + } +out: + xrp_mutex_unlock(&group->mutex); + set_status(status, s); +} + + +/* Queue API. */ + +struct xrp_queue *xrp_create_queue(struct xrp_device *device, + enum xrp_status *status) +{ + return xrp_create_ns_queue(device, NULL, status); +} + +struct xrp_queue *xrp_create_ns_queue(struct xrp_device *device, + const void *nsid, + enum xrp_status *status) +{ + return xrp_create_nsp_queue(device, nsid, 0, status); +} + +struct xrp_queue *xrp_create_nsp_queue(struct xrp_device *device, + const void *nsid, + int priority, + enum xrp_status *status) +{ + struct xrp_queue *queue; + + xrp_retain_device(device); + queue = alloc_refcounted(sizeof(*queue)); + + if (!queue) { + xrp_release_device(device); + set_status(status, XRP_STATUS_FAILURE); + return NULL; + } + + queue->device = device; + if (nsid) { + queue->use_nsid = 1; + memcpy(queue->nsid, nsid, XRP_NAMESPACE_ID_SIZE); + } + queue->priority = priority; + + xrp_impl_create_queue(queue, status); + + return queue; +} + +void xrp_retain_queue(struct xrp_queue *queue) +{ + retain_refcounted(queue); +} + +void xrp_release_queue(struct xrp_queue *queue) +{ + DSP_PRINT(DEBUG," ref %d\n",queue->ref.count); + if (last_release_refcounted(queue)) { + xrp_impl_release_queue(queue); + xrp_release_device(queue->device); + free(queue); + } +} + + +/* Event API. */ + +void xrp_retain_event(struct xrp_event *event) +{ + retain_refcounted(event); +} + +void xrp_release_event(struct xrp_event *event) +{ + DSP_PRINT(TRACE,"event %p ref:%d\n",event,event->ref.count); + if (last_release_refcounted(event)) { + xrp_impl_release_event(event); + xrp_release_queue(event->queue); + free(event); + } +} + +void xrp_event_status(struct xrp_event *event, enum xrp_status *status) +{ + set_status(status, event->status); +} + +/* Communication API */ + +void xrp_run_command_sync(struct xrp_queue *queue, + const void *in_data, size_t in_data_size, + void *out_data, size_t out_data_size, + struct xrp_buffer_group *buffer_group, + enum xrp_status *status) +{ + struct xrp_event *evt; + enum xrp_status s; + + xrp_enqueue_command(queue, in_data, in_data_size, + out_data, out_data_size, + buffer_group, &evt, &s); + if (s != XRP_STATUS_SUCCESS) { + set_status(status, s); + return; + } + xrp_wait(evt, NULL); + xrp_event_status(evt, status); + xrp_release_event(evt); +} + +/*reproter 机制的buffer 需要从用户态去allocated 通知DSP ,并且需要pingpong*/ +struct xrp_report *xrp_create_reporter(struct xrp_device *device,size_t size) +{ + struct xrp_report *report; + enum xrp_status status; + + report = alloc_refcounted(sizeof(*report)); + + if (!report) { + // set_status(status, XRP_STATUS_FAILURE); + return NULL; + } + + xrp_impl_create_report(device,report,size,&status); + if(XRP_STATUS_FAILURE ==status) + { + free(report); + return NULL; + } + return report; + +} + + +int xrp_release_reporter(struct xrp_device *device,struct xrp_report *report) +{ + + enum xrp_status status; + if (!report) { + // set_status(status, XRP_STATUS_FAILURE); + return 0; + } + if(last_release_refcounted(report)) + { + xrp_impl_release_report(device,report,&status); + + } + if(XRP_STATUS_FAILURE ==status) + { + DSP_PRINT(WARNING,"release report fail\n"); + return -1; + } + free(report); + return 0; +} +// struct xrp_report *xrp_add_report_itme(struct xrp_report *report,size_t size,enum xrp_status *status) +// { +// void xrp_impl_add_report_item(struct xrp_report *report, +// int (*cb)(void*context,void*data), +// void* context, +// size_t data_size, +// enum xrp_status *status) + +// } + diff --git a/driver/xrp-user/xrp-host/xrp_host_common.h b/driver/xrp-user/xrp-host/xrp_host_common.h new file mode 100644 index 0000000..006ab3e --- /dev/null +++ b/driver/xrp-user/xrp-host/xrp_host_common.h @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2016 - 2018 Cadence Design Systems Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef _XRP_HOST_COMMON_H +#define _XRP_HOST_COMMON_H + +#include +#include +#include "xrp_atomic.h" +#include "xrp_thread_impl.h" +#include "xrp_host_impl.h" +#include "xrp_report.h" + +struct xrp_refcounted { + _Atomic unsigned long count; +}; + +struct xrp_device { + struct xrp_refcounted ref; + struct xrp_device_impl impl; +}; + +struct xrp_buffer { + struct xrp_refcounted ref; + struct xrp_device *device; + enum { + XRP_BUFFER_TYPE_HOST, + XRP_BUFFER_TYPE_DEVICE, + } type; + void *ptr; + uint64_t phy_addr; + size_t size; + _Atomic unsigned long map_count; + enum xrp_access_flags map_flags; + struct xrp_buffer_impl impl; +}; + +struct xrp_buffer_group_record { + struct xrp_buffer *buffer; + enum xrp_access_flags access_flags; +}; + +struct xrp_buffer_group { + struct xrp_refcounted ref; + xrp_mutex mutex; + size_t n_buffers; + size_t capacity; + struct xrp_buffer_group_record *buffer; +}; + +struct xrp_queue { + struct xrp_refcounted ref; + struct xrp_device *device; + int use_nsid; + int priority; + char nsid[XRP_NAMESPACE_ID_SIZE]; + struct xrp_queue_impl impl; +}; + +struct xrp_event_link { + struct xrp_event *group; + struct xrp_event_link *next, *prev; +}; + +struct xrp_event { + struct xrp_refcounted ref; + struct xrp_queue *queue; + _Atomic enum xrp_status status; + struct xrp_event_impl impl; + struct xrp_event *group; + struct xrp_event_link *link; +}; + +struct xrp_report{ + + struct xrp_refcounted ref; + struct xrp_device *device; + struct xrp_report_list list; + + void *report_buf; + + int buf_size; + +}; + +/* Helpers */ + +static inline void set_status(enum xrp_status *status, enum xrp_status v) +{ + if (status) + *status = v; +} + +static inline void *alloc_refcounted(size_t sz) +{ + void *buf = calloc(1, sz); + struct xrp_refcounted *ref = buf; + + if (ref) + ref->count = 1; + + return buf; +} + +static inline void retain_refcounted(void *buf) +{ + struct xrp_refcounted *ref = buf; + (void)++ref->count; +} + +static inline int last_release_refcounted(void *buf) +{ + struct xrp_refcounted *ref = buf; + return --ref->count == 0; +} + + +#endif diff --git a/driver/xrp-user/xrp-host/xrp_report.c b/driver/xrp-user/xrp-host/xrp_report.c new file mode 100644 index 0000000..cc7f9cc --- /dev/null +++ b/driver/xrp-user/xrp-host/xrp_report.c @@ -0,0 +1,139 @@ +/* + + */ +#include +#include +#include +#include +#include +#include "xrp_debug.h" +#include "xrp_report.h" +#include "xrp_thread_impl.h" +#include "dsp_common.h" + + + +// void xrp_reporter_init(struct xrp_report_list *list) +// { + +// g_list=list; +// g_list->queue.head=NULL; +// } +struct xrp_report_item* xrp_get_report_entry(struct xrp_report_list *list,int id) +{ + struct xrp_report_entry *cur_entry=list->queue.head; + for(;cur_entry!=NULL;cur_entry=cur_entry->next) + { + if(((struct xrp_report_item *)cur_entry)->report_id == id) + { + + return (struct xrp_report_item*)cur_entry; + } + } + return NULL; +} + +void xrp_process_report(struct xrp_report_list *list,void* data,unsigned int id) +{ + struct xrp_report_item* report_item= xrp_get_report_entry(list,id); + if(!report_item) + { + DSP_PRINT(WARNING,"No valid report item by id (%d)\n",id); + return; + } + if(!report_item->fn || + (report_item->size&&!report_item->buf)){ + return; + } + memcpy(report_item->buf,data,report_item->size); + int *ptr=report_item->buf; + + report_item->fn(report_item->context,report_item->buf); +} + +int xrp_add_report(struct xrp_report_list *list, + struct xrp_report_item *item) +{ + // xrp_cond_lock(&queue->request_queue_cond); + struct xrp_report_entry *entry_head=list->queue.head; + struct xrp_report_entry *entry_cur=NULL; + struct xrp_report_item *new_item; + + new_item = malloc(sizeof(struct xrp_report_item)); + if(!new_item) + { + return -1; + } + memcpy(new_item,item,sizeof(struct xrp_report_item)); + new_item->entry.next=NULL; + if(NULL==entry_head) + { + list->queue.head= &new_item->entry; + return 0; + } + for(;entry_head!=NULL;entry_head=entry_head->next) + { + entry_cur = entry_head; + if(((struct xrp_report_item *)entry_head)->report_id == new_item->report_id) + { + DSP_PRINT(WARNING,"the report is already exist\n"); + return -1; + } + + } + entry_cur->next=&new_item->entry; + DSP_PRINT(INFO,"add new report item %d\n",new_item->report_id); + return 0; + // xrp_cond_unlock(&queue->request_queue_cond); +} + +int xrp_remove_report(struct xrp_report_list *list,int id) +{ + struct xrp_report_entry *pre_entry=NULL; + struct xrp_report_entry *cur_entry=list->queue.head; + for(;cur_entry!=NULL;pre_entry=cur_entry,cur_entry=cur_entry->next) + { + if(((struct xrp_report_item *)cur_entry)->report_id == id) + { + if(pre_entry==NULL) + { + list->queue.head = cur_entry->next; + + } + else{ + pre_entry->next=cur_entry->next; + } + free(cur_entry); + return 0; + } + } + return -1; +} + + +int xrp_alloc_report_id(struct xrp_report_list *list) +{ + int new_id; + int retry=0; + while(1) + { + new_id= rand()&0x7fffffff; + struct xrp_report_entry *cur_entry=list->queue.head; + for(;cur_entry!=NULL;cur_entry=cur_entry->next) + { + if(((struct xrp_report_item *)cur_entry)->report_id == new_id) + { + retry++; + if(retry>10) + { + DSP_PRINT(WARNING,"alloc report id fail"); + return -1; + } + break; + } + } + return new_id; + + } + +} \ No newline at end of file diff --git a/driver/xrp-user/xrp-host/xrp_report.h b/driver/xrp-user/xrp-host/xrp_report.h new file mode 100644 index 0000000..bf2abb8 --- /dev/null +++ b/driver/xrp-user/xrp-host/xrp_report.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2018 Cadence Design Systems Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef _XRP_REPORT_H +#define _XRP_REPORT_H + + +struct xrp_report_entry { + struct xrp_report_entry * next; +}; +struct xrp_report_item { + + struct xrp_report_entry entry; + int report_id; + + void *buf; + + int size; + + void (*fn)( void *context,void * data); + void * context; + +}; + +struct xrp_report_list{ + + struct { + struct xrp_report_entry *head; + } queue; + +}; + + + +extern void xrp_process_report(struct xrp_report_list *list,void* data,unsigned int id); +extern int xrp_add_report(struct xrp_report_list *list, + struct xrp_report_item *item); +extern int xrp_remove_report(struct xrp_report_list *list,int id); +extern int xrp_alloc_report_id(struct xrp_report_list *list); +extern struct xrp_report_item* xrp_get_report_entry(struct xrp_report_list *list,int id); +#endif diff --git a/driver/xrp-user/xrp-host/xrp_sync_queue.c b/driver/xrp-user/xrp-host/xrp_sync_queue.c new file mode 100644 index 0000000..18a2982 --- /dev/null +++ b/driver/xrp-user/xrp-host/xrp_sync_queue.c @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2016 - 2018 Cadence Design Systems Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include "xrp_host_common.h" +#include "xrp_sync_queue.h" + +void xrp_queue_init(struct xrp_request_queue *queue, int priority, + void *context, + void (*fn)(struct xrp_queue_item *rq, void *context)) +{ + (void)priority; + queue->context = context; + queue->fn = fn; +} + +void xrp_queue_destroy(struct xrp_request_queue *queue) +{ + (void)queue; +} + +void xrp_queue_push(struct xrp_request_queue *queue, + struct xrp_queue_item *rq) +{ + queue->fn(rq, queue->context); +} + +struct xrp_event *xrp_event_create(void) +{ + struct xrp_event *event = alloc_refcounted(sizeof(*event)); + + if (!event) + return NULL; + event->status = XRP_STATUS_PENDING; + return event; +} + +void xrp_wait(struct xrp_event *event, enum xrp_status *status) +{ + if (event->status == XRP_STATUS_PENDING) + set_status(status, XRP_STATUS_FAILURE); + else + set_status(status, XRP_STATUS_SUCCESS); +} + +size_t xrp_wait_any(struct xrp_event **event, size_t n_events, + enum xrp_status *status) +{ + if (n_events && event[0]->status != XRP_STATUS_PENDING) + set_status(status, XRP_STATUS_SUCCESS); + else + set_status(status, XRP_STATUS_FAILURE); + return 0; +} + +void xrp_impl_broadcast_event(struct xrp_event *event, enum xrp_status status) +{ + event->status = status; +} + +void xrp_impl_release_event(struct xrp_event *event) +{ + (void)event; +} diff --git a/driver/xrp-user/xrp-host/xrp_sync_queue.h b/driver/xrp-user/xrp-host/xrp_sync_queue.h new file mode 100644 index 0000000..18a48c4 --- /dev/null +++ b/driver/xrp-user/xrp-host/xrp_sync_queue.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2018 Cadence Design Systems Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef _XRP_SYNC_QUEUE_IMPL_H +#define _XRP_SYNC_QUEUE_IMPL_H + +#include "xrp_thread_impl.h" + +struct xrp_queue_item { +}; + +struct xrp_request_queue { + void *context; + void (*fn)(struct xrp_queue_item *rq, void *context); +}; + +struct xrp_event_impl { + xrp_cond cond; +}; + +void xrp_queue_init(struct xrp_request_queue *queue, int priority, + void *context, + void (*fn)(struct xrp_queue_item *rq, void *context)); +void xrp_queue_destroy(struct xrp_request_queue *queue); +void xrp_queue_push(struct xrp_request_queue *queue, + struct xrp_queue_item *rq); + +struct xrp_event *xrp_event_create(void); +void xrp_impl_broadcast_event(struct xrp_event *event, enum xrp_status status); +void xrp_impl_release_event(struct xrp_event *event); + +#endif diff --git a/driver/xrp-user/xrp-host/xrp_threaded_queue.c b/driver/xrp-user/xrp-host/xrp_threaded_queue.c new file mode 100644 index 0000000..a444a9d --- /dev/null +++ b/driver/xrp-user/xrp-host/xrp_threaded_queue.c @@ -0,0 +1,242 @@ +/* + * Copyright (c) 2016 - 2018 Cadence Design Systems Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include "xrp_debug.h" +#include "xrp_host_common.h" +#include "xrp_threaded_queue.h" +#include "dsp_common.h" +static struct xrp_queue_item *_xrp_dequeue_request(struct xrp_request_queue *queue) +{ + struct xrp_queue_item *rq = queue->request_queue.head; + + if (!rq) + return NULL; + + if (rq == queue->request_queue.tail) + queue->request_queue.tail = NULL; + queue->request_queue.head = rq->next; + return rq; +} + +static int xrp_queue_process(struct xrp_request_queue *queue) +{ + struct xrp_queue_item *rq; + int exit = 0; + + queue->sync_exit = &exit; + xrp_cond_lock(&queue->request_queue_cond); + for (;;) { + rq = _xrp_dequeue_request(queue); + if (rq || queue->exit) + break; + xrp_cond_wait(&queue->request_queue_cond); + } + xrp_cond_unlock(&queue->request_queue_cond); + + if (!rq) + return 0; + + // printf("%s,queue:%p get item\n",__FUNCTION__,queue); + queue->fn(rq, queue->context); + // printf("%s,queue:%p done item\n",__FUNCTION__,queue); + return !exit; +} + +static void *xrp_queue_thread(void *p) +{ + struct xrp_request_queue *queue = p; + DSP_PRINT(DEBUG,"queue:%p runing....\n",queue); + while (xrp_queue_process(queue)) { + } + DSP_PRINT(DEBUG,"queue:%p exit\n",queue); + return NULL; +} + +void xrp_queue_init(struct xrp_request_queue *queue, int priority, + void *context, + void (*fn)(struct xrp_queue_item *rq, void *context)) +{ + xrp_cond_init(&queue->request_queue_cond); + queue->context = context; + queue->fn = fn; + xrp_thread_create(&queue->thread, priority, xrp_queue_thread, queue); +} + +void xrp_queue_destroy(struct xrp_request_queue *queue) +{ + xrp_cond_lock(&queue->request_queue_cond); + queue->exit = 1; + xrp_cond_broadcast(&queue->request_queue_cond); + xrp_cond_unlock(&queue->request_queue_cond); + if (!xrp_thread_join(&queue->thread)) { + *queue->sync_exit = 1; + xrp_thread_detach(&queue->thread); + DSP_PRINT(DEBUG,"queue thread release\n"); + } + xrp_cond_lock(&queue->request_queue_cond); + if (queue->request_queue.head != NULL) + DSP_PRINT(DEBUG,"releasing non-empty queue\n"); + xrp_cond_unlock(&queue->request_queue_cond); + xrp_cond_destroy(&queue->request_queue_cond); +} + +void xrp_queue_push(struct xrp_request_queue *queue, + struct xrp_queue_item *rq) +{ + xrp_cond_lock(&queue->request_queue_cond); + rq->next = NULL; + if (queue->request_queue.tail) { + queue->request_queue.tail->next = rq; + + } else { + queue->request_queue.head = rq; + xrp_cond_broadcast(&queue->request_queue_cond); + + } + queue->request_queue.tail = rq; + xrp_cond_unlock(&queue->request_queue_cond); +} + +static void xrp_impl_event_init(struct xrp_event *event) +{ + xrp_cond_init(&event->impl.cond); + event->status = XRP_STATUS_PENDING; +} + +struct xrp_event *xrp_event_create(void) +{ + struct xrp_event *event = alloc_refcounted(sizeof(*event)); + + if (!event) + return NULL; + xrp_impl_event_init(event); + return event; +} + +void xrp_wait(struct xrp_event *event, enum xrp_status *status) +{ + + xrp_cond_lock(&event->impl.cond); + while (event->status == XRP_STATUS_PENDING) + xrp_cond_wait(&event->impl.cond); + xrp_cond_unlock(&event->impl.cond); + set_status(status, XRP_STATUS_SUCCESS); + // printf("%s,get event %p\n",__FUNCTION__,event); +} + +size_t xrp_wait_any(struct xrp_event **event, size_t n_events, + enum xrp_status *status) +{ + size_t i, rv; + struct xrp_event group; + struct xrp_event_link *link; + + if (!n_events) { + set_status(status, XRP_STATUS_FAILURE); + return 0; + } + + link = calloc(n_events, sizeof(struct xrp_event_link)); + + xrp_impl_event_init(&group); + + for (i = 0; i < n_events; ++i) { + xrp_cond_lock(&event[i]->impl.cond); + if (event[i]->status == XRP_STATUS_PENDING) { + link[i].group = event[i]->group; + link[i].next = event[i]->link; + + if (event[i]->link) + event[i]->link->prev = link + i; + + event[i]->group = &group; + event[i]->link = link + i; + } else { + xrp_cond_unlock(&event[i]->impl.cond); + break; + } + xrp_cond_unlock(&event[i]->impl.cond); + } + + rv = i; + + if (i == n_events) + xrp_wait(&group, NULL); + else + n_events = i; + + for (i = 0; i < n_events; ++i) { + xrp_cond_lock(&event[i]->impl.cond); + if (event[i]->group == &group) { + event[i]->group = link[i].group; + event[i]->link = link[i].next; + } + if (link[i].next) { + link[i].next->prev = link[i].prev; + } + if (link[i].prev) { + if (link[i].prev->group == &group) { + link[i].prev->group = link[i].group; + link[i].prev->next = link[i].next; + } else { + pr_debug("%s: inconsistent link state\n"); + } + } + if (event[i]->status != XRP_STATUS_PENDING) + rv = i; + xrp_cond_unlock(&event[i]->impl.cond); + } + xrp_impl_release_event(&group); + free(link); + set_status(status, XRP_STATUS_SUCCESS); + return rv; +} + +void xrp_impl_broadcast_event(struct xrp_event *event, enum xrp_status status) +{ + struct xrp_event *group; + struct xrp_event_link *link; + // printf("%s, event %p! entry\n",__func__,event); + xrp_cond_lock(&event->impl.cond); + event->status = status; + xrp_cond_broadcast(&event->impl.cond); + + group = event->group; + link = event->link; + while (link) { + xrp_cond_lock(&group->impl.cond); + group->status = status; + xrp_cond_broadcast(&group->impl.cond); + xrp_cond_unlock(&group->impl.cond); + group = link->group; + link = link->next; + } + xrp_cond_unlock(&event->impl.cond); + // printf("%s, event %p! exit\n",__func__,event); +} + +void xrp_impl_release_event(struct xrp_event *event) +{ + xrp_cond_destroy(&event->impl.cond); +} diff --git a/driver/xrp-user/xrp-host/xrp_threaded_queue.h b/driver/xrp-user/xrp-host/xrp_threaded_queue.h new file mode 100644 index 0000000..3bf1460 --- /dev/null +++ b/driver/xrp-user/xrp-host/xrp_threaded_queue.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2016 - 2018 Cadence Design Systems Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef _XRP_THREADED_QUEUE_IMPL_H +#define _XRP_THREADED_QUEUE_IMPL_H + +#include "xrp_thread_impl.h" + +struct xrp_queue_item { + struct xrp_queue_item *next; +}; + +struct xrp_request_queue { + xrp_thread thread; + xrp_cond request_queue_cond; + struct { + struct xrp_queue_item *head; + struct xrp_queue_item *tail; + } request_queue; + int exit; + int *sync_exit; + + void *context; + void (*fn)(struct xrp_queue_item *rq, void *context); +}; + +struct xrp_event_impl { + xrp_cond cond; +}; + +void xrp_queue_init(struct xrp_request_queue *queue, int priority, + void *context, + void (*fn)(struct xrp_queue_item *rq, void *context)); +void xrp_queue_destroy(struct xrp_request_queue *queue); +void xrp_queue_push(struct xrp_request_queue *queue, + struct xrp_queue_item *rq); + +struct xrp_event *xrp_event_create(void); +void xrp_impl_broadcast_event(struct xrp_event *event, enum xrp_status status); +void xrp_impl_release_event(struct xrp_event *event); + +#endif diff --git a/firmware/dsp1_dummy_algo_flo.lib b/firmware/dsp1_dummy_algo_flo.lib new file mode 100644 index 0000000..c320a03 Binary files /dev/null and b/firmware/dsp1_dummy_algo_flo.lib differ diff --git a/firmware/dsp1_dummy_algo_flo_1.lib b/firmware/dsp1_dummy_algo_flo_1.lib new file mode 100644 index 0000000..d32e09f Binary files /dev/null and b/firmware/dsp1_dummy_algo_flo_1.lib differ diff --git a/firmware/dsp_dummy_algo_flo.lib b/firmware/dsp_dummy_algo_flo.lib new file mode 100644 index 0000000..d2857ca Binary files /dev/null and b/firmware/dsp_dummy_algo_flo.lib differ diff --git a/firmware/dsp_dummy_algo_pisl.lib b/firmware/dsp_dummy_algo_pisl.lib new file mode 100644 index 0000000..94cd1fa Binary files /dev/null and b/firmware/dsp_dummy_algo_pisl.lib differ diff --git a/firmware/x_test_flo_dsp0.lib b/firmware/x_test_flo_dsp0.lib new file mode 100644 index 0000000..4c8a8d0 Binary files /dev/null and b/firmware/x_test_flo_dsp0.lib differ diff --git a/firmware/x_test_flo_dsp1.lib b/firmware/x_test_flo_dsp1.lib new file mode 100644 index 0000000..a6dfb8d Binary files /dev/null and b/firmware/x_test_flo_dsp1.lib differ diff --git a/firmware/xrp0.elf b/firmware/xrp0.elf new file mode 100644 index 0000000..89353f3 Binary files /dev/null and b/firmware/xrp0.elf differ diff --git a/firmware/xrp0_fl.elf b/firmware/xrp0_fl.elf new file mode 100644 index 0000000..0df60be Binary files /dev/null and b/firmware/xrp0_fl.elf differ diff --git a/firmware/xrp0_pil.elf b/firmware/xrp0_pil.elf new file mode 100644 index 0000000..54487e9 Binary files /dev/null and b/firmware/xrp0_pil.elf differ diff --git a/firmware/xrp1.elf b/firmware/xrp1.elf new file mode 100644 index 0000000..a2dc5e6 Binary files /dev/null and b/firmware/xrp1.elf differ diff --git a/firmware/xrp1_fl.elf b/firmware/xrp1_fl.elf new file mode 100644 index 0000000..60486d6 Binary files /dev/null and b/firmware/xrp1_fl.elf differ diff --git a/firmware/xrp1_pil.elf b/firmware/xrp1_pil.elf new file mode 100644 index 0000000..0cc0f3d Binary files /dev/null and b/firmware/xrp1_pil.elf differ diff --git a/test/drv_test/Makefile b/test/drv_test/Makefile new file mode 100644 index 0000000..83e6be8 --- /dev/null +++ b/test/drv_test/Makefile @@ -0,0 +1,83 @@ +TESTS := dsp_demo +TESTS_UT :=test_dsp_drv_ut +TESTS_M_THREAD :=test_dsp_thread +TESTS_MAX_PWR :=test_dsp_max_power +TESTS_X_TEST :=test_dsp_x_test + +CFLAGS += -O0 -Wall -g -lm -lpthread +# LDFLAGS += -L../driver/xrp-user/xrp-host -lxrp_linux +# LDFLAGS += -L../driver/xrp-user/xrp-common -lxrp-common +LDFLAGS += -Ithread-pthread +LDFLAGS += -L../../driver/xrp-user/ -ldsp +LDFLAGS += -L../test_utility/lib/ -lCppUTest -lCppUTestExt +SRCS += dsp_demo.c + +SRCS_UT += test_post_process.cpp +SRCS_UT += test_vi_enhance_process.cpp +SRCS_UT += test_post_process_lib_loader.cpp +SRCS_UT += test_post_process_dma_buf.cpp +# SRCS +=../driver/xrp-user/dsp-ps/dsp_ps_core.c +SRCS_THREAD +=test_dsp_thread.c + +SRCS_MAX_PWR +=dsp_max_power.c +SRCS_X_TEST +=dsp_x_test.c + +INCLUDES += -I../../driver/xrp-user/include +INCLUDES += -I../test_utility/include/ +# object files will be generated from .c sourcefiles +OBJS = $(notdir $(SRCS:.c=.o)) +OBJS_UT = $(notdir $(SRCS_UT:.cpp=.o)) +OBJS_THREAD = $(notdir $(SRCS_THREAD:.c=.o)) +OBJS_MAX_PWR= $(notdir $(SRCS_MAX_PWR:.c=.o)) +OBJS_X_TEST= $(notdir $(SRCS_X_TEST:.c=.o)) + +all: $(TESTS) $(TESTS_UT) $(TESTS_MAX_PWR) $(TESTS_M_THREAD) $(TESTS_X_TEST) + +prepare: + mkdir -p output + +$(OBJS):$(SRCS) + $(CC) -c $(CFLAGS) $(INCLUDES) $(SRCS) + +$(OBJS_UT):$(SRCS_UT) + $(CXX) -c $(CFLAGS) $(INCLUDES) $(SRCS_UT) + +$(OBJS_THREAD):$(SRCS_THREAD) + $(CC) -c $(CFLAGS) $(INCLUDES) $(SRCS_THREAD) + +$(OBJS_MAX_PWR):$(SRCS_MAX_PWR) + $(CC) -c $(CFLAGS) $(INCLUDES) $(SRCS_MAX_PWR) + +$(OBJS_X_TEST):$(SRCS_X_TEST) + $(CC) -c $(CFLAGS) $(INCLUDES) $(SRCS_X_TEST) + + +$(TESTS_UT):prepare $(OBJS_UT) + $(CXX) -o $(TESTS_UT) $(OBJS_UT) $(CFLAGS) $(LDFLAGS) + cp -r $(TESTS_UT) ./output/ + +$(TESTS):prepare $(OBJS) + $(CC) -o $(TESTS) $(OBJS) $(CFLAGS) $(LDFLAGS) + cp -r $(TESTS) ./output/ + +$(TESTS_M_THREAD):prepare $(OBJS_THREAD) + $(CC) -o $(TESTS_M_THREAD) $(OBJS_THREAD) $(CFLAGS) $(LDFLAGS) + cp -r $(TESTS_M_THREAD) ./output/ + +$(TESTS_MAX_PWR):prepare $(OBJS_MAX_PWR) + $(CC) -o $(TESTS_MAX_PWR) $(OBJS_MAX_PWR) $(CFLAGS) $(LDFLAGS) + cp -r $(TESTS_MAX_PWR) ./output/ + +$(TESTS_X_TEST):prepare $(OBJS_X_TEST) + $(CC) -o $(TESTS_X_TEST) $(OBJS_X_TEST) $(CFLAGS) $(LDFLAGS) + cp -r $(TESTS_X_TEST) ./output/ + +clean: + rm -f $(TESTS) + rm -f *.o + rm -rf output + +install: + +.PHONY: clean all prepare common + diff --git a/test/drv_test/dsp_demo.c b/test/drv_test/dsp_demo.c new file mode 100644 index 0000000..1d8937e --- /dev/null +++ b/test/drv_test/dsp_demo.c @@ -0,0 +1,143 @@ + +#include +#include +#include +#include + +#include "csi_dsp_api.h" +#include "csi_dsp_task_defs.h" +#include "csi_dsp_post_process_defs.h" + +#define PAYLOAD_SIZE 32 + +struct message{ + int cmd; + char message[PAYLOAD_SIZE]; +}; + +int main(int argc, char *argv[]) +{ + printf("Dsp Post Process Test Start !\n"); + void *instance = csi_dsp_create_instance(0); + if(!instance) + { + printf("create fail\n"); + return -1; + } + + void *task= csi_dsp_create_task(instance,CSI_DSP_TASK_SW_TO_SW); + if(!task) + { + printf("task create fail\n"); + return -1; + } +#if 0 + csi_dsp_algo_load_req_t alog_config={ + .algo_id=0, + }; + + if(csi_dsp_task_load_algo(task,&alog_config)) + { + printf("algo kernel load fail\n"); + return -1; + + } +#else + if(csi_dsp_task_acquire_algo(task,"dsp_dummy_algo_pisl")) + { + printf("algo kernel load fail\n"); + return -1; + + } + +#endif + struct csi_sw_task_req* req=NULL; + req =csi_dsp_task_create_request(task); + if(req==NULL) + { + printf("req create fail\n"); + return -1; + } + struct csi_dsp_buffer buf1 = + { + .buf_id = 0, + .dir = CSI_DSP_BUFFER_IN, + .type = CSI_DSP_BUF_ALLOC_DRV, + .plane_count = 1, + .width =640, + .height =480, + .planes[0].stride= 640, + .planes[0].size= 640*480, + }; + + if(csi_dsp_request_add_buffer(req,&buf1)) + { + printf("%s,add buffer:%d\n",__FUNCTION__,buf1.buf_id); + csi_dsp_task_release_request(req); + return -1; + } + int i=0; + for(i=0;istatus != CSI_DSP_SW_REQ_DONE) + { + printf("%s,req dequeue fail:%d\n",__FUNCTION__); + return -1; + } + if(memcmp((void*)buf1.planes[0].buf_vir,(void *)buf2.planes[0].buf_vir,buf1.planes[0].size)) + { + printf("%s,cmp fail\n",__FUNCTION__); + csi_dsp_task_release_request(req); + csi_dsp_destroy_task(task); + csi_dsp_delete_instance(instance); + return -1; + } + + csi_dsp_task_release_request(req); + csi_dsp_destroy_task(task); + csi_dsp_delete_instance(instance); + printf("%s,Test Pass!\n",__FUNCTION__); + return 0; +} diff --git a/test/drv_test/dsp_max_power.c b/test/drv_test/dsp_max_power.c new file mode 100644 index 0000000..5d630fc --- /dev/null +++ b/test/drv_test/dsp_max_power.c @@ -0,0 +1,270 @@ + +#include +#include > +#include +#include +#include +#include + +#include "csi_dsp_api.h" +#include "csi_dsp_task_defs.h" +#include "csi_dsp_post_process_defs.h" + +#define PAYLOAD_SIZE 32 + +struct message{ + int cmd; + char message[PAYLOAD_SIZE]; +}; + +int +compareBuffers(int expected, char* src, char* dst, int size) +{ + int i; + for(i = 0 ; i < size; i++) { + if (dst[i] != src[i]) { + if (expected) { + printf("MISMATCH EXPECTED @ byte %d (dst:%x, src:%x)!!\n", i, dst[i], src[i]); + } + else { + printf("COPY FAILED @ byte %d (dst:%x, src:%x)!!\n", i, dst[i], src[i]); + return -1; + } + } + } + printf("Compare OK (src:%p, dst:%p, len:%d)\n", src, dst, size); + return 0; +} +int load_data_from_file(char *fileInName,void* buf,size_t data_size) +{ + // char *fileInName = NULL; + // char *fileReferenceName = NULL; + char fileOutName[512]; + int rt; + FILE *file; + + + // fileInName = "./test/obj_bits_1280.dat"; + // //fileOutName = argv[2]; + // fileReferenceName = "./test/ref_bits_1280.dat"; + + // file = fopen(fileReferenceName, "rb"); + // if (file != NULL) { + // fread(ref_binary, sizeof(char), 1280*1087/8, file); + // fclose(file); + // } else { + // printf("open ref file fail: %s", fileReferenceName); + // return -1; + // } + file = fopen(fileInName, "rb"); + if(file != NULL){ + fread(buf, sizeof(char), data_size, file); + fclose(file); + } else + { + printf("open obj file fail: %s", fileInName); + return -2; + } + return 0; + + +} + + +int main(int argc, char *argv[]) +{ + printf("********************************\n"); + printf("[dsp max power] test\n"); + printf("********************************\n"); + + + if (argc < 2) { + printf("[dsp test] please provide parameter in following format:\n"); + printf(" ./dsp_max_power case_id, repeat."); + exit(-1); + } + + int case_id = atoi(argv[1]); + int repeat = atoi(argv[2]); + + csi_dsp_algo_load_req_t alog_config; + switch(case_id) + { + case 0: + alog_config.algo_id = 1; + printf("Select Ant Algo !\n"); + break; + case 1: + alog_config.algo_id = 2; + printf("Select Vendor Max Power Algo !\n"); + break; + default: + printf("unsupport case id:%d !\n",case_id); + return -1; + } + printf("Case repeat:%d !\n",repeat); + void *instance = csi_dsp_create_instance(1); + if(!instance) + { + printf("create fail\n"); + return -1; + } + + void *task= csi_dsp_create_task(instance,CSI_DSP_TASK_SW_TO_SW); + if(!task) + { + printf("task create fail\n"); + return -1; + } + + if(case_id == 0) + { + if(csi_dsp_task_acquire_algo(task,"x_test_flo")) + { + printf("algo kernel load fail\n"); + return -1; + + } + } + else if(case_id == 1) + { + if(csi_dsp_task_acquire_algo(task,"max_power_diags_flo")) + { + printf("algo kernel load fail\n"); + return -1; + + } + } + else + { + printf("algo kernel no invalid for case :%d\n",case_id); + return -1; + } + + struct csi_sw_task_req* req=NULL; + req =csi_dsp_task_create_request(task); + if(req==NULL) + { + printf("req create fail\n"); + return -1; + } + struct csi_dsp_buffer buf2; + if(case_id == 0) + { + + + /*****************************input buffer****************************************/ + struct csi_dsp_buffer buf1 = + { + .buf_id = 0, + .dir = CSI_DSP_BUFFER_IN, + .type = CSI_DSP_BUF_ALLOC_DRV, + .plane_count = 1, + .width =1280, + .height =960, + .planes[0].stride= 1280/8, + .planes[0].size=1280*1180/8, + }; + + if(csi_dsp_request_add_buffer(req,&buf1)) + { + printf("%s,add buffer:%d\n",__FUNCTION__,buf1.buf_id); + csi_dsp_task_release_request(req); + return -1; + } + if(load_data_from_file("obj_bits_1280.dat",buf1.planes[0].buf_vir,1280*960/8)) + { + return -1; + } + + /*****************************output buffer****************************************/ + + buf2.buf_id = 1; + buf2.dir = CSI_DSP_BUFFER_OUT; + buf2.type = CSI_DSP_BUF_ALLOC_DRV; + buf2.plane_count = 1; + buf2.width =320; + buf2.height =240; + buf2.planes[0].stride= 320*2; + buf2.planes[0].size=640*480*2; + + + if(csi_dsp_request_add_buffer(req,&buf2)) + { + printf("%s,add buffer:%d\n",__FUNCTION__,buf2.buf_id); + csi_dsp_task_release_request(req); + return -1; + } + memset(buf2.planes[0].buf_vir,0x00,buf2.planes[0].size); + + /*****************************user defineed buffer****************************************/ + struct csi_dsp_buffer buf3 = + { + .buf_id = 2, + .dir = CSI_DSP_BUFFER_IN_OUT, + .type = CSI_DSP_BUF_ALLOC_DRV, + .plane_count = 1, + .width =1280, + .height =1080, + .planes[0].stride= 1280/8, + .planes[0].size= 1280*1180/8, + }; + + if(csi_dsp_request_add_buffer(req,&buf3)) + { + printf("%s,add buffer:%d\n",__FUNCTION__,buf3.buf_id); + csi_dsp_task_release_request(req); + return -1; + } + + if(load_data_from_file("ref_bits_1280.dat",buf3.planes[0].buf_vir,1280*1087/8)) + { + return -1; + } + + + + } + + if(csi_dsp_request_set_property(req,&repeat,sizeof(repeat))) + { + printf("%s,seting req fail:%d\n",__FUNCTION__); + csi_dsp_task_release_request(req); + return -1; + } + + if(csi_dsp_request_enqueue(req)) + { + printf("%s,req enqueu fail:%d\n",__FUNCTION__); + csi_dsp_task_release_request(req); + return -1; + } + + req = csi_dsp_request_dequeue(task); + if(req==NULL && req->status != CSI_DSP_SW_REQ_DONE) + { + printf("%s,req dequeue fail:%d\n",__FUNCTION__); + return -1; + } + if(case_id == 0) + { + short result[320*240]; + load_data_from_file("result.raw",result,320*240*2); + if(compareBuffers(1,(void*)buf2.planes[0].buf_vir,result,320*240*2)) + { + printf("%s,ERR cmp fail\n",__FUNCTION__); + csi_dsp_task_release_request(req); + csi_dsp_destroy_task(task); + csi_dsp_delete_instance(instance); + printf("%s,Test FAIL!\n",__FUNCTION__); + return -1; + } + } + + + csi_dsp_task_release_request(req); + csi_dsp_destroy_task(task); + csi_dsp_delete_instance(instance); + printf("%s,Test Pass!\n",__FUNCTION__); + return 0; +} diff --git a/test/drv_test/dsp_x_test.c b/test/drv_test/dsp_x_test.c new file mode 100644 index 0000000..1a213b4 --- /dev/null +++ b/test/drv_test/dsp_x_test.c @@ -0,0 +1,276 @@ + +#include +#include > +#include +#include +#include +#include + +#include "csi_dsp_api.h" +#include "csi_dsp_task_defs.h" +#include "csi_dsp_post_process_defs.h" + +#define PAYLOAD_SIZE 32 + +struct message{ + int cmd; + char message[PAYLOAD_SIZE]; +}; + +int +compareBuffers(int expected, char* src, char* dst, int size) +{ + int i; + for(i = 0 ; i < size; i++) { + if (dst[i] != src[i]) { + if (expected) { + printf("MISMATCH EXPECTED @ byte %d (dst:%x, src:%x)!!\n", i, dst[i], src[i]); + } + else { + printf("COPY FAILED @ byte %d (dst:%x, src:%x)!!\n", i, dst[i], src[i]); + return -1; + } + } + } + printf("Compare OK (src:%p, dst:%p, len:%d)\n", src, dst, size); + return 0; +} +int load_data_from_file(char *fileInName,void* buf,size_t data_size) +{ + // char *fileInName = NULL; + // char *fileReferenceName = NULL; + char fileOutName[512]; + int rt; + FILE *file; + + + // fileInName = "./test/obj_bits_1280.dat"; + // //fileOutName = argv[2]; + // fileReferenceName = "./test/ref_bits_1280.dat"; + + // file = fopen(fileReferenceName, "rb"); + // if (file != NULL) { + // fread(ref_binary, sizeof(char), 1280*1087/8, file); + // fclose(file); + // } else { + // printf("open ref file fail: %s", fileReferenceName); + // return -1; + // } + file = fopen(fileInName, "rb"); + if(file != NULL){ + fread(buf, sizeof(char), data_size, file); + fclose(file); + } else + { + printf("open obj file fail: %s", fileInName); + return -2; + } + return 0; + + +} + + +int main(int argc, char *argv[]) +{ + printf("********************************\n"); + printf("[dsp ant x_test] test\n"); + printf("********************************\n"); + + int en_compress = 0; + if (argc < 2) { + printf("[dsp test] please provide parameter in following format:\n"); + printf(" ./test_dsp_x_test, en_compress(0/1)."); + exit(-1); + } + if (argc >= 2) + { + en_compress = atoi(argv[1]); + } + + void *instance = csi_dsp_create_instance(1); + if(!instance) + { + printf("create fail\n"); + return -1; + } + + void *task= csi_dsp_create_task(instance,CSI_DSP_TASK_SW_TO_SW); + if(!task) + { + printf("task create fail\n"); + return -1; + } + + if(csi_dsp_task_acquire_algo(task,"x_test_flo")) + { + printf("algo kernel load fail\n"); + return -1; + + } + + struct csi_sw_task_req* req=NULL; + req =csi_dsp_task_create_request(task); + if(req==NULL) + { + printf("req create fail\n"); + return -1; + } + struct csi_dsp_buffer buf2; + struct csi_dsp_buffer buf1; + + /*****************************input buffer****************************************/ + if(en_compress) + { + buf1.buf_id = 0; + buf1.dir = CSI_DSP_BUFFER_IN; + buf1.type = CSI_DSP_BUF_ALLOC_DRV; + buf1.plane_count = 1; + buf1.width =1280; + buf1.height =960; + buf1.planes[0].stride= 1280; + buf1.planes[0].size=1280*1180*2; + + if(csi_dsp_request_add_buffer(req,&buf1)) + { + printf("%s,add buffer:%d\n",__FUNCTION__,buf1.buf_id); + csi_dsp_task_release_request(req); + return -1; + } + if(load_data_from_file("obj_bits_1280.dat",buf1.planes[0].buf_vir,buf1.planes[0].size)) + { + return -1; + } + } + else + { + + buf1.buf_id = 0; + buf1.dir = CSI_DSP_BUFFER_IN; + buf1.type = CSI_DSP_BUF_ALLOC_DRV; + buf1.plane_count = 1; + buf1.width =1280; + buf1.height =960; + buf1.planes[0].stride= 1280/8; + buf1.planes[0].size=1280*1180/8; + + if(csi_dsp_request_add_buffer(req,&buf1)) + { + printf("%s,add buffer:%d\n",__FUNCTION__,buf1.buf_id); + csi_dsp_task_release_request(req); + return -1; + } + if(load_data_from_file("obj_bits_1280.dat",buf1.planes[0].buf_vir,1280*960/8)) + { + return -1; + } + } + +/*****************************output buffer****************************************/ + + buf2.buf_id = 1; + buf2.dir = CSI_DSP_BUFFER_OUT; + buf2.type = CSI_DSP_BUF_ALLOC_DRV; + buf2.plane_count = 1; + buf2.width =320; + buf2.height =240; + buf2.planes[0].stride= 320*2; + buf2.planes[0].size=640*480*2; + + + if(csi_dsp_request_add_buffer(req,&buf2)) + { + printf("%s,add buffer:%d\n",__FUNCTION__,buf2.buf_id); + csi_dsp_task_release_request(req); + return -1; + } + memset(buf2.planes[0].buf_vir,0x00,buf2.planes[0].size); + +/*****************************user defineed buffer****************************************/ + struct csi_dsp_buffer buf3 = + { + .buf_id = 2, + .dir = CSI_DSP_BUFFER_IN_OUT, + .type = CSI_DSP_BUF_ALLOC_DRV, + .plane_count = 1, + .width =1280, + .height =1080, + .planes[0].stride= 1280/8, + .planes[0].size= 1280*1180/8, + }; + + if(csi_dsp_request_add_buffer(req,&buf3)) + { + printf("%s,add buffer:%d\n",__FUNCTION__,buf3.buf_id); + csi_dsp_task_release_request(req); + return -1; + } + + if(load_data_from_file("ref_bits_1280.dat",buf3.planes[0].buf_vir,1280*1087/8)) + { + return -1; + } + + if(en_compress) + { + struct csi_dsp_buffer buf4 = + { + .buf_id = 2, + .dir = CSI_DSP_BUFFER_IN_OUT, + .type = CSI_DSP_BUF_ALLOC_DRV, + .plane_count = 1, + .width =1280, + .height =1080, + .planes[0].stride= 1280/8, + .planes[0].size= 1280*1180/8, + }; + + if(csi_dsp_request_add_buffer(req,&buf4)) + { + printf("%s,add buffer:%d\n",__FUNCTION__,buf4.buf_id); + csi_dsp_task_release_request(req); + return -1; + } + } + + if(csi_dsp_request_set_property(req,&en_compress,sizeof(en_compress))) + { + printf("%s,seting req fail:%d\n",__FUNCTION__); + csi_dsp_task_release_request(req); + return -1; + } + + if(csi_dsp_request_enqueue(req)) + { + printf("%s,req enqueu fail:%d\n",__FUNCTION__); + csi_dsp_task_release_request(req); + return -1; + } + + req = csi_dsp_request_dequeue(task); + if(req==NULL && req->status != CSI_DSP_SW_REQ_DONE) + { + printf("%s,req dequeue fail:%d\n",__FUNCTION__); + return -1; + } + + short result[320*240]; + load_data_from_file("result.raw",result,320*240*2); + if(compareBuffers(1,(void*)buf2.planes[0].buf_vir,result,320*240*2)) + { + printf("%s,ERR cmp fail\n",__FUNCTION__); + csi_dsp_task_release_request(req); + csi_dsp_destroy_task(task); + csi_dsp_delete_instance(instance); + printf("%s,Test FAIL!\n",__FUNCTION__); + return -1; + } + + + + csi_dsp_task_release_request(req); + csi_dsp_destroy_task(task); + csi_dsp_delete_instance(instance); + printf("%s,Test Pass!\n",__FUNCTION__); + return 0; +} diff --git a/test/drv_test/test_dsp_thread.c b/test/drv_test/test_dsp_thread.c new file mode 100644 index 0000000..8158683 --- /dev/null +++ b/test/drv_test/test_dsp_thread.c @@ -0,0 +1,250 @@ + +#include +#include +#include +#include +#include +#include + +#include "csi_dsp_api.h" +#include "csi_dsp_task_defs.h" +#include "csi_dsp_post_process_defs.h" + +struct Param { + int dsp_instance_id; + int dsp_plane_cnt; + int dsp_algo_id; + + char *algo_name; + int dsp_buf_width; + int dsp_buf_height; +}; + +struct timespec start_time = {0, 0}; +struct timespec end_time = {0, 0}; + +int create_dsp_task(void *arg) { + struct Param param = *(struct Param *)arg; + int i; + + void *instance = csi_dsp_create_instance(param.dsp_instance_id); + if (!instance) { + printf("[dsp test] create fail\n"); + pthread_exit(-1); + } + + void *task = csi_dsp_create_task(instance, CSI_DSP_TASK_SW_TO_SW); + if (!task) { + printf("[dsp test] task create fail.\n"); + pthread_exit(-1); + } else { + printf("[dsp test] task create success.\n"); + } + + if(csi_dsp_task_acquire_algo(task,param.algo_name)) + { + csi_dsp_algo_load_req_t algo_config = { + .algo_id = param.dsp_algo_id, + }; + + if (csi_dsp_task_load_algo(task, &algo_config)) { + printf("[dsp test] algo kernel config fail.\n"); + pthread_exit(-1); + } else { + printf("[dsp test] algo kernel config success.\n"); + } + } + + + struct csi_sw_task_req* req = NULL; + req = csi_dsp_task_create_request(task); + if (req == NULL) { + printf("[dsp test] req create fail.\n"); + pthread_exit(-1); + } else { + printf("[dsp test] req create success.\n"); + } + + struct csi_dsp_buffer buf0 = { + .buf_id = 0, + .dir = CSI_DSP_BUFFER_IN, + .type = CSI_DSP_BUF_ALLOC_DRV, + .plane_count = param.dsp_plane_cnt, + .width = param.dsp_buf_width, + .height = param.dsp_buf_height, + .planes[0].stride = param.dsp_buf_width, + .planes[0].size = param.dsp_buf_width*param.dsp_buf_height, + .planes[1].stride = param.dsp_buf_width, + .planes[1].size = param.dsp_buf_width*param.dsp_buf_height, + .planes[2].stride = param.dsp_buf_width, + .planes[2].size = param.dsp_buf_width*param.dsp_buf_height, + }; + + if (csi_dsp_request_add_buffer(req, &buf0)) { + printf("[dsp test] %s,add buffer:%d\n", __FUNCTION__, buf0.buf_id); + csi_dsp_task_release_request(req); + pthread_exit(-1); + } else { + printf("[dsp test] req request add buffer success, buf0.\n"); + } + + if (param.dsp_plane_cnt == 1 || param.dsp_plane_cnt == 2 || param.dsp_plane_cnt == 3) { + for (i = 0; i < buf0.planes[0].size/4; i++) { + ((int *)(buf0.planes[0].buf_vir))[i] = rand(); + } + } + if (param.dsp_plane_cnt == 2 || param.dsp_plane_cnt == 3) { + for (i = 0; i < buf0.planes[1].size/4; i++) { + ((int *)(buf0.planes[1].buf_vir))[i] = rand(); + } + } + if (param.dsp_plane_cnt == 3) { + for (i = 0 ; i < buf0.planes[2].size/4; i++) { + ((int *)(buf0.planes[2].buf_vir))[i] = rand(); + } + } + + struct csi_dsp_buffer buf1 = { + .buf_id = 1, + .dir = CSI_DSP_BUFFER_OUT, + .type = CSI_DSP_BUF_ALLOC_DRV, + .plane_count = param.dsp_plane_cnt, + .width = param.dsp_buf_width, + .height = param.dsp_buf_height, + .planes[0].stride = param.dsp_buf_width, + .planes[0].size = param.dsp_buf_width*param.dsp_buf_height, + .planes[1].stride = param.dsp_buf_width, + .planes[1].size = param.dsp_buf_width*param.dsp_buf_height, + .planes[2].stride = param.dsp_buf_width, + .planes[2].size = param.dsp_buf_width*param.dsp_buf_height, + }; + + if (csi_dsp_request_add_buffer(req, &buf1)) { + printf("[dsp test] %s,add buffer:%d\n", __FUNCTION__, buf1.buf_id); + csi_dsp_task_release_request(req); + pthread_exit(-1); + } else { + printf("[dsp test] req request add buffer success, buf1.\n"); + } + + if (csi_dsp_request_enqueue(req)) { + printf("[dsp test] %s,req enqueu fail:%d\n", __FUNCTION__); + csi_dsp_task_release_request(req); + pthread_exit(-1); + } else { + printf("[dsp test] req request enqueque success.\n"); + } + + req = csi_dsp_request_dequeue(task); + if( req == NULL && req->status != CSI_DSP_SW_REQ_DONE ) { + printf("[dsp test] %s,req dequeue fail:%d\n", __FUNCTION__); + pthread_exit(-1); + } else { + printf("[dsp test] req request dequeque success.\n"); + } + + if( param.dsp_plane_cnt == 1 || param.dsp_plane_cnt == 2 || param.dsp_plane_cnt == 3 ) { + if( memcmp((void*)buf0.planes[0].buf_vir, (void *)buf1.planes[0].buf_vir, buf0.planes[0].size) ) { + printf("[dsp test] cmp fail, line num %d\n",__LINE__); + csi_dsp_task_release_request(req); + csi_dsp_destroy_task(task); + csi_dsp_delete_instance(instance); + pthread_exit(-1); + } + } + if ( param.dsp_plane_cnt == 2 || param.dsp_plane_cnt == 3 ) { + if( memcmp((void*)buf0.planes[1].buf_vir, (void *)buf1.planes[1].buf_vir, buf0.planes[1].size) ) { + printf("[dsp test] cmp fail, line num %d\n",__LINE__); + csi_dsp_task_release_request(req); + csi_dsp_destroy_task(task); + csi_dsp_delete_instance(instance); + pthread_exit(-1);; + } + } + if ( param.dsp_plane_cnt == 3 ) { + if( memcmp((void*)buf0.planes[2].buf_vir, (void *)buf1.planes[2].buf_vir, buf0.planes[2].size )) { + printf("[dsp test] cmp fail, line num %d\n",__LINE__); + csi_dsp_task_release_request(req); + csi_dsp_destroy_task(task); + csi_dsp_delete_instance(instance); + pthread_exit(-1);; + } + } + csi_dsp_task_release_request(req); + csi_dsp_destroy_task(task); + csi_dsp_delete_instance(instance); + pthread_exit(0); +} + +int main(int argc, char *argv[]) { + printf("********************************\n"); + printf("[dsp test] kick off test\n"); + printf("********************************\n"); + + pthread_t thread1, thread2; + int ret_thrd1, ret_thrd2; + + if (argc < 6) { + printf("[dsp test] please provide parameter in following format:\n"); + printf(" ./dsp_test dsp_id plane_cnt algo_id buf_width buf_height thread_num."); + exit(-1); + } + + int dsp_instance_id = atoi(argv[1]); + int dsp_plane_cnt = atoi(argv[2]); + char *algo_name = (argv[3]); + int dsp_algo_id = atoi(argv[3]); + int dsp_buf_width = atoi(argv[4]); + int dsp_buf_height = atoi(argv[5]); + int test_thd_num = atoi(argv[6]); + + + + + + printf("========== TEST CONFIGURATIONS ==========\n"); + printf(" dsp_id : %d\n", dsp_instance_id); + printf(" plane_num : %d\n", dsp_plane_cnt); + printf(" algo_name : %s\n", algo_name); + printf(" buf_width : %d\n", dsp_buf_width); + printf(" buf_height : %d\n", dsp_buf_height); + printf(" test_thd_num : %d\n", test_thd_num); + printf("==========================================\n"); + + struct Param param = { + .dsp_instance_id = dsp_instance_id, + .dsp_plane_cnt = dsp_plane_cnt, + .algo_name = algo_name, + .dsp_algo_id = dsp_algo_id, + .dsp_buf_width = dsp_buf_width, + .dsp_buf_height = dsp_buf_height + }; + + printf("[dsp test] Dsp Post Process Test Start !\n"); + void *thread_res; + int res; + int ret; + + clock_gettime(CLOCK_REALTIME, &start_time); + pthread_t * thread = malloc(sizeof(pthread_t)*test_thd_num); + for(int i = 0; i < test_thd_num; i++) { + ret_thrd1 = pthread_create(&thread[i], NULL, (void *)&create_dsp_task, (void*)¶m); + } + for(int i = 0; i < test_thd_num; i++) { + res = pthread_join(thread[i],(void*)&thread_res); + clock_gettime(CLOCK_REALTIME, &end_time); + ret = (int *)thread_res; + printf("==========================================\n"); + if(ret == 0) { + printf("[dsp test] thread %d,Test Pass!\n", i); + } else { + printf("[dsp test] thread %d,Test Fail!\n", i); + } + printf("==========================================\n"); + } + printf("[dsp test] total time cost : %d ms\n", + (end_time.tv_sec - start_time.tv_sec) * 1000 + + (end_time.tv_nsec - start_time.tv_nsec) / 1000000); + + return 0; +} diff --git a/test/drv_test/test_post_process.cpp b/test/drv_test/test_post_process.cpp new file mode 100644 index 0000000..6e8df0d --- /dev/null +++ b/test/drv_test/test_post_process.cpp @@ -0,0 +1,939 @@ + +#include +#include +#include +#include +#include +#include "csi_dsp_api.h" +#include "csi_dsp_task_defs.h" +#include "csi_dsp_post_process_defs.h" + +#include "CppUTest/TestHarness.h" +#include "CppUTest/CommandLineTestRunner.h" + +struct buf_param{ + int with; + int height; + int stride; + int plane_num; +}; + +TEST_GROUP(DspPostProcessTestBasic) +{ + void setup() + { + instance = csi_dsp_create_instance(0); + if(!instance) + { + FAIL_TEST("create fail\n"); + + } + task= csi_dsp_create_task(instance,CSI_DSP_TASK_SW_TO_SW); + if(!task) + { + FAIL_TEST("task create fail\n"); + } + } + void teardown() + { + csi_dsp_destroy_task(task); + csi_dsp_delete_instance(instance); + } + void *instance; + void *task; + + int oneRequsetHelper(int with,int height,int stride,int plane_num) + { + int i=0; + int j=0; + int ret =0 ; + struct timeval time_enqueue; + struct timeval time_dequeue; + csi_dsp_algo_load_req_t alog_config={ + .algo_id=0, + }; + + if(csi_dsp_task_load_algo(task,&alog_config)) + { + FAIL_TEST("algo kernel load fail\n"); + + } + + struct csi_sw_task_req* req=NULL; + req =csi_dsp_task_create_request(task); + if(req==NULL) + { + FAIL_TEST("req create fail\n"); + } + struct csi_dsp_buffer buf1; + + + buf1.buf_id = 0; + buf1.dir = CSI_DSP_BUFFER_IN; + buf1.type = CSI_DSP_BUF_ALLOC_DRV; + buf1.plane_count = plane_num; + buf1.width =with; + buf1.height =height; + for(i=0;istatus != CSI_DSP_SW_REQ_DONE) + { + FAIL_TEST("req dequeue fail\n"); + } + gettimeofday(&time_dequeue, 0); + + printf("req:%d,start:%d,%d,end:%d,%d\n",req->request_id,time_enqueue.tv_sec,time_enqueue.tv_usec,time_dequeue.tv_sec,time_dequeue.tv_usec); + // MEMCMP_EQUAL((void*)buf1.planes[0].buf_vir,(void *)buf2.planes[0].buf_vir,buf1.planes[0].size); + for(i=0;i0;loop--) + { + req = csi_dsp_request_dequeue(task); + if(req==NULL && req->status != CSI_DSP_SW_REQ_DONE) + { + FAIL_TEST("req dequeue fail\n"); + } + // MEMCMP_EQUAL((void*)req->buffers[0].planes[0].buf_vir,(void *)req->buffers[1].planes[0].buf_vir,req->buffers[0].planes[0].size); + int ret = memcmp((void*)req->buffers[0].planes[0].buf_vir,(void *)req->buffers[1].planes[0].buf_vir,req->buffers[0].planes[0].size); + CHECK_EQUAL_ZERO(ret); + csi_dsp_task_release_request(req); + } + +} + + +TEST(DspPostProcessTestBasic,MultiProcessReqEnqueueConcentration) +{ + struct csi_sw_task_req* req_list[6]; + int loop=0; + struct csi_sw_task_req* req=NULL; + int req_num = sizeof(req_list)/sizeof(struct csi_sw_task_req*); + + csi_dsp_algo_load_req_t alog_config={ + .algo_id=0, + }; + + if(csi_dsp_task_load_algo(task,&alog_config)) + { + FAIL_TEST("algo kernel load fail\n"); + + } + for(loop =0 ;loop < req_num;loop++) + { + + req =csi_dsp_task_create_request(task); + if(req==NULL) + { + FAIL_TEST("req create fail\n"); + } + req_list[loop]=req; + struct csi_dsp_buffer buf1; + + + buf1.buf_id = 0; + buf1.dir = CSI_DSP_BUFFER_IN; + buf1.type = CSI_DSP_BUF_ALLOC_DRV; + buf1.plane_count = 1; + buf1.width =640; + buf1.height =480; + buf1.planes[0].stride= 640; + buf1.planes[0].size= 640*480; + + + if(csi_dsp_request_add_buffer(req,&buf1)) + { + + csi_dsp_task_release_request(req); + FAIL_TEST("Add buffer:%d\n"); + } + int i=0; + for(i=0;i0;loop--) + { + req = csi_dsp_request_dequeue(task); + if(req==NULL && req->status != CSI_DSP_SW_REQ_DONE) + { + FAIL_TEST("req dequeue fail\n"); + } + // MEMCMP_EQUAL((void*)req->buffers[0].planes[0].buf_vir,(void *)req->buffers[1].planes[0].buf_vir,req->buffers[0].planes[0].size); + int ret = memcmp((void*)req->buffers[0].planes[0].buf_vir,(void *)req->buffers[1].planes[0].buf_vir,req->buffers[0].planes[0].size); + CHECK_EQUAL_ZERO(ret); + csi_dsp_task_release_request(req); + } + +} + + +TEST(DspPostProcessTestBasic,MultiProcessReqEnqueueConcentration_1) +{ + struct csi_sw_task_req* req_list[6]; + int loop=0; + struct csi_sw_task_req* req=NULL; + int req_num = sizeof(req_list)/sizeof(struct csi_sw_task_req*); + + csi_dsp_algo_load_req_t alog_config={ + .algo_id=0, + }; + + if(csi_dsp_task_load_algo(task,&alog_config)) + { + FAIL_TEST("algo kernel load fail\n"); + + } + for(loop =0 ;loop < req_num;loop++) + { + + req =csi_dsp_task_create_request(task); + if(req==NULL) + { + FAIL_TEST("req create fail\n"); + } + req_list[loop]=req; + struct csi_dsp_buffer buf1; + + + buf1.buf_id = 0; + buf1.dir = CSI_DSP_BUFFER_IN; + buf1.type = CSI_DSP_BUF_ALLOC_DRV; + buf1.plane_count = 1; + buf1.width =640; + buf1.height =480; + buf1.planes[0].stride= 640; + buf1.planes[0].size= 640*480; + + + if(csi_dsp_request_add_buffer(req,&buf1)) + { + + csi_dsp_task_release_request(req); + FAIL_TEST("Add buffer:%d\n"); + } + int i=0; + for(i=0;i0;loop--) + { + req = csi_dsp_request_dequeue(task); + if(req==NULL && req->status != CSI_DSP_SW_REQ_DONE) + { + FAIL_TEST("req dequeue fail\n"); + } + } + for(loop =0 ;loop < req_num;loop++) + { + req = req_list[loop]; + // MEMCMP_EQUAL((void*)req->buffers[0].planes[0].buf_vir,(void *)req->buffers[1].planes[0].buf_vir,req->buffers[0].planes[0].size); + int ret = memcmp((void*)req->buffers[0].planes[0].buf_vir,(void *)req->buffers[1].planes[0].buf_vir,req->buffers[0].planes[0].size); + CHECK_EQUAL_ZERO(ret); + csi_dsp_task_release_request(req); + } + + + +} + + + +TEST(DspPostProcessTestBasic,MultiProcessReqEnqueueConcentration_profile_640) +{ + struct csi_sw_task_req* req_list[6]; + struct timeval cur_time_enqueue[6]; + struct timeval cur_time_dequeue[6]; + int loop=0; + struct csi_sw_task_req* req=NULL; + int req_num = sizeof(req_list)/sizeof(struct csi_sw_task_req*); + + csi_dsp_algo_load_req_t alog_config={ + .algo_id=0, + }; + + if(csi_dsp_task_load_algo(task,&alog_config)) + { + FAIL_TEST("algo kernel load fail\n"); + + } + for(loop =0 ;loop < req_num;loop++) + { + + req =csi_dsp_task_create_request(task); + if(req==NULL) + { + FAIL_TEST("req create fail\n"); + } + req_list[loop]=req; + struct csi_dsp_buffer buf1; + + + buf1.buf_id = 0; + buf1.dir = CSI_DSP_BUFFER_IN; + buf1.type = CSI_DSP_BUF_ALLOC_DRV; + buf1.plane_count = 1; + buf1.width =640; + buf1.height =480; + buf1.planes[0].stride= 640; + buf1.planes[0].size= 640*480; + + + if(csi_dsp_request_add_buffer(req,&buf1)) + { + + csi_dsp_task_release_request(req); + FAIL_TEST("Add buffer:%d\n"); + } + int i=0; + for(i=0;i0;loop--) + { + req = csi_dsp_request_dequeue(task); + if(req==NULL && req->status != CSI_DSP_SW_REQ_DONE) + { + FAIL_TEST("req dequeue fail\n"); + } + gettimeofday(&cur_time_dequeue[loop], 0); + } + for(loop =0 ;loop < req_num;loop++) + { + printf("req:%d,start:%d,%d,end:%d,%d\n",req_list[loop]->request_id,cur_time_enqueue[loop].tv_sec,cur_time_enqueue[loop].tv_usec, + cur_time_dequeue[loop].tv_sec,cur_time_dequeue[loop].tv_usec); + } + for(loop =0 ;loop < req_num;loop++) + { + req = req_list[loop]; + // MEMCMP_EQUAL((void*)req->buffers[0].planes[0].buf_vir,(void *)req->buffers[1].planes[0].buf_vir,req->buffers[0].planes[0].size); + int ret = memcmp((void*)req->buffers[0].planes[0].buf_vir,(void *)req->buffers[1].planes[0].buf_vir,req->buffers[0].planes[0].size); + CHECK_EQUAL_ZERO(ret); + csi_dsp_task_release_request(req); + } + + +} + + +TEST(DspPostProcessTestBasic,MultiProcessReqEnqueueConcentration_profile_1920) +{ + struct csi_sw_task_req* req_list[6]; + struct timeval cur_time_enqueue[6]; + struct timeval cur_time_dequeue[6]; + int loop=0; + struct csi_sw_task_req* req=NULL; + int req_num = sizeof(req_list)/sizeof(struct csi_sw_task_req*); + + csi_dsp_algo_load_req_t alog_config={ + .algo_id=0, + }; + + if(csi_dsp_task_load_algo(task,&alog_config)) + { + FAIL_TEST("algo kernel load fail\n"); + + } + for(loop =0 ;loop < req_num;loop++) + { + + req =csi_dsp_task_create_request(task); + if(req==NULL) + { + FAIL_TEST("req create fail\n"); + } + req_list[loop]=req; + struct csi_dsp_buffer buf1; + + + buf1.buf_id = 0; + buf1.dir = CSI_DSP_BUFFER_IN; + buf1.type = CSI_DSP_BUF_ALLOC_DRV; + buf1.plane_count = 1; + buf1.width =1920; + buf1.height =1080; + buf1.planes[0].stride= 1920; + buf1.planes[0].size= 1920*1080; + + + if(csi_dsp_request_add_buffer(req,&buf1)) + { + + csi_dsp_task_release_request(req); + FAIL_TEST("Add buffer:%d\n"); + } + int i=0; + for(i=0;i0;loop--) + { + req = csi_dsp_request_dequeue(task); + if(req==NULL && req->status != CSI_DSP_SW_REQ_DONE) + { + FAIL_TEST("req dequeue fail\n"); + } + gettimeofday(&cur_time_dequeue[loop], 0); + } + uint32_t counter; + for(loop =0 ;loop < req_num;loop++) + { + printf("req:%d,start:%d,%d,end:%d,%d\n",req_list[loop]->request_id,cur_time_enqueue[loop].tv_sec,cur_time_enqueue[loop].tv_usec, + cur_time_dequeue[loop].tv_sec,cur_time_dequeue[loop].tv_usec); + } + for(loop =0 ;loop < req_num;loop++) + { + req = req_list[loop]; + // MEMCMP_EQUAL((void*)req->buffers[0].planes[0].buf_vir,(void *)req->buffers[1].planes[0].buf_vir,req->buffers[0].planes[0].size); + int ret = memcmp((void*)req->buffers[0].planes[0].buf_vir,(void *)req->buffers[1].planes[0].buf_vir,req->buffers[0].planes[0].size); + CHECK_EQUAL_ZERO(ret); + csi_dsp_task_release_request(req); + } + +} + +TEST(DspPostProcessTestBasic,MultiProcessReqEnqueueConcentration_profile_4096) +{ + struct csi_sw_task_req* req_list[6]; + struct timeval cur_time_enqueue[6]; + struct timeval cur_time_dequeue[6]; + int loop=0; + struct csi_sw_task_req* req=NULL; + int req_num = sizeof(req_list)/sizeof(struct csi_sw_task_req*); + + csi_dsp_algo_load_req_t alog_config={ + .algo_id=0, + }; + + if(csi_dsp_task_load_algo(task,&alog_config)) + { + FAIL_TEST("algo kernel load fail\n"); + + } + for(loop =0 ;loop < req_num;loop++) + { + + req =csi_dsp_task_create_request(task); + if(req==NULL) + { + FAIL_TEST("req create fail\n"); + } + req_list[loop]=req; + struct csi_dsp_buffer buf1; + + + buf1.buf_id = 0; + buf1.dir = CSI_DSP_BUFFER_IN; + buf1.type = CSI_DSP_BUF_ALLOC_DRV; + buf1.plane_count = 1; + buf1.width =4096; + buf1.height =2160; + buf1.planes[0].stride= 4096; + buf1.planes[0].size= 4096*2160; + + + if(csi_dsp_request_add_buffer(req,&buf1)) + { + + csi_dsp_task_release_request(req); + FAIL_TEST("Add buffer:%d\n"); + } + int i=0; + for(i=0;i0;loop--) + { + req = csi_dsp_request_dequeue(task); + if(req==NULL && req->status != CSI_DSP_SW_REQ_DONE) + { + FAIL_TEST("req dequeue fail\n"); + } + gettimeofday(&cur_time_dequeue[loop], 0); + } + + uint32_t counter; + for(loop =0 ;loop < req_num;loop++) + { + printf("req:%d,start:%d,%d,end:%d,%d\n",req_list[loop]->request_id,cur_time_enqueue[loop].tv_sec,cur_time_enqueue[loop].tv_usec, + cur_time_dequeue[loop].tv_sec,cur_time_dequeue[loop].tv_usec); + } + + for(loop =0 ;loop < req_num;loop++) + { + req = req_list[loop]; + // MEMCMP_EQUAL((void*)req->buffers[0].planes[0].buf_vir,(void *)req->buffers[1].planes[0].buf_vir,req->buffers[0].planes[0].size); + int ret = memcmp((void*)req->buffers[0].planes[0].buf_vir,(void *)req->buffers[1].planes[0].buf_vir,req->buffers[0].planes[0].size); + CHECK_EQUAL_ZERO(ret); + csi_dsp_task_release_request(req); + } + +} + +int main( int argc, char **argv ) +{ + + return RUN_ALL_TESTS(argc, argv); +} + +// int main(int argc, char *argv[]) +// { +// printf("Dsp Post Process Test Start !\n"); +// void *instance = csi_dsp_create_instance(0); +// if(!instance) +// { +// printf("create fail\n"); +// return -1; +// } + +// void *task= csi_dsp_create_task(instance,CSI_DSP_TASK_SW_TO_SW); +// if(!task) +// { +// printf("task create fail\n"); +// return -1; +// } + +// struct csi_dsp_algo_config_par alog_config={ +// .algo_id=0, +// }; + +// if(csi_dsp_task_config_algo(task,&alog_config)) +// { +// printf("algo kernel config fail\n"); +// return -1; +// } + +// struct csi_sw_task_req* req=NULL; +// req =csi_dsp_task_create_request(task); +// if(req==NULL) +// { +// printf("req create fail\n"); +// return -1; +// } +// struct csi_dsp_buffer buf1 = +// { +// .buf_id = 0, +// .dir = CSI_DSP_BUFFER_IN, +// .type = CSI_DSP_BUF_ALLOC_DRV, +// .plane_count = 1, +// .width =640, +// .height =480, +// .planes[0].stride= 640, +// .planes[0].size= 604*480, +// }; + +// if(csi_dsp_request_add_buffer(req,&buf1)) +// { +// printf("%s,add buffer:%d\n",__FUNCTION__,buf1.buf_id); +// csi_dsp_task_release_request(req); +// return -1; +// } +// int i=0; +// for(i=0;istatus != CSI_DSP_SW_REQ_DONE) +// { +// printf("%s,req dequeue fail:%d\n",__FUNCTION__); +// return -1; +// } +// if(memcmp((void*)buf1.planes[0].buf_vir,(void *)buf2.planes[0].buf_vir,buf1.planes[0].size)) +// { +// printf("%s,cmp fail\n",__FUNCTION__); +// csi_dsp_task_release_request(req); +// csi_dsp_destroy_task(task); +// csi_dsp_delete_instance(instance); +// return -1; +// } + +// csi_dsp_task_release_request(req); +// csi_dsp_destroy_task(task); +// csi_dsp_delete_instance(instance); +// printf("%s,Test Pass!\n",__FUNCTION__); +// return 0; +// } diff --git a/test/drv_test/test_post_process_dma_buf.cpp b/test/drv_test/test_post_process_dma_buf.cpp new file mode 100644 index 0000000..2383cab --- /dev/null +++ b/test/drv_test/test_post_process_dma_buf.cpp @@ -0,0 +1,284 @@ + +#include +#include +#include +#include +#include +#include +#include "csi_dsp_api.h" +#include "csi_dsp_task_defs.h" +#include "csi_dsp_post_process_defs.h" + +#include "CppUTest/TestHarness.h" +#include "CppUTest/CommandLineTestRunner.h" +#ifdef __cplusplus +extern "C" { +#endif +#include "video_mem.h" +#ifdef __cplusplus +} +#endif +struct buf_param{ + int with; + int height; + int stride; + int plane_num; +}; + +TEST_GROUP(DspPostProcessTestDmaBuf) +{ + void setup() + { + instance = csi_dsp_create_instance(0); + if(!instance) + { + FAIL_TEST("create fail\n"); + + } + task= csi_dsp_create_task(instance,CSI_DSP_TASK_SW_TO_SW); + if(!task) + { + FAIL_TEST("task create fail\n"); + } + if( VMEM_create(&mem_allocor) <0) + { + FAIL_TEST("open mem_alloc_fd fail\n"); + } + } + void teardown() + { + csi_dsp_destroy_task(task); + csi_dsp_delete_instance(instance); + VMEM_destroy(mem_allocor); + + } + void *instance; + void *mem_allocor; + void *task; + + int reqDmaBuffer(VmemParams *params) + { + + int pgsize = getpagesize(); + params->size = ((params->size+pgsize-1)/pgsize)*pgsize; + if(VMEM_allocate(mem_allocor, params)) + { + return -1; + } + + printf("%s,alloct dma buf @ phy:%lx\n",__FUNCTION__,params->phy_address); + if(VMEM_export(mem_allocor,params)) + { + return -1; + } + printf("%s,export dma buf @fd:%x\n",__FUNCTION__,params->fd); + // if(VMEM_mmap(mem_allocor,params)) + // { + // return -1; + // } + // printf("%s,mmap dma buf addr:%lx\n",__FUNCTION__,params->vir_address); + return 0; + + } + int releaseDmaBuffer(VmemParams *params) + { + VMEM_free(mem_allocor, params); + } + int oneRequsetHelper(int with,int height,int stride,int plane_num,char *name) + { + int i=0; + int j=0; + int ret =0 ; + struct timeval time_enqueue; + struct timeval time_dequeue; + VmemParams params_in[3]; + VmemParams params_out[3]; + + csi_dsp_algo_load_req_t alog_config={ + .algo_id=0, + }; + + if(name != NULL) + { + if(csi_dsp_task_acquire_algo(task,name)) + { + FAIL_TEST("algo kernel load fail\n"); + } + } + else + { + if(csi_dsp_task_load_algo(task,&alog_config)) + { + FAIL_TEST("algo kernel load fail\n"); + } + } + + struct csi_sw_task_req* req=NULL; + req =csi_dsp_task_create_request(task); + if(req==NULL) + { + FAIL_TEST("req create fail\n"); + } + for(i=0;istatus != CSI_DSP_SW_REQ_DONE) + { + FAIL_TEST("req dequeue fail\n"); + } + gettimeofday(&time_dequeue, 0); + + printf("req:%d,start:%d,%d,end:%d,%d\n",req->request_id,time_enqueue.tv_sec,time_enqueue.tv_usec,time_dequeue.tv_sec,time_dequeue.tv_usec); + // MEMCMP_EQUAL((void*)buf1.planes[0].buf_vir,(void *)buf2.planes[0].buf_vir,buf1.planes[0].size); + // memset((void *)buf2.planes[0].buf_vir,0xff,16); + for(i=0;i +#include +#include +#include +#include +#include "csi_dsp_api.h" +#include "csi_dsp_task_defs.h" +#include "csi_dsp_post_process_defs.h" + +#include "CppUTest/TestHarness.h" +#include "CppUTest/CommandLineTestRunner.h" + +struct buf_param{ + int with; + int height; + int stride; + int plane_num; +}; + +TEST_GROUP(DspPostProcessTestLibLoader) +{ + void setup() + { + instance = csi_dsp_create_instance(0); + if(!instance) + { + FAIL_TEST("create fail\n"); + + } + task= csi_dsp_create_task(instance,CSI_DSP_TASK_SW_TO_SW); + if(!task) + { + FAIL_TEST("task create fail\n"); + } + } + void teardown() + { + csi_dsp_destroy_task(task); + csi_dsp_delete_instance(instance); + } + void *instance; + void *task; + + int oneRequsetHelper(int with,int height,int stride,int plane_num,char *name) + { + int i=0; + int j=0; + int ret =0 ; + struct timeval time_enqueue; + struct timeval time_dequeue; + csi_dsp_algo_load_req_t alog_config={ + .algo_id=0, + }; + + if(csi_dsp_task_acquire_algo(task,name)) + { + FAIL_TEST("algo kernel load fail\n"); + + } + + struct csi_sw_task_req* req=NULL; + req =csi_dsp_task_create_request(task); + if(req==NULL) + { + FAIL_TEST("req create fail\n"); + } + struct csi_dsp_buffer buf1; + + + buf1.buf_id = 0; + buf1.dir = CSI_DSP_BUFFER_IN; + buf1.type = CSI_DSP_BUF_ALLOC_DRV; + buf1.plane_count = plane_num; + buf1.width =with; + buf1.height =height; + for(i=0;istatus != CSI_DSP_SW_REQ_DONE) + { + FAIL_TEST("req dequeue fail\n"); + } + gettimeofday(&time_dequeue, 0); + + printf("req:%d,start:%d,%d,end:%d,%d\n",req->request_id,time_enqueue.tv_sec,time_enqueue.tv_usec,time_dequeue.tv_sec,time_dequeue.tv_usec); + // MEMCMP_EQUAL((void*)buf1.planes[0].buf_vir,(void *)buf2.planes[0].buf_vir,buf1.planes[0].size); + // memset((void *)buf2.planes[0].buf_vir,0xff,16); + for(i=0;i0;loop--) +// { +// req = csi_dsp_request_dequeue(task); +// if(req==NULL && req->status != CSI_DSP_SW_REQ_DONE) +// { +// FAIL_TEST("req dequeue fail\n"); +// } +// // MEMCMP_EQUAL((void*)req->buffers[0].planes[0].buf_vir,(void *)req->buffers[1].planes[0].buf_vir,req->buffers[0].planes[0].size); +// int ret = memcmp((void*)req->buffers[0].planes[0].buf_vir,(void *)req->buffers[1].planes[0].buf_vir,req->buffers[0].planes[0].size); +// CHECK_EQUAL_ZERO(ret); +// csi_dsp_task_release_request(req); +// } + +// } + + +// TEST(DspPostProcessTestLibLoader,MultiProcessReqEnqueueConcentration) +// { +// struct csi_sw_task_req* req_list[6]; +// int loop=0; +// struct csi_sw_task_req* req=NULL; +// int req_num = sizeof(req_list)/sizeof(struct csi_sw_task_req*); + +// csi_dsp_algo_load_req_t alog_config={ +// .algo_id=0, +// }; + +// if(csi_dsp_task_load_algo(task,&alog_config)) +// { +// FAIL_TEST("algo kernel load fail\n"); + +// } +// for(loop =0 ;loop < req_num;loop++) +// { + +// req =csi_dsp_task_create_request(task); +// if(req==NULL) +// { +// FAIL_TEST("req create fail\n"); +// } +// req_list[loop]=req; +// struct csi_dsp_buffer buf1; + + +// buf1.buf_id = 0; +// buf1.dir = CSI_DSP_BUFFER_IN; +// buf1.type = CSI_DSP_BUF_ALLOC_DRV; +// buf1.plane_count = 1; +// buf1.width =640; +// buf1.height =480; +// buf1.planes[0].stride= 640; +// buf1.planes[0].size= 640*480; + + +// if(csi_dsp_request_add_buffer(req,&buf1)) +// { + +// csi_dsp_task_release_request(req); +// FAIL_TEST("Add buffer:%d\n"); +// } +// int i=0; +// for(i=0;i0;loop--) +// { +// req = csi_dsp_request_dequeue(task); +// if(req==NULL && req->status != CSI_DSP_SW_REQ_DONE) +// { +// FAIL_TEST("req dequeue fail\n"); +// } +// // MEMCMP_EQUAL((void*)req->buffers[0].planes[0].buf_vir,(void *)req->buffers[1].planes[0].buf_vir,req->buffers[0].planes[0].size); +// int ret = memcmp((void*)req->buffers[0].planes[0].buf_vir,(void *)req->buffers[1].planes[0].buf_vir,req->buffers[0].planes[0].size); +// CHECK_EQUAL_ZERO(ret); +// csi_dsp_task_release_request(req); +// } + +// } + + +// TEST(DspPostProcessTestLibLoader,MultiProcessReqEnqueueConcentration_1) +// { +// struct csi_sw_task_req* req_list[6]; +// int loop=0; +// struct csi_sw_task_req* req=NULL; +// int req_num = sizeof(req_list)/sizeof(struct csi_sw_task_req*); + +// csi_dsp_algo_load_req_t alog_config={ +// .algo_id=0, +// }; + +// if(csi_dsp_task_load_algo(task,&alog_config)) +// { +// FAIL_TEST("algo kernel load fail\n"); + +// } +// for(loop =0 ;loop < req_num;loop++) +// { + +// req =csi_dsp_task_create_request(task); +// if(req==NULL) +// { +// FAIL_TEST("req create fail\n"); +// } +// req_list[loop]=req; +// struct csi_dsp_buffer buf1; + + +// buf1.buf_id = 0; +// buf1.dir = CSI_DSP_BUFFER_IN; +// buf1.type = CSI_DSP_BUF_ALLOC_DRV; +// buf1.plane_count = 1; +// buf1.width =640; +// buf1.height =480; +// buf1.planes[0].stride= 640; +// buf1.planes[0].size= 640*480; + + +// if(csi_dsp_request_add_buffer(req,&buf1)) +// { + +// csi_dsp_task_release_request(req); +// FAIL_TEST("Add buffer:%d\n"); +// } +// int i=0; +// for(i=0;i0;loop--) +// { +// req = csi_dsp_request_dequeue(task); +// if(req==NULL && req->status != CSI_DSP_SW_REQ_DONE) +// { +// FAIL_TEST("req dequeue fail\n"); +// } +// } +// for(loop =0 ;loop < req_num;loop++) +// { +// req = req_list[loop]; +// // MEMCMP_EQUAL((void*)req->buffers[0].planes[0].buf_vir,(void *)req->buffers[1].planes[0].buf_vir,req->buffers[0].planes[0].size); +// int ret = memcmp((void*)req->buffers[0].planes[0].buf_vir,(void *)req->buffers[1].planes[0].buf_vir,req->buffers[0].planes[0].size); +// CHECK_EQUAL_ZERO(ret); +// csi_dsp_task_release_request(req); +// } + + + +// } + + + +// TEST(DspPostProcessTestLibLoader,MultiProcessReqEnqueueConcentration_profile_640) +// { +// struct csi_sw_task_req* req_list[6]; +// struct timeval cur_time_enqueue[6]; +// struct timeval cur_time_dequeue[6]; +// int loop=0; +// struct csi_sw_task_req* req=NULL; +// int req_num = sizeof(req_list)/sizeof(struct csi_sw_task_req*); + +// csi_dsp_algo_load_req_t alog_config={ +// .algo_id=0, +// }; + +// if(csi_dsp_task_load_algo(task,&alog_config)) +// { +// FAIL_TEST("algo kernel load fail\n"); + +// } +// for(loop =0 ;loop < req_num;loop++) +// { + +// req =csi_dsp_task_create_request(task); +// if(req==NULL) +// { +// FAIL_TEST("req create fail\n"); +// } +// req_list[loop]=req; +// struct csi_dsp_buffer buf1; + + +// buf1.buf_id = 0; +// buf1.dir = CSI_DSP_BUFFER_IN; +// buf1.type = CSI_DSP_BUF_ALLOC_DRV; +// buf1.plane_count = 1; +// buf1.width =640; +// buf1.height =480; +// buf1.planes[0].stride= 640; +// buf1.planes[0].size= 640*480; + + +// if(csi_dsp_request_add_buffer(req,&buf1)) +// { + +// csi_dsp_task_release_request(req); +// FAIL_TEST("Add buffer:%d\n"); +// } +// int i=0; +// for(i=0;i0;loop--) +// { +// req = csi_dsp_request_dequeue(task); +// if(req==NULL && req->status != CSI_DSP_SW_REQ_DONE) +// { +// FAIL_TEST("req dequeue fail\n"); +// } +// gettimeofday(&cur_time_dequeue[loop], 0); +// } +// for(loop =0 ;loop < req_num;loop++) +// { +// printf("req:%d,start:%d,%d,end:%d,%d\n",req_list[loop]->request_id,cur_time_enqueue[loop].tv_sec,cur_time_enqueue[loop].tv_usec, +// cur_time_dequeue[loop].tv_sec,cur_time_dequeue[loop].tv_usec); +// } +// for(loop =0 ;loop < req_num;loop++) +// { +// req = req_list[loop]; +// // MEMCMP_EQUAL((void*)req->buffers[0].planes[0].buf_vir,(void *)req->buffers[1].planes[0].buf_vir,req->buffers[0].planes[0].size); +// int ret = memcmp((void*)req->buffers[0].planes[0].buf_vir,(void *)req->buffers[1].planes[0].buf_vir,req->buffers[0].planes[0].size); +// CHECK_EQUAL_ZERO(ret); +// csi_dsp_task_release_request(req); +// } + + +// } + + +// TEST(DspPostProcessTestLibLoader,MultiProcessReqEnqueueConcentration_profile_1920) +// { +// struct csi_sw_task_req* req_list[6]; +// struct timeval cur_time_enqueue[6]; +// struct timeval cur_time_dequeue[6]; +// int loop=0; +// struct csi_sw_task_req* req=NULL; +// int req_num = sizeof(req_list)/sizeof(struct csi_sw_task_req*); + +// csi_dsp_algo_load_req_t alog_config={ +// .algo_id=0, +// }; + +// if(csi_dsp_task_load_algo(task,&alog_config)) +// { +// FAIL_TEST("algo kernel load fail\n"); + +// } +// for(loop =0 ;loop < req_num;loop++) +// { + +// req =csi_dsp_task_create_request(task); +// if(req==NULL) +// { +// FAIL_TEST("req create fail\n"); +// } +// req_list[loop]=req; +// struct csi_dsp_buffer buf1; + + +// buf1.buf_id = 0; +// buf1.dir = CSI_DSP_BUFFER_IN; +// buf1.type = CSI_DSP_BUF_ALLOC_DRV; +// buf1.plane_count = 1; +// buf1.width =1920; +// buf1.height =1080; +// buf1.planes[0].stride= 1920; +// buf1.planes[0].size= 1920*1080; + + +// if(csi_dsp_request_add_buffer(req,&buf1)) +// { + +// csi_dsp_task_release_request(req); +// FAIL_TEST("Add buffer:%d\n"); +// } +// int i=0; +// for(i=0;i0;loop--) +// { +// req = csi_dsp_request_dequeue(task); +// if(req==NULL && req->status != CSI_DSP_SW_REQ_DONE) +// { +// FAIL_TEST("req dequeue fail\n"); +// } +// gettimeofday(&cur_time_dequeue[loop], 0); +// } +// uint32_t counter; +// for(loop =0 ;loop < req_num;loop++) +// { +// printf("req:%d,start:%d,%d,end:%d,%d\n",req_list[loop]->request_id,cur_time_enqueue[loop].tv_sec,cur_time_enqueue[loop].tv_usec, +// cur_time_dequeue[loop].tv_sec,cur_time_dequeue[loop].tv_usec); +// } +// for(loop =0 ;loop < req_num;loop++) +// { +// req = req_list[loop]; +// // MEMCMP_EQUAL((void*)req->buffers[0].planes[0].buf_vir,(void *)req->buffers[1].planes[0].buf_vir,req->buffers[0].planes[0].size); +// int ret = memcmp((void*)req->buffers[0].planes[0].buf_vir,(void *)req->buffers[1].planes[0].buf_vir,req->buffers[0].planes[0].size); +// CHECK_EQUAL_ZERO(ret); +// csi_dsp_task_release_request(req); +// } + +// } + +// TEST(DspPostProcessTestLibLoader,MultiProcessReqEnqueueConcentration_profile_4096) +// { +// struct csi_sw_task_req* req_list[6]; +// struct timeval cur_time_enqueue[6]; +// struct timeval cur_time_dequeue[6]; +// int loop=0; +// struct csi_sw_task_req* req=NULL; +// int req_num = sizeof(req_list)/sizeof(struct csi_sw_task_req*); + +// csi_dsp_algo_load_req_t alog_config={ +// .algo_id=0, +// }; + +// if(csi_dsp_task_load_algo(task,&alog_config)) +// { +// FAIL_TEST("algo kernel load fail\n"); + +// } +// for(loop =0 ;loop < req_num;loop++) +// { + +// req =csi_dsp_task_create_request(task); +// if(req==NULL) +// { +// FAIL_TEST("req create fail\n"); +// } +// req_list[loop]=req; +// struct csi_dsp_buffer buf1; + + +// buf1.buf_id = 0; +// buf1.dir = CSI_DSP_BUFFER_IN; +// buf1.type = CSI_DSP_BUF_ALLOC_DRV; +// buf1.plane_count = 1; +// buf1.width =4096; +// buf1.height =2160; +// buf1.planes[0].stride= 4096; +// buf1.planes[0].size= 4096*2160; + + +// if(csi_dsp_request_add_buffer(req,&buf1)) +// { + +// csi_dsp_task_release_request(req); +// FAIL_TEST("Add buffer:%d\n"); +// } +// int i=0; +// for(i=0;i0;loop--) +// { +// req = csi_dsp_request_dequeue(task); +// if(req==NULL && req->status != CSI_DSP_SW_REQ_DONE) +// { +// FAIL_TEST("req dequeue fail\n"); +// } +// gettimeofday(&cur_time_dequeue[loop], 0); +// } + +// uint32_t counter; +// for(loop =0 ;loop < req_num;loop++) +// { +// printf("req:%d,start:%d,%d,end:%d,%d\n",req_list[loop]->request_id,cur_time_enqueue[loop].tv_sec,cur_time_enqueue[loop].tv_usec, +// cur_time_dequeue[loop].tv_sec,cur_time_dequeue[loop].tv_usec); +// } + +// for(loop =0 ;loop < req_num;loop++) +// { +// req = req_list[loop]; +// // MEMCMP_EQUAL((void*)req->buffers[0].planes[0].buf_vir,(void *)req->buffers[1].planes[0].buf_vir,req->buffers[0].planes[0].size); +// int ret = memcmp((void*)req->buffers[0].planes[0].buf_vir,(void *)req->buffers[1].planes[0].buf_vir,req->buffers[0].planes[0].size); +// CHECK_EQUAL_ZERO(ret); +// csi_dsp_task_release_request(req); +// } + +// } + diff --git a/test/drv_test/test_vi_enhance_process.cpp b/test/drv_test/test_vi_enhance_process.cpp new file mode 100644 index 0000000..d9cff00 --- /dev/null +++ b/test/drv_test/test_vi_enhance_process.cpp @@ -0,0 +1,546 @@ + +#include +#include +#include +#include + +#include "csi_dsp_api.h" +#include "csi_dsp_task_defs.h" +#include "csi_dsp_post_process_defs.h" + +#include "CppUTest/TestHarness.h" +#include "CppUTest/CommandLineTestRunner.h" + +#ifdef __cplusplus +extern "C" { +#endif +#include "video_mem.h" +#ifdef __cplusplus +} +#endif +TEST_GROUP(DspViEnhanceProcessTest) +{ + void setup() + { + instance = csi_dsp_create_instance(0); + if(!instance) + { + FAIL_TEST("create fail\n"); + + } + if( VMEM_create(&mem_allocor) <0) + { + FAIL_TEST("open mem_alloc_fd fail\n"); + } + } + void teardown() + { + // csi_dsp_destroy_task(task); + csi_dsp_delete_instance(instance); + VMEM_destroy(mem_allocor); + } + + int reqDmaBuffer(VmemParams *params) + { + + if(VMEM_allocate(mem_allocor, params)) + { + return -1; + } + + printf("%s,alloct dma buf @ phy:%lx\n",__FUNCTION__,params->phy_address); + if(VMEM_export(mem_allocor,params)) + { + return -1; + } + printf("%s,export dma buf @fd:%x\n",__FUNCTION__,params->fd); + return 0; + + } + int releaseDmaBuffer(VmemParams *params) + { + VMEM_free(mem_allocor, params); + } + void *instance; + void *mem_allocor; +// void *task; +}; + +TEST(DspViEnhanceProcessTest,Isp2Dsp2RyProcessTestBasic) +{ + + void *vi_task= csi_dsp_create_task(instance,CSI_DSP_TASK_HW_TO_HW); + if(!vi_task) + { + FAIL_TEST("task create fail\n"); + } + if(csi_dsp_create_reporter(instance)) + { + FAIL_TEST("reporter create fail\n"); + } + struct csi_dsp_task_fe_para config_params; + + config_params.frontend_type = CSI_DSP_FE_TYPE_ISP; + config_params.task_id = -1; + config_params.isp_param.id=0; + config_params.isp_param.hor=640; + config_params.isp_param.ver=480; + config_params.isp_param.data_fmt=CSI_DSP_IMG_FMT_RAW12_ALGIN; + config_params.isp_param.line_in_entry=640*2; + config_params.isp_param.line_stride=640*2; + config_params.isp_param.buffer_size=640*2*16*2; + config_params.isp_param.buffer_addr=0xb0000000; + + if(csi_dsp_task_config_frontend(vi_task,&config_params)) + { + FAIL_TEST("isp config fail\n"); + } + + struct csi_dsp_task_be_para post_config; + + post_config.backend_type = CSI_DSP_BE_TYPE_POST_ISP; + post_config.task_id = -1; + + post_config.post_isp_param.id=0; + post_config.post_isp_param.hor=640; + post_config.post_isp_param.ver=480; + post_config.post_isp_param.data_fmt=CSI_DSP_IMG_FMT_RAW12_ALGIN; + post_config.post_isp_param.line_in_entry=640*2; + post_config.post_isp_param.line_stride=640*2; + post_config.post_isp_param.buffer_size=640*2*16*2; + post_config.post_isp_param.buffer_addr=0xb0000000; + + + if(csi_dsp_task_config_backend(vi_task,&post_config)) + { + + FAIL_TEST("post-isp config fail\n"); + } + + struct csi_dsp_algo_config_par alog_config={ + .algo_id=0, + .sett_ptr =NULL, + .sett_length =0, + }; + + if(csi_dsp_task_config_algo(vi_task,&alog_config)) + { + FAIL_TEST("algo kernel config fail\n"); + } + + if(csi_dsp_task_register_cb(vi_task,NULL,NULL,32)) + { + FAIL_TEST("algo kernel start fail\n"); + } + + if(csi_dsp_task_start(vi_task)) + { + FAIL_TEST("task start fail\n"); + } + if(csi_dsp_task_stop(vi_task)) + { + FAIL_TEST("task stop fail\n"); + } + + if(csi_dsp_ps_task_unregister_cb(vi_task)) + { + FAIL_TEST("unregister_cb fail\n"); + } + + if(csi_dsp_destroy_reporter(instance)) + { + FAIL_TEST("reporter destroy fail\n"); + } + csi_dsp_destroy_task(vi_task); + +} + +TEST(DspViEnhanceProcessTest,Isp2Dsp2RyProcessTestWithPorperty) +{ + + void *vi_task= csi_dsp_create_task(instance,CSI_DSP_TASK_HW_TO_HW); + if(!vi_task) + { + FAIL_TEST("task create fail\n"); + } + if(csi_dsp_create_reporter(instance)) + { + FAIL_TEST("reporter create fail\n"); + } + struct csi_dsp_task_fe_para config_params; + + config_params.frontend_type = CSI_DSP_FE_TYPE_ISP; + config_params.task_id = -1; + config_params.isp_param.id=0; + config_params.isp_param.hor=640; + config_params.isp_param.ver=480; + config_params.isp_param.data_fmt=CSI_DSP_IMG_FMT_RAW12_ALGIN; + config_params.isp_param.line_in_entry=640*2; + config_params.isp_param.line_stride=640*2; + config_params.isp_param.buffer_size=640*2*16*2; + config_params.isp_param.buffer_addr=0xb0000000; + + if(csi_dsp_task_config_frontend(vi_task,&config_params)) + { + FAIL_TEST("isp config fail\n"); + } + + struct csi_dsp_task_be_para post_config; + + post_config.backend_type = CSI_DSP_BE_TYPE_POST_ISP; + post_config.task_id = -1; + + post_config.post_isp_param.id=0; + post_config.post_isp_param.hor=640; + post_config.post_isp_param.ver=480; + post_config.post_isp_param.data_fmt=CSI_DSP_IMG_FMT_RAW12_ALGIN; + post_config.post_isp_param.line_in_entry=640*2; + post_config.post_isp_param.line_stride=640*2; + post_config.post_isp_param.buffer_size=640*2*16*2; + post_config.post_isp_param.buffer_addr=0xb0000000; + + + if(csi_dsp_task_config_backend(vi_task,&post_config)) + { + + FAIL_TEST("post-isp config fail\n"); + } + + struct algo_property{ + uint32_t width; + uint32_t height; + }; + + struct algo_property sett { + .width = 640, + .height = 480, + }; + + struct csi_dsp_algo_config_par alog_config={ + .algo_id=0, + .sett_ptr =(uint64_t)&sett, + .sett_length =sizeof(struct algo_property), + }; + + if(csi_dsp_task_config_algo(vi_task,&alog_config)) + { + FAIL_TEST("algo kernel config fail\n"); + } + + if(csi_dsp_task_register_cb(vi_task,NULL,NULL,32)) + { + FAIL_TEST("register_cb fail\n"); + } + + if(csi_dsp_task_start(vi_task)) + { + FAIL_TEST("task start fail\n"); + } + + if(csi_dsp_task_stop(vi_task)) + { + FAIL_TEST("task stop fail\n"); + } + + if(csi_dsp_ps_task_unregister_cb(vi_task)) + { + FAIL_TEST("unregister_cb fail\n"); + } + + if(csi_dsp_destroy_reporter(instance)) + { + FAIL_TEST("reporter destroy fail\n"); + } + + csi_dsp_destroy_task(vi_task); + +} + + + +TEST(DspViEnhanceProcessTest,Isp2Dsp2RyProcessMini) +{ + + void *vi_task= csi_dsp_create_task(instance,CSI_DSP_TASK_HW_TO_HW); + if(!vi_task) + { + FAIL_TEST("task create fail\n"); + } + if(csi_dsp_create_reporter(instance)) + { + FAIL_TEST("reporter create fail\n"); + } + + struct algo_property{ + uint32_t width; + uint32_t height; + }; + + struct algo_property sett { + .width = 1280, + .height = 960, + }; + + struct csi_dsp_algo_config_par alog_config={ + .algo_id=0, + .sett_ptr =(uint64_t)&sett, + .sett_length =sizeof(struct algo_property), + }; + + if(csi_dsp_task_config_algo(vi_task,&alog_config)) + { + FAIL_TEST("algo kernel config fail\n"); + } + + if(csi_dsp_task_register_cb(vi_task,NULL,NULL,32)) + { + FAIL_TEST("register_cb fail\n"); + } + + + if(csi_dsp_ps_task_unregister_cb(vi_task)) + { + FAIL_TEST("unregister_cb fail\n"); + } + + if(csi_dsp_destroy_reporter(instance)) + { + FAIL_TEST("reporter destroy fail\n"); + } + + csi_dsp_destroy_task(vi_task); + +} + + +TEST(DspViEnhanceProcessTest,Vipre2Dsp2CpuProcessTestWithDmaBuf) +{ + + void *vi_task= csi_dsp_create_task(instance,CSI_DSP_TASK_HW_TO_SW); + if(!vi_task) + { + FAIL_TEST("task create fail\n"); + } + if(csi_dsp_create_reporter(instance)) + { + FAIL_TEST("reporter create fail\n"); + } + struct csi_dsp_task_fe_para config_params; + + config_params.frontend_type = CSI_DSP_FE_TYPE_VIPRE; + config_params.task_id = -1; + config_params.vipre_param.act_channel= 1; + config_params.vipre_param.hor=640; + config_params.vipre_param.ver=480; + config_params.vipre_param.data_fmt=CSI_DSP_IMG_FMT_RAW12_ALGIN; + config_params.vipre_param.line_num=0; + config_params.vipre_param.line_stride=640*2; + config_params.vipre_param.buffer_size=640*2*16*2; + config_params.vipre_param.buffer_num =1; + config_params.vipre_param.buffer_addr[0]=0xb0000000; + + if(csi_dsp_task_config_frontend(vi_task,&config_params)) + { + FAIL_TEST("vipre config fail\n"); + } + int i,j; + struct csi_dsp_task_be_para * host_config; + VmemParams params; + + host_config = (struct csi_dsp_task_be_para *)malloc(sizeof(struct csi_dsp_task_be_para)+3*sizeof(struct csi_dsp_buffer)); + int width = 640; + int stride = 640; + int height = 1280; + host_config->backend_type = CSI_DSP_BE_TYPE_HOST; + host_config->task_id = -1; + host_config->sw_param.num_buf = 3; + for(int i=0;isw_param.num_buf ;i++) + { + + + host_config->sw_param.bufs[i].buf_id = i; + host_config->sw_param.bufs[i].dir = CSI_DSP_BUFFER_OUT; + host_config->sw_param.bufs[i].type = CSI_DSP_BUF_TYPE_DMA_BUF_IMPORT; + host_config->sw_param.bufs[i].plane_count = 1; + host_config->sw_param.bufs[i].width =width; + host_config->sw_param.bufs[i].height =height; + for(j=0;jsw_param.bufs[i].plane_count;j++) + { + params.size = stride*height; + params.flags = VMEM_FLAG_CONTIGUOUS; + if(reqDmaBuffer(¶ms)) + { + FAIL_TEST("req dma buf fail\n"); + } + + + host_config->sw_param.bufs[i].planes[j].stride= stride; + host_config->sw_param.bufs[i].planes[j].size= params.size; + host_config->sw_param.bufs[i].planes[j].fd = params.fd; + } + if(csi_dsp_task_create_buffer(vi_task,&host_config->sw_param.bufs[i])) + { + FAIL_TEST("create buf fail\n"); + } + } + + + if(csi_dsp_task_config_backend(vi_task,host_config)) + { + free(host_config); + FAIL_TEST("post-isp config fail\n"); + } + + + struct csi_dsp_algo_config_par alog_config={ + .algo_id=0, + .sett_ptr =NULL, + .sett_length =0, + }; + + if(csi_dsp_task_config_algo(vi_task,&alog_config)) + { + FAIL_TEST("algo kernel config fail\n"); + } + + if(csi_dsp_task_register_cb(vi_task,NULL,NULL,32)) + { + FAIL_TEST("algo kernel start fail\n"); + } + + if(csi_dsp_task_start(vi_task)) + { + FAIL_TEST("task start fail\n"); + } + if(csi_dsp_task_stop(vi_task)) + { + FAIL_TEST("task stop fail\n"); + } + + for(int i=0;isw_param.num_buf;i++) + { + if(csi_dsp_task_free_buffer(vi_task,&host_config->sw_param.bufs[i])) + { + FAIL_TEST("Dma buffer free fail\n"); + } + params.phy_address = host_config->sw_param.bufs[i].planes[0].buf_phy; + releaseDmaBuffer(¶ms); + } + free(host_config); + if(csi_dsp_ps_task_unregister_cb(vi_task)) + { + FAIL_TEST("unregister_cb fail\n"); + } + + if(csi_dsp_destroy_reporter(instance)) + { + FAIL_TEST("reporter destroy fail\n"); + } + csi_dsp_destroy_task(vi_task); + +} + +// int main(int argc, char *argv[]) +// { +// printf("Dsp Post Process Test Start !\n"); +// void *instance = csi_dsp_create_instance(0); +// if(!instance) +// { +// printf("create fail\n"); +// return -1; +// } + +// void *task= csi_dsp_create_task(instance,CSI_DSP_TASK_SW_TO_SW); +// if(!task) +// { +// printf("task create fail\n"); +// return -1; +// } + +// struct csi_dsp_algo_config_par alog_config={ +// .algo_id=0, +// }; + +// if(csi_dsp_task_config_algo(task,&alog_config)) +// { +// printf("algo kernel config fail\n"); +// return -1; +// } + +// struct csi_sw_task_req* req=NULL; +// req =csi_dsp_task_create_request(task); +// if(req==NULL) +// { +// printf("req create fail\n"); +// return -1; +// } +// struct csi_dsp_buffer buf1 = +// { +// .buf_id = 0, +// .dir = CSI_DSP_BUFFER_IN, +// .type = CSI_DSP_BUF_ALLOC_DRV, +// .plane_count = 1, +// .width =640, +// .height =480, +// .planes[0].stride= 640, +// .planes[0].size= 604*480, +// }; + +// if(csi_dsp_request_add_buffer(req,&buf1)) +// { +// printf("%s,add buffer:%d\n",__FUNCTION__,buf1.buf_id); +// csi_dsp_task_release_request(req); +// return -1; +// } +// int i=0; +// for(i=0;istatus != CSI_DSP_SW_REQ_DONE) +// { +// printf("%s,req dequeue fail:%d\n",__FUNCTION__); +// return -1; +// } +// if(memcmp((void*)buf1.planes[0].buf_vir,(void *)buf2.planes[0].buf_vir,buf1.planes[0].size)) +// { +// printf("%s,cmp fail\n",__FUNCTION__); +// csi_dsp_task_release_request(req); +// csi_dsp_destroy_task(task); +// csi_dsp_delete_instance(instance); +// return -1; +// } + +// csi_dsp_task_release_request(req); +// csi_dsp_destroy_task(task); +// csi_dsp_delete_instance(instance); +// printf("%s,Test Pass!\n",__FUNCTION__); +// return 0; +// } diff --git a/test/ip_test/Makefile b/test/ip_test/Makefile new file mode 100644 index 0000000..6634496 --- /dev/null +++ b/test/ip_test/Makefile @@ -0,0 +1,33 @@ +TESTS := test_dsp_ip + +CFLAGS = -O0 -Wall -g -lm -lpthread +LDFLAGS += -L../../driver/xrp-user/ -ldsp +LDFLAGS += -Ithread-pthread +SRCS += test_dsp_ip.c + +INCLUDES += -I../../driver/xrp-user/include +# object files will be generated from .c sourcefiles +OBJS = $(notdir $(SRCS:.c=.o)) + + +all: $(TESTS) + +prepare: + mkdir -p output + +$(OBJS):$(SRCS) + $(CC) -c $(CFLAGS) $(INCLUDES) $(SRCS) + +$(TESTS):prepare $(OBJS) + $(CC) -o $(TESTS) $(OBJS) $(CFLAGS) $(LDFLAGS) + cp -r $(TESTS) ./output/ + +clean: + rm -f $(TESTS) + rm -f *.o + rm -rf output + +install: + +.PHONY: clean all prepare common + diff --git a/test/ip_test/test_dsp_ip.c b/test/ip_test/test_dsp_ip.c new file mode 100644 index 0000000..3a489ba --- /dev/null +++ b/test/ip_test/test_dsp_ip.c @@ -0,0 +1,144 @@ + +#include +#include +#include +#include +#include +#include "../../driver/xrp-user/dsp-ps/csi_dsp_core.h" + +#define PAYLOAD_SIZE 32 + +struct message{ + int cmd; + char message[PAYLOAD_SIZE]; +}; + +// void vi_callback( void *context,void * data) +// {} +int main(int argc, char *argv[]) +{ + + void *instance = csi_dsp_create_instance(0); + + if(!instance) + { + printf("create fail\n"); + return -1; + } + void * buf = malloc(1024); + if(buf==NULL) + { + printf("malloc fail\n"); + return 0; + } + + struct csi_dsp_ip_test_par config_para={ + .case_goup="VectorizationTest", + .result_buf_size=1024, + }; + printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); + printf("Start testsuite %s .......\n",config_para.case_goup); + printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); + if(csi_dsp_test_config(instance,&config_para,buf)) + { + printf("Suite Fail NO RESP\n"); + } + printf("%s",buf); + + + return 0; +} + + +// int test(int argc, char *argv[]) +// { + +// unsigned char comm_task[] = XRP_PS_NSID_INITIALIZER; +// struct dsp_instnace *instance = create_dsp_instance(0,comm_task); +// if(!instance) +// { +// printf("create fail\n"); +// return -1; +// } +// if(dsp_ps_create_reporter(instance)) +// { +// printf("reporter create fail\n"); +// return -1; +// } +// unsigned char isp_task[] = XRP_PS_NSID_ISP_ALGO; +// struct csi_dsp_ps_task_handler *vi_task= csi_dsp_create_task(instance,isp_task,1); +// if(!vi_task) +// { +// printf("task create fail\n"); +// return -1; +// } + +// sisp_config_par isp_config = +// { +// .id=0, +// .hor=640, +// .ver=480, +// .data_fmt=IMG_RAW12_FORMAT_ALGIN1, +// .line_in_entry=640*2, +// .line_stride=640*2, +// .buffer_size=640*2*16*2, +// .buffer_addr=0xb0000000, + +// }; +// struct csi_dsp_task_fe_para *fe_cfg=malloc(sizeof(struct csi_dsp_task_fe_para)+sizeof(sisp_config_par)-1); + +// fe_cfg->frontend_type=CSI_DSP_FE_TYPE_ISP; +// memcpy(fe_cfg->para_data,&isp_config,siezof(sisp_config_par)); +// if(csi_dsp_task_config_frontend(vi_task,fe_cfg)) +// { + +// printf("isp config fail\n"); +// return -1; +// } +// spost_isp_config_par post_config = +// { +// .id=0, +// .hor=640, +// .ver=480, +// .data_fmt=IMG_RAW12_FORMAT_ALGIN1, +// .line_in_entry=640*2, +// .line_stride=640*2, +// .buffer_size=640*2*16*2, +// .buffer_addr=0xb0000000, + +// }; +// struct csi_dsp_task_be_para *be_cfg=malloc(sizeof(struct csi_dsp_task_be_para)+sizeof(spost_isp_config_par)-1); +// be_cfg->CSI_DSP_BE_TYPE_POST_ISP; +// memcpy(fe_cfg->para_data,&post_config,siezof(sisp_config_par)); +// if(csi_dsp_task_config_backend(vi_task,&be_cfg)) +// { + +// printf("post-isp config fail\n"); +// return -1; +// } + +// salgo_config_par alog_config={ +// .algo_id=0, +// }; + +// if(csi_dsp_task_config_algo(vi_task,&alog_config)) +// { +// printf("algo kernel config fail\n"); +// return -1; +// } +// vi_task->report_id=1; +// if(csi_dsp_task_start(vi_task,isp_algo_result_handler,NULL,32)) +// { +// printf("algo kernel start fail\n"); +// return -1; +// } + +// while(1) +// { +// ; +// } +// csi_dsp_task_stop(vi_task); +// csi_dsp_destroy_task(vi_task); +// csi_dsp_delete_instance(vi_task); +// return 0; +// } \ No newline at end of file diff --git a/test/npu_test/DSP_FW_FOR_NPU b/test/npu_test/DSP_FW_FOR_NPU new file mode 100644 index 0000000..c096c44 Binary files /dev/null and b/test/npu_test/DSP_FW_FOR_NPU differ diff --git a/test/npu_test/Makefile b/test/npu_test/Makefile new file mode 100644 index 0000000..0c1cd6e --- /dev/null +++ b/test/npu_test/Makefile @@ -0,0 +1,38 @@ +TESTS := test_dsp_npu + +CFLAGS = -O0 -Wall -g -lm -lpthread -lrt +LDFLAGS += -L../../driver/xrp-user/ -ldsp +LDFLAGS += -Ithread-pthread +SRCS += io.c +SRCS += test_bench_utils.c +SRCS += dsp_src_test.c + +INCLUDES += -I../../driver/xrp-user/include +# object files will be generated from .c sourcefiles +OBJS = $(notdir $(SRCS:.c=.o)) + + +all: $(TESTS) npu_sink_test + +prepare: + mkdir -p output + +$(OBJS):$(SRCS) + $(CC) -c $(CFLAGS) $(INCLUDES) $(SRCS) + +$(TESTS):prepare $(OBJS) + $(CC) -o $(TESTS) $(OBJS) $(CFLAGS) $(LDFLAGS) + cp -r $(TESTS) ./output/ + +npu_sink_test: npu_sink_test.c io.c test_bench_utils.c + $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) + cp -r npu_sink_test ./output/ +clean: + rm -f $(TESTS) + rm -f *.o + rm -rf output + +install: + +.PHONY: clean all prepare common + diff --git a/test/npu_test/detect.cpp b/test/npu_test/detect.cpp new file mode 100644 index 0000000..18b8424 --- /dev/null +++ b/test/npu_test/detect.cpp @@ -0,0 +1,245 @@ +#include +#include +#include +#include +#include +#include "detect.h" +int num_class = 21; +float nms_threshold = 0.45f; +int nms_top_k = 100; +int keep_top_k = 100; +float confidence_threshold = 0.51f; + + +static inline float intersection_area(const BBoxRect& a, const BBoxRect& b) +{ + if (a.xmin > b.xmax || a.xmax < b.xmin || a.ymin > b.ymax || a.ymax < b.ymin) + { + // no intersection + return 0.f; + } + + float inter_width = std::min(a.xmax, b.xmax) - std::max(a.xmin, b.xmin); + float inter_height = std::min(a.ymax, b.ymax) - std::max(a.ymin, b.ymin); + + return inter_width * inter_height; +} + +template +static void qsort_descent_inplace(std::vector& datas, std::vector& scores, int left, int right) +{ + int i = left; + int j = right; + //must be instanced ... so this function must include vector + float p = scores[(left + right) / 2]; + + while (i <= j) + { + while (scores[i] > p) + i++; + + while (scores[j] < p) + j--; + + if (i <= j) + { + // swap + std::swap(datas[i], datas[j]); + std::swap(scores[i], scores[j]); + + i++; + j--; + } + } + + if (left < j) + qsort_descent_inplace(datas, scores, left, j); + + if (i < right) + qsort_descent_inplace(datas, scores, i, right); +} + +template +static void qsort_descent_inplace(std::vector& datas, std::vector& scores) +{ + if (datas.empty() || scores.empty()) + return; + + qsort_descent_inplace(datas, scores, 0, scores.size() - 1); +} + +static void nms_sorted_bboxes(const std::vector& bboxes, std::vector& picked, float nms_threshold) +{ + picked.clear(); + const int n = bboxes.size(); + std::vector areas(n); + for (int i = 0; i < n; i++) + { + const BBoxRect& r = bboxes[i]; + + float width = r.xmax - r.xmin; + float height = r.ymax - r.ymin; + + areas[i] = width * height; + } + + for (int i = 0; i < n; i++) + { + const BBoxRect& a = bboxes[i]; + + int keep = 1; + for (int j = 0; j < (int)picked.size(); j++) + { + const BBoxRect& b = bboxes[picked[j]]; + + float interarea = intersection_area(a, b); + float unionarea = areas[i] + areas[picked[j]] - interarea; + if (interarea / unionarea > nms_threshold) + keep = 0; + } + + if (keep) + picked.push_back(i); + } +} +int ssdforward(float *location,float * confidence,float * priorbox,BBox *bboxes,BBoxOut *out) +{ + const float* location_ptr = location; + const float* priorbox_ptr = priorbox; + const float* variance_ptr = priorbox + num_prior*4; + + for (int i = 0; i < num_prior; i++) + { + const float* loc = location_ptr + i * 4; + const float* pb = priorbox_ptr + i * 4; + const float* var = variance_ptr;// + i * 4; + + float* bbox = (float*)&bboxes[i];// bboxes.row(i); + + // CENTER_SIZE + float pb_w = pb[2] - pb[0]; + float pb_h = pb[3] - pb[1]; + float pb_cx = (pb[0] + pb[2]) * 0.5f; + float pb_cy = (pb[1] + pb[3]) * 0.5f; + + float bbox_cx = var[0] * loc[0] * pb_w + pb_cx; + float bbox_cy = var[1] * loc[1] * pb_h + pb_cy; + float bbox_w = exp(var[2] * loc[2]) * pb_w; + float bbox_h = exp(var[3] * loc[3]) * pb_h; + + bbox[0] = bbox_cx - bbox_w * 0.5f; + bbox[1] = bbox_cy - bbox_h * 0.5f; + bbox[2] = bbox_cx + bbox_w * 0.5f; + bbox[3] = bbox_cy + bbox_h * 0.5f; + } + + // sort and nms for each class + std::vector< std::vector > all_class_bbox_rects; + std::vector< std::vector > all_class_bbox_scores; + all_class_bbox_rects.resize(num_class); + all_class_bbox_scores.resize(num_class); + + // start from 1 to ignore background class + for (int i = 1; i < num_class; i++) + { + // filter by confidence_threshold + std::vector class_bbox_rects; + std::vector class_bbox_scores; + + for (int j = 0; j < num_prior; j++) + { + float score = confidence[j * num_class + i]; + + if (score > confidence_threshold) + { + const float* bbox = (float*)&bboxes[j]; + BBoxRect c = { bbox[0], bbox[1], bbox[2], bbox[3], i }; + class_bbox_rects.push_back(c); + class_bbox_scores.push_back(score); + } + } + + // sort inplace + qsort_descent_inplace(class_bbox_rects, class_bbox_scores); + + // keep nms_top_k + if (nms_top_k < (int)class_bbox_rects.size()) + { + class_bbox_rects.resize(nms_top_k); + class_bbox_scores.resize(nms_top_k); + } + + // apply nms + std::vector picked; + nms_sorted_bboxes(class_bbox_rects, picked, nms_threshold); + + // select + for (int j = 0; j < (int)picked.size(); j++) + { + int z = picked[j]; + all_class_bbox_rects[i].push_back(class_bbox_rects[z]); + all_class_bbox_scores[i].push_back(class_bbox_scores[z]); + } + } + + // gather all class + std::vector bbox_rects; + std::vector bbox_scores; + + for (int i = 1; i < num_class; i++) + { + const std::vector& class_bbox_rects = all_class_bbox_rects[i]; + const std::vector& class_bbox_scores = all_class_bbox_scores[i]; + + bbox_rects.insert(bbox_rects.end(), class_bbox_rects.begin(), class_bbox_rects.end()); + bbox_scores.insert(bbox_scores.end(), class_bbox_scores.begin(), class_bbox_scores.end()); + } + + // global sort inplace + qsort_descent_inplace(bbox_rects, bbox_scores); + + // keep_top_k + if (keep_top_k < (int)bbox_rects.size()) + { + bbox_rects.resize(keep_top_k); + bbox_scores.resize(keep_top_k); + } + + int num_detected = bbox_rects.size(); + + if(num_detected >100) num_detected =100; + for (int i = 0; i < num_detected; i++) + { + const BBoxRect& r = bbox_rects[i]; + float score = bbox_scores[i]; + float* outptr = (float*)&out[i]; + int *labelptr = (int *)outptr; + labelptr[0] = r.label; + outptr[1] = score; + outptr[2] = r.xmin; + outptr[3] = r.ymin; + outptr[4] = r.xmax; + outptr[5] = r.ymax; + } + + return num_detected; +} + +int readbintomem(float *dst,char *path) +{ + FILE *pFile = fopen (path, "rb" ); + if (pFile==NULL) + { + fputs ("File error",stderr); + exit (1); + } + fseek (pFile , 0 , SEEK_END); + int fsize = ftell(pFile); + rewind (pFile); + + //buffer = (char*) malloc (sizeof(char)*lSize); + int result = fread (dst,1,fsize,pFile); + fclose(pFile); + + return result; +} diff --git a/test/npu_test/detect.h b/test/npu_test/detect.h new file mode 100644 index 0000000..29c688b --- /dev/null +++ b/test/npu_test/detect.h @@ -0,0 +1,49 @@ +#ifndef DETECT_H +#define DETECT_H + +#ifdef __cplusplus +extern "C" { +#endif +//#include "cnndecoder.h" +typedef struct BBoxOut +{ + int label; + float score; + float xmin; + float ymin; + float xmax; + float ymax; +}BBoxOut; +#define PIX3218 0 +#define PIX3030 1 +#if PIX3218 +#define num_prior 1224 +#elif PIX3030 +#define num_prior 1917 +#endif +typedef struct BBox +{ + float xmin; + float ymin; + float xmax; + float ymax; +}BBox; + +typedef struct BBoxRect +{ + float xmin; + float ymin; + float xmax; + float ymax; + int label; +}BBoxRect; + + +int ssdforward(float *location,float * confidence,float * priorbox,BBox *bboxes,BBoxOut *out); +int readbintomem(float *dst,char *path); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/test/npu_test/dsp_src_test.c b/test/npu_test/dsp_src_test.c new file mode 100644 index 0000000..47de202 --- /dev/null +++ b/test/npu_test/dsp_src_test.c @@ -0,0 +1,181 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/* auto generate by HHB_VERSION "1.8.0" */ + +#include +#include +#include +#include +#include +#include +#include "io.h" +// #include "csi_ref.h" +#include "shm_common.h" +#include "test_bench_utils.h" +#include "../../driver/xrp-user/include/dsp_ps_ns.h" +#include "../../driver/xrp-user/dsp-ps/csi_dsp_core.h" +#include "csi_dsp_api.h" +#define MODULE_NAME "dsp_test" +#define FILE_LENGTH 1028 + +#define WIDTH 224 +#define HEIGHT 224 +int input_size[] = {1 * 3 * WIDTH * HEIGHT, }; + +#define BASE_MEMORY 0xD0000000 +typedef struct _PictureBuffer { + unsigned int bus_address; + void *virtual_address; + unsigned int size; +} PictureBuffer; + + +void AllocateBuffers(PictureBuffer picbuffers[NUM_OF_BUFFERS],unsigned int buffer_num, unsigned int size, int fd_mem) { + unsigned int bus_address = BASE_MEMORY; + unsigned int buffer_size = (size + 0xFFF) & ~0xFFF; + for (int i = 0; i < buffer_num; i++) { + picbuffers[i].virtual_address = mmap(0, buffer_size, PROT_READ | PROT_WRITE, + MAP_SHARED, fd_mem, + bus_address); + printf("mmap %p from %x with size %d\n", picbuffers[i].virtual_address, bus_address, size); + picbuffers[i].bus_address = bus_address; + picbuffers[i].size = buffer_size; + bus_address += buffer_size; + } +} + +void FreeBuffers(PictureBuffer picbuffers[NUM_OF_BUFFERS], unsigned int buffer_num, unsigned int size, int fd_mem) { + for (int i = 0; i < buffer_num; i++) { + munmap(picbuffers[i].virtual_address, picbuffers[i].size); + } +} + +int main(int argc, char **argv) { + char **data_path = NULL; + int input_num = 1; + int output_num = 1; + int i; + int index = 0; + + if (argc < (1 + input_num)) { + printf("Please set valide args: ./dsp_src_test image.rgb\n"); + return -1; + } else { + data_path = argv + 1; + } + + struct csi_dsp_instance *instance = csi_dsp_create_instance(0); + if(!instance) + { + printf("create fail\n"); + return -1; + } + struct data_move_msg cmd; + + int fd = shm_open("/ispnpu", O_RDWR, 0); + if (fd == -1) { + printf("%s: failed to shm_open", MODULE_NAME); + return -1; + } + ShmBuffer *buffer = mmap(NULL, sizeof(ShmBuffer), + PROT_READ | PROT_WRITE, + MAP_SHARED, fd, 0); + if (buffer == MAP_FAILED) { + printf("%s: failed to mmap", MODULE_NAME); + return -1; + } + + int fd_mem = open("/dev/mem", O_RDWR | O_SYNC); + if (fd_mem < 0) { + printf("%s: failed to open /dev/mem", MODULE_NAME); + return -1; + } + + int in_size = input_size[0]; + char filename[FILE_LENGTH] = {0}; + char filename_prefix[FILE_LENGTH] = {0}; + uint64_t start_time, end_time; + PictureBuffer picbuffers[NUM_OF_BUFFERS*2]; + AllocateBuffers(picbuffers, NUM_OF_BUFFERS*2,in_size, fd_mem); + + + do { + if (buffer->exit == 0) { + // Wait for available slot in buffer queue + printf("sem_wait before\n"); + if (sem_wait(&buffer->sem_sink) == -1) { + printf("%s: failed to open sem_wait", MODULE_NAME); + return -1; + } + printf("sem_wait end\n"); + //ProcessOneFrame(picbuffers[index].virtual_address, fp, size); + fill_buffer_from_file(data_path[0], picbuffers[index].virtual_address); + printf("%s: prepared frame %d 0x%08x: %dx%d\n", + MODULE_NAME, index, picbuffers[index].bus_address, + WIDTH, HEIGHT); + + cmd.src_addr= picbuffers[index].bus_address; + cmd.dst_addr= picbuffers[NUM_OF_BUFFERS+index].bus_address; + cmd.size = picbuffers[index].size; + + printf("%s: data move cmd frame %d from 0x%lx to 0x%lx ,size:%d\n", + MODULE_NAME, index, cmd.src_addr, cmd.dst_addr,cmd.size); + //snprintf(filename, FILE_LENGTH, "%s_src_data%u.txt", filename_prefix, i); + //save_uint8_to_file(filename, (uint8_t*)picbuffers[index].virtual_address, in_size); + if(csi_dsp_cmd_send(instance->comm_queue,PS_CMD_DATA_MOVE,&cmd,sizeof(struct data_move_msg),NULL,0,NULL)) + { + printf("%s:cmd_to_dsp fail\n",MODULE_NAME); + return -1; + } + + + PictureInfo *pic = &buffer->pics[index]; + pic->bus_address_rgb = picbuffers[NUM_OF_BUFFERS+index].bus_address; + pic->pic_width = WIDTH; + pic->pic_height = HEIGHT; + printf("%s: Processed frame %d 0x%08x: %dx%d\n", + MODULE_NAME, index, pic->bus_address_rgb, + pic->pic_width, pic->pic_height); + // Notify npu one picture is ready for inference + if (sem_post(&buffer->sem_src) == -1) { + printf("%s: failed to sem_post\n", MODULE_NAME); + return -1; + } + } + else { + // If encoder set the 'exit' flag to 1, finish process + printf("%s: Exit at loop %d\n", MODULE_NAME, index); + // Notify encoder all the resource has been released + if (sem_post(&buffer->sem_src) == -1) { + printf("%s: failed to sem_post\n", MODULE_NAME); + return -1; + } + } + index = (index + 1) % NUM_OF_BUFFERS; + } while (buffer->exit == 0); + +cleanup: + FreeBuffers(picbuffers, NUM_OF_BUFFERS*2,in_size, fd_mem); + munmap(buffer, sizeof(ShmBuffer)); + shm_unlink("/ispnpu"); + + return 0; +} + diff --git a/test/npu_test/io.c b/test/npu_test/io.c new file mode 100644 index 0000000..322870a --- /dev/null +++ b/test/npu_test/io.c @@ -0,0 +1,214 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/* auto generate by HHB_VERSION "1.8.x" */ + +#include "io.h" + +/****************************************************************************** + * * + * Utils for process data * + * * + * ***************************************************************************/ + +/*! + * \brief Get the type of file (JPEG PNG or txt/tensor by suffix + * + * \param filename Image file name. + * \return FILE_PNG FILE_JPEG or FILE_TENSOR of enum file_type + * + */ +enum file_type get_file_type(const char* filename) { + enum file_type type = 0; + const char* ptr; + char sep = '.'; + uint32_t pos, n; + char buff[32] = {0}; + + ptr = strrchr(filename, sep); + pos = ptr - filename; + n = strlen(filename) - (pos + 1); + strncpy(buff, filename + (pos + 1), n); + + if (strcmp(buff, "jpg") == 0 || strcmp(buff, "jpeg") == 0 || strcmp(buff, "JPG") == 0 || + strcmp(buff, "JPEG") == 0) { + type = FILE_JPEG; + } else if (strcmp(buff, "png") == 0 || strcmp(buff, "PNG") == 0) { + type = FILE_PNG; + } else if (strcmp(buff, "tensor") == 0) { + type = FILE_TENSOR; + } else if (strcmp(buff, "txt") == 0) { + type = FILE_TXT; + } else if (strcmp(buff, "bin") == 0) { + type = FILE_BIN; + } else if (strcmp(buff, "rgb") == 0) { + type = 0; + } else { + printf("Unsupport for .%s file\n", buff); + exit(1); + } + return type; +} + +/*! + * \brief Save float data into file. + * + * \param filename The file that you will put the data into. + * \param data The float data that you will put into file. + * \param size The size of data. + */ +void save_data_to_file(const char* filename, float* data, uint32_t size) { + int i = 0; + FILE* fp = fopen(filename, "w+"); + for (i = 0; i < size; i++) { + if (i == size - 1) { + fprintf(fp, "%f", data[i]); + } else { + fprintf(fp, "%f\n", data[i]); + } + } + fclose(fp); +} + +void save_uint8_to_file(const char* filename, uint8_t* data, uint32_t size) { + int i = 0; + FILE* fp = fopen(filename, "w+"); + for (i = 0; i < size; i++) { + if (i == size - 1) { + fprintf(fp, "%d", data[i]); + } else { + fprintf(fp, "%d\n", data[i]); + } + } + fclose(fp); +} + +void save_uint8_to_binary(const char* filename, uint8_t* data, uint32_t size) { + int i = 0; + FILE* fp = fopen(filename, "w+"); + fwrite(data, 1, size, fp); + fclose(fp); +} + +/*! + * \brief Get the binary params char from model.params + * + * \param filename It is generally model.params for anole + * \return The char data of params + * + */ +int fill_buffer_from_file(const char* filename, char* buffer) { + int file_size; + int ret; + FILE* fp = fopen(filename, "rb"); + if (fp == NULL) { + printf("Invalid input file: %s\n", filename); + return -1; + } + fseek(fp, 0, SEEK_END); + file_size = ftell(fp); + rewind(fp); + + ret = fread(buffer, 1, file_size, fp); + if (ret != file_size) { + printf("Read input file error\n"); + return -1; + } + + fclose(fp); + return 0; +} + +char* get_binary_from_file(const char* filename) { + char* buffer = NULL; + int file_size; + int ret; + FILE* fp = fopen(filename, "rb"); + if (fp == NULL) { + printf("Invalid input file: %s\n", filename); + return NULL; + } + fseek(fp, 0, SEEK_END); + file_size = ftell(fp); + rewind(fp); + + buffer = (char*)malloc(file_size); // NOLINT + if (buffer == NULL) { + printf("Malloc fail\n"); + return NULL; + } + + ret = fread(buffer, 1, file_size, fp); + if (ret != file_size) { + printf("Read input file error\n"); + return NULL; + } + + fclose(fp); + return buffer; +} + +char** read_string_from_file(const char* filename, int* len) { + char buff[MAX_FILENAME_LEN]; + char** result = (char**)malloc(sizeof(char*) * (MAX_FILE_LINE * MAX_INPUT_NUMBER)); // NOLINT + char *find, *sep, *inter; + FILE* fp = fopen(filename, "r+"); + if (fp == NULL) { + return NULL; + } + int cnt = 0; + while (fgets(buff, sizeof(buff), fp)) { + find = strchr(buff, '\n'); + if (find) { + *find = '\0'; + } + sep = strtok(buff, " "); // NOLINT + inter = (char*)malloc((strlen(sep) + 2) * sizeof(char)); // NOLINT + memcpy(inter, sep, strlen(sep) + 1); + result[cnt++] = inter; + while (sep != NULL) { + sep = strtok(NULL, " "); // NOLINT + if (sep) { + inter = (char*)malloc((strlen(sep) + 2) * sizeof(char)); // NOLINT + memcpy(inter, sep, strlen(sep) + 1); + result[cnt++] = inter; + } + } + } + *len = cnt; + fclose(fp); + return result; +} + +uint32_t shape2string(uint32_t* shape, uint32_t dim_num, char* buf, uint32_t buf_sz) { + uint32_t s; + uint32_t count; + if (NULL == shape || NULL == buf || dim_num == 0 || buf_sz == 0) { + return 0; + } + count = 0; + for (s = 0; s < dim_num; s++) { + if (count >= buf_sz) { + break; + } + count += snprintf(&buf[count], buf_sz - count, "%d_", shape[s]); + } + buf[count - 1] = 0; + return count; +} diff --git a/test/npu_test/io.h b/test/npu_test/io.h new file mode 100644 index 0000000..ad1160b --- /dev/null +++ b/test/npu_test/io.h @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/* auto generate by HHB_VERSION "1.8.x" */ + +#ifndef HHB_IO_H_ +#define HHB_IO_H_ + +#include +#include +#include +#include +#include + +#define MAX_FILE_LINE 50001 +#define MAX_INPUT_NUMBER 4 +#define MAX_FILENAME_LEN 128 + +enum file_type { FILE_PNG, FILE_JPEG, FILE_TENSOR, FILE_TXT, FILE_BIN }; + +/* Utils to process image data*/ +enum file_type get_file_type(const char* filename); +void save_data_to_file(const char* filename, float* data, uint32_t size); +void save_uint8_to_file(const char* filename, uint8_t* data, uint32_t size); +void save_uint8_to_binary(const char* filename, uint8_t* data, uint32_t size); +char* get_binary_from_file(const char* filename); +int fill_buffer_from_file(const char* filename, char *buffer); +char** read_string_from_file(const char* filename, int* len); +uint32_t shape2string(uint32_t* shape, uint32_t dim_num, char* buf, uint32_t buf_sz); + +#endif // HHB_IO_H_ diff --git a/test/npu_test/model.c b/test/npu_test/model.c new file mode 100644 index 0000000..4ae123f --- /dev/null +++ b/test/npu_test/model.c @@ -0,0 +1,3437 @@ +/* auto generate by HHB_VERSION 1.8.x */ + +#include + +void *csinn_(char *params_base) { + struct csi_session *sess = csi_alloc_session(); + sess->model_name = "csi.mbs.bin"; + sess->base_api = CSINN_LIGHT; + sess->base_dtype = CSINN_DTYPE_FLOAT32; + // sess->debug_level = CSI_DEBUG_LEVEL_INFO; + csi_session_init(sess); + csi_set_input_number(1, sess); + csi_set_output_number(3, sess); + + struct csi_tensor *const_output_0 = csi_alloc_tensor(sess); + const_output_0->data = params_base + 0; + const_output_0->dim[0] = 1; + const_output_0->dim[1] = 2; + const_output_0->dim[2] = 7668; + const_output_0->dim_count = 3; + + struct csi_tensor *input0_1 = csi_alloc_tensor(sess); + input0_1->name = "input0_1"; + input0_1->dtype = CSINN_DTYPE_FLOAT32; + input0_1->layout = CSINN_LAYOUT_NCHW; + input0_1->dim[0] = 1; + input0_1->dim[1] = 3; + input0_1->dim[2] = 300; + input0_1->dim[3] = 300; + input0_1->dim_count = 4; + input0_1->qinfo = (struct csi_quant_info *)(params_base + 61344); + input0_1->quant_channel = 1; + struct csi_tensor *output_1 = csi_alloc_tensor(sess); + output_1->name = "output_1"; + output_1->dtype = CSINN_DTYPE_FLOAT32; + output_1->layout = CSINN_LAYOUT_NCHW; + output_1->dim[0] = 1; + output_1->dim[1] = 32; + output_1->dim[2] = 150; + output_1->dim[3] = 150; + output_1->dim_count = 4; + output_1->qinfo = (struct csi_quant_info *)(params_base + 61368); + output_1->quant_channel = 1; + struct csi_tensor *kernel_1 = csi_alloc_tensor(sess); + kernel_1->data = params_base + 61392; + kernel_1->name = "kernel_1"; + kernel_1->is_const = 1; + kernel_1->dtype = CSINN_DTYPE_FLOAT32; + kernel_1->layout = CSINN_LAYOUT_OIHW; + kernel_1->dim[0] = 32; + kernel_1->dim[1] = 3; + kernel_1->dim[2] = 3; + kernel_1->dim[3] = 3; + kernel_1->dim_count = 4; + kernel_1->qinfo = (struct csi_quant_info *)(params_base + 64848); + kernel_1->quant_channel = 1; + struct csi_tensor *bias_1 = csi_alloc_tensor(sess); + bias_1->data = params_base + 64872; + bias_1->name = "bias_1"; + bias_1->is_const = 1; + bias_1->dtype = CSINN_DTYPE_FLOAT32; + bias_1->layout = CSINN_LAYOUT_O; + bias_1->dim[0] = 32; + bias_1->dim_count = 1; + bias_1->qinfo = (struct csi_quant_info *)(params_base + 65000); + bias_1->quant_channel = 1; + struct conv2d_params *params_1 = csi_alloc_params(sizeof(struct conv2d_params), sess); + params_1->group = 1; + params_1->stride_height = 2; + params_1->stride_width = 2; + params_1->dilation_height = 1; + params_1->dilation_width = 1; + params_1->conv_extra.kernel_tm = NULL; + params_1->conv_extra.conv_mode = CSINN_DIRECT; + params_1->pad_top = 1; + params_1->pad_left = 1; + params_1->pad_down = 1; + params_1->pad_right = 1; + params_1->base.name = "params_1"; + csi_conv2d_init(input0_1, output_1, kernel_1, bias_1, params_1); + struct csi_tensor *output_2 = csi_alloc_tensor(sess); + output_2->name = "output_2"; + output_2->dtype = CSINN_DTYPE_FLOAT32; + output_2->layout = CSINN_LAYOUT_NCHW; + output_2->dim[0] = 1; + output_2->dim[1] = 32; + output_2->dim[2] = 150; + output_2->dim[3] = 150; + output_2->dim_count = 4; + output_2->qinfo = (struct csi_quant_info *)(params_base + 65024); + output_2->quant_channel = 1; + struct relu_params *params_2 = csi_alloc_params(sizeof(struct relu_params), sess); + params_2->base.name = "params_2"; + csi_relu_init(output_1, output_2, params_2); + struct csi_tensor *output_3 = csi_alloc_tensor(sess); + output_3->name = "output_3"; + output_3->dtype = CSINN_DTYPE_FLOAT32; + output_3->layout = CSINN_LAYOUT_NCHW; + output_3->dim[0] = 1; + output_3->dim[1] = 32; + output_3->dim[2] = 150; + output_3->dim[3] = 150; + output_3->dim_count = 4; + output_3->qinfo = (struct csi_quant_info *)(params_base + 65048); + output_3->quant_channel = 1; + struct csi_tensor *kernel_3 = csi_alloc_tensor(sess); + kernel_3->data = params_base + 65072; + kernel_3->name = "kernel_3"; + kernel_3->is_const = 1; + kernel_3->dtype = CSINN_DTYPE_FLOAT32; + kernel_3->layout = CSINN_LAYOUT_OIHW; + kernel_3->dim[0] = 32; + kernel_3->dim[1] = 1; + kernel_3->dim[2] = 3; + kernel_3->dim[3] = 3; + kernel_3->dim_count = 4; + kernel_3->qinfo = (struct csi_quant_info *)(params_base + 66224); + kernel_3->quant_channel = 1; + struct csi_tensor *bias_3 = csi_alloc_tensor(sess); + bias_3->data = params_base + 66248; + bias_3->name = "bias_3"; + bias_3->is_const = 1; + bias_3->dtype = CSINN_DTYPE_FLOAT32; + bias_3->layout = CSINN_LAYOUT_O; + bias_3->dim[0] = 32; + bias_3->dim_count = 1; + bias_3->qinfo = (struct csi_quant_info *)(params_base + 66376); + bias_3->quant_channel = 1; + struct conv2d_params *params_3 = csi_alloc_params(sizeof(struct conv2d_params), sess); + params_3->group = 32; + params_3->stride_height = 1; + params_3->stride_width = 1; + params_3->dilation_height = 1; + params_3->dilation_width = 1; + params_3->conv_extra.kernel_tm = NULL; + params_3->conv_extra.conv_mode = CSINN_DIRECT; + params_3->pad_top = 1; + params_3->pad_left = 1; + params_3->pad_down = 1; + params_3->pad_right = 1; + params_3->base.name = "params_3"; + csi_conv2d_init(output_2, output_3, kernel_3, bias_3, params_3); + struct csi_tensor *output_4 = csi_alloc_tensor(sess); + output_4->name = "output_4"; + output_4->dtype = CSINN_DTYPE_FLOAT32; + output_4->layout = CSINN_LAYOUT_NCHW; + output_4->dim[0] = 1; + output_4->dim[1] = 32; + output_4->dim[2] = 150; + output_4->dim[3] = 150; + output_4->dim_count = 4; + output_4->qinfo = (struct csi_quant_info *)(params_base + 66400); + output_4->quant_channel = 1; + struct relu_params *params_4 = csi_alloc_params(sizeof(struct relu_params), sess); + params_4->base.name = "params_4"; + csi_relu_init(output_3, output_4, params_4); + struct csi_tensor *output_5 = csi_alloc_tensor(sess); + output_5->name = "output_5"; + output_5->dtype = CSINN_DTYPE_FLOAT32; + output_5->layout = CSINN_LAYOUT_NCHW; + output_5->dim[0] = 1; + output_5->dim[1] = 64; + output_5->dim[2] = 150; + output_5->dim[3] = 150; + output_5->dim_count = 4; + output_5->qinfo = (struct csi_quant_info *)(params_base + 66424); + output_5->quant_channel = 1; + struct csi_tensor *kernel_5 = csi_alloc_tensor(sess); + kernel_5->data = params_base + 66448; + kernel_5->name = "kernel_5"; + kernel_5->is_const = 1; + kernel_5->dtype = CSINN_DTYPE_FLOAT32; + kernel_5->layout = CSINN_LAYOUT_OIHW; + kernel_5->dim[0] = 64; + kernel_5->dim[1] = 32; + kernel_5->dim[2] = 1; + kernel_5->dim[3] = 1; + kernel_5->dim_count = 4; + kernel_5->qinfo = (struct csi_quant_info *)(params_base + 74640); + kernel_5->quant_channel = 1; + struct csi_tensor *bias_5 = csi_alloc_tensor(sess); + bias_5->data = params_base + 74664; + bias_5->name = "bias_5"; + bias_5->is_const = 1; + bias_5->dtype = CSINN_DTYPE_FLOAT32; + bias_5->layout = CSINN_LAYOUT_O; + bias_5->dim[0] = 64; + bias_5->dim_count = 1; + bias_5->qinfo = (struct csi_quant_info *)(params_base + 74920); + bias_5->quant_channel = 1; + struct conv2d_params *params_5 = csi_alloc_params(sizeof(struct conv2d_params), sess); + params_5->group = 1; + params_5->stride_height = 1; + params_5->stride_width = 1; + params_5->dilation_height = 1; + params_5->dilation_width = 1; + params_5->conv_extra.kernel_tm = NULL; + params_5->conv_extra.conv_mode = CSINN_DIRECT; + params_5->pad_top = 0; + params_5->pad_left = 0; + params_5->pad_down = 0; + params_5->pad_right = 0; + params_5->base.name = "params_5"; + csi_conv2d_init(output_4, output_5, kernel_5, bias_5, params_5); + struct csi_tensor *output_6 = csi_alloc_tensor(sess); + output_6->name = "output_6"; + output_6->dtype = CSINN_DTYPE_FLOAT32; + output_6->layout = CSINN_LAYOUT_NCHW; + output_6->dim[0] = 1; + output_6->dim[1] = 64; + output_6->dim[2] = 150; + output_6->dim[3] = 150; + output_6->dim_count = 4; + output_6->qinfo = (struct csi_quant_info *)(params_base + 74944); + output_6->quant_channel = 1; + struct relu_params *params_6 = csi_alloc_params(sizeof(struct relu_params), sess); + params_6->base.name = "params_6"; + csi_relu_init(output_5, output_6, params_6); + struct csi_tensor *output_7 = csi_alloc_tensor(sess); + output_7->name = "output_7"; + output_7->dtype = CSINN_DTYPE_FLOAT32; + output_7->layout = CSINN_LAYOUT_NCHW; + output_7->dim[0] = 1; + output_7->dim[1] = 64; + output_7->dim[2] = 75; + output_7->dim[3] = 75; + output_7->dim_count = 4; + output_7->qinfo = (struct csi_quant_info *)(params_base + 74968); + output_7->quant_channel = 1; + struct csi_tensor *kernel_7 = csi_alloc_tensor(sess); + kernel_7->data = params_base + 74992; + kernel_7->name = "kernel_7"; + kernel_7->is_const = 1; + kernel_7->dtype = CSINN_DTYPE_FLOAT32; + kernel_7->layout = CSINN_LAYOUT_OIHW; + kernel_7->dim[0] = 64; + kernel_7->dim[1] = 1; + kernel_7->dim[2] = 3; + kernel_7->dim[3] = 3; + kernel_7->dim_count = 4; + kernel_7->qinfo = (struct csi_quant_info *)(params_base + 77296); + kernel_7->quant_channel = 1; + struct csi_tensor *bias_7 = csi_alloc_tensor(sess); + bias_7->data = params_base + 77320; + bias_7->name = "bias_7"; + bias_7->is_const = 1; + bias_7->dtype = CSINN_DTYPE_FLOAT32; + bias_7->layout = CSINN_LAYOUT_O; + bias_7->dim[0] = 64; + bias_7->dim_count = 1; + bias_7->qinfo = (struct csi_quant_info *)(params_base + 77576); + bias_7->quant_channel = 1; + struct conv2d_params *params_7 = csi_alloc_params(sizeof(struct conv2d_params), sess); + params_7->group = 64; + params_7->stride_height = 2; + params_7->stride_width = 2; + params_7->dilation_height = 1; + params_7->dilation_width = 1; + params_7->conv_extra.kernel_tm = NULL; + params_7->conv_extra.conv_mode = CSINN_DIRECT; + params_7->pad_top = 1; + params_7->pad_left = 1; + params_7->pad_down = 1; + params_7->pad_right = 1; + params_7->base.name = "params_7"; + csi_conv2d_init(output_6, output_7, kernel_7, bias_7, params_7); + struct csi_tensor *output_8 = csi_alloc_tensor(sess); + output_8->name = "output_8"; + output_8->dtype = CSINN_DTYPE_FLOAT32; + output_8->layout = CSINN_LAYOUT_NCHW; + output_8->dim[0] = 1; + output_8->dim[1] = 64; + output_8->dim[2] = 75; + output_8->dim[3] = 75; + output_8->dim_count = 4; + output_8->qinfo = (struct csi_quant_info *)(params_base + 77600); + output_8->quant_channel = 1; + struct relu_params *params_8 = csi_alloc_params(sizeof(struct relu_params), sess); + params_8->base.name = "params_8"; + csi_relu_init(output_7, output_8, params_8); + struct csi_tensor *output_9 = csi_alloc_tensor(sess); + output_9->name = "output_9"; + output_9->dtype = CSINN_DTYPE_FLOAT32; + output_9->layout = CSINN_LAYOUT_NCHW; + output_9->dim[0] = 1; + output_9->dim[1] = 128; + output_9->dim[2] = 75; + output_9->dim[3] = 75; + output_9->dim_count = 4; + output_9->qinfo = (struct csi_quant_info *)(params_base + 77624); + output_9->quant_channel = 1; + struct csi_tensor *kernel_9 = csi_alloc_tensor(sess); + kernel_9->data = params_base + 77648; + kernel_9->name = "kernel_9"; + kernel_9->is_const = 1; + kernel_9->dtype = CSINN_DTYPE_FLOAT32; + kernel_9->layout = CSINN_LAYOUT_OIHW; + kernel_9->dim[0] = 128; + kernel_9->dim[1] = 64; + kernel_9->dim[2] = 1; + kernel_9->dim[3] = 1; + kernel_9->dim_count = 4; + kernel_9->qinfo = (struct csi_quant_info *)(params_base + 110416); + kernel_9->quant_channel = 1; + struct csi_tensor *bias_9 = csi_alloc_tensor(sess); + bias_9->data = params_base + 110440; + bias_9->name = "bias_9"; + bias_9->is_const = 1; + bias_9->dtype = CSINN_DTYPE_FLOAT32; + bias_9->layout = CSINN_LAYOUT_O; + bias_9->dim[0] = 128; + bias_9->dim_count = 1; + bias_9->qinfo = (struct csi_quant_info *)(params_base + 110952); + bias_9->quant_channel = 1; + struct conv2d_params *params_9 = csi_alloc_params(sizeof(struct conv2d_params), sess); + params_9->group = 1; + params_9->stride_height = 1; + params_9->stride_width = 1; + params_9->dilation_height = 1; + params_9->dilation_width = 1; + params_9->conv_extra.kernel_tm = NULL; + params_9->conv_extra.conv_mode = CSINN_DIRECT; + params_9->pad_top = 0; + params_9->pad_left = 0; + params_9->pad_down = 0; + params_9->pad_right = 0; + params_9->base.name = "params_9"; + csi_conv2d_init(output_8, output_9, kernel_9, bias_9, params_9); + struct csi_tensor *output_10 = csi_alloc_tensor(sess); + output_10->name = "output_10"; + output_10->dtype = CSINN_DTYPE_FLOAT32; + output_10->layout = CSINN_LAYOUT_NCHW; + output_10->dim[0] = 1; + output_10->dim[1] = 128; + output_10->dim[2] = 75; + output_10->dim[3] = 75; + output_10->dim_count = 4; + output_10->qinfo = (struct csi_quant_info *)(params_base + 110976); + output_10->quant_channel = 1; + struct relu_params *params_10 = csi_alloc_params(sizeof(struct relu_params), sess); + params_10->base.name = "params_10"; + csi_relu_init(output_9, output_10, params_10); + struct csi_tensor *output_11 = csi_alloc_tensor(sess); + output_11->name = "output_11"; + output_11->dtype = CSINN_DTYPE_FLOAT32; + output_11->layout = CSINN_LAYOUT_NCHW; + output_11->dim[0] = 1; + output_11->dim[1] = 128; + output_11->dim[2] = 75; + output_11->dim[3] = 75; + output_11->dim_count = 4; + output_11->qinfo = (struct csi_quant_info *)(params_base + 111000); + output_11->quant_channel = 1; + struct csi_tensor *kernel_11 = csi_alloc_tensor(sess); + kernel_11->data = params_base + 111024; + kernel_11->name = "kernel_11"; + kernel_11->is_const = 1; + kernel_11->dtype = CSINN_DTYPE_FLOAT32; + kernel_11->layout = CSINN_LAYOUT_OIHW; + kernel_11->dim[0] = 128; + kernel_11->dim[1] = 1; + kernel_11->dim[2] = 3; + kernel_11->dim[3] = 3; + kernel_11->dim_count = 4; + kernel_11->qinfo = (struct csi_quant_info *)(params_base + 115632); + kernel_11->quant_channel = 1; + struct csi_tensor *bias_11 = csi_alloc_tensor(sess); + bias_11->data = params_base + 115656; + bias_11->name = "bias_11"; + bias_11->is_const = 1; + bias_11->dtype = CSINN_DTYPE_FLOAT32; + bias_11->layout = CSINN_LAYOUT_O; + bias_11->dim[0] = 128; + bias_11->dim_count = 1; + bias_11->qinfo = (struct csi_quant_info *)(params_base + 116168); + bias_11->quant_channel = 1; + struct conv2d_params *params_11 = csi_alloc_params(sizeof(struct conv2d_params), sess); + params_11->group = 128; + params_11->stride_height = 1; + params_11->stride_width = 1; + params_11->dilation_height = 1; + params_11->dilation_width = 1; + params_11->conv_extra.kernel_tm = NULL; + params_11->conv_extra.conv_mode = CSINN_DIRECT; + params_11->pad_top = 1; + params_11->pad_left = 1; + params_11->pad_down = 1; + params_11->pad_right = 1; + params_11->base.name = "params_11"; + csi_conv2d_init(output_10, output_11, kernel_11, bias_11, params_11); + struct csi_tensor *output_12 = csi_alloc_tensor(sess); + output_12->name = "output_12"; + output_12->dtype = CSINN_DTYPE_FLOAT32; + output_12->layout = CSINN_LAYOUT_NCHW; + output_12->dim[0] = 1; + output_12->dim[1] = 128; + output_12->dim[2] = 75; + output_12->dim[3] = 75; + output_12->dim_count = 4; + output_12->qinfo = (struct csi_quant_info *)(params_base + 116192); + output_12->quant_channel = 1; + struct relu_params *params_12 = csi_alloc_params(sizeof(struct relu_params), sess); + params_12->base.name = "params_12"; + csi_relu_init(output_11, output_12, params_12); + struct csi_tensor *output_13 = csi_alloc_tensor(sess); + output_13->name = "output_13"; + output_13->dtype = CSINN_DTYPE_FLOAT32; + output_13->layout = CSINN_LAYOUT_NCHW; + output_13->dim[0] = 1; + output_13->dim[1] = 128; + output_13->dim[2] = 75; + output_13->dim[3] = 75; + output_13->dim_count = 4; + output_13->qinfo = (struct csi_quant_info *)(params_base + 116216); + output_13->quant_channel = 1; + struct csi_tensor *kernel_13 = csi_alloc_tensor(sess); + kernel_13->data = params_base + 116240; + kernel_13->name = "kernel_13"; + kernel_13->is_const = 1; + kernel_13->dtype = CSINN_DTYPE_FLOAT32; + kernel_13->layout = CSINN_LAYOUT_OIHW; + kernel_13->dim[0] = 128; + kernel_13->dim[1] = 128; + kernel_13->dim[2] = 1; + kernel_13->dim[3] = 1; + kernel_13->dim_count = 4; + kernel_13->qinfo = (struct csi_quant_info *)(params_base + 181776); + kernel_13->quant_channel = 1; + struct csi_tensor *bias_13 = csi_alloc_tensor(sess); + bias_13->data = params_base + 181800; + bias_13->name = "bias_13"; + bias_13->is_const = 1; + bias_13->dtype = CSINN_DTYPE_FLOAT32; + bias_13->layout = CSINN_LAYOUT_O; + bias_13->dim[0] = 128; + bias_13->dim_count = 1; + bias_13->qinfo = (struct csi_quant_info *)(params_base + 182312); + bias_13->quant_channel = 1; + struct conv2d_params *params_13 = csi_alloc_params(sizeof(struct conv2d_params), sess); + params_13->group = 1; + params_13->stride_height = 1; + params_13->stride_width = 1; + params_13->dilation_height = 1; + params_13->dilation_width = 1; + params_13->conv_extra.kernel_tm = NULL; + params_13->conv_extra.conv_mode = CSINN_DIRECT; + params_13->pad_top = 0; + params_13->pad_left = 0; + params_13->pad_down = 0; + params_13->pad_right = 0; + params_13->base.name = "params_13"; + csi_conv2d_init(output_12, output_13, kernel_13, bias_13, params_13); + struct csi_tensor *output_14 = csi_alloc_tensor(sess); + output_14->name = "output_14"; + output_14->dtype = CSINN_DTYPE_FLOAT32; + output_14->layout = CSINN_LAYOUT_NCHW; + output_14->dim[0] = 1; + output_14->dim[1] = 128; + output_14->dim[2] = 75; + output_14->dim[3] = 75; + output_14->dim_count = 4; + output_14->qinfo = (struct csi_quant_info *)(params_base + 182336); + output_14->quant_channel = 1; + struct relu_params *params_14 = csi_alloc_params(sizeof(struct relu_params), sess); + params_14->base.name = "params_14"; + csi_relu_init(output_13, output_14, params_14); + struct csi_tensor *output_15 = csi_alloc_tensor(sess); + output_15->name = "output_15"; + output_15->dtype = CSINN_DTYPE_FLOAT32; + output_15->layout = CSINN_LAYOUT_NCHW; + output_15->dim[0] = 1; + output_15->dim[1] = 128; + output_15->dim[2] = 38; + output_15->dim[3] = 38; + output_15->dim_count = 4; + output_15->qinfo = (struct csi_quant_info *)(params_base + 182360); + output_15->quant_channel = 1; + struct csi_tensor *kernel_15 = csi_alloc_tensor(sess); + kernel_15->data = params_base + 182384; + kernel_15->name = "kernel_15"; + kernel_15->is_const = 1; + kernel_15->dtype = CSINN_DTYPE_FLOAT32; + kernel_15->layout = CSINN_LAYOUT_OIHW; + kernel_15->dim[0] = 128; + kernel_15->dim[1] = 1; + kernel_15->dim[2] = 3; + kernel_15->dim[3] = 3; + kernel_15->dim_count = 4; + kernel_15->qinfo = (struct csi_quant_info *)(params_base + 186992); + kernel_15->quant_channel = 1; + struct csi_tensor *bias_15 = csi_alloc_tensor(sess); + bias_15->data = params_base + 187016; + bias_15->name = "bias_15"; + bias_15->is_const = 1; + bias_15->dtype = CSINN_DTYPE_FLOAT32; + bias_15->layout = CSINN_LAYOUT_O; + bias_15->dim[0] = 128; + bias_15->dim_count = 1; + bias_15->qinfo = (struct csi_quant_info *)(params_base + 187528); + bias_15->quant_channel = 1; + struct conv2d_params *params_15 = csi_alloc_params(sizeof(struct conv2d_params), sess); + params_15->group = 128; + params_15->stride_height = 2; + params_15->stride_width = 2; + params_15->dilation_height = 1; + params_15->dilation_width = 1; + params_15->conv_extra.kernel_tm = NULL; + params_15->conv_extra.conv_mode = CSINN_DIRECT; + params_15->pad_top = 1; + params_15->pad_left = 1; + params_15->pad_down = 1; + params_15->pad_right = 1; + params_15->base.name = "params_15"; + csi_conv2d_init(output_14, output_15, kernel_15, bias_15, params_15); + struct csi_tensor *output_16 = csi_alloc_tensor(sess); + output_16->name = "output_16"; + output_16->dtype = CSINN_DTYPE_FLOAT32; + output_16->layout = CSINN_LAYOUT_NCHW; + output_16->dim[0] = 1; + output_16->dim[1] = 128; + output_16->dim[2] = 38; + output_16->dim[3] = 38; + output_16->dim_count = 4; + output_16->qinfo = (struct csi_quant_info *)(params_base + 187552); + output_16->quant_channel = 1; + struct relu_params *params_16 = csi_alloc_params(sizeof(struct relu_params), sess); + params_16->base.name = "params_16"; + csi_relu_init(output_15, output_16, params_16); + struct csi_tensor *output_17 = csi_alloc_tensor(sess); + output_17->name = "output_17"; + output_17->dtype = CSINN_DTYPE_FLOAT32; + output_17->layout = CSINN_LAYOUT_NCHW; + output_17->dim[0] = 1; + output_17->dim[1] = 256; + output_17->dim[2] = 38; + output_17->dim[3] = 38; + output_17->dim_count = 4; + output_17->qinfo = (struct csi_quant_info *)(params_base + 187576); + output_17->quant_channel = 1; + struct csi_tensor *kernel_17 = csi_alloc_tensor(sess); + kernel_17->data = params_base + 187600; + kernel_17->name = "kernel_17"; + kernel_17->is_const = 1; + kernel_17->dtype = CSINN_DTYPE_FLOAT32; + kernel_17->layout = CSINN_LAYOUT_OIHW; + kernel_17->dim[0] = 256; + kernel_17->dim[1] = 128; + kernel_17->dim[2] = 1; + kernel_17->dim[3] = 1; + kernel_17->dim_count = 4; + kernel_17->qinfo = (struct csi_quant_info *)(params_base + 318672); + kernel_17->quant_channel = 1; + struct csi_tensor *bias_17 = csi_alloc_tensor(sess); + bias_17->data = params_base + 318696; + bias_17->name = "bias_17"; + bias_17->is_const = 1; + bias_17->dtype = CSINN_DTYPE_FLOAT32; + bias_17->layout = CSINN_LAYOUT_O; + bias_17->dim[0] = 256; + bias_17->dim_count = 1; + bias_17->qinfo = (struct csi_quant_info *)(params_base + 319720); + bias_17->quant_channel = 1; + struct conv2d_params *params_17 = csi_alloc_params(sizeof(struct conv2d_params), sess); + params_17->group = 1; + params_17->stride_height = 1; + params_17->stride_width = 1; + params_17->dilation_height = 1; + params_17->dilation_width = 1; + params_17->conv_extra.kernel_tm = NULL; + params_17->conv_extra.conv_mode = CSINN_DIRECT; + params_17->pad_top = 0; + params_17->pad_left = 0; + params_17->pad_down = 0; + params_17->pad_right = 0; + params_17->base.name = "params_17"; + csi_conv2d_init(output_16, output_17, kernel_17, bias_17, params_17); + struct csi_tensor *output_18 = csi_alloc_tensor(sess); + output_18->name = "output_18"; + output_18->dtype = CSINN_DTYPE_FLOAT32; + output_18->layout = CSINN_LAYOUT_NCHW; + output_18->dim[0] = 1; + output_18->dim[1] = 256; + output_18->dim[2] = 38; + output_18->dim[3] = 38; + output_18->dim_count = 4; + output_18->qinfo = (struct csi_quant_info *)(params_base + 319744); + output_18->quant_channel = 1; + struct relu_params *params_18 = csi_alloc_params(sizeof(struct relu_params), sess); + params_18->base.name = "params_18"; + csi_relu_init(output_17, output_18, params_18); + struct csi_tensor *output_19 = csi_alloc_tensor(sess); + output_19->name = "output_19"; + output_19->dtype = CSINN_DTYPE_FLOAT32; + output_19->layout = CSINN_LAYOUT_NCHW; + output_19->dim[0] = 1; + output_19->dim[1] = 256; + output_19->dim[2] = 38; + output_19->dim[3] = 38; + output_19->dim_count = 4; + output_19->qinfo = (struct csi_quant_info *)(params_base + 319768); + output_19->quant_channel = 1; + struct csi_tensor *kernel_19 = csi_alloc_tensor(sess); + kernel_19->data = params_base + 319792; + kernel_19->name = "kernel_19"; + kernel_19->is_const = 1; + kernel_19->dtype = CSINN_DTYPE_FLOAT32; + kernel_19->layout = CSINN_LAYOUT_OIHW; + kernel_19->dim[0] = 256; + kernel_19->dim[1] = 1; + kernel_19->dim[2] = 3; + kernel_19->dim[3] = 3; + kernel_19->dim_count = 4; + kernel_19->qinfo = (struct csi_quant_info *)(params_base + 329008); + kernel_19->quant_channel = 1; + struct csi_tensor *bias_19 = csi_alloc_tensor(sess); + bias_19->data = params_base + 329032; + bias_19->name = "bias_19"; + bias_19->is_const = 1; + bias_19->dtype = CSINN_DTYPE_FLOAT32; + bias_19->layout = CSINN_LAYOUT_O; + bias_19->dim[0] = 256; + bias_19->dim_count = 1; + bias_19->qinfo = (struct csi_quant_info *)(params_base + 330056); + bias_19->quant_channel = 1; + struct conv2d_params *params_19 = csi_alloc_params(sizeof(struct conv2d_params), sess); + params_19->group = 256; + params_19->stride_height = 1; + params_19->stride_width = 1; + params_19->dilation_height = 1; + params_19->dilation_width = 1; + params_19->conv_extra.kernel_tm = NULL; + params_19->conv_extra.conv_mode = CSINN_DIRECT; + params_19->pad_top = 1; + params_19->pad_left = 1; + params_19->pad_down = 1; + params_19->pad_right = 1; + params_19->base.name = "params_19"; + csi_conv2d_init(output_18, output_19, kernel_19, bias_19, params_19); + struct csi_tensor *output_20 = csi_alloc_tensor(sess); + output_20->name = "output_20"; + output_20->dtype = CSINN_DTYPE_FLOAT32; + output_20->layout = CSINN_LAYOUT_NCHW; + output_20->dim[0] = 1; + output_20->dim[1] = 256; + output_20->dim[2] = 38; + output_20->dim[3] = 38; + output_20->dim_count = 4; + output_20->qinfo = (struct csi_quant_info *)(params_base + 330080); + output_20->quant_channel = 1; + struct relu_params *params_20 = csi_alloc_params(sizeof(struct relu_params), sess); + params_20->base.name = "params_20"; + csi_relu_init(output_19, output_20, params_20); + struct csi_tensor *output_21 = csi_alloc_tensor(sess); + output_21->name = "output_21"; + output_21->dtype = CSINN_DTYPE_FLOAT32; + output_21->layout = CSINN_LAYOUT_NCHW; + output_21->dim[0] = 1; + output_21->dim[1] = 256; + output_21->dim[2] = 38; + output_21->dim[3] = 38; + output_21->dim_count = 4; + output_21->qinfo = (struct csi_quant_info *)(params_base + 330104); + output_21->quant_channel = 1; + struct csi_tensor *kernel_21 = csi_alloc_tensor(sess); + kernel_21->data = params_base + 330128; + kernel_21->name = "kernel_21"; + kernel_21->is_const = 1; + kernel_21->dtype = CSINN_DTYPE_FLOAT32; + kernel_21->layout = CSINN_LAYOUT_OIHW; + kernel_21->dim[0] = 256; + kernel_21->dim[1] = 256; + kernel_21->dim[2] = 1; + kernel_21->dim[3] = 1; + kernel_21->dim_count = 4; + kernel_21->qinfo = (struct csi_quant_info *)(params_base + 592272); + kernel_21->quant_channel = 1; + struct csi_tensor *bias_21 = csi_alloc_tensor(sess); + bias_21->data = params_base + 592296; + bias_21->name = "bias_21"; + bias_21->is_const = 1; + bias_21->dtype = CSINN_DTYPE_FLOAT32; + bias_21->layout = CSINN_LAYOUT_O; + bias_21->dim[0] = 256; + bias_21->dim_count = 1; + bias_21->qinfo = (struct csi_quant_info *)(params_base + 593320); + bias_21->quant_channel = 1; + struct conv2d_params *params_21 = csi_alloc_params(sizeof(struct conv2d_params), sess); + params_21->group = 1; + params_21->stride_height = 1; + params_21->stride_width = 1; + params_21->dilation_height = 1; + params_21->dilation_width = 1; + params_21->conv_extra.kernel_tm = NULL; + params_21->conv_extra.conv_mode = CSINN_DIRECT; + params_21->pad_top = 0; + params_21->pad_left = 0; + params_21->pad_down = 0; + params_21->pad_right = 0; + params_21->base.name = "params_21"; + csi_conv2d_init(output_20, output_21, kernel_21, bias_21, params_21); + struct csi_tensor *output_22 = csi_alloc_tensor(sess); + output_22->name = "output_22"; + output_22->dtype = CSINN_DTYPE_FLOAT32; + output_22->layout = CSINN_LAYOUT_NCHW; + output_22->dim[0] = 1; + output_22->dim[1] = 256; + output_22->dim[2] = 38; + output_22->dim[3] = 38; + output_22->dim_count = 4; + output_22->qinfo = (struct csi_quant_info *)(params_base + 593344); + output_22->quant_channel = 1; + struct relu_params *params_22 = csi_alloc_params(sizeof(struct relu_params), sess); + params_22->base.name = "params_22"; + csi_relu_init(output_21, output_22, params_22); + struct csi_tensor *output_23 = csi_alloc_tensor(sess); + output_23->name = "output_23"; + output_23->dtype = CSINN_DTYPE_FLOAT32; + output_23->layout = CSINN_LAYOUT_NCHW; + output_23->dim[0] = 1; + output_23->dim[1] = 256; + output_23->dim[2] = 19; + output_23->dim[3] = 19; + output_23->dim_count = 4; + output_23->qinfo = (struct csi_quant_info *)(params_base + 593368); + output_23->quant_channel = 1; + struct csi_tensor *kernel_23 = csi_alloc_tensor(sess); + kernel_23->data = params_base + 593392; + kernel_23->name = "kernel_23"; + kernel_23->is_const = 1; + kernel_23->dtype = CSINN_DTYPE_FLOAT32; + kernel_23->layout = CSINN_LAYOUT_OIHW; + kernel_23->dim[0] = 256; + kernel_23->dim[1] = 1; + kernel_23->dim[2] = 3; + kernel_23->dim[3] = 3; + kernel_23->dim_count = 4; + kernel_23->qinfo = (struct csi_quant_info *)(params_base + 602608); + kernel_23->quant_channel = 1; + struct csi_tensor *bias_23 = csi_alloc_tensor(sess); + bias_23->data = params_base + 602632; + bias_23->name = "bias_23"; + bias_23->is_const = 1; + bias_23->dtype = CSINN_DTYPE_FLOAT32; + bias_23->layout = CSINN_LAYOUT_O; + bias_23->dim[0] = 256; + bias_23->dim_count = 1; + bias_23->qinfo = (struct csi_quant_info *)(params_base + 603656); + bias_23->quant_channel = 1; + struct conv2d_params *params_23 = csi_alloc_params(sizeof(struct conv2d_params), sess); + params_23->group = 256; + params_23->stride_height = 2; + params_23->stride_width = 2; + params_23->dilation_height = 1; + params_23->dilation_width = 1; + params_23->conv_extra.kernel_tm = NULL; + params_23->conv_extra.conv_mode = CSINN_DIRECT; + params_23->pad_top = 1; + params_23->pad_left = 1; + params_23->pad_down = 1; + params_23->pad_right = 1; + params_23->base.name = "params_23"; + csi_conv2d_init(output_22, output_23, kernel_23, bias_23, params_23); + struct csi_tensor *output_24 = csi_alloc_tensor(sess); + output_24->name = "output_24"; + output_24->dtype = CSINN_DTYPE_FLOAT32; + output_24->layout = CSINN_LAYOUT_NCHW; + output_24->dim[0] = 1; + output_24->dim[1] = 256; + output_24->dim[2] = 19; + output_24->dim[3] = 19; + output_24->dim_count = 4; + output_24->qinfo = (struct csi_quant_info *)(params_base + 603680); + output_24->quant_channel = 1; + struct relu_params *params_24 = csi_alloc_params(sizeof(struct relu_params), sess); + params_24->base.name = "params_24"; + csi_relu_init(output_23, output_24, params_24); + struct csi_tensor *output_25 = csi_alloc_tensor(sess); + output_25->name = "output_25"; + output_25->dtype = CSINN_DTYPE_FLOAT32; + output_25->layout = CSINN_LAYOUT_NCHW; + output_25->dim[0] = 1; + output_25->dim[1] = 512; + output_25->dim[2] = 19; + output_25->dim[3] = 19; + output_25->dim_count = 4; + output_25->qinfo = (struct csi_quant_info *)(params_base + 603704); + output_25->quant_channel = 1; + struct csi_tensor *kernel_25 = csi_alloc_tensor(sess); + kernel_25->data = params_base + 603728; + kernel_25->name = "kernel_25"; + kernel_25->is_const = 1; + kernel_25->dtype = CSINN_DTYPE_FLOAT32; + kernel_25->layout = CSINN_LAYOUT_OIHW; + kernel_25->dim[0] = 512; + kernel_25->dim[1] = 256; + kernel_25->dim[2] = 1; + kernel_25->dim[3] = 1; + kernel_25->dim_count = 4; + kernel_25->qinfo = (struct csi_quant_info *)(params_base + 1128016); + kernel_25->quant_channel = 1; + struct csi_tensor *bias_25 = csi_alloc_tensor(sess); + bias_25->data = params_base + 1128040; + bias_25->name = "bias_25"; + bias_25->is_const = 1; + bias_25->dtype = CSINN_DTYPE_FLOAT32; + bias_25->layout = CSINN_LAYOUT_O; + bias_25->dim[0] = 512; + bias_25->dim_count = 1; + bias_25->qinfo = (struct csi_quant_info *)(params_base + 1130088); + bias_25->quant_channel = 1; + struct conv2d_params *params_25 = csi_alloc_params(sizeof(struct conv2d_params), sess); + params_25->group = 1; + params_25->stride_height = 1; + params_25->stride_width = 1; + params_25->dilation_height = 1; + params_25->dilation_width = 1; + params_25->conv_extra.kernel_tm = NULL; + params_25->conv_extra.conv_mode = CSINN_DIRECT; + params_25->pad_top = 0; + params_25->pad_left = 0; + params_25->pad_down = 0; + params_25->pad_right = 0; + params_25->base.name = "params_25"; + csi_conv2d_init(output_24, output_25, kernel_25, bias_25, params_25); + struct csi_tensor *output_26 = csi_alloc_tensor(sess); + output_26->name = "output_26"; + output_26->dtype = CSINN_DTYPE_FLOAT32; + output_26->layout = CSINN_LAYOUT_NCHW; + output_26->dim[0] = 1; + output_26->dim[1] = 512; + output_26->dim[2] = 19; + output_26->dim[3] = 19; + output_26->dim_count = 4; + output_26->qinfo = (struct csi_quant_info *)(params_base + 1130112); + output_26->quant_channel = 1; + struct relu_params *params_26 = csi_alloc_params(sizeof(struct relu_params), sess); + params_26->base.name = "params_26"; + csi_relu_init(output_25, output_26, params_26); + struct csi_tensor *output_27 = csi_alloc_tensor(sess); + output_27->name = "output_27"; + output_27->dtype = CSINN_DTYPE_FLOAT32; + output_27->layout = CSINN_LAYOUT_NCHW; + output_27->dim[0] = 1; + output_27->dim[1] = 512; + output_27->dim[2] = 19; + output_27->dim[3] = 19; + output_27->dim_count = 4; + output_27->qinfo = (struct csi_quant_info *)(params_base + 1130136); + output_27->quant_channel = 1; + struct csi_tensor *kernel_27 = csi_alloc_tensor(sess); + kernel_27->data = params_base + 1130160; + kernel_27->name = "kernel_27"; + kernel_27->is_const = 1; + kernel_27->dtype = CSINN_DTYPE_FLOAT32; + kernel_27->layout = CSINN_LAYOUT_OIHW; + kernel_27->dim[0] = 512; + kernel_27->dim[1] = 1; + kernel_27->dim[2] = 3; + kernel_27->dim[3] = 3; + kernel_27->dim_count = 4; + kernel_27->qinfo = (struct csi_quant_info *)(params_base + 1148592); + kernel_27->quant_channel = 1; + struct csi_tensor *bias_27 = csi_alloc_tensor(sess); + bias_27->data = params_base + 1148616; + bias_27->name = "bias_27"; + bias_27->is_const = 1; + bias_27->dtype = CSINN_DTYPE_FLOAT32; + bias_27->layout = CSINN_LAYOUT_O; + bias_27->dim[0] = 512; + bias_27->dim_count = 1; + bias_27->qinfo = (struct csi_quant_info *)(params_base + 1150664); + bias_27->quant_channel = 1; + struct conv2d_params *params_27 = csi_alloc_params(sizeof(struct conv2d_params), sess); + params_27->group = 512; + params_27->stride_height = 1; + params_27->stride_width = 1; + params_27->dilation_height = 1; + params_27->dilation_width = 1; + params_27->conv_extra.kernel_tm = NULL; + params_27->conv_extra.conv_mode = CSINN_DIRECT; + params_27->pad_top = 1; + params_27->pad_left = 1; + params_27->pad_down = 1; + params_27->pad_right = 1; + params_27->base.name = "params_27"; + csi_conv2d_init(output_26, output_27, kernel_27, bias_27, params_27); + struct csi_tensor *output_28 = csi_alloc_tensor(sess); + output_28->name = "output_28"; + output_28->dtype = CSINN_DTYPE_FLOAT32; + output_28->layout = CSINN_LAYOUT_NCHW; + output_28->dim[0] = 1; + output_28->dim[1] = 512; + output_28->dim[2] = 19; + output_28->dim[3] = 19; + output_28->dim_count = 4; + output_28->qinfo = (struct csi_quant_info *)(params_base + 1150688); + output_28->quant_channel = 1; + struct relu_params *params_28 = csi_alloc_params(sizeof(struct relu_params), sess); + params_28->base.name = "params_28"; + csi_relu_init(output_27, output_28, params_28); + struct csi_tensor *output_29 = csi_alloc_tensor(sess); + output_29->name = "output_29"; + output_29->dtype = CSINN_DTYPE_FLOAT32; + output_29->layout = CSINN_LAYOUT_NCHW; + output_29->dim[0] = 1; + output_29->dim[1] = 512; + output_29->dim[2] = 19; + output_29->dim[3] = 19; + output_29->dim_count = 4; + output_29->qinfo = (struct csi_quant_info *)(params_base + 1150712); + output_29->quant_channel = 1; + struct csi_tensor *kernel_29 = csi_alloc_tensor(sess); + kernel_29->data = params_base + 1150736; + kernel_29->name = "kernel_29"; + kernel_29->is_const = 1; + kernel_29->dtype = CSINN_DTYPE_FLOAT32; + kernel_29->layout = CSINN_LAYOUT_OIHW; + kernel_29->dim[0] = 512; + kernel_29->dim[1] = 512; + kernel_29->dim[2] = 1; + kernel_29->dim[3] = 1; + kernel_29->dim_count = 4; + kernel_29->qinfo = (struct csi_quant_info *)(params_base + 2199312); + kernel_29->quant_channel = 1; + struct csi_tensor *bias_29 = csi_alloc_tensor(sess); + bias_29->data = params_base + 2199336; + bias_29->name = "bias_29"; + bias_29->is_const = 1; + bias_29->dtype = CSINN_DTYPE_FLOAT32; + bias_29->layout = CSINN_LAYOUT_O; + bias_29->dim[0] = 512; + bias_29->dim_count = 1; + bias_29->qinfo = (struct csi_quant_info *)(params_base + 2201384); + bias_29->quant_channel = 1; + struct conv2d_params *params_29 = csi_alloc_params(sizeof(struct conv2d_params), sess); + params_29->group = 1; + params_29->stride_height = 1; + params_29->stride_width = 1; + params_29->dilation_height = 1; + params_29->dilation_width = 1; + params_29->conv_extra.kernel_tm = NULL; + params_29->conv_extra.conv_mode = CSINN_DIRECT; + params_29->pad_top = 0; + params_29->pad_left = 0; + params_29->pad_down = 0; + params_29->pad_right = 0; + params_29->base.name = "params_29"; + csi_conv2d_init(output_28, output_29, kernel_29, bias_29, params_29); + struct csi_tensor *output_30 = csi_alloc_tensor(sess); + output_30->name = "output_30"; + output_30->dtype = CSINN_DTYPE_FLOAT32; + output_30->layout = CSINN_LAYOUT_NCHW; + output_30->dim[0] = 1; + output_30->dim[1] = 512; + output_30->dim[2] = 19; + output_30->dim[3] = 19; + output_30->dim_count = 4; + output_30->qinfo = (struct csi_quant_info *)(params_base + 2201408); + output_30->quant_channel = 1; + struct relu_params *params_30 = csi_alloc_params(sizeof(struct relu_params), sess); + params_30->base.name = "params_30"; + csi_relu_init(output_29, output_30, params_30); + struct csi_tensor *output_31 = csi_alloc_tensor(sess); + output_31->name = "output_31"; + output_31->dtype = CSINN_DTYPE_FLOAT32; + output_31->layout = CSINN_LAYOUT_NCHW; + output_31->dim[0] = 1; + output_31->dim[1] = 512; + output_31->dim[2] = 19; + output_31->dim[3] = 19; + output_31->dim_count = 4; + output_31->qinfo = (struct csi_quant_info *)(params_base + 2201432); + output_31->quant_channel = 1; + struct csi_tensor *kernel_31 = csi_alloc_tensor(sess); + kernel_31->data = params_base + 2201456; + kernel_31->name = "kernel_31"; + kernel_31->is_const = 1; + kernel_31->dtype = CSINN_DTYPE_FLOAT32; + kernel_31->layout = CSINN_LAYOUT_OIHW; + kernel_31->dim[0] = 512; + kernel_31->dim[1] = 1; + kernel_31->dim[2] = 3; + kernel_31->dim[3] = 3; + kernel_31->dim_count = 4; + kernel_31->qinfo = (struct csi_quant_info *)(params_base + 2219888); + kernel_31->quant_channel = 1; + struct csi_tensor *bias_31 = csi_alloc_tensor(sess); + bias_31->data = params_base + 2219912; + bias_31->name = "bias_31"; + bias_31->is_const = 1; + bias_31->dtype = CSINN_DTYPE_FLOAT32; + bias_31->layout = CSINN_LAYOUT_O; + bias_31->dim[0] = 512; + bias_31->dim_count = 1; + bias_31->qinfo = (struct csi_quant_info *)(params_base + 2221960); + bias_31->quant_channel = 1; + struct conv2d_params *params_31 = csi_alloc_params(sizeof(struct conv2d_params), sess); + params_31->group = 512; + params_31->stride_height = 1; + params_31->stride_width = 1; + params_31->dilation_height = 1; + params_31->dilation_width = 1; + params_31->conv_extra.kernel_tm = NULL; + params_31->conv_extra.conv_mode = CSINN_DIRECT; + params_31->pad_top = 1; + params_31->pad_left = 1; + params_31->pad_down = 1; + params_31->pad_right = 1; + params_31->base.name = "params_31"; + csi_conv2d_init(output_30, output_31, kernel_31, bias_31, params_31); + struct csi_tensor *output_32 = csi_alloc_tensor(sess); + output_32->name = "output_32"; + output_32->dtype = CSINN_DTYPE_FLOAT32; + output_32->layout = CSINN_LAYOUT_NCHW; + output_32->dim[0] = 1; + output_32->dim[1] = 512; + output_32->dim[2] = 19; + output_32->dim[3] = 19; + output_32->dim_count = 4; + output_32->qinfo = (struct csi_quant_info *)(params_base + 2221984); + output_32->quant_channel = 1; + struct relu_params *params_32 = csi_alloc_params(sizeof(struct relu_params), sess); + params_32->base.name = "params_32"; + csi_relu_init(output_31, output_32, params_32); + struct csi_tensor *output_33 = csi_alloc_tensor(sess); + output_33->name = "output_33"; + output_33->dtype = CSINN_DTYPE_FLOAT32; + output_33->layout = CSINN_LAYOUT_NCHW; + output_33->dim[0] = 1; + output_33->dim[1] = 512; + output_33->dim[2] = 19; + output_33->dim[3] = 19; + output_33->dim_count = 4; + output_33->qinfo = (struct csi_quant_info *)(params_base + 2222008); + output_33->quant_channel = 1; + struct csi_tensor *kernel_33 = csi_alloc_tensor(sess); + kernel_33->data = params_base + 2222032; + kernel_33->name = "kernel_33"; + kernel_33->is_const = 1; + kernel_33->dtype = CSINN_DTYPE_FLOAT32; + kernel_33->layout = CSINN_LAYOUT_OIHW; + kernel_33->dim[0] = 512; + kernel_33->dim[1] = 512; + kernel_33->dim[2] = 1; + kernel_33->dim[3] = 1; + kernel_33->dim_count = 4; + kernel_33->qinfo = (struct csi_quant_info *)(params_base + 3270608); + kernel_33->quant_channel = 1; + struct csi_tensor *bias_33 = csi_alloc_tensor(sess); + bias_33->data = params_base + 3270632; + bias_33->name = "bias_33"; + bias_33->is_const = 1; + bias_33->dtype = CSINN_DTYPE_FLOAT32; + bias_33->layout = CSINN_LAYOUT_O; + bias_33->dim[0] = 512; + bias_33->dim_count = 1; + bias_33->qinfo = (struct csi_quant_info *)(params_base + 3272680); + bias_33->quant_channel = 1; + struct conv2d_params *params_33 = csi_alloc_params(sizeof(struct conv2d_params), sess); + params_33->group = 1; + params_33->stride_height = 1; + params_33->stride_width = 1; + params_33->dilation_height = 1; + params_33->dilation_width = 1; + params_33->conv_extra.kernel_tm = NULL; + params_33->conv_extra.conv_mode = CSINN_DIRECT; + params_33->pad_top = 0; + params_33->pad_left = 0; + params_33->pad_down = 0; + params_33->pad_right = 0; + params_33->base.name = "params_33"; + csi_conv2d_init(output_32, output_33, kernel_33, bias_33, params_33); + struct csi_tensor *output_34 = csi_alloc_tensor(sess); + output_34->name = "output_34"; + output_34->dtype = CSINN_DTYPE_FLOAT32; + output_34->layout = CSINN_LAYOUT_NCHW; + output_34->dim[0] = 1; + output_34->dim[1] = 512; + output_34->dim[2] = 19; + output_34->dim[3] = 19; + output_34->dim_count = 4; + output_34->qinfo = (struct csi_quant_info *)(params_base + 3272704); + output_34->quant_channel = 1; + struct relu_params *params_34 = csi_alloc_params(sizeof(struct relu_params), sess); + params_34->base.name = "params_34"; + csi_relu_init(output_33, output_34, params_34); + struct csi_tensor *output_35 = csi_alloc_tensor(sess); + output_35->name = "output_35"; + output_35->dtype = CSINN_DTYPE_FLOAT32; + output_35->layout = CSINN_LAYOUT_NCHW; + output_35->dim[0] = 1; + output_35->dim[1] = 512; + output_35->dim[2] = 19; + output_35->dim[3] = 19; + output_35->dim_count = 4; + output_35->qinfo = (struct csi_quant_info *)(params_base + 3272728); + output_35->quant_channel = 1; + struct csi_tensor *kernel_35 = csi_alloc_tensor(sess); + kernel_35->data = params_base + 3272752; + kernel_35->name = "kernel_35"; + kernel_35->is_const = 1; + kernel_35->dtype = CSINN_DTYPE_FLOAT32; + kernel_35->layout = CSINN_LAYOUT_OIHW; + kernel_35->dim[0] = 512; + kernel_35->dim[1] = 1; + kernel_35->dim[2] = 3; + kernel_35->dim[3] = 3; + kernel_35->dim_count = 4; + kernel_35->qinfo = (struct csi_quant_info *)(params_base + 3291184); + kernel_35->quant_channel = 1; + struct csi_tensor *bias_35 = csi_alloc_tensor(sess); + bias_35->data = params_base + 3291208; + bias_35->name = "bias_35"; + bias_35->is_const = 1; + bias_35->dtype = CSINN_DTYPE_FLOAT32; + bias_35->layout = CSINN_LAYOUT_O; + bias_35->dim[0] = 512; + bias_35->dim_count = 1; + bias_35->qinfo = (struct csi_quant_info *)(params_base + 3293256); + bias_35->quant_channel = 1; + struct conv2d_params *params_35 = csi_alloc_params(sizeof(struct conv2d_params), sess); + params_35->group = 512; + params_35->stride_height = 1; + params_35->stride_width = 1; + params_35->dilation_height = 1; + params_35->dilation_width = 1; + params_35->conv_extra.kernel_tm = NULL; + params_35->conv_extra.conv_mode = CSINN_DIRECT; + params_35->pad_top = 1; + params_35->pad_left = 1; + params_35->pad_down = 1; + params_35->pad_right = 1; + params_35->base.name = "params_35"; + csi_conv2d_init(output_34, output_35, kernel_35, bias_35, params_35); + struct csi_tensor *output_36 = csi_alloc_tensor(sess); + output_36->name = "output_36"; + output_36->dtype = CSINN_DTYPE_FLOAT32; + output_36->layout = CSINN_LAYOUT_NCHW; + output_36->dim[0] = 1; + output_36->dim[1] = 512; + output_36->dim[2] = 19; + output_36->dim[3] = 19; + output_36->dim_count = 4; + output_36->qinfo = (struct csi_quant_info *)(params_base + 3293280); + output_36->quant_channel = 1; + struct relu_params *params_36 = csi_alloc_params(sizeof(struct relu_params), sess); + params_36->base.name = "params_36"; + csi_relu_init(output_35, output_36, params_36); + struct csi_tensor *output_37 = csi_alloc_tensor(sess); + output_37->name = "output_37"; + output_37->dtype = CSINN_DTYPE_FLOAT32; + output_37->layout = CSINN_LAYOUT_NCHW; + output_37->dim[0] = 1; + output_37->dim[1] = 512; + output_37->dim[2] = 19; + output_37->dim[3] = 19; + output_37->dim_count = 4; + output_37->qinfo = (struct csi_quant_info *)(params_base + 3293304); + output_37->quant_channel = 1; + struct csi_tensor *kernel_37 = csi_alloc_tensor(sess); + kernel_37->data = params_base + 3293328; + kernel_37->name = "kernel_37"; + kernel_37->is_const = 1; + kernel_37->dtype = CSINN_DTYPE_FLOAT32; + kernel_37->layout = CSINN_LAYOUT_OIHW; + kernel_37->dim[0] = 512; + kernel_37->dim[1] = 512; + kernel_37->dim[2] = 1; + kernel_37->dim[3] = 1; + kernel_37->dim_count = 4; + kernel_37->qinfo = (struct csi_quant_info *)(params_base + 4341904); + kernel_37->quant_channel = 1; + struct csi_tensor *bias_37 = csi_alloc_tensor(sess); + bias_37->data = params_base + 4341928; + bias_37->name = "bias_37"; + bias_37->is_const = 1; + bias_37->dtype = CSINN_DTYPE_FLOAT32; + bias_37->layout = CSINN_LAYOUT_O; + bias_37->dim[0] = 512; + bias_37->dim_count = 1; + bias_37->qinfo = (struct csi_quant_info *)(params_base + 4343976); + bias_37->quant_channel = 1; + struct conv2d_params *params_37 = csi_alloc_params(sizeof(struct conv2d_params), sess); + params_37->group = 1; + params_37->stride_height = 1; + params_37->stride_width = 1; + params_37->dilation_height = 1; + params_37->dilation_width = 1; + params_37->conv_extra.kernel_tm = NULL; + params_37->conv_extra.conv_mode = CSINN_DIRECT; + params_37->pad_top = 0; + params_37->pad_left = 0; + params_37->pad_down = 0; + params_37->pad_right = 0; + params_37->base.name = "params_37"; + csi_conv2d_init(output_36, output_37, kernel_37, bias_37, params_37); + struct csi_tensor *output_38 = csi_alloc_tensor(sess); + output_38->name = "output_38"; + output_38->dtype = CSINN_DTYPE_FLOAT32; + output_38->layout = CSINN_LAYOUT_NCHW; + output_38->dim[0] = 1; + output_38->dim[1] = 512; + output_38->dim[2] = 19; + output_38->dim[3] = 19; + output_38->dim_count = 4; + output_38->qinfo = (struct csi_quant_info *)(params_base + 4344000); + output_38->quant_channel = 1; + struct relu_params *params_38 = csi_alloc_params(sizeof(struct relu_params), sess); + params_38->base.name = "params_38"; + csi_relu_init(output_37, output_38, params_38); + struct csi_tensor *output_39 = csi_alloc_tensor(sess); + output_39->name = "output_39"; + output_39->dtype = CSINN_DTYPE_FLOAT32; + output_39->layout = CSINN_LAYOUT_NCHW; + output_39->dim[0] = 1; + output_39->dim[1] = 512; + output_39->dim[2] = 19; + output_39->dim[3] = 19; + output_39->dim_count = 4; + output_39->qinfo = (struct csi_quant_info *)(params_base + 4344024); + output_39->quant_channel = 1; + struct csi_tensor *kernel_39 = csi_alloc_tensor(sess); + kernel_39->data = params_base + 4344048; + kernel_39->name = "kernel_39"; + kernel_39->is_const = 1; + kernel_39->dtype = CSINN_DTYPE_FLOAT32; + kernel_39->layout = CSINN_LAYOUT_OIHW; + kernel_39->dim[0] = 512; + kernel_39->dim[1] = 1; + kernel_39->dim[2] = 3; + kernel_39->dim[3] = 3; + kernel_39->dim_count = 4; + kernel_39->qinfo = (struct csi_quant_info *)(params_base + 4362480); + kernel_39->quant_channel = 1; + struct csi_tensor *bias_39 = csi_alloc_tensor(sess); + bias_39->data = params_base + 4362504; + bias_39->name = "bias_39"; + bias_39->is_const = 1; + bias_39->dtype = CSINN_DTYPE_FLOAT32; + bias_39->layout = CSINN_LAYOUT_O; + bias_39->dim[0] = 512; + bias_39->dim_count = 1; + bias_39->qinfo = (struct csi_quant_info *)(params_base + 4364552); + bias_39->quant_channel = 1; + struct conv2d_params *params_39 = csi_alloc_params(sizeof(struct conv2d_params), sess); + params_39->group = 512; + params_39->stride_height = 1; + params_39->stride_width = 1; + params_39->dilation_height = 1; + params_39->dilation_width = 1; + params_39->conv_extra.kernel_tm = NULL; + params_39->conv_extra.conv_mode = CSINN_DIRECT; + params_39->pad_top = 1; + params_39->pad_left = 1; + params_39->pad_down = 1; + params_39->pad_right = 1; + params_39->base.name = "params_39"; + csi_conv2d_init(output_38, output_39, kernel_39, bias_39, params_39); + struct csi_tensor *output_40 = csi_alloc_tensor(sess); + output_40->name = "output_40"; + output_40->dtype = CSINN_DTYPE_FLOAT32; + output_40->layout = CSINN_LAYOUT_NCHW; + output_40->dim[0] = 1; + output_40->dim[1] = 512; + output_40->dim[2] = 19; + output_40->dim[3] = 19; + output_40->dim_count = 4; + output_40->qinfo = (struct csi_quant_info *)(params_base + 4364576); + output_40->quant_channel = 1; + struct relu_params *params_40 = csi_alloc_params(sizeof(struct relu_params), sess); + params_40->base.name = "params_40"; + csi_relu_init(output_39, output_40, params_40); + struct csi_tensor *output_41 = csi_alloc_tensor(sess); + output_41->name = "output_41"; + output_41->dtype = CSINN_DTYPE_FLOAT32; + output_41->layout = CSINN_LAYOUT_NCHW; + output_41->dim[0] = 1; + output_41->dim[1] = 512; + output_41->dim[2] = 19; + output_41->dim[3] = 19; + output_41->dim_count = 4; + output_41->qinfo = (struct csi_quant_info *)(params_base + 4364600); + output_41->quant_channel = 1; + struct csi_tensor *kernel_41 = csi_alloc_tensor(sess); + kernel_41->data = params_base + 4364624; + kernel_41->name = "kernel_41"; + kernel_41->is_const = 1; + kernel_41->dtype = CSINN_DTYPE_FLOAT32; + kernel_41->layout = CSINN_LAYOUT_OIHW; + kernel_41->dim[0] = 512; + kernel_41->dim[1] = 512; + kernel_41->dim[2] = 1; + kernel_41->dim[3] = 1; + kernel_41->dim_count = 4; + kernel_41->qinfo = (struct csi_quant_info *)(params_base + 5413200); + kernel_41->quant_channel = 1; + struct csi_tensor *bias_41 = csi_alloc_tensor(sess); + bias_41->data = params_base + 5413224; + bias_41->name = "bias_41"; + bias_41->is_const = 1; + bias_41->dtype = CSINN_DTYPE_FLOAT32; + bias_41->layout = CSINN_LAYOUT_O; + bias_41->dim[0] = 512; + bias_41->dim_count = 1; + bias_41->qinfo = (struct csi_quant_info *)(params_base + 5415272); + bias_41->quant_channel = 1; + struct conv2d_params *params_41 = csi_alloc_params(sizeof(struct conv2d_params), sess); + params_41->group = 1; + params_41->stride_height = 1; + params_41->stride_width = 1; + params_41->dilation_height = 1; + params_41->dilation_width = 1; + params_41->conv_extra.kernel_tm = NULL; + params_41->conv_extra.conv_mode = CSINN_DIRECT; + params_41->pad_top = 0; + params_41->pad_left = 0; + params_41->pad_down = 0; + params_41->pad_right = 0; + params_41->base.name = "params_41"; + csi_conv2d_init(output_40, output_41, kernel_41, bias_41, params_41); + struct csi_tensor *output_42 = csi_alloc_tensor(sess); + output_42->name = "output_42"; + output_42->dtype = CSINN_DTYPE_FLOAT32; + output_42->layout = CSINN_LAYOUT_NCHW; + output_42->dim[0] = 1; + output_42->dim[1] = 512; + output_42->dim[2] = 19; + output_42->dim[3] = 19; + output_42->dim_count = 4; + output_42->qinfo = (struct csi_quant_info *)(params_base + 5415296); + output_42->quant_channel = 1; + struct relu_params *params_42 = csi_alloc_params(sizeof(struct relu_params), sess); + params_42->base.name = "params_42"; + csi_relu_init(output_41, output_42, params_42); + struct csi_tensor *output_43 = csi_alloc_tensor(sess); + output_43->name = "output_43"; + output_43->dtype = CSINN_DTYPE_FLOAT32; + output_43->layout = CSINN_LAYOUT_NCHW; + output_43->dim[0] = 1; + output_43->dim[1] = 512; + output_43->dim[2] = 19; + output_43->dim[3] = 19; + output_43->dim_count = 4; + output_43->qinfo = (struct csi_quant_info *)(params_base + 5415320); + output_43->quant_channel = 1; + struct csi_tensor *kernel_43 = csi_alloc_tensor(sess); + kernel_43->data = params_base + 5415344; + kernel_43->name = "kernel_43"; + kernel_43->is_const = 1; + kernel_43->dtype = CSINN_DTYPE_FLOAT32; + kernel_43->layout = CSINN_LAYOUT_OIHW; + kernel_43->dim[0] = 512; + kernel_43->dim[1] = 1; + kernel_43->dim[2] = 3; + kernel_43->dim[3] = 3; + kernel_43->dim_count = 4; + kernel_43->qinfo = (struct csi_quant_info *)(params_base + 5433776); + kernel_43->quant_channel = 1; + struct csi_tensor *bias_43 = csi_alloc_tensor(sess); + bias_43->data = params_base + 5433800; + bias_43->name = "bias_43"; + bias_43->is_const = 1; + bias_43->dtype = CSINN_DTYPE_FLOAT32; + bias_43->layout = CSINN_LAYOUT_O; + bias_43->dim[0] = 512; + bias_43->dim_count = 1; + bias_43->qinfo = (struct csi_quant_info *)(params_base + 5435848); + bias_43->quant_channel = 1; + struct conv2d_params *params_43 = csi_alloc_params(sizeof(struct conv2d_params), sess); + params_43->group = 512; + params_43->stride_height = 1; + params_43->stride_width = 1; + params_43->dilation_height = 1; + params_43->dilation_width = 1; + params_43->conv_extra.kernel_tm = NULL; + params_43->conv_extra.conv_mode = CSINN_DIRECT; + params_43->pad_top = 1; + params_43->pad_left = 1; + params_43->pad_down = 1; + params_43->pad_right = 1; + params_43->base.name = "params_43"; + csi_conv2d_init(output_42, output_43, kernel_43, bias_43, params_43); + struct csi_tensor *output_44 = csi_alloc_tensor(sess); + output_44->name = "output_44"; + output_44->dtype = CSINN_DTYPE_FLOAT32; + output_44->layout = CSINN_LAYOUT_NCHW; + output_44->dim[0] = 1; + output_44->dim[1] = 512; + output_44->dim[2] = 19; + output_44->dim[3] = 19; + output_44->dim_count = 4; + output_44->qinfo = (struct csi_quant_info *)(params_base + 5435872); + output_44->quant_channel = 1; + struct relu_params *params_44 = csi_alloc_params(sizeof(struct relu_params), sess); + params_44->base.name = "params_44"; + csi_relu_init(output_43, output_44, params_44); + struct csi_tensor *output_45 = csi_alloc_tensor(sess); + output_45->name = "output_45"; + output_45->dtype = CSINN_DTYPE_FLOAT32; + output_45->layout = CSINN_LAYOUT_NCHW; + output_45->dim[0] = 1; + output_45->dim[1] = 512; + output_45->dim[2] = 19; + output_45->dim[3] = 19; + output_45->dim_count = 4; + output_45->qinfo = (struct csi_quant_info *)(params_base + 5435896); + output_45->quant_channel = 1; + struct csi_tensor *kernel_45 = csi_alloc_tensor(sess); + kernel_45->data = params_base + 5435920; + kernel_45->name = "kernel_45"; + kernel_45->is_const = 1; + kernel_45->dtype = CSINN_DTYPE_FLOAT32; + kernel_45->layout = CSINN_LAYOUT_OIHW; + kernel_45->dim[0] = 512; + kernel_45->dim[1] = 512; + kernel_45->dim[2] = 1; + kernel_45->dim[3] = 1; + kernel_45->dim_count = 4; + kernel_45->qinfo = (struct csi_quant_info *)(params_base + 6484496); + kernel_45->quant_channel = 1; + struct csi_tensor *bias_45 = csi_alloc_tensor(sess); + bias_45->data = params_base + 6484520; + bias_45->name = "bias_45"; + bias_45->is_const = 1; + bias_45->dtype = CSINN_DTYPE_FLOAT32; + bias_45->layout = CSINN_LAYOUT_O; + bias_45->dim[0] = 512; + bias_45->dim_count = 1; + bias_45->qinfo = (struct csi_quant_info *)(params_base + 6486568); + bias_45->quant_channel = 1; + struct conv2d_params *params_45 = csi_alloc_params(sizeof(struct conv2d_params), sess); + params_45->group = 1; + params_45->stride_height = 1; + params_45->stride_width = 1; + params_45->dilation_height = 1; + params_45->dilation_width = 1; + params_45->conv_extra.kernel_tm = NULL; + params_45->conv_extra.conv_mode = CSINN_DIRECT; + params_45->pad_top = 0; + params_45->pad_left = 0; + params_45->pad_down = 0; + params_45->pad_right = 0; + params_45->base.name = "params_45"; + csi_conv2d_init(output_44, output_45, kernel_45, bias_45, params_45); + struct csi_tensor *output_46 = csi_alloc_tensor(sess); + output_46->name = "output_46"; + output_46->dtype = CSINN_DTYPE_FLOAT32; + output_46->layout = CSINN_LAYOUT_NCHW; + output_46->dim[0] = 1; + output_46->dim[1] = 512; + output_46->dim[2] = 19; + output_46->dim[3] = 19; + output_46->dim_count = 4; + output_46->qinfo = (struct csi_quant_info *)(params_base + 6486592); + output_46->quant_channel = 1; + struct relu_params *params_46 = csi_alloc_params(sizeof(struct relu_params), sess); + params_46->base.name = "params_46"; + csi_relu_init(output_45, output_46, params_46); + struct csi_tensor *output_47 = csi_alloc_tensor(sess); + output_47->name = "output_47"; + output_47->dtype = CSINN_DTYPE_FLOAT32; + output_47->layout = CSINN_LAYOUT_NCHW; + output_47->dim[0] = 1; + output_47->dim[1] = 12; + output_47->dim[2] = 19; + output_47->dim[3] = 19; + output_47->dim_count = 4; + output_47->qinfo = (struct csi_quant_info *)(params_base + 6486616); + output_47->quant_channel = 1; + struct csi_tensor *kernel_47 = csi_alloc_tensor(sess); + kernel_47->data = params_base + 6486640; + kernel_47->name = "kernel_47"; + kernel_47->is_const = 1; + kernel_47->dtype = CSINN_DTYPE_FLOAT32; + kernel_47->layout = CSINN_LAYOUT_OIHW; + kernel_47->dim[0] = 12; + kernel_47->dim[1] = 512; + kernel_47->dim[2] = 1; + kernel_47->dim[3] = 1; + kernel_47->dim_count = 4; + kernel_47->qinfo = (struct csi_quant_info *)(params_base + 6511216); + kernel_47->quant_channel = 1; + struct csi_tensor *bias_47 = csi_alloc_tensor(sess); + bias_47->data = params_base + 6511240; + bias_47->name = "bias_47"; + bias_47->is_const = 1; + bias_47->dtype = CSINN_DTYPE_FLOAT32; + bias_47->layout = CSINN_LAYOUT_O; + bias_47->dim[0] = 12; + bias_47->dim_count = 1; + bias_47->qinfo = (struct csi_quant_info *)(params_base + 6511288); + bias_47->quant_channel = 1; + struct conv2d_params *params_47 = csi_alloc_params(sizeof(struct conv2d_params), sess); + params_47->group = 1; + params_47->stride_height = 1; + params_47->stride_width = 1; + params_47->dilation_height = 1; + params_47->dilation_width = 1; + params_47->conv_extra.kernel_tm = NULL; + params_47->conv_extra.conv_mode = CSINN_DIRECT; + params_47->pad_top = 0; + params_47->pad_left = 0; + params_47->pad_down = 0; + params_47->pad_right = 0; + params_47->base.name = "params_47"; + csi_conv2d_init(output_46, output_47, kernel_47, bias_47, params_47); + int32_t *permute_48 = malloc(4 * 4); + permute_48[0] = 0; + permute_48[1] = 2; + permute_48[2] = 3; + permute_48[3] = 1; + struct csi_tensor *output_48 = csi_alloc_tensor(sess); + output_48->name = "output_48"; + output_48->dtype = CSINN_DTYPE_FLOAT32; + output_48->layout = CSINN_LAYOUT_NCHW; + output_48->dim[0] = 1; + output_48->dim[1] = 19; + output_48->dim[2] = 19; + output_48->dim[3] = 12; + output_48->dim_count = 4; + output_48->qinfo = (struct csi_quant_info *)(params_base + 6511312); + output_48->quant_channel = 1; + struct transpose_params *params_48 = csi_alloc_params(sizeof(struct transpose_params), sess); + params_48->permute = permute_48; + params_48->permute_num = 4; + params_48->base.name = "params_48"; + csi_transpose_init(output_47, output_48, params_48); + struct csi_tensor *output_49 = csi_alloc_tensor(sess); + output_49->name = "output_49"; + output_49->dtype = CSINN_DTYPE_FLOAT32; + output_49->layout = CSINN_LAYOUT_NC; + output_49->dim[0] = 1; + output_49->dim[1] = 4332; + output_49->dim_count = 2; + output_49->qinfo = (struct csi_quant_info *)(params_base + 6511336); + output_49->quant_channel = 1; + struct flatten_params *params_49 = csi_alloc_params(sizeof(struct flatten_params), sess); + params_49->base.name = "params_49"; + csi_flatten_init(output_48, output_49, params_49); + struct csi_tensor *output_50 = csi_alloc_tensor(sess); + output_50->name = "output_50"; + output_50->dtype = CSINN_DTYPE_FLOAT32; + output_50->layout = CSINN_LAYOUT_NCHW; + output_50->dim[0] = 1; + output_50->dim[1] = 512; + output_50->dim[2] = 10; + output_50->dim[3] = 10; + output_50->dim_count = 4; + output_50->qinfo = (struct csi_quant_info *)(params_base + 6511360); + output_50->quant_channel = 1; + struct csi_tensor *kernel_50 = csi_alloc_tensor(sess); + kernel_50->data = params_base + 6511384; + kernel_50->name = "kernel_50"; + kernel_50->is_const = 1; + kernel_50->dtype = CSINN_DTYPE_FLOAT32; + kernel_50->layout = CSINN_LAYOUT_OIHW; + kernel_50->dim[0] = 512; + kernel_50->dim[1] = 1; + kernel_50->dim[2] = 3; + kernel_50->dim[3] = 3; + kernel_50->dim_count = 4; + kernel_50->qinfo = (struct csi_quant_info *)(params_base + 6529816); + kernel_50->quant_channel = 1; + struct csi_tensor *bias_50 = csi_alloc_tensor(sess); + bias_50->data = params_base + 6529840; + bias_50->name = "bias_50"; + bias_50->is_const = 1; + bias_50->dtype = CSINN_DTYPE_FLOAT32; + bias_50->layout = CSINN_LAYOUT_O; + bias_50->dim[0] = 512; + bias_50->dim_count = 1; + bias_50->qinfo = (struct csi_quant_info *)(params_base + 6531888); + bias_50->quant_channel = 1; + struct conv2d_params *params_50 = csi_alloc_params(sizeof(struct conv2d_params), sess); + params_50->group = 512; + params_50->stride_height = 2; + params_50->stride_width = 2; + params_50->dilation_height = 1; + params_50->dilation_width = 1; + params_50->conv_extra.kernel_tm = NULL; + params_50->conv_extra.conv_mode = CSINN_DIRECT; + params_50->pad_top = 1; + params_50->pad_left = 1; + params_50->pad_down = 1; + params_50->pad_right = 1; + params_50->base.name = "params_50"; + csi_conv2d_init(output_46, output_50, kernel_50, bias_50, params_50); + struct csi_tensor *output_51 = csi_alloc_tensor(sess); + output_51->name = "output_51"; + output_51->dtype = CSINN_DTYPE_FLOAT32; + output_51->layout = CSINN_LAYOUT_NCHW; + output_51->dim[0] = 1; + output_51->dim[1] = 512; + output_51->dim[2] = 10; + output_51->dim[3] = 10; + output_51->dim_count = 4; + output_51->qinfo = (struct csi_quant_info *)(params_base + 6531912); + output_51->quant_channel = 1; + struct relu_params *params_51 = csi_alloc_params(sizeof(struct relu_params), sess); + params_51->base.name = "params_51"; + csi_relu_init(output_50, output_51, params_51); + struct csi_tensor *output_52 = csi_alloc_tensor(sess); + output_52->name = "output_52"; + output_52->dtype = CSINN_DTYPE_FLOAT32; + output_52->layout = CSINN_LAYOUT_NCHW; + output_52->dim[0] = 1; + output_52->dim[1] = 1024; + output_52->dim[2] = 10; + output_52->dim[3] = 10; + output_52->dim_count = 4; + output_52->qinfo = (struct csi_quant_info *)(params_base + 6531936); + output_52->quant_channel = 1; + struct csi_tensor *kernel_52 = csi_alloc_tensor(sess); + kernel_52->data = params_base + 6531960; + kernel_52->name = "kernel_52"; + kernel_52->is_const = 1; + kernel_52->dtype = CSINN_DTYPE_FLOAT32; + kernel_52->layout = CSINN_LAYOUT_OIHW; + kernel_52->dim[0] = 1024; + kernel_52->dim[1] = 512; + kernel_52->dim[2] = 1; + kernel_52->dim[3] = 1; + kernel_52->dim_count = 4; + kernel_52->qinfo = (struct csi_quant_info *)(params_base + 8629112); + kernel_52->quant_channel = 1; + struct csi_tensor *bias_52 = csi_alloc_tensor(sess); + bias_52->data = params_base + 8629136; + bias_52->name = "bias_52"; + bias_52->is_const = 1; + bias_52->dtype = CSINN_DTYPE_FLOAT32; + bias_52->layout = CSINN_LAYOUT_O; + bias_52->dim[0] = 1024; + bias_52->dim_count = 1; + bias_52->qinfo = (struct csi_quant_info *)(params_base + 8633232); + bias_52->quant_channel = 1; + struct conv2d_params *params_52 = csi_alloc_params(sizeof(struct conv2d_params), sess); + params_52->group = 1; + params_52->stride_height = 1; + params_52->stride_width = 1; + params_52->dilation_height = 1; + params_52->dilation_width = 1; + params_52->conv_extra.kernel_tm = NULL; + params_52->conv_extra.conv_mode = CSINN_DIRECT; + params_52->pad_top = 0; + params_52->pad_left = 0; + params_52->pad_down = 0; + params_52->pad_right = 0; + params_52->base.name = "params_52"; + csi_conv2d_init(output_51, output_52, kernel_52, bias_52, params_52); + struct csi_tensor *output_53 = csi_alloc_tensor(sess); + output_53->name = "output_53"; + output_53->dtype = CSINN_DTYPE_FLOAT32; + output_53->layout = CSINN_LAYOUT_NCHW; + output_53->dim[0] = 1; + output_53->dim[1] = 1024; + output_53->dim[2] = 10; + output_53->dim[3] = 10; + output_53->dim_count = 4; + output_53->qinfo = (struct csi_quant_info *)(params_base + 8633256); + output_53->quant_channel = 1; + struct relu_params *params_53 = csi_alloc_params(sizeof(struct relu_params), sess); + params_53->base.name = "params_53"; + csi_relu_init(output_52, output_53, params_53); + struct csi_tensor *output_54 = csi_alloc_tensor(sess); + output_54->name = "output_54"; + output_54->dtype = CSINN_DTYPE_FLOAT32; + output_54->layout = CSINN_LAYOUT_NCHW; + output_54->dim[0] = 1; + output_54->dim[1] = 1024; + output_54->dim[2] = 10; + output_54->dim[3] = 10; + output_54->dim_count = 4; + output_54->qinfo = (struct csi_quant_info *)(params_base + 8633280); + output_54->quant_channel = 1; + struct csi_tensor *kernel_54 = csi_alloc_tensor(sess); + kernel_54->data = params_base + 8633304; + kernel_54->name = "kernel_54"; + kernel_54->is_const = 1; + kernel_54->dtype = CSINN_DTYPE_FLOAT32; + kernel_54->layout = CSINN_LAYOUT_OIHW; + kernel_54->dim[0] = 1024; + kernel_54->dim[1] = 1; + kernel_54->dim[2] = 3; + kernel_54->dim[3] = 3; + kernel_54->dim_count = 4; + kernel_54->qinfo = (struct csi_quant_info *)(params_base + 8670168); + kernel_54->quant_channel = 1; + struct csi_tensor *bias_54 = csi_alloc_tensor(sess); + bias_54->data = params_base + 8670192; + bias_54->name = "bias_54"; + bias_54->is_const = 1; + bias_54->dtype = CSINN_DTYPE_FLOAT32; + bias_54->layout = CSINN_LAYOUT_O; + bias_54->dim[0] = 1024; + bias_54->dim_count = 1; + bias_54->qinfo = (struct csi_quant_info *)(params_base + 8674288); + bias_54->quant_channel = 1; + struct conv2d_params *params_54 = csi_alloc_params(sizeof(struct conv2d_params), sess); + params_54->group = 1024; + params_54->stride_height = 1; + params_54->stride_width = 1; + params_54->dilation_height = 1; + params_54->dilation_width = 1; + params_54->conv_extra.kernel_tm = NULL; + params_54->conv_extra.conv_mode = CSINN_DIRECT; + params_54->pad_top = 1; + params_54->pad_left = 1; + params_54->pad_down = 1; + params_54->pad_right = 1; + params_54->base.name = "params_54"; + csi_conv2d_init(output_53, output_54, kernel_54, bias_54, params_54); + struct csi_tensor *output_55 = csi_alloc_tensor(sess); + output_55->name = "output_55"; + output_55->dtype = CSINN_DTYPE_FLOAT32; + output_55->layout = CSINN_LAYOUT_NCHW; + output_55->dim[0] = 1; + output_55->dim[1] = 1024; + output_55->dim[2] = 10; + output_55->dim[3] = 10; + output_55->dim_count = 4; + output_55->qinfo = (struct csi_quant_info *)(params_base + 8674312); + output_55->quant_channel = 1; + struct relu_params *params_55 = csi_alloc_params(sizeof(struct relu_params), sess); + params_55->base.name = "params_55"; + csi_relu_init(output_54, output_55, params_55); + struct csi_tensor *output_56 = csi_alloc_tensor(sess); + output_56->name = "output_56"; + output_56->dtype = CSINN_DTYPE_FLOAT32; + output_56->layout = CSINN_LAYOUT_NCHW; + output_56->dim[0] = 1; + output_56->dim[1] = 1024; + output_56->dim[2] = 10; + output_56->dim[3] = 10; + output_56->dim_count = 4; + output_56->qinfo = (struct csi_quant_info *)(params_base + 8674336); + output_56->quant_channel = 1; + struct csi_tensor *kernel_56 = csi_alloc_tensor(sess); + kernel_56->data = params_base + 8674360; + kernel_56->name = "kernel_56"; + kernel_56->is_const = 1; + kernel_56->dtype = CSINN_DTYPE_FLOAT32; + kernel_56->layout = CSINN_LAYOUT_OIHW; + kernel_56->dim[0] = 1024; + kernel_56->dim[1] = 1024; + kernel_56->dim[2] = 1; + kernel_56->dim[3] = 1; + kernel_56->dim_count = 4; + kernel_56->qinfo = (struct csi_quant_info *)(params_base + 12868664); + kernel_56->quant_channel = 1; + struct csi_tensor *bias_56 = csi_alloc_tensor(sess); + bias_56->data = params_base + 12868688; + bias_56->name = "bias_56"; + bias_56->is_const = 1; + bias_56->dtype = CSINN_DTYPE_FLOAT32; + bias_56->layout = CSINN_LAYOUT_O; + bias_56->dim[0] = 1024; + bias_56->dim_count = 1; + bias_56->qinfo = (struct csi_quant_info *)(params_base + 12872784); + bias_56->quant_channel = 1; + struct conv2d_params *params_56 = csi_alloc_params(sizeof(struct conv2d_params), sess); + params_56->group = 1; + params_56->stride_height = 1; + params_56->stride_width = 1; + params_56->dilation_height = 1; + params_56->dilation_width = 1; + params_56->conv_extra.kernel_tm = NULL; + params_56->conv_extra.conv_mode = CSINN_DIRECT; + params_56->pad_top = 0; + params_56->pad_left = 0; + params_56->pad_down = 0; + params_56->pad_right = 0; + params_56->base.name = "params_56"; + csi_conv2d_init(output_55, output_56, kernel_56, bias_56, params_56); + struct csi_tensor *output_57 = csi_alloc_tensor(sess); + output_57->name = "output_57"; + output_57->dtype = CSINN_DTYPE_FLOAT32; + output_57->layout = CSINN_LAYOUT_NCHW; + output_57->dim[0] = 1; + output_57->dim[1] = 1024; + output_57->dim[2] = 10; + output_57->dim[3] = 10; + output_57->dim_count = 4; + output_57->qinfo = (struct csi_quant_info *)(params_base + 12872808); + output_57->quant_channel = 1; + struct relu_params *params_57 = csi_alloc_params(sizeof(struct relu_params), sess); + params_57->base.name = "params_57"; + csi_relu_init(output_56, output_57, params_57); + struct csi_tensor *output_58 = csi_alloc_tensor(sess); + output_58->name = "output_58"; + output_58->dtype = CSINN_DTYPE_FLOAT32; + output_58->layout = CSINN_LAYOUT_NCHW; + output_58->dim[0] = 1; + output_58->dim[1] = 24; + output_58->dim[2] = 10; + output_58->dim[3] = 10; + output_58->dim_count = 4; + output_58->qinfo = (struct csi_quant_info *)(params_base + 12872832); + output_58->quant_channel = 1; + struct csi_tensor *kernel_58 = csi_alloc_tensor(sess); + kernel_58->data = params_base + 12872856; + kernel_58->name = "kernel_58"; + kernel_58->is_const = 1; + kernel_58->dtype = CSINN_DTYPE_FLOAT32; + kernel_58->layout = CSINN_LAYOUT_OIHW; + kernel_58->dim[0] = 24; + kernel_58->dim[1] = 1024; + kernel_58->dim[2] = 1; + kernel_58->dim[3] = 1; + kernel_58->dim_count = 4; + kernel_58->qinfo = (struct csi_quant_info *)(params_base + 12971160); + kernel_58->quant_channel = 1; + struct csi_tensor *bias_58 = csi_alloc_tensor(sess); + bias_58->data = params_base + 12971184; + bias_58->name = "bias_58"; + bias_58->is_const = 1; + bias_58->dtype = CSINN_DTYPE_FLOAT32; + bias_58->layout = CSINN_LAYOUT_O; + bias_58->dim[0] = 24; + bias_58->dim_count = 1; + bias_58->qinfo = (struct csi_quant_info *)(params_base + 12971280); + bias_58->quant_channel = 1; + struct conv2d_params *params_58 = csi_alloc_params(sizeof(struct conv2d_params), sess); + params_58->group = 1; + params_58->stride_height = 1; + params_58->stride_width = 1; + params_58->dilation_height = 1; + params_58->dilation_width = 1; + params_58->conv_extra.kernel_tm = NULL; + params_58->conv_extra.conv_mode = CSINN_DIRECT; + params_58->pad_top = 0; + params_58->pad_left = 0; + params_58->pad_down = 0; + params_58->pad_right = 0; + params_58->base.name = "params_58"; + csi_conv2d_init(output_57, output_58, kernel_58, bias_58, params_58); + int32_t *permute_59 = malloc(4 * 4); + permute_59[0] = 0; + permute_59[1] = 2; + permute_59[2] = 3; + permute_59[3] = 1; + struct csi_tensor *output_59 = csi_alloc_tensor(sess); + output_59->name = "output_59"; + output_59->dtype = CSINN_DTYPE_FLOAT32; + output_59->layout = CSINN_LAYOUT_NCHW; + output_59->dim[0] = 1; + output_59->dim[1] = 10; + output_59->dim[2] = 10; + output_59->dim[3] = 24; + output_59->dim_count = 4; + output_59->qinfo = (struct csi_quant_info *)(params_base + 12971304); + output_59->quant_channel = 1; + struct transpose_params *params_59 = csi_alloc_params(sizeof(struct transpose_params), sess); + params_59->permute = permute_59; + params_59->permute_num = 4; + params_59->base.name = "params_59"; + csi_transpose_init(output_58, output_59, params_59); + struct csi_tensor *output_60 = csi_alloc_tensor(sess); + output_60->name = "output_60"; + output_60->dtype = CSINN_DTYPE_FLOAT32; + output_60->layout = CSINN_LAYOUT_NC; + output_60->dim[0] = 1; + output_60->dim[1] = 2400; + output_60->dim_count = 2; + output_60->qinfo = (struct csi_quant_info *)(params_base + 12971328); + output_60->quant_channel = 1; + struct flatten_params *params_60 = csi_alloc_params(sizeof(struct flatten_params), sess); + params_60->base.name = "params_60"; + csi_flatten_init(output_59, output_60, params_60); + struct csi_tensor *output_61 = csi_alloc_tensor(sess); + output_61->name = "output_61"; + output_61->dtype = CSINN_DTYPE_FLOAT32; + output_61->layout = CSINN_LAYOUT_NCHW; + output_61->dim[0] = 1; + output_61->dim[1] = 256; + output_61->dim[2] = 10; + output_61->dim[3] = 10; + output_61->dim_count = 4; + output_61->qinfo = (struct csi_quant_info *)(params_base + 12971352); + output_61->quant_channel = 1; + struct csi_tensor *kernel_61 = csi_alloc_tensor(sess); + kernel_61->data = params_base + 12971376; + kernel_61->name = "kernel_61"; + kernel_61->is_const = 1; + kernel_61->dtype = CSINN_DTYPE_FLOAT32; + kernel_61->layout = CSINN_LAYOUT_OIHW; + kernel_61->dim[0] = 256; + kernel_61->dim[1] = 1024; + kernel_61->dim[2] = 1; + kernel_61->dim[3] = 1; + kernel_61->dim_count = 4; + kernel_61->qinfo = (struct csi_quant_info *)(params_base + 14019952); + kernel_61->quant_channel = 1; + struct csi_tensor *bias_61 = csi_alloc_tensor(sess); + bias_61->data = params_base + 14019976; + bias_61->name = "bias_61"; + bias_61->is_const = 1; + bias_61->dtype = CSINN_DTYPE_FLOAT32; + bias_61->layout = CSINN_LAYOUT_O; + bias_61->dim[0] = 256; + bias_61->dim_count = 1; + bias_61->qinfo = (struct csi_quant_info *)(params_base + 14021000); + bias_61->quant_channel = 1; + struct conv2d_params *params_61 = csi_alloc_params(sizeof(struct conv2d_params), sess); + params_61->group = 1; + params_61->stride_height = 1; + params_61->stride_width = 1; + params_61->dilation_height = 1; + params_61->dilation_width = 1; + params_61->conv_extra.kernel_tm = NULL; + params_61->conv_extra.conv_mode = CSINN_DIRECT; + params_61->pad_top = 0; + params_61->pad_left = 0; + params_61->pad_down = 0; + params_61->pad_right = 0; + params_61->base.name = "params_61"; + csi_conv2d_init(output_57, output_61, kernel_61, bias_61, params_61); + struct csi_tensor *output_62 = csi_alloc_tensor(sess); + output_62->name = "output_62"; + output_62->dtype = CSINN_DTYPE_FLOAT32; + output_62->layout = CSINN_LAYOUT_NCHW; + output_62->dim[0] = 1; + output_62->dim[1] = 256; + output_62->dim[2] = 10; + output_62->dim[3] = 10; + output_62->dim_count = 4; + output_62->qinfo = (struct csi_quant_info *)(params_base + 14021024); + output_62->quant_channel = 1; + struct relu_params *params_62 = csi_alloc_params(sizeof(struct relu_params), sess); + params_62->base.name = "params_62"; + csi_relu_init(output_61, output_62, params_62); + struct csi_tensor *output_63 = csi_alloc_tensor(sess); + output_63->name = "output_63"; + output_63->dtype = CSINN_DTYPE_FLOAT32; + output_63->layout = CSINN_LAYOUT_NCHW; + output_63->dim[0] = 1; + output_63->dim[1] = 512; + output_63->dim[2] = 5; + output_63->dim[3] = 5; + output_63->dim_count = 4; + output_63->qinfo = (struct csi_quant_info *)(params_base + 14021048); + output_63->quant_channel = 1; + struct csi_tensor *kernel_63 = csi_alloc_tensor(sess); + kernel_63->data = params_base + 14021072; + kernel_63->name = "kernel_63"; + kernel_63->is_const = 1; + kernel_63->dtype = CSINN_DTYPE_FLOAT32; + kernel_63->layout = CSINN_LAYOUT_OIHW; + kernel_63->dim[0] = 512; + kernel_63->dim[1] = 256; + kernel_63->dim[2] = 3; + kernel_63->dim[3] = 3; + kernel_63->dim_count = 4; + kernel_63->qinfo = (struct csi_quant_info *)(params_base + 18739664); + kernel_63->quant_channel = 1; + struct csi_tensor *bias_63 = csi_alloc_tensor(sess); + bias_63->data = params_base + 18739688; + bias_63->name = "bias_63"; + bias_63->is_const = 1; + bias_63->dtype = CSINN_DTYPE_FLOAT32; + bias_63->layout = CSINN_LAYOUT_O; + bias_63->dim[0] = 512; + bias_63->dim_count = 1; + bias_63->qinfo = (struct csi_quant_info *)(params_base + 18741736); + bias_63->quant_channel = 1; + struct conv2d_params *params_63 = csi_alloc_params(sizeof(struct conv2d_params), sess); + params_63->group = 1; + params_63->stride_height = 2; + params_63->stride_width = 2; + params_63->dilation_height = 1; + params_63->dilation_width = 1; + params_63->conv_extra.kernel_tm = NULL; + params_63->conv_extra.conv_mode = CSINN_DIRECT; + params_63->pad_top = 1; + params_63->pad_left = 1; + params_63->pad_down = 1; + params_63->pad_right = 1; + params_63->base.name = "params_63"; + csi_conv2d_init(output_62, output_63, kernel_63, bias_63, params_63); + struct csi_tensor *output_64 = csi_alloc_tensor(sess); + output_64->name = "output_64"; + output_64->dtype = CSINN_DTYPE_FLOAT32; + output_64->layout = CSINN_LAYOUT_NCHW; + output_64->dim[0] = 1; + output_64->dim[1] = 512; + output_64->dim[2] = 5; + output_64->dim[3] = 5; + output_64->dim_count = 4; + output_64->qinfo = (struct csi_quant_info *)(params_base + 18741760); + output_64->quant_channel = 1; + struct relu_params *params_64 = csi_alloc_params(sizeof(struct relu_params), sess); + params_64->base.name = "params_64"; + csi_relu_init(output_63, output_64, params_64); + struct csi_tensor *output_65 = csi_alloc_tensor(sess); + output_65->name = "output_65"; + output_65->dtype = CSINN_DTYPE_FLOAT32; + output_65->layout = CSINN_LAYOUT_NCHW; + output_65->dim[0] = 1; + output_65->dim[1] = 24; + output_65->dim[2] = 5; + output_65->dim[3] = 5; + output_65->dim_count = 4; + output_65->qinfo = (struct csi_quant_info *)(params_base + 18741784); + output_65->quant_channel = 1; + struct csi_tensor *kernel_65 = csi_alloc_tensor(sess); + kernel_65->data = params_base + 18741808; + kernel_65->name = "kernel_65"; + kernel_65->is_const = 1; + kernel_65->dtype = CSINN_DTYPE_FLOAT32; + kernel_65->layout = CSINN_LAYOUT_OIHW; + kernel_65->dim[0] = 24; + kernel_65->dim[1] = 512; + kernel_65->dim[2] = 1; + kernel_65->dim[3] = 1; + kernel_65->dim_count = 4; + kernel_65->qinfo = (struct csi_quant_info *)(params_base + 18790960); + kernel_65->quant_channel = 1; + struct csi_tensor *bias_65 = csi_alloc_tensor(sess); + bias_65->data = params_base + 18790984; + bias_65->name = "bias_65"; + bias_65->is_const = 1; + bias_65->dtype = CSINN_DTYPE_FLOAT32; + bias_65->layout = CSINN_LAYOUT_O; + bias_65->dim[0] = 24; + bias_65->dim_count = 1; + bias_65->qinfo = (struct csi_quant_info *)(params_base + 18791080); + bias_65->quant_channel = 1; + struct conv2d_params *params_65 = csi_alloc_params(sizeof(struct conv2d_params), sess); + params_65->group = 1; + params_65->stride_height = 1; + params_65->stride_width = 1; + params_65->dilation_height = 1; + params_65->dilation_width = 1; + params_65->conv_extra.kernel_tm = NULL; + params_65->conv_extra.conv_mode = CSINN_DIRECT; + params_65->pad_top = 0; + params_65->pad_left = 0; + params_65->pad_down = 0; + params_65->pad_right = 0; + params_65->base.name = "params_65"; + csi_conv2d_init(output_64, output_65, kernel_65, bias_65, params_65); + int32_t *permute_66 = malloc(4 * 4); + permute_66[0] = 0; + permute_66[1] = 2; + permute_66[2] = 3; + permute_66[3] = 1; + struct csi_tensor *output_66 = csi_alloc_tensor(sess); + output_66->name = "output_66"; + output_66->dtype = CSINN_DTYPE_FLOAT32; + output_66->layout = CSINN_LAYOUT_NCHW; + output_66->dim[0] = 1; + output_66->dim[1] = 5; + output_66->dim[2] = 5; + output_66->dim[3] = 24; + output_66->dim_count = 4; + output_66->qinfo = (struct csi_quant_info *)(params_base + 18791104); + output_66->quant_channel = 1; + struct transpose_params *params_66 = csi_alloc_params(sizeof(struct transpose_params), sess); + params_66->permute = permute_66; + params_66->permute_num = 4; + params_66->base.name = "params_66"; + csi_transpose_init(output_65, output_66, params_66); + struct csi_tensor *output_67 = csi_alloc_tensor(sess); + output_67->name = "output_67"; + output_67->dtype = CSINN_DTYPE_FLOAT32; + output_67->layout = CSINN_LAYOUT_NC; + output_67->dim[0] = 1; + output_67->dim[1] = 600; + output_67->dim_count = 2; + output_67->qinfo = (struct csi_quant_info *)(params_base + 18791128); + output_67->quant_channel = 1; + struct flatten_params *params_67 = csi_alloc_params(sizeof(struct flatten_params), sess); + params_67->base.name = "params_67"; + csi_flatten_init(output_66, output_67, params_67); + struct csi_tensor *output_68 = csi_alloc_tensor(sess); + output_68->name = "output_68"; + output_68->dtype = CSINN_DTYPE_FLOAT32; + output_68->layout = CSINN_LAYOUT_NCHW; + output_68->dim[0] = 1; + output_68->dim[1] = 128; + output_68->dim[2] = 5; + output_68->dim[3] = 5; + output_68->dim_count = 4; + output_68->qinfo = (struct csi_quant_info *)(params_base + 18791152); + output_68->quant_channel = 1; + struct csi_tensor *kernel_68 = csi_alloc_tensor(sess); + kernel_68->data = params_base + 18791176; + kernel_68->name = "kernel_68"; + kernel_68->is_const = 1; + kernel_68->dtype = CSINN_DTYPE_FLOAT32; + kernel_68->layout = CSINN_LAYOUT_OIHW; + kernel_68->dim[0] = 128; + kernel_68->dim[1] = 512; + kernel_68->dim[2] = 1; + kernel_68->dim[3] = 1; + kernel_68->dim_count = 4; + kernel_68->qinfo = (struct csi_quant_info *)(params_base + 19053320); + kernel_68->quant_channel = 1; + struct csi_tensor *bias_68 = csi_alloc_tensor(sess); + bias_68->data = params_base + 19053344; + bias_68->name = "bias_68"; + bias_68->is_const = 1; + bias_68->dtype = CSINN_DTYPE_FLOAT32; + bias_68->layout = CSINN_LAYOUT_O; + bias_68->dim[0] = 128; + bias_68->dim_count = 1; + bias_68->qinfo = (struct csi_quant_info *)(params_base + 19053856); + bias_68->quant_channel = 1; + struct conv2d_params *params_68 = csi_alloc_params(sizeof(struct conv2d_params), sess); + params_68->group = 1; + params_68->stride_height = 1; + params_68->stride_width = 1; + params_68->dilation_height = 1; + params_68->dilation_width = 1; + params_68->conv_extra.kernel_tm = NULL; + params_68->conv_extra.conv_mode = CSINN_DIRECT; + params_68->pad_top = 0; + params_68->pad_left = 0; + params_68->pad_down = 0; + params_68->pad_right = 0; + params_68->base.name = "params_68"; + csi_conv2d_init(output_64, output_68, kernel_68, bias_68, params_68); + struct csi_tensor *output_69 = csi_alloc_tensor(sess); + output_69->name = "output_69"; + output_69->dtype = CSINN_DTYPE_FLOAT32; + output_69->layout = CSINN_LAYOUT_NCHW; + output_69->dim[0] = 1; + output_69->dim[1] = 128; + output_69->dim[2] = 5; + output_69->dim[3] = 5; + output_69->dim_count = 4; + output_69->qinfo = (struct csi_quant_info *)(params_base + 19053880); + output_69->quant_channel = 1; + struct relu_params *params_69 = csi_alloc_params(sizeof(struct relu_params), sess); + params_69->base.name = "params_69"; + csi_relu_init(output_68, output_69, params_69); + struct csi_tensor *output_70 = csi_alloc_tensor(sess); + output_70->name = "output_70"; + output_70->dtype = CSINN_DTYPE_FLOAT32; + output_70->layout = CSINN_LAYOUT_NCHW; + output_70->dim[0] = 1; + output_70->dim[1] = 256; + output_70->dim[2] = 3; + output_70->dim[3] = 3; + output_70->dim_count = 4; + output_70->qinfo = (struct csi_quant_info *)(params_base + 19053904); + output_70->quant_channel = 1; + struct csi_tensor *kernel_70 = csi_alloc_tensor(sess); + kernel_70->data = params_base + 19053928; + kernel_70->name = "kernel_70"; + kernel_70->is_const = 1; + kernel_70->dtype = CSINN_DTYPE_FLOAT32; + kernel_70->layout = CSINN_LAYOUT_OIHW; + kernel_70->dim[0] = 256; + kernel_70->dim[1] = 128; + kernel_70->dim[2] = 3; + kernel_70->dim[3] = 3; + kernel_70->dim_count = 4; + kernel_70->qinfo = (struct csi_quant_info *)(params_base + 20233576); + kernel_70->quant_channel = 1; + struct csi_tensor *bias_70 = csi_alloc_tensor(sess); + bias_70->data = params_base + 20233600; + bias_70->name = "bias_70"; + bias_70->is_const = 1; + bias_70->dtype = CSINN_DTYPE_FLOAT32; + bias_70->layout = CSINN_LAYOUT_O; + bias_70->dim[0] = 256; + bias_70->dim_count = 1; + bias_70->qinfo = (struct csi_quant_info *)(params_base + 20234624); + bias_70->quant_channel = 1; + struct conv2d_params *params_70 = csi_alloc_params(sizeof(struct conv2d_params), sess); + params_70->group = 1; + params_70->stride_height = 2; + params_70->stride_width = 2; + params_70->dilation_height = 1; + params_70->dilation_width = 1; + params_70->conv_extra.kernel_tm = NULL; + params_70->conv_extra.conv_mode = CSINN_DIRECT; + params_70->pad_top = 1; + params_70->pad_left = 1; + params_70->pad_down = 1; + params_70->pad_right = 1; + params_70->base.name = "params_70"; + csi_conv2d_init(output_69, output_70, kernel_70, bias_70, params_70); + struct csi_tensor *output_71 = csi_alloc_tensor(sess); + output_71->name = "output_71"; + output_71->dtype = CSINN_DTYPE_FLOAT32; + output_71->layout = CSINN_LAYOUT_NCHW; + output_71->dim[0] = 1; + output_71->dim[1] = 256; + output_71->dim[2] = 3; + output_71->dim[3] = 3; + output_71->dim_count = 4; + output_71->qinfo = (struct csi_quant_info *)(params_base + 20234648); + output_71->quant_channel = 1; + struct relu_params *params_71 = csi_alloc_params(sizeof(struct relu_params), sess); + params_71->base.name = "params_71"; + csi_relu_init(output_70, output_71, params_71); + struct csi_tensor *output_72 = csi_alloc_tensor(sess); + output_72->name = "output_72"; + output_72->dtype = CSINN_DTYPE_FLOAT32; + output_72->layout = CSINN_LAYOUT_NCHW; + output_72->dim[0] = 1; + output_72->dim[1] = 24; + output_72->dim[2] = 3; + output_72->dim[3] = 3; + output_72->dim_count = 4; + output_72->qinfo = (struct csi_quant_info *)(params_base + 20234672); + output_72->quant_channel = 1; + struct csi_tensor *kernel_72 = csi_alloc_tensor(sess); + kernel_72->data = params_base + 20234696; + kernel_72->name = "kernel_72"; + kernel_72->is_const = 1; + kernel_72->dtype = CSINN_DTYPE_FLOAT32; + kernel_72->layout = CSINN_LAYOUT_OIHW; + kernel_72->dim[0] = 24; + kernel_72->dim[1] = 256; + kernel_72->dim[2] = 1; + kernel_72->dim[3] = 1; + kernel_72->dim_count = 4; + kernel_72->qinfo = (struct csi_quant_info *)(params_base + 20259272); + kernel_72->quant_channel = 1; + struct csi_tensor *bias_72 = csi_alloc_tensor(sess); + bias_72->data = params_base + 20259296; + bias_72->name = "bias_72"; + bias_72->is_const = 1; + bias_72->dtype = CSINN_DTYPE_FLOAT32; + bias_72->layout = CSINN_LAYOUT_O; + bias_72->dim[0] = 24; + bias_72->dim_count = 1; + bias_72->qinfo = (struct csi_quant_info *)(params_base + 20259392); + bias_72->quant_channel = 1; + struct conv2d_params *params_72 = csi_alloc_params(sizeof(struct conv2d_params), sess); + params_72->group = 1; + params_72->stride_height = 1; + params_72->stride_width = 1; + params_72->dilation_height = 1; + params_72->dilation_width = 1; + params_72->conv_extra.kernel_tm = NULL; + params_72->conv_extra.conv_mode = CSINN_DIRECT; + params_72->pad_top = 0; + params_72->pad_left = 0; + params_72->pad_down = 0; + params_72->pad_right = 0; + params_72->base.name = "params_72"; + csi_conv2d_init(output_71, output_72, kernel_72, bias_72, params_72); + int32_t *permute_73 = malloc(4 * 4); + permute_73[0] = 0; + permute_73[1] = 2; + permute_73[2] = 3; + permute_73[3] = 1; + struct csi_tensor *output_73 = csi_alloc_tensor(sess); + output_73->name = "output_73"; + output_73->dtype = CSINN_DTYPE_FLOAT32; + output_73->layout = CSINN_LAYOUT_NCHW; + output_73->dim[0] = 1; + output_73->dim[1] = 3; + output_73->dim[2] = 3; + output_73->dim[3] = 24; + output_73->dim_count = 4; + output_73->qinfo = (struct csi_quant_info *)(params_base + 20259416); + output_73->quant_channel = 1; + struct transpose_params *params_73 = csi_alloc_params(sizeof(struct transpose_params), sess); + params_73->permute = permute_73; + params_73->permute_num = 4; + params_73->base.name = "params_73"; + csi_transpose_init(output_72, output_73, params_73); + struct csi_tensor *output_74 = csi_alloc_tensor(sess); + output_74->name = "output_74"; + output_74->dtype = CSINN_DTYPE_FLOAT32; + output_74->layout = CSINN_LAYOUT_NC; + output_74->dim[0] = 1; + output_74->dim[1] = 216; + output_74->dim_count = 2; + output_74->qinfo = (struct csi_quant_info *)(params_base + 20259440); + output_74->quant_channel = 1; + struct flatten_params *params_74 = csi_alloc_params(sizeof(struct flatten_params), sess); + params_74->base.name = "params_74"; + csi_flatten_init(output_73, output_74, params_74); + struct csi_tensor *output_75 = csi_alloc_tensor(sess); + output_75->name = "output_75"; + output_75->dtype = CSINN_DTYPE_FLOAT32; + output_75->layout = CSINN_LAYOUT_NCHW; + output_75->dim[0] = 1; + output_75->dim[1] = 128; + output_75->dim[2] = 3; + output_75->dim[3] = 3; + output_75->dim_count = 4; + output_75->qinfo = (struct csi_quant_info *)(params_base + 20259464); + output_75->quant_channel = 1; + struct csi_tensor *kernel_75 = csi_alloc_tensor(sess); + kernel_75->data = params_base + 20259488; + kernel_75->name = "kernel_75"; + kernel_75->is_const = 1; + kernel_75->dtype = CSINN_DTYPE_FLOAT32; + kernel_75->layout = CSINN_LAYOUT_OIHW; + kernel_75->dim[0] = 128; + kernel_75->dim[1] = 256; + kernel_75->dim[2] = 1; + kernel_75->dim[3] = 1; + kernel_75->dim_count = 4; + kernel_75->qinfo = (struct csi_quant_info *)(params_base + 20390560); + kernel_75->quant_channel = 1; + struct csi_tensor *bias_75 = csi_alloc_tensor(sess); + bias_75->data = params_base + 20390584; + bias_75->name = "bias_75"; + bias_75->is_const = 1; + bias_75->dtype = CSINN_DTYPE_FLOAT32; + bias_75->layout = CSINN_LAYOUT_O; + bias_75->dim[0] = 128; + bias_75->dim_count = 1; + bias_75->qinfo = (struct csi_quant_info *)(params_base + 20391096); + bias_75->quant_channel = 1; + struct conv2d_params *params_75 = csi_alloc_params(sizeof(struct conv2d_params), sess); + params_75->group = 1; + params_75->stride_height = 1; + params_75->stride_width = 1; + params_75->dilation_height = 1; + params_75->dilation_width = 1; + params_75->conv_extra.kernel_tm = NULL; + params_75->conv_extra.conv_mode = CSINN_DIRECT; + params_75->pad_top = 0; + params_75->pad_left = 0; + params_75->pad_down = 0; + params_75->pad_right = 0; + params_75->base.name = "params_75"; + csi_conv2d_init(output_71, output_75, kernel_75, bias_75, params_75); + struct csi_tensor *output_76 = csi_alloc_tensor(sess); + output_76->name = "output_76"; + output_76->dtype = CSINN_DTYPE_FLOAT32; + output_76->layout = CSINN_LAYOUT_NCHW; + output_76->dim[0] = 1; + output_76->dim[1] = 128; + output_76->dim[2] = 3; + output_76->dim[3] = 3; + output_76->dim_count = 4; + output_76->qinfo = (struct csi_quant_info *)(params_base + 20391120); + output_76->quant_channel = 1; + struct relu_params *params_76 = csi_alloc_params(sizeof(struct relu_params), sess); + params_76->base.name = "params_76"; + csi_relu_init(output_75, output_76, params_76); + struct csi_tensor *output_77 = csi_alloc_tensor(sess); + output_77->name = "output_77"; + output_77->dtype = CSINN_DTYPE_FLOAT32; + output_77->layout = CSINN_LAYOUT_NCHW; + output_77->dim[0] = 1; + output_77->dim[1] = 256; + output_77->dim[2] = 2; + output_77->dim[3] = 2; + output_77->dim_count = 4; + output_77->qinfo = (struct csi_quant_info *)(params_base + 20391144); + output_77->quant_channel = 1; + struct csi_tensor *kernel_77 = csi_alloc_tensor(sess); + kernel_77->data = params_base + 20391168; + kernel_77->name = "kernel_77"; + kernel_77->is_const = 1; + kernel_77->dtype = CSINN_DTYPE_FLOAT32; + kernel_77->layout = CSINN_LAYOUT_OIHW; + kernel_77->dim[0] = 256; + kernel_77->dim[1] = 128; + kernel_77->dim[2] = 3; + kernel_77->dim[3] = 3; + kernel_77->dim_count = 4; + kernel_77->qinfo = (struct csi_quant_info *)(params_base + 21570816); + kernel_77->quant_channel = 1; + struct csi_tensor *bias_77 = csi_alloc_tensor(sess); + bias_77->data = params_base + 21570840; + bias_77->name = "bias_77"; + bias_77->is_const = 1; + bias_77->dtype = CSINN_DTYPE_FLOAT32; + bias_77->layout = CSINN_LAYOUT_O; + bias_77->dim[0] = 256; + bias_77->dim_count = 1; + bias_77->qinfo = (struct csi_quant_info *)(params_base + 21571864); + bias_77->quant_channel = 1; + struct conv2d_params *params_77 = csi_alloc_params(sizeof(struct conv2d_params), sess); + params_77->group = 1; + params_77->stride_height = 2; + params_77->stride_width = 2; + params_77->dilation_height = 1; + params_77->dilation_width = 1; + params_77->conv_extra.kernel_tm = NULL; + params_77->conv_extra.conv_mode = CSINN_DIRECT; + params_77->pad_top = 1; + params_77->pad_left = 1; + params_77->pad_down = 1; + params_77->pad_right = 1; + params_77->base.name = "params_77"; + csi_conv2d_init(output_76, output_77, kernel_77, bias_77, params_77); + struct csi_tensor *output_78 = csi_alloc_tensor(sess); + output_78->name = "output_78"; + output_78->dtype = CSINN_DTYPE_FLOAT32; + output_78->layout = CSINN_LAYOUT_NCHW; + output_78->dim[0] = 1; + output_78->dim[1] = 256; + output_78->dim[2] = 2; + output_78->dim[3] = 2; + output_78->dim_count = 4; + output_78->qinfo = (struct csi_quant_info *)(params_base + 21571888); + output_78->quant_channel = 1; + struct relu_params *params_78 = csi_alloc_params(sizeof(struct relu_params), sess); + params_78->base.name = "params_78"; + csi_relu_init(output_77, output_78, params_78); + struct csi_tensor *output_79 = csi_alloc_tensor(sess); + output_79->name = "output_79"; + output_79->dtype = CSINN_DTYPE_FLOAT32; + output_79->layout = CSINN_LAYOUT_NCHW; + output_79->dim[0] = 1; + output_79->dim[1] = 24; + output_79->dim[2] = 2; + output_79->dim[3] = 2; + output_79->dim_count = 4; + output_79->qinfo = (struct csi_quant_info *)(params_base + 21571912); + output_79->quant_channel = 1; + struct csi_tensor *kernel_79 = csi_alloc_tensor(sess); + kernel_79->data = params_base + 21571936; + kernel_79->name = "kernel_79"; + kernel_79->is_const = 1; + kernel_79->dtype = CSINN_DTYPE_FLOAT32; + kernel_79->layout = CSINN_LAYOUT_OIHW; + kernel_79->dim[0] = 24; + kernel_79->dim[1] = 256; + kernel_79->dim[2] = 1; + kernel_79->dim[3] = 1; + kernel_79->dim_count = 4; + kernel_79->qinfo = (struct csi_quant_info *)(params_base + 21596512); + kernel_79->quant_channel = 1; + struct csi_tensor *bias_79 = csi_alloc_tensor(sess); + bias_79->data = params_base + 21596536; + bias_79->name = "bias_79"; + bias_79->is_const = 1; + bias_79->dtype = CSINN_DTYPE_FLOAT32; + bias_79->layout = CSINN_LAYOUT_O; + bias_79->dim[0] = 24; + bias_79->dim_count = 1; + bias_79->qinfo = (struct csi_quant_info *)(params_base + 21596632); + bias_79->quant_channel = 1; + struct conv2d_params *params_79 = csi_alloc_params(sizeof(struct conv2d_params), sess); + params_79->group = 1; + params_79->stride_height = 1; + params_79->stride_width = 1; + params_79->dilation_height = 1; + params_79->dilation_width = 1; + params_79->conv_extra.kernel_tm = NULL; + params_79->conv_extra.conv_mode = CSINN_DIRECT; + params_79->pad_top = 0; + params_79->pad_left = 0; + params_79->pad_down = 0; + params_79->pad_right = 0; + params_79->base.name = "params_79"; + csi_conv2d_init(output_78, output_79, kernel_79, bias_79, params_79); + int32_t *permute_80 = malloc(4 * 4); + permute_80[0] = 0; + permute_80[1] = 2; + permute_80[2] = 3; + permute_80[3] = 1; + struct csi_tensor *output_80 = csi_alloc_tensor(sess); + output_80->name = "output_80"; + output_80->dtype = CSINN_DTYPE_FLOAT32; + output_80->layout = CSINN_LAYOUT_NCHW; + output_80->dim[0] = 1; + output_80->dim[1] = 2; + output_80->dim[2] = 2; + output_80->dim[3] = 24; + output_80->dim_count = 4; + output_80->qinfo = (struct csi_quant_info *)(params_base + 21596656); + output_80->quant_channel = 1; + struct transpose_params *params_80 = csi_alloc_params(sizeof(struct transpose_params), sess); + params_80->permute = permute_80; + params_80->permute_num = 4; + params_80->base.name = "params_80"; + csi_transpose_init(output_79, output_80, params_80); + struct csi_tensor *output_81 = csi_alloc_tensor(sess); + output_81->name = "output_81"; + output_81->dtype = CSINN_DTYPE_FLOAT32; + output_81->layout = CSINN_LAYOUT_NC; + output_81->dim[0] = 1; + output_81->dim[1] = 96; + output_81->dim_count = 2; + output_81->qinfo = (struct csi_quant_info *)(params_base + 21596680); + output_81->quant_channel = 1; + struct flatten_params *params_81 = csi_alloc_params(sizeof(struct flatten_params), sess); + params_81->base.name = "params_81"; + csi_flatten_init(output_80, output_81, params_81); + struct csi_tensor *output_82 = csi_alloc_tensor(sess); + output_82->name = "output_82"; + output_82->dtype = CSINN_DTYPE_FLOAT32; + output_82->layout = CSINN_LAYOUT_NCHW; + output_82->dim[0] = 1; + output_82->dim[1] = 64; + output_82->dim[2] = 2; + output_82->dim[3] = 2; + output_82->dim_count = 4; + output_82->qinfo = (struct csi_quant_info *)(params_base + 21596704); + output_82->quant_channel = 1; + struct csi_tensor *kernel_82 = csi_alloc_tensor(sess); + kernel_82->data = params_base + 21596728; + kernel_82->name = "kernel_82"; + kernel_82->is_const = 1; + kernel_82->dtype = CSINN_DTYPE_FLOAT32; + kernel_82->layout = CSINN_LAYOUT_OIHW; + kernel_82->dim[0] = 64; + kernel_82->dim[1] = 256; + kernel_82->dim[2] = 1; + kernel_82->dim[3] = 1; + kernel_82->dim_count = 4; + kernel_82->qinfo = (struct csi_quant_info *)(params_base + 21662264); + kernel_82->quant_channel = 1; + struct csi_tensor *bias_82 = csi_alloc_tensor(sess); + bias_82->data = params_base + 21662288; + bias_82->name = "bias_82"; + bias_82->is_const = 1; + bias_82->dtype = CSINN_DTYPE_FLOAT32; + bias_82->layout = CSINN_LAYOUT_O; + bias_82->dim[0] = 64; + bias_82->dim_count = 1; + bias_82->qinfo = (struct csi_quant_info *)(params_base + 21662544); + bias_82->quant_channel = 1; + struct conv2d_params *params_82 = csi_alloc_params(sizeof(struct conv2d_params), sess); + params_82->group = 1; + params_82->stride_height = 1; + params_82->stride_width = 1; + params_82->dilation_height = 1; + params_82->dilation_width = 1; + params_82->conv_extra.kernel_tm = NULL; + params_82->conv_extra.conv_mode = CSINN_DIRECT; + params_82->pad_top = 0; + params_82->pad_left = 0; + params_82->pad_down = 0; + params_82->pad_right = 0; + params_82->base.name = "params_82"; + csi_conv2d_init(output_78, output_82, kernel_82, bias_82, params_82); + struct csi_tensor *output_83 = csi_alloc_tensor(sess); + output_83->name = "output_83"; + output_83->dtype = CSINN_DTYPE_FLOAT32; + output_83->layout = CSINN_LAYOUT_NCHW; + output_83->dim[0] = 1; + output_83->dim[1] = 64; + output_83->dim[2] = 2; + output_83->dim[3] = 2; + output_83->dim_count = 4; + output_83->qinfo = (struct csi_quant_info *)(params_base + 21662568); + output_83->quant_channel = 1; + struct relu_params *params_83 = csi_alloc_params(sizeof(struct relu_params), sess); + params_83->base.name = "params_83"; + csi_relu_init(output_82, output_83, params_83); + struct csi_tensor *output_84 = csi_alloc_tensor(sess); + output_84->name = "output_84"; + output_84->dtype = CSINN_DTYPE_FLOAT32; + output_84->layout = CSINN_LAYOUT_NCHW; + output_84->dim[0] = 1; + output_84->dim[1] = 128; + output_84->dim[2] = 1; + output_84->dim[3] = 1; + output_84->dim_count = 4; + output_84->qinfo = (struct csi_quant_info *)(params_base + 21662592); + output_84->quant_channel = 1; + struct csi_tensor *kernel_84 = csi_alloc_tensor(sess); + kernel_84->data = params_base + 21662616; + kernel_84->name = "kernel_84"; + kernel_84->is_const = 1; + kernel_84->dtype = CSINN_DTYPE_FLOAT32; + kernel_84->layout = CSINN_LAYOUT_OIHW; + kernel_84->dim[0] = 128; + kernel_84->dim[1] = 64; + kernel_84->dim[2] = 3; + kernel_84->dim[3] = 3; + kernel_84->dim_count = 4; + kernel_84->qinfo = (struct csi_quant_info *)(params_base + 21957528); + kernel_84->quant_channel = 1; + struct csi_tensor *bias_84 = csi_alloc_tensor(sess); + bias_84->data = params_base + 21957552; + bias_84->name = "bias_84"; + bias_84->is_const = 1; + bias_84->dtype = CSINN_DTYPE_FLOAT32; + bias_84->layout = CSINN_LAYOUT_O; + bias_84->dim[0] = 128; + bias_84->dim_count = 1; + bias_84->qinfo = (struct csi_quant_info *)(params_base + 21958064); + bias_84->quant_channel = 1; + struct conv2d_params *params_84 = csi_alloc_params(sizeof(struct conv2d_params), sess); + params_84->group = 1; + params_84->stride_height = 2; + params_84->stride_width = 2; + params_84->dilation_height = 1; + params_84->dilation_width = 1; + params_84->conv_extra.kernel_tm = NULL; + params_84->conv_extra.conv_mode = CSINN_DIRECT; + params_84->pad_top = 1; + params_84->pad_left = 1; + params_84->pad_down = 1; + params_84->pad_right = 1; + params_84->base.name = "params_84"; + csi_conv2d_init(output_83, output_84, kernel_84, bias_84, params_84); + struct csi_tensor *output_85 = csi_alloc_tensor(sess); + output_85->name = "output_85"; + output_85->dtype = CSINN_DTYPE_FLOAT32; + output_85->layout = CSINN_LAYOUT_NCHW; + output_85->dim[0] = 1; + output_85->dim[1] = 128; + output_85->dim[2] = 1; + output_85->dim[3] = 1; + output_85->dim_count = 4; + output_85->qinfo = (struct csi_quant_info *)(params_base + 21958088); + output_85->quant_channel = 1; + struct relu_params *params_85 = csi_alloc_params(sizeof(struct relu_params), sess); + params_85->base.name = "params_85"; + csi_relu_init(output_84, output_85, params_85); + struct csi_tensor *output_86 = csi_alloc_tensor(sess); + output_86->name = "output_86"; + output_86->dtype = CSINN_DTYPE_FLOAT32; + output_86->layout = CSINN_LAYOUT_NCHW; + output_86->dim[0] = 1; + output_86->dim[1] = 24; + output_86->dim[2] = 1; + output_86->dim[3] = 1; + output_86->dim_count = 4; + output_86->qinfo = (struct csi_quant_info *)(params_base + 21958112); + output_86->quant_channel = 1; + struct csi_tensor *kernel_86 = csi_alloc_tensor(sess); + kernel_86->data = params_base + 21958136; + kernel_86->name = "kernel_86"; + kernel_86->is_const = 1; + kernel_86->dtype = CSINN_DTYPE_FLOAT32; + kernel_86->layout = CSINN_LAYOUT_OIHW; + kernel_86->dim[0] = 24; + kernel_86->dim[1] = 128; + kernel_86->dim[2] = 1; + kernel_86->dim[3] = 1; + kernel_86->dim_count = 4; + kernel_86->qinfo = (struct csi_quant_info *)(params_base + 21970424); + kernel_86->quant_channel = 1; + struct csi_tensor *bias_86 = csi_alloc_tensor(sess); + bias_86->data = params_base + 21970448; + bias_86->name = "bias_86"; + bias_86->is_const = 1; + bias_86->dtype = CSINN_DTYPE_FLOAT32; + bias_86->layout = CSINN_LAYOUT_O; + bias_86->dim[0] = 24; + bias_86->dim_count = 1; + bias_86->qinfo = (struct csi_quant_info *)(params_base + 21970544); + bias_86->quant_channel = 1; + struct conv2d_params *params_86 = csi_alloc_params(sizeof(struct conv2d_params), sess); + params_86->group = 1; + params_86->stride_height = 1; + params_86->stride_width = 1; + params_86->dilation_height = 1; + params_86->dilation_width = 1; + params_86->conv_extra.kernel_tm = NULL; + params_86->conv_extra.conv_mode = CSINN_DIRECT; + params_86->pad_top = 0; + params_86->pad_left = 0; + params_86->pad_down = 0; + params_86->pad_right = 0; + params_86->base.name = "params_86"; + csi_conv2d_init(output_85, output_86, kernel_86, bias_86, params_86); + int32_t *permute_87 = malloc(4 * 4); + permute_87[0] = 0; + permute_87[1] = 2; + permute_87[2] = 3; + permute_87[3] = 1; + struct csi_tensor *output_87 = csi_alloc_tensor(sess); + output_87->name = "output_87"; + output_87->dtype = CSINN_DTYPE_FLOAT32; + output_87->layout = CSINN_LAYOUT_NCHW; + output_87->dim[0] = 1; + output_87->dim[1] = 1; + output_87->dim[2] = 1; + output_87->dim[3] = 24; + output_87->dim_count = 4; + output_87->qinfo = (struct csi_quant_info *)(params_base + 21970568); + output_87->quant_channel = 1; + struct transpose_params *params_87 = csi_alloc_params(sizeof(struct transpose_params), sess); + params_87->permute = permute_87; + params_87->permute_num = 4; + params_87->base.name = "params_87"; + csi_transpose_init(output_86, output_87, params_87); + struct csi_tensor *output_88 = csi_alloc_tensor(sess); + output_88->name = "output_88"; + output_88->dtype = CSINN_DTYPE_FLOAT32; + output_88->layout = CSINN_LAYOUT_NC; + output_88->dim[0] = 1; + output_88->dim[1] = 24; + output_88->dim_count = 2; + output_88->qinfo = (struct csi_quant_info *)(params_base + 21970592); + output_88->quant_channel = 1; + struct flatten_params *params_88 = csi_alloc_params(sizeof(struct flatten_params), sess); + params_88->base.name = "params_88"; + csi_flatten_init(output_87, output_88, params_88); + struct csi_tensor *input_89[6]; + struct csi_tensor *output_89 = csi_alloc_tensor(sess); + output_89->name = "output_89"; + output_89->dtype = CSINN_DTYPE_FLOAT32; + output_89->layout = CSINN_LAYOUT_NC; + output_89->dim[0] = 1; + output_89->dim[1] = 7668; + output_89->dim_count = 2; + output_89->qinfo = (struct csi_quant_info *)(params_base + 21970616); + output_89->quant_channel = 1; + struct concat_params *params_89 = csi_alloc_params(sizeof(struct concat_params), sess); + params_89->inputs_count = 6; + params_89->axis = 1; + params_89->base.name = "params_89"; + csi_concat_init(input_89, output_89, params_89); + struct csi_tensor *output_90 = csi_alloc_tensor(sess); + output_90->name = "output_90"; + output_90->dtype = CSINN_DTYPE_FLOAT32; + output_90->layout = CSINN_LAYOUT_NCHW; + output_90->dim[0] = 1; + output_90->dim[1] = 63; + output_90->dim[2] = 19; + output_90->dim[3] = 19; + output_90->dim_count = 4; + output_90->qinfo = (struct csi_quant_info *)(params_base + 21970640); + output_90->quant_channel = 1; + struct csi_tensor *kernel_90 = csi_alloc_tensor(sess); + kernel_90->data = params_base + 21970664; + kernel_90->name = "kernel_90"; + kernel_90->is_const = 1; + kernel_90->dtype = CSINN_DTYPE_FLOAT32; + kernel_90->layout = CSINN_LAYOUT_OIHW; + kernel_90->dim[0] = 63; + kernel_90->dim[1] = 512; + kernel_90->dim[2] = 1; + kernel_90->dim[3] = 1; + kernel_90->dim_count = 4; + kernel_90->qinfo = (struct csi_quant_info *)(params_base + 22099688); + kernel_90->quant_channel = 1; + struct csi_tensor *bias_90 = csi_alloc_tensor(sess); + bias_90->data = params_base + 22099712; + bias_90->name = "bias_90"; + bias_90->is_const = 1; + bias_90->dtype = CSINN_DTYPE_FLOAT32; + bias_90->layout = CSINN_LAYOUT_O; + bias_90->dim[0] = 63; + bias_90->dim_count = 1; + bias_90->qinfo = (struct csi_quant_info *)(params_base + 22099964); + bias_90->quant_channel = 1; + struct conv2d_params *params_90 = csi_alloc_params(sizeof(struct conv2d_params), sess); + params_90->group = 1; + params_90->stride_height = 1; + params_90->stride_width = 1; + params_90->dilation_height = 1; + params_90->dilation_width = 1; + params_90->conv_extra.kernel_tm = NULL; + params_90->conv_extra.conv_mode = CSINN_DIRECT; + params_90->pad_top = 0; + params_90->pad_left = 0; + params_90->pad_down = 0; + params_90->pad_right = 0; + params_90->base.name = "params_90"; + csi_conv2d_init(output_46, output_90, kernel_90, bias_90, params_90); + int32_t *permute_91 = malloc(4 * 4); + permute_91[0] = 0; + permute_91[1] = 2; + permute_91[2] = 3; + permute_91[3] = 1; + struct csi_tensor *output_91 = csi_alloc_tensor(sess); + output_91->name = "output_91"; + output_91->dtype = CSINN_DTYPE_FLOAT32; + output_91->layout = CSINN_LAYOUT_NCHW; + output_91->dim[0] = 1; + output_91->dim[1] = 19; + output_91->dim[2] = 19; + output_91->dim[3] = 63; + output_91->dim_count = 4; + output_91->qinfo = (struct csi_quant_info *)(params_base + 22099988); + output_91->quant_channel = 1; + struct transpose_params *params_91 = csi_alloc_params(sizeof(struct transpose_params), sess); + params_91->permute = permute_91; + params_91->permute_num = 4; + params_91->base.name = "params_91"; + csi_transpose_init(output_90, output_91, params_91); + struct csi_tensor *output_92 = csi_alloc_tensor(sess); + output_92->name = "output_92"; + output_92->dtype = CSINN_DTYPE_FLOAT32; + output_92->layout = CSINN_LAYOUT_NC; + output_92->dim[0] = 1; + output_92->dim[1] = 22743; + output_92->dim_count = 2; + output_92->qinfo = (struct csi_quant_info *)(params_base + 22100012); + output_92->quant_channel = 1; + struct flatten_params *params_92 = csi_alloc_params(sizeof(struct flatten_params), sess); + params_92->base.name = "params_92"; + csi_flatten_init(output_91, output_92, params_92); + struct csi_tensor *output_93 = csi_alloc_tensor(sess); + output_93->name = "output_93"; + output_93->dtype = CSINN_DTYPE_FLOAT32; + output_93->layout = CSINN_LAYOUT_NCHW; + output_93->dim[0] = 1; + output_93->dim[1] = 126; + output_93->dim[2] = 10; + output_93->dim[3] = 10; + output_93->dim_count = 4; + output_93->qinfo = (struct csi_quant_info *)(params_base + 22100036); + output_93->quant_channel = 1; + struct csi_tensor *kernel_93 = csi_alloc_tensor(sess); + kernel_93->data = params_base + 22100060; + kernel_93->name = "kernel_93"; + kernel_93->is_const = 1; + kernel_93->dtype = CSINN_DTYPE_FLOAT32; + kernel_93->layout = CSINN_LAYOUT_OIHW; + kernel_93->dim[0] = 126; + kernel_93->dim[1] = 1024; + kernel_93->dim[2] = 1; + kernel_93->dim[3] = 1; + kernel_93->dim_count = 4; + kernel_93->qinfo = (struct csi_quant_info *)(params_base + 22616156); + kernel_93->quant_channel = 1; + struct csi_tensor *bias_93 = csi_alloc_tensor(sess); + bias_93->data = params_base + 22616180; + bias_93->name = "bias_93"; + bias_93->is_const = 1; + bias_93->dtype = CSINN_DTYPE_FLOAT32; + bias_93->layout = CSINN_LAYOUT_O; + bias_93->dim[0] = 126; + bias_93->dim_count = 1; + bias_93->qinfo = (struct csi_quant_info *)(params_base + 22616684); + bias_93->quant_channel = 1; + struct conv2d_params *params_93 = csi_alloc_params(sizeof(struct conv2d_params), sess); + params_93->group = 1; + params_93->stride_height = 1; + params_93->stride_width = 1; + params_93->dilation_height = 1; + params_93->dilation_width = 1; + params_93->conv_extra.kernel_tm = NULL; + params_93->conv_extra.conv_mode = CSINN_DIRECT; + params_93->pad_top = 0; + params_93->pad_left = 0; + params_93->pad_down = 0; + params_93->pad_right = 0; + params_93->base.name = "params_93"; + csi_conv2d_init(output_57, output_93, kernel_93, bias_93, params_93); + int32_t *permute_94 = malloc(4 * 4); + permute_94[0] = 0; + permute_94[1] = 2; + permute_94[2] = 3; + permute_94[3] = 1; + struct csi_tensor *output_94 = csi_alloc_tensor(sess); + output_94->name = "output_94"; + output_94->dtype = CSINN_DTYPE_FLOAT32; + output_94->layout = CSINN_LAYOUT_NCHW; + output_94->dim[0] = 1; + output_94->dim[1] = 10; + output_94->dim[2] = 10; + output_94->dim[3] = 126; + output_94->dim_count = 4; + output_94->qinfo = (struct csi_quant_info *)(params_base + 22616708); + output_94->quant_channel = 1; + struct transpose_params *params_94 = csi_alloc_params(sizeof(struct transpose_params), sess); + params_94->permute = permute_94; + params_94->permute_num = 4; + params_94->base.name = "params_94"; + csi_transpose_init(output_93, output_94, params_94); + struct csi_tensor *output_95 = csi_alloc_tensor(sess); + output_95->name = "output_95"; + output_95->dtype = CSINN_DTYPE_FLOAT32; + output_95->layout = CSINN_LAYOUT_NC; + output_95->dim[0] = 1; + output_95->dim[1] = 12600; + output_95->dim_count = 2; + output_95->qinfo = (struct csi_quant_info *)(params_base + 22616732); + output_95->quant_channel = 1; + struct flatten_params *params_95 = csi_alloc_params(sizeof(struct flatten_params), sess); + params_95->base.name = "params_95"; + csi_flatten_init(output_94, output_95, params_95); + struct csi_tensor *output_96 = csi_alloc_tensor(sess); + output_96->name = "output_96"; + output_96->dtype = CSINN_DTYPE_FLOAT32; + output_96->layout = CSINN_LAYOUT_NCHW; + output_96->dim[0] = 1; + output_96->dim[1] = 126; + output_96->dim[2] = 5; + output_96->dim[3] = 5; + output_96->dim_count = 4; + output_96->qinfo = (struct csi_quant_info *)(params_base + 22616756); + output_96->quant_channel = 1; + struct csi_tensor *kernel_96 = csi_alloc_tensor(sess); + kernel_96->data = params_base + 22616780; + kernel_96->name = "kernel_96"; + kernel_96->is_const = 1; + kernel_96->dtype = CSINN_DTYPE_FLOAT32; + kernel_96->layout = CSINN_LAYOUT_OIHW; + kernel_96->dim[0] = 126; + kernel_96->dim[1] = 512; + kernel_96->dim[2] = 1; + kernel_96->dim[3] = 1; + kernel_96->dim_count = 4; + kernel_96->qinfo = (struct csi_quant_info *)(params_base + 22874828); + kernel_96->quant_channel = 1; + struct csi_tensor *bias_96 = csi_alloc_tensor(sess); + bias_96->data = params_base + 22874852; + bias_96->name = "bias_96"; + bias_96->is_const = 1; + bias_96->dtype = CSINN_DTYPE_FLOAT32; + bias_96->layout = CSINN_LAYOUT_O; + bias_96->dim[0] = 126; + bias_96->dim_count = 1; + bias_96->qinfo = (struct csi_quant_info *)(params_base + 22875356); + bias_96->quant_channel = 1; + struct conv2d_params *params_96 = csi_alloc_params(sizeof(struct conv2d_params), sess); + params_96->group = 1; + params_96->stride_height = 1; + params_96->stride_width = 1; + params_96->dilation_height = 1; + params_96->dilation_width = 1; + params_96->conv_extra.kernel_tm = NULL; + params_96->conv_extra.conv_mode = CSINN_DIRECT; + params_96->pad_top = 0; + params_96->pad_left = 0; + params_96->pad_down = 0; + params_96->pad_right = 0; + params_96->base.name = "params_96"; + csi_conv2d_init(output_64, output_96, kernel_96, bias_96, params_96); + int32_t *permute_97 = malloc(4 * 4); + permute_97[0] = 0; + permute_97[1] = 2; + permute_97[2] = 3; + permute_97[3] = 1; + struct csi_tensor *output_97 = csi_alloc_tensor(sess); + output_97->name = "output_97"; + output_97->dtype = CSINN_DTYPE_FLOAT32; + output_97->layout = CSINN_LAYOUT_NCHW; + output_97->dim[0] = 1; + output_97->dim[1] = 5; + output_97->dim[2] = 5; + output_97->dim[3] = 126; + output_97->dim_count = 4; + output_97->qinfo = (struct csi_quant_info *)(params_base + 22875380); + output_97->quant_channel = 1; + struct transpose_params *params_97 = csi_alloc_params(sizeof(struct transpose_params), sess); + params_97->permute = permute_97; + params_97->permute_num = 4; + params_97->base.name = "params_97"; + csi_transpose_init(output_96, output_97, params_97); + struct csi_tensor *output_98 = csi_alloc_tensor(sess); + output_98->name = "output_98"; + output_98->dtype = CSINN_DTYPE_FLOAT32; + output_98->layout = CSINN_LAYOUT_NC; + output_98->dim[0] = 1; + output_98->dim[1] = 3150; + output_98->dim_count = 2; + output_98->qinfo = (struct csi_quant_info *)(params_base + 22875404); + output_98->quant_channel = 1; + struct flatten_params *params_98 = csi_alloc_params(sizeof(struct flatten_params), sess); + params_98->base.name = "params_98"; + csi_flatten_init(output_97, output_98, params_98); + struct csi_tensor *output_99 = csi_alloc_tensor(sess); + output_99->name = "output_99"; + output_99->dtype = CSINN_DTYPE_FLOAT32; + output_99->layout = CSINN_LAYOUT_NCHW; + output_99->dim[0] = 1; + output_99->dim[1] = 126; + output_99->dim[2] = 3; + output_99->dim[3] = 3; + output_99->dim_count = 4; + output_99->qinfo = (struct csi_quant_info *)(params_base + 22875428); + output_99->quant_channel = 1; + struct csi_tensor *kernel_99 = csi_alloc_tensor(sess); + kernel_99->data = params_base + 22875452; + kernel_99->name = "kernel_99"; + kernel_99->is_const = 1; + kernel_99->dtype = CSINN_DTYPE_FLOAT32; + kernel_99->layout = CSINN_LAYOUT_OIHW; + kernel_99->dim[0] = 126; + kernel_99->dim[1] = 256; + kernel_99->dim[2] = 1; + kernel_99->dim[3] = 1; + kernel_99->dim_count = 4; + kernel_99->qinfo = (struct csi_quant_info *)(params_base + 23004476); + kernel_99->quant_channel = 1; + struct csi_tensor *bias_99 = csi_alloc_tensor(sess); + bias_99->data = params_base + 23004500; + bias_99->name = "bias_99"; + bias_99->is_const = 1; + bias_99->dtype = CSINN_DTYPE_FLOAT32; + bias_99->layout = CSINN_LAYOUT_O; + bias_99->dim[0] = 126; + bias_99->dim_count = 1; + bias_99->qinfo = (struct csi_quant_info *)(params_base + 23005004); + bias_99->quant_channel = 1; + struct conv2d_params *params_99 = csi_alloc_params(sizeof(struct conv2d_params), sess); + params_99->group = 1; + params_99->stride_height = 1; + params_99->stride_width = 1; + params_99->dilation_height = 1; + params_99->dilation_width = 1; + params_99->conv_extra.kernel_tm = NULL; + params_99->conv_extra.conv_mode = CSINN_DIRECT; + params_99->pad_top = 0; + params_99->pad_left = 0; + params_99->pad_down = 0; + params_99->pad_right = 0; + params_99->base.name = "params_99"; + csi_conv2d_init(output_71, output_99, kernel_99, bias_99, params_99); + int32_t *permute_100 = malloc(4 * 4); + permute_100[0] = 0; + permute_100[1] = 2; + permute_100[2] = 3; + permute_100[3] = 1; + struct csi_tensor *output_100 = csi_alloc_tensor(sess); + output_100->name = "output_100"; + output_100->dtype = CSINN_DTYPE_FLOAT32; + output_100->layout = CSINN_LAYOUT_NCHW; + output_100->dim[0] = 1; + output_100->dim[1] = 3; + output_100->dim[2] = 3; + output_100->dim[3] = 126; + output_100->dim_count = 4; + output_100->qinfo = (struct csi_quant_info *)(params_base + 23005028); + output_100->quant_channel = 1; + struct transpose_params *params_100 = csi_alloc_params(sizeof(struct transpose_params), sess); + params_100->permute = permute_100; + params_100->permute_num = 4; + params_100->base.name = "params_100"; + csi_transpose_init(output_99, output_100, params_100); + struct csi_tensor *output_101 = csi_alloc_tensor(sess); + output_101->name = "output_101"; + output_101->dtype = CSINN_DTYPE_FLOAT32; + output_101->layout = CSINN_LAYOUT_NC; + output_101->dim[0] = 1; + output_101->dim[1] = 1134; + output_101->dim_count = 2; + output_101->qinfo = (struct csi_quant_info *)(params_base + 23005052); + output_101->quant_channel = 1; + struct flatten_params *params_101 = csi_alloc_params(sizeof(struct flatten_params), sess); + params_101->base.name = "params_101"; + csi_flatten_init(output_100, output_101, params_101); + struct csi_tensor *output_102 = csi_alloc_tensor(sess); + output_102->name = "output_102"; + output_102->dtype = CSINN_DTYPE_FLOAT32; + output_102->layout = CSINN_LAYOUT_NCHW; + output_102->dim[0] = 1; + output_102->dim[1] = 126; + output_102->dim[2] = 2; + output_102->dim[3] = 2; + output_102->dim_count = 4; + output_102->qinfo = (struct csi_quant_info *)(params_base + 23005076); + output_102->quant_channel = 1; + struct csi_tensor *kernel_102 = csi_alloc_tensor(sess); + kernel_102->data = params_base + 23005100; + kernel_102->name = "kernel_102"; + kernel_102->is_const = 1; + kernel_102->dtype = CSINN_DTYPE_FLOAT32; + kernel_102->layout = CSINN_LAYOUT_OIHW; + kernel_102->dim[0] = 126; + kernel_102->dim[1] = 256; + kernel_102->dim[2] = 1; + kernel_102->dim[3] = 1; + kernel_102->dim_count = 4; + kernel_102->qinfo = (struct csi_quant_info *)(params_base + 23134124); + kernel_102->quant_channel = 1; + struct csi_tensor *bias_102 = csi_alloc_tensor(sess); + bias_102->data = params_base + 23134148; + bias_102->name = "bias_102"; + bias_102->is_const = 1; + bias_102->dtype = CSINN_DTYPE_FLOAT32; + bias_102->layout = CSINN_LAYOUT_O; + bias_102->dim[0] = 126; + bias_102->dim_count = 1; + bias_102->qinfo = (struct csi_quant_info *)(params_base + 23134652); + bias_102->quant_channel = 1; + struct conv2d_params *params_102 = csi_alloc_params(sizeof(struct conv2d_params), sess); + params_102->group = 1; + params_102->stride_height = 1; + params_102->stride_width = 1; + params_102->dilation_height = 1; + params_102->dilation_width = 1; + params_102->conv_extra.kernel_tm = NULL; + params_102->conv_extra.conv_mode = CSINN_DIRECT; + params_102->pad_top = 0; + params_102->pad_left = 0; + params_102->pad_down = 0; + params_102->pad_right = 0; + params_102->base.name = "params_102"; + csi_conv2d_init(output_78, output_102, kernel_102, bias_102, params_102); + int32_t *permute_103 = malloc(4 * 4); + permute_103[0] = 0; + permute_103[1] = 2; + permute_103[2] = 3; + permute_103[3] = 1; + struct csi_tensor *output_103 = csi_alloc_tensor(sess); + output_103->name = "output_103"; + output_103->dtype = CSINN_DTYPE_FLOAT32; + output_103->layout = CSINN_LAYOUT_NCHW; + output_103->dim[0] = 1; + output_103->dim[1] = 2; + output_103->dim[2] = 2; + output_103->dim[3] = 126; + output_103->dim_count = 4; + output_103->qinfo = (struct csi_quant_info *)(params_base + 23134676); + output_103->quant_channel = 1; + struct transpose_params *params_103 = csi_alloc_params(sizeof(struct transpose_params), sess); + params_103->permute = permute_103; + params_103->permute_num = 4; + params_103->base.name = "params_103"; + csi_transpose_init(output_102, output_103, params_103); + struct csi_tensor *output_104 = csi_alloc_tensor(sess); + output_104->name = "output_104"; + output_104->dtype = CSINN_DTYPE_FLOAT32; + output_104->layout = CSINN_LAYOUT_NC; + output_104->dim[0] = 1; + output_104->dim[1] = 504; + output_104->dim_count = 2; + output_104->qinfo = (struct csi_quant_info *)(params_base + 23134700); + output_104->quant_channel = 1; + struct flatten_params *params_104 = csi_alloc_params(sizeof(struct flatten_params), sess); + params_104->base.name = "params_104"; + csi_flatten_init(output_103, output_104, params_104); + struct csi_tensor *output_105 = csi_alloc_tensor(sess); + output_105->name = "output_105"; + output_105->dtype = CSINN_DTYPE_FLOAT32; + output_105->layout = CSINN_LAYOUT_NCHW; + output_105->dim[0] = 1; + output_105->dim[1] = 126; + output_105->dim[2] = 1; + output_105->dim[3] = 1; + output_105->dim_count = 4; + output_105->qinfo = (struct csi_quant_info *)(params_base + 23134724); + output_105->quant_channel = 1; + struct csi_tensor *kernel_105 = csi_alloc_tensor(sess); + kernel_105->data = params_base + 23134748; + kernel_105->name = "kernel_105"; + kernel_105->is_const = 1; + kernel_105->dtype = CSINN_DTYPE_FLOAT32; + kernel_105->layout = CSINN_LAYOUT_OIHW; + kernel_105->dim[0] = 126; + kernel_105->dim[1] = 128; + kernel_105->dim[2] = 1; + kernel_105->dim[3] = 1; + kernel_105->dim_count = 4; + kernel_105->qinfo = (struct csi_quant_info *)(params_base + 23199260); + kernel_105->quant_channel = 1; + struct csi_tensor *bias_105 = csi_alloc_tensor(sess); + bias_105->data = params_base + 23199284; + bias_105->name = "bias_105"; + bias_105->is_const = 1; + bias_105->dtype = CSINN_DTYPE_FLOAT32; + bias_105->layout = CSINN_LAYOUT_O; + bias_105->dim[0] = 126; + bias_105->dim_count = 1; + bias_105->qinfo = (struct csi_quant_info *)(params_base + 23199788); + bias_105->quant_channel = 1; + struct conv2d_params *params_105 = csi_alloc_params(sizeof(struct conv2d_params), sess); + params_105->group = 1; + params_105->stride_height = 1; + params_105->stride_width = 1; + params_105->dilation_height = 1; + params_105->dilation_width = 1; + params_105->conv_extra.kernel_tm = NULL; + params_105->conv_extra.conv_mode = CSINN_DIRECT; + params_105->pad_top = 0; + params_105->pad_left = 0; + params_105->pad_down = 0; + params_105->pad_right = 0; + params_105->base.name = "params_105"; + csi_conv2d_init(output_85, output_105, kernel_105, bias_105, params_105); + int32_t *permute_106 = malloc(4 * 4); + permute_106[0] = 0; + permute_106[1] = 2; + permute_106[2] = 3; + permute_106[3] = 1; + struct csi_tensor *output_106 = csi_alloc_tensor(sess); + output_106->name = "output_106"; + output_106->dtype = CSINN_DTYPE_FLOAT32; + output_106->layout = CSINN_LAYOUT_NCHW; + output_106->dim[0] = 1; + output_106->dim[1] = 1; + output_106->dim[2] = 1; + output_106->dim[3] = 126; + output_106->dim_count = 4; + output_106->qinfo = (struct csi_quant_info *)(params_base + 23199812); + output_106->quant_channel = 1; + struct transpose_params *params_106 = csi_alloc_params(sizeof(struct transpose_params), sess); + params_106->permute = permute_106; + params_106->permute_num = 4; + params_106->base.name = "params_106"; + csi_transpose_init(output_105, output_106, params_106); + struct csi_tensor *output_107 = csi_alloc_tensor(sess); + output_107->name = "output_107"; + output_107->dtype = CSINN_DTYPE_FLOAT32; + output_107->layout = CSINN_LAYOUT_NC; + output_107->dim[0] = 1; + output_107->dim[1] = 126; + output_107->dim_count = 2; + output_107->qinfo = (struct csi_quant_info *)(params_base + 23199836); + output_107->quant_channel = 1; + struct flatten_params *params_107 = csi_alloc_params(sizeof(struct flatten_params), sess); + params_107->base.name = "params_107"; + csi_flatten_init(output_106, output_107, params_107); + struct csi_tensor *input_108[6]; + struct csi_tensor *output_108 = csi_alloc_tensor(sess); + output_108->name = "output_108"; + output_108->dtype = CSINN_DTYPE_FLOAT32; + output_108->layout = CSINN_LAYOUT_NC; + output_108->dim[0] = 1; + output_108->dim[1] = 40257; + output_108->dim_count = 2; + output_108->qinfo = (struct csi_quant_info *)(params_base + 23199860); + output_108->quant_channel = 1; + struct concat_params *params_108 = csi_alloc_params(sizeof(struct concat_params), sess); + params_108->inputs_count = 6; + params_108->axis = 1; + params_108->base.name = "params_108"; + csi_concat_init(input_108, output_108, params_108); + struct csi_tensor *output_109 = csi_alloc_tensor(sess); + output_109->name = "output_109"; + output_109->dtype = CSINN_DTYPE_FLOAT32; + output_109->layout = CSINN_LAYOUT_NCW; + output_109->dim[0] = 1; + output_109->dim[1] = 1917; + output_109->dim[2] = 21; + output_109->dim_count = 3; + output_109->qinfo = (struct csi_quant_info *)(params_base + 23199884); + output_109->quant_channel = 1; + int32_t *shape_109 = malloc(3 * 4); + shape_109[0] = 1; + shape_109[1] = 1917; + shape_109[2] = 21; + struct reshape_params *params_109 = csi_alloc_params(sizeof(struct reshape_params), sess); + params_109->shape = shape_109; + params_109->shape_num = 3; + params_109->base.name = "params_109"; + csi_reshape_init(output_108, output_109, params_109); + struct csi_tensor *output_110 = csi_alloc_tensor(sess); + output_110->name = "output_110"; + output_110->dtype = CSINN_DTYPE_FLOAT32; + output_110->layout = CSINN_LAYOUT_NCW; + output_110->dim[0] = 1; + output_110->dim[1] = 1917; + output_110->dim[2] = 21; + output_110->dim_count = 3; + output_110->qinfo = (struct csi_quant_info *)(params_base + 23199908); + output_110->quant_channel = 1; + struct softmax_params *params_110 = csi_alloc_params(sizeof(struct softmax_params), sess); + params_110->axis = 2; + params_110->base.name = "params_110"; + csi_softmax_init(output_109, output_110, params_110); + + csi_set_tensor_entry(input0_1, sess); + csi_set_input(0, input0_1, sess); + + csi_conv2d(input0_1, output_1, kernel_1, bias_1, params_1); + csi_relu(output_1, output_2, params_2); + csi_conv2d(output_2, output_3, kernel_3, bias_3, params_3); + csi_relu(output_3, output_4, params_4); + csi_conv2d(output_4, output_5, kernel_5, bias_5, params_5); + csi_relu(output_5, output_6, params_6); + csi_conv2d(output_6, output_7, kernel_7, bias_7, params_7); + csi_relu(output_7, output_8, params_8); + csi_conv2d(output_8, output_9, kernel_9, bias_9, params_9); + csi_relu(output_9, output_10, params_10); + csi_conv2d(output_10, output_11, kernel_11, bias_11, params_11); + csi_relu(output_11, output_12, params_12); + csi_conv2d(output_12, output_13, kernel_13, bias_13, params_13); + csi_relu(output_13, output_14, params_14); + csi_conv2d(output_14, output_15, kernel_15, bias_15, params_15); + csi_relu(output_15, output_16, params_16); + csi_conv2d(output_16, output_17, kernel_17, bias_17, params_17); + csi_relu(output_17, output_18, params_18); + csi_conv2d(output_18, output_19, kernel_19, bias_19, params_19); + csi_relu(output_19, output_20, params_20); + csi_conv2d(output_20, output_21, kernel_21, bias_21, params_21); + csi_relu(output_21, output_22, params_22); + csi_conv2d(output_22, output_23, kernel_23, bias_23, params_23); + csi_relu(output_23, output_24, params_24); + csi_conv2d(output_24, output_25, kernel_25, bias_25, params_25); + csi_relu(output_25, output_26, params_26); + csi_conv2d(output_26, output_27, kernel_27, bias_27, params_27); + csi_relu(output_27, output_28, params_28); + csi_conv2d(output_28, output_29, kernel_29, bias_29, params_29); + csi_relu(output_29, output_30, params_30); + csi_conv2d(output_30, output_31, kernel_31, bias_31, params_31); + csi_relu(output_31, output_32, params_32); + csi_conv2d(output_32, output_33, kernel_33, bias_33, params_33); + csi_relu(output_33, output_34, params_34); + csi_conv2d(output_34, output_35, kernel_35, bias_35, params_35); + csi_relu(output_35, output_36, params_36); + csi_conv2d(output_36, output_37, kernel_37, bias_37, params_37); + csi_relu(output_37, output_38, params_38); + csi_conv2d(output_38, output_39, kernel_39, bias_39, params_39); + csi_relu(output_39, output_40, params_40); + csi_conv2d(output_40, output_41, kernel_41, bias_41, params_41); + csi_relu(output_41, output_42, params_42); + csi_conv2d(output_42, output_43, kernel_43, bias_43, params_43); + csi_relu(output_43, output_44, params_44); + csi_conv2d(output_44, output_45, kernel_45, bias_45, params_45); + csi_relu(output_45, output_46, params_46); + csi_conv2d(output_46, output_47, kernel_47, bias_47, params_47); + csi_transpose(output_47, output_48, params_48); + csi_flatten(output_48, output_49, params_49); + csi_conv2d(output_46, output_50, kernel_50, bias_50, params_50); + csi_relu(output_50, output_51, params_51); + csi_conv2d(output_51, output_52, kernel_52, bias_52, params_52); + csi_relu(output_52, output_53, params_53); + csi_conv2d(output_53, output_54, kernel_54, bias_54, params_54); + csi_relu(output_54, output_55, params_55); + csi_conv2d(output_55, output_56, kernel_56, bias_56, params_56); + csi_relu(output_56, output_57, params_57); + csi_conv2d(output_57, output_58, kernel_58, bias_58, params_58); + csi_transpose(output_58, output_59, params_59); + csi_flatten(output_59, output_60, params_60); + csi_conv2d(output_57, output_61, kernel_61, bias_61, params_61); + csi_relu(output_61, output_62, params_62); + csi_conv2d(output_62, output_63, kernel_63, bias_63, params_63); + csi_relu(output_63, output_64, params_64); + csi_conv2d(output_64, output_65, kernel_65, bias_65, params_65); + csi_transpose(output_65, output_66, params_66); + csi_flatten(output_66, output_67, params_67); + csi_conv2d(output_64, output_68, kernel_68, bias_68, params_68); + csi_relu(output_68, output_69, params_69); + csi_conv2d(output_69, output_70, kernel_70, bias_70, params_70); + csi_relu(output_70, output_71, params_71); + csi_conv2d(output_71, output_72, kernel_72, bias_72, params_72); + csi_transpose(output_72, output_73, params_73); + csi_flatten(output_73, output_74, params_74); + csi_conv2d(output_71, output_75, kernel_75, bias_75, params_75); + csi_relu(output_75, output_76, params_76); + csi_conv2d(output_76, output_77, kernel_77, bias_77, params_77); + csi_relu(output_77, output_78, params_78); + csi_conv2d(output_78, output_79, kernel_79, bias_79, params_79); + csi_transpose(output_79, output_80, params_80); + csi_flatten(output_80, output_81, params_81); + csi_conv2d(output_78, output_82, kernel_82, bias_82, params_82); + csi_relu(output_82, output_83, params_83); + csi_conv2d(output_83, output_84, kernel_84, bias_84, params_84); + csi_relu(output_84, output_85, params_85); + csi_conv2d(output_85, output_86, kernel_86, bias_86, params_86); + csi_transpose(output_86, output_87, params_87); + csi_flatten(output_87, output_88, params_88); + input_89[0] = output_49; + input_89[1] = output_60; + input_89[2] = output_67; + input_89[3] = output_74; + input_89[4] = output_81; + input_89[5] = output_88; + csi_concat(input_89, output_89, params_89); + csi_conv2d(output_46, output_90, kernel_90, bias_90, params_90); + csi_transpose(output_90, output_91, params_91); + csi_flatten(output_91, output_92, params_92); + csi_conv2d(output_57, output_93, kernel_93, bias_93, params_93); + csi_transpose(output_93, output_94, params_94); + csi_flatten(output_94, output_95, params_95); + csi_conv2d(output_64, output_96, kernel_96, bias_96, params_96); + csi_transpose(output_96, output_97, params_97); + csi_flatten(output_97, output_98, params_98); + csi_conv2d(output_71, output_99, kernel_99, bias_99, params_99); + csi_transpose(output_99, output_100, params_100); + csi_flatten(output_100, output_101, params_101); + csi_conv2d(output_78, output_102, kernel_102, bias_102, params_102); + csi_transpose(output_102, output_103, params_103); + csi_flatten(output_103, output_104, params_104); + csi_conv2d(output_85, output_105, kernel_105, bias_105, params_105); + csi_transpose(output_105, output_106, params_106); + csi_flatten(output_106, output_107, params_107); + input_108[0] = output_92; + input_108[1] = output_95; + input_108[2] = output_98; + input_108[3] = output_101; + input_108[4] = output_104; + input_108[5] = output_107; + csi_concat(input_108, output_108, params_108); + csi_reshape(output_108, output_109, params_109); + csi_softmax(output_109, output_110, params_110); + csi_set_output(0, output_89, sess); + csi_set_output(1, output_110, sess); + const_output_0->name = "const_output_0"; + const_output_0->dtype = CSINN_DTYPE_FLOAT32; + const_output_0->is_const = 1; + csi_set_output(2, const_output_0, sess); + + csi_session_setup(sess); + return sess; +} +void csinn_run(void* data0, void *sess) { + struct csi_tensor input_tensor; + input_tensor.data = data0; + csi_update_input(0, &input_tensor, sess); + csi_session_run(sess); +} + +void *csinn_nbg(char *path) { + struct csi_session *sess = csi_alloc_session(); + sess->base_api = CSINN_LIGHT; + sess->base_dtype = CSINN_DTYPE_FLOAT32; + sess->debug_level = CSI_DEBUG_LEVEL_INFO; + csi_session_init(sess); + csi_set_input_number(1, sess); + csi_set_output_number(2, sess); + + struct csi_tensor *input0_1 = csi_alloc_tensor(sess); + input0_1->dim[0] = 1; + input0_1->dim[1] = 3; + input0_1->dim[2] = 300; + input0_1->dim[3] = 300; + input0_1->dim_count = 4; + input0_1->name = "input0_1"; + input0_1->qinfo->zero_point = 0; + input0_1->qinfo->scale = 0.015625; + input0_1->qinfo->min = -0.994500; + input0_1->qinfo->max = 0.994500; + input0_1->dtype = CSINN_DTYPE_FLOAT32; + input0_1->layout = CSINN_LAYOUT_NCHW; + + struct csi_tensor *output_110 = csi_alloc_tensor(sess); + output_110->dim[0] = 1; + output_110->dim[1] = 1917; + output_110->dim[2] = 21; + output_110->dim_count = 3; + output_110->name = "output_110"; + output_110->qinfo->zero_point = 0; + output_110->qinfo->scale = 0.015625; + output_110->qinfo->min = 0.000000; + output_110->qinfo->max = 1.000000; + output_110->dtype = CSINN_DTYPE_FLOAT32; + output_110->layout = CSINN_LAYOUT_NCW; + + struct csi_tensor *output_89 = csi_alloc_tensor(sess); + output_89->dim[0] = 1; + output_89->dim[1] = 7668; + output_89->dim_count = 2; + output_89->name = "output_89"; + output_89->qinfo->zero_point = 0; + output_89->qinfo->scale = 0.250000; + output_89->qinfo->min = -25.081497; + output_89->qinfo->max = 10.972174; + output_89->dtype = CSINN_DTYPE_FLOAT32; + output_89->layout = CSINN_LAYOUT_NC; + + csi_set_tensor_entry(output_89, sess); + csi_set_output(0, output_89, sess); + csi_set_tensor_entry(output_110, sess); + csi_set_output(1, output_110, sess); + csi_set_tensor_entry(input0_1, sess); + csi_set_input(0, input0_1, sess); + csi_load_binary_model(path, sess); + return sess; +} diff --git a/test/npu_test/npu_sink_test.c b/test/npu_test/npu_sink_test.c new file mode 100644 index 0000000..69444fe --- /dev/null +++ b/test/npu_test/npu_sink_test.c @@ -0,0 +1,254 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/* auto generate by HHB_VERSION "1.8.x" */ + +#include +#include +#include +#include +#include +#include +#include "io.h" +// #include "csi_ref.h" +#include "test_bench_utils.h" +#include "detect.h" +// #include "output_120_out0_nchw_1_2_7668_1.h" + +#define MIN(x, y) ((x) < (y) ? (x) : (y)) +#define FILE_LENGTH 1028 +#define SHAPE_LENGHT 128 + +void *csinn_(char *params); +void csinn_run(void *data0, void *td); +void *csinn_nbg(const char *nbg_file_name); + +int input_size[] = {1 * 3 * 300 * 300, }; +int output_size[] = {1 * 7668, 1 * 2 * 7668, 1 * 1917 * 21, }; +const char model_name[] = "network"; + +#define R_MEAN 127.5 +#define G_MEAN 127.5 +#define B_MEAN 127.5 +#define SCALE (1.0/127.5) + +float mean[] = {B_MEAN, G_MEAN, R_MEAN}; + +const char class_name[][FILE_LENGTH] = { + "background", "aeroplane", "bicycle", "bird", "boat", + "bottle", "bus", "car", "cat", "chair", "cow", "diningtable", + "dog", "horse", "motorbike", "person", "pottedplant", "sheep", + "sofa", "train", "tvmonitor" +}; + +// static void print_tensor_info(struct csi_tensor *t) { +// printf("\n=== tensor info ===\n"); +// printf("shape: "); +// for (int j = 0; j < t->dim_count; j++) { +// printf("%d ", t->dim[j]); +// } +// printf("\n"); +// if (t->dtype == CSINN_DTYPE_UINT8) { +// printf("scale: %f\n", t->qinfo->scale); +// printf("zero point: %d\n", t->qinfo->zero_point); +// } +// printf("data pointer: %p\n", t->data); +// } + + +/* + * Postprocess function + */ +// static void postprocess(void *sess, const char *filename_prefix) { +// int output_num, input_num; +// struct csi_tensor *input = csi_alloc_tensor(NULL); +// struct csi_tensor *output = csi_alloc_tensor(NULL); + +// input_num = csi_get_input_number(sess); +// for (int i = 0; i < input_num; i++) { +// input->data = NULL; +// csi_get_input(i, input, sess); +// //print_tensor_info(input); + +// struct csi_tensor *finput = csi_ref_tensor_transform_f32(input); +// char filename[FILE_LENGTH] = {0}; +// char shape[SHAPE_LENGHT] = {0}; +// shape2string(input->dim, input->dim_count, shape, SHAPE_LENGHT); +// snprintf(filename, FILE_LENGTH, "%s_input%u_%s.txt", filename_prefix, i, shape); +// int input_size = csi_tensor_size(input); +// //printf("input_size: %d\n", input_size); +// //save_data_to_file(filename, (float*)finput->data, input_size); +// } + +// float *location; +// float *confidence; + +// output_num = csi_get_output_number(sess); +// for (int i = 0; i < output_num; i++) { +// output->data = NULL; +// csi_get_output(i, output, sess); +// //print_tensor_info(output); + +// struct csi_tensor *foutput = csi_ref_tensor_transform_f32(output); +// //csi_show_top5(foutput, sess); +// char filename[FILE_LENGTH] = {0}; +// char shape[SHAPE_LENGHT] = {0}; +// shape2string(output->dim, output->dim_count, shape, SHAPE_LENGHT); +// snprintf(filename, FILE_LENGTH, "%s_output%u_%s.txt", filename_prefix, i, shape); +// int output_size = csi_tensor_size(foutput); +// //save_data_to_file(filename, (float*)foutput->data, output_size); + +// if (i == 0) location = (float *)foutput->data; +// if (i == 1) confidence = (float *)foutput->data; + +// //csi_ref_tensor_transform_free_f32(foutput); +// } + +// BBoxOut out[100]; +// BBox gbboxes[num_prior]; + +// int num = ssdforward(location, confidence, priorbox, gbboxes, out); + +// printf("%d\n", num); +// for (int i = 0; i < num; i++) { +// printf("%d, label=%s, score=%f, x1=%f, y1=%f, x2=%f, y2=%f\n", out[i].label, class_name[out[i].label], +// out[i].score, out[i].xmin, out[i].ymin, out[i].xmax, out[i].ymax); +// } +// } + +int is_looping = 1; + +int main(int argc, char **argv) { + char **data_path = NULL; + char *params_path = NULL; + int input_num = 1; + int output_num = 3; + int input_group_num = 1; + int i; + int index = 0; + + // if (argc < (2 + input_num)) { + // printf("Please set valide args: ./model.elf model.params " + // "[tensor1/image1 ...] [tensor2/image2 ...]\n"); + // return -1; + // } else { + // if (argc == 3 && get_file_type(argv[2]) == FILE_TXT) { + // data_path = read_string_from_file(argv[2], &input_group_num); + // input_group_num /= input_num; + // } else { + // data_path = argv + 2; + // input_group_num = (argc - 2) / input_num; + // } + // } + // void *sess; + // params_path = argv[1]; + // char *params = get_binary_from_file(params_path); + // if (params == NULL) { + // return -1; + // } + // char *suffix = params_path + (strlen(params_path) - 8); + // if (strcmp(suffix, ".mbs.bin") == 0) { + // // create binary graph + // sess = csinn_nbg(params_path); + // } else { + // // create general graph + // sess = csinn_(params); + // } + + uint8_t *input[input_num]; + float *finput[input_num]; + char filename_prefix[FILE_LENGTH] = {0}; + uint64_t start_time, end_time; + uint64_t _start_time, _end_time; + + const void *shmSrc = ShmPicSrcOpen("dspnpu"); + printf("npu_sink_test:start\n"); + // while loop to receive shm picture + while(is_looping) { + for (i = 0; i < input_group_num; i++) { + /* set input */ + for (int j = 0; j < input_num; j++) { + char filename[FILE_LENGTH] = {0}; + int in_size = input_size[0]; + // start_time = csi_get_timespec(); + //printf("npu_sink_test: wait frame%d\n", index); + ShmSrcGetPicture(shmSrc, &input[j]); + printf("npu_sink_test: get frame %d\n", index); + snprintf(filename, FILE_LENGTH, "%s_sink_data%u.txt", filename_prefix, i); + //save_uint8_to_file(filename, (uint8_t*)input[j], in_size); + + // // end_time = csi_get_timespec(); + // // printf("wait frame time: %.5fmsf\n", ((float)(end_time-start_time))/1000000); + + // // _start_time = csi_get_timespec(); + // finput[j] = (float *)malloc(in_size * sizeof(float)); + + // // pre-process with submean at each pixels + // for (int k = 0; k < in_size; k++) { + // finput[j][k] = ((float)input[j][k] - mean[k/(in_size/3)]) * SCALE; + // } + + // // _end_time = csi_get_timespec(); + // // printf("submean execution time: %.5fms\n", ((float)(_end_time-_start_time))/1000000); + + // _start_time = csi_get_timespec(); + // input[j] = csi_ref_f32_to_input_dtype(0, finput[j], sess); + // snprintf(filename, FILE_LENGTH, "%s_finput%u.txt", filename_prefix, i); + // //save_data_to_file(filename, (float*)finput[j], in_size); + + // snprintf(filename, FILE_LENGTH, "%s_input%u.txt", filename_prefix, i); + // //save_uint8_to_file(filename, (uint8_t*)input[j], in_size); + // _end_time = csi_get_timespec(); + // printf("csi_f32_to_int8 execution time: %.5fms\n", ((float)(_end_time-_start_time))/1000000); + // } + + // _start_time = csi_get_timespec(); + // csinn_run(input[0], sess); + // _end_time = csi_get_timespec(); + // printf("Run graph execution time: %.5fms, FPS=%.2f\n", ((float)(_end_time-_start_time))/1000000, + // 1000000000.0/((float)(_end_time-_start_time))); + + // snprintf(filename_prefix, FILE_LENGTH, "%s", basename(data_path[i * input_num])); + // _start_time = csi_get_timespec(); + // // postprocess(sess, filename_prefix); + // _end_time = csi_get_timespec(); + // printf("postProcess execution time: %.5fms\n", ((float)(_end_time-_start_time))/1000000); + + for (int j = 0; j < input_num; j++) { + // free(finput[j]); + // free(input[j]); + ShmSrcReleasePicture(shmSrc); + printf("npu_sink_test: release frame%d\n", index); + } + // printf("Run NPU frame inference time: %.5fms, FPS=%.2f\n", ((float)(_end_time-start_time))/1000000, + // 1000000000.0/((float)(_end_time-start_time))); + + } + index++; + } + } + + // free(params); + ShmPicSrcClose("/dspnpu", shmSrc); + // csi_session_deinit(sess); + // csi_free_session(sess); + + return 0; +} + diff --git a/test/npu_test/shm_common.h b/test/npu_test/shm_common.h new file mode 100644 index 0000000..6541510 --- /dev/null +++ b/test/npu_test/shm_common.h @@ -0,0 +1,56 @@ +#ifndef __SHM_COMMON_H__ +#define __SHM_COMMON_H__ +#include +#include +#include +#include +#include +#include +#include + +#define NUM_OF_BUFFERS 6 + +typedef struct PictureInfo { + unsigned int bus_address_rgb; + unsigned int pic_width; + unsigned int pic_height; +} PictureInfo; + +typedef struct Box { + float x1; + float y1; + float x2; + float y2; +} Box; + +typedef struct Landmark { + float x[5]; + float y[5]; +} Landmark; + +typedef struct FaceDetect { + float score; + Box box; + Landmark landmark; +} FaceDetect; + +typedef struct FaceInfo { + unsigned int bus_address_feature; + unsigned int face_cnt; +} FaceInfo; + +typedef struct ShmBuffer { + sem_t sem_src; /* ISP posts to inform NPU that a frame buffer is ready for inference */ + sem_t sem_sink; /* NPU posts to inform ISP that a frame buffer is released */ + PictureInfo pics[NUM_OF_BUFFERS]; + int exit; +} ShmBuffer; + +typedef struct ShmFeatureBuffer { + sem_t sem_src; /* NPU posts to inform G2D that a frame buffer is ready for drawing */ + sem_t sem_sink; /* ISP posts to inform NPU that a frame buffer is released */ + FaceInfo feature[NUM_OF_BUFFERS]; + int exit; +} ShmFeatureBuffer; + +#endif /* __SHM_COMMON_H__ */ diff --git a/test/npu_test/test_bench_utils.c b/test/npu_test/test_bench_utils.c new file mode 100644 index 0000000..2ac0255 --- /dev/null +++ b/test/npu_test/test_bench_utils.c @@ -0,0 +1,133 @@ + +#include "io.h" +#include "shm_common.h" +#include "test_bench_utils.h" + +struct ShmSrc { + int fd; + int fd_mem; + int src_idx; + int sink_idx; + uint8_t *virtual_address; + uint32_t size; + ShmBuffer *buffer; +}; + +const void* ShmPicSrcOpen(const char *name) { + struct ShmSrc* inst = calloc(1, sizeof(struct ShmSrc)); + uint32_t err = 0; + if (inst == NULL) return NULL; + inst->src_idx = 0; + inst->sink_idx = 0; + do { + inst->fd = shm_open(name, O_CREAT | O_EXCL | O_RDWR, + S_IRUSR | S_IWUSR); + if (inst->fd == -1) { + printf("ERROR: shm_open failed,%d\n",inst->fd); + err = NULL; + break; + } + if (ftruncate(inst->fd, sizeof(ShmBuffer)) == -1) { + printf("ERROR: failed to ftruncate shared memory\n"); + err = NULL; + break; + } + inst->buffer = mmap(NULL, sizeof(ShmBuffer), + PROT_READ | PROT_WRITE, + MAP_SHARED, inst->fd, 0); + if (inst->buffer == MAP_FAILED) { + printf("ERROR: failed to map shared memory\n"); + err = NULL; + break; + } + inst->buffer->exit = 0; + if (sem_init(&inst->buffer->sem_sink, 1, NUM_OF_BUFFERS) == -1) { + printf("ERROR: failed to initialize semaphore sem_sink\n"); + err = NULL; + break; + } + if (sem_init(&inst->buffer->sem_src, 1, 0) == -1) { + printf("ERROR: failed to initialize semaphore sem_src\n"); + err = NULL; + break; + } + inst->fd_mem = open("/dev/mem", O_RDWR | O_SYNC); + if (inst->fd_mem == -1) { + printf("ERROR: failed to open: %s\n", "/dev/mem"); + err = NULL; + break; + } + } while (0); + + if (err != 0) { + free((void*)inst); + inst = NULL; + } + return inst; +} + +void ShmSrcGetPicture(const void* inst, uint8_t **pRGBBuffer) { + struct ShmSrc* src = (struct ShmSrc*)inst; + if (src != NULL) { + PictureInfo *pic = NULL; + uint32_t size_rgb = 0; + printf("wait for sem\n"); + sem_wait(&src->buffer->sem_src); + pic = &src->buffer->pics[src->sink_idx]; + //printf("DEBUG: get one frame: %d, %dx%d, phyaddr = 0x%08x\n", + //src->npu_idx, pic->pic_width, pic->pic_height, pic->bus_address_rgb); + size_rgb = 3 * pic->pic_height * pic->pic_width; + src->size = size_rgb; + if (src->fd_mem != -1) { + src->virtual_address = (uint8_t *) mmap(0, size_rgb, PROT_READ | PROT_WRITE, + MAP_SHARED, src->fd_mem, pic->bus_address_rgb); + if (src->virtual_address == MAP_FAILED) { + printf("ERROR: Failed to mmap busAddress: 0x%08x\n", pic->bus_address_rgb); + } + } + printf("DEBUG: get one frame: %d, %dx%d, phyaddr = 0x%08x, viraddr = 0x%08x\n", + src->sink_idx, pic->pic_width, pic->pic_height, pic->bus_address_rgb, src->virtual_address); + *pRGBBuffer = src->virtual_address; + // dump one picture + while (0) { + static FILE *fp = NULL; + if (fp == NULL) { + fp = fopen("npudump.rgb", "wb"); + } + if (fp != NULL) { + fwrite(src->virtual_address, src->size, 1, fp); + } + } + } +} + +void ShmSrcReleasePicture(const void* inst) { + struct ShmSrc* src = (struct ShmSrc*)inst; + if (src != NULL) { + if (src->virtual_address != MAP_FAILED) { + munmap(src->virtual_address, src->size); + } + sem_post(&src->buffer->sem_sink); + printf("DEBUG: release one frame: %d\n", src->sink_idx); + src->sink_idx = (src->sink_idx + 1) % NUM_OF_BUFFERS; + } +} + +void ShmPicSrcClose(const char *name, const void* inst) { + struct ShmSrc* src = (struct ShmSrc*)inst; + if (src != NULL) { + if (src->fd != -1) { + src->buffer->exit = 1; + sem_post(&src->buffer->sem_sink); + printf("DEBUG: post exit signal\n"); + sem_wait(&src->buffer->sem_src); + printf("DEBUG: ISP exit\n"); + shm_unlink(name); + if (src->buffer != MAP_FAILED) { + munmap(src->buffer, sizeof(ShmBuffer)); + } + } + free((void*)inst); + } +} + diff --git a/test/npu_test/test_bench_utils.h b/test/npu_test/test_bench_utils.h new file mode 100644 index 0000000..a53c6ee --- /dev/null +++ b/test/npu_test/test_bench_utils.h @@ -0,0 +1,11 @@ +#ifndef TEST_BENCH_UTILS_H +#define TEST_BENCH_UTILS_H + +//#include "base_type.h" + +const void* ShmPicSrcOpen(const char *name); +void ShmSrcGetPicture(const void* inst, uint8_t **pRGBBuffer); +void ShmSrcReleasePicture(const void* inst); +void ShmPicSrcClose(const char *name, const void* inst); + +#endif // TEST_BENCH_UTILS_H diff --git a/test/test_utility/include/CppUTest/CommandLineArguments.h b/test/test_utility/include/CppUTest/CommandLineArguments.h new file mode 100644 index 0000000..f5661f0 --- /dev/null +++ b/test/test_utility/include/CppUTest/CommandLineArguments.h @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the 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 EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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 D_CommandLineArguments_H +#define D_CommandLineArguments_H + +#include "SimpleString.h" +#include "TestOutput.h" +#include "TestFilter.h" + +class TestPlugin; + +class CommandLineArguments +{ +public: + explicit CommandLineArguments(int ac, const char *const *av); + virtual ~CommandLineArguments(); + + bool parse(TestPlugin* plugin); + bool needHelp() const; + bool isVerbose() const; + bool isVeryVerbose() const; + bool isColor() const; + bool isListingTestGroupNames() const; + bool isListingTestGroupAndCaseNames() const; + bool isListingTestLocations() const; + bool isRunIgnored() const; + size_t getRepeatCount() const; + bool isShuffling() const; + bool isReversing() const; + bool isCrashingOnFail() const; + size_t getShuffleSeed() const; + const TestFilter* getGroupFilters() const; + const TestFilter* getNameFilters() const; + bool isJUnitOutput() const; + bool isEclipseOutput() const; + bool isTeamCityOutput() const; + bool runTestsInSeperateProcess() const; + const SimpleString& getPackageName() const; + const char* usage() const; + const char* help() const; + +private: + + enum OutputType + { + OUTPUT_ECLIPSE, OUTPUT_JUNIT, OUTPUT_TEAMCITY + }; + + int ac_; + const char *const *av_; + + bool needHelp_; + bool verbose_; + bool veryVerbose_; + bool color_; + bool runTestsAsSeperateProcess_; + bool listTestGroupNames_; + bool listTestGroupAndCaseNames_; + bool listTestLocations_; + bool runIgnored_; + bool reversing_; + bool crashOnFail_; + bool shuffling_; + bool shufflingPreSeeded_; + size_t repeat_; + size_t shuffleSeed_; + TestFilter* groupFilters_; + TestFilter* nameFilters_; + OutputType outputType_; + SimpleString packageName_; + + SimpleString getParameterField(int ac, const char *const *av, int& i, const SimpleString& parameterName); + void setRepeatCount(int ac, const char *const *av, int& index); + bool setShuffle(int ac, const char *const *av, int& index); + void addGroupFilter(int ac, const char *const *av, int& index); + bool addGroupDotNameFilter(int ac, const char *const *av, int& index); + void addStrictGroupFilter(int ac, const char *const *av, int& index); + void addExcludeGroupFilter(int ac, const char *const *av, int& index); + void addExcludeStrictGroupFilter(int ac, const char *const *av, int& index); + void addNameFilter(int ac, const char *const *av, int& index); + void addStrictNameFilter(int ac, const char *const *av, int& index); + void addExcludeNameFilter(int ac, const char *const *av, int& index); + void addExcludeStrictNameFilter(int ac, const char *const *av, int& index); + void addTestToRunBasedOnVerboseOutput(int ac, const char *const *av, int& index, const char* parameterName); + bool setOutputType(int ac, const char *const *av, int& index); + void setPackageName(int ac, const char *const *av, int& index); + + CommandLineArguments(const CommandLineArguments&); + CommandLineArguments& operator=(const CommandLineArguments&); + +}; + +#endif diff --git a/test/test_utility/include/CppUTest/CommandLineTestRunner.h b/test/test_utility/include/CppUTest/CommandLineTestRunner.h new file mode 100644 index 0000000..194cd4c --- /dev/null +++ b/test/test_utility/include/CppUTest/CommandLineTestRunner.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the 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 EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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 D_CommandLineTestRunner_H +#define D_CommandLineTestRunner_H + +#include "TestHarness.h" +#include "TestOutput.h" +#include "CommandLineArguments.h" +#include "TestFilter.h" + +class TestRegistry; + +#define DEF_PLUGIN_MEM_LEAK "MemoryLeakPlugin" +#define DEF_PLUGIN_SET_POINTER "SetPointerPlugin" + +class CommandLineTestRunner +{ +public: + static int RunAllTests(int ac, const char *const *av); + static int RunAllTests(int ac, char** av); + + CommandLineTestRunner(int ac, const char *const *av, TestRegistry* registry); + virtual ~CommandLineTestRunner(); + + int runAllTestsMain(); + +protected: + virtual TestOutput* createTeamCityOutput(); + virtual TestOutput* createJUnitOutput(const SimpleString& packageName); + virtual TestOutput* createConsoleOutput(); + virtual TestOutput* createCompositeOutput(TestOutput* outputOne, TestOutput* outputTwo); + + TestOutput* output_; +private: + CommandLineArguments* arguments_; + TestRegistry* registry_; + + bool parseArguments(TestPlugin*); + int runAllTests(); + void initializeTestRun(); +}; + +#endif diff --git a/test/test_utility/include/CppUTest/CppUTestConfig.h b/test/test_utility/include/CppUTest/CppUTestConfig.h new file mode 100644 index 0000000..7c7371f --- /dev/null +++ b/test/test_utility/include/CppUTest/CppUTestConfig.h @@ -0,0 +1,332 @@ +/* + * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the 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 EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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 CPPUTESTCONFIG_H_ +#define CPPUTESTCONFIG_H_ + +#ifndef CPPUTEST_USE_OWN_CONFIGURATION +#include "CppUTestGeneratedConfig.h" +#endif + +/* + * This file is added for some specific CppUTest configurations that earlier were spread out into multiple files. + * + * The goal of this file is to stay really small and not to include other things, but mainly to remove duplication + * from other files and resolve dependencies in #includes. + * + */ + +#ifdef __clang__ + #pragma clang diagnostic push + #if (__clang_major__ == 3 && __clang_minor__ >= 6) || __clang_major__ >= 4 + #pragma clang diagnostic ignored "-Wreserved-id-macro" + #endif +#endif + +/* + * Lib C dependencies that are currently still left: + * + * stdarg.h -> We use formatting functions and va_list requires to include stdarg.h in SimpleString + * stdlib.h -> The TestHarness_c.h includes this to try to avoid conflicts in its malloc #define. This dependency can + * easily be removed by not enabling the MALLOC overrides. + * + * Lib C++ dependencies are all under the CPPUTEST_USE_STD_CPP_LIB. + * The only dependency is to which has the bad_alloc struct + * + */ + +/* Do we use Standard C or not? When doing Kernel development, standard C usage is out. */ +#ifndef CPPUTEST_USE_STD_C_LIB + #ifdef CPPUTEST_STD_C_LIB_DISABLED + #define CPPUTEST_USE_STD_C_LIB 0 + #else + #define CPPUTEST_USE_STD_C_LIB 1 + #endif +#endif + + +/* Do we use Standard C++ or not? */ +#ifndef CPPUTEST_USE_STD_CPP_LIB + #ifdef CPPUTEST_STD_CPP_LIB_DISABLED + #define CPPUTEST_USE_STD_CPP_LIB 0 + #else + #define CPPUTEST_USE_STD_CPP_LIB 1 + #endif +#endif + +/* Is memory leak detection enabled? + * Controls the override of the global operator new/deleted and malloc/free. + * Without this, there will be no memory leak detection in C/C++. +*/ + +#ifndef CPPUTEST_USE_MEM_LEAK_DETECTION + #ifdef CPPUTEST_MEM_LEAK_DETECTION_DISABLED + #define CPPUTEST_USE_MEM_LEAK_DETECTION 0 + #else + #define CPPUTEST_USE_MEM_LEAK_DETECTION 1 + #endif +#endif + +/* Should be the only #include here. Standard C library wrappers */ +#include "StandardCLibrary.h" + +/* Create a _no_return_ macro, which is used to flag a function as not returning. + * Used for functions that always throws for instance. + * + * This is needed for compiling with clang, without breaking other compilers. + */ +#ifndef __has_attribute + #define __has_attribute(x) 0 +#endif + +#if __has_attribute(noreturn) + #define _no_return_ __attribute__((noreturn)) +#else + #define _no_return_ +#endif + +#if __has_attribute(format) + #define _check_format_(type, format_parameter, other_parameters) __attribute__ ((format (type, format_parameter, other_parameters))) +#else + #define _check_format_(type, format_parameter, other_parameters) /* type, format_parameter, other_parameters */ +#endif + +/* + * When we don't link Standard C++, then we won't throw exceptions as we assume the compiler might not support that! + */ + +#if CPPUTEST_USE_STD_CPP_LIB + #if defined(__cplusplus) && __cplusplus >= 201103L + #define UT_THROW(exception) + #define UT_NOTHROW noexcept + #else + #define UT_THROW(exception) throw (exception) + #define UT_NOTHROW throw() + #endif +#else + #define UT_THROW(exception) + #ifdef __clang__ + #define UT_NOTHROW throw() + #else + #define UT_NOTHROW + #endif +#endif + +/* + * Visual C++ doesn't define __cplusplus as C++11 yet (201103), however it doesn't want the throw(exception) either, but + * it does want throw(). + */ + +#ifdef _MSC_VER + #undef UT_THROW + #define UT_THROW(exception) +#endif + +#if defined(__cplusplus) && __cplusplus >= 201103L + #define DEFAULT_COPY_CONSTRUCTOR(classname) classname(const classname &) = default; +#else + #define DEFAULT_COPY_CONSTRUCTOR(classname) +#endif + +/* + * g++-4.7 with stdc++11 enabled On MacOSX! will have a different exception specifier for operator new (and thank you!) + * I assume they'll fix this in the future, but for now, we'll change that here. + * (This should perhaps also be done in the configure.ac) + */ + +#ifdef __GXX_EXPERIMENTAL_CXX0X__ +#ifdef __APPLE__ +#ifdef _GLIBCXX_THROW +#undef UT_THROW +#define UT_THROW(exception) _GLIBCXX_THROW(exception) +#endif +#endif +#endif + +/* + * Address sanitizer is a good thing... and it causes some conflicts with the CppUTest tests + * To check whether it is on or off, we create a CppUTest define here. +*/ +#if defined(__has_feature) +#if __has_feature(address_sanitizer) +#define CPPUTEST_SANITIZE_ADDRESS 1 +#endif +#endif + +#ifdef __SANITIZE_ADDRESS__ +#define CPPUTEST_SANITIZE_ADDRESS 1 +#endif + +#ifndef CPPUTEST_SANITIZE_ADDRESS +#define CPPUTEST_SANITIZE_ADDRESS 0 +#endif + +#if CPPUTEST_SANITIZE_ADDRESS +#define CPPUTEST_SANITIZE_ADDRESS 1 +#define CPPUTEST_DO_NOT_SANITIZE_ADDRESS __attribute__((no_sanitize_address)) + #if defined(__linux__) && defined(__clang__) + #if CPPUTEST_USE_MEM_LEAK_DETECTION + #warning Compiling with Address Sanitizer with clang on linux will cause duplicate symbols for operator new. Turning off memory leak detection. Compile with -DCPPUTEST_MEM_LEAK_DETECTION_DISABLED to get rid of this warning. + #undef CPPUTEST_USE_MEM_LEAK_DETECTION + #define CPPUTEST_USE_MEM_LEAK_DETECTION 0 + #endif + #endif +#else +#define CPPUTEST_SANITIZER_ADDRESS 0 +#define CPPUTEST_DO_NOT_SANITIZE_ADDRESS +#endif + +/* + * Handling of IEEE754 floating point exceptions via fenv.h + * Predominantly works on non-Visual C++ compilers and Visual C++ 2008 and newer + */ + +#if CPPUTEST_USE_STD_C_LIB && \ + (!defined(_MSC_VER) || (_MSC_VER >= 1800)) && \ + (!defined(__APPLE__)) && \ + (!defined(__ghs__) || !defined(__ColdFire__)) +#define CPPUTEST_HAVE_FENV +#if defined(__WATCOMC__) || defined(__ARMEL__) || defined(__m68k__) +#define CPPUTEST_FENV_IS_WORKING_PROPERLY 0 +#else +#define CPPUTEST_FENV_IS_WORKING_PROPERLY 1 +#endif +#endif + +/* + * Detection of different 64 bit environments + */ + +#if defined(__LP64__) || defined(_LP64) || (defined(__WORDSIZE) && (__WORDSIZE == 64 )) || defined(__x86_64) || defined(_WIN64) +#define CPPUTEST_64BIT +#if defined(_WIN64) +#define CPPUTEST_64BIT_32BIT_LONGS +#endif +#endif + +/* Handling of systems with a different byte-width (e.g. 16 bit). + * Since CHAR_BIT is defined in limits.h (ANSI C), use default of 8 when building without Std C library. + */ +#if CPPUTEST_USE_STD_C_LIB +#define CPPUTEST_CHAR_BIT CHAR_BIT +#else +#define CPPUTEST_CHAR_BIT 8 +#endif + +/* Handling of systems with a different int-width (e.g. 16 bit). + */ +#if CPPUTEST_USE_STD_C_LIB && (INT_MAX == 0x7fff) +#define CPPUTEST_16BIT_INTS +#endif + +/* + * Support for "long long" type. + * + * Not supported when CPPUTEST_LONG_LONG_DISABLED is set. + * Can be overridden by using CPPUTEST_USE_LONG_LONG + * + * CPPUTEST_HAVE_LONG_LONG_INT is set by configure + * LLONG_MAX is set in limits.h. This is a crude attempt to detect long long support when no configure is used + * + */ + +#if !defined(CPPUTEST_LONG_LONG_DISABLED) && !defined(CPPUTEST_USE_LONG_LONG) +#if defined(CPPUTEST_HAVE_LONG_LONG_INT) || defined(LLONG_MAX) +#define CPPUTEST_USE_LONG_LONG 1 +#endif +#endif + +#ifdef CPPUTEST_USE_LONG_LONG +typedef long long cpputest_longlong; +typedef unsigned long long cpputest_ulonglong; +#else +/* Define some placeholders to disable the overloaded methods. + * It's not required to have these match the size of the "real" type, but it's occasionally convenient. + */ + +#if defined(CPPUTEST_64BIT) && !defined(CPPUTEST_64BIT_32BIT_LONGS) +#define CPPUTEST_SIZE_OF_FAKE_LONG_LONG_TYPE 16 +#else +#define CPPUTEST_SIZE_OF_FAKE_LONG_LONG_TYPE 8 +#endif + +struct cpputest_longlong +{ +#if defined(__cplusplus) + cpputest_longlong() {} + cpputest_longlong(int) {} +#endif + char dummy[CPPUTEST_SIZE_OF_FAKE_LONG_LONG_TYPE]; +}; + +struct cpputest_ulonglong +{ +#if defined(__cplusplus) + cpputest_ulonglong() {} + cpputest_ulonglong(int) {} +#endif + char dummy[CPPUTEST_SIZE_OF_FAKE_LONG_LONG_TYPE]; +}; + +#if !defined(__cplusplus) +typedef struct cpputest_longlong cpputest_longlong; +typedef struct cpputest_ulonglong cpputest_ulonglong; +#endif + +#endif + +/* Visual C++ 10.0+ (2010+) supports the override keyword, but doesn't define the C++ version as C++11 */ +#if defined(__cplusplus) && ((__cplusplus >= 201103L) || (defined(_MSC_VER) && (_MSC_VER >= 1600))) +#if !defined(__ghs__) +#define CPPUTEST_COMPILER_FULLY_SUPPORTS_CXX11 +#define _override override +#else +/* GreenHills is not compatible with other compilers with regards to where + * it expects the override specifier to be on methods that return function + * pointers. Given this, it is easiest to not use the override specifier. + */ +#define _override +#endif +#define NULLPTR nullptr +#else +#define _override +#define NULLPTR NULL +#endif + +/* Visual C++ 11.0+ (2012+) supports the override keyword on destructors */ +#if defined(__cplusplus) && ((__cplusplus >= 201103L) || (defined(_MSC_VER) && (_MSC_VER >= 1700))) +#define _destructor_override override +#else +#define _destructor_override +#endif + +#ifdef __clang__ + #pragma clang diagnostic pop +#endif + + +#endif diff --git a/test/test_utility/include/CppUTest/CppUTestGeneratedConfig.h b/test/test_utility/include/CppUTest/CppUTestGeneratedConfig.h new file mode 100644 index 0000000..94e293f --- /dev/null +++ b/test/test_utility/include/CppUTest/CppUTestGeneratedConfig.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the 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 EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This file is confusing, sorry for that :) Please never edit this file. + * + * It serves 3 purposes + * + * 1) When you installed CppUTest on your system (make install), then this file should be overwritten by one that + * actually contains some configuration of your system. Mostly info such as availability of types, headers, etc. + * 2) When you build CppUTest using autotools, this file will be included and it will include the generated file. + * That should be the same file as will be installed if you run make install + * 3) When you use CppUTest on another platform that doesn't require configuration, then this file does nothing and + * should be harmless. + * + * If you have done make install and you still found this text, then please report a bug :) + * + */ + +#ifdef HAVE_CONFIG_H +#include "generated/CppUTestGeneratedConfig.h" +#endif + diff --git a/test/test_utility/include/CppUTest/JUnitTestOutput.h b/test/test_utility/include/CppUTest/JUnitTestOutput.h new file mode 100644 index 0000000..1c4a0b0 --- /dev/null +++ b/test/test_utility/include/CppUTest/JUnitTestOutput.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the 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 EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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 D_JUnitTestOutput_h +#define D_JUnitTestOutput_h + +#include "TestOutput.h" +#include "SimpleString.h" + +struct JUnitTestOutputImpl; +struct JUnitTestCaseResultNode; + +class JUnitTestOutput: public TestOutput +{ +public: + JUnitTestOutput(); + virtual ~JUnitTestOutput() _destructor_override; + + virtual void printTestsStarted() _override; + virtual void printTestsEnded(const TestResult& result) _override; + virtual void printCurrentTestStarted(const UtestShell& test) _override; + virtual void printCurrentTestEnded(const TestResult& res) _override; + virtual void printCurrentGroupStarted(const UtestShell& test) _override; + virtual void printCurrentGroupEnded(const TestResult& res) _override; + + virtual void printBuffer(const char*) _override; + virtual void print(const char*) _override; + virtual void print(long) _override; + virtual void print(size_t) _override; + virtual void printFailure(const TestFailure& failure) _override; + + virtual void flush() _override; + + virtual SimpleString createFileName(const SimpleString& group); + void setPackageName(const SimpleString &package); + +protected: + + JUnitTestOutputImpl* impl_; + void resetTestGroupResult(); + + virtual void openFileForWrite(const SimpleString& fileName); + virtual void writeTestGroupToFile(); + virtual void writeToFile(const SimpleString& buffer); + virtual void closeFile(); + + virtual void writeXmlHeader(); + virtual void writeTestSuiteSummary(); + virtual void writeProperties(); + virtual void writeTestCases(); + virtual SimpleString encodeXmlText(const SimpleString& textbody); + virtual SimpleString encodeFileName(const SimpleString& fileName); + virtual void writeFailure(JUnitTestCaseResultNode* node); + virtual void writeFileEnding(); +}; + +#endif diff --git a/test/test_utility/include/CppUTest/MemoryLeakDetector.h b/test/test_utility/include/CppUTest/MemoryLeakDetector.h new file mode 100644 index 0000000..4057ca8 --- /dev/null +++ b/test/test_utility/include/CppUTest/MemoryLeakDetector.h @@ -0,0 +1,270 @@ +/* + * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the 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 EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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 D_MemoryLeakDetector_h +#define D_MemoryLeakDetector_h + +enum MemLeakPeriod +{ + mem_leak_period_all, + mem_leak_period_disabled, + mem_leak_period_enabled, + mem_leak_period_checking +}; + +class TestMemoryAllocator; +class SimpleMutex; + +class MemoryLeakFailure +{ +public: + virtual ~MemoryLeakFailure() + { + } + + virtual void fail(char* fail_string)=0; +}; + +struct SimpleStringBuffer +{ + enum + { + SIMPLE_STRING_BUFFER_LEN = 4096 + }; + + SimpleStringBuffer(); + void clear(); + void add(const char* format, ...) _check_format_(printf, 2, 3); + void addMemoryDump(const void* memory, size_t memorySize); + + char* toString(); + + void setWriteLimit(size_t write_limit); + void resetWriteLimit(); + bool reachedItsCapacity(); +private: + char buffer_[SIMPLE_STRING_BUFFER_LEN]; + size_t positions_filled_; + size_t write_limit_; +}; + +struct MemoryLeakDetectorNode; + +class MemoryLeakOutputStringBuffer +{ +public: + MemoryLeakOutputStringBuffer(); + + void clear(); + + void startMemoryLeakReporting(); + void stopMemoryLeakReporting(); + + void reportMemoryLeak(MemoryLeakDetectorNode* leak); + + void reportDeallocateNonAllocatedMemoryFailure(const char* freeFile, size_t freeLine, TestMemoryAllocator* freeAllocator, MemoryLeakFailure* reporter); + void reportMemoryCorruptionFailure(MemoryLeakDetectorNode* node, const char* freeFile, size_t freeLineNumber, TestMemoryAllocator* freeAllocator, MemoryLeakFailure* reporter); + void reportAllocationDeallocationMismatchFailure(MemoryLeakDetectorNode* node, const char* freeFile, size_t freeLineNumber, TestMemoryAllocator* freeAllocator, MemoryLeakFailure* reporter); + char* toString(); + +private: + void addAllocationLocation(const char* allocationFile, size_t allocationLineNumber, size_t allocationSize, TestMemoryAllocator* allocator); + void addDeallocationLocation(const char* freeFile, size_t freeLineNumber, TestMemoryAllocator* allocator); + + void addMemoryLeakHeader(); + void addMemoryLeakFooter(size_t totalAmountOfLeaks); + void addWarningForUsingMalloc(); + void addNoMemoryLeaksMessage(); + void addErrorMessageForTooMuchLeaks(); + +private: + + size_t total_leaks_; + bool giveWarningOnUsingMalloc_; + + void reportFailure(const char* message, const char* allocFile, + size_t allocLine, size_t allocSize, + TestMemoryAllocator* allocAllocator, const char* freeFile, + size_t freeLine, TestMemoryAllocator* freeAllocator, MemoryLeakFailure* reporter); + + SimpleStringBuffer outputBuffer_; +}; + +struct MemoryLeakDetectorNode +{ + MemoryLeakDetectorNode() : + size_(0), number_(0), memory_(NULLPTR), file_(NULLPTR), line_(0), allocator_(NULLPTR), period_(mem_leak_period_enabled), allocation_stage_(0), next_(NULLPTR) + { + } + + void init(char* memory, unsigned number, size_t size, TestMemoryAllocator* allocator, MemLeakPeriod period, unsigned char allocation_stage, const char* file, size_t line); + + size_t size_; + unsigned number_; + char* memory_; + const char* file_; + size_t line_; + TestMemoryAllocator* allocator_; + MemLeakPeriod period_; + unsigned char allocation_stage_; + +private: + friend struct MemoryLeakDetectorList; + MemoryLeakDetectorNode* next_; +}; + +struct MemoryLeakDetectorList +{ + MemoryLeakDetectorList() : + head_(NULLPTR) + {} + + void addNewNode(MemoryLeakDetectorNode* node); + MemoryLeakDetectorNode* retrieveNode(char* memory); + MemoryLeakDetectorNode* removeNode(char* memory); + + MemoryLeakDetectorNode* getFirstLeak(MemLeakPeriod period); + MemoryLeakDetectorNode* getFirstLeakForAllocationStage(unsigned char allocation_stage); + + MemoryLeakDetectorNode* getNextLeak(MemoryLeakDetectorNode* node, MemLeakPeriod period); + MemoryLeakDetectorNode* getNextLeakForAllocationStage(MemoryLeakDetectorNode* node, unsigned char allocation_stage); + + MemoryLeakDetectorNode* getLeakFrom(MemoryLeakDetectorNode* node, MemLeakPeriod period); + MemoryLeakDetectorNode* getLeakForAllocationStageFrom(MemoryLeakDetectorNode* node, unsigned char allocation_stage); + + size_t getTotalLeaks(MemLeakPeriod period); + void clearAllAccounting(MemLeakPeriod period); + + bool isInPeriod(MemoryLeakDetectorNode* node, MemLeakPeriod period); + bool isInAllocationStage(MemoryLeakDetectorNode* node, unsigned char allocation_stage); + +private: + MemoryLeakDetectorNode* head_; +}; + +struct MemoryLeakDetectorTable +{ + void clearAllAccounting(MemLeakPeriod period); + + void addNewNode(MemoryLeakDetectorNode* node); + MemoryLeakDetectorNode* retrieveNode(char* memory); + MemoryLeakDetectorNode* removeNode(char* memory); + + size_t getTotalLeaks(MemLeakPeriod period); + + MemoryLeakDetectorNode* getFirstLeak(MemLeakPeriod period); + MemoryLeakDetectorNode* getFirstLeakForAllocationStage(unsigned char allocation_stage); + MemoryLeakDetectorNode* getNextLeak(MemoryLeakDetectorNode* leak, MemLeakPeriod period); + MemoryLeakDetectorNode* getNextLeakForAllocationStage(MemoryLeakDetectorNode* leak, unsigned char allocation_stage); + +private: + unsigned long hash(char* memory); + + enum + { + hash_prime = MEMORY_LEAK_HASH_TABLE_SIZE + }; + MemoryLeakDetectorList table_[hash_prime]; +}; + +class MemoryLeakDetector +{ +public: + MemoryLeakDetector(MemoryLeakFailure* reporter); + virtual ~MemoryLeakDetector(); + + void enable(); + void disable(); + + void disableAllocationTypeChecking(); + void enableAllocationTypeChecking(); + + void startChecking(); + void stopChecking(); + + unsigned char getCurrentAllocationStage() const; + void increaseAllocationStage(); + void decreaseAllocationStage(); + + const char* report(MemLeakPeriod period); + void markCheckingPeriodLeaksAsNonCheckingPeriod(); + size_t totalMemoryLeaks(MemLeakPeriod period); + void clearAllAccounting(MemLeakPeriod period); + + char* allocMemory(TestMemoryAllocator* allocator, size_t size, bool allocatNodesSeperately = false); + char* allocMemory(TestMemoryAllocator* allocator, size_t size, + const char* file, size_t line, bool allocatNodesSeperately = false); + void deallocMemory(TestMemoryAllocator* allocator, void* memory, bool allocatNodesSeperately = false); + void deallocMemory(TestMemoryAllocator* allocator, void* memory, const char* file, size_t line, bool allocatNodesSeperately = false); + void deallocAllMemoryInCurrentAllocationStage(); + char* reallocMemory(TestMemoryAllocator* allocator, char* memory, size_t size, const char* file, size_t line, bool allocatNodesSeperately = false); + + void invalidateMemory(char* memory); + void removeMemoryLeakInformationWithoutCheckingOrDeallocatingTheMemoryButDeallocatingTheAccountInformation(TestMemoryAllocator* allocator, void* memory, bool allocatNodesSeperately); + enum + { +#ifdef CPPUTEST_DISABLE_MEM_CORRUPTION_CHECK + memory_corruption_buffer_size = 0 +#else + memory_corruption_buffer_size = 3 +#endif + }; + + unsigned getCurrentAllocationNumber(); + + SimpleMutex* getMutex(void); +private: + MemoryLeakFailure* reporter_; + MemLeakPeriod current_period_; + MemoryLeakOutputStringBuffer outputBuffer_; + MemoryLeakDetectorTable memoryTable_; + bool doAllocationTypeChecking_; + unsigned allocationSequenceNumber_; + unsigned char current_allocation_stage_; + SimpleMutex* mutex_; + + char* allocateMemoryWithAccountingInformation(TestMemoryAllocator* allocator, size_t size, const char* file, size_t line, bool allocatNodesSeperately); + char* reallocateMemoryWithAccountingInformation(TestMemoryAllocator* allocator, char* memory, size_t size, const char* file, size_t line, bool allocatNodesSeperately); + MemoryLeakDetectorNode* createMemoryLeakAccountingInformation(TestMemoryAllocator* allocator, size_t size, char* memory, bool allocatNodesSeperately); + + + bool validMemoryCorruptionInformation(char* memory); + bool matchingAllocation(TestMemoryAllocator *alloc_allocator, TestMemoryAllocator *free_allocator); + + void storeLeakInformation(MemoryLeakDetectorNode * node, char *new_memory, size_t size, TestMemoryAllocator *allocator, const char *file, size_t line); + void ConstructMemoryLeakReport(MemLeakPeriod period); + + size_t sizeOfMemoryWithCorruptionInfo(size_t size); + MemoryLeakDetectorNode* getNodeFromMemoryPointer(char* memory, size_t size); + + char* reallocateMemoryAndLeakInformation(TestMemoryAllocator* allocator, char* memory, size_t size, const char* file, size_t line, bool allocatNodesSeperately); + + void addMemoryCorruptionInformation(char* memory); + void checkForCorruption(MemoryLeakDetectorNode* node, const char* file, size_t line, TestMemoryAllocator* allocator, bool allocateNodesSeperately); +}; + +#endif diff --git a/test/test_utility/include/CppUTest/MemoryLeakDetectorMallocMacros.h b/test/test_utility/include/CppUTest/MemoryLeakDetectorMallocMacros.h new file mode 100644 index 0000000..42c3247 --- /dev/null +++ b/test/test_utility/include/CppUTest/MemoryLeakDetectorMallocMacros.h @@ -0,0 +1,68 @@ + +/* + * This file can be used to get extra debugging information about memory leaks in your production code. + * It defines a preprocessor macro for malloc. This will pass additional information to the + * malloc and this will give the line/file information of the memory leaks in your code. + * + * You can use this by including this file to all your production code. When using gcc, you can use + * the -include file to do this for you. + * + */ + +#include "CppUTestConfig.h" + +#if CPPUTEST_USE_MEM_LEAK_DETECTION + +/* This prevents the declaration from done twice and makes sure the file only #defines malloc, so it can be included anywhere */ +#ifndef CPPUTEST_USE_MALLOC_MACROS + +#ifdef __cplusplus +extern "C" +{ +#endif + +extern void* cpputest_malloc_location(size_t size, const char* file, size_t line); +extern void* cpputest_calloc_location(size_t count, size_t size, const char* file, size_t line); +extern void* cpputest_realloc_location(void *, size_t, const char* file, size_t line); +extern void cpputest_free_location(void* buffer, const char* file, size_t line); + +#ifdef __cplusplus +} +#endif + +extern void crash_on_allocation_number(unsigned number); + + +#define malloc(a) cpputest_malloc_location(a, __FILE__, __LINE__) +#define calloc(a, b) cpputest_calloc_location(a, b, __FILE__, __LINE__) +#define realloc(a, b) cpputest_realloc_location(a, b, __FILE__, __LINE__) +#define free(a) cpputest_free_location(a, __FILE__, __LINE__) + +#define CPPUTEST_USE_MALLOC_MACROS 1 +#endif /* CPPUTEST_USE_MALLOC_MACROS */ + +/* This prevents strdup macros to get defined, unless it has been enabled by the user or generated config */ +#ifdef CPPUTEST_HAVE_STRDUP + +/* This prevents the declaration from done twice and makes sure the file only #defines strdup, so it can be included anywhere */ +#ifndef CPPUTEST_USE_STRDUP_MACROS + +#ifdef __cplusplus +extern "C" +{ +#endif + +extern char* cpputest_strdup_location(const char* str, const char* file, size_t line); +extern char* cpputest_strndup_location(const char* str, size_t n, const char* file, size_t line); + +#ifdef __cplusplus +} +#endif + +#define strdup(str) cpputest_strdup_location(str, __FILE__, __LINE__) +#define strndup(str, n) cpputest_strndup_location(str, n, __FILE__, __LINE__) + +#define CPPUTEST_USE_STRDUP_MACROS 1 +#endif /* CPPUTEST_USE_STRDUP_MACROS */ +#endif /* CPPUTEST_HAVE_STRDUP */ +#endif /* CPPUTEST_USE_MEM_LEAK_DETECTION */ diff --git a/test/test_utility/include/CppUTest/MemoryLeakDetectorNewMacros.h b/test/test_utility/include/CppUTest/MemoryLeakDetectorNewMacros.h new file mode 100644 index 0000000..b756a5d --- /dev/null +++ b/test/test_utility/include/CppUTest/MemoryLeakDetectorNewMacros.h @@ -0,0 +1,95 @@ + +/* + * This file can be used to get extra debugging information about memory leaks in your production code. + * It defines a preprocessor macro for operator new. This will pass additional information to the + * operator new and this will give the line/file information of the memory leaks in your code. + * + * You can use this by including this file to all your production code. When using gcc, you can use + * the -include file to do this for you. + * + * Warning: Using the new macro can cause a conflict with newly declared operator news. This can be + * resolved by: + * 1. #undef operator new before including this file + * 2. Including the files that override operator new before this file. + * This can be done by creating your own NewMacros.h file that includes your operator new overrides + * and THEN this file. + * + * STL (or StdC++ lib) also does overrides for operator new. Therefore, you'd need to include the STL + * files *before* this file too. + * + */ + +#include "CppUTestConfig.h" + +/* Make sure that mem leak detection is on and that this is being included from a C++ file */ +#if CPPUTEST_USE_MEM_LEAK_DETECTION && defined(__cplusplus) + +/* This #ifndef prevents from being included twice and enables the file to be included anywhere */ +#ifndef CPPUTEST_USE_NEW_MACROS + + #if CPPUTEST_USE_STD_CPP_LIB + #ifdef CPPUTEST_USE_STRDUP_MACROS + #if CPPUTEST_USE_STRDUP_MACROS == 1 + /* + * Some platforms (OSx, i.e.) will get or included when using header, + * in order to avoid conflicts with strdup and strndup macros defined by MemoryLeakDetectorMallocMacros.h + * we will undefined those macros, include the C++ headers and then reinclude MemoryLeakDetectorMallocMacros.h. + * The check `#if CPPUTEST_USE_STRDUP_MACROS` will ensure we only include MemoryLeakDetectorMallocMacros.h if + * it has already been includeded earlier. + */ + #undef strdup + #undef strndup + #undef CPPUTEST_USE_STRDUP_MACROS + #define __CPPUTEST_REINCLUDE_MALLOC_MEMORY_LEAK_DETECTOR + #endif + #endif + #include + #include + #include + #ifdef __CPPUTEST_REINCLUDE_MALLOC_MEMORY_LEAK_DETECTOR + #include "MemoryLeakDetectorMallocMacros.h" + #endif + #endif + + /* Some toolkits, e.g. MFC, provide their own new overloads with signature (size_t, const char *, int). + * If we don't provide them, in addition to the (size_t, const char *, size_t) version, we don't get to + * know about all allocations and report freeing of unallocated blocks. Hence, provide both overloads. + */ + + void* operator new(size_t size, const char* file, int line) UT_THROW (std::bad_alloc); + void* operator new(size_t size, const char* file, size_t line) UT_THROW (std::bad_alloc); + void* operator new[](size_t size, const char* file, int line) UT_THROW (std::bad_alloc); + void* operator new[](size_t size, const char* file, size_t line) UT_THROW (std::bad_alloc); + void* operator new(size_t size) UT_THROW(std::bad_alloc); + void* operator new[](size_t size) UT_THROW(std::bad_alloc); + + void operator delete(void* mem, const char* file, int line) UT_NOTHROW; + void operator delete(void* mem, const char* file, size_t line) UT_NOTHROW; + void operator delete[](void* mem, const char* file, int line) UT_NOTHROW; + void operator delete[](void* mem, const char* file, size_t line) UT_NOTHROW; + void operator delete(void* mem) UT_NOTHROW; + void operator delete[](void* mem) UT_NOTHROW; +#if __cplusplus >= 201402L + void operator delete (void* mem, size_t size) UT_NOTHROW; + void operator delete[] (void* mem, size_t size) UT_NOTHROW; +#endif + +#endif + + +#ifdef __clang__ + #pragma clang diagnostic push + #if (__clang_major__ == 3 && __clang_minor__ >= 6) || __clang_major__ >= 4 + #pragma clang diagnostic ignored "-Wkeyword-macro" + #endif +#endif + +#define new new(__FILE__, __LINE__) + +#ifdef __clang__ + #pragma clang diagnostic pop +#endif + +#define CPPUTEST_USE_NEW_MACROS 1 + +#endif diff --git a/test/test_utility/include/CppUTest/MemoryLeakWarningPlugin.h b/test/test_utility/include/CppUTest/MemoryLeakWarningPlugin.h new file mode 100644 index 0000000..ec3c824 --- /dev/null +++ b/test/test_utility/include/CppUTest/MemoryLeakWarningPlugin.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the 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 EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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 D_MemoryLeakWarningPlugin_h +#define D_MemoryLeakWarningPlugin_h + +#include "TestPlugin.h" +#include "MemoryLeakDetectorNewMacros.h" + +#define IGNORE_ALL_LEAKS_IN_TEST() if (MemoryLeakWarningPlugin::getFirstPlugin()) MemoryLeakWarningPlugin::getFirstPlugin()->ignoreAllLeaksInTest() +#define EXPECT_N_LEAKS(n) if (MemoryLeakWarningPlugin::getFirstPlugin()) MemoryLeakWarningPlugin::getFirstPlugin()->expectLeaksInTest(n) + +extern void crash_on_allocation_number(unsigned alloc_number); + +class MemoryLeakDetector; +class MemoryLeakFailure; + +class MemoryLeakWarningPlugin: public TestPlugin +{ +public: + MemoryLeakWarningPlugin(const SimpleString& name, MemoryLeakDetector* localDetector = NULLPTR); + virtual ~MemoryLeakWarningPlugin() _destructor_override; + + virtual void preTestAction(UtestShell& test, TestResult& result) _override; + virtual void postTestAction(UtestShell& test, TestResult& result) _override; + + virtual const char* FinalReport(size_t toBeDeletedLeaks = 0); + + void ignoreAllLeaksInTest(); + void expectLeaksInTest(size_t n); + + void destroyGlobalDetectorAndTurnOffMemoryLeakDetectionInDestructor(bool des); + + MemoryLeakDetector* getMemoryLeakDetector(); + + static MemoryLeakWarningPlugin* getFirstPlugin(); + + static MemoryLeakDetector* getGlobalDetector(); + static MemoryLeakFailure* getGlobalFailureReporter(); + static void setGlobalDetector(MemoryLeakDetector* detector, MemoryLeakFailure* reporter); + static void destroyGlobalDetector(); + + static void turnOffNewDeleteOverloads(); + static void turnOnDefaultNotThreadSafeNewDeleteOverloads(); + static void turnOnThreadSafeNewDeleteOverloads(); + static bool areNewDeleteOverloaded(); + + static void saveAndDisableNewDeleteOverloads(); + static void restoreNewDeleteOverloads(); + +private: + MemoryLeakDetector* memLeakDetector_; + bool ignoreAllWarnings_; + bool destroyGlobalDetectorAndTurnOfMemoryLeakDetectionInDestructor_; + size_t expectedLeaks_; + size_t failureCount_; + + static MemoryLeakWarningPlugin* firstPlugin_; +}; + +extern void* cpputest_malloc_location_with_leak_detection(size_t size, const char* file, size_t line); +extern void* cpputest_realloc_location_with_leak_detection(void* memory, size_t size, const char* file, size_t line); +extern void cpputest_free_location_with_leak_detection(void* buffer, const char* file, size_t line); + +#endif diff --git a/test/test_utility/include/CppUTest/PlatformSpecificFunctions.h b/test/test_utility/include/CppUTest/PlatformSpecificFunctions.h new file mode 100644 index 0000000..6737f58 --- /dev/null +++ b/test/test_utility/include/CppUTest/PlatformSpecificFunctions.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the 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 EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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 PLATFORMSPECIFICFUNCTIONS_H_ +#define PLATFORMSPECIFICFUNCTIONS_H_ + +#include "CppUTest/TestOutput.h" +TestOutput::WorkingEnvironment PlatformSpecificGetWorkingEnvironment(); + +class TestPlugin; +extern void (*PlatformSpecificRunTestInASeperateProcess)(UtestShell* shell, TestPlugin* plugin, TestResult* result); +extern int (*PlatformSpecificFork)(void); +extern int (*PlatformSpecificWaitPid)(int pid, int* status, int options); + +/* Platform specific interface we use in order to minimize dependencies with LibC. + * This enables porting to different embedded platforms. + * + */ + +#include "CppUTest/PlatformSpecificFunctions_c.h" + +#endif diff --git a/test/test_utility/include/CppUTest/PlatformSpecificFunctions_c.h b/test/test_utility/include/CppUTest/PlatformSpecificFunctions_c.h new file mode 100644 index 0000000..35425ad --- /dev/null +++ b/test/test_utility/include/CppUTest/PlatformSpecificFunctions_c.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the 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 EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/****************************************************************************** + * + * PlatformSpecificFunctions_c.H + * + * Provides an interface for when working with pure C + * + *******************************************************************************/ + + +#ifndef PLATFORMSPECIFICFUNCTIONS_C_H_ +#define PLATFORMSPECIFICFUNCTIONS_C_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Jumping operations. They manage their own jump buffers */ +extern int (*PlatformSpecificSetJmp)(void (*function) (void*), void* data); +extern void (*PlatformSpecificLongJmp)(void); +extern void (*PlatformSpecificRestoreJumpBuffer)(void); + +/* Time operations */ +extern long (*GetPlatformSpecificTimeInMillis)(void); +extern const char* (*GetPlatformSpecificTimeString)(void); + +/* String operations */ +extern int (*PlatformSpecificVSNprintf)(char *str, size_t size, const char* format, va_list va_args_list); + +/* Misc */ +extern double (*PlatformSpecificFabs)(double d); +extern int (*PlatformSpecificIsNan)(double d); +extern int (*PlatformSpecificIsInf)(double d); +extern int (*PlatformSpecificAtExit)(void(*func)(void)); + +/* IO operations */ +typedef void* PlatformSpecificFile; + +extern PlatformSpecificFile (*PlatformSpecificFOpen)(const char* filename, const char* flag); +extern void (*PlatformSpecificFPuts)(const char* str, PlatformSpecificFile file); +extern void (*PlatformSpecificFClose)(PlatformSpecificFile file); + +extern int (*PlatformSpecificPutchar)(int c); +extern void (*PlatformSpecificFlush)(void); + +/* Random operations */ +extern void (*PlatformSpecificSrand)(unsigned int); +extern int (*PlatformSpecificRand)(void); + +/* Dynamic Memory operations */ +extern void* (*PlatformSpecificMalloc)(size_t size); +extern void* (*PlatformSpecificRealloc)(void* memory, size_t size); +extern void (*PlatformSpecificFree)(void* memory); +extern void* (*PlatformSpecificMemCpy)(void* s1, const void* s2, size_t size); +extern void* (*PlatformSpecificMemset)(void* mem, int c, size_t size); + +typedef void* PlatformSpecificMutex; +extern PlatformSpecificMutex (*PlatformSpecificMutexCreate)(void); +extern void (*PlatformSpecificSrand)(unsigned int); +extern int (*PlatformSpecificRand)(void); +extern void (*PlatformSpecificMutexLock)(PlatformSpecificMutex mtx); +extern void (*PlatformSpecificMutexUnlock)(PlatformSpecificMutex mtx); +extern void (*PlatformSpecificMutexDestroy)(PlatformSpecificMutex mtx); + +#ifdef __cplusplus +} +#endif + +#endif /* PLATFORMSPECIFICFUNCTIONS_C_H_ */ diff --git a/test/test_utility/include/CppUTest/SimpleMutex.h b/test/test_utility/include/CppUTest/SimpleMutex.h new file mode 100644 index 0000000..eb49900 --- /dev/null +++ b/test/test_utility/include/CppUTest/SimpleMutex.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2014, Michael Feathers, James Grenning, Bas Vodde and Chen YewMing + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the 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 EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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 D_SimpleMutex_h +#define D_SimpleMutex_h + +#include "CppUTest/PlatformSpecificFunctions.h" + +class SimpleMutex +{ +public: + SimpleMutex(void); + ~SimpleMutex(void); + void Lock(void); + void Unlock(void); +private: + PlatformSpecificMutex psMtx; +}; + + +class ScopedMutexLock +{ +public: + ScopedMutexLock(SimpleMutex *); + ~ScopedMutexLock(void); +private: + SimpleMutex * mutex; +}; + +#endif diff --git a/test/test_utility/include/CppUTest/SimpleString.h b/test/test_utility/include/CppUTest/SimpleString.h new file mode 100644 index 0000000..6cacf95 --- /dev/null +++ b/test/test_utility/include/CppUTest/SimpleString.h @@ -0,0 +1,244 @@ +/* + * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the 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 EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/////////////////////////////////////////////////////////////////////////////// +// +// SIMPLESTRING.H +// +// One of the design goals of CppUnitLite is to compilation with very old C++ +// compilers. For that reason, the simple string class that provides +// only the operations needed in CppUnitLite. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef D_SimpleString_h +#define D_SimpleString_h + +#include "StandardCLibrary.h" + +class SimpleStringCollection; +class TestMemoryAllocator; + +class SimpleString +{ + friend bool operator==(const SimpleString& left, const SimpleString& right); + friend bool operator!=(const SimpleString& left, const SimpleString& right); + +public: + SimpleString(const char *value = ""); + SimpleString(const char *value, size_t repeatCount); + SimpleString(const SimpleString& other); + ~SimpleString(); + + SimpleString& operator=(const SimpleString& other); + SimpleString operator+(const SimpleString&) const; + SimpleString& operator+=(const SimpleString&); + SimpleString& operator+=(const char*); + + static const size_t npos = (size_t) -1; + + char at(size_t pos) const; + size_t find(char ch) const; + size_t findFrom(size_t starting_position, char ch) const; + bool contains(const SimpleString& other) const; + bool containsNoCase(const SimpleString& other) const; + bool startsWith(const SimpleString& other) const; + bool endsWith(const SimpleString& other) const; + void split(const SimpleString& split, + SimpleStringCollection& outCollection) const; + bool equalsNoCase(const SimpleString& str) const; + + size_t count(const SimpleString& str) const; + + void replace(char to, char with); + void replace(const char* to, const char* with); + + SimpleString lowerCase() const; + SimpleString subString(size_t beginPos) const; + SimpleString subString(size_t beginPos, size_t amount) const; + SimpleString subStringFromTill(char startChar, char lastExcludedChar) const; + void copyToBuffer(char* buffer, size_t bufferSize) const; + + SimpleString printable() const; + + const char *asCharString() const; + size_t size() const; + bool isEmpty() const; + + static void padStringsToSameLength(SimpleString& str1, SimpleString& str2, char ch); + + static TestMemoryAllocator* getStringAllocator(); + static void setStringAllocator(TestMemoryAllocator* allocator); + + static int AtoI(const char*str); + static unsigned AtoU(const char*str); + static int StrCmp(const char* s1, const char* s2); + static size_t StrLen(const char*); + static int StrNCmp(const char* s1, const char* s2, size_t n); + static char* StrNCpy(char* s1, const char* s2, size_t n); + static const char* StrStr(const char* s1, const char* s2); + static char ToLower(char ch); + static int MemCmp(const void* s1, const void *s2, size_t n); + static char* allocStringBuffer(size_t size, const char* file, size_t line); + static void deallocStringBuffer(char* str, size_t size, const char* file, size_t line); +private: + + const char* getBuffer() const; + + void deallocateInternalBuffer(); + void setInternalBufferAsEmptyString(); + void setInternalBufferToNewBuffer(size_t bufferSize); + void setInternalBufferTo(char* buffer, size_t bufferSize); + void copyBufferToNewInternalBuffer(const char* otherBuffer); + void copyBufferToNewInternalBuffer(const char* otherBuffer, size_t bufferSize); + void copyBufferToNewInternalBuffer(const SimpleString& otherBuffer); + + char *buffer_; + size_t bufferSize_; + + static TestMemoryAllocator* stringAllocator_; + + char* getEmptyString() const; + static char* copyToNewBuffer(const char* bufferToCopy, size_t bufferSize); + static bool isDigit(char ch); + static bool isSpace(char ch); + static bool isUpper(char ch); + static bool isControl(char ch); + static bool isControlWithShortEscapeSequence(char ch); + + size_t getPrintableSize() const; +}; + +class SimpleStringCollection +{ +public: + SimpleStringCollection(); + ~SimpleStringCollection(); + + void allocate(size_t size); + + size_t size() const; + SimpleString& operator[](size_t index); + +private: + SimpleString* collection_; + SimpleString empty_; + size_t size_; + + void operator =(SimpleStringCollection&); + SimpleStringCollection(SimpleStringCollection&); +}; + +class GlobalSimpleStringAllocatorStash +{ +public: + GlobalSimpleStringAllocatorStash(); + void save(); + void restore(); +private: + TestMemoryAllocator* originalAllocator_; +}; + +class MemoryAccountant; +class AccountingTestMemoryAllocator; + +class GlobalSimpleStringMemoryAccountant +{ +public: + GlobalSimpleStringMemoryAccountant(); + ~GlobalSimpleStringMemoryAccountant(); + + void useCacheSizes(size_t cacheSizes[], size_t length); + + void start(); + void stop(); + SimpleString report(); + + AccountingTestMemoryAllocator* getAllocator(); +private: + void restoreAllocator(); + + AccountingTestMemoryAllocator* allocator_; + MemoryAccountant* accountant_; +}; + +SimpleString StringFrom(bool value); +SimpleString StringFrom(const void* value); +SimpleString StringFrom(void (*value)()); +SimpleString StringFrom(char value); +SimpleString StringFrom(const char *value); +SimpleString StringFromOrNull(const char * value); +SimpleString StringFrom(int value); +SimpleString StringFrom(unsigned int value); +SimpleString StringFrom(long value); +SimpleString StringFrom(unsigned long value); +SimpleString StringFrom(cpputest_longlong value); +SimpleString StringFrom(cpputest_ulonglong value); +SimpleString HexStringFrom(unsigned int value); +SimpleString HexStringFrom(int value); +SimpleString HexStringFrom(signed char value); +SimpleString HexStringFrom(long value); +SimpleString HexStringFrom(unsigned long value); +SimpleString HexStringFrom(cpputest_longlong value); +SimpleString HexStringFrom(cpputest_ulonglong value); +SimpleString HexStringFrom(const void* value); +SimpleString HexStringFrom(void (*value)()); +SimpleString StringFrom(double value, int precision = 6); +SimpleString StringFrom(const SimpleString& other); +SimpleString StringFromFormat(const char* format, ...) _check_format_(printf, 1, 2); +SimpleString VStringFromFormat(const char* format, va_list args); +SimpleString StringFromBinary(const unsigned char* value, size_t size); +SimpleString StringFromBinaryOrNull(const unsigned char* value, size_t size); +SimpleString StringFromBinaryWithSize(const unsigned char* value, size_t size); +SimpleString StringFromBinaryWithSizeOrNull(const unsigned char* value, size_t size); +SimpleString StringFromMaskedBits(unsigned long value, unsigned long mask, size_t byteCount); +SimpleString StringFromOrdinalNumber(unsigned int number); +SimpleString BracketsFormattedHexStringFrom(int value); +SimpleString BracketsFormattedHexStringFrom(unsigned int value); +SimpleString BracketsFormattedHexStringFrom(long value); +SimpleString BracketsFormattedHexStringFrom(unsigned long value); +SimpleString BracketsFormattedHexStringFrom(cpputest_longlong value); +SimpleString BracketsFormattedHexStringFrom(cpputest_ulonglong value); +SimpleString BracketsFormattedHexStringFrom(signed char value); +SimpleString BracketsFormattedHexString(SimpleString hexString); +SimpleString PrintableStringFromOrNull(const char * expected); + +/* + * ARM compiler has only partial support for C++11. + * Specifically nullptr_t is not officially supported + */ +#if __cplusplus > 199711L && !defined __arm__ && CPPUTEST_USE_STD_CPP_LIB +SimpleString StringFrom(const std::nullptr_t value); +#endif + +#if CPPUTEST_USE_STD_CPP_LIB + +SimpleString StringFrom(const std::string& other); + +#endif + +#endif diff --git a/test/test_utility/include/CppUTest/SimpleStringInternalCache.h b/test/test_utility/include/CppUTest/SimpleStringInternalCache.h new file mode 100644 index 0000000..94bfdd8 --- /dev/null +++ b/test/test_utility/include/CppUTest/SimpleStringInternalCache.h @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the 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 EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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 D_SimpleStringInternalCache_h +#define D_SimpleStringInternalCache_h + +#include "CppUTest/TestMemoryAllocator.h" + +struct SimpleStringMemoryBlock; +struct SimpleStringInternalCacheNode; + +class SimpleStringInternalCache +{ +public: + SimpleStringInternalCache(); + ~SimpleStringInternalCache(); + + void setAllocator(TestMemoryAllocator* allocator); + + char* alloc(size_t size); + void dealloc(char* memory, size_t size); + + bool hasFreeBlocksOfSize(size_t size); + + void clearCache(); + void clearAllIncludingCurrentlyUsedMemory(); +private: + void printDeallocatingUnknownMemory(char* memory); + + enum { amountOfInternalCacheNodes = 5}; + bool isCached(size_t size); + size_t getIndexForCache(size_t size); + SimpleStringInternalCacheNode* getCacheNodeFromSize(size_t size); + + SimpleStringInternalCacheNode* createInternalCacheNodes(); + void destroyInternalCacheNode(SimpleStringInternalCacheNode * node); + SimpleStringMemoryBlock* createSimpleStringMemoryBlock(size_t sizeOfString, SimpleStringMemoryBlock* next); + void destroySimpleStringMemoryBlock(SimpleStringMemoryBlock * block, size_t size); + void destroySimpleStringMemoryBlockList(SimpleStringMemoryBlock * block, size_t size); + + SimpleStringMemoryBlock* reserveCachedBlockFrom(SimpleStringInternalCacheNode* node); + void releaseCachedBlockFrom(char* memory, SimpleStringInternalCacheNode* node); + void releaseNonCachedMemory(char* memory, size_t size); + + SimpleStringMemoryBlock* allocateNewCacheBlockFrom(SimpleStringInternalCacheNode* node); + SimpleStringMemoryBlock* addToSimpleStringMemoryBlockList(SimpleStringMemoryBlock* newBlock, SimpleStringMemoryBlock* previousHead); + + TestMemoryAllocator* allocator_; + SimpleStringInternalCacheNode* cache_; + SimpleStringMemoryBlock* nonCachedAllocations_; + bool hasWarnedAboutDeallocations; +}; + +class SimpleStringCacheAllocator : public TestMemoryAllocator +{ +public: + SimpleStringCacheAllocator(SimpleStringInternalCache& cache, TestMemoryAllocator* previousAllocator); + virtual ~SimpleStringCacheAllocator() _destructor_override; + + virtual char* alloc_memory(size_t size, const char* file, size_t line) _override; + virtual void free_memory(char* memory, size_t size, const char* file, size_t line) _override; + + virtual const char* name() const _override; + virtual const char* alloc_name() const _override; + virtual const char* free_name() const _override; + + virtual TestMemoryAllocator* actualAllocator() _override; + TestMemoryAllocator* originalAllocator(); +private: + SimpleStringInternalCache& cache_; + TestMemoryAllocator* originalAllocator_; +}; + +class GlobalSimpleStringCache +{ + SimpleStringCacheAllocator* allocator_; + SimpleStringInternalCache cache_; + +public: + GlobalSimpleStringCache(); + ~GlobalSimpleStringCache(); + + TestMemoryAllocator* getAllocator(); +}; + +#endif diff --git a/test/test_utility/include/CppUTest/StandardCLibrary.h b/test/test_utility/include/CppUTest/StandardCLibrary.h new file mode 100644 index 0000000..914f0ac --- /dev/null +++ b/test/test_utility/include/CppUTest/StandardCLibrary.h @@ -0,0 +1,96 @@ + +/* Must include this first to ensure the StandardC include in CppUTestConfig still happens at the right moment */ +#include "CppUTestConfig.h" + +#ifndef STANDARDCLIBRARY_H_ +#define STANDARDCLIBRARY_H_ + +#if CPPUTEST_USE_STD_C_LIB + +/* Needed for size_t */ +#include + +/* Sometimes the C++ library does an #undef in stdlib of malloc and free. We want to prevent that */ +#ifdef __cplusplus + #if CPPUTEST_USE_STD_CPP_LIB + #include + #include + #endif +#endif + +/* Needed for malloc */ +#include + +/* Needed for std::nullptr */ +#ifdef __cplusplus + #if CPPUTEST_USE_STD_CPP_LIB + #include + #endif +#endif + +/* Needed for ... */ +#include + +/* Kludge to get a va_copy in VC++ V6 and in GCC 98 */ +#ifndef va_copy +#ifdef __GNUC__ +#define va_copy __va_copy +#else +#define va_copy(copy, original) copy = original; +#endif +#endif + +/* Needed for some detection of long long and 64 bit */ +#include + +/* Needed to ensure that string.h is included prior to strdup redefinition */ +#ifdef CPPUTEST_HAVE_STRING_H +#include +#endif + +#else + +#ifdef __KERNEL__ + +/* Unfinished and not working! Hacking hacking hacking. Why bother make the header files C++ safe! */ +#define false kernel_false +#define true kernel_true +#define bool kernel_bool +#define new kernel_new +#define _Bool int +#include +#include +#undef false +#undef true +#undef bool +#undef new + +#else + +/* + * #warning "These definitions in StandardCLibrary.h are pure (educated, from linux kernel) guesses at the moment. Replace with your platform includes." + * Not on as warning are as errors :P + */ + +#ifdef __SIZE_TYPE__ +typedef __SIZE_TYPE__ size_t; +#else +typedef long unsigned int size_t; +#endif + +#define NULL (0) +extern void* malloc(size_t); +extern void free(void *); + +#define _bnd(X, bnd) (((sizeof (X)) + (bnd)) & (~(bnd))) + +#define va_list __builtin_va_list +#define va_copy __builtin_va_copy +#define va_start __builtin_va_start +#define va_end __builtin_va_end + +#endif + +#endif + +#endif diff --git a/test/test_utility/include/CppUTest/TeamCityTestOutput.h b/test/test_utility/include/CppUTest/TeamCityTestOutput.h new file mode 100644 index 0000000..186d218 --- /dev/null +++ b/test/test_utility/include/CppUTest/TeamCityTestOutput.h @@ -0,0 +1,28 @@ +#ifndef D_TeamCityTestOutput_h +#define D_TeamCityTestOutput_h + +#include "TestOutput.h" +#include "SimpleString.h" + +class TeamCityTestOutput: public ConsoleTestOutput +{ +public: + TeamCityTestOutput(void); + virtual ~TeamCityTestOutput(void) _destructor_override; + + virtual void printCurrentTestStarted(const UtestShell& test) _override; + virtual void printCurrentTestEnded(const TestResult& res) _override; + virtual void printCurrentGroupStarted(const UtestShell& test) _override; + virtual void printCurrentGroupEnded(const TestResult& res) _override; + + virtual void printFailure(const TestFailure& failure) _override; + +protected: + +private: + void printEscaped(const char* s); + const UtestShell *currtest_; + SimpleString currGroup_; +}; + +#endif diff --git a/test/test_utility/include/CppUTest/TestFailure.h b/test/test_utility/include/CppUTest/TestFailure.h new file mode 100644 index 0000000..373274d --- /dev/null +++ b/test/test_utility/include/CppUTest/TestFailure.h @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the 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 EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/////////////////////////////////////////////////////////////////////////////// +// +// Failure is a class which holds information for a specific +// test failure. It can be overriden for more complex failure messages +// +/////////////////////////////////////////////////////////////////////////////// + + +#ifndef D_TestFailure_H +#define D_TestFailure_H + +#include "SimpleString.h" + +class UtestShell; +class TestOutput; + +class TestFailure +{ + +public: + TestFailure(UtestShell*, const char* fileName, size_t lineNumber, const SimpleString& theMessage); + TestFailure(UtestShell*, const SimpleString& theMessage); + TestFailure(UtestShell*, const char* fileName, size_t lineNumber); + TestFailure(const TestFailure&); + virtual ~TestFailure(); + + virtual SimpleString getFileName() const; + virtual SimpleString getTestName() const; + virtual SimpleString getTestNameOnly() const; + virtual size_t getFailureLineNumber() const; + virtual SimpleString getMessage() const; + virtual SimpleString getTestFileName() const; + virtual size_t getTestLineNumber() const; + bool isOutsideTestFile() const; + bool isInHelperFunction() const; + + +protected: + SimpleString createButWasString(const SimpleString& expected, const SimpleString& actual); + SimpleString createDifferenceAtPosString(const SimpleString& actual, size_t offset, size_t reportedPosition); + SimpleString createUserText(const SimpleString& text); + + SimpleString testName_; + SimpleString testNameOnly_; + SimpleString fileName_; + size_t lineNumber_; + SimpleString testFileName_; + size_t testLineNumber_; + SimpleString message_; + + TestFailure& operator=(const TestFailure&); + +}; + +class EqualsFailure: public TestFailure +{ +public: + EqualsFailure(UtestShell*, const char* fileName, size_t lineNumber, const char* expected, const char* actual, const SimpleString& text); + EqualsFailure(UtestShell*, const char* fileName, size_t lineNumber, const SimpleString& expected, const SimpleString& actual, const SimpleString& text); +}; + +class DoublesEqualFailure: public TestFailure +{ +public: + DoublesEqualFailure(UtestShell*, const char* fileName, size_t lineNumber, double expected, double actual, double threshold, const SimpleString& text); +}; + +class CheckEqualFailure : public TestFailure +{ +public: + CheckEqualFailure(UtestShell* test, const char* fileName, size_t lineNumber, const SimpleString& expected, const SimpleString& actual, const SimpleString& text); +}; + +class ComparisonFailure : public TestFailure +{ +public: + ComparisonFailure(UtestShell* test, const char *fileName, size_t lineNumber, const SimpleString& checkString, const SimpleString& comparisonString, const SimpleString& text); +}; + +class ContainsFailure: public TestFailure +{ +public: + ContainsFailure(UtestShell*, const char* fileName, size_t lineNumber, const SimpleString& expected, const SimpleString& actual, const SimpleString& text); +}; + +class CheckFailure : public TestFailure +{ +public: + CheckFailure(UtestShell* test, const char* fileName, size_t lineNumber, const SimpleString& checkString, const SimpleString& conditionString, const SimpleString& textString = ""); +}; + +class FailFailure : public TestFailure +{ +public: + FailFailure(UtestShell* test, const char* fileName, size_t lineNumber, const SimpleString& message); +}; + +class LongsEqualFailure : public TestFailure +{ +public: + LongsEqualFailure(UtestShell* test, const char* fileName, size_t lineNumber, long expected, long actual, const SimpleString& text); +}; + +class UnsignedLongsEqualFailure : public TestFailure +{ +public: + UnsignedLongsEqualFailure(UtestShell* test, const char* fileName, size_t lineNumber, unsigned long expected, unsigned long actual, const SimpleString& text); +}; + +class LongLongsEqualFailure : public TestFailure +{ +public: + LongLongsEqualFailure(UtestShell* test, const char* fileName, size_t lineNumber, cpputest_longlong expected, cpputest_longlong actual, const SimpleString& text); +}; + +class UnsignedLongLongsEqualFailure : public TestFailure +{ +public: + UnsignedLongLongsEqualFailure(UtestShell* test, const char* fileName, size_t lineNumber, cpputest_ulonglong expected, cpputest_ulonglong actual, const SimpleString& text); +}; + +class SignedBytesEqualFailure : public TestFailure +{ +public: + SignedBytesEqualFailure (UtestShell* test, const char* fileName, size_t lineNumber, signed char expected, signed char actual, const SimpleString& text); +}; + +class StringEqualFailure : public TestFailure +{ +public: + StringEqualFailure(UtestShell* test, const char* fileName, size_t lineNumber, const char* expected, const char* actual, const SimpleString& text); +}; + +class StringEqualNoCaseFailure : public TestFailure +{ +public: + StringEqualNoCaseFailure(UtestShell* test, const char* fileName, size_t lineNumber, const char* expected, const char* actual, const SimpleString& text); +}; + +class BinaryEqualFailure : public TestFailure +{ +public: + BinaryEqualFailure(UtestShell* test, const char* fileName, size_t lineNumber, const unsigned char* expected, const unsigned char* actual, size_t size, const SimpleString& text); +}; + +class BitsEqualFailure : public TestFailure +{ +public: + BitsEqualFailure(UtestShell* test, const char* fileName, size_t lineNumber, unsigned long expected, unsigned long actual, unsigned long mask, size_t byteCount, const SimpleString& text); +}; + +class FeatureUnsupportedFailure : public TestFailure +{ +public: + FeatureUnsupportedFailure(UtestShell* test, const char* fileName, size_t lineNumber, const SimpleString& featureName, const SimpleString& text); +}; + +#endif diff --git a/test/test_utility/include/CppUTest/TestFilter.h b/test/test_utility/include/CppUTest/TestFilter.h new file mode 100644 index 0000000..6f92a00 --- /dev/null +++ b/test/test_utility/include/CppUTest/TestFilter.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the 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 EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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 TESTFILTER_H_ +#define TESTFILTER_H_ + +#include "SimpleString.h" + +class TestFilter +{ +public: + + TestFilter(); + TestFilter(const char* filter); + TestFilter(const SimpleString& filter); + + TestFilter* add(TestFilter* filter); + TestFilter* getNext() const; + + bool match(const SimpleString& name) const; + + void strictMatching(); + void invertMatching(); + + bool operator==(const TestFilter& filter) const; + bool operator!=(const TestFilter& filter) const; + + SimpleString asString() const; +private: + SimpleString filter_; + bool strictMatching_; + bool invertMatching_; + TestFilter* next_; +}; + +SimpleString StringFrom(const TestFilter& filter); + +#endif + diff --git a/test/test_utility/include/CppUTest/TestHarness.h b/test/test_utility/include/CppUTest/TestHarness.h new file mode 100644 index 0000000..8eb5b29 --- /dev/null +++ b/test/test_utility/include/CppUTest/TestHarness.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the 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 EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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 D_TestHarness_h +#define D_TestHarness_h + +#include "CppUTestConfig.h" + +/* original value was 9973 which works well with large programs. Now set to smaller since it takes + * a lot of memory in embedded apps. Change it if you experience the memory leak detector to be slow. + */ + +#define MEMORY_LEAK_HASH_TABLE_SIZE 73 + +#include "Utest.h" +#include "UtestMacros.h" +#include "SimpleString.h" +#include "TestResult.h" +#include "TestFailure.h" +#include "TestPlugin.h" +#include "MemoryLeakWarningPlugin.h" +#endif diff --git a/test/test_utility/include/CppUTest/TestHarness_c.h b/test/test_utility/include/CppUTest/TestHarness_c.h new file mode 100644 index 0000000..26f6203 --- /dev/null +++ b/test/test_utility/include/CppUTest/TestHarness_c.h @@ -0,0 +1,251 @@ +/* + * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the 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 EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/****************************************************************************** + * + * Provides an interface for when working with pure C + * + *******************************************************************************/ + +#ifndef D_TestHarness_c_h +#define D_TestHarness_c_h + +#include "CppUTestConfig.h" + +#define CHECK_EQUAL_C_BOOL(expected,actual) \ + CHECK_EQUAL_C_BOOL_LOCATION(expected,actual,NULLPTR,__FILE__,__LINE__) + +#define CHECK_EQUAL_C_BOOL_TEXT(expected,actual,text) \ + CHECK_EQUAL_C_BOOL_LOCATION(expected,actual,text,__FILE__,__LINE__) + +#define CHECK_EQUAL_C_INT(expected,actual) \ + CHECK_EQUAL_C_INT_LOCATION(expected,actual,NULLPTR,__FILE__,__LINE__) + +#define CHECK_EQUAL_C_INT_TEXT(expected,actual,text) \ + CHECK_EQUAL_C_INT_LOCATION(expected,actual,text,__FILE__,__LINE__) + +#define CHECK_EQUAL_C_UINT(expected,actual) \ + CHECK_EQUAL_C_UINT_LOCATION(expected,actual,NULLPTR,__FILE__,__LINE__) + +#define CHECK_EQUAL_C_UINT_TEXT(expected,actual,text) \ + CHECK_EQUAL_C_UINT_LOCATION(expected,actual,text,__FILE__,__LINE__) + +#define CHECK_EQUAL_C_LONG(expected,actual) \ + CHECK_EQUAL_C_LONG_LOCATION(expected,actual,NULLPTR,__FILE__,__LINE__) + +#define CHECK_EQUAL_C_LONG_TEXT(expected,actual,text) \ + CHECK_EQUAL_C_LONG_LOCATION(expected,actual,text,__FILE__,__LINE__) + +#define CHECK_EQUAL_C_ULONG(expected,actual) \ + CHECK_EQUAL_C_ULONG_LOCATION(expected,actual,NULLPTR,__FILE__,__LINE__) + +#define CHECK_EQUAL_C_ULONG_TEXT(expected,actual,text) \ + CHECK_EQUAL_C_ULONG_LOCATION(expected,actual,text,__FILE__,__LINE__) + +#define CHECK_EQUAL_C_LONGLONG(expected,actual) \ + CHECK_EQUAL_C_LONGLONG_LOCATION(expected,actual,NULLPTR,__FILE__,__LINE__) + +#define CHECK_EQUAL_C_LONGLONG_TEXT(expected,actual,text) \ + CHECK_EQUAL_C_LONGLONG_LOCATION(expected,actual,text,__FILE__,__LINE__) + +#define CHECK_EQUAL_C_ULONGLONG(expected,actual) \ + CHECK_EQUAL_C_ULONGLONG_LOCATION(expected,actual,NULLPTR,__FILE__,__LINE__) + +#define CHECK_EQUAL_C_ULONGLONG_TEXT(expected,actual,text) \ + CHECK_EQUAL_C_ULONGLONG_LOCATION(expected,actual,text,__FILE__,__LINE__) + +#define CHECK_EQUAL_C_REAL(expected,actual,threshold) \ + CHECK_EQUAL_C_REAL_LOCATION(expected,actual,threshold,NULLPTR,__FILE__,__LINE__) + +#define CHECK_EQUAL_C_REAL_TEXT(expected,actual,threshold,text) \ + CHECK_EQUAL_C_REAL_LOCATION(expected,actual,threshold,text,__FILE__,__LINE__) + +#define CHECK_EQUAL_C_CHAR(expected,actual) \ + CHECK_EQUAL_C_CHAR_LOCATION(expected,actual,NULLPTR,__FILE__,__LINE__) + +#define CHECK_EQUAL_C_CHAR_TEXT(expected,actual,text) \ + CHECK_EQUAL_C_CHAR_LOCATION(expected,actual,text,__FILE__,__LINE__) + +#define CHECK_EQUAL_C_UBYTE(expected,actual) \ + CHECK_EQUAL_C_UBYTE_LOCATION(expected,actual,NULLPTR,__FILE__,__LINE__) + +#define CHECK_EQUAL_C_UBYTE_TEXT(expected,actual,text) \ + CHECK_EQUAL_C_UBYTE_LOCATION(expected,actual,text,__FILE__,__LINE__) + +#define CHECK_EQUAL_C_SBYTE(expected,actual) \ + CHECK_EQUAL_C_SBYTE_LOCATION(expected,actual,NULLPTR,__FILE__,__LINE__) + +#define CHECK_EQUAL_C_SBYTE_TEXT(expected,actual,text) \ + CHECK_EQUAL_C_SBYTE_LOCATION(expected,actual,text,__FILE__,__LINE__) + +#define CHECK_EQUAL_C_STRING(expected,actual) \ + CHECK_EQUAL_C_STRING_LOCATION(expected,actual,NULLPTR,__FILE__,__LINE__) + +#define CHECK_EQUAL_C_STRING_TEXT(expected,actual,text) \ + CHECK_EQUAL_C_STRING_LOCATION(expected,actual,text,__FILE__,__LINE__) + +#define CHECK_EQUAL_C_POINTER(expected,actual) \ + CHECK_EQUAL_C_POINTER_LOCATION(expected,actual,NULLPTR,__FILE__,__LINE__) + +#define CHECK_EQUAL_C_POINTER_TEXT(expected,actual,text) \ + CHECK_EQUAL_C_POINTER_LOCATION(expected,actual,text,__FILE__,__LINE__) + +#define CHECK_EQUAL_C_BITS(expected, actual, mask) \ + CHECK_EQUAL_C_BITS_LOCATION(expected, actual, mask, sizeof(actual), NULLPTR, __FILE__, __LINE__) + +#define CHECK_EQUAL_C_BITS_TEXT(expected, actual, mask, text) \ + CHECK_EQUAL_C_BITS_LOCATION(expected, actual, mask, sizeof(actual), text, __FILE__, __LINE__) + +#define FAIL_TEXT_C(text) \ + FAIL_TEXT_C_LOCATION(text,__FILE__,__LINE__) + +#define FAIL_C() \ + FAIL_C_LOCATION(__FILE__,__LINE__) + +#define CHECK_C(condition) \ + CHECK_C_LOCATION(condition, #condition, NULLPTR, __FILE__,__LINE__) + +#define CHECK_C_TEXT(condition, text) \ + CHECK_C_LOCATION(condition, #condition, text, __FILE__, __LINE__) + +/****************************************************************************** + * + * TEST macros for in C. + * + *******************************************************************************/ + +/* For use in C file */ +#define TEST_GROUP_C_SETUP(group_name) \ + extern void group_##group_name##_setup_wrapper_c(void); \ + void group_##group_name##_setup_wrapper_c() + +#define TEST_GROUP_C_TEARDOWN(group_name) \ + extern void group_##group_name##_teardown_wrapper_c(void); \ + void group_##group_name##_teardown_wrapper_c() + +#define TEST_C(group_name, test_name) \ + extern void test_##group_name##_##test_name##_wrapper_c(void);\ + void test_##group_name##_##test_name##_wrapper_c() + +#define IGNORE_TEST_C(group_name, test_name) \ + extern void ignore_##group_name##_##test_name##_wrapper_c(void);\ + void ignore_##group_name##_##test_name##_wrapper_c() + + +/* For use in C++ file */ + +#define TEST_GROUP_C_WRAPPER(group_name) \ + extern "C" void group_##group_name##_setup_wrapper_c(void); \ + extern "C" void group_##group_name##_teardown_wrapper_c(void); \ + TEST_GROUP(group_name) + +#define TEST_GROUP_C_SETUP_WRAPPER(group_name) \ + void setup() _override { \ + group_##group_name##_setup_wrapper_c(); \ + } + +#define TEST_GROUP_C_TEARDOWN_WRAPPER(group_name) \ + void teardown() _override { \ + group_##group_name##_teardown_wrapper_c(); \ + } + +#define TEST_C_WRAPPER(group_name, test_name) \ + extern "C" void test_##group_name##_##test_name##_wrapper_c(); \ + TEST(group_name, test_name) { \ + test_##group_name##_##test_name##_wrapper_c(); \ + } + +#define IGNORE_TEST_C_WRAPPER(group_name, test_name) \ + extern "C" void ignore_##group_name##_##test_name##_wrapper_c(); \ + IGNORE_TEST(group_name, test_name) { \ + ignore_##group_name##_##test_name##_wrapper_c(); \ + } + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/* CHECKS that can be used from C code */ +extern void CHECK_EQUAL_C_BOOL_LOCATION(int expected, int actual, const char* text, const char* fileName, size_t lineNumber); +extern void CHECK_EQUAL_C_INT_LOCATION(int expected, int actual, const char* text, const char* fileName, size_t lineNumber); +extern void CHECK_EQUAL_C_UINT_LOCATION(unsigned int expected, unsigned int actual, const char* text, const char* fileName, size_t lineNumber); +extern void CHECK_EQUAL_C_LONG_LOCATION(long expected, long actual, const char* text, const char* fileName, size_t lineNumber); +extern void CHECK_EQUAL_C_ULONG_LOCATION(unsigned long expected, unsigned long actual, const char* text, const char* fileName, size_t lineNumber); +extern void CHECK_EQUAL_C_LONGLONG_LOCATION(cpputest_longlong expected, cpputest_longlong actual, const char* text, const char* fileName, size_t lineNumber); +extern void CHECK_EQUAL_C_ULONGLONG_LOCATION(cpputest_ulonglong expected, cpputest_ulonglong actual, const char* text, const char* fileName, size_t lineNumber); +extern void CHECK_EQUAL_C_REAL_LOCATION(double expected, double actual, double threshold, const char* text, const char* fileName, size_t lineNumber); +extern void CHECK_EQUAL_C_CHAR_LOCATION(char expected, char actual, const char* text, const char* fileName, size_t lineNumber); +extern void CHECK_EQUAL_C_UBYTE_LOCATION(unsigned char expected, unsigned char actual, const char* text, const char* fileName, size_t lineNumber); +extern void CHECK_EQUAL_C_SBYTE_LOCATION(signed char expected, signed char actual, const char* text, const char* fileName, size_t lineNumber); +extern void CHECK_EQUAL_C_STRING_LOCATION(const char* expected, const char* actual, const char* text, const char* fileName, size_t lineNumber); +extern void CHECK_EQUAL_C_POINTER_LOCATION(const void* expected, const void* actual, const char* text, const char* fileName, size_t lineNumber); +extern void CHECK_EQUAL_C_BITS_LOCATION(unsigned int expected, unsigned int actual, unsigned int mask, size_t size, const char* text, const char* fileName, size_t lineNumber); +extern void FAIL_TEXT_C_LOCATION(const char* text, const char* fileName, size_t lineNumber); +extern void FAIL_C_LOCATION(const char* fileName, size_t lineNumber); +extern void CHECK_C_LOCATION(int condition, const char* conditionString, const char* text, const char* fileName, size_t lineNumber); + +extern void* cpputest_malloc(size_t size); +extern char* cpputest_strdup(const char* str); +extern char* cpputest_strndup(const char* str, size_t n); +extern void* cpputest_calloc(size_t num, size_t size); +extern void* cpputest_realloc(void* ptr, size_t size); +extern void cpputest_free(void* buffer); + +extern void* cpputest_malloc_location(size_t size, const char* file, size_t line); +extern char* cpputest_strdup_location(const char* str, const char* file, size_t line); +extern char* cpputest_strndup_location(const char* str, size_t n, const char* file, size_t line); +extern void* cpputest_calloc_location(size_t num, size_t size, const char* file, size_t line); +extern void* cpputest_realloc_location(void* memory, size_t size, const char* file, size_t line); +extern void cpputest_free_location(void* buffer, const char* file, size_t line); + +void cpputest_malloc_set_out_of_memory(void); +void cpputest_malloc_set_not_out_of_memory(void); +void cpputest_malloc_set_out_of_memory_countdown(int); +void cpputest_malloc_count_reset(void); +int cpputest_malloc_get_count(void); + +#ifdef __cplusplus +} +#endif + + +/* + * Small additional macro for unused arguments. This is common when stubbing, but in C you cannot remove the + * name of the parameter (as in C++). + */ + +#ifndef PUNUSED +#if defined(__GNUC__) || defined(__clang__) +# define PUNUSED(x) PUNUSED_ ##x __attribute__((unused)) +#else +# define PUNUSED(x) x +#endif +#endif + +#endif diff --git a/test/test_utility/include/CppUTest/TestMemoryAllocator.h b/test/test_utility/include/CppUTest/TestMemoryAllocator.h new file mode 100644 index 0000000..17e5b11 --- /dev/null +++ b/test/test_utility/include/CppUTest/TestMemoryAllocator.h @@ -0,0 +1,261 @@ +/* + * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the 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 EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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 D_TestMemoryAllocator_h +#define D_TestMemoryAllocator_h + +struct MemoryLeakNode; +class TestMemoryAllocator; + +extern void setCurrentNewAllocator(TestMemoryAllocator* allocator); +extern TestMemoryAllocator* getCurrentNewAllocator(); +extern void setCurrentNewAllocatorToDefault(); +extern TestMemoryAllocator* defaultNewAllocator(); + +extern void setCurrentNewArrayAllocator(TestMemoryAllocator* allocator); +extern TestMemoryAllocator* getCurrentNewArrayAllocator(); +extern void setCurrentNewArrayAllocatorToDefault(); +extern TestMemoryAllocator* defaultNewArrayAllocator(); + +extern void setCurrentMallocAllocator(TestMemoryAllocator* allocator); +extern TestMemoryAllocator* getCurrentMallocAllocator(); +extern void setCurrentMallocAllocatorToDefault(); +extern TestMemoryAllocator* defaultMallocAllocator(); + +class GlobalMemoryAllocatorStash +{ +public: + GlobalMemoryAllocatorStash(); + void save(); + void restore(); + +private: + TestMemoryAllocator* originalMallocAllocator; + TestMemoryAllocator* originalNewAllocator; + TestMemoryAllocator* originalNewArrayAllocator; +}; + +class TestMemoryAllocator +{ +public: + TestMemoryAllocator(const char* name_str = "generic", const char* alloc_name_str = "alloc", const char* free_name_str = "free"); + virtual ~TestMemoryAllocator(); + bool hasBeenDestroyed(); + + virtual char* alloc_memory(size_t size, const char* file, size_t line); + virtual void free_memory(char* memory, size_t size, const char* file, size_t line); + + virtual const char* name() const; + virtual const char* alloc_name() const; + virtual const char* free_name() const; + + virtual bool isOfEqualType(TestMemoryAllocator* allocator); + + virtual char* allocMemoryLeakNode(size_t size); + virtual void freeMemoryLeakNode(char* memory); + + virtual TestMemoryAllocator* actualAllocator(); + +protected: + + const char* name_; + const char* alloc_name_; + const char* free_name_; + + bool hasBeenDestroyed_; +}; + +class MemoryLeakAllocator : public TestMemoryAllocator +{ +public: + MemoryLeakAllocator(TestMemoryAllocator* originalAllocator); + virtual ~MemoryLeakAllocator() _destructor_override; + + virtual char* alloc_memory(size_t size, const char* file, size_t line) _override; + virtual void free_memory(char* memory, size_t size, const char* file, size_t line) _override; + + virtual const char* name() const _override; + virtual const char* alloc_name() const _override; + virtual const char* free_name() const _override; + + virtual TestMemoryAllocator* actualAllocator() _override; +private: + TestMemoryAllocator* originalAllocator_; +}; + +class CrashOnAllocationAllocator : public TestMemoryAllocator +{ + unsigned allocationToCrashOn_; +public: + CrashOnAllocationAllocator(); + virtual ~CrashOnAllocationAllocator() _destructor_override; + + virtual void setNumberToCrashOn(unsigned allocationToCrashOn); + + virtual char* alloc_memory(size_t size, const char* file, size_t line) _override; +}; + + +class NullUnknownAllocator: public TestMemoryAllocator +{ +public: + NullUnknownAllocator(); + virtual ~NullUnknownAllocator() _destructor_override; + + virtual char* alloc_memory(size_t size, const char* file, size_t line) _override; + virtual void free_memory(char* memory, size_t size, const char* file, size_t line) _override; + + static TestMemoryAllocator* defaultAllocator(); +}; + +class LocationToFailAllocNode; + +class FailableMemoryAllocator: public TestMemoryAllocator +{ +public: + FailableMemoryAllocator(const char* name_str = "failable alloc", const char* alloc_name_str = "alloc", const char* free_name_str = "free"); + virtual ~FailableMemoryAllocator() _destructor_override; + + virtual char* alloc_memory(size_t size, const char* file, size_t line) _override; + virtual char* allocMemoryLeakNode(size_t size) _override; + + virtual void failAllocNumber(int number); + virtual void failNthAllocAt(int allocationNumber, const char* file, size_t line); + + virtual void checkAllFailedAllocsWereDone(); + virtual void clearFailedAllocs(); + +protected: + + LocationToFailAllocNode* head_; + int currentAllocNumber_; +}; + +struct MemoryAccountantAllocationNode; + +class MemoryAccountant +{ +public: + MemoryAccountant(); + ~MemoryAccountant(); + + void useCacheSizes(size_t sizes[], size_t length); + + void clear(); + + void alloc(size_t size); + void dealloc(size_t size); + + size_t totalAllocationsOfSize(size_t size) const; + size_t totalDeallocationsOfSize(size_t size) const; + size_t maximumAllocationAtATimeOfSize(size_t size) const; + + size_t totalAllocations() const; + size_t totalDeallocations() const; + + SimpleString report() const; + + void setAllocator(TestMemoryAllocator* allocator); +private: + MemoryAccountantAllocationNode* findOrCreateNodeOfSize(size_t size); + MemoryAccountantAllocationNode* findNodeOfSize(size_t size) const; + + MemoryAccountantAllocationNode* createNewAccountantAllocationNode(size_t size, MemoryAccountantAllocationNode* next) const; + void destroyAccountantAllocationNode(MemoryAccountantAllocationNode* node) const; + + void createCacheSizeNodes(size_t sizes[], size_t length); + + MemoryAccountantAllocationNode* head_; + TestMemoryAllocator* allocator_; + bool useCacheSizes_; + + SimpleString reportNoAllocations() const; + SimpleString reportTitle() const; + SimpleString reportHeader() const; + SimpleString reportFooter() const; + SimpleString stringSize(size_t size) const; + +}; + +struct AccountingTestMemoryAllocatorMemoryNode; + +class AccountingTestMemoryAllocator : public TestMemoryAllocator +{ +public: + AccountingTestMemoryAllocator(MemoryAccountant& accountant, TestMemoryAllocator* originalAllocator); + virtual ~AccountingTestMemoryAllocator() _destructor_override; + + virtual char* alloc_memory(size_t size, const char* file, size_t line) _override; + virtual void free_memory(char* memory, size_t size, const char* file, size_t line) _override; + + virtual TestMemoryAllocator* actualAllocator() _override; + TestMemoryAllocator* originalAllocator(); + + virtual const char* alloc_name() const _override; + virtual const char* free_name() const _override; +private: + + void addMemoryToMemoryTrackingToKeepTrackOfSize(char* memory, size_t size); + size_t removeMemoryFromTrackingAndReturnAllocatedSize(char* memory); + + size_t removeNextNodeAndReturnSize(AccountingTestMemoryAllocatorMemoryNode* node); + size_t removeHeadAndReturnSize(); + + MemoryAccountant& accountant_; + TestMemoryAllocator* originalAllocator_; + AccountingTestMemoryAllocatorMemoryNode* head_; +}; + +class GlobalMemoryAccountant +{ +public: + GlobalMemoryAccountant(); + ~GlobalMemoryAccountant(); + + void useCacheSizes(size_t sizes[], size_t length); + + void start(); + void stop(); + SimpleString report(); + SimpleString reportWithCacheSizes(size_t sizes[], size_t length); + + TestMemoryAllocator* getMallocAllocator(); + TestMemoryAllocator* getNewAllocator(); + TestMemoryAllocator* getNewArrayAllocator(); + +private: + + void restoreMemoryAllocators(); + + MemoryAccountant accountant_; + AccountingTestMemoryAllocator* mallocAllocator_; + AccountingTestMemoryAllocator* newAllocator_; + AccountingTestMemoryAllocator* newArrayAllocator_; +}; + +#endif + diff --git a/test/test_utility/include/CppUTest/TestOutput.h b/test/test_utility/include/CppUTest/TestOutput.h new file mode 100644 index 0000000..dff6e0a --- /dev/null +++ b/test/test_utility/include/CppUTest/TestOutput.h @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the 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 EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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 D_TestOutput_h +#define D_TestOutput_h + +/////////////////////////////////////////////////////////////////////////////// +// +// This is a minimal printer interface. +// We kept streams out to keep footprint small, and so the test +// harness could be used with less capable compilers so more +// platforms could use this test harness +// +/////////////////////////////////////////////////////////////////////////////// + +#include "SimpleString.h" + +class UtestShell; +class TestFailure; +class TestResult; + +class TestOutput +{ +public: + enum WorkingEnvironment {visualStudio, eclipse, detectEnvironment}; + enum VerbosityLevel {level_quiet, level_verbose, level_veryVerbose}; + + explicit TestOutput(); + virtual ~TestOutput(); + + virtual void printTestsStarted(); + virtual void printTestsEnded(const TestResult& result); + virtual void printCurrentTestStarted(const UtestShell& test); + virtual void printCurrentTestEnded(const TestResult& res); + virtual void printCurrentGroupStarted(const UtestShell& test); + virtual void printCurrentGroupEnded(const TestResult& res); + + virtual void verbose(VerbosityLevel level); + virtual void color(); + virtual void printBuffer(const char*)=0; + virtual void print(const char*); + virtual void print(long); + virtual void print(size_t); + virtual void printDouble(double); + virtual void printFailure(const TestFailure& failure); + virtual void printTestRun(size_t number, size_t total); + virtual void setProgressIndicator(const char*); + + virtual void printVeryVerbose(const char*); + + virtual void flush()=0; + + static void setWorkingEnvironment(WorkingEnvironment workEnvironment); + static WorkingEnvironment getWorkingEnvironment(); + +protected: + + virtual void printEclipseErrorInFileOnLine(SimpleString file, size_t lineNumber); + virtual void printVisualStudioErrorInFileOnLine(SimpleString file, size_t lineNumber); + + virtual void printProgressIndicator(); + void printFileAndLineForTestAndFailure(const TestFailure& failure); + void printFileAndLineForFailure(const TestFailure& failure); + void printFailureInTest(SimpleString testName); + void printFailureMessage(SimpleString reason); + void printErrorInFileOnLineFormattedForWorkingEnvironment(SimpleString testFile, size_t lineNumber); + + TestOutput(const TestOutput&); + TestOutput& operator=(const TestOutput&); + + int dotCount_; + VerbosityLevel verbose_; + bool color_; + const char* progressIndication_; + + static WorkingEnvironment workingEnvironment_; +}; + +TestOutput& operator<<(TestOutput&, const char*); +TestOutput& operator<<(TestOutput&, long); + +/////////////////////////////////////////////////////////////////////////////// +// +// ConsoleTestOutput.h +// +// Printf Based Solution +// +/////////////////////////////////////////////////////////////////////////////// + +class ConsoleTestOutput: public TestOutput +{ +public: + explicit ConsoleTestOutput() + { + } + virtual ~ConsoleTestOutput() _destructor_override + { + } + + virtual void printBuffer(const char* s) _override; + virtual void flush() _override; + +private: + ConsoleTestOutput(const ConsoleTestOutput&); + ConsoleTestOutput& operator=(const ConsoleTestOutput&); +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// StringBufferTestOutput.h +// +// TestOutput for test purposes +// +/////////////////////////////////////////////////////////////////////////////// + + +class StringBufferTestOutput: public TestOutput +{ +public: + explicit StringBufferTestOutput() + { + } + + virtual ~StringBufferTestOutput() _destructor_override; + + void printBuffer(const char* s) _override + { + output += s; + } + + void flush() _override + { + output = ""; + } + + const SimpleString& getOutput() + { + return output; + } + +protected: + SimpleString output; + +private: + StringBufferTestOutput(const StringBufferTestOutput&); + StringBufferTestOutput& operator=(const StringBufferTestOutput&); + +}; + +class CompositeTestOutput : public TestOutput +{ +public: + virtual void setOutputOne(TestOutput* output); + virtual void setOutputTwo(TestOutput* output); + + CompositeTestOutput(); + virtual ~CompositeTestOutput() _destructor_override; + + virtual void printTestsStarted() _override; + virtual void printTestsEnded(const TestResult& result) _override; + + virtual void printCurrentTestStarted(const UtestShell& test) _override; + virtual void printCurrentTestEnded(const TestResult& res) _override; + virtual void printCurrentGroupStarted(const UtestShell& test) _override; + virtual void printCurrentGroupEnded(const TestResult& res) _override; + + virtual void verbose(VerbosityLevel level) _override; + virtual void color() _override; + virtual void printBuffer(const char*) _override; + virtual void print(const char*) _override; + virtual void print(long) _override; + virtual void print(size_t) _override; + virtual void printDouble(double) _override; + virtual void printFailure(const TestFailure& failure) _override; + virtual void setProgressIndicator(const char*) _override; + + virtual void flush() _override; + +protected: + CompositeTestOutput(const TestOutput&); + CompositeTestOutput& operator=(const TestOutput&); + +private: + TestOutput* outputOne_; + TestOutput* outputTwo_; +}; + +#endif diff --git a/test/test_utility/include/CppUTest/TestPlugin.h b/test/test_utility/include/CppUTest/TestPlugin.h new file mode 100644 index 0000000..2b2ed93 --- /dev/null +++ b/test/test_utility/include/CppUTest/TestPlugin.h @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the 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 EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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 D_TestPlugin_h +#define D_TestPlugin_h + +class UtestShell; +class TestResult; + +class TestPlugin +{ +public: + + TestPlugin(const SimpleString& name); + virtual ~TestPlugin(); + + virtual void preTestAction(UtestShell&, TestResult&) + { + } + + virtual void postTestAction(UtestShell&, TestResult&) + { + } + + virtual bool parseArguments(int /* ac */, const char *const * /* av */, int /* index */ ) + { + return false; + } + + virtual void runAllPreTestAction(UtestShell&, TestResult&); + virtual void runAllPostTestAction(UtestShell&, TestResult&); + virtual bool parseAllArguments(int ac, const char *const *av, int index); + virtual bool parseAllArguments(int ac, char** av, int index); + + virtual TestPlugin* addPlugin(TestPlugin*); + virtual TestPlugin* removePluginByName(const SimpleString& name); + virtual TestPlugin* getNext(); + + virtual void disable(); + virtual void enable(); + virtual bool isEnabled(); + + const SimpleString& getName(); + TestPlugin* getPluginByName(const SimpleString& name); + +protected: + TestPlugin(TestPlugin* next_); + +private: + TestPlugin* next_; + SimpleString name_; + bool enabled_; +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// SetPointerPlugin +// +// This is a very small plugin_ that resets pointers to their original value. +// +/////////////////////////////////////////////////////////////////////////////// + +extern void CppUTestStore(void **location); + +class SetPointerPlugin: public TestPlugin +{ +public: + SetPointerPlugin(const SimpleString& name); + virtual void postTestAction(UtestShell&, TestResult&) _override; + + enum + { + MAX_SET = 32 + }; +}; + +#define UT_PTR_SET(a, b) do { CppUTestStore( (void**)&a ); a = b; } while(0) + +///////////// Null Plugin + +class NullTestPlugin: public TestPlugin +{ +public: + + NullTestPlugin(); + + virtual void runAllPreTestAction(UtestShell& test, TestResult& result) _override; + virtual void runAllPostTestAction(UtestShell& test, TestResult& result) _override; + + static NullTestPlugin* instance(); +}; + +#endif diff --git a/test/test_utility/include/CppUTest/TestRegistry.h b/test/test_utility/include/CppUTest/TestRegistry.h new file mode 100644 index 0000000..e57e52c --- /dev/null +++ b/test/test_utility/include/CppUTest/TestRegistry.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the 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 EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/////////////////////////////////////////////////////////////////////////////// +// +// TestRegistry is a collection of tests that can be run +// + +#ifndef D_TestRegistry_h +#define D_TestRegistry_h + +#include "StandardCLibrary.h" +#include "SimpleString.h" +#include "TestFilter.h" + +class UtestShell; +class TestResult; +class TestPlugin; + +class TestRegistry +{ +public: + TestRegistry(); + virtual ~TestRegistry(); + + virtual void addTest(UtestShell *test); + virtual void unDoLastAddTest(); + virtual size_t countTests(); + virtual void runAllTests(TestResult& result); + virtual void shuffleTests(size_t seed); + virtual void reverseTests(); + virtual void listTestGroupNames(TestResult& result); + virtual void listTestGroupAndCaseNames(TestResult& result); + virtual void listTestLocations(TestResult& result); + virtual void setNameFilters(const TestFilter* filters); + virtual void setGroupFilters(const TestFilter* filters); + virtual void installPlugin(TestPlugin* plugin); + virtual void resetPlugins(); + virtual TestPlugin* getFirstPlugin(); + virtual TestPlugin* getPluginByName(const SimpleString& name); + virtual void removePluginByName(const SimpleString& name); + virtual int countPlugins(); + + virtual UtestShell* getFirstTest(); + virtual UtestShell* getTestWithNext(UtestShell* test); + + virtual UtestShell* findTestWithName(const SimpleString& name); + virtual UtestShell* findTestWithGroup(const SimpleString& name); + + static TestRegistry* getCurrentRegistry(); + virtual void setCurrentRegistry(TestRegistry* registry); + + virtual void setRunTestsInSeperateProcess(); + int getCurrentRepetition(); + void setRunIgnored(); + +private: + + bool testShouldRun(UtestShell* test, TestResult& result); + bool endOfGroup(UtestShell* test); + + UtestShell * tests_; + const TestFilter* nameFilters_; + const TestFilter* groupFilters_; + TestPlugin* firstPlugin_; + static TestRegistry* currentRegistry_; + bool runInSeperateProcess_; + int currentRepetition_; + bool runIgnored_; +}; + +#endif diff --git a/test/test_utility/include/CppUTest/TestResult.h b/test/test_utility/include/CppUTest/TestResult.h new file mode 100644 index 0000000..62c4f77 --- /dev/null +++ b/test/test_utility/include/CppUTest/TestResult.h @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the 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 EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/////////////////////////////////////////////////////////////////////////////// +// +// A TestResult is a collection of the history of some test runs. Right now +// it just collects failures. Really it just prints the failures. +// + +#ifndef D_TestResult_h +#define D_TestResult_h + +class TestFailure; +class TestOutput; +class UtestShell; + +class TestResult +{ +public: + TestResult(TestOutput&); + DEFAULT_COPY_CONSTRUCTOR(TestResult) + virtual ~TestResult(); + + virtual void testsStarted(); + virtual void testsEnded(); + virtual void currentGroupStarted(UtestShell* test); + virtual void currentGroupEnded(UtestShell* test); + virtual void currentTestStarted(UtestShell* test); + virtual void currentTestEnded(UtestShell* test); + + virtual void countTest(); + virtual void countRun(); + virtual void countCheck(); + virtual void countFilteredOut(); + virtual void countIgnored(); + virtual void addFailure(const TestFailure& failure); + virtual void print(const char* text); + virtual void printVeryVerbose(const char* text); + + size_t getTestCount() const + { + return testCount_; + } + size_t getRunCount() const + { + return runCount_; + } + size_t getCheckCount() const + { + return checkCount_; + } + size_t getFilteredOutCount() const + { + return filteredOutCount_; + } + size_t getIgnoredCount() const + { + return ignoredCount_; + } + size_t getFailureCount() const + { + return failureCount_; + } + + bool isFailure() const + { + return (getFailureCount() != 0) || (getRunCount() + getIgnoredCount() == 0); + } + + size_t getTotalExecutionTime() const; + void setTotalExecutionTime(size_t exTime); + + size_t getCurrentTestTotalExecutionTime() const; + size_t getCurrentGroupTotalExecutionTime() const; +private: + + TestOutput& output_; + size_t testCount_; + size_t runCount_; + size_t checkCount_; + size_t failureCount_; + size_t filteredOutCount_; + size_t ignoredCount_; + size_t totalExecutionTime_; + size_t timeStarted_; + size_t currentTestTimeStarted_; + size_t currentTestTotalExecutionTime_; + size_t currentGroupTimeStarted_; + size_t currentGroupTotalExecutionTime_; +}; + +#endif diff --git a/test/test_utility/include/CppUTest/TestTestingFixture.h b/test/test_utility/include/CppUTest/TestTestingFixture.h new file mode 100644 index 0000000..17d12d0 --- /dev/null +++ b/test/test_utility/include/CppUTest/TestTestingFixture.h @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the 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 EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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 D_TestTestingFixture_H +#define D_TestTestingFixture_H + +#include "TestRegistry.h" +#include "TestOutput.h" + +class TestTestingFixture +{ +public: + + TestTestingFixture(); + virtual ~TestTestingFixture(); + void flushOutputAndResetResult(); + + void addTest(UtestShell * test); + void installPlugin(TestPlugin* plugin); + + void setTestFunction(void(*testFunction)()); + void setTestFunction(ExecFunction* testFunction); + void setSetup(void(*setupFunction)()); + void setTeardown(void(*teardownFunction)()); + + void setOutputVerbose(); + void setRunTestsInSeperateProcess(); + + void runTestWithMethod(void(*method)()); + void runAllTests(); + + size_t getFailureCount(); + size_t getCheckCount(); + size_t getIgnoreCount(); + size_t getRunCount(); + size_t getTestCount(); + const SimpleString& getOutput(); + TestRegistry* getRegistry(); + + bool hasTestFailed(); + void assertPrintContains(const SimpleString& contains); + void assertPrintContainsNot(const SimpleString& contains); + void checkTestFailsWithProperTestLocation(const char* text, const char* file, size_t line); + + static void lineExecutedAfterCheck(); + +private: + void clearExecFunction(); + + static bool lineOfCodeExecutedAfterCheck; + + TestRegistry* registry_; + ExecFunctionTestShell* genTest_; + bool ownsExecFunction_; + StringBufferTestOutput* output_; + TestResult * result_; +}; + +class SetBooleanOnDestructorCall +{ + bool& booleanToSet_; +public: + SetBooleanOnDestructorCall(bool& booleanToSet) : booleanToSet_(booleanToSet) + { + } + + virtual ~SetBooleanOnDestructorCall() + { + booleanToSet_ = true; + } +}; + +#endif diff --git a/test/test_utility/include/CppUTest/Utest.h b/test/test_utility/include/CppUTest/Utest.h new file mode 100644 index 0000000..b100355 --- /dev/null +++ b/test/test_utility/include/CppUTest/Utest.h @@ -0,0 +1,322 @@ +/* + * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the 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 EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// This file contains the Test class along with the macros which make effective +// in the harness. + +#ifndef D_UTest_h +#define D_UTest_h + +#include "SimpleString.h" + +class TestResult; +class TestPlugin; +class TestFailure; +class TestFilter; +class TestTerminator; + +extern bool doubles_equal(double d1, double d2, double threshold); + +//////////////////// Utest + +class UtestShell; + +class Utest +{ +public: + Utest(); + virtual ~Utest(); + virtual void run(); + + virtual void setup(); + virtual void teardown(); + virtual void testBody(); +}; + +//////////////////// TestTerminator + +class TestTerminator +{ +public: + virtual void exitCurrentTest() const=0; + virtual ~TestTerminator(); +}; + +class NormalTestTerminator : public TestTerminator +{ +public: + virtual void exitCurrentTest() const _override; + virtual ~NormalTestTerminator() _destructor_override; +}; + +class TestTerminatorWithoutExceptions : public TestTerminator +{ +public: + virtual void exitCurrentTest() const _override; + virtual ~TestTerminatorWithoutExceptions() _destructor_override; +}; + +class CrashingTestTerminator : public NormalTestTerminator +{ +public: + virtual void exitCurrentTest() const _override; + virtual ~CrashingTestTerminator() _destructor_override; +}; + +//////////////////// UtestShell + +class UtestShell +{ +public: + static UtestShell *getCurrent(); + + static const TestTerminator &getCurrentTestTerminator(); + + static void setCrashOnFail(); + static void restoreDefaultTestTerminator(); + +public: + UtestShell(const char* groupName, const char* testName, const char* fileName, size_t lineNumber); + virtual ~UtestShell(); + + virtual UtestShell* addTest(UtestShell* test); + virtual UtestShell *getNext() const; + virtual size_t countTests(); + + bool shouldRun(const TestFilter* groupFilters, const TestFilter* nameFilters) const; + const SimpleString getName() const; + const SimpleString getGroup() const; + virtual SimpleString getFormattedName() const; + const SimpleString getFile() const; + size_t getLineNumber() const; + virtual bool willRun() const; + virtual bool hasFailed() const; + void countCheck(); + + virtual void assertTrue(bool condition, const char *checkString, const char *conditionString, const char* text, const char *fileName, size_t lineNumber, const TestTerminator& testTerminator = getCurrentTestTerminator()); + virtual void assertCstrEqual(const char *expected, const char *actual, const char* text, const char *fileName, size_t lineNumber, const TestTerminator& testTerminator = getCurrentTestTerminator()); + virtual void assertCstrNEqual(const char *expected, const char *actual, size_t length, const char* text, const char *fileName, size_t lineNumber, const TestTerminator& testTerminator = getCurrentTestTerminator()); + virtual void assertCstrNoCaseEqual(const char *expected, const char *actual, const char* text, const char *fileName, size_t lineNumber); + virtual void assertCstrContains(const char *expected, const char *actual, const char* text, const char *fileName, size_t lineNumber); + virtual void assertCstrNoCaseContains(const char *expected, const char *actual, const char* text, const char *fileName, size_t lineNumber); + virtual void assertLongsEqual(long expected, long actual, const char* text, const char *fileName, size_t lineNumber, const TestTerminator& testTerminator = getCurrentTestTerminator()); + virtual void assertUnsignedLongsEqual(unsigned long expected, unsigned long actual, const char* text, const char *fileName, size_t lineNumber, const TestTerminator& testTerminator = getCurrentTestTerminator()); + virtual void assertLongLongsEqual(cpputest_longlong expected, cpputest_longlong actual, const char* text, const char *fileName, size_t lineNumber, const TestTerminator& testTerminator = getCurrentTestTerminator()); + virtual void assertUnsignedLongLongsEqual(cpputest_ulonglong expected, cpputest_ulonglong actual, const char* text, const char *fileName, size_t lineNumber, const TestTerminator& testTerminator = getCurrentTestTerminator()); + virtual void assertSignedBytesEqual(signed char expected, signed char actual, const char* text, const char *fileName, size_t lineNumber, const TestTerminator& testTerminator = getCurrentTestTerminator()); + virtual void assertPointersEqual(const void *expected, const void *actual, const char* text, const char *fileName, size_t lineNumber, const TestTerminator& testTerminator = getCurrentTestTerminator()); + virtual void assertFunctionPointersEqual(void (*expected)(), void (*actual)(), const char* text, const char* fileName, size_t lineNumber, const TestTerminator& testTerminator = getCurrentTestTerminator()); + virtual void assertDoublesEqual(double expected, double actual, double threshold, const char* text, const char *fileName, size_t lineNumber, const TestTerminator& testTerminator = getCurrentTestTerminator()); + virtual void assertEquals(bool failed, const char* expected, const char* actual, const char* text, const char* file, size_t lineNumber, const TestTerminator& testTerminator = getCurrentTestTerminator()); + virtual void assertBinaryEqual(const void *expected, const void *actual, size_t length, const char* text, const char *fileName, size_t lineNumber, const TestTerminator& testTerminator = getCurrentTestTerminator()); + virtual void assertBitsEqual(unsigned long expected, unsigned long actual, unsigned long mask, size_t byteCount, const char* text, const char *fileName, size_t lineNumber, const TestTerminator& testTerminator = getCurrentTestTerminator()); + virtual void assertCompare(bool comparison, const char *checkString, const char *comparisonString, const char *text, const char *fileName, size_t lineNumber, const TestTerminator& testTerminator = getCurrentTestTerminator()); + virtual void fail(const char *text, const char *fileName, size_t lineNumber, const TestTerminator& testTerminator = getCurrentTestTerminator()); + virtual void exitTest(const TestTerminator& testTerminator = getCurrentTestTerminator()); + + virtual void print(const char *text, const char *fileName, size_t lineNumber); + virtual void print(const SimpleString & text, const char *fileName, size_t lineNumber); + virtual void printVeryVerbose(const char* text); + + void setFileName(const char *fileName); + void setLineNumber(size_t lineNumber); + void setGroupName(const char *groupName); + void setTestName(const char *testName); + + static void crash(); + static void setCrashMethod(void (*crashme)()); + static void resetCrashMethod(); + + virtual bool isRunInSeperateProcess() const; + virtual void setRunInSeperateProcess(); + + virtual void setRunIgnored(); + + virtual Utest* createTest(); + virtual void destroyTest(Utest* test); + + virtual void runOneTest(TestPlugin* plugin, TestResult& result); + virtual void runOneTestInCurrentProcess(TestPlugin *plugin, TestResult & result); + + virtual void failWith(const TestFailure& failure); + virtual void failWith(const TestFailure& failure, const TestTerminator& terminator); + +protected: + UtestShell(); + UtestShell(const char *groupName, const char *testName, const char *fileName, size_t lineNumber, UtestShell *nextTest); + + virtual SimpleString getMacroName() const; + TestResult *getTestResult(); +private: + const char *group_; + const char *name_; + const char *file_; + size_t lineNumber_; + UtestShell *next_; + bool isRunAsSeperateProcess_; + bool hasFailed_; + + void setTestResult(TestResult* result); + void setCurrentTest(UtestShell* test); + bool match(const char* target, const TestFilter* filters) const; + + static UtestShell* currentTest_; + static TestResult* testResult_; + + static const TestTerminator *currentTestTerminator_; +}; + + + +//////////////////// ExecFunctionTest + +class ExecFunctionTestShell; + +class ExecFunctionTest : public Utest +{ +public: + ExecFunctionTest(ExecFunctionTestShell* shell); + void testBody() _override; + virtual void setup() _override; + virtual void teardown() _override; +private: + ExecFunctionTestShell* shell_; +}; + +//////////////////// ExecFunction + +class ExecFunction +{ +public: + ExecFunction(); + virtual ~ExecFunction(); + + virtual void exec()=0; +}; + +class ExecFunctionWithoutParameters : public ExecFunction +{ +public: + void (*testFunction_)(); + + ExecFunctionWithoutParameters(void(*testFunction)()); + virtual ~ExecFunctionWithoutParameters() _destructor_override; + + virtual void exec() _override; +}; + +//////////////////// ExecFunctionTestShell + +class ExecFunctionTestShell : public UtestShell +{ +public: + void (*setup_)(); + void (*teardown_)(); + ExecFunction* testFunction_; + + ExecFunctionTestShell(void(*set)() = NULLPTR, void(*tear)() = NULLPTR) : + UtestShell("ExecFunction", "ExecFunction", "ExecFunction", 1), setup_(set), teardown_(tear), testFunction_(NULLPTR) + { + } + + Utest* createTest() _override { return new ExecFunctionTest(this); } + virtual ~ExecFunctionTestShell() _destructor_override; +}; + +//////////////////// CppUTestFailedException + +class CppUTestFailedException +{ +public: + int dummy_; +}; + +//////////////////// IgnoredTest + +class IgnoredUtestShell : public UtestShell +{ +public: + IgnoredUtestShell(); + virtual ~IgnoredUtestShell() _destructor_override; + explicit IgnoredUtestShell(const char* groupName, const char* testName, + const char* fileName, size_t lineNumber); + virtual bool willRun() const _override; + virtual void setRunIgnored() _override; +protected: + virtual SimpleString getMacroName() const _override; + virtual void runOneTest(TestPlugin* plugin, TestResult& result) _override; +private: + + IgnoredUtestShell(const IgnoredUtestShell&); + IgnoredUtestShell& operator=(const IgnoredUtestShell&); + + bool runIgnored_; + +}; + +//////////////////// UtestShellPointerArray + +class UtestShellPointerArray +{ +public: + UtestShellPointerArray(UtestShell* firstTest); + ~UtestShellPointerArray(); + + void shuffle(size_t seed); + void reverse(); + void relinkTestsInOrder(); + UtestShell* getFirstTest() const; + UtestShell* get(size_t index) const; + +private: + + void swap(size_t index1, size_t index2); + + UtestShell** arrayOfTests_; + size_t count_; +}; + + +//////////////////// TestInstaller + +class TestInstaller +{ +public: + explicit TestInstaller(UtestShell& shell, const char* groupName, const char* testName, + const char* fileName, size_t lineNumber); + virtual ~TestInstaller(); + + void unDo(); + +private: + + TestInstaller(const TestInstaller&); + TestInstaller& operator=(const TestInstaller&); + +}; + +#endif diff --git a/test/test_utility/include/CppUTest/UtestMacros.h b/test/test_utility/include/CppUTest/UtestMacros.h new file mode 100644 index 0000000..e9ef5c6 --- /dev/null +++ b/test/test_utility/include/CppUTest/UtestMacros.h @@ -0,0 +1,384 @@ +/* + * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the 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 EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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 D_UTestMacros_h +#define D_UTestMacros_h + +/*! \brief Define a group of tests + * + * All tests in a TEST_GROUP share the same setup() + * and teardown(). setup() is run before the opening + * curly brace of each TEST and teardown() is + * called after the closing curly brace of TEST. + * + */ + + +#define TEST_GROUP_BASE(testGroup, baseclass) \ + extern int externTestGroup##testGroup; \ + int externTestGroup##testGroup = 0; \ + struct TEST_GROUP_##CppUTestGroup##testGroup : public baseclass + +#define TEST_BASE(testBaseClass) \ + struct testBaseClass : public Utest + +#define TEST_GROUP(testGroup) \ + TEST_GROUP_BASE(testGroup, Utest) + +#define TEST_SETUP() \ + virtual void setup() _override + +#define TEST_TEARDOWN() \ + virtual void teardown() _override + +#define TEST(testGroup, testName) \ + /* External declarations for strict compilers */ \ + class TEST_##testGroup##_##testName##_TestShell; \ + extern TEST_##testGroup##_##testName##_TestShell TEST_##testGroup##_##testName##_TestShell_instance; \ + \ + class TEST_##testGroup##_##testName##_Test : public TEST_GROUP_##CppUTestGroup##testGroup \ +{ public: TEST_##testGroup##_##testName##_Test () : TEST_GROUP_##CppUTestGroup##testGroup () {} \ + void testBody() _override; }; \ + class TEST_##testGroup##_##testName##_TestShell : public UtestShell { \ + virtual Utest* createTest() _override { return new TEST_##testGroup##_##testName##_Test; } \ + } TEST_##testGroup##_##testName##_TestShell_instance; \ + static TestInstaller TEST_##testGroup##_##testName##_Installer(TEST_##testGroup##_##testName##_TestShell_instance, #testGroup, #testName, __FILE__,__LINE__); \ + void TEST_##testGroup##_##testName##_Test::testBody() + +#define IGNORE_TEST(testGroup, testName)\ + /* External declarations for strict compilers */ \ + class IGNORE##testGroup##_##testName##_TestShell; \ + extern IGNORE##testGroup##_##testName##_TestShell IGNORE##testGroup##_##testName##_TestShell_instance; \ + \ + class IGNORE##testGroup##_##testName##_Test : public TEST_GROUP_##CppUTestGroup##testGroup \ +{ public: IGNORE##testGroup##_##testName##_Test () : TEST_GROUP_##CppUTestGroup##testGroup () {} \ + public: void testBody() _override; }; \ + class IGNORE##testGroup##_##testName##_TestShell : public IgnoredUtestShell { \ + virtual Utest* createTest() _override { return new IGNORE##testGroup##_##testName##_Test; } \ + } IGNORE##testGroup##_##testName##_TestShell_instance; \ + static TestInstaller TEST_##testGroup##testName##_Installer(IGNORE##testGroup##_##testName##_TestShell_instance, #testGroup, #testName, __FILE__,__LINE__); \ + void IGNORE##testGroup##_##testName##_Test::testBody () + +#define IMPORT_TEST_GROUP(testGroup) \ + extern int externTestGroup##testGroup;\ + extern int* p##testGroup; \ + int* p##testGroup = &externTestGroup##testGroup + +#define CPPUTEST_DEFAULT_MAIN \ + /*#include */ \ + int main(int argc, char** argv) \ + { \ + return CommandLineTestRunner::RunAllTests(argc, argv); \ + } + + +// Different checking macros + +#define CHECK(condition)\ + CHECK_TRUE_LOCATION(condition, "CHECK", #condition, NULLPTR, __FILE__, __LINE__) + +#define CHECK_TEXT(condition, text) \ + CHECK_TRUE_LOCATION((bool)(condition), "CHECK", #condition, text, __FILE__, __LINE__) + +#define CHECK_TRUE(condition)\ + CHECK_TRUE_LOCATION((bool) (condition), "CHECK_TRUE", #condition, NULLPTR, __FILE__, __LINE__) + +#define CHECK_TRUE_TEXT(condition, text)\ + CHECK_TRUE_LOCATION(condition, "CHECK_TRUE", #condition, text, __FILE__, __LINE__) + +#define CHECK_FALSE(condition)\ + CHECK_FALSE_LOCATION(condition, "CHECK_FALSE", #condition, NULLPTR, __FILE__, __LINE__) + +#define CHECK_FALSE_TEXT(condition, text)\ + CHECK_FALSE_LOCATION(condition, "CHECK_FALSE", #condition, text, __FILE__, __LINE__) + +#define CHECK_TRUE_LOCATION(condition, checkString, conditionString, text, file, line)\ + do { UtestShell::getCurrent()->assertTrue((condition), checkString, conditionString, text, file, line); } while(0) + +#define CHECK_FALSE_LOCATION(condition, checkString, conditionString, text, file, line)\ + do { UtestShell::getCurrent()->assertTrue(!(condition), checkString, conditionString, text, file, line); } while(0) + +//This check needs the operator!=(), and a StringFrom(YourType) function +#define CHECK_EQUAL(expected, actual)\ + CHECK_EQUAL_LOCATION(expected, actual, NULLPTR, __FILE__, __LINE__) + +#define CHECK_EQUAL_TEXT(expected, actual, text)\ + CHECK_EQUAL_LOCATION(expected, actual, text, __FILE__, __LINE__) + +#define CHECK_EQUAL_LOCATION(expected, actual, text, file, line)\ + do { if ((expected) != (actual)) { \ + if ((actual) != (actual)) \ + UtestShell::getCurrent()->print("WARNING:\n\tThe \"Actual Parameter\" parameter is evaluated multiple times resulting in different values.\n\tThus the value in the error message is probably incorrect.", file, line); \ + if ((expected) != (expected)) \ + UtestShell::getCurrent()->print("WARNING:\n\tThe \"Expected Parameter\" parameter is evaluated multiple times resulting in different values.\n\tThus the value in the error message is probably incorrect.", file, line); \ + UtestShell::getCurrent()->assertEquals(true, StringFrom(expected).asCharString(), StringFrom(actual).asCharString(), text, file, line); \ + } \ + else \ + { \ + UtestShell::getCurrent()->assertLongsEqual((long)0, (long)0, NULLPTR, file, line); \ + } } while(0) + +#define CHECK_EQUAL_ZERO(actual) CHECK_EQUAL(0, (actual)) + +#define CHECK_EQUAL_ZERO_TEXT(actual, text) CHECK_EQUAL_TEXT(0, (actual), (text)) + +#define CHECK_COMPARE(first, relop, second)\ + CHECK_COMPARE_TEXT(first, relop, second, NULLPTR) + +#define CHECK_COMPARE_TEXT(first, relop, second, text)\ + CHECK_COMPARE_LOCATION(first, relop, second, text, __FILE__, __LINE__) + +#define CHECK_COMPARE_LOCATION(first, relop, second, text, file, line)\ + do { SimpleString conditionString;\ + conditionString += StringFrom(first); conditionString += " ";\ + conditionString += #relop; conditionString += " ";\ + conditionString += StringFrom(second);\ + UtestShell::getCurrent()->assertCompare((first) relop (second), "CHECK_COMPARE", conditionString.asCharString(), text, __FILE__, __LINE__);\ + } while(0) + +//This check checks for char* string equality using strcmp. +//This makes up for the fact that CHECK_EQUAL only compares the pointers to char*'s +#define STRCMP_EQUAL(expected, actual)\ + STRCMP_EQUAL_LOCATION(expected, actual, NULLPTR, __FILE__, __LINE__) + +#define STRCMP_EQUAL_TEXT(expected, actual, text)\ + STRCMP_EQUAL_LOCATION(expected, actual, text, __FILE__, __LINE__) + +#define STRCMP_EQUAL_LOCATION(expected, actual, text, file, line)\ + do { UtestShell::getCurrent()->assertCstrEqual(expected, actual, text, file, line); } while(0) + +#define STRNCMP_EQUAL(expected, actual, length)\ + STRNCMP_EQUAL_LOCATION(expected, actual, length, NULLPTR, __FILE__, __LINE__) + +#define STRNCMP_EQUAL_TEXT(expected, actual, length, text)\ + STRNCMP_EQUAL_LOCATION(expected, actual, length, text, __FILE__, __LINE__) + +#define STRNCMP_EQUAL_LOCATION(expected, actual, length, text, file, line)\ + do { UtestShell::getCurrent()->assertCstrNEqual(expected, actual, length, text, file, line); } while(0) + +#define STRCMP_NOCASE_EQUAL(expected, actual)\ + STRCMP_NOCASE_EQUAL_LOCATION(expected, actual, NULLPTR, __FILE__, __LINE__) + +#define STRCMP_NOCASE_EQUAL_TEXT(expected, actual, text)\ + STRCMP_NOCASE_EQUAL_LOCATION(expected, actual, text, __FILE__, __LINE__) + +#define STRCMP_NOCASE_EQUAL_LOCATION(expected, actual, text, file, line)\ + do { UtestShell::getCurrent()->assertCstrNoCaseEqual(expected, actual, text, file, line); } while(0) + +#define STRCMP_CONTAINS(expected, actual)\ + STRCMP_CONTAINS_LOCATION(expected, actual, NULLPTR, __FILE__, __LINE__) + +#define STRCMP_CONTAINS_TEXT(expected, actual, text)\ + STRCMP_CONTAINS_LOCATION(expected, actual, text, __FILE__, __LINE__) + +#define STRCMP_CONTAINS_LOCATION(expected, actual, text, file, line)\ + do { UtestShell::getCurrent()->assertCstrContains(expected, actual, text, file, line); } while(0) + +#define STRCMP_NOCASE_CONTAINS(expected, actual)\ + STRCMP_NOCASE_CONTAINS_LOCATION(expected, actual, NULLPTR, __FILE__, __LINE__) + +#define STRCMP_NOCASE_CONTAINS_TEXT(expected, actual, text)\ + STRCMP_NOCASE_CONTAINS_LOCATION(expected, actual, text, __FILE__, __LINE__) + +#define STRCMP_NOCASE_CONTAINS_LOCATION(expected, actual, text, file, line)\ + do { UtestShell::getCurrent()->assertCstrNoCaseContains(expected, actual, text, file, line); } while(0) + +//Check two long integers for equality +#define LONGS_EQUAL(expected, actual)\ + LONGS_EQUAL_LOCATION((expected), (actual), "LONGS_EQUAL(" #expected ", " #actual ") failed", __FILE__, __LINE__) + +#define LONGS_EQUAL_TEXT(expected, actual, text)\ + LONGS_EQUAL_LOCATION((expected), (actual), text, __FILE__, __LINE__) + +#define UNSIGNED_LONGS_EQUAL(expected, actual)\ + UNSIGNED_LONGS_EQUAL_LOCATION((expected), (actual), NULLPTR, __FILE__, __LINE__) + +#define UNSIGNED_LONGS_EQUAL_TEXT(expected, actual, text)\ + UNSIGNED_LONGS_EQUAL_LOCATION((expected), (actual), text, __FILE__, __LINE__) + +#define LONGS_EQUAL_LOCATION(expected, actual, text, file, line)\ + do { UtestShell::getCurrent()->assertLongsEqual((long)expected, (long)actual, text, file, line); } while(0) + +#define UNSIGNED_LONGS_EQUAL_LOCATION(expected, actual, text, file, line)\ + do { UtestShell::getCurrent()->assertUnsignedLongsEqual((unsigned long)expected, (unsigned long)actual, text, file, line); } while(0) + +#define LONGLONGS_EQUAL(expected, actual)\ + LONGLONGS_EQUAL_LOCATION(expected, actual, NULLPTR, __FILE__, __LINE__) + +#define LONGLONGS_EQUAL_TEXT(expected, actual, text)\ + LONGLONGS_EQUAL_LOCATION(expected, actual, text, __FILE__, __LINE__) + +#define UNSIGNED_LONGLONGS_EQUAL(expected, actual)\ + UNSIGNED_LONGLONGS_EQUAL_LOCATION(expected, actual, NULLPTR, __FILE__, __LINE__) + +#define UNSIGNED_LONGLONGS_EQUAL_TEXT(expected, actual, text)\ + UNSIGNED_LONGLONGS_EQUAL_LOCATION(expected, actual, text, __FILE__, __LINE__) + +#define LONGLONGS_EQUAL_LOCATION(expected, actual, text, file, line)\ + do { UtestShell::getCurrent()->assertLongLongsEqual((long long)expected, (long long)actual, text, file, line); } while(0) + +#define UNSIGNED_LONGLONGS_EQUAL_LOCATION(expected, actual, text, file, line)\ + do { UtestShell::getCurrent()->assertUnsignedLongLongsEqual((unsigned long long)expected, (unsigned long long)actual, text, file, line); } while(0) + +#define BYTES_EQUAL(expected, actual)\ + LONGS_EQUAL((expected) & 0xff,(actual) & 0xff) + +#define BYTES_EQUAL_TEXT(expected, actual, text)\ + LONGS_EQUAL_TEXT((expected) & 0xff, (actual) & 0xff, text) + +#define SIGNED_BYTES_EQUAL(expected, actual)\ + SIGNED_BYTES_EQUAL_LOCATION(expected, actual, __FILE__, __LINE__) + +#define SIGNED_BYTES_EQUAL_LOCATION(expected, actual, file, line) \ + do { UtestShell::getCurrent()->assertSignedBytesEqual(expected, actual, NULLPTR, file, line); } while(0) + +#define SIGNED_BYTES_EQUAL_TEXT(expected, actual, text)\ + SIGNED_BYTES_EQUAL_TEXT_LOCATION(expected, actual, text, __FILE__, __LINE__) + +#define SIGNED_BYTES_EQUAL_TEXT_LOCATION(expected, actual, text, file, line) \ + do { UtestShell::getCurrent()->assertSignedBytesEqual(expected, actual, text, file, line); } while(0) + +#define POINTERS_EQUAL(expected, actual)\ + POINTERS_EQUAL_LOCATION((expected), (actual), NULLPTR, __FILE__, __LINE__) + +#define POINTERS_EQUAL_TEXT(expected, actual, text)\ + POINTERS_EQUAL_LOCATION((expected), (actual), text, __FILE__, __LINE__) + +#define POINTERS_EQUAL_LOCATION(expected, actual, text, file, line)\ + do { UtestShell::getCurrent()->assertPointersEqual((const void *)expected, (const void *)actual, text, file, line); } while(0) + +#define FUNCTIONPOINTERS_EQUAL(expected, actual)\ + FUNCTIONPOINTERS_EQUAL_LOCATION((expected), (actual), NULLPTR, __FILE__, __LINE__) + +#define FUNCTIONPOINTERS_EQUAL_TEXT(expected, actual, text)\ + FUNCTIONPOINTERS_EQUAL_LOCATION((expected), (actual), text, __FILE__, __LINE__) + +#define FUNCTIONPOINTERS_EQUAL_LOCATION(expected, actual, text, file, line)\ + do { UtestShell::getCurrent()->assertFunctionPointersEqual((void (*)())expected, (void (*)())actual, text, file, line); } while(0) + +//Check two doubles for equality within a tolerance threshold +#define DOUBLES_EQUAL(expected, actual, threshold)\ + DOUBLES_EQUAL_LOCATION(expected, actual, threshold, NULLPTR, __FILE__, __LINE__) + +#define DOUBLES_EQUAL_TEXT(expected, actual, threshold, text)\ + DOUBLES_EQUAL_LOCATION(expected, actual, threshold, text, __FILE__, __LINE__) + +#define DOUBLES_EQUAL_LOCATION(expected, actual, threshold, text, file, line)\ + do { UtestShell::getCurrent()->assertDoublesEqual(expected, actual, threshold, text, file, line); } while(0) + +#define MEMCMP_EQUAL(expected, actual, size)\ + MEMCMP_EQUAL_LOCATION(expected, actual, size, NULLPTR, __FILE__, __LINE__) + +#define MEMCMP_EQUAL_TEXT(expected, actual, size, text)\ + MEMCMP_EQUAL_LOCATION(expected, actual, size, text, __FILE__, __LINE__) + +#define MEMCMP_EQUAL_LOCATION(expected, actual, size, text, file, line)\ + do { UtestShell::getCurrent()->assertBinaryEqual(expected, actual, size, text, file, line); } while(0) + +#define BITS_EQUAL(expected, actual, mask)\ + BITS_LOCATION(expected, actual, mask, NULLPTR, __FILE__, __LINE__) + +#define BITS_EQUAL_TEXT(expected, actual, mask, text)\ + BITS_LOCATION(expected, actual, mask, text, __FILE__, __LINE__) + +#define BITS_LOCATION(expected, actual, mask, text, file, line)\ + do { UtestShell::getCurrent()->assertBitsEqual(expected, actual, mask, sizeof(actual), text, file, line); } while(0) + +#define ENUMS_EQUAL_INT(expected, actual)\ + ENUMS_EQUAL_TYPE(int, expected, actual) + +#define ENUMS_EQUAL_INT_TEXT(expected, actual, text)\ + ENUMS_EQUAL_TYPE_TEXT(int, expected, actual, text) + +#define ENUMS_EQUAL_TYPE(underlying_type, expected, actual)\ + ENUMS_EQUAL_TYPE_LOCATION(underlying_type, expected, actual, NULLPTR, __FILE__, __LINE__) + +#define ENUMS_EQUAL_TYPE_TEXT(underlying_type, expected, actual, text)\ + ENUMS_EQUAL_TYPE_LOCATION(underlying_type, expected, actual, text, __FILE__, __LINE__) + +#define ENUMS_EQUAL_TYPE_LOCATION(underlying_type, expected, actual, text, file, line)\ + do { underlying_type expected_underlying_value = (underlying_type)(expected); \ + underlying_type actual_underlying_value = (underlying_type)(actual); \ + if (expected_underlying_value != actual_underlying_value) { \ + UtestShell::getCurrent()->assertEquals(true, StringFrom(expected_underlying_value).asCharString(), StringFrom(actual_underlying_value).asCharString(), text, file, line); \ + } \ + else \ + { \ + UtestShell::getCurrent()->assertLongsEqual((long)0, long(0), NULLPTR, file, line); \ + } \ + } while(0) + +//Fail if you get to this macro +//The macro FAIL may already be taken, so allow FAIL_TEST too +#ifndef FAIL +#define FAIL(text)\ + FAIL_LOCATION(text, __FILE__,__LINE__) + +#define FAIL_LOCATION(text, file, line)\ + do { UtestShell::getCurrent()->fail(text, file, line); } while(0) +#endif + +#define FAIL_TEST(text)\ + FAIL_TEST_LOCATION(text, __FILE__,__LINE__) + +#define FAIL_TEST_LOCATION(text, file,line)\ + do { UtestShell::getCurrent()->fail(text, file, line); } while(0) + +#define TEST_EXIT\ + do { UtestShell::getCurrent()->exitTest(); } while(0) + +#define UT_PRINT_LOCATION(text, file, line) \ + do { UtestShell::getCurrent()->print(text, file, line); } while(0) + +#define UT_PRINT(text) \ + UT_PRINT_LOCATION(text, __FILE__, __LINE__) + +#if CPPUTEST_USE_STD_CPP_LIB +#define CHECK_THROWS(expected, expression) \ + do { \ + SimpleString failure_msg("expected to throw "#expected "\nbut threw nothing"); \ + bool caught_expected = false; \ + try { \ + (expression); \ + } catch(const expected &) { \ + caught_expected = true; \ + } catch(...) { \ + failure_msg = "expected to throw " #expected "\nbut threw a different type"; \ + } \ + if (!caught_expected) { \ + UtestShell::getCurrent()->fail(failure_msg.asCharString(), __FILE__, __LINE__); \ + } \ + else { \ + UtestShell::getCurrent()->countCheck(); \ + } \ + } while(0) +#endif /* CPPUTEST_USE_STD_CPP_LIB */ + +#define UT_CRASH() do { UtestShell::crash(); } while(0) +#define RUN_ALL_TESTS(ac, av) CommandLineTestRunner::RunAllTests(ac, av) + +#endif /*D_UTestMacros_h*/ diff --git a/test/test_utility/include/CppUTestExt/CodeMemoryReportFormatter.h b/test/test_utility/include/CppUTestExt/CodeMemoryReportFormatter.h new file mode 100644 index 0000000..4667841 --- /dev/null +++ b/test/test_utility/include/CppUTestExt/CodeMemoryReportFormatter.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the 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 EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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 D_CodeMemoryReportFormatter_h +#define D_CodeMemoryReportFormatter_h + +#include "CppUTestExt/MemoryReportFormatter.h" + +struct CodeReportingAllocationNode; +class CodeMemoryReportFormatter : public MemoryReportFormatter +{ +private: + CodeReportingAllocationNode* codeReportingList_; + TestMemoryAllocator* internalAllocator_; + +public: + CodeMemoryReportFormatter(TestMemoryAllocator* internalAllocator); + virtual ~CodeMemoryReportFormatter() _destructor_override; + + virtual void report_testgroup_start(TestResult* result, UtestShell& test) _override; + virtual void report_testgroup_end(TestResult* /*result*/, UtestShell& /*test*/) _override {} // LCOV_EXCL_LINE + + virtual void report_test_start(TestResult* result, UtestShell& test) _override; + virtual void report_test_end(TestResult* result, UtestShell& test) _override; + + virtual void report_alloc_memory(TestResult* result, TestMemoryAllocator* allocator, size_t size, char* memory, const char* file, size_t line) _override; + virtual void report_free_memory(TestResult* result, TestMemoryAllocator* allocator, char* memory, const char* file, size_t line) _override; + +private: + + void addNodeToList(const char* variableName, void* memory, CodeReportingAllocationNode* next); + CodeReportingAllocationNode* findNode(void* memory); + bool variableExists(const SimpleString& variableName); + void clearReporting(); + + bool isNewAllocator(TestMemoryAllocator* allocator); + SimpleString createVariableNameFromFileLineInfo(const char *file, size_t line); + + SimpleString getAllocationString(TestMemoryAllocator* allocator, const SimpleString& variableName, size_t size); + SimpleString getDeallocationString(TestMemoryAllocator* allocator, const SimpleString& variableName, const char* file, size_t line); +}; + +#endif diff --git a/test/test_utility/include/CppUTestExt/GMock.h b/test/test_utility/include/CppUTestExt/GMock.h new file mode 100644 index 0000000..71e4c70 --- /dev/null +++ b/test/test_utility/include/CppUTestExt/GMock.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2011, Michael Feathers, James Grenning and Bas Vodde + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the 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 EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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 GMOCK_H_ +#define GMOCK_H_ + +#undef new +#undef strdup +#undef strndup + +#undef RUN_ALL_TESTS + +#define GTEST_DONT_DEFINE_TEST 1 +#define GTEST_DONT_DEFINE_FAIL 1 + +#include "gmock/gmock.h" +#undef RUN_ALL_TESTS + +using testing::Return; +using testing::NiceMock; + +#ifdef CPPUTEST_USE_NEW_MACROS +#include "CppUTest/MemoryLeakDetectorNewMacros.h" +#endif + +#ifdef CPPUTEST_USE_MALLOC_MACROS +#include "CppUTest/MemoryLeakDetectorMallocMacros.h" +#endif + +#endif diff --git a/test/test_utility/include/CppUTestExt/GTest.h b/test/test_utility/include/CppUTestExt/GTest.h new file mode 100644 index 0000000..1d3a7d1 --- /dev/null +++ b/test/test_utility/include/CppUTestExt/GTest.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2011, Michael Feathers, James Grenning and Bas Vodde + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the 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 EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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 GTEST__H_ +#define GTEST__H_ + +#undef new +#undef strdup +#undef strndup + +#undef RUN_ALL_TESTS + +#include "gtest/gtest.h" + +#ifdef CPPUTEST_USE_NEW_MACROS +#include "CppUTest/MemoryLeakDetectorNewMacros.h" +#endif + +#ifdef CPPUTEST_USE_MALLOC_MACROS +#include "CppUTest/MemoryLeakDetectorMallocMacros.h" +#endif + +#include "CppUTestExt/GTestSupport.h" + +#ifndef RUN_ALL_TESTS +#define GTEST_VERSION_GTEST_1_7 +#else +#ifdef ADD_FAILURE_AT +#define GTEST_VERSION_GTEST_1_6 +#else +#define GTEST_VERSION_GTEST_1_5 +#endif +#endif + +#undef RUN_ALL_TESTS + +#endif diff --git a/test/test_utility/include/CppUTestExt/GTestConvertor.h b/test/test_utility/include/CppUTestExt/GTestConvertor.h new file mode 100644 index 0000000..f20de91 --- /dev/null +++ b/test/test_utility/include/CppUTestExt/GTestConvertor.h @@ -0,0 +1,387 @@ +/* + * Copyright (c) 2011, Michael Feathers, James Grenning and Bas Vodde + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the 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 EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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 GTESTCONVERTOR_H_ +#define GTESTCONVERTOR_H_ + +#include "CppUTest/Utest.h" + +#ifdef GTEST__H_ +#error "Please include this file before you include any other GTest files" +#endif + +/* + * Usage: + * + * This file must only be included in the main. The whole implementation is inline so that this can + * be compiled on usage and not on CppUTest compile-time. This avoids a hard dependency with CppUTest + * and with GTest + * + * Add the following lines to your main: + * + * GTestConvertor convertor; + * convertor.addAllGTestToTestRegistry(); + * + * + */ + +class GTestResultReporter; +class GTestFlagsThatAllocateMemory; + +namespace testing { + class TestInfo; + class TestCase; + class Test; +} + +class GTestShell : public UtestShell +{ + ::testing::TestInfo* testinfo_; + GTestShell* next_; + GTestFlagsThatAllocateMemory* flags_; +public: + GTestShell(::testing::TestInfo* testinfo, GTestShell* next, GTestFlagsThatAllocateMemory* flags); + + virtual Utest* createTest() _override; + + GTestShell* nextGTest() + { + return next_; + } +}; + +/* Enormous hack! + * + * This sucks enormously. We need to do two things in GTest that seem to not be possible without + * this hack. Hopefully there is *another way*. + * + * We need to access the factory in the TestInfo in order to be able to create tests. The factory + * is private and there seems to be no way to access it... + * + * We need to be able to call the Test SetUp and TearDown methods, but they are protected for + * some reason. We can't subclass either as the tests are created with the TEST macro. + * + * If anyone knows how to get the above things done *without* these ugly #defines, let me know! + * + */ + +#define private public +#define protected public + +#include "CppUTestExt/GTest.h" +#include "CppUTestExt/GMock.h" +#include "gtest/gtest-spi.h" +#include "gtest/gtest-death-test.h" +/* + * We really need some of its internals as they don't have a public interface. + * + */ +#define GTEST_IMPLEMENTATION_ 1 +#include "src/gtest-internal-inl.h" + +#include "CppUTest/TestRegistry.h" +#include "CppUTest/TestFailure.h" +#include "CppUTest/TestResult.h" + + +#ifdef GTEST_VERSION_GTEST_1_7 +#define GTEST_STRING std::string +#define GTEST_NO_STRING_VALUE "" +#else +#define GTEST_STRING ::testing::internal::String +#define GTEST_NO_STRING_VALUE NULL +#endif + +/* Store some of the flags as we'll need to reset them each test to avoid leaking memory */ + +class GTestFlagsThatAllocateMemory +{ +public: + void storeValuesOfGTestFLags() + { + GTestFlagcolor = ::testing::GTEST_FLAG(color); + GTestFlagfilter = ::testing::GTEST_FLAG(filter); + GTestFlagoutput = ::testing::GTEST_FLAG(output); + GTestFlagdeath_test_style = ::testing::GTEST_FLAG(death_test_style); + GTestFlaginternal_run_death_test = ::testing::internal::GTEST_FLAG(internal_run_death_test); + #ifndef GTEST_VERSION_GTEST_1_5 + GTestFlagstream_result_to = ::testing::GTEST_FLAG(stream_result_to); + #endif + } + + void resetValuesOfGTestFlags() + { + ::testing::GTEST_FLAG(color) = GTestFlagcolor; + ::testing::GTEST_FLAG(filter) = GTestFlagfilter; + ::testing::GTEST_FLAG(output) = GTestFlagoutput; + ::testing::GTEST_FLAG(death_test_style) = GTestFlagdeath_test_style; + ::testing::internal::GTEST_FLAG(internal_run_death_test) = GTestFlaginternal_run_death_test; + #ifndef GTEST_VERSION_GTEST_1_5 + ::testing::GTEST_FLAG(stream_result_to) = GTestFlagstream_result_to; + #endif + } + + void setGTestFLagValuesToNULLToAvoidMemoryLeaks() + { + #ifndef GTEST_VERSION_GTEST_1_7 + ::testing::GTEST_FLAG(color) = GTEST_NO_STRING_VALUE; + ::testing::GTEST_FLAG(filter) = GTEST_NO_STRING_VALUE; + ::testing::GTEST_FLAG(output) = GTEST_NO_STRING_VALUE; + ::testing::GTEST_FLAG(death_test_style) = GTEST_NO_STRING_VALUE; + ::testing::internal::GTEST_FLAG(internal_run_death_test) = GTEST_NO_STRING_VALUE; + #ifndef GTEST_VERSION_GTEST_1_5 + ::testing::GTEST_FLAG(stream_result_to) = GTEST_NO_STRING_VALUE; + #endif + #endif + } + +private: + GTEST_STRING GTestFlagcolor; + GTEST_STRING GTestFlagfilter; + GTEST_STRING GTestFlagoutput; + GTEST_STRING GTestFlagdeath_test_style; + GTEST_STRING GTestFlaginternal_run_death_test; + #ifndef GTEST_VERSION_GTEST_1_5 + GTEST_STRING GTestFlagstream_result_to; + #endif +}; + +class GTestConvertor +{ +public: + GTestConvertor(bool shouldSimulateFailureAtCreationToAllocateThreadLocalData = true); + virtual ~GTestConvertor(); + + virtual void addAllGTestToTestRegistry(); +protected: + virtual void simulateGTestFailureToPreAllocateAllTheThreadLocalData(); + + virtual void addNewTestCaseForTestInfo(::testing::TestInfo* testinfo); + virtual void addAllTestsFromTestCaseToTestRegistry(::testing::TestCase* testcase); + + virtual void createDummyInSequenceToAndFailureReporterAvoidMemoryLeakInGMock(); +private: + GTestResultReporter* reporter_; + GTestShell* first_; + GTestFlagsThatAllocateMemory flags_; +}; + +class GTestDummyResultReporter : public ::testing::ScopedFakeTestPartResultReporter +{ +public: + GTestDummyResultReporter () : ::testing::ScopedFakeTestPartResultReporter(INTERCEPT_ALL_THREADS, NULL) {} + virtual void ReportTestPartResult(const ::testing::TestPartResult& /*result*/) {} +}; + +class GMockTestTerminator : public TestTerminator +{ +public: + GMockTestTerminator(const ::testing::TestPartResult& result) : result_(result) + { + } + + virtual void exitCurrentTest() const + { + /* + * When using GMock, it throws an exception from the destructor leaving + * the system in an unstable state. + * Therefore, when the test fails because of failed gmock expectation + * then don't throw the exception, but let it return. Usually this should + * already be at the end of the test, so it doesn't matter much + */ + + + /* + * TODO: We probably want this check here, however the tests fail when putting it there. Also, we'll need to + * check how to get all the gTest tests to run within CppUTest. At the moment, the 'death tests' seem to fail + * still. + * + * if (result_.type() == ::testing::TestPartResult::kFatalFailure) { + */ + if (!SimpleString(result_.message()).contains("Actual: never called") && + !SimpleString(result_.message()).contains("Actual function call count doesn't match")) + throw CppUTestFailedException(); + + } + virtual ~GMockTestTerminator() + { + } +private: + const ::testing::TestPartResult& result_; +}; + + +class GTestResultReporter : public ::testing::ScopedFakeTestPartResultReporter +{ +public: + GTestResultReporter () : ::testing::ScopedFakeTestPartResultReporter(INTERCEPT_ALL_THREADS, NULL) {} + + virtual void ReportTestPartResult(const ::testing::TestPartResult& result) + { + FailFailure failure(UtestShell::getCurrent(), result.file_name(), result.line_number(), result.message()); + UtestShell::getCurrent()->failWith(failure, GMockTestTerminator(result)); + } +}; + +inline GTestShell::GTestShell(::testing::TestInfo* testinfo, GTestShell* next, GTestFlagsThatAllocateMemory* flags) : testinfo_(testinfo), next_(next), flags_(flags) +{ + setGroupName(testinfo->test_case_name()); + setTestName(testinfo->name()); +} + +class GTestUTest: public Utest { +public: + GTestUTest(::testing::TestInfo* testinfo, GTestFlagsThatAllocateMemory* flags) : testinfo_(testinfo), test_(NULL), flags_(flags) + { + + } + + void testBody() + { + try { + test_->TestBody(); + } + catch (CppUTestFailedException& ex) + { + } + } + + void setup() + { + flags_->resetValuesOfGTestFlags(); + + #ifdef GTEST_VERSION_GTEST_1_5 + test_ = testinfo_->impl()->factory_->CreateTest(); + #else + test_ = testinfo_->factory_->CreateTest(); + #endif + + ::testing::UnitTest::GetInstance()->impl()->set_current_test_info(testinfo_); + try { + test_->SetUp(); + } + catch (CppUTestFailedException& ex) + { + } + } + + void teardown() + { + try { + test_->TearDown(); + } + catch (CppUTestFailedException& ex) + { + } + ::testing::UnitTest::GetInstance()->impl()->set_current_test_info(NULL); + delete test_; + + flags_->setGTestFLagValuesToNULLToAvoidMemoryLeaks(); + ::testing::internal::DeathTest::set_last_death_test_message(GTEST_NO_STRING_VALUE); + } + +private: + ::testing::Test* test_; + ::testing::TestInfo* testinfo_; + GTestFlagsThatAllocateMemory* flags_; +}; + +inline Utest* GTestShell::createTest() +{ + return new GTestUTest(testinfo_, flags_); +}; + +inline void GTestConvertor::simulateGTestFailureToPreAllocateAllTheThreadLocalData() +{ + GTestDummyResultReporter *dummyReporter = new GTestDummyResultReporter(); + ASSERT_TRUE(false); + delete dummyReporter; +} + +inline GTestConvertor::GTestConvertor(bool shouldSimulateFailureAtCreationToAllocateThreadLocalData) : first_(NULL) +{ + if (shouldSimulateFailureAtCreationToAllocateThreadLocalData) + simulateGTestFailureToPreAllocateAllTheThreadLocalData(); + reporter_ = new GTestResultReporter(); +} + +inline GTestConvertor::~GTestConvertor() +{ + delete reporter_; + + while (first_) { + GTestShell* next = first_->nextGTest(); + delete first_; + first_ = next; + } +} + +inline void GTestConvertor::addNewTestCaseForTestInfo(::testing::TestInfo* testinfo) +{ + first_ = new GTestShell(testinfo, first_, &flags_); + TestRegistry::getCurrentRegistry()->addTest(first_); +} + +inline void GTestConvertor::addAllTestsFromTestCaseToTestRegistry(::testing::TestCase* testcase) +{ + int currentTestCount = 0; + ::testing::TestInfo* currentTest = (::testing::TestInfo*) testcase->GetTestInfo(currentTestCount); + while (currentTest) { + addNewTestCaseForTestInfo(currentTest); + currentTestCount++; + currentTest = (::testing::TestInfo*) testcase->GetTestInfo(currentTestCount); + } +} + +inline void GTestConvertor::createDummyInSequenceToAndFailureReporterAvoidMemoryLeakInGMock() +{ + ::testing::InSequence seq; + ::testing::internal::GetFailureReporter(); +} + +inline void GTestConvertor::addAllGTestToTestRegistry() +{ + createDummyInSequenceToAndFailureReporterAvoidMemoryLeakInGMock(); + flags_.storeValuesOfGTestFLags(); + + int argc = 2; + const char * argv[] = {"NameOfTheProgram", "--gmock_catch_leaked_mocks=0"}; + ::testing::InitGoogleMock(&argc, (char**) argv); + + ::testing::UnitTest* unitTests = ::testing::UnitTest::GetInstance(); + + int currentUnitTestCount = 0; + ::testing::TestCase* currentTestCase = (::testing::TestCase*) unitTests->GetTestCase(currentUnitTestCount); + while (currentTestCase) { + addAllTestsFromTestCaseToTestRegistry(currentTestCase); + currentUnitTestCount++; + currentTestCase = (::testing::TestCase*) unitTests->GetTestCase(currentUnitTestCount); + } +} + + +#endif diff --git a/test/test_utility/include/CppUTestExt/GTestSupport.h b/test/test_utility/include/CppUTestExt/GTestSupport.h new file mode 100644 index 0000000..9cbb27b --- /dev/null +++ b/test/test_utility/include/CppUTestExt/GTestSupport.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2011, Michael Feathers, James Grenning and Bas Vodde + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the 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 EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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 GTESTSUPPORT__H_ +#define GTESTSUPPORT__H_ + +extern void CppuTestGTestIgnoreLeaksInTest(); + +#endif diff --git a/test/test_utility/include/CppUTestExt/IEEE754ExceptionsPlugin.h b/test/test_utility/include/CppUTestExt/IEEE754ExceptionsPlugin.h new file mode 100644 index 0000000..9d3f0cd --- /dev/null +++ b/test/test_utility/include/CppUTestExt/IEEE754ExceptionsPlugin.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2015, Michael Feathers, James Grenning, Bas Vodde + * and Arnd Strube. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the 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 EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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 D_IEEE754ExceptionsPlugin_h +#define D_IEEE754ExceptionsPlugin_h + +#include "CppUTest/TestPlugin.h" + +class IEEE754ExceptionsPlugin: public TestPlugin +{ +public: + IEEE754ExceptionsPlugin(const SimpleString& name = "IEEE754ExceptionsPlugin"); + + virtual void preTestAction(UtestShell& test, TestResult& result) _override; + virtual void postTestAction(UtestShell& test, TestResult& result) _override; + + static void disableInexact(void); + static void enableInexact(void); + static bool checkIeee754OverflowExceptionFlag(); + static bool checkIeee754UnderflowExceptionFlag(); + static bool checkIeee754InexactExceptionFlag(); + static bool checkIeee754DivByZeroExceptionFlag(); + +private: + void ieee754Check(UtestShell& test, TestResult& result, int flag, const char* text); + static bool inexactDisabled_; +}; + +#endif diff --git a/test/test_utility/include/CppUTestExt/MemoryReportAllocator.h b/test/test_utility/include/CppUTestExt/MemoryReportAllocator.h new file mode 100644 index 0000000..becdb4a --- /dev/null +++ b/test/test_utility/include/CppUTestExt/MemoryReportAllocator.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the 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 EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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 D_MemoryReportAllocator_h +#define D_MemoryReportAllocator_h + +#include "CppUTest/TestMemoryAllocator.h" + +class MemoryReportFormatter; + +class MemoryReportAllocator : public TestMemoryAllocator +{ +protected: + TestResult* result_; + TestMemoryAllocator* realAllocator_; + MemoryReportFormatter* formatter_; +public: + MemoryReportAllocator(); + virtual ~MemoryReportAllocator() _destructor_override; + + virtual void setFormatter(MemoryReportFormatter* formatter); + virtual void setTestResult(TestResult* result); + virtual void setRealAllocator(TestMemoryAllocator* allocator); + + virtual TestMemoryAllocator* getRealAllocator(); + + virtual char* alloc_memory(size_t size, const char* file, size_t line) _override; + virtual void free_memory(char* memory, size_t size, const char* file, size_t line) _override; + + virtual const char* name() const _override; + virtual const char* alloc_name() const _override; + virtual const char* free_name() const _override; + + virtual TestMemoryAllocator* actualAllocator() _override; +}; + +#endif diff --git a/test/test_utility/include/CppUTestExt/MemoryReportFormatter.h b/test/test_utility/include/CppUTestExt/MemoryReportFormatter.h new file mode 100644 index 0000000..d0034b6 --- /dev/null +++ b/test/test_utility/include/CppUTestExt/MemoryReportFormatter.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the 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 EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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 D_MemoryReportFormatter_h +#define D_MemoryReportFormatter_h + +class TestOutput; +class UtestShell; + +class MemoryReportFormatter +{ +public: + virtual ~MemoryReportFormatter(){} + + virtual void report_testgroup_start(TestResult* result, UtestShell& test)=0; + virtual void report_testgroup_end(TestResult* result, UtestShell& test)=0; + + virtual void report_test_start(TestResult* result, UtestShell& test)=0; + virtual void report_test_end(TestResult* result, UtestShell& test)=0; + + virtual void report_alloc_memory(TestResult* result, TestMemoryAllocator* allocator, size_t size, char* memory, const char* file, size_t line)=0; + virtual void report_free_memory(TestResult* result, TestMemoryAllocator* allocator, char* memory, const char* file, size_t line)=0; +}; + +class NormalMemoryReportFormatter : public MemoryReportFormatter +{ +public: + NormalMemoryReportFormatter(); + virtual ~NormalMemoryReportFormatter() _destructor_override; + + virtual void report_testgroup_start(TestResult* /*result*/, UtestShell& /*test*/) _override; + virtual void report_testgroup_end(TestResult* /*result*/, UtestShell& /*test*/) _override {} // LCOV_EXCL_LINE + + virtual void report_test_start(TestResult* result, UtestShell& test) _override; + virtual void report_test_end(TestResult* result, UtestShell& test) _override; + + virtual void report_alloc_memory(TestResult* result, TestMemoryAllocator* allocator, size_t size, char* memory, const char* file, size_t line) _override; + virtual void report_free_memory(TestResult* result, TestMemoryAllocator* allocator, char* memory, const char* file, size_t line) _override; +}; + +#endif diff --git a/test/test_utility/include/CppUTestExt/MemoryReporterPlugin.h b/test/test_utility/include/CppUTestExt/MemoryReporterPlugin.h new file mode 100644 index 0000000..9874cad --- /dev/null +++ b/test/test_utility/include/CppUTestExt/MemoryReporterPlugin.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the 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 EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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 D_MemoryReporterPlugin_h +#define D_MemoryReporterPlugin_h + +#include "CppUTest/TestPlugin.h" +#include "CppUTestExt/MemoryReportAllocator.h" + +class MemoryReportFormatter; + +class MemoryReporterPlugin : public TestPlugin +{ + MemoryReportFormatter* formatter_; + + MemoryReportAllocator mallocAllocator; + MemoryReportAllocator newAllocator; + MemoryReportAllocator newArrayAllocator; + + SimpleString currentTestGroup_; +public: + MemoryReporterPlugin(); + virtual ~MemoryReporterPlugin() _destructor_override; + + virtual void preTestAction(UtestShell & test, TestResult & result) _override; + virtual void postTestAction(UtestShell & test, TestResult & result) _override; + virtual bool parseArguments(int, const char *const *, int) _override; + + MemoryReportAllocator* getMallocAllocator(); + MemoryReportAllocator* getNewAllocator(); + MemoryReportAllocator* getNewArrayAllocator(); +protected: + virtual MemoryReportFormatter* createMemoryFormatter(const SimpleString& type); + +private: + void destroyMemoryFormatter(MemoryReportFormatter* formatter); + + void setGlobalMemoryReportAllocators(); + void removeGlobalMemoryReportAllocators(); + + void initializeAllocator(MemoryReportAllocator* allocator, TestResult & result); +}; + +#endif diff --git a/test/test_utility/include/CppUTestExt/MockActualCall.h b/test/test_utility/include/CppUTestExt/MockActualCall.h new file mode 100644 index 0000000..b41c3fd --- /dev/null +++ b/test/test_utility/include/CppUTestExt/MockActualCall.h @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the 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 EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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 D_MockActualCall_h +#define D_MockActualCall_h + +#include "CppUTest/CppUTestConfig.h" +#include "CppUTest/TestHarness.h" +#include "CppUTestExt/MockNamedValue.h" +#include "CppUTestExt/MockExpectedCallsList.h" + +class MockFailureReporter; +class MockFailure; + +class MockActualCall +{ +public: + MockActualCall(); + virtual ~MockActualCall(); + + virtual MockActualCall& withName(const SimpleString& name)=0; + virtual MockActualCall& withCallOrder(unsigned int callOrder)=0; + MockActualCall& withParameter(const SimpleString& name, bool value) { return withBoolParameter(name, value); } + MockActualCall& withParameter(const SimpleString& name, int value) { return withIntParameter(name, value); } + MockActualCall& withParameter(const SimpleString& name, unsigned int value) { return withUnsignedIntParameter(name, value); } + MockActualCall& withParameter(const SimpleString& name, long int value) { return withLongIntParameter(name, value); } + MockActualCall& withParameter(const SimpleString& name, unsigned long int value) { return withUnsignedLongIntParameter(name, value); } + MockActualCall& withParameter(const SimpleString& name, cpputest_longlong value) { return withLongLongIntParameter(name, value); } + MockActualCall& withParameter(const SimpleString& name, cpputest_ulonglong value) { return withUnsignedLongLongIntParameter(name, value); } + MockActualCall& withParameter(const SimpleString& name, double value) { return withDoubleParameter(name, value); } + MockActualCall& withParameter(const SimpleString& name, const char* value) { return withStringParameter(name, value); } + MockActualCall& withParameter(const SimpleString& name, void* value) { return withPointerParameter(name, value); } + MockActualCall& withParameter(const SimpleString& name, void (*value)()) { return withFunctionPointerParameter(name, value); } + MockActualCall& withParameter(const SimpleString& name, const void* value) { return withConstPointerParameter(name, value); } + MockActualCall& withParameter(const SimpleString& name, const unsigned char* value, size_t size) { return withMemoryBufferParameter(name, value, size); } + virtual MockActualCall& withParameterOfType(const SimpleString& typeName, const SimpleString& name, const void* value)=0; + virtual MockActualCall& withOutputParameter(const SimpleString& name, void* output)=0; + virtual MockActualCall& withOutputParameterOfType(const SimpleString& typeName, const SimpleString& name, void* output)=0; + + virtual MockActualCall& withBoolParameter(const SimpleString& name, bool value)=0; + virtual MockActualCall& withIntParameter(const SimpleString& name, int value)=0; + virtual MockActualCall& withUnsignedIntParameter(const SimpleString& name, unsigned int value)=0; + virtual MockActualCall& withLongIntParameter(const SimpleString& name, long int value)=0; + virtual MockActualCall& withUnsignedLongIntParameter(const SimpleString& name, unsigned long int value)=0; + virtual MockActualCall& withLongLongIntParameter(const SimpleString& name, cpputest_longlong value)=0; + virtual MockActualCall& withUnsignedLongLongIntParameter(const SimpleString& name, cpputest_ulonglong value)=0; + virtual MockActualCall& withDoubleParameter(const SimpleString& name, double value)=0; + virtual MockActualCall& withStringParameter(const SimpleString& name, const char* value)=0; + virtual MockActualCall& withPointerParameter(const SimpleString& name, void* value)=0; + virtual MockActualCall& withFunctionPointerParameter(const SimpleString& name, void (*value)())=0; + virtual MockActualCall& withConstPointerParameter(const SimpleString& name, const void* value)=0; + virtual MockActualCall& withMemoryBufferParameter(const SimpleString& name, const unsigned char* value, size_t size)=0; + + virtual bool hasReturnValue()=0; + virtual MockNamedValue returnValue()=0; + + virtual bool returnBoolValueOrDefault(bool default_value)=0; + virtual bool returnBoolValue()=0; + + virtual int returnIntValueOrDefault(int default_value)=0; + virtual int returnIntValue()=0; + + virtual unsigned long int returnUnsignedLongIntValue()=0; + virtual unsigned long int returnUnsignedLongIntValueOrDefault(unsigned long int default_value)=0; + + virtual long int returnLongIntValue()=0; + virtual long int returnLongIntValueOrDefault(long int default_value)=0; + + virtual cpputest_ulonglong returnUnsignedLongLongIntValue()=0; + virtual cpputest_ulonglong returnUnsignedLongLongIntValueOrDefault(cpputest_ulonglong default_value)=0; + + virtual cpputest_longlong returnLongLongIntValue()=0; + virtual cpputest_longlong returnLongLongIntValueOrDefault(cpputest_longlong default_value)=0; + + virtual unsigned int returnUnsignedIntValue()=0; + virtual unsigned int returnUnsignedIntValueOrDefault(unsigned int default_value)=0; + + virtual const char * returnStringValueOrDefault(const char * default_value)=0; + virtual const char * returnStringValue()=0; + + virtual double returnDoubleValue()=0; + virtual double returnDoubleValueOrDefault(double default_value)=0; + + virtual void * returnPointerValue()=0; + virtual void * returnPointerValueOrDefault(void * default_value)=0; + + virtual const void * returnConstPointerValue()=0; + virtual const void * returnConstPointerValueOrDefault(const void * default_value)=0; + + virtual void (*returnFunctionPointerValue())()=0; + virtual void (*returnFunctionPointerValueOrDefault(void (*default_value)()))()=0; + + virtual MockActualCall& onObject(const void* objectPtr)=0; +}; + +#endif diff --git a/test/test_utility/include/CppUTestExt/MockCheckedActualCall.h b/test/test_utility/include/CppUTestExt/MockCheckedActualCall.h new file mode 100644 index 0000000..fd6ebd0 --- /dev/null +++ b/test/test_utility/include/CppUTestExt/MockCheckedActualCall.h @@ -0,0 +1,300 @@ +/* + * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the 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 EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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 D_MockCheckedActualCall_h +#define D_MockCheckedActualCall_h + +#include "CppUTestExt/MockActualCall.h" +#include "CppUTestExt/MockExpectedCallsList.h" + +class MockCheckedActualCall : public MockActualCall +{ +public: + MockCheckedActualCall(unsigned int callOrder, MockFailureReporter* reporter, const MockExpectedCallsList& expectations); + virtual ~MockCheckedActualCall() _destructor_override; + + virtual MockActualCall& withName(const SimpleString& name) _override; + virtual MockActualCall& withCallOrder(unsigned int) _override; + virtual MockActualCall& withBoolParameter(const SimpleString& name, bool value) _override; + virtual MockActualCall& withIntParameter(const SimpleString& name, int value) _override; + virtual MockActualCall& withUnsignedIntParameter(const SimpleString& name, unsigned int value) _override; + virtual MockActualCall& withLongIntParameter(const SimpleString& name, long int value) _override; + virtual MockActualCall& withUnsignedLongIntParameter(const SimpleString& name, unsigned long int value) _override; + virtual MockActualCall& withLongLongIntParameter(const SimpleString& name, cpputest_longlong value) _override; + virtual MockActualCall& withUnsignedLongLongIntParameter(const SimpleString& name, cpputest_ulonglong value) _override; + virtual MockActualCall& withDoubleParameter(const SimpleString& name, double value) _override; + virtual MockActualCall& withStringParameter(const SimpleString& name, const char* value) _override; + virtual MockActualCall& withPointerParameter(const SimpleString& name, void* value) _override; + virtual MockActualCall& withConstPointerParameter(const SimpleString& name, const void* value) _override; + virtual MockActualCall& withFunctionPointerParameter(const SimpleString& name, void (*value)()) _override; + virtual MockActualCall& withMemoryBufferParameter(const SimpleString& name, const unsigned char* value, size_t size) _override; + virtual MockActualCall& withParameterOfType(const SimpleString& type, const SimpleString& name, const void* value) _override; + virtual MockActualCall& withOutputParameter(const SimpleString& name, void* output) _override; + virtual MockActualCall& withOutputParameterOfType(const SimpleString& type, const SimpleString& name, void* output) _override; + + virtual bool hasReturnValue() _override; + virtual MockNamedValue returnValue() _override; + + virtual bool returnBoolValueOrDefault(bool default_value) _override; + virtual bool returnBoolValue() _override; + + virtual int returnIntValueOrDefault(int default_value) _override; + virtual int returnIntValue() _override; + + virtual unsigned long int returnUnsignedLongIntValue() _override; + virtual unsigned long int returnUnsignedLongIntValueOrDefault(unsigned long int) _override; + + virtual long int returnLongIntValue() _override; + virtual long int returnLongIntValueOrDefault(long int default_value) _override; + + virtual cpputest_ulonglong returnUnsignedLongLongIntValue() _override; + virtual cpputest_ulonglong returnUnsignedLongLongIntValueOrDefault(cpputest_ulonglong default_value) _override; + + virtual cpputest_longlong returnLongLongIntValue() _override; + virtual cpputest_longlong returnLongLongIntValueOrDefault(cpputest_longlong default_value) _override; + + virtual unsigned int returnUnsignedIntValue() _override; + virtual unsigned int returnUnsignedIntValueOrDefault(unsigned int default_value) _override; + + virtual const char * returnStringValueOrDefault(const char * default_value) _override; + virtual const char * returnStringValue() _override; + + virtual double returnDoubleValue() _override; + virtual double returnDoubleValueOrDefault(double default_value) _override; + + virtual const void * returnConstPointerValue() _override; + virtual const void * returnConstPointerValueOrDefault(const void * default_value) _override; + + virtual void * returnPointerValue() _override; + virtual void * returnPointerValueOrDefault(void *) _override; + + virtual void (*returnFunctionPointerValue())() _override; + virtual void (*returnFunctionPointerValueOrDefault(void (*)()))() _override; + + virtual MockActualCall& onObject(const void* objectPtr) _override; + + virtual bool isFulfilled() const; + virtual bool hasFailed() const; + + virtual void checkExpectations(); + + virtual void setMockFailureReporter(MockFailureReporter* reporter); +protected: + void setName(const SimpleString& name); + SimpleString getName() const; + virtual UtestShell* getTest() const; + virtual void callHasSucceeded(); + virtual void copyOutputParameters(MockCheckedExpectedCall* call); + virtual void completeCallWhenMatchIsFound(); + virtual void failTest(const MockFailure& failure); + virtual void checkInputParameter(const MockNamedValue& actualParameter); + virtual void checkOutputParameter(const MockNamedValue& outputParameter); + virtual void discardCurrentlyMatchingExpectations(); + + enum ActualCallState { + CALL_IN_PROGRESS, + CALL_FAILED, + CALL_SUCCEED + }; + virtual void setState(ActualCallState state); + +private: + SimpleString functionName_; + unsigned int callOrder_; + MockFailureReporter* reporter_; + + ActualCallState state_; + bool expectationsChecked_; + MockCheckedExpectedCall* matchingExpectation_; + + MockExpectedCallsList potentiallyMatchingExpectations_; + const MockExpectedCallsList& allExpectations_; + + class MockOutputParametersListNode + { + public: + SimpleString name_; + SimpleString type_; + void* ptr_; + + MockOutputParametersListNode* next_; + MockOutputParametersListNode(const SimpleString& name, const SimpleString& type, void* ptr) + : name_(name), type_(type), ptr_(ptr), next_(NULLPTR) {} + }; + + MockOutputParametersListNode* outputParameterExpectations_; + + virtual void addOutputParameter(const SimpleString& name, const SimpleString& type, void* ptr); + virtual void cleanUpOutputParameterList(); +}; + +class MockActualCallTrace : public MockActualCall +{ +public: + MockActualCallTrace(); + virtual ~MockActualCallTrace() _destructor_override; + + virtual MockActualCall& withName(const SimpleString& name) _override; + virtual MockActualCall& withCallOrder(unsigned int) _override; + virtual MockActualCall& withBoolParameter(const SimpleString& name, bool value) _override; + virtual MockActualCall& withIntParameter(const SimpleString& name, int value) _override; + virtual MockActualCall& withUnsignedIntParameter(const SimpleString& name, unsigned int value) _override; + virtual MockActualCall& withLongIntParameter(const SimpleString& name, long int value) _override; + virtual MockActualCall& withUnsignedLongIntParameter(const SimpleString& name, unsigned long int value) _override; + virtual MockActualCall& withLongLongIntParameter(const SimpleString& name, cpputest_longlong value) _override; + virtual MockActualCall& withUnsignedLongLongIntParameter(const SimpleString& name, cpputest_ulonglong value) _override; + virtual MockActualCall& withDoubleParameter(const SimpleString& name, double value) _override; + virtual MockActualCall& withStringParameter(const SimpleString& name, const char* value) _override; + virtual MockActualCall& withPointerParameter(const SimpleString& name, void* value) _override; + virtual MockActualCall& withConstPointerParameter(const SimpleString& name, const void* value) _override; + virtual MockActualCall& withFunctionPointerParameter(const SimpleString& name, void (*value)()) _override; + virtual MockActualCall& withMemoryBufferParameter(const SimpleString& name, const unsigned char* value, size_t size) _override; + virtual MockActualCall& withParameterOfType(const SimpleString& typeName, const SimpleString& name, const void* value) _override; + virtual MockActualCall& withOutputParameter(const SimpleString& name, void* output) _override; + virtual MockActualCall& withOutputParameterOfType(const SimpleString& typeName, const SimpleString& name, void* output) _override; + + virtual bool hasReturnValue() _override; + virtual MockNamedValue returnValue() _override; + + virtual bool returnBoolValueOrDefault(bool default_value) _override; + virtual bool returnBoolValue() _override; + + virtual int returnIntValueOrDefault(int default_value) _override; + virtual int returnIntValue() _override; + + virtual unsigned long int returnUnsignedLongIntValue() _override; + virtual unsigned long int returnUnsignedLongIntValueOrDefault(unsigned long int) _override; + + virtual long int returnLongIntValue() _override; + virtual long int returnLongIntValueOrDefault(long int default_value) _override; + + virtual cpputest_ulonglong returnUnsignedLongLongIntValue() _override; + virtual cpputest_ulonglong returnUnsignedLongLongIntValueOrDefault(cpputest_ulonglong default_value) _override; + + virtual cpputest_longlong returnLongLongIntValue() _override; + virtual cpputest_longlong returnLongLongIntValueOrDefault(cpputest_longlong default_value) _override; + + virtual unsigned int returnUnsignedIntValue() _override; + virtual unsigned int returnUnsignedIntValueOrDefault(unsigned int default_value) _override; + + virtual const char * returnStringValueOrDefault(const char * default_value) _override; + virtual const char * returnStringValue() _override; + + virtual double returnDoubleValue() _override; + virtual double returnDoubleValueOrDefault(double default_value) _override; + + virtual void * returnPointerValue() _override; + virtual void * returnPointerValueOrDefault(void *) _override; + + virtual const void * returnConstPointerValue() _override; + virtual const void * returnConstPointerValueOrDefault(const void * default_value) _override; + + virtual void (*returnFunctionPointerValue())() _override; + virtual void (*returnFunctionPointerValueOrDefault(void (*)()))() _override; + + virtual MockActualCall& onObject(const void* objectPtr) _override; + + const char* getTraceOutput(); + void clear(); + static MockActualCallTrace& instance(); + static void clearInstance(); + +private: + SimpleString traceBuffer_; + + static MockActualCallTrace* instance_; + + void addParameterName(const SimpleString& name); +}; + +class MockIgnoredActualCall: public MockActualCall +{ +public: + virtual MockActualCall& withName(const SimpleString&) _override { return *this;} + virtual MockActualCall& withCallOrder(unsigned int) _override { return *this; } + virtual MockActualCall& withBoolParameter(const SimpleString&, bool) _override { return *this; } + virtual MockActualCall& withIntParameter(const SimpleString&, int) _override { return *this; } + virtual MockActualCall& withUnsignedIntParameter(const SimpleString&, unsigned int) _override { return *this; } + virtual MockActualCall& withLongIntParameter(const SimpleString&, long int) _override { return *this; } + virtual MockActualCall& withUnsignedLongIntParameter(const SimpleString&, unsigned long int) _override { return *this; } + virtual MockActualCall& withLongLongIntParameter(const SimpleString&, cpputest_longlong) _override { return *this; } + virtual MockActualCall& withUnsignedLongLongIntParameter(const SimpleString&, cpputest_ulonglong) _override { return *this; } + virtual MockActualCall& withDoubleParameter(const SimpleString&, double) _override { return *this; } + virtual MockActualCall& withStringParameter(const SimpleString&, const char*) _override { return *this; } + virtual MockActualCall& withPointerParameter(const SimpleString& , void*) _override { return *this; } + virtual MockActualCall& withConstPointerParameter(const SimpleString& , const void*) _override { return *this; } + virtual MockActualCall& withFunctionPointerParameter(const SimpleString& , void (*)()) _override { return *this; } + virtual MockActualCall& withMemoryBufferParameter(const SimpleString&, const unsigned char*, size_t) _override { return *this; } + virtual MockActualCall& withParameterOfType(const SimpleString&, const SimpleString&, const void*) _override { return *this; } + virtual MockActualCall& withOutputParameter(const SimpleString&, void*) _override { return *this; } + virtual MockActualCall& withOutputParameterOfType(const SimpleString&, const SimpleString&, void*) _override { return *this; } + + virtual bool hasReturnValue() _override { return false; } + virtual MockNamedValue returnValue() _override { return MockNamedValue(""); } + + virtual bool returnBoolValueOrDefault(bool value) _override { return value; } + virtual bool returnBoolValue() _override { return false; } + + virtual int returnIntValue() _override { return 0; } + virtual int returnIntValueOrDefault(int value) _override { return value; } + + virtual unsigned long int returnUnsignedLongIntValue() _override { return 0; } + virtual unsigned long int returnUnsignedLongIntValueOrDefault(unsigned long int value) _override { return value; } + + virtual long int returnLongIntValue() _override { return 0; } + virtual long int returnLongIntValueOrDefault(long int value) _override { return value; } + + virtual cpputest_ulonglong returnUnsignedLongLongIntValue() _override { return 0; } + virtual cpputest_ulonglong returnUnsignedLongLongIntValueOrDefault(cpputest_ulonglong value) _override { return value; } + + virtual cpputest_longlong returnLongLongIntValue() _override { return 0; } + virtual cpputest_longlong returnLongLongIntValueOrDefault(cpputest_longlong value) _override { return value; } + + virtual unsigned int returnUnsignedIntValue() _override { return 0; } + virtual unsigned int returnUnsignedIntValueOrDefault(unsigned int value) _override { return value; } + + virtual double returnDoubleValue() _override { return 0.0; } + virtual double returnDoubleValueOrDefault(double value) _override { return value; } + + virtual const char * returnStringValue() _override { return ""; } + virtual const char * returnStringValueOrDefault(const char * value) _override { return value; } + + virtual void * returnPointerValue() _override { return NULLPTR; } + virtual void * returnPointerValueOrDefault(void * value) _override { return value; } + + virtual const void * returnConstPointerValue() _override { return NULLPTR; } + virtual const void * returnConstPointerValueOrDefault(const void * value) _override { return value; } + + virtual void (*returnFunctionPointerValue())() _override { return NULLPTR; } + virtual void (*returnFunctionPointerValueOrDefault(void (*value)()))() _override { return value; } + + virtual MockActualCall& onObject(const void* ) _override { return *this; } + + static MockIgnoredActualCall& instance(); +}; + +#endif diff --git a/test/test_utility/include/CppUTestExt/MockCheckedExpectedCall.h b/test/test_utility/include/CppUTestExt/MockCheckedExpectedCall.h new file mode 100644 index 0000000..2079577 --- /dev/null +++ b/test/test_utility/include/CppUTestExt/MockCheckedExpectedCall.h @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the 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 EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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 D_MockCheckedExpectedCall_h +#define D_MockCheckedExpectedCall_h + +#include "CppUTestExt/MockExpectedCall.h" +#include "CppUTestExt/MockNamedValue.h" + +class MockCheckedExpectedCall : public MockExpectedCall +{ + +public: + MockCheckedExpectedCall(); + MockCheckedExpectedCall(unsigned int numCalls); + virtual ~MockCheckedExpectedCall() _destructor_override; + + virtual MockExpectedCall& withName(const SimpleString& name) _override; + virtual MockExpectedCall& withCallOrder(unsigned int callOrder) _override { return withCallOrder(callOrder, callOrder); } + virtual MockExpectedCall& withCallOrder(unsigned int initialCallOrder, unsigned int finalCallOrder) _override; + virtual MockExpectedCall& withBoolParameter(const SimpleString& name, bool value) _override; + virtual MockExpectedCall& withIntParameter(const SimpleString& name, int value) _override; + virtual MockExpectedCall& withUnsignedIntParameter(const SimpleString& name, unsigned int value) _override; + virtual MockExpectedCall& withLongIntParameter(const SimpleString& name, long int value) _override; + virtual MockExpectedCall& withUnsignedLongIntParameter(const SimpleString& name, unsigned long int value) _override; + virtual MockExpectedCall& withLongLongIntParameter(const SimpleString& name, cpputest_longlong value) _override; + virtual MockExpectedCall& withUnsignedLongLongIntParameter(const SimpleString& name, cpputest_ulonglong value) _override; + virtual MockExpectedCall& withDoubleParameter(const SimpleString& name, double value) _override; + virtual MockExpectedCall& withDoubleParameter(const SimpleString& name, double value, double tolerance) _override; + virtual MockExpectedCall& withStringParameter(const SimpleString& name, const char* value) _override; + virtual MockExpectedCall& withPointerParameter(const SimpleString& name, void* value) _override; + virtual MockExpectedCall& withConstPointerParameter(const SimpleString& name, const void* value) _override; + virtual MockExpectedCall& withFunctionPointerParameter(const SimpleString& name, void (*value)()) _override; + virtual MockExpectedCall& withMemoryBufferParameter(const SimpleString& name, const unsigned char* value, size_t size) _override; + virtual MockExpectedCall& withParameterOfType(const SimpleString& typeName, const SimpleString& name, const void* value) _override; + virtual MockExpectedCall& withOutputParameterReturning(const SimpleString& name, const void* value, size_t size) _override; + virtual MockExpectedCall& withOutputParameterOfTypeReturning(const SimpleString& typeName, const SimpleString& name, const void* value) _override; + virtual MockExpectedCall& withUnmodifiedOutputParameter(const SimpleString& name) _override; + virtual MockExpectedCall& ignoreOtherParameters() _override; + + virtual MockExpectedCall& andReturnValue(bool value) _override; + virtual MockExpectedCall& andReturnValue(int value) _override; + virtual MockExpectedCall& andReturnValue(unsigned int value) _override; + virtual MockExpectedCall& andReturnValue(long int value) _override; + virtual MockExpectedCall& andReturnValue(unsigned long int value) _override; + virtual MockExpectedCall& andReturnValue(cpputest_longlong value) _override; + virtual MockExpectedCall& andReturnValue(cpputest_ulonglong value) _override; + virtual MockExpectedCall& andReturnValue(double value) _override; + virtual MockExpectedCall& andReturnValue(const char* value) _override; + virtual MockExpectedCall& andReturnValue(void* value) _override; + virtual MockExpectedCall& andReturnValue(const void* value) _override; + virtual MockExpectedCall& andReturnValue(void (*value)()) _override; + + virtual MockNamedValue returnValue(); + + virtual MockExpectedCall& onObject(void* objectPtr) _override; + + virtual MockNamedValue getInputParameter(const SimpleString& name); + virtual MockNamedValue getOutputParameter(const SimpleString& name); + virtual SimpleString getInputParameterType(const SimpleString& name); + virtual SimpleString getInputParameterValueString(const SimpleString& name); + + virtual bool hasInputParameterWithName(const SimpleString& name); + virtual bool hasInputParameter(const MockNamedValue& parameter); + virtual bool hasOutputParameterWithName(const SimpleString& name); + virtual bool hasOutputParameter(const MockNamedValue& parameter); + virtual bool relatesTo(const SimpleString& functionName); + virtual bool relatesToObject(const void* objectPtr) const; + + virtual bool isFulfilled(); + virtual bool canMatchActualCalls(); + virtual bool isMatchingActualCallAndFinalized(); + virtual bool isMatchingActualCall(); + virtual bool areParametersMatchingActualCall(); + virtual bool isOutOfOrder() const; + + virtual void callWasMade(unsigned int callOrder); + virtual void inputParameterWasPassed(const SimpleString& name); + virtual void outputParameterWasPassed(const SimpleString& name); + virtual void finalizeActualCallMatch(); + virtual void wasPassedToObject(); + virtual void resetActualCallMatchingState(); + + virtual SimpleString callToString(); + virtual SimpleString missingParametersToString(); + + enum { NO_EXPECTED_CALL_ORDER = 0 }; + + virtual unsigned int getActualCallsFulfilled() const; + +protected: + void setName(const SimpleString& name); + SimpleString getName() const; + +private: + SimpleString functionName_; + + class MockExpectedFunctionParameter : public MockNamedValue + { + public: + MockExpectedFunctionParameter(const SimpleString& name); + void setMatchesActualCall(bool b); + bool isMatchingActualCall() const; + + private: + bool matchesActualCall_; + }; + + MockExpectedFunctionParameter* item(MockNamedValueListNode* node); + + bool ignoreOtherParameters_; + bool isActualCallMatchFinalized_; + unsigned int initialExpectedCallOrder_; + unsigned int finalExpectedCallOrder_; + bool outOfOrder_; + MockNamedValueList* inputParameters_; + MockNamedValueList* outputParameters_; + MockNamedValue returnValue_; + void* objectPtr_; + bool isSpecificObjectExpected_; + bool wasPassedToObject_; + unsigned int actualCalls_; + unsigned int expectedCalls_; +}; + +class MockIgnoredExpectedCall: public MockExpectedCall +{ +public: + + virtual MockExpectedCall& withName(const SimpleString&) _override { return *this;} + virtual MockExpectedCall& withCallOrder(unsigned int) _override { return *this; } + virtual MockExpectedCall& withCallOrder(unsigned int, unsigned int) _override { return *this; } + virtual MockExpectedCall& withBoolParameter(const SimpleString&, bool) _override { return *this; } + virtual MockExpectedCall& withIntParameter(const SimpleString&, int) _override { return *this; } + virtual MockExpectedCall& withUnsignedIntParameter(const SimpleString&, unsigned int) _override{ return *this; } + virtual MockExpectedCall& withLongIntParameter(const SimpleString&, long int) _override { return *this; } + virtual MockExpectedCall& withUnsignedLongIntParameter(const SimpleString&, unsigned long int) _override { return *this; } + virtual MockExpectedCall& withLongLongIntParameter(const SimpleString&, cpputest_longlong) _override { return *this; } + virtual MockExpectedCall& withUnsignedLongLongIntParameter(const SimpleString&, cpputest_ulonglong) _override { return *this; } + virtual MockExpectedCall& withDoubleParameter(const SimpleString&, double) _override { return *this; } + virtual MockExpectedCall& withDoubleParameter(const SimpleString&, double, double) _override { return *this; } + virtual MockExpectedCall& withStringParameter(const SimpleString&, const char*) _override { return *this; } + virtual MockExpectedCall& withPointerParameter(const SimpleString& , void*) _override { return *this; } + virtual MockExpectedCall& withConstPointerParameter(const SimpleString& , const void*) _override { return *this; } + virtual MockExpectedCall& withFunctionPointerParameter(const SimpleString& , void(*)()) _override { return *this; } + virtual MockExpectedCall& withMemoryBufferParameter(const SimpleString&, const unsigned char*, size_t) _override { return *this; } + virtual MockExpectedCall& withParameterOfType(const SimpleString&, const SimpleString&, const void*) _override { return *this; } + virtual MockExpectedCall& withOutputParameterReturning(const SimpleString&, const void*, size_t) _override { return *this; } + virtual MockExpectedCall& withOutputParameterOfTypeReturning(const SimpleString&, const SimpleString&, const void*) _override { return *this; } + virtual MockExpectedCall& withUnmodifiedOutputParameter(const SimpleString&) _override { return *this; } + virtual MockExpectedCall& ignoreOtherParameters() _override { return *this;} + + virtual MockExpectedCall& andReturnValue(bool) _override { return *this; } + virtual MockExpectedCall& andReturnValue(int) _override { return *this; } + virtual MockExpectedCall& andReturnValue(unsigned int) _override { return *this; } + virtual MockExpectedCall& andReturnValue(long int) _override { return *this; } + virtual MockExpectedCall& andReturnValue(unsigned long int) _override { return *this; } + virtual MockExpectedCall& andReturnValue(cpputest_longlong) _override { return *this; } + virtual MockExpectedCall& andReturnValue(cpputest_ulonglong) _override { return *this; } + virtual MockExpectedCall& andReturnValue(double) _override { return *this;} + virtual MockExpectedCall& andReturnValue(const char*) _override { return *this; } + virtual MockExpectedCall& andReturnValue(void*) _override { return *this; } + virtual MockExpectedCall& andReturnValue(const void*) _override { return *this; } + virtual MockExpectedCall& andReturnValue(void (*)()) _override { return *this; } + + virtual MockExpectedCall& onObject(void*) _override { return *this; } + + static MockExpectedCall& instance(); +}; + +#endif diff --git a/test/test_utility/include/CppUTestExt/MockExpectedCall.h b/test/test_utility/include/CppUTestExt/MockExpectedCall.h new file mode 100644 index 0000000..51630dc --- /dev/null +++ b/test/test_utility/include/CppUTestExt/MockExpectedCall.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the 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 EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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 D_MockExpectedCall_h +#define D_MockExpectedCall_h + +#include "CppUTest/CppUTestConfig.h" + +class MockNamedValue; + +extern SimpleString StringFrom(const MockNamedValue& parameter); + +class MockExpectedCall +{ +public: + MockExpectedCall(); + virtual ~MockExpectedCall(); + + virtual MockExpectedCall& withName(const SimpleString& name)=0; + virtual MockExpectedCall& withCallOrder(unsigned int)=0; + virtual MockExpectedCall& withCallOrder(unsigned int, unsigned int)=0; + MockExpectedCall& withParameter(const SimpleString& name, bool value) { return withBoolParameter(name, value); } + MockExpectedCall& withParameter(const SimpleString& name, int value) { return withIntParameter(name, value); } + MockExpectedCall& withParameter(const SimpleString& name, unsigned int value) { return withUnsignedIntParameter(name, value); } + MockExpectedCall& withParameter(const SimpleString& name, long int value) { return withLongIntParameter(name, value); } + MockExpectedCall& withParameter(const SimpleString& name, unsigned long int value) { return withUnsignedLongIntParameter(name, value); } + MockExpectedCall& withParameter(const SimpleString& name, cpputest_longlong value) { return withLongLongIntParameter(name, value); } + MockExpectedCall& withParameter(const SimpleString& name, cpputest_ulonglong value) { return withUnsignedLongLongIntParameter(name, value); } + MockExpectedCall& withParameter(const SimpleString& name, double value) { return withDoubleParameter(name, value); } + MockExpectedCall& withParameter(const SimpleString& name, double value, double tolerance) { return withDoubleParameter(name, value, tolerance); } + MockExpectedCall& withParameter(const SimpleString& name, const char* value) { return withStringParameter(name, value); } + MockExpectedCall& withParameter(const SimpleString& name, void* value) { return withPointerParameter(name, value); } + MockExpectedCall& withParameter(const SimpleString& name, const void* value) { return withConstPointerParameter(name, value); } + MockExpectedCall& withParameter(const SimpleString& name, void (*value)()) { return withFunctionPointerParameter(name, value); } + MockExpectedCall& withParameter(const SimpleString& name, const unsigned char* value, size_t size) { return withMemoryBufferParameter(name, value, size); } + virtual MockExpectedCall& withParameterOfType(const SimpleString& typeName, const SimpleString& name, const void* value)=0; + virtual MockExpectedCall& withOutputParameterReturning(const SimpleString& name, const void* value, size_t size)=0; + virtual MockExpectedCall& withOutputParameterOfTypeReturning(const SimpleString& typeName, const SimpleString& name, const void* value)=0; + virtual MockExpectedCall& withUnmodifiedOutputParameter(const SimpleString& name)=0; + virtual MockExpectedCall& ignoreOtherParameters()=0; + + virtual MockExpectedCall& withBoolParameter(const SimpleString& name, bool value)=0; + virtual MockExpectedCall& withIntParameter(const SimpleString& name, int value)=0; + virtual MockExpectedCall& withUnsignedIntParameter(const SimpleString& name, unsigned int value)=0; + virtual MockExpectedCall& withLongIntParameter(const SimpleString& name, long int value)=0; + virtual MockExpectedCall& withUnsignedLongIntParameter(const SimpleString& name, unsigned long int value)=0; + virtual MockExpectedCall& withLongLongIntParameter(const SimpleString& name, cpputest_longlong value)=0; + virtual MockExpectedCall& withUnsignedLongLongIntParameter(const SimpleString& name, cpputest_ulonglong value)=0; + virtual MockExpectedCall& withDoubleParameter(const SimpleString& name, double value)=0; + virtual MockExpectedCall& withDoubleParameter(const SimpleString& name, double value, double tolerance)=0; + virtual MockExpectedCall& withStringParameter(const SimpleString& name, const char* value)=0; + virtual MockExpectedCall& withPointerParameter(const SimpleString& name, void* value)=0; + virtual MockExpectedCall& withFunctionPointerParameter(const SimpleString& name, void (*value)())=0; + virtual MockExpectedCall& withConstPointerParameter(const SimpleString& name, const void* value)=0; + virtual MockExpectedCall& withMemoryBufferParameter(const SimpleString& name, const unsigned char* value, size_t size)=0; + virtual MockExpectedCall& andReturnValue(bool value)=0; + virtual MockExpectedCall& andReturnValue(int value)=0; + virtual MockExpectedCall& andReturnValue(unsigned int value)=0; + virtual MockExpectedCall& andReturnValue(long int value)=0; + virtual MockExpectedCall& andReturnValue(unsigned long int value)=0; + virtual MockExpectedCall& andReturnValue(cpputest_longlong value)=0; + virtual MockExpectedCall& andReturnValue(cpputest_ulonglong value)=0; + virtual MockExpectedCall& andReturnValue(double value)=0; + virtual MockExpectedCall& andReturnValue(const char* value)=0; + virtual MockExpectedCall& andReturnValue(void* value)=0; + virtual MockExpectedCall& andReturnValue(const void* value)=0; + virtual MockExpectedCall& andReturnValue(void (*value)())=0; + + virtual MockExpectedCall& onObject(void* objectPtr)=0; +}; + +#endif diff --git a/test/test_utility/include/CppUTestExt/MockExpectedCallsList.h b/test/test_utility/include/CppUTestExt/MockExpectedCallsList.h new file mode 100644 index 0000000..74c920d --- /dev/null +++ b/test/test_utility/include/CppUTestExt/MockExpectedCallsList.h @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the 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 EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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 D_MockExpectedCallsList_h +#define D_MockExpectedCallsList_h + +class MockCheckedExpectedCall; +class MockNamedValue; + +class MockExpectedCallsList +{ + +public: + MockExpectedCallsList(); + virtual ~MockExpectedCallsList(); + virtual void deleteAllExpectationsAndClearList(); + + virtual unsigned int size() const; + virtual unsigned int amountOfActualCallsFulfilledFor(const SimpleString& name) const; + virtual unsigned int amountOfUnfulfilledExpectations() const; + virtual bool hasUnfulfilledExpectations() const; + virtual bool hasFinalizedMatchingExpectations() const; + virtual bool hasUnmatchingExpectationsBecauseOfMissingParameters() const; + virtual bool hasExpectationWithName(const SimpleString& name) const; + virtual bool hasCallsOutOfOrder() const; + virtual bool isEmpty() const; + + virtual void addExpectedCall(MockCheckedExpectedCall* call); + virtual void addExpectations(const MockExpectedCallsList& list); + virtual void addExpectationsRelatedTo(const SimpleString& name, const MockExpectedCallsList& list); + + virtual void onlyKeepOutOfOrderExpectations(); + virtual void addPotentiallyMatchingExpectations(const MockExpectedCallsList& list); + + virtual void onlyKeepExpectationsRelatedTo(const SimpleString& name); + virtual void onlyKeepExpectationsWithInputParameter(const MockNamedValue& parameter); + virtual void onlyKeepExpectationsWithInputParameterName(const SimpleString& name); + virtual void onlyKeepExpectationsWithOutputParameter(const MockNamedValue& parameter); + virtual void onlyKeepExpectationsWithOutputParameterName(const SimpleString& name); + virtual void onlyKeepExpectationsOnObject(const void* objectPtr); + virtual void onlyKeepUnmatchingExpectations(); + + virtual MockCheckedExpectedCall* removeFirstFinalizedMatchingExpectation(); + virtual MockCheckedExpectedCall* removeFirstMatchingExpectation(); + virtual MockCheckedExpectedCall* getFirstMatchingExpectation(); + + virtual void resetActualCallMatchingState(); + virtual void wasPassedToObject(); + virtual void parameterWasPassed(const SimpleString& parameterName); + virtual void outputParameterWasPassed(const SimpleString& parameterName); + + virtual SimpleString unfulfilledCallsToString(const SimpleString& linePrefix = "") const; + virtual SimpleString fulfilledCallsToString(const SimpleString& linePrefix = "") const; + virtual SimpleString missingParametersToString() const; + +protected: + virtual void pruneEmptyNodeFromList(); + + class MockExpectedCallsListNode + { + public: + MockCheckedExpectedCall* expectedCall_; + + MockExpectedCallsListNode* next_; + MockExpectedCallsListNode(MockCheckedExpectedCall* expectedCall) + : expectedCall_(expectedCall), next_(NULLPTR) {} + }; + +private: + MockExpectedCallsListNode* head_; + + MockExpectedCallsList(const MockExpectedCallsList&); +}; + +#endif diff --git a/test/test_utility/include/CppUTestExt/MockFailure.h b/test/test_utility/include/CppUTestExt/MockFailure.h new file mode 100644 index 0000000..af25785 --- /dev/null +++ b/test/test_utility/include/CppUTestExt/MockFailure.h @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the 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 EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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 D_MockFailure_h +#define D_MockFailure_h + +#include "CppUTest/TestFailure.h" + +class MockExpectedCallsList; +class MockCheckedActualCall; +class MockNamedValue; +class MockFailure; + +class MockFailureReporter +{ +protected: + bool crashOnFailure_; +public: + MockFailureReporter() : crashOnFailure_(false){} + virtual ~MockFailureReporter() {} + + virtual void failTest(const MockFailure& failure); + virtual UtestShell* getTestToFail(); + + virtual void crashOnFailure(bool shouldCrash) { crashOnFailure_ = shouldCrash; } +}; + +class MockFailure : public TestFailure +{ +public: + MockFailure(UtestShell* test); + virtual ~MockFailure() _destructor_override {} +protected: + void addExpectationsAndCallHistory(const MockExpectedCallsList& expectations); + void addExpectationsAndCallHistoryRelatedTo(const SimpleString& function, const MockExpectedCallsList& expectations); +}; + +class MockExpectedCallsDidntHappenFailure : public MockFailure +{ +public: + MockExpectedCallsDidntHappenFailure(UtestShell* test, const MockExpectedCallsList& expectations); +}; + +class MockUnexpectedCallHappenedFailure : public MockFailure +{ +public: + MockUnexpectedCallHappenedFailure(UtestShell* test, const SimpleString& name, const MockExpectedCallsList& expectations); +}; + +class MockCallOrderFailure : public MockFailure +{ +public: + MockCallOrderFailure(UtestShell* test, const MockExpectedCallsList& expectations); +}; + +class MockUnexpectedInputParameterFailure : public MockFailure +{ +public: + MockUnexpectedInputParameterFailure(UtestShell* test, const SimpleString& functionName, const MockNamedValue& parameter, const MockExpectedCallsList& expectations); +}; + +class MockUnexpectedOutputParameterFailure : public MockFailure +{ +public: + MockUnexpectedOutputParameterFailure(UtestShell* test, const SimpleString& functionName, const MockNamedValue& parameter, const MockExpectedCallsList& expectations); +}; + +class MockExpectedParameterDidntHappenFailure : public MockFailure +{ +public: + MockExpectedParameterDidntHappenFailure(UtestShell* test, const SimpleString& functionName, const MockExpectedCallsList& expectations); +}; + +class MockNoWayToCompareCustomTypeFailure : public MockFailure +{ +public: + MockNoWayToCompareCustomTypeFailure(UtestShell* test, const SimpleString& typeName); +}; + +class MockNoWayToCopyCustomTypeFailure : public MockFailure +{ +public: + MockNoWayToCopyCustomTypeFailure(UtestShell* test, const SimpleString& typeName); +}; + +class MockUnexpectedObjectFailure : public MockFailure +{ +public: + MockUnexpectedObjectFailure(UtestShell* test, const SimpleString& functionName, const void* expected, const MockExpectedCallsList& expectations); +}; + +class MockExpectedObjectDidntHappenFailure : public MockFailure +{ +public: + MockExpectedObjectDidntHappenFailure(UtestShell* test, const SimpleString& functionName, const MockExpectedCallsList& expectations); +}; + +#endif diff --git a/test/test_utility/include/CppUTestExt/MockNamedValue.h b/test/test_utility/include/CppUTestExt/MockNamedValue.h new file mode 100644 index 0000000..426b70c --- /dev/null +++ b/test/test_utility/include/CppUTestExt/MockNamedValue.h @@ -0,0 +1,251 @@ +/* + * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the 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 EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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 D_MockNamedValue_h +#define D_MockNamedValue_h + +#include "CppUTest/CppUTestConfig.h" + +/* + * MockNamedValueComparator is an interface that needs to be used when creating Comparators. + * This is needed when comparing values of non-native type. + */ + +class MockNamedValueComparator +{ +public: + MockNamedValueComparator() {} + virtual ~MockNamedValueComparator() {} + + virtual bool isEqual(const void* object1, const void* object2)=0; + virtual SimpleString valueToString(const void* object)=0; +}; + +/* + * MockNamedValueCopier is an interface that needs to be used when creating Copiers. + * This is needed when copying values of non-native type. + */ + +class MockNamedValueCopier +{ +public: + MockNamedValueCopier() {} + virtual ~MockNamedValueCopier() {} + + virtual void copy(void* out, const void* in)=0; +}; + + +class MockFunctionComparator : public MockNamedValueComparator +{ +public: + typedef bool (*isEqualFunction)(const void*, const void*); + typedef SimpleString (*valueToStringFunction)(const void*); + + MockFunctionComparator(isEqualFunction equal, valueToStringFunction valToString) + : equal_(equal), valueToString_(valToString) {} + + virtual bool isEqual(const void* object1, const void* object2) _override { return equal_(object1, object2); } + virtual SimpleString valueToString(const void* object) _override { return valueToString_(object); } +private: + isEqualFunction equal_; + valueToStringFunction valueToString_; +}; + +class MockFunctionCopier : public MockNamedValueCopier +{ +public: + typedef void (*copyFunction)(void*, const void*); + + MockFunctionCopier(copyFunction copier) : copier_(copier) {} + + virtual void copy(void* dst, const void* src) _override { copier_(dst, src); } + +private: + copyFunction copier_; +}; + +/* + * MockNamedValue is the generic value class used. It encapsulates basic types and can use them "as if one" + * Also it enables other types by putting object pointers. They can be compared with comparators. + * + * Basically this class ties together a Name, a Value, a Type, and a Comparator + */ + +class MockNamedValueComparatorsAndCopiersRepository; +class MockNamedValue +{ +public: + MockNamedValue(const SimpleString& name); + DEFAULT_COPY_CONSTRUCTOR(MockNamedValue) + virtual ~MockNamedValue(); + + virtual void setValue(bool value); + virtual void setValue(int value); + virtual void setValue(unsigned int value); + virtual void setValue(long int value); + virtual void setValue(unsigned long int value); + virtual void setValue(cpputest_longlong value); + virtual void setValue(cpputest_ulonglong value); + virtual void setValue(double value); + virtual void setValue(double value, double tolerance); + virtual void setValue(void* value); + virtual void setValue(const void* value); + virtual void setValue(void (*value)()); + virtual void setValue(const char* value); + virtual void setMemoryBuffer(const unsigned char* value, size_t size); + virtual void setConstObjectPointer(const SimpleString& type, const void* objectPtr); + virtual void setObjectPointer(const SimpleString& type, void* objectPtr); + virtual void setSize(size_t size); + + virtual void setName(const char* name); + + virtual bool equals(const MockNamedValue& p) const; + virtual bool compatibleForCopying(const MockNamedValue& p) const; + + virtual SimpleString toString() const; + + virtual SimpleString getName() const; + virtual SimpleString getType() const; + + virtual bool getBoolValue() const; + virtual int getIntValue() const; + virtual unsigned int getUnsignedIntValue() const; + virtual long int getLongIntValue() const; + virtual unsigned long int getUnsignedLongIntValue() const; + virtual cpputest_longlong getLongLongIntValue() const; + virtual cpputest_ulonglong getUnsignedLongLongIntValue() const; + virtual double getDoubleValue() const; + virtual double getDoubleTolerance() const; + virtual const char* getStringValue() const; + virtual void* getPointerValue() const; + virtual const void* getConstPointerValue() const; + virtual void (*getFunctionPointerValue() const)(); + virtual const unsigned char* getMemoryBuffer() const; + virtual const void* getConstObjectPointer() const; + virtual void* getObjectPointer() const; + virtual size_t getSize() const; + + + virtual MockNamedValueComparator* getComparator() const; + virtual MockNamedValueCopier* getCopier() const; + + static void setDefaultComparatorsAndCopiersRepository(MockNamedValueComparatorsAndCopiersRepository* repository); + static MockNamedValueComparatorsAndCopiersRepository* getDefaultComparatorsAndCopiersRepository(); + + static const double defaultDoubleTolerance; +private: + SimpleString name_; + SimpleString type_; + union { + bool boolValue_; + int intValue_; + unsigned int unsignedIntValue_; + long int longIntValue_; + unsigned long int unsignedLongIntValue_; +#ifdef CPPUTEST_USE_LONG_LONG + cpputest_longlong longLongIntValue_; + cpputest_ulonglong unsignedLongLongIntValue_; +#else + char longLongPlaceholder_[CPPUTEST_SIZE_OF_FAKE_LONG_LONG_TYPE]; +#endif + struct { + double value; + double tolerance; + } doubleValue_; + const char* stringValue_; + void* pointerValue_; + const void* constPointerValue_; + void (*functionPointerValue_)(); + const unsigned char* memoryBufferValue_; + const void* constObjectPointerValue_; + void* objectPointerValue_; + const void* outputPointerValue_; + } value_; + size_t size_; + MockNamedValueComparator* comparator_; + MockNamedValueCopier* copier_; + static MockNamedValueComparatorsAndCopiersRepository* defaultRepository_; +}; + +class MockNamedValueListNode +{ +public: + MockNamedValueListNode(MockNamedValue* newValue); + + SimpleString getName() const; + SimpleString getType() const; + + MockNamedValueListNode* next(); + MockNamedValue* item(); + + void destroy(); + void setNext(MockNamedValueListNode* node); +private: + MockNamedValue* data_; + MockNamedValueListNode* next_; +}; + +class MockNamedValueList +{ +public: + MockNamedValueList(); + + MockNamedValueListNode* begin(); + + void add(MockNamedValue* newValue); + void clear(); + + MockNamedValue* getValueByName(const SimpleString& name); + +private: + MockNamedValueListNode* head_; +}; + +/* + * MockParameterComparatorRepository is a class which stores comparators and copiers which can be used for comparing non-native types + * + */ + +struct MockNamedValueComparatorsAndCopiersRepositoryNode; +class MockNamedValueComparatorsAndCopiersRepository +{ + MockNamedValueComparatorsAndCopiersRepositoryNode* head_; +public: + MockNamedValueComparatorsAndCopiersRepository(); + virtual ~MockNamedValueComparatorsAndCopiersRepository(); + + virtual void installComparator(const SimpleString& name, MockNamedValueComparator& comparator); + virtual void installCopier(const SimpleString& name, MockNamedValueCopier& copier); + virtual void installComparatorsAndCopiers(const MockNamedValueComparatorsAndCopiersRepository& repository); + virtual MockNamedValueComparator* getComparatorForType(const SimpleString& name); + virtual MockNamedValueCopier* getCopierForType(const SimpleString& name); + + void clear(); +}; + +#endif diff --git a/test/test_utility/include/CppUTestExt/MockSupport.h b/test/test_utility/include/CppUTestExt/MockSupport.h new file mode 100644 index 0000000..60a5131 --- /dev/null +++ b/test/test_utility/include/CppUTestExt/MockSupport.h @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the 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 EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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 D_MockSupport_h +#define D_MockSupport_h + +#include "CppUTestExt/MockFailure.h" +#include "CppUTestExt/MockCheckedActualCall.h" +#include "CppUTestExt/MockCheckedExpectedCall.h" +#include "CppUTestExt/MockExpectedCallsList.h" + +class UtestShell; +class MockSupport; + +/* This allows access to "the global" mocking support for easier testing */ +MockSupport& mock(const SimpleString& mockName = "", MockFailureReporter* failureReporterForThisCall = NULLPTR); + +class MockSupport +{ +public: + MockSupport(const SimpleString& mockName = ""); + virtual ~MockSupport(); + + virtual void strictOrder(); + virtual MockExpectedCall& expectOneCall(const SimpleString& functionName); + virtual void expectNoCall(const SimpleString& functionName); + virtual MockExpectedCall& expectNCalls(unsigned int amount, const SimpleString& functionName); + virtual MockActualCall& actualCall(const SimpleString& functionName); + virtual bool hasReturnValue(); + virtual MockNamedValue returnValue(); + virtual bool boolReturnValue(); + virtual bool returnBoolValueOrDefault(bool defaultValue); + virtual int intReturnValue(); + virtual int returnIntValueOrDefault(int defaultValue); + virtual unsigned int unsignedIntReturnValue(); + virtual long int longIntReturnValue(); + virtual long int returnLongIntValueOrDefault(long int defaultValue); + virtual unsigned long int unsignedLongIntReturnValue(); + virtual unsigned long int returnUnsignedLongIntValueOrDefault(unsigned long int defaultValue); + virtual cpputest_longlong longLongIntReturnValue(); + virtual cpputest_longlong returnLongLongIntValueOrDefault(cpputest_longlong defaultValue); + virtual cpputest_ulonglong unsignedLongLongIntReturnValue(); + virtual cpputest_ulonglong returnUnsignedLongLongIntValueOrDefault(cpputest_ulonglong defaultValue); + virtual unsigned int returnUnsignedIntValueOrDefault(unsigned int defaultValue); + virtual const char* stringReturnValue(); + virtual const char* returnStringValueOrDefault(const char * defaultValue); + virtual double returnDoubleValueOrDefault(double defaultValue); + virtual double doubleReturnValue(); + virtual void* pointerReturnValue(); + virtual void* returnPointerValueOrDefault(void * defaultValue); + virtual const void* returnConstPointerValueOrDefault(const void * defaultValue); + virtual const void* constPointerReturnValue(); + virtual void (*returnFunctionPointerValueOrDefault(void (*defaultValue)()))(); + virtual void (*functionPointerReturnValue())(); + + bool hasData(const SimpleString& name); + void setData(const SimpleString& name, bool value); + void setData(const SimpleString& name, int value); + void setData(const SimpleString& name, unsigned int value); + void setData(const SimpleString& name, const char* value); + void setData(const SimpleString& name, double value); + void setData(const SimpleString& name, void* value); + void setData(const SimpleString& name, const void* value); + void setData(const SimpleString& name, void (*value)()); + void setDataObject(const SimpleString& name, const SimpleString& type, void* value); + void setDataConstObject(const SimpleString& name, const SimpleString& type, const void* value); + MockNamedValue getData(const SimpleString& name); + + MockSupport* getMockSupportScope(const SimpleString& name); + + const char* getTraceOutput(); + /* + * The following functions are recursively through the lower MockSupports scopes + * This means, if you do mock().disable() it will disable *all* mocking scopes, including mock("myScope"). + */ + + virtual void disable(); + virtual void enable(); + virtual void tracing(bool enabled); + virtual void ignoreOtherCalls(); + + virtual void checkExpectations(); + virtual bool expectedCallsLeft(); + + virtual void clear(); + virtual void crashOnFailure(bool shouldFail = true); + + /* + * Each mock() call will set the activeReporter to standard, unless a special reporter is passed for this call. + */ + + virtual void setMockFailureStandardReporter(MockFailureReporter* reporter); + virtual void setActiveReporter(MockFailureReporter* activeReporter); + virtual void setDefaultComparatorsAndCopiersRepository(); + + virtual void installComparator(const SimpleString& typeName, MockNamedValueComparator& comparator); + virtual void installCopier(const SimpleString& typeName, MockNamedValueCopier& copier); + virtual void installComparatorsAndCopiers(const MockNamedValueComparatorsAndCopiersRepository& repository); + virtual void removeAllComparatorsAndCopiers(); + +protected: + MockSupport* clone(const SimpleString& mockName); + virtual MockCheckedActualCall *createActualCall(); + virtual void failTest(MockFailure& failure); + void countCheck(); + +private: + unsigned int actualCallOrder_; + unsigned int expectedCallOrder_; + bool strictOrdering_; + MockFailureReporter *activeReporter_; + MockFailureReporter *standardReporter_; + MockFailureReporter defaultReporter_; + MockExpectedCallsList expectations_; + bool ignoreOtherCalls_; + bool enabled_; + MockCheckedActualCall *lastActualFunctionCall_; + MockNamedValueComparatorsAndCopiersRepository comparatorsAndCopiersRepository_; + MockNamedValueList data_; + const SimpleString mockName_; + + bool tracing_; + + void checkExpectationsOfLastActualCall(); + bool wasLastActualCallFulfilled(); + void failTestWithExpectedCallsNotFulfilled(); + void failTestWithOutOfOrderCalls(); + + MockNamedValue* retrieveDataFromStore(const SimpleString& name); + + MockSupport* getMockSupport(MockNamedValueListNode* node); + + bool callIsIgnored(const SimpleString& functionName); + bool hasCallsOutOfOrder(); + + SimpleString appendScopeToName(const SimpleString& functionName); + +}; + +#endif + diff --git a/test/test_utility/include/CppUTestExt/MockSupportPlugin.h b/test/test_utility/include/CppUTestExt/MockSupportPlugin.h new file mode 100644 index 0000000..cc0be20 --- /dev/null +++ b/test/test_utility/include/CppUTestExt/MockSupportPlugin.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the 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 EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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 D_MockSupportPlugin_h +#define D_MockSupportPlugin_h + +#include "CppUTest/TestPlugin.h" +#include "CppUTestExt/MockNamedValue.h" + +class MockSupportPlugin : public TestPlugin +{ +public: + MockSupportPlugin(const SimpleString& name = "MockSupportPLugin"); + virtual ~MockSupportPlugin() _destructor_override; + + virtual void preTestAction(UtestShell&, TestResult&) _override; + virtual void postTestAction(UtestShell&, TestResult&) _override; + + virtual void installComparator(const SimpleString& name, MockNamedValueComparator& comparator); + virtual void installCopier(const SimpleString& name, MockNamedValueCopier& copier); + + void clear(); +private: + MockNamedValueComparatorsAndCopiersRepository repository_; +}; + +#endif diff --git a/test/test_utility/include/CppUTestExt/MockSupport_c.h b/test/test_utility/include/CppUTestExt/MockSupport_c.h new file mode 100644 index 0000000..32f2b7d --- /dev/null +++ b/test/test_utility/include/CppUTestExt/MockSupport_c.h @@ -0,0 +1,238 @@ +/* + * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the 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 EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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 D_MockSupport_c_h +#define D_MockSupport_c_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include "CppUTest/CppUTestConfig.h" +#include "CppUTest/StandardCLibrary.h" + +typedef enum { + MOCKVALUETYPE_BOOL, + MOCKVALUETYPE_UNSIGNED_INTEGER, + MOCKVALUETYPE_INTEGER, + MOCKVALUETYPE_LONG_INTEGER, + MOCKVALUETYPE_UNSIGNED_LONG_INTEGER, + MOCKVALUETYPE_LONG_LONG_INTEGER, + MOCKVALUETYPE_UNSIGNED_LONG_LONG_INTEGER, + MOCKVALUETYPE_DOUBLE, + MOCKVALUETYPE_STRING, + MOCKVALUETYPE_POINTER, + MOCKVALUETYPE_CONST_POINTER, + MOCKVALUETYPE_FUNCTIONPOINTER, + MOCKVALUETYPE_MEMORYBUFFER, + MOCKVALUETYPE_OBJECT +} MockValueType_c; + +typedef struct SMockValue_c +{ + MockValueType_c type; + union { + int boolValue; + int intValue; + unsigned int unsignedIntValue; + long int longIntValue; + unsigned long int unsignedLongIntValue; +#ifdef CPPUTEST_USE_LONG_LONG + cpputest_longlong longLongIntValue; + cpputest_ulonglong unsignedLongLongIntValue; +#else + char longLongPlaceholder[CPPUTEST_SIZE_OF_FAKE_LONG_LONG_TYPE]; +#endif + double doubleValue; + const char* stringValue; + void* pointerValue; + const void* constPointerValue; + void (*functionPointerValue)(void); + const unsigned char* memoryBufferValue; + void* objectValue; + const void* constObjectValue; + } value; +} MockValue_c; + +typedef struct SMockActualCall_c MockActualCall_c; +struct SMockActualCall_c +{ + MockActualCall_c* (*withBoolParameters)(const char* name, int value); + MockActualCall_c* (*withIntParameters)(const char* name, int value); + MockActualCall_c* (*withUnsignedIntParameters)(const char* name, unsigned int value); + MockActualCall_c* (*withLongIntParameters)(const char* name, long int value); + MockActualCall_c* (*withUnsignedLongIntParameters)(const char* name, unsigned long int value); + MockActualCall_c* (*withLongLongIntParameters)(const char* name, cpputest_longlong value); + MockActualCall_c* (*withUnsignedLongLongIntParameters)(const char* name, cpputest_ulonglong value); + MockActualCall_c* (*withDoubleParameters)(const char* name, double value); + MockActualCall_c* (*withStringParameters)(const char* name, const char* value); + MockActualCall_c* (*withPointerParameters)(const char* name, void* value); + MockActualCall_c* (*withConstPointerParameters)(const char* name, const void* value); + MockActualCall_c* (*withFunctionPointerParameters)(const char* name, void (*value)(void)); + MockActualCall_c* (*withMemoryBufferParameter)(const char* name, const unsigned char* value, size_t size); + MockActualCall_c* (*withParameterOfType)(const char* type, const char* name, const void* value); + MockActualCall_c* (*withOutputParameter)(const char* name, void* value); + MockActualCall_c* (*withOutputParameterOfType)(const char* type, const char* name, void* value); + int (*hasReturnValue)(void); + MockValue_c (*returnValue)(void); + int (*boolReturnValue)(void); + int (*returnBoolValueOrDefault)(int defaultValue); + int (*intReturnValue)(void); + int (*returnIntValueOrDefault)(int defaultValue); + unsigned int (*unsignedIntReturnValue)(void); + unsigned int (*returnUnsignedIntValueOrDefault)(unsigned int defaultValue); + long int (*longIntReturnValue)(void); + long int (*returnLongIntValueOrDefault)(long int defaultValue); + unsigned long int (*unsignedLongIntReturnValue)(void); + unsigned long int (*returnUnsignedLongIntValueOrDefault)(unsigned long int defaultValue); + cpputest_longlong (*longLongIntReturnValue)(void); + cpputest_longlong (*returnLongLongIntValueOrDefault)(cpputest_longlong defaultValue); + cpputest_ulonglong (*unsignedLongLongIntReturnValue)(void); + cpputest_ulonglong (*returnUnsignedLongLongIntValueOrDefault)(cpputest_ulonglong defaultValue); + const char* (*stringReturnValue)(void); + const char* (*returnStringValueOrDefault)(const char * defaultValue); + double (*doubleReturnValue)(void); + double (*returnDoubleValueOrDefault)(double defaultValue); + void* (*pointerReturnValue)(void); + void* (*returnPointerValueOrDefault)(void * defaultValue); + const void* (*constPointerReturnValue)(void); + const void* (*returnConstPointerValueOrDefault)(const void * defaultValue); + void (*(*functionPointerReturnValue)(void))(void); + void (*(*returnFunctionPointerValueOrDefault)(void(*defaultValue)(void)))(void); +}; + +typedef struct SMockExpectedCall_c MockExpectedCall_c; +struct SMockExpectedCall_c +{ + MockExpectedCall_c* (*withBoolParameters)(const char* name, int value); + MockExpectedCall_c* (*withIntParameters)(const char* name, int value); + MockExpectedCall_c* (*withUnsignedIntParameters)(const char* name, unsigned int value); + MockExpectedCall_c* (*withLongIntParameters)(const char* name, long int value); + MockExpectedCall_c* (*withUnsignedLongIntParameters)(const char* name, unsigned long int value); + MockExpectedCall_c* (*withLongLongIntParameters)(const char* name, cpputest_longlong value); + MockExpectedCall_c* (*withUnsignedLongLongIntParameters)(const char* name, cpputest_ulonglong value); + MockExpectedCall_c* (*withDoubleParameters)(const char* name, double value); + MockExpectedCall_c* (*withDoubleParametersAndTolerance)(const char* name, double value, double tolerance); + MockExpectedCall_c* (*withStringParameters)(const char* name, const char* value); + MockExpectedCall_c* (*withPointerParameters)(const char* name, void* value); + MockExpectedCall_c* (*withConstPointerParameters)(const char* name, const void* value); + MockExpectedCall_c* (*withFunctionPointerParameters)(const char* name, void (*value)(void)); + MockExpectedCall_c* (*withMemoryBufferParameter)(const char* name, const unsigned char* value, size_t size); + MockExpectedCall_c* (*withParameterOfType)(const char* type, const char* name, const void* value); + MockExpectedCall_c* (*withOutputParameterReturning)(const char* name, const void* value, size_t size); + MockExpectedCall_c* (*withOutputParameterOfTypeReturning)(const char* type, const char* name, const void* value); + MockExpectedCall_c* (*withUnmodifiedOutputParameter)(const char* name); + MockExpectedCall_c* (*ignoreOtherParameters)(void); + + MockExpectedCall_c* (*andReturnBoolValue)(int value); + MockExpectedCall_c* (*andReturnUnsignedIntValue)(unsigned int value); + MockExpectedCall_c* (*andReturnIntValue)(int value); + MockExpectedCall_c* (*andReturnLongIntValue)(long int value); + MockExpectedCall_c* (*andReturnUnsignedLongIntValue)(unsigned long int value); + MockExpectedCall_c* (*andReturnLongLongIntValue)(cpputest_longlong value); + MockExpectedCall_c* (*andReturnUnsignedLongLongIntValue)(cpputest_ulonglong value); + MockExpectedCall_c* (*andReturnDoubleValue)(double value); + MockExpectedCall_c* (*andReturnStringValue)(const char* value); + MockExpectedCall_c* (*andReturnPointerValue)(void* value); + MockExpectedCall_c* (*andReturnConstPointerValue)(const void* value); + MockExpectedCall_c* (*andReturnFunctionPointerValue)(void (*value)(void)); +}; + +typedef int (*MockTypeEqualFunction_c)(const void* object1, const void* object2); +typedef const char* (*MockTypeValueToStringFunction_c)(const void* object1); +typedef void (*MockTypeCopyFunction_c)(void* dst, const void* src); + +typedef struct SMockSupport_c MockSupport_c; +struct SMockSupport_c +{ + void (*strictOrder)(void); + MockExpectedCall_c* (*expectOneCall)(const char* name); + void (*expectNoCall)(const char* name); + MockExpectedCall_c* (*expectNCalls)(unsigned int number, const char* name); + MockActualCall_c* (*actualCall)(const char* name); + int (*hasReturnValue)(void); + MockValue_c (*returnValue)(void); + int (*boolReturnValue)(void); + int (*returnBoolValueOrDefault)(int defaultValue); + int (*intReturnValue)(void); + int (*returnIntValueOrDefault)(int defaultValue); + unsigned int (*unsignedIntReturnValue)(void); + unsigned int (*returnUnsignedIntValueOrDefault)(unsigned int defaultValue); + long int (*longIntReturnValue)(void); + long int (*returnLongIntValueOrDefault)(long int defaultValue); + unsigned long int (*unsignedLongIntReturnValue)(void); + unsigned long int (*returnUnsignedLongIntValueOrDefault)(unsigned long int defaultValue); + cpputest_longlong (*longLongIntReturnValue)(void); + cpputest_longlong (*returnLongLongIntValueOrDefault)(cpputest_longlong defaultValue); + cpputest_ulonglong (*unsignedLongLongIntReturnValue)(void); + cpputest_ulonglong (*returnUnsignedLongLongIntValueOrDefault)(cpputest_ulonglong defaultValue); + const char* (*stringReturnValue)(void); + const char* (*returnStringValueOrDefault)(const char * defaultValue); + double (*doubleReturnValue)(void); + double (*returnDoubleValueOrDefault)(double defaultValue); + void* (*pointerReturnValue)(void); + void* (*returnPointerValueOrDefault)(void * defaultValue); + const void* (*constPointerReturnValue)(void); + const void* (*returnConstPointerValueOrDefault)(const void * defaultValue); + void (*(*functionPointerReturnValue)(void))(void); + void (*(*returnFunctionPointerValueOrDefault) (void(*defaultValue)(void)))(void); + + void (*setBoolData) (const char* name, int value); + void (*setIntData) (const char* name, int value); + void (*setUnsignedIntData) (const char* name, unsigned int value); + void (*setStringData) (const char* name, const char* value); + void (*setDoubleData) (const char* name, double value); + void (*setPointerData) (const char* name, void* value); + void (*setConstPointerData) (const char* name, const void* value); + void (*setFunctionPointerData) (const char* name, void (*value)(void)); + void (*setDataObject) (const char* name, const char* type, void* value); + void (*setDataConstObject) (const char* name, const char* type, const void* value); + MockValue_c (*getData)(const char* name); + + void (*disable)(void); + void (*enable)(void); + void (*ignoreOtherCalls)(void); + + void (*checkExpectations)(void); + int (*expectedCallsLeft)(void); + + void (*clear)(void); + void (*crashOnFailure)(unsigned shouldCrash); + + void (*installComparator) (const char* typeName, MockTypeEqualFunction_c isEqual, MockTypeValueToStringFunction_c valueToString); + void (*installCopier) (const char* typeName, MockTypeCopyFunction_c copier); + void (*removeAllComparatorsAndCopiers)(void); +}; + +MockSupport_c* mock_c(void); +MockSupport_c* mock_scope_c(const char* scope); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/test/test_utility/include/CppUTestExt/OrderedTest.h b/test/test_utility/include/CppUTestExt/OrderedTest.h new file mode 100644 index 0000000..bf9a146 --- /dev/null +++ b/test/test_utility/include/CppUTestExt/OrderedTest.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the 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 EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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 D_OrderedTest_h +#define D_OrderedTest_h + +class OrderedTestShell : public UtestShell +{ +public: + OrderedTestShell(); + virtual ~OrderedTestShell() _destructor_override; + + virtual OrderedTestShell* addOrderedTest(OrderedTestShell* test); + virtual OrderedTestShell* getNextOrderedTest(); + + int getLevel(); + void setLevel(int level); + + static void addOrderedTestToHead(OrderedTestShell* test); + static OrderedTestShell* getOrderedTestHead(); + static bool firstOrderedTest(); + + static void setOrderedTestHead(OrderedTestShell* test); +private: + static OrderedTestShell* _orderedTestsHead; + OrderedTestShell* _nextOrderedTest; + + int _level; + +}; + +class OrderedTestInstaller +{ + public: + explicit OrderedTestInstaller(OrderedTestShell& test, const char* groupName, const char* testName, const char* fileName, size_t lineNumber, int level); + virtual ~OrderedTestInstaller(); + + private: + void addOrderedTestInOrder(OrderedTestShell* test); + void addOrderedTestInOrderNotAtHeadPosition(OrderedTestShell* test); + +}; + +#define TEST_ORDERED(testGroup, testName, testLevel) \ + /* declarations for compilers */ \ + class TEST_##testGroup##_##testName##_TestShell; \ + extern TEST_##testGroup##_##testName##_TestShell TEST_##testGroup##_##testName##_Instance; \ + class TEST_##testGroup##_##testName##_Test : public TEST_GROUP_##CppUTestGroup##testGroup \ +{ public: TEST_##testGroup##_##testName##_Test () : TEST_GROUP_##CppUTestGroup##testGroup () {} \ + void testBody() _override; }; \ + class TEST_##testGroup##_##testName##_TestShell : public OrderedTestShell { \ + virtual Utest* createTest() _override { return new TEST_##testGroup##_##testName##_Test; } \ + } TEST_##testGroup##_##testName##_Instance; \ + static OrderedTestInstaller TEST_##testGroup##_##testName##_Installer(TEST_##testGroup##_##testName##_Instance, #testGroup, #testName, __FILE__,__LINE__, testLevel); \ + void TEST_##testGroup##_##testName##_Test::testBody() + +#define TEST_ORDERED_C_WRAPPER(group_name, test_name, testLevel) \ + extern "C" void test_##group_name##_##test_name##_wrapper_c(void); \ + TEST_ORDERED(group_name, test_name, testLevel) { \ + test_##group_name##_##test_name##_wrapper_c(); \ + } + +#endif diff --git a/test/test_utility/include/Platforms/c2000/stdint.h b/test/test_utility/include/Platforms/c2000/stdint.h new file mode 100644 index 0000000..e2831fd --- /dev/null +++ b/test/test_utility/include/Platforms/c2000/stdint.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2007, Michael Feathers, James Grenning, Bas Vodde + * and Arnd R. Strube + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the 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 EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (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 stdint_wrapper_h + #define stdint_wrapper_h + + #include + + typedef unsigned char uint8_t; /* This will still compile to 16 bit */ + + #endif /* stdint_wrapper_h */ \ No newline at end of file diff --git a/test/test_utility/lib/.dirstamp b/test/test_utility/lib/.dirstamp new file mode 100644 index 0000000..e69de29 diff --git a/test/vi_test/Makefile b/test/vi_test/Makefile new file mode 100644 index 0000000..a66a07c --- /dev/null +++ b/test/vi_test/Makefile @@ -0,0 +1,36 @@ +TESTS := test_dsp_vi +TESTS1 := test_dsp_ip + +CFLAGS = -O0 -Wall -g -lm -lpthread +LDFLAGS += -L../../driver/xrp-user/ -ldsp +LDFLAGS += -Ithread-pthread +SRCS += test_dsp_vi.c + +SRCS1 +=test_dsp_ip.c + +INCLUDES += -I../../driver/xrp-user/include +# object files will be generated from .c sourcefiles +OBJS = $(notdir $(SRCS:.c=.o)) + + +all: $(TESTS) + +prepare: + mkdir -p output + +$(OBJS):$(SRCS) + $(CC) -c $(CFLAGS) $(INCLUDES) $(SRCS) + +$(TESTS):prepare $(OBJS) + $(CC) -o $(TESTS) $(OBJS) $(CFLAGS) $(LDFLAGS) + cp -r $(TESTS) ./output/ + +clean: + rm -f $(TESTS) + rm -f *.o + rm -rf output + +install: + +.PHONY: clean all prepare common + diff --git a/test/vi_test/test_dsp_vi.c b/test/vi_test/test_dsp_vi.c new file mode 100644 index 0000000..f39674b --- /dev/null +++ b/test/vi_test/test_dsp_vi.c @@ -0,0 +1,210 @@ + +#include +#include +#include +#include + +#include "csi_dsp_api.h" +#include "csi_dsp_task_defs.h" +#include "csi_dsp_post_process_defs.h" +#define PAYLOAD_SIZE 32 + +struct message{ + int cmd; + char message[PAYLOAD_SIZE]; +}; + +// void vi_callback( void *context,void * data) +// {} +int main(int argc, char *argv[]) +{ + + void *instance = csi_dsp_create_instance(0); + if(!instance) + { + printf("create fail\n"); + return -1; + } + + void *vi_task= csi_dsp_create_task(instance,CSI_DSP_TASK_HW_TO_HW); + if(!vi_task) + { + printf("task create fail\n"); + return -1; + } + if(csi_dsp_create_reporter(instance)) + { + printf("reporter create fail\n"); + return -1; + } + struct csi_dsp_task_fe_para config_params = + { + .frontend_type = CSI_DSP_FE_TYPE_ISP, + .task_id = -1, + { + .isp_param.id=0, + .isp_param.hor=640, + .isp_param.ver=480, + .isp_param.data_fmt=CSI_DSP_IMG_FMT_RAW12_ALGIN, + .isp_param.line_in_entry=640*2, + .isp_param.line_stride=640*2, + .isp_param.buffer_size=640*2*16*2, + .isp_param.buffer_addr=0xb0000000, + } + }; + + + if(csi_dsp_task_config_frontend(vi_task,&config_params)) + { + + printf("isp config fail\n"); + return -1; + } + + struct csi_dsp_task_be_para post_config = + { + .backend_type = CSI_DSP_BE_TYPE_POST_ISP, + .task_id = -1, + { + .post_isp_param.id=0, + .post_isp_param.hor=640, + .post_isp_param.ver=480, + .post_isp_param.data_fmt=CSI_DSP_IMG_FMT_RAW12_ALGIN, + .post_isp_param.line_in_entry=640*2, + .post_isp_param.line_stride=640*2, + .post_isp_param.buffer_size=640*2*16*2, + .post_isp_param.buffer_addr=0xb0000000, + } + }; + + if(csi_dsp_task_config_backend(vi_task,&post_config)) + { + + printf("post-isp config fail\n"); + return -1; + } + + struct csi_dsp_algo_config_par alog_config={ + .algo_id=0, + }; + + if(csi_dsp_task_config_algo(vi_task,&alog_config)) + { + printf("algo kernel config fail\n"); + return -1; + } + + if(csi_dsp_task_register_cb(vi_task,isp_algo_result_handler,NULL,32)) + { + printf("algo kernel start fail\n"); + return -1; + } + + if(csi_dsp_task_start(vi_task)) + { + printf("task start fail\n"); + return -1; + } + + + while(1) + { + ; + } + + return 0; +} + + +// int test(int argc, char *argv[]) +// { + +// unsigned char comm_task[] = XRP_PS_NSID_INITIALIZER; +// struct dsp_instnace *instance = create_dsp_instance(0,comm_task); +// if(!instance) +// { +// printf("create fail\n"); +// return -1; +// } +// if(dsp_ps_create_reporter(instance)) +// { +// printf("reporter create fail\n"); +// return -1; +// } +// unsigned char isp_task[] = XRP_PS_NSID_ISP_ALGO; +// struct csi_dsp_ps_task_handler *vi_task= csi_dsp_create_task(instance,isp_task,1); +// if(!vi_task) +// { +// printf("task create fail\n"); +// return -1; +// } + +// sisp_config_par isp_config = +// { +// .id=0, +// .hor=640, +// .ver=480, +// .data_fmt=IMG_RAW12_FORMAT_ALGIN1, +// .line_in_entry=640*2, +// .line_stride=640*2, +// .buffer_size=640*2*16*2, +// .buffer_addr=0xb0000000, + +// }; +// struct csi_dsp_task_fe_para *fe_cfg=malloc(sizeof(struct csi_dsp_task_fe_para)+sizeof(sisp_config_par)-1); + +// fe_cfg->frontend_type=CSI_DSP_FE_TYPE_ISP; +// memcpy(fe_cfg->para_data,&isp_config,siezof(sisp_config_par)); +// if(csi_dsp_task_config_frontend(vi_task,fe_cfg)) +// { + +// printf("isp config fail\n"); +// return -1; +// } +// spost_isp_config_par post_config = +// { +// .id=0, +// .hor=640, +// .ver=480, +// .data_fmt=IMG_RAW12_FORMAT_ALGIN1, +// .line_in_entry=640*2, +// .line_stride=640*2, +// .buffer_size=640*2*16*2, +// .buffer_addr=0xb0000000, + +// }; +// struct csi_dsp_task_be_para *be_cfg=malloc(sizeof(struct csi_dsp_task_be_para)+sizeof(spost_isp_config_par)-1); +// be_cfg->CSI_DSP_BE_TYPE_POST_ISP; +// memcpy(fe_cfg->para_data,&post_config,siezof(sisp_config_par)); +// if(csi_dsp_task_config_backend(vi_task,&be_cfg)) +// { + +// printf("post-isp config fail\n"); +// return -1; +// } + +// salgo_config_par alog_config={ +// .algo_id=0, +// }; + +// if(csi_dsp_task_config_algo(vi_task,&alog_config)) +// { +// printf("algo kernel config fail\n"); +// return -1; +// } +// vi_task->report_id=1; +// if(csi_dsp_task_start(vi_task,isp_algo_result_handler,NULL,32)) +// { +// printf("algo kernel start fail\n"); +// return -1; +// } + +// while(1) +// { +// ; +// } +// csi_dsp_task_stop(vi_task); +// csi_dsp_destroy_task(vi_task); +// csi_dsp_delete_instance(vi_task); +// return 0; +// } \ No newline at end of file