1) Set svn:keywords where they should've been set
2) Onda VX747 specific changes


git-svn-id: svn://svn.rockbox.org/rockbox/trunk@18080 a1c6a512-1295-4272-9138-f99709370657
diff --git a/bootloader/ondavx747.c b/bootloader/ondavx747.c
index 96c4c6c..6400ccd 100644
--- a/bootloader/ondavx747.c
+++ b/bootloader/ondavx747.c
@@ -21,18 +21,17 @@
 
 #include <stdio.h>
 #include <stdarg.h>
-#include <string.h>
 #include "config.h"
 #include "jz4740.h"
 #include "backlight.h"
 #include "font.h"
 #include "lcd.h"
 #include "system.h"
-#include "mips.h"
 #include "button.h"
 #include "timefuncs.h"
 #include "rtc.h"
 #include "common.h"
+#include "mipsregs.h"
 
 static void audiotest(void)
 {
@@ -123,35 +122,8 @@
     printf("NAND Flash 4: 0x%x is found [0x%x 0x%x 0x%x]", dwNandID, cData[2], cData[3], cData[4]);
 }
 
-static void jz_store_icache(void)
-{
-    unsigned long start;
-    unsigned long end;
-
-    start = KSEG0BASE;
-    end = start + CFG_ICACHE_SIZE;
-    while(start < end)
-    {
-        cache_unroll(start, 8);
-        start += CFG_CACHELINE_SIZE;
-    }
-}
-
 int main(void)
