Browse Source

Merge pull request #2 from RT-Thread/master

update form origin
孙冬梅 7 years ago
parent
commit
6e987b2350
100 changed files with 15824 additions and 43 deletions
  1. 1 0
      .travis.yml
  2. 98 0
      ChangeLog.md
  3. 1 1
      bsp/CME_M7/rtconfig.py
  4. 265 0
      bsp/allwinner_tina/.config
  5. 29 0
      bsp/allwinner_tina/Kconfig
  6. 131 0
      bsp/allwinner_tina/README.md
  7. 14 0
      bsp/allwinner_tina/SConscript
  8. 27 0
      bsp/allwinner_tina/SConstruct
  9. 9 0
      bsp/allwinner_tina/applications/SConscript
  10. 36 0
      bsp/allwinner_tina/applications/main.c
  11. 16 0
      bsp/allwinner_tina/drivers/Kconfig
  12. 16 0
      bsp/allwinner_tina/drivers/SConscript
  13. 117 0
      bsp/allwinner_tina/drivers/board.c
  14. 38 0
      bsp/allwinner_tina/drivers/board.h
  15. 527 0
      bsp/allwinner_tina/drivers/drv_clock.c
  16. 243 0
      bsp/allwinner_tina/drivers/drv_clock.h
  17. 564 0
      bsp/allwinner_tina/drivers/drv_gpio.c
  18. 244 0
      bsp/allwinner_tina/drivers/drv_gpio.h
  19. 327 0
      bsp/allwinner_tina/drivers/drv_uart.c
  20. 83 0
      bsp/allwinner_tina/drivers/drv_uart.h
  21. 13 0
      bsp/allwinner_tina/libcpu/SConscript
  22. 92 0
      bsp/allwinner_tina/libcpu/context_gcc.S
  23. 41 0
      bsp/allwinner_tina/libcpu/cpu.c
  24. 229 0
      bsp/allwinner_tina/libcpu/cpuport.c
  25. 206 0
      bsp/allwinner_tina/libcpu/interrupt.c
  26. 107 0
      bsp/allwinner_tina/libcpu/interrupt.h
  27. 457 0
      bsp/allwinner_tina/libcpu/mmu.c
  28. 65 0
      bsp/allwinner_tina/libcpu/mmu.h
  29. 81 0
      bsp/allwinner_tina/libcpu/rt_low_level_init.c
  30. 81 0
      bsp/allwinner_tina/libcpu/stack.c
  31. 346 0
      bsp/allwinner_tina/libcpu/start_gcc.S
  32. 223 0
      bsp/allwinner_tina/libcpu/trap.c
  33. 148 0
      bsp/allwinner_tina/link.lds
  34. 235 0
      bsp/allwinner_tina/rtconfig.h
  35. 58 0
      bsp/allwinner_tina/rtconfig.py
  36. 1 1
      bsp/apollo2/rtconfig.h
  37. 4 4
      bsp/apollo2/rtconfig.py
  38. 1 1
      bsp/asm9260t/.config
  39. 1 1
      bsp/asm9260t/rtconfig.h
  40. 1 1
      bsp/asm9260t/rtconfig.py
  41. 1 1
      bsp/at91sam9260/rtconfig.py
  42. 6 6
      bsp/avr32uc3b0/rtconfig.py
  43. 3 3
      bsp/beaglebone/rtconfig.py
  44. 1 1
      bsp/dm365/rtconfig.py
  45. 7 7
      bsp/efm32/rtconfig.py
  46. 4 4
      bsp/frdm-k64f/rtconfig.py
  47. 2 2
      bsp/gd32450z-eval/SConstruct
  48. 2 2
      bsp/gd32450z-eval/applications/application.c
  49. 2 2
      bsp/gd32450z-eval/applications/rtgui_demo.c
  50. 1 1
      bsp/gd32450z-eval/drivers/SConscript
  51. 1 1
      bsp/gd32450z-eval/drivers/drv_lcd.c
  52. 1 1
      bsp/gd32450z-eval/rtconfig.h
  53. 3 3
      bsp/gd32450z-eval/rtconfig.py
  54. 340 0
      bsp/gkipc/.config
  55. 134 0
      bsp/gkipc/Kconfig
  56. 61 0
      bsp/gkipc/README.md
  57. 19 0
      bsp/gkipc/SConscript
  58. 33 0
      bsp/gkipc/SConstruct
  59. 10 0
      bsp/gkipc/applications/SConscript
  60. 41 0
      bsp/gkipc/applications/main.c
  61. 10 0
      bsp/gkipc/armv6/SConscript
  62. 376 0
      bsp/gkipc/armv6/arm1176_mmu.gcc.s
  63. 64 0
      bsp/gkipc/armv6/arm1176_mmu_ttb.c
  64. 34 0
      bsp/gkipc/armv6/arm1176_mmu_ttb.h
  65. 62 0
      bsp/gkipc/armv6/arm1176_vfp_fast_gcc.s
  66. 160 0
      bsp/gkipc/armv6/context_gcc.s
  67. 297 0
      bsp/gkipc/armv6/cpuport.c
  68. 81 0
      bsp/gkipc/armv6/gk7101.h
  69. 148 0
      bsp/gkipc/armv6/interrupt.c
  70. 563 0
      bsp/gkipc/armv6/mmu.c
  71. 73 0
      bsp/gkipc/armv6/mmu.h
  72. 39 0
      bsp/gkipc/armv6/reset.c
  73. 27 0
      bsp/gkipc/armv6/rtos.h
  74. 1450 0
      bsp/gkipc/armv6/rtos_lib.c
  75. 236 0
      bsp/gkipc/armv6/rtos_lib.h
  76. 130 0
      bsp/gkipc/armv6/rtos_memory.h
  77. 77 0
      bsp/gkipc/armv6/stack.c
  78. 481 0
      bsp/gkipc/armv6/start_gcc.s
  79. 56 0
      bsp/gkipc/armv6/system_clock.c
  80. 250 0
      bsp/gkipc/armv6/trap.c
  81. 24 0
      bsp/gkipc/drivers/SConscript
  82. 131 0
      bsp/gkipc/drivers/board.c
  83. 32 0
      bsp/gkipc/drivers/board.h
  84. 237 0
      bsp/gkipc/drivers/drv_adc.c
  85. 77 0
      bsp/gkipc/drivers/drv_adc.h
  86. 226 0
      bsp/gkipc/drivers/drv_dma.c
  87. 121 0
      bsp/gkipc/drivers/drv_dma.h
  88. 349 0
      bsp/gkipc/drivers/drv_flash.c
  89. 6 0
      bsp/gkipc/drivers/drv_flash.h
  90. 519 0
      bsp/gkipc/drivers/drv_gmac.c
  91. 35 0
      bsp/gkipc/drivers/drv_gmac.h
  92. 304 0
      bsp/gkipc/drivers/drv_i2c.c
  93. 144 0
      bsp/gkipc/drivers/drv_i2c.h
  94. 342 0
      bsp/gkipc/drivers/drv_mmc.c
  95. 186 0
      bsp/gkipc/drivers/drv_mmc.h
  96. 512 0
      bsp/gkipc/drivers/drv_pwm.c
  97. 75 0
      bsp/gkipc/drivers/drv_pwm.h
  98. 1684 0
      bsp/gkipc/drivers/drv_sdio.c
  99. 41 0
      bsp/gkipc/drivers/drv_sdio.h
  100. 317 0
      bsp/gkipc/drivers/drv_ssi.c

+ 1 - 0
.travis.yml

@@ -27,6 +27,7 @@ env:
 #  - RTT_BSP='apollo2' RTT_TOOL_CHAIN='sourcery-arm'
   - RTT_BSP='asm9260t' RTT_TOOL_CHAIN='sourcery-arm'
   - RTT_BSP='at91sam9260' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='allwinner_tina' RTT_TOOL_CHAIN='sourcery-arm'
 #  - RTT_BSP='avr32uc3b0' RTT_TOOL_CHAIN='atmel-avr32'
 #  - RTT_BSP='bf533' # no scons
   - RTT_BSP='efm32' RTT_TOOL_CHAIN='sourcery-arm' 

+ 98 - 0
ChangeLog.md

@@ -1,3 +1,101 @@
+# RT-Thread 3.0.3 Change Log
+
+## Kernel
+
+* Add scheduler protection when do cleanup for a detached thread;
+* Fix the object_find issue when enable module feature;
+* Improve POSIX signal support and add rt_signal_wait function and POSIX sigwait interface;
+* When enable finsh shell, rtthread.h header file includes the API file of finsh. Therefore, the application code can use command export feature without finsh.h file;
+* Improve the comments of rtdbg.h file. In RT-Thread, just use following code to add debug log feature:
+
+```c
+    #define DBG_ENABLE
+
+    #define DBG_SECTION_NAME    "[ MOD]"
+    #define DBG_LEVEL           DBG_INFO
+    #define DBG_COLOR
+    #include <rtdbg.h>
+```
+
+When close the DBG_ENABLE definition, the debug log will be closed. Otherwise, the `dbg_log(level, fmt, ...)` can be used to print debug information. 
+
+DBG_SECTION_NAME - The prefix information for each log line;
+DBG_LEVEL - The debug log level;
+DBG_COLOR - Whether use color log in console.
+
+## Components
+
+* Fix the flag issue of fopen in GNU GCC;
+* Fix the pthread_detach issue when used for a detached pthread;
+* Fix the _TIMESPEC_DEFINED issue in IAR 8;
+* Add libc_stdio_get_console() interface for returns the fd of console;
+* Move UI engine component as a standalone package;
+* Add a unify TF/SD card driver on SPI device bus;
+* Add soft-RTC device, therefore device can synchronize with network time and maintains the time with OS tick later;
+* Change the open/fcntl/ioctl API to POSIX standard  interface;
+* Fix ramfs issue when update with RTT 3.0.x;
+* Fix the elm fatfs umount issue; (liu2guang)
+* ignore the O_CREAT flag when open a device file;
+* Improve VCOM class driver in USB stack; (ChunfengMu, Aubr.Cool)
+
+## BSP
+
+* Fix the potential issue when enable Cortex-M hardware FPU;
+* Add v2m-mps2 bsp, which is used in Keil MDK5 for Cortex-M4/M7/M23/M33 simulation;
+* Add sdcard driver for stm32f10x-HAL;(liu2guang)
+* Improve GNU GCC support for stm32f10x-HAL;(Xeon Xu)
+* simulator bsp can be used in Windows/Visual C++ and update SDL to v2.0.7;
+* Add gk7102 bsp by gokemicro;(gokemicro)
+* Add allwinner F1C100s ARM9 bsp;(uestczyh222)
+* Fix some issues in peripherals drive library of NXP LPC54608/i.MX RT; (Valeriy Van)
+
+## Tools
+
+* scons building script will automatically add `_REENT_SMALL` macro when enable newlib nanao;
+* Modify building script for Python 3.x and scons 3.0
+
+# RT-Thread v3.0.2 Change log
+
+## Platform
+
+* Make sure the Object_Class to a fixed value
+* Add `rt_device_create/destroy` API
+* Add memory trace for small memory management algorithm for memory leak and overwritten.
+* Add a first version of asynchronous I/O API
+* Add cputime for high resolution counter
+* Add pipe device functions in DeviceDrivers
+* USB Host available in stm32f4 with mass storage class
+* Add 'df' command in msh
+* Update UI engine and add an example
+* Split `clock_time` from pthreads and add a new clock id: `CLOCK_CPUTIME_ID`
+* Enable IPv6 in lwIP 2.0.2 version
+* Add memlog in logtrace
+* Fix closesocket issue in dfs_net
+* Fix IPv6 issue in NFS
+* Update JFFS2 file system with new DFS API
+* Fix the issue of stat "/.." of lwext4 (parai)
+* Fix the fs type search issue in mkfs
+* Fix the select issue in dfs_net
+
+## Tools
+
+* scons: add '--useconfig' command to use an exist config file
+* scons: force to use g++ for link when enable `RT_USING_CPLUSPLUS` in GNU GCC configuration
+* Enable package feature in Linux/MacOS host
+
+## BSP
+
+* Add NUC472 bsp (bluebear)
+* Update SD/MMC driver for qemu-vexpress-A9
+* Add keyboard/mouse driver for qemu-vexpress-a9
+* Add ADC/I2C/Flash/PWM/RTC/smbus/SPI driver for apollo2 (Haleyl)
+* Add I2C/LCD/Touch driver for i.MXRT1052-EVK
+* Update SD/MMC driver for mini2440 (kuangdazzidd)
+* Update simulator to adapt VC++ compiler
+* Add USB host driver in stm32f4xx-HAL (uestczyh222)
+* Update EMAC driver for IPv6 in stm32f40x/stm32f107
+* Add stm32h743-nucleo bsp (polariss)
+
 # RT-Thread v3.0.1 Change log
 
 ## Platform:

+ 1 - 1
bsp/CME_M7/rtconfig.py

@@ -35,7 +35,7 @@ if PLATFORM == 'gcc':
     AS = PREFIX + 'gcc'
     AR = PREFIX + 'ar'
     LINK = PREFIX + 'gcc'
-    TARGET_EXT = 'axf'
+    TARGET_EXT = 'elf'
     SIZE = PREFIX + 'size'
     OBJDUMP = PREFIX + 'objdump'
     OBJCPY = PREFIX + 'objcopy'

+ 265 - 0
bsp/allwinner_tina/.config

@@ -0,0 +1,265 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# RT-Thread Configuration
+#
+
+#
+# RT-Thread Kernel
+#
+CONFIG_RT_NAME_MAX=8
+CONFIG_RT_ALIGN_SIZE=4
+# CONFIG_RT_THREAD_PRIORITY_8 is not set
+CONFIG_RT_THREAD_PRIORITY_32=y
+# CONFIG_RT_THREAD_PRIORITY_256 is not set
+CONFIG_RT_THREAD_PRIORITY_MAX=32
+CONFIG_RT_TICK_PER_SECOND=100
+CONFIG_RT_DEBUG=y
+CONFIG_RT_USING_OVERFLOW_CHECK=y
+CONFIG_RT_DEBUG_INIT=0
+CONFIG_RT_DEBUG_THREAD=0
+CONFIG_RT_USING_HOOK=y
+CONFIG_IDLE_THREAD_STACK_SIZE=256
+# CONFIG_RT_USING_TIMER_SOFT is not set
+
+#
+# Inter-Thread communication
+#
+CONFIG_RT_USING_SEMAPHORE=y
+CONFIG_RT_USING_MUTEX=y
+CONFIG_RT_USING_EVENT=y
+CONFIG_RT_USING_MAILBOX=y
+CONFIG_RT_USING_MESSAGEQUEUE=y
+# CONFIG_RT_USING_SIGNALS is not set
+
+#
+# Memory Management
+#
+CONFIG_RT_USING_MEMPOOL=y
+# CONFIG_RT_USING_MEMHEAP is not set
+# CONFIG_RT_USING_NOHEAP is not set
+CONFIG_RT_USING_SMALL_MEM=y
+# CONFIG_RT_USING_SLAB is not set
+# CONFIG_RT_USING_MEMTRACE is not set
+CONFIG_RT_USING_HEAP=y
+
+#
+# Kernel Device Object
+#
+CONFIG_RT_USING_DEVICE=y
+# CONFIG_RT_USING_INTERRUPT_INFO is not set
+CONFIG_RT_USING_CONSOLE=y
+CONFIG_RT_CONSOLEBUF_SIZE=128
+CONFIG_RT_CONSOLE_DEVICE_NAME="uart0"
+# CONFIG_RT_USING_MODULE is not set
+CONFIG_ARCH_ARM=y
+CONFIG_ARCH_ARM_ARM9=y
+
+#
+# RT-Thread Components
+#
+CONFIG_RT_USING_COMPONENTS_INIT=y
+CONFIG_RT_USING_USER_MAIN=y
+
+#
+# C++ features
+#
+# CONFIG_RT_USING_CPLUSPLUS is not set
+
+#
+# Command shell
+#
+CONFIG_RT_USING_FINSH=y
+CONFIG_FINSH_THREAD_NAME="tshell"
+CONFIG_FINSH_USING_HISTORY=y
+CONFIG_FINSH_HISTORY_LINES=5
+CONFIG_FINSH_USING_SYMTAB=y
+CONFIG_FINSH_USING_DESCRIPTION=y
+CONFIG_FINSH_THREAD_PRIORITY=20
+CONFIG_FINSH_THREAD_STACK_SIZE=4096
+CONFIG_FINSH_CMD_SIZE=80
+# CONFIG_FINSH_USING_AUTH is not set
+CONFIG_FINSH_USING_MSH=y
+CONFIG_FINSH_USING_MSH_DEFAULT=y
+# CONFIG_FINSH_USING_MSH_ONLY is not set
+
+#
+# Device virtual file system
+#
+CONFIG_RT_USING_DFS=y
+CONFIG_DFS_USING_WORKDIR=y
+CONFIG_DFS_FILESYSTEMS_MAX=2
+CONFIG_DFS_FILESYSTEM_TYPES_MAX=2
+CONFIG_DFS_FD_MAX=4
+CONFIG_RT_USING_DFS_ELMFAT=y
+
+#
+# elm-chan's FatFs, Generic FAT Filesystem Module
+#
+CONFIG_RT_DFS_ELM_CODE_PAGE=437
+CONFIG_RT_DFS_ELM_WORD_ACCESS=y
+CONFIG_RT_DFS_ELM_USE_LFN_0=y
+# CONFIG_RT_DFS_ELM_USE_LFN_1 is not set
+# CONFIG_RT_DFS_ELM_USE_LFN_2 is not set
+# CONFIG_RT_DFS_ELM_USE_LFN_3 is not set
+CONFIG_RT_DFS_ELM_USE_LFN=0
+CONFIG_RT_DFS_ELM_MAX_LFN=255
+CONFIG_RT_DFS_ELM_DRIVES=2
+CONFIG_RT_DFS_ELM_MAX_SECTOR_SIZE=512
+# CONFIG_RT_DFS_ELM_USE_ERASE is not set
+CONFIG_RT_DFS_ELM_REENTRANT=y
+CONFIG_RT_USING_DFS_DEVFS=y
+# CONFIG_RT_USING_DFS_NET is not set
+# CONFIG_RT_USING_DFS_ROMFS is not set
+# CONFIG_RT_USING_DFS_RAMFS is not set
+# CONFIG_RT_USING_DFS_UFFS is not set
+# CONFIG_RT_USING_DFS_JFFS2 is not set
+# CONFIG_RT_USING_DFS_NFS is not set
+
+#
+# Device Drivers
+#
+CONFIG_RT_USING_DEVICE_IPC=y
+CONFIG_RT_USING_SERIAL=y
+# CONFIG_RT_USING_CAN is not set
+# CONFIG_RT_USING_HWTIMER is not set
+# CONFIG_RT_USING_CPUTIME is not set
+# CONFIG_RT_USING_I2C is not set
+CONFIG_RT_USING_PIN=y
+# CONFIG_RT_USING_MTD_NOR is not set
+# CONFIG_RT_USING_MTD_NAND is not set
+# CONFIG_RT_USING_RTC is not set
+# CONFIG_RT_USING_SDIO is not set
+# CONFIG_RT_USING_SPI is not set
+# CONFIG_RT_USING_WDT is not set
+# CONFIG_RT_USING_WIFI is not set
+
+#
+# Using USB
+#
+# CONFIG_RT_USING_USB_HOST is not set
+# CONFIG_RT_USING_USB_DEVICE is not set
+
+#
+# POSIX layer and C standard library
+#
+CONFIG_RT_USING_LIBC=y
+# CONFIG_RT_USING_PTHREADS is not set
+CONFIG_RT_USING_POSIX=y
+# CONFIG_RT_USING_POSIX_MMAP is not set
+# CONFIG_RT_USING_POSIX_TERMIOS is not set
+# CONFIG_RT_USING_POSIX_AIO is not set
+
+#
+# Network stack
+#
+
+#
+# light weight TCP/IP stack
+#
+# CONFIG_RT_USING_LWIP is not set
+
+#
+# Modbus master and slave stack
+#
+# CONFIG_RT_USING_MODBUS is not set
+
+#
+# RT-Thread UI Engine
+#
+# CONFIG_PKG_USING_GUIENGINE is not set
+
+#
+# VBUS(Virtual Software BUS)
+#
+# CONFIG_RT_USING_VBUS is not set
+
+#
+# Utilities
+#
+# CONFIG_RT_USING_LOGTRACE is not set
+# CONFIG_RT_USING_RYM is not set
+
+#
+# RT-Thread online packages
+#
+
+#
+# system packages
+#
+# CONFIG_PKG_USING_LWEXT4 is not set
+# CONFIG_PKG_USING_PARTITION is not set
+# CONFIG_PKG_USING_PERSIMMON is not set
+# CONFIG_PKG_USING_SQLITE is not set
+# CONFIG_PKG_USING_RTI is not set
+
+#
+# IoT - internet of things
+#
+# CONFIG_PKG_USING_PAHOMQTT is not set
+# CONFIG_PKG_USING_WEBCLIENT is not set
+# CONFIG_PKG_USING_MONGOOSE is not set
+# CONFIG_PKG_USING_WEBTERMINAL is not set
+# CONFIG_PKG_USING_CJSON is not set
+# CONFIG_PKG_USING_LJSON is not set
+# CONFIG_PKG_USING_EZXML is not set
+# CONFIG_PKG_USING_NANOPB is not set
+# CONFIG_PKG_USING_GAGENT_CLOUD is not set
+
+#
+# Wi-Fi
+#
+
+#
+# Marvell WiFi
+#
+# CONFIG_PKG_USING_WLANMARVELL is not set
+
+#
+# Wiced WiFi
+#
+# CONFIG_PKG_USING_WLAN_WICED is not set
+# CONFIG_PKG_USING_COAP is not set
+# CONFIG_PKG_USING_NOPOLL is not set
+
+#
+# security packages
+#
+# CONFIG_PKG_USING_MBEDTLS is not set
+# CONFIG_PKG_USING_libsodium is not set
+# CONFIG_PKG_USING_TINYCRYPT is not set
+
+#
+# language packages
+#
+# CONFIG_PKG_USING_JERRYSCRIPT is not set
+# CONFIG_PKG_USING_MICROPYTHON is not set
+
+#
+# multimedia packages
+#
+# CONFIG_PKG_USING_OPENMV is not set
+
+#
+# tools packages
+#
+# CONFIG_PKG_USING_CMBACKTRACE is not set
+# CONFIG_PKG_USING_EASYLOGGER is not set
+# CONFIG_PKG_USING_SYSTEMVIEW is not set
+# CONFIG_PKG_USING_IPERF is not set
+
+#
+# miscellaneous packages
+#
+# CONFIG_PKG_USING_FASTLZ is not set
+# CONFIG_PKG_USING_MINILZO is not set
+
+#
+# example package: hello
+#
+# CONFIG_PKG_USING_HELLO is not set
+# CONFIG_PKG_USING_MULTIBUTTON is not set
+CONFIG_TINA_USING_UART0=y
+# CONFIG_TINA_USING_UART1 is not set
+CONFIG_TINA_USING_UART2=y
+CONFIG_RT_USING_CPU_FFS=y
+CONFIG_RT_MAIN_THREAD_STACK_SIZE=2048

+ 29 - 0
bsp/allwinner_tina/Kconfig

@@ -0,0 +1,29 @@
+mainmenu "RT-Thread Configuration"
+
+config $BSP_DIR
+    string
+    option env="BSP_ROOT"
+    default "."
+
+config $RTT_DIR
+    string
+    option env="RTT_ROOT"
+    default "../.."
+
+# you can change the RTT_ROOT default "../.." to your rtthread_root,
+# example : default "F:/git_repositories/rt-thread"
+
+config $PKGS_DIR
+    string
+    option env="PKGS_ROOT"
+    default "packages"
+
+source "$RTT_DIR/Kconfig"
+source "$PKGS_DIR/Kconfig"
+
+config SOC_TINA
+    bool 
+    select ARCH_ARM_ARM9
+    default y
+
+source "$BSP_DIR/drivers/Kconfig"

+ 131 - 0
bsp/allwinner_tina/README.md

@@ -0,0 +1,131 @@
+# Allwinner tina板级支持包
+
+## 1. 简介
+
+Allwinner tina 是由全志公司推出的ARM9内核的SOC
+包括如下硬件特性:
+
+| 硬件 | 描述 |
+| -- | -- |
+|芯片型号| tina系列 |
+|CPU| ARM9 |
+|主频| 408MHz |
+|片内DDR | 32MB |
+|板载SPI Nor Flash | 8/16MB|
+
+## 2. 编译说明
+
+| 环境 | 说明 |
+| --- | --- |
+|PC操作系统|Linux/MacOS|
+|编译器|arm-none-eabi-gcc version 6.3.1 20170620 (release)|
+|构建工具|scons|
+1) 下载源码
+
+```
+    git clone https://github.com/RT-Thread/rt-thread.git
+```
+2) 配置工程并准备env
+```
+    cd rt-thread/bsp/allwinner_tina
+    scons --menuconfig
+    source ~/.env/env.sh
+    pkgs --upgrade
+    
+```
+3) 编译安装下载工具
+```
+    pushd /tmp
+    git clone https://github.com/Icenowy/sunxi-tools.git
+    pushd sunxi-tools
+    git checkout -b f1c100s origin/f1c100s
+    make
+    sudo make install
+    popd
+    popd
+```
+4) 编译
+```
+    scons
+```
+如果编译正确无误,会产生rtthread.elf、rtthread.bin文件。其中rtthread.bin需要烧写到设备中进行运行。
+
+## 3. 烧写及执行
+**烧写工具目前仅支持Linux/MacOS环境,请在Linux/MaxOS环境下进行烧写操作**
+当正确编译产生出rtthread.bin映像文件后可以使用下面的方式来烧写到设备中。
+
+1)编译初始化引导文件
+编译依赖 arm-eabi-gcc
+```
+    pushd ../../..
+    git clone https://github.com/uestczyh222/tina-spl.git
+    pushd tina-spl
+    make
+    cp output/f1c100s.bin ../rt-thread/bsp/tina/tina-spl.bin
+    popd
+    popd
+```
+2)下载并运行
+
+```
+1.短接flash 1、4脚(当flash中无可引导代码时无需此步骤)
+2.连接USB
+3.松开短接的引脚
+4.输入下列指令
+```
+
+```
+    sudo sunxi-fel -p write  0x00000000 tina-spl.bin
+    sudo sunxi-fel exec 0x00000000
+    sudo sunxi-fel -p write  0x80000000 rtthread.bin
+    sudo sunxi-fel exec 0x80000000
+```
+
+### 3.1 运行结果
+
+如果编译 & 烧写无误,会在串口0上看到RT-Thread的启动logo信息:
+
+```
+ \ | /
+- RT -     Thread Operating System
+ / | \     3.0.2 build Feb  8 2018
+ 2006 - 2017 Copyright by rt-thread team
+periph_get_pll_clk:600000000
+cpu_get_clk:408000000
+ahb_get_clk:200000000
+apb_get_clk:100000000
+msh />
+```
+
+
+## 4. 驱动支持情况及计划
+
+| 驱动 | 支持情况  |  备注  |
+| ------ | :----:  | :------:  |
+| UART | 支持 | UART0/1/2 |
+| GPIO | 支持 | / |
+| clock | 支持 | / |
+| mmu | 支持 | / |
+
+
+### 4.1 IO在板级支持包中的映射情况
+
+| IO号 | 板级包中的定义 |
+| -- | -- |
+| PE8 | USART2 RX |
+| PE7 | USART2 TX |
+| PA3 | USART1 RX |
+| PA2 | USART1 TX |
+| PE1 | USART0 TX |
+| PE0 | USART0 RX |
+
+
+## 5. 联系人信息
+
+维护人:
+[uestczyh222][4] < [lymz@foxmail.com][5] >
+
+
+  [1]: https://www.rt-thread.org/page/download.html
+  [4]: https://github.com/uestczyh222
+  [5]: mailto:lymz@foxmail.com

+ 14 - 0
bsp/allwinner_tina/SConscript

@@ -0,0 +1,14 @@
+# for module compiling
+import os
+from building import *
+
+cwd = GetCurrentDir()
+objs = []
+list = os.listdir(cwd)
+
+for d in list:
+    path = os.path.join(cwd, d)
+    if os.path.isfile(os.path.join(path, 'SConscript')):
+        objs = objs + SConscript(os.path.join(d, 'SConscript'))
+
+Return('objs')

+ 27 - 0
bsp/allwinner_tina/SConstruct

@@ -0,0 +1,27 @@
+import os
+import sys
+import rtconfig
+
+from rtconfig import RTT_ROOT
+
+sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')]
+from building import *
+
+TARGET = 'rtthread.' + rtconfig.TARGET_EXT
+
+env = Environment(tools = ['mingw'],
+    AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS,
+    CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS,
+    CXX = rtconfig.CC, CXXFLAGS = rtconfig.CXXFLAGS,
+    AR = rtconfig.AR, ARFLAGS = '-rc',
+    LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS)
+env.PrependENVPath('PATH', rtconfig.EXEC_PATH)
+
+Export('RTT_ROOT')
+Export('rtconfig')
+
+# prepare building environment
+objs = PrepareBuilding(env, RTT_ROOT, has_libcpu=True)
+
+# make a building
+DoBuilding(TARGET, objs)

+ 9 - 0
bsp/allwinner_tina/applications/SConscript

@@ -0,0 +1,9 @@
+from building import *
+
+cwd     = GetCurrentDir()
+src     = Glob('*.c')
+CPPPATH = [cwd, str(Dir('#'))]
+
+group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')

+ 36 - 0
bsp/allwinner_tina/applications/main.c

@@ -0,0 +1,36 @@
+/*
+ * File      : main.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2017, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2017-5-30      Bernard      the first version
+ */
+
+#include "rtthread.h"
+#include "drv_clock.h"
+
+int main(int argc, char **argv)
+{
+    rt_kprintf("periph_get_pll_clk:%d\n", periph_get_pll_clk());
+    rt_kprintf("cpu_get_clk:%d\n", cpu_get_clk());
+    rt_kprintf("ahb_get_clk:%d\n", ahb_get_clk());
+    rt_kprintf("apb_get_clk:%d\n", apb_get_clk());
+
+    return 0;
+}

+ 16 - 0
bsp/allwinner_tina/drivers/Kconfig

@@ -0,0 +1,16 @@
+
+
+config TINA_USING_UART0
+    bool "Using UART0"
+    select RT_USING_SERIAL
+    default n
+
+config TINA_USING_UART1
+    bool "Using UART1"
+    select RT_USING_SERIAL
+    default y
+
+config TINA_USING_UART2
+    bool "Using UART2"
+    select RT_USING_SERIAL
+    default y

+ 16 - 0
bsp/allwinner_tina/drivers/SConscript

@@ -0,0 +1,16 @@
+from building import *
+
+cwd  = GetCurrentDir()
+src  = Glob('*.c')
+list = os.listdir(cwd)
+CPPPATH = [cwd]
+objs = []
+
+group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH)
+
+for d in list:
+    path = os.path.join(cwd, d)
+    if os.path.isfile(os.path.join(path, 'SConscript')):
+        objs = objs + SConscript(os.path.join(d, 'SConscript'))
+objs = objs + group
+Return('objs')

+ 117 - 0
bsp/allwinner_tina/drivers/board.c

@@ -0,0 +1,117 @@
+/*
+ * File      : board.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2017, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2017-5-30      Bernard      the first version
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+
+#include "board.h"
+#include "drv_uart.h"
+#include "interrupt.h"
+#include "mmu.h"
+
+static void os_clock_irq_handle(int irqno, void *param)
+{
+    volatile rt_uint32_t *temp_addr = (rt_uint32_t *)(0x01C20C00 + 0x04);
+
+    /* clear timer */
+    *temp_addr |= 0x01;
+
+    rt_tick_increase();
+}
+
+static void mmu_init(void)
+{
+    struct mem_desc r6_mem_desc[] =
+    {
+        { 0x00000000, 0xFFFFFFFF, 0x00000000, RW_NCNB },     /* None cached for 4G memory */
+        { 0x80000000, 0x82000000 - 1, 0x80000000, RW_CB },   /* 32M cached SDRAM memory */
+        //{ 0x00000000, 0x00001000-1, 0x80000000, RW_CB },         /* isr vector table */
+        //here not set mmu
+        //start_gcc.S Copy vector to the correct address
+    };
+
+    rt_hw_mmu_init(r6_mem_desc, sizeof(r6_mem_desc) / sizeof(r6_mem_desc[0]));
+}
+
+static void os_clock_init(void)
+{
+    rt_uint32_t temp;
+    volatile rt_uint32_t *temp_addr;
+
+    /* reload value */
+    temp = 0xB71B00 / RT_TICK_PER_SECOND;
+    temp_addr = (rt_uint32_t *)(0x01C20C00 + 0x14);
+    *temp_addr = temp;
+
+    /* continuous | /2 | 24Mhz |  reload*/
+    temp = (0x00 << 7) | (0x01 << 4) | (0x01 << 2) | (0x00 << 1);
+    temp_addr = (rt_uint32_t *)(0x01C20C00 + 0x10);
+    *temp_addr &= 0xffffff00;
+    *temp_addr |= temp;
+
+    /* open timer irq */
+    temp = 0x01 << 0;
+    temp_addr = (rt_uint32_t *)(0x01C20C00);
+    *temp_addr |= temp;
+
+    /* set init value */
+    temp_addr = (rt_uint32_t *)(0x01C20C00 + 0x18);
+    *temp_addr = 0;
+
+    /* begin run timer */
+    temp = 0x01 << 0;
+    temp_addr = (rt_uint32_t *)(0x01C20C00 + 0x10);
+    *temp_addr |= temp;
+
+    temp_addr = (rt_uint32_t *)(0x01C20C00);
+    /* set irq handle */
+    rt_hw_interrupt_install(TIMER0_INTERRUPT, os_clock_irq_handle, (void *)temp_addr, "timer");
+    rt_hw_interrupt_umask(TIMER0_INTERRUPT);
+
+}
+
+void rt_hw_board_init(void)
+{
+    mmu_init();
+
+    rt_hw_interrupt_init();
+
+#ifdef RT_USING_HEAP
+    /* init memory system */
+    rt_system_heap_init(RT_HW_HEAP_BEGIN, RT_HW_HEAP_END);
+#endif
+    /* init hardware interrupt */
+    rt_hw_uart_init();
+
+#ifdef RT_USING_CONSOLE
+    /* set console device */
+    rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
+#endif /* RT_USING_CONSOLE */
+
+    os_clock_init();
+
+#ifdef RT_USING_COMPONENTS_INIT
+    rt_components_board_init();
+#endif
+}

+ 38 - 0
bsp/allwinner_tina/drivers/board.h

@@ -0,0 +1,38 @@
+/*
+ * File      : board.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2017, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2017-5-30      Bernard      the first version
+ */
+
+#ifndef _BOARD_H_
+#define _BOARD_H_
+
+#include <stdint.h>
+
+extern unsigned char __bss_start;
+extern unsigned char __bss_end;
+
+#define RT_HW_HEAP_BEGIN    (void*)&__bss_end
+#define RT_HW_HEAP_END      (void*)(0x80000000 + 32 * 1024 * 1024)
+
+void rt_hw_board_init(void);
+
+#endif

+ 527 - 0
bsp/allwinner_tina/drivers/drv_clock.c

@@ -0,0 +1,527 @@
+/*
+ * File      : drv_clock.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2017, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2018-02-08     RT-Thread    the first version
+ */
+#include <rtthread.h>
+#include <rthw.h>
+
+#include "drv_clock.h"
+
+int cpu_get_pll_clk(void)
+{
+    rt_uint32_t reg;
+    int n, k, m, p;
+
+    reg = CCU->pll_cpu_ctrl;
+    if (!(reg & (0x01 << 31)))
+        return 0;
+
+    p = PLL_CPU_DIV_P(reg) + 1;
+    n = PLL_CPU_FACTOR_N(reg) + 1;
+    k = PLL_CPU_FACTOR_K(reg) + 1;
+    m = PLL_CPU_FACTOR_M(reg) + 1;
+    //(24MHz*n*k)/(m*p)
+    return (_24MHZ_ * n * k) / (m * p);
+}
+
+int audio_get_pll_clk(void)
+{
+    rt_uint32_t reg;
+    unsigned char n, m;
+
+    reg = CCU->pll_audio_ctrl;
+    if (!(reg & (0x01 << 31)))
+        return 0;
+
+    n = PLL_AUDIO_FACTOR_N(reg) + 1;
+    m = PLL_AUDIO_PREDIV_M(reg) + 1;
+
+    //24MHz*n*2/m
+    return _24MHZ_ * 2 * n / m;
+}
+
+int video_get_pll_clk(void)
+{
+    rt_uint32_t reg;
+    int n, m;
+
+    reg = CCU->pll_video_ctrl;
+    if (!(reg & (0x01 << 31)))
+        return 0;
+
+    if (reg & PLL_VIDEO_MODE_SEL)
+    {
+        //(24MHz*n)/m
+        n = PLL_VIDEO_FACTOR_N(reg) + 1;
+        m = PLL_VIDEO_PREDIV_M(reg) + 1;
+        return (_24MHZ_ * n) / m;
+    }
+
+    if (reg & PLL_VIDEO_FRAC_CLK_OUT)
+        return 270000000;
+    else
+        return 297000000;
+
+    return 0;
+}
+
+int ve_get_pll_clk(void)
+{
+    rt_uint32_t reg;
+    int n, m;
+
+    reg = CCU->pll_ve_ctrl;
+    if (!(reg & (0x01 << 31)))
+        return 0;
+
+    if (reg & PLL_VE_MODE_SEL)
+    {
+        //(24MHz*n)/m
+        n = PLL_VE_FACTOR_N(reg) + 1;
+        m = PLL_VE_PREDIV_M(reg) + 1;
+
+        return (_24MHZ_ * n) / m;
+    }
+
+    if (reg & PLL_VE_FRAC_CLK_OUT)
+        return 297000000;
+    else
+        return 270000000;
+
+    return 0;
+}
+
+int ddr_get_pll_clk(void)
+{
+    rt_uint32_t reg;
+    int n, k, m;
+
+    reg = CCU->pll_ddr_ctrl;
+    if (!(reg & (0x01 << 31)))
+        return 0;
+
+    n = PLL_DDR_FACTOR_N(reg) + 1;
+    k = PLL_DDR_FACTOR_K(reg) + 1;
+    m = PLL_DDR_FACTOR_M(reg) + 1;
+
+    //(24MHz*n*k)/m
+    return (_24MHZ_ * n * k) / m;
+}
+
+int periph_get_pll_clk(void)
+{
+    rt_uint32_t reg;
+    int n, k;
+
+    reg = CCU->pll_periph_ctrl;
+    if (!(reg & (0x01 << 31)))
+        return 0;
+
+    n = PLL_PERIPH_FACTOR_N(reg) + 1;
+    k = PLL_PERIPH_FACTOR_K(reg) + 1;
+
+    return _24MHZ_ * n * k;
+}
+
+static int cpu_get_clk_src(void)
+{
+    return (CCU->cpu_clk_src >> 16) & 0x3;
+}
+
+int cpu_get_clk(void)
+{
+    rt_uint32_t reg;
+    int cpusrc;
+
+    reg = CCU->ahb_apb_hclkc_cfg;
+    cpusrc = cpu_get_clk_src();
+
+    if (cpusrc == CLK_PLL_SRC)
+        return (cpu_get_pll_clk() / (HCLKC_DIV(reg) + 1));
+    else if (cpusrc == CLK_OSC24M_SRC)
+        return _24MHZ_ / (HCLKC_DIV(reg) + 1);
+    else
+        return _32KHZ_ / (HCLKC_DIV(reg) + 1);  //猜测 内部32KHz时钟
+
+    return 0;
+}
+
+int ahb_get_clk(void)
+{
+    rt_uint32_t reg;
+    int sel, spd;
+
+    reg = CCU->ahb_apb_hclkc_cfg;
+    sel = AHB_SRC_SEL(reg);
+
+    if (sel == CLK_PLL_SRC)
+    {
+        spd = cpu_get_clk();
+        return spd / (1 << AHB_CLK_DIV(reg));
+    }
+    else if (sel == PRE_DIV_SRC)
+    {
+        spd = periph_get_pll_clk();
+        return spd / (AHB_PRE_DIV(reg) + 1) / (1 << AHB_CLK_DIV(reg));
+    }
+    else if (sel == CLK_OSC24M_SRC)
+        return _24MHZ_ / (1 << AHB_CLK_DIV(reg));
+    else
+        return _32KHZ_ / (1 << AHB_CLK_DIV(reg));
+}
+
+int apb_get_clk(void)
+{
+    rt_uint32_t reg;
+    int spd;
+
+    reg = CCU->ahb_apb_hclkc_cfg;
+    spd = ahb_get_clk();
+    // 0x:/2 10:/4 11:/8
+    if (!(APH_CLK_PATIO(reg) & 0x1))
+        return spd / 2;
+    else
+        return spd / (1 << APH_CLK_PATIO(reg));
+}
+
+
+static rt_err_t wait_pll_stable(rt_uint32_t base)
+{
+    rt_uint32_t rval = 0;
+    volatile int time = 0xfff;
+
+    do
+    {
+        rval = *((volatile rt_uint32_t *)base);
+        time--;
+    }
+    while (time && !(rval & (1 << 28)));
+
+    return !time;
+}
+
+rt_err_t cpu_set_pll_clk(int clk)
+{
+    rt_uint32_t cpu_src;
+    int p = 0, k = 1, m = 1, n = 0;
+
+    if (clk == 0)
+        return RT_EINVAL;
+
+    if (clk > 1152000000)
+    {
+        k = 2;
+    }
+    else if (clk > 768000000)
+    {
+        k = 3;
+        m = 2;
+    }
+
+    n = clk / (_24MHZ_ * k / m) - 1;
+    cpu_src = (CCU->cpu_clk_src >> 16) & 0x3;
+    CCU->cpu_clk_src = CLK_OSC24M_SRC << 16;
+    CCU->pll_cpu_ctrl &= ~(0x1 << 31);
+    //PLL1 rate = ((24000000 * n * k) >> 0) / m   (p is ignored)
+    CCU->pll_cpu_ctrl = (0x1 << 31) | (m << 0) | (k << 4) | (n << 8) | (p << 16);
+    if (wait_pll_stable((rt_uint32_t)(&CCU->pll_cpu_ctrl)))
+        return RT_ERROR;
+
+    CCU->cpu_clk_src = cpu_src << 16;
+
+    return RT_EOK;
+}
+
+rt_err_t audio_set_pll_clk(int clk)
+{
+    int n = 0, m = 0;
+    int n_temp = clk;
+    int m_temp = _24MHZ_ * 2;
+
+    if ((clk > 200000000) || (clk < 20000000))
+        return RT_EINVAL;
+
+    if (clk == 0)
+    {
+        CCU->pll_audio_ctrl &= ~(0x1 << 31);
+        return RT_EOK;
+    }
+
+    while (n_temp != m_temp)
+    {
+        if (n_temp > m_temp)
+        {
+            n_temp = n_temp - m_temp;
+        }
+        else if (m_temp > n_temp)
+        {
+            m_temp = m_temp - n_temp;
+        }
+    }
+
+    n = clk / n_temp;
+    m = _24MHZ_ * 2 / m_temp;
+    if ((n > 128) || (m > 32) || (clk != (_24MHZ_ * n * 2) / m))
+        return RT_ERROR;
+
+    CCU->pll_audio_ctrl &= ~(0x1 << 31);
+    n = (n - 1) & 0x7f;
+    m = (m - 1) & 0x1f;
+    //clk = (24 * n * 2) / m
+    CCU->pll_audio_ctrl = (0x1 << 31) | (0x0 << 24) | (n << 8) | m;
+
+    if (wait_pll_stable((rt_uint32_t)(&CCU->pll_audio_ctrl)))
+        return RT_ERROR;
+    else
+        return RT_EOK;
+}
+
+rt_err_t video_set_pll_clk(int clk)
+{
+    int n = 0, m = 0;
+    int n_temp = clk;
+    int m_temp = _24MHZ_;
+
+    if ((clk > 600000000) || (clk < 30000000))
+        return RT_EINVAL;
+
+    if (clk == 0)
+    {
+        CCU->pll_video_ctrl &= ~(0x1 << 31);
+        return RT_EOK;
+    }
+
+    while (n_temp != m_temp)
+    {
+        if (n_temp > m_temp)
+        {
+            n_temp = n_temp - m_temp;
+        }
+        else if (m_temp > n_temp)
+        {
+            m_temp = m_temp - n_temp;
+        }
+    }
+
+    n = clk / n_temp;
+    m = _24MHZ_ / m_temp;
+
+    if ((n > 128) || (m > 16) || (clk != (_24MHZ_ * n) / m))
+        return RT_ERROR;
+
+    CCU->pll_video_ctrl &= ~(0x1 << 31);
+    n = (n - 1) & 0x7f;
+    m = (m - 1) & 0xf;
+    //speed = (24*n)/m
+    CCU->pll_video_ctrl = (0x1 << 31) | (0x0 << 30) | (0x1 << 24) | (n << 8) | m;
+
+    if (wait_pll_stable((rt_uint32_t)(&CCU->pll_video_ctrl)))
+        return RT_ERROR;
+    else
+        return RT_EOK;
+}
+
+rt_err_t ve_set_pll_clk(int clk)
+{
+    int n = 0, m = 0;
+    int n_temp = clk;
+    int m_temp = _24MHZ_;
+
+    if ((clk > 600000000) || (clk < 30000000))
+        return RT_EINVAL;
+
+    if (clk == 0)
+    {
+        CCU->pll_ve_ctrl &= ~(0x1 << 31);
+        return RT_EOK;
+    }
+
+    while (n_temp != m_temp)
+    {
+        if (n_temp > m_temp)
+        {
+            n_temp = n_temp - m_temp;
+        }
+        else if (m_temp > n_temp)
+        {
+            m_temp = m_temp - n_temp;
+        }
+    }
+
+    n = clk / n_temp;
+    m = _24MHZ_ / m_temp;
+
+    if ((n > 128) || (m > 16) || (clk != (_24MHZ_ * n) / m))
+        return RT_ERROR;
+
+    CCU->pll_ve_ctrl &= ~(0x1 << 31);
+    n = (n - 1) & 0x7f;
+    m = (m - 1) & 0xf;
+    //clk = (24 * n) / m
+    CCU->pll_ve_ctrl = (0x1 << 31) | (0x1 << 24) | (n << 8) | m;
+    if (wait_pll_stable((rt_uint32_t)(&CCU->pll_ve_ctrl)))
+        return RT_ERROR;
+    else
+        return RT_EOK;
+}
+
+rt_err_t periph_set_pll_clk(int clk)
+{
+    rt_uint32_t clk_src;
+    rt_uint32_t temp_data;
+    int n = 0, k = 0;
+
+    if ((clk > 1800000000) || (clk < 200000000) || (clk == 0) || (clk % _24MHZ_ != 0))
+        return RT_EINVAL;
+
+    n = clk / _24MHZ_;
+
+    for (k = 2; ((n > 32) || (k < 5)); k++)
+    {
+        if ((n % k) != 0)
+            n /= k;
+    }
+
+    if ((n > 32) || (k > 4) || (clk != (_24MHZ_ * n * k)))
+        return RT_ERROR;
+    temp_data = CCU->ahb_apb_hclkc_cfg;
+    clk_src = (temp_data >> 12) & 0x3;
+    temp_data &= ~(0x3 << 12);
+    temp_data |= (CLK_PLL_SRC << 12);
+    CCU->ahb_apb_hclkc_cfg = temp_data;
+    CCU->pll_periph_ctrl &= ~(0x1 << 31);
+    n = (n - 1) & 0x1f;
+    k = (k - 1) & 0x3;
+    //clk = 24 * n *k
+    CCU->pll_periph_ctrl = (0x1 << 31) | (0x1 << 18) | (n << 8) | (k << 4) || (0x1);
+    if (wait_pll_stable((rt_uint32_t)(&CCU->pll_periph_ctrl)))
+        return RT_ERROR;
+
+    temp_data = CCU->ahb_apb_hclkc_cfg;
+    temp_data &= ~(0x3 << 12);
+    temp_data |= (clk_src << 12);
+    CCU->ahb_apb_hclkc_cfg = temp_data;
+
+    return RT_EOK;
+}
+
+rt_err_t cpu_set_clk(int clk)
+{
+    if (clk < _24MHZ_)
+        return RT_EINVAL;
+
+    if (clk == cpu_get_clk())
+        return RT_EOK;
+
+    CCU->cpu_clk_src = CLK_OSC24M_SRC << 16;
+    if (clk == _24MHZ_)
+        return RT_EOK;
+
+    if (cpu_set_pll_clk(clk))
+        return RT_ERROR;
+
+    CCU->ahb_apb_hclkc_cfg &= ~(0x3 << 16);
+    CCU->cpu_clk_src = CLK_PLL_SRC << 16;
+
+    return RT_EOK;
+}
+
+rt_err_t bus_gate_clk_enalbe(enum bus_gate bus)
+{
+    rt_uint32_t offset;
+    rt_uint32_t gate_reg;
+
+    offset = bus & 0xfff;
+    gate_reg = bus >> BUS_GATE_OFFSET_BIT;
+
+    if (gate_reg == 0x00)
+        CCU->bus_clk_gating0 |= (0x1 << offset);
+    else if (gate_reg == 0x01)
+        CCU->bus_clk_gating1 |= (0x1 << offset);
+    else if (gate_reg == 0x02)
+        CCU->bus_clk_gating2 |= (0x1 << offset);
+    else
+        return RT_EINVAL;
+
+    return RT_EOK;
+}
+
+rt_err_t bus_gate_clk_disalbe(enum bus_gate bus)
+{
+    rt_uint32_t offset;
+    rt_uint32_t gate_reg;
+
+    offset = bus & 0xfff;
+    gate_reg = bus >> BUS_GATE_OFFSET_BIT;
+
+    if (gate_reg == 0x00)
+        CCU->bus_clk_gating0 &= ~(0x1 << offset);
+    else if (gate_reg == 0x01)
+        CCU->bus_clk_gating1 &= ~(0x1 << offset);
+    else if (gate_reg == 0x02)
+        CCU->bus_clk_gating2 &= ~(0x1 << offset);
+    else
+        return RT_EINVAL;
+
+    return RT_EOK;
+}
+
+rt_err_t bus_software_reset_disalbe(enum bus_gate bus)
+{
+    rt_uint32_t offset;
+    rt_uint32_t gate_reg;
+
+    offset = bus & 0xfff;
+    gate_reg = bus >> BUS_GATE_OFFSET_BIT;
+
+    if (gate_reg == 0x00)
+        CCU->bus_soft_rst0 |= (0x1 << offset);
+    else if (gate_reg == 0x01)
+        CCU->bus_soft_rst1 |= (0x1 << offset);
+    else if (gate_reg == 0x02)
+        CCU->bus_soft_rst2 |= (0x1 << offset);
+    else
+        return RT_EINVAL;
+
+    return RT_EOK;
+}
+
+rt_err_t bus_software_reset_enalbe(enum bus_gate bus)
+{
+    rt_uint32_t offset;
+    rt_uint32_t gate_reg;
+
+    offset = bus & 0xfff;
+    gate_reg = bus >> BUS_GATE_OFFSET_BIT;
+
+    if (gate_reg == 0x00)
+        CCU->bus_soft_rst0 &= ~(0x1 << offset);
+    else if (gate_reg == 0x01)
+        CCU->bus_soft_rst1 &= ~(0x1 << offset);
+    else if (gate_reg == 0x02)
+        CCU->bus_soft_rst2 &= ~(0x1 << offset);
+    else
+        return RT_EINVAL;
+
+    return RT_EOK;
+}
+

+ 243 - 0
bsp/allwinner_tina/drivers/drv_clock.h

@@ -0,0 +1,243 @@
+/*
+ * File      : drv_clock.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2017, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2018-02-08     RT-Thread    the first version
+ */
+#ifndef __DRV_CLOCK_H__
+#define __DRV_CLOCK_H__
+
+/* PLL state */
+#define PLL_ENBALE              (0x1)
+#define PLL_STABLE              (0x2)
+
+/* Clock source selection */
+#define CLK_LOSC_SRC            (0x00)
+#define CLK_OSC24M_SRC          (0x01)
+#define CLK_PLL_SRC             (0x02)
+#define PRE_DIV_SRC             (0x03)
+
+/*  */
+#define BE_GATING_DRAM          (0x1<<26)
+#define FE_GATING_DRAM          (0x1<<24)
+#define TVD_GATING_DRAM         (0x1<<3)
+#define DEINTERLACE_GATING_DRAM (0x1<<2)
+#define CSI_GATING_DRAM         (0x1<<1)
+#define VE_GATING_DRAM          (0x1<<0)
+
+/*  */
+#define TCON_PLL_VIDEO_X1       (0x000)
+#define TCON_PLL_VIDEO_X2       (0x002)
+
+
+#define PLL_CPU_ENABLE_STATE            (0x1<<31)
+#define PLL_CPU_HAS_BEEN_STABLE         (0x1<<28)
+#define PLL_CPU_DIV_P(reg)              ((reg>>16)&0x3)
+#define PLL_CPU_FACTOR_N(reg)           ((reg>>8)&0x1f)
+#define PLL_CPU_FACTOR_K(reg)           ((reg>>4)&0x3)
+#define PLL_CPU_FACTOR_M(reg)           ((reg)&0x3)
+
+#define PLL_AUDIO_ENABLE_STATE          (0x1<<31)
+#define PLL_AUDIO_HAS_BEEN_STABLE       (0x1<<28)
+#define PLL_AUDIO_FACTOR_N(reg)         ((reg>>8)&0x7f)
+#define PLL_AUDIO_PREDIV_M(reg)         ((reg)&0x1f)
+
+#define PLL_VIDEO_ENABLE_STATE          (0x1<<31)
+#define PLL_VIDEO_MODE                  (0x1<<30)
+#define PLL_VIDEO_HAS_BEEN_STABLE       (0x1<<28)
+#define PLL_VIDEO_FRAC_CLK_OUT          (0x1<<25)
+#define PLL_VIDEO_MODE_SEL              (0x1<<24)
+#define PLL_VIDEO_SDM_EN                (0x1<<20)
+#define PLL_VIDEO_FACTOR_N(reg)         ((reg>>8)&0x7f)
+#define PLL_VIDEO_PREDIV_M(reg)         (reg&0xf)
+
+#define PLL_VE_ENABLE_STATE             (0x1<<31)
+#define PLL_VE_HAS_BEEN_STABLE          (0x1<<28)
+#define PLL_VE_FRAC_CLK_OUT             (0x1<<25)
+#define PLL_VE_MODE_SEL                 (0x1<<24)
+#define PLL_VE_FACTOR_N(reg)            ((reg>>8)&0x7f)
+#define PLL_VE_PREDIV_M(reg)            (reg&0xf)
+
+#define PLL_DDR_ENABLE_STATE            (0x1<<31)
+#define PLL_DDR_HAS_BEEN_STABLE         (0x1<<28)
+#define SDRAM_SIGMA_DELTA_EN            (0x1<<24)
+#define PLL_DDR_CFG_UPDATE              (0x1<<20)
+#define PLL_DDR_FACTOR_N(reg)           ((reg>>8)&0x1f)
+#define PLL_DDR_FACTOR_K(reg)           ((reg>>4)&0x3)
+#define PLL_DDR_FACTOR_M(reg)           ((reg)&0x3)
+
+#define PLL_PERIPH_ENABLE_STATE         (0x1<<31)
+#define PLL_PERIPH_HAS_BEEN_STABLE      (0x1<<28)
+#define PLL_PERIPH_24M_OUT_EN           (0x1<<18)
+#define PLL_PERIPH_24M_POST_DIV(reg)    ((reg>>16)&0x3)
+#define PLL_PERIPH_FACTOR_N(reg)        ((reg>>8)&0x1f)
+#define PLL_PERIPH_FACTOR_K(reg)        ((reg>>4)&0x3)
+#define PLL_PERIPH_FACTOR_M(reg)        (reg&0x3)
+
+#define HCLKC_DIV(reg)                  ((reg>>16)&0x3)
+#define AHB_SRC_SEL(reg)                ((reg>>12)&0x3)
+#define AHB_CLK_DIV(reg)                ((reg>>4)&0x3)
+#define AHB_PRE_DIV(reg)                ((reg>>6)&0x3)
+#define APH_CLK_PATIO(reg)              ((reg>>8)&0x3)
+
+
+#define CCM_MMC_CTRL_OSCM24             (0x00)
+#define CCM_MMC_CTRL_PLL_PERIPH         (0x01)
+
+#define CCU_BASE_ADDR      (0x01C20000)
+
+#define _24MHZ_     (24000000U)
+#define _32KHZ_     (32000U)
+
+/* GATE */
+
+#define BUS_GATE_OFFSET_BIT    (12)
+
+enum bus_gate
+{
+    USB_OTG_GATING     = (0x18 | (0x0 << BUS_GATE_OFFSET_BIT)),
+    SPI1_GATING        = (0x15 | (0x0 << BUS_GATE_OFFSET_BIT)),
+    SPI0_GATING        = (0x14 | (0x0 << BUS_GATE_OFFSET_BIT)),
+    SDRAM_GATING       = (0x0E | (0x0 << BUS_GATE_OFFSET_BIT)),
+    SD1_GATING         = (0x09 | (0x0 << BUS_GATE_OFFSET_BIT)),
+    SD0_GATING         = (0x08 | (0x0 << BUS_GATE_OFFSET_BIT)),
+    DMA_GATING         = (0x06 | (0x0 << BUS_GATE_OFFSET_BIT)),
+
+    DEFE_GATING        = (0x0E | (0x1 << BUS_GATE_OFFSET_BIT)),
+    DEBE_GATING        = (0x0C | (0x1 << BUS_GATE_OFFSET_BIT)),
+    TVE_GATING         = (0x0A | (0x1 << BUS_GATE_OFFSET_BIT)),
+    TVD_GATING         = (0x09 | (0x1 << BUS_GATE_OFFSET_BIT)),
+    CSI_GATING         = (0x08 | (0x1 << BUS_GATE_OFFSET_BIT)),
+    DEINTERLACE_GATING = (0x05 | (0x1 << BUS_GATE_OFFSET_BIT)),
+    LCD_GATING         = (0x04 | (0x1 << BUS_GATE_OFFSET_BIT)),
+    VE_GATING          = (0x00 | (0x1 << BUS_GATE_OFFSET_BIT)),
+
+    UART2_GATING       = (0x16 | (0x2 << BUS_GATE_OFFSET_BIT)),
+    UART1_GATING       = (0x15 | (0x2 << BUS_GATE_OFFSET_BIT)),
+    UART0_GATING       = (0x14 | (0x2 << BUS_GATE_OFFSET_BIT)),
+    TWI2_GATING        = (0x12 | (0x2 << BUS_GATE_OFFSET_BIT)),
+    TWI1_GATING        = (0x11 | (0x2 << BUS_GATE_OFFSET_BIT)),
+    TWI0_GATING        = (0x10 | (0x2 << BUS_GATE_OFFSET_BIT)),
+    DAUDIO_GATING      = (0x0C | (0x2 << BUS_GATE_OFFSET_BIT)),
+    RSB_GATING         = (0x03 | (0x2 << BUS_GATE_OFFSET_BIT)),
+    CIR_GATING         = (0x02 | (0x2 << BUS_GATE_OFFSET_BIT)),
+    OWA_GATING         = (0x01 | (0x2 << BUS_GATE_OFFSET_BIT)),
+    AUDIO_CODEC_GATING = (0x00 | (0x2 << BUS_GATE_OFFSET_BIT)),
+};
+
+struct tina_ccu
+{
+    volatile rt_uint32_t pll_cpu_ctrl;         /* 0x000 */
+    volatile rt_uint32_t reserved0;
+    volatile rt_uint32_t pll_audio_ctrl;       /* 0x008 */
+    volatile rt_uint32_t reserved1;
+    volatile rt_uint32_t pll_video_ctrl;       /* 0x010 */
+    volatile rt_uint32_t reserved2;
+    volatile rt_uint32_t pll_ve_ctrl;          /* 0x018 */
+    volatile rt_uint32_t reserved3;
+    volatile rt_uint32_t pll_ddr_ctrl;         /* 0x020 */
+    volatile rt_uint32_t reserved4;
+    volatile rt_uint32_t pll_periph_ctrl;      /* 0x028 */
+    volatile rt_uint32_t reserved5[9];
+    volatile rt_uint32_t cpu_clk_src;          /* 0x050 */
+    volatile rt_uint32_t ahb_apb_hclkc_cfg;    /* 0x054 */
+    volatile rt_uint32_t reserved6[2];
+    volatile rt_uint32_t bus_clk_gating0;      /* 0x060 */
+    volatile rt_uint32_t bus_clk_gating1;      /* 0x064 */
+    volatile rt_uint32_t bus_clk_gating2;      /* 0x068 */
+    volatile rt_uint32_t reserved7[7];
+    volatile rt_uint32_t sdmmc0_clk;           /* 0x088 */
+    volatile rt_uint32_t sdmmc1_clk;           /* 0x08C */
+    volatile rt_uint32_t reserved8[8];
+    volatile rt_uint32_t daudio_clk;           /* 0x0B0 */
+    volatile rt_uint32_t owa_clk;              /* 0x0B4 */
+    volatile rt_uint32_t cir_clk;              /* 0x0B8 */
+    volatile rt_uint32_t reserved9[4];
+    volatile rt_uint32_t usbphy_clk;           /* 0x0CC */
+    volatile rt_uint32_t reserved10[12];
+    volatile rt_uint32_t dram_gating;          /* 0x100 */
+    volatile rt_uint32_t be_clk;               /* 0x104 */
+    volatile rt_uint32_t reserved11;
+    volatile rt_uint32_t fe_clk;               /* 0x10C */
+    volatile rt_uint32_t reserved12[2];
+    volatile rt_uint32_t tcon_clk;             /* 0x118*/
+    volatile rt_uint32_t di_clk;               /* 0x11C */
+    volatile rt_uint32_t tve_clk;              /* 0x120 */
+    volatile rt_uint32_t tvd_clk;              /* 0x124 */
+    volatile rt_uint32_t reserved13[3];
+    volatile rt_uint32_t csi_clk;              /* 0x134 */
+    volatile rt_uint32_t reserved14;
+    volatile rt_uint32_t ve_clk;               /* 0x13C */
+    volatile rt_uint32_t audio_codec_clk;      /* 0x140 */
+    volatile rt_uint32_t avs_clk;              /* 0x144 */
+    volatile rt_uint32_t reserved15[46];
+    volatile rt_uint32_t pll_stable_time0;     /* 0x200 */
+    volatile rt_uint32_t pll_stable_time1;     /* 0x204 */
+    volatile rt_uint32_t reserved16[6];
+    volatile rt_uint32_t pll_cpu_bias;         /* 0x220 */
+    volatile rt_uint32_t pll_audio_bias;       /* 0x224 */
+    volatile rt_uint32_t pll_video_bias;       /* 0x228 */
+    volatile rt_uint32_t pll_ve_bias;          /* 0x22C */
+    volatile rt_uint32_t pll_ddr_bias;         /* 0x230 */
+    volatile rt_uint32_t pll_periph_bias;      /* 0x234 */
+    volatile rt_uint32_t reserved17[6];
+    volatile rt_uint32_t pll_cpu_tun;          /* 0x250 */
+    volatile rt_uint32_t reserved18[3];
+    volatile rt_uint32_t pll_ddr_tun;          /* 0x260 */
+    volatile rt_uint32_t reserved19[8];
+    volatile rt_uint32_t pll_audio_pat_ctrl;   /* 0x284 */
+    volatile rt_uint32_t pll_video_pat_ctrl;   /* 0x288 */
+    volatile rt_uint32_t reserved20;
+    volatile rt_uint32_t pll_ddr_pat_ctrl;     /* 0x290 */
+    volatile rt_uint32_t reserved21[11];
+    volatile rt_uint32_t bus_soft_rst0;        /* 0x2C0 */
+    volatile rt_uint32_t bus_soft_rst1;        /* 0x2C4 */
+    volatile rt_uint32_t reserved22[2];
+    volatile rt_uint32_t bus_soft_rst2;        /* 0x2D0 */
+};
+
+typedef struct tina_ccu *tina_ccu_t;
+
+#define CCU ((tina_ccu_t) CCU_BASE_ADDR)
+
+int cpu_get_pll_clk(void);
+int audio_get_pll_clk(void);
+int video_get_pll_clk(void);
+int ve_get_pll_clk(void);
+int ddr_get_pll_clk(void);
+int periph_get_pll_clk(void);
+int cpu_get_clk(void);
+int ahb_get_clk(void);
+int apb_get_clk(void);
+
+rt_err_t cpu_set_pll_clk(int clk);
+rt_err_t audio_set_pll_clk(int clk);
+rt_err_t video_set_pll_clk(int clk);
+rt_err_t ve_set_pll_clk(int clk);
+rt_err_t periph_set_pll_clk(int clk);
+
+rt_err_t cpu_set_clk(int clk);
+
+rt_err_t bus_gate_clk_enalbe(enum bus_gate bus);
+rt_err_t bus_gate_clk_disalbe(enum bus_gate bus);
+rt_err_t bus_software_reset_enalbe(enum bus_gate bus);
+rt_err_t bus_software_reset_disalbe(enum bus_gate bus);
+
+#endif

+ 564 - 0
bsp/allwinner_tina/drivers/drv_gpio.c

@@ -0,0 +1,564 @@
+/*
+ * File      : drv_gpio.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2017, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2018-02-08     RT-Thread    the first version
+ */
+#include <rtthread.h>
+#include <rthw.h>
+
+#include "drv_gpio.h"
+#include "interrupt.h"
+
+#define DBG_ENABLE
+#define DBG_SECTION_NAME  "[GPIO]"
+#define DBG_LEVEL         DBG_WARNING
+#define DBG_COLOR
+#include <rtdbg.h>
+
+
+#define readl(addr)           (*(volatile unsigned int *)(addr))
+#define writel(value,addr)    (*(volatile unsigned int *)(addr) = (value))
+
+// Todo: add RT_ASSERT.
+
+/*********************************************************
+**   IO
+*********************************************************/
+int gpio_set_func(enum gpio_port port, enum gpio_pin pin, rt_uint8_t func)
+{
+    rt_uint32_t addr;
+    rt_uint32_t offset;
+    rt_uint32_t data;
+
+    RT_ASSERT((GPIO_PORT_A <= port) && (port < GPIO_PORT_NUM));
+    RT_ASSERT((GPIO_PIN_0 <= pin) && (pin < GPIO_PIN_NUM));
+
+    if (func & 0x8)
+    {
+        dbg_log(DBG_WARNING, "[line]:%d There is a warning with parameter input\n", __LINE__);
+        return RT_EINVAL;
+    }
+
+    addr = GPIOn_CFG_ADDR(port) + (pin / 8) * 4;
+    offset = (pin % 8) * 4;
+
+    data = readl(addr);
+    data &= ~(0x7 << offset);
+    data |= func << offset;
+    writel(data, addr);
+
+    dbg_log(DBG_LOG, "[line]:%d offset:%d addr:%08x data:%08x\n", __LINE__, offset, addr, *((rt_uint32_t *)addr));
+    return RT_EOK;
+}
+
+int gpio_set_value(enum gpio_port port, enum gpio_pin pin, rt_uint8_t value)
+{
+    rt_uint32_t addr;
+    rt_uint32_t offset;
+    rt_uint32_t data;
+
+    RT_ASSERT((GPIO_PORT_A <= port) && (port < GPIO_PORT_NUM));
+    RT_ASSERT((GPIO_PIN_0 <= pin) && (pin < GPIO_PIN_NUM));
+
+    if (value & 0xE)
+    {
+        dbg_log(DBG_WARNING, "[line]:%d There is a warning with parameter input\n", __LINE__);
+        return RT_EINVAL;
+    }
+
+    addr = GPIOn_DATA_ADDR(port);
+    offset = pin;
+
+    data = readl(addr);
+    data &= ~(0x1 << offset);
+    data |= value << offset;
+    writel(data, addr);
+
+    dbg_log(DBG_LOG, "[line]:%d offset:%d addr:%08x data:%08x\n", __LINE__, offset, addr, *((rt_uint32_t *)addr));
+    return RT_EOK;
+}
+
+int gpio_get_value(enum gpio_port port, enum gpio_pin pin)
+{
+    rt_uint32_t addr;
+    rt_uint32_t offset;
+    rt_uint32_t data;
+
+    RT_ASSERT((GPIO_PORT_A <= port) && (port < GPIO_PORT_NUM));
+    RT_ASSERT((GPIO_PIN_0 <= pin) && (pin < GPIO_PIN_NUM));
+
+    addr = GPIOn_DATA_ADDR(port);
+    offset = pin;
+
+    data = readl(addr);
+
+    dbg_log(DBG_LOG, "[line]:%d offset:%d addr:%08x data:%08x\n", __LINE__, offset, addr, *((rt_uint32_t *)addr));
+    return (data >> offset) & 0x01;
+}
+
+int gpio_set_pull_mode(enum gpio_port port,  enum gpio_pin pin, enum gpio_pull pull)
+{
+    rt_uint32_t addr;
+    rt_uint32_t offset;
+    rt_uint32_t data;
+
+    RT_ASSERT((GPIO_PORT_A <= port) && (port < GPIO_PORT_NUM));
+    RT_ASSERT((GPIO_PIN_0 <= pin) && (pin < GPIO_PIN_NUM));
+
+    if (pull & 0xC)
+    {
+        dbg_log(DBG_WARNING, "[line]:%d There is a warning with parameter input\n", __LINE__);
+        return RT_EINVAL;
+    }
+
+    addr = GPIOn_PUL_ADDR(port);
+    addr += pin > GPIO_PIN_15 ? 0x4 : 0x0;
+    offset = (pin & 0xf) << 1;
+
+    data = readl(addr);
+    data &= ~(0x3 << offset);
+    data |= pull << offset;
+    writel(data, addr);
+
+    dbg_log(DBG_LOG, "[line]:%d offset:%d addr:%08x data:%08x\n", __LINE__, offset, addr, *((rt_uint32_t *)addr));
+    return RT_EOK;
+}
+
+int gpio_set_drive_level(enum gpio_port port, enum gpio_pin pin, enum gpio_drv_level level)
+{
+    volatile rt_uint32_t addr;
+    rt_uint32_t offset;
+    rt_uint32_t data;
+
+    RT_ASSERT((GPIO_PORT_A <= port) && (port < GPIO_PORT_NUM));
+    RT_ASSERT((GPIO_PIN_0 <= pin) && (pin < GPIO_PIN_NUM));
+
+    if (level & 0xC)
+    {
+        dbg_log(DBG_WARNING, "[line]:%d There is a warning with parameter input\n", __LINE__);
+        return RT_EINVAL;
+    }
+
+    addr = GPIOn_DRV_ADDR(port);
+    addr += pin > GPIO_PIN_15 ? 0x4 : 0x0;
+    offset = (pin & 0xf) << 1;
+
+    data = readl(addr);
+    data &= ~(0x3 << offset);
+    data |= level << offset;
+    writel(data, addr);
+
+    dbg_log(DBG_LOG, "[line]:%d offset:%d addr:%08x data:%08x\n", __LINE__, offset, addr, *((rt_uint32_t *)addr));
+    return RT_EOK;
+}
+
+void gpio_direction_input(enum gpio_port port,  enum gpio_pin pin)
+{
+    volatile rt_uint32_t addr;
+    rt_uint32_t offset;
+    rt_uint32_t data;
+
+    RT_ASSERT((GPIO_PORT_A <= port) && (port < GPIO_PORT_NUM));
+    RT_ASSERT((GPIO_PIN_0 <= pin) && (pin < GPIO_PIN_NUM));
+
+    addr = GPIOn_CFG_ADDR(port) + (pin / 8) * 4;
+    offset = (pin % 8) * 4;
+
+    data = readl(addr);
+    data &= ~(0x7 << offset);
+    data |= IO_INPUT << offset;
+    writel(data, addr);
+
+    dbg_log(DBG_LOG, "[line]:%d offset:%d addr:%08x data:%08x\n", __LINE__, offset, addr, *((rt_uint32_t *)addr));
+}
+
+void gpio_direction_output(enum gpio_port port, enum gpio_pin pin, int value)
+{
+    volatile rt_uint32_t addr;
+    rt_uint32_t offset;
+    rt_uint32_t data;
+
+    RT_ASSERT((GPIO_PORT_A <= port) && (port < GPIO_PORT_NUM));
+    RT_ASSERT((GPIO_PIN_0 <= pin) && (pin < GPIO_PIN_NUM));
+
+    gpio_set_value(port, pin, value);
+    addr = GPIOn_CFG_ADDR(port) + (pin / 8) * 4;
+    offset = (pin % 8) * 4;
+
+    data = readl(addr);
+    data &= ~(0x7 << offset);
+    data |= IO_OUTPUT << offset;
+    writel(data, addr);
+
+    dbg_log(DBG_LOG, "[line]:%d offset:%d addr:%08x data:%08x\n", __LINE__, offset, addr, *((rt_uint32_t *)addr));
+}
+/*********************************************************
+**   IRQ
+*********************************************************/
+static void gpio_ack_irq(enum gpio_port port,  enum gpio_pin pin)
+{
+    rt_uint32_t addr;
+    rt_uint32_t data;
+
+    addr = GPIOn_INT_STA_ADDR(port);
+    data = readl(addr);
+    data |= 0x1 << pin;
+    writel(data, addr);
+}
+
+void gpio_select_irq_clock(enum gpio_port port, enum gpio_irq_clock clock)
+{
+    rt_uint32_t addr;
+    rt_uint32_t data;
+
+    RT_ASSERT((GPIO_PORT_C < port) && (port < GPIO_PORT_NUM));
+
+    addr = GPIOn_INT_DEB_ADDR(port - GPIO_PORT_D);
+
+    data = readl(addr);
+    data &= ~0x01;
+    data |= clock;
+    writel(data, addr);
+    dbg_log(DBG_LOG, "[line]:%d addr:%08x data:%08x\n", __LINE__, addr, *((rt_uint32_t *)addr));
+}
+
+void gpio_set_debounce(enum gpio_port port, enum gpio_direction_type prescaler)
+{
+    rt_uint32_t addr;
+    rt_uint32_t data;
+
+    RT_ASSERT((GPIO_PORT_C < port) && (port < GPIO_PORT_NUM));
+
+    addr = GPIOn_INT_DEB_ADDR(port - GPIO_PORT_D);
+
+    data = readl(addr);
+    data &= ~(0x07 << 4);
+    data |= prescaler << 4;
+    writel(data, addr);
+    dbg_log(DBG_LOG, "[line]:%d addr:%08x data:%08x\n", __LINE__, addr, *((rt_uint32_t *)addr));
+}
+
+void gpio_irq_enable(enum gpio_port port,  enum gpio_pin pin)
+{
+    rt_uint32_t addr;
+    rt_uint32_t offset;
+    rt_uint32_t data;
+
+    RT_ASSERT((GPIO_PORT_C < port) && (port < GPIO_PORT_NUM));
+    RT_ASSERT((GPIO_PIN_0 <= pin) && (pin < GPIO_PIN_NUM));
+
+    addr = GPIOn_INT_CTRL_ADDR(port - GPIO_PORT_D);
+    offset = pin;
+
+    data = readl(addr);
+    data |= 0x1 << offset;
+    writel(data, addr);
+    gpio_select_irq_clock(port, GPIO_IRQ_HOSC_24MHZ);
+    dbg_log(DBG_LOG, "[line]:%d offset:%d addr:%08x data:%08x\n", __LINE__, offset, addr, *((rt_uint32_t *)addr));
+}
+
+void gpio_irq_disable(enum gpio_port port,  enum gpio_pin pin)
+{
+    rt_uint32_t addr;
+    rt_uint32_t offset;
+    rt_uint32_t data;
+
+    RT_ASSERT((GPIO_PORT_C < port) && (port < GPIO_PORT_NUM));
+    RT_ASSERT((GPIO_PIN_0 <= pin) && (pin < GPIO_PIN_NUM));
+
+    gpio_ack_irq(port - GPIO_PORT_D, pin);
+    addr = GPIOn_INT_CTRL_ADDR(port - GPIO_PORT_D);
+    offset = pin;
+
+    data = readl(addr);
+    data &= ~(0x1 << offset);
+
+    writel(data, addr);
+    dbg_log(DBG_LOG, "[line]:%d offset:%d addr:%08x data:%08x\n", __LINE__, offset, addr, *((rt_uint32_t *)addr));
+}
+
+void gpio_set_irq_type(enum gpio_port port,  enum gpio_pin pin, enum gpio_irq_type irq_type)
+{
+    rt_uint32_t addr;
+    rt_uint32_t offset;
+    rt_uint32_t data;
+
+    RT_ASSERT((GPIO_PORT_C < port) && (port < GPIO_PORT_NUM));
+    RT_ASSERT((GPIO_PIN_0 <= pin) && (pin < GPIO_PIN_NUM));
+
+    addr = GPIOn_INT_CFG_ADDR(port - GPIO_PORT_D) + (pin / 8) * 4;
+    offset = (pin % 8) * 4;
+
+    data = readl(addr);
+    data &= ~(0x7 << offset);
+    data |= irq_type << offset;
+    writel(data, addr);
+
+    dbg_log(DBG_LOG, "[line]:%d offset:%d addr:%08x data:%08x\n", __LINE__, offset, addr, *((rt_uint32_t *)addr));
+}
+
+static struct gpio_irq_def _g_gpio_irq_tbl[GPIO_PORT_NUM];
+
+void gpio_set_irq_callback(enum gpio_port port, enum gpio_pin pin, void (*irq_cb)(void *), void *irq_arg)
+{
+    RT_ASSERT((GPIO_PORT_C < port) && (port < GPIO_PORT_NUM));
+    RT_ASSERT((GPIO_PIN_0 <= pin) && (pin < GPIO_PIN_NUM));
+
+    _g_gpio_irq_tbl[port].irq_cb[pin]    = irq_cb;
+    _g_gpio_irq_tbl[port].irq_arg[pin]   = irq_arg;
+}
+
+void gpio_clear_irq_callback(enum gpio_port port, enum gpio_pin pin)
+{
+    gpio_irq_disable(port, pin);
+
+    _g_gpio_irq_tbl[port].irq_cb[pin]    = RT_NULL;
+    _g_gpio_irq_tbl[port].irq_arg[pin]   = RT_NULL;
+}
+
+static void gpio_irq_handler(int irq, void *param)
+{
+    struct gpio_irq_def *irq_def = (struct gpio_irq_def *)param;
+    rt_uint32_t pend, enable;
+    int port, pin;
+    rt_uint32_t addr;
+
+    pin = 0;
+    port = irq - PIOD_INTERRUPT;
+    addr = GPIOn_INT_STA_ADDR(port);
+    pend = readl(addr);
+    addr = GPIOn_INT_CTRL_ADDR(port);
+    enable = readl(addr);
+    pend &= enable;
+
+    while (pend)
+    {
+        if ((pend & 0x1) && (irq_def->irq_cb[pin] != RT_NULL))
+        {
+            dbg_log(DBG_LOG, "do irq callback...\n", port, pin);
+            irq_def->irq_cb[pin](irq_def->irq_arg[pin]);
+        }
+        pin++;
+        pend = pend >> 1;
+        gpio_ack_irq(port, pin);
+    }
+}
+
+
+#ifdef RT_USING_PIN
+#include <rtdevice.h>
+
+#define PIN_MAGIC    (0x5A)
+#define PIN_NUM(_N)      (sizeof(_N) / sizeof(_N[0]))
+
+struct _pin_index
+{
+    rt_uint8_t id;
+    rt_uint8_t pin_port;
+    rt_uint8_t pin;
+    rt_uint8_t magic;
+};
+
+static struct _pin_index pin_index[] =
+{
+    {0, 0, 0, 0},
+    {1, 0, 0, 0},
+    {2, 0, 0, 0},
+    {3, 0, 0, 0},
+    {4, 0, 0, 0},
+    {5, 0, 0, 0},
+    {6, GPIO_PORT_D, GPIO_PIN_0,  PIN_MAGIC},
+    {7, GPIO_PORT_D, GPIO_PIN_1,  PIN_MAGIC},
+    {8, GPIO_PORT_D, GPIO_PIN_2,  PIN_MAGIC},
+    {9, GPIO_PORT_D, GPIO_PIN_3,  PIN_MAGIC},
+    {10, GPIO_PORT_D, GPIO_PIN_4,  PIN_MAGIC},
+    {11, GPIO_PORT_D, GPIO_PIN_5,  PIN_MAGIC},
+    {12, GPIO_PORT_D, GPIO_PIN_6,  PIN_MAGIC},
+    {13, GPIO_PORT_D, GPIO_PIN_7,  PIN_MAGIC},
+    {14, GPIO_PORT_D, GPIO_PIN_8,  PIN_MAGIC},
+    {15, GPIO_PORT_D, GPIO_PIN_9,  PIN_MAGIC},
+    {16, GPIO_PORT_D, GPIO_PIN_10, PIN_MAGIC},
+    {17, GPIO_PORT_D, GPIO_PIN_11, PIN_MAGIC},
+    {18, GPIO_PORT_D, GPIO_PIN_12, PIN_MAGIC},
+    {19, GPIO_PORT_D, GPIO_PIN_13, PIN_MAGIC},
+    {20, 0, 0, 0},
+    {21, GPIO_PORT_D, GPIO_PIN_14, PIN_MAGIC},
+    {22, 0, 0, 0},
+    {23, GPIO_PORT_D, GPIO_PIN_15, PIN_MAGIC},
+    {24, GPIO_PORT_D, GPIO_PIN_16, PIN_MAGIC},
+    {25, GPIO_PORT_D, GPIO_PIN_17, PIN_MAGIC},
+    {26, GPIO_PORT_D, GPIO_PIN_18, PIN_MAGIC},
+    {27, GPIO_PORT_D, GPIO_PIN_19, PIN_MAGIC},
+    {28, GPIO_PORT_D, GPIO_PIN_20, PIN_MAGIC},
+    {29, GPIO_PORT_D, GPIO_PIN_21, PIN_MAGIC},
+    {30, 0, 0, 0},
+    {31, 0, 0, 0},
+    {32, 0, 0, 0},
+    {33, 0, 0, 0},
+    {34, 0, 0, 0},
+    {35, 0, 0, 0},
+    {36, 0, 0, 0},
+    {37, GPIO_PORT_E, GPIO_PIN_12, PIN_MAGIC},
+    {38, GPIO_PORT_E, GPIO_PIN_11, PIN_MAGIC},
+    {39, GPIO_PORT_E, GPIO_PIN_10, PIN_MAGIC},
+    {40, GPIO_PORT_E, GPIO_PIN_9,  PIN_MAGIC},
+    {41, GPIO_PORT_E, GPIO_PIN_8,  PIN_MAGIC},
+    {42, GPIO_PORT_E, GPIO_PIN_7,  PIN_MAGIC},
+    {43, GPIO_PORT_E, GPIO_PIN_6,  PIN_MAGIC},
+    {44, GPIO_PORT_E, GPIO_PIN_5,  PIN_MAGIC},
+    {45, GPIO_PORT_E, GPIO_PIN_4,  PIN_MAGIC},
+    {46, GPIO_PORT_E, GPIO_PIN_3,  PIN_MAGIC},
+    {47, GPIO_PORT_E, GPIO_PIN_2,  PIN_MAGIC},
+    {48, GPIO_PORT_E, GPIO_PIN_1,  PIN_MAGIC},
+    {49, GPIO_PORT_E, GPIO_PIN_0,  PIN_MAGIC},
+    {50, 0, 0, 0},
+    {51, 0, 0, 0},
+    {52, 0, 0, 0},
+    {53, GPIO_PORT_F, GPIO_PIN_5, PIN_MAGIC},
+    {54, GPIO_PORT_F, GPIO_PIN_4, PIN_MAGIC},
+    {55, GPIO_PORT_F, GPIO_PIN_3, PIN_MAGIC},
+    {56, GPIO_PORT_F, GPIO_PIN_2, PIN_MAGIC},
+    {57, GPIO_PORT_F, GPIO_PIN_1, PIN_MAGIC},
+    {58, GPIO_PORT_F, GPIO_PIN_0, PIN_MAGIC},
+    {59, GPIO_PORT_C, GPIO_PIN_0, PIN_MAGIC},
+    {60, GPIO_PORT_C, GPIO_PIN_1, PIN_MAGIC},
+    {61, GPIO_PORT_C, GPIO_PIN_2, PIN_MAGIC},
+    {62, GPIO_PORT_C, GPIO_PIN_3, PIN_MAGIC},
+    {63, GPIO_PORT_A, GPIO_PIN_3, PIN_MAGIC},
+    {64, GPIO_PORT_A, GPIO_PIN_2, PIN_MAGIC},
+    {65, GPIO_PORT_A, GPIO_PIN_1, PIN_MAGIC},
+    {66, GPIO_PORT_A, GPIO_PIN_0, PIN_MAGIC},
+};
+
+static void pin_mode(struct rt_device *dev, rt_base_t pin, rt_base_t mode)
+{
+    if ((pin > PIN_NUM(pin_index)) || (pin_index[pin].magic != PIN_MAGIC))
+    {
+        dbg_log(DBG_ERROR, "pin:%d value wrongful\n", pin);
+        return;
+    }
+
+    gpio_set_func(pin_index[pin].pin_port, pin_index[pin].pin, mode);
+}
+
+static void pin_write(struct rt_device *dev, rt_base_t pin, rt_base_t value)
+{
+    if ((pin > PIN_NUM(pin_index)) || (pin_index[pin].magic != PIN_MAGIC))
+    {
+        dbg_log(DBG_ERROR, "pin:%d value wrongful\n", pin);
+        return;
+    }
+
+    gpio_set_value(pin_index[pin].pin_port, pin_index[pin].pin, value);
+}
+
+static int pin_read(struct rt_device *device, rt_base_t pin)
+{
+    if ((pin > PIN_NUM(pin_index)) || (pin_index[pin].magic != PIN_MAGIC))
+    {
+        dbg_log(DBG_ERROR, "pin:%d value wrongful\n", pin);
+        return 0;
+    }
+
+    return gpio_get_value(pin_index[pin].pin_port, pin_index[pin].pin);
+}
+
+static rt_err_t pin_attach_irq(struct rt_device *device, rt_int32_t pin, rt_uint32_t mode, void (*hdr)(void *args), void *args)
+{
+    if ((pin > PIN_NUM(pin_index)) || (pin_index[pin].magic != PIN_MAGIC))
+    {
+        dbg_log(DBG_ERROR, "pin:%d value wrongful\n", pin);
+        return RT_ERROR;
+    }
+
+    gpio_set_irq_callback(pin_index[pin].pin_port, pin_index[pin].pin, hdr, args);
+    gpio_set_irq_type(pin_index[pin].pin_port, pin_index[pin].pin, mode);
+    return RT_EOK;
+}
+static rt_err_t pin_dettach_irq(struct rt_device *device, rt_int32_t pin)
+{
+    if ((pin > PIN_NUM(pin_index)) || (pin_index[pin].magic != PIN_MAGIC))
+    {
+        dbg_log(DBG_ERROR, "pin:%d value wrongful\n", pin);
+        return RT_ERROR;
+    }
+
+    gpio_clear_irq_callback(pin_index[pin].pin_port, pin_index[pin].pin);
+
+    return RT_EOK;
+}
+
+rt_err_t pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint32_t enabled)
+{
+    if ((pin > PIN_NUM(pin_index)) || (pin_index[pin].magic != PIN_MAGIC))
+    {
+        dbg_log(DBG_ERROR, "pin:%d value wrongful\n", pin);
+        return RT_ERROR;
+    }
+
+    if (enabled)
+        gpio_irq_enable(pin_index[pin].pin_port, pin_index[pin].pin);
+    else
+        gpio_irq_disable(pin_index[pin].pin_port, pin_index[pin].pin);
+
+    return RT_EOK;
+}
+
+/*
+ID GPIO   ID GPIO    ID GPIO    ID GPIO    ID GPIO   ID GPIO   ID GPIO
+6  PD0    13 PD7     21 PD14    29 PD21    43 PE6    53 PF5    60 PC1
+7  PD1    14 PD8     23 PD15    37 PE12    44 PE5    54 PF4    61 PC2
+8  PD2    15 PD9     24 PD16    38 PE11    45 PE4    55 PF3    62 PC3
+9  PD3    16 PD10    25 PD17    39 PE10    46 PE3    56 PF2    63 PA3
+10 PD4    17 PD11    26 PD18    40 PE9     47 PE2    57 PF1    64 PA2
+11 PD5    18 PD12    27 PD19    41 PE8     48 PE1    58 PF0    65 PA1
+12 PD6    19 PD13    28 PD20    42 PE7     49 PE0    59 PC0    66 PA0
+*/
+
+static const struct rt_pin_ops ops =
+{
+    pin_mode,
+    pin_write,
+    pin_read,
+    pin_attach_irq,
+    pin_dettach_irq,
+    pin_irq_enable,
+};
+#endif
+
+int rt_hw_gpio_init(void)
+{
+#ifdef RT_USING_PIN
+    rt_device_pin_register("gpio", &ops, RT_NULL);
+#endif
+    /* install ISR */
+    rt_hw_interrupt_install(PIOD_INTERRUPT, gpio_irq_handler, &_g_gpio_irq_tbl[GPIO_PORT_D], "gpiod_irq");
+    rt_hw_interrupt_umask(PIOD_INTERRUPT);
+
+    rt_hw_interrupt_install(PIOE_INTERRUPT, gpio_irq_handler, &_g_gpio_irq_tbl[GPIO_PORT_E], "gpioe_irq");
+    rt_hw_interrupt_umask(PIOE_INTERRUPT);
+
+    rt_hw_interrupt_install(PIOF_INTERRUPT, gpio_irq_handler, &_g_gpio_irq_tbl[GPIO_PORT_F], "gpiof_irq");
+    rt_hw_interrupt_umask(PIOF_INTERRUPT);
+
+    return 0;
+}
+INIT_DEVICE_EXPORT(rt_hw_gpio_init);

+ 244 - 0
bsp/allwinner_tina/drivers/drv_gpio.h

@@ -0,0 +1,244 @@
+/*
+ * File      : drv_gpio.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2017, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2018-02-08     RT-Thread    the first version
+ */
+#ifndef __DRV_GPIO_H__
+#define __DRV_GPIO_H__
+
+/* IO default function */
+#define IO_INPUT         (0x00)
+#define IO_OUTPUT        (0x01)
+#define IO_DISABLE       (0x07)
+
+#define IO_FUN_1         (0x02)
+#define IO_FUN_2         (0x03)
+#define IO_FUN_3         (0x04)
+#define IO_FUN_4         (0x05)
+#define IO_FUN_5         (0x06)
+
+/* IO port */
+enum gpio_port
+{
+    GPIO_PORT_A = 0,
+    GPIO_PORT_B,
+    GPIO_PORT_C,
+    GPIO_PORT_D,
+    GPIO_PORT_E,
+    GPIO_PORT_F,
+    GPIO_PORT_NUM,
+};
+
+/* IO pin */
+enum gpio_pin
+{
+    GPIO_PIN_0 = 0,
+    GPIO_PIN_1,
+    GPIO_PIN_2,
+    GPIO_PIN_3,
+    GPIO_PIN_4,
+    GPIO_PIN_5,
+    GPIO_PIN_6,
+    GPIO_PIN_7,
+    GPIO_PIN_8,
+    GPIO_PIN_9,
+    GPIO_PIN_10,
+    GPIO_PIN_11,
+    GPIO_PIN_12,
+    GPIO_PIN_13,
+    GPIO_PIN_14,
+    GPIO_PIN_15,
+    GPIO_PIN_16,
+    GPIO_PIN_17,
+    GPIO_PIN_18,
+    GPIO_PIN_19,
+    GPIO_PIN_20,
+    GPIO_PIN_21,
+    GPIO_PIN_22,
+    GPIO_PIN_23,
+    GPIO_PIN_NUM,
+};
+
+/* Drive level */
+enum gpio_drv_level
+{
+    DRV_LEVEL_0 = 0,
+    DRV_LEVEL_1,
+    DRV_LEVEL_2,
+    DRV_LEVEL_3,
+};
+
+/* Pull mode */
+enum gpio_pull
+{
+    PULL_DISABLE = 0,
+    PULL_UP,
+    PULL_DOWN,
+};
+
+/* interrupt type */
+enum gpio_irq_type
+{
+    POSITIVE = 0,
+    NEGATIVE,
+    HIGH,
+    LOW,
+    DOUBLE,
+};
+
+enum gpio_irq_clock
+{
+    GPIO_IRQ_LOSC_32KHZ = 0,
+    GPIO_IRQ_HOSC_24MHZ
+};
+
+enum gpio_direction_type
+{
+    DEBOUNCE_PRE_SCALE_1 = 0,
+    DEBOUNCE_PRE_SCALE_2,
+    DEBOUNCE_PRE_SCALE_4,
+    DEBOUNCE_PRE_SCALE_8,
+    DEBOUNCE_PRE_SCALE_16,
+    DEBOUNCE_PRE_SCALE_32,
+    DEBOUNCE_PRE_SCALE_64,
+    DEBOUNCE_PRE_SCALE_128,
+};
+
+struct gpio_irq_def
+{
+    void    *irq_arg[32];
+    void (*irq_cb[32])(void *param);
+};
+
+#define GPIO_BASE_ADDR           (0x01C20800)
+#define GPIOn_CFG_ADDR(n)        (GPIO_BASE_ADDR + (n) * 0x24 + 0x00)
+#define GPIOn_DATA_ADDR(n)       (GPIO_BASE_ADDR + (n) * 0x24 + 0x10)
+#define GPIOn_DRV_ADDR(n)        (GPIO_BASE_ADDR + (n) * 0x24 + 0x14)
+#define GPIOn_PUL_ADDR(n)        (GPIO_BASE_ADDR + (n) * 0x24 + 0x1C)
+#define GPIOn_INT_CFG_ADDR(n)    (GPIO_BASE_ADDR + 0x200 + (n) * 0x20 + 0x00)
+#define GPIOn_INT_CTRL_ADDR(n)   (GPIO_BASE_ADDR + 0x200 + (n) * 0x20 + 0x10)
+#define GPIOn_INT_STA_ADDR(n)    (GPIO_BASE_ADDR + 0x200 + (n) * 0x20 + 0x14)
+#define GPIOn_INT_DEB_ADDR(n)    (GPIO_BASE_ADDR + 0x200 + (n) * 0x20 + 0x18)
+
+struct tina_gpio
+{
+    volatile rt_uint32_t pa_cfg0;        /* 0x00 */
+    volatile rt_uint32_t pa_cfg1;        /* 0x04 */
+    volatile rt_uint32_t pa_cfg2;        /* 0x08 */
+    volatile rt_uint32_t pa_cfg3;        /* 0x0C */
+    volatile rt_uint32_t pa_data;        /* 0x10 */
+    volatile rt_uint32_t pa_drv0;        /* 0x14 */
+    volatile rt_uint32_t pa_drv1;        /* 0x18 */
+    volatile rt_uint32_t pa_pul0;        /* 0x1C */
+    volatile rt_uint32_t pa_pul1;        /* 0x20 */
+    volatile rt_uint32_t pb_cfg0;        /* 0x24 */
+    volatile rt_uint32_t pb_cfg1;        /* 0x28 */
+    volatile rt_uint32_t pb_cfg2;        /* 0x2C */
+    volatile rt_uint32_t pb_cfg3;        /* 0x30 */
+    volatile rt_uint32_t pb_data;        /* 0x34 */
+    volatile rt_uint32_t pb_drv0;        /* 0x38 */
+    volatile rt_uint32_t pb_drv1;        /* 0x3C */
+    volatile rt_uint32_t pb_pul0;        /* 0x40 */
+    volatile rt_uint32_t pb_pul1;        /* 0x44 */
+    volatile rt_uint32_t pc_cfg0;        /* 0x48 */
+    volatile rt_uint32_t pc_cfg1;        /* 0x4C */
+    volatile rt_uint32_t pc_cfg2;        /* 0x50 */
+    volatile rt_uint32_t pc_cfg3;        /* 0x54 */
+    volatile rt_uint32_t pc_data;        /* 0x58 */
+    volatile rt_uint32_t pc_drv0;        /* 0x5C */
+    volatile rt_uint32_t pc_drv1;        /* 0x60 */
+    volatile rt_uint32_t pc_pul0;        /* 0x64 */
+    volatile rt_uint32_t pc_pul1;        /* 0x68 */
+    volatile rt_uint32_t pd_cfg0;        /* 0x6C */
+    volatile rt_uint32_t pd_cfg1;        /* 0x70 */
+    volatile rt_uint32_t pd_cfg2;        /* 0x74 */
+    volatile rt_uint32_t pd_cfg3;        /* 0x78 */
+    volatile rt_uint32_t pd_data;        /* 0x7C */
+    volatile rt_uint32_t pd_drv0;        /* 0x80 */
+    volatile rt_uint32_t pd_drv1;        /* 0x84 */
+    volatile rt_uint32_t pd_pul0;        /* 0x88 */
+    volatile rt_uint32_t pd_pul1;        /* 0x8C */
+    volatile rt_uint32_t pe_cfg0;        /* 0x90 */
+    volatile rt_uint32_t pe_cfg1;        /* 0x94 */
+    volatile rt_uint32_t pe_cfg2;        /* 0x98 */
+    volatile rt_uint32_t pe_cfg3;        /* 0x9C */
+    volatile rt_uint32_t pe_data;        /* 0xA0 */
+    volatile rt_uint32_t pe_drv0;        /* 0xA4 */
+    volatile rt_uint32_t pe_drv1;        /* 0xA8 */
+    volatile rt_uint32_t pe_pul0;        /* 0xAC */
+    volatile rt_uint32_t pe_pul1;        /* 0xB0 */
+    volatile rt_uint32_t pf_cfg0;        /* 0xB4 */
+    volatile rt_uint32_t pf_cfg1;        /* 0xB8 */
+    volatile rt_uint32_t pf_cfg2;        /* 0xBC */
+    volatile rt_uint32_t pf_cfg3;        /* 0xC0 */
+    volatile rt_uint32_t pf_data;        /* 0xC4 */
+    volatile rt_uint32_t pf_drv0;        /* 0xC8 */
+    volatile rt_uint32_t pf_drv1;        /* 0xCC */
+    volatile rt_uint32_t pf_pul0;        /* 0xD0 */
+    volatile rt_uint32_t reserved0[76];
+    volatile rt_uint32_t pd_int_cfg0;    /* 0x200 */
+    volatile rt_uint32_t pd_int_cfg1;    /* 0x204 */
+    volatile rt_uint32_t pd_int_cfg2;    /* 0x208 */
+    volatile rt_uint32_t pd_int_cfg3;    /* 0x20C */
+    volatile rt_uint32_t pd_int_ctrl;    /* 0x210 */
+    volatile rt_uint32_t pd_int_sta;     /* 0x214 */
+    volatile rt_uint32_t pd_int_deb;     /* 0x218 */
+    volatile rt_uint32_t reserved1;
+    volatile rt_uint32_t pe_int_cfg0;    /* 0x220 */
+    volatile rt_uint32_t pe_int_cfg1;    /* 0x224 */
+    volatile rt_uint32_t pe_int_cfg2;    /* 0x228 */
+    volatile rt_uint32_t pe_int_cfg3;    /* 0x22C */
+    volatile rt_uint32_t pe_int_ctrl;    /* 0x230 */
+    volatile rt_uint32_t pe_int_sta;     /* 0x234 */
+    volatile rt_uint32_t pe_int_deb;     /* 0x238 */
+    volatile rt_uint32_t reserved2;
+    volatile rt_uint32_t pf_int_cfg0;    /* 0x240 */
+    volatile rt_uint32_t pf_int_cfg1;    /* 0x244 */
+    volatile rt_uint32_t pf_int_cfg2;    /* 0x248 */
+    volatile rt_uint32_t pf_int_cfg3;    /* 0x24C */
+    volatile rt_uint32_t pf_int_ctrl;    /* 0x250 */
+    volatile rt_uint32_t pf_int_sta;     /* 0x254 */
+    volatile rt_uint32_t pf_int_deb;     /* 0x258 */
+    volatile rt_uint32_t reserved3[26];
+    volatile rt_uint32_t sdr_pad_drv;    /* 0x2C0*/
+    volatile rt_uint32_t sdr_pad_pul;    /* 0x2C4 */
+};
+
+typedef struct tina_gpio *tina_gpio_t;
+
+#define GPIO ((tina_gpio_t)GPIO_BASE_ADDR)
+
+int gpio_set_func(enum gpio_port port, enum gpio_pin pin, rt_uint8_t func);
+int gpio_set_value(enum gpio_port port, enum gpio_pin pin, rt_uint8_t value);
+int gpio_get_value(enum gpio_port port, enum gpio_pin pin);
+int gpio_set_pull_mode(enum gpio_port port,  enum gpio_pin pin, enum gpio_pull pull);
+int gpio_set_drive_level(enum gpio_port port, enum gpio_pin pin, enum gpio_drv_level level);
+void gpio_direction_input(enum gpio_port port,  enum gpio_pin pin);
+void gpio_direction_output(enum gpio_port port, enum gpio_pin pin, int value);
+void gpio_irq_enable(enum gpio_port port,  enum gpio_pin pin);
+void gpio_irq_disable(enum gpio_port port,  enum gpio_pin pin);
+void gpio_set_irq_type(enum gpio_port port,  enum gpio_pin pin, enum gpio_irq_type irq_type);
+void gpio_select_irq_clock(enum gpio_port port, enum gpio_irq_clock clock);
+void gpio_set_debounce(enum gpio_port port, rt_uint8_t prescaler);
+void gpio_set_irq_callback(enum gpio_port port, enum gpio_pin pin, void (*irq_cb)(void *), void *irq_arg);
+int rt_hw_gpio_init(void);
+
+#endif /* __DRV_GPIO_H__ */

+ 327 - 0
bsp/allwinner_tina/drivers/drv_uart.c

@@ -0,0 +1,327 @@
+/*
+ * File      : drv_uart.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2017, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2018-02-08     RT-Thread    the first version
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+#include <rtdevice.h>
+
+#include "drv_uart.h"
+#include "interrupt.h"
+
+#include "drv_gpio.h"
+#include "drv_clock.h"
+
+#define readl(addr)           (*(volatile unsigned int *)(addr))
+#define writel(value,addr)    (*(volatile unsigned int *)(addr) = (value))
+
+#ifdef RT_USING_SERIAL
+
+struct device_uart
+{
+    rt_uint32_t hw_base;
+    rt_uint32_t irqno;
+    char name[RT_NAME_MAX];
+    rt_uint32_t gpio_rx_port;
+    rt_uint32_t gpio_tx_port;
+    rt_uint32_t gpio_rx_pin;
+    rt_uint32_t gpio_tx_pin;
+    rt_uint32_t gpio_rx_fun;
+    rt_uint32_t gpio_tx_fun;
+};
+
+static rt_err_t uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg);
+static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *arg);
+static int      uart_putc(struct rt_serial_device *serial, char c);
+static int      uart_getc(struct rt_serial_device *serial);
+static rt_size_t uart_dma_transmit(struct rt_serial_device *serial, rt_uint8_t *buf, rt_size_t size, int direction);
+
+void     uart_irq_handler(int irqno, void *param);
+
+const struct rt_uart_ops _uart_ops =
+{
+    uart_configure,
+    uart_control,
+    uart_putc,
+    uart_getc,
+    uart_dma_transmit
+};
+
+/*
+ * UART Initiation
+ */
+int rt_hw_uart_init(void)
+{
+    struct rt_serial_device *serial;
+    struct device_uart      *uart;
+    struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
+
+#ifdef TINA_USING_UART0
+    {
+        static struct rt_serial_device  serial0;
+        static struct device_uart       uart0;
+
+        serial  = &serial0;
+        uart    = &uart0;
+
+        serial->ops              = &_uart_ops;
+        serial->config           = config;
+        serial->config.baud_rate = 115200;
+
+        uart->hw_base      = UART0_BASE_ADDR; // UART0_BASE;
+        uart->irqno        = UART0_INTERRUPT; // IRQ_UART0;
+        uart->gpio_rx_port = GPIO_PORT_E;
+        uart->gpio_tx_port = GPIO_PORT_E;
+        uart->gpio_rx_pin  = GPIO_PIN_0;
+        uart->gpio_tx_pin  = GPIO_PIN_1;
+        uart->gpio_rx_fun  = IO_FUN_4;
+        uart->gpio_tx_fun  = IO_FUN_4;
+
+        rt_hw_serial_register(serial,
+                              "uart0",
+                              RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
+                              uart);
+    }
+#endif
+
+#ifdef TINA_USING_UART1
+    {
+        static struct rt_serial_device  serial1;
+        static struct device_uart       uart1;
+
+        serial  = &serial1;
+        uart    = &uart1;
+
+        serial->ops              = &_uart_ops;
+        serial->config           = config;
+        serial->config.baud_rate = 115200;
+
+        uart->hw_base      = UART1_BASE_ADDR; // UART1_BASE;
+        uart->irqno        = UART1_INTERRUPT; // IRQ_UART1;
+        uart->gpio_rx_port = GPIO_PORT_A;
+        uart->gpio_tx_port = GPIO_PORT_A;
+        uart->gpio_rx_pin  = GPIO_PIN_3;
+        uart->gpio_tx_pin  = GPIO_PIN_2;
+        uart->gpio_rx_fun  = IO_FUN_4;
+        uart->gpio_tx_fun  = IO_FUN_4;
+
+        rt_hw_serial_register(serial,
+                              "uart1",
+                              RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
+                              uart);
+    }
+#endif
+
+#ifdef TINA_USING_UART2
+    {
+        static struct rt_serial_device  serial2;
+        static struct device_uart       uart2;
+
+        serial  = &serial2;
+        uart    = &uart2;
+
+        serial->ops              = &_uart_ops;
+        serial->config           = config;
+        serial->config.baud_rate = 115200;
+
+        uart->hw_base      = UART2_BASE_ADDR; // UART1_BASE;
+        uart->irqno        = UART2_INTERRUPT; // IRQ_UART1;
+        uart->gpio_rx_port = GPIO_PORT_E;
+        uart->gpio_tx_port = GPIO_PORT_E;
+        uart->gpio_rx_pin  = GPIO_PIN_8;
+        uart->gpio_tx_pin  = GPIO_PIN_7;
+        uart->gpio_rx_fun  = IO_FUN_2;
+        uart->gpio_tx_fun  = IO_FUN_2;
+
+        rt_hw_serial_register(serial,
+                              "uart2",
+                              RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
+                              uart);
+    }
+#endif
+
+    return 0;
+}
+
+/*
+ * UART interface
+ */
+static rt_err_t uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
+{
+    rt_uint32_t addr, val;
+    struct device_uart *uart;
+
+    RT_ASSERT(serial != RT_NULL);
+    serial->config = *cfg;
+
+    uart = serial->parent.user_data;
+    RT_ASSERT(uart != RT_NULL);
+    /* config gpio port */
+    gpio_set_func(uart->gpio_rx_port, uart->gpio_rx_pin, uart->gpio_rx_fun);
+    gpio_set_func(uart->gpio_tx_port, uart->gpio_tx_pin, uart->gpio_tx_fun);
+    /* Enable UART clock */
+    /* Open the clock gate for uart */
+    if ((rt_uint32_t)(uart->hw_base) == UART0_BASE_ADDR)
+    {
+        bus_gate_clk_enalbe(UART0_GATING);
+        bus_software_reset_enalbe(UART0_GATING);
+        bus_software_reset_disalbe(UART0_GATING);
+    }
+    else if ((rt_uint32_t)(uart->hw_base) == UART1_BASE_ADDR)
+    {
+        bus_gate_clk_enalbe(UART1_GATING);
+        bus_software_reset_enalbe(UART1_GATING);
+        bus_software_reset_disalbe(UART1_GATING);
+    }
+    else if ((rt_uint32_t)(uart->hw_base) == UART2_BASE_ADDR)
+    {
+        bus_gate_clk_enalbe(UART2_GATING);
+        bus_software_reset_enalbe(UART2_GATING);
+        bus_software_reset_disalbe(UART2_GATING);
+    }
+    else
+        RT_ASSERT(0);
+    /* Config uart0 to 115200-8-1-0 */
+    addr = uart->hw_base;
+    /* close uart irq */
+    writel(0x0, addr + UART_IER);
+    /* config fifo */
+    writel(0x37, addr + UART_FCR);
+    /* config modem */
+    writel(0x0, addr + UART_MCR);
+    /* config baud */
+    val = readl(addr + UART_LCR);
+    val |= (1 << 7);
+    writel(val, addr + UART_LCR);
+    val = apb_get_clk() / 16 / serial->config.baud_rate;
+    writel(val & 0xff, addr + UART_DLL);
+    writel((val >> 8) & 0xff, addr + UART_DLH);
+    val = readl(addr + UART_LCR);
+    val &= ~(1 << 7);
+    writel(val, addr + UART_LCR);
+
+    val = readl(addr + UART_LCR);
+    val &= ~0x1f;
+    val |= ((serial->config.data_bits - DATA_BITS_5) << 0) | (0 << 2) | (0x0 << 3);
+    writel(val, addr + UART_LCR);
+
+    writel(0xf, addr + UART_TFL);
+    writel(0x3F, addr + UART_RFL);
+
+    writel(0x1, addr + UART_IER);
+    return RT_EOK;
+}
+
+static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *arg)
+{
+    struct device_uart *uart;
+
+    uart = serial->parent.user_data;
+
+    RT_ASSERT(uart != RT_NULL);
+
+    switch (cmd)
+    {
+    case RT_DEVICE_CTRL_CLR_INT:
+        /* Disable the UART Interrupt */
+        rt_hw_interrupt_mask(uart->irqno);
+        writel(0x00, uart->hw_base + UART_IER);
+        break;
+
+    case RT_DEVICE_CTRL_SET_INT:
+        /* install interrupt */
+        rt_hw_interrupt_install(uart->irqno, uart_irq_handler,
+                                serial, uart->name);
+        rt_hw_interrupt_umask(uart->irqno);
+        writel(0x01, uart->hw_base + UART_IER);
+        /* Enable the UART Interrupt */
+        break;
+    }
+
+    return (RT_EOK);
+}
+
+
+static int uart_putc(struct rt_serial_device *serial, char c)
+{
+    struct device_uart *uart;
+    volatile rt_uint32_t *sed_buf;
+    volatile rt_uint32_t *sta;
+
+    uart = serial->parent.user_data;
+    sed_buf = (rt_uint32_t *)(uart->hw_base + UART_THR);
+    sta = (rt_uint32_t *)(uart->hw_base + UART_USR);
+    /* FIFO status, contain valid data */
+    while (!(*sta & 0x02));
+    *sed_buf = c;
+
+    return (1);
+}
+
+static int uart_getc(struct rt_serial_device *serial)
+{
+    int ch = -1;
+    volatile rt_uint32_t *rec_buf;
+    volatile rt_uint32_t *sta;
+    struct device_uart *uart = serial->parent.user_data;
+
+    RT_ASSERT(serial != RT_NULL);
+
+    rec_buf = (rt_uint32_t *)(uart->hw_base + UART_RHB);
+    sta = (rt_uint32_t *)(uart->hw_base + UART_USR);
+    /* Receive Data Available */
+    if (*sta & 0x08)
+    {
+        ch = *rec_buf & 0xff;
+    }
+
+    return ch;
+}
+
+static rt_size_t uart_dma_transmit(struct rt_serial_device *serial, rt_uint8_t *buf, rt_size_t size, int direction)
+{
+    return (0);
+}
+
+/* UART ISR */
+void uart_irq_handler(int irqno, void *param)
+{
+    rt_uint32_t val;
+    struct rt_serial_device *serial = (struct rt_serial_device *)param;
+    struct device_uart *uart = serial->parent.user_data;
+
+    val = readl(uart->hw_base + 0x08) & 0x0F;
+    /* read interrupt status and clear it */
+    if (val & 0x4) /* rx ind */
+    {
+        rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
+    }
+
+    if (0) /* tx done */
+    {
+        rt_hw_serial_isr(serial, RT_SERIAL_EVENT_TX_DONE);
+    }
+
+}
+
+#endif

+ 83 - 0
bsp/allwinner_tina/drivers/drv_uart.h

@@ -0,0 +1,83 @@
+/*
+ * File      : drv_uart.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2017, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2018-02-08     RT-Thread    the first version
+ */
+
+
+#ifndef __DRV_UART_H__
+#define __DRV_UART_H__
+
+#define UART0_BASE_ADDR (0x01C25000)
+#define UART1_BASE_ADDR (0x01C25400)
+#define UART2_BASE_ADDR (0x01C25800)
+
+#define UART_THR        (0X00)
+#define UART_RHB        (0X00)
+#define UART_DLL        (0X00)
+#define UART_DLH        (0X04)
+#define UART_IER        (0X04)
+#define UART_IIR        (0X08)
+#define UART_FCR        (0X08)
+#define UART_LCR        (0X0C)
+#define UART_MCR        (0X10)
+#define UART_LSR        (0X14)
+#define UART_MSR        (0X18)
+#define UART_SCH        (0X1C)
+#define UART_USR        (0X7C)
+#define UART_TFL        (0X80)
+#define UART_RFL        (0X84)
+#define UART_HSK        (0X88)
+#define UART_HALT       (0XA4)
+#define UART_DBG_DLL    (0XB0)
+#define UART_DBG_DLH    (0XB4)
+
+struct tina_uart
+{
+    volatile rt_uint32_t rx_tx_dll;          /* 0x00 */
+    volatile rt_uint32_t dlh_ier;           /* 0x04 */
+    volatile rt_uint32_t iir_fcr;           /* 0x08 */
+    volatile rt_uint32_t lcr;               /* 0x0C */
+    volatile rt_uint32_t mcr;               /* 0x10 */
+    volatile rt_uint32_t lsr;               /* 0x14 */
+    volatile rt_uint32_t msr;               /* 0x18 */
+    volatile rt_uint32_t sch;               /* 0x1C */
+    volatile rt_uint32_t reserved0[23];
+    volatile rt_uint32_t usr;               /* 0x7c */
+    volatile rt_uint32_t tfl;               /* 0x80 */
+    volatile rt_uint32_t rfl;               /* 0x84 */
+    volatile rt_uint32_t hsk;               /* 0x88 */
+    volatile rt_uint32_t reserved1[6];
+    volatile rt_uint32_t halt;              /* 0xa4 */
+    volatile rt_uint32_t reserved2[2];
+    volatile rt_uint32_t dbg_dll;           /* 0xb0 */
+    volatile rt_uint32_t dbg_dlh;           /* 0xb4 */
+};
+
+typedef struct tina_uart *tina_uart_t;
+
+#define UART0 ((tina_uart_t)UART0_BASE_ADDR)
+#define UART1 ((tina_uart_t)UART1_BASE_ADDR)
+#define UART2 ((tina_uart_t)UART2_BASE_ADDR)
+
+int rt_hw_uart_init(void);
+
+#endif /* __DRV_UART_H__ */

+ 13 - 0
bsp/allwinner_tina/libcpu/SConscript

@@ -0,0 +1,13 @@
+Import('rtconfig')
+from building import *
+
+cwd     = GetCurrentDir()
+src     = Glob('*.c')
+CPPPATH = [cwd]
+
+if rtconfig.PLATFORM == 'gcc':
+    src += Glob('*_gcc.S')
+
+group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')

+ 92 - 0
bsp/allwinner_tina/libcpu/context_gcc.S

@@ -0,0 +1,92 @@
+;/*
+; * File      : context_iar.S
+; * This file is part of RT-Thread RTOS
+; * COPYRIGHT (C) 2006, RT-Thread Development Team
+; *
+; *  This program is free software; you can redistribute it and/or modify
+; *  it under the terms of the GNU General Public License as published by
+; *  the Free Software Foundation; either version 2 of the License, or
+; *  (at your option) any later version.
+; *
+; *  This program is distributed in the hope that it will be useful,
+; *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+; *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+; *  GNU General Public License for more details.
+; *
+; *  You should have received a copy of the GNU General Public License along
+; *  with this program; if not, write to the Free Software Foundation, Inc.,
+; *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+; *
+; * Change Logs:
+; * Date           Author       Notes
+; * 2011-08-14     weety    copy from mini2440
+; */
+
+#define NOINT   0xC0
+
+;/*
+; * rt_base_t rt_hw_interrupt_disable();
+; */
+    .globl rt_hw_interrupt_disable
+rt_hw_interrupt_disable:
+    MRS     R0, CPSR
+    ORR     R1, R0, #NOINT
+    MSR     CPSR_c, R1
+    BX      LR
+
+/*
+ * void rt_hw_interrupt_enable(rt_base_t level);
+ */
+    .globl rt_hw_interrupt_enable
+rt_hw_interrupt_enable:
+    MSR     CPSR, R0
+    BX      LR
+
+/*
+ * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
+ * r0 --> from
+ * r1 --> to
+ */
+    .globl rt_hw_context_switch
+rt_hw_context_switch:
+    STMFD   SP!, {LR}           @; push pc (lr should be pushed in place of pc)
+    STMFD   SP!, {R0-R12, LR}       @; push lr & register file
+    MRS     R4, CPSR
+    STMFD   SP!, {R4}               @; push cpsr
+    STR     SP, [R0]                @; store sp in preempted tasks tcb
+    LDR     SP, [R1]                @; get new task stack pointer
+    LDMFD   SP!, {R4}               @; pop new task spsr
+    MSR     SPSR_cxsf, R4
+    LDMFD   SP!, {R0-R12, LR, PC}^  @; pop new task r0-r12, lr & pc
+
+/*
+ * void rt_hw_context_switch_to(rt_uint32 to);
+ * r0 --> to
+ */
+    .globl rt_hw_context_switch_to
+rt_hw_context_switch_to:
+    LDR     SP, [R0]                @; get new task stack pointer
+    LDMFD   SP!, {R4}               @; pop new task cpsr
+    MSR     SPSR_cxsf, R4
+    LDMFD   SP!, {R0-R12, LR, PC}^  @; pop new task r0-r12, lr & pc
+
+/*
+ * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to);
+ */
+    .globl rt_thread_switch_interrupt_flag
+    .globl rt_interrupt_from_thread
+    .globl rt_interrupt_to_thread
+    .globl rt_hw_context_switch_interrupt
+rt_hw_context_switch_interrupt:
+    LDR     R2, =rt_thread_switch_interrupt_flag
+    LDR     R3, [R2]
+    CMP     R3, #1
+    BEQ     _reswitch
+    MOV     R3, #1                          @; set flag to 1
+    STR     R3, [R2]
+    LDR     R2, =rt_interrupt_from_thread   @; set rt_interrupt_from_thread
+    STR     R0, [R2]
+_reswitch:
+    LDR     R2, =rt_interrupt_to_thread     @; set rt_interrupt_to_thread
+    STR     R1, [R2]
+    BX      LR

+ 41 - 0
bsp/allwinner_tina/libcpu/cpu.c

@@ -0,0 +1,41 @@
+/*
+ * File      : cpu.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2017, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2018-02-08     RT-Thread    the first version
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+
+RT_WEAK void machine_reset(void)
+{
+    rt_kprintf("reboot system...\n");
+    rt_hw_interrupt_disable();
+    while (1);
+}
+
+RT_WEAK void machine_shutdown(void)
+{
+    rt_kprintf("shutdown...\n");
+    rt_hw_interrupt_disable();
+    while (1);
+}
+

+ 229 - 0
bsp/allwinner_tina/libcpu/cpuport.c

@@ -0,0 +1,229 @@
+/*
+ * File      : cpuport.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2017, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2018-02-08     RT-Thread    the first version
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+
+#define ICACHE_MASK    (rt_uint32_t)(1 << 12)
+#define DCACHE_MASK    (rt_uint32_t)(1 << 2)
+
+extern void machine_reset(void);
+extern void machine_shutdown(void);
+
+#if defined(__GNUC__) || defined(__ICCARM__)
+rt_inline rt_uint32_t cp15_rd(void)
+{
+    rt_uint32_t i;
+
+    __asm volatile("mrc p15, 0, %0, c1, c0, 0":"=r"(i));
+    return i;
+}
+
+rt_inline void cache_enable(rt_uint32_t bit)
+{
+    __asm volatile(\
+                   "mrc  p15,0,r0,c1,c0,0\n\t"    \
+                   "orr  r0,r0,%0\n\t"            \
+                   "mcr  p15,0,r0,c1,c0,0"        \
+                   :                              \
+                   : "r"(bit)                     \
+                   : "memory");
+}
+
+rt_inline void cache_disable(rt_uint32_t bit)
+{
+    __asm volatile(\
+                   "mrc  p15,0,r0,c1,c0,0\n\t"    \
+                   "bic  r0,r0,%0\n\t"            \
+                   "mcr  p15,0,r0,c1,c0,0"        \
+                   :                              \
+                   : "r"(bit)                     \
+                   : "memory");
+}
+#endif
+
+#if defined(__CC_ARM)
+rt_inline rt_uint32_t cp15_rd(void)
+{
+    rt_uint32_t i;
+
+    __asm volatile
+    {
+        mrc p15, 0, i, c1, c0, 0
+    }
+
+    return i;
+}
+
+rt_inline void cache_enable(rt_uint32_t bit)
+{
+    rt_uint32_t value;
+
+    __asm volatile
+    {
+        mrc p15, 0, value, c1, c0, 0
+        orr value, value, bit
+        mcr p15, 0, value, c1, c0, 0
+    }
+}
+
+rt_inline void cache_disable(rt_uint32_t bit)
+{
+    rt_uint32_t value;
+
+    __asm volatile
+    {
+        mrc p15, 0, value, c1, c0, 0
+        bic value, value, bit
+        mcr p15, 0, value, c1, c0, 0
+    }
+}
+#endif
+
+/**
+ * enable I-Cache
+ *
+ */
+void rt_hw_cpu_icache_enable()
+{
+    cache_enable(ICACHE_MASK);
+}
+
+/**
+ * disable I-Cache
+ *
+ */
+void rt_hw_cpu_icache_disable()
+{
+    cache_disable(ICACHE_MASK);
+}
+
+/**
+ * return the status of I-Cache
+ *
+ */
+rt_base_t rt_hw_cpu_icache_status()
+{
+    return (cp15_rd() & ICACHE_MASK);
+}
+
+/**
+ * enable D-Cache
+ *
+ */
+void rt_hw_cpu_dcache_enable()
+{
+    cache_enable(DCACHE_MASK);
+}
+
+/**
+ * disable D-Cache
+ *
+ */
+void rt_hw_cpu_dcache_disable()
+{
+    cache_disable(DCACHE_MASK);
+}
+
+/**
+ * return the status of D-Cache
+ *
+ */
+rt_base_t rt_hw_cpu_dcache_status()
+{
+    return (cp15_rd() & DCACHE_MASK);
+}
+
+/**
+ * reset cpu by dog's time-out
+ *
+ */
+void rt_hw_cpu_reset()
+{
+
+    rt_kprintf("Restarting system...\n");
+    machine_reset();
+
+    while (1);   /* loop forever and wait for reset to happen */
+
+    /* NEVER REACHED */
+}
+
+/**
+ *  shutdown CPU
+ *
+ */
+void rt_hw_cpu_shutdown()
+{
+    rt_uint32_t level;
+    rt_kprintf("shutdown...\n");
+
+    level = rt_hw_interrupt_disable();
+    machine_shutdown();
+    while (level)
+    {
+        RT_ASSERT(0);
+    }
+}
+
+#ifdef RT_USING_CPU_FFS
+/**
+ * This function finds the first bit set (beginning with the least significant bit)
+ * in value and return the index of that bit.
+ *
+ * Bits are numbered starting at 1 (the least significant bit).  A return value of
+ * zero from any of these functions means that the argument was zero.
+ *
+ * @return return the index of the first bit set. If value is 0, then this function
+ * shall return 0.
+ */
+#if defined(__CC_ARM)
+int __rt_ffs(int value)
+{
+    register rt_uint32_t x;
+
+    if (value == 0)
+        return value;
+
+    __asm
+    {
+        rsb x, value, #0
+        and x, x, value
+        clz x, x
+        rsb x, x, #32
+    }
+
+    return x;
+}
+#elif defined(__GNUC__) || defined(__ICCARM__)
+int __rt_ffs(int value)
+{
+    return __builtin_ffs(value);
+}
+#endif
+
+#endif
+
+
+/*@}*/

+ 206 - 0
bsp/allwinner_tina/libcpu/interrupt.c

@@ -0,0 +1,206 @@
+/*
+ * File      : interrupt.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2017, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2018-02-08     RT-Thread    the first version
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+
+#include "interrupt.h"
+
+extern rt_uint32_t rt_interrupt_nest;
+rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
+rt_uint32_t rt_thread_switch_interrupt_flag;
+
+static struct rt_irq_desc isr_table[INTERRUPTS_MAX];
+
+static void rt_hw_interrupt_handler(int vector, void *param)
+{
+    rt_kprintf("Unhandled interrupt %d occured!!!\n", vector);
+}
+
+#define readl(addr)           (*(volatile unsigned int *)(addr))
+#define writel(value,addr)    (*(volatile unsigned int *)(addr) = (value))
+
+/**
+ * This function will initialize hardware interrupt
+ */
+void rt_hw_interrupt_init(void)
+{
+    rt_int32_t idx;
+
+    rt_memset(isr_table, 0x00, sizeof(isr_table));
+    for (idx = 0; idx < INTERRUPTS_MAX; idx ++)
+    {
+        isr_table[idx].handler = rt_hw_interrupt_handler;
+    }
+
+    /* init interrupt nest, and context in thread sp */
+    rt_interrupt_nest               = 0;
+    rt_interrupt_from_thread        = 0;
+    rt_interrupt_to_thread          = 0;
+    rt_thread_switch_interrupt_flag = 0;
+
+    /* set base_addr reg */
+    INTC->base_addr_reg = 0x00000000;
+    /* clear enable */
+    INTC->en_reg0 = 0x00000000;
+    INTC->en_reg1 = 0x00000000;
+    /* mask interrupt */
+    INTC->mask_reg0 = 0xFFFFFFFF;
+    INTC->mask_reg1 = 0xFFFFFFFF;
+    /* clear pending */
+    INTC->pend_reg0 = 0x00000000;
+    INTC->pend_reg1 = 0x00000000;
+    /* set priority */
+    INTC->resp_reg0 = 0x00000000;
+    INTC->resp_reg1 = 0x00000000;
+    /* close fiq interrupt */
+    INTC->ff_reg0 = 0x00000000;
+    INTC->ff_reg1 = 0x00000000;
+}
+
+/**
+ * This function will mask a interrupt.
+ * @param vector the interrupt number
+ */
+void rt_hw_interrupt_mask(int vector)
+{
+    rt_uint32_t mask_addr, data;
+
+    if ((vector < 0) || (vector > INTERRUPTS_MAX))
+    {
+        return;
+    }
+
+    mask_addr = (rt_uint32_t)(&INTC->mask_reg0);
+    mask_addr += vector & 0xE0 ? sizeof(rt_uint32_t *) : 0;
+
+    vector &= 0x1F;
+    data = readl(mask_addr);
+    data |= 0x1 << vector;
+    writel(data, mask_addr);
+}
+
+/**
+ * This function will un-mask a interrupt.
+ * @param vector the interrupt number
+ */
+void rt_hw_interrupt_umask(int vector)
+{
+    rt_uint32_t mask_addr, data;
+
+    if ((vector < 0) || (vector > INTERRUPTS_MAX))
+    {
+        return;
+    }
+
+    mask_addr = (rt_uint32_t)(&INTC->mask_reg0);
+    mask_addr += vector & 0xE0 ? sizeof(rt_uint32_t *) : 0;
+
+    vector &= 0x1F;
+    data = readl(mask_addr);
+    data &= ~(0x1 << vector);
+    writel(data, mask_addr);
+}
+
+/**
+ * This function will install a interrupt service routine to a interrupt.
+ * @param vector the interrupt number
+ * @param handler the interrupt service routine to be installed
+ * @param param the interrupt service function parameter
+ * @param name the interrupt name
+ * @return old handler
+ */
+rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler,
+        void *param, char *name)
+{
+    rt_isr_handler_t old_handler = RT_NULL;
+    rt_uint32_t pend_addr, en_addr, data;
+
+    if ((vector < 0) || (vector > INTERRUPTS_MAX))
+    {
+        return old_handler;
+    }
+
+    old_handler = isr_table[vector].handler;
+
+#ifdef RT_USING_INTERRUPT_INFO
+    rt_strncpy(isr_table[vector].name, name, RT_NAME_MAX);
+#endif /* RT_USING_INTERRUPT_INFO */
+    isr_table[vector].handler = handler;
+    isr_table[vector].param = param;
+
+    pend_addr = (rt_uint32_t)(&INTC->pend_reg0);
+    en_addr = (rt_uint32_t)(&INTC->en_reg0);
+    pend_addr += vector & 0xE0 ? sizeof(rt_uint32_t *) : 0;
+    en_addr += vector & 0xE0 ? sizeof(rt_uint32_t *) : 0;
+
+    vector &= 0x1F;
+    data = readl(pend_addr);
+    data &= ~(0x1 << vector);
+    writel(data, pend_addr);
+
+    data = readl(en_addr);
+    data |= 0x1 << vector;
+    writel(data, en_addr);
+
+    return old_handler;
+}
+
+void rt_interrupt_dispatch(void)
+{
+    void *param;
+    int vector;
+    rt_isr_handler_t isr_func;
+    rt_uint32_t pend_addr, data;
+
+    vector = INTC->vector_reg - INTC->base_addr_reg;
+    vector = vector >> 2;
+
+    isr_func = isr_table[vector].handler;
+    param = isr_table[vector].param;
+
+    /* jump to fun */
+    isr_func(vector, param);
+    /* clear pend bit */
+    pend_addr = (rt_uint32_t)(&INTC->pend_reg0);
+    pend_addr += vector & 0xE0 ? sizeof(rt_uint32_t *) : 0;
+
+    vector &= 0x1F;
+    data = readl(pend_addr);
+    data &= ~(0x1 << vector);
+    writel(data, pend_addr);
+
+#ifdef RT_USING_INTERRUPT_INFO
+    isr_table[vector].counter ++;
+#endif
+}
+
+
+
+
+
+
+
+
+

+ 107 - 0
bsp/allwinner_tina/libcpu/interrupt.h

@@ -0,0 +1,107 @@
+/*
+ * File      : interrupt.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2017, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2018-02-08     RT-Thread    the first version
+ */
+#ifndef __INTERRUPT_H__
+#define __INTERRUPT_H__
+
+/* Max number of interruptions */
+#define INTERRUPTS_MAX       (64)
+/* a group num */
+#define GROUP_NUM            (32)
+/* Interrupt Source */
+#define NMI_INTERRUPT              (0)
+#define UART0_INTERRUPT            (1)
+#define UART1_INTERRUPT            (2)
+#define UART2_INTERRUPT            (3)
+#define OWA_INTERRUPT              (5)
+#define CIR_INTERRUPT              (6)
+#define TWI0_INTERRUPT             (7)
+#define TWI1_INTERRUPT             (8)
+#define TWI2_INTERRUPT             (9)
+#define SPI0_INTERRUPT             (10)
+#define SPI1_INTERRUPT             (11)
+#define TIMER0_INTERRUPT           (13)
+#define TIMER1_INTERRUPT           (14)
+#define TIMER2_INTERRUPT           (15)
+#define WATCHDOG_INTERRUPT         (16)
+#define RSB_INTERRUPT              (17)
+#define DMA_INTERRUPT              (18)
+#define TOUCHPANEL_INTERRUPT       (20)
+#define AUDIOCODEC_INTERRUPT       (21)
+#define KEYADC_INTERRUPT           (22)
+#define SDC0_INTERRUPT             (23)
+#define SDC1_INTERRUPT             (24)
+#define USB_OTG_INTERRUPT          (26)
+#define TVD_INTERRUPT              (27)
+#define TVE_INTERRUPT              (28)
+#define TCON_INTERRUPT             (29)
+#define DE_FE_INTERRUPT            (30)
+#define DE_BE_INTERRUPT            (31)
+#define CSI_INTERRUPT              (32)
+#define DE_INTERLACER_INTERRUPT    (33)
+#define VE_INTERRUPT               (34)
+#define DAUDIO_INTERRUPT           (35)
+#define PIOD_INTERRUPT             (38)
+#define PIOE_INTERRUPT             (39)
+#define PIOF_INTERRUPT             (40)
+
+/* intc  register address */
+#define INTC_BASE_ADDR     (0x01C20400)
+
+struct tina_intc
+{
+    volatile rt_uint32_t vector_reg;       /* 0x00 */
+    volatile rt_uint32_t base_addr_reg;    /* 0x04 */
+    volatile rt_uint32_t reserved0;
+    volatile rt_uint32_t nmi_ctrl_reg;     /* 0x0C */
+    volatile rt_uint32_t pend_reg0;        /* 0x10 */
+    volatile rt_uint32_t pend_reg1;        /* 0x14 */
+    volatile rt_uint32_t reserved1[2];
+    volatile rt_uint32_t en_reg0;          /* 0x20 */
+    volatile rt_uint32_t en_reg1;          /* 0x24 */
+    volatile rt_uint32_t reserved2[2];
+    volatile rt_uint32_t mask_reg0;        /* 0x30 */
+    volatile rt_uint32_t mask_reg1;        /* 0x34 */
+    volatile rt_uint32_t reserved3[2];
+    volatile rt_uint32_t resp_reg0;        /* 0x40 */
+    volatile rt_uint32_t resp_reg1;        /* 0x44 */
+    volatile rt_uint32_t reserved4[2];
+    volatile rt_uint32_t ff_reg0;          /* 0x50 */
+    volatile rt_uint32_t ff_reg1;          /* 0x54 */
+    volatile rt_uint32_t reserved5[2];
+    volatile rt_uint32_t prio_reg0;        /* 0x60 */
+    volatile rt_uint32_t prio_reg1;        /* 0x64 */
+    volatile rt_uint32_t prio_reg2;        /* 0x68 */
+    volatile rt_uint32_t prio_reg3;        /* 0x6C */
+} ;
+
+typedef struct tina_intc *tina_intc_t;
+
+#define INTC ((tina_intc_t)INTC_BASE_ADDR)
+
+void rt_hw_interrupt_init(void);
+void rt_hw_interrupt_mask(int vector);
+void rt_hw_interrupt_umask(int vector);
+rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, void *param, char *name);
+
+#endif /* __INTERRUPT_H__ */

+ 457 - 0
bsp/allwinner_tina/libcpu/mmu.c

@@ -0,0 +1,457 @@
+/*
+ * File      : mmu.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2017, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2018-02-08     RT-Thread    the first version
+ */
+
+#include "mmu.h"
+
+/*----- Keil -----------------------------------------------------------------*/
+#ifdef __CC_ARM
+void mmu_setttbase(rt_uint32_t i)
+{
+    register rt_uint32_t value;
+
+    /* Invalidates all TLBs.Domain access is selected as
+     * client by configuring domain access register,
+     * in that case access controlled by permission value
+     * set by page table entry
+     */
+    value = 0;
+    __asm volatile{ mcr p15, 0, value, c8, c7, 0 }
+    value = 0x55555555;
+    __asm volatile { mcr p15, 0, value, c3, c0, 0 }
+    __asm volatile { mcr p15, 0, i, c2, c0, 0 }
+}
+
+void mmu_set_domain(rt_uint32_t i)
+{
+    __asm volatile { mcr p15, 0, i, c3, c0,  0 }
+}
+
+void mmu_enable()
+{
+    register rt_uint32_t value;
+
+    __asm volatile
+    {
+        mrc p15, 0, value, c1, c0, 0
+        orr value, value, #0x01
+        mcr p15, 0, value, c1, c0, 0
+    }
+}
+
+void mmu_disable()
+{
+    register rt_uint32_t value;
+
+    __asm volatile
+    {
+        mrc p15, 0, value, c1, c0, 0
+        bic value, value, #0x01
+        mcr p15, 0, value, c1, c0, 0
+    }
+}
+
+void mmu_enable_icache()
+{
+    register rt_uint32_t value;
+
+    __asm volatile
+    {
+        mrc p15, 0, value, c1, c0, 0
+        orr value, value, #0x1000
+        mcr p15, 0, value, c1, c0, 0
+    }
+}
+
+void mmu_enable_dcache()
+{
+    register rt_uint32_t value;
+
+    __asm volatile
+    {
+        mrc p15, 0, value, c1, c0, 0
+        orr value, value, #0x04
+        mcr p15, 0, value, c1, c0, 0
+    }
+}
+
+void mmu_disable_icache()
+{
+    register rt_uint32_t value;
+
+    __asm volatile
+    {
+        mrc p15, 0, value, c1, c0, 0
+        bic value, value, #0x1000
+        mcr p15, 0, value, c1, c0, 0
+    }
+}
+
+void mmu_disable_dcache()
+{
+    register rt_uint32_t value;
+
+    __asm volatile
+    {
+        mrc p15, 0, value, c1, c0, 0
+        bic value, value, #0x04
+        mcr p15, 0, value, c1, c0, 0
+    }
+}
+
+void mmu_enable_alignfault()
+{
+    register rt_uint32_t value;
+
+    __asm volatile
+    {
+        mrc p15, 0, value, c1, c0, 0
+        orr value, value, #0x02
+        mcr p15, 0, value, c1, c0, 0
+    }
+}
+
+void mmu_disable_alignfault()
+{
+    register rt_uint32_t value;
+
+    __asm volatile
+    {
+        mrc p15, 0, value, c1, c0, 0
+        bic value, value, #0x02
+        mcr p15, 0, value, c1, c0, 0
+    }
+}
+
+void mmu_clean_invalidated_cache_index(int index)
+{
+    __asm volatile { mcr p15, 0, index, c7, c14, 2 }
+}
+
+void mmu_clean_invalidated_dcache(rt_uint32_t buffer, rt_uint32_t size)
+{
+    unsigned int ptr;
+
+    ptr = buffer & ~(CACHE_LINE_SIZE - 1);
+
+    while (ptr < buffer + size)
+    {
+        __asm volatile { MCR p15, 0, ptr, c7, c14, 1 }
+        ptr += CACHE_LINE_SIZE;
+    }
+}
+
+void mmu_clean_dcache(rt_uint32_t buffer, rt_uint32_t size)
+{
+    unsigned int ptr;
+
+    ptr = buffer & ~(CACHE_LINE_SIZE - 1);
+
+    while (ptr < buffer + size)
+    {
+        __asm volatile { MCR p15, 0, ptr, c7, c10, 1 }
+        ptr += CACHE_LINE_SIZE;
+    }
+}
+
+void mmu_invalidate_dcache(rt_uint32_t buffer, rt_uint32_t size)
+{
+    unsigned int ptr;
+
+    ptr = buffer & ~(CACHE_LINE_SIZE - 1);
+
+    while (ptr < buffer + size)
+    {
+        __asm volatile { MCR p15, 0, ptr, c7, c6, 1 }
+        ptr += CACHE_LINE_SIZE;
+    }
+}
+
+void mmu_invalidate_tlb()
+{
+    register rt_uint32_t value;
+
+    value = 0;
+    __asm volatile { mcr p15, 0, value, c8, c7, 0 }
+}
+
+void mmu_invalidate_icache()
+{
+    register rt_uint32_t value;
+
+    value = 0;
+
+    __asm volatile { mcr p15, 0, value, c7, c5, 0 }
+}
+
+
+void mmu_invalidate_dcache_all()
+{
+    register rt_uint32_t value;
+
+    value = 0;
+
+    __asm volatile { mcr p15, 0, value, c7, c6, 0 }
+}
+/*----- GNU ------------------------------------------------------------------*/
+#elif defined(__GNUC__) || defined(__ICCARM__)
+void mmu_setttbase(register rt_uint32_t i)
+{
+    register rt_uint32_t value;
+
+    /* Invalidates all TLBs.Domain access is selected as
+     * client by configuring domain access register,
+     * in that case access controlled by permission value
+     * set by page table entry
+     */
+    value = 0;
+    asm volatile("mcr p15, 0, %0, c8, c7, 0"::"r"(value));
+
+    value = 0x55555555;
+    asm volatile("mcr p15, 0, %0, c3, c0, 0"::"r"(value));
+
+    asm volatile("mcr p15, 0, %0, c2, c0, 0"::"r"(i));
+
+}
+
+void mmu_set_domain(register rt_uint32_t i)
+{
+    asm volatile("mcr p15,0, %0, c3, c0,  0": :"r"(i));
+}
+
+void mmu_enable()
+{
+    asm volatile
+    (
+        "mrc p15, 0, r0, c1, c0, 0 \n"
+        "orr r0, r0, #0x1 \n"
+        "mcr p15, 0, r0, c1, c0, 0 \n"
+        :::"r0"
+    );
+}
+
+void mmu_disable()
+{
+    asm volatile
+    (
+        "mrc p15, 0, r0, c1, c0, 0 \n"
+        "bic r0, r0, #0x1 \n"
+        "mcr p15, 0, r0, c1, c0, 0 \n"
+        :::"r0"
+    );
+
+}
+
+void mmu_enable_icache()
+{
+    asm volatile
+    (
+        "mrc p15, 0, r0, c1, c0, 0 \n"
+        "orr r0, r0, #(1<<12) \n"
+        "mcr p15, 0, r0, c1, c0, 0 \n"
+        :::"r0"
+    );
+}
+
+void mmu_enable_dcache()
+{
+    asm volatile
+    (
+        "mrc p15, 0, r0, c1, c0, 0 \n"
+        "orr r0, r0, #(1<<2) \n"
+        "mcr p15, 0, r0, c1, c0, 0 \n"
+        :::"r0"
+    );
+
+}
+
+void mmu_disable_icache()
+{
+    asm volatile
+    (
+        "mrc p15, 0, r0, c1, c0, 0 \n"
+        "bic r0, r0, #(1<<12) \n"
+        "mcr p15, 0, r0, c1, c0, 0 \n"
+        :::"r0"
+    );
+
+}
+
+void mmu_disable_dcache()
+{
+    asm volatile
+    (
+        "mrc p15, 0, r0, c1, c0, 0 \n"
+        "bic r0, r0, #(1<<2) \n"
+        "mcr p15, 0, r0, c1, c0, 0 \n"
+        :::"r0"
+    );
+
+}
+
+void mmu_enable_alignfault()
+{
+    asm volatile
+    (
+        "mrc p15, 0, r0, c1, c0, 0 \n"
+        "orr r0, r0, #1 \n"
+        "mcr p15, 0, r0, c1, c0, 0 \n"
+        :::"r0"
+    );
+
+}
+
+void mmu_disable_alignfault()
+{
+    asm volatile
+    (
+        "mrc p15, 0, r0, c1, c0, 0 \n"
+        "bic r0, r0, #1 \n"
+        "mcr p15, 0, r0, c1, c0, 0 \n"
+        :::"r0"
+    );
+
+}
+
+void mmu_clean_invalidated_cache_index(int index)
+{
+    asm volatile("mcr p15, 0, %0, c7, c14, 2": :"r"(index));
+}
+
+void mmu_clean_invalidated_dcache(rt_uint32_t buffer, rt_uint32_t size)
+{
+    unsigned int ptr;
+
+    ptr = buffer & ~(CACHE_LINE_SIZE - 1);
+
+    while (ptr < buffer + size)
+    {
+        asm volatile("mcr p15, 0, %0, c7, c14, 1": :"r"(ptr));
+
+        ptr += CACHE_LINE_SIZE;
+    }
+}
+
+
+void mmu_clean_dcache(rt_uint32_t buffer, rt_uint32_t size)
+{
+    unsigned int ptr;
+
+    ptr = buffer & ~(CACHE_LINE_SIZE - 1);
+
+    while (ptr < buffer + size)
+    {
+        asm volatile("mcr p15, 0, %0, c7, c10, 1": :"r"(ptr));
+
+        ptr += CACHE_LINE_SIZE;
+    }
+}
+
+void mmu_invalidate_dcache(rt_uint32_t buffer, rt_uint32_t size)
+{
+    unsigned int ptr;
+
+    ptr = buffer & ~(CACHE_LINE_SIZE - 1);
+
+    while (ptr < buffer + size)
+    {
+        asm volatile("mcr p15, 0, %0, c7, c6, 1": :"r"(ptr));
+
+        ptr += CACHE_LINE_SIZE;
+    }
+}
+
+void mmu_invalidate_tlb()
+{
+    asm volatile("mcr p15, 0, %0, c8, c7, 0": :"r"(0));
+
+}
+
+void mmu_invalidate_icache()
+{
+    asm volatile("mcr p15, 0, %0, c7, c5, 0": :"r"(0));
+
+}
+
+void mmu_invalidate_dcache_all()
+{
+    asm volatile("mcr p15, 0, %0, c7, c6, 0": :"r"(0));
+
+}
+#endif
+
+/* level1 page table */
+#if defined(__ICCARM__)
+#pragma data_alignment=(16*1024)
+static volatile rt_uint32_t _page_table[4 * 1024];
+#else
+static volatile rt_uint32_t _page_table[4 * 1024] \
+__attribute__((aligned(16 * 1024)));
+#endif
+
+void mmu_setmtt(rt_uint32_t vaddrStart, rt_uint32_t vaddrEnd,
+                rt_uint32_t paddrStart, rt_uint32_t attr)
+{
+    volatile rt_uint32_t *pTT;
+    volatile int nSec;
+    int i = 0;
+    pTT = (rt_uint32_t *)_page_table + (vaddrStart >> 20);
+    nSec = (vaddrEnd >> 20) - (vaddrStart >> 20);
+    for (i = 0; i <= nSec; i++)
+    {
+        *pTT = attr | (((paddrStart >> 20) + i) << 20);
+        pTT++;
+    }
+}
+
+void rt_hw_mmu_init(struct mem_desc *mdesc, rt_uint32_t size)
+{
+    /* disable I/D cache */
+    mmu_disable_dcache();
+    mmu_disable_icache();
+    mmu_disable();
+    mmu_invalidate_tlb();
+
+    /* set page table */
+    for (; size > 0; size--)
+    {
+        mmu_setmtt(mdesc->vaddr_start, mdesc->vaddr_end,
+                   mdesc->paddr_start, mdesc->attr);
+        mdesc++;
+    }
+
+    /* set MMU table address */
+    mmu_setttbase((rt_uint32_t)_page_table);
+
+    /* enables MMU */
+    mmu_enable();
+
+    /* enable Instruction Cache */
+    mmu_enable_icache();
+
+    /* enable Data Cache */
+    mmu_enable_dcache();
+
+    mmu_invalidate_icache();
+    mmu_invalidate_dcache_all();
+}

+ 65 - 0
bsp/allwinner_tina/libcpu/mmu.h

@@ -0,0 +1,65 @@
+/*
+ * File      : mmu.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2017, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2018-02-08     RT-Thread    the first version
+ */
+#ifndef __MMU_H__
+#define __MMU_H__
+
+#include <rtthread.h>
+
+#define CACHE_LINE_SIZE     32
+
+#define DESC_SEC            (0x2|(1<<4))
+#define CB                  (3<<2)  //cache_on, write_back
+#define CNB                 (2<<2)  //cache_on, write_through
+#define NCB                 (1<<2)  //cache_off,WR_BUF on
+#define NCNB                (0<<2)  //cache_off,WR_BUF off
+#define AP_RW               (3<<10) //supervisor=RW, user=RW
+#define AP_RO               (2<<10) //supervisor=RW, user=RO
+
+#define DOMAIN_FAULT        (0x0)
+#define DOMAIN_CHK          (0x1)
+#define DOMAIN_NOTCHK       (0x3)
+#define DOMAIN0             (0x0<<5)
+#define DOMAIN1             (0x1<<5)
+
+#define DOMAIN0_ATTR        (DOMAIN_CHK<<0)
+#define DOMAIN1_ATTR        (DOMAIN_FAULT<<2)
+
+#define RW_CB       (AP_RW|DOMAIN0|CB|DESC_SEC)     /* Read/Write, cache, write back */
+#define RW_CNB      (AP_RW|DOMAIN0|CNB|DESC_SEC)    /* Read/Write, cache, write through */
+#define RW_NCNB     (AP_RW|DOMAIN0|NCNB|DESC_SEC)   /* Read/Write without cache and write buffer */
+#define RW_FAULT    (AP_RW|DOMAIN1|NCNB|DESC_SEC)   /* Read/Write without cache and write buffer */
+
+struct mem_desc
+{
+    rt_uint32_t vaddr_start;
+    rt_uint32_t vaddr_end;
+    rt_uint32_t paddr_start;
+    rt_uint32_t attr;
+};
+
+void rt_hw_mmu_init(struct mem_desc *mdesc, rt_uint32_t size);
+void mmu_clean_invalidated_dcache(rt_uint32_t buffer, rt_uint32_t size);
+void mmu_clean_dcache(rt_uint32_t buffer, rt_uint32_t size);
+void mmu_invalidate_dcache(rt_uint32_t buffer, rt_uint32_t size);
+#endif

+ 81 - 0
bsp/allwinner_tina/libcpu/rt_low_level_init.c

@@ -0,0 +1,81 @@
+/*
+ * File      : rt_low_level_init.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2017, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2018-02-08     RT-Thread    the first version
+ */
+
+void rt_low_level_init(void)
+{
+    volatile unsigned int *addr;
+    volatile unsigned int time;
+    int i;
+
+    //change cpu clk source to 24M
+    addr = (unsigned int *)(0x01c20000 + 0x050);
+    *addr = 0x10000;
+    //init cpu pll clk 408M
+    addr = (unsigned int *)(0x01c20000 + 0x000);
+    *addr = 0x80001000;
+    time = 0xffff;
+    while ((!(*addr & (0x1 << 28))) && (time--));
+    //change cpu clk source to pll
+    if (time > 0)
+    {
+        addr = (unsigned int *)(0x01c20000 + 0x050);
+        *addr = 0x20000;
+    }
+
+    //init periph pll clk:600M
+    //init ahb    pll clk:200M
+    //init apb    pll clk:100M
+    addr = (unsigned int *)(0x01c20000 + 0x028);
+    if (*addr & (0x1 << 31))
+        return;
+
+    addr = (unsigned int *)(0x01c20000 + 0x200);
+    *addr = 0x1ff;
+    addr = (unsigned int *)(0x01c20000 + 0x204);
+    *addr = 0x1ff;
+
+    addr = (unsigned int *)(0x01c20000 + 0x028);
+    *addr |= (0x1 << 31);
+    while (!(*addr & (0x1 << 28)));
+
+    addr = (unsigned int *)(0x01c20000 + 0x054);
+    *addr = (0x0 << 16) | (0x3 << 12) | (0x0 << 8) | (0x2 << 6) | (0x0 << 4);
+
+    //init gpio config
+    for (i = 0; i < 6; i++)
+    {
+        if (i == 1)
+            continue;// not config gpio B
+
+        addr = (unsigned int *)(0x01c20800 + i * 0x24 + 0x00);
+        *addr = 0x77777777;
+        addr = (unsigned int *)(0x01c20800 + i * 0x24 + 0x04);
+        *addr = 0x77777777;
+        addr = (unsigned int *)(0x01c20800 + i * 0x24 + 0x08);
+        *addr = 0x77777777;
+        addr = (unsigned int *)(0x01c20800 + i * 0x24 + 0x0C);
+        *addr = 0x77777777;
+    }
+}
+

+ 81 - 0
bsp/allwinner_tina/libcpu/stack.c

@@ -0,0 +1,81 @@
+/*
+ * File      : stack.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2017, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2018-02-08     RT-Thread    the first version
+ */
+#include <rtthread.h>
+
+/*****************************/
+/* CPU Mode                  */
+/*****************************/
+#define USERMODE        0x10
+#define FIQMODE         0x11
+#define IRQMODE         0x12
+#define SVCMODE         0x13
+#define ABORTMODE       0x17
+#define UNDEFMODE       0x1b
+#define MODEMASK        0x1f
+#define NOINT           0xc0
+
+/**
+ * This function will initialize thread stack
+ *
+ * @param tentry the entry of thread
+ * @param parameter the parameter of entry
+ * @param stack_addr the beginning stack address
+ * @param texit the function will be called when thread exit
+ *
+ * @return stack address
+ */
+rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter,
+                             rt_uint8_t *stack_addr, void *texit)
+{
+    rt_uint32_t *stk;
+
+    //stk      = (rt_uint32_t*)stack_addr;
+    stack_addr += sizeof(rt_uint32_t);
+    stack_addr  = (rt_uint8_t *)RT_ALIGN_DOWN((rt_uint32_t)stack_addr, 8);
+    stk  = (rt_uint32_t *)stack_addr;
+
+    *(--stk) = (rt_uint32_t)tentry;         /* entry point */
+    *(--stk) = (rt_uint32_t)texit;          /* lr */
+    *(--stk) = 0xdeadbeef;                  /* r12 */
+    *(--stk) = 0xdeadbeef;                  /* r11 */
+    *(--stk) = 0xdeadbeef;                  /* r10 */
+    *(--stk) = 0xdeadbeef;                  /* r9 */
+    *(--stk) = 0xdeadbeef;                  /* r8 */
+    *(--stk) = 0xdeadbeef;                  /* r7 */
+    *(--stk) = 0xdeadbeef;                  /* r6 */
+    *(--stk) = 0xdeadbeef;                  /* r5 */
+    *(--stk) = 0xdeadbeef;                  /* r4 */
+    *(--stk) = 0xdeadbeef;                  /* r3 */
+    *(--stk) = 0xdeadbeef;                  /* r2 */
+    *(--stk) = 0xdeadbeef;                  /* r1 */
+    *(--stk) = (rt_uint32_t)parameter;      /* r0 : argument */
+    /* cpsr */
+    if ((rt_uint32_t)tentry & 0x01)
+        *(--stk) = SVCMODE | 0x20;          /* thumb mode */
+    else
+        *(--stk) = SVCMODE;                 /* arm mode   */
+
+    /* return task's current stack address */
+    return (rt_uint8_t *)stk;
+}

+ 346 - 0
bsp/allwinner_tina/libcpu/start_gcc.S

@@ -0,0 +1,346 @@
+/*
+ * File      : start_gcc.S
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2013-2018, RT-Thread Development Team
+ */
+
+.equ MODE_USR,        0x10
+.equ MODE_FIQ,        0x11
+.equ MODE_IRQ,        0x12
+.equ MODE_SVC,        0x13
+.equ MODE_ABT,        0x17
+.equ MODE_UND,        0x1B
+.equ MODE_SYS,        0x1F
+.equ MODEMASK,        0x1F
+.equ NOINT,           0xC0
+
+.equ I_BIT,           0x80
+.equ F_BIT,           0x40
+
+.equ UND_STACK_SIZE,  0x00000100
+.equ SVC_STACK_SIZE,  0x00000100
+.equ ABT_STACK_SIZE,  0x00000100
+.equ FIQ_STACK_SIZE,  0x00000100
+.equ IRQ_STACK_SIZE,  0x00000100
+.equ SYS_STACK_SIZE,  0x00000100
+
+ /*
+ ***************************************
+ * Interrupt vector table
+ ***************************************
+ */
+.section .vectors
+.code 32
+
+.global system_vectors
+system_vectors:
+    ldr pc, _vector_reset
+    ldr pc, _vector_undef
+    ldr pc, _vector_swi
+    ldr pc, _vector_pabt
+    ldr pc, _vector_dabt
+    ldr pc, _vector_resv
+    ldr pc, _vector_irq
+    ldr pc, _vector_fiq
+
+_vector_reset:
+    .word reset
+_vector_undef:
+    .word vector_undef
+_vector_swi:
+    .word vector_swi
+_vector_pabt:
+    .word vector_pabt
+_vector_dabt:
+    .word vector_dabt
+_vector_resv:
+    .word vector_resv
+_vector_irq:
+    .word vector_irq
+_vector_fiq:
+    .word vector_fiq
+
+.balignl    16,0xdeadbeef
+
+
+ /*
+ ***************************************
+ *  Stack and Heap Definitions 
+ ***************************************
+ */
+    .section .data
+    .space UND_STACK_SIZE
+    .align 3
+    .global und_stack_start
+und_stack_start:
+
+    .space ABT_STACK_SIZE
+    .align 3
+    .global abt_stack_start
+abt_stack_start:
+
+    .space FIQ_STACK_SIZE
+    .align 3
+    .global fiq_stack_start
+fiq_stack_start:
+
+    .space IRQ_STACK_SIZE
+    .align 3
+    .global irq_stack_start
+irq_stack_start:
+
+    .skip SYS_STACK_SIZE
+    .align 3
+    .global sys_stack_start
+sys_stack_start:
+
+    .space SVC_STACK_SIZE
+    .align 3
+    .global svc_stack_start
+svc_stack_start:
+
+/*
+ ***************************************
+ * Startup Code 
+ ***************************************
+ */
+    .section .text
+    .global reset
+reset:
+    /* Enter svc mode and mask interrupts */
+    mrs r0, cpsr
+    bic r0, r0, #MODEMASK
+    orr r0, r0, #MODE_SVC|NOINT
+    msr cpsr_cxsf, r0
+
+    /* init cpu  */
+    bl  cpu_init_crit
+    
+    /* todo:copyself to link address */
+    
+    /* Copy vector to the correct address */
+    ldr r0, =system_vectors
+    mrc p15, 0, r2, c1, c0, 0
+    ands r2, r2, #(1 << 13)
+    ldreq r1, =0x00000000
+    ldrne r1, =0xffff0000
+    ldmia r0!, {r2-r8, r10}
+    stmia r1!, {r2-r8, r10}
+    ldmia r0!, {r2-r8, r10}
+    stmia r1!, {r2-r8, r10}
+
+    /* turn off the watchdog */
+    ldr r0, =0x01C20CB8
+    mov     r1, #0x0
+    str     r1, [r0]
+
+    /* mask all IRQs source */
+    ldr r1, =0xffffffff
+    ldr r0, =0x01C20430
+    str r1, [r0], #0x04
+    str r1, [r0]
+    
+    /* Call low level init function */
+    ldr     sp, =svc_stack_start
+    ldr     r0, =rt_low_level_init
+    blx     r0
+    
+    /* init stack */
+    bl stack_setup
+    
+    /* clear bss */
+    mov     r0, #0
+    ldr     r1, =__bss_start
+    ldr     r2, =__bss_end
+
+bss_clear_loop:
+    cmp     r1, r2
+    strlo   r0, [r1], #4
+    blo     bss_clear_loop
+       
+    /* call c++ constructors of global objects */
+    /*
+    ldr     r0, =__ctors_start__
+    ldr     r1, =__ctors_end__
+
+ctor_loop:
+    cmp     r0, r1
+    beq     ctor_end
+    ldr     r2, [r0], #4
+    stmfd   sp!, {r0-r1}
+    mov     lr, pc
+    bx      r2
+    ldmfd   sp!, {r0-r1}
+    b       ctor_loop
+ctor_end:
+    */
+    /* start RT-Thread Kernel */
+    ldr     pc, _rtthread_startup
+_rtthread_startup:
+    .word  rtthread_startup
+
+
+
+cpu_init_crit:
+    /* invalidate I/D caches */
+    mov r0, #0
+    mcr p15, 0, r0, c7, c7, 0
+    mcr p15, 0, r0, c8, c7, 0
+
+    /* disable MMU stuff and caches */
+    mrc p15, 0, r0, c1, c0, 0
+    bic r0, r0, #0x00002300
+    bic r0, r0, #0x00000087
+    orr r0, r0, #0x00000002
+    orr r0, r0, #0x00001000
+    mcr p15, 0, r0, c1, c0, 0
+
+    bx lr
+ 
+stack_setup:
+    /* Setup Stack for each mode */
+    mrs     r0, cpsr
+    bic     r0, r0, #MODEMASK
+
+    orr     r1, r0, #MODE_UND|NOINT
+    msr     cpsr_cxsf, r1
+    ldr     sp, =und_stack_start
+
+    orr     r1, r0, #MODE_ABT|NOINT
+    msr     cpsr_cxsf, r1
+    ldr     sp, =abt_stack_start
+
+    orr     r1, r0, #MODE_IRQ|NOINT
+    msr     cpsr_cxsf, r1
+    ldr     sp, =irq_stack_start
+
+    orr     r1, r0, #MODE_FIQ|NOINT
+    msr     cpsr_cxsf, r1
+    ldr     sp, =fiq_stack_start
+
+    orr     r1, r0, #MODE_SYS|NOINT
+    msr     cpsr_cxsf,r1
+    ldr     sp, =sys_stack_start
+
+    orr     r1, r0, #MODE_SVC|NOINT
+    msr     cpsr_cxsf, r1
+    ldr     sp, =svc_stack_start
+
+    bx      lr
+ 
+/*
+ ***************************************
+ * exception handlers 
+ ***************************************
+ */
+    .global rt_hw_trap_udef
+    .global rt_hw_trap_swi
+    .global rt_hw_trap_pabt
+    .global rt_hw_trap_dabt
+    .global rt_hw_trap_resv
+    .global rt_hw_trap_irq
+    .global rt_hw_trap_fiq
+    
+    .global rt_interrupt_enter
+    .global rt_interrupt_leave
+    .global rt_thread_switch_interrupt_flag
+    .global rt_interrupt_from_thread
+    .global rt_interrupt_to_thread
+
+    /* Interrupt */
+    .align  5
+vector_fiq:
+    stmfd   sp!,{r0-r7,lr}
+    bl      rt_hw_trap_fiq
+    ldmfd   sp!,{r0-r7,lr}
+    subs    pc, lr, #4
+
+    .align  5
+vector_irq:
+    stmfd   sp!, {r0-r12,lr}
+
+    bl      rt_interrupt_enter
+    bl      rt_hw_trap_irq
+    bl      rt_interrupt_leave
+
+    ldr     r0, =rt_thread_switch_interrupt_flag
+    ldr     r1, [r0]
+    cmp     r1, #1
+    beq     rt_hw_context_switch_interrupt_do
+
+    ldmfd   sp!, {r0-r12,lr}
+    subs    pc,  lr, #4
+
+rt_hw_context_switch_interrupt_do:
+    mov     r1,  #0         
+    str     r1,  [r0]
+
+    mov     r1, sp          
+    add     sp, sp, #4*4
+    ldmfd   sp!, {r4-r12,lr}
+    mrs     r0,  spsr       
+    sub     r2,  lr, #4     
+
+    msr     cpsr_c, #I_BIT|F_BIT|MODE_SVC
+
+    stmfd   sp!, {r2}       
+    stmfd   sp!, {r4-r12,lr}
+    ldmfd   r1,  {r1-r4}    
+    stmfd   sp!, {r1-r4}    
+    stmfd   sp!, {r0}       
+
+    ldr     r4,  =rt_interrupt_from_thread
+    ldr     r5,  [r4]
+    str     sp,  [r5]       
+
+    ldr     r6,  =rt_interrupt_to_thread
+    ldr     r6,  [r6]
+    ldr     sp,  [r6]       
+
+    ldmfd   sp!, {r4}       
+    msr     spsr_cxsf, r4
+
+    ldmfd   sp!, {r0-r12,lr,pc}^ 
+
+    /* Exception */
+.macro push_svc_reg
+    sub     sp, sp, #17 * 4
+    stmia   sp, {r0 - r12} 
+    mov     r0, sp
+    mrs     r6, spsr       
+    str     lr, [r0, #15*4]
+    str     r6, [r0, #16*4]
+    str     sp, [r0, #13*4]
+    str     lr, [r0, #14*4]
+.endm
+
+    .align  5
+vector_swi:
+    push_svc_reg
+    bl      rt_hw_trap_swi
+    b       .
+
+    .align  5
+vector_undef:
+    push_svc_reg
+    bl      rt_hw_trap_udef
+    b       .
+
+    .align  5
+vector_pabt:
+    push_svc_reg
+    bl      rt_hw_trap_pabt
+    b       .
+
+    .align  5
+vector_dabt:
+    push_svc_reg
+    bl      rt_hw_trap_dabt
+    b       .
+
+    .align  5
+vector_resv:
+    push_svc_reg
+    bl      rt_hw_trap_resv
+    b       .
+

+ 223 - 0
bsp/allwinner_tina/libcpu/trap.c

@@ -0,0 +1,223 @@
+/*
+ * File      : trap.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2017, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2018-02-08     RT-Thread    the first version
+ */
+
+#include <rtthread.h>
+#include <rthw.h>
+
+#define INT_IRQ     0x00
+#define INT_FIQ     0x01
+
+extern struct rt_thread *rt_current_thread;
+#ifdef RT_USING_FINSH
+extern long list_thread(void);
+#endif
+
+struct rt_hw_register
+{
+    rt_uint32_t r0;
+    rt_uint32_t r1;
+    rt_uint32_t r2;
+    rt_uint32_t r3;
+    rt_uint32_t r4;
+    rt_uint32_t r5;
+    rt_uint32_t r6;
+    rt_uint32_t r7;
+    rt_uint32_t r8;
+    rt_uint32_t r9;
+    rt_uint32_t r10;
+    rt_uint32_t fp;
+    rt_uint32_t ip;
+    rt_uint32_t sp;
+    rt_uint32_t lr;
+    rt_uint32_t pc;
+    rt_uint32_t cpsr;
+    rt_uint32_t ORIG_r0;
+};
+static rt_err_t (*rt_exception_hook)(void *context) = RT_NULL;
+void rt_hw_exception_install(rt_err_t (*exception_handle)(void *context))
+{
+    rt_exception_hook = exception_handle;
+}
+/**
+ * this function will show registers of CPU
+ *
+ * @param regs the registers point
+ */
+
+void rt_hw_show_register(struct rt_hw_register *regs)
+{
+    rt_kprintf("Execption:\n");
+    rt_kprintf("r00:0x%08x r01:0x%08x r02:0x%08x r03:0x%08x\n",
+               regs->r0, regs->r1, regs->r2, regs->r3);
+    rt_kprintf("r04:0x%08x r05:0x%08x r06:0x%08x r07:0x%08x\n",
+               regs->r4, regs->r5, regs->r6, regs->r7);
+    rt_kprintf("r08:0x%08x r09:0x%08x r10:0x%08x\n",
+               regs->r8, regs->r9, regs->r10);
+    rt_kprintf("fp :0x%08x ip :0x%08x\n",
+               regs->fp, regs->ip);
+    rt_kprintf("sp :0x%08x lr :0x%08x pc :0x%08x\n",
+               regs->sp, regs->lr, regs->pc);
+    rt_kprintf("cpsr:0x%08x\n", regs->cpsr);
+}
+
+/**
+ * When ARM7TDMI comes across an instruction which it cannot handle,
+ * it takes the undefined instruction trap.
+ *
+ * @param regs system registers
+ *
+ * @note never invoke this function in application
+ */
+void rt_hw_trap_udef(struct rt_hw_register *regs)
+{
+    if (rt_exception_hook != RT_NULL)
+    {
+        rt_err_t result;
+
+        result = rt_exception_hook(regs);
+        if (result == RT_EOK) return;
+    }
+    rt_hw_show_register(regs);
+
+    rt_kprintf("undefined instruction\n");
+    rt_kprintf("thread - %s stack:\n", rt_current_thread->name);
+
+#ifdef RT_USING_FINSH
+    list_thread();
+#endif
+    rt_hw_cpu_shutdown();
+}
+
+/**
+ * The software interrupt instruction (SWI) is used for entering
+ * Supervisor mode, usually to request a particular supervisor
+ * function.
+ *
+ * @param regs system registers
+ *
+ * @note never invoke this function in application
+ */
+void rt_hw_trap_swi(struct rt_hw_register *regs)
+{
+    if (rt_exception_hook != RT_NULL)
+    {
+        rt_err_t result;
+
+        result = rt_exception_hook(regs);
+        if (result == RT_EOK) return;
+    }
+    rt_hw_show_register(regs);
+
+    rt_kprintf("software interrupt\n");
+    rt_hw_cpu_shutdown();
+}
+
+/**
+ * An abort indicates that the current memory access cannot be completed,
+ * which occurs during an instruction prefetch.
+ *
+ * @param regs system registers
+ *
+ * @note never invoke this function in application
+ */
+void rt_hw_trap_pabt(struct rt_hw_register *regs)
+{
+    if (rt_exception_hook != RT_NULL)
+    {
+        rt_err_t result;
+
+        result = rt_exception_hook(regs);
+        if (result == RT_EOK) return;
+    }
+    rt_hw_show_register(regs);
+
+    rt_kprintf("prefetch abort\n");
+    rt_kprintf("thread - %s stack:\n", RT_NAME_MAX, rt_current_thread->name);
+
+#ifdef RT_USING_FINSH
+    list_thread();
+#endif
+    rt_hw_cpu_shutdown();
+}
+
+/**
+ * An abort indicates that the current memory access cannot be completed,
+ * which occurs during a data access.
+ *
+ * @param regs system registers
+ *
+ * @note never invoke this function in application
+ */
+void rt_hw_trap_dabt(struct rt_hw_register *regs)
+{
+    if (rt_exception_hook != RT_NULL)
+    {
+        rt_err_t result;
+
+        result = rt_exception_hook(regs);
+        if (result == RT_EOK) return;
+    }
+    rt_hw_show_register(regs);
+
+    rt_kprintf("data abort\n");
+    rt_kprintf("thread - %s stack:\n", RT_NAME_MAX, rt_current_thread->name);
+
+#ifdef RT_USING_FINSH
+    list_thread();
+#endif
+    rt_hw_cpu_shutdown();
+}
+
+/**
+ * Normally, system will never reach here
+ *
+ * @param regs system registers
+ *
+ * @note never invoke this function in application
+ */
+void rt_hw_trap_resv(struct rt_hw_register *regs)
+{
+    if (rt_exception_hook != RT_NULL)
+    {
+        rt_err_t result;
+
+        result = rt_exception_hook(regs);
+        if (result == RT_EOK) return;
+    }
+    rt_kprintf("not used\n");
+    rt_hw_show_register(regs);
+    rt_hw_cpu_shutdown();
+}
+
+extern void rt_interrupt_dispatch(void);
+
+void rt_hw_trap_irq(void)
+{
+    rt_interrupt_dispatch();
+}
+
+void rt_hw_trap_fiq(void)
+{
+    rt_interrupt_dispatch();
+}

+ 148 - 0
bsp/allwinner_tina/link.lds

@@ -0,0 +1,148 @@
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+
+SECTIONS
+{
+    . = 0x80000000;
+    
+    . = ALIGN(4);
+    __text_start = .;
+    .text :
+    {
+        *(.vectors)
+        *(.text)
+        *(.text.*)
+	KEEP(*(.fini))
+
+        /* section information for finsh shell */
+        . = ALIGN(4);
+        __fsymtab_start = .;
+        KEEP(*(FSymTab))
+        __fsymtab_end = .;
+        . = ALIGN(4);
+        __vsymtab_start = .;
+        KEEP(*(VSymTab))
+        __vsymtab_end = .;
+        . = ALIGN(4);
+
+        /* section information for modules */
+        . = ALIGN(4);
+        __rtmsymtab_start = .;
+        KEEP(*(RTMSymTab))
+        __rtmsymtab_end = .;
+
+        /* section information for initialization */
+        . = ALIGN(4);
+        __rt_init_start = .;
+        KEEP(*(SORT(.rti_fn*)))
+        __rt_init_end = .;
+    } =0
+    __text_end = .;
+
+    __rodata_start = .;
+    .rodata   : { *(.rodata) *(.rodata.*) *(.eh_frame) }
+    __rodata_end = .;
+
+    . = ALIGN(4);
+    .ctors :
+    {
+        PROVIDE(__ctors_start__ = .);
+	*crtbegin.o(.ctors)
+	*crtbegin?.o(.ctors)
+	*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
+	*(SORT(.ctors.*))
+	*(.ctors)
+        PROVIDE(__ctors_end__ = .);       
+    }
+
+    .ARM.extab : 
+    {
+	*(.ARM.extab* .gnu.linkonce.armextab.*)
+    } 
+    /* The .ARM.exidx section is used for C++ exception handling. */
+    /* .ARM.exidx is sorted, so has to go in its own output section.  */
+    __exidx_start = .;
+    ARM.exidx :
+    {
+        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+
+        /* This is used by the startup in order to initialize the .data secion */
+        _sidata = .;
+    }
+    __exidx_end = .;
+    
+    .dtors :
+    {
+        PROVIDE(__dtors_start__ = .);
+        *crtbegin.o(.dtors)
+ 		*crtbegin?.o(.dtors)
+ 		*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
+ 		*(SORT(.dtors.*))
+ 		*(.dtors)
+        PROVIDE(__dtors_end__ = .);
+    }
+
+    __data_start = .;
+    . = ALIGN(4);
+    .data :
+    {
+        *(.data)
+        *(.data.*)
+
+		. = ALIGN(4);
+		/* preinit data */
+		PROVIDE_HIDDEN (__preinit_array_start = .);
+		KEEP(*(.preinit_array))
+		PROVIDE_HIDDEN (__preinit_array_end = .);
+
+		. = ALIGN(4);
+		/* init data */
+		PROVIDE_HIDDEN (__init_array_start = .);
+		KEEP(*(SORT(.init_array.*)))
+		KEEP(*(.init_array))
+		PROVIDE_HIDDEN (__init_array_end = .);
+
+
+		. = ALIGN(4);
+		/* finit data */
+		PROVIDE_HIDDEN (__fini_array_start = .);
+		KEEP(*(SORT(.fini_array.*)))
+		KEEP(*(.fini_array))
+		PROVIDE_HIDDEN (__fini_array_end = .);
+
+		KEEP(*(.jcr*))
+		. = ALIGN(4);
+		/* All data end */
+
+        *(.gnu.linkonce.d*)
+    }
+    __data_end = .;
+
+    . = ALIGN(4);
+    __bss_start = .;
+    .bss       :
+    {
+    *(.bss)
+    *(.bss.*)
+    *(COMMON)
+    . = ALIGN(4);
+    }
+    . = ALIGN(4);
+    __bss_end = .;
+
+    /* Stabs debugging sections.  */
+    .stab 0 : { *(.stab) }
+    .stabstr 0 : { *(.stabstr) }
+    .stab.excl 0 : { *(.stab.excl) }
+    .stab.exclstr 0 : { *(.stab.exclstr) }
+    .stab.index 0 : { *(.stab.index) }
+    .stab.indexstr 0 : { *(.stab.indexstr) }
+    .comment 0 : { *(.comment) }
+
+    .debug_abbrev 0 : { *(.debug_abbrev) }
+    .debug_info 0 : { *(.debug_info) }
+    .debug_line 0 : { *(.debug_line) }
+    .debug_pubnames 0 : { *(.debug_pubnames) }
+    .debug_aranges 0 : { *(.debug_aranges) }
+    _end = .;
+}

+ 235 - 0
bsp/allwinner_tina/rtconfig.h

@@ -0,0 +1,235 @@
+#ifndef RT_CONFIG_H__
+#define RT_CONFIG_H__
+
+/* Automatically generated file; DO NOT EDIT. */
+/* RT-Thread Configuration */
+
+/* RT-Thread Kernel */
+
+#define RT_NAME_MAX 8
+#define RT_ALIGN_SIZE 4
+/* RT_THREAD_PRIORITY_8 is not set */
+#define RT_THREAD_PRIORITY_32
+/* RT_THREAD_PRIORITY_256 is not set */
+#define RT_THREAD_PRIORITY_MAX 32
+#define RT_TICK_PER_SECOND 100
+#define RT_DEBUG
+#define RT_USING_OVERFLOW_CHECK
+#define RT_DEBUG_INIT 0
+#define RT_DEBUG_THREAD 0
+#define RT_USING_HOOK
+#define IDLE_THREAD_STACK_SIZE 256
+/* RT_USING_TIMER_SOFT is not set */
+
+/* Inter-Thread communication */
+
+#define RT_USING_SEMAPHORE
+#define RT_USING_MUTEX
+#define RT_USING_EVENT
+#define RT_USING_MAILBOX
+#define RT_USING_MESSAGEQUEUE
+/* RT_USING_SIGNALS is not set */
+
+/* Memory Management */
+
+#define RT_USING_MEMPOOL
+/* RT_USING_MEMHEAP is not set */
+/* RT_USING_NOHEAP is not set */
+#define RT_USING_SMALL_MEM
+/* RT_USING_SLAB is not set */
+/* RT_USING_MEMTRACE is not set */
+#define RT_USING_HEAP
+
+/* Kernel Device Object */
+
+#define RT_USING_DEVICE
+/* RT_USING_INTERRUPT_INFO is not set */
+#define RT_USING_CONSOLE
+#define RT_CONSOLEBUF_SIZE 128
+#define RT_CONSOLE_DEVICE_NAME "uart0"
+/* RT_USING_MODULE is not set */
+#define ARCH_ARM
+#define ARCH_ARM_ARM9
+
+/* RT-Thread Components */
+
+#define RT_USING_COMPONENTS_INIT
+#define RT_USING_USER_MAIN
+
+/* C++ features */
+
+/* RT_USING_CPLUSPLUS is not set */
+
+/* Command shell */
+
+#define RT_USING_FINSH
+#define FINSH_THREAD_NAME "tshell"
+#define FINSH_USING_HISTORY
+#define FINSH_HISTORY_LINES 5
+#define FINSH_USING_SYMTAB
+#define FINSH_USING_DESCRIPTION
+#define FINSH_THREAD_PRIORITY 20
+#define FINSH_THREAD_STACK_SIZE 4096
+#define FINSH_CMD_SIZE 80
+/* FINSH_USING_AUTH is not set */
+#define FINSH_USING_MSH
+#define FINSH_USING_MSH_DEFAULT
+/* FINSH_USING_MSH_ONLY is not set */
+
+/* Device virtual file system */
+
+#define RT_USING_DFS
+#define DFS_USING_WORKDIR
+#define DFS_FILESYSTEMS_MAX 2
+#define DFS_FILESYSTEM_TYPES_MAX 2
+#define DFS_FD_MAX 4
+#define RT_USING_DFS_ELMFAT
+
+/* elm-chan's FatFs, Generic FAT Filesystem Module */
+
+#define RT_DFS_ELM_CODE_PAGE 437
+#define RT_DFS_ELM_WORD_ACCESS
+#define RT_DFS_ELM_USE_LFN_0
+/* RT_DFS_ELM_USE_LFN_1 is not set */
+/* RT_DFS_ELM_USE_LFN_2 is not set */
+/* RT_DFS_ELM_USE_LFN_3 is not set */
+#define RT_DFS_ELM_USE_LFN 0
+#define RT_DFS_ELM_MAX_LFN 255
+#define RT_DFS_ELM_DRIVES 2
+#define RT_DFS_ELM_MAX_SECTOR_SIZE 512
+/* RT_DFS_ELM_USE_ERASE is not set */
+#define RT_DFS_ELM_REENTRANT
+#define RT_USING_DFS_DEVFS
+/* RT_USING_DFS_NET is not set */
+/* RT_USING_DFS_ROMFS is not set */
+/* RT_USING_DFS_RAMFS is not set */
+/* RT_USING_DFS_UFFS is not set */
+/* RT_USING_DFS_JFFS2 is not set */
+/* RT_USING_DFS_NFS is not set */
+
+/* Device Drivers */
+
+#define RT_USING_DEVICE_IPC
+#define RT_USING_SERIAL
+/* RT_USING_CAN is not set */
+/* RT_USING_HWTIMER is not set */
+/* RT_USING_CPUTIME is not set */
+/* RT_USING_I2C is not set */
+#define RT_USING_PIN
+/* RT_USING_MTD_NOR is not set */
+/* RT_USING_MTD_NAND is not set */
+/* RT_USING_RTC is not set */
+/* RT_USING_SDIO is not set */
+/* RT_USING_SPI is not set */
+/* RT_USING_WDT is not set */
+/* RT_USING_WIFI is not set */
+
+/* Using USB */
+
+/* RT_USING_USB_HOST is not set */
+/* RT_USING_USB_DEVICE is not set */
+
+/* POSIX layer and C standard library */
+
+#define RT_USING_LIBC
+/* RT_USING_PTHREADS is not set */
+#define RT_USING_POSIX
+/* RT_USING_POSIX_MMAP is not set */
+/* RT_USING_POSIX_TERMIOS is not set */
+/* RT_USING_POSIX_AIO is not set */
+
+/* Network stack */
+
+/* light weight TCP/IP stack */
+
+/* RT_USING_LWIP is not set */
+
+/* Modbus master and slave stack */
+
+/* RT_USING_MODBUS is not set */
+
+/* RT-Thread UI Engine */
+
+/* PKG_USING_GUIENGINE is not set */
+
+/* VBUS(Virtual Software BUS) */
+
+/* RT_USING_VBUS is not set */
+
+/* Utilities */
+
+/* RT_USING_LOGTRACE is not set */
+/* RT_USING_RYM is not set */
+
+/* RT-Thread online packages */
+
+/* system packages */
+
+/* PKG_USING_LWEXT4 is not set */
+/* PKG_USING_PARTITION is not set */
+/* PKG_USING_PERSIMMON is not set */
+/* PKG_USING_SQLITE is not set */
+/* PKG_USING_RTI is not set */
+
+/* IoT - internet of things */
+
+/* PKG_USING_PAHOMQTT is not set */
+/* PKG_USING_WEBCLIENT is not set */
+/* PKG_USING_MONGOOSE is not set */
+/* PKG_USING_WEBTERMINAL is not set */
+/* PKG_USING_CJSON is not set */
+/* PKG_USING_LJSON is not set */
+/* PKG_USING_EZXML is not set */
+/* PKG_USING_NANOPB is not set */
+/* PKG_USING_GAGENT_CLOUD is not set */
+
+/* Wi-Fi */
+
+/* Marvell WiFi */
+
+/* PKG_USING_WLANMARVELL is not set */
+
+/* Wiced WiFi */
+
+/* PKG_USING_WLAN_WICED is not set */
+/* PKG_USING_COAP is not set */
+/* PKG_USING_NOPOLL is not set */
+
+/* security packages */
+
+/* PKG_USING_MBEDTLS is not set */
+/* PKG_USING_libsodium is not set */
+/* PKG_USING_TINYCRYPT is not set */
+
+/* language packages */
+
+/* PKG_USING_JERRYSCRIPT is not set */
+/* PKG_USING_MICROPYTHON is not set */
+
+/* multimedia packages */
+
+/* PKG_USING_OPENMV is not set */
+
+/* tools packages */
+
+/* PKG_USING_CMBACKTRACE is not set */
+/* PKG_USING_EASYLOGGER is not set */
+/* PKG_USING_SYSTEMVIEW is not set */
+/* PKG_USING_IPERF is not set */
+
+/* miscellaneous packages */
+
+/* PKG_USING_FASTLZ is not set */
+/* PKG_USING_MINILZO is not set */
+
+/* example package: hello */
+
+/* PKG_USING_HELLO is not set */
+/* PKG_USING_MULTIBUTTON is not set */
+#define TINA_USING_UART0
+/* TINA_USING_UART1 is not set */
+#define TINA_USING_UART2
+#define RT_USING_CPU_FFS
+#define RT_MAIN_THREAD_STACK_SIZE 2048
+
+#endif

+ 58 - 0
bsp/allwinner_tina/rtconfig.py

@@ -0,0 +1,58 @@
+import os
+
+# toolchains options
+ARCH        ='arm'
+CPU         ='R6'
+CROSS_TOOL  ='gcc'
+
+if os.getenv('RTT_ROOT'):
+    RTT_ROOT = os.getenv('RTT_ROOT')
+else:
+    RTT_ROOT = '../..'
+
+if os.getenv('RTT_CC'):
+    CROSS_TOOL = os.getenv('RTT_CC')
+
+if  CROSS_TOOL == 'gcc':
+    PLATFORM    = 'gcc'
+    EXEC_PATH   = r'E:\work\env\tools\gnu_gcc\arm_gcc\mingw\bin'
+else:
+    print 'Please make sure your toolchains is GNU GCC!'
+    exit(0)
+
+if os.getenv('RTT_EXEC_PATH'):
+    EXEC_PATH = os.getenv('RTT_EXEC_PATH')
+
+BUILD = 'release'
+# BUILD = 'debug'
+
+if PLATFORM == 'gcc':
+    # toolchains
+    PREFIX  = 'arm-none-eabi-'
+    CC      = PREFIX + 'gcc'
+    CXX     = PREFIX + 'g++'
+    AS      = PREFIX + 'gcc'
+    AR      = PREFIX + 'ar'
+    LINK    = PREFIX + 'g++'
+    TARGET_EXT = 'elf'
+    SIZE    = PREFIX + 'size'
+    OBJDUMP = PREFIX + 'objdump'
+    OBJCPY  = PREFIX + 'objcopy'
+
+    DEVICE  = ' -mcpu=arm926ej-s -ffunction-sections -fdata-sections'
+    CFLAGS  = DEVICE + ' -Wall'
+    AFLAGS  = ' -c' + DEVICE + ' -x assembler-with-cpp'
+    LFLAGS  = DEVICE + ' -nostartfiles -Wl,--gc-sections,-Map=rtthread.map,-cref,-u,system_vectors -T link.lds'
+    CPATH   = ''
+    LPATH   = ''
+
+    if BUILD == 'debug':
+        CFLAGS += ' -O0 -gdwarf-2'
+        AFLAGS += ' -gdwarf-2'
+    else:
+        CFLAGS += ' -O2'
+
+    CXXFLAGS = CFLAGS
+
+DUMP_ACTION = OBJDUMP + ' -D -S $TARGET > rtt.asm\n'
+POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread.bin\n' + SIZE + ' $TARGET \n'

+ 1 - 1
bsp/apollo2/rtconfig.h

@@ -138,7 +138,7 @@
 
 /* RT-Thread UI Engine */
 
-/* RT_USING_GUIENGINE is not set */
+/* PKG_USING_GUIENGINE is not set */
 
 /* VBUS(Virtual Software BUS) */
 

+ 4 - 4
bsp/apollo2/rtconfig.py

@@ -18,9 +18,9 @@ elif CROSS_TOOL == 'keil':
 	PLATFORM 	= 'armcc'
 	EXEC_PATH 	= 'C:/Keil_v5'
 elif CROSS_TOOL == 'iar':
-    print '================ERROR============================'
-    print 'Not support iar yet!'
-    print '================================================='
+    print('================ERROR============================')
+    print('Not support iar yet!')
+    print('=================================================')
     exit(0)
 
 if os.getenv('RTT_EXEC_PATH'):
@@ -35,7 +35,7 @@ if PLATFORM == 'gcc':
     AS = PREFIX + 'gcc'
     AR = PREFIX + 'ar'
     LINK = PREFIX + 'gcc'
-    TARGET_EXT = 'axf'
+    TARGET_EXT = 'elf'
     SIZE = PREFIX + 'size'
     OBJDUMP = PREFIX + 'objdump'
     OBJCPY = PREFIX + 'objcopy'

+ 1 - 1
bsp/asm9260t/.config

@@ -120,7 +120,7 @@ CONFIG_RT_USING_LIBC=y
 #
 # RT-Thread UI Engine
 #
-# CONFIG_RT_USING_GUIENGINE is not set
+# CONFIG_PKG_USING_GUIENGINE is not set
 
 #
 # RT-Thread online packages

+ 1 - 1
bsp/asm9260t/rtconfig.h

@@ -106,7 +106,7 @@
 
 /* RT-Thread UI Engine */
 
-/* RT_USING_GUIENGINE is not set */
+/* PKG_USING_GUIENGINE is not set */
 
 /* RT-Thread online packages */
 

+ 1 - 1
bsp/asm9260t/rtconfig.py

@@ -39,7 +39,7 @@ if PLATFORM == 'gcc':
     AS = PREFIX + 'gcc'
     AR = PREFIX + 'ar'
     LINK = PREFIX + 'gcc'
-    TARGET_EXT = 'axf'
+    TARGET_EXT = 'elf'
     SIZE = PREFIX + 'size'
     OBJDUMP = PREFIX + 'objdump'
     OBJCPY = PREFIX + 'objcopy'

+ 1 - 1
bsp/at91sam9260/rtconfig.py

@@ -37,7 +37,7 @@ if PLATFORM == 'gcc':
     AS = PREFIX + 'gcc'
     AR = PREFIX + 'ar'
     LINK = PREFIX + 'gcc'
-    TARGET_EXT = 'axf'
+    TARGET_EXT = 'elf'
     SIZE = PREFIX + 'size'
     OBJDUMP = PREFIX + 'objdump'
     OBJCPY = PREFIX + 'objcopy'

+ 6 - 6
bsp/avr32uc3b0/rtconfig.py

@@ -15,14 +15,14 @@ if  CROSS_TOOL == 'gcc':
 	PLATFORM 	= 'gcc'
 	EXEC_PATH 	= 'C:/Program Files/Atmel/AVR Tools/AVR Toolchain/bin'
 elif CROSS_TOOL == 'keil':
-    print '================ERROR============================'
-    print 'Not support keil yet!'
-    print '================================================='
+    print('================ERROR============================')
+    print('Not support keil yet!')
+    print('=================================================')
     exit(0)
 elif CROSS_TOOL == 'iar':
-    print '================ERROR============================'
-    print 'Not support iar yet!'
-    print '================================================='
+    print('================ERROR============================')
+    print('Not support iar yet!')
+    print('=================================================')
     exit(0)
 
 if os.getenv('RTT_EXEC_PATH'):

+ 3 - 3
bsp/beaglebone/rtconfig.py

@@ -15,9 +15,9 @@ elif CROSS_TOOL == 'keil':
     PLATFORM 	= 'armcc'
     EXEC_PATH 	= 'C:/Keil'
 elif CROSS_TOOL == 'iar':
-    print '================ERROR============================'
-    print 'Not support IAR yet!'
-    print '================================================='
+    print('================ERROR============================')
+    print('Not support IAR yet!')
+    print('=================================================')
     exit(0)
 
 if os.getenv('RTT_EXEC_PATH'):

+ 1 - 1
bsp/dm365/rtconfig.py

@@ -25,7 +25,7 @@ if PLATFORM == 'gcc':
     AS = PREFIX + 'gcc'
     AR = PREFIX + 'ar'
     LINK = PREFIX + 'gcc'
-    TARGET_EXT = 'axf'
+    TARGET_EXT = 'elf'
     SIZE = PREFIX + 'size'
     OBJDUMP = PREFIX + 'objdump'
     OBJCPY = PREFIX + 'objcopy'

+ 7 - 7
bsp/efm32/rtconfig.py

@@ -13,14 +13,14 @@ if CROSS_TOOL == 'gcc':
     EXEC_PATH   = 'C:\Program Files (x86)\CodeSourcery\Sourcery G++ Lite\bin'
     #EXEC_PATH  = 'C:\Program Files (x86)\yagarto\bin'
 elif CROSS_TOOL == 'keil':
-    print '================ERROR============================'
-    print 'Not support keil yet!'
-    print '================================================='
+    print('================ERROR============================')
+    print('Not support keil yet!')
+    print('=================================================')
     exit(0)
 elif CROSS_TOOL == 'iar':
-    print '================ERROR============================'
-    print 'Not support iar yet!'
-    print '================================================='
+    print('================ERROR============================')
+    print('Not support iar yet!')
+    print('=================================================')
     exit(0)
 
 if os.getenv('RTT_EXEC_PATH'):
@@ -52,7 +52,7 @@ if PLATFORM == 'gcc':
     AS = PREFIX + 'gcc'
     AR = PREFIX + 'ar'
     LINK = PREFIX + 'gcc'
-    TARGET_EXT = 'axf'
+    TARGET_EXT = 'elf'
     SIZE = PREFIX + 'size'
     OBJDUMP = PREFIX + 'objdump'
     OBJCPY = PREFIX + 'objcopy'

+ 4 - 4
bsp/frdm-k64f/rtconfig.py

@@ -17,9 +17,9 @@ elif CROSS_TOOL == 'keil':
 	PLATFORM 	= 'armcc'
 	EXEC_PATH 	= r'C:/Keil'
 elif CROSS_TOOL == 'iar':
-    print '================ERROR============================'
-    print 'Not support iar yet!'
-    print '================================================='
+    print('================ERROR============================')
+    print('Not support iar yet!')
+    print('=================================================')
     exit(0)
 
 if os.getenv('RTT_EXEC_PATH'):
@@ -34,7 +34,7 @@ if PLATFORM == 'gcc':
     AS = PREFIX + 'gcc'
     AR = PREFIX + 'ar'
     LINK = PREFIX + 'gcc'
-    TARGET_EXT = 'axf'
+    TARGET_EXT = 'elf'
     SIZE = PREFIX + 'size'
     OBJDUMP = PREFIX + 'objdump'
     OBJCPY = PREFIX + 'objcopy'

+ 2 - 2
bsp/gd32450z-eval/SConstruct

@@ -11,8 +11,8 @@ sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')]
 try:
     from building import *
 except:
-    print 'Cannot found RT-Thread root directory, please check RTT_ROOT'
-    print RTT_ROOT
+    print('Cannot found RT-Thread root directory, please check RTT_ROOT')
+    print(RTT_ROOT)
     exit(-1)
 
 TARGET = 'rtthread-gd32f4xx.' + rtconfig.TARGET_EXT

+ 2 - 2
bsp/gd32450z-eval/applications/application.c

@@ -17,7 +17,7 @@
 #include <rtthread.h>
 #include <finsh.h>
 
-#ifdef RT_USING_GUIENGINE
+#ifdef PKG_USING_GUIENGINE
 #include "rtgui_demo.h"
 #include <rtgui/driver.h>
 #endif
@@ -41,7 +41,7 @@ void rt_init_thread_entry(void* parameter)
     rt_components_init();
 #endif
     
-#ifdef RT_USING_GUIENGINE
+#ifdef PKG_USING_GUIENGINE
 	{
 		rt_device_t device;
 

+ 2 - 2
bsp/gd32450z-eval/applications/rtgui_demo.c

@@ -23,7 +23,7 @@
 #define DEBUG_PRINTF(...)   
 #endif
 
-#ifdef RT_USING_GUIENGINE
+#ifdef PKG_USING_GUIENGINE
 
 #include <rtgui/rtgui.h>
 #include <rtgui/rtgui_system.h>
@@ -122,4 +122,4 @@ int rt_gui_demo_init(void)
     
     return 0;
 }
-#endif /* RT_USING_GUIENGINE */
+#endif /* PKG_USING_GUIENGINE */

+ 1 - 1
bsp/gd32450z-eval/drivers/SConscript

@@ -18,7 +18,7 @@ if GetDepend('RT_USING_LWIP'):
     src += ['drv_enet.c', 'synopsys_emac.c']
     
 # add lcd drivers.
-if GetDepend('RT_USING_GUIENGINE'):
+if GetDepend('PKG_USING_GUIENGINE'):
     src += ['drv_lcd.c', 'gd32f450z_lcd_eval.c']
 
 # add spi flash drivers.

+ 1 - 1
bsp/gd32450z-eval/drivers/drv_lcd.c

@@ -18,7 +18,7 @@
 #include <board.h>
 #include <finsh.h>
 
-#ifdef RT_USING_GUIENGINE
+#ifdef PKG_USING_GUIENGINE
 
 
 #define RT_HW_LCD_WIDTH                ((uint16_t)320)     /* LCD PIXEL WIDTH            */

+ 1 - 1
bsp/gd32450z-eval/rtconfig.h

@@ -67,7 +67,7 @@
 
 /* SECTION: RTGUI support */
 /* using RTGUI support */
-#define RT_USING_GUIENGINE
+// #define PKG_USING_GUIENGINE
 
 /* name length of RTGUI object */
 #define RTGUI_NAME_MAX		16

+ 3 - 3
bsp/gd32450z-eval/rtconfig.py

@@ -13,9 +13,9 @@ if os.getenv('RTT_ROOT'):
 # cross_tool provides the cross compiler
 # EXEC_PATH is the compiler execute path, for example, CodeSourcery, Keil MDK, IAR
 if  CROSS_TOOL == 'gcc':
-    print '================ERROR============================'
-    print 'Not support gcc yet!'
-    print '================================================='
+    print('================ERROR============================')
+    print('Not support gcc yet!')
+    print('=================================================')
     PLATFORM    = 'gcc'
 elif CROSS_TOOL == 'keil':
     PLATFORM 	= 'armcc'

+ 340 - 0
bsp/gkipc/.config

@@ -0,0 +1,340 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# RT-Thread Configuration
+#
+
+#
+# RT-Thread Kernel
+#
+CONFIG_RT_NAME_MAX=32
+CONFIG_RT_ALIGN_SIZE=4
+# CONFIG_RT_THREAD_PRIORITY_8 is not set
+# CONFIG_RT_THREAD_PRIORITY_32 is not set
+CONFIG_RT_THREAD_PRIORITY_256=y
+CONFIG_RT_THREAD_PRIORITY_MAX=256
+CONFIG_RT_TICK_PER_SECOND=100
+CONFIG_RT_DEBUG=y
+CONFIG_RT_USING_OVERFLOW_CHECK=y
+CONFIG_RT_DEBUG_INIT=0
+CONFIG_RT_DEBUG_THREAD=0
+CONFIG_RT_USING_HOOK=y
+CONFIG_IDLE_THREAD_STACK_SIZE=1024
+CONFIG_RT_USING_TIMER_SOFT=y
+CONFIG_RT_TIMER_THREAD_PRIO=4
+CONFIG_RT_TIMER_THREAD_STACK_SIZE=10240
+
+#
+# Inter-Thread communication
+#
+CONFIG_RT_USING_SEMAPHORE=y
+CONFIG_RT_USING_MUTEX=y
+CONFIG_RT_USING_EVENT=y
+CONFIG_RT_USING_MAILBOX=y
+CONFIG_RT_USING_MESSAGEQUEUE=y
+# CONFIG_RT_USING_SIGNALS is not set
+
+#
+# Memory Management
+#
+# CONFIG_RT_USING_MEMPOOL is not set
+CONFIG_RT_USING_MEMHEAP=y
+# CONFIG_RT_USING_NOHEAP is not set
+CONFIG_RT_USING_SMALL_MEM=y
+# CONFIG_RT_USING_SLAB is not set
+# CONFIG_RT_USING_MEMHEAP_AS_HEAP is not set
+# CONFIG_RT_USING_MEMTRACE is not set
+CONFIG_RT_USING_HEAP=y
+
+#
+# Kernel Device Object
+#
+CONFIG_RT_USING_DEVICE=y
+CONFIG_RT_USING_INTERRUPT_INFO=y
+CONFIG_RT_USING_CONSOLE=y
+CONFIG_RT_CONSOLEBUF_SIZE=128
+CONFIG_RT_CONSOLE_DEVICE_NAME="uart0"
+# CONFIG_RT_USING_MODULE is not set
+
+#
+# RT-Thread Components
+#
+CONFIG_RT_USING_COMPONENTS_INIT=y
+CONFIG_RT_USING_USER_MAIN=y
+CONFIG_RT_MAIN_THREAD_STACK_SIZE=16384
+
+#
+# C++ features
+#
+CONFIG_RT_USING_CPLUSPLUS=y
+
+#
+# Command shell
+#
+CONFIG_RT_USING_FINSH=y
+CONFIG_FINSH_THREAD_NAME="tshell"
+CONFIG_FINSH_USING_HISTORY=y
+CONFIG_FINSH_HISTORY_LINES=5
+CONFIG_FINSH_USING_SYMTAB=y
+CONFIG_FINSH_USING_DESCRIPTION=y
+CONFIG_FINSH_THREAD_PRIORITY=20
+CONFIG_FINSH_THREAD_STACK_SIZE=4096
+CONFIG_FINSH_CMD_SIZE=80
+# CONFIG_FINSH_USING_AUTH is not set
+CONFIG_FINSH_USING_MSH=y
+CONFIG_FINSH_USING_MSH_DEFAULT=y
+# CONFIG_FINSH_USING_MSH_ONLY is not set
+
+#
+# Device virtual file system
+#
+CONFIG_RT_USING_DFS=y
+CONFIG_DFS_USING_WORKDIR=y
+CONFIG_DFS_FILESYSTEMS_MAX=9
+CONFIG_DFS_FILESYSTEM_TYPES_MAX=9
+CONFIG_DFS_FD_MAX=16
+CONFIG_RT_USING_DFS_ELMFAT=y
+
+#
+# elm-chan's FatFs, Generic FAT Filesystem Module
+#
+CONFIG_RT_DFS_ELM_CODE_PAGE=437
+CONFIG_RT_DFS_ELM_WORD_ACCESS=y
+CONFIG_RT_DFS_ELM_USE_LFN_0=y
+# CONFIG_RT_DFS_ELM_USE_LFN_1 is not set
+# CONFIG_RT_DFS_ELM_USE_LFN_2 is not set
+# CONFIG_RT_DFS_ELM_USE_LFN_3 is not set
+CONFIG_RT_DFS_ELM_USE_LFN=0
+CONFIG_RT_DFS_ELM_MAX_LFN=255
+CONFIG_RT_DFS_ELM_DRIVES=2
+CONFIG_RT_DFS_ELM_MAX_SECTOR_SIZE=4096
+# CONFIG_RT_DFS_ELM_USE_ERASE is not set
+CONFIG_RT_DFS_ELM_REENTRANT=y
+CONFIG_RT_USING_DFS_DEVFS=y
+# CONFIG_RT_USING_DFS_NET is not set
+# CONFIG_RT_USING_DFS_ROMFS is not set
+# CONFIG_RT_USING_DFS_RAMFS is not set
+# CONFIG_RT_USING_DFS_UFFS is not set
+CONFIG_RT_USING_DFS_JFFS2=y
+CONFIG_RT_USING_DFS_NFS=y
+CONFIG_RT_NFS_HOST_EXPORT="192.168.10.82:/"
+
+#
+# Device Drivers
+#
+CONFIG_RT_USING_DEVICE_IPC=y
+CONFIG_RT_USING_SERIAL=y
+# CONFIG_RT_USING_CAN is not set
+# CONFIG_RT_USING_HWTIMER is not set
+# CONFIG_RT_USING_CPUTIME is not set
+CONFIG_RT_USING_I2C=y
+CONFIG_RT_USING_I2C_BITOPS=y
+CONFIG_RT_USING_PIN=y
+CONFIG_RT_USING_MTD_NOR=y
+# CONFIG_RT_USING_MTD_NAND is not set
+# CONFIG_RT_USING_RTC is not set
+CONFIG_RT_USING_SDIO=y
+CONFIG_RT_USING_SPI=y
+# CONFIG_RT_USING_SPI_MSD is not set
+# CONFIG_RT_USING_SFUD is not set
+# CONFIG_RT_USING_W25QXX is not set
+# CONFIG_RT_USING_GD is not set
+# CONFIG_RT_USING_ENC28J60 is not set
+# CONFIG_RT_USING_SPI_WIFI is not set
+CONFIG_RT_USING_WDT=y
+# CONFIG_RT_USING_WIFI is not set
+
+#
+# Using USB
+#
+# CONFIG_RT_USING_USB_HOST is not set
+# CONFIG_RT_USING_USB_DEVICE is not set
+
+#
+# POSIX layer and C standard library
+#
+CONFIG_RT_USING_LIBC=y
+CONFIG_RT_USING_PTHREADS=y
+# CONFIG_RT_USING_POSIX is not set
+
+#
+# Network stack
+#
+
+#
+# light weight TCP/IP stack
+#
+CONFIG_RT_USING_LWIP=y
+# CONFIG_RT_USING_LWIP141 is not set
+CONFIG_RT_USING_LWIP202=y
+# CONFIG_RT_USING_LWIP_IPV6 is not set
+CONFIG_RT_LWIP_IGMP=y
+CONFIG_RT_LWIP_ICMP=y
+# CONFIG_RT_LWIP_SNMP is not set
+CONFIG_RT_LWIP_DNS=y
+CONFIG_RT_LWIP_DHCP=y
+CONFIG_IP_SOF_BROADCAST=1
+CONFIG_IP_SOF_BROADCAST_RECV=1
+
+#
+# Static IPv4 Address
+#
+CONFIG_RT_LWIP_IPADDR="192.168.1.30"
+CONFIG_RT_LWIP_GWADDR="192.168.1.1"
+CONFIG_RT_LWIP_MSKADDR="255.255.255.0"
+CONFIG_RT_LWIP_UDP=y
+CONFIG_RT_LWIP_TCP=y
+# CONFIG_RT_LWIP_RAW is not set
+# CONFIG_RT_LWIP_PPP is not set
+CONFIG_RT_MEMP_NUM_NETCONN=64
+CONFIG_RT_LWIP_PBUF_NUM=16
+CONFIG_RT_LWIP_RAW_PCB_NUM=10
+CONFIG_RT_LWIP_UDP_PCB_NUM=64
+CONFIG_RT_LWIP_TCP_PCB_NUM=8
+CONFIG_RT_LWIP_TCP_SEG_NUM=256
+CONFIG_RT_LWIP_TCP_SND_BUF=12040
+CONFIG_RT_LWIP_TCP_WND=11680
+CONFIG_RT_LWIP_TCPTHREAD_PRIORITY=100
+CONFIG_RT_LWIP_TCPTHREAD_MBOX_SIZE=32
+CONFIG_RT_LWIP_TCPTHREAD_STACKSIZE=32768
+CONFIG_RT_LWIP_ETHTHREAD_PRIORITY=126
+CONFIG_RT_LWIP_ETHTHREAD_STACKSIZE=1024
+CONFIG_RT_LWIP_ETHTHREAD_MBOX_SIZE=32
+CONFIG_RT_LWIP_REASSEMBLY_FRAG=y
+CONFIG_LWIP_NETIF_STATUS_CALLBACK=1
+CONFIG_SO_REUSE=1
+CONFIG_LWIP_SO_RCVTIMEO=1
+CONFIG_LWIP_SO_SNDTIMEO=1
+CONFIG_LWIP_SO_RCVBUF=1
+# CONFIG_RT_LWIP_NETIF_LOOPBACK is not set
+CONFIG_LWIP_NETIF_LOOPBACK=0
+
+#
+# Modbus master and slave stack
+#
+# CONFIG_RT_USING_MODBUS is not set
+CONFIG_LWIP_USING_DHCPD=y
+
+#
+# RT-Thread UI Engine
+#
+# CONFIG_RT_USING_GUIENGINE is not set
+
+#
+# VBUS(Virtual Software BUS)
+#
+# CONFIG_RT_USING_VBUS is not set
+
+#
+# Utilities
+#
+# CONFIG_RT_USING_LOGTRACE is not set
+# CONFIG_RT_USING_RYM is not set
+
+#
+# RT-Thread online packages
+#
+
+#
+# system packages
+#
+# CONFIG_PKG_USING_PARTITION is not set
+# CONFIG_PKG_USING_SQLITE is not set
+# CONFIG_PKG_USING_RTI is not set
+
+#
+# IoT - internet of things
+#
+# CONFIG_PKG_USING_PAHOMQTT is not set
+# CONFIG_PKG_USING_WEBCLIENT is not set
+# CONFIG_PKG_USING_MONGOOSE is not set
+# CONFIG_PKG_USING_WEBTERMINAL is not set
+# CONFIG_PKG_USING_CJSON is not set
+# CONFIG_PKG_USING_LJSON is not set
+# CONFIG_PKG_USING_EZXML is not set
+# CONFIG_PKG_USING_NANOPB is not set
+# CONFIG_PKG_USING_GAGENT_CLOUD is not set
+
+#
+# Wi-Fi
+#
+
+#
+# Marvell WiFi
+#
+# CONFIG_PKG_USING_WLANMARVELL is not set
+
+#
+# Wiced WiFi
+#
+# CONFIG_PKG_USING_WLAN_WICED is not set
+# CONFIG_PKG_USING_COAP is not set
+# CONFIG_PKG_USING_NOPOLL is not set
+
+#
+# security packages
+#
+# CONFIG_PKG_USING_MBEDTLS is not set
+# CONFIG_PKG_USING_libsodium is not set
+# CONFIG_PKG_USING_TINYCRYPT is not set
+
+#
+# language packages
+#
+# CONFIG_PKG_USING_JERRYSCRIPT is not set
+# CONFIG_PKG_USING_MICROPYTHON is not set
+
+#
+# multimedia packages
+#
+# CONFIG_PKG_USING_OPENMV is not set
+
+#
+# tools packages
+#
+# CONFIG_PKG_USING_CMBACKTRACE is not set
+# CONFIG_PKG_USING_EASYLOGGER is not set
+# CONFIG_PKG_USING_SYSTEMVIEW is not set
+# CONFIG_PKG_USING_IPERF is not set
+
+#
+# miscellaneous packages
+#
+# CONFIG_PKG_USING_FASTLZ is not set
+# CONFIG_PKG_USING_MINILZO is not set
+
+#
+# example package: hello
+#
+# CONFIG_PKG_USING_HELLO is not set
+
+# CONFIG_SOC_GK7101 is not set
+# CONFIG_SOC_GK7102 is not set
+# CONFIG_SOC_GK7101S is not set
+# CONFIG_SOC_GK7102S is not set
+CONFIG_SOC_GK7102C=y
+CONFIG_BOARD_GK7102C_EVB=y
+CONFIG_SENSOR_TYPE_SC1135=y
+# CONFIG_SENSOR_TYPE_SC1145 is not set
+# CONFIG_SENSOR_TYPE_JXH65 is not set
+# CONFIG_SENSOR_TYPE_OV9750 is not set
+# CONFIG_SENSOR_TYPE_AR0130 is not set
+# CONFIG_SENSOR_TYPE_JXH42 is not set
+CONFIG_TUNNING_TOOL_SUPPORT=y
+CONFIG_RT_USING_DMA_MEM=y
+CONFIG_ARM1176_USE_VFP=y
+CONFIG_RT_USING_VFP=y
+CONFIG_RT_USING_CPU_FFS=y
+
+#
+# Goke Peripheral Device Config
+#
+CONFIG_RT_USING_ADC=y
+CONFIG_RT_USING_GMAC=y
+CONFIG_RT_USING_PWM=y
+CONFIG_RT_USING_GK_DMA=y
+CONFIG_RT_USING_LIBZ=y
+CONFIG_RT_USING_LOGCAPTURE=y
+CONFIG_RT_ALIGN_UC_SIZE=8
+CONFIG_RT_ALIGN_DSP_SIZE=32
+CONFIG_RT_DEBUG_UC_MEM=0
+CONFIG_RT_DEBUG_DSP_MEM=0

+ 134 - 0
bsp/gkipc/Kconfig

@@ -0,0 +1,134 @@
+mainmenu "RT-Thread Configuration"
+
+config $BSP_DIR
+    string
+    option env="BSP_ROOT"
+    default "."
+
+config $RTT_DIR
+    string
+    option env="RTT_ROOT"
+    default "../.."
+
+config $PKGS_DIR
+    string
+    option env="PKGS_ROOT"
+    default "packages"
+
+source "$RTT_DIR/Kconfig"
+source "$PKGS_DIR/Kconfig"
+
+
+choice
+    prompt "Device type"
+    default GK7102C
+    config SOC_GK7101
+        bool "GK7101"
+    config SOC_GK7102
+        bool "GK7102"
+    config SOC_GK7101S
+        bool "GK7101S"
+    config SOC_GK7102S
+        bool "GK7102S"
+    config SOC_GK7102C
+        bool "GK7102C"
+endchoice
+
+choice
+    prompt "Board type"
+    default GK7102C_EVB
+    config BOARD_GK7101_EVB
+        bool "GK7101_EVB"
+        depends on SOC_GK7101
+    config BOARD_GK7101_EVB
+        bool "GK7101_EVB"
+        depends on SOC_GK7102
+    config BOARD_GK7101S_EVB
+        bool "GK7101S_EVB"
+        depends on SOC_GK7101S
+    config BOARD_GK7101S_EVB
+        bool "GK7101S_EVB"
+        depends on SOC_GK7102S
+    config BOARD_GK7102C_EVB
+        bool "GK7102C_EVB"
+        depends on SOC_GK7102C
+endchoice
+
+choice
+    prompt "Sensor type"
+    default SENSOR_TYPE_SC1135
+    config SENSOR_TYPE_SC1135
+        bool "SC1135"
+    config SENSOR_TYPE_SC1145
+        bool "SC1145"
+    config SENSOR_TYPE_JXH65
+        bool "JXH65"
+    config SENSOR_TYPE_OV9750
+        bool "OV9750"
+    config SENSOR_TYPE_AR0130
+        bool "AR0130"
+    config SENSOR_TYPE_JXH42
+        bool "JXH42"
+endchoice
+
+config TUNNING_TOOL_SUPPORT
+    bool "Using Tuning Tool"
+    default y
+    
+config RT_USING_DMA_MEM
+    bool "Enable DMA Mem"
+    default y  
+
+config ARM1176_USE_VFP
+    bool "Enable ARM1176 VFP"
+    default y  
+    
+config RT_USING_VFP
+    bool "Enable VFP"
+    default y  
+
+config RT_USING_CPU_FFS
+    bool "Enable CPU FFS"
+    default y
+      
+menu "Goke Peripheral Device Config"
+    config RT_USING_ADC
+        bool "Enable ADC"
+        default y    
+ 
+    config RT_USING_GMAC
+        bool "Enable GMAC"
+        default y     
+
+    config RT_USING_PWM
+        bool "Enable PWM"
+        default y    
+  
+    config RT_USING_GK_DMA
+        bool "Enable DMA"
+        default y    
+        
+    config RT_USING_LIBZ
+        bool "Enable Zlib for firmware uncompress"
+        default y  
+        
+    config RT_USING_LOGCAPTURE
+        bool "Enable DSP Logcaputure"
+        default y
+        
+    config RT_ALIGN_UC_SIZE
+        int "Align UC Size"
+        default 8
+    
+    config RT_ALIGN_DSP_SIZE
+        int "Align DSP Size"
+        default 32
+        
+    config RT_DEBUG_UC_MEM
+        int "Debug UC Memory"
+        default 0
+    
+    config RT_DEBUG_DSP_MEM
+        int "Debug DSP Memory"
+        default 0
+endmenu 

+ 61 - 0
bsp/gkipc/README.md

@@ -0,0 +1,61 @@
+# gkipc板级支持包
+
+标签: bsp说明文档
+
+---
+
+## 1. 简介
+
+GK7102C是针对高清IP Camera产品开发的一款低功耗高性能 SOC芯片,支持 960@30p多路码流 H.264 编码及高质量的 ISP 处理,内置  3D降噪和动态对比度提升模块,支持主流的多种并口 8bit/10bit/12bit sensor。视频输出支持 RGB 小型 LCD 屏显示接口。 GK7102C 内封 DDR2 DRAM 芯片,内置 Ethernet PHY, Audio codec,USB PHY 等模拟 IP。 GK7102C 拥有
+丰富的外设接口,如 USB2.0,SDIO,PWM,SPI,I2C 等等,支持最多 32 个GPIO,可灵活配置各功能模块的输出管脚,为实现高集成度 IPC提供了高性价比的解决方案。包括如下硬件特性:
+
+| 硬件 | 描述 |
+| -- | -- |
+|芯片型号| GK7102C |
+|CPU| ARM1176ZJFS |
+|主频| 432MHz |
+|片内DDR2|  512M bit@800MHz |
+
+
+## 2. 编译说明
+
+推荐使用[env工具][1],可以在console下进入到`bsp/gkipc`目录中,运行以下命令:
+
+    scons
+
+来编译这个板级支持包。如果编译正确无误,会产生rtthread.elf、rtthread.bin文件。其中rtthread.bin可以通过网络加载或者烧写到设备中进行运行。
+
+## 3. 烧写及执行
+
+[需要说明电源连接情况,串口连接情况]
+
+连接好串口,可以使用115200-N-8-1的配置方式连接到设备上。设备使用的串口引脚是:`[GPIO25/GPIO26]`
+
+当正确编译产生出rtthread.bin映像文件后,可以使用tftp的方式来加载到设备中运行。
+
+### 3.1 运行结果
+
+如果编译 & 烧写无误,当复位设备后,会在串口上看到RT-Thread的启动logo信息:
+
+## 4. 驱动支持情况及计划
+
+| 驱动 | 支持情况  |  备注  |
+| ------ | ----  | :------:  |
+| UART | 支持 | UART0/1/2 |
+| clock | 支持 |  |
+| SPI |  | SPI0 |
+| ADC | 支持 |  |
+| DMA | 支持 |  |
+| GMAC | 支持 |  |
+| I2C | 支持 |  |
+| PWM | 支持 |  |
+| SDIO | 支持 | SDIO0/1 |
+| WDT | 支持 |  |
+| MMC | 支持 |  |
+| SSI | 支持 |  |
+
+## 5. 联系人信息
+
+维护人:gokemicro < gokemicro@yeah.net >
+
+[1]: https://www.rt-thread.org/page/download.html

+ 19 - 0
bsp/gkipc/SConscript

@@ -0,0 +1,19 @@
+# for module compiling
+import os
+Import('RTT_ROOT')
+
+cwd = str(Dir('#'))
+objs = []
+list = os.listdir(cwd)
+
+print('------------------------------------------------')
+print('rtt_root:    ' + RTT_ROOT)
+print('current dir: ' + cwd)
+print('------------------------------------------------')
+
+for d in list:
+    path = os.path.join(cwd, d)
+    if os.path.isfile(os.path.join(path, 'SConscript')):
+        objs = objs + SConscript(os.path.join(d, 'SConscript'))
+
+Return('objs')

+ 33 - 0
bsp/gkipc/SConstruct

@@ -0,0 +1,33 @@
+import os
+import sys
+import rtconfig
+
+if os.getenv('RTT_ROOT'):
+    RTT_ROOT = os.getenv('RTT_ROOT')
+else:
+    RTT_ROOT = os.path.normpath(os.getcwd() + '/../..')
+
+sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')]
+from building import *
+
+TARGET = rtconfig.OUTPUT_NAME + rtconfig.TARGET_EXT
+
+# add rtconfig.h path to the assembler
+rtconfig.AFLAGS += ' -I' + str(Dir('#')) +' -I' + str(Dir('#')) + '/bsp'
+
+env = Environment(tools = ['mingw'],
+        AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS,
+        CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS,
+        CXX = rtconfig.CXX, CXXFLAGS = rtconfig.CXXFLAGS,
+        AR = rtconfig.AR, ARFLAGS = '-rc',
+        LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS)
+env.PrependENVPath('PATH', rtconfig.EXEC_PATH)
+
+Export('RTT_ROOT')
+Export('rtconfig')
+
+# prepare building environment
+objs = PrepareBuilding(env, RTT_ROOT, has_libcpu=True)
+
+# make a building
+DoBuilding(TARGET, objs)

+ 10 - 0
bsp/gkipc/applications/SConscript

@@ -0,0 +1,10 @@
+from building import *
+
+cwd = GetCurrentDir()
+src = Glob('*.c')
+
+CPPPATH = [cwd, cwd + '/../drivers', cwd + '/../libraries/inc']
+
+group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')

+ 41 - 0
bsp/gkipc/applications/main.c

@@ -0,0 +1,41 @@
+/*
+ * File      : main.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2017, RT-Thread Develop Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+#include <rtthread.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef RT_USING_GMAC
+#include <drv_gmac.h>
+#endif
+
+int main(void)
+{
+#ifdef RT_USING_GMAC
+    rt_app_gk_gmac_init();
+#endif
+
+    printf("Hello\n");
+
+    return 0;
+}

+ 10 - 0
bsp/gkipc/armv6/SConscript

@@ -0,0 +1,10 @@
+from building import *
+
+cwd = GetCurrentDir()
+src	= Glob('*.c')
+src += Glob('*.s')
+path = [cwd, cwd + '../../../include', cwd + '/../libraries/inc', cwd + '/../drivers']
+
+group = DefineGroup('armv6', src, depend = [''], CPPPATH = path)
+
+Return('group')

+ 376 - 0
bsp/gkipc/armv6/arm1176_mmu.gcc.s

@@ -0,0 +1,376 @@
+@*******************************************************************************
+@*******************************************************************************
+@**
+@** Filename...: src/arm1176_mmu.gcc.s
+@** Source.....: src/arm1176_mmu.s
+@** Generator..: asm2gas.pl
+@** Note.......: DO NOT MODIFY THIS FILE BY HAND!
+@**
+@*******************************************************************************
+@*******************************************************************************
+
+@*******************************************************************************
+@*******************************************************************************
+@**
+@** ARM1176 Startup, MMU initialization and data cache setup
+@**
+@** This module initialized the MMU in flat memory mode, all addresses are
+@** directly mapped, vitual addresses are equal to physical addresses. The
+@** MMU is required only to enable the cache mode of dedicated memory
+@** regions.
+@**
+@** Version: $Id: arm1176_mmu.gcc.s 9143 2012-04-25 09:33:55Z jrende $
+@**
+@** (C) Copyright 2012-2013 by Goke Microelectronics Shanghai Branch**
+@*******************************************************************************
+@*******************************************************************************
+
+    .text
+    .section ".ARM1176INIT"
+    .align 8
+
+    .extern _start
+    .extern _end_readonly
+    .extern |_start|
+    .extern |ARM1176_MMU_ttb0|
+    .extern |ARM1176_MMU_ttb1|
+	
+    .equ ARM1176_PHYSICAL_TTB0_BASE,      arm1176_mmu_ttb0 
+    .equ ARM1176_PHYSICAL_TTB1_BASE,      arm1176_mmu_ttb1 
+    .equ ARM1176_TTB_ENTRIES,             4096 
+
+    .if CPU_USE_GK710XS==1
+    .equ ARM1176_PHYSICAL_PERI_BASE,       0x90000000 
+    .else
+    .equ ARM1176_PHYSICAL_PERI_BASE,       0x60000000 
+    .endif
+    .equ ARM1176_PHYSICAL_PERI_SIZE,       0x20000000 
+    .equ ARM1176_REMAPPED_PERI_BASE,       ARM1176_PHYSICAL_PERI_BASE 
+
+    .equ ARM1176_PHYSICAL_PPM_BASE,        DDR_MEMORY_PPM_BASE 
+    .equ ARM1176_PHYSICAL_PPM_SIZE,        DDR_MEMORY_PPM_SIZE 
+    .equ ARM1176_REMAPPED_PPM_BASE,        ARM1176_PHYSICAL_PPM_BASE
+	
+    .equ ARM1176_PHYSICAL_RTOS_BASE,       DDR_MEMORY_OS_BASE 
+    .equ ARM1176_PHYSICAL_RTOS_SIZE,       DDR_MEMORY_OS_SIZE
+    .equ ARM1176_REMAPPED_RTOS_BASE,       ARM1176_PHYSICAL_RTOS_BASE
+
+@  use mmu map bsb address from 0xCxxxxxxx(DDR_MEMORY_BSB_BASE) to 0xD0000000|DDR_MEMORY_BSB_BASE
+    .equ ARM1176_PHYSICAL_BSB_REAMP_BASE,   0xD0000000
+    .equ ARM1176_PHYSICAL_BSB_BASE,        DDR_MEMORY_BSB_BASE
+    .equ ARM1176_PHYSICAL_BSB_SIZE,        DDR_MEMORY_BSB_SIZE 
+    .equ ARM1176_REMAPPED_BSB_BASE,        ARM1176_PHYSICAL_BSB_BASE|ARM1176_PHYSICAL_BSB_REAMP_BASE
+
+@  use mmu remap bsb address 0xCxxxxxxx(DDR_MEMORY_BSB_BASE) to ARM1176_REMAPPED_BSB_BASE+DDR_MEMORY_BSB_SIZE, it resolve bsb data revert.
+    .equ ARM1176_PHYSICAL_BSB_BASE,        DDR_MEMORY_BSB_BASE
+    .equ ARM1176_PHYSICAL_BSB_SIZE,        DDR_MEMORY_BSB_SIZE 
+    .equ ARM1176_REMAPPED_BSB_BASE_EXT,    ARM1176_REMAPPED_BSB_BASE+DDR_MEMORY_BSB_SIZE
+	
+	.equ ARM1176_PHYSICAL_DSP_BASE,        DDR_MEMORY_DSP_BASE 
+    .equ ARM1176_PHYSICAL_DSP_SIZE,        DDR_MEMORY_DSP_SIZE 
+    .equ ARM1176_REMAPPED_DSP_BASE,        ARM1176_PHYSICAL_DSP_BASE 
+	
+    .equ ARM1176_1MB_CACHE_NOBUFFER,      0x00000DEA  @ cachable/non-bufferable
+    .equ ARM1176_1MB_CACHE_BUFFER,        0x00000DEE  @ cachable/bufferable
+    .equ ARM1176_1MB_NOCACHE_NOBUFFER,    0x00000DE2  @ non-cachable/non-bufferable
+    .equ ARM1176_1MB_NORMAL_NOCACHE,      0x00001DE2  @ Normal memory, non-cachable/non-bufferable
+    .equ ARM1176_1MB_CACHE_BUFFER_RO,     0x000011EE  @ cachable/bufferable read-only
+    .equ ARM1176_1MB_NOCACHE_NOBUFFER_RO, 0x000011E2  @ non-cachable/non-bufferable read-only
+
+@*******************************************************************************
+@** Initialise the MMU
+@*******************************************************************************
+
+    .global ARM1176_MmuInitialise
+
+ARM1176_MmuInitialise:
+
+@*******************************************************************************
+@** save link register on r11 as we are using bl commands internally
+@*******************************************************************************
+
+    mov r11,lr
+
+@*******************************************************************************
+@** if MMU/MPU enabled - disable (useful for ARMulator tests)
+@*******************************************************************************
+
+    mrc p15,0,r0,c1,c0,0 @ read CP15 register 1 into r0
+    bic r0,r0,#0x1000    @ disable I-cache
+    bic r0,r0,#0x0004    @ disable D-cache
+    bic r0,r0,#0x0001    @ disable MMU
+    mcr p15,0,r0,c1,c0,0 @ write value back
+
+@*******************************************************************************
+@** MMU Configuration
+@**
+@** Configure system to use extended v6 format pagetables
+@** Set translation table base
+@** Specify v6 format pagetables with no subpages
+@** set bit 23 [XP] in CP15 control register.
+@** ARM1176 supports two translation tables
+@** Configure translation table base (TTB) control register cp15,c2
+@** to a value of all zeros, indicates we are using TTB register 0.
+@*******************************************************************************
+
+    mrc p15,0,r0,c1,c0,0 @ read CP15 register 1 into r0
+    mov r1,#0x800000
+    orr r0,r0,r1	 @ disable Subpage AP bits
+    mcr p15,0,r0,c1,c0,0 @ write value back
+    mov r0,#0x0
+    mcr p15,0,r0,c2,c0,2 @ Write Translation Table Base Control Register to 0, use Register 0
+    ldr r0,ARM1176_PHYSICAL_TTB0_BASE
+    mcr p15,0,r0,c2,c0,0 @ Write Translation Table Base Register 0 to ARM1176_PHYSICAL_TTB0_BASE
+
+@*******************************************************************************
+@** PAGE TABLE generation
+@**
+@** Generate the page tables
+@** Build a flat translation table for the whole address space.
+@** ie: Create 4096 1MB sections from 0x000xxxxx to 0xFFFxxxxx
+@**
+@** |31................20|19..18|17|16| 15|14..12|11.10|9|8....5| 4|3.2|1.0|
+@** |section base address| 0   0|nG| S|APX|   TEX|  AP |P|Domain|XN|C B|1 0|
+@**
+@** Bits[31:20] Top 12 bits of VA is pointer into table
+@** nG[17]=0.   Non global, enables matching against ASID in the TLB when set.
+@** S[16]=0.    Indicates normal memory is shared when set.
+@** Access Permissions - configure for full read/write access in all modes
+@** APX[15]=0 and AP[11:10]=11
+@**
+@** Set attributes to normal memory, non cacheable.
+@** TEX[14:12]=001 and CB[3:2]= 00
+@** P[9]=0.     ECC enabled memory (not supported on ARM1136).
+@** Domain[5:8]=1111 = Set all pages to use domain 15
+@** XN[4]:=0    Execute never disabled.
+@** Bits[1:0]   Indicate entry is a 1MB section.
+@**
+@** r0 contains the address of the translation table base
+@** r1 is loop counter
+@** r2 is level1 descriptor (bits 19:0)
+@**
+@** use loop counter to create 4096 individual table entries
+@** this writes from address 0x7FFC down to 0x4000 in word steps (4bytes).
+@**
+@** In this example we will set the cacheable attribute in the first descriptor
+@**  only, so virtual memory from 0 to 1MB will be cacheable (write back mode).
+@** TEX[14:12]=000 and CB[3:2]=11
+@*******************************************************************************
+
+@*******************************************************************************
+@** create empty TTB entries to initialize entries 0..2047
+@** r0 = TTB base address
+@** r1 = unused
+@** r2 = unused
+@** r3 = virtual DDR address, upper 12 bits shifted 20 bits right (virt. index)
+@** r4 = remap size upper 12 bits shifted 20 bits right (table max. index)
+@** r5 = unused
+@*******************************************************************************
+
+    ldr r0,ARM1176_PHYSICAL_TTB0_BASE       @ set the MMU table base address
+    ldr r1,=0x00000000                      @ 0x00000000 == disable access
+    ldr r2,=0x00000000                      @ remap addresses from 0x00000000..
+    ldr r3,=0x00000000                      @                   to 0x00000000..
+    ldr r4,=0x80000000                      @ fixed remap RAM size (2048MB)
+    bl  arm1176_update_mmu_table            @ update mmu table entries
+
+@*******************************************************************************
+@** set the peri
+@*******************************************************************************
+
+    ldr r0,ARM1176_PHYSICAL_TTB0_BASE
+    ldr r1,=ARM1176_1MB_NOCACHE_NOBUFFER
+    ldr r2,=ARM1176_PHYSICAL_PERI_BASE
+    ldr r3,=ARM1176_REMAPPED_PERI_BASE
+    ldr r4,=ARM1176_PHYSICAL_PERI_SIZE
+    bl  arm1176_update_mmu_table
+
+@*******************************************************************************
+@** set the ppm
+@*******************************************************************************
+
+    ldr r0,ARM1176_PHYSICAL_TTB0_BASE
+    ldr r1,=ARM1176_1MB_NOCACHE_NOBUFFER
+    ldr r2,=ARM1176_PHYSICAL_PPM_BASE
+    ldr r3,=ARM1176_REMAPPED_PPM_BASE
+    ldr r4,=ARM1176_PHYSICAL_PPM_SIZE
+    bl  arm1176_update_mmu_table
+	
+@*******************************************************************************
+@** set the rtos (nocache_section(1M)/code_heap(RTOSSIZE-1M))
+@*******************************************************************************
+
+    ldr r0,ARM1176_PHYSICAL_TTB0_BASE
+    ldr r1,=ARM1176_1MB_NOCACHE_NOBUFFER
+    ldr r2,=ARM1176_PHYSICAL_RTOS_BASE
+    ldr r3,=ARM1176_REMAPPED_RTOS_BASE
+    ldr r4,=0x200000
+    bl  arm1176_update_mmu_table
+
+    ldr r0,ARM1176_PHYSICAL_TTB0_BASE
+    ldr r1,=ARM1176_1MB_CACHE_BUFFER
+    ldr r2,=ARM1176_PHYSICAL_RTOS_BASE+0x100000
+    ldr r3,=ARM1176_REMAPPED_RTOS_BASE+0x100000
+    ldr r4,=ARM1176_PHYSICAL_RTOS_SIZE-0x100000
+    bl  arm1176_update_mmu_table
+
+@*******************************************************************************
+@** set the bsb
+@*******************************************************************************
+
+    ldr r0,ARM1176_PHYSICAL_TTB0_BASE
+    ldr r1,=ARM1176_1MB_CACHE_BUFFER
+    ldr r2,=ARM1176_PHYSICAL_BSB_BASE
+    ldr r3,=ARM1176_REMAPPED_BSB_BASE
+    ldr r4,=ARM1176_PHYSICAL_BSB_SIZE
+    bl  arm1176_update_mmu_table
+
+@*******************************************************************************
+@** set the bsb again for continues address for frame address
+@*******************************************************************************
+    ldr r0,ARM1176_PHYSICAL_TTB0_BASE
+    ldr r1,=ARM1176_1MB_CACHE_BUFFER
+    ldr r2,=ARM1176_PHYSICAL_BSB_BASE
+    ldr r3,=ARM1176_REMAPPED_BSB_BASE_EXT
+    ldr r4,=ARM1176_PHYSICAL_BSB_SIZE
+    bl  arm1176_update_mmu_table
+	
+@*******************************************************************************
+@** set the dsp
+@*******************************************************************************
+
+    ldr r0,ARM1176_PHYSICAL_TTB0_BASE
+    ldr r1,=ARM1176_1MB_CACHE_BUFFER
+    ldr r2,=ARM1176_PHYSICAL_DSP_BASE
+    ldr r3,=ARM1176_REMAPPED_DSP_BASE
+    ldr r4,=ARM1176_PHYSICAL_DSP_SIZE
+    bl  arm1176_update_mmu_table
+	
+@*******************************************************************************
+@** copy TTB0 into TTB1
+@*******************************************************************************
+
+    ldr r0,ARM1176_PHYSICAL_TTB0_BASE
+    ldr r1,ARM1176_PHYSICAL_TTB1_BASE
+    ldr r2,=ARM1176_TTB_ENTRIES
+    bl arm1176_copy_mmu_table
+
+@*******************************************************************************
+@** Setup domain control register
+@** Enable all domains to client mode
+@*******************************************************************************
+
+    mrc p15,0,r0,c3,c0,0 @ Read Domain Access Control Register
+    ldr r0,=0x55555555   @ Initialise every domain entry to b01 (client)
+    mcr p15,0,r0,c3,c0,0 @ Write Domain Access Control Register
+
+@*******************************************************************************
+@** Now the MMU is enabled, virtual to physical address translations will occur.
+@** This will affect the next instruction fetch.
+@**
+@** The two instructions currently in the ARM pipeline will have been fetched
+@** before the MMU was enabled. This property is useful because the next two
+@** instructions are safe even if new instruction fetches fail - If this
+@** routine was mapped out of the new virtual memory map, the branch to
+@** arm1176_BootLoaderMain would still succeed.
+@*******************************************************************************
+
+    mov r0,#0             @ move 0 into r0
+    mcr p15,0,r0,c7,c5,0  @ invalidate instruction cache
+    mcr p15,0,r0,c7,c6,0  @ invalidate data cache
+    mcr p15,0,r0,c7,c10,4 @ drain write barrier
+    mcr p15,0,r0,c8,c5,0  @ reset intruction TLB entries
+    mcr p15,0,r0,c8,c6,0  @ reset data TLB entries
+    mcr p15,0,r0,c8,c7,0  @ reset unified TLB entries
+
+    mrc p15,0,r0,c1,c0,0  @ read CP15 register c1 into r0
+    orr r0,r0,#0x00001000 @ enable I-cache
+    orr r0,r0,#0x00000004 @ enable D-cache
+    orr r0,r0,#0x00000001 @ enable MMU
+    orr r0,r0,#0x00400000 @ enable unaligned load/store
+    orr r0,r0,#0x00000100 @ system bit enabled
+    bic r0,r0,#0x00000200 @ rom bit disabled
+    mcr p15,0,r0,c1,c0,0  @ write r0 back to CP15 register c1
+    mov lr,r11            @ restore link register
+    bx lr                 @ branch back to caller
+
+@*******************************************************************************
+@** create TTB entries to remap 1MB junks of memory
+@** register arguments:
+@**   r0 = TTB base address
+@**   r1 = access mask, lower 20 bits only
+@**   r2 = physical address, upper 12 bits shifted 20 bits right (phys. index)
+@**   r3 = virtual address, upper 12 bits shifted 20 bits right (virt. index)
+@**   r4 = remap size upper 12 bits shifted 20 bits right (table max. index)
+@** internal used registers:
+@**   r5 = temporary vector to be written into TTB entry
+@*******************************************************************************
+
+arm1176_update_mmu_table:
+    lsr  r2,r2,#20	@ 1M
+    lsr  r3,r3,#20	@ 1M
+    lsr  r4,r4,#20	@ 1M
+    cmp  r4,#0x0
+    bxeq lr
+    add  r4,r4,r3
+arm1176_update_mmu_table_loop: @ update r4 times 1MB entries
+    orr  r5,r1,r2,LSL#20      @ r5 now contains full L1 descriptor to write
+    str  r5,[r0,r3,LSL#2]     @ store table entry at TTB base + loopcount*4
+    add  r3,r3,#1             @ increment virtual address index
+    add  r2,r2,#1             @ increment physical address index
+    cmp  r3,r4                @ check for last entry
+    bne  arm1176_update_mmu_table_loop
+    bx lr
+
+@*******************************************************************************
+@** copy one TTB into another
+@** register arguments:
+@**   r0 = address of 1st TTB
+@**   r1 = address of 2nd TTB
+@**   r2 = table entry count
+@** internal used registers:
+@**   r3 = temporary register holding read/wrrite values
+@*******************************************************************************
+
+arm1176_copy_mmu_table:
+    cmp  r2,#0x0
+    bxeq lr
+arm1176_copy_mmu_table_loop: @ load entry from 1st table
+    ldr  r3,[r0]            @ store entry into 2nd table
+    str  r3,[r1]            @ store table entry at TTB base + loopcount*4
+    add  r0,r0,#4           @ increment 1st table address by 4 byte
+    add  r1,r1,#4           @ increment 2nd table address  by 4 byte
+    sub  r2,r2,#1           @ decrement entry counter by 1
+    cmp  r2,#0x0
+    bne  arm1176_copy_mmu_table_loop
+    bx lr
+
+@*******************************************************************************
+@** local variables containing far addresses
+@*******************************************************************************
+
+    .ltorg
+
+arm1176_image_ro_base:
+    .long _start
+arm1176_image_ro_limit:
+    .long _end_readonly
+arm1176_image_start:
+    .long _start
+arm1176_mmu_ttb0:
+    .long ARM1176_MMU_ttb0
+arm1176_mmu_ttb1:
+    .long ARM1176_MMU_ttb1
+arm1176_mmu_video_cached_ptr:
+    .long arm1176_mmu_video_cached
+arm1176_mmu_video_cached:
+    .long 0x0
+
+    .global arm1176_mmu_video_cached
+    .weak arm1176_mmu_video_cached
+
+@*******************************************************************************
+@** End of file
+@*******************************************************************************
+
+    .end

+ 64 - 0
bsp/gkipc/armv6/arm1176_mmu_ttb.c

@@ -0,0 +1,64 @@
+/*
+********************************************************************************
+********************************************************************************
+**
+** \file        ./boot/startup/src/arm1176_mmu_ttb.c
+**
+** \version     $Id: arm1176_mmu_ttb.c 5280 2011-02-21 16:39:28Z wlaris $
+**
+** \brief       ARM1176 MMU page table.
+**
+** This files contains ARM1176 specific MMU page table variables.
+**
+** \attention   THIS SAMPLE CODE IS PROVIDED AS IS. GOKE SEMICONDUCTOR
+**              ACCEPTS NO RESPONSIBILITY OR LIABILITY FOR ANY ERRORS OR
+**              OMMISSIONS.
+**
+********************************************************************************
+********************************************************************************
+*/
+#include <stdint.h>
+#include "arm1176_mmu_ttb.h"
+
+#define ARM1176_MMU_TTB_ALIGNMENT 14
+#define ARM1176_RVS_ALIGN(bits) __align(1UL<<bits)
+#define ARM1176_GCC_ALIGN(bits) __attribute__((aligned(1UL<<bits)))
+
+#if !defined(__GNUC__)
+#define ARM1176_MMU_ALIGN_PRE ARM1176_RVS_ALIGN(ARM1176_MMU_TTB_ALIGNMENT)
+#endif
+
+#if defined(__GNUC__)
+#define ARM1176_MMU_ALIGN_POST ARM1176_GCC_ALIGN(ARM1176_MMU_TTB_ALIGNMENT)
+#endif
+
+#if defined(__LINT__)
+#undef ARM1176_RVS_ALIGN
+#define ARM1176_RVS_ALIGN(bits)
+#undef ARM1176_GCC_ALIGN
+#define ARM1176_GCC_ALIGN(bits)
+#endif
+
+/*lint -save -e785 */
+
+#if !defined(__GNUC__)
+
+    ARM1176_RVS_ALIGN(ARM1176_MMU_TTB_ALIGNMENT)
+    uint32_t ARM1176_MMU_ttb0[ARM1176_MMU_TTB_ENTRIES] __attribute__ ((section(".nocache_buffer"))) = { 0x000011E2UL };
+
+    ARM1176_RVS_ALIGN(ARM1176_MMU_TTB_ALIGNMENT)
+    uint32_t ARM1176_MMU_ttb1[ARM1176_MMU_TTB_ENTRIES] __attribute__ ((section(".nocache_buffer"))) = { 0x000011E2UL };
+
+#endif
+
+#if defined(__GNUC__)
+
+    uint32_t ARM1176_MMU_ttb0[ARM1176_MMU_TTB_ENTRIES]
+    ARM1176_GCC_ALIGN(ARM1176_MMU_TTB_ALIGNMENT) __attribute__ ((section(".nocache_buffer"))) = { 0x000011E2UL };
+
+    uint32_t ARM1176_MMU_ttb1[ARM1176_MMU_TTB_ENTRIES]
+    ARM1176_GCC_ALIGN(ARM1176_MMU_TTB_ALIGNMENT) __attribute__ ((section(".nocache_buffer"))) = { 0x000011E2UL };
+
+#endif
+
+/*lint -restore */

+ 34 - 0
bsp/gkipc/armv6/arm1176_mmu_ttb.h

@@ -0,0 +1,34 @@
+/*
+********************************************************************************
+********************************************************************************
+**
+** \file        ./boot/startup/src/arm1176_mmu_ttb.h
+**
+** \version     $Id: arm1176_mmu_ttb.h 5280 2011-02-21 16:39:28Z wlaris $
+**
+** \brief       ARM1176 MMU page table.
+**
+** This files contains ARM1176 specific MMU page table variables.
+**
+** \attention   THIS SAMPLE CODE IS PROVIDED AS IS. GOKE SEMICONDUCTOR
+**              ACCEPTS NO RESPONSIBILITY OR LIABILITY FOR ANY ERRORS OR
+**              OMMISSIONS.
+**
+********************************************************************************
+********************************************************************************
+*/
+#ifndef STARTUP_ARM1176_MMU_TTB_H
+#define STARTUP_ARM1176_MMU_TTB_H
+
+#define ARM1176_MMU_TTB_ENTRIES 4096
+
+#define ARM1176_MMU_TTB_NUMS    8
+
+#define ARM1176_1MB_NOCACHE_BUFFER      0x00000DE6  // non-cachable/bufferable
+#define ARM1176_1MB_CACHE_NOBUFFER      0x00000DEA  // cachable/non-bufferable
+#define ARM1176_1MB_CACHE_BUFFER        0x00000DEE  // cachable/bufferable
+#define ARM1176_1MB_NOCACHE_NOBUFFER    0x00000DE2  // non-cachable/non-bufferable
+#define ARM1176_1MB_NORMAL_NOCACHE      0x00001DE2  // Normal memory, non-cachable/non-bufferable
+#define ARM1176_1MB_CACHE_BUFFER_RO     0x000011EE  // cachable/bufferable read-only
+#define ARM1176_1MB_NOCACHE_NOBUFFER_RO 0x000011E2  // non-cachable/non-bufferable read-only
+#endif

+ 62 - 0
bsp/gkipc/armv6/arm1176_vfp_fast_gcc.s

@@ -0,0 +1,62 @@
+@*******************************************************************************
+@*******************************************************************************
+@**
+@** ARM1176 Startup, VFP initialization for fast mode
+@**
+@** This module initializes the VFP co-processor unit in fast mode
+@**
+@** Version: $Id: arm1176_vfp_fast.s 5280 2011-02-21 16:39:28Z wlaris $
+@**
+@** (C) Copyright 2006-2010 by Fujitsu Microelectronics Europe GmbH;**
+@** (C) Copyright 2010-2011 by Fujitsu Semiconductor Europe GmbH
+@*******************************************************************************
+@*******************************************************************************
+#if ARM1176_USE_VFP == 1
+    .text
+    .section ".ARM1176INIT"
+    .code 32
+
+@*******************************************************************************
+@** Bit pattern to enable RunFast mode
+@** - FPSCR [24] - Flush to Zero mode
+@** - FPSCR [25] - Default NaN mode
+@*******************************************************************************
+
+    .equ ARM1176_VFP_ENABLE,   0x40000000 @
+    .equ ARM1176_VFP_FASTMODE, 0x03000000 @ 2_11:SHL:24
+
+@*******************************************************************************
+@** enable the fast-mode of the VFP block
+@*******************************************************************************
+
+    .global ARM1176_VfpSetFastmode
+
+ARM1176_VfpSetFastmode:
+    mov r0,#ARM1176_VFP_FASTMODE
+    fmxr fpscr,r0
+    bx lr
+
+@*******************************************************************************
+@** enable the the VFP block
+@*******************************************************************************
+
+    .global ARM1176_VfpInitialise
+
+ARM1176_VfpInitialise:
+    mrc p15,0,r1,c1,c0,2  @ r1 = Access Control Register
+    orr r1,r1,#(0xf<<20)  @ enable full access for p10,11
+    mcr p15,0,r1,c1,c0,2  @ Access Control Register = r1
+    mov r1,#0             @
+    mcr p15,0,r1,c7,c5,4  @ flush prefetch buffer because of FMXR below and
+                          @ CP 10 & 11 were only just enabled
+    @ Enable VFP itself
+    mov  r0,#ARM1176_VFP_ENABLE
+    fmxr fpexc,r0
+    bx   lr
+
+@*******************************************************************************
+@** End of file
+@*******************************************************************************
+
+    .end
+#endif

+ 160 - 0
bsp/gkipc/armv6/context_gcc.s

@@ -0,0 +1,160 @@
+/*
+ * File      : context.S
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2011-01-13     weety    copy from mini2440
+ */
+
+#define NOINT			0xc0
+
+.globl __delay
+__delay:
+		subs	r0, r0, #1
+#if 1
+		movls	pc, lr
+		subs	r0, r0, #1
+		movls	pc, lr
+		subs	r0, r0, #1
+		movls	pc, lr
+		subs	r0, r0, #1
+		movls	pc, lr
+		subs	r0, r0, #1
+		movls	pc, lr
+		subs	r0, r0, #1
+		movls	pc, lr
+		subs	r0, r0, #1
+		movls	pc, lr
+		subs	r0, r0, #1
+#endif
+		bhi	__delay
+		mov	pc, lr
+
+
+/*
+ * rt_base_t rt_hw_interrupt_disable();
+ */
+.globl rt_hw_interrupt_disable
+rt_hw_interrupt_disable:
+	mrs r0, cpsr
+	orr r1, r0, #NOINT
+	msr cpsr_c, r1
+	mov pc, lr
+
+/*
+ * void rt_hw_interrupt_enable(rt_base_t level);
+ */
+.globl rt_hw_interrupt_enable
+rt_hw_interrupt_enable:
+	msr cpsr, r0
+	mov pc, lr
+
+
+    .globl  restore_context
+    @.func   restore_context
+    
+    .globl  save_context
+    @.func   save_context
+
+save_context:
+    stmfd	sp!, {lr}		@ push pc (lr should be pushed in place of PC)
+	stmfd	sp!, {r0-r12, lr}	@ push lr & register file
+
+	mrs	r4, cpsr
+	stmfd	sp!, {r4}		@ push cpsr
+	mrs	r4, spsr
+	stmfd	sp!, {r4}		@ push spsr
+
+	str	sp, [r0]			@ store sp in preempted tasks TCB
+	mov pc, lr
+    bx lr                 @ branch back to caller
+
+
+restore_context:
+    ldr	sp, [r0]			@ get new task stack pointer
+
+	ldmfd	sp!, {r4}		@ pop new task spsr
+	msr	spsr_cxsf, r4
+	ldmfd	sp!, {r4}		@ pop new task cpsr
+	msr	spsr_cxsf, r4
+
+	ldmfd	sp!, {r0-r12, lr, pc}^	@ pop new task r0-r12, lr & pc
+
+    
+    
+/*
+ * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
+ * r0 --> from
+ * r1 --> to
+ */
+.globl rt_hw_context_switch
+rt_hw_context_switch:
+	stmfd	sp!, {lr}		@ push pc (lr should be pushed in place of PC)
+	stmfd	sp!, {r0-r12, lr}	@ push lr & register file
+
+	mrs	r4, cpsr
+	stmfd	sp!, {r4}		@ push cpsr
+	mrs	r4, spsr
+	stmfd	sp!, {r4}		@ push spsr
+
+	str	sp, [r0]			@ store sp in preempted tasks TCB
+	ldr	sp, [r1]			@ get new task stack pointer
+
+	ldmfd	sp!, {r4}		@ pop new task spsr
+	msr	spsr_cxsf, r4
+	ldmfd	sp!, {r4}		@ pop new task cpsr
+	msr	spsr_cxsf, r4
+
+	ldmfd	sp!, {r0-r12, lr, pc}^	@ pop new task r0-r12, lr & pc
+
+/*
+ * void rt_hw_context_switch_to(rt_uint32 to);
+ * r0 --> to
+ */
+.globl rt_hw_context_switch_to
+rt_hw_context_switch_to:
+	ldr	sp, [r0]		@ get new task stack pointer
+
+	ldmfd	sp!, {r4}		@ pop new task spsr
+	msr	spsr_cxsf, r4
+	ldmfd	sp!, {r4}		@ pop new task cpsr
+	msr	cpsr_cxsf, r4
+
+	ldmfd	sp!, {r0-r12, lr, pc}	@ pop new task r0-r12, lr & pc
+
+/*
+ * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to);
+ */
+.globl rt_thread_switch_interrupt_flag
+.globl rt_interrupt_from_thread
+.globl rt_interrupt_to_thread
+.globl rt_hw_context_switch_interrupt
+rt_hw_context_switch_interrupt:
+	ldr r2, =rt_thread_switch_interrupt_flag
+	ldr r3, [r2]
+	cmp r3, #1
+	beq _reswitch
+	mov r3, #1				@ set rt_thread_switch_interrupt_flag to 1
+	str r3, [r2]
+	ldr r2, =rt_interrupt_from_thread	@ set rt_interrupt_from_thread
+	str r0, [r2]
+_reswitch:
+	ldr r2, =rt_interrupt_to_thread		@ set rt_interrupt_to_thread
+	str r1, [r2]
+	mov pc, lr

+ 297 - 0
bsp/gkipc/armv6/cpuport.c

@@ -0,0 +1,297 @@
+/*
+ * File      : cpu.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Develop Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+
+#define ICACHE_MASK (rt_uint32_t)(1 << 12)
+#define DCACHE_MASK (rt_uint32_t)(1 << 2)
+
+extern void machine_reset(void);
+extern void machine_shutdown(void);
+
+#ifdef __GNUC__
+rt_inline rt_uint32_t cp15_rd(void)
+{
+    rt_uint32_t i;
+
+    asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
+    return i;
+}
+
+rt_inline void cache_enable(rt_uint32_t bit)
+{
+    __asm__ __volatile__(           \
+        "mrc  p15,0,r0,c1,c0,0\n\t" \
+        "orr  r0,r0,%0\n\t"         \
+        "mcr  p15,0,r0,c1,c0,0"     \
+        :                           \
+        :"r" (bit)                  \
+        :"memory");
+}
+
+rt_inline void cache_disable(rt_uint32_t bit)
+{
+    __asm__ __volatile__(           \
+        "mrc  p15,0,r0,c1,c0,0\n\t" \
+        "bic  r0,r0,%0\n\t"         \
+        "mcr  p15,0,r0,c1,c0,0"     \
+        :                           \
+        :"r" (bit)                  \
+        :"memory");
+}
+#endif
+
+#ifdef __CC_ARM
+rt_inline rt_uint32_t cp15_rd(void)
+{
+    rt_uint32_t i;
+
+    __asm
+    {
+        mrc p15, 0, i, c1, c0, 0
+    }
+
+    return i;
+}
+
+rt_inline void cache_enable(rt_uint32_t bit)
+{
+    rt_uint32_t value;
+
+    __asm
+    {
+        mrc p15, 0, value, c1, c0, 0
+        orr value, value, bit
+        mcr p15, 0, value, c1, c0, 0
+    }
+}
+
+rt_inline void cache_disable(rt_uint32_t bit)
+{
+    rt_uint32_t value;
+
+    __asm
+    {
+        mrc p15, 0, value, c1, c0, 0
+        bic value, value, bit
+        mcr p15, 0, value, c1, c0, 0
+    }
+}
+#endif
+
+/**
+ * enable I-Cache
+ *
+ */
+void rt_hw_cpu_icache_enable()
+{
+    cache_enable(ICACHE_MASK);
+}
+
+/**
+ * disable I-Cache
+ *
+ */
+void rt_hw_cpu_icache_disable()
+{
+    cache_disable(ICACHE_MASK);
+}
+
+/**
+ * return the status of I-Cache
+ *
+ */
+rt_base_t rt_hw_cpu_icache_status()
+{
+    return (cp15_rd() & ICACHE_MASK);
+}
+
+/**
+ * enable D-Cache
+ *
+ */
+void rt_hw_cpu_dcache_enable()
+{
+    cache_enable(DCACHE_MASK);
+}
+
+/**
+ * disable D-Cache
+ *
+ */
+void rt_hw_cpu_dcache_disable()
+{
+    cache_disable(DCACHE_MASK);
+}
+
+/**
+ * return the status of D-Cache
+ *
+ */
+rt_base_t rt_hw_cpu_dcache_status()
+{
+    return (cp15_rd() & DCACHE_MASK);
+}
+
+/**
+ * reset cpu by dog's time-out
+ *
+ */
+void rt_hw_cpu_reset()
+{
+
+    rt_kprintf("Restarting system...\n");
+    machine_reset();
+
+    while(1);   /* loop forever and wait for reset to happen */
+
+    /* NEVER REACHED */
+}
+
+/**
+ *  shutdown CPU
+ *
+ */
+void rt_hw_cpu_shutdown()
+{
+    rt_uint32_t level;
+    rt_kprintf("shutdown...\n");
+
+    level = rt_hw_interrupt_disable();
+    machine_shutdown();
+    while (level)
+    {
+        RT_ASSERT(0);
+    }
+}
+
+#ifdef RT_USING_CPU_FFS
+/**
+ * This function finds the first bit set (beginning with the least significant bit)
+ * in value and return the index of that bit.
+ *
+ * Bits are numbered starting at 1 (the least significant bit).  A return value of
+ * zero from any of these functions means that the argument was zero.
+ *
+ * @return return the index of the first bit set. If value is 0, then this function
+ * shall return 0.
+ */
+#if defined(__CC_ARM)
+int __rt_ffs(int value)
+{
+    register rt_uint32_t x;
+
+    if (value == 0)
+        return value;
+
+    __asm
+    {
+        rsb x, value, #0
+        and x, x, value
+        clz x, x
+        rsb x, x, #32
+    }
+
+    return x;
+}
+#elif defined(__IAR_SYSTEMS_ICC__)
+int __rt_ffs(int value)
+{
+    if (value == 0)
+        return value;
+
+    __ASM("RSB  r4, r0, #0");
+    __ASM("AND  r4, r4, r0");
+    __ASM("CLZ  r4, r4");
+    __ASM("RSB  r0, r4, #32");
+}
+#elif defined(__GNUC__)
+int __rt_ffs(int value)
+{
+    if (value == 0)
+        return value;
+
+    value &= (-value);
+    asm ("clz %0, %1": "=r"(value) :"r"(value));
+
+    return (32 - value);
+}
+#endif
+
+#endif
+
+/*
+rt_base_t rt_hw_interrupt_disable()
+{
+    unsigned long old;
+    unsigned long tmp;
+
+    __asm__ __volatile__ (
+        "mrs %0, cpsr\n"
+        "orr %1, %0, #0xc0\n"
+        "msr cpsr_c, %1"
+        : "=r" (old), "=r" (tmp)
+        :
+        : "memory");
+
+    return old;
+}
+
+void rt_hw_interrupt_enable(rt_base_t level)
+{
+    unsigned long tmp;
+
+
+    __asm__ __volatile__ (
+        "mrs %0, cpsr\n"
+        "bic %0, %0, #0xc0\n"
+        "msr cpsr_c, %0"
+        : "=r" (tmp)
+        :
+        : "memory");
+
+}
+*/
+/*
+rt_base_t rt_hw_interrupt_disable()
+{
+    unsigned long old;
+    unsigned long tmp;
+
+    __asm__ __volatile__( "mrs %0,cpsr"     : "=r"(old) : "r"(tmp) );
+    __asm__ __volatile__( "orr %0,%1,#0xC0" : "=r"(tmp) : "r"(old) );
+    __asm__ __volatile__( "msr cpsr_c,%0"   : : "r"(tmp) );
+
+    return old;
+}
+
+void rt_hw_interrupt_enable(rt_base_t level)
+{
+
+   asm volatile ( "msr cpsr_c,%0" : : "r"(level) );
+
+}
+*/
+
+/*@}*/

+ 81 - 0
bsp/gkipc/armv6/gk7101.h

@@ -0,0 +1,81 @@
+/*
+ * File      : at91sam926x.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Develop Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+
+ */
+
+#ifndef GK7101_H
+#define GK7101_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtthread.h>
+
+
+
+/*****************************/
+/* CPU Mode                  */
+/*****************************/
+#define USERMODE		0x10
+#define FIQMODE			0x11
+#define IRQMODE			0x12
+#define SVCMODE			0x13
+#define ABORTMODE		0x17
+#define UNDEFMODE		0x1b
+#define MODEMASK		0x1f
+#define NOINT			0xc0
+
+struct rt_hw_register
+{
+	rt_uint32_t r0;
+	rt_uint32_t r1;
+	rt_uint32_t r2;
+	rt_uint32_t r3;
+	rt_uint32_t r4;
+	rt_uint32_t r5;
+	rt_uint32_t r6;
+	rt_uint32_t r7;
+	rt_uint32_t r8;
+	rt_uint32_t r9;
+	rt_uint32_t r10;
+	rt_uint32_t fp;
+	rt_uint32_t ip;
+	rt_uint32_t sp;
+	rt_uint32_t lr;
+	rt_uint32_t pc;
+	rt_uint32_t cpsr;
+	rt_uint32_t ORIG_r0;
+};
+
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
+extern struct clk *clk_get(const char *id);
+extern rt_uint32_t clk_get_rate(struct clk *clk);
+extern void rt_hw_clock_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+

+ 148 - 0
bsp/gkipc/armv6/interrupt.c

@@ -0,0 +1,148 @@
+/*
+ * File      : interrupt.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+
+#include <rthw.h>
+#include "gk7101.h"
+
+#define MAX_HANDLERS    (64)
+
+extern rt_uint32_t rt_interrupt_nest;
+
+/* exception and interrupt handler table */
+struct rt_irq_desc irq_desc[MAX_HANDLERS];
+
+rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
+rt_uint32_t rt_thread_switch_interrupt_flag;
+
+
+/* --------------------------------------------------------------------
+ *  Interrupt initialization
+ * -------------------------------------------------------------------- */
+
+
+
+void rt_hw_interrupt_mask(int irq);
+void rt_hw_interrupt_umask(int irq);
+
+rt_isr_handler_t rt_hw_interrupt_handle(rt_uint32_t vector, void *param)
+{
+    rt_kprintf("Unhandled interrupt %d occured!!!\n", vector);
+    return RT_NULL;
+}
+
+
+
+/**
+ * This function will initialize hardware interrupt
+ */
+void rt_hw_interrupt_init(void)
+{
+    //rt_int32_t i;
+    //register rt_uint32_t idx;
+
+
+    /* init interrupt nest, and context in thread sp */
+    rt_interrupt_nest = 0;
+    rt_interrupt_from_thread = 0;
+    rt_interrupt_to_thread = 0;
+    rt_thread_switch_interrupt_flag = 0;
+}
+
+
+/**
+ * This function will mask a interrupt.
+ * @param vector the interrupt number
+ */
+void rt_hw_interrupt_mask(int irq)
+{
+
+}
+
+
+/**
+ * This function will un-mask a interrupt.
+ * @param vector the interrupt number
+ */
+void rt_hw_interrupt_umask(int irq)
+{
+
+}
+
+/**
+ * This function will install a interrupt service routine to a interrupt.
+ * @param vector the interrupt number
+ * @param handler the interrupt service routine to be installed
+ * @param param the interrupt service function parameter
+ * @param name the interrupt name
+ * @return old handler
+ */
+rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler,
+                                    void *param, char *name)
+{
+    rt_isr_handler_t old_handler = RT_NULL;
+
+    if(vector < MAX_HANDLERS)
+    {
+        old_handler = irq_desc[vector].handler;
+        if (handler != RT_NULL)
+        {
+
+#ifdef RT_USING_INTERRUPT_INFO
+            rt_snprintf(irq_desc[vector].name, RT_NAME_MAX - 1, "%s", name);
+            irq_desc[vector].counter = 0;
+#endif
+            irq_desc[vector].handler = (rt_isr_handler_t)handler;
+            irq_desc[vector].param = param;
+        }
+    }
+
+    return old_handler;
+}
+
+/*@}*/
+
+
+
+#ifdef RT_USING_FINSH
+void list_irq(void)
+{
+    int irq;
+
+#ifdef RT_USING_INTERRUPT_INFO
+    rt_kprintf("number\tcount\tname\n");
+    for (irq = 0; irq < MAX_HANDLERS; irq++)
+    {
+        if (rt_strncmp(irq_desc[irq].name, "default", sizeof("default")))
+        {
+            rt_kprintf("%02ld: %10ld  %s\n", irq, irq_desc[irq].counter, irq_desc[irq].name);
+        }
+    }
+#endif
+}
+
+#include <finsh.h>
+FINSH_FUNCTION_EXPORT(list_irq, list system irq);
+
+#endif
+
+

+ 563 - 0
bsp/gkipc/armv6/mmu.c

@@ -0,0 +1,563 @@
+/*
+ * File      : mmu.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+
+#include "mmu.h"
+#include "rtthread.h"
+
+#ifdef __CC_ARM
+void mmu_setttbase(rt_uint32_t i)
+{
+	register rt_uint32_t value;
+
+   /* Invalidates all TLBs.Domain access is selected as
+    * client by configuring domain access register,
+    * in that case access controlled by permission value
+    * set by page table entry
+    */
+	value = 0;
+    __asm
+    {
+        mcr p15, 0, value, c8, c7, 0
+	}
+
+	value = 0x55555555;
+	__asm
+	{
+        mcr p15, 0, value, c3, c0, 0
+        mcr p15, 0, i, c2, c0, 0
+    }
+}
+
+void mmu_set_domain(rt_uint32_t i)
+{
+    __asm
+    {
+        mcr p15,0, i, c3, c0,  0
+    }
+}
+
+void mmu_enable()
+{
+    register rt_uint32_t value;
+
+    __asm
+    {
+        mrc p15, 0, value, c1, c0, 0
+        orr value, value, #0x01
+        mcr p15, 0, value, c1, c0, 0
+    }
+}
+
+void mmu_disable()
+{
+    register rt_uint32_t value;
+
+    __asm
+    {
+        mrc p15, 0, value, c1, c0, 0
+        bic value, value, #0x01
+        mcr p15, 0, value, c1, c0, 0
+    }
+}
+
+void mmu_enable_icache()
+{
+    register rt_uint32_t value;
+
+    __asm
+    {
+        mrc p15, 0, value, c1, c0, 0
+        orr value, value, #0x1000
+        mcr p15, 0, value, c1, c0, 0
+    }
+}
+
+void mmu_enable_dcache()
+{
+    register rt_uint32_t value;
+
+    __asm
+    {
+        mrc p15, 0, value, c1, c0, 0
+        orr value, value, #0x04
+        mcr p15, 0, value, c1, c0, 0
+    }
+}
+
+void mmu_disable_icache()
+{
+    register rt_uint32_t value;
+
+    __asm
+    {
+        mrc p15, 0, value, c1, c0, 0
+        bic value, value, #0x1000
+        mcr p15, 0, value, c1, c0, 0
+    }
+}
+
+void mmu_disable_dcache()
+{
+    register rt_uint32_t value;
+
+    __asm
+    {
+        mrc p15, 0, value, c1, c0, 0
+        bic value, value, #0x04
+        mcr p15, 0, value, c1, c0, 0
+    }
+}
+
+void mmu_enable_alignfault()
+{
+    register rt_uint32_t value;
+
+    __asm
+    {
+        mrc p15, 0, value, c1, c0, 0
+        orr value, value, #0x02
+        mcr p15, 0, value, c1, c0, 0
+    }
+}
+
+void mmu_disable_alignfault()
+{
+    register rt_uint32_t value;
+
+    __asm
+    {
+        mrc p15, 0, value, c1, c0, 0
+        bic value, value, #0x02
+        mcr p15, 0, value, c1, c0, 0
+    }
+}
+
+void mmu_clean_invalidated_cache_index(int index)
+{
+    __asm
+    {
+        mcr p15, 0, index, c7, c14, 2
+    }
+}
+
+void mmu_clean_invalidated_dcache(rt_uint32_t buffer, rt_uint32_t size)
+{
+    unsigned int ptr;
+
+    ptr = buffer & ~(CACHE_LINE_SIZE - 1);
+
+    while(ptr < buffer + size)
+    {
+    	__asm
+    	{
+    		MCR p15, 0, ptr, c7, c14, 1
+    	}
+        ptr += CACHE_LINE_SIZE;
+    }
+}
+
+void mmu_clean_dcache(rt_uint32_t buffer, rt_uint32_t size)
+{
+	unsigned int ptr;
+
+	ptr = buffer & ~(CACHE_LINE_SIZE - 1);
+
+	while (ptr < buffer + size)
+	{
+		__asm
+		{
+			MCR p15, 0, ptr, c7, c10, 1
+		}
+		ptr += CACHE_LINE_SIZE;
+	}
+}
+
+void mmu_invalidate_dcache(rt_uint32_t buffer, rt_uint32_t size)
+{
+	unsigned int ptr;
+
+	ptr = buffer & ~(CACHE_LINE_SIZE - 1);
+
+	while (ptr < buffer + size)
+	{
+		__asm
+		{
+			MCR p15, 0, ptr, c7, c6, 1
+		}
+		ptr += CACHE_LINE_SIZE;
+	}
+}
+
+void mmu_invalidate_tlb()
+{
+    register rt_uint32_t value;
+
+    value = 0;
+    __asm
+    {
+        mcr p15, 0, value, c8, c7, 0
+    }
+}
+
+void mmu_invalidate_icache()
+{
+    register rt_uint32_t value;
+
+    value = 0;
+
+    __asm
+    {
+        mcr p15, 0, value, c7, c5, 0
+    }
+}
+
+
+void mmu_invalidate_dcache_all()
+{
+    register rt_uint32_t value;
+
+    value = 0;
+
+    __asm
+    {
+        mcr p15, 0, value, c7, c6, 0
+    }
+}
+#elif defined(__GNUC__)
+void mmu_setttbase(register rt_uint32_t i)
+{
+	//register rt_uint32_t value;
+
+   /* Invalidates all TLBs.Domain access is selected as
+    * client by configuring domain access register,
+    * in that case access controlled by permission value
+    * set by page table entry
+    */
+#if 0
+	value = 0;
+	asm ("mcr p15, 0, %0, c8,c7, 0"::"r"(value));
+
+	value = 0x55555555;
+	asm ("mcr p15, 0, %0, c3,c0, 0"::"r"(value));
+	asm ("mcr p15, 0, %0, c2,c0, 0"::"r"(i));
+#endif
+
+	asm (
+    	"mrc p15,0,r0,c1,c0,0 \r\n"
+        "mov r1,#0x800000  \r\n"
+        "orr r0,r0,r1	 @ disable Subpage AP bits  \r\n"
+        "mcr p15,0,r0,c1,c0,0 @ write value back  \r\n"
+        "mov r0,#0x0  \r\n"
+        "mcr p15,0,r0,c2,c0,2 @ W  \r\n"
+    );
+    asm("mcr p15,0,%0,c2,c0,0"::"r"(i));
+}
+
+void mmu_set_domain(register rt_uint32_t i)
+{
+	asm ("mcr p15,0, %0, c3, c0,  0": :"r" (i));
+}
+
+void mmu_enable()
+{
+	register rt_uint32_t i;
+
+	/* read control register */
+	asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
+
+	i |= 0x1;
+
+	/* write back to control register */
+	asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
+}
+
+void mmu_disable()
+{
+	register rt_uint32_t i;
+
+	/* read control register */
+	asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
+
+	i &= ~0x1;
+
+	/* write back to control register */
+	asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
+}
+
+void mmu_enable_icache()
+{
+	register rt_uint32_t i;
+
+	/* read control register */
+	asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
+
+	i |= (1 << 12);
+
+	/* write back to control register */
+	asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
+}
+
+void mmu_enable_dcache()
+{
+	register rt_uint32_t i;
+
+	/* read control register */
+	asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
+
+	i |= (1 << 2);
+
+	/* write back to control register */
+	asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
+}
+
+void mmu_disable_icache()
+{
+	register rt_uint32_t i;
+
+	/* read control register */
+	asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
+
+	i &= ~(1 << 12);
+
+	/* write back to control register */
+	asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
+}
+
+void mmu_disable_dcache()
+{
+	register rt_uint32_t i;
+
+	/* read control register */
+	asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
+
+	i &= ~(1 << 2);
+
+	/* write back to control register */
+	asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
+}
+
+void mmu_enable_alignfault()
+{
+	register rt_uint32_t i;
+
+	/* read control register */
+	asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
+
+	i |= (1 << 1);
+
+	/* write back to control register */
+	asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
+}
+
+void mmu_disable_alignfault()
+{
+	register rt_uint32_t i;
+
+	/* read control register */
+	asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
+
+	i &= ~(1 << 1);
+
+	/* write back to control register */
+	asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
+}
+
+void mmu_clean_invalidated_cache_index(int index)
+{
+	asm ("mcr p15, 0, %0, c7, c14, 2": :"r" (index));
+}
+
+void mmu_clean_invalidated_dcache(rt_uint32_t buffer, rt_uint32_t size)
+{
+    unsigned int ptr;
+
+    ptr = buffer & ~(CACHE_LINE_SIZE - 1);
+
+    while(ptr < buffer + size)
+    {
+    	asm ("mcr p15, 0, %0, c7, c14, 1": :"r" (ptr));
+        ptr += CACHE_LINE_SIZE;
+    }
+}
+
+
+void mmu_clean_dcache(rt_uint32_t buffer, rt_uint32_t size)
+{
+	unsigned int ptr;
+
+	ptr = buffer & ~(CACHE_LINE_SIZE - 1);
+
+	while (ptr < buffer + size)
+	{
+		asm ("mcr p15, 0, %0, c7, c10, 1": :"r" (ptr));
+		ptr += CACHE_LINE_SIZE;
+	}
+}
+
+void mmu_invalidate_dcache(rt_uint32_t buffer, rt_uint32_t size)
+{
+	unsigned int ptr;
+
+	ptr = buffer & ~(CACHE_LINE_SIZE - 1);
+
+	while (ptr < buffer + size)
+	{
+		asm ("mcr p15, 0, %0, c7, c6, 1": :"r" (ptr));
+		ptr += CACHE_LINE_SIZE;
+	}
+}
+
+void mmu_invalidate_tlb()
+{
+	asm ("mcr p15, 0, %0, c8, c7, 0": :"r" (0));
+}
+
+void mmu_invalidate_icache()
+{
+	asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (0));
+}
+
+void mmu_invalidate_dcache_all()
+{
+    asm ("mcr p15, 0, %0, c7, c6, 0": :"r" (0));
+}
+#endif
+
+/* level1 page table */
+//static volatile unsigned int _page_table[4*1024] __attribute__((aligned(16*1024)));
+#define ARM1176_GCC_ALIGN(bits) __attribute__((aligned(1UL<<bits)))
+#define ARM1176_MMU_TTB_ALIGNMENT 14
+static volatile unsigned int _page_table[4096]
+    ARM1176_GCC_ALIGN(ARM1176_MMU_TTB_ALIGNMENT) __attribute__ ((section(".nocache_buffer"))) = { 0x000011E2UL };
+
+void mmu_setmtt(rt_uint32_t vaddrStart, rt_uint32_t vaddrEnd, rt_uint32_t paddrStart, rt_uint32_t attr)
+{
+    volatile rt_uint32_t *pTT;
+    volatile int i,nSec;
+    pTT=(rt_uint32_t *)_page_table+(vaddrStart>>20);
+    nSec=(vaddrEnd>>20)-(vaddrStart>>20);
+    for(i=0;i<=nSec;i++)
+    {
+		*pTT = attr |(((paddrStart>>20)+i)<<20);
+		pTT++;
+    }
+}
+
+
+void rt_hw_cpu_dump_page_table(rt_uint32_t *ptb)
+{
+    int i;
+    int fcnt = 0;
+
+    rt_kprintf("page table@%p\n", ptb);
+    for (i = 0; i < 1024*4; i++)
+    {
+        rt_uint32_t pte1 = ptb[i];
+        if ((pte1 & 0x3) == 0)
+        {
+            rt_kprintf("%03x: ", i);
+            fcnt++;
+            if (fcnt == 16)
+            {
+                rt_kprintf("fault\n");
+                fcnt = 0;
+            }
+            continue;
+        }
+        if (fcnt != 0)
+        {
+            rt_kprintf("fault\n");
+            fcnt = 0;
+        }
+
+        rt_kprintf("%03x: %08x: ", i, pte1);
+        if ((pte1 & 0x3) == 0x3)
+        {
+            rt_kprintf("LPAE\n");
+        }
+        else if ((pte1 & 0x3) == 0x1)
+        {
+            rt_kprintf("pte,ns:%d,domain:%d\n",
+                       (pte1 >> 3) & 0x1, (pte1 >> 5) & 0xf);
+            /*
+             *rt_hw_cpu_dump_page_table_2nd((void*)((pte1 & 0xfffffc000)
+             *                               - 0x80000000 + 0xC0000000));
+             */
+        }
+        else if (pte1 & (1 << 18))
+        {
+            rt_kprintf("super section,ns:%d,ap:%x,xn:%d,texcb:%02x\n",
+                       (pte1 >> 19) & 0x1,
+                       ((pte1 >> 13) | (pte1 >> 10))& 0xf,
+                       (pte1 >> 4) & 0x1,
+                       ((pte1 >> 10) | (pte1 >> 2)) & 0x1f);
+        }
+        else
+        {
+            rt_kprintf("section,ns:%d,ap:%x,"
+                       "xn:%d,texcb:%02x,domain:%d\n",
+                       (pte1 >> 19) & 0x1,
+                       ((pte1 >> 13) | (pte1 >> 10))& 0xf,
+                       (pte1 >> 4) & 0x1,
+                       (((pte1 & (0x7 << 12)) >> 10) |
+                        ((pte1 &        0x0c) >>  2)) & 0x1f,
+                       (pte1 >> 5) & 0xf);
+        }
+    }
+}
+
+void rt_hw_mmu_init(struct mem_desc *mdesc, rt_uint32_t size)
+{
+	/* disable I/D cache */
+	mmu_disable_dcache();
+	mmu_disable_icache();
+	mmu_disable();
+	mmu_invalidate_tlb();
+
+	/* set page table */
+	for (; size > 0; size--)
+	{
+		mmu_setmtt(mdesc->vaddr_start, mdesc->vaddr_end,
+			mdesc->paddr_start, mdesc->attr);
+		mdesc++;
+	}
+
+	/* set MMU table address */
+	mmu_setttbase((rt_uint32_t)_page_table);
+
+    /* enables MMU */
+    mmu_enable();
+
+    /* enable Instruction Cache */
+    mmu_enable_icache();
+
+    /* enable Data Cache */
+    mmu_enable_dcache();
+
+    mmu_invalidate_icache();
+    mmu_invalidate_dcache_all();
+}
+
+
+
+

+ 73 - 0
bsp/gkipc/armv6/mmu.h

@@ -0,0 +1,73 @@
+/*
+ * File      : mmu.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+
+#ifndef __MMU_H__
+#define __MMU_H__
+
+#include <rtthread.h>
+
+#define CACHE_LINE_SIZE	32
+
+#define DESC_SEC		(0x2|(1<<4))
+#define CB				(3<<2)  //cache_on, write_back
+#define CNB				(2<<2)  //cache_on, write_through
+#define NCB				(1<<2)  //cache_off,WR_BUF on
+#define NCNB			(0<<2)  //cache_off,WR_BUF off
+#define AP_RW			(3<<10) //supervisor=RW, user=RW
+#define AP_RO			(2<<10) //supervisor=RW, user=RO
+
+#define DOMAIN_FAULT	(0x0)
+#define DOMAIN_CHK		(0x1)
+#define DOMAIN_NOTCHK	(0x3)
+#define DOMAIN0			(0x0<<5)
+#define DOMAIN1			(0x1<<5)
+
+#define DOMAIN0_ATTR	(DOMAIN_CHK<<0)
+#define DOMAIN1_ATTR	(DOMAIN_FAULT<<2)
+
+#define RW_CB		(AP_RW|DOMAIN0|CB|DESC_SEC)		/* Read/Write, cache, write back */
+#define RW_CNB		(AP_RW|DOMAIN0|CNB|DESC_SEC)	/* Read/Write, cache, write through */
+#define RW_NCNB		(AP_RW|DOMAIN0|NCNB|DESC_SEC)	/* Read/Write without cache and write buffer */
+#define RW_FAULT	(AP_RW|DOMAIN1|NCNB|DESC_SEC)	/* Read/Write without cache and write buffer */
+
+#define ARM1176_1MB_NOCACHE_BUFFER      0x00000DE6  // non-cachable/bufferable
+#define ARM1176_1MB_CACHE_NOBUFFER      0x00000DEA  // cachable/non-bufferable
+#define ARM1176_1MB_CACHE_BUFFER        0x00000DEE  // cachable/bufferable
+#define ARM1176_1MB_NOCACHE_NOBUFFER    0x00000DE2  // non-cachable/non-bufferable
+#define ARM1176_1MB_NORMAL_NOCACHE      0x00001DE2  // Normal memory, non-cachable/non-bufferable
+#define ARM1176_1MB_CACHE_BUFFER_RO     0x000011EE  // cachable/bufferable read-only
+#define ARM1176_1MB_NOCACHE_NOBUFFER_RO 0x000011E2  // non-cachable/non-bufferable read-only
+
+
+struct mem_desc {
+	rt_uint32_t vaddr_start;
+	rt_uint32_t vaddr_end;
+	rt_uint32_t paddr_start;
+	rt_uint32_t attr;
+};
+
+void rt_hw_mmu_init(struct mem_desc *mdesc, rt_uint32_t size);
+void rt_hw_cpu_dump_page_table(rt_uint32_t *ptb);
+
+#endif
+

+ 39 - 0
bsp/gkipc/armv6/reset.c

@@ -0,0 +1,39 @@
+/*
+ * File      : reset.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Develop Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+#include "gk7101.h"
+
+
+
+void machine_reset(void)
+{
+
+}
+
+void machine_shutdown(void)
+{
+}
+
+/*@}*/

+ 27 - 0
bsp/gkipc/armv6/rtos.h

@@ -0,0 +1,27 @@
+/*!
+********************************************************************************
+**
+** \file        ./GKOS2/inc/rtos_lib.h
+**
+** \brief       RTOS user interface
+**
+** This file contains all public API functions and definitions to use the
+** RTOS real time operating system within an application.
+**
+** \attention   THIS SAMPLE CODE IS PROVIDED AS IS. Goke SEMICONDUCTOR
+**              ACCEPTS NO RESPONSIBILITY OR LIABILITY FOR ANY ERRORS OR
+**              OMMISSIONS.
+**
+********************************************************************************
+*/
+#ifndef RTOS__H
+#define RTOS__H
+
+#include "rtos_lib.h"
+#include "rtos_memory.h"
+/*
+********************************************************************************
+** end of file
+********************************************************************************
+*/
+#endif /* RTOS__H */

+ 1450 - 0
bsp/gkipc/armv6/rtos_lib.c

@@ -0,0 +1,1450 @@
+#include <sys/time.h>
+#include <time.h>
+#include "rtos_lib.h"
+#include "gd_timer.h"
+#include "gm_debug.h"
+#include "rtthread.h"
+#include "shell.h"
+
+#ifdef RT_USING_FINSH
+#include "shell.h"
+#endif
+
+//#define CACHE_MEM_MANAGE
+#define CACHE_MEM_SIZE  0x200000//1152k
+#define CACHE_DSP_SIZE  0x330000//3168k
+
+#define CACHE_LINE_SIZE     32
+#define CACHE_LINE_MASK     ~(CACHE_LINE_SIZE - 1)
+
+static int cache_check_end = 0;
+static int cache_check_start = 1;
+//static int cache_check_fail_halt = 0;
+void RTOS_MMU_ChangeMapEntry(U32 vaddrStart, U32 vaddrEnd, U32 paddrStart, U32 attr);
+
+static inline void __delay(int loops);
+
+u32 cpu_cpsr;
+#define HZ      RT_TICK_PER_SECOND
+
+#define LPS_PREC 8
+
+#define jiffies raid6_jiffies()
+
+static inline void __delay(int loops)
+{
+    return;
+}
+
+static inline unsigned int raid6_jiffies(void)
+{
+    //struct timeval tv;
+    //gettimeofday(&tv, NULL);
+    //return tv.tv_sec*1000 + tv.tv_usec/1000;
+    return rt_tick_get()*1000;
+}
+
+static unsigned long  calibrate_delay_converge(void)
+{
+    /* First stage - slowly accelerate to find initial bounds */
+    unsigned long lpj, lpj_base, ticks, loopadd, loopadd_base, chop_limit;
+    int trials = 0, band = 0, trial_in_band = 0;
+
+    lpj = (1<<12);
+
+    /* wait for "start of" clock tick */
+    ticks = jiffies;
+    while (ticks == jiffies)
+        ; /* nothing */
+    /* Go .. */
+    ticks = jiffies;
+    do {
+        if (++trial_in_band == (1<<band)) {
+            ++band;
+            trial_in_band = 0;
+        }
+        __delay(lpj * band);
+        trials += band;
+    } while (ticks == jiffies);
+    /*
+     * We overshot, so retreat to a clear underestimate. Then estimate
+     * the largest likely undershoot. This defines our chop bounds.
+     */
+    trials -= band;
+    loopadd_base = lpj * band;
+    lpj_base = lpj * trials;
+
+recalibrate:
+    lpj = lpj_base;
+    loopadd = loopadd_base;
+
+    /*
+     * Do a binary approximation to get lpj set to
+     * equal one clock (up to LPS_PREC bits)
+     */
+    chop_limit = lpj >> LPS_PREC;
+    while (loopadd > chop_limit) {
+        lpj += loopadd;
+        ticks = jiffies;
+        while (ticks == jiffies)
+            ; /* nothing */
+        ticks = jiffies;
+        __delay(lpj);
+        if (jiffies != ticks)   /* longer than 1 tick */
+            lpj -= loopadd;
+        loopadd >>= 1;
+    }
+    /*
+     * If we incremented every single time possible, presume we've
+     * massively underestimated initially, and retry with a higher
+     * start, and larger range. (Only seen on x86_64, due to SMIs)
+     */
+    if (lpj + loopadd * 2 == lpj_base + loopadd_base * 2) {
+        lpj_base = lpj;
+        loopadd_base <<= 2;
+        goto recalibrate;
+    }
+
+    return lpj;
+}
+
+void RTOS_Jiffies()
+{
+    unsigned long lpj;
+    lpj = calibrate_delay_converge();
+    rt_kprintf("Calibrating delay loop... %lu.%02lu BogoMIPS (lpj=%lu)\n",
+            lpj/(500000/HZ),
+            (lpj/(5000/HZ)) % 100, lpj);
+}
+
+void gk7101_setting_pll()
+{
+    int i = 0;
+
+    *((volatile U32 *)0x70170000) = 0x01202e01;
+    *((volatile U32 *)0x70170004) = 0x00000000;
+    *((volatile U32 *)0x7017000C) = 0x0000000c;
+    *((volatile U32 *)0x70170014) = 0x01202401;
+    *((volatile U32 *)0x70170018) = 0x00000000;
+    *((volatile U32 *)0x7017001C) = 0x00000001;
+    *((volatile U32 *)0x70170024) = 0x02406301;
+    *((volatile U32 *)0x70170028) = 0x00000000;
+    *((volatile U32 *)0x70170030) = 0x00000000;
+    *((volatile U32 *)0x70170034) = 0x00000000;
+    *((volatile U32 *)0x70170038) = 0x00000001;
+    *((volatile U32 *)0x7017003C) = 0x00000008;
+    *((volatile U32 *)0x7017004C) = 0x00000001;
+    *((volatile U32 *)0x70170050) = 0x00000001;
+    *((volatile U32 *)0x70170054) = 0x01202001;
+    *((volatile U32 *)0x70170058) = 0x00c49ba5;
+    *((volatile U32 *)0x7017005C) = 0x00000008;
+    *((volatile U32 *)0x70170060) = 0x00000001;
+    *((volatile U32 *)0x70170068) = 0x00000002;
+    *((volatile U32 *)0x70170080) = 0x00206978;
+    *((volatile U32 *)0x70170084) = 0x00000020;
+    *((volatile U32 *)0x7017008C) = 0x0000000f;
+    *((volatile U32 *)0x7017009C) = 0x00000002;
+    *((volatile U32 *)0x701700A0) = 0x00000010;
+    *((volatile U32 *)0x701700BC) = 0x00000001;
+    *((volatile U32 *)0x701700E4) = 0x01203201;
+    *((volatile U32 *)0x701700E8) = 0x00000000;
+    *((volatile U32 *)0x701700EC) = 0x00000008;
+    *((volatile U32 *)0x70170100) = 0x00000030;
+    *((volatile U32 *)0x70170108) = 0x00000030;
+    *((volatile U32 *)0x70170118) = 0x00000002;
+    *((volatile U32 *)0x7017011C) = 0x00000030;
+    *((volatile U32 *)0x70170124) = 0x00000030;
+    *((volatile U32 *)0x70170130) = 0x00000030;
+    *((volatile U32 *)0x70170148) = 0x00000001;
+    *((volatile U32 *)0x70170198) = 0x00000000;
+    *((volatile U32 *)0x7017019C) = 0x00000000;
+    *((volatile U32 *)0x701701E0) = 0x00000000;
+    *((volatile U32 *)0x701701E4) = 0x00000000;
+    *((volatile U32 *)0x701701F4) = 0x00000002;
+    *((volatile U32 *)0x701701FC) = 0x00000021;
+    *((volatile U32 *)0x70170200) = 0x00000022;
+    *((volatile U32 *)0x70170214) = 0x00000022;
+#if 0
+    *((volatile U32 *)0x7017021C) = 0x00000000;
+    *((volatile U32 *)0x70170228) = 0x00000000;
+    *((volatile U32 *)0x7017022C) = 0x00000000;
+#endif
+
+    for(i=0; i<14; i++)
+    {
+        *((volatile U32 *)((U32)0x70170230 + i*4)) = 0x11111111;
+    }
+
+#if 0
+    *((volatile U32 *)0x70170270) = 0x00000000;
+#endif
+
+    *(volatile U32 *)(0x70009100+20*4) = (1<<8);
+    *(volatile U32 *)(0x70009200+7*4) = 20;
+
+    *(volatile U32 *)(0x70009100+22*4) = 9;
+
+}
+//-------------------------------------------------------
+
+#if 0
+rt_inline unsigned int rt_list_len(const rt_list_t *l)
+{
+    unsigned int len = 0;
+    const rt_list_t *p = l;
+    while (p->next != l)
+    {
+        p = p->next;
+        len ++;
+    }
+
+    return len;
+}
+#endif
+
+static void show_wait_queue(struct rt_list_node *list)
+{
+    struct rt_thread *thread;
+    struct rt_list_node *node;
+
+    for (node = list->next; node != list; node = node->next)
+    {
+        thread = rt_list_entry(node, struct rt_thread, tlist);
+        rt_kprintf("%s", thread->name);
+
+        if (node->next != list)
+            rt_kprintf("/");
+    }
+}
+
+void rtos_cache_inv_range(void *addr, unsigned int size)
+{
+    u32                 vstart;
+    u32                 vend;
+    u32                 addr_tmp;
+
+    vstart = (u32)addr & CACHE_LINE_MASK;
+    vend = ((u32)addr + size + CACHE_LINE_SIZE - 1) & CACHE_LINE_MASK;
+
+    if (cache_check_start && (vstart != (u32)addr)) {
+        return;
+    }
+    if (cache_check_end && (vend != ((u32)addr + size))) {
+        return;
+    }
+
+
+    for (addr_tmp = vstart; addr_tmp < vend; addr_tmp += CACHE_LINE_SIZE) {
+        __asm__ __volatile__ (
+            "mcr p15, 0, %0, c7, c6, 1" : : "r" (addr_tmp));
+    }
+    dsb();
+}
+
+void rtos_cache_clean_range(void *addr, unsigned int size)
+{
+
+
+    u32                 vstart;
+    u32                 vend;
+
+    u32                 addr_tmp;
+
+    vstart = (u32)addr & CACHE_LINE_MASK;
+    vend = ((u32)addr + size + CACHE_LINE_SIZE - 1) & CACHE_LINE_MASK;
+    if (cache_check_start && (vstart != (u32)addr)) {
+        return;
+    }
+    if (cache_check_end && (vend != ((u32)addr + size))) {
+        return;
+    }
+
+
+    for (addr_tmp = vstart; addr_tmp < vend; addr_tmp += CACHE_LINE_SIZE) {
+        __asm__ __volatile__ (
+            "mcr p15, 0, %0, c7, c10, 1" : : "r" (addr_tmp));
+    }
+
+    dsb();
+}
+
+
+
+
+
+U32 RTOS_EnterCriticalSection( void )
+{
+    #if 0
+    /*lint -save -e529 */
+    U32 old_flags = 0;
+    U32 new_flags = 0;
+
+    #if defined(_ARM) && !defined(__GNUC__) && !defined(__polyspace__)
+        __asm { mrs old_flags,cpsr }
+        __asm { orr new_flags,old_flags,#0xC0 }
+        __asm { msr cpsr_c,new_flags }
+    #endif
+
+    #if defined(_ARM) && defined(__GNUC__) && !defined(__polyspace__)
+        asm volatile( "mrs %0,cpsr"     : "=r"(old_flags) : "r"(new_flags) );
+        asm volatile( "orr %0,%1,#0xC0" : "=r"(new_flags) : "r"(old_flags) );
+        asm volatile( "msr cpsr_c,%0"   : : "r"(new_flags) );
+    #endif
+
+    #if defined(_ARC) && !defined(__polyspace__)
+        old_flags = _lr(0);
+        _flag(0);
+    #endif
+
+    return( old_flags );
+    #else
+    return (U32)rt_hw_interrupt_disable();
+    #endif
+    /*lint -restore */
+}
+
+void RTOS_LeaveCriticalSection( U32 cpuStatus )
+{
+    #if 0
+    /*lint -save -e715 */
+
+    #if defined(_ARM) && !defined(__GNUC__) && !defined(__polyspace__)
+        __asm { msr cpsr_c,cpuStatus }
+    #endif
+
+    #if defined(_ARM) && defined(__GNUC__) && !defined(__polyspace__)
+        asm volatile ( "msr cpsr_c,%0" : : "r"(cpuStatus) );
+    #endif
+
+    #if defined(_ARC) && !defined(__polyspace__)
+        cpuStatus &= 0x0C000000;
+        _flag( cpuStatus >> 25 );
+    #endif
+    #else
+    rt_hw_interrupt_enable(cpuStatus);
+    #endif
+    /*lint -restore */
+}
+
+
+
+
+void RTOS_Halt( void )
+{
+    RTOS_EnterCriticalSection();
+}
+
+
+
+//-------------------------------------------------------------
+RTOS_Memory RTOS_MemorySet( RTOS_Memory mem, U8 value, RTOS_Size bytes )
+{
+    if( ( mem == (RTOS_Memory)0 ) || ( bytes == 0 ) )
+        return( (RTOS_Memory)0 );
+#if 0
+    return rt_memset(mem,value,bytes);
+#else// use libc 's memset to improve performance.
+    return memset(mem,value,bytes);
+#endif
+}
+
+RTOS_Memory RTOS_Malloc( RTOS_Size bytes)
+{
+    return rt_malloc(bytes);
+}
+
+RTOS_Memory RTOS_Realloc( RTOS_Memory addr, RTOS_Size bytes )
+{
+    return rt_realloc(addr, bytes);
+}
+
+char * RTOS_ThreadGetSelfName(void);
+RTOS_Memory RTOS_MemoryAllocate( RTOS_Size bytes, RTOS_Flag shared )
+{
+    //if (bytes >= 0x10000)
+    //    printf("RTOS_MemoryAllocate: %d(%s)\n",bytes, RTOS_ThreadGetSelfName());
+    return rt_malloc(bytes);
+}
+
+RTOS_Status RTOS_MemoryRelease( RTOS_Memory memory )
+{
+    if(memory) rt_free(memory);
+    return 0;
+}
+
+RTOS_Memory RTOS_SysMemoryAllocate( RTOS_Size bytes, RTOS_Flag shared )
+{
+#ifndef CACHE_MEM_MANAGE
+    return (RTOS_Memory)rt_malloc(bytes);
+#else
+    return (RTOS_Memory)rt_dspmem_malloc(bytes);
+#endif
+}
+
+RTOS_Status RTOS_SysMemoryRelease( RTOS_Memory memory )
+{
+    if(memory)
+#ifndef CACHE_MEM_MANAGE
+     rt_free(memory);
+#else
+    rt_dspmem_free(memory);
+#endif
+    return 0;
+}
+
+RTOS_Memory RTOS_KernelMemoryAllocate( RTOS_Size bytes)
+{
+    return (RTOS_Memory)RT_KERNEL_MALLOC(bytes);
+}
+
+RTOS_Status RTOS_KernelMemoryRelease( RTOS_Memory memory )
+{
+    if(memory)
+        RT_KERNEL_FREE(memory);
+    return 0;
+}
+
+
+void RTOS_GetMemInfo( RTOS_Size *Cache_memory, RTOS_Size *Uncache_memory)
+{
+    rt_uint32_t total,used,max_used;
+
+    rt_memory_info(&total,&used,&max_used);
+    *Cache_memory = total;
+    *Uncache_memory = 0;
+
+    #ifdef  CACHE_MEM_MANAGE
+    rt_cache_memory_info(&total,&used,&max_used);
+    *Uncache_memory = total;
+    #endif
+}
+
+
+
+void RTOS_HeapMemoryReport( void )
+{
+    rt_uint32_t total,used,max_used;
+
+    rt_memory_info(&total,&used,&max_used);
+    rt_kprintf("Heap Memory Info [cache memory]\n");
+    rt_kprintf("total memory:             %d KBytes,%d Btyes\n", total/1024,total);
+    rt_kprintf("used memory :             %d KBytes,%d Btyes\n", used/1024,used);
+    rt_kprintf("maximum allocated memory: %d KBytes,%d Btyes\n", max_used/1024,max_used);
+}
+
+void RTOS_SysMemoryReport( void )
+{
+#ifdef  CACHE_MEM_MANAGE
+    rt_uint32_t total,used,max_used;
+
+    rt_cache_memory_info(&total,&used,&max_used);
+    rt_kprintf("Sys  Memory Info [cache memory]\n");
+    rt_kprintf("total memory:             %d KBytes\n", total/1024);
+    rt_kprintf("used memory :             %d KBytes\n", used/1024);
+    rt_kprintf("maximum allocated memory: %d KBytes\n", max_used/1024);
+
+    rt_dspmem_memory_info(&total,&used,&max_used);
+    rt_kprintf("Drv  Memory Info [uncache memory]\n");
+    rt_kprintf("total memory:             %d KBytes\n", total/1024);
+    rt_kprintf("used memory :             %d KBytes\n", used/1024);
+    rt_kprintf("maximum allocated memory: %d KBytes\n", max_used/1024);
+
+#endif
+}
+
+RTOS_Memory RTOS_MemoryCopy( RTOS_Memory dst, RTOS_Memory src, RTOS_Size bytes )
+{
+#if 0
+    U8*       dstArray = (U8*)dst;
+    U8*       srcArray = (U8*)src;
+    RTOS_Size index;
+
+    if( ( dst == (RTOS_Memory)0 ) || ( bytes == 0 ) )
+        return( (RTOS_Memory)0 );
+
+    for( index=0; index < bytes; index++ )
+        dstArray[index] = srcArray[index];
+
+    return( dst );
+#else// use libc 's memcpy to improve performance.
+    if( ( dst == (RTOS_Memory)0 ) || ( bytes == 0 ) )
+        return( (RTOS_Memory)0 );
+    memcpy(dst, src, bytes);
+    return( dst );
+#endif
+}
+
+//-------------------------------------------------------------
+
+U32 RTOS_SetThreadName( RTOS_ThreadT threadHandle, const char* optName)
+{
+    rt_base_t level;
+
+    level = rt_hw_interrupt_disable();
+    if(threadHandle)
+    {
+        rt_strncpy(((rt_thread_t)threadHandle)->name, optName, RT_NAME_MAX);
+    }
+    rt_hw_interrupt_enable(level);
+
+    return 0;
+}
+
+U32 RTOS_ThreadSetName( RTOS_ThreadT threadHandle, const char* optName)
+{
+    rt_base_t level;
+
+    level = rt_hw_interrupt_disable();
+    if(threadHandle)
+    {
+        rt_strncpy(((rt_thread_t)threadHandle)->name, optName, RT_NAME_MAX);
+    }
+    rt_hw_interrupt_enable(level);
+
+    return 0;
+}
+char * RTOS_ThreadGetSelfName(void)
+{
+    return rt_thread_self()->name;
+}
+
+// thread-safe errno related api functions.
+void RTOS_SetErrno(const int err)
+{
+#if 0
+    rt_base_t level;
+    level = rt_hw_interrupt_disable();
+
+    rt_thread_t self = rt_thread_self();
+    self->thr_internal_errno = err;//FIXME(heyong): error is used to errno.
+
+    rt_hw_interrupt_enable(level);
+    //rt_kprintf("RTOS_SetErrno %d\n", err);
+#endif
+}
+int RTOS_GetErrno()
+{
+    int err;
+#if 0
+    rt_base_t level;
+    level = rt_hw_interrupt_disable();
+
+    rt_thread_t self = rt_thread_self();
+    err = (int)self->thr_internal_errno;//FIXME(heyong): error is used to errno.
+
+    rt_hw_interrupt_enable(level);
+    //rt_kprintf("RTOS_GetErrno %d\n", err);
+#endif
+    return err;
+}
+
+RTOS_ThreadT RTOS_CreateThread(
+        U32* stackBuffer, U32 stackSize, U32 priority,
+        RTOS_ThreadFunctionT function, void* optArg, void* optData,
+        const char* optName )
+{
+    rt_thread_t tid;
+
+    if (priority < RTOS_ThreadPriorityHighest)
+    {
+        priority = RTOS_ThreadPriorityHighest - priority;
+    }
+    else
+    {
+        priority = 1;
+    }
+
+    tid = rt_thread_create((optName == NULL)?"thread":optName,
+                    function, optArg,
+                    stackSize, priority, THREAD_TIMESLICE);
+    if (tid != RT_NULL)
+    {
+        rt_thread_startup(tid);
+    }
+
+    return (RTOS_ThreadT)tid;
+}
+
+U32 RTOS_DestroyThread( RTOS_ThreadT threadHandle )
+{
+    rt_err_t ret = 0;
+
+    rt_enter_critical();
+    ret = rt_thread_delete((rt_thread_t)threadHandle);
+    rt_exit_critical();
+
+    if (RT_EOK == ret)
+    {
+        ret = 1;
+    }
+    else
+    {
+        ret = 0;
+    }
+
+    return ret;
+}
+
+U32 RTOS_ThreadDestroy( RTOS_ThreadT threadHandle )
+{
+    rt_err_t ret = 0;
+
+    rt_enter_critical();
+    ret = rt_thread_delete((rt_thread_t)threadHandle);
+    rt_exit_critical();
+
+    if (RT_EOK == ret)
+    {
+        ret = 1;
+    }
+    else
+    {
+        ret = 0;
+    }
+
+    return ret;
+}
+
+U32 RTOS_GetThreadPriority(RTOS_ThreadT threadHandle)
+{
+    rt_thread_t tid = (rt_thread_t)threadHandle;
+    int priority = tid->current_priority;
+
+    if (priority < RTOS_ThreadPriorityHighest)
+    {
+        priority = RTOS_ThreadPriorityHighest - priority;
+    }
+    else
+    {
+        priority = 1;
+    }
+    return priority;
+}
+
+
+void gkosFinishThread( void )
+{
+    //rt_thread_t t = rt_thread_self();
+
+    //rt_thread_detach(t);
+}
+
+
+void RTOS_LockScheduler( void )
+{
+    rt_enter_critical();
+}
+
+void RTOS_UnlockScheduler( void )
+{
+    rt_exit_critical();
+}
+
+void RTOS_SchedulerLock( void )
+{
+    rt_enter_critical();
+}
+
+void RTOS_SchedulerUnlock( void )
+{
+    rt_exit_critical();
+}
+
+U32 RTOS_SleepThread( U32 msecs )
+{
+    return  rt_thread_delay( msecs )  ;
+}
+
+U32 msleep( U32 msecs )
+{
+    return  rt_thread_delay( msecs )  ;
+}
+
+
+U32 RTOS_SuspendThread( RTOS_ThreadT threadHandle )
+{
+    return rt_thread_suspend((rt_thread_t)threadHandle);
+}
+
+U32 RTOS_WakeupThread( RTOS_ThreadT threadHandle )
+{
+    return rt_thread_resume( (rt_thread_t)threadHandle );
+}
+
+void thread_statistics()
+{
+    struct rt_thread *thread;
+    struct rt_list_node *node;
+    rt_uint8_t *ptr;
+
+    rt_base_t level;
+
+    struct rt_object_information *information;
+
+    information = rt_object_get_information(RT_Object_Class_Thread);
+    RT_ASSERT(information != RT_NULL);
+
+    struct rt_list_node *list = &(information->object_list);
+
+    level = rt_hw_interrupt_disable();
+
+    for (node = list->next; node != list; node = node->next)
+    {
+        thread = rt_list_entry(node, struct rt_thread, list);
+        //if(thread) thread->total_tick = 0;
+    }
+
+    rt_hw_interrupt_enable(level);
+
+    rt_thread_delay(5000);
+
+    //not close interrupt to avoid the venc error because the print time is too long.
+    //level = rt_hw_interrupt_disable();
+    rt_kprintf("          thread                 pri  status  tick   cpu%%         sp    stack addr stack size  max used  left tick\n");
+    rt_kprintf("-------------------------------- --- ------- ------ -------    ---------- ---------- ---------- ---------- ---------- \n");
+    for (node = list->next; node != list; node = node->next)
+    {
+        thread = rt_list_entry(node, struct rt_thread, list);
+#if 0
+        rt_kprintf("%-32.*s 0x%02x", RT_NAME_MAX, thread->name, thread->current_priority);
+#else
+        int priority = thread->current_priority;
+        if (priority < RTOS_ThreadPriorityHighest)
+        {
+            priority = RTOS_ThreadPriorityHighest - priority;
+        }
+        else
+        {
+            priority = 1;
+        }
+        rt_kprintf("%-32.*s %3d", RT_NAME_MAX, thread->name, priority);
+#endif
+        if (thread->stat == RT_THREAD_READY)        rt_kprintf("   ready");
+        else if (thread->stat == RT_THREAD_SUSPEND) rt_kprintf(" suspend");
+        else if (thread->stat == RT_THREAD_INIT)    rt_kprintf("    init");
+        else if (thread->stat == RT_THREAD_CLOSE)   rt_kprintf("   close");
+
+        ptr = (rt_uint8_t*)thread->stack_addr;
+        while (*ptr == '#')ptr ++;
+#if 0
+        rt_kprintf(" %5d   %5.2f%%    0x%08x 0x%08x 0x%08x 0x%08x 0x%08x \n",
+            thread->total_tick,
+            ((double)thread->total_tick/50)>=100.00?99.9:((double)thread->total_tick/50),
+            thread->stack_size + ((rt_uint32_t)thread->stack_addr - (rt_uint32_t)thread->sp),
+            thread->stack_addr,
+            thread->stack_size,
+            thread->stack_size - ((rt_uint32_t) ptr - (rt_uint32_t)thread->stack_addr),
+            thread->remaining_tick);
+#endif
+
+        rt_kprintf(" 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x \n",
+            thread->stack_size + ((rt_uint32_t)thread->stack_addr - (rt_uint32_t)thread->sp),
+            thread->stack_addr,
+            thread->stack_size,
+            thread->stack_size - ((rt_uint32_t) ptr - (rt_uint32_t)thread->stack_addr),
+            thread->remaining_tick);
+    }
+    //rt_hw_interrupt_enable(level);
+}
+
+void RTOS_ThreadDisplayStatistics( void )
+{
+    rt_uint32_t total;
+    rt_uint32_t used;
+    rt_uint32_t max_used;
+
+    rt_memory_info(&total,&used,&max_used);
+    rt_kprintf("\n         memory info       size \n");
+    rt_kprintf("--------------------------------- -------\n");
+    rt_kprintf("total heap memory :               %d(%dKB)\n", total, total/1024);
+    rt_kprintf("used  heap memory :               %d(%dKB)\n", used, used/1024);
+    rt_kprintf("maximum allocated heap memory:    %d(%dKB)\n\n", max_used, max_used/1024);
+#ifdef CACHE_MEM_MANAGE
+    rt_cache_memory_info(&total,&used,&max_used);
+    rt_kprintf("total sys  memory :             %d(%dKB)\n", total, total/1024);
+    rt_kprintf("used  sys  memory :             %d(%dKB)\n", used, used/1024);
+    rt_kprintf("maximum allocated sys memory:   %d(%dKB)\n", max_used, max_used/1024);
+
+    rt_dspmem_memory_info(&total,&used,&max_used);
+    rt_kprintf("total drv  memory :             %d(%dKB)\n", total, total/1024);
+    rt_kprintf("used  drv  memory :             %d(%dKB)\n", used, used/1024);
+    rt_kprintf("maximum allocated drv memory:   %d(%dKB)\n", max_used, max_used/1024);
+#endif
+
+    thread_statistics();
+
+    return ;
+}
+
+U32 RTOS_GetFreeHeapSize()
+{
+    rt_uint32_t total;
+    rt_uint32_t used;
+    rt_uint32_t max_used;
+
+    rt_memory_info(&total,&used,&max_used);
+
+    return (total-used);
+}
+
+RTOS_Time RTOS_KernelTimerGetPeriod(void)
+{
+    return (1000 / RT_TICK_PER_SECOND);
+}
+
+//-------------------------sem--------------------------
+RTOS_SemaphoreT RTOS_CreateSemaphore( U32 initCount )
+{
+    return (RTOS_SemaphoreT)rt_sem_create("sem", initCount, RT_IPC_FLAG_PRIO);
+}
+
+U32 RTOS_WaitSemaphore(RTOS_SemaphoreT semaphoreHandle, U32 suspend)
+{
+    if(suspend)
+        return RTOS_GetSemaphore((RTOS_Semaphore)semaphoreHandle, RTOS_SUSPEND);
+    else
+        return RTOS_GetSemaphore((RTOS_Semaphore)semaphoreHandle, RTOS_NO_SUSPEND);
+}
+
+
+U32 RTOS_GetSemaphore( RTOS_SemaphoreT semaphoreHandle,
+                           U32 msecsTimeout )
+{
+    return rt_sem_take((rt_sem_t)semaphoreHandle, msecsTimeout);
+}
+
+U32 RTOS_SetSemaphore( RTOS_SemaphoreT semaphoreHandle,
+                            U32 msecsTimeout )
+{
+    return rt_sem_release((rt_sem_t)semaphoreHandle);
+}
+
+RTOS_Status RTOS_SemaphoreDestroy( RTOS_Semaphore semaphoreHandle )
+{
+    return rt_sem_delete((rt_sem_t)semaphoreHandle);
+}
+
+RTOS_Status RTOS_DestroySemaphore( RTOS_Semaphore semaphoreHandle )
+{
+    return rt_sem_delete((rt_sem_t)semaphoreHandle);
+}
+
+S32 RTOS_SemaphoreQuery( RTOS_Semaphore semaphoreHandle )
+{
+    S32 countPtr = 0;
+    rt_ubase_t level;
+
+    level = rt_hw_interrupt_disable();
+
+    countPtr = ((rt_sem_t)semaphoreHandle)->value;
+
+    rt_hw_interrupt_enable(level);
+
+    return (S32)countPtr;
+}
+
+//-------------------------timer-------------------------
+void GKOS_KernelTimerSetHook(RTOS_HookFunction function)
+{
+    if(gkosHookData)
+    {
+        if(gkosHookData->timerFunctionCount < (GKOS_TIMER_HOOK_TABLE_SIZE - 1))
+        {
+            gkosHookData->timerFunctionArray[gkosHookData->timerFunctionCount] = function;
+            gkosHookData->timerFunctionCount ++;
+        }
+    }
+}
+
+
+void RTOS_KernelTimerSetHook(RTOS_HookFunction function)
+{
+    GKOS_KernelTimerSetHook(function);
+}
+
+//-------------------------mail queue-------------------------
+#if 0
+RTOS_MailqueueT RTOS_MailqueueCreate( U32 queueElements)
+{
+    struct rt_mailbox *mq;
+
+    mq = rt_mb_create("mqt", queueElements, RT_IPC_FLAG_FIFO);
+
+    return (RTOS_MailqueueT)mq;
+}
+#endif
+
+RTOS_MailqueueT RTOS_CreateMailqueue( U32 queueElements, U32 elementBytes )
+{
+    struct rt_mailbox *mq;
+
+    mq = rt_mb_create("mqt", queueElements, RT_IPC_FLAG_FIFO);
+
+    return (RTOS_MailqueueT)mq;
+}
+
+RTOS_Status RTOS_MailqueueSend(RTOS_Mailqueue mailqueue, RTOS_Message data)
+{
+    //rt_kprintf("mail send...0x%x\n", data);
+    return rt_mb_send((rt_mailbox_t)mailqueue, (rt_uint32_t)data);
+}
+
+RTOS_Status RTOS_MailqueueSendTimeout(RTOS_Mailqueue mailqueue, RTOS_Message data, RTOS_Time timeout)
+{
+    //rt_kprintf("mail send...0x%x\n", data);
+    return rt_mb_send_wait((rt_mailbox_t)mailqueue, (rt_uint32_t)data, timeout);
+}
+
+RTOS_Message RTOS_MailqueueWait(RTOS_Mailqueue mailqueue, RTOS_Flag suspend)
+{
+    int ret;
+    U32 timeout;
+    U8* messagePtr;
+
+    if( suspend )
+        timeout = RTOS_SUSPEND;
+    else
+        timeout = RTOS_NO_SUSPEND;
+
+    ret = rt_mb_recv((rt_mailbox_t)mailqueue, (void*)(&messagePtr), timeout);
+    //rt_kprintf("mail recv [0x%x]...0x%x\n", (U32)timeout, messagePtr);
+
+    if(ret != 0)
+        return NULL;
+
+    return (RTOS_Message)messagePtr;
+}
+
+RTOS_Message RTOS_MailqueueWaitTimeout( RTOS_Mailqueue mailqueue, RTOS_Time timeout )
+{
+    U8* messagePtr;
+    int ret;
+
+    ret = rt_mb_recv((rt_mailbox_t)mailqueue, (void*)(&messagePtr), timeout);
+    //rt_kprintf("mail recv [0x%x]...0x%x\n", (U32)timeout, messagePtr);
+
+    if(ret != 0)
+        return NULL;
+    return (RTOS_Message)messagePtr;
+}
+
+U32 RTOS_MailqueueDestroy( RTOS_MailqueueT mailqueuePtr )
+{
+    rt_mb_delete((rt_mailbox_t)mailqueuePtr);
+
+    return 0;
+}
+
+U32 RTOS_DestroyMailqueue( RTOS_MailqueueT mailqueuePtr )
+{
+    rt_mb_delete((rt_mailbox_t)mailqueuePtr);
+
+    return 0;
+}
+
+U32 RTOS_GetTimerStamp()
+{
+    return rt_tick_get();
+}
+
+/*
+*******************************************************************************
+**
+** Create a new mutex and initializes it with the given value.
+**
+*******************************************************************************
+*/
+RTOS_MutexT RTOS_MutexCreate( void )
+{
+    return( (RTOS_MutexT) rt_mutex_create("mutex", RT_IPC_FLAG_FIFO) );
+}
+
+/*
+*******************************************************************************
+**
+** Destroy a given mutex.
+**
+*******************************************************************************
+*/
+U32 RTOS_MutexDestroy( RTOS_MutexT mutex )
+{
+
+    return rt_mutex_delete( (rt_mutex_t) mutex );
+}
+
+/*
+*******************************************************************************
+**
+** Query (read) the current value from a given mutex.
+**
+*******************************************************************************
+*/
+S32 RTOS_MutexQuery( RTOS_MutexT mutex )
+{
+
+    S32 countPtr = 0;
+    rt_ubase_t level;
+
+    level = rt_hw_interrupt_disable();
+
+    countPtr = ((rt_mutex_t)mutex)->value;
+
+    rt_hw_interrupt_enable(level);
+
+    return countPtr;
+}
+
+/*
+*******************************************************************************
+**
+** Wait and lock a given mutex
+**
+*******************************************************************************
+*/
+U32 RTOS_MutexLock( RTOS_MutexT mutex, RTOS_Flag suspend )
+{
+    U32 timeout;
+
+    if( suspend )
+        timeout = RTOS_SUSPEND;
+    else
+        timeout = RTOS_NO_SUSPEND;
+
+    return rt_mutex_take( (rt_mutex_t) mutex, timeout );
+
+}
+
+U32 RTOS_MutexLockTimeout( RTOS_MutexT mutex, U32 timeout )
+{
+
+    return rt_mutex_take( (rt_mutex_t) mutex, timeout );
+
+}
+
+/*
+*******************************************************************************
+**
+** Unlock an occupied mutex
+**
+*******************************************************************************
+*/
+U32 RTOS_MutexUnlock( RTOS_MutexT mutex )
+{
+    return rt_mutex_release( (rt_mutex_t) mutex );
+}
+
+
+//--------------------------------------------------------
+RTOS_ThreadT RTOS_ThreadSelf( void )
+{
+    return( (RTOS_ThreadT)rt_thread_self() );
+}
+
+
+//-------------------------------------------------------
+
+extern unsigned char __heap_end__[];
+gkosHookDataT  HookData;
+
+void RTOS_HwTickInit(void)
+{
+
+    GD_HANDLE   timerHandle;
+    GBOOL       timerFlag;
+    GERR        result;
+
+    GD_INT_DisableAllInterrupts();
+    // only use the os's timers
+    // RTOS_TIMERTICK_IRQ must use the GD_INT_LOW_PRIORITY mode
+    GD_INT_SetVector( GD_INT_TIMER1_IRQ, NULL );
+    result = GD_TIMER_SoftTimerOpen( &timerHandle );
+
+    if( result == GD_OK )
+    {
+        // modify the hard timer to Timer Tick
+        result = GD_TIMER_SoftTimerSet( &timerHandle, 1, &timerFlag, NULL );
+        GD_INT_SetVector( GD_INT_TIMER1_IRQ, rt_tick_increase );
+    }
+
+
+    int bytes = sizeof(gkosHookDataT);
+    gkosHookData = &HookData;
+    memset( gkosHookData, 0, bytes );
+
+}
+
+extern u32 ARM1176_MMU_ttb0[4096];
+
+
+U32 RTOS_InitKernel(U32 Heap_size)
+{
+    u32 os_end_address=0;
+    /* disable interrupt first */
+    rt_hw_interrupt_disable();
+    /* enable cpu cache */
+    //rt_hw_cpu_icache_disable();
+    //mmu_invalidate_icache();
+    //rt_hw_cpu_icache_enable();
+
+    /* initialize hardware interrupt */
+    rt_hw_interrupt_init();
+
+    /* initialize board */
+    //rt_hw_board_init();
+
+    /* show version */
+    //rt_show_version();
+
+    /* initialize tick */
+    //rt_system_tick_init();
+    RTOS_HwTickInit();
+    //rt_kprintf("set tick\n");
+
+    /* initialize kernel object */
+    rt_system_object_init();
+
+    /* initialize timer system */
+    rt_system_timer_init();
+
+    /* initialize heap memory system */
+    os_end_address= (u32)__heap_end__+Heap_size;
+
+#ifdef  CACHE_MEM_MANAGE
+    rt_system_heap_init((void*)__heap_end__, (void*)(os_end_address-CACHE_MEM_SIZE-CACHE_DSP_SIZE));
+
+    rt_system_cache_init((void*)(os_end_address-CACHE_MEM_SIZE-CACHE_DSP_SIZE),
+                          (void*)(os_end_address-CACHE_DSP_SIZE));
+    //cache-buffer for system
+    #if 0
+    RTOS_MMU_ChangeMapEntry((U32)(os_end_address-CACHE_MEM_SIZE-CACHE_DSP_SIZE),(U32)os_end_address-CACHE_DSP_SIZE,
+                            (U32)(os_end_address-CACHE_MEM_SIZE), 0x00000DE2);
+    #endif
+
+    rt_system_dspmem_init((void*)(os_end_address-CACHE_DSP_SIZE), (void*)(os_end_address));
+    //nocache nobuffer
+    RTOS_MMU_ChangeMapEntry((U32)(os_end_address-CACHE_DSP_SIZE), (U32)os_end_address,
+                            (U32)(os_end_address-CACHE_DSP_SIZE), 0x00000DE2);
+
+        /* print mmu table */
+    //rt_hw_cpu_dump_page_table((rt_uint32_t*)ARM1176_MMU_ttb0);
+
+#else
+    rt_system_heap_init((void*)__heap_end__, (void*)os_end_address);
+#endif
+
+
+
+#ifdef RT_USING_MODULE
+    /* initialize module system*/
+    rt_system_module_init();
+#endif
+
+    /* initialize scheduler system */
+    rt_system_scheduler_init();
+
+    return 0;
+}
+
+void RTOS_StartMultitasking( void )
+{
+    #ifdef RT_USING_FINSH
+    /* initialize finsh */
+    finsh_system_init();
+#ifdef RT_USING_DEVICE
+    finsh_set_device(RT_CONSOLE_DEVICE_NAME);
+#endif
+#endif
+
+    /* initialize system timer thread */
+    rt_system_timer_thread_init();
+
+    /* initialize idle thread */
+    rt_thread_idle_init();
+
+    rt_kprintf("start scheduler\n");
+    /* start scheduler */
+
+    rt_system_scheduler_start();
+
+    /* never reach here */
+    return ;
+}
+
+
+U32 RTOS_GetMailqueue( RTOS_MailqueueT mailqueueHandle,
+                           void* resultBuffer, U32 msecsTimeout )
+{
+    return rt_mb_recv((rt_mailbox_t)mailqueueHandle,(rt_uint32_t*)resultBuffer,
+                        (rt_uint32_t)msecsTimeout);
+}
+
+U32 RTOS_SetMailqueue( RTOS_MailqueueT mailqueueHandle,
+                           void* messagePtr, U32 toFront,
+                           U32 msecsTimeout )
+{
+    return rt_mb_send_wait((rt_mailbox_t)mailqueueHandle,
+                            (rt_uint32_t)messagePtr, (rt_uint32_t)msecsTimeout);
+}
+
+
+/*Dummy func of os*/
+
+//-----------------------------cond------------------------------
+RTOS_CondT RTOS_CondCreate( void )
+{
+    rt_event_t evt;
+
+    evt = rt_event_create("evt", 0);
+
+    /* detach the object from system object container */
+    rt_object_detach(&(evt->parent.parent));
+
+    return (RTOS_CondT) evt;
+}
+
+RTOS_Status RTOS_CondDestroy( RTOS_CondT cond )
+{
+    rt_err_t result;
+    if (cond == RT_NULL)
+        return -2;
+
+    result = rt_event_delete((rt_event_t)cond);
+    if (result != RT_EOK)
+        return -3;
+
+    return( 0 );
+}
+
+int _cond_timedwait(RTOS_CondT  cond, RTOS_MutexT mutex, U32 timeout)
+{
+    int result;
+    rt_uint32_t recved = 0XFF;
+    if (!cond || !mutex)
+        return -1;
+
+    if(RTOS_MutexUnlock(mutex)!=0) return -2;
+
+    result = rt_event_recv((rt_event_t)cond, 0x01,RT_EVENT_FLAG_AND|RT_EVENT_FLAG_CLEAR,timeout,&recved);
+    if(result == -RT_ERROR && recved == 0XFF) // for boardcase event
+    {
+        result = RT_EOK;
+    }
+    /* lock mutex again */
+    RTOS_MutexLock(mutex, 1);
+
+    return result;
+}
+
+
+RTOS_Status RTOS_CondWait( RTOS_CondT cond, RTOS_MutexT mutex, RTOS_Flag suspend )
+{
+    S32 value = 0;
+    U32 timeout;
+
+    if( suspend )
+        timeout = RTOS_SUSPEND;
+    else
+        timeout = RTOS_NO_SUSPEND;
+
+    value = _cond_timedwait( (RTOS_CondT) cond, (RTOS_MutexT) mutex, timeout );
+    if( value != RT_EOK )
+        return( -1 );
+
+    return( value );
+}
+
+RTOS_Status RTOS_CondWaitTimeout( RTOS_CondT cond, RTOS_MutexT mutex, U32 timeout )
+{
+    S32 value = 0;
+
+    value = _cond_timedwait( (RTOS_CondT) cond, (RTOS_MutexT) mutex, timeout );
+    if( value != RT_EOK )
+        return( -1 );
+
+    return( value );
+}
+
+
+RTOS_Status RTOS_CondSignal( RTOS_CondT cond )
+{
+    RTOS_Status result;
+
+    result = rt_event_send((rt_event_t)cond,0x01);
+    if (result != RT_EOK)
+        return -1;
+
+    return 0;
+}
+
+RTOS_Status RTOS_CondBroadcast( RTOS_CondT cond )
+{
+
+    rt_event_control((rt_event_t)cond,RT_IPC_CMD_RESET,0);
+
+    return 0;
+}
+
+U32 RTOS_OsType(void)
+{
+    return RTOS_RTTHREAD;
+}
+
+
+void RTOS_MMU_ChangeMapEntry(U32 vaddrStart, U32 vaddrEnd, U32 paddrStart, U32 attr)
+{
+    volatile U32 *pTT;
+    volatile int i,nSec;
+
+    extern U32 ARM1176_MMU_ttb0[];
+    extern U32 ARM1176_MMU_ttb1[];
+
+    U32*   table_ptr  = (U32*)ARM1176_MMU_ttb0;
+    //printf("mmu table: 0x%x \n", (U32)ARM1176_MMU_ttb0);
+
+    pTT  = (U32 *)table_ptr + (vaddrStart>>20);
+    nSec = (vaddrEnd>>20) - (vaddrStart>>20);
+    //printf("change table: 0x%x -- %d\n", (U32)pTT, nSec);
+
+    for(i=0;i<=nSec;i++)
+    {
+        *pTT = attr |(((paddrStart>>20)+i)<<20);
+        pTT++;
+    }
+
+    table_ptr  = (U32*)ARM1176_MMU_ttb1;
+    //printf("mmu table: 0x%x \n", (U32)ARM1176_MMU_ttb1);
+
+    pTT  = (U32 *)table_ptr + (vaddrStart>>20);
+    nSec = (vaddrEnd>>20) - (vaddrStart>>20);
+    //printf("change table: 0x%x -- %d\n", (U32)pTT, nSec);
+
+    for(i=0;i<=nSec;i++)
+    {
+        *pTT = attr |(((paddrStart>>20)+i)<<20);
+        pTT++;
+    }
+
+}
+
+int RTOS_thread_yield(void)
+{
+    rt_thread_yield();
+
+    return 0;
+}
+
+unsigned int RTOS_jiffies(void)
+{
+    return jiffies;
+}
+
+RTOS_TimerT RTOS_CreateTimer(U32 isContinouos, RTOS_SemaphoreT fireSemaphore, RTOS_HookFunctionT callbackFunction)
+{
+    //U8 name[32];
+
+    //sprintf(name, "timer %X", (U32)callbackFunction);
+    if(isContinouos)
+    {
+        return (RTOS_TimerT)rt_timer_create("timer", callbackFunction, NULL, 0, RT_TIMER_FLAG_PERIODIC);
+    }
+    else
+    {
+        return (RTOS_TimerT)rt_timer_create("timer", callbackFunction, NULL, 0, RT_TIMER_FLAG_ONE_SHOT);
+    }
+}
+
+RTOS_TimerT RTOS_CreateTimerEx(const char *name, U8 flag, void *parameter, RTOS_TimerFunctionT callbackFunction)
+{
+    U8 timer_flag = 0;
+
+    if(flag & RTOS_TIMER_FLAG_PERIODIC)
+    {
+        timer_flag = timer_flag | RT_TIMER_FLAG_PERIODIC;
+    }
+    else
+    {
+        timer_flag = timer_flag | RT_TIMER_FLAG_ONE_SHOT;
+    }
+
+    if(flag & RTOS_TIMER_FLAG_SOFT_TIMER)
+    {
+        timer_flag = timer_flag | RT_TIMER_FLAG_SOFT_TIMER;
+    }
+    else
+    {
+        timer_flag = timer_flag | RT_TIMER_FLAG_SOFT_TIMER;
+    }
+
+    return (RTOS_TimerT)rt_timer_create(name, callbackFunction, parameter, 0, timer_flag);
+}
+
+
+U32 RTOS_DestroyTimer(RTOS_TimerT timerHandle)
+{
+    return rt_timer_delete((rt_timer_t)timerHandle);
+}
+U32 RTOS_StartTimer(RTOS_TimerT timerHandle, U32 fireInterval)
+{
+    rt_timer_t handler = (rt_timer_t)timerHandle;
+
+    handler->init_tick = fireInterval;
+    return rt_timer_start((rt_timer_t)timerHandle);
+}
+
+U32 RTOS_StopTimer(RTOS_TimerT timerHandle)
+{
+    return rt_timer_stop((rt_timer_t)timerHandle);
+}
+
+U32 RTOS_ControlTimer(RTOS_TimerT timerHandle, U32 delay_time)
+{
+    return rt_timer_control((rt_timer_t)timerHandle, RT_TIMER_CTRL_SET_TIME, &delay_time);
+}
+
+U32 RTOS_GetTimerStatus(RTOS_TimerT timerHandle)
+{
+    rt_timer_t t;
+
+    t = (rt_timer_t)timerHandle;
+    if(t->parent.flag & RT_TIMER_FLAG_ACTIVATED)
+    {
+        return RTOS_TIMER_FLAG_ACTIVATED;
+    }
+    else
+    {
+        return RTOS_TIMER_FLAG_DEACTIVATED;
+    }
+}
+
+void *RTOS_timer_get_context(RTOS_TimerT timerHandle)
+{
+    rt_timer_t t;
+
+    t = (rt_timer_t)timerHandle;
+
+    return t->parameter;
+}
+
+int RTOS_Thead_Switch_Priority(int priority)
+{
+    if (priority < RTOS_ThreadPriorityHighest)
+    {
+        priority = RTOS_ThreadPriorityHighest - priority;
+    }
+    else
+    {
+        priority = 1;
+    }
+    return priority;
+}
+
+void usleep(int micro_sec)
+{
+    int ms = micro_sec/1000;
+    rt_thread_delay(ms);
+}
+
+void sleep(int sec)
+{
+    rt_thread_delay(sec*1000);
+}

+ 236 - 0
bsp/gkipc/armv6/rtos_lib.h

@@ -0,0 +1,236 @@
+#ifndef RTOS_LIB_H
+#define RTOS_LIB_H
+#include <limits.h>
+#include <string.h>
+#include "rthw.h"
+#include "rtthread.h"
+
+#include "gtypes.h"    /* global type definitions */
+#include "gd_int.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void(*RTOS_ThreadFunctionT)(void*);
+typedef void(*RTOS_HookFunctionT)(void*);
+typedef void (*RTOS_TimerFunctionT)(void *);
+typedef void* RTOS_ThreadT;
+typedef void* RTOS_EventT;
+typedef void* RTOS_SemaphoreT;
+typedef void* RTOS_MailboxT;
+typedef void* RTOS_MailqueueT;
+typedef void* RTOS_MutexT;
+typedef void* RTOS_TimerT;
+typedef void* RTOS_CondT;
+
+typedef U32   RTOS_SYS_SemaphoreT;
+typedef void* RTOS_SYS_MailqueueT;
+
+//typedef struct rt_thread *RTOS_ThreadT;
+//typedef struct rt_semaphore * RTOS_SemaphoreT;
+//typedef struct rt_messagequeue *RTOS_MailqueueT;
+//typedef struct rt_mailbox *RTOS_MailqueueT;
+//typedef struct rt_mutex *RTOS_MutexT;
+
+/*
+********************************************************************************
+********************************************************************************
+**
+** macros to define various suspend modes
+**
+********************************************************************************
+********************************************************************************
+*/
+#define RTOS_OK                     (RTOS_Status)0   //!< The OK status
+#define RTOS_FAILURE                (RTOS_Status)-1  //!< The general FAILURE status
+
+
+#define RTOS_NO_SUSPEND                0x00000000UL //!< do not suspend, return immediately
+#define RTOS_SUSPEND                   0xFFFFFFFFUL //!< suspend forever, wait for valid event without timeout
+
+#define RTOS_MAX_MAILQUEUE_ENTRIES     4096
+#define RTOS_MSG_IS_POINTER 0xFFFFFFFFUL //!< the message to transport is a generic pointer only
+
+typedef GBOOL                    RTOS_Flag;             //!< the boolean flag type
+typedef S32                      RTOS_Status;           //!< the result status type
+typedef S32                      RTOS_Size;             //!< the generic size type
+typedef U32                      RTOS_Time;             //!< the generic time type
+typedef RTOS_TimerT              RTOS_Timer;            //!< the generic time type
+typedef RTOS_ThreadT             RTOS_Thread;           //!< the thread identifier type
+typedef S32                      RTOS_Priority;         //!< the generic priority type
+typedef RTOS_SemaphoreT          RTOS_Semaphore;        //!< the semaphore identifier type
+typedef RTOS_MutexT              RTOS_Mutex;            //!< the mutex semaphore identifier type
+typedef RTOS_MailboxT            RTOS_Mailbox;          //!< the mailbox identifier type
+typedef RTOS_MailqueueT          RTOS_Mailqueue;        //!< the mailqueue identifier type
+typedef void*                    RTOS_Message;          //!< the generic message identifier type
+typedef void*                    RTOS_Memory;           //!< the generic memory pointer type
+typedef U32                      RTOS_Segment;          //!< the memory heap segment type
+typedef RTOS_ThreadFunctionT     RTOS_ThreadFunction;   //!< the thread function definition type
+typedef RTOS_HookFunctionT       RTOS_HookFunction;     //!< the hook function definition type
+typedef RTOS_ThreadT             RTOS_ThreadData;       //!< the optional thread data structure
+typedef RTOS_CondT               RTOS_Cond;             //!< the cond semaphore identifier type
+
+
+#define GKOS_TIMER_HOOK_TABLE_SIZE   8    //!< number of timer-tick hook function entries
+#define GKOS_SWITCH_HOOK_TABLE_SIZE  4    //!< number of context-switch hook function entries
+
+#define RTOS_ThreadPriorityHighest (RTOS_Priority)127 //!< The highest possible priority
+#define RTOS_ThreadPriorityLowest  (RTOS_Priority)1   //!< The lowest possible priority
+
+/*
+********************************************************************************
+********************************************************************************
+**
+** rtos type, gkos:0, rtthread:1
+**
+********************************************************************************
+********************************************************************************
+*/
+#define RTOS_GKOS                   0
+#define RTOS_RTTHREAD               1
+
+#define RTOS_TIMER_FLAG_DEACTIVATED       0x0             /**< timer is deactive */
+#define RTOS_TIMER_FLAG_ACTIVATED         0x1             /**< timer is active */
+#define RTOS_TIMER_FLAG_ONE_SHOT          0x0             /**< one shot timer */
+#define RTOS_TIMER_FLAG_PERIODIC          0x2             /**< periodic timer */
+
+#define RTOS_TIMER_FLAG_HARD_TIMER        0x0             /**< hard timer,the timer's callback function will be called in tick isr. */
+#define RTOS_TIMER_FLAG_SOFT_TIMER        0x4             /**< soft timer,the timer's callback function will be called in timer thread. */
+
+#define RTOS_TIMER_CTRL_SET_TIME          0x0             /**< set timer control command */
+#define RTOS_TIMER_CTRL_GET_TIME          0x1             /**< get timer control command */
+#define RTOS_TIMER_CTRL_SET_ONESHOT       0x2             /**< change timer to one shot */
+#define RTOS_TIMER_CTRL_SET_PERIODIC      0x3             /**< change timer to periodic */
+
+typedef struct
+{
+    RTOS_HookFunctionT timerFunctionArray[GKOS_TIMER_HOOK_TABLE_SIZE];
+    U32                timerFunctionCount;
+    RTOS_HookFunctionT switchFunctionArray[GKOS_SWITCH_HOOK_TABLE_SIZE];
+    U32                switchFunctionCount;
+}gkosHookDataT;
+
+gkosHookDataT*      gkosHookData;
+
+
+#define THREAD_TIMESLICE       10
+
+#define RTOS_ThreadCreate(function,arg,priority,stackBuffer,stackSize)  \
+        RTOS_CreateThread(stackBuffer, stackSize, priority, function, arg, 0, 0)
+U32 RTOS_DestroyThread( RTOS_ThreadT threadHandle );
+
+#define RTOS_ThreadSleep(msecs)    rt_thread_delay(msecs)
+
+
+
+U32 RTOS_ThreadSetName( RTOS_ThreadT threadHandle, const char* optName);
+U32 RTOS_SetThreadName( RTOS_ThreadT threadHandle, const char* optName);
+char * RTOS_ThreadGetName();
+
+
+
+
+RTOS_Status RTOS_MemoryRelease( RTOS_Memory memory );
+RTOS_Memory RTOS_MemoryAllocate( RTOS_Size bytes, RTOS_Flag shared );
+RTOS_Memory RTOS_MemorySet( RTOS_Memory mem, U8 value, RTOS_Size bytes );
+RTOS_Memory RTOS_MemoryCopy( RTOS_Memory dst, RTOS_Memory src, RTOS_Size bytes );
+
+RTOS_Memory RTOS_KernelMemoryAllocate( RTOS_Size bytes);
+RTOS_Status RTOS_KernelMemoryRelease( RTOS_Memory memory );
+
+#define RTOS_ATOM_PRINTF(format, ...)   do {\
+        U32 pval = 0;\
+        RTOS_EnterCritical(pval);\
+        printf("\033[0;31m[@%s.%d]->"format"\033[0;0m\n", __FUNCTION__, __LINE__, ##__VA_ARGS__);\
+        RTOS_LeaveCritical(pval);\
+    }while(0)
+
+#define RTOS_ASSERT(EX)                                                         \
+    if (!(EX))                                                                    \
+    {                                                                             \
+        volatile char dummy = 0;                                                  \
+        U32 pval = 0;\
+        RTOS_EnterCritical(pval);\
+        printf("(%s) assert failed at %s:%d thread name:%s\n", #EX, __FUNCTION__, __LINE__, RTOS_ThreadGetSelfName());\
+        while (dummy == 0);                                                       \
+    }
+
+//U32 GKOS_EnterCriticalSection( void );
+//void GKOS_LeaveCriticalSection( U32 cpuStatus );
+
+void RTOS_LockScheduler( void );
+void RTOS_UnlockScheduler( void );
+
+void gkosFinishThread( void );
+
+U32 RTOS_SleepThread( U32 msecs );
+
+
+RTOS_SemaphoreT RTOS_CreateSemaphore( U32 initCount );
+U32 RTOS_GetSemaphore( RTOS_SemaphoreT semaphoreHandle, U32 msecsTimeout );
+U32 RTOS_SetSemaphore( RTOS_SemaphoreT semaphoreHandle, U32 msecsTimeout );
+S32 RTOS_SemaphoreQuery( RTOS_Semaphore semaphoreHandle );
+RTOS_Status RTOS_SemaphoreDestroy( RTOS_Semaphore semaphoreHandle );
+
+#define RTOS_SemaphoreWait(semaphoreHandle, suspend)		RTOS_WaitSemaphore(semaphoreHandle, suspend)
+#define RTOS_SemaphoreWaitTimeout(semaphoreHandle, timeout) RTOS_GetSemaphore((RTOS_Semaphore)semaphoreHandle, timeout)
+#define RTOS_SemaphoreCreate(initCount)                     RTOS_CreateSemaphore(initCount)
+#define RTOS_SemaphoreRelease(semaphoreHandle)              RTOS_SetSemaphore((RTOS_Semaphore)semaphoreHandle,RTOS_SUSPEND)
+
+
+void RTOS_HwTickInit(void);
+
+
+void RTOS_KernelTimerSetHook(RTOS_HookFunction function);
+
+
+RTOS_MailqueueT RTOS_CreateMailqueue( U32 queueElements, U32 elementBytes );
+#define RTOS_MailqueueCreate(elements)      RTOS_CreateMailqueue(elements, RTOS_MSG_IS_POINTER)
+
+
+#define RTOS_EnterCritical(cpusr)   {cpusr=rt_hw_interrupt_disable();}
+#define RTOS_LeaveCritical(cpusr)   {rt_hw_interrupt_enable(cpusr);}
+
+extern U32 cpu_cpsr;
+
+#define RTOS_EnterCriticalEx()   cpu_cpsr = RTOS_EnterCriticalSection()
+#define RTOS_LeaveCriticalEx()   RTOS_LeaveCriticalSection(cpu_cpsr)
+
+#define RTOS_ThreadSuspend(threadHandle)                                RTOS_SuspendThread(threadHandle)
+#define RTOS_ThreadWakeup(threadHandle)                                 RTOS_WakeupThread(threadHandle)
+
+RTOS_Status RTOS_MailqueueSend(RTOS_Mailqueue mailqueue, RTOS_Message data);
+
+#define isb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c5, 4" \
+                                    : : "r" (0) : "memory")
+#define dsb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \
+                                    : : "r" (0) : "memory")
+#define dmb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" \
+                                    : : "r" (0) : "memory")
+
+void 	rtos_cache_inv_range(void *addr, unsigned int size);
+void 	rtos_cache_clean_range(void *addr, unsigned int size);
+
+
+U32 RTOS_Initialize(U32 Heap_size);
+
+#define RTOS_Initialize             RTOS_InitKernel
+
+#define RTOS_GetIdentity            RTOS_GetIdentity
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/*
+********************************************************************************
+** end of file
+********************************************************************************
+*/
+#endif /* RTOS_LIB_H */
+
+
+

+ 130 - 0
bsp/gkipc/armv6/rtos_memory.h

@@ -0,0 +1,130 @@
+/*!
+*******************************************************************************
+**
+** \file        rtos_memory.h
+**
+** \version     1.0
+**
+** \date        March 20, 2003
+**
+** \author      Wolfgang Larisch
+**
+** \brief       A generic OS adaptation layer library
+**
+** This header file defines RTOS internal functions which are implemented
+** either in the uC/OS or the Nucleus port (maybe others OSes will follow in
+** the future).
+**
+** \attention   THIS SAMPLE CODE IS PROVIDED AS IS. GOKE MICROELECTRONICS
+**              ACCEPTS NO RESPONSIBILITY OR LIABILITY FOR ANY ERRORS OR
+**              OMMISSIONS.
+**
+** (C) Copyright 2002 - 2007 by Goke Microelectronics China
+**
+*******************************************************************************
+*/
+#ifndef RTOS_MEMORY_H
+#define RTOS_MEMORY_H
+#include "gtypes.h"
+#include "rtos_lib.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!
+*******************************************************************************
+**
+** \brief Allocate a bunch of memory from the system heap
+**
+** This function allocates the given size of memory from the available
+** OS controlled SDRAM heap space.
+**
+** \param  size   size of memory in bytes to allocate.
+** \param  shared a boolean value which decides whether to allocate a
+**                memory block as shared (GTRUE) or as private (GFALSE)
+**                memory. Private memory can only be de-allocated by
+**                the thread that has allocated the memory, shared
+**                memory can be de-allocated by any thread.
+**
+** \return memory a pointer to the start address of the allocated memory
+**                block, or \b NULL if the required size of memory was not
+**                available.
+**
+** \sa     rtos_types
+**
+*******************************************************************************
+*/
+RTOS_Memory RTOS_SysMemoryAllocate( RTOS_Size size, RTOS_Flag shared );
+
+/*!
+*******************************************************************************
+**
+** \brief Release (de-allocate) a bunch of system heap memory
+**
+** This function de-allocates a previoulsy allocated bunch of memory.
+**
+** \param  memory a pointer to the start of the memory block  to release.
+**
+** \return status the result status, either \b RTOS_OK,
+**                \b RTOS_MEMORY_FAILURE if the given memory pointer does not
+**                point to dynamic allocated memory  or \b RTOS_THREAD_FAILURE
+**                if the allocated memory space is owned by a different
+**                thread.
+**
+** \sa     rtos_types
+** \sa     rtos_status
+**
+*******************************************************************************
+*/
+RTOS_Status RTOS_SysMemoryRelease( RTOS_Memory memory );
+
+/*
+*******************************************************************************
+**
+** This function allocates the given size of memory from the available
+** OS controlled user heap.
+** For better performace, we control all the available OS handled RAM by
+** segments of a min. size of RTOS_HeapMinAllocSize bytes.
+**
+*******************************************************************************
+*/
+RTOS_Memory RTOS_MemoryAllocate( RTOS_Size bytes, RTOS_Flag shared );
+
+RTOS_Memory RTOS_Malloc( RTOS_Size bytes);
+
+RTOS_Memory RTOS_Realloc( RTOS_Memory addr, RTOS_Size bytes );
+
+/*
+*******************************************************************************
+**
+** This function de-allocates a previoulsy allocated bunch of memory
+** within the user heap.
+**
+*******************************************************************************
+*/
+RTOS_Status RTOS_MemoryRelease( RTOS_Memory memory );
+
+/*
+*******************************************************************************
+**
+** This function sets the given amount of bytes in the given source address
+** the the specified byte value.
+**
+*******************************************************************************
+*/
+RTOS_Memory RTOS_MemorySet( RTOS_Memory mem, U8 value, RTOS_Size bytes );
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/*
+*******************************************************************************
+**
+** end
+**
+*******************************************************************************
+*/
+#endif /* RTOS_MEMORY_H */

+ 77 - 0
bsp/gkipc/armv6/stack.c

@@ -0,0 +1,77 @@
+/*
+ * File      : stack.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+#include <rtthread.h>
+
+/*****************************/
+/* CPU Mode                  */
+/*****************************/
+#define USERMODE		0x10
+#define FIQMODE			0x11
+#define IRQMODE			0x12
+#define SVCMODE			0x13
+#define ABORTMODE		0x17
+#define UNDEFMODE		0x1b
+#define MODEMASK		0x1f
+#define NOINT			0xc0
+
+/**
+ * This function will initialize thread stack
+ *
+ * @param tentry the entry of thread
+ * @param parameter the parameter of entry 
+ * @param stack_addr the beginning stack address
+ * @param texit the function will be called when thread exit
+ *
+ * @return stack address
+ */
+rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter,
+	rt_uint8_t *stack_addr, void *texit)
+{
+	rt_uint32_t *stk;
+
+    stack_addr += sizeof(rt_uint32_t);
+    stack_addr  = (rt_uint8_t *)RT_ALIGN_DOWN((rt_uint32_t)stack_addr, 8);
+    stk      = (rt_uint32_t *)stack_addr;
+
+    *(--stk) = (rt_uint32_t)tentry;         /* entry point */
+    *(--stk) = (rt_uint32_t)texit;          /* lr */
+    *(--stk) = 0xdeadbeef;                  /* r12 */
+    *(--stk) = 0xdeadbeef;                  /* r11 */
+    *(--stk) = 0xdeadbeef;                  /* r10 */
+    *(--stk) = 0xdeadbeef;                  /* r9 */
+    *(--stk) = 0xdeadbeef;                  /* r8 */
+    *(--stk) = 0xdeadbeef;                  /* r7 */
+    *(--stk) = 0xdeadbeef;                  /* r6 */
+    *(--stk) = 0xdeadbeef;                  /* r5 */
+    *(--stk) = 0xdeadbeef;                  /* r4 */
+    *(--stk) = 0xdeadbeef;                  /* r3 */
+    *(--stk) = 0xdeadbeef;                  /* r2 */
+    *(--stk) = 0xdeadbeef;                  /* r1 */
+    *(--stk) = (rt_uint32_t)parameter;      /* r0 : argument */
+	*(--stk) = SVCMODE;						/* cpsr */
+	*(--stk) = SVCMODE;						/* spsr */
+
+	/* return task's current stack address */
+	return (rt_uint8_t *)stk;
+}
+

+ 481 - 0
bsp/gkipc/armv6/start_gcc.s

@@ -0,0 +1,481 @@
+/*
+ * File      : start.S
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date                 Author          Notes
+ * 2016/3/9 16:27:48    louis           first version
+ */
+
+#define CONFIG_STACKSIZE    512
+#define S_FRAME_SIZE        72
+
+#define S_OLD_R0            68
+#define S_PSR               64
+#define S_PC                60
+#define S_LR                56
+#define S_SP                52
+
+#define S_IP                48
+#define S_FP                44
+#define S_R10               40
+#define S_R9                36
+#define S_R8                32
+#define S_R7                28
+#define S_R6                24
+#define S_R5                20
+#define S_R4                16
+#define S_R3                12
+#define S_R2                8
+#define S_R1                4
+#define S_R0                0
+
+.equ    USERMODE,           0x10
+.equ    FIQMODE,            0x11
+.equ    IRQMODE,            0x12
+.equ    SVCMODE,            0x13
+.equ    ABORTMODE,          0x17
+.equ    UNDEFMODE,          0x1b
+.equ    MODEMASK,           0x1f
+.equ    NOINT,              0xc0
+
+
+
+
+    .text
+    .section ".ARM1176START"
+    .code 32
+
+
+@*******************************************************************************
+@** Common cpu modes
+@*******************************************************************************
+
+    .equ ARM1176_MODE_USR,   0x10  @ CPSR_c xxx10000
+    .equ ARM1176_MODE_FIQ,   0x11  @ CPSR_c xxx10001
+    .equ ARM1176_MODE_IRQ,   0x12  @ CPSR_c xxx10010
+    .equ ARM1176_MODE_SVC,   0x13  @ CPSR_c xxx10011
+    .equ ARM1176_MODE_ABT,   0x17  @ CPSR_c xxx10111
+    .equ ARM1176_MODE_UND,   0x1B  @ CPSR_c xxx11011
+    .equ ARM1176_MODE_SYS,   0x1F  @ CPSR_c xxx11111
+    .equ ARM1176_CPSR_I_BIT, 0x80  @ CPSR_c 100xxxxx
+    .equ ARM1176_CPSR_F_BIT, 0x40  @ CPSR_c 010xxxxx
+    .equ ARM1176_CPSR_T_BIT, 0x20  @ CPSR_c 001xxxxx
+
+
+
+.globl _start
+.globl  ARM1176_Start
+_start:
+ARM1176_Start:
+    msr cpsr_c,#(ARM1176_MODE_SYS | ARM1176_CPSR_I_BIT | ARM1176_CPSR_F_BIT)    @disable irq/fiq first
+    ldr r0, =Reset          ;@load translation table base address
+    mcr p15,0,r0,c12,c0,0   ;@write translation table base address req
+    nop
+    nop
+    nop
+    nop
+    nop
+    nop
+    nop
+    nop
+    nop
+    nop
+    nop
+    nop
+    nop
+Reset:
+    ldr pc, =reset
+    ldr pc, =vector_undef
+    ldr pc, =vector_swi
+    ldr pc, =vector_pabt
+    ldr pc, =vector_dabt
+    ldr pc, =vector_resv
+    ldr pc, =vector_irq
+    ldr pc, =vector_fiq
+    nop
+    nop
+
+
+.balignl    16,0xdeadbeef
+
+/*
+ *************************************************************************
+ *
+ * Startup Code (reset vector)
+ * relocate armboot to ram
+ * setup stack
+ * jump to second stage
+ *
+ *************************************************************************
+ */
+
+
+/*
+ * rtthread bss start and end which are defined in linker script
+ */
+
+
+.extern __stack_start__
+
+
+
+.equ Mode_USR,        0x10
+.equ Mode_FIQ,        0x11
+.equ Mode_IRQ,        0x12
+.equ Mode_SVC,        0x13
+.equ Mode_ABT,        0x17
+.equ Mode_UND,        0x1B
+.equ Mode_SYS,        0x1F
+
+.equ I_Bit,           0x80            @ when I bit is set, IRQ is disabled
+.equ F_Bit,           0x40            @ when F bit is set, FIQ is disabled
+
+.equ UND_Stack_Size,  0x00000200
+.equ SVC_Stack_Size,  0x00000200
+.equ ABT_Stack_Size,  0x00000000
+.equ FIQ_Stack_Size,  0x00000000
+.equ IRQ_Stack_Size,  0x00000200
+.equ USR_Stack_Size,  0x00000200
+
+#define ISR_Stack_Size  (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \
+                 FIQ_Stack_Size + IRQ_Stack_Size)
+
+.globl stack_top
+stack_top:
+    .word __stack_start__
+
+
+
+    .extern ARM1176_TcmInitialise
+    .extern ARM1176_MmuInitialise
+    .extern GH_VIC_set_EdgeClr
+    .extern entry
+
+/*
+ *************************************************************************
+ *
+ * Jump vector table
+ *
+ *************************************************************************
+ */
+
+/* ----------------------------------entry------------------------------*/
+reset:
+    msr cpsr_c,#(ARM1176_MODE_SYS | ARM1176_CPSR_I_BIT | ARM1176_CPSR_F_BIT)    @disable irq/fiq first
+    @/* First read in some misc registers */
+    mrc p15, 0, r0, c0, c0, 0     @/* Read ID value {A5S=0x41 1 7 b36 5}*/
+    mrc p15, 0, r1, c0, c0, 1     @/* Read cache type {0x1d152152}*/
+    mrc p15, 0, r2, c0, c0, 2     @/* Read TCM status {0x10001}*/
+
+#ifdef GK7102C    
+    @mrc    p15, 0, r0, c15,c14,0  @ read CP15 register c15 into r0
+    @orr    r0,  r0,#0x80000000    @ system bit enabled
+    @bic    r0,  r0,#0x00000077    @
+    @orr    r0,  r0,#0x00000055    @ specifies 16KB data cache
+    @mcr    p15, 0, r0, c15,c14,0  @ wraite CP15 register c15 into r0
+
+    mrc     p15, 0, r0, c1, c0, 1  @read CP15 register c1 into r0
+    orr     r0,  r0,#0x00000040    @CZ bit enabled
+    mcr     p15, 0, r0, c1, c0, 1  @read CP15 register c1 into r0
+#endif
+    
+    @/* Turn on instrucion cache and disable MMU */
+    mrc p15, 0, r0, c1, c0, 0     @/* Read control register {0x5327d}*/
+    @bic r0, r0, #0x1000          @ Turn off bit 12 - I-cache
+    orr    r0, r0, #0x1000        @ Turn on bit 12 - I-cache
+    @bic r0, r0, #0x0004          @ Turn off bit 03 - D-cache
+    orr    r0, r0, #0x0004        @ Turn on bit 03 - D-cache
+    bic r0, r0, #0x2000           @ Turn off bit 13 - HV
+    bic r0, r0, #0x0001           @ Turn off bit 1 - MMU
+
+    @orr    r0, r0, #0x2    @ Turn on bit 1 - Alignment fault
+    bic r0, r0, #0x400000   @ Turn off bit 22 - Unainged support
+
+    @bic    r0, r0, #0x2        @ Turn off bit 1 - Alignment fault
+    @orr    r0, r0, #0x400000   @ Turn on bit 22 - Unainged support
+
+    mcr p15, 0, r0, c1, c0, 0   @/* Write control register */
+
+    mov r0, #0x1
+    mcr p15, 0, r0, c3, c0, 0   @/* Write domain access control reg */
+
+
+    @bl switch_core_freq    @/* Change PLL for core if necessary */
+    @bl memsetup5       @/* Initialize Memory */
+
+
+    @/* -------------------------------------------------- */
+    @/* Redirect peripheral port 0x60000000 - 0x7fffffff   */
+    @/* -------------------------------------------------- */
+    .if CPU_USE_GK710XS==1
+    mov r0, #0x80000000
+    orr r0, r0, #0x00000015 @0x14=512M
+    .else
+    mov r0, #0x60000000
+    orr r0, r0, #0x00000014 @0x14=512M
+    .endif
+    mcr p15, 0, r0, c15, c2, 4
+
+    @ clear the irq or fiq first
+    mov r0,#0x0
+    mov r1,#0xFFFFFFFF
+    bl GH_VIC_set_EdgeClr
+    mov r0,#0x1
+    mov r1,#0xFFFFFFFF
+    bl GH_VIC_set_EdgeClr
+
+    nop
+
+    @ bl ARM1176_TcmInitialise
+    msr cpsr_c,#(ARM1176_MODE_SYS | ARM1176_CPSR_I_BIT | ARM1176_CPSR_F_BIT)    @disable irq/fiq first
+    .if ARM1176_USE_VFP == 1
+    bl ARM1176_VfpInitialise
+    bl ARM1176_VfpSetFastmode
+    .endif
+    bl ARM1176_Invalid_Cache
+
+    /* setup stack */
+    ldr     r0, =stack_top
+    ldr     r0, [r0]
+
+    @  Enter Undefined Instruction Mode and set its Stack Pointer
+    msr     cpsr_c, #Mode_UND|I_Bit|F_Bit
+    mov     sp, r0
+    sub     r0, r0, #UND_Stack_Size
+
+    @  Enter Abort Mode and set its Stack Pointer
+    msr     cpsr_c, #Mode_ABT|I_Bit|F_Bit
+    mov     sp, r0
+    sub     r0, r0, #ABT_Stack_Size
+
+    @  Enter FIQ Mode and set its Stack Pointer
+    msr     cpsr_c, #Mode_FIQ|I_Bit|F_Bit
+    mov     sp, r0
+    sub     r0, r0, #FIQ_Stack_Size
+
+    @  Enter IRQ Mode and set its Stack Pointer
+    msr     cpsr_c, #Mode_IRQ|I_Bit|F_Bit
+    mov     sp, r0
+    sub     r0, r0, #IRQ_Stack_Size
+
+    @  Enter Supervisor Mode and set its Stack Pointer
+    msr     cpsr_c, #Mode_SVC|I_Bit|F_Bit
+    mov     sp, r0
+    sub     r0, r0, #SVC_Stack_Size
+
+    @  Enter User Mode and set its Stack Pointer
+    mov     sp, r0
+    sub     sl, sp, #USR_Stack_Size
+
+    /* clear .bss */
+    mov     r0,#0                   /* get a zero                       */
+    ldr     r1,=__bss_start__         /* bss start                      */
+    ldr     r2,=__bss_end__           /* bss end                            */
+
+bss_loop:
+    cmp     r1,r2                   /* check if data to clear           */
+    strlo   r0,[r1],#4              /* clear 4 bytes                    */
+    blo     bss_loop                /* loop until done                  */
+
+    /* call C++ constructors of global objects                          */
+    ldr     r0, =__ctors_start__
+    ldr     r1, =__ctors_end__
+
+ctor_loop:
+    cmp     r0, r1
+    beq     ctor_end
+    ldr     r2, [r0], #4
+    stmfd   sp!, {r0-r1}
+    mov     lr, pc
+    bx      r2
+    ldmfd   sp!, {r0-r1}
+    b       ctor_loop
+
+ctor_end:
+
+
+    @ need nocache buffer
+    bl ARM1176_MmuInitialise
+
+    /* start RT-Thread Kernel       */
+    ldr     pc, =entry
+
+    .global ARM1176_Invalid_Cache
+    .func   ARM1176_Invalid_Cache
+
+ARM1176_Invalid_Cache:
+    stmfd sp!,{r0-r12,lr}
+    mov r11,lr
+
+    mov r0,#0x0        @Set [31:30]
+    mov r1,#0x3
+loop1:
+    mov r2,#0x0
+    mov r3,#0x80
+
+loop2:
+    mov r4,r0,LSL #30
+    mov r5,r2,LSL #5        @Index [S+4:5] S=8 32K
+    add r4,r4,r5
+    mcr    p15, 0, r4, c7, c5, 2
+    add r2,r2,#0x1
+    cmp r2,r3
+    bne loop2
+
+    add r0,r0,#1
+    cmp r0,r1
+    bne loop1
+
+    mov lr,r11            @ restore link register
+    ldmfd sp!,{r0-r12,lr}
+    bx lr                 @ branch back to caller
+
+    .size ARM1176_Invalid_Cache, . - ARM1176_Invalid_Cache
+    .endfunc
+
+
+.global cpu_reset
+cpu_reset:
+    mov pc, lr
+
+/*
+ *************************************************************************
+ *
+ * Interrupt handling
+ *
+ *************************************************************************
+ */
+
+/* exception handlers               */
+    .align  5
+vector_undef:
+    sub     sp, sp, #S_FRAME_SIZE
+    stmia   sp, {r0 - r12}          /* Calling r0-r12                   */
+    add     r8, sp, #S_PC
+    stmdb   r8, {sp, lr}^           /* Calling SP, LR                   */
+    str     lr, [r8, #0]            /* Save calling PC                  */
+    mrs     r6, spsr
+    str     r6, [r8, #4]            /* Save CPSR                        */
+    str     r0, [r8, #8]            /* Save OLD_R0                      */
+    mov     r0, sp
+
+    bl      rt_hw_trap_udef
+
+    .align  5
+vector_swi:
+    bl      rt_hw_trap_swi
+
+    .align  5
+vector_pabt:
+    bl      rt_hw_trap_pabt
+
+    .align  5
+vector_dabt:
+    sub     sp, sp, #S_FRAME_SIZE
+    stmia   sp, {r0 - r12}          /* Calling r0-r12                   */
+    add     r8, sp, #S_PC
+    stmdb   r8, {sp, lr}^           /* Calling SP, LR                   */
+    str     lr, [r8, #0]            /* Save calling PC                  */
+    mrs     r6, spsr
+    str     r6, [r8, #4]            /* Save CPSR                        */
+    str     r0, [r8, #8]            /* Save OLD_R0                      */
+    mov     r0, sp
+
+    bl      rt_hw_trap_dabt
+
+    .align  5
+vector_resv:
+    bl      rt_hw_trap_resv
+
+    .align  5
+.globl      rt_interrupt_enter
+.globl      rt_interrupt_leave
+.globl      rt_thread_switch_interrupt_flag
+.globl      rt_interrupt_from_thread
+.globl      rt_interrupt_to_thread
+vector_irq:
+    stmfd   sp!, {r0-r12,lr}
+    bl      rt_interrupt_enter
+    bl      rt_hw_trap_irq
+    bl      rt_interrupt_leave
+
+    /* if rt_thread_switch_interrupt_flag set, jump to _interrupt_thread_switch and don't return */
+    ldr     r0, =rt_thread_switch_interrupt_flag
+    ldr     r1, [r0]
+    cmp     r1, #1
+    beq     _interrupt_thread_switch
+
+    ldmfd   sp!, {r0-r12,lr}
+    subs    pc, lr, #4
+
+    .align  5
+vector_fiq:
+    stmfd   sp!,{r0-r7,lr}
+    bl      rt_hw_trap_fiq
+    ldmfd   sp!,{r0-r7,lr}
+    subs    pc,lr,#4
+
+_interrupt_thread_switch:
+    mov     r1,  #0                 /* clear rt_thread_switch_interrupt_flag*/
+    str     r1,  [r0]
+
+    ldmfd   sp!, {r0-r12,lr}        /* reload saved registers           */
+    stmfd   sp!, {r0-r3}            /* save r0-r3                       */
+    mov     r1,  sp
+    add     sp,  sp, #16            /* restore sp                       */
+    sub     r2,  lr, #4             /* save old task's pc to r2         */
+
+    mrs     r3,  spsr               /* disable interrupt                */
+    orr     r0,  r3, #NOINT
+    msr     spsr_c, r0
+
+    ldr     r0,  =.+8               /* switch to interrupted task's stack*/
+    movs    pc,  r0
+
+    stmfd   sp!, {r2}               /* push old task's pc               */
+    stmfd   sp!, {r4-r12,lr}        /* push old task's lr,r12-r4        */
+    mov     r4,  r1                 /* Special optimised code below     */
+    mov     r5,  r3
+    ldmfd   r4!, {r0-r3}
+    stmfd   sp!, {r0-r3}            /* push old task's r3-r0            */
+    stmfd   sp!, {r5}               /* push old task's psr              */
+    mrs     r4,  spsr
+    stmfd   sp!, {r4}               /* push old task's spsr             */
+
+    ldr     r4,  =rt_interrupt_from_thread
+    ldr     r5,  [r4]
+    str     sp,  [r5]               /* store sp in preempted tasks's TCB*/
+
+    ldr r6,  =rt_interrupt_to_thread
+    ldr r6,  [r6]
+    ldr sp,  [r6]                   /* get new task's stack pointer     */
+
+    ldmfd   sp!, {r4}               /* pop new task's spsr              */
+    msr     SPSR_cxsf, r4
+    ldmfd   sp!, {r4}               /* pop new task's psr               */
+    msr     CPSR_cxsf, r4
+
+    ldmfd   sp!, {r0-r12,lr,pc}     /* pop new task's r0-r12,lr & pc    */
+
+
+
+@*******************************************************************************
+@** End of file
+@*******************************************************************************
+

+ 56 - 0
bsp/gkipc/armv6/system_clock.c

@@ -0,0 +1,56 @@
+/*
+ * File      : clock.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+
+#include <rtthread.h>
+#include "gk7101.h"
+#include "board.h"
+
+/**
+ * @brief System Clock Configuration
+ */
+void rt_hw_clock_init(void)
+{
+
+}
+
+void rt_hw_us_delay(rt_uint32_t us)
+{
+    rt_uint32_t     start_time = 0;
+    rt_uint32_t     end_time = 0;
+    int     time_difference  = 0;
+
+    start_time = gkosGetTicks();
+    do
+    {
+        end_time = gkosGetTicks();
+        time_difference = (rt_uint32_t)(end_time - start_time);
+        /* check overflow */
+        if(start_time > end_time)
+        {
+            time_difference = ((time_difference < 0L) ? -time_difference : time_difference); /* C-LIB code for labs() */
+        }
+    }while(time_difference < (us/1000));
+
+}
+
+

+ 250 - 0
bsp/gkipc/armv6/trap.c

@@ -0,0 +1,250 @@
+/*
+ * File      : trap.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+
+#include <rtthread.h>
+#include <rthw.h>
+
+#include "gk7101.h"
+#include <gtypes.h>
+#include <gd_int.h>
+#include "rtos_lib.h"
+
+
+extern struct rt_thread *rt_current_thread;
+#ifdef RT_USING_FINSH
+extern long list_thread(void);
+#endif
+
+/**
+ * this function will show registers of CPU
+ *
+ * @param regs the registers point
+ */
+
+/* FIXME(Heyong): add for print the system infos when sys abort */
+static void _rtt_statistics()
+{
+    rt_uint32_t total;
+    rt_uint32_t used;
+    rt_uint32_t max_used;
+    struct rt_thread *thread;
+    struct rt_list_node *node;
+    rt_uint8_t *ptr;
+
+    rt_base_t level;
+    struct rt_object_information *information;
+
+    information = rt_object_get_information(RT_Object_Class_Thread);
+    RT_ASSERT(information != RT_NULL);
+
+    struct rt_list_node *list = &(information->object_list);
+
+    level = rt_hw_interrupt_disable();
+
+    for (node = list->next; node != list; node = node->next)
+    {
+        thread = rt_list_entry(node, struct rt_thread, list);
+        //if(thread) thread->total_tick = 0;
+    }
+
+    rt_hw_interrupt_enable(level);
+    rt_memory_info(&total,&used,&max_used);
+    rt_kprintf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
+    rt_kprintf("\n         memory info       size \n");
+    rt_kprintf("------------------------- ------\n");
+    rt_kprintf("total memory:             (%dKB)\n",  total/1024);
+    rt_kprintf("used memory :             (%dKB)\n",  used/1024);
+    rt_kprintf("maximum allocated memory: (%dKB)\n\n",  max_used/1024);
+
+    rt_kprintf("          thread                 pri  status     sp     stack addr stack size  max used \n");
+    rt_kprintf("-------------------------------- --- ------- ---------- ---------- ---------- ---------- \n");
+    for (node = list->next; node != list; node = node->next)
+    {
+        thread = rt_list_entry(node, struct rt_thread, list);
+#if 0
+        rt_kprintf("%-32.*s 0x%02x", RT_NAME_MAX, thread->name, thread->current_priority);
+#else
+        int priority = thread->current_priority;
+        rt_kprintf("%-32.*s %03d", RT_NAME_MAX, thread->name, priority);
+#endif
+        if (thread->stat == RT_THREAD_READY)        rt_kprintf(" ready  ");
+        else if (thread->stat == RT_THREAD_SUSPEND) rt_kprintf(" suspend");
+        else if (thread->stat == RT_THREAD_INIT)    rt_kprintf(" init   ");
+        else if (thread->stat == RT_THREAD_CLOSE)   rt_kprintf(" close  ");
+
+        ptr = (rt_uint8_t*)thread->stack_addr;
+        while (*ptr == '#')ptr++;
+
+        rt_kprintf("  0x%08x 0x%08x 0x%08x 0x%08x  \n",
+            thread->stack_size + ((rt_uint32_t)thread->stack_addr - (rt_uint32_t)thread->sp),
+            thread->stack_addr,
+            thread->stack_size,
+            thread->stack_size - ((rt_uint32_t) ptr - (rt_uint32_t)thread->stack_addr)
+           );
+    }
+    rt_kprintf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
+}
+
+// FIXME(heyong): add for debug when sys abort.
+int g_eth_input = 0;
+int g_eth_output = 0;
+int g_wifi_input = 0;
+int g_wifi_output = 0;
+void rt_hw_show_register (struct rt_hw_register *regs)
+{
+	rt_kprintf("Execption:\n");
+	rt_kprintf("r00:0x%08x r01:0x%08x r02:0x%08x r03:0x%08x\n", regs->r0, regs->r1, regs->r2, regs->r3);
+	rt_kprintf("r04:0x%08x r05:0x%08x r06:0x%08x r07:0x%08x\n", regs->r4, regs->r5, regs->r6, regs->r7);
+	rt_kprintf("r08:0x%08x r09:0x%08x r10:0x%08x\n", regs->r8, regs->r9, regs->r10);
+	rt_kprintf("fp :0x%08x ip :0x%08x\n", regs->fp, regs->ip);
+	rt_kprintf("sp :0x%08x lr :0x%08x pc :0x%08x\n", regs->sp, regs->lr, regs->pc);
+	rt_kprintf("cpsr:0x%08x\n", regs->cpsr);
+	rt_kprintf("eth info : in = %d out = %d\n", g_eth_input, g_eth_output);
+	rt_kprintf("wifi info: in = %d out = %d\n", g_wifi_input, g_wifi_output);
+	_rtt_statistics();
+}
+
+/**
+ * When ARM7TDMI comes across an instruction which it cannot handle,
+ * it takes the undefined instruction trap.
+ *
+ * @param regs system registers
+ *
+ * @note never invoke this function in application
+ */
+void rt_hw_trap_udef(struct rt_hw_register *regs)
+{
+	rt_hw_show_register(regs);
+
+	rt_kprintf("undefined instruction\n");
+	rt_kprintf("thread - %s stack:\n", rt_current_thread->name);
+
+#ifdef RT_USING_FINSH
+	list_thread();
+#endif
+	rt_hw_cpu_shutdown();
+}
+
+/**
+ * The software interrupt instruction (SWI) is used for entering
+ * Supervisor mode, usually to request a particular supervisor
+ * function.
+ *
+ * @param regs system registers
+ *
+ * @note never invoke this function in application
+ */
+void rt_hw_trap_swi(struct rt_hw_register *regs)
+{
+	rt_hw_show_register(regs);
+
+	rt_kprintf("software interrupt\n");
+	rt_hw_cpu_shutdown();
+}
+
+/**
+ * An abort indicates that the current memory access cannot be completed,
+ * which occurs during an instruction prefetch.
+ *
+ * @param regs system registers
+ *
+ * @note never invoke this function in application
+ */
+void rt_hw_trap_pabt(struct rt_hw_register *regs)
+{
+	rt_hw_show_register(regs);
+
+	rt_kprintf("prefetch abort\n");
+	rt_kprintf("thread - %s stack:\n", rt_current_thread->name);
+
+#ifdef RT_USING_FINSH
+	list_thread();
+#endif
+	rt_hw_cpu_shutdown();
+}
+
+/**
+ * An abort indicates that the current memory access cannot be completed,
+ * which occurs during a data access.
+ *
+ * @param regs system registers
+ *
+ * @note never invoke this function in application
+ */
+void rt_hw_trap_dabt(struct rt_hw_register *regs)
+{
+
+	rt_kprintf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
+	rt_kprintf("data abort\n");
+	rt_kprintf("thread - [%s] stack:\n", rt_current_thread->name);
+
+	rt_hw_show_register(regs);
+
+#ifdef RT_USING_FINSH
+	list_thread();
+#endif
+	rt_hw_cpu_shutdown();
+}
+
+/**
+ * Normally, system will never reach here
+ *
+ * @param regs system registers
+ *
+ * @note never invoke this function in application
+ */
+void rt_hw_trap_resv(struct rt_hw_register *regs)
+{
+	rt_kprintf("not used\n");
+	rt_hw_show_register(regs);
+	rt_hw_cpu_shutdown();
+}
+
+extern struct rt_irq_desc irq_desc[];
+
+void rt_hw_trap_irq()
+{
+    int index;
+	//rt_kprintf("irq interrupt request\n");
+    GD_IRQ_ISR();
+
+	if(gkosHookData)
+	{
+	    for( index=0; index < gkosHookData->timerFunctionCount; index++ )
+	    {
+	        if( gkosHookData->timerFunctionArray[index] )
+	        {
+	            (*gkosHookData->timerFunctionArray[index])(NULL);
+	        }
+	    }
+	}
+}
+
+void rt_hw_trap_fiq()
+{
+	//rt_kprintf("fast interrupt request\n");
+	GD_FIQ_ISR();
+	//rt_tick_increase();
+}
+
+/*@}*/

+ 24 - 0
bsp/gkipc/drivers/SConscript

@@ -0,0 +1,24 @@
+from building import *
+Import('rtconfig')
+
+cwd = GetCurrentDir()
+src	= Glob('*.c')
+path = [cwd + '/..']
+
+if GetDepend('SOC_GK7101') or GetDepend('SOC_GK7102'):
+    path += [cwd + '/../libraries/drv/710X/gh/inc', cwd + '/../libraries/drv/710X/gd/inc']
+elif GetDepend('SOC_GK7101S') or GetDepend('SOC_GK7102S'):
+    path += [cwd + '/../libraries/drv/710XS/gh/inc', cwd + '/../libraries/drv/710XS/gd/inc']
+elif GetDepend('SOC_GK7102C'):
+    path += [cwd + '/../libraries/drv/7102C/gh/inc', cwd + '/../libraries/drv/7102C/gd/inc']
+	
+path += [cwd + '/../../../components/drivers/include/drivers']
+path += [cwd + '/../libraries/adi/inc']
+path += [cwd + '/../platform/board']
+path += [cwd + '/../platform']
+
+libcwd = str(Dir('#'))
+
+group = DefineGroup('drivers', src, depend = [''], CPPPATH = path)
+
+Return('group')

+ 131 - 0
bsp/gkipc/drivers/board.c

@@ -0,0 +1,131 @@
+#include <rtthread.h>
+#include <rthw.h>
+
+#include "gd_int.h"
+#include "gd_gpio.h"
+#include "gd_timer.h"
+#include "drv_uart.h"
+#include "gpio_cfg.h"
+#include "board.h"
+#include "drv_flash.h"
+#include "gh_debug_rct.h"
+
+#ifdef RT_USING_I2C
+#include "drv_i2c.h"
+#endif
+
+#ifdef RT_USING_SPI
+#include "drv_ssi.h"
+#endif
+
+#ifdef RT_USING_WDT
+#include "drv_wdt.h"
+#endif
+
+#ifdef RT_USING_GK_DMA
+#include "drv_dma.h"
+#endif
+
+#ifdef RT_USING_ADC
+#include "drv_adc.h"
+#endif
+
+#ifdef RT_USING_PWM
+#include "drv_pwm.h"
+#endif
+#include "rtos_lib.h"
+
+extern unsigned char __heap_start__[];
+extern unsigned char __heap_end__[];
+extern unsigned char __nocache_buffer_start__[];
+
+/**
+ * This function will init goke board
+ */
+void rt_hw_board_init(void)
+{
+    rt_uint32_t code_seg_size = 0;
+    rt_uint32_t heap_seg_size = 0;
+    rt_uint32_t os_end_address=0;
+
+    GD_TIMER_INIT_PARAMS_S gdTimerParams;
+    GD_GPIO_XREF_S gdGpioXrefTable[] = { SYSTEM_GPIO_XREF_TABLE };
+    GD_GPIO_INIT_PARAMS_S gdGpioInitParam =
+    {
+        .irqPriority = GD_INT_MID_PRIORITY,
+        .phyType = 0,
+        .xrefTableCount = sizeof(gdGpioXrefTable)/sizeof(gdGpioXrefTable[0]),
+        .xrefTable = gdGpioXrefTable,
+    };
+
+    gdTimerParams.softTimerReg      = GD_REG_TIMER1;
+    gdTimerParams.hardTimerReg      = GD_REG_TIMER2;
+    gdTimerParams.gpregTimerReg     = GD_REG_TIMER3;
+    gdTimerParams.softTimerpriority  = GD_INT_MID_PRIORITY;
+    gdTimerParams.hardTimerpriority  = GD_INT_MID_PRIORITY;
+    gdTimerParams.gpregTimerpriority = GD_INT_MID_PRIORITY;
+
+    GD_INT_DisableAllInterrupts();
+
+    // Sensor ioctrl
+    GH_PLL_set_IOCTRL_SENSOR(0x00000012);
+
+    GD_INT_Init(NULL);
+    GD_TIMER_Init(&gdTimerParams);
+    GD_GPIO_Init(&gdGpioInitParam);
+
+    /* initialize hardware interrupt */
+    rt_hw_interrupt_init();
+
+    /* initialize heap memory system */
+    code_seg_size = __heap_end__ - __nocache_buffer_start__;
+    heap_seg_size = DDR_MEMORY_OS_SIZE - code_seg_size;
+    os_end_address= (rt_uint32_t)__heap_end__+heap_seg_size;
+    rt_system_heap_init((void*)__heap_end__, (void*)os_end_address);
+
+    /* initialize uart */
+    rt_hw_uart_init();
+    rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
+
+    /* initalize sflash */
+    rt_flash_init();
+
+    RTOS_HwTickInit();
+}
+
+int rt_board_driver_init(void)
+{
+#ifdef RT_USING_I2C
+    rt_hw_i2c_init();
+#endif
+
+#ifdef RT_USING_SPI
+    rt_hw_spi_init();
+#endif
+
+#ifdef RT_USING_WDT
+    rt_hw_wdt_init();
+#endif
+
+#ifdef RT_USING_GK_DMA
+    rt_gk_dma_init();
+#endif
+
+#ifdef RT_USING_ADC
+    rt_hw_adc_init();
+#endif
+
+#ifdef RT_USING_PWM
+    rt_hw_pwm_init();
+#endif
+
+    return 0;
+}
+
+//static unsigned long nticks = 0;
+unsigned long gkosGetTicks(void)
+{
+    return rt_tick_get();
+}
+
+/*@}*/

+ 32 - 0
bsp/gkipc/drivers/board.h

@@ -0,0 +1,32 @@
+/*
+ * File      : board.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Develop Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2011-01-13     weety      add board.h to this bsp
+ */
+
+#ifndef __BOARD_H__
+#define __BOARD_H__
+
+unsigned long gkosGetTicks(void);
+void rt_hw_board_init(void);
+int rt_board_driver_init(void);
+
+#endif

+ 237 - 0
bsp/gkipc/drivers/drv_adc.c

@@ -0,0 +1,237 @@
+/*
+ * File      : drv_adc.c
+ * This file is part of GK710X BSP for RT-Thread distribution.
+ *
+ * Copyright (c) 2017 GOKE Microelectronics Co., Ltd.
+ * All rights reserved
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *  Visit http://www.goke.com to get contact with Goke.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+
+#include "drv_adc.h"
+#ifdef RT_USING_ADC
+#include "gtypes.h"
+#include "gd_adc.h"
+#include "platform.h"
+
+#include <rtdef.h>
+#include <rtthread.h>
+
+#define GK_TEST_ADC
+
+#define IOCTL_GET_ADC_DATA 1
+#define IOCTL_ADC_POWER_DOWN 0xff
+#define ADC_WRAP_BASE (0xf1200000)
+#define ADC_IRQn (23)
+#define ADC_MAX_CONTROLLER (1)
+#define ADC_STATUS_COLESD (0)
+#define ADC_STATUS_OPEN (1)
+
+static rt_err_t gk_adc_read_data(struct wrap_adc_obj *adc, rt_uint32_t channel,
+                               rt_uint32_t *buf)
+{
+    rt_err_t ret = RT_EOK;
+
+    ret = GD_ADC_Read((GD_HANDLE*)&(adc->handle), buf);
+
+    return ret;
+}
+
+static rt_err_t gk_adc_init(rt_device_t dev)
+{
+    rt_err_t ret = RT_EOK;
+
+    ret = (rt_err_t)GD_ADC_Init();
+
+    return ret;
+}
+
+static rt_err_t gk_adc_open(rt_device_t dev, rt_uint16_t oflag)
+{
+    rt_err_t ret = RT_EOK;
+    GD_ADC_OPEN_PARAMS_S openParams;
+
+    struct wrap_adc_obj *adc_pri = (struct wrap_adc_obj *)dev->user_data;
+    rt_memset(&openParams, 0, sizeof(GD_ADC_OPEN_PARAMS_S));
+    openParams.channel = adc_pri->active_channel_no;
+
+    ret = (rt_err_t)GD_ADC_Open(&openParams, (GD_HANDLE*)&(adc_pri->handle));
+
+    return ret;
+}
+
+static rt_err_t gk_adc_close(rt_device_t dev)
+{
+    rt_err_t ret = RT_EOK;
+
+    struct wrap_adc_obj *adc_pri = (struct wrap_adc_obj *)dev->user_data;
+
+    ret = (rt_err_t)GD_ADC_Close((GD_HANDLE*)(adc_pri->handle));
+
+    return ret;
+}
+
+static rt_err_t gk_adc_ioctl(rt_device_t dev, int cmd, void *arg)
+{
+    rt_uint32_t control_reg;
+    struct wrap_adc_obj *adc_pri = (struct wrap_adc_obj *)dev->user_data;
+    rt_uint32_t ad_data;
+
+    ADC_INFO *adc_info = (ADC_INFO *)arg;
+    rt_err_t ret;
+
+    switch (cmd)
+    {
+        case ADC_CMD_READ_RAW_DATA:
+            ret = gk_adc_read_data(adc_pri, adc_info->channel, &ad_data);
+            if (ret != RT_EOK)
+            {
+                return ret;
+            }
+
+            adc_info->adc_data = ad_data;
+
+            break;
+
+        case ADC_CMD_DISABLE:
+            gk_adc_close(dev);
+
+            break;
+
+        default:
+            rt_kprintf("wrong para...\n");
+            return RT_EIO;
+    }
+
+    return RT_EOK;
+}
+
+int gk_adc_probe(void *priv_data)
+{
+    rt_device_t adc_dev;
+    // check if the hw is init already...
+    // caution this is a read only data...if the driver want to use.malloc and
+    // copy it..
+    struct wrap_adc_obj *adc_obj = (struct wrap_adc_obj *)priv_data;
+    if (adc_obj->init_flag == ADC_INIT_ALREADY) return RT_EFULL;
+
+    // malloc a rt device..
+    adc_dev = RT_KERNEL_MALLOC(sizeof(struct rt_device));
+    if (!adc_dev)
+    {
+        return RT_ENOMEM;
+    }
+    rt_memset(adc_dev, 0, sizeof(struct rt_device));
+    rt_kprintf("id:%d\n", adc_obj->id);
+
+    // bind rtdev to obj data...
+    // caution ...this is used to free mem when exit....
+    // free step:1:get adc obj...2:free adc_obj->rt_dev->user_data..3:free
+    // adc_obj->rt_dev 4:adc_obj->rt_dev = NULL
+    adc_obj->rt_dev = adc_dev;
+
+    // malloc a private data adc use only...copy data from platform...
+    struct wrap_adc_obj *adc_pri =
+        RT_KERNEL_MALLOC(sizeof(struct wrap_adc_obj));
+    if (!adc_pri)
+    {
+        RT_KERNEL_FREE(adc_dev);
+        return RT_ENOMEM;
+    }
+
+    // copy platform data to pri data..
+    rt_memcpy(adc_pri, adc_obj, sizeof(struct wrap_adc_obj));
+
+    rt_kprintf("id:%d\n", adc_pri->id);
+
+    // bind pri data to rt_adc_dev...
+    adc_dev->user_data = (void *)adc_pri;
+    adc_dev->open      = gk_adc_open;
+    adc_dev->close     = gk_adc_close;
+    adc_dev->control   = gk_adc_ioctl;
+    adc_dev->init      = gk_adc_init;
+    adc_dev->type      = RT_Device_Class_Miscellaneous;
+
+    rt_device_register(adc_dev, "adc", RT_DEVICE_FLAG_RDWR);
+
+    adc_obj->init_flag = ADC_INIT_ALREADY;
+
+    return RT_EOK;
+}
+
+int gk_adc_exit(void *priv_data)
+{
+    struct wrap_adc_obj *adc_obj = (struct wrap_adc_obj *)priv_data;
+
+    struct wrap_adc_obj *adc_pri = adc_obj->rt_dev->user_data;
+
+    RT_KERNEL_FREE(adc_obj->rt_dev->user_data);
+
+    adc_obj->rt_dev->user_data = RT_NULL;
+    RT_KERNEL_FREE(adc_obj->rt_dev);
+    adc_obj->rt_dev = RT_NULL;
+
+    GD_ADC_Exit();
+
+    return 0;
+}
+
+struct gk_platform_driver adc_driver_ops = {
+    .name = "adc", .probe = gk_adc_probe, .remove = gk_adc_exit,
+};
+
+void rt_hw_adc_init(void)
+{
+    gk_platform_driver_init(&adc_driver_ops);
+}
+
+#ifdef GK_TEST_ADC
+int gk_adc_test(void)
+{
+    rt_device_t adc_dev;
+    ADC_INFO info;
+    info.channel   = 0;
+    info.adc_data = 0;
+    adc_dev       = rt_device_find("adc");
+    if (!adc_dev)
+    {
+        rt_kprintf("cann't find the adc dev\n");
+        return -1;
+    }
+    adc_dev->init(adc_dev);
+    adc_dev->open(adc_dev, 0);
+    while (1)
+    {
+        adc_dev->control(adc_dev, ADC_CMD_READ_RAW_DATA, &info);
+        rt_kprintf("channel:%d, data:0x%x\n", info.channel, info.adc_data);
+    }
+
+    return 0;
+}
+#endif
+
+#ifdef RT_USING_FINSH
+#include <finsh.h>
+#ifdef GK_TEST_ADC
+FINSH_FUNCTION_EXPORT(gk_adc_test, gk_adc_test);
+#endif
+#endif
+
+#endif

+ 77 - 0
bsp/gkipc/drivers/drv_adc.h

@@ -0,0 +1,77 @@
+/*
+ * File      : drv_adc.h
+ * This file is part of GK710X BSP for RT-Thread distribution.
+ *
+ * Copyright (c) 2017 GOKE Microelectronics Co., Ltd.
+ * All rights reserved
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *  Visit http://www.goke.com to get contact with Goke.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+
+#ifndef ADC_H_
+#define ADC_H_
+
+#include <rtdef.h>
+#ifdef RT_USING_ADC
+
+/****************************************************************************
+ * #define section
+ *	add constant #define here if any
+ ***************************************************************************/
+#define MAX_CHANNEL_NO (2)
+#define ADC_INIT_ALREADY (0x33)
+
+#define ADC_CMD_READ_RAW_DATA (0x22)
+#define ADC_CMD_DISABLE (0x44)
+
+/****************************************************************************
+ * ADT section
+ *	add Abstract Data Type definition here
+ ***************************************************************************/
+
+struct wrap_adc_obj
+{
+    rt_uint32_t id;
+    rt_uint32_t init_flag;
+    rt_uint32_t active_channel_no;
+    rt_uint32_t handle;
+    rt_uint16_t channel_data[MAX_CHANNEL_NO];
+
+    // bind to the rtdev..
+    rt_device_t rt_dev;
+};
+
+typedef struct
+{
+    rt_uint32_t channel;
+    rt_uint32_t adc_data;
+} ADC_INFO;
+
+/****************************************************************************
+ *  extern variable declaration section
+ ***************************************************************************/
+
+/****************************************************************************
+ *  section
+ *	add function prototype here if any
+ ***************************************************************************/
+void rt_hw_adc_init(void);
+#endif
+#endif /* ADC_H_ */

+ 226 - 0
bsp/gkipc/drivers/drv_dma.c

@@ -0,0 +1,226 @@
+/*
+ * File      : drv_dma.c
+ * This file is part of gkipc BSP for RT-Thread distribution.
+ *
+ * Copyright (c) 2017 ChengDu goke Microelectronics Co., Ltd.
+ * All rights reserved
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *  Visit http://www.goke.com to get contact with goke.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+
+/*****************************************************************************
+ *  Include Section
+ *  add all #include here
+ *****************************************************************************/
+#include "drivers/drv_dma.h"
+
+#include "gd_dma.h"
+
+/*****************************************************************************
+ * Define section
+ * add all #define here
+ *****************************************************************************/
+
+//#define GK_DMA_DEBUG
+#ifndef GK_DMA_DEBUG
+#define DMA_PRINT_DBG(fmt, args...)
+#define DMA_PRINT_ERR(fmt, args...) rt_kprintf(fmt, ##args);
+#else
+#define DMA_PRINT_DBG(fmt, args...) rt_kprintf(fmt, ##args);
+#define DMA_PRINT_ERR(fmt, args...) rt_kprintf(fmt, ##args);
+#endif
+
+/****************************************************************************
+ * ADT section
+ *  add definition of user defined Data Type that only be used in this file here
+ ***************************************************************************/
+
+static struct rt_dma_device _dma_device;
+
+
+/******************************************************************************
+ * Function prototype section
+ * add prototypes for all functions called by this file,execepting those
+ * declared in header file
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Global variables section - Exported
+ * add declaration of global variables that will be exported here
+ * e.g.
+ *  int8_t foo;
+ ****************************************************************************/
+
+/*****************************************************************************
+
+ *  static fun;
+ *****************************************************************************/
+static rt_err_t rt_dma_init(struct rt_device *dev);
+static rt_err_t rt_dma_open(struct rt_device *dev, rt_uint16_t oflag);
+static rt_err_t rt_dma_close(struct rt_device *dev);
+static rt_err_t rt_dma_control(struct rt_device *dev, int cmd,void *args);
+/*****************************************************************************
+ * Global variables section - Local
+ * define global variables(will be refered only in this file) here,
+ * static keyword should be used to limit scope of local variable to this file
+ * e.g.
+ *  static uint8_t ufoo;
+ *****************************************************************************/
+
+/* function body */
+/*****************************************************************************
+ * Description:
+ *      add funtion description here
+ * Parameters:
+ *      description for each argument, new argument starts at new line
+ * Return:
+ *      what does this function returned?
+ *****************************************************************************/
+static rt_err_t rt_dma_init(struct rt_device *dev)
+{
+    return (RT_EOK);
+}
+
+static rt_err_t rt_dma_open(struct rt_device *dev, rt_uint16_t oflag)
+{
+    rt_uint32_t retVal = 0;
+    struct rt_dma_device *dma;
+
+    RT_ASSERT(dev != RT_NULL);
+    dma = (struct rt_dma_device *)dev->user_data;
+
+    retVal = GD_DMA_Open((GD_DMA_OPEN_PARAM_S *)&dma->openParam,(GD_HANDLE *)&dma->handle);
+    if(retVal != RT_EOK)
+    {
+        DMA_PRINT_ERR("GD_DMA_Open failed!\n");
+        return (-RT_ERROR);
+    }
+
+    return (RT_EOK);
+}
+
+static rt_err_t rt_dma_close(struct rt_device *dev)
+{
+    rt_uint32_t retVal = 0;
+    struct rt_dma_device *dma;
+
+    RT_ASSERT(dev != RT_NULL);
+    dma = (struct rt_dma_device *)dev->user_data;
+
+    GD_DMA_Stop((GD_HANDLE)dma->handle);
+
+    retVal = GD_DMA_Close((GD_HANDLE)dma->handle);
+    if (retVal != RT_EOK)
+    {
+        DMA_PRINT_ERR("GD_DMA_Close failed!\n");
+        return (-RT_ERROR);
+    }
+
+    return (RT_EOK);
+}
+
+static rt_err_t rt_dma_control(struct rt_device *dev, int cmd,void *args)
+{
+    rt_uint32_t retVal = 0;
+    rt_uint32_t des    = 0;
+    RT_DMA_DESCRIPTOR_S *descriptor;
+
+    struct rt_dma_device *dma;
+    RT_ASSERT(dev != RT_NULL);
+    dma = (struct rt_dma_device *)dev->user_data;
+
+    switch(cmd)
+    {
+        case DMA_CMD_ADD_DESCRIPTOR:
+            descriptor = (RT_DMA_DESCRIPTOR_S *)args;
+            retVal = GD_DMA_AddDescriptor((GD_HANDLE)dma->handle,(GD_DMA_DESCRIPTOR_S *)descriptor);
+            if (retVal != RT_EOK)
+            {
+                DMA_PRINT_ERR("GD_DMA_AddDescriptor failed!\n");
+                return (-RT_ERROR);
+            }
+
+            break;
+
+        case DMA_CMD_START:
+            des = *(rt_uint32_t*)args;
+            retVal = GD_DMA_Start((GD_HANDLE)dma->handle,des);
+            if (retVal != RT_EOK)
+            {
+                DMA_PRINT_ERR("GD_DMA_Start failed!\n");
+                return (-RT_ERROR);
+            }
+
+            break;
+
+        case DMA_CMD_STOP:
+            GD_DMA_Stop((GD_HANDLE)dma->handle);
+            break;
+
+        default:break;
+
+
+    }
+
+    return (RT_EOK);
+}
+
+/**
+ * This function register a dma device
+ */
+static rt_err_t rt_hw_dma_register(const char *name,rt_uint32_t flag)
+{
+    rt_uint32_t ret;
+    struct rt_device *device;
+
+    device = &(_dma_device.parent);
+
+    device->type        = RT_Device_Class_Miscellaneous;
+    device->rx_indicate = RT_NULL;
+    device->tx_complete = RT_NULL;
+
+    device->init      = rt_dma_init;
+    device->open      = rt_dma_open;
+    device->close     = rt_dma_close;
+    device->read      = RT_NULL;
+    device->write     = RT_NULL;
+    device->control   = rt_dma_control;
+    device->user_data = (void *)&_dma_device;
+
+    /* register a character device */
+    ret = rt_device_register(device, name, flag);
+
+    return ret;
+}
+
+void rt_gk_dma_init(void)
+{
+    rt_uint32_t retVal = 0;
+
+    retVal = GD_DMA_Init();
+    if (retVal != RT_EOK)
+    {
+        DMA_PRINT_ERR("GD_DMA_Init failed!\n");
+		return;
+    }
+
+    rt_hw_dma_register("gk_dma",RT_DEVICE_FLAG_RDWR);
+}
+

+ 121 - 0
bsp/gkipc/drivers/drv_dma.h

@@ -0,0 +1,121 @@
+/*
+ * File      : drv_dma.h
+ * This file is part of FH8620 BSP for RT-Thread distribution.
+ *
+ * Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
+ * All rights reserved
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *  Visit http://www.fullhan.com to get contact with Fullhan.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+
+#ifndef DMA_H_
+#define DMA_H_
+#include <rtthread.h>
+/****************************************************************************
+* #include section
+*	add #include here if any
+***************************************************************************/
+
+/****************************************************************************
+* #define section
+*	add constant #define here if any
+***************************************************************************/
+#define RT_DEVICE_CTRL_DMA_OPEN (1)
+#define RT_DEVICE_CTRL_DMA_CLOSE (2)
+#define RT_DEVICE_CTRL_DMA_REQUEST_CHANNEL (3)
+#define RT_DEVICE_CTRL_DMA_RELEASE_CHANNEL (4)
+#define RT_DEVICE_CTRL_DMA_SINGLE_TRANSFER (5)
+
+// cyclic add func below....
+
+#define RT_DEVICE_CTRL_DMA_CYCLIC_PREPARE (6)
+#define RT_DEVICE_CTRL_DMA_CYCLIC_START (7)
+#define RT_DEVICE_CTRL_DMA_CYCLIC_STOP (8)
+#define RT_DEVICE_CTRL_DMA_CYCLIC_FREE (9)
+#define RT_DEVICE_CTRL_DMA_PAUSE (10)
+#define RT_DEVICE_CTRL_DMA_RESUME (11)
+
+//#define RT_DEVICE_CTRL_  	 (3) /* get the left time before reboot(in
+//seconds) */
+//#define RT_DEVICE_CTRL_      (4) /* refresh watchdog */
+//#define RT_DEVICE_CTRL_      (5) /* start watchdog */
+//#define RT_DEVICE_CTRL_      (6) /* stop watchdog */
+
+/****************************************************************************
+* ADT section
+*	add Abstract Data Type definition here
+***************************************************************************/
+
+#define ADC_CMD_READ_RAW_DATA (0x22)
+#define ADC_CMD_DISABLE (0x44)
+
+
+/*dma cmd */
+typedef enum
+{
+    DMA_CMD_ADD_DESCRIPTOR = 0,
+    DMA_CMD_START,
+    DMA_CMD_STOP,
+}RT_DMA_DMD;
+
+
+
+typedef void (*RT_DMA_NOTIFIER_F)(void);
+
+typedef struct rt_dma_descriptor_s
+{
+    rt_uint32_t srcAddr;        /*  Source address */
+    rt_uint32_t dstAddr;        /* Destination address */
+    struct dma_descriptor_s *next; /* Pointing to next descriptor */
+    rt_uint32_t reportAddr;     /* The physical address to store DMA hardware reporting status */
+    rt_uint32_t dataLength;     /* Transfer byte count , max value = 2^22 */
+    rt_uint32_t descAttr;       /* Descriptor 's attribute */
+}RT_DMA_DESCRIPTOR_S;
+
+typedef struct
+{
+    rt_uint32_t      channel;
+    rt_uint32_t      mode;
+	RT_DMA_NOTIFIER_F intNotifier;
+}RT_DMA_OPEN_PARAM_S;
+
+typedef struct rt_dma_device
+{
+    // the parent must be the fitst para..
+    rt_uint32_t         handle;
+    struct rt_device    parent;
+    RT_DMA_OPEN_PARAM_S openParam;
+}rt_dma_device_s;
+
+
+/****************************************************************************
+*  extern variable declaration section
+***************************************************************************/
+
+/****************************************************************************
+*  section
+*	add function prototype here if any
+***************************************************************************/
+
+void rt_gk_dma_init(void);
+
+/********************************End Of File********************************/
+
+#endif

+ 349 - 0
bsp/gkipc/drivers/drv_flash.c

@@ -0,0 +1,349 @@
+#include <stdio.h>
+#include <rtdevice.h>
+
+#include "gtypes.h"
+#include "gd_sflash.h"
+
+/*---------------------------------------------------------------------------*/
+/* local defines                                                             */
+/*---------------------------------------------------------------------------*/
+
+
+/*---------------------------------------------------------------------------*/
+/* local data types                                                          */
+/*---------------------------------------------------------------------------*/
+
+struct gk_flash
+{
+
+    struct rt_device device;
+    struct rt_mutex lock;
+    struct rt_device_blk_geometry flashinfo;
+
+    GD_HANDLE    handle;
+
+};
+
+static struct gk_flash flashdev;
+
+/*---------------------------------------------------------------------------*/
+/* local data                                                                */
+/*---------------------------------------------------------------------------*/
+
+
+static rt_uint32_t auctempArr[512] = {0};
+
+/*---------------------------------------------------------------------------*/
+/* local  functions                                                          */
+/*---------------------------------------------------------------------------*/
+static rt_err_t  gk_flash_init  (rt_device_t dev)
+{
+    return RT_EOK;
+}
+
+static rt_err_t  gk_flash_open  (rt_device_t dev, rt_uint16_t oflag)
+{
+    return RT_EOK;
+}
+
+static rt_err_t  gk_flash_close (rt_device_t dev)
+{
+    return RT_EOK;
+}
+
+static rt_size_t gk_flash_read  (rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
+{
+    RT_ASSERT(dev != RT_NULL);
+    RT_ASSERT(buffer != RT_NULL);
+    RT_ASSERT(size > 0);
+    RT_ASSERT(dev->user_data != NULL);
+
+    int  ret     = 0;
+    rt_uint32_t temp        = 0;
+    rt_uint32_t readSize    = 0;
+    char *ptr            = NULL;
+    U8  readLastBuffer[4] = {0};
+    rt_uint32_t numReadSize        = 0;
+    rt_uint32_t offsetAddr         = 0;
+
+    struct gk_flash *flashdevPtr = (struct gk_flash *)dev->user_data;
+
+    rt_mutex_take(&flashdevPtr->lock, RT_WAITING_FOREVER);
+
+    rt_memset(auctempArr, 0, 512);
+
+    if(pos%4 != 0)
+    {
+        temp = pos%4;
+        if((size+8) > 512)
+        {
+            ret |= GD_SFLASH_Read(flashdevPtr->handle, pos-temp, auctempArr, 4);
+            readSize = 4-temp;
+            ptr = (char*)auctempArr;
+            rt_memcpy(buffer,ptr+temp,readSize);
+            ret |= GD_SFLASH_Read(flashdevPtr->handle, pos+readSize, (rt_uint32_t *)buffer+readSize, (size-readSize)/4);
+        }
+        else
+        {
+            readSize = ((size+8)/4);
+            ret |= GD_SFLASH_Read(flashdevPtr->handle, pos-temp, auctempArr, readSize);
+            ptr = (char *)auctempArr;
+            rt_memcpy(buffer, ptr+temp, size);
+        }
+    }
+    else
+    {
+        if (size % 4)
+        {
+            if (size/4 != 0)
+            {
+                ret |= GD_SFLASH_Read(flashdevPtr->handle, pos, (rt_uint32_t*)buffer, size/4);
+                if ( ret != GD_OK )
+                {
+                   rt_kprintf( "\n[%d][gk_flash_read] GD_SFLASH_Read_Byte err!!\n",__LINE__);
+                }
+            }
+
+            numReadSize = size % 4;
+            offsetAddr  = size - numReadSize;
+            ret |= GD_SFLASH_Read(flashdevPtr->handle, pos+offsetAddr, (rt_uint32_t *)readLastBuffer, 1); // read 4 bytes
+            if ( ret != GD_OK )
+            {
+               rt_kprintf( "\n[%d][gk_flash_read] GD_SFLASH_Read_Byte err!!\n",__LINE__);
+            }
+
+            rt_memcpy((U8 *)buffer+offsetAddr, readLastBuffer, numReadSize);
+
+        }
+        else
+        {
+            ret |= GD_SFLASH_Read(flashdevPtr->handle, pos, (rt_uint32_t *)buffer, size/4);
+            if ( ret != GD_OK )
+            {
+               rt_kprintf( "\n[%d][gk_flash_read] GD_SFLASH_Read_Byte err!!\n",__LINE__);
+            }
+        }
+
+    }
+
+    rt_mutex_release(&flashdevPtr->lock);
+
+    return (ret == GD_OK)?RT_EOK:RT_ERROR;
+
+}
+
+static rt_size_t gk_flash_write (rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
+{
+    RT_ASSERT(dev != RT_NULL);
+    RT_ASSERT(buffer != RT_NULL);
+    RT_ASSERT(size > 0);
+    RT_ASSERT(dev->user_data != NULL);
+
+    int ret             = GD_OK;
+    U8  writeLastBuffer[4] = {0};
+    rt_uint32_t numWriteSize       = 0;
+    rt_uint32_t offsetAddr         = 0;
+
+    struct gk_flash *flashdevPtr = (struct gk_flash *)dev->user_data;
+
+    if(pos %4 != 0)
+    {
+        rt_kprintf("\n[gk_flash_write] the write flash address isn't assigned in 4 bytes.\n");
+        return RT_ERROR;
+    }
+
+    rt_mutex_take(&flashdevPtr->lock, RT_WAITING_FOREVER);
+
+    if(size%4)
+    {
+        if (size/4 != 0)
+        {
+            ret = GD_SFLASH_Write(flashdevPtr->handle, pos, (rt_uint32_t*)buffer, size/4);
+            if ( ret != GD_OK )
+            {
+               rt_kprintf("\n[gk_flash_write:%d] GD_SFLASH_Write_Byte err!!,ret = %ld\n",__LINE__,ret);
+            }
+        }
+        numWriteSize = size%4;
+        offsetAddr   = size - numWriteSize;
+
+        rt_memcpy(writeLastBuffer, (U8 *)buffer+offsetAddr, numWriteSize);
+
+        ret |= GD_SFLASH_Program(flashdevPtr->handle, (pos + offsetAddr), (rt_uint32_t*)writeLastBuffer, 1);// write 4 bytes
+        if ( ret != GD_OK )
+        {
+           rt_kprintf("\n[gk_flash_write:%d] GD_SFLASH_Write_Byte err!!,ret = %ld\n",__LINE__,ret);
+        }
+    }
+    else
+    {
+        ret = GD_SFLASH_Write(flashdevPtr->handle, pos, (rt_uint32_t*)buffer, size/4);
+        if ( ret != GD_OK )
+        {
+           rt_kprintf("\n[gk_flash_write:%d] GD_SFLASH_Write_Byte err!!,ret = %ld\n",__LINE__,ret);
+        }
+    }
+
+    rt_mutex_release(&flashdevPtr->lock);
+
+    return (ret == GD_OK)?RT_EOK:RT_ERROR;
+
+}
+
+static rt_err_t  gk_flash_control(rt_device_t dev, int cmd, void *args)
+{
+    RT_ASSERT(dev != RT_NULL);
+    RT_ASSERT(dev->user_data != NULL);
+    RT_ASSERT(args != RT_NULL);
+    rt_uint32_t i = 0,ret;
+
+    struct gk_flash *flashdevPtr = (struct gk_flash *)dev->user_data;
+
+    rt_mutex_take(&flashdevPtr->lock, RT_WAITING_FOREVER);
+
+    switch(cmd)
+    {
+        case RT_DEVICE_CTRL_BLK_GETGEOME:
+        {
+            struct rt_device_blk_geometry *geometry;
+
+            geometry = (struct rt_device_blk_geometry *)args;
+            if (geometry == RT_NULL)
+            {
+                rt_mutex_release(&flashdevPtr->lock);
+                return -RT_ERROR;
+            }
+            geometry->bytes_per_sector = flashdevPtr->flashinfo.bytes_per_sector;
+            geometry->sector_count = flashdevPtr->flashinfo.sector_count;
+            geometry->block_size = flashdevPtr->flashinfo.bytes_per_sector;//64k
+
+            break;
+        }
+        case RT_DEVICE_CTRL_BLK_ERASE: //params are sector index to erase start and end.
+        {
+            rt_uint32_t *addrs = (rt_uint32_t *) args, start_sector = addrs[0], end_sector = addrs[1];
+
+            rt_size_t phy_size;
+
+            if (addrs == RT_NULL || start_sector > end_sector || start_sector > flashdevPtr->flashinfo.sector_count)
+            {
+                rt_mutex_release(&flashdevPtr->lock);
+                return -RT_ERROR;
+            }
+
+            for(i = start_sector; i <= end_sector; i++)
+            {
+                ret = GD_SFLASH_EraseSector(flashdevPtr->handle, (rt_uint16_t)i);
+                if ( ret != GD_OK )
+                {
+                    rt_kprintf("\n[gk_flash_control] GD_SFLASH_EraseSector err!!\n");
+                }
+
+                rt_kprintf("\n[gk_flash_control] erase sector number = %ld\n", i);
+            }
+
+            break;
+        }
+        default:
+            break;
+    }
+
+    rt_mutex_release(&flashdevPtr->lock);
+
+    return RT_EOK;
+}
+
+
+void rt_flash_init(void)
+{
+
+    GD_SFLASH_CHANNEL_E channel = GD_SFLASH_CHANNEL_0;
+    rt_uint32_t deviceBytes = 0;
+    rt_uint16_t sectorCount = 0;
+    rt_uint32_t sectorSize = 0;
+    rt_uint16_t tmp_sectorIndex = 16;
+    rt_int32_t ret;
+
+    GD_SFLASH_Init();
+
+    rt_memset((void *)&flashdev,0,sizeof(struct gk_flash));
+
+    for(;channel<GD_SFLASH_SPI_CHANNEL_0_0; channel++)
+    {
+      ret = GD_SFLASH_Open((GD_HANDLE *)&flashdev.handle, GD_SFLASH_FREQ_DIV4, channel);
+      if(ret == GD_OK)
+          break;
+    }
+
+    if ( channel == GD_SFLASH_SPI_CHANNEL_0_0 )
+    {
+      rt_kprintf("\nrt_flash_init failed!!\n");
+      return;
+    }
+
+
+    ret = GD_SFLASH_GetSize(flashdev.handle, &deviceBytes);
+
+    deviceBytes *= sizeof(rt_uint32_t);
+
+    if (ret != GD_OK)
+    {
+        rt_kprintf("\n[rt_flash_init] GD_SFLASH_GetSize err!!\n");
+    }
+    else
+    {
+        //rt_kprintf("\n[rt_flash_init] deviceBytes = 0x%lx\n", deviceBytes);
+    }
+
+
+    ret = GD_SFLASH_GetNumberOfSectors(flashdev.handle, &sectorCount);
+    if (ret != GD_OK)
+    {
+        rt_kprintf("\n[rt_flash_init] GD_SFLASH_GetNumberOfSectors err!!\n");
+    }
+    else
+    {
+        //rt_kprintf("\n[rt_flash_init] sectorCount = %ld\n", sectorCount);
+    }
+
+
+    ret = GD_SFLASH_GetSectorSize(flashdev.handle, tmp_sectorIndex, &sectorSize);
+    sectorSize *= sizeof(rt_uint32_t);
+    if (ret != GD_OK)
+    {
+        rt_kprintf("\n[gk_flash_control] GD_SFLASH_GetSectorSize err!!\n");
+    }
+    else
+    {
+        //rt_kprintf("\n[gk_flash_control] sectorBytes = 0x%lx\n", sectorSize);
+    }
+
+    flashdev.flashinfo.bytes_per_sector = sectorSize;
+    flashdev.flashinfo.sector_count = sectorCount;
+    flashdev.flashinfo.block_size = sectorSize;//64k
+
+    flashdev.device.type            = RT_Device_Class_Block;
+    flashdev.device.rx_indicate     = RT_NULL;
+    flashdev.device.tx_complete     = RT_NULL;
+
+    flashdev.device.init            = gk_flash_init;
+    flashdev.device.open            = gk_flash_open;
+    flashdev.device.close           = gk_flash_close;
+    flashdev.device.read            = gk_flash_read;
+    flashdev.device.write           = gk_flash_write;
+    flashdev.device.control         = gk_flash_control;
+    flashdev.device.user_data       = (void *)&flashdev;
+
+
+    ret = rt_mutex_init(&flashdev.lock,"sflash", RT_IPC_FLAG_FIFO);
+    if (ret != RT_EOK)
+    {
+        rt_kprintf("\nrt_flash_init creat mutex failed!!\n");
+        return;
+    }
+
+    rt_device_register(&flashdev.device, "sflash",
+                               RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STANDALONE);
+
+}
+

+ 6 - 0
bsp/gkipc/drivers/drv_flash.h

@@ -0,0 +1,6 @@
+#ifndef __FLASH__
+#define __FLASH__
+
+void rt_flash_init(void);
+
+#endif

+ 519 - 0
bsp/gkipc/drivers/drv_gmac.c

@@ -0,0 +1,519 @@
+/*
+ * File      : drv_gmac.c
+ * This file is part of GK710X BSP for RT-Thread distribution.
+ *
+ * Copyright (c) 2017 GOKE Microelectronics Co., Ltd.
+ * All rights reserved
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *  Visit http://www.goke.com to get contact with Goke.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+
+/*****************************************************************************
+ *  Include Section
+ *  add all #include here
+ *****************************************************************************/
+#include <rtthread.h>
+#include <rthw.h>
+#include <rtdevice.h>
+#include <netif/ethernetif.h>
+#include "lwipopts.h"
+#include "drv_gmac.h"
+#include "gtypes.h"
+#include "gd_ethernet.h"
+
+#ifdef RT_USING_GMAC
+/*****************************************************************************
+ * Define section
+ * add all #define here
+ *****************************************************************************/
+#define GMAC_TX_BUFFER_SIZE 2048
+#define GMAC_RX_BUFFER_SIZE 2048
+
+#define MAC_ADDR0   0x11
+#define MAC_ADDR1   0x10
+#define MAC_ADDR2   0xAA
+#define MAC_ADDR3   0xBB
+#define MAC_ADDR4   0xCC
+#define MAC_ADDR5   0x01
+
+
+/****************************************************************************
+ * ADT section
+ *  add definition of user defined Data Type that only be used in this file here
+ ***************************************************************************/
+
+#define MAX_ADDR_LEN 6
+typedef struct gk_gmac_object
+{
+    /* inherit from ethernet device */
+    struct eth_device parent;
+
+    GD_ETH_InitParamsT init_param;
+    GD_ETH_OpenParamsT params;
+    GD_HANDLE eth_handle;
+
+    int link;
+    struct rt_timer timer;
+    U8 local_mac_address[MAX_ADDR_LEN];
+
+    U8* rx_buffer;
+    U16 rx_len;
+    struct rt_semaphore rx_lock;
+#if 0
+    UINT8 local_mac_address[MAX_ADDR_LEN];
+    unsigned short phy_addr;
+    int full_duplex;  // read only
+    int speed_100m;   // read only
+
+    UINT8* rx_ring_original;
+    UINT8* tx_ring_original;
+    UINT8* rx_buffer_original;
+    UINT8* tx_buffer_original;
+
+    UINT8* rx_buffer;
+    UINT8* tx_buffer;
+
+    Gmac_Rx_DMA_Descriptors* rx_ring;
+    Gmac_Tx_DMA_Descriptors* tx_ring;
+
+    unsigned long rx_buffer_dma;
+    unsigned long tx_buffer_dma;
+    unsigned long rx_ring_dma;
+    unsigned long tx_ring_dma;
+
+    unsigned int tx_stop;
+
+    struct rt_semaphore tx_lock;
+    struct rt_semaphore rx_lock;
+    struct rt_semaphore tx_ack;
+    struct rt_semaphore rx_ack;
+    struct rt_semaphore mdio_bus_lock;
+    int speed;
+    int duplex;
+    int link;
+    int phy_interface;
+    struct rt_timer timer;
+    struct rt_timer rx_poll_timer;
+
+    gk_gmac_stats_t stats;
+
+    unsigned int rx_cur_desc;
+    unsigned int tx_cur_desc;
+    unsigned int get_frame_no;
+    struct rt_workqueue* rx_queue;
+    struct rt_work* rx_work;
+#endif
+
+} gk_gmac_object_t;
+
+static int recv_state = 0;
+static void recv_isr_callback(volatile U8* buffer, U16 len);
+
+/******************************************************************************
+ * Function prototype section
+ * add prototypes for all functions called by this file,execepting those
+ * declared in header file
+ *****************************************************************************/
+int gk_gmac_init(rt_device_t dev)
+{
+    GERR ret = GD_OK;
+    int open_retry = 3;
+    GD_ETH_MacT macaddr;
+    gk_gmac_object_t* gmac;
+    gmac = (gk_gmac_object_t*)dev->user_data;
+
+    // eth init .....
+    gmac->init_param.bHWReset = GFALSE;
+    gmac->init_param.phyreset = GD_GPIO_0;
+    gmac->init_param.phyType = 0;
+    ret = GD_ETH_Init(&(gmac->init_param));
+    if (ret != GD_OK)
+    {
+        rt_kprintf("GD_ETH_Init error", ret);
+        return -1;
+    }
+
+    gmac->eth_handle = 0;
+    // Open eth device.
+    gmac->params.addr = GD_ETH_PHY_EXTERNAL_AUTO;
+    gmac->params.workmode.speed       = GD_ETH_SPEED_100M;
+    gmac->params.workmode.duplex      = GD_ETH_FULL_DUPLEX;
+    gmac->params.workmode.loopback    = GD_ETH_LOOP_OFF;
+    gmac->params.workmode.mode        = GD_ETH_PHY_IF_MODE_RMII;
+
+    ret = GD_ETH_Open(&(gmac->params), &(gmac->eth_handle));
+    while ((ret != GD_OK) && (open_retry--)) {
+        rt_kprintf("GD_ETH_Open: device open failed(%ld)"
+                                            ", retry %ld\n", ret, open_retry);
+        rt_thread_delay(10);
+        ret = GD_ETH_Open(&(gmac->params), &(gmac->eth_handle));
+    }
+    if  (ret == GD_OK) {
+        rt_kprintf("GD_ETH_Open: device open successed 0x%x.\n", gmac->eth_handle);
+    }
+
+    ret = GD_ETH_GetMacAddress(gmac->eth_handle, &macaddr);
+    if (ret != GD_OK) {
+        rt_kprintf("GD_ETH_GetMacAddress: device getMacAddress failed, use default.\n");
+
+        macaddr[0] = MAC_ADDR0;
+        macaddr[1] = MAC_ADDR1;
+        macaddr[2] = MAC_ADDR2;
+        macaddr[3] = MAC_ADDR3;
+        macaddr[4] = MAC_ADDR4;
+        macaddr[5] = MAC_ADDR5;
+    }
+
+    rt_memcpy(gmac->local_mac_address, macaddr, MAX_ADDR_LEN);
+
+    // set data coming callback.
+    GD_ETH_SetNetReceiveFuc(recv_isr_callback);
+
+    return 0;
+}
+
+void gk_gmac_update_link(void* param)
+{
+    gk_gmac_object_t* gmac;
+    gmac = (gk_gmac_object_t*)param;
+
+    rt_device_t dev = &gmac->parent.parent;
+    GD_ETH_StatParamsT ethstat;
+
+    GD_ETH_GetStat(gmac->eth_handle, &ethstat);
+    if (gmac->link != ethstat.linkup)
+    {
+        rt_kprintf("ipc ethif link is %s\n", (ethstat.linkup == GD_ETH_LINKUP ?"UP":"DOWN"));
+        rt_kprintf("  speed is %d\n", (int)ethstat.speed);
+        rt_kprintf("  duplex is %d\n", (int)ethstat.duplex);
+
+        if (ethstat.linkup == GD_ETH_LINKUP)
+        {
+            rt_kprintf("%s: link up\n", dev->parent.name);
+            eth_device_linkchange(&gmac->parent, RT_TRUE);
+        }
+        else
+        {
+            rt_kprintf("%s: link down\n", dev->parent.name);
+            eth_device_linkchange(&gmac->parent, RT_FALSE);
+        }
+
+        gmac->link = ethstat.linkup;
+    }
+}
+
+
+/*********************
+ *
+ * up level use interface
+ *
+ *********************/
+static rt_err_t rt_gk_gmac_init(rt_device_t dev)
+{
+    int ret;
+    gk_gmac_object_t* gmac;
+    gmac = (gk_gmac_object_t*)dev->user_data;
+
+    rt_timer_init(&gmac->timer, "link_timer", gk_gmac_update_link, (void*)gmac,
+                  RT_TICK_PER_SECOND, RT_TIMER_FLAG_PERIODIC);
+
+    rt_timer_start(&gmac->timer);
+
+    return RT_EOK;
+}
+
+static rt_err_t rt_gk_gmac_open(rt_device_t dev, rt_uint16_t oflag)
+{
+    return RT_EOK;
+}
+
+static rt_err_t rt_gk_gmac_close(rt_device_t dev)
+{
+    gk_gmac_object_t* gmac;
+    gmac = (gk_gmac_object_t*)dev->user_data;
+
+    GD_ETH_Close(&(gmac->eth_handle));
+
+    return RT_EOK;
+}
+static rt_size_t rt_gk_gmac_read(rt_device_t dev, rt_off_t pos, void* buffer,
+                                 rt_size_t size)
+{
+    rt_set_errno(-RT_ENOSYS);
+    return 0;
+}
+
+static rt_size_t rt_gk_gmac_write(rt_device_t dev, rt_off_t pos,
+                                  const void* buffer, rt_size_t size)
+{
+    rt_set_errno(-RT_ENOSYS);
+    return 0;
+}
+
+static rt_err_t rt_gk_gmac_control(rt_device_t dev, int cmd, void* args)
+{
+    gk_gmac_object_t* gmac;
+    gmac = (gk_gmac_object_t*)dev->user_data;
+
+    switch (cmd)
+    {
+    case NIOCTL_GADDR:
+        /* get mac address */
+        if (args)
+            rt_memcpy(args, gmac->local_mac_address, MAX_ADDR_LEN);
+        else
+            return -RT_ERROR;
+
+        break;
+
+    default:
+        break;
+    }
+
+    return RT_EOK;
+}
+
+/* ethernet device interface */
+/* transmit packet. */
+static rt_uint8_t g_output_buf[PBUF_POOL_BUFSIZE+20];
+static rt_err_t rt_gk_gmac_tx(rt_device_t dev, struct pbuf* p)
+{
+    rt_err_t ret = RT_EOK;
+    struct pbuf *q = NULL;
+    gk_gmac_object_t* gmac;
+    gmac = (gk_gmac_object_t*)dev->user_data;
+
+    if (p == NULL)
+    {
+        rt_kprintf("rt_gk_gmac_tx: out_pbuf is NULL\n");
+        ret = ERR_MEM;
+        return ret;
+    }
+    if (gmac->eth_handle == 0)
+    {
+        rt_kprintf("rt_gk_gmac_tx: eth_handle is 0\n");
+        ret = ERR_MEM;
+        return ret;
+    }
+
+    rt_uint8_t *output_bufptr = p->payload;
+
+    if (p->len != p->tot_len)
+    {
+        rt_uint8_t *bufptr = g_output_buf;
+        for (q = p; q != NULL; q = q->next)
+        {
+            rt_memcpy(bufptr, q->payload, q->len);
+            bufptr += q->len;
+        }
+        output_bufptr = g_output_buf;
+    }/* (else)  write to ethernet, reduce memcpy */
+
+
+    ret = GD_ETH_Write(gmac->eth_handle, (char *) output_bufptr, p->tot_len, GD_ETH_FRAME_END);
+    if (ret != GD_OK)
+    {
+        rt_kprintf("rt_gk_gmac_tx: eth Write error, len = %d, ret = %lu\n", p->tot_len, ret);
+        ret = RT_EIO;
+    }
+    else
+    {
+        ret = RT_EOK;
+    }
+
+    return ret;
+}
+
+static struct pbuf * _convert_data_to_pbuf(U8 *buffer, U32 len)
+{
+    struct pbuf *p, *q;
+    U8 *bufptr;
+    U32 buflen;
+
+    if (len <= 0) {
+        rt_kprintf("_convert_data_to_pbuf: len(%d) <= 0\n", len);
+        return NULL;
+    }
+    buflen = len;
+    p = pbuf_alloc(PBUF_RAW, buflen, PBUF_POOL);
+    if (p != NULL) {
+
+        bufptr = (U8 *) buffer;
+        for (q = p; q != NULL; q = q->next) {
+            SMEMCPY(q->payload, bufptr, q->len);
+            bufptr += q->len;
+        }
+
+    } else {
+        rt_kprintf("_convert_data_to_pbuf: can't alloc pbuf(len=%lu)\n", buflen);
+        return NULL;
+    }
+
+    return p;
+}
+
+/* reception packet. */
+static struct pbuf* rt_gk_gmac_rx(rt_device_t dev)
+{
+    gk_gmac_object_t* gmac;
+    gmac = (gk_gmac_object_t*)dev->user_data;
+
+    if (!recv_state)
+    {
+        return RT_NULL;
+    }
+
+    struct pbuf* temp_pbuf = RT_NULL;
+
+    if (gmac->rx_len <= 0)
+    {
+        rt_kprintf("rt_gk_gmac_rx: len(%d) <= 0\n", gmac->rx_len);
+        return RT_NULL;
+    }
+
+    rt_sem_take(&gmac->rx_lock, RT_WAITING_FOREVER);
+
+    //rt_kprintf("rt_gk_gmac_rx buffer = 0x%x, len = %d\n", gmac->rx_buffer, gmac->rx_len);
+
+    //temp_pbuf = pbuf_alloc(PBUF_LINK, gmac->rx_len, PBUF_RAM);
+    temp_pbuf = _convert_data_to_pbuf(gmac->rx_buffer, gmac->rx_len);
+    if (!temp_pbuf)
+    {
+        rt_kprintf("alloc pbuf failed\n");
+        rt_sem_release(&gmac->rx_lock);
+        return RT_NULL;
+    }
+
+    //rt_memcpy(temp_pbuf->payload, gmac->rx_buffer, gmac->rx_len);
+
+    recv_state = 0;
+
+    rt_sem_release(&gmac->rx_lock);
+
+    return temp_pbuf;
+}
+
+static void recv_isr_callback(volatile U8* buffer, U16 len)
+{
+    gk_gmac_object_t* gmac;
+    int ret_eth;
+
+    recv_state = 1;
+
+    rt_device_t dev = rt_device_find("e0");
+    if (dev == RT_NULL)
+    {
+        rt_kprintf("rt_device_find e0 == NULL\n");
+        return;
+    }
+
+    gmac = (gk_gmac_object_t*)dev->user_data;
+
+    if (buffer == NULL) {
+        rt_kprintf("recv_isr_callback: error buffer == NULL\n");
+        return;
+    }
+
+    if ((len <= 0) || (len > GMAC_RX_BUFFER_SIZE)) {
+        rt_kprintf("recv_isr_callback: error len = %d(1~%d)\n", len, GMAC_RX_BUFFER_SIZE);
+        return;
+    }
+
+    gmac->rx_buffer = (U8*)buffer;
+    gmac->rx_len = len;
+    //rt_kprintf("recv_isr_callback = 0x%x, len = %d\n", gmac->rx_buffer, gmac->rx_len);
+
+    ret_eth = eth_device_ready(&(gmac->parent));
+    if (ret_eth != RT_EOK)
+    {
+        rt_kprintf("eth_device_ready error %d\n",ret_eth);
+    }
+}
+
+int rt_app_gk_gmac_init(void)
+{
+    gk_gmac_object_t* gmac;
+
+    GD_ETH_MacT macaddr;
+    gmac = (gk_gmac_object_t*)rt_malloc(sizeof(*gmac));
+    if (gmac == NULL)
+    {
+        rt_kprintf("gk_eth_initialize: Cannot allocate Gmac_Object %d\n", 1);
+        return (-1);
+    }
+
+    memset(gmac, 0, sizeof(gk_gmac_object_t));
+
+    rt_sem_init(&gmac->rx_lock, "rx_lock", 1, RT_IPC_FLAG_FIFO);
+
+    gmac->parent.parent.init      = rt_gk_gmac_init;
+    gmac->parent.parent.open      = rt_gk_gmac_open;
+    gmac->parent.parent.close     = rt_gk_gmac_close;
+    gmac->parent.parent.read      = rt_gk_gmac_read;
+    gmac->parent.parent.write     = rt_gk_gmac_write;
+    gmac->parent.parent.control   = rt_gk_gmac_control;
+    gmac->parent.parent.user_data = (void*)gmac;
+
+    gmac->parent.eth_rx = rt_gk_gmac_rx;
+    gmac->parent.eth_tx = rt_gk_gmac_tx;
+
+    gk_gmac_init(&gmac->parent.parent);
+
+    eth_device_init(&(gmac->parent), "e0");
+
+    return 0;
+}
+
+#ifdef RT_USING_FINSH
+#include "finsh.h"
+
+void dump_rx_desc(void)
+{
+    int i;
+    gk_gmac_object_t* gmac;
+    rt_device_t dev = rt_device_find("e0");
+
+    if (dev == RT_NULL) return;
+
+    gmac = (gk_gmac_object_t*)dev->user_data;
+
+    rt_kprintf("soft current desc is:%d\n", gmac->link);
+}
+
+void dump_tx_desc(void)
+{
+    int i;
+    gk_gmac_object_t* gmac;
+    rt_device_t dev = rt_device_find("e0");
+
+    if (dev == RT_NULL) return;
+
+    gmac = (gk_gmac_object_t*)dev->user_data;
+
+    rt_kprintf("soft current desc is:%d\n", gmac->link);
+}
+
+
+FINSH_FUNCTION_EXPORT(dump_rx_desc, dump e0 rx desc);
+FINSH_FUNCTION_EXPORT(dump_tx_desc, dump e0 tx desc);
+
+#endif
+
+#endif

+ 35 - 0
bsp/gkipc/drivers/drv_gmac.h

@@ -0,0 +1,35 @@
+/*
+ * File      : drv_gmac.h
+ * This file is part of GK710X BSP for RT-Thread distribution.
+ *
+ * Copyright (c) 2017 GOKE Microelectronics Co., Ltd.
+ * All rights reserved
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *  Visit http://www.goke.com to get contact with Goke.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+
+#ifndef GMAC_H_
+#define GMAC_H_
+
+#ifdef RT_USING_GMAC
+int rt_app_gk_gmac_init(void);
+#endif
+
+#endif /* GMAC_H_ */

+ 304 - 0
bsp/gkipc/drivers/drv_i2c.c

@@ -0,0 +1,304 @@
+/*
+ * File      : drv_i2c.c
+ * This file is part of gkipc BSP for RT-Thread distribution.
+ *
+ * Copyright (c) 2016 Shanghai goke Microelectronics Co., Ltd.
+ * All rights reserved
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *  Visit http://www.goke.com to get contact with Fullhan.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+
+#include <rtdevice.h>
+#include <rthw.h>
+#include "drv_i2c.h"
+
+#include "gtypes.h"
+
+#include "platform.h"
+
+#include "gd_i2c.h"
+
+/*---------------------------------------------------------------------------*/
+/* local defines                                                             */
+/*---------------------------------------------------------------------------*/
+
+
+//#define GK_I2C_DEBUG
+#ifndef GK_I2C_DEBUG
+#define I2C_PRINT_DBG(fmt, args...)
+#define I2C_PRINT_ERR(fmt, args...) rt_kprintf(fmt, ##args);
+#else
+#define I2C_PRINT_DBG(fmt, args...) rt_kprintf(fmt, ##args);
+#define I2C_PRINT_ERR(fmt, args...) rt_kprintf(fmt, ##args);
+#endif
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Local structures
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Global Data
+//*****************************************************************************
+//*****************************************************************************
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Local Data
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Local Functions Declaration
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Local Functions
+//*****************************************************************************
+//*****************************************************************************
+
+static int gk_i2c_init(struct gk_i2c_obj *i2c_obj)
+{
+    int ret = RT_EOK;
+
+    ret = GD_I2C_Init((GD_I2C_INIT_PARAMS_S*)&i2c_obj->config.i2cInitParams);
+
+    return ret;
+}
+
+static rt_size_t gk_i2c_xfer(struct rt_i2c_bus_device *dev,
+                             struct rt_i2c_msg msgs[], rt_uint32_t num)
+{
+    int ret;
+    U8 address    = 0;
+    U8* buffer    = NULL;
+    U8* regbuffer = NULL;
+    U32 regbytes  = 0;
+    U32 bytes     = 0;
+
+    struct gk_i2c_obj *i2c_obj = (struct gk_i2c_obj *)dev->priv;
+
+    if (num < 2)
+    {
+        if (msgs[0].flags == RT_I2C_WR)
+        {
+            address = msgs[0].addr;
+            buffer  = msgs[0].buf;
+            bytes   = msgs[0].len;
+            ret = GD_I2C_Write( (GD_HANDLE *)&i2c_obj->handle,address,buffer,bytes );
+            if (ret != RT_EOK)
+            {
+                I2C_PRINT_ERR("[%s:%d]I2C Write error!\n",__func__,__LINE__);
+                return RT_ERROR;
+            }
+
+        }
+    }
+    else
+    {
+        if ((msgs[0].flags == RT_I2C_WR) && (msgs[1].flags == RT_I2C_RD))
+        {
+            address    = msgs[0].addr;
+            regbuffer  = msgs[0].buf;
+            regbytes   = msgs[0].len;
+
+            buffer     = msgs[1].buf;
+            bytes      = msgs[1].len;
+        }
+        else if ((msgs[0].flags == RT_I2C_RD ) && (msgs[1].flags == RT_I2C_WR))
+        {
+            address    = msgs[1].addr;
+            regbuffer  = msgs[1].buf;
+            regbytes   = msgs[1].len;
+
+            buffer     = msgs[0].buf;
+            bytes      = msgs[0].len;
+        }
+        ret = GD_I2C_Read( (GD_HANDLE *)&i2c_obj->handle,(U8)address, (U8*)regbuffer,(U32)regbytes,(U8*) buffer, (U32)bytes );
+        if (ret != RT_EOK)
+        {
+            I2C_PRINT_ERR("[%s:%d]I2C_Read error!\n",__func__,__LINE__);
+            return RT_ERROR;
+        }
+
+    }
+
+    return ret;
+}
+
+
+static const struct rt_i2c_bus_device_ops gk_i2c_ops = {
+    .master_xfer = gk_i2c_xfer,
+};
+
+int gk_i2c_probe(void *priv_data)
+{
+    int ret;
+    struct rt_i2c_bus_device *i2c_bus_dev;
+    struct gk_i2c_obj *i2c_obj = (struct gk_i2c_obj *)priv_data;
+    char i2c_dev_name[5]       = {0};
+
+    i2c_bus_dev = (struct rt_i2c_bus_device *)rt_malloc(sizeof(struct rt_i2c_bus_device));
+    rt_memset(i2c_bus_dev, 0, sizeof(struct rt_i2c_bus_device));
+    i2c_bus_dev->ops = &gk_i2c_ops;
+
+    rt_sprintf(i2c_dev_name, "%s%d", "i2c", i2c_obj->id);
+    ret = rt_i2c_bus_device_register(i2c_bus_dev, i2c_dev_name);
+    if (ret != RT_EOK)
+    {
+        I2C_PRINT_ERR("ERROR:rt_spi_bus_register failed, ret=%d\n", ret);
+        return -RT_ENOMEM;
+    }
+
+    // priv struct init
+    i2c_obj->lock = rt_mutex_create("i2c_mux", RT_IPC_FLAG_FIFO);
+
+    gk_i2c_init(i2c_obj);
+
+    return ret;
+}
+
+
+int gk_i2c_exit(void *priv_data)
+{
+    struct gk_i2c_obj *i2c_obj = (struct gk_i2c_obj *)priv_data;
+
+    GD_I2C_Close((GD_HANDLE *)&i2c_obj->handle);
+    GD_I2C_Exit();
+    return 0;
+}
+
+struct gk_platform_driver i2c_driver_ops = {
+    .name = "i2c", .probe = gk_i2c_probe, .remove = gk_i2c_exit,
+};
+
+void rt_hw_i2c_init(void)
+{
+    I2C_PRINT_DBG("%s start\n", __func__);
+    gk_platform_driver_init(&i2c_driver_ops);
+    I2C_PRINT_DBG("%s end\n", __func__);
+    // fixme: never release?
+}
+
+
+//#define GK_TEST_I2C
+#ifdef GK_TEST_I2C
+static rt_err_t gk_i2c_test_read_reg(struct rt_i2c_bus_device *gk_i2c,
+                                rt_uint16_t reg, rt_uint8_t *data)
+{
+    struct rt_i2c_msg msg[2];
+    rt_uint8_t send_buf[2];
+    rt_uint8_t recv_buf[1] = {0};
+
+    I2C_PRINT_DBG("%s start\n", __func__);
+
+    send_buf[0] = (reg & 0xFF);
+
+    msg[0].addr  = 0x51;
+    msg[0].flags = RT_I2C_WR;
+    msg[0].len   = 1;
+    msg[0].buf   = send_buf;
+
+    msg[1].addr  = 0x51;
+    msg[1].flags = RT_I2C_RD;
+    msg[1].len   = 1;
+    msg[1].buf   = recv_buf;
+
+    rt_i2c_transfer(gk_i2c, msg, 2);
+    *data = recv_buf[0];
+    return RT_EOK;
+}
+static rt_err_t gk_i2c_test_write_reg(struct rt_i2c_bus_device *gk_i2c,
+                                 rt_uint16_t reg, rt_uint8_t data)
+{
+    struct rt_i2c_msg msg;
+    rt_uint8_t send_buf[3];
+
+    I2C_PRINT_DBG("%s start\n", __func__);
+
+    // send_buf[0] = ((reg >> 8) & 0xff);
+    send_buf[1] = (reg & 0xFF);
+    send_buf[2] = data;
+
+    msg.addr  = 0x51;
+    msg.flags = RT_I2C_WR;
+    msg.len   = 2;
+    msg.buf   = send_buf;
+
+    rt_i2c_transfer(gk_i2c, &msg, 1);
+    I2C_PRINT_DBG("%s end\n", __func__);
+    return RT_EOK;
+}
+
+void i2c_test_sensor()
+{
+    struct rt_i2c_bus_device *gk_i2c;
+    gk_i2c_obj_s i2c_obj;
+
+    rt_uint8_t data[1] = {0x00};
+    int ret = 0;
+    gk_i2c = rt_i2c_bus_device_find("i2c1");
+
+    GD_I2C_OPEN_PARAMS_S i2c_param;
+    i2c_param.channel = GADI_I2C_CHANNEL_ONE;
+    i2c_param.speed   = GADI_I2C_100KBPS;
+    i2c_param.mode    = GADI_I2C_INTERRUPT;//GADI_I2C_NORMAL;
+
+    i2c_obj.handle = 0;
+    ret = GD_I2C_Open((GD_I2C_OPEN_PARAMS_S*)&i2c_param, &i2c_obj.handle);
+    if (ret != 0)
+    {
+        I2C_PRINT_DBG("GD_I2C_Open error!\n");
+        return -1;
+    }
+    gk_i2c.priv = &i2c_obj;
+
+    gk_i2c_test_write_reg(gk_i2c, 0x04, 0x02);
+
+    gk_i2c_test_read_reg(gk_i2c, 0x02, data);
+
+    I2C_PRINT_DBG("data read from 0x3038 is 0x%x\r\n", data[0]);
+    I2C_PRINT_DBG("%s end\n", __func__);
+}
+
+#ifdef RT_USING_FINSH
+#include <finsh.h>
+FINSH_FUNCTION_EXPORT(i2c_test_sensor, sensor i2c test);
+#endif
+
+
+#endif /*GK_TEST_I2C end*/
+

+ 144 - 0
bsp/gkipc/drivers/drv_i2c.h

@@ -0,0 +1,144 @@
+/*
+ * File      : drv_i2c.h
+ * This file is part of gkipc BSP for RT-Thread distribution.
+ *
+ * Copyright (c) 2017 ChengDu goke Microelectronics Co., Ltd.
+ * All rights reserved
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *  Visit http://www.goke.com to get contact with goke.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+
+#ifndef _I2C_H_
+#define _I2C_H_
+
+#include <rtthread.h>
+
+
+/*!
+*******************************************************************************
+** \brief I2C channel number.
+*******************************************************************************
+*/
+typedef enum
+{
+    RT_I2C_CHANNEL_ONE = 0, /*!< I2C channel 1.*/
+    RT_I2C_CHANNEL_TWO,     /*!< I2C channel 2.*/
+}RT_I2C_ChannelT;
+
+
+/*!
+*******************************************************************************
+** \brief I2C operition modes.
+*******************************************************************************
+*/
+typedef enum
+{
+    RT_I2C_GENERIC_MASTER_MODE, /*!< Generic master mode.*/
+    RT_I2C_GENERIC_SLAVER_MODE, /*!< Generic slave mode.*/
+    RT_I2C_AUTO_MASTER_MODE,    /*!< Auto master mode.*/
+    RT_I2C_AUTO_SLAVER_MODE,    /*!< Auto slave mode.*/
+    RT_I2C_DMA_MASTER_MODE,     /*!< DMA master mode.*/
+    RT_I2C_DMA_SLAVER_MODE,     /*!< DMA slave mode.*/
+}RT_I2C_OpenModeT;
+
+
+/*!
+*******************************************************************************
+** \brief Protocol modes.
+*******************************************************************************
+*/
+typedef enum
+{
+    RT_I2C_COMMON_PROTOCOL = 0,  /*!< Common protocol.*/
+    RT_I2C_RESTART_PROTOCOL,     /*!< Protocol with restart.*/
+}RT_I2C_ProtocolT;
+
+
+/*!
+*******************************************************************************
+** \brief I2C datarate speed modes.
+*******************************************************************************
+*/
+typedef enum
+{
+    RT_I2C_100KBPS = 100000, /*!< 100kHz datarate.*/
+    RT_I2C_400KBPS = 400000,     /*!< 400kHz datarate.*/
+}RT_I2C_SpeedT;
+
+/*!
+*******************************************************************************
+** \brief I2C transmit modes.
+*******************************************************************************
+*/
+typedef enum
+{
+    RT_I2C_NORMAL = 0,
+    RT_I2C_TURBO_MODE,  // write operation only.
+    RT_I2C_INTERRUPT,
+}RT_I2C_ModeT;
+
+/*!
+*******************************************************************************
+** \brief Init parameters.
+*******************************************************************************
+*/
+typedef struct
+{
+    RT_I2C_OpenModeT       mode;          /*!< Operation mode.*/
+    rt_int8_t              priority;      /*!< IRQ priority */
+    rt_int8_t              gpioSdaPinCh1; /*!< GPIO SDA pin assigmnet channel 1.*/
+    rt_int8_t              gpioSclPinCh1; /*!< GPIO SCL pin assigmnet channel 1.*/
+    rt_int8_t              gpioSdaPinCh2; /*!< For future use.*/
+    rt_int8_t              gpioSclPinCh2; /*!< For future use.*/
+}RT_I2C_InitParamsT;
+
+
+/*!
+*******************************************************************************
+** \brief Open parameters.
+*******************************************************************************
+*/
+typedef struct
+{
+    RT_I2C_ChannelT    channel;   /*!< i2c channel index*/
+    RT_I2C_SpeedT      speed;     /*!< i2c speed*/
+    RT_I2C_ModeT       mode;      /*!< i2c mode*/
+}RT_I2C_OpenParamsT;
+
+typedef struct gk_i2c_config
+{
+    RT_I2C_InitParamsT  i2cInitParams;
+}gk_i2c_config_s;
+
+
+
+typedef struct gk_i2c_obj
+{
+    rt_uint32_t id;
+    rt_uint32_t handle;
+    rt_mutex_t lock;
+    gk_i2c_config_s config;
+}gk_i2c_obj_s;
+
+
+void rt_hw_i2c_init(void);
+
+
+#endif/*_I2C_H_*/

+ 342 - 0
bsp/gkipc/drivers/drv_mmc.c

@@ -0,0 +1,342 @@
+/*
+ * File      : drv_mmc.c
+ * This file is part of gkipc BSP for RT-Thread distribution.
+ *
+ * Copyright (c) 2017 chengdu goke Microelectronics Co., Ltd.
+ * All rights reserved
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *  Visit http://www.goke.com to get contact with goke.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+
+#include "platform.h"
+#include <rtdef.h>
+#include <rtdevice.h>
+#include <drivers/mmcsd_core.h>
+#include <dfs_fs.h>
+
+#include "gd_sdio.h"
+#include "drv_mmc.h"
+
+
+//#define GK_MMC_DEBUG
+
+#if defined(GK_MMC_DEBUG) && defined(RT_DEBUG)
+#define PRINT_MMC_DBG(fmt, args...)                           \
+    do                                                        \
+    {                                                         \
+        rt_kprintf("FH_MMC_DEBUG: tick-%d, ", rt_tick_get()); \
+        rt_kprintf(fmt, ##args);                              \
+    } while (0)
+#else
+#define PRINT_MMC_DBG(fmt, args...) \
+    do                              \
+    {                               \
+    } while (0)
+#endif
+
+
+#define RT_SDIO_MAX_BLOCK_LEN       512    /*block size*/
+
+
+/*GLOBAL SD DEVICE PONITER*/
+static gk_mmc_driver_s sd_driver;
+fs_sdio_notify_func_t notifyFunc = NULL;
+
+
+static rt_err_t rt_sdcard_init(rt_device_t dev)
+{
+    gk_mmc_driver_s *mmc_drv = (gk_mmc_driver_s *)dev->user_data;
+    rt_uint32_t index        = mmc_drv->handle.index;
+    rt_uint32_t retVal       = RT_EOK;
+
+
+    return RT_EOK;
+}
+
+static rt_err_t rt_sdcard_open(rt_device_t dev, rt_uint16_t oflag)
+{
+    gk_mmc_driver_s *mmc_drv = (gk_mmc_driver_s *)dev->user_data;
+    rt_uint32_t index        = mmc_drv->handle.index;
+    rt_uint32_t retVal       = RT_EOK;
+
+    if (mmc_drv->handle.inUse == 0)
+    {
+        mmc_drv->openParams.isUseDmaWay      = 0;
+        retVal = GD_SDIO_Open((GD_SDIO_OpenParamsT *)&mmc_drv->openParams,(sdioHandleT *)&mmc_drv->handle,index);
+        if (retVal != RT_EOK)    {
+            rt_kprintf("[%s:%d]GD_SDIO_Open failed!\n",__func__,__LINE__);
+            return-RT_ENOMEM;
+        }
+    }
+    else
+    {
+        PRINT_MMC_DBG("----ALREADY_OPEN SDIO_%d----\n",index);
+    }
+
+	return RT_EOK;
+}
+
+static rt_err_t rt_sdcard_close(rt_device_t dev)
+{
+    gk_mmc_driver_s *mmc_drv = (gk_mmc_driver_s *)dev->user_data;
+    rt_uint32_t index        = mmc_drv->handle.index;
+    rt_uint32_t retVal       = RT_EOK;
+
+
+    retVal = GD_SDIO_Close((sdioHandleT *)&mmc_drv->handle,index);
+    if (retVal != RT_EOK)
+    {
+        rt_kprintf("[%s-%s:%d] failed!,retVal = %d\n",__FILE__,__func__,__LINE__,retVal);
+        return-RT_ENOMEM;
+    }
+
+
+    rt_device_unregister(mmc_drv->deviceP[index]);
+
+    if (mmc_drv->deviceP[index] != NULL){
+        rt_free(mmc_drv->deviceP[index]);
+        mmc_drv->deviceP[index] = NULL;
+    }
+
+    if (mmc_drv->partP[index] != NULL)
+    {
+        rt_free(mmc_drv->partP[index]);
+        mmc_drv->partP[index] = NULL;
+    }
+
+	return RT_EOK;
+}
+
+static rt_size_t rt_sdcard_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
+{
+    gk_mmc_driver_s *mmc_drv   = (gk_mmc_driver_s *)dev->user_data;
+    rt_uint32_t index          = mmc_drv->handle.index;
+    struct dfs_partition *part = (struct dfs_partition *)mmc_drv->partP[index];
+    rt_uint32_t retVal         = RT_EOK;
+
+    rt_sem_take(part->lock, RT_WAITING_FOREVER);
+    retVal = GD_SDIO_ReadSector((sdioHandleT *)&mmc_drv->handle, pos, buffer, size);
+    if (retVal != RT_EOK)
+    {
+        rt_kprintf("[%s-%s:%d]error!,retVal = %d\n",__FILE__,__func__,__LINE__,retVal);
+        rt_sem_release(part->lock);
+        return -RT_ENOMEM;
+    }
+    rt_sem_release(part->lock);
+
+    return size;
+
+}
+
+static rt_size_t rt_sdcard_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
+{
+    gk_mmc_driver_s *mmc_drv   = (gk_mmc_driver_s *)dev->user_data;
+    rt_uint32_t index          = mmc_drv->handle.index;
+    struct dfs_partition *part = (struct dfs_partition *)mmc_drv->partP[index];
+    rt_uint32_t retVal         = RT_EOK;
+
+    rt_sem_take(part->lock, RT_WAITING_FOREVER);
+    retVal = GD_SDIO_WriteSector((sdioHandleT *)&mmc_drv->handle,pos,(void*)buffer,size);
+    if (retVal != RT_EOK)
+    {
+        rt_kprintf("[%s-%s:%d]GD_SDIO_WriteSector failed!\n",__FILE__,__func__,__LINE__);
+        rt_sem_release(part->lock);
+        return -RT_ENOMEM;
+    }
+    rt_sem_release(part->lock);
+
+    return size;
+}
+
+static rt_err_t rt_sdcard_control(rt_device_t dev, int cmd, void *args)
+{
+    gk_mmc_driver_s *mmc_drv   = (gk_mmc_driver_s *)dev->user_data;
+    rt_uint32_t index          = mmc_drv->handle.index;
+    struct dfs_partition *part = (struct dfs_partition *)mmc_drv->partP[index];
+    rt_uint32_t retVal         = RT_EOK;
+
+
+    switch(cmd)
+    {
+        case RT_DEVICE_CTRL_BLK_GETGEOME:
+        {
+            struct rt_device_blk_geometry *geometry;
+            GD_SDIO_VolumeInfoT sdInfo;
+            rt_memset(&sdInfo,0,sizeof(sdInfo));
+            geometry = (struct rt_device_blk_geometry *)args;
+            retVal = GD_SDIO_GetCardInfo((sdioHandleT *)&mmc_drv->handle,&sdInfo,index);
+            if (retVal != RT_EOK)
+            {
+                rt_kprintf("[%s:%d]GD_SDIO_GetCardInfo failed!\n",__func__,__LINE__);
+                return-RT_ENOMEM;
+            }
+
+            geometry->block_size       = sdInfo.sectorSize;
+            geometry->sector_count     = sdInfo.sectorCount;
+            geometry->bytes_per_sector = sdInfo.sectorSize;
+            PRINT_MMC_DBG("[%s:%d]sd card block_size:%d,sector_count:%d!\n",__func__,__LINE__,
+                                                        geometry->block_size,geometry->sector_count);
+
+            break;
+        }
+
+        case RT_DEVICE_CTRL_BLK_ERASE:
+        {
+            unsigned int eraseAdress = 0x00;
+            unsigned short blkcnt = *(unsigned short *)args;
+            retVal = GD_SDIO_EraseSector((sdioHandleT *)&mmc_drv->handle,eraseAdress,blkcnt);
+            if (retVal != RT_EOK)
+            {
+                rt_kprintf("[%s-%s:%d]GD_SDIO_EraseSector failed!\n",__FILE__,__func__,__LINE__);
+                return-RT_ENOMEM;
+            }
+
+            break;
+        }
+
+        default:break;
+    }
+
+
+	return RT_EOK;
+}
+
+
+int rt_hw_mmc_init(gk_mmc_driver_s *pMmcParams)
+{
+    gk_mmc_driver_s *mmc_drv   = &sd_driver;
+    rt_uint32_t index          = pMmcParams->handle.index;
+    rt_uint32_t retVal         = RT_EOK;
+    rt_uint8_t *sector         = NULL;
+    rt_uint8_t sname[8]        = {0};
+    rt_uint8_t sdDeviceName[4] = {0};
+
+    if (pMmcParams == NULL)
+    {
+        rt_kprintf("[%s:%d] sdio init params is error!\n",__func__,__LINE__);
+        return -RT_ENOMEM;
+    }
+
+    mmc_drv->openParams.isUseDmaWay      = pMmcParams->openParams.isUseDmaWay;
+    mmc_drv->openParams.notifyFunc       = pMmcParams->openParams.notifyFunc;
+    mmc_drv->openParams.notifyFuncOptPtr = pMmcParams->openParams.notifyFuncOptPtr;
+    retVal = GD_SDIO_Open((GD_SDIO_OpenParamsT *)&mmc_drv->openParams,(sdioHandleT *)&mmc_drv->handle,index);
+    if (retVal != RT_EOK)    {
+        rt_kprintf("[%s:%d]GD_SDIO_Open failed!\n",__func__,__LINE__);
+        return -RT_ENOMEM;
+    }
+
+    /* get the first sector to read partition table */
+    sector = (rt_uint8_t*) rt_malloc (RT_SDIO_MAX_BLOCK_LEN);
+    if (sector == RT_NULL)
+    {
+        rt_kprintf("allocate partition sector buffer failed\n");
+        GD_SDIO_Close((sdioHandleT *)&mmc_drv->handle,index);
+        return -RT_ENOMEM;
+    }
+
+    /*alloc device buffer*/
+    mmc_drv->deviceP[index] = (struct rt_device*)rt_malloc(sizeof(struct rt_device));
+    if(mmc_drv->deviceP[index] == RT_NULL)
+    {
+         rt_kprintf("[%s:%d]allocate device failed\n",__func__,__LINE__);
+         GD_SDIO_Close((sdioHandleT *)&mmc_drv->handle,index);
+         return -RT_ENOMEM;
+    }
+
+    mmc_drv->partP[index] = (struct dfs_partition*)rt_malloc(sizeof(struct dfs_partition));
+    if(mmc_drv->partP[index] == RT_NULL)
+    {
+         rt_kprintf("[%s:%d]allocate partP failed\n",__func__,__LINE__);
+         GD_SDIO_Close((sdioHandleT *)&mmc_drv->handle,index);
+         return -RT_ENOMEM;
+    }
+
+    retVal = GD_SDIO_ReadSector((sdioHandleT *)&mmc_drv->handle, 0, sector, 1);
+    if (retVal != RT_EOK)
+    {
+        rt_kprintf("[%s-%s:%d]GD_SDIO_ReadSector failed!\n",__FILE__,__func__,__LINE__);
+        GD_SDIO_Close((sdioHandleT *)&mmc_drv->handle,index);
+        goto err;
+    }
+
+    /* get the first partition */
+    retVal = dfs_filesystem_get_partition(mmc_drv->partP[index], sector, 0);
+    if (retVal != RT_EOK)
+    {
+        rt_kprintf("[%s-%s:%d] failed!,retVal = %d\n",__FILE__,__func__,__LINE__,retVal);
+        GD_SDIO_Close((sdioHandleT *)&mmc_drv->handle,index);
+        goto err;
+    }
+    rt_snprintf(sname, 8, "sem_sd%d", index);
+    mmc_drv->partP[index]->lock = rt_sem_create(sname, 1, RT_IPC_FLAG_FIFO);
+
+    /* sdcard hardware init */
+    rt_memset(mmc_drv->deviceP[index],0,sizeof(struct rt_device));
+    mmc_drv->deviceP[index]->type       = RT_Device_Class_Block;
+    mmc_drv->deviceP[index]->init       = rt_sdcard_init;
+    mmc_drv->deviceP[index]->open       = rt_sdcard_open;
+    mmc_drv->deviceP[index]->close      = rt_sdcard_close;
+    mmc_drv->deviceP[index]->read       = rt_sdcard_read;
+    mmc_drv->deviceP[index]->write      = rt_sdcard_write;
+    mmc_drv->deviceP[index]->control    = rt_sdcard_control;
+    mmc_drv->deviceP[index]->user_data  = (void *)mmc_drv;
+
+
+    rt_snprintf(sdDeviceName, 4, "sd%d",index);
+    retVal = rt_device_register(mmc_drv->deviceP[index], sdDeviceName,
+        RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE);
+
+    if (retVal != RT_EOK)
+    {
+        rt_kprintf("[%s:%d]rt_device_register name :%s failed!\n",__func__,__LINE__,sdDeviceName);
+        GD_SDIO_Close((sdioHandleT *)&mmc_drv->handle,index);
+        goto err;
+    }
+
+    /* release sector buffer */
+    if (sector != NULL){
+        rt_free(sector);
+        sector = NULL;
+    }
+
+    return RT_EOK;
+
+err:
+    if (mmc_drv->deviceP[index] != NULL){
+        rt_free(mmc_drv->deviceP[index]);
+        mmc_drv->deviceP[index] = NULL;
+    }
+
+    if (mmc_drv->partP[index] != NULL)
+    {
+        rt_free(mmc_drv->partP[index]);
+        mmc_drv->partP[index] = NULL;
+    }
+
+    if (sector != NULL){
+        rt_free(sector);
+        sector = NULL;
+    }
+
+    return -RT_ETIMEOUT;
+
+}
+

+ 186 - 0
bsp/gkipc/drivers/drv_mmc.h

@@ -0,0 +1,186 @@
+/*
+ * File      : drv_mmc.h
+ * This file is part of gkipc BSP for RT-Thread distribution.
+ *
+ * Copyright (c) 2017 chengdu goke Microelectronics Co., Ltd.
+ * All rights reserved
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *  Visit http://www.goke.com to get contact with goke.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+
+#ifndef MMC_H_
+#define MMC_H_
+
+#include "rtdevice.h"
+
+#define MMC_FEQ_MIN 100000
+#define MMC_FEQ_MAX 50000000
+#define MMC_DMA_DESC_BUFF_SIZE (0x1f00)
+#define MMC_HANDLE_COUNT 2
+
+
+#define CARD_UNPLUGED 1
+#define CARD_PLUGED 0
+
+typedef enum {
+    RT_GAPI_SDIO_VERSION = (rt_int32_t)0x00010000 //!< The current driver version
+} RT_SDIO_VersionEnumT;
+
+
+ typedef enum {
+    RT_GAPI_SDIO_TRANSFER_TYPE_NORMAL = 0,     //!< Normal transfer type for SD/SDHC/MMC cards (default)
+    RT_GAPI_SDIO_TRANSFER_TYPE_DIRECT,         //!< Direct transfer mode special for SDIO cards
+    RT_GAPI_SDIO_TRANSFER_TYPE_SECURE,         //!< Spezial secure transfer mode for SD-Cards
+    RT_GAPI_SDIO_TRANSFER_TYPE_WIFI
+} RT_SDIO_TransferTypeEnumT;
+
+ typedef enum rt_card_type
+ {
+     RT_CARDTYPE_NONE = 0,
+     RT_CARDTYPE_MMC,
+     RT_CARDTYPE_SD10,
+     RT_CARDTYPE_SD20,
+     RT_CARDTYPE_SDHC
+ }RT_SDIO_Card_Type;
+
+ /*!
+****************************************************************************
+**
+** \brief SDIO callback function signature
+**
+** This is the callback function signature required by the SDIO driver
+** for internally notification functions.
+**
+** \param comState  Comunication status.
+** \param optArgPtr Optional arg pointer.
+**
+****************************************************************************
+*/
+typedef void (*RT_SDIO_NotifyFuncT)(rt_uint32_t index, rt_uint32_t comState, void* optArgPtr);
+
+typedef void (*RT_SDIO_IRQFuncT)();
+typedef void (*RT_SDIO_RESETFuncT)(rt_uint32_t index);
+
+
+
+
+typedef struct {
+    /*!
+       The version of the driver.
+       \ref GAPI_SDIO_VersionEnumT "GAPI_SDIO_VERSION".
+    */
+    RT_SDIO_VersionEnumT      version;
+	RT_SDIO_TransferTypeEnumT type;
+    /*!
+    ** The handle specific notification function.
+    */
+    RT_SDIO_NotifyFuncT  notifyFunc;
+
+	RT_SDIO_IRQFuncT	 irqFunc;
+
+	RT_SDIO_RESETFuncT   resetFunc;
+    /*!
+    ** Optional data pointer for the notification function.
+    */
+    void*                notifyFuncOptPtr;
+    /*!
+       Flag to request DMA for read/write transfer operation.
+    */
+    rt_uint32_t          isUseDmaWay;
+}RT_SDIO_OpenParamsT;
+
+
+/*cid info */
+typedef struct
+{
+    rt_uint8_t    MID;        /*Manufacturer ID            width:8[127:120]*/
+    rt_uint16_t   OID;        /*OEM/Application ID       width:16[119:104]*/
+    rt_uint8_t    PNM[5];     /*Product name               width:40[103:64]*/
+    rt_uint8_t    PRV;        /*Product revision            width:8[63:56]*/
+    rt_uint32_t   PSN;        /*Product serial number    width:32[55:24]*/
+    rt_uint16_t   MDT;        /*Manufacturing date        width:12[19:8]*/
+}rtSdioCidInfo;
+
+/*I just care about usefull info of CSD*/
+typedef struct
+{
+    rt_uint8_t    csdStructure;        /*csd revision*/
+    rt_uint32_t   classes;            /*Describes the card command classes  CCC*/
+    rt_uint32_t   tranSpeed;           /*transfer speed*/
+    rt_uint8_t    eraseBlkEn;          /*erase block enable*/
+    rt_uint8_t    permWriteProtect;    /*write protect*/
+    rt_uint8_t    tmpWriteProtect;     /*write protect*/
+}rtSdiocsdInfo;
+
+/*I just case ablot usefull info of SCR*/
+typedef struct
+{
+    rt_uint32_t    scrStructure;        // SCR Register Structure Version
+    rt_uint32_t    sdSpec;              // Describes the Physical Layer Specification Version supported by the card.
+    rt_uint32_t    stateaftererase;     // Defines the data status after erase, whether it is 0 or 1.
+    rt_uint32_t    sdSecurity;          // Describes the Security Specification Version supported by the card.
+    rt_uint32_t    sdBusWith;           // Describes all the DAT bus widths that are supported by this card.
+}rtSdioScrInfo;
+
+typedef struct
+{
+    rt_uint32_t    index;                /*index of handle array*/
+    rt_uint32_t    ocr;                  /*card volage info*/
+    rt_uint32_t    csd[4];               /*csd info (invert)*/
+    rt_uint32_t    read_bl_len;
+    rt_uint32_t    write_bl_len;
+    unsigned long long    capacity_user;
+    rt_uint32_t    sectorcount;
+    rt_uint32_t    inhighspeed;
+    rt_uint32_t    maxTransferBlk;
+    rt_uint32_t    eraseGrpSize;
+    rtSdioScrInfo  scr;
+    rtSdiocsdInfo  csdInfo;
+    rt_uint32_t    tran_speed;            /*max transfer speed*/
+    rt_uint32_t    rca;                   /*card address*/
+    rt_uint32_t    cid[4];                /*card  cid info*/
+    enum rt_card_type    type;       /*card type*/
+    rt_uint32_t      highCapacity;          /*is high capacity*/
+    rtSdioCidInfo    cidInfo;
+}rtSdioBlockT;
+
+/* SDIO specific handle */
+typedef struct
+ {
+     rt_uint32_t           inUse;        /* specifies if handle is in use */
+     rt_uint32_t           index;        /*index of handle array*/
+     RT_SDIO_OpenParamsT   openParams;   /* open params of the handle */
+     rtSdioBlockT          devicePtr;    /* pointer to hardware device */
+ } rtSdioHandleT;
+
+typedef struct gk_mmc_driver
+{
+    rtSdioHandleT        handle;
+    RT_SDIO_OpenParamsT  openParams;
+    struct rt_device     *deviceP[MMC_HANDLE_COUNT];
+    struct dfs_partition *partP[MMC_HANDLE_COUNT];
+}gk_mmc_driver_s;
+
+
+typedef void (*fs_sdio_notify_func_t)(rt_uint32_t index, rt_uint32_t comState, void* optArgPtr);
+
+int rt_hw_mmc_init(gk_mmc_driver_s *pMmcParams);
+
+#endif /* MMC_H_ */

+ 512 - 0
bsp/gkipc/drivers/drv_pwm.c

@@ -0,0 +1,512 @@
+/*
+ * File      : drv_pwm.c
+ * This file is part of GK710X BSP for RT-Thread distribution.
+ *
+ * Copyright (c) 2017 GOKE Microelectronics Co., Ltd.
+ * All rights reserved
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *  Visit http://www.goke.com to get contact with Goke.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+#include <rtdevice.h>
+//#include "gpio.h"
+
+#include "drv_pwm.h"
+
+#include <rtdef.h>
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <drivers/watchdog.h>
+
+#include "gtypes.h"
+#include "gd_pwm.h"
+#include "platform.h"
+
+#define GK_TEST_PWM
+static struct gk_pwm_obj *pwm_drv = NULL;
+static struct pwm_driver pwm_drv_table;
+
+static rt_err_t pwm_get_status(rt_uint32_t *status)
+{
+    rt_uint32_t channel_enable;
+
+    struct gk_pwm_obj *pwm_obj = (struct gk_pwm_obj *)pwm_drv;
+    if(status == NULL || pwm_obj->id >= PWM_MAX_CHANNEL)
+    {
+        rt_kprintf("PWM: > max channel \n");
+        return RT_ERROR;
+    }
+
+    if (GD_OK != GD_PWM_Get_Status(pwm_obj->id, &channel_enable))
+    {
+        rt_kprintf("get pwm status failed!\n");
+        return RT_ERROR;
+    }
+    *status = channel_enable;
+
+    return RT_EOK;
+}
+
+static rt_err_t pwm_enable(struct gk_pwm_obj *pwm_obj)
+{
+    rt_uint32_t ret = RT_EOK;
+
+    if (pwm_obj->id >= PWM_MAX_CHANNEL)
+    {
+        rt_kprintf("PWM: > max channel \n");
+        return RT_ERROR;
+    }
+
+    ret = GD_PwmOnOff(pwm_obj->id, GTRUE);
+    if (ret != GD_OK)
+    {
+        rt_kprintf("enable pwm device failed!\n");
+        return RT_ERROR;
+    }
+
+    return RT_EOK;
+}
+
+static rt_err_t pwm_disable(struct gk_pwm_obj *pwm_obj)
+{
+    rt_uint32_t ret = RT_EOK;
+
+    if (pwm_obj->id >= PWM_MAX_CHANNEL)
+    {
+        rt_kprintf("PWM: > max channel \n");
+        return RT_ERROR;
+    }
+
+    ret = GD_PwmOnOff(pwm_obj->id, GFALSE);
+    if (ret != GD_OK)
+    {
+        rt_kprintf("disable pwm device failed!\n");
+        return RT_ERROR;
+    }
+
+    return ret;
+}
+
+static int pwm_get_duty_cycle_ns(struct pwm_device *pwm)
+{
+    struct gk_pwm_obj *pwm_obj = (struct gk_pwm_obj *)pwm_drv;
+    rt_uint32_t freq, duty;
+
+    if (pwm_obj->id >= PWM_MAX_CHANNEL)
+    {
+        rt_kprintf("PWM: > max channel \n");
+        return -1;
+    }
+
+    if (GD_PWM_Get_Param(pwm_obj->id, &freq, &duty))
+    {
+        rt_kprintf("GD_PWM_Get_Param error.\n");
+        return -1;
+    }
+
+    rt_kprintf("get duty: %lu%%, freq: %lu\n", duty, freq);
+
+    return 0;
+}
+
+static int pwm_set_duty_cycle_ns(struct pwm_device *pwm)
+{
+    struct gk_pwm_obj *pwm_obj = (struct gk_pwm_obj *)pwm_drv;
+    rt_uint32_t range, duty, freq;
+    GERR ret = 0;
+
+    if(pwm_obj->id >= PWM_MAX_CHANNEL)
+    {
+        rt_kprintf("PWM: > max channel \n");
+        return -1;
+    }
+
+    freq = pwm->freq;
+    range = pwm->range;
+    duty = pwm->duty;
+    //param mode The PWM mode: 0 - Normal Speed Mode; 1 - Sync Speed Mode.
+    ret = GD_PWM_Set_Mode(pwm_obj->id, 0);
+    if(ret != GD_OK)
+    {
+        rt_kprintf("Set pwm mode 0 failed!\n");
+        return -1;
+    }
+
+    ret = GD_PWM_Set_Param(pwm_obj->id, freq, range, duty);
+    if (GD_PWM_NO_ERR != ret)
+    {
+        if (GD_PWM_ERR_NOT_SUPPORTED_CHANNEL == ret)
+        {
+            rt_kprintf("PWM Set_Param:set[%d %d %d]error *not support channel.\n",
+                       (int)freq, (int)range, (int)duty);
+        }
+        else if(GD_PWM_ERR_NOT_SUPPORTED_FREQUENCY == ret)
+        {
+            rt_kprintf("PWM Set_Param:set[%d %d %d]error *not support Freq.\n",
+                    (int)freq, (int)range, (int)duty);
+        }
+        else if(GD_PWM_ERR_NOT_SUPPORTED_RANGE == ret)
+        {
+            rt_kprintf("PWM Set_Param:set[%d %d %d]error *not support Range.\n",
+                    (int)freq, (int)range, (int)duty);
+        }
+        else if(GD_PWM_ERR_WRONG_DUTY_CONFIGURATION == ret)
+        {
+            rt_kprintf("PWM Set_Param:set[%d %d %d]error *wrong duty.\n",
+                    (int)freq, (int)range, (int)duty);
+        }
+        else if(GD_PWM_ERR_RANGE_EXCEED_LIMIT == ret)
+        {
+            rt_kprintf("PWM Set_Param:set[%d %d %d]error *exceed Range limit.\n",
+                    (int)freq, (int)range, (int)duty);
+        }
+
+        return -1;
+    }
+
+    return 0;
+}
+
+static int pwm_get_vsync_mode_param(rt_uint16_t *speed)
+{
+    struct gk_pwm_obj *pwm_obj = (struct gk_pwm_obj *)pwm_drv;
+    GERR ret = GD_OK;
+
+    if (pwm_obj->id >= PWM_MAX_CHANNEL)
+    {
+        rt_kprintf("PWM: > max channel \n");
+        return -1;
+    }
+
+    ret = GD_PWM_Get_Speed(pwm_obj->id, speed);
+    if(ret != GD_OK)
+    {
+        rt_kprintf("Get pwm speed failed!\n");
+        return -1;
+    }
+
+    rt_kprintf("get speed: %u\n", *speed);
+
+    return 0;
+}
+
+static int pwm_set_vsync_mode_param(struct pwm_param_vsync_mode *param)
+{
+    struct gk_pwm_obj *pwm_obj = (struct gk_pwm_obj *)pwm_drv;
+    GERR ret = GD_OK;
+
+    if(pwm_obj->id >= PWM_MAX_CHANNEL)
+    {
+        rt_kprintf("PWM: > max channel \n");
+        return -1;
+    }
+
+    //param mode The PWM mode: 0 - Normal Speed Mode; 1 - Sync Speed Mode.
+    ret = GD_PWM_Set_Mode(pwm_obj->id, 1);
+    if(ret != GD_OK)
+    {
+        rt_kprintf("Set pwm mode 1 failed!\n");
+        return -1;
+    }
+
+    ret = GD_PWM_Set_Speed(pwm_obj->id, param->speed);
+    if(ret != GD_OK)
+    {
+        rt_kprintf("Set pwm speed failed!\n");
+        return -1;
+    }
+
+    ret = GD_PWM_Cycle(pwm_obj->id, param->highLevelCnt, param->lowLevelCnt);
+    if(ret != GD_OK)
+    {
+        rt_kprintf("Set pwm cycle failed!\n");
+        return -1;
+    }
+
+    return 0;
+}
+
+static int pwm_set_clock_divider(int ratio)
+{
+    struct gk_pwm_obj *pwm_obj = (struct gk_pwm_obj *)pwm_drv;
+    rt_uint32_t range, duty, freq;
+    GERR ret = 0;
+
+    if (pwm_obj->id >= PWM_MAX_CHANNEL)
+    {
+        rt_kprintf("PWM: > max channel \n");
+        return -1;
+    }
+
+	if ((ratio != 1) && (ratio != 2) && (ratio != 3))
+	{
+	    rt_kprintf("pwm_set_clock_divider:%d wrong param.\n", ratio);
+		return -1;
+	}
+
+	if (GD_OK != GD_PWM_Set_Clock_Divider(pwm_obj->id, ratio))
+	{
+		rt_kprintf("gadi_pwm_set_clock_divider:%d set error.\n", ratio);
+		return -1;
+	}
+
+	return 0;
+}
+
+static int pwm_set_active_channel(int id)
+{
+    GERR ret = 0;
+
+    if (id >= PWM_MAX_CHANNEL)
+    {
+        rt_kprintf("PWM: > max channel \n");
+        return -1;
+    }
+
+    if (pwm_drv_table.pwm[id].gpio_id == 0xff)
+    {
+        rt_kprintf("channel not open \n");
+        return -1;
+    }
+
+    pwm_drv->id = id;
+
+    return 0;
+}
+
+static rt_err_t pwm_start(struct gk_pwm_obj *pwm_obj)
+{
+    rt_uint32_t pwmStatus = 0;
+    rt_uint32_t ret = GD_OK;
+
+    ret = pwm_get_status(&pwmStatus);
+    if(ret != RT_EOK)
+    {
+        return ret;
+    }
+
+    if(pwmStatus)
+    {
+        ret = pwm_disable(pwm_obj);
+        if(ret != RT_EOK)
+        {
+            return ret;
+        }
+    }
+
+    return pwm_enable(pwm_obj);
+}
+
+static rt_err_t gk_pwm_open(rt_device_t dev, rt_uint16_t oflag)
+{
+    rt_err_t ret = RT_EOK;
+    int index;
+
+    for (index=0; index<PWM_MAX_CHANNEL; index++)
+    {
+        if ((pwm_drv_table.pwm[index].id != 0xff) && (pwm_drv_table.pwm[index].gpio_id != 0xff))
+        {
+            rt_kprintf("pwm_drv_table.pwm[%d] id= %d, gpio_id = %d\n",
+                        index,
+                        pwm_drv_table.pwm[index].id,
+                        pwm_drv_table.pwm[index].gpio_id);
+
+            ret = GD_PWM_Open(pwm_drv_table.pwm[index].id, pwm_drv_table.pwm[index].gpio_id);
+            if(ret != GD_OK)
+            {
+               rt_kprintf("open pwm device %d channel failed!\n", pwm_drv_table.pwm[index].id);
+               continue;
+            }
+        }
+    }
+
+    if (pwm_drv_table.pwm[0].gpio_id != 0xff)
+    {
+        pwm_drv->id = pwm_drv_table.pwm[0].id;
+    }
+
+    return ret;
+}
+
+static rt_err_t gk_pwm_close(rt_device_t dev)
+{
+    struct gk_pwm_obj *pwm_obj = (struct gk_pwm_obj *)pwm_drv;
+
+    if(pwm_obj->id >= PWM_MAX_CHANNEL)
+    {
+        rt_kprintf("PWM: > max channel \n");
+        return RT_ERROR;
+    }
+
+    GD_PWM_Close(pwm_obj->id);
+
+    return RT_EOK;
+}
+
+static rt_err_t gk_pwm_ioctl(rt_device_t dev, int cmd, void *arg)
+{
+    int ratio, ret = 0;
+    rt_uint16_t *speed = NULL;
+    struct pwm_device *pwm = NULL;
+    struct pwm_param_vsync_mode *vsync_param = NULL;
+    struct gk_pwm_obj *pwm_obj = (struct gk_pwm_obj *)pwm_drv;
+
+    switch (cmd)
+    {
+        case ENABLE_PWM:
+            pwm_start(pwm_obj);
+            break;
+
+        case DISABLE_PWM:
+            pwm_disable(pwm_obj);
+            break;
+
+        case SET_PWM_DUTY_CYCLE:
+            pwm = (struct pwm_device *)arg;
+            pwm_set_duty_cycle_ns(pwm);
+            break;
+
+        case GET_PWM_DUTY_CYCLE:
+            pwm = (struct pwm_device *)arg;
+            pwm_get_duty_cycle_ns(pwm);
+            break;
+
+        case SET_PWM_VSYNC_MODE:
+            vsync_param = (struct pwm_param_vsync_mode *)arg;
+            pwm_set_vsync_mode_param(vsync_param);
+            break;
+
+        case GET_PWM_VSYNC_MODE:
+            speed = (rt_uint16_t *)arg;
+            pwm_get_vsync_mode_param(speed);
+            break;
+
+        case SET_PWM_CLOCK_DIV:
+            ratio = *((int*)arg);
+            pwm_set_clock_divider(ratio);
+            break;
+
+        case SET_PWM_ACT_CHANNEL:
+            ratio = *((int*)arg);
+            pwm_set_active_channel(ratio);
+            break;
+
+        default:
+            break;
+    }
+
+    return ret;
+}
+
+static rt_err_t gk_pwm_init(rt_device_t dev)
+{
+    rt_err_t ret = RT_EOK;
+
+    ret = (rt_err_t)GD_PWM_Init();
+
+    return ret;
+}
+
+int gk_pwm_probe(void *priv_data)
+{
+    rt_device_t pwm_dev;
+    int index;
+
+    for (index=0; index < PWM_MAX_CHANNEL; index++)
+    {
+        pwm_drv_table.pwm[index].id  = 0xff;
+        pwm_drv_table.pwm[index].gpio_id = 0xff;
+    }
+
+    for (index=0; index < PWM_MAX_CHANNEL; index++)
+    {
+        if (((struct pwm_driver *)priv_data)->pwm[index].gpio_id > 0)
+        {
+            pwm_drv_table.pwm[index].id  = ((struct pwm_driver *)priv_data)->pwm[index].id;
+            pwm_drv_table.pwm[index].gpio_id = ((struct pwm_driver *)priv_data)->pwm[index].gpio_id;
+        }
+    }
+
+    pwm_drv = rt_malloc(sizeof(struct gk_pwm_obj));
+    if (pwm_drv == RT_NULL)
+    {
+        rt_kprintf("ERROR: %s pwm_drv malloc failed\n", __func__);
+    }
+    rt_memset(pwm_drv, 0, sizeof(struct gk_pwm_obj));
+
+    pwm_dev = rt_malloc(sizeof(struct rt_device));
+    if (pwm_dev == RT_NULL)
+    {
+        rt_kprintf("ERROR: %s rt_device malloc failed\n", __func__);
+    }
+    rt_memset(pwm_dev, 0, sizeof(struct rt_device));
+
+    pwm_dev->user_data = &pwm_drv_table;
+    pwm_dev->open      = gk_pwm_open;
+    pwm_dev->close     = gk_pwm_close;
+    pwm_dev->control   = gk_pwm_ioctl;
+    pwm_dev->init      = gk_pwm_init;
+    pwm_dev->type      = RT_Device_Class_Miscellaneous;
+
+    rt_device_register(pwm_dev, "pwm", RT_DEVICE_FLAG_RDWR);
+
+    return 0;
+}
+
+int gk_pwm_exit(void *priv_data) { return 0; }
+struct gk_platform_driver pwm_driver_ops = {
+    .name = "pwm", .probe = gk_pwm_probe, .remove = gk_pwm_exit,
+};
+
+void rt_hw_pwm_init(void)
+{
+	gk_platform_driver_init(&pwm_driver_ops);
+}
+
+#ifdef GK_TEST_PWM
+int gk_pwm_test(void)
+{
+    rt_device_t pwm_dev;
+    struct pwm_device pwm;
+
+    pwm.duty = 50;
+    pwm.range = 100;
+    pwm.freq = 1000;
+
+    pwm_dev = rt_device_find("pwm");
+    if (!pwm_dev)
+    {
+        rt_kprintf("cann't find the pwm dev\n");
+    }
+
+    pwm_dev->init(pwm_dev);
+    pwm_dev->open(pwm_dev, 0);
+    pwm_dev->control(pwm_dev, SET_PWM_DUTY_CYCLE, &pwm);
+    pwm_dev->control(pwm_dev, ENABLE_PWM, NULL);
+
+    return 0;
+}
+#endif
+
+#ifdef RT_USING_FINSH
+#include <finsh.h>
+#ifdef GK_TEST_PWM
+FINSH_FUNCTION_EXPORT(gk_pwm_test, gk_pwm_test);
+#endif
+#endif

+ 75 - 0
bsp/gkipc/drivers/drv_pwm.h

@@ -0,0 +1,75 @@
+/*
+ * File      : drv_pwm.h
+ * This file is part of GK710X BSP for RT-Thread distribution.
+ *
+ * Copyright (c) 2017 GOKE Microelectronics Co., Ltd.
+ * All rights reserved
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *  Visit http://www.goke.com to get contact with Goke.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+
+#ifndef PWM_H_
+#define PWM_H_
+
+#include <rtthread.h>
+#include <rtdef.h>
+
+#define ENABLE_PWM (0x10)
+#define DISABLE_PWM (0x11)
+
+#define SET_PWM_DUTY_CYCLE (0x12)
+#define GET_PWM_DUTY_CYCLE (0x13)
+
+#define SET_PWM_VSYNC_MODE (0x14)
+#define GET_PWM_VSYNC_MODE (0x15)
+
+#define SET_PWM_CLOCK_DIV  (0x16)
+#define SET_PWM_ACT_CHANNEL (0x17)
+
+#define PWM_MAX_CHANNEL 8
+
+struct pwm_param_vsync_mode
+{
+    rt_uint16_t speed;
+    rt_uint32_t highLevelCnt;
+    rt_uint32_t lowLevelCnt;
+};
+
+struct pwm_device
+{
+    rt_uint32_t freq;
+    rt_uint32_t range;
+    rt_uint32_t duty;
+};
+
+struct gk_pwm_obj
+{
+    int id;
+    rt_uint32_t gpio_id;
+};
+
+struct pwm_driver
+{
+    struct gk_pwm_obj pwm[PWM_MAX_CHANNEL];
+};
+
+void rt_hw_pwm_init(void);
+
+#endif /* PWM_H_ */

+ 1684 - 0
bsp/gkipc/drivers/drv_sdio.c

@@ -0,0 +1,1684 @@
+#include <rtdef.h>
+#include <rtdevice.h>
+#include <drivers/mmcsd_core.h>
+
+#include <string.h>
+#include <gd_int.h>
+#include <gd_timer.h>
+#include <gh_sdio_all.h>
+
+#include "drv_sdio.h"
+#include "platform.h"
+
+/*
+*interrupt config
+*/
+#define SDIO_USE_DMA    (0)
+#define SDIO_INT_STATUS_EN  (1 | 1<<1 | 1<<3 | 1<<4 |1<<5 | 1<<6 | 1<<7)
+#define SDIO_INT_SIG_EN     (1 | 1<<1 | 1<<3 | 1<<4 |1<<5 | 1<<6 | 1<<7)
+
+/*config for dma*/
+/* 7 -> 512Kbyte 6->256 5->128 4->64 3->32 2->16 1->8 0->4*/
+#define SDIO_DEFAULT_BOUNDARY_SIZE    (64* 1024)//support max 512Kbyte,for memory issue,use 64kbyte
+#define SDIO_DEFAULT_BOUNDARY_ARG     (4)
+
+#define MMC_NOREP          (1<<0)        /* no response*/
+#define MMC_REP_136        (1<<1)        /* 136 bit response */
+#define MMC_REP_48         (1<<2)        /* 48 bit response */
+#define MMC_REP_48_BUSY    (1<<3)        /* card may send busy */
+#define MMC_REP_CRC        (1<<4)        /* expect valid crc */
+#define MMC_COM_INDEX_CHEC (1<<5)        /* command index check enable */
+#define MMC_DATE_PRES      (1<<6)        /* data present select */
+
+
+#define MMC_RSP_NONE  (0)
+#define MMC_RSP_R1    (MMC_REP_48|MMC_REP_CRC|MMC_COM_INDEX_CHEC)
+#define MMC_RSP_R1B   (MMC_REP_48_BUSY|MMC_REP_CRC|MMC_COM_INDEX_CHEC)
+#define MMC_RSP_R2    (MMC_REP_136|MMC_REP_CRC)
+#define MMC_RSP_R3    (MMC_REP_48)
+#define MMC_RSP_R4    (MMC_REP_48)
+#define MMC_RSP_R5    (MMC_REP_48|MMC_REP_CRC|MMC_COM_INDEX_CHEC)
+#define MMC_RSP_R6    (MMC_REP_48|MMC_REP_CRC|MMC_COM_INDEX_CHEC)
+#define MMC_RSP_R7    (MMC_REP_48)
+
+#define SDIO_IRQ_CMD_COMPLETE        0x0001
+#define SDIO_IRQ_BLOCK_GAP_EVENT     0x0002
+#define SDIO_IRQ_DMA                 0x0004
+#define SDIO_IRQ_TRANSFER_COMPLETE   0x0008
+#define SDIO_IRQ_WRITE_READY         0x0010
+#define SDIO_IRQ_CARD_INSERTED       0x0020
+#define SDIO_IRQ_READ_READY          0x0040
+#define SDIO_IRQ_CARD_REMOVED        0x0080
+#define SDIO_IRQ_CARD_INT            0x0100
+#define SDIO_ERROR_IRQ               0x8000
+
+#define MMC_STOP_TRANSMISSION    12   /* ac                      R1b         */
+
+#ifdef CODEC_710XS
+#define SDIO_SLOT_COUNT       2              /* total handle count */
+#else
+#define SDIO_SLOT_COUNT       1              /* total handle count */
+#endif
+
+#define SDIO_CMD_DEFAULT_TIMEOUT  3     /* FIXME, default 3s for one sdio cmd */
+
+static GD_HANDLE inthandleArray[SDIO_SLOT_COUNT*2];
+static struct gk_sdio *sdioInstancePtr[SDIO_SLOT_COUNT] = {RT_NULL};
+
+#if SDIO_USE_DMA
+static rt_uint8_t  dmBuf[SDIO_SLOT_COUNT][SDIO_DEFAULT_BOUNDARY_SIZE] __attribute__((aligned(32))) __attribute__ ((section(".nocache_buffer"))) = {0,};//64kbyte
+#endif
+
+static void sdio_soft_reset(rt_uint32_t index)
+{
+#ifdef CODEC_710X
+    GH_SDIO_set_Control01Reg_SoftwareResetAll(index, 1);
+    GH_SDIO_set_Control01Reg_SoftwareResetCmdLine(index, 1);
+    GH_SDIO_set_Control01Reg_SoftwareResetDatLine(index, 1);
+
+#elif defined GK7102C
+
+    GH_SDIO_set_SoftResetReg_SoftwareResetAll(index,1);
+    GH_SDIO_set_SoftResetReg_SoftwareResetCmdLine(index,1);
+    GH_SDIO_set_SoftResetReg_SoftwareResetDatLine(index,1);
+#elif defined CODEC_710XS
+    GH_SDIO_set_Control01Reg_SoftwareResetAll(index,1);
+    GH_SDIO_set_Control01Reg_SoftwareResetCmdLine(index,1);
+    GH_SDIO_set_Control01Reg_SoftwareResetDatLine(index,1);
+#endif
+}
+
+static void sdio_clock_onoff(rt_uint32_t index, rt_uint32_t on)
+{
+#ifdef CODEC_710X
+    if (on == 0)
+    {
+        GH_SDIO_set_Control01Reg_SdClkEn(index, 0);
+    }
+    else
+    {
+        GH_SDIO_set_Control01Reg_SdClkEn(index, 1);
+    }
+
+#elif defined GK7102C
+
+    if (on == 0)
+    {
+        GH_SDIO_set_ClkControlReg_SdClkEn(index, 0);
+    }
+    else
+    {
+        GH_SDIO_set_ClkControlReg_SdClkEn(index, 1);
+    }
+#elif defined CODEC_710XS
+
+    if (on == 0)
+    {
+        GH_SDIO_set_Control01Reg_SdClkEn(index, 0);
+    }
+    else
+    {
+        GH_SDIO_set_Control01Reg_SdClkEn(index, 1);
+    }
+
+#endif
+}
+
+static void sdio_set_clockdiv(rt_uint32_t index, rt_uint8_t div)
+{
+#ifdef CODEC_710X
+
+    GH_SDIO_set_Control01Reg_SdclkFreSelect(index, div);
+    GH_SDIO_set_Control01Reg_InternalClkEn(index, 1);
+
+    while(1)
+    {
+        if(GH_SDIO_get_Control01Reg_InternalClkStable(index)&0x1)
+              break;
+    }
+    sdio_clock_onoff(index, 1);
+
+#elif defined GK7102C
+    GH_SDIO_set_ClkControlReg_SdclkFreSelect(index, div);
+    GH_SDIO_set_ClkControlReg_InternalClkEn(index, 1);
+
+    while(1)
+    {
+        if(GH_SDIO_get_ClkControlReg_InternalClkStable(index)&0x1)
+              break;
+    }
+    sdio_clock_onoff(index, 1);
+
+#elif defined CODEC_710XS
+
+    GH_SDIO_set_Control01Reg_SdclkFreSelect(index, div);
+    GH_SDIO_set_Control01Reg_InternalClkEn(index, 1);
+
+    while(1)
+    {
+        if(GH_SDIO_get_Control01Reg(index)&(0x1<<16))
+              break;
+    }
+    sdio_clock_onoff(index, 1);
+
+#endif
+}
+
+static void sdio_select_voltage(rt_uint32_t index)
+{
+    rt_uint32_t caps = 0;
+    caps=GH_SDIO_get_CapReg(index);
+
+    if(caps & 0x1<<24)
+    {
+        GH_SDIO_set_Control00Reg_SdBusVoltageSelect(index, 0x7);
+        GH_SDIO_set_Control00Reg_SdBusPower(index, 1);
+    }
+    else if(caps & 0x1<<25)
+    {
+        GH_SDIO_set_Control00Reg_SdBusVoltageSelect(index, 0x6);
+        GH_SDIO_set_Control00Reg_SdBusPower(index, 1);
+    }
+    else if(caps & 0x1<<26)
+    {
+        GH_SDIO_set_Control00Reg_SdBusVoltageSelect(index, 0x5);
+        GH_SDIO_set_Control00Reg_SdBusPower(index, 1);
+    }
+
+}
+
+static void sdio_set_timeout_control(rt_uint32_t index,rt_uint8_t timeout)
+{
+#ifdef CODEC_710X
+    GH_SDIO_set_Control01Reg_DataTimeoutCounterValue(index, timeout);
+#elif defined GK7102C
+    GH_SDIO_set_SoftResetReg_DataTimeoutCounterValue(index,timeout);
+#elif defined CODEC_710XS
+    GH_SDIO_set_SoftResetReg_DataTimeoutCounterValue(index,timeout);
+#endif
+}
+
+static void sdio_set_host_ctl_speed(rt_uint32_t index, rt_uint8_t mode)
+{
+    GH_SDIO_set_Control00Reg_HostSpeedEn(index, mode);
+}
+
+static void sdio_set_host_ctl_width(rt_uint32_t index,rt_uint8_t mode)
+{
+    GH_SDIO_set_Control00Reg_DataTraWidth(index, mode);
+}
+
+static void sdio_enable_int_status(rt_uint32_t index)
+{
+#ifdef CODEC_710X
+    /*clear int*/
+    if(GH_SDIO_get_NorIntStaReg_ErrInt(index) & 0x1)
+    {
+        GH_SDIO_set_NorIntStaReg(index, GH_SDIO_get_NorIntStaReg(index));
+        GH_SDIO_set_ErrIntStaReg(index, GH_SDIO_get_ErrIntStaReg(index));
+    }
+    GH_SDIO_set_NorIntStaEnReg(index, 0x0000);
+    GH_SDIO_set_NorIntStaEnReg(index, SDIO_INT_STATUS_EN);
+    GH_SDIO_set_ErrIntStaEnReg(index, 0xffff);
+
+#elif defined GK7102C
+    if(GH_SDIO_get_NorIntStaReg_ErrInt(index) & 0x1)
+    {
+        GH_SDIO_set_ErrIntStatusReg(index, \
+            GH_SDIO_get_ErrIntStatusReg(index));
+    }
+    GH_SDIO_set_NorIntStaEnReg(index, 0x0);
+    GH_SDIO_set_ErrIntStaEnReg(index, 0x0);
+    GH_SDIO_set_NorIntStaEnReg_CmdCompleteStatusEn(index, 1);
+    GH_SDIO_set_NorIntStaEnReg_TraCompleteStatusEn(index, 1);
+    GH_SDIO_set_NorIntStaEnReg_DmaIntStatusEn(index, 1);
+    GH_SDIO_set_NorIntStaEnReg_BufWReadyStatusEn(index, 1);
+    GH_SDIO_set_NorIntStaEnReg_BufRReadyStatusEn(index, 1);
+    GH_SDIO_set_NorIntStaEnReg_CardInsertionStatusEn(index, 1);
+    GH_SDIO_set_NorIntStaEnReg_CardRemStatusEn(index, 1);
+    GH_SDIO_set_ErrIntStaEnReg(index, 0xffff);
+
+#elif defined CODEC_710XS
+
+    if(GH_SDIO_get_ErrIntStaEnNorIntStaReg_ErrInt(index) & 0x1)
+    {
+        GH_SDIO_set_ErrIntStaEnNorIntStaReg(index, \
+        GH_SDIO_get_ErrIntStaEnNorIntStaReg(index));
+    }
+    GH_SDIO_set_BlkSizeNorIntStaEnReg(index, \
+    GH_SDIO_get_BlkSizeNorIntStaEnReg(index)&0x0000ffff);
+    GH_SDIO_set_BlkSizeNorIntStaEnReg(index, \
+    (GH_SDIO_get_BlkSizeNorIntStaEnReg(index)&0x0000ffff)|(SDIO_INT_STATUS_EN<<16));
+    GH_SDIO_set_ErrIntStaEnNorIntStaReg(index, \
+    GH_SDIO_get_ErrIntStaEnNorIntStaReg(index)|0x0000ffff);
+#endif
+}
+
+static void sdio_enable_intsig(rt_uint32_t index)
+{
+#ifdef CODEC_710X
+    GH_SDIO_set_NorIntSigEnReg(index, 0x0000);
+    GH_SDIO_set_NorIntSigEnReg(index, SDIO_INT_SIG_EN);
+    GH_SDIO_set_ErrIntSigEnReg(index, 0xffff);
+
+#elif defined GK7102C
+    GH_SDIO_set_NorIntSigEnReg(index, 0x0);
+    GH_SDIO_set_ErrIntSigEnReg(index, 0x0);
+    GH_SDIO_set_NorIntSigEnReg_CmdCompleteSigEn(index, 1);
+    GH_SDIO_set_NorIntSigEnReg_TraCompleteSigEn(index, 1);
+    GH_SDIO_set_NorIntSigEnReg_DmaIntSigEn(index, 1);
+    GH_SDIO_set_NorIntSigEnReg_BufWReadySigEn(index, 1);
+    GH_SDIO_set_NorIntSigEnReg_BufRReadySigEn(index, 1);
+    GH_SDIO_set_NorIntSigEnReg_CardInsertionSigEn(index, 1);
+    GH_SDIO_set_NorIntSigEnReg_CardRemSigEn(index, 1);
+    GH_SDIO_set_ErrIntSigEnReg(index, 0xffff);
+#elif defined CODEC_710XS
+    GH_SDIO_set_TranModeNorIntSigEnReg(index, \
+    GH_SDIO_get_TranModeNorIntSigEnReg(index)&0x0000ffff);
+    GH_SDIO_set_TranModeNorIntSigEnReg(index, \
+    (GH_SDIO_get_TranModeNorIntSigEnReg(index)&0x0000ffff)|(SDIO_INT_SIG_EN<<16));
+    GH_SDIO_set_ErrIntSigEnBlkCouReg(index, \
+    GH_SDIO_get_ErrIntSigEnBlkCouReg(index)|0x0000ffff);
+#endif
+}
+
+
+static void sdio_set_blksize_reg(rt_uint32_t index, U16 boundary,U16 blksize)
+{
+#ifdef CODEC_710X
+    GH_SDIO_set_BlkSizeReg_HostSdmaBufSize(index, boundary);
+    GH_SDIO_set_BlkSizeReg_TraBlkSize(index, blksize);
+#elif defined GK7102C
+    GH_SDIO_set_BlkSizeReg_HostSdmaBufSize(index, boundary);
+    GH_SDIO_set_BlkSizeReg_TraBlkSize(index, blksize);
+#elif defined CODEC_710XS
+    GH_SDIO_set_BlkSizeNorIntStaEnReg_HostSdmaBufSize(index, boundary);
+    GH_SDIO_set_BlkSizeNorIntStaEnReg_TraBlkSize(index, blksize);
+#endif
+}
+
+static void sdio_set_blkcnt_reg(rt_uint32_t index, U16  blkcnt)
+{
+#ifdef CODEC_710X
+    GH_SDIO_set_BlkCouReg_BlkCountForCurTra(index, blkcnt);
+#elif defined GK7102C
+    GH_SDIO_set_BlkCouReg_BlkCountForCurTra(index, blkcnt);
+#elif defined CODEC_710XS
+    GH_SDIO_set_ErrIntSigEnBlkCouReg_BlkCountForCurTra(index, blkcnt);
+#endif
+}
+
+static void sdio_set_arg_reg (rt_uint32_t index, rt_uint32_t arg)
+{
+    GH_SDIO_set_ArgReg(index, arg);
+}
+
+static rt_uint32_t sdio_set_tramode_reg (rt_uint32_t index, rt_uint32_t  multblk, rt_uint32_t direction, rt_uint32_t  autocmd12en,
+    rt_uint32_t  blkcnten, rt_uint32_t  dmaen)
+{
+#ifdef CODEC_710X
+    rt_uint32_t modereg=GH_SDIO_get_TranModeReg(index);
+    modereg=(modereg & ~0xffff) | (direction << 5)| (multblk << 4) | (dmaen << 2) | (autocmd12en << 1) | (blkcnten << 0) ;
+    return modereg<<16;
+
+#elif defined GK7102C
+
+    GH_SDIO_TRANMODEREG_S tansModRegVal;
+    rt_uint32_t retVal;
+
+    tansModRegVal.bitc.msblkselect = multblk;
+    tansModRegVal.bitc.datatradirselect = direction;
+    tansModRegVal.bitc.dmaen = dmaen;
+    tansModRegVal.bitc.autocmd12en = autocmd12en;
+    tansModRegVal.bitc.blkcounten = blkcnten;
+
+    retVal = ((U32)tansModRegVal.all) << 16;
+    return retVal;
+
+#elif defined CODEC_710XS
+    rt_uint32_t modereg=GH_SDIO_get_TranModeNorIntSigEnReg(index);
+    modereg=(modereg & ~0xffff) | (multblk << 4) | (direction << 5)| (dmaen << 2) | (autocmd12en << 1) | (blkcnten << 0) ;
+    return modereg<<16;
+
+#endif
+}
+
+static void sdio_set_system_address_reg(rt_uint32_t index,rt_uint32_t addr)
+{
+    GH_SDIO_set_SysAddrReg(index, addr);
+}
+static void sdio_set_hostctl8BitMode(rt_uint8_t channel,rt_uint8_t mode)
+{
+#ifdef CODEC_710X
+    GH_SDIO_set_Control00Reg_Sd8BitMode(channel,mode);
+#elif defined GK7102C
+
+#elif defined CODEC_710XS
+
+#endif
+}
+
+static void sdio_reset(rt_uint8_t index)
+{
+    sdio_soft_reset(index);
+    sdio_clock_onoff(index, 0);
+#ifdef CODEC_710X
+    sdio_set_clockdiv(index, 1);
+#elif defined GK7102C
+    sdio_set_clockdiv(index, 0x40);
+#elif defined CODEC_710XS
+    sdio_set_clockdiv(index, 0x02);
+#endif
+    sdio_select_voltage(index);
+    sdio_set_timeout_control(index, 0xe);
+    sdio_set_host_ctl_speed(index, 0);
+    sdio_set_host_ctl_width(index, 0);
+    /*clear interrupt status*/
+
+#ifdef CODEC_710X
+    GH_SDIO_set_NorIntStaReg(index, GH_SDIO_get_NorIntStaReg(index));
+    GH_SDIO_set_ErrIntStaReg(index, GH_SDIO_get_ErrIntStaReg(index));
+#elif defined GK7102C
+    GH_SDIO_set_NorIntStaReg(index, GH_SDIO_get_NorIntStaReg(index));
+    GH_SDIO_set_ErrIntStatusReg(index,  GH_SDIO_get_ErrIntStatusReg(index));
+#elif defined CODEC_710XS
+    GH_SDIO_set_ErrIntStaEnNorIntStaReg(index, GH_SDIO_get_ErrIntStaEnNorIntStaReg(index));
+#endif
+    /*card remove*/
+    sdio_enable_int_status(index);
+    sdio_enable_intsig(index);
+}
+
+static void sdio_power_on(rt_uint32_t index)
+{
+    /* Bus power on */
+    GH_SDIO_set_Control00Reg_SdBusPower(index, 1);
+
+    /* Enable SDIO interrupt */
+    sdio_enable_int_status(index);
+    sdio_enable_intsig(index);
+
+#ifdef CODEC_710X
+    GH_SDIO_set_NorIntStaEnReg_CardIntStatusEn(index, 1);
+    GH_SDIO_set_NorIntSigEnReg_CardIntSigEN(index, 1);
+#elif GK7102C
+    GH_SDIO_set_NorIntStaEnReg_CardIntStatusEn(index, 1);
+    GH_SDIO_set_NorIntSigEnReg_CardIntSigEN(index, 1);
+#elif defined(CODEC_710XS)
+    GH_SDIO_set_TranModeNorIntSigEnReg_CardIntSigEN(index, 1);
+    GH_SDIO_set_BlkSizeNorIntStaEnReg_CardIntStatusEn(index, 1);
+#endif
+
+}
+
+
+static void sdio_power_off(rt_uint32_t index)
+{
+    /* Disable SDIO interrupt */
+
+#ifdef CODEC_710X
+    GH_SDIO_set_NorIntStaReg(index, 0);
+    GH_SDIO_set_ErrIntStaReg(index, 0);
+#elif defined GK7102C
+    GH_SDIO_set_NorIntStaReg(index, 0);
+    GH_SDIO_set_ErrIntStatusReg(index,  0);
+#elif defined CODEC_710XS
+    GH_SDIO_set_ErrIntStaEnNorIntStaReg(index, 0);
+#endif
+
+    /* Bus power off */
+    GH_SDIO_set_Control00Reg_SdBusPower(index, 0);
+}
+
+static void sdio_set_dma(rt_uint32_t index, struct rt_mmcsd_data *data,rt_uint8_t isDmaEnd)
+{
+#if SDIO_USE_DMA
+
+    rt_uint32_t total_len = data->blks * data->blksize;
+    rt_int32_t dma_len = 0,left_len = 0;
+    rt_uint32_t offset = 0;
+    rt_uint32_t read_len = 0;
+
+    if(!data)
+        return;
+
+    offset = data->bytes_xfered;
+
+    read_len = ((total_len - data->bytes_xfered) > SDIO_DEFAULT_BOUNDARY_SIZE)?\
+            SDIO_DEFAULT_BOUNDARY_SIZE:(total_len - data->bytes_xfered);
+
+    left_len = total_len - data->bytes_xfered;
+
+    if(left_len <= 0 && (data->flags & DATA_DIR_WRITE))
+        return;
+
+    dma_len = (left_len > SDIO_DEFAULT_BOUNDARY_SIZE)?SDIO_DEFAULT_BOUNDARY_SIZE:left_len;
+
+    if(data->flags & DATA_DIR_WRITE)
+    {
+        rt_memcpy((void *)&dmBuf[index][0],(void *)((rt_uint32_t)data->buf + offset),dma_len);
+        sdio_set_system_address_reg(index,(rt_uint32_t)&dmBuf[index][0]);
+
+        data->bytes_xfered += dma_len;
+    }
+    else if(data->flags & DATA_DIR_READ)
+    {
+        if(isDmaEnd)
+        {
+            rt_memcpy((void *)((rt_uint8_t *)data->buf + offset),(void *)&dmBuf[index][0],read_len);
+            data->bytes_xfered += dma_len;
+        }
+
+        if(dma_len <= 0)
+            return;
+
+        //rt_memset((void *)&dmBuf[index][0],0x0,SDIO_DEFAULT_BOUNDARY_SIZE);
+        sdio_set_system_address_reg(index,(rt_uint32_t)&dmBuf[index][0]);
+    }
+
+#endif
+
+}
+static void sdio_isr0(void)
+{
+    rt_int32_t   ret = RT_EOK;
+    rt_uint32_t  index = 0;
+    rt_uint32_t  bufferpos= 0,*pdata = NULL;
+#ifdef CODEC_710X
+    rt_uint32_t  irq_status_reg =(GH_SDIO_get_NorIntStaReg(index)| GH_SDIO_get_ErrIntStaReg(index)<<16);
+#elif defined GK7102C
+    rt_uint32_t irq_status_reg=(GH_SDIO_get_NorIntStaReg(index) | GH_SDIO_get_ErrIntStatusReg(index)<<16);
+#elif defined CODEC_710XS
+    rt_uint32_t  irq_status_reg=(((GH_SDIO_get_ErrIntStaEnNorIntStaReg(index)&0xffff0000)>>16) | \
+    ((GH_SDIO_get_ErrIntStatusCommondReg(index)&0x0000ffff)<<16));
+#endif
+
+    //rt_kprintf("%s, irq_status_reg = 0x%x\n", __func__,irq_status_reg);
+    if( irq_status_reg & SDIO_ERROR_IRQ )
+    {
+
+#ifdef CODEC_710X
+        GH_SDIO_set_NorIntStaReg(index,GH_SDIO_get_NorIntStaReg(index));
+        GH_SDIO_set_ErrIntStaReg(index,GH_SDIO_get_ErrIntStaReg(index));
+        GH_SDIO_set_Control01Reg_SoftwareResetDatLine(index,1);
+        GH_SDIO_set_Control01Reg_SoftwareResetCmdLine(index,1);
+#elif defined GK7102C
+        GH_SDIO_set_NorIntStaReg(index,GH_SDIO_get_NorIntStaReg(index));
+        GH_SDIO_set_ErrIntStatusReg(index,GH_SDIO_get_ErrIntStatusReg(index));
+        GH_SDIO_set_SoftResetReg_SoftwareResetDatLine(index,1);
+        GH_SDIO_set_SoftResetReg_SoftwareResetCmdLine(index,1);
+#elif defined CODEC_710XS
+        GH_SDIO_set_ErrIntStaEnNorIntStaReg(index,GH_SDIO_get_ErrIntStaEnNorIntStaReg(index));
+        *(volatile rt_int16_t *)(0x90000000+0x14) = *(volatile U16 *)(0x90000000+0x14);
+        GH_SDIO_set_Control01Reg_SoftwareResetDatLine(index,1);
+        GH_SDIO_set_Control01Reg_SoftwareResetCmdLine(index,1);
+#endif
+        rt_kprintf("%s,error irq\n",__FUNCTION__);
+        ret = RT_ERROR;
+
+        goto EXIT;
+
+    }
+
+    if( irq_status_reg & SDIO_IRQ_CMD_COMPLETE )
+    {
+
+#ifdef CODEC_710X
+        if(GH_SDIO_get_CmdReg_RepTypeSelect(index)==1)
+#elif defined GK7102C
+        if(GH_SDIO_get_CommondReg_RepTypeSelect(index)==1)
+#elif defined CODEC_710XS
+        if(GH_SDIO_get_ErrIntStatusCommondReg_RepTypeSelect(index)==1)
+#endif
+        {
+            sdioInstancePtr[index]->cmd->resp[0] = GH_SDIO_get_Resp3Reg(index)<<8 | (GH_SDIO_get_Resp2Reg(index) & 0xff000000)>>24;
+            sdioInstancePtr[index]->cmd->resp[1] = GH_SDIO_get_Resp2Reg(index)<<8 | (GH_SDIO_get_Resp1Reg(index) & 0xff000000)>>24;
+            sdioInstancePtr[index]->cmd->resp[2] = GH_SDIO_get_Resp1Reg(index)<<8 | (GH_SDIO_get_Resp0Reg(index) & 0xff000000)>>24;
+            sdioInstancePtr[index]->cmd->resp[3] = GH_SDIO_get_Resp0Reg(index)<<8;
+        }
+        else
+            sdioInstancePtr[index]->cmd->resp[0] = GH_SDIO_get_Resp0Reg(index);
+
+#ifdef CODEC_710X
+        GH_SDIO_set_NorIntStaReg(index, SDIO_IRQ_CMD_COMPLETE);
+#elif defined GK7102C
+        GH_SDIO_set_NorIntStaReg(index, SDIO_IRQ_CMD_COMPLETE);
+#elif defined CODEC_710XS
+        GH_SDIO_set_ErrIntStaEnNorIntStaReg(index, \
+            (GH_SDIO_get_ErrIntStaEnNorIntStaReg(index)&0x0000ffff)|(SDIO_IRQ_CMD_COMPLETE<<16));
+
+#endif
+
+        if(!sdioInstancePtr[index]->cmd->data)
+        {
+            sdioInstancePtr[index]->cmd->err = RT_EOK;
+            rt_completion_done(&(sdioInstancePtr[index]->completion));
+        }
+
+    }
+
+    if( irq_status_reg & SDIO_IRQ_CARD_REMOVED )
+    {
+        sdio_reset(index);
+
+#ifdef CODEC_710X
+        GH_SDIO_set_NorIntStaReg(index, SDIO_IRQ_CARD_REMOVED);
+#elif defined GK7102C
+        GH_SDIO_set_NorIntStaReg(index, SDIO_IRQ_CARD_REMOVED);
+#elif defined CODEC_710XS
+    GH_SDIO_set_ErrIntStaEnNorIntStaReg(index, \
+        (GH_SDIO_get_ErrIntStaEnNorIntStaReg(index)&0x0000ffff)|SDIO_IRQ_CARD_REMOVED<<16);
+#endif
+        if(sdioInstancePtr[index]->cmd)
+        {
+            sdioInstancePtr[index]->cmd->err = ret;
+            if(sdioInstancePtr[index]->cmd->data)
+                sdioInstancePtr[index]->cmd->data->err = ret;
+        }
+
+        rt_completion_done(&(sdioInstancePtr[index]->completion));
+        mmcsd_change(sdioInstancePtr[index]->host);
+
+    }
+    else if( irq_status_reg & SDIO_IRQ_CARD_INSERTED )
+    {
+#ifdef CODEC_710X
+        GH_SDIO_set_NorIntStaReg(index, SDIO_IRQ_CARD_INSERTED);
+#elif defined GK7102C
+        GH_SDIO_set_NorIntStaReg(index, SDIO_IRQ_CARD_INSERTED);
+#elif defined CODEC_710XS
+        GH_SDIO_set_ErrIntStaEnNorIntStaReg(index, \
+            (GH_SDIO_get_ErrIntStaEnNorIntStaReg(index)&0x0000ffff)|(SDIO_IRQ_CARD_INSERTED<<16));
+
+#endif
+        mmcsd_change(sdioInstancePtr[index]->host);
+    }
+
+    if( irq_status_reg & SDIO_IRQ_READ_READY )
+    {
+
+#ifdef CODEC_710X
+        if (!(GH_SDIO_get_PresentStateReg(index) & 0x1<<11))
+#elif defined GK7102C
+        if (!(GH_SDIO_get_PresentStateReg_BufREn(index)))
+#elif defined CODEC_710XS
+        if (!(GH_SDIO_get_PresentStateReg(index) & 0x1<<11))
+#endif
+        {
+            ret = RT_EBUSY;
+            goto EXIT;
+        }
+        else
+        {
+#ifdef CODEC_710X
+            GH_SDIO_set_NorIntStaReg(index, SDIO_IRQ_READ_READY);
+#elif defined GK7102C
+            GH_SDIO_set_NorIntStaReg(index,SDIO_IRQ_READ_READY);
+#elif defined CODEC_710XS
+            GH_SDIO_set_ErrIntStaEnNorIntStaReg(index, \
+            (GH_SDIO_get_ErrIntStaEnNorIntStaReg(index)&0x0000ffff)|(SDIO_IRQ_READ_READY<<16));
+
+#endif
+
+            if(!sdioInstancePtr[index]->cmd)
+                return;
+
+            if(!sdioInstancePtr[index]->cmd->data)
+                return;
+
+            if(!sdioInstancePtr[index]->cmd->data->buf)
+                return;
+
+            pdata = sdioInstancePtr[index]->cmd->data->buf + sdioInstancePtr[index]->cmd->data->bytes_xfered/4;
+            while( bufferpos < sdioInstancePtr[index]->cmd->data->blksize)
+            {
+                *pdata++ = GH_SDIO_get_BufferDataPortReg(index);
+                bufferpos += 4;
+                sdioInstancePtr[index]->cmd->data->bytes_xfered += 4;
+            }
+
+        }
+
+    }
+
+    if( irq_status_reg & SDIO_IRQ_WRITE_READY )
+    {
+
+#ifdef CODEC_710X
+        if (!(GH_SDIO_get_PresentStateReg(index) & 0x1<<10))
+#elif defined GK7102C
+        if (!(GH_SDIO_get_PresentStateReg_BufWEn(index)))
+#elif defined CODEC_710XS
+        if (!(GH_SDIO_get_PresentStateReg(index) & 0x1<<10))
+#endif
+        {
+            ret = RT_EBUSY;
+            goto EXIT;
+        }
+        else
+        {
+#ifdef CODEC_710X
+            GH_SDIO_set_NorIntStaReg(index, SDIO_IRQ_WRITE_READY);
+#elif defined GK7102C
+            GH_SDIO_set_NorIntStaReg(index, SDIO_IRQ_WRITE_READY);//|(SDIO_IRQ_WRITE_READY<<16));
+#elif defined CODEC_710XS
+            GH_SDIO_set_ErrIntStaEnNorIntStaReg(index, \
+                (GH_SDIO_get_ErrIntStaEnNorIntStaReg(index)&0x0000ffff)|(SDIO_IRQ_WRITE_READY<<16));//|(SDIO_IRQ_WRITE_READY<<16));
+
+#endif
+            if(!sdioInstancePtr[index]->cmd)
+                return;
+
+            if(!sdioInstancePtr[index]->cmd->data)
+                return;
+
+            if(!sdioInstancePtr[index]->cmd->data->buf)
+                return;
+
+            pdata = sdioInstancePtr[index]->cmd->data->buf + sdioInstancePtr[index]->cmd->data->bytes_xfered/4;
+            while( bufferpos < sdioInstancePtr[index]->cmd->data->blksize )
+            {
+                GH_SDIO_set_BufferDataPortReg(index, *pdata++);
+                bufferpos += 4;
+                sdioInstancePtr[index]->cmd->data->bytes_xfered += 4;
+            }
+
+        }
+    }
+
+    if(irq_status_reg & SDIO_IRQ_DMA)//FIXME,need check
+    {
+#ifdef CODEC_710X
+        GH_SDIO_set_NorIntStaReg(index, SDIO_IRQ_DMA);
+#elif defined GK7102C
+        GH_SDIO_set_NorIntStaReg(index, SDIO_IRQ_DMA);
+#elif defined CODEC_710XS
+        GH_SDIO_set_ErrIntStaEnNorIntStaReg(index, \
+            (GH_SDIO_get_ErrIntStaEnNorIntStaReg(index)&0x0000ffff)|(SDIO_IRQ_DMA<<16));
+#endif
+
+        if(!sdioInstancePtr[index]->cmd)
+            return;
+
+        if(!sdioInstancePtr[index]->cmd->data)
+            return;
+
+        if(!sdioInstancePtr[index]->cmd->data->buf)
+            return;
+
+        sdio_set_dma(index,sdioInstancePtr[index]->cmd->data,1);
+
+    }
+
+    if( irq_status_reg & SDIO_IRQ_TRANSFER_COMPLETE )
+    {
+#ifdef CODEC_710X
+        GH_SDIO_set_NorIntStaReg(index, SDIO_IRQ_TRANSFER_COMPLETE);
+#elif defined GK7102C
+        GH_SDIO_set_NorIntStaReg(index, SDIO_IRQ_TRANSFER_COMPLETE);
+#elif defined CODEC_710XS
+        GH_SDIO_set_ErrIntStaEnNorIntStaReg(index, \
+            (GH_SDIO_get_ErrIntStaEnNorIntStaReg(index)&0x0000ffff)|(SDIO_IRQ_TRANSFER_COMPLETE<<16));
+#endif
+        ret = RT_EOK;
+
+        if(!sdioInstancePtr[index]->cmd)
+            goto EXIT;
+
+        if(!sdioInstancePtr[index]->cmd->data)
+            goto EXIT;
+
+        if(!sdioInstancePtr[index]->cmd->data->buf)
+            goto EXIT;
+
+        if(sdioInstancePtr[index]->cmd->data->flags & DATA_DIR_READ)
+            sdio_set_dma(index,sdioInstancePtr[index]->cmd->data,1);
+
+        goto EXIT;
+    }
+
+    if( irq_status_reg & SDIO_IRQ_CARD_INT )
+    {
+        do
+        {
+            if(!sdioInstancePtr[index])
+                goto CASE2;
+
+            if(!sdioInstancePtr[index]->host)
+                goto CASE2;
+
+            if(!sdioInstancePtr[index]->host->sdio_irq_sem)
+                goto CASE2;
+
+        CASE1:
+            sdio_irq_wakeup(sdioInstancePtr[index]->host);
+            break;
+
+        CASE2:
+#ifdef CODEC_710X
+            GH_SDIO_set_NorIntStaEnReg_CardIntStatusEn(index, 0);
+            GH_SDIO_set_NorIntSigEnReg_CardIntSigEN(index, 0);
+#elif GK7102C
+            GH_SDIO_set_NorIntStaEnReg_CardIntStatusEn(index, 0);
+            GH_SDIO_set_NorIntSigEnReg_CardIntSigEN(index, 0);
+#elif defined(CODEC_710XS)
+            GH_SDIO_set_TranModeNorIntSigEnReg_CardIntSigEN(index, 0);
+            GH_SDIO_set_BlkSizeNorIntStaEnReg_CardIntStatusEn(index, 0);
+#endif
+
+        }while(0);
+
+    }
+
+    return;
+
+EXIT:
+
+    if(sdioInstancePtr[index]->cmd)
+    {
+        sdioInstancePtr[index]->cmd->err = ret;
+        if(sdioInstancePtr[index]->cmd->data)
+            sdioInstancePtr[index]->cmd->data->err = ret;
+    }
+
+    rt_completion_done(&(sdioInstancePtr[index]->completion));
+}
+
+#ifdef CODEC_710X
+
+static void sdio_isr1(void)
+{
+
+}
+
+#else
+static void sdio_isr1(void)
+{
+    rt_int32_t   ret = RT_EOK;
+    rt_uint8_t   index = 1;
+    rt_uint32_t  bufferpos= 0;
+    rt_uint32_t  *pdata;
+
+#ifdef GK7102C
+    rt_uint32_t irq_status_reg=(GH_SDIO_get_NorIntStaReg(index) | \
+        GH_SDIO_get_ErrIntStatusReg(index)<<16);
+#else
+    rt_uint32_t  irq_status_reg=(((GH_SDIO_get_ErrIntStaEnNorIntStaReg(index)&0xffff0000)>>16) | \
+        ((GH_SDIO_get_ErrIntStatusCommondReg(index)&0x0000ffff)<<16));
+
+#endif
+
+    //rt_kprintf("%s, irq_status_reg = 0x%x\n", __func__,irq_status_reg);
+
+    if( irq_status_reg & SDIO_ERROR_IRQ )
+    {
+#ifdef GK7102C
+        GH_SDIO_set_NorIntStaReg(index,GH_SDIO_get_NorIntStaReg(index));
+        GH_SDIO_set_ErrIntStatusReg(index,GH_SDIO_get_ErrIntStatusReg(index));
+        GH_SDIO_set_SoftResetReg_SoftwareResetDatLine(index,1);
+        GH_SDIO_set_SoftResetReg_SoftwareResetCmdLine(index,1);
+#else
+        GH_SDIO_set_ErrIntStaEnNorIntStaReg(index,GH_SDIO_get_ErrIntStaEnNorIntStaReg(index));
+        *(volatile U16 *)(0x90010000+0x14) = *(volatile U16 *)(0x90010000+0x14);
+        GH_SDIO_set_Control01Reg_SoftwareResetDatLine(index,1);
+        GH_SDIO_set_Control01Reg_SoftwareResetCmdLine(index,1);
+
+#endif
+        ret = RT_ERROR;
+
+        goto EXIT;
+
+    }
+
+    if( irq_status_reg & SDIO_IRQ_CMD_COMPLETE )
+    {
+#ifdef GK7102C
+        if(GH_SDIO_get_CommondReg_RepTypeSelect(index)==1)
+#else
+        if(GH_SDIO_get_ErrIntStatusCommondReg_RepTypeSelect(index)==1)
+#endif
+        {
+            sdioInstancePtr[index]->cmd->resp[0] = GH_SDIO_get_Resp3Reg(index)<<8 | (GH_SDIO_get_Resp2Reg(index) & 0xff000000)>>24;
+            sdioInstancePtr[index]->cmd->resp[1] = GH_SDIO_get_Resp2Reg(index)<<8 | (GH_SDIO_get_Resp1Reg(index) & 0xff000000)>>24;
+            sdioInstancePtr[index]->cmd->resp[2] = GH_SDIO_get_Resp1Reg(index)<<8 | (GH_SDIO_get_Resp0Reg(index) & 0xff000000)>>24;
+            sdioInstancePtr[index]->cmd->resp[3] = GH_SDIO_get_Resp0Reg(index)<<8;
+        }
+        else
+            sdioInstancePtr[index]->cmd->resp[0] = GH_SDIO_get_Resp0Reg(index);
+#ifdef GK7102C
+        GH_SDIO_set_NorIntStaReg(index, SDIO_IRQ_CMD_COMPLETE);
+#else
+        GH_SDIO_set_ErrIntStaEnNorIntStaReg(index, \
+            (GH_SDIO_get_ErrIntStaEnNorIntStaReg(index)&0x0000ffff)|(SDIO_IRQ_CMD_COMPLETE<<16));
+
+#endif
+        if(!sdioInstancePtr[index]->cmd->data)
+        {
+            sdioInstancePtr[index]->cmd->err = RT_EOK;
+            rt_completion_done(&(sdioInstancePtr[index]->completion));
+        }
+
+    }
+
+    if( irq_status_reg & SDIO_IRQ_CARD_REMOVED )
+    {
+        sdio_reset(index);
+
+#ifdef GK7102C
+        GH_SDIO_set_NorIntStaReg(index, SDIO_IRQ_CARD_REMOVED);
+#else
+        GH_SDIO_set_ErrIntStaEnNorIntStaReg(index, \
+            (GH_SDIO_get_ErrIntStaEnNorIntStaReg(index)&0x0000ffff)|SDIO_IRQ_CARD_REMOVED<<16);
+
+#endif
+        if(sdioInstancePtr[index]->cmd)
+        {
+            sdioInstancePtr[index]->cmd->err = ret;
+            if(sdioInstancePtr[index]->cmd->data)
+                sdioInstancePtr[index]->cmd->data->err = ret;
+        }
+
+        rt_completion_done(&(sdioInstancePtr[index]->completion));
+        mmcsd_change(sdioInstancePtr[index]->host);
+    }
+    else if( irq_status_reg & SDIO_IRQ_CARD_INSERTED )
+    {
+#ifdef GK7102C
+        GH_SDIO_set_NorIntStaReg(index, SDIO_IRQ_CARD_INSERTED);
+#else
+        GH_SDIO_set_ErrIntStaEnNorIntStaReg(index, \
+            (GH_SDIO_get_ErrIntStaEnNorIntStaReg(index)&0x0000ffff)|(SDIO_IRQ_CARD_INSERTED<<16));
+
+#endif
+
+        mmcsd_change(sdioInstancePtr[index]->host);
+    }
+
+    if( irq_status_reg & SDIO_IRQ_READ_READY )
+    {
+#ifdef GK7102C
+        if (!(GH_SDIO_get_PresentStateReg_BufREn(index)))
+#else
+        if (!(GH_SDIO_get_PresentStateReg(index) & 0x1<<11))
+#endif
+        {
+            ret = RT_EBUSY;
+
+            goto EXIT;
+        }
+        else
+        {
+#ifdef GK7102C
+            GH_SDIO_set_NorIntStaReg(index,SDIO_IRQ_READ_READY);
+#else
+            GH_SDIO_set_ErrIntStaEnNorIntStaReg(index, \
+                (GH_SDIO_get_ErrIntStaEnNorIntStaReg(index)&0x0000ffff)|(SDIO_IRQ_READ_READY<<16));
+#endif
+            if(!sdioInstancePtr[index]->cmd)
+                return;
+
+            if(!sdioInstancePtr[index]->cmd->data)
+                return;
+
+            if(!sdioInstancePtr[index]->cmd->data->buf)
+                return;
+
+            pdata = sdioInstancePtr[index]->cmd->data->buf + sdioInstancePtr[index]->cmd->data->bytes_xfered/4;
+            while( bufferpos < sdioInstancePtr[index]->cmd->data->blksize)
+            {
+                *pdata++ = GH_SDIO_get_BufferDataPortReg(index);
+                bufferpos += 4;
+                sdioInstancePtr[index]->cmd->data->bytes_xfered += 4;
+            }
+        }
+
+    }
+
+    if( irq_status_reg & SDIO_IRQ_WRITE_READY )
+    {
+#ifdef GK7102C
+        if (!(GH_SDIO_get_PresentStateReg_BufWEn(index)))
+#else
+        if (!(GH_SDIO_get_PresentStateReg(index) & 0x1<<10))
+#endif
+        {
+            ret = RT_EBUSY;
+
+            goto EXIT;
+        }
+        else
+        {
+#ifdef GK7102C
+            GH_SDIO_set_NorIntStaReg(index, SDIO_IRQ_WRITE_READY);//|(SDIO_IRQ_WRITE_READY<<16));
+#else
+            GH_SDIO_set_ErrIntStaEnNorIntStaReg(index, \
+                (GH_SDIO_get_ErrIntStaEnNorIntStaReg(index)&0x0000ffff)|(SDIO_IRQ_WRITE_READY<<16));//|(SDIO_IRQ_WRITE_READY<<16));
+
+#endif
+            if(!sdioInstancePtr[index]->cmd)
+                return;
+
+            if(!sdioInstancePtr[index]->cmd->data)
+                return;
+
+            if(!sdioInstancePtr[index]->cmd->data->buf)
+                return;
+
+            pdata = sdioInstancePtr[index]->cmd->data->buf + sdioInstancePtr[index]->cmd->data->bytes_xfered/4;
+            while( bufferpos < sdioInstancePtr[index]->cmd->data->blksize)
+            {
+                GH_SDIO_set_BufferDataPortReg(index, *pdata++);
+                bufferpos += 4;
+                sdioInstancePtr[index]->cmd->data->bytes_xfered += 4;
+            }
+
+        }
+    }
+
+    if(irq_status_reg & SDIO_IRQ_DMA)//FIXME,need check
+    {
+#ifdef GK7102C
+        GH_SDIO_set_NorIntStaReg(index, SDIO_IRQ_DMA);
+#else
+        GH_SDIO_set_ErrIntStaEnNorIntStaReg(index, \
+            (GH_SDIO_get_ErrIntStaEnNorIntStaReg(index)&0x0000ffff)|(SDIO_IRQ_DMA<<16));
+#endif
+        if(!sdioInstancePtr[index]->cmd)
+            return;
+
+        if(!sdioInstancePtr[index]->cmd->data)
+            return;
+
+        if(!sdioInstancePtr[index]->cmd->data->buf)
+            return;
+
+        sdio_set_dma(index,sdioInstancePtr[index]->cmd->data,1);
+    }
+
+    if( irq_status_reg & SDIO_IRQ_TRANSFER_COMPLETE )
+    {
+#ifdef GK7102C
+        GH_SDIO_set_NorIntStaReg(index, SDIO_IRQ_TRANSFER_COMPLETE);
+#else
+        GH_SDIO_set_ErrIntStaEnNorIntStaReg(index, \
+            (GH_SDIO_get_ErrIntStaEnNorIntStaReg(index)&0x0000ffff)|(SDIO_IRQ_TRANSFER_COMPLETE<<16));
+#endif
+        ret = RT_EOK;
+
+        if(!sdioInstancePtr[index]->cmd)
+            goto EXIT;
+
+        if(!sdioInstancePtr[index]->cmd->data)
+            goto EXIT;
+
+        if(!sdioInstancePtr[index]->cmd->data->buf)
+            goto EXIT;
+
+        if(sdioInstancePtr[index]->cmd->data->flags & DATA_DIR_READ)
+            sdio_set_dma(index,sdioInstancePtr[index]->cmd->data,1);
+
+        goto EXIT;
+    }
+
+    if( irq_status_reg & SDIO_IRQ_CARD_INT )
+    {
+        do
+        {
+            if(!sdioInstancePtr[index])
+                goto CASE2;
+
+            if(!sdioInstancePtr[index]->host)
+                goto CASE2;
+
+            if(!sdioInstancePtr[index]->host->sdio_irq_sem)
+                goto CASE2;
+
+        CASE1:
+            sdio_irq_wakeup(sdioInstancePtr[index]->host);
+            break;
+
+        CASE2:
+#ifdef CODEC_710X
+            GH_SDIO_set_NorIntStaEnReg_CardIntStatusEn(index, 0);
+            GH_SDIO_set_NorIntSigEnReg_CardIntSigEN(index, 0);
+#elif GK7102C
+            GH_SDIO_set_NorIntStaEnReg_CardIntStatusEn(index, 0);
+            GH_SDIO_set_NorIntSigEnReg_CardIntSigEN(index, 0);
+#elif defined(CODEC_710XS)
+            GH_SDIO_set_TranModeNorIntSigEnReg_CardIntSigEN(index, 0);
+            GH_SDIO_set_BlkSizeNorIntStaEnReg_CardIntStatusEn(index, 0);
+#endif
+
+        }while(0);
+
+    }
+
+    return;
+
+EXIT:
+
+    if(sdioInstancePtr[index]->cmd)
+    {
+        sdioInstancePtr[index]->cmd->err = ret;
+        if(sdioInstancePtr[index]->cmd->data)
+            sdioInstancePtr[index]->cmd->data->err = ret;
+    }
+
+    rt_completion_done(&(sdioInstancePtr[index]->completion));
+}
+
+#endif
+
+static rt_int32_t sdio_init(rt_uint32_t index)
+{
+    rt_int32_t ret;
+    GD_INT_OPEN_PARAMS_S     intParams;
+
+#ifdef CODEC_710XS
+    rt_int8_t detect_irq[SDIO_SLOT_COUNT] = {GD_INT_SD_CARD_DETECT_IRQ, GD_INT_SD2_CARD_DETECT_IRQ};
+    rt_int8_t ctl_irq[SDIO_SLOT_COUNT]  = {GD_INT_SD_CONTROLLER_IRQ, GD_INT_SD2_CONTROLLER_IRQ};
+#else
+    rt_int8_t detect_irq[SDIO_SLOT_COUNT] = {GD_INT_SD_CARD_DETECT_IRQ};
+    rt_int8_t ctl_irq[SDIO_SLOT_COUNT]  = {GD_INT_SD_CONTROLLER_IRQ};
+#endif
+    rt_int8_t i = (index == 0)? 0:2;
+
+    intParams.type           = ctl_irq[index];
+    intParams.sensitivity    = GD_INT_LEVEL_HIGH;
+    intParams.active         = GD_INT_INVERT_IRQ;
+    intParams.priority       = GD_INT_MID_PRIORITY;
+    intParams.isrFct.lowPrio = (index == 0)? sdio_isr0:sdio_isr1;
+    ret = GD_INT_Open(&intParams, &inthandleArray[i]);
+    if(ret != 0)
+    {
+        return -RT_ERROR;
+    }
+
+    GD_INT_Enable(&inthandleArray[i],GD_INT_ENABLED);
+    /*open the sdio detec interrupt*/
+    intParams.type           = detect_irq[index];
+    intParams.sensitivity    = GD_INT_BOTH_EDGES;
+    intParams.active         = GD_INT_INVERT_IRQ;
+    intParams.priority       = GD_INT_MID_PRIORITY;
+    intParams.isrFct.lowPrio = (index == 0)? sdio_isr0:sdio_isr1;
+    ret = GD_INT_Open(&intParams, &inthandleArray[i+1]);
+    if(ret != 0)
+    {
+        return -RT_ERROR;
+    }
+
+    GD_INT_Enable(&inthandleArray[i+1],GD_INT_ENABLED);
+    if(ret != 0)
+    {
+        return -RT_ERROR;
+    }
+
+    return RT_EOK;
+}
+
+static rt_uint8_t sdio_get_inserted_flag(rt_uint32_t index)
+{
+    return ((GH_SDIO_get_PresentStateReg(index)&0x00070000) == 0x00070000);
+}
+
+static void sdio_set_cmd_reg(rt_uint32_t index,rt_uint32_t cmdarg,rt_uint32_t data,rt_uint32_t flags)
+{
+#ifdef GK7102C
+
+    rt_uint8_t cmd = cmdarg & 0x3f;
+    rt_uint16_t transMod = cmdarg >> 16;
+    GH_SDIO_COMMONDREG_S commRegVal;
+
+    commRegVal.all = 0;
+    commRegVal.bitc.cmdindex = cmd;
+
+    if(cmd == 12)
+    {
+        /*abort cmd*/
+        commRegVal.bitc.cmdtype = 3;
+    }
+    else
+    {
+        /*suspend/resume cmd(sdio)*/
+    }
+
+    if (flags & MMC_REP_136)                /* Long REP */
+    {
+        commRegVal.bitc.reptypeselect = 1;
+    }
+    else if (flags & MMC_REP_48_BUSY)        /* R1B */
+    {
+        commRegVal.bitc.reptypeselect = 3;
+    }
+    else if (flags & MMC_REP_48)            /* Normal REP */
+    {
+        commRegVal.bitc.reptypeselect = 2;
+    }
+
+    if (flags & MMC_COM_INDEX_CHEC)
+    {
+        commRegVal.bitc.cmdindexchecken = 1;
+    }
+
+    if (flags & MMC_REP_CRC)
+    {
+        commRegVal.bitc.cmdcrcchecken = 1;
+    }
+
+    if (data)
+    {
+        commRegVal.bitc.datapreselect = 1;
+    }
+
+    GH_SDIO_set_TranModeReg(index, transMod);
+    GH_SDIO_set_CommondReg(index, commRegVal.all);
+#else
+
+    rt_uint8_t cmd=cmdarg & 0x3f;
+    unsigned short cmdval=(cmd<<8);
+
+    if(cmd == MMC_STOP_TRANSMISSION)
+    {
+        /*abort cmd*/
+        cmdval |=(3<<6);
+    }
+    else
+    {
+        /*suspend/resume cmd(sdio)*/
+    }
+
+    if (flags & MMC_REP_136)                /* Long REP */
+    {
+        cmdval |= 0x01;
+    }
+    else if (flags & MMC_REP_48_BUSY)        /* R1B */
+    {
+        cmdval |= 0x03;
+    }
+    else if (flags & MMC_REP_48)            /* Normal REP */
+    {
+        cmdval |= 0x02;
+    }
+
+    if (flags & MMC_COM_INDEX_CHEC)
+    {
+        cmdval |= (1<<5);
+    }
+
+    if (flags & MMC_REP_CRC)
+    {
+        cmdval |= (1<<3);
+    }
+
+    if (data)
+    {
+        cmdval |= (1<<4);
+    }
+
+    #ifdef CODEC_710X
+
+    GH_SDIO_set_TranModeReg(index, cmdarg>>16);
+    GH_SDIO_set_CmdReg(index, cmdval);
+
+    #elif defined(CODEC_710XS)
+
+    GH_SDIO_set_TranModeNorIntSigEnReg(index, \
+        (GH_SDIO_get_TranModeNorIntSigEnReg(index)&0xffff0000)|(cmdarg>>16));
+    GH_SDIO_set_ErrIntStatusCommondReg(index, \
+        (GH_SDIO_get_ErrIntStatusCommondReg(index)&0x0000ffff)|(cmdval<<16));
+
+    #endif
+
+#endif
+}
+
+static int sdio_issue_cmd(rt_uint8_t index,rt_uint32_t cmd, rt_uint32_t arg, rt_uint32_t data, rt_uint32_t flags)
+{
+    int i;
+
+    if(data == 0)
+    {
+        /*wait for cmd line free */
+        for(i = 0; i < 0x1000; i++)
+        {
+            if(!(GH_SDIO_get_PresentStateReg_CmdInhibitCmd(index)))
+                break;
+            GD_TIMER_Delay(10);
+        }
+
+        if (i >= 0x1000)
+        {
+            return -RT_EBUSY;
+        }
+    }
+    else
+    {
+        /*wait for data line (Cmd_inhibit_dat) free */
+        if(flags & MMC_REP_48_BUSY && cmd != MMC_STOP_TRANSMISSION)
+        {
+             for(i = 0; i < 0x1000; i++)
+             {
+                 if(!(GH_SDIO_get_PresentStateReg_CmdInhibitData(index)))
+                     break;
+                 GD_TIMER_Delay(10);
+             }
+
+             if (i >= 0x1000)
+             {
+                return -RT_EBUSY;
+             }
+        }
+    }
+
+    sdio_set_arg_reg(index, arg);
+    sdio_set_cmd_reg(index,cmd,data,flags);
+
+    return RT_EOK;
+}
+
+static void sdio_send_command(struct gk_sdio *sdiodrv, struct rt_mmcsd_cmd *cmd)
+{
+    rt_err_t ret = RT_EOK;
+    rt_uint32_t cmd_flags = 0,tmp_cmd = 0;
+    rt_uint8_t multblk = 0,readop = 1,timeout = SDIO_CMD_DEFAULT_TIMEOUT;
+    struct gk_sdio_info *sdio_info;
+    struct rt_mmcsd_data *data;
+
+    if (!sdiodrv || !cmd)
+    {
+        rt_kprintf("ERROR: %s, params is NULL\n", __func__);
+        return;
+    }
+
+    sdio_info = (struct gk_sdio_info *)sdiodrv->priv;
+
+
+    data = cmd->data;
+
+    rt_enter_critical();
+    sdiodrv->cmd = cmd;
+    sdiodrv->req = cmd->mrq;
+    rt_exit_critical();
+
+
+    if (data)
+    {
+        data->bytes_xfered = 0;
+
+        sdio_set_dma(sdio_info->id,data,0);
+        sdio_set_blksize_reg(sdio_info->id, SDIO_DEFAULT_BOUNDARY_ARG,data->blksize);
+        sdio_set_blkcnt_reg(sdio_info->id, data->blks);
+
+        if(data->flags & DATA_DIR_WRITE)
+            readop = 0;
+
+        if(data->blks > 1)
+            multblk = 1;
+
+        if((data->stop != RT_NULL) && multblk)
+        {
+            if(data->stop->cmd_code == MMC_STOP_TRANSMISSION)
+                tmp_cmd = sdio_set_tramode_reg(sdio_info->id,multblk,readop,1,multblk,SDIO_USE_DMA);
+            else
+                tmp_cmd = sdio_set_tramode_reg(sdio_info->id,multblk,readop,0,multblk,SDIO_USE_DMA);
+        }
+        else
+            tmp_cmd = sdio_set_tramode_reg(sdio_info->id,multblk,readop,0,multblk,SDIO_USE_DMA);
+
+    }
+
+    switch (resp_type(cmd))
+    {
+        case RESP_NONE:
+            cmd_flags = MMC_RSP_NONE;
+            break;
+        case RESP_R1:
+            cmd_flags = MMC_RSP_R1;
+            break;
+        case RESP_R2:
+            cmd_flags = MMC_RSP_R2;
+            break;
+        case RESP_R3:
+            cmd_flags = MMC_RSP_R3;
+            break;
+        case RESP_R4:
+            cmd_flags = MMC_RSP_R4;
+            break;
+        case RESP_R5:
+            cmd_flags = MMC_RSP_R5;
+            break;
+        case RESP_R6:
+            cmd_flags = MMC_RSP_R6;
+            break;
+        case RESP_R7:
+            cmd_flags = MMC_RSP_R7;
+            break;
+        case RESP_R1B:
+            cmd_flags = MMC_RSP_R1B;
+            break;
+        default:
+            rt_kprintf("ERROR: %s, unknown cmd type %x\n", __func__, resp_type(cmd));
+            return;
+    }
+
+    tmp_cmd |= cmd->cmd_code;
+
+    ret = sdio_issue_cmd(sdio_info->id, tmp_cmd, cmd->arg, (data != RT_NULL), cmd_flags);
+
+    if(ret != RT_EOK)
+    {
+        rt_kprintf("\n%s, issue cmd timeout!\n",__func__);
+        rt_kprintf("\ntmp_cmd: %d, cmd code: %d, args: 0x%x, resp type: 0x%x, dataflag: 0x%x, cmdflag: 0x%x\n",tmp_cmd, cmd->cmd_code, cmd->arg, resp_type(cmd), (data != RT_NULL),cmd_flags);
+        if(data == RT_NULL)
+            cmd->err = RT_ETIMEOUT;
+
+        return;
+    }
+
+    rt_completion_init(&sdiodrv->completion);
+    ret = rt_completion_wait(&sdiodrv->completion, RT_TICK_PER_SECOND * timeout);
+    if(ret != RT_EOK)
+    {
+        rt_kprintf("\n%s, cmd process timeout!\n",__func__);
+        rt_kprintf("\ntmp_cmd: %d, cmd code: %d, args: 0x%x, resp type: 0x%x, dataflag: 0x%x, cmdflag: 0x%x\n",tmp_cmd, cmd->cmd_code, cmd->arg, resp_type(cmd), (data != RT_NULL),cmd_flags);
+        if(data == RT_NULL)
+            cmd->err = RT_ETIMEOUT;
+
+        return;
+    }
+
+}
+
+
+static void gk_sdio_set_iocfg(struct rt_mmcsd_host *host, struct rt_mmcsd_io_cfg *io_cfg)
+{
+    int ret;
+    rt_uint32_t clkdiv;
+    struct gk_sdio *sdio_drv;
+    struct gk_sdio_info *sdio_info;
+
+    if(!host || !io_cfg)
+        return;
+
+    //rt_kprintf("\nclock: %d, vdd: %d, bus_mode: %d, bus_width: %d\n",io_cfg->clock,io_cfg->vdd,io_cfg->bus_mode,io_cfg->bus_width);
+    sdio_drv = host->private_data;
+    sdio_info = (struct gk_sdio_info *)sdio_drv->priv;
+
+    switch (io_cfg->power_mode)
+    {
+        case MMCSD_POWER_OFF:
+            sdio_power_off(sdio_info->id);
+            break;
+        case MMCSD_POWER_UP:
+            break;
+        case MMCSD_POWER_ON:
+            sdio_power_on(sdio_info->id);
+            break;
+        default:
+            break;
+    }
+
+    if (io_cfg->bus_width == MMCSD_BUS_WIDTH_1)
+        sdio_set_host_ctl_width(sdio_info->id,0);
+    else if(io_cfg->bus_width == MMCSD_BUS_WIDTH_4)
+        sdio_set_host_ctl_width(sdio_info->id,1);
+    else if(io_cfg->bus_width == MMCSD_BUS_WIDTH_8)
+    {
+        sdio_set_host_ctl_width(sdio_info->id,0);
+        sdio_set_hostctl8BitMode(sdio_info->id,1);
+    }
+
+    if (io_cfg->vdd)
+        sdio_select_voltage(sdio_info->id);
+
+    if (io_cfg->clock > 25000000) //FIXME:need check
+    {
+#ifdef CODEC_710X
+        sdio_set_host_ctl_speed(sdio_info->id,1);
+        sdio_clock_onoff(sdio_info->id, 0);
+        sdio_set_clockdiv(sdio_info->id, 0);
+#else
+        sdio_set_host_ctl_speed(sdio_info->id,0);
+        sdio_clock_onoff(sdio_info->id, 0);
+        sdio_set_clockdiv(sdio_info->id, 1);
+#endif
+    }
+    else
+    {
+        sdio_set_host_ctl_speed(sdio_info->id,0);
+        sdio_clock_onoff(sdio_info->id, 0);
+        sdio_set_clockdiv(sdio_info->id, 1);
+    }
+
+}
+
+static void gk_sdio_enable_sdio_irq(struct rt_mmcsd_host *host,rt_int32_t enable)
+{
+    int ret;
+    struct gk_sdio *sdio_drv;
+    struct gk_sdio_info *sdio_info;
+
+    if(!host)
+        return;
+
+    sdio_drv = host->private_data;
+    sdio_info = (struct gk_sdio_info *)sdio_drv->priv;
+
+    //rt_kprintf("\n%s, enable:%d\n", __func__,enable);
+#ifdef CODEC_710X
+    GH_SDIO_set_NorIntStaEnReg_CardIntStatusEn(sdio_info->id, enable);
+    GH_SDIO_set_NorIntSigEnReg_CardIntSigEN(sdio_info->id, enable);
+#elif GK7102C
+    GH_SDIO_set_NorIntStaEnReg_CardIntStatusEn(sdio_info->id, enable);
+    GH_SDIO_set_NorIntSigEnReg_CardIntSigEN(sdio_info->id, enable);
+#elif defined(CODEC_710XS)
+    GH_SDIO_set_TranModeNorIntSigEnReg_CardIntSigEN(sdio_info->id, enable);
+    GH_SDIO_set_BlkSizeNorIntStaEnReg_CardIntStatusEn(sdio_info->id, enable);
+#endif
+
+}
+
+static void gk_sdio_request(struct rt_mmcsd_host *host, struct rt_mmcsd_req *req)
+{
+    int ret;
+
+    struct gk_sdio *sdio_drv = (struct gk_sdio *)host->private_data;
+    struct gk_sdio_info *sdio_info = (struct gk_sdio_info *)sdio_drv->priv;
+
+    if (!host || !req || !sdio_drv)
+    {
+        rt_kprintf("ERROR: %s, params is NULL\n", __func__);
+        return;
+    }
+
+    if(sdio_info->type != SDIO_DEVICE_TYPE_WIFI)
+    {
+        if (!sdio_get_inserted_flag(sdio_info->id))
+        {
+            if(req->cmd)
+                req->cmd->err = -RT_EIO;
+
+            mmcsd_req_complete(host);
+
+            return;
+        }
+    }
+
+    if(req->cmd)
+        sdio_send_command(sdio_drv, req->cmd);
+
+#if 0
+    if(req->stop && req->stop != req->cmd )
+        sdio_send_command(sdio_drv, req->stop);
+#endif
+
+    rt_enter_critical();
+    sdio_drv->cmd = RT_NULL;
+    sdio_drv->req = RT_NULL;
+    rt_exit_critical();
+
+    mmcsd_req_complete(host);
+
+}
+
+static rt_int32_t gk_sdio_get_card_status(struct rt_mmcsd_host *host)
+{
+    return 0;
+}
+
+
+static const struct rt_mmcsd_host_ops gk_sdio_ops = {
+
+    .request         = gk_sdio_request,
+    .set_iocfg       = gk_sdio_set_iocfg,
+    .get_card_status = gk_sdio_get_card_status,
+    .enable_sdio_irq = gk_sdio_enable_sdio_irq,
+};
+
+int gk_sdio_probe(void *priv_data)
+{
+    struct gk_sdio *sdio_drv;
+    struct rt_mmcsd_host *host;
+    struct gk_sdio_info *sdio_info = (struct gk_sdio_info *)priv_data;
+
+    sdio_drv = (struct gk_sdio *)rt_malloc(sizeof(struct gk_sdio));
+
+    if (!sdio_drv)
+    {
+        rt_kprintf("ERROR: %s,line:%d, failed to malloc host\n", __func__,__LINE__);
+        return -RT_ENOMEM;
+    }
+
+    rt_memset(sdio_drv, 0, sizeof(struct gk_sdio));
+
+    host = mmcsd_alloc_host();
+    if (!host)
+    {
+        rt_kprintf("ERROR: %s,LINE:%d failed to malloc host\n", __func__,__LINE__);
+        rt_free((void *)sdio_drv);
+        return -RT_ENOMEM;
+    }
+
+    host->ops       = &gk_sdio_ops;
+    host->freq_min  = 400*1000; ///FIXME:need check
+    host->freq_max  = 50*1000000; ///FIXME:need check
+    host->valid_ocr = VDD_32_33 | VDD_33_34 | VDD_165_195;
+
+    host->flags = MMCSD_MUTBLKWRITE | MMCSD_SUP_HIGHSPEED | MMCSD_SUP_SDIO_IRQ | MMCSD_BUSWIDTH_4;
+    host->max_seg_size  = SDIO_DEFAULT_BOUNDARY_SIZE;
+    host->max_blk_size  = 1024;
+    host->max_blk_count = 65535;
+    host->private_data  = sdio_drv;
+
+    sdio_drv->host = host;
+    sdio_drv->priv = sdio_info;
+
+    sdio_init(sdio_info->id);
+    sdio_reset(sdio_info->id);
+
+    sdioInstancePtr[sdio_info->id] = sdio_drv;
+
+    mmcsd_change(host);
+
+    return 0;
+}
+
+int gk_sdio_exit(void *priv_data)
+{
+    struct gk_sdio_info *sdio_info = (struct gk_sdio_info *)priv_data;
+    rt_int8_t i;
+
+    if(!sdio_info)
+        return RT_EINVAL;
+
+    if(!sdioInstancePtr[sdio_info->id])
+        return RT_EINVAL;
+
+    i = (sdio_info->id == 0)? 0:2;
+
+    GD_INT_Close(&inthandleArray[i]);
+    GD_INT_Close(&inthandleArray[i+1]);
+
+    rt_completion_done(&(sdioInstancePtr[sdio_info->id]->completion));
+
+    if(sdioInstancePtr[sdio_info->id]->host)
+        mmcsd_free_host(sdioInstancePtr[sdio_info->id]->host);
+
+    rt_free(sdioInstancePtr[sdio_info->id]);
+    sdioInstancePtr[sdio_info->id] = RT_NULL;
+
+    return 0;
+}
+
+struct gk_platform_driver sdio_driver_ops = {
+
+    .name = "gk-sdio", .probe = gk_sdio_probe, .remove = gk_sdio_exit,
+
+};
+
+#if 0
+#include "adi_types.h"
+#include "adi_gpio.h"
+
+static GADI_SYS_HandleT resetHandle = NULL;
+
+void gk_sdio_wifi_reset_gpio_init(GADI_U8 num_gpio)
+{
+    rt_int32_t error;
+    GADI_GPIO_OpenParam resetParam;
+
+    if(num_gpio == 0)
+    {
+        resetHandle = NULL;
+        return;
+    }
+
+    resetParam.active_low = 0;
+    resetParam.direction = 1;
+    resetParam.num_gpio = num_gpio;
+    resetParam.value = 1;
+
+    rt_kprintf("wifi reset num_gpio %d !\n", num_gpio);
+
+    if(resetHandle == NULL)
+    {
+        resetHandle = gadi_gpio_open(&error, &resetParam);
+        if(resetHandle == NULL)
+        {
+            rt_kprintf("open sensor reset GPIO failed %d !\n", error);
+            return;
+        }
+    }
+}
+
+int gk_sdio_wifi_hw_reset(void)
+{
+
+    rt_int32_t error;
+
+    if(resetHandle == NULL)
+    {
+        return 1;
+    }
+
+    error = gadi_gpio_clear(resetHandle);
+    rt_thread_delay(20);
+    error = gadi_gpio_set(resetHandle);
+    rt_thread_delay(20);
+    if(error != 0)
+    {
+        rt_kprintf("wifi reset failed %d !\n", error);
+        return -1;
+    }
+
+    return 0;
+
+}
+#endif
+
+void rt_hw_sdio_init(void)
+{
+    GH_SDIO_init();
+    gk_platform_driver_init(&sdio_driver_ops);
+}
+

+ 41 - 0
bsp/gkipc/drivers/drv_sdio.h

@@ -0,0 +1,41 @@
+#ifndef __DRV_SDIO_H__
+#define __DRV_SDIO_H__
+
+#include <rtthread.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ typedef enum
+ {
+    SDIO_DEVICE_TYPE_NORMAL = 0,     //!< Normal transfer type for SD/SDHC/MMC cards (default)
+    SDIO_DEVICE_TYPE_WIFI,
+    
+} SDIO_DEVICE_TYPE_E;
+
+
+struct gk_sdio_info
+{
+    rt_uint32_t id;
+	SDIO_DEVICE_TYPE_E type;
+};
+
+struct gk_sdio
+{
+    struct rt_mmcsd_host *host;
+    struct rt_mmcsd_req  *req;
+    struct rt_mmcsd_cmd  *cmd;
+	
+    struct rt_completion completion;
+    void *priv;
+};
+void rt_hw_sdio_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
+

+ 317 - 0
bsp/gkipc/drivers/drv_ssi.c

@@ -0,0 +1,317 @@
+#include <rtdevice.h>
+#include "gtypes.h"
+#include "gd_spi.h"
+#include "drv_ssi.h"
+#include "platform.h"
+
+/*---------------------------------------------------------------------------*/
+/* local defines                                                             */
+/*---------------------------------------------------------------------------*/
+
+
+/*---------------------------------------------------------------------------*/
+/* local data types                                                          */
+/*---------------------------------------------------------------------------*/
+
+
+
+/*---------------------------------------------------------------------------*/
+/* local data                                                                */
+/*---------------------------------------------------------------------------*/
+
+
+
+/*---------------------------------------------------------------------------*/
+/* local  functions                                                          */
+/*---------------------------------------------------------------------------*/
+static void *gk_get_spi_dev_pri_data(struct rt_spi_device *device)
+{
+    return device->parent.user_data;
+}
+
+static rt_err_t gk_spi_configure(struct rt_spi_device *device, struct rt_spi_configuration *configuration)
+{
+	struct gk_spi_slave_info *spi_slave;
+	struct gk_spi_controller *spi_control;
+	GD_SPI_OPEN_PARAMS_S openParamsP;
+	rt_uint32_t spi_hz;
+	rt_int32_t	ret;
+	rt_uint8_t	data_width = 8,polarity;
+
+	if(!device || !configuration)
+	{
+		rt_kprintf("%s,%d,param wrong!\n",__FUNCTION__,__LINE__);
+		return RT_ERROR;
+	}
+
+	spi_slave   = (struct gk_spi_slave_info *)gk_get_spi_dev_pri_data(device);
+	spi_control = spi_slave->control;
+
+	rt_sem_take(&spi_control->xfer_lock, RT_WAITING_FOREVER);
+
+	if(spi_slave->spihandle > 0)
+	{
+		GD_SPI_Close(&spi_slave->spihandle);
+		spi_slave->spihandle = -1;
+	}
+
+	 openParamsP.spi 	    = spi_control->id;
+	 openParamsP.slave      = spi_slave->id;
+	 openParamsP.csgpio     = spi_slave->cs_pin;
+	 openParamsP.used_irq   = 1;
+
+	 if (configuration->max_hz > GD_SPI_FREQ_81M)
+		 spi_hz = GD_SPI_FREQ_81M;
+	 else
+		 spi_hz = configuration->max_hz;
+
+	 openParamsP.baudrate = spi_hz;
+
+	 /* CPOL */
+	 if (configuration->mode & RT_SPI_CPOL && configuration->mode & RT_SPI_CPHA)
+	 {
+	 	polarity = SPI_POLARITY_MODE3;
+	 }
+	 else if(configuration->mode & RT_SPI_CPOL && !configuration->mode & RT_SPI_CPHA)
+	 {
+	 	polarity = SPI_POLARITY_MODE2;
+	 }
+	 else if(!configuration->mode & RT_SPI_CPOL && configuration->mode & RT_SPI_CPHA)
+	 {
+	 	polarity = SPI_POLARITY_MODE1;
+	 }
+	 else
+		 polarity = SPI_POLARITY_MODE0;
+
+	 openParamsP.polarity = polarity;
+
+	 ret = GD_SPI_Open(&openParamsP,&(spi_slave->spihandle));
+	 if(ret != GD_OK)
+	 {
+	     rt_kprintf("GD_SPI_Open failed!\n");
+		 rt_sem_release(&spi_control->xfer_lock);
+	     return RT_ERROR;
+	 }
+
+	 /* data_width */
+	 if (configuration->data_width <= 8)
+	 {
+	 	data_width = 8;
+	 }
+	 else if (configuration->data_width <= 16)
+	 {
+
+	 	data_width = 16;
+	 }
+
+	 ret = GD_SPI_SetDatFormat(spi_slave->spihandle, data_width);;
+	 if(ret != GD_OK)
+	 {
+	     rt_kprintf("GD_SPI_SetDatFormat failed!\n");
+		 rt_sem_release(&spi_control->xfer_lock);
+	     return RT_ERROR;
+	 }
+
+	 rt_sem_release(&spi_control->xfer_lock);
+
+	return RT_EOK;
+}
+
+static rt_uint32_t gk_spi_xfer(struct rt_spi_device *device, struct rt_spi_message *message)
+{
+	struct gk_spi_slave_info *spi_slave;
+	struct gk_spi_controller *spi_control;
+	GERR ret = GD_OK;
+
+	if(!device || !message)
+	{
+		rt_kprintf("%s,%d,param wrong!\n",__FUNCTION__,__LINE__);
+		return 0;
+	}
+
+	spi_slave   = (struct gk_spi_slave_info *)gk_get_spi_dev_pri_data(device);
+
+	if(!spi_slave)
+	{
+		rt_kprintf("%s,%d,param wrong!\n",__FUNCTION__,__LINE__);
+		return 0;
+	}
+
+	spi_control = spi_slave->control;
+
+	if(spi_slave->spihandle < 0)
+	{
+		rt_kprintf("%s,%d,spi channel not configured!\n",__FUNCTION__,__LINE__);
+		return 0;
+	}
+
+	if(!message)
+	{
+		rt_kprintf("%s,%d,params wrong!\n",__FUNCTION__,__LINE__);
+		return 0;
+	}
+
+	rt_sem_take(&spi_control->xfer_lock, RT_WAITING_FOREVER);
+
+	if(message->cs_take)
+		GD_SPI_GetDevice(spi_slave->spihandle);
+
+	if(message->recv_buf && message->send_buf)
+    	ret = GD_SPI_WriteThenReadBytes(spi_slave->spihandle,(rt_uint8_t *)message->send_buf,message->length,
+    	(rt_uint8_t *)message->recv_buf,message->length);
+	else if(message->send_buf && !message->recv_buf)
+		ret = GD_SPI_WriteBytes(spi_slave->spihandle,(rt_uint8_t *)message->send_buf,message->length);
+	else if(!message->send_buf && message->recv_buf)
+		ret = GD_SPI_WriteThenReadBytes(spi_slave->spihandle,NULL,0,(rt_uint8_t *)message->recv_buf,message->length);
+
+
+	if(message->cs_release)
+		GD_SPI_ReleaseDevice(spi_slave->spihandle);
+
+	rt_sem_release(&spi_control->xfer_lock);
+
+
+	if(ret != GD_OK)
+	{
+		rt_kprintf("%s,%d,transfer error!\n",__FUNCTION__,__LINE__);
+		return 0;
+	}
+	else
+	{
+		return message->length;
+	}
+
+}
+
+static struct rt_spi_ops gk_spi_ops = {
+
+    .configure = gk_spi_configure, .xfer = gk_spi_xfer,
+
+};
+
+int gk_spi_probe(void *priv_data)
+{
+	int ret,i;
+    char spi_dev_name[20]  = {0};
+    char spi_bus_name[20]  = {0};
+    char spi_lock_name[20] = {0};
+    struct gk_spi_controller *spi_control;
+	struct gk_spi_controller_data *spi_controller_data = (struct gk_spi_controller_data *)priv_data;
+    struct gk_spi_slave_info **control_slave;
+    struct gk_spi_slave_info *spi_slave,*next_slave;
+
+	if (!spi_controller_data)
+	{
+		rt_kprintf("%s,%d input param wrong!\n",__FUNCTION__,__LINE__);
+		return -1;
+	}
+
+    spi_control = (struct gk_spi_controller *)rt_malloc(sizeof(struct gk_spi_controller));
+    if (!spi_control)
+    {
+        rt_kprintf("%s,%d malloc failed!\n",__FUNCTION__,__LINE__);
+        return -1;
+    }
+
+    rt_memset(spi_control, 0, sizeof(struct gk_spi_controller));
+
+	spi_control->id = spi_controller_data->id;
+
+    rt_sprintf(spi_lock_name, "%s%d", "spi_lock", spi_control->id);
+    rt_sprintf(spi_bus_name, "%s%d", "spi_bus", spi_control->id);
+
+    rt_sem_init(&spi_control->xfer_lock, spi_lock_name, 1, RT_IPC_FLAG_FIFO);
+
+    ret = rt_spi_bus_register(&spi_control->spi_bus, spi_bus_name, &gk_spi_ops);
+
+	control_slave = &spi_control->spi_slave;
+
+    for (i = 0; i < spi_controller_data->total_slave; i++)
+    {
+        spi_slave = (struct gk_spi_slave_info *)rt_malloc(sizeof(struct gk_spi_slave_info));
+        if (!spi_slave)
+        {
+			rt_kprintf("%s,%d malloc failed!\n",__FUNCTION__,__LINE__);
+            goto exit;
+        }
+        rt_memset(spi_slave, 0, sizeof(struct gk_spi_slave_info));
+
+        spi_slave->id      = i;
+        spi_slave->control = spi_control;
+        spi_slave->cs_pin  = spi_controller_data->slave_cs_pin[i];
+		spi_slave->spihandle = -1;
+
+        rt_sprintf(spi_dev_name, "%s%d%s%d", "ssi", spi_control->id, "_", spi_slave->id);
+
+        *control_slave = spi_slave;
+        control_slave  = &spi_slave->next;
+
+        ret = rt_spi_bus_attach_device(&spi_slave->spi_device, spi_dev_name,spi_bus_name, spi_slave);
+        if (ret != RT_EOK)
+        {
+            rt_kprintf("register dev to bus failed...\n");
+            goto exit;
+        }
+    }
+
+	spi_controller_data->control = spi_control;
+
+	GD_SPI_Init();
+
+    return RT_EOK;
+
+exit:
+
+	spi_slave = spi_control->spi_slave;
+	while (spi_slave != RT_NULL)
+	{
+		next_slave = spi_slave->next;
+		rt_free(spi_slave);
+		spi_slave = next_slave;
+	}
+
+    rt_sem_detach(&spi_control->xfer_lock);
+
+    rt_free(spi_control);
+
+	return RT_ERROR;
+}
+
+int gk_spi_exit(void *priv_data)
+{
+
+    struct gk_spi_controller *spi_control;
+    struct gk_spi_controller_data *plat_data;
+    struct gk_spi_slave_info *spi_slave;
+    struct gk_spi_slave_info *next_slave;
+
+    plat_data   = (struct gk_spi_controller_data *)priv_data;
+    spi_control = plat_data->control;
+    spi_slave   = spi_control->spi_slave;
+
+    while (spi_slave != RT_NULL)
+    {
+        next_slave = spi_slave->next;
+        rt_free(spi_slave);
+        spi_slave = next_slave;
+    }
+
+    rt_sem_detach(&spi_control->xfer_lock);
+
+    rt_free(spi_control);
+
+    return RT_EOK;
+}
+
+struct gk_platform_driver gk_spi_driver_ops = {
+
+    .name = "spi", .probe = gk_spi_probe, .remove = gk_spi_exit,
+
+};
+
+void rt_hw_spi_init(void)
+{
+
+	gk_platform_driver_init(&gk_spi_driver_ops);
+}
+

Some files were not shown because too many files changed in this diff