summaryrefslogtreecommitdiff
path: root/arch/mips/Kconfig
AgeCommit message (Collapse)Author
2020-04-27mips: mtmips: add SPL supportWeijie Gao
This patch adds SPL support for mtmips platform. The lowlevel architecture is split into SPL and the rest parts are built into a memory loadable u-boot image. Optional SPL_DM and OF_CONTROL are also supported. The increment of size is very small (< 10 KiB) if SPL_DM and OF_CONTROL are not enabled and the memory bootable u-boot (u-boot.img) is generated automatically so there is not need to add a separate config for it. A lzma compressed payload (u-boot-lzma.img) is also generated and it will be combined with u-boot-spl.bin to form the unified ROM bootable binary u-boot-mtmips.bin. A spl loader is added to support uncompress the payload. Reviewed-by: Stefan Roese <sr@denx.de> Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
2020-04-27mips: add a option to support not reserving malloc space on initial stackWeijie Gao
The initial stack on some platforms is too small to hold a large malloc space. This patch adds a option to allow these platforms not reserving the malloc space on initial stack. These platforms should set the malloc base after DRAM is usable. Reviewed-by: Stefan Roese <sr@denx.de> Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
2020-04-27mips: add an option to support initialize SRAM for initial stackWeijie Gao
Currently CONFIG_MIPS_INIT_STACK_IN_SRAM assumes the memory space for the initial stack can be used directly. However on some platform the SRAM needs initialization, e.g. lock cache. This patch adds an option to allow a new function mips_sram_init() being called before setup_stack_gd. Reviewed-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> Reviewed-by: Stefan Roese <sr@denx.de> Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
2020-04-27mips: add an option to enable u_boot_list section for SPL loaders in ↵Weijie Gao
u-boot-spl.lds u_boot_list is not only used by DM, but also by some SPL image load methods such as spl_nor.c. This patch adds an option CONFIG_SPL_LOADER_SUPPORT in conjunction with CONFIG_SPL_DM surrounding the u_boot_list section to make sure SPL image loaders can be correctly built into u-boot SPL without DM enabled. Reviewed-by: Stefan Roese <sr@denx.de> Reviewed-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
2020-04-27mips: add support to restore exception vector base before booting linuxWeijie Gao
In U-Boot the exception vector base will be moved to top of memory, to be used to display register dump when exception occurs. But some old linux kernel does not honor the base set in CP0_EBASE. A modified exception vector base will cause kernel crash. This patch adds an option to enable reset exception vector base to its previous value, or a user configured value before booting linux kernel. Reviewed-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
2019-11-29MIPS: remove Micronas VCT boardsDaniel Schwierzeck
The deadline for migration to CONFIG_DM is v2020.01. The VCT baords would need an almost complete rewrite of all drivers to support driver model. Unless someone has access to the hardware and volunteers to do the migration, the board should be scheduled for removal. Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> Acked-by: Stefan Roese <sr@denx.de>
2019-10-25mips: mtmips: select essential drivers in KconfigWeijie Gao
Some drivers (clk, pinctrl, reset, ...) are necessary for reset of the system, they should be always selected. Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
2019-10-25MIPS: add compile time definition of L2 cache sizeRamon Fried
If configuration is set to skip low level init, automatic probe of L2 cache size is not performed and the size is set to 0. Flushing or invalidating the L2 cache will fail in this case. Add a static configuration (SYS_DCACHE_LINE_SIZE) with default set to 0. Signed-off-by: Ramon Fried <rfried.dev@gmail.com>
2019-07-05mips: mt76xx: Implement new d-cache fix in last_stage_init()Stefan Roese
With commit 06985289d452 ("watchdog: Implement generic watchdog_reset() version") the init sequence has changed in arch_misc_init(), resulting in a re-appearance of the d-cache issue on MT7688 boards (e.g. gardena). When this happens, the first (or sometimes later ones as well) TFTP command hangs and does not complete correctly. This leads to the assumption that the d-cache is not in a clean state once the ethernet driver is called (d-cache is used here for the buffers). The old work- around with the cache flush somehow does not work any more now with the new code change. Unfortunately adding CONFIG_SYS_MALLOC_CLEAR_ON_INIT also did not fix this issue. With v2019.07-rc3 it shows again. The time of accessing the data seems to be very important here. It needs to be "very late" in the boot process. Testing has shown, that copying a 64KiB area in DDR at a very late bootup time, directly before calling into the prompt, fixes this issue. Flushing of the complete d-cache does not seem to necessary, as this copy alone seems to fix this problem. Signed-off-by: Stefan Roese <sr@denx.de> Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
2019-05-24mips: mt76xx: Remove cache workaround and select SYS_MALLOC_CLEAR_ON_INITStefan Roese
With commit 06985289d452 ("watchdog: Implement generic watchdog_reset() version") the init sequence has changed in arch_misc_init(), resulting in a re-appearance of the d-cache issue on MT7688 boards (e.g. gardena). When this happens, the first (or sometimes later ones as well) TFTP command hangs and does not complete correctly. This leads to the assumption that the d-cache is not in a clean state once the ethernet driver is called (d-cache is used here for the buffers). The old work- around with the cache flush somehow does not work any more now with the new code change. To fix this issue, this patch now removes the old workaround and selects CONFIG_SYS_MALLOC_CLEAR_ON_INIT for ARCH_MTMIPS. With this option the complete malloc area is initialized with zeros (cache lines are touched). Testing has shown that this also fixes the issue on the MT7688 boards. Signed-off-by: Stefan Roese <sr@denx.de> Suggested-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
2019-05-03mips: rename mach-mt7620 to mach-mtmipsWeijie Gao
Currently mach-mt7620 contains only support for mt7628. To avoid confusion, rename mach-mt7620 to mach-mtmips, which means MediaTek MIPS platforms. MT7620 and MT7628 should be distinguished by SOC_MT7620 and SOC_MT7628 because they do not share the same lowlevel codes. Dependencies of four drivers are changed to SOC_MT7628 as these drivers are only used by MT7628. Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> Reviewed-by: Stefan Roese <sr@denx.de> Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
2018-12-19mips: jz47xx: Add JZ4780 SoC supportPaul Burton
Add initial support for the Ingenic JZ47xx MIPS SoC. Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> Signed-off-by: Paul Burton <paul.burton@imgtec.com> Signed-off-by: Marek Vasut <marek.vasut@gmail.com> Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com> Reviewed-by: Marek Vasut <marex@denx.de>
2018-12-19MSCC: add support for Ocelot SoCsGregory CLEMENT
This family of SoCs are found in the Microsemi Switches solution and have already a support in the linux kernel. Signed-off-by: Gregory CLEMENT <gregory.clement@bootlin.com>
2018-12-19mips: mt76xx: Flush d-cache in arch_misc_init() to solve d-cache issuesStefan Roese
It has been noticed, that sometimes the d-cache is not in a "clean-state" when U-Boot is running on MT7688. This was detected when using the ethernet driver (which uses d-cache) and a TFTP command does not complete. Flushing the complete d-cache (again?) here seems to fix this issue. Signed-off-by: Stefan Roese <sr@denx.de> Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
2018-11-18mips: mt76xx: Enable watchdog supportStefan Roese
This patch enables and starts the watchdog on the MT7620 platform. Currently the WD timeout is configured to 60 seconds. Signed-off-by: Stefan Roese <sr@denx.de> Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> [fixed build error due to missing function prototype arch_misc_init] Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
2018-11-18mips: mt76xx: Kconfig: Add ethernet and GPIO supportStefan Roese
Imply DM_ETH and DM_GPIO for ARCH_MT7620, as this platform now supports ethernet and GPIO as well. Signed-off-by: Stefan Roese <sr@denx.de> Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
2018-11-02MIPS: make size of relocation table fixed but configurableDaniel Schwierzeck
Currently the size of the relocation table will be shrunk to the actual size needed. Although this gives a maximal space saving, it messes up the _end symbol. This breaks features like appended DTBs because the _end symbol doesn't point to the real end of the U-Boot binary. Remove the size shrinking and make the size of the relocation table fixed but configurable. This follows the Linux approach and the user can adjust the size to his needs. Also rename the relocation table section from .rel to .data.reloc to follow the Linux approach and to avoid ambiguities with the .rel.* sections added by the linker. Reported-by: Lars Povlsen <lars.povlsen@microsemi.com> Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
2018-09-23mips: mt76xx: Add sysreset supportStefan Roese
This patch adds the necessary sysreset DT node and enables the required drivers via Kconfig. Signed-off-by: Stefan Roese <sr@denx.de> Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
2018-09-22mips: Add basic MediaTek MT7620/88 supportStefan Roese
This patch adds basic support for the MediaTek MT7620/88 SoCs. Parts of the code is copied from the MediaTek GitHub repository: https://github.com/MediaTek-Labs/linkit-smart-uboot.git The mt7628a.dtsi file is imported from Linux v4.17. Support for the LinkIt Smart 7688 module and the Gardena Smart Gateway both based on the MT7688 will be added in further patches. Signed-off-by: Stefan Roese <sr@denx.de> Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
2018-09-22MIPS: cache: make index base address configurableDaniel Schwierzeck
The index base address used for the cache initialisation is currently hard-coded to CKSEG0. Make this value configurable if a MIPS system needs to have a different address (e.g. in SRAM or ScratchPad RAM). Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
2018-09-22MIPS: start.S: make boot config at offset 0x10 configurableDaniel Schwierzeck
Some MIPS systems store some board-specific boot configuration in the U-Boot binary at offset 0x10. This is used by Malta boards and by Lantiq/Intel SoC's when booting from parallel NOR flash. Convert the hard-coded values to Kconfig options to remove such board-specific stuff out of the generic start.S code. This also deprecates the config option CONFIG_SYS_XWAY_EBU_BOOTCFG. Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
2018-08-08mips: au1x00: Remove support for these SoCsTom Rini
The only platform left for the AU1x00 SoCs was the pb1x00 platform, an apparent clone of the dbau1x00 platform. As pb1x00 had no listed maintainer I am assuming that it is also orphaned. Remove this platform and then remove the unused SoC support. Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> Signed-off-by: Tom Rini <trini@konsulko.com> Reviewed-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
2018-08-08mips: dbau1x00: Remove this boardTom Rini
This platform has been marked as orphan since June of 2016 and should have been removed some time ago. Do so now. Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> Signed-off-by: Tom Rini <trini@konsulko.com> Reviewed-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
2018-07-30dm: Change CMD_DM enablingMichal Simek
CMD_DM is used for debug purpose and it shouldn't be enabled by default via Kconfig. Unfortunately this is in the tree for quite a long time that's why solution is to use imply DM for all targets which are enabling DM. Signed-off-by: Michal Simek <michal.simek@xilinx.com> Reviewed-by: Tom Rini <trini@konsulko.com> Reviewed-by: Joe Hershberger <joe.hershberger@ni.com>
2018-07-30Kconfig: Sort bool, default, select and imply optionsMichal Simek
Fix Kconfig bool, default, select and imply options to be alphabetically sorted. Signed-off-by: Michal Simek <michal.simek@xilinx.com> Reviewed-by: Tom Rini <trini@konsulko.com>
2017-08-15env: Convert CONFIG_ENV_IS_IN... to a choiceSimon Glass
At present we support multiple environment drivers but there is not way to select between them at run time. Also settings related to the position and size of the environment area are global (i.e. apply to all locations). Until these limitations are removed we cannot really support more than one environment location. Adjust the location to be a choice so that only one can be selected. By default the environment is 'nowhere', meaning that the environment exists only in memory and cannot be saved. Also expand the help for the 'nowhere' option and move it to the top since it is the default. Signed-off-by: Simon Glass <sjg@chromium.org> [trini: Move all of the imply logic to default X if Y so it works again] Signed-off-by: Tom Rini <trini@konsulko.com>
2017-07-25Convert CONFIG_ENV_IS_IN_FLASH to KconfigSimon Glass
This converts the following to Kconfig: CONFIG_ENV_IS_IN_FLASH Signed-off-by: Simon Glass <sjg@chromium.org>
2017-07-25Convert CONFIG_ENV_IS_IN_MMC/NAND/UBI and NOWHERE to KconfigSimon Glass
This converts the following to Kconfig: CONFIG_ENV_IS_IN_MMC CONFIG_ENV_IS_IN_NAND CONFIG_ENV_IS_IN_UBI CONFIG_ENV_IS_NOWHERE In fact this already exists for sunxi as a 'choice' config. However not all the choices are available in Kconfig yet so we cannot use that. It would lead to more than one option being set. In addition, one purpose of this series is to allow the environment to be stored in more than one place. So the existing choice is converted to a normal config allowing each option to be set independently. There are not many opportunities for Kconfig updates to reduce the size of this patch. This was tested with ./tools/moveconfig.py -i CONFIG_ENV_IS_IN_MMC And then manual updates. This is because for CHAIN_OF_TRUST boards they can only have ENV_IS_NOWHERE set, so we enforce that via Kconfig logic now. Signed-off-by: Simon Glass <sjg@chromium.org> Signed-off-by: Tom Rini <trini@konsulko.com>
2017-05-12boston: Setup memory ranges in FDT provided to LinuxPaul Burton
The boston memory map isn't suited to the simple "all memory starting from 0" approach that the MIPS arch_fixup_fdt() implementation takes. Instead we need to indicate the first 256MiB of DDR from 0 and the rest from 0x90000000. Implement ft_board_setup to do that. Signed-off-by: Paul Burton <paul.burton@imgtec.com> Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> Reviewed-by: Simon Glass <sjg@chromium.org>
2017-05-12boston: Move CM GCRs away from flashPaul Burton
Move the MIPS Coherence Manager (CM) Global Configuration Registers (GCRs) away from the region of the physical address space which the Boston board's parallel flash is found in, such that we can access all of flash without clobbering GCRs. Signed-off-by: Paul Burton <paul.burton@imgtec.com> Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> Reviewed-by: Simon Glass <sjg@chromium.org>
2017-05-12MIPS: Make CM GCR base configurablePaul Burton
Without adding a prompt for CONFIG_MIPS_CM_BASE, Kconfig doesn't allow defconfigs to set it. Provide the prompt in order to allow for that. Signed-off-by: Paul Burton <paul.burton@imgtec.com> Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> Reviewed-by: Simon Glass <sjg@chromium.org>
2017-05-10MIPS: add initial infrastructure for Broadcom MIPS SoCsÁlvaro Fernández Rojas
CFE checks CPU Thread in a different way (using register $22): mfc0 t1, C0_BCM_CONFIG, 3 # $22 li t2, CP0_CMT_TPID # (1 << 31) and t1, t2 bnez t1, 2f # if we are running on thread 1, skip init nop Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com> Reviewed-by: Simon Glass <sjg@chromium.org>
2016-11-30MIPS: add possibility to setup initial stack and global data in SRAMDaniel Schwierzeck
This adds a new Kconfig option CONFIG_MIPS_INIT_STACK_IN_SRAM which a SoC can select if it supports some kind of SRAM. Together with CONFIG_SYS_INIT_SP_ADDR the initial stack and global data can be set up in that SRAM. This can be used to provide a C environment also for lowlevel_init(). Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
2016-11-30MIPS: make inclusion of ROM exception vectors configurableDaniel Schwierzeck
This adds a compile time option to include code for static exception vectors. Static exception vectors are only needed, when the U-Boot entry point is equal to the CPU reset exception vector address. For instance this is the case when U-Boot is used as ROM in Qemu or booted from parallel NOR flash. When U-Boot is booted from RAM (e.g. loaded there by SPL), the exception vectors need to be setup dynamically, which is done in follow-up commits. Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
2016-09-21boston: Introduce support for the MIPS Boston development boardPaul Burton
This patch introduces support for building U-Boot to run on the MIPS Boston development board. This is a board built around an FPGA & an Intel EG20T Platform Controller Hub, used largely as part of the development of new CPUs and their software support. It is essentially the successor to the older MIPS Malta board. Signed-off-by: Paul Burton <paul.burton@imgtec.com>
2016-09-21MIPS: Malta: Enable CM & L2 supportPaul Burton
Enable support for the MIPS Coherence Manager & L2 caches on the MIPS Malta board, removing the need for us to attempt to bypass the L2 during boot (which would fail with recent CPUs that expose L2 config via the CM anyway). Signed-off-by: Paul Burton <paul.burton@imgtec.com>
2016-09-21MIPS: L2 cache supportPaul Burton
This patch adds support for initialising & maintaining L2 caches on MIPS systems. The L2 cache configuration may be advertised through either coprocessor 0 or the MIPS Coherence Manager depending upon the system, and support for both is included. If the L2 can be bypassed then we bypass it early in boot & initialise the L1 caches first, such that we can start making use of the L1 instruction cache as early as possible. Otherwise we initialise the L2 first such that the L1s have no opportunity to generate access to the uninitialised L2. Signed-off-by: Paul Burton <paul.burton@imgtec.com>
2016-09-21MIPS: Map CM Global Control RegistersPaul Burton
Map the Global Control Registers (GCRs) provided by the MIPS Coherence Manager (CM) in preparation for using some of them in later patches. Signed-off-by: Paul Burton <paul.burton@imgtec.com>
2016-09-21mips: Add MIPSfpga platform supportZubair Lutfullah Kakakhel
MIPSfpga is an FPGA based dev platform. In a nutshell, its a microAptiv cpu core with lots of Xilinx IP blocks The FPGA dev board used is the Nexys4DDR board by Digilent. For more information, check the Readme file in board/imgtec/xilfpga Signed-off-by: Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.com> Reviewed-by: Paul Burton <paul.burton@imgtec.com> Reviewed-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
2016-06-10MIPS: Make CONFIG_SYS_DCACHE_LINE_SIZE int, not hexPaul Burton
For consistency with the other cache-related Kconfig entries & the values actually set by boards, make CONFIG_SYS_DCACHE_LINE_SIZE an int entry instead of a hex entry. Signed-off-by: Paul Burton <paul.burton@imgtec.com> Fixes: 372286217f05 ("MIPS: Split I & D cache line size config")
2016-05-31MIPS: Split I & D cache line size configPaul Burton
Allow L1 Icache & L1 Dcache line size to be specified separately, since there's no architectural mandate that they be the same. The [id]cache_line_size functions are tidied up to take advantage of the fact that the Kconfig entries are always present to simply check them for zero rather than needing to #ifdef on their presence. Signed-off-by: Paul Burton <paul.burton@imgtec.com> [removed CONFIG_SYS_CACHELINE_SIZE in include/configs/pic32mzdask.h] Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
2016-05-31MIPS: Move cache sizes to KconfigPaul Burton
Move details of the L1 cache line sizes & total sizes into Kconfig, defaulting to 0. A new CONFIG_SYS_CACHE_SIZE_AUTO Kconfig entry is introduced to allow platforms to select auto-detection of cache sizes, and it defaults to being enabled if none of the cache sizes are set by the configuration (ie. sizes are all the default 0), and code is adjusted to #ifdef on that rather than on the definition of the sizes (which will always be defined even if 0). Signed-off-by: Paul Burton <paul.burton@imgtec.com>
2016-05-31MIPS: add tune for MIPS 34kcDaniel Schwierzeck
Add tune Kconfig option for MIPS 34kc. Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
2016-05-31malta: Allow MIPS64 buildsPaul Burton
Both real Malta boards & emulators that mimic Malta (eg. QEMU) can support MIPS64 CPUs. Allow MIPS64 builds of U-Boot for such boards, which enables the user to make use of the whole 64 bit address space. Signed-off-by: Paul Burton <paul.burton@imgtec.com>
2016-05-26malta: Use device model & tree for UARTPaul Burton
Make use of device model & device tree to probe the UART driver. This is the initial step in bringing Malta up to date with driver model, and allows for cleaner handling of the different I/O addresses for different system controllers by specifying the ISA bus address instead of a translated memory address. Signed-off-by: Paul Burton <paul.burton@imgtec.com> Reviewed-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
2016-05-21malta: Support MIPS32r6 configurationsPaul Burton
Both real Malta boards & QEMU's Malta emulation can feature MIPS32r6 CPUs. Allow building U-Boot for such systems by selecting CONFIG_SUPPORTS_CPU_MIPS32_R6 for Malta. Signed-off-by: Paul Burton <paul.burton@imgtec.com>
2016-05-21MIPS: Support for targetting MIPSr6Paul Burton
Add support for targetting MIPS32r6 & MIPS64r6 systems, in the same way that we currently select release 1 or release 2 targets. MIPSr6 is not entirely backwards compatible with earlier releases of the architecture. Some instructions are encoded differently, some are removed, some are reused, so it is not practical to run U-Boot built for earlier revisions on a MIPSr6 system. Update their Kconfig help text to reflect that. Signed-off-by: Paul Burton <paul.burton@imgtec.com>
2016-05-21MIPS: Simplify CONFIG_SYS_CPU valuesPaul Burton
Rather than having the values for CONFIG_SYS_CPU depend upon each architecture revision, have them depend upon the more general CONFIG_CPU_MIPS32 & CONFIG_CPU_MIPS64 which in turn depend upon the architecture revisions. This is done in preparation for adding MIPSr6 support, which would otherwise need to introduce new cases here. Signed-off-by: Paul Burton <paul.burton@imgtec.com>
2016-05-21mips: Add MIPS 74Kc tuneMarek Vasut
Add MIPS 74Kc tune Kconfig option. Signed-off-by: Marek Vasut <marex@denx.de> Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> Cc: Wills Wang <wills.wang@live.com> [added missing tune-y entry in arch/mips/Makefile] Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
2016-05-21mips: add base support for QCA/Atheros ath79 SOCsWills Wang
This patch add some common code for QCA/Atheros ath79 SOCs such as DDR tuning, chip reset and CPU detection. Signed-off-by: Wills Wang <wills.wang@live.com>