-{
-    cli();
-    
-    write_c0_status(0x10000400);
-    
-    memcpy((void *)A_K0BASE, (void *)0x80E00080, 0x20);
-    memcpy((void *)(A_K0BASE + 0x180), (void *)0x80E00080, 0x20);
-    memcpy((void *)(A_K0BASE + 0x200), (void *)0x80E00080, 0x20);
-    
-    jz_flush_dcache();
-    jz_store_icache();
-    
-    sti();
-    
+{   
     kernel_init();
     lcd_init();
     font_init();
@@ -165,7 +137,8 @@
     REG8(USB_REG_POWER) &= ~USB_POWER_SOFTCONN;
 
     int touch, btn;
-    lcd_clear_display();
+    char datetime[30];
+    reset_screen();
     printf("Rockbox bootloader v0.000001");
     jz_nand_scan_id();
     printf("REG_EMC_SACR0: 0x%x", REG_EMC_SACR0 >> EMC_SACR_BASE_BIT);
@@ -174,6 +147,11 @@
     printf("REG_EMC_SACR3: 0x%x", REG_EMC_SACR3 >> EMC_SACR_BASE_BIT);
     printf("REG_EMC_SACR4: 0x%x", REG_EMC_SACR4 >> EMC_SACR_BASE_BIT);
     printf("REG_EMC_DMAR0: 0x%x", REG_EMC_DMAR0 >> EMC_DMAR_BASE_BIT);
+    unsigned int cpu_id = read_c0_prid();
+    printf("CPU_ID: (0x%x)", cpu_id);
+    printf(" * Company ID: 0x%x", (cpu_id >> 16) & 7);
+    printf(" * Processor ID: 0x%x", (cpu_id >> 8) & 7);
+    printf(" * Revision ID: 0x%x", cpu_id & 7);
     while(1)
     {
         btn = button_read_device(&touch);
@@ -186,15 +164,23 @@
         if(btn & BUTTON_POWER)
             printf("BUTTON_POWER");
         if(button_hold())
+        {
             printf("BUTTON_HOLD");
+            asm("break 7");
+        }
         if(touch != 0)
         {
             lcd_set_foreground(LCD_RGBPACK(touch & 0xFF, (touch >> 8)&0xFF, (touch >> 16)&0xFF));
-            lcd_fillrect((touch>>16)-10, (touch&0xFFFF)-10, 20, 20);
+            lcd_fillrect((touch>>16)-5, (touch&0xFFFF)-5, 10, 10);
             lcd_update();
+            lcd_set_foreground(LCD_WHITE);
         }
-        /*_printf("%02d/%02d/%04d %02d:%02d:%02d", get_time()->tm_mday, get_time()->tm_mon, get_time()->tm_year,
-                                     get_time()->tm_hour, get_time()->tm_min, get_time()->tm_sec);*/
+        snprintf(datetime, 30, "%02d/%02d/%04d %02d:%02d:%02d", get_time()->tm_mday, get_time()->tm_mon, get_time()->tm_year,
+                                     get_time()->tm_hour, get_time()->tm_min, get_time()->tm_sec);
+        lcd_putsxy(LCD_WIDTH-SYSFONT_WIDTH*strlen(datetime), LCD_HEIGHT-SYSFONT_HEIGHT, datetime);
+        snprintf(datetime, 30, "%d", REG_TCU_TCNT0);
+        lcd_putsxy(LCD_WIDTH-SYSFONT_WIDTH*strlen(datetime), LCD_HEIGHT-SYSFONT_HEIGHT*2, datetime);
+        lcd_update();
     }
     
     return 0;
diff --git a/firmware/drivers/rtc/rtc_jz4740.c b/firmware/drivers/rtc/rtc_jz4740.c
index b9cceec..dadc93a 100644
--- a/firmware/drivers/rtc/rtc_jz4740.c
+++ b/firmware/drivers/rtc/rtc_jz4740.c
@@ -293,15 +293,11 @@
 }
 #endif
 
-#define udelay(x) for(i=0; i<x*100000; i++) asm("nop");
 void rtc_init(void)
 {
-    int i;
-    REG_RTC_RSR = 0;
-    while(!(REG_RTC_RCR & 0x80));
-    REG_RTC_RCR = 1;
+    REG_RTC_RCR = RTC_RCR_RTCE;
     udelay(70);
-    while(!(REG_RTC_RCR & 0x80));
-    REG_RTC_RGR = 0x7fff; 
+    while( !(REG_RTC_RCR & RTC_RCR_WRDY) );
+    REG_RTC_RGR = (0x7fff | RTC_RGR_LOCK); 
     udelay(70);
 }
diff --git a/firmware/export/jz4740.h b/firmware/export/jz4740.h
index 7a7a0d1..2f7f83b 100644
--- a/firmware/export/jz4740.h
+++ b/firmware/export/jz4740.h
@@ -6,58 +6,6 @@
 
 #ifndef __ASSEMBLY__
 
-#define cache_unroll(base,op)	        	\
-	__asm__ __volatile__("	         	\
-		.set noreorder;		        \
-		.set mips3;		        \
-		cache %1, (%0);	                \
-		.set mips0;			\
-		.set reorder"			\
-		:				\
-		: "r" (base),			\
-		  "i" (op));
-          
-#define Index_Invalidate_I      0x00
-#define Index_Writeback_Inv_D   0x01
-
-#define CFG_DCACHE_SIZE		16384
-#define CFG_ICACHE_SIZE		16384
-#define CFG_CACHELINE_SIZE	32
-
-#define KSEG0BASE 0x80003FFF /* HACK */
-
-static inline void jz_flush_dcache(void)
-{
-	unsigned long start;
-	unsigned long end;
-
-	start = KSEG0BASE;
-	end = start + CFG_DCACHE_SIZE;
-	while (start < end) {
-		cache_unroll(start,Index_Writeback_Inv_D);
-		start += CFG_CACHELINE_SIZE;
-	}
-}
-
-static inline void jz_flush_icache(void)
-{
-	unsigned long start;
-	unsigned long end;
-
-	start = KSEG0BASE;
-	end = start + CFG_ICACHE_SIZE;
-	while(start < end) {
-		cache_unroll(start,Index_Invalidate_I);
-		start += CFG_CACHELINE_SIZE;
-	}
-}
-
-/* cpu pipeline flush */
-static inline void jz_sync(void)
-{
-	__asm__ volatile ("sync");
-}
-
 #define REG8(addr)	(*(volatile unsigned char *)(addr))
 #define REG16(addr)	(*(volatile unsigned short *)(addr))
 #define REG32(addr)	(*(volatile unsigned int *)(addr))
diff --git a/firmware/target/mips/ingenic_jz47xx/boot.lds b/firmware/target/mips/ingenic_jz47xx/boot.lds
index 9bc635a..ef5809d 100644
--- a/firmware/target/mips/ingenic_jz47xx/boot.lds
+++ b/firmware/target/mips/ingenic_jz47xx/boot.lds
@@ -25,6 +25,10 @@
     .text : {
         loadaddress = .;
         _loadaddress = .;
+        _resetvectorsstart = .;
+        KEEP(*(.resetvectors));
+        *(.resetvectors);
+        _resetvectorsend = .;
         *(.init.text);
         *(.text*);
         *(.glue_7);
@@ -92,16 +96,13 @@
     
     . = ALIGN(4);
 
-    .vectors IRAMORIG :
+    .vectors :
     {
         _vectorsstart = .;
-        KEEP(*(.resetvectors));
-        *(.resetvectors);
         KEEP(*(.vectors));
         *(.vectors);
         _vectorsend = .;
-    } AT > DRAM
-    _vectorscopy = LOADADDR(.vectors);
+    } > DRAM
     
     . = ALIGN(4);
 }
diff --git a/firmware/target/mips/ingenic_jz47xx/crt0.S b/firmware/target/mips/ingenic_jz47xx/crt0.S
index 43daa2d..d56bd57 100644
--- a/firmware/target/mips/ingenic_jz47xx/crt0.S
+++ b/firmware/target/mips/ingenic_jz47xx/crt0.S
@@ -1,3 +1,24 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2008 by Maurus Cuelenaere
+ *
+ * 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 software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
 /*
  * init.S
  *
@@ -21,14 +42,10 @@
     
     .set mips3
 
-    .extern main
+    .extern system_main
 
     .global    _start
-#ifdef BOOTLOADER
-    .section .init.text,"ax",%progbits
-#else
     .section .resetvectors,"ax",%progbits
-#endif
     .set    noreorder
     .set    noat
     
@@ -80,6 +97,15 @@
     ori     t0, 2
     mtc0    t0, C0_CONFIG
     nop
+    
+	//----------------------------------------------------
+	// clear BSS section
+	//----------------------------------------------------
+	la	t0, _edata
+	la	t1, _end
+1:	sw	zero, 0(t0)
+	bne	t0, t1, 1b
+	addiu	t0, 4
 
     //----------------------------------------------------
     // setup stack, jump to C code
@@ -93,14 +119,12 @@
     bne     t0, sp, _init_stack_loop
     addiu   t0, t0, 4
 
-    la      t0, main
+    la      t0, system_main
     jr      t0
     nop
 
     
-#ifndef BOOTLOADER
     .section .vectors,"ax",%progbits
-#endif
     .extern exception_handler
     .global except_common_entry
     .type   except_common_entry,@function
@@ -119,57 +143,57 @@
 exception_handler:
 
 
-    addiu   sp, -0x80      # Add Immediate Unsigned
-    sw      ra, 0(sp)      # Store Word
-    sw      fp, 4(sp)      # Store Word
-    sw      gp, 8(sp)      # Store Word
-    sw      t9, 0xC(sp)    # Store Word
-    sw      t8, 0x10(sp)   # Store Word
-    sw      s7, 0x14(sp)   # Store Word
-    sw      s6, 0x18(sp)   # Store Word
-    sw      s5, 0x1C(sp)   # Store Word
-    sw      s4, 0x20(sp)   # Store Word
-    sw      s3, 0x24(sp)   # Store Word
-    sw      s2, 0x28(sp)   # Store Word
-    sw      s1, 0x2C(sp)   # Store Word
-    sw      s0, 0x30(sp)   # Store Word
-    sw      t7, 0x34(sp)   # Store Word
-    sw      t6, 0x38(sp)   # Store Word
-    sw      t5, 0x3C(sp)   # Store Word
-    sw      t4, 0x40(sp)   # Store Word
-    sw      t3, 0x44(sp)   # Store Word
-    sw      t2, 0x48(sp)   # Store Word
-    sw      t1, 0x4C(sp)   # Store Word
-    sw      t0, 0x50(sp)   # Store Word
-    sw      a3, 0x54(sp)   # Store Word
-    sw      a2, 0x58(sp)   # Store Word
-    sw      a1, 0x5C(sp)   # Store Word
-    sw      a0, 0x60(sp)   # Store Word
-    sw      v1, 0x64(sp)   # Store Word
-    sw      v0, 0x68(sp)   # Store Word
-    sw      $1, 0x6C(sp)   # Store Word
-    mflo    t0             # Move F LO
+    addiu   sp, -0x80
+    sw      ra, 0(sp)
+    sw      fp, 4(sp)
+    sw      gp, 8(sp)
+    sw      t9, 0xC(sp)
+    sw      t8, 0x10(sp)
+    sw      s7, 0x14(sp)
+    sw      s6, 0x18(sp)
+    sw      s5, 0x1C(sp)
+    sw      s4, 0x20(sp)
+    sw      s3, 0x24(sp)
+    sw      s2, 0x28(sp)
+    sw      s1, 0x2C(sp)
+    sw      s0, 0x30(sp)
+    sw      t7, 0x34(sp)
+    sw      t6, 0x38(sp)
+    sw      t5, 0x3C(sp)
+    sw      t4, 0x40(sp)
+    sw      t3, 0x44(sp)
+    sw      t2, 0x48(sp)
+    sw      t1, 0x4C(sp)
+    sw      t0, 0x50(sp)
+    sw      a3, 0x54(sp)
+    sw      a2, 0x58(sp)
+    sw      a1, 0x5C(sp)
+    sw      a0, 0x60(sp)
+    sw      v1, 0x64(sp)
+    sw      v0, 0x68(sp)
+    sw      $1, 0x6C(sp)
+    mflo    t0             # Move From LO
     nop
-    sw      t0, 0x70(sp)   # Store Word
-    mfhi    t0             # Move F HI
+    sw      t0, 0x70(sp)
+    mfhi    t0             # Move From HI
     nop
-    sw      t0, 0x74(sp)   # Store Word
+    sw      t0, 0x74(sp)
     mfc0    t0, C0_STATUS  # Status register
-    sll     zero, 1        # Shift Left Logical
-    sll     zero, 1        # Shift Left Logical
-    sll     zero, 1        # Shift Left Logical
-    sll     zero, 1        # Shift Left Logical
-    sw      t0, 0x78(sp)   # Store Word
+    sll     zero, 1
+    sll     zero, 1
+    sll     zero, 1
+    sll     zero, 1
+    sw      t0, 0x78(sp)
     mfc0    t0, C0_EPC     # Exception Program Counter
-    sll     zero, 1        # Shift Left Logical
-    sll     zero, 1        # Shift Left Logical
-    sll     zero, 1        # Shift Left Logical
-    sll     zero, 1        # Shift Left Logical
-    sw      t0, 0x7C(sp)   # Store Word
-    li      k1, 0x7C       # Load Immediate
+    sll     zero, 1
+    sll     zero, 1
+    sll     zero, 1
+    sll     zero, 1
+    sw      t0, 0x7C(sp)
+    li      k1, 0x7C
     mfc0    k0, C0_CAUSE   # C0_CAUSE of last exception
-    and     k0, k1         # AND
-    beq     zero, k0, _int # Branch on Equal
+    and     k0, k1
+    beq     zero, k0, _int
     nop
     la    k0, _exception
     jr    k0
@@ -178,57 +202,57 @@
     .global _int
     .type    _int,@function
 _int:
-    jal     intr_handler   # Jump And Link
+    jal     intr_handler
     nop
-    lw      ra, 0(sp)      # Load Word
-    lw      fp, 4(sp)      # Load Word
-    sw      gp, 8(sp)      # Store Word
-    lw      t9, 0xC(sp)    # Load Word
-    lw      t8, 0x10(sp)   # Load Word
-    lw      s7, 0x14(sp)   # Load Word
-    lw      s6, 0x18(sp)   # Load Word
-    lw      s5, 0x1C(sp)   # Load Word
-    lw      s4, 0x20(sp)   # Load Word
-    lw      s3, 0x24(sp)   # Load Word
-    lw      s2, 0x28(sp)   # Load Word
-    lw      s1, 0x2C(sp)   # Load Word
-    lw      s0, 0x30(sp)   # Load Word
-    lw      t7, 0x34(sp)   # Load Word
-    lw      t6, 0x38(sp)   # Load Word
-    lw      t5, 0x3C(sp)   # Load Word
-    lw      t4, 0x40(sp)   # Load Word
-    lw      t3, 0x44(sp)   # Load Word
-    lw      t2, 0x48(sp)   # Load Word
-    lw      t1, 0x4C(sp)   # Load Word
-    lw      t0, 0x50(sp)   # Load Word
-    lw      a3, 0x54(sp)   # Load Word
-    lw      a2, 0x58(sp)   # Load Word
-    lw      a1, 0x5C(sp)   # Load Word
-    lw      a0, 0x60(sp)   # Load Word
-    lw      v1, 0x64(sp)   # Load Word
-    lw      v0, 0x68(sp)   # Load Word
-    lw      v1, 0x6C(sp)   # Load Word
-    lw      k0, 0x70(sp)   # Load Word
+    lw      ra, 0(sp)
+    lw      fp, 4(sp)
+    sw      gp, 8(sp)
+    lw      t9, 0xC(sp)
+    lw      t8, 0x10(sp)
+    lw      s7, 0x14(sp)
+    lw      s6, 0x18(sp)
+    lw      s5, 0x1C(sp)
+    lw      s4, 0x20(sp)
+    lw      s3, 0x24(sp)
+    lw      s2, 0x28(sp)
+    lw      s1, 0x2C(sp)
+    lw      s0, 0x30(sp)
+    lw      t7, 0x34(sp)
+    lw      t6, 0x38(sp)
+    lw      t5, 0x3C(sp)
+    lw      t4, 0x40(sp)
+    lw      t3, 0x44(sp)
+    lw      t2, 0x48(sp)
+    lw      t1, 0x4C(sp)
+    lw      t0, 0x50(sp)
+    lw      a3, 0x54(sp)
+    lw      a2, 0x58(sp)
+    lw      a1, 0x5C(sp)
+    lw      a0, 0x60(sp)
+    lw      v1, 0x64(sp)
+    lw      v0, 0x68(sp)
+    lw      v1, 0x6C(sp)
+    lw      k0, 0x70(sp)
     mtlo    k0             # Move To LO
     nop
-    lw      k0, 0x74(sp)   # Load Word
+    lw      k0, 0x74(sp)
     mthi    k0             # Move To HI
     nop
-    lw      k0, 0x78(sp)   # Load Word
+    lw      k0, 0x78(sp)
     nop
     mtc0    k0, C0_STATUS  # Status register
-    sll     zero, 1        # Shift Left Logical
-    sll     zero, 1        # Shift Left Logical
-    sll     zero, 1        # Shift Left Logical
-    sll     zero, 1        # Shift Left Logical
-    lw      k0, 0x7C(sp)   # Load Word
+    sll     zero, 1
+    sll     zero, 1
+    sll     zero, 1
+    sll     zero, 1
+    lw      k0, 0x7C(sp)
     nop
     mtc0    k0, C0_EPC     # Exception Program Counter
-    sll     zero, 1        # Shift Left Logical
-    sll     zero, 1        # Shift Left Logical
-    sll     zero, 1        # Shift Left Logical
-    sll     zero, 1        # Shift Left Logical
-    addiu   sp, 0x80       # Add Immediate Unsigned
+    sll     zero, 1
+    sll     zero, 1
+    sll     zero, 1
+    sll     zero, 1
+    addiu   sp, 0x80
     eret                   # Exception Return
     nop
     
@@ -239,8 +263,8 @@
     move    a0, sp
     mfc0    a1, C0_CAUSE       # C0_CAUSE of last exception
     mfc0    a2, C0_EPC         # Exception Program Counter
-    la      k0, except_handler # Load Address
-    jr      k0                 # Jump Register
+    la      k0, except_handler
+    jr      k0
     nop
 
     .set reorder
diff --git a/firmware/target/mips/ingenic_jz47xx/lcd-jz4740.c b/firmware/target/mips/ingenic_jz47xx/lcd-jz4740.c
index 5a3eedf..7950e8d 100644
--- a/firmware/target/mips/ingenic_jz47xx/lcd-jz4740.c
+++ b/firmware/target/mips/ingenic_jz47xx/lcd-jz4740.c
@@ -71,7 +71,7 @@
                        | DMAC_DCMD_DWDH_16 | DMAC_DCMD_DS_16BIT);             /* | (2 << 12) | (3 << 8) */
     REG_DMAC_DCCSR(0) = (DMAC_DCCSR_NDES | DMAC_DCCSR_EN);                     /* (1 << 31) | (1 << 0) */
     
-    jz_flush_dcache();
+    __dcache_writeback_all();
     
     REG_DMAC_DMACR = DMAC_DMACR_DMAE;
 
diff --git a/firmware/target/mips/ingenic_jz47xx/onda_vx747/button-onda_vx747.c b/firmware/target/mips/ingenic_jz47xx/onda_vx747/button-onda_vx747.c
index b3c0a5f..a6846ba 100644
--- a/firmware/target/mips/ingenic_jz47xx/onda_vx747/button-onda_vx747.c
+++ b/firmware/target/mips/ingenic_jz47xx/onda_vx747/button-onda_vx747.c
@@ -37,7 +37,8 @@
                         SADC_CFG_SNUM_5                |  \
                         (1 << SADC_CFG_CLKDIV_BIT)     |  \
                         SADC_CFG_PBAT_HIGH             |  \
-                        SADC_CFG_CMD_INT_PEN )
+                        SADC_CFG_CMD_INT_PEN              \
+                        )
 
 bool button_hold(void)
 {
@@ -102,7 +103,7 @@
             REG_SADC_CTRL |= (SADC_CTRL_PENDM);
             unsigned int dat;
             unsigned short xData,yData;
-            short tsz1Data,tsz2Data;
+            short tszData;
             
             dat = REG_SADC_TSDAT;
             
@@ -110,12 +111,11 @@
             yData = (dat >> 16) & 0xfff;
             
             dat = REG_SADC_TSDAT;
-            tsz1Data = (dat >>  0) & 0xfff;
-            tsz2Data = (dat >> 16) & 0xfff;
+            tszData = (dat >>  0) & 0xfff;
+            tszData = tszData - ((dat >> 16) & 0xfff);
             
             *data = touch_to_pixels(xData, yData);
             
-            tsz1Data = tsz2Data - tsz1Data;
         }
         REG_SADC_STATE = 0;
         //__intc_unmask_irq(IRQ_SADC);
diff --git a/firmware/target/mips/ingenic_jz47xx/system-jz4740.c b/firmware/target/mips/ingenic_jz47xx/system-jz4740.c
index 2dca461..3068197 100644
--- a/firmware/target/mips/ingenic_jz47xx/system-jz4740.c
+++ b/firmware/target/mips/ingenic_jz47xx/system-jz4740.c
@@ -21,12 +21,16 @@
  
 #include "config.h"
 #include "jz4740.h"
+#include "mips.h"
 #include "mipsregs.h"
 #include "panic.h"
+#include "system-target.h"
+#include <string.h>
+#include "kernel.h"
 
 void intr_handler(void)
 {
-    //printf("Interrupt!");
+    printf("Interrupt!");
     return;
 }
 
@@ -35,35 +39,243 @@
     panicf("Exception occurred: [0x%x] at 0x%x (stack at 0x%x)", cause, epc, (unsigned int)stack_ptr);
 }
 
-void system_reboot(void)
+static const int FR2n[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
+static unsigned int iclk;
+ 
+static void detect_clock(void)
 {
-    while(1);
+    unsigned int cfcr, pllout;
+    cfcr = REG_CPM_CPCCR;
+    pllout = (__cpm_get_pllm() + 2)* JZ_EXTAL / (__cpm_get_plln() + 2);
+    iclk = pllout / FR2n[__cpm_get_cdiv()];
+    /*printf("EXTAL_CLK = %dM PLL = %d iclk = %d\r\n",EXTAL_CLK / 1000 /1000,pllout,iclk);*/
 }
 
+void udelay(unsigned int usec)
+{
+    unsigned int i = usec * (iclk / 2000000);
+    __asm__ __volatile__ (
+                          ".set noreorder    \n"
+                          "1:                \n"
+                          "bne  %0, $0, 1b   \n"
+                          "addi %0, %0, -1   \n"
+                          ".set reorder      \n"
+                          : "=r" (i)
+                          : "0" (i)
+                          );
+}
+void mdelay(unsigned int msec)
+{
+    unsigned int i;
+    for(i=0; i<msec; i++)
+        udelay(1000);
+}
+
+/* Core-level interrupt masking */
 void cli(void)
 {
-	register unsigned int t;
-	t = read_c0_status();
-	t &= ~1;
-	write_c0_status(t);
+    register unsigned int t;
+    t = read_c0_status();
+    t &= ~1;
+    write_c0_status(t);
 }
 
 unsigned int mips_get_sr(void)
 {
-	unsigned int t = read_c0_status();
-	return t;
+    return read_c0_status();
 }
 
 void sti(void)
 {
-	register unsigned int t;
-	t = read_c0_status();
-	t |= 1;
-	t &= ~2;
-	write_c0_status(t);
+    register unsigned int t;
+    t = read_c0_status();
+    t |= 1;
+    t &= ~2;
+    write_c0_status(t);
 }
 
+#define Index_Invalidate_I      0x00
+#define Index_Writeback_Inv_D   0x01
+#define Index_Load_Tag_I        0x04
+#define Index_Load_Tag_D        0x05
+#define Index_Store_Tag_I       0x08
+#define Index_Store_Tag_D       0x09
+#define Hit_Invalidate_I        0x10
+#define Hit_Invalidate_D        0x11
+#define Hit_Writeback_Inv_D     0x15
+#define Hit_Writeback_I         0x18
+#define Hit_Writeback_D         0x19
+
+#define CACHE_SIZE              16*1024
+#define CACHE_LINE_SIZE         32
+#define KSEG0                   0x80000000
+
+#define SYNC_WB() __asm__ __volatile__ ("sync")
+
+#define cache_op(op,addr)                    \
+    __asm__ __volatile__(                    \
+    "    .set    noreorder        \n"        \
+    "    .set    mips32\n\t       \n"        \
+    "    cache    %0, %1          \n"        \
+    "    .set    mips0            \n"        \
+    "    .set    reorder          \n"        \
+    :                                        \
+    : "i" (op), "m" (*(unsigned char *)(addr)))
+
+void __flush_dcache_line(unsigned long addr)
+{
+    cache_op(Hit_Writeback_Inv_D, addr);
+    SYNC_WB();
+}
+
+void __icache_invalidate_all(void)
+{
+    unsigned int i;
+
+    do 
+    {
+        unsigned long __k0_addr;
+        
+        __asm__ __volatile__(
+                             "la    %0, 1f      \n"
+                             "or    %0, %0, %1  \n"
+                             "jr    %0          \n"
+                             "nop               \n"
+                             "1: nop            \n"
+                             : "=&r"(__k0_addr)
+                             : "r" (0x20000000)
+                             );
+    } while(0);
+
+    asm volatile (".set   noreorder  \n"
+                  ".set   mips32     \n"
+                  "mtc0   $0,$28     \n"
+                  "mtc0   $0,$29     \n"
+                  ".set   mips0      \n"
+                  ".set   reorder    \n"
+                  );
+    for(i=KSEG0; i<KSEG0+CACHE_SIZE; i+=CACHE_LINE_SIZE)
+        cache_op(Index_Store_Tag_I, i);
+
+    do
+    {
+        unsigned long __k0_addr;
+        __asm__ __volatile__(
+                             "nop;nop;nop;nop;nop;nop;nop  \n"
+                             "la    %0, 1f                 \n"
+                             "jr    %0                     \n"
+                             "nop                          \n"
+                             "1:    nop                    \n"
+                             : "=&r" (__k0_addr)
+                             );
+    } while(0);
+
+    do
+    {
+        unsigned long tmp;
+        __asm__ __volatile__(
+        ".set mips32       \n"
+        "mfc0 %0, $16, 7   \n"
+        "nop               \n"
+        "ori  %0, 2        \n"
+        "mtc0 %0, $16, 7   \n"
+        "nop               \n"
+        ".set mips0        \n"
+        : "=&r" (tmp));
+    } while(0);
+}
+
+void __dcache_invalidate_all(void)
+{
+    unsigned int i;
+
+    asm volatile (".set   noreorder  \n"
+                  ".set   mips32     \n"
+                  "mtc0   $0,$28     \n"
+                  "mtc0   $0,$29     \n"
+                  ".set   mips0      \n"
+                  ".set   reorder    \n"
+                  );
+    for (i=KSEG0; i<KSEG0+CACHE_SIZE; i+=CACHE_LINE_SIZE)
+        cache_op(Index_Store_Tag_D, i);
+}
+
+void __dcache_writeback_all(void)
+{
+    unsigned int i;
+    for(i=KSEG0; i<KSEG0+CACHE_SIZE; i+=CACHE_LINE_SIZE)
+        cache_op(Index_Writeback_Inv_D, i);
+    
+    SYNC_WB();
+}
+
+extern void (*tick_funcs[MAX_NUM_TICK_TASKS])(void);
+
+#define USE_RTC_CLOCK 0
 void tick_start(unsigned int interval_in_ms)
 {
-    (void)interval_in_ms;
+    unsigned int tps = interval_in_ms;
+	unsigned int latch;
+	__cpm_start_tcu();
+	
+	__tcu_disable_pwm_output(0);
+	__tcu_mask_half_match_irq(0); 
+	__tcu_unmask_full_match_irq(0);
+
+#if USE_RTC_CLOCK
+	__tcu_select_rtcclk(0);
+	__tcu_select_clk_div1(0);
+    latch = (__cpm_get_rtcclk() + (tps>>1)) / tps;
+#else	
+	__tcu_select_extalclk(0);
+	__tcu_select_clk_div4(0);
+	
+	latch = (JZ_EXTAL / 4 + (tps>>1)) / tps;
+#endif
+	REG_TCU_TDFR(0) = latch;
+	REG_TCU_TDHR(0) = latch;
+
+	__tcu_clear_full_match_flag(0);
+	__tcu_start_counter(0);
+	
+    //printf("TCSR = 0x%04x\r\n",*(volatile u16 *)0xb000204C);
+}
+
+extern int main(void);
+extern unsigned int _loadaddress;
+extern unsigned int _resetvectorsstart;
+extern unsigned int _resetvectorsend;
+extern unsigned int _vectorsstart;
+extern unsigned int _vectorsend; /* see boot.lds/app.lds */
+
+void system_main(void)
+{
+    cli();
+    write_c0_status(0x10000400);
+    
+    memcpy((void *)A_K0BASE, (void *)&_loadaddress, 0x20);
+    memcpy((void *)(A_K0BASE + 0x180), (void *)&_vectorsstart, 0x20);
+    memcpy((void *)(A_K0BASE + 0x200), (void *)&_vectorsstart, 0x20);
+    
+    __dcache_writeback_all();
+    __icache_invalidate_all();
+    
+    sti();
+    
+    detect_clock();
+    
+    main();
+    
+    while(1);
+}
+
+void system_reboot(void)
+{
+    REG_WDT_TCSR = WDT_TCSR_PRESCALE4 | WDT_TCSR_EXT_EN;
+    REG_WDT_TCNT = 0;
+    REG_WDT_TDR = JZ_EXTAL/1000;   /* reset after 4ms */
+    REG_TCU_TSCR = TCU_TSSR_WDTSC; /* enable wdt clock */
+    REG_WDT_TCER = WDT_TCER_TCEN;  /* wdt start */
+    
+    while (1);
 }
diff --git a/firmware/target/mips/ingenic_jz47xx/system-target.h b/firmware/target/mips/ingenic_jz47xx/system-target.h
index a84a991..c11ad4b 100644
--- a/firmware/target/mips/ingenic_jz47xx/system-target.h
+++ b/firmware/target/mips/ingenic_jz47xx/system-target.h
@@ -18,13 +18,14 @@
  * KIND, either express or implied.
  *
  ****************************************************************************/
- 
+
+#ifndef __SYSTEM_TARGET_H_
+#define __SYSTEM_TARGET_H_
+
 #include "config.h"
 #include "jz4740.h"
 #include "mipsregs.h"
 
-/* Core-level interrupt masking */
-
 /* This one returns the old status */
 #define HIGHEST_IRQ_LEVEL 0
 
@@ -99,7 +100,14 @@
 #define	swap16(x) (((x) & 0xff) << 8 | ((x) >> 8) & 0xff)
 #define	swap32(x) (((x) & 0xff) << 24 | ((x) & 0xff00) << 8 | ((x) & 0xff0000) >> 8 | ((x) >> 24) & 0xff)
 
+#define UNCACHED_ADDRESS(addr)    ((unsigned int)(addr) | 0xA0000000)
+
+void __dcache_writeback_all(void);
+void __dcache_invalidate_all(void);
+void __icache_invalidate_all(void);
+void __flush_dcache_line(unsigned long addr);
 void sti(void);
 void cli(void);
 
-#define UNCACHED_ADDRESS(addr)    ((unsigned int)(addr) | 0xA0000000)
+#endif /* __SYSTEM_TARGET_H_ */
+
diff --git a/firmware/thread.c b/firmware/thread.c
index 2eaa422..5c404b1 100644
--- a/firmware/thread.c
+++ b/firmware/thread.c
@@ -1124,7 +1124,18 @@
  */
 static inline void core_sleep(void)
 {
-    asm volatile("nop\n");
+    /*
+	REG_CPM_LCR &= ~CPM_LCR_LPM_MASK;
+	REG_CPM_LCR |= CPM_LCR_LPM_SLEEP;
+    */
+	asm volatile(".set   mips3  \n"
+                 "wait          \n"
+                 ".set   mips0  \n"
+                 );
+	/*
+    REG_CPM_LCR &= ~CPM_LCR_LPM_MASK;
+	REG_CPM_LCR |= CPM_LCR_LPM_IDLE;
+    */
 }